feat(simulation): T-1170 A2/A3 + T-1168 A5 — course inventor, coast termination, riparian signal

A2 (river_course.rs): Stage A rung-independent valley-seeking control
path (chord/8 stations, k=5 bilinear-scored candidates + continuity
penalty); Stage B rung-indexed perpendicular warp on GLOBAL arc-length
(window-independence, Ruling 1e), band chord/2 down to min_wavelength_m
hard-truncate, sine taper to zero at anchors, amplitude min(8% chord,
half-cell) slope/class-scaled. SeedDomain::RiverCourse=17, distinct
salt. Wire: RiverCourse{edge_id,class,points,terminus} on
DistrictWindowLayer.courses (serde-default); bbox-culled, window-
cropped +1 station. TerrainAnalysisCache retains Layer1Output (the
gen_queue:626 discard, Ruling 4b). A3: mouth termination walks
stations sampling the window's OWN rung-consistent morphology verdict,
6-iteration bisect; land-at-anchor probes one segment then None;
EdgeDrain never probes. A5: near_perennial_water point-to-segment
predicate (D-239 §8 governed bands 1-3m class-scaled) threaded through
both batch and window paths; Region always false; never touches
moisture_q. Discipline closed: dormant zoom-ladder bench run + numbers
recorded in the design doc (District 3.009/1.785, Quarter 1.823
us/cell, Region window 0.617ms); course-cost bench CAUGHT a real
+12-36% per-cell riparian scan regression -> precomputed bbox O(1)
reject (60ns->2.2ns/call), final delta +3.4-6.9% at budget; three
determinism tests (overlapping-window byte-identity, cross-rung
amplitude bound, warp-stream cross-correlation r<0.3); goldens: window
sweep gained a verified course-bearing position (pure append), new
river_course golden at both rungs, believability verified unchanged.
Revert-verification discovered the pole-row branch is structurally
unreachable (flow_direction bounds-check) — the real edge-drain path
is k<0 flat-plateau; test fixture rewritten to exercise reality.
scale.rs stale comment fixed. Full cargo test green.

Tickets: T-1170, T-1168

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-23 13:36:16 +02:00
co-authored by Claude Fable 5
parent c31cc6220e
commit 4320df9b60
16 changed files with 4353 additions and 78 deletions
+6
View File
@@ -305,6 +305,11 @@ pub fn run_cascade_from_heightmap(
// thalweg direction into each DistrictProfile.basin_direction
// (T-1047). Pass the map through derive_all_districts.
let basin_dirs = snapshot.layer1.as_ref().map(|l1| &l1.district_basin_dirs);
// T-1168 Ruling 4c: same `snapshot.layer1` source as
// `basin_dirs`/`river_cells` (the `road_graph` precedent
// below) — the river network for the batch-path riparian
// signal.
let river_network = snapshot.layer1.as_ref().map(|l1| &l1.river_network);
let districts = district_profile::derive_all_districts(
body_seed,
params,
@@ -312,6 +317,7 @@ pub fn run_cascade_from_heightmap(
scale::HEIGHTMAP_CELLS_PER_DISTRICT,
&snapshot.body_id,
basin_dirs,
river_network,
);
snapshot.layer_district = Some(LayerDistrictOutput { districts });
}