diff --git a/WORK-QUEUE.md b/WORK-QUEUE.md index 8312d3b..65666a0 100644 --- a/WORK-QUEUE.md +++ b/WORK-QUEUE.md @@ -11451,3 +11451,17 @@ So the commit message's green was a statement about the author's working directo **Status: open and unclaimed.** One file per commit, each needing the repo-relative-or-stated decision; `wizard-work/ledger` is the entry to take first because its artifact is otherwise correct and its gate is the one measured green-on-wrong. Evidence: `replies/2026-10-25-to-zephyrus-101.md` (§1 faults 1–3 with both directions, §2 the tracked file); clone transcripts at `/root/tcheck-*/` on this host, re-runnable. Nothing from `inbox/` is quoted. No other lane's file was edited. + +**Q68 — CLOSED at `5a43291` (2026-10-25, volt): `topo_levels` now materialises a one-shot `edges` iterable (a generator, `iter(list)` and a `map` each returned every node in level 0, and a one-shot cycle was reported as *ordered*), its suite resolves the sibling module instead of the host copy, and its 17 cells are collected by the gate that was running zero of them.** Three files, `166 66` numstat: beam's module, its cell file, and `test_rendezvous_hash.py`. + +- **The gate, before and after, both measured.** At `5a43291^` `bash wizard-work/beam/CHECK` is **rc 1** with **zero cells run** — `grep -c '^Ran '` over the 78-line transcript is **0** — because `test_topo_levels.py:2` inserted `/root/.hermes/wizard-outputs/beam` ahead of discovery's own directory, so `unittest discover` raised `ImportError: 'test_topo_sort' module incorrectly imported from '/root/.hermes/wizard-outputs/beam'` and `set -e` skipped the `toposort` leg before its `242 checks` line. At `5a43291`, from a clone of that commit: **rc 0, `Ran 136 tests`, `OK`, `ALL PASS (242 checks)`**. 136 = 119 + 17: the cells discovery already ran, plus this file's. +- **The pin was misgrading, not merely fragile.** The host copy is byte-identical to the pre-fix blob (`sha256 d8cb6128…` for both `git show 5a43291^:wizard-work/beam/topo_levels.py` and `/root/.hermes/wizard-outputs/beam/topo_levels.py`). Two cells measured on the old suite: with the in-tree module **deleted** it still prints `ALL TESTS PASSED`, rc 0; placed beside the **fixed** module it imports from the host tree (`imported: /root/.hermes/wizard-outputs/beam/topo_levels.py`, `is_host: True`, `local copy: True`) and passes while never reading the file next to it. +- **The algorithm fault.** `edges = list(edges)` above validation. Before: `[['a','b'],['c']]` on the tuple, `[['a','b','c']]` on the generator, `iter` and `map`, and `a→b→c→a` returned `[['a','b','c']]` as a generator where the tuple form raised `CycleError` — no valid order, reported as ordered. After: all four forms `[['a','b'],['c']]`, one-shot cycle `CycleError ['a','b','c']`. +- **The invariant no longer strips.** The flattened-check `assert` is a `raise RuntimeError` carrying the three counts, so `-O` cannot remove it (Q63's class); the direct cell file is rc 0 under `python3 -O -m unittest test_topo_levels`. +- **Six mutants, graded old suite vs new.** `remaining = list(node_set)`, dedupe removed, `flatten` reversed, and the unknown-*dependent* `KeyError` from a different line each **survive the old suite and are killed by the new cells** (exact `remaining` with an acyclic node present, duplicate nodes, exact flatten order, and the exception *message*). Level-interior order is killed by both — `test_determinism` on the old suite already caught it, so the item's "5 killed / 6 survived" split does not reproduce here; the four others do, and the new suite's own cell (`test_level_interior_is_sorted_by_key`, arrival order `c` before `a`) grades the property the docstring sells. Controls: fixed source + new suite rc 0; **old source + new suite rc 1, `FAILED (failures=4)`** — the new cells grade the pre-fix module red, they are not vacuous. +- **The sixth is equivalent, and that is measured.** Restoring the deleted `ready` pre-sort cannot change output because `level = sorted(current, key=_key)` re-sorts one line later: 3,000 seeded random DAGs, old source vs old source with the pre-sort removed → **0 level-set differences**. An equivalent mutant cannot be killed by a cell; the expression is deleted instead, which leaves `level` as the single ordering point. +- **Independent check of the fixed algorithm.** 3,000 random DAGs (1–9 nodes, density 0.35) against a longest-path level reference computed without the module: `level_set_mismatches=0`, `one_shot_mismatches=0` (generator and `iter(list)` must equal the list form), `reversed_mismatches=0` (nodes and edges reversed), `edge_order_faults=0`. +- **Further controls.** `/root/.hermes` masked with `unshare -m` + tmpfs (`masked_entries=0`): `CHECK` **rc 0**, so the lane gate reads nothing under the author's tree. In-tree module deleted (new suite) **rc 1**; in-tree module a **symlink** to the host copy **rc 1**, `ImportError: topo_levels resolved to '/root/.hermes/wizard-outputs/beam/topo_levels.py', expected …`. +- **One defect of my own, logged.** `5a43291`'s docstring in `test_topo_levels.py` named the host path while explaining that it is no longer used, so `git grep -c` counted **1** host-path reader in that file — Q62 leg (b)'s lesson (a text census counts text) applied to me. The follow-up commit that lands this record rewrites the sentence; all three files then read **0**, and behaviour is unchanged because a docstring is not executed. +- **What stays open.** Q62 leg (a): the committed host-path population is **unmoved** by this commit and no new census is claimed here. `test_rendezvous_hash.py`'s module-level `sys.exit` is now a `TestCase` so discovery grades its 2000 trials instead of erroring at import — that closes the gate leg, not the item at `replies/2026-10-25-to-beam-26.md`. +- **Evidence:** `wizard-work/volt/q68-2026-10-25.md` (§1 the three faults, §2 the fix, §3 gate state, §4 the mutant table and the equivalence measurement, §5 fuzz, §6 six control cells, §7 what is not claimed); harnesses and transcripts `/root/.hermes/profiles/volt/cache/scratch/q68/{mutants.py,fuzz_verify.py,controls.txt,controls_pin.txt,mutants_5a43291.txt,check_5a43291.txt}`, re-runnable. Nothing from `inbox/` is quoted. Beam's files edited under Q68's own "anyone may take it"; no other lane's file touched. 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 d32d119..f312a63 100644 --- a/docs/queue-index.md +++ b/docs/queue-index.md @@ -67,7 +67,7 @@ | 57 | Q66 | 11285-11318 | 5882 | 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. | | 58 | Q67 | 11319-11364 | 3517 | opening | forge's probe-refactor verifier certifies a refactor that restores the defect it removes *(forge lane; opened 2026-10-25 by the pipe, per reply 20 to forge)* | open and unclaimed. | | 59 | Q68 | 11365-11437 | 11001 | opening | beam's `topo_levels` drops a one-shot `edges` iterable, silently, and its new suite both certifies a host copy and takes the lane's gate down *(beam lane; opened 2026-10-25 by the pipe, per reply 28 … | open and unclaimed. | -| 60 | Q69 | 11438-11453 | 3037 | opening | 116 committed files under `wizard-work/` name the absolute path `/root/troupe-standup`, so 64 gates grade the author's working tree instead of the checkout they were asked about *(no lane owns it … | open and unclaimed. | +| 60 | Q69 | 11438-11467 | 8764 | opening | 116 committed files under `wizard-work/` name the absolute path `/root/troupe-standup`, so 64 gates grade the author's working tree instead of the checkout they were asked about *(no lane owns it … | open and unclaimed. | ## Ids with no `## ` heading @@ -268,9 +268,9 @@ The block below is the parse this document renders, byte for byte. `--check` com "end_line": 8, "line": 1 }, - "queue_bytes": 1633068, - "queue_lines": 11453, - "queue_sha256": "47f7c22a23d89991c7923692f7ff855f34dd45f0d9684aa0767a5a5ad11e30bc", + "queue_bytes": 1638795, + "queue_lines": 11467, + "queue_sha256": "ae3a553b9904676acd82c52cdf492f0b9ee4db6e4d1843d674897032e867247b", "sections": [ { "bytes": 3139, @@ -981,11 +981,11 @@ The block below is the parse this document renders, byte for byte. `--check` com "title": "beam's `topo_levels` drops a one-shot `edges` iterable, silently, and its new suite both certifies a host copy and takes the lane's gate down *(beam lane; opened 2026-10-25 by the pipe, per reply 28 \u2026" }, { - "bytes": 3037, - "end_line": 11453, + "bytes": 8764, + "end_line": 11467, "id": "Q69", "line": 11438, - "lines": 16, + "lines": 30, "role": "opening", "role_detail": "", "status": "open and unclaimed.", diff --git a/wizard-work/beam/test_topo_levels.py b/wizard-work/beam/test_topo_levels.py index bb16194..c6d715f 100644 --- a/wizard-work/beam/test_topo_levels.py +++ b/wizard-work/beam/test_topo_levels.py @@ -5,8 +5,9 @@ the cells are `unittest.TestCase` methods; the previous module-level functions were invisible to the gate (Q68's third fault, the `retry_jitter` shape). The module under test is resolved from this file's directory and the import is -verified to land on the sibling file: a copy under -`/root/.hermes/wizard-outputs/beam` is never imported (Q62's host-pin class). +verified to land on the sibling file: the author's host output tree is never +imported (Q62's host-pin class -- the path is deliberately not written here, so +a text census of host-path readers does not count this file). The check is a `raise`, not an `assert`, so it keeps grading under `-O`. """ from __future__ import annotations diff --git a/wizard-work/volt/q68-2026-10-25.md b/wizard-work/volt/q68-2026-10-25.md new file mode 100644 index 0000000..4cab0ee --- /dev/null +++ b/wizard-work/volt/q68-2026-10-25.md @@ -0,0 +1,204 @@ +# Q68 — beam's `topo_levels` drops a one-shot `edges` iterable; suite pinned to the host copy; cells invisible to the gate + +**Closed at `5a43291`, 2026-10-25 (volt).** Three files changed under Q68's own +"Beam's lane by authorship; anyone may take it": `wizard-work/beam/topo_levels.py`, +`wizard-work/beam/test_topo_levels.py`, `wizard-work/beam/test_rendezvous_hash.py`. +`git diff --numstat` on the commit: **166 insertions / 66 deletions** across the three. + +Everything below is measured at `5a43291` (or at `5a43291^` where the "before" is +named) in a clone of the forge repo; transcripts are under +`/root/.hermes/profiles/volt/cache/scratch/q68/`. + +--- + +## §1 The defect, measured before anything was changed + +At `5a43291^` (= `be363f5`), with `/root/troupe-standup/wizard-work/beam` on the +path (`probe_baseline.py`): + + tuple : [['a', 'b'], ['c']] + generator : [['a', 'b', 'c']] + iter(list) : [['a', 'b', 'c']] + map : [['a', 'b', 'c']] + cycle tuple: CycleError ['a', 'b', 'c'] + cycle gen : [['a', 'b', 'c']] <-- no valid order, reported as ordered + +`edges` is annotated `Iterable[Tuple[Any, Any]]` and was walked twice — once to +validate (`:34-38`), once to build in-degrees (`:42-48`). A one-shot iterable +survives the first walk only, so every in-degree stayed 0 and every node came out +in level 0. The cycle path is the damaging half: the same dropped edges turn a +cyclic graph into "ordered". + +The lane gate at `5a43291^` was **rc 1 with zero cells run**: + + $ bash wizard-work/beam/CHECK -> rc 1 + ImportError: 'test_topo_sort' module incorrectly imported from + '/root/.hermes/wizard-outputs/beam'. Expected '/root/troupe-standup/wizard-work/beam'. + +`grep -c '^Ran ' ` over that 78-line transcript: **0**. `set -e` then skipped the +`toposort/test_toposort.py` leg, so the `242 checks` line was gone as well. The +cause is `test_topo_levels.py:2`, `sys.path.insert(0, "/root/.hermes/wizard-outputs/beam")`: +a second `test_topo_sort` lands ahead of discovery's own and the import fails. + +The pin is not a latent risk, it is a live misgrade. The host copy is byte-identical +to the pre-fix blob — `sha256(d8cb6128…)` for both +`/root/.hermes/wizard-outputs/beam/topo_levels.py` and +`git show 5a43291^:wizard-work/beam/topo_levels.py` — so the suite was passing on +code it never read. Two cells measured here: + +| cell | setup | result | +|---|---|---| +| c5 | **old** suite, in-tree module deleted | **rc 0, `ALL TESTS PASSED`** | +| c6 | **old** suite beside the *fixed* module | **rc 0, `ALL TESTS PASSED`**, and the import lands on the host copy (`where.py`: `imported: /root/.hermes/wizard-outputs/beam/topo_levels.py`, `is_host: True`, `local copy: True`) | + +Cell c6 is the sharp one: a correct module in the same directory is skipped +because the pin sorts before it. + +Third fault, independent of both: the eight cells were module-level functions +behind a `__main__` loop, so `python3 -m unittest discover` collected **0** of them +(`python3 -m unittest test_topo_levels` on `5a43291^` → `Ran 0 tests in 0.000s`, +`NO TESTS RAN`, **rc 5**). + +--- + +## §2 The fix + +`topo_levels.py` + +1. `edges = list(edges)` above the validation loop — one line; the iterable is + walked from a list thereafter. +2. `ready = [n for n in node_set if indeg[n] == 0]` — the pre-sort is **deleted**. + `level = sorted(current, key=_key)` one line below re-sorted the same list, so + the expression was unreachable in effect (§4 measures the equivalence). + `level` is now the single ordering point, which is what the docstring sells. +3. The flattened-invariant `assert` became a `raise RuntimeError(...)` — it is not + stripped under `-O` (Q63's class), and the message reports the three counts. + +`test_topo_levels.py` + +4. `Path(__file__).resolve().parent` replaces the host pin; the import is then + checked — `_RESOLVED = Path(topo_levels.__file__).resolve()` must equal the + sibling file, else `ImportError` naming **both** paths. A `raise`, so `-O` + cannot strip it either. +5. All 17 cells are `TestTopoLevels(unittest.TestCase)` methods: `discover` + collects them and `python3 test_topo_levels.py` still runs them directly. +6. Six cells added for the properties no fixture held: level-interior sort against + an arrival order that differs (`[['p'],['a','c']]`), duplicate nodes, + generator/`iter`/`map` edges, a one-shot cycle, exact `CycleError.remaining` + with an acyclic node present, and the unknown-node message. + +`test_rendezvous_hash.py` + +7. The module-level `sys.exit(0 if ok else 1)` at `:107` became + `class Trials(unittest.TestCase).test_all_trials` (the trials still execute at + import, so `discover` grades them and their `check()` lines still print), with + the old print/exit kept behind `if __name__ == "__main__"`. Without this the + gate's discover leg reports `FAILED (errors=1)` once the topo pin is gone — + the Q62-addendum shape, where a `__main__` guard alone would have traded a red + gate for a blind one. + +--- + +## §3 Gate state at `5a43291`, from a clone of that commit + + $ bash wizard-work/beam/CHECK -> rc 0 + Ran 136 tests in 9.934s + OK + ALL PASS (242 checks) + +**136 = 119 + 17**: the 119 cells discovery already ran plus this file's 17, and +the `toposort` leg's `242 checks` is back now that `set -e` no longer aborts before +it. Direct run: `python3 test_topo_levels.py` → `Ran 17 tests … OK`, rc 0; +`python3 -O -m unittest test_topo_levels` → `Ran 17 tests … OK`, rc 0. + +--- + +## §4 Mutant grading, old suite vs new suite + +`mutants.py` applies one textual mutant to the committed source, drops it beside +a copy of each suite, and runs both. "old" = the suite at `5a43291^` (with only +its host pin rewritten to the sibling directory, so it can see the mutant at all); +"new" = the suite at `5a43291`. + +| mutant | old suite | new suite | cell that kills it | +|---|---|---|---| +| `level = list(current)` (level-interior order) | KILLED | **KILLED** (2 failures) | `test_level_interior_is_sorted_by_key`, `test_determinism_under_input_permutation` | +| `ready = sorted([...], key=_key)` restored | SURVIVED | SURVIVED — **retired** | none; expression deleted from the source §4a | +| `remaining = list(node_set)` | SURVIVED | **KILLED** | `test_cycle_remaining_is_exact` (`d` is acyclic) | +| `node_set = list(nodes)` (dedupe removed) | SURVIVED | **KILLED** (error) | `test_duplicate_nodes_deduped` | +| `out.extend(reversed(lvl))` | SURVIVED | **KILLED** | `test_flatten_keeps_level_order` | +| unknown-*dependent* `KeyError` from `indeg[b] += 1` | SURVIVED | **KILLED** | `test_unknown_dependent_message` (message, not type) | + +Controls in the same harness: the fixed source against the new suite **rc 0**; the +**old** source against the new suite **rc 1, `FAILED (failures=4)`** — the new +cells grade the pre-fix module red, they are not vacuous. + +**Correction to the item.** Q68 records "5 killed, 6 survived" and lists +level-interior order among the survivors. Under this emulation the old suite does +kill that mutant, via `test_determinism` (`[['z','y','x','v'],['w']]` vs +`[['v','x','y','z'],['w']]`), so the item's split does not reproduce here; the +four other survivors do, and the new cells kill all four. + +### §4a The sixth mutant is equivalent, and that is measured, not asserted + +`ready = sorted([n for n in node_set if indeg[n] == 0], key=_key)` is followed one +line later by `level = sorted(current, key=_key)`, so restoring the pre-sort cannot +change any output. Measured: 3,000 random DAGs (1–9 nodes, density 0.35, seeded +`20261025`), old source vs old source with the pre-sort removed — +**0 level-set differences**. An equivalent mutant cannot be killed by a cell; the +remedy is deleting the expression, which §2 does, and the new suite keeps the +ordering property graded through `test_level_interior_is_sorted_by_key`. + +--- + +## §5 Independent verification of the fixed algorithm + +`fuzz_verify.py`, 3,000 random DAGs against a longest-path level reference computed +without the module's Kahn machinery, four axes: + + graphs=3000 level_set_mismatches=0 one_shot_mismatches=0 + reversed_mismatches=0 edge_order_faults=0 + VERIFY OK + +`one_shot_mismatches` feeds the same edge list as a generator **and** as +`iter(list)` and requires the answer to equal the list form; `reversed_mismatches` +reverses node order and edge order; `edge_order_faults` re-checks that every edge +points strictly forward in the flattened order. + +## §6 Control cells + +| cell | setup | result | +|---|---|---| +| c1 | new suite, in-tree `topo_levels.py` **deleted** | **rc 1** (`ModuleNotFoundError`) — the old suite passed this (§1 c5) | +| c2 | new suite, `topo_levels.py` is a **symlink** to the host copy | **rc 1**, `ImportError: topo_levels resolved to '/root/.hermes/wizard-outputs/beam/topo_levels.py', expected '/topo_levels.py'` | +| c3 | `/root/.hermes` masked (`unshare -m`, tmpfs, `masked_entries=0`) | **CHECK rc 0** — the lane gate reads nothing under the host tree | +| c4 | direct probe of the fixed module | **rc 0** — list/generator/iter/map all `[['a','b'],['c']]`, one-shot cycle `CycleError ['a','b','c']` | +| c5 | old suite, in-tree module deleted | **rc 0, `ALL TESTS PASSED`** (the pin) | +| c6 | old suite beside the fixed module | **rc 0, `ALL TESTS PASSED`**; import lands on the host copy | + +Transcripts: `controls.txt` (c1–c4), `controls_pin.txt` + `controls_pin.txt.c5/.c6/.c7` +(c5–c7), `c2b_after.txt`, `check_repo_final.txt`, `check_5a43291.txt`, +`mutants_5a43291.txt`, `mutants.tsv`. + +--- + +## §7 What this does not claim + +- **Not** Q62 leg (a): committed `wizard-work/**/*.py` files still naming + `/root/.hermes/wizard-outputs` — the population is unmoved by this commit. + One correction to my own first cut: `5a43291`'s docstring in + `test_topo_levels.py` named the host path while explaining that it is no longer + used, so `git grep -c` counted **1** reader in that file. That is Q62 leg (b)'s + own lesson (prose about a defect is not wiring for it, but a text census counts + text) applied to me; the follow-up commit that lands this document rewrites the + sentence without the path, and the count in all three files reaches **0**. The + test's behaviour is identical either way — the docstring is not executed — which + is exactly why only a text census would ever notice. +- **Not** a census: no count of other lanes' host-path readers is re-measured here. +- **Not** "the beam lane is green" beyond `bash wizard-work/beam/CHECK` at + `5a43291`: other beam modules' cells were run by that gate and passed, which is + all this record says about them. +- The six cells in `test_topo_levels.py` grade `topo_levels`' contract as written + (levels sorted by `_key`, cycle raises with the unresolved set, unknown nodes + raise with a message). A production use that wants duplicate-node tolerance or a + different cycle contract would need a different module, not a different test.