Plan the neutral forge delivery refactor

This commit is contained in:
2026-11-01 16:37:50 +00:00
parent 71746f437e
commit 44823ce323
2 changed files with 458 additions and 97 deletions

View File

@@ -1,6 +1,9 @@
# Roadmap: separate shared delivery from forge adapters
Status: proposed; implementation has not started.
Status: accepted; implementation has not started.
The [implementation plan](implementation.md) owns stages, concrete design
choices, task sequencing, and verification.
## Objective and scope
@@ -50,9 +53,9 @@ dependency direction.
### Neutral public destination and explicit forge selection
Replace `GiteaDestination` with a facade-owned neutral destination type, such as
`DeliveryDestination`, and require explicit forge selection in the public API
and delivery configuration. Gitea is the sole supported selection initially.
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.
@@ -101,101 +104,33 @@ Current Gitea behavior is the concrete compatibility target. This work does
not establish compatibility guarantees for unimplemented forges or a public
plugin protocol.
## Work required
## Behavioral scope and compatibility
### 1. Define the internal seam and dependency direction
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.
- Inventory the data and operations currently crossing from `internal/delivery`
into `internal/gitea`, including asset identities, inspections, failure
categories, release references, and write-attempt evidence.
- Introduce a small internal contract shared by orchestration and adapters.
Choose its package placement to keep dependencies acyclic. Exact private
package and method names can follow the implementation's responsibilities.
- Represent the observed release data needed by current comparisons without
making Gitea wire structures part of the generic model. Keep numeric-ID and
repository-path-segment validation with the Gitea implementation.
- Put concrete backend construction in composition code, using the explicitly
selected forge from the neutral public destination.
Local verification reuse, streaming, cancellation, stream closure, temporary
build ownership, and upload cleanup remain part of the affected workflow.
Credential environment/file selection and forbidden-file validation retain
their existing responsibilities. Backend-specific address validation stays
with that backend.
### 2. Extract shared policy and artifact mechanics
The public destination replacement and required forge selection are deliberate
API and configuration changes for the next minor release. Migration guidance
describes the consumer edits under the project's direct-cutover approach.
Current contract documents and examples change with implementation; historical
release notes retain their original contents.
- Move manifest generation and local content verification to shared internal
ownership, reusing the existing artifact package where appropriate.
- Move matching-page decisions, remote-content comparisons, missing-asset
selection, upload sequencing, reconciliation decisions, and result
aggregation out of the Gitea HTTP implementation.
- Preserve the current Gitea behavior for complete note bodies, existing page
titles, stable release state, content conflicts, unrelated attachments,
source-only delivery, and managed or prebuilt binary delivery.
- Preserve current write-history and uncertainty handling. In particular, a
read-only inspection failure and an unresolved write retain their distinct
meanings. Keep existing Gitea reconciliation behavior where the integration
contract specifies it, including the current follow-up lookup behavior.
- Retain the existing reuse of local verification and streamed content hashing
as responsibilities move. Preserve cancellation, stream closure, temporary
output ownership, and cleanup around uploads.
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.
### 3. Adapt Gitea and reconnect the facade and CLI
- Replace `GiteaDestination` with the neutral facade-owned destination and add
required forge selection to the public API and delivery profile. Validate
omitted, blank, and unsupported selections without assuming Gitea.
- Implement the internal contract with the Gitea client. Keep Gitea JSON
decoding, HTTP status interpretation, URL escaping, credential forwarding,
redirect behavior, and upload transport in the adapter.
- Map protocol errors into shared outcomes while retaining useful causes and
Gitea HTTP details. Preserve documented diagnostics and cancellation behavior;
use existing contracts to decide which wording or interactions are meaningful.
- Reconnect `Deliver`, CLI `deliver` and `ci-deliver`, managed builds, and
prebuilt delivery through the same shared workflow and concrete Gitea adapter.
- Continue resolving credentials in the CLI and passing them explicitly. Token
environment/file selection and forbidden-file validation retain their
existing responsibilities.
### 4. Align tests and documentation with ownership
- Retain Gitea HTTP fixture tests for routes, payloads, authentication,
pagination, escaping, redirects, malformed responses, and transport failures.
- Move tests of manifests, content comparison, conflict handling, and result
aggregation to the shared layer as those responsibilities move. Use small
controlled backends where protocol-independent recovery needs an external
boundary; reuse existing behavioral cases and consolidate redundant coverage.
- Retain representative public-facade and CLI workflows proving that Gitea
page-only delivery, binary delivery, tagged retries, and failure reporting
continue to work through the assembled boundary with explicit Gitea selection.
Cover missing, blank, and unsupported selections in destination validation.
- Update the internal inventory and delivery documentation when implementation
lands. Keep Gitea protocol details in the integration guide and shared
orchestration details in internal documentation. Update public GoDoc,
configuration, examples, and ReleaseKit's own profile for the neutral
destination and explicit Gitea selection. Supply migration guidance in the
next minor release for the public type replacement and profile changes,
consistent with the project's direct-cutover approach.
- Record the accepted architectural boundary in an ADR when its design is
settled, following the [documentation policy](../policy/documentation.md#architecture-decision-records).
## Verification and completion
Follow the [testing policy](../policy/testing.md) and reuse existing tests where
they protect the relevant behavior. Run focused checks while moving
responsibilities, then the complete offline suite and compiled
API/dependency-boundary checks from the [development guide](../development.md#validation).
The final full-suite run also covers the affected executable workflows.
Review the resulting imports and data flow as well as test results: generic
orchestration and artifact policy should consume the internal contract, with
Gitea transport selected through composition. Exercise an internal test backend
at that seam to verify that shared logic can operate independently of the Gitea
client. Keep the test collaborator proportionate to the cases it protects.
Completion means the shared workflow and asset policy have independent internal
ownership, the Gitea adapter implements the boundary, the existing Gitea
contracts pass through that boundary, and documentation describes the resulting
structure. The neutral public destination and required forge selection are
reflected consistently in declarations, profiles, examples, and migration
guidance.
This is an architectural refactor of the implemented Gitea delivery path.
Support claims and compatibility testing for additional forges belong to the
work that implements those backends. Release preparation and publication
continue under the [existing procedure](../release.md).
Additional forge implementations and compatibility claims belong to later work.
Release preparation and publication continue under the
[existing procedure](../release.md).