Commit Graph
2343 Commits
Author SHA1 Message Date
jpmschweitzerandClaude Opus 4.8 5cc4ff6c0c test(simulation): address PR #165 review (T-1031)
Hoshe review findings — close silent-pass gaps in the §8 drainage tests:
- assert_drainage_monotonicity now returns whether it actually checked (chunk
  had both wet and dry tiles); the three sweep tests (Alluvial/Meander/Braided
  Delta) assert at least one chunk exercised the law, so a regression that
  zeroes all channels fails loudly instead of passing vacuously.
- The fjord-floor test scans the full 64x64 chunk instead of a single Y=32 row
  and asserts the deep-water trough exists, so the sea-level floor law can no
  longer be skipped by a probe that missed the trough.
- Remove the unreferenced make_test_terrain_analysis helper (was behind
  #[allow(dead_code)] with a 'future use' comment — the maintenance trap the
  review flagged); make_dry_terrain_analysis covers the validation bodies.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 22:27:02 +02:00
jpmschweitzerandClaude Opus 4.8 de5f0f1e58 test(simulation): align T-1031 harness with D-240 class-envelope temps
Adapt the believability/budget verification harness to the T-1033 BodyParams
strip: validation-body fixtures (Kallast/Glødberg/Marevna) no longer set the
removed orbit/star fields (orbital_period_days, axial_tilt_deg, spectral_class,
star_type). Temperature is now derived from the planet_class envelope (D-240),
so the Marevna validation note/assertion is rewritten — oceanic band [-12,28]°C
+ maritime 0.6 + standard-atmosphere greenhouse yields ~+26°C at the equator
(was a stale ~-56°C orbit-equilibrium note). Add the seed→tile golden fixture
(tests/golden/derivation_harness.json) that the determinism regression locks.

Also fmt the harness and fix one clippy lint (iter().copied().collect() ->
to_vec()) — the file predated the pre-push gate's cargo-test/clippy coverage.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 19:35:58 +02:00
jpmschweitzer b8f8a5fb23 Merge remote-tracking branch 'origin/main' into verification-harness 2026-06-08 19:25:27 +02:00
jpmschweitzerandClaude Opus 4.8 a943147843 test(simulation): believability + budget verification harness (T-1031)
D-239 §1/§8/§9/§10 verification harness (server/tests/derivation_harness.rs):
golden-seed determinism regression, §8 binding-law sweeps (drainage monotonicity,
lithology->landform, glaciation->form no-glacial-U-at-grade-0, climate->vegetation
no-skip + riparian), per-family <5ms/chunk budget assertion, and validation-case
bodies (Kallast=alluvial pass; Velen/Gruenfeld skipped-not-in-wiki). Exposes
derive_morphology_zone as pub for the integration test.

NOTE: golden file not yet generated + fixtures predate the T-1033 BodyParams strip;
fixed in follow-up commits after merging main.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 19:25:18 +02:00
jpmschweitzerandClaude Opus 4.8 1897c0b450 chore(meta): T-1031 resume note (context reset handoff)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 19:22:10 +02:00
jpmschweitzerandClaude Opus 4.8 f34bcb431f chore(meta): T-1033 done (PR #164 merged) — class-envelope temperature
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 19:17:59 +02:00
jpmschweitzer 00fcb78988 Merge remote-tracking branch 'origin/class-envelope-temperature' 2026-06-08 19:14:50 +02:00
jpmschweitzerandClaude Opus 4.8 bafed6ad9a test+docs(simulation): address PR #164 re-review (maritime)
Re-review of the maritime moderation addition (Hoshe REQUEST_CHANGES, Tyre APPROVE):

- every_planet_class_derives_within_its_band now sweeps hydrosphere
  (none/ocean/liquid_water/rivers/ice) as well, so the maritime-compressed
  gradient path is covered by the band invariant — not just the None/1.0 case.
  (Hoshe #1, Tyre #1)
- Update the BodyParams.hydrosphere doc comment to the real systems.db vocabulary
  (liquid_water/ocean-coastal/extensive/etc.) the maritime table keys on. (Hoshe #2)

cargo test passes (the band sweep now ~59k in-band assertions), clippy -D warnings
clean, fmt clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 19:09:39 +02:00
jpmschweitzerandClaude Opus 4.8 b894a721ad feat(simulation): hydrosphere maritime moderation of temperature (T-1033, D-240)
Add the D-240 hydrosphere modulator: water-rich worlds compress the equator->pole
temperature gradient toward the band midpoint (milder at both ends); dry worlds
swing the full class band.

- [hydrosphere_maritime] table in climate_constants.toml + ClimateConstants
  field/method (maritime_factor). Keyed on the ACTUAL bodies.hydrosphere vocab
  (liquid_water/ocean/extensive=0.6, rivers/moderate=0.8, ice=0.85, subsurface*
  =0.9-0.95; minimal/trace/none/NULL -> 1.0).
- derive_temperature_c step 2 now lerps across a maritime-compressed sub-band
  (mid +/- band_half*factor) instead of the full band. Clamp still guarantees the
  class-band invariant.
- New maritime_hydrosphere_compresses_the_gradient test (ocean delta < dry delta).

Verified on real worlds: liquid_water/ocean temperate worlds now delta ~24 (milder)
vs dry ~40, all in-band. cargo test passes, clippy -D warnings clean, fmt clean.

Note: discovered derive_moisture_q has the SAME vocab mismatch (expects 'ocean',
DB uses 'liquid_water' for 175 bodies -> falls to default moisture). Pre-existing,
out of scope here — filing a follow-up.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 18:53:26 +02:00
jpmschweitzerandClaude Opus 4.8 54609eab1a test+docs(simulation): address PR #164 review (both APPROVE)
- Band-invariant test now sweeps high altitude (6 km) as well as sea level, so
  the lapse term + cold-end clamp are exercised jointly, not lat alone. (Hoshe #1, Tyre #3)
- Clarify the temp() helper comment: seed 0 is deterministic but still applies a
  constant non-zero nudge. (Hoshe #2)
- (Hoshe #3: confirmed tectonic_activity is genuinely absent from systems-schema.sql;
  the reader's 'not in schema' comment is accurate — no change.)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 18:36:41 +02:00
jpmschweitzerandClaude Opus 4.8 970bbb715e chore(meta): T-1033 -> review (PR for class-envelope temperature)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 18:30:14 +02:00
jpmschweitzerandClaude Opus 4.8 b6be9f5758 feat(simulation): planet_class temperature envelope, drop orbit/star inputs (T-1033, D-240)
Replace the sun-driven Stefan-Boltzmann temperature with the D-240 class-envelope
model. Temperature derives only from authored fields — no orbit/star physics.

- [planet_class_temperature] envelope table in climate_constants.toml (approved
  bands: frozen [-90,-25] .. hot_arid [20,58] .. volcanic [30,90]); cold_/hot_/
  warm_ prefix parsing; temperate fallback for unknowns.
- derive_temperature_c(params, constants, body_seed): band = envelope(planet_class);
  latitude lerps across it (equator=warm, pole=cold); atmosphere greenhouse +
  elevation lapse modulate within; small seed nudge for per-body variety; CLAMP to
  band — a body can never escape its class. Airless -> None.
- Delete the dead astrophysics: derive_distance_au, ClimateConstants::luminosity(),
  the [star_luminosity] table. Strip orbital_period_days/spectral_class/star_type/
  axial_tilt_deg from BodyParams + BodyParamsReader (read 3 cols from bodies, no
  star_systems join). DB columns left in place (no regen).
- New every_planet_class_derives_within_its_band test (13 classes x 5 atmo x 19 lat
  x 4 seeds, all in band) — the D-240 consistency guard.

Verified on 25 diverse real bodies: the worlds that derived to +356C now sit inside
their class bands (temperate capped at 28C). cargo test passes, clippy -D warnings
clean, fmt clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 18:28:24 +02:00
jpmschweitzerandClaude Opus 4.8 bf7da1105d docs(architecture): D-240 — registry orbit/star non-canonical; class-envelope climate (T-1033)
Record D-240: a body's orbital position and stellar assignment are placeholder
registry data with no authored physical intent, so no derivation may use them as
physical inputs. Climate derives from authored planet_class (temperature envelope)
+ atmosphere + hydrosphere + seed. Supersedes the sun-driven Stefan-Boltzmann
portion of D-239 §2, which produced +356 C 'temperate' worlds (NULL spectral_class
-> G-Sun default on an M-dwarf catalog).

File T-1033 under T-974: rewrite derive_temperature_c to the class-envelope model,
drop the orbit/star inputs, regen the T-1031 golden. Audit confirmed the blast
radius is one function (derive_temperature_c).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 18:06:49 +02:00
jpmschweitzerandClaude Opus 4.8 f519dc6e76 chore(meta): T-1030 done (PR #163 merged)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 17:34:05 +02:00
jpmschweitzer 66e5c7cc31 Merge remote-tracking branch 'origin/freeze-snow-model' 2026-06-08 17:32:30 +02:00
jpmschweitzerandClaude Opus 4.8 88b4323585 fix(simulation): address PR #163 review (freeze/snow model)
Hoshe found a CRITICAL coherence defect (Tyre APPROVE):

- CRITICAL: cluster_scatter received the per-voxel sub_chunk_seed as its cluster
  seed, so voxels in the same 6m cell got different scatter -> salt-and-pepper,
  not the §3-mandated clustered patches. Re-key on (world, body, cluster-cell):
  add SeedDomain::Cover=10 (pinned); cluster_scatter(world_seed, body_id, x, y)
  derives for_body(world_seed,body_id).derive(Cover, cluster_pair_id). derive_cover
  now takes (world_seed, body_id, ...). (Hoshe #1)
- The coherence test was tautological (constant seed bypassed the broken path).
  Rewritten to the production derive_cover signature in a cold-lake scatter band;
  it FAILED at 20% on the old code, passes 100% now. (Hoshe #2)
- Zigzag-encode cluster (cx,cy) before Cantor pairing (negatives were cast as u64
  directly); fix the misleading 'no collision' comment. (Hoshe #3, Tyre)
- Sea-ice band was inverted (~85% ice at the -2 onset). Now monotonic: ice grows
  ~8% (onset) -> ~92% (cold edge); leads (open gaps) layered only in the cold half
  via a 3x super-cell, passing the super-cell index directly. Dead depth==0 guard
  removed. (Hoshe #4, Tyre #1/#3)

cargo test passes, clippy -D warnings clean, fmt clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 17:30:48 +02:00
jpmschweitzerandClaude Opus 4.8 22f1fd9462 chore(meta): T-1030 -> review (PR for freeze/snow model)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 17:16:48 +02:00
jpmschweitzerandClaude Opus 4.8 ed7380245d feat(simulation): static scattered freeze/snow model (T-1030)
D-239 §3 — the static mean-state freeze/snow cover. New SeasonalCover
{None,Snow,Ice} overlay axis on VoxelColumn (D-228 cover, NOT TerrainMaterial),
derived after the family generator in derive_voxel_column.

- Spatially-COHERENT cluster scatter (never per-tile dice): coarse 6m cluster
  cells (div_euclid) -> Cantor pair -> splitmix64 ^ sub_chunk_seed, so voxels in
  a cell share the freeze decision -> ragged patches. All integer (D-010).
- Bands by surface (classify_surface from morphology_zone + water): freshwater
  +5..-10C; salt water (OpenOcean) -2C onset / -14C, 3x-coarser sheets+leads;
  land snow +2..-10C, moisture-gated (moisture_q<30 -> None). Linear frozen
  fraction across the band; permanent below the band (poles/glaciers).
- Airless (temperature_c None) -> cover None.
- Transient/clock-bound layer (dawn frost melting by noon) doc'd as a Q-105
  forward contract; only the static model is built.

16 new cover tests incl real spatial-coherence (>=90% intra-cluster agreement),
band edges per surface, moisture gating, determinism. cargo test passes, clippy
-D warnings clean, fmt clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 17:15:07 +02:00
jpmschweitzerandClaude Opus 4.8 8f83785c8f chore(meta): T-1029 done (PR #162 merged)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 16:44:27 +02:00
jpmschweitzer 93f94f8c38 Merge remote-tracking branch 'origin/morphology-geometry' 2026-06-08 16:42:48 +02:00
jpmschweitzerandClaude Opus 4.8 fb47f144f8 fix(simulation): address PR #162 review (morphology geometry)
Hoshe + Tyre CHANGES REQUESTED (§8 laws + D-010 confirmed clean):

- FjordWall floor 4+grade -> ~12m violated D-239 §9 (<=8m). Cap to
  glacier_grade.clamp(2,4) = 4-8m (still widens with glaciation, in-spec);
  add fjord_wall_floor_width_in_spec test. (Hoshe #1)
- BraidedDelta circular-distance wrap was one-sided (edge threads invisible).
  Fix to true modular distance: d.rem_euclid(64).min(64-d). (Tyre #1)
- BraidedDelta thread centres used correlated bit-slices of one u8 -> threads
  could merge. Derive 3 centres via independent splitmix64 passes (distinct
  salts) so separation holds across all phase values. Remove dead *64/64. (Tyre #2, Hoshe #4)
- Add N/S basin-direction guard asserts to the gorge + 2 fjord cross-section
  tests (were passing by seed luck). (Hoshe #2)
- meander_reach_stronger_sinuosity test was a tautology (|| elev_q!=elev_q
  always true). Rewrite: same elev_q, only morphology_zone differs, assert
  wet-tile sets differ -> fails if MeanderReach regresses to AlluvialPlain. (Hoshe #3)
- Fix FjordWall moraine + DuneStrand comments. (Tyre #3/#4)
- Lead: fix manual RangeInclusive::contains in the new fjord test.

cargo test passes (1457 lib), clippy -D warnings clean, fmt clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 16:40:38 +02:00
jpmschweitzerandClaude Opus 4.8 7c73e68827 chore(meta): T-1029 -> review (PR for morphology geometry generators)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 16:20:08 +02:00
jpmschweitzerandClaude Opus 4.8 311eabc51d feat(simulation): 7 specialized morphology geometry generators (T-1029)
D-239 §5/§8/§9 — replace the AlluvialPlain-fallback stubs with real per-family
geometry on the VoxelColumn pipeline. All integer (D-010); warp is the only f64.

- LavaField: Lava shield slopes + tube depressions, immature drainage (no deep water).
- FjordWall: Rock glacial U-valley — Deep-water floor, moraine band (grade>=1),
  near-vertical walls, cirques (grade>=2); floor half-width 4..8m (§9).
- CliffCoast: Rock vertical face at the water edge; plateau -> cliff -> splash -> ocean.
- BraidedDelta: Gravel, 3 braided threads (not single-thread), capped near sea level.
- DuneStrand: Sand, wind-aligned dunes at <=32deg angle of repose (integer ratio).
- IncisedGorge: Rock gorge, floor 2..8m wide (§9), near-vertical walls, single channel.
- MeanderReach: Soil single-thread meander (higher sinuosity than AlluvialPlain),
  thalweg below / levees above the waterline (§9 ElevationDelta); Wetland sub-zone.

§8 laws honoured: drainage monotonicity (mouths at sea level), lithology->landform,
glaciation->form (FjordWall U not V; grade-0 gated upstream at classification).
New helpers: compute_meander_reach_channel, in_levee_band.

53 family tests incl real geometry assertions (gorge floor width in [2,8]m, fjord
walls > floor, braided multi-thread, dune Sand). cargo test 1595 pass, clippy
-D warnings clean, fmt clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 16:13:40 +02:00
jpmschweitzerandClaude Opus 4.8 e6600c4a90 chore(meta): T-1028 done (PR #161 merged)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 15:18:37 +02:00
jpmschweitzer a0ed4fbef4 Merge remote-tracking branch 'origin/voxel-walking-skeleton' 2026-06-08 14:57:18 +02:00
jpmschweitzerandClaude Opus 4.8 841e222192 fix(simulation): address PR #161 review (VoxelColumn skeleton)
Hoshe REQUEST_CHANGES + Tyre APPROVE:

- Cache key omitted world_seed → a cache reused across worlds could return
  another seed's column. CacheKey is now (world_seed, body_id_hash, voxel_pos).
  (Hoshe #1)
- Sub-chunk voxel seed reused SeedDomain::ChunkContext (tier-collision risk vs
  the region meander seed). Add SeedDomain::Voxel = 9 (append-only, pin test
  updated) and use it. (Hoshe #2, Tyre #1)
- get_or_derive forced callers to pre-compute body_id_hash while fnv1a_64 is
  pub(crate). Drop the param; compute the hash internally. (Tyre #2)
- Fix two inaccurate comments (micro-relief range [-4,+3] not ±2; scatter mask
  is 4-bit [0,15] not bits [4:6]). (Hoshe #3/#4)
- Strengthen the LRU eviction test: add a test-only contains_voxel() helper and
  assert WHICH entry was evicted (refreshed pos survives, LRU pos evicted). (Hoshe #5)
- LRU O(capacity)-scan perf flagged on T-1031 (Tyre #3, deferred to the budget harness).

cargo test passes, clippy -D warnings clean, fmt clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 14:48:07 +02:00
jpmschweitzerandClaude Opus 4.8 0bcbc1573a chore(meta): note VoxelCache LRU perf on T-1031 (T-1028 review)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 14:47:56 +02:00
jpmschweitzerandClaude Opus 4.8 c40631aa53 chore(meta): T-1028 -> review (PR for VoxelColumn walking skeleton)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 14:38:12 +02:00
jpmschweitzerandClaude Opus 4.8 cd8bfec64b feat(simulation): VoxelColumn walking skeleton (T-1028)
D-239 §1/§7/§10 — the lower derivation chain end-to-end with the AlluvialPlain
fallback only (specialized families are T-1029).

- chunk_context.rs: ChunkContext (64m) — basin_direction + meander phase/wavelength
  + active-channel params. NO per-tile flow_direction[64x64] (D8 ~152m coarser than
  a chunk, D-239 §10); features >64m seed from Region-or-higher. SeedDomain::ChunkContext=8.
- voxel.rs: VoxelColumn (1m) composing the D-228 tile axes (TerrainMaterial /
  FloorMaterial=None / Vegetation / Water / elevation_m). Derive-on-demand + VoxelCache
  (LRU BTreeMap, never persisted per D-227). Domain warp (T-1026) wired through:
  f64 warp -> as-i32 truncation to the voxel address; all material/morphology gates
  integer (D-010 — the meander wavelength f64 is truncated before the Water decision).
- AlluvialPlain generator: Soil/Wetland terrain, climate vegetation, integer-meander
  channel (Shallow/Deep) from ChunkContext. The other 7 families are dispatch stubs
  (canonical terrain material, fall back to AlluvialPlain geometry) — no panic.

29 new tests incl end-to-end determinism (same seed/pos -> identical column),
cache hit/miss/eviction/re-derivation, warp-applied. cargo test 1563 pass,
clippy -D warnings clean, fmt clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 13:53:47 +02:00
jpmschweitzerandClaude Opus 4.8 de86281c4f chore(meta): T-1025, T-1027 done (PR #160 merged)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 13:27:13 +02:00
jpmschweitzer 211c16c334 Merge remote-tracking branch 'origin/climate-morphology-layers' 2026-06-08 13:25:39 +02:00
jpmschweitzerandClaude Opus 4.8 868da28192 fix(simulation): address PR #160 review (climate + morphology)
Hoshe REQUEST_CHANGES + Tyre APPROVE:

- Riparian vegetation logic was doubly-wrong: it granted the micro-oasis only
  in the impossible cold case (temp < -50, no liquid water) and DENIED it in the
  intended hyper-arid case. Split: extreme cold -> Barren always; hyper-arid ->
  RiparianScrub iff near perennial water. (Hoshe #2)
- morphology_zone_has_exactly_17_variants was misleading (asserted >=16). Rename
  to morphology_zone_region_scale_emits_16_of_17, tighten to ==16, and document
  that BraidedPlain is the lone region-unreachable zone (needs lithology, deferred
  to ChunkContext) and that Lake IS reachable. Tyre's 'Lake also deferred' was a
  false positive (ocean 60-79 -> Lake). (Hoshe #1, Tyre #1)
- derive_morphology_zone docstring now lists the real multi-path emission sites
  for TidalFlat/Wetland, ValleyFloor/RiverBank as their own gates, and BraidedPlain's
  deferral — the §6 parent-family names are descriptive, not exhaustive. (Hoshe #3, Tyre #2/#3/#4)
- D-239 record: added a T-1025/T-1027 implementation note (enum freeze location,
  16/17 region reachability + BraidedPlain deferral, §7 gate-ordering interpretation).

No vocabulary change. cargo test passes, clippy -D warnings clean, fmt clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 13:24:13 +02:00
jpmschweitzerandClaude Opus 4.8 8865cfd0a2 chore(meta): T-1025, T-1027 -> review (PR for climate + morphology)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 13:14:10 +02:00
jpmschweitzerandClaude Opus 4.8 961855f276 feat(simulation): climate-derived fields + frozen 17-zone morphology (T-1025, T-1027)
T-1025 (D-239 §2) — climate-derived fields, all from the temperature(+moisture)
primitive:
- precipitation_class + glaciation_grade re-keyed to (temperature_c, moisture_q)
  inputs (were keyed off raw body params); river_threshold signature follows.
- New VegetationClass (Absent/Barren/Scrub/Forest/RiparianScrub/RiparianThicket)
  + derive_vegetation: treeline bands x elevation, structural Forest->Scrub->Barren
  no-skip, riparian 1-3 tile band; airless (temp None) -> Absent.
- 21 tests.

T-1027 (D-239 §5/§6/§7) — morphology classifier:
- FROZEN 17-zone MorphologyZone enum exactly per D-239 §6 (OpenOcean..Wetland,
  repr(u8) pinned). Removed legacy Sea/CoastalLowland/Island/Canyon/Unknown;
  all consumers (skeleton_gen street_topology) remapped to nearest D-239 zone.
- 8-family gated decision tree (LavaField..AlluvialPlain fallback) over integer
  inputs; hard gates: Fjord>=GlaciationGrade2, LavaField=Volcanic tectonic,
  lithology slope/form laws (§8). 4 sub-classification zones (TidalFlat,
  Estuarine, Alpine, Wetland) derived from family + elevation/water.
- Build-time compatibility-matrix invariant tests (§7): MeanderReach<->Volcanic
  and Volcanic<->Fjord forbidden adjacencies structurally prevented by gate order.
- 13 tests incl 17-variant completeness + discriminant pinning.

D-010 integer discipline throughout. cargo test 1534 pass, clippy -D warnings
clean, fmt clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 13:12:34 +02:00
jpmschweitzerandClaude Opus 4.8 bca80617e6 chore(meta): T-1032 done (PR #159 merged)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 12:53:51 +02:00
jpmschweitzer 17f8e87e5a Merge remote-tracking branch 'origin/region-profile-dispatch' 2026-06-08 12:51:52 +02:00
jpmschweitzerandClaude Opus 4.8 0a8933fbcc test+docs(simulation): address PR #159 review (T-1032)
- Hoshe: body_without_system_row test inserted a NULL system_id, impossible
  under production schema (system_id NOT NULL REFERENCES star_systems). Rewrite
  as body_with_orphan_system_id_* — non-NULL system_id with no matching
  star_systems row (the real case the LEFT JOIN guards) + NOT NULL in the test
  schema + corrected comment.
- Tyre: cascade.rs PERF/TODO comment said the region path 'defers to T-1032';
  T-1032 IS this PR, so production dispatch is now live. Update to track T-1028
  only and note the cost is live in production.

No production logic change. cargo test body_params_reader 7 pass, clippy clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 12:50:35 +02:00
jpmschweitzerandClaude Opus 4.8 935d164aa3 chore(meta): T-1032 in_progress -> review (PR #159)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 12:38:28 +02:00
jpmschweitzerandClaude Opus 4.8 1887c886ef feat(simulation): dispatch RegionProfile layer in production (T-1032)
The D-239 carrier layer (T-1023/1024/1026) only ran in tests because every
production AnalyzeBody enqueue passed body_params: None. Wire the real path:

- New BodyParamsReader (server/src/atlas/body_params_reader.rs): read-only
  systems.db reader, joins bodies -> star_systems (LEFT JOIN) for the climate/
  tectonic inputs. SQL verified against systems-schema.sql. All fields Option,
  NULLs handled; tectonic_activity absent from schema -> None (derives from
  planet_class). 5 unit tests.
- layer_proxy.rs: on cache miss, read the body's params and pass
  Some(Box::new(..)). On read error, warn + fall back to None (cascade stops at
  Settlement, no panic) — graceful degradation.
- plugin.rs / main.rs: register BodyParamsReaderResource (CityContextReader
  pattern) and thread it through serve_atlas_requests.

BodyWorldState.regions now populates for real bodies in the D-206 background
pass. End-to-end tests cover wired (regions populated) + unwired (empty) paths.

cargo test 1504 pass, clippy -D warnings clean, fmt clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 12:28:01 +02:00
jpmschweitzerandClaude Opus 4.8 a516b06de9 chore(meta): T-1023/1024/1026 done (PR #158 merged)
D-239 three-carrier foundation merged to main. Review found a correctness
bug (per-region elevation) + hollow determinism tests, both fixed before merge.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 11:25:34 +02:00
jpmschweitzer b883b31c67 Merge remote-tracking branch 'origin/tile-derivation-carriers' 2026-06-08 11:23:05 +02:00
jpmschweitzerandClaude Opus 4.8 7084a41013 docs(simulation): fix stale elevation comment in derive_all_regions
Re-review (Hoshe + Tyre, both APPROVE) caught one stale comment: after the
per-region elevation fix, derive_region_profile owns elevation_km (from elev_q),
not the caller. Update the comment so maintainers don't read it as caller-supplied.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 11:21:35 +02:00
jpmschweitzerandClaude Opus 4.8 95f26ae3e9 fix(simulation): address PR #158 review (carrier foundation)
Hoshe + Tyre review (CHANGES REQUESTED):

- domain_warp golden tests were hollow (discarded values, only asserted
  dx!=dy). Consolidate into one real golden_vector test with pinned f64
  literals as the regression anchor. (Hoshe #1, Tyre #2)
- Per-region temperature used body-level elevation_km for every region, so
  alpine and sea-level regions on a body got identical lapse — defeats the
  D-239 §2 per-district temperature. Derive elevation_km per region from the
  region's own elev_q (× MAX_REGION_ELEVATION_KM). (Tyre #1)
- Region seed was derived under SeedDomain::DomainWarp (collision risk with
  the tile warp) and discarded unused. Remove it + the orphaned region_pos_id
  and SeedDomain import; keep a reserved _seed param for T-1027/T-1028. (Hoshe #2)
- Fix inverted tilt_factor comment. (Hoshe #3)
- ClimateConstants doc referenced a load() that doesn't exist; correct it —
  embedded default() is authoritative today, climate_constants.toml is the
  canonical mirror, runtime load lands with T-1032. (Hoshe + Tyre)
- cascade.rs: drainage re-run was mislabeled 'cheap'/'no drainage needed';
  document the real cost + PERF/TODO(T-1028/T-1032) against the D-239 §10
  budget. (Tyre #3)

cargo test 1497 pass, clippy -D warnings clean, fmt clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 11:10:32 +02:00
jpmschweitzerandClaude Opus 4.8 b4eef33e7e chore(skills): whats-next recommends clearing open PRs before new work
Add step 1a: check open PRs first and recommend /pr-review (review -> merge)
before selecting a batch. Open PRs are in-flight WIP; starting new work on top
piles up the board, and the cascade-correct next batch is often dependency-gated
on an in-review PR (won't show as --unblocked, or must stack on an unmerged
branch). Renumber the existing 1a-1d substeps to 1b-1e.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 10:53:51 +02:00
jpmschweitzerandClaude Opus 4.8 c318cea6db chore(config): gate cargo test in pre-push on Rust changes
Add `cargo test --quiet` to the pre-push Rust block (sharing clippy's
target/ guard) so the suite runs automatically on every push touching
server/. Nothing ran the tests before — pre-push did only fmt/clippy/deny
and there is no CI — so a Rust regression could reach main unverified.

Document the resulting agent-spawn rule in team-patterns.md: don't have
implementation agents pre-run fmt/clippy/test pre-emptively, since the push
gate now enforces all three. The gate is authoritative; the lead patches any
fallout at push.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 10:39:55 +02:00
jpmschweitzerandClaude Opus 4.8 71a0544622 chore(meta): T-974 carriers -> review (PR #158); file T-1032 dispatch follow-up
T-1023/1024/1026 implemented and pushed as PR #158; moved to review.
T-1032 (new, under T-974) tracks wiring the production AnalyzeBody dispatch
to read BodyParams from the DB — currently always None, so the carrier layer
only runs in tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 10:29:34 +02:00
jpmschweitzerandClaude Opus 4.8 def70eaf37 feat(simulation): D-239 three-carrier foundation (T-1023/1024/1026)
First foundation slice of the Atlas-to-tile derivation model (epic T-974),
building the carrier layer ahead of its T-1027+ consumers.

T-1026 — Anti-squaring domain warp (D-239 §4): stateless pure
fn(seed,body_id,pos)->(f64,f64), ±8m, f64 to the final voxel then as-i32
truncation for IEEE-754 cross-target determinism. New domain_warp.rs,
SeedDomain::DomainWarp; golden-vector + cross-thread tests. Position math
only — D-010 integer discipline preserved downstream. Marked dead_code
until the T-1028 VoxelColumn pipeline consumes it.

T-1023 — RegionProfile carrier (D-239 §1,§10): new RegionProfile +
TectonicClass/GlaciationGrade/PrecipitationClass enums + BodyParams; derived
per-region river_threshold replacing the global 200 for tile consumers.
regions: BTreeMap on BodyWorldState, populated via the cascade's new
RegionProfile layer (runs when body_params is Some, else falls back to
Settlement). D-010 integer discipline, BTree ordering.

T-1024 — District climate primitives (D-239 §2): nullable temperature_c +
moisture on RegionProfile, mean-annual scalar (no clock dep; dynamic branch
deferred to Q-105). Hybrid inputs — new bodies.axial_tilt_deg column imported
from planet-gen body-defs (populate_axial_tilt_deg, 2611 bodies), luminosity
and orbital distance derived at runtime; greenhouse + diurnal-swing tables in
source-canonical climate_constants.toml. D-239 implementation note added.

cargo test: 1498 passed, 0 failed. clippy clean (pre-existing
large_enum_variant only). make check-systems-db: stamp fresh.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 09:28:31 +02:00
jpmschweitzerandClaude Opus 4.8 b7b4626035 chore(meta): T-1022 done; activate T-974 carrier trio (T-1023/1024/1026)
PR #157 merged -> T-1022 done. Activate the D-239 three-carrier foundation
batch via /whats-next: T-1023 (RegionProfile), T-1026 (domain warp), and
T-1024 (district climate) with refinement notes. T-1024 blocked-by T-1023
(temperature fields live on the RegionProfile struct).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 18:47:09 +02:00
jpmschweitzerandClaude Opus 4.8 ff42dc2241 chore(meta): remove stale PROJECT_STATE.md
The file was last updated 2026-04-05 (Sprint 32) and had gone
comprehensively stale: it claimed Phase 1 active / Sprint 32 current,
listed D-001..D-170 (now D-239), and showed the pre-D-166 phase
ordering (player control before world gen, with a 2-floor test map) —
directly contradicting the canonical cascade in CLAUDE.md. All of its
content is canonical elsewhere (cascade in CLAUDE.md, phase + decision
status in pql/governance), and no briefing references it anymore.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 18:47:09 +02:00
jpmschweitzerandClaude Opus 4.8 c395ca1e1a chore(meta): realign repo config after directory move
The repo moved to /var/mnt/data/projects/settled-reach (flat layout,
no more /main worktree subdir). Drop the stale autoMemoryDirectory
override (pointed at the old /home path; revert to the native
per-slug memory store) and gitignore .worktrees/, which now holds
per-machine git worktrees under the repo root.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 18:47:09 +02:00