test(serve): pin zero duplicate agent resumes across headless serve desktop promotion (#12666)

STA-1716 reported that a packaged `orca serve` could become the single-instance owner after the desktop app exits, leaving Dock/Finder unable to restore a window — and that forcing a reopen made the headless process hydrate a renderer that interrupted and DUPLICATED live agent sessions.

Verification against main found every criterion already fixed (#8646 for desktop promotion and the fail-closed CLI, #12212 for duplicate serve activation, #12574 + #9729 for the resume/ownership guards). The genuine gap was criterion 6: the ticket's own automated regression never existed. An existing reliability gate asserted PTY identity survives promotion, but nothing asserted what the incident was actually about — how many agents the promoted renderer resumes.

This adds that coverage: a unit/service-level journey that drives the real single-instance lock, activation gate, settle and focus paths, then runs the real resume logic against a store seeded as a renderer freshly mounted inside the serve process, asserting zero duplicate resumes.

`settleServeDesktopActivation` moved from `index.ts` into its own module with identical semantics, so the test drives the real decision rather than re-implementing it — the earlier repro had to mirror that logic locally, which is the "test passes without running the scenario" failure mode.

Proven to be a real oracle: breaking each guard individually turns it red, and reverting the pre-#12574 pane form reproduces the incident exactly (two duplicate `codex resume` tabs).
This commit is contained in:
Jinwoo Hong
2026-08-05 00:34:10 -07:00
committed by GitHub
parent e233d6a641
commit 84df99e2f1
5 changed files with 344 additions and 9 deletions
+7 -6
View File
@@ -174,7 +174,10 @@ import {
} from './startup/startup-diagnostics'
import { ensureWindowsUserDataAclGrant } from './startup/windows-user-data-acl'
import { shouldQuitWhenAllWindowsClosed } from './startup/window-all-closed-quit-policy'
import { createServeDesktopActivationGate } from './startup/serve-desktop-activation'
import {
createServeDesktopActivationGate,
settleServeDesktopActivation as settleServeDesktopActivationGate
} from './startup/serve-desktop-activation'
import { RateLimitService } from './rate-limits/service'
import { readMiniMaxSessionCookie } from './minimax/minimax-cookie-store'
import { getInitialClaudeRateLimitTarget } from './rate-limits/claude-rate-limit-target'
@@ -630,11 +633,9 @@ function getDesktopWindowStatus(): RuntimeDesktopWindowStatus {
}
function settleServeDesktopActivation(): void {
if (getLocalPtyProvider() instanceof LocalPtyProvider) {
desktopActivationGate.markBlocked('persistent PTY provider unavailable')
return
}
desktopActivationGate.markReady()
settleServeDesktopActivationGate(desktopActivationGate, {
hasPersistentPtyProvider: !(getLocalPtyProvider() instanceof LocalPtyProvider)
})
}
// Why: webContents-scoped auto-expiring flag so an intent can't leak to a later renderer load; `consume` clears on match for one-shot signals.
@@ -9,6 +9,24 @@ export type ServeDesktopActivationGate = {
markBlocked: (reason: string) => void
}
export const SERVE_DESKTOP_ACTIVATION_BLOCKED_REASON = 'persistent PTY provider unavailable'
/**
* Why: promotion is only safe when serve owns daemon-backed (persistent) PTYs —
* the desktop renderer then reattaches the surviving sessions instead of
* cold-restoring them. Without that provider, fail closed (#8457).
*/
export function settleServeDesktopActivation(
gate: ServeDesktopActivationGate,
options: { hasPersistentPtyProvider: boolean }
): void {
if (!options.hasPersistentPtyProvider) {
gate.markBlocked(SERVE_DESKTOP_ACTIVATION_BLOCKED_REASON)
return
}
gate.markReady()
}
export function createServeDesktopActivationGate(options: {
initialState: 'initializing' | 'ready'
activateWindow: () => void