Floor guard: reference implementation
Every numbered dimension in CONSTRAINTS.md maps to a de facto tool (Step 4). The floor does not: it is a diff-scoped check for the five moves in Step 6, and without a shipped reference every agent invents its own, so two runs (or a Python repo and a Go one) produce two different guards. That is the exact non-determinism this skill exists to remove.
This is the reference. Adapt the patterns to your stack; keep the contract identical.
Contract
- Input: the diff between the merge base and the working tree (added and removed lines, plus untracked files). A guard that reads only
git diffmisses new files and staged-but-uncommitted work. - Detects the five Step 6 moves: a weakened threshold in
CONSTRAINTS.md, a test made easier (.skip, a deleted test file, an assertion removed from a test that stayed), a silenced checker (a new suppression comment), unfinished work (a stub or emptycatch), a new Exceptions row. - Exit codes:
0clean,1at least one floor violation (block the change),2the guard could not run (no merge base, not a git repo). Never let a2read as a0. - Reports the rule and the location, never the matched secret value. Redaction is not optional (Step 4).
- Tightening is silent, loosening is loud: only surfaces moves that lower the bar.
Reference (Node, ~stack-agnostic patterns)
#!/usr/bin/env node
// floor-guard.mjs — diff-scoped enforcement of the CONSTRAINTS.md floor.
// Usage: node floor-guard.mjs [--base <ref>] (default base: origin/main)
import { execFileSync } from 'node:child_process';
const base = (() => {
const i = process.argv.indexOf('--base');
return i > -1 ? process.argv[i + 1] : 'origin/main';
})();
const git = (args) => {
try { return execFileSync('git', args, { encoding: 'utf8' }); }
catch { return null; }
};
// Merge base; bail to exit 2 rather than pretending a shallow/rootless clone is clean.
const mergeBase = git(['merge-base', base, 'HEAD'])?.trim();
if (!mergeBase) { console.error('floor-guard: no merge base against ' + base); process.exit(2); }
// Unified diff plus untracked files (git diff alone cannot see new files).
const tracked = git(['diff', '--unified=0', mergeBase, '--']) ?? '';
const untracked = (git(['ls-files', '--others', '--exclude-standard']) ?? '')
.split('\n').filter(Boolean)
.map((f) => git(['diff', '--no-index', '--unified=0', '/dev/null', f]) ?? '')
.join('\n');
const diff = tracked + '\n' + untracked;
const added = [], removed = [];
let file = '';
for (const line of diff.split('\n')) {
if (line.startsWith('+++ ')) file = line.slice(6);
else if (line.startsWith('+') && !line.startsWith('+++')) added.push({ file, text: line.slice(1) });
else if (line.startsWith('-') && !line.startsWith('---')) removed.push({ file, text: line.slice(1) });
}
const findings = [];
const flag = (rule, f, text) => findings.push({ rule, file: f, text: text.trim().slice(0, 120) });
// 1. Silenced checker — extend this list for your ecosystem.
const SUPPRESSIONS = /@ts-ignore|@ts-nocheck|eslint-disable|biome-ignore|# *noqa|# *type: *ignore|istanbul ignore|nosemgrep|gitleaks:allow|Stryker disable/;
// 4. Unfinished work.
const STUBS = /throw new (Error|NotImplemented).*[Nn]ot implemented|catch\s*\(\w*\)\s*\{\s*\}|catch\s*\{\s*\}|\bTODO\b|\bpass\s*# *stub/;
// 2. A test made easier (added skips).
const SKIPS = /\.(skip|todo)\b|\bxit\(|\bxdescribe\(|@pytest\.mark\.skip|t\.Skip\(/;
for (const { file, text } of added) {
if (SUPPRESSIONS.test(text)) flag('silenced-checker', file, text);
if (STUBS.test(text)) flag('unfinished-work', file, text);
if (SKIPS.test(text)) flag('test-made-easier', file, text);
if (/CONSTRAINTS\.md$/.test(file) && /^\| *(W|E)\d+ *\|/.test(text)) flag('new-exception', file, text);
}
// 2b. Assertion removed from a test file that still exists.
for (const { file, text } of removed) {
if (/\.(test|spec)\.|_test\.|test_/.test(file) && /\b(expect|assert|should)\b/.test(text)) {
flag('assertion-removed', file, text);
}
}
// 1b/2c. Weakened threshold: a number in CONSTRAINTS.md that went down, or a floor bullet deleted.
const nums = (s) => (s.match(/\d+(\.\d+)?/g) || []).map(Number);
const removedConstraints = removed.filter((l) => /CONSTRAINTS\.md$/.test(l.file));
const addedConstraints = added.filter((l) => /CONSTRAINTS\.md$/.test(l.file));
for (const r of removedConstraints) {
const a = addedConstraints.find((x) => x.text.split(/[|:]/)[0] === r.text.split(/[|:]/)[0]);
if (a && nums(a.text).some((n, i) => nums(r.text)[i] !== undefined && n < nums(r.text)[i])) {
flag('threshold-lowered', r.file, r.text + ' -> ' + a.text);
}
}
if (findings.length === 0) { console.log('floor-guard: clean'); process.exit(0); }
console.error('floor-guard: ' + findings.length + ' floor violation(s):');
for (const f of findings) console.error(` [${f.rule}] ${f.file}: ${f.text}`);
console.error('\nEach is a move that lowers the bar. Fix the code, or route it through a tracked exception.');
process.exit(1);Adapting it
- Patterns are the only stack-specific part. Add your language's suppression and stub forms to the three regexes; the diff plumbing, the CONSTRAINTS.md checks, and the exit codes stay as-is.
- A
.constraintsignore(one glob per line) lets you exempt a path the guard would otherwise flag; check each added line's file against it before flagging, so a genuine exception is a tracked file rather than a loosened rule. - This is a starting point, not a finished tool. It is deliberately regex-shallow: it catches the cheap-road-to-green moves agents actually make, not a determined human hiding a change. That is the right trade for a check that runs on every diff. Once you outgrow it, move to a real runner (Escalation Path level 3).