Section 04 - mutation-gate hook (INV-6)
Goal
Close INV-6: a PreToolUse hook DENIES any Edit / Write / Bash-mutation of a manifest-distributed harness
artifact unless an /improve-tooling sentinel is live. The workflow IS the edit path — there is no
“quick edit just this once.” Promote “improve tooling, never work around” from discipline + reviewer-time
flag to a HARD GATE.
Implementation Sketch
Mirror the proven thin-shell → python-guard deny-envelope pattern
(scripts/create_plan_runtime/manual_invocation_guard.py + .claude/hooks/block-create-plan-manual.sh).
- New
scripts/harness_dist/manual_invocation_guard.pywhose banned surface is Edit/Write/Bash-mutation against any path in the manifest-resolved distributed set (§01 fingerprint domain —resolve_includes×canonical_path_for).guard-checkreads PreToolUse JSON on stdin, matchesfile_path/path/command, emits the deny envelope (permissionDecision: deny) unless a sentinel is live; alwaysexit 0. - Use the SCOPED + EXPIRING sentinel shape (
.claude/.route-unlock-activemodel in.claude/hooks/block-route-edits.sh:139-171) rather than a bare TTL — scoped to the touched paths, guarding against a stale blanket-allow marker. /improve-tooling’simplementphaseactivates the sentinel (.claude/.improve-tooling-active) anddeactivates atresume_original(mirrorcreate_plan_runtimeactivate/deactivate). While live, edits to harness paths are allowed; otherwise denied with a redirect to “run /improve-tooling”.- New
.claude/hooks/block-harness-edit.sh(thin pipe) registered in.claude/settings.jsonPreToolUse on Edit / Write / Bash. - BOOTSTRAP exemption: the gate depends on
/improve-toolingalready owning versioning (s-03). Until s-03 lands, the hook carries a bootstrap exemption so it does not block the edits that build the engine (workflow-ownership.md §3.3bootstrap-window). - Lock the governance design: add a
locked_designs:entry (scripts/improve_tooling_runtime/locked_designs.pymodel) whosetouches:covers the versioning engine + mutation-gate hook + migration contract, so post-landing edits require a user-typed unlock. Add athreat-model.md §2Tampering row +§4mediation entry.
Spec & Rule References
INV-6 (mission). skill-control-contract.md §Skill Control Contract (sentinel = authorization).
workflow-ownership.md §3.3 (bootstrap window). CLAUDE.md §Locked Designs. threat-model.md §2/§4.
Layer Coverage
Tooling-scope: L1-L11 N/A. L12 = the registered hook denying a real Edit to a harness path with no
sentinel, allowing it with a live sentinel. pytest gate:
scripts/harness_dist/tests/test_manual_invocation_guard.py (allow/deny/sentinel-TTL matrix, mirror the
create_plan_runtime self-test shape).
Work Items
- Add scripts/harness_dist/manual_invocation_guard.py denying Edit/Write/Bash-mutation of any manifest-distributed harness path unless an /improve-tooling sentinel is live.
- Use the scoped+expiring sentinel shape; /improve-tooling activate/deactivate it across implement..resume_original; carry a bootstrap exemption until s-03 lands.
- Add .claude/hooks/block-harness-edit.sh + settings.json registration; add a locked_designs entry covering the governance surface + threat-model.md §2/§4 rows.
Fresh intel (regenerated)
{ “schema_version”: 1, “target”: { “kind”: “plan-section”, “ref”: “installable-harness/s-0f191f30” }, “generated_at”: “2026-06-25T14:37:53.619342+00:00”, “graph_state”: { “head_sha”: “b74d6b9a”, “last_code_import_at”: “2026-06-25T14:34:26.259Z”, “embedding_stale”: false, “insights_stale”: false, “cpg_stale”: false }, “surfaces”: {}, “summary”: “intel-package[plan-section:installable-harness/s-0f191f30] agent-authored dossier”, “degraded”: false, “dossier”: { “objective_symbols”: [], “tiers”: {}, “agent_authored”: true, “difficulty”: { “class”: “routine”, “research_online”: false, “research_mode”: “auto”, “signals”: [], “plan_dir”: “/home/eric/projects/ori_lang/plans/installable-harness” } } }
(full dossier: mutation-gate-hook—s-0f191f30.intel.json)