Files
releasekit/docs/roadmap/forge-boundary.md

179 lines
9.5 KiB
Markdown
Raw Normal View History

# Roadmap: forge delivery boundary and credential preflight
Status: accepted; implementation has not started.
The [implementation plan](implementation.md) owns stages, concrete design
choices, task sequencing, and verification.
## Objective and scope
Introduce an internal boundary between shared hosted-release delivery and the
Gitea implementation. The result should support adding another forge through
an adapter while reusing ReleaseKit's release and asset-delivery policy.
Add operation-specific credential preflight through that boundary so delivery
stops on credential problems before expensive preparation or builds.
ReleaseKit's `Publish` operation validates and publishes source through Git.
Its `Deliver` operation verifies tagged source and delivers release notes and
declared assets to a hosting service. This refactor concerns the latter operation
and its composition through the existing public facade and CLI.
Gitea is the concrete backend for this work. Forgejo, GitHub, GitLab, and other
backends remain future implementation work. The boundary should express the
operations used by the current delivery workflow and allow refinement when a
second backend supplies concrete requirements.
## Current baseline
The source baseline is `ac78e7d`, following the published v0.5.0 module migration
and the subsequent token-file and forbidden-file changes.
- [delivery.go](../../delivery.go) exposes `GiteaDestination` through
`DeliveryRequest.Destination` and converts it into `gitea.Destination`.
- [internal/delivery](../../internal/delivery/delivery.go) resolves source
identity, checks tagged source, reads notes, coordinates builds, and directly
calls `gitea.Client` for release and asset operations. Its result conversion
and failure classification use Gitea-owned internal types.
- [release.go](../../internal/gitea/release.go) combines Gitea HTTP operations
with hosted-tag verification, matching-page acceptance, release creation,
and reconciliation of ambiguous creates.
- [assets.go](../../internal/gitea/assets.go) and
[upload.go](../../internal/gitea/upload.go) combine HTTP operations with
manifests, local-file verification, remote-content comparison, asset
observations, upload sequencing, and retry bookkeeping.
- CLI credential resolution supplies an explicit token from the configured
environment variable or token file. The profile describes a Gitea repository;
it has no forge selector.
- CLI loading checks token availability, but forge API authentication first occurs
through delivery requests after application dependency preparation and managed
builds. Library delivery also checks a blank token only at the later Gitea
request boundary. There is no dedicated authenticated credential preflight.
The [Gitea integration guide](../integrations/gitea.md) and public Go declarations
document the baseline contracts. Current behavioral tests provide regression
coverage to assess against those contracts. The
[architecture policy](../policy/architecture.md) governs facade ownership and
dependency direction.
## Targeted end state
### Neutral public destination and explicit forge selection
Replace `GiteaDestination` with a facade-owned neutral destination type and
require explicit forge selection in the public API and delivery configuration.
Gitea is the sole supported selection initially.
An omitted, blank, or unsupported selection produces a validation error; Gitea
is selected explicitly rather than inferred from a default or destination URL.
The destination represents the addressing and credentials needed for current
delivery through neutral public names. Concrete backend construction uses the
selected forge. Additional backends may extend that model when their addressing
and protocol requirements are implemented.
### Shared delivery responsibilities
Shared internal code owns:
- Automatic credential preflight coordination before expensive delivery work.
- Captured source identity, local tag/commit checks, committed release notes,
managed or prebuilt artifact coordination, and local artifact verification.
- The existing logical rules for accepting matching hosted content, reporting
conflicts, creating missing content, and reconciling uncertain writes.
- Manifest generation, content comparison, and asset observations used to decide
which declared assets require delivery.
- Aggregation into the existing public delivery outcomes and asset categories.
These operations consume backend-neutral internal values and operations. The
generic delivery workflow has no dependency on `internal/gitea`. The facade or
private composition code constructs the concrete backend and supplies it to
shared delivery.
### Credential preflight
Delivery automatically checks the credentials required for its selected backend.
Local checks establish availability and valid destination settings; a read-only
backend probe establishes authentication and access to the configured repository.
Reliable evidence of insufficient required permissions stops the operation.
Unexposed permissions remain unverified; successful reads establish no blanket
guarantee that later writes will succeed. Preflight performs no test writes and
preserves ordinary delivery authorization and recovery handling.
Library and ordinary CLI delivery perform preflight before managed builds and
full artifact verification. CI loads the verified tagged profile first, then
performs preflight before application dependency preparation. A callable facade
operation lets consumers check a destination before their own preparation,
without requiring a release tag or note to exist.
Failures distinguish missing or rejected credentials, insufficient permissions,
an inaccessible destination, and unavailable or unverifiable service responses.
Delivery reports `not_attempted` for these pre-write failures. Diagnostics retain
useful causes while excluding tokens. Each check describes access at that time;
later operations retain their normal checks.
Required credentials follow operation scope. Candidate checking and standalone
builds remain credential-free. Source publication continues using Git's native
SSH/HTTPS authentication and existing remote guards, independently of hosted
delivery credentials. This feature adds no Gitea-token requirement to `Publish`.
### Backend responsibilities
The Gitea adapter owns destination validation specific to Gitea, API routes,
authentication headers, request and response formats, pagination, multipart
uploads, attachment downloads, and HTTP-specific error interpretation.
It also owns authenticated credential probes and interpretation of available
permission evidence, using repository-scoped checks without requiring unrelated
account or administration scopes.
The internal contract supplies the logical operations needed to preflight
credentials, inspect a hosted tag, find or create a release, enumerate assets,
read asset content, and upload an asset. Release and asset references carry
backend-owned handles; shared orchestration works with logical identity and content rather than
interpreting Gitea's positive integer IDs.
The contract also carries the evidence needed for existing recovery behavior:
whether a write was attempted, whether its outcome is established or uncertain,
and actionable failure information. Generic code interprets delivery outcomes;
the adapter interprets protocol responses. A logical backend operation may
involve multiple HTTP requests.
The operations and values stay internal under the existing facade policy.
Current Gitea behavior is the concrete compatibility target. This work does
not establish compatibility guarantees for unimplemented forges or a public
plugin protocol.
## Behavioral scope and compatibility
The refactor preserves the existing Gitea delivery contracts for complete note
bodies, retained existing titles, stable release state, content conflicts,
unrelated attachments, additive retries, and source-only or binary delivery.
Read-only inspection failures and unresolved writes retain their distinct
outcomes. Recovery retains write history, including confirmed progress after
an ambiguous create. The current integration guide owns the concrete protocol
and follow-up lookup behavior.
Local verification reuse, streaming, cancellation, stream closure, temporary
build ownership, and upload cleanup remain part of the affected workflow.
Read-only credential preflight precedes expensive local artifact work; local
content verification still completes before hosted release or asset writes.
Credential environment/file selection and forbidden-file validation retain
their existing responsibilities. Backend-specific address validation stays
with that backend.
The public destination replacement, required forge selection, and earlier
credential failures are deliberate changes for the next minor release.
Migration guidance describes consumer edits under the project's direct-cutover
approach.
Current contract documents and examples change with implementation; historical
release notes retain their original contents.
Completion means shared delivery and asset policy have independent internal
ownership, Gitea implements the backend boundary, existing Gitea contracts work
through it, and the neutral public destination and explicit selection are
consistent across the API, configuration, examples, and documentation.
Credential preflight operates through the backend boundary in both library and
CLI delivery, with accurate failure distinctions and documented permission limits.
Additional forge implementations and compatibility claims belong to later work.
Release preparation and publication continue under the
[existing procedure](../release.md).