fix: preserve imported runner choices and qualify Mac install fixtures

Forward explicit import runner overrides, preserve native harness identity without experimental Codex gating, refresh existing host daemon outputs atomically, and retain strict public install probes with target paths and the executing Node SDK.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-10-12 08:55:54 -05:00
1 parent dc7304d7c4
commit d522822a5d
9 files changed
+446 -57

No files matched your search

@@ -1,16 +1,46 @@
import assert from 'node:assert/strict';
import { mkdirSync, mkdtempSync, readFileSync, realpathSync, rmSync, writeFileSync } from 'node:fs';
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, assertNoBundledCodexPayloads, grokConsumerDockerArgs, installedCodexProbeSource, installedDaemonProbeSource, macPublicInstallLifecycleProfile, macInstalledStartupProbeSource } from '../grok-public-install-sandbox.mjs';
import { GROK_PUBLIC_INSTALL_IMAGE, GROK_PUBLIC_INSTALL_LIFECYCLE, assertInstalledCodexPlatformProvenance, 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('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']);
@@ -399,3 +429,38 @@ test('Mac startup wiring normalizes only validated manifest digests and uses ser
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 }); }
});
+27
View File
@@ -1,4 +1,6 @@
import assert from 'node:assert/strict';
import { readFileSync, realpathSync, statSync } from 'node:fs';
import { basename, dirname, join } from 'node:path';
// Keep public-package lifecycle code off the verification host. Resolve and
// cache the public npm graph without scripts, then execute it offline.
@@ -9,6 +11,31 @@ export const GROK_PUBLIC_INSTALL_LIFECYCLE = [
'npm', 'rebuild', '--offline', '--ignore-scripts=false', '--dangerously-allow-all-scripts',
];
// setup-node provides its matching SDK alongside the executing Node binary.
// Deferred lifecycle scripts may read that SDK, but may never download headers.
export function macNodeHeadersDirectory(nodeExecutable, nodeVersion) {
assert.match(nodeVersion, /^\d+\.\d+\.\d+$/, 'Executing Node must have an exact release version');
const executable = realpathSync(nodeExecutable);
assert.equal(basename(executable), 'node', 'Node SDK must belong to the executing Node binary');
assert.ok(statSync(executable).isFile(), 'Executing Node must be a regular file');
const prefix = realpathSync(join(dirname(executable), '..'));
const include = join(prefix, 'include/node');
for (const name of ['node.h', 'node_version.h']) {
const header = join(include, name);
assert.equal(realpathSync(header), header, 'Node SDK headers must remain inside the executing Node prefix');
assert.ok(statSync(header).isFile(), 'Node SDK headers must be regular files');
}
assert.match(readFileSync(join(include, 'node.h'), 'utf8'), /#\s*include\s+"node_version\.h"/, 'Node SDK must include its version header');
const versionHeader = readFileSync(join(include, 'node_version.h'), 'utf8');
const versions = ['MAJOR', 'MINOR', 'PATCH'].map(part => {
const matches = [...versionHeader.matchAll(new RegExp('^#\\s*define\\s+NODE_' + part + '_VERSION\\s+(\\d+)\\s*$', 'gm'))];
assert.equal(matches.length, 1, 'Node SDK must declare one ' + part.toLowerCase() + ' version');
return matches[0][1];
});
assert.equal(versions.join('.'), nodeVersion, 'Node SDK version must match the executing Node');
return prefix;
}
// Inspect the actual npm archive, independently of the staging helper.
export function assertNoBundledCodexPayloads(entries) {
assert.ok(Array.isArray(entries) && entries.length > 0, 'Packed package must have tar members');
+40 -3
View File
@@ -2,10 +2,44 @@
// Run in a credential-free public npm consumer after `paperclipai runtime setup pi`.
// Use the server's normal packaged daemon resolver; never submit a prompt.
import assert from 'node:assert/strict';
import { createHash } from 'node:crypto';
import { mkdir, mkdtemp, readFile, realpath, rm } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { pathToFileURL } from 'node:url';
import { join, resolve } from 'node:path';
import { fileURLToPath, pathToFileURL } from 'node:url';
export async function verifyPiPackagedDaemon(server, daemon, target, runnerBinaryTarget) {
assert.match(target, /^(?:linux|darwin)-(?:x64|arm64)$/);
const output = join(server, 'dist/vendor/paperclip-runner'), manifestPath = join(output, 'bin/release-manifest.json');
let manifest;
try { manifest = JSON.parse(await readFile(manifestPath, 'utf8')); }
catch (error) { if (error.code !== 'ENOENT') throw error; }
let expectedPath = join(output, 'bin/paperclip-runnerd');
if (manifest !== undefined) {
assert.ok(manifest && typeof manifest === 'object' && !Array.isArray(manifest), 'Release manifest must be an object');
assert.equal(await realpath(manifestPath), manifestPath, 'Release manifest must remain inside the installed package');
assert.equal(manifest.schema, 'paperclip.runner.release-binaries.v1');
assert.match(manifest.sourceRevision, /^[a-f0-9]{40}$/);
const build = JSON.parse(await readFile(join(server, 'dist/build-info.json'), 'utf8'));
assert.equal(manifest.sourceRevision, build.commit, 'Packaged daemon source must match the installed server build');
const artifact = manifest.platforms?.[target];
assert.equal(artifact?.path, `${target}/paperclip-runnerd`, 'Packaged daemon must use the known host target path');
assert.match(artifact.sha256, /^sha256:[a-f0-9]{64}$/);
expectedPath = join(output, 'bin', artifact.path);
assert.equal(await realpath(daemon), expectedPath, 'Production must select the installed host daemon');
assert.equal(await realpath(expectedPath), expectedPath, 'Packaged daemon cannot escape through a symlink');
const bytes = await readFile(expectedPath);
assert.equal(`sha256:${createHash('sha256').update(bytes).digest('hex')}`, artifact.sha256);
assert.equal(runnerBinaryTarget(bytes), target);
} else {
// Existing host-only source packages have no multi-target release manifest.
// They must still use their exact normal flat daemon, never an override.
assert.equal(await realpath(daemon), expectedPath);
assert.equal(runnerBinaryTarget(await readFile(expectedPath)), target);
}
}
async function main() {
const [serverDirectory, ...extra] = process.argv.slice(2);
assert.ok(serverDirectory && extra.length === 0, 'Usage: pi-public-install-probe.mjs INSTALLED_SERVER_ROOT');
@@ -25,7 +59,8 @@ assert.equal(QUALIFIED_ACPX_PROFILES.pi.commandDigest, 'sha256:e92078bee3c23bec4
assert.equal(Object.hasOwn(QUALIFIED_ACPX_PROFILES.pi, 'qualificationModel'), false);
assert.equal(Object.hasOwn(QUALIFIED_ACPX_PROFILES.pi, 'reportedModelId'), false);
const daemon = resolvePaperclipRunnerBinary();
assert.equal(await realpath(daemon), join(server, 'dist/vendor/paperclip-runner/bin/paperclip-runnerd'));
const { runnerBinaryTarget } = await import(pathToFileURL(join(server, 'dist/vendor/paperclip-runner/live/runner-binary.js')));
await verifyPiPackagedDaemon(server, daemon, `${process.platform}-${process.arch}`, runnerBinaryTarget);
const root = await mkdtemp(join(tmpdir(), 'pi-public-install-probe-'));
const evidence = [];
const started = performance.now();
@@ -69,3 +104,5 @@ try {
try { await bundle?.transport.close(); }
finally { clearTimeout(watchdog); await rm(root, { recursive: true, force: true }); }
}
}
if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) await main();
+7 -4
View File
@@ -12,7 +12,7 @@ import { basename, dirname, join, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
import { packConcurrency, packStagedPackages, packTimings } from './pack-staged-packages.mjs';
import { materializePublishManifest } from './prepare-bundled-package.mjs';
import { GROK_PUBLIC_INSTALL_IMAGE, GROK_PUBLIC_INSTALL_LIFECYCLE, assertNoBundledCodexPayloads, grokConsumerDockerArgs, installedCodexProbeSource, installedDaemonProbeSource, macPublicInstallLifecycleProfile, macInstalledStartupProbeSource } from './grok-public-install-sandbox.mjs';
import { GROK_PUBLIC_INSTALL_IMAGE, GROK_PUBLIC_INSTALL_LIFECYCLE, assertNoBundledCodexPayloads, grokConsumerDockerArgs, installedCodexProbeSource, installedDaemonProbeSource, macNodeHeadersDirectory, macPublicInstallLifecycleProfile, macInstalledStartupProbeSource } from './grok-public-install-sandbox.mjs';
import { startPrefetch, stopPrefetches } from './prefetch-child.mjs';
import { retainRunnerQualificationPackages } from './retain-runner-qualification-packages.mjs';
import { bundledInstallTimings, startBundledInstalls } from './stage-bundled-packages.mjs';
@@ -39,7 +39,7 @@ async function verifyMacConsumer(packageDirectory, sourceRevision, receiptPath)
// command can hide missing installed dependencies.
const env = { PATH: `${tools}:/usr/bin:/bin:/usr/sbin:/sbin`, HOME: home, TMPDIR: join(root, 'tmp'),
npm_config_cache: join(root, 'cache'), npm_config_audit: 'false', npm_config_fund: 'false' };
const run = (command, args, cwd = consumer) => execFileSync(command, args, { cwd, env,
const run = (command, args, cwd = consumer, runEnv = env) => execFileSync(command, args, { cwd, env: runEnv,
timeout: 10 * 60_000, maxBuffer: 32 * 1024 * 1024, encoding: 'utf8' });
const tarballs = manifest.archives.map(entry => {
assert.match(entry.file, /^[A-Za-z0-9._-]+\.tgz$/); assert.match(entry.sha256, /^[a-f0-9]{64}$/);
@@ -71,7 +71,9 @@ async function verifyMacConsumer(packageDirectory, sourceRevision, receiptPath)
run(process.execPath, ['--input-type=module', '-e', networkProbe, 'allowed']);
run('/usr/bin/sandbox-exec', ['-f', profile, process.execPath, '--input-type=module', '-e', networkProbe, 'denied']);
} finally { await new Promise(resolve => listener.close(resolve)); }
run('/usr/bin/sandbox-exec', ['-f', profile, process.execPath, npmCli, 'rebuild', '--offline', '--ignore-scripts=false', '--dangerously-allow-all-scripts', '--foreground-scripts']);
const nodeHeaders = macNodeHeadersDirectory(process.execPath, process.versions.node);
run('/usr/bin/sandbox-exec', ['-f', profile, process.execPath, npmCli, 'rebuild', '--offline', '--ignore-scripts=false', '--dangerously-allow-all-scripts', '--foreground-scripts'],
consumer, { ...env, npm_config_nodedir: nodeHeaders });
assert.equal(readFileSync(sentinel, 'utf8'), 'ok');
assert.equal(readFileSync(join(consumer, 'package-lock.json'), 'utf8'), lock);
for (const entry of manifest.archives) {
@@ -86,7 +88,8 @@ async function verifyMacConsumer(packageDirectory, sourceRevision, receiptPath)
const startup = JSON.parse(run(process.execPath, ['--import', 'tsx', startupFile], join(repo, 'server')).trim());
const receipt = { schema: 'paperclip.runner.mac-public-install.v1', sourceRevision, platform: process.platform, architecture: process.arch,
cleanNpmInstall: true, packageCount: manifest.archives.length, codexPackedPayloadsOmitted: true,
consumerLockPreserved: true, lifecycleSentinelVerified: true, lifecycleNetwork: 'sandbox-exec denied (loopback negative control)',
consumerLockPreserved: true, lifecycleSentinelVerified: true, lifecycleNodeHeadersVerified: true, lifecycleNodeVersion: process.versions.node,
lifecycleNetwork: 'sandbox-exec denied (loopback negative control)',
...daemon, ...codex, startup, providerCalls: 0 };
writeFileSync(receiptPath, JSON.stringify(receipt, null, 2) + '\n');
console.log(JSON.stringify(receipt));