[data-reveal]{opacity:1!important;transform:none!important}
Provider Promotion Contract
File Storage

Provider Promotion Contract

This page is for storage backend authors. Application authors can start with file operations; their authorization, admission, and cancellation responsibilities remain in that guide.

Implement the promotion hook

Providers implement internal.promoteFile(resourceKey, storage?) and return Promise<PromoteFileResponse>. The public signature is unchanged, but this is a required provider-contract change: there is no fallback to MoveFile plus FileExists. Existing adapters must add the hook before using this interface.

Publish a complete object

Provider obligationWhy it matters
Publish bytes, metadata, visibility, and trusted origin togetherA reader must not see an incomplete result.
Make local metadata publication recoverableRenaming bytes and independently writing metadata is insufficient.
Reject or isolate upload-controlled origin fieldsClient metadata must not forge promotion provenance.
Bind trusted provenance to the source and canonical destination across retriesMatching retries converge on the same complete result.
Enforce conditional publication or throwA provider must never silently overwrite a destination.

Publish to the canonical key returned by stripStagingPrefix in the same storage, and clean up the source only after verifying final publication. A complete matching destination allows a retry to succeed even if the source has already been removed. An unrelated or unverifiably incomplete destination throws FileConflictError; a missing source without a committed destination throws FileNotFoundError. Unknown outcomes must throw, not return an assumed success.

For private uploads, enforce private access for both staged and final bytes. Issuing signed URLs over publicly accessible storage does not make files private. Promotion does not provide a cancellation fence: delayed work may publish an orphan, which the application must never admit into a cancelled record.

Validate an adapter

Run the shared provider conformance suite with a disposable backend. Keep provider-specific fault, signature, routing, and lifecycle tests in the adapter. Passing the interface's forwarding unit tests is not evidence that an adapter publishes complete objects safely.