fix(composer): three-state model availability - never brick on unknown keys
The ported availability gate treated "we don't know the key state" the same as "there are no keys": the Word add-in's composer stuck on "No API Key" after one flaky WKWebView preflight, and the web toggle flashed "No API Key" on every page load while the profile was in flight (a render test even asserted the flash). WHAT FAIL-OPEN VS FAIL-CLOSED MEANS HERE The key-status preflight is a UX hint, not the security boundary - the backend authoritatively rejects any model it has no key for (and, since the allowlist commit, any router model outside the user's selection). Failing CLOSED on a hint means one dropped fetch blocks sends the backend would have accepted, with no recovery except reloading the pane. Failing OPEN on an UNKNOWN state costs nothing: the worst case is a request the backend answers with a clear error. So unknown now fails open, while a successfully LOADED status still gates exactly as before - fail-closed is preserved where the information is real. HOW IT WORKS - three states in both clients - loading: neutral, disabled trigger showing the selected model's label (never "No API Key"); submits are not blocked. - loaded: unchanged - filter models by configured providers, show "No API Key" when a real loaded status has none. - failed: retry once with backoff (loadWithRetry in the add-in; an inline retry in UserProfileContext on the web), then console.warn and fail open. The web context exposes `apiKeysDegraded` so ChatInput, TRChatPanel and TabularReviewView pass `undefined` (unknown) instead of the fallback profile's all-false key map to their gates. Tests: composerAvailability.test.ts (add-in isModelAvailable fails open on null, still gates on loaded state; loadWithRetry retries once, reports the final error, resolves null) and ModelToggle.render.test.tsx (loading renders neutral+disabled; unknown-after-failure renders enabled without "No API Key"; loaded no-keys still says "No API Key"). The old test that ENSHRINED the flash (asserting "No API Key" for apiKeys-undefined) is rewritten. Verified pre-fix via stash: 3 tests fail on the ported fail-closed code. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
| Repository | open-legal-products/mike |
|---|---|
| Author | Amal <mamalanand3@gmail.com> |
| Authored | |
| Committed | |
| Parents | 09757c44 |
| Stats | 11 files changed , +321 , -37 |
| Part of | Harden model-router selection and failure handling |
Capture this commit into my fork
Download a Markdown prompt that tells Claude how to port this
exact commit into your working tree. Run it via
claude -p < capture-commit-728c4a9f.md
from inside the repo you want the change in.