Files
stack/agents/darkwing/work/queue-50-review/r1/mut/mutate.py
T
jason.woltjeandClaude Opus 5.5 5a55109d89 review: row 50 round 1, approve (darkwing)
Packet for #1536 comment 27055: suites, 13 mutants, review notes.

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

42 lines
2.9 KiB
Python

# mutate.py <id>: apply one named mutant (each edit exact text, must match once). Run from the tree root.
import sys
C = "packages/conversation/"
CT = C + "src/controller.mjs"
CO = C + "src/cohort.mjs"
RELSTOP = (CT, " await this.#releaseScope(\"force-stop\", proven);\n", "")
RELCLOSE = (CT, " if (this.b?.state === \"stopped\" && this.#stopped(this.stops.get(this.b.stop))) await this.#releaseScope(\"close\");\n", "")
GUARD = " if (!rec || rec.state !== \"stopped\" || rec.proof?.kind !== \"cohortProof\" || !rec.shim) return null;\n"
M = {
"norelstop": [RELSTOP],
"norelclose": [RELCLOSE],
"norel": [RELSTOP, RELCLOSE],
# releaseCohort reports the unit absent without looking.
"nowait": [(CO, " const end = Date.now() + waitMs;\n", " return { outcome: \"released\", unit: \"absent\" };\n const end = Date.now() + waitMs;\n")],
# releaseCohort doesn't wait for systemd at all, and says so.
"wait0": [(CO, "shimSocket, waitMs = 3000 })", "shimSocket, waitMs = 0 })")],
# #releaseScope keeps only the shim check; callers unchanged.
"noguard": [(CT, GUARD, " if (!rec || !rec.shim) return null;\n")],
# close releases whenever the binding reads stopped, with no #stopped check.
"closenoproof": [(CT, " if (this.b?.state === \"stopped\" && this.#stopped(this.stops.get(this.b.stop))) await", " if (this.b?.state === \"stopped\") await")],
# The release result isn't pushed to observers.
"nopush": [(CT, " this.#push({ kind: \"evidence\", evidence: entry });\n", "")],
# The release result isn't recorded in evidence.releases.
"noevid": [(CT, " this.evidence.releases.push(entry);\n", "")],
# releaseCohort drops the null-ID check.
"invnull": [(CO, "if (!invocationId || hello.invocationId !== invocationId)", "if (hello.invocationId !== invocationId)")],
# releaseCohort sends release with no hello and no ID check.
"nohello": [(CO, " const hello = await shimRequest(shimSocket, \"hello\");\n if (!hello.ok) return { outcome: \"unavailable\", reason: hello.unavailable };\n if (!invocationId || hello.invocationId !== invocationId) return { outcome: \"unavailable\", reason: \"the shim does not answer for the recorded scope; nothing released\" };\n", "")],
# The force stop releases before the claim records stopped (guard intact).
"early": [RELSTOP, (CT, " let session = null;\n try {\n session = this.#readSession();", " await this.#releaseScope(\"force-stop\", this.claim);\n let session = null;\n try {\n session = this.#readSession();")],
# N2: killShims signals any unit.
"n2": [(C + "tests/harness.mjs", " if (!/^mosaic-chat-/.test(s.unit ?? \"\")) {\n", " if (false) {\n")],
}
if "--files" in sys.argv:
print(" ".join(sorted({f for f, _, _ in M[sys.argv[1]]}))); sys.exit(0)
for f, old, new in M[sys.argv[1]]:
s = open(f).read()
n = s.count(old)
if n != 1: sys.exit(f"{sys.argv[1]}: {n} matches in {f}")
open(f, "w").write(s.replace(old, new))
print(f)