# Background wait approval proof

AI-assisted; verified with the tests and tools listed above.

Manual live-provider comparison, not replay. Both commits ran the real server and Vite web client on Linux, in separate worktrees with T3CODE_DEV_SEED=0 and fresh worktree-local databases. Browser viewport: 1280×800 CSS pixels, light theme. No live database was copied. The model selector was hidden with CSS solely to omit private runtime metadata from captures. The desktop shell was not exercised.

## Seed and driver

Install dependencies with `vp i` in each checkout. Start each with `T3CODE_DEV_SEED=0 vp run dev`, retaining the process for cleanup. Pair a browser with its startup URL.

Use one empty synthetic git repository, with an initial empty commit, titled Background wait demo. Add it to each server through `node apps/server/src/bin.ts project add --base-dir .t3 --title 'Background wait demo' "$PROJECT"`.

Create a thread in each with `thread start --base-dir .t3 --provider claudeAgent --model "$CONFIGURED_MODEL" --title 'Plan background wait' "$PROJECT" 'Reply Ready only. Do not run any tools.' --json`. CONFIGURED_MODEL is a locally available inexpensive Claude model; its private identifier is deliberately omitted.

Issue a short-lived local bearer with `auth session issue --base-dir .t3 --ttl 1h --token-only`, saving privately. Run the attached rpc.cjs as:

```
node rpc.cjs "$CHECKOUT" "$SERVER_PORT" "$PRIVATE_TOKEN_FILE" "$THREAD" interaction-mode plan
node rpc.cjs "$CHECKOUT" "$SERVER_PORT" "$PRIVATE_TOKEN_FILE" "$THREAD" runtime-mode full-access
```

This sends the app's standard orchestration commands, without modifying a database. Open the resulting thread in the browser, close its Thread details panel, and record the conversation. To omit model metadata, insert a style whose text is `button[aria-label^="Claude "]{visibility:hidden !important}` before recording.

Send each attached prompt through `node apps/server/src/bin.ts thread send --base-dir .t3 "$THREAD" - < prompt.txt`, then prompt2.txt, then repeat.txt, waiting for each turn and background completion as appropriate. On base, prompt.txt initially produced a refusal to start the timer; prompt2.txt clarified its harmlessness. The same three prompts were sent on head, which ran the first timer immediately.

On base, the first t3_background_wait registration displayed an approval card. Open More and choose Always allow this session. Repeat with the fresh timer using repeat.txt: another registration approval card appears. Approve it to let the task proceed. On completion, clearing its wait also asks for approval; before-clear.mp4 shows this. On head no approvals were needed, registrations returned matched IDs, and timers completed with exit code 0. Clearing after completion also completed without approval, with an unmatched ID because the timer had already finished.

The initial base registration was delayed long enough by approval that its timer had finished before registration; it returned unmatched. The second base registration returned matched after approval. Do not interpret the difference in task IDs or reply prose as evidence: the visible approval cards are the failure, and their absence throughout the head recordings plus matched tool results and normal completion are the fix.

runtime-results.json contains only the actual persisted background-wait tool inputs, outputs, statuses and timestamps, extracted read-only from these synthetic development databases. It supplements the real-app videos. No tests were used as proof.
