import os, subprocess, signal, pathlib, json root=pathlib.Path.home()/'filbert-scratch/r90-review/wt' out=root.parent/'mutants';out.mkdir(exist_ok=True) env=dict(os.environ,TMPDIR=str(pathlib.Path.home()/'filbert-scratch/tmp'),DOCKER_HOST='unix:///nonexistent.sock') R='packages/tasks/src/requirements.mjs';V='packages/tasks/src/verbs.mjs';B='packages/bus/src/broker.mjs';T='packages/harness/src/tools.mjs';RU='packages/harness/src/runner.mjs' req=['node','--test','packages/tasks/tests/requirements.test.mjs'] verb=['node','--test','packages/tasks/tests/verbs.test.mjs'] bus=['node','--test','packages/bus/tests/requirements.test.mjs'] tools=['node','--test','packages/harness/tests/tools.test.mjs'] turn=['node','--test','--test-name-pattern=turnRequest','packages/harness/tests/runner.test.mjs'] M=[ ('own keys replaced by inherited keys',R,'Object.hasOwn(x, k)','(k in x)',req), ('most approved ids omitted',V,'loadRequirements().requirements.map((r) => r.id)',"loadRequirements().requirements.filter((r,i,a)=>i===0 || i===a.length-1 || r.id==='REQ-TASK-1').map((r) => r.id)",verb), ('load unchecked',R,'return freeze(checkRequirements(list));','return freeze(list);',req), ('unknown requirement accepted',V," if (!requirements.has(plan.requirement)) fail('unknown-requirement');",'',verb), ('read permits a nonholder',B,' keys(a, []);\n this.#agent(s);\n return this.#requirements;',' keys(a, []);\n return this.#requirements;',bus), ('tool points at tasks',T,'add("list_requirements", "requirements",','add("list_requirements", "tasks",',tools), ('human header drops request',RU,' if (m.request) head.push(`request ${m.request}`);','',turn), ] rows=[] def run(cmd,log): with log.open('w') as f: p=subprocess.Popen(cmd,cwd=root,env=env,stdout=f,stderr=subprocess.STDOUT,start_new_session=True) try:p.wait(timeout=45) except subprocess.TimeoutExpired: os.killpg(p.pid,signal.SIGKILL);p.wait();return 'timeout' return p.returncode for i,(name,path,old,new,cmd) in enumerate(M,1): p=root/path;src=p.read_text();assert src.count(old)==1,(name,src.count(old)) try: p.write_text(src.replace(old,new));rc=run(cmd,out/f'{i}-suite.log') row={'name':name,'suite_rc':rc,'result':'survived' if rc==0 else 'killed' if rc!='timeout' else 'timeout'} if rc==0: row['independent_probe_rc']=run(['node','--test',str(root.parent/'probes.test.mjs')],out/f'{i}-probes.log') rows.append(row);print(json.dumps(row),flush=True) finally:p.write_text(src) (out/'summary.json').write_text(json.dumps(rows,indent=2)+'\n')