Covers:
- health endpoint returns {ready, status, model_loaded}
- precomputed fast path: state_vector float[29] → vector_source=precomputed
- correct 6177-dim tensor shape reaches the mock model
- all 8 MacroAction values are valid responses
- encoder fallback: missing state_vector → vector_source=encoder
- encoder fallback: wrong-length state_vector → vector_source=encoder
- GameSession field name aliases (turnNumber, activePlayer,
commanderTax, handCount, commandZone) are accepted without 422
- 503 when model not loaded
- /api/policy/stats tracks precomputed_vector_hits vs encoder_fallbacks
- both phase strings (MAIN1, main_1) round-trip correctly
Uses a MockPolicyInferenceService that captures the tensor shape passed
to the model so we can assert on dim without needing a real checkpoint.