From 9336209ea9aa36e0821a471906b08213e85f4b5c Mon Sep 17 00:00:00 2001 From: Jeroen Schweitzer Date: Thu, 16 Jul 2026 13:09:04 +0200 Subject: [PATCH] =?UTF-8?q?chore(meta):=20close=20settlement-dataset=20bat?= =?UTF-8?q?ch=20=E2=80=94=20T-1074/T-1075=20done=20(PR=20#177=20merged);?= =?UTF-8?q?=20T-1076=20unblocked?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pql/changelog/ticket_history/2026-07.sql | 2 ++ .pql/changelog/tickets/2026-07.sql | 34 +++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/.pql/changelog/ticket_history/2026-07.sql b/.pql/changelog/ticket_history/2026-07.sql index 8594076a8..df7edbfe2 100644 --- a/.pql/changelog/ticket_history/2026-07.sql +++ b/.pql/changelog/ticket_history/2026-07.sql @@ -1334,3 +1334,5 @@ INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, chang 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 ('06FCDG73S4ET8KKTK62Z5KFEQM', 'assigned_to', NULL, 'dudley', NULL, '2026-07-16 07:33:41', '2026-07-16 07:33:41.107', '2026-07-16 07:33:41.107', NULL, '03dde46fff5a35876bdb227f008f3d7f', 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 ('06FCDG73NW7SNCA5Y8JN905QMR', 'status', 'in_progress', 'review', NULL, '2026-07-16 09:49:28', '2026-07-16 09:49:28.596', '2026-07-16 09:49:28.596', NULL, '7977bc9541bfce61e29855667c0fcdcb', 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 ('06FCDG73S4ET8KKTK62Z5KFEQM', 'status', 'in_progress', 'review', NULL, '2026-07-16 09:49:28', '2026-07-16 09:49:28.604', '2026-07-16 09:49:28.604', NULL, '7be819d7fe6d3c5613640599658348d4', 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 ('06FCDG73NW7SNCA5Y8JN905QMR', 'status', 'review', 'done', NULL, '2026-07-16 11:08:50', '2026-07-16 11:08:50.978', '2026-07-16 11:08:50.978', NULL, 'd29af2ba9bc5ff62a5d55990eea82614', 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 ('06FCDG73S4ET8KKTK62Z5KFEQM', 'status', 'review', 'done', NULL, '2026-07-16 11:08:50', '2026-07-16 11:08:50.980', '2026-07-16 11:08:50.980', NULL, '2b775e39c956ac93cd4a6bacbbc8cedc', 2) ON CONFLICT(hash) DO NOTHING; diff --git a/.pql/changelog/tickets/2026-07.sql b/.pql/changelog/tickets/2026-07.sql index 736671009..ae5da05ce 100644 --- a/.pql/changelog/tickets/2026-07.sql +++ b/.pql/changelog/tickets/2026-07.sql @@ -1648,3 +1648,37 @@ Refinement (2026-07-16, /whats-next Si review + gap resolution): Si verification notes: 463 atlas_city_names rows, all population=0 / settlement_class NULL — claim exact. match_cities (server/src/atlas/attractor_matching.rs) only READS these fields for tiering; nothing assigns them. D-242/D-223/D-211/D-196 chain is consistent; no conflicting open Q-records. Importer entry point: populate_atlas_city_names (tooling/economy-db/economy_import/atlas.py:61-141).', 'review', 'high', 'dudley', 'server', 'D-242', '2026-06-14 15:29:50', '2026-07-16 09:49:28.604', NULL, 'f8adeb8ec7747d76448aca85bc5f6020', 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 ('06FPM32KT5Z1JBP9BCN2KC53EG', 'task', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Wiki content: corp-placement coverage gaps — 10 pageless corps + GJ702B city names', 'Follow-up from T-1074 (D-242). Two wiki content gaps cap corp-HQ placement coverage: (1) 10 legacy DB-only corps (mvg, adams-ford, dsmc, 7 Cygni-B combines) have no wiki/corporations page, so no corp_specialization/hq_placement/headquarters_body — left NULL, non-fatal; they remain load-bearing for 2468 brand_products rows so rows were kept. Author pages (or record a deferral). (2) GJ 702B (Prometheus) has zero authored city names anywhere in the system, so prometheus-labs + kovalev-freight are logged unmatched CityTenant corps — the Reach''s longevity-monopoly hero system needs city names in its markers pool. Note: sova-station-works'' broken headquarters ref is NOT this ticket — it resolves under T-1054.', 'backlog', 'low', NULL, 'copy', NULL, '2026-07-16 08:30:20.625', '2026-07-16 10:16:18.763', NULL, '9e9055326c3c23b9252f3890767230a5', 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 ('06FCDG73NW7SNCA5Y8JN905QMR', 'story', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Corp HQ settlement model — remove HQs from the city pool; specialization-keyed standalone-vs-tenant; install-baked', 'Per D-242. Corp HQs are not cities and must leave atlas_city_names. + +1. Remove the D-207/D-223 reserved=1 corp-HQ cross-reference (populate_atlas_city_names_corps, tooling/economy-db/economy_import/atlas.py) — it inserts one atlas_city_names row per corp HQ, creating duplicate co-named cities (e.g. 10 Groombridge rows on GJ380c). +2. Author a source-canonical specialization -> HQ-placement map ({CityTenant, Standalone}). corp_type is degenerate (corporation/combine only); key on corporations.specialization (and/or supply_chain_role). Install-baked. +3. CityTenant HQs: a corp->city link, no new settlement (many corps may tenant one city). +4. Standalone HQs (extraction/heavy-industry/shipyards): emit their own settlement (body + position) into the cascade settlement list. Requires resolving headquarters_body (today 0/165 set; only headquarters_system + a most-populated-body heuristic). +5. Cascade settlement input becomes: city pool + standalone-HQ settlements, merged. + +Amends D-207, D-223. Blocks the road-graph hub refinement. + +--- +Refinement (2026-07-16, /whats-next Si review + gap resolution): + +1. Specialization key-space (gap): corporations.specialization is unconstrained free text — 20/165 rows hand-seeded prose via the ORPHANED tooling/populate-corporations.sh (raw sqlite3 INSERTs, single commit e05444f70, not in the Makefile or generator_sources.py; nothing in import_economics writes the column). supply_chain_role is 100% NULL, never wired. RESOLUTION: author a corp_specialization controlled vocabulary + source-canonical TOML (mirror the D-237 wiki/economics/specialization_vocabulary.toml pattern), backfill all 165 corps, and key the {CityTenant, Standalone} placement map on it — all in this ticket. Retire/supersede the orphaned populate-corporations.sh as part of the cleanup (hand-seeded DB values violate the source-canonical rule). + +2. headquarters_body resolution (gap): RESOLUTION — explicitly reuse the most-populated-body-in-system heuristic from populate_atlas_city_names_corps (tooling/economy-db/economy_import/atlas.py:229-233) at import/bake time to backfill headquarters_body for Standalone HQs. Deterministic, install-baked. + +Si verification notes: all 30 duplicate-name groups in atlas_city_names are 100% reserved=1 rows (zero duplicates among reserved=0) — removal is cleanly scoped. corp_type confirmed degenerate (158 corporation / 7 combine). Consumption side has zero corp/Standalone/Tenant scaffolding: the merge point is greenfield, natural seam is read_body_settlements (server/src/atlas/city_context_reader.rs:268) feeding match_cities (server/src/atlas/attractor_matching.rs).', 'done', 'high', 'dudley', 'server', 'D-242', '2026-06-14 15:29:50', '2026-07-16 11:08:50.978', NULL, '21ea17fd54d054f8b1034f388025e327', 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 ('06FCDG73S4ET8KKTK62Z5KFEQM', 'story', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Bake per-settlement population + settlement_class into the install dataset (only position stays seed-derived)', 'Per D-242. population + settlement_class are install-baked, not seed-derived. + +Today: body-level population is baked (273/3240 bodies > 0), but per-city population is 0 and settlement_class NULL for all 463 atlas_city_names rows. D-223 deferred these ''to placement (T-955)'', but match_cities only READS them for tiering — nothing assigns them, so the pop-from-seed step was never built and all cities fall to synthetic placement. + +Bake the per-settlement population spread + settlement_class into the source data (importer/source TOMLs). Only POSITION stays seed-derived (D-211). Drop the never-built seed-population idea. + +Supersedes the D-223 deferred-pop/class note. Enables significance-ranked hub selection. + +--- +Refinement (2026-07-16, /whats-next Si review + gap resolution): + +1. Population source (gap): RESOLUTION — pure importer derivation. import_economics computes the per-city population spread from the authored bodies.population on every regen-db run via a documented rank-size (Zipf-style) curve; no per-city population source file. Keep the curve constants named + documented in the importer — tuning is a code change by design. Only POSITION stays seed-derived (D-211). Amend D-242''s "carried down into the city/settlement source data" wording while implementing, to record the derivation rule (derivation-at-import, not hand-authoring). + +2. settlement_class assignment (gap): RESOLUTION — default every pooled city to PopulationBudget; the D-196 thresholds (>=50k active / <5k ghost) decide state from the baked population. An authored NameLocked override list (small new source TOML) pins hero cities. EconomicTriggered and OrganicGrowth are simulation-time classes per D-196 — out of bake scope. + +Si verification notes: 463 atlas_city_names rows, all population=0 / settlement_class NULL — claim exact. match_cities (server/src/atlas/attractor_matching.rs) only READS these fields for tiering; nothing assigns them. D-242/D-223/D-211/D-196 chain is consistent; no conflicting open Q-records. Importer entry point: populate_atlas_city_names (tooling/economy-db/economy_import/atlas.py:61-141).', 'done', 'high', 'dudley', 'server', 'D-242', '2026-06-14 15:29:50', '2026-07-16 11:08:50.980', NULL, '308acb6c5b17ed676ed92d81f3dc160f', 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);