"""Transport for the `ledger` domain — args in, delegate, format out.""" from __future__ import annotations from pathlib import Path import typer from tooling.core import cli from tooling.core.command import command app = cli.domain("ledger", "The economics pipeline — the import that builds systems.db.") @app.callback() def _domain() -> None: """Keeps `ledger` a group (Typer collapses a single-command app).""" @app.command("import") @command def import_( db: Path = typer.Option(None, "--db", help="systems.db to import into (default: server/data/systems.db)."), dry_run: bool = typer.Option(False, "--dry-run", help="Validate every step, write nothing."), strict_specialization: bool = typer.Option( False, "--strict-specialization", help="Treat the D-237 completeness gates (V-SES-02, V-FAC-01) as hard errors.", ), ) -> None: """Rebuild systems.db from the economics sources, and stamp it. The sole generator of server/data/systems.db — `make regen-db` runs this. It regenerates generated_brands.toml first (skipped on --dry-run), imports in one transaction, and stamps the meta table so the push gate can tell a stale snapshot from a fresh one. Exit 2 means imported AND stamped but the D-175 coverage gate is not met: a content gap, not a failure, and tolerated by regen-db and the tooling gate. Exit 1 means nothing was written. """ # Imported here, not at module level: the service pulls in the whole # importer package and the stamp registry, and `reach ledger --help` # should not pay for that (T-1260). from tooling.domains.ledger import service service.run(db or service.DB_PATH, dry_run=dry_run, strict_specialization=strict_specialization)