Retire completed roadmaps and preserve adoption work
This commit is contained in:
13
README.md
13
README.md
@@ -7,9 +7,8 @@ tagged-source delivery API, and `version`, `check`, `publish`, `build`, and
|
||||
`deliver` commands are implemented. ReleaseKit's source-only maintainer
|
||||
procedure and prepared Woodpecker workflow for hosted note-page delivery are
|
||||
documented. ReleaseKit does not declare binary deliverables. The
|
||||
[product roadmap](docs/roadmap/releasekit.md) and
|
||||
[implementation plan](docs/roadmap/implementation.md) describe their selected
|
||||
behavior and sequence.
|
||||
[product roadmap](docs/roadmap/releasekit.md) records remaining adoption and
|
||||
deployment work.
|
||||
|
||||
Run the offline Go test suite from the repository root with:
|
||||
|
||||
@@ -41,8 +40,8 @@ failure recovery.
|
||||
|
||||
## Documentation
|
||||
|
||||
- [ReleaseKit proposal](docs/roadmap/releasekit.md): selected publication, builds,
|
||||
version injection, and delivery conventions, with the implementation plan.
|
||||
- [Product roadmap](docs/roadmap/releasekit.md): consumer adoption goals and
|
||||
remaining release and deployment work.
|
||||
- [Contributor guide](docs/development.md): orientation, validation, and selective
|
||||
policy reading.
|
||||
- [CLI contract](docs/cli.md): the `version`, `check`, `publish`, `build`, and
|
||||
@@ -65,8 +64,8 @@ failure recovery.
|
||||
- [Architecture policy](docs/policy/architecture.md): responsibility and dependency
|
||||
boundaries for development.
|
||||
- [ADR 0001](docs/adr/0001-public-facade.md): the accepted public facade decision.
|
||||
- [Policy adoption roadmap](docs/roadmap/policy.md): completed adoption and the
|
||||
current source-release path.
|
||||
- [Policy provenance](docs/policy/meta.md): adopted policy sources and update
|
||||
guidance.
|
||||
|
||||
ReleaseKit is licensed under the [LGPL v3.0 or later](COPYRIGHT).
|
||||
|
||||
|
||||
@@ -50,8 +50,9 @@ go run ./internal/apicheck
|
||||
```
|
||||
|
||||
See the [candidate check guide](consumers/check.md), [build consumer guide](consumers/build.md),
|
||||
[internal package inventory](internal/overview.md), and [implementation plan](roadmap/implementation.md)
|
||||
for current implementation progress.
|
||||
and [internal package inventory](internal/overview.md) for implemented behavior
|
||||
and capability ownership. The [product roadmap](roadmap/releasekit.md) records
|
||||
remaining adoption and deployment work.
|
||||
|
||||
For prose changes, review the diff and check local links, fragment destinations,
|
||||
provenance, template residue, and consistency with current repository contents.
|
||||
|
||||
@@ -1,997 +0,0 @@
|
||||
# ReleaseKit staged implementation plan
|
||||
|
||||
Status: Complete. Stages 1–18 are complete.
|
||||
|
||||
Date: 2026-10-05
|
||||
|
||||
## Purpose and baseline
|
||||
|
||||
This plan gives a Luna coding agent bounded implementation assignments, in
|
||||
execution order, for the target state in the [feature roadmap](releasekit.md).
|
||||
The roadmap owns product intent and selected release conventions. This document
|
||||
owns implementation steps, dependencies, acceptance evidence, and progress.
|
||||
|
||||
The baseline is ReleaseKit commit `6c2695f`. It contains documentation, adopted
|
||||
policies, licensing notices, and [ADR 0001](../adr/0001-public-facade.md). It has
|
||||
no Go module, packages, executable, tests, or publication automation. The
|
||||
worktree was clean when this plan was prepared. The available tools were Go
|
||||
1.26.8 on linux/amd64 and Git 2.53.0; these observations are not minimum support
|
||||
requirements.
|
||||
|
||||
The six sibling checkouts provide design evidence; this implementation sequence
|
||||
changes ReleaseKit only. Consumer migrations and measurement of deleted consumer
|
||||
infrastructure belong to later adoption work. Consult code through the knowledge
|
||||
graph, indexing a repository when necessary. Documents, scripts, and CI
|
||||
configuration may be read directly under the discovery instructions.
|
||||
|
||||
## Scope and completion
|
||||
|
||||
Deliver the complete initial library, executable, configuration, shared build
|
||||
and delivery mechanics, Woodpecker examples, and ReleaseKit's own prepared
|
||||
release wiring. Hosted Gitea release pages are part of the selected standard
|
||||
for every project, including source-only projects. Source-only delivery uses
|
||||
the committed release note and zero binary assets; it needs no binary build or
|
||||
checksum manifest.
|
||||
|
||||
Proceed through all stages using the local checkout and controlled fixtures.
|
||||
No stage depends on an intermediate release, published tool/runtime pin,
|
||||
consumer pilot, external service action, or human review. Ordinary automated
|
||||
development checks accompany implementation under the testing policy.
|
||||
|
||||
After the complete initial implementation, the maintainer will review the
|
||||
architecture, address discovered issues, and then choose the broader testing
|
||||
plan and next steps. Consumer adoption, live integration testing, secret
|
||||
provisioning, CI activation, and actual publication are outside this sequence.
|
||||
|
||||
## Execution instructions
|
||||
|
||||
- Implement stages in integer order. Each stage is one assignment; finish its
|
||||
acceptance checks and local commit before starting the next stage. Record
|
||||
completed work and evidence here. Read the stage's dependencies and relevant
|
||||
decisions before editing.
|
||||
- Start with the [developer guide](../development.md) and applicable policies.
|
||||
Architecture, testing, documentation, and release policies apply to the core
|
||||
implementation. Read the OSS policy when incorporating third-party material.
|
||||
- Follow the [architecture policy](../policy/architecture.md) and ADR 0001.
|
||||
Add exported declarations as their behavior is implemented, with GoDoc.
|
||||
Implement the selected contract with proportionate internal collaborators.
|
||||
- The design choices below specify this draft's recommended implementation.
|
||||
Apply the selected scope and decisions throughout the sequence. Later
|
||||
agent-authored code or tests provide evidence of implementation, rather than
|
||||
independent authority to strengthen the contract.
|
||||
- For each stage, run focused behavioral checks for its changed risks and the
|
||||
established offline default suite. Reuse unchanged evidence where appropriate.
|
||||
Stage acceptance checks are development checks; they add no publication gates
|
||||
beyond the release policy and a repository's selected candidate checks.
|
||||
- Use temporary repositories, local bare remotes, test programs, and local HTTP
|
||||
servers. Keep fixtures independent of the six consumer checkouts and real
|
||||
services. Temporary fixture module replacements may connect test programs to
|
||||
this checkout; keep them outside committed production module configuration.
|
||||
- Update canonical documentation with each implemented responsibility. Create
|
||||
consumer, CLI, configuration, integration, and internal documents when they
|
||||
have substantive content. Keep future behavior and stage progress here.
|
||||
- Keep the implementation self-contained. Build the tool from this checkout;
|
||||
temporary fixture modules may use local replacements. Integration templates
|
||||
accept an operator-selected immutable tool pin for later deployment, without
|
||||
requiring one to complete this plan or claiming that a release already exists.
|
||||
- Complete stages with local implementation commits and controlled checks.
|
||||
Prepare runnable automation and deployment instructions without activating
|
||||
live workflows. Distinguish implemented integration from verified live use.
|
||||
Finish the whole sequence before the maintainer's architecture review; add no
|
||||
intermediate approval or external-action checkpoint.
|
||||
|
||||
## Implementation decisions
|
||||
|
||||
### Module, runtime access, and public ownership
|
||||
|
||||
Use one module, `gitea.maximumdirect.net/eric/ReleaseKit`, preserving the case
|
||||
advertised by the forge's Go import metadata. Set the initial Go language
|
||||
baseline to `go 1.25.0`, matching the oldest consumer module line. Use APIs
|
||||
available on that baseline. Actual execution uses a prepared local toolchain
|
||||
capable of building the consumer; Narratio already needs Go 1.26. There is no
|
||||
mandatory multi-toolchain release matrix.
|
||||
|
||||
The supported packages are the root `releasekit` facade and `buildinfo`. Put
|
||||
the executable at `cmd/releasekit`. Start with standard-library implementations
|
||||
and the installed Git and Go executables. Introduce internal packages as their
|
||||
responsibilities land: runtime information, process execution, release engine,
|
||||
Git operations, builds, Gitea transport, and CLI adaptation. Put command-owned
|
||||
parsing and file-format helpers under `cmd/releasekit/internal/cli`; keep facade
|
||||
calls in the `cmd/releasekit` controller. Those helpers return their own settings
|
||||
for explicit conversion by the controller and import neither public facade.
|
||||
The executable therefore consumes the supported APIs while library internal
|
||||
packages retain inward dependencies. There are no public transport clients or
|
||||
assembly APIs.
|
||||
|
||||
The initial runtime API is `buildinfo.Version() string`. It returns an injected
|
||||
release identifier when supplied; otherwise it uses the running executable's
|
||||
main-module version when present and different from `(devel)`, then `dev` when
|
||||
that metadata is unavailable. This supports source installs as well as explicit
|
||||
release builds. It describes the application version, not the ReleaseKit
|
||||
dependency version. [Go build information](https://pkg.go.dev/runtime/debug#ReadBuildInfo)
|
||||
documents the main-module metadata available to implement this fallback.
|
||||
|
||||
Keep the injected string private in the internal runtime implementation. Keep
|
||||
the linker symbol identifier in a small internal contract used by the builder.
|
||||
The builder and runtime implementation change together. Consumers call the
|
||||
accessor; their configuration supplies no linker symbol. The runtime import
|
||||
graph uses the standard library and small runtime implementation, independent
|
||||
of orchestration. A tool/runtime version mismatch must be exposed by the native
|
||||
version smoke check; do not introduce an exact dependency-version equality gate.
|
||||
|
||||
### Orchestration API
|
||||
|
||||
Implement these root operations as the corresponding stages land:
|
||||
|
||||
| Operation | Request and result responsibilities |
|
||||
| --- | --- |
|
||||
| `Check(ctx, ReleaseRequest)` | Capture and validate a local committed candidate; return its commit and version. This diagnostic operation does not query publication services, create a tag, or claim remote readiness. |
|
||||
| `Publish(ctx, ReleaseRequest)` | Validate once, check authoritative state, create and publish the selected annotated tag, and return publication state and retained recovery facts. |
|
||||
| `Build(ctx, BuildRequest)` | Build the selected targets with the requested version, verify a native version invocation, and return source identity and generated artifacts. |
|
||||
| `Deliver(ctx, DeliveryRequest)` | Verify tagged source and supplied artifact identity, create or find a hosted release, compare content, and add missing assets with explicit partial or uncertain outcomes. |
|
||||
|
||||
Each operation returns a facade-owned result and an error. Requests carry the
|
||||
repository directory explicitly. `ReleaseRequest` also carries the display
|
||||
product name, version, selected remote, optional validation callback, optional
|
||||
build specification, and optional output writer. The remote defaults to
|
||||
`origin`; publication uses `main`. The callback receives a facade-owned
|
||||
`Candidate` containing directory, captured commit, and selected version. A nil
|
||||
callback selects the default Go test invocation. A supplied callback replaces
|
||||
that invocation with the repository's complete selected validation; it is
|
||||
called once. The CLI adapts configured commands into this callback.
|
||||
|
||||
A build specification carries main package, binary name, and targets. Each
|
||||
facade-owned `Target` contains Go OS and architecture strings. A build request
|
||||
adds version and output directory. A delivery request identifies version,
|
||||
product, repository directory, Gitea destination, and optional build result.
|
||||
The Gitea destination carries base URL, owner, repository name, and caller-supplied
|
||||
token. Library code obtains no credentials from ambient configuration. Before
|
||||
the first remote write, an inspection failure reports that this invocation has
|
||||
not attempted mutation. Reserve uncertain-mutation classification and exit 3
|
||||
for writes whose authoritative outcome remains unresolved.
|
||||
|
||||
Publication results identify version, candidate commit, captured endpoint,
|
||||
phase, and tag object when created. Use distinct states for `not_attempted`,
|
||||
`not_published`, `published`, `conflict`, and `unknown`. These describe this
|
||||
invocation; a pre-existing remote release is not described as unpublished.
|
||||
Delivery results identify release URL and the matching, uploaded, pending, and
|
||||
uncertain assets, with `not_attempted`, `complete`, `partial`, `conflict`, or
|
||||
`unknown` state. Ordinary errors preserve useful causes through wrapping.
|
||||
Document exactly when nonzero results accompany errors. Add only the named
|
||||
types needed to represent these responsibilities; field spelling and internal
|
||||
package layout can follow idiomatic Go without changing the decisions here.
|
||||
|
||||
### CLI and configuration
|
||||
|
||||
Use standard-library flag parsing and JSON configuration. The default profile
|
||||
is `<repository>/releasekit.json`; `--config` selects another file. Configuration
|
||||
paths are resolved from the selected repository, whose default is the current
|
||||
directory. A profile supplies product identity, remote, candidate commands,
|
||||
optional build specification, and optional Gitea delivery declaration. The
|
||||
command supplies the version rather than persisting it in the profile.
|
||||
|
||||
This composite profile shows the implemented fields together; working
|
||||
[source-only](../../examples/releasekit.json) and
|
||||
[binary-producing](../../examples/releasekit-binary.json) profiles are maintained
|
||||
under `examples/`:
|
||||
|
||||
```json
|
||||
{
|
||||
"product": "Scriptorium",
|
||||
"remote": "origin",
|
||||
"checks": [{"args": ["sh", "scripts/check-release-candidate.sh"]}],
|
||||
"build": {
|
||||
"main_package": "./cmd/scriptorium",
|
||||
"binary_name": "scriptorium",
|
||||
"targets": ["linux/amd64", "linux/arm64"]
|
||||
},
|
||||
"delivery": {
|
||||
"base_url": "https://gitea.maximumdirect.net",
|
||||
"owner": "eric",
|
||||
"repository": "scriptorium",
|
||||
"token_env": "GITEA_RELEASE_TOKEN"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Command entries also accept an `env` map. Run argument vectors directly, without
|
||||
implicit shell parsing. A repository that needs shell syntax selects `sh` or
|
||||
`bash` explicitly. Run commands in the captured repository directory and supply
|
||||
`RELEASEKIT_VERSION` and `RELEASEKIT_CANDIDATE` for candidate-specific checks.
|
||||
Those captured values take precedence over conflicting command environment
|
||||
entries. Inherit the remaining environment and overlay explicitly owned values
|
||||
without mutating the caller process.
|
||||
|
||||
An absent or empty check list selects `go test -count=1 ./...`; a nonempty list
|
||||
is the repository's complete validation sequence. Decode profile fields
|
||||
strictly so unsupported build or delivery settings cannot silently disappear
|
||||
from the selected checks. Validate required values for the operation being run;
|
||||
source-only checks and publication need neither a main package nor credentials.
|
||||
Hosted page delivery requires a destination and token for source-only profiles
|
||||
as well as binary-producing profiles.
|
||||
The CLI loads the token named by `delivery.token_env`, defaulting to
|
||||
`RELEASEKIT_GITEA_TOKEN`, only for delivery. Build receipt identity covers resolved
|
||||
build inputs; delivery credentials, destination, and unrelated check settings
|
||||
are excluded from that identity.
|
||||
|
||||
The eventual command forms are:
|
||||
|
||||
```text
|
||||
releasekit version
|
||||
releasekit check [--repo DIR] [--config FILE] VERSION
|
||||
releasekit publish [--repo DIR] [--config FILE] VERSION
|
||||
releasekit build [--repo DIR] [--config FILE] [--output DIR] VERSION
|
||||
releasekit deliver [--repo DIR] [--config FILE] [--assets DIR] VERSION
|
||||
```
|
||||
|
||||
Flags precede the positional version. `version` prints `releasekit <version>`.
|
||||
Use exit 0 for completed success, 1 for a known failure or conflict, 2 for usage
|
||||
or invalid configuration, and 3 for an uncertain remote mutation. Library
|
||||
outcomes retain more detail. Send validation progress and diagnostics to stderr;
|
||||
stdout presents the command's final result. Signals cancel the operation through
|
||||
its context. There is no interactive confirmation loop.
|
||||
|
||||
### Candidate checks and Git publication
|
||||
|
||||
Parse stable versions using the roadmap's exact syntax. Validate decimal
|
||||
components as strings without introducing a machine-integer size limit. Read
|
||||
the release note from the captured commit at `docs/releases/<version>.md`. Its
|
||||
first line must be a Markdown H1 containing the configured product name and
|
||||
exact version as complete title elements. Preserve the note content for the annotated tag.
|
||||
The shared tool imposes no additional note section inventory.
|
||||
|
||||
`Check` checks a clean worktree and index on `main`, captures HEAD, checks the
|
||||
committed note and unused local version, runs validation and selected builds,
|
||||
and rechecks local mutable state. `Publish` adds authoritative endpoint and
|
||||
remote branch/tag checks before validation and immediately before publication.
|
||||
Cleanliness includes untracked files; ordinary Git ignore rules still apply.
|
||||
Snapshot resolved request values and CLI profile content for the invocation so
|
||||
configuration is not reloaded into different checks midway through the run.
|
||||
Source changes remain subject to the ordinary candidate rechecks. The Go API
|
||||
accepts caller-supplied values without requiring a particular profile file.
|
||||
|
||||
Resolve the selected remote's effective push destination using Git's own remote
|
||||
configuration semantics. A missing destination or more than one distinct
|
||||
effective publication destination is an actionable configuration error because
|
||||
this operation needs one authoritative endpoint. A separate fetch URL is
|
||||
supported. Inspect the publication endpoint,
|
||||
rather than assuming the selected remote's normal fetch URL is authoritative.
|
||||
|
||||
Use a transient, command-scoped named remote with explicit read and push URLs
|
||||
and mirror mode disabled. Verify that both effective URLs equal the captured
|
||||
publication destination after Git URL rewriting. Reuse that scoped remote for
|
||||
queries and push; persist no new remote configuration. Retain normal Git
|
||||
credential and transport settings, carrying remote-specific transport settings
|
||||
into the scoped remote as needed. If rewriting prevents establishing this
|
||||
equality, report the unresolved destination before mutation.
|
||||
Recheck the original remote resolution before pushing. Test ordinary
|
||||
`insteadOf`, `pushInsteadOf`, and explicit push-URL cases using local remotes.
|
||||
[Git's remote documentation](https://git-scm.com/docs/git-remote) describes the
|
||||
effective URL lookup on which this relies.
|
||||
|
||||
Use exact ref names in remote queries. Require authoritative `main` to equal
|
||||
the captured candidate and the selected tag to be absent. Create the annotated
|
||||
tag from the committed note with signing disabled for this invocation, inspect
|
||||
its object type and peeled commit, then freeze its object ID. Push
|
||||
`<tag-object-id>:refs/tags/<version>` with automatic following of tags and mirror
|
||||
defaults disabled. Publish no branch updates, unrelated tags, or force updates.
|
||||
|
||||
A successful push returns immediately as published. After a failed or ambiguous
|
||||
push, make one authoritative tag query: an exact object match confirms success;
|
||||
absence confirms not published at observation; a different object is conflict;
|
||||
an unavailable or uninterpretable answer is unknown. Retain the local tag in
|
||||
all failed or uncertain cases. Caller cancellation after push starts also needs
|
||||
this bounded reconciliation attempt using a separate finite recovery context.
|
||||
Use a 30-second recovery deadline as an operational default, not a guarantee
|
||||
that the endpoint will respond. Cancellation before push does not initiate it.
|
||||
|
||||
The last remote branch check is an observation before the tag push. This design
|
||||
provides no transaction locking remote `main` against concurrent writers. Do not
|
||||
add branch pushes or assert stronger concurrency guarantees in tests.
|
||||
|
||||
### Go execution, builds, and assets
|
||||
|
||||
For ReleaseKit-owned candidate Go commands and builds, use prepared dependencies
|
||||
and a local toolchain. Set child environment values `GOWORK=off`, `GOPROXY=off`,
|
||||
`GONOPROXY=none`, `GOSUMDB=off`, and `GOTOOLCHAIN=local`. Set module mode to
|
||||
readonly, preserving a repository's deliberately selected testing flags.
|
||||
ReleaseKit-owned builds replace ambient `GOFLAGS` with `-mod=readonly` and use
|
||||
their explicit build arguments; custom validation commands retain their
|
||||
deliberately configured flags.
|
||||
Preparation of caches and tools occurs separately. These settings do not
|
||||
sandbox arbitrary repository callbacks or establish a general network firewall.
|
||||
|
||||
Build with `CGO_ENABLED=0`, `-mod=readonly`, `-trimpath`, `-buildvcs=false`, and
|
||||
linker flags `-s -w` plus the shared version injection. This selects the pure-Go
|
||||
build convention already used by the current asset builders. Additional cgo
|
||||
toolchains remain outside this implementation. The injected string must use a
|
||||
linker-supported initializer. [Go's linker documentation](https://pkg.go.dev/cmd/link)
|
||||
defines the `-X` mechanism.
|
||||
|
||||
Initially verify linux/amd64, linux/arm64, and darwin/arm64. Represent targets
|
||||
as values rather than a closed enum; other explicit Go OS/architecture pairs
|
||||
can be passed to the prepared compiler and may fail according to its support.
|
||||
This establishes no native-execution promise for other platforms.
|
||||
|
||||
Asset names are `<binary-name>-<version>-<goos>-<goarch>`, with `.exe` when the
|
||||
requested Go OS needs it. Binary names and target components must be nonempty
|
||||
filename components without path separators, backslashes, CR, or LF, so names
|
||||
stay in the output directory and have unambiguous manifest entries. Normalize
|
||||
repeated target pairs to one target, retaining their first position. Distinguish
|
||||
the display product name used by notes from this binary name. Preserve selected
|
||||
target order for progress; generate manifests in filename order.
|
||||
|
||||
For nonempty targets, invoke the built application with `version` and require
|
||||
`<binary-name> <version>` plus a final newline. Reuse a target artifact when it
|
||||
matches `GOHOSTOS/GOHOSTARCH`; otherwise build a temporary native executable
|
||||
with the same flags and injection. Determine the host independently of ambient
|
||||
`GOOS/GOARCH`. Native smoke binaries are temporary and are not extra assets.
|
||||
An empty target set performs no Go build or version invocation. Source-only
|
||||
projects may retain an explicitly selected application check; no binary check
|
||||
is silently imposed on them.
|
||||
|
||||
Candidate build checks use a temporary output directory outside the worktree
|
||||
and discard it. Artifact builds record the commit, version, main package,
|
||||
targets, compiler identity, and generated filename/hash pairs. Return these
|
||||
facts in `BuildResult`. The CLI persists them in an internal local receipt,
|
||||
`.releasekit-build.json`, alongside the generated files after a successful
|
||||
complete build and smoke check. A partial build returns progress without a
|
||||
receipt authorizing delivery. This receipt is for tool coordination, with no
|
||||
public format or attestation promise. It contains no credentials and is not a
|
||||
hosted asset. Build output defaults to `dist`; create
|
||||
the directory as needed, regenerate owned local filenames, and preserve
|
||||
unrelated files. Report generated files on partial local failure and clean up
|
||||
only tool-owned temporary paths.
|
||||
|
||||
Delivery uses a clean checkout whose HEAD equals the selected local tag's peeled
|
||||
commit; detached HEAD is valid. Read the note from that commit and snapshot the
|
||||
selected settings. Repository-local tracked profiles come from that source;
|
||||
explicit caller-supplied settings are identified in the build result. Verify
|
||||
the hosted repository already has the same tag targeting that commit before
|
||||
creating a release. Existing lightweight historical tags may be inspected and
|
||||
delivered; new publication follows the annotated-tag standard. Do not require
|
||||
current remote `main` to remain at an old release commit during delivery retries.
|
||||
|
||||
The CLI's `deliver --assets DIR` consumes a verified build receipt and checks
|
||||
file hashes, selected filenames, and source/build-input identity before remote
|
||||
mutation. When no directory is supplied, build into a temporary directory from
|
||||
the tagged checkout and then deliver. With zero targets, hosted delivery creates
|
||||
the required note page without a binary manifest or build receipt. An absent
|
||||
build specification is equivalent to zero targets for source-only delivery.
|
||||
Neither mode reruns the candidate test suite or changes source-publication status.
|
||||
|
||||
### Hosted delivery and Woodpecker
|
||||
|
||||
Use a small internal standard-library Gitea REST client. On 2026-10-05 the host's
|
||||
[version endpoint](https://gitea.maximumdirect.net/api/v1/version) reported Gitea
|
||||
1.25.4; its [served API schema](https://gitea.maximumdirect.net/swagger.v1.json)
|
||||
confirmed release-by-tag lookup, JSON release creation, asset listing, and
|
||||
multipart attachment upload. Implement the operations described here against
|
||||
local fixtures and record them in the integration guide. Verification against
|
||||
the deployed host belongs to later live testing and is not needed to complete
|
||||
this sequence. This observation is not an all-version Gitea compatibility promise.
|
||||
|
||||
Read the tag through `/api/v1/repos/{owner}/{repo}/tags/{tag}` and verify its
|
||||
`commit.sha`. Use the repository API prefix for each following operation. Find
|
||||
the release through `/releases/tags/{tag}`. Create it through
|
||||
`POST /releases` with the existing tag, captured commit, title from the note's
|
||||
H1, complete committed note as body, and stable, non-draft settings. A found
|
||||
release must match the note body and tag and be stable/non-draft; retain its
|
||||
existing title, including a historical title chosen by other tooling. A content
|
||||
conflict is reported; its body, title, assets, and tag are not edited. Existing
|
||||
historical pages remain intact.
|
||||
|
||||
List attachments through `/releases/{id}/assets`. Identify expected filenames
|
||||
and stream their downloads to compare SHA-256 content; size and name alone do
|
||||
not prove a match. Use multipart field `attachment` and the filename query
|
||||
parameter for missing uploads. The client obtains no automatic tag-creation
|
||||
responsibility. Keep authorization on the configured service origin when
|
||||
following attachment URLs or redirects; never include token values in receipts
|
||||
or diagnostics.
|
||||
|
||||
For nonempty binary sets, generate `SHA256SUMS` with lowercase hashes, two spaces,
|
||||
filenames, and LF-terminated lines, sorted by filename. It describes the complete
|
||||
declared binary set and excludes itself and the private receipt. An existing
|
||||
manifest must match that expected content. Fill missing assets covered by that
|
||||
manifest only with matching bytes. A manifest describing a different or smaller
|
||||
set cannot be replaced to extend that version. Leave unrelated attachments
|
||||
untouched.
|
||||
|
||||
Inspect all known declared asset and manifest conflicts before uploading.
|
||||
Upload missing binaries in filename order, then a missing manifest. HTTP writes
|
||||
are separate operations. After an ambiguous creation or upload, re-read the
|
||||
affected resource once; classify matching content as completed, conflict as
|
||||
conflict, and inaccessible or still-indeterminate content as unknown. Handle
|
||||
concurrent creation by finding and verifying the created resource. Do not
|
||||
blindly retry writes or delete attachments. Record partial progress so an
|
||||
operator can rerun against the same tag and retained assets.
|
||||
|
||||
Woodpecker uses tag-triggered repository-local YAML with a pinned Go image
|
||||
and an explicit tool preparation step. Provide source-only and binary-producing
|
||||
examples. Consumer templates accept an operator-selected immutable ReleaseKit
|
||||
source pin for deployment; template preparation and local execution use the
|
||||
implementation checkout and require no published pin. Prepare consumer module
|
||||
caches separately, then run builds and delivery with offline Go execution.
|
||||
This honors ReleaseKit's source-only distribution; a dedicated ReleaseKit
|
||||
container image would require a separate deliverable decision. Use a Go image
|
||||
that satisfies the repository's module requirements.
|
||||
|
||||
ReleaseKit's own prepared workflow builds `cmd/releasekit` from its tagged
|
||||
checkout using the local toolchain and delivers its hosted note page. It needs
|
||||
no previously released executable and produces no distributed binary assets.
|
||||
Prepare this workflow locally; activation belongs to the later next-step plan.
|
||||
|
||||
Use `CI_COMMIT_TAG` and `CI_COMMIT_SHA` to bind the workflow to tagged source,
|
||||
with an explicit tag fetch when the checkout omits local tag refs. For binary
|
||||
profiles, the build step writes to ignored `dist` and the delivery step shares
|
||||
the workspace. Source-only workflows call delivery directly without an artifact
|
||||
build step. Supply the Gitea token only to delivery from a Woodpecker secret.
|
||||
Document operator substitution of image digests and source pins for eventual
|
||||
consumer deployment. Pipeline preparation may access dependency services;
|
||||
candidate validation and builds use the prepared caches. CI does not call
|
||||
`publish`, push refs, or gate source completion. The supported retry is a rerun
|
||||
from the same tagged source with content comparison; reproducible bytes across
|
||||
arbitrary toolchains or elapsed time are not promised.
|
||||
|
||||
## Stage 1: Establish the Go module and development baseline
|
||||
|
||||
Status: Complete. Depends on the baseline only.
|
||||
|
||||
1. Add the module with the selected path and language baseline. Add root package
|
||||
documentation for the orchestration facade and establish ordinary Go layout.
|
||||
2. Keep committed module state independent of sibling checkouts and workspaces.
|
||||
Start without external runtime dependencies or a generic plugin framework.
|
||||
3. Add the working offline developer test command and initial implemented-package
|
||||
inventory. Update README to its actual implemented boundary.
|
||||
|
||||
Acceptance: module loading and `go test ./...` work with the prepared local
|
||||
toolchain and network disabled. Review module identity and licensing notices.
|
||||
Do not invent tests merely to assert that an empty package exists.
|
||||
|
||||
Completion evidence: added the Go 1.25.0 module and documented root facade,
|
||||
updated the README and developer guide to describe the implemented boundary and
|
||||
offline test command, and confirmed module loading and `go test ./...` with
|
||||
network access disabled. The module has no external dependencies; existing
|
||||
LGPL licensing and attribution notices remain consistent.
|
||||
|
||||
## Stage 2: Implement the runtime version facade
|
||||
|
||||
Status: Complete. Depends on Stage 1.
|
||||
|
||||
1. Implement `buildinfo.Version` and its internal injected-string and main-module
|
||||
fallback logic. Keep runtime state private and the public accessor small.
|
||||
2. Add the internal injection-symbol contract without importing orchestration
|
||||
into the runtime path. Test injected precedence and missing/development
|
||||
metadata through stable internal seams and a small executable fixture.
|
||||
3. Add `cmd/releasekit` with a working `version` command using this accessor.
|
||||
Record its implemented command contract and the runtime consumer guidance.
|
||||
|
||||
Acceptance: a source-built fixture reports `dev`; a fixture linked with a stable
|
||||
version reports that version. Fallback metadata uses the executable main module.
|
||||
CLI version output is correct and no runtime orchestration initialization occurs.
|
||||
|
||||
Completion evidence: implemented `buildinfo.Version`, its private injected
|
||||
string and main-module fallback, and the internal linker-symbol contract. Unit
|
||||
tests cover injection precedence and missing, development, and stable main
|
||||
module metadata. Built and ran a separate consumer executable from source and
|
||||
with an injected stable version using network-disabled Go commands; both
|
||||
reported the selected value. CLI tests cover its version line, and the CLI's
|
||||
dependency closure contains no orchestration package. Added runtime consumer
|
||||
guidance and documented the command contract.
|
||||
|
||||
## Stage 3: Protect public contracts and dependency direction
|
||||
|
||||
Status: Complete. Depends on Stage 2.
|
||||
|
||||
1. Add a compiled-export boundary checker for both facades using `go list` export
|
||||
data and `go/types`. Inspect exported signatures, fields, callbacks, aliases,
|
||||
generic constraints, and pointer/value method sets recursively.
|
||||
2. Assert facade ownership of public named types. Permit deliberately selected
|
||||
standard-library contracts. Protect the private-state forwarding approach
|
||||
against leaked internal types and promoted implementation methods.
|
||||
3. Add import-direction checks: internal production packages use internal
|
||||
contracts; the runtime facade's dependency closure excludes orchestration,
|
||||
process, build, Gitea, and CLI implementation.
|
||||
4. Use small negative fixtures proving that the checker catches a leaked type
|
||||
and promoted internal method, and accepts a private implementation field.
|
||||
|
||||
Acceptance: actual exports pass and meaningful negative fixtures fail. Tests
|
||||
inspect contracts and imports, with no fixed inventory of future internal
|
||||
package names. Extend these checks as subsequent exports land.
|
||||
|
||||
Completion evidence: added `internal/apicheck`, which loads compiled exports
|
||||
from `go list -deps -export` and inspects signatures, fields, aliases, generic
|
||||
constraints, and pointer and value method sets through `go/types`. The checks
|
||||
pass for both public facades and enforce internal import direction and the
|
||||
runtime dependency boundary. Negative fixtures detect leaked types, aliases,
|
||||
callbacks, generic constraints, and promoted implementation methods; a private
|
||||
implementation field and selected standard-library contracts pass. Added the
|
||||
checker command and internal package inventory to the canonical developer docs.
|
||||
|
||||
## Stage 4: Implement profile loading and command adaptation
|
||||
|
||||
Status: Complete. Depends on Stage 3.
|
||||
|
||||
1. Implement JSON product, remote, and command settings under an internal CLI
|
||||
adapter. Add strict field decoding, directory resolution, required-value
|
||||
diagnostics, direct argument execution, and per-child environment overlays.
|
||||
2. Implement an internal cancellable process runner with directory, argument,
|
||||
environment, stdout, stderr, and exit-error support. Use `os/exec` directly;
|
||||
expose no public runner abstraction solely for test assembly.
|
||||
3. Add CLI parsing infrastructure and selected usage/exit behavior. Advertise
|
||||
commands only when their following stages implement them.
|
||||
4. Add small profile examples and `docs/config.md` for implemented fields.
|
||||
|
||||
Acceptance: paths and arguments containing spaces remain separate arguments;
|
||||
selected environment values reach the child without changing process globals;
|
||||
missing executables, invalid configuration, and cancellation report useful
|
||||
errors. Tests use controlled local child commands and temporary directories.
|
||||
|
||||
Completion evidence: added strict profile decoding, repository-relative and
|
||||
absolute profile resolution, required product and command diagnostics, and
|
||||
direct check argument adaptation. Added a cancellable `os/exec` runner with
|
||||
working directory, inherited environment plus child-only overlays, stdout,
|
||||
stderr, and preserved exit errors. Tests cover spaced paths and arguments,
|
||||
environment isolation, missing executables, exit failures, cancellation, and
|
||||
invalid profiles. Added a profile example and canonical CLI, configuration, and
|
||||
internal package documentation.
|
||||
|
||||
## Stage 5: Capture and validate one local candidate
|
||||
|
||||
Status: Complete. Depends on Stage 4.
|
||||
|
||||
1. Implement stable-version syntax, clean `main` and index/worktree inspection,
|
||||
captured HEAD, profile snapshot/note loading, title identity, and unused local
|
||||
tag checks. Preserve immutable candidate facts in internal values.
|
||||
2. Implement default offline Go validation and callback adaptation. Bind the
|
||||
callback to the captured candidate; pass captured version/commit to CLI
|
||||
commands. Call the complete validation callback once, stopping on failure.
|
||||
3. Recheck branch, HEAD, and cleanliness after validation. Retain the captured
|
||||
settings throughout the operation. Implement the public `Check` operation
|
||||
and local diagnostic `check` command.
|
||||
4. Document that local check success provides local candidate evidence and makes
|
||||
no authoritative remote availability claim.
|
||||
|
||||
Acceptance: temporary repositories cover invalid versions, missing or mismatched
|
||||
committed notes, dirty tracked/untracked state, existing local tags, detached
|
||||
HEAD, callback failure, and a callback changing HEAD or the worktree. Count a
|
||||
successful callback once. No test needs a publication service, and `Check`
|
||||
creates no tag or remote ref.
|
||||
|
||||
Evidence: `internal/candidate` validates stable versions and committed note
|
||||
identity, captures a clean `main` commit, runs either the offline default or the
|
||||
configured callback once, and rechecks local mutable state. The public
|
||||
`releasekit.Check` API and `releasekit check` command provide the local
|
||||
diagnostic. Temporary Git repositories cover the acceptance cases; offline
|
||||
`go test -count=1 ./...` and `go run ./internal/apicheck` pass.
|
||||
|
||||
## Stage 6: Resolve and inspect the authoritative endpoint
|
||||
|
||||
Status: Complete. Depends on Stage 5.
|
||||
|
||||
1. Implement effective push-URL capture, command-scoped remote configuration,
|
||||
matching read/write resolution, and endpoint rechecks described above.
|
||||
2. Implement exact remote main/tag queries with distinct present, absent,
|
||||
conflicting, and unreadable results. Query failures never establish absence.
|
||||
3. Compose the pre-validation and pre-publication remote guards around captured
|
||||
local state. Require main equality, rather than ancestor-only publication.
|
||||
|
||||
Acceptance: local remotes cover a separate fetch endpoint, explicit push URL,
|
||||
ordinary URL rewrites, multiple push destinations, missing main, conflicting
|
||||
tags, main ahead/behind the candidate, endpoint changes, and remote failure.
|
||||
Queries leave local tags, persistent remote configuration, and remote refs intact.
|
||||
|
||||
Evidence: `internal/git` captures effective push destinations through Git,
|
||||
rejects multiple distinct destinations, verifies scoped URL rewriting, and
|
||||
queries exact main and version-tag refs. A candidate check requires main to
|
||||
equal the captured commit and the version tag to be absent. Local bare remote
|
||||
tests cover separate fetch/push URLs, both rewrite modes, missing main, an
|
||||
existing tag, main ahead and behind, endpoint changes, unreadable remote state,
|
||||
and unchanged persistent config and refs.
|
||||
|
||||
## Stage 7: Create and push the exact annotated tag
|
||||
|
||||
Status: Complete. Depends on Stage 6.
|
||||
|
||||
1. Implement public publication request/result values and explicit conversion
|
||||
into the engine. Validate once between the complete preflight guards.
|
||||
2. Create an annotated tag from captured note bytes, inspect type and peeled
|
||||
commit, capture its object ID, and push only that object to the selected ref.
|
||||
3. Recheck mutable local state and endpoint before the push, including the local
|
||||
tag still identifying the captured object. A changed local tag prevents this
|
||||
invocation from proceeding; cleanup remains deliberate recovery.
|
||||
4. On successful push, return published state without another remote read-back.
|
||||
On push error, retain the tag and return unknown until Stage 8 adds resolution.
|
||||
|
||||
Acceptance: a local bare remote receives the expected tag object and commit;
|
||||
its main and unrelated refs do not change. Follow-tags and mirror configuration
|
||||
cannot expand publication. Note content, tag identity, and one-validation
|
||||
behavior are checked through the public facade. Restrict stage trials to test
|
||||
remotes while failure handling is incomplete.
|
||||
|
||||
Evidence: the public `releasekit.Publish` API captures the committed note,
|
||||
validates once between exact remote guards, creates an unsigned annotated tag,
|
||||
rechecks local and remote state, and pushes only the captured tag object. Bare
|
||||
remote tests verify the note bytes, peeled commit, tag object, unchanged branch
|
||||
and unrelated refs, disabled follow-tags and mirror expansion, validation count,
|
||||
remote conflicts, and retained local tags after push error; Stage 8 adds outcome
|
||||
classification through remote reconciliation.
|
||||
|
||||
## Stage 8: Resolve rejected and ambiguous publication
|
||||
|
||||
Status: Complete. Depends on Stage 7.
|
||||
|
||||
1. Add the one-query reconciliation path and public error/result classification.
|
||||
Preserve the original push cause when resolution does not confirm success.
|
||||
2. Give post-push cancellation a separate bounded recovery context. Retain local
|
||||
tag/object facts when the read fails or recovery is cancelled/times out.
|
||||
3. Add real rejected-push tests using bare-remote hooks. Simulate lost
|
||||
acknowledgments at the subprocess boundary after a real successful push.
|
||||
Separate known absence, conflicting object, and unavailable-query cases.
|
||||
4. Cover a remote branch change during validation and local tag mutation before
|
||||
push. Keep concurrency promises at the observed guard boundaries.
|
||||
|
||||
Acceptance: exact remote object match succeeds despite a reported push error;
|
||||
missing, conflicting, and unavailable remote tags have distinct outcomes. Failed
|
||||
pushes issue one reconciliation query, successful pushes issue none, and no
|
||||
recovery force-update or automatic tag deletion occurs.
|
||||
|
||||
Evidence: failed tag pushes receive one bounded exact-tag query. Matching object
|
||||
identity returns published; absence returns not_published with the original push
|
||||
error; a different object returns conflict; query failure returns unknown while
|
||||
preserving the push cause. Tests cover rejection by a bare remote's receive
|
||||
hook, an installed conflicting tag, unavailable reconciliation, and a lost
|
||||
acknowledgment after the bare remote accepted the tag while the caller context
|
||||
was canceled. Query counts confirm one recovery read after errors and none after
|
||||
a successful push.
|
||||
Tests also verify that a remote branch change during validation and a changed
|
||||
local tag before push prevent publication.
|
||||
|
||||
## Stage 9: Expose publication and document ReleaseKit bootstrap
|
||||
|
||||
Status: Complete. Depends on Stage 8.
|
||||
|
||||
1. Wire the complete public publisher into `releasekit publish`, with selected
|
||||
progress output, final result, exit classification, and signal cancellation.
|
||||
2. Add ReleaseKit's source-only profile and one short maintainer entry script.
|
||||
The profile selects the offline default suite; no inherited race, lint,
|
||||
documentation, image, or platform gates are added.
|
||||
3. Create `docs/release.md` now that publication works. Name authoritative
|
||||
`origin` at the ReleaseKit forge URL and `main`; document preparation,
|
||||
successful-push completion, exact-object recovery, local tag retention, and
|
||||
deliberate cleanup of proven unpublished tags.
|
||||
4. Document first-release execution from the captured candidate source using
|
||||
the local Go toolchain, before a released ReleaseKit executable exists.
|
||||
Include immutable release-note licensing footer construction and dependency
|
||||
preparation separate from validation.
|
||||
5. Update current development documentation and the policy-adoption roadmap's
|
||||
bootstrap status to the implemented boundary. Preserve pending deliverables.
|
||||
|
||||
Acceptance: an end-to-end CLI fixture publishes to a local remote through a
|
||||
committed profile and returns the expected exit/output behavior. Runbook commands
|
||||
are exercised using a temporary repository configured like ReleaseKit. This
|
||||
stage prepares self-publication and does not publish a real ReleaseKit release.
|
||||
|
||||
Evidence: `publish` runs the public publisher with the CLI signal context,
|
||||
selected progress output, final commit and tag-object output, and separate exit
|
||||
status for unresolved outcomes. A temporary committed profile runs the offline
|
||||
test command and publishes to a local bare remote. ReleaseKit's root profile,
|
||||
entry script, CLI and configuration guides, development guide, and maintainer
|
||||
runbook describe source-only publication and exact-object recovery. The
|
||||
runbook's dependency preparation is separate from offline validation. No real
|
||||
ReleaseKit release was published.
|
||||
|
||||
## Stage 10: Build selected targets with shared version injection
|
||||
|
||||
Status: Complete. Depends on Stage 9.
|
||||
|
||||
1. Implement public build values and internal build execution using the fixed
|
||||
flags, version symbol, filename convention, and prepared Go environment.
|
||||
2. Build explicit OS/architecture pairs and verify the application `version`
|
||||
invocation using a host artifact or temporary native build. Preserve
|
||||
caller-owned output files and report partial generated output on failure.
|
||||
3. Return source identity, artifact paths, filenames, targets, hashes, and
|
||||
compiler identity. Keep byte reproducibility and cross-platform execution
|
||||
promises outside the result contract.
|
||||
4. Add a temporary consumer module importing only `buildinfo` and exposing the
|
||||
canonical version command. Its local replacement is fixture-only.
|
||||
|
||||
Acceptance: the fixture compiles for the three initial targets and a native
|
||||
execution reports the injected version. An ambient cross-target environment
|
||||
does not select the smoke host. Empty targets perform no build or smoke test;
|
||||
missing main packages, build failures, incorrect version output, unsafe binary
|
||||
names, and cancellation fail with useful partial results.
|
||||
|
||||
Evidence: `releasekit.Build` and `internal/build` compile Linux amd64, Linux
|
||||
arm64, and macOS arm64 artifacts using the shared linker symbol and prepared
|
||||
local Go environment. The consumer fixture imports `buildinfo` and reports the
|
||||
injected version through its `version` invocation. Results retain the observed
|
||||
source commit, compiler identity, normalized targets, absolute paths, filenames,
|
||||
and SHA-256 digests. Tests cover host selection despite ambient cross-target
|
||||
variables, empty target sets, existing output preservation, partial target
|
||||
failure, missing packages, incorrect version output, unsafe names, and
|
||||
cancellation with completed artifacts retained. No byte-reproducibility or
|
||||
cross-platform execution guarantee is added.
|
||||
|
||||
## Stage 11: Integrate candidate builds and artifact command
|
||||
|
||||
Status: Complete. Depends on Stage 10.
|
||||
|
||||
1. Add build profile fields, CLI `build`, and the private artifact receipt.
|
||||
Bind receipts to source/build-input identity and generated hashes. Validate
|
||||
data on reload; leave the receipt outside the public API and hosted asset list.
|
||||
2. Integrate selected builds into `Check` and `Publish` after the single candidate
|
||||
callback. Use disposable output outside the worktree for candidate builds.
|
||||
Recheck mutable state after the entire validation/build sequence.
|
||||
3. Add ignored `dist` output and source-only and binary-producing examples.
|
||||
Document the API, profile target selection, version invocation, and build
|
||||
output ownership.
|
||||
4. Refresh facade and runtime dependency checks with the new values.
|
||||
|
||||
Acceptance: source-only publication invokes no builder; selected build failure
|
||||
prevents tag creation; selected builds inject the exact candidate version;
|
||||
callback validation runs once. CLI artifacts and receipts agree on filenames,
|
||||
hashes, commit, and resolved build settings. Generated validation output does
|
||||
not dirty the candidate. Continue directly to hosted delivery implementation;
|
||||
no publication or consumer pilot is needed to complete this stage.
|
||||
|
||||
## Stage 12: Find and create Gitea release pages
|
||||
|
||||
Status: Complete. Depends on Stage 11.
|
||||
|
||||
1. Implement the small internal REST transport using the served API operations,
|
||||
explicit destination/token inputs, context cancellation, and structured
|
||||
failure mapping. Use standard HTTP and JSON packages.
|
||||
2. Verify the hosted tag targets the captured source commit. Find a release by
|
||||
tag, create a missing stable release from the committed note, and verify
|
||||
existing note body/tag and stable, non-draft state before accepting it.
|
||||
Preserve the existing title.
|
||||
3. Handle create conflicts and lost acknowledgments by one lookup and content
|
||||
comparison. Never edit the existing page to make it match.
|
||||
4. Add `docs/integrations/gitea.md` describing implemented API interactions,
|
||||
credential supply, source binding, and failure semantics.
|
||||
|
||||
Acceptance: `httptest.Server` covers found, missing, created, conflicting,
|
||||
unauthorized, malformed, cancelled, and ambiguous-create results. A missing or
|
||||
wrong hosted tag prevents page creation. Existing historical titles are retained
|
||||
when the body, tag, and release state match. Fixture assertions cover actual
|
||||
request paths, payloads, and authentication without using real credentials.
|
||||
|
||||
## Stage 13: Inspect asset and manifest content
|
||||
|
||||
Status: Complete. Depends on Stage 12.
|
||||
|
||||
1. Generate the expected binary manifest from the declared build result. Add
|
||||
attachment discovery and streaming hash comparison of existing assets.
|
||||
2. Compare existing `SHA256SUMS` with the complete declared manifest. Identify
|
||||
matching, missing, conflicting, and unverifiable content separately.
|
||||
3. Inspect all declared conflicts before any upload and preserve unrelated
|
||||
attachments. Keep download authorization confined to the configured origin.
|
||||
|
||||
Acceptance: equal name/size with different bytes is conflict; matching content
|
||||
is accepted; a full matching manifest can cover missing binaries; a subset or
|
||||
different manifest is conflict; unreadable content is not treated as missing.
|
||||
Source-only delivery generates no binary manifest. No write endpoint is used
|
||||
by inspection tests.
|
||||
|
||||
## Stage 14: Upload missing assets and report partial delivery
|
||||
|
||||
Status: Complete. Depends on Stage 13.
|
||||
|
||||
1. Add multipart uploads for missing binaries in filename order, followed by a
|
||||
missing manifest. Record completed work and pending asset identities.
|
||||
2. Resolve ambiguous uploads by one resource read and content comparison.
|
||||
Handle concurrent matching uploads without creating replacement content;
|
||||
detect duplicate/conflicting attachment names as conflicts.
|
||||
3. Implement rerun behavior that accepts existing matching files, adds missing
|
||||
ones, and stops on conflicts. Preserve every existing page and attachment.
|
||||
4. Add tests where the first binary succeeds, a later write fails, and a second
|
||||
invocation completes only the missing assets; also cover a lost manifest
|
||||
acknowledgment and failure of the reconciliation read.
|
||||
|
||||
Acceptance: partial and unknown outcomes retain exact completed/pending facts;
|
||||
retries do not overwrite or delete content; no blind repeat POST is made after
|
||||
an ambiguous acknowledgment. Published manifest constraints hold across reruns.
|
||||
|
||||
## Stage 15: Expose tagged-source delivery through the facade and CLI
|
||||
|
||||
Status: Complete. Depends on Stage 14.
|
||||
|
||||
1. Implement `Deliver`, its facade-owned request/result values, and conversions.
|
||||
Bind source note, resolved build settings, tag commit, and hosted repository
|
||||
as specified.
|
||||
2. Add delivery profile fields, environment-name token loading in the CLI, and
|
||||
`deliver` with an optional verified assets directory. With no directory,
|
||||
build declared tagged-source artifacts in temporary storage before uploading.
|
||||
An absent build specification or empty target set selects page-only delivery:
|
||||
skip the builder, native smoke, receipt requirement, and manifest generation.
|
||||
3. Accept detached tagged checkouts and historical tags without requiring old
|
||||
remote main equality. Verify receipt identity/hashes before supplied assets
|
||||
are used. Keep the library credential input explicit.
|
||||
4. Add current consumer/CLI guidance for source status, delivery status,
|
||||
retained assets, and retry commands. Extend public boundary checks.
|
||||
|
||||
Acceptance: facade/CLI fixtures cover both page-only delivery and binary delivery
|
||||
from tagged source to a local server, with content-aware reruns. Page-only
|
||||
delivery preserves the complete note, needs no main package or receipt, and
|
||||
performs no Go build or asset upload. Wrong commit, stale build settings or
|
||||
receipt, tampered assets, and missing credentials prevent relevant writes.
|
||||
Candidate tests and Git publication are not run by delivery. A delivery failure
|
||||
leaves the existing source tag intact and reports only delivery failure.
|
||||
|
||||
Evidence: `releasekit.Deliver` and `releasekit deliver` now verify lightweight or
|
||||
annotated local tags from clean, attached or detached checkouts, compare the
|
||||
hosted tag commit, and use the note read from the tagged commit. The CLI loads
|
||||
delivery credentials only for delivery; it builds selected tagged-source
|
||||
artifacts in temporary storage or verifies a supplied build receipt and its
|
||||
artifact hashes before calling the facade. Page-only fixtures create and reuse
|
||||
the complete note without a main package, receipt, manifest, build, or upload.
|
||||
Binary fixtures build a tagged-source executable, upload it with `SHA256SUMS`,
|
||||
and accept matching page and asset content on rerun. Local server tests verify
|
||||
that wrong hosted and local commits, stale build settings, tampered receipt
|
||||
assets, and missing credentials prevent remote writes; the tag remains intact
|
||||
after delivery failure. `go test ./...`, `go run ./internal/apicheck`, and the
|
||||
Markdown whitespace check pass. All delivery checks use a local HTTP fixture;
|
||||
no live Gitea service or credentials were used.
|
||||
|
||||
## Stage 16: Provide the common Woodpecker integration
|
||||
|
||||
Status: Complete. Depends on Stage 15.
|
||||
|
||||
1. Add maintained source-only and binary-producing tag-pipeline templates.
|
||||
Parameterize the Go image and immutable ReleaseKit source pin for eventual
|
||||
deployment, with explicit installation/cache preparation and a delivery
|
||||
secret. Document required template inputs rather than inventing a published
|
||||
pin. Create no new ReleaseKit image-distribution requirement.
|
||||
2. Bind tag and commit variables to the checkout, fetch the selected tag when
|
||||
necessary, share generated assets between steps, and keep output ignored.
|
||||
3. Document preparation versus offline execution, asynchronous status, and
|
||||
rerunning the same immutable tag. The source-only template delivers the note
|
||||
page directly; the binary template first builds its declared assets. Neither
|
||||
workflow executes the publisher.
|
||||
4. Exercise both command sequences locally with a tool built from this checkout,
|
||||
fixture repositories, and a local server. Substitute the local executable for
|
||||
the templates' installation step during development checks. Check YAML using
|
||||
locally available tooling or static inspection; no live runner or new
|
||||
external validator is needed to complete the stage.
|
||||
|
||||
Acceptance: the maintained commands reach common delivery for both profile types
|
||||
and common builds for declared binary targets, with the selected version and
|
||||
commit. Secrets enter only the delivery step. Agent-performed static YAML checks
|
||||
and local command evidence are recorded accurately. No published tool pin,
|
||||
container pull, configured secret, or live runner is a stage prerequisite.
|
||||
CI success is not a source release gate. The
|
||||
[Woodpecker environment reference](https://woodpecker-ci.org/docs/usage/environment)
|
||||
owns the runner-provided tag and commit variables.
|
||||
|
||||
Evidence: maintained source-only and binary tag workflows are in
|
||||
`examples/woodpecker/`. Both parameterize the Go image and immutable ReleaseKit
|
||||
commit through their matrix entries, verify the fetched tag against the runner
|
||||
commit, and keep shared output under the locally ignored `.releasekit/`
|
||||
directory. Only the delivery step maps the configured Woodpecker secret to the
|
||||
CLI token variable. The source-only workflow delivers the note page; the binary
|
||||
workflow prepares module caches, builds declared targets offline, and passes
|
||||
the build receipt and assets into delivery. The delivery guide covers template
|
||||
inputs, source publication versus delivery status, and retries against the same
|
||||
tag. A test builds the CLI from this checkout and exercises both workflows'
|
||||
delivery command sequences against fixture repositories and a local HTTP
|
||||
server; it substitutes the built executable for the installation command. Both
|
||||
YAML files parse with locally available PyYAML 6.0.3, and static checks confirm
|
||||
their tag filters, step layout, and delivery-only secret mapping. `go test ./...`,
|
||||
`go run ./internal/apicheck`, and the Markdown whitespace check pass. No live
|
||||
Woodpecker runner, image pull, secret, or hosted delivery service was used.
|
||||
|
||||
## Stage 17: Prepare ReleaseKit's own hosted-page delivery
|
||||
|
||||
Status: Complete. Depends on Stage 16.
|
||||
|
||||
1. Extend ReleaseKit's source-only profile with its Gitea destination and token
|
||||
environment name. Keep the build target set empty and retain its selected
|
||||
offline candidate suite. No distributed executable or binary manifest is
|
||||
introduced.
|
||||
2. Prepare a repository-specific Woodpecker workflow under the maintained
|
||||
examples, using the tagged checkout to build the local release tool and call
|
||||
page-only delivery. Keep it outside active CI discovery during this sequence.
|
||||
Document where to place it for later activation and how to supply its secret.
|
||||
3. Update the release policy's deliverable declaration and `docs/release.md`
|
||||
together to identify the hosted note page, automation responsibility, and
|
||||
page-delivery retry command. Source completion remains the exact tag push.
|
||||
4. Exercise the prepared command sequence against a temporary tagged repository
|
||||
and local HTTP server. Retain the note's complete body, including licensing
|
||||
footer, on the hosted page.
|
||||
|
||||
Acceptance: ReleaseKit's source-only example creates a hosted page and accepts
|
||||
an identical rerun without building consumer binaries, generating a manifest,
|
||||
requiring a receipt, or consulting a previously released tool. Delivery failure
|
||||
leaves source status unchanged. Workflow preparation requires no real tag,
|
||||
credentials, remote push, CI activation, or maintainer checkpoint.
|
||||
|
||||
Evidence: ReleaseKit's root profile identifies its Gitea destination and
|
||||
`RELEASEKIT_GITEA_TOKEN`, preserves the offline default test suite, and declares
|
||||
no build targets. The repository-specific Woodpecker example remains under
|
||||
`examples/` and builds the CLI from the fetched, commit-checked tag before
|
||||
page-only delivery; the release procedure documents later activation and secret
|
||||
configuration, source-tag completion, and same-tag retry. A local integration
|
||||
test clones and tags a temporary copy of the repository, builds the CLI from
|
||||
that tag, and exercises delivery against a local HTTP server. It verifies a
|
||||
hosted-tag failure leaves the source tag intact, then checks page creation and
|
||||
an identical rerun without assets; the complete note body, including its three
|
||||
license links, is preserved. No real tag, push, credential, or hosted service
|
||||
was used.
|
||||
|
||||
## Stage 18: Complete the initial implementation and handoff documentation
|
||||
|
||||
Status: Complete. Depends on Stage 17.
|
||||
|
||||
1. Map each initial capability in the feature roadmap to its implemented owner
|
||||
and existing behavioral evidence. Record the concrete package and dependency
|
||||
inventory, both supported facades, and their implemented responsibilities in
|
||||
the canonical internal and consumer documentation.
|
||||
2. Finish current API, CLI, configuration, integration, example, development,
|
||||
and release documentation. Check links and consistency with actual behavior;
|
||||
keep licensing and attribution accurate for incorporated material.
|
||||
3. Run the established offline default suite and relevant existing boundary
|
||||
checks for the assembled implementation. Resolve implementation defects
|
||||
within this scope without adding a new permanent release matrix or live
|
||||
testing requirement.
|
||||
4. Record the completed initial implementation and evidence in this plan.
|
||||
Identify prepared integrations whose live operation remains unverified and
|
||||
hand off the implementation for the maintainer's subsequent architecture
|
||||
review. Keep consumer migrations and their anticipated code savings marked
|
||||
as future adoption work.
|
||||
|
||||
Acceptance: the initial library and executable provide check, publication,
|
||||
build, runtime version access, page-only and binary delivery, partial/uncertain
|
||||
recovery, and prepared Woodpecker integration. The documentation describes the
|
||||
implemented boundary accurately. Completion depends on local implementation
|
||||
and development evidence; architectural review, a broader testing plan,
|
||||
consumer migrations, and release/deployment decisions follow this sequence.
|
||||
|
||||
Evidence and handoff: `docs/internal/overview.md` records both public Go
|
||||
facades, all 14 implemented Go packages, the absence of third-party module
|
||||
dependencies, capability ownership, and representative behavioral tests. The
|
||||
README and canonical CLI, configuration, consumer, integration, development,
|
||||
and release documents describe the implemented behavior; the policy and product
|
||||
roadmaps no longer present completed facade, delivery, or workflow work as
|
||||
pending. `go test ./...`, `go run ./internal/apicheck`, local Markdown link and
|
||||
fragment checks, and prose whitespace checks pass. All three maintained
|
||||
Woodpecker examples parse with local PyYAML 6.0.3, with the token mapped only in
|
||||
each delivery step. Local Git and HTTP fixtures exercise source-only delivery,
|
||||
binary delivery, publication recovery, and the ReleaseKit tagged-source workflow.
|
||||
|
||||
The Woodpecker workflows remain prepared, not activated. No live runner,
|
||||
configured deployment secret, immutable deployment pin, hosted Gitea delivery,
|
||||
or ReleaseKit source release was used or verified. Consumer migrations and
|
||||
measurement of removed consumer infrastructure remain future adoption work.
|
||||
The implementation is ready for the maintainer's subsequent architecture
|
||||
review; broader testing and release or deployment decisions remain outside this
|
||||
completed implementation sequence.
|
||||
|
||||
## Coverage of the feature roadmap
|
||||
|
||||
| Initial target responsibility | Implementing stages |
|
||||
| --- | --- |
|
||||
| Two public facades and small runtime dependencies | 1–3, extended in 10–11 and 15 |
|
||||
| Stable version and committed note identity | 5 |
|
||||
| Candidate capture, one validation, mutable guards | 5–8, 11 |
|
||||
| Authoritative endpoint and remote ref state | 6–8 |
|
||||
| Annotated object publication and failure recovery | 7–9 |
|
||||
| ReleaseKit source-only bootstrap/runbook | 9, 17 |
|
||||
| Shared version injection and selected cross-builds | 2, 10–11 |
|
||||
| Native smoke, empty target sets, consistent names | 10–11 |
|
||||
| Hosted page/note creation, including source-only projects | 12, 15, 17 |
|
||||
| Full checksums, comparison, partial/additive retries | 13–15 |
|
||||
| Prepared Woodpecker workflows for both delivery profiles | 16–17 |
|
||||
| Complete initial implementation and canonical documentation | 18 |
|
||||
|
||||
Consumer infrastructure reduction and convergence on the shared standard remain
|
||||
feature-roadmap adoption goals. Their migration sequence, real-world testing,
|
||||
and measured savings will be determined after the initial architecture review.
|
||||
|
||||
## Open Questions
|
||||
|
||||
None block this initial implementation sequence. The maintainer has selected
|
||||
hosted pages for source-only projects and deferred pilots, releases, consumer
|
||||
adoption, and broader testing decisions until after implementation and the
|
||||
subsequent architecture review. Actual release pins and deployment credentials
|
||||
are inputs to later adoption; no stage requires them.
|
||||
@@ -1,183 +0,0 @@
|
||||
# Adopt the policy framework
|
||||
|
||||
Status: Policy adoption complete. Source publication, its maintainer runbook,
|
||||
and prepared hosted note-page delivery are implemented; no ReleaseKit release
|
||||
has been published. Binary distribution remains deferred.
|
||||
|
||||
Date: 2026-10-05
|
||||
|
||||
## Purpose and scope
|
||||
|
||||
Standard Repository Policies are adopted into ReleaseKit as locally maintained
|
||||
rules for an opinionated Go library and its proposed release executable. The
|
||||
adoption preserves the project's existing licensing choice, supports deliberate
|
||||
standardization of release behavior, and keeps documentation accurate about what
|
||||
has been implemented.
|
||||
|
||||
This roadmap covers policy adoption, contributor navigation, documentation
|
||||
ownership, licensing notices, and the preparation of ReleaseKit's own release
|
||||
procedure. Product implementation and consumer migrations belong to the separate
|
||||
[ReleaseKit proposal](releasekit.md).
|
||||
|
||||
## Upstream baseline and references
|
||||
|
||||
Use upstream commit `d84a38ebab26f048cafbe59a2246700c35d29843`. The local
|
||||
`../policy` checkout and upstream `main` matched that revision during the review.
|
||||
PromptKit and ConfigKit adopted the same baseline.
|
||||
|
||||
Follow the [adoption guide at the selected revision](https://gitea.maximumdirect.net/eric/policy/src/commit/d84a38ebab26f048cafbe59a2246700c35d29843/docs/adoption.md).
|
||||
Copy applicable policies locally and customize them. Retain each file's exact
|
||||
upstream provenance; later upstream changes become local rules through deliberate
|
||||
review and adoption. Git history is sufficient to record this process.
|
||||
|
||||
Useful library adaptations include
|
||||
[ConfigKit's architecture policy](../../../ConfigKit/docs/policy/architecture.md),
|
||||
[PromptKit's architecture policy](../../../promptkit/docs/policy/architecture.md),
|
||||
and their documentation, testing, and attribution policies. Use these as examples
|
||||
of adaptation rather than copying their product-specific requirements.
|
||||
|
||||
## Policy adaptations
|
||||
|
||||
All seven policies are adopted under `docs/policy/`:
|
||||
|
||||
| Policy | Base version | ReleaseKit adaptation |
|
||||
| --- | --- | --- |
|
||||
| `meta.md` | 1.0 | Retain local authority, per-document adoption provenance, and upstream update navigation. |
|
||||
| `agents.md` | 1.3 | Retain proportionate implementation and local commit practices. Add the libraries' clarification that implementation, tests, and agent-authored plans do not independently establish new contracts. |
|
||||
| `architecture.md` | 1.3 | Define the library, proposed executable, consumer responsibilities, external effects, and dependency boundaries. |
|
||||
| `testing.md` | 1.3 | Retain behavioral, deterministic, offline testing. Prioritize publication integrity, ambiguous outcomes, partial delivery, cross-builds, and version injection as those features are implemented. |
|
||||
| `documentation.md` | 1.11 | Assign exact exported Go contracts to declarations and GoDoc, workflows to consumer guides, and proposals to roadmap documents. Add CLI and integration owners when those interfaces exist. |
|
||||
| `oss.md` | 1.8 | Preserve the library licensing choice, apply the attribution format, and identify separately licensed copied policy material. |
|
||||
| `release.md` | 1.4 | Govern releases of ReleaseKit itself, with explicit deliverables and justified checks. Distinguish its maintainer procedure from the release standard offered to consumers. |
|
||||
|
||||
## Adopted architectural constraints
|
||||
|
||||
The [architecture policy](../policy/architecture.md) owns the adopted boundaries,
|
||||
including [ADR 0001](../adr/0001-public-facade.md) and the runtime version
|
||||
constraints. The following summarizes those rules for this adoption record.
|
||||
|
||||
Evaluate ReleaseKit against both of ConfigKit's relevant success criteria:
|
||||
applications should delete substantial infrastructure, and consumers should adopt
|
||||
one consistent set of deliberately selected conventions.
|
||||
|
||||
- ReleaseKit owns the selected publication, version injection, build, and delivery
|
||||
conventions. Consumers supply product identity, main package, selected targets,
|
||||
and application-specific checks.
|
||||
- Consumers use the root `releasekit` orchestration facade and the lightweight
|
||||
`buildinfo` runtime facade. Both packages own their public contracts and
|
||||
delegate through private state and explicit conversions to internal
|
||||
implementation. ReleaseKit builds and tests independently
|
||||
of the consuming repositories and does not depend on their private packages.
|
||||
- Git, filesystem, Go toolchain, and Gitea effects have proportionate boundaries
|
||||
and occur through explicit operations. Package layout and abstractions should
|
||||
serve those boundaries without requiring an application framework.
|
||||
- The library returns meaningful errors and publication outcomes. The executable
|
||||
handles command parsing, output, and exit codes.
|
||||
- The `buildinfo` facade provides runtime version access through a lightweight
|
||||
dependency graph. ReleaseKit's builder and runtime implementation own version
|
||||
injection together.
|
||||
|
||||
Architecture policy may govern future development. Concrete package inventory,
|
||||
API semantics, and implemented behavior must be documented when they exist.
|
||||
|
||||
## Adoption stages
|
||||
|
||||
### 1. Copy and tailor policies
|
||||
|
||||
- [x] Copy the seven policies from the selected baseline.
|
||||
- [x] Preserve each `Base Policy Version`, set `Last Updated` to the actual
|
||||
adoption date, and add an `Upstream Source` link to that file at the full commit.
|
||||
- [x] Customize the policies for ReleaseKit and remove their `Base Policy
|
||||
Template` sections.
|
||||
- [x] Adapt upstream `agents/AGENTS.md` into root `AGENTS.md`, preserving the
|
||||
existing knowledge-graph discovery instructions.
|
||||
- [x] Create `docs/development.md` with contributor orientation and the selective
|
||||
policy reading guide. Route tasks to applicable policies instead of requiring
|
||||
the entire suite for every task.
|
||||
|
||||
### 2. Establish documentation ownership
|
||||
|
||||
- [x] Move the substantive contents of `ideas.md` to
|
||||
`docs/roadmap/releasekit.md`, preserving the proposal, and retain `ideas.md` as a
|
||||
navigation pointer. Update this roadmap's proposal link in the same change.
|
||||
- [x] Update README with accurate current status and navigation.
|
||||
- [x] Define ownership for GoDoc, consumer guidance, architecture constraints,
|
||||
internal implementation, release procedures, ADRs, and unfinished work.
|
||||
- [x] Reserve consumer, CLI, configuration, integration, and internal ownership
|
||||
in the documentation policy. Their documents await corresponding implementation;
|
||||
no empty owners or speculative command references were created.
|
||||
|
||||
### 3. Complete notices and attribution
|
||||
|
||||
- [x] Add root `COPYRIGHT` using the upstream library example and verified project
|
||||
details. The grant is `LGPL-3.0-or-later`, consistent with the existing library
|
||||
licensing choice and the two library examples.
|
||||
- [x] Restore the complete, verbatim LGPLv3 and incorporated GPLv3 texts in
|
||||
`LICENSE`; the original contained reformatted text and a customized appendix.
|
||||
Keep project-specific grant statements in `COPYRIGHT`.
|
||||
- [x] Add `docs/oss/attribution.md` with the supplied policy attribution entry,
|
||||
describing the actual adapted policies, agent orientation, and reading guide.
|
||||
- [x] Copy the CC-BY-SA 4.0 text to `docs/oss/licenses/CC-BY-SA-4.0.txt` and identify
|
||||
the copied material's separate licensing scope in `COPYRIGHT`.
|
||||
- [x] Add README links to the project grant and attribution document. Keep source
|
||||
and notice links pinned to the adopted commit and reference examples upstream.
|
||||
|
||||
The library's selected license remains the project grant. A future executable
|
||||
does not automatically acquire a different license merely because the upstream
|
||||
policy has separate defaults for applications and libraries.
|
||||
|
||||
### 4. Define ReleaseKit's own release path
|
||||
|
||||
- [x] Adopt the general versioning, compatibility, integrity, immutability, and
|
||||
successful-tag-push completion rules.
|
||||
- [x] Select the immutable source tag as the source-completion point and the
|
||||
hosted note page as a separate asynchronous deliverable. Supporting downstream
|
||||
cross-builds does not declare ReleaseKit binaries.
|
||||
- [x] Add `docs/release.md` alongside the first working publication command,
|
||||
documenting real prerequisites, authoritative remote, branch, validation,
|
||||
publication, and failure recovery.
|
||||
- [x] Account for first-release bootstrap: the initial publication command must
|
||||
run from the captured candidate source with dependencies prepared separately.
|
||||
The first release uses that source execution path before a released ReleaseKit
|
||||
tool exists. The maintainer procedure documents the command and the temporary
|
||||
repository integration test exercises the same CLI workflow.
|
||||
- [ ] Add executable delivery declarations and target checks when corresponding
|
||||
deliverables exist. Keep source completion and asynchronous delivery status
|
||||
separate. This task is deferred unless executable deliverables are selected.
|
||||
|
||||
The publication command, its automated guards, offline candidate validation,
|
||||
executable maintainer runbook, and prepared hosted-page workflow are implemented.
|
||||
This adoption does not claim that a ReleaseKit version has been published.
|
||||
|
||||
## Validation and completion
|
||||
|
||||
Review provenance, attribution scope, faithful license texts, template residue,
|
||||
local links, whitespace, and consistency with implemented repository behavior.
|
||||
Documentation-only adoption should use those checks; executable commands and
|
||||
examples added later require appropriate execution checks.
|
||||
|
||||
Adoption is complete when the tailored policy set, contributor navigation,
|
||||
documentation ownership, and licensing notices are coherent and verified. The
|
||||
source-publication command and hosted-page delivery are implemented; actual
|
||||
publication and binary distribution remain outside policy adoption.
|
||||
|
||||
Do not inherit PromptKit's or ConfigKit's extra release gates automatically.
|
||||
Select additional checks only for identified ReleaseKit risks, recording their
|
||||
justification in the adopted policy. Upstream synchronization, recurring license
|
||||
approval, and CI polling are not additional adoption or release gates.
|
||||
|
||||
## Adoption result
|
||||
|
||||
The seven policies, root agent orientation, developer reading guide, documentation
|
||||
ownership, project grant, attribution, license texts, source publication command,
|
||||
maintainer runbook, and prepared hosted-page delivery are in place. The product
|
||||
proposal lives at `docs/roadmap/releasekit.md`; `ideas.md` remains a navigation
|
||||
pointer. Binary distribution is deferred, and no ReleaseKit release has been
|
||||
published.
|
||||
|
||||
Verification covers local file and fragment links, per-policy source revision and
|
||||
base version, removed template adoption sections, attribution scope and pinned
|
||||
notice destinations, verbatim license bytes, and prose whitespace. The preserved
|
||||
ADR decision and relocated proposal are checked against their pre-adoption source.
|
||||
ReleaseKit's source publication command, runbook, and hosted-page deliverable are
|
||||
implemented; binary delivery declarations remain deferred under stage 4.
|
||||
@@ -1,16 +1,16 @@
|
||||
# ReleaseKit: shared release process
|
||||
|
||||
This proposal records a review of PromptKit, ConfigKit, Audita, Notarius,
|
||||
Narratio, and Scriptorium on 2026-09-29. The initial library, CLI, build and
|
||||
delivery paths, and prepared Woodpecker examples are implemented; the
|
||||
[implementation plan](implementation.md) records the completed boundary and
|
||||
evidence. The public facade architecture is accepted in
|
||||
[ADR 0001](../adr/0001-public-facade.md) and implemented for runtime version,
|
||||
candidate validation, source publication, selected-target builds, and tagged-
|
||||
source delivery.
|
||||
The [implementation plan](implementation.md) owns ordered stages, execution
|
||||
instructions, acceptance checks, and implementation status. Consumer migration
|
||||
and measurement of local infrastructure reduction remain future adoption work.
|
||||
Status: Initial implementation, policy adoption, and architecture remediation
|
||||
are complete. Consumer adoption, publication, and live integration work remain.
|
||||
|
||||
This roadmap records the shared release-process opportunity identified in
|
||||
PromptKit, ConfigKit, Audita, Notarius, Narratio, and Scriptorium on 2026-09-29,
|
||||
and the remaining adoption goals. The [internal package inventory](../internal/overview.md)
|
||||
records implemented capability owners and behavioral evidence. The
|
||||
[architecture policy](../policy/architecture.md) and
|
||||
[ADR 0001](../adr/0001-public-facade.md) own the facade boundaries and rationale.
|
||||
The completed implementation, policy adoption, and remediation plans are
|
||||
preserved in Git history.
|
||||
|
||||
## Opportunity
|
||||
|
||||
@@ -96,8 +96,8 @@ and GoDoc own exact public API contracts; additional public packages and
|
||||
extension interfaces require a deliberate decision grounded in durable consumer
|
||||
needs.
|
||||
|
||||
Compiled-export and dependency checks will protect facade ownership.
|
||||
External-package behavioral tests will protect error identity, value ownership,
|
||||
Compiled-export and dependency checks protect facade ownership.
|
||||
External-package behavioral tests protect error identity, value ownership,
|
||||
callback lifetime, and observable outcomes across forwarding and conversions.
|
||||
|
||||
## Shared tool boundary
|
||||
@@ -202,10 +202,24 @@ Existing published tags, notes, pages, and assets retain their historical conten
|
||||
|
||||
Consumer policy and procedure changes should describe the deliberately adopted
|
||||
standard and its compatibility impact. Adoption should demonstrate reduced local
|
||||
infrastructure and one coherent release model. The implementation plan owns the
|
||||
complete initial ReleaseKit implementation and its development evidence.
|
||||
Architecture review follows that implementation; broader testing and consumer
|
||||
migration steps will be chosen afterward.
|
||||
infrastructure and one coherent release model.
|
||||
|
||||
## Remaining work
|
||||
|
||||
- Prepare and publish the first ReleaseKit source release under the
|
||||
[maintainer procedure](../release.md), then deliver its hosted note page.
|
||||
- Choose the broader consumer integration test plan and migration sequence.
|
||||
Evaluate API clarity, product-specific checks, and the infrastructure removed
|
||||
from each consuming repository.
|
||||
- Select immutable ReleaseKit deployment pins and Go image digests for consumer
|
||||
workflows. Provision delivery credentials and activate the prepared Woodpecker
|
||||
workflows as part of deployment.
|
||||
- Verify live Gitea delivery and Woodpecker execution. Existing verification uses
|
||||
local Git and HTTP fixtures; no live deployment has been verified.
|
||||
- Keep ReleaseKit executable binary distribution deferred until deliverables
|
||||
are deliberately selected. Selecting binaries would require delivery
|
||||
declarations, target checks, automation responsibilities, and corresponding
|
||||
release policy and procedure updates.
|
||||
|
||||
## Reviewed implementations
|
||||
|
||||
|
||||
@@ -1,428 +0,0 @@
|
||||
# ReleaseKit implementation review and remediation
|
||||
|
||||
Status: Complete. R1–R10 are resolved; resolution notes record the fixes and
|
||||
verification.
|
||||
|
||||
Date: 2026-10-06
|
||||
|
||||
## Review scope and evidence
|
||||
|
||||
Reviewed the initial implementation from `cc7ca47` through `539877e`, including
|
||||
the public facades, internal publication/build/delivery paths, executable and
|
||||
profile/receipt adapters, boundary checker, tests, maintained workflows, and
|
||||
current documentation. The worktree was clean at the start of the review.
|
||||
The [feature roadmap](releasekit.md), [implementation plan](implementation.md),
|
||||
[ADR 0001](../adr/0001-public-facade.md), and applicable adopted policies define
|
||||
the intended scope. An agent-authored implementation or assertion does not
|
||||
independently authorize an additional restriction.
|
||||
|
||||
The uncached offline suite passed with `go test -count=1 ./...`, using
|
||||
`GOWORK=off`, `GOPROXY=off`, `GONOPROXY=none`, `GOSUMDB=off`, and
|
||||
`GOTOOLCHAIN=local`. The compiled-export and dependency checker passed with
|
||||
`go run ./internal/apicheck`. Passing these checks does not resolve the findings
|
||||
below: controlled reproductions exposed behavior outside their current coverage.
|
||||
Reproductions used temporary consumer modules, local Git repositories and bare
|
||||
remotes, local HTTP servers, and one temporary Go test overlay. They changed no
|
||||
tracked implementation files and used no real credentials or publication service.
|
||||
|
||||
The prepared workflow syntax was also compared with the official Woodpecker
|
||||
[matrix](https://woodpecker-ci.org/docs/usage/matrix-workflows) and
|
||||
[environment](https://woodpecker-ci.org/docs/usage/environment) references.
|
||||
Live CI, live Gitea delivery, consumer migrations, and measured consumer code
|
||||
reduction remain intentionally deferred; their absence is not a finding.
|
||||
|
||||
## Initial architecture assessment
|
||||
|
||||
One Go module exposes two supported packages. The root `releasekit` package
|
||||
owns `Check`, `Publish`, `Build`, `Deliver`, and their public request/result
|
||||
values. `buildinfo.Version` forwards into a small standard-library runtime
|
||||
implementation. The builder and runtime share a private injection-symbol
|
||||
contract. Public signatures own their named types and expose no internal
|
||||
implementation types.
|
||||
|
||||
`cmd/releasekit` calls the supported facades; command-owned internal helpers
|
||||
parse profiles, execute configured checks, and handle private receipts. Internal
|
||||
packages own candidate inspection, Git endpoint/ref operations, publication
|
||||
reconciliation, cross-builds, subprocess execution, and Gitea transport/delivery.
|
||||
Source publication and asynchronous delivery have separate outcomes. Page-only
|
||||
delivery and the three initial binary targets are implemented. The default
|
||||
suite uses local collaborators and is independent of consuming checkouts.
|
||||
|
||||
This structure substantially matches the decision. R5 identifies implementation
|
||||
mechanics still placed in the public package. The more consequential gaps are
|
||||
source/artifact binding and accurate recovery state, rather than exposed type
|
||||
ownership or runtime dependency weight.
|
||||
|
||||
## Findings
|
||||
|
||||
### R1 — High: Delivery accepts binaries built from uncommitted source
|
||||
|
||||
Status: Resolved.
|
||||
|
||||
Category: Correctness and divergence from tagged-source delivery.
|
||||
|
||||
**Evidence:** [The builder](../../internal/build/build.go) records `HEAD` in
|
||||
`gitCommit` but compiles the current worktree without establishing that it is
|
||||
that committed source. [Delivery](../../internal/delivery/delivery.go) checks
|
||||
checkout cleanliness and tag equality at delivery time, then accepts matching
|
||||
commit metadata and artifact hashes. The [receipt adapter](../../cmd/releasekit/internal/cli/receipt.go)
|
||||
adds hashes and build settings, but no evidence of source cleanliness during
|
||||
compilation.
|
||||
|
||||
A temporary application was committed and tagged, changed to print
|
||||
`UNCOMMITTED`, and built successfully. Its result recorded the original tagged
|
||||
commit. After restoring the original clean source, `Deliver` accepted the
|
||||
result and uploaded the uncommitted binary and manifest with state `complete`.
|
||||
No caller forged metadata or edited a receipt.
|
||||
|
||||
**Required remediation:** Bind delivery-eligible build results and receipts to
|
||||
the committed source actually compiled. Observe the relevant source state
|
||||
before and after compilation, or build the committed source in a controlled
|
||||
checkout. Verify eligibility when consuming a result or receipt. Keep ordinary
|
||||
local build behavior explicit: this finding does not authorize a universal
|
||||
clean-`main` restriction, an attestation system, or a concurrency-proof source
|
||||
snapshot guarantee. Delivery still accepts detached historical tagged source.
|
||||
|
||||
**Focused verification:** An ordinary build from modified source must not
|
||||
become eligible for tagged delivery merely by cleaning the worktree afterward.
|
||||
Cover source changes during a build and unchanged clean tagged builds through
|
||||
the supported API and CLI receipt path.
|
||||
|
||||
**Resolution:** Build results and private receipts now carry `SourceVerified`,
|
||||
set only after completed builds observe clean source and unchanged HEAD. Local
|
||||
dirty builds remain supported; binary delivery rejects their results and
|
||||
receipts even after checkout cleanup. API tests cover clean, initially dirty,
|
||||
changed-during-build source, and HEAD advancement; a CLI regression covers
|
||||
receipt delivery after
|
||||
cleanup. The offline suite and public boundary checks pass.
|
||||
|
||||
### R2 — High: Some successful page writes are reported as not attempted
|
||||
|
||||
Status: Resolved.
|
||||
|
||||
Category: Failure handling and recovery-state correctness.
|
||||
|
||||
**Evidence:** [EnsureRelease](../../internal/gitea/release.go), at the
|
||||
`postErr == nil` branch around line 152, returns `acceptCreated` directly.
|
||||
Semantic verification failures therefore bypass the reconciliation used for
|
||||
JSON decoding or transport failures. [Delivery](../../internal/delivery/delivery.go)
|
||||
then calls `stateForError(err, false)` and reports `not_attempted`.
|
||||
|
||||
A fixture stored the requested page, returned HTTP 201 with a different title,
|
||||
and exposed the correct page on subsequent GET. Delivery returned
|
||||
`not_attempted` and `malformed_response` after one POST and only the initial
|
||||
page lookup. It did not perform the selected reconciliation lookup, even though
|
||||
the page existed. A reconciled successful create also loses write history when
|
||||
`acceptExisting` returns `Created: false`, affecting subsequent error reporting.
|
||||
|
||||
**Required remediation:** Route both syntactic and semantic create-response
|
||||
failures through the one-lookup recovery path. Preserve sufficient write and
|
||||
confirmed-page progress to classify later failures accurately. A confirmed
|
||||
page match resolves delivery of that page; unresolved write outcomes remain
|
||||
unknown. Retain the selected bounded reconciliation and immutable-content rules.
|
||||
|
||||
**Focused verification:** Cover HTTP 201 with an inconsistent decoded response,
|
||||
its matching and conflicting follow-up lookups, and a recovered create followed
|
||||
by asset-inspection failure. Assert both request counts and returned state.
|
||||
|
||||
**Resolution:** Semantic create-response failures now use one reconciliation
|
||||
lookup. Recovered page results retain create-request history, preserving partial
|
||||
progress on later asset-inspection failure. Local HTTP tests cover matching,
|
||||
conflicting, and unavailable lookups; a CLI fixture verifies recovered creation
|
||||
followed by failed asset inspection. Both affected suites pass.
|
||||
|
||||
### R3 — Medium: Read-only asset failures are classified as unknown writes
|
||||
|
||||
Status: Resolved.
|
||||
|
||||
Category: Divergence from the selected outcome contract.
|
||||
|
||||
**Evidence:** [UploadMissing](../../internal/gitea/upload.go), around line 102,
|
||||
sets `DeliveryUnknown` when preflight contains an unverifiable attachment.
|
||||
This occurs before any upload. [The CLI](../../cmd/releasekit/main.go) maps that
|
||||
state to exit 3, documented as an unresolved remote mutation.
|
||||
|
||||
With an existing matching page and an attachment download returning HTTP 503,
|
||||
a local reproduction returned `unknown` with zero POST requests. Uncertainty
|
||||
about existing content was promoted into uncertainty about a write that never
|
||||
occurred.
|
||||
|
||||
**Required remediation:** Keep unverifiable-content facts separate from
|
||||
uncertain mutation outcomes. Report a known inspection failure when no write
|
||||
was attempted; preserve partial page progress if this invocation already
|
||||
created a page. Reserve unknown-write state and exit 3 for unresolved writes,
|
||||
as selected in the plan. Adjust tests and documentation consistently.
|
||||
|
||||
**Focused verification:** An unreadable existing attachment on an otherwise
|
||||
read-only invocation must not return unknown-write state or exit 3. A genuinely
|
||||
ambiguous upload must continue to do so.
|
||||
|
||||
**Resolution:** Unverifiable preflight assets now return an inspection failure
|
||||
with `not_attempted`, retaining partial page progress when creation preceded
|
||||
the read failure. CLI tests cover existing and newly created pages, no asset
|
||||
writes, and exit 1. Existing ambiguous-upload regressions still verify unknown
|
||||
write outcomes. Both affected suites pass.
|
||||
|
||||
### R4 — Medium: Local artifact regeneration is prohibited
|
||||
|
||||
Status: Resolved.
|
||||
|
||||
Category: Inadvertently strengthened prohibition.
|
||||
|
||||
**Evidence:** [Build](../../internal/build/build.go), around line 114, refuses
|
||||
any existing selected artifact filename, including its own prior output. A
|
||||
second identical successful-build request to the same directory fails with
|
||||
`already exists; preserving caller-owned file`. The
|
||||
[build guide](../consumers/build.md) and [CLI contract](../cli.md) turn this
|
||||
implementation choice into a stated restriction.
|
||||
|
||||
The plan selects regeneration of owned local filenames while preserving
|
||||
unrelated files. Published remote content remains immutable; that rule does
|
||||
not prohibit rebuilding local output. This refusal also obstructs recovery
|
||||
from a partial local build without manual deletion.
|
||||
|
||||
**Required remediation:** Regenerate the selected tool-owned local outputs and
|
||||
preserve unrelated files. Keep receipt validity consistent with complete build
|
||||
and smoke success when outputs are regenerated. Update tests and the current
|
||||
documents to remove the blanket existing-output prohibition. Use ordinary
|
||||
filesystem operations without adding broad directory cleanup or durability
|
||||
machinery.
|
||||
|
||||
**Focused verification:** Repeating a build in its output directory succeeds;
|
||||
a changed local build can regenerate its owned names; unrelated files survive;
|
||||
a partial rebuild does not authorize incomplete assets through a stale receipt.
|
||||
|
||||
**Resolution:** Builds regenerate selected local artifact names and preserve
|
||||
unrelated output files. The CLI invalidates prior receipts once a rebuild has
|
||||
reached its output directory, including failed rebuilds. API regressions cover
|
||||
repeated and changed-source builds; CLI coverage proves a failed smoke check
|
||||
removes the previous receipt. Affected suites pass.
|
||||
|
||||
### R5 — Medium: The root facade still owns release mechanics
|
||||
|
||||
Status: Resolved.
|
||||
|
||||
Category: Architectural ownership gap and maintainability.
|
||||
|
||||
**Evidence:** [candidate_build.go](../../internal/build/candidate.go) implements temporary
|
||||
storage allocation, containment checking, cleanup, and candidate-build
|
||||
coordination in the public package. [delivery_assets.go](../../internal/delivery/assets.go)
|
||||
implements artifact inventory validation, file opening/stat/hash checks,
|
||||
filename derivation, and manifest assembly there. These are substantial
|
||||
implementation responsibilities beyond forwarding and type conversion.
|
||||
|
||||
No internal type leak was found. The gap is the placement of mechanics that
|
||||
ADR 0001 and the architecture policy assign behind the internal boundary.
|
||||
|
||||
**Required remediation:** Move these responsibilities into cohesive internal
|
||||
implementation, leaving the root package to own supported declarations,
|
||||
explicit conversion, callback adaptation, forwarding, and error identity.
|
||||
Choose package placement around existing responsibilities; add no public
|
||||
assembly API or generic framework.
|
||||
|
||||
**Focused verification:** Existing external-package behavior and boundary
|
||||
checks remain valid after the move. Confirm filesystem and artifact algorithms
|
||||
are owned internally without introducing inward imports of public facades.
|
||||
|
||||
**Resolution:** Candidate-build coordination now belongs to `internal/build`;
|
||||
artifact inventory, hashing, and manifest assembly belong to `internal/delivery`.
|
||||
The root facade performs conversions and forwarding only. Existing artifact
|
||||
tests moved with their implementation; external API and CLI tests, the complete
|
||||
offline suite, and compiled-export/import checks pass.
|
||||
|
||||
### R6 — Medium: Builds require a writable parent of the repository
|
||||
|
||||
Status: Resolved.
|
||||
|
||||
Category: Inadvertently strengthened filesystem prerequisite.
|
||||
|
||||
**Evidence:** [Candidate builds](../../internal/build/candidate.go), around line 21,
|
||||
and [CLI delivery builds](../../cmd/releasekit/main.go), around line 194,
|
||||
allocate temporary storage with `os.MkdirTemp(filepath.Dir(repositoryDir), ...)`.
|
||||
The requirement is disposable output outside the worktree, not sibling output.
|
||||
|
||||
A clean candidate in a writable repository under a read-only parent failed at
|
||||
candidate temporary-directory creation with `permission denied`, despite an
|
||||
available writable system temporary directory.
|
||||
|
||||
**Required remediation:** Allocate ordinary temporary build storage outside the
|
||||
worktree without requiring write access to its parent. Share the mechanism
|
||||
where appropriate. Preserve cleanup of tool-owned temporary paths and avoid
|
||||
adding broad output-directory restrictions.
|
||||
|
||||
**Focused verification:** Candidate and temporary delivery builds work with a
|
||||
read-only repository parent and a usable system temporary directory. Generated
|
||||
candidate output still leaves the worktree clean.
|
||||
|
||||
**Resolution:** Candidate and CLI delivery builds use shared system temporary
|
||||
storage allocated by `internal/tempdir`, with worktree containment checks and
|
||||
caller-owned cleanup. Regressions execute both operations with read-only
|
||||
repository parents and confirm clean worktrees. Additional helper regressions
|
||||
cover relative system temporary paths and cleanup after rejecting in-worktree
|
||||
storage. Affected suites pass.
|
||||
|
||||
### R7 — Medium: Attachment origin restrictions exceed credential isolation
|
||||
|
||||
Status: Resolved.
|
||||
|
||||
Category: Inadvertently strengthened prohibition.
|
||||
|
||||
**Evidence:** [downloadHash](../../internal/gitea/assets.go), around lines 164
|
||||
and 188, rejects cross-origin attachment URLs and redirects before making a
|
||||
request. The [integration guide](../integrations/gitea.md) and tests state this
|
||||
as a prohibition. A matching asset hosted by a second local server was marked
|
||||
unverifiable; that server received zero download requests.
|
||||
|
||||
The selected requirement keeps authorization on the configured Gitea origin.
|
||||
It does not prohibit downloading an attachment elsewhere without that token.
|
||||
The implementation adds a deployment restriction for external asset hosting.
|
||||
|
||||
**Required remediation:** Support content verification across attachment URLs
|
||||
and redirects while sending the Gitea token only to the configured origin.
|
||||
Keep credential supply explicit and retain digest comparison. Remove the
|
||||
stronger request-origin ban from tests and documentation; introduce no new
|
||||
network-policy framework.
|
||||
|
||||
**Focused verification:** Matching cross-origin bytes can be verified and
|
||||
conflicting bytes rejected. Direct and redirected external requests never
|
||||
carry the Gitea token; same-origin authenticated downloads continue to work.
|
||||
|
||||
**Resolution:** Attachment URLs and redirects may cross origins; the client
|
||||
sets the Gitea token only on requests to its configured origin. HTTP tests
|
||||
verify direct and redirected external matches, conflicting external bytes,
|
||||
absence of authorization on external requests, and continued same-origin
|
||||
authentication. The Gitea suite passes.
|
||||
|
||||
### R8 — Medium: The release wrapper collapses documented exit codes
|
||||
|
||||
Status: Resolved.
|
||||
|
||||
Category: Executable integration and documentation correctness.
|
||||
|
||||
**Evidence:** [scripts/release](../../scripts/release), line 9, executes
|
||||
`go run ./cmd/releasekit publish`. The Go driver exits 1 when its child exits
|
||||
2 or 3. [The runbook](../release.md) attributes the native CLI's distinct
|
||||
statuses to that wrapper.
|
||||
|
||||
Both `go run ./cmd/releasekit check invalid` and `./scripts/release invalid`
|
||||
returned shell status 1; the native CLI classifies invalid versions as 2.
|
||||
The same driver behavior loses the unknown-publication status 3.
|
||||
|
||||
**Required remediation:** Keep source bootstrap, but build and invoke the native
|
||||
executable with the prepared local toolchain so the maintainer entry point
|
||||
preserves its status. Keep generated tool output ignored or outside the
|
||||
worktree. Clarify the distinction for retained `go run` examples, and make
|
||||
runbook status claims match the actual entry point. This adds no publication,
|
||||
distribution, or external preparation gate.
|
||||
|
||||
**Focused verification:** The real wrapper preserves invalid-input status 2 and
|
||||
unknown-publication status 3, as well as ordinary success and known failure.
|
||||
Use local fixtures rather than a real publication endpoint.
|
||||
|
||||
**Resolution:** The source wrapper builds its native executable into ignored
|
||||
`.releasekit/bin` and invokes it directly. Documentation distinguishes native
|
||||
exit codes from `go run` driver behavior. Local-repository tests execute the
|
||||
actual wrapper and verify success 0, rejected publication 1, invalid input 2,
|
||||
and unresolved publication 3. The focused wrapper test passes.
|
||||
|
||||
### R9 — High: Manual recovery inspects the fetch endpoint
|
||||
|
||||
Status: Resolved.
|
||||
|
||||
Category: Release recovery correctness and documentation gap.
|
||||
|
||||
**Evidence:** [The runbook](../release.md), around line 82, prescribes
|
||||
`git ls-remote --refs origin refs/tags/<version>` and permits local-tag removal
|
||||
when that query returns absence. This query uses the normal fetch URL, whereas
|
||||
the selected publisher deliberately supports a separate push URL.
|
||||
|
||||
A local `origin` with different bare fetch and push repositories returned no
|
||||
tag through the documented query after that tag was successfully published to
|
||||
the push repository. The actual publication endpoint still contained the tag.
|
||||
The CLI's failure summary currently omits the captured endpoint present in
|
||||
`PublicationResult.Endpoint`.
|
||||
|
||||
**Required remediation:** Make recovery inspect the exact captured publication
|
||||
endpoint and intended tag object. Provide the needed endpoint information in
|
||||
CLI recovery output and accurate copyable instructions. Do not infer that a
|
||||
published version or local tag is safe to remove from absence at the fetch
|
||||
repository. Preserve the existing rule that unresolved publication retains the
|
||||
local tag.
|
||||
|
||||
**Focused verification:** Exercise the documented recovery path with separate
|
||||
fetch/push repositories and confirm that a published tag is recognized. Include
|
||||
endpoint changes after an uncertain push when verifying retained recovery facts.
|
||||
|
||||
**Resolution:** Failed publication output includes the captured endpoint. The
|
||||
runbook checks URL resolution and queries that exact endpoint, retaining tags
|
||||
on failed or unresolved checks. Local wrapper fixtures use separate fetch and
|
||||
push repositories; a lost acknowledgment changes the configured push URL, and
|
||||
recovery still finds the intended object at the captured endpoint while the
|
||||
fetch endpoint reports absence. The guarded runbook commands are exercised
|
||||
verbatim, including refusing a query after URL rewriting changes the endpoint.
|
||||
Focused publication/wrapper tests pass.
|
||||
|
||||
### R10 — Medium: The boundary checker bans valid command-internal composition
|
||||
|
||||
Status: Resolved.
|
||||
|
||||
Category: Inadvertently strengthened architectural prohibition.
|
||||
|
||||
**Evidence:** [checkImportDirections](../../internal/apicheck/main.go), around
|
||||
line 115, applies its blanket rejection of every `cmd/` import to command-owned
|
||||
internal packages too. A temporary overlay fixture supplied a dependency from
|
||||
`cmd/releasekit/internal/cli/parser` to
|
||||
`cmd/releasekit/internal/cli/settings`; the checker rejected it as importing a
|
||||
public or command package.
|
||||
|
||||
Both sides are internal helpers owned by the same executable. This composition
|
||||
respects the agreed separation of command parsing from facade calls. The
|
||||
checker adds a prohibition that would constrain ordinary internal refactoring.
|
||||
|
||||
**Required remediation:** Distinguish library internal packages, executable
|
||||
controllers, and command-owned internal helpers. Keep library dependencies
|
||||
inward and keep facade calls in the controller, while permitting coherent
|
||||
command-internal collaborators to use their own internal contracts. Avoid
|
||||
turning current package inventory into a fixed future architecture.
|
||||
|
||||
**Focused verification:** A command-internal helper dependency passes. Library
|
||||
internal imports of command code and internal-helper imports of public facades
|
||||
remain rejected.
|
||||
|
||||
**Resolution:** The import checker identifies each executable’s internal helper
|
||||
subtree and permits collaboration inside it. Library-to-command imports,
|
||||
helper-to-controller imports, and internal-to-facade imports remain rejected.
|
||||
Positive and negative dependency fixtures and the actual compiled repository
|
||||
boundary checks pass.
|
||||
|
||||
## Completion verification
|
||||
|
||||
The final uncached offline suite passes with `go test -count=1 ./...`, using
|
||||
`GOWORK=off`, `GOPROXY=off`, `GONOPROXY=none`, `GOSUMDB=off`, and
|
||||
`GOTOOLCHAIN=local`. `go run ./internal/apicheck` passes against the completed
|
||||
facades and dependency graph. All ten findings have resolution notes and
|
||||
focused behavioral evidence. Changed documentation's local links and fragments
|
||||
and prose whitespace validate. Each implementation unit and follow-up fix was
|
||||
committed separately with a plain English message; every commit is nonempty.
|
||||
|
||||
The current root facade contains declarations, explicit conversions, callback
|
||||
adaptation, and forwarding. Filesystem and artifact mechanics are internal;
|
||||
`buildinfo` retains its lightweight runtime boundary. The new source-eligibility
|
||||
fact records ordinary pre/post-build observations and adds no attestation or
|
||||
concurrency-proof snapshot guarantee. Hosted content remains immutable, and
|
||||
source publication remains independent of asynchronous delivery.
|
||||
|
||||
All verification used local Git and HTTP collaborators. No real source release,
|
||||
hosted delivery, consumer migration, or live CI activation was performed.
|
||||
|
||||
## Remediation boundaries
|
||||
|
||||
The completed work repairs the selected behavior and ownership boundaries,
|
||||
with focused regression checks for the reproduced defects. It preserves the
|
||||
two facades, selected publication
|
||||
standard, immutable hosted contents, lightweight runtime dependency graph,
|
||||
source-only hosted pages, and separate publication/delivery status.
|
||||
|
||||
The findings require no consumer migration, intermediate release, live service
|
||||
probe, or new human approval gate. After remediation, the maintainer can choose
|
||||
the broader testing, adoption, and deployment steps.
|
||||
4
ideas.md
4
ideas.md
@@ -1,4 +1,4 @@
|
||||
# ReleaseKit ideas
|
||||
|
||||
The [ReleaseKit proposal](docs/roadmap/releasekit.md) owns the shared release
|
||||
process ideas, proposed capabilities, and implementation plan.
|
||||
The [product roadmap](docs/roadmap/releasekit.md) records shared release-process
|
||||
adoption goals and remaining release and deployment work.
|
||||
|
||||
Reference in New Issue
Block a user