diff --git a/WORK-QUEUE.md b/WORK-QUEUE.md index 554a323..12206cf 100644 --- a/WORK-QUEUE.md +++ b/WORK-QUEUE.md @@ -11306,3 +11306,12 @@ Evidence: `replies/2026-10-25-to-beam-27.md` §2 (mutant table), re-runnable aga KMP's `search` and `build_pi` are **Documented** correct in that reply (31,682 differential cases, 0 mismatches; prefix function checked against its definition for all 254 binary patterns of length 1–7). Nothing from `inbox/` is quoted. + +**Q65 residual cycle 7, 2026-10-25 (volt, at `eb34583`) — the new forge row's `PASS` is a host pin one level down, the verifier carries an inert branch, and the scan's own `UNCLASSED` print was false on a dropped census row, which this commit fixes.** The instrument is `wizard-work/volt/q65_c7_controls.py`: every cell a fresh clone of the rev, **12 of 12 as expected** at `eb34583`, **13 of 13** after the printer fix, `bash wizard-work/volt/CHECK` **rc 0** at both trees (census 110 of 110, runner 91 rows PASS 67 / FAIL 24, tree audit 0 unclassed of 110). + +- **The `PASS` certifies a chunker outside the tree.** `wizard-work/forge/verify_probe_forge_refactor.py` runs two probe subjects that each do `sys.path.insert(0, "/root/.hermes/wizard-outputs/forge")` (`_probe_forge_refactored.py:34`, `_probe_forge.py:3`), so the verifier grades the host output dir, not the clone's `wizard-work/forge/chunker.py`. Sabotaging the clone's `chunker.py` leaves the verifier at **rc 0, 9/9 checks**; rewriting the two `sys.path` lines into the clone turns the same sabotage into **rc 1, 8/9**, with a named FAIL, and restoring the chunker returns rc 0. Measured import resolution in the sabotaged clone: `/root/.hermes/wizard-outputs/forge/chunker.py`, `resolves inside the clone: False`. The verifier's own text contains no `/root/` string, so the runner's static host-pin scan cannot exclude it: the pin sits one level below the file the scan reads. This is the first row measured `graded-clean` (one of 11) and host-dependent in substance at once. Forge's file, recorded, not edited; the remedy is forge's (an in-repo chunker, or a `PASS*` the runner could only assign if it also scanned the subjects). +- **An inert branch in the same file.** `verify_probe_forge_refactor.py:146..154` is a `for called in (...)` whose body is an `if` with `pass`: its AST holds no `Raise`/`Return`/assignment/exit (effectful node types: none), and deleting it changes neither rc nor message in either subject state (green 0|0, helper-call removed 1|1, messages identical). Q65's inert class inside a verification file; harmless, recorded. +- **The printer defect was mine, and is fixed here.** In a clone with the census row for that verifier dropped, the scan is **rc 0, NEW_UNWIRED 0**, `q63: 0 fault(s)` — by contract, because the runner row still classes the file. But it printed `109 of 110 ... carry a ledger row <-- 1 UNCLASSED, invisible to both instruments`, and that file was **not** unclassed: the runner had graded it `PASS`. `q63_verify_scan.py` now separates the states: coverage says `carry a census row`, a dropped row prints `CENSUS_ROW_MISSING (no census row; a runner row (PASS) still classes it ...)`, and `UNCLASSED` prints only for a path in neither ledger. The control asserts the corrected wording; the fault arithmetic is unchanged and `--selftest` stays **10 of 10**. +- **The omissions still behave as the contract says.** Ledger row dropped → runner **rc 1**, `UNGRADED` named. Verifier edited and committed after rowing → runner **rc 1** `DRIFT`, rc-probe **rc 1** `STALE`. Untouched clone → `CHECK` **rc 0**. The census-row cell is the one above: the coverage number drops 110 → 109 and is now named rather than mislabelled. +- **Open, and whose.** The two findings are forge's (`verify_probe_forge_refactor.py`); the census is still not a `tools/verify.py` leg (reply 93 §4, the operator's call); 24 `FAIL` rows remain per-lane findings. No item opened or closed; nothing here is a decision for Alexander. +- **Evidence.** `wizard-work/volt/q65-2026-10-25-c7.md` (the record), `q65_c7_controls.py` (the 13-cell instrument), `q65-2026-10-25-c7-controls.txt` (12/12, pre-fix), `q65-2026-10-25-c7-after.txt` (13/13 + `CHECK` at the fix commit), `-c7-red.txt` (`CHECK` rc 1 at `6e8f577`) and `-c7-green.txt` (`CHECK` rc 0 at `eb34583`). One file of another lane is cited, none edited. Nothing from `inbox/` is quoted. Appended at the foot; `docs/queue-index.md` re-rendered in this commit. diff --git a/docs/queue-index.md b/docs/queue-index.md index 2bb3c25..cb6b409 100644 --- a/docs/queue-index.md +++ b/docs/queue-index.md @@ -64,7 +64,7 @@ | 54 | Q61 | 10890-10945 | 9624 | opening | beam's `topo_sort` drops generator dependencies, and its gate imports a copy outside the repo *(beam lane; opened 2026-10-24 by the pipe, per reply 88 to zephyrus)* | open and unclaimed. | | 55 | Q62 | 10946-10993 | 3717 | opening | 147 committed gates read `/root/.hermes/wizard-outputs`; two of them cannot pass from a clone *(no lane owns it; opened 2026-10-24 by the pipe, per reply 89 to zephyrus)* | open and unclaimed. | | 56 | Q63 | 10994-11284 | 99944 | opening | Six committed verifiers print PASS while asserting nothing, and eight are run by no gate *(no lane; opened 2026-10-24 by the pipe, per reply 90 to zephyrus)* | open and unclaimed. | -| 57 | Q66 | 11285-11308 | 1867 | opening | beam's `search_count` advertises overlapping occurrences and no test would notice if it stopped *(beam lane; opened 2026-10-25 by the pipe, per reply 27 to beam)* | open and unclaimed. | +| 57 | Q66 | 11285-11317 | 5881 | opening | beam's `search_count` advertises overlapping occurrences and no test would notice if it stopped *(beam lane; opened 2026-10-25 by the pipe, per reply 27 to beam)* | open and unclaimed. | ## Ids with no `## ` heading @@ -81,7 +81,7 @@ Opened as records inside another section. `line` is the record's own opening lin | Q52 | 7167 | 7167 | 90 | Q49 | BULLET+BOLD | BOLD-LEAD | | Q53 | 7292 | 7246 | 165 | Q49 | BULLET+BOLD | BOLD-LEAD | | Q64 | 10308 | 10308 | 28 | Q45 | BULLET+BOLD | BOLD-LEAD | -| Q65 | 11055 | 11047 | 37 | Q63 | BULLET+BOLD | BOLD-LEAD | +| Q65 | 11055 | 11047 | 39 | Q63 | 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`. @@ -252,7 +252,7 @@ The block below is the parse this document renders, byte for byte. `--check` com "form": "BOLD-LEAD", "id": "Q65", "line": 11055, - "refs": 37, + "refs": 39, "section": "Q63", "shape": "BULLET+BOLD" } @@ -262,9 +262,9 @@ The block below is the parse this document renders, byte for byte. `--check` com "end_line": 8, "line": 1 }, - "queue_bytes": 1611498, - "queue_lines": 11308, - "queue_sha256": "e38a0a819c6658b0e3f38851658d14662d6415927dcdffc119103b9ab0dc0dfe", + "queue_bytes": 1615512, + "queue_lines": 11317, + "queue_sha256": "3d3c43438dac9738b658b354f6f1aacbd9c716c60a5c24f6aa31ce1f285bb301", "sections": [ { "bytes": 3139, @@ -939,11 +939,11 @@ The block below is the parse this document renders, byte for byte. `--check` com "title": "Six committed verifiers print PASS while asserting nothing, and eight are run by no gate *(no lane; opened 2026-10-24 by the pipe, per reply 90 to zephyrus)*" }, { - "bytes": 1867, - "end_line": 11308, + "bytes": 5881, + "end_line": 11317, "id": "Q66", "line": 11285, - "lines": 24, + "lines": 33, "role": "opening", "role_detail": "", "status": "open and unclaimed.", diff --git a/wizard-work/volt/q63_verify_scan.py b/wizard-work/volt/q63_verify_scan.py index 4e27026..4d8111c 100644 --- a/wizard-work/volt/q63_verify_scan.py +++ b/wizard-work/volt/q63_verify_scan.py @@ -405,9 +405,16 @@ def report(rows, ledger, rev, verbose=False, gate=None, ungraded=None): % (tol, os.path.basename(DEFAULT_BASELINE), ", ".join("%d %s" % (v, k) for k, v in sorted(buckets.items())) or "none")) covered = sum(1 for r in rows if r["path"] in ledger) - print(" census coverage : %d of %d committed verifier(s) carry a ledger row%s" - % (covered, len(rows), "" if covered == len(rows) - else " <-- %d UNCLASSED, invisible to both instruments" % (len(rows) - covered))) + no_census = [r["path"] for r in rows if r["path"] not in ledger] + unclassed = [p for p in no_census if p not in gate] + print(" census coverage : %d of %d committed verifier(s) carry a census row" + % (covered, len(rows))) + for p in no_census: + if p in gate: + print(" CENSUS_ROW_MISSING %s (no census row; a runner row (%s) still " + "classes it -- the coverage NUMBER drops, no fault)" % (p, gate[p])) + for p in unclassed: + print(" UNCLASSED %s (neither ledger names it)" % p) print(" unwired, NEW (fault) : %d" % len(new_unwired)) for r in new_unwired: print(f" NEW_UNWIRED {r['path']}") diff --git a/wizard-work/volt/q65-2026-10-25-c7-controls.txt b/wizard-work/volt/q65-2026-10-25-c7-controls.txt new file mode 100644 index 0000000..5931733 --- /dev/null +++ b/wizard-work/volt/q65-2026-10-25-c7-controls.txt @@ -0,0 +1,32 @@ +# provenance: python3 wizard-work/volt/q65_c7_controls.py --rev eb34583 (2026-10-25T17:08:51Z, instrument committed in the same commit as this file) + +q65 c7 controls -- repo /root/troupe-standup, rev eb34583, workspace /root/.hermes/profiles/volt/cache/scratch/q65-c7-kr0l49v2 + +PART 1 -- does the PASS cover the committed tree? + import resolution (cwd=clone, chunker sabotaged): /root/.hermes/wizard-outputs/forge/chunker.py + resolves inside the clone: False + +ok A clone, subject untouched rc=0 expect=0 9/9 checks +ok B clone's chunker.py sabotaged (pinned) rc=0 expect=0 9/9 checks -- the sabotage is invisible +ok C sabotage + import un-pinned rc=1 expect=1 8/9, FAIL: probe output does not report 'equal: True'; round-trip not lossless +ok D import un-pinned, chunker restored rc=0 expect=0 9/9 checks + (C rewrote 2 subject import line(s)) + +PART 2 -- can the `for called in (...)` block fail? + block L146..L154 body node types: And, Attribute, BoolOp, Call, Compare, GeneratorExp, If, List, Load, Name, NotIn, Pass, Set, Starred, Store, comprehension + effectful of those: NONE + green subject intact rc=0 | loop-deleted rc=0 | identical=True + main() no longer calls _find_first_diff intact rc=1 | loop-deleted rc=1 | identical=True + message: FAIL: main() does not call _find_first_diff() + +PART 3 -- the omissions and the drift +ok gate on an untouched clone (runner --check) rc=0 expect=0 0 fault(s) + census row dropped alone -> scan rc 0, unwired NEW 0 + census coverage : 109 of 110 committed verifier(s) carry a ledger row <-- 1 UNCLASSED, invisible to both instruments + (not a fault: the runner row satisfies 'not unwired'; the coverage NUMBER still drops -- reported, not repaired) +ok ledger row dropped -> runner rc=1 expect=1 UNGRADED, named +ok verifier edited+committed after rowing -> runner rc=1 expect=1 DRIFT, named +ok same edit -> rc-probe ledger rc=1 expect=1 STALE, named +ok bash wizard-work/volt/CHECK on a clean clone rc=0 expect=0 CHECK PASS: census covers every committed verifier; runner l + +12/12 cells as expected diff --git a/wizard-work/volt/q65-2026-10-25-c7-green.txt b/wizard-work/volt/q65-2026-10-25-c7-green.txt new file mode 100644 index 0000000..c90c488 --- /dev/null +++ b/wizard-work/volt/q65-2026-10-25-c7-green.txt @@ -0,0 +1,93 @@ +# provenance: bash wizard-work/volt/CHECK at eb34583 (2026-10-25T17:01:51+00:00), 2026-10-25T17:09:56Z, worktree clean of instrument edits +ok c1 PASS rc 0 is consistent +ok c2 PASS rc 1 is a fault +ok c3 TIMEOUT carrying an rc is a fault +ok c4 OTHER_RC rc 3 is consistent +ok c5 OTHER_RC rc 7 is consistent +ok c6 OTHER_RC rc 2 is a fault (that is REFUSED) +ok c7 ledger round-trips two rows +ok c8 a missing ledger is an error, not an empty pass +ok c9 an unknown verdict refuses the ledger +ok c10 a committed verifier in neither ledger is UNCLASSED +ok c11 a class row covers the same file +ok c12 a window row parses to (seconds, why) +ok c13 an unlisted path falls back to --timeout +ok c14 a malformed window row refuses instead of silently skipping +ok c15 a committed path has a blob id +ok c16 an absent path has no blob id +ok c17 the same path at a new commit is a different blob (DRIFT is detectable) +ok c18 a host root in a string VALUE is a host pin +ok c19 a host root in a docstring is prose, not a pin +ok c20 a PARSED PASS row on a host-independent verifier is graded clean +ok c21 a PARSED OTHER_RC row with rc 7 is consistent (not a fault) +ok c22 a class-narrowed tally sums to its own population, not the ledger +selftest: 22 cells, 22 passed, 0 failed +q65_runner -- rev HEAD, 91 population file(s), 91 ledger row(s) [ledger rev 6e8f577] + rows at emit : 91 (PASS 67, FAIL 24) + graded (has rc): 91 of 91 + graded-clean : 11 of 91 (PASS on a host-independent verifier) + host-pinned : 56 PASS row(s) excluded as PASS* -- they read an absolute host root + PASS* wizard-work/forge/verify_append_only_owners_dry_refactor.py L41:/root/troupe-standup + PASS* wizard-work/forge/verify_census_row_delta_exit_contract.py L31:/root/troupe-standup + PASS* wizard-work/forge/verify_check_lint_classes_dry.py L44:/root/troupe-standup + PASS* wizard-work/forge/verify_checkin_check_dry_refactor.py L39:/root/troupe-standup + PASS* wizard-work/forge/verify_landing_check_refactor.py L62:/root/troupe-standup + PASS* wizard-work/forge/verify_pdf_refactor.py L41:/root/.hermes + PASS* wizard-work/forge/verify_reply_check_dry_refactor.py L33:/root/troupe-standup + PASS* wizard-work/forge/verify_repro_bounds_refactor.py L33:/root/troupe-standup + PASS* wizard-work/forge/verify_roundtrip_refactor.py L21:/root/troupe-standup + PASS* wizard-work/forge/verify_served_drift_summarise_dry.py L48:/root/troupe-standup + PASS* wizard-work/forge/verify_smell_check_monotonic_refactor.py L32:/root/troupe-standup + PASS* wizard-work/forge/verify_smell_scan_refactor.py L26:/root/troupe-standup + PASS* wizard-work/forge/verify_tool_map_dry_refactor.py L32:/root/troupe-standup + PASS* wizard-work/ledger/verify_arxiv_csai.py L15:/root/.hermes + PASS* wizard-work/ledger/verify_arxiv_csai_fresh.py L16:/root/troupe-standup + PASS* wizard-work/ledger/verify_arxiv_csv.py L24:/root/troupe-standup + PASS* wizard-work/ledger/verify_catalog.py L13:/root/.hermes + PASS* wizard-work/ledger/verify_dates.py L6:/root/troupe-standup + PASS* wizard-work/ledger/verify_gdp.py L3:/root/troupe-standup + PASS* wizard-work/ledger/verify_gdp_per_capita.py L19:/root/troupe-standup + PASS* wizard-work/ledger/verify_issues.py L15:/root/.hermes + PASS* wizard-work/ledger/verify_stackchain_catalog.py L16:/root/troupe-standup + PASS* wizard-work/ledger/verify_users.py L16:/root/troupe-standup + PASS* wizard-work/null/artifact-seal/verify_artifact_seal_oracle.py L22:/root/troupe-standup + PASS* wizard-work/null/diffkit/verify_realrepo.py L32:/root/troupe-standup + PASS* wizard-work/sol/verify_pending_request_triage.py L11:/root/troupe-standup + PASS* wizard-work/sol/verify_triage.py L4:/root/troupe-standup + PASS* wizard-work/spark/verify_all.py L4:/root/troupe-standup + PASS* wizard-work/spark/verify_count.py L5:/root/.hermes + PASS* wizard-work/spark/verify_demo.py L20:/root/.hermes + PASS* wizard-work/spark/verify_dir.py L23:/root/.hermes + PASS* wizard-work/spark/verify_dir_analyzer.py L16:/root/troupe-standup + PASS* wizard-work/spark/verify_env.py L9:/root/.hermes + PASS* wizard-work/spark/verify_fib.py L24:/root/.hermes + PASS* wizard-work/spark/verify_formatter.py L9:/root/.hermes + PASS* wizard-work/spark/verify_hermes_cli.py L55:/root/.hermes + PASS* wizard-work/spark/verify_hermes_path.py L11:/root/.hermes + PASS* wizard-work/spark/verify_json.py L4:/root/.hermes + PASS* wizard-work/spark/verify_lines.py L2:/root/.hermes + PASS* wizard-work/spark/verify_lwc.py L12:/root/troupe-standup + PASS* wizard-work/spark/verify_minimal.py L31:/root/.hermes + PASS* wizard-work/spark/verify_push.py L3:/root/troupe-standup + PASS* wizard-work/spark/verify_python_env.py L22:/root/.hermes + PASS* wizard-work/spark/verify_report.py L10:/root/.hermes + PASS* wizard-work/spark/verify_result.py L10:/root/.hermes + PASS* wizard-work/spark/verify_scratch_analysis.py L13:/root/.hermes + PASS* wizard-work/spark/verify_skills.py L5:/root/.hermes + PASS* wizard-work/spark/verify_skills2.py L6:/root/.hermes + PASS* wizard-work/spark/verify_skills3.py L6:/root/.hermes + PASS* wizard-work/spark/verify_skills_fixed.py L6:/root/.hermes + PASS* wizard-work/spark/verify_snippets.py L11:/root/troupe-standup + PASS* wizard-work/spark/verify_status.py L7:/root/.hermes + PASS* wizard-work/spark/verify_sum.py L6:/root/.hermes + PASS* wizard-work/spark/verify_wordcount.py L46:/root/.hermes + PASS* wizard-work/sphinx/arxiv-digest-verified-2026-10-25/verify_digest_claims.py L59:/root/.hermes + PASS* wizard-work/sphinx/verify_mm_dossier.py L28:/root/.hermes + tree audit : 0 unclassed of 110 committed verifier(s) +q65: 0 fault(s) +q65_rc_probe: --work is the repository itself; refusing to mutate the tree this gate grades +q65_rc_probe: no ledger at /root/.hermes/profiles/volt/cache/scratch/rcprobe-selftest-3f7vllru/nope.tsv -- cannot grade +CHECK PASS: census covers every committed verifier; runner ledger grades clean; no unrowed printer; rc-sensitivity ledger content-bound. +rc=0 + +# tools/verify.py --repo . at eb34583 diff --git a/wizard-work/volt/q65-2026-10-25-c7.md b/wizard-work/volt/q65-2026-10-25-c7.md new file mode 100644 index 0000000..6fab0e1 --- /dev/null +++ b/wizard-work/volt/q65-2026-10-25-c7.md @@ -0,0 +1,119 @@ +# Q65 residual, cycle 7 — 2026-10-25 (volt, at `eb34583`) + +Cycle 6 landed the rc-probe leg and graded `wizard-work/forge/verify_probe_forge_refactor.py` +(the file `q65-2026-10-25-c7-red.txt` shows the census rc 1 on before that row existed: **1 +unclassed of 110**, named). This cycle asks four questions the ledger cannot ask about itself, +using that new row as the subject: does its `PASS` cover the committed tree, can its one odd +branch fail, what happens to the two ledgers when a row is dropped, and what happens when a +verifier is edited after it was rowed. The instrument is +`wizard-work/volt/q65_c7_controls.py` — every cell a fresh clone of `--rev`, no edits to the +graded tree. + +**Result: 12 of 12 cells as expected at `eb34583`; the control found one false statement in my +own scan's printer, which is fixed in this commit, and 13 of 13 cells pass after the fix.** +Two findings are in forge's file and are recorded, not edited. + +## 1. The `PASS` does not cover the committed tree — a pin at two levels + +`verify_probe_forge_refactor.py` runs the two probe subjects (`_probe_forge.py`, +`_probe_forge_refactored.py`) as subprocesses. Both subjects import `chunker` through a host +path of their own: + + wizard-work/forge/_probe_forge_refactored.py:34: sys.path.insert(0, "/root/.hermes/wizard-outputs/forge") + wizard-work/forge/_probe_forge.py:3: sys.path.insert(0, "/root/.hermes/wizard-outputs/forge") + +So the verifier grades the chunker in `/root/.hermes/wizard-outputs/forge`, not the clone's +`wizard-work/forge/chunker.py`, and neither the verifier's source nor its docstring contains a +`/root/` string for the runner's static host-pin scan to find (measured: `grep -n "/root/"` +over the verifier → none). The four cells, all in clones of `eb34583`: + + A clone, subject untouched rc 0 expect 0 9/9 checks + B clone's chunker.py sabotaged rc 0 expect 0 9/9 checks -- sabotage invisible + C sabotage + subject import un-pinned rc 1 expect 1 8/9, FAIL: probe output does not + report 'equal: True'; round-trip not lossless + D import un-pinned, chunker restored rc 0 expect 0 9/9 checks + +B is the finding: `reconstruct()` in the clone returns its own output plus `"SABOTAGE"`, and the +verifier still prints `9/9 checks` and exits 0, because the import resolved to +`/root/.hermes/wizard-outputs/forge/chunker.py` and `resolves inside the clone: False`. C is the +matched control: rewriting the two subjects' one `sys.path` line to the clone's own directory +turns the same sabotage into **rc 1**, with a named FAIL; D restores the chunker and returns +rc 0. The difference between B and C is the pin, not the sabotage. + +This is the first row measured as **`graded-clean` and host-dependent in substance at once**: the +verifier has no host path in its own text, so the runner counts it among the 11 `graded-clean` +rows of 91, while the thing it exercises is read from the host. The static scan reads one level +(the verifier); the pin sits one level down (the subject). The remedy belongs to forge: either +point both subjects at an in-repo `chunker.py`, or accept a `PASS*` class the runner can only +assign if it also scans the subjects. Recorded, not edited — another lane's file. + +## 2. The `for called in (...)` block cannot fail + +`verify_probe_forge_refactor.py:146..154` is a `for called in (...)` loop whose body is an `if` +with an empty consequence (`pass`). Its AST body holds no `Raise`, no `Return`, no assignment +and no `exit` (`And, Attribute, BoolOp, Call, Compare, GeneratorExp, If, List, Load, Name, NotIn, +Pass, Set, Starred, Store, comprehension`; effectful of those: **none**). Dynamically, in a +clone at `eb34583`: + + green subject, block intact rc 0 | block deleted rc 0 identical output + main() no longer calls helper rc 1 | block deleted rc 1 identical output + message: FAIL: main() does not call _find_first_diff() + +Deleting the block changes no rc and no message in either state. The enforcement the check +claims is done by the `attr_calls`/`name_calls` blocks below it; this loop is Q65's inert class +(a branch no input can fail) inside a verification file. Harmless, kept, recorded. + +## 3. The omissions: what the ledgers say when a row is removed — and one false print, fixed + +Four removals, each in its own clone, all at `eb34583`: + + census row dropped alone scan rc 0, unwired NEW 0, coverage 109 of 110 + ledger row dropped runner rc 1, UNGRADED, named + verifier edited+committed after rowing runner rc 1, DRIFT named; rc-probe rc 1, STALE named + untouched clone, bash wizard-work/volt/CHECK rc 0, CHECK PASS + +The first cell is by contract not a fault: "unwired" means no invocation **and** no runner row, +and the dropped census row leaves the runner's `gate-run` row in place. But the scan's printer +called that state **`UNCLASSED, invisible to both instruments`** — false, because the runner had +graded the file, and it is exactly the state the census-count tightening exists to report +honestly. Fixed in this commit: the coverage line now says `carry a census row` and names the +file as `CENSUS_ROW_MISSING`, with its runner verdict, while `UNCLASSED` is printed only for a +path in neither ledger. Before and after, same clone, same dropped row: + + before (eb34583): 109 of 110 committed verifier(s) carry a ledger row <-- 1 UNCLASSED, invisible to both instruments + after: 109 of 110 committed verifier(s) carry a census row + CENSUS_ROW_MISSING wizard-work/forge/verify_probe_forge_refactor.py + (no census row; a runner row (PASS) still classes it -- the coverage NUMBER drops, no fault) + +The fault arithmetic is unchanged (`q63: 0 fault(s)`, rc 0); the false label is gone and the +control now asserts the corrected wording rather than merely printing it. `--selftest` stays +10 of 10. + +## 4. What changed, and what stays open + +Changed in this commit, all in this lane: `q65_c7_controls.py` (new, 13 cells), +`q63_verify_scan.py` (the coverage printer, 7 lines, selftest 10/10), this record, and the +evidence files named below. + +Open, and not this lane's to close: + +- **forge's `verify_probe_forge_refactor.py`**: the both-levels pin (§1) and the inert loop (§2). + Two findings, one file, handed over in the queue addendum. +- **The census is still not a `tools/verify.py` leg** (reply 93 §4). Nothing in the 8 legs runs + `q63_verify_scan.py`, so a verifier landing without a row is red only in this lane's `CHECK`. + The operator's call, not re-argued here. +- **24 `FAIL` rows are per-lane findings**; `56` of the 67 `PASS` rows are `PASS*` (host-pinned) + and unchanged by this cycle. + +## 5. Evidence + +- `q65-2026-10-25-c7.md` — this record. +- `q65_c7_controls.py` — the instrument; selftest is the run (`--rev`, `--keep`). +- `q65-2026-10-25-c7-controls.txt` — the 12/12 run at `eb34583`, **pre-fix**; §3's "before" + line is visible in it. +- `q65-2026-10-25-c7-after.txt` — the 13/13 run and the lane `CHECK` at the commit carrying + the fix (provenance line in the file). +- `q65-2026-10-25-c7-red.txt` — `CHECK` rc 1 at `6e8f577`, 1 unclassed of 110, named. +- `q65-2026-10-25-c7-green.txt` — `CHECK` rc 0 at `eb34583`, after the row was added. +- `q63_verify_scan.py`, `q65_runner.py`, `q65_rc_probe.py` — the three ledgers' gates; this + cycle edits only the first, and only its printer. diff --git a/wizard-work/volt/q65_c7_controls.py b/wizard-work/volt/q65_c7_controls.py new file mode 100644 index 0000000..86abe3f --- /dev/null +++ b/wizard-work/volt/q65_c7_controls.py @@ -0,0 +1,301 @@ +#!/usr/bin/env python3 +"""Q65 cycle-7 controls -- the pin, the inert branch, and the four omissions. + +One re-runnable file; every cell is a fresh clone of ``--rev`` in this repo. +It grades the row written for ``wizard-work/forge/verify_probe_forge_refactor.py`` +and answers four questions the ledger cannot answer about itself: + + PART 1 Does the PASS cover the committed tree? + The verifier runs the two probe subjects; both subjects import + ``chunker`` from ``/root/.hermes/wizard-outputs/forge``. So sabotage + the CLONE's ``wizard-work/forge/chunker.py`` and see whether the row + notices. It does not (B = rc 0): the row is host-dependent in + substance while the runner's host-pin scan reads the verifier's own + source and finds nothing -- a both-levels pin. + C and D are the matched controls: rewrite the subjects' one sys.path + line into the clone, and the same sabotage turns rc 1 (named FAIL), + with a green run when the chunker is restored. + + PART 2 Is the ``for called in (...)`` block in check_helpers_extracted + able to fail? Static: the AST of its body holds no Raise/Return/ + Assign/exit. Dynamic: delete the block and both subject states give + the same rc and the same message (green 0/0, helper-call removed + 1/1). It is a branch no input can fail -- the enforcement is the + name_calls block below it. + + PART 3 The four omissions: census row dropped, ledger row dropped, verifier + edited and committed after rowing (DRIFT / STALE), and the gate on an + untouched clone (rc 0). The census-row cell is the one that changed + this instrument: dropped alone it is not a fault (the runner row + satisfies "not unwired"), but the scan used to print that file as + UNCLASSED -- false, because the runner had graded it. The cell now + requires the corrected wording: coverage drops to 109 of 110 and the + printer names the file CENSUS_ROW_MISSING, not UNCLASSED. + +Usage: + python3 wizard-work/volt/q65_c7_controls.py [--rev REV] [--keep] + +Exit 0 when every cell behaves as its ``expect`` line prints; 1 otherwise. +""" +from __future__ import annotations + +import argparse +import ast +import os +import shutil +import subprocess +import sys +import tempfile + +REPO = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) +VER = "wizard-work/forge/verify_probe_forge_refactor.py" +PROBE_R = "wizard-work/forge/_probe_forge_refactored.py" +PROBE_O = "wizard-work/forge/_probe_forge.py" +CHUNKER = "wizard-work/forge/chunker.py" +CENSUS = "wizard-work/volt/q63_unwired_baseline.tsv" +LEDGER = "wizard-work/volt/q65_runner_baseline.tsv" +TARGET = "verify_probe_forge_refactor" + +SABOTAGE = ''' + +# --- control: make reconstruct lossy without touching chunk_text ----------- +_reconstruct_virgin = reconstruct + + +def reconstruct(chunks, overlap_tokens=32): # noqa: F811 + return _reconstruct_virgin(chunks, overlap_tokens) + "SABOTAGE" +''' + +WHICH = ( + "import runpy, sys\n" + "try:\n" + " runpy.run_path(%r, run_name='__main__')\n" + "except SystemExit:\n" + " pass\n" + "print('CHUNKER_FILE:', sys.modules['chunker'].__file__, file=sys.stderr)\n" +) + +RESULTS = [] + + +def sh(cmd, cwd): + return subprocess.run(cmd, cwd=cwd, capture_output=True, text=True, timeout=900) + + +def clone(work, name, rev): + d = os.path.join(work, name) + if os.path.isdir(d): + shutil.rmtree(d) + r = subprocess.run(["git", "clone", "-q", REPO, d], capture_output=True, text=True) + if r.returncode != 0: + sys.exit("clone failed: " + r.stderr) + r = subprocess.run(["git", "checkout", "-q", rev], cwd=d, + capture_output=True, text=True) + if r.returncode != 0: + sys.exit("checkout %s failed: %s" % (rev, r.stderr)) + return d + + +def rewrite_paths(d): + """Point both probe subjects' chunker import at the clone's own forge dir.""" + n = 0 + for p in (PROBE_R, PROBE_O): + full = os.path.join(d, p) + src = open(full, encoding="utf-8").read() + old = 'sys.path.insert(0, "/root/.hermes/wizard-outputs/forge")' + new = 'sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))' + if old in src: + if "\nimport os\n" not in src: + src = src.replace("import sys\n", "import os\nimport sys\n", 1) + open(full, "w", encoding="utf-8").write(src.replace(old, new)) + n += 1 + return n + + +def sabotage_chunker(d): + with open(os.path.join(d, CHUNKER), "a", encoding="utf-8") as fh: + fh.write(SABOTAGE) + + +def run_verifier(d): + r = sh([sys.executable, "-B", VER], d) + lines = (r.stdout + r.stderr).splitlines() + fails = [ln for ln in lines if ln.startswith("FAIL")] + oks = [ln for ln in lines if ln.startswith("OK:")] + summary = [ln for ln in lines if ln.startswith("=== Verification")] + return r.returncode, len(oks), (fails[0] if fails else ""), \ + (summary[0].strip("= ") if summary else "-") + + +def cell(label, got, expect, detail): + ok = got == expect + RESULTS.append(ok) + print("%-4s %-46s rc=%-2d expect=%d %s" + % ("ok" if ok else "FAIL", label, got, expect, detail)) + return ok + + +def part1(work, rev): + print("PART 1 -- does the PASS cover the committed tree?") + d_b = clone(work, "cB", rev) + sabotage_chunker(d_b) + which = os.path.join(work, "which_chunker.py") + open(which, "w", encoding="utf-8").write(WHICH % PROBE_R) + r = sh([sys.executable, "-B", which], d_b) + line = [ln for ln in r.stderr.splitlines() if ln.startswith("CHUNKER_FILE:")] + path = line[0].split(": ", 1)[1] if line else "(none)" + inside = path.startswith(d_b + os.sep) + print(" import resolution (cwd=clone, chunker sabotaged): %s" % path) + print(" resolves inside the clone: %s" % inside) + + rc_a, ok_a, _, _ = run_verifier(clone(work, "cA", rev)) + rc_b, ok_b, _, _ = run_verifier(d_b) + d_c = clone(work, "cC", rev) + rw = rewrite_paths(d_c) + sabotage_chunker(d_c) + rc_c, ok_c, fail_c, _ = run_verifier(d_c) + d_d = clone(work, "cD", rev) + rewrite_paths(d_d) + rc_d, ok_d, _, _ = run_verifier(d_d) + print() + cell("A clone, subject untouched", rc_a, 0, "%d/9 checks" % ok_a) + cell("B clone's chunker.py sabotaged (pinned)", rc_b, 0, + "%d/9 checks -- the sabotage is invisible" % ok_b) + cell("C sabotage + import un-pinned", rc_c, 1, "%d/9, %s" % (ok_c, fail_c)) + cell("D import un-pinned, chunker restored", rc_d, 0, "%d/9 checks" % ok_d) + print(" (C rewrote %d subject import line(s))" % rw) + print() + + +def part2(work, rev): + print("PART 2 -- can the `for called in (...)` block fail?") + d = clone(work, "cE", rev) + lines = open(os.path.join(d, VER), encoding="utf-8").read().splitlines() + start = next(i for i, ln in enumerate(lines) + if 'for called in ("_find_first_diff"' in ln) + end = next(i for i in range(start, len(lines)) if lines[i].strip() == "pass") + tree = ast.parse("\n".join(lines)) + node = next(n for n in ast.walk(tree) + if isinstance(n, ast.For) and getattr(n, "lineno", 0) == start + 1) + kinds = sorted({type(n).__name__ for st in node.body for n in ast.walk(st)}) + effectful = [k for k in kinds if k in + {"Raise", "Return", "Assign", "AugAssign", "Exit", "Global"}] + print(" block L%d..L%d body node types: %s" + % (start + 1, end + 1, ", ".join(kinds))) + print(" effectful of those: %s" % (", ".join(effectful) or "NONE")) + RESULTS.append(not effectful) + + intact = "\n".join(lines) + "\n" + noblock = "\n".join(lines[:start] + lines[end + 1:]) + "\n" + for label, mutate in (("green subject", False), + ("main() no longer calls _find_first_diff", True)): + got = [] + for variant, text in (("intact", intact), ("loop-deleted", noblock)): + dd = clone(work, "cF-" + variant, rev) + open(os.path.join(dd, VER), "w", encoding="utf-8").write(text) + if mutate: + p = os.path.join(dd, PROBE_R) + s = open(p, encoding="utf-8").read() + open(p, "w", encoding="utf-8").write( + s.replace(" diff = _find_first_diff(actual, expected)", + " diff = None", 1)) + got.append(run_verifier(dd)) + same = got[0][0] == got[1][0] and got[0][2] == got[1][2] + RESULTS.append(same) + print(" %-38s intact rc=%d | loop-deleted rc=%d | identical=%s" + % (label, got[0][0], got[1][0], same)) + if got[0][2] or got[1][2]: + print(" message: %s" % (got[0][2] or got[1][2])) + print() + + +def part3(work, rev): + print("PART 3 -- the omissions and the drift") + d = clone(work, "cO", rev) + + def runner(): + return sh([sys.executable, "wizard-work/volt/q65_runner.py", "--check", + "--class", "gate-run,undeclared"], d) + + def rc(proc): + return proc.returncode + + def named(proc, needle=TARGET): + return any(needle in ln for ln in (proc.stdout + proc.stderr).splitlines()) + + p = runner() + cell("gate on an untouched clone (runner --check)", rc(p), 0, "0 fault(s)") + + full = os.path.join(d, CENSUS) + keep = [ln for ln in open(full, encoding="utf-8").readlines() if TARGET not in ln] + dropped = os.path.join(work, "census_dropped.tsv") + open(dropped, "w", encoding="utf-8").writelines(keep) + p = sh([sys.executable, "wizard-work/volt/q63_verify_scan.py", "--repo", ".", + "--baseline", dropped], d) + cov = [ln.strip() for ln in p.stdout.splitlines() if "census coverage" in ln] + miss = [ln.strip() for ln in p.stdout.splitlines() if "CENSUS_ROW_MISSING" in ln] + ok = (rc(p) == 0 and not named(p, "NEW_UNWIRED") + and bool(cov) and "carry a census row" in cov[0] and bool(miss)) + cell("census row dropped alone -> scan", 0 if ok else 1, 0, + "CENSUS_ROW_MISSING named" if ok else "NOT NAMED (rc %d)" % rc(p)) + print(" %s" % (cov[0] if cov else "-")) + print(" %s" % (miss[0] if miss else "-")) + print(" (not a fault: the runner row satisfies 'not unwired'; the coverage " + "NUMBER drops and the printer names the file CENSUS_ROW_MISSING, not UNCLASSED)") + + fresh = clone(work, "cO2", rev) + d = fresh + full = os.path.join(d, LEDGER) + keep = [ln for ln in open(full, encoding="utf-8").readlines() if TARGET not in ln] + open(full, "w", encoding="utf-8").writelines(keep) + p = runner() + cell("ledger row dropped -> runner", rc(p), 1, "UNGRADED, named" + if named(p, "UNGRADED") else "NOT NAMED") + RESULTS[-1] = RESULTS[-1] and named(p, "UNGRADED") + + d = clone(work, "cO3", rev) + pth = os.path.join(d, VER) + src = open(pth, encoding="utf-8").read() + open(pth, "w", encoding="utf-8").write(src.replace( + 'print("OK: py_compile passes")', + 'print("OK: py_compile passes (edited)")', 1)) + subprocess.run(["git", "-c", "user.name=ctl", "-c", "user.email=ctl@x.invalid", + "commit", "-q", "-am", "control: edit the verifier after its row"], + cwd=d, capture_output=True, text=True) + p = runner() + cell("verifier edited+committed after rowing -> runner", rc(p), 1, + "DRIFT, named" if named(p, "DRIFT") else "NOT NAMED") + RESULTS[-1] = RESULTS[-1] and named(p, "DRIFT") + p = sh([sys.executable, "wizard-work/volt/q65_rc_probe.py", "--repo", ".", + "--check"], d) + cell("same edit -> rc-probe ledger", rc(p), 1, + "STALE, named" if named(p, "STALE") else "NOT NAMED") + RESULTS[-1] = RESULTS[-1] and named(p, "STALE") + + d = clone(work, "cO4", rev) + p = sh(["bash", "wizard-work/volt/CHECK"], d) + cell("bash wizard-work/volt/CHECK on a clean clone", rc(p), 0, + p.stdout.strip().splitlines()[-1][:60] if p.stdout.strip() else "-") + + +def main() -> int: + ap = argparse.ArgumentParser() + ap.add_argument("--rev", default="HEAD") + ap.add_argument("--keep", action="store_true", + help="keep the clones (default: workspace removed on exit)") + args = ap.parse_args() + rev = sh(["git", "rev-parse", "--short", args.rev], REPO).stdout.strip() + work = tempfile.mkdtemp(prefix="q65-c7-") + print("q65 c7 controls -- repo %s, rev %s, workspace %s\n" % (REPO, rev, work)) + part1(work, rev) + part2(work, rev) + part3(work, rev) + print() + print("%d/%d cells as expected" % (sum(RESULTS), len(RESULTS))) + if not args.keep: + shutil.rmtree(work) + return 0 if all(RESULTS) else 1 + + +if __name__ == "__main__": + sys.exit(main())