Spaces:
Running
Running
| """One-shot migration: add ``events.mode`` column + index. | |
| W5-A1 (2026-05-26): introduces a 2-mode system for the event lifecycle: | |
| * ``live`` (default) β real LLM, real Arc tx, real RSS, real judges. | |
| * ``mock`` β MockLLM + ``0xsim_*`` tx hashes + canned news + judges short-circuit. | |
| This script applies the schema delta to the local SQLite DB outside the | |
| SQLModel ``create_all`` path because (a) the table already exists with rows | |
| and (b) ``ALTER TABLE`` is the safe non-destructive way to add a | |
| ``NOT NULL`` column with a default. We use the stdlib ``sqlite3`` driver | |
| directly rather than the shell ``sqlite3`` binary because the shell client | |
| has surfaced "malformed file" errors on the WAL-mode DB during the wave3 | |
| debugging session. | |
| The same delta is also applied at backend startup by | |
| ``polyglot_alpha.persistence.db._migrate_events_add_mode`` so fresh checkouts | |
| do not need to run this script β it remains here as documentation + an | |
| operator escape hatch. | |
| Usage:: | |
| python scripts/migrate_add_mode_column.py | |
| Idempotent: re-running is a no-op (the helper checks ``PRAGMA table_info`` | |
| before issuing the ``ALTER TABLE``). | |
| """ | |
| from __future__ import annotations | |
| import os | |
| import sqlite3 | |
| import sys | |
| from pathlib import Path | |
| # Resolve the DB path relative to the repo root so the script works no | |
| # matter where it's invoked from. | |
| _REPO_ROOT = Path(__file__).resolve().parents[1] | |
| _DEFAULT_DB_PATH = _REPO_ROOT / "polyglot_alpha.db" | |
| def main(db_path: Path = _DEFAULT_DB_PATH) -> int: | |
| if not db_path.exists(): | |
| print(f"[migrate] no DB at {db_path} β nothing to do", file=sys.stderr) | |
| return 0 | |
| conn = sqlite3.connect(str(db_path)) | |
| try: | |
| cols = {row[1] for row in conn.execute("PRAGMA table_info(events)").fetchall()} | |
| if "mode" in cols: | |
| print("[migrate] events.mode already present β skipping ALTER") | |
| else: | |
| conn.execute( | |
| "ALTER TABLE events ADD COLUMN mode VARCHAR DEFAULT 'live' NOT NULL" | |
| ) | |
| print("[migrate] added events.mode VARCHAR (default 'live')") | |
| conn.execute("CREATE INDEX IF NOT EXISTS idx_events_mode ON events(mode)") | |
| print("[migrate] ensured idx_events_mode on events(mode)") | |
| conn.commit() | |
| # Verification pass. | |
| cols_after = conn.execute("PRAGMA table_info(events)").fetchall() | |
| mode_col = next((c for c in cols_after if c[1] == "mode"), None) | |
| if mode_col is None: | |
| print("[migrate] ERROR: mode column not visible after ALTER", file=sys.stderr) | |
| return 2 | |
| print(f"[migrate] verified: {mode_col}") | |
| # Show distribution of mode values for confidence. | |
| for row in conn.execute( | |
| "SELECT mode, COUNT(*) FROM events GROUP BY mode" | |
| ).fetchall(): | |
| print(f"[migrate] mode={row[0]!r} -> {row[1]} row(s)") | |
| finally: | |
| conn.close() | |
| return 0 | |
| if __name__ == "__main__": | |
| raise SystemExit(main()) | |