ci(ssh): qualify the Windows SSH provider on x64 as well as ARM64

This commit is contained in:
m4air
2026-09-29 01:36:57 -07:00
parent 1cfe4c16a5
commit c24adccff0
8 changed files with 159 additions and 45 deletions
@@ -1,4 +1,4 @@
name: Diagnostic stable Bun ARM SSH provider qualification
name: Diagnostic stable Bun Windows SSH provider qualification
on:
push:
branches: [OrcaWin/np-windows-ssh-provider-diagnostic]
@@ -7,7 +7,7 @@ permissions:
contents: read
actions: read
concurrency:
group: arm-ssh-provider-${{ github.ref }}
group: windows-ssh-provider-${{ github.ref }}
cancel-in-progress: false
jobs:
windows_watcher:
@@ -17,7 +17,17 @@ jobs:
ref: 2084c58ba5410106ce61153a9fb16cdb4b6e5301
qualify:
needs: windows_watcher
runs-on: windows-11-arm
strategy:
fail-fast: false
matrix:
include:
- arch: arm64
runner: windows-11-arm
archive: OpenSSH-ARM64.zip
- arch: x64
runner: windows-2022
archive: OpenSSH-Win64.zip
runs-on: ${{ matrix.runner }}
timeout-minutes: 45
env:
ORCA_BACKGROUND_LAUNCH: '1'
@@ -63,29 +73,29 @@ jobs:
shell: pwsh
run: |
$tools=Join-Path $pwd '.build/qualification-tools/config/ci/windows-ssh-provider'
node (Join-Path $tools 'verify-bun-output.mjs') candidate .build/producer . arm64 .build/ssh-provider-receipts/candidate.json $env:PRODUCER_RUN
node (Join-Path $tools 'verify-bun-output.mjs') candidate .build/producer . ${{ matrix.arch }} .build/ssh-provider-receipts/candidate.json $env:PRODUCER_RUN
if($LASTEXITCODE -ne 0){throw 'Stable producer/candidate admission failed'}
$receipt=(Resolve-Path .build/ssh-provider-receipts/candidate.json).Path
$hash=(Get-FileHash -Algorithm SHA256 -LiteralPath $receipt).Hash.ToLowerInvariant()
"CANDIDATE_RECEIPT=$receipt" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
"CANDIDATE_RECEIPT_SHA256=$hash" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
@{candidateReceiptSha256=$hash;producerRun=$env:PRODUCER_RUN;product=$env:QUALIFICATION_SOURCE_SHA;candidateOverride=$true;expectedSourcePin=$false;scope='diagnostic in-memory ARM executable pin and private cache only'} | ConvertTo-Json | Set-Content .build/ssh-provider-receipts/admission.json
@{candidateReceiptSha256=$hash;producerRun=$env:PRODUCER_RUN;product=$env:QUALIFICATION_SOURCE_SHA;candidateOverride=$true;expectedSourcePin=$false;scope='diagnostic in-memory ${{ matrix.arch }} executable pin and private cache only'} | ConvertTo-Json | Set-Content .build/ssh-provider-receipts/admission.json
- name: Build production relay artifacts and native process table
shell: pwsh
run: |
node config/scripts/build-cli-runtime.mjs --platform win32 --arch arm64
node config/scripts/build-cli-runtime.mjs --platform win32 --arch ${{ matrix.arch }}
if($LASTEXITCODE -ne 0){throw 'CLI runtime build failed'}
node config/scripts/build-windows-process-tree-relay-addon.mjs --arch=arm64
node config/scripts/build-windows-process-tree-relay-addon.mjs --arch=${{ matrix.arch }}
if($LASTEXITCODE -ne 0){throw 'Native process-table build failed'}
$env:ORCA_REQUIRE_RELAY_NATIVE_ADDONS='arm64'
$env:ORCA_REQUIRE_RELAY_NATIVE_ADDONS='${{ matrix.arch }}'
node config/scripts/build-relay.mjs
if($LASTEXITCODE -ne 0){throw 'Relay build failed'}
- name: Run watcher fault harness with production-pinned CLI Bun
shell: pwsh
timeout-minutes: 5
run: |
Write-Output 'Scope: production-pinned bundled CLI Bun; actual SSH provider qualification separately uses the admitted stable candidate.' | Tee-Object .build/ssh-provider-receipts/watcher-fault-arm64.log
node config/scripts/relay-watcher-fault-harness.mjs 2>&1 | Tee-Object -Append .build/ssh-provider-receipts/watcher-fault-arm64.log
Write-Output 'Scope: production-pinned bundled CLI Bun; actual SSH provider qualification separately uses the admitted stable candidate.' | Tee-Object .build/ssh-provider-receipts/watcher-fault-${{ matrix.arch }}.log
node config/scripts/relay-watcher-fault-harness.mjs 2>&1 | Tee-Object -Append .build/ssh-provider-receipts/watcher-fault-${{ matrix.arch }}.log
if($LASTEXITCODE -ne 0){throw 'Production-pinned CLI Bun watcher fault harness failed'}
- name: Parse and typecheck all fixture code before provisioning
shell: pwsh
@@ -99,7 +109,7 @@ jobs:
& (Join-Path $tools 'preview-ssh/test-preview-diagnostics.ps1')
$copied=[Collections.Generic.List[string]]::new()
try {
foreach($name in @('windows-arm-provider-route.test.ts','windows-provider-candidate.ts','windows-provider-repaint.ts','windows-provider-loaded-images.ts')){
foreach($name in @('windows-provider-route.test.ts','windows-provider-candidate.ts','windows-provider-repaint.ts','windows-provider-loaded-images.ts')){
$destination=Join-Path $pwd "src/main/ssh/$name"
if(Test-Path -LiteralPath $destination){throw 'Fixture destination already exists'}
Copy-Item -LiteralPath (Join-Path $tools $name) -Destination $destination
@@ -116,23 +126,23 @@ jobs:
run: |
$tools=Join-Path $pwd '.build/qualification-tools/config/ci/windows-ssh-provider'
$sourceRoot=$pwd.Path
$archive=Join-Path $env:RUNNER_TEMP 'preview-OpenSSH-ARM64.zip'
& "$env:WINDIR\System32\curl.exe" --fail --location --connect-timeout 15 --max-time 90 --output $archive 'https://github.com/PowerShell/Win32-OpenSSH/releases/download/10.0.0.0p2-Preview/OpenSSH-ARM64.zip'
$archive=Join-Path $env:RUNNER_TEMP 'preview-${{ matrix.archive }}'
& "$env:WINDIR\System32\curl.exe" --fail --location --connect-timeout 15 --max-time 90 --output $archive 'https://github.com/PowerShell/Win32-OpenSSH/releases/download/10.0.0.0p2-Preview/${{ matrix.archive }}'
if($LASTEXITCODE -ne 0){throw 'SSH archive fetch failed'}
$callback={param($user,$port,$identity,$known)
& (Join-Path $tools 'invoke-provider-route.ps1') -SourceRoot $sourceRoot -SourceCommit $env:QUALIFICATION_SOURCE_SHA -Username $user -Port $port -IdentityFile $identity -KnownHosts $known -ReceiptRoot "$env:RUNNER_TEMP\arm-provider-route" -CandidateReceipt $env:CANDIDATE_RECEIPT -CandidateReceiptSha256 $env:CANDIDATE_RECEIPT_SHA256
& (Join-Path $tools 'invoke-provider-route.ps1') -SourceRoot $sourceRoot -SourceCommit $env:QUALIFICATION_SOURCE_SHA -Username $user -Port $port -IdentityFile $identity -KnownHosts $known -ReceiptRoot "$env:RUNNER_TEMP\provider-route" -CandidateReceipt $env:CANDIDATE_RECEIPT -CandidateReceiptSha256 $env:CANDIDATE_RECEIPT_SHA256 -Arch '${{ matrix.arch }}'
}.GetNewClosure()
& (Join-Path $tools 'preview-ssh/prove-preview-openssh.ps1') -Archive $archive -Receipt "$env:RUNNER_TEMP\arm-provider-server.json" -ProductionRouteProbe $callback 2>&1 | Tee-Object .build/ssh-provider-receipts/native-route.log
& (Join-Path $tools 'preview-ssh/prove-preview-openssh.ps1') -Archive $archive -Arch '${{ matrix.arch }}' -Receipt "$env:RUNNER_TEMP\provider-server.json" -ProductionRouteProbe $callback 2>&1 | Tee-Object .build/ssh-provider-receipts/native-route.log
- uses: actions/upload-artifact@v7
if: always()
with:
name: stable-bun-arm-ssh-provider-receipts
name: stable-bun-${{ matrix.arch }}-ssh-provider-receipts
path: |
.build/ssh-provider-receipts/
.build/producer/results/
.build/producer/work/source-cache-receipt.json
.build/producer/producer-run.json
${{ runner.temp }}/arm-provider-server.json
${{ runner.temp }}/arm-provider-route/production-route.json
${{ runner.temp }}/arm-provider-route/repaint-events.json
${{ runner.temp }}/provider-server.json
${{ runner.temp }}/provider-route/production-route.json
${{ runner.temp }}/provider-route/repaint-events.json
retention-days: 7
@@ -7,7 +7,8 @@ param(
[Parameter(Mandatory=$true)][string]$KnownHosts,
[Parameter(Mandatory=$true)][string]$ReceiptRoot,
[Parameter(Mandatory=$true)][string]$CandidateReceipt,
[Parameter(Mandatory=$true)][string]$CandidateReceiptSha256
[Parameter(Mandatory=$true)][string]$CandidateReceiptSha256,
[Parameter(Mandatory=$true)][ValidateSet('arm64','x64')][string]$Arch
)
$ErrorActionPreference='Stop'
if($env:GITHUB_ACTIONS -ne 'true' -or $env:ORCA_ISOLATED_SSH_CI -ne '1'){throw 'Disposable CI only'}
@@ -22,7 +23,7 @@ if($knownExisted){$priorKnown=[IO.File]::ReadAllBytes($knownPath)}
try {
$observed=(& git rev-parse HEAD).Trim()
if($LASTEXITCODE -ne 0 -or $observed -ne $SourceCommit){throw 'Source checkout mismatch'}
if(!(Test-Path 'out\relay\win32-arm64\relay.js')){throw 'Build real relay artifacts before server provisioning'}
if(!(Test-Path "out\relay\win32-$Arch\relay.js")){throw 'Build real relay artifacts before server provisioning'}
New-Item -ItemType Directory -Path $ReceiptRoot -Force | Out-Null
New-Item -ItemType Directory -Path (Split-Path $knownPath) -Force | Out-Null
$pinned=[IO.File]::ReadAllText($KnownHosts)
@@ -35,13 +36,13 @@ try {
$env:ORCA_RELAY_PATH=Join-Path $SourceRoot 'out\relay'
$env:ORCA_SSH_PROBE_CONFIG=Join-Path $ReceiptRoot 'config.json'
@{sourceCommit=$SourceCommit;observedSourceCommit=$observed;username=$Username;port=$Port;identityFile=$IdentityFile;candidateReceiptPath=$CandidateReceipt;candidateReceiptSha256=$CandidateReceiptSha256;receiptPath=(Join-Path $ReceiptRoot 'production-route.json')} | ConvertTo-Json | Set-Content $env:ORCA_SSH_PROBE_CONFIG
foreach($name in @('windows-arm-provider-route.test.ts','windows-provider-candidate.ts','windows-provider-repaint.ts','windows-provider-loaded-images.ts')) {
foreach($name in @('windows-provider-route.test.ts','windows-provider-candidate.ts','windows-provider-repaint.ts','windows-provider-loaded-images.ts')) {
$destination=Join-Path $SourceRoot "src\main\ssh\$name"
if(Test-Path -LiteralPath $destination){throw 'Diagnostic source destination already exists'}
Copy-Item -LiteralPath (Join-Path $PSScriptRoot $name) -Destination $destination
$copiedPaths.Add($destination)
}
& node node_modules/vitest/vitest.mjs run --config config/vitest.config.ts src/main/ssh/windows-arm-provider-route.test.ts --no-file-parallelism --reporter=verbose
& node node_modules/vitest/vitest.mjs run --config config/vitest.config.ts src/main/ssh/windows-provider-route.test.ts --no-file-parallelism --reporter=verbose
if($LASTEXITCODE -ne 0){throw 'Production SSH route qualification failed'}
$result=Get-Content (Join-Path $ReceiptRoot 'production-route.json') -Raw | ConvertFrom-Json
if(!$result.sameShellState -or !$result.cleanupVerified -or !$result.sourcePinRestored -or !$result.candidateAdmission.candidateOverride -or $result.repaint.koreanRows -ne 8 -or $result.repaint.latinRows -ne 8 -or !$result.repaint.exactRowsOnly -or !$result.repaint.provider.modules){throw 'Provider route cleanup/evidence incomplete'}
@@ -0,0 +1,96 @@
{
"release": "10.0.0.0p2-Preview",
"archiveSha256": "23f50f3458c4c5d0b12217c6a5ddfde0137210a30fa870e98b29827f7b43aba5",
"files": [
{
"name": "libcrypto.dll",
"sha256": "4652e861c0335ee80a51306ceab75aa35c8865b235f97ce7dd5a0fd9dab44b5d",
"machine": "0x8664",
"certificateTableBytes": 10312
},
{
"name": "scp.exe",
"sha256": "ca014ddb0a3c058719e7061eb604de7dfe1f7732954792ac8176e6c1fc99b4a3",
"machine": "0x8664",
"certificateTableBytes": 10312
},
{
"name": "sftp-server.exe",
"sha256": "63462c6904943f5f32ca363065f2eb7e883ee308f40c7c1637a307a253522151",
"machine": "0x8664",
"certificateTableBytes": 10312
},
{
"name": "sftp.exe",
"sha256": "97271ea46fa2eeb5e9e22cd5e919931727a2a11f79993c1ef151b4f618d9fd22",
"machine": "0x8664",
"certificateTableBytes": 10296
},
{
"name": "ssh-add.exe",
"sha256": "b6fec08648deaf7a77b50bc34ea8ac17c3cf240d06d0f1bffc60bf56d6f914b1",
"machine": "0x8664",
"certificateTableBytes": 10312
},
{
"name": "ssh-agent.exe",
"sha256": "138df27c7a8c35fbadde6fee35592336b04e058f4690b03f459ad79edd68ab63",
"machine": "0x8664",
"certificateTableBytes": 10272
},
{
"name": "ssh-keygen.exe",
"sha256": "b51fdd26be0f7c83398d18e5354a0acb0406a9de25516791758fe63bbe3ae870",
"machine": "0x8664",
"certificateTableBytes": 10272
},
{
"name": "ssh-keyscan.exe",
"sha256": "32eb6a2b80443207a2481085582c0ed01bbddcfef4b1f3f2cc680aa16d0f3135",
"machine": "0x8664",
"certificateTableBytes": 10296
},
{
"name": "ssh-pkcs11-helper.exe",
"sha256": "0f1ee63b38af0a96670ffc3f1c5421c4fba678d96ab0485854b550467b987ff5",
"machine": "0x8664",
"certificateTableBytes": 10272
},
{
"name": "ssh-shellhost.exe",
"sha256": "f090cb45e3b9dd830201993fc274e75a9be2058c1d4e900e85eff334dfd5a84c",
"machine": "0x8664",
"certificateTableBytes": 10296
},
{
"name": "ssh-sk-helper.exe",
"sha256": "4550082d459bccc5baf13cfe43c36c1e484bb012c4e0efb3990ae33a79e71c96",
"machine": "0x8664",
"certificateTableBytes": 10312
},
{
"name": "ssh.exe",
"sha256": "6890c128c86cc2c38aad9fcb32a82b851ff3d38c714a1f656b8e445d7cd5e1c6",
"machine": "0x8664",
"certificateTableBytes": 10296
},
{
"name": "sshd-auth.exe",
"sha256": "71b11418681e1ae8a3eb84494658f4ca66a7dac7ccc7674f3c74a36a3a5b7d14",
"machine": "0x8664",
"certificateTableBytes": 10272
},
{
"name": "sshd-session.exe",
"sha256": "5b28ad2046596454bd1e0b1ab19e8d66945def1d18ec9bec6f0ef538600a03cf",
"machine": "0x8664",
"certificateTableBytes": 10296
},
{
"name": "sshd.exe",
"sha256": "d66150486d472b8748cae2d6f5078a210dae91621447974bde028f077a4ef90c",
"machine": "0x8664",
"certificateTableBytes": 10272
}
]
}
@@ -1,7 +1,8 @@
# Ephemeral CI only. Preview ZIP server qualification, not inbox capability coverage.
param([Parameter(Mandatory=$true)][string]$Receipt,[Parameter(Mandatory=$true)][string]$Archive,[scriptblock]$ProductionRouteProbe)
param([Parameter(Mandatory=$true)][string]$Receipt,[Parameter(Mandatory=$true)][string]$Archive,[Parameter(Mandatory=$true)][ValidateSet('arm64','x64')][string]$Arch,[scriptblock]$ProductionRouteProbe)
$ErrorActionPreference = 'Stop'
$report = @{scope='Microsoft Win32-OpenSSH 10.0.0.0p2-Preview ARM64 private loopback authentication and stock cmd.exe dispatch; NOT inbox server or relay deployment'; status='running'; imageVersion=$env:ImageVersion; cleanup=@('not-confirmed'); globalBootstrapCleanup='Not qualified: service bootstrap may create ProgramData SSH and OpenSSH registry entries; disposable CI VM destruction is the boundary'; observations=@(); stages=@(); diagnosticCaptureFailures=@()}
$target=@{arm64=@{os='Arm64';folder='OpenSSH-ARM64';machine='0xAA64';archive='698c6aec31c1dd0fb996206e8741f4531a97355686b5431ef347d531b07fcd42'};x64=@{os='X64';folder='OpenSSH-Win64';machine='0x8664';archive='23f50f3458c4c5d0b12217c6a5ddfde0137210a30fa870e98b29827f7b43aba5'}}[$Arch]
$report = @{scope='Microsoft Win32-OpenSSH 10.0.0.0p2-Preview $Arch private loopback authentication and stock cmd.exe dispatch; NOT inbox server or relay deployment'; status='running'; imageVersion=$env:ImageVersion; cleanup=@('not-confirmed'); globalBootstrapCleanup='Not qualified: service bootstrap may create ProgramData SSH and OpenSSH registry entries; disposable CI VM destruction is the boundary'; observations=@(); stages=@(); diagnosticCaptureFailures=@()}
$script:receiptWritten=$false
function Write-Stage([string]$Stage) {
$timestamp=[DateTime]::UtcNow.ToString('o')
@@ -18,7 +19,7 @@ function Write-Stage([string]$Stage) {
}
Write-Stage 'preflight-start'
if(-not $script:receiptWritten){throw 'Initial progress receipt unavailable; refuse provisioning'}
if ($env:GITHUB_ACTIONS -ne 'true' -or $env:ORCA_ISOLATED_SSH_CI -ne '1' -or [Runtime.InteropServices.RuntimeInformation]::OSArchitecture.ToString() -ne 'Arm64') { throw 'Requires isolated native ARM64 GitHub runner' }
if ($env:GITHUB_ACTIONS -ne 'true' -or $env:ORCA_ISOLATED_SSH_CI -ne '1' -or [Runtime.InteropServices.RuntimeInformation]::OSArchitecture.ToString() -ne $target.os) { throw "Requires isolated native $Arch GitHub runner" }
$admin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
if (-not $admin) { throw 'Administrative private service/account setup required' }
Write-Stage 'existing-server-query-start'
@@ -37,7 +38,7 @@ New-Item -ItemType Directory -Path $root | Out-Null
Write-Stage 'private-directory-create-complete'
$report.root=$root
$createdUser=$false; $createdService=$false; $sid=$null; $ownedServerPid=$null
$sshDir=Join-Path $root 'OpenSSH-ARM64'
$sshDir=Join-Path $root $target.folder
$sshdLog=Join-Path $root 'private-sshd.log'
$serviceStartAttempt=$null
function Diagnostic-Categories([string]$Text) {
@@ -119,7 +120,7 @@ function Machine([string]$Path){
}
try {
Write-Stage 'preview-archive-verify-start'
$expectedArchive='698c6aec31c1dd0fb996206e8741f4531a97355686b5431ef347d531b07fcd42'
$expectedArchive=$target.archive
if((Get-FileHash -LiteralPath $Archive -Algorithm SHA256).Hash.ToLowerInvariant() -ne $expectedArchive){throw 'Preview archive hash mismatch'}
$report.archiveSha256=$expectedArchive
Write-Stage 'preview-archive-verify-complete'
@@ -128,7 +129,7 @@ try {
[IO.Compression.ZipFile]::ExtractToDirectory($Archive,$root)
Write-Stage 'preview-extract-complete'
Write-Stage 'preview-native-input-verification-start'
$manifest=Get-Content -LiteralPath (Join-Path $PSScriptRoot 'preview-native-inputs.json') -Raw | ConvertFrom-Json
$manifest=Get-Content -LiteralPath (Join-Path $PSScriptRoot "preview-native-inputs-$Arch.json") -Raw | ConvertFrom-Json
if($manifest.archiveSha256 -ne $expectedArchive -or $manifest.files.Count -ne 15){throw 'Preview input manifest mismatch'}
$nativeFiles=@(Get-ChildItem -LiteralPath $sshDir -File | Where-Object {$_.Extension -in @('.exe','.dll')})
if($nativeFiles.Count -ne $manifest.files.Count){throw 'Unexpected preview native input count'}
@@ -136,10 +137,10 @@ try {
foreach($file in $nativeFiles){
$expected=@($manifest.files | Where-Object name -eq $file.Name)
if($expected.Count -ne 1 -or (Get-FileHash -LiteralPath $file.FullName -Algorithm SHA256).Hash.ToLowerInvariant() -ne $expected[0].sha256){throw 'Preview native input hash mismatch'}
if((Machine $file.FullName) -ne '0xAA64'){throw 'Preview native input is not ARM64'}
if((Machine $file.FullName) -ne $target.machine){throw "Preview native input is not $Arch"}
$signature=Get-AuthenticodeSignature -LiteralPath $file.FullName
if($signature.Status -ne 'Valid' -or $signature.SignerCertificate.Subject -notmatch '(?:^|, )O=Microsoft Corporation(?:,|$)'){throw 'Preview native input Microsoft signature invalid'}
$verified+=@{name=$file.Name;sha256=$expected[0].sha256;machine='0xAA64';signature='Valid';publisher=$signature.SignerCertificate.Subject}
$verified+=@{name=$file.Name;sha256=$expected[0].sha256;machine=$target.machine;signature='Valid';publisher=$signature.SignerCertificate.Subject}
}
$report.nativeInputs=$verified
Write-Stage 'preview-native-input-verification-complete'
@@ -24,17 +24,19 @@ export function installCandidateOverride(config: Record<string, unknown>, state:
assert.equal(receipt.patch, '276f475c90c6761c58b9f56b3f4bfafa079d0c29c5861b23d2320c9ff39c35fb')
assert.equal(receipt.product, '2084c58ba5410106ce61153a9fb16cdb4b6e5301')
assert.equal(String(receipt.producerRun), '36503596770')
assert.equal(receipt.architecture, 'arm64')
assert(process.arch === 'arm64' || process.arch === 'x64')
assert.equal(receipt.architecture, process.arch)
const platform = `win32-${process.arch}` as const
assert(typeof receipt.binary === 'string' && /^[a-f0-9]{64}$/.test(receipt.sha256))
assert.equal(
createHash('sha256').update(readFileSync(receipt.binary)).digest('hex'),
receipt.sha256
)
const cache = join(state, 'orcad-artifacts', 'bun', `v${ORCAD_BUN_VERSION}`, 'win32-arm64')
const cache = join(state, 'orcad-artifacts', 'bun', `v${ORCAD_BUN_VERSION}`, platform)
mkdirSync(cache, { recursive: true })
copyFileSync(receipt.binary, join(cache, 'bun-runtime.exe'))
const original = ORCAD_BUN_RELEASE_ASSETS['win32-arm64'].executableSha256
ORCAD_BUN_RELEASE_ASSETS['win32-arm64'].executableSha256 = receipt.sha256
const original = ORCAD_BUN_RELEASE_ASSETS[platform].executableSha256
ORCAD_BUN_RELEASE_ASSETS[platform].executableSha256 = receipt.sha256
return {
receipt: {
...receipt,
@@ -45,7 +47,7 @@ export function installCandidateOverride(config: Record<string, unknown>, state:
scope: 'diagnostic process only; private cache; production deployment validation retained'
},
restore: () => {
ORCAD_BUN_RELEASE_ASSETS['win32-arm64'].executableSha256 = original
ORCAD_BUN_RELEASE_ASSETS[platform].executableSha256 = original
}
}
}
@@ -6,6 +6,9 @@ import { runProcess } from '../../shared/child-process/run-process'
import { readWindowsProcessTableFresh } from '../windows/windows-process-table'
import { WINDOWS_CONPTY_FILES } from '../../shared/windows-conpty-release'
// Hashes for the runner's own architecture; the harness never cross-deploys.
const providerHashes = WINDOWS_CONPTY_FILES[process.arch === 'x64' ? 'x64' : 'arm64']
export async function inspectProviderImages(
daemon: { pid: number; creationTimeMs?: number },
relayDirectory: string
@@ -90,12 +93,12 @@ export async function inspectProviderImages(
)
assert.equal(
createHash('sha256').update(readFileSync(image.path)).digest('hex'),
WINDOWS_CONPTY_FILES.arm64['OpenConsole.exe']
providerHashes['OpenConsole.exe']
)
}
assert.equal(
createHash('sha256').update(readFileSync(evidence.modules[0])).digest('hex'),
WINDOWS_CONPTY_FILES.arm64['conpty.dll']
providerHashes['conpty.dll']
)
const after = await readWindowsProcessTableFresh()
for (const original of [daemon, ...consoles]) {
@@ -112,5 +115,5 @@ export async function inspectProviderImages(
assert(typeof row.creationTimeMs === 'number', 'descendant cleanup identity unavailable')
return { pid: row.pid, creationTimeMs: row.creationTimeMs }
})
return { ...evidence, providerHashes: WINDOWS_CONPTY_FILES.arm64, daemon, descendantIdentities }
return { ...evidence, providerHashes, daemon, descendantIdentities }
}
@@ -274,13 +274,14 @@ it('does not retain unknown identifiers, paths, numeric source echoes or incompl
})
const configPath = process.env.ORCA_SSH_PROBE_CONFIG
it(
'native ARM OpenSSH candidate provider preserves all settled rows and shell state',
'native OpenSSH candidate provider preserves all settled rows and shell state',
{ timeout: 600_000 },
async () => {
if (!configPath || !process.env.ORCA_SSH_PROBE_STATE)
throw new Error('Explicit private SSH fixture configuration is required')
expect(process.platform).toBe('win32')
expect(process.arch).toBe('arm64')
expect(['arm64', 'x64']).toContain(process.arch)
const platform = `win32-${process.arch}` as const
const config = record(JSON.parse(readFileSync(configPath!, 'utf8')))
const source = textField(config, 'sourceCommit')
expect(source).toMatch(/^[a-f0-9]{40}$/)
@@ -289,7 +290,7 @@ it(
const port = config.port
if (typeof port !== 'number' || !Number.isInteger(port))
throw new Error('Invalid private SSH port')
const instance = `arm-native-${randomUUID()}`
const instance = `${process.arch}-native-${randomUUID()}`
const createConnection = (): SshConnection =>
new SshConnection(
{
@@ -347,7 +348,7 @@ it(
instance
)
stage = 'artifact-and-runtime-identity'
expect(result.platform).toBe('win32-arm64')
expect(result.platform).toBe(platform)
expect(result.nodePath?.toLowerCase()).toContain('bun')
if (!result.remoteRelayDir) throw new Error('Missing actual remote relay directory')
const artifactHashes: Record<string, string> = {}
@@ -358,7 +359,7 @@ it(
...RELAY_WINDOWS_CONPTY_FILENAMES
]) {
const expected = createHash('sha256')
.update(readFileSync(join(process.cwd(), 'out', 'relay', 'win32-arm64', filename)))
.update(readFileSync(join(process.cwd(), 'out', 'relay', platform, filename)))
.digest('hex')
const actual = createHash('sha256')
.update(readFileSync(join(result.remoteRelayDir, filename)))
@@ -370,7 +371,7 @@ it(
const runtimePath = result.nodePath
if (!runtimePath) throw new Error('Missing actual runtime executable')
const runtimeHash = createHash('sha256').update(readFileSync(runtimePath)).digest('hex')
expect(runtimeHash).toBe(ORCAD_BUN_RELEASE_ASSETS['win32-arm64'].executableSha256)
expect(runtimeHash).toBe(ORCAD_BUN_RELEASE_ASSETS[platform].executableSha256)
remoteRelayDirectory = result.remoteRelayDir
deployedRuntime = runtimePath
receipts.runtime = {