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>
This commit is contained in:
@@ -492,3 +492,4 @@ INSERT INTO ticket_deps (blocker_id, blocked_id, created_at, updated_at, deleted
|
||||
INSERT INTO ticket_deps (blocker_id, blocked_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-1028', 'T-1029', '2026-06-07 10:34:18', '2026-06-07 10:34:18', NULL, '846b9769bc3f915a5b78d26f8043e56f', 1) ON CONFLICT(blocker_id, blocked_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_deps.updated_at OR (excluded.updated_at = ticket_deps.updated_at AND excluded.hash > ticket_deps.hash);
|
||||
INSERT INTO ticket_deps (blocker_id, blocked_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-1025', 'T-1030', '2026-06-07 10:34:18', '2026-06-07 10:34:18', NULL, '2b004621493b0df5775816debfe01d4e', 1) ON CONFLICT(blocker_id, blocked_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_deps.updated_at OR (excluded.updated_at = ticket_deps.updated_at AND excluded.hash > ticket_deps.hash);
|
||||
INSERT INTO ticket_deps (blocker_id, blocked_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-1029', 'T-1031', '2026-06-07 10:34:18', '2026-06-07 10:34:18', NULL, '65f71e85655dd9eb24de7741e9a9df44', 1) ON CONFLICT(blocker_id, blocked_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_deps.updated_at OR (excluded.updated_at = ticket_deps.updated_at AND excluded.hash > ticket_deps.hash);
|
||||
INSERT INTO ticket_deps (blocker_id, blocked_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-1023', 'T-1024', '2026-06-07 16:35:38', '2026-06-07 16:35:38', NULL, 'e6cd055a2303968d1f63de9dfdcb486b', 1) ON CONFLICT(blocker_id, blocked_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_deps.updated_at OR (excluded.updated_at = ticket_deps.updated_at AND excluded.hash > ticket_deps.hash);
|
||||
|
||||
@@ -100,3 +100,59 @@ Edge cases: empty state.placements -> loop submits nothing, returns normally (no
|
||||
Verified: Layer-4 geometry (D-234a/b) fully implemented in server/src/atlas/skeleton_gen.rs (derive_corridors reads morphology_zone, derive_access_points reads road_entry_directions, waterfront rule ~108-113 reads founding_orientation). Only the dispatch is dormant.', NULL, '2026-06-07 10:42:27', '2026-06-07 10:42:27', '2026-06-07 10:42:27', NULL, 'aa1911b38c699f46e21fed37aacde669', 1) ON CONFLICT(hash) DO NOTHING;
|
||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-1022', 'status', 'backlog', 'in_progress', NULL, '2026-06-07 10:44:24', '2026-06-07 10:44:24', '2026-06-07 10:44:24', NULL, 'bae44ce724f650962ff7d1d27aafd2bc', 1) ON CONFLICT(hash) DO NOTHING;
|
||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-1022', 'status', 'in_progress', 'review', NULL, '2026-06-07 11:33:25', '2026-06-07 11:33:25', '2026-06-07 11:33:25', NULL, '96b9df26d2ea52af819b5e0fd85c9bf7', 1) ON CONFLICT(hash) DO NOTHING;
|
||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-19', 'status', 'backlog', 'done', NULL, '2026-06-07 12:31:26', '2026-06-07 12:31:26', '2026-06-07 12:31:26', NULL, '2973969c998433415a8e9add0d9f5764', 1) ON CONFLICT(hash) DO NOTHING;
|
||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-1024', 'description', 'D-239 section 2. Scalar district temperature in degrees C, NULLABLE (no atmosphere -> null -> climate branch absent; airless surface ice is geology per D-227). Derived from sun (luminosity+insolation), planet (latitude+elevation lapse+orbital/axial phase=season term, day-phase=diurnal term), atmosphere (greenhouse->base, heat-retention->diurnal-swing amplitude; thick air=small swing). Separate moisture primitive from hydrosphere. Formalises D-210''s temperature proxy. Tiles inherit district values.', 'D-239 section 2. Scalar district temperature in degrees C, NULLABLE (no atmosphere -> null -> climate branch absent; airless surface ice is geology per D-227). Derived from sun (luminosity+insolation), planet (latitude+elevation lapse+orbital/axial phase=season term, day-phase=diurnal term), atmosphere (greenhouse->base, heat-retention->diurnal-swing amplitude; thick air=small swing). Separate moisture primitive from hydrosphere. Formalises D-210''s temperature proxy. Tiles inherit district values.
|
||||
|
||||
---
|
||||
Refinement (/whats-next 2026-06-07) — gaps resolved with Jeroen:
|
||||
|
||||
1. Data inputs (hybrid): import axial_tilt_deg into the bodies table from the
|
||||
already-authored planet-gen body-def TOMLs (via the import pipeline); derive
|
||||
the rest at runtime in Rust — luminosity from spectral_class lookup, orbital
|
||||
distance (AU) from orbital_period_days via Kepler''s third law + star mass.
|
||||
Do NOT re-encode the full Python tuning tables in Rust beyond these.
|
||||
|
||||
2. Carrier rung: temperature is carried as `temperature_c: Option<f32>` (+ a
|
||||
moisture primitive) ON the T-1023 RegionProfile struct — NOT a new carrier
|
||||
tier. Compute on a 2x2km climate grid; regions sample it. The "~1km vs 2km"
|
||||
label is cosmetic. Needs a one-line D-239 clarification (see note below).
|
||||
|
||||
3. Diurnal-swing values: reuse the tuned greenhouse offsets from
|
||||
tooling/planet-gen planet_simulation.py; add a NEW small atmosphere ->
|
||||
diurnal_amplitude_C table (5 classes; airless/thin large swing ~40-60C,
|
||||
dense/thick small swing ~2-5C). Store these constants in a SOURCE TOML
|
||||
(source-canonical, tunable without recompiling), not hardcoded in Rust.
|
||||
|
||||
4. Season term: produce a MEAN-ANNUAL scalar temperature (orbital phase fixed,
|
||||
e.g. equinox); carry diurnal swing as an amplitude only — NO time argument.
|
||||
No clock dependency. The dynamic clock-bound seasonal branch stays deferred
|
||||
to Q-105 / Phase 5. Per Jeroen: these calculations don''t need perfection;
|
||||
plausible-and-present beats precise.
|
||||
|
||||
Blocked-by T-1023 (temperature fields live on RegionProfile, which T-1023 defines).
|
||||
|
||||
D-239 follow-up: the implementer should add a one-line clarification to D-239
|
||||
(§1/§2) recording that district temperature is a nullable field on RegionProfile
|
||||
sampled from a 2km climate grid, and that climate physics inputs come via the
|
||||
hybrid import/derive strategy above. Fold into the implementation PR.', NULL, '2026-06-07 16:35:37', '2026-06-07 16:35:37', '2026-06-07 16:35:37', NULL, '57cd19da7740c893765d89846dfa5955', 1) ON CONFLICT(hash) DO NOTHING;
|
||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-1023', 'description', 'First stage of the D-239 three-carrier chain. Define the RegionProfile struct (morphology_zone, tectonic_class, glaciation_grade, slope/lithology/elevation summaries, and a derived per-body-class RIVER_THRESHOLD via (hydrosphere,tectonic_activity,precipitation_class)->threshold, NOT the global 200). Pure region-derivation fn(seed,atlas,body-params,pos). Cache in BodyWorldState (D-203, ~6k regions/body) populated in the D-206 background pass so the Atlas reads zone labels without triggering voxel derivation. No authoring at this layer — all gating params derived from body params. D-239 sections 1,10.', 'First stage of the D-239 three-carrier chain. Define the RegionProfile struct (morphology_zone, tectonic_class, glaciation_grade, slope/lithology/elevation summaries, and a derived per-body-class RIVER_THRESHOLD via (hydrosphere,tectonic_activity,precipitation_class)->threshold, NOT the global 200). Pure region-derivation fn(seed,atlas,body-params,pos). Cache in BodyWorldState (D-203, ~6k regions/body) populated in the D-206 background pass so the Atlas reads zone labels without triggering voxel derivation. No authoring at this layer — all gating params derived from body params. D-239 sections 1,10.
|
||||
|
||||
---
|
||||
Refinement (/whats-next 2026-06-07) — Si review: READY.
|
||||
|
||||
Scope note: the existing MorphologyZone enum (server/src/simulation/generator.rs,
|
||||
12 variants) does NOT need reconciling to the D-239 §6 frozen 17-zone vocabulary
|
||||
in this ticket — that reconciliation is T-1027''s job (Morphology classifier —
|
||||
17-zone frozen vocab + 8-family gate). T-1023 uses the existing MorphologyZone
|
||||
(or a placeholder field) and does not block on the vocabulary change.
|
||||
|
||||
Companion note: T-1024 will add temperature_c: Option<f32> + a moisture primitive
|
||||
as fields on the RegionProfile struct defined here (see T-1024 refinement). Define
|
||||
the struct so those fields can be added without churn.
|
||||
|
||||
Cache populate hooks into the same GenCompletion::BodyAnalyzed drain arm
|
||||
(server/src/atlas/plugin.rs) that T-1022 just wired for L3->L4 dispatch.', NULL, '2026-06-07 16:35:38', '2026-06-07 16:35:38', '2026-06-07 16:35:38', NULL, '8b567f1a36210bec12925a1dfba49369', 1) ON CONFLICT(hash) DO NOTHING;
|
||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-1022', 'status', 'review', 'done', NULL, '2026-06-07 16:46:01', '2026-06-07 16:46:01', '2026-06-07 16:46:01', NULL, '6f72695d5cddd6cdab8ccdb01d7f3934', 1) ON CONFLICT(hash) DO NOTHING;
|
||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-1023', 'status', 'backlog', 'in_progress', NULL, '2026-06-07 16:46:01', '2026-06-07 16:46:01', '2026-06-07 16:46:01', NULL, '69beda3a00dc991cac42f9b84a4a2e78', 1) ON CONFLICT(hash) DO NOTHING;
|
||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-1024', 'status', 'backlog', 'in_progress', NULL, '2026-06-07 16:46:01', '2026-06-07 16:46:01', '2026-06-07 16:46:01', NULL, '8b2967986ce3433c4ef79e8a95a19d96', 1) ON CONFLICT(hash) DO NOTHING;
|
||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-1026', 'status', 'backlog', 'in_progress', NULL, '2026-06-07 16:46:01', '2026-06-07 16:46:01', '2026-06-07 16:46:01', NULL, 'ba35702257d615d2efe0fc1e1110c857', 1) ON CONFLICT(hash) DO NOTHING;
|
||||
|
||||
@@ -301,3 +301,127 @@ DECISION for implementer (no open Q, one-liner): quarter_id has no canonical der
|
||||
Edge cases: empty state.placements -> loop submits nothing, returns normally (no special case). Q-109 (station/multi-source dispatch) non-blocking — BodyAnalyzed only fires on the planetary AnalyzeBody path; stations have no AnalyzeBody enqueue site yet.
|
||||
|
||||
Verified: Layer-4 geometry (D-234a/b) fully implemented in server/src/atlas/skeleton_gen.rs (derive_corridors reads morphology_zone, derive_access_points reads road_entry_directions, waterfront rule ~108-113 reads founding_orientation). Only the dispatch is dormant.', 'review', 'high', NULL, 'server', 'D-234', '2026-06-07 08:10:17', '2026-06-07 11:33:25', NULL, '073bbf10c9acad1a04547af6aea8f632', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
|
||||
INSERT INTO tickets (id, type, parent_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-19', 'story', NULL, 'v0.1 prototype scope', NULL, 'done', 'medium', NULL, NULL, 'Q-002', '2026-02-09 15:21:44', '2026-06-07 12:31:26', NULL, '9d212bbd1fd5f7a9a505c7369ce2d49d', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
|
||||
INSERT INTO tickets (id, type, parent_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-1024', 'task', 'T-974', 'District climate primitives — temperature + moisture (2x2km)', 'D-239 section 2. Scalar district temperature in degrees C, NULLABLE (no atmosphere -> null -> climate branch absent; airless surface ice is geology per D-227). Derived from sun (luminosity+insolation), planet (latitude+elevation lapse+orbital/axial phase=season term, day-phase=diurnal term), atmosphere (greenhouse->base, heat-retention->diurnal-swing amplitude; thick air=small swing). Separate moisture primitive from hydrosphere. Formalises D-210''s temperature proxy. Tiles inherit district values.
|
||||
|
||||
---
|
||||
Refinement (/whats-next 2026-06-07) — gaps resolved with Jeroen:
|
||||
|
||||
1. Data inputs (hybrid): import axial_tilt_deg into the bodies table from the
|
||||
already-authored planet-gen body-def TOMLs (via the import pipeline); derive
|
||||
the rest at runtime in Rust — luminosity from spectral_class lookup, orbital
|
||||
distance (AU) from orbital_period_days via Kepler''s third law + star mass.
|
||||
Do NOT re-encode the full Python tuning tables in Rust beyond these.
|
||||
|
||||
2. Carrier rung: temperature is carried as `temperature_c: Option<f32>` (+ a
|
||||
moisture primitive) ON the T-1023 RegionProfile struct — NOT a new carrier
|
||||
tier. Compute on a 2x2km climate grid; regions sample it. The "~1km vs 2km"
|
||||
label is cosmetic. Needs a one-line D-239 clarification (see note below).
|
||||
|
||||
3. Diurnal-swing values: reuse the tuned greenhouse offsets from
|
||||
tooling/planet-gen planet_simulation.py; add a NEW small atmosphere ->
|
||||
diurnal_amplitude_C table (5 classes; airless/thin large swing ~40-60C,
|
||||
dense/thick small swing ~2-5C). Store these constants in a SOURCE TOML
|
||||
(source-canonical, tunable without recompiling), not hardcoded in Rust.
|
||||
|
||||
4. Season term: produce a MEAN-ANNUAL scalar temperature (orbital phase fixed,
|
||||
e.g. equinox); carry diurnal swing as an amplitude only — NO time argument.
|
||||
No clock dependency. The dynamic clock-bound seasonal branch stays deferred
|
||||
to Q-105 / Phase 5. Per Jeroen: these calculations don''t need perfection;
|
||||
plausible-and-present beats precise.
|
||||
|
||||
Blocked-by T-1023 (temperature fields live on RegionProfile, which T-1023 defines).
|
||||
|
||||
D-239 follow-up: the implementer should add a one-line clarification to D-239
|
||||
(§1/§2) recording that district temperature is a nullable field on RegionProfile
|
||||
sampled from a 2km climate grid, and that climate physics inputs come via the
|
||||
hybrid import/derive strategy above. Fold into the implementation PR.', 'backlog', 'high', NULL, 'server', 'D-239', '2026-06-07 10:33:47', '2026-06-07 16:35:37', NULL, '51c76d5bc270256134459a02427fe479', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
|
||||
INSERT INTO tickets (id, type, parent_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-1023', 'task', 'T-974', 'RegionProfile carrier (~1km) + derived gating params + BodyWorldState cache', 'First stage of the D-239 three-carrier chain. Define the RegionProfile struct (morphology_zone, tectonic_class, glaciation_grade, slope/lithology/elevation summaries, and a derived per-body-class RIVER_THRESHOLD via (hydrosphere,tectonic_activity,precipitation_class)->threshold, NOT the global 200). Pure region-derivation fn(seed,atlas,body-params,pos). Cache in BodyWorldState (D-203, ~6k regions/body) populated in the D-206 background pass so the Atlas reads zone labels without triggering voxel derivation. No authoring at this layer — all gating params derived from body params. D-239 sections 1,10.
|
||||
|
||||
---
|
||||
Refinement (/whats-next 2026-06-07) — Si review: READY.
|
||||
|
||||
Scope note: the existing MorphologyZone enum (server/src/simulation/generator.rs,
|
||||
12 variants) does NOT need reconciling to the D-239 §6 frozen 17-zone vocabulary
|
||||
in this ticket — that reconciliation is T-1027''s job (Morphology classifier —
|
||||
17-zone frozen vocab + 8-family gate). T-1023 uses the existing MorphologyZone
|
||||
(or a placeholder field) and does not block on the vocabulary change.
|
||||
|
||||
Companion note: T-1024 will add temperature_c: Option<f32> + a moisture primitive
|
||||
as fields on the RegionProfile struct defined here (see T-1024 refinement). Define
|
||||
the struct so those fields can be added without churn.
|
||||
|
||||
Cache populate hooks into the same GenCompletion::BodyAnalyzed drain arm
|
||||
(server/src/atlas/plugin.rs) that T-1022 just wired for L3->L4 dispatch.', 'backlog', 'high', NULL, 'server', 'D-239', '2026-06-07 10:33:47', '2026-06-07 16:35:38', NULL, 'c78abae94e54b2f9032ff6a451e38041', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
|
||||
INSERT INTO tickets (id, type, parent_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-1022', 'story', 'T-750', 'Layer-3 -> Layer-4 GenerateSkeleton dispatch (founding_orientation wiring)', 'Wire Layer-3 settlement placement to Layer-4 quarter generation so the already-implemented Layer-4 geometry runs in production with real per-settlement orientation. Today there is NO production call site that dispatches GenerateSkeleton from a placement: city_context_reader.rs:484 stubs founding_orientation=Cardinal, so the implemented D-234b waterfront rule (and morphology-correct streets) stay dormant.
|
||||
|
||||
Scope: on GenCompletion::BodyAnalyzed, iterate state.placements and submit one GenerateSkeleton work item per placed settlement, building CityGenerationContext from each CityPlacement (context_from_read_set, city_context_reader.rs:~462) and overriding founding_orientation with the attractor-matched CityPlacement.founding_orientation (already computed in attractor_matching.rs:~535, carried on CityPlacement:~63).
|
||||
|
||||
Call sites: plugin.rs BodyAnalyzed handler (~84), gen_queue.rs GenerateSkeleton arm, city_context_reader.rs (stub at 484), attractor_matching.rs. Q-109 (multi-source/station dispatch) is adjacent but non-blocking for the planetary path. Surfaced by Si vetting (2026-06-07): T-976/989/990/991 geometry is done+tested but dormant without this dispatch.
|
||||
|
||||
---
|
||||
Refinement (Si, 2026-06-07) — READY:
|
||||
|
||||
Wiring point: drain_generation_completions in server/src/atlas/plugin.rs:78. The BodyAnalyzed arm (line 84) currently calls cache.insert(state) and discards placements. Expand it: after cache insert, iterate state.placements (Vec<CityPlacement>, body_world_state.rs:85) and submit one GenWorkItem::GenerateSkeleton per placement. System signature grows by Option<Res<CityContextReaderResource>> + Option<Res<SimRng>> (world_seed), mirroring serve_atlas_requests; both already imported.
|
||||
|
||||
Per placement: ctx = reader.build_context(placement.city_id, world_seed) (city_context_reader.rs:221) -> read_set -> context_from_read_set -> CityGenerationContext. Override the stub: ctx.founding_orientation = placement.founding_orientation.clone() (the one field stubbed Cardinal at city_context_reader.rs:484; value computed by founding_orientation() at attractor_matching.rs:535, carried on CityPlacement:63 from attractor.water_bearing + territorial_status).
|
||||
|
||||
GenerateSkeleton other fields: economic_role/population/founding_age_years from reader.read_set() CityEconomicReadSet (call read_set directly to capture them; carried separately per gen_queue.rs:93-108). body_id = state.body_id.clone(). chain = SeedChain::for_body(world_seed,&body_id).derive(SeedDomain::Layer4Quarter, placement.city_id) (Layer4Quarter at seed.rs:92; mirrors Layer3Settlement use at city_context_reader.rs:389).
|
||||
|
||||
DECISION for implementer (no open Q, one-liner): quarter_id has no canonical derivation yet (test placeholder city_id*10). Use SeedChain::for_body(world_seed,&body_id).derive(SeedDomain::Layer4Quarter, placement.city_id).seed() — deterministic, namespace-isolated; add a comment referencing D-194/D-230.
|
||||
|
||||
Edge cases: empty state.placements -> loop submits nothing, returns normally (no special case). Q-109 (station/multi-source dispatch) non-blocking — BodyAnalyzed only fires on the planetary AnalyzeBody path; stations have no AnalyzeBody enqueue site yet.
|
||||
|
||||
Verified: Layer-4 geometry (D-234a/b) fully implemented in server/src/atlas/skeleton_gen.rs (derive_corridors reads morphology_zone, derive_access_points reads road_entry_directions, waterfront rule ~108-113 reads founding_orientation). Only the dispatch is dormant.', 'done', 'high', NULL, 'server', 'D-234', '2026-06-07 08:10:17', '2026-06-07 16:46:01', NULL, 'f266938273b1579f912bb4b6fa430c6e', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
|
||||
INSERT INTO tickets (id, type, parent_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-1023', 'task', 'T-974', 'RegionProfile carrier (~1km) + derived gating params + BodyWorldState cache', 'First stage of the D-239 three-carrier chain. Define the RegionProfile struct (morphology_zone, tectonic_class, glaciation_grade, slope/lithology/elevation summaries, and a derived per-body-class RIVER_THRESHOLD via (hydrosphere,tectonic_activity,precipitation_class)->threshold, NOT the global 200). Pure region-derivation fn(seed,atlas,body-params,pos). Cache in BodyWorldState (D-203, ~6k regions/body) populated in the D-206 background pass so the Atlas reads zone labels without triggering voxel derivation. No authoring at this layer — all gating params derived from body params. D-239 sections 1,10.
|
||||
|
||||
---
|
||||
Refinement (/whats-next 2026-06-07) — Si review: READY.
|
||||
|
||||
Scope note: the existing MorphologyZone enum (server/src/simulation/generator.rs,
|
||||
12 variants) does NOT need reconciling to the D-239 §6 frozen 17-zone vocabulary
|
||||
in this ticket — that reconciliation is T-1027''s job (Morphology classifier —
|
||||
17-zone frozen vocab + 8-family gate). T-1023 uses the existing MorphologyZone
|
||||
(or a placeholder field) and does not block on the vocabulary change.
|
||||
|
||||
Companion note: T-1024 will add temperature_c: Option<f32> + a moisture primitive
|
||||
as fields on the RegionProfile struct defined here (see T-1024 refinement). Define
|
||||
the struct so those fields can be added without churn.
|
||||
|
||||
Cache populate hooks into the same GenCompletion::BodyAnalyzed drain arm
|
||||
(server/src/atlas/plugin.rs) that T-1022 just wired for L3->L4 dispatch.', 'in_progress', 'high', NULL, 'server', 'D-239', '2026-06-07 10:33:47', '2026-06-07 16:46:01', NULL, '2a19219acf11a133ee17b5cb1d86e070', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
|
||||
INSERT INTO tickets (id, type, parent_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-1026', 'task', 'T-974', 'Anti-squaring domain warp — stateless f64-to-voxel', 'D-239 section 4. Stateless hash-based pure fn(seed,body_id,pos) — no lookup table / thread-local cache (order-independent across threads/platforms). Keep f64 sub-metre precision to the final voxel coordinate, then truncate (a cast, NOT a comparison) to the integer voxel address -> IEEE-754-deterministic across targets. +/-8m range makes FMA-contraction ULP variance harmless (no platform guards). Cross-target determinism test. Position math only — D-010 integer discipline preserved on all material/morphology decisions.', 'in_progress', 'high', NULL, 'server', 'D-239', '2026-06-07 10:33:47', '2026-06-07 16:46:01', NULL, 'a507104c0959737d99a128bd9ff2483c', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
|
||||
INSERT INTO tickets (id, type, parent_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-1024', 'task', 'T-974', 'District climate primitives — temperature + moisture (2x2km)', 'D-239 section 2. Scalar district temperature in degrees C, NULLABLE (no atmosphere -> null -> climate branch absent; airless surface ice is geology per D-227). Derived from sun (luminosity+insolation), planet (latitude+elevation lapse+orbital/axial phase=season term, day-phase=diurnal term), atmosphere (greenhouse->base, heat-retention->diurnal-swing amplitude; thick air=small swing). Separate moisture primitive from hydrosphere. Formalises D-210''s temperature proxy. Tiles inherit district values.
|
||||
|
||||
---
|
||||
Refinement (/whats-next 2026-06-07) — gaps resolved with Jeroen:
|
||||
|
||||
1. Data inputs (hybrid): import axial_tilt_deg into the bodies table from the
|
||||
already-authored planet-gen body-def TOMLs (via the import pipeline); derive
|
||||
the rest at runtime in Rust — luminosity from spectral_class lookup, orbital
|
||||
distance (AU) from orbital_period_days via Kepler''s third law + star mass.
|
||||
Do NOT re-encode the full Python tuning tables in Rust beyond these.
|
||||
|
||||
2. Carrier rung: temperature is carried as `temperature_c: Option<f32>` (+ a
|
||||
moisture primitive) ON the T-1023 RegionProfile struct — NOT a new carrier
|
||||
tier. Compute on a 2x2km climate grid; regions sample it. The "~1km vs 2km"
|
||||
label is cosmetic. Needs a one-line D-239 clarification (see note below).
|
||||
|
||||
3. Diurnal-swing values: reuse the tuned greenhouse offsets from
|
||||
tooling/planet-gen planet_simulation.py; add a NEW small atmosphere ->
|
||||
diurnal_amplitude_C table (5 classes; airless/thin large swing ~40-60C,
|
||||
dense/thick small swing ~2-5C). Store these constants in a SOURCE TOML
|
||||
(source-canonical, tunable without recompiling), not hardcoded in Rust.
|
||||
|
||||
4. Season term: produce a MEAN-ANNUAL scalar temperature (orbital phase fixed,
|
||||
e.g. equinox); carry diurnal swing as an amplitude only — NO time argument.
|
||||
No clock dependency. The dynamic clock-bound seasonal branch stays deferred
|
||||
to Q-105 / Phase 5. Per Jeroen: these calculations don''t need perfection;
|
||||
plausible-and-present beats precise.
|
||||
|
||||
Blocked-by T-1023 (temperature fields live on RegionProfile, which T-1023 defines).
|
||||
|
||||
D-239 follow-up: the implementer should add a one-line clarification to D-239
|
||||
(§1/§2) recording that district temperature is a nullable field on RegionProfile
|
||||
sampled from a 2km climate grid, and that climate physics inputs come via the
|
||||
hybrid import/derive strategy above. Fold into the implementation PR.', 'in_progress', 'high', NULL, 'server', 'D-239', '2026-06-07 10:33:47', '2026-06-07 16:46:01', NULL, 'cbef65fab33ff3bc14e65881ac77fbda', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
|
||||
|
||||
Reference in New Issue
Block a user