Section 01: PreToolUse Deny-Gate (emergency)
Status: Not Started
Goal: Block the write that created the §08 fabrication. A PreToolUse hook on Edit|Write|MultiEdit denies introducing status: → complete or reviewed: true → false on a plans/** / bug-tracker/plans/** file without a valid independent_review attestation. Pure gate — denies, never mutates.
Success Criteria:
- Deny
status: → completewithout attestation on a plan file (satisfies mission criterion 1). - Deny
reviewed: true → falsewithout attestation (satisfies mission criterion 1). - Allow
reviewed: false → true, in-flight status transitions, and non-plan edits (no false positives). - Pure gate: stderr reason + deny verdict; zero file writes.
-
--self-testexits 0 across the six cases in frontmattersuccess_criteria.
Context: The §08 fabrication was a raw Edit to frontmatter (status: not-started → complete, reviewed: false → true) with zero deliverables. No Python write-API was involved, so an API-level guard cannot catch it. The PreToolUse boundary is the only point that intercepts a Claude-initiated raw Edit BEFORE it lands — and .claude/settings.json already runs block-spec-edits.sh on every Edit/Write, so the mechanism is proven in-tree.
Depends on: None. Emergency — land first.
Intelligence Reconnaissance
Queries run 2026-05-26:
scripts/intel-query.sh search "PreToolUse hook deny"— N/A surface: the Ori code-symbol graph indexes Rust compiler crates only; this section touches.claude/settings.json+.claude/hooks/*.sh+ a Python deny-module (not in the Rust index). Recorded per plan-schema allowance for non-Rust targets.- Direct grounding (this session):
.claude/settings.jsonPreToolUse already wiresblock-spec-edits.sh+python3 -m scripts.plan_corpus.hook_dispatchonEditandWritematchers.block-spec-edits.shis the pure-deny-gate precedent.MultiEditmatcher absent today — add it.
Results summary [ori]: enforcement home is the existing .claude/settings.json PreToolUse Edit/Write hook chain; add MultiEdit matcher; new deny module mirrors block-spec-edits.sh deny-JSON shape (hookSpecificOutput.permissionDecision: deny + reason; exit 0 to allow; block-only, no mutation).
Gate-scope decision (2026-05-26, surgical — user-selected): until §04 (attestation) + §06 (/independent-review) land, the gate is SURGICAL, not a blanket completion freeze: it denies status: → complete ONLY when a declared deliverable is missing — a touches: path absent OR a tracking table with pending rows. Sections whose deliverables genuinely exist still complete via the normal path in this window. This catches the §08 shape (missing aims-proof/proofs/08-realization/, all-pending Per-RL table) without freezing legitimate completions for parallel sessions / normal /review-plan close-outs. The surgical deliverable check IS the write-time precursor to §06’s deliverable-existence teeth; §04 later adds attestation-binding on top.
01.1 Deny-gate hook script + settings.json wiring
File(s): .claude/hooks/block-unattested-completion.sh (new) OR a scripts/plan_corpus deny-module invoked from the hook; .claude/settings.json
- Author the deny-gate. Input: PreToolUse
tool_input(file_path + proposed content) on stdin. Output: deny via{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"..."}}+exit 0; allow viaexit 0no-output (mirrorblock-spec-edits.sh). Logic: if file_path matchesplans/**orbug-tracker/plans/**AND the proposed content introducesstatus: → complete(vs the on-disk pre-edit value) AND a declared deliverable is MISSING → deny. Else allow.- Diff against the on-disk pre-edit frontmatter to detect the TRANSITION (not just presence) — an already-
completesection being edited for other reasons MUST NOT re-fire. - SURGICAL deliverable check (per the 2026-05-26 gate-scope decision): deny
status: → completewhen ANY declaredtouches:path is absent on disk OR the section body still contains a tracking-table row withpendingproof_status. Sections whose deliverables exist pass. Also denyreviewed: true → false(the reversal) outside /independent-review. Do NOT blanket-deny completions whose deliverables exist. - Implementation home: a Python module (YAML frontmatter parse + on-disk pre-edit diff + filesystem deliverable check is Python-natural) invoked on the
Edit/Write/MultiEditPreToolUse chain alongsideblock-spec-edits.sh+scripts.plan_corpus.hook_dispatch. Confirm whether to extendhook_dispatchor add a sibling module at build time.
- Diff against the on-disk pre-edit frontmatter to detect the TRANSITION (not just presence) — an already-
- Wire into
.claude/settings.jsonPreToolUse: add the hook to theEditandWritematchers; add aMultiEditmatcher carrying the same hook. - Pure-gate invariant: the hook MUST NOT write, stage, or mutate any file. Deny-only.
- Subsection close-out (01.1) — MANDATORY before 01.2:
- All tasks above
[x], behavior verified against a hand-edit attempt on a scratch plan file. - Update this subsection’s
statustocomplete. - Repo hygiene check —
compiler_repo/diagnostics/repo-hygiene.sh --check;--cleanif needed.
- All tasks above
01.2 Self-test + decision-shape conformance
File(s): the deny-gate script’s --self-test path; scripts/<runtime>/tests/ if a Python module
- Implement
--self-testcovering: (a) deny →complete-no-attestation, (b) deny reviewed:true→false-no-attestation, (c) allow reviewed:false→true, (d) allow in-progress transition, (e) allow attested-complete (mock attestation), (f) ignore non-plan path. - Confirm the deny decision shape matches the PreToolUse hook contract Claude Code expects (deny verdict + human-readable reason). Mirror
block-spec-edits.shoutput shape. - Subsection close-out (01.2) — MANDATORY before 01.N:
- All tasks
[x];--self-testexits 0. - Update this subsection’s
statustocomplete. - Repo hygiene check —
compiler_repo/diagnostics/repo-hygiene.sh --check.
- All tasks
01.N Completion Checklist
- 01.1–01.2 all
[x]and statuscomplete. -
<deny-gate> --self-testexits 0 (all six cases). -
.claude/settings.jsonvalid JSON;Edit+Write+MultiEditmatchers carry the hook. - Manual proof: a hand-edit introducing
status: completeto a scratchplans/**file is denied; an unrelated edit to the same file is allowed. - Pure-gate audit:
grepthe hook for any write/stage/git add— must be zero. - Plan sync — this section
status→ (NOTcompletedirectly per bootstrap caveat; close via §06/independent-review); update00-overview.mdQuick Reference +index.md. - Repo hygiene check —
compiler_repo/diagnostics/repo-hygiene.sh --check.
Exit Criteria: A Claude-initiated Edit introducing status: complete (or reviewed: true→false) to a plans/** / bug-tracker/plans/** file without an independent_review attestation is denied at the PreToolUse boundary; reviewed: false→true and in-flight transitions pass; the hook writes nothing; --self-test exits 0.