feat(db): corp-HQ settlement model + per-settlement population/class bake (T-1074/T-1075, D-242)
Remove the reserved=1 corp-HQ city-pool cross-reference (duplicate co-named cities); corp_specialization keyed on the D-237 vocabulary extended 27->30; authored corp_hq_placement.toml {CityTenant,Standalone} map; headquarters_body backfill via lifted most-populated-body heuristic + body-type tiebreak; standalone HQs emitted as ordinary settlement rows; Zipf rank-size population spread from bodies.population at import; settlement_class defaults PopulationBudget + settlement_name_locked.toml hero pins; retire orphaned populate-corporations.sh; regen systems.db.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,194 @@
|
||||
# ==========================================================================
|
||||
# Settled Reach — Corp HQ Placement Map (D-242)
|
||||
# Source of truth. Compiled into corporations.hq_placement by
|
||||
# import_economics.py (populate_corp_specialization), and into the
|
||||
# Standalone-HQ settlement rows atlas_city_names gains by
|
||||
# populate_standalone_hq_settlements (both economy_import/corporations.py).
|
||||
#
|
||||
# D-242: a corporate headquarters is not a city. Each corp's HQ is either:
|
||||
# CityTenant — a tenant of an EXISTING city; a corp -> city link
|
||||
# (corporations.headquarters_city_id), NO new settlement.
|
||||
# Many corps may tenant one city (a bank and a newspaper
|
||||
# share a downtown).
|
||||
# Standalone — its OWN settlement, emitted into the cascade settlement
|
||||
# list with its own body + position (a mine or shipyard
|
||||
# sits alone). Standalone stanzas carry a second field,
|
||||
# standalone_economic_role, so the emitted atlas_city_names
|
||||
# row has a real economic_role (the existing 10-value
|
||||
# D-195/D-197 vocabulary — manufacturing | financial |
|
||||
# agricultural | extraction | service_mixed | institutional |
|
||||
# transit_hub | research | military | residential) instead
|
||||
# of a generic fallback. CityTenant stanzas do not carry this
|
||||
# field — no settlement is emitted for them, so it would be
|
||||
# dead data.
|
||||
#
|
||||
# This file has exactly one stanza per corp_specialization value — the
|
||||
# REUSED D-237 specialization_vocabulary id-space (see
|
||||
# wiki/economics/specialization_vocabulary.toml): the original 27
|
||||
# system-authored values plus 3 corp-only Services-extension values added
|
||||
# alongside this file (trade_distribution, hospitality_hub,
|
||||
# professional_services — a real gap the T-1074 corp categorization pass
|
||||
# found: ~10% of corps do logistics/hospitality/consulting work no original
|
||||
# value covered). D-242 asked for an authored "specialization -> HQ-placement
|
||||
# map"; this vocabulary already exists and already carries the signal that
|
||||
# decides placement (bulk_class_projected: NonPhysical vs everything else),
|
||||
# so rather than invent a second, parallel corp-only taxonomy, the map below
|
||||
# is this vocabulary keyed onto the two-value placement enum (D-242
|
||||
# amendment, recorded 2026-07-16 alongside T-1074).
|
||||
#
|
||||
# The default follows bulk_class_projected exactly:
|
||||
# NonPhysical (financial/institutional/media/legal/research services)
|
||||
# -> CityTenant — an office; no physical plant needed.
|
||||
# Everything else (BulkSolid/BulkLiquid/PrecisionDense/Perishable —
|
||||
# farms, mines, refineries, shipyards, factories)
|
||||
# -> Standalone — needs land/plant of its own.
|
||||
#
|
||||
# hq_placement is authored EXPLICITLY per value (not computed from
|
||||
# bulk_class_projected at import time) so a future ticket can flip one
|
||||
# value without touching import code — three values in the Services group
|
||||
# (governance_center, transit_hub, research_station) are individually
|
||||
# lore-ambiguous (a "transit hub" corp could plausibly BE its own
|
||||
# spaceport-town, e.g. Gateway/Wolf 359 read as whole transit-identity
|
||||
# systems in the vocabulary's own descriptions) but are pinned to the
|
||||
# bulk_class_projected default here for consistency; revisit case-by-case
|
||||
# if a specific corp's placement reads wrong once bodies are walkable.
|
||||
#
|
||||
# Decisions: D-242 (this map), D-237 (the reused vocabulary + the
|
||||
# bulk_class_projected signal this defaults from). Ticket: T-1074.
|
||||
# ==========================================================================
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Agricultural — Standalone (farms/estates need land)
|
||||
# -------------------------------------------------------------------------
|
||||
[estate_farming]
|
||||
hq_placement = "Standalone"
|
||||
standalone_economic_role = "agricultural"
|
||||
|
||||
[breadbasket]
|
||||
hq_placement = "Standalone"
|
||||
standalone_economic_role = "agricultural"
|
||||
|
||||
[terroir_agriculture]
|
||||
hq_placement = "Standalone"
|
||||
standalone_economic_role = "agricultural"
|
||||
|
||||
[terroir_spirits]
|
||||
hq_placement = "Standalone"
|
||||
standalone_economic_role = "agricultural"
|
||||
|
||||
[terroir_organics]
|
||||
hq_placement = "Standalone"
|
||||
standalone_economic_role = "agricultural"
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Energy — Standalone (extraction/refinery infrastructure)
|
||||
# -------------------------------------------------------------------------
|
||||
[fuel_production]
|
||||
hq_placement = "Standalone"
|
||||
standalone_economic_role = "extraction"
|
||||
|
||||
[geothermal_hub]
|
||||
hq_placement = "Standalone"
|
||||
standalone_economic_role = "extraction"
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Extraction — Standalone (mine/quarry sits on the deposit)
|
||||
# -------------------------------------------------------------------------
|
||||
[ore_extraction]
|
||||
hq_placement = "Standalone"
|
||||
standalone_economic_role = "extraction"
|
||||
|
||||
[company_mining]
|
||||
hq_placement = "Standalone"
|
||||
standalone_economic_role = "extraction"
|
||||
|
||||
[marble_monopoly]
|
||||
hq_placement = "Standalone"
|
||||
standalone_economic_role = "extraction"
|
||||
|
||||
[rare_mineral_extraction]
|
||||
hq_placement = "Standalone"
|
||||
standalone_economic_role = "extraction"
|
||||
|
||||
[lattice_material_source]
|
||||
hq_placement = "Standalone"
|
||||
standalone_economic_role = "extraction"
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Manufacturing — Standalone (factory/yard footprint)
|
||||
# -------------------------------------------------------------------------
|
||||
[general_industrial]
|
||||
hq_placement = "Standalone"
|
||||
standalone_economic_role = "manufacturing"
|
||||
|
||||
[shipbuilding]
|
||||
hq_placement = "Standalone"
|
||||
standalone_economic_role = "manufacturing"
|
||||
|
||||
[vehicle_production]
|
||||
hq_placement = "Standalone"
|
||||
standalone_economic_role = "manufacturing"
|
||||
|
||||
[consumer_goods_bazaar]
|
||||
hq_placement = "Standalone"
|
||||
standalone_economic_role = "manufacturing"
|
||||
|
||||
[gate_fabrication]
|
||||
hq_placement = "Standalone"
|
||||
standalone_economic_role = "manufacturing"
|
||||
|
||||
[military_industrial]
|
||||
hq_placement = "Standalone"
|
||||
standalone_economic_role = "military"
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# High-tech — Standalone (fabrication/aquaculture plant)
|
||||
# -------------------------------------------------------------------------
|
||||
[precision_tech]
|
||||
hq_placement = "Standalone"
|
||||
standalone_economic_role = "manufacturing"
|
||||
|
||||
[marine_farming]
|
||||
hq_placement = "Standalone"
|
||||
standalone_economic_role = "agricultural"
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Services (all NonPhysical) — CityTenant (an office, no plant); no
|
||||
# standalone_economic_role — no settlement is ever emitted for these.
|
||||
# -------------------------------------------------------------------------
|
||||
[financial_hub]
|
||||
hq_placement = "CityTenant"
|
||||
|
||||
[governance_center]
|
||||
hq_placement = "CityTenant"
|
||||
|
||||
[transit_hub]
|
||||
hq_placement = "CityTenant"
|
||||
|
||||
[research_station]
|
||||
hq_placement = "CityTenant"
|
||||
|
||||
[legal_archive]
|
||||
hq_placement = "CityTenant"
|
||||
|
||||
[media_center]
|
||||
hq_placement = "CityTenant"
|
||||
|
||||
[longevity_monopoly]
|
||||
hq_placement = "CityTenant"
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Services extension (3, all NonPhysical) — added alongside the vocabulary
|
||||
# extension in specialization_vocabulary.toml (D-242/T-1074). Same rule as
|
||||
# the rest of Services: NonPhysical -> CityTenant (an office/depot, not a
|
||||
# factory — this is exactly what made these corps hard to place in the
|
||||
# original 27).
|
||||
# -------------------------------------------------------------------------
|
||||
[trade_distribution]
|
||||
hq_placement = "CityTenant"
|
||||
|
||||
[hospitality_hub]
|
||||
hq_placement = "CityTenant"
|
||||
|
||||
[professional_services]
|
||||
hq_placement = "CityTenant"
|
||||
@@ -0,0 +1,88 @@
|
||||
# ==========================================================================
|
||||
# Settled Reach — Authored NameLocked Settlement Overrides (D-242, T-1075)
|
||||
# Source of truth. Compiled by import_economics.py
|
||||
# (atlas.populate_settlement_population_class) onto atlas_city_names.settlement_class.
|
||||
#
|
||||
# D-196 defines four SettlementClass variants. Bake scope (T-1075) only
|
||||
# assigns two of them: every pooled city defaults to PopulationBudget (the
|
||||
# D-196 population thresholds — >=50k active / <5k ghost — are read from
|
||||
# this baked population by a later, not-yet-built GENERATION-time consumer;
|
||||
# out of this bake's scope); this file is the small authored override list
|
||||
# that PINS a settlement to NameLocked instead — "named in wiki; always
|
||||
# active regardless of population" (D-196). EconomicTriggered and
|
||||
# OrganicGrowth are simulation-time classes (D-196) — out of bake scope,
|
||||
# never written here.
|
||||
#
|
||||
# Use sparingly. NameLocked exists for settlements whose narrative
|
||||
# significance does not depend on (and must survive) whatever population
|
||||
# number the rank-size bake happens to produce — capitals and the handful of
|
||||
# systems with a singular landmark identity (D-237's must-pin hero systems:
|
||||
# docs/workshops/system-economic-specialization/workshop-outcomes.md §7).
|
||||
#
|
||||
# REVISED 2026-07-16 after the first live make regen-db (T-1074+T-1075
|
||||
# integration test): the first draft of this file picked names straight out
|
||||
# of the PRE-T-1074 atlas_city_names table (Sirius, Groombridge, Cygni B,
|
||||
# Renaissance, Parallax, Prometheus, Nova Roma) — those turned out to be
|
||||
# corp-HQ cross-reference ARTIFACTS from the retired D-207
|
||||
# populate_atlas_city_names_corps (the corp's authored HQ-city text
|
||||
# frequently equalled its system's proper_name, e.g. Gate Corp's
|
||||
# "headquarters: Renaissance (GJ 251)"). Once that insert path was removed
|
||||
# (D-242's whole point), those names no longer exist in the pure
|
||||
# markers.json pool. Every entry below was re-verified against a real
|
||||
# `make regen-db` output — see the note on each stanza for its actual
|
||||
# source row. Prometheus (GJ 702B) is DROPPED from this list — verified
|
||||
# live: every one of its 12 bodies has zero authored markers.json city
|
||||
# names AND zero population, so there is no settlement to pin at all (a
|
||||
# genuine wiki content gap: the Reach's longevity-monopoly hero system has
|
||||
# no named city anywhere in its system — flagged for the lead, not fixed
|
||||
# here; population/settlement_class baking cannot invent a name to pin).
|
||||
#
|
||||
# Match key: (body_id, name) against atlas_city_names — NOT the numeric
|
||||
# atlas_city_names.id, which is regen-volatile (AUTOINCREMENT, no
|
||||
# UNIQUE(body_id, name) — see the atlas_city_names schema comment, D-242).
|
||||
# A stanza with no matching row is a silent no-op (logged) rather than an
|
||||
# import error, so a future markers.json rename doesn't hard-fail regen-db.
|
||||
#
|
||||
# Decisions: D-196 (SettlementClass), D-242 (population/class baking scope),
|
||||
# D-237 (the hero-system set these are drawn from). Ticket: T-1075.
|
||||
# ==========================================================================
|
||||
|
||||
[[hero]]
|
||||
body_id = "GJ144d"
|
||||
name = "Kallast"
|
||||
note = "Kallast / GJ 144 (Ran) — THE breadbasket; lore-anchored plains body (D-239 §1). Pure markers.json pool name, unaffected by the corp-HQ-artifact issue."
|
||||
|
||||
[[hero]]
|
||||
body_id = "GJ820Bc"
|
||||
name = "Cygni Combines"
|
||||
note = "Cygni B / GJ 820B — shipbuilding cluster, 7 competing combines (D-237). D-242 Standalone-HQ settlement (general_industrial corp_specialization) — the corp's own settlement IS the hero identity here; the pure pool has only 'Metropolis' (generic)."
|
||||
|
||||
[[hero]]
|
||||
body_id = "GJ251c"
|
||||
name = "The Gate Corporation"
|
||||
note = "Renaissance / GJ 251 — Gate Corp fabrication monopoly (D-237). D-242 Standalone-HQ settlement (gate_fabrication, MonopolySource) — the pure pool has only 'Tributarium'/'Ruhr' (generic); the monopolist's own company town is the hero place."
|
||||
|
||||
[[hero]]
|
||||
body_id = "GJ764d"
|
||||
name = "Mastroianni Vehicle Group"
|
||||
note = "Nova Roma / GJ 764 — MVG vehicle production (D-237). D-242 Standalone-HQ settlement (vehicle_production) — pure pool has only 'Mirafiori'/'Fiorino' (generic)."
|
||||
|
||||
[[hero]]
|
||||
body_id = "GJ380c"
|
||||
name = "Aldren"
|
||||
note = "Groombridge / GJ 380 — financial cluster + GSH clearing-house landmark (D-237). D-237's hero identity is the SERVICES/finance character, not any one CityTenant corp's manufacturing HQ — pinned to the lowest-id pure-pool city (a CityTenant host) rather than a Standalone-HQ settlement, since Groombridge's Standalone HQs (Alcyone Tech, Arclamp, ...) are all general_industrial/precision_tech, not financial_hub."
|
||||
|
||||
[[hero]]
|
||||
body_id = "GJ244Ad"
|
||||
name = "Mandate"
|
||||
note = "Sirius / GJ 244A — 'the capital' (system_specialization.toml). Lowest-id pure-pool city; the pure pool no longer contains 'Sirius' itself (that was a corp-HQ artifact)."
|
||||
|
||||
[[hero]]
|
||||
body_id = "GJ280Ad"
|
||||
name = "Strata"
|
||||
note = "Parallax / GJ 280A — news syndicates / cultural production center (D-237). Lowest-id pure-pool city (CityTenant host for the media_center specialization)."
|
||||
|
||||
[[hero]]
|
||||
body_id = "GJ338Bd"
|
||||
name = "Viridarium"
|
||||
note = "Arbour / GJ 338B — estate amenity agriculture (D-237). Lowest-id pure-pool city; reads as the manor/estate theme D-237 describes."
|
||||
@@ -1,5 +1,5 @@
|
||||
# ==========================================================================
|
||||
# Settled Reach — Economic Specialization Vocabulary (D-237)
|
||||
# Settled Reach — Economic Specialization Vocabulary (D-237, extended D-242)
|
||||
# Source of truth. Compiled to systems.db specialization_vocabulary by
|
||||
# import_economics.py.
|
||||
#
|
||||
@@ -8,6 +8,18 @@
|
||||
# SCALE is encoded in the value itself (breadbasket vs estate_farming vs
|
||||
# terroir_agriculture) — there is no separate scale column.
|
||||
#
|
||||
# SHARED VOCABULARY (D-242, T-1074): this id-space is used by TWO axes —
|
||||
# system_economy.economic_specialization (D-237, the original per-SYSTEM
|
||||
# authored identity) and corporations.corp_specialization (D-242, the
|
||||
# per-CORP HQ-placement key; see corp_hq_placement.toml). A corp's
|
||||
# specialization is authored directly in its wiki-page frontmatter
|
||||
# (wiki/corporations/*.md, key: corp_specialization), not in a separate
|
||||
# per-corp TOML — one value in this table, two authored sources reading it.
|
||||
# The 3-value "Services extension" block near the end of the Services
|
||||
# section was added for corp_specialization coverage (a corp-only gap the
|
||||
# original 27 system-scale values didn't need to cover); nothing stops a
|
||||
# future system from adopting them too if the fit is right.
|
||||
#
|
||||
# Fields per entry:
|
||||
# commodity_id FK -> commodities.commodity_id (the anchor
|
||||
# commodity; also drives body-level draws)
|
||||
@@ -252,3 +264,41 @@ production_ubiquity_override = "monopolistic"
|
||||
bulk_class_projected = "NonPhysical"
|
||||
production_ubiquity_projected = "MonopolySource"
|
||||
description = "The single licensed longevity/re-embodiment facility; access-controlled (Prometheus)."
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Services extension (3) — added D-242/T-1074 for corp_specialization reuse.
|
||||
#
|
||||
# The categorization pass that backfilled corp_specialization for all 165
|
||||
# corporations (T-1074) found 16/155 wiki corps (~10%) whose actual business
|
||||
# — moving/selling already-made goods, running hospitality/tourism
|
||||
# properties, or general professional advisory — had no honest fit among
|
||||
# the original 24 system-authored values above. Per D-242's amendment
|
||||
# ("prefer reusing/extending the existing vocabulary over inventing a
|
||||
# parallel taxonomy"), these three values extend the shared vocabulary
|
||||
# rather than spawn a corp-only one. All three are NonPhysical (services;
|
||||
# CityTenant HQ placement per corp_hq_placement.toml) even though
|
||||
# trade_distribution's anchor commodity is itself physical — the
|
||||
# SPECIALIZATION is the logistics/service activity, not manufacture, which
|
||||
# is exactly the distinction that made these corps ungroupable in the first
|
||||
# place (a distributor's HQ is an office/depot, not a factory).
|
||||
# -------------------------------------------------------------------------
|
||||
[trade_distribution]
|
||||
commodity_id = "consumer_goods"
|
||||
production_ubiquity_override = "" # catalog default (ubiquitous) — distribution touches everything
|
||||
bulk_class_projected = "NonPhysical"
|
||||
production_ubiquity_projected = "Common"
|
||||
description = "Wholesale/retail trade and freight distribution — moves goods at scale, does not manufacture them (Mercado Travessia, Eastbay Trading)."
|
||||
|
||||
[hospitality_hub]
|
||||
commodity_id = "hospitality"
|
||||
production_ubiquity_override = "" # catalog default (regional)
|
||||
bulk_class_projected = "NonPhysical"
|
||||
production_ubiquity_projected = "Specialist"
|
||||
description = "Lodging, resort, spa, and recovery-stay operators; tourism/hospitality is the settlement's economic identity (Alcazar Hospitality, Thalassa Resort Group)."
|
||||
|
||||
[professional_services]
|
||||
commodity_id = "insurance"
|
||||
production_ubiquity_override = "" # catalog default (regional)
|
||||
bulk_class_projected = "NonPhysical"
|
||||
production_ubiquity_projected = "Common"
|
||||
description = "General business/strategy/operational advisory — risk, consulting, arbitration outside the dedicated legal_archive/financial_hub identities (Saigon Consulting, Lusaka Advisory)."
|
||||
|
||||
Reference in New Issue
Block a user