# Development ## Code map - `facts.py`: pure game-state parsing and arithmetic. - `brain.py`: policy entry point; dispatch, navigation, shops, and minigames. - `policy/combat.py` and `policy/selection.py`: combat and selection proposals. - `policy/context.py`: shared `Decision`, pending actions, and session-owned `PolicyContext`. - `run.py`: observe–decide–act loop, captures, and session attribution. - `run_state.py`: reported run identity and combat-pile provenance; see `docs/RUN_STATE.md`. - `sts2.py`: local game HTTP client. `jev.py`: TypeSafe model client and gates. - `migrate.py`: dataset migration and integrity checks. - `CONTEXT.md`: domain terms. `docs/POLICY.md`: policy boundaries. `docs/DATASET.md`: dataset schema and limits. - `docs/research/11-prototype-hardening.md`: audited findings and the proposed development order. - Treat historical claims in `docs/DESIGN.md` as context; verify against current code. ## Checks Use Python 3.10+ from the repository root. Core Python code uses the standard library. ```sh python3 test_facts.py && python3 test_brain.py && python3 test_run.py python3 migrate.py --check-only bash -n eval_batch.sh ab_card_skip.sh ``` Tests are executable scripts, not unittest/pytest suites. They need no model or game connection. Some checks read local captures and game history when available. Prefer integration/end-to-end checks; keep only essential regression tests and use temporary isolated probes for unit-level edge cases. ## Invariants - Execute one game action, then read a fresh observation. Card indices can change after each action. - Keep policy memory session-owned. Proposals do not record execution; reconcile accepted requests with fresh observations. - Compute arithmetic and legality in code, not in Jev. Confidence does not prove correctness. - Keep deterministic fallbacks usable with `client=None`. Test model paths with stubs. - Preserve session/step attribution. Run outcomes are not per-decision correctness labels. - Split evaluation data by run, not by decision row. ## Safety and scope - Default to offline tests. Ask before live game actions, model calls, or evaluation batches. - `run.py --dry-run` sends no action POSTs; state/identity reads, model calls, and logs still run. - The runner ignores legacy `deck.json`. Combat-pile evidence is session-local and is not the persistent deck. - Never print or commit credentials. Do not read secret files for development checks. - Do not rebuild `dataset/`, change captures, or edit `vendor/` unless the task requires it. - `migrate.py --verify` rebuilds data; use `--check-only` for routine verification. - Keep code simple and lean. Use `docs/` as the detailed reference for humans and agents. - Keep changes focused. Prefer `jj status` and `jj diff`; do not create commits unless asked. ## Pi Project prompts live in `.pi/prompts/`: `/sts2-check` and `/sts2-review`. They provide instructions, not a sandbox or permission enforcement.