feat(simulation): climate-derived fields + frozen 17-zone morphology (T-1025, T-1027) #160

Closed
jpmschweitzer wants to merge 0 commits from climate-morphology-layers into main
Owner

Summary

The D-239 region-derivation chain on RegionProfile: T-1025 (climate-derived fields) → T-1027 (frozen morphology vocabulary + classifier). Both derive from the existing temperature/moisture primitives; no authored inputs (D-239 "no authoring at the derivation layers").

T-1025 — Climate-derived fields (D-239 §2)

  • precipitation_class and glaciation_grade re-keyed to take (temperature_c, moisture_q) as direct inputs (previously keyed off raw body params) — everything climatic now flows from the temperature primitive. river_threshold signature follows.
  • New VegetationClass (Absent/Barren/Scrub/Forest/RiparianScrub/RiparianThicket) + derive_vegetation: treeline bands × elevation with a structural Forest→Scrub→Barren no-skip guarantee, riparian 1–3 tile band near perennial water; airless (temperature_c == None) → Absent.
  • 21 tests.

T-1027 — Morphology classifier (D-239 §5/§6/§7)

  • FROZEN 17-zone MorphologyZone enum, exactly per D-239 §6 (OpenOcean..Wetland, repr(u8) pinned). The canonical freeze point — verified to match the D-record. Removed legacy Sea/CoastalLowland/Island/Canyon/Unknown; all consumers (skeleton_gen street topology) remapped to the nearest D-239 zone.
  • 8-family gated decision tree (LavaField..AlluvialPlain fallback) over integer inputs; hard gates in tree order: Fjord ≥ GlaciationGrade 2, LavaField = Volcanic tectonic, lithology slope/form laws (§8). Four zones (TidalFlat, Estuarine, Alpine, Wetland) are sub-classifications from family + elevation/water, not families.
  • Build-time compatibility-matrix invariant tests (§7): MeanderReach↔Volcanic and Volcanic↔Fjord forbidden adjacencies are structurally prevented by gate ordering (encoded as "same input can't yield both" — see reviewer note below).
  • 13 tests incl. 17-variant completeness + discriminant pinning.

Reviewer notes

  • The §7 compatibility tests encode the invariant at the classifier-gate level (a single region can't produce a forbidden pair), not true spatial neighbor-adjacency — adjacency needs cross-region context not present at this layer. Flagging the interpretation.
  • The enum freeze realizes the already-decided D-239 §6 vocabulary (reconciling the old 12 variants to the decided 17); it does not change the decision, so no D-record amendment is needed — but please confirm the enum matches §6 exactly.

Verification

D-010 integer discipline throughout. cargo test 1534 pass, clippy --all-targets -D warnings clean, fmt clean (pre-push gate, incl. cargo test, ran on push).

Tickets: T-1025, T-1027 (epic T-974, Phase 4).

🤖 Generated with Claude Code

## Summary The D-239 region-derivation chain on `RegionProfile`: **T-1025** (climate-derived fields) → **T-1027** (frozen morphology vocabulary + classifier). Both derive from the existing temperature/moisture primitives; no authored inputs (D-239 "no authoring at the derivation layers"). ### T-1025 — Climate-derived fields (D-239 §2) - `precipitation_class` and `glaciation_grade` **re-keyed** to take `(temperature_c, moisture_q)` as direct inputs (previously keyed off raw body params) — everything climatic now flows from the temperature primitive. `river_threshold` signature follows. - New `VegetationClass` (Absent/Barren/Scrub/Forest/RiparianScrub/RiparianThicket) + `derive_vegetation`: treeline bands × elevation with a **structural Forest→Scrub→Barren no-skip** guarantee, riparian 1–3 tile band near perennial water; airless (`temperature_c == None`) → `Absent`. - 21 tests. ### T-1027 — Morphology classifier (D-239 §5/§6/§7) - **FROZEN 17-zone `MorphologyZone` enum**, exactly per D-239 §6 (`OpenOcean..Wetland`, `repr(u8)` pinned). The canonical freeze point — verified to match the D-record. Removed legacy `Sea/CoastalLowland/Island/Canyon/Unknown`; all consumers (`skeleton_gen` street topology) remapped to the nearest D-239 zone. - **8-family gated decision tree** (`LavaField..AlluvialPlain` fallback) over integer inputs; hard gates in tree order: Fjord ≥ GlaciationGrade 2, LavaField = Volcanic tectonic, lithology slope/form laws (§8). Four zones (TidalFlat, Estuarine, Alpine, Wetland) are sub-classifications from family + elevation/water, not families. - **Build-time compatibility-matrix invariant tests** (§7): MeanderReach↔Volcanic and Volcanic↔Fjord forbidden adjacencies are structurally prevented by gate ordering (encoded as "same input can't yield both" — see reviewer note below). - 13 tests incl. 17-variant completeness + discriminant pinning. ### Reviewer notes - The §7 compatibility tests encode the invariant at the **classifier-gate** level (a single region can't produce a forbidden pair), not true spatial neighbor-adjacency — adjacency needs cross-region context not present at this layer. Flagging the interpretation. - The enum freeze **realizes** the already-decided D-239 §6 vocabulary (reconciling the old 12 variants to the decided 17); it does not change the decision, so no D-record amendment is needed — but please confirm the enum matches §6 exactly. ### Verification D-010 integer discipline throughout. `cargo test` 1534 pass, `clippy --all-targets -D warnings` clean, `fmt` clean (pre-push gate, incl. `cargo test`, ran on push). Tickets: T-1025, T-1027 (epic T-974, Phase 4). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
jpmschweitzer added 1 commit 2026-06-08 13:14:10 +02:00
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>
jpmschweitzer added 1 commit 2026-06-08 13:24:50 +02:00
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>
Author
Owner

Review: climate-morphology-layers → main (type: code)

Reviewers: Hoshe (code quality) + Tyre (architecture). Source read from the branch worktree. No merge-path surface. Gate green (cargo test 1534, clippy -D warnings, fmt).

Tyre (Architecture): APPROVE

§6 vocabulary freeze matches the D-record exactly — all 17 zones, correct names + repr(u8) discriminants, pinned. Climate derivation clean (temperature keystone, airless None branch consistent, no authored input leaked). §7 gate-ordering interpretation confirmed architecturally correct (the spec's "build-time test" means classifier-structure, not spatial scan). D-010 clean (float confined to physics/ingestion boundary). Exhaustive 17-zone topology remap in skeleton_gen.

Hoshe (Code Quality): REQUEST_CHANGES → resolved

Structural guarantees hold (airless short-circuit, no-skip ladder, exhaustive match). Three findings.

Findings & resolution (868da281)

# Reviewer Finding Resolution
A Hoshe + Tyre morphology_zone_has_exactly_17_variants asserts >=16; BraidedPlain never emitted at region scale, deferral not in §6 Renamed …region_scale_emits_16_of_17, tightened to == 16, documented BraidedPlain's lithology-deferral to ChunkContext, and added a D-239 §6 implementation note. Tyre's "Lake also deferred" was a false positive — ocean_fraction 60–79 → Lake is reachable.
B Hoshe RiparianScrub returned at temp < −50 °C (no liquid water) Fixed — and the logic was doubly-wrong: it granted the oasis only in the impossible cold case and denied it in the intended hyper-arid case. Now: extreme cold → Barren always; hyper-arid → riparian micro-oasis iff near perennial water.
C Hoshe + Tyre derive_morphology_zone docstring inaccurate (TidalFlat 3 paths, ValleyFloor a separate gate, Wetland's MeanderReach path) Docstring rewritten to list the real multi-path emission sites; clarified that §6 "parent family" names are descriptive, not exhaustive.

Tyre's remaining comments were positive confirmations (D-010, topology remap, climate flow) — no change needed.

Verdict: APPROVED (after resolution)

The §6 freeze is faithful, the one behavioral fix (riparian) corrects a real bug the reviewers surfaced, and the rest are documentation/test-accuracy. cargo test passes, clippy -D warnings clean.

🤖 Generated with Claude Code

## Review: climate-morphology-layers → main (type: code) Reviewers: **Hoshe** (code quality) + **Tyre** (architecture). Source read from the branch worktree. No merge-path surface. Gate green (cargo test 1534, clippy `-D warnings`, fmt). ### Tyre (Architecture): APPROVE **§6 vocabulary freeze matches the D-record exactly** — all 17 zones, correct names + `repr(u8)` discriminants, pinned. Climate derivation clean (temperature keystone, airless `None` branch consistent, no authored input leaked). **§7 gate-ordering interpretation confirmed architecturally correct** (the spec's "build-time test" means classifier-structure, not spatial scan). D-010 clean (float confined to physics/ingestion boundary). Exhaustive 17-zone topology remap in `skeleton_gen`. ### Hoshe (Code Quality): REQUEST_CHANGES → resolved Structural guarantees hold (airless short-circuit, no-skip ladder, exhaustive match). Three findings. ### Findings & resolution (`868da281`) | # | Reviewer | Finding | Resolution | |---|----------|---------|------------| | A | Hoshe + Tyre | `morphology_zone_has_exactly_17_variants` asserts `>=16`; `BraidedPlain` never emitted at region scale, deferral not in §6 | Renamed `…region_scale_emits_16_of_17`, tightened to `== 16`, documented BraidedPlain's lithology-deferral to ChunkContext, and added a **D-239 §6 implementation note**. *Tyre's "Lake also deferred" was a false positive — `ocean_fraction 60–79 → Lake` is reachable.* | | B | Hoshe | `RiparianScrub` returned at temp < −50 °C (no liquid water) | Fixed — and the logic was **doubly-wrong**: it granted the oasis only in the impossible cold case and *denied* it in the intended hyper-arid case. Now: extreme cold → Barren always; hyper-arid → riparian micro-oasis iff near perennial water. | | C | Hoshe + Tyre | `derive_morphology_zone` docstring inaccurate (TidalFlat 3 paths, ValleyFloor a separate gate, Wetland's MeanderReach path) | Docstring rewritten to list the real multi-path emission sites; clarified that §6 "parent family" names are descriptive, not exhaustive. | Tyre's remaining comments were positive confirmations (D-010, topology remap, climate flow) — no change needed. ### Verdict: APPROVED (after resolution) The §6 freeze is faithful, the one behavioral fix (riparian) corrects a real bug the reviewers surfaced, and the rest are documentation/test-accuracy. `cargo test` passes, clippy `-D warnings` clean. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
jpmschweitzer closed this pull request 2026-06-08 13:27:11 +02:00

Pull request closed

This pull request cannot be reopened because the branch was deleted.
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: jpmschweitzer/settled-reach#160