Blocking Budget
- Entity ID:
ent-20260410-ec50e65326b2 - Type:
mechanism - Scope:
shared - Status:
active
Description
The Blocking Budget is a mechanism that prevents long-running shell commands from blocking the Claude Code agent in assistant mode. When a Bash or PowerShell command runs longer than 15 seconds in the main agent thread, a timer fires and automatically moves the command to a background task, returning control to the agent immediately. The command continues running -- nothing is killed -- and the agent is notified when it completes. This keeps the assistant responsive for coordination while expensive builds, tests, or installations proceed in the background.
The constant ASSISTANT_BLOCKING_BUDGET_MS = 15_000 is defined locally in both src/tools/BashTool/BashTool.tsx (line 57) and src/tools/PowerShellTool/PowerShellTool.tsx (line 162). The mechanism is gated behind the KAIROS feature flag and only activates when getKairosActive() returns true (assistant mode), the command is running on the main agent thread (isMainThread), background tasks are not disabled, and the command was not already explicitly requested to run in the background (run_in_background !== true). The timer is created with .unref() so it does not prevent the process from exiting.
When the timer fires, it calls startBackgrounding(), which checks whether a foreground task has already been registered for this command. If so, it calls backgroundExistingForegroundTask() to convert it in-place without re-spawning (avoiding duplicate task_started SDK events and cleanup callback leaks). If no foreground task exists, it spawns a new background task via spawnBackgroundTask(). The tool result message includes a specific backgroundInfo string explaining: "Command exceeded the assistant-mode blocking budget (15s) and was moved to the background with ID: {taskId}. It is still running -- you will be notified when it completes." This instructs the agent to delegate long-running work to subagents or use run_in_background explicitly. The assistantAutoBackgrounded flag is set to true on the output schema so downstream consumers can distinguish auto-backgrounded commands from user-initiated or timeout-initiated backgrounding.
Key claims
- The blocking budget is exactly 15 seconds:
const ASSISTANT_BLOCKING_BUDGET_MS = 15_000insrc/tools/BashTool/BashTool.tsx(line 57) andsrc/tools/PowerShellTool/PowerShellTool.tsx(line 162). - The timer uses
.unref()to avoid preventing process exit:setTimeout(..., ASSISTANT_BLOCKING_BUDGET_MS).unref()(BashTool line 982, PowerShellTool equivalent). - Auto-backgrounding only fires when all conditions are met:
feature('KAIROS') && getKairosActive() && isMainThread && !isBackgroundTasksDisabled && run_in_background !== true(BashTool line 976). - In-place backgrounding via
backgroundExistingForegroundTask()is preferred over re-spawning to avoid overwritingtasks[taskId], emitting duplicatetask_startedSDK events, and leaking cleanup callbacks (BashTool line 925-931). - The tool result message explicitly advises the agent: "In assistant mode, delegate long-running work to a subagent or use run_in_background to keep this conversation responsive" (BashTool line 610).
Relations
- implemented-by:
src/tools/BashTool/BashTool.tsx-- auto-backgrounding logic for Bash commands - implemented-by:
src/tools/PowerShellTool/PowerShellTool.tsx-- auto-backgrounding logic for PowerShell commands - depends-on:
src/tasks/LocalShellTask/LocalShellTask.tsx--backgroundExistingForegroundTask(),spawnShellTask(),registerForeground(),unregisterForeground() - gated-by:
KAIROSfeature flag andgetKairosActive()fromsrc/bootstrap/state.ts - related-to:
run_in_backgroundparameter -- explicit user/agent request to background a command, which bypasses the budget mechanism
Sources
src/tools/BashTool/BashTool.tsxsrc/tools/PowerShellTool/PowerShellTool.tsxsrc/tasks/LocalShellTask/LocalShellTask.tsx