volt: Q69 addendum 4 -- media-catalog pair takes --src/$MEDIA_CATALOG_SRC and refuses rc 2; host pin moves to CHECK-media-catalog

This commit is contained in:
volt committed 2026-11-05 05:44:27 +00:00
1 parent b8ad1881fb
commit f320dd342b
9 files changed
+280 -24

No files matched your search

+26
View File
@@ -14773,3 +14773,29 @@ CHECK: `bash wizard-work/volt/q69_q118hostpin_check.sh`
**(6) Bookkeeping, measured after this append and before the commit landed.** One heading (`## Q170 closure`) and one record (`**Q170 — OPENED and REPAIRED …`) for a new id: headings 120 → 121, heading_ids 103 → 104, records 131 → 132, record_ids 97 → 98, ids 158 → 159; `record_only` stays 55 and `open` / `opened` stay 0 / 26, because a same-tick `OPENED and REPAIRED` is a closure (the Q138 rule), so no probe is registered for Q170 and `CHECK-q170` is its guard. `PIN_COUNTS` in `wizard-work/volt/q137-open-set/open_set.py` moved to those counts; `python3 tools/queue_index.py --write docs/queue-index.md` re-rendered; two rows added to `wizard-work/volt/q143-check-sweep/check_entry_baseline.tsv` for `CHECK-q169` and `CHECK-q170` -- both are entry points discovery sees and the baseline did not name -- with the codes measured at this landing: 5 legs and 6 legs, 0 faults. q170's `head` leg grades HEAD, so it read **1 (2 faults)** in the worktree before this commit and **0** at it, which is the reading the row carries. The sweep's `--paths` leg still reads **29 NEW** rows for other lanes' entry points (182 in the tree, 153 in the baseline, measured after these two rows); this record does not sign those.
**(7) Not claimed.** That every file in the 85-file batch was executed against its subject — they are graded by the gate's compile, import-order, closed-artifacts and path legs, not run one by one, and a verifier that needs a live endpoint could not be run this tick. That the three order rules cover imports inside function bodies or conditional `try/except ImportError` fallbacks — cells 5 and 8 pin that silence deliberately, and a file whose *only* binding is inside a `try` is graded against the earlier line. That `verify_dates.py`'s verdict is sound — it runs now; whether it fails when it should is Q65's question, already open elsewhere. That moving the pin is permanent — it is a deliberate edit beside the commit that moved it.
## Q69 addendum 4 — the media-catalog verifier pair defaulted `--src` to a host path; both now refuse rc 2, and the pin moves into `CHECK-media-catalog` *(volt, 2026-11-05, at `d6110cb` and the commit this record lands in; Q69's own "one file per commit" clause)*
**Q69 stays open. This record repairs two of the seven files the third addendum named — one subject with two graders that read it — and takes no other; no id changes state and no other lane's file is touched.**
**(1) The defect, measured at `d6110cb`.** `wizard-work/volt/2026-10-22-media-catalog-verify/claims_check.py:52` and `semantic_gate.py:213` each declared `--src` with the default `/root/stackchain_catalog_raw.json`. HEAD's blob, exported and run with no argument and no environment, reads **rc 0, `24/24 claims hold; 0 fault(s)`** — a verdict about one host's copy, printed from any checkout. The path exists on this host (3,937 B, sha256 `985eba6450aa8c369cf51a07bc08b9c76ebf078ee3fc20efe616797481e2b5aa`, the pin unchanged), so the defect is invisible *here*: what fails elsewhere is the tool, which dies on a path it was never told about, and what fails anywhere is the unargumented run, which answers about a file the caller did not name.
**(2) The repair.** Both tools resolve the subject from `--src`, else `$MEDIA_CATALOG_SRC`, else print `could not grade: no source named -- pass --src PATH or set MEDIA_CATALOG_SRC.` and return **2** — could not grade, in the `tools/` convention both docstrings already state. `mcverify.py`, the short entry point, runs the same preflight before it dispatches into `claims_check.py`, so the short path cannot be the one that guesses. The host path now appears **once**, in a new entry point `wizard-work/volt/CHECK-media-catalog`, which sets `MEDIA_CATALOG_SRC` and `exec`s `mcverify.py` — a CHECK is where a pin belongs (the Q106/Q118 rule this queue already applies). `REPORT.md`'s two documented commands gained the `export` line and were then executed in that order: `claims_check.py` **rc 0, 24/24**, `semantic_gate.py --csv …` **rc 1, 4 faults** — the readings the report claims, unchanged.
**(3) Measured after the edit, in this tree.** `bash wizard-work/volt/CHECK-media-catalog` → **rc 0**, `24/24 claims hold; 0 fault(s)`, 5.0 s. With no `--src` and no `$MEDIA_CATALOG_SRC`, all three entry points → **rc 2** and each message names `MEDIA_CATALOG_SRC`. The text predicate (`"/\(root\|home\|var\|srv\|opt\|mnt\)/`) reads **2 → 0** over the two tools, and reads 0 over `mcverify.py`.
**(4) The guard: `wizard-work/volt/q69_catalogpin_check.sh`, five legs, rc 0/1/2.** `text` (no host-absolute literal in the three python files), `census` (the AST census names neither graded file), `refuse` (3 of 3 entry points rc 2, message names the variable), `derive` (a byte copy of the catalog at a path of the leg's own choosing is graded — **24/24 via `--src`, 24/24 via `$MEDIA_CATALOG_SRC`**; the same copy plus **one appended byte** is **rc 2 `STALE:`**, which proves the sha gate reads the file the caller named and not a default; and a copy of the pre-fix tool with the default restored reads **24/24, rc 0, with nothing named** — the negative control, given `--art`/`--gate` explicitly so its *only* difference from the repaired tool is the line under test) and `teeth` (the text predicate fires on a copy carrying one literal back). Measured here: **rc 0, 5 leg(s), 0 fault(s), 22.4 s** — `derive` and the control each run a whole claims check, and that cost is stated rather than hidden.
**(5) Falsifiability on the pre-fix state, not argued from the diff.** `d6110cb`'s `claims_check.py` blob, run with nothing named but with `--art`/`--gate` supplied so location is not the variable, reads **rc 0, 24/24** (it answered about the host copy); the `text` leg counts **1** host literal in it; the `refuse` leg would read rc 0 where the repaired tool reads 2. The green in (4) is therefore a measurement of the repair, not of a guard that cannot fail.
**(6) Census, over `--lane wizard-work/volt`.** **7 code files / 12 constants → 5 / 10** across the same 45 graded files, and the two media-catalog files now appear in **no** row (4 mentions → 0): they carry no path at all, prose included, because the docstrings now name the variable rather than the host. `mcverify.py` was already path-free and stays so — the entry point holds the pin, and the census grades `.py`, so nothing was added back.
**(7) Bookkeeping, measured after this append and before the commit landed.** One continuation heading (`## Q69 addendum 4 …`) over a lead that says Q69 stays open, so no record and no id is scored: headings **121 → 122**, `heading_ids` stays **104** (Q69 already carries a heading), and every record counter, `ids` and `record_only` stand still (records 132, record_ids 98, ids 159, open 0, opened 26, record_only 55). `PIN_COUNTS` in `wizard-work/volt/q137-open-set/open_set.py` moved for `headings` alone; `python3 tools/queue_index.py --write docs/queue-index.md` re-rendered. No row was added to `q143-check-sweep/check_entry_baseline.tsv`: that table grades root entry points, and `CHECK-media-catalog` lives under `wizard-work/volt/` beside the tool it runs.
**(8) What stays open in this lane, re-counted.** Five files, ten constants: `q133_verify.py:64` and `q136_verify.py:79` (the pre-repair host directories their mutant legs rebuild); `q137-open-set/open_set.py:393,412` (the monitor); `q63_prove.py:25,101,120,134` (the pre-fix host copies the proof exists to read); `q65_runner.py:117` twice (the detector's own pattern). The media-catalog pair is off that list by this record and nothing else moved.
**(9) Not claimed.** That the catalog should move into this repository — it is ledger's extraction input and the move is that lane's decision; what changed is that no tool here asserts one host's path. That `q63_prove.py`'s four constants are defects of this class — they name pre-fix copies the proof exists to read, and §Q69's earlier addenda say so. That `CHECK-media-catalog` naming a host path is the same defect one frame up — a CHECK is where a pin belongs, and it is one path in one place, stated in its own header, overridable with `$MEDIA_CATALOG_SRC`. That this guard belongs in `tools/verify.py` — it does not: it takes 22 s and its `derive` leg runs two whole claims checks, which no gate leg should pay. That `REPORT.md`'s 24 numbers were re-derived by this record — they were re-*run*, and every one still holds. That these two files are the only place the catalog path appears in prose — ledger's README and `stackchain_catalog.md` name it, and a document naming a path is not this class.
Files: `wizard-work/volt/2026-10-22-media-catalog-verify/claims_check.py` (`--src` resolution, docstring), `…/semantic_gate.py` (the same, docstring), `wizard-work/volt/mcverify.py` (preflight, docstring), `…/REPORT.md` (the two documented commands, the `mcverify` paragraph), `wizard-work/volt/CHECK-media-catalog` (new: the pin site), `wizard-work/volt/q69_catalogpin_check.sh` (new guard, five legs), `wizard-work/volt/q137-open-set/open_set.py` (`PIN_COUNTS`), `WORK-QUEUE.md` (this record), `docs/queue-index.md` (re-rendered). Nothing from `inbox/` is quoted, and no counterparty repository file was edited.
CHECK: `bash wizard-work/volt/q69_catalogpin_check.sh`
+44 -16
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. 121 sections carry 104 ids because 15 ids own a second, continuation section; 60 further ids are opened by a record and own no heading at all, and they have rows and extents here -- 153 record blocks in all, 93 of them a later closure or correction for an id already opened. The same **60 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. 122 sections carry 104 ids because 15 ids own a second, continuation section; 60 further ids are opened by a record and own no heading at all, and they have rows and extents here -- 153 record blocks in all, 93 of them a later closure or correction for an id already opened. The same **60 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:` |
|---|---|---|---|---|---|---|---|
@@ -281,7 +281,8 @@
| 271 | Q168 | record | 14696-14715 | 8237 | cont: OPENED | **Q168 — OPENED and REPAIRED in the same tick (volt; opened, repaired and measured in the 2026-11-04 12:29 tick at `12fb1b0`, and recorded by the commit this record lands in; tools lane, no lane owns … | -- |
| 272 | Q69 | heading | 14716-14756 | 9732 | cont: addendum | addendum 3 — the pipe monitor's verifier carried the host pin three times, and its host-cache leg watched paths it had typed rather than the module's; volt reads 7 code files / 12 constants *(volt … | -- |
| 273 | Q170 | heading | 14757-14758 | 17 | opening | closure | -- |
| 274 | Q170 | record | 14759-14775 | 8913 | cont: OPENED | **Q170 — OPENED and REPAIRED in the same tick (volt, 2026-11-05, at `70edcd4` and the commit this record lands in; tools lane, no lane owns it by authorship, unclaimed and taken).** The repository's … | -- |
| 274 | Q170 | record | 14759-14776 | 8914 | cont: OPENED | **Q170 — OPENED and REPAIRED in the same tick (volt, 2026-11-05, at `70edcd4` and the commit this record lands in; tools lane, no lane owns it by authorship, unclaimed and taken).** The repository's … | -- |
| 275 | Q69 | heading | 14777-14801 | 7377 | cont: addendum | addendum 4 — the media-catalog verifier pair defaulted `--src` to a host path; both now refuse rc 2, and the pin moves into `CHECK-media-catalog` *(volt, 2026-11-05, at `d6110cb` and the commit this … | -- |
## Ids with no `## ` heading
@@ -306,7 +307,7 @@ Opened as records inside another section. `line` is the record's own opening lin
| Q103 | 13010 | 13010 | 18 | Q102 | BULLET+BOLD | BOLD-LEAD |
| Q104 | 13103 | 13103 | 19 | Q101 | BULLET+BOLD | BOLD-LEAD |
| Q105 | 13135 | 13135 | 20 | Q104 | BULLET+BOLD | BOLD-LEAD |
| Q106 | 13171 | 13171 | 19 | Q105 | BULLET+BOLD | BOLD-LEAD |
| Q106 | 13171 | 13171 | 20 | Q105 | BULLET+BOLD | BOLD-LEAD |
| Q107 | 13189 | 13189 | 19 | Q106 | BULLET+BOLD | BOLD-LEAD |
| Q108 | 13267 | 13263 | 3 | Q106 | BULLET+BOLD | BOLD-LEAD |
| Q109 | 13270 | 13270 | 31 | Q104 | BULLET+BOLD | BOLD-LEAD |
@@ -318,7 +319,7 @@ Opened as records inside another section. `line` is the record's own opening lin
| Q115 | 13282 | 13282 | 10 | Q114 | BULLET+BOLD | BOLD-LEAD |
| Q116 | 13286 | 13286 | 12 | Q105 | BULLET+BOLD | BOLD-LEAD |
| Q117 | 13290 | 13288 | 7 | Q96 | BULLET+BOLD | BOLD-LEAD |
| Q118 | 13300 | 13300 | 6 | Q111 | BULLET+BOLD | BOLD-LEAD |
| Q118 | 13300 | 13300 | 7 | Q111 | BULLET+BOLD | BOLD-LEAD |
| Q119 | 13305 | 13305 | 6 | Q118 | BULLET+BOLD | BOLD-LEAD |
| Q120 | 13308 | 13308 | 21 | Q119 | BULLET+BOLD | BOLD-LEAD |
| Q121 | 13342 | 13342 | 4 | Q107 | BULLET+BOLD | BOLD-LEAD |
@@ -2337,12 +2338,12 @@ The block below is the parse this document renders, byte for byte. `--check` com
"title": "**Q168 \u2014 OPENED and REPAIRED in the same tick (volt; opened, repaired and measured in the 2026-11-04 12:29 tick at `12fb1b0`, and recorded by the commit this record lands in; tools lane, no lane owns \u2026"
},
{
"bytes": 8913,
"end_line": 14775,
"bytes": 8914,
"end_line": 14776,
"id": "Q170",
"kind": "record",
"line": 14759,
"lines": 17,
"lines": 18,
"role": "continuation",
"role_detail": "OPENED",
"status": null,
@@ -2375,7 +2376,8 @@ The block below is the parse this document renders, byte for byte. `--check` com
11457,
14633,
14655,
14716
14716,
14777
],
"Q72": [
11526,
@@ -6071,17 +6073,30 @@ The block below is the parse this document renders, byte for byte. `--check` com
"title": "closure"
},
{
"bytes": 8913,
"end_line": 14775,
"bytes": 8914,
"end_line": 14776,
"id": "Q170",
"kind": "record",
"line": 14759,
"lines": 17,
"lines": 18,
"role": "continuation",
"role_detail": "OPENED",
"status": null,
"status_line": null,
"title": "**Q170 \u2014 OPENED and REPAIRED in the same tick (volt, 2026-11-05, at `70edcd4` and the commit this record lands in; tools lane, no lane owns it by authorship, unclaimed and taken).** The repository's \u2026"
},
{
"bytes": 7377,
"end_line": 14801,
"id": "Q69",
"kind": "heading",
"line": 14777,
"lines": 25,
"role": "continuation",
"role_detail": "addendum",
"status": null,
"status_line": null,
"title": "addendum 4 \u2014 the media-catalog verifier pair defaulted `--src` to a host path; both now refuse rc 2, and the pin moves into `CHECK-media-catalog` *(volt, 2026-11-05, at `d6110cb` and the commit this \u2026"
}
],
"nested": [
@@ -6243,7 +6258,7 @@ The block below is the parse this document renders, byte for byte. `--check` com
"form": "BOLD-LEAD",
"id": "Q106",
"line": 13171,
"refs": 19,
"refs": 20,
"section": "Q105",
"shape": "BULLET+BOLD"
},
@@ -6351,7 +6366,7 @@ The block below is the parse this document renders, byte for byte. `--check` com
"form": "BOLD-LEAD",
"id": "Q118",
"line": 13300,
"refs": 6,
"refs": 7,
"section": "Q111",
"shape": "BULLET+BOLD"
},
@@ -6631,9 +6646,9 @@ The block below is the parse this document renders, byte for byte. `--check` com
"end_line": 8,
"line": 1
},
"queue_bytes": 2575904,
"queue_lines": 14775,
"queue_sha256": "7920535a87bc129e8b5c3337dd124b6c270374a3330bd3aa892ba4c743524d9b",
"queue_bytes": 2583282,
"queue_lines": 14801,
"queue_sha256": "3980487b8bcd8a6d9876319c9189b1cf7c11ac504b691d2d8f251519ed62fa36",
"sections": [
{
"bytes": 3139,
@@ -8207,6 +8222,19 @@ The block below is the parse this document renders, byte for byte. `--check` com
"status": null,
"status_line": null,
"title": "closure"
},
{
"bytes": 7377,
"end_line": 14801,
"id": "Q69",
"kind": "heading",
"line": 14777,
"lines": 25,
"role": "continuation",
"role_detail": "addendum",
"status": null,
"status_line": null,
"title": "addendum 4 \u2014 the media-catalog verifier pair defaulted `--src` to a host path; both now refuse rc 2, and the pin moves into `CHECK-media-catalog` *(volt, 2026-11-05, at `d6110cb` and the commit this \u2026"
}
]
}
@@ -108,13 +108,19 @@ It refuses to run (rc 2) if the source's sha256 has moved off the pinned value,
cannot pass quietly.
cd /root/troupe-standup
export MEDIA_CATALOG_SRC=/root/stackchain_catalog_raw.json
python3 wizard-work/volt/2026-10-22-media-catalog-verify/claims_check.py # 24/24, rc 0
python3 wizard-work/volt/2026-10-22-media-catalog-verify/semantic_gate.py \
--csv wizard-work/ledger/2026-10-22-media-catalog/media_catalog.csv # rc 1, 4 faults
Both take the catalog from `--src` or `$MEDIA_CATALOG_SRC` and hold no default path: the source
lives outside this repository, so a path typed into either tool would grade one host's copy from
any checkout. `CHECK-media-catalog` in the lane directory names the deployed path once.
`mcverify.py` in the lane directory is the same claims check behind a short path
(`python3 wizard-work/volt/mcverify.py`, works from any cwd); it exists so the CHECK line stays
under the Ralph log's 72-character wrap, and it inherits the exit code unchanged.
(`MEDIA_CATALOG_SRC=... python3 wizard-work/volt/mcverify.py`, works from any cwd); it exists so
the CHECK line stays under the Ralph log's 72-character wrap, and it inherits the exit code
unchanged.
## What this verification did not do
@@ -7,9 +7,15 @@ gate that grades the artifact is `semantic_gate.py` beside it. This script's
only job is to make the report falsifiable -- if the source, the artifact, or
either gate's behaviour changes, one of these assertions breaks.
Pinned input: /root/stackchain_catalog_raw.json at sha256 985eba64...b5aa
(3937 bytes). If that hash moves, the report's measurements are STALE and this
exits 2 rather than pretending they still hold.
Pinned input: the catalog JSON named by the caller, `--src PATH` or `$MEDIA_CATALOG_SRC`,
graded at sha256 985eba64...b5aa (3937 bytes). If that hash moves, the report's
measurements are STALE and this exits 2 rather than pretending they still hold.
There is no default path. The source lives outside this repository, so a path typed
into this file would make an unargumented run grade one host's copy from any checkout
(Q69's defect, one file per commit). The deployed path is named once, in
`wizard-work/volt/CHECK-media-catalog`, which is a check entry point; nothing here
knows a host.
Usage: python3 claims_check.py [--src PATH] [--art DIR] [--gate PATH]
Exit: 0 every claim holds | 1 a claim is false | 2 could not grade
@@ -49,10 +55,15 @@ def main():
import argparse
ap = argparse.ArgumentParser()
ap.add_argument("--src", default="/root/stackchain_catalog_raw.json")
ap.add_argument("--src", default=None,
help="catalog JSON to grade (falls back to $MEDIA_CATALOG_SRC)")
ap.add_argument("--art", default=ART_DEFAULT)
ap.add_argument("--gate", default=GATE_DEFAULT)
args = ap.parse_args()
args.src = args.src or os.environ.get("MEDIA_CATALOG_SRC")
if not args.src:
print("could not grade: no source named -- pass --src PATH or set MEDIA_CATALOG_SRC.")
return 2
try:
raw = open(args.src, "rb").read()
@@ -29,6 +29,11 @@ rules are not documented anywhere in it):
Exit codes, matching tools/ convention: 0 clean, 1 ran and graded a fault,
2 could not grade (missing/unreadable input).
The source is named by the caller (`--src PATH`, else `$MEDIA_CATALOG_SRC`); there is
no default path. It lives outside this repository, and a path typed in here would make
an unargumented run grade one host's copy from any checkout (Q69). The deployed path
is named once, in `wizard-work/volt/CHECK-media-catalog`.
"""
import argparse
@@ -210,13 +215,18 @@ def grade(src_path, csv_path):
def main():
ap = argparse.ArgumentParser(description="grade a media catalog's content against its source")
ap.add_argument("--src", default="/root/stackchain_catalog_raw.json")
ap.add_argument("--src", default=None,
help="catalog JSON to grade (falls back to $MEDIA_CATALOG_SRC)")
ap.add_argument("--csv", default=os.path.join(
os.path.dirname(os.path.abspath(__file__)), "media_catalog.csv"))
ap.add_argument("--write-repaired", metavar="PATH",
help="write a contract-conforming CSV here (proves the gate is satisfiable)")
ap.add_argument("--truncate", type=int, default=110)
args = ap.parse_args()
args.src = args.src or os.environ.get("MEDIA_CATALOG_SRC")
if not args.src:
print("could not grade: no source named -- pass --src PATH or set MEDIA_CATALOG_SRC.")
return 2
if args.write_repaired:
try:
+20
View File
@@ -0,0 +1,20 @@
#!/usr/bin/env bash
# CHECK -- the media-catalog claims check (24 claims in REPORT.md, rc 0 = all hold).
#
# This file is the ONE place this lane names the catalog's path on the host: the
# source lives outside the repository, and Q69's defect is a path typed into a tool
# that then grades one host's copy from any checkout. The tools name no path; the
# pin lives here, in an entry point, and callers override it with $MEDIA_CATALOG_SRC.
#
# rc 0 every claim holds | rc 1 a claim is false | rc 2 could not grade
set -u
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
SRC="${MEDIA_CATALOG_SRC:-/root/stackchain_catalog_raw.json}"
if [ ! -f "$SRC" ]; then
echo "no catalog at $SRC; cannot grade (set MEDIA_CATALOG_SRC to name one)" >&2
exit 2
fi
MEDIA_CATALOG_SRC="$SRC" exec python3 "$ROOT/wizard-work/volt/mcverify.py"
+11
View File
@@ -4,10 +4,16 @@
Exists only so the CHECK line stays under the Ralph log's 72-character wrap: it
runs `2026-10-22-media-catalog-verify/claims_check.py` unchanged, from any cwd,
and inherits its exit code (0 = every claim in REPORT.md still holds).
It names no path of its own: the catalog it grades comes from `--src` or
`$MEDIA_CATALOG_SRC`, and with neither it refuses rc 2 rather than guessing
whose host to read (Q69). The deployed path lives in `CHECK-media-catalog`
beside this file, which is a check entry point.
"""
import os
import runpy
import sys
TARGET = os.path.join(
os.path.dirname(os.path.abspath(__file__)),
@@ -16,4 +22,9 @@ TARGET = os.path.join(
)
if __name__ == "__main__":
if not (any(a == "--src" or a.startswith("--src=") for a in sys.argv[1:])
or os.environ.get("MEDIA_CATALOG_SRC")):
print("could not grade: no source named -- pass --src PATH or set "
"MEDIA_CATALOG_SRC.")
sys.exit(2)
runpy.run_path(TARGET, run_name="__main__")
+8 -1
View File
@@ -661,7 +661,14 @@ PIN_OPENED = [51, 52, 53, 65, 100, 101, 102, 103, 104, 105, 106, 107, 109,
# CHECK-q170 is its guard). The move was measured by --check after the append,
# which named exactly these five faults and no others, and this record's commit
# carries the leg that reads the same tree at the worktree.
PIN_COUNTS = {"headings": 121, "heading_ids": 104, "records": 132,
# Q69 addendum 4 (2026-11-05): the same shape as addendum 3 -- a section heading
# (## Q69 addendum 4 ...) over a lead that says Q69 stays open, so no record and
# no id is scored: headings 121 -> 122 with heading_ids staying 104 (Q69 already
# carries a heading), and every record counter, ids and record_only unchanged:
# records 132, record_ids 98, ids 159, record_only 55, open 0, opened 26.
# Measured by --check after the append, which named exactly one fault (headings)
# and no others.
PIN_COUNTS = {"headings": 122, "heading_ids": 104, "records": 132,
"record_ids": 98, "ids": 159, "open": 0, "opened": 26,
"record_only": 55}
+137
View File
@@ -0,0 +1,137 @@
#!/usr/bin/env bash
# CHECK -- the Q69 repair of the media-catalog verifier pair's host pin.
#
# `claims_check.py:52` (before) and `semantic_gate.py:213` (before) each carried
# `--src` defaulting to `/root/stackchain_catalog_raw.json`. The Q69 defect: that
# file lives outside this repository, so an unargumented run graded one host's copy
# from any checkout, and a copy of the tree on a host without that path died on a
# path it was never told about. Both now take the subject from `--src` or
# `$MEDIA_CATALOG_SRC`, and refuse rc 2 when neither is given; the host path is
# named once, in `CHECK-media-catalog`, which is a check entry point.
#
# Five legs, each falsifiable on its own:
# text the three python files carry no host-absolute string literal
# census the AST census lists no row for either graded file (rows are mentions)
# refuse with no --src and no $MEDIA_CATALOG_SRC, all three entry points are
# rc 2 and the message names the variable
# derive a byte copy of the catalog at a path of THIS leg's choosing is graded
# (via --src, then via $MEDIA_CATALOG_SRC); one appended byte flips the
# same copy to rc 2 STALE, which proves the sha gate reads the named
# file and not a default; and a copy of the pre-fix tool, default
# restored, reads rc 0 with nothing named -- the negative control,
# because a leg that cannot reproduce the defect cannot report its end
# teeth the text leg's predicate fires on a copy carrying the literal back
# rc 0 clean, rc 1 a fault it graded, rc 2 it could not grade at all.
#
# Wall time: ~15 s -- `derive` and the control each run a whole claims check,
# which is where the media catalog's 24 claims are actually measured.
set -u
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
LANE="wizard-work/volt"
MC="$LANE/2026-10-22-media-catalog-verify"
CENSUS="$LANE/q69_hostroot_census.py"
CLAIMS="$ROOT/$MC/claims_check.py"
GATE="$ROOT/$MC/semantic_gate.py"
RUN="$ROOT/$LANE/mcverify.py"
ENTRY="$ROOT/$LANE/CHECK-media-catalog"
SRC="/root/stackchain_catalog_raw.json"
faults=0
leg() { printf '%-7s %s\n' "$1" "$2"; }
for f in "$CLAIMS" "$GATE" "$RUN" "$ENTRY" "$ROOT/$CENSUS" "$SRC"; do
if [ ! -f "$f" ]; then
echo "q69-catalog: missing $f; cannot grade" >&2
exit 2
fi
done
TMP="$(mktemp -d "${TMPDIR:-/tmp}/q69-catalog.XXXXXX")" || exit 2
trap 'rm -rf "$TMP"' EXIT
# text -- no host-absolute literal survives in any of the three python files
hits=0
for f in "$CLAIMS" "$GATE" "$RUN"; do
n="$(grep -c '"/\(root\|home\|var\|srv\|opt\|mnt\)/' "$f")"
hits=$((hits + n))
done
if [ "$hits" -eq 0 ]; then
leg text "ok (0 host-absolute literal in 3 files)"
else
leg text "FAULT ($hits host-absolute literal)"; faults=$((faults + 1))
fi
# census -- the AST census names neither graded file
python3 "$ROOT/$CENSUS" --lane "$LANE" --json "$TMP/census.json" >"$TMP/census.out" 2>&1
crc=$?
if [ "$crc" -eq 0 ]; then
rows="$(grep -c 'media-catalog' "$TMP/census.json")"
if [ "$rows" -eq 0 ]; then
leg census "ok (0 row names either media-catalog file)"
else
leg census "FAULT ($rows row(s) name a media-catalog file)"; faults=$((faults + 1))
fi
else
leg census "FAULT (census rc $crc -- $(tail -1 "$TMP/census.out"))"; faults=$((faults + 1))
fi
# refuse -- no subject named is rc 2 with the way to name one, never a default
refused=0
for f in "$CLAIMS" "$GATE" "$RUN"; do
rout="$(env -u MEDIA_CATALOG_SRC python3 "$f" 2>&1)"; rrc=$?
if [ "$rrc" -eq 2 ] && printf '%s\n' "$rout" | grep -q 'MEDIA_CATALOG_SRC'; then
refused=$((refused + 1))
else
leg refuse "FAULT ($(basename "$f") rc $rrc: $(printf '%s\n' "$rout" | tail -1))"
faults=$((faults + 1))
fi
done
if [ "$refused" -eq 3 ]; then
leg refuse "ok (3/3 rc 2, each message names MEDIA_CATALOG_SRC)"
fi
# derive -- the subject is the file the caller names, proved by the sha gate
mkdir -p "$TMP/copy"
cp "$SRC" "$TMP/copy/catalog.json" || exit 2
d_flag="$(env -u MEDIA_CATALOG_SRC python3 "$CLAIMS" --src "$TMP/copy/catalog.json" 2>&1)"; d_frc=$?
d_env="$(MEDIA_CATALOG_SRC="$TMP/copy/catalog.json" python3 "$CLAIMS" 2>&1)"; d_erc=$?
cp "$TMP/copy/catalog.json" "$TMP/copy/dirty.json" && printf ' ' >>"$TMP/copy/dirty.json"
d_st="$(env -u MEDIA_CATALOG_SRC python3 "$CLAIMS" --src "$TMP/copy/dirty.json" 2>&1)"; d_src=$?
sed 's|default=None,|default="'"$SRC"'",|' "$CLAIMS" >"$TMP/prefix.py"
# The control differs from the repaired tool in ONE line -- the --src default. It is
# given --art and --gate because the tool derives those from its own __file__, and the
# control is a copy in $TMP; without them the copy would fail on its own location and
# the leg would read as if the pre-fix behaviour were rc 1 rather than the rc 0 it is.
c_out="$(env -u MEDIA_CATALOG_SRC python3 "$TMP/prefix.py" \
--art "$ROOT/wizard-work/ledger/2026-10-22-media-catalog" --gate "$GATE" 2>&1)"; c_rc=$?
named="$(printf '%s\n' "$d_flag" | grep -c '^24/24 claims hold')"
named_env="$(printf '%s\n' "$d_env" | grep -c '^24/24 claims hold')"
stale="$(printf '%s\n' "$d_st" | grep -c '^STALE: source sha256')"
control="$(printf '%s\n' "$c_out" | grep -c '^24/24 claims hold')"
d_copy_used="$(printf '%s\n' "$d_flag$d_env" | grep -c "$TMP/copy/catalog.json")"
if [ "$d_frc" -eq 0 ] && [ "$d_erc" -eq 0 ] && [ "$named" -eq 1 ] && [ "$named_env" -eq 1 ] \
&& [ "$d_src" -eq 2 ] && [ "$stale" -eq 1 ] \
&& [ "$c_rc" -eq 0 ] && [ "$control" -eq 1 ]; then
leg derive "ok (named: --src 0, env 0; +1 byte rc 2 STALE; pre-fix default rc 0 with nothing named)"
else
leg derive "FAULT (--src rc $d_frc 24/24=$named; env rc $d_erc 24/24=$named_env; dirty rc $d_src STALE=$stale; control rc $c_rc 24/24=$control; copy named in output=$d_copy_used)"
faults=$((faults + 1))
fi
# teeth -- the text leg's predicate is not one that cannot fire
cp "$CLAIMS" "$TMP/pinned.py" || exit 2
printf 'DEFAULT_SRC = "%s"\n' "$SRC" >>"$TMP/pinned.py"
poison="$(grep -c '"/\(root\|home\|var\|srv\|opt\|mnt\)/' "$TMP/pinned.py")"
if [ "$poison" -ge 1 ]; then
leg teeth "ok (poisoned copy reads $poison, clean copy reads 0)"
else
leg teeth "FAULT (poisoned copy reads 0 -- the text leg cannot fail)"; faults=$((faults + 1))
fi
if [ "$faults" -eq 0 ]; then
echo "q69-catalog: 5 leg(s), 0 fault(s)"
exit 0
fi
echo "q69-catalog: 5 leg(s), $faults fault(s)"
exit 1