# Cursor shell-output performance proof

These are real T3 server turns, not tests, mocks, or a microbenchmark. Both worktrees were unmodified, with independent fresh T3 homes and identical synthetic project files. No production database was read or seeded. Surface: server/CLI and live WebSocket RPC, Linux, Node 26.12.1, Cursor SDK 1.2.0, Cursor Grok 4.7.

Base: 13f89ae0a7fcecbdcd06ac1551d5ff549bb76926 (merge-base with origin/main). Head: 53c5f7e36a871c0f2f7f1872c41d48bb0cdff0a6.

1. Each real Cursor agent ran `python3 emit.py 16` foreground, no redirect/pipe/background. Both replied with line 00275035. The burst control has little handler CPU cost.
2. Each ran `python3 paced.py 30000`: 30,000 flushed 64-byte lines, 1 ms apart, same foreground prompt. Both replied with line 00029999.
3. `profile` runs used V8 CPU sampling (500 us interval) and allocation sampling (32 KiB interval), including objects collected by both minor and major GC. Allocation numbers are statistical estimates, not exact copied-byte counters. No breakpoints or adapter instrumentation.
4. Separate `cpu` runs repeated the exact paced command with allocation sampling OFF. The base handleInteractionUpdate frame has 380.195 ms self / 469.285 ms inclusive; head 43.744 / 137.670 ms. Base CPU source position ticks heavily identify adapter.ts:2115, the concat+slice line (624 of 664 handler self ticks). Head no longer copies on every chunk.
5. Separate allocation runs show 3,203,398,480 bytes allocated in slice beneath that handler on base, versus 1,048,736 on head. All allocations beneath the handler: 3,234,536,928 versus 31,795,104 bytes. This is the repeated-tail-copying defect.
6. Live command-output RPC subscriptions captured replace/append/finished frames with timestamps. Reconstructing the running frames produces exactly the same first 1,048,576 characters on both sides (all lines 0..16383, SHA-256 in metrics.json). The SDK's approximately 1 MiB stream ceiling persists on both commits. Persisted command output is byte-identical at 262,144 characters on both sides. Each command exits 0; final assistant replies contain the actual last line 29999.

CPU time means sampled frame time, not whole-command latency. Model latency and SDK batching vary; no end-to-end speedup or GC reduction is claimed. Profiles cover the entire turn, but metrics isolate the same adapter frame and slice descendants. Generic text updates share that frame; source position ticks identify the hot copying statement on base. Heap sampling and CPU-only profiling are separate evidence pairs. A supplementary precise-coverage capture was interrupted before saving, and is not evidence or included here.

The MP4s are explicitly labeled rendered playbacks of the timestamped live RPC recordings at their original timing (4 fps), not browser screen captures. They show the real streaming output and eventual completion. Their completion card includes the final reply taken from the completed turn transcript. The side-by-side PNGs are derived charts of the raw profiles, not screenshots of T3. Raw JSON/CPU/heap captures, output hashes, transcripts, and scripts are included so the charts are independently checkable. No web, desktop, or mobile rendering claim is made.

## Replay

Install each checkout with `vp i`. Set PROOF_ROOT, BASE_CHECKOUT and HEAD_CHECKOUT. Place paced.py and emit.py in `$PROOF_ROOT/workload`, initialize a git repository there, and add it to each fresh server using `t3 project add`.

Start each real server with T3CODE_DEV_SEED=0, an explicit independent --base-dir, --host 127.0.0.1, and --no-browser. The base server port/inspector port are 19480/19481; head 19470/19471. Enable the cursor provider instance in each fresh settings.json; the server must inherit CURSOR_API_KEY. Use `node --inspect=127.0.0.1:<inspector> apps/server/src/bin.ts serve ...`.

Run `node drive.mjs base cpu`, then `node drive.mjs head cpu`; repeat using `profile` for allocation sampling, and `profile 'emit.py 16'` for the burst control. The driver uses the real thread CLI and real live RPC, with temporary read-only sessions issued by the local auth CLI. It never logs session tokens. Each run writes a new timestamped output directory. `metrics.py` extracts profiles and reads only those synthetic databases in read-only mode.

Open .cpuprofile in Chrome DevTools Performance or VS Code; open .heapprofile in Chrome DevTools Memory (load allocation sampling profile). URLs have been sanitized to /checkout, /proof and /runtime, so source mapping requires selecting the corresponding public commit locally. Metrics use node IDs and original line numbers; sanitization does not change sample counts, allocations or timings.
