---
type: implementation-record
title: "Pokémon TCG AI Battle — Temporal BC Overhaul, 2026-07-29"
description: "Historical implementation record for recurrent TBPTT, FP16 MLX training, Muon/AdamW routing, progress accounting and self-contained PyTorch inference; current runtime is reconciled separately."
tags: [pokemon-tcg, mlx, pytorch, tbptt, fp16, muon, checkpoint]
timestamp: "2026-07-29T01:09:56-03:00"
---

# Pokémon TCG AI Battle — Temporal BC Overhaul, 2026-07-29

## Evidence boundary

This record describes commit `2a57659` in `~/workdir/pokemon-tcg`.
The implementation was validated only with real competition replays through
`configs/smoke.json`. No long training run is part of this workflow.
It is a historical July 29 implementation record. The later source snapshot
enforces strict FP32 for training and PyTorch conversion; see
[[pokemon_tcg_current_state_reconciliation]] and
[[pokemon_tcg_training_pipeline]] before treating the runtime table below as
current.

The preserved baseline checkpoint contains 14 epochs: zero-based `epoch=13`,
`gstep=93,386`, and validation accuracy `0.7419737`. The user reports that an
earlier seven-epoch submission reached roughly 900–930 ladder rating. This
ladder result is user-reported, not a causal comparison.

## Runtime and artifact contract

```text
dataset construction -> Python game engine and encoder
training             -> MLX on Apple Silicon
arena inference      -> PyTorch FP16
```

`configs/train_config.json` and `configs/smoke.json` are transient session
sheets. Neither is included in the submission archive or read by arena
inference. A checkpoint carries:

- resolved training provenance;
- architecture and token-schema versions;
- exact inference settings, including would-KO;
- static card-feature table and card CSV hash;
- model, optimizer, scheduler, epoch, global step, and phase identity;
- dataset manifest and build fingerprint.

The portable PyTorch artifact contains the same runtime contract and a strict
FP16 state dictionary. Old checkpoints without inference metadata
conservatively use `would_ko=false`.

## Temporal unit

The recurrent unit is an engine decision, not an emitted row. A multi-select
decision can expand into several autoregressive labels:

\[
\pi(a_1\mid s),\quad
\pi(a_2\mid s,a_1),\quad
\pi(\mathrm{SUBMIT}\mid s,a_{<k}).
\]

Every row from one decision reads the same incoming recurrent memory. Only the
last substep commits memory to the next engine decision. Memory is isolated by
`(episode_id, side)`.

TBPTT chunks are measured in decisions. Independent episode-side lanes can be
packed up to the configured physical row limit. The limit is dynamic: 128 is
the current smoke value, not an architectural maximum. Validation uses the same
temporal and multi-select semantics and reconstructs logits in original row
order.

## Optimization and precision

| Parameter class | Optimizer |
|---|---|
| hidden two-dimensional Transformer matrices | Muon |
| embeddings, heads, vectors, biases, and remaining parameters | AdamW |

Parameters and forward activations are FP16. Cross entropy, reductions,
accumulated gradients, Muon velocity, and AdamW moments use FP32. Loss is
summed per microbatch and divided exactly once by the real accumulated example
count. Clipping and scheduling advance once per optimizer update.

Optimizer and scheduler state are explicit. `reset` starts a new optimization
phase while retaining model weights; `resume` continues a compatible,
interrupted phase. Daily phases carry a fingerprint of the dataset and session
sheet, and rolling checkpoints carry the same phase identity.

## Progress semantics

The progress plan is derived from the exact temporal batches before an epoch.
It reports real microbatches, optimizer updates after accumulation, scheduler
position, and phase-specific ETA. Training, validation, metrics, checkpoint,
and epoch completion are separate phases. A training bar at 100% therefore
does not claim that validation or checkpointing has finished.

## Real smoke evidence

`configs/smoke.json` built two real episodes from the 2026-07-28 competition
archive:

```text
rows=322
attack_rows=78
would-KO computed options=78
valid zero would-KO options=44
failed would-KO options=0
masked labels=0
```

Two smoke epochs used:

```text
batch_size=128
val_batch_size=128
accum_steps=2
tbptt_chunk=32
microbatches/epoch=3
optimizer_steps/epoch=2
```

Observed peak unified memory was 0.65 GiB. Global step reached 4. The portable
submission loaded `would_ko=true` from its checkpoint without a JSON file and
returned the 60-card deck in an isolated extracted environment.

## Operational boundary

Only smoke runs are authorized during implementation. Increasing smoke epochs
is permitted through `configs/smoke.json`; starting a long/full-corpus training
run is not.

## Related pages

- [[pokemon_tcg_temporal_learning]]
- [[pokemon_tcg_would_ko_prospective_search]]
- [[pokemon_tcg_prospective_v2]]
- [[pokemon_tcg_action_coverage]]
- [[pokemon_tcg_data_pipeline]]
- [[pokemon_tcg_tbptt_training_contract]]
- [[pokemon_tcg_daily_corpus_training]]
- [[pokemon_tcg_ladder_and_research]]
