Files
releasekit/docs/adr/0006-neutral-forge-delivery-and-preflight.md

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 ForgeGitea in 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.