Files
ReleaseKit/docs/roadmap/implementation.md

537 lines
31 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ReleaseKit v0.2.0 implementation plan
Status: Agreed stages for the remaining v0.2.0 work.
This plan replaces the completed foundation sequence. It implements the target
state in [v0.2.0.md](v0.2.0.md), using the shared design in [model.md](model.md),
[ADR 0003](../adr/0003-declarative-validation.md), and
[ADR 0004](../adr/0004-module-selected-tooling.md). A Luna coding agent should
execute one numbered stage per prompt, in order.
## Current baseline and completion scope
At `3974a46`, the foundation and all six [remediation findings](remediation.md)
are complete. `Check` and `Publish` share candidate-request conversion and validation.
`internal/validation` runs the default offline suite and owns diagnostics and
candidate-tree access. Committed-file readers are offline; destination resolution
handles symlinks, parent traversal, cancellation, and absolute in-checkout paths.
The root error types and CLI presentation preserve findings and cause context.
`buildinfo` retains its independent runtime dependency graph.
The public validation specification and its JSON settings remain unimplemented.
The consumer CI template still selects an independent tool version. This sequence
completes every remaining release-roadmap capability and Audita's CI migration.
It ends with local verification and committed changes. Architecture review,
hosted deployment, release tagging, and decisions about further testing follow
this implementation.
| Release-roadmap item | Implementation stages |
| --- | --- |
| 1. Shared validation API/profile model | 1–3, 5–11, 15 |
| 2. Module-selected CI tool and Audita migration | 12–14 |
| 3. One suite with race selection | 1 |
| 4. Separate full vet | 2 |
| 5. Package compilation | 3 |
| 6. Expected publication endpoint | 4 |
| 7. Go formatting | 5 |
| 8. Markdown links and optional boundary | 9–11 |
| 9. Independent distribution rules | 6–7 |
| 10. Individual file size | 8 |
## Instructions for every stage
- Start with [development.md](../development.md) and applicable policies. Locate
current symbols with the codebase graph and inspect the worktree. The named
paths below describe the current baseline.
- Introduce each public and profile setting with its working capability, as
agreed. Update its GoDoc, configuration reference, consumer guidance, and
relevant CLI/internal documentation in that same stage.
- Use ordinary internal structs/functions and explicit facade conversions.
Keep product assertions in `AdditionalChecks` and profile `checks`.
- Select tests for the stage's actual risks under the
[testing policy](../policy/testing.md). Use local Git repositories, Go
packages, controlled command doubles, and HTTP fixtures. Default tests remain
offline and independent of real credentials or sibling checkouts.
- Verification lists describe required evidence, including existing tests.
Give each behavior a test owner: parser/checker tests cover syntax and rules;
candidate-tree and Git tests cover file access and resolution; conversion
tests cover each API/profile selection; shared orchestration tests cover
ordering, failure stopping, cancellation, and callback execution. Use
representative integration cases to verify these boundaries work together.
Add coverage where the change introduces a risk or leaves an evidence gap.
- Prepare newly selected development dependencies before offline validation.
Apply the [OSS policy](../policy/oss.md) when adding dependencies or adapting
third-party material, including any required attribution and license texts.
- Verify the focused outcome, stage its relevant changes, review the diff, and
create a nonempty commit with a short plain English message. Preserve unrelated
work, report the stage's outcome and verification, and stop until the next
stage is requested. These stages require local work and automated checks;
consumer changes in Stage 14 are committed in that repository.
## Design carried through the stages
### Public and profile declarations
The completed specification is facade-owned:
```go
type ValidationSpec struct {
Go GoValidationSpec
GoFormat bool
Markdown *MarkdownValidationSpec
ModuleDistribution ModuleDistributionValidationSpec
FileSize *FileSizeValidationSpec
}
type GoValidationSpec struct {
Race bool
FullVet bool
CompileTargets []Target
}
type MarkdownValidationSpec struct {
EnforceCheckoutBoundary bool
}
type ModuleDistributionValidationSpec struct {
WorkspaceFiles bool
LocalReplacements bool
}
type FileSizeValidationSpec struct {
LimitBytes *int64
Exclusions []string
}
```
Add `Validation ValidationSpec` and `ExpectedPushURL string` to `ReleaseRequest`.
`Target` is the existing root-facade operating-system/architecture pair. Each
stage adds only the fields it makes operational. The CLI owns corresponding
JSON structs and converts them in `cmd/releasekit`; internal production packages
use their own contracts.
| Go selection | Profile selection | Omitted/zero behavior |
| --- | --- | --- |
| `Go.Race` | `validation.go.race` | Ordinary native test suite |
| `Go.FullVet` | `validation.go.full_vet` | Existing test-time vet |
| `Go.CompileTargets` | `validation.go.compile_targets` | No package-compilation pass |
| `GoFormat` | `validation.go_format` | No formatting check |
| `Markdown` | `validation.markdown` | Nil/omitted/null disables the check; `{}` enables it |
| `Markdown.EnforceCheckoutBoundary` | `validation.markdown.enforce_checkout_boundary` | Outside-checkout links reported as out of scope |
| `ModuleDistribution.WorkspaceFiles` | `validation.module_distribution.workspace_files` | Rule disabled |
| `ModuleDistribution.LocalReplacements` | `validation.module_distribution.local_replacements` | Rule disabled |
| `FileSize` | `validation.file_size` | Nil/omitted/null disables the check; `{}` enables it |
| `FileSize.LimitBytes` | `validation.file_size.limit_bytes` | Nil/omitted/null selects 1,000,000 bytes when enabled |
| `FileSize.Exclusions` | `validation.file_size.exclusions` | No exclusions |
| `ExpectedPushURL` | `expected_push_url` | Empty/omitted disables the publication expectation |
Profile compilation targets use `GOOS/GOARCH` strings. Require a complete pair
because a partial target would otherwise silently select different compilation.
Use the existing Go target/environment mechanisms; let the selected Go toolchain
report unsupported targets. An artifact naming constraint does not determine
package-compilation compatibility.
Byte limits are integer counts; zero is an explicit zero-byte limit, and negative
counts are invalid. Exclusions are literal repository-relative file or directory
paths; directory selections include committed descendants. Match path boundaries
so excluding `assets` leaves `assets-other` selected. Ordinary relative path
normalization is sufficient. An unmatched exclusion has no effect. Metacharacters
remain literal Git path characters.
### Execution and ownership
The shared procedure is one native test suite, selected full vet, selected
package-compilation targets, and selected file checks, followed by product
checks and existing artifact builds/rechecks. File-check ordering is an internal
procedure: formatting, workspace files, local replacements, file size, then
Markdown. Stop after a failed check. A checker may return multiple findings;
this plan does not require collecting failures from every selected check.
Resolve the Go environment once per validation operation and reuse it. Native
race/vet work preserves the existing effective cgo/C-tool configuration. Static
package compilation uses `CGO_ENABLED=0`. The existing offline module/toolchain
controls remain owned by `internal/gotool`.
Pass settings through the root `candidateRequest`, `internal/candidate.Request`,
`internal/publish.Request`, and `validation.Request`. Both operations and their
CLI forms use the same decisions. Keep expected URL comparison in publication
preflight. Existing capture/rechecks, endpoint guards, recovery, publication
completion, and delivery outcomes retain their meaning.
Reuse the existing internal failures and facade conversion. Add stable identities
`go-vet`, `package-compile`, `go-format`, `workspace-files`, `local-replacements`,
`file-size`, and `markdown-links` as implemented. Supply paths, locations,
targets, directives, and measurements as applicable. Preserve causes and
cancellation through `errors.Is`/`errors.As`. CLI failures use existing exit
classifications and complete contextual presentation.
File checks share one candidate inventory per validation operation and load blobs
as needed. Inventory includes tracked vendor files and nested modules. Regular
source blobs feed formatting and Markdown parsing. Workspace-file detection
includes named symlink blobs; module parsing follows committed symlinks to
candidate-contained regular declarations. Unavailable selected input produces
an inspection error. File size measures regular and symlink blobs. Gitlinks have
no parent-tree blob size, and their contents remain outside the inspected tree.
### Dependencies and Markdown convention
Use standard `go/format` for Go formatting. Its convention follows the Go
standard library used to build ReleaseKit. Use `golang.org/x/mod/modfile` at
`golang.org/x/mod v0.40.0` for complete module-declaration parsing. Use
`github.com/yuin/goldmark/v2 v2.1.6` internally for Markdown AST parsing and source
positions. Both selected module manifests support the existing Go 1.25 baseline;
implementation should record their exact source revisions and notices under the
OSS policy. References: [modfile](https://pkg.go.dev/golang.org/x/mod/modfile)
and [Goldmark](https://github.com/yuin/goldmark/tree/v2.1.6).
PromptKit's current script supplies the starting heading/link examples. Preserve
its basic anchor transformation: lowercase heading text, retain Unicode letters
and numbers, underscore, hyphen, and spaces, then replace spaces with hyphens.
Use visible heading text from the Markdown AST, including inline code text and
excluding HTML tags/formatting delimiters. Support ATX and Setext headings. For
repeated headings, append increasing numeric suffixes starting at `-1`, selecting
an unused identifier when a generated suffix collides with another heading.
Document these refinements to the starting script's behavior.
Recognize inline links, images, and full/collapsed/shortcut reference links through
the parser. Code blocks and inline code supply examples rather than link nodes.
Raw HTML destinations remain outside this Markdown-link capability. Undefined
references rendered as ordinary text by the parser are not a new Markdown lint
rule. Decode Markdown escapes/entities through the parser and percent escapes
once when resolving URI path/fragment components. Ignore URI query components
for file existence. Empty paths target the source document; an empty fragment
selects its top. Schemed and protocol-relative URIs receive no availability
request. Fragment checking applies to regular Markdown destinations; other
existing files/directories receive existence checking.
Use committed destination resolution and cached parsed documents/anchors.
Missing destinations, unresolved cycles, and missing supported anchors fail the
selected Markdown check. Actual outside-checkout destinations are reported as
out of scope by default and fail with boundary enforcement. Submodule-content
observations remain reported as out of scope under either setting: the boundary
option concerns checkout escape and does not establish a submodule prohibition.
Write nonfailure observations to the supplied output writer; a nil writer
selects ordinary quiet library use. Diagnostics identify the source use site,
location, and destination. Document source columns as one-based byte columns.
### CI tool bootstrap
Build using temporary copies of the released application's `go.mod` and `go.sum`,
with Go's alternate `-modfile` and normal module preparation in those copies.
Confirm that ReleaseKit is already selected before building its command. This
preserves the application's version declaration and require/replace semantics
while allowing missing tool-only indirect requirements/checksums to be prepared
without dirtying immutable tagged source. It supports consumers whose application
imports only lightweight `buildinfo`. Stages 12–14 implement this agreed approach.
## Stage 1: Introduce the specification with race selection
**Outcome:** The first public/profile selection changes the one existing suite.
1. Add `ReleaseRequest.Validation`, `ValidationSpec.Go`, and
`GoValidationSpec.Race`, plus equivalent CLI-owned JSON settings. Add explicit
conversions through both candidate and publication request paths.
2. Build the base invocation in `internal/validation`: preserve
`go test -mod=readonly -count=1 ./...`, adding `-race` when selected. Reuse
the native Go environment and report tool/prerequisite failures as `go-test`.
3. Preserve additional-check and build ordering. Update exact API/profile
references and add a minimal consumer example for the selection.
**Verification:** Default and selected invocations, exactly one suite, API/profile
selection equivalence, both operations, unavailable race prerequisites with no
silent fallback, preserved causes/cancellation, and failure before product
checks/builds/tag creation. Use a small real race-enabled fixture on supported
hosts and a controlled Go command for portable prerequisite-failure coverage.
## Stage 2: Coordinate a separate full vet pass
**Outcome:** Full vet replaces test-time vet overlap through one declaration.
1. Add `Go.FullVet` and `validation.go.full_vet` through the same conversion path.
2. When enabled, add `-vet=off` to the one test invocation and run native
`go vet -mod=readonly ./...` afterward using the same tool/environment.
3. Attribute vet failures to `go-vet` and update canonical usage guidance.
**Verification:** Ordinary, race-only, vet-only, and combined selections; one
suite; vet after successful tests; suppression of test-time vet only when
selected; failure/cancellation stopping; default behavior and API/profile parity.
Protect the selected command relationship without freezing incidental flag order.
## Stage 3: Compile packages for selected targets
**Outcome:** Source compatibility checks work independently of artifacts.
1. Add `Go.CompileTargets` and string-array profile targets. Convert to internal
Go targets and validate complete pairs consistently for API and profile use.
2. After test/vet, run `go build -mod=readonly -o <os.DevNull> ./...` in static
mode for each selected target. The Go build null-output mode suppresses
executable output, including a module with a single main package.
3. Report failures as `package-compile`, including the selected target. Keep
output names, linker version injection, smoke tests, receipts, and manifests
in artifact building. Document compilation versus target execution.
**Verification:** Linux amd64/arm64, a supported additional Go pair, source-only
library, single-main and multiple-main modules (including repeated executable
basenames), target failure, unchanged candidate files, `CGO_ENABLED=0`, preserved
ordering, and page-only delivery with compilation selected but no build targets.
Reuse the existing Go environment tests for controls already protected there.
## Stage 4: Compare the optional expected push URL
**Outcome:** Publication rejects a different effective destination before validation.
1. Add `ExpectedPushURL` and `expected_push_url`, with an empty value selecting
existing behavior. Carry it only into the publication request.
2. Immediately after resolving/capturing `endpoint.PushURL`, compare exact strings.
Report expected and resolved values through a publication preflight error.
Add `ErrUnexpectedPushURL` as a public sentinel using the existing shared-error
ownership pattern so callers can use `errors.Is`.
3. Keep later endpoint rechecks and reconciliation intact. Update GoDoc,
publication guidance, and the profile reference.
**Verification:** Omitted/matching/mismatching values, Git `insteadOf` resolution,
separate fetch/push URLs, exact spelling differences, mismatch before Go/callbacks
or tag creation, and a local-only `Check` that ignores the publication expectation.
Existing endpoint-change and uncertain-push tests keep their ownership.
## Stage 5: Check committed Go formatting
**Outcome:** A declaration replaces tracked-file formatting loops.
1. Add `GoFormat` and `validation.go_format` with working executor integration.
2. Load the shared captured inventory and apply `format.Source` to regular `.go`
blobs. Compare original and formatted bytes, preserving repository contents.
3. Return `go-format` findings for affected paths and preserve parser/inspection
causes. Update usage and formatting-convention documentation.
**Verification:** Formatted and unformatted files, parse errors, vendor/nested
source, unusual filenames, committed versus worktree bytes, disabled/default
behavior, API/profile parity, and failure before later product/build work.
## Stage 6: Select committed workspace-file inspection
**Outcome:** One distribution rule works independently of the Go environment.
1. Add `ModuleDistributionValidationSpec.WorkspaceFiles` and the matching JSON
group/field. The remaining rule is added in Stage 7.
2. Inspect committed blob entries named `go.work` or `go.work.sum`, including
nested and symlink entries. Report paths using `workspace-files`.
3. Keep testing's existing workspace setting and consumer vendor choices in their
current owners. Document the distinction between environment and distribution.
**Verification:** Either workspace filename, nested paths, symlink names,
committed files with `GOWORK=off`, uncommitted files excluded from inspection,
selection disabled, and shared API/profile execution. Use meaningful rule cases
rather than retesting Git enumeration mechanics.
## Stage 7: Select filesystem replacement inspection
**Outcome:** The second distribution rule parses actual module declarations.
1. Add `ModuleDistribution.LocalReplacements` and the equivalent profile field.
Prepare `golang.org/x/mod v0.40.0`, module sums, and required OSS notices.
2. Parse committed `go.mod` files with `modfile.Parse`, including nested/vendor
declarations. Resolve symlink declarations within the candidate; report an
inspection error when their selected contents cannot be obtained locally.
3. Identify filesystem replacements by the parsed replacement's absent version;
permit versioned replacements. Report path, directive/source location, and
target through `local-replacements`, preserving parse/inspection causes.
4. Document independent distribution selections and their inspection scope.
**Verification:** Single and block directives, comments, quoted paths, relative
and absolute filesystem targets, versioned replacements, nested declarations,
valid/broken symlinks, parse failure, and all independent boolean combinations.
The rule applies to candidate contents even when testing disables workspace use.
## Stage 8: Inspect individual committed file sizes
**Outcome:** Optional limits and intentional path exceptions are operational.
1. Add `FileSizeValidationSpec`, `ValidationSpec.FileSize`, and matching JSON
fields according to the declaration table. Validate nonnegative byte limits.
2. Use shared blob sizes for regular files and symlink link-text blobs. Apply
literal file/directory exclusions. On an oversized blob, return `file-size`
with its path and existing `FileSizeMeasurement` fields; reporting one offending
file per failure fits the current diagnostic model.
3. Document decimal bytes, strict greater-than comparison, exclusions, and
current-candidate scope. Preserve default disabled behavior.
**Verification:** Below/at/above limits, the exact 1,000,000-byte enabled default,
zero/custom/negative limits, nil versus empty objects, directory/path boundaries,
literal metacharacters, unmatched exclusions, small binaries, symlink sizes, and
omitted submodule sizes. Historical and aggregate size do not become release gates.
## Stage 9: Implement internal Markdown parsing and anchors
**Outcome:** A parser with source positions and documented anchor semantics is ready.
1. Add `github.com/yuin/goldmark/v2 v2.1.6`, prepared dependencies, and applicable
OSS notices. Keep parser types inside internal implementation.
2. Parse links/images, reference uses, headings, and source positions into small
internal records. Derive visible heading text and apply the convention above.
3. Cache parsed records/anchors per candidate document. Keep this stage internal;
Stage 11 adds the public selection once complete checking works.
4. Compare fixtures with PromptKit's starting examples. Record intended refinements
in the roadmap until the public behavior lands, avoiding a second regex parser.
**Verification:** Inline/reference forms and images, escaped/parenthesized
and angle-bracket destinations, optional titles, code fences/inline code,
Unicode/entity headings, ATX/Setext headings, repeated headings and suffix
collisions, and source use-site locations including repeated reference uses.
Undefined references and HTML prose remain governed by parser interpretation.
## Stage 10: Implement internal destination and fragment checking
**Outcome:** Committed Markdown navigation is checked with boundary observations.
1. Resolve parsed local URI components through `CandidateTree.ResolveDestination`.
Apply escaping/query/fragment rules above and use actual resolved identities
for target-document anchor lookup.
2. Check committed existence and supported heading fragments, recording source
path/location/target. Produce `markdown-links` failures and distinct nonfailure
observations for outside-checkout and submodule contents.
3. Implement optional checkout-boundary enforcement internally. Preserve the
distinction between external URIs, checkout escapes, and uninspected submodules.
4. Reuse remediated symlink/cancellation/local-object behavior. Keep parsing,
resolution, and rule evaluation in ordinary internal functions.
**Verification:** Valid/missing files and anchors, same-document/empty fragments,
percent-escaped paths and fragments, query strings, directories and non-Markdown
files, outside links with both settings, and submodule observations. Check how
resolver results and inspection errors become Markdown findings, preserving
causes and cancellation. Use representative committed-tree integration cases
and verify unchanged candidate/worktree bytes. Existing candidate-tree and Git
tests own detailed absolute-path, symlink-parent, cycle, neighboring-file,
missing-object, and traversal-cancellation cases.
## Stage 11: Expose Markdown selection and complete validation integration
**Outcome:** All agreed validation selections work through both public operations.
1. Add `MarkdownValidationSpec`, `ValidationSpec.Markdown`, and their JSON fields.
Enable on a non-nil group/empty object and map the boundary boolean explicitly.
2. Wire the checker and nonfailure observations into the shared executor/output
writer. Reuse existing facade/CLI diagnostic formatting and exit classification.
3. Document the newly operational Markdown selection in its canonical owners.
Review earlier stages' GoDoc, configuration, check/publish guides, CLI reference,
internal inventory, and examples for consistency across combined selections.
4. Use self-contained fixtures representing Audita defaults/artifacts, ConfigKit's
race/vet/compilation, and PromptKit's shared settings plus example assertions.
Document how consumers remove duplicate generic commands when adopting settings.
**Verification:** Equivalent Go/profile declarations, nil/empty/null Markdown
settings, warnings with successful results, boundary failures before product/build
work, all-zero compatibility, representative combined selections, one suite and
one additional-check callback. Run the compiled API/dependency check, including
`buildinfo`'s standard-library/runtime-only dependency boundary.
## Stage 12: Build the CI tool from verified released module configuration
**Outcome:** The standard template has one tool-version declaration.
1. Revise `examples/woodpecker/tag-delivery.yml` into a compact bootstrap/delivery
step. Use available Git to validate/fetch the explicit event tag, compare its
peeled commit to the full provider object ID using existing case-insensitive
object-ID semantics, check out that commit detached, and confirm HEAD and
the existing clean tagged-source requirement. This ensures module files
actually belong to the verified release before selecting the tool.
Do this before reading/resolving the application module or executing Go.
2. Apply the agreed CI tool bootstrap approach: create a disposable directory
outside the source checkout, copy its `go.mod` and existing `go.sum`, and use
an alternate `-modfile` for tool resolution/build.
Run from the verified source with `GOWORK=off` and `GOTOOLCHAIN=local`.
3. Confirm the ReleaseKit module is already selected by that module configuration
using `go list -m`; then build its `cmd/releasekit` package without an `@version`
suffix. Allow ordinary network-capable module preparation in the temporary
metadata copies (`-mod=mod`). Respect selected require/replace relationships.
4. Invoke the resulting native executable's existing `ci-deliver` with the event
repository, commit, and tag. Keep delivery credentials in the existing delivery
step and use an exit cleanup trap for temporary metadata and executable files.
5. Remove the independent `RELEASEKIT_VERSION` workflow setting. Preserve current
Go-image customization, destination/profile ownership, and delivery outcomes.
Keep the bootstrap Git block small; the built tool retains its runtime guards.
**Verification:** Execute maintained template commands with a local tag/module
fixture and instrument Go/transport operations. Prove wrong tag/commit stops
before module resolution/build, a dirty module cannot select a different tool,
the verified checkout selects the tool, module metadata and source remain
unchanged, and the executable/temporary files are cleaned up. Tool metadata
preparation is separate from offline candidate checks. Include a representative
case that verifies invocation of the selected executable with the event arguments
and propagation of its exit status. Existing delivery tests own hosted behavior.
## Stage 13: Verify upgrades, retries, and bootstrap variants
**Outcome:** Tool selection follows the triggering release across supported uses.
1. Extend Stage 12's bootstrap fixtures with a local module proxy for two tool
versions and tagged consumer module configurations. Execute the maintained
workflow body against both.
Keep live infrastructure outside the default test suite.
2. Verify a retry of an older tag still selects that tag's module configuration
when the default branch has upgraded. Include missing tool-only checksums and
an existing versioned replacement to protect source-based resolution.
3. Align `releasekit-source-delivery.yml` with source verification before self
bootstrap and temporary output. Preserve self-bootstrap from `./cmd/releasekit`
and separately installed-tool guidance using the existing command.
4. Update delivery/configuration/CLI guidance and maintained templates together.
Explain compatible Go environments, dependency preparation, immutable-source
retries, and the distinct tool/app artifact preparation steps.
**Verification:** Two dependency versions, older-source retries, self bootstrap,
and separately installed tool, using the shared bootstrap fixtures. Existing
delivery and publication tests retain ownership of source-only pages, binary
delivery, destination handling, and publication states. Add integration coverage
for any new interaction introduced by bootstrap changes. An application without
a declared ReleaseKit dependency uses the installed-tool integration.
## Stage 14: Migrate Audita's local CI integration
**Outcome:** Audita's local wrapper and CI select the same module-declared tool.
1. Read `../audita` orientation/policies and inspect its worktree before editing.
Adapt `.woodpecker/release.yml` to the maintained module-based template,
preserving its Go image, Gitea secret name, and release profile.
2. Retain its existing released ReleaseKit module selection for this migration;
that version already supplies `ci-deliver`. Make any necessary adjustments to
`scripts/release.sh` for the selected bootstrap metadata approach, preserving
arguments and native executable exit behavior. Keep generated tool output
outside the candidate source where needed.
3. Verify the consumer's actual wrapper/workflow using local tagged fixtures and
prepared module caches. Confirm matching tool selection, preserved arguments
and exit status, and unchanged source files. Review the diff for preservation
of the release profile and binary targets. Existing consumer and ReleaseKit
tests retain ownership of source validation and hosted delivery behavior.
4. Commit the focused migration in Audita with a plain English message. Record
its commit and local verification in this plan's implementation status.
**Verification:** The actual adapted consumer declarations use one dependency
version; local and CI bootstraps agree and retain existing caller arguments/status
semantics. Keep integration fixtures self-contained in ReleaseKit's default suite.
This migration uses an existing release and requires no intermediate publication
or live Woodpecker/Gitea run to complete the stage.
## Stage 15: Audit the completed v0.2.0 implementation
**Outcome:** The entire scoped feature set is implemented and locally verified.
1. Match every row in the roadmap/stage table to implemented settings, execution,
diagnostics, current documentation, and focused behavioral evidence. Verify
all-zero compatibility, independent distribution choices, one coordinated Go
suite, source-only compilation/delivery, and selected endpoint preflight.
2. Review new code and tests for unintended defaults, restrictions, caps, or
stronger guarantees. Preserve user choice and the existing facade boundaries.
3. Run `go test ./...` and `go run ./internal/apicheck`. Add further integration
coverage only for a concrete remaining risk. Check documentation links,
fragments, whitespace, dependency notices, and maintained examples.
4. Update statuses in this plan, the release roadmap, and the model roadmap to
reflect actual completion, including the Audita migration evidence. Update
canonical current-behavior owners as needed and remove stale prospective text.
5. Commit the completed unit, report each stage's outcome and remaining work,
and finish with a clean workspace while preserving any unrelated user changes.
The subsequent architecture review and release/testing decisions follow here.
## Open Questions
None.