Files
PaperClipAI/scripts/__tests__/grok-public-install-sandbox.test.mjs
DottaandPaperclip 598e190cb3 test: bind installed native payloads and await saved state
Isolate actual Codex resolver fixtures from global bridge lookup and preserve host qualification blockers with literal evidence.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-12 11:45:22 -05:00

543 lines
45 KiB
JavaScript

import assert from 'node:assert/strict';
import { createHash } from 'node:crypto';
import { mkdirSync, mkdtempSync, readFileSync, realpathSync, rmSync, symlinkSync, writeFileSync } from 'node:fs';
import { spawnSync } from 'node:child_process';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import test from 'node:test';
import { fileURLToPath } from 'node:url';
import { isWorkspacePackage, parseWorkspaceEntries } from '../build-standalone-public-packages.mjs';
import { GROK_PUBLIC_INSTALL_IMAGE, GROK_PUBLIC_INSTALL_LIFECYCLE, assertInstalledCodexPlatformProvenance, assertInstalledNativeConsumerContinuity, assertNoBundledCodexPayloads, grokConsumerDockerArgs, installedCodexProbeSource, installedDaemonProbeSource, macNodeHeadersDirectory, macPublicInstallLifecycleProfile, macInstalledStartupProbeSource } from '../grok-public-install-sandbox.mjs';
import { verifyPiPackagedDaemon } from '../pi-public-install-probe.mjs';
import { runnerBinaryTarget } from '../../packages/paperclip-runner/src/live/runner-binary.ts';
const paths = { assets: '/private/staging/assets', consumer: '/private/staging/consumer', cache: '/private/staging/cache', uid: 1001, gid: 1001 };
const values = (args, flag) => args.flatMap((value, index) => value === flag ? [args[index + 1]] : []);
test('native host startup preserves the consumer lock and both executable byte identities', () => {
const before = { lockSha256: 'a'.repeat(64), runnerSha256: 'b'.repeat(64), codexCommandSha256: 'c'.repeat(64), codexNativeExecutableSha256: 'e'.repeat(64) };
assert.doesNotThrow(() => assertInstalledNativeConsumerContinuity(before, { ...before }));
for (const field of Object.keys(before)) {
assert.throws(() => assertInstalledNativeConsumerContinuity(before, { ...before, [field]: 'd'.repeat(64) }), new RegExp(field));
assert.throws(() => assertInstalledNativeConsumerContinuity({ ...before, [field]: '' }, { ...before, [field]: '' }), new RegExp(field));
}
const source = readFileSync(new URL('../verify-grok-npm-install.mjs', import.meta.url), 'utf8');
const arm = source.split('async function verifyLinuxArmConsumer')[1].split("if (process.argv[2] === '--linux-arm64-consumer')")[0];
assert.match(arm, /const hostEnv = \{ PATH: .*HOME: home, TMPDIR: hostTmp, LC_ALL: 'C', TZ: 'UTC' \}/);
assert.match(arm, /execFileSync\(process.execPath, \[file\], \{ cwd: consumer, env: hostEnv/);
assert.ok(arm.indexOf('isolated(GROK_PUBLIC_INSTALL_LIFECYCLE)') < arm.indexOf("hostProbe('host-startup-probe.mjs'"));
assert.ok(arm.indexOf('const before =') < arm.indexOf("hostProbe('host-startup-probe.mjs'"));
assert.ok(arm.indexOf("hostProbe('host-startup-probe.mjs'") < arm.indexOf('const after ='));
assert.match(arm, /assertInstalledNativeConsumerContinuity\(before, after\)/);
assert.doesNotMatch(arm, /externallySandboxed|externalSandbox|sudo|sysctl|--privileged|seccomp=unconfined|unshare/);
});
test('Mac offline lifecycle uses only the matching executing Node SDK', () => {
const root = realpathSync(mkdtempSync(join(tmpdir(), 'mac-node-headers-test-')));
try {
const prefix = join(root, 'sdk'), executable = join(prefix, 'bin/node'), include = join(prefix, 'include/node');
mkdirSync(join(prefix, 'bin'), { recursive: true }); mkdirSync(include, { recursive: true });
writeFileSync(executable, 'fixture Node executable');
writeFileSync(join(include, 'node.h'), '#include "node_version.h"\n');
const header = '#define NODE_MAJOR_VERSION 24\n#define NODE_MINOR_VERSION 20\n#define NODE_PATCH_VERSION 0\n';
writeFileSync(join(include, 'node_version.h'), header);
assert.equal(macNodeHeadersDirectory(executable, '24.20.0'), prefix);
assert.throws(() => macNodeHeadersDirectory(executable, '24.19.0'), /must match the executing Node/);
assert.throws(() => macNodeHeadersDirectory(executable, '24.20.0-custom'), /exact release version/);
writeFileSync(join(include, 'node_version.h'), header + '#define NODE_PATCH_VERSION 0\n');
assert.throws(() => macNodeHeadersDirectory(executable, '24.20.0'), /declare one patch version/);
writeFileSync(join(include, 'node_version.h'), header);
rmSync(join(include, 'node.h'));
assert.throws(() => macNodeHeadersDirectory(executable, '24.20.0'), /ENOENT/);
writeFileSync(join(root, 'outside-node.h'), '#include "node_version.h"\n');
symlinkSync(join(root, 'outside-node.h'), join(include, 'node.h'));
assert.throws(() => macNodeHeadersDirectory(executable, '24.20.0'), /inside the executing Node prefix/);
const source = readFileSync(new URL('../verify-grok-npm-install.mjs', import.meta.url), 'utf8');
assert.ok(source.includes('macNodeHeadersDirectory(process.execPath, process.versions.node)'));
assert.ok(source.includes('consumer, { ...env, npm_config_nodedir: nodeHeaders }'), 'SDK is bound only to the deferred lifecycle environment');
assert.equal(source.split('npm_config_nodedir:').length, 2);
} finally { rmSync(root, { recursive: true, force: true }); }
});
test('lifecycle execution has no network, host credentials, checkout, or elevated privileges', () => {
const args = grokConsumerDockerArgs({ ...paths, command: GROK_PUBLIC_INSTALL_LIFECYCLE });
assert.deepEqual(values(args, '--network'), ['none']);
assert.deepEqual(values(args, '--user'), ['1001:1001']);
assert.ok(args.includes('--read-only'));
assert.deepEqual(values(args, '--cap-drop'), ['ALL']);
assert.deepEqual(values(args, '--security-opt'), ['no-new-privileges']);
assert.deepEqual(values(args, '--mount'), [
'type=bind,src=/private/staging/assets,dst=/packages,readonly',
'type=bind,src=/private/staging/consumer,dst=/consumer',
'type=bind,src=/private/staging/cache,dst=/cache',
]);
assert.deepEqual(values(args, '--env'), ['HOME=/tmp', 'npm_config_cache=/cache', 'npm_config_nodedir=/usr/local', 'npm_config_audit=false', 'npm_config_fund=false', 'npm_config_ignore_scripts=false']);
assert.match(GROK_PUBLIC_INSTALL_IMAGE, /@sha256:[a-f0-9]{64}$/);
});
test('deferred lifecycle execution rebuilds the installed graph without dependency resolution', () => {
assert.deepEqual(GROK_PUBLIC_INSTALL_LIFECYCLE, ['npm', 'rebuild', '--offline', '--ignore-scripts=false', '--dangerously-allow-all-scripts']);
});
test('a root or malformed host identity cannot run lifecycle scripts', () => {
for (const uid of [0, -1, undefined, '1001']) {
assert.throws(() => grokConsumerDockerArgs({ ...paths, uid, command: ['npm', 'ci'] }), /unprivileged/);
}
});
test('only the scripts-disabled dependency download gets network access', () => {
const args = grokConsumerDockerArgs({ ...paths, download: true, command: ['npm', 'install', '--ignore-scripts'] });
assert.deepEqual(values(args, '--network'), ['bridge']);
assert.ok(values(args, '--env').includes('npm_config_ignore_scripts=true'));
});
test('Pi assembly gets bounded scratch capacity while preserving sandbox restrictions', () => {
const args = grokConsumerDockerArgs({ ...paths, download: true, temporarySizeMiB: 2048, command: ['node', '/consumer/node_modules/paperclipai/dist/index.js', 'runtime', 'setup', 'pi'] });
assert.deepEqual(values(args, '--tmpfs'), ['/tmp:rw,nosuid,nodev,noexec,size=2048m,mode=1777']);
assert.deepEqual(values(args, '--memory'), ['3g']);
assert.ok(args.includes('--read-only'));
assert.deepEqual(values(args, '--cap-drop'), ['ALL']);
assert.deepEqual(values(args, '--security-opt'), ['no-new-privileges']);
for (const temporarySizeMiB of [0, 255, 2049, Infinity, '2048']) {
assert.throws(() => grokConsumerDockerArgs({ ...paths, temporarySizeMiB, command: ['node'] }), /bounded/);
}
});
test('only an offline runtime probe can execute its verified scratch snapshot', () => {
const command = ['node', '/packages/pi-public-install-probe.mjs', '/consumer/node_modules/@paperclipai/server'];
const args = grokConsumerDockerArgs({ ...paths, command, temporarySizeMiB: 2048, temporaryExecutable: true });
assert.deepEqual(values(args, '--tmpfs'), ['/tmp:rw,nosuid,nodev,exec,size=2048m,mode=1777']);
assert.deepEqual(values(args, '--network'), ['none']);
assert.deepEqual(values(args, '--user'), ['1001:1001']);
assert.ok(args.includes('--read-only'));
assert.deepEqual(values(args, '--cap-drop'), ['ALL']);
assert.deepEqual(values(args, '--security-opt'), ['no-new-privileges']);
assert.throws(() => grokConsumerDockerArgs({ ...paths, command, download: true, temporaryExecutable: true }), /offline/);
assert.throws(() => grokConsumerDockerArgs({ ...paths, command, temporaryExecutable: 'true' }), /offline/);
const source = readFileSync(new URL('../verify-grok-npm-install.mjs', import.meta.url), 'utf8');
assert.ok(source.includes("temporarySizeMiB: 2048, temporaryExecutable: true"));
});
test('the separately provisioned executable is exposed read-only to the offline probe', () => {
const prerequisite = '/private/staging/native/grok';
const args = grokConsumerDockerArgs({ ...paths, prerequisite, command: ['node', '/packages/probe.mjs', 'present'] });
assert.deepEqual(values(args, '--network'), ['none']);
assert.equal(values(args, '--mount').at(-1), `type=bind,src=${prerequisite},dst=/opt/paperclip/providers/grok/1.0.13/grok,readonly`);
});
test('verification never elevates PR-controlled provisioning or cleanup on the host', () => {
const source = readFileSync(new URL('../verify-grok-npm-install.mjs', import.meta.url), 'utf8');
assert.doesNotMatch(source, /\bsudo\b/);
assert.ok(source.includes("const prerequisite = join(root, 'native/grok')"));
});
test('the image and Grok downloads start before staging and join without weakening the npm checks', () => {
const source = readFileSync(new URL('../verify-grok-npm-install.mjs', import.meta.url), 'utf8');
// The optional Mac consumer owns separate scratch and no Linux prefetches.
const linuxSource = source.slice(source.indexOf("assert.equal(process.platform, 'linux'"));
const position = fragment => { const index = linuxSource.indexOf(fragment); assert.notEqual(index, -1, `verifier must contain ${fragment}`); return index; };
// Exactly the pinned consumer image is pulled, for the platform the probes run on.
const imagePull = position("prefetch('image', 'docker', ['pull', '--platform', 'linux/amd64', GROK_PUBLIC_INSTALL_IMAGE])");
// Grok is provisioned into the prefetch directory, never straight into `native/grok`.
const grokProvision = position("prefetch('grok', process.execPath, [join(repo, 'packages/paperclip-runner/scripts/provision-grok.mjs'), stagedGrok])");
assert.ok(source.includes("const stagedGrok = join(prefetched, 'grok')"));
assert.doesNotMatch(source, /provision-grok\.mjs'\), prerequisite\]/);
// Both downloads start before any package is staged and before the first sandbox runs.
const staging = position("visit('@paperclipai/server')");
const firstSandbox = position("isolated(['npm', 'install', '--ignore-scripts', '--omit=dev'");
assert.ok(imagePull < staging && grokProvision < staging);
assert.ok(position("await awaited('image', imageReady)") < firstSandbox);
// The binary moves to the canonical host path only after npm is proven not to
// have provisioned it, after the negative probe, and before the positive probe.
const npmCheck = position("'npm must not provision Grok'");
const negativeProbe = position("isolated(['node', '/packages/probe.mjs', 'missing'])");
const grokJoin = position("await awaited('grok', grokReady)");
const move = position('renameSync(stagedGrok, prerequisite)');
const positiveProbe = position("isolated(['node', '/packages/probe.mjs', 'present'], { prerequisite })");
assert.ok(npmCheck < negativeProbe && negativeProbe < grokJoin && grokJoin < move && move < positiveProbe);
// The children run through the helper covered by prefetch-child.test.mjs, and
// cleanup waits for them before removing the directory they write into.
assert.ok(source.includes("import { startPrefetch, stopPrefetches } from './prefetch-child.mjs'"));
assert.ok(position('await stopPrefetches(prefetches)') < position('rmSync(root, { recursive: true, force: true })'));
assert.equal(linuxSource.match(/rmSync\(root/g).length, 1);
});
test('the bundled-dependency installs run together while the other packages are copied, and pack in order', () => {
const source = readFileSync(new URL('../verify-grok-npm-install.mjs', import.meta.url), 'utf8');
const position = fragment => { const index = source.indexOf(fragment); assert.notEqual(index, -1, `verifier must contain ${fragment}`); return index; };
// The installs are children of the script's own CLI entry through the helper
// covered by stage-bundled-packages.test.mjs, never in-process calls.
assert.doesNotMatch(source, /prepareBundledPackage/);
assert.ok(source.includes("import { bundledInstallTimings, startBundledInstalls } from './stage-bundled-packages.mjs'"));
// Only the bundled packages' sources are staged before the installs start;
// the installs are registered for cleanup at once, before anything else can
// fail; the other packages are copied while the installs run; the join comes
// before the packs start; and the packs run through the helper covered by
// pack-staged-packages.test.mjs, bundled packages first, each registered for
// cleanup as it starts, with the results put back into dependency order
// before every tarball is checked.
const bundledSources = position('for (const entry of entries.filter(entry => entry.bundled)) stageSource(entry)');
const start = position("startBundledInstalls(entries.filter(entry => entry.bundled), { logDir: prefetched, cwd: repo })");
const registered = position('prefetches.push(...installs.map(({ handle }) => handle))');
const otherSources = position('for (const entry of entries.filter(entry => !entry.bundled))');
const join = position("await awaited('bundled', Promise.all(installs.map(({ handle }) => handle.done)))");
assert.ok(source.includes("import { packConcurrency, packStagedPackages, packTimings } from './pack-staged-packages.mjs'"));
const packs = position("await packStagedPackages([...entries].sort((a, b) => Number(b.bundled) - Number(a.bundled)), { logDir: prefetched, env, concurrency, register: handle => prefetches.push(handle) })");
const reordered = position('packs.sort((a, b) => a.index - b.index)');
const checks = position("for (const tarball of tarballs) assertNoBundledCodexPayloads(run('tar', ['-tzf', tarball])");
const copied = position('for (const tarball of tarballs) {');
assert.ok(bundledSources < start && start < registered && registered < otherSources && otherSources < join && join < packs && packs < reordered && reordered < checks && checks < copied);
const packagingLane = source.slice(position("} else {\nassert.equal(process.platform, 'linux'"));
assert.equal(packagingLane.match(/run\('npm', \['pack'/g).length, 1, 'only the lifecycle sentinel is packed in-process in the packaging lane');
assert.ok(source.includes("destination: join(root, `pack-${index}`)"), 'each pack writes into its own directory');
// The timing line reports the split staging phase, each install, and the
// pack step with what the packs would have cost one after another.
for (const key of ['stage_ui_dist_ms', 'stage_sources_ms', 'stage_bundled_ms', 'stage_pack_ms', 'stage_pack_check_ms']) assert.ok(source.includes(`timing.${key} =`));
assert.ok(source.includes('...bundledInstallTimings(installs)'));
assert.ok(source.includes('Object.assign(timing, packTimings(packs, concurrency))'));
});
test('the verifier stages only workspace packages, so it skips the standalone build release.sh needs', () => {
const source = readFileSync(new URL('../verify-grok-npm-install.mjs', import.meta.url), 'utf8');
const position = fragment => { const index = source.indexOf(fragment); assert.notEqual(index, -1, `verifier must contain ${fragment}`); return index; };
// The standalone public packages are the ones outside the pnpm workspace
// (the sandbox-provider plugins). release.sh builds them because it publishes
// them; the verifier packs only the closure of the server and the CLI under
// `workspace:` specs, and a `workspace:` spec can only name a workspace
// package, so no tarball here ever contains or depends on a standalone build.
// The one reader of that build is qualification-package retention, which
// packs the Daytona plugin from its `dist`, so the build runs exactly when
// retention is requested: the single reference sits inside that gate, and
// the same flag is what later decides whether retention runs at all.
const standaloneBuild = "run(process.execPath, [join(repo, 'scripts/build-standalone-public-packages.mjs')], repo)";
assert.equal(source.split('build-standalone-public-packages').length - 1, 1, 'the standalone build is referenced once, inside the retention gate');
const gate = position("const retainQualificationPackages = Boolean(process.env.PAPERCLIP_RUNNER_QUALIFICATION_PACKAGES_DIR);\n if (retainQualificationPackages) {\n const standaloneStarted = performance.now();\n " + standaloneBuild);
assert.ok(source.includes('timing.stage_standalone_build_ms ='), 'the gated build is timed under its own key');
assert.ok(source.includes('if (retainQualificationPackages) {\n const retained = retainRunnerQualificationPackages({'), 'retention is gated by the same flag as the build');
assert.doesNotMatch(source, /if \(process\.env\.PAPERCLIP_RUNNER_QUALIFICATION_PACKAGES_DIR\)/, 'no second reading of the retention flag can diverge from the build gate');
const retention = readFileSync(new URL('../retain-runner-qualification-packages.mjs', import.meta.url), 'utf8');
assert.ok(retention.includes("const pluginRelative = 'packages/plugins/sandbox-providers/daytona';") && retention.includes("cpSync(join(repo, pluginRelative, 'dist'), join(plugin, 'dist'), { recursive: true })"), 'retention still packs the Daytona plugin from its dist, which is why the gated build exists');
const repo = new URL('../../', import.meta.url);
const listing = spawnSync(process.execPath, [fileURLToPath(new URL('scripts/release-package-map.mjs', repo)), 'list'], { cwd: fileURLToPath(repo), encoding: 'utf8' });
assert.equal(listing.status, 0, listing.stderr);
const packages = new Map(listing.stdout.trim().split('\n').map(line => line.split('\t')).map(([dir, name]) => [name, { dir, manifest: JSON.parse(readFileSync(new URL(`${dir}/package.json`, repo), 'utf8')) }]));
const needed = new Set();
const visit = name => {
if (needed.has(name)) return;
const entry = packages.get(name); assert.ok(entry, `missing public workspace dependency ${name}`); needed.add(name);
for (const [dep, spec] of Object.entries({ ...entry.manifest.dependencies, ...entry.manifest.optionalDependencies })) if (spec.startsWith('workspace:')) visit(dep);
};
assert.ok(source.includes("visit('@paperclipai/server');\n visit('paperclipai');"));
visit('@paperclipai/server'); visit('paperclipai');
const workspace = parseWorkspaceEntries(readFileSync(new URL('pnpm-workspace.yaml', repo), 'utf8'));
const standalone = [...packages.values()].filter(({ dir }) => !isWorkspacePackage(dir, workspace)).map(({ dir }) => dir);
assert.ok(standalone.length > 0, 'the public package map must still carry standalone packages for this check to mean anything');
assert.ok(standalone.includes('packages/plugins/sandbox-providers/daytona'), 'the Daytona plugin retention packs is a standalone package, so pnpm build alone cannot produce its dist');
for (const name of needed) assert.ok(isWorkspacePackage(packages.get(name).dir, workspace), `${name} is staged by the verifier but is not a workspace package`);
// The server publishes `ui-dist`, so that copy stays, before any package is
// staged, reusing the UI that `pnpm build` produced, and it is timed. The
// gated standalone build keeps release.sh's order: after the closure is
// known and before the UI copy and any staged source.
assert.deepEqual(JSON.parse(readFileSync(new URL('server/package.json', repo), 'utf8')).files, ['dist', 'ui-dist', 'skills']);
assert.ok(source.includes("PAPERCLIP_RELEASE_REUSE_UI_DIST: '1'"));
const uiDist = position("run('bash', [join(repo, 'scripts/prepare-server-ui-dist.sh')], repo)");
assert.ok(position("visit('paperclipai')") < gate && gate < uiDist && uiDist < position('timing.stage_ui_dist_ms =') && uiDist < position('const stageSource = '));
});
test('the installed Codex probe exercises the public export and rejects incomplete or mismatched packages', () => {
const root = realpathSync(mkdtempSync(join(tmpdir(), 'installed-codex-probe-')));
try {
const consumer = join(root, 'consumer'); mkdirSync(consumer);
const target = `${process.platform}-${process.arch}`;
const platformPath = `node_modules/@openai/codex-${target}`;
const platform = join(consumer, platformPath); mkdirSync(platform, { recursive: true });
const nativeVendor = join(platform, 'vendor'); mkdirSync(nativeVendor);
const triple = { 'linux-x64': 'x86_64-unknown-linux-musl', 'linux-arm64': 'aarch64-unknown-linux-musl',
'darwin-x64': 'x86_64-apple-darwin', 'darwin-arm64': 'aarch64-apple-darwin', 'win32-x64': 'x86_64-pc-windows-msvc', 'win32-arm64': 'aarch64-pc-windows-msvc' }[target];
const nativeBytes = Buffer.alloc(64);
if (process.platform === 'darwin') { nativeBytes.writeUInt32LE(0xfeedfacf); nativeBytes.writeUInt32LE(process.arch === 'arm64' ? 0x0100000c : 0x01000007, 4); }
else if (process.platform === 'win32') { nativeBytes.set([0x4d, 0x5a]); nativeBytes.writeUInt32LE(40, 60); nativeBytes.writeUInt32LE(0x00004550, 40); nativeBytes.writeUInt16LE(process.arch === 'arm64' ? 0xaa64 : 0x8664, 44); }
else { nativeBytes.set([0x7f, 0x45, 0x4c, 0x46, 2, 1]); nativeBytes.writeUInt16LE(process.arch === 'arm64' ? 183 : 62, 18); }
const nativeFile = join(nativeVendor, triple, 'bin', process.platform === 'win32' ? 'codex.exe' : 'codex');
mkdirSync(join(nativeVendor, triple, 'bin'), { recursive: true }); writeFileSync(nativeFile, nativeBytes, { mode: 0o755 });
const manifest = { name: '@openai/codex', version: `0.160.0-${target}`, os: [process.platform], cpu: [process.arch] };
writeFileSync(join(platform, 'package.json'), JSON.stringify(manifest));
const entry = { name: manifest.name, version: manifest.version,
resolved: `https://registry.npmjs.org/@openai/codex/-/codex-${manifest.version}.tgz`, integrity: `sha512-${Buffer.alloc(64, 1).toString('base64')}` };
const lock = { lockfileVersion: 3, packages: { [platformPath]: entry } };
writeFileSync(join(consumer, 'package-lock.json'), JSON.stringify(lock));
const server = join(consumer, 'node_modules/@paperclipai/server');
const vendor = join(server, 'dist/vendor/paperclip-runner'), drivers = join(vendor, 'drivers/acpx'); mkdirSync(drivers, { recursive: true });
mkdirSync(join(vendor, 'live'));
writeFileSync(join(vendor, 'live/runner-binary.js'), `export const runnerBinaryTarget = ${runnerBinaryTarget.toString()};`);
writeFileSync(join(server, 'package.json'), JSON.stringify({ name: '@paperclipai/server', type: 'module' }));
const integrity = join(drivers, 'installation-integrity.js');
const security = join(vendor, 'drivers/codex/codex-security-config.js'); mkdirSync(join(vendor, 'drivers/codex'));
const securitySource = `export const codexExecutableReadOnlyRoots = () => [${JSON.stringify(nativeVendor)}];
export const createIsolatedCodexAppServerArgs = (source, roots) => roots.map(root => JSON.stringify(root) + '=\"read\"');`;
writeFileSync(security, securitySource);
const moduleSource = `import assert from 'node:assert/strict'; import { writeFileSync } from 'node:fs';
export function createAcpxPackageJsonResolver(root, manifest) { assert.equal(root, ${JSON.stringify(server)}); assert.equal(manifest, root + '/package.json'); return () => 'selected-authority'; }
export async function verifyQualifiedAcpxInstallation(profile, resolver) { assert.deepEqual(profile, { agent: 'codex', model: 'gpt-5.4' }); assert.equal(resolver(), 'selected-authority');
return { openCommand: async () => ({ close: async () => { writeFileSync(${JSON.stringify(join(server, 'lease-closed'))}, 'ok'); } }) }; }`;
writeFileSync(integrity, moduleSource);
writeFileSync(join(drivers, 'qualified-profiles.js'), "export const resolveQualifiedAcpxProfile = (agent, model) => ({ agent, model });");
const wrapper = join(consumer, 'node_modules/@openai/codex/bin'); mkdirSync(wrapper, { recursive: true });
writeFileSync(join(wrapper, '../package.json'), JSON.stringify({ name: '@openai/codex', version: '0.160.0' }));
const index = join(vendor, 'index.mjs'), command = join(wrapper, 'codex.js'), probe = join(root, 'probe.mjs');
const executable = version => writeFileSync(command, `#!/bin/sh\n[ "$1" = --version ] || exit 65\nprintf '%s\\n' 'codex-cli ${version}'\n`, { mode: 0o755 });
writeFileSync(probe, installedCodexProbeSource(index, consumer, '0.160.0'));
const run = () => spawnSync(process.execPath, [probe], { encoding: 'utf8', timeout: 10_000, env: { PATH: '/usr/bin:/bin', NODE_PATH: '' } });
writeFileSync(index, `export const resolvePinnedCodexCommand = () => ${JSON.stringify(command)};`);
executable('0.160.0');
let result = run(); assert.equal(result.status, 0, result.stderr);
assert.equal(JSON.parse(result.stdout).pinnedCodexCommandVerified, true);
assert.equal(JSON.parse(result.stdout).codexPlatformPackageSource, 'official npm');
assert.equal(JSON.parse(result.stdout).codexConsumerPlatform, target);
assert.equal(JSON.parse(result.stdout).codexCommandSha256, createHash('sha256').update(readFileSync(command)).digest('hex'));
assert.equal(JSON.parse(result.stdout).codexNativeExecutableSha256, createHash('sha256').update(nativeBytes).digest('hex'));
const original = JSON.parse(result.stdout);
nativeBytes[63] = 1; writeFileSync(nativeFile, nativeBytes);
result = run(); assert.equal(result.status, 0, result.stderr);
const changed = JSON.parse(result.stdout);
assert.equal(changed.codexCommandSha256, original.codexCommandSha256, 'native mutation does not change the npm launcher');
assert.notEqual(changed.codexNativeExecutableSha256, original.codexNativeExecutableSha256);
assert.throws(() => assertInstalledNativeConsumerContinuity({ lockSha256: 'a'.repeat(64), runnerSha256: 'b'.repeat(64), ...original },
{ lockSha256: 'a'.repeat(64), runnerSha256: 'b'.repeat(64), ...changed }), /codexNativeExecutableSha256/);
nativeBytes[63] = 0; writeFileSync(nativeFile, nativeBytes);
rmSync(nativeFile);
result = run(); assert.notEqual(result.status, 0); assert.match(result.stderr, /one native executable/);
const foreignNative = join(root, 'foreign-codex'); writeFileSync(foreignNative, nativeBytes, { mode: 0o755 });
symlinkSync(foreignNative, nativeFile);
result = run(); assert.notEqual(result.status, 0); assert.match(result.stderr, /bounded regular file in its selected platform package/);
rmSync(nativeFile); writeFileSync(nativeFile, nativeBytes, { mode: 0o755 });
result = run(); assert.equal(result.status, 0, result.stderr);
assert.equal(JSON.parse(result.stdout).codexQualifiedInstallationVerified, true);
assert.equal(JSON.parse(result.stdout).codexCommandLeaseVerified, true);
assert.equal(JSON.parse(result.stdout).codexNativeSandboxResourcesVerified, true);
assert.equal(readFileSync(join(server, 'lease-closed'), 'utf8'), 'ok');
assert.equal(JSON.parse(result.stdout).providerCalls, 0);
const legacyPath = 'node_modules/legacy-codex-adapter/node_modules/@openai/codex-' + target;
const legacy = join(consumer, legacyPath); mkdirSync(legacy, { recursive: true });
const legacyManifest = { ...manifest, version: '0.156.1-' + target };
writeFileSync(join(legacy, 'package.json'), JSON.stringify(legacyManifest));
lock.packages[legacyPath] = { ...entry, version: legacyManifest.version,
resolved: 'https://registry.npmjs.org/@openai/codex/-/codex-' + legacyManifest.version + '.tgz' };
writeFileSync(join(consumer, 'package-lock.json'), JSON.stringify(lock));
result = run(); assert.equal(result.status, 0, result.stderr);
assert.equal(JSON.parse(result.stdout).codexPlatformPackages.length, 2);
assert.equal(JSON.parse(result.stdout).codexSelectedPlatformPath, platformPath);
assert.equal(JSON.parse(result.stdout).codexSelectedPlatformVersion, '0.160.0-' + target);
const legacyCommand = join(legacy, 'codex');
writeFileSync(legacyCommand, '#!/bin/sh\nexit 0\n', { mode: 0o755 });
writeFileSync(index, `export const resolvePinnedCodexCommand = () => ${JSON.stringify(legacyCommand)};`);
result = run(); assert.notEqual(result.status, 0); assert.match(result.stderr, /Selected Codex platform version must match the qualified pin/);
// Native Codex uses protocol compatibility, not the ACPX version allowlist.
// Keep exact official-npm host provenance and the selected resource boundary.
mkdirSync(join(legacy, 'vendor'));
const legacyNative = join(legacy, 'vendor', triple, 'codex', process.platform === 'win32' ? 'codex.exe' : 'codex');
mkdirSync(join(legacy, 'vendor', triple, 'codex'), { recursive: true }); writeFileSync(legacyNative, nativeBytes, { mode: 0o755 });
writeFileSync(legacyCommand, '#!/bin/sh\nprintf "codex-cli 0.156.1\\n"\n', { mode: 0o755 });
writeFileSync(security, securitySource.replaceAll(JSON.stringify(nativeVendor), JSON.stringify(join(legacy, 'vendor'))));
writeFileSync(probe, installedCodexProbeSource(index, consumer, undefined, { nativeCodex: true }));
result = run(); assert.equal(result.status, 0, result.stderr);
assert.equal(JSON.parse(result.stdout).installedCodexVersion, 'codex-cli 0.156.1');
assert.equal(JSON.parse(result.stdout).codexQualifiedInstallationVerified, undefined);
writeFileSync(probe, installedCodexProbeSource(index, consumer, '0.160.0'));
writeFileSync(security, securitySource);
writeFileSync(index, `import { writeFileSync } from 'node:fs'; export const resolvePinnedCodexCommand = () => {
writeFileSync(${JSON.stringify(join(platform, 'package.json'))}, ${JSON.stringify(JSON.stringify({ ...manifest, altered: true }))});
return ${JSON.stringify(command)}; };`);
result = run(); assert.notEqual(result.status, 0); assert.match(result.stderr, /metadata must match its scanned provenance/);
writeFileSync(join(platform, 'package.json'), JSON.stringify(manifest));
writeFileSync(index, "export const resolvePinnedCodexCommand = () => { throw new Error('Bundled Codex runtime version mismatch'); };");
result = run(); assert.notEqual(result.status, 0); assert.match(result.stderr, /Bundled Codex runtime version mismatch/);
writeFileSync(index, `export const resolvePinnedCodexCommand = () => ${JSON.stringify(command)};`);
writeFileSync(security, securitySource.replace(JSON.stringify(nativeVendor), '"/missing-vendor-root"'));
result = run(); assert.notEqual(result.status, 0); assert.match(result.stderr, /vendor directory must be readable/);
writeFileSync(security, securitySource.replace(JSON.stringify(nativeVendor), `${JSON.stringify(nativeVendor)}, ${JSON.stringify(consumer)}`));
result = run(); assert.notEqual(result.status, 0); assert.match(result.stderr, /must not grant enclosing npm/);
writeFileSync(security, securitySource.replace("'=\"read\"'", "'=\"write\"'"));
result = run(); assert.notEqual(result.status, 0); assert.match(result.stderr, /retain the selected native executable resources/);
writeFileSync(security, securitySource);
const emptySlot = join(server, 'node_modules/@openai/codex-' + target);
mkdirSync(emptySlot, { recursive: true });
result = run(); assert.equal(result.status, 0, result.stderr);
assert.equal(JSON.parse(result.stdout).codexPlatformPackages.length, 2,
'An empty nested npm optional slot must not obscure the qualified hoisted host package');
writeFileSync(join(emptySlot, 'undeclared-native-payload'), 'native fixture; never executed');
result = run(); assert.notEqual(result.status, 0); assert.match(result.stderr, /empty regular directory; found.*undeclared-native-payload/);
rmSync(join(emptySlot, 'undeclared-native-payload'));
writeFileSync(join(emptySlot, 'package.json'), '{ malformed');
result = run(); assert.notEqual(result.status, 0); assert.match(result.stderr, /SyntaxError/);
rmSync(join(emptySlot, 'package.json'));
writeFileSync(integrity, moduleSource.replace('assert.deepEqual(profile,', "throw new Error('qualified executable digest mismatch'); assert.deepEqual(profile,"));
result = run(); assert.notEqual(result.status, 0); assert.match(result.stderr, /qualified executable digest mismatch/);
writeFileSync(integrity, moduleSource.replace("writeFileSync(", "throw new Error('command lease close failed'); writeFileSync("));
result = run(); assert.notEqual(result.status, 0); assert.match(result.stderr, /command lease close failed/);
writeFileSync(integrity, moduleSource);
lock.packages[platformPath].inBundle = true;
writeFileSync(join(consumer, 'package-lock.json'), JSON.stringify(lock));
result = run(); assert.notEqual(result.status, 0); assert.match(result.stderr, /downloaded, not bundled/);
delete lock.packages[platformPath].inBundle;
writeFileSync(join(consumer, 'package-lock.json'), JSON.stringify(lock));
const foreign = join(consumer, 'node_modules/@openai/codex-win32-arm64'); mkdirSync(foreign);
writeFileSync(join(foreign, 'package.json'), JSON.stringify({ name: '@openai/codex', version: '0.160.0-win32-arm64' }));
result = run(); assert.notEqual(result.status, 0); assert.match(result.stderr, /only the host/);
rmSync(foreign, { recursive: true });
executable('9.9.9'); result = run(); assert.notEqual(result.status, 0); assert.match(result.stderr, /qualified pin/);
rmSync(command); result = run(); assert.notEqual(result.status, 0); assert.match(result.stderr, /ENOENT/);
const outside = join(root, 'outside'); writeFileSync(outside, '#!/bin/sh\nexit 0\n', { mode: 0o755 });
writeFileSync(index, `export const resolvePinnedCodexCommand = () => ${JSON.stringify(outside)};`);
result = run(); assert.notEqual(result.status, 0); assert.match(result.stderr, /inside the installed consumer/);
writeFileSync(index, 'export const unrelated = true;'); result = run(); assert.notEqual(result.status, 0); assert.match(result.stderr, /must export the pinned Codex resolver/);
} finally { rmSync(root, { recursive: true, force: true }); }
});
test('actual tar member checks allow Codex JavaScript but reject nested platform packages and native vendor payloads', () => {
const javascript = ['package/package.json', 'package/node_modules/@openai/codex/package.json',
'package/node_modules/@openai/codex/bin/codex.js', 'package/dist/vendor/paperclip-runner/index.js'];
assert.doesNotThrow(() => assertNoBundledCodexPayloads(javascript));
for (const payload of [
'package/node_modules/@openai/codex-linux-x64/package.json',
'package/node_modules/@openai/codex-linux-arm64/package.json',
'package/node_modules/bridge/node_modules/@openai/codex-darwin-arm64/package.json',
'package/node_modules/@openai/codex-win32-x64/package.json',
'package/node_modules/@openai/codex/vendor/x86_64-unknown-linux-musl/codex/codex',
'package/dist/vendor/aarch64-apple-darwin/bin/codex',
'package/dist/vendor/x86_64-pc-windows-msvc/bin/codex.exe',
]) assert.throws(() => assertNoBundledCodexPayloads([...javascript, payload]), /must not bundle/);
assert.throws(() => assertNoBundledCodexPayloads(['package/../outside']), /inside the package/);
const source = readFileSync(new URL('../verify-grok-npm-install.mjs', import.meta.url), 'utf8');
assert.match(source, /assertNoBundledCodexPayloads\(run\('tar', \['-tzf', tarball\]\)/);
});
test('consumer provenance rejects bundled, foreign, inconsistent and non-official Codex payloads', () => {
for (const target of ['linux-x64', 'linux-arm64']) {
const path = `node_modules/@openai/codex-${target}`;
const manifest = { name: '@openai/codex', version: `0.160.0-${target}`, os: ['linux'], cpu: [target.slice('linux-'.length)] };
const entry = { version: manifest.version, resolved: `https://registry.npmjs.org/@openai/codex/-/codex-${manifest.version}.tgz`,
integrity: `sha512-${Buffer.alloc(64, 1).toString('base64')}` };
const check = (value = entry, installed = [{ path, manifest }]) => assertInstalledCodexPlatformProvenance({ packages: { [path]: value } }, installed, target);
assert.equal(check().codexConsumerHostOnly, true);
const legacyManifest = { ...manifest, version: `0.156.1-${target}` };
assert.equal(check({ ...entry, version: legacyManifest.version,
resolved: `https://registry.npmjs.org/@openai/codex/-/codex-0.156.1-${target}.tgz` }, [{ path, manifest: legacyManifest }]).codexConsumerHostOnly, true);
assert.throws(() => check(entry, [{ path, manifest: { ...manifest, version: `^0.160.0-${target}` } }]), /exact host version/);
for (const change of [
{ inBundle: true }, { link: true }, { version: `0.156.1-${target}` },
{ resolved: `https://example.com/@openai/codex/-/codex-0.160.0-${target}.tgz` },
{ resolved: `https://registry.npmjs.org/@openai/codex/-/codex-0.156.1-${target}.tgz` },
{ resolved: `https://user@registry.npmjs.org/@openai/codex/-/codex-0.160.0-${target}.tgz` },
{ integrity: undefined }, { integrity: 'sha512-AA==' },
]) assert.throws(() => check({ ...entry, ...change }));
assert.throws(() => check(entry, []), /must install its host/);
assert.throws(() => check(entry, [{ path: 'node_modules/@openai/codex-darwin-arm64', manifest }]), /only the host/);
assert.throws(() => check(entry, [{ path, manifest: { ...manifest, name: 'untrusted' } }]), /identity/);
}
});
test('hosted Mac lifecycle denies OS networking and writes outside owned scratch', () => {
const profile = macPublicInstallLifecycleProfile('/Users/runner/work/_temp/owned-check');
assert.match(profile, /\(deny network\*\)/);
assert.match(profile, /\(deny file-write\*/);
assert.match(profile, /subpath "\/Users\/runner\/work\/_temp\/owned-check"/);
assert.throws(() => macPublicInstallLifecycleProfile('relative'), /absolute/);
assert.throws(() => macPublicInstallLifecycleProfile('/tmp/owned\0bad'), /absolute/);
const source = readFileSync(new URL('../verify-grok-npm-install.mjs', import.meta.url), 'utf8');
assert.match(source, /process.env.GITHUB_ACTIONS, 'true'/);
assert.match(source, /networkProbe, 'allowed'/);
assert.match(source, /networkProbe, 'denied'/);
assert.match(source, /error.code,'EPERM'/);
assert.match(source, /'rebuild', '--offline', '--ignore-scripts=false', '--dangerously-allow-all-scripts'/);
assert.match(source, /readFileSync\(sentinel, 'utf8'\), 'ok'/);
assert.match(source, /readFileSync\(join\(consumer, 'package-lock.json'\), 'utf8'\), lock/);
assert.match(source, /finally \{ rmSync\(root, \{ recursive: true, force: true \}\); \}/);
});
test('installed daemon proof uses the production host resolver and complete source-bound manifest', () => {
const source = installedDaemonProbeSource('/consumer/server/dist/vendor/paperclip-runner', '/consumer', 'a'.repeat(40));
assert.match(source, /defaultCapabilityRunnerdBinary\(\)/);
assert.match(source, /Object.keys\(manifest.platforms\).sort\(\), targets.sort\(\)/);
assert.match(source, /manifest.sourceRevision, "a{40}"/);
assert.match(source, /runnerBinaryTarget\(bytes\), target/);
assert.match(source, /createHash\('sha256'\)/);
assert.match(source, /metadata.binaryContractVersion, expected.contracts.runnerdArtifact/);
assert.match(source, /'linux-arm64'/);
assert.doesNotMatch(source, /PAPERCLIP_RUNNERD_BINARY|runner\/target\/debug|execFileSync\('paperclip-runnerd'/);
});
test('native ARM clean consumers keep the existing container and installed-runtime boundaries', () => {
const args = grokConsumerDockerArgs({ ...paths, platform: 'linux/arm64', command: GROK_PUBLIC_INSTALL_LIFECYCLE });
assert.deepEqual(values(args, '--platform'), ['linux/arm64']);
assert.deepEqual(values(args, '--network'), ['none']);
assert.deepEqual(values(args, '--user'), ['1001:1001']);
assert.ok(args.includes('--read-only'));
assert.deepEqual(values(args, '--cap-drop'), ['ALL']);
assert.deepEqual(values(args, '--security-opt'), ['no-new-privileges']);
assert.ok(values(args, '--mount').some(value => value.endsWith('dst=/packages,readonly')));
assert.throws(() => grokConsumerDockerArgs({ ...paths, platform: 'linux/arm/v7', command: [] }), /supported native Linux platform/);
const source = readFileSync(new URL('../verify-grok-npm-install.mjs', import.meta.url), 'utf8');
const arm = source.split('async function verifyLinuxArmConsumer(')[1].split("if (process.argv[2] === '--linux-arm64-consumer')")[0];
assert.match(arm, /process.platform \+ '-' \+ process.arch, 'linux-arm64'/);
assert.match(arm, /const platform = 'linux\/arm64'/);
assert.match(arm, /isolated\(GROK_PUBLIC_INSTALL_LIFECYCLE\)/);
assert.match(arm, /installedCodexProbeSource\(installed \+ '\/index.js', '\/consumer', undefined, \{ nativeCodex: true \}\)/);
assert.match(arm, /tests\/runner-e2e\/installed-cli.ts/);
assert.match(arm, /process.versions.node.split\('\.'\)\[0\], '24'/);
assert.match(arm, /macInstalledStartupProbeSource\(consumer, hostServer, daemon.sha256, join\(assets, 'installed-cli.ts'\)\)/);
assert.match(arm, /startupEnvironment: 'native host, same installed graph, isolated empty homes'/);
assert.doesNotMatch(arm, /stage-runner|runner\/target|PAPERCLIP_RUNNER_BINARY|prerequisite:/);
});
test('Mac startup wiring normalizes only validated manifest digests and uses server-scoped tooling', () => {
const source = macInstalledStartupProbeSource('/owned/consumer', '/owned/consumer/server', 'sha256:' + 'a'.repeat(64), '/source/tests/runner-e2e/installed-cli.ts');
assert.match(source, /expectedRunnerSha256:"a{64}"/);
assert.doesNotMatch(source, /expectedRunnerSha256:"sha256:/);
for (const digest of ['a'.repeat(64), 'sha256:bad', 'sha512:' + 'a'.repeat(64), 'sha256:' + 'A'.repeat(64)]) {
assert.throws(() => macInstalledStartupProbeSource('/owned/consumer', '/owned/consumer/server', digest, '/source/helper.ts'), /verified SHA-256/);
}
const verifier = readFileSync(new URL('../verify-grok-npm-install.mjs', import.meta.url), 'utf8');
assert.match(verifier, /\['--import', 'tsx', startupFile\], join\(repo, 'server'\)/);
const closedEnvironment = verifier.match(/const env = \{ PATH: `\$\{tools\}[\s\S]*?\};/)[0];
assert.doesNotMatch(closedEnvironment, /NODE_PATH|NODE_OPTIONS|\.\.\.process.env/);
});
test('Pi admission verifies assembled host daemon identity and preserves the flat source-package control', async () => {
const root = realpathSync(mkdtempSync(join(tmpdir(), 'pi-installed-daemon-'))), server = join(root, 'server');
const output = join(server, 'dist/vendor/paperclip-runner'), target = 'linux-x64', source = 'a'.repeat(40);
const binary = join(output, 'bin', target, 'paperclip-runnerd'), manifestPath = join(output, 'bin/release-manifest.json');
const bytes = Buffer.alloc(64); bytes.set([0x7f, 0x45, 0x4c, 0x46, 2, 1]); bytes.writeUInt16LE(62, 18);
const sha256 = value => `sha256:${createHash('sha256').update(value).digest('hex')}`;
const manifest = { schema: 'paperclip.runner.release-binaries.v1', sourceRevision: source,
platforms: { [target]: { path: `${target}/paperclip-runnerd`, sha256: sha256(bytes) } } };
const check = () => verifyPiPackagedDaemon(server, binary, target, runnerBinaryTarget);
try {
mkdirSync(join(output, 'bin', target), { recursive: true });
writeFileSync(binary, bytes); writeFileSync(join(server, 'dist/build-info.json'), JSON.stringify({ commit: source }));
writeFileSync(manifestPath, JSON.stringify(manifest));
await check();
for (const changed of [null, { ...manifest, schema: 'untrusted' }, { ...manifest, sourceRevision: 'b'.repeat(40) },
{ ...manifest, platforms: { [target]: { ...manifest.platforms[target], path: '../outside' } } },
{ ...manifest, platforms: { [target]: { ...manifest.platforms[target], sha256: 'sha256:' + '0'.repeat(64) } } }]) {
writeFileSync(manifestPath, JSON.stringify(changed)); await assert.rejects(check());
}
const wrongHeader = Buffer.from(bytes); wrongHeader.writeUInt16LE(183, 18);
writeFileSync(binary, wrongHeader);
writeFileSync(manifestPath, JSON.stringify({ ...manifest, platforms: { [target]: { ...manifest.platforms[target], sha256: sha256(wrongHeader) } } }));
await assert.rejects(check(), /linux-arm64/);
writeFileSync(binary, bytes); writeFileSync(manifestPath, JSON.stringify(manifest));
const outside = join(root, 'outside'); writeFileSync(outside, bytes);
rmSync(binary); symlinkSync(outside, binary); await assert.rejects(check());
rmSync(binary); writeFileSync(binary, bytes); rmSync(manifestPath);
const flat = join(output, 'bin/paperclip-runnerd'); writeFileSync(flat, bytes);
await verifyPiPackagedDaemon(server, flat, target, runnerBinaryTarget);
await assert.rejects(check(), /strictly equal/);
writeFileSync(manifestPath, 'null');
await assert.rejects(verifyPiPackagedDaemon(server, flat, target, runnerBinaryTarget), /manifest must be an object/);
} finally { rmSync(root, { recursive: true, force: true }); }
});