Precision with Runs

The same guard two ways — recall vs precision.

The conservative match has a cost: git commit -m "git stash" blocks too, and that’s a command you actually want to run. capt-hook gives you both ends of the tradeoff. Page one’s block_command sits at one end; here’s the other — the same guard rebuilt on Runs, which matches the parsed argv of each command in the line. Same input, two verdicts, side by side:

Work through the presets and watch the verdicts split. The table shows what the real engine answers — Pattern is page one’s guard, Runs is the hook above, and the widget runs the Runs version (it declines wrapper payloads honestly; capt-hook test covers those for real):

Command Pattern Runs
git stash blocks blocks
git commit -m "git stash" blocks allows — it’s an argument, not a command
echo "git stash" blocks allows
sudo git stash blocks allowsRuns sees sudo’s argv, not what it wraps
sh -c "git stash" blocks blocks — the parser descends into the payload

The last two rows are the lesson, and they cut in opposite directions. Runs matches structure, so a wrapper like sudo hides the command from it — cover wrappers with their own entry. But a string payload doesn’t hide anything: the parser descends into sh -c and finds the git stash inside. Precision costs you wrappers, not depth.

So pick by stakes: Runs when false positives break real workflows, the conservative pattern when the command must never slip through. For rm -rf, take the false positives.

Next: stack conditions into one guard.