Fix main's red app-host shards and intermittent CI failures
Summary
Main's app-host shards 2, 3 and 5 have been red on every run since #20248 merged. This fixes the causes and four intermittent failures seen in the same runs.
Real regression from #20246: a stale Codex record could resume a dead session on restore. #20246 treats an agent as running when the session index isn't authoritative, so a cached quit index can't mark a live session stopped. It read that authority from isComplete(). For Codex, that is also false whenever the panel's recorded checkpoint fails verification. So a fresh index holding only a rejected stale record left wasAgentRunning nil, and restore queued the dead current binding's resume command (SurfaceResumeAgentBindingGenerationTests: hasInitialInput: true). Authority now comes from whether the kind's hook store was observed (observesEveryLiveSession(forKind:)) in both the workspace and Dock snapshot paths, which is what #20246 meant. A cached markingIncomplete() index and an unreadable store still count as not authoritative, so #20246's Claude liveness case is unchanged.
Stale tests:
MuseVaultRegistrationTestsexpected an unquotedmuse resume …. Registered agents have quoted each argument and added acd --prefix since August. It now asserts the exact command, like the Pi, RovoDev and Hermes vault tests.GhosttyMinimumContrastLayerBackgroundTests.darkTextOnLightThemeStaysDarknever renders on Blacksmith (draws=0 visible=false): the app-host process isn't the active app there, so the window is never key or reported visible. It passes on owned minis.ScrollbackTestTerminalcan now opt into a window that reports.visibleocclusion, asSimulatorPanelThemeTestsalready does.
Intermittent failures:
cmuxd-remotedispatchcould returncontext.Canceledinstead of the queued attach write error, because theselectcould see the cancellation first (TestStdioRPCAsyncAttachWriteFailureInterruptsReadLoop).TestWebSocketPTYReplacedAttachmentCannotWriteInput: macOSshcan print a job-control warning betweenSIZE:andstty's output. Oneprintfnow writes both.repeatedWorkerPastesPreservePayload: four jobs share one FIFO whose 5s deadline starts at admission, so a slow runner expired the fourth. This test checks payload fidelity, so its deadline now ends only on cancellation.testUnreadChangeUpdatesOnlyAffectedSidebarRow: an unrelatedWorkspaceupdate inside the measured window re-evaluatedWorkspaceContentView. The test now counts those updates and allows exactly that many. The ContentView and sidebar checks stay strict.
Cloud window test: CloudWorkspaceCreationRevealTests "Closing the window during ⌘N releases its manager…" failed because of when the test checked, not because of a leak. The Cloud create path holds the manager only weakly. The test checked it in the same main-actor job as commitMainWindowClose, while the close's own notification (whose object is the manager) and the cleanup it queued on the main queue still held it. It now runs the close in an autorelease pool and waits one main-queue turn, with the create still blocked, before checking.
Claude project-directory fixtures: claudeRestorableIndexMapsNestedTranscriptPathToProjectCwd failed on runners whose temp path contains _. The fixture built the Claude project directory name by replacing only / and ., but Claude replaces every character that isn't a letter or digit. Four test files now share one slug helper that matches Claude's rule.
Testing
python3 scripts/verify-local.py: 17/17 checks passed. App-host tests and Go tests run in this PR's CI; local test runs aren't allowed here.- The red results on main are in run 38511822800.
- This PR at c217589161: all 64 checks pass. The changed-suites job ran 832 tests in 48 suites, all passing, including the Cloud window test (both cases), the Muse vault test,
darkTextOnLightThemeStaysDarkon Blacksmith, the sidebar unread test, and the Claude project-directory test.remote-daemon-macos-testspassed with the dispatch fix.SurfaceResumeAgentBindingGenerationTestsis in a full app-host shard, not the changed-suites job, so its first run will be on main after merge.
Changelog
Fixed: A restored Codex terminal no longer re-runs an ended session's resume command when its saved checkpoint couldn't be verified
🤖 Generated with Claude Code