From 4d7e8b43cfa0f606e91a38658c1109d90fd6e7b5 Mon Sep 17 00:00:00 2001 From: Timmy Date: Sat, 17 Oct 2026 03:34:07 +0000 Subject: [PATCH] tools (volt): census_row_delta.py -- a row-level partition of two censuses, and the 96->95 pair measured instead of argued The briefs over the 2026-10-16 digest-rev fix agreed on the new census total and disagreed on the partition, because a partition is a property of the two runs AND of the key a row is identified by. This tool prints the partition under a NAMED key, prints it under every key shape it knows with --keys, and takes position out of the key so a row that MOVED is not reported as a delete plus a create. Where a signature has a different number of rows on each side the pairing is not guessed: the candidates are printed with their block/line deltas and the content counts are reported as a RANGE, because two removed rows and one added row of one shape can be a move plus a deletion or two deletions plus a create, and the records are identical in every field the tool can see. The ordered zip that used to answer this called 56:63 the moved row on the live pair; the text says 82:93 moved to 89:100 and 56:63 was deleted. Count right, identity wrong -- the defect class this tool exists for. selftest: 33 cells, 33 passed, 0 failed. --- tools/census_row_delta.py | 438 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 438 insertions(+) create mode 100644 tools/census_row_delta.py diff --git a/tools/census_row_delta.py b/tools/census_row_delta.py new file mode 100644 index 0000000..a3930cd --- /dev/null +++ b/tools/census_row_delta.py @@ -0,0 +1,438 @@ +#!/usr/bin/env python3 +"""census_row_delta.py -- row-level diff of two doc_census_check.py censuses. + +WHY THIS EXISTS + `tools/doc_census_check.py` prints a census; the number a reader quotes is its + row total. When that total moved (the digest-rev fix of 2026-10-16), the + sentence that mattered was not the total but the PARTITION: how many rows were + REMOVED, how many ADDED, how many CHANGED VERDICT. Two briefs over the same + pair of runs reached the same new total with different partitions -- nineteen + removed and three added in one, twenty removed and four added in the other -- + and both are arithmetically consistent, because the partition is not a property + of the two runs alone. It is a property of the two runs AND of the key a row is + identified by. A census row is a record (tool, block, line, rev, unit, claim, + token, verdict); pick a different subset of those as the identity and you + rename a row that only moved position into a row that was deleted and another + that was created. + + So this tool prints the partition under a NAMED key, never a bare "removed N", + and `--keys` prints it under every key shape it knows -- so a disagreement + about the count can be resolved to the key that produced it instead of argued + about. Every partition is then restated with position taken out of the key: a + removed row and an added row whose records agree on every field the key holds + fixed are ONE row that MOVED, reported separately from a row that was deleted + or introduced. Reading a position shift as a content change is the whole defect + class this tool exists for. + +WHAT IT READS + Two JSON files written by `doc_census_check.py --json`. It does not run the + census and does not judge a census: it cannot see anything the JSON does not + carry, and it makes no claim about which census is right. + +READ-ONLY. The only write path is `--json PATH`; every other mode prints. + +A STATED LIMIT, NOT AN IMPLIED ONE + Rows are compared as records, so a claim whose TEXT moved between blocks (a + docstring line re-wrapped, a claim reworded) is REMOVED and ADDED, never + CHANGED. `--moves` catches the pure-position case and nothing else; a reworded + claim is reported as a delete plus a create and is not paired. The key shapes + below are the whole vocabulary this tool has for that; it invents no similarity + metric. + +PASS-THROUGH, because a census leg drives every tool as `