Files
jason.woltje 6bad02612a lead: commit dewey's untracked evidence (721 files: queue-124-review queue-143 queue-149 queue-165-review queue-170 queue-175 queue-177 queue-184 queue-191)
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:14 -06:00

60 lines
4.8 KiB
Python

# Row 149 (#1643) mutants: one per new check. Each edits one file in the worktree, the test files
# that cover row 149 run per package, and the file is restored afterwards.
import subprocess, os
W = os.path.expanduser('~/dewey-scratch/r149')
OUT = os.path.expanduser('~/dewey-scratch/r149-mut')
os.makedirs(OUT, exist_ok=True)
TOOLS = 'packages/harness/src/tools.mjs'
SR, MG = 'roles/security-reviewer.json', 'roles/merge-gate.json'
PROACTIVE = 'Within your grants, act on what you see without waiting to be asked, and\nraise a decision or send a message for anything outside them.\n\n'
ROUTING = ("Where a raise goes (PRD 1.5 REQ-DEC-2): a cross-role raise, or a gated\nraise that cites the project's current spec commit, goes to the\n"
"business's arbiter for its domain. Pass `domain` to `raise_decision`,\n`technical` or `delivery`; leaving it out means `delivery`. An uncited\n"
"gated raise, and every hard wait, goes to the human through the inbox.\n")
SR_MSG = ',\n "messaging": {\n "sendTo": ["human", "chief-of-staff", "pm", "cto", "coder"],\n "receiveFrom": ["human", "chief-of-staff", "pm", "cto", "coder"]\n }'
MG_MSG = ',\n "messaging": {\n "sendTo": ["human", "chief-of-staff", "pm", "cto"],\n "receiveFrom": ["human", "chief-of-staff", "pm", "cto"]\n }'
M = {
'T1-domain-param': (TOOLS, ' domain: str("The arbiter domain for a routed raise: technical or delivery. Leaving it out means delivery", { enum: ["technical", "delivery"] }),\n', ''),
'T2-domain-enum': (TOOLS, '{ enum: ["technical", "delivery"] }', '{ enum: ["technical", "delivery", "human"] }'),
'T3-domain-desc': (TOOLS, 'Leaving it out means delivery"', 'Optional"'),
'T4-raise-desc': (TOOLS, "A cross-role raise, or a gated raise citing the project's current spec commit, goes to the business's arbiter for its domain; an uncited gated raise or a hard wait goes to the human. ", ''),
'S1-sr-bash': (SR, '"tools": ["read", "grep", "find", "ls"]', '"tools": ["read", "grep", "find", "ls", "bash"]'),
'S2-sr-send': (SR, '"withinRole": ["review.verdict"]', '"withinRole": ["review.verdict", "message.send"]'),
'S3-sr-messaging': (SR, SR_MSG, ''),
'G1-mg-within': (MG, '"withinRole": [],\n "crossRole": ["git.merge.protected"]', '"withinRole": ["git.merge.protected"],\n "crossRole": []'),
'G2-mg-extra-cross': (MG, '"crossRole": ["git.merge.protected"]', '"crossRole": ["git.merge.protected", "task.reassign"]'),
'G3-mg-edit': (MG, '"tools": ["read", "grep", "find", "ls"]', '"tools": ["read", "grep", "find", "ls", "edit"]'),
'G4-mg-no-cto': (MG, '"receiveFrom": ["human", "chief-of-staff", "pm", "cto"]', '"receiveFrom": ["human", "chief-of-staff", "pm"]'),
'G5-mg-messaging': (MG, MG_MSG, ''),
'G6-mg-send': (MG, '"withinRole": []', '"withinRole": ["message.send"]'),
'H1-header': ('roles/merge-gate.md', '# Role contract: merge-gate\n', '# Merge gate\n'),
'P1-proactive-gone': ('roles/reviewer.md', PROACTIVE, ''),
'P2-proactive-outside': ('roles/coder.md', PROACTIVE, '## Elsewhere\n\n' + PROACTIVE),
'R1-routing-gone': ('roles/chief-of-staff.md', ROUTING, ''),
'R2-hard-wait': ('roles/pm.md', '`deploy`', '`git.merge.protected`'),
'R3-old-text': ('roles/pm.md', 'raise a decision and wait for', 'raise a decision for the human and wait for'),
}
FILES = [
('packages/business', ['tests/workflow-roles.test.mjs', 'tests/role.test.mjs', 'tests/assistant.test.mjs', 'tests/record-grants.test.mjs']),
('packages/bus', ['tests/workflow-roles.test.mjs', 'tests/csuite-messaging.test.mjs']),
('packages/harness', ['tests/raise-domain.test.mjs', 'tests/tools.test.mjs', 'tests/spec-tools.test.mjs']),
]
env = dict(os.environ, TMPDIR=os.path.expanduser('~/dewey-scratch/tmp'))
origs = {f: open(os.path.join(W, f)).read() for f in {v[0] for v in M.values()}}
try:
for name, (f, a, b) in M.items():
assert origs[f].count(a) == 1, name
for name, (f, a, b) in M.items():
open(os.path.join(W, f), 'w').write(origs[f].replace(a, b))
killed, log = [], ''
for pkg, tests in FILES:
r = subprocess.run(['node', '--test', *tests], cwd=os.path.join(W, pkg), env=env, capture_output=True, text=True, timeout=300, start_new_session=True)
log += f'== {pkg} rc={r.returncode}\n' + r.stdout + r.stderr
fails = sorted({l[2:].split(' (')[0] for l in r.stdout.splitlines() if l.startswith('✖ ') and 'failing tests' not in l})
if r.returncode != 0: killed.append(f'{pkg.split("/")[1]}: ' + '; '.join(fails))
open(os.path.join(W, f), 'w').write(origs[f])
open(os.path.join(OUT, f'{name}.log'), 'w').write(log)
print(name, 'KILLED' if killed else 'SURVIVED', '|', ' | '.join(killed)[:700], flush=True)
finally:
for f, s in origs.items(): open(os.path.join(W, f), 'w').write(s)
print('restored', all(open(os.path.join(W, f)).read() == s for f, s in origs.items()))