chore(meta): refine + activate T-977 batch — T-992/T-994/T-995/T-1003 in_progress, T-1003 blocked by T-994, T-1004 parked to Phase 5

Si refinement round resolved 7 decisions: district-dominant = D-243 2048m tier
(build in T-994), draw at GenerateSkeleton, body-level coverage aggregate,
ratify shipped 28-tag palette (amend D-235), Gemma proposes text fields only,
swerve driver mappings pinned, T-1004 render mechanism deferred to Phase 5.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-07 19:19:09 +02:00
co-authored by Claude Fable 5
parent 3d6dcc9d05
commit e097874587
3 changed files with 126 additions and 0 deletions
+1
View File
@@ -1 +1,2 @@
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FKE0EW2617K9VE4QHSYSR9HW', '06FKCPBF41RWK9PW9M22Q7961C', '2026-07-06 10:38:33.017', '2026-07-06 10:38:33.017', NULL, '290574b958bce69afc8a81d7487f8fd5', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_deps.updated_at OR (excluded.updated_at = ticket_deps.updated_at AND excluded.hash > ticket_deps.hash);
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRWYHR72SC80F5T0TBW', '06FB0TNSRWGDT3AJJE5QD0E3FR', '2026-07-07 16:57:31.296', '2026-07-07 16:57:31.296', NULL, 'e6784e95e525cb6458fe258ab4b6e4c2', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_deps.updated_at OR (excluded.updated_at = ticket_deps.updated_at AND excluded.hash > ticket_deps.hash);
+49
View File
@@ -1057,3 +1057,52 @@ Follow-facing refinement (user, live session 2026-07-06): during an RMB path-fol
SIDEQUEST CLOSE-OUT (2026-07-07): all scope delivered and pushed sandbox (scene, greybox store, rig, gait machine, camera, cutaway modes w/ user-verdict mode-2 default recorded as D-250 amendment), RMB navigation vocabulary, layered head/torso look-at, D-252 view/movement protocol split (server+client), purchased UAL tiers wired (turn-in-place, stance enter/exits), design doc committed to docs/design/t1088-locomotion-sandbox-design.md (the ''design §'' references in sandbox code resolve in-repo now). Design-delta close-out notes: no new Gauntlet room was needed (constraint 12 never triggered, server untouched except D-252); ~40 lines of main.gd boot boilerplate duplicated with Pattern: markers for the T-962 extraction; seek-during-blend + remove_immutable_tracks caveats did not manifest in practice; ual_extended wiring superseded by the purchased-tier ual1/ual2 libraries; 2D select_yaw_target moving-branch is dead code post-D-252 (cleanup rides Phase 5). Remaining feel work parked as T-1096 (S9 live tuning needs the user). Closing.', NULL, '2026-07-07 12:10:20', '2026-07-07 12:10:20.956', '2026-07-07 12:10:20.956', NULL, '846e89916f601a4622a03b275f200bc6', 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 ('06FKCER95EK266H8RWPW8XT1F0', 'status', 'backlog', 'done', NULL, '2026-07-07 12:10:20', '2026-07-07 12:10:20.986', '2026-07-07 12:10:20.986', NULL, '3016244358c491462e72331ef063ed35', 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 ('06FB0TNSRX65YFYFR5RNCM9MCG', 'description', 'Methodology doc analogous to the D-223 naming one: stage-1 register selection from wiki prose, stage-2 structured output {tag, allow, block, weight, trauma_decay_rate}. Defines the Gemma prompt + review at GTTR/wiki authoring.
Round 3 reframe: Gemma is a BOUNDED corpus-distillation pass (one read of all wiki -> propose catalog templates -> human-gated), NOT per-body open-vocab generation. Plus core catalog hand-authoring (Miri = cultural meaning + eligibility; Araminta = matching visual_bundle).
Round-3 refinement (2026-05-26): reframed as a FOLLOW-ON extension, not a blocker of the core catalog (1005). Runs AFTER the core hand-authored set exists, to propose additional templates (corpus-distillation, human-gated) toward the 40-45 target. Needs an architecture-flavor Gemma methodology doc (analogous to the naming one) defining the extraction prompt + structured output schema + human-review gate.', 'Methodology doc analogous to the D-223 naming one: stage-1 register selection from wiki prose, stage-2 structured output {tag, allow, block, weight, trauma_decay_rate}. Defines the Gemma prompt + review at GTTR/wiki authoring.
Round 3 reframe: Gemma is a BOUNDED corpus-distillation pass (one read of all wiki -> propose catalog templates -> human-gated), NOT per-body open-vocab generation. Plus core catalog hand-authoring (Miri = cultural meaning + eligibility; Araminta = matching visual_bundle).
Round-3 refinement (2026-05-26): reframed as a FOLLOW-ON extension, not a blocker of the core catalog (1005). Runs AFTER the core hand-authored set exists, to propose additional templates (corpus-distillation, human-gated) toward the 40-45 target. Needs an architecture-flavor Gemma methodology doc (analogous to the naming one) defining the extraction prompt + structured output schema + human-review gate.
---
Refinement (/whats-next 2026-07-07): The stage-2 schema in the description is stale round-2 text there is no trauma_decay_rate anywhere in schema or code; D-232 round 3 (trait-template model) is authoritative. RESOLVED (user): Gemma proposes TEXT FIELDS ONLY tag, label, cultural_description, candidate allow_tags/block_tags. Humans set all numeric/eligibility fields with whole-pool knowledge (Miri: gates, base_weight, weight_mods, zone_affinity, corridor_pool/geographic_sector; Araminta: visual_bundle) the catalog-wide CI guardrails (V-TT-01 pool>=5, V-TT-02 weight<=60%) cannot be satisfied by a per-template extraction pass, so Gemma never sets numbers. Doc target: docs/gemma-architecture-flavor-methodology.md (analogous to docs/gemma-naming-methodology.md). Stage-1 register selection reads the current wiki tree (wiki/star-systems/*/index.md); state that assumption explicitly in the doc — location may move if Q-107 resolves. Q-106 is dissolved: no era-band logic in the doc.', NULL, '2026-07-07 16:57:22', '2026-07-07 16:57:22.053', '2026-07-07 16:57:22.053', NULL, '09163b19207472ac445d6e8fc496c104', 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 ('06FB0TNSRWYHR72SC80F5T0TBW', 'description', 'Apply the flavor profile as a filter over the D-142 zone-type ObjectTag baseline pool: block removed, allow weighted up by weight; dominant wins categorical, weighted-avg continuous. Three-layer: body x district x era-band (depth Q-106).
Round 3: this becomes the THREE-PHASE DRAW (body K-draw [K=5/3/1/0 by complexity_tier, SeedChain, coverage-aware] -> district-dominant by zone_affinity -> within-template seed picks) + CI guardrails, per D-232 not a flat per-body allow/block filter.', 'Apply the flavor profile as a filter over the D-142 zone-type ObjectTag baseline pool: block removed, allow weighted up by weight; dominant wins categorical, weighted-avg continuous. Three-layer: body x district x era-band (depth Q-106).
Round 3: this becomes the THREE-PHASE DRAW (body K-draw [K=5/3/1/0 by complexity_tier, SeedChain, coverage-aware] -> district-dominant by zone_affinity -> within-template seed picks) + CI guardrails, per D-232 not a flat per-body allow/block filter.
---
Refinement (/whats-next 2026-07-07): Paragraph 1 of the description is superseded round-1/2 prose the "D-142 zone-type ObjectTag baseline pool" is a miscite (D-142 = NPC-behavior zone taxonomy; no such pool exists anywhere) and era-bands were dissolved with Q-106. The round-3 three-phase draw is the whole scope. RESOLVED (user decisions):
1. "District-dominant" = the TRUE D-243 2048m District tier (4 quarters), NOT the 512m Quarter. The District tier has no code representation in the cascade yet building the District aggregation (grouping quarters, assigning one dominant template per 2048m District) is IN SCOPE for this ticket. The D-222/D-243 district redefinition was never captured into D-232 amend D-232 with a dated note pinning "district" = the D-243 2048m tier as part of this work.
2. The dominant-template pick runs at GenerateSkeleton (NOT "FillChunk head" FillChunk is pure/cache-free by design per T-987); store the resolved template on skeleton/block tags.
3. Coverage: thread a body-level district-type-mix aggregate into CityGenerationContext (from settlement placement / the L3-L4 dispatch) so draw_body_vocabulary() is coverage-aware up front (>=1 eligible template per present district type).
4. Seed the body K-draw from SeedChain::for_body(world_seed, body_id) NOT the per-dispatch chain so every city/quarter on a body draws the identical closed vocabulary (D-232 invariant).
5. Files: server/src/atlas/skeleton_gen.rs is the primary site replace the shipped flat assign_block_tags/zone_type_hash flavor_index pick (round-1/2 model) with the three-phase draw. The CI guardrails already exist and pass (V-TT-01/V-TT-02 in tooling/economy-db/economy_import/traits.py) no importer work needed.
6. geographic_sector remains a SOFT weight, two-part pool join (PR #148 note stands).', NULL, '2026-07-07 16:57:22', '2026-07-07 16:57:22.461', '2026-07-07 16:57:22.461', NULL, 'fedcae768907dabfea9d33e22a2face0', 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 ('06FB0TNSRZCG08B0P6PRNQV8KG', 'description', 'Author the ObjectTag + exterior-material vocabulary the allow/block lists and D-235 grammar reference. Carried over from the retired generator-arch D-READY-9 requirement. Content task, Miri + Araminta.', 'Author the ObjectTag + exterior-material vocabulary the allow/block lists and D-235 grammar reference. Carried over from the retired generator-arch D-READY-9 requirement. Content task, Miri + Araminta.
---
Refinement (/whats-next 2026-07-07): RESOLVED (user): the shipped 28-tag material palette in wiki/economics/architecture_trait_catalog.toml (T-1005) is RATIFIED as canonical. D-235''s example WallMaterial/RoofForm/FacadeRhythm/StreetSurface token lists must be amended to match shipped reality as part of this ticket. Deliverable = formalize-and-validate: (a) a machine-readable tag registry (proposal: wiki/economics/object_tag_vocabulary.toml, imported by economy_import/traits.py) covering every tag used in allow_tags/block_tags/visual_bundle; (b) importer validation that all catalog tags resolve against the registry; (c) fallback-graph validation absorbed from T-1004 (parked to Phase 5): every specific token declares a generic parent (generic_wall/roof/facade/street) and resolution is acyclic build-time check. Cite Q-049 (ObjectTag ownership/co-maintenance, still open Miri: cultural meaning, Araminta: visual) this ticket''s registry + review flow is the practical answer; close or update Q-049 with it. Q-107: the registry is generator-facing and Q-107-invariant like the catalog table; note the location assumption in the file header.', NULL, '2026-07-07 16:57:23', '2026-07-07 16:57:23.405', '2026-07-07 16:57:23.405', NULL, '4286256417fad064caadc02f0defc6fd', 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 ('06FB0TNSRWGDT3AJJE5QD0E3FR', 'description', 'Closed vocabulary by default; a rare per-building wildcard draws a COHERENT whole foreign template (cultural-only — function still passes economic hard gates; never an axis-scramble). Two OPPOSED active drivers: foreign-import (another corridor) scaled UP by cosmopolitanism/centrality/transit/Epicenter tier; heritage-callback (the body''s own corridor heritage sub-pool) scaled UP by remoteness/isolation/conservatism. Passive past-vogue holdover from age (D-217 wear). Sparsity escape-hatch = the SAME mechanism triggered by necessity when the closed vocabulary cannot serve a district. Per D-232.', 'Closed vocabulary by default; a rare per-building wildcard draws a COHERENT whole foreign template (cultural-only — function still passes economic hard gates; never an axis-scramble). Two OPPOSED active drivers: foreign-import (another corridor) scaled UP by cosmopolitanism/centrality/transit/Epicenter tier; heritage-callback (the body''s own corridor heritage sub-pool) scaled UP by remoteness/isolation/conservatism. Passive past-vogue holdover from age (D-217 wear). Sparsity escape-hatch = the SAME mechanism triggered by necessity when the closed vocabulary cannot serve a district. Per D-232.
---
Refinement (/whats-next 2026-07-07): Blocked by T-994 (edge added) the swerve overrides the three-phase draw; implement after it lands, within this batch. RESOLVED (user): resolve driver mappings now. Proposed mappings to REAL fields (integer bps mods, constants in one tunable block):
- foreign-import scale-ups: WorldTier::Epicenter / WorldTier::Passage (transit), dominant_faction == mixed (cosmopolitanism), road/rail-graph hub degree where available in context (centrality; else world_tier proxy).
- heritage-callback scale-ups: remoteness/isolation from star_systems dist_ly / earth_proximity percentile plus absence of Passage tier; conservatism from founding_age_years (older = stronger callback; T-1000 backfilled the field).
- Placeholder wildcard rate: base 100 bps (1%) per building, driver mods multiplicative, hard cap 300 bps; all constants integer bps per D-010 determinism.
- Passive past-vogue holdover rides D-217 wear/era; no new fields.
Data-model prerequisite: extend ArchitectureFlavorRef (server/src/simulation/generator.rs:826, currently a u8 index into trait_selection) to represent an out-of-vocabulary template (e.g. InVocabulary(u8) | Swerve(template_tag)) the wildcard draws outside the closed K-set by definition.
Sparsity escape-hatch: the SAME mechanism, necessity-triggered at District-dominant assignment time (2048m tier per T-994 refinement) when zero eligible templates serve the district type post-hard-gate.', NULL, '2026-07-07 16:57:23', '2026-07-07 16:57:23.876', '2026-07-07 16:57:23.876', NULL, '8a1882447dbd25441a6c9d0a6c3ba4eb', 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 ('06FB0TNSRZNNMZPXSEZ7HN778R', 'description', 'Every specific texture/material token declares a generic parent it degrades to: temple_wall_wood -> generic wood_wall placeholder until the specific asset ships, then it upgrades IN PLACE. The logical token a building uses is fixed + deterministic at generation (frozen world); only render fidelity is incremental. This is where patched-in themes/textures live -> NO catalog versioning needed for art (versioning only re-enters if a NEW logical template is added post-launch). Per D-232 + D-235. Cross-refs ticket 988 (exterior visual grammar).', 'Every specific texture/material token declares a generic parent it degrades to: temple_wall_wood -> generic wood_wall placeholder until the specific asset ships, then it upgrades IN PLACE. The logical token a building uses is fixed + deterministic at generation (frozen world); only render fidelity is incremental. This is where patched-in themes/textures live -> NO catalog versioning needed for art (versioning only re-enters if a NEW logical template is added post-launch). Per D-232 + D-235. Cross-refs ticket 988 (exterior visual grammar).
---
Refinement (/whats-next 2026-07-07): PARKED TO PHASE 5 (user decision) reparented under the Phase 5 epic. D-235 itself marks the patch-upgrade render mechanism Phase 5+/post-launch; the fallback DATA already shipped (T-1005 catalog visual_bundle.fallback maps + the four generic placeholders generic_wall/roof/facade/street). The Phase-4-needed slice (build-time fallback-graph validation: every specific token resolves to a generic, no cycles) moved to T-995. When picked up in Phase 5: the mechanism is client/asset-pipeline resolution (which assets have shipped -> in-place upgrade); coordinate with T-988 (BuildingExteriorTag grammar), T-1050 (production-status catalog, held) and open Q-119 (generic-parent asset set enumeration).', NULL, '2026-07-07 16:57:24', '2026-07-07 16:57:24.538', '2026-07-07 16:57:24.538', NULL, '2f7bc164f3f5c8ec52c75a1352d94520', 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 ('06FB0TNSRZNNMZPXSEZ7HN778R', 'parent_id', 'T-977', 'T-749', NULL, '2026-07-07 16:57:31', '2026-07-07 16:57:31.903', '2026-07-07 16:57:31.903', NULL, '30d225e7be67fc2d91ac18e180a19ffc', 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 ('06FB0TNSRX65YFYFR5RNCM9MCG', 'status', 'backlog', 'in_progress', NULL, '2026-07-07 17:18:47', '2026-07-07 17:18:47.873', '2026-07-07 17:18:47.873', NULL, '33c494db88791e3acea11b8e08d9a49b', 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 ('06FB0TNSRWYHR72SC80F5T0TBW', 'status', 'backlog', 'in_progress', NULL, '2026-07-07 17:18:47', '2026-07-07 17:18:47.875', '2026-07-07 17:18:47.875', NULL, '022f4ff2df5ad20c9269eea9952ded10', 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 ('06FB0TNSRWGDT3AJJE5QD0E3FR', 'status', 'backlog', 'in_progress', NULL, '2026-07-07 17:18:47', '2026-07-07 17:18:47.876', '2026-07-07 17:18:47.876', NULL, '413acc4af15800667d8dbcae00f00ce2', 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 ('06FB0TNSRZCG08B0P6PRNQV8KG', 'status', 'backlog', 'in_progress', NULL, '2026-07-07 17:18:47', '2026-07-07 17:18:47.876', '2026-07-07 17:18:47.876', NULL, '91996bb1360bb2954c97a01e536ba8b7', 2) ON CONFLICT(hash) DO NOTHING;
+76
View File
@@ -903,3 +903,79 @@ RMB gesture vocabulary (user, live session 2026-07-06, added to the path-preview
Follow-facing refinement (user, live session 2026-07-06): during an RMB path-follow the BODY commits to the leg/movement direction (mouse no longer swings body yaw); the mouse instead drives a LAYERED LOOK-AT Head bone (~70deg limit) plus torso twist via a spine bone (~30deg) for looking far lateral/behind; beyond their sum the character physically cannot look further without turning (correct). Pure client presentation on the D-249 model; SetFacing continues to ride the wire during follows, so the SERVER vision cone still follows the mouse (diegetic: the character looks where the player points while walking a committed path). Implementation: Godot LookAtModifier3D pair under the CharacterVisual skeleton, influence-faded in/out on follow start/end; rig gains a commit_body_to_motion flag (yaw from leg velocity while set).
SIDEQUEST CLOSE-OUT (2026-07-07): all scope delivered and pushed sandbox (scene, greybox store, rig, gait machine, camera, cutaway modes w/ user-verdict mode-2 default recorded as D-250 amendment), RMB navigation vocabulary, layered head/torso look-at, D-252 view/movement protocol split (server+client), purchased UAL tiers wired (turn-in-place, stance enter/exits), design doc committed to docs/design/t1088-locomotion-sandbox-design.md (the ''design §'' references in sandbox code resolve in-repo now). Design-delta close-out notes: no new Gauntlet room was needed (constraint 12 never triggered, server untouched except D-252); ~40 lines of main.gd boot boilerplate duplicated with Pattern: markers for the T-962 extraction; seek-during-blend + remove_immutable_tracks caveats did not manifest in practice; ual_extended wiring superseded by the purchased-tier ual1/ual2 libraries; 2D select_yaw_target moving-branch is dead code post-D-252 (cleanup rides Phase 5). Remaining feel work parked as T-1096 (S9 live tuning needs the user). Closing.', 'done', 'high', NULL, 'client', NULL, '2026-07-06 07:01:06.475', '2026-07-07 12:10:20.986', NULL, 'ce4896d59ece08a42a88e7e026b7d15f', 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 ('06FB0TNSRX65YFYFR5RNCM9MCG', 'task', '06FB0TNSRWMZBFV1V6F79VW8S4', 'Gemma architecture-flavor methodology doc (stage1 register + stage2 structured)', 'Methodology doc analogous to the D-223 naming one: stage-1 register selection from wiki prose, stage-2 structured output {tag, allow, block, weight, trauma_decay_rate}. Defines the Gemma prompt + review at GTTR/wiki authoring.
Round 3 reframe: Gemma is a BOUNDED corpus-distillation pass (one read of all wiki -> propose catalog templates -> human-gated), NOT per-body open-vocab generation. Plus core catalog hand-authoring (Miri = cultural meaning + eligibility; Araminta = matching visual_bundle).
Round-3 refinement (2026-05-26): reframed as a FOLLOW-ON extension, not a blocker of the core catalog (1005). Runs AFTER the core hand-authored set exists, to propose additional templates (corpus-distillation, human-gated) toward the 40-45 target. Needs an architecture-flavor Gemma methodology doc (analogous to the naming one) defining the extraction prompt + structured output schema + human-review gate.
---
Refinement (/whats-next 2026-07-07): The stage-2 schema in the description is stale round-2 text there is no trauma_decay_rate anywhere in schema or code; D-232 round 3 (trait-template model) is authoritative. RESOLVED (user): Gemma proposes TEXT FIELDS ONLY tag, label, cultural_description, candidate allow_tags/block_tags. Humans set all numeric/eligibility fields with whole-pool knowledge (Miri: gates, base_weight, weight_mods, zone_affinity, corridor_pool/geographic_sector; Araminta: visual_bundle) the catalog-wide CI guardrails (V-TT-01 pool>=5, V-TT-02 weight<=60%) cannot be satisfied by a per-template extraction pass, so Gemma never sets numbers. Doc target: docs/gemma-architecture-flavor-methodology.md (analogous to docs/gemma-naming-methodology.md). Stage-1 register selection reads the current wiki tree (wiki/star-systems/*/index.md); state that assumption explicitly in the doc — location may move if Q-107 resolves. Q-106 is dissolved: no era-band logic in the doc.', 'backlog', 'high', NULL, 'server', 'D-232', '2026-05-25 19:11:41', '2026-07-07 16:57:22.053', NULL, 'b7e7fec5b37551d04fc6249ab697de70', 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 ('06FB0TNSRWYHR72SC80F5T0TBW', 'task', '06FB0TNSRWMZBFV1V6F79VW8S4', 'allow/block weighted filter at chunk fill over zone-type ObjectTag pool', 'Apply the flavor profile as a filter over the D-142 zone-type ObjectTag baseline pool: block removed, allow weighted up by weight; dominant wins categorical, weighted-avg continuous. Three-layer: body x district x era-band (depth Q-106).
Round 3: this becomes the THREE-PHASE DRAW (body K-draw [K=5/3/1/0 by complexity_tier, SeedChain, coverage-aware] -> district-dominant by zone_affinity -> within-template seed picks) + CI guardrails, per D-232 not a flat per-body allow/block filter.
---
Refinement (/whats-next 2026-07-07): Paragraph 1 of the description is superseded round-1/2 prose the "D-142 zone-type ObjectTag baseline pool" is a miscite (D-142 = NPC-behavior zone taxonomy; no such pool exists anywhere) and era-bands were dissolved with Q-106. The round-3 three-phase draw is the whole scope. RESOLVED (user decisions):
1. "District-dominant" = the TRUE D-243 2048m District tier (4 quarters), NOT the 512m Quarter. The District tier has no code representation in the cascade yet building the District aggregation (grouping quarters, assigning one dominant template per 2048m District) is IN SCOPE for this ticket. The D-222/D-243 district redefinition was never captured into D-232 amend D-232 with a dated note pinning "district" = the D-243 2048m tier as part of this work.
2. The dominant-template pick runs at GenerateSkeleton (NOT "FillChunk head" FillChunk is pure/cache-free by design per T-987); store the resolved template on skeleton/block tags.
3. Coverage: thread a body-level district-type-mix aggregate into CityGenerationContext (from settlement placement / the L3-L4 dispatch) so draw_body_vocabulary() is coverage-aware up front (>=1 eligible template per present district type).
4. Seed the body K-draw from SeedChain::for_body(world_seed, body_id) NOT the per-dispatch chain so every city/quarter on a body draws the identical closed vocabulary (D-232 invariant).
5. Files: server/src/atlas/skeleton_gen.rs is the primary site replace the shipped flat assign_block_tags/zone_type_hash flavor_index pick (round-1/2 model) with the three-phase draw. The CI guardrails already exist and pass (V-TT-01/V-TT-02 in tooling/economy-db/economy_import/traits.py) no importer work needed.
6. geographic_sector remains a SOFT weight, two-part pool join (PR #148 note stands).', 'backlog', 'medium', NULL, 'server', 'D-232', '2026-05-25 19:11:45', '2026-07-07 16:57:22.461', NULL, 'f6c6be1e3a52525551f1c3bce89c8dac', 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 ('06FB0TNSRZCG08B0P6PRNQV8KG', 'task', '06FB0TNSRWMZBFV1V6F79VW8S4', 'ObjectTag vocabulary authoring (Miri + Araminta co-maintenance)', 'Author the ObjectTag + exterior-material vocabulary the allow/block lists and D-235 grammar reference. Carried over from the retired generator-arch D-READY-9 requirement. Content task, Miri + Araminta.
---
Refinement (/whats-next 2026-07-07): RESOLVED (user): the shipped 28-tag material palette in wiki/economics/architecture_trait_catalog.toml (T-1005) is RATIFIED as canonical. D-235''s example WallMaterial/RoofForm/FacadeRhythm/StreetSurface token lists must be amended to match shipped reality as part of this ticket. Deliverable = formalize-and-validate: (a) a machine-readable tag registry (proposal: wiki/economics/object_tag_vocabulary.toml, imported by economy_import/traits.py) covering every tag used in allow_tags/block_tags/visual_bundle; (b) importer validation that all catalog tags resolve against the registry; (c) fallback-graph validation absorbed from T-1004 (parked to Phase 5): every specific token declares a generic parent (generic_wall/roof/facade/street) and resolution is acyclic build-time check. Cite Q-049 (ObjectTag ownership/co-maintenance, still open Miri: cultural meaning, Araminta: visual) this ticket''s registry + review flow is the practical answer; close or update Q-049 with it. Q-107: the registry is generator-facing and Q-107-invariant like the catalog table; note the location assumption in the file header.', 'backlog', 'medium', NULL, 'server', 'D-232', '2026-05-25 19:11:47', '2026-07-07 16:57:23.405', NULL, 'ab05a81fedd1e474794fe03fe8eff4f4', 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 ('06FB0TNSRWGDT3AJJE5QD0E3FR', 'task', '06FB0TNSRWMZBFV1V6F79VW8S4', 'Deviation/swerve system — closed-default + rare per-building wildcard', 'Closed vocabulary by default; a rare per-building wildcard draws a COHERENT whole foreign template (cultural-only — function still passes economic hard gates; never an axis-scramble). Two OPPOSED active drivers: foreign-import (another corridor) scaled UP by cosmopolitanism/centrality/transit/Epicenter tier; heritage-callback (the body''s own corridor heritage sub-pool) scaled UP by remoteness/isolation/conservatism. Passive past-vogue holdover from age (D-217 wear). Sparsity escape-hatch = the SAME mechanism triggered by necessity when the closed vocabulary cannot serve a district. Per D-232.
---
Refinement (/whats-next 2026-07-07): Blocked by T-994 (edge added) the swerve overrides the three-phase draw; implement after it lands, within this batch. RESOLVED (user): resolve driver mappings now. Proposed mappings to REAL fields (integer bps mods, constants in one tunable block):
- foreign-import scale-ups: WorldTier::Epicenter / WorldTier::Passage (transit), dominant_faction == mixed (cosmopolitanism), road/rail-graph hub degree where available in context (centrality; else world_tier proxy).
- heritage-callback scale-ups: remoteness/isolation from star_systems dist_ly / earth_proximity percentile plus absence of Passage tier; conservatism from founding_age_years (older = stronger callback; T-1000 backfilled the field).
- Placeholder wildcard rate: base 100 bps (1%) per building, driver mods multiplicative, hard cap 300 bps; all constants integer bps per D-010 determinism.
- Passive past-vogue holdover rides D-217 wear/era; no new fields.
Data-model prerequisite: extend ArchitectureFlavorRef (server/src/simulation/generator.rs:826, currently a u8 index into trait_selection) to represent an out-of-vocabulary template (e.g. InVocabulary(u8) | Swerve(template_tag)) the wildcard draws outside the closed K-set by definition.
Sparsity escape-hatch: the SAME mechanism, necessity-triggered at District-dominant assignment time (2048m tier per T-994 refinement) when zero eligible templates serve the district type post-hard-gate.', 'backlog', 'medium', NULL, 'server', 'D-232', '2026-05-25 20:36:39', '2026-07-07 16:57:23.876', NULL, '9ea58bb1214745200ab1cd3f9ff22011', 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 ('06FB0TNSRZNNMZPXSEZ7HN778R', 'task', '06FB0TNSRWMZBFV1V6F79VW8S4', 'Visual-asset fallback hierarchy (specific->generic tokens, patch-upgradable)', 'Every specific texture/material token declares a generic parent it degrades to: temple_wall_wood -> generic wood_wall placeholder until the specific asset ships, then it upgrades IN PLACE. The logical token a building uses is fixed + deterministic at generation (frozen world); only render fidelity is incremental. This is where patched-in themes/textures live -> NO catalog versioning needed for art (versioning only re-enters if a NEW logical template is added post-launch). Per D-232 + D-235. Cross-refs ticket 988 (exterior visual grammar).
---
Refinement (/whats-next 2026-07-07): PARKED TO PHASE 5 (user decision) reparented under the Phase 5 epic. D-235 itself marks the patch-upgrade render mechanism Phase 5+/post-launch; the fallback DATA already shipped (T-1005 catalog visual_bundle.fallback maps + the four generic placeholders generic_wall/roof/facade/street). The Phase-4-needed slice (build-time fallback-graph validation: every specific token resolves to a generic, no cycles) moved to T-995. When picked up in Phase 5: the mechanism is client/asset-pipeline resolution (which assets have shipped -> in-place upgrade); coordinate with T-988 (BuildingExteriorTag grammar), T-1050 (production-status catalog, held) and open Q-119 (generic-parent asset set enumeration).', 'backlog', 'medium', NULL, 'server', 'D-235', '2026-05-25 20:36:42', '2026-07-07 16:57:24.538', NULL, '130f4ab3b4173c89730061c68dc85aa6', 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 ('06FB0TNSRZNNMZPXSEZ7HN778R', 'task', '06FB0TNSRXX29H5X0EB0F0GBW4', 'Visual-asset fallback hierarchy (specific->generic tokens, patch-upgradable)', 'Every specific texture/material token declares a generic parent it degrades to: temple_wall_wood -> generic wood_wall placeholder until the specific asset ships, then it upgrades IN PLACE. The logical token a building uses is fixed + deterministic at generation (frozen world); only render fidelity is incremental. This is where patched-in themes/textures live -> NO catalog versioning needed for art (versioning only re-enters if a NEW logical template is added post-launch). Per D-232 + D-235. Cross-refs ticket 988 (exterior visual grammar).
---
Refinement (/whats-next 2026-07-07): PARKED TO PHASE 5 (user decision) reparented under the Phase 5 epic. D-235 itself marks the patch-upgrade render mechanism Phase 5+/post-launch; the fallback DATA already shipped (T-1005 catalog visual_bundle.fallback maps + the four generic placeholders generic_wall/roof/facade/street). The Phase-4-needed slice (build-time fallback-graph validation: every specific token resolves to a generic, no cycles) moved to T-995. When picked up in Phase 5: the mechanism is client/asset-pipeline resolution (which assets have shipped -> in-place upgrade); coordinate with T-988 (BuildingExteriorTag grammar), T-1050 (production-status catalog, held) and open Q-119 (generic-parent asset set enumeration).', 'backlog', 'medium', NULL, 'server', 'D-235', '2026-05-25 20:36:42', '2026-07-07 16:57:31.896', NULL, 'b5ac81f800b50c83375168b8890577e6', 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 ('06FB0TNSRX65YFYFR5RNCM9MCG', 'task', '06FB0TNSRWMZBFV1V6F79VW8S4', 'Gemma architecture-flavor methodology doc (stage1 register + stage2 structured)', 'Methodology doc analogous to the D-223 naming one: stage-1 register selection from wiki prose, stage-2 structured output {tag, allow, block, weight, trauma_decay_rate}. Defines the Gemma prompt + review at GTTR/wiki authoring.
Round 3 reframe: Gemma is a BOUNDED corpus-distillation pass (one read of all wiki -> propose catalog templates -> human-gated), NOT per-body open-vocab generation. Plus core catalog hand-authoring (Miri = cultural meaning + eligibility; Araminta = matching visual_bundle).
Round-3 refinement (2026-05-26): reframed as a FOLLOW-ON extension, not a blocker of the core catalog (1005). Runs AFTER the core hand-authored set exists, to propose additional templates (corpus-distillation, human-gated) toward the 40-45 target. Needs an architecture-flavor Gemma methodology doc (analogous to the naming one) defining the extraction prompt + structured output schema + human-review gate.
---
Refinement (/whats-next 2026-07-07): The stage-2 schema in the description is stale round-2 text there is no trauma_decay_rate anywhere in schema or code; D-232 round 3 (trait-template model) is authoritative. RESOLVED (user): Gemma proposes TEXT FIELDS ONLY tag, label, cultural_description, candidate allow_tags/block_tags. Humans set all numeric/eligibility fields with whole-pool knowledge (Miri: gates, base_weight, weight_mods, zone_affinity, corridor_pool/geographic_sector; Araminta: visual_bundle) the catalog-wide CI guardrails (V-TT-01 pool>=5, V-TT-02 weight<=60%) cannot be satisfied by a per-template extraction pass, so Gemma never sets numbers. Doc target: docs/gemma-architecture-flavor-methodology.md (analogous to docs/gemma-naming-methodology.md). Stage-1 register selection reads the current wiki tree (wiki/star-systems/*/index.md); state that assumption explicitly in the doc — location may move if Q-107 resolves. Q-106 is dissolved: no era-band logic in the doc.', 'in_progress', 'high', NULL, 'server', 'D-232', '2026-05-25 19:11:41', '2026-07-07 17:18:47.872', NULL, 'a3d2c8fddd45a640973e0d5540d88d5c', 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 ('06FB0TNSRWYHR72SC80F5T0TBW', 'task', '06FB0TNSRWMZBFV1V6F79VW8S4', 'allow/block weighted filter at chunk fill over zone-type ObjectTag pool', 'Apply the flavor profile as a filter over the D-142 zone-type ObjectTag baseline pool: block removed, allow weighted up by weight; dominant wins categorical, weighted-avg continuous. Three-layer: body x district x era-band (depth Q-106).
Round 3: this becomes the THREE-PHASE DRAW (body K-draw [K=5/3/1/0 by complexity_tier, SeedChain, coverage-aware] -> district-dominant by zone_affinity -> within-template seed picks) + CI guardrails, per D-232 not a flat per-body allow/block filter.
---
Refinement (/whats-next 2026-07-07): Paragraph 1 of the description is superseded round-1/2 prose the "D-142 zone-type ObjectTag baseline pool" is a miscite (D-142 = NPC-behavior zone taxonomy; no such pool exists anywhere) and era-bands were dissolved with Q-106. The round-3 three-phase draw is the whole scope. RESOLVED (user decisions):
1. "District-dominant" = the TRUE D-243 2048m District tier (4 quarters), NOT the 512m Quarter. The District tier has no code representation in the cascade yet building the District aggregation (grouping quarters, assigning one dominant template per 2048m District) is IN SCOPE for this ticket. The D-222/D-243 district redefinition was never captured into D-232 amend D-232 with a dated note pinning "district" = the D-243 2048m tier as part of this work.
2. The dominant-template pick runs at GenerateSkeleton (NOT "FillChunk head" FillChunk is pure/cache-free by design per T-987); store the resolved template on skeleton/block tags.
3. Coverage: thread a body-level district-type-mix aggregate into CityGenerationContext (from settlement placement / the L3-L4 dispatch) so draw_body_vocabulary() is coverage-aware up front (>=1 eligible template per present district type).
4. Seed the body K-draw from SeedChain::for_body(world_seed, body_id) NOT the per-dispatch chain so every city/quarter on a body draws the identical closed vocabulary (D-232 invariant).
5. Files: server/src/atlas/skeleton_gen.rs is the primary site replace the shipped flat assign_block_tags/zone_type_hash flavor_index pick (round-1/2 model) with the three-phase draw. The CI guardrails already exist and pass (V-TT-01/V-TT-02 in tooling/economy-db/economy_import/traits.py) no importer work needed.
6. geographic_sector remains a SOFT weight, two-part pool join (PR #148 note stands).', 'in_progress', 'medium', NULL, 'server', 'D-232', '2026-05-25 19:11:45', '2026-07-07 17:18:47.875', NULL, '939966b06bcf04503b737256f2d2a148', 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 ('06FB0TNSRZCG08B0P6PRNQV8KG', 'task', '06FB0TNSRWMZBFV1V6F79VW8S4', 'ObjectTag vocabulary authoring (Miri + Araminta co-maintenance)', 'Author the ObjectTag + exterior-material vocabulary the allow/block lists and D-235 grammar reference. Carried over from the retired generator-arch D-READY-9 requirement. Content task, Miri + Araminta.
---
Refinement (/whats-next 2026-07-07): RESOLVED (user): the shipped 28-tag material palette in wiki/economics/architecture_trait_catalog.toml (T-1005) is RATIFIED as canonical. D-235''s example WallMaterial/RoofForm/FacadeRhythm/StreetSurface token lists must be amended to match shipped reality as part of this ticket. Deliverable = formalize-and-validate: (a) a machine-readable tag registry (proposal: wiki/economics/object_tag_vocabulary.toml, imported by economy_import/traits.py) covering every tag used in allow_tags/block_tags/visual_bundle; (b) importer validation that all catalog tags resolve against the registry; (c) fallback-graph validation absorbed from T-1004 (parked to Phase 5): every specific token declares a generic parent (generic_wall/roof/facade/street) and resolution is acyclic build-time check. Cite Q-049 (ObjectTag ownership/co-maintenance, still open Miri: cultural meaning, Araminta: visual) this ticket''s registry + review flow is the practical answer; close or update Q-049 with it. Q-107: the registry is generator-facing and Q-107-invariant like the catalog table; note the location assumption in the file header.', 'in_progress', 'medium', NULL, 'server', 'D-232', '2026-05-25 19:11:47', '2026-07-07 17:18:47.875', NULL, 'd7f3d3ab41881fcdfa12682680a8eff1', 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 ('06FB0TNSRWGDT3AJJE5QD0E3FR', 'task', '06FB0TNSRWMZBFV1V6F79VW8S4', 'Deviation/swerve system — closed-default + rare per-building wildcard', 'Closed vocabulary by default; a rare per-building wildcard draws a COHERENT whole foreign template (cultural-only — function still passes economic hard gates; never an axis-scramble). Two OPPOSED active drivers: foreign-import (another corridor) scaled UP by cosmopolitanism/centrality/transit/Epicenter tier; heritage-callback (the body''s own corridor heritage sub-pool) scaled UP by remoteness/isolation/conservatism. Passive past-vogue holdover from age (D-217 wear). Sparsity escape-hatch = the SAME mechanism triggered by necessity when the closed vocabulary cannot serve a district. Per D-232.
---
Refinement (/whats-next 2026-07-07): Blocked by T-994 (edge added) the swerve overrides the three-phase draw; implement after it lands, within this batch. RESOLVED (user): resolve driver mappings now. Proposed mappings to REAL fields (integer bps mods, constants in one tunable block):
- foreign-import scale-ups: WorldTier::Epicenter / WorldTier::Passage (transit), dominant_faction == mixed (cosmopolitanism), road/rail-graph hub degree where available in context (centrality; else world_tier proxy).
- heritage-callback scale-ups: remoteness/isolation from star_systems dist_ly / earth_proximity percentile plus absence of Passage tier; conservatism from founding_age_years (older = stronger callback; T-1000 backfilled the field).
- Placeholder wildcard rate: base 100 bps (1%) per building, driver mods multiplicative, hard cap 300 bps; all constants integer bps per D-010 determinism.
- Passive past-vogue holdover rides D-217 wear/era; no new fields.
Data-model prerequisite: extend ArchitectureFlavorRef (server/src/simulation/generator.rs:826, currently a u8 index into trait_selection) to represent an out-of-vocabulary template (e.g. InVocabulary(u8) | Swerve(template_tag)) the wildcard draws outside the closed K-set by definition.
Sparsity escape-hatch: the SAME mechanism, necessity-triggered at District-dominant assignment time (2048m tier per T-994 refinement) when zero eligible templates serve the district type post-hard-gate.', 'in_progress', 'medium', NULL, 'server', 'D-232', '2026-05-25 20:36:39', '2026-07-07 17:18:47.876', NULL, '12387d8b75191ae9e2a0ace0b43e2c9d', 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);