- Add _export_forge_episode() adapter: translates ForgeEpisode transitions
back into DecisionExporter.record_step() calls so Forge-sourced wins flow
into the distillation JSONL pipeline (closes Phase 1 for real games)
- ppo_consumer() now accepts an optional `exporter: DecisionExporter` arg;
begin_episode / record_step / end_episode are called around each episode
as it is dequeued
- run_forge_pipeline() forwards the exporter kwarg down to ppo_consumer and
calls exporter.flush() after the pipeline completes, returning the output
path in the stats dict under "exporter_file"
- Fix snapshots_to_episode(): compute_terminal_reward() was called with
non-existent kwargs `turns=` and `life_remaining=`; compute_intermediate_reward()
was called with non-existent kwargs `life_delta=`, `cards_drawn=`,
`creatures_played=`. Both now use the correct signatures from reward.py
(prev_state/curr_state/action_taken for intermediate; won/draw/timeout for
terminal). Forge snapshots carry `players` arrays so we reconstruct minimal
prev/curr dicts for the intermediate path.
Ref: docs/CLOSED-LOOP-DISTILLATION.md Phase 1