45 lines
3.3 KiB
Python
45 lines
3.3 KiB
Python
#!/usr/bin/env python3
|
|
# Row 271 mutants M1-M14 (BUILD.md "Mutants", lines at e567f949c; M14 is r3's). `apply <id>` edits the
|
|
# worktree and prints the touched path; each edit asserts its anchor appears exactly once.
|
|
import sys
|
|
WT = "/mnt/storage/scratch/gizmo-270/"
|
|
B = "packages/bus/src/broker.mjs"
|
|
L = "packages/cli/src/launcher.mjs"
|
|
M = {
|
|
"M1": (B, " this.#sessionFence(s.session);\n if (this.#sessionHolder(s.session)?.op === 'claim') fail('thread-already-held');",
|
|
" if (this.#sessionHolder(s.session)?.op === 'claim') fail('thread-already-held');"),
|
|
"M2": (B, " // Row 271 (264d, D7 step 1): nor sent to, by name or as the default.\n this.#sessionFence(session);\n",
|
|
" // Row 271 (264d, D7 step 1): nor sent to, by name or as the default.\n"),
|
|
"M3": (B, " // Row 271 (264d, D7 step 1): a session being cleared, or a retired one, isn't opened.\n this.#sessionFence(session);\n",
|
|
" // Row 271 (264d, D7 step 1): a session being cleared, or a retired one, isn't opened.\n"),
|
|
"M4": (B, " this.#processingWork();\n this.#sessionFence(session);\n if (this.#revision(session) !== a.revision)",
|
|
" this.#processingWork();\n if (this.#revision(session) !== a.revision)"),
|
|
"M5": (B, " if (!this.#opRow(open.thread, open.op, 'drained')) this.#appendOp(open, 'drained', { run: s.run, generation: this.#runGeneration(s) });\n return [];",
|
|
" return [];"),
|
|
"M6": (B, " if (open?.stage === 'requested') this.#appendOp(open, 'drained', { run: session.run, generation: h.generation });\n", ""),
|
|
"M7": (B, " if (this.#sessionHolder(session)?.op !== 'claim') this.#appendOp(op, 'drained');",
|
|
" if (false && this.#sessionHolder(session)?.op !== 'claim') this.#appendOp(op, 'drained');"),
|
|
"M8": (L, " if (survivors.some((x) => x.business === b.id && x.run === c.run && liveRun(x))) return;\n", ""),
|
|
"M9": (L, 'const CLEAR_HELD = new Set(["capacity-full", "limit-reached"]);', 'const CLEAR_HELD = new Set([]);'),
|
|
"M10": (B, "\n AND NOT EXISTS(SELECT 1 FROM message_cancels x WHERE x.message=m.id)) AS pending,", ") AS pending,"),
|
|
"M11": (L, '} else if (stage === "drained" && now - clearStops', '} else if (true && now - clearStops'),
|
|
"M12": (B, " const refusal = this.#ownerRefusal(t);", " const refusal = null;"),
|
|
"M13": (B, "this.#granted({ ...s, grants: this.#userGrants(s) }, 'session.clear', t.project, t.instance)",
|
|
"this.#granted({ ...s, grants: this.#userGrants(s) }, t.project, t.instance)"),
|
|
"M14": (L, " try {\n await (start ? clearStart(c, legacyThreads) : clearStop(c, now));\n } catch (e) {\n clearLog(c.op, e.code ?? e.message, `clear ${c.op} (session ${c.session}): ${e.code ?? e.message}`);\n }\n",
|
|
" await (start ? clearStart(c, legacyThreads) : clearStop(c, now));\n"),
|
|
}
|
|
cmd = sys.argv[1]
|
|
if cmd == "list":
|
|
print(" ".join(M)); sys.exit(0)
|
|
if cmd == "check":
|
|
for k, (f, a, b) in M.items():
|
|
n = open(WT + f).read().count(a)
|
|
print(k, f, n)
|
|
sys.exit(0)
|
|
f, a, b = M[sys.argv[2]]
|
|
s = open(WT + f).read()
|
|
assert s.count(a) == 1, (sys.argv[2], s.count(a))
|
|
open(WT + f, "w").write(s.replace(a, b))
|
|
print(f)
|