Batch-7 server track: T-1116. Several real bodies (GJ251c, GJ380c) generated settlements but ZERO road edges — every A* pair dropped because a coastal settlement's land pixel can sit inside a routing cell that is water-majority after downsampling (a cell folds up to 64 native pixels), and astar() hard-returned None for any pair touching an IMPASSABLE anchor.
The fix (single file, road_graph.rs): relax only the start/goal anchor lookup. nearest_passable_cell (ring BFS, deterministic row-major tie-break, bounded at COASTAL_ANCHOR_MAX_RING=3) finds a surrogate anchor; the route pays COASTAL_ACCESS_COST_PER_RING per ring — a short, honestly-priced access road, never a free water crossing. IMPASSABLE semantics untouched everywhere else (D-210 transit costs, open ocean). The placement-nudge alternative was rejected: it would move Layer-3 state D-211 promises is seed-derived.
Boundary semantics pinned by test: exactly-half-water cells stay passable (strict-majority rule); a settlement with no passable cell within the search ring degrades to an isolated 0-edge node — never a panic, never a fabricated route.
Test plan
Failing-first repro on real bodies via the real cascade entry point: GJ251c 0→2 edges (all 3 placements were in IMPASSABLE cells), GJ380c 0→1 (Sethvale)
6 new tests incl. threshold-boundary and surrounded-by-water degradation; road_graph suite 24/24
Same-seed determinism pinned; full cargo test green (1976+ lib and all harness binaries)
Live road-overlay eyeball at merge: GJ251c (Tributarium/Ruhr/The Gate Corporation) and GJ380c (Sethvale coastal-access spur) — roads should now be visible on bodies that showed none
## Summary
Batch-7 server track: T-1116. Several real bodies (GJ251c, GJ380c) generated settlements but ZERO road edges — every A* pair dropped because a coastal settlement's land pixel can sit inside a routing cell that is water-majority after downsampling (a cell folds up to 64 native pixels), and astar() hard-returned None for any pair touching an IMPASSABLE anchor.
**The fix (single file, road_graph.rs):** relax only the start/goal anchor lookup. `nearest_passable_cell` (ring BFS, deterministic row-major tie-break, bounded at COASTAL_ANCHOR_MAX_RING=3) finds a surrogate anchor; the route pays COASTAL_ACCESS_COST_PER_RING per ring — a short, honestly-priced access road, never a free water crossing. IMPASSABLE semantics untouched everywhere else (D-210 transit costs, open ocean). The placement-nudge alternative was rejected: it would move Layer-3 state D-211 promises is seed-derived.
**Boundary semantics pinned by test:** exactly-half-water cells stay passable (strict-majority rule); a settlement with no passable cell within the search ring degrades to an isolated 0-edge node — never a panic, never a fabricated route.
## Test plan
- Failing-first repro on real bodies via the real cascade entry point: GJ251c 0→2 edges (all 3 placements were in IMPASSABLE cells), GJ380c 0→1 (Sethvale)
- 6 new tests incl. threshold-boundary and surrounded-by-water degradation; road_graph suite 24/24
- Same-seed determinism pinned; full cargo test green (1976+ lib and all harness binaries)
- Believability + cascade goldens verified unaffected (Layer-2-only change; validation bodies don't measure road edges)
- Live road-overlay eyeball at merge: GJ251c (Tributarium/Ruhr/The Gate Corporation) and GJ380c (Sethvale coastal-access spur) — roads should now be visible on bodies that showed none
A routing cell folds up to 64 native pixels, so a coastal settlement's
own land pixel (placement always filters !ocean_mask) can sit inside a
water-majority cell that RouteGrid marks IMPASSABLE — and astar()
hard-returned None for every pair touching it, zeroing whole road
graphs (GJ251c: all 3 placements; GJ380c: Sethvale). The fix relaxes
only the start/goal anchor lookup: nearest_passable_cell (ring BFS,
deterministic row-major tie-break, bounded at COASTAL_ANCHOR_MAX_RING=3)
finds a surrogate anchor and prices it via COASTAL_ACCESS_COST_PER_RING
— a short, honestly-costed access road, never a free water crossing.
IMPASSABLE semantics untouched everywhere else (D-210 transit costs,
open-ocean). The placement-nudge alternative was rejected: it would
move Layer-3 state D-211 promises is seed-derived, for no gain.
Boundary semantics pinned by test: exactly-half-water cells stay
passable (strict-majority rule); a settlement with no passable cell
within the search ring degrades to an isolated 0-edge node, never a
panic or fabricated route. Failing-first repro on real bodies
(GJ251c 0->2 edges, GJ380c 0->1) via the real cascade entry point,
plus same-seed determinism. Full cargo test green; believability and
cascade goldens verified unaffected (Layer-2-only change).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Review: road-routing-coastal-fix -> main (type: code)
Reviewers: Hoshe (QA) + Tyre (architecture/governance). Both REQUEST_CHANGES.
Hoshe (QA): REQUEST_CHANGES
#
File
Issue
1
road_graph.rs:110/:121-143
Unit-mismatch bug: length_cells is a pure HOP COUNT (a grassland step contributes 1 regardless of its 200-unit cost), but the surcharge is computed in cost units then div_ceil(MIN_CELL_COST=50)-folded in — yielding 4 hops per ring, not the documented "one extra grassland hop." Worst case (both anchors ring 3) adds +24 length_cells — double WAYPOINT_THRESHOLD_CELLS — spuriously tripping (or elsewhere masking) the add_waypoints gate for physically short edges. Fix: derive the surcharge directly in hop units (or a separate field the waypoint gate doesn't read) and correct the comment's stated rationale.
2
road_graph.rs:2072
The GJ251c repro case asserts min_edges = 1 while the commit message and the test's own module comment claim "GJ251c 0→2" — a regression to exactly 1 edge would pass silently. Tighten to the documented 2.
Hoshe's confirmations on record: nearest_passable_cell genuinely deterministic (plain Vec, fixed push order, no hash iteration), correctly bounded (ring 0 = self; 1..=MAX_RING, no off-by-one) and grid-edge-safe (rows clamp, columns wrap); IMPASSABLE untouched for mid-path transit (main-loop guard diffed against main); the drawn geometry force-anchors both ends at the exact settlement position — no visible road-to-marker disconnect risk for the eyeball; the determinism test compares full structural graph equality (PartialEq over edges/costs/paths/nodes), not counts.
Tyre (architecture/governance): REQUEST_CHANGES
#
File
Issue
1
road_graph.rs:12
Misattributed load-bearing citation: the !ocean_mask "always land" guarantee lives in features.rs::extract_attractors (D-209, lines 544/570) — not attractor_matching.rs (D-211), which does no ocean filtering. Fix the pointer, and add a word on the D-211 phase-4 synthetic-overflow path (PlainCenter) — verify it also guarantees land, since synthetic attractors are generated positionally rather than extracted.
2
governance (D-210)
Amendment required: the surrogate-anchor-at-cost carve-out is a reusable, citable principle (a genuine qualification of "IMPASSABLE is absolute for all routing purposes") and the layer-analysis adjudication (relaxation over nudge, D-211 seed-derived promise — verified accurate) currently lives only in code+ticket. One-paragraph D-210 amendment on this branch, cross-referencing T-1116.
3
road_graph.rs:34
COASTAL_ACCESS_COST_PER_RING = ORTHO * 100 re-hardcodes the grassland baseline 100 (cost-field initializer) as a bare literal — if the baseline changes, the surcharge silently decouples from its own rationale. Extract a shared named constant. (Interacts with Hoshe #1 — resolve together.)
Tyre's confirmations on record: the fix-choice adjudication is accurate (D-211's positions genuinely seed-derived; layer analysis right); D-210 else-branch transit semantics byte-identical to main; determinism pure-integer with no cross-platform hazard; believability provably inert to roads (zero road_graph references in believability.rs; the layer runs but no metric reads it); scope containment decisive — length_cells is dropped at the Atlas wire boundary (layer_proxy.rs:1796/1800) and maintenance_authority uses straight-line euclid, so the surcharge never reaches the client.
Verdict: CHANGES REQUESTED
All five findings dispatched to the authoring agent; fix round → gate → live road-overlay eyeball (GJ251c, GJ380c) → merge.
# Review: road-routing-coastal-fix -> main (type: code)
Reviewers: Hoshe (QA) + Tyre (architecture/governance). Both REQUEST_CHANGES.
## Hoshe (QA): REQUEST_CHANGES
| # | File | Issue |
|---|------|-------|
| 1 | road_graph.rs:110/:121-143 | **Unit-mismatch bug**: `length_cells` is a pure HOP COUNT (a grassland step contributes 1 regardless of its 200-unit cost), but the surcharge is computed in cost units then `div_ceil(MIN_CELL_COST=50)`-folded in — yielding **4 hops per ring**, not the documented "one extra grassland hop." Worst case (both anchors ring 3) adds +24 length_cells — double WAYPOINT_THRESHOLD_CELLS — spuriously tripping (or elsewhere masking) the add_waypoints gate for physically short edges. Fix: derive the surcharge directly in hop units (or a separate field the waypoint gate doesn't read) and correct the comment's stated rationale. |
| 2 | road_graph.rs:2072 | The GJ251c repro case asserts `min_edges = 1` while the commit message and the test's own module comment claim "GJ251c 0→2" — a regression to exactly 1 edge would pass silently. Tighten to the documented 2. |
Hoshe's confirmations on record: `nearest_passable_cell` genuinely deterministic (plain Vec, fixed push order, no hash iteration), correctly bounded (ring 0 = self; `1..=MAX_RING`, no off-by-one) and grid-edge-safe (rows clamp, columns wrap); IMPASSABLE untouched for mid-path transit (main-loop guard diffed against main); **the drawn geometry force-anchors both ends at the exact settlement position — no visible road-to-marker disconnect risk for the eyeball**; the determinism test compares full structural graph equality (PartialEq over edges/costs/paths/nodes), not counts.
## Tyre (architecture/governance): REQUEST_CHANGES
| # | File | Issue |
|---|------|-------|
| 1 | road_graph.rs:12 | Misattributed load-bearing citation: the `!ocean_mask` "always land" guarantee lives in **features.rs::extract_attractors** (D-209, lines 544/570) — not attractor_matching.rs (D-211), which does no ocean filtering. Fix the pointer, and add a word on the D-211 phase-4 synthetic-overflow path (PlainCenter) — verify it also guarantees land, since synthetic attractors are generated positionally rather than extracted. |
| 2 | governance (D-210) | **Amendment required**: the surrogate-anchor-at-cost carve-out is a reusable, citable principle (a genuine qualification of "IMPASSABLE is absolute for all routing purposes") and the layer-analysis adjudication (relaxation over nudge, D-211 seed-derived promise — verified accurate) currently lives only in code+ticket. One-paragraph D-210 amendment on this branch, cross-referencing T-1116. |
| 3 | road_graph.rs:34 | `COASTAL_ACCESS_COST_PER_RING = ORTHO * 100` re-hardcodes the grassland baseline `100` (cost-field initializer) as a bare literal — if the baseline changes, the surcharge silently decouples from its own rationale. Extract a shared named constant. (Interacts with Hoshe #1 — resolve together.) |
Tyre's confirmations on record: the fix-choice adjudication is accurate (D-211's positions genuinely seed-derived; layer analysis right); D-210 else-branch transit semantics byte-identical to main; determinism pure-integer with no cross-platform hazard; believability provably inert to roads (zero road_graph references in believability.rs; the layer runs but no metric reads it); scope containment decisive — `length_cells` is dropped at the Atlas wire boundary (layer_proxy.rs:1796/1800) and maintenance_authority uses straight-line euclid, so the surcharge never reaches the client.
## Verdict: CHANGES REQUESTED
All five findings dispatched to the authoring agent; fix round → gate → live road-overlay eyeball (GJ251c, GJ380c) → merge.
The surcharge is now COASTAL_ACCESS_SURCHARGE_HOPS_PER_RING=1 added
directly to length_cells (a pure hop count) — the old cost-unit
constant div_ceil'd through MIN_CELL_COST silently produced 4 hops per
ring, worst-case +24 (double the waypoint threshold) for physically
short edges; worst case is now 6. A formula-pinning test asserts both
the arithmetic and the constant. GJ251c's repro tightened to the
documented 2 edges. The always-land citation now points at the real
guarantee (features.rs::extract_attractors, D-209) — and checking the
D-211 Phase-4 synthetic-overflow path exposed a real gap: it has no
ocean-mask guard at all (T-1206 filed); documented, not papered over.
D-210 gains a dated amendment recording the surrogate-anchor-at-cost
carve-out and the relaxation-over-nudge adjudication. The bare 100
dependency dissolved with the unit fix. Edge counts on both repro
bodies verified unchanged (reachability was never affected).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Fixed — the surcharge is now COASTAL_ACCESS_SURCHARGE_HOPS_PER_RING = 1, added directly to length_cells with no unit conversion (the old cost-unit constant div_ceil'd to 4 hops/ring; worst case was +24 — double the waypoint threshold — now +6). A formula-pinning test asserts both the arithmetic (in isolation via the start==goal short-circuit) and the constant's value, so regression requires a visible deliberate change. Edge counts on both repro bodies verified unchanged (reachability was never affected — the bug only inflated reported length).
Hoshe
2
Fixed — GJ251c tightened to the documented 2 edges; passes.
Tyre
1 (citation)
Fixed — pointer corrected to features.rs::extract_attractors (D-209). The instructed check of the D-211 Phase-4 synthetic-overflow path found a REAL gap: synthetic_attractor takes no terrain argument and never checks ocean_mask — a synthetic-overflow settlement can land in open water. Documented in the code comment and the D-210 amendment, not papered over; T-1206 filed (the routing relaxation degrades that case gracefully, but the placement guarantee is Layer 3's gap to fix).
Tyre
2 (governance)
Fixed — dated D-210 amendment on this branch (D-226 format precedent): the surrogate-anchor-at-cost carve-out, transit-IMPASSABLE-untouched scope, the relaxation-over-nudge adjudication vs D-211's seed-derived positions, and the synthetic-overflow flag. pql decisions validate ok; sync clean, 0 broken refs.
Tyre
3 (bare 100)
Resolved via finding 1 — the hop-unit surcharge has no cost-unit derivation left, so the grassland-baseline dependency dissolved rather than being renamed. The only other bare 100 in the file is the pre-existing cost-vector pre-fill (immediately overwritten), untouched as out of scope.
No retractions — all five findings accurate. road_graph suite 25/25; full cargo test 0 failures (1977 lib + all golden harnesses). Gate green on push. Live before/after road-overlay eyeball (GJ251c, GJ380c) in progress — merge follows it.
# Fix round — all 5 findings addressed in `de8bcf4eb`
| Reviewer | # | Resolution |
|----------|---|------------|
| Hoshe | 1 (unit bug) | **Fixed** — the surcharge is now `COASTAL_ACCESS_SURCHARGE_HOPS_PER_RING = 1`, added directly to `length_cells` with no unit conversion (the old cost-unit constant div_ceil'd to 4 hops/ring; worst case was +24 — double the waypoint threshold — now +6). A formula-pinning test asserts both the arithmetic (in isolation via the start==goal short-circuit) and the constant's value, so regression requires a visible deliberate change. Edge counts on both repro bodies verified unchanged (reachability was never affected — the bug only inflated reported length). |
| Hoshe | 2 | **Fixed** — GJ251c tightened to the documented 2 edges; passes. |
| Tyre | 1 (citation) | **Fixed** — pointer corrected to `features.rs::extract_attractors` (D-209). The instructed check of the D-211 Phase-4 synthetic-overflow path found a REAL gap: `synthetic_attractor` takes no terrain argument and never checks `ocean_mask` — a synthetic-overflow settlement can land in open water. Documented in the code comment and the D-210 amendment, not papered over; **T-1206 filed** (the routing relaxation degrades that case gracefully, but the placement guarantee is Layer 3's gap to fix). |
| Tyre | 2 (governance) | **Fixed** — dated D-210 amendment on this branch (D-226 format precedent): the surrogate-anchor-at-cost carve-out, transit-IMPASSABLE-untouched scope, the relaxation-over-nudge adjudication vs D-211's seed-derived positions, and the synthetic-overflow flag. `pql decisions validate` ok; sync clean, 0 broken refs. |
| Tyre | 3 (bare 100) | **Resolved via finding 1** — the hop-unit surcharge has no cost-unit derivation left, so the grassland-baseline dependency dissolved rather than being renamed. The only other bare `100` in the file is the pre-existing cost-vector pre-fill (immediately overwritten), untouched as out of scope. |
No retractions — all five findings accurate. road_graph suite 25/25; full cargo test 0 failures (1977 lib + all golden harnesses). Gate green on push. Live before/after road-overlay eyeball (GJ251c, GJ380c) in progress — merge follows it.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
Batch-7 server track: T-1116. Several real bodies (GJ251c, GJ380c) generated settlements but ZERO road edges — every A* pair dropped because a coastal settlement's land pixel can sit inside a routing cell that is water-majority after downsampling (a cell folds up to 64 native pixels), and astar() hard-returned None for any pair touching an IMPASSABLE anchor.
The fix (single file, road_graph.rs): relax only the start/goal anchor lookup.
nearest_passable_cell(ring BFS, deterministic row-major tie-break, bounded at COASTAL_ANCHOR_MAX_RING=3) finds a surrogate anchor; the route pays COASTAL_ACCESS_COST_PER_RING per ring — a short, honestly-priced access road, never a free water crossing. IMPASSABLE semantics untouched everywhere else (D-210 transit costs, open ocean). The placement-nudge alternative was rejected: it would move Layer-3 state D-211 promises is seed-derived.Boundary semantics pinned by test: exactly-half-water cells stay passable (strict-majority rule); a settlement with no passable cell within the search ring degrades to an isolated 0-edge node — never a panic, never a fabricated route.
Test plan
Review: road-routing-coastal-fix -> main (type: code)
Reviewers: Hoshe (QA) + Tyre (architecture/governance). Both REQUEST_CHANGES.
Hoshe (QA): REQUEST_CHANGES
length_cellsis a pure HOP COUNT (a grassland step contributes 1 regardless of its 200-unit cost), but the surcharge is computed in cost units thendiv_ceil(MIN_CELL_COST=50)-folded in — yielding 4 hops per ring, not the documented "one extra grassland hop." Worst case (both anchors ring 3) adds +24 length_cells — double WAYPOINT_THRESHOLD_CELLS — spuriously tripping (or elsewhere masking) the add_waypoints gate for physically short edges. Fix: derive the surcharge directly in hop units (or a separate field the waypoint gate doesn't read) and correct the comment's stated rationale.min_edges = 1while the commit message and the test's own module comment claim "GJ251c 0→2" — a regression to exactly 1 edge would pass silently. Tighten to the documented 2.Hoshe's confirmations on record:
nearest_passable_cellgenuinely deterministic (plain Vec, fixed push order, no hash iteration), correctly bounded (ring 0 = self;1..=MAX_RING, no off-by-one) and grid-edge-safe (rows clamp, columns wrap); IMPASSABLE untouched for mid-path transit (main-loop guard diffed against main); the drawn geometry force-anchors both ends at the exact settlement position — no visible road-to-marker disconnect risk for the eyeball; the determinism test compares full structural graph equality (PartialEq over edges/costs/paths/nodes), not counts.Tyre (architecture/governance): REQUEST_CHANGES
!ocean_mask"always land" guarantee lives in features.rs::extract_attractors (D-209, lines 544/570) — not attractor_matching.rs (D-211), which does no ocean filtering. Fix the pointer, and add a word on the D-211 phase-4 synthetic-overflow path (PlainCenter) — verify it also guarantees land, since synthetic attractors are generated positionally rather than extracted.COASTAL_ACCESS_COST_PER_RING = ORTHO * 100re-hardcodes the grassland baseline100(cost-field initializer) as a bare literal — if the baseline changes, the surcharge silently decouples from its own rationale. Extract a shared named constant. (Interacts with Hoshe #1 — resolve together.)Tyre's confirmations on record: the fix-choice adjudication is accurate (D-211's positions genuinely seed-derived; layer analysis right); D-210 else-branch transit semantics byte-identical to main; determinism pure-integer with no cross-platform hazard; believability provably inert to roads (zero road_graph references in believability.rs; the layer runs but no metric reads it); scope containment decisive —
length_cellsis dropped at the Atlas wire boundary (layer_proxy.rs:1796/1800) and maintenance_authority uses straight-line euclid, so the surcharge never reaches the client.Verdict: CHANGES REQUESTED
All five findings dispatched to the authoring agent; fix round → gate → live road-overlay eyeball (GJ251c, GJ380c) → merge.
Fix round — all 5 findings addressed in
de8bcf4ebCOASTAL_ACCESS_SURCHARGE_HOPS_PER_RING = 1, added directly tolength_cellswith no unit conversion (the old cost-unit constant div_ceil'd to 4 hops/ring; worst case was +24 — double the waypoint threshold — now +6). A formula-pinning test asserts both the arithmetic (in isolation via the start==goal short-circuit) and the constant's value, so regression requires a visible deliberate change. Edge counts on both repro bodies verified unchanged (reachability was never affected — the bug only inflated reported length).features.rs::extract_attractors(D-209). The instructed check of the D-211 Phase-4 synthetic-overflow path found a REAL gap:synthetic_attractortakes no terrain argument and never checksocean_mask— a synthetic-overflow settlement can land in open water. Documented in the code comment and the D-210 amendment, not papered over; T-1206 filed (the routing relaxation degrades that case gracefully, but the placement guarantee is Layer 3's gap to fix).pql decisions validateok; sync clean, 0 broken refs.100in the file is the pre-existing cost-vector pre-fill (immediately overwritten), untouched as out of scope.No retractions — all five findings accurate. road_graph suite 25/25; full cargo test 0 failures (1977 lib + all golden harnesses). Gate green on push. Live before/after road-overlay eyeball (GJ251c, GJ380c) in progress — merge follows it.
Pull request closed