PreToolUse:Agent advisory — warns orchestrator if git status is dirty
before spawning next agent. Closes the workflow gap that caused 28
uncommitted files across 5 bundles on main (2026-04-22 incident).
hooks/orchestrator-dirty-check.sh (51 LOC, POSIX sh):
- Sources _lib/gate.sh, respects KEI_DISABLED_HOOKS
- Reads git status --porcelain at repo root
- Emits stderr advisory with modified/untracked counts + sample
- Exit 0 always (advisory, not blocking)
- Bypass: ORCHESTRATOR_META=1 (existing RULE 0.13 flag) or
ORCHESTRATOR_DIRTY_OK=1 (new, explicit)
- Severity: warn — per RULE 0.10 ladder; upgrade to enforce
only after 2nd recurrence
hooks/_lib/test-orchestrator-dirty-check.sh (60 LOC):
- 5 test cases with mocked git PATH shim
- Clean / dirty-modified / dirty-untracked / env-bypass /
gate-bypass
- PASS 5/5 (existing gate.sh tests unchanged — 11/11)
Wired into hooks/hooks.json (plugin format) and settings-snippet.json
(classic install) at PreToolUse/Agent matcher.
skills/hooks-control/SKILL.md — hook list 9 → 10.
README.md — hook table gains 1 row; count marker left at 9 for
scripts/regen-counts.sh to update post-merge.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
97 lines
2.4 KiB
JSON
97 lines
2.4 KiB
JSON
{
|
|
"hooks": {
|
|
"PostToolUse": [
|
|
{
|
|
"matcher": "Write|Edit",
|
|
"hooks": [
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/assemble-agents.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/site-wysiwyd-check.sh",
|
|
"statusMessage": "site-wysiwyd drift check..."
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"matcher": "Bash",
|
|
"hooks": [
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/milestone-commit-hook.sh",
|
|
"statusMessage": "milestone self-audit check (RULE 0.14)..."
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"matcher": "*",
|
|
"hooks": [
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/error-spike-detector.sh",
|
|
"statusMessage": "error-spike rolling window (RULE 0.14)..."
|
|
}
|
|
]
|
|
}
|
|
],
|
|
"PreToolUse": [
|
|
{
|
|
"matcher": "Bash",
|
|
"hooks": [
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/assemble-validate.sh"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"matcher": "Edit|Write",
|
|
"hooks": [
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/no-hand-edit-agents.sh"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"matcher": "Read",
|
|
"hooks": [
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/tomd-preread.sh",
|
|
"statusMessage": "tomd pre-read auto-convert check..."
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"matcher": "Agent",
|
|
"hooks": [
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/agent-fork-logger.sh",
|
|
"statusMessage": "agent-fork-logger (RULE 0.12)..."
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/orchestrator-dirty-check.sh",
|
|
"statusMessage": "orchestrator-dirty-check (RULE 0.13)..."
|
|
}
|
|
]
|
|
}
|
|
],
|
|
"Stop": [
|
|
{
|
|
"matcher": "*",
|
|
"hooks": [
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/session-end-dump.sh",
|
|
"statusMessage": "session-end trace dump (RULE 0.14)..."
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
}
|