From 5bbd81a01fa5281ee17c4b4fbafc2e58d1327f7d Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN Date: Wed, 30 Sep 2026 21:10:06 -0400 Subject: [PATCH] TASK-pilot-executor-outcomes fail closed CLI fixture --- docs/TEST_INTEGRITY.md | 2 +- src/cli.mjs | 5 +++- test/fleet/executor-outcomes.test.mjs | 35 ++++++++++++++++++++++++--- 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/docs/TEST_INTEGRITY.md b/docs/TEST_INTEGRITY.md index 31bac41..1ef5775 100644 --- a/docs/TEST_INTEGRITY.md +++ b/docs/TEST_INTEGRITY.md @@ -129,7 +129,7 @@ test_integrity_note: - Actual CLI JSON response and persisted identity state from a fake executable on an isolated PATH determinism_controls: - Local child process signal handshake driven by receipt of thread.started; a bounded watchdog only terminates and awaits the owned fixture on failed emission, never retries or asserts product timing - - Disposable Git/XDG fixtures and a hermetic executable; no provider, network, or account access + - Disposable Git/XDG fixtures and a hermetic executable; a tagged guard rejects an absent or mismatched env before native spawn, then delegates unchanged to native spawnSync only for the validated fake path anti_cheat_rationale: prevents: - Delaying identity output until child close and losing it on interruption diff --git a/src/cli.mjs b/src/cli.mjs index 5b01283..e136d1d 100644 --- a/src/cli.mjs +++ b/src/cli.mjs @@ -52,7 +52,10 @@ const CODEX_PROTOCOL_REDUCER = fileURLToPath(new URL('./runtime/codex-protocol-r export function executeRuntimeLaunch(spawn, launch, options = {}) { // Tests and adapter qualification inject a deterministic executor. The real // synchronous CLI boundary alone needs protocol reduction before buffering. - if (launch.runtime === 'codex' && spawn === spawnSync) { + // A tagged guard may delegate to native spawnSync after asserting hermetic + // launch preconditions; it must opt in rather than changing fake executors. + const usesNativeSpawn = spawn === spawnSync || spawn?.torchNativeSpawnGuard === true; + if (launch.runtime === 'codex' && usesNativeSpawn) { return spawn(process.execPath, [CODEX_PROTOCOL_REDUCER, launch.command, ...launch.args], options); } return spawn(launch.command, launch.args, options); diff --git a/test/fleet/executor-outcomes.test.mjs b/test/fleet/executor-outcomes.test.mjs index a3f13e2..ce1bf65 100644 --- a/test/fleet/executor-outcomes.test.mjs +++ b/test/fleet/executor-outcomes.test.mjs @@ -148,6 +148,23 @@ async function captureStdout(action) { } } +function nativeSpawnGuard({ expectedEnv, expectedMarker, delegate } = {}) { + const calls = []; + const guard = (command, args, options) => { + calls.push({ command, args, options }); + assert.equal(command, process.execPath, 'Codex must launch through the real protocol reducer process'); + assert.equal(args[0], CODEX_PROTOCOL_REDUCER); + assert.equal(args[1], 'codex'); + assert.equal(options.env, expectedEnv, 'runCli must forward the exact injected environment'); + assert.equal(options.env.PATH, expectedEnv.PATH); + assert.equal(options.env.TORCH_FAKE_CODEX_INVOCATION_MARKER, expectedMarker); + if (!expectedMarker) throw new Error('fixture guard rejected missing Codex invocation marker before spawn'); + return delegate(command, args, options); + }; + guard.torchNativeSpawnGuard = true; + return { guard, calls }; +} + test('SCN-executor-interrupted-outcomes: a graceful ready timeout, signal, or ENOBUFS cannot create an idle turn or disclose output', () => { const readyDirectory = mkdtempSync(join(tmpdir(), 'torch-executor-ready-')); const readyPath = join(readyDirectory, 'ready'); @@ -322,20 +339,30 @@ test('SCN-cli-codex-real-executable: an actual runCli invocation reaches the iso 'worktrees', '--parent', worktreeParent, '--yes', '--json', ], cliOptions)); assert.equal(worktrees.status, 0, worktrees.output); + const missingEnv = { ...context.env, PATH: `${bin}:${process.env.PATH}` }; + const missingMarkerGuard = nativeSpawnGuard({ + expectedEnv: missingEnv, expectedMarker: undefined, delegate: spawnSync, + }); const missingMarker = await captureStdout(() => runCli([ 'up', '--fresh', '--only', context.worker, '--yes', '--json', ], { cwd: context.root, - env: { ...context.env, PATH: `${bin}:${process.env.PATH}` }, + env: missingEnv, + spawn: missingMarkerGuard.guard, })); - assert.equal(missingMarker.status, 2, missingMarker.output); - assert.equal(JSON.parse(missingMarker.output).error, 'FLEET_START_FAILED'); + assert.equal(missingMarker.status, 1, missingMarker.output); + assert.equal(JSON.parse(missingMarker.output).error, 'UNEXPECTED_ERROR'); + assert.equal(missingMarkerGuard.calls.length, 1, 'guard must reject before any native child starts'); assert.equal(existsSync(marker), false, 'fake executable must fail before it can claim invocation without its marker'); assert.ok(Buffer.byteLength(missingMarker.output) < 4 * 1024, 'failed CLI response must remain bounded'); + const validGuard = nativeSpawnGuard({ + expectedEnv: cliOptions.env, expectedMarker: marker, delegate: spawnSync, + }); const captured = await captureStdout(() => runCli([ 'up', '--fresh', '--only', context.worker, '--yes', '--json', - ], cliOptions)); + ], { ...cliOptions, spawn: validGuard.guard })); assert.equal(captured.status, 0, captured.output); + assert.equal(validGuard.calls.length, 1, 'valid guard must delegate exactly one native reducer launch'); assert.equal(process.env[markerEnv], inheritedMarker, 'runCli must not mutate the process environment'); const invocation = JSON.parse(readFileSync(marker, 'utf8')); assert.equal(invocation.args.includes('exec'), true, 'the isolated executable must receive the Codex exec invocation');