Each Orca Cloud create logs `[orca-cloud] create <creationId> <phase> +<ms>`
(ms since its provision started) to the main app log, so a slow create shows
which phase took the time. The provision's own `[orca-cloud] <stage>` progress
lines are unchanged.
Also folds the two identical post-start cleanup-and-fail blocks in the
provision handler into one helper (ephemeral-vm.ts was at the 300-line cap).
Quitting and reopening the app restored a running cloud terminal's saved
scrollback, then its reattach replayed the host's subscribe snapshot with a
clear - capped at the phone-sized 1000 rows - so everything above was gone.
Local panes survive the same clear because their daemon snapshot carries the
full 5000 rows.
Host side (runs in the VM; needs the dev golden rotation):
- the initial subscribe snapshot for a non-mobile stream tries 5000 rows
(DESKTOP_TERMINAL_SCROLLBACK_ROWS_DEFAULT) under a 2 MB raw budget (the same
a requested desktop snapshot already gets; snapshots are chunked), stepping
down 5000 -> 2000 -> 1000 -> ... when over; phones keep 1000 rows / 512 KB;
- ack-recovery snapshots after dropped output: desktop depth for non-mobile.
Renderer: a gap resync asks for desktop depth (the host caps by bytes).
journey-audit v2: the 'Claude isn't set up' toast followed the user through other workspaces and the sleep view. design-squad (PC-3 reversed on purpose): in the workspace the pane's Set up once strip asks; away, the sidebar row shows a key mark with the tooltip and aria-label 'Claude isn't set up for Orca Cloud' (or 'sign-in expired'). The away toast and its modules are removed. Toast-stack scoping (push notice) is env-check-ux's half.
Past 5 s the running Start sandbox row says what it is waiting on: 'Getting your project ready…'
(the desktop is still preparing, before the create is sent), 'Checking your plan…', 'Starting the
sandbox…', or 'Connecting to the sandbox…' (after the server answered). A normal start stays quiet.
Replaces the immediate phase detail (latestOrcaCloudPhaseLabel).
Two defects the real-app proof found:
- ~400 ms blank pane on attach: the woken terminal's fresh-spawn viewport
blanking ran before the snapshot drain. A pane with pre-sleep output to put
back now holds rendering (DEC 2026) there instead of blanking; it keeps its
greyed history until the restore rewrites it.
- History cut to ~880 rows: by "asleep" the transport had resubscribed and
replaced the buffer with the host's 1000-row snapshot, and the capture could
re-run on it. It now captures when sleep is asked for (going to sleep), once
per sleep (a later look only refines the start time), and arms only after
the workspace was actually asleep.
Sleep reboots the VM; the woken pane attaches to a new terminal whose snapshot
replay erases scrollback (`\x1b[3J`), so everything the pane showed was gone.
- Capture (asleep/waking, before the new terminal attaches): the pane's normal
buffer rendered from its cells as text + SGR only (never its escape stream),
capped at terminalScrollbackRows. Shell panes keep their visible rows too;
agent / full-screen panes (the #451 rule) keep only the scrollback above, so
no frozen TUI frame comes back. No live buffer (never mounted, restarted
while asleep): the plain-text read-only copy saved at sleep, uncoloured; none
at all: nothing restored, nothing said.
- Restore (once the workspace left "asleep"; the woken terminal's snapshot
drain): after the snapshot paints, a client-side rewrite of restored output,
the dim divider, then the woken screen, cursor put back with relative moves.
Nothing reaches the PTY (replay writer, replay guard); a final sanitizer keeps
only text and CSI…m (OSC 52/0, DECSET, bracketed paste, cursor moves dropped).
Pinned to the bottom unless the person had scrolled up. One divider per sleep.
- The kept output is dropped once restored, or when its pane / tab / workspace
goes away.
On cut 68321452c9 a shell pane running `sleep 900` woke with no "Woke up"
bar. The command printed nothing, so its prompt line was the last text and the
detector read it as idle / half-typed (a rule from the first JA-15 detector).
The capture now notes whether the cursor sat below the last text: Enter was
pressed on that prompt line, so the silent command is running and gets Rerun. A
half-typed line (cursor still on it) and a bare prompt still offer nothing; agent
launches and the orca-launch script are still never offered.
#402's fallback sent the raw settings.agentDefaultArgs string as agentArgs for a
pane with nothing recorded. The host takes explicit agentArgs verbatim and only
projects its launch profile (configured Arguments + permission choice) when none
are sent, so a pane launched as 'claude --dangerously-skip-permissions --model
opus --effort high' restarted as 'claude --model opus --effort high' (real-app,
pane's own process by marker, before/after). Project the defaults through
resolveTuiAgentLaunchRawArgs (the same projection a fresh launch uses), so the
permission choice is kept; with no default args nothing is sent, as before.