Loading
feat(oci): add OCI format package (manifests, blobs, uploads, tags) (MR 4/5)
Why
Layer 3 (OCI format) of the S12 OCI-local stack. The internal/format/oci package: the format-specific handling for the 16 OCI Distribution Spec endpoints.
This MR cannot land before MR-3 because:
- Wiring (
cmd/registry, router) imports the OCI handlers. - Format integrates the layers below: datastore (manifest/tag state), CAS (blob storage), namespace (authorization scope), auth (request identity).
Issue: #19 (closed) Spec: S12 (already merged via !48 (merged))
Stack and merge order
| # | MR | Branch | Targets | Blocks |
|---|---|---|---|---|
| 0 | !141 (merged) | 19-oci-boilerplate |
main |
!124 (closed) |
| 1 | !124 (closed) | 19-oci-foundation |
19-oci-boilerplate |
!125 (closed) |
| 2 | !125 (closed) | 19-oci-database |
19-oci-foundation |
!126 (closed) |
| 3 | !126 (closed) | 19-oci-cas |
19-oci-database |
!127 (closed) |
| 4 | !127 (closed) ← you are here | 19-oci-format |
19-oci-cas |
!128 (closed) |
| 5 | !128 (closed) | 19-oci-wiring |
19-oci-format |
n/a |
What's in MR-4
37 files, ~17,500 insertions, all Go code and fuzz seed corpus. This is the largest MR in the stack. File-by-file review is unrealistic at this size, so this MR description points reviewers at the highest-risk areas.
Worth a closer read:
manifest.goandmanifest_state_test.go(~2,200 lines): manifest parsing/validation across all OCI mediatypes (image manifest, image index, scratch). State machine for manifest lifecycle (uploaded → tagged → referenced → soft-deleted).upload.goandupload_state_test.go(~1,600 lines): multi-step upload flow (POST → PATCH → PUT) backed by CAS sessions. State transitions covered by property-based and rapid state-machine tests per !55 (merged) §Technique selection.store.go(~1,300 lines): the integration point that ties datastore, CAS, namespace, and the format-specific logic together. Reviewers should check the transaction boundaries on push (manifest write, blob refs, tags) and pull paths.referrers.go: OCI 1.1 §referrers API. Returns subject-referrer manifest index given a digest.digest.go/mediatype.go/ Content-Range parser: each has atesting.Ffuzz target. Seed corpus committed alongside.tags.go: tag list pagination per OCI Distribution Spec.
The package follows !55 (merged) two-agent test flow per the spec-coverage table (Steps 7-12 of docs/plans/2026-04-28-oci-local.md).
Test plan
- CI green on this MR (build, vet, lint, full unit test suite). The package is the heaviest test surface in the stack, expected duration ~1 minute.
-
test:integrationactivates (changes matchinternal/datastore/**transitively) andstore_integration_test.goandstore_size_integration_test.gopass. -
test:fuzzdoes not retrigger (gated byinternal/auth/**). - !128 (closed)'s wiring builds the OCI handlers via
internal/router, which imports this package. Tested locally.
Reviewer notes
- The 17k-line size is acknowledged. Pawel proposed a 1k-LOC bar in the !124 (closed) review thread, and this MR is over that. The OCI format is highly cohesive (datastore + CAS + state machines + protocol parsing inseparable), and decomposing it further would only displace complexity into the wiring layer. We accept the size for this milestone (Friday OCI-local deadline) and revisit decomposition post-merge if reviewer feedback identifies natural boundaries.
- Spec gaps surfaced during implementation are journaled in
docs/dev/oci-spec-gaps.md(already in MR-0). Each entry names the resolution and the pointer to where the choice landed.
Edited by Hayley Swimelar