#!/usr/bin/env bash # CHECK-q148 -- the baseline re-take tool, and the re-take it performed. # # Q148 (2026-11-01): `check_entry_baseline.tsv` fails in the direction nobody # automates -- a row whose entry point has since been repaired reads IMPROVED in # the sweep, and the row is re-taken by hand (Q145, Q146, Q147 each did it once). # `wizard-work/volt/q143-check-sweep/retake.py` measures named rows with the # sweep's own `run_entry`/`classify`, reports the codes that moved, and rewrites # only those rows behind `--write`, with a provenance comment. # # leg 1 the tool's 12-cell selftest # leg 2 two rows the sweep recorded green still read green from the tool # leg 3 a copy of the baseline with one row's code moved is named, written # back, and reads clean on a second take (the tool's own contract) # leg 4 the baseline on disk carries this tick's provenance block and still # parses under the sweep's own reader # leg 5 no row in the baseline names evidence the tree does not have # (the MISSING direction; the NEW direction is another lane's row) # # rc 0 all legs pass, rc 1 a leg faulted, rc 2 could not grade. set -u HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" || { echo "CANNOT GRADE: no directory"; exit 2; } ROOT="$(git -C "$HERE" rev-parse --show-toplevel 2>/dev/null)" || { echo "CANNOT GRADE: not a git repository"; exit 2; } SWEEP="$ROOT/wizard-work/volt/q143-check-sweep" TOOL="$SWEEP/retake.py" BASE="$SWEEP/check_entry_baseline.tsv" for f in "$TOOL" "$BASE" "$SWEEP/check_sweep.py"; do [ -f "$f" ] || { echo "CANNOT GRADE: missing $f"; exit 2; } done PY="${PYTHON:-python3}" WORK="$(mktemp -d "${TMPDIR:-/tmp}/q148.XXXXXX")" || exit 2 trap 'rm -rf "$WORK"' EXIT # The baseline is a shared file: other ticks re-take rows in it, and a re-take is # an atomic whole-file replace. Leg 3 grades the TOOL by mutating a copy and # asking it to name the move, so it compares against a snapshot taken here, not # against $BASE at compare time -- otherwise a lane that re-took a row between # the copy and the compare reads as this tool writing the wrong row (measured: # 2026-11-01 11:57Z and 12:14Z, FAIL beside a green tool selftest). SNAP="$WORK/base.orig.tsv" cp "$BASE" "$SNAP" 2>/dev/null && [ -s "$SNAP" ] \ || { echo "CANNOT GRADE: cannot snapshot $BASE"; exit 2; } faults=0 pass() { echo "PASS $1"; } fail() { echo "FAIL $1"; faults=$((faults+1)); } # leg 1 if out="$("$PY" "$TOOL" --selftest 2>&1)"; then pass "selftest $(printf '%s' "$out" | tail -1 | sed 's/selftest: //')" else fail "selftest"; printf '%s\n' "$out" | tail -4 fi # leg 2 -- two green rows, measured again if out="$("$PY" "$TOOL" --repo "$ROOT" --path CHECK-q147 --path CHECK-q146 2>&1)"; then pass "green-rows $(printf '%s' "$out" | tail -1 | sed 's/retake: //')" else fail "green-rows rc=$?"; printf '%s\n' "$out" | grep '^MOVED' | head -3 fi # leg 3 -- the mutation: one row's code moved, named, written, re-read clean. # The mutation is applied to the snapshot, so what is compared at the end is # "the tool's rewrite vs the file it was handed". "$PY" - "$SNAP" "$WORK/base.tsv" <<'PY' import sys src, dst = sys.argv[1], sys.argv[2] lines = open(src, encoding="utf-8").read().split("\n") out = [] for line in lines: parts = line.split("\t") if parts[0] == "CHECK-q147" and len(parts) > 2: parts[1] = "1" line = "\t".join(parts) out.append(line) open(dst, "w", encoding="utf-8", newline="\n").write("\n".join(out)) PY out="$("$PY" "$TOOL" --baseline "$WORK/base.tsv" --repo "$ROOT" --path CHECK-q147 2>&1)"; rc=$? if [ "$rc" -eq 1 ] && printf '%s' "$out" | grep -q '^MOVED CHECK-q147 1 -> 0'; then wout="$("$PY" "$TOOL" --baseline "$WORK/base.tsv" --repo "$ROOT" --path CHECK-q147 --write 2>&1)"; wrc=$? if [ "$wrc" -eq 0 ] && "$PY" "$TOOL" --baseline "$WORK/base.tsv" --repo "$ROOT" --path CHECK-q147 >/dev/null 2>&1; then if "$PY" - "$SNAP" "$WORK/base.tsv" <<'PY' import sys def rows(p): out = {} for line in open(p, encoding="utf-8"): if line.startswith("#") or not line.strip(): continue parts = line.rstrip("\n").split("\t") out[parts[0]] = (parts[1], parts[2] if len(parts) > 2 else "") return out a, b = rows(sys.argv[1]), rows(sys.argv[2]) bad = ["%s %s!=%s" % (k, a[k], b[k]) for k in a if a.get(k) != b.get(k)] print("data rows: %d compared, %d differ" % (len(a), len(bad))) sys.exit(1 if bad else 0) PY then pass "mutation named, written, re-read clean, other rows identical" else fail "mutation reintroduced a difference in another row" fi else fail "mutation write rc=$wrc or second take still moved" fi else fail "mutation not named (rc=$rc)"; printf '%s\n' "$out" | tail -2 fi # leg 4 -- the on-disk baseline carries this tick's provenance and still parses if grep -q '^# row-level re-take (q148 via retake.py' "$BASE" \ && "$PY" - "$BASE" <<'PY' import sys sys.path.insert(0, sys.argv[1].rsplit("/", 1)[0]) import check_sweep rev, rows = check_sweep.read_baseline(sys.argv[1]) print("baseline parses: %d row(s), rev %s" % (len(rows), rev)) sys.exit(0 if rows and rev else 1) PY then pass "provenance block present, baseline parses" else fail "provenance block missing or baseline does not parse" fi # leg 5 -- no MISSING row (evidence the baseline names and the tree lacks) out="$("$PY" "$SWEEP/check_sweep.py" --repo "$ROOT" --paths 2>&1)" if printf '%s' "$out" | grep -q '^FAIL: MISSING'; then fail "baseline names a path the tree lacks" printf '%s\n' "$out" | grep '^FAIL: MISSING' | head -3 else pass "no MISSING row ($(printf '%s' "$out" | tail -1 | sed 's/paths: //'))" fi echo "q148: $((5-faults)) of 5 leg(s) passed" [ "$faults" -eq 0 ] || exit 1 exit 0