- V-B06 enum validation: the five VALID_* sets
(VALID_BRAND_CATEGORIES, VALID_VALUE_TRAJECTORIES, VALID_SCARCITY_CLASSES,
VALID_BRAND_TIERS, VALID_CURRENCY_DENOMINATIONS) were defined but never
referenced. brand_products.brand_category etc. are plain TEXT with no
CHECK constraints, so a typo like `brand_category = "terrior"` silently
imported. `validate_brands` now runs a V-B06 pass that asserts every
enum column is a member of its VALID_* set. V-B01..V-B05 + V-B06 all
reported together on import failure.
- Explicit transaction wrapper: the clear-then-reimport cycle (10 DELETEs
followed by 9 imports and structural validation) used to depend on
Python's implicit-deferred-transaction semantics and sys.exit() on
validation failure. A crash mid-import could leave the DB with some
tables empty and others intact. The body now runs inside
`conn.execute("BEGIN")` + try/except with an explicit `_ImportAborted`
for validation failures and a `BaseException` catch-all for
KeyboardInterrupt / programmer errors. All failure paths rollback
before exit; the commit only fires after structural validation
passes. Dry-run leaves the transaction open so the coverage check
below can still SELECT against in-memory state.
- system_fiscal docstring: previously cited the D-189 §6 derived
formula (`collection_efficiency = 1.0 - shadow_economy_intensity × 0.6`)
while the implementation hardcodes `collection_efficiency = 0.85` for
every system. The docstring now explicitly states these are Phase 2
placeholder values (with named constants PHASE2_CORP_TAX_RATE and
PHASE2_COLLECTION_EFFICIENCY) and calls out the shadow_economy.toml
pipeline as the Phase 3 follow-up.
Adds the brand layer per D-189 §5:
- Schema: brand_products, brand_inputs, system_fiscal, corp_financial_state,
corp_lifecycle_events (+ 5 indexes).
- Importer: reads wiki/economics/corporations/brands.toml, populates the
new tables, validates V-B01–V-B05 structural rules, and derives
system_fiscal for inhabited systems.
- Data: 8 brand_products, 16 brand_inputs, 301 system_fiscal rows.
Brand products are demand nodes — they consume commodities; they are not
commodities themselves (D-185). Depends on copy PR #127 for the corp
records referenced by brands.toml.
Add D-180 EconEvent struct (target, effect, duration, visibility enums)
with no-op handler to satisfy #809 spec. Import MARK_PRIMARY and MIXED
currency zone assignments from wiki/economics/currency_zones.toml (D-172).
All four D-179 stability tests now pass.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
import_corp_presence() was inserting system IDs with location_type='system',
violating the schema which expects body/station IDs (location_type='body'|'station').
Fix:
- import_economics.py: add _resolve_hq_location() that picks the most-populated
body in the HQ system (falling back to any body, then any station)
- econ-sim/db.rs: load_corp_presences() now JOINs bodies/stations to recover
system_id from body/station location_ids, dropping the 'system' filter
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Extends import_economics.py from 6-step to 8-step pipeline:
- Loads wiki corporation markdown frontmatter as authoritative source
- Syncs corporations table (hard error on proper_name divergence per D-182)
- Populates corp_presence table (one row per corp × headquarters system)
- Splits validation: structural checks block commit; coverage checks post-commit
- D-175 Phase 2 gate: 3+ corps per commodity, 1+ corp per system with pop > 100K
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add 5 new tables: gate_links (668 bidirectional edges from star-map.json),
commodities (36 types from commodities.toml), production_chains (21
Leontief recipes), chain_inputs (52 input requirements), corp_presence
(empty, populated by future pipeline). Add currency_zone column to
star_systems (D-172), archetype columns to corporations (D-175).
New import pipeline: tooling/economy-db/import_economics.py reads
TOML/JSON source files and populates the DB. Idempotent — safe to
rerun via `make economy-db`.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>