Files
orca/config/scripts/windows-cmd-shim-spawn-boundary.test.mjs
T
ff27338299 refactor(ssh): connect fails for hosts orcad can't serve; remove the relay client path (#27214)
* wip: connect fails for hosts the managed server can't serve; remove relay session, deploy and relay UI

* wip: delete relay-only client modules left unreachable, prune their tests and gates

* wip: format

* wip: exhaustive unserved message

* wip: drop relay attestation test for the deleted ownership proof

* fix: prune stale baselines; type the test transport stub

* fix(ssh): census proves leftover relay leases; name the remedy for older terminals; translate every connect-failure surface

* test(ssh): leftover leases defer to the host census

* test(e2e): remove relay-path SSH e2e specs and their CI lanes

* test(e2e): drop the auto-convert case that built its relay era through a live relay

* test(e2e): mark relay-era browser and catalog journeys fixme until they seed a profile

* test(e2e): seed relay-era browser and catalog journeys from a saved profile

The three journeys built their old-version state through a connect without an orcad template, which now refuses the host. They now start from a seeded relay-era profile, so the first connect converts the host as an upgrading user's would.

* chore(ci): drop shard timings for the deleted relay tests

* test(e2e): carry a relay-era login cookie across the browser conversion; own every launch

* test(ci): drop the deleted SSH layout oracle from its route

* test(e2e): open the retained browser after conversion, retrying a pre-connect card

* test(e2e): bind the relay-era browser partition before seeding its cookie

A relay-era build always recorded the partition binding before a page stored
data in it. Seeding the cookie into an unbound partition made the binding store
refuse it (browser_route_partition_binding_store_invalid), so the retained tab
showed the generic routing card and Retry could never clear it.

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: m4air <m4air@Mac.localdomain>
Co-authored-by: Claude <noreply@anthropic.com>
2026-10-10 22:10:33 -07:00

107 lines
4.8 KiB
JavaScript

import { readdirSync, readFileSync } from 'node:fs'
import path from 'node:path'
import { describe, expect, it } from 'vitest'
import { hasNodeModulesBinSpawn } from './windows-bin-spawn-predicate.mjs'
/**
* Bare JS scripts cannot use the TS runProcess chokepoint; resolve package bins
* under process.execPath instead (see oxc-cli-invocation.mjs). The list only shrinks.
* The literal check catches quoted .cmd/.bat paths, excluding drive letters and
* templates; comment-only lines are dropped, but trailing comments fail closed.
* The AST check catches spawn/spawnSync/execFile/execFileSync first arguments
* containing node_modules/.bin: literals, templates, concatenation, join/resolve,
* local variable initializers and ternaries. It does not follow imports, function
* returns, assignments, destructuring, aliased spawn names or computed members.
* Names are matched without scope/import resolution; shadowed names and non-path
* join/resolve calls can fail closed. Paths are joined textually, without reducing
* dot segments. Neither check proves a Windows branch or an actual unsafe spawn.
*/
const WINDOWS_SHIM_LITERAL = /['"][\w./\\-]*\.(?:cmd|bat)['"]/i
const SCANNED_ROOTS = ['config/scripts', 'tests/tools']
/** Scripts that still name a batch shim, held as data so it reads as the list it is. */
const WINDOWS_SHIM_SPAWN_ALLOWLIST = [
// Owns the pnpm invocation decision for every other script.
'config/scripts/pnpm-cli-invocation.mjs',
'config/scripts/pnpm-cli-invocation.test.mjs',
// Write or assert on shim files rather than spawning one.
'config/scripts/dev-cli-terminal-wrapper.mjs',
'config/scripts/dev-cli-terminal-wrapper.test.mjs',
'config/scripts/electron-builder-config.test.mjs',
'config/scripts/live-remote-freeze-rpc.mjs',
'config/scripts/pty-transcript-secret-scan.test.mjs',
'config/scripts/remote-agent-session-authority-repro.mjs',
// Platform-local build paths; the win32 branch is dead code on both.
'config/scripts/build-mac-local.mjs',
'config/scripts/build-linux-local.mjs',
'config/scripts/build-linux-local.test.mjs',
// Benchmarks, repros and e2e drivers — developer-invoked or Linux-only in CI.
'config/scripts/run-ai-vault-typing-bench.mjs',
'config/scripts/run-ephemeral-vm-runtime-store-rollback-repro.mjs',
'config/scripts/run-multi-client-navigation-e2e.mjs',
'config/scripts/run-multi-workspace-typing-bench.mjs',
'config/scripts/run-ssh-staged-upload-reliability.mjs',
'config/scripts/run-terminal-ibus-hangul-e2e.mjs',
'config/scripts/run-terminal-scale-perf-e2e.mjs',
// Routes its shim through an explicit `cmd.exe /d /s /c`, which is the correct form.
'config/scripts/verify-skill-update-roundtrip.mjs',
'tests/tools/benchmarks/startup-time-bench.mjs',
'tests/tools/benchmarks/worktree-deletion-dev-bench.mjs',
'tests/tools/repro-terminal-send-submit.mjs'
]
/** Drop comment-only lines so prose about the old idiom is not an offender. */
function codeText(contents) {
return contents
.split('\n')
.filter((line) => !/^\s*(?:\/\/|\/\*|\*)/.test(line))
.join('\n')
}
// Why recursive: a future config/scripts/<subdir>/ would otherwise escape silently.
function collectScripts(directory, repoRoot, found = []) {
for (const entry of readdirSync(directory, { withFileTypes: true })) {
const full = path.join(directory, entry.name)
if (entry.isDirectory()) {
if (entry.name !== 'node_modules') {
collectScripts(full, repoRoot, found)
}
continue
}
if (/\.[cm]?js$/.test(entry.name)) {
found.push(path.relative(repoRoot, full).split(path.sep).join('/'))
}
}
return found
}
describe('windows batch shim spawn boundary', () => {
const repoRoot = path.resolve(import.meta.dirname, '..', '..')
const scripts = SCANNED_ROOTS.flatMap((root) =>
collectScripts(path.join(repoRoot, root), repoRoot)
)
const offenders = scripts.filter((relativePath) => {
const contents = readFileSync(path.join(repoRoot, relativePath), 'utf8')
return WINDOWS_SHIM_LITERAL.test(codeText(contents)) || hasNodeModulesBinSpawn(contents)
})
it('scans a plausible number of scripts', () => {
// A broken root or extension filter would make the guard silently vacuous.
expect(scripts.length).toBeGreaterThan(100)
})
it('has no unlisted script naming a Windows batch shim or spawning a package bin shim', () => {
const unlisted = offenders.filter((name) => !WINDOWS_SHIM_SPAWN_ALLOWLIST.includes(name))
expect(
unlisted,
'Node cannot spawn a Windows batch shim without a shell. Resolve the real executable — see oxc-cli-invocation.mjs.'
).toEqual([])
})
it('has no stale allowlist entry', () => {
const stale = WINDOWS_SHIM_SPAWN_ALLOWLIST.filter((name) => !offenders.includes(name))
expect(stale, 'Script no longer matches either shim predicate — delete the line.').toEqual([])
})
})