diff --git a/mobile/src/diagnostics/connection-diagnostics-analysis.test.ts b/mobile/src/diagnostics/connection-diagnostics-analysis.test.ts index 762d82b10d5..ab40b3511b2 100644 --- a/mobile/src/diagnostics/connection-diagnostics-analysis.test.ts +++ b/mobile/src/diagnostics/connection-diagnostics-analysis.test.ts @@ -98,23 +98,6 @@ describe('diagnoseConnection', () => { }) }) - it('marks authenticated Relay liveness failures as safe to send', () => { - expect( - diagnoseConnection({ - endpoint: 'ws://192.168.1.2:6768', - state: 'reconnecting', - activePath: 'relay', - entries: [ - { - ...event('Relay health check failed'), - code: 'liveness-timeout', - path: 'relay' - } - ] - }).reportability - ).toBe('orca-relay') - }) - it.each([ ['direct timeout', 'connect-timeout', 'tailscale'], ['handshake timeout', 'handshake-timeout', 'relay'], diff --git a/mobile/src/hooks/mobile-dictation-desktop-start.test.ts b/mobile/src/hooks/mobile-dictation-desktop-start.test.ts index 6fdd66a2354..8166028d2dd 100644 --- a/mobile/src/hooks/mobile-dictation-desktop-start.test.ts +++ b/mobile/src/hooks/mobile-dictation-desktop-start.test.ts @@ -150,26 +150,6 @@ describe('startMobileDictationDesktopSession', () => { }) }) - it('does not surface a desktop-start failure after the start became stale', async () => { - let setNewerStart = () => undefined - const harness = createStartHarness({ - sendRequest: async (method) => { - if (method === 'speech.dictation.start') { - setNewerStart() - throw new Error('Desktop start failed') - } - return OK_RESPONSE - } - }) - setNewerStart = harness.setNewerStart - - await expect(startMobileDictationDesktopSession(harness.options)).resolves.toBe(false) - - expect(harness.setIdle).not.toHaveBeenCalled() - expect(harness.getActiveId()).toBe('dictation-b') - expect(harness.commitRecordingStart).not.toHaveBeenCalled() - }) - it('commits recording before returning a current start to the hook', async () => { const harness = createStartHarness() diff --git a/mobile/src/mobile-web-shell/bridge/page-first-paint.test.tsx b/mobile/src/mobile-web-shell/bridge/page-first-paint.test.tsx index a397729a9e8..0699f330a2f 100644 --- a/mobile/src/mobile-web-shell/bridge/page-first-paint.test.tsx +++ b/mobile/src/mobile-web-shell/bridge/page-first-paint.test.tsx @@ -188,29 +188,4 @@ describe('which commit the page reports its frame from', () => { }) expect(reports).toBe(1) }) - - it('reports the screen that arrived and not the one that replaced it', async () => { - const route = deferredRouteChunk() - const Screen = lazy(() => route.chunk.then(withRouteScreenPaintReport)) - let reports = 0 - await act(async () => { - create( - { - reports += 1 - return () => undefined - }} - > - - - - - ) - }) - await act(async () => { - route.arrive() - }) - // Once per screen that commits: the shell latches the first, and a re-render is not a new one. - expect(reports).toBe(1) - }) }) diff --git a/mobile/src/mobile-web-shell/bridge/use-native-verbs.test.tsx b/mobile/src/mobile-web-shell/bridge/use-native-verbs.test.tsx index 9ce2cb04a91..77fcd9dd077 100644 --- a/mobile/src/mobile-web-shell/bridge/use-native-verbs.test.tsx +++ b/mobile/src/mobile-web-shell/bridge/use-native-verbs.test.tsx @@ -197,11 +197,6 @@ describe('a verb the shell refuses', () => { expect(reasons).toEqual(['native_verb_failed', 'reply-too-large', 'native_verb_result']) }) - it('names the frame refusal when the reply could never have reached the page', async () => { - const error = await rejectionFrom(() => Promise.resolve({ value: 'a'.repeat(9 * 1024 * 1024) })) - expect(error.reason).toBe('reply-too-large') - }) - it('names the grant when this side refused before sending', async () => { const page = createPageClient() page.deliver({ ...INIT, grants: { ...GRANTS, native: ['navigate'] } }) diff --git a/mobile/src/mobile-web-shell/catch-all-page-route.test.tsx b/mobile/src/mobile-web-shell/catch-all-page-route.test.tsx index 969157ff781..e4ab0593e5e 100644 --- a/mobile/src/mobile-web-shell/catch-all-page-route.test.tsx +++ b/mobile/src/mobile-web-shell/catch-all-page-route.test.tsx @@ -176,14 +176,6 @@ describe('the catch-all switch', () => { expect(dependencies.routes[0]?.params).toEqual({ tab: 'diff' }) }) - it('never carries its own segments back as query params', async () => { - // `useLocalSearchParams` merges the route params into the search params, and both of these are - // already in the pathname above. - dependencies.params = { hostId: 'host-1', page: ['settings'] } - await render() - expect(dependencies.routes[0]).not.toHaveProperty('params') - }) - it('refuses a deep link carrying more params than the bridge will take', async () => { // The schema bounds them, so `shellScreenRoute` answers null and the switch refuses. Dropping // the overflow instead would open the page on a screen missing the state it was asked for. diff --git a/mobile/src/tasks/composer-linked-work-item.test.ts b/mobile/src/tasks/composer-linked-work-item.test.ts index f3ce9299e92..faf5d80cd73 100644 --- a/mobile/src/tasks/composer-linked-work-item.test.ts +++ b/mobile/src/tasks/composer-linked-work-item.test.ts @@ -1,7 +1,4 @@ import { describe, expect, it } from 'vitest' -import type { GitHubWorkItem } from '../../../src/shared/github/work-item-types' -import type { GitLabWorkItem } from '../../../src/shared/gitlab-types' -import type { LinearIssue } from '../../../src/shared/linear/issue-types' import { buildGitHubLinkedWorkItem, buildGitLabLinkedWorkItem, @@ -240,6 +237,3 @@ describe('resolveComposerBranchPick', () => { expect(pick.base.branchNameOverride).toBeUndefined() }) }) - -// Keep the exported type aliases referenced so the module surface stays covered. -export type _Ref = [GitHubWorkItem, GitLabWorkItem, LinearIssue] diff --git a/mobile/src/tasks/workspace-source-reply-schema.test.ts b/mobile/src/tasks/workspace-source-reply-schema.test.ts index 30597e8e536..74ccecfbd04 100644 --- a/mobile/src/tasks/workspace-source-reply-schema.test.ts +++ b/mobile/src/tasks/workspace-source-reply-schema.test.ts @@ -256,15 +256,6 @@ describe('the orca.yaml hooks require nothing', () => { }) describe('sparse presets', () => { - it('reads the recorded preset, which carries no repoId or timestamps', () => { - const parsed = repoSparsePresetListSchema.safeParse({ - presets: [{ id: 'p1', name: 'docs', directories: ['docs'] }] - }) - expect(parsed.success && parsed.data).toEqual([ - { id: 'p1', name: 'docs', directories: ['docs'] } - ]) - }) - it('drops a preset with no id, which the picker could not select', () => { const parsed = repoSparsePresetListSchema.safeParse({ presets: [{ name: 'docs' }] }) expect(parsed.success && parsed.data).toEqual([]) diff --git a/mobile/src/transport/mobile-endpoint-supervisor-nudge.test.ts b/mobile/src/transport/mobile-endpoint-supervisor-nudge.test.ts index 86ea50e5c45..6fd90b8f86d 100644 --- a/mobile/src/transport/mobile-endpoint-supervisor-nudge.test.ts +++ b/mobile/src/transport/mobile-endpoint-supervisor-nudge.test.ts @@ -136,20 +136,6 @@ describe('mobile endpoint supervisor nudges', () => { supervisor.stop() }) - it('does not suspend a relay from one focus RPC failure', async () => { - const logical = new FakeLogicalClient('connected', 'relay') - const deps = dependencies() - const supervisor = new MobileEndpointSupervisor(logical, host.id, relay, deps) - await supervisor.start() - - supervisor.nudge('focus') - await vi.advanceTimersByTimeAsync(0) - expect(logical.suspendActiveSession).not.toHaveBeenCalled() - expect(deps.openRelay).not.toHaveBeenCalled() - expect(logical.getState()).toBe('connected') - supervisor.stop() - }) - it('queues a network replacement that lands while another dial owns the mutex', async () => { const logical = new FakeLogicalClient('disconnected', 'lan') let resolveWrite: (() => void) | null = null diff --git a/mobile/src/transport/mobile-web-bundle-compat.test.ts b/mobile/src/transport/mobile-web-bundle-compat.test.ts index 4fea3dab176..5a8f63501de 100644 --- a/mobile/src/transport/mobile-web-bundle-compat.test.ts +++ b/mobile/src/transport/mobile-web-bundle-compat.test.ts @@ -55,12 +55,6 @@ describe('evaluateMobileWebBundleCompat', () => { }) }) - it('separates permission to fetch a manifest from permission to open one', () => { - // Why: both are `ok`, and a caller that mounted on the first would mount an unchecked bundle. - expect(evaluate({ manifest: null })).toEqual({ kind: 'ok', manifestChecked: false }) - expect(evaluate({})).toEqual({ kind: 'ok', manifestChecked: true }) - }) - it('blocks a host that ships no bundle', () => { expect(evaluate({ hostCapabilities: ['browser.screencast.v1'] })).toEqual({ kind: 'blocked', diff --git a/mobile/src/transport/relay-host-signed-out-verdict.test.ts b/mobile/src/transport/relay-host-signed-out-verdict.test.ts index e27e241706c..ce0f01844ee 100644 --- a/mobile/src/transport/relay-host-signed-out-verdict.test.ts +++ b/mobile/src/transport/relay-host-signed-out-verdict.test.ts @@ -234,40 +234,4 @@ describe('classifyConnection with a signed-out desktop', () => { classifyConnection({ ...base, state: 'reconnecting', reconnectAttempts: 20 }).label ).toBe(SIGNED_OUT_LABEL) }) - - it('reads as stale once this session had been connected', () => { - expect( - classifyConnection({ ...base, state: 'reconnecting', lastConnectedAt: 1, nowMs: 2 }).reason - ).toBe('stale') - }) - - // A Tailscale endpoint cannot make "sign in on your desktop" better advice. - it('never appends the Tailscale hint', () => { - expect( - classifyConnection({ ...base, state: 'reconnecting', endpoint: '100.64.0.1' }) - ).not.toHaveProperty('hint') - }) - - it('never outranks a connected session', () => { - expect(classifyConnection({ ...base, state: 'connected' }).label).toBe('Connected') - }) - - // Re-pairing, not signing in, is the remedy when the pairing itself is dead. - it('never outranks a revoked pairing', () => { - expect(classifyConnection({ ...base, state: 'reconnecting', pairingRejected: true }).kind).toBe( - 'auth-failed' - ) - }) - - it('leaves every other verdict alone when the desktop is not signed out', () => { - expect( - classifyConnection({ - state: 'connecting', - reconnectAttempts: 0, - lastConnectedAt: null, - pendingPath: 'relay', - relayHostReachability: 'connecting' - }).label - ).toBe('Connecting via Relay…') - }) }) diff --git a/mobile/src/transport/rpc-client-stream-registry.test.ts b/mobile/src/transport/rpc-client-stream-registry.test.ts index 48c62af478d..c58b3d938f7 100644 --- a/mobile/src/transport/rpc-client-stream-registry.test.ts +++ b/mobile/src/transport/rpc-client-stream-registry.test.ts @@ -275,26 +275,6 @@ describe('RpcClientStreamRegistry', () => { }) }) - it('keeps a disposed browser tombstone until ready can be unsubscribed', () => { - const { registry, sent } = createRegistry() - const dispose = registry.subscribe('browser.screencast', { page: 'page-1' }, () => {}) - const request = sent[0]! - - dispose() - expect(sent).toHaveLength(1) - - registry.handleResponse( - streamingResponse(request.id, { - type: 'ready', - subscriptionId: 'browser-screencast:page-1:test' - }) - ) - expect(sent[1]).toMatchObject({ - method: 'browser.screencast.unsubscribe', - params: { subscriptionId: 'browser-screencast:page-1:test' } - }) - }) - it('releases a replayed browser stream replaced by a new one before its ready', () => { const { registry, sent } = createRegistry() registry.subscribe('browser.screencast', { page: 'page-1' }, () => {}) diff --git a/mobile/tests-typecheck-baseline.txt b/mobile/tests-typecheck-baseline.txt index ab63d955f7a..9d47b7ab801 100644 --- a/mobile/tests-typecheck-baseline.txt +++ b/mobile/tests-typecheck-baseline.txt @@ -115,7 +115,6 @@ src/transport/mobile-relay-rpc-session.test.ts src/transport/mobile-relay-runtime-failover.test.ts src/transport/pairing-relay-candidate.test.ts src/transport/pre-profile-pairing-coordinator.test.ts -src/transport/relay-host-signed-out-verdict.test.ts src/transport/rpc-client-synthesized-close-diagnostics.test.ts src/transport/rpc-operation.test.ts src/transport/rpc-session-liveness-watchdog.test.ts diff --git a/src/main/github/client-issue-source.test.ts b/src/main/github/client-issue-source.test.ts index d9c593be3a0..a4f8b646831 100644 --- a/src/main/github/client-issue-source.test.ts +++ b/src/main/github/client-issue-source.test.ts @@ -730,23 +730,6 @@ describe('GitHub issue source split', () => { expect(result.issueSourceFellBack).toBeUndefined() }) - it("preference='auto' + no upstream → queries origin", async () => { - resolveIssueSourceMock.mockResolvedValueOnce({ - source: { owner: 'solo', repo: 'orca' }, - fellBack: false - }) - getOwnerRepoMock.mockResolvedValueOnce({ owner: 'solo', repo: 'orca' }) - ghExecFileAsyncMock.mockResolvedValueOnce({ stdout: '[]' }).mockResolvedValueOnce({ - stdout: '[]' - }) - - await listWorkItems('/repo-root', 10, undefined, undefined, 'auto') - - expect(ghExecFileAsyncMock).toHaveBeenNthCalledWith(1, issueSearchArgs('solo/orca'), { - cwd: '/repo-root' - }) - }) - it("preference='auto' + upstream exists → PRs query upstream too", async () => { // Why: fork-contribution PRs live on the upstream repo — the fork's own // PR list is almost always empty. 'auto' must resolve PRs upstream-first @@ -799,22 +782,6 @@ describe('GitHub issue source split', () => { ) }) - it("preference='upstream' + upstream exists → queries upstream", async () => { - resolveIssueSourceMock.mockResolvedValueOnce({ - source: { owner: 'stablyai', repo: 'orca' }, - fellBack: false - }) - getOwnerRepoMock.mockResolvedValueOnce({ owner: 'fork', repo: 'orca' }) - ghExecFileAsyncMock.mockResolvedValueOnce({ stdout: '[]' }).mockResolvedValueOnce({ - stdout: '[]' - }) - - const result = await listWorkItems('/repo-root', 10, undefined, undefined, 'upstream') - - expect(decodedIssueSearchPath(0)).toContain('q=repo:stablyai/orca is:issue is:open') - expect(result.issueSourceFellBack).toBeUndefined() - }) - it("preference='upstream' + no upstream → falls back to origin with fellBack=true", async () => { resolveIssueSourceMock.mockResolvedValueOnce({ source: { owner: 'solo', repo: 'orca' }, @@ -831,36 +798,6 @@ describe('GitHub issue source split', () => { expect(result.issueSourceFellBack).toBe(true) }) - it("preference='origin' + upstream exists → queries origin (not upstream)", async () => { - resolveIssueSourceMock.mockResolvedValueOnce({ - source: { owner: 'fork', repo: 'orca' }, - fellBack: false - }) - getOwnerRepoMock.mockResolvedValueOnce({ owner: 'fork', repo: 'orca' }) - ghExecFileAsyncMock.mockResolvedValueOnce({ stdout: '[]' }).mockResolvedValueOnce({ - stdout: '[]' - }) - - await listWorkItems('/repo-root', 10, undefined, undefined, 'origin') - - expect(decodedIssueSearchPath(0)).toContain('q=repo:fork/orca is:issue is:open') - }) - - it("preference='origin' + no upstream → queries origin", async () => { - resolveIssueSourceMock.mockResolvedValueOnce({ - source: { owner: 'solo', repo: 'orca' }, - fellBack: false - }) - getOwnerRepoMock.mockResolvedValueOnce({ owner: 'solo', repo: 'orca' }) - ghExecFileAsyncMock.mockResolvedValueOnce({ stdout: '[]' }).mockResolvedValueOnce({ - stdout: '[]' - }) - - await listWorkItems('/repo-root', 10, undefined, undefined, 'origin') - - expect(decodedIssueSearchPath(0)).toContain('q=repo:solo/orca is:issue is:open') - }) - it('surfaces upstreamCandidate in sources regardless of effective preference', async () => { // Why: the renderer selector needs to keep rendering after the user picks // 'origin'. That requires the envelope to carry the raw upstream even diff --git a/src/main/github/client-pr-push-target.test.ts b/src/main/github/client-pr-push-target.test.ts index daaa05155ae..36fd97823f3 100644 --- a/src/main/github/client-pr-push-target.test.ts +++ b/src/main/github/client-pr-push-target.test.ts @@ -144,32 +144,6 @@ describe('getPRForBranch', () => { }) }) - it('omits maintainerCanModify when the API does not report the flag', async () => { - getOwnerRepoMock.mockResolvedValueOnce({ owner: 'stablyai', repo: 'orca' }) - getOwnerRepoForRemoteMock.mockResolvedValueOnce({ owner: 'stablyai', repo: 'orca' }) - ghExecFileAsyncMock.mockResolvedValueOnce({ - stdout: JSON.stringify({ - head: { - ref: 'fix-sidebar', - repo: { - full_name: 'stablyai/orca', - name: 'orca', - clone_url: 'https://github.com/stablyai/orca.git', - ssh_url: 'git@github.com:stablyai/orca.git', - owner: { login: 'stablyai' } - } - } - }) - }) - - await expect(getPullRequestPushTarget('/repo-root', 1738)).resolves.toEqual({ - pushTarget: { - remoteName: 'origin', - branchName: 'fix-sidebar' - } - }) - }) - it('uses origin for same-repository PR push targets', async () => { getOwnerRepoMock.mockResolvedValueOnce({ owner: 'stablyai', repo: 'orca' }) getOwnerRepoForRemoteMock.mockResolvedValueOnce({ owner: 'stablyai', repo: 'orca' }) diff --git a/src/main/github/gh-utils.test.ts b/src/main/github/gh-utils.test.ts index 5400eaeb565..c239dc026f2 100644 --- a/src/main/github/gh-utils.test.ts +++ b/src/main/github/gh-utils.test.ts @@ -149,16 +149,6 @@ describe('github owner/repo resolution', () => { expect(gitRemoteGetUrlCalls('origin')).toHaveLength(1) }) - it('prefers upstream for issue owner/repo resolution', async () => { - mockGitRemoteCommands({ - origin: 'git@github.com:fork/orca.git\n', - upstream: 'git@github.com:stablyai/orca.git\n' - }) - - await expect(getIssueOwnerRepo('/repo')).resolves.toEqual({ owner: 'stablyai', repo: 'orca' }) - expect(gitRemoteGetUrlCalls('upstream')).toHaveLength(1) - }) - it('falls back to origin when upstream is present but non-GitHub', async () => { mockGitRemoteCommands({ origin: 'git@github.com:fork/orca.git\n', diff --git a/src/main/github/github-repository-identity.fork-owner-repo.test.ts b/src/main/github/github-repository-identity.fork-owner-repo.test.ts index e0cd7de6ca4..9c6f2a21159 100644 --- a/src/main/github/github-repository-identity.fork-owner-repo.test.ts +++ b/src/main/github/github-repository-identity.fork-owner-repo.test.ts @@ -30,7 +30,7 @@ vi.mock('./local-git-config-signature', () => ({ import { _resetRemoteNameListingCache } from '../git/remote-name-listing' import { getOwnerRepoForRemote, _resetOwnerRepoCache } from './github-repository-identity' -import { getOwnerRepo, getIssueOwnerRepo } from './github-owner-repo-selection' +import { getOwnerRepo } from './github-owner-repo-selection' import { getRepoUpstream } from './client' const FORK_PATH = '/tmp/fork-checkout' @@ -84,13 +84,6 @@ describe('issue #7331: fork PR owner/repo resolution', () => { expect(prRepo).toEqual({ owner: 'stablyai', repo: 'orca' }) }) - it('getOwnerRepo and getIssueOwnerRepo agree on a fork checkout', async () => { - const prRepo = await getOwnerRepo(FORK_PATH) - const issueRepo = await getIssueOwnerRepo(FORK_PATH) - - expect(prRepo).toEqual(issueRepo) - }) - it('getOwnerRepo falls back to origin when there is no upstream remote', async () => { const prRepo = await getOwnerRepo(NON_FORK_PATH) diff --git a/src/main/github/work-item-details.test.ts b/src/main/github/work-item-details.test.ts index 11a063b51ba..3ec1a5a4d9f 100644 --- a/src/main/github/work-item-details.test.ts +++ b/src/main/github/work-item-details.test.ts @@ -708,76 +708,6 @@ describe('getWorkItemDetails', () => { expect(getWorkItemMock).toHaveBeenCalledWith('/repo-root', 42, 'pr', null, {}, 'origin') }) - // Why: a rate-limited/auth-failed file fetch must not render as an empty PR; - // the Files tab keys its retry state off details.filesUnavailable. - it('flags filesUnavailable when the PR file fetch fails but leaves the PR empty otherwise intact', async () => { - getWorkItemMock.mockResolvedValueOnce({ - id: 'pr:8305', - type: 'pr', - number: 8305, - title: 'Files fetch fails', - state: 'open', - url: 'https://github.com/acme/widgets/pull/8305', - labels: [], - updatedAt: '2026-07-11T00:00:00Z', - author: 'pr-author' - }) - getOwnerRepoForRemoteMock.mockResolvedValue({ owner: 'acme', repo: 'widgets' }) - getPRCommentsMock.mockResolvedValue([]) - getPRChecksMock.mockResolvedValue([]) - ghExecFileAsyncMock.mockImplementation(async (args: string[]) => { - const target = args.at(-1) - if (target === 'repos/acme/widgets/pulls/8305') { - return { - stdout: JSON.stringify({ head: { sha: 'head-sha' }, base: { sha: 'base-sha' } }) - } - } - if (target === 'repos/acme/widgets/pulls/8305/files?per_page=100') { - throw new Error('gh: API rate limit exceeded (403)') - } - return { stdout: JSON.stringify({ data: {} }) } - }) - - const details = await getWorkItemDetails('/repo-root', 8305, 'pr') - - expect(details?.filesUnavailable).toBe(true) - expect(details?.files).toBeUndefined() - }) - - it('treats an empty file list as a genuinely empty PR, not an unavailable one', async () => { - getWorkItemMock.mockResolvedValueOnce({ - id: 'pr:8306', - type: 'pr', - number: 8306, - title: 'Empty PR', - state: 'open', - url: 'https://github.com/acme/widgets/pull/8306', - labels: [], - updatedAt: '2026-07-11T00:00:00Z', - author: 'pr-author' - }) - getOwnerRepoForRemoteMock.mockResolvedValue({ owner: 'acme', repo: 'widgets' }) - getPRCommentsMock.mockResolvedValue([]) - getPRChecksMock.mockResolvedValue([]) - ghExecFileAsyncMock.mockImplementation(async (args: string[]) => { - const target = args.at(-1) - if (target === 'repos/acme/widgets/pulls/8306') { - return { - stdout: JSON.stringify({ head: { sha: 'head-sha' }, base: { sha: 'base-sha' } }) - } - } - if (target === 'repos/acme/widgets/pulls/8306/files?per_page=100') { - return { stdout: '[]' } - } - return { stdout: JSON.stringify({ data: {} }) } - }) - - const details = await getWorkItemDetails('/repo-root', 8306, 'pr') - - expect(details?.filesUnavailable).toBe(false) - expect(details?.files).toEqual([]) - }) - // Why: `gh pr view` omits avatar_url, so the login-based github.com URL 404s on // GHE. getWorkItemDetails must resolve author/reviewer/assignee avatars via the // GraphQL user(login:) batch and stamp them onto the returned item. See #8784. diff --git a/src/main/persistence-ssh-remote-pty-binding-replay.test.ts b/src/main/persistence-ssh-remote-pty-binding-replay.test.ts index f32f3836827..77054a2eafb 100644 --- a/src/main/persistence-ssh-remote-pty-binding-replay.test.ts +++ b/src/main/persistence-ssh-remote-pty-binding-replay.test.ts @@ -393,61 +393,4 @@ describe('Store', () => { [TEST_LEAF_2]: 'runtime-pty-2' }) }) - - it('does not restore a binding with an explicit SSH termination tombstone', async () => { - const store = await createStore() - const hostId = 'ssh:ssh-1' - const session: WorkspaceSessionState = { - activeRepoId: 'r1', - activeWorktreeId: 'wt1', - activeTabId: 'tab1', - tabsByWorktree: { - wt1: [ - { - id: 'tab1', - worktreeId: 'wt1', - title: 'Terminal', - customTitle: null, - color: null, - sortOrder: 0, - createdAt: 1, - ptyId: 'ssh:ssh-1@@closed' - } - ] - }, - terminalLayoutsByTabId: { - tab1: { - root: { type: 'leaf', leafId: TEST_LEAF_1 }, - activeLeafId: TEST_LEAF_1, - expandedLeafId: null, - ptyIdsByLeafId: { [TEST_LEAF_1]: 'ssh:ssh-1@@closed' } - } - } - } - store.setWorkspaceSession(session, hostId) - store.upsertSshRemotePtyLease({ - targetId: 'ssh-1', - ptyId: 'closed', - worktreeId: 'wt1', - tabId: 'tab1', - leafId: TEST_LEAF_1, - state: 'terminated' - }) - store.setWorkspaceSession( - { - ...session, - tabsByWorktree: { - wt1: [{ ...session.tabsByWorktree.wt1[0]!, ptyId: null }] - }, - terminalLayoutsByTabId: { - tab1: { ...session.terminalLayoutsByTabId.tab1!, ptyIdsByLeafId: {} } - } - }, - hostId - ) - - const persisted = store.getWorkspaceSession(hostId) - expect(persisted.tabsByWorktree.wt1[0]!.ptyId).toBeNull() - expect(persisted.terminalLayoutsByTabId.tab1.ptyIdsByLeafId).toEqual({}) - }) }) diff --git a/src/main/repo-git-remote-identity-enrichment.test.ts b/src/main/repo-git-remote-identity-enrichment.test.ts index d1e54e11de8..54350dda3d4 100644 --- a/src/main/repo-git-remote-identity-enrichment.test.ts +++ b/src/main/repo-git-remote-identity-enrichment.test.ts @@ -614,22 +614,4 @@ describe('retiring probes for removed repos', () => { expect(listHandlersChanged).toHaveBeenCalledTimes(1) expect(runtimeChanged).toHaveBeenCalledTimes(1) }) - - it('still notifies a caller whose sweep was coalesced into one already running', async () => { - const first = deferred() - vi.mocked(probeGitRemoteIdentity).mockReturnValue(first.promise) - const store = makeMutableStore([makeRepo()]) - const listHandlerChanged = vi.fn() - // The runtime RPC caller also drops a resolved-worktree cache, so it must not be dropped. - const runtimeChanged = vi.fn() - - enrichMissingRepoGitRemoteIdentities(store, { onChanged: listHandlerChanged }) - enrichMissingRepoGitRemoteIdentities(store, { onChanged: runtimeChanged }) - - first.resolve(resolvedProbe) - await drainEnrichmentSweep() - - expect(listHandlerChanged).toHaveBeenCalledTimes(1) - expect(runtimeChanged).toHaveBeenCalledTimes(1) - }) }) diff --git a/src/main/runtime/rpc/e2ee-channel.test.ts b/src/main/runtime/rpc/e2ee-channel.test.ts index 8602263400d..f4a09397d9a 100644 --- a/src/main/runtime/rpc/e2ee-channel.test.ts +++ b/src/main/runtime/rpc/e2ee-channel.test.ts @@ -388,19 +388,6 @@ describe('E2EEChannel', () => { }) }) - describe('cross-compatibility', () => { - it('desktop encrypt is decryptable by desktop decrypt (sanity)', () => { - const a = generateKeyPair() - const b = generateKeyPair() - const sharedA = deriveSharedKey(a.secretKey, b.publicKey) - const sharedB = deriveSharedKey(b.secretKey, a.publicKey) - - const msg = '{"method":"terminal.subscribe","params":{"terminal":"t1"}}' - const enc = encrypt(msg, sharedA) - expect(decrypt(enc, sharedB)).toBe(msg) - }) - }) - describe('destroy', () => { it('clears state and stops forwarding', () => { const ctx = setup() diff --git a/src/main/runtime/rpc/methods/orchestration-worker-release-reap-fixed.func.test.ts b/src/main/runtime/rpc/methods/orchestration-worker-release-reap-fixed.func.test.ts deleted file mode 100644 index 579f37eaf9e..00000000000 --- a/src/main/runtime/rpc/methods/orchestration-worker-release-reap-fixed.func.test.ts +++ /dev/null @@ -1,358 +0,0 @@ -// PRB-0219 / upstream #18737 — FUNCTIONAL (integration) reproduction of the steady-state -// worker-release reap LEAK. -// -// This is the "functional/integration" tier of the PRB-0219 test strategy. It wires the REAL -// orchestration RPC surface (orchestration.workerStart / workerRelease / workerList), the REAL -// OrchestrationDb, and the REAL release completion + observation modules against a fake runtime -// that faithfully models the two identity planes involved in the bug: -// -// * VOLATILE, epoch-fenced handle table — `handleTable` keyed by terminal handle, each entry -// stamped with the `rendererGraphEpoch` at which it was issued. `showTerminal` resolves a -// handle ONLY while its stamped epoch matches the current epoch (mirrors getLiveLeafForHandle -// throwing 'terminal_handle_stale' on a rendererGraphEpoch bump). A relay reconnect / renderer -// remount on headless serve bumps the epoch. -// * DURABLE, incarnation-addressed process table — `ptysById` keyed by the ptyId embedded in the -// worker's persisted process_incarnation (`${ptyId}:${incarnationId}`). The pty stays LIVE -// across an epoch bump; nothing about the graph epoch kills the process. -// -// The bug (mechanism): when the epoch bumps, the durable db handle stops resolving through -// showTerminal WHILE THE PTY IS STILL ALIVE. inspectWorkerTerminal swallows the throw and reports -// `missing`; completeWorkerTerminalRelease then commits `release_unknown` and returns WITHOUT ever -// calling runtime.closeTerminal — so the process/PTY leaks. On mtl-02 those orphans accumulate in -// the orca-serve@factory cgroup until TasksMax=4096 is hit and Bun/omp abort() on EAGAIN. -// -// The observable leak signal asserted here: state 'release_unknown' + processAction 'none' + -// closeTerminal NEVER called + the pty STILL alive in ptysById + worker-list terminalState stuck -// on 'release_unknown' (never 'released'). - -import { afterEach, describe, expect, it, vi } from 'vitest' -import { ORCHESTRATION_METHODS } from './orchestration' -import { eraseRpcMethods, type RpcContext } from '../core' -import { OrchestrationDb } from '../../orchestration/db' -import { OrcaRuntimeService } from '../../orca-runtime' - -describe('PRB-0219 worker-release reap FIX (functional verification)', () => { - let db: OrchestrationDb - let dbOpen = false - let runtime: OrcaRuntimeService - let ctx: RpcContext - let activeRunId: string - - const coordinatorPaneKey = 'tab_coord:aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa' - const workerPaneKey = 'tab_worker:bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb' - - // Dispatch/automation ptyId shape: `${repoId}::${worktreePath}@@${suffix}` (executionHostId:null). - const PTY_ID = 'repo-7f3a::/data/wt/factory-task-1@@a1b2c3d4' - const INCARNATION_ID = 1 - const PROCESS_INCARNATION = `${PTY_ID}:${INCARNATION_ID}` - - // ---- fake runtime process/handle planes (module-level so spies can mutate them) ---- - let ptysById: Map - let handleTable: Map - let rendererGraphEpoch: number - let closedPtyIds: string[] - - /** Resolve a handle to its live pty only while its stamped graph epoch is current. */ - function resolveHandleToLivePty( - handle: string - ): { ptyId: string; pty: { incarnationId: number; alive: boolean } } | null { - const entry = handleTable.get(handle) - if (!entry) { - return null - } - if (entry.epoch !== rendererGraphEpoch) { - // rendererGraphEpoch fence: the durable handle no longer resolves to a live leaf. - return null - } - const pty = ptysById.get(entry.ptyId) - if (!pty || !pty.alive) { - return null - } - return { ptyId: entry.ptyId, pty } - } - - /** Wire the real RPC surface and db against the two-plane fake runtime. */ - function setup(): void { - ptysById = new Map([ - ['coord-pty', { incarnationId: 1, alive: true }], - [PTY_ID, { incarnationId: INCARNATION_ID, alive: true }] - ]) - handleTable = new Map([ - ['term_coord', { ptyId: 'coord-pty', epoch: 0 }], - ['term_worker', { ptyId: PTY_ID, epoch: 0 }] - ]) - rendererGraphEpoch = 0 - closedPtyIds = [] - - db = new OrchestrationDb(':memory:') - dbOpen = true - runtime = new OrcaRuntimeService() - runtime.setOrchestrationDb(db) - - // Incarnation-addressed liveness probe: reads the DURABLE plane, so it stays 'live' across the - // epoch bump (the process really is still running). Matches the real asymmetry. - vi.spyOn(runtime, 'inspectTerminalProcessIncarnationLiveness').mockImplementation( - async (incarnation: string) => { - const idx = incarnation.lastIndexOf(':') - const ptyId = incarnation.slice(0, idx) - const pty = ptysById.get(ptyId) - return pty?.alive ? 'live' : 'exited' - } - ) - - // The incarnation-addressed re-resolution primitive the fix adds. Present here as a spy so the - // same harness proves BOTH tiers: pre-fix completion never calls it (leak); post-fix completion - // calls it to remint a live handle (reap). Fence: EXACT incarnationId match only. - vi.spyOn(runtime, 'resolveTerminalHandleByProcessIncarnation').mockImplementation( - (incarnation: string): string | null => { - const idx = incarnation.lastIndexOf(':') - const ptyId = incarnation.slice(0, idx) - const inc = Number(incarnation.slice(idx + 1)) - const pty = ptysById.get(ptyId) - if (!pty || !pty.alive) { - return null - } - if (pty.incarnationId !== inc) { - // Fence: a reused ptyId with a different incarnation must NOT resolve. - return null - } - // Remint a live handle at the current graph epoch. - handleTable.set('term_reminted', { ptyId, epoch: rendererGraphEpoch }) - return 'term_reminted' - } - ) - - // Identity plane (durable) — answers for the original AND any reminted handle. Independent of - // the graph epoch, exactly like the real getTerminal* accessors that read dispatch authority. - const knownWorkerHandle = (handle: string): boolean => - handle === 'term_worker' || handle === 'term_reminted' - vi.spyOn(runtime, 'getTerminalPaneKey').mockImplementation((handle) => - handle === 'term_coord' - ? coordinatorPaneKey - : knownWorkerHandle(handle) - ? workerPaneKey - : null - ) - vi.spyOn(runtime, 'getTerminalProcessIncarnation').mockImplementation((handle) => - knownWorkerHandle(handle) ? PROCESS_INCARNATION : null - ) - vi.spyOn(runtime, 'getOrchestrationDispatchAuthority').mockImplementation((handle) => - knownWorkerHandle(handle) - ? // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: This test fixture is deliberately shaped to exercise the private/runtime boundary. - ({ - terminalHandle: handle, - paneKey: workerPaneKey, - processIncarnation: PROCESS_INCARNATION, - hostScope: { kind: 'local', hostId: 'local' } - // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: Test fixture crosses a private/runtime boundary with a verified shape. - // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: Test fixture crosses a private/runtime boundary with a verified shape. - } as never) - : null - ) - vi.spyOn(runtime, 'validateOrchestrationAgentLauncher').mockImplementation(() => {}) - - // Volatile handle resolution — epoch-fenced. Throws 'terminal_handle_stale' once the epoch - // moves past the epoch at which the handle was issued. - vi.spyOn(runtime, 'showTerminal').mockImplementation(async (handle) => { - if (!resolveHandleToLivePty(handle)) { - throw new Error('terminal_handle_stale') - } - // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: Test fixture crosses a private/runtime boundary with a verified shape. - // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: Test fixture crosses a private/runtime boundary with a verified shape. - return { handle, worktreeId: 'repo::worktree', status: 'running' } as never - }) - - // The reap: closing a handle kills exactly the pty it resolves to. - vi.spyOn(runtime, 'closeTerminal').mockImplementation(async (handle) => { - const live = resolveHandleToLivePty(handle) - if (!live) { - // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: Test fixture crosses a private/runtime boundary with a verified shape. - // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: Test fixture crosses a private/runtime boundary with a verified shape. - return { handle, tabId: null, ptyKilled: false } as never - } - live.pty.alive = false - ptysById.delete(live.ptyId) - closedPtyIds.push(live.ptyId) - // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: Test fixture crosses a private/runtime boundary with a verified shape. - // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: Test fixture crosses a private/runtime boundary with a verified shape. - return { handle, tabId: `tab:${live.ptyId}`, ptyKilled: true } as never - }) - - // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: Test fixture crosses a private/runtime boundary with a verified shape. - // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: Test fixture crosses a private/runtime boundary with a verified shape. - // Remaining runtime surface required to start + settle a worker (mirrors the unit harness). - // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: Test fixture crosses a private/runtime boundary with a verified shape. - vi.spyOn(runtime, 'showManagedTerminalWorkspace').mockResolvedValue({ - id: 'repo::worktree' - // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: Test fixture crosses a private/runtime boundary with a verified shape. - // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: Test fixture crosses a private/runtime boundary with a verified shape. - } as never) - vi.spyOn(runtime, 'createTerminal').mockResolvedValue({ - handle: 'term_worker', - worktreeId: 'repo::worktree', - title: 'worker' - }) - vi.spyOn(runtime, 'waitForTerminal').mockResolvedValue({ - handle: 'term_worker', - condition: 'tui-idle', - satisfied: true, - status: 'running', - exitCode: null - }) - vi.spyOn(runtime, 'getTerminalOrchestrationCliCommand').mockReturnValue('orca') - vi.spyOn(runtime, 'sendTerminalAgentPrompt').mockResolvedValue({ - handle: 'term_worker', - accepted: true, - bytesWritten: 1 - }) - vi.spyOn(runtime, 'isTerminalRunningAgent').mockResolvedValue(true) - vi.spyOn(runtime, 'getExactWorkerProviderSession').mockReturnValue(null) - vi.spyOn(runtime, 'readTerminal').mockResolvedValue({ - handle: 'term_worker', - status: 'running', - tail: ['worker output line 1', 'worker output line 2'], - truncated: false, - nextCursor: '2' - }) - vi.spyOn(runtime, 'notifyMessageArrived').mockImplementation(() => {}) - - activeRunId = db.createRun({ - objective: 'PRB-0219 reap leak fixture', - coordinatorHandle: 'term_coord', - coordinatorPaneKey - }).id - ctx = { runtime } - } - - afterEach(() => { - if (dbOpen) { - dbOpen = false - db.close() - } - vi.restoreAllMocks() - }) - - /** Look up a registered orchestration RPC method by name. */ - function findMethod(name: string) { - const method = eraseRpcMethods(ORCHESTRATION_METHODS).find((m) => m.name === name) - if (!method) { - throw new Error(`Method not found: ${name}`) - } - return method - } - - /** Parse a method's params and invoke its handler against the shared ctx. */ - async function call(name: string, params: Record) { - const method = findMethod(name) - const parsed = method.params ? method.params.parse(params) : undefined - return method.handler(parsed, ctx) - } - - // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: Test fixture crosses a private/runtime boundary with a verified shape. - // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: Test fixture crosses a private/runtime boundary with a verified shape. - /** Start a worker and settle its report, the state a release acts on. */ - async function startSettledWorker(): Promise<{ taskId: string; dispatchId: string }> { - const task = db.createTask({ spec: 'reap-leak fixture task', runId: activeRunId }) - // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: Test fixture crosses a private/runtime boundary with a verified shape. - const result = (await call('orchestration.workerStart', { - task: task.id, - from: 'term_coord', - agent: 'codex' - // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: Test fixture crosses a private/runtime boundary with a verified shape. - // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: Test fixture crosses a private/runtime boundary with a verified shape. - })) as { dispatchId: string; state: string } - expect(result.state).toBe('ready') - const settlement = db.settleWorkerReport({ - taskId: task.id, - dispatchId: result.dispatchId, - outcome: 'succeeded', - result: 'worker succeeded' - }) - expect(settlement.action).toBe('settled') - return { taskId: task.id, dispatchId: result.dispatchId } - } - - /** The terminalState workerList projects for a dispatch, or null. */ - async function workerTerminalState(dispatchId: string): Promise { - // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: Test fixture crosses a private/runtime boundary with a verified shape. - // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: Test fixture crosses a private/runtime boundary with a verified shape. - const listed = (await call('orchestration.workerList', { run: activeRunId })) as { - workers: { dispatchId: string; terminalState: string | null }[] - } - return listed.workers.find((w) => w.dispatchId === dispatchId)?.terminalState ?? null - } - - it('REAP (fixed): a rendererGraphEpoch bump strands the durable handle, but the incarnation fallback remints a live handle and reaps the process', async () => { - setup() - const { dispatchId } = await startSettledWorker() - const resource = db.getWorkerTerminalResourceByOwner(dispatchId) - expect(resource?.process_incarnation).toBe(PROCESS_INCARNATION) - - // Relay reconnect / renderer remount bumps the graph epoch: the durable handle goes stale - // while the PTY stays alive. - rendererGraphEpoch = 1 - await expect(runtime.showTerminal('term_worker')).rejects.toThrow('terminal_handle_stale') - expect(ptysById.get(PTY_ID)?.alive).toBe(true) - - // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: Test fixture crosses a private/runtime boundary with a verified shape. - // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: Test fixture crosses a private/runtime boundary with a verified shape. - const receipt = (await call('orchestration.workerRelease', { dispatch: dispatchId })) as { - state: string - processAction: string - } - - // The fix: inspectWorkerTerminal re-resolved the live PTY by process incarnation, reminted a - // handle, and completion closed THAT handle — the process is actually reaped. - expect(receipt.state).toBe('released') - expect(receipt.processAction).toBe('closed_agent_terminal') - expect(runtime.closeTerminal).toHaveBeenCalledWith('term_reminted') - expect(closedPtyIds).toEqual([PTY_ID]) - expect(ptysById.has(PTY_ID)).toBe(false) - expect(await workerTerminalState(dispatchId)).toBe('released') - }) - - it('CONTROL: with the graph epoch intact the same release reaps exactly that PTY', async () => { - setup() - const { dispatchId } = await startSettledWorker() - - // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: Test fixture crosses a private/runtime boundary with a verified shape. - // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: Test fixture crosses a private/runtime boundary with a verified shape. - const receipt = (await call('orchestration.workerRelease', { dispatch: dispatchId })) as { - state: string - processAction: string - } - - expect(receipt.state).toBe('released') - expect(receipt.processAction).toBe('closed_agent_terminal') - expect(closedPtyIds).toEqual([PTY_ID]) - expect(ptysById.has(PTY_ID)).toBe(false) - expect(await workerTerminalState(dispatchId)).toBe('released') - }) - - it('FENCE (fixed): a reused ptyId carrying a different incarnation must NOT remint or close — stays release_unknown', async () => { - setup() - const { dispatchId } = await startSettledWorker() - - // The graph epoch bumps AND the ptyId has been reused by a different process (incarnation 2), - // while the worker's recorded incarnation is still 1. The exact-incarnation fence must refuse. - rendererGraphEpoch = 1 - const reused = ptysById.get(PTY_ID) - if (reused) { - reused.incarnationId = 2 - } - - // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: Test fixture crosses a private/runtime boundary with a verified shape. - // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: Test fixture crosses a private/runtime boundary with a verified shape. - const receipt = (await call('orchestration.workerRelease', { dispatch: dispatchId })) as { - state: string - processAction: string - } - - expect(receipt.state).toBe('release_unknown') - expect(receipt.processAction).toBe('none') - expect(runtime.closeTerminal).not.toHaveBeenCalled() - // The other lane's live process is left untouched (never reaped by an over-broad match). - expect(ptysById.get(PTY_ID)?.alive).toBe(true) - expect(await workerTerminalState(dispatchId)).toBe('release_unknown') - }) -}) diff --git a/src/main/ssh/ssh-connection-store.test.ts b/src/main/ssh/ssh-connection-store.test.ts index b086a9c5e31..d7aaee2046f 100644 --- a/src/main/ssh/ssh-connection-store.test.ts +++ b/src/main/ssh/ssh-connection-store.test.ts @@ -89,11 +89,6 @@ describe('SshConnectionStore', () => { sshConfigHostsToTargetsMock.mockReset() }) - it('listTargets delegates to store', () => { - sshStore.listTargets() - expect(mockStore.getSshTargets).toHaveBeenCalled() - }) - it('lists picker suppression aliases without consulting re-adoption tombstones', () => { mockStore.addDeletedSshConfigAlias('config-removed') mockStore.addRemovedSshTargetTombstone({ @@ -166,26 +161,6 @@ describe('SshConnectionStore', () => { expect(sshStore.listTargets()).toEqual([userTarget]) }) - it('updateTarget delegates to store', () => { - const original: SshTarget = { - id: 'ssh-1', - label: 'Old Name', - host: 'example.com', - port: 22, - username: 'user' - } - mockStore.addSshTarget(original) - - const result = sshStore.updateTarget('ssh-1', { label: 'New Name' }) - expect(result).toBeTruthy() - expect(mockStore.updateSshTarget).toHaveBeenCalledWith('ssh-1', { label: 'New Name' }) - }) - - it('removeTarget delegates to store', () => { - sshStore.removeTarget('ssh-1') - expect(mockStore.removeSshTarget).toHaveBeenCalledWith('ssh-1') - }) - describe('importFromSshConfig', () => { function candidate(overrides: Partial & { configHost: string }): SshTarget { return { diff --git a/src/main/ssh/ssh-relay-ripgrep-cache-gc.test.ts b/src/main/ssh/ssh-relay-ripgrep-cache-gc.test.ts index d69bdb497f1..bc61c5572ba 100644 --- a/src/main/ssh/ssh-relay-ripgrep-cache-gc.test.ts +++ b/src/main/ssh/ssh-relay-ripgrep-cache-gc.test.ts @@ -84,19 +84,6 @@ describe('remote ripgrep cache GC', () => { expect(removedTrees()).toEqual([]) }) - // Why this case exists: the relay directory is named from a hash of the relay bytes, and - // ripgrep is not among them, so a release that bumps only the ripgrep package -- the monthly - // Dependabot PR -- shares a relay directory with its predecessor while minting a new entry. - // With a single marker slot the second client overwrote the first's reference and this pass - // then collected the binary the first client's relay was still running against. - it('keeps both builds when two clients share one relay directory', async () => { - reply([CURRENT, SUPERSEDED], [CURRENT, SUPERSEDED]) - - await gcRemoteRipgrepCache(conn, LINUX, '/home/me', { pinnedEntry: CURRENT }) - - expect(removedTrees()).toEqual([]) - }) - // Why assert the shell and not just the parse: the marker is per entry, so a scan that read a // single fixed filename would silently see only one of the two references above. it('scans every marker in a relay directory, not one fixed name', async () => {