* feat(adapters): map sonnet tier to Claude Sonnet 5; Copilot fable to claude-fable-5
Claude Sonnet 5 is GA (Copilot GA 2026-06-30) and Copilot now serves
Fable 5 natively, so the sonnet/inherit aliases move off Sonnet 4.6 and
the Copilot fable alias no longer falls back to Opus 4.8. Catalog
verification date bumped to 2026-07.
* fix(plugin-eval): judge sonnet tier resolves to claude-sonnet-5
* docs: refresh model alias table and tier counts (Sonnet 5, five-tier, 66/22/52)
* docs(plugins): update model examples to Sonnet 5 / Opus 4.8
Replace claude-sonnet-4-6 with claude-sonnet-5 and Opus 4.7 mentions
with 4.8 in llm-application-dev; replace retired claude-3-5-sonnet in
performance-testing-review's ai-review. Drop temperature args from
migrated examples — Sonnet 5 rejects non-default sampling params.
- judge: guard _measured_score against non-dict JSON; strip whitespace text
before the result fallback (typed result param as Any for ty).
- monte_carlo: use the shared result fallback for activation/quality; sum real
SDK usage token fields via _sdk.usage_total_tokens (no fake total_tokens=0).
- tests: importorskip claude_agent_sdk so dev-only (no llm extra) collection
doesn't fail; add tests for non-dict scores, whitespace/result fallback,
result-only activation, and token summing.
- run-tests.sh: cd guard + multiline-tolerant in-on-String detection.
- docs: cedar-validate if/else, repo-root-safe path, and #598 narrative
corrected to the verified conclusion (reporter essentially correct;
protect-mcp evaluate/sign subcommands absent -> separate issue).
ResultMessage has no .content attribute, so the judge always read empty
text and silently fell back to 0.5. Extract from AssistantMessage TextBlocks
with ResultMessage.result fallback; mark errored/empty/non-JSON as unmeasured.