Honest read-failure states and MCP scope-note correction - #753
Merged
Conversation
…ggle The note above the write toggle claimed tokens are read-only in every case, which the toggle directly below it contradicts by minting a read_write scope. Rewrite it to state the real model: read-only by default, write opt-in per token, never admin. Resolve the pronoun that read as a formal address, and promote both scope notes to foreground so this security copy no longer renders as muted meta.
The central-codex and auto-read consent notes are safety copy the user has to read before enabling a data-sharing path, but both rendered as muted extra-small meta. Promote them to foreground text-sm and keep only the decorative icon muted.
The respiratory-rate tile hard-coded the English unit while the metric sub-page already reads the localized string. Point the tile at the same key so every locale shows its own unit.
…or classes Three small copy corrections that share the locale bundles: - Resolve the formal-address outliers on the owner sharing and report scopes to the informal register the rest of those surfaces use. - Add the direct-address comma to the personalized dashboard greeting. - Split the managed-record form error: a client-side validation failure no longer surfaces as a network error, and a failed save gets its own line.
…ty state The share-link query had no error or loading handling, so a failed read collapsed to an empty list and rendered the "no active share links" copy — on a clinical sharing surface a load failure was indistinguishable from "you have shared nothing". Gate the list on the query state: QueryErrorCard with retry on failure, a skeleton while loading, the lists only once the data is in. The added test was watched fail first against the old fall-through before this fix made it pass.
…y state Same fall-through as the share-link list on another security surface: the token query had no error or loading branch, so a failed read rendered "no active tokens". Gate the list on the query state with QueryErrorCard and retry, a skeleton while loading. Test watched fail first against the old empty-state fall-through.
…ty states The connected-assistants and connector-token queries had no error or loading branch, so a failed read rendered "no connected assistants" or "no active tokens" on this security surface. Gate both lists with QueryErrorCard and retry, a skeleton while loading. Test watched fail first against the old empty-state fall-through.
…y state The tile already read the query's error flag but never branched on it, so a failed reminder read fell through to "no upcoming checkup reminders" — a missed preventive-care nudge hiding behind an honest-looking empty state. Add a QueryErrorRow with retry before the empty check. Test watched fail first against the fall-through.
… form The three AI configuration reads each returned null on a non-OK response, so a failed read painted the default provider form as if the account were configured that way. Throw on a non-OK response so the query reports its error, and render a QueryErrorCard with retry when any read fails. Test watched the misleading form render first, then pass on the honest error.
The ECG detail rendered a read failure as a muted, non-recoverable line; the routed list page had no error branch at all, leaving the shell heading over an empty body that read the same as loading. The detail now paints a QueryErrorCard with retry (an alert is content, not muted meta), and the page shows the same instead of an empty shell. The overview teaser still unmounts silently, which is right for the overview. Tests watched each fail first.
…degradation The mood-insights regions returned nothing on a failed read by documented intent, degrading to the line chart. Enforce the honest-error standard here too: on error the main region paints a QueryErrorRow with retry, once, mirroring how the loading skeleton is scoped to that one region so the three regions do not stack identical rows. Test watched the silent empty first.
The cycle tabs rendered a bespoke error row in muted text, wrapped in a bare card. Replace it with the shared primitives: QueryErrorCard on the standalone prediction/insights/settings tabs, and a borderless QueryErrorRow inside the calendar card so the failure reads as foreground content with retry rather than muted meta. Test watched the muted row first.
A family of settings surfaces rendered a failed read as a bare text-destructive line with no way to recover: the security sessions, trusted-devices and activity cards, the coach memory and reminders sections, the about-me section, and the document link/share pickers. Swap each to the shared QueryErrorRow primitive with a retry control. The suite covering the statically renderable members was watched fail first against the bare lines; the two portaled pickers take the same swap.
The section carried a bespoke muted error row with its own retry button — the exact drift QueryErrorRow was made to absorb. Swap it for the shared primitive so the failure reads as foreground content. Test watched the bespoke row first.
…itive Eight admin surfaces rendered a failed read as their own destructive- tinted box, and most offered no way to recover. Sweep them onto the shared QueryErrorRow with retry so the console uses one error form (§13). The statically renderable sections were watched fail first against the hand-rolled boxes.
Adding recoverable read-failure handling to thirteen surfaces and the MCP and managed-record copy rewrites across six locales lifts the whole-build client total to 3404 KB gz. Every per-route ceiling is still met; the aggregate cap moves 3352 to 3428 with the same margin.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The first charge from the app-wide UI and copy audit: honest read-failure states and two security-copy corrections.
Two things that read as false before:
The MCP settings note claimed tokens are read-only in every case, printed directly above the toggle that mints a write token. It now describes the real model: read by default, write opt-in per token, and never admin. Six locales, and the pronoun that read as a formal address is resolved.
The share-link list rendered "no active share links" when the read failed, so on the clinic-sharing surface a failure was indistinguishable from having shared nothing. It shows an honest error with retry now.
The same read-fails-as-empty pattern is fixed across the app: the API and MCP token lists, the AI settings screen (which had been swallowing three reads and painting a default form), the Vorsorge dashboard tile, the ECG detail and list, the mood insights, the cycle view, the destructive-action settings cards, the document and share pickers, and the eight admin error boxes. Each now shows a recoverable error instead of an empty frame, and each carries a component test that fails if the empty state ever comes back.
Full detail in the CHANGELOG.