feat(simulation): believability gate learns basin-direction variety (T-964, D-245)
A real D-245 gate-shape strengthening, not just a test: the D-256/T-1174 finding proved the believability golden byte-identical under a total all-North basin_direction collapse — every scalar contrast field is structurally blind to the one field that regressed. ContrastMetrics gains land_districts and basin_directions_distinct (both over ALL districts, no new derive calls — the evidence-backed pick over the voxel-transect proxy, which washes out at production sample density), and evaluate_criteria gains 'basin direction variety': pass when land_districts == 0 (the drained-body guard — an all-ocean body has no cells that can cast a D8 vote per the aggregator's own exclusion rule, so a uniform default is legitimate, mirroring the file's existing nothing-to-vary idiom) or distinct >= 2. Negative test proves the criterion catches the land-bearing all-North regression; vacuous-pass test proves the waterworld guard. Golden regenerated and rerun-stable; both validation bodies (Arbour, Edict) pass at distinct=2. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -129,6 +129,24 @@ pub struct ContrastMetrics {
|
||||
/// (min vs mean/median), the final K, and same-class-only pooling are Q-123's to
|
||||
/// calibrate against the enforcer's baselines.
|
||||
pub micro_habitat_distinct: usize,
|
||||
/// Count of districts with `ocean_fraction_q < 100` (not fully submerged) across
|
||||
/// **all** districts (T-964, D-256/T-1174 addendum) — the guard signal for
|
||||
/// [`basin_directions_distinct`](Self::basin_directions_distinct): an all-ocean or
|
||||
/// otherwise basin-less body legitimately has no land to carry a D8 direction, so
|
||||
/// the criterion below must not fire there. Cheap (no voxel derivation, reuses the
|
||||
/// same `districts` iteration the scalar contrast fields already run over).
|
||||
pub land_districts: usize,
|
||||
/// Distinct [`crate::atlas::scale::BasinDirection`] values across **all** districts
|
||||
/// (T-964, D-256/T-1174 addendum). Closes the gap the D-256/T-1174 investigation
|
||||
/// found: an all-North `basin_direction` collapse (every survey cell defaulting,
|
||||
/// D-256(b)'s `aggregate_survey_basin_dirs` "no valid votes → North" fallback firing
|
||||
/// everywhere) produced a BYTE-IDENTICAL report under every OTHER field here —
|
||||
/// `basin_direction` feeds no scalar/categorical contrast field and only reaches the
|
||||
/// voxel-derived fields indirectly (`chunk_context`'s cross/along channel axis, T-964
|
||||
/// evidence), too diluted at the ~3% production voxel-sample ratio to move them. This
|
||||
/// field reads the SAME field the regression hits, directly, over every district —
|
||||
/// not a proxy.
|
||||
pub basin_directions_distinct: usize,
|
||||
}
|
||||
|
||||
/// Coherence checks — does the world render as a *caused* place? Pass/fail counts
|
||||
@@ -215,6 +233,15 @@ pub fn analyze(
|
||||
terrain_materials: 0, // filled from the voxel sample below
|
||||
voxel_relief_m: 0, // filled from the relief transect below
|
||||
micro_habitat_distinct: 0, // filled from the per-district triple sets below
|
||||
land_districts: districts
|
||||
.values()
|
||||
.filter(|d| d.ocean_fraction_q < 100)
|
||||
.count(),
|
||||
basin_directions_distinct: distinct(
|
||||
districts
|
||||
.values()
|
||||
.map(|d| format!("{:?}", d.basin_direction)),
|
||||
),
|
||||
};
|
||||
|
||||
// ── Voxel-derived metrics over a deterministic seeded spread of districts ──
|
||||
@@ -411,6 +438,24 @@ pub fn evaluate_criteria(r: &BelievabilityReport) -> Vec<Criterion> {
|
||||
pass: c.morphology_zones >= 2,
|
||||
detail: format!("{} distinct zones", c.morphology_zones),
|
||||
},
|
||||
Criterion {
|
||||
name: "basin direction variety",
|
||||
// T-964, D-256/T-1174 addendum: catches an all-North basin_direction
|
||||
// collapse (D-256(b)'s "no valid votes → North" fallback firing on every
|
||||
// district) that every other field here is blind to. GUARDED on
|
||||
// `land_districts`: a body with no land (all-ocean/basin-less) has no
|
||||
// cells that can cast a D8 vote at all (`aggregate_survey_basin_dirs`
|
||||
// excludes ocean-masked cells from voting by construction), so every
|
||||
// district legitimately defaults to North — `land_districts == 0` means
|
||||
// "nothing to vary" and passes vacuously (the same idiom "intra-class
|
||||
// variety" above uses for a barren/ocean world), never a false fail on a
|
||||
// legitimate waterworld.
|
||||
pass: c.land_districts == 0 || c.basin_directions_distinct >= 2,
|
||||
detail: format!(
|
||||
"{} distinct basin directions across {} land district(s)",
|
||||
c.basin_directions_distinct, c.land_districts
|
||||
),
|
||||
},
|
||||
Criterion {
|
||||
name: "terrain-material variety",
|
||||
pass: c.terrain_materials >= 2,
|
||||
@@ -815,33 +860,119 @@ mod tests {
|
||||
VegetationClass::Forest,
|
||||
VegetationClass::RiparianThicket,
|
||||
];
|
||||
let dirs = [
|
||||
BasinDirection::North,
|
||||
BasinDirection::East,
|
||||
BasinDirection::South,
|
||||
BasinDirection::West,
|
||||
];
|
||||
let mut districts: BTreeMap<SurveyCellPos, DistrictProfile> = BTreeMap::new();
|
||||
for x in 0..8 {
|
||||
for y in 0..8 {
|
||||
let i = (x * 8 + y) as usize;
|
||||
districts.insert(
|
||||
SurveyCellPos(x, y),
|
||||
district(
|
||||
zones[i % zones.len()],
|
||||
(i as i32 * 7) % 100, // varied elevation
|
||||
(i as i32 * 3) % 60, // varied slope
|
||||
(i as i32 * 11) % 100, // varied moisture
|
||||
(i as i32 * 13) % 40,
|
||||
vegs[i % vegs.len()],
|
||||
),
|
||||
let mut d = district(
|
||||
zones[i % zones.len()],
|
||||
(i as i32 * 7) % 100, // varied elevation
|
||||
(i as i32 * 3) % 60, // varied slope
|
||||
(i as i32 * 11) % 100, // varied moisture
|
||||
(i as i32 * 13) % 40,
|
||||
vegs[i % vegs.len()],
|
||||
);
|
||||
d.basin_direction = dirs[i % dirs.len()]; // varied basin direction (T-964)
|
||||
districts.insert(SurveyCellPos(x, y), d);
|
||||
}
|
||||
}
|
||||
let report = analyze(42, "varied", &districts, 64, 64, None);
|
||||
assert!(report.contrast.moisture_q.distinct >= 3);
|
||||
assert!(report.contrast.morphology_zones >= 2);
|
||||
assert!(report.contrast.elev_q.spread() >= 10);
|
||||
assert!(report.contrast.basin_directions_distinct >= 2);
|
||||
|
||||
let crit = evaluate_criteria(&report);
|
||||
let passed = |name: &str| crit.iter().find(|c| c.name == name).is_some_and(|c| c.pass);
|
||||
assert!(passed("moisture gradient"));
|
||||
assert!(passed("morphology variety"));
|
||||
assert!(passed("elevation relief"));
|
||||
assert!(passed("basin direction variety"));
|
||||
}
|
||||
|
||||
/// T-964, D-256/T-1174 addendum: the "basin direction variety" criterion catches
|
||||
/// an all-North collapse on a body that HAS land (real basins to vary), but must
|
||||
/// pass VACUOUSLY on a genuine waterworld (no land districts at all) — the D-256(b)
|
||||
/// survey aggregator excludes ocean-masked cells from voting by construction, so
|
||||
/// an all-ocean body legitimately defaults every district to North.
|
||||
#[test]
|
||||
fn basin_direction_variety_guards_on_land_presence() {
|
||||
// All-ocean body: ocean_fraction_q = 100 everywhere, every district defaults
|
||||
// to BasinDirection::South here only because `district()`'s fixed default
|
||||
// happens to be South — the guard must pass regardless of the value, since
|
||||
// there is no land to cast a real D8 vote.
|
||||
let mut all_ocean: BTreeMap<SurveyCellPos, DistrictProfile> = BTreeMap::new();
|
||||
for x in 0..4 {
|
||||
for y in 0..4 {
|
||||
all_ocean.insert(
|
||||
SurveyCellPos(x, y),
|
||||
district(
|
||||
MorphologyZone::AlluvialPlain,
|
||||
10,
|
||||
0,
|
||||
50,
|
||||
100, // fully submerged — no land
|
||||
VegetationClass::Barren,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
let report = analyze(42, "all_ocean", &all_ocean, 64, 64, None);
|
||||
assert_eq!(
|
||||
report.contrast.land_districts, 0,
|
||||
"fixture sanity: an all-ocean body must report zero land districts"
|
||||
);
|
||||
let crit = evaluate_criteria(&report);
|
||||
let passed = |name: &str| crit.iter().find(|c| c.name == name).is_some_and(|c| c.pass);
|
||||
assert!(
|
||||
passed("basin direction variety"),
|
||||
"an all-ocean body must pass the basin-direction criterion vacuously, \
|
||||
not false-fail for having only one (defaulted) direction"
|
||||
);
|
||||
|
||||
// A body WITH land but a genuine all-North collapse (the actual regression
|
||||
// this criterion exists to catch) must FAIL.
|
||||
let mut land_all_north: BTreeMap<SurveyCellPos, DistrictProfile> = BTreeMap::new();
|
||||
for x in 0..4 {
|
||||
for y in 0..4 {
|
||||
let mut d = district(
|
||||
MorphologyZone::AlluvialPlain,
|
||||
(x * 20) as i32,
|
||||
0,
|
||||
50,
|
||||
0, // dry land
|
||||
VegetationClass::Scrub,
|
||||
);
|
||||
d.basin_direction = BasinDirection::North; // every cell defaults
|
||||
land_all_north.insert(SurveyCellPos(x, y), d);
|
||||
}
|
||||
}
|
||||
let report2 = analyze(42, "land_all_north", &land_all_north, 64, 64, None);
|
||||
assert!(
|
||||
report2.contrast.land_districts > 0,
|
||||
"fixture sanity: this body must have land districts"
|
||||
);
|
||||
assert_eq!(
|
||||
report2.contrast.basin_directions_distinct, 1,
|
||||
"fixture sanity: every district must collapse to the same direction"
|
||||
);
|
||||
let crit2 = evaluate_criteria(&report2);
|
||||
let failed2 = |name: &str| {
|
||||
crit2
|
||||
.iter()
|
||||
.find(|c| c.name == name)
|
||||
.is_some_and(|c| !c.pass)
|
||||
};
|
||||
assert!(
|
||||
failed2("basin direction variety"),
|
||||
"a land-bearing body with a genuine all-North collapse must FAIL this criterion"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -29,7 +29,9 @@
|
||||
"vegetation_classes": 4,
|
||||
"terrain_materials": 3,
|
||||
"voxel_relief_m": 28,
|
||||
"micro_habitat_distinct": 3
|
||||
"micro_habitat_distinct": 3,
|
||||
"land_districts": 698,
|
||||
"basin_directions_distinct": 2
|
||||
},
|
||||
"coherence": {
|
||||
"water_districts": 46,
|
||||
@@ -70,7 +72,9 @@
|
||||
"vegetation_classes": 3,
|
||||
"terrain_materials": 2,
|
||||
"voxel_relief_m": 22,
|
||||
"micro_habitat_distinct": 0
|
||||
"micro_habitat_distinct": 0,
|
||||
"land_districts": 1602,
|
||||
"basin_directions_distinct": 2
|
||||
},
|
||||
"coherence": {
|
||||
"water_districts": 19,
|
||||
|
||||
Reference in New Issue
Block a user