vacuousguard

package
v1.0.13 Latest Latest
Warning

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

Go to latest
Published: Nov 1, 2026 License: Apache-2.0 Imports: 12 Imported by: 0

Documentation

Overview

Package vacuousguard is the repository-wide proof that a green test actually ran something.

A failing test is loud. A test that quietly declines to test is silent, and silence reads as success on every dashboard forge has. Two shapes produce it, and both have already cost this codebase real time:

  • TestProjectWorkflows_* (sibling repo, reliant) skipped itself when a fixture DIRECTORY was missing. A checkout leaves that directory present but EMPTY, so the skip never fired, the loop over its contents ran zero times, and six tests sat hard-red and unwatched. Both halves of that bug are guarded here: a guard that skips instead of failing, and a loop that passes because it never executed.

  • forge's own tree still carries skips conditioned on the presence of files that are tracked in this repository. Those skips cannot fire today, which sounds harmless — it means they are unfalsifiable. Rename the file they stat and the tests do not fail, they evaporate.

THE RULES

vacuous-loop  A test discovers a set from the filesystem (os.ReadDir,
              filepath.Glob, …), ranges over it, and nothing in the test
              proves the set was non-empty. Such a test passes when the
              discovery returns nothing, which is precisely when something
              is wrong.

dead-skip     A t.Skip that is unconditional (a test that can never run),
              or one conditioned on the presence of a REPO-RELATIVE path.
              A file tracked in this repository is present on every
              checkout, so a skip guarding it either never fires — an
              assertion nobody can falsify — or fires because the repo
              layout moved, which must be a failure, not a shrug.

unwritten-gate  An audit category or lint check gates on a generated Go
              file in the user's project, and nothing in forge writes that
              file. The check then returns its PASSING verdict every time,
              on every project, forever. `forge project audit` shipped a
              wire_coverage category and two lint flags reading
              pkg/app/wire_gen.go for months after the DI rewrite stopped
              emitting it; all three were green, and green is what people
              read. Every one of them had passing unit tests — the tests
              fed the scanner synthetic strings, and none asked whether a
              real project could produce the input. The discriminator is
              not "is it tested" but "does anything write the file", so the
              ledger in gates_test.go answers that per path, with the
              emitter named.

WHAT IS DELIBERATELY NOT A RULE

A skip on a missing TOOLCHAIN (kcl, node, dlv, golangci-lint), on testing.Short(), on runtime.GOOS, on an environment opt-in, or on os.UserHomeDir() is legitimate: the thing it guards is genuinely absent on some machines and no checkout can supply it. Those are left alone, on purpose. A rule broad enough to catch them is a rule that gets switched off.

The analysis is a package library rather than a bare test so its rules can be unit-tested against planted defects in testdata/. Nothing in forge's production path imports it.

Index

Constants

View Source
const (
	RuleVacuousLoop = "vacuous-loop"
	RuleDeadSkip    = "dead-skip"
)

Rule names. They double as the stable first half of a ledger key.

View Source
const RuleSilentCapability = "silent-capability"

RuleSilentCapability names the third rule. See checkCapabilityGuards.

View Source
const RuleUnwrittenGate = "unwritten-gate"

RuleUnwrittenGate names the third rule. See ScanGates.

Variables

This section is empty.

Functions

func LookPathProbeFuncs

func LookPathProbeFuncs(root string) ([]string, error)

LookPathProbeFuncs returns the name of every function under root that is a capability probe by CONSTRUCTION: it takes a name, consults exec.LookPath, and answers a bool. Its caller (TestCapabilityProbeSetIsComplete) asserts that every one of them appears in capabilityProbeNames, so the rule cannot go blind because someone spelled the helper differently.

Both test and non-test files are walked: a probe helper that migrates into production code and gets re-used from a test is the same blind spot.

Types

type Finding

type Finding struct {
	Rule   string
	Key    string
	Line   int
	Detail string
}

Finding is one violation, keyed by "<repo-relative file>::<TestFunc>" so a ledger entry survives reformatting and line moves.

func Scan

func Scan(root string) ([]Finding, error)

Scan walks root and returns every finding, sorted by rule then key.

func ScanGateSource

func ScanGateSource(rel string, src []byte) ([]Finding, error)

ScanGateSource applies the unwritten-gate rule to one file's source. ScanGates is this over the judging trees; the guard's own tests are this over planted defects, so the rule under test is the rule that ships.

func ScanGates

func ScanGates(root string) ([]Finding, error)

ScanGates reports every existence-gate, in the judging trees, on a generated-project Go file.

WHY THIS RULE EXISTS. `forge project audit` shipped a `wire_coverage` category that stat'd pkg/app/wire_gen.go and, finding nothing, returned StatusOK with the summary "n/a". Two `forge lint` flags scanned the same ghost. No code path had emitted pkg/app/wire_gen.go since the DI rewrite — forge's own generator test asserts the file is never written — so the category was permanently green, the flags permanently silent, and every dashboard read that as a clean bill of health. The checks had unit tests, and those tests passed: they fed the scanner synthetic strings. What no test asserted was that a real project could ever produce the input.

The discriminator is not "does a test exist" but "does anything WRITE the file". So the rule reports the gates and the ledger in the test answers that question per path, one entry at a time, with the emitter named.

Scoped to paths ending in `.go`: a gate on proto/, db/migrations/ or forge.yaml is reading the USER's tree, which is legitimately absent in projects that have none. A generated Go file is forge's own output, and forge either writes it or is lying about it.

func ScanSource

func ScanSource(rel string, src []byte) ([]Finding, error)

ScanSource applies both rules to a single test file's source. Scan is this over the repository; the guard's own tests are this over a file of planted defects, so the rules under test are the rules that ship.

func (Finding) String

func (f Finding) String() string

Jump to

Keyboard shortcuts

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