#!/usr/bin/env python3 """q57_mutation.py -- the committed negative control for check.py. Exit code IS the verdict: 0 = the gate behaves the way its own docstring says on a mutated entry, 1 = it does not. Nothing here is asserted; every cell is a run. python3 wizard-work/null/q57_mutation.py WHY A FIXTURE, AND NOT THE LIVE TREE `python3 check.py` reads whatever is on disk, so running it in the shared checkout grades the worktree and calls the result the commit -- Timmy's own first pass on this artifact made exactly that mistake (reply 06). This harness never touches the live tree. It takes a `git clone --bare` snapshot of it, clones THAT, and mutates only the clone. origin/main inside the fixture is the frozen bare repo, so a concurrent push by another wizard cannot change what the test is measuring. WHERE THE REPO IS Resolved from this file's own path (`git rev-parse --show-toplevel`), so the copy in a clone grades that clone. It used to default to the host path /root/troupe-standup, which meant a clone's copy silently snapshotted the host instead of the tree it sat in -- Q62's class, measured 2026-10-25. NULL_REPO= overrides it, and the path actually used is printed. WHAT IT MEASURES -- eight cases, expectations computed here, never hardcoded case 0 clean clone -> rc 0, ALL CHECKS GREEN case 1 one byte inside a work-file bullet -> rc 1, names that line case 2 the operator line -> rc 1, names that line case 3 the base-commit line -> rc 1, names that line case 4 one line appended -> rc 1, names the line past the end case 5 final newline becomes CRLF -> rc 1, "a line terminator differs", and NO line number is invented case 6 replay in the clone -> the clone's entry is byte-identical, its mtime is untouched, `git status` is empty, and the HOST's entry is untouched (self-location) case 7 the published gate moved on -> rc 1, names check.py, while the entry check still PASSES Case 5 was GREEN before this artifact. Both sides of the old comparison ran under universal-newline translation (subprocess text=True and open(..., encoding=...)), so the CRLF never reached the comparison: a doctored entry read "byte-identical". Case 7 was impossible before: nothing compared the gate on disk with the gate on main, so an entry could be certified by a private build. Case 6 was added 2026-10-25: before it, the builder carried REPO and HERE as constants, so `python3 wizard-work/null/wizard.py` in a clone rewrote the HOST's entry and left the clone alone -- a replay that reproduces nothing is not a replay. Expected line numbers are computed two independent ways and both must agree: by locating the mutated text in the graded bytes, and by a first-difference scan over `graded.split(b"\\n")`. Neither reads the gate's own message. SET NULL_Q57_KEEP=1 to keep the fixture directory for inspection. """ import os import re import shutil import subprocess import sys import tempfile HERE = os.path.dirname(os.path.abspath(__file__)) def _toplevel(start): """The repository root containing `start`, or "" when there is none.""" try: r = subprocess.run(["git", "-C", start, "rev-parse", "--show-toplevel"], capture_output=True, text=True) except OSError: return "" return r.stdout.strip() if r.returncode == 0 else "" REPO = os.environ.get("NULL_REPO") or _toplevel(HERE) LOGREL = "wizard-work/null/wizard.log.md" GATEREL = "wizard-work/null/check.py" BUILDER = "wizard-work/null/wizard.py" PASSED, FAILED = [], [] def sh(args): return subprocess.run(args, capture_output=True) def git(root, *args): return sh(["git", "-C", root] + list(args)) def check(name, ok, detail=""): ok = bool(ok) (PASSED if ok else FAILED).append(name) print(("PASS " if ok else "FAIL ") + name + (" -> " + detail if detail else "")) return ok def line_of(lines, needle): """1-based number of the line containing `needle`, or 0 if it is absent.""" for i, l in enumerate(lines): if needle in l: return i + 1 return 0 def first_diff_scan(want, got): """Independent first-difference scan over raw bytes split on b'\\n'.""" w, g = want.split(b"\n"), got.split(b"\n") for i in range(max(len(w), len(g))): a = w[i] if i < len(w) else None b = g[i] if i < len(g) else None if a != b: return i + 1 return None def main(): print("grading repo: %s" % (REPO or "")) if not REPO: print("CANNOT GRADE: no repository root from %s (set NULL_REPO)" % HERE) return 2 root = tempfile.mkdtemp(prefix="q57-mutation-") bare = os.path.join(root, "origin.git") fx = os.path.join(root, "fixture") logp = os.path.join(fx, LOGREL) gatep = os.path.join(fx, GATEREL) print("fixture root: %s" % root) r = sh(["git", "clone", "--bare", "--quiet", REPO, bare]) if r.returncode != 0: print("CANNOT GRADE cannot snapshot the repo: " + r.stderr.decode("utf-8", "replace")[:200]) return 2 r = sh(["git", "clone", "--quiet", bare, fx]) if r.returncode != 0: print("CANNOT GRADE cannot clone the fixture: " + r.stderr.decode("utf-8", "replace")[:200]) return 2 def run_gate(): p = subprocess.run([sys.executable, gatep], capture_output=True, text=True) return p.returncode, (p.stdout or "") + (p.stderr or "") graded = git(fx, "show", "origin/main:" + LOGREL).stdout text = graded.decode("utf-8") lines = text.splitlines() if not graded or not lines: print("FAIL the fixture has no graded entry to mutate") return 1 # ---- case 0: the fixture is clean and the gate is green on it --------- disk = open(logp, "rb").read() pre = check("fixture precondition: disk entry == the blob the gate grades", disk == graded, "%d bytes" % len(graded)) rc, out = run_gate() check("case 0 clean clone exits 0", rc == 0 and "ALL CHECKS GREEN" in out, "rc %d, last line %r" % (rc, out.strip().splitlines()[-1] if out.strip() else "")) if not pre: print("\nFAILED: the fixture is not clean; no mutation result is meaningful") return 1 def reset_log(): with open(logp, "wb") as fh: fh.write(graded) def case(label, mutated, expect_line, needles=()): """Write `mutated`, run the gate, and require it to name `expect_line`.""" with open(logp, "wb") as fh: fh.write(mutated) rc, out = run_gate() named = re.search(r"line (\d+) differs", out) ok = (rc == 1 and "ALL CHECKS GREEN" not in out and expect_line is not None and named is not None and int(named.group(1)) == expect_line and all(n in out for n in needles)) check(label, ok, "rc %d, gate named line %s, expected %s" % (rc, named.group(1) if named else "nothing", expect_line)) if not ok: print(" gate output:\n" + "\n".join(" " + l for l in out.strip().splitlines())) return ok # ---- case 1: one byte inside a data line ----------------------------- needle1 = b"arguments, not the clock" i1 = line_of(lines, needle1.decode()) m1 = list(graded.split(b"\n")) m1[i1 - 1] = m1[i1 - 1].replace(b"arguments", b"argumentz") mutated1 = b"\n".join(m1) check("case 1 expectation cross-check: needle line == byte-scan line", i1 > 0 and i1 == first_diff_scan(graded, mutated1), "line %d" % i1) case("case 1 one byte inside a work-file bullet is named by line", mutated1, i1, needles=("graded=", "disk=")) # ---- case 2: the operator line --------------------------------------- reset_log() needle2 = b"- operator: " i2 = line_of(lines, needle2.decode()) m2 = list(graded.split(b"\n")) m2[i2 - 1] = m2[i2 - 1].replace(b"null", b"nobody-at-all") mutated2 = b"\n".join(m2) check("case 2 expectation cross-check: needle line == byte-scan line", i2 > 0 and i2 == first_diff_scan(graded, mutated2), "line %d" % i2) case("case 2 a doctored operator line is named by line", mutated2, i2) # ---- case 3: the base-commit line ------------------------------------ reset_log() needle3 = b"- base commit: " i3 = line_of(lines, needle3.decode()) m3 = list(graded.split(b"\n")) m3[i3 - 1] = re.sub(rb"(?<=- base commit: )[0-9a-f]+", b"deadbeef", m3[i3 - 1]) mutated3 = b"\n".join(m3) check("case 3 expectation cross-check: needle line == byte-scan line", i3 > 0 and i3 == first_diff_scan(graded, mutated3), "line %d" % i3) case("case 3 a doctored base commit is named by line", mutated3, i3) # ---- case 4: one line appended --------------------------------------- reset_log() mutated4 = graded + b"- extra: a line no writer produced\n" i4 = len(lines) + 1 check("case 4 expectation cross-check: appended line == byte-scan line", i4 == first_diff_scan(graded, mutated4), "line %d" % i4) case("case 4 an appended line is named, and the graded side reads ", mutated4, i4, needles=("",)) # ---- case 5: a line terminator, and no line to name ------------------- reset_log() mutated5 = graded[:-1] + b"\r\n" with open(logp, "wb") as fh: fh.write(mutated5) rc, out = run_gate() check("case 5 a CRLF mutation is a failure, not a PASS", rc == 1 and "ALL CHECKS GREEN" not in out, "rc %d" % rc) check("case 5 every line is equal, so no line number is invented", "line terminator" in out and re.search(r"line \d+ differs", out) is None, "reported as a terminator") check("case 5 the byte count is printed, so the 1-byte delta is visible", "%d bytes" % len(graded) in out and "%d bytes" % len(mutated5) in out) # ---- case 6: a replay in the clone reproduces it and touches nothing --- # Before 2026-10-25 the builder held REPO and HERE as constants, so this # exact run rewrote the HOST's entry and left the clone alone: mtime moved # at /root/troupe-standup, the clone's file never opened. Both halves are # measured here -- the clone's bytes and mtime, and the host's. reset_log() host_log = os.path.join(REPO, LOGREL) clone_before = open(logp, "rb").read() mtime_before = os.stat(logp).st_mtime_ns host_before = open(host_log, "rb").read() host_mtime = os.stat(host_log).st_mtime_ns p = subprocess.run([sys.executable, os.path.join(fx, BUILDER)], cwd=fx, capture_output=True, text=True) clone_after = open(logp, "rb").read() mtime_after = os.stat(logp).st_mtime_ns host_after = open(host_log, "rb").read() status = git(fx, "status", "--porcelain").stdout.decode("utf-8", "replace").strip() check("case 6 the fixture's builder exits 0", p.returncode == 0, "rc %d" % p.returncode) check("case 6 the replay reproduces the entry byte-for-byte", clone_after == clone_before, "%d bytes" % len(clone_after) if clone_after == clone_before else "clone entry changed: %d -> %d bytes" % (len(clone_before), len(clone_after))) check("case 6 the replay opens no file for writing (mtime unchanged)", mtime_after == mtime_before, "mtime %d" % mtime_after if mtime_after == mtime_before else "mtime moved %d -> %d" % (mtime_before, mtime_after)) check("case 6 the worktree is clean after the replay", status == "", "clean" if status == "" else status.splitlines()[0]) check("case 6 the HOST's entry is untouched: the builder grades its own checkout", host_after == host_before and os.stat(host_log).st_mtime_ns == host_mtime, "host %s untouched" % LOGREL if host_after == host_before and os.stat(host_log).st_mtime_ns == host_mtime else "the host's entry was written by a clone-side replay") # ---- case 7: the published gate has moved on -------------------------- reset_log() m = re.search(r"^- base commit: ([0-9a-f]{40})$", text, re.M) if not m: check("case 7 the entry names a 40-hex base commit", False, "no base commit line") else: named = m.group(1) with open(gatep, "ab") as fh: fh.write(b"\n# fixture: a later commit on main changed this file\n") git(fx, "-c", "user.name=null", "-c", "user.email=null@agents.invalid", "commit", "-aqm", "fixture: publish a gate that moved on") push = git(fx, "push", "--quiet", "origin", "HEAD:main") check("case 7 fixture: the frozen origin advanced past the named commit", push.returncode == 0, "origin/main is now %s" % git(fx, "rev-parse", "HEAD").stdout.decode().strip()[:12]) # Put the GRADED gate back on disk: disk == named commit's blob (so the # named-commit check still passes) but != the published blob. with open(gatep, "wb") as fh: fh.write(git(fx, "show", "%s:%s" % (named, GATEREL)).stdout) rc, out = run_gate() check("case 7 a gate that main does not carry is refused", rc == 1 and "FAIL the gate on disk is the gate published on the remote main" in out, "rc %d" % rc) check("case 7 isolation: the entry itself is still byte-identical on main", "FAIL entry bytes are the blob on the remote main" not in out and "PASS entry bytes are the blob on the remote main" in out, "only the published-gate cell moved") print("\n%d passed, %d failed" % (len(PASSED), len(FAILED))) if os.environ.get("NULL_Q57_KEEP") != "1": shutil.rmtree(root, ignore_errors=True) else: print("fixture kept at %s" % root) if FAILED: print("FAILED: " + ", ".join(FAILED)) return 1 print("MUTATION CONTROL GREEN") return 0 if __name__ == "__main__": sys.exit(main())