feat(oci): blob upload initiate and PATCH chunk (S12 Step 8)

Why

Step 8 of the OCI local plan. Implements the first two endpoints of the chunked blob-upload flow from S12: initiate (POST) and chunk-append (PATCH). Finalize (PUT, GET, and DELETE) follows in Step 9.

What

  • The upload session is scoped to (namespace_id, repository_id) and carries no container_image_id. POST lazy-creates the image row via the ImageUpserter seam. Finalize re-resolves the image from the URL in Step 9 (S12 Session-to-URL binding).
  • The dispatcher gains an optional upload-handler seam (NewDispatchHandlerWithUpload). The two-arg NewDispatchHandler keeps the interim 501 for resolved-but-unwired routes, so the composition root stays on the existing path until S06 lands a production BlobStore. Only the stub exists today.
Context for LLM agents

Rationale

  • Stash container_image_id on the upload_sessions row (the original plan). Rejected: S12 Session-to-URL binding scopes the session to (namespace_id, repository_id), and the row has no such column. Finalize re-resolves the image from the request URL instead.

Non-goals

  • PUT, GET, DELETE, and single-POST finalize. Owned by Step 9.
  • blob_max_size 413 cap and read-deadline extension. Step 9, where the S01 chain and ContainerConfig supply them.
  • S03 wide-event fields. Deferred until the S03 helper merges, with no emission surface to assert against yet.
  • hash_state cross-Go-release rehash fallback. Needs the real upload_sessions datastore (FOR UPDATE) plus S03.

Merge request reports

Loading
Loading