Implements the D-237 authored per-system specialization layer end-to-end and
rebalances the corridor's cultural distribution on top of it.
Each inhabited system gains three authored, deterministic identity fields that feed
world generation:
economic_specialization — 27-value vocabulary with scale baked in (breadbasket
vs estate_farm vs terroir), each mapped to a D-233 BulkClass × ProductionUbiquity
projection via specialization_vocabulary
cultural_specialization — activity or founding-heritage value (heritage wins)
dominant_faction — D-214 PoliticalArchetype
Authored lore wins; unnamed systems fall back to the generator heuristic (NULL).
The corridor over-represented southern-African heritage (afrikaans on 15 systems;
arab=2, persian/turkic=0). Five genuinely-thin afrikaans systems — whose distinctive
threads are heritage-agnostic — are refounded with new cultures:
Result: afrikaans 15→10; arab 0→2, persian 0→2, turkic 0→1. Full narrative
retouch (gttr + index prose, body/station names, gttr_hook, atlas_city_names), the
4 brand-corps named after the converted systems renamed (corp IDs kept stable), and
all cross-references (neighbours, catalog, aggregate drifter guides, atlas proposals)
updated to match. Load-bearing mystery systems (Eerste Wacht, Helderoog, Brandpunt)
left untouched. Also fixes a pre-existing canon bug: Sawad no longer claims GJ 914A
is "unsettled" — it is Marib, a three-century settlement.
Notes / follow-ups
_CULTURAL_HERITAGE gained arab/persian/turkic here so the rebalance values
validate. The full canonical 47-value migration (renaming the 4 hero values,
normalizing all sectors) remains #1016 — taxonomy doc records the rest.
--strict-specialization completeness gates stay off-by-default until #1014 / #1016 land.
Verification
make regen-db clean · meta stamp fresh · DB + file + corp-source stale-name sweeps
all clean · ruff clean · pre-push gates (cargo-deny, ruff, JSON, systems.db stamp) green.
Wires the D-237 authored specialization layer into import_economics.py:
- import_system_specialization(): reads specialization_vocabulary.toml
(FK-validated against commodities; repopulates specialization_vocabulary)
and system_specialization.toml (UPSERTs economic_specialization +
cultural_specialization onto system_economy, dominant_faction onto
system_factions for authored systems only). Hard errors on bad commodity
FK / projected enum / unknown system_id abort the transaction; prints a
coverage report + missing-row warnings.
- Called as step 4b in main() (after commodities so the FK resolves, before
currency zones). economic/cultural columns are importer-owned and cleared
to NULL first for idempotency; dominant_faction only overwritten for
authored systems (never globally cleared — shared with other derivation).
- specialization_vocabulary added to MIGRATION_SQL (after commodities for FK)
so the migration path on existing DBs creates the table, not just fresh
systems-schema.sql builds — this is what #1011 missed. Also cleared before
commodities in the FK-safe clear block.
- Both source TOMLs added to IMPORT_ECONOMICS_SOURCES and mirrored in
check-systems-db-stamp GENERATOR_SOURCES so editing them flips the stamp.
Validated: full non-dry-run import on a copy of the live systems.db exits 0;
27 vocab rows, 27/27/27 economic/cultural/faction set, no missing rows;
spot checks Ran=breadbasket/agrarian, Vuurkloof=independent,
financial_hub=NonPhysical/Specialist. Dry-run also exits 0.
V-SES CI guardrail suite remains #1015; code note flags that V-SES-03
(equal-or-higher) must not hard-fail HUB specializations.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds the V-SES / V-FAC guardrail suite to import_system_specialization():
Always-on hard errors (abort the import transaction): V-SES-01 economic
value in vocabulary; V-SES-03 production_ubiquity_override >= commodity
catalog concentration (HUB values with empty override exempt — they
intentionally project lower); V-SES-04 cultural value in the combined
activity+heritage vocabulary; V-SES-05 faction in 8-value vocab; V-SES-06
vocab commodity FK; plus unknown system_id.
Completeness gates — V-SES-02 (every inhabited system resolves a non-null
economic value) and V-FAC-01 (every inhabited named system has authored
faction) — are HARD only under --strict-specialization (default off). Their
preconditions are the #1014 heuristic fallback (blocked by #982) and the
#1016 content pass; until those land they print as warnings so regen-db
stays green.
Soft warnings (always print): W-SES-01 MonopolySource D-177 review list,
W-SES-02 single-value concentration, W-SES-08 estate_farming + large pop,
W-FAC-01 compact + TRACTUS currency, W-FAC-02 compact + MonopolySource
(terroir/marble exempt), W-FAC-03 syndic_dominant w/o corp HQ, W-FAC-04
compact_sympathetic + MARK currency. Coverage report always prints
economic/cultural/faction counts + BulkClass/ProductionUbiquity dists.
Cultural vocabulary is _CULTURAL_ACTIVITY | _CULTURAL_HERITAGE module
constants — #1016 adds heritage values there in one place.
Validated on a copy of the live DB: default exits 0 (gates as warnings, real
W-SES-08 hit on Arbour); strict exits 1 on V-SES-02 (Sol, Struve) and rolls
back cleanly; dry-run exits 0.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The #1015 V-SES-03 edit replaced the vocabulary validation loop body and
dropped the trailing vocab_rows.append(), so specialization_vocabulary was
inserted with 0 rows even though per-system UPSERTs (which read the dict
directly via valid_spec_ids) still succeeded. regen-db reported
'vocab 0 | economic 27 | ...'. Restored the append at the end of the loop.
Verified: regen-db now writes 27 vocab rows + 27/27 economic/cultural;
spot checks financial_hub=NonPhysical/Specialist, Ran=breadbasket.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
make regen-db with the D-237 authored layer live: 27-row
specialization_vocabulary, economic_specialization + cultural_specialization
on 27 hero systems, dominant_faction on the authored set. Meta stamp fresh
(check-systems-db OK). Unauthored systems remain NULL pending the #1014
fallback and #1016 content pass.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Records that the two are a deliberate parallel representation, not a
duplicate: economic_base_primary is uncomputable GTTR prose flavor rendered
to the wiki infobox; economic_specialization is the higher-fidelity enum the
D-233 generator consumes. Notes they must stay mutually consistent (#1016
authors the enum from the same lore; W-SES-03 flags divergence), that
unification was considered and rejected (each carries info the other can't),
and clarifies the DB-canonical / index.md-projection data flow (only the
prose sections are authored in-place). Surfaced when the content-pass review
questioned the redundancy.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
generate_infobox() now renders economic_specialization (Specialization) and
cultural_specialization (Cultural Register) as read-only infobox rows when
authored (NULL = omitted, falls to heuristic). dominant_faction already
showed via Governance. Makes the authored generator-input values visible on
the wiki face so the #1016 content pass output renders. Verified: Ran shows
'breadbasket'/'agrarian'; unauthored systems omit the rows.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The 6-sector content pass (core pilot + deep_frontier/north/east/south/west,
~260 systems read from both index.md and gttr.md) authored economic_
specialization + dominant_faction for the systems whose lore makes those
identities distinct. Conservative pin bar: corridor-typical systems left NULL
for the heuristic/derivation fallback.
Totals now: economic 170 (27 hero + 143), faction 76 (27 hero + 49),
cultural still 27 (DEFERRED — the culture pass needs a canonical heritage
vocabulary first; the agents surfaced ~30 real heritages from the names plus a
genuine Middle-East/Arabic gap, to be reconciled into one taxonomy before
writing cultural_specialization).
regen-db green, stamp fresh, all CI guardrails pass. Soft warnings are the
expected D-177 MonopolySource review list, the known Arbour estate/breadbasket
question, and sparse-corp_presence W-FAC-03 advisories — none blocking.
Notable pins: Haodu financial_hub/syndic_dominant, Matamba legal_archive,
Inhambane/Sonnwend/etc breadbasket, the terroir cluster, the west_reach
Compact zone, Aurelius governance_center/veil_institute. FLAGs left NULL
pending human calls (ISPI=veil_institute?, Gate-Corp-as-faction).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reconciles the ~30 inconsistent heritage proposals from the 6-sector #1016
content pass into one canonical cultural_specialization heritage vocabulary
(47 values). Key reconciliations: norse_compact->nordic (un-fuses people from
faction), spanish_iberian+spanish_hispanic->spanish, brazilian_portuguese+
lusophone_frontier->brazilian, italian_northern->italian, afrikaans_cape->
afrikaans, french_provencal+french_canadian->french. No compound values; one
token per system (blends take dominant heritage or the cosmopolitan activity
value).
Maintainer decisions (2026-06-01): keep ALL values distinct (no lumping —
welsh/afro_brazilian/cape_malay/xhosa/luxembourgish/konkan all retained);
keep empty-but-complete slots (yoruba/hausa/hungarian/persian/turkic). Fills
the Middle-East gap the pass exposed: arab/persian/turkic added even at near-
zero current usage so the canon is complete.
Logs the southern-African overrepresentation (~25/300, afrikaans=15) as a DLC
content-rewrite rebalancing task (#1019) rather than lumping the taxonomy.
Migration note included: 4 already-shipped hero cultural values use old suffix
forms (afrikaans_cape, french_provencal, italian_northern, norse_compact) and
will be renamed in the culture-write pass when _CULTURAL_HERITAGE is replaced.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The corridor over-represented southern-African heritage (afrikaans on 15
systems; arab=2, persian/turkic=0) as an artifact of the earlier
name-balancing overcorrecting. Convert five genuinely-thin afrikaans
systems — whose distinctive threads are heritage-agnostic — into
Arab/Persian/Turkic founders so the cultural cascade is built on a
balanced set. Load-bearing mystery systems (Eerste Wacht / Helderoog /
Brandpunt etc.) are left untouched.
Droëland (GJ 914A) -> Marib (arab)
Stilwater (GJ 508A) -> Sawad (arab)
Koeberg (GJ 1245B) -> Akhgar (persian)
Skuilplek (GJ 722) -> Siginak (turkic)
Carnarvon (GJ 680) -> Golestan (persian; Mostert dynasty -> Farahani)
Result: afrikaans 15->10; arab 0->2, persian 0->2, turkic 0->1.
Full narrative retouch (not just names): gttr.md + index.md prose,
body/station proper_names, cultural_specialization, gttr_hook,
atlas_city_names, and the four brand-corps named after the converted
systems (corp IDs kept stable; only display names + products renamed).
Cross-references in neighbour systems, the catalog, the aggregate
drifter guides, and the atlas proposals are updated to match.
arab/persian/turkic added to _CULTURAL_HERITAGE so the values validate;
the full canonical 47-value migration remains #1016.
Also fixes a pre-existing canon bug: Sawad (GJ 508A) no longer claims
GJ 914A is "unsettled" — it is Marib, a three-century settlement.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The pre-execution conversion plan and shipped-state addendum for the
South-African heritage rebalance: per-system field maps, the worked
gttr rewrites, the cross-reference cleanup list, and the rationale for
keeping load-bearing mystery systems out of scope.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Review fixes for the #1019 heritage rebalance:
- Marib's farm world Ghouta -> Ghawr (Miri): "Ghouta" carries strong
modern associations (2013 Damascus attack); Ghawr (the Jordan Rift
Valley, an irrigated lowland farming region) keeps the water-fed-
drylands sense without the resonance.
- Add dominant_faction = "independent" to GJ 914A / 508A / 1245B (Hoshe)
— all five rebalanced systems are self-governing independent
communities; uniform with siblings GJ 722 / 680 and clears V-FAC-01.
- catalog.md: fill GJ 914A -> Marib and GJ 722 -> Sığınak (Hoshe) — the
two anchor systems still showed em-dash placeholders.
- Marib gttr: name the second aperture neighbour Sığınak instead of the
bare "GJ 722" (Miri).
Pre-existing Golestan aperture/spur wording (reviewers split on whether
it is even wrong) is left for a separate content pass — not introduced
by this rename.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Multi-agent review (Hoshe / Paula / Miri) of the D-237 specialization layer + #1019 heritage rebalance.
Reviewer
Focus
Verdict
Hoshe
QA / integrity
REQUEST_CHANGES
Paula
Narrative depth
APPROVE
Miri
World consistency
REQUEST_CHANGES
Initial verdict: CHANGES REQUESTED. All actionable findings have now been addressed in 8dc6c0ed4.
Findings & resolutions
#
Reviewer
Finding
Resolution
1
Hoshe
system_specialization.toml — GJ 914A/508A/1245B lacked dominant_faction while siblings 722/680 had it; fires V-FAC-01
Fixed — added dominant_faction = "independent" to all three (all five are self-governing independent communities); V-FAC-01 cleared
2
Hoshe
catalog.md — GJ 914A & GJ 722 still showed — in the name column
Fixed — filled in Marib / Sığınak
3
Miri
Marib gttr named its 2nd aperture by bare ID "GJ 722"
Fixed — now "Sawad and Sığınak"
4
Miri
Body name Ghouta carries modern (2013) connotations
Fixed — renamed Ghouta → Ghawr (Jordan Rift Valley; keeps the irrigated-drylands etymology without the resonance). Maintainer-confirmed
5
Hoshe
Golestan gttr "one aperture connecting to Enugu and Athabasca" vs infobox "2 aperture"
Deferred (not introduced here). Inherited verbatim from the original Carnarvon page; reviewers split (Miri reads it as the setting's normal single-gate-spur framing). A proper fix needs a topology decision — tracked for a separate content pass, not this rename
Paula refinements (non-blocking, acknowledged)
Landbou Raad gloss ("external Cape-heritage corridor institution") is in Sawad's gttr but not its index prose — minor, left for a future polish pass.
"Helderoog" column placement in the Brandpunt naming-convention sentence is debatable but defensible as written.
Verified after fixes
make regen-db clean · stale-name sweep CLEAN across wiki/docs/client · dominant_faction applied to all 5 · Ghawr persisted (atlas_city_names clean) · meta stamp fresh · pre-push gates (cargo-deny, ruff, JSON, systems.db stamp) green.
Paula's standout note: the Golestan opening ("…the irony of naming the place after a walled garden one family tends has occurred to no one as worth commenting on") lands the Drifter's Guide voice well, and the Sawad canon-bug fix (GJ 914A no longer called "unsettled") is confirmed correct.
## Review — PR #146 (copy: wiki/docs content)
Multi-agent review (Hoshe / Paula / Miri) of the D-237 specialization layer + #1019 heritage rebalance.
| Reviewer | Focus | Verdict |
|---|---|---|
| Hoshe | QA / integrity | REQUEST_CHANGES |
| Paula | Narrative depth | APPROVE |
| Miri | World consistency | REQUEST_CHANGES |
**Initial verdict: CHANGES REQUESTED.** All actionable findings have now been addressed in `8dc6c0ed4`.
### Findings & resolutions
| # | Reviewer | Finding | Resolution |
|---|----------|---------|------------|
| 1 | Hoshe | `system_specialization.toml` — GJ 914A/508A/1245B lacked `dominant_faction` while siblings 722/680 had it; fires V-FAC-01 | **Fixed** — added `dominant_faction = "independent"` to all three (all five are self-governing independent communities); V-FAC-01 cleared |
| 2 | Hoshe | `catalog.md` — GJ 914A & GJ 722 still showed `—` in the name column | **Fixed** — filled in **Marib** / **Sığınak** |
| 3 | Miri | Marib gttr named its 2nd aperture by bare ID "GJ 722" | **Fixed** — now "Sawad and Sığınak" |
| 4 | Miri | Body name **Ghouta** carries modern (2013) connotations | **Fixed** — renamed **Ghouta → Ghawr** (Jordan Rift Valley; keeps the irrigated-drylands etymology without the resonance). Maintainer-confirmed |
| 5 | Hoshe | Golestan gttr "one aperture connecting to Enugu and Athabasca" vs infobox "2 aperture" | **Deferred (not introduced here).** Inherited verbatim from the original Carnarvon page; reviewers split (Miri reads it as the setting's normal single-gate-spur framing). A proper fix needs a topology decision — tracked for a separate content pass, not this rename |
### Paula refinements (non-blocking, acknowledged)
- Landbou Raad gloss ("external Cape-heritage corridor institution") is in Sawad's gttr but not its index prose — minor, left for a future polish pass.
- "Helderoog" column placement in the Brandpunt naming-convention sentence is debatable but defensible as written.
### Verified after fixes
`make regen-db` clean · stale-name sweep CLEAN across wiki/docs/client · `dominant_faction` applied to all 5 · Ghawr persisted (atlas_city_names clean) · meta stamp fresh · pre-push gates (cargo-deny, ruff, JSON, systems.db stamp) green.
Paula's standout note: the Golestan opening ("…the irony of naming the place after a walled garden one family tends has occurred to no one as worth commenting on") lands the Drifter's Guide voice well, and the Sawad canon-bug fix (GJ 914A no longer called "unsettled") is confirmed correct.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
GJ 680 has aperture_count=2 / gate_connections=2, linking two distinct
systems (Athabasca GJ 1289 and Enugu GJ 75) — but the prose, inherited
verbatim from the original Carnarvon page, described "one gate in, one
gate out, both the same gate" and "one aperture connecting to Enugu and
Athabasca" (self-contradictory). Reword the gttr and index to two gates
while keeping the system's low-through-traffic spur character (the
spur_end topology label and "nobody routes through here" identity are
unchanged). Resolves the deferred PR #146 review finding.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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
Implements the D-237 authored per-system specialization layer end-to-end and
rebalances the corridor's cultural distribution on top of it.
Each inhabited system gains three authored, deterministic identity fields that feed
world generation:
economic_specialization— 27-value vocabulary with scale baked in (breadbasketvs estate_farm vs terroir), each mapped to a D-233 BulkClass × ProductionUbiquity
projection via
specialization_vocabularycultural_specialization— activity or founding-heritage value (heritage wins)dominant_faction— D-214 PoliticalArchetypeAuthored lore wins; unnamed systems fall back to the generator heuristic (NULL).
What's in the branch
4f53793(#schema)import_system_specialization()883c1ab(#1013),9fe4ddf(fix)2f994c1(#1015)0251c65e0d7963(D-237)8addf04(#1016, cultural deferred)01ba14a8844bef(#1019)03188de,36ae931Heritage rebalance (#1019)
The corridor over-represented southern-African heritage (afrikaans on 15 systems;
arab=2, persian/turkic=0). Five genuinely-thin afrikaans systems — whose distinctive
threads are heritage-agnostic — are refounded with new cultures:
Result: afrikaans 15→10; arab 0→2, persian 0→2, turkic 0→1. Full narrative
retouch (gttr + index prose, body/station names, gttr_hook, atlas_city_names), the
4 brand-corps named after the converted systems renamed (corp IDs kept stable), and
all cross-references (neighbours, catalog, aggregate drifter guides, atlas proposals)
updated to match. Load-bearing mystery systems (Eerste Wacht, Helderoog, Brandpunt)
left untouched. Also fixes a pre-existing canon bug: Sawad no longer claims GJ 914A
is "unsettled" — it is Marib, a three-century settlement.
Notes / follow-ups
_CULTURAL_HERITAGEgainedarab/persian/turkichere so the rebalance valuesvalidate. The full canonical 47-value migration (renaming the 4 hero values,
normalizing all sectors) remains #1016 — taxonomy doc records the rest.
--strict-specializationcompleteness gates stay off-by-default until #1014 /#1016 land.
Verification
make regen-dbclean · meta stamp fresh · DB + file + corp-source stale-name sweepsall clean · ruff clean · pre-push gates (cargo-deny, ruff, JSON, systems.db stamp) green.
🤖 Generated with Claude Code
Review — PR #146 (copy: wiki/docs content)
Multi-agent review (Hoshe / Paula / Miri) of the D-237 specialization layer + #1019 heritage rebalance.
Initial verdict: CHANGES REQUESTED. All actionable findings have now been addressed in
8dc6c0ed4.Findings & resolutions
system_specialization.toml— GJ 914A/508A/1245B lackeddominant_factionwhile siblings 722/680 had it; fires V-FAC-01dominant_faction = "independent"to all three (all five are self-governing independent communities); V-FAC-01 clearedcatalog.md— GJ 914A & GJ 722 still showed—in the name columnPaula refinements (non-blocking, acknowledged)
Verified after fixes
make regen-dbclean · stale-name sweep CLEAN across wiki/docs/client ·dominant_factionapplied to all 5 · Ghawr persisted (atlas_city_names clean) · meta stamp fresh · pre-push gates (cargo-deny, ruff, JSON, systems.db stamp) green.Paula's standout note: the Golestan opening ("…the irony of naming the place after a walled garden one family tends has occurred to no one as worth commenting on") lands the Drifter's Guide voice well, and the Sawad canon-bug fix (GJ 914A no longer called "unsettled") is confirmed correct.
🤖 Generated with Claude Code
Pull request closed