2026-10-07 21:25:58 +00:00
|
|
|
|
# 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.
|
|
|
|
|
|
|
2026-10-07 22:18:47 +00:00
|
|
|
|
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.
|
2026-10-07 21:25:58 +00:00
|
|
|
|
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.
|
2026-10-07 21:34:28 +00:00
|
|
|
|
- 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.
|
2026-10-07 21:25:58 +00:00
|
|
|
|
- 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
|
2026-10-07 21:34:28 +00:00
|
|
|
|
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.
|
2026-10-07 21:25:58 +00:00
|
|
|
|
|
|
|
|
|
|
## Design carried through the stages
|
|
|
|
|
|
|
|
|
|
|
|
### Public and profile declarations
|
|
|
|
|
|
|
|
|
|
|
|
The completed specification is facade-owned:
|
2026-10-07 17:14:26 +00:00
|
|
|
|
|
|
|
|
|
|
```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
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2026-10-07 21:25:58 +00:00
|
|
|
|
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.
|
2026-10-07 17:14:26 +00:00
|
|
|
|
|
|
|
|
|
|
### Execution and ownership
|
|
|
|
|
|
|
2026-10-07 21:25:58 +00:00
|
|
|
|
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
|
2026-10-07 23:17:10 +00:00
|
|
|
|
once when resolving URI path/fragment components. Compare decoded fragments in
|
|
|
|
|
|
lowercase to preserve PromptKit's starting convention. 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
|
2026-10-07 21:25:58 +00:00
|
|
|
|
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
|
|
|
|
|
|
|
2026-10-07 22:10:34 +00:00
|
|
|
|
**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.
|
|
|
|
|
|
|
2026-10-07 21:25:58 +00:00
|
|
|
|
**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
|
|
|
|
|
|
|
2026-10-07 22:18:47 +00:00
|
|
|
|
**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.
|
|
|
|
|
|
|
2026-10-07 21:25:58 +00:00
|
|
|
|
**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
|
|
|
|
|
|
|
2026-10-07 22:27:31 +00:00
|
|
|
|
**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.
|
|
|
|
|
|
|
2026-10-07 21:25:58 +00:00
|
|
|
|
**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
|
|
|
|
|
|
|
2026-10-07 22:31:58 +00:00
|
|
|
|
**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.
|
|
|
|
|
|
|
2026-10-07 21:25:58 +00:00
|
|
|
|
**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
|
|
|
|
|
|
|
2026-10-07 22:39:15 +00:00
|
|
|
|
**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.
|
|
|
|
|
|
|
2026-10-07 21:25:58 +00:00
|
|
|
|
**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
|
|
|
|
|
|
|
2026-10-07 22:45:47 +00:00
|
|
|
|
**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.
|
|
|
|
|
|
|
2026-10-07 21:25:58 +00:00
|
|
|
|
**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
|
|
|
|
|
|
|
2026-10-07 22:51:55 +00:00
|
|
|
|
**Completion:** Complete. `Validation.ModuleDistribution.LocalReplacements` and
|
|
|
|
|
|
`validation.module_distribution.local_replacements` parse committed `go.mod`
|
|
|
|
|
|
declarations, including nested/vendor files and committed symlink declarations.
|
|
|
|
|
|
Filesystem replacements report their declaration path, line, directive, and
|
|
|
|
|
|
target as `local-replacements`; versioned replacements are permitted. Parse and
|
|
|
|
|
|
inspection failures retain their causes, and this rule is independent of both
|
|
|
|
|
|
workspace-file selection and `GOWORK`.
|
|
|
|
|
|
|
2026-10-07 21:25:58 +00:00
|
|
|
|
**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
|
|
|
|
|
|
|
2026-10-07 22:58:38 +00:00
|
|
|
|
**Completion:** Complete. `Validation.FileSize` and `validation.file_size` enable
|
|
|
|
|
|
a per-blob decimal-byte limit with a 1,000,000-byte default, strict greater-than
|
|
|
|
|
|
comparison, and literal repository-relative file/directory exclusions. The check
|
|
|
|
|
|
uses captured blob sizes, counts symlink link text, omits gitlinks, and reports
|
|
|
|
|
|
one oversized file with its measurement. Nil disables the check, and historical
|
|
|
|
|
|
or aggregate repository size is outside its scope.
|
|
|
|
|
|
|
2026-10-07 21:25:58 +00:00
|
|
|
|
**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
|
|
|
|
|
|
|
2026-10-07 23:07:50 +00:00
|
|
|
|
**Completion:** Complete. Goldmark now records parsed links, images, reference
|
|
|
|
|
|
uses, use-site locations, and collision-free heading anchors behind an internal
|
|
|
|
|
|
per-candidate document cache. Its behavior remains unselected until the later
|
|
|
|
|
|
validation-integration stage.
|
|
|
|
|
|
|
2026-10-07 21:25:58 +00:00
|
|
|
|
**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.
|
|
|
|
|
|
|
2026-10-07 23:07:50 +00:00
|
|
|
|
**Parser refinements:** PromptKit's starting script scans inline links, images,
|
|
|
|
|
|
and ATX headings with regular expressions. The Goldmark parser also records
|
|
|
|
|
|
resolved full, collapsed, and shortcut reference uses at each source use site.
|
|
|
|
|
|
Heading anchors use decoded visible AST text, include inline code,
|
|
|
|
|
|
exclude raw HTML tags, and support Setext headings. Parser-recognized CommonMark
|
|
|
|
|
|
autolinks are recorded alongside inline and reference links. Repeated-heading
|
|
|
|
|
|
suffixes skip identifiers already used by another heading.
|
|
|
|
|
|
|
2026-10-07 21:25:58 +00:00
|
|
|
|
**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
|
|
|
|
|
|
|
2026-10-07 23:17:10 +00:00
|
|
|
|
**Completion:** Complete. The internal checker resolves committed destinations,
|
|
|
|
|
|
checks supported fragments, preserves inspection errors, and reports distinct
|
|
|
|
|
|
outside-checkout and submodule observations. Public selection and shared executor
|
|
|
|
|
|
wiring remain in Stage 11.
|
|
|
|
|
|
|
2026-10-07 21:25:58 +00:00
|
|
|
|
**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.
|
|
|
|
|
|
|
2026-10-07 23:17:10 +00:00
|
|
|
|
**Resolution refinement:** URI query components do not participate in path
|
|
|
|
|
|
checking. Compare fragments after one percent-decoding pass and lowercase them
|
|
|
|
|
|
to preserve PromptKit's starting anchor matching.
|
|
|
|
|
|
|
2026-10-07 21:25:58 +00:00
|
|
|
|
**Verification:** Valid/missing files and anchors, same-document/empty fragments,
|
|
|
|
|
|
percent-escaped paths and fragments, query strings, directories and non-Markdown
|
2026-10-07 21:34:28 +00:00
|
|
|
|
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.
|
2026-10-07 21:25:58 +00:00
|
|
|
|
|
|
|
|
|
|
## 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.
|
2026-10-07 21:34:28 +00:00
|
|
|
|
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.
|
2026-10-07 21:25:58 +00:00
|
|
|
|
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
|
2026-10-07 21:34:28 +00:00
|
|
|
|
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.
|
2026-10-07 21:25:58 +00:00
|
|
|
|
|
|
|
|
|
|
## Stage 13: Verify upgrades, retries, and bootstrap variants
|
|
|
|
|
|
|
|
|
|
|
|
**Outcome:** Tool selection follows the triggering release across supported uses.
|
|
|
|
|
|
|
2026-10-07 21:34:28 +00:00
|
|
|
|
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.
|
2026-10-07 21:25:58 +00:00
|
|
|
|
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,
|
2026-10-07 21:34:28 +00:00
|
|
|
|
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.
|
2026-10-07 21:25:58 +00:00
|
|
|
|
|
|
|
|
|
|
## 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;
|
2026-10-07 21:34:28 +00:00
|
|
|
|
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.
|
2026-10-07 21:25:58 +00:00
|
|
|
|
3. Verify the consumer's actual wrapper/workflow using local tagged fixtures and
|
2026-10-07 21:34:28 +00:00
|
|
|
|
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.
|
2026-10-07 21:25:58 +00:00
|
|
|
|
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.
|