test(cso): make recheck retention overlap deterministic

Co-Authored-By: OpenAI Codex <noreply@openai.com>
This commit is contained in:
Garry TanandOpenAI Codex committed 2026-09-11 17:46:05 +00:00
1 parent f539f7ea9e
commit 9a759d1840
1 file changed
+10 -7
+10 -7
View File
@@ -21,22 +21,25 @@ beforeAll(()=>{root=fs.mkdtempSync(path.join(os.tmpdir(),'cso-cli-recheck-'));re
afterAll(()=>fs.rmSync(root,{recursive:true,force:true}));
describe('CSO recheck persistence',()=>{
test('requires an immutable finished original audit',()=>{const run=JSON.parse(command(['start','--repo',repo,'--scope','auth','--offline']).stdout),report=JSON.parse(fs.readFileSync(reportPath(run),'utf8'));expect(command(['submit',run.runId,writeInput('unfinished.json',completeEvidence(report,[finding]))]).status).toBe(0);const id=JSON.parse(fs.readFileSync(reportPath(run),'utf8')).findings[0].id,recheck=command(['recheck',id,'--run',run.runId,'--repo',repo]);expect(recheck.status).not.toBe(0);expect(recheck.stderr).toContain('finished original audit');});
test('requires an immutable finished original audit',()=>{const run=JSON.parse(command(['start','--repo',repo,'--scope','auth','--offline']).stdout),report=JSON.parse(fs.readFileSync(reportPath(run),'utf8'));expect(command(['submit',run.runId,writeInput('unfinished.json',completeEvidence(report,[finding]))]).status).toBe(0);const id=JSON.parse(fs.readFileSync(reportPath(run),'utf8')).findings[0].id,recheck=command(['recheck',id,'--run',run.runId,'--repo',repo]);expect(recheck.status).not.toBe(0);expect(recheck.stderr).toContain('finished original audit');},30_000);
test('resolved closure rejects free-form or unrelated boundary evidence',()=>{const original=JSON.parse(command(['start','--repo',repo,'--scope','auth','--offline']).stdout),originalPath=reportPath(original),initial=JSON.parse(fs.readFileSync(originalPath,'utf8'));expect(command(['submit',original.runId,writeInput('bound-original.json',completeEvidence(initial,[finding]))]).status).toBe(0);expect(command(['finish',original.runId]).status).toBe(0);const findingId=JSON.parse(fs.readFileSync(originalPath,'utf8')).findings[0].id,started=JSON.parse(command(['recheck',findingId,'--run',original.runId,'--repo',repo]).stdout);
const freeForm=command(['submit',started.runId,writeInput('free-form-claim.json',{recheck:{findingId,outcome:'resolved',evidence:['caller words','boundary words'],rootCause:finding.rootCause}})]);expect(freeForm.status).not.toBe(0);expect(freeForm.stderr).toContain('recheck evidence[0]');
const unrelated=command(['submit',started.runId,writeInput('unrelated-boundary-claim.json',{recheck:{findingId,outcome:'resolved',evidence:[{kind:'caller',path:'src/users.ts',line:1,observation:'Fresh caller trace reaches the predicate'},{kind:'security_boundary',path:'src/other.ts',line:1,observation:'Unrelated source says nothing about authorization'}],rootCause:finding.rootCause}})]);expect(unrelated.status).not.toBe(0);expect(unrelated.stderr).toContain('original finding location');
const phantomLine=command(['submit',started.runId,writeInput('phantom-line-claim.json',{recheck:{findingId,outcome:'resolved',evidence:[{kind:'caller',path:'src/users.ts',line:2,observation:'A trailing newline must not create a source line'},{kind:'security_boundary',path:'src/users.ts',line:1,observation:'Fresh boundary trace checks authorization'}],rootCause:finding.rootCause}})]);expect(phantomLine.status).not.toBe(0);expect(phantomLine.stderr).toContain('line is outside the fresh source file');
});
test('a failed report write cannot leave a closure claim behind',()=>{const original=JSON.parse(command(['start','--repo',repo,'--scope','auth','--offline']).stdout),originalPath=reportPath(original),initial=JSON.parse(fs.readFileSync(originalPath,'utf8'));expect(command(['submit',original.runId,writeInput('original.json',completeEvidence(initial,[finding]))]).status).toBe(0);expect(command(['finish',original.runId]).status).toBe(0);const originalReport=JSON.parse(fs.readFileSync(originalPath,'utf8')),findingId=originalReport.findings[0].id,started=command(['recheck',findingId,'--run',original.runId,'--repo',repo]);expect(started.status).toBe(0);const child=JSON.parse(started.stdout),childPath=reportPath({...child,repoId:original.repoId}),childDir=path.dirname(childPath),childInitial=JSON.parse(fs.readFileSync(childPath,'utf8'));expect(command(['submit',child.runId,writeInput('child-baseline.json',completeEvidence(childInitial))]).status).toBe(0);const complete=JSON.parse(fs.readFileSync(childPath,'utf8'));expect(complete.completeness).toBe('complete');complete.events.push({at:new Date().toISOString(),kind:'padding',message:''});const empty=Buffer.byteLength(JSON.stringify(complete,null,2)+'\n'),target=1024*1024-8;complete.events.at(-1).message='x'.repeat(target-empty);const encoded=JSON.stringify(complete,null,2)+'\n';expect(Buffer.byteLength(encoded)).toBe(target);fs.writeFileSync(childPath,encoded);const failed=command(['submit',child.runId,writeInput('failed-claim.json',{modelUsage:{source:'host',tokens:0},recheck:{findingId,outcome:'resolved',evidence:recheckEvidence(),rootCause:finding.rootCause}})]);expect(failed.status).not.toBe(0);expect(failed.stderr).toContain('PERSISTENCE_FAILED');expect(fs.existsSync(path.join(childDir,'recheck-claim.json'))).toBe(false);});
test.skipIf(process.platform==='win32')('retention cannot retire an expiring parent while fresh recheck capture is in flight',async()=>{const original=JSON.parse(command(['start','--repo',repo,'--scope','auth','--offline']).stdout),currentDir=path.dirname(reportPath(original)),initial=JSON.parse(fs.readFileSync(reportPath(original),'utf8'));expect(command(['submit',original.runId,writeInput('leased-original.json',completeEvidence(initial,[finding]))]).status).toBe(0);expect(command(['finish',original.runId]).status).toBe(0);const finished=JSON.parse(fs.readFileSync(reportPath(original),'utf8')),findingId=finished.findings[0].id,created=Date.now()-30*86400_000+750,oldRun=`${created}-${'8'.repeat(16)}`,oldDir=path.join(path.dirname(currentDir),oldRun);finished.runId=oldRun;fs.writeFileSync(path.join(currentDir,'report.json'),JSON.stringify(finished,null,2)+'\n');fs.renameSync(currentDir,oldDir);original.runId=oldRun;
const stress=path.join(repo,'recheck-stress');fs.mkdirSync(stress);for(let index=0;index<1800;index++)fs.writeFileSync(path.join(stress,`source-${String(index).padStart(4,'0')}.ts`),`export const value${index}=${index}\n`);let stdout='',stderr='';const child=spawn(launcher,['recheck',findingId,'--run',oldRun,'--repo',repo],{cwd:repo,env:{HOME:root,GSTACK_HOME:state,PATH:'/usr/bin:/bin'}});child.stdout!.setEncoding('utf8');child.stderr!.setEncoding('utf8');child.stdout!.on('data',chunk=>stdout+=chunk);child.stderr!.on('data',chunk=>stderr+=chunk);const leases=path.join(oldDir,'.mutation-lock-leases');let leased=false;for(let attempt=0;attempt<2000;attempt++){if(fs.existsSync(leases)&&fs.readdirSync(leases).some(name=>/^[a-f0-9]{32}\.json$/.test(name))){leased=true;break;}await Bun.sleep(1);}expect(leased).toBe(true);while(Date.now()<=created+30*86400_000)await Bun.sleep(5);expect(fs.readdirSync(leases).some(name=>/^[a-f0-9]{32}\.json$/.test(name))).toBe(true);const sweep=spawnSync(process.execPath,['--eval',`import {retention} from ${JSON.stringify(path.join(ROOT,'lib/cso/state.ts'))};retention(${Date.now()});`],{encoding:'utf8',env:{HOME:root,GSTACK_HOME:state,PATH:process.env.PATH},timeout:30_000});expect(sweep.status).toBe(0);expect(fs.existsSync(path.join(oldDir,'report.json'))).toBe(true);const code=await new Promise<number|null>(resolve=>child.on('close',resolve));fs.rmSync(stress,{recursive:true,force:true});expect(code).toBe(0);expect(stderr).toBe('');const result=JSON.parse(stdout);expect(fs.existsSync(path.join(oldDir,'report.json'))).toBe(true);expect(fs.existsSync(path.join(state,'security','cso',original.repoId,result.runId,'report.json'))).toBe(true);
},30_000);
test('closure cannot survive mutation of the fresh recheck snapshot',()=>{const original=JSON.parse(command(['start','--repo',repo,'--scope','auth','--offline']).stdout),originalPath=reportPath(original),initial=JSON.parse(fs.readFileSync(originalPath,'utf8'));expect(command(['submit',original.runId,writeInput('source-bound-original.json',completeEvidence(initial,[finding]))]).status).toBe(0);expect(command(['finish',original.runId]).status).toBe(0);const originalReport=JSON.parse(fs.readFileSync(originalPath,'utf8')),findingId=originalReport.findings[0].id,started=command(['recheck',findingId,'--run',original.runId,'--repo',repo]);expect(started.status).toBe(0);const child=JSON.parse(started.stdout),childPath=reportPath({...child,repoId:original.repoId}),childDir=path.dirname(childPath),childInitial=JSON.parse(fs.readFileSync(childPath,'utf8')),claim={findingId,outcome:'resolved',evidence:recheckEvidence(),rootCause:finding.rootCause};expect(command(['submit',child.runId,writeInput('source-bound-claim.json',{...completeEvidence(childInitial),recheck:claim})]).status).toBe(0);fs.writeFileSync(path.join(childDir,'snapshot','src','users.ts'),'mutated retained evidence\n');const finished=command(['finish',child.runId]);expect(finished.status).not.toBe(0);expect(finished.stderr).toContain('Retained snapshot changed');expect(JSON.parse(fs.readFileSync(originalPath,'utf8')).findings[0].closure).toBe('open');});
test('a failed report write cannot leave a closure claim behind',()=>{const original=JSON.parse(command(['start','--repo',repo,'--scope','auth','--offline']).stdout),originalPath=reportPath(original),initial=JSON.parse(fs.readFileSync(originalPath,'utf8'));expect(command(['submit',original.runId,writeInput('original.json',completeEvidence(initial,[finding]))]).status).toBe(0);expect(command(['finish',original.runId]).status).toBe(0);const originalReport=JSON.parse(fs.readFileSync(originalPath,'utf8')),findingId=originalReport.findings[0].id,started=command(['recheck',findingId,'--run',original.runId,'--repo',repo]);expect(started.status).toBe(0);const child=JSON.parse(started.stdout),childPath=reportPath({...child,repoId:original.repoId}),childDir=path.dirname(childPath),childInitial=JSON.parse(fs.readFileSync(childPath,'utf8'));expect(command(['submit',child.runId,writeInput('child-baseline.json',completeEvidence(childInitial))]).status).toBe(0);const complete=JSON.parse(fs.readFileSync(childPath,'utf8'));expect(complete.completeness).toBe('complete');complete.events.push({at:new Date().toISOString(),kind:'padding',message:''});const empty=Buffer.byteLength(JSON.stringify(complete,null,2)+'\n'),target=1024*1024-8;complete.events.at(-1).message='x'.repeat(target-empty);const encoded=JSON.stringify(complete,null,2)+'\n';expect(Buffer.byteLength(encoded)).toBe(target);fs.writeFileSync(childPath,encoded);const failed=command(['submit',child.runId,writeInput('failed-claim.json',{modelUsage:{source:'host',tokens:0},recheck:{findingId,outcome:'resolved',evidence:recheckEvidence(),rootCause:finding.rootCause}})]);expect(failed.status).not.toBe(0);expect(failed.stderr).toContain('PERSISTENCE_FAILED');expect(fs.existsSync(path.join(childDir,'recheck-claim.json'))).toBe(false);},30_000);
test.skipIf(process.platform==='win32')('retention and recheck share the lease that protects an expiring parent',async()=>{const original=JSON.parse(command(['start','--repo',repo,'--scope','auth','--offline']).stdout),currentDir=path.dirname(reportPath(original)),initial=JSON.parse(fs.readFileSync(reportPath(original),'utf8'));expect(command(['submit',original.runId,writeInput('leased-original.json',completeEvidence(initial,[finding]))]).status).toBe(0);expect(command(['finish',original.runId]).status).toBe(0);const finished=JSON.parse(fs.readFileSync(reportPath(original),'utf8')),findingId=finished.findings[0].id,created=Date.now()-30*86400_000+60_000,oldRun=`${created}-${'8'.repeat(16)}`,oldDir=path.join(path.dirname(currentDir),oldRun);finished.runId=oldRun;fs.writeFileSync(path.join(currentDir,'report.json'),JSON.stringify(finished,null,2)+'\n');fs.renameSync(currentDir,oldDir);original.runId=oldRun;
const leases=path.join(oldDir,'.mutation-lock-leases'),active=/^[a-f0-9]{32}\.active\.[a-f0-9]{16}$/,ready=path.join(root,'lease-ready'),release=path.join(root,'lease-release'),holderSource=`import * as fs from 'node:fs';import {withLock} from ${JSON.stringify(path.join(ROOT,'lib/cso/state.ts'))};await withLock(${JSON.stringify(oldDir)},async()=>{fs.writeFileSync(${JSON.stringify(ready)},'ready',{flag:'wx'});while(!fs.existsSync(${JSON.stringify(release)}))await Bun.sleep(5);});`;
let holderStderr='';const holder=spawn(process.execPath,['--eval',holderSource],{env:{HOME:root,GSTACK_HOME:state,PATH:process.env.PATH},stdio:['ignore','ignore','pipe']}),holderClosed=new Promise<number|null>(resolve=>holder.on('close',resolve));holder.stderr!.setEncoding('utf8');holder.stderr!.on('data',chunk=>holderStderr+=chunk);let holderCode:number|null|'timeout'='timeout';
try{const readyOutcome=await Promise.race([(async()=>{const deadline=Date.now()+10_000;while(Date.now()<deadline){if(fs.existsSync(ready))return'ready' as const;await Bun.sleep(5);}return'timeout' as const;})(),holderClosed.then(code=>`closed:${code}` as const)]);expect(readyOutcome).toBe('ready');expect(fs.readdirSync(leases).some(name=>active.test(name))).toBe(true);const sweepNow=created+30*86400_000+1,sweep=spawnSync(process.execPath,['--eval',`import {retention} from ${JSON.stringify(path.join(ROOT,'lib/cso/state.ts'))};retention(${sweepNow});`],{encoding:'utf8',env:{HOME:root,GSTACK_HOME:state,PATH:process.env.PATH},timeout:30_000});expect(sweep.status).toBe(0);expect(fs.existsSync(path.join(oldDir,'report.json'))).toBe(true);const blocked=command(['recheck',findingId,'--run',oldRun,'--repo',repo]);expect(blocked.status).not.toBe(0);expect(blocked.stderr).toContain('INSUFFICIENT_CAPACITY');expect(blocked.stderr).toContain('Another helper is updating this run');}finally{fs.writeFileSync(release,'release');holderCode=await Promise.race([holderClosed,Bun.sleep(10_000).then(()=>'timeout' as const)]);if(holderCode==='timeout'){holder.kill('SIGKILL');holderCode=await holderClosed;}}
expect(holderCode).toBe(0);expect(holderStderr).toBe('');expect(fs.readdirSync(leases)).toEqual([]);const completed=command(['recheck',findingId,'--run',oldRun,'--repo',repo]);expect(completed.status).toBe(0);expect(completed.stderr).toBe('');const result=JSON.parse(completed.stdout);expect(fs.existsSync(path.join(oldDir,'report.json'))).toBe(true);expect(fs.existsSync(path.join(state,'security','cso',original.repoId,result.runId,'report.json'))).toBe(true);
},30_000);
test('closure cannot survive mutation of the fresh recheck snapshot',()=>{const original=JSON.parse(command(['start','--repo',repo,'--scope','auth','--offline']).stdout),originalPath=reportPath(original),initial=JSON.parse(fs.readFileSync(originalPath,'utf8'));expect(command(['submit',original.runId,writeInput('source-bound-original.json',completeEvidence(initial,[finding]))]).status).toBe(0);expect(command(['finish',original.runId]).status).toBe(0);const originalReport=JSON.parse(fs.readFileSync(originalPath,'utf8')),findingId=originalReport.findings[0].id,started=command(['recheck',findingId,'--run',original.runId,'--repo',repo]);expect(started.status).toBe(0);const child=JSON.parse(started.stdout),childPath=reportPath({...child,repoId:original.repoId}),childDir=path.dirname(childPath),childInitial=JSON.parse(fs.readFileSync(childPath,'utf8')),claim={findingId,outcome:'resolved',evidence:recheckEvidence(),rootCause:finding.rootCause};expect(command(['submit',child.runId,writeInput('source-bound-claim.json',{...completeEvidence(childInitial),recheck:claim})]).status).toBe(0);fs.writeFileSync(path.join(childDir,'snapshot','src','users.ts'),'mutated retained evidence\n');const finished=command(['finish',child.runId]);expect(finished.status).not.toBe(0);expect(finished.stderr).toContain('Retained snapshot changed');expect(JSON.parse(fs.readFileSync(originalPath,'utf8')).findings[0].closure).toBe('open');},30_000);
test('complete fresh-source evidence resolves only the targeted original finding',()=>{const second={...finding,title:'Unprotected audit export',rootCause:'Audit export omits the caller authorization predicate',location:{...finding.location,symbol:'auditExport'},trace:['GET /audit/export','auditExport','record response'],references:['src/users.ts:1'],scenario:'A tenant requests another tenant audit export and receives it'},original=JSON.parse(command(['start','--repo',repo,'--scope','auth','--offline']).stdout),originalPath=reportPath(original),initial=JSON.parse(fs.readFileSync(originalPath,'utf8'));expect(command(['submit',original.runId,writeInput('closure-original.json',completeEvidence(initial,[finding,second]))]).status).toBe(0);expect(command(['finish',original.runId]).status).toBe(0);const finishedOriginal=JSON.parse(fs.readFileSync(originalPath,'utf8')),findingId=finishedOriginal.findings.find((item:any)=>item.rootCause===finding.rootCause).id,otherId=finishedOriginal.findings.find((item:any)=>item.rootCause===second.rootCause).id,originalHash=finishedOriginal.source.originalHash,source=path.join(repo,'src','users.ts'),before=fs.readFileSync(source,'utf8');
try{
fs.writeFileSync(source,'export const tenantQuery = (tenantId:string,id:string) => db.user.findUnique({where:{id,tenantId}})\n');const started=command(['recheck',findingId,'--run',original.runId,'--repo',repo]);expect(started.status).toBe(0);const child=JSON.parse(started.stdout),childPath=reportPath({...child,repoId:original.repoId}),childInitial=JSON.parse(fs.readFileSync(childPath,'utf8')),claim={findingId,outcome:'resolved',evidence:recheckEvidence(),rootCause:finding.rootCause};expect(childInitial.source.originalHash).not.toBe(originalHash);expect(JSON.parse(fs.readFileSync(originalPath,'utf8')).findings.every((item:any)=>item.closure==='open')).toBe(true);
expect(command(['submit',child.runId,writeInput('closure-claim-first.json',{recheck:claim})]).status).toBe(0);expect(JSON.parse(fs.readFileSync(originalPath,'utf8')).findings.find((item:any)=>item.id===findingId).closure).toBe('open');const incomplete=command(['finish',child.runId]);expect(incomplete.status).not.toBe(0);expect(incomplete.stderr).toContain('Partial or incompatible rechecks cannot establish closure');expect(JSON.parse(fs.readFileSync(originalPath,'utf8')).findings.find((item:any)=>item.id===findingId).closure).toBe('open');
expect(command(['submit',child.runId,writeInput('closure-fresh-evidence.json',completeEvidence(childInitial))]).status).toBe(0);const closed=command(['finish',child.runId]);expect(closed.status).toBe(0);expect(JSON.parse(closed.stdout)).toMatchObject({status:'finished',completeness:'complete'});const updated=JSON.parse(fs.readFileSync(originalPath,'utf8'));expect(updated.findings.find((item:any)=>item.id===findingId).closure).toBe('resolved');expect(updated.findings.find((item:any)=>item.id===otherId).closure).toBe('open');expect(updated.events.at(-1)).toMatchObject({kind:'closure'});expect(updated.events.at(-1).message).toContain(`resolved ${findingId}`);
}finally{fs.writeFileSync(source,before);}
});
},30_000);
});