gander: guard unique mutation targets and separate SSO ordering mutant

This commit is contained in:
jason.woltje committed 2026-10-21 14:26:36 -05:00
1 parent 84aea3063c
commit f8a59e6aad
14 files changed
+1108 -12

No files matched your search

+1
View File
@@ -104,3 +104,4 @@ changes are planned before the batch. M1-M29 remain prepared and unexecuted.
2026-10-21 r2 stop 2: base killer invocations 14/0 under 30 seconds each; M23-M27 killed, M28 survived due rebase making its generic mutation target the earlier SSO insertion. No M29 or golden suite run. Every restored hash and Git status clean; leftover process sweep count 0. Slot returned to Sage in gander-0035. Full per-step counts, base/mutant times and kill table in r2/run2/. Awaiting ruling before any fix or rerun; third stop goes to Mos.
2026-10-21 sage-2072 product test: added the merge-scoped SSO/socket conversion case without --send, asserting pointer argv order, rendered unit argv order, status agreement and no secret-file reads. Removing socket from sso_for_target is its planned RED case (M28b). Focused RED/GREEN remains pending the busy gate: Herb's suite was active at the preflight, so no test started. Runtime code unchanged. Mos mos-1197 owner-subject ruling recorded in queue-252/BUILD-NOTES.md.
2026-10-21 sage-2072/2077 driver: unique string-target guard preflights every definition before any tests and before creating scratch state; M28 names without_proof, M28b names kept, M5 names the parse catch, M25 names append flags, M29 uses the unique full line. Static audit accepts all 30 definitions; zero/duplicate targets refuse. Against 64539c96b, M5 old/narrowed bytes match; M25 differs and joins the next batch. No mutation tests ran in this static check.
@@ -0,0 +1,16 @@
// Synchronous mutation preparation only. No file is written until every replacement is unique.
export function guardMutation(input, mutate, { auditOnly = false } = {}) {
const targets = [];
class UniqueText extends String {
replace(target, replacement) { return this.applyReplacement('replace', target, replacement); }
replaceAll(target, replacement) { return this.applyReplacement('replaceAll', target, replacement); }
applyReplacement(method, target, replacement) {
if (typeof target !== 'string' || !target) throw Error('mutation target must be a nonempty string');
const source = String(this), count = source.split(target).length - 1;
targets.push({ method, target, count });
if (count !== 1 && !auditOnly) throw Error(`mutation target occurs ${count} times, expected exactly once: ${target}`);
return new UniqueText(String.prototype[method].call(source, target, replacement));
}
}
return { text: String(mutate(new UniqueText(input))), targets };
}
+12 -6
View File
@@ -1,3 +1,4 @@
import { guardMutation } from './mutant-guard.mjs';
// Authorized batch only. Mutate isolated scratch copies, never the candidate or installed tree.
import {mkdtempSync,cpSync,readFileSync,writeFileSync,rmSync,symlinkSync,existsSync,mkdirSync} from 'node:fs';
import {tmpdir} from 'node:os';import {join,resolve} from 'node:path';
@@ -5,7 +6,6 @@ import {spawnSync,execFileSync} from 'node:child_process';import {createHash} fr
import {fileURLToPath} from 'node:url';
const root=fileURLToPath(new URL('../../../../',import.meta.url));
const out=join(root,'agents/gander/work/queue-196/evidence/mutants');mkdirSync(out,{recursive:true});
const scratch=mkdtempSync(join(tmpdir(),'g196-mut-'));
const p='packages/bus/src/principal.mjs',h='packages/bus/src/human.mjs',w='packages/webui/src/tester-socket.mjs',s='packages/bus/src/server.mjs',peer='packages/bus/src/peercred.mjs';
const principal='packages/bus/tests/principal.test.mjs',socket='packages/webui/tests/tester-socket.test.mjs',transport='packages/bus/tests/peer-transport.test.mjs',interpreter='packages/bus/tests/interpreter.test.mjs';
const release=['--test-name-pattern=row196 explicit socket','packages/cli/tests/stack-release.test.mjs'];
@@ -14,7 +14,7 @@ const specs=[
['M2',w,'socket mode widened',socket,t=>t.replace('chmodSync(temporary, 0o600)','chmodSync(temporary, 0o666)')],
['M3','packages/webui/src/serve.mjs','sign-in accepted on tester',socket,t=>t.replace("if (tester && (Object.hasOwn(req.headers, 'authorization')", "if (false && (Object.hasOwn(req.headers, 'authorization')")],
['M4',p,'copied PID accepted',principal,t=>t.replace('peer.pid !== proof.pid','false')],
['M5',peer,'helper parse error ignored','packages/bus/tests/peercred.test.mjs',t=>t.replace('} catch { finish(true); }','} catch { finish(false, {pid:2,uid:0,gid:0}); }')],
['M5',peer,'helper parse error ignored','packages/bus/tests/peercred.test.mjs',t=>t.replace('finish(false, Object.freeze(p));\n } catch { finish(true); }','finish(false, Object.freeze(p));\n } catch { finish(false, {pid:2,uid:0,gid:0}); }')],
['M6',p,'foreign uid accepted',principal,t=>t.replace('peer.uid !== process.getuid()','false')],
['M7',w,'unsafe parent accepted',socket,t=>t.replace('(dir.mode & 0o077)','false')],
['M8',h,'agent environment walk skipped',principal,t=>t.replace('current.env !== null && MARKERS.some','false && MARKERS.some')],
@@ -34,19 +34,25 @@ const specs=[
['M22',s,'cap requests invoke helper',transport,t=>t.replace(' if (kind) {',' if (r.cap) await peers.read(socket);\n if (kind) {')],
['M23','packages/bus/src/interpreter.mjs','restart retains stale identity',interpreter,t=>t.replace('export function recordInterpreterStart(directory, record) {','export function recordInterpreterStart(directory, record) {\n try { readFileSync(join(directory,"peercred-starts.jsonl")); return; } catch {}')],
['M24',w,'listener binds final path directly',socket,t=>t.replace("const temporary = join(parent, '.' + randomBytes(4).toString('hex') + '.s');",'const temporary = path;')],
['M25','packages/bus/src/interpreter.mjs','FIFO receipt blocks before type refusal',['--test-name-pattern=non-regular startup receipt',interpreter],t=>t.replaceAll(' | constants.O_NONBLOCK','')],
['M25','packages/bus/src/interpreter.mjs','FIFO receipt blocks before type refusal',['--test-name-pattern=non-regular startup receipt',interpreter],t=>t.replace('constants.O_WRONLY | constants.O_APPEND | constants.O_CREAT | constants.O_NOFOLLOW | constants.O_NONBLOCK, 0o600','constants.O_WRONLY | constants.O_APPEND | constants.O_CREAT | constants.O_NOFOLLOW, 0o600')],
['M26',peer,'missing helper accepted at startup',['--test-name-pattern=missing or non-regular peer helper','packages/bus/tests/peercred.test.mjs'],t=>t.replace('if (!s.isFile() || s.isSymbolicLink()) throw Error();','if (false) throw Error();').replace('catch { throw refused(); }','catch {}')],
['M27',peer,'shutdown returns before helpers are reaped',['--test-name-pattern=shutdown waits','packages/bus/tests/peercred.test.mjs'],t=>t.replace(" await Promise.all([...children].map(child => new Promise(resolve => {\n child.once('close', resolve);\n child.kill('SIGKILL');\n })));"," for (const child of children) child.kill('SIGKILL');")],
['M28','scripts/stack-release.sh','proof pair placed after tester socket flag',release,t=>t.replace('--send | --tester-port | --tester-socket) break','--send | --tester-port) break')],
['M29','scripts/stack-release.sh','unsafe tester path reaches service stop',release,t=>t.split('\n').filter(line=>!line.includes('|| check_refuse tester-socket-path')).join('\n')],
['M28','scripts/stack-release.sh','proof pair placed after tester socket flag',release,t=>t.replace('case "${without_proof[i]}" in --send | --tester-port | --tester-socket) break','case "${without_proof[i]}" in --send | --tester-port) break')],
['M28b','scripts/stack-release.sh','SSO placed after tester socket flag',['--test-name-pattern=row196 SSO socket','packages/cli/tests/stack-release.test.mjs'],t=>t.replace('case "${kept[i]}" in --send | --tester-port | --tester-socket) break','case "${kept[i]}" in --send | --tester-port) break')],
['M29','scripts/stack-release.sh','unsafe tester path reaches service stop',release,t=>t.replace(t.split('\n').find(line=>line.includes('|| check_refuse tester-socket-path'))+'\n','')],
];
const hash=x=>createHash('sha256').update(x).digest('hex');
const results=[];
for (const [id,file,,,mutate] of specs) {
try { guardMutation(readFileSync(join(root,file),'utf8'),mutate); }
catch(error) { throw Error(id+': '+error.message); }
}
const scratch=mkdtempSync(join(tmpdir(),'g196-mut-'));
try {
for(const name of ['packages','scripts','adapters','roles','contracts','RELEASE','package.json','package-lock.json','.git'])if(existsSync(join(root,name)))cpSync(join(root,name),join(scratch,name),{recursive:true,filter:src=>!src.includes('/node_modules/')&&!src.endsWith('/node_modules')});
symlinkSync(join(root,'node_modules'),join(scratch,'node_modules'));
for(const [id,file,description,test,mutate] of specs) {
const at=join(scratch,file),original=readFileSync(at,'utf8'),before=hash(original),changed=mutate(original);
const at=join(scratch,file),original=readFileSync(at,'utf8'),before=hash(original),changed=guardMutation(original,mutate).text;
if(changed===original)throw Error(id+' did not change bytes');
writeFileSync(at,changed);
const syntax=spawnSync(file.endsWith('.sh')?'bash':process.execPath,[file.endsWith('.sh')?'-n':'--check',at],{encoding:'utf8'});
+12 -6
View File
@@ -1,3 +1,4 @@
import { guardMutation } from '../mutant-guard.mjs';
// Authorized batch only. Mutate isolated scratch copies, never the candidate or installed tree.
import {mkdtempSync,cpSync,readFileSync,writeFileSync,rmSync,symlinkSync,existsSync,mkdirSync} from 'node:fs';
import {tmpdir} from 'node:os';import {join,resolve} from 'node:path';
@@ -5,7 +6,6 @@ import {spawnSync,execFileSync} from 'node:child_process';import {createHash} fr
import {fileURLToPath} from 'node:url';
const root='/mnt/storage/scratch/tmp/g196-tree-tn651z';
const out='/home/jwoltje/.t3/worktrees/mosaic-stack/gander-row196/agents/gander/work/queue-196/r2/mutants';mkdirSync(out,{recursive:true});
const scratch=mkdtempSync(join(tmpdir(),'g196-mut-'));
const p='packages/bus/src/principal.mjs',h='packages/bus/src/human.mjs',w='packages/webui/src/tester-socket.mjs',s='packages/bus/src/server.mjs',peer='packages/bus/src/peercred.mjs';
const principal='packages/bus/tests/principal.test.mjs',socket='packages/webui/tests/tester-socket.test.mjs',transport='packages/bus/tests/peer-transport.test.mjs',interpreter='packages/bus/tests/interpreter.test.mjs';
const release=['--test-name-pattern=row196 explicit socket','packages/cli/tests/stack-release.test.mjs'];
@@ -14,7 +14,7 @@ const specs=[
['M2',w,'socket mode widened',socket,t=>t.replace('chmodSync(temporary, 0o600)','chmodSync(temporary, 0o666)')],
['M3','packages/webui/src/serve.mjs','sign-in accepted on tester',socket,t=>t.replace("if (tester && (Object.hasOwn(req.headers, 'authorization')", "if (false && (Object.hasOwn(req.headers, 'authorization')")],
['M4',p,'copied PID accepted',principal,t=>t.replace('peer.pid !== proof.pid','false')],
['M5',peer,'helper parse error ignored','packages/bus/tests/peercred.test.mjs',t=>t.replace('} catch { finish(true); }','} catch { finish(false, {pid:2,uid:0,gid:0}); }')],
['M5',peer,'helper parse error ignored','packages/bus/tests/peercred.test.mjs',t=>t.replace('finish(false, Object.freeze(p));\n } catch { finish(true); }','finish(false, Object.freeze(p));\n } catch { finish(false, {pid:2,uid:0,gid:0}); }')],
['M6',p,'foreign uid accepted',principal,t=>t.replace('peer.uid !== process.getuid()','false')],
['M7',w,'unsafe parent accepted',socket,t=>t.replace('(dir.mode & 0o077)','false')],
['M8',h,'agent environment walk skipped',principal,t=>t.replace('current.env !== null && MARKERS.some','false && MARKERS.some')],
@@ -34,20 +34,26 @@ const specs=[
['M22',s,'cap requests invoke helper',transport,t=>t.replace(' if (kind) {',' if (r.cap) await peers.read(socket);\n if (kind) {')],
['M23','packages/bus/src/interpreter.mjs','restart retains stale identity',interpreter,t=>t.replace('export function recordInterpreterStart(directory, record) {','export function recordInterpreterStart(directory, record) {\n try { readFileSync(join(directory,"peercred-starts.jsonl")); return; } catch {}')],
['M24',w,'listener binds final path directly',socket,t=>t.replace("const temporary = join(parent, '.' + randomBytes(4).toString('hex') + '.s');",'const temporary = path;')],
['M25','packages/bus/src/interpreter.mjs','FIFO receipt blocks before type refusal',['--test-name-pattern=non-regular startup receipt',interpreter],t=>t.replaceAll(' | constants.O_NONBLOCK','')],
['M25','packages/bus/src/interpreter.mjs','FIFO receipt blocks before type refusal',['--test-name-pattern=non-regular startup receipt',interpreter],t=>t.replace('constants.O_WRONLY | constants.O_APPEND | constants.O_CREAT | constants.O_NOFOLLOW | constants.O_NONBLOCK, 0o600','constants.O_WRONLY | constants.O_APPEND | constants.O_CREAT | constants.O_NOFOLLOW, 0o600')],
['M26',peer,'missing helper accepted at startup',['--test-name-pattern=missing or non-regular peer helper','packages/bus/tests/peercred.test.mjs'],t=>t.replace('if (!s.isFile() || s.isSymbolicLink()) throw Error();','if (false) throw Error();').replace('catch { throw refused(); }','catch {}')],
['M27',peer,'shutdown returns before helpers are reaped',['--test-name-pattern=shutdown waits','packages/bus/tests/peercred.test.mjs'],t=>t.replace(" await Promise.all([...children].map(child => new Promise(resolve => {\n child.once('close', resolve);\n child.kill('SIGKILL');\n })));"," for (const child of children) child.kill('SIGKILL');")],
['M28','scripts/stack-release.sh','proof pair placed after tester socket flag',release,t=>t.replace('--send | --tester-port | --tester-socket) break','--send | --tester-port) break')],
['M29','scripts/stack-release.sh','unsafe tester path reaches service stop',release,t=>t.split('\n').filter(line=>!line.includes('|| check_refuse tester-socket-path')).join('\n')],
['M28','scripts/stack-release.sh','proof pair placed after tester socket flag',release,t=>t.replace('case "${without_proof[i]}" in --send | --tester-port | --tester-socket) break','case "${without_proof[i]}" in --send | --tester-port) break')],
['M28b','scripts/stack-release.sh','SSO placed after tester socket flag',['--test-name-pattern=row196 SSO socket','packages/cli/tests/stack-release.test.mjs'],t=>t.replace('case "${kept[i]}" in --send | --tester-port | --tester-socket) break','case "${kept[i]}" in --send | --tester-port) break')],
['M29','scripts/stack-release.sh','unsafe tester path reaches service stop',release,t=>t.replace(t.split('\n').find(line=>line.includes('|| check_refuse tester-socket-path'))+'\n','')],
];
const hash=x=>createHash('sha256').update(x).digest('hex');
const results=[];
for (const [id,file,,,mutate] of specs) {
try { guardMutation(readFileSync(join(root,file),'utf8'),mutate); }
catch(error) { throw Error(id+': '+error.message); }
}
const scratch=mkdtempSync(join(tmpdir(),'g196-mut-'));
try {
for(const name of ['packages','scripts','adapters','roles','contracts','RELEASE','package.json','package-lock.json','.gitignore'])if(existsSync(join(root,name)))cpSync(join(root,name),join(scratch,name),{recursive:true,filter:src=>!src.includes('/node_modules/')&&!src.endsWith('/node_modules')});
symlinkSync(join(root,'node_modules'),join(scratch,'node_modules'));
for(const args of [['init','-q'],['add','.'],['-c','user.name=fixture','-c','user.email=fixture@invalid','-c','commit.gpgsign=false','-c','core.hooksPath=/dev/null','commit','-qm','candidate snapshot']])execFileSync('git',args,{cwd:scratch});
for(const [id,file,description,test,mutate] of specs) {
const at=join(scratch,file),original=readFileSync(at,'utf8'),before=hash(original),changed=mutate(original);
const at=join(scratch,file),original=readFileSync(at,'utf8'),before=hash(original),changed=guardMutation(original,mutate).text;
if(changed===original)throw Error(id+' did not change bytes');
writeFileSync(at,changed);
const syntax=spawnSync(file.endsWith('.sh')?'bash':process.execPath,[file.endsWith('.sh')?'-n':'--check',at],{encoding:'utf8'});
@@ -0,0 +1,67 @@
import { realpathSync, statSync, readFileSync, openSync, fstatSync, writeSync, fsyncSync, closeSync, constants } from 'node:fs';
import { dirname, join, sep } from 'node:path';
import { createHash } from 'node:crypto';
import { execFileSync } from 'node:child_process';
const systemPython = '/usr/bin/python3';
const defaultIO = { realpath: realpathSync, stat: statSync, readFile: readFileSync, exec: execFileSync };
const below = (path, parent) => path === parent || path.startsWith(parent + sep);
// Trusted dependency injection is for offline tests, never a CLI/env interpreter override.
export function inspectInterpreter({ io = defaultIO } = {}) {
try {
const path = io.realpath(systemPython);
const homes = ['/home', '/root', ...String(io.readFile('/etc/passwd', 'utf8')).split('\n')
.map(line => line.split(':')[5]).filter(p => p?.startsWith('/') && p !== '/')];
if (!path.startsWith('/') || homes.some(home => below(path, home))) throw Error();
// Check both the system entry's parent and every resolved component. /usr/bin/python3
// may be a system symlink; its containing directory and resolved target must be safe.
for (const start of [dirname(systemPython), path]) {
for (let at = start;; at = dirname(at)) {
const s = io.stat(at);
if (s.uid !== 0 || (s.mode & 0o022) || (at === path ? !s.isFile() : !s.isDirectory())) throw Error();
if (at === '/') break;
}
}
const data = io.readFile(path);
if (!Buffer.isBuffer(data) || !data.subarray(0, 4).equals(Buffer.from([127, 69, 76, 70]))) throw Error();
const version = JSON.parse(String(io.exec(path, ['-I', '-S', '-c', 'import json,sys,socket;assert hasattr(socket,"SO_PEERCRED");print(json.dumps(list(sys.version_info[:3])))'],
{ env: {}, timeout: 1000, maxBuffer: 256, encoding: 'utf8' })));
if (!Array.isArray(version) || version.length !== 3 || !version.every(Number.isSafeInteger) ||
version[0] < 3 || (version[0] === 3 && version[1] < 10)) throw Error();
const s = io.stat(path);
return Object.freeze({ path, version: Object.freeze(version), dev: s.dev, ino: s.ino,
sha256: createHash('sha256').update(data).digest('hex') });
} catch { throw Error('interpreter-unsafe'); }
}
export function verifyInterpreterReceipt(directory, expected, since) {
let fd;
try {
fd = openSync(join(directory, 'peercred-starts.jsonl'), constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
const s = fstatSync(fd);
if (!s.isFile() || s.uid !== process.getuid() || (s.mode & 0o077) || s.nlink !== 1) throw Error();
const text = readFileSync(fd, 'utf8');
if (!text.endsWith('\n')) throw Error();
const actual = JSON.parse(text.trimEnd().split('\n').at(-1));
if (actual.copy !== new URL('../../../', import.meta.url).pathname || !(Date.parse(actual.at) >= Number(since)) ||
Date.parse(actual.at) > Date.now() + 1000 || ['path', 'sha256', 'dev', 'ino', 'version'].some(k => JSON.stringify(actual[k]) !== JSON.stringify(expected[k]))) throw Error();
return true;
} catch { throw Error('interpreter-receipt-mismatch'); }
finally { if (fd !== undefined) closeSync(fd); }
}
export function recordInterpreterStart(directory, record) {
let fd;
try {
const dir = statSync(directory);
if (!dir.isDirectory() || dir.uid !== process.getuid() || (dir.mode & 0o077)) throw Error();
fd = openSync(join(directory, 'peercred-starts.jsonl'),
constants.O_WRONLY | constants.O_APPEND | constants.O_CREAT | constants.O_NOFOLLOW, 0o600);
const s = fstatSync(fd);
if (!s.isFile() || s.uid !== process.getuid() || (s.mode & 0o077) || s.nlink !== 1) throw Error();
const line = Buffer.from(JSON.stringify({ at: new Date().toISOString(), copy: new URL('../../../', import.meta.url).pathname, ...record }) + '\n');
if (writeSync(fd, line) !== line.length) throw Error();
fsyncSync(fd);
} catch { throw Error('interpreter-receipt-unsafe'); }
finally { if (fd !== undefined) closeSync(fd); }
}
@@ -0,0 +1,67 @@
import { realpathSync, statSync, readFileSync, openSync, fstatSync, writeSync, fsyncSync, closeSync, constants } from 'node:fs';
import { dirname, join, sep } from 'node:path';
import { createHash } from 'node:crypto';
import { execFileSync } from 'node:child_process';
const systemPython = '/usr/bin/python3';
const defaultIO = { realpath: realpathSync, stat: statSync, readFile: readFileSync, exec: execFileSync };
const below = (path, parent) => path === parent || path.startsWith(parent + sep);
// Trusted dependency injection is for offline tests, never a CLI/env interpreter override.
export function inspectInterpreter({ io = defaultIO } = {}) {
try {
const path = io.realpath(systemPython);
const homes = ['/home', '/root', ...String(io.readFile('/etc/passwd', 'utf8')).split('\n')
.map(line => line.split(':')[5]).filter(p => p?.startsWith('/') && p !== '/')];
if (!path.startsWith('/') || homes.some(home => below(path, home))) throw Error();
// Check both the system entry's parent and every resolved component. /usr/bin/python3
// may be a system symlink; its containing directory and resolved target must be safe.
for (const start of [dirname(systemPython), path]) {
for (let at = start;; at = dirname(at)) {
const s = io.stat(at);
if (s.uid !== 0 || (s.mode & 0o022) || (at === path ? !s.isFile() : !s.isDirectory())) throw Error();
if (at === '/') break;
}
}
const data = io.readFile(path);
if (!Buffer.isBuffer(data) || !data.subarray(0, 4).equals(Buffer.from([127, 69, 76, 70]))) throw Error();
const version = JSON.parse(String(io.exec(path, ['-I', '-S', '-c', 'import json,sys,socket;assert hasattr(socket,"SO_PEERCRED");print(json.dumps(list(sys.version_info[:3])))'],
{ env: {}, timeout: 1000, maxBuffer: 256, encoding: 'utf8' })));
if (!Array.isArray(version) || version.length !== 3 || !version.every(Number.isSafeInteger) ||
version[0] < 3 || (version[0] === 3 && version[1] < 10)) throw Error();
const s = io.stat(path);
return Object.freeze({ path, version: Object.freeze(version), dev: s.dev, ino: s.ino,
sha256: createHash('sha256').update(data).digest('hex') });
} catch { throw Error('interpreter-unsafe'); }
}
export function verifyInterpreterReceipt(directory, expected, since) {
let fd;
try {
fd = openSync(join(directory, 'peercred-starts.jsonl'), constants.O_RDONLY | constants.O_NOFOLLOW);
const s = fstatSync(fd);
if (!s.isFile() || s.uid !== process.getuid() || (s.mode & 0o077) || s.nlink !== 1) throw Error();
const text = readFileSync(fd, 'utf8');
if (!text.endsWith('\n')) throw Error();
const actual = JSON.parse(text.trimEnd().split('\n').at(-1));
if (actual.copy !== new URL('../../../', import.meta.url).pathname || !(Date.parse(actual.at) >= Number(since)) ||
Date.parse(actual.at) > Date.now() + 1000 || ['path', 'sha256', 'dev', 'ino', 'version'].some(k => JSON.stringify(actual[k]) !== JSON.stringify(expected[k]))) throw Error();
return true;
} catch { throw Error('interpreter-receipt-mismatch'); }
finally { if (fd !== undefined) closeSync(fd); }
}
export function recordInterpreterStart(directory, record) {
let fd;
try {
const dir = statSync(directory);
if (!dir.isDirectory() || dir.uid !== process.getuid() || (dir.mode & 0o077)) throw Error();
fd = openSync(join(directory, 'peercred-starts.jsonl'),
constants.O_WRONLY | constants.O_APPEND | constants.O_CREAT | constants.O_NOFOLLOW, 0o600);
const s = fstatSync(fd);
if (!s.isFile() || s.uid !== process.getuid() || (s.mode & 0o077) || s.nlink !== 1) throw Error();
const line = Buffer.from(JSON.stringify({ at: new Date().toISOString(), copy: new URL('../../../', import.meta.url).pathname, ...record }) + '\n');
if (writeSync(fd, line) !== line.length) throw Error();
fsyncSync(fd);
} catch { throw Error('interpreter-receipt-unsafe'); }
finally { if (fd !== undefined) closeSync(fd); }
}
@@ -0,0 +1,58 @@
import { spawn as nodeSpawn } from 'node:child_process';
import { fileURLToPath } from 'node:url';
import { lstatSync } from 'node:fs';
import { BusError } from './broker.mjs';
const helper = fileURLToPath(new URL('./peercred.py', import.meta.url));
const refused = () => new BusError('peercred-required');
export function createPeerReader({ interpreter, spawn = nodeSpawn, timeout = 1000, stat = lstatSync } = {}) {
try { const s = stat(helper); if (!s.isFile() || s.isSymbolicLink()) throw Error(); }
catch { throw refused(); }
const children = new Set();
let closed = false;
return {
read(socket) {
if (closed || children.size >= 16) return Promise.reject(refused());
return new Promise((resolve, reject) => {
let child, timer, output = '', settled = false, invalid = false;
const finish = (error, value) => {
if (settled) return;
settled = true;
clearTimeout(timer);
error ? reject(refused()) : resolve(value);
};
try {
// Keep this connection's Socket in this closure. Never borrow another pending fd.
child = spawn(interpreter.path, ['-I', '-S', helper],
{ env: {}, stdio: ['ignore', 'pipe', 'pipe', socket] });
children.add(child);
timer = setTimeout(() => { child.kill('SIGKILL'); finish(true); }, timeout);
child.stdout.on('data', data => {
output += data.toString('utf8');
if (Buffer.byteLength(output) > 256) { invalid = true; child.kill('SIGKILL'); finish(true); }
});
child.stderr.on('data', () => { invalid = true; });
child.on('error', () => { children.delete(child); finish(true); });
child.on('close', (code, signal) => {
children.delete(child);
if (settled) return;
try {
if (closed || invalid || code !== 0 || signal) throw Error();
const p = JSON.parse(output);
if (!p || Array.isArray(p) || Object.keys(p).sort().join(',') !== 'gid,pid,uid' ||
!['pid', 'uid', 'gid'].every(k => Number.isSafeInteger(p[k])) || p.pid < 2 || p.uid < 0 || p.gid < 0) throw Error();
finish(false, Object.freeze(p));
} catch { finish(false, {pid:2,uid:0,gid:0}); }
});
} catch { finish(true); }
});
},
async close() {
closed = true;
await Promise.all([...children].map(child => new Promise(resolve => {
child.once('close', resolve);
child.kill('SIGKILL');
})));
},
};
}
@@ -0,0 +1,58 @@
import { spawn as nodeSpawn } from 'node:child_process';
import { fileURLToPath } from 'node:url';
import { lstatSync } from 'node:fs';
import { BusError } from './broker.mjs';
const helper = fileURLToPath(new URL('./peercred.py', import.meta.url));
const refused = () => new BusError('peercred-required');
export function createPeerReader({ interpreter, spawn = nodeSpawn, timeout = 1000, stat = lstatSync } = {}) {
try { const s = stat(helper); if (!s.isFile() || s.isSymbolicLink()) throw Error(); }
catch { throw refused(); }
const children = new Set();
let closed = false;
return {
read(socket) {
if (closed || children.size >= 16) return Promise.reject(refused());
return new Promise((resolve, reject) => {
let child, timer, output = '', settled = false, invalid = false;
const finish = (error, value) => {
if (settled) return;
settled = true;
clearTimeout(timer);
error ? reject(refused()) : resolve(value);
};
try {
// Keep this connection's Socket in this closure. Never borrow another pending fd.
child = spawn(interpreter.path, ['-I', '-S', helper],
{ env: {}, stdio: ['ignore', 'pipe', 'pipe', socket] });
children.add(child);
timer = setTimeout(() => { child.kill('SIGKILL'); finish(true); }, timeout);
child.stdout.on('data', data => {
output += data.toString('utf8');
if (Buffer.byteLength(output) > 256) { invalid = true; child.kill('SIGKILL'); finish(true); }
});
child.stderr.on('data', () => { invalid = true; });
child.on('error', () => { children.delete(child); finish(true); });
child.on('close', (code, signal) => {
children.delete(child);
if (settled) return;
try {
if (closed || invalid || code !== 0 || signal) throw Error();
const p = JSON.parse(output);
if (!p || Array.isArray(p) || Object.keys(p).sort().join(',') !== 'gid,pid,uid' ||
!['pid', 'uid', 'gid'].every(k => Number.isSafeInteger(p[k])) || p.pid < 2 || p.uid < 0 || p.gid < 0) throw Error();
finish(false, Object.freeze(p));
} catch { finish(false, {pid:2,uid:0,gid:0}); }
});
} catch { finish(true); }
});
},
async close() {
closed = true;
await Promise.all([...children].map(child => new Promise(resolve => {
child.once('close', resolve);
child.kill('SIGKILL');
})));
},
};
}
@@ -0,0 +1,15 @@
import {readFileSync,writeFileSync} from 'node:fs';import vm from 'node:vm';import {join} from 'node:path';
const source=readFileSync('agents/gander/work/queue-196/r2/driver.mjs','utf8');
const context=vm.createContext({});vm.runInContext(source.slice(source.indexOf("const p='"),source.indexOf('const hash='))+';globalThis.rows=specs;',context);
const rows=[];
// The mutate functions originate in the VM, so instrument that realm's string methods.
context.audit=[];
vm.runInContext(`for(const method of ['replace','replaceAll']){const original=String.prototype[method];String.prototype[method]=function(target,...rest){const text=String(this);if(typeof target==='string')audit.push({method,target,count:text.split(target).length-1});return original.call(this,target,...rest);};}`,context);
for(const [id,file,description,test,mutate] of context.rows){
context.audit.length=0;const original=readFileSync(join('/mnt/storage/scratch/tmp/g196-tree-tn651z',file),'utf8');
// Force the input primitive to be boxed by the VM realm before mutation.
context.input=original;context.fn=mutate;vm.runInContext('fn(input)',context);
rows.push({id,file,targets:[...context.audit],nonUnique:context.audit.filter(x=>x.count!==1)});
}
writeFileSync('agents/gander/work/queue-196/r2/run3/uniqueness-initial.json',JSON.stringify(rows,null,2)+'\n');
for(const row of rows)if(row.nonUnique.length)console.log(JSON.stringify(row));
@@ -0,0 +1,17 @@
import {readFileSync,writeFileSync} from 'node:fs';import vm from 'node:vm';import {join} from 'node:path';import {createHash} from 'node:crypto';
import {guardMutation} from '../../mutant-guard.mjs';
const root='/mnt/storage/scratch/tmp/g196-tree-tn651z',out=new URL('.',import.meta.url).pathname;
const source=readFileSync('agents/gander/work/queue-196/r2/driver.mjs','utf8');
const context=vm.createContext({});vm.runInContext(source.slice(source.indexOf("const p='"),source.indexOf('const hash='))+';globalThis.rows=specs;',context);
const rows=[];
for(const [id,file,,,mutate] of context.rows){const original=readFileSync(join(root,file),'utf8');const result=guardMutation(original,mutate);rows.push({id,file,targets:result.targets,accepted:true});}
writeFileSync(out+'uniqueness-final.json',JSON.stringify(rows,null,2)+'\n');console.log(rows.length+' definitions pass uniqueness guard; no mutation tests run');
const sha=s=>createHash('sha256').update(s).digest('hex'),pairs=[];
for(const id of ['M5','M25']){
const row=context.rows.find(r=>r[0]===id),original=readFileSync(join(root,row[1]),'utf8');
const old=id==='M5'?original.replace('} catch { finish(true); }','} catch { finish(false, {pid:2,uid:0,gid:0}); }'):original.replaceAll(' | constants.O_NONBLOCK','');
const narrowed=guardMutation(original,row[4]).text;
writeFileSync(out+id+'-old.mjs',old);writeFileSync(out+id+'-narrowed.mjs',narrowed);
pairs.push({id,product:'64539c96b',oldSha256:sha(old),narrowedSha256:sha(narrowed),identical:old===narrowed});
}
writeFileSync(out+'narrowing-sha256.json',JSON.stringify(pairs,null,2)+'\n');console.log(JSON.stringify(pairs,null,2));
@@ -0,0 +1,25 @@
[
{
"count": 0,
"refused": true
},
{
"count": 2,
"refused": true
},
{
"chainedUniqueTargets": [
{
"method": "replace",
"target": "left",
"count": 1
},
{
"method": "replace",
"target": "right",
"count": 1
}
],
"accepted": true
}
]
@@ -0,0 +1,16 @@
[
{
"id": "M5",
"product": "64539c96b",
"oldSha256": "803bd73ccaf0730a7ab69c70d513257484df788fa96c13c3c4ed87664b67c45a",
"narrowedSha256": "803bd73ccaf0730a7ab69c70d513257484df788fa96c13c3c4ed87664b67c45a",
"identical": true
},
{
"id": "M25",
"product": "64539c96b",
"oldSha256": "2668be95c72562a76987ed3cdffdc8ee029ac15bd12eb8b23f4a541eb4c53e28",
"narrowedSha256": "cd20a831fbaecbd1aedcbb634062786099266d0a6196d9b8987706dfd5a6aa1c",
"identical": false
}
]
@@ -0,0 +1,372 @@
[
{
"id": "M1",
"file": "packages/webui/src/serve.mjs",
"targets": [
{
"method": "replace",
"target": "if (tester) return bindTesterSocket(server, testerSocket);",
"count": 1
}
],
"accepted": true
},
{
"id": "M2",
"file": "packages/webui/src/tester-socket.mjs",
"targets": [
{
"method": "replace",
"target": "chmodSync(temporary, 0o600)",
"count": 1
}
],
"accepted": true
},
{
"id": "M3",
"file": "packages/webui/src/serve.mjs",
"targets": [
{
"method": "replace",
"target": "if (tester && (Object.hasOwn(req.headers, 'authorization')",
"count": 1
}
],
"accepted": true
},
{
"id": "M4",
"file": "packages/bus/src/principal.mjs",
"targets": [
{
"method": "replace",
"target": "peer.pid !== proof.pid",
"count": 1
}
],
"accepted": true
},
{
"id": "M5",
"file": "packages/bus/src/peercred.mjs",
"targets": [
{
"method": "replace",
"target": "finish(false, Object.freeze(p));\n } catch { finish(true); }",
"count": 1
}
],
"accepted": true
},
{
"id": "M6",
"file": "packages/bus/src/principal.mjs",
"targets": [
{
"method": "replace",
"target": "peer.uid !== process.getuid()",
"count": 1
}
],
"accepted": true
},
{
"id": "M7",
"file": "packages/webui/src/tester-socket.mjs",
"targets": [
{
"method": "replace",
"target": "(dir.mode & 0o077)",
"count": 1
}
],
"accepted": true
},
{
"id": "M8",
"file": "packages/bus/src/human.mjs",
"targets": [
{
"method": "replace",
"target": "current.env !== null && MARKERS.some",
"count": 1
}
],
"accepted": true
},
{
"id": "M9",
"file": "packages/bus/src/human.mjs",
"targets": [
{
"method": "replace",
"target": "if (again.startTime !== proof.startTime || again.ppid !== p.ppid)",
"count": 1
}
],
"accepted": true
},
{
"id": "M10",
"file": "packages/bus/src/principal.mjs",
"targets": [
{
"method": "replace",
"target": "if (parent.uid !== peer.uid || parent.argv[1] !== resolve(paths.console) || parent.argv[2] !== 'serve')",
"count": 1
}
],
"accepted": true
},
{
"id": "M11",
"file": "packages/bus/src/principal.mjs",
"targets": [
{
"method": "replace",
"target": "import { resolve }",
"count": 1
},
{
"method": "replace",
"target": "parent.argv[1] !== resolve(paths.console)",
"count": 1
}
],
"accepted": true
},
{
"id": "M12",
"file": "packages/bus/src/human.mjs",
"targets": [
{
"method": "replace",
"target": "Object.keys(proof).some((k) => !['pid', 'startTime', 'nonce', 'business'].includes(k))",
"count": 1
}
],
"accepted": true
},
{
"id": "M13",
"file": "packages/bus/src/server.mjs",
"targets": [
{
"method": "replace",
"target": "broker.disconnect(boundCap)",
"count": 1
}
],
"accepted": true
},
{
"id": "M14",
"file": "packages/bus/src/principal.mjs",
"targets": [
{
"method": "replace",
"target": "verifyHuman(checked, { cliPath: paths[kind], launches, readProcess,\n nonceKey: kind === 'user' ? 'MOSAIC_BUS_USER_NONCE' : 'MOSAIC_BUS_CLI_NONCE' })",
"count": 1
}
],
"accepted": true
},
{
"id": "M15",
"file": "scripts/stack-release.sh",
"targets": [
{
"method": "replace",
"target": "RUN_CONSOLE=(\"${without_tester[@]}\" --tester-socket)",
"count": 1
}
],
"accepted": true
},
{
"id": "M16",
"file": "scripts/stack-release.sh",
"targets": [
{
"method": "replace",
"target": "RUN_CONSOLE=(\"${without_tester[@]}\") DROP_TESTER=\"--tester-socket",
"count": 1
}
],
"accepted": true
},
{
"id": "M17",
"file": "packages/bus/src/broker.mjs",
"targets": [
{
"method": "replace",
"target": "if (this.#business(record.business).vars?.['bus.tester'] !== true)",
"count": 1
}
],
"accepted": true
},
{
"id": "M18",
"file": "packages/bus/src/principal.mjs",
"targets": [
{
"method": "replace",
"target": "return { kind: 'user', business, id: proof.user }",
"count": 1
}
],
"accepted": true
},
{
"id": "M19",
"file": "packages/cli/src/tester-http.mjs",
"targets": [
{
"method": "replace",
"target": "socketPath: testerSocketPath(dataRoot)",
"count": 1
}
],
"accepted": true
},
{
"id": "M20",
"file": "packages/bus/src/peercred.mjs",
"targets": [
{
"method": "replace",
"target": "export function createPeerReader",
"count": 1
}
],
"accepted": true
},
{
"id": "M21",
"file": "packages/bus/src/interpreter.mjs",
"targets": [
{
"method": "replace",
"target": "s.uid !== 0 || (s.mode & 0o022)",
"count": 1
}
],
"accepted": true
},
{
"id": "M22",
"file": "packages/bus/src/server.mjs",
"targets": [
{
"method": "replace",
"target": " if (kind) {",
"count": 1
}
],
"accepted": true
},
{
"id": "M23",
"file": "packages/bus/src/interpreter.mjs",
"targets": [
{
"method": "replace",
"target": "export function recordInterpreterStart(directory, record) {",
"count": 1
}
],
"accepted": true
},
{
"id": "M24",
"file": "packages/webui/src/tester-socket.mjs",
"targets": [
{
"method": "replace",
"target": "const temporary = join(parent, '.' + randomBytes(4).toString('hex') + '.s');",
"count": 1
}
],
"accepted": true
},
{
"id": "M25",
"file": "packages/bus/src/interpreter.mjs",
"targets": [
{
"method": "replace",
"target": "constants.O_WRONLY | constants.O_APPEND | constants.O_CREAT | constants.O_NOFOLLOW | constants.O_NONBLOCK, 0o600",
"count": 1
}
],
"accepted": true
},
{
"id": "M26",
"file": "packages/bus/src/peercred.mjs",
"targets": [
{
"method": "replace",
"target": "if (!s.isFile() || s.isSymbolicLink()) throw Error();",
"count": 1
},
{
"method": "replace",
"target": "catch { throw refused(); }",
"count": 1
}
],
"accepted": true
},
{
"id": "M27",
"file": "packages/bus/src/peercred.mjs",
"targets": [
{
"method": "replace",
"target": " await Promise.all([...children].map(child => new Promise(resolve => {\n child.once('close', resolve);\n child.kill('SIGKILL');\n })));",
"count": 1
}
],
"accepted": true
},
{
"id": "M28",
"file": "scripts/stack-release.sh",
"targets": [
{
"method": "replace",
"target": "case \"${without_proof[i]}\" in --send | --tester-port | --tester-socket) break",
"count": 1
}
],
"accepted": true
},
{
"id": "M28b",
"file": "scripts/stack-release.sh",
"targets": [
{
"method": "replace",
"target": "case \"${kept[i]}\" in --send | --tester-port | --tester-socket) break",
"count": 1
}
],
"accepted": true
},
{
"id": "M29",
"file": "scripts/stack-release.sh",
"targets": [
{
"method": "replace",
"target": " node -e 'const fs=require(\"fs\"),p=require(\"path\"),root=process.argv[1],parent=p.join(root,\"console\");if(!p.isAbsolute(root)||Buffer.byteLength(p.join(parent,\"tester.sock\"))>107)process.exit(1);try{const s=fs.lstatSync(parent);if(!s.isDirectory()||s.isSymbolicLink()||s.uid!==process.getuid()||(s.mode&0o077))process.exit(1);}catch(e){if(e.code!==\"ENOENT\")process.exit(1);}' -- \"$DATA\" || check_refuse tester-socket-path \"private tester path is too long or its parent is unsafe\"\n",
"count": 1
}
],
"accepted": true
}
]
@@ -0,0 +1,372 @@
[
{
"id": "M1",
"file": "packages/webui/src/serve.mjs",
"targets": [
{
"method": "replace",
"target": "if (tester) return bindTesterSocket(server, testerSocket);",
"count": 1
}
],
"nonUnique": []
},
{
"id": "M2",
"file": "packages/webui/src/tester-socket.mjs",
"targets": [
{
"method": "replace",
"target": "chmodSync(temporary, 0o600)",
"count": 1
}
],
"nonUnique": []
},
{
"id": "M3",
"file": "packages/webui/src/serve.mjs",
"targets": [
{
"method": "replace",
"target": "if (tester && (Object.hasOwn(req.headers, 'authorization')",
"count": 1
}
],
"nonUnique": []
},
{
"id": "M4",
"file": "packages/bus/src/principal.mjs",
"targets": [
{
"method": "replace",
"target": "peer.pid !== proof.pid",
"count": 1
}
],
"nonUnique": []
},
{
"id": "M5",
"file": "packages/bus/src/peercred.mjs",
"targets": [
{
"method": "replace",
"target": "} catch { finish(true); }",
"count": 2
}
],
"nonUnique": [
{
"method": "replace",
"target": "} catch { finish(true); }",
"count": 2
}
]
},
{
"id": "M6",
"file": "packages/bus/src/principal.mjs",
"targets": [
{
"method": "replace",
"target": "peer.uid !== process.getuid()",
"count": 1
}
],
"nonUnique": []
},
{
"id": "M7",
"file": "packages/webui/src/tester-socket.mjs",
"targets": [
{
"method": "replace",
"target": "(dir.mode & 0o077)",
"count": 1
}
],
"nonUnique": []
},
{
"id": "M8",
"file": "packages/bus/src/human.mjs",
"targets": [
{
"method": "replace",
"target": "current.env !== null && MARKERS.some",
"count": 1
}
],
"nonUnique": []
},
{
"id": "M9",
"file": "packages/bus/src/human.mjs",
"targets": [
{
"method": "replace",
"target": "if (again.startTime !== proof.startTime || again.ppid !== p.ppid)",
"count": 1
}
],
"nonUnique": []
},
{
"id": "M10",
"file": "packages/bus/src/principal.mjs",
"targets": [
{
"method": "replace",
"target": "if (parent.uid !== peer.uid || parent.argv[1] !== resolve(paths.console) || parent.argv[2] !== 'serve')",
"count": 1
}
],
"nonUnique": []
},
{
"id": "M11",
"file": "packages/bus/src/principal.mjs",
"targets": [
{
"method": "replace",
"target": "import { resolve }",
"count": 1
},
{
"method": "replace",
"target": "parent.argv[1] !== resolve(paths.console)",
"count": 1
}
],
"nonUnique": []
},
{
"id": "M12",
"file": "packages/bus/src/human.mjs",
"targets": [
{
"method": "replace",
"target": "Object.keys(proof).some((k) => !['pid', 'startTime', 'nonce', 'business'].includes(k))",
"count": 1
}
],
"nonUnique": []
},
{
"id": "M13",
"file": "packages/bus/src/server.mjs",
"targets": [
{
"method": "replace",
"target": "broker.disconnect(boundCap)",
"count": 1
}
],
"nonUnique": []
},
{
"id": "M14",
"file": "packages/bus/src/principal.mjs",
"targets": [
{
"method": "replace",
"target": "verifyHuman(checked, { cliPath: paths[kind], launches, readProcess,\n nonceKey: kind === 'user' ? 'MOSAIC_BUS_USER_NONCE' : 'MOSAIC_BUS_CLI_NONCE' })",
"count": 1
}
],
"nonUnique": []
},
{
"id": "M15",
"file": "scripts/stack-release.sh",
"targets": [
{
"method": "replace",
"target": "RUN_CONSOLE=(\"${without_tester[@]}\" --tester-socket)",
"count": 1
}
],
"nonUnique": []
},
{
"id": "M16",
"file": "scripts/stack-release.sh",
"targets": [
{
"method": "replace",
"target": "RUN_CONSOLE=(\"${without_tester[@]}\") DROP_TESTER=\"--tester-socket",
"count": 1
}
],
"nonUnique": []
},
{
"id": "M17",
"file": "packages/bus/src/broker.mjs",
"targets": [
{
"method": "replace",
"target": "if (this.#business(record.business).vars?.['bus.tester'] !== true)",
"count": 1
}
],
"nonUnique": []
},
{
"id": "M18",
"file": "packages/bus/src/principal.mjs",
"targets": [
{
"method": "replace",
"target": "return { kind: 'user', business, id: proof.user }",
"count": 1
}
],
"nonUnique": []
},
{
"id": "M19",
"file": "packages/cli/src/tester-http.mjs",
"targets": [
{
"method": "replace",
"target": "socketPath: testerSocketPath(dataRoot)",
"count": 1
}
],
"nonUnique": []
},
{
"id": "M20",
"file": "packages/bus/src/peercred.mjs",
"targets": [
{
"method": "replace",
"target": "export function createPeerReader",
"count": 1
}
],
"nonUnique": []
},
{
"id": "M21",
"file": "packages/bus/src/interpreter.mjs",
"targets": [
{
"method": "replace",
"target": "s.uid !== 0 || (s.mode & 0o022)",
"count": 1
}
],
"nonUnique": []
},
{
"id": "M22",
"file": "packages/bus/src/server.mjs",
"targets": [
{
"method": "replace",
"target": " if (kind) {",
"count": 1
}
],
"nonUnique": []
},
{
"id": "M23",
"file": "packages/bus/src/interpreter.mjs",
"targets": [
{
"method": "replace",
"target": "export function recordInterpreterStart(directory, record) {",
"count": 1
}
],
"nonUnique": []
},
{
"id": "M24",
"file": "packages/webui/src/tester-socket.mjs",
"targets": [
{
"method": "replace",
"target": "const temporary = join(parent, '.' + randomBytes(4).toString('hex') + '.s');",
"count": 1
}
],
"nonUnique": []
},
{
"id": "M25",
"file": "packages/bus/src/interpreter.mjs",
"targets": [
{
"method": "replaceAll",
"target": " | constants.O_NONBLOCK",
"count": 2
}
],
"nonUnique": [
{
"method": "replaceAll",
"target": " | constants.O_NONBLOCK",
"count": 2
}
]
},
{
"id": "M26",
"file": "packages/bus/src/peercred.mjs",
"targets": [
{
"method": "replace",
"target": "if (!s.isFile() || s.isSymbolicLink()) throw Error();",
"count": 1
},
{
"method": "replace",
"target": "catch { throw refused(); }",
"count": 1
}
],
"nonUnique": []
},
{
"id": "M27",
"file": "packages/bus/src/peercred.mjs",
"targets": [
{
"method": "replace",
"target": " await Promise.all([...children].map(child => new Promise(resolve => {\n child.once('close', resolve);\n child.kill('SIGKILL');\n })));",
"count": 1
}
],
"nonUnique": []
},
{
"id": "M28",
"file": "scripts/stack-release.sh",
"targets": [
{
"method": "replace",
"target": "--send | --tester-port | --tester-socket) break",
"count": 2
}
],
"nonUnique": [
{
"method": "replace",
"target": "--send | --tester-port | --tester-socket) break",
"count": 2
}
]
},
{
"id": "M29",
"file": "scripts/stack-release.sh",
"targets": [],
"nonUnique": []
}
]