# 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. Committed-tree metadata and blob reads disable lazy fetching and Git transports for those child commands. Missing local objects produce inspection errors; source preparation retains its separate network-capable operations. See Git's [lazy-fetch controls](https://git-scm.com/docs/git) for the command mechanism. Public validation errors convert their diagnostic fields to the internal failure model for shared formatting. Converted failures retain their original contextual cause and reuse its rendering when it already contains the same diagnostics. The CLI presents the complete error chain, including candidate context around callback-supplied diagnostics. ## 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. Resolution walks committed components and symlink targets in order. 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. 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.