fix(simulation): one absolute-metre derive core (D-256, T-1174)

derive_district_profile is now a thin wrapper over the shared
derive_at_metres_with_riparian core at survey-cell-centre world metres
— one derive core, two position sets. The batch pseudo-grid and the
true D-243 district grid were two coordinate systems sharing one bare
(i32,i32) type; the new SurveyCellPos newtype re-keys every batch
product (BodyWorldState.districts, Layer1Output.survey_basin_dirs) so
the compiler rejects cross-namespace passing.

Fixes two latent same-position divergences the T-1174 investigation
surfaced: three inconsistent latitude conventions collapse into the
core's single inverse mapping, and the region-climate baseline now
floor-divides true world metres instead of collapsing the whole body
onto region (0,0)'s baseline — batch climate becomes latitude/region
graded (D-245 direction: every changed believability metric increased).

Binding preservations per D-256(c): basin_direction rides a post-call
override with the true L1 D8 survey-cell aggregate (layer1's map
re-keyed to SurveyCellPos, identity lookup — a floor-divide lookup
against the pseudo-keyed map would have silently defaulted every cell
North); the riparian verdict comes from near_perennial_water_at, never
the empty-slice default (which would have flipped riverside
vegetation_class).

Quarter-skeleton morphology_zone now resolves at the settlement's
exact world position via derive_at_metres at work-item execution
(where TerrainAnalysisCache lives), replacing the survey-cell-centre
map lookup (D-256(d)); settlement_district_pos fixed to true-district
floor-division in passing (same doc/impl mismatch class). Second
pixel-vs-metre conflation fixed in aliveness_probe's anchor-walk math.

Window path byte-unchanged (window_derivation_golden 6/6 byte-
identical); derivation_harness golden untouched; believability golden
regenerated. Full lib + integration suites green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-25 00:40:13 +02:00
co-authored by Claude Fable 5
parent 35a4137304
commit 933e1f4ee4
15 changed files with 1272 additions and 479 deletions
+113 -40
View File
@@ -6,11 +6,15 @@
//! `atlas::believability` so this binary and `tests/believability_harness` measure the
//! exact same thing.
//!
//! ## Why the *district* tier
//! ## Why the *survey-cell* tier (D-256(b))
//!
//! No production code maps a world chunk → its covering `DistrictProfile` yet (the voxel
//! layer is a walking skeleton), so analysis is addressed in district space; the voxel
//! sample inside each district is illustrative ground-truth of what its 1 m tiles derive to.
//! layer is a walking skeleton), so the body-level report is addressed in survey-cell
//! space — a coarse planning raster, NOT the true D-243 district grid (see
//! `settled_reach_server::atlas::scale::SurveyCellPos`); the voxel sample inside each
//! survey cell (at its own D-256(b) centre world metres) is illustrative ground-truth of
//! what its 1 m tiles derive to. The `--render` mode below is the true-district
//! counterpart, at real 2 km fidelity via the on-demand `derive_district` path.
//!
//! ```sh
//! cargo run --bin aliveness_probe -- --body GJ338Bd --seed yolo --probes 5
@@ -37,13 +41,11 @@ use settled_reach_server::atlas::believability::{
use settled_reach_server::atlas::body_world_state::BodyWorldState;
use settled_reach_server::atlas::chunk_context::derive_chunk_context;
use settled_reach_server::atlas::district_profile::{
derive_district, BodyParams, ClimateConstants, DistrictProfile, GlaciationGrade,
self, derive_district, BodyParams, ClimateConstants, DistrictProfile, GlaciationGrade,
VegetationClass,
};
use settled_reach_server::atlas::features::TerrainAnalysis;
use settled_reach_server::atlas::scale::{
self, ChunkPos, DistrictPos, CHUNKS_PER_DISTRICT, CHUNK_M,
};
use settled_reach_server::atlas::scale::{self, ChunkPos, DistrictPos, SurveyCellPos, CHUNK_M};
use settled_reach_server::atlas::voxel::derive_voxel_column;
use settled_reach_server::seed::SeedChain;
use settled_reach_server::simulation::generator::MorphologyZone;
@@ -89,9 +91,9 @@ fn main() {
eprintln!("cascade produced no districts — cannot probe (body params missing?). Aborting.");
std::process::exit(1);
}
let keys: Vec<DistrictPos> = districts.keys().copied().collect();
let keys: Vec<SurveyCellPos> = districts.keys().copied().collect();
eprintln!(
"cascade: {} districts, {} settlement placements",
"cascade: {} survey cells, {} settlement placements",
districts.len(),
bws.placements.len()
);
@@ -102,38 +104,79 @@ fn main() {
);
// ── Body-level believability report — the D-245 enforcer verdict ────────
let report = analyze(world_seed, &args.body, districts);
let report = analyze(
world_seed,
&args.body,
districts,
bws.heightmap_width,
bws.heightmap_height,
body_params.body_radius_km,
);
print_report(&report);
// ── Anchored probe: ≈150 chunks west of the principal settlement ────────
// (highest placement score; per-city population is 0 in the DB).
let anchor_district = bws.placements.iter().max_by_key(|p| p.score).map(|p| {
let dp = scale::heightmap_pixel_to_district(p.position);
// (highest placement score; per-city population is 0 in the DB). D-256(b):
// `heightmap_pixel_to_survey_cell` — a survey-raster position, NOT a true
// district — so "west" is walked in survey-cell units (each cell spans
// HEIGHTMAP_CELLS_PER_DISTRICT working pixels), never true DISTRICT_M.
let anchor_cell = bws.placements.iter().max_by_key(|p| p.score).map(|p| {
let cell = scale::heightmap_pixel_to_survey_cell(p.position);
println!(
"\nprincipal settlement: city {} @ pixel {:?}district {:?} (placement score {})",
p.city_id, p.position, dp, p.score
"\nprincipal settlement: city {} @ pixel {:?}survey cell {:?} (placement score {})",
p.city_id, p.position, cell, p.score
);
let west_districts = (ANCHOR_OFFSET_CHUNKS * CHUNK_M) / scale::DISTRICT_M;
(dp.0 - west_districts.max(1) - 1, dp.1)
// 150 chunks (9 600 m) ÷ one survey cell's ACTUAL metric width at this
// row — measured directly via two adjacent cells' D-256(b) centre
// world metres (the same bridge derive_district_profile uses), NOT
// `HEIGHTMAP_CELLS_PER_DISTRICT * DISTRICT_M` (that formula silently
// treats a working pixel as if it were DISTRICT_M metres wide, which
// is only true in the no-radius fallback — on a real body a working
// pixel's metric width is `circumference / heightmap_width`, unrelated
// to DISTRICT_M; the earlier version was the SAME pseudo-grid/true-grid
// conflation this ticket's basin-dirs fix corrected). Diagnostic-only
// "west" nudge — exact enough to land roughly the requested distance
// away, never used for anything position-authoritative.
let gcpr = scale::HEIGHTMAP_CELLS_PER_DISTRICT;
let (x0, _) = district_profile::survey_cell_centre_world_m(
cell,
gcpr,
bws.heightmap_width as usize,
bws.heightmap_height as usize,
body_params.body_radius_km,
);
let (x1, _) = district_profile::survey_cell_centre_world_m(
SurveyCellPos(cell.0 + 1, cell.1),
gcpr,
bws.heightmap_width as usize,
bws.heightmap_height as usize,
body_params.body_radius_km,
);
let cell_width_m = (x1 - x0).abs().max(1.0);
let cell_width_chunks = (cell_width_m / CHUNK_M as f64).round() as i32;
let west_cells = (ANCHOR_OFFSET_CHUNKS / cell_width_chunks.max(1)).max(1);
SurveyCellPos(cell.0 - west_cells - 1, cell.1)
});
if let Some(adp) = anchor_district {
if let Some(acell) = anchor_cell {
println!(
"\n---- ANCHORED PROBE: ≈{ANCHOR_OFFSET_CHUNKS} chunks (9.6 km) west of the principal city ----"
);
match nearest_present(districts, adp) {
Some((dp, prof)) => probe(
match nearest_present(districts, acell) {
Some((cell, prof)) => probe(
&args.body,
world_seed,
dp,
cell,
bws.heightmap_width,
bws.heightmap_height,
body_params.body_radius_km,
prof,
if dp == adp {
if cell == acell {
""
} else {
"(nearest land district — target is off-map / open ocean)"
"(nearest land survey cell — target is off-map / open ocean)"
},
),
None => println!(" target {adp:?} and neighbours are off-map; nothing to sample."),
None => println!(" target {acell:?} and neighbours are off-map; nothing to sample."),
}
}
@@ -141,11 +184,20 @@ fn main() {
println!("\n---- {} RANDOM PROBES ----", args.probes);
for i in 0..args.probes {
let pick = (seed_to_u64(&format!("{}/{i}", args.seed)) % keys.len() as u64) as usize;
let dp = keys[pick];
probe(&args.body, world_seed, dp, &districts[&dp], "");
let cell = keys[pick];
probe(
&args.body,
world_seed,
cell,
bws.heightmap_width,
bws.heightmap_height,
body_params.body_radius_km,
&districts[&cell],
"",
);
}
println!("\n(district tier — voxel addressing is not production-wired yet; voxel rows are illustrative ground-truth for a representative chunk of each district.)");
println!("\n(survey-cell tier — voxel addressing is not production-wired yet; voxel rows are illustrative ground-truth for a representative chunk at each cell's centre.)");
// ── --render: district-window PNG maps (T-1123) ──────────────────────────
if let Some(out_dir) = &args.render {
@@ -201,12 +253,32 @@ fn print_report(r: &BelievabilityReport) {
println!("{}/{} criteria pass", passes, crit.len());
}
/// Probe one district: print its profile + a derived voxel-column sample for colour.
fn probe(body: &str, world_seed: u64, dp: DistrictPos, prof: &DistrictProfile, note: &str) {
// Representative chunk at the district centre (32 chunks / district).
/// Probe one survey cell: print its profile + a derived voxel-column sample for
/// colour, at the TRUE chunk covering the cell's own D-256(b) centre world
/// metres (never the pseudo-grid coordinates scaled by `CHUNKS_PER_DISTRICT`
/// directly — that arithmetic silently assumed the survey grid WAS the true
/// district grid, exactly the D-256 namespace collision).
#[allow(clippy::too_many_arguments)]
fn probe(
body: &str,
world_seed: u64,
dp: SurveyCellPos,
heightmap_width: u32,
heightmap_height: u32,
body_radius_km: Option<f64>,
prof: &DistrictProfile,
note: &str,
) {
let (world_x_m, world_y_m) = district_profile::survey_cell_centre_world_m(
dp,
scale::HEIGHTMAP_CELLS_PER_DISTRICT,
heightmap_width as usize,
heightmap_height as usize,
body_radius_km,
);
let chunk: ChunkPos = (
dp.0 * CHUNKS_PER_DISTRICT + CHUNKS_PER_DISTRICT / 2,
dp.1 * CHUNKS_PER_DISTRICT + CHUNKS_PER_DISTRICT / 2,
(world_x_m / CHUNK_M as f64).floor() as i32,
(world_y_m / CHUNK_M as f64).floor() as i32,
);
let ctx = derive_chunk_context(world_seed, body, prof, chunk, None);
@@ -232,7 +304,7 @@ fn probe(body: &str, world_seed: u64, dp: DistrictPos, prof: &DistrictProfile, n
}
}
println!("\ndistrict {dp:?} {note}");
println!("\nsurvey cell {dp:?} {note}");
println!(
" zone={:?} elev_q={} slope_q={} ocean%q={} moisture_q={} temp={} precip={:?} veg_class={:?} glaciation={:?} basin={:?}",
prof.morphology_zone,
@@ -279,18 +351,18 @@ fn fmt_hist(h: &BTreeMap<String, u32>, n: i64) -> String {
.join(", ")
}
/// Find the district at `dp`, else the nearest present district within a small ring.
/// Find the survey cell at `dp`, else the nearest present cell within a small ring.
fn nearest_present(
districts: &BTreeMap<DistrictPos, DistrictProfile>,
dp: DistrictPos,
) -> Option<(DistrictPos, &DistrictProfile)> {
districts: &BTreeMap<SurveyCellPos, DistrictProfile>,
dp: SurveyCellPos,
) -> Option<(SurveyCellPos, &DistrictProfile)> {
if let Some(p) = districts.get(&dp) {
return Some((dp, p));
}
for r in 1..=8 {
for dx in -r..=r {
for dy in -r..=r {
let q = (dp.0 + dx, dp.1 + dy);
let q = SurveyCellPos(dp.0 + dx, dp.1 + dy);
if let Some(p) = districts.get(&q) {
return Some((q, p));
}
@@ -493,8 +565,9 @@ fn render_window_panels(
/// Map a working-grid settlement pixel `(row, col)` to the TRUE metric 2 km
/// district containing it — the inverse of `derive_district`'s forward mapping
/// (district → fractional working-grid position via the body radius, the D-204
/// elastic seam). NOT `scale::heightmap_pixel_to_district`: that addresses the
/// eager gcpr = 8 pseudo-grid, whose cells span tens of km.
/// elastic seam). NOT `scale::heightmap_pixel_to_survey_cell` (D-256(b)
/// rename): that addresses the eager gcpr = 8 survey raster, whose cells span
/// tens of km — a coarse planning grid, not the true district.
fn true_district_of_pixel(
pixel: (u16, u16),
ta_w: usize,