Finalizes #849 core-world atlas cohesion: GJ0d (Earth/Sol) markers.json cleaned of erroneous data, refine_log updated with Sol body gap notes, atlas_quality_analysis.py added for ongoing metric tracking. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
256 lines
16 KiB
Markdown
256 lines
16 KiB
Markdown
# 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 <id>` 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.
|