570 lines
32 KiB
Markdown
570 lines
32 KiB
Markdown
# 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 shared validation specification and profile settings are implemented
|
||
incrementally with each capability; remaining selections are not yet
|
||
implemented. 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
|
||
|
||
**Completion:** Complete. `ReleaseRequest.Validation.Go.Race` and profile
|
||
`validation.go.race` select `-race` for the single native Go suite. Both
|
||
candidate operations share the selection, and race failures retain the `go-test`
|
||
identity without falling back to an ordinary suite.
|
||
|
||
**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
|
||
|
||
**Completion:** Complete. `ReleaseRequest.Validation.Go.FullVet` and profile
|
||
`validation.go.full_vet` disable test-time vet for the one native test suite and
|
||
run native `go vet -mod=readonly ./...` afterward. Vet failures retain the
|
||
`go-vet` identity, and the selection is shared by the API and profile paths.
|
||
|
||
**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
|
||
|
||
**Completion:** Complete. `Go.CompileTargets` and profile
|
||
`validation.go.compile_targets` select static package compilation after tests
|
||
and vet. Failures use `package-compile` and include the selected target;
|
||
artifact building remains separate.
|
||
|
||
**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
|
||
|
||
**Completion:** Complete. `ReleaseRequest.ExpectedPushURL` and profile
|
||
`expected_push_url` require an exact match with Git's resolved effective push
|
||
URL before validation. Mismatches return `ErrUnexpectedPushURL` with expected
|
||
and resolved values; `Check` ignores the publication-only expectation.
|
||
|
||
**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
|
||
|
||
**Completion:** Complete. `ValidationSpec.GoFormat` and profile
|
||
`validation.go_format` run `go/format` on regular Go blobs from the captured
|
||
commit. Findings identify unformatted paths; parser and inspection failures
|
||
retain their causes, and the check leaves repository contents unchanged.
|
||
|
||
**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
|
||
|
||
**Completion:** Complete. `Validation.ModuleDistribution.WorkspaceFiles` and
|
||
`validation.module_distribution.workspace_files` report committed blob entries
|
||
named `go.work` or `go.work.sum`, including nested paths and symlinks. The rule
|
||
inspects the captured candidate independently of `GOWORK` and leaves the Go
|
||
workspace environment and vendor behavior unchanged.
|
||
|
||
**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.
|