D-255 filed (server-determines-content / client map-art function / stepped six-level ladder Global+Region→Chunk / tagged-envelope wire discharging D-225 / three-tier cache with distinct staleness-storage axes / cache-accelerated-pure- function seed-chaining / lakes from settled hydrology, endorheic cue = outflow-course presence). Twelve in-place amendments: D-166 corollary repoint, D-192 persistent-cache boundary, D-225 deferral discharged, D-226 consolidated (ceiling re-scope, select_rung→step-index, stepped transport, item-(d) per-request + retention cap + chunk-floor partial restore, courses gloss + cliff sparse-list), D-227 four-part (TTL-split, version tag, seed-chaining, lakes), D-243 gridunit vocabulary. Clerk-audit fixes: atlas-zoom-ladder-t1143 superseded banner, CLAUDE.md Phase-4 cascade row updated to the stepped model, Q-093 prior-art cross-ref. river-courses-t1170 carrier gloss. governance README index regenerated (109 decisions through D-255); validate clean, sync 1344 refs 0 broken. Ticket chain T-1181–T-1185 + reconciliations in changelog. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
26 KiB
title, description, type, status, round, created
| title | description | type | status | round | created |
|---|---|---|---|---|---|
| River Course Invention — T-1170/T-1168 Design Ruling | Binding design ruling for course invention + riparian vegetation (Tyre, from the three-audit design pass) | design | binding | T-1170 | 2026-07-23 |
Note (2026-07-24, body-map-viewer workshop — D-255): the carrier three-way rule below (Ruling 1c / Ruling 6) survives unchanged in substance. Two terminology/scope updates from D-255: (1) "the windowed payload" is repointed to "the per-step data-canvas payload — formerly the
district_windowfield, now the tagged step-canvas envelope" (D-226 2026-07-23 amendment / D-255 §c). (2) Rule (iii) — rung-indexed invented detail rides the windowed payload regardless of geometric kind — gains a second vector member alongsidecourses:cliffs: Vec<CliffSegment>(carved-gorge geometry: dominantelevation+ per-segmentchannel_depth+cliff_edge), a sparse list zero-length when nothing is carved (T-1177 population survey: zero carved cells across all 267 real bodies), Phase-4 Atlas scope. Governance capture is in the D-226 and D-227 body-map-viewer amendments; this note only glosses the design doc so its "windowed payload" language stays current.
cracks knuckles — I've read both tickets in full, the D-226 amendment block (wave-1 carrier note, two-waterline note, T-1137 queue ruling, windowed-family ceiling), D-227, D-243, and the T-1143 zoom-ladder serving model. The audits are code-true and the tension called out in point 1 is real — I created it, and it resolves cleanly once the carrier rule is split on the right axis. Ruling follows.
TYRE — Binding Design Ruling: T-1170 (river course invention) + T-1168 (riparian vegetation)
Date: 2026-07-23. Status: binding for this batch; implementers code from this directly. Governance capture text in Ruling 6.
The keystone insight, stated once up front: the framework tension between my wave-1 carrier note ("discrete geometry rides whole-body") and my two-waterline note ("invention detail is rung-indexed") dissolves when you split on the correct axis. The wave-1 rule was written for the skeleton — a fixed, finite, rung-independent graph, computed once, valid forever. Course geometry is not skeleton; it is invention — the linear sibling of the coast crinkle, refined per rung by construction. Skeleton rides whole-body; invention rides the window. The rule wasn't wrong, it was under-specified, and this ruling refines it rather than reversing it.
Ruling 1 — Invention locus and wire carrier: server-side, per-window, inside DistrictWindowLayer
1a. Locus: server, per-window, at serve time — Dudley's option (b). Binding. Course geometry is invented inside the window derive (GenWorkItem::DeriveWindow, background queue per T-1137 — queue discipline [HARD], unchanged), at the window's granularity and min_wavelength_m. Dudley's numbers close this: +0.09–0.21 ms against a measured ~5 ms window baseline, under 5% — noise. Whole-body precompute at Quarter detail is rejected on payload grounds (~4.4 MB dense-body for geometry 99% never viewed — categorically the wrong shape under D-227 derive-don't-store). Client-side GDScript invention is rejected on the determinism surface, not CPU: a byte-exact two-language mirror of splitmix64/value_noise/octave tables is a standing D-010/D-227 liability the project has deliberately avoided everywhere else, purchased for a compute saving option (b) proves unnecessary.
1b. Carrier: a new vector field inside the existing windowed payload. The windowed-family ceiling is untouched — and here is why, precisely. The ceiling ([HARD], D-226 T-1124 §2) counts windowed-query fields on AtlasLayerResponse. It exists to prevent a second concurrently-in-flight windowed query needing per-field request correlation. Course geometry is not a second query: it is content of the one windowed payload, keyed by the same (body, center, n, granularity) echo, arriving in the same response, stale-discardable by the same rule. DistrictWindowLayer gains courses: Vec<RiverCourse> (#[serde(default)]), exactly as it holds six dense arrays today. No ceiling impact, no tagged-envelope migration, no new request class.
1c. The carrier rule, refined (this is the governance-grade restatement — capture text in Ruling 6):
Three-way, replacing the wave-1 two-way rule: (i) rung-independent discrete features — skeletons, graphs, point markers, computed once and valid forever — ride the whole-body overlay family, filtered per-rung client-side. (ii) Continuous per-metre fields ride the windowed per-cell arrays. (iii) Rung-indexed invented detail rides the windowed payload regardless of geometric kind — raster or vector — because rung is a request parameter, and only the windowed query carries one. The coast crinkle has always followed (iii) implicitly (it arrives baked into windowed cell verdicts); course polylines are its vector sibling, arriving alongside them.
1d. The two-waterline problem dissolves under this carrier. A whole-body course would need a rung-parametrized terminus (the fork the audit flagged as sharpest). A windowed course does not: the server invents the course at a known rung, in the same pass that computes that rung's per-cell water verdicts — so the terminus is resolved against the drawn coast at that rung, server-side, consistently. Nothing whole-body ever carries a terminus. The skeleton stays rung-independent, as the two-waterline note requires.
1e. Window-independence invariant (binding, tested). The geometry is a pure function of (seed, body, edge, rung) — never of the window rect. Stations are generated at deterministic global arc-length positions along the edge; the window crops, it never re-parametrizes. Two overlapping windows at the same granularity must produce byte-identical points for the shared stretch. This is the course analog of the coast warp's absolute-world-metre keying and it is a mandatory determinism test (see Discipline).
Ruling 2 — Adjacency: persisted downstream pointer. Reconstruction rejected.
2a. RiverNetwork gains river_downstream: Vec<u8> — additive, #[serde(default)], parallel to river_cells (the exact river_class precedent). Captured in extract_river_network (drainage.rs:247-349) where fdir[i] is already in scope and currently discarded after its boolean use. One .map(), zero new grid passes, ~1 byte/river cell. This is the opening move of the batch — everything else consumes it.
2b. Reconstruction is rejected on the Si audit's confluence finding: adjacency alone cannot distinguish inflow from outflow at a 3-river-neighbor confluence, and re-deriving direction from elevation is re-running D8 badly. We had the true answer in hand and threw it away; stop throwing it away. The D-203 memory-frugality rationale for discarding covered the 131 KB full grid, not the river-cell projection.
2c. Sentinel vocabulary (values in the u8 space above 7): MOUTH (flow reaches raw-sea) · EDGE_DRAIN (flow exits the grid's top/bottom edge — a grid artifact, not a mouth, per Ruling 3f) · TERMINAL — reserved now, unused in round 1 — flow ends in an interior sink (future endorheic basin / inland delta, see Ruling 7b). Reserving the value costs one enum arm and keeps the future option additive instead of a wire migration.
2d. Each edge is uniquely identified by its upstream cell (every river cell has exactly one downstream pointer), so edge_id = pack(u16,u16) → u32. This is the seeding key (Ruling 3a).
Ruling 3 — Course algorithm
3a. Seeding (D-227/D-010 discipline). SeedChain::for_body(...).derive(SeedDomain::RiverCourse, edge_id as u64), new SeedDomain variant, with a distinct RIVER_COURSE_WARP_SALT on the noise stream (the COAST_WARP_SALT pattern verbatim) — never correlated with coast warp, terrain scatter, or vegetation massif fields at the same position. Pure (seed, body, edge, rung).
3b. Two-stage shape — and the stage split is load-bearing for cross-rung stability:
- Stage A — coarse valley-seeking control path. Rung-INDEPENDENT. Between the two anchor points (upstream/downstream cell centres — skeleton truth, never moved), place control stations at chord/8 (~9.6 km). At each, evaluate k=5 candidate perpendicular offsets within the amplitude envelope; score = bilinear
ta.elev_pctat the candidate (plus a small continuity penalty against the previous chosen offset to prevent zigzag); pick minimum. The elevation proxy is the bilinearTerrainAnalysisread — the same tradeoff the coast warp already made atdistrict_profile.rs:1152-1157— NOTderive_at_metresper candidate. Dudley's numbers make this affordable (+µs/segment); the Si audit's unmeasured-derive-cost gap is thereby not load-bearing for this design (we still close the measurement gap — see Discipline). Stage A is computed identically at every rung, so the coarse course never moves as you refine. - Stage B — fine warp octaves. Rung-INDEXED. Perpendicular scalar displacement of intermediate stations via salted multi-octave value noise keyed on global arc-length, octave band from ~chord/2 (~38 km) down to the window's
min_wavelength_mhard-truncate (thewarp_fbmcutoff idiom, T-1162 rung discipline, reused exactly). Station spacing = the rung's sample spacing (2,048 m District / 512 m Quarter — Dudley's ~37/~150 points per segment), at global arc-length multiples so windows agree (Ruling 1e).
Cross-rung invariant that falls out: the Quarter course is the District course plus octaves in the (1,024 m..4,096 m) band — displacement between rungs is bounded by the truncated-octave amplitude sum, sub-cell at District spacing. And at Region spacing no octaves survive at all, so the rung-truncated course degenerates to the straight chord — which means the client's Region-rung skeleton-chord drawing (Ruling 5a) IS the course at that rung, not an approximation. That's the kind of unification I get excited about: one function, every rung, no special cases.
3c. Amplitude envelope. Sine-shaped taper to zero at both endpoints — this is what makes confluences work for free: every edge into and out of a cell meets exactly at the cell-centre anchor, C0-continuous, and the confluence marker draws at the anchor. Peak amplitude ≤ ~8% of chord (~6 km), scaled down by local ta.slope_deg (steep terrain → straighter) and up modestly by river_class (trunks meander wider). All tunables; taper-to-zero and the ≤ half-cell hard cap are binding.
3d. Valley preference is IN for round 1 (costed at noise level by Dudley), via Stage A only. This is the round-1 answer to the wave-1 "rivers may cross invented hills" gap: courses prefer invented-terrain valleys at coarse wavelengths; residual fine-octave conflicts (a course crossing a voxel_relief hillock) are accepted and documented. The converse mechanism — terrain invention becoming course-aware (valley carving along courses) — is explicitly deferred; it belongs at the block/tile rungs and Phase 5 fill, noted in governance as the future direction, not built now.
3e. Termination at the invented coast (the T-1172 retirement mechanism). For an edge whose downstream sentinel is MOUTH: walk stations upstream→downstream, sampling the same rung-consistent morphology water verdict the window's own cells use (the open_water/morphology path, at the window's min_wavelength_m — not raw ocean_frac, so the terminus agrees with what is drawn). First water station → bisect against the previous land station (fixed 6 iterations) → terminus point, flagged Mouth on the wire. If the final anchor still samples land at this rung (drawn coast receded past the raw-sea cell — the inland-mouth oddity, fixed by construction here), extend along the D8 direction up to one cell length probing; if still no water, terminate at the anchor with no mouth flag (degenerate, rare, bounded). A few dozen probes per mouth edge, on the background queue — within the T-1137 discipline by construction.
3f. Pole-edge drains are not mouths. Binding. EDGE_DRAIN termini get no mouth flag and no double-ring; the course ends at the last in-grid station. Server-side, extract_river_network stops classifying grid-edge exits into mouths (deliberate Layer-1 golden re-pin, see Discipline). They are grid artifacts, exactly as Jeroen's capture question suspected.
3g. T-1172 clip: restructured, not blanket-deleted. The three marker sites in atlas_window_nature_overlay.gd (lines 288/311/347) retire for the course-drawing rungs (District/Quarter) — courses carry real rung-consistent termini, the clip's job is done there, and suppressed offshore mouths return as real geometry. The Region-rung skeleton path keeps a clip: Region still draws whole-body skeleton against a rung-dependent drawn coast, which is precisely the presentation-frame reconciliation the two-waterline note prescribes. Rewrite the marker comments: the surviving clip is documented as permanent-until-Region-goes-windowed (T-1143 ruling 2's progressive tiling), at which point Region inherits windowed courses and the last clip retires.
3h. Wire shape. RiverCourse { edge_id: u32, class: u8, points: Vec<(i32,i32)> /* world-metres */, terminus: CourseTerminus /* None | Mouth | EdgeDrain | ContinuesBeyondWindow */ }. Only edges whose chord-inflated-by-max-amplitude bounding box intersects the window ship; points cropped to window + one station beyond each edge of it. ~1–2 KB typical per window. Well inside every budget.
Ruling 4 — T-1168: shape and sequencing
4a. The mechanism: a scale-free point-sample distance test. This dissolves the blotch problem rather than mitigating it. near_perennial_water(sample_pos) = distance(sample_pos, nearest invented course polyline) ≤ band_m, where band_m defaults to D-239 §8's governed 1–3 tiles (class-scaled: thicket band for trunks, scrub band for streams — tunable constants, governed default). Because the test is a pure point predicate against real course geometry, it is automatically correct at every sampling density: at 512 m Quarter spacing it essentially never fires (the band is sub-cell — honest, no over-fattening, the exact Lendel-failure discipline), and at 1 m tile spacing it fires on exactly the 1–3 tile bank strip. No per-rung riparian policy exists or is needed. The audit's skeleton-disc model — any "within N km of a 76 km-spaced skeleton point" test — is rejected outright: it is off by 3–4 orders of magnitude from the governed band and cannot be tuned into anything but green blotches.
4b. Consequently the 512×256 distance-field-over-grid proposal is also rejected — a grid quantized at 76 km cannot express a metres-scale band. The test runs against course polylines resident in the derive context: in the window path, T-1170's already-invented courses (coarse bounding-box cull, then point-to-segment distance — most cells cull to zero edges); in the batch path, courses for edges near the district, invented on demand via the same pure function (cachable per derive batch). The Si audit's observation that gen_queue.rs:626 discards the Layer1Output still gets fixed — the window path needs RiverNetwork (cells + downstream pointers) resident to know which edges exist; retain it in TerrainAnalysisCache instead of re-deriving-and-discarding.
4c. Hard sequencing: T-1168's riparian test lands AFTER T-1170's course inventor, full stop. The test is meaningless without course geometry (4a). The threading scaffolding is exempt and proceeds in parallel — it is mechanical and fully mapped by the audit: build_district_profile gains the riparian signal parameter consumed at district_profile.rs:1469; threaded via derive_all_districts → derive_district_profile (batch, sourced from cascade.rs's already-unpacked river_network, the road_graph precedent) and build_district_window_layer → derive_window_cell → derive_at_metres/derive_orbital_at_metres (window, sourced from the retained Layer1Output). Until the course inventor lands, the provider returns "no course in range" — wired but inert, zero behavioral change, zero golden churn.
4d. T-1162 composition contract, re-affirmed as binding: near_perennial_water is a separate boolean/geometry signal into derive_vegetation; it never touches moisture_q, and moisture_perturb_q never reads river data. The existing parameter separation already enforces this — the implementer's only job is not to break it. Climate gating stands: extreme-cold Barren beats riparian (ice is geology per D-227); Marine/airless precedence unchanged.
4e. Experience honesty (what Jeroen will see): after this batch, District/Quarter windows show continuous meandering rivers with real coast mouths. They will not show visible green riparian corridors — under the governed 1–3 tile band that is sub-cell at every Atlas rung, and honestly so. T-1168's visible payoff arrives at the block/tile rungs (opened by T-1143 ruling 1) and Phase 5 ground truth. If Atlas-visible green corridors are wanted, that is a design widening of D-239 §8 — flagged to Jeroen in Ruling 7a, one constant away, not an architecture change.
Ruling 5 — Per-rung presentation surface
5a. Region and coarser (skeleton path, whole-body layer1): the client upgrades dots to connected straight chords via river_downstream — which per Ruling 3b is the rung-truncated course, so this is not an approximation, it is the course at Region truncation. Clip retained (Ruling 3g). Confluence/mouth markers from the skeleton lists (mouths now excluding pole drains).
5b. District and Quarter (course path, windowed): polylines from DistrictWindowLayer.courses via the existing _pos()/draw_polyline plumbing (_draw_basins precedent — no new transform code). Mouth markers at Mouth termini. No clip. Quarter rivers return — the streams class draws at Quarter, executing exactly the pre-announced fade-down revisit from the wave-1 visibility note.
5c. The revisit point is preserved and split: RIVER_CLASS_VISIBLE_BY_RUNG is replaced by two tables in atlas_window_geometry.gd — SKELETON_CLASS_VISIBLE_BY_RUNG (Region+, path 5a) and COURSE_CLASS_VISIBLE_BY_RUNG (District/Quarter, path 5b), with per-class width/opacity companion tables. This is where Araminta's forthcoming presentation ruling plugs in — implementers land functional defaults (trunk widest, streams thinnest, class-filtered per rung: District trunk+tributary, Quarter all three), and Araminta's ruling edits those tables and only those tables. Same single-revisit-point discipline as wave 1.
Ruling 6 — Governance captures (exact text)
Append to the D-226 amendment block (governance/decisions/architecture.md), dated 2026-07-23:
Course-invention carrier note (T-1170, 2026-07-23 — Tyre): river course geometry below D8 resolution is invention, not skeleton, and rides the windowed payload as a vector field inside
DistrictWindowLayer(courses, additive) — invented server-side per window on the background queue (T-1137 discipline) at the window's rung, terminated server-side against the same rung's morphology water verdict the window's cells carry. This does not count against the windowed-family ceiling (§2 [HARD]): the ceiling counts windowed query fields onAtlasLayerResponse; courses are content of the single existing windowed payload, same echo key, same staleness semantics. The wave-1 carrier rule is hereby refined three-way: (i) rung-independent discrete features (skeletons, graphs, markers — computed once, valid forever) ride the whole-body family, filtered per-rung client-side; (ii) continuous per-metre fields ride the windowed per-cell arrays; (iii) rung-indexed invented detail rides the windowed payload regardless of geometric kind, because rung is a request parameter and only the windowed query carries one — the coast crinkle has always implicitly been (iii); courses are its vector sibling. The two-waterline note's reconciliation resolves per-rung server-side for courses (the terminus is windowed content at a known rung); the Region-rung skeleton path retains the presentation-frame clip until Region itself goes windowed (T-1143 ruling 2), which retires the last clip site. The skeleton itself gainsriver_downstream(additive per-river-cell D8 pointer withMOUTH/EDGE_DRAIN/reserved-TERMINALsentinels) onRiverNetwork— whole-body, rung-independent, per rule (i). Pole-edge drains are grid artifacts, not mouths — excluded frommouthsat extraction.
Append to D-227's amendment trail:
Amended 2026-07-23 (T-1170 — river courses join the invention family): the "invented deterministically" clause now covers linear features: river courses between D8 cells are pure
(seed, body, edge, rung)functions — a rung-independent valley-seeking coarse path (bilinearTerrainAnalysisproxy, never full re-derivation) plus rung-indexed perpendicular warp octaves under themin_wavelength_mtruncation discipline, distinct salted stream, amplitude tapered to zero at cell-centre anchors (confluence continuity), stations at global arc-length positions (window-independent). Round-1 relief reconciliation is course-follows-terrain (valley preference); terrain-carves-for-course is the deferred converse, targeted at block/tile rungs.
Also: fix the stale scale.rs:107 grid-shape comment (one line, audit nit) in whichever PR touches that file first.
Ruling 7 — Jeroen items
7a. Riparian visibility at Atlas rungs (genuine design call). Under D-239 §8's governed 1–3 tile band, riparian vegetation is honestly invisible at every Atlas rung (Ruling 4e) — the drawn river itself is the only visible river response at District/Quarter. If you want the Nile effect — a visible green corridor at Atlas scale — that is a design widening of the band (e.g. floodplain-riparian corridors of hundreds of metres on alluvial-plain morphology, class- and morphology-scaled). The mechanism ships scale-free, so this is one governed constant/function away, zero architecture change. Your call, not blocking this batch.
7b. Endorheic basins (one paragraph, as asked). This design does not foreclose deliberate endorheic basins or inland deltas — it deliberately cheapens the future path. The TERMINAL downstream sentinel is reserved now (Ruling 2c), so an interior sink becomes an additive drainage-extraction change, not a wire migration; and the termination mechanism (walk stations to the first rung-consistent water verdict — which is the morphology verdict, covering lakes, not just ocean) generalizes unchanged to a terminal lake shoreline. When you want endorheic basins, the work is in D8 sink retention and lake morphology, and every piece this batch builds — pointers, courses, termination, riparian — consumes them without modification. Nothing to design today.
Discipline — benches, goldens, determinism tests
- Run the dormant bench first.
zoom_ladder_bench.rs--release --ignored, before the course inventor merges; record the numbers indocs/architecture/atlas-zoom-ladder-t1143.md(which itself flags them UNMEASURED). Cheap, closes a documented gap this batch would otherwise inherit blind. Not load-bearing for the design (Ruling 3b avoided depending on it) but the gap closes now. - Course-cost bench: window derive with courses on/off; assert the delta stays under ~5% of the window baseline (Dudley's envelope).
- Determinism tests (mandatory, new): (a) overlapping-windows agreement — two windows sharing an edge produce byte-identical course stations in the overlap (Ruling 1e); (b) cross-rung stability — Quarter course points within the truncated-octave amplitude bound of the District polyline (Ruling 3b); (c) salt isolation — course stream uncorrelated with coast warp at shared positions (the existing isolation-test pattern).
- Goldens, deliberate re-pin discipline (
UPDATE_GOLDEN=1+ rationale comment, the T-1162 precedent):cascade_goldenre-pins (mouths list loses pole drains;river_downstreamadded).window_derivation_golden: first verify empirically whether the 128×64 fixture produces river cells near the sweep positions (audit: unconfirmed); add a course-bearing sweep position either way so courses are actually pinned.believability: expected unchanged (the point test cannot fire at district spacing) — verify, don't assume; an unexpected re-pin there is a bug signal, not a regen chore. - Full
cargo testbefore push (the golden harnesses are separate test binaries;--libmisses them), and the live-screenshot pixel-diff eyeball check on the merged result, cold-launched — this batch is rendered-path.
Work split and sequencing
Dudley — server (owns the cost model he probed):
- A1 (opening move, unblocks everything):
river_downstream+ sentinels + pole-drain mouth exclusion + Layer-1 golden re-pin. - A2: course inventor (Ruling 3a–3d, 3h) in the window derive +
Layer1Outputretention inTerrainAnalysisCache+ wire field. - A3: termination + mouth flags (3e–3f) — with A2.
- A5 (after A2): T-1168 riparian point test wired into the threaded signal, batch + window paths.
Stig — client + mechanical threading:
- B1 (parallel with A2): T-1168 threading scaffolding (Ruling 4c), inert provider, zero behavior change.
- B2 (needs A1 only): Region skeleton-chord drawing.
- B3 (needs A2/A3): course polyline drawing, mouth markers, clip restructure (3g), visibility-table split (5c) with functional defaults for Araminta.
Hard edges: A1 → everything. A2 → {A3, A5, B3}. B1 ∥ A2, converging at A5. Nothing else serializes.
Difficulty tier, honestly: challenging but doable — and the architecture is on our side. Every primitive exists (value_noise, splitmix64, the cutoff idiom, the queue, the polyline draw path); this batch composes them, it doesn't invent machinery. The one place I'd have called "extremely difficult" — reconciling a whole-body course with a rung-indexed coastline — stopped being a problem the moment courses went windowed. That's the ruling doing the work.
— Tyre