# Proof audit, pass 1 — Grok Privacy Mode guidance

PR [#28097](https://git.cafe/pingdotgg/t3code/pull/28097), branch `fix/issue-28094`, reviewed head [8d1ec13](https://github.com/pingdotgg/t3code/commit/8d1ec13ca126532d1ec083f62e15985f756a2bb8), against merge-base [eef35b0](https://github.com/pingdotgg/t3code/commit/eef35b0262f24e83ef09cd4d2a59b4baed1c2581). Pass 1 has no visual captures. Read-only checkout: `/home/ubuntu/wt/pr-28097`.

## Findings first

1. **Evidence gate remains open.** The new backend message has five distinct renderer families: web/desktop pooled Limits warning, web/desktop composer banner, web/desktop thread-details tooltip, native pooled Limits warning, and native composer account card. A backend transcript establishes the data, not their readability or reachability. Capture rows W0–W5, M1–M4, and R1 below.
2. **The PR's shared-render-path claim is correct, with an important qualification.** `limitsNotice` returns `unavailable.message` for `probeFailed`. Pooled Limits excludes these accounts from bars and appends their messages to a warning. Thread details shows only “Limits / Unavailable” until its tooltip opens. The Usage row is off by default. A capture of a healthy Grok pool, a settings provider card, a generic “Unavailable” label, or an unopened tooltip does not prove this change.
3. **A real dev server can exercise the changed branch without xAI or real credentials. Verified here.** With `T3CODE_DEV_SEED=0`, an explicit scratch T3 home, fake HOME/GROK_HOME, a synthetic account, a fake Grok CLI, and a process-local fetch preload, the unedited server published `grok`, installed/authenticated/ready, with `windows: []`, `unavailable.reason: "probeFailed"`, and exactly “Switch your xAI account to Privacy Mode to show Grok usage limits.”
4. **Two suggested shortcuts do not work.** The billing URL is a literal. `GROK_CLI_CHAT_PROXY_BASE_URL` is an unsupported-custom-deployment guard, not a redirect for this reader. Startup reads `caches/grok.json` but its hydration drops `usageLimits`; writing that message into the cache cannot seed the client state.
5. **Start from an unreadable/fresh account.** A successful prior probe for the same account survives a subsequent `probeFailed`, including this new failure. A usable duplicate login also wins when composer reports deduplicate. Expect recovery from privacy failure to success; do not expect a later privacy failure to replace already published healthy limits in the same server process.

No implementation defect was established in this proof-focused pass. The lack of captures blocks proof approval.

## Fixture data and capture conventions

- **P:** native Grok provider, enabled, installed, available (`status: ready` in the seed), authenticated cached-token auth; `auth.label: "Grok account"`; synthetic email `fixture0@example.test`; display name `Grok`; limits `{checkedAt: <current ISO time>, windows: [], unavailable: {reason: "probeFailed", message: "Switch your xAI account to Privacy Mode to show Grok usage limits."}}`.
- **G:** same provider/account shape, but a fresh generic failure, message `Grok could not read usage limits.`. Trigger with a 403 JSON `error` without the marker. This is the before-equivalent diagnostic; an actual before capture must be labeled with the base revision, not represented as a base capture if taken at head.
- **S:** another distinct Grok account with a 200 body `{config: {creditUsagePercent: 27, currentPeriod: {type: "USAGE_PERIOD_TYPE_WEEKLY", end: "2099-11-08T00:00:00Z"}}}`. It produces one Weekly window, 73% left. No reset credit or external link.
- **Mixed:** five native Grok instances with five different synthetic emails: 3 P, 1 S, 1 G. Long display names `Grok account with a deliberately long synthetic display name N`. The fresh `mixed` generator supplies these. This is not “five pooled failed accounts”: only S has a pool; the failures form warning lines on Limits and separate account entries in the composer.
- **Multi-environment:** a second isolated server with a different explicit T3 home; connect both to the same client; use long synthetic labels, e.g. `Synthetic development environment with a long label A/B`. Selecting both makes `collectLimitNotices` prefix environment labels. A single server with five instances cannot prove that prefix branch.
- **Web sizes:** wide 1440×1000 CSS px; narrow 390×844 CSS px. **Native sizes:** iOS phone 393×852 logical points; Android phone 412×915 dp (use the device's actual equivalent and report it). Native wide controls change at content width 600; 834×1194 is a tablet representative if that surrounding layout needs separate evidence.
- Minimums use representative width/theme pairs, not a factorial expansion: there is no new theme or breakpoint code. W1/W2 and M1/M2 cover light/dark and short/long content per pooled renderer; W3/W4 and M3/M4 do the same for each composer renderer. Existing custom palettes and platform shell chrome do not create another new message branch.
- A **recording** must show the relevant action, the new text legibly, and its result. A still extracted from it is useful but cannot replace it. Entering an ordinary route to capture its settled state does not by itself turn a static row into an interaction fixture.
- Every capture must identify revision, client/platform, size, theme, fixture ID, and whether real app or harness. Do not show pairing tokens, real paths/account data, or real credentials.

## Row table

| ID / named fixture | Diff affected? | Distinct state / expected visible result | Seed and real-app entry | Minimum viewport × theme × row; medium | Pass-1 status |
| --- | --- | --- | --- | --- | --- |
| W0 — original generic guidance | Baseline | P's same account at the base revision renders G's short generic text in the Limits warning. | Use the same synthetic 403-with-marker stub against the base revision in the lead's authorized baseline checkout. Route `/usage`, select Limits. A head run with stub mode `generic` is a clearly labeled **before-equivalent**, not an actual base capture. | Web 1440×1000 light + 390×844 dark; **stills**, paired with W1. | **NEEDS CAPTURE**; no before image exists. |
| W1 — one privacy failure, standalone warning | Yes | Full new sentence, prefixed `Grok:`; no Grok bar; warning present even with zero healthy pools; no raw xAI text, WKE marker, reset button, or Manage usage link. | Fresh `single` seed; `/usage` → Limits. Grok visible, environment selected. Web sidebar, Settings usage entry, command palette “Open usage”, and `usage.open` (`mod+u`) converge on this route; web/desktop use the same React renderer. | Web 1440×1000 light + 390×844 dark; **stills**, paired with W0. | **NEEDS CAPTURE**; real server seed verified. |
| W2 — mixed accounts, long prefixes, filtering | Yes, warning text | One healthy weekly Grok pool plus 3 privacy lines and 1 generic line; with two selected environments, each warning has its environment prefix. Long unbroken labels/message wrap without clipping. Hiding Grok/removing its environment removes its warning; showing/reselecting restores it. | Fresh `mixed` seed, second isolated server for the environment-prefix branch; `/usage` → Limits. Change provider visibility and environment selection through the actual menus; scroll if needed. | Web 390×844 light + 1440×1000 dark; **recording** of prefix/filter/scroll states. | **NEEDS RECORDING**; second environment not started in this pass. |
| W3 — single-account composer command | Yes | “Usage limits” banner with single-account summary (`Grok · Grok account`) and full new sentence; no duplicate account heading in its body. Command is intercepted locally, not sent to Grok. Dismiss then reopen works. | `single`; create/select an isolated project/thread or draft using Grok; no attachments. Submit exact `/usage-limits`, and exercise slash-menu selection of `usage-limits`. These are two callers of the same opening function. | Web 1440×1000 light + 390×844 dark; **recording** of both entries, dismiss/reopen. | **NEEDS RECORDING**. |
| W4 — multi-account composer, overflow and label details | Yes | Banner summary becomes “5 accounts”; each body row gains its account summary. 3 long privacy messages coexist with S's bar and G's short failure. All rows remain reachable in the bounded scroller. Long summary can truncate / expose notice details; an `@` display name uses redaction. | `mixed`, selected Grok thread/draft; `/usage-limits`. For the redaction substate, set one **synthetic** display name to `fixture-label@example.test` in this run's settings, then use reveal/hide. Scroll to bottom; use header details if responsive overflow exposes it; dismiss/reopen. | Web 390×844 light + 1440×1000 dark; **recording** of scrolling, visible summary/details branch and synthetic-label reveal/hide. | **NEEDS RECORDING**. |
| W5 — thread-details unavailable tooltip, inline and popup | Yes, tooltip text only | Resting row says `Limits` / `Unavailable`; hovering or focusing the whole row reveals the complete new message. Tooltip fits the viewport. The shared row is the same in full/compact/essential card density. | `single`, Grok thread/draft. Open Thread details; its context menu → enable **Usage limits** (`threadDetailsItems.usage=true`; legacy `threadDetailsUsageEnabled=true` also defaults it on). Wide canvas can place it inline; narrow canvas uses a popover. Record pointer hover **and** keyboard focus/blur; close the popup. | Web 1440×1000 light (inline) + 390×844 dark (popover); **recording**. Verify actual `data-thread-details-panel` mode; width alone is not proof of mode. | **NEEDS RECORDING**; default-off setting identified. |
| M1 — native single privacy warning | Yes | Native warning contains `Grok:` and the full new sentence, wrapping naturally; no failed-account pool/bar. | Pair native client to fresh `single` environment; Settings → Usage (`SettingsUsage`, link path `settings/usage`) → Limits. Mobile command-palette “Usage” and workspace Usage screen also render `UsageScreen`. Default tab is Limits unless `tab=usage`. | iOS phone light + Android phone dark; **stills**. | **NEEDS CAPTURE**; no device/browser launched. |
| M2 — native mixed warning and environments | Yes, privacy text | Mixed pool + warning lines; multi-environment prefix appears. Filter selection removes/restores correct lines. A successful RPC containing this 403's `probeFailed` must not be confused with the separate “could not refresh limits” RPC-failure notice. | `mixed` + second environment; actual native environment menu and pull-to-refresh. No hub or external real server required. The unrelated failed-RPC branch is inventoried below and does not add a capture requirement. | iOS phone dark + Android phone light; **recording** of filtering/refresh. A tablet 834×1194 may replace one environment-filter segment to show `wide>=600`; warning JSX itself does not branch on `wide`. | **NEEDS RECORDING**; unrelated RPC-failure state excluded from minimum. |
| M3 — native single composer, keyboard and close | Yes | Dense account card with Grok label, `Grok account` detail, full sentence and first-card close button. It opens above composer, reserves keyboard space, closes and reopens without losing the message. | `single`, Grok thread/draft; no attachments. Exact `/usage-limits` send and slash-menu selection. Show keyboard present/hidden; dismiss/reopen. | iOS phone light + Android phone dark; **recording**. | **NEEDS RECORDING**. |
| M4 — native multi composer, first/next cards and scroll | Yes | 5 account cards; first alone has close; later cards have separators. Long labels truncate independently of the wrapping privacy sentence; S shows a bar, G a generic notice. All accounts are reachable within computed `maxHeight`; keyboard does not cover last entry. | `mixed`; open exact `/usage-limits` and scroll to last account with keyboard visible, then hide keyboard. Synthetic `@` instance label supports reveal/hide; dismiss using first card. | iOS phone dark + Android phone light; **recording**. | **NEEDS RECORDING**. |
| R1 — recovery, later failure and live updates | Yes for outgoing privacy message; retention is existing | Fresh P warning → change stub to success → explicit refresh → Weekly 73% appears and privacy guidance disappears, including open composer/details consumers. Change back to privacy and refresh: previously successful same-account windows remain. Restart the isolated server fresh with privacy to show message again. No wall-clock reset countdown proof is needed for `windows:[]`. | Edit scratch `modes.json` (`fixture-0`: `privacy` → `success` → `privacy`); real Usage Refresh calls `server.refreshProviders` with `{}`. Native pull-to-refresh uses the same RPC. Opened panels derive fresh provider data. Await observed response/UI milestones, not a long sleep or auto-refresh. | Web 1440×1000 dark + one native phone light; **recording**. Can extend W3/M3 clips instead of creating redundant clips. | **NEEDS RECORDING**; retention source traced; only initial P runtime verified here. |
| C1 — generic/non-marker/invalid error equivalence | No additional layout | Other 403 error, malformed/non-JSON 403, non-string/missing `error`, marker on non-403, network/timeout → G. Blank/no credentials or guarded deployment → unsupported or generic as described in source, never P. | Stub/reader test; mode `generic` supplies the representative G. Inspect existing reader tests for hidden upstream text; do not generate a new UI capture for every equivalent error body. | G is covered by W0 and Mixed; protocol-only cases need no extra capture. | **SOURCE VERIFIED / no additional visual row**. |
| C2 — missing/loading/empty/hidden/unsupported | No | Before provider snapshot, no new text. Disabled/uninstalled/unavailable/filtered providers are absent from collection. `unsupported` is skipped by pooled notices; direct composer/details can show its existing fallback. Empty successful 200 → “No limits reported.” Missing limits → details absent. No environments → route empty state, not a privacy warning. | Disable Grok / deselect environment / switch stub to `empty` (fresh process if healthy limits were published). Existing route/visibility behavior. | Covered by W2/M2 filter transitions plus source; no separate stills. | **SOURCE VERIFIED / no additional visual row**. |
| C3 — duplicate same-login and retained success | No visible new text when suppressed | Composer dedup prefers any usable same-email account over failed duplicate; Limits still collects notices for failed providers independently. Managed provider keeps previous same-account healthy windows on failure. Different known account identity drops old limits. | Use same synthetic email for two instances, one S and one P; or R1 for retention. Normalize emails case-insensitively. No real account needed. | Retention covered by R1; duplicate priority is shared-logic control, no extra UI matrix expansion. | **SOURCE VERIFIED / no additional visual row**. |
| C4 — absent features and other clients | No separate changed branch | P carries no externalUsage/resetCredits, so Manage usage and redemption are absent. No populated windows, exhausted-bar/pace/reset countdown combinations arise from P. Grok is not among the widget's Codex/Claude entries. Desktop wraps web renderers; no separate Electron notice implementation. No native thread-details usage tooltip exists in this path. | Source inspection. CLI Proxy reader supports Codex/Claude accounts, so it cannot add a Grok reset-credit footer to P through normal source collection. Local/remote/tunnel carry the same typed provider snapshot; stub the **server**, not browser fetch. | No independent capture required; do not substitute these surfaces for affected ones. | **SOURCE VERIFIED / not affected**. |

## Render-path inventory and conditional boundaries

**Changed producer:** [usageLimits.ts](https://github.com/pingdotgg/t3code/blob/8d1ec13ca126532d1ec083f62e15985f756a2bb8/packages/provider-grok/src/server/usageLimits.ts#L161). Only status 403 + decodable `{error:string}` containing literal `WKE=privacy-mode:` produces P. Token/email, installed/authenticated/enabled gates are outside that changed branch. Output has current `checkedAt`, zero windows, fixed probeFailed message. No new control/link/action is introduced.

**Server propagation:** [GrokDriver.create](https://github.com/pingdotgg/t3code/blob/8d1ec13ca126532d1ec083f62e15985f756a2bb8/packages/provider-grok/src/server/driver.ts#L171) calls `readGrokAccount(processEnv)` only after a successful installed/authenticated/enabled status check. Its managed snapshot preserves healthy same-account limits across failed probes; `refreshUsage` allows probeFailed and excludes unsupported ([managedProvider.ts](https://github.com/pingdotgg/t3code/blob/8d1ec13ca126532d1ec083f62e15985f756a2bb8/packages/provider-core/src/server/managedProvider.ts#L145)). Registry/WebSocket config publishes that snapshot to local and remote clients. No provider settings-card renderer consumes this specific message directly.

**Shared projection:** [limitsNotice](https://github.com/pingdotgg/t3code/blob/8d1ec13ca126532d1ec083f62e15985f756a2bb8/packages/shared/src/usageLimits.ts#L605) branches unsupported / probeFailed / empty windows / usable. [collectLimitAccounts](https://github.com/pingdotgg/t3code/blob/8d1ec13ca126532d1ec083f62e15985f756a2bb8/packages/shared/src/usageLimits.ts#L254) excludes notice accounts from pools. [collectLimitNotices](https://github.com/pingdotgg/t3code/blob/8d1ec13ca126532d1ec083f62e15985f756a2bb8/packages/shared/src/usageLimits.ts#L380) filters enabled+installed+available providers; prefixes trimmed displayName or driver, plus environment label iff selected presentation count >1; preserves multiple notice lines; skips unsupported. Source errors/no accounts append distinct notices. [collectProviderUsageLimits](https://github.com/pingdotgg/t3code/blob/8d1ec13ca126532d1ec083f62e15985f756a2bb8/packages/shared/src/usageLimits.ts#L741) includes failed native accounts, limits to selected driver's accounts, deduplicates same-login identities preferring usable data then freshness, and reports source notices separately.

**Web/desktop pooled:** `UsagePage` at `/usage` calls `UsageLimitsSection` only with selected environments and Limits metric; provider/environment filters shape presentations. [UsageLimitsPooled](https://github.com/pingdotgg/t3code/blob/8d1ec13ca126532d1ec083f62e15985f756a2bb8/apps/web/src/components/usage/UsageLimitsPooled.tsx#L605) has empty / pools / cursor prompt / external-links / notices branches. [LimitNotices](https://github.com/pingdotgg/t3code/blob/8d1ec13ca126532d1ec083f62e15985f756a2bb8/apps/web/src/components/usage/UsageLimitsPooled.tsx#L691) returns null on zero notices; otherwise one warning Alert with icon aligned to first line, one break-words title per notice, flexible min-width-zero content. P supplies only the notice branch. Healthy pool count, bar segmentation, exhaustion, reset credits, hover popovers, pace, and Cursor-specific layouts are independent and unchanged; Mixed covers coexistence rather than their full matrix.

**Web/desktop composer:** `ChatView` → `useUsageLimitsPanel` → [usageLimitsBannerItem / UsageLimitsBannerBody](https://github.com/pingdotgg/t3code/blob/8d1ec13ca126532d1ec083f62e15985f756a2bb8/apps/web/src/components/chat/ComposerUsageLimits.tsx#L47). Exact prompt send (`useComposerSend`) and slash-menu selection (`ChatComposer`) share opening. Guards include selected provider coverage, valid panel key, and no attachments; missing report gives a toast. Single vs multi accounts changes header/body labels; plan appends summary text; custom display name/instance ID/driver fallback changes label length; `@` labels use `RedactedSensitiveText`; source entries have source labels. The body substitutes notice text for `LimitWindows`, with optional external link and credits (absent for P), then source notices. `ComposerBannerStack` can attach or detach the same body, stack with other banners, fade on mount, truncate/suppress header summary at container width <=400, expose header-detail popover on overflow, and cap body scrolling to min(24rem,40dvh). Detached/attached placement does not change P's text implementation; one ordinary attached run is the minimum. Dismiss, send, thread/model/run/pending-request changes clear or invalidate the panel; source code supplies those existing reverse paths.

**Web/desktop thread details:** `ChatView` → `ThreadDetailsPanel` (`visible.usage`) → [ThreadDetailsUsage](https://github.com/pingdotgg/t3code/blob/8d1ec13ca126532d1ec083f62e15985f756a2bb8/apps/web/src/components/chat/ThreadDetailsUsage.tsx#L42). Selected instance's report entry is used, with its own snapshot fallback, never an arbitrary different login. Missing limits returns null; notice renders one text-only `UsageRow` (no fill/tone); usable limits render window rows. The entire row is a focusable tooltip trigger, tooltip prefers left with collision handling. `ThreadDetailsCard` can be inline or a popover, full/compact/essential based on available canvas height. Usage is rendered regardless of density when visible; no additional changed density branch. Visibility is off by default, with legacy toggle support ([threadDetailsItems.ts](https://github.com/pingdotgg/t3code/blob/8d1ec13ca126532d1ec083f62e15985f756a2bb8/apps/web/src/components/chat/threadDetailsItems.ts#L15)).

**Native pooled:** `Stack` SettingsUsage / workspace Usage → `UsageRouteScreen` → `UsageScreen` → [UsageLimitsPooled.UsageLimitsSection](https://github.com/pingdotgg/t3code/blob/8d1ec13ca126532d1ec083f62e15985f756a2bb8/apps/mobile/src/features/usage/UsageLimitsPooled.tsx#L407). Route tab, selected environments and `wide>=600` change surrounding controls/pool layout; warning itself is width-independent View/Text with min-width-zero flex content. Empty selection/content, healthy pools, Cursor prompt, external links, notices, and failed RPC labels are separate branches. P goes into notices with live-region alert. SettingsUsageAccount only receives usable pool accounts/windows and cannot display this new notice directly. Native widgets build only Codex/Claude provider entries, excluding Grok.

**Native composer:** `ThreadComposer` exact-send handler or command-menu callback → `ThreadDetailScreen` → [ComposerUsageLimits](https://github.com/pingdotgg/t3code/blob/8d1ec13ca126532d1ec083f62e15985f756a2bb8/apps/mobile/src/features/threads/ComposerUsageLimits.tsx#L10) → [AccountLimits](https://github.com/pingdotgg/t3code/blob/8d1ec13ca126532d1ec083f62e15985f756a2bb8/apps/mobile/src/features/usage/UsageLimitsSection.tsx#L159) → `limitsNotice`. Missing limits returns null. Dense/non-dense changes padding but the only caller of AccountLimits is dense composer here. First card gets close, later cards get separators; empty report gets a separate close header; report notices render after cards with a border only when cards exist. Instance label differs from driver → secondary text (single-line; `@` uses reveal/hide); plan/detail is optional and single-line. Notice replaces windows; optional link/footer are absent for P. The panel requires a report and no active user-input request; keyboard height, approvals and available overlay size determine maxHeight. Open/close animations, keyboard, scroll, account reveal and pending-request dismissal require recordings when exercised.

## Concrete isolated seeding recipe

All artifacts for this pass are below `/tmp/lead-28097-r1/proof-audit-1/`. None touches the developer's real T3 home or credentials. The generator allocates a NEW timestamped directory on every invocation and never deletes earlier runs.

```sh
python3 /tmp/lead-28097-r1/proof-audit-1/make-fixture.py single
# or: python3 /tmp/lead-28097-r1/proof-audit-1/make-fixture.py mixed
# Prints the fresh absolute run directory. Run its start-dev.sh, capturing PID and log.
```

Verified single run: `/tmp/lead-28097-r1/proof-audit-1/20261103T011540760350Z-single/`. Prepared mixed run (one environment): `/tmp/lead-28097-r1/proof-audit-1/20261103T011712521947Z-mixed/`. Do not reuse this completed run for new output; generate a fresh one. The generator currently uses the audited checkout's absolute path; change only the scratch generator's repo path if the lead supplies a separately authorized baseline checkout.

Generated files and exact controls:

| File / environment | Meaning |
| --- | --- |
| `<run>/home/` | Fake `HOME`; no real home/config copied or linked. `GROK_HOME=<run>/home/.grok` is explicit. |
| `<run>/t3/` | Explicit T3 home. `start-dev.sh` invokes `vp run dev --home-dir <run>/t3 --no-seed` from the checkout, with `T3CODE_DEV_SEED=0`. `--home-dir` is necessary because worktree `.t3` outranks ambient `T3CODE_HOME`. |
| `<run>/t3/userdata/settings.json` | Seeds `providerInstances`: enabled Grok with fake CLI binary path; other built-in default providers disabled. Settings are decoded by the real server. State is a new isolated `statev2.sqlite`; no migration/real-data seeding. |
| `providerInstances.<id>.environment` | `{name:"GROK_AUTH", value:'{"https://accounts.x.ai/sign-in":{"key":"fixture-0","email":"fixture0@example.test"}}', sensitive:false}`. Plain `GROK_AUTH` in the server environment also works because the driver merges instance environment over `process.env`. The script keeps different synthetic tokens/emails per instance. |
| `<run>/bin/grok` | Executable fake CLI: `--version` → grok 1.0.13; `models` → logged-in Grok model catalog; `inspect --json` → `{"skills":[]}`; `agent stdio` uses this checkout's `apps/server/scripts/acp-mock-agent.ts` for initialize. This installed/authenticated gate is required; a synthetic auth string alone does not make a missing CLI probe authenticated. |
| `<run>/preload.mjs` | `NODE_OPTIONS=--import=<run>/preload.mjs`, set before server modules load. Server runtime uses `FetchHttpClient.layer`; the preload replaces **global fetch** only for exact billing URL, returns a real `Response.json(...,{status:403})`, and logs method-independent URL/status/mode without tokens. Other outbound remote fetches are blocked; loopback fetches remain allowed. It also makes the checkout's optional root `.env` and `.env.local` absent to `loadRepoEnv` so it cannot load existing developer configuration. No source file is edited. |
| `<run>/modes.json` | Token → `privacy`, `generic`, `success`, or `empty`. Read afresh per billing request. Change only this synthetic scratch file, then use actual Usage Refresh / native pull-to-refresh. `privacy` returns the exact issue error with WKE marker; `generic` returns a marker-free 403; `success` returns S; `empty` returns `{}` with 200. |
| `<run>/billing.ndjson` | Sanitized request proof (`url`, status, mode). Never logs Authorization or any real account. |
| `start-dev.sh` environment | Uses `env -i`, fake HOME/GROK_HOME, synthetic instance settings, explicit T3CODE_HOME, `T3CODE_DEV_SEED=0`, `T3CODE_NO_BROWSER=1`, `T3CODE_TELEMETRY_ENABLED=false`, `T3CODE_AUTO_BOOTSTRAP_PROJECT_FROM_CWD=false`, preload NODE_OPTIONS and executable PATH. No inherited `XAI_API_KEY`, custom Grok endpoints or deployment config. No `VITE_HTTP_URL`/`VITE_WS_URL` are set; normal single-origin proxying is preserved. |

First startup printed server port 13813 and web port 5773 in this run; read each new `[dev-runner]` line instead of assuming them. Dev did not open a browser. Its generated pairing URL stays in private raw logs and is not included in this public report. Capturer may use the normal authorized Browser/device pairing flow to its own isolated environment. For a second simultaneous environment, run `python3 /tmp/lead-28097-r1/proof-audit-1/make-fixture.py mixed 28097-second`; its new start script sets `T3CODE_DEV_INSTANCE=28097-second` inside the clean environment, selecting a distinct deterministic server/web port pair. Verify the printed actual origins; occupied ports can shift.

**Credential alternatives, from source:** reader first checks deployment guards, then reads config files `<GROK_HOME>/config.toml`, `managed_config.toml`, `requirements.toml`, `/etc/grok/managed_config.toml`, `/etc/grok/requirements.toml`; auth/grok_com_config/endpoints sections opt out. Only then does it prefer `GROK_AUTH` over `<GROK_HOME>/auth.json`. Without `GROK_HOME`, the directory is `<HOME>/.grok` (then USERPROFILE, then HostProcess home fallback). An auth file under the fake HOME therefore works as well: put the above synthetic auth object at `<run>/home/.grok/auth.json` and omit `GROK_AUTH`; keep the fake CLI for status. Supported scopes are `https://auth.x.ai::b1a00492-073a-47ea-816f-4c329264a828` (preferred) and legacy `https://accounts.x.ai/sign-in`. API-key auth does not take this path.

Unset/empty these synthetic-server environment variables: `XAI_API_KEY`, `GROK_OIDC_ISSUER`, `GROK_OIDC_CLIENT_ID`, `GROK_OAUTH2_ISSUER`, `GROK_OAUTH2_CLIENT_ID`, `GROK_OAUTH2_PRINCIPAL_TYPE`, `GROK_OAUTH2_PRINCIPAL_ID`, `GROK_AUTH_PROVIDER_COMMAND`, `GROK_LOCAL_AUTH`, `GROK_CLI_CHAT_PROXY_BASE_URL`, `GROK_MODELS_BASE_URL`, `GROK_CONFIG`, `GROK_CONFIG_PATH`. Any nonblank value makes the credential reader decline. No `GROK_BILLING_URL` or equivalent billing override exists. HttpClient dependency injection works in the reader test/Effect harness; the actual CLI server provides FetchHttpClient itself, so use a process-local preload for real-app capture instead of merely providing a test service to an unrelated Effect.

**Cache answer:** [providerStatusCache.ts](https://github.com/pingdotgg/t3code/blob/8d1ec13ca126532d1ec083f62e15985f756a2bb8/apps/server/src/provider/providerStatusCache.ts#L63) reads `<T3 home>/caches/<instanceId>.json`; `grok.json` is a complete ServerProvider, not just a limits blob. Hydration copies installed/version/status/auth/checkedAt/slashCommands/skills/models into a fresh fallback, intentionally not usageLimits. Do not seed this cache to force the notice. The verified run's cache was inspected only as the server's **output**, after its actual synthetic 403 probe. Provider-managed healthy limits retention is in-memory; a fresh process is needed when deliberately replacing prior healthy S with P for a new fixture.

**Real app vs harness:** W1–W5 and M1–M4 can all run in real clients against this synthetic server. No renderer requires a component harness. If the capturer cannot provision a second environment or native client, the corresponding row remains missing, or any component-only fallback must be labeled **harness capture**, explicitly not real-client verification. A `readGrokAccount` transcript alone is backend evidence, not a UI harness capture.

## Verification and limits of this pass

- Refreshed PR description/comments/status through GitCafe; current head matched. No comments/reviews/pushes/edits made. Supplied merge-base matches `git merge-base HEAD <PR observed main tip>`. The local `main` ref is stale and was not used to broaden the audit; the supplied base-to-head diff contains exactly the two briefed files.
- Read complete diff, producer/auth logic, driver/status gates, managed-provider retention, startup cache hydration, shared limits collection, all five renderer families and their entry/caller paths, command/keyboard entries, native screen route/keyboard sizing, and widget exclusion.
- Ran synthetic status + reader probe with real FetchHttpClient and fake CLI: installed=true, authenticated cached token, status=ready, exact P message. Then launched the real `vp run dev` server and verified its emitted Grok cache contains the same result. See private/local `server-result.json`, `probe.log`, and `billing.ndjson` in the verified run. No browser/device use and no captures.
- Did not rerun repo tests or checks: no code edits; this pass derives proof fixtures. Did not verify recovery or UI behavior at runtime, native iOS/Android, remote/tunnel transport, or baseline visual output. Those claims remain capture tasks.
- Stopped the single dev process group by its captured spawn PID (2294697). Launcher exited, runtime-state file was removed, and both listener ports were free. All scratch/raw logs retained; none deleted. Free disk remained 15 GiB, above the 5 GiB stop threshold.

FRICTION:
- tool | Scratch probe initially used CommonJS `require.resolve` for an import-only `@t3tools/provider-grok/testing` export and failed with ERR_PACKAGE_PATH_NOT_EXPORTED; corrected to the exact source entry without changing the worktree, then verified successfully | Use source-entry ESM imports in out-of-tree diagnostic drivers.
- brief | Local `main` points behind the supplied PR merge-base; `main...HEAD` would include unrelated history | Use the supplied base and PR-observed base SHA, which matched, for proof scope.

VERDICT: INSUFFICIENT W0–W5, M1–M4, R1 need captures/recordings
