Documentation
¶
Overview ¶
Package quality runs read-only coverage and verification checks for a local repository fleet. It deliberately reports every selected repository instead of stopping at the first failure, so people and AI agents can act on one complete index.
Index ¶
- Constants
- Variables
- func EvaluateRatchet(blocks []CoverageBlock, changed ChangedLines, touchedFiles map[string]bool, ...) ([]PackageRatchet, []RatchetWarning)
- func FormatDeadcodeBaseline(findings []DeadcodeFinding) string
- func GitLineOffsets(ctx context.Context, repoRoot, mergeBase string) (map[string]FileLineOffsets, error)
- func GitTouchedFiles(ctx context.Context, repoRoot, mergeBase string) (map[string]bool, error)
- func LoadDeadcodeBaseline(path string) (entries map[string]bool, missing bool, err error)
- func PackageOf(file, modulePath string) string
- func PackageUncoveredCounts(blocks []CoverageBlock, modulePath string) map[string]int
- func ReadModulePath(moduleRoot string) (string, error)
- func SaveValidationCache(cacheRoot string, key ValidationCacheKey, report VerificationReport) error
- func SingleWorkerNodeEnv() []string
- func SortVerificationReports(reports []VerificationReport)
- func ValidateBaseline(baseline PackageBaseline, expectedSHA string) error
- func ValidationCacheDir(root string) string
- func WriteBaseline(path string, baseline PackageBaseline) error
- func WriteDeadcodeBaseline(path string, findings []DeadcodeFinding) error
- type ChangedLines
- type Check
- type CoverageBlock
- type CoverageDiagnostic
- type CoverageDiagnosticFile
- type CoverageDiagnosticManifest
- type CoverageReport
- type DeadcodeFinding
- type DeadcodeOptions
- type DeadcodeReport
- type FileLineOffsets
- type ModuleCoverage
- type PackageBaseline
- type PackageRatchet
- type Progress
- type ProgressState
- type RatchetFinding
- type RatchetWarning
- type RepositoryCoverage
- type RunOptions
- type Status
- type UncoveredBlock
- type ValidationCacheKey
- type VerificationEntry
- type VerificationReport
- func LoadValidationCache(cacheRoot string, key ValidationCacheKey) (VerificationReport, bool, error)
- func Verify(ctx context.Context, repository, path string, checks []Check) VerificationReport
- func VerifyWithOptions(ctx context.Context, repository, path string, checks []Check, ...) VerificationReport
Constants ¶
const ( // ReasonChangedStatementUncovered is a statement the diff itself adds or // modifies, found via GitChangedLines. ReasonChangedStatementUncovered = "added or changed statement is not covered by a test" // ReasonNewlyUncoveredAtBase is a statement the diff does not touch at // all, found only because the package's uncovered count rose (review // B2): it was covered when baseline was measured and is not now. ReasonNewlyUncoveredAtBase = "newly uncovered (was covered at base)" )
Ratchet finding/warning reasons (review-696 non-blocking #4): a genuinely added or changed line and a pre-existing statement whose *coverage* changed are different situations and must read differently, since the first names something the diff shows and the second does not.
const DefaultDeadcodeBaseline = ".wb/deadcode-baseline.txt"
DefaultDeadcodeBaseline is the repository-relative baseline path. It sits beside .wb/quality.yaml because it is repository-owned policy, reviewed in the pull request that changes it, not machine state.
Variables ¶
var DefaultDeadcodeTool = []string{"go", "run", "golang.org/x/tools/cmd/deadcode@v0.50.0"}
DefaultDeadcodeTool pins the analyzer the way .wb/quality.yaml pins golangci-lint: an unpinned analyzer silently changes the gate's verdict between runs, which is the one thing a ratchet must never do.
Functions ¶
func EvaluateRatchet ¶ added in v0.164.0
func EvaluateRatchet(blocks []CoverageBlock, changed ChangedLines, touchedFiles map[string]bool, lineOffsets map[string]FileLineOffsets, baseline PackageBaseline, modulePath string) ([]PackageRatchet, []RatchetWarning)
EvaluateRatchet applies the per-change coverage ratchet (spec/plans/coverage-to-100/README.md task-3, founder decisions 11 and 12): a package the PR changes fails when its uncovered-statement count rises against baseline, or when a changed, non-moved line is uncovered anywhere. A package the PR does not change only ever warns on a count rise — touchedFiles (repository-relative paths, including files the diff only deletes lines from, deletes entirely, or a rename's old AND new path) decides package ownership; a changed package with no baseline entry at all is treated as a baseline of 0 (review-696 blocking #2: the merge-base measurement covers every package that existed then, so a missing entry means the package did not exist, not that it is exempt).
Attributing a count-only rise to an exact statement (uncoveredBlockKey against baseline.UncoveredBlocks) can land on a block inside a file the PR itself touched: editing a file shifts every later line's position, so the baseline's raw stored position there does not directly compare. Set lineOffsets (from GitLineOffsets) maps each baseline block's stored line through that file's own diff hunks to its current line first: a current block landing on that mapped line is the same pre-existing statement, just shifted, not new (review-696 non-blocking #3) — pass nil to skip this mapping entirely, which means no touched-file block can be matched to a shifted baseline position, so every uncovered block in a touched file is reported as attributable (the original, pre-5a7d0df6 behavior, before the blanket touched-file skip existed — this is the LEAST conservative option, not a conservative one).
func FormatDeadcodeBaseline ¶ added in v0.137.0
func FormatDeadcodeBaseline(findings []DeadcodeFinding) string
FormatDeadcodeBaseline renders findings as a baseline file. Entries are sorted and one per line so that a diff of this file reviews as a list of mechanisms that lost or gained a caller.
func GitLineOffsets ¶ added in v0.164.0
func GitLineOffsets(ctx context.Context, repoRoot, mergeBase string) (map[string]FileLineOffsets, error)
GitLineOffsets computes FileLineOffsets for every file a diff against mergeBase touches (review-696 non-blocking #3). --no-renames matches GitTouchedFiles: a rename is a plain delete-then-add pair, so its old path's hunks (an entire "delete everything") never falsely offset the new path's line numbers.
func GitTouchedFiles ¶ added in v0.164.0
GitTouchedFiles reports every repository-relative file path a diff touches against mergeBase — added, modified, deleted, or renamed — independent of whether the diff added any line at all. A pure deletion (for example removing a test function) never appears in ChangedLines (it added no line), but it must still count as "the PR changed this package" (founder decision 2026-09-23, review B1): the caller uses this, not ChangedLines, to decide per-package ratchet ownership.
func LoadDeadcodeBaseline ¶ added in v0.137.0
LoadDeadcodeBaseline reads a baseline file. A missing file is not an error: it reports every finding as new, which is what a repository adopting the gate should see before it records its starting point.
func PackageOf ¶ added in v0.164.0
PackageOf maps a coverage profile's module-qualified file path (for example "github.com/sneat-dev/wb/internal/quality/ratchet.go") to the package directory relative to the module root ("internal/quality"). modulePath is the module declaration from go.mod (for example "github.com/sneat-dev/wb"); the module root package itself maps to ".".
func PackageUncoveredCounts ¶ added in v0.164.0
func PackageUncoveredCounts(blocks []CoverageBlock, modulePath string) map[string]int
PackageUncoveredCounts sums the uncovered statement count per package.
func ReadModulePath ¶ added in v0.164.0
func SaveValidationCache ¶ added in v0.98.3
func SaveValidationCache(cacheRoot string, key ValidationCacheKey, report VerificationReport) error
SaveValidationCache writes terminal evidence atomically. Failed writes are returned to the caller; a cache failure never changes validation semantics.
func SingleWorkerNodeEnv ¶ added in v0.88.0
func SingleWorkerNodeEnv() []string
SingleWorkerNodeEnv is the environment a single-worker Node run must carry. It is exported so a caller that composes its own command still states the same environment the profile does.
func SortVerificationReports ¶
func SortVerificationReports(reports []VerificationReport)
SortVerificationReports orders reports for deterministic output.
func ValidateBaseline ¶ added in v0.164.0
func ValidateBaseline(baseline PackageBaseline, expectedSHA string) error
ValidateBaseline reports whether baseline is usable against expectedSHA. A wrong schema version, an empty package map, or (when expectedSHA is non-empty) a SHA that does not match expectedSHA each make the baseline unusable: EvaluateRatchet treats a package missing from Packages as having no baseline and passes the count rule for it by design, so a baseline that silently lost its contents (an empty `{}` artifact, a schema drift, or one published for the wrong commit) would otherwise disable the per-package count rule for every package without failing anything (spec/plans/coverage-to-100/README.md task-3(b)). Callers must treat a non-nil error as "this baseline cannot be trusted", not "no baseline available" — the caller falls back to measuring the merge base directly, or fails loudly, either way never using the untrusted baseline as-is.
func ValidationCacheDir ¶ added in v0.98.3
ValidationCacheDir is kept in one place so all merge baseline callers share the same private WB state and tests can replace it without touching a user repository.
func WriteBaseline ¶ added in v0.164.0
func WriteBaseline(path string, baseline PackageBaseline) error
WriteBaseline writes baseline as deterministic, indented JSON.
func WriteDeadcodeBaseline ¶ added in v0.137.0
func WriteDeadcodeBaseline(path string, findings []DeadcodeFinding) error
WriteDeadcodeBaseline records findings as the new tolerated set.
Types ¶
type ChangedLines ¶ added in v0.164.0
ChangedLines is the set of new-file line numbers a diff added or modified against a merge base, excluding lines git identifies as moved-but-unmodified (spec/plans/coverage-to-100/README.md task-3(a)). Keys are file paths relative to the repository root, matching `git diff`'s `b/<path>` spelling.
func GitChangedLines ¶ added in v0.164.0
func GitChangedLines(ctx context.Context, repoRoot, mergeBase string) (ChangedLines, error)
GitChangedLines computes ChangedLines for repoRoot against mergeBase, running `git diff --merge-base <mergeBase> -U0 --color-moved=plain` with explicit color assignments so moved lines are distinguishable from plain additions regardless of the caller's git config.
type Check ¶
type Check string
Check selects a conventional verification class.
func ParseChecks ¶
ParseChecks validates the explicit --checks list. A missing list defaults to the conventional lint, test, build sequence.
type CoverageBlock ¶ added in v0.164.0
type CoverageBlock struct {
File string
StartLine int
StartCol int
EndLine int
EndCol int
Statements int
Count int
}
CoverageBlock is one statement-range entry from a Go coverage profile (`go test -coverprofile`). Count is the number of times the profiled binary executed every statement in the block; Count == 0 means the block is uncovered.
func ParseCoverageProfile ¶ added in v0.164.0
func ParseCoverageProfile(profilePath string) ([]CoverageBlock, error)
ParseCoverageProfile reads a Go coverage profile (`mode: ...` header followed by `file:startLine.startCol,endLine.endCol numStmt count` rows) into its constituent blocks, preserving line ranges that profileTotals collapses into a single aggregate.
type CoverageDiagnostic ¶ added in v0.67.9
type CoverageDiagnostic struct {
Manifest string `yaml:"manifest" json:"manifest"`
SHA256 string `yaml:"sha256" json:"sha256"`
}
CoverageDiagnostic points at the private manifest containing lossless raw output for failed coverage jobs.
type CoverageDiagnosticFile ¶ added in v0.67.9
type CoverageDiagnosticManifest ¶ added in v0.67.9
type CoverageDiagnosticManifest struct {
SchemaVersion int `yaml:"schema_version" json:"schema_version"`
Repository string `yaml:"repository" json:"repository"`
Module string `yaml:"module" json:"module"`
// Ambient names the machine-state signals present in the gate's own
// environment and in the ancestors of TMPDIR and Module when the shard
// failures below were recorded. Empty when none were observed.
Ambient envguard.AmbientInputs `yaml:"ambient,omitempty" json:"ambient,omitempty"`
Files []CoverageDiagnosticFile `yaml:"files" json:"files"`
}
CoverageDiagnosticManifest is intentionally separate from CoverageReport: it contains unbounded command output and therefore stays in the private report root rather than crossing the bounded hook/session boundary.
type CoverageReport ¶
type CoverageReport struct {
SchemaVersion int `yaml:"schema_version" json:"schema_version"`
Repositories []RepositoryCoverage `yaml:"repositories" json:"repositories"`
Statements int `yaml:"statements" json:"statements"`
Covered int `yaml:"covered" json:"covered"`
Percentage float64 `yaml:"percentage" json:"percentage"`
}
CoverageReport is a deterministic, machine-readable coverage index.
func NewCoverageReport ¶
func NewCoverageReport(repositories []RepositoryCoverage) CoverageReport
NewCoverageReport aggregates reports in deterministic repository order.
type DeadcodeFinding ¶ added in v0.137.0
type DeadcodeFinding struct {
// Identity is the baseline key: import path + "." + function name. It
// deliberately excludes the source position, so moving a function or
// editing the lines above it does not invalidate the baseline and does not
// silently re-admit a genuinely new finding.
Identity string `yaml:"identity" json:"identity"`
Package string `yaml:"package" json:"package"`
Function string `yaml:"function" json:"function"`
File string `yaml:"file,omitempty" json:"file,omitempty"`
Line int `yaml:"line,omitempty" json:"line,omitempty"`
}
DeadcodeFinding is one unreachable function.
type DeadcodeOptions ¶ added in v0.137.0
type DeadcodeOptions struct {
// Patterns are the main packages to analyze. deadcode only starts from
// executables, so a pattern matching no main package reports nothing.
Patterns []string
// BaselinePath is relative to the repository root when not absolute.
BaselinePath string
// Tool overrides the analyzer invocation; nil uses DefaultDeadcodeTool.
Tool []string
// Filter is deadcode's -filter regular expression. Empty keeps deadcode's
// own default, which reports the module of the first listed package.
Filter string
// IncludeGenerated reports dead functions in generated files too. Off by
// default: generated code is not hand-wired, so its reachability is the
// generator's contract, not this repository's.
IncludeGenerated bool
// Timeout bounds the analyzer. Zero disables the bound.
Timeout time.Duration
}
DeadcodeOptions configures one reachability run.
type DeadcodeReport ¶ added in v0.137.0
type DeadcodeReport struct {
// Findings is every unreachable function found, baselined or not.
Findings []DeadcodeFinding `yaml:"findings" json:"findings"`
// New is the gate: findings absent from the baseline. Non-empty fails.
New []DeadcodeFinding `yaml:"new,omitempty" json:"new,omitempty"`
// Fixed lists baseline entries that are now reachable or gone. They never
// fail the gate; they are what the baseline should shed.
Fixed []string `yaml:"fixed,omitempty" json:"fixed,omitempty"`
// BaselinePath is the file consulted, empty when none was configured.
BaselinePath string `yaml:"baseline_path,omitempty" json:"baseline_path,omitempty"`
// BaselineMissing distinguishes "no baseline file yet" from "empty
// baseline". The first is a repository that has not adopted the gate; the
// second is a repository that has adopted it and is clean.
BaselineMissing bool `yaml:"baseline_missing,omitempty" json:"baseline_missing,omitempty"`
}
DeadcodeReport is the verdict of one run.
func Deadcode ¶ added in v0.137.0
func Deadcode(ctx context.Context, repositoryPath string, options DeadcodeOptions) (DeadcodeReport, error)
Deadcode runs the reachability analysis in repositoryPath and compares it against the configured baseline.
type FileLineOffsets ¶ added in v0.164.0
type FileLineOffsets struct {
// contains filtered or unexported fields
}
FileLineOffsets maps one file's merge-base (old) line numbers to its current (new) line numbers, built from that file's own unified-diff hunks. EvaluateRatchet uses it (review-696 non-blocking #3) to find the current position of a baseline-recorded statement whose file was edited elsewhere, instead of treating every uncovered block in a touched file as unattributable.
func (FileLineOffsets) Map ¶ added in v0.164.0
func (offsets FileLineOffsets) Map(oldLine int) (newLine int, ok bool)
Map translates a merge-base line to its current line. ok is false when oldLine falls inside a hunk's old range: the diff itself touched that exact line, so there is no single current line to point to for it — the direct changed-line rule (GitChangedLines) already covers whatever replaced it.
type ModuleCoverage ¶
type ModuleCoverage struct {
Path string `yaml:"path" json:"path"`
Statements int `yaml:"statements" json:"statements"`
Covered int `yaml:"covered" json:"covered"`
Percentage float64 `yaml:"percentage" json:"percentage"`
Attempts int `yaml:"attempts,omitempty" json:"attempts,omitempty"`
}
ModuleCoverage records the statement totals from one Go module's generated coverage profile.
type PackageBaseline ¶ added in v0.164.0
type PackageBaseline struct {
SchemaVersion int `json:"schema_version"`
SHA string `json:"sha,omitempty"`
Packages map[string]int `json:"packages"`
UncoveredBlocks map[string][]UncoveredBlock `json:"uncovered_blocks,omitempty"`
}
PackageBaseline is the per-package uncovered-statement baseline the ratchet compares against. It has no committed file of its own: go-ci's coverage job publishes it as a build artifact on every push to the default branch (spec/plans/coverage-to-100/README.md task-3(b)). Packages holds each package's uncovered statement count for the rise check; UncoveredBlocks holds the exact uncovered statement ranges behind that count, so a rise can be attributed to specific newly-uncovered statements instead of only reported as a number.
func BaselineFromProfile ¶ added in v0.164.0
func BaselineFromProfile(blocks []CoverageBlock, modulePath, sha string) PackageBaseline
BaselineFromProfile builds a PackageBaseline from a measured coverage profile, for publishing as the baseline artifact.
func ComputeBaselineAtRef ¶ added in v0.164.0
func ComputeBaselineAtRef(ctx context.Context, repoRoot, ref string, timeout time.Duration, options RunOptions) (PackageBaseline, error)
ComputeBaselineAtRef checks out ref into a throwaway git worktree and measures its per-package uncovered-statement counts, for the fallback path when no published baseline artifact exists yet (spec/plans/coverage-to-100/README.md task-3(b)). It is bounded by timeout so a missing artifact cannot make every PR pay for an open-ended run. options carries the same Retry/CoverageDiagnosticsDir a normal `wb coverage` run uses; RepositoryRunOptions is applied to the checked-out worktree so the merge base is measured through the identical .wb/quality.yaml-aware sharded, retried CoverWithOptions runner the head measurement uses (review item 5/non-blocking #1), not a bare `go test`.
func LoadBaseline ¶ added in v0.164.0
func LoadBaseline(path string) (PackageBaseline, error)
LoadBaseline reads a PackageBaseline written by WriteBaseline. A missing file is reported as os.ErrNotExist so callers can distinguish "no baseline available yet" from a malformed one.
type PackageRatchet ¶ added in v0.164.0
type PackageRatchet struct {
Package string
Uncovered int
BaselineUncovered int
HasBaseline bool
Rose bool
Changed bool // true when the PR itself touches a file (including _test.go) in this package
NewlyUncoveredChanged []RatchetFinding
Pass bool
}
PackageRatchet is one package's ratchet verdict.
type Progress ¶ added in v0.50.0
type Progress struct {
Repository string
Language string
Module string
Check Check
Command string
Detail string
State ProgressState
Status Status
Attempts int
Completed int
Total int
}
Progress describes one external check or a completed repository. Repository is filled by the fleet runner, which owns cross-repository scheduling.
type ProgressState ¶ added in v0.50.0
type ProgressState string
ProgressState identifies a visible quality-work transition.
const ( ProgressStarted ProgressState = "started" ProgressRetrying ProgressState = "retrying" ProgressCompleted ProgressState = "completed" ProgressRepositoryCompleted ProgressState = "repository_completed" )
type RatchetFinding ¶ added in v0.164.0
RatchetFinding names one newly uncovered statement that fails the ratchet.
type RatchetWarning ¶ added in v0.164.0
type RatchetWarning struct {
Package string `json:"package"`
File string `json:"file"`
Line int `json:"line"`
Reason string `json:"reason"`
}
RatchetWarning names one newly uncovered statement in a package the PR did not itself change (review B1, founder decision 2026-09-23: "only packages the PR changes" are hard-gated on their uncovered count; every other package's count rise is reported, never failed on).
type RepositoryCoverage ¶
type RepositoryCoverage struct {
Repository string `yaml:"repository" json:"repository"`
Path string `yaml:"path" json:"path"`
Status Status `yaml:"status" json:"status"`
Modules []ModuleCoverage `yaml:"modules,omitempty" json:"modules,omitempty"`
Statements int `yaml:"statements" json:"statements"`
Covered int `yaml:"covered" json:"covered"`
Percentage float64 `yaml:"percentage" json:"percentage"`
Error string `yaml:"error,omitempty" json:"error,omitempty"`
Diagnostic *CoverageDiagnostic `yaml:"diagnostic,omitempty" json:"diagnostic,omitempty"`
}
RepositoryCoverage records aggregate Go coverage for one repository.
func Cover ¶
func Cover(ctx context.Context, repository, path string) RepositoryCoverage
Cover measures all Go modules below path. It creates profiles in the system temporary directory, never in the repository.
func CoverWithOptions ¶
func CoverWithOptions(ctx context.Context, repository, path string, options RunOptions) RepositoryCoverage
CoverWithOptions measures coverage with a deadline and retries for each Go module's test command.
type RunOptions ¶
type RunOptions struct {
Timeout time.Duration
Retry int
// CheckTimeout bounds one logical verification check, including all of its
// command attempts and any process-isolated Go shards. Zero leaves the
// existing per-command Timeout behavior unchanged.
CheckTimeout time.Duration
// ShardAttemptTimeout bounds one process-isolated Go test shard attempt.
// Zero retains Timeout as the shard-attempt bound when Timeout is set.
ShardAttemptTimeout time.Duration
// GoTestShards runs each explicitly named Go package in this many
// process-isolated shards. It is opt-in because TestMain and process-global
// fixtures run once per shard; callers must name packages whose contract
// permits that isolation. Discovery invokes TestMain once before each shard
// process invokes it again.
GoTestShards int
// GoShardPackages are module-relative package patterns such as
// ./internal/worktrees. Packages not named here still run exactly once.
GoShardPackages []string
// GoLintCommands replaces the default `go vet ./...` lint step with the
// repository-owned argv sequences from .wb/quality.yaml. Structured argv
// keeps exact tool pins reproducible without invoking a shell.
GoLintCommands [][]string
// CoverageProfile retains the exact merged Go profile for one module.
// Fleet and multi-module adapters reject it rather than inventing names.
CoverageProfile string
// CoverageDiagnosticsDir retains raw output from failed process-isolated
// coverage jobs beside the durable coverage report. The human-facing error
// remains bounded; this private artifact is the lossless recovery path.
CoverageDiagnosticsDir string
// CoverageDiagnosticsRepository identifies the owning repository in the
// private manifest when a fleet runner executes several repositories.
CoverageDiagnosticsRepository string
// SingleWorker constrains every check to one worker, so a verification
// run cannot exceed the workstation's concurrency cap on its own. Go tests
// gain `-p 1` and never `-race`; package-script Node runs gain
// `--parallel=1` and `--maxWorkers=1`, while mixed Nx target runs gain
// only Nx's executor-neutral `--parallel=1`. The Nx daemon and cache are
// disabled in either case.
//
// Serialization is deliberately *not* a substitute for per-file
// isolation: nothing here relaxes an isolation flag, because a serialized
// leak is worse than a flake — it is reproducible and misattributed.
SingleWorker bool
// Env is appended to each check's environment as KEY=VALUE entries. It is
// how a caller states the environment a run must carry (GOWORK=off,
// NX_DAEMON=false) rather than leaving it to the shell that invoked wb.
Env []string
// Progress receives lifecycle events for external checks. Callers may use it
// for terminal diagnostics; reports remain the authoritative output.
Progress func(Progress)
}
RunOptions bounds a single external command and retries only failed attempts. Zero Timeout disables the per-command deadline.
func RepositoryRunOptions ¶ added in v0.67.1
func RepositoryRunOptions(root string, base RunOptions) (RunOptions, error)
RepositoryRunOptions applies an explicit repository-owned quality policy to one validation run. Absence is the portable default; malformed or ambiguous policy fails closed rather than silently falling back to a slower or weaker command.
type Status ¶
type Status string
Status is the outcome of a repository or a discrete verification command.
type UncoveredBlock ¶ added in v0.164.0
type UncoveredBlock struct {
File string `json:"file"`
StartLine int `json:"start_line"`
StartCol int `json:"start_col"`
EndLine int `json:"end_line"`
EndCol int `json:"end_col"`
}
UncoveredBlock names one uncovered statement range in the baseline, keyed the same way a Go coverage profile line names it, so a later EvaluateRatchet run can tell which of a package's currently-uncovered blocks are new against the baseline and which already existed there (spec/plans/coverage-to-100/README.md task-3, review item B2: a count-only failure must still name file:line).
type ValidationCacheKey ¶ added in v0.98.3
type ValidationCacheKey struct {
Repository string `json:"repository"`
TargetRevision string `json:"target_revision"`
Checks []Check `json:"checks"`
QualityConfigSHA string `json:"quality_config_sha"`
WBRevision string `json:"wb_revision"`
GoToolchain string `json:"go_toolchain"`
ModuleFiles []string `json:"module_files"`
// ValidatorSHAs binds cached evidence to the executable bytes that produced
// it. In particular, SpecScore's rules can change between installed
// versions while the repository and WB revision remain identical.
ValidatorSHAs map[string]string `json:"validator_shas,omitempty"`
}
ValidationCacheKey identifies the exact inputs that make a verification report reusable. Checks remain ordered because the order is part of the command contract and can affect the resulting evidence.
func NewValidationCacheKey ¶ added in v0.98.3
func NewValidationCacheKey(repository, targetRevision, root, wbRevision string, checks []Check, validatorSHAs map[string]string) (ValidationCacheKey, error)
NewValidationCacheKey fingerprints repository-local policy, module manifests, and the executable digests used by external validators. The caller supplies the exact target revision and WB revision, and passes nil validatorSHAs when no external validator participates.
One constructor rather than two: the original signature was kept alongside a WithValidators variant that delegated to it, and `wb deadcode` immediately reported the original as unreachable once the only caller moved. A dead wrapper beside a live near-identical function is a reliable way to have the wrong one called later.
type VerificationEntry ¶
type VerificationEntry struct {
Language string `yaml:"language" json:"language"`
Module string `yaml:"module,omitempty" json:"module,omitempty"`
Check Check `yaml:"check" json:"check"`
Command string `yaml:"command,omitempty" json:"command,omitempty"`
Status Status `yaml:"status" json:"status"`
Detail string `yaml:"detail,omitempty" json:"detail,omitempty"`
Attempts int `yaml:"attempts,omitempty" json:"attempts,omitempty"`
}
VerificationEntry is one command WB attempted or intentionally skipped.
type VerificationReport ¶
type VerificationReport struct {
Repository string `yaml:"repository" json:"repository"`
Path string `yaml:"path" json:"path"`
// Revision and WorkspaceClean are populated by the WB command adapter
// around the complete verification run. They let a downstream receipt bind
// successful mechanisms to the exact clean Git tree they exercised.
Revision string `yaml:"revision,omitempty" json:"revision,omitempty"`
WorkspaceClean bool `yaml:"workspace_clean,omitempty" json:"workspace_clean,omitempty"`
Status Status `yaml:"status" json:"status"`
Results []VerificationEntry `yaml:"results" json:"results"`
}
VerificationReport records all conventional checks applicable to a repository. Unsupported stacks and missing optional Node scripts are skipped rather than treated as failures.
func LoadValidationCache ¶ added in v0.98.3
func LoadValidationCache(cacheRoot string, key ValidationCacheKey) (VerificationReport, bool, error)
LoadValidationCache returns only an intact terminal report with an exact key. Any malformed, stale, or otherwise incomplete record is a cache miss.
func Verify ¶
func Verify(ctx context.Context, repository, path string, checks []Check) VerificationReport
Verify runs the requested conventional Go and Node checks. The caller owns cross-repository parallelism; checks within one module run in the requested order to keep output and failures clear.
func VerifyWithOptions ¶
func VerifyWithOptions(ctx context.Context, repository, path string, checks []Check, options RunOptions) VerificationReport
VerifyWithOptions runs the requested checks with per-command reliability controls. The returned report includes every attempted, skipped, passed, or failed command.