diff --git a/src/main/ssh/ssh-relay-cross-version-isolation.test.ts b/src/main/ssh/ssh-relay-cross-version-isolation.test.ts index d566a9b067d..ce5fcecb835 100644 --- a/src/main/ssh/ssh-relay-cross-version-isolation.test.ts +++ b/src/main/ssh/ssh-relay-cross-version-isolation.test.ts @@ -104,7 +104,7 @@ describe('cross-version isolation', () => { // // We feed enough exec results to walk through the deploy: platform, // $HOME, isRelayAlreadyInstalled probe, lock acquire, upload (no exec), - // npm install, finalize, socket probe, socket poll, then GC scan. + // npm install, finalize, socket probe, credential publication, socket poll, then GC scan. const responses: string[] = [ '__ORCA_REMOTE_PLATFORM__ Linux x86_64', // tagged POSIX platform probe '/home/u', // echo $HOME @@ -122,6 +122,7 @@ describe('cross-version isolation', () => { '', // rm -f probe-stderr (best-effort cleanup after probe resolved) '', // touch .install-complete (finalizeInstall) 'DEAD', // launch socket probe + '', // publish the per-launch credential 'READY', // socket poll '', // release .install-lock after relay liveness is observable // GC scan begins here diff --git a/src/main/ssh/ssh-relay-native-deps-install-fixture.ts b/src/main/ssh/ssh-relay-native-deps-install-fixture.ts index ea2b1aa073b..f2f9ebf4298 100644 --- a/src/main/ssh/ssh-relay-native-deps-install-fixture.ts +++ b/src/main/ssh/ssh-relay-native-deps-install-fixture.ts @@ -71,6 +71,7 @@ export function makeRepairToolchainSkipExecResponses(): ExecResponse[] { '', // cat probe stderr '', // rm -f probe stderr 'DEAD', + '', // publish the per-launch credential 'READY' ] } @@ -80,7 +81,7 @@ export function decodePowerShellCommand(command: string): string | null { return match ? Buffer.from(match[1], 'base64').toString('utf16le') : null } -// Happy-path exec order: uname, $HOME, mkdir, chmod node, npm install, chmod prebuilds, probe, [cat stderr + rm if MISSING], [rebuild → chmod → re-probe if MISSING], DEAD, READY. +// Happy-path exec order ends with socket probe, credential publication, then readiness poll. // When the probe rejects (SSH channel close or vanished install dir), the catch skips both stderr-capture and the rm. // A failed npm install takes one of the two early branches below instead, which never reach `probe`. export function makeExecResponses(opts: { @@ -134,6 +135,7 @@ export function makeExecResponses(opts: { '', // cat probe stderr '', // rm -f probe stderr 'DEAD', + '', // publish the per-launch credential 'READY' ] } @@ -176,6 +178,6 @@ export function makeExecResponses(opts: { slots.push('') // rm -f stderr after rebuild probe } } - slots.push('DEAD', 'READY') + slots.push('DEAD', '', 'READY') return slots } diff --git a/src/main/ssh/ssh-relay-native-deps-install.test.ts b/src/main/ssh/ssh-relay-native-deps-install.test.ts index 5aaf7e6aa49..3036d1d633c 100644 --- a/src/main/ssh/ssh-relay-native-deps-install.test.ts +++ b/src/main/ssh/ssh-relay-native-deps-install.test.ts @@ -567,6 +567,7 @@ describe('installNativeDeps (via deployAndLaunchRelay)', () => { 'MISSING\n', // rebuilt native process still cannot load '', // no persisted active pipe marker 'WAITING', + '', // publish the per-launch credential '', // WMI relay launch 'READY', '' // persist active pipe marker @@ -661,6 +662,7 @@ describe('installNativeDeps (via deployAndLaunchRelay)', () => { 'ORCA-NPTY-PROBE-OK\n', '', // rm probe stderr 'DEAD', + '', // publish the per-launch credential 'READY' ]) @@ -711,8 +713,8 @@ describe('installNativeDeps (via deployAndLaunchRelay)', () => { 'MISSING', // re-probe after lock '', // SFTP-namespace install-owner marker (repair) { reject: 'npm ERR! network ETIMEDOUT' }, // npm install fails (offline) - '', // remote credential generation after degraded repair 'DEAD', + '', // remote credential generation after degraded repair 'READY' ]) @@ -739,8 +741,8 @@ describe('installNativeDeps (via deployAndLaunchRelay)', () => { sshChannelCloseConfirmed: false }) ) - .mockResolvedValueOnce('') // remote credential generation after degraded repair .mockResolvedValueOnce('DEAD') + .mockResolvedValueOnce('') // remote credential generation after degraded repair .mockResolvedValueOnce('READY') await deployAndLaunchRelay(conn) @@ -886,8 +888,8 @@ describe('installNativeDeps (via deployAndLaunchRelay)', () => { '__ORCA_REMOTE_PLATFORM__ Linux x86_64', '/home/u', 'MISSING', - '', // remote credential generation without a namespace marker 'DEAD', + '', // remote credential generation without a namespace marker 'READY' ]) @@ -910,6 +912,7 @@ describe('installNativeDeps (via deployAndLaunchRelay)', () => { 'ORCA-NATIVE-DEPS-OK', '', // launch namespace marker 'DEAD', + '', // publish the per-launch credential 'READY' ]) @@ -934,6 +937,7 @@ describe('installNativeDeps (via deployAndLaunchRelay)', () => { 'ORCA-NATIVE-DEPS-OK', '', // launch namespace marker 'DEAD', + '', // publish the per-launch credential 'READY' ]) diff --git a/src/main/ssh/ssh-relay-sftp-namespace-install.test.ts b/src/main/ssh/ssh-relay-sftp-namespace-install.test.ts index 4c2ffad19b8..324781486de 100644 --- a/src/main/ssh/ssh-relay-sftp-namespace-install.test.ts +++ b/src/main/ssh/ssh-relay-sftp-namespace-install.test.ts @@ -238,6 +238,7 @@ const POSIX_FIRST_INSTALL = [ 'ORCA-NPTY-PROBE-OK\n', '', // rm probe stderr 'DEAD', + '', // publish the per-launch credential 'READY' ] @@ -253,6 +254,7 @@ const POSIX_REPAIR = [ 'ORCA-NPTY-PROBE-OK\n', '', // rm probe stderr 'DEAD', + '', // publish the per-launch credential 'READY' ] @@ -262,6 +264,7 @@ const POSIX_HEALTHY_RECONNECT = [ 'ORCA-NATIVE-DEPS-OK', '', // per-launch namespace marker 'DEAD', + '', // publish the per-launch credential 'READY' ] @@ -289,7 +292,7 @@ describe('relay install writes on a split SFTP namespace', () => { vi.restoreAllMocks() }) - it('redirects every first-install write while shell commands keep the canonical path', async () => { + it('redirects every first-install artifact transfer while shell commands stay canonical', async () => { const conn = makeConnection(capture) feed(POSIX_FIRST_INSTALL) @@ -298,8 +301,7 @@ describe('relay install writes on a split SFTP namespace', () => { expect(capture.uploadTargets).toEqual([SFTP_RELAY_DIR]) expect(capture.writePaths).toEqual([ `${SFTP_RELAY_DIR}/.version`, - `${SFTP_RELAY_DIR}/package.json`, - `${SFTP_RELAY_DIR}/relay.sock.credential` + `${SFTP_RELAY_DIR}/package.json` ]) // Every shell command — mkdir, chmod, npm, launch — still names the shell path. for (const command of execCommands()) { @@ -320,7 +322,7 @@ describe('relay install writes on a split SFTP namespace', () => { expect(markerCommands[0]).toContain(`${SHELL_RELAY_DIR}/.install-lock`) }) - it('probes one shared marker for every write of an install', async () => { + it('probes one shared marker for every first-install artifact transfer', async () => { const conn = makeConnection(capture) feed(POSIX_FIRST_INSTALL) @@ -334,8 +336,6 @@ describe('relay install writes on a split SFTP namespace', () => { `${SHELL_RELAY_DIR}/.install-lock/${marker}`, `${SFTP_RELAY_DIR}/.install-lock/${marker}`, `${SHELL_RELAY_DIR}/.install-lock/${marker}`, - `${SFTP_RELAY_DIR}/.install-lock/${marker}`, - `${SHELL_RELAY_DIR}/.install-lock/${marker}`, `${SFTP_RELAY_DIR}/.install-lock/${marker}` ]) }) @@ -352,8 +352,7 @@ describe('relay install writes on a split SFTP namespace', () => { expect(capture.uploadTargets).toEqual([SHELL_RELAY_DIR]) expect(capture.writePaths).toEqual([ `${SHELL_RELAY_DIR}/.version`, - `${SHELL_RELAY_DIR}/package.json`, - `${SHELL_RELAY_DIR}/relay.sock.credential` + `${SHELL_RELAY_DIR}/package.json` ]) }) @@ -389,14 +388,13 @@ describe('relay install writes on a split SFTP namespace', () => { expect(capture.uploadTargets).toEqual([SHELL_RELAY_DIR]) expect(capture.writePaths).toEqual([ `${SHELL_RELAY_DIR}/.version`, - `${SHELL_RELAY_DIR}/package.json`, - `${SHELL_RELAY_DIR}/relay.sock.credential` + `${SHELL_RELAY_DIR}/package.json` ]) const marker = issuedMarkerName() const mappings = [...capture.uploadOptions, ...capture.writeOptions].map( (options) => options?.sftpNamespace ) - expect(mappings).toHaveLength(4) + expect(mappings).toHaveLength(3) for (const mapping of mappings) { expect(mapping?.shellProbePath).toBe(`${SHELL_RELAY_DIR}/.install-lock/${marker}`) expect(mapping?.homeRelativeProbePath).toBe(`${RELAY_SUFFIX}/.install-lock/${marker}`) @@ -404,8 +402,7 @@ describe('relay install writes on a split SFTP namespace', () => { expect(mappings.map((mapping) => mapping?.homeRelativePath)).toEqual([ RELAY_SUFFIX, `${RELAY_SUFFIX}/.version`, - `${RELAY_SUFFIX}/package.json`, - `${RELAY_SUFFIX}/relay.sock.credential` + `${RELAY_SUFFIX}/package.json` ]) expect(capture.realpathCalls).toEqual([]) }) @@ -425,11 +422,10 @@ describe('relay install writes on a split SFTP namespace', () => { expect(capture.uploadTargets).toEqual([SHELL_RELAY_DIR]) expect(capture.writePaths).toEqual([ `${SHELL_RELAY_DIR}/.version`, - `${SHELL_RELAY_DIR}/package.json`, - `${SHELL_RELAY_DIR}/relay.sock.credential` + `${SHELL_RELAY_DIR}/package.json` ]) const transferOptions = [...capture.uploadOptions, ...capture.writeOptions] - expect(transferOptions).toHaveLength(4) + expect(transferOptions).toHaveLength(3) for (const options of transferOptions) { expect(options?.sftpNamespace).toBeUndefined() } @@ -530,36 +526,28 @@ describe('relay repair writes on a split SFTP namespace', () => { vi.restoreAllMocks() }) - it('retains a healthy install marker through the shipping credential write', async () => { + it('publishes a healthy reconnect credential in the canonical shell namespace', async () => { const conn = makeConnection(capture, { transferMethods: true }) feed(POSIX_HEALTHY_RECONNECT) await deployAndLaunchRelay(conn) - const marker = issuedMarkerName() - expect(capture.writePaths).toEqual([`${SHELL_RELAY_DIR}/relay.sock.credential`]) - expect(capture.writeOptions[0]?.sftpNamespace).toEqual({ - homeRelativePath: `${RELAY_SUFFIX}/relay.sock.credential`, - shellProbePath: `${SHELL_RELAY_DIR}/.install-lock/${marker}`, - homeRelativeProbePath: `${RELAY_SUFFIX}/.install-lock/${marker}` - }) - expect(vi.mocked(conn.writeFile).mock.invocationCallOrder[0]).toBeLessThan( - vi.mocked(abandonInstall).mock.invocationCallOrder[0]! + expect(capture.writePaths).toEqual([]) + expect(execCommands().find((command) => command.includes('randomBytes'))).toContain( + `${SHELL_RELAY_DIR}/relay.sock.credential` ) }) - it('redirects a healthy installed reconnect through the fallback SFTP session', async () => { + it('does not redirect a healthy reconnect credential through fallback SFTP', async () => { const conn = makeConnection(capture) feed(POSIX_HEALTHY_RECONNECT) await deployAndLaunchRelay(conn) - const marker = issuedMarkerName() - expect(capture.writePaths).toEqual([`${SFTP_RELAY_DIR}/relay.sock.credential`]) - expect(capture.lstatCalls).toEqual([ - `${SHELL_RELAY_DIR}/.install-lock/${marker}`, - `${SFTP_RELAY_DIR}/.install-lock/${marker}` - ]) + expect(capture.writePaths).toEqual([]) + expect(execCommands().find((command) => command.includes('randomBytes'))).toContain( + `${SHELL_RELAY_DIR}/relay.sock.credential` + ) }) it.each(['busy', 'error'] as const)( @@ -593,15 +581,17 @@ describe('relay repair writes on a split SFTP namespace', () => { SHELL_HOME, 'ORCA-NATIVE-DEPS-OK', 'DEAD', + '', // remote credential generation 'READY' ]) await deployAndLaunchRelay(conn) expect(conn.sftp).not.toHaveBeenCalled() - expect(execCommands().some((command) => command.includes('randomBytes'))).toBe(false) - expect(capture.writePaths).toEqual([`${SHELL_RELAY_DIR}/relay.sock.credential`]) - expect(capture.writeOptions[0]?.sftpNamespace).toBeUndefined() + expect(execCommands().find((command) => command.includes('randomBytes'))).toContain( + `${SHELL_RELAY_DIR}/relay.sock.credential` + ) + expect(capture.writePaths).toEqual([]) }) it('falls back to remote credential generation when a healthy marker is unavailable', async () => { @@ -634,10 +624,7 @@ describe('relay repair writes on a split SFTP namespace', () => { expect(markerIndex).toBeGreaterThan(execCountAtLock) // The re-probe under the lock is the last exec before the marker. expect(commands[markerIndex - 1]).toContain('loadNativeModule') - expect(capture.writePaths).toEqual([ - `${SFTP_RELAY_DIR}/package.json`, - `${SFTP_RELAY_DIR}/relay.sock.credential` - ]) + expect(capture.writePaths).toEqual([`${SFTP_RELAY_DIR}/package.json`]) }) it('does not stamp a marker when repairing over system SSH', async () => { @@ -660,14 +647,11 @@ describe('relay repair writes on a split SFTP namespace', () => { expect(execCommands().some((command) => MARKER_PATTERN.test(command))).toBe(false) expect(conn.sftp).not.toHaveBeenCalled() - expect(capture.writePaths).toEqual([ - `${SHELL_RELAY_DIR}/package.json`, + expect(capture.writePaths).toEqual([`${SHELL_RELAY_DIR}/package.json`]) + expect(capture.writeOptions).toEqual([expect.objectContaining({ sftpNamespace: undefined })]) + expect(execCommands().find((command) => command.includes('randomBytes'))).toContain( `${SHELL_RELAY_DIR}/relay.sock.credential` - ]) - expect(capture.writeOptions).toEqual([ - expect.objectContaining({ sftpNamespace: undefined }), - expect.objectContaining({ sftpNamespace: undefined }) - ]) + ) }) it('degrades to shell paths when marker creation fails outright', async () => {