Merge pull request #5064 from deepseek-harness/worktree/ssh-helper-binaries

feat(ssh): ship standalone helper runtimes for Linux and macOS
This commit is contained in:
Yichen Jiang authored and GitHub committed 2026-10-09 11:46:00 +08:00
commit 15c10e0e87
82 files changed
+2679 -283

No files matched your search

@@ -2,7 +2,7 @@ import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { dirname, join } from 'node:path'
import { afterEach, describe, expect, it } from 'vitest'
import { resolveLinuxNodePtyAddon, resolveWindowsNodePtyAddons } from './build-exe-for-python-sdk-native-pty.ts'
import { resolveLinuxNodePtyAddon, resolveWindowsNodePtyAddons } from './executable-native-pty.ts'
const roots: string[] = []
+4 -2
View File
@@ -1,4 +1,4 @@
/** Prepare a symlink-free Python runtime payload with shared workspace module instances. */
/** Prepare a symlink-free executable runtime payload with shared workspace module instances. */
import { cp, lstat, readFile, readdir, realpath, rm, unlink } from 'node:fs/promises'
import { isAbsolute, join, relative, resolve, sep } from 'node:path'
import { load } from 'js-yaml'
@@ -78,7 +78,9 @@ export async function materializeStagedLinks(staging: string): Promise<void> {
const segments = remaining.slice(nodeModules.length + 1).split(sep)
const binIndex = segments.lastIndexOf('.bin')
if (binIndex >= 0) {
await rm(join(nodeModules, ...segments.slice(0, binIndex + 1)), { recursive: true, force: true })
const directory = join(nodeModules, ...segments.slice(0, binIndex + 1))
if ((await lstat(directory)).isSymbolicLink()) await unlink(directory)
else await rm(directory, { recursive: true, force: true })
remaining = await findSymlink(nodeModules)
continue
}
+10 -59
View File
@@ -7,12 +7,13 @@
*/
import { spawn } from 'node:child_process'
import { pnpmInvocation, restoreLegacyHoists } from './executable-packaging.ts'
import { existsSync, statSync } from 'node:fs'
import { chmod, copyFile, cp, mkdir, readFile, rm, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { basename, dirname, extname, join, resolve, sep } from 'node:path'
import { basename, dirname, join, resolve, sep } from 'node:path'
import { parseArgs } from 'node:util'
import { resolveLinuxNodePtyAddon, resolveWindowsNodePtyAddons } from './build-exe-for-python-sdk-native-pty.ts'
import { resolveLinuxNodePtyAddon, resolveWindowsNodePtyAddons } from './executable-native-pty.ts'
import { copyOfficeSidecar, OFFICE_ASSET_IGNORES } from './build-exe-for-python-sdk-office.ts'
import { deduplicateStagedWorkspacePackages, materializeStagedLinks } from './build-exe-for-python-sdk-staging.ts'
import { preparePrimaryRuntime, smokePrimaryRuntime, type PrimaryRuntimeTarget } from './primary-runtime/prepare.ts'
@@ -232,29 +233,6 @@ class BuildCli {
}
}
function pnpmInvocation(args: string[]): [command: string, args: string[]] {
const entrypoint = process.env.npm_execpath?.trim()
if (entrypoint !== undefined && entrypoint !== '') {
const extension = extname(entrypoint).toLowerCase()
if (extension === '.js' || extension === '.cjs' || extension === '.mjs') {
return [process.execPath, [entrypoint, ...args]]
}
if (extension !== '.cmd') return [entrypoint, args]
}
const home = process.env.PNPM_HOME?.trim()
if (home !== undefined && home !== '') {
const packageBin = resolve(home, '..', 'pnpm', 'bin')
for (const filename of ['pnpm.mjs', 'pnpm.cjs']) {
const candidate = resolve(packageBin, filename)
if (existsSync(candidate)) return [process.execPath, [candidate, ...args]]
}
}
if (process.platform === 'win32') {
throw new Error('build-exe-for-python-sdk: pnpm must expose a JavaScript entrypoint through npm_execpath or PNPM_HOME on Windows.')
}
return ['pnpm', args]
}
/**
* Render a command for logs and errors, quoting arguments with spaces.
* @param command - the executable.
@@ -300,7 +278,7 @@ class SingleExeBuild {
}
if (this.cli.dryRun) console.log(`build-exe-for-python-sdk: [dry-run] rm -rf ${this.staging}`)
else await rm(this.staging, { recursive: true, force: true })
await this.runPnpm('deploy', [
try { await this.runPnpm('deploy', [
'--filter',
DEPLOY_ROOT_PACKAGE,
'deploy',
@@ -313,7 +291,10 @@ class SingleExeBuild {
'--config.link-workspace-packages=true',
'--config.hoist-workspace-packages=false',
this.staging,
])
]) } finally {
// Legacy deploy records production-only workspace state; restore the development installation before exec.
await this.runPnpm('restore development dependencies', ['install', '--offline', '--frozen-lockfile', '--prod=false', '--ignore-scripts'])
}
await this.restoreLegacyHoists()
await this.materializeStagedLinks()
if (this.cli.dryRun) {
@@ -334,38 +315,8 @@ class SingleExeBuild {
console.log('build-exe-for-python-sdk: [dry-run] restore direct dependencies omitted by legacy deploy')
return
}
const manifestPath = join(this.staging, 'package.json')
const manifest = JSON.parse(await readFile(manifestPath, 'utf8')) as {
dependencies?: Record<string, string>
}
const sourceNodeModules = resolve(root, DEPLOY_SOURCE_NODE_MODULES)
const restored: string[] = []
for (const dependency of Object.keys(manifest.dependencies ?? {}).sort()) {
const destination = join(this.staging, 'node_modules', dependency)
if (existsSync(destination)) continue
const source = join(sourceNodeModules, dependency)
if (!existsSync(source)) {
throw new Error(
`build-exe-for-python-sdk: deployed dependency ${dependency} is absent from both ${destination} and ${source}.`,
)
}
await mkdir(dirname(destination), { recursive: true })
const nestedNodeModules = join(source, 'node_modules')
await cp(source, destination, {
recursive: true,
dereference: true,
filter: path => path !== nestedNodeModules && !path.startsWith(nestedNodeModules + sep),
})
restored.push(dependency)
}
const stillMissing = Object.keys(manifest.dependencies ?? {})
.filter(dependency => !existsSync(join(this.staging, 'node_modules', dependency)))
if (stillMissing.length > 0) {
throw new Error(`build-exe-for-python-sdk: staged dependencies remain missing: ${stillMissing.join(', ')}.`)
}
if (restored.length > 0) {
console.log(`build-exe-for-python-sdk: restored legacy deploy hoists: ${restored.join(', ')}`)
}
const restored = await restoreLegacyHoists(this.staging, resolve(root, DEPLOY_SOURCE_NODE_MODULES))
if (restored.length > 0) console.log(`build-exe-for-python-sdk: restored legacy deploy hoists: ${restored.join(', ')}`)
}
/** Replace deploy-time package links with files and reject any remaining link. */
+176
View File
@@ -0,0 +1,176 @@
/** Build a relocatable, native-host SSH helper archive with its private Node workers. */
import { spawn, execFileSync } from 'node:child_process'
import { existsSync, globSync } from 'node:fs'
import { chmod, copyFile, cp, lstat, mkdir, mkdtemp, readFile, readdir, rm, writeFile } from 'node:fs/promises'
import { basename, dirname, join, resolve } from 'node:path'
import { parseArgs } from 'node:util'
import { build } from 'tsdown'
import { create as createTar } from 'tar'
import { verifyRuntimeClosure } from './verify-runtime-closure.ts'
import { pnpmInvocation, restoreLegacyHoists } from './executable-packaging.ts'
import { materializeStagedLinks, deduplicateStagedWorkspacePackages } from './build-exe-for-python-sdk-staging.ts'
import { resolveLinuxNodePtyAddon } from './executable-native-pty.ts'
import { artifactManifestSchema, fileDigest, payloadFiles, SSH_HELPER_TARGETS, verifyPayload, type SshHelperTarget } from './ssh-helper/artifact.ts'
import { probeHelper } from './ssh-helper/probe.ts'
import { verifyNativePayload } from './ssh-helper/native.ts'
const root = resolve(import.meta.dirname, '..')
const closureDirectory = 'packages/ssh/ssh-helper-runtime'
const closureName = '@deepseek-ai/dsh-ssh-helper-runtime'
const assets = ['package.json', 'lib/**/*.js', ...['js', 'cjs', 'mjs', 'json', 'node', 'so', 'so.*', 'dylib', 'wasm', 'sh', 'bash'].map(extension => `node_modules/**/*.${extension}`)]
interface Manifest { name: string; version: string; license?: string; dependencies?: Record<string, string> }
async function manifest(path: string): Promise<Manifest> { return JSON.parse(await readFile(path, 'utf8')) as Manifest }
async function run(command: string, args: string[]): Promise<void> {
console.log(`ssh-helper build: ${[command, ...args].join(' ')}`)
await new Promise<void>((resolve, reject) => {
const child = spawn(command, args, { cwd: root, stdio: 'inherit', env: { ...process.env, CI: 'true' } })
child.once('error', reject)
child.once('close', (code, signal) => {
if (code === 0 && signal === null) resolve()
else reject(new Error(`SSH helper build command failed (${code ?? signal}): ${command}`))
})
})
}
async function pnpm(...args: string[]): Promise<void> { const [command, argv] = pnpmInvocation(args); await run(command, argv) }
async function compileRuntime(dependencies: Readonly<Record<string, string>>): Promise<void> {
await pnpm('exec', 'tsx', 'native/system/scripts/build.ts')
await pnpm('exec', 'tsc', '-b', closureDirectory, 'native/system/packages/entry')
const names = new Set([closureName, ...Object.keys(dependencies)])
for (const path of globSync(['packages/*/*/package.json', 'vendor/*/package.json'], { cwd: root }).sort()) {
if (!names.has((await manifest(join(root, path))).name)) continue
const cwd = dirname(join(root, path))
const config = join(cwd, 'tsdown.config.ts')
if (existsSync(config)) await build({ cwd, config })
else await build({ cwd, config: false, entry: ['lib/types/{index,invariant,startup}.js'], outDir: 'lib', format: ['esm'], platform: 'node', target: 'es2024', fixedExtension: false, dts: false, clean: false })
}
}
async function prepareNative(staging: string, product: string, platform: string, arch: 'x64' | 'arm64'): Promise<void> {
const pty = join(staging, 'node_modules', 'node-pty')
await rm(join(pty, 'build'), { recursive: true, force: true })
for (const entry of await readdir(join(pty, 'prebuilds'))) {
if (entry !== `${platform}-${arch}`) await rm(join(pty, 'prebuilds', entry), { recursive: true, force: true })
}
if (platform === 'linux') {
const addon = resolveLinuxNodePtyAddon(join(root, 'packages/subprocess/subprocess-local/node_modules/node-pty'), arch)
await mkdir(join(pty, 'build/Release'), { recursive: true })
await copyFile(addon, join(pty, 'build/Release/pty.node'))
} else {
const destination = join(product, 'dsh-ssh-helper-spawn-helper')
await copyFile(join(pty, 'prebuilds', `darwin-${arch}`, 'spawn-helper'), destination)
await chmod(destination, 0o755)
}
const source = join(root, 'native/system/packages', `${platform}-${arch}`)
const destination = join(product, 'native/system')
await mkdir(destination, { recursive: true })
await copyFile(join(source, 'package.json'), join(destination, 'package.json'))
await cp(join(source, 'bin'), join(destination, 'bin'), { recursive: true })
// The Linux carrier targets glibc; no unused musl addon travels in this archive.
if (platform === 'linux') await rm(join(destination, 'bin/musl'), { recursive: true, force: true })
const binaries = platform === 'linux' ? ['bin/landlock-run', 'bin/glibc/system.node'] : ['bin/system.node']
for (const binary of binaries) {
if (!(await lstat(join(destination, binary))).isFile()) throw new Error(`Missing SSH native resource: ${binary}`)
}
}
async function copyLicenses(staging: string, product: string): Promise<void> {
const destination = join(product, 'LICENSES')
await mkdir(destination, { recursive: true })
const inventory: { name: string; version: string; license?: string }[] = []
for (const path of globSync(['node_modules/*/package.json', 'node_modules/@*/*/package.json'], { cwd: staging }).sort()) {
const directory = dirname(join(staging, path))
const data = await manifest(join(staging, path))
inventory.push({ name: data.name, version: data.version, ...(data.license === undefined ? {} : { license: data.license }) })
const licenses = (await readdir(directory)).filter(name => /^(?:licen[cs]e|copying|notice)(?:[.-]|$)/i.test(name))
for (const name of licenses) {
const source = join(directory, name)
if (!(await lstat(source)).isFile()) continue
const output = join(destination, data.name.replaceAll('/', '__'), name)
await mkdir(dirname(output), { recursive: true })
await copyFile(source, output)
}
}
await copyFile(join(root, 'LICENSE'), join(destination, 'deepseek-harness-MIT.txt'))
await copyFile(join(root, 'native/system/LICENSE'), join(destination, 'node-addon-system-BSD.txt'))
await writeFile(join(destination, 'packages.json'), `${JSON.stringify(inventory, null, 2)}\n`)
}
/**
* Build the selected native target and retain only its complete release archive.
* @param argv - command-line arguments, excluding the interpreter and script.
*/
export async function buildSshHelper(argv: string[]): Promise<void> {
const { values } = parseArgs({ args: argv, options: {
target: { type: 'string' }, output: { type: 'string' },
'skip-build': { type: 'boolean', default: false }, 'dry-run': { type: 'boolean', default: false },
} })
const host = `node24-${process.platform === 'darwin' ? 'macos' : process.platform}-${process.arch}`
const selected = values.target ?? host
if (!SSH_HELPER_TARGETS.some(target => target === selected)) throw new Error(`Unsupported SSH helper target: ${selected}`)
if (!values['dry-run'] && selected !== host) throw new Error(`SSH helper target ${selected} requires its native host; current host is ${host}`)
const target = selected as SshHelperTarget
const definition = await manifest(join(root, closureDirectory, 'package.json'))
const closure = await verifyRuntimeClosure(root, `${closureDirectory}/package.json`, false)
if (closure.failures.length > 0) throw new Error(`SSH helper runtime dependencies are incomplete:\n${closure.failures.join('\n')}`)
const output = resolve(root, values.output ?? 'dist-exe/ssh-helper')
if (values['dry-run']) {
console.log(`SSH helper ${target}: ${values['skip-build'] ? 'reuse built modules' : 'compile runtime'} -> deploy ${closureName} -> pkg --sea -> handshake -> ${output}`)
return
}
if (!values['skip-build']) await compileRuntime(definition.dependencies ?? {})
await mkdir(join(root, '.dsh-build'), { recursive: true })
const temporary = await mkdtemp(join(root, '.dsh-build/ssh-helper-'))
try {
const staging = join(temporary, 'staging')
const product = join(temporary, 'dsh-ssh-helper')
await mkdir(product)
try {
await pnpm('--filter', closureName, 'deploy', '--legacy', '--prod', '--config.allow-unused-patches=true', '--config.node-linker=hoisted', '--config.auto-install-peers=false', '--config.link-workspace-packages=true', '--config.hoist-workspace-packages=false', staging)
} finally {
// Legacy deploy records production-only workspace state; pnpm's next exec otherwise prunes build tools.
await pnpm('install', '--offline', '--frozen-lockfile', '--prod=false', '--ignore-scripts')
}
await restoreLegacyHoists(staging, join(root, closureDirectory, 'node_modules'))
await materializeStagedLinks(staging)
await deduplicateStagedWorkspacePackages(staging, root)
await prepareNative(staging, product, process.platform, process.arch as 'x64' | 'arm64')
await verifyNativePayload(join(staging, 'node_modules'), target)
const stagedManifest = await manifest(join(staging, 'package.json'))
await writeFile(join(staging, 'runtime-bootstrap.mjs'), 'import { runSshHelperRuntime } from "./lib/index.js";\nawait runSshHelperRuntime();\n')
await writeFile(join(staging, 'package.json'), `${JSON.stringify({ ...stagedManifest,
bin: 'runtime-bootstrap.mjs', pkg: { assets, ignore: ['node_modules/@deepseek-ai/node-addon-system-*/**/*'] },
}, null, 2)}\n`)
const executable = join(product, 'dsh-ssh-helper')
await pnpm('exec', 'pkg', staging, '--sea', '--targets', target, '--output', executable)
await chmod(executable, 0o755)
await verifyNativePayload(product, target)
await copyLicenses(staging, product)
const hello = await probeHelper(executable, product)
if (hello.kind !== 'executable' || hello.executable !== executable) throw new Error('Packaged SSH helper did not report its physical executable')
const metadata = artifactManifestSchema.parse({
format: 1, version: definition.version, target,
commit: execFileSync('git', ['rev-parse', 'HEAD'], { cwd: root, encoding: 'utf8' }).trim(),
dirty: execFileSync('git', ['status', '--porcelain'], { cwd: root, encoding: 'utf8' }).trim() !== '',
protocol: hello.protocol, nodeVersion: hello.nodeVersion,
files: await Promise.all((await payloadFiles(product)).map(async path => ({
path, sha256: await fileDigest(join(product, path)), mode: (await lstat(join(product, path))).mode & 0o777,
}))),
})
await writeFile(join(product, 'manifest.json'), `${JSON.stringify(metadata, null, 2)}\n`)
await verifyPayload(product)
await mkdir(output, { recursive: true })
const archive = join(output, `dsh-ssh-helper-${definition.version}-${target.slice('node24-'.length)}.tar.gz`)
await createTar({ cwd: temporary, file: archive, gzip: true, portable: true }, ['dsh-ssh-helper'])
await writeFile(`${archive}.sha256`, `${await fileDigest(archive)} ${basename(archive)}\n`)
console.log(`SSH helper archive: ${archive}`)
} finally {
await rm(temporary, { recursive: true, force: true })
}
}
if (import.meta.main) await buildSshHelper(process.argv.slice(2))
+2
View File
@@ -378,6 +378,8 @@ export function checkExperimentalNameExceptions(manifests: readonly WorkspaceMan
}
function isReleaseMemberDirectory(dir: string): boolean {
// The SSH carrier is distributed as executable archives, never as an npm application.
if (dir === 'packages/ssh/ssh-helper-runtime') return false
return standardReleaseMemberDirectory.test(dir) || isPublicExperimentalPackageDirectory(dir)
}
+108
View File
@@ -715,6 +715,7 @@ describe('CI workflow', () => {
const NOT_PUSH_REACHABLE = new Set([
"github.event_name == 'workflow_dispatch' && inputs.suite == 'larger-runner-benchmark'",
"github.event_name == 'workflow_dispatch' && inputs.suite == 'consolidated-runner-benchmark'",
"github.event_name == 'workflow_dispatch' && inputs.suite == 'ssh-helper'",
])
const pushReachable = Object.entries(workflow.jobs)
.filter(([, job]) => {
@@ -800,6 +801,104 @@ describe('CI workflow', () => {
expect(aggregate.needs).toContain('python-runtime')
})
it('builds SSH executables only for explicit manual or release requests', () => {
const ci = loadWorkflow('.github/workflows/ci.yml')
if (!isRecord(ci.jobs)) throw new Error('PR CI must define jobs')
expect(Object.values(ci.jobs)).not.toContainEqual(expect.objectContaining({ uses: './.github/workflows/build-exe-for-ssh-helper.yml' }))
expect(workflowJob(ci, 'all-checks-passed').needs).not.toContain('ssh-helper')
const master = workflowJob(loadWorkflow('.github/workflows/ci-master.yml'), 'ssh-helper')
if (typeof master.if !== 'string') throw new Error('SSH manual caller must define its trigger condition')
for (const [event, suite, expected] of [
['push', 'ssh-helper', false], ['pull_request', 'ssh-helper', false],
['workflow_dispatch', 'larger-runner-benchmark', false], ['workflow_dispatch', 'ssh-helper', true],
] as const) {
expect(runInNewContext(master.if, { github: { event_name: event, ref: 'refs/heads/master' }, inputs: { suite } }, { timeout: 1000 })).toBe(expected)
}
expect(master.with).toEqual({ targets: 'node24-linux-x64,node24-linux-arm64,node24-macos-arm64,node24-macos-x64' })
const workflow = loadWorkflow('.github/workflows/build-exe-for-ssh-helper.yml')
if (!isRecord(workflow.on)) throw new Error('SSH builder must define triggers')
expect(Object.keys(workflow.on).sort()).toEqual(['workflow_call', 'workflow_dispatch'])
})
it('requires SSH helper acceptance before uploading artifacts or publishing', () => {
const workflow = loadWorkflow('.github/workflows/build-exe-for-ssh-helper.yml')
const build = workflowJob(workflow, 'build')
if (!Array.isArray(build.steps)) throw new Error('SSH build must define its verification steps')
const steps = build.steps.filter(isRecord)
const artifact = steps.findIndex(step => String(step.run).includes('scripts/verify-ssh-helper-artifact.ts'))
const transport = steps.findIndex(step => String(step.run).includes('scripts/verify-ssh-helper-ssh.ts'))
const landlock = steps.findIndex(step => String(step.run).includes('--backend=landlock-run'))
const upload = steps.findIndex(step => String(step.uses).startsWith('actions/upload-artifact@'))
expect(artifact).toBeGreaterThan(-1)
expect(landlock).toBeGreaterThan(artifact)
expect(transport).toBeGreaterThan(artifact)
expect(upload).toBeGreaterThan(transport)
for (const index of [artifact, transport, landlock, upload]) expect(steps[index]).not.toHaveProperty('continue-on-error', true)
const publish = loadWorkflow('.github/workflows/publish-ssh-helper.yml')
expect(publish.permissions).toEqual({ contents: 'read' })
expect(workflowJob(publish, 'build')).toMatchObject({ needs: 'validate', with: { release: true } })
const verify = workflowJob(publish, 'verify')
expect(verify.needs).toEqual(['validate', 'build'])
expect(verify).not.toHaveProperty('if')
expect(verify).not.toHaveProperty('permissions')
if (!Array.isArray(verify.steps)) throw new Error('Release verification must define steps')
const verification = verify.steps.findIndex(step => isRecord(step) && String(step.run).includes('scripts/ssh-helper/release.ts'))
const checksums = verify.steps.findIndex(step => isRecord(step) && String(step.uses).startsWith('actions/upload-artifact@'))
expect(verification).toBeGreaterThan(-1)
expect(checksums).toBeGreaterThan(verification)
expect(verify.steps[verification]).not.toHaveProperty('continue-on-error', true)
const publication = workflowJob(publish, 'publish')
expect(publication).toMatchObject({ if: 'inputs.publish', needs: ['validate', 'verify'], permissions: { contents: 'write' } })
for (const requested of [false, true]) {
expect(runInNewContext(String(publication.if), { inputs: { publish: requested } }, { timeout: 1000 })).toBe(requested)
}
})
it('validates any ref by default but refuses publication without the matching SSH release tag', () => {
const workflow = loadWorkflow('.github/workflows/publish-ssh-helper.yml')
if (!isRecord(workflow.on)) throw new Error('SSH release must define triggers')
expect(Object.keys(workflow.on)).toEqual(['workflow_dispatch'])
expect(workflowEvent(workflow, 'workflow_dispatch').inputs).toMatchObject({ publish: { type: 'boolean', default: false } })
const validate = workflowJob(workflow, 'validate')
expect(validate.steps).toContainEqual(expect.objectContaining({ id: 'source', env: { PUBLISH: '${{ inputs.publish }}' } }))
const source = nodeStepSource(validate, 'source')
const evaluate = (publish: boolean, type: string, name: string): string => {
let output = ''
runInNewContext(source, {
process: { env: { PUBLISH: String(publish), GITHUB_REF_TYPE: type, GITHUB_REF_NAME: name, GITHUB_OUTPUT: 'output' } },
readFileSync: () => JSON.stringify({ version: '1.2.3' }),
execFileSync: () => `${'a'.repeat(40)}\n`,
appendFileSync: (_path: string, text: string) => { output += text },
}, { timeout: 1000 })
return output
}
const expected = `version=1.2.3\ncommit=${'a'.repeat(40)}\n`
expect(evaluate(false, 'branch', 'worktree/helper')).toBe(expected)
expect(evaluate(false, 'tag', 'arbitrary-tag')).toBe(expected)
expect(evaluate(true, 'tag', 'dsh-v1.2.3')).toBe(expected)
for (const [type, name] of [['branch', 'dsh-v1.2.3'], ['tag', 'dsh-v1.2.2'], ['tag', 'python-v1.2.3']] as const) {
expect(() => evaluate(true, type, name)).toThrow('Publication requires the matching dsh-v<version> tag')
}
})
it('validates the SSH native matrix before allocating runners', () => {
const plan = workflowJob(loadWorkflow('.github/workflows/build-exe-for-ssh-helper.yml'), 'plan')
const source = nodeStepSource(plan, 'targets')
const evaluate = (requested: string): unknown => {
let output = ''
runInNewContext(source, {
process: { env: { REQUESTED_TARGETS: requested, GITHUB_OUTPUT: 'output' } },
appendFileSync: (_path: string, text: string) => { output += text },
}, { timeout: 1000 })
return JSON.parse(output.slice('matrix='.length))
}
expect(evaluate('')).toHaveLength(4)
expect(evaluate('node24-linux-arm64')).toEqual([{ target: 'node24-linux-arm64', runner: 'ubuntu-24.04-arm' }])
for (const invalid of ['node24-linux-arm64,node24-linux-arm64', 'node24-win-x64', 'node24-linux-x64,', ' ']) {
expect(() => evaluate(invalid)).toThrow('Invalid or duplicate')
}
})
it('keeps every Vitest project process-isolated on native Windows', () => {
const config = readFileSync(resolve(root, 'vitest.config.ts'), 'utf8')
@@ -1438,6 +1537,15 @@ function loadWorkflow(path: string): Record<string, unknown> {
return workflow
}
function nodeStepSource(job: Record<string, unknown>, id: string): string {
if (!Array.isArray(job.steps)) throw new Error('Node workflow job must define steps')
const step: unknown = job.steps.find(value => isRecord(value) && value.id === id)
if (!isRecord(step) || typeof step.run !== 'string') throw new Error(`Missing Node workflow step: ${id}`)
const source = step.run.split("<<'JS'\n")[1]?.split('\nJS')[0]?.replace(/^import .*;\n/gm, '')
if (source === undefined) throw new Error(`Workflow step ${id} must contain an executable Node script`)
return source
}
function workflowEvent(workflow: Record<string, unknown>, event: string): Record<string, unknown> {
if (!isRecord(workflow.on) || !isRecord(workflow.on[event])) {
throw new TypeError(`workflow must define the ${event} event`)
+1
View File
@@ -70,6 +70,7 @@ const PACKAGE_LIBRARIES: Readonly<Record<string, string>> = {
'packages/sandbox/sandbox-windows-acl': 'Windows ACL sandbox library consumed by sandbox-local.',
'packages/sdk/client': 'Client-process library; the spawned runtime owns plugin behavior.',
'packages/sdk/protocol': 'Wire-protocol library with type declarations only.',
'packages/ssh/ssh-helper-runtime': 'Private executable entry consumed by the packaging pipeline; no Cordis plugin export.',
'packages/session/session-format': 'Pure Session format planning, codec dispatch, and lossless JSON library.',
'packages/session/session-format-catalog': 'Generated build-static Session format inventory with no plugin registration.',
'packages/session/session-format-v0-to-v1': 'Pure released-v0 codec and adjacent migration library.',
@@ -1,4 +1,4 @@
/** Resolve the native node-pty input used by the Python SDK runtime builder. */
/** Resolve the native node-pty input used by the SDK and SSH executable builders. */
import { existsSync } from 'node:fs'
import { join } from 'node:path'
@@ -18,7 +18,7 @@ export function resolveLinuxNodePtyAddon(
const prebuilt = join(packageDirectory, 'prebuilds', `linux-${arch}`, 'pty.node')
if (existsSync(prebuilt)) return prebuilt
throw new Error(
`build-exe-for-python-sdk: node-pty addon is absent from both ${built} and ${prebuilt}.`,
`executable-native-pty: node-pty addon is absent from both ${built} and ${prebuilt}.`,
)
}
@@ -39,7 +39,7 @@ export function resolveWindowsNodePtyAddons(
]
const missing = addons.filter(path => !existsSync(path))
if (missing.length > 0) {
throw new Error(`build-exe-for-python-sdk: Windows node-pty addons are missing: ${missing.join(', ')}.`)
throw new Error(`executable-native-pty: Windows node-pty addons are missing: ${missing.join(', ')}.`)
}
return addons
}
+47
View File
@@ -0,0 +1,47 @@
import { lstat, mkdir, mkdtemp, readFile, rm, symlink, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { expect, it, onTestFinished } from 'vitest'
import { restoreLegacyHoists } from './executable-packaging.ts'
import { materializeStagedLinks } from './build-exe-for-python-sdk-staging.ts'
async function fixture() {
const root = await mkdtemp(join(tmpdir(), 'dsh-exe-deploy-'))
onTestFinished(() => rm(root, { recursive: true, force: true }))
const source = join(root, 'source')
const staging = join(root, 'staging')
await mkdir(source)
await mkdir(join(staging, 'node_modules'), { recursive: true })
return { root, source, staging, modules: join(staging, 'node_modules') }
}
it('restores omitted direct peers without copying their nested module instances', async () => {
const test = await fixture()
await writeFile(join(test.staging, 'package.json'), JSON.stringify({ dependencies: { peer: 'workspace:^' } }))
await mkdir(join(test.source, 'peer/node_modules/shadow'), { recursive: true })
await writeFile(join(test.source, 'peer/index.js'), 'export const identity = 1\n')
await writeFile(join(test.source, 'peer/node_modules/shadow/index.js'), 'shadow')
expect(await restoreLegacyHoists(test.staging, test.source)).toEqual(['peer'])
expect(await readFile(join(test.modules, 'peer/index.js'), 'utf8')).toBe('export const identity = 1\n')
await expect(lstat(join(test.modules, 'peer/node_modules'))).rejects.toThrow('ENOENT')
expect(await restoreLegacyHoists(test.staging, test.source)).toEqual([])
})
it('rejects a missing dependency instead of packaging an incomplete graph', async () => {
const test = await fixture()
await writeFile(join(test.staging, 'package.json'), JSON.stringify({ dependencies: { missing: 'workspace:^' } }))
await expect(restoreLegacyHoists(test.staging, test.source)).rejects.toThrow('absent from both')
})
it('materializes a package junction without deleting its source and drops linked command directories', async () => {
const test = await fixture()
await mkdir(join(test.source, 'peer'))
await writeFile(join(test.source, 'peer/index.js'), 'intact')
await symlink(join(test.source, 'peer'), join(test.modules, 'peer'), 'junction')
await symlink(join(test.source, 'peer'), join(test.modules, '.bin'), 'junction')
await materializeStagedLinks(test.staging)
expect((await lstat(join(test.modules, 'peer'))).isSymbolicLink()).toBe(false)
expect(await readFile(join(test.modules, 'peer/index.js'), 'utf8')).toBe('intact')
expect(await readFile(join(test.source, 'peer/index.js'), 'utf8')).toBe('intact')
await expect(lstat(join(test.modules, '.bin'))).rejects.toThrow('ENOENT')
})
+70
View File
@@ -0,0 +1,70 @@
/** Shared production-deploy preparation for the SDK and SSH executable carriers. */
import { existsSync } from 'node:fs'
import { cp, mkdir, readFile } from 'node:fs/promises'
import { dirname, extname, join, resolve, sep } from 'node:path'
/**
* Resolve pnpm without invoking a command shell, including Windows shims.
* @param args - pnpm arguments.
* @returns the executable and its argument vector.
*/
export function pnpmInvocation(args: string[]): [command: string, args: string[]] {
const entrypoint = process.env.npm_execpath?.trim()
if (entrypoint !== undefined && entrypoint !== '') {
const extension = extname(entrypoint).toLowerCase()
if (extension === '.js' || extension === '.cjs' || extension === '.mjs') {
return [process.execPath, [entrypoint, ...args]]
}
if (extension !== '.cmd') return [entrypoint, args]
}
const home = process.env.PNPM_HOME?.trim()
if (home !== undefined && home !== '') {
const packageBin = resolve(home, '..', 'pnpm', 'bin')
for (const filename of ['pnpm.mjs', 'pnpm.cjs']) {
const candidate = resolve(packageBin, filename)
if (existsSync(candidate)) return [process.execPath, [candidate, ...args]]
}
}
if (process.platform === 'win32') {
throw new Error('executable-packaging: pnpm must expose a JavaScript entrypoint through npm_execpath or PNPM_HOME on Windows.')
}
return ['pnpm', args]
}
/**
* Restore direct dependencies omitted by pnpm's legacy hoister, excluding nested module trees.
* @param staging - deployed runtime root.
* @param sourceNodeModules - deploy source's installed dependencies.
* @returns names restored from the source installation.
*/
export async function restoreLegacyHoists(staging: string, sourceNodeModules: string): Promise<string[]> {
const manifestPath = join(staging, 'package.json')
const manifest = JSON.parse(await readFile(manifestPath, 'utf8')) as {
dependencies?: Record<string, string>
}
const restored: string[] = []
for (const dependency of Object.keys(manifest.dependencies ?? {}).sort()) {
const destination = join(staging, 'node_modules', dependency)
if (existsSync(destination)) continue
const source = join(sourceNodeModules, dependency)
if (!existsSync(source)) {
throw new Error(
`executable-packaging: deployed dependency ${dependency} is absent from both ${destination} and ${source}.`,
)
}
await mkdir(dirname(destination), { recursive: true })
const nestedNodeModules = join(source, 'node_modules')
await cp(source, destination, {
recursive: true,
dereference: true,
filter: path => path !== nestedNodeModules && !path.startsWith(nestedNodeModules + sep),
})
restored.push(dependency)
}
const stillMissing = Object.keys(manifest.dependencies ?? {})
.filter(dependency => !existsSync(join(staging, 'node_modules', dependency)))
if (stillMissing.length > 0) {
throw new Error(`executable-packaging: staged dependencies remain missing: ${stillMissing.join(', ')}.`)
}
return restored
}
-5
View File
@@ -1447,11 +1447,6 @@
"aa5de2d4958ec64219565d53ec5a9d7f40f1f60037a2d52d1a9c3c65db034d73": 1,
"be027af1ef5cb3bfe41eeb19b54dbb176ec7c23ae367d709059839f9851833d5": 1
},
"packages/ptc-runtime/ptc-runtime-node/tests/launch.spec.ts": {
"57f598f462c77fae2b147b07c2e1228199c53dfd43652021af57712b4860732a": 1,
"9ddf7336f94d8ff4be8fe0ae7977c1846e6e92e7ea66180f8e2e6f8902b3c915": 1,
"e02136d8ab1f1fb84c6e772bbc863ceb3a0a3801f6eb158d5b9be074baa0885c": 1
},
"packages/ptc-runtime/ptc-runtime-node/tests/output-json.spec.ts": {
"8c4c486bbc27559714f4e0aaf376c72c49ac9157539b03c6c12853b8d3fc6e74": 1
},
+23
View File
@@ -0,0 +1,23 @@
#!/usr/bin/env bash
set -euo pipefail
# Generate node-gyp's Makefile on the runner, then compile against glibc 2.28.
case "$(uname -m)" in
x86_64) image=quay.io/pypa/manylinux_2_28_x86_64 ;;
aarch64) image=quay.io/pypa/manylinux_2_28_aarch64 ;;
*) echo 'node-pty release preparation requires native Linux x64 or arm64' >&2; exit 1 ;;
esac
addon_dir="$(realpath packages/subprocess/subprocess-local/node_modules/node-pty)"
pnpm_setup_root="$(realpath "$(dirname "$(dirname "$PNPM_HOME")")")"
(cd "$addon_dir" && npm_config_build_from_source=true pnpm run install)
addon="$addon_dir/build/Release/pty.node"
test -f "$addon_dir/build/Makefile"
docker run --rm \
--user "$(id -u):$(id -g)" \
-v "$PWD:$PWD" \
-v "$HOME/.cache/node-gyp:$HOME/.cache/node-gyp:ro" \
-v "$pnpm_setup_root:$pnpm_setup_root:ro" \
-w "$addon_dir" "$image" \
bash -euxo pipefail -c 'rm -rf build/Release && make -C build -j2 BUILDTYPE=Release'
test -f "$addon"
readelf --version-info "$addon"
+1
View File
@@ -22,6 +22,7 @@ export const PRODUCT_PACKAGE_POLICY: Readonly<Record<string, ProductPackagePolic
'packages/lsp/lsp-stdio': { category: 'optional', reason: 'Requires an explicit server list and language-server executables.' },
'packages/lsp/tool-lsp': { category: 'optional', reason: 'Model tools selected together with a configured LSP provider.' },
'packages/ssh/ssh': { category: 'optional', reason: 'Explicit remote connection and helper configuration.' },
'packages/ssh/ssh-helper-runtime': { category: 'optional', reason: 'Private executable carrier for explicitly configured SSH connections.' },
'packages/ssh/fs-ssh': { category: 'optional', reason: 'Remote filesystem provider selected in an SSH composition.' },
'packages/ssh/sandbox-ssh': { category: 'optional', reason: 'Remote confinement provider selected in an SSH composition.' },
'packages/ssh/subprocess-ssh': { category: 'optional', reason: 'Remote process provider selected in an SSH composition.' },
+117
View File
@@ -0,0 +1,117 @@
import { cp, lstat, mkdir, mkdtemp, readFile, rm, symlink, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { dirname, join } from 'node:path'
import { create as createTar } from 'tar'
import { expect, it, onTestFinished } from 'vitest'
import { artifactManifestSchema, fileDigest, payloadFiles, SSH_HELPER_TARGETS, verifyPayload } from './artifact.ts'
import { macosDeploymentVersions } from './native.ts'
import { extractHelper } from '../verify-ssh-helper-artifact.ts'
import { prepareSshRelease } from './release.ts'
async function fixture() {
const root = await mkdtemp(join(tmpdir(), 'dsh-helper-archive-'))
onTestFinished(() => rm(root, { recursive: true, force: true }))
const payload = join(root, 'dsh-ssh-helper')
await mkdir(join(payload, 'native/system'), { recursive: true })
await writeFile(join(payload, 'dsh-ssh-helper'), 'fixture executable')
await writeFile(join(payload, 'native/system/package.json'), '{}')
const metadata = {
format: 1, version: '1.0.0', commit: 'a'.repeat(40), dirty: false,
target: 'node24-linux-x64', protocol: 2, nodeVersion: 'v24.1.0',
files: await Promise.all((await payloadFiles(payload)).map(async path => ({
path, sha256: await fileDigest(join(payload, path)), mode: (await lstat(join(payload, path))).mode & 0o777,
}))),
}
const save = async () => { await writeFile(join(payload, 'manifest.json'), JSON.stringify(metadata)) }
await save()
return { root, payload, metadata, save }
}
it('validates the exact unpacked inventory and rejects altered bytes', async () => {
const test = await fixture()
expect(await verifyPayload(test.payload)).toEqual(test.metadata)
await writeFile(join(test.payload, 'dsh-ssh-helper'), 'changed executable')
await expect(verifyPayload(test.payload)).rejects.toThrow('digest differs')
})
it('rejects missing, undeclared and duplicate payload files', async () => {
const test = await fixture()
await writeFile(join(test.payload, 'undeclared'), '')
await expect(verifyPayload(test.payload)).rejects.toThrow('inventory')
await rm(join(test.payload, 'undeclared'))
test.metadata.files.push(test.metadata.files[0]!)
await test.save()
await expect(verifyPayload(test.payload)).rejects.toThrow('inventory')
test.metadata.files.pop()
await test.save()
await rm(join(test.payload, 'native/system/package.json'))
await expect(verifyPayload(test.payload)).rejects.toThrow('inventory')
})
it.each(['../outside', '/absolute', 'a/../b', 'a\\b', 'a//b'])('rejects unsafe manifest path %s', async (path) => {
const test = await fixture()
expect(() => artifactManifestSchema.parse({ ...test.metadata, files: [{ ...test.metadata.files[0], path }] })).toThrow('payload path')
})
it.skipIf(process.platform === 'win32')('rejects links before extracting an archive', async () => {
const test = await fixture()
await symlink('/etc/passwd', join(test.payload, 'outside'))
await expect(payloadFiles(test.payload)).rejects.toThrow('symbolic link')
const archive = join(test.root, 'linked.tar.gz')
await createTar({ cwd: test.root, file: archive, gzip: true }, ['dsh-ssh-helper'])
const extracted = join(test.root, 'unpack')
await mkdir(extracted)
await expect(extractHelper(archive, extracted)).rejects.toThrow('Invalid SSH helper archive entry')
})
it('extracts and verifies a portable archive in a new directory', async () => {
const test = await fixture()
const archive = join(test.root, 'helper.tar.gz')
await createTar({ cwd: test.root, file: archive, gzip: true, portable: true }, ['dsh-ssh-helper'])
const extracted = join(test.root, 'relocated')
await mkdir(extracted)
const directory = await extractHelper(archive, extracted)
expect(dirname(directory)).toBe(extracted)
expect(await verifyPayload(directory)).toEqual(test.metadata)
expect(await readFile(join(directory, 'dsh-ssh-helper'), 'utf8')).toBe('fixture executable')
})
it('reads minimum macOS versions without accepting a linked library version as the OS version', () => {
expect(macosDeploymentVersions('Load command 0\ncmd LC_VERSION_MIN_MACOSX\nversion 11.0\nLoad command 1\ncmd LC_LOAD_DYLIB\ncurrent version 1311.100.3\nLoad command 2\ncmd LC_BUILD_VERSION\nminos 14.0\nsdk 15.1\n'))
.toEqual(['11.0', '14.0'])
expect(macosDeploymentVersions('Load command 0\ncmd LC_LOAD_DYLIB\ncurrent version 14.0\n')).toEqual([])
})
it('publishes only a complete clean-source matrix with native and no-Node evidence', async () => {
const test = await fixture()
const archives = join(test.root, 'release')
await mkdir(archives)
const checks = ['executable-handshake', 'guarded-files-and-streams', 'managed-process-output', 'process-cancellation', 'native-pty', 'native-flock', 'embedded-ptc-and-deadline', 'sandbox-enforcement']
for (const target of SSH_HELPER_TARGETS) {
const parent = join(test.root, target)
await mkdir(parent)
const payload = join(parent, 'dsh-ssh-helper')
await cp(test.payload, payload, { recursive: true })
const manifest = { ...test.metadata, target }
await writeFile(join(payload, 'manifest.json'), JSON.stringify(manifest))
const archive = join(archives, `dsh-ssh-helper-1.0.0-${target.slice('node24-'.length)}.tar.gz`)
await createTar({ cwd: parent, file: archive, gzip: true, portable: true }, ['dsh-ssh-helper'])
await writeFile(`${archive}.sha256`, `${await fileDigest(archive)} archive\n`)
const runtime = { checks, nodeVersion: 'v24.1.0', platform: target.includes('linux') ? 'linux' : 'darwin', sandboxLane: 'required' }
await writeFile(join(archives, `${target}.json`), JSON.stringify({ manifest, runtime, restrictedWorker: true, readonlyInstall: true, concurrentColdStarts: 2 }))
if (target.includes('linux')) {
await writeFile(join(archives, `${target}.ssh.json`), JSON.stringify({ manifest, runtime: { ...runtime, checks: [...checks, 'target-has-no-node'], sandboxLane: 'portable' }, glibc: 'glibc 2.28' }))
await writeFile(join(archives, `${target}.landlock.json`), JSON.stringify({ manifest, runtime, expectedBackend: 'landlock-run' }))
}
}
expect(await prepareSshRelease(archives, '1.0.0', test.metadata.commit)).toHaveLength(5)
expect((await readFile(join(archives, 'SHA256SUMS'), 'utf8')).trim().split('\n')).toHaveLength(4)
await expect(prepareSshRelease(archives, '1.0.0', 'b'.repeat(40))).rejects.toThrow()
const report = join(archives, 'node24-linux-x64.ssh.json')
const evidence = JSON.parse(await readFile(report, 'utf8')) as { runtime: { checks: string[] } }
evidence.runtime.checks = evidence.runtime.checks.filter(check => check !== 'target-has-no-node')
await writeFile(report, JSON.stringify(evidence))
await expect(prepareSshRelease(archives, '1.0.0', test.metadata.commit)).rejects.toThrow('lacks target-has-no-node')
await rm(report)
await expect(prepareSshRelease(archives, '1.0.0', test.metadata.commit)).rejects.toThrow('ENOENT')
})
+88
View File
@@ -0,0 +1,88 @@
/** Versioned archive metadata and file integrity checks for SSH helper releases. */
import { createHash } from 'node:crypto'
import { lstat, readFile, readdir } from 'node:fs/promises'
import { join, relative, sep } from 'node:path'
import { z } from 'zod'
/** Native target identifiers accepted by the builder and release workflow. */
export const SSH_HELPER_TARGETS = ['node24-linux-x64', 'node24-linux-arm64', 'node24-macos-x64', 'node24-macos-arm64'] as const
/** One qualified OS and architecture for a bundled Node 24 helper. */
export type SshHelperTarget = typeof SSH_HELPER_TARGETS[number]
const payloadPath = z.string().min(1).refine(value =>
!value.startsWith('/') && !value.includes('\\') && !value.includes('\0')
&& value.split('/').every(part => part !== '' && part !== '.' && part !== '..'), 'invalid payload path')
/** Parser for metadata supplied beside an executable, including every runtime resource. */
export const artifactManifestSchema = z.object({
format: z.literal(1),
version: z.string().regex(/^\d+\.\d+\.\d+(?:-[a-zA-Z0-9.-]+)?$/),
commit: z.string().regex(/^[a-f0-9]{40}$/),
dirty: z.boolean(),
target: z.enum(SSH_HELPER_TARGETS),
protocol: z.number().int().positive(),
nodeVersion: z.string().regex(/^v24\./),
files: z.array(z.object({
path: payloadPath, sha256: z.string().regex(/^[a-f0-9]{64}$/), mode: z.number().int().min(0).max(0o777),
}).strict()).min(1),
}).strict()
/** Results written by the isolated Loader consumer after its assertions succeed. */
export const runtimeReportSchema = z.object({
checks: z.array(z.string()), platform: z.enum(['linux', 'darwin']), nodeVersion: z.string(),
sandboxLane: z.enum(['required', 'unavailable', 'portable']),
}).strict()
/** Parsed release metadata; files excludes manifest.json to avoid a self-referential digest. */
export type ArtifactManifest = z.infer<typeof artifactManifestSchema>
/**
* Enumerate an owned payload without following links outside its directory.
* @param root - unpacked payload directory.
* @returns sorted POSIX relative file paths, excluding manifest.json.
*/
export async function payloadFiles(root: string): Promise<string[]> {
const paths: string[] = []
const visit = async (directory: string): Promise<void> => {
for (const name of await readdir(directory)) {
const path = join(directory, name)
const metadata = await lstat(path)
if (metadata.isSymbolicLink()) throw new Error(`SSH helper payload contains a symbolic link: ${path}`)
if (metadata.isDirectory()) await visit(path)
else if (metadata.isFile()) paths.push(relative(root, path).split(sep).join('/'))
else throw new Error(`SSH helper payload contains a non-regular file: ${path}`)
}
}
await visit(root)
return paths.filter(path => path !== 'manifest.json').sort()
}
/**
* Hash the exact file bytes used for installation or publication.
* @param path - regular file path.
* @returns lowercase SHA-256.
*/
export async function fileDigest(path: string): Promise<string> {
return createHash('sha256').update(await readFile(path)).digest('hex')
}
/**
* Verify all payload bytes and permissions before running an unpacked release.
* @param directory - unpacked payload root.
* @returns the validated metadata; missing, duplicate, extra, or altered files reject.
*/
export async function verifyPayload(directory: string): Promise<ArtifactManifest> {
const manifest = artifactManifestSchema.parse(JSON.parse(await readFile(join(directory, 'manifest.json'), 'utf8')))
const actual = await payloadFiles(directory)
const declared = manifest.files.map(file => file.path).sort()
if (new Set(declared).size !== declared.length || JSON.stringify(actual) !== JSON.stringify(declared)) {
throw new Error('SSH helper payload file inventory differs from manifest.json')
}
if (!declared.includes('dsh-ssh-helper') || !declared.includes('native/system/package.json')) throw new Error('SSH helper payload omits required runtime files')
for (const file of manifest.files) {
const path = join(directory, file.path)
if (await fileDigest(path) !== file.sha256) throw new Error(`SSH helper payload digest differs: ${file.path}`)
if (((await lstat(path)).mode & 0o777) !== file.mode) throw new Error(`SSH helper payload permissions differ: ${file.path}`)
}
return manifest
}
+74
View File
@@ -0,0 +1,74 @@
/** Inspect every native payload, including modules embedded in the executable. */
import { execFileSync } from 'node:child_process'
import { open } from 'node:fs/promises'
import { join } from 'node:path'
import { payloadFiles, type SshHelperTarget } from './artifact.ts'
function newer(version: string, ceiling: number[]): boolean {
const components = version.split('.').map(Number)
for (let index = 0; index < Math.max(components.length, ceiling.length); index += 1) {
const difference = (components[index] ?? 0) - (ceiling[index] ?? 0)
if (difference !== 0) return difference > 0
}
return false
}
/**
* Read deployment versions without confusing linked-library versions with OS requirements.
* @param output - otool load-command text, possibly containing multiple architecture slices.
* @returns every minimum macOS version declared by the binary.
*/
export function macosDeploymentVersions(output: string): string[] {
let command: string | undefined
const versions: string[] = []
for (const line of output.split('\n')) {
const text = line.trim()
if (/^Load command \d+$/.test(text)) command = undefined
else if (text.startsWith('cmd ')) command = text.slice(4)
else {
const match = /^(minos|version)\s+(\d+(?:\.\d+)+)$/.exec(text)
if (match !== null && ((command === 'LC_BUILD_VERSION' && match[1] === 'minos') || (command === 'LC_VERSION_MIN_MACOSX' && match[1] === 'version'))) versions.push(match[2] as string)
}
}
return versions
}
/**
* Inspect all ELF or Mach-O files for the requested architecture and deployment baseline.
* @param directory - symlink-free staging or payload directory.
* @param target - build target whose ABI must match every native file.
* @returns relative paths of inspected native files.
*/
export async function verifyNativePayload(directory: string, target: SshHelperTarget): Promise<string[]> {
const inspected: string[] = []
const linux = target.includes('-linux-')
const arch = target.endsWith('-arm64') ? 'arm64' : 'x64'
for (const path of await payloadFiles(directory)) {
const filename = join(directory, path)
const file = await open(filename, 'r')
const header = Buffer.alloc(4)
try { await file.read(header, 0, 4, 0) } finally { await file.close() }
const magic = header.readUInt32BE()
const elf = magic === 0x7f454c46
const macho = [0xcffaedfe, 0xcefaedfe, 0xfeedfacf, 0xfeedface, 0xcafebabe, 0xbebafeca, 0xcafebabf].includes(magic)
if (!elf && !macho) continue
if (linux !== elf) throw new Error(`Native file does not belong to ${target}: ${path}`)
if (elf) {
const elfHeader = execFileSync('readelf', ['--file-header', filename], { encoding: 'utf8' })
const expected = arch === 'arm64' ? /Machine:\s+AArch64/ : /Machine:\s+Advanced Micro Devices X86-64/
if (!expected.test(elfHeader)) throw new Error(`ELF architecture differs from ${target}: ${path}`)
const versions = execFileSync('readelf', ['--version-info', filename], { encoding: 'utf8' })
for (const match of versions.matchAll(/\bGLIBC_(\d+(?:\.\d+)+)/g)) {
if (newer(match[1] as string, [2, 28])) throw new Error(`${path} requires GLIBC_${match[1]}, exceeding 2.28`)
}
} else {
execFileSync('lipo', [filename, '-verify_arch', arch === 'arm64' ? 'arm64' : 'x86_64'], { stdio: 'pipe' })
const loads = execFileSync('otool', ['-l', filename], { encoding: 'utf8' })
const versions = macosDeploymentVersions(loads)
if (versions.length === 0) throw new Error(`Mach-O has no deployment version: ${path}`)
if (versions.some(version => newer(version, [14, 0]))) throw new Error(`${path} requires macOS newer than 14.0`)
}
inspected.push(path)
}
return inspected
}
+42
View File
@@ -0,0 +1,42 @@
/** Short handshake against an actual executable, with bounded process ownership. */
import { spawn } from 'node:child_process'
import { z } from 'zod'
import { SshRpcPeer, SSH_PROTOCOL_VERSION } from '../../packages/ssh/ssh/src/protocol.ts'
import { helloSchema } from '../../packages/ssh/ssh/src/schemas.ts'
/**
* Run a packaged helper and read its runtime version through the private wire protocol.
* @param executable - physical executable under test.
* @param workspace - existing directory supplied for the handshake.
* @returns the validated handshake after the helper has exited.
*/
export async function probeHelper(executable: string, workspace: string): Promise<z.infer<typeof helloSchema>> {
const child = spawn(executable, [], { cwd: workspace, env: { ...process.env, NODE_OPTIONS: '--disable-sigusr1' }, stdio: ['pipe', 'pipe', 'pipe'] })
let diagnostic = ''
child.stderr.on('data', (chunk: Buffer) => { diagnostic = (diagnostic + chunk.toString()).slice(-8192) })
const closed = new Promise<void>((resolve, reject) => {
child.once('error', reject)
child.once('close', (code, signal) => {
if (code === 0 && signal === null) resolve()
else reject(new Error(`SSH helper probe exited (${code ?? signal}): ${diagnostic}`))
})
})
void closed.catch(() => {})
const rpc = new SshRpcPeer(child.stdout, child.stdin, 64 * 1024 * 1024, 128)
child.once('error', (error) => { rpc.close(error) })
const force = setTimeout(() => { child.kill('SIGKILL') }, 30_000)
try {
const hello = await rpc.request('hello', { protocol: SSH_PROTOCOL_VERSION, workspace, leaseMs: 30_000 }, helloSchema, AbortSignal.timeout(20_000))
await rpc.request('close', {}, z.null(), AbortSignal.timeout(5000))
child.stdin.end()
await closed
return hello
} catch (error) {
child.kill('SIGTERM')
await closed.catch(() => {})
throw new Error(`SSH helper handshake failed: ${diagnostic}`, { cause: error })
} finally {
clearTimeout(force)
rpc.close()
}
}
+76
View File
@@ -0,0 +1,76 @@
/** Require four complete, same-commit executable reports before publishing release assets. */
import assert from 'node:assert/strict'
import { mkdir, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { basename, join, resolve } from 'node:path'
import { parseArgs } from 'node:util'
import { z } from 'zod'
import { artifactManifestSchema, fileDigest, runtimeReportSchema, SSH_HELPER_TARGETS, verifyPayload, type ArtifactManifest } from './artifact.ts'
import { extractHelper } from '../verify-ssh-helper-artifact.ts'
const reportSchema = z.object({
manifest: artifactManifestSchema,
runtime: runtimeReportSchema,
restrictedWorker: z.boolean().optional(), expectedBackend: z.string().nullable().optional(), glibc: z.string().optional(),
readonlyInstall: z.boolean().optional(), concurrentColdStarts: z.number().optional(),
}).strict()
const coreChecks = ['executable-handshake', 'guarded-files-and-streams', 'managed-process-output', 'process-cancellation', 'native-pty', 'native-flock', 'embedded-ptc-and-deadline']
async function report(path: string, manifest: ArtifactManifest, checks: readonly string[]) {
const evidence = reportSchema.parse(JSON.parse(await readFile(path, 'utf8')))
assert.deepEqual(evidence.manifest, manifest, `Report metadata differs: ${path}`)
assert.equal(evidence.runtime.nodeVersion, manifest.nodeVersion)
assert.equal(evidence.runtime.platform, manifest.target.includes('-linux-') ? 'linux' : 'darwin')
for (const check of [...coreChecks, ...checks]) assert(evidence.runtime.checks.includes(check), `Report ${path} lacks ${check}`)
return evidence
}
/**
* Validate archives and their required native and SSH evidence, then write the release checksum list.
* @param directory - downloaded artifacts from one successful four-target workflow run.
* @param version - version selected by the release tag.
* @param commit - immutable source commit checked out by every build job.
* @returns the exact archive and checksum files permitted for upload.
*/
export async function prepareSshRelease(directory: string, version: string, commit: string): Promise<string[]> {
const temporary = await mkdtemp(join(tmpdir(), 'dsh-helper-release-'))
const archives: string[] = []
const sums: string[] = []
try {
for (const target of SSH_HELPER_TARGETS) {
const archive = join(directory, `dsh-ssh-helper-${version}-${target.slice('node24-'.length)}.tar.gz`)
const digest = await fileDigest(archive)
assert.equal(digest, (await readFile(`${archive}.sha256`, 'utf8')).split(/\s/)[0])
const destination = join(temporary, target)
await mkdir(destination)
const manifest = await verifyPayload(await extractHelper(archive, destination))
assert.equal(manifest.target, target)
assert.equal(manifest.version, version)
assert.equal(manifest.commit, commit)
assert.equal(manifest.dirty, false, 'Release artifacts must come from a clean source checkout')
const native = await report(join(directory, `${target}.json`), manifest, ['sandbox-enforcement'])
assert.equal(native.runtime.sandboxLane, 'required')
assert.equal(native.readonlyInstall, true)
assert.equal(native.concurrentColdStarts, 2)
if (target.includes('-macos-')) assert.equal(native.restrictedWorker, true)
else {
const ssh = await report(join(directory, `${target}.ssh.json`), manifest, ['target-has-no-node'])
assert.equal(ssh.glibc, 'glibc 2.28')
const landlock = await report(join(directory, `${target}.landlock.json`), manifest, ['sandbox-enforcement'])
assert.equal(landlock.expectedBackend, 'landlock-run')
assert.equal(landlock.runtime.sandboxLane, 'required')
}
archives.push(archive)
sums.push(`${digest} ${basename(archive)}`)
}
const checksums = join(directory, 'SHA256SUMS')
await writeFile(checksums, `${sums.join('\n')}\n`)
return [...archives, checksums]
} finally { await rm(temporary, { recursive: true, force: true }) }
}
if (import.meta.main) {
const { values } = parseArgs({ options: { directory: { type: 'string' }, version: { type: 'string' }, commit: { type: 'string' } } })
if (values.directory === undefined || values.version === undefined || values.commit === undefined) throw new Error('Release verification requires --directory, --version and --commit')
console.log((await prepareSshRelease(resolve(values.directory), values.version, values.commit)).join('\n'))
}
+67
View File
@@ -0,0 +1,67 @@
/** Run the embedded worker while macOS denies access to the checkout and host Node. */
import assert from 'node:assert/strict'
import { spawn } from 'node:child_process'
import { Duplex, type Readable, type Writable } from 'node:stream'
import { join } from 'node:path'
import { z } from 'zod'
import { JsonChannel } from '../../packages/ptc-runtime/ptc-runtime-node/src/channel.ts'
import { decodePtcJsonWire } from '../../packages/ptc-runtime/ptc-runtime-node/src/json-wire.ts'
import { SUBPROCESS_CONTROL_ENV, SUBPROCESS_CONTROL_FD } from '../../packages/subprocess/subprocess/src/control.ts'
/**
* Execute a PTC program with the host runtime and source files inaccessible.
* @param executable - relocated helper executable.
* @param workspace - isolated program working directory.
* @param home - empty helper home and native-resource cache.
* @param checkout - real source checkout path denied by Seatbelt.
* @param hostNode - real host Node path denied by Seatbelt.
*/
export async function probeRestrictedWorker(
executable: string, workspace: string, home: string, checkout: string, hostNode: string,
): Promise<void> {
const profile = `(version 1)(allow default)${[checkout, hostNode].map(path => `(deny file-read* (subpath ${JSON.stringify(path)}))(deny process-exec (subpath ${JSON.stringify(path)}))`).join('')}`
const child = spawn('/usr/bin/sandbox-exec', ['-p', profile, executable, '1048576'], {
cwd: workspace, env: { HOME: home, TMPDIR: home, PATH: '/usr/bin:/bin', DSH_PTC_RUNTIME_NODE: '1', [SUBPROCESS_CONTROL_ENV]: 'pipe', NODE_OPTIONS: '--disable-sigusr1' },
stdio: ['ignore', 'pipe', 'pipe', 'ignore', 'ignore', 'ignore', 'ignore', 'pipe'],
})
const completed = Promise.withResolvers<unknown>()
let diagnostic = ''
assert(child.stderr !== null && child.stdout !== null)
child.stderr.on('data', (chunk: Buffer) => { diagnostic = (diagnostic + chunk.toString()).slice(-8192) })
child.stdout.resume()
const exited = new Promise<void>((resolve, reject) => {
child.once('error', reject)
child.once('close', (code, signal) => {
if (code === 0 && signal === null) resolve()
else reject(new Error(`Restricted PTC worker exited (${code ?? signal}): ${diagnostic}`))
})
})
void exited.catch((error: unknown) => { completed.reject(error) })
const streams: ReadonlyArray<Readable | Writable | null | undefined> = child.stdio
const control = streams[SUBPROCESS_CONTROL_FD]
assert(control instanceof Duplex)
const channel = new JsonChannel(control, 1_048_576, (raw) => {
const message = z.object({ type: z.string(), value: z.unknown().optional(), error: z.unknown().optional() }).parse(raw)
if (message.type === 'ready') {
const code = `const fs=await import('node:fs/promises'); const denied=[]; for(const path of ${JSON.stringify([join(checkout, 'package.json'), hostNode])}) { try { await fs.readFile(path); denied.push('readable') } catch(error) { denied.push(error.code) } } return {executable:process.execPath,env:Object.keys(process.env),denied};`
void channel.send({ type: 'boot', data: { code, namespaces: [], maxOutputBytes: 65_536 } })
.catch((error: unknown) => { completed.reject(error) })
} else if (message.type === 'done') {
if (message.error !== undefined) completed.reject(new Error(JSON.stringify(message.error)))
else completed.resolve(decodePtcJsonWire(message.value))
channel.close()
} else completed.reject(new Error(`Unexpected restricted-worker message: ${message.type}`))
}, (error) => { completed.reject(error) })
const force = setTimeout(() => { child.kill('SIGKILL') }, 20_000)
try {
const result = z.object({ executable: z.string(), env: z.array(z.string()), denied: z.array(z.enum(['EPERM', 'EACCES'])) }).parse(await completed.promise)
assert.equal(result.executable, executable)
assert.deepEqual(result.env, [])
assert.equal(result.denied.length, 2)
await exited
} finally {
channel.close()
child.kill('SIGTERM')
try { await exited } finally { clearTimeout(force) }
}
}
+5
View File
@@ -2311,6 +2311,11 @@
"symbol": "PtcRunSandbox",
"source": "packages/ptc-runtime/ptc-runtime/src/types.ts"
},
{
"doc": "docs/subsystems/ssh.md",
"symbol": "HelperLaunch",
"source": "packages/ssh/ssh/src/index.ts"
},
{
"doc": "docs/subsystems/ssh.md",
"symbol": "Config",
@@ -57,6 +57,7 @@ const SENTENCE_MODEL_EXPERIENCE: Readonly<Record<string, SentenceContract>> = {
'packages/host/product-telemetry-otel': { kind: 'none', reason: 'The plugin exports explicit analytics records without contributing model context.' },
'packages/api/terminal-controller': { kind: 'indirect', reason: 'Working-directory recovery owns directory context; user terminal screens never enter model requests.' },
'packages/client/ui-sidebar-terminal': { kind: 'none', reason: 'The browser renders user terminal screens without exposing them to the model.' },
'packages/ssh/ssh-helper-runtime': { kind: 'none', reason: 'The private executable carrier registers no model-facing content; its providers and consumers own operation results.' },
'packages/experimental/worktree': { kind: 'indirect', reason: 'The worktree tool renders creation results; the working-directory service owns model-visible directory context.' },
'packages/ssh/ssh': { kind: 'none', reason: 'The connection owner transports private provider operations; consumers own all model-facing content.' },
'packages/ssh/fs-ssh': { kind: 'indirect', reason: 'The remote filesystem delegates model rendering to the existing filesystem consumers.' },
+10
View File
@@ -39,6 +39,16 @@ afterEach(() => {
})
describe('verifyRuntimeClosure', () => {
it('checks a private worker closure without requiring application presets', async () => {
const manifestPath = 'packages/ssh/ssh-helper-runtime/package.json'
const root = fixture({ [manifestPath]: { name: 'helper', dependencies: { '@scope/worker': 'workspace:^' } } })
workspace(root, '@scope/worker', { peerDependencies: { '@scope/peer': 'workspace:^' } })
workspace(root, '@scope/peer', {})
expect((await verifyRuntimeClosure(root, manifestPath, false)).failures).toEqual(['helper -> @scope/worker -> @scope/peer'])
writeFileSync(join(root, manifestPath), JSON.stringify({ name: 'helper', dependencies: { '@scope/worker': 'workspace:^', '@scope/peer': 'workspace:^' } }))
expect(await verifyRuntimeClosure(root, manifestPath, false)).toMatchObject({ failures: [], presetCount: 0 })
})
it('requires only plugins active for each published target', async () => {
const root = fixture({
'python/sdk-runtime/package.json': { name: 'runtime', dependencies: { '@scope/shared': 'workspace:^' } },
+6 -4
View File
@@ -42,18 +42,20 @@ export interface RuntimeClosureResult {
* Check that the runtime manifest contains every shipped-preset plugin and workspace peer.
* @param root repository root containing the runtime manifest and shipped presets.
* @param manifestPath runtime manifest path relative to {@link root}.
* @param includePresets whether this carrier includes the shipped application presets.
* @returns the discovered preset count, reachable workspace package count, and violations.
*/
export async function verifyRuntimeClosure(
root: string,
manifestPath = 'python/sdk-runtime/package.json',
includePresets = true,
): Promise<RuntimeClosureResult> {
const runtimeManifest = await loadManifest(resolve(root, manifestPath))
const runtimeName = runtimeManifest.name ?? manifestPath
const workspace = await loadWorkspacePackages(root)
const runtimeDependencies = runtimeManifest.dependencies ?? {}
const platforms = await loadJson<RuntimePlatformManifest>(resolve(root, 'python/sdk-runtime/platforms.json'))
const presetPaths = globSync(AGENT_PRESET_GLOB, { cwd: root }).sort()
const platforms = includePresets ? await loadJson<RuntimePlatformManifest>(resolve(root, 'python/sdk-runtime/platforms.json')) : {}
const presetPaths = includePresets ? globSync(AGENT_PRESET_GLOB, { cwd: root }).sort() : []
const targets = Object.keys(platforms).sort()
const parents = new Map<string, string | undefined>()
const queue: string[] = []
@@ -65,8 +67,8 @@ export async function verifyRuntimeClosure(
}
const failures: string[] = []
if (presetPaths.length === 0) failures.push(`no agent presets matched ${AGENT_PRESET_GLOB}`)
if (targets.length === 0) failures.push('python/sdk-runtime/platforms.json defines no runtime targets')
if (includePresets && presetPaths.length === 0) failures.push(`no agent presets matched ${AGENT_PRESET_GLOB}`)
if (includePresets && targets.length === 0) failures.push('python/sdk-runtime/platforms.json defines no runtime targets')
failures.push(...await missingPresetPlugins(root, runtimeDependencies, presetPaths, targets))
for (let index = 0; index < queue.length; index += 1) {
const packageName = queue[index]
+167
View File
@@ -0,0 +1,167 @@
/** Unpack and run a release archive through the actual Loader-mounted SSH consumers. */
import { spawn } from 'node:child_process'
import { chmod, mkdir, mkdtemp, readFile, readdir, realpath, rm, writeFile } from 'node:fs/promises'
import { homedir } from 'node:os'
import { dirname, join, resolve } from 'node:path'
import { parseArgs } from 'node:util'
import { extract, list } from 'tar'
import { fileDigest, runtimeReportSchema, verifyPayload, type ArtifactManifest } from './ssh-helper/artifact.ts'
import { probeRestrictedWorker } from './ssh-helper/worker-probe.ts'
import { verifyNativePayload } from './ssh-helper/native.ts'
const root = resolve(import.meta.dirname, '..')
const fixtures = join(root, 'packages/ssh/ssh-helper-runtime/tests/fixtures')
async function directoryPermissions(directory: string, mode: number): Promise<void> {
await chmod(directory, mode)
for (const entry of await readdir(directory, { withFileTypes: true })) {
if (entry.isDirectory()) await directoryPermissions(join(directory, entry.name), mode)
}
}
async function makeReadonly(directory: string, manifest: ArtifactManifest): Promise<void> {
for (const file of manifest.files) await chmod(join(directory, file.path), file.mode & ~0o222)
await chmod(join(directory, 'manifest.json'), 0o444)
await directoryPermissions(directory, 0o555)
}
/**
* Reject links and escaping paths before extracting a helper's release archive.
* @param archive - gzip tar file supplied by the build.
* @param directory - empty extraction directory owned by the caller.
* @returns the extracted payload root.
*/
export async function extractHelper(archive: string, directory: string): Promise<string> {
const entries: { path: string; type: string }[] = []
await list({ file: archive, onReadEntry: (entry) => { entries.push({ path: entry.path, type: entry.type }) } })
const seen = new Set<string>()
for (const entry of entries) {
const path = entry.path.replace(/\/$/, '')
if (!['File', 'Directory'].includes(entry.type) || path.split('/').some(part => part === '..' || part === '.' || part === '')
|| path.includes('\\') || !path.startsWith('dsh-ssh-helper') || (path !== 'dsh-ssh-helper' && !path.startsWith('dsh-ssh-helper/')) || seen.has(path)) {
throw new Error(`Invalid SSH helper archive entry: ${entry.path} (${entry.type})`)
}
seen.add(path)
}
if (!seen.has('dsh-ssh-helper/manifest.json')) throw new Error('SSH helper archive has no manifest.json')
await extract({ file: archive, cwd: directory, strict: true })
return join(directory, 'dsh-ssh-helper')
}
/**
* Run the isolated consumer process and await all output and process teardown.
* @param config - generated Loader configuration.
* @param report - output report path.
* @param sandbox - expected confinement availability on this lane.
* @param environment - isolated client environment, including any test-owned SSH wrapper.
*/
export async function runArtifactDriver(config: string, report: string, sandbox: string, environment: NodeJS.ProcessEnv): Promise<void> {
const child = spawn(process.execPath, ['--import', 'tsx/esm', join(fixtures, 'driver.ts'), config, report, sandbox], {
cwd: root, stdio: ['ignore', 'pipe', 'pipe'], env: environment,
})
let output = ''
for (const stream of [child.stdout, child.stderr]) stream.on('data', (chunk: Buffer) => {
output = (output + chunk.toString()).slice(-32_768)
})
const force = setTimeout(() => { child.kill('SIGKILL') }, 120_000)
try {
await new Promise<void>((resolve, reject) => {
child.once('error', reject)
child.once('close', (code, signal) => {
if (code === 0 && signal === null) resolve()
else reject(new Error(`SSH artifact consumer exited (${code ?? signal}):\n${output}`))
})
})
} finally { clearTimeout(force) }
}
/**
* Serialize the shared provider composition around a selected helper transport.
* @param connection - concrete Loader connection row, direct fixture or OpenSSH.
* @param workspace - target-side workspace path.
* @returns YAML consumed by the normal application boot path.
*/
export function artifactComposition(connection: { id: string; name: string; config: object }, workspace: string): string {
const rows = [
{ id: 'projections', name: '@deepseek-ai/dsh-session-projection' },
{ id: 'policy', name: '@deepseek-ai/dsh-sandbox-policy', config: { mode: 'workspace-write', workspaceRoot: workspace } },
connection,
{ id: 'fs', name: '@deepseek-ai/dsh-fs-ssh' },
{ id: 'subprocess', name: '@deepseek-ai/dsh-subprocess-ssh' },
{ id: 'sandbox', name: '@deepseek-ai/dsh-sandbox-ssh' },
]
return rows.map(row => `- ${JSON.stringify(row)}`).join('\n')
+ '\n- id: ptc\n name: "@deepseek-ai/dsh-ptc-runtime-node"\n inject: [ssh]\n config:\n launch: !!js ctx.ssh.ptcLaunch\n'
}
/**
* Verify archive integrity and all core operations after relocation outside the checkout.
* @param argv - verifier flags.
*/
export async function verifySshHelper(argv: string[]): Promise<void> {
const { values } = parseArgs({ args: argv, options: {
archive: { type: 'string' }, sandbox: { type: 'string', default: 'required' },
report: { type: 'string' },
backend: { type: 'string' },
} })
if (values.archive === undefined || !['required', 'unavailable'].includes(values.sandbox)) throw new Error('Use --archive=<file> --sandbox=required|unavailable')
if (values.backend !== undefined && !['bwrap', 'landlock-run', 'sandbox-exec'].includes(values.backend)) throw new Error('Unknown expected sandbox backend')
if (values.backend === 'landlock-run' && process.platform !== 'linux') throw new Error('Landlock verification requires Linux')
const archive = resolve(values.archive)
const checksum = (await readFile(`${archive}.sha256`, 'utf8')).split(/\s/)[0]
if (await fileDigest(archive) !== checksum) throw new Error('SSH helper archive checksum mismatch')
const temporary = await realpath(await mkdtemp(join(homedir(), '.dsh-helper-check-')))
try {
const installed = await extractHelper(archive, temporary)
const manifest = await verifyPayload(installed)
const host = `node24-${process.platform === 'darwin' ? 'macos' : process.platform}-${process.arch}`
if (manifest.target !== host) throw new Error(`Artifact ${manifest.target} cannot be validated on ${host}`)
await verifyNativePayload(installed, manifest.target)
await makeReadonly(installed, manifest)
const workspace = join(temporary, 'workspace')
const home = join(temporary, 'home')
await mkdir(workspace); await mkdir(home)
let path = '/usr/bin:/bin'
if (values.backend === 'landlock-run') {
const bin = join(temporary, 'bin')
await mkdir(bin)
await writeFile(join(bin, 'bwrap'), '#!/bin/sh\nexit 127\n')
await chmod(join(bin, 'bwrap'), 0o755)
path = `${bin}:${path}`
}
const executable = join(installed, 'dsh-ssh-helper')
const helperHash = await fileDigest(executable)
const environment = {
HOME: home, PATH: process.env.PATH, DSH_HOME: join(home, 'dsh'),
TSX_TSCONFIG_PATH: join(root, 'tsconfig.base.json'), DSH_TELEMETRY_DISABLED: '1',
...(values.backend === undefined ? {} : { DSH_EXPECT_SANDBOX_RUNNER: values.backend }),
}
const runs = await Promise.allSettled([0, 1].map(async (index) => {
const cwd = join(workspace, String(index))
await mkdir(cwd)
const config = join(temporary, `cordis-${index}.yml`)
const report = join(temporary, `report-${index}.json`)
await writeFile(config, artifactComposition({ id: 'ssh', name: join(fixtures, 'direct-helper.ts'), config: {
executable, helperHash, workspace: cwd, home, path,
} }, cwd))
await runArtifactDriver(config, report, values.sandbox, environment)
}))
const failures = runs.filter(result => result.status === 'rejected').map((result): unknown => result.reason)
if (failures.length > 0) throw new AggregateError(failures, 'Concurrent SSH artifact consumers failed')
if (process.platform === 'darwin') await probeRestrictedWorker(executable, workspace, home, await realpath(root), await realpath(process.execPath))
const evidence = { manifest, runtime: runtimeReportSchema.parse(JSON.parse(await readFile(join(temporary, 'report-0.json'), 'utf8'))),
restrictedWorker: process.platform === 'darwin', expectedBackend: values.backend ?? null,
readonlyInstall: true, concurrentColdStarts: 2 }
if (values.report !== undefined) {
const destination = resolve(values.report)
await mkdir(dirname(destination), { recursive: true })
await writeFile(destination, `${JSON.stringify(evidence, null, 2)}\n`)
}
console.log(`SSH helper ${manifest.target}: ${JSON.stringify(evidence.runtime)}`)
} finally {
await directoryPermissions(temporary, 0o755)
await rm(temporary, { recursive: true, force: true })
}
}
if (import.meta.main) await verifySshHelper(process.argv.slice(2))
+108
View File
@@ -0,0 +1,108 @@
/** Real OpenSSH acceptance against a glibc 2.28 container with no installed Node. */
import assert from 'node:assert/strict'
import { execFile, spawn } from 'node:child_process'
import { chmod, mkdir, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { dirname, join, resolve } from 'node:path'
import { parseArgs, promisify } from 'node:util'
import { randomUUID } from 'node:crypto'
import { fileDigest, runtimeReportSchema, verifyPayload } from './ssh-helper/artifact.ts'
import { artifactComposition, extractHelper, runArtifactDriver } from './verify-ssh-helper-artifact.ts'
const run = promisify(execFile)
const root = resolve(import.meta.dirname, '..')
async function docker(...args: string[]): Promise<string> {
return (await run('docker', args, { timeout: 300_000, maxBuffer: 16 * 1024 * 1024 })).stdout.trim()
}
async function sshdReady(container: string): Promise<void> {
const logs = spawn('docker', ['logs', '--follow', container], { stdio: ['ignore', 'pipe', 'pipe'] })
let text = ''
const ready = Promise.withResolvers<void>()
const closed = new Promise<void>((resolve) => { logs.once('close', () => { resolve(); ready.reject(new Error(`sshd exited before readiness: ${text}`)) }) })
const read = (chunk: Buffer): void => {
text = (text + chunk.toString()).slice(-8192)
if (text.includes('Server listening on')) ready.resolve()
}
logs.stdout.on('data', read); logs.stderr.on('data', read)
logs.once('error', (error) => { ready.reject(error) })
const deadline = setTimeout(() => { ready.reject(new Error(`sshd readiness timed out: ${text}`)) }, 30_000)
try { await ready.promise }
finally { clearTimeout(deadline); logs.kill('SIGTERM'); await closed }
}
/**
* Install only a validated release into an isolated SSH server and exercise production providers.
* @param argv - archive and optional report flags.
*/
export async function verifySshTransport(argv: string[]): Promise<void> {
const { values } = parseArgs({ args: argv, options: { archive: { type: 'string' }, report: { type: 'string' } } })
if (values.archive === undefined) throw new Error('Use --archive=<Linux helper archive>')
const archive = resolve(values.archive)
assert.equal(await fileDigest(archive), (await readFile(`${archive}.sha256`, 'utf8')).split(/\s/)[0], 'Archive checksum')
const temporary = await mkdtemp(join(tmpdir(), 'dsh-helper-ssh-'))
const image = `dsh-helper-test:${randomUUID()}`
let imageBuilt = false
let container: string | undefined
try {
const installed = await extractHelper(archive, temporary)
const manifest = await verifyPayload(installed)
if (!manifest.target.includes('-linux-')) throw new Error('OpenSSH container acceptance requires a Linux artifact')
const platform = manifest.target.endsWith('-arm64') ? 'linux/arm64' : 'linux/amd64'
await docker('build', '--platform', platform, '--tag', image, join(root, 'packages/ssh/ssh-helper-runtime/tests/fixtures/sshd'))
imageBuilt = true
const identity = join(temporary, 'identity')
await run('ssh-keygen', ['-q', '-t', 'ed25519', '-N', '', '-f', identity])
container = await docker('run', '--detach', '--platform', platform, '--publish', '127.0.0.1::22',
'--mount', `type=bind,src=${installed},dst=/opt/dsh-helper,readonly`,
'--mount', `type=bind,src=${identity}.pub,dst=/fixture-key.pub,readonly`, image)
await sshdReady(container)
const published = await docker('port', container, '22/tcp')
const port = /^127\.0\.0\.1:(\d+)$/.exec(published)?.[1]
if (port === undefined) throw new Error(`Unexpected Docker port mapping: ${published}`)
const publicKey = await docker('exec', container, 'cat', '/etc/ssh/ssh_host_ed25519_key.pub')
const knownHosts = join(temporary, 'known_hosts')
await writeFile(knownHosts, `[127.0.0.1]:${port} ${publicKey}\n`, { mode: 0o600 })
const sshConfig = join(temporary, 'ssh_config')
await writeFile(sshConfig, `Host artifact\n HostName 127.0.0.1\n Port ${port}\n User dsh\n IdentityFile "${identity}"\n IdentitiesOnly yes\n UserKnownHostsFile "${knownHosts}"\n GlobalKnownHostsFile /dev/null\n`, { mode: 0o600 })
const bin = join(temporary, 'bin')
await mkdir(bin)
const quote = (value: string): string => `'${value.replaceAll("'", "'\\''")}'`
await writeFile(join(bin, 'ssh'), `#!/bin/sh\nexec /usr/bin/ssh -F ${quote(sshConfig)} "$@"\n`)
await chmod(join(bin, 'ssh'), 0o755)
const workspace = '/home/dsh/workspace'
const config = join(temporary, 'cordis.yml')
await writeFile(config, artifactComposition({ id: 'ssh', name: '@deepseek-ai/dsh-ssh', config: {
host: 'artifact', launch: { kind: 'executable' }, helper: '/opt/dsh-helper/dsh-ssh-helper',
helperHash: await fileDigest(join(installed, 'dsh-ssh-helper')), workspace,
} }, workspace))
const home = join(temporary, 'client-home')
await mkdir(home)
const report = join(temporary, 'report.json')
await runArtifactDriver(config, report, 'portable', {
HOME: home, PATH: `${bin}:${process.env.PATH ?? '/usr/bin:/bin'}`, DSH_HOME: join(home, 'dsh'),
TSX_TSCONFIG_PATH: join(root, 'tsconfig.base.json'), DSH_TELEMETRY_DISABLED: '1', DSH_VERIFY_NO_NODE: '1',
})
const evidence = { manifest, runtime: runtimeReportSchema.parse(JSON.parse(await readFile(report, 'utf8'))), glibc: await docker('exec', container, 'getconf', 'GNU_LIBC_VERSION') }
assert.equal(evidence.glibc, 'glibc 2.28')
if (values.report !== undefined) {
const destination = resolve(values.report)
await mkdir(dirname(destination), { recursive: true })
await writeFile(destination, `${JSON.stringify(evidence, null, 2)}\n`)
}
console.log(`SSH helper real SSH ${manifest.target}: ${JSON.stringify(evidence.runtime)}`)
} catch (error) {
if (container === undefined) throw error
const logs = await run('docker', ['logs', container], { maxBuffer: 1024 * 1024 })
throw new Error(`SSH container diagnostics:\n${logs.stdout}\n${logs.stderr}`, { cause: error })
} finally {
try { if (container !== undefined) await docker('rm', '--force', container) }
finally {
try { if (imageBuilt) await docker('image', 'rm', image) }
finally { await rm(temporary, { recursive: true, force: true }) }
}
}
}
if (import.meta.main) await verifySshTransport(process.argv.slice(2))