chore(meta): close T-977 batch — T-992/T-994/T-995/T-1003 + T-977 done (PR #173 merged)

T-959 (Layer 5 Chunk→Tile fill) is now unblocked.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-08 15:57:45 +02:00
co-authored by Claude Fable 5
parent efe4596e58
commit 39313bc854
2 changed files with 48 additions and 0 deletions
@@ -1110,3 +1110,8 @@ 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 ('06FB0TNSRZCG08B0P6PRNQV8KG', 'status', 'in_progress', 'review', NULL, '2026-07-08 08:01:20', '2026-07-08 08:01:20.008', '2026-07-08 08:01:20.008', NULL, '133e5644895f233a0c61a112d54405a5', 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', 'in_progress', 'review', NULL, '2026-07-08 08:01:20', '2026-07-08 08:01:20.008', '2026-07-08 08:01:20.008', NULL, '60ebe4e3cf5bcf3b62aa723e2987d86a', 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', 'in_progress', 'review', NULL, '2026-07-08 08:01:20', '2026-07-08 08:01:20.010', '2026-07-08 08:01:20.010', NULL, '4407b55d5c6ca0c5f9244b9db442bfd2', 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', 'review', 'done', NULL, '2026-07-08 13:57:21', '2026-07-08 13:57:21.371', '2026-07-08 13:57:21.371', NULL, '111bf664d7dc8ac7e9e64568d45b3f5a', 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', 'review', 'done', NULL, '2026-07-08 13:57:21', '2026-07-08 13:57:21.375', '2026-07-08 13:57:21.375', NULL, '9080dd67e697dc8c741913212a38b92d', 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', 'review', 'done', NULL, '2026-07-08 13:57:21', '2026-07-08 13:57:21.375', '2026-07-08 13:57:21.375', NULL, 'c14519c10e49aa58b51649dcc270b207', 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', 'review', 'done', NULL, '2026-07-08 13:57:21', '2026-07-08 13:57:21.375', '2026-07-08 13:57:21.375', NULL, 'c2f0106efbb248444ee8829633830021', 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 ('06FB0TNSRWMZBFV1V6F79VW8S4', 'status', 'backlog', 'done', NULL, '2026-07-08 13:57:27', '2026-07-08 13:57:27.196', '2026-07-08 13:57:27.196', NULL, '8315da7993ab8e37f2e85b04aefc6d78', 2) ON CONFLICT(hash) DO NOTHING;
+43
View File
@@ -1013,3 +1013,46 @@ Refinement (/whats-next 2026-07-07): Blocked by T-994 (edge added) — the swerv
- 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.', 'review', 'medium', NULL, 'server', 'D-232', '2026-05-25 20:36:39', '2026-07-08 08:01:20.010', NULL, '2bfd9945118124da5bcac7c3a16f8c30', 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.', 'done', 'high', NULL, 'server', 'D-232', '2026-05-25 19:11:41', '2026-07-08 13:57:21.366', NULL, '8b15a2a9d07a51002b2acbf662bb228d', 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.', 'done', 'medium', NULL, 'server', 'D-232', '2026-05-25 20:36:39', '2026-07-08 13:57:21.375', NULL, '299ff8e1df1e007b464e990c4a4d40f1', 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).', 'done', 'medium', NULL, 'server', 'D-232', '2026-05-25 19:11:45', '2026-07-08 13:57:21.375', NULL, '9b26e2b199f409ce4b68b905a8da81a4', 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.', 'done', 'medium', NULL, 'server', 'D-232', '2026-05-25 19:11:47', '2026-07-08 13:57:21.375', NULL, 'bba85ea7c4e2b53cb09bf1915a68c5ed', 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 ('06FB0TNSRWMZBFV1V6F79VW8S4', 'story', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Architecture-flavor pipeline — wiki to generator cultural grammar (D-232)', 'Architecture-domain completion of D-167. (a) Gemma architecture-flavor methodology doc: stage-1 register selection + stage-2 structured output {tag, allow:[ObjectTag], block:[ObjectTag], weight, trauma_decay_rate}, analogous to the D-223 naming methodology. (b) trait_templates catalog + atlas_body_trait_bias bake (see round-3 note) (GTTR+index.md). (c) allow/block weighted filter applied at chunk fill over the D-142 zone-type ObjectTag pool (dominant wins categorical; weighted-avg continuous). (d) ObjectTag vocabulary authoring (Miri+Araminta co-maintenance). Three-layer resolution body x district x era-band (era-band depth = Q-106). NOTE: source-authoring location rides on Q-107 (content consolidation); the table+filter are buildable independently. Formally retires D-104/D-105/D-101-axisA/D-107. Flavor stays purely wiki-authored; economics (D-233) is a parallel channel composing only at the filter.
Round 3 (2026-05-25): D-232 rewritten to the TRAIT-TEMPLATE model (not per-body Gemma arrays). Build: (1) trait_templates table = shared holistic catalog (~35 floor / 40-45 target); two-tier eligibility = integer-bps hard gates (bulk_class/prosperity/ubiquity) + weight mods (role/faction/age/corridor/morphology); corridor (geographic_sector) is a WEIGHT, never a gate. (2) atlas_body_trait_bias (sparse, ~30-40 hero bodies: pin/boost/suppress); RETIRE atlas_body_culture + atlas_body_culture_era. (3) Three-phase draw: body vocabulary K-draw (K=5/3/1/0 by complexity_tier, SeedChain D-224, coverage-aware, pin counts toward K) -> district-dominant by zone_affinity (one template/district, applied whole) -> within-template seed picks. (4) Deviation/swerve system + (5) visual fallback hierarchy = separate tasks. CI guardrails (Nigel): eligible pool >=5 post-gate, no template >60pct weight, bias per-body, catalog grows with corpus. Result trait_selection: Vec<String> on skeleton, re-derivable. Channel-separate from D-233 (what vs how). Era = maintenance/wear (D-217), NOT a tech ladder. Source location -> Q-107.
Scope note (2026-05-26): the catalog CONTENT authoring is split out to story #1005 (blocking). 977 is now the MECHANISM only tables, three-phase draw, district-dominant, deviation system, fallback hierarchy. #1005 (the ~35-template content) blocks the draw/fill/visual tasks.
Refinement (2026-05-26): READY behind 1006/1005. Mechanism only. trait_templates + atlas_body_trait_bias DDL into import_economics.py MIGRATION_SQL + systems-schema.sql, integer-bps weights throughout. draw_body_vocabulary() inside the GenerateSkeleton Rayon task: hard-gate filter -> weight (mods x bias) -> SeedChain weighted draw of K (5/3/1/0 by ComplexityTier) -> trait_selection on skeleton; pin counts toward K; coverage-aware (>=1 template per present district type, else sparsity escape-hatch). pick_district_dominant() at the FillChunk head (zone_affinity-weighted). CI guardrails in importer validation (pool>=5, weight<=60pct, bias per-body). Swerve (1003) + fallback (1004) are child tasks. SeedChain complete, no change. Files: import_economics.py, generator.rs.
--- From PR #148 review (Tyre): the trait_templates.geographic_sector column is a pool-narrowing hint for baseline/heritage sub-pools and a SOFT weight (never a gate); it composes with weight_mods.geographic_sector. The draw must join both, not treat the column as a gate. (D-232 corridor = two-part pool.)', 'done', 'high', NULL, 'server', 'D-232', '2026-05-25 19:08:55', '2026-07-08 13:57:27.196', NULL, '1f849322586a58890fdc6985f24ddfb5', 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);