diff --git a/.github/workflows/ssh-relay-runtime-artifacts.yml b/.github/workflows/ssh-relay-runtime-artifacts.yml
index 060ed032bc6..d90f0de0a07 100644
--- a/.github/workflows/ssh-relay-runtime-artifacts.yml
+++ b/.github/workflows/ssh-relay-runtime-artifacts.yml
@@ -289,6 +289,7 @@ jobs:
src/main/ssh/ssh-relay-runtime-posix-control-command.test.ts \
src/main/ssh/ssh-relay-runtime-posix-file-destination.test.ts \
src/main/ssh/ssh-relay-runtime-windows-file-destination.test.ts \
+ src/main/ssh/ssh-relay-runtime-windows-staging-control.test.ts \
src/main/ssh/ssh-relay-runtime-posix-tree-transfer.test.ts \
src/main/ssh/ssh-relay-runtime-system-ssh-file-channel.test.ts \
src/main/ssh/ssh-relay-runtime-sftp-file-destination.test.ts \
@@ -1029,6 +1030,7 @@ jobs:
src/main/ssh/ssh-relay-runtime-posix-control-command.test.ts `
src/main/ssh/ssh-relay-runtime-posix-file-destination.test.ts `
src/main/ssh/ssh-relay-runtime-windows-file-destination.test.ts `
+ src/main/ssh/ssh-relay-runtime-windows-staging-control.test.ts `
src/main/ssh/ssh-relay-runtime-posix-tree-transfer.test.ts `
src/main/ssh/ssh-relay-runtime-system-ssh-file-channel.test.ts `
src/main/ssh/ssh-relay-runtime-sftp-file-destination.test.ts `
diff --git a/config/scripts/ssh-relay-runtime-workflow.test.mjs b/config/scripts/ssh-relay-runtime-workflow.test.mjs
index a6fe6d77643..a5ee8115b4e 100644
--- a/config/scripts/ssh-relay-runtime-workflow.test.mjs
+++ b/config/scripts/ssh-relay-runtime-workflow.test.mjs
@@ -203,6 +203,7 @@ describe('SSH relay runtime artifact workflow', () => {
'ssh-relay-runtime-posix-control-command.test.ts',
'ssh-relay-runtime-posix-file-destination.test.ts',
'ssh-relay-runtime-windows-file-destination.test.ts',
+ 'ssh-relay-runtime-windows-staging-control.test.ts',
'ssh-relay-runtime-posix-tree-transfer.test.ts',
'ssh-relay-runtime-system-ssh-file-channel.test.ts',
'ssh-relay-runtime-sftp-file-destination.test.ts',
diff --git a/docs/reference/plans/2026-07-14-ssh-relay-github-release-implementation-checklist-summary.md b/docs/reference/plans/2026-07-14-ssh-relay-github-release-implementation-checklist-summary.md
index fc6fbf7b87c..2f9aa143edd 100644
--- a/docs/reference/plans/2026-07-14-ssh-relay-github-release-implementation-checklist-summary.md
+++ b/docs/reference/plans/2026-07-14-ssh-relay-github-release-implementation-checklist-summary.md
@@ -10,12 +10,19 @@ A checked box means the work has evidence in the detailed ledger. Design approva
complete a box.
Active checkpoint: **Milestone 6 / Work Package 5 bounded runtime transfer — disconnected Windows
-system-SSH staging-control contract audit, 2026-07-15, Codex implementation owner.**
+system-SSH staging control is locally green; native Windows CI is next, 2026-07-15, Codex
+implementation owner.**
The next slice is limited to fixed-command, bounded binary PowerShell 5.1 requests for exclusive
staging-root creation, declared-directory creation, and owned-root cleanup. It must preserve a
pre-existing root, bound and strictly decode paths, join cancellation/settlement, and remain
disconnected. File/tree composition, live OpenSSH, product callers, legacy upload/fallback/default
behavior, tuple enablement, publication, and SignPath remain out of scope.
+`E-M6-WINDOWS-SYSTEM-SSH-CONTROL-LOCAL-RED-001` proves the native workflow oracle passes 9/9 and
+the purpose suite fails solely because the audited production staging-control module is absent.
+`E-M6-WINDOWS-SYSTEM-SSH-CONTROL-LOCAL-001` records 16/17 purpose cases locally with the real
+PowerShell case honestly skipped, 207 focused cases, 686 broad relay cases, 282/282 release
+contracts, typecheck, full lint, formatting, diff, protected-resolver, and no-product-consumer
+gates. Native Windows x64/arm64 `powershell.exe` proof remains required.
`E-M6-WINDOWS-SYSTEM-SSH-FILE-LOCAL-RED-001` proves the workflow oracle passes 9/9 and the new
purpose suite fails solely because the audited production destination is absent.
`E-M6-WINDOWS-SYSTEM-SSH-FILE-LOCAL-001` records 14/15 Windows purpose cases locally with the real
diff --git a/docs/reference/plans/2026-07-14-ssh-relay-github-release-implementation-checklist.md b/docs/reference/plans/2026-07-14-ssh-relay-github-release-implementation-checklist.md
index 0710dc08c23..ed966eee804 100644
--- a/docs/reference/plans/2026-07-14-ssh-relay-github-release-implementation-checklist.md
+++ b/docs/reference/plans/2026-07-14-ssh-relay-github-release-implementation-checklist.md
@@ -8,8 +8,8 @@ work; keep exact commands, runner identities, hashes, metrics, and residual gaps
Date created: 2026-07-14
Last updated: 2026-07-15
-Current phase: Milestone 6 / Work Package 5 bounded runtime transfer — **In progress — 2026-07-15, Codex implementation owner: disconnected Windows system-SSH staging-control contract audit**. Keep every capability disconnected from every production/default SSH path. Real Apple/SignPath rehearsals remain an explicit late gate and are not on this package's critical path.
-Session checkpoint: **WINDOWS PER-FILE NATIVE PROOF CLOSED / STAGING CONTROL AUDIT ACTIVE — 2026-07-15, Codex implementation owner** — `E-M6-WINDOWS-SYSTEM-SSH-FILE-CI-001` proves the real PowerShell receiver on native Windows x64/arm64 and closes the adjacent watcher flake with a same-SHA rerun; only the declared hosted Windows arm64 build-26200 versus required-26100 floor rejection remains. Audit the next disconnected fixed-command staging-root/directory/cleanup contract before writing RED tests. Do not compose file streaming into a tree, connect a product caller, change legacy upload/fallback/default behavior, enable a tuple, publish an artifact, or perform SignPath work in this package. Merging to `main` remains prohibited, SignPath is deferred, and legacy remains the production default.
+Current phase: Milestone 6 / Work Package 5 bounded runtime transfer — **In progress — 2026-07-15, Codex implementation owner: disconnected Windows system-SSH staging-control native proof**. Keep every capability disconnected from every production/default SSH path. Real Apple/SignPath rehearsals remain an explicit late gate and are not on this package's critical path.
+Session checkpoint: **WINDOWS STAGING CONTROL LOCALLY GREEN / NATIVE WINDOWS CI NEXT — 2026-07-15, Codex implementation owner** — `E-M6-WINDOWS-SYSTEM-SSH-CONTROL-LOCAL-001` proves the fixed-command bounded request, strict rooted-path/descendant validation, exclusive root/directory creation, parent-first enforcement, owned-root removal primitive, 30-second ceiling, joined command-channel lifecycle, prior transfer regressions, and production isolation locally. The real PowerShell 5.1 case is skipped on macOS and earns no native claim; commit and push the exact package, then require native Windows x64/arm64 proof. Do not compose file streaming into a tree, connect a product caller, change legacy upload/fallback/default behavior, enable a tuple, publish an artifact, or perform SignPath work in this package. Merging to `main` remains prohibited, SignPath is deferred, and legacy remains the production default.
Primary design: [SSH relay GitHub Release plan](./2026-07-14-ssh-relay-github-release-plan.html)
Motivating issues: [#8450](https://github.com/stablyai/orca/issues/8450), [#1693](https://github.com/stablyai/orca/issues/1693)
@@ -18286,6 +18286,73 @@ src/main/ssh/ssh-remote-node-resolution.ts src/main/ssh/ssh-remote-node-resoluti
settings/fallback/tuple/publication/default behavior, or SignPath is included. Legacy remains the
sole production/default path and every tuple stays disabled.
+### E-M6-WINDOWS-SYSTEM-SSH-CONTROL-LOCAL-RED-001 — audited staging control is absent
+
+- Date/owner/base/runner: 2026-07-15, Codex implementation owner; purpose test, native-workflow
+ wiring, and checklist-only diff atop exact base
+ `d24f877d96f07d691508cc686c0791a86d3dd308` on Apple arm64, macOS 26.2 build 25C56, Node
+ 26.0.0, pnpm 10.24.0.
+- Command: `pnpm exec vitest run --config config/vitest.config.ts --maxWorkers=1
+src/main/ssh/ssh-relay-runtime-windows-staging-control.test.ts
+config/scripts/ssh-relay-runtime-workflow.test.mjs`.
+- Result: expected failure in 1.39 seconds. The workflow oracle passes 9/9 and proves the new purpose
+ suite occurs exactly once in both native artifact command families. The purpose suite fails before
+ collection solely because `./ssh-relay-runtime-windows-staging-control` does not exist; zero
+ production modules are added or changed at this boundary.
+- Residual boundary: no PowerShell staging behavior or Windows runner claim follows from a missing
+ module. Purpose, native Windows, prior Windows/POSIX regression, broad relay/release, static,
+ isolation, and no-product-consumer gates remain required.
+
+### E-M6-WINDOWS-SYSTEM-SSH-CONTROL-LOCAL-001 — bounded staging control is locally green
+
+- Date/owner/base/runner: 2026-07-15, Codex implementation owner; uncommitted implementation,
+ purpose-test, native-workflow, and checklist package atop exact base
+ `d24f877d96f07d691508cc686c0791a86d3dd308` on Apple arm64, macOS 26.2 build 25C56, Node
+ 26.0.0, pnpm 10.24.0. The local Node version is newer than the repository's Node 24 contract and
+ the real Windows PowerShell case is skipped off Windows, so exact-head native proof remains
+ mandatory.
+- Implementation: add one disconnected fixed encoded PowerShell receiver with an at-most
+ 65,556-byte request, two independently bounded 32-KiB strict-UTF-8 path fields, operation byte and
+ zeroed reserved bytes. Client validation rejects non-rooted, reserved, traversal, non-descendant,
+ and oversized paths before channel open. The receiver rejects malformed framing/extra bytes,
+ requires each direct parent to exist, uses fail-on-existing `New-Item` for root/directories, and
+ removes only a root whose ownership is tracked by a later tree caller. Each operation has a
+ 30-second ceiling and reuses the proven 250 ms graceful/2-second forced channel settlement.
+- Focused command: `/usr/bin/time -l pnpm exec vitest run --config config/vitest.config.ts
+--maxWorkers=1` with the staging-control, Windows/POSIX file/control/tree, system-channel,
+ source-tree/scan/stream, system-fallback, connection, and workflow-oracle suites. Result: 11 files,
+ 207 passed and three declared platform skips out of 210; 8.85 seconds real, 184,500,224-byte
+ maximum RSS, 96,818,624-byte peak footprint, zero swaps and block I/O. The staging-control suite
+ contributes 16 passed plus one macOS-skipped real-PowerShell case; the workflow oracle passes 9/9.
+- Broad relay command: `/usr/bin/time -l pnpm exec vitest run --config config/vitest.config.ts
+--maxWorkers=1 src/main/ssh/ssh-relay-*.test.ts`. Result: 52 files passed, five files skipped; 686
+ passed and nine declared skips out of 695; 113.77 seconds real, 257,605,632-byte maximum RSS,
+ 97,572,312-byte peak footprint, zero swaps and block I/O. This and the release/lint commands ran
+ concurrently, so their wall times are recorded but are not standalone performance baselines.
+- Release-contract command: `/usr/bin/time -l pnpm exec vitest run --config
+config/vitest.config.ts --maxWorkers=1 config/scripts/ssh-relay-runtime-*.test.mjs`. Result: 50 files
+ and 282/282 cases pass; 81.81 seconds real, 189,317,120-byte maximum RSS, 96,146,808-byte peak
+ footprint, zero swaps and block I/O. Two prior quoted-wildcard invocations found no literal file;
+ they were command errors and were immediately replaced by these exact checklist commands.
+- Static evidence: `pnpm typecheck` passes. `/usr/bin/time -l pnpm lint` passes in 78.78 seconds real
+ with 2,106,277,888-byte maximum RSS and 96,081,152-byte peak footprint; its 26 warnings are
+ pre-existing outside this diff. Full lint proves switch exhaustiveness, 41 reliability gates, the
+ 355-entry max-lines ratchet with no new bypass, bundled guides, and localization checks. Targeted
+ `oxlint` and `oxfmt --check` pass.
+- Isolation evidence: `git diff --check` passes; `git diff --exit-code
+d24f877d96f07d691508cc686c0791a86d3dd308 -- src/main/ssh/ssh-remote-node-resolution.ts
+src/main/ssh/ssh-remote-node-resolution.test.ts` is empty. A non-test reference search finds the
+ staging-control export only in its owning production module. The intended diff is limited to the
+ disconnected staging-control module/purpose test, native workflow/oracle wiring, and both
+ checklist documents. No existing file receiver, POSIX/SFTP transfer, legacy uploader, product
+ importer, settings, Beta, fallback, tuple, publication, default-path, or signing behavior changes.
+- Residual boundary: local execution does not prove Windows PowerShell 5.1 parsing, exclusive
+ directory semantics, or cleanup on native Windows. Exact-head native Windows x64/arm64 purpose
+ proof and all-six adjacent native regression cells remain required. File/tree composition, live
+ Windows OpenSSH, full-size runtime transfer, long paths, endpoint-protection faults, capability
+ classification/cache, bundled-Node verification/install/publish/launch, product/Beta/fallback/
+ default behavior, tuple enablement, publication, Apple signing, and SignPath remain absent.
+
## Accepted Gaps
No product gap is accepted merely because it appears in this list. Each entry requires explicit
@@ -18344,9 +18411,9 @@ The project is not complete until every applicable item below is checked with ev
## Next Required Action
-Write and run the purpose-named RED suite and native-workflow oracle for
-`E-M6-WINDOWS-SYSTEM-SSH-CONTROL-AUDIT-001`, proving failure solely because the audited production
-module is absent. Do not check the broad Milestone 6 Windows system-SSH item yet. Do not compose file
+Commit and push the exact `E-M6-WINDOWS-SYSTEM-SSH-CONTROL-LOCAL-001` package, then require the real
+PowerShell 5.1 process oracle on native Windows x64/arm64 plus all-six native and adjacent repository
+regression cells. Do not check the broad Milestone 6 Windows system-SSH item yet. Do not compose file
streaming into a remote-tree owner or add an Electron/startup/product importer, per-target mode
wiring, fallback, tuple enablement, release publication, or default behavior.
Keep Node upstream `.tar.xz` inputs, Windows ZIP, `ORCA_RELAY_PATH`, existing desktop required-assets
diff --git a/src/main/ssh/ssh-relay-runtime-windows-staging-control.test.ts b/src/main/ssh/ssh-relay-runtime-windows-staging-control.test.ts
new file mode 100644
index 00000000000..1338f22b712
--- /dev/null
+++ b/src/main/ssh/ssh-relay-runtime-windows-staging-control.test.ts
@@ -0,0 +1,285 @@
+import { spawn } from 'node:child_process'
+import { mkdtemp, readFile, rm, writeFile } from 'node:fs/promises'
+import { tmpdir } from 'node:os'
+import path from 'node:path'
+import { afterEach, describe, expect, it, vi } from 'vitest'
+
+import type { SshRelayRuntimeCommandFileChannel } from './ssh-relay-runtime-command-file-destination'
+import {
+ runSshRelayRuntimeWindowsStagingControl,
+ SSH_RELAY_RUNTIME_WINDOWS_STAGING_CONTROL_LIMITS
+} from './ssh-relay-runtime-windows-staging-control'
+
+type Callback = (error?: Error) => void
+
+function createChannel() {
+ let resolveSettled: () => void = () => {}
+ let rejectSettled: (error: Error) => void = () => {}
+ const settled = new Promise((resolve, reject) => {
+ resolveSettled = resolve
+ rejectSettled = reject
+ })
+ const channel = {
+ write: vi.fn((_chunk: Buffer, callback: Callback) => callback()),
+ end: vi.fn(),
+ settled,
+ requestClose: vi.fn(),
+ forceClose: vi.fn()
+ }
+ return { channel, resolve: resolveSettled, reject: rejectSettled }
+}
+
+function decodeRequest(frame: Buffer) {
+ const rootLength = frame.readUInt32LE(12)
+ const pathLength = frame.readUInt32LE(16)
+ const rootStart = 20
+ const pathStart = rootStart + rootLength
+ return {
+ magic: frame.subarray(0, 8).toString('ascii'),
+ operation: frame.readUInt8(8),
+ reserved: frame.subarray(9, 12),
+ remoteRoot: frame.subarray(rootStart, pathStart).toString('utf8'),
+ remotePath: frame.subarray(pathStart, pathStart + pathLength).toString('utf8')
+ }
+}
+
+function decodePowerShellCommand(command: string): string {
+ const encoded = command.match(/-EncodedCommand\s+([A-Za-z0-9+/=]+)$/u)?.[1]
+ if (!encoded) {
+ throw new Error('PowerShell staging control command is not encoded')
+ }
+ return Buffer.from(encoded, 'base64').toString('utf16le')
+}
+
+function runControl(
+ channel: SshRelayRuntimeCommandFileChannel,
+ overrides: Partial[0]> = {}
+) {
+ return runSshRelayRuntimeWindowsStagingControl({
+ operation: 'create-directory',
+ remoteRoot: 'C:/Users/测试/.orca-remote/stage',
+ remotePath: 'C:/Users/测试/.orca-remote/stage/bin/native',
+ signal: new AbortController().signal,
+ openChannel: vi.fn(async () => channel),
+ ...overrides
+ })
+}
+
+afterEach(() => {
+ vi.useRealTimers()
+ vi.restoreAllMocks()
+})
+
+describe('SSH relay runtime Windows system-SSH staging control', () => {
+ it.each([
+ ['create-root', 1, ''],
+ ['create-directory', 2, 'C:/Users/测试/.orca-remote/stage/bin/native'],
+ ['remove-root', 3, '']
+ ] as const)(
+ 'sends one fixed bounded binary %s request',
+ async (operation, opcode, remotePath) => {
+ const fixture = createChannel()
+ const openChannel = vi.fn(async (_command: string, _signal: AbortSignal) => fixture.channel)
+ const running = runControl(fixture.channel, {
+ operation,
+ remotePath: remotePath || undefined,
+ openChannel
+ })
+
+ await vi.waitFor(() => expect(fixture.channel.end).toHaveBeenCalledOnce())
+ expect(openChannel).toHaveBeenCalledOnce()
+ const command = openChannel.mock.calls[0]?.[0] ?? ''
+ expect(command).toMatch(/^powershell\.exe .* -EncodedCommand [A-Za-z0-9+/=]+$/u)
+ expect(command).not.toContain('测试')
+ const script = decodePowerShellCommand(command)
+ expect(script).toContain('[Console]::OpenStandardInput()')
+ expect(script).toContain('New-Item -ItemType Directory -Path')
+ expect(script).toContain('[IO.Path]::GetDirectoryName')
+ expect(script).toContain('[IO.Directory]::Delete')
+ expect(script).toContain('$inputStream.ReadByte() -ne -1')
+ for (const forbidden of ['ReadToEnd', 'FromBase64String', 'ConvertFrom-Json']) {
+ expect(script).not.toContain(forbidden)
+ }
+
+ const frame = fixture.channel.write.mock.calls[0]?.[0]
+ expect(Buffer.isBuffer(frame)).toBe(true)
+ expect(frame.length).toBeLessThanOrEqual(
+ SSH_RELAY_RUNTIME_WINDOWS_STAGING_CONTROL_LIMITS.maximumRequestBytes
+ )
+ expect(decodeRequest(frame)).toEqual({
+ magic: 'ORCACTL1',
+ operation: opcode,
+ reserved: Buffer.alloc(3),
+ remoteRoot: 'C:/Users/测试/.orca-remote/stage',
+ remotePath
+ })
+ fixture.resolve()
+ await expect(running).resolves.toBeUndefined()
+ }
+ )
+
+ it.each([
+ ['create-root', 'relative/stage', undefined],
+ ['create-root', 'C:/', undefined],
+ ['create-root', 'C:/owned/../stage', undefined],
+ ['create-root', 'C:/owned/NUL', undefined],
+ [
+ 'create-root',
+ `C:/${'a'.repeat(SSH_RELAY_RUNTIME_WINDOWS_STAGING_CONTROL_LIMITS.maximumPathBytes)}`,
+ undefined
+ ],
+ ['create-root', 'C:/owned/stage', 'C:/owned/stage/extra'],
+ ['create-directory', 'C:/owned/stage', undefined],
+ ['create-directory', 'C:/owned/stage', 'C:/outside'],
+ ['create-directory', 'C:/owned/stage', 'C:/owned/stage'],
+ ['create-directory', 'C:/owned/stage', 'C:/owned/stage/report.txt:stream']
+ ] as const)(
+ 'rejects hostile %s root %j path %j before channel open',
+ async (operation, remoteRoot, remotePath) => {
+ const fixture = createChannel()
+ const openChannel = vi.fn(async () => fixture.channel)
+ await expect(
+ runControl(fixture.channel, { operation, remoteRoot, remotePath, openChannel })
+ ).rejects.toThrow(/invalid/i)
+ expect(openChannel).not.toHaveBeenCalled()
+ }
+ )
+
+ it('settles retained-request cancellation before rejecting', async () => {
+ const fixture = createChannel()
+ const controller = new AbortController()
+ const reason = new Error('cancelled retained Windows control request')
+ fixture.channel.write.mockImplementationOnce(() => {})
+ fixture.channel.requestClose.mockImplementation(() => fixture.resolve())
+ const running = runControl(fixture.channel, { signal: controller.signal })
+
+ await vi.waitFor(() => expect(fixture.channel.write).toHaveBeenCalledOnce())
+ controller.abort(reason)
+ await expect(running).rejects.toBe(reason)
+ expect(fixture.channel.requestClose).toHaveBeenCalledOnce()
+ expect(fixture.channel.forceClose).not.toHaveBeenCalled()
+ })
+
+ it('propagates remote failure only after request EOF and settlement', async () => {
+ const fixture = createChannel()
+ const running = runControl(fixture.channel)
+ await vi.waitFor(() => expect(fixture.channel.end).toHaveBeenCalledOnce())
+ const error = new Error('PowerShell staging control failed')
+ fixture.reject(error)
+ await expect(running).rejects.toBe(error)
+ })
+
+ it('turns the command ceiling into bounded cancellation and settlement', async () => {
+ vi.useFakeTimers()
+ const fixture = createChannel()
+ fixture.channel.requestClose.mockImplementation(() => fixture.resolve())
+ const running = runControl(fixture.channel)
+ const rejection = expect(running).rejects.toThrow(/timed out/i)
+
+ await vi.advanceTimersByTimeAsync(
+ SSH_RELAY_RUNTIME_WINDOWS_STAGING_CONTROL_LIMITS.commandTimeoutMs
+ )
+ await rejection
+ expect(fixture.channel.requestClose).toHaveBeenCalledOnce()
+ expect(fixture.channel.forceClose).not.toHaveBeenCalled()
+ })
+
+ it.skipIf(process.platform !== 'win32')(
+ 'proves exclusive root ownership, Unicode directories, and owned cleanup in PowerShell 5.1',
+ async () => {
+ const parent = await mkdtemp(path.join(tmpdir(), 'orca-relay-win-control-'))
+ const remoteRoot = path.join(parent, '测试 stage')
+ const remoteParent = path.join(remoteRoot, 'bin')
+ const remotePath = path.join(remoteParent, 'native')
+ try {
+ await runSshRelayRuntimeWindowsStagingControl({
+ operation: 'create-root',
+ remoteRoot,
+ signal: new AbortController().signal,
+ openChannel: openPowerShellChannel
+ })
+ const marker = path.join(remoteRoot, 'original.txt')
+ await writeFile(marker, 'preserve')
+ await expect(
+ runSshRelayRuntimeWindowsStagingControl({
+ operation: 'create-root',
+ remoteRoot,
+ signal: new AbortController().signal,
+ openChannel: openPowerShellChannel
+ })
+ ).rejects.toThrow(/PowerShell staging control failed/i)
+ expect(await readFile(marker, 'utf8')).toBe('preserve')
+
+ await expect(
+ runSshRelayRuntimeWindowsStagingControl({
+ operation: 'create-directory',
+ remoteRoot,
+ remotePath,
+ signal: new AbortController().signal,
+ openChannel: openPowerShellChannel
+ })
+ ).rejects.toThrow(/PowerShell staging control failed/i)
+ await runSshRelayRuntimeWindowsStagingControl({
+ operation: 'create-directory',
+ remoteRoot,
+ remotePath: remoteParent,
+ signal: new AbortController().signal,
+ openChannel: openPowerShellChannel
+ })
+ await runSshRelayRuntimeWindowsStagingControl({
+ operation: 'create-directory',
+ remoteRoot,
+ remotePath,
+ signal: new AbortController().signal,
+ openChannel: openPowerShellChannel
+ })
+ await runSshRelayRuntimeWindowsStagingControl({
+ operation: 'remove-root',
+ remoteRoot,
+ signal: new AbortController().signal,
+ openChannel: openPowerShellChannel
+ })
+ await expect(readFile(marker)).rejects.toMatchObject({ code: 'ENOENT' })
+ } finally {
+ await rm(parent, { recursive: true, force: true })
+ }
+ },
+ 30_000
+ )
+})
+
+async function openPowerShellChannel(command: string): Promise {
+ const encoded = command.match(/-EncodedCommand\s+([A-Za-z0-9+/=]+)$/u)?.[1]
+ if (!encoded) {
+ throw new Error('PowerShell staging control command is not encoded')
+ }
+ const child = spawn(
+ 'powershell.exe',
+ ['-NoProfile', '-NonInteractive', '-ExecutionPolicy', 'Bypass', '-EncodedCommand', encoded],
+ { stdio: ['pipe', 'ignore', 'pipe'], windowsHide: true }
+ )
+ let diagnostic = ''
+ child.stderr.setEncoding('utf8')
+ child.stderr.on('data', (chunk: string) => {
+ diagnostic = `${diagnostic}${chunk}`.slice(-4_096)
+ })
+ const settled = new Promise((resolve, reject) => {
+ child.once('error', reject)
+ child.once('close', (code, signal) => {
+ if (code === 0) {
+ resolve()
+ } else {
+ reject(new Error(`PowerShell staging control failed (${code ?? signal}): ${diagnostic}`))
+ }
+ })
+ })
+ return {
+ write: (chunk: Buffer, callback: Callback) => {
+ child.stdin.write(chunk, (error) => callback(error ?? undefined))
+ },
+ end: () => child.stdin.end(),
+ settled,
+ requestClose: () => child.kill(),
+ forceClose: () => child.kill('SIGKILL')
+ }
+}
diff --git a/src/main/ssh/ssh-relay-runtime-windows-staging-control.ts b/src/main/ssh/ssh-relay-runtime-windows-staging-control.ts
new file mode 100644
index 00000000000..0de0db3c57c
--- /dev/null
+++ b/src/main/ssh/ssh-relay-runtime-windows-staging-control.ts
@@ -0,0 +1,213 @@
+import { assertSafeRemotePathSegment, normalizeWindowsRemotePath } from './ssh-remote-platform'
+import { powerShellCommand } from './ssh-remote-powershell'
+import {
+ openSshRelayRuntimeCommandFileDestination,
+ type SshRelayRuntimeCommandFileChannel
+} from './ssh-relay-runtime-command-file-destination'
+
+export type SshRelayRuntimeWindowsStagingOperation =
+ | 'create-root'
+ | 'create-directory'
+ | 'remove-root'
+
+export type RunSshRelayRuntimeWindowsStagingControlOptions = Readonly<{
+ operation: SshRelayRuntimeWindowsStagingOperation
+ remoteRoot: string
+ remotePath?: string
+ signal: AbortSignal
+ openChannel: (command: string, signal: AbortSignal) => Promise
+}>
+
+const REQUEST_MAGIC = Buffer.from('ORCACTL1', 'ascii')
+const FIXED_REQUEST_BYTES = 20
+const MAXIMUM_PATH_BYTES = 32 * 1024
+const COMMAND_TIMEOUT_MS = 30_000
+
+const OPERATION_CODES: Record = {
+ 'create-root': 1,
+ 'create-directory': 2,
+ 'remove-root': 3
+}
+
+export const SSH_RELAY_RUNTIME_WINDOWS_STAGING_CONTROL_LIMITS = Object.freeze({
+ commandTimeoutMs: COMMAND_TIMEOUT_MS,
+ maximumPathBytes: MAXIMUM_PATH_BYTES,
+ maximumRequestBytes: FIXED_REQUEST_BYTES + MAXIMUM_PATH_BYTES * 2
+})
+
+const RECEIVER_SCRIPT = `
+$ErrorActionPreference = 'Stop'
+function Read-Exact([System.IO.Stream]$Stream, [byte[]]$Buffer, [int]$Count) {
+ $offset = 0
+ while ($offset -lt $Count) {
+ $read = $Stream.Read($Buffer, $offset, $Count - $offset)
+ if ($read -eq 0) { throw 'SSH relay runtime Windows staging control early EOF' }
+ $offset += $read
+ }
+}
+$inputStream = [Console]::OpenStandardInput()
+try {
+ [byte[]]$header = New-Object byte[] ${FIXED_REQUEST_BYTES}
+ Read-Exact $inputStream $header ${FIXED_REQUEST_BYTES}
+ if ([Text.Encoding]::ASCII.GetString($header, 0, 8) -ne 'ORCACTL1') { throw 'bad header' }
+ [byte]$operation = $header[8]
+ if ($header[9] -ne 0 -or $header[10] -ne 0 -or $header[11] -ne 0) { throw 'bad reserved bytes' }
+ [uint32]$rootLength = [BitConverter]::ToUInt32($header, 12)
+ [uint32]$pathLength = [BitConverter]::ToUInt32($header, 16)
+ if ($rootLength -eq 0 -or $rootLength -gt ${MAXIMUM_PATH_BYTES}) { throw 'bad root length' }
+ if ($pathLength -gt ${MAXIMUM_PATH_BYTES}) { throw 'bad path length' }
+ if (($operation -eq 2 -and $pathLength -eq 0) -or ($operation -ne 2 -and $pathLength -ne 0)) { throw 'bad operation path' }
+ if ($operation -lt 1 -or $operation -gt 3) { throw 'bad operation' }
+ [byte[]]$rootBytes = New-Object byte[] ([int]$rootLength)
+ [byte[]]$pathBytes = New-Object byte[] ([int]$pathLength)
+ Read-Exact $inputStream $rootBytes ([int]$rootLength)
+ Read-Exact $inputStream $pathBytes ([int]$pathLength)
+ if ($inputStream.ReadByte() -ne -1) { throw 'extra byte' }
+ $utf8 = New-Object Text.UTF8Encoding($false, $true)
+ $root = $utf8.GetString($rootBytes)
+ $path = if ($pathLength -eq 0) { '' } else { $utf8.GetString($pathBytes) }
+ if (-not [IO.Path]::IsPathRooted($root) -or $root.IndexOf([char]0) -ge 0) { throw 'bad root' }
+ if ($operation -eq 2) {
+ if (-not [IO.Path]::IsPathRooted($path) -or $path.IndexOf([char]0) -ge 0 -or -not $path.StartsWith($root + '/', [StringComparison]::Ordinal)) { throw 'bad child path' }
+ }
+ switch ($operation) {
+ 1 {
+ $parent = [IO.Path]::GetDirectoryName($root)
+ if ([string]::IsNullOrEmpty($parent) -or -not [IO.Directory]::Exists($parent)) { throw 'missing root parent' }
+ New-Item -ItemType Directory -Path $root -ErrorAction Stop | Out-Null
+ }
+ 2 {
+ $parent = [IO.Path]::GetDirectoryName($path)
+ if ([string]::IsNullOrEmpty($parent) -or -not [IO.Directory]::Exists($parent)) { throw 'missing directory parent' }
+ New-Item -ItemType Directory -Path $path -ErrorAction Stop | Out-Null
+ }
+ 3 {
+ if ([IO.File]::Exists($root)) { throw 'staging root became a file' }
+ if ([IO.Directory]::Exists($root)) { [IO.Directory]::Delete($root, $true) }
+ }
+ }
+} catch {
+ throw 'SSH relay runtime Windows staging control failed'
+}
+`.trim()
+
+const RECEIVER_COMMAND = powerShellCommand(RECEIVER_SCRIPT)
+
+function normalizeAbsolutePath(value: string): string {
+ if (
+ typeof value !== 'string' ||
+ value === '' ||
+ value.includes('\0') ||
+ value.includes('\r') ||
+ value.includes('\n')
+ ) {
+ throw new Error('SSH relay runtime Windows staging control path is invalid')
+ }
+ const normalized = normalizeWindowsRemotePath(value)
+ const driveRooted = /^[A-Za-z]:\//u.test(normalized)
+ const uncRooted = /^\/\/[^/]+\/[^/]+\//u.test(normalized)
+ if ((!driveRooted && !uncRooted) || normalized.endsWith('/')) {
+ throw new Error('SSH relay runtime Windows staging control path is invalid')
+ }
+ const segments = driveRooted ? normalized.slice(3).split('/') : normalized.slice(2).split('/')
+ try {
+ for (const segment of segments) {
+ assertSafeRemotePathSegment(segment, 'windows')
+ }
+ } catch {
+ throw new Error('SSH relay runtime Windows staging control path is invalid')
+ }
+ if (Buffer.byteLength(normalized, 'utf8') > MAXIMUM_PATH_BYTES) {
+ throw new Error('SSH relay runtime Windows staging control path is invalid')
+ }
+ return normalized
+}
+
+function validateOptions(options: RunSshRelayRuntimeWindowsStagingControlOptions): {
+ operation: SshRelayRuntimeWindowsStagingOperation
+ remoteRoot: string
+ remotePath: string
+} {
+ if (
+ !options ||
+ typeof options.operation !== 'string' ||
+ !Object.hasOwn(OPERATION_CODES, options.operation) ||
+ !options.signal ||
+ typeof options.openChannel !== 'function'
+ ) {
+ throw new Error('SSH relay runtime Windows staging control input is invalid')
+ }
+ const remoteRoot = normalizeAbsolutePath(options.remoteRoot)
+ if (options.operation !== 'create-directory') {
+ if (options.remotePath !== undefined) {
+ throw new Error('SSH relay runtime Windows staging control input is invalid')
+ }
+ return { operation: options.operation, remoteRoot, remotePath: '' }
+ }
+ const remotePath = normalizeAbsolutePath(options.remotePath as string)
+ // Why: control requests may create only a strict descendant of the root owned by the tree caller.
+ if (!remotePath.startsWith(`${remoteRoot}/`)) {
+ throw new Error('SSH relay runtime Windows staging control path is invalid')
+ }
+ return { operation: options.operation, remoteRoot, remotePath }
+}
+
+function buildRequest(
+ operation: SshRelayRuntimeWindowsStagingOperation,
+ remoteRoot: string,
+ remotePath: string
+): Buffer {
+ const rootBytes = Buffer.from(remoteRoot, 'utf8')
+ const pathBytes = Buffer.from(remotePath, 'utf8')
+ const request = Buffer.alloc(FIXED_REQUEST_BYTES + rootBytes.length + pathBytes.length)
+ REQUEST_MAGIC.copy(request, 0)
+ request.writeUInt8(OPERATION_CODES[operation], 8)
+ request.writeUInt32LE(rootBytes.length, 12)
+ request.writeUInt32LE(pathBytes.length, 16)
+ rootBytes.copy(request, FIXED_REQUEST_BYTES)
+ pathBytes.copy(request, FIXED_REQUEST_BYTES + rootBytes.length)
+ return request
+}
+
+export async function runSshRelayRuntimeWindowsStagingControl(
+ options: RunSshRelayRuntimeWindowsStagingControlOptions
+): Promise {
+ const { operation, remoteRoot, remotePath } = validateOptions(options)
+ const request = buildRequest(operation, remoteRoot, remotePath)
+ const commandController = new AbortController()
+ const onCallerAbort = (): void => commandController.abort(options.signal.reason)
+ options.signal.addEventListener('abort', onCallerAbort, { once: true })
+ if (options.signal.aborted) {
+ onCallerAbort()
+ }
+ const timeout = setTimeout(
+ () => commandController.abort(new Error('SSH relay runtime Windows staging control timed out')),
+ COMMAND_TIMEOUT_MS
+ )
+ try {
+ const destination = await openSshRelayRuntimeCommandFileDestination({
+ command: RECEIVER_COMMAND,
+ fileKind: 'Windows',
+ signal: commandController.signal,
+ openChannel: options.openChannel
+ })
+ try {
+ await destination.write(request)
+ await destination.close()
+ } catch (error) {
+ try {
+ // Why: a retained request buffer must settle before this bounded control operation returns.
+ await destination.abort(error)
+ } catch (cleanupError) {
+ throw new AggregateError(
+ [error, cleanupError],
+ 'SSH relay runtime Windows staging control cleanup failed'
+ )
+ }
+ throw error
+ }
+ } finally {
+ clearTimeout(timeout)
+ options.signal.removeEventListener('abort', onCallerAbort)
+ }
+}