mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-20 15:09:57 +02:00
test(cursor): verify public install and provider-loss settlement
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
37ba674378
commit
f67dcc56fd
6 files changed
+25
-11
No files matched your search
@@ -7,17 +7,18 @@ export const GROK_PUBLIC_INSTALL_LIFECYCLE = [
|
||||
'npm', 'rebuild', '--offline', '--ignore-scripts=false', '--dangerously-allow-all-scripts',
|
||||
];
|
||||
|
||||
export function grokConsumerDockerArgs({ assets, consumer, cache, command, uid, gid, download = false, prerequisite }) {
|
||||
export function grokConsumerDockerArgs({ assets, consumer, cache, command, uid, gid, download = false, prerequisite, temporarySizeMb = 256 }) {
|
||||
if (!Number.isSafeInteger(uid) || uid <= 0 || !Number.isSafeInteger(gid) || gid <= 0) {
|
||||
throw new Error('Public-install verification requires an unprivileged host user');
|
||||
}
|
||||
if (!Number.isSafeInteger(temporarySizeMb) || temporarySizeMb < 256 || temporarySizeMb > 2048) throw new Error('Invalid bounded public-install temporary size');
|
||||
return [
|
||||
'run', '--rm', '--platform', 'linux/amd64',
|
||||
'--user', `${uid}:${gid}`, '--read-only',
|
||||
'--cap-drop', 'ALL', '--security-opt', 'no-new-privileges',
|
||||
'--pids-limit', '256', '--memory', '3g',
|
||||
'--network', download ? 'bridge' : 'none',
|
||||
'--tmpfs', '/tmp:rw,nosuid,nodev,size=256m,mode=1777',
|
||||
'--tmpfs', `/tmp:rw,nosuid,nodev,size=${temporarySizeMb}m,mode=1777`,
|
||||
'--env', 'HOME=/tmp', '--env', 'npm_config_cache=/cache',
|
||||
'--env', 'npm_config_nodedir=/usr/local',
|
||||
'--env', 'npm_config_audit=false', '--env', 'npm_config_fund=false',
|
||||
|
||||
@@ -56,7 +56,8 @@ const sentinelSource = join(root,'lifecycle-sentinel'); mkdirSync(sentinelSource
|
||||
writeFileSync(join(sentinelSource,'package.json'), JSON.stringify({name:'paperclip-verification-lifecycle-sentinel',version:'1.0.0',private:true,scripts:{postinstall:'node -e "require(\'node:fs\').writeFileSync(\'lifecycle-ran\', \'ok\')"'}}));
|
||||
run('npm',['pack','--ignore-scripts','--pack-destination',assets],sentinelSource);
|
||||
for (const file of readdirSync(assets)) chmodSync(join(assets,file),0o644);
|
||||
const isolated = (command, options={}) => run('docker',grokConsumerDockerArgs({assets,consumer,cache,uid:process.getuid(),gid:process.getgid(),command,...options}));
|
||||
// Cursor's verified execution snapshot exceeds the smaller Grok fixture tmpfs.
|
||||
const isolated = (command, options={}) => run('docker',grokConsumerDockerArgs({assets,consumer,cache,uid:process.getuid(),gid:process.getgid(),temporarySizeMb:1024,command,...options}));
|
||||
isolated(['npm','install','--ignore-scripts','--omit=dev',...readdirSync(assets).filter(f=>f.endsWith('.tgz')).map(f=>`/packages/${f}`)],{download:true});
|
||||
const sentinel = join(consumer,'node_modules/paperclip-verification-lifecycle-sentinel/lifecycle-ran');
|
||||
assert.equal(existsSync(sentinel),false);
|
||||
@@ -71,11 +72,13 @@ const setupOutput = isolated(['node','node_modules/paperclipai/dist/index.js','r
|
||||
console.log(setupOutput.trim());
|
||||
assert.match(setupOutput,/Verified Cursor 2026\.09\.26-dd393fe \(linux-x64\), paperclip-cursor-usage-v4/);
|
||||
const probe = `import assert from 'node:assert/strict';
|
||||
import { verifyQualifiedAcpxInstallation } from '/consumer/node_modules/@paperclipai/server/dist/vendor/paperclip-runner/drivers/acpx/installation-integrity.js';
|
||||
import { verifyAcpxProfileInstallation } from '/consumer/node_modules/@paperclipai/server/dist/vendor/paperclip-runner/drivers/acpx/profile-installation.js';
|
||||
import { resolveQualifiedAcpxProfile } from '/consumer/node_modules/@paperclipai/server/dist/vendor/paperclip-runner/drivers/acpx/qualified-profiles.js';
|
||||
const profile = resolveQualifiedAcpxProfile('cursor', 'gpt-5.6-luna[context=272k,reasoning=medium,fast=false]');
|
||||
const installation = await verifyQualifiedAcpxInstallation(profile, () => { throw new Error('Cursor must not resolve an npm package'); });
|
||||
assert.equal(installation.agentServerPackageJsonPath,null); assert.equal(installation.agentRuntimePackageJsonPath,null);
|
||||
const installation = await verifyAcpxProfileInstallation(profile);
|
||||
assert.equal(installation.agentServerPackageJsonPath,'/consumer/node_modules/@paperclipai/server/dist/vendor/paperclip-runner/provider-assets/cursor/linux-x64/.paperclip-cursor-closure.json');
|
||||
assert.equal(installation.agentRuntimePackageJsonPath,null);
|
||||
assert.equal(installation.commandDigest,profile.commandDigest);
|
||||
await (await installation.openCommand()).close();
|
||||
console.log('Installed Cursor closure and command lease verified without credentials or candidate overrides');`;
|
||||
writeFileSync(join(assets,'probe.mjs'),probe,{mode:0o644});
|
||||
|
||||
Reference in new issue
Block a user