feat(simulation): planet_class temperature envelope (T-1033, D-240) #164

Closed
jpmschweitzer wants to merge 0 commits from class-envelope-temperature into main
Owner

Summary

T-1033 implements D-240: temperature derives from the authored planet_class envelope, not astrophysics. This fixes the unusable sun-driven model that produced +356 °C "temperate" worlds (NULL spectral_class → G-Sun default on an M-dwarf catalog).

Model (D-240)

  • New [planet_class_temperature] envelope table in climate_constants.toml — the approved bands (frozen [−90,−25]hot_arid [20,58]volcanic [30,90]), with cold_*/hot_*/warm_* prefix parsing and a temperate fallback.
  • derive_temperature_c(params, constants, body_seed): band from planet_class; latitude lerps across the band (equator → warm, pole → cold); atmosphere greenhouse + elevation lapse modulate within; a small seed nudge for per-world variety; clamped to the band — a body can never derive outside its class. Airless → None.

Removed (the non-canonical inputs, per D-240)

  • Deleted derive_distance_au, ClimateConstants::luminosity(), the [star_luminosity] table.
  • Stripped orbital_period_days / spectral_class / star_type / axial_tilt_deg from BodyParams + BodyParamsReader (now reads 3 columns from bodies, no star_systems join). DB columns left in place — no schema change, no systems.db regen.

Verification

  • New every_planet_class_derives_within_its_band test — 13 classes × 5 atmospheres × 19 latitudes × 4 seeds, all in band (the D-240 consistency guard, true by construction via the final clamp).
  • Acceptance check on 25 diverse real bodies (lead-run): every world now sits inside its class band — the +356 °C bodies derive to ≤28 °C, frozen → −25/−70, volcanic → 90/58, airless → none, latitude gradient holds everywhere.
  • cargo test passes, clippy --all-targets -D warnings clean, fmt clean. D-010 integer-disciplined (the f32 temp feeds the integer climate ladders as before).

Ticket: T-1033 (epic T-974, decision D-240). After merge, the T-1031 harness rebases onto this and regenerates its golden against the corrected temperatures.

🤖 Generated with Claude Code

## Summary **T-1033** implements **D-240**: temperature derives from the authored `planet_class` envelope, not astrophysics. This fixes the unusable sun-driven model that produced +356 °C "temperate" worlds (NULL `spectral_class` → G-Sun default on an M-dwarf catalog). ### Model (D-240) - New `[planet_class_temperature]` envelope table in `climate_constants.toml` — the approved bands (`frozen [−90,−25]` … `hot_arid [20,58]` … `volcanic [30,90]`), with `cold_*`/`hot_*`/`warm_*` prefix parsing and a `temperate` fallback. - `derive_temperature_c(params, constants, body_seed)`: band from `planet_class`; **latitude lerps across the band** (equator → warm, pole → cold); atmosphere greenhouse + elevation lapse modulate within; a small **seed nudge** for per-world variety; **clamped to the band** — a body can never derive outside its class. Airless → `None`. ### Removed (the non-canonical inputs, per D-240) - Deleted `derive_distance_au`, `ClimateConstants::luminosity()`, the `[star_luminosity]` table. - Stripped `orbital_period_days` / `spectral_class` / `star_type` / `axial_tilt_deg` from `BodyParams` + `BodyParamsReader` (now reads 3 columns from `bodies`, no `star_systems` join). **DB columns left in place** — no schema change, no `systems.db` regen. ### Verification - New `every_planet_class_derives_within_its_band` test — 13 classes × 5 atmospheres × 19 latitudes × 4 seeds, **all in band** (the D-240 consistency guard, true by construction via the final clamp). - **Acceptance check on 25 diverse real bodies** (lead-run): every world now sits inside its class band — the +356 °C bodies derive to ≤28 °C, frozen → −25/−70, volcanic → 90/58, airless → none, latitude gradient holds everywhere. - `cargo test` passes, `clippy --all-targets -D warnings` clean, `fmt` clean. D-010 integer-disciplined (the f32 temp feeds the integer climate ladders as before). Ticket: T-1033 (epic T-974, decision D-240). After merge, the T-1031 harness rebases onto this and regenerates its golden against the corrected temperatures. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
jpmschweitzer added 1 commit 2026-06-08 18:30:13 +02:00
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>
jpmschweitzer added 1 commit 2026-06-08 18:36:53 +02:00
- 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>
Author
Owner

Review: class-envelope-temperature → main (type: code) — APPROVED

Reviewers: Hoshe (code quality) + Tyre (architecture). Both APPROVE.

Tyre (Architecture): APPROVE

D-240 faithfully realized. Orbit/star removal complete + clean (BodyParams carries none; derive_distance_au/luminosity() deleted; reader drops the star_systems join, selects 3 columns). Temperature = planet_class envelope + latitude lerp + greenhouse-as-band-fraction + lapse + seed nudge, clamped to [cold,warm] — the band invariant is structural, not conventional. No schema change (correct call). Determinism preserved.

Hoshe (Code Quality): APPROVE

Zero orbit/star data reaches derive_temperature_c; remaining references are only DB-authoring tools/schema, correctly untouched. Clamp makes out-of-band impossible by construction; the parametric sweep is a genuine regression guard.

Tidy-ups applied (54609eab1)

  • Band-invariant test now sweeps high altitude (6 km) as well as sea level, exercising lapse + cold-end clamp jointly. (Hoshe #1 / Tyre #3)
  • Clarified the temp() helper comment re: seed-0 nudge. (Hoshe #2)
  • Confirmed tectonic_activity is genuinely absent from systems-schema.sql — the reader comment is accurate. (Hoshe #3)

One open design question (non-blocking) — Tyre #4

D-240 lists hydrosphere among the canonical modulators ("atmosphere / hydrosphere / elevation modulate within the bounds"). In the implementation, hydrosphere drives moisture (→ precipitation/glaciation/vegetation) but does not directly modulate temperature (e.g. ocean → maritime moderation / reduced swing). Tyre reads D-240's wording as permitting the moisture-mediated interpretation; flagged for the author to confirm intent. Tracked as a possible follow-up, not a blocker.

Verdict: APPROVED

Verified on 25 diverse real bodies — the +356 °C worlds now derive in-band. cargo test passes, clippy -D warnings clean, fmt clean.

🤖 Generated with Claude Code

## Review: class-envelope-temperature → main (type: code) — APPROVED Reviewers: **Hoshe** (code quality) + **Tyre** (architecture). Both **APPROVE**. ### Tyre (Architecture): APPROVE D-240 faithfully realized. Orbit/star removal complete + clean (`BodyParams` carries none; `derive_distance_au`/`luminosity()` deleted; reader drops the `star_systems` join, selects 3 columns). Temperature = `planet_class` envelope + latitude lerp + greenhouse-as-band-fraction + lapse + seed nudge, **clamped to `[cold,warm]`** — the band invariant is structural, not conventional. No schema change (correct call). Determinism preserved. ### Hoshe (Code Quality): APPROVE Zero orbit/star data reaches `derive_temperature_c`; remaining references are only DB-authoring tools/schema, correctly untouched. Clamp makes out-of-band impossible by construction; the parametric sweep is a genuine regression guard. ### Tidy-ups applied (`54609eab1`) - Band-invariant test now sweeps **high altitude (6 km)** as well as sea level, exercising lapse + cold-end clamp jointly. (Hoshe #1 / Tyre #3) - Clarified the `temp()` helper comment re: seed-0 nudge. (Hoshe #2) - Confirmed `tectonic_activity` is genuinely absent from `systems-schema.sql` — the reader comment is accurate. (Hoshe #3) ### One open design question (non-blocking) — Tyre #4 D-240 lists `hydrosphere` among the canonical modulators ("atmosphere / hydrosphere / elevation modulate within the bounds"). In the implementation, hydrosphere drives **moisture** (→ precipitation/glaciation/vegetation) but does **not** directly modulate **temperature** (e.g. ocean → maritime moderation / reduced swing). Tyre reads D-240's wording as permitting the moisture-mediated interpretation; flagged for the author to confirm intent. Tracked as a possible follow-up, not a blocker. ### Verdict: APPROVED Verified on 25 diverse real bodies — the +356 °C worlds now derive in-band. `cargo test` passes, clippy `-D warnings` clean, fmt clean. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
jpmschweitzer added 1 commit 2026-06-08 19:00:08 +02:00
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>
jpmschweitzer added 1 commit 2026-06-08 19:09:56 +02:00
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>
Author
Owner

Re-review: class-envelope-temperature → main (maritime moderation) — APPROVED

Covers the post-approval addition (b894a721 hydrosphere maritime moderation). The class-envelope core was approved in the prior round.

Tyre (Architecture): APPROVE

The maritime addition soundly completes the D-240 "hydrosphere modulates temperature within bounds" clause. Compressing the gradient toward the class midpoint is the correct model (moderates both ends; the pre-existing clamp catches greenhouse overshoot without widening the band). TOML/embedded in sync; scope clean. Confirmed T-1034 (the derive_moisture_q vocab twin) is correctly filed separately.

Hoshe (Code Quality): REQUEST_CHANGES → resolved

Verified the gradient math (sub-band ⊆ class band, no inversion possible), TOML sync, complete vocab mapping, and that the maritime test is non-trivial (a no-op maritime_factor → 1.0 would fail it). Two contained findings, both fixed.

Findings & resolution (bafed6ad)

# Reviewer Finding Resolution
1 Hoshe + Tyre every_planet_class_derives_within_its_band only swept hydrosphere: None (maritime=1.0) — the compressed path wasn't covered by the band invariant Test now sweeps hydrosphere (none/ocean/liquid_water/rivers/ice) too — ~59k in-band assertions covering the maritime path.
2 Hoshe BodyParams.hydrosphere doc comment listed the stale pre-maritime vocab Updated to the real systems.db vocabulary the maritime table keys on.

Verdict: APPROVED

Maritime moderation completes D-240's hydrosphere clause, the class-band invariant is now also test-covered for compressed gradients, and the +356 °C → in-band fix is verified across 25 real worlds. cargo test passes, clippy -D warnings clean, fmt clean.

Note: a pre-existing flaky test voice::lookup::cache_miss_returns_base_text (unrelated — this branch doesn't touch voice/) intermittently fails under suite parallelism; passes on retry. Worth a separate CI-hygiene ticket.

🤖 Generated with Claude Code

## Re-review: class-envelope-temperature → main (maritime moderation) — APPROVED Covers the post-approval addition (`b894a721` hydrosphere maritime moderation). The class-envelope core was approved in the prior round. ### Tyre (Architecture): APPROVE The maritime addition soundly completes the D-240 "hydrosphere modulates temperature within bounds" clause. Compressing the gradient toward the **class midpoint** is the correct model (moderates both ends; the pre-existing clamp catches greenhouse overshoot without widening the band). TOML/embedded in sync; scope clean. Confirmed T-1034 (the `derive_moisture_q` vocab twin) is correctly filed separately. ### Hoshe (Code Quality): REQUEST_CHANGES → resolved Verified the gradient math (sub-band ⊆ class band, no inversion possible), TOML sync, complete vocab mapping, and that the maritime test is non-trivial (a no-op `maritime_factor → 1.0` would fail it). Two contained findings, both fixed. ### Findings & resolution (`bafed6ad`) | # | Reviewer | Finding | Resolution | |---|----------|---------|------------| | 1 | Hoshe + Tyre | `every_planet_class_derives_within_its_band` only swept `hydrosphere: None` (maritime=1.0) — the compressed path wasn't covered by the band invariant | Test now sweeps hydrosphere (`none/ocean/liquid_water/rivers/ice`) too — ~59k in-band assertions covering the maritime path. | | 2 | Hoshe | `BodyParams.hydrosphere` doc comment listed the stale pre-maritime vocab | Updated to the real `systems.db` vocabulary the maritime table keys on. | ### Verdict: APPROVED Maritime moderation completes D-240's hydrosphere clause, the class-band invariant is now also test-covered for compressed gradients, and the +356 °C → in-band fix is verified across 25 real worlds. `cargo test` passes, clippy `-D warnings` clean, fmt clean. *Note: a pre-existing flaky test `voice::lookup::cache_miss_returns_base_text` (unrelated — this branch doesn't touch `voice/`) intermittently fails under suite parallelism; passes on retry. Worth a separate CI-hygiene ticket.* 🤖 Generated with [Claude Code](https://claude.com/claude-code)
jpmschweitzer closed this pull request 2026-06-08 19:17:58 +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#164