fix(simulation): address PR #172 review — C1 over-vegetation + H1 biosphere gate (T-1084/T-1085)

Hoshe + Tyre review of the micro-habitat-mosaic branch requested changes on two
data-confirmed correctness bugs plus follow-through. All addressed.

Blocking:
- C1 (voxel.rs): the mosaic re-granted vegetation the climate withheld — a frozen
  ice world (Edict) read 61% vegetated tundra. The Grassland apply-gate now fires
  only where the climate already grants cover (!Barren); a climatically-barren
  district (frozen < -50C = surface ice/geology D-239 §2, or hyper-arid moisture<5,
  both resolved to VegetationClass::Barren upstream) is skipped. Genuine tundra
  (cold + moisture>=15) is Scrub upstream and still reaches the tundra palette via
  the same !Barren path. believability.json regenerated: Edict vegetated_districts
  39->0, Arbour 20->8 (its real cold-pole/arid districts revert to barren);
  intra-class variety preserved (Arbour vegetation_classes 3, micro_habitat_distinct 2).
- H1 (bodies.py): biosphere Gate 0 keyed on `inhabited`, conflating settlement with
  biosphere and force-Airless'ing uninhabited-but-alive worlds (D-247: worlds were
  alive before humans). Gate 0 is now settlement-independent — keyed on
  atmosphere/hydrosphere/planet_class. 24 uninhabited-alive worlds now classified
  (was 0); GJ0g-1 (dense atm + rivers) -> NativeMirror. Split 122 Compatible :
  121 Mirror; all 9 canon exemplars hold.

Follow-through:
- C2 (bodies.py + D-247): Gate 0 now reads planet_class (barren -> Airless) as
  D-247's "+ planet_class" phrasing names. D-247 amended to record the actual
  two-gate signal set (atm/hydro/planet_class habitability; economic_base_primary
  chirality; settlement-independence).
- C3 (believability.rs): micro_habitat_distinct criterion relaxed to `== 0 || >= 2`
  — the min-over-patches estimator makes K=3 unreachable against a dominant-entry
  palette; K=2 provisional, Q-123 calibrates.
- C4 + H2 (D-246): amended to record the v1 scope cut — only the Soil-derived
  vegetated/wet classes take the mosaic; material-driven families are `_ => false`
  so Hardpan/Scree are authored but unreachable in v1; no elevation change in v1;
  the mosaic OWNS the §8 climate->vegetation law for the classes it touches.
- H3 (voxel.rs): three dedicated mosaic-pass regression tests — C1 barren-respect,
  §8 material-untouched + forest-textured, T-1040 no-water-without-channel.
- H4 (voxel.rs): relief_signal comment corrected to ~[-1,+1].
- H5 (bodies.py): frontmatter override now strips quotes + validates against the
  4-value enum (warn-and-skip on typo).

systems.db regenerated + stamped (H1). believability golden regenerated (C1).
Full cargo test green; clippy -D warnings + ruff clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-05 17:46:19 +02:00
co-authored by Claude Opus 4.8
parent b71df601b2
commit c17b4f5442
9 changed files with 239 additions and 41 deletions
+16 -6
View File
@@ -113,10 +113,16 @@ pub struct ContrastMetrics {
/// traverses — not the single 64 m sample chunk, which is too narrow to register it.
pub voxel_relief_m: i32,
/// Minimum distinct micro-habitat axis-triples (terrain × vegetation × water) found
/// in any single sampled VEGETATED-land district (T-1084, D-246). The D-245 intra-class
/// variety screen: a vegetated patch must show ≥K distinct micro-features, never 100%
/// one — near 1 on the pre-mosaic uniform world ("Wetland 100%"), ≥3 once the mosaic
/// textures the class. Barren / water patches are excluded (legitimately uniform).
/// in any single sampled VEGETATED-land district (T-1084, D-246); `0` = no vegetated
/// patch was sampled (barren / ocean world). The D-245 intra-class variety screen: a
/// vegetated patch must show ≥K distinct micro-features, never 100% one — near 1 on the
/// pre-mosaic uniform world ("Wetland 100%"). Barren / water patches are excluded
/// (legitimately uniform). NOTE (PR #172, C3): this is a *minimum over patches* against
/// palettes with a dominant entry (e.g. dense stand 40/90), so a single 64 m chunk
/// often sits in the dominant bucket → the provisional floor is K=2 ("no vegetated
/// patch is 100% one micro-habitat"), the achievable, meaningful bar. The estimator
/// (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,
}
@@ -375,9 +381,13 @@ pub fn evaluate_criteria(r: &BelievabilityReport) -> Vec<Criterion> {
},
Criterion {
name: "intra-class variety",
pass: c.micro_habitat_distinct >= 3,
// 0 = no vegetated patch sampled (barren/ocean world — legitimately nothing to
// vary). Otherwise the provisional floor is K=2 = "no vegetated patch is 100%
// one micro-habitat" — the achievable bar for a min-over-patches estimator;
// ≥3 + the estimator are Q-123's to calibrate (PR #172, C3).
pass: c.micro_habitat_distinct == 0 || c.micro_habitat_distinct >= 2,
detail: format!(
"min {} distinct micro-habitats per vegetated patch",
"min {} distinct micro-habitats per vegetated patch (K≥2 provisional; Q-123 calibrates)",
c.micro_habitat_distinct
),
},