queue: record for the mutation study of the write axis (nine cases, nine red, one green control)

Appended at the foot with docs/queue-index.md re-rendered in the same commit, so
the newest queue-touching commit leaves the index current in its own tree.

The record carries what cc2c6a5 measured: the nine cases (M0 21/21 clean, M1
TRACEBACK, M1-leg the gate red at rc 1, M2 RC_OTHER, M3 SILENT, M4 UNNAMED, M4b
the limitation of that class, M5 the 67f94cc shadowed write, CTL green), the
detail line that named a healthy tool and now names the faulting one, the one
TOOL_MISSING row in doc_command_check.py that was this tool's own recipe (64/64
now), and the gate at 6 legs / 6 pass / 0 fault. No Q-item opened or closed; the
open set still reads Q37, Q53, Q64.
This commit is contained in:
volt committed 2026-10-21 14:34:04 +00:00
1 parent cc2c6a5fdb
commit c3ffee91e9
2 files changed
+29 -11

No files matched your search

+18
View File
@@ -10482,3 +10482,21 @@ Verification, read at `6cd2114` (the revision this record was written against; a
— Volt
**Write-axis tick 2026-10-21 (volt, Workhorse) — the write gate mutated one defect at a time: nine cases, nine red, one green control; the leg's detail line was naming a healthy tool on a red row (fixed), and the tool's own recipe was the one red row in `doc_command_check.py` (fixed).** No item opened or closed; the open set is as the previous record left it (`Q37`'s pipe span, the career-lane `Q53` decision held for Alexander, `Q64`'s design question Alexander's). Appended at the foot; `docs/queue-index.md` re-rendered in the same commit.
1. **The question.** `write_probe.py` landed as leg 6 with one kind of evidence: it reads green (21 probed, 21 OK, gate 6/6 at `7da4283`, re-measured here). A gate that has never been seen to go red is indistinguishable from a gate that cannot. So the defects the guards were written against were put back, one at a time, in a throwaway `git worktree` per case — never in the shared clone — and the verdict was read out of the probe's own `--json`, not out of its prose. The instrument is `/root/.hermes/wizard-outputs/volt/2026-10-21-write-axis-bites/mutation_study.py`; it refuses (rc 2) if a mutation does not match exactly once, because a mutation that silently no-ops would grade the unmutated file.
2. **Nine cases, measured at `cc2c6a5`, all agreeing with prediction.** `M0` clean tree → 21 probed, 0 fault(s), rc 0. `M1` the write guard narrowed so a FileNotFoundError escapes uncaught (`doc_census_check.py`) → TRACEBACK, rc 1. `M1-leg` `verify.py --fast` over that same worktree → write-axis FAULT, process rc 1. `M2` the refusal returns 1 (`tool_map.py`) → RC_OTHER, rc 1. `M3` rc 2 with the message deleted (`queue_index.py`) → SILENT, rc 1. `M4` rc 2 with a message that names nothing (`reply_check.py`) → UNNAMED, rc 1. `M4b` the explicit path dropped but `str(exc)` kept → OK, rc 0 (point 5). `M5` `gate_blame.py` restored to `67f94cc`, where the write sat behind the all-UNGRADABLE early return → UNNAMED, rc 1. `CTL` `verify.py --fast` over a clean worktree → write-axis PASS, rc 0. The two directions are both in the table: the leg goes red on one defect and stays green on none.
3. **What the study found and what landed (`cc2c6a5`).** On the `M1` worktree — whose only defect was `doc_census_check.py` — `verify.py` printed the detail `append_only_audit.py OK 2 cannot write --json ...`: the first reason-shaped line of the probe's report was the table's first *healthy* row, because every row contains the word "cannot". A red leg whose detail names a tool with nothing wrong with it is worse than a bare red leg; it sends the reader to the wrong file. `write_probe.py` now prints a `FAULT <tool> ...` block above the table, one line per non-OK row, and `verify.py` carries `FAULT` in its strong hints so a SILENT fault (whose own detail carries no marker) is still the line that surfaces. Measured after the fix, on the same `M1` worktree: the leg's detail is `FAULT doc_census_check.py TRACEBACK 1 FileNotFoundError: [Errno 2] ...` — the faulting tool. Cell `c11` grades the block itself; the instrument's selftest moved **10 → 11 cells, 11/11 rc 0**, and its docstring census moved with it (`doc_census_check.py --tools tools/write_probe.py --fail` → 0 INTERNAL SPLIT, 0 STALE, rc 0).
4. **The second defect was in a different instrument's result, not its code.** `doc_command_check.py` at `7da4283` read **64 commands over 19 oracles, OK 63, 1 TOOL_MISSING** — and the missing tool was this tool, because its own reproduction recipe named the copied absolute path (`<dir>/tools/write_probe.py`), which is not in the tree at HEAD. The recipe now reads `cd <dir> && python3 tools/write_probe.py --repo <dir>`: the command a reader actually types, and a path the checker resolves. At `cc2c6a5`: **64 commands over 19 oracles, OK 64, rc 0**. The alternative — teaching the checker a TEMPLATE class for `<dir>` — was not taken: the recipe can simply name the tracked path, and a new ungraded class is a weaker answer than a resolvable command.
5. **What was corrected and not changed: UNNAMED grades the text, not the guard's sentence.** Dropping the guard's explicit path while keeping `str(exc)` still reads **OK**, because every `OSError` string carries the path it failed on (`M4b`, measured). The class is therefore reachable only when no stream carries a path at all. The code is unchanged — a refusal that prints the path is what the contract asks for — and the docstring now says what the class actually grades, with the case that measured it named. A caveat stated beside the claim is cheaper than a class that means less than its name.
6. **Verification at `cc2c6a5`.** `write_probe.py --repo .` **21 probed, 21 ok, 0 fault(s)**, rc 0; `write_probe.py --selftest` **11/11**, rc 0; `verify.py --repo .` **6 legs, 6 pass, 0 fault, 0 ungradable, 0 skipped**, rc 0, with `selftest-sweep` **21 tools, 21 OK, 0 fatal**; `doc_command_check.py --repo . --fail` **64/64**, rc 0; `doc_census_check.py --fail` on `tools/write_probe.py` and `tools/verify.py` **0 STALE**, rc 0; `tool_map.py --repo . --check docs/TOOLS.md` rc 0 (every derived cell — purpose, flags, probes, gate leg — is unchanged by the edit, so the document is still the render of this tree).
7. **What it does not claim.** The nine cases grade the *classes* the probe distinguishes, not every tool: `M0` is the only case that touches all 21, and a defect form the judge has no class for would still read OK. The `M4b` limitation above is real and unfixed by design. `NO_REACH` is not reproduced by mutation — no real tool produces it, and a contrived one would grade the mutation rather than the gate; it remains covered by the instrument's own `c5` cell. The fault block's line is printed inside a report that also prints the table, so a red leg's detail now begins `FAULT doc_census_check.py ...` under a row whose verdict word is already `FAULT` — a doubled label, cosmetic, kept because the alternative is a marker a SILENT fault does not have. No Q-item state changed, and nothing here decides anything Alexander holds.
— Volt
+11 -11
View File
@@ -56,7 +56,7 @@
| 46 | Q44 | 6162-6705 | 88496 | opening | The pin class: redirect every constant composed from the live data root, not only `SNAPSHOT_PATH` *(Helm lane; opened 2026-10-12 by the pipe, per Q43's own closing sentence — "extend the redirect … | DONE 2026-10-12 — `recoveries/helm-root-redirect.md` (Merlin, Helm lane); the closure block is at the foot |
| 47 | Q48 | 6706-6825 | 15123 | opening | The runtime-resolution redirect: close the class Q45's literals cannot see | DONE 2026-10-13 — `recoveries/helm-runtime-redirect.md` (Merlin, Helm lane), scratch tree |
| 48 | Q49 | 6826-7593 | 92050 | opening | The runtime-resolved root's live write path: name it, reproduce it, then close it | open and unclaimed. Opened by the pipe 2026-10-13 |
| 49 | Q45 | 7594-10484 | 507975 | opening | §9 follow-on — the home-directory channel *(Helm lane; Merlin)* | OPEN — awaiting Alexander's zoom/whole-shop answer; build is the pipe's. |
| 49 | Q45 | 7594-10502 | 514132 | opening | §9 follow-on — the home-directory channel *(Helm lane; Merlin)* | OPEN — awaiting Alexander's zoom/whole-shop answer; build is the pipe's. |
## Ids with no `## ` heading
@@ -71,9 +71,9 @@ Opened as records inside another section. `line` is the record's own opening lin
| Q50 | 6990 | 6990 | 46 | Q49 | BULLET+BOLD | BOLD-LEAD |
| Q51 | 7106 | 7106 | 37 | Q49 | BULLET+BOLD | BOLD-LEAD |
| Q52 | 7167 | 7167 | 90 | Q49 | BULLET+BOLD | BOLD-LEAD |
| Q53 | 7292 | 7246 | 147 | Q49 | BULLET+BOLD | BOLD-LEAD |
| Q53 | 7292 | 7246 | 148 | Q49 | BULLET+BOLD | BOLD-LEAD |
| Q63 | 9918 | 9909 | 17 | Q45 | BULLET+BOLD | BOLD-LEAD |
| Q64 | 10308 | 10308 | 10 | Q45 | BULLET+BOLD | BOLD-LEAD |
| Q64 | 10308 | 10308 | 11 | Q45 | 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`.
@@ -218,7 +218,7 @@ The block below is the parse this document renders, byte for byte. `--check` com
"form": "BOLD-LEAD",
"id": "Q53",
"line": 7292,
"refs": 147,
"refs": 148,
"section": "Q49",
"shape": "BULLET+BOLD"
},
@@ -236,7 +236,7 @@ The block below is the parse this document renders, byte for byte. `--check` com
"form": "BOLD-LEAD",
"id": "Q64",
"line": 10308,
"refs": 10,
"refs": 11,
"section": "Q45",
"shape": "BULLET+BOLD"
}
@@ -246,9 +246,9 @@ The block below is the parse this document renders, byte for byte. `--check` com
"end_line": 8,
"line": 1
},
"queue_bytes": 1400236,
"queue_lines": 10484,
"queue_sha256": "d74551c3f747c60c1a4ca71529cf26bf9cd47472963e0420e75231dc083dd329",
"queue_bytes": 1406393,
"queue_lines": 10502,
"queue_sha256": "88948ef446c4171e126a023538f78c1a0df49ea074fe8fca6726f6167f1167c9",
"sections": [
{
"bytes": 3139,
@@ -827,11 +827,11 @@ The block below is the parse this document renders, byte for byte. `--check` com
"title": "The runtime-resolved root's live write path: name it, reproduce it, then close it"
},
{
"bytes": 507975,
"end_line": 10484,
"bytes": 514132,
"end_line": 10502,
"id": "Q45",
"line": 7594,
"lines": 2891,
"lines": 2909,
"role": "opening",
"role_detail": "",
"status": "OPEN \u2014 awaiting Alexander's zoom/whole-shop answer; build is the pipe's.",