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.
## 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)
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>
- 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>
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)
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.
## 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)
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>
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>
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.
## 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)
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
T-1033 implements D-240: temperature derives from the authored
planet_classenvelope, not astrophysics. This fixes the unusable sun-driven model that produced +356 °C "temperate" worlds (NULLspectral_class→ G-Sun default on an M-dwarf catalog).Model (D-240)
[planet_class_temperature]envelope table inclimate_constants.toml— the approved bands (frozen [−90,−25]…hot_arid [20,58]…volcanic [30,90]), withcold_*/hot_*/warm_*prefix parsing and atemperatefallback.derive_temperature_c(params, constants, body_seed): band fromplanet_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)
derive_distance_au,ClimateConstants::luminosity(), the[star_luminosity]table.orbital_period_days/spectral_class/star_type/axial_tilt_degfromBodyParams+BodyParamsReader(now reads 3 columns frombodies, nostar_systemsjoin). DB columns left in place — no schema change, nosystems.dbregen.Verification
every_planet_class_derives_within_its_bandtest — 13 classes × 5 atmospheres × 19 latitudes × 4 seeds, all in band (the D-240 consistency guard, true by construction via the final clamp).cargo testpasses,clippy --all-targets -D warningsclean,fmtclean. 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
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 (
BodyParamscarries none;derive_distance_au/luminosity()deleted; reader drops thestar_systemsjoin, selects 3 columns). Temperature =planet_classenvelope + 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)temp()helper comment re: seed-0 nudge. (Hoshe #2)tectonic_activityis genuinely absent fromsystems-schema.sql— the reader comment is accurate. (Hoshe #3)One open design question (non-blocking) — Tyre #4
D-240 lists
hydrosphereamong 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 testpasses, clippy-D warningsclean, fmt clean.🤖 Generated with Claude Code
Re-review: class-envelope-temperature → main (maritime moderation) — APPROVED
Covers the post-approval addition (
b894a721hydrosphere 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_qvocab 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.0would fail it). Two contained findings, both fixed.Findings & resolution (
bafed6ad)every_planet_class_derives_within_its_bandonly swepthydrosphere: None(maritime=1.0) — the compressed path wasn't covered by the band invariantnone/ocean/liquid_water/rivers/ice) too — ~59k in-band assertions covering the maritime path.BodyParams.hydrospheredoc comment listed the stale pre-maritime vocabsystems.dbvocabulary 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 testpasses, clippy-D warningsclean, fmt clean.Note: a pre-existing flaky test
voice::lookup::cache_miss_returns_base_text(unrelated — this branch doesn't touchvoice/) intermittently fails under suite parallelism; passes on retry. Worth a separate CI-hygiene ticket.🤖 Generated with Claude Code
Pull request closed