diff --git a/.pql/changelog/ticket_history/2026-07.sql b/.pql/changelog/ticket_history/2026-07.sql index 3531974d8..e44bbf1a5 100644 --- a/.pql/changelog/ticket_history/2026-07.sql +++ b/.pql/changelog/ticket_history/2026-07.sql @@ -1373,3 +1373,4 @@ Si verification notes: road_graph.rs has NO hub concept and NO edge-split machin 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 ('06FCDG73V9R6N024QSFDEJ4R68', 'status', 'backlog', 'in_progress', NULL, '2026-07-16 13:34:42', '2026-07-16 13:34:42.070', '2026-07-16 13:34:42.070', NULL, '59512cd5b886bad98a03e3bbb106b07d', 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 ('06FCDG73V9R6N024QSFDEJ4R68', 'assigned_to', NULL, 'dudley', NULL, '2026-07-16 13:34:49', '2026-07-16 13:34:49.724', '2026-07-16 13:34:49.724', NULL, '974c9ac15c87788ce7b7bc1af07548d5', 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 ('06FCDG73V9R6N024QSFDEJ4R68', 'status', 'in_progress', 'review', NULL, '2026-07-16 14:25:25', '2026-07-16 14:25:25.191', '2026-07-16 14:25:25.191', NULL, '4db8483f0395e003366d0313acca2bbb', 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 ('06FCDG73V9R6N024QSFDEJ4R68', 'status', 'review', 'done', NULL, '2026-07-16 15:15:16', '2026-07-16 15:15:16.465', '2026-07-16 15:15:16.465', NULL, '45ac7e300870b581b76c0a195c32ff67', 2) ON CONFLICT(hash) DO NOTHING; diff --git a/.pql/changelog/tickets/2026-07.sql b/.pql/changelog/tickets/2026-07.sql index bcd6cd412..fa710bb12 100644 --- a/.pql/changelog/tickets/2026-07.sql +++ b/.pql/changelog/tickets/2026-07.sql @@ -1788,3 +1788,29 @@ Deferred (no preference given): standalone-HQ Zipf population shares stay as-is Si verification notes: road_graph.rs has NO hub concept and NO edge-split machinery today (T-1038 treats every placement as a uniform MST node); RoadGraph::high_connectivity_junctions() exists (JUNCTION_DEGREE=3); FoundingOrientation consumers are founding_orientation() and coastal_edge() (if-let, safe); skeleton_gen has zero rail-facing rotation logic (new work, scoped); PR #177 data preconditions verified (population>0 + settlement_class on all rows; standalone HQs present as ordinary rows).', 'review', 'medium', 'dudley', 'server', 'D-242', '2026-06-14 15:29:50', '2026-07-16 14:25:25.189', NULL, '6489dd0ff1f3803b055b0911e9c3b62e', 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 ('06FPPYPF4PCTW99YMKXPA60Y40', 'task', '06FB0TNSRZXCHGS16BFHSSGSV4', 'heavy_works vocabulary value — split civilian heavy industry off military_industrial', 'PR #178 re-review (Tyre). The M1 re-tag parked three CIVILIAN heavy-works corps (sova-station-works habitat modules, stalownia-kowalski ore-processing machinery, westphalia-heavy-works Compact heavy equipment) on military_industrial — placement-class correct, but that value''s standalone_economic_role=''military'' is NOT inert: it feeds the D-211 CompatibilityMatrix military row (attractor_matching.rs:113, placement scoring — LIVE today) and political_archetype -> Military -> FortifiedPerimeter garrison geometry (attractor_matching.rs:659/686 — latent; masks to Pioneer today only because GJ896A/GJ601A lack system_factions data). Fix per the D-242 amendment note: add a heavy_works vocabulary value (D-237 pattern; anchor heavy_equipment, BulkSolid, Specialist, standalone_economic_role=manufacturing, Standalone placement), re-tag the three corps, regen. NEVER re-coarsen general_industrial (recorded non-regressive rule). Also consider whether sede-chemical-works (currently fuel_production, wrong commodity fusion_fuel vs chemical feedstock) belongs on a chemical/processing value in the same pass — Miri flagged it as the loosest fit.', 'backlog', 'medium', NULL, 'server', 'D-242', '2026-07-16 15:10:38.373', '2026-07-16 15:10:38.373', NULL, '7ddcf9c15c2a93b3b0543fb69d4d3804', 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 ('06FCDG73V9R6N024QSFDEJ4R68', 'story', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Road-graph hub refinement — scaled-cap hubs + co-location collapse + hybrid minor attach + RailHeadFacing junction pass', 'Follow-on to T-1038 (road-graph core shipped). Hub-selection refinement, gated on the resolved settlement model (D-242). + +Build on server/src/atlas/road_graph.rs: +1. Hub selection: ''real cities, scaled cap'' — wiki cities anchor the MST; cap scales with body size; standalone HQs/minor settlements are non-hub. +2. Co-location collapse: group same-named settlements (defensive; the D-242 corp-HQ fix removes most at source). +3. Hybrid minor-settlement attach: snap to nearest existing road edge if close, else spur to nearest hub (add edge-split-at-attach). +4. RailHeadFacing junction pass (T-1038 step 6, deferred): junction settlements (RoadGraph::high_connectivity_junctions already computed) get FoundingOrientation::RailHeadFacing. REQUIRES a D-213 amendment (adopted enum has no RailHeadFacing) + Layer-4 skeleton_gen handling. + +Needs population ranking — blocked on the corp-HQ-model + population-bake tickets. + +--- +Refinement (2026-07-16, /whats-next Si review + gap resolution with Jeroen): + +SCOPE ITEM 0 (added — placement-map correction, precedes hub work): corp_hq_placement.toml over-generalized D-242''s Standalone boundary (bulk_class != NonPhysical -> Standalone gave 95 Standalone / 60 CityTenant, incl. distilleries/wineries/leatherworks as standalone belt settlements). Jeroen''s ruling, faithful to D-242''s own examples: Standalone ONLY where the HQ is itself an industrial complex / company town — extraction/mining/quarrying, heavy vehicle + shipyard manufacturing, heavy energy (refinery/extraction complexes), gate/orbital infrastructure. Everything else CityTenant, explicitly including craft/consumer manufacturing (distilleries, breweries, wineries, ceramics, textiles, furniture), agriculture (estate offices sit in market towns), and high-tech fabs. Re-author per-value (judge each of the 31 value descriptions against this boundary), regen, and amend D-242 to state the boundary explicitly so it cannot be re-coarsened; record Jeroen''s "edge of settlement / clusters" color as CityTenant rendering detail for later phases, not a third placement class. + +1. Hub selection (gap: no cap formula, no HQ-row identity): RESOLUTION — thread an is_standalone_hq flag through read_body_settlements/CityRecord (join corporations.headquarters_body + proper_name where hq_placement=''Standalone''; the city_context_reader.rs:1165-1170 test comment predicted exactly this threading). Hubs = top-cap by population among NON-HQ cities; cap scales with body size via a documented inline constant (existing workshop-tunable pattern in road_graph.rs), sanity-checked on 2-3 bodies of different sizes. + +2. Co-location collapse (gap: zero live cases, no rule): RESOLUTION — ship trivial defensive: exact (body_id, name) match collapses to one node keeping lowest id, loud log warning when it ever fires. + +3. Hybrid minor-settlement attach (gap: no snap threshold, no edge-split machinery): RESOLUTION — engineer''s judgment: design the edge-split representation + pick the snap threshold as a documented inline constant; extend the RoadEdge/RoadNode invariants and the ten existing unit tests accordingly. + +4. RailHeadFacing (well-specified per Si): add the FoundingOrientation variant (consumers use if-let, no exhaustive-match break), assign via existing RoadGraph::high_connectivity_junctions (degree >= 3, matches D-213''s paula-round3 source), amend D-213, and make the skeleton_gen rotation call inline (Si''s suggested default: face the junction''s dominant incident-edge bearing). + +Deferred (no preference given): standalone-HQ Zipf population shares stay as-is (e.g. Gate Corporation 909M on GJ251c); the item-0 re-tune shrinks standalone rows to genuine company-towns where a real share is defensible. Revisit if Atlas numbers read wrong. + +Si verification notes: road_graph.rs has NO hub concept and NO edge-split machinery today (T-1038 treats every placement as a uniform MST node); RoadGraph::high_connectivity_junctions() exists (JUNCTION_DEGREE=3); FoundingOrientation consumers are founding_orientation() and coastal_edge() (if-let, safe); skeleton_gen has zero rail-facing rotation logic (new work, scoped); PR #177 data preconditions verified (population>0 + settlement_class on all rows; standalone HQs present as ordinary rows).', 'done', 'medium', 'dudley', 'server', 'D-242', '2026-06-14 15:29:50', '2026-07-16 15:15:16.460', NULL, 'fa5cf116e084387017b5d6a0d280c768', 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);