Repository navigation
fix(agent-status): keep launch flags on a woken agent's record so a restart restores them - #33523
Conversation
…again Waking a sleeping terminal agent in its pane registers the pane's launch config and then clears the sleeping record it woke from. Clearing that record also deleted the launch config it had just registered, so the next sleep captured a record without it. The second wake then resumed the agent without its saved permission flags, custom args, and env. Clearing a sleeping record now clears only the record. The launch-config registry stays owned by pane retirement and the existing identity checks.
…ore resumes from Manual sleep now captures in main from the live PTY, so the regression that still reaches users is the live record a woken pane writes on its first launch-token hook; that record is what a restart cold-restores from.
Walkthrough
Priority: Merge Risk:
|
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to GitHub limitations.

Minor · Retain the consumed provider session in the launch-config… · agent-status-runtime.ts:187-216
src/renderer/src/store/slices/agent-status-runtime.ts:187-216
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick winRetain the consumed provider session in the launch-config identity.
clearSleepingAgentSessionsByPaneKeyremoves the sleeping record but leaves a token-only registry entry.registryEntryMatchesStatusreturnstruefor that entry after the launch-token check, before it can compareexistingProviderSession. A Pisession_startresume hook can provide a differentproviderSessionunder the same launch token, sorecordAgentProviderSessioncopies the old launch flags into the new session’s sleeping record. Cold restore can then relaunch that session with stale model or permission flags.When consuming the sleeping record, copy its
providerSessioninto the retained registry entry’s identity before deleting the record. The existing provider-session comparison will then preserve flags for the original session and reject registry reuse for a different session.Suggested fix
set((s) => { let nextSleeping = s.sleepingAgentSessionsByPaneKey + let nextLaunchConfigs = s.agentLaunchConfigByPaneKey for (const paneKey of uniquePaneKeys) { + const sleepingRecord = s.sleepingAgentSessionsByPaneKey[paneKey] if (paneKey in nextSleeping) { if (nextSleeping === s.sleepingAgentSessionsByPaneKey) { nextSleeping = { ...nextSleeping } } delete nextSleeping[paneKey] + const registryEntry = s.agentLaunchConfigByPaneKey[paneKey] + if (registryEntry && sleepingRecord) { + if (nextLaunchConfigs === s.agentLaunchConfigByPaneKey) { + nextLaunchConfigs = { ...nextLaunchConfigs } + } + nextLaunchConfigs[paneKey] = { + ...registryEntry, + identity: { + ...registryEntry.identity, + providerSession: sleepingRecord.providerSession + } + } + } } } - if (nextSleeping === s.sleepingAgentSessionsByPaneKey) { + if ( + nextSleeping === s.sleepingAgentSessionsByPaneKey && + nextLaunchConfigs === s.agentLaunchConfigByPaneKey + ) { return s } - return { sleepingAgentSessionsByPaneKey: nextSleeping } + return { + sleepingAgentSessionsByPaneKey: nextSleeping, + agentLaunchConfigByPaneKey: nextLaunchConfigs + } })

Review info
-
Run configuration-
- Source mode: Auto
- Repository: Unavailable
- Branch: Unavailable
- File: No configuration file from this repository applied
- Commit: Unavailable
- Layers: Repository UI
- Review profile: CHILL
- Plan: Advanced
- Run ID:
b587feaf-2520-4f29-9f7a-e1affd00a4db
Files selected for processing: 3-
src/renderer/src/store/slices/agent-status-provider-session.test.tssrc/renderer/src/store/slices/agent-status-quit-capture.test.tssrc/renderer/src/store/slices/agent-status-runtime.ts
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 0 remain after this review.
-
3beb493 to
10894d9
Compare
ELI5
You start Claude with your own flags (say
--dangerously-skip-permissions --model haiku), sleep the workspace, and wake it. The woken agent runs with your flags. But if Orca restarts after that wake (an update, a reboot, a crash), the restored agent comes back as a bareclaude --resume <id>: on the default model, and without bypass permissions. Orca erased the pane's saved flags at the moment it woke.This takes the smallest part of #31756 by @Jinwoo-H (STA-11575). Their two commits are kept as written, plus one test commit.
Root cause
When a pane wakes in place, it registers its launch config (registry entry, keyed by launch token) and then consumes the sleeping record it resumed from. The consume step,
clearSleepingAgentSessionsByPaneKey(agent-status-runtime.ts), deleted the registry entry too, so the config the pane had just registered was gone. A moment later the agent's first hook arrives carrying the launch token (Claude sendsSessionStartat startup).recordAgentProviderSessionthen looks for a matching registry entry, finds none, and writes the pane's live record with nolaunchConfig. That live record is the one persisted and used for cold restore.Why main hides this until a restart: since #31564, a manual sleep is captured in main from the live PTY's
launchConfig(worktree-sleep-resume-recording.ts), so sleep→wake→sleep→wake keeps the flags. The renderer's live record is still the cold-restore source after a quit, and it is the record that loses them.What changed
clearSleepingAgentSessionsByPaneKeyclears only sleeping records. Launch configs still retire with the pane (removeAgentStatus*,dropAgentStatus*,dropHibernatedAgentStatusPane,retireAgentPaneAuthority, worktree-level clears). A stale entry can't attach to a different launch, becauseregistryEntryMatchesStatusrequires the launch token and provider session to match. fix(agent-status): keep saved launch flags when a woken agent sleeps again #31756 has the full audit of everyclearSleepingAgentSession*caller.launchConfigon its live record. It fails on main and passes with the fix.Left out of #31756 on purpose: the
resumedProviderSessioncapture-only field (its commits 3–4). It covered renderer sleep capture (captureSleepingAgentSessionsByWorktree) for a Codex pane that sleeps before its first prompt. Production no longer calls that capture, because main captures sleeps now. Every Codex hook carries the launch token (hook-envelope.ts). Codex runsSessionStartonly inside the first turn (codex-rs/core/src/session/turn.rs:341→hook_runtime.rs:129), and until then the renderer has no provider session for the pane to capture anyway. If the orchestrator wants that path covered too, it can be a follow-up.How verified
Real Orca dev build (background, isolated HOME /
CLAUDE_CONFIG_DIR/ profile), real Claude Code 2.1.310, flags--dangerously-skip-permissions --model haiku:claude --dangerously-skip-permissions --model haiku... --model haiku --resume <id>launchConfig: null--dangerously-skip-permissions --model haiku{}claude --resume <id>: Opus default, "auto mode on"claude --dangerously-skip-permissions --model haiku --resume <id>: Haiku, "bypass permissions on"Argv was read from the process table, and each screen was checked with a CDP screenshot.
pnpm tc:web,pnpm run check:code-quality:changed: passpnpm test src/renderer/src/store/slices/agent-status src/renderer/src/components/terminal-pane/pty-connection ...: 97 files, 1352 tests pass, plus the terminal-pane suites that touch the registry.Risk
Low. 3 files, about 40 lines. The only behavior change is that a registry entry outlives the consume of its pane's sleeping record. Pane retirement still removes it, and token/identity matching gates any reuse. Remote, SSH, mobile, and folder workspaces use the same renderer store path, with no platform-specific code.
Co-authored-by: Jinwoo Hong 73622457+Jinwoo-H@users.noreply.github.com