mirror of
https://github.com/stablyai/orca.git
synced 2026-10-23 08:03:39 +00:00
fix(worktrees): stop trusting a UNC ENOENT, which is what a shut-down distro looks like
Windows reports an unreachable 9P route as ENOENT, so a distro that has merely been shut down is indistinguishable from one that never held any buckets. wsl.ts already refuses to trust a UNC ENOENT for the same reason, probing inside the distro instead. The classification added earlier called ENOENT a complete answer, which is right for a local home that simply has no agent state but wrong here. After a wsl --shutdown the cached distro home still resolves, so nothing else marked the scan incomplete: the empty result was memoized for the whole process lifetime and every later generated create in that namespace reissued names spent inside the distro. That is STA-4472 again, reached by a different route. ENOENT now only means "absent" off UNC.
This commit is contained in:
@@ -109,6 +109,23 @@ describe('retirement discovery on WSL', () => {
|
||||
}
|
||||
})
|
||||
|
||||
it('does not trust a UNC ENOENT, which is what a shut-down distro looks like', async () => {
|
||||
// Windows maps an unreachable 9P route to ENOENT, so `wsl --shutdown` is indistinguishable
|
||||
// from a distro that never held buckets. The home stays cached and still resolves, so nothing
|
||||
// else marks the scan incomplete — believing ENOENT here memoizes the STA-4472 hole for good.
|
||||
const enoent = Object.assign(new Error('ENOENT'), { code: 'ENOENT' })
|
||||
runWslTranscriptFsTaskMock.mockRejectedValue(enoent)
|
||||
|
||||
const retired = await discoverRetiredWorktreeNames({
|
||||
workspaceRoots: [DISTRO_ROOT],
|
||||
home: '/nonexistent-home',
|
||||
env: {},
|
||||
resolveWslHome: async () => '\\\\wsl.localhost\\Ubuntu\\home\\ada'
|
||||
})
|
||||
|
||||
expect(retired.complete).toBe(false)
|
||||
})
|
||||
|
||||
it('stays retryable when the distro home cannot be resolved, rather than memoizing the hole', async () => {
|
||||
// `getWslHomeAsync` shells out to `wsl.exe` and returns null for a stopped or slow distro.
|
||||
// Memoizing that as a complete "nothing is retired" is the STA-4472 defect itself, since the
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { homedir } from 'node:os'
|
||||
import { join } from 'node:path'
|
||||
import { parseWslUncPath } from '../shared/wsl-paths'
|
||||
import { isWslUncPath, parseWslUncPath } from '../shared/wsl-paths'
|
||||
import {
|
||||
encodeClaudeProjectPaths,
|
||||
isClaudeProjectDirInScope
|
||||
@@ -68,8 +68,14 @@ async function readDirectoryNames(path: string): Promise<{ names: string[]; refu
|
||||
// A missing root is itself a complete answer: the agent may never have run on this machine.
|
||||
// Anything else — a gate refusal, an EIO on a redirected or network home — leaves names
|
||||
// unread, and memoizing that as "nothing is retired" is the under-retiring direction.
|
||||
//
|
||||
// Never on UNC though: Windows reports an unreachable 9P route as ENOENT, so a distro that is
|
||||
// merely shut down is indistinguishable from one that never held buckets. `wsl.ts` already
|
||||
// refuses to trust a UNC ENOENT for the same reason. Believing it here would memoize the
|
||||
// STA-4472 hole for the process lifetime, since the cached distro home still resolves.
|
||||
const code = (error as NodeJS.ErrnoException | null)?.code
|
||||
return { names: [], refused: code !== 'ENOENT' && code !== 'ENOTDIR' }
|
||||
const absent = code === 'ENOENT' || code === 'ENOTDIR'
|
||||
return { names: [], refused: !absent || isWslUncPath(path) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user