# Usage-limit comparison driver

Synthetic data only. Run date: 2026-11-11. Server/browser timezone UTC. Web viewport 1280 × 800, light theme, sidebar hidden; Environment and Worktree detail rows hidden. Native iOS captures use the same server data and the unmodified dev client.

This is a protocol fixture, not a real subscription or a mock of T3 internals. `fixture.cjs` implements the external CLI app-server protocol and CLIProxyAPI management endpoints. The real T3 server, Codex adapter, terminal event ingestor, usage services, persistence, RPC, and clients run from each target commit. No tests are used as evidence.

## Setup on each commit

Put all supplied scripts in one empty scratch directory. Set CHECKOUT to a worktree at the base or head commit, run `vp i` there. Keep fresh, separate `.t3` directories; never seed from a live database. Initialize `workspace/` beside the scripts as a new git repository with an empty initial commit and synthetic author. Run:

```sh
node fixture.cjs --hub
```

Keep that server running. In another shell:

```sh
python3 prepare.py "$CHECKOUT"
python3 launch.py "$CHECKOUT" base-or-head
python3 seed.py "$CHECKOUT" base-or-head
```

Read the web and server ports from the launcher log. Open the real web app, pair using that checkout's CLI, select Quota routing proof → Routed quota, enable Usage limits in thread details. Both native reads fail with “Proxy did not provide a native snapshot.” The synthetic model is `quota-demo` (UI: Quota demo).

The hub exposes two Claude accounts routed to this model, A and B, plus an unrelated Codex account routed only to `other-demo`. Initially A has 75% session remaining, B 35%, both weekly 70%. B is marked most recently successful. The unrelated account has 98% available. Inspect the thread card, then send `/usage-limits` (a local command).

## Exhaustion and missing terminal reset

Create an empty file named `exhausted` beside fixture.cjs. This makes both eligible accounts' session and weekly windows 100% used while leaving the unrelated account available. Wait for the real usage source refresh. Open Hub recovery and submit:

```
HUB_EXHAUSTED: continue after exhausting both routed accounts.
```

Record from submit through terminal recovery. The external CLI emits usageLimitExceeded with no timestamp or snapshot. Account A's bottleneck resets November 13 at 14:00Z; B's November 14 at 16:00Z. Head recovers November 13 at 14:00Z, enables reset-based actions, and existing auto-resume/snooze settings schedule and snooze it. Base says reset time unavailable.

## Reset only in error text

Open Text recovery (or create another thread named Text reset proof using the same `thread start` command as seed.py) and submit:

```
TEXT_RESET: continue with the reset supplied only in the CLI error text.
```

The CLI emits “You've hit your usage limit. Try again at Nov 15th, 2026 2:30 PM.” with no structured reset; native reads still fail. Record the interaction. Head uses November 15 at 14:31Z (the parser's safety minute), ahead of the hub fallback, enables recovery, and schedules/snoozes. Base has no reset actions.

The final text video pair was repeated on fresh Text reset proof threads to eliminate a navigation splash in the first recording. The steady-state screenshots show the subsequent automatic scheduling. `runtime-transcript.json` contains selected fields from real `thread show --json` output, with identifiers/paths omitted.

## Native iOS

Install each checkout's dev client with `vp run mobile:install ios`, start that checkout's `apps/mobile` Metro via `vp run dev:client --port PORT`, pair to its server using the repository pair-client.sh, and open Routed quota. Submit `/usage-limits` and collapse/expand the existing message to dismiss the keyboard. This exercises both ThreadComposer's initial report and ThreadDetailScreen's report recomputation. Capture the report for each bundle. Both use the exhausted hub state. The supplied iOS images uniformly crop the top 54-pixel system status bar; the app region in two consecutive native captures was pixel-identical. The report is scrollable, and both accounts’ Session and Weekly rows are visible in the supplied head capture.

No real credentials, provider account, or private runtime model identifiers are required. Future automatic wake execution is not covered by these captures. AI-assisted; verified with the tests and tools listed above.
