Retire completed roadmaps and retain pending adoption work
This commit is contained in:
@@ -117,9 +117,7 @@ for product behavior.
|
|||||||
## Go command environment reuse
|
## Go command environment reuse
|
||||||
|
|
||||||
The current executor uses the [shared Go command environment](gotool.md) for
|
The current executor uses the [shared Go command environment](gotool.md) for
|
||||||
its offline suite, vet pass, and selected-target package compilation. The
|
its offline suite, vet pass, and selected-target package compilation.
|
||||||
[implementation roadmap](../roadmap/implementation.md#execution-and-ownership)
|
|
||||||
records the shared ordering across validation and later file checks.
|
|
||||||
|
|
||||||
Reuse `internal/gotool` for native and static environments and target handling.
|
Reuse `internal/gotool` for native and static environments and target handling.
|
||||||
Keep toolchain and module-cache discovery in `gotool`; do not reproduce its
|
Keep toolchain and module-cache discovery in `gotool`; do not reproduce its
|
||||||
@@ -140,7 +138,6 @@ symlink expansion detects cycles, and traversal honors cancellation. Absolute
|
|||||||
destinations and symlink targets within the repository directory map back to
|
destinations and symlink targets within the repository directory map back to
|
||||||
candidate-relative paths; existence still comes from committed entries.
|
candidate-relative paths; existence still comes from committed entries.
|
||||||
|
|
||||||
The [implementation plan](../roadmap/implementation.md) records the completed
|
The public selection is owned by the facade and profile;
|
||||||
Markdown integration. The public selection is owned by the facade and profile;
|
|
||||||
the internal checker uses the committed-file and destination-resolution
|
the internal checker uses the committed-file and destination-resolution
|
||||||
primitives described here.
|
primitives described here.
|
||||||
|
|||||||
@@ -1,67 +0,0 @@
|
|||||||
# Feature request from ConfigKit: adaptable release validation
|
|
||||||
|
|
||||||
Status: Requested by a prospective downstream consumer; not yet adopted by
|
|
||||||
ReleaseKit.
|
|
||||||
|
|
||||||
ConfigKit would like to adopt ReleaseKit's common source-release process and
|
|
||||||
retire most of its repository-owned release scripts and publication tests. It is
|
|
||||||
a source-only Go library. ConfigKit can follow ReleaseKit's existing convention
|
|
||||||
of publishing the candidate to `main` before running the tag-publication
|
|
||||||
command; it does not need binary artifacts or a different source-publication
|
|
||||||
sequence.
|
|
||||||
|
|
||||||
## Select one base Go test invocation
|
|
||||||
|
|
||||||
ReleaseKit's [candidate check](../consumers/check.md) currently runs its
|
|
||||||
standard `go test` suite before any configured additional checks. ConfigKit's
|
|
||||||
selected release validation includes a race-enabled run of its full test
|
|
||||||
suite, with a separate full vet pass. Expressing the race run as an additional
|
|
||||||
check would run the suite twice and retain avoidable consumer-specific release
|
|
||||||
wiring.
|
|
||||||
|
|
||||||
Please provide a small public API and profile capability for a consumer to
|
|
||||||
select its **one base Go test invocation** for candidate validation. The
|
|
||||||
selection should replace the default invocation, rather than add a second test
|
|
||||||
run. Without a selection, ReleaseKit's current default remains useful. Both
|
|
||||||
`Check` and `Publish`, including their CLI forms, should use the selected
|
|
||||||
invocation consistently while ReleaseKit continues to own candidate capture,
|
|
||||||
validation order, result reporting, and publication. ConfigKit needs to select
|
|
||||||
a full-suite race run with test-time vet omitted because it selects a separate
|
|
||||||
full vet pass. ReleaseKit can choose the simplest public expression of that
|
|
||||||
choice; ConfigKit is not asking for a general-purpose release pipeline or
|
|
||||||
consumer-owned orchestration.
|
|
||||||
|
|
||||||
## Evaluate shared release checks
|
|
||||||
|
|
||||||
ConfigKit also uses a separate full `go vet` pass and compile checks for Linux
|
|
||||||
amd64 and arm64. Please assess whether these checks are useful enough across
|
|
||||||
ReleaseKit consumers to offer directly through its public API and profile,
|
|
||||||
either as defaults or as selected options where product support differs.
|
|
||||||
|
|
||||||
In particular, a source-only library needs to verify that its packages compile
|
|
||||||
for selected targets without declaring executable artifacts or adding delivery
|
|
||||||
work. ReleaseKit could make that distinction available to consumers. The goal
|
|
||||||
is to keep these checks, when selected, within the same candidate validation
|
|
||||||
and publication flow without repeating work already done by the base test.
|
|
||||||
Whether race, vet, or cross-target compilation should be common defaults is a
|
|
||||||
ReleaseKit product decision; ConfigKit asks for an assessment, not a universal
|
|
||||||
new release gate.
|
|
||||||
|
|
||||||
## Optional publication endpoint expectation
|
|
||||||
|
|
||||||
ConfigKit currently identifies one expected authoritative Git destination. An
|
|
||||||
optional expected-endpoint setting in ReleaseKit's public API and profile could
|
|
||||||
let a consumer verify that the selected remote resolves to its declared
|
|
||||||
destination before publication. Please consider whether this is broadly useful
|
|
||||||
and simpler than retaining a small consumer-owned preflight check. Existing
|
|
||||||
ReleaseKit remote selection and endpoint handling should remain the common
|
|
||||||
publication model.
|
|
||||||
|
|
||||||
## Adoption outcome
|
|
||||||
|
|
||||||
A useful outcome would let ConfigKit declare its product identity, selected
|
|
||||||
validation, and any expected publication destination, then rely on ReleaseKit's
|
|
||||||
standard candidate check and tag-publication command. ConfigKit would retain
|
|
||||||
its compatibility decisions and release notes while removing duplicated release
|
|
||||||
mechanics. Source publication would still complete at the confirmed tag push;
|
|
||||||
CI and hosted delivery would remain separate from that completion point.
|
|
||||||
@@ -1,182 +0,0 @@
|
|||||||
# Feature Request From PromptKit: Shared Release Validation
|
|
||||||
|
|
||||||
Status: Requested by a prospective downstream consumer; not yet adopted by
|
|
||||||
ReleaseKit.
|
|
||||||
|
|
||||||
Date: 2026-10-07.
|
|
||||||
|
|
||||||
This request derives from PromptKit's
|
|
||||||
[ReleaseKit adoption assessment](https://gitea.maximumdirect.net/eric/promptkit/src/commit/7310ef34a44dae7288db7b281e2a6b7f2c56c4e9/docs/roadmap/releasekit.md),
|
|
||||||
which reviewed ReleaseKit `v0.1.0`. It describes downstream needs and leaves
|
|
||||||
public API design, shared defaults, and implementation choices to ReleaseKit.
|
|
||||||
|
|
||||||
## Consumer Context And Goal
|
|
||||||
|
|
||||||
PromptKit is a source-only Go library with concurrent LLM execution and
|
|
||||||
backend-capacity management. It would like to adopt ReleaseKit's common
|
|
||||||
source-publication process and reduce its own release infrastructure to
|
|
||||||
product settings and a few substantive project checks. Its existing release
|
|
||||||
scripts contain 209 lines, most of which implement validation rather than
|
|
||||||
publication.
|
|
||||||
|
|
||||||
PromptKit accepts changes to its release process in exchange for a common
|
|
||||||
standard and lower maintenance. The opportunity is to share useful validation
|
|
||||||
capabilities, rather than preserve every existing shell command or local rule.
|
|
||||||
Its consumer-example assertions and compatibility decisions remain meaningful
|
|
||||||
project responsibilities.
|
|
||||||
|
|
||||||
The four primary requests below concern reusable validation. Two additional
|
|
||||||
candidates are included for evaluation if their wider value justifies shared
|
|
||||||
support. PromptKit's choices about race testing, full vet, and credential
|
|
||||||
scanning remain under review; these requests describe useful capabilities
|
|
||||||
without making their acceptance a prerequisite for adoption.
|
|
||||||
|
|
||||||
## Primary Requests
|
|
||||||
|
|
||||||
### 1. Shared Go Formatting Validation
|
|
||||||
|
|
||||||
Please make Go formatting validation available through ReleaseKit's public
|
|
||||||
validation API and release profile, so the shared candidate workflow can
|
|
||||||
report tracked Go source that needs formatting.
|
|
||||||
|
|
||||||
PromptKit currently owns a shell check that identifies its tracked Go files
|
|
||||||
and verifies their formatting. The operation is common to Go repositories;
|
|
||||||
maintaining that mechanism independently adds little project-specific value.
|
|
||||||
A useful shared capability would inspect source, report the affected files,
|
|
||||||
and leave formatting changes to ordinary development.
|
|
||||||
|
|
||||||
The benefit is consistent validation and diagnostics with less local script
|
|
||||||
maintenance. PromptKit can follow ReleaseKit's selected formatting convention
|
|
||||||
without requiring preservation of its current enumeration or command loop.
|
|
||||||
|
|
||||||
### 2. Shared Offline Markdown-Link Validation
|
|
||||||
|
|
||||||
Please make validation of local Markdown links available through the public
|
|
||||||
validation API and release profile. PromptKit needs checks for local file
|
|
||||||
destinations and heading fragments, with enough diagnostic context to locate
|
|
||||||
and correct a broken link.
|
|
||||||
|
|
||||||
Documentation is part of PromptKit's consumer interface. Broken navigation
|
|
||||||
between its guides, formats, policies, and examples makes otherwise correct
|
|
||||||
documentation harder to use. Its current local Markdown checker is the
|
|
||||||
largest generic block in its release-validation script.
|
|
||||||
|
|
||||||
Shared support would remove a locally maintained parser and standardize the
|
|
||||||
supported Markdown behavior across consumers. ReleaseKit can establish the
|
|
||||||
supported link and heading conventions; PromptKit does not require its exact
|
|
||||||
current parsing or anchor rules. Repository-specific choices about links to
|
|
||||||
material outside the checkout should remain distinguishable from generally
|
|
||||||
useful local-link validation.
|
|
||||||
|
|
||||||
The desired operation is offline and reports problems without changing
|
|
||||||
documentation. External website availability is a separate concern and adds
|
|
||||||
no value to this request.
|
|
||||||
|
|
||||||
### 3. Race Detection Within One Standard Test Run
|
|
||||||
|
|
||||||
Please provide a supported public API and profile choice for race-enabled
|
|
||||||
execution of the standard full Go suite during candidate validation.
|
|
||||||
|
|
||||||
PromptKit's concurrent execution and capacity management make race detection
|
|
||||||
useful: ordinary successful tests can miss unsafe shared-state access. Its
|
|
||||||
current release validation runs the full suite with the race detector.
|
|
||||||
ReleaseKit's current
|
|
||||||
[candidate workflow](../consumers/check.md) always runs the ordinary suite;
|
|
||||||
expressing a race run as an additional check would execute the complete suite
|
|
||||||
twice.
|
|
||||||
|
|
||||||
The desired capability selects race-enabled execution for that one suite
|
|
||||||
run, while ReleaseKit continues to own the candidate workflow. The selection
|
|
||||||
should work consistently through the public API and CLI/profile forms of
|
|
||||||
candidate checking and publication. A consumer can select the ordinary suite
|
|
||||||
when that is sufficient.
|
|
||||||
|
|
||||||
This overlaps with ConfigKit's
|
|
||||||
[base-test invocation request](feature-request-configkit.md#select-one-base-go-test-invocation).
|
|
||||||
PromptKit would benefit from the same shared capability; it does not need a
|
|
||||||
separate PromptKit-specific test mechanism. ReleaseKit can decide the smallest
|
|
||||||
appropriate public expression of the choice and whether race testing belongs
|
|
||||||
among its common defaults.
|
|
||||||
|
|
||||||
### 4. Shared Full Go Vet Validation
|
|
||||||
|
|
||||||
Please consider exposing full Go vet analysis as part of ReleaseKit's public
|
|
||||||
validation API and release profile, coordinated with the standard suite.
|
|
||||||
|
|
||||||
PromptKit currently runs full vet separately. Ordinary Go test execution
|
|
||||||
includes only a subset of vet analyses, so replacing the current procedure
|
|
||||||
with the standard test run does not provide equivalent static analysis. The
|
|
||||||
additional analyses can detect defects that are not exercised by tests.
|
|
||||||
|
|
||||||
PromptKit can temporarily retain a configured full-vet command. A shared
|
|
||||||
capability would let consumers express that validation choice directly and
|
|
||||||
let ReleaseKit coordinate the analysis with testing to avoid unnecessary
|
|
||||||
overlap. The desired outcome is full selected analysis and one complete
|
|
||||||
suite execution; PromptKit leaves the means of achieving that outcome to
|
|
||||||
ReleaseKit.
|
|
||||||
|
|
||||||
This also overlaps with ConfigKit's
|
|
||||||
[shared-check request](feature-request-configkit.md#evaluate-shared-release-checks).
|
|
||||||
Full vet may be useful as a common default or as an explicit selection.
|
|
||||||
PromptKit is asking for a shared capability, not prescribing additional gates
|
|
||||||
for every ReleaseKit consumer.
|
|
||||||
|
|
||||||
## Additional Candidates For Evaluation
|
|
||||||
|
|
||||||
### 5. Optional Go Module Distribution Checks
|
|
||||||
|
|
||||||
PromptKit's architecture keeps committed workspace files and local filesystem
|
|
||||||
module replacements out of its released source. These rules help a shared
|
|
||||||
library remain independent of neighboring checkouts. Disabling workspace
|
|
||||||
discovery during validation controls the test environment but does not check
|
|
||||||
the files being distributed.
|
|
||||||
|
|
||||||
If other consumers have the same need, optional public validation capabilities
|
|
||||||
could check for committed workspace files and local filesystem replacements.
|
|
||||||
Consumers should be able to select the distribution rules relevant to them;
|
|
||||||
a versioned module replacement is different from a local filesystem
|
|
||||||
dependency, and Go applications may deliberately distribute workspace files.
|
|
||||||
|
|
||||||
The potential benefit is reusable inspection and consistent diagnostics
|
|
||||||
without each library owning its own checks. PromptKit can also keep a small
|
|
||||||
local check if that is simpler than introducing shared support. This is a
|
|
||||||
lower-priority candidate, not a request for universal bans on workspaces,
|
|
||||||
replacement directives, or vendoring.
|
|
||||||
|
|
||||||
### 6. Optional Recognizable-Credential Checks
|
|
||||||
|
|
||||||
PromptKit's assessment recommends retiring its mandatory credential-pattern
|
|
||||||
scan, while retaining ordinary credential-aware change review. A viable
|
|
||||||
alternative is to keep a lightweight automated signal for recognizable
|
|
||||||
accidentally committed credential formats.
|
|
||||||
|
|
||||||
If ReleaseKit finds broader consumer value in that alternative, please
|
|
||||||
consider an optional public validation capability for such checks. A useful
|
|
||||||
offering would make its detection scope clear and account for the possibility
|
|
||||||
of matching synthetic examples or fixtures. It would complement ordinary
|
|
||||||
review rather than imply comprehensive detection.
|
|
||||||
|
|
||||||
Shared support could centralize maintenance of the selected detection behavior
|
|
||||||
and remove another local script fragment. PromptKit is not requesting a
|
|
||||||
general security-scanning subsystem, preservation of its current regex, or
|
|
||||||
a mandatory credential gate. This candidate warrants adoption only if its
|
|
||||||
additional protection justifies its maintenance and false-positive costs.
|
|
||||||
|
|
||||||
## Desired Adoption Outcome
|
|
||||||
|
|
||||||
The strongest opportunities are shared formatting and Markdown validation,
|
|
||||||
followed by useful race/vet choices within a single candidate-validation flow.
|
|
||||||
The module-distribution and credential candidates merit separate evaluation
|
|
||||||
because their policies and benefits vary between consumers.
|
|
||||||
|
|
||||||
For accepted capabilities, availability through both the public Go API and
|
|
||||||
the maintained CLI/profile would let PromptKit select them without creating
|
|
||||||
its own release executable. PromptKit can retain its consumer-example
|
|
||||||
assertions as additional checks and use ReleaseKit's supported conventions
|
|
||||||
for shared validation and diagnostics.
|
|
||||||
|
|
||||||
PromptKit would continue to prepare its release note and publish its candidate
|
|
||||||
to authoritative `main` before invoking source publication. Confirmed tag
|
|
||||||
publication completes the source release; CI and hosted delivery remain
|
|
||||||
separate. Those responsibilities already fit ReleaseKit's common workflow
|
|
||||||
and do not require new features for this request.
|
|
||||||
@@ -1,656 +0,0 @@
|
|||||||
# ReleaseKit v0.2.0 implementation plan
|
|
||||||
|
|
||||||
Status: Complete. Stages 1–15 are implemented and locally verified.
|
|
||||||
|
|
||||||
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 baseline commit `3974a46`, the foundation and all six
|
|
||||||
[remediation findings](remediation.md) were complete. `Check` and `Publish`
|
|
||||||
shared 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 stages in this plan complete the remaining v0.2.0 validation selections,
|
|
||||||
module-selected CI bootstrap, and Audita migration. Audita's migration is
|
|
||||||
recorded in commit `17421bc`. The final local audit covers the full Go suite,
|
|
||||||
compiled API/dependency boundaries, maintained examples, documentation, and
|
|
||||||
dependency notices. 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. 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
|
|
||||||
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
|
|
||||||
|
|
||||||
**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`.
|
|
||||||
|
|
||||||
**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
|
|
||||||
|
|
||||||
**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.
|
|
||||||
|
|
||||||
**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
|
|
||||||
|
|
||||||
**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.
|
|
||||||
|
|
||||||
**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.
|
|
||||||
|
|
||||||
**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.
|
|
||||||
|
|
||||||
**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
|
|
||||||
|
|
||||||
**Completion:** Complete. The internal checker resolves committed destinations,
|
|
||||||
checks supported fragments, preserves inspection errors, and reports distinct
|
|
||||||
outside-checkout and submodule observations. Stage 11 exposes this checker
|
|
||||||
through public and profile selections and the shared executor.
|
|
||||||
|
|
||||||
**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.
|
|
||||||
|
|
||||||
**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.
|
|
||||||
|
|
||||||
**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
|
|
||||||
|
|
||||||
**Completion:** Complete. `ValidationSpec.Markdown` and
|
|
||||||
`validation.markdown` select the shared committed-link checker through both
|
|
||||||
public operations and CLI profile commands. Omitted/null settings disable the
|
|
||||||
check; an empty object enables it, and the boundary option maps explicitly.
|
|
||||||
Warnings use the shared output writer, while Markdown failures stop product
|
|
||||||
checks and builds. GoDoc, profile, consumer, CLI, and internal documentation
|
|
||||||
now describe the operational behavior.
|
|
||||||
|
|
||||||
**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
|
|
||||||
|
|
||||||
**Completion:** Complete. The maintained tag workflow verifies and checks out
|
|
||||||
the event tag before reading module files, then confirms the ReleaseKit module
|
|
||||||
selection and builds its CLI with temporary alternate module metadata outside
|
|
||||||
the source tree. The delivery command retains the event arguments and exit
|
|
||||||
status, and the cleanup trap removes its module copies and executable.
|
|
||||||
|
|
||||||
**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
|
|
||||||
|
|
||||||
**Completion:** Complete. The tag workflow is exercised against a local module
|
|
||||||
proxy with two tool versions, an older tagged configuration after the default
|
|
||||||
branch upgrades, and a versioned replacement. Missing tool-only dependency
|
|
||||||
checksums are prepared in temporary module metadata. The ReleaseKit source
|
|
||||||
workflow verifies its tag before self-bootstrap and writes the executable
|
|
||||||
outside the checkout. Delivery, configuration, and CLI guidance now distinguish
|
|
||||||
tool bootstrap from application dependency preparation and describe
|
|
||||||
immutable-source retries and installed-tool use.
|
|
||||||
|
|
||||||
**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
|
|
||||||
|
|
||||||
**Completion:** Complete. Audita commit `17421bc` makes both local and hosted
|
|
||||||
bootstraps resolve ReleaseKit v0.1.0 from the consumer's module configuration.
|
|
||||||
The existing Go image, `GITEA_RELEASE_TOKEN` secret, release profile, caller
|
|
||||||
arguments, and native tool status are preserved. The local wrapper uses
|
|
||||||
temporary alternate module metadata and cleans it up before executing the tool.
|
|
||||||
Audita's runbook now describes the module-selected workflow.
|
|
||||||
|
|
||||||
**Verification:** Audita's `go test ./scripts -count=1`,
|
|
||||||
`bash -n scripts/release.sh`, and real `bash scripts/release.sh version` passed;
|
|
||||||
the wrapper reported `releasekit v0.1.0` and left source module files unchanged.
|
|
||||||
ReleaseKit's `TestWoodpeckerTagDeliveryTemplate` and
|
|
||||||
`TestWoodpeckerTagDeliveryUsesTaggedModuleVersion` passed with local Git and
|
|
||||||
module-proxy fixtures. Both repositories passed their relevant diff checks.
|
|
||||||
|
|
||||||
**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
|
|
||||||
|
|
||||||
**Completion:** Complete. All ten release-roadmap items map to implemented API,
|
|
||||||
profile, execution, diagnostics, canonical documentation, and focused behavioral
|
|
||||||
evidence. The audit confirms default zero-value behavior, independent
|
|
||||||
module-distribution selections, one coordinated Go suite, source-only
|
|
||||||
compilation/delivery, and expected-push preflight. Review found no unintended
|
|
||||||
defaults, restrictions, or stronger guarantees. Audita's migration is recorded
|
|
||||||
at `17421bc`.
|
|
||||||
|
|
||||||
**Verification:** `go test ./...` and `go run ./internal/apicheck` passed.
|
|
||||||
Local Markdown destinations and fragments resolved across the documentation;
|
|
||||||
dependency versions, source revisions, attribution entries, and license texts
|
|
||||||
were checked. Maintained Woodpecker examples passed their offline fixtures.
|
|
||||||
|
|
||||||
**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.
|
|
||||||
@@ -1,149 +0,0 @@
|
|||||||
# Validation API and profile model
|
|
||||||
|
|
||||||
Status: Complete for the agreed v0.2.0 shared validation model. Every selection
|
|
||||||
and execution path described here is implemented and locally verified; broader
|
|
||||||
consumer adoption remains in the product roadmap.
|
|
||||||
|
|
||||||
This roadmap describes the shared model that enables the optional validation
|
|
||||||
capabilities in the [v0.2.0 roadmap](v0.2.0.md). It owns their common API,
|
|
||||||
configuration, execution, and diagnostic design. The release roadmap owns each
|
|
||||||
capability's purpose and scope. The [implementation plan](implementation.md)
|
|
||||||
owns the stages and the agreed API rollout.
|
|
||||||
|
|
||||||
## Rationale and v0.1.0 baseline
|
|
||||||
|
|
||||||
ReleaseKit v0.1.0 exposes `Check` and `Publish` through the root facade. Both
|
|
||||||
accept `ReleaseRequest` and use shared candidate-validation machinery. Validation
|
|
||||||
runs the standard offline Go suite, followed by `AdditionalChecks` when supplied.
|
|
||||||
Selected executable builds follow validation. The CLI maps profile `checks`
|
|
||||||
commands to the additional-check callback.
|
|
||||||
|
|
||||||
This provides a common procedure and a product-specific extension point. The
|
|
||||||
request and profile have structured selections for race testing, separate full
|
|
||||||
vet, package compilation, formatting, Markdown, module distribution, and file
|
|
||||||
size. Publication also supports an expected push endpoint.
|
|
||||||
|
|
||||||
The model lets consumers declare their choices once while ReleaseKit owns
|
|
||||||
execution and coordination. This follows [ADR 0002](../adr/0002-routine-releases.md):
|
|
||||||
shared capabilities should reduce application code and routine developer
|
|
||||||
decisions. The facade boundaries in [ADR 0001](../adr/0001-public-facade.md)
|
|
||||||
provide the existing architectural foundation.
|
|
||||||
|
|
||||||
Optional capabilities can serve a small subset of consumers when they remove
|
|
||||||
application-owned release mechanics and have clear scope, compact configuration,
|
|
||||||
and proportionate maintenance costs.
|
|
||||||
|
|
||||||
## Target end state
|
|
||||||
|
|
||||||
### One validation specification
|
|
||||||
|
|
||||||
The facade-owned `ValidationSpec` on `ReleaseRequest` has a corresponding
|
|
||||||
`validation` object in the release profile. Typed Go fields and ordinary JSON
|
|
||||||
settings express the same supported selections. Related choices, including
|
|
||||||
base-test and vet settings, are grouped so their relationship is clear.
|
|
||||||
|
|
||||||
The specification includes the agreed capabilities in the
|
|
||||||
[release roadmap](v0.2.0.md), including optional Markdown boundary enforcement,
|
|
||||||
independent module-distribution rules, and file-size settings. Its zero value
|
|
||||||
and an omitted profile object preserve current default validation. Consumers
|
|
||||||
enable optional checks according to their product needs.
|
|
||||||
|
|
||||||
Go callers and CLI users receive equivalent validation behavior. The CLI owns
|
|
||||||
profile parsing and presentation; the facade owns the public types and contracts;
|
|
||||||
internal implementation owns execution. The [implementation plan](implementation.md)
|
|
||||||
records the selected field names, representations, and completed rollout.
|
|
||||||
|
|
||||||
### Shared coordination
|
|
||||||
|
|
||||||
`Check` and `Publish` pass the same specification through one internal validation
|
|
||||||
path bound to the captured candidate. ReleaseKit constructs the selected Go
|
|
||||||
commands, manages its shared environment, determines execution order, and
|
|
||||||
propagates failures and cancellation.
|
|
||||||
|
|
||||||
Race selection changes the one base suite invocation. Selecting a separate
|
|
||||||
full-vet pass automatically omits test-time vet. Package-compilation targets
|
|
||||||
express compatibility checks independently of executable artifact selection.
|
|
||||||
Consumers obtain this coordination through their declarations.
|
|
||||||
|
|
||||||
Keep the executor straightforward and internal, with ordinary functions for
|
|
||||||
the selected capabilities. The public model expresses validation choices;
|
|
||||||
ReleaseKit maintains their execution procedure. Existing candidate rechecks,
|
|
||||||
offline validation, and source-publication outcomes retain their meaning.
|
|
||||||
|
|
||||||
### Candidate-content inspection
|
|
||||||
|
|
||||||
File-oriented checks share candidate-file enumeration and inspection where
|
|
||||||
useful. Their scope is the captured candidate, and inspection remains offline
|
|
||||||
and read-only. Inspect committed candidate contents and define symlink and
|
|
||||||
submodule handling explicitly in the shared inspection model. Module-distribution
|
|
||||||
rules inspect the files being released independently of the environment used
|
|
||||||
to run Go commands. Markdown boundary
|
|
||||||
validation operates independently of neighboring checkout contents.
|
|
||||||
|
|
||||||
Keep each check's settings together: Markdown validation owns its optional
|
|
||||||
boundary rule; module-distribution validation owns its independent rule
|
|
||||||
selections; file-size validation owns its limit and path exclusions. The
|
|
||||||
[release roadmap](v0.2.0.md) defines the scope and defaults of each capability.
|
|
||||||
|
|
||||||
### Clear responsibility boundaries
|
|
||||||
|
|
||||||
| Concern | Model owner |
|
|
||||||
| --- | --- |
|
|
||||||
| Base tests, full vet, and package compilation | Shared validation specification |
|
|
||||||
| Formatting, Markdown links, module distribution, and file size | Shared validation specification |
|
|
||||||
| Product-specific assertions and example checks | Existing `AdditionalChecks` callback and profile `checks` |
|
|
||||||
| Expected authoritative push destination | Publication settings and endpoint handling |
|
|
||||||
| Executable package, binary name, and artifact targets | Build declaration |
|
|
||||||
| Hosted destination and credentials | Delivery settings |
|
|
||||||
|
|
||||||
`AdditionalChecks` and profile `checks` remain available for substantive
|
|
||||||
consumer behavior. Shared capabilities use the validation specification.
|
|
||||||
Preserve the current behavior of existing declarations as the new options land.
|
|
||||||
|
|
||||||
The expected-endpoint feature remains a publication guard, and `Check` remains
|
|
||||||
local-only. Selecting package-compilation checks leaves a source-only consumer's
|
|
||||||
deliverable selection unchanged. Tool installation and dependency preparation
|
|
||||||
remain separate from offline candidate validation.
|
|
||||||
|
|
||||||
### Consistent diagnostics
|
|
||||||
|
|
||||||
Shared validation failures identify the check and expose useful details to Go
|
|
||||||
callers. File-oriented checks provide source locations and actionable findings
|
|
||||||
where applicable, including relevant paths, directives, and measured values.
|
|
||||||
The CLI presents those details consistently through the ordinary candidate-check
|
|
||||||
and publication commands.
|
|
||||||
|
|
||||||
Use a small facade-owned error model with stable check identity and support for
|
|
||||||
underlying error causes and cancellation. Preserve `errors.Is` and `errors.As`
|
|
||||||
behavior across internal conversions and facade wrapping. Exact error types
|
|
||||||
and diagnostic fields are proposed in the [implementation plan](implementation.md).
|
|
||||||
|
|
||||||
Validation failures and publication outcomes have distinct meanings. Existing
|
|
||||||
publication states continue to describe whether publication was attempted,
|
|
||||||
confirmed, conflicted, or remains uncertain. The model preserves the existing
|
|
||||||
failure-stopping behavior of the candidate workflow.
|
|
||||||
|
|
||||||
## Implementation
|
|
||||||
|
|
||||||
The [implementation plan](implementation.md) records the completed rollout and
|
|
||||||
verification. The facade and CLI profile expose equivalent selections for the
|
|
||||||
single test suite, separate full vet, package compilation, formatting, Markdown,
|
|
||||||
module distribution, file size, and the expected publication endpoint. Shared
|
|
||||||
execution, ordering, diagnostics, cancellation, and failure stopping are
|
|
||||||
implemented by the owners described above. The maintained Woodpecker template
|
|
||||||
and Audita's local wrapper use the module-selected ReleaseKit version; see the
|
|
||||||
[v0.2.0 roadmap](v0.2.0.md) and [delivery guide](../consumers/delivery.md).
|
|
||||||
|
|
||||||
## Adoption evidence
|
|
||||||
|
|
||||||
Self-contained integration fixtures evaluate all three known consumer shapes:
|
|
||||||
Audita's default validation and executable builds; ConfigKit's selected test,
|
|
||||||
vet, and library compilation checks; and PromptKit's shared validation plus
|
|
||||||
substantive example assertions. Audita's module-selected CI migration is
|
|
||||||
committed at `17421bc`; the other consumer migrations remain separate adoption
|
|
||||||
work.
|
|
||||||
|
|
||||||
The model gives each adopting consumer a small declaration and the same routine
|
|
||||||
release operation. Shared execution and diagnostics cover the agreed v0.2.0
|
|
||||||
capabilities while product-specific work remains in the existing extension
|
|
||||||
point.
|
|
||||||
@@ -1,210 +1,43 @@
|
|||||||
# ReleaseKit: shared release process
|
# ReleaseKit adoption and deployment roadmap
|
||||||
|
|
||||||
Status: The v0.2.0 implementation, policy adoption, and architecture
|
Status: Pending consumer adoption and live deployment. The v0.2.0 implementation
|
||||||
remediation are complete. Audita's module-selected local and CI integration is
|
and its remediation are complete.
|
||||||
committed at `17421bc`; broader consumer adoption and live deployment remain.
|
|
||||||
|
|
||||||
This roadmap records the shared release-process opportunity identified in
|
The [v0.2.0 release note](../releases/v0.2.0.md) summarizes the implemented
|
||||||
PromptKit, ConfigKit, Audita, Notarius, Narratio, and Scriptorium on 2026-09-29,
|
capabilities. The [internal inventory](../internal/overview.md) records their
|
||||||
and the remaining adoption goals. The [internal package inventory](../internal/overview.md)
|
owners and local verification. Completed plans and review findings remain in
|
||||||
records implemented capability owners and behavioral evidence. The
|
Git history. The [architecture policy](../policy/architecture.md) and accepted
|
||||||
[architecture policy](../policy/architecture.md) and
|
ADRs own the selected architectural constraints.
|
||||||
[ADR 0001](../adr/0001-public-facade.md) own the facade boundaries and rationale.
|
|
||||||
The initial foundation, policy adoption, and remediation plans are preserved
|
|
||||||
in Git history; the current v0.2.0 completion evidence is in the
|
|
||||||
[implementation plan](implementation.md).
|
|
||||||
|
|
||||||
## Opportunity
|
## Remaining work
|
||||||
|
|
||||||
All six repositories follow the same base release policy. Their release scripts
|
- Choose the broader consumer integration test plan and migration sequence for
|
||||||
repeat stable-version parsing, candidate and release-note checks, local and
|
PromptKit, ConfigKit, Notarius, Narratio, and Scriptorium. Evaluate API clarity,
|
||||||
remote tag checks, validation of one captured commit, explicit Git publication,
|
product-specific checks, and the infrastructure removed from each repository.
|
||||||
and recovery guidance for uncertain pushes. They differ in publication approach,
|
- Adopt the common publication, validation, runtime-version, build, and delivery
|
||||||
tag type, validation commands, and artifact delivery. The mechanics of embedding
|
conventions where they apply. Keep product identity, compatibility decisions,
|
||||||
a release version and cross-building an application are further candidates for
|
and substantive application checks with each consumer.
|
||||||
standardization.
|
- Provision delivery credentials and activate ReleaseKit and consumer Woodpecker
|
||||||
|
workflows as part of deployment. The maintained consumer template selects
|
||||||
|
tooling from the released application's module configuration.
|
||||||
|
- Verify live Gitea delivery and Woodpecker execution. Current verification uses
|
||||||
|
local Git and HTTP fixtures; live deployment remains unverified.
|
||||||
|
- Measure realized reductions in consumer release infrastructure after migration.
|
||||||
|
Audita's module-selected local and CI integration is committed at `17421bc`.
|
||||||
|
|
||||||
If the projects deliberately standardize publication approach and tag type,
|
## Proposals and deferred work
|
||||||
ReleaseKit can own most of the repeated release-process code. The current six
|
|
||||||
repositories contain 942 lines of release shell scripts and 742 lines of
|
|
||||||
dedicated release tests, or 1,684 lines total. A directional estimate is that
|
|
||||||
roughly 1,000–1,250 lines could leave those repositories: about 450–500 lines
|
|
||||||
of publication scripts, 150–250 lines of checks and builders, and 400–500 lines
|
|
||||||
of repeated publication tests. ReleaseKit would gain its own implementation and
|
|
||||||
tests, so this is a reduction in local code, not a net line-count saving.
|
|
||||||
|
|
||||||
## Selected publication standard
|
- Optional recognizable-credential checks remain an unevaluated suggestion from
|
||||||
|
PromptKit's feature request. Evaluate their detection scope, synthetic-fixture
|
||||||
1. Prepare and commit a version-matched note at `docs/releases/<version>.md`.
|
handling, false-positive costs, and maintenance benefit before selecting shared
|
||||||
2. Publish the candidate commit to authoritative `main` before invoking the
|
support. The proposal establishes no mandatory credential gate.
|
||||||
release command.
|
- ReleaseKit executable binary distribution remains deferred until deliverables
|
||||||
3. Run one command that checks the candidate and unused stable version, runs
|
are deliberately selected. Selecting binaries would require delivery
|
||||||
that repository's offline candidate validation once, and rechecks mutable
|
declarations, target checks, automation responsibilities, and corresponding
|
||||||
state.
|
release policy and procedure updates.
|
||||||
4. Create an annotated tag at the validated commit with a message derived from
|
- Evaluate a maintained ReleaseKit CI image or specialized validation/build
|
||||||
the checked-in note. Push only that exact tag object to the authoritative
|
settings when a demonstrated consumer need justifies their maintenance cost
|
||||||
endpoint. A successful tag push completes the source release.
|
under [ADR 0002](../adr/0002-routine-releases.md).
|
||||||
5. Treat hosted release pages and binary assets as asynchronous delivery with
|
|
||||||
their own status. Do not poll CI or require artifact availability to declare
|
|
||||||
the source release complete.
|
|
||||||
|
|
||||||
This would replace Audita's atomic branch-and-tag push, ConfigKit's and
|
|
||||||
Notarius's branch push during the release command, and Audita's, Notarius's,
|
|
||||||
and Narratio's lightweight tags. Those changes require updates to each
|
|
||||||
repository's adopted release policy and procedure; they are not merely code
|
|
||||||
cleanup.
|
|
||||||
|
|
||||||
## Architecture
|
|
||||||
|
|
||||||
[ADR 0001](../adr/0001-public-facade.md) owns the accepted facade decision.
|
|
||||||
The [architecture policy](../policy/architecture.md) owns the adopted
|
|
||||||
responsibility and dependency rules, including the runtime version boundary.
|
|
||||||
The root `releasekit` package provides the public facade for candidate
|
|
||||||
validation, source publication, selected-target builds, and tagged-source
|
|
||||||
delivery. The Gitea page and asset-delivery client is integrated through that
|
|
||||||
facade and the CLI. The separate public `buildinfo` package provides lightweight
|
|
||||||
runtime version access.
|
|
||||||
|
|
||||||
Each facade owns its public named types and documented contracts. Public
|
|
||||||
operations, inputs, outcomes, errors, and callbacks express deliberately
|
|
||||||
selected consumer needs. Handles retain private implementation state; explicit
|
|
||||||
forwarding and conversions connect the public contracts to internal
|
|
||||||
representations.
|
|
||||||
|
|
||||||
Git operations, Go toolchain execution, Gitea integration, and orchestration
|
|
||||||
bookkeeping belong under Go's `internal/` boundary. Dependency direction runs
|
|
||||||
from the facades into internal implementation, with internal collaborators using
|
|
||||||
contracts defined inside that boundary. Implementation packages can evolve
|
|
||||||
while the supported public contracts retain their compatibility obligations.
|
|
||||||
|
|
||||||
The `buildinfo` facade keeps runtime version access lightweight. Applications
|
|
||||||
read their embedded version through its supported accessor. ReleaseKit's builder
|
|
||||||
and runtime implementation own the linker symbol and injection mechanism
|
|
||||||
together.
|
|
||||||
|
|
||||||
The `buildinfo` facade follows three constraints:
|
|
||||||
|
|
||||||
- Its public API exposes only runtime information justified by consumer needs.
|
|
||||||
- Its implementation uses the standard library and a small internal dependency
|
|
||||||
graph independent of release orchestration.
|
|
||||||
- Dependency checks protect that boundary, and build-and-run integration tests
|
|
||||||
verify that the builder injects the selected version and the public accessor
|
|
||||||
reports it correctly.
|
|
||||||
|
|
||||||
The release executable calls the orchestration facade and handles command
|
|
||||||
parsing, output, and exit codes. Library errors and outcomes report meaningful
|
|
||||||
publication state, including partial progress and uncertainty. Go declarations
|
|
||||||
and GoDoc own exact public API contracts; additional public packages and
|
|
||||||
extension interfaces require a deliberate decision grounded in durable consumer
|
|
||||||
needs.
|
|
||||||
|
|
||||||
Compiled-export and dependency checks protect facade ownership.
|
|
||||||
External-package behavioral tests protect error identity, value ownership,
|
|
||||||
callback lifetime, and observable outcomes across forwarding and conversions.
|
|
||||||
|
|
||||||
## Shared tool boundary
|
|
||||||
|
|
||||||
Provide a versioned ReleaseKit executable backed by a Go library. Existing
|
|
||||||
shell entry points can become short invocations of that executable. A library
|
|
||||||
alone would still require a caller in every shell-driven repository.
|
|
||||||
|
|
||||||
ReleaseKit should own:
|
|
||||||
|
|
||||||
- stable-version parsing and committed-note identity checks;
|
|
||||||
- authoritative Git endpoint resolution, candidate capture, clean `main` and
|
|
||||||
remote-branch agreement checks, and unused local/remote tag checks;
|
|
||||||
- one validation invocation bound to the captured candidate, followed by cheap
|
|
||||||
rechecks before publication;
|
|
||||||
- annotated-tag creation and verification, explicit tag-object push, and one
|
|
||||||
bounded authoritative-ref check after a failed or ambiguous push;
|
|
||||||
- a standard version accessor in the public `buildinfo` facade, backed by
|
|
||||||
release-build injection of the selected tag;
|
|
||||||
- a cross-build API that accepts the application's main package and selected
|
|
||||||
targets, initially Linux amd64, Linux arm64, and macOS arm64 (Go's
|
|
||||||
`darwin/arm64`), including an empty set for source-only projects;
|
|
||||||
- consistent release build flags and asset naming, plus a host-runnable build
|
|
||||||
that checks the executable's reported version; and
|
|
||||||
- Git publication tests using temporary local remotes, including remote
|
|
||||||
advancement, rejected pushes, lost acknowledgments, and unavailable remotes.
|
|
||||||
|
|
||||||
Each repository should retain its product name, compatibility decisions,
|
|
||||||
candidate-specific checks, main package, selected build targets, delivery
|
|
||||||
declaration, and a small test of its ReleaseKit wiring. For example, PromptKit
|
|
||||||
exercises its consumer examples. Applications would adapt their existing
|
|
||||||
version output to use the `buildinfo` accessor; one agreed version command
|
|
||||||
or flag would let ReleaseKit smoke-test a host-runnable build the same way.
|
|
||||||
Cross-built binaries would use the same injection mechanism, but compilation
|
|
||||||
alone would not establish that they run correctly on another platform.
|
|
||||||
ReleaseKit should run the selected checks and builds without silently adding
|
|
||||||
binary gates to source-only projects.
|
|
||||||
|
|
||||||
The build API should own the mechanics rather than require each application to
|
|
||||||
provide a custom linker symbol or shell loop. The initial target list reflects
|
|
||||||
the current projects, not a permanent limit on future platforms. It should
|
|
||||||
support both candidate cross-build checks and artifact builds from the tagged
|
|
||||||
source, using the same version and target selection.
|
|
||||||
|
|
||||||
## Woodpecker and Gitea delivery
|
|
||||||
|
|
||||||
A common tag-triggered Woodpecker workflow can run ReleaseKit against the
|
|
||||||
tagged source. Repository-local YAML should declare the pinned tool image and
|
|
||||||
credentials; each repository's ReleaseKit configuration should declare its
|
|
||||||
delivery destination and any binary main package and target set. ReleaseKit can
|
|
||||||
own version injection, cross-builds, checksum generation, and delivery. All
|
|
||||||
projects should receive hosted Gitea
|
|
||||||
release pages. Source-only repositories declare zero binary assets and deliver
|
|
||||||
the committed release note without a binary build or checksum manifest.
|
|
||||||
|
|
||||||
The shared delivery command should create or find the release for the tag,
|
|
||||||
use the checked-in note, and add declared binary assets and their checksum
|
|
||||||
manifest where applicable. A retry should inspect existing assets, verify
|
|
||||||
matching content, add only missing items, and stop on a conflict.
|
|
||||||
An existing checksum manifest must remain consistent with any later addition.
|
|
||||||
The release and its attachments are separate remote operations, so partial
|
|
||||||
delivery must be expected and reported clearly.
|
|
||||||
|
|
||||||
Audita, Narratio, and Scriptorium currently use the Woodpecker release plugin
|
|
||||||
with `file-exists: skip` and `overwrite: false`. Those settings avoid deliberate
|
|
||||||
replacement by filename, but they do not prove that a rebuilt file has the
|
|
||||||
same bytes as a previously published file. Content comparison would be a
|
|
||||||
reason to implement a shared Gitea delivery client rather than rely solely on
|
|
||||||
the plugin's skip behavior.
|
|
||||||
|
|
||||||
Hosted pages are selected for source-only projects, including PromptKit,
|
|
||||||
ConfigKit, Notarius, and ReleaseKit. Adoption adds a page deliverable and delivery
|
|
||||||
credentials to their procedures while preserving successful tag publication as
|
|
||||||
source completion. The initial implementation should support both page-only and
|
|
||||||
binary delivery through the same facade and command.
|
|
||||||
|
|
||||||
## Failure states
|
|
||||||
|
|
||||||
ReleaseKit should report source publication and artifact delivery separately:
|
|
||||||
|
|
||||||
| Event | Result |
|
|
||||||
| --- | --- |
|
|
||||||
| Candidate validation or a pre-push guard fails | No release was published; correct and validate the candidate again. |
|
|
||||||
| Tag push reports success | Source release is complete; delivery may still be pending. |
|
|
||||||
| Tag push fails or its acknowledgment is lost | Query the authoritative ref once. Confirm success only if the exact intended tag object is present on the intended commit; otherwise report failed or unknown status and retain the local tag. |
|
|
||||||
| Woodpecker or Gitea delivery fails after tag publication | Keep the source release successful. Retry missing delivery from the immutable tag after checking existing content. |
|
|
||||||
| Published source or content needs correction | Publish a new version; never replace content under the published version. |
|
|
||||||
|
|
||||||
## Consumer adoption target
|
|
||||||
|
|
||||||
All six projects should use the same selected publication, runtime version,
|
|
||||||
build, and delivery conventions where those responsibilities apply. Repository
|
|
||||||
entry points should contain only tool invocation and product-specific settings
|
|
||||||
or checks. Shared mechanics and their repeated tests belong in ReleaseKit.
|
|
||||||
|
|
||||||
Application runtime code should obtain version information through `buildinfo`.
|
|
||||||
Source-only libraries need no runtime import or automatic binary deliverable.
|
|
||||||
Projects declaring binaries should use the common target selection and version
|
|
||||||
injection; hosted delivery should use content-aware retries for both page-only
|
|
||||||
and binary releases.
|
|
||||||
Existing published tags, notes, pages, and assets retain their historical contents.
|
|
||||||
|
|
||||||
Consumer policy and procedure changes should describe the deliberately adopted
|
|
||||||
standard and its compatibility impact. Adoption should demonstrate reduced local
|
|
||||||
infrastructure and one coherent release model.
|
|
||||||
|
|
||||||
## Representative migration review
|
## Representative migration review
|
||||||
|
|
||||||
@@ -226,40 +59,3 @@ The self-contained ReleaseKit fixtures exercise a meaningful source-only
|
|||||||
compatibility check through local Git publication, and a `buildinfo` binary
|
compatibility check through local Git publication, and a `buildinfo` binary
|
||||||
consumer with selected targets through local HTTP delivery. These are separate
|
consumer with selected targets through local HTTP delivery. These are separate
|
||||||
publication and delivery operations.
|
publication and delivery operations.
|
||||||
|
|
||||||
## Remaining work
|
|
||||||
|
|
||||||
- Use the [v0.1.0 baseline](../releases/v0.1.0.md) for initial consumer
|
|
||||||
integration under the [maintainer procedure](../release.md). Consumers that
|
|
||||||
adopt the maintained tag workflow select ReleaseKit through the tagged
|
|
||||||
source's `go.mod` rather than a separate workflow version value.
|
|
||||||
- Choose the broader consumer integration test plan and migration sequence.
|
|
||||||
Evaluate API clarity, product-specific checks, and the infrastructure removed
|
|
||||||
from each consuming repository.
|
|
||||||
- Provision delivery credentials and activate consumer Woodpecker workflows
|
|
||||||
as part of deployment. The tagged consumer's module configuration selects
|
|
||||||
the ReleaseKit version used by the maintained workflow.
|
|
||||||
- Verify live Gitea delivery and Woodpecker execution. Existing verification uses
|
|
||||||
local Git and HTTP fixtures; no live deployment has been verified.
|
|
||||||
- Keep ReleaseKit executable binary distribution deferred until deliverables
|
|
||||||
are deliberately selected. Selecting binaries would require delivery
|
|
||||||
declarations, target checks, automation responsibilities, and corresponding
|
|
||||||
release policy and procedure updates.
|
|
||||||
- Evaluate a maintained ReleaseKit CI image or specialized validation/build
|
|
||||||
settings when a demonstrated consumer need justifies their maintenance cost
|
|
||||||
under [ADR 0002](../adr/0002-routine-releases.md).
|
|
||||||
|
|
||||||
## Reviewed implementations
|
|
||||||
|
|
||||||
- [PromptKit release script](../../../promptkit/scripts/release.sh),
|
|
||||||
[checker](../../../promptkit/scripts/release-check.sh)
|
|
||||||
- [ConfigKit release script](../../../ConfigKit/scripts/release.sh),
|
|
||||||
[checker](../../../ConfigKit/scripts/release-check.sh)
|
|
||||||
- [Audita release script](../../../audita/scripts/release.sh),
|
|
||||||
[Woodpecker job](../../../audita/.woodpecker/release.yml)
|
|
||||||
- [Notarius release script](../../../notarius/scripts/release.sh),
|
|
||||||
[checker](../../../notarius/scripts/check-release-source.sh)
|
|
||||||
- [Narratio release script](../../../narratio/scripts/release.sh),
|
|
||||||
[Woodpecker job](../../../narratio/.woodpecker/release.yml)
|
|
||||||
- [Scriptorium release script](../../../scriptorium/scripts/release.sh),
|
|
||||||
[Woodpecker job](../../../scriptorium/.woodpecker/release.yml)
|
|
||||||
|
|||||||
@@ -1,430 +0,0 @@
|
|||||||
# ReleaseKit implementation remediation
|
|
||||||
|
|
||||||
Status: All nine findings addressed.
|
|
||||||
|
|
||||||
The v0.2.0 review covers committed state `edd670e` and the implementation
|
|
||||||
commits after `89981ab`, against the [implementation plan](implementation.md),
|
|
||||||
[feature roadmap](v0.2.0.md), [model roadmap](model.md), accepted ADRs, and
|
|
||||||
applicable repository policies. Both ReleaseKit and Audita had clean worktrees
|
|
||||||
when inspected. The review changed only this document; the resolutions below
|
|
||||||
record subsequent remediation.
|
|
||||||
|
|
||||||
## Foundation review history
|
|
||||||
|
|
||||||
Reviewed committed implementation `f53354b`, covering the eight foundation
|
|
||||||
commits after `0c7129a`, against the [implementation plan](implementation.md),
|
|
||||||
[model roadmap](model.md), accepted ADRs, and applicable repository policies.
|
|
||||||
The worktree was clean when review began. This document records required fixes;
|
|
||||||
production code was unchanged during the review.
|
|
||||||
|
|
||||||
## Foundation architecture assessment
|
|
||||||
|
|
||||||
The root orchestration facade and independent `buildinfo` runtime facade retain
|
|
||||||
their intended dependency direction. Both candidate operations share request
|
|
||||||
conversion and `internal/candidate.Validate`. Candidate capture, product
|
|
||||||
callbacks, builds, and rechecks retain their owners; `internal/validation` owns
|
|
||||||
the default Go suite, structured failures, and committed-tree inspection.
|
|
||||||
Publication retains endpoint guards, tag operations, and recovery. The CLI
|
|
||||||
shares profile conversion and owns output and exit classification.
|
|
||||||
|
|
||||||
The public error types belong to the root facade, and conversion preserves the
|
|
||||||
underlying error chain. Candidate inventory reads committed entries and blobs,
|
|
||||||
with separate handling for symlinks and gitlinks. Its default validation path
|
|
||||||
does not load that inventory.
|
|
||||||
|
|
||||||
The absent `ValidationSpec`, request/profile selections, optional checkers, CI
|
|
||||||
tooling changes, and expected-endpoint option are intentionally deferred under
|
|
||||||
the agreed incremental rollout. Their absence is consistent with foundation
|
|
||||||
scope. The defects below affect the implemented foundation, including helpers
|
|
||||||
that subsequent checkers will use.
|
|
||||||
|
|
||||||
## 1. P2: Expanding symlink cycles do not terminate or honor cancellation
|
|
||||||
|
|
||||||
**Resolution:** Addressed. The resolver tracks active symlink expansions,
|
|
||||||
releases them before traversing the remaining destination, and checks context
|
|
||||||
cancellation during traversal. Regression coverage includes direct and mutual
|
|
||||||
expanding cycles, finite repeated links, and cancellation.
|
|
||||||
`go test ./internal/validation` passed.
|
|
||||||
|
|
||||||
**Owner:** [candidate destination resolver](../../internal/validation/tree.go),
|
|
||||||
`CandidateTree.ResolveDestination`, especially the restart loop and cycle key.
|
|
||||||
|
|
||||||
The cycle key combines the symlink path with the unresolved suffix. For a
|
|
||||||
committed symlink `loop -> loop/child`, resolving `loop` visits suffixes of
|
|
||||||
increasing length. The key never repeats. Cached link reads do not consult the
|
|
||||||
context, and the resolver loop has no cancellation check. Resolution can keep
|
|
||||||
consuming CPU and memory after cancellation.
|
|
||||||
|
|
||||||
**Evidence:** A temporary overlay test using committed-entry metadata and
|
|
||||||
cached symlink text confirmed that the operation neither returned a cycle
|
|
||||||
classification nor stopped within 150 ms, despite a 20 ms context deadline.
|
|
||||||
Existing tests cover a two-link cycle whose suffix stays constant.
|
|
||||||
|
|
||||||
**Required remediation:** Detect recursive symlink expansion using the active
|
|
||||||
expansion chain and honor context cancellation during traversal. Preserve
|
|
||||||
legitimate finite paths that encounter a symlink again after an earlier
|
|
||||||
expansion has completed. Keep cycle detection separate from any arbitrary
|
|
||||||
hop/path-length limit; such a limit was not requested.
|
|
||||||
|
|
||||||
**Verification:** Add focused cases for direct and mutual expanding cycles,
|
|
||||||
finite repeated symlink traversal, and cancellation. Keep the fixture local
|
|
||||||
and bounded even when testing the broken behavior.
|
|
||||||
|
|
||||||
## 2. P2: Path cleanup changes symlink traversal and checkout classification
|
|
||||||
|
|
||||||
**Resolution:** Addressed. Destination components and symlink targets are
|
|
||||||
traversed in order, with parent traversal applied to resolved directories.
|
|
||||||
Missing entries and regular-file traversal remain observable. Regression tests
|
|
||||||
cover both destination and symlink-target parent components and confirm that
|
|
||||||
neighboring files do not change classification.
|
|
||||||
`go test ./internal/validation` passed.
|
|
||||||
|
|
||||||
**Owner:** [candidate destination resolver](../../internal/validation/tree.go),
|
|
||||||
initial destination construction and construction after symlink expansion.
|
|
||||||
|
|
||||||
`path.Join`/`path.Clean` eliminate `..` components before intervening symlinks
|
|
||||||
are resolved. This changes the destination rather than resolving it. It can
|
|
||||||
also discard a symlink that crosses the checkout boundary.
|
|
||||||
|
|
||||||
**Evidence:** With `docs/link -> ../nested/inner`, resolving
|
|
||||||
`docs/link/../file.md` returns `docs/file.md` instead of `nested/file.md`.
|
|
||||||
With `link -> ../neighbor`, `link/../README.md` is incorrectly classified as
|
|
||||||
the captured root's `README.md`, hiding its outside-checkout destination.
|
|
||||||
Both failures were reproduced with overlay tests. PromptKit's starting
|
|
||||||
convention resolves paths before checking their relation to the checkout.
|
|
||||||
|
|
||||||
**Required remediation:** Walk path components and symlink expansions in order.
|
|
||||||
Apply parent traversal to the resolved directory, retaining missing-file and
|
|
||||||
non-directory observations where traversal encounters them. Derive checkout
|
|
||||||
classification from that traversal, using candidate entries throughout.
|
|
||||||
|
|
||||||
**Verification:** Cover `..` following internal and external symlinks and
|
|
||||||
following missing or regular-file components. Assert resolved identities and
|
|
||||||
boundary classifications independently of neighboring filesystem contents.
|
|
||||||
|
|
||||||
## 3. P2: Committed-file inspection can fetch from a promisor remote
|
|
||||||
|
|
||||||
**Resolution:** Addressed. Candidate tree, size, and blob reads share a local
|
|
||||||
Git command helper that disables lazy fetching and transport access per child
|
|
||||||
process. Missing blobs report local unavailability, and Git process causes
|
|
||||||
remain wrapped. Partial-clone tests cover missing blobs and missing trees,
|
|
||||||
instrument transport attempts, and verify the object database stays unchanged.
|
|
||||||
`go test ./internal/git ./internal/validation` passed.
|
|
||||||
|
|
||||||
**Owner:** [Git source readers](../../internal/git/source.go), `ReadTree`,
|
|
||||||
`populateBlobSizes`, and `ReadBlob`.
|
|
||||||
|
|
||||||
The new readers invoke ordinary Git object-reading commands without suppressing
|
|
||||||
automatic fetching of missing promisor objects. Inspecting a filtered checkout
|
|
||||||
can therefore initiate remote access during the promised offline operation.
|
|
||||||
Successful fetching can also populate the checkout's object database.
|
|
||||||
|
|
||||||
**Evidence:** A local `--filter=blob:none --no-checkout` clone contained commit
|
|
||||||
and tree objects but no blobs. Its promisor URL was replaced with a synthetic
|
|
||||||
SSH destination, and a local SSH stub recorded attempts and exited. Calling
|
|
||||||
`ReadCandidateTree` invoked that stub through `cat-file --batch-check` and
|
|
||||||
returned a promisor-fetch error. No external host was contacted. Ordinary
|
|
||||||
fully populated repository tests do not exercise this behavior.
|
|
||||||
|
|
||||||
**Required remediation:** Make these candidate object reads explicitly local
|
|
||||||
and suppress lazy fetching using a mechanism supported by the applicable Git
|
|
||||||
version. Report unavailable local objects with preserved causes. Keep source
|
|
||||||
preparation and network-capable publication/delivery operations in their
|
|
||||||
existing separate boundaries; a global ban on partial clones is unnecessary.
|
|
||||||
|
|
||||||
**Verification:** Inspect a local filtered-clone fixture with unavailable blobs
|
|
||||||
and an instrumented remote transport. Assert that metadata/content requests
|
|
||||||
fail locally when necessary and never invoke that transport. Retain successful
|
|
||||||
reads from fully populated candidates.
|
|
||||||
|
|
||||||
## 4. P2: Public and CLI error presentation loses diagnostic information
|
|
||||||
|
|
||||||
**Resolution:** Addressed. Public errors use the internal diagnostic formatter
|
|
||||||
with explicit conversions, including findings, targets, directives,
|
|
||||||
measurements, and causes. Matching converted diagnostics reuse their contextual
|
|
||||||
cause's rendering once. The CLI preserves outer wrappers, and callback errors
|
|
||||||
retain their public identity. Regression tests cover both candidate operations
|
|
||||||
and caller-created errors with and without causes.
|
|
||||||
`go test . ./cmd/releasekit ./internal/validation ./internal/apicheck` and
|
|
||||||
`go run ./internal/apicheck` passed.
|
|
||||||
|
|
||||||
**Owners:** [public diagnostics](../../validation_error.go),
|
|
||||||
`ValidationError.Error` and its formatter; [CLI presentation](../../cmd/releasekit/main.go),
|
|
||||||
`candidateFailureText`; [internal formatting](../../internal/validation/diagnostic.go).
|
|
||||||
|
|
||||||
Two branches lose information:
|
|
||||||
|
|
||||||
- A caller-created `ValidationError` with a cause returns only `Cause.Error()`.
|
|
||||||
Its check, findings, and measurement disappear from the textual diagnostic.
|
|
||||||
Converted built-in failures happen to work because their retained internal
|
|
||||||
cause already formats those details.
|
|
||||||
- The CLI extracts an inner `ValidationError` with `errors.As` and formats that
|
|
||||||
inner value. For a callback-supplied public error, this drops the candidate
|
|
||||||
wrapper added by `candidate.Validate`.
|
|
||||||
|
|
||||||
The public and internal formatters also duplicate the finding/measurement
|
|
||||||
formatting procedure, making it easier for their behavior to diverge.
|
|
||||||
|
|
||||||
**Evidence:** A public error with check `go-format`, a `main.go:3` finding, and
|
|
||||||
cause `inspection failed` renders only `inspection failed`. A candidate-wrapped
|
|
||||||
callback diagnostic loses its captured-commit context through
|
|
||||||
`candidateFailureText`. Both failures were reproduced with temporary overlay
|
|
||||||
tests. Existing tests exercise only converted Go-suite failures.
|
|
||||||
|
|
||||||
**Required remediation:** Share diagnostic formatting behind the facade with
|
|
||||||
explicit conversions. Preserve the full contextual chain when presenting an
|
|
||||||
error and include caller-supplied structured detail alongside its cause.
|
|
||||||
Ensure converted built-in failures render once. Retain `errors.Is`/`errors.As`
|
|
||||||
and existing exit/publication classifications.
|
|
||||||
|
|
||||||
**Verification:** Cover public errors with and without causes, callback errors
|
|
||||||
with candidate context, and converted built-in failures. Assert useful fields,
|
|
||||||
cause identity, context, and absence of duplicate diagnostics without fixing
|
|
||||||
complete message wording as a contract.
|
|
||||||
|
|
||||||
## 5. P2: Absolute paths inside the checkout are classified as outside
|
|
||||||
|
|
||||||
**Resolution:** Addressed. Absolute destinations and symlink targets within the
|
|
||||||
captured repository directory map to candidate paths before component
|
|
||||||
traversal. Absolute paths with similar external prefixes remain outside.
|
|
||||||
Regression tests also retain symlink-before-parent semantics and demonstrate
|
|
||||||
that removed committed files resolve while live-only files remain missing.
|
|
||||||
`go test ./internal/validation` passed.
|
|
||||||
|
|
||||||
**Owner:** [candidate destination resolver](../../internal/validation/tree.go),
|
|
||||||
the absolute-destination and absolute-symlink branches.
|
|
||||||
|
|
||||||
Both branches classify every path beginning with `/` as outside the checkout.
|
|
||||||
This substitutes path syntax for the requested checkout boundary. An absolute
|
|
||||||
path naming a file inside the captured repository is also labeled outside by this
|
|
||||||
classification. A later boundary-enforcing checker would consequently apply
|
|
||||||
an additional restriction that the user did not select.
|
|
||||||
|
|
||||||
**Evidence:** For repository directory `/checkout/project` with captured
|
|
||||||
`README.md`, the resolver classifies `/checkout/project/README.md` as
|
|
||||||
outside-checkout. An overlay test confirmed this. PromptKit's starting checker
|
|
||||||
uses resolved containment and accepts an existing absolute destination within
|
|
||||||
its checkout; the user selected that convention as the starting specification.
|
|
||||||
The implementation plan calls for checkout-boundary classification and
|
|
||||||
committed-file access, without establishing an absolute-path prohibition.
|
|
||||||
|
|
||||||
**Required remediation:** Map absolute destinations and symlink targets that
|
|
||||||
name paths within the captured repository directory back to candidate-relative
|
|
||||||
paths, then resolve against committed entries. Classify actual external paths
|
|
||||||
as outside without reading them. A different absolute-path policy requires an
|
|
||||||
explicit scope decision.
|
|
||||||
|
|
||||||
**Verification:** Cover absolute direct destinations and absolute symlinks
|
|
||||||
inside and outside the captured root, including similar root prefixes. Use
|
|
||||||
committed entries for existence; neighboring files remain irrelevant.
|
|
||||||
|
|
||||||
## 6. P3: Future Go command behavior appears in implemented internal documentation
|
|
||||||
|
|
||||||
**Resolution:** Addressed. The internal guide describes current environment
|
|
||||||
reuse and links to the roadmap for proposed command coordination and Markdown
|
|
||||||
behavior. Its implemented executor, candidate-file mechanics, and checker
|
|
||||||
integration guidance remain in place. Local links and fragments were checked.
|
|
||||||
|
|
||||||
**Owner:** [shared validation guide](../internal/validation.md),
|
|
||||||
`Prospective Go command recipe`.
|
|
||||||
|
|
||||||
The section describes race, separate vet, and package-compilation behavior that
|
|
||||||
has not been implemented. Although it is labeled prospective, the
|
|
||||||
[documentation policy](../policy/documentation.md) assigns future behavior to
|
|
||||||
`docs/roadmap/` and limits other documents to their implemented boundary.
|
|
||||||
|
|
||||||
**Required remediation:** Replace the future command recipe with a link to the
|
|
||||||
roadmap's coordination design. Keep the internal guide's implemented executor,
|
|
||||||
environment reuse, candidate-file mechanics, and checker integration procedure.
|
|
||||||
Document exact command behavior in its canonical owners when the capabilities
|
|
||||||
land.
|
|
||||||
|
|
||||||
**Verification:** Review the guide against the current executor and check its
|
|
||||||
links. Preserve the distinction between foundation completion and completed
|
|
||||||
optional features.
|
|
||||||
|
|
||||||
## Foundation review evidence and limits
|
|
||||||
|
|
||||||
- `go test ./...` passed; unchanged packages used cached results.
|
|
||||||
- `go run ./internal/apicheck` passed.
|
|
||||||
- Recent production-code, test, and documentation diffs were inspected. The
|
|
||||||
existing tests protect default execution, callback failure handling, facade
|
|
||||||
error identity, publication state, and representative committed-tree cases.
|
|
||||||
- Temporary Go overlays outside the worktree reproduced the additional cases
|
|
||||||
above against current code. Their expected failures are review evidence,
|
|
||||||
not changes to the committed test suite.
|
|
||||||
- No new universal release gate, public validator-registration framework,
|
|
||||||
consumer-check requirement, or change to publication completion was found.
|
|
||||||
Finding 5 identifies an additional boundary restriction; findings 1–4
|
|
||||||
identify failures to satisfy the intended behavior. Finding 6 concerns
|
|
||||||
documentation ownership.
|
|
||||||
|
|
||||||
This review evaluates the completed foundation. It does not establish that the
|
|
||||||
remaining v0.2.0 features have been implemented or that their eventual checker
|
|
||||||
semantics are verified.
|
|
||||||
|
|
||||||
## v0.2.0 architecture assessment
|
|
||||||
|
|
||||||
The intended package and ownership boundaries are implemented. The root
|
|
||||||
`releasekit` facade owns requests, validation selections, diagnostics, and
|
|
||||||
publication/delivery outcomes. The separate `buildinfo` facade depends on the
|
|
||||||
standard library and `internal/runtimeinfo`; its graph remains independent of
|
|
||||||
orchestration and the new parsing dependencies.
|
|
||||||
|
|
||||||
`Check` and `Publish` use the same request conversion and
|
|
||||||
`internal/candidate.Validate`. `internal/validation` coordinates one native
|
|
||||||
test suite, selected full vet and static package compilation, and selected
|
|
||||||
committed-file checks. Formatting, distribution, file-size, and Markdown checks
|
|
||||||
share candidate inventory and lazy blob access. Goldmark and `x/mod/modfile`
|
|
||||||
remain internal dependencies. Product callbacks, artifact building and version
|
|
||||||
injection, publication guards/recovery, and hosted delivery retain their owners.
|
|
||||||
The expected push URL is compared exactly in publication preflight; local
|
|
||||||
checking ignores it. The CLI owns profile conversion, presentation, and exits.
|
|
||||||
|
|
||||||
The consumer Woodpecker template verifies tagged source before selecting the
|
|
||||||
tool through temporary module metadata. Audita's local wrapper and workflow
|
|
||||||
adopt that approach in commit `17421bc`; the inspected declarations preserve
|
|
||||||
its existing dependency version, image, secret name, and release profile.
|
|
||||||
|
|
||||||
All ten feature areas are present. The review identified three behavior gaps
|
|
||||||
within Markdown validation and self-bootstrap. Finding 8 imposed unrequested
|
|
||||||
existence/boundary checks on image alternative text. Finding 9 effectively
|
|
||||||
required a prepopulated tool module cache. The review found no
|
|
||||||
additional public package, validator-registration framework, universal optional
|
|
||||||
check, arbitrary inspection limit, or change to source-publication completion.
|
|
||||||
|
|
||||||
## 7. P2: Heading anchors omit autolink display text
|
|
||||||
|
|
||||||
**Resolution:** Addressed. Heading extraction includes autolink display labels.
|
|
||||||
Parser coverage includes URL/email headings and surrounding text; committed
|
|
||||||
fragment checks cover both forms. The new cases failed before the fix, and
|
|
||||||
`go test ./internal/validation` passed afterward.
|
|
||||||
|
|
||||||
**Owner:** [Markdown heading extraction](../../internal/validation/markdown.go),
|
|
||||||
`markdownHeadingText`, lines 115–139.
|
|
||||||
|
|
||||||
The agreed convention derives anchors from visible heading text. The extractor
|
|
||||||
handles text and code spans and recurses through formatting nodes, but Goldmark's
|
|
||||||
`ast.AutoLink` stores its visible text in `Label` and has no text children.
|
|
||||||
URL and email autolinks therefore disappear from the heading before slugging.
|
|
||||||
|
|
||||||
**Evidence:** A temporary overlay probe against the current checker used:
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
# <https://example.invalid>
|
|
||||||
[section](#httpsexampleinvalid)
|
|
||||||
```
|
|
||||||
|
|
||||||
The computed anchor was the empty string, and the section link failed with
|
|
||||||
`heading anchor does not exist`. The same failure occurred for a heading
|
|
||||||
`# <maintainer@example.invalid>` and fragment `#maintainerexampleinvalid`.
|
|
||||||
Existing anchor tests cover text, code, formatting, entities, Unicode, and
|
|
||||||
duplicates, while existing autolink coverage only checks URL extraction.
|
|
||||||
|
|
||||||
**Required remediation:** Include an autolink's display label in heading text
|
|
||||||
before applying the existing normalization and duplicate-anchor algorithm.
|
|
||||||
Preserve the current HTML, code-span, and ordinary link-label handling.
|
|
||||||
|
|
||||||
**Verification:** Add parser coverage for URL and email autolinks inside headings,
|
|
||||||
including surrounding text, and a representative committed-fragment check.
|
|
||||||
Keep external destination availability outside this offline capability.
|
|
||||||
|
|
||||||
## 8. P2: Image alternative text creates additional release requirements
|
|
||||||
|
|
||||||
**Resolution:** Addressed. Destination extraction records an image source and
|
|
||||||
skips its alternative-text children. Regression coverage exercises nested
|
|
||||||
images/links, missing anchors, and outside-checkout label syntax under both
|
|
||||||
boundary settings. Real linked images still report missing sources and link
|
|
||||||
targets. The regression failed before the fix, and
|
|
||||||
`go test ./internal/validation` passed afterward.
|
|
||||||
|
|
||||||
**Owner:** [Markdown link extraction](../../internal/validation/markdown.go),
|
|
||||||
`parseMarkdown`, especially the image branch and AST traversal at lines 65–110.
|
|
||||||
|
|
||||||
After recording an image destination, the walker continues through the image's
|
|
||||||
label children and records nested link/image syntax as independent destinations.
|
|
||||||
Those children contribute plain alternative text to the rendered image. The
|
|
||||||
checker consequently requires files and anchors that the document does not
|
|
||||||
navigate to or load, and boundary enforcement can also reject those labels.
|
|
||||||
|
|
||||||
**Evidence:** With only `image.png` committed, this valid Markdown is rejected
|
|
||||||
for missing `missing.png`:
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
](image.png)
|
|
||||||
```
|
|
||||||
|
|
||||||
Goldmark's own renderer produces `<img src="image.png" alt="inner">`.
|
|
||||||
Similarly, `](image.png)` renders an image with alternative
|
|
||||||
text `label`, while ReleaseKit records and validates `missing.md` as a link.
|
|
||||||
Temporary overlay probes confirmed both extraction and rendering; the first
|
|
||||||
case also reproduced the checker failure against committed Git contents.
|
|
||||||
|
|
||||||
**Required remediation:** Record the outer image destination and treat its label
|
|
||||||
as alternative text during destination extraction. Preserve real linked images:
|
|
||||||
`[](guide.md)` has an image source and an enclosing link target
|
|
||||||
that both require validation. This change removes the unintended requirement
|
|
||||||
without narrowing supported Markdown syntax.
|
|
||||||
|
|
||||||
**Verification:** Cover nested image/link syntax in alternative text, including
|
|
||||||
an outside-checkout label destination under boundary enforcement. Verify that
|
|
||||||
real linked images still report missing image sources and missing link targets.
|
|
||||||
|
|
||||||
## 9. P1: ReleaseKit's source-delivery bootstrap fails with an empty module cache
|
|
||||||
|
|
||||||
**Resolution:** Addressed. Self-bootstrap uses normal Go dependency access for
|
|
||||||
its readonly tool build after tag verification. The maintained workflow test
|
|
||||||
starts with an empty module cache and a local HTTP module proxy, builds a tool
|
|
||||||
with an external dependency, and verifies execution, clean tagged source, and
|
|
||||||
temporary-output cleanup. A wrong commit stops before Go or proxy access. The
|
|
||||||
regression failed before the fix and passed afterward. The delivery guide now
|
|
||||||
describes tool dependency access and its separation from offline validation.
|
|
||||||
The uncached offline suite, `go run ./internal/apicheck`, and local documentation
|
|
||||||
link/fragment checks passed after all three fixes.
|
|
||||||
|
|
||||||
**Owners:** [source-delivery workflow](../../examples/woodpecker/releasekit-source-delivery.yml),
|
|
||||||
lines 27–31; [workflow verification](../../cmd/releasekit/woodpecker_test.go),
|
|
||||||
`TestWoodpeckerSourceDeliveryTemplateSelfBootstraps`; and the
|
|
||||||
[delivery guide](../consumers/delivery.md#woodpecker-tag-workflows).
|
|
||||||
|
|
||||||
The source template sets `GOPROXY=off` and `GOSUMDB=off` before building the tool
|
|
||||||
and provides no tool dependency preparation. ReleaseKit now imports Goldmark and
|
|
||||||
`x/mod` through validation, so the standard Go image needs those modules to build
|
|
||||||
`./cmd/releasekit`. On a fresh runner the workflow stops before `ci-deliver` and
|
|
||||||
the hosted note page is never delivered. The previous dependency-free tool did
|
|
||||||
not expose this problem. The guide describes cache mounts as optional, while
|
|
||||||
the current implementation effectively requires a prepopulated module cache.
|
|
||||||
|
|
||||||
**Evidence:** Running the template's build command against `edd670e`, with a
|
|
||||||
temporary empty `GOMODCACHE` and its workspace/toolchain/proxy settings, returned
|
|
||||||
exit 1. Both dependencies reported `module lookup disabled by GOPROXY=off`.
|
|
||||||
The existing self-bootstrap test builds a synthetic command that imports only
|
|
||||||
`fmt` and `os`, so it cannot detect missing tool dependencies.
|
|
||||||
|
|
||||||
**Required remediation:** Allow ordinary tool dependency preparation after tag
|
|
||||||
verification. A network-capable readonly tool build or an explicit preparation
|
|
||||||
step can populate the module cache while preserving tagged source. Honor normal
|
|
||||||
Go proxy/private-module/cache settings. Keep offline candidate validation and
|
|
||||||
application artifact compilation in their existing owners. Update the template
|
|
||||||
and guidance together; a prewarmed cache remains an optional deployment choice.
|
|
||||||
|
|
||||||
**Verification:** Exercise the maintained self-bootstrap commands with an empty
|
|
||||||
module cache and a local module proxy serving a real external tool dependency.
|
|
||||||
Verify preparation follows tag/commit verification, the executable runs, tagged
|
|
||||||
module files remain unchanged, and temporary output is cleaned up. Existing
|
|
||||||
delivery tests retain ownership of hosted page behavior.
|
|
||||||
|
|
||||||
## v0.2.0 review evidence and limits
|
|
||||||
|
|
||||||
- Reviewed recent production, test, template, and documentation changes and
|
|
||||||
their shared request, execution, and dependency boundaries.
|
|
||||||
- `GOPROXY=off GOSUMDB=off GOTOOLCHAIN=local go test -count=1 ./...` passed.
|
|
||||||
- `go run ./internal/apicheck` passed. Direct dependency inspection of
|
|
||||||
`buildinfo` confirmed its standard-library/runtime-only graph.
|
|
||||||
- Inspected Audita commit `17421bc` and its actual local and CI bootstrap files.
|
|
||||||
- Temporary overlay tests outside the worktree reproduced findings 7 and 8.
|
|
||||||
Goldmark's renderer confirmed the alternative-text semantics. A separate
|
|
||||||
temporary empty module cache reproduced finding 9. These probes are review
|
|
||||||
evidence; production code and the committed test suite remain unchanged.
|
|
||||||
- Existing tests passed but omitted these cases at review time. The resolutions
|
|
||||||
above record completed fixes and regression coverage.
|
|
||||||
@@ -1,299 +0,0 @@
|
|||||||
# ReleaseKit v0.2.0 roadmap
|
|
||||||
|
|
||||||
Status: Implemented and locally verified. Stages 1–15 are complete; see the
|
|
||||||
[implementation plan](implementation.md) for the completion record. Audita's
|
|
||||||
module-selected local and CI integration is committed at `17421bc`. Broader
|
|
||||||
consumer adoption, architecture review, hosted deployment, and release tagging
|
|
||||||
remain separate work.
|
|
||||||
|
|
||||||
This roadmap catalogs improvements to ReleaseKit v0.1.0. Each item records its
|
|
||||||
rationale, target state, and relevant scope decisions. The
|
|
||||||
[implementation plan](implementation.md) owns the staged work and verification
|
|
||||||
evidence.
|
|
||||||
|
|
||||||
The priorities in [ADR 0002](../adr/0002-routine-releases.md) guide this work:
|
|
||||||
minimize application-owned release code, duplicated mechanics, and routine
|
|
||||||
developer decisions through a standard, minimal API.
|
|
||||||
|
|
||||||
## 1. Establish the shared validation API and profile model
|
|
||||||
|
|
||||||
### Rationale and baseline at plan start
|
|
||||||
|
|
||||||
The shared validation foundation and its remediation are complete. ReleaseKit
|
|
||||||
has common candidate execution, facade-owned diagnostics, committed-file
|
|
||||||
inspection, and a product-specific additional-check extension point. The
|
|
||||||
optional v0.2.0 capabilities now have functioning API/profile selections and
|
|
||||||
checker implementations.
|
|
||||||
|
|
||||||
The [validation-model roadmap](model.md) records this enabling work and its
|
|
||||||
rationale. A common model lets consumers declare choices once and receive
|
|
||||||
ReleaseKit's shared execution and coordination.
|
|
||||||
|
|
||||||
### Target end state
|
|
||||||
|
|
||||||
A facade-owned validation specification and corresponding profile object
|
|
||||||
express the agreed optional checks with consistent defaults and behavior.
|
|
||||||
ReleaseKit owns coordination and diagnostics through the existing `Check` and
|
|
||||||
`Publish` operations. Product-specific checks, publication expectations,
|
|
||||||
artifact builds, and delivery retain their distinct responsibilities.
|
|
||||||
|
|
||||||
The implemented API and profile provide equivalent declarations for the
|
|
||||||
validation capabilities below through the existing shared foundation.
|
|
||||||
|
|
||||||
## 2. Use the application's module-selected ReleaseKit version in CI
|
|
||||||
|
|
||||||
### Rationale and baseline at plan start
|
|
||||||
|
|
||||||
At the v0.1.0 planning baseline, the maintained CI template selected ReleaseKit
|
|
||||||
through a separate `RELEASEKIT_VERSION` value and invoked its command with an
|
|
||||||
explicit `@version`.
|
|
||||||
|
|
||||||
Audita demonstrates the resulting duplication: its local release wrapper builds
|
|
||||||
ReleaseKit using the application's module dependencies, while CI independently
|
|
||||||
selects ReleaseKit v0.1.0. A dependency upgrade can leave CI using an older tool.
|
|
||||||
Maintainers must remember to coordinate both declarations.
|
|
||||||
|
|
||||||
Using the application's module-selected version for both paths gives upgrades
|
|
||||||
one dependency declaration and keeps local publication and CI delivery aligned.
|
|
||||||
Stages 12–14 changed the maintained template and Audita's workflow to this
|
|
||||||
approach; the current [adoption guidance](../consumers/delivery.md#woodpecker-tag-workflows)
|
|
||||||
describes it.
|
|
||||||
|
|
||||||
### Target end state
|
|
||||||
|
|
||||||
For applications that declare ReleaseKit as a module dependency, the standard
|
|
||||||
CI integration uses the ReleaseKit version selected by the released source's
|
|
||||||
module configuration. The workflow verifies the triggering tag and commit and
|
|
||||||
checks out that source before resolving and building the release tool.
|
|
||||||
|
|
||||||
Local publication and CI delivery use the same module-based selection approach.
|
|
||||||
Updating the application's ReleaseKit dependency updates both paths. The
|
|
||||||
consumer workflow supplies the CI event, environment, and credentials; the
|
|
||||||
application profile continues to supply product and delivery settings.
|
|
||||||
|
|
||||||
Tool bootstrap and dependency preparation remain distinct from offline
|
|
||||||
validation and builds. Source publication and hosted delivery retain separate
|
|
||||||
outcomes. ReleaseKit's own source bootstrap and consumers using a separately
|
|
||||||
installed tool remain supported use cases.
|
|
||||||
|
|
||||||
Audita adopted the module-based integration as the first consumer migration in
|
|
||||||
commit `17421bc`.
|
|
||||||
|
|
||||||
The maintained template and Audita's first migration now use one ReleaseKit
|
|
||||||
module declaration for local and hosted integration.
|
|
||||||
|
|
||||||
## 3. Select one base test invocation, including race testing
|
|
||||||
|
|
||||||
### Rationale and baseline at plan start
|
|
||||||
|
|
||||||
ReleaseKit always runs its standard offline Go suite before additional product
|
|
||||||
checks. ConfigKit selects race-enabled testing for its release validation.
|
|
||||||
PromptKit requests the same capability for its concurrent execution and
|
|
||||||
backend-capacity management.
|
|
||||||
Expressing that selection as an additional check would execute the suite twice
|
|
||||||
and leave the application coordinating shared validation mechanics.
|
|
||||||
|
|
||||||
A small declarative selection lets consumers retain their chosen validation
|
|
||||||
while ReleaseKit owns the procedure and runs the suite once.
|
|
||||||
|
|
||||||
### Target end state
|
|
||||||
|
|
||||||
The public Go API and profile support selecting race testing for the single
|
|
||||||
base Go test invocation. With no selection, the current default applies.
|
|
||||||
`Check` and `Publish`, including their CLI forms, use the same selection.
|
|
||||||
|
|
||||||
ReleaseKit constructs the invocation and owns candidate capture, full-suite
|
|
||||||
scope, offline execution, ordering, and failure reporting. Additional product
|
|
||||||
checks remain available after shared validation. Selecting race testing reports
|
|
||||||
unavailable prerequisites clearly and preserves the selected validation.
|
|
||||||
|
|
||||||
The API and profile now let ConfigKit and PromptKit select a race-enabled suite
|
|
||||||
once and remove the corresponding consumer-owned test invocation when they
|
|
||||||
adopt the selection.
|
|
||||||
|
|
||||||
## 4. Offer a separate full vet pass
|
|
||||||
|
|
||||||
### Rationale and baseline at plan start
|
|
||||||
|
|
||||||
ConfigKit and PromptKit currently run a full `go vet` pass in addition to their
|
|
||||||
test suites. ReleaseKit relies on test-time vet unless a consumer supplies an
|
|
||||||
additional command. That leaves consumers coordinating vet coverage and
|
|
||||||
repeated work.
|
|
||||||
|
|
||||||
### Target end state
|
|
||||||
|
|
||||||
A public API and profile option selects a separate full vet pass within shared
|
|
||||||
candidate validation. ReleaseKit automatically omits test-time vet when that
|
|
||||||
pass is selected. The base suite runs once, followed by the selected vet pass,
|
|
||||||
with failures reported through the ordinary check and publication flow.
|
|
||||||
|
|
||||||
The option preserves current defaults for consumers that leave it unset.
|
|
||||||
ReleaseKit owns the offline command and its coordination with base testing.
|
|
||||||
|
|
||||||
The API and profile now support replacing ConfigKit's and PromptKit's separate
|
|
||||||
vet commands and manual test-time vet settings with one declarative choice.
|
|
||||||
|
|
||||||
## 5. Verify package compilation for selected targets
|
|
||||||
|
|
||||||
### Rationale and baseline at plan start
|
|
||||||
|
|
||||||
ReleaseKit's existing build declaration selects executable artifacts and their
|
|
||||||
delivery. ConfigKit is a source-only library that checks package compilation
|
|
||||||
for Linux amd64 and arm64. Its current release script owns the cross-target
|
|
||||||
build loop even though the underlying mechanics are shared across consumers.
|
|
||||||
|
|
||||||
### Target end state
|
|
||||||
|
|
||||||
The public API and profile can declare optional package-compilation targets
|
|
||||||
independently of executable artifacts. ReleaseKit compiles the module's packages
|
|
||||||
for those targets within candidate validation, after the selected test and vet
|
|
||||||
work. `Check` and `Publish` share this behavior and report compilation failures
|
|
||||||
through their existing outcomes.
|
|
||||||
|
|
||||||
Package compilation uses the existing pure-Go build baseline (`CGO_ENABLED=0`).
|
|
||||||
|
|
||||||
A source-only library retains page-only delivery. Package-compilation checks
|
|
||||||
require no binary name, version smoke command, or artifact manifest. Successful
|
|
||||||
compilation establishes build compatibility; execution on a target remains a
|
|
||||||
separate concern. Consumers select targets for their support commitments.
|
|
||||||
|
|
||||||
The API and profile now let ConfigKit declare its two Linux targets and remove
|
|
||||||
its release-specific compilation loop when it adopts the selection.
|
|
||||||
|
|
||||||
## 6. Check an optional expected publication endpoint
|
|
||||||
|
|
||||||
### Rationale and baseline at plan start
|
|
||||||
|
|
||||||
ReleaseKit resolves and captures the selected remote's push endpoint and
|
|
||||||
rechecks it during publication. ConfigKit additionally declares an expected
|
|
||||||
authoritative destination in its release script. Retaining that expectation
|
|
||||||
outside ReleaseKit would duplicate destination-resolution work.
|
|
||||||
|
|
||||||
### Target end state
|
|
||||||
|
|
||||||
An optional public API and profile setting declares the expected publication
|
|
||||||
destination. `Publish` compares it exactly with the effective push URL resolved
|
|
||||||
by Git before candidate validation and publication. A mismatch produces a clear
|
|
||||||
failure.
|
|
||||||
The existing captured-endpoint, recheck, and recovery machinery continues to
|
|
||||||
govern the operation.
|
|
||||||
|
|
||||||
The expectation applies to the publication destination. Fetch configuration
|
|
||||||
retains its existing semantics, and `Check` retains its local-only behavior.
|
|
||||||
Consumers that omit the expectation keep the current remote-selection model.
|
|
||||||
|
|
||||||
Consumers can now declare the intended push destination without maintaining
|
|
||||||
their own publication preflight logic.
|
|
||||||
|
|
||||||
## 7. Offer Go formatting validation
|
|
||||||
|
|
||||||
### Rationale and baseline at plan start
|
|
||||||
|
|
||||||
PromptKit maintains a shell loop that enumerates tracked Go files and checks
|
|
||||||
their formatting. ReleaseKit currently leaves this generic mechanism to
|
|
||||||
consumer-owned additional checks. Shared support would remove that script
|
|
||||||
fragment and provide consistent diagnostics across applications.
|
|
||||||
|
|
||||||
### Target end state
|
|
||||||
|
|
||||||
An optional public API and profile selection enables formatting validation for
|
|
||||||
tracked Go source using ordinary `gofmt` conventions. `Check` and `Publish`,
|
|
||||||
including their CLI forms, apply the same check within candidate validation.
|
|
||||||
The check runs offline, reports affected paths, and leaves files unchanged.
|
|
||||||
|
|
||||||
Consumers select the capability once and rely on ReleaseKit for enumeration,
|
|
||||||
format checking, and failure reporting. Existing validation defaults remain
|
|
||||||
unchanged when the option is unset.
|
|
||||||
|
|
||||||
PromptKit can now remove its local formatting loop and select the shared check
|
|
||||||
through its release profile when it adopts the capability.
|
|
||||||
|
|
||||||
## 8. Offer offline Markdown-link validation
|
|
||||||
|
|
||||||
### Rationale and baseline at plan start
|
|
||||||
|
|
||||||
PromptKit's largest generic validation block is a local Markdown-link checker.
|
|
||||||
It owns parsing, destination resolution, heading anchors, and diagnostics.
|
|
||||||
ReleaseKit currently leaves these mechanics to consumer-owned additional checks.
|
|
||||||
|
|
||||||
Sharing the check would remove a locally maintained parser and give consumers
|
|
||||||
one documented convention for validating navigation within their documentation.
|
|
||||||
Consumers that require documentation to remain within the checkout also need
|
|
||||||
a shared option to enforce that boundary.
|
|
||||||
|
|
||||||
### Target end state
|
|
||||||
|
|
||||||
An optional public API and profile selection checks tracked Markdown documents
|
|
||||||
for local destinations and supported heading fragments within the checkout.
|
|
||||||
`Check` and `Publish`, including their CLI forms, use the same offline,
|
|
||||||
read-only validation and report the source file, location, and target of each
|
|
||||||
problem.
|
|
||||||
|
|
||||||
ReleaseKit owns a documented link and heading-anchor convention that consumers
|
|
||||||
can follow, using PromptKit's current conventions as the starting specification.
|
|
||||||
The supported behavior accounts for common inline and reference links, code
|
|
||||||
examples, escaped destinations, and duplicate headings. External
|
|
||||||
website availability is outside the check's scope.
|
|
||||||
|
|
||||||
By default, links outside the checkout are classified and reported as outside
|
|
||||||
the shared check's scope. An optional setting makes local destinations outside
|
|
||||||
the checkout a validation failure, using the same parser and diagnostics.
|
|
||||||
Boundary validation remains independent of neighboring checkout contents.
|
|
||||||
Existing validation defaults remain unchanged when the option is unset.
|
|
||||||
|
|
||||||
PromptKit can now replace its local Markdown checker with a profile selection
|
|
||||||
and rely on shared parsing rules and diagnostics when it adopts the capability.
|
|
||||||
|
|
||||||
## 9. Offer module-distribution checks
|
|
||||||
|
|
||||||
### Rationale and baseline at plan start
|
|
||||||
|
|
||||||
PromptKit checks that released source is independent of neighboring checkouts
|
|
||||||
by excluding committed workspace files and local filesystem module replacements.
|
|
||||||
ReleaseKit's offline Go environment controls validation execution; inspecting
|
|
||||||
the distributed candidate requires separate checks that consumers currently own.
|
|
||||||
|
|
||||||
Shared inspection would remove these local checks and provide consistent
|
|
||||||
diagnostics for consumers with the same distribution requirements.
|
|
||||||
|
|
||||||
### Target end state
|
|
||||||
|
|
||||||
The public API and profile offer independently selectable rules for committed
|
|
||||||
workspace files (`go.work` and `go.work.sum`) and local filesystem replacements
|
|
||||||
in committed module declarations. Each selected rule reports offending paths
|
|
||||||
and, where applicable, module directives through shared candidate validation.
|
|
||||||
|
|
||||||
The replacement rule permits versioned module replacements. Workspace use and
|
|
||||||
vendoring retain their existing behavior unless affected by a selected rule.
|
|
||||||
The checks inspect candidate contents independently of the Go test environment.
|
|
||||||
`Check` and `Publish`, including their CLI forms, apply the same offline,
|
|
||||||
read-only checks. Omitted selections preserve current defaults.
|
|
||||||
|
|
||||||
PromptKit can now declare its distribution requirements and remove the
|
|
||||||
corresponding consumer-owned checks when it adopts the selections.
|
|
||||||
|
|
||||||
## 10. Offer an individual-file-size check
|
|
||||||
|
|
||||||
### Rationale and baseline at plan start
|
|
||||||
|
|
||||||
Unintentionally committed binaries and large assets can increase the size of
|
|
||||||
released source. ReleaseKit currently leaves file-size inspection to consumers.
|
|
||||||
A shared check would catch oversized files while allowing each consumer to
|
|
||||||
declare its intended size limit and exceptions.
|
|
||||||
|
|
||||||
### Target end state
|
|
||||||
|
|
||||||
An optional public API and profile selection checks individual tracked files
|
|
||||||
in the current candidate. When enabled, the default limit is 1 MB (1,000,000
|
|
||||||
bytes); consumers can configure the limit and explicit repository-relative
|
|
||||||
path exclusions for intentional large files. A file exceeding the limit fails
|
|
||||||
validation with its path, observed size, and configured limit.
|
|
||||||
|
|
||||||
The check measures file size. Small binaries remain subject to ordinary review.
|
|
||||||
Its scope is the current candidate's files; historical objects and aggregate
|
|
||||||
repository size remain separate concerns. `Check` and `Publish`, including
|
|
||||||
their CLI forms, use the same offline, read-only inspection. The check is
|
|
||||||
disabled by default.
|
|
||||||
|
|
||||||
Consumers can now catch oversized candidate files through a small declaration
|
|
||||||
and remove corresponding local inspection code when they adopt the check.
|
|
||||||
Reference in New Issue
Block a user