"""Per-turn orchestration trace (Open-Trace bonus). Enable by setting VN_TRACE=runs/.jsonl. Each line records the player input, the assembled context, the raw directive output, applied effects, and the painter prompts/seeds — clean and shareable as a Hub dataset because the state is structured. """ from __future__ import annotations import json import time from pathlib import Path from typing import Any class Tracer: def __init__(self, path: str | None) -> None: self.path = Path(path) if path else None if self.path: self.path.parent.mkdir(parents=True, exist_ok=True) def log(self, **record: Any) -> None: if not self.path: return record["ts"] = time.time() with self.path.open("a", encoding="utf-8") as f: f.write(json.dumps(record, ensure_ascii=False, default=str) + "\n")