Propagate runtime approval policy and sandbox mode to thread turn startup#100
Propagate runtime approval policy and sandbox mode to thread turn startup#100juliusmarminge merged 10 commits intomainfrom
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughAdds optional Changes
Sequence Diagram(s)sequenceDiagram
participant Client as ChatView
participant Decider as Decider
participant Reactor as ProviderCommandReactor
participant Provider as Provider Session
participant Ingest as ProviderRuntimeIngestion
Client->>Decider: dispatch thread.turn.start(approvalPolicy, sandboxMode)
Decider->>Reactor: sendTurnForThread(..., approvalPolicy, sandboxMode)
Reactor->>Provider: ensureSessionForThread -> check existing session
alt session exists & policy/mode unchanged
Reactor->>Provider: reuse session
else session exists & policy/mode changed
Reactor->>Provider: stop session
Reactor->>Provider: start session(approvalPolicy, sandboxMode)
else no session
Reactor->>Provider: start session(approvalPolicy, sandboxMode)
end
Provider-->>Reactor: session details
Reactor->>Ingest: emit thread.session.set(..., approvalPolicy, sandboxMode)
Ingest->>Ingest: update projections / persistence with new fields
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes 🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Autofix Details
Bugbot Autofix prepared a fix for the issue found in the latest run.
- ✅ Fixed: Existing session ignores runtime mode changes
- Added in-memory tracking of per-thread session runtime settings (approvalPolicy/sandboxMode) so that when ensureSessionForThread detects the requested settings differ from the stored ones, it stops the old session and creates a new one with the updated configuration.
Or push these changes by commenting:
@cursor push 9ee36a6e77
Preview (9ee36a6e77)
diff --git a/apps/server/src/orchestration/Layers/ProviderCommandReactor.ts b/apps/server/src/orchestration/Layers/ProviderCommandReactor.ts
--- a/apps/server/src/orchestration/Layers/ProviderCommandReactor.ts
+++ b/apps/server/src/orchestration/Layers/ProviderCommandReactor.ts
@@ -127,6 +127,11 @@
return readModel.threads.find((entry) => entry.id === threadId);
});
+ const sessionRuntimeSettings = new Map<
+ string,
+ { approvalPolicy?: ProviderApprovalPolicy; sandboxMode?: ProviderSandboxMode }
+ >();
+
const ensureSessionForThread = Effect.fnUntraced(function* (
threadId: ThreadId,
createdAt: string,
@@ -143,7 +148,15 @@
const existingSessionId = thread.session?.providerSessionId;
if (existingSessionId) {
- return existingSessionId;
+ const stored = sessionRuntimeSettings.get(threadId);
+ const runtimeModeChanged =
+ (options?.approvalPolicy !== undefined &&
+ options.approvalPolicy !== stored?.approvalPolicy) ||
+ (options?.sandboxMode !== undefined && options.sandboxMode !== stored?.sandboxMode);
+ if (!runtimeModeChanged) {
+ return existingSessionId;
+ }
+ yield* providerService.stopSession({ sessionId: existingSessionId });
}
const preferredProvider: ProviderKind | undefined =
@@ -163,6 +176,11 @@
...(options?.sandboxMode !== undefined ? { sandboxMode: options.sandboxMode } : {}),
});
+ sessionRuntimeSettings.set(threadId, {
+ approvalPolicy: options?.approvalPolicy,
+ sandboxMode: options?.sandboxMode,
+ });
+
yield* setThreadSession({
threadId,
session: {
@@ -314,6 +332,8 @@
yield* providerService.stopSession({ sessionId });
}
+ sessionRuntimeSettings.delete(thread.id);
+
yield* setThreadSession({
threadId: thread.id,
session: {e33ca5f to
8916262
Compare
aedb803 to
5fdf30b
Compare

Summary
approvalPolicyandsandboxModetothread.turn.startcommand andthread.turn-start-requestedpayload contracts.ChatViewto derive runtime settings fromruntimeMode(full-access=>never+danger-full-access, otherwiseon-request+workspace-write).Testing
apps/server/src/orchestration/decider.projectScripts.test.ts: verifiesthread.turn-start-requestedincludesapprovalPolicyandsandboxMode.apps/server/src/orchestration/Layers/ProviderCommandReactor.test.ts: verifiesstartSessionreceivesapprovalPolicyandsandboxMode.Note
Medium Risk
Touches turn-start/session lifecycle and persistence (contracts, provider session management, projections, and a DB migration), so regressions could break turn dispatch or session reuse/restart behavior; changes are scoped and covered by updated tests.
Overview
Propagates runtime controls by making
approvalPolicyandsandboxModerequired onthread.turn.startand carrying them intothread.turn-start-requestedandOrchestrationSessionso the values are visible end-to-end.Updates
ProviderCommandReactorto pass these settings intoproviderService.startSession, persist them onto the thread session, and restart the provider session when either setting changes (otherwise reuse the existing session).Persists the new fields in
projection_thread_sessions(adds columns via a new migration, projects them inProjectionPipeline, and hydrates them inProjectionSnapshotQuery). The webChatViewnow derives the two fields fromruntimeModewhen dispatching turn start, and tests are updated/expanded to assert propagation and session restart behavior.Written by Cursor Bugbot for commit 7d0226c. This will update automatically on new commits. Configure here.
Note
Propagate
approvalPolicyandsandboxModethroughthread.turn.startand persist them in projection-backed session reads across server and web dispatch pathsAdd required
approvalPolicyandsandboxModetoThreadTurnStartCommand, forward them viadeciderintothread.turn-start-requested, ensureProviderCommandReactor.makestarts/restarts sessions based on these fields, and persist them via projection repositories and migration. Update UI dispatch to include these fields based on runtime mode.📍Where to Start
Start with
processTurnStartRequestedand session handling in ProviderCommandReactor.ts, then review event emission in decider.ts and projection persistence in ProjectionThreadSessions.ts.Macroscope summarized 7d0226c.
Summary by CodeRabbit