mirror of
https://github.com/stablyai/orca.git
synced 2026-10-17 16:02:55 +00:00
test(ssh): settle Windows runtime PTY smoke
Co-authored-by: Orca <help@stably.ai>
This commit is contained in:
@@ -108,6 +108,7 @@ jobs:
|
||||
config/scripts/ssh-relay-node-tar-inspection.test.mjs \
|
||||
config/scripts/ssh-relay-node-zip-inspection.test.mjs \
|
||||
config/scripts/ssh-relay-runtime-artifact.test.mjs \
|
||||
config/scripts/ssh-relay-runtime-pty-smoke.test.mjs \
|
||||
config/scripts/ssh-relay-runtime-windows-tree.test.mjs \
|
||||
config/scripts/ssh-relay-runtime-zip.test.mjs \
|
||||
config/scripts/ssh-relay-runtime-workflow.test.mjs
|
||||
@@ -249,6 +250,7 @@ jobs:
|
||||
config/scripts/ssh-relay-node-tar-inspection.test.mjs `
|
||||
config/scripts/ssh-relay-node-zip-inspection.test.mjs `
|
||||
config/scripts/ssh-relay-runtime-artifact.test.mjs `
|
||||
config/scripts/ssh-relay-runtime-pty-smoke.test.mjs `
|
||||
config/scripts/ssh-relay-runtime-windows-tree.test.mjs `
|
||||
config/scripts/ssh-relay-runtime-zip.test.mjs `
|
||||
config/scripts/ssh-relay-runtime-workflow.test.mjs
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
'use strict'
|
||||
|
||||
function deadline(label, timeoutMs) {
|
||||
let timeout
|
||||
const promise = new Promise((_, reject) => {
|
||||
timeout = setTimeout(() => reject(new Error(`${label} exceeded ${timeoutMs} ms`)), timeoutMs)
|
||||
})
|
||||
return { promise, cancel: () => clearTimeout(timeout) }
|
||||
}
|
||||
|
||||
async function runSshRelayRuntimePtySmoke({
|
||||
nodePty,
|
||||
runtimeRequire,
|
||||
runtimeRoot,
|
||||
platform = process.platform,
|
||||
environment = process.env,
|
||||
timeoutMs = 15_000
|
||||
}) {
|
||||
const windows = platform === 'win32'
|
||||
const executable = windows
|
||||
? 'powershell.exe'
|
||||
: environment.SHELL && environment.SHELL.startsWith('/')
|
||||
? environment.SHELL
|
||||
: '/bin/sh'
|
||||
const arguments_ = windows
|
||||
? [
|
||||
'-NoLogo',
|
||||
'-NoProfile',
|
||||
'-Command',
|
||||
"$ErrorActionPreference='Stop';" +
|
||||
'[Console]::OutputEncoding=[Text.UTF8Encoding]::new($false);' +
|
||||
"Write-Output 'ORCA_PTY_READY';" +
|
||||
'$line=[Console]::ReadLine();' +
|
||||
'$size=$Host.UI.RawUI.WindowSize;' +
|
||||
'Write-Output ("ORCA_PTY_SIZE:{0}x{1}" -f $size.Width,$size.Height);' +
|
||||
'Write-Output ("ORCA_PTY_INPUT:{0}" -f $line);' +
|
||||
'exit 23'
|
||||
]
|
||||
: [
|
||||
'-c',
|
||||
'printf "ORCA_PTY_READY\\n"; IFS= read -r line; stty size; printf "ORCA_PTY_INPUT:%s\\n" "$line"; exit 23'
|
||||
]
|
||||
const terminal = nodePty.spawn(executable, arguments_, {
|
||||
name: 'xterm-256color',
|
||||
cols: 80,
|
||||
rows: 24,
|
||||
cwd: runtimeRoot,
|
||||
env: environment,
|
||||
useConpty: windows,
|
||||
// Why: the relay uses the bundled ConPTY runtime to preserve terminal rendering behavior.
|
||||
useConptyDll: windows
|
||||
})
|
||||
let output = ''
|
||||
let wroteInput = false
|
||||
const outputSubscription = terminal.onData((data) => {
|
||||
output += data
|
||||
if (!wroteInput && output.includes('ORCA_PTY_READY')) {
|
||||
wroteInput = true
|
||||
terminal.resize(101, 37)
|
||||
terminal.write('bounded-marker\r')
|
||||
}
|
||||
})
|
||||
let exitSubscription
|
||||
let limitSubscription
|
||||
const exited = new Promise((resolve, reject) => {
|
||||
exitSubscription = terminal.onExit(resolve)
|
||||
limitSubscription = terminal.onData(() => {
|
||||
if (output.length > 1024 * 1024) {
|
||||
reject(new Error('PTY smoke output exceeded 1 MiB'))
|
||||
}
|
||||
})
|
||||
})
|
||||
const timer = deadline('PTY smoke', timeoutMs)
|
||||
let result
|
||||
let cleanupStarted = false
|
||||
function settlePtyResources() {
|
||||
if (cleanupStarted) {
|
||||
return
|
||||
}
|
||||
cleanupStarted = true
|
||||
try {
|
||||
outputSubscription.dispose()
|
||||
exitSubscription.dispose()
|
||||
limitSubscription.dispose()
|
||||
} finally {
|
||||
if (!result || windows) {
|
||||
// Why: node-pty retains its Windows ConPTY worker handles after process exit until kill().
|
||||
terminal.kill()
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
result = await Promise.race([exited, timer.promise])
|
||||
if (
|
||||
result.exitCode !== 23 ||
|
||||
!output.includes('ORCA_PTY_INPUT:bounded-marker') ||
|
||||
!output.includes(windows ? 'ORCA_PTY_SIZE:101x37' : '37 101')
|
||||
) {
|
||||
throw new Error(
|
||||
`PTY smoke mismatch: exit=${result.exitCode} output=${JSON.stringify(output)}`
|
||||
)
|
||||
}
|
||||
const { loadNativeModule } = runtimeRequire('node-pty/lib/utils')
|
||||
const nativeNames = windows ? ['conpty', 'conpty_console_list'] : ['pty']
|
||||
const nativeDirectories = nativeNames.map((name) => loadNativeModule(name).dir)
|
||||
if (
|
||||
nativeDirectories.some(
|
||||
(directory) => !directory.replaceAll('\\', '/').includes('build/Release/')
|
||||
)
|
||||
) {
|
||||
throw new Error(
|
||||
`node-pty did not load patched build/Release artifacts: ${nativeDirectories.join(', ')}`
|
||||
)
|
||||
}
|
||||
return {
|
||||
exitCode: result.exitCode,
|
||||
resizedRows: 37,
|
||||
resizedColumns: 101,
|
||||
nativeDirectory: nativeDirectories.join(', ')
|
||||
}
|
||||
} finally {
|
||||
timer.cancel()
|
||||
settlePtyResources()
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { runSshRelayRuntimePtySmoke }
|
||||
@@ -0,0 +1,91 @@
|
||||
import { createRequire } from 'node:module'
|
||||
|
||||
import { describe, expect, it, vi } from 'vitest'
|
||||
|
||||
const require = createRequire(import.meta.url)
|
||||
const { runSshRelayRuntimePtySmoke } = require('./ssh-relay-runtime-pty-smoke.cjs')
|
||||
|
||||
function successfulTerminalFixture({ windows }) {
|
||||
const dataListeners = []
|
||||
const exitListeners = []
|
||||
const subscriptions = []
|
||||
const terminal = {
|
||||
kill: vi.fn(),
|
||||
resize: vi.fn(),
|
||||
write: vi.fn(),
|
||||
onData: vi.fn((listener) => {
|
||||
dataListeners.push(listener)
|
||||
const subscription = { dispose: vi.fn() }
|
||||
subscriptions.push(subscription)
|
||||
return subscription
|
||||
}),
|
||||
onExit: vi.fn((listener) => {
|
||||
exitListeners.push(listener)
|
||||
const subscription = { dispose: vi.fn() }
|
||||
subscriptions.push(subscription)
|
||||
return subscription
|
||||
})
|
||||
}
|
||||
const nodePty = {
|
||||
spawn: vi.fn(() => {
|
||||
queueMicrotask(() => {
|
||||
const output = windows
|
||||
? 'ORCA_PTY_READY\r\nORCA_PTY_SIZE:101x37\r\nORCA_PTY_INPUT:bounded-marker\r\n'
|
||||
: 'ORCA_PTY_READY\n37 101\nORCA_PTY_INPUT:bounded-marker\n'
|
||||
dataListeners.forEach((listener) => listener(output))
|
||||
exitListeners.forEach((listener) => listener({ exitCode: 23, signal: 0 }))
|
||||
})
|
||||
return terminal
|
||||
})
|
||||
}
|
||||
return { nodePty, subscriptions, terminal }
|
||||
}
|
||||
|
||||
function runtimeRequire() {
|
||||
return {
|
||||
loadNativeModule: () => ({ dir: '../build/Release/' })
|
||||
}
|
||||
}
|
||||
|
||||
describe('SSH relay runtime PTY smoke lifecycle', () => {
|
||||
it('releases successful Windows ConPTY resources after validating the exit', async () => {
|
||||
const fixture = successfulTerminalFixture({ windows: true })
|
||||
|
||||
await expect(
|
||||
runSshRelayRuntimePtySmoke({
|
||||
nodePty: fixture.nodePty,
|
||||
runtimeRequire,
|
||||
runtimeRoot: 'C:\\runtime',
|
||||
platform: 'win32',
|
||||
environment: {},
|
||||
timeoutMs: 100
|
||||
})
|
||||
).resolves.toMatchObject({ exitCode: 23, resizedColumns: 101, resizedRows: 37 })
|
||||
|
||||
expect(fixture.terminal.kill).toHaveBeenCalledOnce()
|
||||
expect(fixture.subscriptions).toHaveLength(3)
|
||||
fixture.subscriptions.forEach((subscription) => {
|
||||
expect(subscription.dispose).toHaveBeenCalledOnce()
|
||||
})
|
||||
})
|
||||
|
||||
it('disposes successful POSIX listeners without killing an exited terminal', async () => {
|
||||
const fixture = successfulTerminalFixture({ windows: false })
|
||||
|
||||
await expect(
|
||||
runSshRelayRuntimePtySmoke({
|
||||
nodePty: fixture.nodePty,
|
||||
runtimeRequire,
|
||||
runtimeRoot: '/runtime',
|
||||
platform: 'linux',
|
||||
environment: { SHELL: '/bin/sh' },
|
||||
timeoutMs: 100
|
||||
})
|
||||
).resolves.toMatchObject({ exitCode: 23, resizedColumns: 101, resizedRows: 37 })
|
||||
|
||||
expect(fixture.terminal.kill).not.toHaveBeenCalled()
|
||||
fixture.subscriptions.forEach((subscription) => {
|
||||
expect(subscription.dispose).toHaveBeenCalledOnce()
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -5,6 +5,8 @@ const { tmpdir } = require('node:os')
|
||||
const { join } = require('node:path')
|
||||
const { createRequire } = require('node:module')
|
||||
|
||||
const { runSshRelayRuntimePtySmoke } = require('./ssh-relay-runtime-pty-smoke.cjs')
|
||||
|
||||
const runtimeRoot = process.argv[2]
|
||||
if (!runtimeRoot) {
|
||||
throw new Error('runtime root argument is required')
|
||||
@@ -22,96 +24,6 @@ function deadline(label) {
|
||||
return { promise, cancel: () => clearTimeout(timeout) }
|
||||
}
|
||||
|
||||
async function ptySmoke() {
|
||||
const windows = process.platform === 'win32'
|
||||
const executable = windows
|
||||
? 'powershell.exe'
|
||||
: process.env.SHELL && process.env.SHELL.startsWith('/')
|
||||
? process.env.SHELL
|
||||
: '/bin/sh'
|
||||
const arguments_ = windows
|
||||
? [
|
||||
'-NoLogo',
|
||||
'-NoProfile',
|
||||
'-Command',
|
||||
"$ErrorActionPreference='Stop';" +
|
||||
'[Console]::OutputEncoding=[Text.UTF8Encoding]::new($false);' +
|
||||
"Write-Output 'ORCA_PTY_READY';" +
|
||||
'$line=[Console]::ReadLine();' +
|
||||
'$size=$Host.UI.RawUI.WindowSize;' +
|
||||
'Write-Output ("ORCA_PTY_SIZE:{0}x{1}" -f $size.Width,$size.Height);' +
|
||||
'Write-Output ("ORCA_PTY_INPUT:{0}" -f $line);' +
|
||||
'exit 23'
|
||||
]
|
||||
: [
|
||||
'-c',
|
||||
'printf "ORCA_PTY_READY\\n"; IFS= read -r line; stty size; printf "ORCA_PTY_INPUT:%s\\n" "$line"; exit 23'
|
||||
]
|
||||
const terminal = nodePty.spawn(executable, arguments_, {
|
||||
name: 'xterm-256color',
|
||||
cols: 80,
|
||||
rows: 24,
|
||||
cwd: runtimeRoot,
|
||||
env: process.env,
|
||||
useConpty: windows,
|
||||
// Why: the relay uses the bundled ConPTY runtime to preserve terminal rendering behavior.
|
||||
useConptyDll: windows
|
||||
})
|
||||
let output = ''
|
||||
let wroteInput = false
|
||||
terminal.onData((data) => {
|
||||
output += data
|
||||
if (!wroteInput && output.includes('ORCA_PTY_READY')) {
|
||||
wroteInput = true
|
||||
terminal.resize(101, 37)
|
||||
terminal.write('bounded-marker\r')
|
||||
}
|
||||
})
|
||||
const exited = new Promise((resolve, reject) => {
|
||||
terminal.onExit(resolve)
|
||||
terminal.onData(() => {
|
||||
if (output.length > 1024 * 1024) {
|
||||
reject(new Error('PTY smoke output exceeded 1 MiB'))
|
||||
}
|
||||
})
|
||||
})
|
||||
const timer = deadline('PTY smoke')
|
||||
let result
|
||||
try {
|
||||
result = await Promise.race([exited, timer.promise])
|
||||
} finally {
|
||||
timer.cancel()
|
||||
if (!result) {
|
||||
terminal.kill()
|
||||
}
|
||||
}
|
||||
if (
|
||||
result.exitCode !== 23 ||
|
||||
!output.includes('ORCA_PTY_INPUT:bounded-marker') ||
|
||||
!output.includes(windows ? 'ORCA_PTY_SIZE:101x37' : '37 101')
|
||||
) {
|
||||
throw new Error(`PTY smoke mismatch: exit=${result.exitCode} output=${JSON.stringify(output)}`)
|
||||
}
|
||||
const { loadNativeModule } = runtimeRequire('node-pty/lib/utils')
|
||||
const nativeNames = windows ? ['conpty', 'conpty_console_list'] : ['pty']
|
||||
const nativeDirectories = nativeNames.map((name) => loadNativeModule(name).dir)
|
||||
if (
|
||||
nativeDirectories.some(
|
||||
(directory) => !directory.replaceAll('\\', '/').includes('build/Release/')
|
||||
)
|
||||
) {
|
||||
throw new Error(
|
||||
`node-pty did not load patched build/Release artifacts: ${nativeDirectories.join(', ')}`
|
||||
)
|
||||
}
|
||||
return {
|
||||
exitCode: result.exitCode,
|
||||
resizedRows: 37,
|
||||
resizedColumns: 101,
|
||||
nativeDirectory: nativeDirectories.join(', ')
|
||||
}
|
||||
}
|
||||
|
||||
async function waitFor(events, predicate, label) {
|
||||
const timer = deadline(label)
|
||||
try {
|
||||
@@ -177,7 +89,10 @@ async function watcherSmoke() {
|
||||
|
||||
async function main() {
|
||||
const started = process.hrtime.bigint()
|
||||
const [pty, watched] = await Promise.all([ptySmoke(), watcherSmoke()])
|
||||
const [pty, watched] = await Promise.all([
|
||||
runSshRelayRuntimePtySmoke({ nodePty, runtimeRequire, runtimeRoot }),
|
||||
watcherSmoke()
|
||||
])
|
||||
const durationMs = Number(process.hrtime.bigint() - started) / 1e6
|
||||
process.stdout.write(
|
||||
`${JSON.stringify({ nodeVersion: process.version, modulesAbi: process.versions.modules, pty, watcher: watched, durationMs, rssBytes: process.memoryUsage().rss })}\n`
|
||||
|
||||
@@ -59,6 +59,7 @@ describe('SSH relay runtime artifact workflow', () => {
|
||||
expect(source).toContain('cp "$output"/*.tar.xz')
|
||||
expect(source).toContain("Get-ChildItem -LiteralPath $output -Filter '*.zip'")
|
||||
expect(source).toContain('ssh-relay-node-zip-inspection.test.mjs')
|
||||
expect(source).toContain('ssh-relay-runtime-pty-smoke.test.mjs')
|
||||
expect(source).toContain('ssh-relay-runtime-zip.test.mjs')
|
||||
expect(source).toContain('node-v24.18.0-headers.tar.gz')
|
||||
expect(source).toContain('node_library: win-x64/node.lib')
|
||||
|
||||
+154
-14
@@ -2,7 +2,7 @@
|
||||
|
||||
Date created: 2026-07-14<br>
|
||||
Last updated: 2026-07-14<br>
|
||||
Current phase: Milestone 3 / Work Package 2 target-native runtime assembly — four POSIX native-runner artifact builds are CI-green; Windows signed-input verification and runtime/ZIP assembly reach native smoke on both architectures, but bounded smoke diagnostics/execution, reproducibility, oldest-baseline, native-trust, cross-family remote, and measured-baseline gates remain open; no bundled-runtime path is enabled<br>
|
||||
Current phase: Milestone 3 / Work Package 2 target-native runtime assembly — correct prompt Windows PTY smoke-process settlement after functionally successful native x64 and arm64 execution; exact-head green CI, reproducibility, oldest-baseline, native-trust, cross-family remote, and measured-baseline gates remain open; no bundled-runtime path is enabled<br>
|
||||
Primary design: [SSH relay GitHub Release plan](./2026-07-14-ssh-relay-github-release-plan.html)<br>
|
||||
Motivating issues: [#8450](https://github.com/stablyai/orca/issues/8450), [#1693](https://github.com/stablyai/orca/issues/1693)
|
||||
|
||||
@@ -61,12 +61,15 @@ same change as the work it records.
|
||||
smoke, SBOM, and provenance only. The Windows x64/arm64 artifact candidate and portability
|
||||
corrections are implemented through `b6903b220`, with bounded smoke diagnostics in `3aab5aff8`,
|
||||
in stacked draft PR
|
||||
[#8741](https://github.com/stablyai/orca/pull/8741). Both native architectures passed all seven
|
||||
contract suites, exact signed-input verification, native compilation, and bounded runtime/ZIP
|
||||
assembly at exact CI head `42aa02fa9` (E-M3-WINDOWS-CI-RED-004). Both then time out during the
|
||||
bundled smoke, while the parent currently suppresses bounded child stderr needed to classify the
|
||||
failing PTY or watcher substage. This package may produce test artifacts but must not publish,
|
||||
resolve, transfer, install, launch, or enable them.
|
||||
[#8741](https://github.com/stablyai/orca/pull/8741). Exact-head run
|
||||
[29341643555](https://github.com/stablyai/orca/actions/runs/29341643555) proves the bundled Node,
|
||||
patched PTY input/resize/exit, and watcher lifecycle complete on x64 in 3,357.413 ms with
|
||||
56,905,728-byte RSS and arm64 in 6,593.663 ms with 54,505,472-byte RSS, but each child retains a
|
||||
Windows handle until the parent kills it at its 45-second bound. The active slice is a
|
||||
discriminating PTY-listener/terminal-cleanup contract followed by explicit prompt ConPTY
|
||||
settlement; the injected lifecycle contract and repository static gates are locally green, while
|
||||
exact-head native execution remains mandatory. This package may produce test artifacts but must
|
||||
not publish, resolve, transfer, install, launch, or enable them.
|
||||
- Active evidence gate: the immutable Node v24.18.0 contract, pinned release key, bounded verifier,
|
||||
and artifact-only CLI are locally green under E-M3-NODE-RED-001 and E-M3-NODE-PROVENANCE-001.
|
||||
E-M3-RUNTIME-LOCAL-001 additionally proves one unpublished Linux arm64 glibc assembly, exact-tree
|
||||
@@ -578,6 +581,11 @@ archive inspection, bundled-Node/native-module/PTY/watcher smoke, SBOM, and prov
|
||||
behind purpose-named scripts and CI artifacts. No release publication, desktop resolver, SSH
|
||||
transfer, install, fallback, rollout setting, or tuple enablement belongs in this package.
|
||||
|
||||
**Active sub-gate — 2026-07-14, Codex implementation owner:** the discriminating lifecycle test and
|
||||
explicit listener/ConPTY cleanup are locally green without `process.exit()` or a weakened 45-second
|
||||
bound. Exact-head native x64/arm64 CI must now prove normal child settlement and artifact retention;
|
||||
the prior common failure is run 29341643555/jobs 87114639412 and 87114639449.
|
||||
|
||||
Each runtime must contain only the executable closure required by the relay.
|
||||
|
||||
- [ ] Replace or extend `config/scripts/build-relay.mjs` without weakening its existing relay and
|
||||
@@ -1231,6 +1239,7 @@ focused commands as their scripts/tests are introduced.
|
||||
- [x] `node config/scripts/verify-ssh-relay-node-release-inputs.mjs --inputs-directory <verified-input-directory> --archive linux-x64-glibc` (E-M3-NODE-PROVENANCE-001; metadata and archive verification only)
|
||||
- [x] `pnpm exec vitest run --config config/vitest.config.ts config/scripts/ssh-relay-node-zip-inspection.test.mjs config/scripts/ssh-relay-runtime-zip.test.mjs` (E-M3-WINDOWS-ZIP-RED-001, E-M3-WINDOWS-INPUT-001; synthetic ZIP/input contracts only)
|
||||
- [x] `pnpm exec vitest run --config config/vitest.config.ts config/scripts/ssh-relay-runtime-windows-tree.test.mjs` (E-M3-WINDOWS-LOCAL-002; structural Windows ConPTY closure only, no execution)
|
||||
- [x] `pnpm exec vitest run --config config/vitest.config.ts config/scripts/ssh-relay-runtime-pty-smoke.test.mjs` (E-M3-WINDOWS-SMOKE-SETTLEMENT-LOCAL-RED-001, E-M3-WINDOWS-SMOKE-SETTLEMENT-LOCAL-001; native evidence remains pending)
|
||||
- [x] `node config/scripts/verify-ssh-relay-node-release-inputs.mjs --inputs-directory <verified-windows-input-directory> --archive win32-x64` (E-M3-WINDOWS-INPUT-001; signed real Node ZIP, headers, and import library; no Windows execution)
|
||||
- [x] `node config/scripts/build-ssh-relay-runtime.mjs --tuple linux-arm64-glibc --inputs-directory <verified-input-directory> --output-directory <exclusive-output> --source-date-epoch <epoch> --git-commit <full-sha>` (E-M3-RUNTIME-LOCAL-001; local native Linux arm64 only)
|
||||
- [x] `node config/scripts/verify-ssh-relay-runtime.mjs --runtime-directory <runtime-tree> --identity <identity.json> --archive <runtime.tar.xz>` (E-M3-RUNTIME-LOCAL-001; local native Linux arm64 only)
|
||||
@@ -2842,6 +2851,136 @@ or unexpected token`; the first logs did not identify a source location.
|
||||
- Follow-up: rerun native Windows x64, capture the classified child tail, and make no execution-path
|
||||
change until that evidence identifies the actual failure.
|
||||
|
||||
### E-M3-WINDOWS-SMOKE-SETTLEMENT-CI-RED-001 — Native Windows smoke succeeds but does not settle
|
||||
|
||||
- Date: 2026-07-14
|
||||
- Commit SHA / PR: exact workflow head `df661e370102b9b66c26f4c708e641abef0aa1ae`; draft PR
|
||||
[#8741](https://github.com/stablyai/orca/pull/8741)
|
||||
- Runners and jobs: GitHub Actions run
|
||||
[29341643555](https://github.com/stablyai/orca/actions/runs/29341643555); Windows x64 job
|
||||
[87114639412](https://github.com/stablyai/orca/actions/runs/29341643555/job/87114639412),
|
||||
`windows-2022` image `20260706.237.1`, Windows Server 2022 10.0.20348, native x64, Node
|
||||
v24.18.0; Windows arm64 job
|
||||
[87114639449](https://github.com/stablyai/orca/actions/runs/29341643555/job/87114639449),
|
||||
`windows-11-arm64` image `20260706.102.1`, Windows 11 Enterprise 10.0.26200, native arm64,
|
||||
Node v24.18.0
|
||||
- Remote and transport: no SSH remote; target-native artifact build and bundled-runtime execution
|
||||
on the hosted runner; exact signed inputs downloaded from pinned nodejs.org URLs
|
||||
- Exact command:
|
||||
|
||||
```sh
|
||||
gh api repos/stablyai/orca/actions/jobs/87114639412/logs | \
|
||||
rg -n -C 16 'Bundled runtime smoke command failed|timeoutMs=|Image:|Version:'
|
||||
gh api repos/stablyai/orca/actions/jobs/87114639449/logs | \
|
||||
rg -n -C 16 'Bundled runtime smoke command failed|timeoutMs=|Image:|Version:'
|
||||
```
|
||||
|
||||
- Result: expected discriminating FAIL. The exact signed inputs, offline native build, archive and
|
||||
complete-tree verification all passed. Bundled Node v24.18.0/ABI 137 then completed the patched
|
||||
ConPTY smoke with exit 23, 101×37 resize, input marker, and both native modules loaded from
|
||||
`build/Release`; watcher create, update, rename-as-delete/create, and delete also completed. The
|
||||
x64 child emitted valid JSON after 3,357.413 ms with 56,905,728-byte RSS; arm64 emitted the same
|
||||
functional result after 6,593.663 ms with 54,505,472-byte RSS. Both remained alive until the
|
||||
parent killed them at 45 seconds (`code=null`, `killed=true`, `signal="SIGTERM"`, empty stderr).
|
||||
- Artifact metrics: x64 content ID
|
||||
`sha256:8cf9eb4e04459e25d710a28235a57e777d39f65168841c2408ab658243a21d94`; ZIP
|
||||
37,212,068 bytes with SHA-256
|
||||
`sha256:11f83971ed20cde7be41aa2f753cfd4350cd4a70a3fe46a27540ebc872c4ca56`; build
|
||||
151,226.208 ms. Arm64 content ID
|
||||
`sha256:dda60b6237b320c74236f57bece072d0f847479eb322f43f22c829daf2ce9bf6`; ZIP
|
||||
33,261,533 bytes with SHA-256
|
||||
`sha256:f3fefed7b959fb6c3945170e8f0f7d2766cf26240aef9928b0e25770e5b19a26`; 86,189,740
|
||||
expanded bytes; build 248,307.259 ms. Uploads remained skipped because prompt process settlement
|
||||
is part of executable proof.
|
||||
- Oracle proved: Windows x64 and arm64 PTY/ConPTY and watcher functionality succeeds through each
|
||||
exact bundled runtime, and the common remaining failure occurs after successful JSON emission in
|
||||
child-process handle settlement rather than in PTY, watcher, archive, or tree validation.
|
||||
- Does not prove: prompt cleanup, durable artifact upload, clean-rebuild identity, native
|
||||
trust/signing, oldest baseline, SSH, or any enabled tuple. Both per-tuple rows remain unchecked
|
||||
until the child exits normally and exact-head CI retains each artifact.
|
||||
- Follow-up: retain and dispose the PTY listener subscriptions, call the supported Windows terminal
|
||||
cleanup after a validated successful exit, and prove normal child settlement without
|
||||
`process.exit()` on both native architectures.
|
||||
|
||||
### E-M3-WINDOWS-SMOKE-SETTLEMENT-LOCAL-RED-001 — PTY lifecycle cleanup contract red gate
|
||||
|
||||
- Date: 2026-07-14
|
||||
- Commit SHA / PR: uncommitted contract test and behavior-preserving PTY-smoke module extraction on
|
||||
exact base `df661e370102b9b66c26f4c708e641abef0aa1ae`; draft PR
|
||||
[#8741](https://github.com/stablyai/orca/pull/8741)
|
||||
- Runner: macOS 26.2 arm64; Node v26.0.0 and pnpm 10.24.0
|
||||
- Remote and transport: none; injected terminal/listener lifecycle only
|
||||
- Exact command:
|
||||
`pnpm exec vitest run --config config/vitest.config.ts config/scripts/ssh-relay-runtime-pty-smoke.test.mjs`
|
||||
- Result: expected FAIL in 122 ms. The Windows success case returned a valid exit result but called
|
||||
`terminal.kill()` zero times; the POSIX success case and Windows case both disposed zero of their
|
||||
three `onData`/`onExit` subscriptions. Two tests failed, with no timeout or synthetic forced exit.
|
||||
- Oracle proved: the current success path lacks the exact listener and ConPTY cleanup operations
|
||||
required by the native x64 diagnostic, and the purpose-named suite distinguishes Windows-only
|
||||
terminal cleanup from platform-neutral listener disposal.
|
||||
- Does not prove: the green implementation, actual Windows handle release, timeout/error cleanup,
|
||||
full child-process settlement, arm64 behavior, or any tuple support.
|
||||
- Checklist items satisfied: red half of the Windows PTY smoke-settlement correction only.
|
||||
- Follow-up: add idempotent finally cleanup, preserve successful POSIX no-kill behavior, rerun this
|
||||
suite and all artifact/static gates, then require exact-head native Windows CI.
|
||||
|
||||
### E-M3-WINDOWS-SMOKE-SETTLEMENT-LOCAL-001 — Explicit PTY resource settlement
|
||||
|
||||
- Date: 2026-07-14
|
||||
- Commit SHA / PR: uncommitted implementation on exact base
|
||||
`df661e370102b9b66c26f4c708e641abef0aa1ae`; draft PR
|
||||
[#8741](https://github.com/stablyai/orca/pull/8741)
|
||||
- Runner: macOS 26.2 arm64; Node v26.0.0 and pnpm 10.24.0. Exact-head Node 24 native CI remains
|
||||
authoritative.
|
||||
- Remote and transport: none; injected terminal lifecycle plus local source/static verification
|
||||
- Exact commands:
|
||||
|
||||
```sh
|
||||
pnpm exec vitest run --config config/vitest.config.ts \
|
||||
config/scripts/ssh-relay-runtime-pty-smoke.test.mjs
|
||||
pnpm exec vitest run --config config/vitest.config.ts \
|
||||
config/scripts/ssh-relay-node-release-verification.test.mjs \
|
||||
config/scripts/ssh-relay-node-tar-inspection.test.mjs \
|
||||
config/scripts/ssh-relay-node-zip-inspection.test.mjs \
|
||||
config/scripts/ssh-relay-runtime-artifact.test.mjs \
|
||||
config/scripts/ssh-relay-runtime-pty-smoke.test.mjs \
|
||||
config/scripts/ssh-relay-runtime-windows-tree.test.mjs \
|
||||
config/scripts/ssh-relay-runtime-zip.test.mjs \
|
||||
config/scripts/ssh-relay-runtime-workflow.test.mjs
|
||||
pnpm run typecheck
|
||||
pnpm exec oxlint \
|
||||
config/scripts/ssh-relay-runtime-smoke-child.cjs \
|
||||
config/scripts/ssh-relay-runtime-pty-smoke.cjs \
|
||||
config/scripts/ssh-relay-runtime-pty-smoke.test.mjs \
|
||||
config/scripts/ssh-relay-runtime-workflow.test.mjs
|
||||
pnpm run check:max-lines-ratchet
|
||||
GOMAXPROCS=2 pnpm run lint
|
||||
pnpm exec oxfmt --check .github/workflows/ssh-relay-runtime-artifacts.yml \
|
||||
config/scripts/ssh-relay-runtime-smoke-child.cjs \
|
||||
config/scripts/ssh-relay-runtime-pty-smoke.cjs \
|
||||
config/scripts/ssh-relay-runtime-pty-smoke.test.mjs \
|
||||
config/scripts/ssh-relay-runtime-workflow.test.mjs \
|
||||
docs/reference/plans/2026-07-14-ssh-relay-github-release-implementation-checklist.md
|
||||
git diff --check
|
||||
```
|
||||
|
||||
- Result: PASS. The lifecycle suite passed 2/2 tests in 117 ms; the eight artifact suites passed
|
||||
25/25 tests in 417 ms. Typecheck, focused oxlint, max-lines ratchet, full
|
||||
lint/reliability/localization checks, formatting, and diff whitespace passed. Full lint reported
|
||||
only pre-existing warnings outside this package.
|
||||
- Oracle proved: the success path retains and disposes both data subscriptions and the exit
|
||||
subscription exactly once; a validated Windows exit additionally calls the supported node-pty
|
||||
terminal cleanup exactly once, while a successful POSIX exit does not kill its terminal. Cleanup
|
||||
is in `finally`, the existing timeout/error path still kills the terminal, and no `process.exit()`
|
||||
was introduced. Both native workflow families now run the lifecycle contract.
|
||||
- Does not prove: actual Windows ConPTY handle release, prompt bundled child-process exit, exact-head
|
||||
Node 24 behavior, artifact retention, clean-rebuild identity, native trust, oldest baseline, SSH,
|
||||
or any enabled tuple. Both Windows per-tuple cells remain unchecked.
|
||||
- Checklist items satisfied: local green half of the PTY smoke-settlement correction and its
|
||||
purpose-named verification-command inventory only.
|
||||
- Follow-up: commit and push the isolated correction, run both target-native Windows jobs at the
|
||||
exact head, and require normal smoke completion plus artifact upload before advancing.
|
||||
|
||||
### E-M3-RUNTIME-LOCAL-001 — First target-native Linux arm64 runtime artifact
|
||||
|
||||
- Date: 2026-07-14
|
||||
@@ -3081,7 +3220,7 @@ owner and promotion condition.
|
||||
| ------------------------------------------ | ----------------------------------------------------------------------- | ----------------------------------------------- | ------------------------------------------------------- | ------------------------------------------------------------------------------ | ------------ |
|
||||
| Bundled runtime only partially implemented | Four unpublished POSIX native artifact proofs; no production consumer | #8450/#1693 environment failures remain | Codex implementation owner | Complete Work Packages 2–7 plus Milestones 3–14 | Open |
|
||||
| No bundled tuple enabled | Every target's default and effective mode remains legacy | No bundled support claim can be made | Codex implementation owner | Complete target-native build/trust and both required live-evidence layers | Open |
|
||||
| Windows runtime smoke incomplete | Native candidate ZIPs build, but smoke fails before artifact retention | Pre-smoke proof cannot establish relay behavior | Codex implementation owner | Classified passing PTY/watcher smoke, reproducibility, trust, and live gates | Open |
|
||||
| Windows runtime smoke incomplete | Both native smokes work but prior children hung; local cleanup awaits CI | No prompt settlement or retained artifact proof | Codex implementation owner | Exact-head clean exit/upload, reproducibility, trust, and live gates | Open |
|
||||
| Native clean-rebuild identity unproved | One successful artifact per corrected-head hosted runner | Toolchain drift may change native content IDs | Codex implementation owner | Same-head, same-runner clean builds match or a reviewed reproducibility policy | Open |
|
||||
| Cross-family Layer B remotes unavailable | GitHub native runner labels exist; no approved reachable target pool | Client/remote integration gaps may escape | Repository release administrator + implementation owner | Approve provider/snapshots/credentials/egress/teardown/cost owner | BLOCKED |
|
||||
| Musl has no accepted official Node binary | Musl is deliberately legacy-only | Unofficial binary would break provenance trust | Codex implementation owner | Orca-owned target-native source build, signing, provenance, and live gates | ACCEPTED GAP |
|
||||
@@ -3129,9 +3268,10 @@ The project is not complete until every applicable item below is checked with ev
|
||||
|
||||
## Next Required Action
|
||||
|
||||
Implement bounded deterministic Windows ZIP/native assembly as its own evidence-gated slice, add
|
||||
native Windows x64/arm64 jobs without publishing assets, and add a same-head/same-runner clean-build
|
||||
identity comparison for native reproducibility. The cross-family Layer B target pool, protected
|
||||
manifest-signing environment, and paired legacy performance baseline remain release/default-path
|
||||
blockers; no publication, desktop resolver, SSH transfer/install, per-target Beta, fallback, tuple
|
||||
enablement, or default behavior may be connected by this package.
|
||||
Commit and push the isolated PTY smoke-settlement correction, then require exact-head Windows
|
||||
x64/arm64 jobs to exit normally and upload their unpublished evidence artifacts. If both pass, record
|
||||
their exact hashes, sizes, smoke/build durations, RSS, runner images, and residual gaps before the
|
||||
separate same-head/same-runner clean-build identity gate. The cross-family Layer B target pool,
|
||||
protected manifest-signing environment, and paired legacy performance baseline remain
|
||||
release/default-path blockers; no publication, desktop resolver, SSH transfer/install, per-target
|
||||
Beta, fallback, tuple enablement, or default behavior may be connected by this package.
|
||||
|
||||
Reference in New Issue
Block a user