docs(meta): D-259 + D-260 — the two rulings that only existed in /tmp

Everything else from the pair session was either shipped or ticketed with its
rationale in git. These two were design decisions Jeroen made, living only in
a scratchpad under /tmp, one cleanup away from gone.

D-259 — ENCLOSED SETTLEMENTS. Open-air requires atmosphere == standard;
everything else is enclosed, as point locations on the Atlas with interiors
deferred to a separate generator and handled like embedded stations. Branch on
an explicit `enclosed` property rather than the atmosphere string, so enclosed
settlements on breathable worlds (hostile-biome posts, undersea, arcologies)
need no second code path. NULL defaults to enclosed, which fails safe.

The load-bearing claim is that D-220's density model is PHYSICALLY
INAPPLICABLE to a pressure vessel, not mistuned: it measures people per km2 of
footprint driven by utility cost per metre of street, so run airless it yields
1,500 ppl/km2 of open-air streets in vacuum. The handoff mechanism was already
planned — D-166's door boundary contract, where a dome's airlock IS that door.
Atmosphere keeps its full range for the surface-expedition layer; the binary
collapse applies to settlement layout only, and the record says so to stop the
collapse being read as atmosphere not mattering.

D-260 — GENERATOR SCOPE. Sol is encoded as Authored { deepest_rung: Global }
rather than excluded by convention. The DLC gate is a DEPTH, not a boolean, so
a Sol expansion changes one value instead of unpicking an exclusion. No new
wire status: "viewable at Global, no deeper" IS the existing rung-liveness
path. Sol art is an authored data canvas, not a finished image, so it rides
the existing wire and is drawn by the same map-art function as all 269
procedural bodies.

The hazard that made encoding necessary is recorded: systems.db still carries
terrain_reference rows for Sol bodies pointing at heightmaps deliberately never
baked, so a real Earth DEM dropped at that exact path would silently start
generating a procedural homeworld. The importer comment said Sol was excluded;
nothing enforced it.

Also files the last three parked items, which were likewise /tmp-only:
T-1233 tiled/interlaced map loading (workshop-sized D-255 revision, blocked in
spirit on the rung-0.5 cost numbers), T-1234 enumerate the flow tweaks the
fetch panel exposed but which were never written down, T-1235 zoom
discoverability — the person who specified wheel-only zoom could not find it.

T-1231 closed.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-07-27 09:09:34 +02:00
co-authored by Claude
parent 58cd87d48c
commit b7dfc8c50f
5 changed files with 120 additions and 1 deletions
+28
View File
@@ -3239,3 +3239,31 @@ Context: make atlas (the D-254 companion shell) was never verified post-D-255 la
Context: make atlas (the D-254 companion shell) was never verified post-D-255 landing before this session -- last touched 2026-07-22, viewer replaced 2026-07-24/25, so this is likely the first real shutdown exercise since the stepped-Atlas rebuild. Fix both: (1) null-check server_process instance before calling stop on it, or guard the call site in atlas_standalone.gd:292; (2) downgrade or restructure the attach-probe''s expected-failure log to not read as an ERROR. Verify with a full cold-launch-then-quit cycle leaving no orphaned server process.
OBSERVED TWICE 2026-07-27, and the two runs differed worth knowing before someone tries to reproduce. The crash itself is DETERMINISTIC: every Atlas shutdown logs ''Attempt to call function stop in base null instance'' at server_process.gd:87, reached via atlas_standalone.gd:292 (_stop_spawned_server) from _exit_tree. The ORPHANED SERVER is INTERMITTENT: on the first run the spawned settled-reach-server survived the Godot exit and had to be killed by hand (PID 1917179, found ~40min later); on the second run, same crash in the log, but the child was reaped correctly and no stray remained. So this is a race on the shutdown path, not a straight always-leaks bug which means a fix verified by a single clean shutdown proves nothing. Reproduce by launching and closing repeatedly and checking for surviving ''settled-reach-server --port 0'' processes, not by reading one log. Note the null instance is reached during _notification, so the reap may be racing Godot''s own teardown of the ServerProcess node.', NULL, '2026-07-27 07:05:31', '2026-07-27 07:05:31.990', '2026-07-27 07:05:31.990', NULL, '9cc5b0e2a196151d167cb1608a90146a', 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 ('06FT1CZSETZPGX9F5747TDBA7W', 'description', 'GAP FLAGGED BY QATUX during the 2026-07-26/27 reconciliation, and it is real: two substantive design rulings from the pair session exist ONLY in a scratchlog under /tmp, with no governance record backing them. D-258 covers rung-0.5; neither of these is in it.
(A) ENCLOSED SETTLEMENTS. Non-breathable worlds get enclosed settlements -- point locations on the Atlas, interiors deferred to a separate generator, handled like embedded stations. Rationale: D-220''s density model is physically inapplicable to a pressure vessel, not merely mistuned (it measures people per km2 of footprint driven by utility cost per metre of street; run airless it yields 1,500 ppl/km2 of open-air streets in vacuum). The handoff mechanism already exists -- D-166''s door boundary contract, where a dome''s airlock IS that door. Branch on an explicit ''enclosed'' PROPERTY, not on the atmosphere string, which leaves room for enclosed settlements on breathable worlds (hostile-biome research posts, undersea, arcologies) with no second code path.
Jeroen ruled that ''thin'' folds into enclosed. By the same logic ''thick'' (Venus-like) and ''reducing'' (toxic) must too -- neither is open-air -- which collapses the rule to a single condition: open-air requires atmosphere == standard, everything else is enclosed. NULL atmosphere defaults to enclosed, which fails safe (an enclosed settlement on a breathable world is merely conservative; an open one in vacuum is absurd). Split: 231 open / 38 enclosed across 269 in-bounds populated bodies. NOTE the thick/reducing extension is the lead''s inference from Jeroen''s thin ruling, not his words -- confirm before writing.
Atmosphere keeps its full expressive range for the SURFACE-EXPEDITION layer (Jeroen: ''surface expeditions will play differently'' -- thin gives suit + dust storms + weather; none gives hard vacuum, no weather, extreme swings, radiation). The binary collapse applies ONLY to settlement layout. Record that, so the collapse is not later mistaken for atmosphere being unimportant.
(B) SOL GENERATOR SCOPE. T-1219..T-1221 carry the implementation; the DESIGN has no record. Needs capturing: the GeneratorScope enum shape (Procedural | Authored with a deepest_rung), the DLC gate being a DEPTH rather than a boolean (a Sol expansion deepens the ladder by changing one value), the absence of any new wire status because ''viewable at Global, no deeper'' IS the existing rung-liveness path rather than an error to report, and the ruling that Sol art is an authored DATA CANVAS rather than a finished image -- it rides the existing wire untouched, needs no new client draw path, and goes through the same map-art function as all 269 procedural bodies. The framing Jeroen accepted: you are not looking at a photograph of Earth, you are looking at your implant rendering Earth in the same visual language it renders everything else.
Also record that Sol bodies carry dangling terrain_reference rows pointing at heightmaps deliberately never baked (import_heightmaps.py explicitly excludes Sol), so a real Earth or Mars DEM dropped at that exact path would silently start generating a procedural homeworld with no gate to stop it.
Claim ids with ''pql decisions claim D architecture ...'' before writing.', 'GAP FLAGGED BY QATUX during the 2026-07-26/27 reconciliation, and it is real: two substantive design rulings from the pair session exist ONLY in a scratchlog under /tmp, with no governance record backing them. D-258 covers rung-0.5; neither of these is in it.
(A) ENCLOSED SETTLEMENTS. Non-breathable worlds get enclosed settlements -- point locations on the Atlas, interiors deferred to a separate generator, handled like embedded stations. Rationale: D-220''s density model is physically inapplicable to a pressure vessel, not merely mistuned (it measures people per km2 of footprint driven by utility cost per metre of street; run airless it yields 1,500 ppl/km2 of open-air streets in vacuum). The handoff mechanism already exists -- D-166''s door boundary contract, where a dome''s airlock IS that door. Branch on an explicit ''enclosed'' PROPERTY, not on the atmosphere string, which leaves room for enclosed settlements on breathable worlds (hostile-biome research posts, undersea, arcologies) with no second code path.
Jeroen ruled that ''thin'' folds into enclosed. By the same logic ''thick'' (Venus-like) and ''reducing'' (toxic) must too -- neither is open-air -- which collapses the rule to a single condition: open-air requires atmosphere == standard, everything else is enclosed. NULL atmosphere defaults to enclosed, which fails safe (an enclosed settlement on a breathable world is merely conservative; an open one in vacuum is absurd). Split: 231 open / 38 enclosed across 269 in-bounds populated bodies. NOTE the thick/reducing extension is the lead''s inference from Jeroen''s thin ruling, not his words -- confirm before writing.
Atmosphere keeps its full expressive range for the SURFACE-EXPEDITION layer (Jeroen: ''surface expeditions will play differently'' -- thin gives suit + dust storms + weather; none gives hard vacuum, no weather, extreme swings, radiation). The binary collapse applies ONLY to settlement layout. Record that, so the collapse is not later mistaken for atmosphere being unimportant.
(B) SOL GENERATOR SCOPE. T-1219..T-1221 carry the implementation; the DESIGN has no record. Needs capturing: the GeneratorScope enum shape (Procedural | Authored with a deepest_rung), the DLC gate being a DEPTH rather than a boolean (a Sol expansion deepens the ladder by changing one value), the absence of any new wire status because ''viewable at Global, no deeper'' IS the existing rung-liveness path rather than an error to report, and the ruling that Sol art is an authored DATA CANVAS rather than a finished image -- it rides the existing wire untouched, needs no new client draw path, and goes through the same map-art function as all 269 procedural bodies. The framing Jeroen accepted: you are not looking at a photograph of Earth, you are looking at your implant rendering Earth in the same visual language it renders everything else.
Also record that Sol bodies carry dangling terrain_reference rows pointing at heightmaps deliberately never baked (import_heightmaps.py explicitly excludes Sol), so a real Earth or Mars DEM dropped at that exact path would silently start generating a procedural homeworld with no gate to stop it.
Claim ids with ''pql decisions claim D architecture ...'' before writing.
DONE 2026-07-27. Both rulings written up: D-259 (enclosed settlements open-air requires a breathable atmosphere; branch on an explicit property, not the atmosphere string; NULL fails safe to enclosed; D-220''s density model declared physically inapplicable to a pressure vessel rather than merely mistuned; the D-166 door boundary contract identified as the already-planned handoff) and D-260 (generator scope Sol encoded as Authored with deepest_rung Global, the DLC gate a DEPTH not a boolean, no new wire status because rung-liveness already covers it, Sol art an authored DATA CANVAS not a finished image). The thick/reducing extension of Jeroen''s thin ruling is flagged inside D-259 as the author''s inference rather than his words. D-260 records the concrete hazard that motivated encoding the exclusion: systems.db still carries terrain_reference rows for Sol bodies pointing at heightmaps deliberately never baked, so a real Earth DEM dropped at that path would silently start generating a procedural homeworld. Also records that Earth will never have a walkable world by construction (8.5B people, 14% of the setting) as an explicit choice rather than a gap.', NULL, '2026-07-27 07:09:08', '2026-07-27 07:09:08.309', '2026-07-27 07:09:08.309', NULL, 'c9bf7a93d9c93e09883a5f7a9ca75070', 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 ('06FT1CZSETZPGX9F5747TDBA7W', 'status', 'backlog', 'done', NULL, '2026-07-27 07:09:08', '2026-07-27 07:09:08.345', '2026-07-27 07:09:08.345', NULL, 'ee39b3b41c7eee7ef7a01da8141d0d83', 2) ON CONFLICT(hash) DO NOTHING;
+3
View File
@@ -146,3 +146,6 @@ INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FT1CXPZ8HH73P67G6R98NV6M', 'T-1230', '2026-07-26 23:12:40.186', '2026-07-26 23:12:40.186', NULL, 'e915b5b01c1970246c33217b337b6d7e', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_idmap.updated_at OR (excluded.updated_at = ticket_idmap.updated_at AND excluded.hash > ticket_idmap.hash);
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FT1CZSETZPGX9F5747TDBA7W', 'T-1231', '2026-07-26 23:12:57.211', '2026-07-26 23:12:57.211', NULL, '54cbe170611367610549c31882930676', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_idmap.updated_at OR (excluded.updated_at = ticket_idmap.updated_at AND excluded.hash > ticket_idmap.hash);
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FT1D64MS28Z2BGV4Z771JRQG', 'T-1232', '2026-07-26 23:13:49.222', '2026-07-26 23:13:49.222', NULL, 'c5a8956d41c58cd2a29decf840ebdc77', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_idmap.updated_at OR (excluded.updated_at = ticket_idmap.updated_at AND excluded.hash > ticket_idmap.hash);
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FT4SV8HMA2V98CSBGS12VE0C', 'T-1233', '2026-07-27 07:08:33.805', '2026-07-27 07:08:33.805', NULL, '664479a938343fac03b17f8fefd29399', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_idmap.updated_at OR (excluded.updated_at = ticket_idmap.updated_at AND excluded.hash > ticket_idmap.hash);
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FT4SWTWSMBG0PEPQNK8DT7ZW', 'T-1234', '2026-07-27 07:08:46.695', '2026-07-27 07:08:46.695', NULL, '582e004a5dd3b45f3c00afa335ab4845', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_idmap.updated_at OR (excluded.updated_at = ticket_idmap.updated_at AND excluded.hash > ticket_idmap.hash);
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FT4SY5BK5SBDA8G2MCPCB3AW', 'T-1235', '2026-07-27 07:08:57.564', '2026-07-27 07:08:57.564', NULL, '040d8befbcc613e958d46601dab04438', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_idmap.updated_at OR (excluded.updated_at = ticket_idmap.updated_at AND excluded.hash > ticket_idmap.hash);
+33
View File
@@ -5529,3 +5529,36 @@ INSERT INTO tickets (record_id, type, parent_record_id, title, description, stat
Context: make atlas (the D-254 companion shell) was never verified post-D-255 landing before this session -- last touched 2026-07-22, viewer replaced 2026-07-24/25, so this is likely the first real shutdown exercise since the stepped-Atlas rebuild. Fix both: (1) null-check server_process instance before calling stop on it, or guard the call site in atlas_standalone.gd:292; (2) downgrade or restructure the attach-probe''s expected-failure log to not read as an ERROR. Verify with a full cold-launch-then-quit cycle leaving no orphaned server process.
OBSERVED TWICE 2026-07-27, and the two runs differed worth knowing before someone tries to reproduce. The crash itself is DETERMINISTIC: every Atlas shutdown logs ''Attempt to call function stop in base null instance'' at server_process.gd:87, reached via atlas_standalone.gd:292 (_stop_spawned_server) from _exit_tree. The ORPHANED SERVER is INTERMITTENT: on the first run the spawned settled-reach-server survived the Godot exit and had to be killed by hand (PID 1917179, found ~40min later); on the second run, same crash in the log, but the child was reaped correctly and no stray remained. So this is a race on the shutdown path, not a straight always-leaks bug which means a fix verified by a single clean shutdown proves nothing. Reproduce by launching and closing repeatedly and checking for surviving ''settled-reach-server --port 0'' processes, not by reading one log. Note the null instance is reached during _notification, so the reap may be racing Godot''s own teardown of the ServerProcess node.', 'backlog', 'medium', NULL, NULL, NULL, '2026-07-26 21:55:50.150', '2026-07-27 07:05:31.990', NULL, 'c254af187f565cdfae408d04a65f2ac2', 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 OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
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 ('06FT4SV8HMA2V98CSBGS12VE0C', 'story', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Tiled/interlaced map loading — replace the monolithic per-rung canvas', 'PARKED BY JEROEN during the 2026-07-26 pair session, once the DOWNLOADING MAP DATA panel made fetch latency visible: google-maps-style tiles (~100x100 gridunits, size TBD) instead of one monolithic canvas per rung. Two payoffs he named. (1) PROGRESSIVE REVEAL during a slow derive -- tiles pop in as they complete instead of the whole canvas arriving at once, so a 0.5s derive stops reading as a hang. (2) TILE STREAMING as the user pans -- fetch only the newly-exposed segments, replacing the current re-request-the-whole-canvas-on-pan-edge behaviour. His words: ''the load wait is also much lighter if we pop in 100x100 gridunit tiles as they are done (if we can manage that with the generator code)''. THIS IS WORKSHOP-SIZED, NOT A TWEAK: it is a significant revision to D-255''s canvas model, touching the wire shape (one response per tile rather than one flat tagged response per canvas), the three-tier cache (keys become per-tile), the client terrain layer (compose from tiles rather than adopt one texture), and the pan/refetch state machine. Interacts with D-258''s rung 0.5 -- if every rung sources from one cached whole-body layer, tiling the DERIVE may be less valuable than tiling the TRANSFER, and that should be settled before design starts. Do not start before the rung-0.5 cost measurement (T-1212) lands, since its numbers change the argument.', 'backlog', 'medium', NULL, 'client', 'D-255', '2026-07-27 07:08:33.805', '2026-07-27 07:08:33.805', NULL, 'abb4da5cf1a813ebde4cffd85d71ab3f', 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 OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
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 ('06FT4SWTWSMBG0PEPQNK8DT7ZW', 'task', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Enumerate the Atlas flow/usability tweaks Jeroen spotted', 'PARKED BY JEROEN, 2026-07-26 pair session, verbatim: ''panel is there. thanks. there are a bunch of flow and usability tweaks I spot now I can see what is happening.'' The DOWNLOADING MAP DATA panel made the fetch state visible for the first time, which surfaced flow problems that were previously invisible rather than absent. The tweaks themselves were NEVER ENUMERATED -- he deferred them to get the original trio landed first, and the session then went deep into the extent inversion and D-258 instead. So this ticket is the enumeration, not the fix: sit with the Atlas (make atlas, body GJ380c / Lendel), exercise open-zoom-pan-resize, and write down what feels wrong. Known-adjacent items already captured elsewhere so they are not re-discovered here: zoom discoverability (sibling ticket), tiled/progressive loading (T-1233), and Global having no hydrology (T-1211). Worth doing while the panel is fresh; the observations decay.', 'backlog', 'low', NULL, 'client', NULL, '2026-07-27 07:08:46.695', '2026-07-27 07:08:46.695', NULL, 'bea870ea3dc7e0ea0124d2e2970c6985', 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 OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
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 ('06FT4SY5BK5SBDA8G2MCPCB3AW', 'task', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Atlas zoom is wheel-only and undiscoverable — add an affordance', 'Surfaced 2026-07-26 when Jeroen reported ''I can''t zoom in at all'', then immediately corrected himself: ''I found the zoom is now only scroll. which I forgot I asked''. The behaviour is correct and is his own round-A ruling (fully stepped zoom, cursor-anchored, wheel-driven). The problem is purely DISCOVERABILITY -- the person who specified it could not find it, which is about as strong a signal as that class of finding gets. Nothing about the zoom mechanism should change. What is missing is an affordance: some combination of on-canvas hint, a rung indicator that reads as interactive, +/- controls, or keyboard bindings surfaced in the legend. Note the screen header and legend already display the current rung and km/gridunit, so there is a place to hang it. Low priority but cheap, and it costs a first-time user their first minute in the Atlas.', 'backlog', 'low', NULL, 'client', NULL, '2026-07-27 07:08:57.564', '2026-07-27 07:08:57.564', NULL, '7d78c0d46372f3026bb0061b3eec8ac6', 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 OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
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 ('06FT1CZSETZPGX9F5747TDBA7W', 'task', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Record the Sol GeneratorScope + enclosed-settlement rulings as D-records', 'GAP FLAGGED BY QATUX during the 2026-07-26/27 reconciliation, and it is real: two substantive design rulings from the pair session exist ONLY in a scratchlog under /tmp, with no governance record backing them. D-258 covers rung-0.5; neither of these is in it.
(A) ENCLOSED SETTLEMENTS. Non-breathable worlds get enclosed settlements -- point locations on the Atlas, interiors deferred to a separate generator, handled like embedded stations. Rationale: D-220''s density model is physically inapplicable to a pressure vessel, not merely mistuned (it measures people per km2 of footprint driven by utility cost per metre of street; run airless it yields 1,500 ppl/km2 of open-air streets in vacuum). The handoff mechanism already exists -- D-166''s door boundary contract, where a dome''s airlock IS that door. Branch on an explicit ''enclosed'' PROPERTY, not on the atmosphere string, which leaves room for enclosed settlements on breathable worlds (hostile-biome research posts, undersea, arcologies) with no second code path.
Jeroen ruled that ''thin'' folds into enclosed. By the same logic ''thick'' (Venus-like) and ''reducing'' (toxic) must too -- neither is open-air -- which collapses the rule to a single condition: open-air requires atmosphere == standard, everything else is enclosed. NULL atmosphere defaults to enclosed, which fails safe (an enclosed settlement on a breathable world is merely conservative; an open one in vacuum is absurd). Split: 231 open / 38 enclosed across 269 in-bounds populated bodies. NOTE the thick/reducing extension is the lead''s inference from Jeroen''s thin ruling, not his words -- confirm before writing.
Atmosphere keeps its full expressive range for the SURFACE-EXPEDITION layer (Jeroen: ''surface expeditions will play differently'' -- thin gives suit + dust storms + weather; none gives hard vacuum, no weather, extreme swings, radiation). The binary collapse applies ONLY to settlement layout. Record that, so the collapse is not later mistaken for atmosphere being unimportant.
(B) SOL GENERATOR SCOPE. T-1219..T-1221 carry the implementation; the DESIGN has no record. Needs capturing: the GeneratorScope enum shape (Procedural | Authored with a deepest_rung), the DLC gate being a DEPTH rather than a boolean (a Sol expansion deepens the ladder by changing one value), the absence of any new wire status because ''viewable at Global, no deeper'' IS the existing rung-liveness path rather than an error to report, and the ruling that Sol art is an authored DATA CANVAS rather than a finished image -- it rides the existing wire untouched, needs no new client draw path, and goes through the same map-art function as all 269 procedural bodies. The framing Jeroen accepted: you are not looking at a photograph of Earth, you are looking at your implant rendering Earth in the same visual language it renders everything else.
Also record that Sol bodies carry dangling terrain_reference rows pointing at heightmaps deliberately never baked (import_heightmaps.py explicitly excludes Sol), so a real Earth or Mars DEM dropped at that exact path would silently start generating a procedural homeworld with no gate to stop it.
Claim ids with ''pql decisions claim D architecture ...'' before writing.
DONE 2026-07-27. Both rulings written up: D-259 (enclosed settlements open-air requires a breathable atmosphere; branch on an explicit property, not the atmosphere string; NULL fails safe to enclosed; D-220''s density model declared physically inapplicable to a pressure vessel rather than merely mistuned; the D-166 door boundary contract identified as the already-planned handoff) and D-260 (generator scope Sol encoded as Authored with deepest_rung Global, the DLC gate a DEPTH not a boolean, no new wire status because rung-liveness already covers it, Sol art an authored DATA CANVAS not a finished image). The thick/reducing extension of Jeroen''s thin ruling is flagged inside D-259 as the author''s inference rather than his words. D-260 records the concrete hazard that motivated encoding the exclusion: systems.db still carries terrain_reference rows for Sol bodies pointing at heightmaps deliberately never baked, so a real Earth DEM dropped at that path would silently start generating a procedural homeworld. Also records that Earth will never have a walkable world by construction (8.5B people, 14% of the setting) as an explicit choice rather than a gap.', 'backlog', 'high', NULL, 'server', NULL, '2026-07-26 23:12:57.206', '2026-07-27 07:09:08.309', NULL, '9bea19903181c294b2da2ce96907b758', 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 OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
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 ('06FT1CZSETZPGX9F5747TDBA7W', 'task', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Record the Sol GeneratorScope + enclosed-settlement rulings as D-records', 'GAP FLAGGED BY QATUX during the 2026-07-26/27 reconciliation, and it is real: two substantive design rulings from the pair session exist ONLY in a scratchlog under /tmp, with no governance record backing them. D-258 covers rung-0.5; neither of these is in it.
(A) ENCLOSED SETTLEMENTS. Non-breathable worlds get enclosed settlements -- point locations on the Atlas, interiors deferred to a separate generator, handled like embedded stations. Rationale: D-220''s density model is physically inapplicable to a pressure vessel, not merely mistuned (it measures people per km2 of footprint driven by utility cost per metre of street; run airless it yields 1,500 ppl/km2 of open-air streets in vacuum). The handoff mechanism already exists -- D-166''s door boundary contract, where a dome''s airlock IS that door. Branch on an explicit ''enclosed'' PROPERTY, not on the atmosphere string, which leaves room for enclosed settlements on breathable worlds (hostile-biome research posts, undersea, arcologies) with no second code path.
Jeroen ruled that ''thin'' folds into enclosed. By the same logic ''thick'' (Venus-like) and ''reducing'' (toxic) must too -- neither is open-air -- which collapses the rule to a single condition: open-air requires atmosphere == standard, everything else is enclosed. NULL atmosphere defaults to enclosed, which fails safe (an enclosed settlement on a breathable world is merely conservative; an open one in vacuum is absurd). Split: 231 open / 38 enclosed across 269 in-bounds populated bodies. NOTE the thick/reducing extension is the lead''s inference from Jeroen''s thin ruling, not his words -- confirm before writing.
Atmosphere keeps its full expressive range for the SURFACE-EXPEDITION layer (Jeroen: ''surface expeditions will play differently'' -- thin gives suit + dust storms + weather; none gives hard vacuum, no weather, extreme swings, radiation). The binary collapse applies ONLY to settlement layout. Record that, so the collapse is not later mistaken for atmosphere being unimportant.
(B) SOL GENERATOR SCOPE. T-1219..T-1221 carry the implementation; the DESIGN has no record. Needs capturing: the GeneratorScope enum shape (Procedural | Authored with a deepest_rung), the DLC gate being a DEPTH rather than a boolean (a Sol expansion deepens the ladder by changing one value), the absence of any new wire status because ''viewable at Global, no deeper'' IS the existing rung-liveness path rather than an error to report, and the ruling that Sol art is an authored DATA CANVAS rather than a finished image -- it rides the existing wire untouched, needs no new client draw path, and goes through the same map-art function as all 269 procedural bodies. The framing Jeroen accepted: you are not looking at a photograph of Earth, you are looking at your implant rendering Earth in the same visual language it renders everything else.
Also record that Sol bodies carry dangling terrain_reference rows pointing at heightmaps deliberately never baked (import_heightmaps.py explicitly excludes Sol), so a real Earth or Mars DEM dropped at that exact path would silently start generating a procedural homeworld with no gate to stop it.
Claim ids with ''pql decisions claim D architecture ...'' before writing.
DONE 2026-07-27. Both rulings written up: D-259 (enclosed settlements open-air requires a breathable atmosphere; branch on an explicit property, not the atmosphere string; NULL fails safe to enclosed; D-220''s density model declared physically inapplicable to a pressure vessel rather than merely mistuned; the D-166 door boundary contract identified as the already-planned handoff) and D-260 (generator scope Sol encoded as Authored with deepest_rung Global, the DLC gate a DEPTH not a boolean, no new wire status because rung-liveness already covers it, Sol art an authored DATA CANVAS not a finished image). The thick/reducing extension of Jeroen''s thin ruling is flagged inside D-259 as the author''s inference rather than his words. D-260 records the concrete hazard that motivated encoding the exclusion: systems.db still carries terrain_reference rows for Sol bodies pointing at heightmaps deliberately never baked, so a real Earth DEM dropped at that path would silently start generating a procedural homeworld. Also records that Earth will never have a walkable world by construction (8.5B people, 14% of the setting) as an explicit choice rather than a gap.', 'done', 'high', NULL, 'server', NULL, '2026-07-26 23:12:57.206', '2026-07-27 07:09:08.345', NULL, '58dab2bc8c4d68c3c49469e5df790e98', 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 OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
+2
View File
@@ -324,6 +324,8 @@ line in place — keep the Q-record for the audit trail rather than deleting it.
- [D-256: Canonical sampling convention — one absolute-metre derive core; the batch layer is a survey raster](decisions/architecture.md#d-256-canonical-sampling-convention--one-absolute-metre-derive-core-the-batch-layer-is-a-survey-raster) — _architecture_
- [D-257: Environment props share the character toon shading treatment; minimal-PBR carve-out for glazing](decisions/architecture.md#d-257-environment-props-share-the-character-toon-shading-treatment-minimal-pbr-carve-out-for-glazing) — _architecture_
- [D-258: Rung-0.5 expanded layer — one derived base for the whole ladder](decisions/architecture.md#d-258-rung-05-expanded-layer--one-derived-base-for-the-whole-ladder) — _architecture_
- [D-259: Enclosed settlements — open-air requires a breathable atmosphere](decisions/architecture.md#d-259-enclosed-settlements--open-air-requires-a-breathable-atmosphere) — _architecture_
- [D-260: Generator scope — Sol is authored, not generated](decisions/architecture.md#d-260-generator-scope--sol-is-authored-not-generated) — _architecture_
## Open questions
+54 -1
View File
@@ -2381,4 +2381,57 @@ Technical foundation decisions that constrain implementation: engine, client-ser
---
*112 decisions (D-001 through D-258, excluding gaps). Last updated: 2026-07-26 (D-258 — rung-0.5 expanded layer: one cached whole-body derivation from heightmap + reliefmap, hydrology resolved there and only there, every deeper rung sourced from it; the reliefmap read as a dominant-biome plurality, so descending reveals composition under a conservation invariant).*
### D-259: Enclosed settlements — open-air requires a breathable atmosphere
- **Date:** 2026-07-27
- **Decision:** A settlement is either **open-air** or **enclosed**, and **open-air requires `atmosphere == 'standard'`. Everything else is enclosed.** This is the first design ruling in the settlement-generator space.
- **Enclosed settlements are point locations on the Atlas.** Their interiors are deferred to a separate generator and handled like **embedded stations** — a bounded pressurised volume placed at a point, not a footprint laid out across terrain. The exterior cascade still runs on those bodies in full (terrain, heightmap, climate, hydrology); only settlement *layout* changes.
- **Branch on an explicit `enclosed` property, never on the atmosphere string.** Atmosphere derives the default at generation time; the generator reads the property. This leaves room for enclosed settlements on breathable worlds — hostile-biome research posts, undersea, arcologies — with no second code path, and makes the boundary a data decision rather than a code fork.
- **A NULL atmosphere defaults to enclosed**, which fails safe: an enclosed settlement on a breathable world is merely conservative, an open-air one in vacuum is absurd.
- Split on current content: **231 open / 38 enclosed** across the 269 in-bounds populated bodies (96.6% of population still open-air).
- **Atmosphere keeps its full expressive range where it earns it.** One field, two consumers at different granularity: the settlement generator collapses it to a binary; the **surface-expedition layer differentiates every class**`thin` gives suit + dust storms + weather + some thermal buffer, `none` gives hard vacuum, no weather, extreme swings, radiation and silence, `thick` crushing and corrosive, `reducing` toxic. Recorded explicitly so the binary collapse is never mistaken for atmosphere being unimportant.
- **Rationale:** D-220's density model is **physically inapplicable** to a pressure vessel, not merely mistuned. It measures people per km² of *footprint*, driven by utility cost per metre of street, agricultural plots filling grid gaps, and wealth dispersing into villa estates. A dome is governed by a different constraint entirely — pressurised volume. Run the settlement generator on an airless world and it yields 1,500 people per km² of open-air streets in vacuum. That is not a tuning bug a multiplier fixes.
The handoff mechanism already exists and is already the plan: **[D-166](content.md#d-166)'s door boundary contract**, where exterior generation stops at a door and hands off to interior generation. A dome's airlock *is* that door, so this invents no mechanism — it applies the planned one.
Jeroen ruled that `thin` folds into enclosed (Mars-thin supports no open-air street either). **By extension `thick` (Venus-like) and `reducing` (toxic) must too** — neither is survivable unprotected — which is what collapses the rule to a single condition instead of a list to maintain. *The thick/reducing extension is the record author's inference from Jeroen's `thin` ruling, not his words; it moves 2 bodies and 344K people, and is flagged here rather than buried.*
- **Raised by:** Jeroen, pair session 2026-07-26, unprompted mid-implementation: *"would it be sane to deal with atmosphere-less planets with underground/dome bases as if they were embedded stations… just show their locations and leave the rest for a separate generator"*, then *"let's fold in thin, but surface expeditions will play differently"*.
- **Implementation:** Not yet ticketed as its own work. Interacts with [D-258](#d-258)'s rung-0.5 epic (T-1211) only insofar as settlements are placed after the terrain layer. The two populated `asteroid_belt` bodies with no radius (T-1225) are a separate problem — a belt is not a sphere, has no equirectangular surface, and therefore no ladder at all; it is not an enclosed-settlement case.
- **Cross-reference:** [D-220](#d-220) (settlement density model — the record this carves an exception out of, and the one whose applicability limit this establishes), [D-166](content.md#d-166) (door boundary contract — the handoff this reuses), [D-260](#d-260) (generator scope — the sibling boundary ruling from the same session), [D-197](#d-197) (prosperity_baseline — the wealth/absence disambiguation that stays open-air-only), [D-194](#d-194) (district mix), [D-215](#d-215) (spatial arrangement patterns — all footprint-shaped, hence open-air-only).
- **Dissent:** None.
---
### D-260: Generator scope — Sol is authored, not generated
- **Date:** 2026-07-27
- **Decision:** **Sol (system `"GJ 0"`) is out of bounds for every generator**, and that exclusion is **encoded** rather than emergent. Scope is expressed as a per-body value:
```rust
pub enum GeneratorScope {
/// The core procedural cascade owns this body — every rung derived.
Procedural,
/// Authored content: only rungs at or above `deepest_rung` exist, served
/// from installed assets rather than derived.
Authored { deepest_rung: StepCanvasRung },
}
```
- **Sol maps to `Authored { deepest_rung: Global }`** — viewable at the whole-body rung, no deeper.
- **The DLC gate is a DEPTH, not a boolean.** A future Sol expansion deepens the ladder by changing one value; nothing has to be unpicked, and no "is this Sol" branch is created.
- **No new wire status.** "Viewable at Global, no deeper" *is* the existing **rung-liveness** path ([D-255](#d-255) amendment): the rungs below simply are not in that body's ladder, so there is nothing to report as an error. Without this, Sol bodies hit `SourceResolveError::NoTerrainReference` and report `NotFound` — i.e. "broken" — on the most populous places in the setting.
- **Checked in two places:** in `step_canvas.rs` *before* `resolver.resolve()`, and in the heightmap importer, so a stray DEM cannot enter the pipeline.
- **Sol's Atlas art is an authored DATA CANVAS, not a finished image.** An artist paints elevation/biome fields; an importer converts them. It rides the existing wire untouched, needs no new client display path, and goes through the **same map-art function as all 269 procedural bodies** — so Earth is drawn by the Atlas rather than pasted into it. A finished image would need a new wire shape, a new draw path, and would sit outside [D-255](#d-255)'s texel-exactness.
- **Rationale:** Sol is real geography. Generating a procedural Earth or Mars would be wrong in a way no tuning fixes, and the setting treats Sol as the legacy homeworld rather than a destination.
**The exclusion was previously an accident dressed as a rule.** `import_heightmaps.py` does say *"For each NON-Sol inhabited body…"* and *"Sol's terrain is real-geography (`sol_import`) and is NOT re-simulated"* — but `systems.db` still carries **`terrain_reference` rows for Sol bodies pointing at heightmaps that were deliberately never baked**. The files are simply absent. Drop a real Earth DEM at `wiki/star-systems/GJ-0/bodies/GJ0d/heightmap.png` — trivially available data — and the cascade begins generating a procedural homeworld with no gate to stop it and no warning. Encoding scope closes that path; documenting it in a comment did not.
**Scale of what this excludes, stated plainly:** Sol is 19 bodies including Earth (8.5B), Mars (1.2B), Luna (350M) and Europa (30M) — **10.08 billion people, ~16% of the Reach's 60.9B**. So **Earth will never have a walkable world by construction.** That is assumed deliberate; it is recorded here so it is an explicit choice rather than a gap someone later "fixes".
- **Raised by:** Jeroen, pair session 2026-07-26: *"sol is out of bounds of all generators, including mars"*, then *"encode the occlusion, with an option to gate out calls to a future dlc generator for sol"*, then *"we will add some atlas art so the user can view sol, but not zoom in deeper than global level… pull from server installed assets we will handcraft"*, and finally **data canvas** over finished image.
- **Implementation:** [T-1219](../../.pql) (epic), [T-1220](../../.pql) (enum + both gate points), [T-1221](../../.pql) (authored data canvas). The dangling Sol `terrain_reference` rows should be cleaned or made explicitly inert as part of T-1220.
- **Cross-reference:** [D-255](#d-255) (stepped ladder + the 2026-07-26 rung-liveness amendment this reuses instead of adding a status), [D-258](#d-258) (rung 0.5 — what Procedural bodies get and Sol does not), [D-259](#d-259) (enclosed settlements — the sibling boundary ruling from the same session), [D-202](#d-202) (per-body elevation assets; `import_heightmaps.py` is where the informal exclusion already lived), [D-227](#d-227) (derive-don't-store — authored content is outside its scope entirely, being neither derived nor cached).
- **Dissent:** None.
---
*114 decisions (D-001 through D-260, excluding gaps). Last updated: 2026-07-27 (D-259 — enclosed settlements: open-air requires a breathable atmosphere, branch on an explicit property, D-220's density model declared inapplicable to pressure vessels; D-260 — generator scope: Sol encoded as `Authored { deepest_rung: Global }`, the DLC gate a depth not a boolean, Sol art an authored data canvas).*