test(#805): check the corpus's zone accounting per zone, not only in its last statement - #824
Conversation
…its last statement #762 gave `faithful_walker_drift_corpus` a completeness refusal and put it in the test's LAST statement. #763 says that corpus never terminates on blackburrow, so on the one run where a zone is known to misbehave the refusal is never reached — a guard that is written but not run. Opening a zone now goes through `open_zone_checked`, which re-checks the `unaccounted` bucket ("a zone left the loop body without reaching add or skip" — a corpus WIRING bug, never an asset problem) before opening the next one. A run that hangs, returns early or dies at zone K has therefore already checked zones 1..K-1. `unmeasured`/`skipped` stay in the terminal assert on purpose: whether the corpus HAS an asset hole is a question about the whole denominator and is not answerable at zone 3 of 11; checking them per zone would abort the table on the first missing .glb. #763's hang is untouched, and this adds no output an operator can see while a run is wedged. Three asset-free tests over WaterRollup pin the gate, its silence on properly closed zones, and the limit (the zone still OPEN when a run stops is not covered). Closes #805 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HQVEpaaKeXsZcW9VT2roeV
|
CHANGES REQUESTED Independent adversarial review of #824 at The code is sound — the per-zone BlockingB1 — "not answerable at zone 3 of 11" is false, and it is the load-bearing justification for the scope split
Restated at Measured false. I added a probe test to the shipped tree (added, run, removed; It establishes three things by execution, not by reading:
What is true is the sentence immediately after: checking those per zone "would abort the run on the first missing B2 — "the only zone whose accounting depends on reaching this line is the LAST one opened"
B3 —
|
| # | Mutation | Result |
|---|---|---|
| M_A | Author's M1, reproduced. Reach-control call site (walker_sim.rs:899) open_zone_checked(&mut wr, &mut r423, zone); → wr.begin_zone(zone); r423.begin_zone(zone); |
RED — zone_accounting_fires_before_the_corpus_loop_ends FAILED, 9 passed; 1 failed |
| M_B | Author's M2, re-run on the shipped tree (they ran it one revision back). if false { assert!(orphans.is_empty(), …) } |
RED — same test, 9 passed; 1 failed |
| M_C | Invented. #[cfg(any())] on the gate's assert |
RED — same test |
| M_D | Invented. Delete the gate's assert outright | RED — same test. But zone_accounting_does_not_cover_the_zone_that_is_still_open and zone_accounting_stays_silent_while_every_zone_is_closed both stayed ok |
| M_E | Invented. Gate checks one rollup only: for (label, roll) in [("wat-route", &*wr)] |
SURVIVED — 10 passed; 0 failed. See N1 |
| M_F | Invented. Move the check after begin_zone instead of before |
RED — ..._does_not_cover_the_zone_that_is_still_open and ..._stays_silent_while_every_zone_is_closed both FAILED |
| M_G | Invented, the important one. Revert the real corpus call site (walker_sim.rs:604) to the pre-#805 roll_wr.begin_zone(zone); roll_423.begin_zone(zone); — full workspace |
SURVIVED — 55 = 55 headers/results, 1814 passed; 0 failed; 47 ignored; 0 filtered, byte-identical totals to the unmutated run. See N3 |
M_B confirms the author's M2 transfers to the shipped tree, so the untested-revision caveat in the PR body is now discharged. I also verified the byte-identity claim itself against the branch reflog: the M2 revision differs from 12019df by exactly one reworded rustdoc paragraph and the added rename-guard test; open_zone_checked's body and all four call sites are byte-identical. (The PR body says "both call sites" — there are four.)
Non-blocking
N1 — half the gate is unpinned (M_E). Deleting the #423 arm from the gate's rollup array leaves the whole suite green. The two rollups are driven in lockstep everywhere, so no existing test can distinguish them, and the {label} interpolation is unexercised. One cheap RED-direction test fixes it: close wr but not r423 for zone 1, open zone 2, and should_panic on a message containing #423.
N2 — zone_accounting_does_not_cover_the_zone_that_is_still_open does not test the gate. Under M_D (assert deleted) it stays green: its two asserts are statements about WaterRollup, and near-identical ones already exist at crates/eqoxide-nav/src/water_grid.rs:866-875 (only_unaccounted: same begin_zone-and-abandon, same unaccounted_zones(), same !is_complete()). Its doc says "If a future change makes the gate cover the open zone too, this test goes RED" — I could not construct a coverage-extending change that makes it red (a close_zone_checked at the end of the body, or a check after the loop, both leave it green); it goes red only under a Drop-guard design. It did earn one kill (M_F, the order swap) — but so did zone_accounting_stays_silent_while_every_zone_is_closed, so it has no unique kill among the seven mutations here. Either give it a unique kill or downgrade its doc from "pinned rather than described" to what it is.
N3 — the fix itself is unreached in CI (M_G). The PR discloses this ("the gate's call site inside the real corpus is exercised only when a human runs the corpus by hand"), and the disclosure is accurate: .github/workflows/test.yml:148 runs cargo test --workspace --locked with no --ignored, and faithful_walker_drift_corpus is #[ignore]d at tests/walker_sim.rs:313. M_G measures the consequence: the entire behavioural change can be reverted and nothing goes red. The reach control covers the helper, not the fix — which is the #799 shape the PR is fixing elsewhere. I am not asking for the owner-gated #[ignore]-in-CI decision (#777/#654/#659) here. A cheap partial pin exists though: a non-ignored test that runs the corpus against an empty $ZONE_DIR with a two-zone ZONES list would drive the real loop through open_zone_checked and land on assert!(tot_walked > 0, "no journeys walked — check $ZONE_DIR") under should_panic. That pins reach of the loop, not gate behaviour — worth stating either way.
N4 — diagnostics cost, undisclosed in the tracked doc. The gate aborts mid-loop, so a wiring bug now loses the table's remaining rows and the === FAITHFUL WALKER DRIFT total line, and names only the first unaccounted zone instead of all of them. The PR body's M3 output shows exactly this and frames it as evidence; it is also a cost, and open_zone_checked's "What this does NOT buy" paragraph is the right place for it.
Figures — PR branch merged with 41cca4e, stdout/stderr captured separately
cargo test --workspace --locked --no-fail-fast, exit code captured explicitly (EXIT=0), judged by log content.
Finished \test` profile [unoptimized + debuginfo] target(s) in 3m 03s— the **compile** sentinel, present on stderr; the run was judged complete by process exit plus 55 completetest result:` lines.- 55
^running [0-9]+ tests?$headers vs 55^test result:lines — equal, no lost binary. (Regex admits the singularrunning 1 test.) - 0 non-canonical result lines.
- 14 truly-empty targets, field-anchored on
^test result: ok\. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out. 1814 passed + 0 failed + 47 ignored + 0 filtered = 1861, and the header sum is 1861. Equal.
Reconciliation against the 41cca4e baseline (55 = 55, 0 non-canonical, 14 truly-empty, 1810 + 0 + 47 + 0 = 1857): +4 passed, +4 total, target count unchanged, exactly the four tests this PR adds, all confirmed present and ok by name — doc_comment_citations_in_this_file_are_rename_guarded, zone_accounting_does_not_cover_the_zone_that_is_still_open, zone_accounting_fires_before_the_corpus_loop_ends - should panic, zone_accounting_stays_silent_while_every_zone_is_closed.
scripts/check-no-local-detail.sh → OK — no forbidden patterns in tracked files.
Claims I checked and found TRUE
- CI runs no
--ignored(.github/workflows/test.yml:148) and the corpus is#[ignore]d (tests/walker_sim.rs:313). - The total line prints after the zone loop (
tests/walker_sim.rs:795-798, after the loop closes at:793) — the statement-order claim inopen_zone_checked's doc holds. - The gate reads
unaccounted_zones()beforebegin_zone, so the still-open previous zone is caught viachain(self.open)(water_grid.rs:509-513) and the zone being opened is not falsely flagged. M_F shows the ordering is pinned. - No false positive: the gate is silent whenever every zone is closed, and
unaccountedis monotone, so it never fires where the terminal assert would not. - M2's "byte-identical" caveat, verified against the reflog, and re-run here as M_B.
NOT verified
- Anything about a real hang. I did not run blackburrow and did not run the corpus at all — no baked GLBs used, no
$ZONE_DIR, no live client. The author's M3/M3b/GREEN runs against real assets are unreproduced by me; I neither confirm nor dispute their numbers. - The author's
origin/mainbaseline (1798 + 0 + 47 + 0 = 1845) — that is against their older base; I measured against41cca4einstead and the delta reconciles. - Whether the diagnostics trade-off in B1 is the right call. I am asking for the reason to be corrected, not for the decision to be reversed.
- The four
*_blast_radiuscorpora andwater_grid_budget_measurement, whichWaterRollup's own type doc says are not covered by any of this. Out of scope here, unexamined. crates/eqoxide-nav/src/water_grid.rsis untouched by this PR (confirmed: the diff istests/walker_sim.rsonly, 147 insertions), so no interaction with fix(#803): make "no exits" and "could not read the exits" different types #821 was assessed beyond that.
…cidability claim Round-2 review (PR #824). B1 — the doc justified exempting `unmeasured`/`skipped` from the per-zone refusal on the grounds that a corpus hole "is not answerable at zone 3 of 11". The reviewer measured that false: the rollup's buckets are push-only, so every bucket is settled the instant a zone closes and none can un-fire. The real reason was always diagnostics, and it only ever applied to `skipped` — the empirical case cited (akanon skipped at zone 1 of 2) leaves `unmeasured_zones()` empty and so never supported exempting `unmeasured` at all. B3 — so `unmeasured` is now refused per zone as well. That is #762's motivating exhibit (a `.wtr` that did not load scoring as zero water), which round 1 left terminal and hence unreached on precisely the non-terminating run #805 is about. `skipped` stays terminal on a stated, measured diagnostics trade. B2 — 'the only zone whose accounting depends on reaching this line is the LAST one opened' was false and is deleted; the terminal assert is the ONLY check of `skipped` for every zone, and the only check of any kind for the last zone opened. M_G/#799 — the corpus call site is pinned by nothing CI runs. Said plainly in the rustdoc and at the call site instead of being left to read as covered. N1/M_E — new divergent-rollup test: `wat-route` clean, `#423` abandoned. Pins the second arm and the `{label}` interpolation, both previously unpinned. N4 — an abort is mid-loop and partial. The refusal now prints a partial rollup line before panicking (the corpus's own total line runs after the loop and never executes), and says so. N2 — `zone_accounting_does_not_cover_the_zone_that_is_still_open` deleted: it survived deletion of its own assert, had no unique kill across seven mutations, and re-pinned `WaterRollup` semantics already pinned in water_grid.rs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HQVEpaaKeXsZcW9VT2roeV
The round-2 `unmeasured` extension shipped with a description of that bucket that a real run falsifies. `walker_sim.rs`'s water arm loads the zone's `.glb`, builds the grid, then calls `ZoneWater::install`; when the `.wtr` is missing the zone is closed with `add(zone, &zw.tally())` and `continue`d — BEFORE a single journey is sampled. So "the zone was walked and its .wtr did not load" is wrong in the one clause that matters. Measured, not reasoned: `ZONES=crushbone,felwithea` against real baked GLBs with `crushbone.wtr` moved aside printed crushbone - - - - - unmeasured unmeasured (unmeasured: no .wtr file for this zone) and the whole test finished in 0.53s — zero journeys walked. The rustdoc, the panic text and the `should_panic` substring now say what the bucket means: the water check RAN and the `.wtr` did not load, so the zone was abandoned unwalked with no number. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HQVEpaaKeXsZcW9VT2roeV
Round 2 — commit → findingBranch merged with
One thing you did not find, that I found while substantiating B3
and finished in 0.48 s — zero journeys. The wording now reads "the water check ran and the Measurements, all on the shipped head
|
|
APPROVED — round 2, independent adversarial review of Four findings below, all non-blocking; I would merge over every one of them. Round 1's blocking finding (the false decidability claim) is fixed, and I re-verified the retraction by execution rather than crediting it. Baseline hazard — re-measured on the merge with
|
| # | figure | value |
|---|---|---|
| 1 | compile sentinel | Finished `test` profile [unoptimized + debuginfo] target(s) in 36m 39s (cold builder), rbuild EXIT=0 |
| 2 | targets | 55 running [0-9]+ tests? headers = 55 test result: lines |
| 3 | non-canonical result lines | 0 |
| 4 | truly-empty targets (0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out) |
14 |
| 5 | totals | 1828 passed + 0 failed + 47 ignored + 0 measured = 1875, equal to the header sum; 0 FAILED targets |
223ac9b baseline is 1823 + 0 + 47 + 0 = 1870 across 55/55 ⇒ delta +5, reconciled by name against the five tests this PR adds. The dropped zone_accounting_does_not_cover_the_zone_that_is_still_open is absent (grep count 0). No cross-PR semantic conflict with #821: green on the merge, not only on the PR's own base.
Mutations run (all at the CALL SITE unless stated; every revert md5sum-verified)
| # | mutation | result | killed by |
|---|---|---|---|
| R1 | hard-code {label} → "wat-route" in the panic |
RED | zone_accounting_covers_the_423_rollup_not_just_wat_route, with note: panic did not contain expected string — the right reason |
| R2 | drop the ("#423", &*r423) arm from the loop |
RED | ..._covers_the_423_rollup_not_just_wat_route only |
| R3 | gate ignores unmeasured (if orphans.is_empty() { continue; }) |
RED | zone_accounting_refuses_an_unmeasured_zone_before_the_corpus_ends only |
| R4 | gate ignores unaccounted (if unmeasured.is_empty() { continue; }) |
RED | ..._fires_before_the_corpus_loop_ends + ..._covers_the_423...; ..._refuses_an_unmeasured... stayed green — clean bucket discrimination |
| R5 | if true { continue; } at the top of the rollup loop (repro of the author's M2) |
RED | the three gate tests; ..._stays_silent_while_every_zone_is_closed green — matches the author's report |
| R6 | delete the open_zone_checked(…) call from the reach-control test (repro of M1) |
RED | ..._fires_before_the_corpus_loop_ends only |
| R7 | delete the [ABORTED …] println! entirely |
SURVIVED — test result: ok. 11 passed; 0 failed; 5 ignored |
(finding 2) |
| R8 | if false { continue; } — refuse unconditionally (false-positive control) |
RED | ..._stays_silent_while_every_zone_is_closed fires, plus ..._covers_the_423... on the label mismatch |
| R9 | delete the real corpus call site at tests/walker_sim.rs:608, restore the bare begin_zone pair — full workspace |
SURVIVED | nothing (confirms the #799 bullet) |
R9 / M_G spot-check (the self-measured control). Independently reproduced: 1828 + 0 + 47 + 0 = 1875 across 55/55 targets, 0 FAILED — figure-for-figure identical to the unmutated merge — and the sorted set of test … ok|ignored lines is diff -q-identical at 1875 lines. The author's control holds. (My line count differs from their 1819 only because my base is 223ac9b.)
M2 is a body mutation, not a call-site one — and that is fine here, but only because M1 exists. if true { continue; } sits inside open_zone_checked's loop; it cannot by itself distinguish "the gate is dead" from "the predicate is false". It is admissible in this PR because (a) the tests that kill it are should_panic tests whose kill signal is reaching a post-loop UNREACHED panic — a reach signal, not a predicate signal — and (b) a genuine call-site mutation is measured separately (author's M1; my R6, RED). M2 alone would not have been sufficient evidence; the pair is.
The round-2 retraction — verified independently, not credited
The corrected wording ("the water check ran and the .wtr did not load, so the zone was abandoned unwalked with no number") is true, and I checked it against the code rather than against the correction's own reasoning:
install()returnsErrexactly when theZoneWaterisUnmeasured— so the only path into theunmeasuredbucket is theinstall-error arm attests/walker_sim.rs:630-634, whichaddszw.tally()andcontinues before any journey pair is sampled.- The only other
addis at:795-796, reachable only afterinstallreturnedOk, i.e. with aMeasuredzw— which can never land inunmeasured.
So there is no second path that could make "walked but unscored" true for some run. The surviving sentence in the correction block checks out.
Findings
1. NON-BLOCKING — the replacement "never" universal is false as written (tests/walker_sim.rs:871-872)
"…so a per-zone refusal on any of them could never fire where the terminal one would not"
Counterexample, by satisfying the premise (monotonicity, close-decidability — both of which I confirmed) and breaking the conclusion: assert!(tot_walked > 0, "no journeys walked — check $ZONE_DIR") at :810 runs BEFORE the completeness assert at :828. On a run where every zone lands in unmeasured (the install arm walks nothing — the very fact the retraction above establishes), tot_walked == 0, so without the gate the run dies at :810 and the terminal completeness refusal is never reached — while the per-zone gate does fire. The same holds for an all-skipped run. This is not exotic: it is exactly the "build host holding 2 of 497 .wtr files" shape the doc cites two paragraphs earlier, taken to a $ZONE_DIR where none load.
The property the sentence is reaching for is true and I verified it: the hole Vecs are push-only (no clear/retain/pop/remove in water_grid.rs), so whenever the gate fires the run was going to fail anyway — at :810 or at :828. No new false positives. Suggested wording: "could never fire on a run that would otherwise have passed". This paragraph has now carried a wrong universal in two consecutive revisions, which is why I am naming it rather than waving it through — but it is a wording defect over a sound property, and I would merge over it.
2. NON-BLOCKING — the honesty framing on the abort path is pinned by nothing (tests/walker_sim.rs:913-916)
R7 deleted the entire [ABORTED …] — PARTIAL rollups … this is not a corpus score println! and the target stayed 11 passed / 0 failed. By entailment, any weaker edit survives too — including the dangerous direction, dropping the "PARTIAL"/"not a corpus score" framing while keeping the numbers. The three should_panic expected strings pin only bucket-name fragments ("unaccounted (left the loop body…", "the #423 rollup already holds a hole", "unmeasured (the water check ran…"); nothing pins "not a corpus score" in either the println! or the panic. Given that #799's whole lesson is written ≠ reached, an unpinned honesty surface is worth a follow-up contains assertion in one of the existing should_panic tests. Not blocking: the text is correct today, and R7's direction makes the output less informative, not dishonest.
3. NON-BLOCKING (theoretical) — WaterRollup's complete form carries no INCOMPLETE marker
The gate fires when either rollup is dirty and prints both. Display's complete branch renders "{total} (over {m}/{k} zones)" with no marker, so a reader slicing just the wat-route: … fragment out of the ABORTED line could see a clean-looking number inside a partial report. This cannot arise in the corpus — every add/skip is paired across both rollups (:617, :623, :633-634, :730, :795-796), so they move in lockstep — but ..._covers_the_423_rollup_not_just_wat_route proves divergence is representable in the type. Recorded, not asked for.
4. NON-BLOCKING — undisclosed asymmetry in the skipped exemption rationale (:874)
skipped is exempted because it is "the COMMON state of a partial $ZONE_DIR". True — but by the doc's own #762 exhibit (2 of 497 .wtr files), unmeasured is equally common on a dev box, and that bucket is gated. The trade is defensible (the skipped table row is printed per zone and a skip costs a zone that was never going to be scored anyway), but the doc states the cost asymmetrically. A clause would fix it.
The two judgement calls you asked me to make
Closes #805 — justified. #805's success criterion is that "an abandoned run cannot leave a clean-looking rollup behind". After this PR, on an abandoned run no rollup is published at all: the only publication points are the total line at :799 and the terminal assert at :828, both after the loop, plus the new ABORTED line which is explicitly labelled not-a-score. The residue (skipped, and the zone still open when the run stops) is a coverage gap, not a publication gap — and both are named in two tracked places (:826-827 and the fn's doc). #805's headline harm — a silent zero-water score from unmeasured — is closed. A corpus that can still hold a terminal-only skipped therefore still satisfies the issue as written; #805's "Shape of a fix" explicitly leaves scope to the fixer.
The ABORTED line is honest enough about being partial. Captured live from R1's failing run:
=== FAITHFUL WALKER DRIFT [ABORTED while opening zone_b] — PARTIAL rollups; the zones after
zone_b were never opened, so this is not a corpus score: wat-route: 0 over 0/1 zones —
INCOMPLETE, 1 skipped [zone_a (no glb)], #423: 0 over 0/1 zones — INCOMPLETE, 1 unaccounted
[zone_a] (opened by begin_zone, never reached add/skip) ===
It puts ABORTED while opening {zone} in the slot where the run mode normally goes, says PARTIAL, says "this is not a corpus score", names where it died and that later zones were never opened, and each rollup's own Display independently prints INCOMPLETE with its hole named. A reader cannot mistake this for the === FAITHFUL WALKER DRIFT [mode]: N full journeys walked … score line at :799. Subject only to findings 2 and 3.
What I did NOT verify
- The two live corpus runs the doc cites —
ZONES=crushbone,felwitheaprinting the all-dashescrushbonerow in 0.53s, andZONES=akanon,crushboneskipping akanon at zone 1 of 2. I have no baked zone GLBs; those figures remain the author's own measurement, uncorroborated. (Note the first implies a run that also trips:810, consistent with finding 1.) - That the corpus actually hangs on blackburrow (faithful_walker_drift_corpus never terminates on blackburrow — the wat-route:12 baseline is now unreplaceable #763). No blackburrow run was executed by me, and the doc says none was executed by the author either.
- Real GitHub-runner behaviour. I checked the merged tree by reading:
.github/workflows/test.yml:148iscargo test --workspace --locked, and--ignoredappears 0 times in.github/workflows/*.yml. - Runtime cost of the gate (it is two
Vec::is_empty()checks per zone; not measured). - fix(#803): make "no exits" and "could not read the exits" different types #821's own content — I merged it and measured the result green; I did not review it.
scripts/check-no-local-detail.shpasses on the merged tree (that I did run: OK).
…nstead of copying them Addresses #819 — deliberately NOT `Closes`, see below. `fine_tier_corpus_route_success_and_cost` declared its own `LOCAL_REACH` and `LOCAL_CELL` instead of using the `pub const`s in `steering`. #818/#733 promoted `LOCAL_REACH` to `pub` precisely so `drive_walk` and `resync_cursor` could not judge two different carrots; this corpus predates the promotion and was never swept into it, so a future change to either shared constant would have left it measuring the old number and reporting a confident green about a tier production no longer runs. Both are now imported. `LOCAL_BOUND` stays a private local copy: no `pub const LOCAL_BOUND` exists anywhere in the repo, and every site that needs it (`walker.rs:1507`, `steering.rs:1063`, `tests/walker_sim.rs:348`) restates the literal with a comment pointing back to `drive_walk`. Importing it would require deciding where it lives, which #819 does not decide. Those three citations were re-checked at source before merge, not taken from the PR body. WHY THIS IS `Addresses` AND NOT `Closes` — the acceptance bar is not met. #819 asks for a test that goes RED when the copy comes back. The reviewer enumerated the reintroduction paths: a duplicate `const LOCAL_REACH` alongside the import is a duplicate-definition error, and a shadowing `let LOCAL_REACH = 24.0` is a refutable-pattern error — but **deleting the `use` and restoring both private consts (a straight revert of this hunk) compiles clean and nothing catches it, ever.** That is the realistic regression path and it is open after this merge. No assertion in that test can close it, and the reason is structural rather than a missing check: carrots are generated once via `carrot_along(&route, i, from, LOCAL_REACH)` and the same set feeds both the OLD and NEW comparators, so any change to the constant moves both sides symmetrically and `assert_eq!(tot_old_only, 0)` / `assert!(tot_new_ok >= tot_old_ok)` stay satisfied at any value. The test is incapable of observing the constant it consumes. The author's own mutation says the same thing and was disclosed rather than dressed up: `steering::LOCAL_REACH` 24.0 → 200.0 collapsed route success from 97.5% to 4.6% (240 pairs, blackburrow) and the test still reported `ok`. What that does prove is that the import is live and load-bearing — it rules out a dead-import false positive — and that is the honest extent of the claim. A source-scanning guard was considered and rejected. This repo has measured seven distinct ways a source-text pin proves a call is *written* rather than *reached* (#799), and the analogous `doc_citations` machinery was itself found covering a fraction of its intended corpus (#778). An eighth text scan defending a latent drift risk is a worse trade than an open, precisely-stated issue. #819 stays open with the revert path recorded on it. Drift check: none had occurred. Verified at this branch's actual parent — both private copies matched the shared values exactly (`LOCAL_REACH = 24.0`, `LOCAL_CELL = 2.0`). A latent hazard closed, not a live bug fixed. The `24.0` literal sweep was re-run workspace-wide, not just in-crate: `CURSOR_RESYNC_MAX_HOP = 24.0` is rejected as a deliberately separate constant whose doc frames the relationship as conceptual rather than mechanical, and the remaining hits are unrelated coordinates and depths. Figures measured by the reviewer on head `72a9dae` merged with `5fba300`, streams captured separately, run-completion confirmed by process exit rather than by the compile sentinel: `Finished \`test\` profile … in 3m 10s` · **55 `running N tests?` headers = 55 `test result:` lines** (equality is the lost-binary check) · **0** non-canonical result lines · **14** targets with the full `0 passed; 0 failed; 0 ignored` triple · **1830 passed + 0 failed + 47 ignored + 0 filtered = 1877** = the header sum. Identical to plain `5fba300`, zero test-count movement — which is what an import-for-identical-literal swap should look like. The author's own run on the older base reconciles exactly: `1823 + 0 + 47 + 0 = 1870` plus #825's +2 and #824's +5. NOT verified, and not claimed: - The `#[ignore]`d asset-gated corpus test was not re-run by the reviewer — no baked zone GLBs. Only the author ran it, and only to observe the mutation's effect. - The reviewer's reintroduction probes were done via a standalone `rustc` repro rather than by rebuilding the real `collision.rs`, so the two compile-error rows are established for the language rule, not for this file specifically. The third row — the one that matters — needs no probe: it is the diff read backwards. - No live run. This is a test-constant change with nothing observable in game. - The 47 `#[ignore]`d tests were not run (#777).
Closes #805
The defect
#762 gave
faithful_walker_drift_corpusa completeness refusal — "a hole in the corpus is not awater score" — and made it the last statement of the test. #763 says the corpus never terminates
on blackburrow. So on the one run where a zone is known to misbehave, the refusal is not reached: a
guard that is written and not run. Same shape as #778's scanner and the #799 source pins.
Mechanism: close the accounting per zone
Opening a zone in the corpus loop now goes through
open_zone_checked(&mut roll_wr, &mut roll_423, zone)(intests/walker_sim.rs) instead of a barebegin_zonepair. Before it opens zone K itrefuses the run if any already-closed zone sits in the
unaccountedorunmeasuredbucket. Arun that hangs, returns early, or dies at zone K has therefore already checked zones 1..K-1 for
both.
skippedis deliberately not checked per zone, and the reason is diagnostics, notdecidability. All three buckets are push-only
Vecs, so all three are settled the instant a zonecloses and none can un-fire; a per-zone refusal on
skippedcould never fire where the terminal onewould not. What is true is that
skippedis the common state of a partial$ZONE_DIR, i.e. thenormal state of a dev box: on the two-zone run below, akanon is
skipped for "no routable pairs" atzone 1 of 2, so gating
skippedhere would kill the run before crushbone's 60 journeys everrun — and
skippedis already printed per zone in the table ((no glb — skipped)), so gating itbuys little. That is a judgement call, and it is labelled as one in the code.
Alternatives rejected, and the failure mode each has
Dropimpl onWaterRollupthat assertsWaterRolluplives incrates/eqoxide-nav/src/water_grid.rs, which is held by open PR #821 — editing it manufactures a conflict. (b) ADropthat panics while a panic is already unwinding aborts the process, replacing a real corpus failure's diagnostics with a confusing abort; avoidable only with astd::thread::panicking()guard, which then makes the guard do nothing on exactly the runs that already failed. (c) A hang never drops anything.Dropruns on scope exit or unwind; a process wedged inside zone K's loop body does neither. The mechanism that looks strongest against "the last statement is skipped" does not fire in #805's scenario at all.panic!on a non-test thread does not fail a libtest test, so it would needprocess::abort, which destroys all captured output — the opposite of the honesty goal. And the threshold would be flaky by construction: a two-zone run measured 49 s–150 s here depending on which zones, and the corpus's runtime is a function of whatever$ZONE_DIRhappens to contain.is_complete()per zone (i.e. also gateskipped).glb/ unroutable zone. Measured below: it would kill this box's own two-zone run at zone 1. This is the diagnostics trade, not a claim that it cannot be decided.What an operator sees
wedged blackburrow run still sees nothing extra. The gain is only that zones 1..K-1 are verified
individually as they complete, instead of all of them resting on a statement the run never
reaches.
corpus's own total line runs after the loop and so never executes on an aborted run. That line
is explicitly labelled
PARTIALand "not a corpus score", since the zones after the offending onewere never opened. Raw output in RED-A below.
begin_zoneobserves it, so it remains the terminal assert's job — as doesskipped, for everyzone. The terminal assert is still load-bearing; it is not a backstop.
Mutation checks — both directions, all on the shipped tree
Every run below is on
3667927'stests/walker_sim.rs. Between runs the file was restored from abyte-identical copy (
md5sumverified,git status --porcelainempty). Four of the six use thereal corpus loop against real baked zone GLBs, so the mutation is at the real call site and not
only in a fixture.
M1 — kill the gate at the CALL SITE (not in its body)
In the reach-control test,
open_zone_checked(&mut wr, &mut r423, zone);→wr.begin_zone(zone); r423.begin_zone(zone);. RED:The
should_panicsubstring is hand-written text; it does not consultunaccounted_zones()oranything else the gate consults, so instrument and subject do not share a code path (#818).
M2 — the "written but not reached" evasion
if orphans.is_empty() && unmeasured.is_empty() { continue; }→if true { continue; }. The wholerefusal —
println!andpanic!— stays in the source and is never executed. Three of the fourgate tests RED, all with a wrong-message
should_panicfailure:The one test that stays green under M2 is the no-false-positive control, which is the correct
direction for it.
RED-A — real corpus, real GLBs, a
.wtrremoved (theunmeasuredbucket, #762's exhibit)crushbone.wtrmoved aside,ZONES=crushbone,felwithea, release. The gate fires while openingfelwithea, i.e. mid-loop:
RED-B — the same assets with the gate removed from the real call site (the pre-#805 picture)
open_zone_checked(…)→ the barebegin_zonepair, same command:The whole loop ran — felwithea's 60 journeys included — and the hole was reported only by the last
statement. That is exactly the #805 shape and exactly the statement a non-terminating run does not
reach.
GREEN — every
.wtrpresent, gate silent, no false positiveZONES=akanon,crushbone, all region files present:No
[ABORTED …]line anywhere: the gate stayed silent across both zones, the whole table printed,and the run fails at the terminal assert on the pre-existing skip — the same outcome as before this
PR. This is also the measurement the
skippedexemption rests on: akanon is skipped at zone 1 of 2.M_G — what the gate at the REAL call site is NOT pinned by
Reverting the corpus's
open_zone_checked(…)to the barebegin_zonepair and running the wholeworkspace suite:
55headers =55results,0non-canonical,14all-zero,1815 + 0 + 47 + 0 = 1862— identical to the unmutated figures, and the sorted set oftest … ok|ignoredlines (1819 of them) isdiff -q-identical. Nothing CI runs notices the fixbeing deleted. That is disclosed in
open_zone_checked's rustdoc in those words; see "NOT verified"below.
Simulating the hang without blackburrow
Blackburrow cannot be run (it hangs, per #763), so early termination is proved on
WaterRollupalone with no GLB:
zone_accounting_fires_before_the_corpus_loop_endswalks a three-zone list whosesecond zone is abandoned and whose third stands in for blackburrow, and both statements after the
loop are
panic!("UNREACHED: …")with messages theshould_panicfilter rejects. The test passesonly if the gate fires at zone 3 before anything post-loop runs.
The five figures
cargo test --workspace --locked --no-fail-faston the remote build host, stdout and stderrcaptured separately.
Finished \test` profileappears once — that is the **build** finishing, not the run. The completion signal used here was process exit plus a complete finaltest result:` line.^running [0-9]+ tests?$headers vs 55^test result:lines — equal, no lost binary.(The regex matches
testandtests;running 1 testis singular.)^test result: ok\. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out.1815 passed + 0 failed + 47 ignored + 0 filtered out = 1862, and the header total is 1862.origin/main41cca4ebaseline is 55 = 55, 0 non-canonical, 14 all-zero, 1857 total. Delta +5,reconciled by name — the five tests this PR adds:
zone_accounting_fires_before_the_corpus_loop_endszone_accounting_stays_silent_while_every_zone_is_closedzone_accounting_covers_the_423_rollup_not_just_wat_routezone_accounting_refuses_an_unmeasured_zone_before_the_corpus_endsdoc_comment_citations_in_this_file_are_rename_guardedNo target count changed.
scripts/check-no-local-detail.sh→OK — no forbidden patterns in tracked files.One test that is not about #805, and why it is here
The first workspace run in round 1 went RED on
eqoxide-nav … every_test_citation_in_the_four_citation_files_resolves_and_is_listed_in_a_guard:open_zone_checked's rustdoc citesfaithful_walker_drift_corpusby name,tests/walker_sim.rsisin that scan's citation corpus, and the file had no guard array.
doc_comment_citations_in_this_file_are_rename_guardedsupplies thelet _cited: &[fn()]the scanrequires. That failure was measured, not anticipated — it is why the test exists.
Why this still says
Closes #805, and what remains terminal-only#805's exhibit is #762's motivating defect: a
.wtrthat did not load being scored as0, on a runthat may never reach the reconciliation. That bucket —
unmeasured— is now refused per zone, as isunaccounted, and RED-A demonstrates the refusal firing at the real call site mid-loop. So theissue's own scenario is covered and
Closesis the honest verb.Two things stay in the terminal assert, both named in the code rather than glossed:
skipped, for every zone — the diagnostics trade above. If a reviewer judges that leavingskippedterminal means #762's completeness guard is the corpus's LAST statement, so blackburrow's non-termination (#763) skips it entirely #805 is not closed, the one-word fix isRefs #805; I am not treatingthat as a defensible-either-way toss-up, I am stating my reason and the cost of the alternative.
nothing closes it and no later
begin_zoneobserves it.NOT verified, and not claimed
faithful_walker_drift_corpusis#[ignore]d and.github/workflows/test.ymlrunscargo test --workspace --lockedwith no--ignored. M_G measures the consequence exactly:delete the
open_zone_checked(…)call from the corpus loop and the entire workspace suite staysbyte-identically green. The four gate tests pin the helper's behaviour; nothing CI runs pins
that the corpus calls it. This is Source-scan call-site pins prove a call is written, not reached (#721 A2b, #773 E1b/E2, #791 round 1) #799 applying to this PR, it is written in the rustdoc in those
words, and it is not fixed here — whether
#[ignore]d tests should run in CI is The merge gate cannot see asset-gated pins: #[ignore]'d tests carry load-bearing evidence CI never runs #777 / Asset-gated #[ignore]d tests never run anywhere — the #648 capability tests were merged unexecuted by any reviewer #654 /Decision: synthetic mini-zone fixtures vs a self-hosted runner for asset-gated CI (#657 is blocked on this) #659, an owner-gated decision I did not touch (no CI config, no un-
#[ignore]ing, no runnerproposed).
Blackburrow was never run; its hang is not observed anywhere in this PR. Every "hang" claim here is
about early termination in general, simulated on
WaterRollupwith a truncated zone list.tests/walker_sim.rs, established by reading the file — and consistent with RED-A's stdout, wherethe total line is absent and only the
[ABORTED …]partial line appears. It is not an observationof a hung run.
ZONES=akanon,crushboneandZONES=crushbone,felwithea. I did not run the default eleven-zone corpus and make no claim aboutits numbers. akanon skipping for "no routable pairs" is what that asset set produced on that host;
it is not asserted to be a property of akanon.
open_zone_checkedhas seven lexical call sites on this tree — one in the corpus loop, sixacross the four gate tests. (Round 1's body said "both call sites"; there were four then, and the
reviewer was right to count. Nothing now rests on that sentence: M1, M2 and every corpus run above
were re-taken on the shipped tree, so there is no cross-revision byte-identity argument left in
this PR.)
water_grid.rs,collision.rs,observe.rs, …) are untouched. Thewhole change is
tests/walker_sim.rs, usingWaterRollup's existing public API only.validation is claimed.
What round 2 changed, and which claims were retracted
unmeasured/skipped… is a question about the whole denominator — notanswerable at zone 3 of 11." Measured false by the reviewer: the buckets are push-only, so every
bucket is decided the instant a zone closes and
is_complete()is monotone. The gate now coversunmeasured, andskipped's exemption is restated as the diagnostics trade it always was.opened." Only
unaccountedwas per-zone at the time;unmeasuredandskippedwere not.unmeasured— the zone was walked and its.wtrdid not load." The water arm closes the zone withadd(…)andcontinues before anyjourney is sampled — RED-A prints a row of dashes and the whole run took 0.48 s. The rustdoc, the
panic text and the
should_panicsubstring now say "the water check ran and the.wtrdid notload, so the zone was abandoned unwalked".
zone_accounting_covers_the_423_rollup_not_just_wat_route, a divergent-rollup REDtest — the round-1 tests drove both rollups identically, so the
#423arm and its{label}interpolation were unpinned.
zone_accounting_does_not_cover_the_zone_that_is_still_openhad no unique killand duplicated
crates/eqoxide-nav/src/water_grid.rs's own coverage of that property. The limit itdescribed is still stated in
open_zone_checked's rustdoc.[ABORTED …]partial rollup line, printed before the panic, so an aborted runstill shows what it did establish — labelled PARTIAL so it cannot be read as a score.
🤖 Generated with Claude Code
https://claude.ai/code/session_01HQVEpaaKeXsZcW9VT2roeV