fix(simulation): PR #194 review round — rung-floor dependency direction, golden body coverage, doc honesty
Tyre's I1 (his ruling: the cutoff's job is Nyquist, a property of the RUNG): MIN_WL_BANDS_M's District band now derives from 2*DISTRICT_M directly, decoupled from OCTAVE_WAVELENGTHS_M[3] — a detail_scatter retune can no longer silently redefine the Atlas rung floor. Direction- agnostic const assert pins the coincidence so drift on either side breaks the build for a deliberate human decision; golden_cutoffs_match_ the_scale_ladder now pins the District coupling too. I2: D-226 paraphrase replaced with cites to the T-1150 wire-contract note + T-1162 refinement resolution (2), plus a self-found stale 2048m claim fixed in the same comments. I4: golden extended with airless/dry (ceiling_q==0 short-circuit) and volcanic-coast (ridged warp) body rows via body_sweep_samples() — fixture regen verified 510 insertions, 0 deletions (existing rows byte-identical, purely appended). Q2 nit: vegetation_invention module doc now states majority-preservation as the coherence guarantee, not per-cell class stability (a boundary cell's flip IS the clearing mechanism). Forward-contract for T-1156: 0x5EED_C0DE promoted to named WINDOW_RELIEF_SALT const. 158 focused tests green; cargo check --tests clean. Tickets: T-1162, T-1161 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -64,13 +64,14 @@ const CHARACTER_FIELD_SALT: u64 = 0x0C0A_57C4_A24C_7E12;
|
||||
/// density, not detail). A Quarter-rung request (`min_wavelength_m` cutoff
|
||||
/// quantized to 1,024 m, see `layer_proxy::MIN_WL_BANDS_M`) admits every
|
||||
/// octave down to this floor; a District-rung request (cutoff quantized to
|
||||
/// District's OWN real band, 4,096 m — District's Nyquist limit, matching
|
||||
/// `terrain_detail`'s pre-existing finest octave) truncates the two finest
|
||||
/// additions (2,048/1,024 m — genuinely below District's floor) while
|
||||
/// legitimately ADMITTING the other two (8,192/4,096 m — new content that IS
|
||||
/// coarse enough for District to resolve, not a leak). Either way Quarter
|
||||
/// still sees strictly more than District at the SAME position (the two
|
||||
/// finest additions are Quarter-exclusive). The
|
||||
/// District's OWN real band, `2 × DISTRICT_M = 4,096` m — District's own
|
||||
/// Nyquist limit, derived independently from the rung's spacing per PR #194
|
||||
/// I1, NOT from any invention field's octave array) truncates the two
|
||||
/// finest additions (2,048/1,024 m — genuinely below District's floor)
|
||||
/// while legitimately ADMITTING the other two (8,192/4,096 m — new content
|
||||
/// that IS coarse enough for District to resolve, not a leak). Either way
|
||||
/// Quarter still sees strictly more than District at the SAME position (the
|
||||
/// two finest additions are Quarter-exclusive). The
|
||||
/// `enveloped_fbm`-style hard-truncate cutoff discipline is honored via
|
||||
/// [`warp_fbm`]'s own `min_wavelength_m` parameter — `0.0` (no cutoff) is
|
||||
/// byte-identical to every pre-T-1162 caller.
|
||||
|
||||
@@ -1058,6 +1058,16 @@ pub fn derive_moisture_q(
|
||||
// T-1125 — invented primitives (shared by both derivation paths)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/// Distinct hash-path salt for the T-1162 sub-district relief stream (part
|
||||
/// b) — keeps `voxel_relief`'s noise uncorrelated with the district-band
|
||||
/// `terrain_detail` scatter sampled at the same position. Promoted to a
|
||||
/// named const (Tyre, PR #194 forward-contract for T-1156) matching
|
||||
/// `vegetation_invention::VEGETATION_MASSIF_SALT`/`VEGETATION_TEXTURE_SALT`'s
|
||||
/// named-and-greppable convention, ahead of T-1156 adding a fourth
|
||||
/// isolated stream (rivers) — a fourth inline hex literal here would have
|
||||
/// made the pattern harder to audit at a glance.
|
||||
const WINDOW_RELIEF_SALT: u64 = 0x5EED_C0DE;
|
||||
|
||||
/// The invented `(slope_q, elev_q, ocean_fraction_q)` triple (T-1125, D-227).
|
||||
struct InventedPrimitives {
|
||||
slope_q: i32,
|
||||
@@ -1165,22 +1175,25 @@ fn invent_primitives(
|
||||
// envelope/ruggedness inputs as the district-band `scatter` above (one
|
||||
// amplitude ceiling, two wavelength bands composing additively — never a
|
||||
// second independently-tuned amplitude rule) and the SAME
|
||||
// `min_wavelength_m` cutoff. At District's cutoff (≥2,048 m) every
|
||||
// VOXEL_OCTAVE_WAVELENGTHS_M entry (all ≤1,024 m) is truncated, so
|
||||
// `relief` is always exactly 0.0 there — District's output is unchanged
|
||||
// byte-for-byte. At Quarter's cutoff (1,024 m) only the two coarsest
|
||||
// voxel-band entries (1,024, 512) survive; the two finest (256, 128) stay
|
||||
// truncated even at Quarter (below Quarter's own 512 m spacing's Nyquist
|
||||
// floor of 1,024 m) — this is correct and expected (D-226(d) note): a
|
||||
// contributing wavelength is never capped BY the request-granularity
|
||||
// floor ruling itself (the coast warp already crosses scales the other
|
||||
// way), it is simply that only 2 of the 4 voxel octaves are coarse enough
|
||||
// to matter at Quarter's own sample density; the other two are reserved
|
||||
// for a future finer-than-Quarter rung. Distinct seed salt (`^ 0x5EED_C0DE`)
|
||||
// keeps this stream uncorrelated with `scatter`'s stream at the same
|
||||
// position (same isolation discipline as `coast_invention`'s warp salt).
|
||||
// `min_wavelength_m` cutoff. At District's real Nyquist floor (4,096 m,
|
||||
// `layer_proxy::MIN_WL_BANDS_M`) every VOXEL_OCTAVE_WAVELENGTHS_M entry
|
||||
// (all ≤1,024 m) is truncated, so `relief` is always exactly 0.0 there —
|
||||
// District's output is unchanged byte-for-byte. At Quarter's cutoff
|
||||
// (1,024 m) only the two coarsest voxel-band entries (1,024, 512)
|
||||
// survive; the two finest (256, 128) stay truncated even at Quarter
|
||||
// (below Quarter's own 512 m spacing's Nyquist floor of 1,024 m) — this
|
||||
// is correct and expected per the D-226 T-1150 wire-contract note and
|
||||
// T-1162 refinement resolution (2): a contributing wavelength is never
|
||||
// capped by the rung's sample-density floor alone (the coast warp
|
||||
// already crosses scales the other way), it is simply that only 2 of
|
||||
// the 4 voxel octaves are coarse enough to matter at Quarter's own
|
||||
// sample density; the other two are reserved for a future
|
||||
// finer-than-Quarter rung. Distinct seed salt
|
||||
// ([`WINDOW_RELIEF_SALT`]) keeps this stream uncorrelated with
|
||||
// `scatter`'s stream at the same position (same isolation discipline as
|
||||
// `coast_invention`'s warp salt).
|
||||
let relief = crate::atlas::detail_scatter::voxel_relief(
|
||||
seed.seed() ^ 0x5EED_C0DE,
|
||||
seed.seed() ^ WINDOW_RELIEF_SALT,
|
||||
world_x_m,
|
||||
world_y_m,
|
||||
env_amp,
|
||||
|
||||
@@ -405,17 +405,27 @@ fn clamp_window_n_v2(raw_n: u32, granularity: WindowGranularity) -> u32 {
|
||||
}
|
||||
|
||||
/// Quantized `window_min_wl_m` bands (T-1150, zoom ladder design doc §5;
|
||||
/// retuned T-1162 part (c)): `0` (no cutoff) plus every entry of
|
||||
/// [`crate::atlas::detail_scatter::OCTAVE_WAVELENGTHS_M`] (32,768/16,384/
|
||||
/// 8,192/4,096 m — District's own Nyquist floor, `2 × DISTRICT_M`), plus a
|
||||
/// FIFTH band at `1,024` m — Quarter's own Nyquist floor (`2 × QUARTER_M =
|
||||
/// 1,024`, matching a rung's content wavelength to what its `512` m sample
|
||||
/// spacing can actually resolve — nothing finer than the rung can express,
|
||||
/// nothing coarser than it deserves). `1,024` m is also the finest entry of
|
||||
/// the extended [`crate::atlas::coast_invention::WARP_OCTAVE_WAVELENGTHS_M`]
|
||||
/// band (T-1162 part a) and the coarsest entry of
|
||||
/// [`crate::atlas::detail_scatter::VOXEL_OCTAVE_WAVELENGTHS_M`] the sub-district
|
||||
/// relief wiring (T-1162 part b) admits at Quarter — one band serves both.
|
||||
/// retuned T-1162 part (c); band 4 re-derived per Tyre's PR #194 review I1).
|
||||
/// `0` (no cutoff) plus the two coarse legacy bands
|
||||
/// [`crate::atlas::detail_scatter::OCTAVE_WAVELENGTHS_M`]`[0..2]` (32,768/
|
||||
/// 16,384/8,192 m — carried over unchanged, no rung claims these as its own
|
||||
/// Nyquist floor), plus **District's own Nyquist floor** computed directly
|
||||
/// from the rung's spacing (`2 × DISTRICT_M = 4,096` m), plus **Quarter's own
|
||||
/// Nyquist floor** (`2 × QUARTER_M = 1,024` m).
|
||||
///
|
||||
/// **Dependency direction (Tyre, PR #194 I1):** the cutoff's semantic job is
|
||||
/// Nyquist truncation — a property of the RUNG (its sample spacing), never of
|
||||
/// any one invention field's octave choices. Band 4 is therefore derived from
|
||||
/// `scale::DISTRICT_M` directly, NOT from
|
||||
/// `detail_scatter::OCTAVE_WAVELENGTHS_M[3]` (the old T-1162 wiring) — that
|
||||
/// coupling ran backwards: a future `detail_scatter` retune could silently
|
||||
/// redefine the Atlas rung floor, and the coast warp already extends its OWN
|
||||
/// octaves below `OCTAVE_WAVELENGTHS_M`'s range (T-1162 part a), proving no
|
||||
/// single invention field's array is entitled to dictate the floor. The two
|
||||
/// values happen to coincide today (4,096 = `2 × DISTRICT_M` = also
|
||||
/// `OCTAVE_WAVELENGTHS_M[3]`) — the `const _: () = assert!(...)` immediately
|
||||
/// below pins that coincidence so a future drift on EITHER side breaks the
|
||||
/// build loudly instead of silently decoupling the two meanings.
|
||||
///
|
||||
/// **Pre-T-1162 bands unchanged in VALUE** (32,768/16,384/8,192/4,096 stay
|
||||
/// exactly where they were) — but **NOT unchanged in behavior at 8,192/4,096
|
||||
@@ -442,10 +452,25 @@ const MIN_WL_BANDS_M: [f64; 6] = [
|
||||
crate::atlas::detail_scatter::OCTAVE_WAVELENGTHS_M[0],
|
||||
crate::atlas::detail_scatter::OCTAVE_WAVELENGTHS_M[1],
|
||||
crate::atlas::detail_scatter::OCTAVE_WAVELENGTHS_M[2],
|
||||
crate::atlas::detail_scatter::OCTAVE_WAVELENGTHS_M[3],
|
||||
1_024.0,
|
||||
2.0 * DISTRICT_M as f64,
|
||||
2.0 * crate::atlas::scale::QUARTER_M as f64,
|
||||
];
|
||||
|
||||
/// Direction-agnostic guard (Tyre, PR #194 I1): `MIN_WL_BANDS_M`'s District
|
||||
/// band is now derived from `2 × DISTRICT_M`, deliberately decoupled from
|
||||
/// `detail_scatter::OCTAVE_WAVELENGTHS_M[3]` (see the doc above). The two
|
||||
/// values are expected to keep coinciding — `terrain_detail`'s finest octave
|
||||
/// IS meant to sit at District's Nyquist floor — but nothing in the type
|
||||
/// system enforces that anymore now that the dependency runs one direction
|
||||
/// only. This assert exists so that if either side ever drifts (a
|
||||
/// `detail_scatter` octave retune, or a `DISTRICT_M` scale-ladder change).
|
||||
/// the build breaks loudly and a human decides deliberately whether the
|
||||
/// coincidence should be restored or the two meanings were meant to diverge
|
||||
/// — never a silent redefinition of the Atlas rung floor.
|
||||
const _: () = assert!(
|
||||
crate::atlas::detail_scatter::OCTAVE_WAVELENGTHS_M[3] as i64 == 2 * DISTRICT_M as i64
|
||||
);
|
||||
|
||||
/// Snap a wire-supplied `window_min_wl_m` to the nearest fixed band in
|
||||
/// [`MIN_WL_BANDS_M`] (T-1150, design doc §5's gap-fix): "as specified,
|
||||
/// `window_min_wl_m` is viewport-continuous while the cache key/echo tuple is
|
||||
|
||||
@@ -49,22 +49,35 @@
|
||||
//!
|
||||
//! ## Cross-rung coherence (the ticket's hard requirement)
|
||||
//!
|
||||
//! A forest at Region scale MUST still read as forest-majority when sampled
|
||||
//! at Quarter — the finer rungs REFINE the boundary and punch clearings, they
|
||||
//! never contradict the coarse verdict wholesale. This is achieved the SAME
|
||||
//! way `coast_invention`'s warp achieves cross-rung coherence: a SINGLE fBm
|
||||
//! sum whose octave terms span coarse-to-fine wavelengths, sampled at
|
||||
//! whatever position/cutoff a rung asks for — not two independently-seeded
|
||||
//! fields for "coarse" and "fine" that could disagree. The coarse octaves
|
||||
//! (massif-scale, ≈100–400 km, always present regardless of cutoff — same
|
||||
//! posture as `coast_invention::character_field`, which is NEVER
|
||||
//! cutoff-gated) set the DC bias (which side of "possible forest" a broad
|
||||
//! area sits on); the fine octaves (district/quarter-scale, cutoff-gated
|
||||
//! exactly like `terrain_detail`/`voxel_relief`) add zero-mean texture on top
|
||||
//! that punches clearings and copses WITHOUT being able to flip the coarse
|
||||
//! bias's sign at typical amplitudes (the fine-octave contribution is capped
|
||||
//! well inside the coarse term's own swing — see [`moisture_perturb_q`]'s
|
||||
//! amplitude split).
|
||||
//! A forest at Region scale MUST still read as forest-**majority** when
|
||||
//! sampled at Quarter — the finer rungs REFINE the boundary and punch
|
||||
//! clearings, they never contradict the coarse verdict wholesale. **This is
|
||||
//! a majority-preservation guarantee, not a per-cell class-stability
|
||||
//! guarantee** — punching an individual clearing or copse INTO a forest
|
||||
//! massif is the fine tier doing its job, not a violation of coherence; the
|
||||
//! two are compatible because the guarantee is about the aggregate reading
|
||||
//! over a patch, not about any single cell's class surviving refinement
|
||||
//! unchanged. This is achieved the SAME way `coast_invention`'s warp
|
||||
//! achieves cross-rung coherence: a SINGLE fBm sum whose octave terms span
|
||||
//! coarse-to-fine wavelengths, sampled at whatever position/cutoff a rung
|
||||
//! asks for — not two independently-seeded fields for "coarse" and "fine"
|
||||
//! that could disagree. The coarse octaves (massif-scale, ≈100–400 km,
|
||||
//! always present regardless of cutoff — same posture as
|
||||
//! `coast_invention::character_field`, which is NEVER cutoff-gated) set the
|
||||
//! DC bias (which side of "possible forest" a broad area sits on) at 70% of
|
||||
//! the blend weight; the fine octaves (district/quarter-scale, cutoff-gated
|
||||
//! exactly like `terrain_detail`/`voxel_relief`) contribute the remaining
|
||||
//! 30% as zero-mean texture. That weighting means the fine tier alone can
|
||||
//! never flip the BLENDED FIELD's sign — but the blended field is only an
|
||||
//! intermediate `[-1, 1]` value; after it is scaled by the body's
|
||||
//! `ceiling_q` and added to `base_moisture_q`, the RESULT crosses
|
||||
//! `derive_vegetation`'s class thresholds exactly as elevation/temperature
|
||||
//! do elsewhere in this cascade. A boundary cell sitting close enough to a
|
||||
//! threshold WILL legitimately flip class under the fine tier's
|
||||
//! contribution — that flip IS the clearing/copse the ticket asks for. What
|
||||
//! the weighting guarantees is that flips stay localized (isolated cells
|
||||
//! near a boundary), so the MAJORITY class over any sampled patch tracks the
|
||||
//! coarse massif tier, never the fine tier alone.
|
||||
//!
|
||||
//! ## Wavelength discipline (per rung, identical to parts 1–2 of T-1162)
|
||||
//!
|
||||
|
||||
@@ -253,5 +253,515 @@
|
||||
"temperature_dc": -64,
|
||||
"moisture_q": 43,
|
||||
"vegetation": 1
|
||||
},
|
||||
{
|
||||
"label": "airless_dry/coastal_a",
|
||||
"rung": "district",
|
||||
"wx_m": 2000000,
|
||||
"wy_m": 1500000,
|
||||
"min_wl_m": 4096,
|
||||
"morphology": 8,
|
||||
"tectonic": 0,
|
||||
"glaciation": 0,
|
||||
"precipitation": 0,
|
||||
"slope_q": 2,
|
||||
"elev_q": 44,
|
||||
"ocean_fraction_q": 0,
|
||||
"temperature_dc": -2147483648,
|
||||
"moisture_q": 0,
|
||||
"vegetation": 0
|
||||
},
|
||||
{
|
||||
"label": "airless_dry/coastal_a",
|
||||
"rung": "quarter",
|
||||
"wx_m": 2000000,
|
||||
"wy_m": 1500000,
|
||||
"min_wl_m": 1024,
|
||||
"morphology": 8,
|
||||
"tectonic": 0,
|
||||
"glaciation": 0,
|
||||
"precipitation": 0,
|
||||
"slope_q": 2,
|
||||
"elev_q": 48,
|
||||
"ocean_fraction_q": 0,
|
||||
"temperature_dc": -2147483648,
|
||||
"moisture_q": 0,
|
||||
"vegetation": 0
|
||||
},
|
||||
{
|
||||
"label": "airless_dry/coastal_a",
|
||||
"rung": "region",
|
||||
"wx_m": 2000000,
|
||||
"wy_m": 1500000,
|
||||
"min_wl_m": 0,
|
||||
"morphology": 8,
|
||||
"tectonic": 0,
|
||||
"glaciation": 0,
|
||||
"precipitation": 0,
|
||||
"slope_q": 0,
|
||||
"elev_q": 41,
|
||||
"ocean_fraction_q": 0,
|
||||
"temperature_dc": -2147483648,
|
||||
"moisture_q": 0,
|
||||
"vegetation": 0
|
||||
},
|
||||
{
|
||||
"label": "airless_dry/coastal_b",
|
||||
"rung": "district",
|
||||
"wx_m": 2050000,
|
||||
"wy_m": 1500000,
|
||||
"min_wl_m": 4096,
|
||||
"morphology": 8,
|
||||
"tectonic": 0,
|
||||
"glaciation": 0,
|
||||
"precipitation": 0,
|
||||
"slope_q": 1,
|
||||
"elev_q": 42,
|
||||
"ocean_fraction_q": 0,
|
||||
"temperature_dc": -2147483648,
|
||||
"moisture_q": 0,
|
||||
"vegetation": 0
|
||||
},
|
||||
{
|
||||
"label": "airless_dry/coastal_b",
|
||||
"rung": "quarter",
|
||||
"wx_m": 2050000,
|
||||
"wy_m": 1500000,
|
||||
"min_wl_m": 1024,
|
||||
"morphology": 8,
|
||||
"tectonic": 0,
|
||||
"glaciation": 0,
|
||||
"precipitation": 0,
|
||||
"slope_q": 2,
|
||||
"elev_q": 39,
|
||||
"ocean_fraction_q": 0,
|
||||
"temperature_dc": -2147483648,
|
||||
"moisture_q": 0,
|
||||
"vegetation": 0
|
||||
},
|
||||
{
|
||||
"label": "airless_dry/coastal_b",
|
||||
"rung": "region",
|
||||
"wx_m": 2050000,
|
||||
"wy_m": 1500000,
|
||||
"min_wl_m": 0,
|
||||
"morphology": 8,
|
||||
"tectonic": 0,
|
||||
"glaciation": 0,
|
||||
"precipitation": 0,
|
||||
"slope_q": 0,
|
||||
"elev_q": 41,
|
||||
"ocean_fraction_q": 0,
|
||||
"temperature_dc": -2147483648,
|
||||
"moisture_q": 0,
|
||||
"vegetation": 0
|
||||
},
|
||||
{
|
||||
"label": "airless_dry/coastal_c",
|
||||
"rung": "district",
|
||||
"wx_m": 2100000,
|
||||
"wy_m": 1560000,
|
||||
"min_wl_m": 4096,
|
||||
"morphology": 8,
|
||||
"tectonic": 0,
|
||||
"glaciation": 0,
|
||||
"precipitation": 0,
|
||||
"slope_q": 2,
|
||||
"elev_q": 44,
|
||||
"ocean_fraction_q": 0,
|
||||
"temperature_dc": -2147483648,
|
||||
"moisture_q": 0,
|
||||
"vegetation": 0
|
||||
},
|
||||
{
|
||||
"label": "airless_dry/coastal_c",
|
||||
"rung": "quarter",
|
||||
"wx_m": 2100000,
|
||||
"wy_m": 1560000,
|
||||
"min_wl_m": 1024,
|
||||
"morphology": 8,
|
||||
"tectonic": 0,
|
||||
"glaciation": 0,
|
||||
"precipitation": 0,
|
||||
"slope_q": 2,
|
||||
"elev_q": 45,
|
||||
"ocean_fraction_q": 0,
|
||||
"temperature_dc": -2147483648,
|
||||
"moisture_q": 0,
|
||||
"vegetation": 0
|
||||
},
|
||||
{
|
||||
"label": "airless_dry/coastal_c",
|
||||
"rung": "region",
|
||||
"wx_m": 2100000,
|
||||
"wy_m": 1560000,
|
||||
"min_wl_m": 0,
|
||||
"morphology": 8,
|
||||
"tectonic": 0,
|
||||
"glaciation": 0,
|
||||
"precipitation": 0,
|
||||
"slope_q": 0,
|
||||
"elev_q": 41,
|
||||
"ocean_fraction_q": 0,
|
||||
"temperature_dc": -2147483648,
|
||||
"moisture_q": 0,
|
||||
"vegetation": 0
|
||||
},
|
||||
{
|
||||
"label": "airless_dry/inland",
|
||||
"rung": "district",
|
||||
"wx_m": 500000,
|
||||
"wy_m": 3000000,
|
||||
"min_wl_m": 4096,
|
||||
"morphology": 8,
|
||||
"tectonic": 0,
|
||||
"glaciation": 0,
|
||||
"precipitation": 0,
|
||||
"slope_q": 3,
|
||||
"elev_q": 44,
|
||||
"ocean_fraction_q": 0,
|
||||
"temperature_dc": -2147483648,
|
||||
"moisture_q": 0,
|
||||
"vegetation": 0
|
||||
},
|
||||
{
|
||||
"label": "airless_dry/inland",
|
||||
"rung": "quarter",
|
||||
"wx_m": 500000,
|
||||
"wy_m": 3000000,
|
||||
"min_wl_m": 1024,
|
||||
"morphology": 8,
|
||||
"tectonic": 0,
|
||||
"glaciation": 0,
|
||||
"precipitation": 0,
|
||||
"slope_q": 4,
|
||||
"elev_q": 39,
|
||||
"ocean_fraction_q": 0,
|
||||
"temperature_dc": -2147483648,
|
||||
"moisture_q": 0,
|
||||
"vegetation": 0
|
||||
},
|
||||
{
|
||||
"label": "airless_dry/inland",
|
||||
"rung": "region",
|
||||
"wx_m": 500000,
|
||||
"wy_m": 3000000,
|
||||
"min_wl_m": 0,
|
||||
"morphology": 8,
|
||||
"tectonic": 0,
|
||||
"glaciation": 0,
|
||||
"precipitation": 0,
|
||||
"slope_q": 0,
|
||||
"elev_q": 42,
|
||||
"ocean_fraction_q": 0,
|
||||
"temperature_dc": -2147483648,
|
||||
"moisture_q": 0,
|
||||
"vegetation": 0
|
||||
},
|
||||
{
|
||||
"label": "airless_dry/high_lat",
|
||||
"rung": "district",
|
||||
"wx_m": 1200000,
|
||||
"wy_m": 8500000,
|
||||
"min_wl_m": 4096,
|
||||
"morphology": 8,
|
||||
"tectonic": 0,
|
||||
"glaciation": 0,
|
||||
"precipitation": 0,
|
||||
"slope_q": 2,
|
||||
"elev_q": 76,
|
||||
"ocean_fraction_q": 0,
|
||||
"temperature_dc": -2147483648,
|
||||
"moisture_q": 0,
|
||||
"vegetation": 0
|
||||
},
|
||||
{
|
||||
"label": "airless_dry/high_lat",
|
||||
"rung": "quarter",
|
||||
"wx_m": 1200000,
|
||||
"wy_m": 8500000,
|
||||
"min_wl_m": 1024,
|
||||
"morphology": 8,
|
||||
"tectonic": 0,
|
||||
"glaciation": 0,
|
||||
"precipitation": 0,
|
||||
"slope_q": 3,
|
||||
"elev_q": 79,
|
||||
"ocean_fraction_q": 0,
|
||||
"temperature_dc": -2147483648,
|
||||
"moisture_q": 0,
|
||||
"vegetation": 0
|
||||
},
|
||||
{
|
||||
"label": "airless_dry/high_lat",
|
||||
"rung": "region",
|
||||
"wx_m": 1200000,
|
||||
"wy_m": 8500000,
|
||||
"min_wl_m": 0,
|
||||
"morphology": 8,
|
||||
"tectonic": 0,
|
||||
"glaciation": 0,
|
||||
"precipitation": 0,
|
||||
"slope_q": 0,
|
||||
"elev_q": 77,
|
||||
"ocean_fraction_q": 0,
|
||||
"temperature_dc": -2147483648,
|
||||
"moisture_q": 0,
|
||||
"vegetation": 0
|
||||
},
|
||||
{
|
||||
"label": "volcanic_coast/coastal_a",
|
||||
"rung": "district",
|
||||
"wx_m": 2000000,
|
||||
"wy_m": 1500000,
|
||||
"min_wl_m": 4096,
|
||||
"morphology": 15,
|
||||
"tectonic": 2,
|
||||
"glaciation": 0,
|
||||
"precipitation": 3,
|
||||
"slope_q": 3,
|
||||
"elev_q": 25,
|
||||
"ocean_fraction_q": 0,
|
||||
"temperature_dc": 497,
|
||||
"moisture_q": 60,
|
||||
"vegetation": 3
|
||||
},
|
||||
{
|
||||
"label": "volcanic_coast/coastal_a",
|
||||
"rung": "quarter",
|
||||
"wx_m": 2000000,
|
||||
"wy_m": 1500000,
|
||||
"min_wl_m": 1024,
|
||||
"morphology": 15,
|
||||
"tectonic": 2,
|
||||
"glaciation": 0,
|
||||
"precipitation": 3,
|
||||
"slope_q": 6,
|
||||
"elev_q": 13,
|
||||
"ocean_fraction_q": 0,
|
||||
"temperature_dc": 560,
|
||||
"moisture_q": 62,
|
||||
"vegetation": 3
|
||||
},
|
||||
{
|
||||
"label": "volcanic_coast/coastal_a",
|
||||
"rung": "region",
|
||||
"wx_m": 2000000,
|
||||
"wy_m": 1500000,
|
||||
"min_wl_m": 0,
|
||||
"morphology": 15,
|
||||
"tectonic": 2,
|
||||
"glaciation": 0,
|
||||
"precipitation": 3,
|
||||
"slope_q": 0,
|
||||
"elev_q": 28,
|
||||
"ocean_fraction_q": 0,
|
||||
"temperature_dc": 482,
|
||||
"moisture_q": 59,
|
||||
"vegetation": 3
|
||||
},
|
||||
{
|
||||
"label": "volcanic_coast/coastal_b",
|
||||
"rung": "district",
|
||||
"wx_m": 2050000,
|
||||
"wy_m": 1500000,
|
||||
"min_wl_m": 4096,
|
||||
"morphology": 15,
|
||||
"tectonic": 2,
|
||||
"glaciation": 0,
|
||||
"precipitation": 3,
|
||||
"slope_q": 4,
|
||||
"elev_q": 34,
|
||||
"ocean_fraction_q": 0,
|
||||
"temperature_dc": 456,
|
||||
"moisture_q": 58,
|
||||
"vegetation": 3
|
||||
},
|
||||
{
|
||||
"label": "volcanic_coast/coastal_b",
|
||||
"rung": "quarter",
|
||||
"wx_m": 2050000,
|
||||
"wy_m": 1500000,
|
||||
"min_wl_m": 1024,
|
||||
"morphology": 15,
|
||||
"tectonic": 2,
|
||||
"glaciation": 0,
|
||||
"precipitation": 3,
|
||||
"slope_q": 6,
|
||||
"elev_q": 24,
|
||||
"ocean_fraction_q": 0,
|
||||
"temperature_dc": 508,
|
||||
"moisture_q": 60,
|
||||
"vegetation": 3
|
||||
},
|
||||
{
|
||||
"label": "volcanic_coast/coastal_b",
|
||||
"rung": "region",
|
||||
"wx_m": 2050000,
|
||||
"wy_m": 1500000,
|
||||
"min_wl_m": 0,
|
||||
"morphology": 15,
|
||||
"tectonic": 2,
|
||||
"glaciation": 0,
|
||||
"precipitation": 3,
|
||||
"slope_q": 0,
|
||||
"elev_q": 28,
|
||||
"ocean_fraction_q": 0,
|
||||
"temperature_dc": 487,
|
||||
"moisture_q": 59,
|
||||
"vegetation": 3
|
||||
},
|
||||
{
|
||||
"label": "volcanic_coast/coastal_c",
|
||||
"rung": "district",
|
||||
"wx_m": 2100000,
|
||||
"wy_m": 1560000,
|
||||
"min_wl_m": 4096,
|
||||
"morphology": 15,
|
||||
"tectonic": 2,
|
||||
"glaciation": 0,
|
||||
"precipitation": 3,
|
||||
"slope_q": 2,
|
||||
"elev_q": 28,
|
||||
"ocean_fraction_q": 0,
|
||||
"temperature_dc": 486,
|
||||
"moisture_q": 59,
|
||||
"vegetation": 3
|
||||
},
|
||||
{
|
||||
"label": "volcanic_coast/coastal_c",
|
||||
"rung": "quarter",
|
||||
"wx_m": 2100000,
|
||||
"wy_m": 1560000,
|
||||
"min_wl_m": 1024,
|
||||
"morphology": 15,
|
||||
"tectonic": 2,
|
||||
"glaciation": 0,
|
||||
"precipitation": 3,
|
||||
"slope_q": 4,
|
||||
"elev_q": 33,
|
||||
"ocean_fraction_q": 0,
|
||||
"temperature_dc": 460,
|
||||
"moisture_q": 59,
|
||||
"vegetation": 3
|
||||
},
|
||||
{
|
||||
"label": "volcanic_coast/coastal_c",
|
||||
"rung": "region",
|
||||
"wx_m": 2100000,
|
||||
"wy_m": 1560000,
|
||||
"min_wl_m": 0,
|
||||
"morphology": 15,
|
||||
"tectonic": 2,
|
||||
"glaciation": 0,
|
||||
"precipitation": 3,
|
||||
"slope_q": 0,
|
||||
"elev_q": 29,
|
||||
"ocean_fraction_q": 0,
|
||||
"temperature_dc": 481,
|
||||
"moisture_q": 59,
|
||||
"vegetation": 3
|
||||
},
|
||||
{
|
||||
"label": "volcanic_coast/inland",
|
||||
"rung": "district",
|
||||
"wx_m": 500000,
|
||||
"wy_m": 3000000,
|
||||
"min_wl_m": 4096,
|
||||
"morphology": 15,
|
||||
"tectonic": 2,
|
||||
"glaciation": 0,
|
||||
"precipitation": 2,
|
||||
"slope_q": 3,
|
||||
"elev_q": 24,
|
||||
"ocean_fraction_q": 0,
|
||||
"temperature_dc": 565,
|
||||
"moisture_q": 49,
|
||||
"vegetation": 3
|
||||
},
|
||||
{
|
||||
"label": "volcanic_coast/inland",
|
||||
"rung": "quarter",
|
||||
"wx_m": 500000,
|
||||
"wy_m": 3000000,
|
||||
"min_wl_m": 1024,
|
||||
"morphology": 15,
|
||||
"tectonic": 2,
|
||||
"glaciation": 0,
|
||||
"precipitation": 2,
|
||||
"slope_q": 4,
|
||||
"elev_q": 21,
|
||||
"ocean_fraction_q": 0,
|
||||
"temperature_dc": 581,
|
||||
"moisture_q": 49,
|
||||
"vegetation": 3
|
||||
},
|
||||
{
|
||||
"label": "volcanic_coast/inland",
|
||||
"rung": "region",
|
||||
"wx_m": 500000,
|
||||
"wy_m": 3000000,
|
||||
"min_wl_m": 0,
|
||||
"morphology": 15,
|
||||
"tectonic": 2,
|
||||
"glaciation": 0,
|
||||
"precipitation": 2,
|
||||
"slope_q": 0,
|
||||
"elev_q": 23,
|
||||
"ocean_fraction_q": 0,
|
||||
"temperature_dc": 571,
|
||||
"moisture_q": 49,
|
||||
"vegetation": 3
|
||||
},
|
||||
{
|
||||
"label": "volcanic_coast/high_lat",
|
||||
"rung": "district",
|
||||
"wx_m": 1200000,
|
||||
"wy_m": 8500000,
|
||||
"min_wl_m": 4096,
|
||||
"morphology": 15,
|
||||
"tectonic": 2,
|
||||
"glaciation": 0,
|
||||
"precipitation": 2,
|
||||
"slope_q": 3,
|
||||
"elev_q": 68,
|
||||
"ocean_fraction_q": 0,
|
||||
"temperature_dc": 545,
|
||||
"moisture_q": 29,
|
||||
"vegetation": 2
|
||||
},
|
||||
{
|
||||
"label": "volcanic_coast/high_lat",
|
||||
"rung": "quarter",
|
||||
"wx_m": 1200000,
|
||||
"wy_m": 8500000,
|
||||
"min_wl_m": 1024,
|
||||
"morphology": 15,
|
||||
"tectonic": 2,
|
||||
"glaciation": 0,
|
||||
"precipitation": 2,
|
||||
"slope_q": 4,
|
||||
"elev_q": 65,
|
||||
"ocean_fraction_q": 0,
|
||||
"temperature_dc": 561,
|
||||
"moisture_q": 30,
|
||||
"vegetation": 2
|
||||
},
|
||||
{
|
||||
"label": "volcanic_coast/high_lat",
|
||||
"rung": "region",
|
||||
"wx_m": 1200000,
|
||||
"wy_m": 8500000,
|
||||
"min_wl_m": 0,
|
||||
"morphology": 15,
|
||||
"tectonic": 2,
|
||||
"glaciation": 0,
|
||||
"precipitation": 2,
|
||||
"slope_q": 0,
|
||||
"elev_q": 66,
|
||||
"ocean_fraction_q": 0,
|
||||
"temperature_dc": 555,
|
||||
"moisture_q": 30,
|
||||
"vegetation": 2
|
||||
}
|
||||
]
|
||||
|
||||
@@ -18,6 +18,16 @@
|
||||
//! quantization will change this golden's values — regenerate deliberately
|
||||
//! (per the asset-pipeline discipline: source changes, not hand-edits).
|
||||
//!
|
||||
//! **Body coverage (Tyre, PR #194 review I4):** the sweep runs against THREE
|
||||
//! bodies, not one — the original temperate/ocean/breathable body (unchanged
|
||||
//! from the initial T-1162 landing), plus an airless/dry body (exercises
|
||||
//! `vegetation_invention::VegetationEnvelope`'s `ceiling_q == 0` short
|
||||
//! circuit at the full derivation-stack level) and a volcanic/high-tectonic
|
||||
//! coastal body (exercises the ridged-warp/wide-`scatter_floor` branch of
|
||||
//! `coast_invention`). The two new bodies' rows are APPENDED after the
|
||||
//! original body's rows (never interleaved), so the original rows stay
|
||||
//! byte-identical across the I4 regen — see `body_sweep_samples`'s doc.
|
||||
//!
|
||||
//! Run: `cargo test --test window_derivation_golden`
|
||||
//! Regenerate: `UPDATE_GOLDEN=1 cargo test --test window_derivation_golden`
|
||||
|
||||
@@ -36,6 +46,14 @@ const GOLDEN_FILE: &str = "tests/golden/window_derivation_golden.json";
|
||||
|
||||
/// Compact representation of a `DistrictProfile` sample for golden pinning.
|
||||
/// Integer-discriminant fields only (D-010) — no float equality flakiness.
|
||||
///
|
||||
/// **No `body` field (Tyre, PR #194 I4 constraint):** the two new body rows
|
||||
/// (I4) distinguish themselves via the `label` field's prefix instead of a
|
||||
/// new struct field — adding a field here would change the JSON shape of
|
||||
/// EVERY existing row (not just the new ones), which fails I4's explicit
|
||||
/// "existing rows must stay byte-identical" requirement. `label` was always
|
||||
/// a free-form string, so `"golden_body/coastal_a"` vs `"airless_dry/coastal_a"`
|
||||
/// costs nothing structurally and keeps the diff a pure append.
|
||||
#[derive(Debug, serde::Serialize, serde::Deserialize, PartialEq, Eq, Clone)]
|
||||
struct GoldenSample {
|
||||
label: String,
|
||||
@@ -97,6 +115,43 @@ fn sample_params() -> BodyParams {
|
||||
}
|
||||
}
|
||||
|
||||
/// I4 (Tyre, PR #194 review): airless/dry body params — exercises
|
||||
/// `vegetation_invention::VegetationEnvelope`'s `ceiling_q == 0` short
|
||||
/// circuit (no water, no atmosphere → zero patchiness swing, per
|
||||
/// `envelope_airless_or_dry_body_has_zero_ceiling`'s unit-level proof) at
|
||||
/// the FULL derivation-stack level, which the unit test alone doesn't pin.
|
||||
/// Also airless (`atmosphere: "none"`) so `temperature_c`/`vegetation_class`
|
||||
/// take the `None`/`Absent` branches — a body-envelope regression that
|
||||
/// invented forest on a bone-dry world would show up here as a NEW
|
||||
/// non-Barren/non-Absent vegetation discriminant in the golden diff.
|
||||
fn airless_dry_params() -> BodyParams {
|
||||
BodyParams {
|
||||
hydrosphere: Some("none".into()),
|
||||
atmosphere: Some("none".into()),
|
||||
planet_class: Some("arid".into()),
|
||||
body_radius_km: Some(3_390.0), // Mars-scale, deliberately distinct from the wet body
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
/// I4 (Tyre, PR #194 review): volcanic/high-tectonic coastal body params —
|
||||
/// exercises `coast_invention`'s ridged-warp + wide-`scatter_floor` branch
|
||||
/// (`TectonicClass::Volcanic` → `tectonic_energy` near its ceiling in
|
||||
/// `body_coast_envelope`, driving up `roughness`/`warp_amplitude_px`/
|
||||
/// `scatter_floor` per that function's doc) — the coast-crinkle branch most
|
||||
/// likely to visibly differ from the temperate body's gentler warp, and thus
|
||||
/// the branch most likely to silently regress without dedicated coverage.
|
||||
fn volcanic_coast_params() -> BodyParams {
|
||||
BodyParams {
|
||||
hydrosphere: Some("ocean".into()),
|
||||
atmosphere: Some("breathable".into()),
|
||||
planet_class: Some("volcanic".into()),
|
||||
tectonic_activity: Some("volcanic".into()),
|
||||
body_radius_km: Some(6_000.0),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
/// Fixed sweep positions (world metres from origin) — a handful of points
|
||||
/// spanning a coastal stretch (per the heightmap's ripple) plus a couple of
|
||||
/// clearly inland/high-latitude points, so the golden exercises coast warp,
|
||||
@@ -165,53 +220,105 @@ const DISTRICT_MIN_WL_M: f64 = 4_096.0;
|
||||
/// new T-1162 entry — Quarter's own Nyquist floor, `2 * QUARTER_M`).
|
||||
const QUARTER_MIN_WL_M: f64 = 1_024.0;
|
||||
|
||||
/// Build the full fixed sweep: every position × the three rung cutoffs
|
||||
/// (District / Quarter use their REAL production `MIN_WL_BANDS_M` values /
|
||||
/// Region via `derive_orbital_at_metres`, which takes no cutoff parameter —
|
||||
/// see its own doc on why).
|
||||
fn golden_samples() -> Vec<GoldenSample> {
|
||||
let hm = sample_hm();
|
||||
let ta = sample_ta(&hm);
|
||||
let params = sample_params();
|
||||
let climate = ClimateConstants::default();
|
||||
let seed = SeedChain::root(0xC0FFEE_u64).derive(SeedDomain::Body, 7);
|
||||
let body_id = "golden_body";
|
||||
|
||||
/// Run the fixed sweep (every position × the three rung cutoffs — District /
|
||||
/// Quarter use their REAL production `MIN_WL_BANDS_M` values / Region via
|
||||
/// `derive_orbital_at_metres`, which takes no cutoff parameter — see its own
|
||||
/// doc on why) for ONE body. Extracted (Tyre, PR #194 I4) so multiple bodies
|
||||
/// can share the same sweep logic; `label_prefix` (empty for the original
|
||||
/// body, non-empty for the I4 additions) is prepended to each row's `label`
|
||||
/// so multi-body output stays distinguishable without a new struct field
|
||||
/// (see [`GoldenSample`]'s doc on why no `body` field was added).
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn body_sweep_samples(
|
||||
label_prefix: &str,
|
||||
seed: SeedChain,
|
||||
body_id: &str,
|
||||
params: &BodyParams,
|
||||
ta: &TerrainAnalysis,
|
||||
climate: &ClimateConstants,
|
||||
) -> Vec<GoldenSample> {
|
||||
let mut out = Vec::new();
|
||||
for (label, wx, wy) in sweep_positions() {
|
||||
let label = format!("{label_prefix}{label}");
|
||||
out.push(derive_golden_sample(
|
||||
label,
|
||||
&label,
|
||||
"district",
|
||||
seed,
|
||||
body_id,
|
||||
¶ms,
|
||||
&ta,
|
||||
&climate,
|
||||
params,
|
||||
ta,
|
||||
climate,
|
||||
wx,
|
||||
wy,
|
||||
DISTRICT_MIN_WL_M,
|
||||
false,
|
||||
));
|
||||
out.push(derive_golden_sample(
|
||||
label,
|
||||
&label,
|
||||
"quarter",
|
||||
seed,
|
||||
body_id,
|
||||
¶ms,
|
||||
&ta,
|
||||
&climate,
|
||||
params,
|
||||
ta,
|
||||
climate,
|
||||
wx,
|
||||
wy,
|
||||
QUARTER_MIN_WL_M,
|
||||
false,
|
||||
));
|
||||
out.push(derive_golden_sample(
|
||||
label, "region", seed, body_id, ¶ms, &ta, &climate, wx, wy, 0.0, true,
|
||||
&label, "region", seed, body_id, params, ta, climate, wx, wy, 0.0, true,
|
||||
));
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
/// Build the full golden sample set: the ORIGINAL temperate/ocean/breathable
|
||||
/// body's sweep first (byte-identical inputs to the pre-I4 `golden_samples`
|
||||
/// — same seed, same `body_id`, same unprefixed labels, so its rows are
|
||||
/// byte-identical in the regenerated fixture), THEN the two I4 body rows
|
||||
/// appended after (never interleaved) so the diff against the pre-I4 golden
|
||||
/// is a pure append, not a reshuffle.
|
||||
fn golden_samples() -> Vec<GoldenSample> {
|
||||
let hm = sample_hm();
|
||||
let ta = sample_ta(&hm);
|
||||
let climate = ClimateConstants::default();
|
||||
|
||||
let mut out = Vec::new();
|
||||
|
||||
// Original body — UNCHANGED inputs from pre-I4 (T-1162 initial landing).
|
||||
out.extend(body_sweep_samples(
|
||||
"",
|
||||
SeedChain::root(0xC0FFEE_u64).derive(SeedDomain::Body, 7),
|
||||
"golden_body",
|
||||
&sample_params(),
|
||||
&ta,
|
||||
&climate,
|
||||
));
|
||||
|
||||
// I4 addition 1: airless/dry — ceiling_q == 0 vegetation short-circuit.
|
||||
out.extend(body_sweep_samples(
|
||||
"airless_dry/",
|
||||
SeedChain::root(0xC0FFEE_u64).derive(SeedDomain::Body, 8),
|
||||
"golden_body_airless_dry",
|
||||
&airless_dry_params(),
|
||||
&ta,
|
||||
&climate,
|
||||
));
|
||||
|
||||
// I4 addition 2: volcanic/high-tectonic coast — ridged warp, wide scatter_floor.
|
||||
out.extend(body_sweep_samples(
|
||||
"volcanic_coast/",
|
||||
SeedChain::root(0xC0FFEE_u64).derive(SeedDomain::Body, 9),
|
||||
"golden_body_volcanic_coast",
|
||||
&volcanic_coast_params(),
|
||||
&ta,
|
||||
&climate,
|
||||
));
|
||||
|
||||
out
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn window_derivation_golden_regression() {
|
||||
let manifest = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||
@@ -294,12 +401,18 @@ fn quarter_and_district_rungs_diverge_at_the_same_position() {
|
||||
);
|
||||
}
|
||||
|
||||
/// `scale::DISTRICT_M` / `scale::QUARTER_M` sanity — documents WHY 2,048/1,024
|
||||
/// are the cutoffs used above (District's own spacing; Quarter's own Nyquist
|
||||
/// floor, `2 × QUARTER_M`), so a future scale-ladder change surfaces here.
|
||||
/// `scale::DISTRICT_M` / `scale::QUARTER_M` sanity — documents WHY
|
||||
/// `DISTRICT_MIN_WL_M`/`QUARTER_MIN_WL_M` are the cutoffs used above (each
|
||||
/// rung's own Nyquist floor, `2 × <rung's spacing>`), so a future
|
||||
/// scale-ladder change surfaces here. Pins BOTH rungs' coupling (Tyre, PR
|
||||
/// #194 I1 — District's coupling was previously unpinned; only Quarter's
|
||||
/// `2 × QUARTER_M` was checked) — this mirrors
|
||||
/// `layer_proxy::MIN_WL_BANDS_M`'s own direct `2 × DISTRICT_M` / `2 ×
|
||||
/// QUARTER_M` derivation, not `detail_scatter::OCTAVE_WAVELENGTHS_M`.
|
||||
#[test]
|
||||
fn golden_cutoffs_match_the_scale_ladder() {
|
||||
assert_eq!(scale::DISTRICT_M, 2_048);
|
||||
assert_eq!(scale::QUARTER_M, 512);
|
||||
assert_eq!(2 * scale::QUARTER_M, 1_024);
|
||||
assert_eq!(2 * scale::DISTRICT_M, DISTRICT_MIN_WL_M as i32);
|
||||
assert_eq!(2 * scale::QUARTER_M, QUARTER_MIN_WL_M as i32);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user