Commit Graph
16 Commits
Author SHA1 Message Date
jpmschweitzerandClaude Opus 5 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>
2026-08-08 10:01:16 +02:00
jpmschweitzerandClaude Fable 5 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>
2026-07-25 18:59:13 +02:00
jpmschweitzerandClaude Fable 5 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>
2026-07-25 13:08:26 +02:00
jpmschweitzerandClaude Fable 5 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>
2026-07-25 02:26:22 +02:00
jpmschweitzerandClaude Fable 5 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>
2026-07-25 00:40:13 +02:00
jpmschweitzerandClaude Fable 5 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>
2026-07-22 22:56:48 +02:00
jpmschweitzerandClaude Fable 5 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>
2026-07-17 08:21:57 +02:00
jpmschweitzerandClaude Opus 4.8 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>
2026-07-05 17:46:19 +02:00
jpmschweitzerandClaude Opus 4.8 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>
2026-07-04 20:30:33 +02:00
jpmschweitzerandClaude Opus 4.8 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>
2026-07-03 10:42:20 +02:00
jpmschweitzerandClaude Opus 4.8 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>
2026-06-28 21:43:39 +02:00
jpmschweitzerandClaude Opus 4.8 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>
2026-06-28 20:41:59 +02:00
jpmschweitzerandClaude Opus 4.8 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>
2026-06-28 17:41:03 +02:00
jpmschweitzerandClaude Opus 4.8 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>
2026-06-28 17:25:18 +02:00
jpmschweitzerandClaude Opus 4.8 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>
2026-06-28 15:30:25 +02:00
jpmschweitzerandClaude Opus 4.8 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>
2026-06-28 14:55:08 +02:00