# Atlas Generator Refinement Notes — Sprint 36 **Scope:** Systems-level sanity pass across 273 inhabited bodies (ticket #838). **Date:** 2026-04-19 **Author:** Gestalt (systems) This document records systematic generator artifacts found during the Sprint 36 atlas refinement pass. Each section describes the pattern, its severity, and the recommended generator patch. --- ## 1. Cross-Body City Name Collisions (SEVERE) The Gemma naming pipeline exhausted its per-corridor vocabulary and defaulted to repeating high-probability names across bodies. 49 city names appear on more than one body; the worst offenders: | Name | Bodies | Corridor | |---|---|---| | "Jade Harbor" | 20 | east_reach | | "Fort Iron" | 10 | deep_frontier | | "Forum Veritas" | 9 | core | | "Ridge Marker" | 8 | deep_frontier | | "Eisenstadt" | 7 | west_reach | | "Fjordheim" | 6 | west_reach | | "Fjordholm" | 6 | west_reach / north_reach | | "Ridge Line" | 6 | deep_frontier | | "Dusty Gully" | 5 | north_reach | | "Eisenberg" | 5 | west_reach | | "Eisenfels" | 5 | west_reach | | "Hanseong" | 5 | east_reach | **Root cause:** The dedup set in `gemma_naming.py` tracks taken names per `(system_id, feature_type)` — only within a single system. Cross-system dedup does not exist. Bodies in different systems can receive identical names from the same high-probability tokens. **Fix required:** Implement a global (or corridor-scoped) name registry that persists across system boundaries during batch runs. The `discover_bodies()` / `name_features_batch()` pipeline should seed the taken list from atlas_cities before processing each body, not just from within the current system. **Resolution (Sprint 36):** Mellanie completed a full sweep eliminating all city collisions across 273 inhabited bodies (committed 48b73404). Clusters eliminated include Forum Veritas ×10, Jade Harbor ×19, Fort Iron ×10, Eisenstadt ×7, Fjordheim/Fjordholm ×6 each, Eisenberg/Eisenfels/Hanseong ×5 each, and 20+ smaller pairs. City collision count is now zero. --- ## 2. Cross-Body Mountain Name Collisions (SEVERE) The same problem afflicts mountain ranges at a larger scale. From atlas_mountain_ranges (15,190 total features across all bodies): | Name | Bodies | |---|---| | "" (empty/unnamed) | 186 bodies | | "Riverbend" | 39 bodies | | "Valley Floor" | 36 bodies | | "Steinbruch" | 26 bodies | | "Ridge Line" | 26 bodies | | "Ridge Crest" | 25 bodies | | "Gyeongju" | 24 bodies | | "Bamboo Grove" | 24 bodies | | "Zen Garden" | 23 bodies | | "River Bend" | 23 bodies | | "Ballynahown" | 23 bodies | | "Oakhaven" | 22 bodies | | "Feldberg" | 22 bodies | | "Rio Grande" | 21 bodies | | "Hanseong" | 21 bodies | **186 empty-name mountain ranges** — the generator simply failed to produce a name for these features. They exist in the markers.json with `"name": ""`. **Root cause:** Same as city collisions — no cross-system dedup. Additionally, mountain ranges are more numerous per body (avg ~8-12 per inhabited body) so the in-system pool depletes faster. **Fix required:** 1. Cross-system mountain name dedup (same approach as city fix above). 2. Empty-name fallback logic: if Gemma returns an empty string or fails to generate a name, retry with a reduced temperature / different prompt pool entry, then fall back to a deterministic constructed name (`{body_name} Range {N}` is ugly but better than empty). --- ## 3. Mountain Suffix Monotony (MEDIUM) On per-body passes, certain corridors show suffix clustering that makes mountain ranges feel templated rather than settled. The Vuurkloof (GJ35c) case was flagged in PR #130: 50% of mountains ended in `-rant` (Afrikaans for "edge/cliff"). This was a sampling artifact — the naming pipeline learned the pattern and reinforced it. **Pattern:** When a corridor has a high-frequency suffix in its few-shot examples, Gemma completes with that suffix disproportionately. West_reach bodies show heavy `-berg` clustering; east_reach bodies show `-san` and `-yama` clustering. **Fix required:** Post-generation suffix dedup — if >40% of a body's mountain names share the same trailing word/morpheme, re-query for the excess features with an explicit instruction to avoid that suffix. --- ## 4. Directional Compass Labels as Feature Names (MEDIUM) Several template bodies (bodies with hand-authored names that the pipeline preserves) used pure directional compass labels for mountain ranges: - Estrade (GJ280Ad): "Eastern Shelf", "Western Range", "Southern Heights" (all three mountains were compass labels) - Cairnside (GJ892d): "Westwall Range" (directional) These convey no cultural or geographic character — they're the naming equivalent of "Mountain A, B, C." **Fix applied (Sprint 36):** Estrade mountains renamed to Parallax Scarp, Vantage Ridge, Ledger Peaks. Cairnside "Westwall Range" renamed to Kappa Escarpment. **Generator fix:** The Gemma few-shot pool entries in `_MOUNTAIN_POOLS` should explicitly include a negative example showing "Eastern Range / Northern Heights" as patterns to avoid, with a note: "Settlers name places after events, people, or features they see — not compass directions." --- ## 5. Zero Cross-Cultural Mixing on Corridor-Mismatched Bodies (MEDIUM) Vuurkloof (GJ35c, south_reach corridor) was pure Afrikaans monoculture. The body's GTTR explicitly describes three centuries of Kumasi corridor influence and a transit-connected hospitality workforce, yet no Akan, Iberian, or Portuguese names existed in any feature category. **Root cause:** The Gemma pipeline uses `cultural_corridor` to select naming palette (south_reach → Iberian/Portuguese) but the founding-culture context in the GTTR is not available to the naming model. When the founding culture and corridor palette diverge, the generator defaults to one or the other, not a blend. **Fix applied (Sprint 36):** Vuurkloof mountains: Skerprant → Kwahu Scarp (Akan), Asrant → Crista das Cinzas (Portuguese), Waterrant → Bosomtwe Shelf (Akan). River: Rooistroom → Obotan (Akan). Ocean: Suidelike Poel → Lagoa do Sul (Portuguese). **Generator fix:** The `gemma_naming.py` pipeline already reads `gttr_hook` per body. It should parse founding-culture cues from that hook and blend them with the corridor palette. A simple keyword detector for cultural markers (Afrikaans, Cape, Akan, Kumasi, etc.) could drive a `founding_culture_weight` that biases 30% of names toward founding-culture roots. --- ## 6. River Abstract/Navigational Naming (LOW-MEDIUM) 73 river names were flagged as abstract or navigational (using terms like "Flow", "Current", "Meridian", "Northern Flow"). Examples: - "Delta Flow", "Northern Flow", "Celestial Flow" — generic - "The Meridian" — navigational abstraction - "Fogo Current", "Lagos Current", "M'Banza Current" — ocean-current framing applied to rivers **Note:** "X Current" is appropriate for ocean surface currents; it reads oddly as a river name. Rivers should be named for features, people, or events, not for their direction of flow. **Root cause:** The `_RIVER_POOLS` in `gemma_naming.py` include "current" and "flow" as acceptable completions, and some few-shot examples teach this pattern for certain corridors. **Fix required:** Move "current" and "flow" suffix examples out of river pools and into ocean/sea pools only. Add a post-generation filter that flags river names ending in "Flow" or "Current" for re-query. --- ## 7. Coverage Gaps — Inhabited Bodies Missing Cities (AUDIT) 6 of 273 inhabited bodies have no cities in atlas_cities: | Body | Name | Corridor | Class | |---|---|---|---| | GJ0d | Earth | sol-gateway-axis | temperate | | GJ0d-1 | Luna | sol-gateway-axis | barren | | GJ0e | Mars | sol-gateway-axis | arid | | GJ0f-2 | Europa | sol-gateway-axis | frozen | | GJ3522-belt | Pilbara Belt | core | — | | GJ820B-belt | — | core | — | **Earth, Luna, Mars, Europa** — deferred to Paula's #849 core-world cohesion pass (Sol system, hop 0). **Pilbara Belt, GJ820B-belt** — asteroid belts. These may not need traditional city placements. Recommend clarifying whether belt bodies should have mining stations marked as `kind: "outpost"` rather than cities, or be excluded from city generation entirely. --- ## 8. Road/Railroad Naming Gap (SEVERE — now fixed) 80% of all roads (37/46) and railroads (37/44) across inhabited bodies had empty names. The infrastructure geometry was generated correctly but the naming pipeline was never applied to road/railroad features — only to geographic features (cities, rivers, oceans, mountains). **Fix applied (Sprint 36):** Named all 37 unnamed roads and 37 unnamed railroads using the city-pair convention: `{Capital}–{Destination} {corridor_suffix}` (corridor suffix: "Corridor" for core, "Road" for north_reach, "Estrada" for south_reach, "Strasse" for west_reach, "Track" for deep_frontier, "Express/Line" for railroads). **Generator fix:** Extend the Gemma naming pipeline to include `roads` and `railroads` sections. Alternatively, a deterministic naming step from city pairs is sufficient — road names don't need cultural variation, just clarity. --- ## Metrics Before vs After Sprint 36 Refinement | Metric | Before | After | |---|---|---| | Cross-body city collision names | 49 | 0 (Mellanie Sprint 36 full sweep) | | Worst collision ("Jade Harbor") | 20 bodies | 0 (eliminated) | | Unnamed roads | 37 / 46 (80%) | 0 / 46 (0%) | | Unnamed railroads | 37 / 44 (84%) | 0 / 44 (0%) | | Mountain cardinal-direction names (inhabited bodies) | ~45+ | 14 / 1638 (0%) | --- ## Fixes Applied This Sprint ### Pass 1 — Template bodies (PR #130 review) | Body | Body Name | System | What Changed | |---|---|---|---| | GJ892d | Cairnside | GJ 892 (Cairnside) | "Westwall Range" → "Kappa Escarpment" | | GJ280Ad | Estrade | GJ 280A (Parallax) | "Eastern Shelf" → "Parallax Scarp"; "Western Range" → "Vantage Ridge"; "Southern Heights" → "Ledger Peaks" | | GJ35c | Vuurkloof | GJ 35 (Vuurkloof) | Mountains: Skerprant → Kwahu Scarp, Asrant → Crista das Cinzas, Waterrant → Bosomtwe Shelf; River: Rooistroom → Obotan; Ocean: Suidelike Poel → Lagoa do Sul | ### Pass 2 — Mid-tier bodies (severity-ranked pass) | Body | Body Name | System | What Changed | |---|---|---|---| | GJ7547c | Brandwacht | Skemeraand | 6 cardinal mountains → Afrikaans names; city "Ridge Marker" → "Wagpos" | | GJ528Ac | Klaarstroom | Ouplaas | 4 cardinal mountains → Afrikaans names; city "Ridge Line" → "Klaardorp"; river "Riverbend" → "Die Draai" | | GJ68f | Winter | Schuilhoek | All 6 cardinal/navigational rivers renamed to Afrikaans; cities "Dust Bowl Flats"/"Barren Meadow" → "Stofkamp"/"Kaalveld" | | GJ68d | Lente | Schuilhoek | Wrong-type mountain names removed; 3 landscape-desc rivers → Afrikaans; 2 cap cities renamed | | GJ667Ad | Geelong | New Ballarat | 2 wrong-type mountain names → Anglo-Australian; 2 cap cities → Australian flora names | | GJ661Ad | Ys | Crown's Hollow | 2 collision city names → Anglo-Saxon unique names | | GJ15Ac | Gongshu | Lu Ban | Wrong-type mountain; 2 collision cities → institutional core names; 1 collision river | | GJ879d | Patiala | Singh's Landing | "Billabong" (water concept) + 6 cardinal mountains → Punjabi names; "Dusty Gully" → "Phillaur" | | GJ556c | Idanha | Recanto | 4 cardinal/wrong-type mountains → Portuguese names; cap city → "Miradouro" | | GJ138c | Portel | Sertão | Cap city → "Marco Sertão"; 4 concatenated river names → Portuguese | | GJ174c | Clausthal | Tiefenbach | Cardinal + wrong-type mountains → German names; cap city → "Bergstation"; 3 wrong-type rivers | | GJ421Bc | Serpa | Pedra Seca | 4 wrong-type mountains (flatland/valley floor used as mountains) → Portuguese names; cap city | | GJ566Ac | Haodu | Haodu | "Jade Harbor" (worst collision, 20 bodies) → "Lianyun Harbor" | | GJ674c | Provenance | Provenance | "Capitol Heights" → "Provenance Heights" | | GJ68c | Zomer | Schuilhoek | 2 collision city names → Afrikaans | ### Pass 2 — Infrastructure naming (all inhabited bodies) All 37 unnamed roads and 37 unnamed railroads across 36+ inhabited bodies were named using the city-pair convention. Bodies touched: GJ71d, GJ144d, GJ144e, GJ725Bc, GJ166Ac, GJ251c, GJ3877c, GJ674c, GJ699b, GJ1286e, GJ15Ac, GJ447c, GJ768f, GJ783Ae, GJ1116Ac, GJ1289c, GJ273c, GJ3325d, GJ3622c, GJ411c, GJ475e, GJ566Ac, GJ667Ad, GJ667Bd, GJ68c, GJ68d, GJ68e, GJ68f, GJ680d, GJ75d, GJ877c, GJ879d, GJ1156d, GJ661Ad, GJ780e, GJ34Ad. All bodies re-synced via `generate_atlas.py --body ` and verified in atlas_* tables. --- ## Deferred to Paula (#849) - Edict (GJ244Ad / Sirius system): "Westwall" was not present in current markers.json or DB — either removed in a prior pass or the query data was stale. Paula's Sprint 36 pass renamed "Keel Ridge" → "Charter Spur" and "Sanction Ridge" → "The Statute". Edict mountains are clean. "Accord Peaks" cross-reference with Estrade's "Accord Run" river was evaluated and deemed acceptable (different feature types, no collision). - Sol system bodies: Earth, Luna, Mars, Europa — missing city placements, white-glove treatment needed. - Lendel (GJ380c / Groombridge system): check for any quality issues. --- ## 9. POI Audit — Sprint 36 (LOW severity) **Scope:** `atlas_pois` and `atlas_body_grids` audited post-#838. ### atlas_body_grids Pure structural data (body_id, grid_w, grid_h, updated_at). No name column. **Clean — no action required.** ### atlas_pois 287 total POIs across 267 inhabited bodies. Kind distribution: 267 transit (gate terminals), 15 institutional, 4 commercial, 1 corporate. **Zero empty names.** All 267 transit POIs have names. Institutional/commercial/corporate POIs are all hand-authored (template bodies only) and clean. **Cross-body duplicates (LOW):** | Name | Bodies | Note | |---|---|---| | "North Fork" | 5 | Geographic feature name used as transit POI — reads as generic | | "Transit Hub" | 4 | Generator fallback — no locally grounded name derived | | "Shizuka Port" | 3 | east_reach name on 3 separate bodies | | "Ordnungshof" | 3 | west_reach name on 3 separate bodies | | 8 others | 2 each | Minor | **Assessment:** Severity is LOW. Max collision depth is 5 bodies ("North Fork") vs. 20 for worst city collision. No empty names. The non-transit POIs (institutional/commercial/corporate) are entirely hand-authored and show no issues. Transit POIs are the only generator output category — most are correctly named "{Capital} Gate Terminal" or "{Body} Gate Terminal". **No hand-fixes required this sprint.** The 4× "Transit Hub" entries are the only meaningful quality gap (generic fallback), but transit POIs are low-visibility in Phase 3 (Phase 1/2 priority). **Generator fixes recommended (add to #853):** 7. **Transit POI deterministic naming** — derive gate terminal name from body's capital city: `{capital_name} Gate Terminal`. Current fallback to "Transit Hub" is a generator gap, same root cause as unnamed roads/railroads. 8. **Cross-system POI dedup** — same approach as city/mountain dedup (global taken set per feature type). --- ## Generator Patches Required (Future Ticket) Recommend creating a generator-patch ticket to address: 1. **Cross-system city name dedup** — seed taken list from global atlas_cities 2. **Cross-system mountain name dedup** — same approach 3. **Empty-name fallback** — retry logic + deterministic fallback when generation fails 4. **Suffix monotony post-filter** — re-query if >40% same suffix per body 5. **Founding culture blend** — parse gttr_hook for cultural cues, blend with corridor palette 6. **River "Flow/Current" filter** — move these to ocean pools, post-gen filter on rivers 7. **Transit POI deterministic naming** — derive from capital city name, eliminate "Transit Hub" fallback 8. **Cross-system POI name dedup** — extend global dedup to atlas_pois 9. **River/ocean cross-body name dedup (secondary/uninhabited bodies)** — Mellanie's Sprint 36 sweep confirmed river/ocean collisions remain on secondary and uninhabited bodies (Rio Grande ×23, Steinbruch ×19, others). Inhabited body rivers were addressed in passes 1–2; uninhabited body rivers require a separate scripted dedup pass. Same root cause as city/mountain: no global taken set in Gemma pipeline.