// tools/guardrails.mjs - lines 106-108 const tracked = execFileSync("git", ["ls-files", "-z"], { cwd: root, encoding: "utf8" }) .split("\0") .filter(Boolean) A new file is covered when it is added, not when somebody remembers to list it.
"the gate has to derive what to check from the project graph. An enumerated
target list is a list, and lists get edited by whoever is editing them."Source:
tools/guardrails.manifest.json, the "why" of the second assertion
3. A check that cannot fail for the right reason is not a check
If it passes on malformed input, it is not asserting the property it appears
to, and the reader of the green build is misled.
That sentence cost the corpus three checks to learn: "A check has to fail for
the right reason before it is trusted." (ADR 0015 lines 38-42.)
Beyond this codebase: a check that skips what it cannot read is not lenient. It
has stopped reading, and it reports success about a file it never opened.
Starting Monday
Seven things, in order.
- Write down what you are protecting, and hash it. The day it is created, not after you notice it missing.
- Turn each removal into a recorded removal. A path and a reason, printed on every run. An unexplained absence reads as an oversight; a recorded exclusion reads as judgement.
- Derive the checks from the project graph. A project with no tags has no boundary; make the missing tag a failure, not a skip.
- State scope as paths, not as principles. "Stay inside the brief" is a sentiment; a named path is a check. Nothing in this corpus enforces scope, so the mechanical version must be written.
- Flip rules instead of deleting them. A rule with a direction survives the decision changing. A rule that can only say no must be rewritten whenever the decision changes, and rewriting a rule is what an agent can do in the same commit as the thing the rule forbids.
- Put the negative case in the contract. If a file cannot be parsed, that is a failure, not a skip.
- Fewer agents on one repository. Concurrency is the multiplier on every ambiguity in the rulebook. F2 needed four agents on one task to produce four implementations of a feature the platform already ships; F1 needed one agent and one commit.
Reproducing it
Everything in this post is reproducible from two public repositories.
The corpus: https://github.com/effinrich/h2-fe-assessment, pinned to
commit b200e23.
git clone https://github.com/effinrich/h2-fe-assessment cd h2-fe-assessment git checkout b200e23 bun run budget bun run guardrails 