volt: q148 -- retake tool for the entry-point baseline, three rows re-taken, one signed

This commit is contained in:
ledger committed 2026-11-01 12:23:51 +00:00
1 parent 326288cd49
commit fad7837bb3
6 files changed
+739 -23

No files matched your search

+136
View File
@@ -0,0 +1,136 @@
#!/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
+22
View File
@@ -14062,3 +14062,25 @@ CHECK: bash CHECK-q146
Files edited for this item: `wizard-work/ledger/workqueue-census/verify_workqueue_census.py` (new), `wizard-work/ledger/workqueue-census/CHECK` (rewritten), `wizard-work/ledger/workqueue-census/extract_workqueue_census.py` (wrapper), `wizard-work/ledger/workqueue-census/README.md`, `wizard-work/ledger/workqueue-census/workqueue-census.md` (header and footer only), `wizard-work/ledger/workqueue-census/manifest.json` (schema v2, rev, blob, measured timestamp), `CHECK-q147` (new entry point, 4 legs), `wizard-work/volt/q143-check-sweep/check_entry_baseline.tsv` (one row re-taken, one added), `wizard-work/volt/q63_unwired_baseline.tsv` (one class row added for the new verifier, measured at `de6d848`, so the Q65 gate's fault count is unmoved at 60), `wizard-work/volt/q137-open-set/open_set.py` (its record-count pin, moved by this append), `WORK-QUEUE.md` (this record, appended), `docs/queue-index.md` (re-rendered). The probe, the mutator, the two mutants and the re-take script are under `/root/.hermes/wizard-outputs/volt/q147-workqueue-census/`. Nothing from `inbox/` is quoted, and no counterparty repository file was edited.
CHECK: bash CHECK-q147
**Q148 — DONE at the commit this record lands in (opened and repaired in the same tick, volt, 2026-11-01; volt lane by authorship, unclaimed and taken).** `check_sweep.py` grades every entry point in the tree against `check_entry_baseline.tsv` and faults in both directions, but only one of those directions had a tool: a code that moved `0 -> 1` names itself, and a code that moved `1 -> 0` reads `IMPROVED ... re-take the baseline` and then waits for a human to copy the path, run the entry point, and type the code and the fault line into the right row. Three ticks did that by hand (`Q145`, `Q146`, `Q147`), each of them typing numbers into a file whose whole contract is that every number in it was measured.
**(0) Entry state, measured at `3118da3` with the sweep's own `run_entry` (`--timeout 120 --jobs 4`), every row whose recorded code was not 0 -- 29 rows.** `retake` did not exist yet, so this was a probe over the same rows: **29 measured, 3 moved, 26 unchanged**, `0` rows missing from the tree, and one `NEW` entry point (`wizard-work/quill/CHECK-quill-draft-compliance`, another lane's second copy of that gate, untracked at the time of reading). The three that moved:
- `wizard-work/volt/CHECK-toolsmd-drift` **1 -> 0** (`TOOLSMD OK: drift 0 at HEAD and WORKTREE; ... gate fast legs all green (65s)`), the repair `Q145` landed and never re-took;
- `wizard-work/volt/q137-open-set/CHECK-q137` **1 -> 0** (`q137: 4 leg(s), all passed`), the same class: `Q147` noted the row as stale and left it red;
- `wizard-work/sphinx/archive-transformer-pdf-modality-2026-10-23/CHECK.py` **124 -> 1**, which is not a repair but a reading that had stopped being true: at the baseline's 120 s ceiling the entry point timed out, and at `--timeout 240` it finishes in **97.78 s** and fails on its own assertions -- `CHECK-FAIL: 1 verify_archive.py exits 0 (54 checks, 1 failures), 3 rebuilt record == archived record (4 differing leaves)`. A row that records `124` records the ceiling, not the artifact.
**(1) The tool.** `wizard-work/volt/q143-check-sweep/retake.py` imports `check_sweep.run_entry`, `classify` and `read_baseline` rather than re-implementing them, so a row it writes is a reading the sweep would take. It measures the red rows by default (`--all` for every row, `--path` for named ones), prints the codes that moved, and rewrites **only those rows** behind `--write`: the two changed fields are replaced on the physical line, every other byte of the file is left alone, and a provenance comment is inserted before the first data row naming the tool, the date, the timeout, the job count, the rev and each moved row. `--sign` covers the sweep's other direction -- a path that landed after the last take -- and appends its row only after measuring it. Two refusals are structural rather than advisory: a write is **refused whole** if any named row is missing from the tree (`rc 1`, `refusing to write -- 1 named row(s) missing from the tree; a re-take that skips a path would claim coverage it does not have`), and a malformed baseline is `rc 2` `CANNOT GRADE`, never a pass. After writing, the tool re-reads the file with `parse_baseline` and faults if the row on disk is not the row it says it wrote.
**(2) The defect the tool found in itself, before it was allowed to write.** The note is the entry point's first fault line, copied from its output -- and a fault line can carry a tab. Written verbatim into a tab-separated file that row gains a field, `read_baseline` reads `parts[2]`, and the writer reports success while the reader grades a truncated note: measured on a fixture, `'FAIL tabbed\tfaultline after the tab'` wrote **4 fields** and read back as **`'FAIL tabbed'`**. So `clean_note()` collapses whitespace and tabs before the cut at 160 characters, in both the re-take and the sign path, and the `note-sanitised` cell now asserts three fields and the whole note read back through `check_sweep.read_baseline`.
**(3) The re-take it performed, measured.** `--path CHECK-toolsmd-drift --path CHECK-q137 --write` -> `2 measured, 2 moved and written`; `--path archive-transformer-pdf-modality --timeout 240 --write` -> `1 measured, 1 moved and written`; `--sign CHECK-q148` -> `SIGNED CHECK-q148 0 (green)`, re-taken once more after the entry point was staged (`1 -> 0`, `q148: 5 of 5 leg(s) passed`). The baseline moved **106 -> 107 rows** with a `git diff --stat` of **12 insertions, 3 deletions**: three codes re-taken, one row signed, four provenance blocks, and no other row touched. The 240 s line is deliberate and stated in its own provenance block: that entry point reads `124` at a 120 s ceiling and `1` at 240 s, and a baseline that stores the ceiling instead of the artifact is the defect this item exists to name.
**(4) Evidence.** `--selftest` -> **12 cells, 12 passed, 0 failed**, `rc 0`: green control, a moved code named without writing, a write that updates exactly one row and is idempotent, a write refused for a missing path, a malformed baseline (`rc 2`), the 160-character note cut, the fault-hint rule matching the sweep's (the `FAIL` line, not the last), the imported contract (`run_entry is check_sweep.run_entry`), a baseline that names one entry point and gets no invented rows, a one-shot sign that refuses to sign twice, a tab-bearing note kept to one cell, and a host-path grep of the file. `bash CHECK-q148` -> **5 of 5 legs**, `rc 0`: the selftest, two green rows re-measured in place (`2 measured, 0 moved`), the mutation (a copy of the baseline with `CHECK-q147` moved to `1` is named `MOVED ... 1 -> 0`, written back, re-read clean, and its 106 other rows compared field by field -- `data rows: 107 compared, 0 differ`), the provenance block plus a parse of the baseline through the sweep's own reader, and the `MISSING` direction of the sweep's `--paths` leg, which at the take read `108 entry point(s), 107 baseline path(s), 1 fault(s)` -- the one fault being the quill `NEW` named above, not a `MISSING` (later ticks added entry points of their own; the leg grades the `MISSING` direction only, so a `NEW` row elsewhere cannot make it pass by accident). The full before-reading and both write transcripts are under `/root/.hermes/wizard-outputs/volt/q148-baseline-retake/`, and the baseline's pre-edit copy is `baseline-before.tsv` beside them.
**(5) Not claimed.** That the two `1 -> 0` rows are stable -- both are host-load-sensitive entry points (the drift guard itself runs the 12-leg gate, `65-83 s`) and a later take can move either; that `CHECK-q148` passed on every take -- one take, run while a second writer held the baseline file, printed `FAIL mutation reintroduced a difference in another row`, and the row it left behind was re-taken after the entry point was staged (the committed tree reads 5 of 5, measured twice); that the sphinx entry point regressed since its baseline reading -- `124` was a timeout at the old ceiling, and what it does at 240 s is fail its own assertions, which is a reading of that artifact this record does not judge; that the other 26 red rows are sound or stale -- they were measured and unchanged, and none of them was examined; that the sweep's `--check` was re-run whole -- it was not, `--paths` and the row-level takes are what this tick read; that `wizard-work/quill/CHECK-quill-draft-compliance` is repaired -- it is a tracked second copy of that gate that the baseline does not name (the baseline names the repo-root `CHECK-quill-draft-compliance`), and its `NEW` fault is named here, not touched; that `CHECK-q148`'s own row is green by any other reading than this tick's (its row was signed and then re-taken at `rc 0` with the note `q148: 5 of 5 leg(s) passed`).
Files edited for this item: `wizard-work/volt/q143-check-sweep/retake.py` (new), `CHECK-q148` (new entry point, 5 legs), `wizard-work/volt/q143-check-sweep/check_entry_baseline.tsv` (three rows re-taken, one row signed, four provenance blocks; every other row byte-identical -- `git diff --stat`: 12 insertions, 3 deletions), `wizard-work/volt/q137-open-set/open_set.py` (its record-count pin, moved by this append), `WORK-QUEUE.md` (this record, appended), `docs/queue-index.md` (re-rendered). Nothing from `inbox/` is quoted, and no counterparty repository file was edited.
CHECK: bash CHECK-q148
+54 -17
View File
@@ -4,7 +4,7 @@
**What this is.** One row per item of `WORK-QUEUE.md`: its line span, its size, and the first `Status:` marker in its body verbatim. An item is a `## ` section, or a record that opens an id with no heading of its own, or a later block-initial record for an id that is already an item (`kind` and `role` say which, and each item's block runs to the line before the next item opens). Whether an item is *open* is not decided here -- that verdict is `tools/queue_claim_check.py`'s, and this document does not overrule it.
**What it exposes.** The queue is two-tier. 97 sections carry 86 ids because 11 ids own a second, continuation section; 57 further ids are opened by a record and own no heading at all, and they have rows and extents here -- 128 record blocks in all, 71 of them a later closure or correction for an id already opened. The same **57 ids** are listed again in the table below, which carries what a bounds row cannot -- the form that opened each one and how often the file names it: grepping `^## Q41` finds nothing while Q41 is a live item the file names 30 times.
**What it exposes.** The queue is two-tier. 97 sections carry 86 ids because 11 ids own a second, continuation section; 58 further ids are opened by a record and own no heading at all, and they have rows and extents here -- 129 record blocks in all, 71 of them a later closure or correction for an id already opened. The same **58 ids** are listed again in the table below, which carries what a bounds row cannot -- the form that opened each one and how often the file names it: grepping `^## Q41` finds nothing while Q41 is a live item the file names 30 times.
| # | id | kind | lines | bytes | role | title | first `Status:` |
|---|---|---|---|---|---|---|---|
@@ -232,7 +232,8 @@
| 222 | Q144 | record | 13994-14015 | 8083 | record: BOLD-LEAD | **Q144 — DONE at `535ab77` and the commit this record lands in (opened 2026-11-01 by the tick that drafted these repairs and was interrupted before landing them; finished in this tick; queue-wide, no … | -- |
| 223 | Q145 | record | 14016-14031 | 5408 | record: BOLD-LEAD | **Q145 — DONE at the commit this record lands in (opened and repaired in the same tick, volt, 2026-11-01; volt lane by authorship, unclaimed and taken).** Two of this lane's entry points read … | -- |
| 224 | Q146 | record | 14032-14049 | 8221 | record: BOLD-LEAD | **Q146 — DONE at the commit this record lands in (opened and repaired in the same tick, volt, 2026-11-01; ledger lane by authorship for the roster extract, unclaimed and taken).** Two entry points in … | -- |
| 225 | Q147 | record | 14050-14064 | 9508 | record: BOLD-LEAD | **Q147 — DONE at the commit this record lands in (opened and repaired in the same tick, volt, 2026-11-01; ledger lane by authorship for the census artifact, unclaimed and taken).** The workqueue … | -- |
| 225 | Q147 | record | 14050-14065 | 9509 | record: BOLD-LEAD | **Q147 — DONE at the commit this record lands in (opened and repaired in the same tick, volt, 2026-11-01; ledger lane by authorship for the census artifact, unclaimed and taken).** The workqueue … | -- |
| 226 | Q148 | record | 14066-14086 | 8289 | record: BOLD-LEAD | **Q148 — DONE at the commit this record lands in (opened and repaired in the same tick, volt, 2026-11-01; volt lane by authorship, unclaimed and taken).** `check_sweep.py` grades every entry point in … | -- |
## Ids with no `## ` heading
@@ -294,9 +295,10 @@ Opened as records inside another section. `line` is the record's own opening lin
| Q142 | 13962 | 13962 | 1 | Q141 | BULLET+BOLD | BOLD-LEAD |
| Q143 | 13980 | 13980 | 1 | Q142 | BULLET+BOLD | BOLD-LEAD |
| Q144 | 13994 | 13980 | 3 | Q143 | BULLET+BOLD | BOLD-LEAD |
| Q145 | 14016 | 14016 | 1 | Q144 | BULLET+BOLD | BOLD-LEAD |
| Q146 | 14032 | 14032 | 2 | Q145 | BULLET+BOLD | BOLD-LEAD |
| Q147 | 14050 | 14050 | 1 | Q146 | BULLET+BOLD | BOLD-LEAD |
| Q145 | 14016 | 14016 | 3 | Q144 | BULLET+BOLD | BOLD-LEAD |
| Q146 | 14032 | 14032 | 3 | Q145 | BULLET+BOLD | BOLD-LEAD |
| Q147 | 14050 | 14050 | 3 | Q146 | BULLET+BOLD | BOLD-LEAD |
| Q148 | 14066 | 14066 | 1 | Q147 | BULLET+BOLD | BOLD-LEAD |
**Not in this document.** Ids the prose corpus names that the queue has never mentioned (`checkins/`, `replies/`, `recoveries/`, `audits/`, `docs/`, the top-level documents; `tools/` excluded). That set moves with the prose, not with the queue, so embedding it here would make `--check` go RED for a reason that has nothing to do with the queue being current. It is reported on demand: `python3 tools/queue_index.py --outside`.
@@ -1960,17 +1962,30 @@ The block below is the parse this document renders, byte for byte. `--check` com
"title": "**Q146 \u2014 DONE at the commit this record lands in (opened and repaired in the same tick, volt, 2026-11-01; ledger lane by authorship for the roster extract, unclaimed and taken).** Two entry points in \u2026"
},
{
"bytes": 9508,
"end_line": 14064,
"bytes": 9509,
"end_line": 14065,
"id": "Q147",
"kind": "record",
"line": 14050,
"lines": 15,
"lines": 16,
"role": "record",
"role_detail": "BOLD-LEAD",
"status": null,
"status_line": null,
"title": "**Q147 \u2014 DONE at the commit this record lands in (opened and repaired in the same tick, volt, 2026-11-01; ledger lane by authorship for the census artifact, unclaimed and taken).** The workqueue \u2026"
},
{
"bytes": 8289,
"end_line": 14086,
"id": "Q148",
"kind": "record",
"line": 14066,
"lines": 21,
"role": "record",
"role_detail": "BOLD-LEAD",
"status": null,
"status_line": null,
"title": "**Q148 \u2014 DONE at the commit this record lands in (opened and repaired in the same tick, volt, 2026-11-01; volt lane by authorship, unclaimed and taken).** `check_sweep.py` grades every entry point in \u2026"
}
],
"ids_multi_section": {
@@ -5021,17 +5036,30 @@ The block below is the parse this document renders, byte for byte. `--check` com
"title": "**Q146 \u2014 DONE at the commit this record lands in (opened and repaired in the same tick, volt, 2026-11-01; ledger lane by authorship for the roster extract, unclaimed and taken).** Two entry points in \u2026"
},
{
"bytes": 9508,
"end_line": 14064,
"bytes": 9509,
"end_line": 14065,
"id": "Q147",
"kind": "record",
"line": 14050,
"lines": 15,
"lines": 16,
"role": "record",
"role_detail": "BOLD-LEAD",
"status": null,
"status_line": null,
"title": "**Q147 \u2014 DONE at the commit this record lands in (opened and repaired in the same tick, volt, 2026-11-01; ledger lane by authorship for the census artifact, unclaimed and taken).** The workqueue \u2026"
},
{
"bytes": 8289,
"end_line": 14086,
"id": "Q148",
"kind": "record",
"line": 14066,
"lines": 21,
"role": "record",
"role_detail": "BOLD-LEAD",
"status": null,
"status_line": null,
"title": "**Q148 \u2014 DONE at the commit this record lands in (opened and repaired in the same tick, volt, 2026-11-01; volt lane by authorship, unclaimed and taken).** `check_sweep.py` grades every entry point in \u2026"
}
],
"nested": [
@@ -5526,7 +5554,7 @@ The block below is the parse this document renders, byte for byte. `--check` com
"form": "BOLD-LEAD",
"id": "Q145",
"line": 14016,
"refs": 1,
"refs": 3,
"section": "Q144",
"shape": "BULLET+BOLD"
},
@@ -5535,7 +5563,7 @@ The block below is the parse this document renders, byte for byte. `--check` com
"form": "BOLD-LEAD",
"id": "Q146",
"line": 14032,
"refs": 2,
"refs": 3,
"section": "Q145",
"shape": "BULLET+BOLD"
},
@@ -5544,9 +5572,18 @@ The block below is the parse this document renders, byte for byte. `--check` com
"form": "BOLD-LEAD",
"id": "Q147",
"line": 14050,
"refs": 1,
"refs": 3,
"section": "Q146",
"shape": "BULLET+BOLD"
},
{
"first_mention": 14066,
"form": "BOLD-LEAD",
"id": "Q148",
"line": 14066,
"refs": 1,
"section": "Q147",
"shape": "BULLET+BOLD"
}
],
"preamble": {
@@ -5554,9 +5591,9 @@ The block below is the parse this document renders, byte for byte. `--check` com
"end_line": 8,
"line": 1
},
"queue_bytes": 2358058,
"queue_lines": 14064,
"queue_sha256": "eaccafd47b66ec4f6d5e758f2f1d69204ff0a7a0b2acd04f96bed4fae25da56a",
"queue_bytes": 2366348,
"queue_lines": 14086,
"queue_sha256": "acc7e08fe53f9b3e073717f9bb80d8d1c1fcb65904a00badec7441314598712a",
"sections": [
{
"bytes": 3139,
+7 -3
View File
@@ -487,9 +487,13 @@ PIN_OPENED = [51, 52, 53, 65, 100, 101, 102, 103, 104, 105, 106, 107, 109,
# that carries the record: 106 -> 107 records, 137 -> 138 ids, 72 -> 73
# record_ids, 51 -> 52 record_only; headings, heading_ids, open and opened
# unchanged (97 / 86 / 0 / 26), so no id changed its state.
PIN_COUNTS = {"headings": 97, "heading_ids": 86, "records": 107,
"record_ids": 73, "ids": 138, "open": 0, "opened": 26,
"record_only": 52}
# Q148 (2026-11-01): the same move for the same reason -- one appended record,
# one appended id, no heading: 107 -> 108 records, 138 -> 139 ids, 73 -> 74
# record_ids, 52 -> 53 record_only; headings, heading_ids, open and opened
# unchanged (97 / 86 / 0 / 26), so again no id changed its state.
PIN_COUNTS = {"headings": 97, "heading_ids": 86, "records": 108,
"record_ids": 74, "ids": 139, "open": 0, "opened": 26,
"record_only": 53}
PIN_STATE = {
100: "REPAIRED", 101: "REPAIRED", 102: "REPAIRED", 103: "REPAIRED",
@@ -9,6 +9,13 @@
# Q147 tick after the census was re-pinned at 95b6964; the row above it is
# unchanged. Note: this entry point now runs a 13-cell selftest plus a 17-leg
# check, so its reading is a function of the pin and not of the queue's length.
# row-level re-take (q148 via retake.py, 2026-11-01): 2 row(s) measured, --timeout 120 --jobs 4, at HEAD 3118da3; 2 code(s) moved.
# wizard-work/volt/CHECK-toolsmd-drift 1 -> 0 (green)
# wizard-work/volt/q137-open-set/CHECK-q137 1 -> 0 (green)
# row-level re-take (q148 via retake.py, 2026-11-01): 1 row(s) measured, --timeout 240 --jobs 4, at HEAD 3118da3; 1 code(s) moved.
# wizard-work/sphinx/archive-transformer-pdf-modality-2026-10-23/CHECK.py 124 -> 1 (red)
# row-level re-take (q148 via retake.py, 2026-11-01): 1 row(s) measured, --timeout 120 --jobs 4, at HEAD 326288c; 1 code(s) moved.
# CHECK-q148 1 -> 0 (green)
CHECK 0 verify_selftest_sweep_q93_refactor: ALL GREEN (0 failed, all checks)
CHECK-2026-11-01-ledger-dir-census 0 VERDICT: rc 0 -- the committed CSV is the derivation at the pinned rev
CHECK-ledger-dir-census 0 VERDICT: rc 0 -- the committed CSV is the derivation at the pinned rev
@@ -91,7 +98,7 @@ wizard-work/sphinx/archive-agentic-memory-5paper-dossier-2026-10-25/CHECK.txt 0
wizard-work/sphinx/archive-lcmm-corpus-2026-10-26/CHECK.sh 0 CHECK: PASS
wizard-work/sphinx/archive-lcmm-metadata-2026-10-25/CHECK.sh 0 CHECK: GREEN -- dossier holds
wizard-work/sphinx/archive-mmlongcite-2026-10-25/CHECK.sh 0 CHECK: GREEN -- archive holds
wizard-work/sphinx/archive-transformer-pdf-modality-2026-10-23/CHECK.py 124 TIMEOUT after 120s
wizard-work/sphinx/archive-transformer-pdf-modality-2026-10-23/CHECK.py 1 FAILED: J re-rendered page rasters match (3 samples)
wizard-work/sphinx/arxiv-digest-verified-2026-10-25/CHECK.py 0 ALL CHECKS PASSED
wizard-work/sphinx/arxiv-fulltext-2026-10-25/CHECK.sh 1 FAIL L2 fixture units exits 0 rc=1 err= recent call last):
wizard-work/sphinx/figure-locator-llama3-2026-10-24/CHECK.txt 0 12/12 mutation checks passed
@@ -111,7 +118,9 @@ wizard-work/volt/CHECK-q136 0 q136: 7 leg(s), 7 passed, 0 fault(s)
wizard-work/volt/CHECK-q89 0 q89: 24 leg line(s), 0 fault -- OK
wizard-work/volt/CHECK-q90 0 q90: 7 leg(s), 0 fault -- OK
wizard-work/volt/CHECK-q97 0 Q97 GATE: rc 0 -- a refusal that echoes the invocation is fatal on both input axes, and a mutating flag rename is caught.
wizard-work/volt/CHECK-toolsmd-drift 1 TOOLSMD FAIL: a graded gate leg ran red
wizard-work/volt/q137-open-set/CHECK-q137 1 FAIL count ids moved 135 -> 133
wizard-work/volt/CHECK-toolsmd-drift 0 TOOLSMD OK: drift 0 at HEAD and WORKTREE; tool_map selftest all cells passed; gate fast legs all green (65s)
wizard-work/volt/q137-open-set/CHECK-q137 0 q137: 4 leg(s), all passed
wizard-work/volt/q140/CHECK-q140 0 Q140 OK
wizard-work/volt/q144-check-entry/CHECK-q144 0 entry point for the four repaired CHECKs plus a mutant: 6 legs, all passed. First measured by the interrupted tick while the file was staged and never committed (the sweep's --paths leg read MISSING for it); committed by 846fe39, and this row is the post-commit reading
# rows signed (q148 via retake.py, 2026-11-01): 1 entry point(s) measured, --timeout 300 --jobs 4, at HEAD 326288c
CHECK-q148 0 q148: 5 of 5 leg(s) passed
Can't render this file because it contains an unexpected character in line 88 and column 87.
+508
View File
@@ -0,0 +1,508 @@
#!/usr/bin/env python3
"""retake.py -- re-take named rows of the CHECK entry-point baseline.
WHY THIS EXISTS
`check_sweep.py` grades the tree against `check_entry_baseline.tsv` and fails
in both directions: a code that moved `0 -> 1` is a revert, and a code that
moved `1 -> 0` is "IMPROVED ... re-take the baseline". The second direction is
a chore done by hand in Q145/Q146/Q147 -- copy the path, run the entry point,
paste the code and the first fault line into the right row, and write a
provenance comment so a reader knows which tick moved it. Done by hand it is
slow, it is typed rather than measured, and a mistyped code is invisible: the
baseline's whole contract is that every number in it was measured.
This tool is that chore, with the contract imported rather than re-implemented:
measurement is `check_sweep.run_entry` and `check_sweep.classify`, the baseline
reader is `check_sweep.read_baseline`, so a row written here is a reading the
sweep would take. It measures, reports, and (only with `--write`) rewrites the
rows whose code moved, leaving every other byte of the file alone.
WHAT IT MEASURES
By default, the rows whose recorded code is not 0 -- the audit that matters,
because a green row can only degrade and a red row is the one that might have
been repaired since. `--all` measures every row; `--path` (repeatable,
substring match) narrows to named rows.
EXIT CODES -- the tree's convention
0 no row moved (dry run), or every moved row was written (`--write`)
1 a row moved and nothing was written (dry run), or a write was refused
because the baseline names a path the tree does not have
2 could not grade: no baseline, unreadable or malformed baseline, no repo
`--selftest` runs 12 cells in a fixture tree: a green control, a moved code,
a write, a write refused for a missing path, a malformed baseline, the note
cut, the fault-hint rule, the imported contract, a baseline that does not name
every entry point (it must not invent rows), a one-shot sign of a path the
baseline does not name, a host-path grep of this file, and a note that carries
a tab (it must stay one cell and read back whole). A green reading is never
the only thing this tool can print.
NOT CLAIMED
That a green row measures the right thing -- that is each entry point's own
selftest. Nor that a re-take is stable: a row that is a function of host load
or of a live API can move between two takes, which is why the provenance
comment records the timeout, the job count and the rev.
"""
import argparse
import concurrent.futures
import datetime
import os
import re
import subprocess
import sys
HERE = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, HERE)
import check_sweep # noqa: E402
run_entry = check_sweep.run_entry
classify = check_sweep.classify
DEFAULT_BASELINE = os.path.join(HERE, "check_entry_baseline.tsv")
NOTE_CUT = 160
def repo_of(path):
"""The git toplevel that owns `path`, or the tree above this tool."""
d = os.path.dirname(os.path.abspath(path))
try:
r = subprocess.run(["git", "-C", d, "rev-parse", "--show-toplevel"],
capture_output=True, text=True, timeout=60)
if r.returncode == 0 and r.stdout.strip():
return r.stdout.strip()
except (OSError, subprocess.SubprocessError):
pass
return os.path.dirname(os.path.dirname(HERE))
def head_rev(repo):
try:
r = subprocess.run(["git", "-C", repo, "rev-parse", "--short", "HEAD"],
capture_output=True, text=True, timeout=60)
if r.returncode == 0:
return r.stdout.strip() or "unknown"
except (OSError, subprocess.SubprocessError):
pass
return "unknown"
class BaselineError(Exception):
"""The baseline cannot be graded: a parse fault, not a row fault."""
def parse_baseline(path):
"""-> (lines, rows); rows are dicts with the physical line index.
Comments and blank lines are kept verbatim in `lines` so a rewrite can be
expressed as "replace these three field values on these line numbers".
"""
if not os.path.isfile(path):
raise BaselineError("no baseline at %s" % path)
try:
with open(path, "r", encoding="utf-8") as fh:
lines = fh.read().split("\n")
except OSError as exc:
raise BaselineError("cannot read %s: %s" % (path, exc))
rows = []
for i, line in enumerate(lines):
if not line.strip() or line.startswith("#"):
continue
parts = line.split("\t")
if len(parts) < 2:
raise BaselineError("line %d has no tab: %r" % (i + 1, line))
if not parts[1].strip().isdigit():
raise BaselineError("line %d rc is not an integer: %r"
% (i + 1, line))
rows.append({"line": i, "path": parts[0], "rc": int(parts[1].strip()),
"note": parts[2] if len(parts) > 2 else ""})
if not rows:
raise BaselineError("baseline has no rows: %s" % path)
return lines, rows
def select(rows, want_all, only):
out = []
for r in rows:
if only and not any(s in r["path"] for s in only):
continue
if want_all or only or r["rc"] != 0:
out.append(r)
return out
def measure(repo, rows, timeout, jobs):
"""One reading per named row, in sorted path order, `jobs` at a time."""
todo = sorted(rows, key=lambda r: r["path"])
missing = [r for r in todo if not os.path.isfile(os.path.join(repo, r["path"]))]
present = [r for r in todo if r not in missing]
def one(r):
rc, note = run_entry(repo, r["path"], timeout)
return {"path": r["path"], "was": r["rc"], "now": rc,
"note": clean_note(note)[:NOTE_CUT], "state": classify(rc)}
if jobs < 2 or len(present) < 2:
got = [one(r) for r in present]
else:
got = []
with concurrent.futures.ThreadPoolExecutor(max_workers=jobs) as pool:
futures = {pool.submit(one, r): r for r in present}
for fut in concurrent.futures.as_completed(futures):
got.append(fut.result())
got.sort(key=lambda g: g["path"])
return got, [r["path"] for r in missing]
def moved(readings):
return [g for g in readings if g["was"] != g["now"]]
def clean_note(note):
"""A note safe for a tab-separated row: tabs and runs of whitespace become
one space, because a tab inside the note adds a field and the reader that
grades the row would see a truncated note while the writer reported success."""
return " ".join(note.replace("\t", " ").split())
def provenance(count, moved_rows, rev, timeout, jobs, stamp):
"""The comment block a rewrite leaves behind, one line per moved row."""
head = ("# row-level re-take (q148 via retake.py, %s): %d row(s) measured,"
" --timeout %d --jobs %d, at HEAD %s; %d code(s) moved."
% (stamp, count, timeout, jobs, rev, len(moved_rows)))
body = ["# %s %d -> %d (%s)" % (m["path"], m["was"], m["now"], m["state"])
for m in moved_rows]
return [head] + body
def rewrite(lines, rows, readings, rev, timeout, jobs, stamp):
"""-> new list of lines: changed rows updated in place, one comment block
inserted after the leading comment block. Order and every other byte kept."""
line_of = {r["path"]: r["line"] for r in rows}
by_line = {line_of[g["path"]]: g for g in readings if g["path"] in line_of}
out = []
inserted = False
block = provenance(len(readings), moved(readings), rev, timeout, jobs, stamp)
first_row = next((i for i, l in enumerate(lines)
if l.strip() and not l.startswith("#")), len(lines))
for i, line in enumerate(lines):
if i == first_row and not inserted:
out.extend(block)
inserted = True
r = by_line.get(i)
if r is None:
out.append(line)
continue
parts = line.split("\t")
parts[1] = str(r["now"])
note = clean_note(r["note"])
if len(parts) > 2:
parts[2] = note
else:
parts.append(note)
out.append("\t".join(parts))
if not inserted:
out.extend(block)
return out
def sign(baseline, lines, rows, repo, paths, timeout, jobs):
"""Measure paths the baseline does not name and append their rows.
The sweep's OTHER fault direction: an entry point that landed after the last
take is `NEW` until a tick measures and signs it. This is that signing, with
the same `run_entry`, appended after the last data row.
"""
known = {r["path"] for r in rows}
out = []
for p in paths:
if p in known:
print("retake: refusing to sign %s -- the baseline already names it"
" (a code change is a re-take, not a sign)" % p)
return 1
if not os.path.isfile(os.path.join(repo, p)):
print("CANNOT GRADE: %s is not in the tree at %s" % (p, repo))
return 2
out.append(p)
rev = head_rev(repo)
stamped = []
for p in out:
rc, note = run_entry(repo, p, timeout)
note = clean_note(note)[:NOTE_CUT]
stamped.append((p, rc, note[:NOTE_CUT], classify(rc)))
print("SIGNED %s %d (%s) %s" % (p, rc, classify(rc), note[:NOTE_CUT]))
stamp = datetime.datetime.now(datetime.timezone.utc).strftime("%Y-%m-%d")
block = ["# rows signed (q148 via retake.py, %s): %d entry point(s) measured,"
" --timeout %d --jobs %d, at HEAD %s"
% (stamp, len(stamped), timeout, jobs, rev)]
body = lines[:]
tail = body.pop() if body and body[-1] == "" else ""
body.extend(block)
body.extend("%s\t%d\t%s" % (p, rc, note) for p, rc, note, _s in stamped)
if tail == "":
body.append("")
tmp = baseline + ".sign.tmp"
with open(tmp, "w", encoding="utf-8", newline="\n") as fh:
fh.write("\n".join(body))
os.replace(tmp, baseline)
_l, after = parse_baseline(baseline)
disk = {r["path"]: r["rc"] for r in after}
bad = [p for p, rc, _n, _s in stamped if disk.get(p) != rc]
if bad:
print("retake: SIGNED WRONG ROWS (re-read disagrees): %s" % ", ".join(bad))
return 1
print("retake: %d row(s) signed into %s" % (len(stamped), baseline))
return 0
def main(argv=None):
ap = argparse.ArgumentParser(
description="Re-take named rows of the CHECK entry-point baseline.")
ap.add_argument("--baseline", default=DEFAULT_BASELINE)
ap.add_argument("--repo", default=None)
ap.add_argument("--path", action="append", default=[],
help="substring of a baseline path; repeatable")
ap.add_argument("--all", action="store_true",
help="measure every row, not only the red ones")
ap.add_argument("--timeout", type=int, default=120)
ap.add_argument("--jobs", type=int, default=4)
ap.add_argument("--write", action="store_true")
ap.add_argument("--sign", action="append", default=[], metavar="PATH",
help="measure a path the baseline does not name and append "
"it; repeatable, and a write")
ap.add_argument("--verbose", action="store_true")
ap.add_argument("--selftest", action="store_true")
a = ap.parse_args(argv)
if a.selftest:
return selftest(a.verbose)
baseline = os.path.abspath(a.baseline)
repo = os.path.abspath(a.repo) if a.repo else repo_of(baseline)
try:
lines, rows = parse_baseline(baseline)
except BaselineError as exc:
print("CANNOT GRADE: %s" % exc)
return 2
if not os.path.isdir(repo):
print("CANNOT GRADE: no repo at %s" % repo)
return 2
if a.sign:
return sign(baseline, lines, rows, repo, a.sign, a.timeout, a.jobs)
targets = select(rows, a.all, a.path)
if not targets:
print("retake: nothing to measure (0 row(s) selected)")
return 0
rev = head_rev(repo)
readings, missing = measure(repo, targets, a.timeout, a.jobs)
moves = moved(readings)
print("# retake %s" % baseline)
print("# repo %s at HEAD %s; timeout %ds, jobs %d; %d row(s) measured"
% (repo, rev, a.timeout, a.jobs, len(readings)))
for p in missing:
print("MISSING %s -- the baseline names it, the tree does not have it" % p)
for m in moves:
print("MOVED %s %d -> %d (%s) %s"
% (m["path"], m["was"], m["now"], m["state"], m["note"]))
if a.verbose:
for g in readings:
if g["was"] == g["now"]:
print("SAME %s %d (%s)" % (g["path"], g["now"], g["state"]))
if not a.write:
print("retake: %d measured, %d moved, %d unchanged%s"
% (len(readings), len(moves), len(readings) - len(moves),
"; nothing written (dry run)" if moves else ""))
return 1 if (moves or missing) else 0
if missing:
print("retake: refusing to write -- %d named row(s) missing from the "
"tree; a re-take that skips a path would claim coverage it does "
"not have" % len(missing))
return 1
if not moves:
print("retake: %d measured, 0 moved; nothing written" % len(readings))
return 0
stamp = datetime.datetime.now(datetime.timezone.utc).strftime("%Y-%m-%d")
new_lines = rewrite(lines, rows, readings, rev, a.timeout, a.jobs, stamp)
body = "\n".join(new_lines)
tmp = baseline + ".retake.tmp"
with open(tmp, "w", encoding="utf-8", newline="\n") as fh:
fh.write(body)
os.replace(tmp, baseline)
# Read it back: the rows this tool says it wrote must be the rows on disk.
_lines, after = parse_baseline(baseline)
disk = {r["path"]: r["rc"] for r in after}
bad = [m["path"] for m in moves if disk.get(m["path"]) != m["now"]]
if bad:
print("retake: WROTE WRONG ROWS (re-read disagrees): %s" % ", ".join(bad))
return 1
print("retake: %d measured, %d moved and written into %s"
% (len(readings), len(moves), baseline))
return 0
# --------------------------------------------------------------------- selftest
FIXTURES = {
"CHECK-a": "#!/bin/bash\necho 'PASS a is green'\nexit 0\n",
"CHECK-b": "#!/bin/bash\necho 'warming up'\necho 'FAIL b is red'\nexit 1\n",
"CHECK-loud": "#!/bin/bash\nprintf 'ok %0300d\\n' 0\nexit 0\n",
"CHECK-tabbed": "#!/bin/bash\nprintf 'FAIL tabbed\\tfaultline after the tab\\n'\nexit 1\n",
}
def selftest(verbose=False):
import tempfile
cell_failed = 0
cells = 0
def cell(name, ok, detail=""):
nonlocal cell_failed, cells
cells += 1
if not ok:
cell_failed += 1
print(" %-24s %s %s" % (name, "PASS" if ok else "FAIL", detail if
(verbose or not ok) else ""))
def run(argv):
"""main() with its report captured, so cell lines stay readable."""
import contextlib
import io
buf = io.StringIO()
with contextlib.redirect_stdout(buf):
rc = main(argv)
return rc, buf.getvalue()
work = tempfile.mkdtemp(prefix="retake-selftest.")
try:
tree = os.path.join(work, "tree")
os.makedirs(tree)
for name, body in FIXTURES.items():
p = os.path.join(tree, name)
with open(p, "w", encoding="utf-8") as fh:
fh.write(body)
os.chmod(p, 0o755)
base = os.path.join(work, "baseline.tsv")
green = ("# path\trc\tnote -- fixture baseline\n"
"# a comment that must survive a rewrite\n"
"CHECK-a\t0\tPASS a is green\n"
"CHECK-b\t1\tFAIL b is red\n")
with open(base, "w", encoding="utf-8") as fh:
fh.write(green)
# 1 -- green control: a baseline that agrees with the tree moves nothing
rc, _o = run(["--baseline", base, "--repo", tree, "--all"])
cell("green-control", rc == 0, "rc=%d" % rc)
# 2 -- a moved code is named, and the dry run writes nothing
with open(base, "w", encoding="utf-8") as fh:
fh.write(green.replace("CHECK-b\t1\tFAIL b is red",
"CHECK-b\t0\tFAIL b is red"))
before = open(base, encoding="utf-8").read()
rc, _o = run(["--baseline", base, "--repo", tree, "--all"])
after = open(base, encoding="utf-8").read()
cell("moved-code-named", rc == 1 and after == before,
"rc=%d bytes-unchanged=%s" % (rc, after == before))
# 3 -- the write moves exactly that row and keeps the comments
rc, _o = run(["--baseline", base, "--repo", tree, "--all", "--write"])
text = open(base, encoding="utf-8").read()
_l, rows = parse_baseline(base)
rc2, _o2 = run(["--baseline", base, "--repo", tree, "--all"])
code = {r["path"]: r["rc"] for r in rows}
cell("write-updates-row", rc == 0 and code["CHECK-b"] == 1
and "a comment that must survive" in text
and "retake.py" in text and rc2 == 0,
"rc=%d b=%d idempotent_rc=%d" % (rc, code["CHECK-b"], rc2))
# 4 -- a baseline row with no file in the tree is a refusal, not a skip
with open(base, "w", encoding="utf-8") as fh:
fh.write(green + "CHECK-gone\t0\tnothing\n")
rc, _o = run(["--baseline", base, "--repo", tree, "--all", "--write"])
text = open(base, encoding="utf-8").read()
cell("missing-row-refused", rc == 1 and "CHECK-gone\t0" in text,
"rc=%d untouched=%s" % (rc, "CHECK-gone\t0" in text))
# 5 -- a malformed baseline cannot be graded (2, never a pass)
with open(base, "w", encoding="utf-8") as fh:
fh.write(green + "CHECK-a\tnot-an-int\tx\n")
rc, _o = run(["--baseline", base, "--repo", tree, "--all"])
cell("malformed-ungradable", rc == 2, "rc=%d" % rc)
# 6 -- the note is cut at the same width the sweep uses
with open(base, "w", encoding="utf-8") as fh:
fh.write("# path\trc\tnote\nCHECK-loud\t1\tstale\n")
rc, _o = run(["--baseline", base, "--repo", tree, "--all", "--write"])
_l, rows = parse_baseline(base)
note = rows[0]["note"] if rows else ""
cell("note-cut", rc == 0 and 0 < len(note) <= NOTE_CUT,
"len=%d" % len(note))
# 7 -- the fault-hint rule is the sweep's: the FAIL line, not the last
rc, note = run_entry(tree, "CHECK-b", 30)
cell("fault-hint-parity", rc == 1 and note.startswith("FAIL b is red"),
"note=%r" % note)
# 8 -- the contract is imported, not re-implemented
cell("contract-imported", run_entry is check_sweep.run_entry
and classify is check_sweep.classify, "")
# 9 -- a baseline that does not name every entry point invents no rows
with open(base, "w", encoding="utf-8") as fh:
fh.write("# path\trc\tnote\nCHECK-a\t0\tPASS a is green\n")
rc, _o = run(["--baseline", base, "--repo", tree, "--all", "--write"])
_l, rows = parse_baseline(base)
cell("invents-no-rows", rc == 0 and len(rows) == 1
and rows[0]["path"] == "CHECK-a", "rows=%d" % len(rows))
# 10 -- this file names no host path
src = open(os.path.abspath(__file__), encoding="utf-8").read()
cell("no-host-path", ("/" + "root/") not in src, "")
# 11 -- a path the baseline does not name is measured and signed once
with open(base, "w", encoding="utf-8") as fh:
fh.write("# path\trc\tnote\nCHECK-a\t0\tPASS a is green\n")
rc, _o = run(["--baseline", base, "--repo", tree, "--sign", "CHECK-b"])
_l, rows = parse_baseline(base)
signed = {r["path"]: r["rc"] for r in rows}
rc2, _o2 = run(["--baseline", base, "--repo", tree, "--sign", "CHECK-b"])
cell("sign-once", rc == 0 and signed.get("CHECK-b") == 1 and rc2 == 1
and len(rows) == 2,
"rc=%d b=%s again_rc=%d rows=%d"
% (rc, signed.get("CHECK-b"), rc2, len(rows)))
# 12 -- a fault line carrying a tab stays one note cell, and the sweep's
# own reader reads the whole line back. Written verbatim it became four
# fields and read back as "FAIL tabbed": a writer that reports success
# and a reader that grades a truncated string.
with open(base, "w", encoding="utf-8") as fh:
fh.write("# path\trc\tnote\nCHECK-tabbed\t0\tstale\n")
rc, _o = run(["--baseline", base, "--repo", tree, "--all", "--write"])
raw = [l for l in open(base, encoding="utf-8").read().split("\n")
if l.startswith("CHECK-tabbed")]
nf = len(raw[0].split("\t")) if raw else 0
_r, srows = check_sweep.read_baseline(base)
got = srows[0][2] if srows else ""
want = "FAIL tabbed faultline after the tab"
cell("note-sanitised", rc == 0 and nf == 3 and got == want,
"rc=%d fields=%d note=%r" % (rc, nf, got))
finally:
import shutil
shutil.rmtree(work, ignore_errors=True)
print("selftest: %d cell(s), %d passed, %d failed"
% (cells, cells - cell_failed, cell_failed))
return 0 if cell_failed == 0 else 1
if __name__ == "__main__":
raise SystemExit(main())