feat(guardrails): refusal ends the attempt; doctrine-citers census; make test suite=

Root causes of the 2026-09-24 errors turned into mechanisms (BDR-100). hard_deny 'Routing around a guardrail': a refused command is never rerun through a wrapper, alias, heredoc, Makefile target, env file, other shell or other agent; the same clause in 14 agents and in the doctrine's sub-agent rule. make test suite=<file> runs one suite hermetically so the denied env-prefix form is never needed by hand. lib/tests/doctrine-citers.test.sh: every CLAUDE.md "Section" / § Label citation across skills, agents, lib, rules and hooks must resolve to a heading or bold label (flip-tested); its first run fixed rest-api-node.md. Doctrine 'After code changes' step 4: a changed rule, heading, label or threshold → grep every citer in the same commit.
This commit is contained in:
bastien
2026-09-24 20:58:25 +02:00
parent 8f10047ac4
commit 27f201d4aa
20 changed files with 129 additions and 6 deletions
+16
View File
@@ -7,6 +7,15 @@ Format follows [Keep a Changelog](https://keepachangelog.com/).
## [Unreleased]
### Added
- **`make test suite=<file>`** runs one suite hermetically; the
`GIT_CONFIG_GLOBAL=/dev/null` export lives in the Makefile so nobody types
the denied env-prefix form by hand (the reason an executor wrote a wrapper
around it on 2026-09-24).
- **`lib/tests/doctrine-citers.test.sh`** — every `CLAUDE.md "Section"` or
`CLAUDE.md … § Label` citation in skills, agents, lib, rules and hooks must
resolve to a heading or bold label of CLAUDE.global.md; flip-tested. Would
have caught the five "§ Language" pointers the density pass left dangling.
First run fixed one more (`rest-api-node.md` cited the heading without its dash).
- **graphify threshold signal** — `lib/graphify-gate.sh` counts tracked code
files (vendored trees excluded) and, from 200 with no
`graphify-out/graph.json`, the session-start banner shows one line
@@ -112,6 +121,13 @@ Format follows [Keep a Changelog](https://keepachangelog.com/).
until it lands.
### Changed
- **Routing around a guardrail is the same action** — new `hard_deny` entry: a
refused command is never rerun through a wrapper script, alias, heredoc,
Makefile target, env file, other shell or other agent; a refusal ends the
attempt and is reported with its rule; a brief that orders the refused form is
wrong. The same clause sits in every executor and reviewer agent, and the
doctrine's sub-agent rule names it. "After code changes" gains step 4: a
changed rule, heading, label or threshold → grep every citer, same commit.
- **Doctrine/skill coherence pass (C2)** — 30 rule pairs in tension found by
three read-only audits and resolved in the doctrine's favour: one ask
policy (visible / public-name / open-scope choices are asked); mandated