# First live LLM-played 4E match — glm-5.3 vs Aggressive

The fleet's first game of 4E played by a language model, 2026-08-17 ~14:45Z.
Engine `a7aa2be`+ (phase-b branch), harness per issue #15.

- Player side: **LLM (glm-5.3 via z.ai anthropic route)** — every tactical
  decision made by the model from the enumerated legal candidates.
- Enemy side: Aggressive heuristic.
- Map `test-mm2-ai-combat`, seed 42, maxTurns 50. Result: **capped at 50
  turns, no kills** — consistent with the ~2–5% termination rate at book-true
  math (b7).

## Match record

- 23 LLM decisions, **0 declines, 0 API errors** — the INDEX|RATIONALE
  protocol held first-try on every call.
- Tokens: 8,632 in + 1,979 out ≈ **$0.015** (proxy pricing) — a full
  encounter costs ~1.5 cents of model time.
- Player damage 126 (b7 Aggressive-player baseline: 205 ± 47 — glm-5.3
  landed ~1.7σ below on this single seed; no conclusion from n=1).
- Reasoning quality is real: quotes from the decision log —
  *"Allies are at full health, so healing is wasted; Sacred Flame on the
  Ankheg targets the biggest threat"*; focus-fire on the wounded ankheg
  ("already damaged (39/100)... adds pressure").

Artifacts: `decisions.jsonl` (full candidate set per decision), `match-events.json`
(event log), `analysis.json` (--analyze output), `cost.json` (cost report).

## Reproduce

```
export ZAI_API_TOKEN=...   # from ~/.agents/.credential-zai; never commit
dotnet src/Tactics.CLI/bin/Release/net8.0/Tactics.CLI.dll \
  --map test-mm2-ai-combat --ai Enemy:Aggressive,Player:LLM \
  --llm-backend "anthropic:model=glm-5.3;keyEnv=ZAI_API_TOKEN;maxTokens=200;timeoutSeconds=90" \
  --llm-budget-usd 1 --llm-log decisions.jsonl --llm-cost-report cost.json \
  --seed 42 --timeout 1200 --test-mode --output match.json
```

GLM at temperature 0 has no seed parameter — reruns may differ; the decision
log is the reproducibility artifact (replay mode replays it with zero calls).

## Route findings (engineering, documented for the fleet)

1. **The z.ai edge rejects .NET HttpClient's TLS ClientHello** with a
   misleading `permission_error: "No permission to access model"` — verified:
   byte-identical requests succeed via python and curl, fail via
   SocketsHttpHandler on HTTP/1.1 and 2, with/without User-Agent. The backend
   therefore defaults to `transport=curl` (stock client, key passed via a
   0600 temp config — never argv). Not a spoof: we are genuinely curl.
2. The OpenAI paas/v4 route authenticates but has no inference balance on
   this subscription; the anthropic route is the live path (operator decision).
3. First live attempt (glm-5.3 via dotnet transport) failed 23/23 with the
   403 — and the harness degraded honestly: every decision declined, zero
   silent fallbacks, $0 spent. That failure mode is itself a validation of
   the honest-abort design.

## Next

- LLM batch (phase c): ~$0.75 per 50-seed pairing at measured cost.
- LLM-vs-LLM (phase d): sync with lead on prompt fairness first.
- Replay CLI flag (`--llm-replay <file>`) for offline reproduction of live
  matches — follow-up; replay mechanics are unit-tested today.
