Skip to content

Apply permission escalation per turn in the Claude adapter - #1236

Open
sholub-dev wants to merge 1 commit into
get-bb:mainfrom
sholub-dev:per-turn-permission-escalation
Open

Apply permission escalation per turn in the Claude adapter#1236
sholub-dev wants to merge 1 commit into
get-bb:mainfrom
sholub-dev:per-turn-permission-escalation

Conversation

@sholub-dev

Copy link
Copy Markdown
Contributor

Summary

permissionEscalation follows the turn initiator, but it was pinned into Claude session construction, so every user/system turn alternation looked like a settings change and replaced the session — killing all background tasks (workflows, backgrounded commands, background agents) inside it. Fixes #1235.

Escalation is now per-turn state:

  • turn/start and turn/steer bridge commands carry permissionEscalation and the bridge updates the live session in place.
  • The two construction-time consumers read it live instead: the readonly PreToolUse hook resolves escalation at tool-call time, and the workspace sandbox keeps allowUnsandboxedCommands: true, with the unsandboxed retry auto-denied by canUseTool on escalation-denied turns. A new guard denies dangerouslyDisableSandbox Bash on denied turns before the cached session-grant shortcut, so an "always allow" grant from an ask turn cannot leak into a deny turn.
  • The construction config compared on thread/resume omits escalation structurally, so an escalation-only resume adopts the new value instead of replacing the session.
  • The Claude adapter declares appliesPermissionEscalationPerTurn: true (the field is required; Codex, Pi, and ACP declare false and keep existing behavior). For such adapters the runtime records an escalation-only options change without dispatching a session-replacing thread/resume, keeping its stored options fresh for approval auto-deny.

No HOST_DAEMON_PROTOCOL_VERSION bump: nothing sent between server and host daemon changed — the new field is on the daemon-to-bridge JSON-RPC protocol, which ships in the same bundle as the daemon.

Tests: a bridge test proves a live session survives an escalation-only thread/resume; a runtime test proves no thread/resume is dispatched for an escalation-only change; a new canUseTool policy case covers the unsandboxed-retry deny; existing policy cases cover the sandbox enforcement move.

Escalation follows the turn initiator, but it was pinned into Claude session
construction, so every user/system turn alternation replaced the session and
killed the background tasks inside it. Turn commands now carry escalation, the
bridge adopts it in place, and the runtime records escalation-only changes
without a session-replacing reconfigure.
@sholub-dev
sholub-dev force-pushed the per-turn-permission-escalation branch from 4aa085b to 1c28080 Compare August 9, 2026 18:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Background tasks are killed when user and system turns alternate

1 participant