# CLI wait evidence for [#34688](https://github.com/pingdotgg/t3code/issues/34688)

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

## Environment and method

Base: [a21b43fc70](https://github.com/pingdotgg/t3code/commit/a21b43fc70fe1c835dc817cb0281befbea95a58c). Head: [5819dda701](https://github.com/pingdotgg/t3code/commit/5819dda70110d8f168d591007c0dc6bc5ebbe563).

Linux, real Node server and CLI, isolated worktrees and worktree-local T3 homes, synthetic empty git project. Both servers were started with `T3CODE_DEV_SEED=0 vp run dev`. No live database was copied. No application code was edited and no test result is offered as evidence. This is CLI behavior, so a web/replay scenario would not exercise the affected command.

`recording.mp4` is a real-time (1x), uninterrupted capture of the driver's live command monitor, not a web client recording. FFmpeg renders the current monitor text at 2 fps, 1600x1000, dark background. The same driver and rendering settings run on both sides. The monitor displays observed persisted run transitions, completed assistant messages, actual CLI exit codes, elapsed durations, and selected background-related tool state. A tool's completed status means its invocation completed; it does not mean the asynchronous sleep ended. The later wake run and DONE message establish that milestone.

The monitor's observer opens only each isolated server's SQLite database, read-only. It never creates or changes application state. The CLI creates threads and sends messages through the real server. The driver keeps observing after an early CLI return so the later wake is in the same recording. No mock provider or injected run is used.

## Exact procedure

Install each checkout using `vp i`. Start a fresh isolated server in each checkout with `T3CODE_DEV_SEED=0 vp run dev`; retain the launcher PID for cleanup. Create an empty scratch git repository, commit an empty initial commit, and run in each checkout:

```sh
node apps/server/src/bin.ts project add "$PROJECT" --title 'Wait proof' --base-dir "$CHECKOUT/.t3"
```

Then run the *same* published driver against each checkout, with side `before` or `after`. Supply the same installed provider and its cheapest available model through environment variables (runtime identifiers are private and deliberately omitted):

```sh
python3 driver.py "$CHECKOUT" before "$OUTPUT_ROOT" "$PROJECT"
python3 driver.py "$CHECKOUT" after "$OUTPUT_ROOT" "$PROJECT"
```

Each invocation creates a timestamped output directory; it does not delete earlier output. Requirements: Python 3 standard library, Git, Node, FFmpeg with libx264 and drawtext, DejaVu Sans Mono at the font path in the script, and an installed/authenticated provider. Set `T3_PROOF_PROVIDER` and `T3_PROOF_MODEL` before running. The provider must support background commands and `t3_background_wait`.

The driver performs, in order:

1. Start a new thread with `Reply exactly READY.` using `--wait --json`, recording the actual duration. Retain this idle thread for send.
2. Start a different new thread with the exact prompt below using `--wait --json`. Keep observing until the background wake run finishes, even when the CLI exits early.
3. Send the same prompt to the seeded READY thread using `thread send --wait --json`. Keep observing until the background wake run finishes.

```text
Run `sleep 45` in the background (run_in_background), call t3_background_wait on its task ID, and end your turn. When it finishes, reply DONE.
```

The command's stdout, stderr, observations, and summary are published alongside the continuous recordings. The driver's paths and runtime selection are redacted before public output. No source is modified between these steps.

## Attempt accounting

There are two complete comparison pairs in this bundle. The first pair (`pilot/`) used `driver-v1.py`; inspecting its base start-case frames revealed the monitor could clip the newest lines. The final pair (`before/`, `after/`) used `driver.py`, whose only changes are text wrapping, scrolling, and font size. Both drivers are included, with checksums. The reproduction prompts, CLI commands, observation logic and timeout ceiling are identical. The first pair is retained for audit, not offered as the primary visual proof. All recordings are uninterrupted and at real speed.

Before the pilot pair, one diagnostic plain READY request was made on head. Its persisted run took about 3.76 seconds; its CLI JSON is included as `diagnostic-ready.json`. It contained no background work. A project-add setup command initially ran before the scratch directory existed and failed; creating the scratch git repository resolved that before recording. Those were the only preliminary application requests.

Before the final comparison pair, both dev servers were stopped, both scratch T3 homes were removed, and both servers were restarted with seeding disabled. Each started with an empty database, and received the same project-add command followed by the same driver sequence. Thus the preliminary diagnostic and pilot threads were absent from both final databases. No application source was modified. No attempt has been omitted from this bundle.

The previous submission's 182-second seed stall was not reproduced by this fresh-state run. These observations establish the fresh-state behavior only; they do not establish why that earlier run stalled or rule out a state-dependent stall.

## Verification boundaries

This capture covers successful background-wake replies from both `thread start` and `thread send`, plus plain-reply latency on both commits. It does not exercise failed/interrupted wake runs, pending-input exits, concurrent sends from another client, restarts, long delegated-child chains, or paginated history. It does not claim to prove those paths.

## Final observed results

| Command | Before | After |
| --- | --- | --- |
| Plain READY start | 5.01 s; READY; run 1; exit 0 | 4.26 s; READY; run 1; exit 0 |
| Background start | 9.28 s; interim reply; run 1; exit 0 | 59.69 s; DONE; wake run 2; exit 0 |
| Background send | 9.53 s; interim reply; run 2; exit 0 | 49.93 s; DONE; wake run 3; exit 0 |

Base's later DONE replies were observed at 64.45 s (start) and 119.90 s (send) on the recording clock, after the corresponding CLI exits at 17.30 s and 76.99 s. Head's corresponding CLI exits occur after the wake runs complete. Plain READY is visible in the first seconds of each full recording. The final sequences each take about 127 seconds including the observation tail.

The `failed` dynamic-tool lines visible in the final head capture are transient provider invocation errors: one invented tool name during start, and singular `taskId` instead of the accepted `taskIds` during send. The provider corrected each invocation within the same run. They are included, not edited out; both actual wake runs completed successfully. They do not test failed-run exit codes.

The stills are lossless renders of the finished monitor text. `capture-stills.py` renders each monitor twice with a 500 ms gap and requires identical PNG hashes. Both checks passed. The videos and representative frames were opened for visual inspection; the final pair fits the full monitor content in the viewport. The pilot pair retains its original layout limitation.
