Add hook dispatch probes to isolate why bash-guard never fires
Registers five inert probe entries covering the 2x2 of timeout and statusMessage on PreToolUse:Bash, plus a PostToolUse statusMessage cell. Each probe is in its own matcher block so a dropped entry cannot take the others with it, and logs its identity before reading stdin so a failed dispatch stays distinguishable from a failed payload read. The real bash-guard entry is unchanged and serves as the control.
This commit is contained in:
@@ -11,6 +11,46 @@
|
|||||||
"statusMessage": "Checking jj/attribution policy; gating push on build + tests..."
|
"statusMessage": "Checking jj/attribution policy; gating push on build + tests..."
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"matcher": "Bash",
|
||||||
|
"hooks": [
|
||||||
|
{
|
||||||
|
"type": "command",
|
||||||
|
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/probe.mjs\" P1-plain"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"matcher": "Bash",
|
||||||
|
"hooks": [
|
||||||
|
{
|
||||||
|
"type": "command",
|
||||||
|
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/probe.mjs\" P2-timeout-only",
|
||||||
|
"timeout": 600
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"matcher": "Bash",
|
||||||
|
"hooks": [
|
||||||
|
{
|
||||||
|
"type": "command",
|
||||||
|
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/probe.mjs\" P3-status-only",
|
||||||
|
"statusMessage": "probe P3 status-only"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"matcher": "Bash",
|
||||||
|
"hooks": [
|
||||||
|
{
|
||||||
|
"type": "command",
|
||||||
|
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/probe.mjs\" P4-both",
|
||||||
|
"timeout": 600,
|
||||||
|
"statusMessage": "probe P4 both"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"PostToolUse": [
|
"PostToolUse": [
|
||||||
@@ -23,6 +63,16 @@
|
|||||||
"timeout": 5
|
"timeout": 5
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"matcher": "Write|Edit|MultiEdit",
|
||||||
|
"hooks": [
|
||||||
|
{
|
||||||
|
"type": "command",
|
||||||
|
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/probe.mjs\" P5-post-status",
|
||||||
|
"statusMessage": "probe P5 post status"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
// Diagnostic probe for hook dispatch. Inert: logs and exits 0, never emits a decision.
|
||||||
|
//
|
||||||
|
// Logs BEFORE reading stdin, so three outcomes stay distinguishable:
|
||||||
|
// no line at all -> entry never dispatched
|
||||||
|
// phase=spawned only -> dispatched, but the stdin read threw (bash-guard's line 29)
|
||||||
|
// phase=stdin-ok -> dispatched and payload readable; records permission_mode
|
||||||
|
//
|
||||||
|
// Each hooks.json entry passes a distinct label so the transcript's `command` field
|
||||||
|
// and this log both identify which config variant ran.
|
||||||
|
|
||||||
|
import { appendFileSync, readFileSync } from 'fs';
|
||||||
|
import { homedir } from 'os';
|
||||||
|
import { join } from 'path';
|
||||||
|
|
||||||
|
const label = process.argv[2] ?? '<none>';
|
||||||
|
const stamp = new Date().toISOString();
|
||||||
|
|
||||||
|
// Two sinks: a sandboxed hook child might see a private /tmp but still reach $HOME.
|
||||||
|
const log = (line) => {
|
||||||
|
for (const p of ['/tmp/guard-probe.log', join(homedir(), 'guard-probe.log')]) {
|
||||||
|
try { appendFileSync(p, line); } catch {}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
log(`${stamp} probe=${label} phase=spawned\n`);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const input = JSON.parse(readFileSync('/dev/stdin', 'utf8'));
|
||||||
|
log(`${stamp} probe=${label} phase=stdin-ok mode=${input?.permission_mode ?? '<absent>'}`
|
||||||
|
+ ` tool=${input?.tool_name ?? '?'} cmd=${(input?.tool_input?.command ?? '').slice(0, 40)}\n`);
|
||||||
|
} catch (e) {
|
||||||
|
log(`${stamp} probe=${label} phase=stdin-FAILED err=${e?.message ?? e}\n`);
|
||||||
|
}
|
||||||
|
|
||||||
|
process.exit(0);
|
||||||
Reference in New Issue
Block a user