"""Run the M16 platform invariants against a ModelForge database and report each outcome. Read-only. Used as a standalone operator check, and by the chaos harness before injection, after injection and after recovery, so a scenario can prove it left no invariant broken. python scripts/m16_invariants.py --database-url postgresql+psycopg://... [--json] """ from __future__ import annotations import argparse import json import sys from pathlib import Path from sqlalchemy import create_engine from sqlalchemy.orm import Session sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "backend" / "src")) from modelforge_api.services.invariants import ( # noqa: E402 InvariantStatus, check_invariants, ) from modelforge_api.settings import get_settings # noqa: E402 def main(argv: list[str] | None = None) -> int: parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--database-url", default=None) parser.add_argument("--json", action="store_true", help="emit the full machine-readable report") parser.add_argument("--label", default="invariants", help="label used in the human summary") args = parser.parse_args(argv) url = args.database_url or get_settings().database_url engine = create_engine(url, pool_pre_ping=True) try: with Session(engine) as session: report = check_invariants(session) finally: engine.dispose() if args.json: print(report.model_dump_json(indent=2)) else: print(f"{args.label}: {report.holding}/{report.checked} hold, {report.violated} violated") for item in report.results: mark = "OK " if item.status is InvariantStatus.HOLDS else "FAIL" print(f" {mark} {item.key:38} {item.detail}") for example in item.violations: print(f" - {example}") return 0 if report.ok else 1 if __name__ == "__main__": raise SystemExit(main())