docs(governance): file D-242 corp-HQ settlement model + T-1074/1075/1076

Reviewing the T-1038 road-graph hub model surfaced that corp HQs are
cross-referenced into atlas_city_names as reserved rows — one per corp —
producing duplicate co-named "cities" (e.g. 10 'Groombridge' rows on
GJ380c) that the spatial layers place as separate settlements.

D-242 resolves the data model: corp HQs are not cities. The HQ relationship
lives with the corp; placement is a baked, specialization-keyed preference
(CityTenant vs Standalone, since corp_type is degenerate); population and
settlement_class are install-baked with only position seed-derived. This
supersedes the D-223 corp-HQ-cross-ref and deferred-pop/class notes.

Companion tickets under T-750: T-1074 (corp-HQ model / remove the cross-ref /
specialization map / standalone HQ settlements), T-1075 (bake per-settlement
population + settlement_class), T-1076 (road-graph hub refinement — scaled-cap
hubs, co-location collapse, hybrid minor attach, deferred RailHeadFacing pass;
blocked on T-1074 + T-1075). T-1038 annotated with shipped-vs-deferred.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-14 20:13:10 +02:00
co-authored by Claude Opus 4.8
parent 1044939748
commit 301be77b49
6 changed files with 168 additions and 1 deletions
+1
View File
@@ -307,6 +307,7 @@ line in place — keep the Q-record for the audit trail rather than deleting it.
- [D-239: Tile derivation contract — coarse→fine refinement chain (resolves Q-101)](decisions/architecture.md#d-239-tile-derivation-contract--coarsefine-refinement-chain-resolves-q-101) — _architecture_
- [D-240: Registry orbit/star data is non-canonical — climate derives from a `planet_class` temperature envelope](decisions/architecture.md#d-240-registry-orbitstar-data-is-non-canonical--climate-derives-from-a-planet-class-temperature-envelope) — _architecture_
- [D-241: Spike binary artifacts are local-only — gitignored, never tracked](decisions/process.md#d-241-spike-binary-artifacts-are-local-only--gitignored-never-tracked) — _process_
- [D-242: Corp HQ settlement model — HQs are not cities; separate from the name pool, specialization-keyed, install-baked](decisions/architecture.md#d-242-corp-hq-settlement-model--hqs-are-not-cities-separate-from-the-name-pool-specialization-keyed-install-baked) — _architecture_
## Open questions
+19 -1
View File
@@ -1787,4 +1787,22 @@ Technical foundation decisions that constrain implementation: engine, client-ser
---
*98 decisions (D-001 through D-240, excluding gaps). Last updated: 2026-06-08 (climate-canonicity correction — D-240 declares registry orbit/star data non-canonical; temperature flips from sun-driven [D-239 §2] to a `planet_class` envelope, superseding the Stefan-Boltzmann path that produced +356 °C "temperate" worlds).*
### D-242: Corp HQ settlement model — HQs are not cities; separate from the name pool, specialization-keyed, install-baked
- **Date:** 2026-06-14
- **Decision:** A corporate **headquarters is not a city** and does not belong in the `atlas_city_names` flavored name pool.
- **Remove the corp-HQ cross-reference into the city pool.** The [D-207](#d-207-fully-generative-placement--markersjson-stripped-to-topographic-features)/[D-223](#d-223) `reserved=1` step (`populate_atlas_city_names_corps`, `tooling/economy-db/economy_import/atlas.py`) inserts **one `atlas_city_names` row per corp HQ** whose name isn't already pooled. With no `UNIQUE(body_id, name)` it produces **duplicate co-named "cities"** — e.g. **10 `Groombridge` rows on GJ380c**, one per corp — which every downstream spatial layer (placement, roads, hinterland) then renders as separate settlements scattered across the map. This insert path is removed; the HQ relationship lives with the corp (`corporations.headquarters_system`, plus a resolved `headquarters_body`), not in the city pool. This **supersedes [D-223](#d-223)'s** "the `reserved=1` corp-HQ cross-reference stays" note.
- **HQ placement is a baked, specialization-keyed preference.** Each corp's HQ is `CityTenant` or `Standalone`, chosen by a **source-canonical `specialization → HQ-placement` map** (`corp_type` is degenerate — only `corporation`/`combine`, 158/7 — so the key is `corporations.specialization`, optionally `supply_chain_role`):
- **CityTenant** (finance, media, retail, services …): the HQ is a **tenant of an existing city** — a corp→city link, **no new settlement**. Many corps may tenant one city (supplemental, non-competing HQs realistically cluster — a bank and a newspaper share a downtown).
- **Standalone** (extraction/mining, heavy industry, shipyards …): the HQ **is its own settlement**, emitted into the cascade settlement list with its own body + position, so the road graph and downstream layers treat it as a place.
- The preference depends only on corp specialization — **not on seed or install** — so it is authored once and baked into `systems.db` at import (a difference of corp *type*, not of run).
- **`population` and `settlement_class` are install-baked, not seed-derived.** Body-level `population` is already baked (273/3 240 bodies > 0); the **per-settlement spread is carried down into the city/settlement source data**, so every settlement starts with a fixed `population` + `settlement_class`. **Only position remains seed-derived** (the [D-211](#d-211) placement pipeline). This **supersedes [D-223](#d-223)'s** "`population`/`settlement_class` deferred to placement (T-955)" and **retires the never-built "assign population from the seed" step** — `match_cities` only ever *read* those fields (all `0`/NULL) and nothing assigned them, so faking population in the seed layer buys nothing over baking it.
- **The cascade settlement input** = the city name pool (cities, baked pop/class) **+** standalone-HQ settlements, merged. The Layer-2 road graph ([D-211](#d-211), T-1038) routes over that merged list unchanged; "hubs" are the significant cities, standalone HQs are typically minor nodes.
- **Rationale:** Modelling HQs as city rows conflated two different things and made corp-dense worlds nonsensical — ten "Groombridge" dots, ten trunk roads, where there is one city hosting ten tenants. HQs *are* sometimes their own settlement (a mine or shipyard sits alone) and *sometimes* a tenant (a bank wants a downtown); that split is intrinsic to the corp's specialization and never varies by run, so it is authored, not derived. Baking `population`/`settlement_class` (rather than deriving them from the seed) keeps generation deterministic with **only position variable**, matches the already-baked body population, and deletes an unbuilt seed step instead of building it. The names pool ([D-223](#d-223)) returns to being **cities only**.
- **Raised by:** Jeroen, 2026-06-14 — reviewing the T-1038 road-graph hub model; the corp-HQ-as-city rows surfaced as duplicate map settlements.
- **Implementation:** corp-HQ model + specialization map + standalone-HQ settlements, remove the cross-ref insert, resolve `headquarters_body` (**T-1074**); per-settlement population/settlement_class baking (**T-1075**); and the gated road-graph hub refinement — scaled-cap hubs + co-location collapse + hybrid minor-settlement attach + the deferred `RailHeadFacing` junction pass (which itself needs a [D-213](#d-213) amendment) — (**T-1076**, blocked by T-1074 + T-1075). All under Phase 4 (epic T-750). The T-1038 road-graph **core** (MST + A\* + MaintenanceAuthority + waypoints + junction detection) ships independently of this record — it routes over whatever settlement list it is handed.
- **Cross-reference:** [D-207](#d-207-fully-generative-placement--markersjson-stripped-to-topographic-features) (corp-HQ cross-ref — the insert path is removed here), [D-223](#d-223) (names-only pool — the corp-HQ-stays + pop/class-deferred notes are superseded here), [D-211](#d-211) (placement — consumes the merged list; only position is seed-derived), [D-213](#d-213) (`FoundingOrientation` — a `RailHeadFacing` variant is the gated follow-on), [D-237](#d-237) (corp `specialization` vocabulary — the HQ-placement key), [D-010](#d-010) (determinism — only position is seed-derived).
- **Dissent:** None
---
*99 decisions (D-001 through D-242, excluding gaps). Last updated: 2026-06-14 (corp-HQ settlement model — D-242: HQs leave the city name pool, HQ placement is a specialization-keyed CityTenant/Standalone preference, population/settlement_class become install-baked with only position seed-derived; supersedes the D-223 corp-HQ-cross-ref and deferred-pop/class notes).*