4.5 KiB
ADR 0006: Separate delivery policy from forge protocols
Status
Accepted.
Date
2026-11-01
Context
ReleaseKit's delivery workflow handles release-page matching and creation recovery, remote asset comparison, upload ordering, retries, and partial or uncertain outcomes. Those policies are useful independently of the Gitea HTTP protocol, but the earlier client-owned flow coupled them to Gitea types and operations.
Delivery also benefits from checking credentials and repository access before
managed builds, dependency preparation, or complete artifact hashing. Gitea
exposes authenticated repository reads, but its permissions.push metadata and
basic token evidence do not establish permission to write release pages or
assets. A read-only check must represent that evidence limit without claiming
that later writes are guaranteed.
The root releasekit facade owns public types, while implementation packages
remain internal. The CLI owns credential loading and process exit status.
Source publication has separate Git authentication and completion semantics.
Decision
The root facade owns Forge, DeliveryDestination, explicit backend selection,
and public preflight errors. internal/forge defines the internal backend
contract and neutral release, asset, failure, and write-evidence values.
internal/delivery owns shared delivery coordination and policy.
internal/gitea owns Gitea destination rules, authenticated preflight requests,
protocol operations, codecs, handles, streaming, and conversion to neutral
failures. internal/artifact owns local asset declarations and verification.
Shared delivery, forge, and artifact packages have no production dependency
path to the Gitea adapter.
Delivery selection is explicit. The supported value is gitea; neither a URL
nor an omitted selection chooses a backend. There is no compatibility alias for
the removed public Gitea destination type.
The facade exposes PreflightDelivery and runs the same read-only backend
preflight automatically during Deliver. Gitea preflight authenticates through
repository-scoped reads and classifies missing or rejected credentials,
inaccessible destinations, and unavailable verification. It does not issue a
test release or upload, require extra user/admin token scopes, or treat
unexposed write permission evidence as a failure. Success confirms only the
authentication, repository access, and permission evidence available through
that check; ordinary writes remain authoritative. Preflight failures preserve
their causes and leave delivery not_attempted.
The CLI requires delivery.forge only for deliver and ci-deliver. Binary
CI delivery performs a standalone preflight after checkout/profile/token
preparation and before application dependency downloads, then Deliver
rechecks. Page-only CI relies on automatic delivery preflight. check,
build, and source publish do not require delivery configuration or hosted
credentials. Local artifact verification follows preflight but completes before
hosted writes.
Alternatives considered
- Keep delivery policy in the Gitea client. This retains protocol coupling and makes shared recovery behavior harder to exercise without the adapter.
- Select Gitea from the URL or preserve the old Gitea-specific facade type. This hides backend selection and keeps the public contract tied to one adapter.
- Probe permissions with a test release or asset, or require additional user scopes. Those operations can create remote state or demand evidence unrelated to release delivery; the repository read does not expose the required release-write proof.
- Skip preflight and let the first write discover credential problems. That delays a known failure until after costly local work and provides no standalone check for callers preparing their own delivery.
Consequences
- Shared policy can be tested with controlled backends, while local HTTP tests focus on Gitea protocol behavior and assembled integration flows.
- Consumers must replace the removed Gitea-specific destination type, set
ForgeGiteain API calls, and add"forge": "gitea"to delivery profiles. - Delivery may make additional authenticated read requests before local artifact hashing. It still verifies full local content before any hosted write.
- Credential, access, and availability failures have distinct public error kinds and CLI classifications. Successful preflight does not certify future release or asset writes.
- Source publication retains native Git authentication and is not gated by hosted delivery preflight.