7.8 KiB
Producer HTTP Upload Package Implementation Roadmap
Current Baseline
distributor serve and the http_upload source backend are implemented.
Producers can already submit complete tar or gzip-compressed tar source bundles
to POST /upload with bearer authentication, and each bearer token maps to one
configured upload pipeline.
The public pkg/bundle package already provides producer-side source manifest
semantics, digest calculation, path validation, local manifest building, local
bundle writing, and local bundle validation helpers.
The current implementation does not have a server-side producer idempotency
contract, and it does not provide a public pkg/upload helper package.
Future behavior remains under docs/roadmap/ until implemented. Do not update
README, current user docs, examples, or current-behavior internal docs until the
corresponding stage has been implemented.
This active roadmap implements the accepted producer upload package plan in
docs/roadmap/producer.md. It supersedes the older docs/roadmap/http.md
deferred note for producer-supplied idempotency keys; producer idempotency is
now active roadmap work.
Active Roadmap
Stage 1: Server-Side Upload Idempotency
Goal:
Add Idempotency-Key support to POST /upload so safe producer retries do not
create duplicate accepted runs.
Implementation scope:
- Validate optional
Idempotency-Keyheaders using the syntax defined indocs/roadmap/producer.md. - Scope keys by the authenticated pipeline selected through bearer-token mapping.
- Record accepted keys after archive staging and source bundle validation succeed.
- Compare normalized source manifest identity, not raw archive bytes.
- Return the original accepted run response for the same pipeline, same key, and same manifest identity.
- Return
409 Conflictfor the same pipeline and key with a different manifest identity. - Return a retryable conflict response when the same key is already being processed concurrently for the same pipeline before manifest identity is known.
- Expire idempotency records with existing upload status retention.
- Keep idempotency records memory-only; server restart clears them.
- Preserve current raw HTTP behavior when no idempotency key is supplied.
Current-behavior documentation updates after implementation:
docs/integrations/http-upload.mddocs/operations.mddocs/internal/app.mddocs/troubleshooting.md
Tests:
- Same key and same bundle returns the original run id and does not enqueue a second run.
- Same key and different bundle returns
409. - Same key under different authenticated pipelines does not conflict.
- Missing key preserves current raw HTTP behavior.
- Invalid key syntax returns
400. - Expiration removes idempotency records.
- Tokens are never leaked; idempotency keys appear only where needed for diagnostics.
Completion criteria:
- Existing upload clients continue to work.
- The HTTP API has an implemented, tested idempotency contract.
- Idempotent retries cannot create duplicate accepted runs.
Stage 2: Public pkg/upload API And Client
Goal:
Add a producer-facing upload package that builds or validates bundles, archives them, and submits them to the HTTP upload API.
Implementation scope:
- Add public
pkg/upload. - Use
pkg/bundlefor manifest generation, digest and path semantics, local validation, and temporary bundle creation. - Implement options-struct APIs matching
docs/roadmap/producer.md:ClientOptions,RetryOptions,UploadBundleOptions,UploadFilesOptions,Result,RunStatus,NewClient,UploadBundle,UploadFiles, andStatus. - Treat
Endpointas the distributor server base URL, deriving/uploadand/runs/<run-id>internally. - Require bearer token authentication and redact token values from all errors.
- Always send
Idempotency-Key. - Use caller-supplied idempotency keys when provided.
- When no key is supplied, generate one random 128-bit lowercase hex key per upload operation and reuse it across retries from that call.
- Support uploading an existing local bundle root.
- Support building a temporary bundle from explicit
bundle.BundleFilevalues and uploading it. - Create replayable gzip-compressed tar uploads with
Content-Type: application/gzip. - Retry only safe cases:
503 Service Unavailable, temporary network errors, and ambiguous mid-upload failures, using the same idempotency key and replayable body. - Do not retry
400,401,409,413, or415. - Do not retry after
202 Accepted. - Respect context cancellation before waiting and before each retry.
- Close response bodies on every attempt.
Current-behavior documentation updates after implementation:
- Update
pkg/bundleintegration references only as needed oncepkg/uploadexists. - Keep full user-facing docs and examples for Stage 3.
Tests:
- Client construction validates endpoint and token requirements.
- Token values are redacted from errors.
- Caller-supplied and generated idempotency keys are sent correctly.
- Existing bundle upload includes only
manifest.jsonand manifest-listed files. - File-based upload builds a compliant temporary bundle without touching producer source directories.
- Local validation failures prevent HTTP requests.
- Response parsing covers
202,400,401,409,413,415,503, non-JSON errors, and unexpected statuses. - Retry uses the same idempotency key and stops correctly.
- Context cancellation during retry backoff is honored.
- Custom
*http.Clientbehavior is covered withhttptest.
Completion criteria:
- Go producers can upload valid bundles through
pkg/upload. - Safe retry behavior relies on the implemented server idempotency contract.
- Public package tests prove upload behavior does not duplicate or drift from
pkg/bundlesemantics.
Stage 3: Documentation And Examples
Goal:
Document implemented producer upload and idempotency behavior after the server contract and public package exist.
Implementation scope:
- Update current-behavior docs only after Stages 1 and 2 are implemented.
- Add secret-free examples where they are safe, copyable, and describe implemented behavior.
- Keep deferred items out of current docs.
Docs to update:
README.mddocs/integrations/source-bundle.mddocs/integrations/http-upload.mddocs/operations.mddocs/internal/app.mddocs/policy/development.mdexamples/, only if examples are safe, copyable, and implemented
Tests and checks:
go test ./...
rg -n "idempotency|Idempotency-Key|pkg/upload|UploadBundle|UploadFiles" README.md docs examples
Completion criteria:
- Current docs describe the implemented server idempotency and
pkg/uploadAPI. - Completed behavior is not documented only as future work.
docs/roadmap/contains only future or deferred producer-upload work.
Deferred Work
- Durable idempotency storage across server restarts.
- Database-backed queues or durable producer retry processing.
UploadAndWait, long polling, run cancellation, run retry, or run listing helpers.- Zstandard archives.
- Multipart, resumable, or streaming upload protocols.
- URL-token authentication.
- Browser UI or public exposure defaults.
Validation
For this documentation pass:
rg -n "Idempotency-Key|pkg/upload|UploadBundle|UploadFiles|Stage 1: Server-Side Upload Idempotency" docs/roadmap/implementation.md
rg -n "Producer-supplied idempotency keys|Producer Coordination" docs/roadmap/http.md docs/roadmap/implementation.md
rg -n "pkg/upload|UploadBundle|UploadFiles|Idempotency-Key" README.md docs examples --glob '!docs/roadmap/**'
git status --short
git diff -- docs/roadmap/implementation.md
Expected result:
- New future behavior appears only under
docs/roadmap/. - Existing unrelated worktree changes, including any current
docs/roadmap/documentation.mddeletion, are not touched. - This pass changes only
docs/roadmap/implementation.md.