Files
stack/agents/darkwing/work/queue-118/r1/mutants.py
T
jason.woltjeandClaude Opus 5.5 5a68df7275 agents: darkwing row 118 round 1 packet (#1612)
SAFE in packages/seat/src/checkout.mjs adds maintenance.auto=false and
gc.auto=0; probe, tests, mutants m1-m3 (all killed), targeted gate
(seat 132/0, cli 184/0) and the leftover sweep. Candidate is build.patch
against 2727dd3ec; manifest digests check out.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-14 14:41:09 -05:00

72 lines
3.0 KiB
Python
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""Row 118 mutants: drop each new SAFE key, and both. Each edits checkout.mjs,
runs packages/seat/tests/checkout.test.mjs, and restores the file from .orig."""
import hashlib, os, re, shutil, signal, subprocess, sys
WT = os.path.expanduser('~/darkwing-scratch/r118/wt')
PKT = os.path.expanduser('~/darkwing-scratch/r118/pkt')
TMP = os.path.expanduser('~/darkwing-scratch/r118/tmp')
F = 'packages/seat/src/checkout.mjs'
MA = ' "-c", "maintenance.auto=false",\n'
GC = ' "-c", "gc.auto=0",\n'
M = [
('m1-drop-maintenance-auto', [MA]),
('m2-drop-gc-auto', [GC]),
('m3-drop-both', [MA, GC]),
]
def sha(p):
return hashlib.sha256(open(p, 'rb').read()).hexdigest()
# A detached `maintenance run` a mutant started runs in a test's temp dir;
# kill only those, by cwd under this row's TMPDIR.
def sweep():
left = []
for pid in filter(str.isdigit, os.listdir('/proc')):
try:
if os.readlink(f'/proc/{pid}/cwd').startswith(TMP + '/'):
left.append(int(pid)); os.kill(int(pid), signal.SIGKILL)
except OSError:
pass
return left
only = set(sys.argv[1:])
os.chdir(WT)
env = dict(os.environ, TMPDIR=TMP, NO_COLOR='1')
base = sha(F)
os.makedirs(os.path.join(PKT, 'mutants'), exist_ok=True)
log = open(os.path.join(PKT, 'mutants-run.log'), 'a')
for name, drops in M:
if only and name not in only:
continue
src = open(F).read()
if any(src.count(d) != 1 for d in drops):
print(f'{name}: pattern not found once, skipped', file=log, flush=True); print(name, 'BAD PATTERN'); continue
shutil.copy2(F, F + '.orig')
try:
out = src
for d in drops:
out = out.replace(d, '')
open(F, 'w').write(out)
p = subprocess.Popen(['node', '--test', 'tests/checkout.test.mjs'], cwd='packages/seat', stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, env=env, start_new_session=True, text=True)
try:
res, _ = p.communicate(timeout=600)
except subprocess.TimeoutExpired:
os.killpg(p.pid, signal.SIGKILL); res, _ = p.communicate(); res += '\nTIMEOUT\n'
open(os.path.join(PKT, 'mutants', f'mutant-{name}.log'), 'w').write(res)
fails = sorted({l[2:] for l in res.splitlines() if l.startswith('✖ ') and l != '✖ failing tests:'})
tally = dict(re.findall(r'^ℹ (pass|fail) (\d+)$', res, re.M))
verdict = 'killed' if p.returncode != 0 else 'SURVIVED'
print(f'{name}: {verdict} (rc {p.returncode}, pass {tally.get("pass", "?")}, fail {tally.get("fail", "?")})', file=log, flush=True)
for l in fails:
print(f' fail: {l}', file=log, flush=True)
left = sweep()
if left:
print(f' swept {len(left)} leftover process(es) under TMPDIR: {left}', file=log, flush=True)
print(name, verdict, tally, flush=True)
finally:
shutil.move(F + '.orig', F)
assert sha(F) == base, f'{F} not restored'
print('restored:', sha(F) == base, file=log, flush=True)