diff --git a/check.go b/check.go index 654a4f7..c235dec 100644 --- a/check.go +++ b/check.go @@ -55,7 +55,10 @@ type ReleaseRequest struct { } // ValidationSpec selects optional shared validation checks. Its zero value -// preserves the current validation behavior. +// preserves the current validation behavior. File checks inspect the selected +// module and shared-file inputs. Independent nested modules form automatic +// input boundaries; vendored files remain included. Referenced destinations +// remain available for targeted inspection without expanding the input set. type ValidationSpec struct { // SharedFiles adds repository-relative committed files to optional file // checks. Nil selects the optional root COPYRIGHT, LICENSE, and @@ -103,7 +106,8 @@ type ModuleDistributionValidationSpec struct { // nested paths and symlink entries. It does not select Go's test workspace. WorkspaceFiles bool // LocalReplacements rejects filesystem replacements in committed go.mod - // declarations, including nested modules. It does not select Go's workspace. + // declarations in the selected inputs, including vendor and explicit shared + // files. It does not select Go's workspace. LocalReplacements bool } @@ -139,7 +143,7 @@ type GoValidationSpec struct { // files after formatting. Its zero value disables that distribution check and // does not change Go's workspace environment. // Validation.ModuleDistribution.LocalReplacements parses committed go.mod -// declarations, including nested modules, and rejects filesystem replacements +// declarations in the selected inputs and rejects filesystem replacements // after workspace-file inspection. Its zero value disables that check. // Validation.FileSize checks each selected committed blob after module // distribution checks. Its nil value disables size checks; an empty object diff --git a/docs/cli.md b/docs/cli.md index 49c44ad..142be64 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -47,11 +47,13 @@ mode with cgo disabled. This check produces no artifacts and does not execute target binaries. Compilation failures use the `package-compile` identity and show the selected target. When `validation.go_format` is true, `check` examines regular committed Go files with the Go formatter after tests, vet, and package -compilation. It includes vendor and nested-module source, ignores the worktree +compilation. It uses the selected module and shared-file inputs, including +vendored source, and ignores the worktree and symlink blobs, and reports unformatted paths as `go-format` without modifying files. When `validation.module_distribution.workspace_files` is true, -`check` reports committed `go.work` and `go.work.sum` blobs, including nested -and symlink entries, as `workspace-files`. This inspection is independent of +`check` reports committed `go.work` and `go.work.sum` blobs in those inputs, +including symlink entries, as `workspace-files`. Automatic file inputs stop at +independent nested modules. This inspection is independent of `GOWORK` and ignores uncommitted files. Any artifact build selected by the separate `build` setting runs after shared validation and configured checks. When `validation.markdown` is a non-null object, `check` checks committed local @@ -107,7 +109,8 @@ go.work.sum paths as `workspace-files`. Formatting failures are reported as When `validation.module_distribution.local_replacements` is true, the command parses committed `go.mod` declarations in the selected module after workspace-file inspection. Vendored contents remain in scope, while -independently released nested modules are excluded. Filesystem replacements use +automatic inputs stop at independently released nested modules. Explicit shared +files join the file-check inputs without expanding Go scope. Filesystem replacements use the `local-replacements` identity and include the declaration path, source line, and target; versioned replacements are permitted. Committed module symlinks are resolved within the candidate, regardless of `GOWORK`. diff --git a/docs/config.md b/docs/config.md index 3e163ae..b911e0e 100644 --- a/docs/config.md +++ b/docs/config.md @@ -44,7 +44,10 @@ shared files. An explicit list replaces those defaults. Each explicit file must exist in the candidate, even when no file checks are enabled. Paths are literal, repository-relative files with no glob semantics and may select a file outside the chosen module. ReleaseKit deduplicates them with module inputs by path. This -field does not enable any checks. +field does not enable any checks or expand Go test, vet, or package-compilation +scope. Automatic file inputs stop at independent nested-module boundaries; +vendored files remain included. Reference inspection can read destinations +elsewhere in the captured repository without adding them to those inputs. `validation.go.race` enables the race detector for the single standard Go test suite. `validation.go.full_vet` runs a separate native `go vet` pass after that suite succeeds; ReleaseKit disables test-time vet for that suite to avoid @@ -57,7 +60,8 @@ executable, or create an artifact manifest. Omitted or empty `compile_targets` selects no package-compilation pass. When `full_vet` is omitted or false, the test command keeps its existing vet behavior. These settings are independent. `validation.go_format` checks regular committed Go blobs with the Go formatter -used to build ReleaseKit. It includes vendor and nested-module source, ignores +used to build ReleaseKit. It uses the selected file inputs, including vendor and +explicit shared files, and ignores symlink blobs and the worktree, and reports every selected path whose bytes change under formatting. It never writes formatted bytes back. Omitted or false disables the check. It runs after tests, selected full vet, and selected package @@ -92,7 +96,8 @@ of `GOWORK`; it does not select or change the workspace used by Go commands, and vendored contents remain in scope. Omitted or false disables it. When `validation.module_distribution.local_replacements` is true, it parses the selected module's committed `go.mod` declarations. Vendored contents remain in -scope, while independently released nested modules are excluded. It reports +scope; an explicit shared-file selection can include an individual declaration +from another module. It reports `replace` directives whose replacement has no version. These filesystem replacements include relative and absolute paths; versioned module replacements are permitted. Committed `go.mod` symlinks are resolved within the candidate, diff --git a/docs/consumers/check.md b/docs/consumers/check.md index 35032ef..c527072 100644 --- a/docs/consumers/check.md +++ b/docs/consumers/check.md @@ -33,10 +33,11 @@ example, both `integrations/core/v2` and `integrations/core` can declare `/docs/releases/.md`. The repository must have a clean index and worktree on `main`, and the selected -version must be stable `vMAJOR.MINOR.PATCH`. The committed -`docs/releases/.md` note must have a first Markdown H1 containing the +version must be stable `vMAJOR.MINOR.PATCH`. The module-local committed +`/docs/releases/.md` note must have a first Markdown H1 containing the product name and exact version as complete title elements. No local tag with -that version may already exist. +the derived complete tag may already exist. Different modules may use the same +semantic version with distinct notes and tags. ReleaseKit runs one `go test -mod=readonly -count=1 ./...` suite from the selected module directory with the available compatible local Go toolchain. @@ -49,20 +50,22 @@ complete target pair after tests and vet. Package compilation uses failures use the `package-compile` identity and include the target. The zero values retain the ordinary native test behavior and select no compilation. Set `Validation.GoFormat` to check committed regular Go files using the Go -formatter built into ReleaseKit. It includes vendor and nested-module source, +formatter built into ReleaseKit. It uses the selected file inputs, including +vendor and explicit shared files, and ignores symlink blobs and worktree changes, and reports unformatted paths as `go-format` without rewriting files. Its zero value disables the check; it runs after tests, selected vet, and package compilation, before `AdditionalChecks`. Set `Validation.ModuleDistribution.WorkspaceFiles` to reject committed `go.work` and `go.work.sum` files in the selected module inputs, including -nested and symlink entries. It examines the captured candidate even when +symlink entries. It examines the captured candidate even when `GOWORK=off`, ignores uncommitted files, and does not change Go test workspace selection; vendored contents remain in scope. The zero value disables the check; failures use `workspace-files`. Set `Validation.ModuleDistribution.LocalReplacements` independently to parse the selected module's committed `go.mod` declarations. Vendored contents remain -in scope, while independently released nested modules are excluded. It reports +in scope; automatic inputs stop at independently released nested modules. An +explicit shared-file selection can include another module's declaration. It reports filesystem `replace` directives with their source path, line, and target as `local-replacements`; versioned replacements are permitted. Committed module symlinks are resolved within the candidate. Parse @@ -103,6 +106,12 @@ Explicit files replace those defaults, must exist even when file checks are disabled, and may be in another module. Combined inputs are deduplicated by repository-relative path. +Automatic file inputs stop at independent nested-module boundaries, including +fixture modules. Vendored files remain included. Shared selection affects file +inputs only; Go validation retains the selected module's scope. Reference reads +can inspect destinations elsewhere in the captured repository without adding +those destinations to the input set. + It does not download a different toolchain automatically. If race prerequisites are unavailable, the `go-test` check fails rather than being skipped; a selected full-vet failure is reported as `go-vet`. The suite uses the Go host target, @@ -123,10 +132,11 @@ commands from `releasekit.json`. ## Publishing the source tag `releasekit.Publish` uses the same request and validation order: the standard -suite runs first, followed by `AdditionalChecks` when supplied. It then performs -authoritative remote checks, annotated-tag creation, and an exact tag push. The +suite runs first, followed by `AdditionalChecks` when supplied. It surrounds +validation with authoritative remote guards before annotated-tag creation and +an exact tag push. The selected remote must publish `main` at the captured commit and must not already -contain the selected version tag. A successful result includes the endpoint and +contain the selected complete tag. A successful result includes the endpoint and tag object ID. Publication states distinguish an unattempted push, a tag that was created locally but not pushed, a successful push, a guard conflict, and an unresolved push error. See the [publication guide](publish.md) for the complete diff --git a/docs/consumers/publish.md b/docs/consumers/publish.md index 5b5ca9c..3cbe077 100644 --- a/docs/consumers/publish.md +++ b/docs/consumers/publish.md @@ -14,7 +14,7 @@ result, err := releasekit.Publish(ctx, releasekit.ReleaseRequest{ Go: releasekit.GoValidationSpec{Race: true, FullVet: true}, }, AdditionalChecks: func(ctx context.Context, candidate releasekit.Candidate) error { - return runProjectChecks(ctx, candidate.RepositoryDir) + return runProjectChecks(ctx, candidate.ModuleDir) }, }) if err != nil { @@ -63,21 +63,23 @@ does not execute target binaries. A failure is reported as `package-compile` with the selected target and prevents tag creation. Set `Validation.GoFormat` to check committed regular Go source using the Go -formatter built into ReleaseKit. It includes vendor and nested modules, ignores +formatter built into ReleaseKit. It uses the selected file inputs, including +vendor and explicit shared files, and ignores worktree changes and symlink blobs, and reports unformatted paths as `go-format` without changing files. The default is disabled. The check follows tests, selected vet, and package compilation, and a failure stops publication before product checks or tag creation. Set `Validation.ModuleDistribution.WorkspaceFiles` to reject committed -`go.work` and `go.work.sum` blobs, including nested paths and symlink entries. +`go.work` and `go.work.sum` blobs in the selected inputs, including symlink entries. The rule reads the captured candidate regardless of `GOWORK`; uncommitted files are ignored, and Go workspace selection and vendor behavior are unchanged. Its zero value disables the check. Findings use `workspace-files` and stop publication before product checks or tag creation. Set `Validation.ModuleDistribution.LocalReplacements` independently to parse selected module's committed `go.mod` declarations. Vendored contents remain in -scope, while independently released nested modules are excluded. Filesystem +scope; automatic inputs stop at independently released nested modules. Explicit +shared files can include another module's declaration. Filesystem `replace` directives are reported with their source path, line, and target as `local-replacements`; versioned replacements are permitted. Committed module symlinks are resolved within the candidate, and diff --git a/docs/integrations/gitea.md b/docs/integrations/gitea.md index 06202c2..da5cb78 100644 --- a/docs/integrations/gitea.md +++ b/docs/integrations/gitea.md @@ -22,10 +22,12 @@ declared module stored at `integrations/core` derives the same tag. ReleaseKit removes a final physical `/v2` directory from the tag prefix only when the module declaration has that `/v2` suffix. A module-local note stays at `/docs/releases/.md`, including a physical `/v2` directory. -Shared license files remain at the repository root. Use the complete derived -tag as the immutable source ref in note links, with paths rooted at the -repository; license footer links target the root `COPYRIGHT`, `LICENSE`, and -`docs/oss/attribution.md` files. The client first reads +The default shared validation convention uses repository-root `COPYRIGHT`, +`LICENSE`, and `docs/oss/attribution.md` when present. Consumers own their license +layout and release-note links. Use the complete derived tag as the immutable +source ref and the actual repository-relative file paths in those links. +Shared-file selection controls validation inputs; delivery preserves the +committed note and its footer links. The client first reads `/api/v1/repos/{owner}/{repo}/tags/{tag}` and requires the hosted tag's commit SHA to equal the captured source commit. It then reads `/api/v1/repos/{owner}/{repo}/releases/tags/{tag}`. A matching existing page diff --git a/docs/internal/gotool.md b/docs/internal/gotool.md index 645a4ee..405dd0a 100644 --- a/docs/internal/gotool.md +++ b/docs/internal/gotool.md @@ -54,8 +54,10 @@ file. The operation-local owner snapshots the inherited environment and selected settings file. It reuses the resolved tool across validation and its following -build callback while those inputs match, and rediscovers after a consumer -callback changes either input. It does not cache settings across operations. +build callback while those inputs match. Subsequent Go acquisition rediscovers +settings when a consumer callback changes either input. An unavailable snapshot +disables reuse while discovery follows the Go tool's accepted configuration. +Ownership is operation-local. Configuration discovery parses JSON from stdout. Stderr is captured separately and included in command-failure diagnostics, so a successful query can emit diff --git a/docs/internal/validation.md b/docs/internal/validation.md index f8e6fbd..81e4d45 100644 --- a/docs/internal/validation.md +++ b/docs/internal/validation.md @@ -21,7 +21,8 @@ selected target where applicable, and underlying causes. Its request carries the captured repository directory and commit, output writer, and internal settings. When selected, the Go-format check loads the candidate tree once, reads regular Go blobs from the captured commit, and compares them -with go/format output. It includes vendor and nested-module files, skips +with go/format output. It uses the selected inputs, including vendor and explicit +shared files, and skips symlink blobs, reports all unformatted paths, and stops with a contextual cause on parse or inspection errors. It runs before product checks and build callbacks. `Request.ReadCandidateTree` lets selected file checks request candidate @@ -30,7 +31,7 @@ contents; the Go-only path does not enumerate the tree. ## Selected validation inputs `CandidateTree` keeps the full committed repository lookup separate from the -ordered file input set. The selected module's committed regular-file inputs +ordered file input set. The selected module's committed inputs exclude independently released nested modules, while vendored contents stay in scope. Selection indexes boundary directories once and checks each entry's ancestors, so unrelated boundaries are not scanned for each file. The @@ -48,8 +49,8 @@ The workspace-file check uses that same candidate inventory and reports blob entries named go.work or go.work.sum, including nested paths and symlink blobs. It does not read workspace contents or depend on the workspace selected for Go commands. -The local-replacement check parses every committed go.mod blob with -`golang.org/x/mod/modfile`, including nested modules and vendor declarations. +The local-replacement check parses selected go.mod blobs with +`golang.org/x/mod/modfile`, including vendor and explicitly shared declarations. It follows committed symlink declarations through the captured tree and fails with an inspection cause when their selected contents are unavailable. A replacement with no parsed version is reported with its go.mod path, line, @@ -167,7 +168,8 @@ directories, missing paths, checkout boundaries, submodule paths, and symlink cycles; the caller selects which observations fail validation or are reported as out of scope. -Resolution walks committed components and symlink targets in order. Active +The shared Git path resolver walks committed components and symlink targets +in order using the tree's indexed metadata and lazy symlink reader. Active symlink expansion detects cycles, and traversal honors cancellation. Absolute destinations and symlink targets within the repository directory map back to candidate-relative paths; existence still comes from committed entries. diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md index fccbe68..53fa0a8 100644 --- a/docs/roadmap/implementation.md +++ b/docs/roadmap/implementation.md @@ -2,6 +2,10 @@ Status: complete; all 15 stages implemented and locally verified. +The subsequent [remediation review](remediation.md) records post-implementation +findings, corrections, and their verification. The baseline and stage accounts +below retain the implementation sequence. + ## Objective and authority Implement the complete target in the [module-release roadmap](module-releases.md), diff --git a/docs/roadmap/module-releases.md b/docs/roadmap/module-releases.md index 374fa6f..d9684a4 100644 --- a/docs/roadmap/module-releases.md +++ b/docs/roadmap/module-releases.md @@ -1,6 +1,7 @@ # Roadmap: release individual Go modules -Status: planned feature; scope and ownership decisions resolved. +Status: implemented; post-implementation findings and corrections are recorded +in the [remediation review](remediation.md). Release version remains unselected. ## Purpose @@ -10,14 +11,16 @@ ReleaseKit's API and CLI. CommandKit's core and optional integrations provide th consumer case. Each invocation should require only module selection, product settings, and a semantic version, with ReleaseKit owning the common mechanics. -This roadmap defines the target state and its scope and ownership decisions. -The [implementation plan](implementation.md) owns the ordered work from the -current baseline. This roadmap does not select a ReleaseKit release version. +This roadmap records the feature's target and resolved scope and ownership +decisions. The [implementation plan](implementation.md) records the completed +stages; [remediation](remediation.md) records review corrections. Current behavior +belongs in the [consumer guides](../consumers/), [CLI](../cli.md), +[configuration](../config.md), and facade GoDoc. -## Current baseline +## Historical starting baseline -The baseline is ReleaseKit v0.3.0 plus accepted ADR 0005; module selection is -not implemented. +Work started from ReleaseKit v0.3.0 plus accepted ADR 0005. At that starting +point, module selection was unimplemented and the following baseline applied. - `ReleaseRequest` selects a repository, product, and version. `Candidate` and `PublicationResult` expose the version without a distinct module or tag name. @@ -33,9 +36,9 @@ not implemented. consumer Woodpecker template selects `refs/tags/v*` and bootstraps ReleaseKit from repository-root module files. -The existing candidate capture, declarative validation, exact-object publication, -and outcome reporting provide the foundation. Scope and identity need to be -carried through those paths together. +Candidate capture, declarative validation, exact-object publication, and outcome +reporting provided the foundation for carrying scope and identity through all +operations. ## Targeted end state diff --git a/docs/roadmap/remediation.md b/docs/roadmap/remediation.md index 98606e6..bcd287c 100644 --- a/docs/roadmap/remediation.md +++ b/docs/roadmap/remediation.md @@ -1,7 +1,7 @@ # Remediation: module release implementation review -Status: open findings from review of `90559fe`, compared with planning baseline -`dbfae9e`. +Status: complete; all eleven findings addressed and verified. The review examined +`90559fe`, compared with planning baseline `dbfae9e`. ## Scope and evidence @@ -20,7 +20,7 @@ bare repository. No ReleaseKit source or real release refs were changed. Each issue describes required work and verification. Preserve the selected scope, existing error causes, publication/delivery outcomes, facade boundaries, and clean API cutover. These corrections add no release, live-service, or human -review gates. Add focused completion markers as issues are resolved. +review gates. Each completion record describes the correction and verification. ## Issue 1: Resolve the actual Git repository root before release identity (P1) @@ -366,7 +366,18 @@ or new validation policies. ## Issue 11: Reconcile documentation with implemented scope and status (P3) -Status: open. Category: incomplete documentation adoption and misleading contracts. +Status: complete. Category: incomplete documentation adoption and misleading contracts. + +**Completion:** Facade GoDoc and canonical API, CLI, configuration, Gitea, and +internal guidance describe selected inputs, full-tag uniqueness, module-local +notes, shared-file scope, committed references, and lazy Go reuse consistently. +The feature roadmap identifies its historical baseline and completed stages, +with this review recording the corrections. Consumer-owned license layouts and +note links are distinguished from optional validation defaults. ReleaseKit's +root release policy and procedure retain their existing requirements. Reviewed +root/nested examples, verified local links/fragments across 37 Markdown documents, +checked example JSON/shell syntax and whitespace, and passed the final complete +offline suite and compiled API/dependency checks. **Evidence:**