Verified against the harness source before locking in:
- agent-loop appends request/header (reason 'change' when the envelope
differs) BEFORE request/context per request, so a model switch is always a
header change — firing the model event only there equals the durable
record, and route/capacity metadata can never double-fire it.
- dsh-llm TokenUsage buckets are disjoint: billed prompt-side =
inputTokens + cacheReadTokens + cacheWriteTokens, outputTokens already
contains reasoningTokens — the fold's prompt/output mapping was already
correct; comments now cite the official semantics.
No behavior change; new assertions cover the switch event (exactly one, from
model-a to model-b), provider-only changes (route update, not a switch), and
the usage mapping (1000 = 800+150+50; output 30).