The relationship between wiki/, the generators, systems.db and the runtime is
a directed graph with two edges running opposite to the obvious direction and
one running backwards into its own producer. Prose renders that badly: every
document that has described it states a single ownership direction and is
therefore wrong about part of the tree. D-262 makes the diagram the source of
truth and points CLAUDE.md, Skill(wiki), project-structure.md and
wiki/GOVERNANCE.md at it.
The correction that matters most: body pages were described everywhere as
machine-owned and reverted on sync. They are not. scaffold_bodies.py writes
one once and never overwrites it, and import_economics then reads that
frontmatter directly as input — so a hand-edit is not reverted, it is obeyed,
and silently changes world generation. Worse than being overwritten, and the
actual reason GOVERNANCE.md forbids the edit.
New: tooling/check-dataflow-graph.py, wired into the Makefile and the pre-push
hook. It asserts every repo path named in a hand-authored diagram still
resolves — and its docstring states plainly what it cannot do: verify that an
edge still MEANS what it says. If wiki_sync.py stopped writing body pages
tomorrow, every path would still exist and the check would still pass. Edge
semantics stay a human check against the tool's source, so nobody reads a green
gate as a verified map.
Verified by breaking it: pointing one label at a moved path fails with exit 1
naming that path; restoring it passes. Building the checker also caught two
real vaguenesses in the diagram — "GJ-*/index.md" and "bodies/{id}/index.md"
were written without their wiki/star-systems/ prefix, which is precisely the
ambiguity this map exists to remove. Generated star-map .d2 files are excluded
by name; their correctness belongs to their generator under D-223.
Also files Q-124 + T-1246 (tooling): whether the 123 Python files under
tooling/ should become one Rust CLI of pql's calibre. The friction is real and
mostly not about the language — the permission gate prefix-matches whole
command strings and a blanket Bash(python3 *) grant is forbidden, so each tool
prompts near-individually, while a single binary is one allowlist entry. The
record requires pricing the cheap alternative (a Python dispatcher entrypoint)
before recommending Rust, and flags the hard constraint: import_economics is
stamped by source SHA, so any port must keep that contract intact through the
transition rather than disabled during it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
11 KiB
name: wiki description: Read or edit the wiki seed data — world content, star systems, bodies, corporations, factions, economics vocabularies, GTTR prose. Use when the task touches wiki/ at all: authoring lore or corp/faction pages, changing a body definition, adding a system, editing economics TOMLs, or answering "where does this world fact live". Also use before assuming a wiki page is hand-written — most are generated and hand-edits are silently reverted.
The wiki is a seed, and it is mostly generated
wiki/ is the authored input the world generator varies from — written once at
dev time, then read by the cascade. It is not a reference work to maintain, and
it is not hand-written throughout: 3,262 of its 3,515 pages are generated.
Everything below is the part that bites. The wiki documents itself well and you should read its own docs for detail:
wiki/GOVERNANCE.md— ownership, status lifecycle, directory ruleswiki/index.md— the mapwiki/_templates/— 17 templates, one per entity kindwiki/authoring/— 10 guides (monologue, culture, dual-lens, line-id, …)wiki/economics/schema.md— the economics TOML spec
The one rule: which direction does truth run?
Two ownership models, running OPPOSITE ways. Get this wrong and your work vanishes on the next sync, without an error.
The canonical answer is a diagram, not this text (D-262):
docs/diagrams/data-flow/wiki-generator-flow.d2 — view it with
clide draw --file docs/diagrams/data-flow/wiki-generator-flow.d2. Every edge
in it was read in the tool's own source. What follows here is a summary; where
the two disagree, the diagram is right.
star-systems/ — DB owns structure, wiki owns prose (OUTPUT)
3,262 pages, 93% of the wiki. Generated FROM server/data/systems.db and
star-map.json by tooling/db/wiki_sync.py, with scaffold_bodies.py and the
atlas sync alongside.
Never hand-edit:
- anything inside a
<!-- READ-ONLY -->block (System Profile, Topology, Celestial Bodies, Stations & Facilities) bodies/*/index.mdfrontmatter — machine-owned
System pages and BODY pages behave differently. Do not merge them in your head.
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.)
Body page (bodies/{id}/index.md) — different, and more dangerous:
- 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 survivesmake regen-db(Skill(atlas)). scaffold_bodies.pyreads the system page's Celestial Bodies table, runsbody_definition_parser.py, and writes the body frontmatter once. Resolution order is documented in that parser: override dict > direct read from the tablederived (e.g.
tectonicsis a lookup offplanet_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.scaffold_bodies.pynever overwrites — "Only creates files that don't exist yet… existing body index.md files are skipped."- 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, Silence Topic, Narrative Hook, Calibration Note
gttr.md(system),gttr-{location}.md(station/settlement),gttr-{corridor}.md(corridor) — the Drifter's Guide channel
To change a generated fact, change the SOURCE and regenerate. Editing the page is editing a render.
Flat categories — wiki is truth (INPUT)
Authored markdown plus TOML. Generators import FROM these. What is actually there, counted 2026-08-20 — the distribution is lopsided and four categories are empty scaffolding:
| category | files | note |
|---|---|---|
corporations/ |
156 | the authored mass; frontmatter feeds systems.db |
economics/ |
17 entries | the economic MODEL — see below |
factions/ |
9 | Assembly, Commission, Institute, Syndics, Guardians, Unbound |
technology/ |
7 | |
contraband/, concepts/ |
4 each | |
triangles/ |
2 | relationship structures |
institutions/, species/, cultural-groups/, lore/ |
0 | templates exist — but see Q-118 |
Those four empty categories are an OPEN QUESTION, not an invitation.
governance/questions/scope.md Q-118 (2026-06-12, unresolved) asks whether they
should be populated at all or retired: Phase 1 closed as done without them,
because the cultural layer shipped structurally instead (D-232 trait catalog +
D-237 system pins as TOML). Surface Q-118 before authoring into them — the
template's existence is not scope approval.
To add one: copy the matching _templates/ file, fill ALL frontmatter, write a
one-line description, set status: proposed, follow the template's structure.
Real corp frontmatter is richer than it looks — title, description, slug, category, status, created, updated, scope, faction_type, headquarters, corp_specialization, tags, decision_refs, cross_refs. Only some is machine-read
(corp_specialization keys HQ placement via corp_hq_placement.toml), but the
whole file is in the importer's stamped set.
wiki/economics/ is the economic model, not a lookup table
This is the tree that will generate WORLD CONTENT once geology and nature spawn to the 1×1 m pixel — production chains decide what is physically present on the ground, so it is a seed one tier above the body definitions.
economics/
schema.md the spec — read this first
commodities.toml + commodities/ (37 authored commodity pages)
production_chains.toml real recipes: 2t metallic_ore + 0.3 fusion_fuel
-> 1t refined_metals, location_bound flags
currency_zones.toml shadow_economy.toml
specialization_vocabulary.toml system_specialization.toml
corp_hq_placement.toml settlement_name_locked.toml
architecture_trait_catalog.toml / _bias.toml / architecture_zone_bias.toml
color_register_bands.toml object_tag_vocabulary.toml
archetypes/ behavioral.toml, brand_templates.toml, lore.toml
corporations/ brands.toml, generated_brands.toml, tier1.toml
specialization_vocabulary.toml is a shared id-space read by TWO axes:
system_economy.economic_specialization (per system) and
corporations.corp_specialization (per corp, authored in the corp page's
frontmatter, NOT in a per-corp TOML). Change a value and both move.
generated_brands.toml is OUTPUT — written by the generate_brands binary that
import_economics shells out to; do not hand-edit it.
Traps
Stations and districts have no directories. They are systems.db rows
rendered into each system page's table. Their prose lives in flat
gttr-{slug}.md files in the system dir. Do not create wiki/stations/.
Two spellings of one id. System dirs hyphenate (GJ-820B/), body dirs do
not (GJ820Bc/). Body dirs key on body id, never on a display-name slug.
Editing corp PROSE stales systems.db. _corporation_pages() globs every
wiki/corporations/*.md (except index.md) into import_economics' stamped
source set, so a typo fix in body text trips the pre-push stamp check. Run
make regen-db and stage server/data/systems.db.
description exists for you. GOVERNANCE.md: "agents filter by description
before loading full files". Read frontmatter descriptions and load selectively —
this tree is 11,864 files and will eat a context window whole.
Check the current state before editing anything. A task can describe a change that is already true. Ferrath was asked to be made "arid with low tectonics" and already was, in all four places it is recorded — acting on the framing would have hand-edited a machine-owned, already-correct file. Read the target first; the rules below only protect you if you look before you touch.
Some bodies are visual-regression goldens. Ferrath (GJ820Bc) appears in
tests/visual.json and tests/atlas_shots.json (Global, District, and the
descent-ladder set) precisely because of its current terrain. Regenerating its
terrain is legitimate under every rule here and will silently break goldens —
re-capture them if you do. Nothing in wiki/ says so; check tests/ for the
body id before regenerating any body.
status is editorial, not a gate. import_economics has no status filter,
so a proposed corp imports into the live economy exactly like a canonical
one. Do not assume proposed means inert.
Absent variance is often deliberate. Fields can be forward-reservations or
staged gates, not gaps. chemosynthetic: false on every body reserves the
namespace for dextro-DNA-style biochemistry once geology and nature spawn to the
1×1 m pixel. enabled: false on ~65% is staged rollout — clean planet types are
learned first, then generator scripts follow and the playable count rises. Do
not populate or delete a zero-variance field without asking why it is empty.
What the seed actually supplies
Measured over 2,625 body definitions (2026-08-20):
- Rich:
seedunique per body;distance_au716 distinct,polar_ice_lat691,axial_tilt_deg578,land_fraction460. - Concentrated:
tectonics68%low,atmosphere66%none,planet_class51%frozen,substrate51%ice.
The categorical fields gate morphology and biome branches, so a mostly-low
tectonics world is mostly flat BY THE SEED. Before treating flat terrain as a
rendering bug, check what the body was authored as — that mistake cost a full
session once already.
Tooling
| tool | does |
|---|---|
tooling/db/wiki_sync.py |
systems.db → star-system page sections |
tooling/planet-gen/scaffold_bodies.py |
creates body dirs/pages |
tooling/planet-gen/body_definition_parser.py |
reads body frontmatter |
tooling/db/populate_gttr_hook.py |
GTTR prose → gttr_hook |
tooling/planet-gen/populate_terrain_reference.py |
terrain asset paths |
tooling/planet-gen/atlas_cohesion_audit.py |
audits atlas coherence |
make regen-db |
economics TOML + corp frontmatter → systems.db |
pql queries the vault: pql search, pql backlinks, pql related,
pql context — prefer these over grepping 11,864 files.