Foreman

Speed

Light enough to forget it's there

Hooks run on every tool call, so each has a time budget and the bench holds them to it. Only the guard and the write validators run in the call's path.

Hook time per event, p95Measured by bench_hooks.py; the dashed tick is each hook's budget.
PreToolUse:Bash:scriptPreToolUse:Bash:script: 274 ms274 msbudget 300 msUserPromptSubmitUserPromptSubmit: 92.6 ms92.6 msbudget 150 msPreToolUse:BashPreToolUse:Bash: 67.1 ms67.1 msbudget 150 msSessionStartSessionStart: 63.4 ms63.4 msbudget 150 msPreToolUse:EditPreToolUse:Edit: 56.5 ms56.5 msbudget 150 msPreToolUse:Bash:blockPreToolUse:Bash:block: 48.7 ms48.7 msbudget 150 msStopStop: 47.6 ms47.6 msbudget 150 msPreCompactPreCompact: 45.3 ms45.3 msbudget 150 msNotificationNotification: 42.4 ms42.4 msbudget 150 msPostToolUsePostToolUse: 41.5 ms41.5 msbudget 150 msSubagentStopSubagentStop: 41.4 ms41.4 msbudget 150 msPostToolUseFailurePostToolUseFailure: 39 ms39 msbudget 150 msSessionEndSessionEnd: 38.8 ms38.8 msbudget 150 msTaskCompletedTaskCompleted: 35.8 ms35.8 msbudget 150 msMessageDisplayMessageDisplay: 35.6 ms35.6 msbudget 100 msSubagentStartSubagentStart: 35.4 ms35.4 msbudget 150 ms
Show the numbers
valuebudget
PreToolUse:Bash:script274300
UserPromptSubmit92.6150
PreToolUse:Bash67.1150
SessionStart63.4150
PreToolUse:Edit56.5150
PreToolUse:Bash:block48.7150
Stop47.6150
PreCompact45.3150
Notification42.4150
PostToolUse41.5150
SubagentStop41.4150
PostToolUseFailure39150
SessionEnd38.8150
TaskCompleted35.8150
MessageDisplay35.6100
SubagentStart35.4150

How it stays fast

  • Budgets per hook, checked by bench_hooks.py on every release.
  • Reused gate passes. fm check skips a gate that passed on an identical tree.
  • Cached verdicts. Scripts the guard read are cached by content.
  • Notes once. Context is injected only when it changes what Claude should do next.
Gate runs558
Median full gate run, s75.6

Next: Learning