0%

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: → complete without attestation on a plan file (satisfies mission criterion 1).
  • Deny reviewed: true → false without 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-test exits 0 across the six cases in frontmatter success_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.json PreToolUse already wires block-spec-edits.sh + python3 -m scripts.plan_corpus.hook_dispatch on Edit and Write matchers. block-spec-edits.sh is the pure-deny-gate precedent. MultiEdit matcher 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 via exit 0 no-output (mirror block-spec-edits.sh). Logic: if file_path matches plans/** or bug-tracker/plans/** AND the proposed content introduces status: → 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-complete section being edited for other reasons MUST NOT re-fire.
    • SURGICAL deliverable check (per the 2026-05-26 gate-scope decision): deny status: → complete when ANY declared touches: path is absent on disk OR the section body still contains a tracking-table row with pending proof_status. Sections whose deliverables exist pass. Also deny reviewed: 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/MultiEdit PreToolUse chain alongside block-spec-edits.sh + scripts.plan_corpus.hook_dispatch. Confirm whether to extend hook_dispatch or add a sibling module at build time.
  • Wire into .claude/settings.json PreToolUse: add the hook to the Edit and Write matchers; add a MultiEdit matcher 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 status to complete.
    • Repo hygiene checkcompiler_repo/diagnostics/repo-hygiene.sh --check; --clean if needed.

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-test covering: (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.sh output shape.
  • Subsection close-out (01.2) — MANDATORY before 01.N:
    • All tasks [x]; --self-test exits 0.
    • Update this subsection’s status to complete.
    • Repo hygiene checkcompiler_repo/diagnostics/repo-hygiene.sh --check.

01.N Completion Checklist

  • 01.1–01.2 all [x] and status complete.
  • <deny-gate> --self-test exits 0 (all six cases).
  • .claude/settings.json valid JSON; Edit + Write + MultiEdit matchers carry the hook.
  • Manual proof: a hand-edit introducing status: complete to a scratch plans/** file is denied; an unrelated edit to the same file is allowed.
  • Pure-gate audit: grep the hook for any write/stage/git add — must be zero.
  • Plan sync — this section status → (NOT complete directly per bootstrap caveat; close via §06 /independent-review); update 00-overview.md Quick Reference + index.md.
  • Repo hygiene checkcompiler_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.