docs(meta): D-258 amended — rung 0.5 measured, storage not forced (T-1212, T-1213)

The 2026-08-06 amendment ruled: build the un-summarisation as a pure function,
measure it, and open the storage question only if the numbers force it. They
do not.

tests/rung_cost_bench.rs (ignored, run with --release) times the real derive on
Ferrath at the ladder anchor: the whole-body solve 114 ms once per body, one
served canvas 118 / 141 / 175 / 175 ms at Global / Region / District / Quarter.
Storage that could serve Region is ~71 GB for one body; a layer at the record's
own sizing holds only Global's resolution, the rung that least needs it.

The amendment also states what the conservation gate actually protects: the
reliefmap D-258 names as the biome input is read by no server code, so the
"summary" is the derive's own uncomposed verdict. Whether it should become an
input is left for Jeroen. T-1214/T-1215 are annotated, not cancelled.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-24 22:44:36 +02:00
co-authored by Claude Opus 5.5
parent 6b50829d69
commit 5a45c69280
4 changed files with 974 additions and 0 deletions
+88
View File
@@ -0,0 +1,88 @@
//! Rung-0.5 cost measurement on a real body (T-1213, carrying T-1212's question).
//!
//! D-258 ruled a STORED expanded layer; its 2026-08-06 amendment said to build
//! the un-summarisation as a pure function first, measure that, and argue for
//! storage only if the numbers force it. This is that measurement: the
//! once-per-body solve every rung samples, and one served canvas per rung, on
//! Ferrath at the descent ladder's own anchor and the ladder's own extent.
//!
//! Run: `cargo test --release --test rung_cost_bench -- --ignored --nocapture`
//! (debug is several times slower and not worth recording).
use std::time::Instant;
use settled_reach_server::atlas::believability::cascade_snapshot_for_body;
use settled_reach_server::atlas::district_profile::{derive_moisture_ceiling_q, ClimateConstants};
use settled_reach_server::atlas::layer1::run_layer1_with_moisture;
use settled_reach_server::atlas::step_canvas::{build_step_canvas, StepCanvasRung};
use settled_reach_server::seed::SeedChain;
const BODY: &str = "GJ820Bc";
/// The descent ladder's anchor (tests/visual.json, atlas_GJ820Bc_land_*).
const ANCHOR: (i64, i64) = (29_422_008, -5_675_959);
/// The ladder's held extent at 3440x1440 (2x2 display ratio).
const EXTENT: (u32, u32) = (1290, 540);
const RUNS: u32 = 5;
#[test]
#[ignore = "benchmark on a real body; run explicitly with --release"]
fn rung_cost_on_a_real_body() {
let Ok((snapshot, params)) = cascade_snapshot_for_body(42, BODY) else {
eprintln!("skip: {BODY} not loadable");
return;
};
let ceiling = derive_moisture_ceiling_q(&params);
// The whole-body solve (drainage + settled hydrology) — what D-258 first
// proposed moving onto a stored layer, and what already runs once per
// body behind the server's TerrainAnalysisCache.
let t = Instant::now();
let mut solved = None;
for _ in 0..RUNS {
solved = Some(run_layer1_with_moisture(&snapshot.heightmap, ceiling));
}
let solve_ms = t.elapsed().as_secs_f64() * 1e3 / RUNS as f64;
let (l1, ta) = solved.expect("ran");
eprintln!(
"whole-body solve ({}x{} working grid): {solve_ms:.1} ms",
ta.w, ta.h
);
let climate = ClimateConstants::default();
let seed = SeedChain::for_body(42, BODY);
for rung in [
StepCanvasRung::Global,
StepCanvasRung::Region,
StepCanvasRung::District,
StepCanvasRung::Quarter,
] {
let t = Instant::now();
let mut w = 0;
let mut h = 0;
for _ in 0..RUNS {
let raw = build_step_canvas(
seed,
BODY,
&params,
&ta,
&l1.river_network,
&[],
rung,
ANCHOR,
EXTENT,
&climate,
0,
);
w = raw.width;
h = raw.height;
}
let ms = t.elapsed().as_secs_f64() * 1e3 / RUNS as f64;
assert!(w > 0 && h > 0, "{rung:?} built an empty canvas");
// Wall time: build_step_canvas derives rows in parallel (rayon), so
// this is the latency a request sees on this machine, not CPU cost.
eprintln!(
"{rung:?}: {w}x{h} canvas in {ms:.1} ms wall ({:.2} us/cell)",
ms * 1e3 / (w as f64 * h as f64),
);
}
}