check

package
v0.16.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 21, 2026 License: Apache-2.0 Imports: 25 Imported by: 0

Documentation

Overview

Package check holds the check verb's body and the verb-level check-rule helpers that need git access. The pure-tree rules live in internal/check; this package composes them with history walks (runTestsMetricsCheck, runProvenanceCheck) and renders the final output envelope.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewCmd

func NewCmd() *cobra.Command

NewCmd builds `aiwf check`: validate the consumer repo's planning state. Read-only; produces no commit. The pre-push git hook runs this verb — its findings + exit code are the framework's authoritative correctness gate.

func ParseUntrailedCommits

func ParseUntrailedCommits(s string) []check.UntrailedCommit

ParseUntrailedCommits unpacks the multi-record stream produced by ReadUntrailedCommits. The format is:

<RS>{SHA}<US>{parent SHAs, space-separated}<US>{subject}<US>{trailers}<US>
{file1}
{file2}
...
<RS>{SHA}<US>...

Parents, trailers, and file lists are all whitespace- or newline- delimited. Subject is the commit's first line, used for the squash-merge specialization (G31); parent SHAs feed the merge- commit carveout (G-0231 item 3). Empty input (no unpushed commits) returns nil.

func ReadUntrailedCommits

func ReadUntrailedCommits(ctx context.Context, root, rangeArg string) ([]check.UntrailedCommit, error)

ReadUntrailedCommits returns the commits in rangeArg (e.g. `@{u}..HEAD`, or `<sha>..HEAD` from --since) along with their trailer set and the relative paths each commit touched.

The range is supplied by the caller (ResolveUntrailedRange); ReadUntrailedCommits is purely the git-log invocation + parsing. An empty range (HEAD == @{u}) returns no commits, no findings.

`-m --first-parent` walks the integration-branch view (G32): merge commits surface their introduced changes (against their first parent) so the audit pass sees entity-file paths brought in by `git merge`, while feature-branch commits not on first-parent ancestry are correctly excluded (those are the feature branch's own warning scope, not the integration branch's). Without `-m` the default is "show no diff for merge commits," which silently bypassed the audit for merges that absorbed entity-file changes from a feature branch.

G-0231 item 3 shifts where the merge-vs-direct-edit decision lives: the reader still emits the data (the merge commit's touched paths, its parent SHAs), and RunUntrailedAudit decides to SKIP ordinary `--no-ff` merges based on len(ParentSHAs) > 1 + non-squash subject. The reader stays dumb; the rule decides. Squash-merge commits keep firing because GitHub strips trailers and the squash IS the only audit-trail event on the integration branch. See `internal/check/provenance.go` RunUntrailedAudit for the carveout's predicate and rationale.

func ResolveUntrailedRange

func ResolveUntrailedRange(ctx context.Context, root, since string) (string, *check.Finding, error)

ResolveUntrailedRange picks the `git log` range for the step-7b untrailered-entity audit. Three branches:

  1. since != "" — the operator's explicit choice wins. Validates the ref shape via `git rev-parse --verify`; an unrecognized ref returns a usage-error advisory finding so the audit is still skipped (rather than failing the whole check verb).
  2. else, an upstream is configured — return `@{u}..HEAD`.
  3. else — return ("", advisory) so the caller skips the scan and surfaces the undefined-scope warning.

func Run

func Run(root, format string, pretty bool, since string, shapeOnly, verbose bool, registeredVerbs map[string]struct{}) int

Run is the check verb's body. Loads the tree, runs every rule (pure-tree + provenance + tests-metrics + contracts + tree discipline), applies aiwf.yaml-driven severity bumps, renders the findings in the chosen format, and returns the exit code.

func RunGitConfigCheck added in v0.9.0

func RunGitConfigCheck(ctx context.Context, root string) []check.Finding

RunGitConfigCheck verifies that the local repo's `core.worktree` configuration, if set, resolves to the directory `aiwf` is operating in (the resolved root). A mismatch means every subsequent git operation from this directory is silently redirected against a different working tree — git reports no error, `git status` shows the wrong worktree's files, and `aiwf check` itself loads the wrong tree. The failure is invisible without inspection; this rule is the chokepoint that catches it. G-0155.

Returns no findings in three healthy cases:

  • core.worktree unset (the normal state — `git config --get` exits 1)
  • core.worktree set but resolves to the directory aiwf was invoked from (linked worktrees typically have this set to their own path; that's legitimate)
  • The root or configured path can't be made absolute (don't fire a noisy finding on path-resolution edge cases)

Fires SeverityError otherwise — the misdirection corrupts every subsequent aiwf verb's view of the tree, so the push must block.

func RunProvenanceCheck

func RunProvenanceCheck(ctx context.Context, root string, t *tree.Tree, since string, registeredVerbs map[string]struct{}, ackedSHAs map[string]bool, ackedSHAEntities map[string]map[string]bool, postCutoffSHAs map[string]bool) ([]check.Finding, error)

RunProvenanceCheck walks every commit reachable from HEAD that carries any `aiwf-*` trailer and runs the I2.5 standing rules against the result. It also runs the step-7b untrailered-entity- commit warning, scoped per the rules in ResolveUntrailedRange:

  • --since <ref> on the verb wins.
  • Otherwise `@{u}..HEAD` when an upstream is configured.
  • Otherwise the audit is SKIPPED with a single `provenance-untrailered-scope-undefined` advisory; the fallback used to be "all of HEAD," which on long-lived branches floods with warnings against commits already merged in from trunk. See issue #5 sub-item 2.

Returns a single concatenated finding slice; transport errors propagate.

Why grep on `^aiwf-` for the standing rules: every rule is keyed on at least one aiwf trailer (actor, principal, scope-ends, etc.). Untrailered commits are handled by the separate step-7b audit pass, which uses a different filter (range scoped per ResolveUntrailedRange, no trailer grep).

M-0159/AC-3: ackedSHAs is the gather-layer-computed map of retroactively-acknowledged commit SHAs (via check.WalkAcknowledgedSHAs called once at check.go::Run). Passed through to three rules that consume it from this gather (check.RunIsolationEscape, check.RunTrailerVerbUnknown, check.RunIDRenameUntrailered — the third added at M-0160/AC-4); the fourth consumer (check.FSMHistoryConsistent) is called directly from check.go::Run with the same map.

G-0218 Patch 2: postCutoffSHAs is the gather-layer-computed map of commit SHAs that descend from check.HookInstallSHA (via check.WalkPostCutoffSHAs called once at check.go::Run). Mirrors the ackedSHAs pattern — single-compute, cascading pass-through. The map drives the trailer-verb-unknown rule's severity decision (post-cutoff → SeverityError; pre-cutoff or nil-map fallback → SeverityWarning per the G-0150 baseline). Threaded as a parameter rather than computed inside this function so seam tests can pin the rule's severity transition against fixture cutoffs (the production HookInstallSHA points at a specific main-branch commit that fresh-fixture repos don't carry).

func RunTestsMetricsCheck

func RunTestsMetricsCheck(ctx context.Context, root string, t *tree.Tree, require bool) ([]check.Finding, error)

RunTestsMetricsCheck emits an `acs-tdd-tests-missing` warning for every AC at `tdd_phase: done` under a `tdd: required` milestone whose `aiwf history` carries no `aiwf-tests:` trailer on any commit. Gated on require: when false (the default), returns nil without walking history — the trailer is informational metadata and absence is not a finding.

Why the check lives here rather than in package check: the rule requires git access (a history walk per qualifying AC) which the pure-tree check.Run intentionally does not have. Composing this pass in the check verb's package keeps the rule's runtime cost scoped to invocations that opt in via aiwf.yaml.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL