6b31111cd215ff0d3cee5cfe9dfd97e69f6630b6
16
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
6cfd829445 |
feat(simulation): sub-cell composition — a summarised cell can contain its minority (T-1213)
D-258 invariant 2: descending the ladder must reveal COMPOSITION, so a cell reading "forest" globally contains the clearings, marsh, rock and scrub the vote suppressed. Below Global it contained nothing: morphology carried NINE zones at Global and exactly ONE (AlluvialPlain) at every rung under it, and vegetation collapsed to one class from District down. WHY THE EXISTING TIERS COULD NOT DO IT. vegetation_invention already perturbs moisture with a massif band and a texture band — but that pair was built for cross-rung coherence and is weighted 70/30 specifically so "the texture term alone can never outweigh the massif term". It is designed NOT to change a verdict, which is the exact opposite of what composition needs. And it could not simply be turned up. Measured: 50.2% of the texture field's amplitude sits in its 32,768 m octave alone, and everything at or below 2,048 m holds 5.9% of the total. Across a District window only that 5.9% varies, which after the 30% weight and a ~29-point ceiling swings moisture by +/-0.51 points against vegetation gates 5-15 points apart. Nothing could ever cross one. That is the geometric series, not a tuning shortfall — raising the ceiling enough to matter at District would make the field violent at Region. So a third tier carries the fine band ALONE, normalized to its own full swing: quiet where the coarse tiers are loud, loud where they have nothing left to say. It feeds BOTH classification inputs, because moisture alone would have left morphology just as flat. CONSERVATION IS THE BOUND, not weighting (D-258 invariant 3). The field is zero-mean, so a downsample returns the summary it was added to. Pinned two ways: a field-level zero-mean test, and a real-terrain test that derives a District-sized patch and asserts the majority vegetation class survives. RARE INCLUSIONS, and this was a correction. The smooth term is a gentle sway around the base, so it can only flip a verdict where the ground already sits near a gate — which made deep-in-class ground immune, and the conservation test duly measured a patch that was 100% Forest. A monoculture is the flat map this ticket exists to fix, one scale down. Jeroen: "maybe a dense forest should still sometimes produce a clearing or a rocky outcropping." D-258 says CONTAIN, not border on. A sparse high-contrast term now rides on top — thresholded value noise so inclusions are connected blobs rather than stray speckled cells. The same patch now reads 98.9% Forest with 1.1% Barren outcrops. The moisture half of an inclusion obeys the envelope rule (a world with no patchiness ceiling grows no glades — caught by the zero-ceiling test, which the first version failed by putting damp pockets on airless rock); the slope half does not, because an outcrop is geology and a dead world is exactly where bare rock should break the surface. The slope ceiling is 6, not the 15 first written. Measured against the window-derivation fixtures, base slope_q on ordinary ground is 2-6, so +/-15 did not vary the signal but REPLACED it — one fixture moved 6 -> 19 and two coastal samples flipped to Wetland on invented slope alone. The morphology gates are far apart because a cliff coast is a real landform; composition must let marginal ground fall both ways, never manufacture a fjord on a flood plain. NOT applied at the orbital rung, which is envelope-only by design and documents that it never invents slope — pinned by derive_orbital_at_metres_never_invents_slope, which caught the first version. Both goldens move in the IMPROVING direction, checked before updating rather than blind-refreshed: GJ338Bd moisture 75->85 distinct, slope 28->34 (range 0-50), materials 3->4 GJ244Ad moisture 25->42, slope 15->22, morphology zones 6->7, materials 2->3 Ladder effect (was -> now): Region moisture 25->39; District moisture 3->17 and vegetation 1->2; Quarter moisture 3->8. 45 server suites green, clippy clean. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
e141a595b1 |
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> |
||
|
|
07f0fa307f |
fix(simulation): region baseline latitude — equator-anchored signed rows (T-1186)
region_centre_latitude_deg mapped row 0 to the north pole with lat_frac clamped [0,1] while the derive core floor-divides equator-anchored signed world metres — every northern-hemisphere region clamped to +90 (polar everywhere) and the southern hemisphere read as compressed northern tropics. Now mirrors the derive core's exact inverse mapping (lat_frac = centre_y/meridian clamped [-0.5,0.5], lat = -frac*180). The ticket's in-the-wild datapoint flips as predicted: GJ338Bd region (136,43), old baseline +13.94N/26.8C -> new -76.06S/10.3C; the 76S district cell now derives Lake/2.07C/Light glaciation. Goldens regenerated (believability + window derivation, stable on rerun); two region_profile unit tests repositioned — their probe coordinates meant different places under the old convention. step_canvas rung-0 already used the correct signed convention; layer_proxy's pole-anchored pseudo-grid stays deferred to T-1181's rung-0 rebuild per D-256(f). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
24fad7090f |
feat(simulation): lakes from settled hydrology (D-227, T-1184)
Productionizes the T-1177 equilibrium solver: run_layer1 now solves hydrology once per body (~24ms, mirrors drainage::analyze) and carries it as TerrainAnalysis.hydrology; run_layer1_with_moisture threads the real body moisture ceiling (extracted derive_moisture_ceiling_q), with the T-1177 population-survey default as fallback. The resident rung-0 global tier does not exist yet (T-1181's scope) — hydrology rides TerrainAnalysis and lands in that tier for free when it is built (deviation recorded on the ticket). MorphologyZone::Lake is now sourced from the settled solver at derive time: a gridunit is Lake when bilinear-sampled filled surface exceeds bilinear-sampled original elevation at the sample's own (px, py) — the continuous comparison, so lake edges refine with rung like coastlines; never a discrete basin-cell projection. The gate sits strictly between OpenOcean (>= 80) and the old ocean_fraction heuristic (>= 60), which survives as the derive-fresh fallback when no solve is attached — byte-identical to pre-T-1184 output in that case. Static classification, distinct from the sim-state flooded plane; no endorheic bit (the drains-vs-closed cue is T-1185's outlet-course presence, per the D-227 amendment (4) sequencing). Zero new wire bytes. Acceptance: lake_classification_cache_hit_equals_cache_miss (solve twice independently, byte-identical zones, non-vacuous Lake hit) plus hydrology determinism tests. Golden fidelity: the window golden fixture now builds TerrainAnalysis through the production entry point (run_layer1_with_moisture, per-body), and a dedicated lake_bowl golden body pins the hydrology-sourced Lake path (morphology 1 at ocean_fraction_q 0 — provably not the heuristic); the 108 pre-existing golden rows are byte-identical (pure append). believability.json moved by one lake-shaped line (GJ338Bd voxel_relief_m 27->28, a correctly reclassified lake district leaving the dry-relief sample set). river_course and derivation-harness goldens unchanged. Full suite: 2114 passed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
933e1f4ee4 |
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> |
||
|
|
d33256a8ba |
test(simulation): regenerate believability golden — deliberate T-1162 output change
The octave extension changes derived window output by design (coast crinkle below 16384m, voxel relief at Quarter, vegetation moisture perturbation) — this regen records the sanctioned new baseline per the ticket's part (d) discipline. The pre-existing BELIEVABILITY_STRICT=1 'vegetation present' advisory failure predates this change (Q-123- tracked debt) and is unaffected. Tickets: T-1162 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
aa1471069b |
test(simulation): derivation-harness call sites + believability golden regen for coastline invention
Mechanical call-site updates (7) for the invent_primitives signature; believability golden regenerated via UPDATE_GOLDEN=1. Deltas are deliberate: slope_q/elev_q spreads widen, vegetation_classes +1 (Marine), water-districts-wet coherence reaches 46/46 and 19/19 (T-1082 class closed — classification and coastline are the same line). Reductions (ocean_fraction distinct, morphology_zones on GJ244Ad) are the eager pseudo-grid point-sampling coasts honestly instead of area-averaging them into synthetic intermediates; believability coast-sampling resolution is Q-123 calibration territory. All 37 derivation-harness law checks unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
c17b4f5442 |
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> |
||
|
|
5fb34675eb |
feat(simulation): grassland biome-awareness + alien-ecology vocab (T-1085 workstream 4, D-246)
The mosaic palette gains a climate-biome dimension for the Grassland surface-class: savanna / temperate / boreal / tundra now read distinctly rather than collapsing to one biome-blind palette (the D-246 biome-awareness fix). - atlas/mosaic.rs: ClimateBiome (from temperature_c + moisture_q) + four biome-keyed Grassland palettes; palette(class, biome). Savanna carries scattered Forest copses, tundra carries lichen + sparse bare ground and no forest. §8-safe (veg + water only). - atlas/voxel.rs: derive the biome; a cold barren district (tundra/boreal) now takes the sparse mosaic rather than staying blank — worlds that read "0 vegetated / blank" now read structured-sparse (D-245 climate-appropriateness). vegetated_districts 8→20 and 0→39 on the cold validation bodies. - data/mosaic_constants.toml: biome-keyed grassland mirror. - docs/design/alien-ecology-vocabulary.md: Miri's full biome × register naming layer (the cane/vane/wrack/husk/drum-root native lexicon + Earth-register names) — the derived-label source for the palette and Phase-5 rendering. Believability golden regenerated. Full server suite green. Forest biomes and the introduced-Earth register are the noted continuation. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
31b553a3b3 |
feat(simulation): intra-class micro-habitat mosaic v1 — vegetation/water texture (T-1084, D-246)
Sub-chunk mosaic that modulates the D-228 axes into a spatially-coherent,
relief/moisture-conditioned mosaic of micro-habitats within a terrain class —
the fix for the aliveness probe's uniform "Wetland 100%".
- seed.rs: SeedDomain::VoxelMosaic = 12 (append-only; pinned-discriminant guard)
- voxel.rs: five new D-228 axis values (Vegetation::{Meadow,Deadfall,Lichen},
TerrainMaterial::{Hardpan,Scree}); the per-family-gated mosaic pass
- detail_scatter.rs: voxel_mosaic() selection field (~8-64 m band)
- atlas/mosaic.rs: surface-class palette + integer-basis-point weighted selection
with moisture-affinity conditioning; temperate/native baseline palettes
- data/mosaic_constants.toml: source-canonical palette mirror
- believability.rs: micro_habitat_distinct metric + D-245 intra-class criterion
v1 scope (D-246-faithful): modulates vegetation + water only, in the vegetated
classes (Wetland/Forest/Grassland), so the D-239 §8 lithology law is untouched;
water is gated on the T-1040 has_active_channel hydrology rule. Material variants
(hardpan/scree) and the extreme classes are a §8-aware follow-up; the biome-aware
palette variants (T-1085 vocab) extend the baseline before generation.
Goldens regenerated (believability + derivation). Full server suite green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|
|
677de42bd2 |
fix(simulation): make voxel relief sub-district + fix integration-test fallout (T-1081)
The push gate's integration tests (not in cargo test --lib) caught two regressions from the relief change: - derivation_harness::cross_district_elevation_blend_reduces_seam_step — the relief's large per-position term (span 300 → ±200 m, far above the compressed elev_q/2 base) swamped the T-1042 seam measurement and clamped heavily at sea level. Fixes: (1) shift the voxel-relief octave band to 0.13–1 km (all sub-district, dropping the 2 km octave that competed with elev_q's district role); (2) reduce VOXEL_RELIEF_SPAN_M 300 → 100 so relief stays mostly below the base (fewer sea-level clamp artifacts, proportional hills); (3) rewrite the seam test's avg_elev to average over an 8 km multi-wavelength y-transect so the zero-mean relief cancels, isolating the base seam. - derivation_harness::golden_seed_determinism_regression — legitimate golden refresh (determinism still holds; elevation values changed intentionally). Believability relief now ≈22 m mean (was 5 m flat; 59 m at the over-aggressive span 300) — navigable hills without clamp artifacts, 7/8 criteria. Both goldens regenerated; full cargo test (38 binaries) + clippy --all-targets -D warnings green. D-239 amendment + Q-123 item 4 updated to the final span/octave/numbers. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
ab6e1413d9 |
feat(simulation): voxel-tier mid-scale relief — navigable hills (T-1081)
The voxel tier read flat (the D-245 "0–3 m, no hills to navigate by" bug): family generators set elevation from elev_q at a compressed scale plus only ±4 m micro-scatter, and detail-scatter's mid-scale relief (D-243 §2) only ever reached the district tier (elev_q), never per-voxel elevation_m. - detail_scatter.rs: extract the enveloped-fBm core; add `voxel_relief` at the 0.25–2 km octave band (vs the district 4–40 km band). - voxel.rs: add the mid-scale relief post-dispatch in derive_voxel_column, body-global SeedDomain::VoxelRelief seed (position-keyed), f64 truncated to integer metres (D-010). Envelope = slope_q*3 + elev_q — the coarse heightmap gives slope_q ≈ 0 even on high ground (Arbour max 13), so elevation must drive ruggedness. Flat families only (Alluvial/Lava/BraidedDelta/Dune/Meander); the dramatic families already carry strong internal relief and WaterBody stays at sea level. - seed.rs: SeedDomain::VoxelRelief (D-224 domain separation). - believability.rs: new `contrast.voxel_relief_m` metric — mean within-district elevation range over a 2 km transect (a single 64 m sample chunk is narrower than the relief band) + a "voxel relief" criterion. Arbour @ yolo: voxel relief 5 m → 59 m, 6/8 → 7/8 criteria (remaining fail = the Q-123 vegetation-denominator item). Edict 59 m. Golden regenerated; 1586 lib tests + believability harness (determinism) pass; clippy -D warnings clean. D-239 amended (T-1081); Q-123 item 4 updated. Deferred to Q-123/follow-up: the provisional span + threshold, and a per-body hypsometric absolute-elevation model. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
f771c9ce4e |
fix(simulation): address believability-stack review — all findings processed
Stack review (Hoshe + Tyre) of T-1083+T-1082+T-1080. Every finding fixed or disposed: - believability.rs sample_indices: replace the rejection-sampling loop (could stall when n ≈ take) with deterministic partial Fisher-Yates — O(n), guaranteed termination, distinct, sorted (Hoshe+Tyre). - believability.rs drainage proxy: exclude water-body districts (all elev 0, no banks) and require both wet + dry voxels — they were passing vacuously and inflating the metric (Hoshe). - believability.rs read_cities: log skipped malformed rows instead of dropping silently (Hoshe). - voxel.rs: add the 3 WaterBody zones to all_families_no_panic_at_extreme_positions + fix the "7 families" comment (Hoshe). - climate_constants.toml: bold warning that [moisture_gradient] is not loaded until T-1032 — tune ClimateConstants::default() (Tyre). - Q-123: record the per-zone "water renders wet" threshold + the land-relative vegetation-present denominator as calibration items (Tyre + the open 7th criterion). - T-1083 ticket: note the sampling-fix attribution (landed in the T-1082 commit). Believability golden regenerated (sampler + drainage fixes moved the metrics). clippy --all-targets -D warnings clean; 1580 lib tests + harness pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
bb5069aa13 |
feat(simulation): district moisture spatial gradient (T-1080)
moisture_q was a single body constant (derive_moisture_q took only &BodyParams → 80 for every one of 2048 ocean-world districts), so vegetation/terrain/ecotones were uniform — "nothing to fuzz" (the T-1080 believability bug). - district_profile.rs: derive_moisture_q is now a body ceiling (hydrosphere+atmosphere) × per-district gradient — latitude (equator wet → pole dry), elevation (orographic/ rain-shadow), continentality (100 − ocean_fraction_q). Integer/D-010, no new plumbing (elev_q/ocean_fraction_q/latitude_deg already reach build_district_profile). Mirrors D-240's temperature model. Coefficients in ClimateConstants + climate_constants.toml [moisture_gradient] (provisional; Q-123 calibrates). Tuned so a wet body stays mostly green with drier patches and a frozen body clamps mostly barren. + gradient unit test. - region_profile.rs: region-tier moisture gets the region-latitude gradient (elevation/ continentality are district-scale). - Propagates to precipitation_class / vegetation_class / morphology_zone (all read moisture_q). D-239 §2 amended. Believability golden regenerated. Probe (Arbour @ yolo): moisture_q distinct 1 → 49 (spread 0 → 48); 5/7 → 6/7 criteria. Edict (frozen): moisture 0..20 ×21 — gradient within its low ceiling. Remaining fail (vegetation-present) is the metric dividing by all-sampled incl. water on a 2/3-ocean world — a Q-123 calibration concern, not a climate defect. clippy --all-targets -D warnings clean; 1580 lib tests + harnesses pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
cdc55032df |
feat(simulation): WaterBody voxel family — oceans/lakes/tidal flats render wet (T-1082)
The water zones (OpenOcean/Lake/TidalFlat) fell through to the dry-land AlluvialPlain fallback, so the sea rendered as dry forested land (the D-245 believability bug). - voxel.rs: new MorphologyFamily::WaterBody (9th family) + generate_water_body, dispatched from zone_to_family. Deep open water with a Shallow shoal band on the district-anchored coast line (wider for shallower bodies); TidalFlat all-Shallow. Seabed Rock (steep) / Sand (gentle) / Wetland (tidal mud); Vegetation::Barren; water surface elevation_m = 0; seasonal Ice via derive_cover (frozen seas). Wetland stays AlluvialPlain (it is land — a marsh, not open water). Integer/D-010. + 4 tests. - believability.rs: fix a sampling bias in the T-1083 enforcer found while verifying this — the metrics sampled the first 64 districts in BTreeMap order (a spatial corner, e.g. all-ocean), which reported a forested world as "0 vegetated". Now a deterministic seeded spread across the body (matches D-245's "randomly-sampled locations"). - D-239 amended (§5 8→9 families; §6 refined — the 3 water zones now dispatch to WaterBody). Believability golden regenerated. Probe (Arbour @ yolo): water-renders-wet 4/64 FAIL → 42/44 PASS; terrain-material variety 1 → 4 PASS; 3/7 → 5/7 criteria. (Remaining fails — moisture gradient, vegetation-present — are T-1080.) clippy --all-targets -D warnings clean; 1579 lib tests + the harness pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
91a079718b |
feat(simulation): believability test protocol — D-245 enforcer (T-1083)
Promote the throwaway aliveness probe into a committed, repeatable believability protocol — the instrument that found T-1080/T-1081/T-1082. - atlas/believability.rs (new): BelievabilityReport (serde) + analyze() computing CONTRAST (per-field min/max/distinct for moisture/elev/slope/ocean over all districts; distinct morphology zones / vegetation classes / terrain materials) and COHERENCE (water-renders-wet, drainage-monotonic, vegetation-present) — never marginal per-tile counts (the lesson: that called a broken uniform world ALIVE). evaluate_criteria() = advisory D-245 checks; cascade_for_body()/seed_to_u64() loader shared by the bin and the harness. Unit tests prove the metric tells a uniform world (fails) from a varied one (passes) + determinism. - bin/aliveness_probe.rs: refactored to a thin CLI over the module — prints the body-level report + advisory D-245 criteria, drops the naive per-tile verdict. - tests/believability_harness.rs (+ golden): runs the real cascade for Arbour (temperate/ocean) + Edict (frozen/ice), asserts determinism, golden-snapshots the reports (regression — updates when T-1080/T-1082 land), advisory criteria with BELIEVABILITY_STRICT=1 to fail on unmet D-245 criteria. Skips if committed data absent. x86_64 golden (cascade has f32 warp paths). Baseline @ believability-v1: Arbour 3/7, Edict 3/7 criteria pass — moisture gradient, water-renders-wet, drainage all FAIL (T-1080/T-1082); Edict vegetation 0/64 (blank tundra — the frozen 'reads dead' case D-245 targets). PNG layer maps (ticket item 3) deferred — explicitly optional; the contrast + coherence metrics are the core enforcer. clippy --all-targets -D warnings clean; 1575 lib tests + the harness pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |