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>