Apply Claude turn settings without replacing live sessions - #1236
Conversation
4aa085b to
1c28080
Compare
|
🚨 SLOP COP 🚨 · I am SlopCop. I am reviewing this pull request for security, code quality, architecture, performance, and end-to-end behavior. |
| return; | ||
| } | ||
|
|
||
| threadSession.permissionEscalation = params.permissionEscalation; |
There was a problem hiding this comment.
🚨 slopcop/review — A shared session value applies the newest turn policy to all background work.
Background tasks outlive their start turn. A later turn overwrites this shared value. An older system task can then read ask from a user turn and enter the approval path. The reverse change can also deny older user work. Please attach the policy to the work that created each tool request. Add overlap tests for both policy directions.
There was a problem hiding this comment.
The SDK gives canUseTool no link to the originating turn or task, so per-work policy isn't possible at this layer. The old behavior rebuilt the session on every escalation flip and killed background work — the bug this PR fixes. Both crossovers fail safe: ask only happens while a user turn is active, deny auto-denies.
| return; | ||
| } | ||
|
|
||
| threadSession.permissionEscalation = params.permissionEscalation; |
There was a problem hiding this comment.
🚨 slopcop/review — A failed steer leaves the new permission policy active.
This assignment occurs before pushInput confirms the steer. The error path returns an error without restoring the old value. A rejected ask steer can therefore loosen the policy for existing deny work. Update the value after acceptance, or restore it in the error path. Add a failed-steer test.
There was a problem hiding this comment.
Fixed in d4bf20e: escalation is set only after pushInput succeeds. Added a failed-steer test.
SawyerHood
left a comment
There was a problem hiding this comment.
🚨 SLOP COP 🚨 · review
ELI5: This change keeps old Claude jobs alive. But it gives all jobs one permission switch. It is like one light switch for every room.
I found two defects. I recommend fixes before merge.
-
High — Background work crosses the per-turn permission boundary.
Background tasks outlive their start turn. Each new turn overwrites one session-wide
permissionEscalationvalue. An older system task can later readaskfrom a user turn and enter the approval path. The reverse change can deny older user work. Attach the policy to the work that created each tool request. Add overlap tests for both policy directions. -
Medium — A failed steer keeps its permission change.
The bridge changes the value before
pushInputsucceeds. The error path does not restore the old value. A rejectedasksteer can loosen existingdenywork. Update the value after acceptance, or restore it after failure.
Architecture and performance
The adapter capability is an acceptable abstraction. The two Claude permission checks serve different SDK enforcement points. I found no useful refactor requirement. The change removes session replacement and adds constant-time state access.
Validation
I verified the exact head SHA and reviewed all 14 changed files. Three newer base commits do not touch these files. git diff --check passed. All reported GitHub CI checks passed. The change does not require a host-daemon protocol increase.
The pull request comes from an untrusted fork, and this backend change has no browser route. I did not start a server or execute the pull-request code locally.
This is a comment-only review. I did not approve the pull request or request changes.
9269d62 to
d4bf20e
Compare
d4bf20e to
3b81ef3
Compare
3b81ef3 to
f79aeb7
Compare
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.
## Summary - resolve PRs through the configured upstream remote and branch when a BB managed local branch has a different name - preserve distinct no-PR and unavailable GitHub CLI outcomes - add real-Git regression coverage for fork remotes, renamed branches, no-PR, authentication, and missing CLI cases - bump the host-daemon protocol to 97 so enrolled hosts receive the corrected lookup behavior ## Validation - pnpm exec turbo run test --filter=@bb/host-workspace --force - pnpm exec turbo run test --filter=@bb/host-daemon-contract --force - pnpm exec turbo run typecheck --filter=@bb/host-workspace - pnpm exec turbo run typecheck --filter=@bb/host-daemon-contract --filter=@bb/host-daemon - live read-only lookup against env_yikdjjfryt resolved get-bb#1236
551feeb to
daae198
Compare
Summary
Fixes #1235.
Claude background commands, workflows, and agents all live inside one Agent SDK session. bb previously treated execution-option drift as construction-time configuration, dispatched
thread/resume, and replaced that session. Alternating user/system turns therefore interrupted background work, and several other setting changes had the same destructive behavior.This PR makes reconfiguration provider-specific. Claude settings that can safely change in place now travel with each turn; only actual session-construction changes rebuild the provider session.
What changes
Agent/legacyTasktool chain, including SDK callbacks that omit agent metadata. Permission-request hooks provide an additional tool-level provenance boundary.setModelcontrol.applyFlagSettings, including transitions to and frommaxreasoning.Agent/legacyTaskandWorkflowtoggles are enforced live. They no longer depend on stale construction-timedisallowedTools, and disabling them rejects new launches without replacing the session or killing existing work.serviceTier: "fast"is normalized to"default"before validation, comparison, persistence, and provider command construction, so it cannot cause a rebuild or reach the Claude bridge.The permission path remains conservative: readonly enforcement resolves escalation at tool-call time, unsandboxed retries are automatically denied on escalation-denied turns, and that denial runs before cached session grants so an approval from an earlier user turn cannot leak into later system work.
The following remain session-scoped and still rebuild when changed:
HOST_DAEMON_PROTOCOL_VERSIONis bumped to 99 because the server no longer sends construction-time ClaudedisallowedToolsvalues for workflow/subagent settings. Version 98 is already used by qualified upstream PR lookup on the updated base.Validation
serviceTier: "fast"on both start and agent-origin steer. It retained one provider thread, preserved the background child's originalaskpolicy after the steer changed the current thread todeny, surfaced the dangerous write as a pending approval, and completed it afterallow_once.@bb/agent-runtime,@bb/server,@bb/host-daemon, and@bb/host-daemon-contract.bounds provider stderr while data arrives without a newlinelifecycle test, which is outside this diff.