# Local candidate check Use `releasekit.Check` to verify a candidate against the current local repository state: ```go result, err := releasekit.Check(ctx, releasekit.ReleaseRequest{ RepositoryDir: "/work/project", Product: "Example", Version: "v1.2.3", Validation: releasekit.ValidationSpec{ Go: releasekit.GoValidationSpec{Race: true, FullVet: true}, }, AdditionalChecks: func(ctx context.Context, candidate releasekit.Candidate) error { return runProjectChecks(ctx, candidate.RepositoryDir) }, }) if err != nil { return err } fmt.Println(result.Version, result.Commit) ``` 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 product name and exact version as complete title elements. No local tag with that version may already exist. ReleaseKit runs one `go test -mod=readonly -count=1 ./...` suite with the available compatible local Go toolchain. Set `Validation.Go.Race` to run that suite with `-race`; set `Validation.Go.FullVet` to run `go vet -mod=readonly ./...` after successful tests, with test-time vet disabled for the suite. Set `Validation.Go.CompileTargets` to compile packages for each complete target pair after tests and vet. Package compilation uses `CGO_ENABLED=0`, writes no artifact, and does not execute a target binary; its 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, 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` blobs, including nested and symlink entries. It examines the captured candidate even when `GOWORK=off`, ignores uncommitted files, and does not change Go test workspace selection or vendor behavior. The zero value disables the check; failures use `workspace-files`. Set `Validation.ModuleDistribution.LocalReplacements` independently to parse committed `go.mod` declarations throughout the candidate, including nested and vendor modules. 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 and inspection errors retain their causes, and the rule applies even when `GOWORK=off`. Its zero value disables the check. Set `Validation.FileSize` to check each committed blob against a byte limit. Nil disables the check; an empty object enables the default of 1,000,000 decimal bytes. `LimitBytes` is strict greater-than, accepts zero, and rejects negative values. `Exclusions` contains literal repository-relative files or directories; excluded directories include descendants. Symlink blobs are measured by link-text bytes, and gitlinks are omitted. The check applies to the captured candidate and reports one oversized file with its measurement as `file-size`; it does not measure historical or aggregate size. Set `Validation.Markdown` to check committed local Markdown destinations and supported heading fragments. Nil disables the check; an empty object enables it with outside-checkout destinations reported as out of scope. Set `EnforceCheckoutBoundary` to fail outside-checkout links. Submodule contents remain out of scope under either setting. The checker runs after file-size inspection and before `AdditionalChecks`; its nonfailure observations use the request's output writer. Markdown failures use the `markdown-links` identity and include the source location and destination. Use these selections for ReleaseKit-owned validation rather than repeating the standard suite, selected vet/format/distribution checks, or Markdown navigation checks in `AdditionalChecks` or profile `checks`. Keep release-note rules and consumer-specific assertions—such as tests of maintained examples—in those product-owned checks. ReleaseKit calls `AdditionalChecks` once after shared validation when supplied. 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, disables workspace and module network access, and ignores ambient `GOFLAGS`, experiment, and CPU feature overrides. Effective cache and native cgo/C-tool settings are preserved, including values from Go's persistent environment file. The check revalidates the branch, commit, and cleanliness after validation. For checksum failures during dependency preparation, use the [module checksum investigation guide](delivery.md#investigating-module-checksum-mismatches). A successful check is evidence about the local candidate only. It does not check whether a remote branch or tag is available and does not create a tag. The [`check` command](../cli.md) reads the product and optional additional 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 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 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 workflow. When a push reports an error, ReleaseKit makes one bounded query for the authoritative tag. An exact tag object match confirms success. An absent tag is reported as `not_published`, a different object as `conflict`, and an unreadable query as `unknown`. The local annotated tag is retained in every case; an `unknown` result is neither success nor proof that the remote lacks the tag.