Two model refs that route to the same model on OpenRouter behave very differently on the bill. Point an agent at openrouter/~anthropic/claude-haiku-latest and usage.cacheRead stays 0 on every turn. Point it at openrouter/anthropic/claude-haiku-5.5 and the first turn writes the cache while every later turn reads it. This is openclaw/openclaw#172642.
Nothing errors. The alias run just re-bills the whole prompt each call. Measured on a stable 24k-token prefix, the alias cost 0.0003 per turn - roughly eight times the input cost for the identical conversation.
Why it happens
Anthropic prompt caching is opt-in per request. The client marks the stable prefix with cache_control markers before sending, and that marking is conditional on the model looking like an Anthropic model. The check reads the raw model ID and matches the anthropic/ prefix, so a tilde alias like ~anthropic/claude-haiku-latest classifies as not-Anthropic and no markers are injected. The shared Chat Completions path had the same gap.
The fix
PR #172652 normalises the alias family before classification, so ~anthropic/*-latest refs get the same cache treatment as exact IDs. It needs no configuration change once it reaches your release.
On versions without it, pin the exact model ID instead of the floating alias:
agents:
defaults:
modelPolicy:
allow:
- openrouter/anthropic/claude-haiku-5.5
More generally, if cacheRead never moves across consecutive turns in one session, check your model ref spelling before you go hunting for cache TTLs. An alias form the provider resolves server-side can still be a form your client does not recognise.