From 20b4e1b6d78e5bebf86f76829bf84e10f950a024 Mon Sep 17 00:00:00 2001 From: OrcaWin <293788423+OrcaWin@users.noreply.github.com> Date: Thu, 12 Nov 2026 21:56:16 -0800 Subject: [PATCH] test: remove simulated mobile and worker observation pipelines --- config/flaky-test-pattern-baseline.txt | 1 - .../scripts/ci/sharding/ci-shard-timings.json | 2 - .../worker-interactive-wait.test.ts | 134 ---------- .../lifecycle/mobile-session-dead-pty.test.ts | 232 ------------------ 4 files changed, 369 deletions(-) delete mode 100644 src/main/runtime/rpc/methods/orchestration/worker/observation/worker-interactive-wait.test.ts delete mode 100644 src/main/runtime/terminal/lifecycle/mobile-session-dead-pty.test.ts diff --git a/config/flaky-test-pattern-baseline.txt b/config/flaky-test-pattern-baseline.txt index ce2660684da..74d59db41c9 100644 --- a/config/flaky-test-pattern-baseline.txt +++ b/config/flaky-test-pattern-baseline.txt @@ -480,7 +480,6 @@ 1 test-no-wall-clock:src/main/runtime/rpc/methods/agent-launch/agent-launch-replay.test.ts 1 test-no-wall-clock:src/main/runtime/rpc/methods/orchestration/federation/federation-output.test.ts 2 test-no-wall-clock:src/main/runtime/rpc/methods/orchestration/worker/observation/fleet-status-observed-identity.test.ts -1 test-no-wall-clock:src/main/runtime/rpc/methods/orchestration/worker/observation/worker-interactive-wait.test.ts 1 test-no-wall-clock:src/main/runtime/rpc/methods/orchestration/worker/output/worker-output.test.ts 2 test-no-wall-clock:src/main/runtime/rpc/server/remote-runtime-request-connection.integration.test.ts 2 test-no-wall-clock:src/main/runtime/rpc/server/runtime-rpc-pairing-mode-persistence.test.ts diff --git a/config/scripts/ci/sharding/ci-shard-timings.json b/config/scripts/ci/sharding/ci-shard-timings.json index 05694083e28..99963c77012 100644 --- a/config/scripts/ci/sharding/ci-shard-timings.json +++ b/config/scripts/ci/sharding/ci-shard-timings.json @@ -2979,7 +2979,6 @@ "src/main/runtime/push/notifications/mobile-notification-replay.test.ts": 43, "src/main/runtime/rpc/server/pairing/mobile-pairing-userdata-path.test.ts": 171, "src/main/runtime/terminal/layout/mobile-presence-lock.test.ts": 25928, - "src/main/runtime/terminal/lifecycle/mobile-session-dead-pty.test.ts": 4708, "src/main/runtime/session-tabs/headless-editor-tabs.test.ts": 57, "src/main/runtime/session-lifecycle/publication/mobile-session-tabs-agent-status-heartbeat.test.ts": 65, "src/main/runtime/terminal/surface/mobile-session-terminal-persistence-retirement.test.ts": 278, @@ -3270,7 +3269,6 @@ "src/main/runtime/rpc/methods/orchestration/worker/release/worker-auto-release-turns.test.ts": 3578, "src/main/runtime/rpc/methods/orchestration/worker/release/worker-auto-release.test.ts": 4863, "src/main/runtime/rpc/methods/orchestration/worker/follow-up/worker-follow-up.test.ts": 4916, - "src/main/runtime/rpc/methods/orchestration/worker/observation/worker-interactive-wait.test.ts": 5579, "src/main/runtime/rpc/methods/orchestration/worker/fleet/worker-list-pagination.test.ts": 4740, "src/main/runtime/rpc/methods/orchestration/worker/output/worker-output.test.ts": 541, "src/main/runtime/rpc/methods/orchestration/worker/release/worker-release-authority-contracts.test.ts": 3949, diff --git a/src/main/runtime/rpc/methods/orchestration/worker/observation/worker-interactive-wait.test.ts b/src/main/runtime/rpc/methods/orchestration/worker/observation/worker-interactive-wait.test.ts deleted file mode 100644 index 19f23d68467..00000000000 --- a/src/main/runtime/rpc/methods/orchestration/worker/observation/worker-interactive-wait.test.ts +++ /dev/null @@ -1,134 +0,0 @@ -// Drive real detector/plumbing through RPC to distinguish workers waiting on human prompts (STA-3714, STA-4513). -import { readFileSync } from 'node:fs' -import { join } from 'node:path' -import { afterEach, describe, expect, it, vi } from 'vitest' -import { OrcaRuntimeService } from '../../../../../orca-runtime' -import { OrchestrationDb } from '../../../../../orchestration/db/orchestration-db' -import '../../../../../orchestration/db/contract-constants' -import '../../../../../orchestration/db/messages/mailbox-routing-page' -import '../../../../../orchestration/db/dispatch-row-writer' -import '../../../../../orchestration/db/attempt-outcome-projection' -import { ORCHESTRATION_METHODS } from '../../orchestration' -import { createRootDispatch } from '../../../../../orchestration/db/root-dispatch-test-fixture' - -vi.mock('electron', () => ({ - BrowserWindow: { fromId: vi.fn(() => null) }, - webContents: { fromId: vi.fn(() => null) }, - ipcMain: { on: vi.fn(), removeListener: vi.fn() }, - app: { getPath: vi.fn(() => '/tmp') } -})) - -const LEAF_ID = '22222222-2222-4222-8222-222222222222' -const TAB_ID = 'tab-worker' -const WORKTREE_ID = 'wt-worker' -const PTY_ID = 'pty-worker' - -// Captured verbatim from cursor-agent 2026.08.11-e8db854 driven through Orca. -function fixture(name: string): string { - return readFileSync(join(__dirname, '../../../../../__fixtures__', `${name}.txt`), 'utf8') -} - -function workerShowMethod() { - const method = ORCHESTRATION_METHODS.find( - (candidate) => candidate.name === 'orchestration.workerShow' - ) - if (!method) { - throw new Error('Missing method orchestration.workerShow') - } - return method -} - -describe('worker-show interactive wait (STA-3714, STA-4513)', () => { - let db: OrchestrationDb | undefined - - afterEach(() => db?.close()) - - async function showWorkerPaneServing(paneOutput: string, opts?: { breakIdentity?: boolean }) { - const runtime = new OrcaRuntimeService(null) - const internals = runtime as unknown as { - resolveTerminalWorkspaceLaunchScope: (selector: string) => Promise - } - vi.spyOn(internals, 'resolveTerminalWorkspaceLaunchScope').mockResolvedValue({ - id: WORKTREE_ID, - path: '/repo/app', - connectionId: null, - repo: null, - folderWorkspace: null - }) - runtime.setPtyController({ - spawn: vi.fn().mockResolvedValue({ id: PTY_ID, incarnationId: 'inc-1' }), - write: () => true, - kill: () => true, - getForegroundProcess: async () => 'cursor-agent' - }) - const terminal = await runtime.createTerminal(`id:${WORKTREE_ID}`, { - tabId: TAB_ID, - leafId: LEAF_ID, - title: 'worker' - }) - runtime.attachWindow(1) - runtime.syncWindowGraph(1, { - tabs: [ - { - tabId: TAB_ID, - worktreeId: WORKTREE_ID, - title: 'worker', - activeLeafId: LEAF_ID, - layout: null - } - ], - leaves: [ - { - tabId: TAB_ID, - worktreeId: WORKTREE_ID, - leafId: LEAF_ID, - paneRuntimeId: 1, - ptyId: PTY_ID, - // cursor-agent's spinner title, identical whether it runs or waits. - paneTitle: '⠇ Cursor Agent' - } - ] - }) - runtime.onPtyData(PTY_ID, paneOutput, Date.now()) - - db = new OrchestrationDb(':memory:') - runtime.setOrchestrationDb(db) - const run = db.createRun({ - objective: 'supervise lanes', - coordinatorHandle: 'term_coord', - coordinatorPaneKey: 'tab_coord:leaf_coord' - }) - const task = db.createTask({ spec: 'run the suite', runId: run.id }) - const paneKey = runtime.getTerminalPaneKey(terminal.handle) - const incarnation = runtime.getTerminalProcessIncarnation(terminal.handle) - if (!paneKey || !incarnation) { - throw new Error('Runtime did not expose the worker pane identity.') - } - const dispatch = createRootDispatch( - db, - task.id, - terminal.handle, - paneKey, - 'launch-hash', // A dispatch recorded against a process that has since been replaced. - opts?.breakIdentity === true ? `${incarnation}:replaced` : incarnation - ) - - const method = workerShowMethod() - return method.handler(method.params?.parse({ dispatch: dispatch.id }), { runtime }) - } - - it('names the pending prompt on the observation a coordinator polls', async () => { - const result = await showWorkerPaneServing(fixture('cursor-agent-approval-prompt')) - - expect(result).toMatchObject({ - observation: { - exactWorker: true, - agentWait: { - source: 'prompt-text', - reason: 'agent-approval-prompt', - since: expect.any(Number) - } - } - }) - }) -}) diff --git a/src/main/runtime/terminal/lifecycle/mobile-session-dead-pty.test.ts b/src/main/runtime/terminal/lifecycle/mobile-session-dead-pty.test.ts deleted file mode 100644 index e7004f46437..00000000000 --- a/src/main/runtime/terminal/lifecycle/mobile-session-dead-pty.test.ts +++ /dev/null @@ -1,232 +0,0 @@ -import { expect, it, vi } from 'vitest' -import { rmSync } from 'node:fs' -import { DaemonPtyAdapter } from '../../../daemon/providers/adapter/daemon-pty-adapter' -import { DaemonPtyRouter } from '../../../daemon/providers/routing/daemon-pty-router' -import { DegradedDaemonPtyProvider } from '../../../daemon/providers/routing/degraded-daemon-pty-provider' -import { LocalPtyProvider } from '../../../providers/local-pty/local-pty-provider' -import { - createMockSubprocess, - startDaemonAdapterHarness, - waitFor -} from '../../../daemon/providers/adapter/testing/daemon-pty-adapter-test-harness' -import type { IPtyProvider } from '../../../providers/pty/provider-contract' -import { PtyWriteUnavailableError } from '../../../providers/pty/write-unavailable-error' - -await import('../../orca-runtime-tests/runtime-test-module-registration.spec') -await import('../../orca-runtime-tests/orca-runtime-test-lifecycle.spec') -await import('../../orca-runtime-tests/runtime-test-module-registration.spec') -const { OrcaRuntimeService } = await import('../../orca-runtime') -const { - HEADLESS_LEAF_ID, - TEST_WORKTREE_ID, - TEST_WORKTREE_PATH, - makeRuntimeStoreWithWorkspaceSession, - makeWorkspaceSessionWithHeadlessTerminal -} = await import('../../orca-runtime-tests/orca-runtime-test-fixtures.spec') - -const providerSession = { key: 'session_id' as const, id: 'codex-conversation' } - -function mobileChat(provider: IPtyProvider) { - const { runtimeStore } = makeRuntimeStoreWithWorkspaceSession( - makeWorkspaceSessionWithHeadlessTerminal() - ) - const runtime = new OrcaRuntimeService(runtimeStore) - const spawn = vi.fn() - const write = vi.fn(() => true) - runtime.setPtyController({ - spawn, - write, - kill: () => true, - getForegroundProcess: async () => null, - hasPty: (id) => provider.hasPty?.(id) ?? null, - getPtyAvailability: (id) => provider.getPtyAvailability?.(id) ?? null, - listProcesses: () => provider.listProcesses() - }) - runtime.attachWindow(1) - let snapshotVersion = 0 - const publish = (ptyId: string) => - runtime.syncWindowGraph(1, { - tabs: [ - { - tabId: 'host-tab', - worktreeId: TEST_WORKTREE_ID, - title: 'Codex', - activeLeafId: HEADLESS_LEAF_ID, - layout: null - } - ], - leaves: [ - { - tabId: 'host-tab', - worktreeId: TEST_WORKTREE_ID, - leafId: HEADLESS_LEAF_ID, - paneRuntimeId: 1, - ptyId, - paneTitle: 'Codex' - } - ], - mobileSessionTabs: [ - { - worktree: TEST_WORKTREE_ID, - publicationEpoch: 'renderer', - snapshotVersion: ++snapshotVersion, - activeGroupId: null, - activeTabId: 'host-tab', - activeTabType: 'terminal', - tabs: [ - { - type: 'terminal', - id: `host-tab::${HEADLESS_LEAF_ID}`, - parentTabId: 'host-tab', - leafId: HEADLESS_LEAF_ID, - ptyId, - title: 'Codex', - isActive: true, - agentStatus: { - agentType: 'codex', - state: 'waiting', - prompt: '', - updatedAt: 1, - stateStartedAt: 1, - stateHistory: [], - paneKey: `host-tab:${HEADLESS_LEAF_ID}`, - providerSession - } - } - ] - } - ] - }) - const read = () => runtime.listMobileSessionTabs(`id:${TEST_WORKTREE_ID}`) - const published = () => runtime['getMobileSessionTabsForWorktree'](TEST_WORKTREE_ID) - return { runtime, publish, read, published, spawn, write } -} - -it.each(['direct', 'router', 'degraded'] as const)( - 'keeps an unattached retained conversation ready, then withholds a gone PTY through %s', - async (route) => { - const subprocesses: ReturnType[] = [] - const harness = await startDaemonAdapterHarness(() => { - const subprocess = createMockSubprocess() - subprocesses.push(subprocess) - return subprocess - }) - const owner = new DaemonPtyAdapter(harness) - try { - await harness.adapter.spawn({ - sessionId: 'persisted-pty', - cwd: TEST_WORKTREE_PATH, - cols: 80, - rows: 24 - }) - harness.adapter.dispose() - const provider = - route === 'direct' - ? owner - : route === 'router' - ? new DaemonPtyRouter({ current: owner, legacy: [] }) - : new DegradedDaemonPtyProvider({ - current: owner, - legacy: [], - fallback: new LocalPtyProvider() - }) - const chat = mobileChat(provider) - chat.publish('persisted-pty') - const before = await chat.read() - expect(owner.hasPty('persisted-pty')).toBe(false) - expect(before.tabs[0]).toMatchObject({ status: 'ready', terminal: expect.any(String) }) - const original = before.tabs[0] - if (original?.type !== 'terminal') { - throw new Error('Expected the retained terminal') - } - - await owner.attach('persisted-pty') - expect((await chat.read()).tabs[0]).toHaveProperty('terminal', original.terminal) - expect(subprocesses).toHaveLength(1) - subprocesses[0]?._simulateExit(0) - await waitFor(() => !owner.hasPty('persisted-pty')) - expect((await chat.read()).tabs[0]).toMatchObject({ - status: 'pending-handle', - terminal: null - }) - chat.publish('persisted-pty') - expect(chat.published().tabs[0]).toMatchObject({ status: 'pending-handle', terminal: null }) - - await owner.spawn({ - sessionId: 'replacement-pty', - cwd: TEST_WORKTREE_PATH, - cols: 80, - rows: 24 - }) - chat.publish('replacement-pty') - const restored = (await chat.read()).tabs[0] - expect(restored).toMatchObject({ - id: original.id, - status: 'ready', - terminal: expect.any(String), - agentStatus: expect.objectContaining({ providerSession }) - }) - expect(restored).not.toHaveProperty('terminal', original.terminal) - expect(chat.spawn).not.toHaveBeenCalled() - expect(chat.write).not.toHaveBeenCalled() - expect(subprocesses.every((subprocess) => subprocess.write.mock.calls.length === 0)).toBe( - true - ) - } finally { - owner.dispose() - harness.adapter.dispose() - await harness.server.shutdown() - rmSync(harness.dir, { recursive: true, force: true }) - } - } -) - -it('withholds an attached PTY during endpoint recovery and restores its same conversation without replay', async () => { - const subprocess = createMockSubprocess() - const harness = await startDaemonAdapterHarness(() => subprocess) - const respawn = vi.fn(async () => {}) - const owner = new DaemonPtyAdapter({ ...harness, respawn }) - try { - await owner.spawn({ sessionId: 'persisted-pty', cwd: TEST_WORKTREE_PATH, cols: 80, rows: 24 }) - const chat = mobileChat(owner) - chat.publish('persisted-pty') - const original = (await chat.read()).tabs[0] - if (original?.type !== 'terminal') { - throw new Error('Expected the attached terminal') - } - expect(original.status).toBe('ready') - const unavailable = new Promise((resolve) => owner.onWriteUnavailable(() => resolve())) - owner['client'].disconnect() - expect(() => owner.write('persisted-pty', 'refused')).toThrow(PtyWriteUnavailableError) - await unavailable - expect(owner.hasPty('persisted-pty')).toBe(true) - expect(chat.published().tabs[0]).toMatchObject({ status: 'pending-handle', terminal: null }) - - // Successful inventory reconnects transport but does not clear the remount fence. - expect((await chat.read()).tabs[0]).toMatchObject({ status: 'pending-handle', terminal: null }) - await owner.attach('persisted-pty') - expect((await chat.read()).tabs[0]).toMatchObject({ - id: original.id, - status: 'ready', - terminal: original.terminal, - agentStatus: expect.objectContaining({ providerSession }) - }) - expect(subprocess.write).not.toHaveBeenCalled() - expect(chat.spawn).not.toHaveBeenCalled() - expect(chat.write).not.toHaveBeenCalled() - expect(respawn).not.toHaveBeenCalled() - - respawn.mockRejectedValue(new Error('daemon remains unavailable')) - await harness.server.shutdown() - await waitFor(() => owner.getDaemonIdentity() === null) - expect((await chat.read()).tabs[0]).toMatchObject({ status: 'pending-handle', terminal: null }) - expect(owner.hasPty('persisted-pty')).toBe(true) - expect(subprocess.write).not.toHaveBeenCalled() - expect(chat.spawn).not.toHaveBeenCalled() - } finally { - owner.dispose() - harness.adapter.dispose() - await harness.server.shutdown() - rmSync(harness.dir, { recursive: true, force: true }) - } -})