# Issue 22299 — pass 1 proof audit and capture matrix

Read-only source audit of /home/ubuntu/wt/issue-22299, head 2717b5d42104e30d50ad3e448359676e2d9f783b, base 70e5e384da. No PR. No captures, browser work, server launches, tests, or launcher executions performed by this reviewer. Existing real-launcher results and the primary's integrated browser pass are supplied context, not independently verified here. Matrix rows below are capture requirements, not claims of completed proof.

## Scope and source trace

Entire diff: packages/provider-muse/src/server/status.ts and status.test.ts only. Enabled Muse runs --version with makeMuseEnvironment setting MUSE_NO_AUTO_UPDATE=1. Nonzero exit plus stderr containing `muse: installed binary is missing` changes only message; installed=true, status=error, auth=unknown, no SDK host/catalog call. Missing executable, timeout, other nonzero exits, disabled provider, and successful catalog checks retain their previous behavior. Custom model settings can still populate models on an error snapshot; use customModels=[] for the minimal fixture.

Driver checkProvider -> makeManagedServerProvider refresh/settings/startup probe -> identity-stamped provider snapshot -> server configuration provider-status projection -> shared client runtime -> renderers. Refresh is createEnvironmentRpcCommand in packages/client-runtime/src/state/server.ts. Settings refresh and background refresh use the same status path. No contracts, adapter turn behavior, authentication flow, or mobile navigation changes.

Visible paths:
1. apps/web/src/components/settings/providerStatus.ts: installed/error/unknown => headline Unavailable and new detail. ProviderInstanceCard.tsx list mode clamps headline+detail to two lines; editor mode wraps the detail. Both are required, even though wide layouts may show them together. No compatibility warning is needed; such a warning would replace inline detail with compatibility text and move diagnostic to a tooltip. Do not manufacture that unrelated state.
2. ChatView.tsx activeProviderStatus=selectedProviderEntry.snapshot -> ChatBannerLane -> ProviderStatusBanner.tsx. Error/unknown creates error alert; message clamps to three lines, full text in tooltip; dismiss key includes message. Use an existing stopped Muse-selected thread so fallback selection of a ready provider does not hide the banner.
3. ModelPickerContent -> ModelPickerSidebar.tsx: enabled Muse remains visible; error means unavailable/disabled button wrapped in a tooltip trigger span. Tooltip adds provider label and Unavailable prefix to the diagnostic. Hover the wrapper rather than attempting to click the disabled button. On narrow touch, verify an actual supported means to expose this tooltip; do not claim a hover harness proves touch access.
4. Mobile SettingsEnvironmentDetailRouteScreen.tsx: enabled providers only, selectable Text renders unavailableReason ?? message. Seed no unavailableReason so the diagnostic is not masked. Separate React Native renderer, not covered by desktop/web evidence.
5. Excluded: ModelPickerProviderNotices setup message requires hasProviderSetup. Muse snapshot defaults canAuthenticate=false/canInstall=false; enrichment does not change setup. Muse cannot enter that notice. Mobile composer compatibility message is a different field, not this diagnostic. Provider-specific CLI errors for other providers and unrelated entry points do not need duplicate visual fixtures.

## Minimum matrix

Variants: A=1440/light, B=1440/dark, C=390/light, D=390/dark; widths are client content viewport logical pixels. Use consistent height (e.g. 1000 at 1440, 844 at 390) and record actual viewport, OS, renderer and font scale. Every expanded ID is affected and required. Stills must be paired base/head for the same fixture; recordings must identify revision and show settled before/after states. One wide Settings image may satisfy S-L and S-E if both are legible. No interaction row may be replaced by a still.

| Required IDs (each A/B/C/D) | Surface / state | Required capture | Seed | Acceptance |
| --- | --- | --- | --- | --- |
| S-L-A, S-L-B, S-L-C, S-L-D | web + desktop shared Settings provider list, fresh Muse error | still base/head | real app F | Unavailable; longer message clamps cleanly; no horizontal overflow or displaced controls |
| S-E-A, S-E-B, S-E-C, S-E-D | web + desktop shared Settings Muse editor, fresh error | still base/head | real app F | complete host-local setup guidance readable, wrapping/backticks checked, binary path and refresh accessible |
| B-A, B-B, B-C, B-D | web + desktop shared stopped Muse thread, error banner -> full-message tooltip -> dismiss | recording base/head, settled banner frame | real app F + stopped Muse-selected thread; labelled production-component harness only if no safe real thread seed | error styling; three-line clamp; full tooltip text; dismiss removes alert; no agent turn sent |
| P-A, P-B, P-C, P-D | web + desktop shared model picker, unavailable Muse tooltip | recording base/head, settled tooltip frame | real app F; alternate labelled production-component harness | disabled/unavailable Muse; prefixed full diagnostic readable within viewport; desktop pointer access and actual narrow input mode documented |
| M-A, M-B, M-C, M-D | mobile native Environment Settings provider block, fresh error | still base/head | native real app connected to isolated environment F; labelled native component harness if necessary | selectable diagnostic wraps completely, no unavailableReason mask, enabled Muse shown; A/B require actual wide native/tablet viewport or explicit unverified status |
| R-W | web Settings refresh repeat failure -> initialized launcher path -> refresh -> no-models warning | recording, head; 390/dark is minimum representative | real app F then I via isolated provider binary-path setting | pending/disabled refresh state visible; old diagnostic cleared by settled snapshot; warning is not presented as authenticated/ready |
| R-M | native mobile Environment Settings Refresh providers with F then I configured at isolated host | recording, head; 390/dark representative | real native app; change host binary path using authorized isolated Settings | pending refresh then correct fresh error / no-model warning; no stale error after recovery |

20 expanded state/path IDs plus 2 recovery recordings. B/P have recordings in every variant because tooltip placement and clipping are geometry-dependent. Static S/M variants remain stills. Theme/width do not alter backend behavior, so recovery needs one representative per separate client renderer. Navigation into static Settings states does not require an additional recording; if the submission claims navigation/selection behavior, record that claim too.

Desktop collapse: one web-rendered evidence set covers the shared DOM/CSS paths at both widths/themes. This does NOT claim a native Electron-shell run: explicitly mark desktop shell unverified unless the primary already tested it. No Electron IPC is changed. Mobile iOS/Android share this native screen; capture one actual platform and mark the other unverified with reason. A browser rendering RN Web is a labelled harness, never native proof. Do not count a stretched browser viewport as a 1440 native tablet capture.

## Seeding plan for the capturer (proposal only; no file committed)

Reuse already-running isolated server 14328 / web 6288 and its seeded stopped threads. Never launch a server, use live ~/.t3/userdata, copy credentials, or start an agent turn. Record actual origin and revision; existing server ports alone do not establish which source revision was served.

F: enable an isolated Muse provider instance, customModels=[], binaryPath=/tmp/issue-22299-repro/data/installs/http-muse/1.4.11-R6667.1/muse. Use existing Settings controls and Refresh provider status. This fresh real Muse launcher is reported to reproduce; preserve it uninitialized. Capture base's generic message and head's actionable message with the same fixture. Keep automatic provider update operations out of the sequence. No credentials needed.

I: change that isolated instance's binaryPath to /tmp/issue-22299-initialized/muse and refresh. This launcher is reported to succeed at --version and return no models without credentials; expected status=warning with existing `Muse Code returned no models...` text. Switching F->I is deterministic recovery simulation, not proof that the suggested command initializes F. If claiming the command itself repairs setup, use a disposable copy of the fresh installation preserving its launcher directory layout and record its --version execution plus refresh; never initialize the canonical F fixture.

Suggested smallest committable fixture helper, if real thread seeding is impractical: add a development/browser-test fixture module that invokes the production Settings card list/editor, ProviderStatusBanner, and ModelPickerSidebar with one identity-stamped ServerProvider snapshot obtained from the real checkMuseProviderStatus F probe. Set enabled=true/installed=true/status=error/auth=unknown/customModels=[], no compatibility advisory, no update in progress, no unavailableReason. Swap only base/head diagnostic; use real themes and production wrappers. Label every output `component harness — injected provider snapshot; no server integration`. Banner parent must implement production dismissal-key behavior. Tooltip must use production provider and delays. Native harness must mount actual native Settings screen/provider block, not an HTML imitation. Do not add in-app setup flags to make unreachable notices appear.

## Backend proof requirements and audit observations

Required nonvisual proof: red test at base / green at head for added fresh-launcher case; targeted provider status suite; runtime transcript of F --version with MUSE_NO_AUTO_UPDATE=1 showing nonzero exit and recognized stderr, and I succeeding under the same probe environment. Primary/capturer owns execution; none run here. Avoid raw environment dumps or credentials. Verify snapshot=installed/error/unknown and SDK host not called. Existing generic nonzero stderr-redaction test must stay green.

Test addition catches the intended regression and verifies host is not started, but only asserts substrings `muse --version` and `exit code 1`; it does not assert host-local instruction, refresh guidance, generic fallback exact text, absence of unrelated stderr in a matching-error payload, or full message. A focused assertion of actionable guidance is a useful improvement, not a UI matrix substitute.

Low-risk edge: matcher accepts the known stderr substring at any nonzero exit but message hardcodes exit code 1. If actual supported launchers can emit the marker with another code, message is inaccurate; either constrain matching to code 1, interpolate actual code, or establish that launcher invariant. Current provided real reproduction is code 1, so no demonstrated blocker from this edge. The message says literal `muse --version` even for custom binary paths, as existing host-local guidance does; a non-PATH custom installation needs its configured absolute command. Check that nuance before claiming universal recovery guidance.

## Verification status / friction

Source trace completed; worktree had no reported changes. No platform capture independently verified. Primary reportedly already owns/completed the one integrated browser pass; this audit does not request or launch a second pass. Native mobile and Electron shell remain unverified because this was expressly a read-only, no-capture review. 1440 native mobile requires a tablet/wide native viewport; if unavailable, keep M-A/M-B explicitly missing, not silently covered by web. Narrow touch tooltip access needs real-device evidence or an explicit limitation. Upload contains only authored audit text and local fixture paths, no tokens or user data.
