feat(agents): wire contract + verify + security into feat/bugfix/hotfix (verify-loops lot 4)

lib/verify-secure-loop.md: shared main-loop include. GATE 1 fresh verifier
(blind, contract from disk) → CONFORME straight to GATE 2, ECARTS loop max
3; GATE 2 fresh security-auditor (MODE gate) → PASS to commit, BLOCK loop
max 3 with re-verify-request-FIRST order invariant. Mute agent never a PASS.

feater.md: STEP 0.7 CONTRACT (proportional, silent on a clear feature) +
STEP 3 VERIFY+SECURE via the include. Nominal = one verifier + one security
dispatch; the loop only costs when it loops.

bugfixer.md: STEP 3.5 CONTRACT fed by the DIAGNOSIS (bug report verbatim +
reproduced-then-gone + regression test criteria) + STEP 5 fresh gates via
the include. Renumbered STEP 5 sub-steps (gates before the commit gate).

hotfixer.md: STEP 1.7 CONTRACT (silent autofill, zero questions) + STEP 3
security gate whose FAILURE REVERTS (git restore to pre-flight SHA + escalate
to /bugfix), never loops — the 1-attempt model preserved. No fresh verifier
at hotfix weight (the smoke-check verifies the trivial contract). Adds the
Agent tool to hotfixer.md + hotfix/SKILL.md for the security dispatch.

lib/tests/loops-light.test.sh: 27 structure locks green, shellcheck clean.
Behavioral pipeline dogfood on a fixture (feat adding a feature WITH a SQLi):
GATE1 CONFORME (feature present, SQLi not a conformity gap — orthogonal
gates) → GATE2 BLOCK(1) (checklist caught the %-interp SQLi semgrep's taint
rules missed) → [fix to parameterized] → re-verify CONFORME (order invariant,
feature intact) → re-scan PASS. Loop converges to green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XpphkdTosUzokBDNG7PToS
This commit is contained in:
Bastien Chanot
2026-07-03 20:47:07 +02:00
co-authored by Claude Opus 4.8
parent 5aa4216409
commit 0f0162dcae
6 changed files with 224 additions and 20 deletions
+28 -12
View File
@@ -65,6 +65,17 @@ already constrain or forbid the approach; an LRN may name a gotcha to apply. Emi
MEMORY; feed STEP 1 MINI-PLAN. Inline consumption — reader = planner, no injection.
`.claude/memory/` absent → guarded no-op (zero overhead on a memory-less repo).
## STEP 0.7 — CONTRACT
Run `$HOME/.claude/lib/contract-interview.md` (main loop — you are it). It
captures the request verbatim, asks 0-3 questions PROPORTIONAL to ambiguity
(a complete request → zero questions, silent), derives testable acceptance
criteria + file scope, and writes the contract to
`.claude/tasks/contracts/<date>-<slug>-<HHMM>.md`. Keep the path — GATE 1
(STEP 3) hands it to a fresh verifier. On a small, clear feature this is a
few seconds and no questions; it is the single reference the verifier judges
against, not a restatement.
## STEP 1 — MINI-PLAN
Quick mental model, not a formal plan document:
@@ -101,19 +112,24 @@ Work through the plan:
- Follow existing patterns in the codebase.
- Run tests incrementally as you go.
## STEP 3 — VERIFY
## STEP 3 — VERIFY + SECURE (fresh gates, bounded loops)
1. Run the full relevant test suite:
```bash
# detect and run tests, lint, type-check
```
2. If a dev server is relevant, mention what the user should
check visually.
3. Quick self-review: scan your diff for obvious issues:
```bash
git diff --stat
git diff
```
First, your own pre-check (dev-side, fast): run the relevant test suite /
lint / type-check, and if a dev server is relevant note what to check
visually. This is your smoke test, NOT the gate.
Then run the two fresh gates per `$HOME/.claude/lib/verify-secure-loop.md`
with `CONTRACT` = the STEP 0.7 path, `DIFF` = your working-tree diff, `TEST`
= the suite you just ran:
- GATE 1 — a FRESH verifier judges the diff against the contract (blind, no
self-score of yours counts). CONFORME on the first pass → straight to GATE
2, no loop. ECARTS → fix the named gaps, re-verify, max 3 → escalate.
- GATE 2 — a FRESH security-auditor (`MODE: gate`) scans the diff. PASS →
commit. BLOCK → fix, re-verify the request THEN re-scan, max 3 → escalate.
Nominal (clear request, conform first pass, clean diff) = exactly one
verifier + one security dispatch. The loop only costs when it loops.
## STEP 4 — COMMIT