Repository navigation
[EPIC] Files on every data plane: one store, one API, and the authority behind it #1750
Description
Problem
api/routes/files.py and services/files/ hold no control plane references, and the bytes already move through FileStoragePort with local, S3 and fsspec adapters. But a data plane that holds no database cannot serve files at all, because a file's record has nowhere to live.
Direction
Decided in #1606.
- Otari's store is the source of truth for a file's bytes in both directions. An uploaded file's provider copy is never read back, and a produced file is copied in before the response that mentions it is forwarded.
- A provider copy is a tracked derivative with its own expiry, never the record.
- Bytes move by Try-Confirm-Cancel with a scoped grant, per Decide how a data plane reaches the code-execution backend: control-plane proxy, or a scoped grant #1603. The record exists before the bytes, quota is enforced at Try, and Confirm is retried to exhaustion and then parked rather than dropped.
- In hybrid, the platform supplies the bucket, and the grant is a presigned write to it. An operator-owned bucket is deferred to Decide the authority model for an operator-owned bucket in hybrid #1749.
- A download streams and never redirects, because
files_backend: localhas no URL and one public endpoint must behave the same on every backend. - Files is one service with two bindings. Nothing on the request path asks which mode it is running in.
The work
Foundations. The wire contract comes first, because the port and the adapter implement it.
- Allocate a file's storage reference before its bytes are written #1740 Allocate a file's storage reference before its bytes are written
- Specify the Files wire contract in docs/hybrid-mode-protocol.md #1743 Specify the Files wire contract in
docs/hybrid-mode-protocol.md - Add FileAuthorityPort, so a data plane with no database can serve files #1741 Add
FileAuthorityPort, so a data plane with no database can serve files - Give FileStoragePort a shutdown method, so a store's client is released #1921 Give
FileStoragePorta shutdown method (before A grant-backed file storage adapter, for presigned writes and reads #1742) - A grant-backed file storage adapter, for presigned writes and reads #1742 A grant-backed file storage adapter, for presigned writes and reads
Serving it, after #1741.
- Serve the files surface on every data plane, and validate storage at startup #1744 Serve the files surface on every data plane, and validate storage at startup
- Resolve a completion's file references through the files service on every data plane #1745 Resolve a completion's file references through the files service on every data plane, with A completion resolves each referenced file on its own, with its own query and its own transaction #1592's batching
- Bind the sandbox file bridge to the files service, not to a local database #1746 Bind the sandbox file bridge to the files service, with Split SandboxFileBridge into its three jobs #1599's split
- Copy a provider's produced files into Otari's store on every data plane #1747 Copy a provider's produced files into Otari's store on every data plane
Provider copies and deletion.
- Refuse a container_upload block naming a file Otari does not hold, on every path #1611 Refuse a
container_uploadblock naming a file Otari does not hold, on every path - Hybrid mode forwards a caller's container_upload file ID to a shared provider account #1798 The data plane refuses a
container_uploadblock on a managed attempt - Retention and deletion that reach every copy of a file #1487 Deletion reaches every provider copy of a file
Store and service hardening. Independent of the work above.
- The S3 file store lets storage failures escape the port's OSError contract #1920 The S3 file store lets storage failures escape the port's
OSErrorcontract - File storage callers catch OSError but the port also documents ValueError #1601 File storage callers catch
OSErrorbut the port also documentsValueError - A download abandoned before its body starts does not close the store's handle promptly #1604 A download abandoned before its body starts does not close the store's handle promptly
- Warn when the local files backend runs on more than one replica #1607 Warn when the local files backend runs on more than one replica
- Turning the files API off also stops the sweep, so expired rows stay forever #1595 Turning the files surface off must not stop the sweep, and the flag's name must say so
- Shield the orphan-blob cleanup with an AnyIO cancel scope #1636 Shield the orphan-blob cleanup from cancellation
- Remove the OpenAI container-file download once any-llm can read container files #1480 Remove the OpenAI container-file download once any-llm can read container files (upstream)
Decisions and documentation.
- Decide the hybrid retention ceiling for canonical files #1731 The hybrid retention ceiling for canonical files is 168 hours
- docs/modes.md: where a file's bytes live, and what deleting one promises #1748
docs/modes.md: where a file's bytes live, and what deleting one promises (after Decide the hybrid retention ceiling for canonical files #1731) - Decide the authority model for an operator-owned bucket in hybrid #1749 Decide the authority model for an operator-owned bucket in hybrid (deferred until a deployment needs it)
Rules for implementers
The rules for every capability on the seam are on #1790. Two are specific to files.
- Files is core. One service with two bindings, never two services. The public files router is never an overlay contribution.
- Every file write goes through the files service. Call
FileService.storeorstore_produced, which own the allocate, reserve, write, stamp and give-back sequence. Do not write that sequence out again.
Not in scope
OpenAI native code execution input staging, a Gemini-specific files integration, provider copies made only to speed up reading an attachment, and file transfer between unrelated deployments.
Done when
- One set of public files tests passes against a standalone and a hybrid deployment, with the same assertions.
- No module under
services/files/names a runtime mode. - A peer can implement the files half of the protocol from
docs/hybrid-mode-protocol.mdalone.
Activity