Files
jason.woltje 068d868a99 lead: commit rocko's untracked evidence (4471 files: queue-124 queue-129 queue-171 queue-178 queue-280 queue-31 queue-84 queue-85 queue-94)
Unclaimed files left in the canonical checkout. Inventory: canonical-cleanup-inventory.md (commit-as-evidence groups). detect-secrets scan clean on 2026-11-02: hits are sha256 pins, git object ids, test sentinels already in tracked tests and unit-file lines.
2026-11-02 15:05:15 -06:00

34 lines
2.0 KiB
Python

# Row 84 mutants: each edit applied alone to <tree>, the chief-of-staff
# tests run, the file restored. Usage: python3 mutants.py <tree>
import subprocess, shutil, sys
W=sys.argv[1] # the tree with the candidate applied
R='roles/chief-of-staff.json'
B='packages/business/src/business.mjs'
M=[
('tools + write', R, '"ls"]', '"ls", "write"]'),
('tools + bash', R, '"ls"]', '"ls", "bash"]'),
('tools drop ls', R, ', "ls"]', ']'),
('network open', R, '"network": "api-only"', '"network": "open"'),
('network none', R, '"network": "api-only"', '"network": "none"'),
('withinRole + task.create', R, '["message.send"]', '["message.send", "task.create"]'),
('withinRole + role.launch', R, '["message.send"]', '["message.send", "role.launch"]'),
('withinRole empty', R, '["message.send"]', '[]'),
('crossRole + task.priority.change', R, '"crossRole": []', '"crossRole": ["task.priority.change"]'),
('credentials + gitea', R, '"credentials": []', '"credentials": [{ "service": "gitea", "scopes": ["read:issue"] }]'),
('instance may carry authority', B, '["definition", "holder", "vars", "tracker", "credentials"], at', '["definition", "holder", "vars", "tracker", "credentials", "authority"], at'),
('launch.by unchecked', B, 'if (!launcher.authority.withinRole.includes("role.launch")) {', 'if (false) {'),
('credential map unchecked', B, "if (names.join(\",\") !== wanted.join(\",\")) {", 'if (false) {'),
]
res=[]
for name,f,a,b in M:
p=f'{W}/{f}'; s=open(p).read()
if s.count(a)!=1: res.append(f'NOMATCH {name} ({s.count(a)})'); continue
shutil.copy(p,p+'.bak'); open(p,'w').write(s.replace(a,b))
try:
r=subprocess.run(['node','--test','tests/chief-of-staff.test.mjs'],cwd=f'{W}/packages/business',capture_output=True,text=True,timeout=300)
fails=[l for l in r.stdout.splitlines() if l.startswith('✖') and 'failing tests' not in l]
res.append(f"{'KILLED' if r.returncode else 'SURVIVED'} {name}: {len(set(fails))} failing")
finally:
shutil.move(p+'.bak',p)
print('\n'.join(res))