data(content): core architecture-flavor trait-template catalog (#1005)

The D-232 core hand-curated catalog (28 templates) the architecture-flavor
draw reads from, baked into trait_templates (#993):

- Cross-corridor pool (10): economic-function templates gated by BulkClass
  (extraction/industrial/cold-chain/precision/information/civic) + universal
  baselines + the foreign-import swerve. Guarantees the CI floor.
- Per-corridor baseline (8): each corridor's default cohesive look — core
  cosmopolitan, north anglo-frontier, south lusophone, west germanic +
  compact-cooperative, east dense-utilitarian, deep-frontier surname +
  hardscrabble.
- Heritage sub-pools (10): deep-history callbacks tied to the D-237 heritage
  taxonomy (scottish highland, west-african compound, iberian hacienda,
  atlantic creole, nordic timber, central-european blok, east-asian temple,
  vietnamese water village, afrikaans kraal, arab oasis).

Each template = holistic bundle: two-tier eligibility (hard gates
bulk_class/ubiquity/prosperity_bps + soft weight mods), zone_affinity over
the real DistrictType enum, allow/block tags from a shared ObjectTag
palette, and a D-235 visual_bundle with generic fallback parents. All
numerics integer basis-points (D-010).

Adds the D-232 CI guardrails to the baker (V-TT-01: >=5 templates eligible
per BulkClass; V-TT-02: no template >60% of pool weight) — both pass with
margin (23-24 eligible/class, 5% max share). Catalog can grow via the
bounded Gemma pass (#992); hero pins are #1017.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-03 11:04:43 +02:00
co-authored by Claude Opus 4.8
parent a133b6416e
commit 375d04a29d
3 changed files with 458 additions and 58 deletions
+27
View File
@@ -2126,6 +2126,33 @@ def populate_trait_templates(conn: sqlite3.Connection, dry_run: bool) -> int:
for e in errors:
print(f" - {e}")
raise _ImportAborted()
# CI guardrails (D-232, Nigel): >=5 templates eligible per BulkClass (a
# template with no bulk_class_gate is eligible for all); no single template
# may exceed 60% of its eligible pool's base weight. Skipped when the catalog
# is empty (the bootstrap/absent-source case). Integer math (no float).
if templates:
gerrors = []
for bc in ("BulkSolid", "BulkLiquid", "PrecisionDense", "Perishable", "NonPhysical"):
elig = [t for t in templates.values()
if not t.get("bulk_class_gate") or bc in t["bulk_class_gate"]]
if len(elig) < 5:
gerrors.append(
f"V-TT-01: only {len(elig)} template(s) eligible for BulkClass "
f"{bc} (need >=5)"
)
total = sum(int(t.get("base_weight", 10000)) for t in elig)
for t in elig:
w = int(t.get("base_weight", 10000))
if total and w * 5 > total * 3: # w/total > 0.60
gerrors.append(
f"V-TT-02: template '{t.get('label')}' is "
f"{w * 100 // total}% of the {bc} pool weight (>60%)"
)
if gerrors:
print(f" TRAIT TEMPLATE GUARDRAIL FAILURES ({len(gerrors)}):")
for e in gerrors:
print(f" - {e}")
raise _ImportAborted()
conn.executemany(
"""INSERT INTO trait_templates
(tag, label, cultural_description, corridor_pool, geographic_sector,