Files
stack/agents/darkwing/work/queue-117/r1/mutants.py
T
jason.woltjeandClaude Opus 5.5 17d801f482 work: row 117 round 1 packet, fetch a clone on another branch or dirty (#1611)
Candidate manifest, patch against 559ef2287, build notes, five killed
mutants and the targeted gate (seat, cli, harness, two scripts).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-14 12:31:50 -05:00

68 lines
3.3 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 117 (#1611): the brief's five mutants of the fetched outcome, one per check.
# m1 fetches for a third reason: a failed status becomes a fetched reason.
# m2 merges after the fetch in a fetched clone.
# m3 drops the fetch for a fetched clone.
# m4 reports the clone's HEAD as the origin commit.
# m5 fetches before the gitlink check (and so before the root checks too).
# Each runs the FULL seat suite (node --test tests/*.test.mjs in packages/seat)
# and restores the source from the .orig copy whatever happens.
# Usage: mutants.py <worktree> <log dir>
import os, shutil, subprocess, sys, signal
WT, LOGS = sys.argv[1], sys.argv[2]
SRC = 'packages/seat/src/checkout.mjs'
FETCH = '[...inClone(dest), "fetch", "-q", "--no-tags", "--no-recurse-submodules", "origin"]'
MERGE = '[...inClone(dest), "merge", "-q", "--ff-only", "--no-edit", `refs/remotes/origin/${at.branch}`]'
MUTANTS = {
'm1': (SRC,
' if (!status.ok) return { outcome: "kept", reason: "status-failed" };\n',
' if (!status.ok) reason = "status-failed";\n'),
'm2': (SRC,
' if (reason) {\n',
f' if (reason) {{\n await g({MERGE});\n'),
'm3': (SRC,
f' if (!(await g({FETCH})).ok)',
f' if (!reason && !(await g({FETCH})).ok)'),
'm4': (SRC,
'origin: { branch: at.branch, commit: origin.ok ? origin.out.trim() : null } };',
'origin: { branch: at.branch, commit: before } };'),
'm5': (SRC,
' // ls-files reads only the index: no filter, hook or submodule runs.\n',
f' await g({FETCH});\n // ls-files reads only the index: no filter, hook or submodule runs.\n'),
}
os.makedirs(LOGS, exist_ok=True)
env = dict(os.environ, TMPDIR=os.path.expanduser('~/darkwing-scratch/r117/tmp'))
for name, (rel, cur, new) in MUTANTS.items():
src = os.path.join(WT, rel)
text = open(src).read()
if text.count(cur) != 1:
sys.exit(f'STOP {name}: the target text in {rel} is not unique or has moved')
if os.path.exists(src + '.orig'):
sys.exit(f'STOP {rel}.orig already exists')
log_path = os.path.join(LOGS, f'mutant-{name}.log')
shutil.copy2(src, src + '.orig')
try:
open(src, 'w').write(text.replace(cur, new))
with open(log_path, 'w') as out:
p = subprocess.Popen('node --test tests/*.test.mjs', shell=True, cwd=os.path.join(WT, 'packages/seat'),
stdout=out, stderr=subprocess.STDOUT, env=env, start_new_session=True)
try:
rc = p.wait(timeout=600)
except subprocess.TimeoutExpired:
os.killpg(p.pid, signal.SIGKILL)
p.wait()
rc = 'timeout'
finally:
shutil.move(src + '.orig', src)
restored = open(src).read() == text
log = open(log_path).read()
counts = [l for l in log.splitlines() if l.startswith(('ℹ pass', 'ℹ fail', 'ℹ skipped'))]
failed = [l.strip() for l in log.splitlines() if l.lstrip().startswith('✖') and 'failing tests' not in l]
print(f'mutant {name} rc={rc} {" ".join(counts)} restored={restored}')
for f in sorted(set(failed)):
print(' ' + f)
print('KILLED' if rc != 0 else 'SURVIVED')
if not restored:
sys.exit(f'STOP {rel} was not restored')