"""Phase 0 (SPEC §12) — prove mapping quality before any art or UI. Runs Agent 1 (the Deck Designer) against the open ≤32B model for several varied themes and prints each deck as a readable archetype→concept table plus the full JSON. Inspect by hand: do the mappings read as clever-but-right across all themes? If not, fix the prompt/few-shots before building anything else. Usage: set -a; source ~/tokens; set +a python -m scripts.phase0_mapping # default 5 themes python -m scripts.phase0_mapping "free jazz" "tax law" """ from __future__ import annotations import json import os import sys import time from arcana.archetypes import MAJOR_ARCANA from arcana.designer import DeckError, design_deck from arcana.llm import get_llm DEFAULT_THEMES = [ "thermodynamics", # serious / scientific "Lord of the Rings", # fandom "the French Revolution", # history "breakfast foods", # silly "professional wrestling", # pop-culture wildcard ] OUT_DIR = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "phase0_out") def print_table(deck: dict) -> None: print(f"\n style: {deck['style_suffix']}") for a in MAJOR_ARCANA: c = deck["cards"][a.number] print(f" {a.roman:<5} {a.name:<18} → {c['concept']}") print(f" ↳ {c['justification']}") def main(themes: list[str]) -> int: os.makedirs(OUT_DIR, exist_ok=True) llm = get_llm() print(f"Model: {getattr(llm, 'model', '?')} via {getattr(llm, 'base_url', '?')}") failures = 0 for theme in themes: print("\n" + "=" * 72) print(f"THEME: {theme}") print("=" * 72) t0 = time.time() try: deck = design_deck(theme, llm=llm) except DeckError as e: failures += 1 print(f" ✗ FAILED: {e} ({time.time() - t0:.1f}s)") continue dt = time.time() - t0 print_table(deck) slug = "".join(ch if ch.isalnum() else "_" for ch in theme.lower())[:40] path = os.path.join(OUT_DIR, f"{slug}.json") with open(path, "w") as f: json.dump(deck, f, indent=2, ensure_ascii=False) print(f"\n ✓ 22 cards in {dt:.1f}s → {path}") print("\n" + "=" * 72) print(f"DONE — {len(themes) - failures}/{len(themes)} decks generated.") print("Inspect the tables above: do the mappings feel clever-but-right?") return 1 if failures else 0 if __name__ == "__main__": args = sys.argv[1:] or DEFAULT_THEMES raise SystemExit(main(args))