From 33f5356c82a18e81512583e69fed2d9532473e38 Mon Sep 17 00:00:00 2001 From: Bastien Chanot Date: Mon, 24 Aug 2026 13:36:32 +0200 Subject: [PATCH] feat(gates): wire GATE 0 into the four orchestrator skill restatements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The include is authoritative, but feat/bugfix/ship-feature/init-project each restate the verify loop inline — an orchestrator following the restatement alone would have skipped the floor. Each now carries the GATE 0 bullet ahead of GATE 1 (4 new structure locks, flip-tested). The contract-interview weight table stops promising a hotfix oracle nothing executes: hotfix runs no floor, the hotfixer runs the suite itself. CHANGELOG extended with the wiring + the RED result. --- .claude/tasks/TODO.md | 5 +++++ CHANGELOG.md | 4 ++++ lib/contract-interview.md | 9 +++++---- lib/tests/loops-heavy.test.sh | 2 ++ lib/tests/loops-light.test.sh | 2 ++ skills/bugfix/SKILL.md | 7 ++++++- skills/feat/SKILL.md | 9 +++++++-- skills/init-project/SKILL.md | 5 +++++ skills/ship-feature/SKILL.md | 5 +++++ 9 files changed, 41 insertions(+), 7 deletions(-) diff --git a/.claude/tasks/TODO.md b/.claude/tasks/TODO.md index 54ecefc..18687b9 100644 --- a/.claude/tasks/TODO.md +++ b/.claude/tasks/TODO.md @@ -1182,4 +1182,9 @@ Health Stack = shellcheck). n'exécute pas) + locks de structure sur W2/W3/W4/W5. - [x] W7 shellcheck + bash -n + `make test` complet. - [x] W8 CHANGELOG + registres (BDR + LRN + journal). +- [x] W10 restatements skills : bullet GATE 0 dans feat/bugfix/ship-feature/ + init-project (+4 locks, flip-testé) ; ligne hotfix du tableau de poids + corrigée (aucun floor à ce poids). 2026-08-24. +- [x] W11 RED comportemental : 16/16 runs frais non-amorcés conformes + (verifier ×9, feater ×2, orchestrateur ×5) → EVAL-027. 2026-08-24. - [ ] W9 PAS de merge — gate humain explicite. diff --git a/CHANGELOG.md b/CHANGELOG.md index c771b3a..e781ae8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,10 @@ Format follows [Keep a Changelog](https://keepachangelog.com/). Adapted from the `unlazy` skill (Leonxlnx/unlazy, MIT); its Stop hook, approval store, `.unlazy/` tree, depth-tree arithmetic and Node checker were deliberately refused — see BDR-083 for each reason. + The four orchestrator skills (`feat`, `bugfix`, `ship-feature`, + `init-project`) restate the GATE 0 bullet ahead of GATE 1 (locked); + hotfix explicitly runs no floor. Behavioral RED: 16/16 fresh unprimed + runs followed the new doctrine (EVAL-027). 64 new assertions in `lib/tests/gates.test.sh`. ### Changed diff --git a/lib/contract-interview.md b/lib/contract-interview.md index 684bf85..47256b7 100644 --- a/lib/contract-interview.md +++ b/lib/contract-interview.md @@ -140,10 +140,11 @@ Print one line to the user, then continue the flow: | init-project | Full. The interviewer's PROJECT BRIEF pours into the contract (V1 features → criteria). | | onboard | Audit-scope contract (interview answers → what to audit, which axes). | -Oracles follow the same proportion. hotfix: the build/tests criterion carries -its `CHECK:`, nothing else. feat / bugfix: the suite criterion at minimum, and -for bugfix the regression test the DIAGNOSIS names — its `CHECK:` runs that -test alone, so a green result means the reproduction actually flipped. +Oracles follow the same proportion. hotfix: none — that flow runs no floor +(and no verifier); the hotfixer runs build/tests itself. feat / bugfix: the +suite criterion at minimum, and for bugfix the regression test the DIAGNOSIS +names — its `CHECK:` runs that test alone, so a green result means the +reproduction actually flipped. ship-feature / init-project: build, suite, and every criterion a command can settle. onboard: audit criteria are mostly judgement — leave them oracle-free rather than invent a check that cannot fail. diff --git a/lib/tests/loops-heavy.test.sh b/lib/tests/loops-heavy.test.sh index 64a2847..9ee79cf 100644 --- a/lib/tests/loops-heavy.test.sh +++ b/lib/tests/loops-heavy.test.sh @@ -27,6 +27,7 @@ tf "shf enrich at gate" "$SHF" "ENRICH the STEP 0e contract" tf "shf gated marker" "$SHF" "[gated ]" tf "shf verify+secure step" "$SHF" "STEP 5 — VERIFY + SECURE" tf "shf uses shared include" "$SHF" "lib/verify-secure-loop.md" +tf "shf gate0 floor" "$SHF" "GATE 0 — deterministic floor" tf "shf judges enriched" "$SHF" "ENRICHED contract" tf "shf orthogonal to review" "$SHF" "DISTINCT axis from STEP 6 code review" @@ -36,6 +37,7 @@ tf "ini criteria from V1" "$INI" "V1 FEATURES (each testable)" tf "ini enrich at gate1" "$INI" "ENRICH the STEP 1 contract" tf "ini verify+secure step" "$INI" "STEP 9 — VERIFY + SECURE" tf "ini uses shared include" "$INI" "lib/verify-secure-loop.md" +tf "ini gate0 floor" "$INI" "GATE 0 — deterministic floor" tf "ini adds security gate" "$INI" "adds the security gate init-project previously lacked" echo "-- onboard (explicit NO-LOOP audit) --" diff --git a/lib/tests/loops-light.test.sh b/lib/tests/loops-light.test.sh index 61e0de4..092cf6c 100644 --- a/lib/tests/loops-light.test.sh +++ b/lib/tests/loops-light.test.sh @@ -57,6 +57,7 @@ tf "feat contract step" "$FSK" "STEP 0.7 — CONTRACT" tf "feat contract-interview" "$FSK" "lib/contract-interview.md" tf "feat verify+secure step" "$FSK" "STEP 4 — VERIFY + SECURE" tf "feat uses shared include" "$FSK" "lib/verify-secure-loop.md" +tf "feat gate0 floor" "$FSK" "GATE 0 — deterministic floor" tf "feat nominal 1+1 dispatch" "$FSK" "verifier + one security dispatch" tf "feat dispatches feater" "$FSK" 'subagent_type="feater"' @@ -65,6 +66,7 @@ tf "bug contract step" "$BSK" "STEP 3.5 — CONTRACT" tf "bug diagnosis feeds it" "$BSK" "feeds it: REQUEST verbatim" tf "bug fresh gates" "$BSK" "the two fresh gates per" tf "bug uses shared include" "$BSK" "lib/verify-secure-loop.md" +tf "bug gate0 floor" "$BSK" "GATE 0 — deterministic floor" tf "bug dispatches bugfixer" "$BSK" 'subagent_type="bugfixer"' echo "── agents/bugfixer.md (bugfix executor — sonnet, no Agent) ──" diff --git a/skills/bugfix/SKILL.md b/skills/bugfix/SKILL.md index 6c4f70c..30d3cce 100644 --- a/skills/bugfix/SKILL.md +++ b/skills/bugfix/SKILL.md @@ -172,6 +172,11 @@ Parse the `BUGFIX-EXEC REPORT`: 1. Run the two fresh gates per `$HOME/.claude/lib/verify-secure-loop.md` with `CONTRACT` = the STEP 3.5 path, `DIFF` = the executor's working-tree diff, `TEST` = the suite named in its report: + - GATE 0 — deterministic floor, no dispatch: `bash ~/.claude/lib/gates.sh + run "$CONTRACT"` executes the criteria's declared oracles fail-closed + (the regression-test criterion included). UNMET → re-dispatch a FRESH + bugfixer with the NOT-MET rows verbatim — no verifier is spent on a red + floor; own budget, max 3 → escalate. MET → GATE 1. - GATE 1 — a FRESH verifier judges the fix against the contract (bug gone + regression test present). CONFORME on the first pass → straight to GATE 2, no loop. ECARTS → the "dev" of the loop is the dispatched @@ -183,7 +188,7 @@ Parse the `BUGFIX-EXEC REPORT`: path; re-verify the request THEN re-scan, max 3 → escalate. Loop decisions stay HERE, in the main loop (LRN-083). Nominal = one - executor + one verifier + one security dispatch. + executor + a free floor run + one verifier + one security dispatch. 2. **Pre-commit confirmation gate.** Before running `git commit`, present the diff summary and the proposed message, then wait for approval: diff --git a/skills/feat/SKILL.md b/skills/feat/SKILL.md index 43dbeae..54b96f4 100644 --- a/skills/feat/SKILL.md +++ b/skills/feat/SKILL.md @@ -161,6 +161,11 @@ Run the two fresh gates per `$HOME/.claude/lib/verify-secure-loop.md` with `CONTRACT` = the STEP 0.7 path, `DIFF` = the working-tree diff the executor produced, `TEST` = the suite named in its report: +- GATE 0 — deterministic floor, no dispatch: `bash ~/.claude/lib/gates.sh + run "$CONTRACT"` executes the criteria's declared oracles fail-closed. + UNMET → re-dispatch a FRESH feater with the NOT-MET rows verbatim — no + verifier is spent on a red floor; own budget, max 3 → escalate. + MET (an all-manual contract too) → GATE 1. - GATE 1 — a FRESH verifier judges the diff against the contract (blind). CONFORME on the first pass → straight to GATE 2, no loop. ECARTS → the "dev" of the loop is the dispatched executor: re-dispatch a FRESH feater @@ -171,8 +176,8 @@ produced, `TEST` = the suite named in its report: CONTRACT path; re-verify the request THEN re-scan, max 3 → escalate. Loop decisions stay HERE, in the main loop (LRN-083). Nominal (clear -request, conform first pass, clean diff) = one executor + one -verifier + one security dispatch. +request, conform first pass, clean diff) = one executor + a free floor +run + one verifier + one security dispatch. ## STEP 5 — COMMIT diff --git a/skills/init-project/SKILL.md b/skills/init-project/SKILL.md index 4478abd..301fe36 100644 --- a/skills/init-project/SKILL.md +++ b/skills/init-project/SKILL.md @@ -227,6 +227,11 @@ If `graphify` not installed or complexity < 30% → skip silently. Run the two fresh gates per `$HOME/.claude/lib/verify-secure-loop.md` with `CONTRACT` = the STEP 1 path (ENRICHED at STEP 4), `DIFF` = the MVP branch diff (`develop..HEAD`), `TEST` = the project suite: +- GATE 0 — deterministic floor, no dispatch: `bash ~/.claude/lib/gates.sh + run "$CONTRACT"` executes the criteria's declared oracles fail-closed. + UNMET → hand the dev with the NOT-MET rows verbatim — no + verifier is spent on a red floor; own budget, max 3 → escalate. + MET (an all-manual contract too) → GATE 1. - GATE 1 — a FRESH verifier judges the MVP against the enriched contract (V1 features + `[gated]` design criteria). CONFORME → GATE 2. ECARTS → fix, re-verify, max 3 → STOP + human escalation with the CRITERIA table. diff --git a/skills/ship-feature/SKILL.md b/skills/ship-feature/SKILL.md index 4cb8602..7c02b18 100644 --- a/skills/ship-feature/SKILL.md +++ b/skills/ship-feature/SKILL.md @@ -210,6 +210,11 @@ OPTIONS : Run the two fresh gates per `$HOME/.claude/lib/verify-secure-loop.md` with `CONTRACT` = the STEP 0e path (ENRICHED at STEP 3), `DIFF` = the branch diff (`develop..HEAD`), `TEST` = the project suite: +- GATE 0 — deterministic floor, no dispatch: `bash ~/.claude/lib/gates.sh + run "$CONTRACT"` executes the criteria's declared oracles fail-closed. + UNMET → hand the dev with the NOT-MET rows verbatim — no + verifier is spent on a red floor; own budget, max 3 → escalate. + MET (an all-manual contract too) → GATE 1. - GATE 1 — a FRESH verifier judges the branch against the ENRICHED contract (all criteria, including the `[gated]` design ones). CONFORME → GATE 2. ECARTS → hand the dev the gap list, fix, re-verify, max 3 → STOP + human