From 89c5b2c1fd127b012a1d16e2c98fc8aff568294f Mon Sep 17 00:00:00 2001 From: Eric Rakestraw Date: Wed, 7 Oct 2026 18:39:15 +0000 Subject: [PATCH] Document shared validation integration --- docs/internal/overview.md | 2 + docs/internal/validation.md | 82 ++++++++++++++++ docs/roadmap/implementation.md | 171 +++++++++++++++++++++++++++++++++ 3 files changed, 255 insertions(+) create mode 100644 docs/internal/validation.md diff --git a/docs/internal/overview.md b/docs/internal/overview.md index ee0e1bf..98d0fae 100644 --- a/docs/internal/overview.md +++ b/docs/internal/overview.md @@ -67,6 +67,8 @@ publication owns endpoint guards, tag creation, push, and recovery around that same candidate validation path. `internal/validation.CandidateTree` reads committed blobs lazily and resolves local destinations from committed entries; it does not consult neighboring files or traverse submodule checkouts. +See the [shared validation guide](validation.md) for checker, Go command, and +candidate-file integration mechanics. ## Capability owners and behavioral evidence diff --git a/docs/internal/validation.md b/docs/internal/validation.md new file mode 100644 index 0000000..118c9b8 --- /dev/null +++ b/docs/internal/validation.md @@ -0,0 +1,82 @@ +# Shared validation mechanics + +`internal/validation` owns reusable checks for one captured candidate. +`internal/candidate` captures the clean source revision and keeps the +validation sequence shared by local checking and publication. It calls the +shared executor, runs product-specific `AdditionalChecks` once, and owns the +post-validation build callback and local-state recheck. `internal/publish` +adds its endpoint guards, tag creation, push, and recovery around that same +candidate path. + +The current executor runs the default offline Go suite. Its request carries the +captured repository directory and commit, output writer, and internal +settings. `Request.ReadCandidateTree` lets a selected file check request +candidate contents; the default Go-only path does not enumerate the tree. +`CandidateTree` gets metadata and bytes from Git objects, reads blob bytes +lazily, and resolves destinations without consulting the worktree or +neighboring files. + +## Adding a shared check + +When an optional check is accepted for implementation: + +1. Define its typed Go setting in the root facade and its equivalent CLI-owned + JSON field. Specify zero-value and omitted-profile behavior in GoDoc and the + configuration reference. Keep future settings in the roadmap until their + check is implemented. +2. Add the corresponding internal setting and explicit conversions. Use the + same root request conversion for `Check` and `Publish`, and the shared CLI + request conversion for profile-based candidate commands. +3. Implement a plain check function owned by `internal/validation`. Keep its + rule semantics in the capability owner and pass only the captured candidate + inputs it needs. A file-oriented check can call `Request.ReadCandidateTree` + and read only the blobs it inspects. +4. Return an internal `*Failure` with the check identity, repository-relative + findings, useful locations where available, and the underlying cause. Let + the root facade convert those records to its own diagnostic types. Preserve + cancellation and process errors through `Unwrap`. +5. Add the check to the shared executor at the ordering point selected by its + capability. Stop on failure. Keep product assertions in `AdditionalChecks` + and profile `checks`; keep artifact building in `internal/build`. +6. Cover observable behavior through both the Go facade and profile path when + both are supported. Check default behavior, useful findings, cause + preservation, cancellation where relevant, and failure stopping. Reuse the + existing local Git and CLI fixtures. +7. Update only the canonical owners for behavior that has landed: GoDoc for the + API, configuration and CLI references for profile behavior, and this + inventory for internal ownership. Keep later feature contracts in the + product roadmap. + +Do not add a public validator registration interface. The public specification +selects ReleaseKit-owned checks; `AdditionalChecks` remains the extension point +for product behavior. + +## Prospective Go command recipe + +The complete planned procedure uses one test invocation. Race selection +modifies that command. When a separate full vet pass is selected, run tests with +vet disabled and then run native `go vet`. Selected package-compilation targets +run after test and vet with the static Go environment, including +`CGO_ENABLED=0`. Keep these compatibility checks independent of executable +artifact declarations. These selections become operational as their checkers +are implemented. + +Reuse `internal/gotool` for native and static environments and target handling. +Keep toolchain and module-cache discovery in `gotool`; do not reproduce its +environment logic in a checker. Build output names, version injection, native +smoke checks, and artifact digests remain owned by `internal/build`. + +## File-check coordination + +File checks consume the captured tree and return findings to the shared error +model. They do not read sibling worktrees or follow live symlink targets. +`CandidateTree.ResolveDestination` returns data describing entries, +directories, missing paths, checkout boundaries, submodule paths, and symlink +cycles; the caller selects which observations fail validation or are reported +as out of scope. + +The Markdown capability will use PromptKit's current parser and anchor +conventions as its starting evidence. Supported link syntax, anchors, +diagnostics, and boundary policy belong to that feature's roadmap and +implementation prompt. This foundation provides only the committed-file and +destination-resolution primitives. diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md index 98d9e38..20ecf5c 100644 --- a/docs/roadmap/implementation.md +++ b/docs/roadmap/implementation.md @@ -342,6 +342,11 @@ will add setting-specific mapping/equivalence cases at this established boundary ## Stage 7: Record capability integration recipes and consumer shapes +**Completion:** Complete. Internal guidance now records setting and checker +ownership, Go command coordination, and candidate-file integration. The +prospective examples below compare the agreed declarations with the read-only +consumer review. + **Outcome:** Subsequent feature prompts can use the foundation without redesigning its ownership or inventing a public extension framework. @@ -372,6 +377,172 @@ and the ownership table in `model.md`. Confirm product checks still fit the existing callback/profile extension point. Runtime tests are self-contained and independent of the three sibling checkouts. +### Prospective consumer shapes + +These examples show the agreed model before its optional settings are +implemented. The `Validation` field and the profile `validation` object are +prospective until their corresponding checkers land. + +#### Audita: retain the existing artifact build + +The zero-value validation selection preserves current defaults while the +existing Linux application artifacts remain declared separately: + +```go +request := releasekit.ReleaseRequest{ + Product: "Audita", + Version: version, + Validation: releasekit.ValidationSpec{}, // prospective; zero value keeps current validation + Build: &releasekit.BuildSpec{ + MainPackage: "./cmd/audita", + BinaryName: "audita", + Targets: []releasekit.Target{ + {OS: "linux", Arch: "amd64"}, + {OS: "linux", Arch: "arm64"}, + }, + }, +} +``` + +Its profile keeps the existing build declaration and omits `validation`: + +```json +{ + "product": "Audita", + "remote": "origin", + "build": { + "main_package": "./cmd/audita", + "binary_name": "audita", + "targets": ["linux/amd64", "linux/arm64"] + }, + "delivery": { + "base_url": "https://gitea.maximumdirect.net", + "owner": "eric", + "repository": "audita", + "token_env": "RELEASEKIT_GITEA_TOKEN" + } +} +``` + +#### ConfigKit: select release compatibility checks + +The declaration expresses its race test, separate full vet, and source-only +Linux compilation commitments without selecting executable artifacts: + +```go +request := releasekit.ReleaseRequest{ + Product: "ConfigKit", + Version: version, + Validation: releasekit.ValidationSpec{ + Go: releasekit.GoValidationSpec{ + Race: true, + FullVet: true, + CompileTargets: []releasekit.Target{ + {OS: "linux", Arch: "amd64"}, + {OS: "linux", Arch: "arm64"}, + }, + }, + }, +} +``` + +```json +{ + "product": "ConfigKit", + "validation": { + "go": { + "race": true, + "full_vet": true, + "compile_targets": ["linux/amd64", "linux/arm64"] + } + } +} +``` + +The consumer's baseline-toolchain requirement remains its compatibility +decision. The selection above describes checks, not a promise to run them with +every Go toolchain. + +#### PromptKit: share mechanics and keep example assertions + +Shared settings cover the maintained race and vet passes, Go formatting, +checkout-bounded Markdown links, and the two distribution rules. Substantive +example assertions remain in the existing `AdditionalChecks` extension point +or profile `checks`: + +```go +request := releasekit.ReleaseRequest{ + Product: "Promptkit", + Version: version, + Validation: releasekit.ValidationSpec{ + Go: releasekit.GoValidationSpec{Race: true, FullVet: true}, + GoFormat: true, + Markdown: &releasekit.MarkdownValidationSpec{EnforceCheckoutBoundary: true}, + ModuleDistribution: releasekit.ModuleDistributionValidationSpec{ + WorkspaceFiles: true, + LocalReplacements: true, + }, + }, + AdditionalChecks: checkExamples, +} +``` + +```json +{ + "product": "Promptkit", + "validation": { + "go": {"race": true, "full_vet": true}, + "go_format": true, + "markdown": {"enforce_checkout_boundary": true}, + "module_distribution": { + "workspace_files": true, + "local_replacements": true + } + }, + "checks": [ + {"args": ["python3", "scripts/check-examples.py"]} + ] +} +``` + +The example-check command is illustrative of a product-owned check retained +from PromptKit's current release assertions; it is not a file in the reviewed +checkout. + +### Read-only consumer review + +Reviewed on 2026-10-07. All three local worktrees were clean. The declarations +were compared with Audita `bd62f36`, ConfigKit `dc09959`, and PromptKit +`7310ef3`; no sibling repository was modified. + +- Audita's `releasekit.json` already declares its product, remote, Linux binary + build, and Gitea destination. Its nine-line `scripts/release.sh` builds the + module-selected ReleaseKit executable and delegates to it. It has no + additional candidate-validation block to remove; omitting optional + selections preserves its current validation. Module-selected CI bootstrap + remains separate later work. +- ConfigKit's 29-line `scripts/release-check.sh` selects one race test run with + test-time vet disabled, runs full vet, and compiles all packages for Linux + amd64 and arm64. Those invocation and target-loop mechanics correspond to + the shared Go settings. Its 133-line publication script also checks an + expected remote URL and advances `main` before publishing a tag. The + endpoint expectation is a separate publication capability; the main-branch + publication flow remains product-specific. Its `CONFIGKIT_BASELINE_TOOLCHAIN` + requirement covers cached supported Go 1.25 patch releases and remains a + consumer commitment. +- PromptKit's 152-line `scripts/release-check.sh` owns the race suite, separate + vet, tracked-Go formatting check, Markdown link and heading checks, + workspace-file and local-replacement checks, a vendor-directory rejection, + and substantive example output assertions. The shared validation settings + correspond to race, vet, formatting, Markdown, workspace-file, and + replacement mechanics; vendor and example assertions remain product checks. + Its 57-line `scripts/release.sh` also checks release-note sections and + publishes an annotated tag, which remain in the product's release procedure. + +The file-size capability has no corresponding local check in these reviewed +scripts. Consumer migrations and measurements of realized code removal remain +outside this implementation plan. + ## Stage 8: Verify and document the completed foundation **Outcome:** The enabling refactor is complete, its current boundary is clear,