mirror of
https://github.com/stablyai/orca.git
synced 2026-10-07 08:02:21 +00:00
Resolves 208 candidate pairs where the same case title appears verbatim in two or more
files, produced by a repo-wide scan calibrated against a known positive. 46 case
declarations removed across 32 files, 798 lines gone. No file deleted whole, no
production code touched.
The headline result is the measurement, not the deletions: across the three buckets that
reported in detail, the signal ran roughly 86% false-positive (3/42, 9/42, and the rest).
It has good recall and poor precision, and it reorders a reading queue rather than
replacing one. Calibrating a detector against a known positive proves recall, not
precision.
What the deletions were:
- Duplicate invocation through a re-export shim. `native-chat-tool-summary.ts` is a
ten-line `export {...} from '../../../../shared/native-chat-tool-summary'`, and
`agent-status.ts:161` is `export { isExplicitAgentStatusFresh } from
'./pane-agent-evidence'`. Cases on the shim side were byte-equivalent to the owner's
with no rendering or transport hop.
- Provider-local replays of a shared helper: three `repository-ref` providers that are
each `createRemoteRefProbeCache(parseXRef)` and contribute nothing to transient
handling; two `local-pty` and `daemon/session` tables replaying
`shell-startup-output-scanner`, whose owner additionally checks every split point.
- A reader-side replay of store policy. `runtime-worktree-agent-rows-structured.test.ts`
asserted an attention-to-blocked mapping; the reader contains zero `attention` or
`blocked` tokens and copies `state` through. The mapping lives in
`structuredAgentSessionAgentStatus`. Consistent with
`docs/reference/agent-status-store.md`: readers keep only presentation policy.
- Constructor-only subclass duplication: the shared capability-cache case is covered by
`codex-app-server-capability-cache.test.ts`, whose ten cases include the identical
title plus all four risks `docs/reference/git-compatibility.md` names — first fallback,
later cached call, concurrent probes, per-host isolation.
- A private predicate duplicated at a real boundary, varying only a path passed straight
into the shared predicate.
Why most pairs were KEPT, because the false positives are principled rather than noise:
- Two independent execution hosts. `src/relay/git-handler-*` and `src/main/git/*` are
separate Git implementations that cannot import each other and hold separate capability
caches, exactly as the compatibility doc requires; the repo already ships
`status-branch-line-total-relay-parity.test.ts` to pin the duality deliberately. Neither
side's argv, timeout or cache regression is visible to the other.
- Deliberately duplicated production siblings: Codex vs Claude (different account fields,
different CLIs, different wire protocols), gitea vs bitbucket (`/pulls/42` vs
`/pullrequests/42`), gl-utils vs gh-utils (separate in-flight maps). Same contract
shape, different implementations — an identical title is the correct naming.
- Shared-predicate consumers: one side tests the predicate, the other tests a caller's
wiring to it. A caller that forgot to call the predicate passes the shared test.
In a codebase with intentional provider and host symmetry, identical test titles are
expected, and the signal cannot distinguish "copied" from "parallel by design" because
both produce the same prose. Only reading both bodies separates them.
Verified: 6,968 desktop test files pass; the three modified mobile files pass (39 cases);
`check-reliability-gates.mjs` 140 gates; nothing under
`mobile/src/test-support/rpc-recording/` or `mobile/rpc-foundation/goldens/` touched.
62 local failures across 12 files were each accounted for and none is caused by this
change: `browser-manager-tab-identity`, `browser-manager-viewport-ownership`,
`session-scanner-codex-workers` and `managed-hook-script-refresh` all fail identically in
a pristine `origin/main` worktree; five `mobile-web-app-*-render` tests need Playwright
browsers this machine lacks; `structured-agent-session-restart-ownership` and
`ssh-remote-commands` pass in isolation and fail only under concurrent load.
490 lines
15 KiB
TypeScript
490 lines
15 KiB
TypeScript
import {
|
|
closeTestStores,
|
|
testState,
|
|
createStore,
|
|
writeDataFile,
|
|
readDataFile,
|
|
makeRepo,
|
|
makeProject,
|
|
makeProjectHostSetup,
|
|
createSqliteTestStore
|
|
} from './persistence-test-harness'
|
|
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
|
|
import { writeFileSync, rmSync, mkdtempSync, mkdirSync } from 'node:fs'
|
|
import { join } from 'node:path'
|
|
import { tmpdir } from 'node:os'
|
|
import type { PersistedState } from '../shared/persisted-state-types'
|
|
import type { WorkspaceSessionState } from '../shared/workspace-session-state-types'
|
|
import { getDefaultPersistedState, getDefaultWorkspaceSession } from '../shared/constants'
|
|
import { closeTerminalTabInWorkspaceSession } from '../shared/workspace-session-terminal-tab-close'
|
|
|
|
import { TEST_LEAF_1 } from './persistence-session-fixtures'
|
|
import { ProfileStateSqliteAuthority } from './persistence/profile-state/profile-state-sqlite-authority'
|
|
|
|
import {
|
|
getLocalWorktreeScanGeneration,
|
|
isLocalWorktreeScanGenerationCurrent
|
|
} from './local-worktree-scan-generation'
|
|
|
|
// Stub the ~/.ssh/config parser so the SSH-import test drives the real Store with deterministic hosts, not the operator's actual ~/.ssh/config.
|
|
const { loadUserSshConfigMock, sshConfigHostsToTargetsMock } = vi.hoisted(() => ({
|
|
loadUserSshConfigMock: vi.fn(),
|
|
sshConfigHostsToTargetsMock: vi.fn()
|
|
}))
|
|
|
|
vi.mock('./ssh/ssh-config-parser', () => ({
|
|
loadUserSshConfig: loadUserSshConfigMock,
|
|
sshConfigHostsToTargets: sshConfigHostsToTargetsMock
|
|
}))
|
|
const { trackMock, getCohortAtEmitMock } = vi.hoisted(() => ({
|
|
trackMock: vi.fn(),
|
|
getCohortAtEmitMock: vi.fn()
|
|
}))
|
|
|
|
vi.mock('electron', () => ({
|
|
app: {
|
|
getPath: () => testState.dir
|
|
},
|
|
safeStorage: {
|
|
isEncryptionAvailable: () => true,
|
|
encryptString: (plaintext: string) => Buffer.from(`encrypted:${plaintext}`, 'utf-8'),
|
|
decryptString: (ciphertext: Buffer) => {
|
|
const decoded = ciphertext.toString('utf-8')
|
|
if (!decoded.startsWith('encrypted:')) {
|
|
throw new Error('invalid ciphertext')
|
|
}
|
|
return decoded.slice('encrypted:'.length)
|
|
}
|
|
}
|
|
}))
|
|
|
|
vi.mock('./telemetry/client', () => ({
|
|
track: trackMock
|
|
}))
|
|
|
|
vi.mock('./telemetry/cohort-classifier', () => ({
|
|
getCohortAtEmit: getCohortAtEmitMock
|
|
}))
|
|
|
|
describe('Store', () => {
|
|
beforeEach(() => {
|
|
testState.dir = mkdtempSync(join(tmpdir(), 'orca-test-'))
|
|
trackMock.mockReset()
|
|
getCohortAtEmitMock.mockReset()
|
|
getCohortAtEmitMock.mockReturnValue({ nth_repo_added: 2 })
|
|
})
|
|
|
|
afterEach(async () => {
|
|
await closeTestStores()
|
|
rmSync(testState.dir, { recursive: true, force: true })
|
|
})
|
|
// ── 1. Defaults when no file exists ──────────────────────────────────
|
|
|
|
it('returns empty repos when no data file exists', async () => {
|
|
const store = await createStore()
|
|
expect(store.getRepos()).toEqual([])
|
|
}, 15_000)
|
|
|
|
it('clone-reads and durably persists the main-owned Codex reset ledger', async () => {
|
|
const store = await createStore()
|
|
const ledger = {
|
|
version: 1 as const,
|
|
attempts: [
|
|
{
|
|
idempotencyKey: '11111111-1111-4111-8111-111111111111',
|
|
expectedScope: {
|
|
target: { runtime: 'host' as const, wslDistro: null },
|
|
accountId: 'account-host',
|
|
accountRevision: 42,
|
|
offerRevision: 'v1:offer'
|
|
},
|
|
state: 'providerPending' as const
|
|
}
|
|
]
|
|
}
|
|
|
|
await store.replaceCodexResetCreditAttemptLedgerAndFlush(ledger)
|
|
const firstRead = store.getCodexResetCreditAttemptLedger()
|
|
firstRead.attempts.splice(0, 1)
|
|
|
|
expect(store.getCodexResetCreditAttemptLedger()).toEqual(ledger)
|
|
expect((readDataFile() as PersistedState).codexResetCreditAttemptLedger).toEqual(ledger)
|
|
})
|
|
|
|
it('rolls the in-memory Codex reset ledger back when its durable write fails', async () => {
|
|
const store = await createStore()
|
|
const before = store.getCodexResetCreditAttemptLedger()
|
|
const write = vi
|
|
.spyOn(ProfileStateSqliteAuthority.prototype, 'writeCompleteSerializedDomains')
|
|
.mockImplementationOnce(() => {
|
|
throw new Error('disk full')
|
|
})
|
|
|
|
try {
|
|
await expect(
|
|
store.replaceCodexResetCreditAttemptLedgerAndFlush({
|
|
version: 1,
|
|
attempts: [
|
|
{
|
|
idempotencyKey: '11111111-1111-4111-8111-111111111111',
|
|
expectedScope: {
|
|
target: { runtime: 'host', wslDistro: null },
|
|
accountId: 'account-host',
|
|
accountRevision: 42,
|
|
offerRevision: 'v1:offer'
|
|
},
|
|
state: 'providerPending'
|
|
}
|
|
]
|
|
})
|
|
).rejects.toThrow('disk full')
|
|
expect(store.getCodexResetCreditAttemptLedger()).toEqual(before)
|
|
} finally {
|
|
write.mockRestore()
|
|
}
|
|
})
|
|
|
|
it('preserves a corrupt Codex reset ledger as a fail-closed read error', async () => {
|
|
writeDataFile({
|
|
...getDefaultPersistedState(testState.dir),
|
|
codexResetCreditAttemptLedger: {
|
|
version: 1,
|
|
attempts: [{ state: 'providerPending' }]
|
|
}
|
|
})
|
|
|
|
const store = await createStore()
|
|
expect(() => store.getCodexResetCreditAttemptLedger()).toThrow(
|
|
'Codex reset-credit attempt ledger is corrupt'
|
|
)
|
|
})
|
|
|
|
it('does not restore a terminal tab after its durable close flush returns', async () => {
|
|
const store = await createStore()
|
|
// Registered on purpose: rows owned by an unregistered repo id are swept as orphans on load.
|
|
store.addRepo(makeRepo({ id: 'repo-1', path: '/repo-1' }))
|
|
const worktreeId = 'repo-1::/tmp/worktree-1'
|
|
const tabId = 'terminal-1'
|
|
const session: WorkspaceSessionState = {
|
|
...getDefaultWorkspaceSession(),
|
|
activeWorktreeId: worktreeId,
|
|
activeTabId: tabId,
|
|
tabsByWorktree: {
|
|
[worktreeId]: [
|
|
{
|
|
id: tabId,
|
|
ptyId: 'pty-1',
|
|
worktreeId,
|
|
title: 'Terminal',
|
|
customTitle: null,
|
|
color: null,
|
|
sortOrder: 0,
|
|
createdAt: 1
|
|
}
|
|
]
|
|
},
|
|
terminalLayoutsByTabId: {
|
|
[tabId]: {
|
|
root: { type: 'leaf', leafId: TEST_LEAF_1 },
|
|
activeLeafId: TEST_LEAF_1,
|
|
expandedLeafId: null,
|
|
ptyIdsByLeafId: { [TEST_LEAF_1]: 'pty-1' }
|
|
}
|
|
},
|
|
activeTabIdByWorktree: { [worktreeId]: tabId },
|
|
defaultTerminalTabsAppliedByWorktreeId: { [worktreeId]: true }
|
|
}
|
|
store.setWorkspaceSession(session)
|
|
store.flushOrThrow()
|
|
|
|
const closed = closeTerminalTabInWorkspaceSession(
|
|
store.getWorkspaceSession(),
|
|
worktreeId,
|
|
tabId
|
|
)
|
|
store.setWorkspaceSession(closed.session)
|
|
store.flushOrThrow()
|
|
|
|
const reloaded = await createStore()
|
|
expect(reloaded.getWorkspaceSession().tabsByWorktree[worktreeId]).toEqual([])
|
|
expect(reloaded.getWorkspaceSession().terminalLayoutsByTabId[tabId]).toBeUndefined()
|
|
expect(
|
|
reloaded.getWorkspaceSession().defaultTerminalTabsAppliedByWorktreeId?.[worktreeId]
|
|
).toBe(true)
|
|
})
|
|
|
|
it('loads state from an explicit profile data file path', async () => {
|
|
const profileDataDirectory = join(testState.dir, 'profiles', 'local-default')
|
|
const profileDataFile = join(profileDataDirectory, 'orca-data.json')
|
|
mkdirSync(profileDataDirectory, { recursive: true })
|
|
writeDataFile({
|
|
schemaVersion: 1,
|
|
repos: [makeRepo({ id: 'legacy-root-repo', path: '/legacy' })]
|
|
})
|
|
writeFileSync(
|
|
profileDataFile,
|
|
JSON.stringify({
|
|
schemaVersion: 1,
|
|
repos: [makeRepo({ id: 'profile-repo', path: '/profile' })]
|
|
}),
|
|
'utf-8'
|
|
)
|
|
|
|
vi.resetModules()
|
|
const { Store, initDataPath } = await import('./persistence')
|
|
initDataPath()
|
|
const store = createSqliteTestStore(Store, { dataFile: profileDataFile })
|
|
|
|
expect(store.getRepos().map((repo) => repo.id)).toEqual(['profile-repo'])
|
|
}, 15_000)
|
|
|
|
it('backfills project host setup compatibility records from legacy repos on load', async () => {
|
|
writeDataFile({
|
|
schemaVersion: 1,
|
|
repos: [
|
|
makeRepo({
|
|
id: 'local-repo',
|
|
path: '/Users/alice/orca',
|
|
displayName: 'Orca',
|
|
upstream: { owner: 'StablyAI', repo: 'Orca' }
|
|
}),
|
|
makeRepo({
|
|
id: 'remote-repo',
|
|
path: '/home/alice/orca',
|
|
displayName: 'orca',
|
|
connectionId: 'gpu-vm',
|
|
upstream: { owner: 'stablyai', repo: 'orca' }
|
|
})
|
|
]
|
|
})
|
|
|
|
const store = await createStore()
|
|
|
|
expect(store.getProjects()).toEqual([
|
|
expect.objectContaining({
|
|
id: 'github:stablyai/orca',
|
|
sourceRepoIds: ['local-repo', 'remote-repo']
|
|
})
|
|
])
|
|
expect(store.getProjectHostSetups()).toEqual([
|
|
expect.objectContaining({
|
|
id: 'local-repo',
|
|
projectId: 'github:stablyai/orca',
|
|
hostId: 'local',
|
|
path: '/Users/alice/orca'
|
|
}),
|
|
expect.objectContaining({
|
|
id: 'remote-repo',
|
|
projectId: 'github:stablyai/orca',
|
|
hostId: 'ssh:gpu-vm',
|
|
path: '/home/alice/orca'
|
|
})
|
|
])
|
|
|
|
store.flush()
|
|
const persisted = readDataFile() as PersistedState
|
|
expect(persisted.projects).toEqual(store.getProjects())
|
|
expect(persisted.projectHostSetups).toEqual(store.getProjectHostSetups())
|
|
})
|
|
|
|
it('preserves independent project host setup records on load', async () => {
|
|
const independentProject = makeProject({
|
|
id: 'cloud-project',
|
|
displayName: 'Cloud Project'
|
|
})
|
|
const independentSetup = makeProjectHostSetup({
|
|
id: 'cloud-project::gpu-vm',
|
|
projectId: independentProject.id,
|
|
hostId: 'runtime:gpu-vm',
|
|
repoId: '',
|
|
path: '/srv/cloud-project',
|
|
displayName: 'GPU VM'
|
|
})
|
|
writeDataFile({
|
|
...getDefaultPersistedState(testState.dir),
|
|
repos: [makeRepo({ id: 'r1', path: '/repo', displayName: 'Repo' })],
|
|
projects: [independentProject],
|
|
projectHostSetups: [independentSetup]
|
|
})
|
|
|
|
const store = await createStore()
|
|
|
|
expect(store.getProjects().map((project) => project.id)).toEqual(['repo:r1', 'cloud-project'])
|
|
expect(store.getProjectHostSetups().map((setup) => setup.id)).toEqual([
|
|
'r1',
|
|
'cloud-project::gpu-vm'
|
|
])
|
|
store.flush()
|
|
const persisted = readDataFile() as PersistedState
|
|
expect(persisted.projectHostSetups).toContainEqual(independentSetup)
|
|
})
|
|
|
|
it('updates and persists a project Windows runtime preference', async () => {
|
|
const project = makeProject({
|
|
id: 'repo:r1',
|
|
sourceRepoIds: ['r1'],
|
|
localWindowsRuntimePreference: { kind: 'inherit-global' }
|
|
})
|
|
writeDataFile({
|
|
...getDefaultPersistedState(testState.dir),
|
|
repos: [makeRepo({ id: 'r1' })],
|
|
projects: [project],
|
|
projectHostSetups: [
|
|
makeProjectHostSetup({
|
|
id: 'setup-1',
|
|
projectId: project.id,
|
|
repoId: ''
|
|
})
|
|
]
|
|
})
|
|
const store = await createStore()
|
|
const scanGeneration = getLocalWorktreeScanGeneration('r1')
|
|
|
|
const updated = store.updateProject(project.id, {
|
|
localWindowsRuntimePreference: { kind: 'wsl', distro: 'Ubuntu' }
|
|
})
|
|
|
|
expect(updated?.localWindowsRuntimePreference).toEqual({ kind: 'wsl', distro: 'Ubuntu' })
|
|
expect(isLocalWorktreeScanGenerationCurrent('r1', scanGeneration)).toBe(false)
|
|
store.flush()
|
|
const reloaded = await createStore()
|
|
expect(reloaded.getProjects()[0]?.localWindowsRuntimePreference).toEqual({
|
|
kind: 'wsl',
|
|
distro: 'Ubuntu'
|
|
})
|
|
})
|
|
|
|
it('carries project state and independent setups across a repo remote identity change', async () => {
|
|
const originProjectId = 'git:git.example.com/acme/app'
|
|
writeDataFile({
|
|
...getDefaultPersistedState(testState.dir),
|
|
repos: [
|
|
makeRepo({
|
|
id: 'r1',
|
|
path: '/repo',
|
|
displayName: 'App',
|
|
gitRemoteIdentity: {
|
|
canonicalKey: 'git.example.com/acme/app',
|
|
remoteName: 'origin',
|
|
remoteUrl: 'git@git.example.com:acme/app.git'
|
|
}
|
|
})
|
|
],
|
|
projects: [
|
|
makeProject({
|
|
id: originProjectId,
|
|
sourceRepoIds: ['r1'],
|
|
localWindowsRuntimePreference: { kind: 'wsl', distro: 'Ubuntu' }
|
|
})
|
|
],
|
|
projectHostSetups: [
|
|
makeProjectHostSetup({ id: 'r1', projectId: originProjectId, repoId: 'r1' }),
|
|
makeProjectHostSetup({
|
|
id: 'app::gpu-vm',
|
|
projectId: originProjectId,
|
|
hostId: 'runtime:gpu-vm',
|
|
repoId: '',
|
|
path: '/srv/app'
|
|
})
|
|
]
|
|
})
|
|
const store = await createStore()
|
|
|
|
// A re-probe that now prefers the `upstream` remote rewrites the derived project id.
|
|
store.updateRepo('r1', {
|
|
gitRemoteIdentity: {
|
|
canonicalKey: 'git.example.com/acme/app-upstream',
|
|
remoteName: 'upstream',
|
|
remoteUrl: 'git@git.example.com:acme/app-upstream.git'
|
|
}
|
|
})
|
|
|
|
const upstreamProjectId = 'git:git.example.com/acme/app-upstream'
|
|
expect(store.getProjects().map((project) => project.id)).toEqual([upstreamProjectId])
|
|
expect(store.getProjects()[0]?.localWindowsRuntimePreference).toEqual({
|
|
kind: 'wsl',
|
|
distro: 'Ubuntu'
|
|
})
|
|
expect(
|
|
store.getProjectHostSetups().find((setup) => setup.id === 'app::gpu-vm')?.projectId
|
|
).toBe(upstreamProjectId)
|
|
})
|
|
|
|
it('migrates legacy WSL agent settings into the global Windows runtime default', async () => {
|
|
writeDataFile({
|
|
schemaVersion: 1,
|
|
repos: [],
|
|
worktreeMeta: {},
|
|
settings: {
|
|
localAgentRuntime: 'wsl',
|
|
localAgentWslDistro: 'Ubuntu'
|
|
}
|
|
})
|
|
|
|
const store = await createStore()
|
|
|
|
expect(store.getSettings().localWindowsRuntimeDefault).toEqual({
|
|
kind: 'wsl',
|
|
distro: 'Ubuntu'
|
|
})
|
|
store.flush()
|
|
expect((readDataFile() as PersistedState).settings.localWindowsRuntimeDefault).toEqual({
|
|
kind: 'wsl',
|
|
distro: 'Ubuntu'
|
|
})
|
|
})
|
|
|
|
it('migrates the legacy host account-runtime default to auto once', async () => {
|
|
writeDataFile({
|
|
schemaVersion: 1,
|
|
repos: [],
|
|
worktreeMeta: {},
|
|
settings: {
|
|
localAccountRuntime: 'host'
|
|
}
|
|
})
|
|
|
|
const store = await createStore()
|
|
|
|
expect(store.getSettings().localAccountRuntime).toBe('auto')
|
|
expect(store.getSettings().localAccountRuntimeDefaultedToAutoForAllUsers).toBe(true)
|
|
store.flush()
|
|
const persisted = (readDataFile() as PersistedState).settings
|
|
expect(persisted.localAccountRuntime).toBe('auto')
|
|
expect(persisted.localAccountRuntimeDefaultedToAutoForAllUsers).toBe(true)
|
|
})
|
|
|
|
it('preserves an explicit WSL account-runtime pin through the migration', async () => {
|
|
writeDataFile({
|
|
schemaVersion: 1,
|
|
repos: [],
|
|
worktreeMeta: {},
|
|
settings: {
|
|
localAccountRuntime: 'wsl',
|
|
localAccountWslDistro: 'Ubuntu'
|
|
}
|
|
})
|
|
|
|
const store = await createStore()
|
|
|
|
expect(store.getSettings().localAccountRuntime).toBe('wsl')
|
|
expect(store.getSettings().localAccountRuntimeDefaultedToAutoForAllUsers).toBe(true)
|
|
})
|
|
|
|
it('does not re-flip an explicit host pin chosen after migration', async () => {
|
|
writeDataFile({
|
|
schemaVersion: 1,
|
|
repos: [],
|
|
worktreeMeta: {},
|
|
settings: {
|
|
localAccountRuntime: 'host',
|
|
localAccountRuntimeDefaultedToAutoForAllUsers: true
|
|
}
|
|
})
|
|
|
|
const store = await createStore()
|
|
|
|
expect(store.getSettings().localAccountRuntime).toBe('host')
|
|
})
|
|
})
|