diff --git a/server/data/systems.db b/server/data/systems.db index e3ac9f8c3..814a530a9 100644 Binary files a/server/data/systems.db and b/server/data/systems.db differ diff --git a/tooling/economy-db/import_economics.py b/tooling/economy-db/import_economics.py index 2d9ed3979..0c6439514 100755 --- a/tooling/economy-db/import_economics.py +++ b/tooling/economy-db/import_economics.py @@ -2082,12 +2082,10 @@ def populate_trait_templates(conn: sqlite3.Connection, dry_run: bool) -> int: (the table still exists for the downstream pipeline). Deterministic rebuild: clears trait_templates (cascading atlas_body_trait_bias) first. """ - if dry_run: - # Still surface row count that WOULD be baked. - pass - conn.execute("DELETE FROM atlas_body_trait_bias") - conn.execute("DELETE FROM trait_templates") if not ARCHITECTURE_TRAIT_CATALOG_TOML.exists(): + if not dry_run: + conn.execute("DELETE FROM atlas_body_trait_bias") + conn.execute("DELETE FROM trait_templates") return 0 with open(ARCHITECTURE_TRAIT_CATALOG_TOML, "rb") as f: data = tomllib.load(f) @@ -2153,15 +2151,19 @@ def populate_trait_templates(conn: sqlite3.Connection, dry_run: bool) -> int: for e in gerrors: print(f" - {e}") raise _ImportAborted() - conn.executemany( - """INSERT INTO trait_templates - (tag, label, cultural_description, corridor_pool, geographic_sector, - bulk_class_gate, production_ubiquity_gate, min_prosperity_bps, - base_weight, weight_mods, zone_affinity, allow_tags, block_tags, - era_scope, visual_bundle) - VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)""", - rows, - ) + # Validation/guardrails run on dry-run too; only mutate when committing. + if not dry_run: + conn.execute("DELETE FROM atlas_body_trait_bias") + conn.execute("DELETE FROM trait_templates") + conn.executemany( + """INSERT INTO trait_templates + (tag, label, cultural_description, corridor_pool, geographic_sector, + bulk_class_gate, production_ubiquity_gate, min_prosperity_bps, + base_weight, weight_mods, zone_affinity, allow_tags, block_tags, + era_scope, visual_bundle) + VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)""", + rows, + ) return len(rows) @@ -2175,8 +2177,9 @@ def populate_atlas_body_trait_bias(conn: sqlite3.Connection, dry_run: bool) -> i multiplier). Hero-pin *content* is authored in #1017. Absent source -> 0 rows. Must run AFTER populate_trait_templates. """ - conn.execute("DELETE FROM atlas_body_trait_bias") if not ARCHITECTURE_TRAIT_BIAS_TOML.exists(): + if not dry_run: + conn.execute("DELETE FROM atlas_body_trait_bias") return 0 with open(ARCHITECTURE_TRAIT_BIAS_TOML, "rb") as f: data = tomllib.load(f) @@ -2205,18 +2208,22 @@ def populate_atlas_body_trait_bias(conn: sqlite3.Connection, dry_run: bool) -> i errors.append(f"{loc}: boost weight_multiplier_bps must be 10001..30000 (<=3x), got {mult}") if kind == "suppress" and not (mult and 3300 <= mult <= 9999): errors.append(f"{loc}: suppress weight_multiplier_bps must be 3300..9999 (>=0.33x, never 0), got {mult}") + if kind == "pin" and mult is not None: + errors.append(f"{loc}: pin is mandatory and must not carry weight_multiplier_bps (got {mult})") rows.append((bid, tag, kind, mult, b.get("note"))) if errors: print(f" TRAIT BIAS ERRORS ({len(errors)}):") for e in errors: print(f" - {e}") raise _ImportAborted() - conn.executemany( - """INSERT INTO atlas_body_trait_bias - (body_id, template_tag, bias_kind, weight_multiplier_bps, note) - VALUES (?,?,?,?,?)""", - rows, - ) + if not dry_run: + conn.execute("DELETE FROM atlas_body_trait_bias") + conn.executemany( + """INSERT INTO atlas_body_trait_bias + (body_id, template_tag, bias_kind, weight_multiplier_bps, note) + VALUES (?,?,?,?,?)""", + rows, + ) return len(rows)