docs(meta): body pages are obeyed, not reverted — correcting the wiki skill again

Jeroen asked whether I had read the python that writes the frontmatter. I had not — only grepped it. Reading body_definition_parser.py and scaffold_bodies.py properly overturned what I had written twice today.

scaffold_bodies.py NEVER OVERWRITES ('Only creates files that don't exist yet... existing body index.md files are skipped'), and the generator reads that frontmatter directly. So a hand-edited body page is not reverted, it is OBEYED, and it silently changes world generation — worse than being overwritten, and the actual reason GOVERNANCE.md forbids it. System pages behave the opposite way: wiki_sync.py re-renders their READ-ONLY blocks, so edits there ARE reverted. Three cases, not two.

It also explains T-1244's whole measurement: body_definition_parser resolves each field override > direct read > derived > inferred > SEEDED RANDOM. Continuous axes vary because they fall to the random tier; categorical axes are concentrated because they are read from the bodies table. The variance question belongs to the atlas CLI catalog, not the wiki.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-20 00:53:00 +02:00
co-authored by Claude Opus 5
parent 0dc68dc1b8
commit 34e5d7b636
3 changed files with 185 additions and 14 deletions
+27 -14
View File
@@ -34,22 +34,35 @@ atlas sync alongside.
Celestial Bodies, Stations & Facilities)
- `bodies/*/index.md` frontmatter — machine-owned
**Body frontmatter is a MIDDLE layer, not the origin.** GOVERNANCE.md calls it
"the body definition", which is true of its role downstream and misleading about
where it comes from. Actually:
**System pages and BODY pages behave differently. Do not merge them in your head.**
1. The bodies catalog in `server/data/systems.db` is the origin, authored through
the atlas CLI (`tooling/atlas add-body` / `author-system`) — atlas-CLI-owned
and surviving `make regen-db` (`Skill(atlas)`).
2. `scaffold_bodies.py` + `body_definition_parser.py` WRITE the page frontmatter
from that, deriving fields as they go — e.g. `tectonics` is a lookup off
`planet_class` (`body_definition_parser.py:563`), with an override hook, not
an independently authored value.
3. `import_economics` then READS some of those fields back.
*System page* (`GJ-{id}/index.md`) — `wiki_sync.py::generate_wiki()` re-renders it
from `systems.db` + `star-map.json`, preserving the authored prose sections. A
hand-edit inside a `<!-- READ-ONLY -->` block IS reverted on the next sync.
(`wiki_sync.py` also has `import_from_wiki()`, a bootstrap/migration path running
the other way — wiki frontmatter into the DB. Know it exists before assuming any
single direction is "the" direction.)
So it is output of one stage and input to the next, which is exactly why hand
edits are both reverted AND wrong. To change a body's identity, go to the atlas
CLI, not the page.
*Body page* (`bodies/{id}/index.md`) — different, and more dangerous:
1. Origin is the bodies catalog in `server/data/systems.db`, authored through the
atlas CLI (`tooling/atlas add-body` / `author-system`), which is
atlas-CLI-owned and survives `make regen-db` (`Skill(atlas)`).
2. `scaffold_bodies.py` reads the system page's Celestial Bodies table, runs
`body_definition_parser.py`, and writes the body frontmatter once. Resolution
order is documented in that parser: override dict > direct read from the table
> derived (e.g. `tectonics` is a lookup off `planet_class`, line 563) >
inferred > SEEDED RANDOM within planet-class constraints (the `"rand"`
sentinel). That last tier is why the continuous fields vary richly per body.
3. `scaffold_bodies.py` **never overwrites** — "Only creates files that don't
exist yet… existing body index.md files are skipped."
4. The generator then reads that frontmatter directly as its input.
So a hand-edited body frontmatter is **NOT reverted — it is obeyed**, and it
silently changes world generation. That is worse than being overwritten, and it
is the real reason GOVERNANCE.md says never to hand-edit it. To change a body,
change the catalog through the atlas CLI and re-scaffold (which means removing
the page first, since scaffold skips what exists).
**Do author**, in place, and it survives regeneration:
- the named prose sections of a system page: Supply Dependency, Faction Notes,
+93
View File
@@ -1125,3 +1125,96 @@ original measurement scanned frontmatter VALUES and never asked where they came
from, so a derived field was read as an authored one. Same class of error as the
scalar-only parser caveat already recorded — a scan tells you what a field says,
never who decided it.', NULL, '2026-08-19 22:45:45', '2026-08-19 22:45:45.557', '2026-08-19 22:45:45.557', NULL, '2b98fb90a8e4d5ea3447cfe489c89848', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06G1R8WZ987YCP1ARANSA70R0W', 'description', 'Measured 2026-08-20 over all 2,625 body definitions in wiki/star-systems/*/bodies/*/index.md. The seed''s CONTINUOUS axes vary richly: seed is unique per body, distance_au 716 distinct values, polar_ice_lat 691, axial_tilt_deg 578, land_fraction 460. The CATEGORICAL axes do not: tectonics 4 values with 67.8% ''low'', atmosphere 4 with 66.3% ''none'', planet_class 13 with 51.1% ''frozen'', substrate 3 with 51.1% ''ice'', geothermal_flux 3 with 91.2% ''low''. Those categoricals are what gate the morphology and biome branches, so a mostly-low-tectonics world is mostly FLAT BY THE SEED, before any rendering question. This matters because a full session (2026-08-16..18) went into making the Atlas render terrain legibly at the deep rungs, and composition.rs already states the honest position: ''where the terrain is flat, flat is the honest answer, and the morphology variety visible at Global comes from places that actually have slope''. If two thirds of bodies genuinely have no slope, there is a ceiling on what renderer work can deliver and it is set in the seed. QUESTION TO ANSWER FIRST, before any change: is the distribution intended? A galaxy where most worlds are dull and the interesting ones stand out is a legitimate and probably good design; an authoring pass that defaulted tectonics to ''low'' and moved on is not. Check how the values were produced (scaffold_bodies.py / the authoring pass) before touching them. NOT a defect report -- two things that looked like defects in the same measurement turned out deliberate (chemosynthetic:false is a namespace reservation for dextro-DNA biochemistry once geology and nature spawn to the 1x1m pixel; enabled:false on ~65% is staged rollout, clean planet types first then generator scripts for the others). Method caveat: the aggregator reads scalar frontmatter only, so list-valued fields are unreliable -- atmosphere_color first read as ''100% null'' and that was a parser artefact. Full measurement and method: docs/wiki-structure-findings.md.
---
MATERIAL CORRECTION (2026-08-20, same day): tectonics is DERIVED, not authored.
`tooling/planet-gen/body_definition_parser.py:563` reads
`tectonics = tectonic_map.get(planet_class, "low")`, with an override hook on the
next line. So the "67.8% tectonics: low" measured above is not an authoring
decision at all — it is a projection of the planet_class distribution (51.1%
frozen, and whatever else maps to low) through a fixed lookup, plus a default of
"low" for any class not in the map.
That changes the question this ticket asks. It is NOT "did the authoring pass
default tectonics and move on". It is:
1. Is the PLANET_CLASS distribution intended? That is the real authored axis,
and it is where variance would have to come from.
2. Is the class -> tectonics map right? A lookup that sends most classes to
"low", plus a "low" default for unmapped classes, concentrates the output
further than the input. Check the map''s spread before blaming the data.
3. Is the override hook used at all? If no body sets it, the map is the whole
story.
Found by a cold-context agent reading body_definition_parser.py while testing
Skill(wiki); verified directly afterwards. Worth noting how it was missed: the
original measurement scanned frontmatter VALUES and never asked where they came
from, so a derived field was read as an authored one. Same class of error as the
scalar-only parser caveat already recorded — a scan tells you what a field says,
never who decided it.', 'Measured 2026-08-20 over all 2,625 body definitions in wiki/star-systems/*/bodies/*/index.md. The seed''s CONTINUOUS axes vary richly: seed is unique per body, distance_au 716 distinct values, polar_ice_lat 691, axial_tilt_deg 578, land_fraction 460. The CATEGORICAL axes do not: tectonics 4 values with 67.8% ''low'', atmosphere 4 with 66.3% ''none'', planet_class 13 with 51.1% ''frozen'', substrate 3 with 51.1% ''ice'', geothermal_flux 3 with 91.2% ''low''. Those categoricals are what gate the morphology and biome branches, so a mostly-low-tectonics world is mostly FLAT BY THE SEED, before any rendering question. This matters because a full session (2026-08-16..18) went into making the Atlas render terrain legibly at the deep rungs, and composition.rs already states the honest position: ''where the terrain is flat, flat is the honest answer, and the morphology variety visible at Global comes from places that actually have slope''. If two thirds of bodies genuinely have no slope, there is a ceiling on what renderer work can deliver and it is set in the seed. QUESTION TO ANSWER FIRST, before any change: is the distribution intended? A galaxy where most worlds are dull and the interesting ones stand out is a legitimate and probably good design; an authoring pass that defaulted tectonics to ''low'' and moved on is not. Check how the values were produced (scaffold_bodies.py / the authoring pass) before touching them. NOT a defect report -- two things that looked like defects in the same measurement turned out deliberate (chemosynthetic:false is a namespace reservation for dextro-DNA biochemistry once geology and nature spawn to the 1x1m pixel; enabled:false on ~65% is staged rollout, clean planet types first then generator scripts for the others). Method caveat: the aggregator reads scalar frontmatter only, so list-valued fields are unreliable -- atmosphere_color first read as ''100% null'' and that was a parser artefact. Full measurement and method: docs/wiki-structure-findings.md.
---
MATERIAL CORRECTION (2026-08-20, same day): tectonics is DERIVED, not authored.
`tooling/planet-gen/body_definition_parser.py:563` reads
`tectonics = tectonic_map.get(planet_class, "low")`, with an override hook on the
next line. So the "67.8% tectonics: low" measured above is not an authoring
decision at all — it is a projection of the planet_class distribution (51.1%
frozen, and whatever else maps to low) through a fixed lookup, plus a default of
"low" for any class not in the map.
That changes the question this ticket asks. It is NOT "did the authoring pass
default tectonics and move on". It is:
1. Is the PLANET_CLASS distribution intended? That is the real authored axis,
and it is where variance would have to come from.
2. Is the class -> tectonics map right? A lookup that sends most classes to
"low", plus a "low" default for unmapped classes, concentrates the output
further than the input. Check the map''s spread before blaming the data.
3. Is the override hook used at all? If no body sets it, the map is the whole
story.
Found by a cold-context agent reading body_definition_parser.py while testing
Skill(wiki); verified directly afterwards. Worth noting how it was missed: the
original measurement scanned frontmatter VALUES and never asked where they came
from, so a derived field was read as an authored one. Same class of error as the
scalar-only parser caveat already recorded — a scan tells you what a field says,
never who decided it.
---
THE VARIANCE SPLIT IS NOW FULLY EXPLAINED (2026-08-20, after reading
body_definition_parser.py and scaffold_bodies.py properly rather than grepping
them).
Body frontmatter is written once by `scaffold_bodies.py`, which reads the SYSTEM
page''s Celestial Bodies table and resolves each field through a documented
priority order (body_definition_parser.py header):
1. override dict (hand-authored, special cases like Sol)
2. direct read (the field is verbatim in the bodies table)
3. derived (computed — e.g. tectonics = lookup off planet_class)
4. inferred (implied by a combination of fields)
5. randomised (SEEDED, within planet-class constraints — the "rand"
sentinel)
That resolves the measurement in this ticket exactly:
- The CONTINUOUS axes vary richly (seed unique, distance_au 716 distinct,
axial_tilt_deg 578, land_fraction 460) because they fall through to tier 5
and are seeded-random per body.
- The CATEGORICAL axes are concentrated because they come from tier 2 — read
from the bodies table, i.e. from systems.db — and tier 3 derives from them.
So the variance question does not belong to the wiki at all. It belongs to the
BODIES CATALOG in systems.db, authored through the atlas CLI, and to the
class->tectonics map. Whoever picks this up should start at
`tooling/atlas add-body` / `author-system` and the catalog''s planet_class
distribution, NOT at the wiki pages, which are a faithful projection of it.
Second-order note worth keeping: this ticket has now been corrected twice from
the same root cause — measuring VALUES without reading the CODE that produced
them. First correction: tectonics is derived. Second: the whole continuous/
categorical split is an artefact of the resolution tiers. Both were available in
a docstring the original pass grepped but never read.', NULL, '2026-08-19 22:52:46', '2026-08-19 22:52:46.636', '2026-08-19 22:52:46.636', NULL, '7fcf06ee54c5fbc71568e6b5e30760ff', 2) ON CONFLICT(hash) DO NOTHING;
+65
View File
@@ -1111,3 +1111,68 @@ original measurement scanned frontmatter VALUES and never asked where they came
from, so a derived field was read as an authored one. Same class of error as the
scalar-only parser caveat already recorded — a scan tells you what a field says,
never who decided it.', 'backlog', 'medium', NULL, 'server', NULL, '2026-08-19 22:28:11.722', '2026-08-19 22:45:45.557', NULL, '7a1737a72bba4913d5e8f5fa78e44312', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= tickets.updated_at;
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06G1R8WZ987YCP1ARANSA70R0W', 'story', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Seed variance: 68% of bodies are tectonics:low — is the categorical monoculture intended?', 'Measured 2026-08-20 over all 2,625 body definitions in wiki/star-systems/*/bodies/*/index.md. The seed''s CONTINUOUS axes vary richly: seed is unique per body, distance_au 716 distinct values, polar_ice_lat 691, axial_tilt_deg 578, land_fraction 460. The CATEGORICAL axes do not: tectonics 4 values with 67.8% ''low'', atmosphere 4 with 66.3% ''none'', planet_class 13 with 51.1% ''frozen'', substrate 3 with 51.1% ''ice'', geothermal_flux 3 with 91.2% ''low''. Those categoricals are what gate the morphology and biome branches, so a mostly-low-tectonics world is mostly FLAT BY THE SEED, before any rendering question. This matters because a full session (2026-08-16..18) went into making the Atlas render terrain legibly at the deep rungs, and composition.rs already states the honest position: ''where the terrain is flat, flat is the honest answer, and the morphology variety visible at Global comes from places that actually have slope''. If two thirds of bodies genuinely have no slope, there is a ceiling on what renderer work can deliver and it is set in the seed. QUESTION TO ANSWER FIRST, before any change: is the distribution intended? A galaxy where most worlds are dull and the interesting ones stand out is a legitimate and probably good design; an authoring pass that defaulted tectonics to ''low'' and moved on is not. Check how the values were produced (scaffold_bodies.py / the authoring pass) before touching them. NOT a defect report -- two things that looked like defects in the same measurement turned out deliberate (chemosynthetic:false is a namespace reservation for dextro-DNA biochemistry once geology and nature spawn to the 1x1m pixel; enabled:false on ~65% is staged rollout, clean planet types first then generator scripts for the others). Method caveat: the aggregator reads scalar frontmatter only, so list-valued fields are unreliable -- atmosphere_color first read as ''100% null'' and that was a parser artefact. Full measurement and method: docs/wiki-structure-findings.md.
---
MATERIAL CORRECTION (2026-08-20, same day): tectonics is DERIVED, not authored.
`tooling/planet-gen/body_definition_parser.py:563` reads
`tectonics = tectonic_map.get(planet_class, "low")`, with an override hook on the
next line. So the "67.8% tectonics: low" measured above is not an authoring
decision at all — it is a projection of the planet_class distribution (51.1%
frozen, and whatever else maps to low) through a fixed lookup, plus a default of
"low" for any class not in the map.
That changes the question this ticket asks. It is NOT "did the authoring pass
default tectonics and move on". It is:
1. Is the PLANET_CLASS distribution intended? That is the real authored axis,
and it is where variance would have to come from.
2. Is the class -> tectonics map right? A lookup that sends most classes to
"low", plus a "low" default for unmapped classes, concentrates the output
further than the input. Check the map''s spread before blaming the data.
3. Is the override hook used at all? If no body sets it, the map is the whole
story.
Found by a cold-context agent reading body_definition_parser.py while testing
Skill(wiki); verified directly afterwards. Worth noting how it was missed: the
original measurement scanned frontmatter VALUES and never asked where they came
from, so a derived field was read as an authored one. Same class of error as the
scalar-only parser caveat already recorded — a scan tells you what a field says,
never who decided it.
---
THE VARIANCE SPLIT IS NOW FULLY EXPLAINED (2026-08-20, after reading
body_definition_parser.py and scaffold_bodies.py properly rather than grepping
them).
Body frontmatter is written once by `scaffold_bodies.py`, which reads the SYSTEM
page''s Celestial Bodies table and resolves each field through a documented
priority order (body_definition_parser.py header):
1. override dict (hand-authored, special cases like Sol)
2. direct read (the field is verbatim in the bodies table)
3. derived (computed — e.g. tectonics = lookup off planet_class)
4. inferred (implied by a combination of fields)
5. randomised (SEEDED, within planet-class constraints — the "rand"
sentinel)
That resolves the measurement in this ticket exactly:
- The CONTINUOUS axes vary richly (seed unique, distance_au 716 distinct,
axial_tilt_deg 578, land_fraction 460) because they fall through to tier 5
and are seeded-random per body.
- The CATEGORICAL axes are concentrated because they come from tier 2 — read
from the bodies table, i.e. from systems.db — and tier 3 derives from them.
So the variance question does not belong to the wiki at all. It belongs to the
BODIES CATALOG in systems.db, authored through the atlas CLI, and to the
class->tectonics map. Whoever picks this up should start at
`tooling/atlas add-body` / `author-system` and the catalog''s planet_class
distribution, NOT at the wiki pages, which are a faithful projection of it.
Second-order note worth keeping: this ticket has now been corrected twice from
the same root cause — measuring VALUES without reading the CODE that produced
them. First correction: tectonics is derived. Second: the whole continuous/
categorical split is an artefact of the resolution tiers. Both were available in
a docstring the original pass grepped but never read.', 'backlog', 'medium', NULL, 'server', NULL, '2026-08-19 22:28:11.722', '2026-08-19 22:52:46.636', NULL, '65db5461d46f8f84aed68526113025a6', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= tickets.updated_at;