Repository navigation
A slept native-chat workspace reads asleep and hides - #28457
Conversation
4f5bd1f to
9d4018c
Compare
d4779c1 to
3f08225
Compare
|
Sleep already stops native chat agents, but retained chat tabs keep the workspace looking awake and visible under “Hide sleeping workspaces.” This PR saves explicit Sleep on the execution host. Slept workspaces hide and stay asleep across restart; opening shows history, and an admitted new message wakes the chat through the existing send path. Full review completed on CI: full PR workflow 39542491347, attempt 2 passed on this exact head, including Windows packaging and aggregate PR checks passed. Named integration tests passed 210 tests; the test-only project-boundary correction passed 16 affected tests. The first corrected-head CI attempt timed out starting an unchanged Windows fixture; the owner's single failed-job rerun passed. Final-head M4Air QA passed with real Claude and Codex: explicit Sleep stopped both, no failure toast, moon/accessibility Sleeping, hide in both styles, opening retained Sleep, and a real Claude wake/reply retained its name and visibility for 20 seconds. Restart observation recorded zero slept-row insertions/visible frames across 3,132 frames and continuous mutations for 60 seconds, through the first host answer at 5.2 seconds. Show sleeping restored Codex's original mark. The owner accepted these gates; the rig was cleaned. Prior saved-profile main-versus-branch upgrade/restart and two replies per agent remain historical coverage, not new-head claims. Intended behavior: an identified unanswered host stays unknown; an unidentified legacy owner stays awake/visible; old hosts stop without marking; a prior confirmed Sleep survives a later failed Sleep. Existing Interrupted/Unread attention and whole-workspace teardown-owner refusal remain. Existing review-refresh, palette/shortcut and hidden-notification preferences now also apply to slept chats. Not exercised live: all stop-failure/race/internal-move cases, multi-host/twin/subtree/phone/dashboard triggers, real old/disconnected hosts, configured setup scripts and every phone/CLI/worker/Vault route. The PR body maps these to named tests or source-only evidence. Notification and review-refresh tests cover their existing policies; their slept-chat combinations were source-traced. These limits follow the lane owner's QA scope disposition. For Brennan's review Historical main after Sleep with Hide sleeping: Final-head before Sleep, sleeping presentation, wake/reply and restart reveal: Three judgment points: proved-stop marking, wake in the existing admission transaction, and naming metadata leaves unanswered Sleep unknown. |
06217f7 to
1d79a56
Compare
3f08225 to
786fb00
Compare
685ac16 to
ba9385a
Compare
8166736 to
e77be71
Compare
e77be71 to
f284818
Compare
|
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:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Priority: ➖ Normal Merge Risk: 🟡 Moderate · up to
|
There was a problem hiding this comment.
Actionable comments posted: 1
🔇 Additional comments: 45
src/shared/workspace-chat-sleep-schema.ts: 1
1-14: LGTM!src/shared/workspace-session-state-types.ts: 1
11-11: LGTM!Also applies to: 136-137
src/shared/workspace-chat-sleep.ts: 1
1-131: LGTM!src/shared/workspace-layout/workspace-layout-beside.ts: 1
46-46: LGTM!src/shared/workspace-layout/workspace-layout-fact-locations.test.ts: 1
152-154: LGTM!src/shared/workspace-layout/workspace-layout-round-trip.test.ts: 1
40-51: LGTM!src/shared/workspace-session-host-field-ownership.ts: 1
54-54: LGTM!Also applies to: 106-107
src/shared/workspace-session-schema-field-coverage.test.ts: 1
54-54: LGTM!Also applies to: 108-121
src/shared/workspace-session-schema.ts: 1
36-36: LGTM!Also applies to: 313-313
src/renderer/src/lib/workspace-session.ts: 1
62-62: LGTM!Also applies to: 102-102, 269-269, 282-289, 336-338
src/renderer/src/lib/workspace-session-patch.ts: 1
195-197: LGTM!src/renderer/src/lib/workspace-session-relevant-fields.test.ts: 1
38-38: LGTM!src/renderer/src/lib/workspace-session-host-split.test.ts: 1
117-119: LGTM!src/shared/wsl-move/wsl-move-dispositions.ts: 1
138-141: LGTM!src/main/orca-profiles/profile-project-session-field-disposition.ts: 1
120-123: LGTM!src/main/orca-profiles/profile-project-session-field-disposition.test.ts: 1
264-264: LGTM!Also applies to: 279-279
src/main/orca-profiles/profile-project-session-state.test.ts: 1
9-9: LGTM!Also applies to: 17-71
src/main/orca-profiles/profile-project-session-state.ts: 1
126-133: LGTM!src/main/persistence/migrating-orcad-catalog/orcad-source-release-upgrade.test.ts: 1
238-240: LGTM!Also applies to: 244-244
src/main/persistence/migrating-orcad-catalog/orcad-source-workspace-session.ts: 1
167-168: LGTM!src/main/persistence/restoring-sessions/session-owner-fields.test.ts: 1
66-66: LGTM!Also applies to: 68-69, 77-81, 91-93
src/main/persistence/restoring-sessions/session-owner-fields.ts: 1
10-15: LGTM!Also applies to: 19-21, 25-27, 100-102, 104-105
src/main/persistence/restoring-sessions/session-worktree-ownership.ts: 1
53-54: LGTM!src/main/persistence/tracking-repos/worktree-identity-migration-field-coverage.test.ts: 1
209-223: LGTM!src/main/persistence/tracking-repos/worktree-identity-migration.ts: 1
12-12: LGTM!Also applies to: 193-194
src/shared/workspace-chat-sleep.test.ts: 1
1-31: LGTM!src/renderer/src/store/slices/worktree-helpers.ts: 1
47-50: LGTM!Also applies to: 113-123
src/renderer/src/store/slices/worktrees/session/worktree-slice-initial-state.ts: 1
13-13: LGTM!Also applies to: 36-36
src/renderer/src/store/slices/worktrees/session/workspace-chat-sleep.ts: 1
1-81: LGTM!src/renderer/src/store/slices/worktrees.ts: 1
6-6: LGTM!Also applies to: 74-74
src/renderer/src/store/slices/worktrees/session/set-active-worktree.ts: 1
21-21: LGTM!Also applies to: 120-123, 142-142, 168-171
src/renderer/src/store/slices/worktrees/session/worktree-identity-rename-state.ts: 1
10-10: LGTM!Also applies to: 227-238
src/renderer/src/store/slices/tabs/tabs-close-actions.ts: 1
19-19: LGTM!Also applies to: 111-129, 177-179
src/renderer/src/store/slices/tabs/tabs-session-actions.ts: 1
14-14: LGTM!Also applies to: 97-103, 107-108, 113-136
src/renderer/src/store/slices/worktrees-workspace-selection-state.test.ts: 1
3-3: LGTM!Also applies to: 60-97
src/renderer/src/store/slices/worktrees/teardown/remove-worktree-store-cleanup.ts: 1
10-10: LGTM!Also applies to: 92-95
src/renderer/src/store/slices/worktrees/teardown/worktree-purge-state.ts: 1
14-14: LGTM!Also applies to: 63-66, 160-163
src/renderer/src/store/slices/worktrees/teardown/purge-stale-runtime-host-state.ts: 1
2-2: LGTM!Also applies to: 22-25, 220-220, 222-231, 276-276
src/renderer/src/store/slices/purge-stale-runtime-host-state.test.ts: 1
198-213: LGTM!src/renderer/src/store/slices/worktrees/teardown/remove-worktree-map-identity.test.ts: 1
28-28: LGTM!Also applies to: 69-69, 84-88, 97-99
src/renderer/src/store/terminals/workspace-terminal-hydration-patch.ts: 1
21-21: LGTM!Also applies to: 169-170
src/renderer/src/runtime/web-session-tabs-sync/apply-final-patch.ts: 1
10-10: LGTM!Also applies to: 94-98, 112-115
src/renderer/src/runtime/web-session-tabs-sync/state.ts: 1
243-243: LGTM!src/renderer/src/store/terminals/workspace-terminal-hydration.ts: 1
171-172: 🗄️ Data Integrity & IntegrationNo production pull caller reaches this branch. The only production invocation of
hydrateWorkspaceSessionis startup hydration insrc/renderer/src/app-shell/use-app-startup-hydration.ts:202, and it passes startup replacement options. The stale-map overwrite through an SSH pull is therefore not reachable from the inspected source, so no change is required here.src/shared/tab-types.ts-73-73: 1
73-73: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
⚠️ Unverified finding
Verification ran but could not confirm this finding. It is shown for review, not as a verified issue.Remove the orphaned JSDoc comment.
Line 73 describes a client-only field ("When Sleep stopped this chat's agent; activating its workspace clears it.").
Tabdoes not declare that field. The Sleep state lives inexplicitlySleptChatsByWorkspaceinstead. The comment now sits directly above theviewModeJSDoc. TypeScript tooling can attach both comments toviewMode, so hover text and generated docs describeviewModeincorrectly.Proposed fix
agentSessionAgent?: AgentType - /** When Sleep stopped this chat's agent; activating its workspace clears it. Client-only. */ /** Why: per-tab rendering mode for coding-agent terminals. `'chat'` shows the
ℹ️ Review info
⚙️ Run configuration
- Configuration used: Repository UI
- Review profile: CHILL
- Plan: Advanced
- Run ID:
619eeaae-8a57-46dd-9419-2997b16710c0
📒 Files selected for processing: 64
src/main/orca-profiles/profile-project-session-field-disposition.test.tssrc/main/orca-profiles/profile-project-session-field-disposition.tssrc/main/orca-profiles/profile-project-session-state.test.tssrc/main/orca-profiles/profile-project-session-state.tssrc/main/persistence/migrating-orcad-catalog/orcad-source-release-upgrade.test.tssrc/main/persistence/migrating-orcad-catalog/orcad-source-workspace-session.tssrc/main/persistence/restoring-sessions/session-owner-fields.test.tssrc/main/persistence/restoring-sessions/session-owner-fields.tssrc/main/persistence/restoring-sessions/session-worktree-ownership.tssrc/main/persistence/tracking-repos/worktree-identity-migration-field-coverage.test.tssrc/main/persistence/tracking-repos/worktree-identity-migration.tssrc/renderer/src/components/native-chat/StructuredAgentSessionStatusBridge.test.tsxsrc/renderer/src/components/native-chat/StructuredAgentSessionStatusBridge.tsxsrc/renderer/src/components/sidebar/sleep-worktree-flow.test.tssrc/renderer/src/components/sidebar/sleep-worktree-flow.tssrc/renderer/src/components/sidebar/use-visible-workspace-kanban-worktree-ids.tssrc/renderer/src/components/sidebar/use-worktree-context-menu-model.tsxsrc/renderer/src/components/sidebar/use-worktree-sleep-state.test.tsxsrc/renderer/src/components/sidebar/use-worktree-sleep-state.tssrc/renderer/src/components/sidebar/visible-worktree-activity-inputs.tssrc/renderer/src/components/sidebar/visible-worktree-options-from-state.tssrc/renderer/src/components/sidebar/workspace-lineage-menu-actions.test.tssrc/renderer/src/components/sidebar/workspace-lineage-menu-actions.tssrc/renderer/src/components/sidebar/worktree-context-menu-policy.tssrc/renderer/src/components/sidebar/worktree-list/listing/use-filters.tssrc/renderer/src/components/sidebar/worktree-list/listing/use-visible-worktrees.tssrc/renderer/src/components/use-worktree-jump-palette-store-state.tssrc/renderer/src/components/use-worktree-jump-palette-worktrees.tssrc/renderer/src/lib/workspace-session-host-split.test.tssrc/renderer/src/lib/workspace-session-patch.tssrc/renderer/src/lib/workspace-session-relevant-fields.test.tssrc/renderer/src/lib/workspace-session.tssrc/renderer/src/lib/worktree-activity-state.tssrc/renderer/src/runtime/web-session-tabs-sync/apply-final-patch.tssrc/renderer/src/runtime/web-session-tabs-sync/state.tssrc/renderer/src/store/slices/agent-status-live-facts.tssrc/renderer/src/store/slices/purge-stale-runtime-host-state.test.tssrc/renderer/src/store/slices/tabs/tabs-close-actions.tssrc/renderer/src/store/slices/tabs/tabs-session-actions.tssrc/renderer/src/store/slices/worktree-helpers.tssrc/renderer/src/store/slices/worktrees-workspace-selection-state.test.tssrc/renderer/src/store/slices/worktrees.tssrc/renderer/src/store/slices/worktrees/session/set-active-worktree.tssrc/renderer/src/store/slices/worktrees/session/workspace-chat-sleep.tssrc/renderer/src/store/slices/worktrees/session/worktree-identity-rename-state.tssrc/renderer/src/store/slices/worktrees/session/worktree-slice-initial-state.tssrc/renderer/src/store/slices/worktrees/teardown/purge-stale-runtime-host-state.tssrc/renderer/src/store/slices/worktrees/teardown/remove-worktree-map-identity.test.tssrc/renderer/src/store/slices/worktrees/teardown/remove-worktree-store-cleanup.tssrc/renderer/src/store/slices/worktrees/teardown/worktree-purge-state.tssrc/renderer/src/store/terminals/workspace-terminal-hydration-patch.tssrc/renderer/src/store/terminals/workspace-terminal-hydration.tssrc/shared/tab-types.tssrc/shared/workspace-chat-sleep-schema.tssrc/shared/workspace-chat-sleep.test.tssrc/shared/workspace-chat-sleep.tssrc/shared/workspace-layout/workspace-layout-beside.tssrc/shared/workspace-layout/workspace-layout-fact-locations.test.tssrc/shared/workspace-layout/workspace-layout-round-trip.test.tssrc/shared/workspace-session-host-field-ownership.tssrc/shared/workspace-session-schema-field-coverage.test.tssrc/shared/workspace-session-schema.tssrc/shared/workspace-session-state-types.tssrc/shared/wsl-move/wsl-move-dispositions.ts
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 4 remain after this review.
The fact "the user's Sleep put this chat to rest" now lives on the host that runs the chat, on its session record, instead of in the window. - New runtime capability agent-session.workspace-sleep-mark.v1 and an optional markAsleep on agentSession.sleepWorkspace (strict params, so only hosts advertising the capability are sent it). - The Sleep close decides each chat's receipt inside the same per-session step that stopped it; with markAsleep it writes sleptAt in that step's record write, so a chat is marked exactly when it is in the receipt. - The next send the host hands over clears sleptAt, whichever client sent it; the idle sweep and plain stops never mark. - sleptAt rides the status summary (optional field), its equality, and the retained summary of a closed chat, so it survives restart through the persisted tab index.
…ow record The window no longer keeps its own saved record of which chats Sleep stopped (explicitlySleptChatsByWorkspace). That record had to mirror every host event that should end it (sends, replaced conversations, renames, profile and WSL moves, removal, wakes during teardown), and each missed mirror was a bug. The host now owns the fact (previous commit). - Delete the record, its schema, store slice, workspace-session field registrations, moves, renames, purges, migrations and hydration, and the renderer clearing hooks. Those files are back to main. - Opening a workspace no longer wakes its slept chats (product ruling): drop the chat Sleep-attempt tokens and their set-active-worktree hook. A slept chat wakes only when a send reaches its host, from any client. - The status bridge mirrors each chat tab's published sleptAt into a store map keyed by the chat's pane key, dropped when its projection unmounts and never saved; a chat whose host runs it again is not slept. - The asleep derivation, hide filter, palette, board and context menu read that map. Explicit Sleep sends markAsleep only to the local host and to hosts last probed with the new capability; a project move never does.
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
- Configuration used: Repository UI
- Review profile: CHILL
- Plan: Advanced
- Run ID:
e3a377f6-e254-48b2-8ff1-92a3db3b6662
📒 Files selected for processing: 43
docs/reference/agent-browser-focus-isolation.mdsrc/main/native-chat/agent-session-wire/structured-agent-session-client-delivery.tssrc/main/native-chat/agent-session-wire/structured-agent-session-host.tssrc/main/native-chat/agent-session-wire/structured-agent-session-mutation-turn-context.tssrc/main/native-chat/agent-session-wire/structured-agent-session-status-feed-conversation-name.test.tssrc/main/native-chat/agent-session-wire/structured-agent-session-status-feed.tssrc/main/native-chat/agent-session-wire/structured-agent-session-status-summary-equality.tssrc/main/native-chat/agent-session-wire/structured-agent-session-status-summary.tssrc/main/native-chat/agent-session-wire/structured-agent-session-turns.tssrc/main/native-chat/agent-session-wire/structured-agent-session-workspace-sleep-lifetime.test.tssrc/main/native-chat/agent-session-wire/structured-agent-session-workspace-sleep.tssrc/main/runtime/rpc/methods/structured-agent-session-workspace-sleep.test.tssrc/main/runtime/rpc/methods/structured-agent-session.tssrc/renderer/src/components/native-chat/StructuredAgentSessionStatusBridge.test.tsxsrc/renderer/src/components/native-chat/StructuredAgentSessionStatusBridge.tsxsrc/renderer/src/components/sidebar/sleep-workspace-chat-stop.tssrc/renderer/src/components/sidebar/sleep-worktree-flow.test.tssrc/renderer/src/components/sidebar/sleep-worktree-flow.tssrc/renderer/src/components/sidebar/use-visible-workspace-kanban-worktree-ids.tssrc/renderer/src/components/sidebar/use-worktree-context-menu-model.tsxsrc/renderer/src/components/sidebar/use-worktree-sleep-state.test.tsxsrc/renderer/src/components/sidebar/use-worktree-sleep-state.tssrc/renderer/src/components/sidebar/visible-worktree-activity-inputs.tssrc/renderer/src/components/sidebar/visible-worktree-options-from-state.tssrc/renderer/src/components/sidebar/workspace-lineage-menu-actions.test.tssrc/renderer/src/components/sidebar/workspace-lineage-menu-actions.tssrc/renderer/src/components/sidebar/worktree-context-menu-policy.tssrc/renderer/src/components/sidebar/worktree-list/listing/use-filters.tssrc/renderer/src/components/sidebar/worktree-list/listing/use-visible-worktrees.tssrc/renderer/src/components/use-worktree-jump-palette-store-state.tssrc/renderer/src/components/use-worktree-jump-palette-worktrees.tssrc/renderer/src/lib/sidebar-shadow/workspace-activity-shadow.tssrc/renderer/src/store/index.tssrc/renderer/src/store/slices/store-test-helpers.tssrc/renderer/src/store/slices/structured-chat-slept-at.tssrc/renderer/src/store/types.tssrc/shared/agent-session-record-stored-form.test.tssrc/shared/agent-session-record-stored-form.tssrc/shared/agent-session-record.tssrc/shared/agent-session-wire.tssrc/shared/agent-session-workspace-sleep.tssrc/shared/protocol-version.tssrc/shared/rpc-contract/structured-agent-session-params.ts
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 6 remain after this review.
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
- Configuration used: Repository UI
- Review profile: CHILL
- Plan: Advanced
- Run ID:
934d7bf7-773f-477d-85fa-e4f3012d68be
📒 Files selected for processing: 19
src/main/native-chat/agent-session-wire/structured-agent-session-queued-messages.tssrc/main/native-chat/agent-session-wire/structured-agent-session-queued-mutations.tssrc/main/native-chat/agent-session-wire/structured-agent-session-queued-wiring.tssrc/main/native-chat/agent-session-wire/structured-agent-session-workspace-sleep-lifetime.test.tssrc/main/native-chat/agent-session-wire/structured-agent-session-workspace-sleep-queued.test.tssrc/main/native-chat/agent-session-wire/structured-agent-session-workspace-sleep.tssrc/main/runtime/rpc/methods/structured-agent-session-status-stream.test.tssrc/main/runtime/rpc/methods/structured-agent-session-status-stream.tssrc/renderer/src/components/native-chat/StructuredAgentSessionStatusBridge.test.tsxsrc/renderer/src/components/native-chat/StructuredAgentSessionStatusBridge.tsxsrc/renderer/src/components/native-chat/structured-chat-sleep-projection.tssrc/renderer/src/components/native-chat/structured-chat-sleep-startup.test.tsxsrc/renderer/src/components/sidebar/use-worktree-sleep-state.tssrc/renderer/src/components/sidebar/visible-worktree-activity-inputs.tssrc/renderer/src/components/sidebar/workspace-lineage-menu-actions.test.tssrc/renderer/src/components/sidebar/workspace-lineage-menu-actions.tssrc/renderer/src/runtime/structured-agent-session-status-feed.test.tssrc/renderer/src/runtime/structured-agent-session-status-feed.tssrc/renderer/src/store/slices/structured-chat-slept-at.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.
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
- Configuration used: Repository UI
- Review profile: CHILL
- Plan: Advanced
- Run ID:
ab0669e8-4336-48ec-8f3a-8ab1a5ad5d7d
📒 Files selected for processing: 17
src/main/native-chat/agent-session-wire/structured-agent-session-conversation-lifetime.tssrc/main/native-chat/agent-session-wire/structured-agent-session-queued-messages.tssrc/main/native-chat/agent-session-wire/structured-agent-session-queued-wiring.tssrc/main/native-chat/agent-session-wire/structured-agent-session-workspace-sleep-lifetime.test.tssrc/main/native-chat/agent-session-wire/structured-agent-session-workspace-sleep-stop.tssrc/main/native-chat/agent-session-wire/structured-agent-session-workspace-sleep.tssrc/main/runtime/agent-session-operation-receipt.tssrc/main/runtime/agent-session-record-store.tssrc/main/runtime/agent-session-store-transactions.tssrc/renderer/src/components/native-chat/structured-chat-sleep-startup.test.tsxsrc/renderer/src/components/right-sidebar/AiVaultSessionRow.structured-title.test.tsxsrc/renderer/src/components/sidebar/use-visible-workspace-kanban-worktree-ids.test.tsxsrc/renderer/src/components/sidebar/use-worktree-sleep-state.test.tsxsrc/renderer/src/components/sidebar/workspace-lineage-menu-actions.test.tssrc/renderer/src/components/sidebar/workspace-lineage-menu-actions.tssrc/renderer/src/runtime/structured-agent-session-status-feed.test.tssrc/renderer/src/runtime/structured-agent-session-status-feed.ts
💤 Files with no reviewable changes: 2
- src/renderer/src/components/sidebar/use-worktree-sleep-state.test.tsx
- src/renderer/src/runtime/structured-agent-session-status-feed.ts
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 6 remain after this review.





ELI5
After Sleep stops a workspace's native chats, the workspace still looks awake and stays listed under “Hide sleeping workspaces.” A retained chat tab currently counts as awake even after its agent stops.
This change makes an explicitly slept chat workspace read asleep and hide under that filter. It stays asleep across app restarts. Opening it shows its history without waking it; sending a new message wakes it through the existing send path.
What Changed
The machine running each chat saves
sleptAton that chat's session record when an explicit Sleep proves it stopped. Its existing status feed publishes that optional field. The window keeps an unsaved projection and derives the existing sleeping indicator, filter, board, search and Sleep availability from it.A newly admitted message from any client clears the saved mark. Held drafts clear it only when submitted. Merely opening a workspace, restoring history, an idle shutdown or moving a project to WSL does not write or clear Sleep.
While restored chats await their host's first answer, their sleep state is unknown and they wait to appear under Hide sleeping. Known answers survive disconnection. Hosts without the new capability receive the existing stop request without the new parameter; those chats remain awake. Failed stops continue through the remaining chats and use the existing single toast. If an earlier Sleep already confirmed a chat stopped, a later failed Sleep keeps that earlier confirmed state; the workspace can remain asleep and hidden. This is intended: the failed request does not erase the host's last confirmed state.
A legacy chat whose host cannot be identified keeps its workspace awake and visible under Hide sleeping, as on main. Once its host is known, that host’s actual Sleep state applies. This is intended.
Why
An idle or absent chat process does not mean the user chose Sleep. The execution host stores that explicit fact with the chat, so another client's new message can clear it and a restart can restore it. This replaces the earlier saved window record and wake-on-open behavior.
Differences from the common pattern are intended: explicit workspace Sleep also coordinates terminals and chats across publishing hosts, so only a proved stop can mark a chat. Existing startup and send behavior stays on its normal path.
Linked Issue
Reported in the workspace Sleep discussion. The stopping behavior is tracked in merged PR #28445; this PR adds sleeping presentation and visibility.
Visual Proof
The saved-profile comparison below ran on M4Air: main
3be5039eed0aversus branch75fdf27bb05e. It covered the same chats/profile through main restart and branch upgrade/restart. Both Claude and Codex produced two real replies after restart, one from the desktop composer and one from an independent authenticated WebSocket client. Held drafts, queued submission, replay, both card styles, board, palette, batch Sleep, folder exemptions and default terminal recreation were exercised.Main after Sleep with Hide sleeping enabled:
Branch with the same saved inventory and filter:
On that branch head, a fresh-profile restart passed continuous document-mutation observation for 60 seconds (3,561 frames, zero target-row insertions or visible samples through the first host answer). Opening retained history and the saved Sleep mark; a real composer send replied and restored visibility. Opening can run the existing model-list probe without resuming the saved conversation.
Sleep during a running Codex turn stopped its process, saved the mark and hid it in both card styles for 20 seconds each. A real send/reply cleared the mark and kept it visible. When shown, its card retained Interrupted · Unread because existing attention takes precedence over Sleeping; quiet slept chats show Sleeping.
Final-head real Electron QA passed on exact
cbb493eon M4Air (ticket 1016, isolated profile, real Claude and Codex through the load balancers). Context-menu Sleep stopped both providers with no failure toast. New cards showed the moon and accessible Sleeping label; both card styles hid the workspaces. Opening retained history and Sleep. A real Claude send cleared Sleep, replied, retained the chat name and stayed visible under Hide sleeping for 20 seconds. Restart preserved Codex's original mark: a pre-document mutation observer plus 3,132 frames over 60 seconds recorded zero slept-row insertions or visible frames, including the first host answer at 5.2 seconds. Show sleeping revealed the retained row. The moon plus accessible label is the existing rendering; no visible tooltip is required. Existing Interrupted/Unread attention still takes precedence over Sleeping.The QA lead verified cleanup of all recorded processes and listeners and removed its throwaway profiles. The report is
/Users/m4air/orca-qa/pr-28457/final-cbb493e/REPORT.md; the lane owner accepted F1/F2 on this head. Earlier saved-profile upgrade/restart, two real replies per agent, queue/replay and running-Codex Sleep evidence is historical and is not relabelled as final-head execution.Current-head captures:
Testing
Full review path: saved lifecycle, process-stop receipts, startup ordering and optional mixed-version host data require full review and real QA.
Current head:
cbb493eb24ba7bfd6c4409fbc090bf76f63f62c8, with merged-main parentf7c07409d6e8f453b4e8ae7459e0267ffa993ff4. Integration preserves main's chat naming/skill behavior and host-owned Sleep. Main's naming-only snapshot cannot resolve unanswered Sleep state; an actual-event regression failed before that correction and passed afterward. Before the final line-budget consolidation, 12 named suites passed 210 tests. The initial merged-head workflow failed because the new renderer regression imported host-only modules. Test-only follow-upcbb493eremoves those imports, preserves the shared protocol regression and pins the actual publisher in its host suite; production is unchanged. The two affected suites passed all 16 tests, and normal commit hooks passed. Fresh independent final integration/reference/readiness review passed on this exact head with no open proven defect. The full PR workflow 39542491347 is green on this exact head (attempt 2), including Windows packaging job 119037527462 and aggregate “PR checks passed” job 119039534804. The first attempt timed out waiting for an unchanged Windows test fixture; the lane owner reran its failed jobs once, and they passed. No source change or additional retry was made. Owner-run exact-head QA passed as recorded above. Earlier broader QA remains explicitly historical.The full loop corrected separate send/mark writes, a history-reopen race and failed first-contact handling. New sends clear Sleep inside the existing journal transaction; a host-memory admission count supersedes stale stop receipts; first contact remains unknown until the actual host answers. No send startup gate was added. Earlier architecture/correctness/presentation, security, performance and compatibility reviews are recorded in the loop; the final independent check verifies their integration on the new head.
Not exercised live; automated contracts and source review provide the remaining evidence:
structured-agent-session-workspace-sleep-lifetime.test.tsandstructured-agent-session-queued-action-receipts.test.ts; real remote/error timing is not certified.sleep-worktree-flow.test.ts,sleep-twin-confirmation.test.ts,workspace-lineage-menu-actions.test.ts; individual dashboard/phone menu triggers were source-traced, not exercised live.structured-agent-session-status-feed.test.tsandstructured-chat-sleep-startup.test.tsx; mocked transport, not a real old or disconnected remote host.hidden-workspace-notification-mute.test.tscovers existing filter/notification policy;workspace-reference-refresh-targets.test.tscovers the existing scheduler/owner selection. Applying these policies to a slept chat was source-traced, not exercised live or asserted by a new end-to-end test.The lane owner's accepted QA scope distinguishes these from the live core path. An independent WebSocket client is transport coverage, not shipped phone UI or CLI coverage.
Review
The new admission-race thread was independently refuted and resolved: normal Send, Send-now and automatic queue drain all hold the same per-session queue through receipt commit, and the final Sleep operation holds that queue through its awaited store write. An earlier send invalidates the Sleep receipt; a later send clears the mark. No extra guard or production change was needed. The lane owner’s single failed-job rerun and final-head QA passed.
The earlier saved-window design was replaced with the execution host's persisted fact. The full review loop, independent final integration/reference check, full CI and owner-accepted real-agent QA are complete on the current head. The original status comment is updated in place with the exact-head marker; no new comment was created. No open proven defect or unresolved review thread remains. Unmeasured scale/performance concerns remain disclosed in the private source report; no benchmark or all-platform live guarantee is claimed.
Agent skill upstream boundary
Notes
Intended existing policies now apply to slept chats: linked-review refresh can pause even while history is selected; shortcut/palette membership follows visible rows while typed search can reveal slept workspaces; disabling Notify About Hidden Workspaces can mute notifications for hidden slept chats. These policies and defaults are unchanged.
The existing whole-workspace twin model, terminal teardown-owner refusal and host-owned status rows remain. Folder workspaces and paired/SSH execution were source-reviewed; their individual remote UI flows were not all exercised live. No minimum server version is introduced.
Checklist