tools/inspect_tree.py (249 B, /root-pinned TSV slicer) red seven rows
across selftest_sweep, write_probe c7 and tool_map at 43af771. Retired at
9d15294; this lands the record, the three-leg verifier behind CHECK-q134
(absence, contract, mutant clone) and the re-rendered index.
Measured at HEAD: CHECK-q134 3/3 rc 0; blob-restored clone 2 faults rc 1;
selftest_sweep 23 tools 23 OK; write_probe 15/15; verify 10/10.
182 lines
8.3 KiB
Python
182 lines
8.3 KiB
Python
#!/usr/bin/env python3
|
|
"""q134_verify.py -- grade the retirement of `tools/inspect_tree.py`.
|
|
|
|
WHY THIS EXISTS
|
|
Q134: sol's `93fa377` committed an 8-line scoping script into `tools/`, the one
|
|
directory where every tracked `.py` must be a graded instrument. Measured at
|
|
`43af771`, that single file red the repo gate in two legs and two instruments'
|
|
own selftests -- five rows from one 249-byte file:
|
|
|
|
selftest_sweep `inspect_tree.py NO_SELFTEST_FLAG no "--selftest" in source`
|
|
selftest_sweep `tool_map.py SELFTEST_FAILED 22/23 (docs/TOOLS.md drift)`
|
|
selftest_sweep `write_probe.py SELFTEST_FAILED 14/15 (c7 table vs tree)`
|
|
write_probe `FAULT inspect_tree.py NO_PROBE no write probe in the table`
|
|
tool_map `FAIL HEAD: docs/TOOLS.md is the render of this tree`
|
|
|
|
The repair retired the file out of the graded namespace and kept its bytes
|
|
reachable: blob `3fea636f` at `93fa377`, sha256 `9e81ec9f`, copied to
|
|
/root/.hermes/wizard-outputs/volt/2026-10-31-q134/inspect_tree.py.retired.
|
|
A retirement that cannot be re-read is a deletion, so leg 1 grades the blob as
|
|
well as the absence.
|
|
|
|
WHAT IT GRADES -- three legs, each a reading rather than an assertion
|
|
absence `tools/inspect_tree.py` is not in `git ls-tree HEAD tools/`, and
|
|
blob `3fea636f` still resolves in this repository -- the file is
|
|
retired, not lost.
|
|
contract `tools/write_probe.py --selftest` in the graded tree exits 0. Its c7
|
|
is the cell that was red: the probe table must name every tracked
|
|
tool under `tools/`, exactly. This is also the cheapest statement of
|
|
the invariant the rogue file broke -- every `tools/*.py` is graded.
|
|
mutant a clone of the graded tree with the retired blob written back and
|
|
committed reads rc 1 from the same `--selftest`, with c7 naming
|
|
`inspect_tree.py`. Without this leg the first two would be green on a
|
|
tree where nothing can go red -- the class Q117 filed.
|
|
|
|
The graded tree is only read. Legs 1 and 3 write inside a TemporaryDirectory.
|
|
|
|
USAGE
|
|
python3 wizard-work/volt/q134_verify.py [--repo DIR] [--verbose]
|
|
EXIT
|
|
0 every leg as expected; 1 a graded fault; 2 could not grade (no git, no
|
|
python3, or a --repo that is not a git worktree).
|
|
"""
|
|
import argparse
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
import tempfile
|
|
|
|
RETIRED = "tools/inspect_tree.py"
|
|
BLOB = "3fea636fa5710d37b0f209321b0e62b5d3ccae15"
|
|
BLOB_REV = "93fa377"
|
|
DEFAULT_REPO = os.path.dirname(os.path.dirname(os.path.dirname(
|
|
os.path.abspath(__file__))))
|
|
|
|
|
|
def git(repo, *args):
|
|
p = subprocess.run(["git", "-C", repo] + list(args),
|
|
capture_output=True, text=True, errors="replace")
|
|
return p.returncode, (p.stdout or "").strip(), (p.stderr or "").strip()
|
|
|
|
|
|
def run(argv, cwd=None, timeout=600):
|
|
try:
|
|
p = subprocess.run([sys.executable] + argv, cwd=cwd, capture_output=True,
|
|
text=True, errors="replace", timeout=timeout)
|
|
return p.returncode, p.stdout or "", p.stderr or ""
|
|
except subprocess.TimeoutExpired:
|
|
return None, "", "TIMEOUT after %ss" % timeout
|
|
except OSError as exc:
|
|
return None, "", "<exec failed: %s>" % exc
|
|
|
|
|
|
def leg_absence(repo):
|
|
"""Retired, not lost: absent from the tracked tree, blob still resolvable."""
|
|
rc, out, err = git(repo, "ls-tree", "-r", "--name-only", "HEAD", "tools/")
|
|
if rc != 0:
|
|
return "FAULT", "cannot list tools/ at HEAD: " + (err or "git rc %s" % rc)
|
|
if RETIRED in out.splitlines():
|
|
return "FAULT", "%s is tracked at HEAD -- the retirement did not land" % RETIRED
|
|
rc, out, err = git(repo, "rev-parse", "%s:%s" % (BLOB_REV, RETIRED))
|
|
if rc != 0 or not out:
|
|
return "FAULT", "blob at %s:%s does not resolve: %s" % (BLOB_REV, RETIRED,
|
|
err or "no output")
|
|
if out != BLOB:
|
|
return "FAULT", "blob moved: %s:%s reads %s, pinned %s" % (BLOB_REV, RETIRED,
|
|
out[:12], BLOB[:12])
|
|
rc, size, _ = git(repo, "cat-file", "-s", BLOB)
|
|
if rc != 0 or size != "249":
|
|
return "FAULT", "blob %s size %r, expected 249 bytes" % (BLOB[:12], size)
|
|
return "OK", "absent from tools/ at HEAD; blob %s resolves, %s bytes" % (BLOB[:12],
|
|
size)
|
|
|
|
|
|
def leg_contract(repo, verbose=False):
|
|
tool = os.path.join(repo, "tools", "write_probe.py")
|
|
if not os.path.isfile(tool):
|
|
return "FAULT", "no tools/write_probe.py in %s" % repo
|
|
rc, out, err = run([tool, "--selftest", "--repo", repo], timeout=900)
|
|
tail = [l for l in (out or "").splitlines() if l.strip()][-1:] or [""]
|
|
if rc == 0:
|
|
return "OK", tail[0][:100]
|
|
if verbose:
|
|
print(out)
|
|
detail = " ".join(l.strip() for l in (out or "").splitlines()
|
|
if "FAIL" in l)[:180] or (err or "").strip()[:180]
|
|
return "FAULT", "write_probe --selftest rc %s: %s" % (rc, detail)
|
|
|
|
|
|
def leg_mutant(repo, verbose=False):
|
|
"""The retired bytes put back must red the same cell that caught them."""
|
|
with tempfile.TemporaryDirectory(prefix="q134-mutant-") as td:
|
|
dst = os.path.join(td, "clone")
|
|
rc, _, err = git(repo, "clone", "--quiet", "--no-hardlinks", repo, dst)
|
|
if rc != 0:
|
|
# Older gits refuse the four-argument local-clone form.
|
|
rc, _, err = git(td, "clone", "--quiet", repo, "clone")
|
|
if rc != 0:
|
|
return "FAULT", "could not clone the graded tree: " + err[:140]
|
|
rc, blob, err = git(dst, "cat-file", "blob", BLOB)
|
|
if not blob:
|
|
return "FAULT", "clone cannot read blob %s: %s" % (BLOB[:12], err[:120])
|
|
with open(os.path.join(dst, RETIRED), "w", encoding="utf-8",
|
|
newline="") as fh:
|
|
# git's output has already had its one trailing newline stripped by
|
|
# git(), so the exact blob is `blob + "\n"`; the size check below is
|
|
# what keeps that reasoning from being an assumption.
|
|
fh.write(blob + "\n")
|
|
got = os.path.getsize(os.path.join(dst, RETIRED))
|
|
if got != 249:
|
|
return "FAULT", "restored copy is %d bytes, the blob is 249" % got
|
|
for argv in (["add", RETIRED],
|
|
["-c", "user.email=volt@agents.invalid",
|
|
"-c", "user.name=volt", "commit", "-q", "-m",
|
|
"mutant: %s restored" % RETIRED]):
|
|
rc, _, err = git(dst, *argv)
|
|
if rc != 0:
|
|
return "FAULT", "could not stage the mutant: " + err[:140]
|
|
rc, out, err = run([os.path.join(dst, "tools", "write_probe.py"),
|
|
"--selftest", "--repo", dst], timeout=900)
|
|
if verbose:
|
|
print(out)
|
|
named = [l.strip() for l in (out or "").splitlines()
|
|
if "FAIL" in l and "inspect_tree.py" in l]
|
|
if rc != 1 or not named:
|
|
return "FAULT", ("restored blob read rc %s, expected 1 naming "
|
|
"inspect_tree.py: %s"
|
|
% (rc, (named[0] if named else (out or "")[-120:])))
|
|
return "OK", "restored blob -> rc 1, " + named[0][:90]
|
|
|
|
|
|
def main(argv=None):
|
|
ap = argparse.ArgumentParser(description=__doc__.splitlines()[0])
|
|
ap.add_argument("--repo", default=DEFAULT_REPO)
|
|
ap.add_argument("--verbose", action="store_true")
|
|
a = ap.parse_args(argv)
|
|
repo = os.path.abspath(a.repo)
|
|
if not os.path.isdir(repo):
|
|
print("q134: could not grade -- no such directory: " + repo)
|
|
return 2
|
|
rc, _, err = git(repo, "rev-parse", "--git-dir")
|
|
if rc != 0:
|
|
print("q134: could not grade -- not a git worktree: " + repo)
|
|
return 2
|
|
rc, head, _ = git(repo, "rev-parse", "--short", "HEAD")
|
|
print("q134: %s at %s" % (repo, head or "?"))
|
|
|
|
faults = 0
|
|
for name, fn in (("absence", leg_absence),
|
|
("contract", leg_contract),
|
|
("mutant", leg_mutant)):
|
|
verdict, detail = (fn(repo) if fn is leg_absence
|
|
else fn(repo, a.verbose))
|
|
if verdict != "OK":
|
|
faults += 1
|
|
print(" %-9s %-5s %s" % (name, verdict, detail))
|
|
print("q134: 3 leg(s), %d passed, %d fault(s)" % (3 - faults, faults))
|
|
return 1 if faults else 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|