test(server): measure shell, second client, and reconnect transfer - #9157

Merged
t3dotgg merged 1 commit into
mainfrom
t3code/transfer-budget-shell-and-multi-client
Sep 2, 2026
Merged

test(server): measure shell, second client, and reconnect transfer#9157
t3dotgg merged 1 commit into
mainfrom
t3code/transfer-budget-shell-and-multi-client

Conversation

@t3dotgg

@t3dotggt3dotgg commented Sep 2, 2026

Copy link
Copy Markdown
Member

The transfer budget measured one thread subscription during one turn. Real clients also hold the sidebar (shell) subscription, users often have a desktop and a phone connected at once, and clients reconnect. Nobody had measured those, and the larger perf proposals (sharing the sidebar projector across clients, sharing git services across connections, incremental history) are gated on knowing whether they matter.

This PR measures them in the same test and prints them next to the existing capped rows. The single-thread measurement and its caps are unchanged.

What it adds:

  • A shell-only socket and a second client socket holding both the thread and shell subscriptions during the measured turn. The report shows per-socket wire bytes, decoded bytes, message counts, and total server egress.
  • A reconnect after the turn. The second client disconnects and resubscribes each subscription from the cursor it held before the turn. The report shows catch-up bytes and whether the server chose replay or a snapshot reset.
  • A SQL statement count from sql.execute spans. A counting tracer is installed on the harness runtime and the HTTP/WS app so reactor writes and subscription reads land in one total. No new instrumentation in src/.
  • openMeasuredWsClient opens each RPC socket on its own child scope so clients disconnect independently.

The new rows have no caps. The shell stream coalesces on a 50 ms window, so the second client's message count moved between 9 and 10 across runs and its wire bytes between 6.7 and 7.1 KiB. SQL statement counts moved between 1096 and 1167 for the same reason. The capped thread rows stayed within a few bytes.

Measured (local, one run):

ProviderPhaseMetricObservedBudgetResult
codexthread snapshotHTTP wire6.9 KiB (7,049 B)7.3 KiB (7,500 B)PASS
codexmeasured turnWebSocket wire6.3 KiB (6,401 B)7.8 KiB (8,000 B)PASS
codexmeasured turnWebSocket decoded54.7 KiB (55,974 B)66.4 KiB (68,000 B)PASS
codexmeasured turnWebSocket messages821PASS
codexshell snapshotHTTP wire829 BnoneINFO
codexmeasured turn, shellWebSocket wire628 BnoneINFO
codexmeasured turn, shellWebSocket decoded3.7 KiB (3,793 B)noneINFO
codexmeasured turn, shellWebSocket messages3noneINFO
codexmeasured turn, second clientWebSocket wire7.0 KiB (7,144 B)noneINFO
codexmeasured turn, second clientWebSocket decoded58.3 KiB (59,723 B)noneINFO
codexmeasured turn, second clientWebSocket messages10noneINFO
codexmeasured turnserver egress wire13.8 KiB (14,173 B)noneINFO
codexmeasured turnSQL statements1096noneINFO
codexreconnect, thread (replay)WebSocket wire6.2 KiB (6,325 B)noneINFO
codexreconnect, thread (replay)WebSocket decoded54.4 KiB (55,707 B)noneINFO
codexreconnect, thread (replay)WebSocket messages2noneINFO
codexreconnect, shell (replay)WebSocket wire386 BnoneINFO
codexreconnect, shell (replay)WebSocket decoded1.3 KiB (1,355 B)noneINFO
codexreconnect, shell (replay)WebSocket messages2noneINFO
codexreconnectSQL statements10noneINFO
claudeAgentthread snapshotHTTP wire6.9 KiB (7,059 B)7.3 KiB (7,500 B)PASS
claudeAgentmeasured turnWebSocket wire6.3 KiB (6,409 B)7.8 KiB (8,000 B)PASS
claudeAgentmeasured turnWebSocket decoded55.5 KiB (56,806 B)66.4 KiB (68,000 B)PASS
claudeAgentmeasured turnWebSocket messages821PASS
claudeAgentshell snapshotHTTP wire829 BnoneINFO
claudeAgentmeasured turn, shellWebSocket wire626 BnoneINFO
claudeAgentmeasured turn, shellWebSocket decoded3.8 KiB (3,877 B)noneINFO
claudeAgentmeasured turn, shellWebSocket messages3noneINFO
claudeAgentmeasured turn, second clientWebSocket wire7.0 KiB (7,161 B)noneINFO
claudeAgentmeasured turn, second clientWebSocket decoded59.2 KiB (60,602 B)noneINFO
claudeAgentmeasured turn, second clientWebSocket messages10noneINFO
claudeAgentmeasured turnserver egress wire13.9 KiB (14,196 B)noneINFO
claudeAgentmeasured turnSQL statements1096noneINFO
claudeAgentreconnect, thread (replay)WebSocket wire6.2 KiB (6,342 B)noneINFO
claudeAgentreconnect, thread (replay)WebSocket decoded55.2 KiB (56,539 B)noneINFO
claudeAgentreconnect, thread (replay)WebSocket messages2noneINFO
claudeAgentreconnect, shell (replay)WebSocket wire379 BnoneINFO
claudeAgentreconnect, shell (replay)WebSocket decoded1.4 KiB (1,383 B)noneINFO
claudeAgentreconnect, shell (replay)WebSocket messages2noneINFO
claudeAgentreconnectSQL statements10noneINFO

Reading the numbers:

  • The sidebar costs about 630 B wire and 3 messages per turn, about 10% of the thread stream. A second device costs one more thread stream plus one more shell stream, about 7 KiB. Egress scales linearly with connected clients and there is no hidden multiplier.
  • Reconnecting from the pre-turn cursor replays about the same bytes as live delivery (6.3 KiB thread, 380 B shell) in 2 messages each and 10 SQL statements total. Replay was chosen every time at this gap size. Snapshot fallback did not trigger.
  • This fixture mocks git, so it says nothing about sharing git services across connections.

Change authored by Claude Fable 5.1 running in Claude Code.


Note

Low Risk
Changes are confined to integration tests and reporting helpers; production server code is not modified.

Overview
Extends the thread transfer budget integration test so CI reports more than a single thread WebSocket during one turn. Existing capped thread snapshot and measured-turn rows are unchanged.

The scenario now opens three measured WebSocket clients (thread-only, shell-only, and a second device with both subscriptions), records shell HTTP snapshot size, and sums server egress across the three sockets. After the turn, the second client closes and resubscribes from its pre-turn cursors; the report records catch-up wire/decoded/message totals and whether catch-up used replay or snapshot.

Test harness plumbing adds openMeasuredWsClient (per-client forked scope + close), WebSocket recorder improvements (awaitOpen, wire totals after close), shared SQL statement counting via a counting Tracer on the orchestration harness and HTTP/WS app (sql.execute spans), and helpers moved into TransferBudgetScenario for thread/shell subscribe and sync detection. New report fields are INFO-only (no new budgets).

Reviewed by Cursor Bugbot for commit 7aff2b1. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Expand transfer-budget test to measure shell, second client, and reconnect transfer

  • Reworks the live transfer-budget integration test in server.test.ts to open three concurrent measured clients (thread-only, shell-only, second-client), capture per-socket WebSocket transfer and server-wide sql.execute deltas, then close and reconnect the second client to measure replay-or-snapshot catch-up
  • Adds openMeasuredWsClient, a factory that forks a per-client child scope, builds a counting WebSocket protocol, waits for open (10s timeout defect), and returns an explicit close effect
  • Updates makeWebSocketTransferRecorder to retain the underlying transport at open time so wire-byte totals remain readable after socket closure
  • Adds makeSqlStatementCounter, a tracer that increments a counter for spans named exactly sql.execute while returning native spans for all operations
  • Extends formatTransferBudgetReport with informational (uncapped) rows for shell snapshot, shell-only and second-client WebSocket diagnostics, aggregate server egress, SQL counts, and reconnect catch-up modes alongside existing capped thread rows
  • Adds subscription helpers subscribeThreadItems, subscribeShellItems, and awaitSubscriptionSynchronized in TransferBudgetScenario.integration.ts that run scoped subscriptions and classify initial catch-up as replay or snapshot
  • Risk: makeWebSocketTransferRecorder open wait fails with a timeout defect after 10 seconds; awaitSubscriptionSynchronized similarly defects after 10 seconds if the synchronization marker never arrives

Macroscope summarized 7aff2b1.

The transfer budget measured one thread subscription. Real clients also hold
a sidebar subscription, often run on two devices, and reconnect. Measure all
three on the same turn and print them next to the capped thread rows, plus a
SQL statement count from sql.execute spans.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Sep 2, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ProviderMetricMain baselineThis PRImpactPR ceiling
CodexTotal thread wire13.3 KiB13.3 KiB+15 B (+0.1%)15.1 KiB
CodexThread snapshot wire6.9 KiB6.9 KiB+6 B (+0.1%)7.3 KiB
CodexLive turn WebSocket wire6.4 KiB6.4 KiB+9 B (+0.1%)7.8 KiB
CodexLive turn WebSocket decoded55.6 KiB55.6 KiB0 B (0.0%)66.4 KiB
CodexLive turn messages10100 (0.0%)21
ClaudeTotal thread wire13.3 KiB13.3 KiB+13 B (+0.1%)15.1 KiB
ClaudeThread snapshot wire6.9 KiB6.9 KiB−6 B (−0.1%)7.3 KiB
ClaudeLive turn WebSocket wire6.4 KiB6.4 KiB+19 B (+0.3%)7.8 KiB
ClaudeLive turn WebSocket decoded56.4 KiB56.4 KiB0 B (0.0%)66.4 KiB
ClaudeLive turn messages10100 (0.0%)21

Baseline: 80c708a · PR result: 7aff2b1 · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 109.4 KiB
  • Claude decoded thread snapshot: 110.1 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 7aff2b1

Macroscope's review found this PR approvable — This PR expands a server integration test to measure shell traffic, multiple clients, reconnects, and SQL activity. All changes are confined to test and reporting infrastructure, with no shipped production behavior or product-default changes.

Notes:

  • No code objects were reviewed. Approvability was decided on eligibility alone.

You can add or adjust custom eligibility rules. Learn more.

@t3dotgg
t3dotgg merged commit c37fd13 into mainSep 2, 2026
22 checks passed
@t3dotgg
t3dotgg deleted the t3code/transfer-budget-shell-and-multi-client branch September 2, 2026 02:16
github-actionsBot added a commit to omarcresp/t3code-flake that referenced this pull request Sep 2, 2026
## What's Changed
* perf(client-runtime): keep turn and checkpoint refs stable while streaming by @t3dotgg in pingdotgg/t3code#9145
* perf(clients): lease sidebar status by visibility by @StiensWout in pingdotgg/t3code#9052
* fix(desktop): show newest changes in nightly previews by @t3dotgg in pingdotgg/t3code#9138
* fix(settings): sync auto-settle and other shared preferences across environments by @t3dotgg in pingdotgg/t3code#9147
* fix(server): prevent accidental service downgrades by @t3dotgg in pingdotgg/t3code#5302
* fix(server): keep attachments until the command commits by @t3dotgg in pingdotgg/t3code#7941
* fix(claude): preview images read from the workspace by @t3dotgg in pingdotgg/t3code#9119
* fix(web): keep generated muted foreground dimmer than entered text by @flamboh in pingdotgg/t3code#9113
* fix(clients): stop repeating expanded commands by @t3dotgg in pingdotgg/t3code#9120
* fix(grok): health check, model selection, and stop all work against the real CLI by @t3dotgg in pingdotgg/t3code#9154
* perf(web): halve the cold-start bundle by splitting Clerk and cold routes by @StiensWout in pingdotgg/t3code#9058
* feat(desktop): update the desktop app on remote Macs from the Update button by @t3dotgg in pingdotgg/t3code#6554
* test(server): measure shell, second client, and reconnect transfer by @t3dotgg in pingdotgg/t3code#9157
* fix(web): project default model works on the hosted app by @juliusmarminge in pingdotgg/t3code#9142
* fix(web): darken neutral control surfaces by @maria-rcks in pingdotgg/t3code#9064
* fix(web): preserve panel state across workspace refreshes by @maria-rcks in pingdotgg/t3code#8968
* feat(files): open markdown, HTML, and PDF files outside the workspace by @juliusmarminge in pingdotgg/t3code#9140
* feat(web): render HTML and PDF files in the file viewer by @juliusmarminge in pingdotgg/t3code#9143
* fix(web): compact project settings actions by @maria-rcks in pingdotgg/t3code#9160
* fix(web): browse folders from file breadcrumbs by @404khai in pingdotgg/t3code#8910
## New Contributors
* @404khai made their first contribution in pingdotgg/t3code#8910
**Full Changelog**: pingdotgg/t3code@v0.0.39-nightly.20260902.1252...v0.0.39-nightly.20260902.1253
Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.39-nightly.20260902.1253
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

test(server): measure shell, second client, and reconnect transfer - #9157

Merged
t3dotgg merged 1 commit into
mainfrom
t3code/transfer-budget-shell-and-multi-client
Sep 2, 2026
Merged

test(server): measure shell, second client, and reconnect transfer#9157
t3dotgg merged 1 commit into
mainfrom
t3code/transfer-budget-shell-and-multi-client

Conversation

@t3dotgg

@t3dotggt3dotgg commented Sep 2, 2026

Copy link
Copy Markdown
Member

The transfer budget measured one thread subscription during one turn. Real clients also hold the sidebar (shell) subscription, users often have a desktop and a phone connected at once, and clients reconnect. Nobody had measured those, and the larger perf proposals (sharing the sidebar projector across clients, sharing git services across connections, incremental history) are gated on knowing whether they matter.

This PR measures them in the same test and prints them next to the existing capped rows. The single-thread measurement and its caps are unchanged.

What it adds:

  • A shell-only socket and a second client socket holding both the thread and shell subscriptions during the measured turn. The report shows per-socket wire bytes, decoded bytes, message counts, and total server egress.
  • A reconnect after the turn. The second client disconnects and resubscribes each subscription from the cursor it held before the turn. The report shows catch-up bytes and whether the server chose replay or a snapshot reset.
  • A SQL statement count from sql.execute spans. A counting tracer is installed on the harness runtime and the HTTP/WS app so reactor writes and subscription reads land in one total. No new instrumentation in src/.
  • openMeasuredWsClient opens each RPC socket on its own child scope so clients disconnect independently.

The new rows have no caps. The shell stream coalesces on a 50 ms window, so the second client's message count moved between 9 and 10 across runs and its wire bytes between 6.7 and 7.1 KiB. SQL statement counts moved between 1096 and 1167 for the same reason. The capped thread rows stayed within a few bytes.

Measured (local, one run):

ProviderPhaseMetricObservedBudgetResult
codexthread snapshotHTTP wire6.9 KiB (7,049 B)7.3 KiB (7,500 B)PASS
codexmeasured turnWebSocket wire6.3 KiB (6,401 B)7.8 KiB (8,000 B)PASS
codexmeasured turnWebSocket decoded54.7 KiB (55,974 B)66.4 KiB (68,000 B)PASS
codexmeasured turnWebSocket messages821PASS
codexshell snapshotHTTP wire829 BnoneINFO
codexmeasured turn, shellWebSocket wire628 BnoneINFO
codexmeasured turn, shellWebSocket decoded3.7 KiB (3,793 B)noneINFO
codexmeasured turn, shellWebSocket messages3noneINFO
codexmeasured turn, second clientWebSocket wire7.0 KiB (7,144 B)noneINFO
codexmeasured turn, second clientWebSocket decoded58.3 KiB (59,723 B)noneINFO
codexmeasured turn, second clientWebSocket messages10noneINFO
codexmeasured turnserver egress wire13.8 KiB (14,173 B)noneINFO
codexmeasured turnSQL statements1096noneINFO
codexreconnect, thread (replay)WebSocket wire6.2 KiB (6,325 B)noneINFO
codexreconnect, thread (replay)WebSocket decoded54.4 KiB (55,707 B)noneINFO
codexreconnect, thread (replay)WebSocket messages2noneINFO
codexreconnect, shell (replay)WebSocket wire386 BnoneINFO
codexreconnect, shell (replay)WebSocket decoded1.3 KiB (1,355 B)noneINFO
codexreconnect, shell (replay)WebSocket messages2noneINFO
codexreconnectSQL statements10noneINFO
claudeAgentthread snapshotHTTP wire6.9 KiB (7,059 B)7.3 KiB (7,500 B)PASS
claudeAgentmeasured turnWebSocket wire6.3 KiB (6,409 B)7.8 KiB (8,000 B)PASS
claudeAgentmeasured turnWebSocket decoded55.5 KiB (56,806 B)66.4 KiB (68,000 B)PASS
claudeAgentmeasured turnWebSocket messages821PASS
claudeAgentshell snapshotHTTP wire829 BnoneINFO
claudeAgentmeasured turn, shellWebSocket wire626 BnoneINFO
claudeAgentmeasured turn, shellWebSocket decoded3.8 KiB (3,877 B)noneINFO
claudeAgentmeasured turn, shellWebSocket messages3noneINFO
claudeAgentmeasured turn, second clientWebSocket wire7.0 KiB (7,161 B)noneINFO
claudeAgentmeasured turn, second clientWebSocket decoded59.2 KiB (60,602 B)noneINFO
claudeAgentmeasured turn, second clientWebSocket messages10noneINFO
claudeAgentmeasured turnserver egress wire13.9 KiB (14,196 B)noneINFO
claudeAgentmeasured turnSQL statements1096noneINFO
claudeAgentreconnect, thread (replay)WebSocket wire6.2 KiB (6,342 B)noneINFO
claudeAgentreconnect, thread (replay)WebSocket decoded55.2 KiB (56,539 B)noneINFO
claudeAgentreconnect, thread (replay)WebSocket messages2noneINFO
claudeAgentreconnect, shell (replay)WebSocket wire379 BnoneINFO
claudeAgentreconnect, shell (replay)WebSocket decoded1.4 KiB (1,383 B)noneINFO
claudeAgentreconnect, shell (replay)WebSocket messages2noneINFO
claudeAgentreconnectSQL statements10noneINFO

Reading the numbers:

  • The sidebar costs about 630 B wire and 3 messages per turn, about 10% of the thread stream. A second device costs one more thread stream plus one more shell stream, about 7 KiB. Egress scales linearly with connected clients and there is no hidden multiplier.
  • Reconnecting from the pre-turn cursor replays about the same bytes as live delivery (6.3 KiB thread, 380 B shell) in 2 messages each and 10 SQL statements total. Replay was chosen every time at this gap size. Snapshot fallback did not trigger.
  • This fixture mocks git, so it says nothing about sharing git services across connections.

Change authored by Claude Fable 5.1 running in Claude Code.


Note

Low Risk
Changes are confined to integration tests and reporting helpers; production server code is not modified.

Overview
Extends the thread transfer budget integration test so CI reports more than a single thread WebSocket during one turn. Existing capped thread snapshot and measured-turn rows are unchanged.

The scenario now opens three measured WebSocket clients (thread-only, shell-only, and a second device with both subscriptions), records shell HTTP snapshot size, and sums server egress across the three sockets. After the turn, the second client closes and resubscribes from its pre-turn cursors; the report records catch-up wire/decoded/message totals and whether catch-up used replay or snapshot.

Test harness plumbing adds openMeasuredWsClient (per-client forked scope + close), WebSocket recorder improvements (awaitOpen, wire totals after close), shared SQL statement counting via a counting Tracer on the orchestration harness and HTTP/WS app (sql.execute spans), and helpers moved into TransferBudgetScenario for thread/shell subscribe and sync detection. New report fields are INFO-only (no new budgets).

Reviewed by Cursor Bugbot for commit 7aff2b1. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Expand transfer-budget test to measure shell, second client, and reconnect transfer

  • Reworks the live transfer-budget integration test in server.test.ts to open three concurrent measured clients (thread-only, shell-only, second-client), capture per-socket WebSocket transfer and server-wide sql.execute deltas, then close and reconnect the second client to measure replay-or-snapshot catch-up
  • Adds openMeasuredWsClient, a factory that forks a per-client child scope, builds a counting WebSocket protocol, waits for open (10s timeout defect), and returns an explicit close effect
  • Updates makeWebSocketTransferRecorder to retain the underlying transport at open time so wire-byte totals remain readable after socket closure
  • Adds makeSqlStatementCounter, a tracer that increments a counter for spans named exactly sql.execute while returning native spans for all operations
  • Extends formatTransferBudgetReport with informational (uncapped) rows for shell snapshot, shell-only and second-client WebSocket diagnostics, aggregate server egress, SQL counts, and reconnect catch-up modes alongside existing capped thread rows
  • Adds subscription helpers subscribeThreadItems, subscribeShellItems, and awaitSubscriptionSynchronized in TransferBudgetScenario.integration.ts that run scoped subscriptions and classify initial catch-up as replay or snapshot
  • Risk: makeWebSocketTransferRecorder open wait fails with a timeout defect after 10 seconds; awaitSubscriptionSynchronized similarly defects after 10 seconds if the synchronization marker never arrives

Macroscope summarized 7aff2b1.

The transfer budget measured one thread subscription. Real clients also hold
a sidebar subscription, often run on two devices, and reconnect. Measure all
three on the same turn and print them next to the capped thread rows, plus a
SQL statement count from sql.execute spans.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Sep 2, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ProviderMetricMain baselineThis PRImpactPR ceiling
CodexTotal thread wire13.3 KiB13.3 KiB+15 B (+0.1%)15.1 KiB
CodexThread snapshot wire6.9 KiB6.9 KiB+6 B (+0.1%)7.3 KiB
CodexLive turn WebSocket wire6.4 KiB6.4 KiB+9 B (+0.1%)7.8 KiB
CodexLive turn WebSocket decoded55.6 KiB55.6 KiB0 B (0.0%)66.4 KiB
CodexLive turn messages10100 (0.0%)21
ClaudeTotal thread wire13.3 KiB13.3 KiB+13 B (+0.1%)15.1 KiB
ClaudeThread snapshot wire6.9 KiB6.9 KiB−6 B (−0.1%)7.3 KiB
ClaudeLive turn WebSocket wire6.4 KiB6.4 KiB+19 B (+0.3%)7.8 KiB
ClaudeLive turn WebSocket decoded56.4 KiB56.4 KiB0 B (0.0%)66.4 KiB
ClaudeLive turn messages10100 (0.0%)21

Baseline: 80c708a · PR result: 7aff2b1 · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 109.4 KiB
  • Claude decoded thread snapshot: 110.1 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 7aff2b1

Macroscope's review found this PR approvable — This PR expands a server integration test to measure shell traffic, multiple clients, reconnects, and SQL activity. All changes are confined to test and reporting infrastructure, with no shipped production behavior or product-default changes.

Notes:

  • No code objects were reviewed. Approvability was decided on eligibility alone.

You can add or adjust custom eligibility rules. Learn more.

@t3dotgg
t3dotgg merged commit c37fd13 into mainSep 2, 2026
22 checks passed
@t3dotgg
t3dotgg deleted the t3code/transfer-budget-shell-and-multi-client branch September 2, 2026 02:16
github-actionsBot added a commit to omarcresp/t3code-flake that referenced this pull request Sep 2, 2026
## What's Changed
* perf(client-runtime): keep turn and checkpoint refs stable while streaming by @t3dotgg in pingdotgg/t3code#9145
* perf(clients): lease sidebar status by visibility by @StiensWout in pingdotgg/t3code#9052
* fix(desktop): show newest changes in nightly previews by @t3dotgg in pingdotgg/t3code#9138
* fix(settings): sync auto-settle and other shared preferences across environments by @t3dotgg in pingdotgg/t3code#9147
* fix(server): prevent accidental service downgrades by @t3dotgg in pingdotgg/t3code#5302
* fix(server): keep attachments until the command commits by @t3dotgg in pingdotgg/t3code#7941
* fix(claude): preview images read from the workspace by @t3dotgg in pingdotgg/t3code#9119
* fix(web): keep generated muted foreground dimmer than entered text by @flamboh in pingdotgg/t3code#9113
* fix(clients): stop repeating expanded commands by @t3dotgg in pingdotgg/t3code#9120
* fix(grok): health check, model selection, and stop all work against the real CLI by @t3dotgg in pingdotgg/t3code#9154
* perf(web): halve the cold-start bundle by splitting Clerk and cold routes by @StiensWout in pingdotgg/t3code#9058
* feat(desktop): update the desktop app on remote Macs from the Update button by @t3dotgg in pingdotgg/t3code#6554
* test(server): measure shell, second client, and reconnect transfer by @t3dotgg in pingdotgg/t3code#9157
* fix(web): project default model works on the hosted app by @juliusmarminge in pingdotgg/t3code#9142
* fix(web): darken neutral control surfaces by @maria-rcks in pingdotgg/t3code#9064
* fix(web): preserve panel state across workspace refreshes by @maria-rcks in pingdotgg/t3code#8968
* feat(files): open markdown, HTML, and PDF files outside the workspace by @juliusmarminge in pingdotgg/t3code#9140
* feat(web): render HTML and PDF files in the file viewer by @juliusmarminge in pingdotgg/t3code#9143
* fix(web): compact project settings actions by @maria-rcks in pingdotgg/t3code#9160
* fix(web): browse folders from file breadcrumbs by @404khai in pingdotgg/t3code#8910
## New Contributors
* @404khai made their first contribution in pingdotgg/t3code#8910
**Full Changelog**: pingdotgg/t3code@v0.0.39-nightly.20260902.1252...v0.0.39-nightly.20260902.1253
Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.39-nightly.20260902.1253
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

test(server): measure shell, second client, and reconnect transfer - #9157

Merged
t3dotgg merged 1 commit into
mainfrom
t3code/transfer-budget-shell-and-multi-client
Sep 2, 2026
Merged

test(server): measure shell, second client, and reconnect transfer#9157
t3dotgg merged 1 commit into
mainfrom
t3code/transfer-budget-shell-and-multi-client

Conversation

@t3dotgg

@t3dotggt3dotgg commented Sep 2, 2026

Copy link
Copy Markdown
Member

The transfer budget measured one thread subscription during one turn. Real clients also hold the sidebar (shell) subscription, users often have a desktop and a phone connected at once, and clients reconnect. Nobody had measured those, and the larger perf proposals (sharing the sidebar projector across clients, sharing git services across connections, incremental history) are gated on knowing whether they matter.

This PR measures them in the same test and prints them next to the existing capped rows. The single-thread measurement and its caps are unchanged.

What it adds:

  • A shell-only socket and a second client socket holding both the thread and shell subscriptions during the measured turn. The report shows per-socket wire bytes, decoded bytes, message counts, and total server egress.
  • A reconnect after the turn. The second client disconnects and resubscribes each subscription from the cursor it held before the turn. The report shows catch-up bytes and whether the server chose replay or a snapshot reset.
  • A SQL statement count from sql.execute spans. A counting tracer is installed on the harness runtime and the HTTP/WS app so reactor writes and subscription reads land in one total. No new instrumentation in src/.
  • openMeasuredWsClient opens each RPC socket on its own child scope so clients disconnect independently.

The new rows have no caps. The shell stream coalesces on a 50 ms window, so the second client's message count moved between 9 and 10 across runs and its wire bytes between 6.7 and 7.1 KiB. SQL statement counts moved between 1096 and 1167 for the same reason. The capped thread rows stayed within a few bytes.

Measured (local, one run):

ProviderPhaseMetricObservedBudgetResult
codexthread snapshotHTTP wire6.9 KiB (7,049 B)7.3 KiB (7,500 B)PASS
codexmeasured turnWebSocket wire6.3 KiB (6,401 B)7.8 KiB (8,000 B)PASS
codexmeasured turnWebSocket decoded54.7 KiB (55,974 B)66.4 KiB (68,000 B)PASS
codexmeasured turnWebSocket messages821PASS
codexshell snapshotHTTP wire829 BnoneINFO
codexmeasured turn, shellWebSocket wire628 BnoneINFO
codexmeasured turn, shellWebSocket decoded3.7 KiB (3,793 B)noneINFO
codexmeasured turn, shellWebSocket messages3noneINFO
codexmeasured turn, second clientWebSocket wire7.0 KiB (7,144 B)noneINFO
codexmeasured turn, second clientWebSocket decoded58.3 KiB (59,723 B)noneINFO
codexmeasured turn, second clientWebSocket messages10noneINFO
codexmeasured turnserver egress wire13.8 KiB (14,173 B)noneINFO
codexmeasured turnSQL statements1096noneINFO
codexreconnect, thread (replay)WebSocket wire6.2 KiB (6,325 B)noneINFO
codexreconnect, thread (replay)WebSocket decoded54.4 KiB (55,707 B)noneINFO
codexreconnect, thread (replay)WebSocket messages2noneINFO
codexreconnect, shell (replay)WebSocket wire386 BnoneINFO
codexreconnect, shell (replay)WebSocket decoded1.3 KiB (1,355 B)noneINFO
codexreconnect, shell (replay)WebSocket messages2noneINFO
codexreconnectSQL statements10noneINFO
claudeAgentthread snapshotHTTP wire6.9 KiB (7,059 B)7.3 KiB (7,500 B)PASS
claudeAgentmeasured turnWebSocket wire6.3 KiB (6,409 B)7.8 KiB (8,000 B)PASS
claudeAgentmeasured turnWebSocket decoded55.5 KiB (56,806 B)66.4 KiB (68,000 B)PASS
claudeAgentmeasured turnWebSocket messages821PASS
claudeAgentshell snapshotHTTP wire829 BnoneINFO
claudeAgentmeasured turn, shellWebSocket wire626 BnoneINFO
claudeAgentmeasured turn, shellWebSocket decoded3.8 KiB (3,877 B)noneINFO
claudeAgentmeasured turn, shellWebSocket messages3noneINFO
claudeAgentmeasured turn, second clientWebSocket wire7.0 KiB (7,161 B)noneINFO
claudeAgentmeasured turn, second clientWebSocket decoded59.2 KiB (60,602 B)noneINFO
claudeAgentmeasured turn, second clientWebSocket messages10noneINFO
claudeAgentmeasured turnserver egress wire13.9 KiB (14,196 B)noneINFO
claudeAgentmeasured turnSQL statements1096noneINFO
claudeAgentreconnect, thread (replay)WebSocket wire6.2 KiB (6,342 B)noneINFO
claudeAgentreconnect, thread (replay)WebSocket decoded55.2 KiB (56,539 B)noneINFO
claudeAgentreconnect, thread (replay)WebSocket messages2noneINFO
claudeAgentreconnect, shell (replay)WebSocket wire379 BnoneINFO
claudeAgentreconnect, shell (replay)WebSocket decoded1.4 KiB (1,383 B)noneINFO
claudeAgentreconnect, shell (replay)WebSocket messages2noneINFO
claudeAgentreconnectSQL statements10noneINFO

Reading the numbers:

  • The sidebar costs about 630 B wire and 3 messages per turn, about 10% of the thread stream. A second device costs one more thread stream plus one more shell stream, about 7 KiB. Egress scales linearly with connected clients and there is no hidden multiplier.
  • Reconnecting from the pre-turn cursor replays about the same bytes as live delivery (6.3 KiB thread, 380 B shell) in 2 messages each and 10 SQL statements total. Replay was chosen every time at this gap size. Snapshot fallback did not trigger.
  • This fixture mocks git, so it says nothing about sharing git services across connections.

Change authored by Claude Fable 5.1 running in Claude Code.


Note

Low Risk
Changes are confined to integration tests and reporting helpers; production server code is not modified.

Overview
Extends the thread transfer budget integration test so CI reports more than a single thread WebSocket during one turn. Existing capped thread snapshot and measured-turn rows are unchanged.

The scenario now opens three measured WebSocket clients (thread-only, shell-only, and a second device with both subscriptions), records shell HTTP snapshot size, and sums server egress across the three sockets. After the turn, the second client closes and resubscribes from its pre-turn cursors; the report records catch-up wire/decoded/message totals and whether catch-up used replay or snapshot.

Test harness plumbing adds openMeasuredWsClient (per-client forked scope + close), WebSocket recorder improvements (awaitOpen, wire totals after close), shared SQL statement counting via a counting Tracer on the orchestration harness and HTTP/WS app (sql.execute spans), and helpers moved into TransferBudgetScenario for thread/shell subscribe and sync detection. New report fields are INFO-only (no new budgets).

Reviewed by Cursor Bugbot for commit 7aff2b1. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Expand transfer-budget test to measure shell, second client, and reconnect transfer

  • Reworks the live transfer-budget integration test in server.test.ts to open three concurrent measured clients (thread-only, shell-only, second-client), capture per-socket WebSocket transfer and server-wide sql.execute deltas, then close and reconnect the second client to measure replay-or-snapshot catch-up
  • Adds openMeasuredWsClient, a factory that forks a per-client child scope, builds a counting WebSocket protocol, waits for open (10s timeout defect), and returns an explicit close effect
  • Updates makeWebSocketTransferRecorder to retain the underlying transport at open time so wire-byte totals remain readable after socket closure
  • Adds makeSqlStatementCounter, a tracer that increments a counter for spans named exactly sql.execute while returning native spans for all operations
  • Extends formatTransferBudgetReport with informational (uncapped) rows for shell snapshot, shell-only and second-client WebSocket diagnostics, aggregate server egress, SQL counts, and reconnect catch-up modes alongside existing capped thread rows
  • Adds subscription helpers subscribeThreadItems, subscribeShellItems, and awaitSubscriptionSynchronized in TransferBudgetScenario.integration.ts that run scoped subscriptions and classify initial catch-up as replay or snapshot
  • Risk: makeWebSocketTransferRecorder open wait fails with a timeout defect after 10 seconds; awaitSubscriptionSynchronized similarly defects after 10 seconds if the synchronization marker never arrives

Macroscope summarized 7aff2b1.

The transfer budget measured one thread subscription. Real clients also hold
a sidebar subscription, often run on two devices, and reconnect. Measure all
three on the same turn and print them next to the capped thread rows, plus a
SQL statement count from sql.execute spans.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Sep 2, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ProviderMetricMain baselineThis PRImpactPR ceiling
CodexTotal thread wire13.3 KiB13.3 KiB+15 B (+0.1%)15.1 KiB
CodexThread snapshot wire6.9 KiB6.9 KiB+6 B (+0.1%)7.3 KiB
CodexLive turn WebSocket wire6.4 KiB6.4 KiB+9 B (+0.1%)7.8 KiB
CodexLive turn WebSocket decoded55.6 KiB55.6 KiB0 B (0.0%)66.4 KiB
CodexLive turn messages10100 (0.0%)21
ClaudeTotal thread wire13.3 KiB13.3 KiB+13 B (+0.1%)15.1 KiB
ClaudeThread snapshot wire6.9 KiB6.9 KiB−6 B (−0.1%)7.3 KiB
ClaudeLive turn WebSocket wire6.4 KiB6.4 KiB+19 B (+0.3%)7.8 KiB
ClaudeLive turn WebSocket decoded56.4 KiB56.4 KiB0 B (0.0%)66.4 KiB
ClaudeLive turn messages10100 (0.0%)21

Baseline: 80c708a · PR result: 7aff2b1 · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 109.4 KiB
  • Claude decoded thread snapshot: 110.1 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 7aff2b1

Macroscope's review found this PR approvable — This PR expands a server integration test to measure shell traffic, multiple clients, reconnects, and SQL activity. All changes are confined to test and reporting infrastructure, with no shipped production behavior or product-default changes.

Notes:

  • No code objects were reviewed. Approvability was decided on eligibility alone.

You can add or adjust custom eligibility rules. Learn more.

@t3dotgg
t3dotgg merged commit c37fd13 into mainSep 2, 2026
22 checks passed
@t3dotgg
t3dotgg deleted the t3code/transfer-budget-shell-and-multi-client branch September 2, 2026 02:16
github-actionsBot added a commit to omarcresp/t3code-flake that referenced this pull request Sep 2, 2026
## What's Changed
* perf(client-runtime): keep turn and checkpoint refs stable while streaming by @t3dotgg in pingdotgg/t3code#9145
* perf(clients): lease sidebar status by visibility by @StiensWout in pingdotgg/t3code#9052
* fix(desktop): show newest changes in nightly previews by @t3dotgg in pingdotgg/t3code#9138
* fix(settings): sync auto-settle and other shared preferences across environments by @t3dotgg in pingdotgg/t3code#9147
* fix(server): prevent accidental service downgrades by @t3dotgg in pingdotgg/t3code#5302
* fix(server): keep attachments until the command commits by @t3dotgg in pingdotgg/t3code#7941
* fix(claude): preview images read from the workspace by @t3dotgg in pingdotgg/t3code#9119
* fix(web): keep generated muted foreground dimmer than entered text by @flamboh in pingdotgg/t3code#9113
* fix(clients): stop repeating expanded commands by @t3dotgg in pingdotgg/t3code#9120
* fix(grok): health check, model selection, and stop all work against the real CLI by @t3dotgg in pingdotgg/t3code#9154
* perf(web): halve the cold-start bundle by splitting Clerk and cold routes by @StiensWout in pingdotgg/t3code#9058
* feat(desktop): update the desktop app on remote Macs from the Update button by @t3dotgg in pingdotgg/t3code#6554
* test(server): measure shell, second client, and reconnect transfer by @t3dotgg in pingdotgg/t3code#9157
* fix(web): project default model works on the hosted app by @juliusmarminge in pingdotgg/t3code#9142
* fix(web): darken neutral control surfaces by @maria-rcks in pingdotgg/t3code#9064
* fix(web): preserve panel state across workspace refreshes by @maria-rcks in pingdotgg/t3code#8968
* feat(files): open markdown, HTML, and PDF files outside the workspace by @juliusmarminge in pingdotgg/t3code#9140
* feat(web): render HTML and PDF files in the file viewer by @juliusmarminge in pingdotgg/t3code#9143
* fix(web): compact project settings actions by @maria-rcks in pingdotgg/t3code#9160
* fix(web): browse folders from file breadcrumbs by @404khai in pingdotgg/t3code#8910
## New Contributors
* @404khai made their first contribution in pingdotgg/t3code#8910
**Full Changelog**: pingdotgg/t3code@v0.0.39-nightly.20260902.1252...v0.0.39-nightly.20260902.1253
Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.39-nightly.20260902.1253
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

test(server): measure shell, second client, and reconnect transfer - #9157

Merged
t3dotgg merged 1 commit into
mainfrom
t3code/transfer-budget-shell-and-multi-client
Sep 2, 2026
Merged

test(server): measure shell, second client, and reconnect transfer#9157
t3dotgg merged 1 commit into
mainfrom
t3code/transfer-budget-shell-and-multi-client

Conversation

@t3dotgg

@t3dotggt3dotgg commented Sep 2, 2026

Copy link
Copy Markdown
Member

The transfer budget measured one thread subscription during one turn. Real clients also hold the sidebar (shell) subscription, users often have a desktop and a phone connected at once, and clients reconnect. Nobody had measured those, and the larger perf proposals (sharing the sidebar projector across clients, sharing git services across connections, incremental history) are gated on knowing whether they matter.

This PR measures them in the same test and prints them next to the existing capped rows. The single-thread measurement and its caps are unchanged.

What it adds:

  • A shell-only socket and a second client socket holding both the thread and shell subscriptions during the measured turn. The report shows per-socket wire bytes, decoded bytes, message counts, and total server egress.
  • A reconnect after the turn. The second client disconnects and resubscribes each subscription from the cursor it held before the turn. The report shows catch-up bytes and whether the server chose replay or a snapshot reset.
  • A SQL statement count from sql.execute spans. A counting tracer is installed on the harness runtime and the HTTP/WS app so reactor writes and subscription reads land in one total. No new instrumentation in src/.
  • openMeasuredWsClient opens each RPC socket on its own child scope so clients disconnect independently.

The new rows have no caps. The shell stream coalesces on a 50 ms window, so the second client's message count moved between 9 and 10 across runs and its wire bytes between 6.7 and 7.1 KiB. SQL statement counts moved between 1096 and 1167 for the same reason. The capped thread rows stayed within a few bytes.

Measured (local, one run):

ProviderPhaseMetricObservedBudgetResult
codexthread snapshotHTTP wire6.9 KiB (7,049 B)7.3 KiB (7,500 B)PASS
codexmeasured turnWebSocket wire6.3 KiB (6,401 B)7.8 KiB (8,000 B)PASS
codexmeasured turnWebSocket decoded54.7 KiB (55,974 B)66.4 KiB (68,000 B)PASS
codexmeasured turnWebSocket messages821PASS
codexshell snapshotHTTP wire829 BnoneINFO
codexmeasured turn, shellWebSocket wire628 BnoneINFO
codexmeasured turn, shellWebSocket decoded3.7 KiB (3,793 B)noneINFO
codexmeasured turn, shellWebSocket messages3noneINFO
codexmeasured turn, second clientWebSocket wire7.0 KiB (7,144 B)noneINFO
codexmeasured turn, second clientWebSocket decoded58.3 KiB (59,723 B)noneINFO
codexmeasured turn, second clientWebSocket messages10noneINFO
codexmeasured turnserver egress wire13.8 KiB (14,173 B)noneINFO
codexmeasured turnSQL statements1096noneINFO
codexreconnect, thread (replay)WebSocket wire6.2 KiB (6,325 B)noneINFO
codexreconnect, thread (replay)WebSocket decoded54.4 KiB (55,707 B)noneINFO
codexreconnect, thread (replay)WebSocket messages2noneINFO
codexreconnect, shell (replay)WebSocket wire386 BnoneINFO
codexreconnect, shell (replay)WebSocket decoded1.3 KiB (1,355 B)noneINFO
codexreconnect, shell (replay)WebSocket messages2noneINFO
codexreconnectSQL statements10noneINFO
claudeAgentthread snapshotHTTP wire6.9 KiB (7,059 B)7.3 KiB (7,500 B)PASS
claudeAgentmeasured turnWebSocket wire6.3 KiB (6,409 B)7.8 KiB (8,000 B)PASS
claudeAgentmeasured turnWebSocket decoded55.5 KiB (56,806 B)66.4 KiB (68,000 B)PASS
claudeAgentmeasured turnWebSocket messages821PASS
claudeAgentshell snapshotHTTP wire829 BnoneINFO
claudeAgentmeasured turn, shellWebSocket wire626 BnoneINFO
claudeAgentmeasured turn, shellWebSocket decoded3.8 KiB (3,877 B)noneINFO
claudeAgentmeasured turn, shellWebSocket messages3noneINFO
claudeAgentmeasured turn, second clientWebSocket wire7.0 KiB (7,161 B)noneINFO
claudeAgentmeasured turn, second clientWebSocket decoded59.2 KiB (60,602 B)noneINFO
claudeAgentmeasured turn, second clientWebSocket messages10noneINFO
claudeAgentmeasured turnserver egress wire13.9 KiB (14,196 B)noneINFO
claudeAgentmeasured turnSQL statements1096noneINFO
claudeAgentreconnect, thread (replay)WebSocket wire6.2 KiB (6,342 B)noneINFO
claudeAgentreconnect, thread (replay)WebSocket decoded55.2 KiB (56,539 B)noneINFO
claudeAgentreconnect, thread (replay)WebSocket messages2noneINFO
claudeAgentreconnect, shell (replay)WebSocket wire379 BnoneINFO
claudeAgentreconnect, shell (replay)WebSocket decoded1.4 KiB (1,383 B)noneINFO
claudeAgentreconnect, shell (replay)WebSocket messages2noneINFO
claudeAgentreconnectSQL statements10noneINFO

Reading the numbers:

  • The sidebar costs about 630 B wire and 3 messages per turn, about 10% of the thread stream. A second device costs one more thread stream plus one more shell stream, about 7 KiB. Egress scales linearly with connected clients and there is no hidden multiplier.
  • Reconnecting from the pre-turn cursor replays about the same bytes as live delivery (6.3 KiB thread, 380 B shell) in 2 messages each and 10 SQL statements total. Replay was chosen every time at this gap size. Snapshot fallback did not trigger.
  • This fixture mocks git, so it says nothing about sharing git services across connections.

Change authored by Claude Fable 5.1 running in Claude Code.


Note

Low Risk
Changes are confined to integration tests and reporting helpers; production server code is not modified.

Overview
Extends the thread transfer budget integration test so CI reports more than a single thread WebSocket during one turn. Existing capped thread snapshot and measured-turn rows are unchanged.

The scenario now opens three measured WebSocket clients (thread-only, shell-only, and a second device with both subscriptions), records shell HTTP snapshot size, and sums server egress across the three sockets. After the turn, the second client closes and resubscribes from its pre-turn cursors; the report records catch-up wire/decoded/message totals and whether catch-up used replay or snapshot.

Test harness plumbing adds openMeasuredWsClient (per-client forked scope + close), WebSocket recorder improvements (awaitOpen, wire totals after close), shared SQL statement counting via a counting Tracer on the orchestration harness and HTTP/WS app (sql.execute spans), and helpers moved into TransferBudgetScenario for thread/shell subscribe and sync detection. New report fields are INFO-only (no new budgets).

Reviewed by Cursor Bugbot for commit 7aff2b1. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Expand transfer-budget test to measure shell, second client, and reconnect transfer

  • Reworks the live transfer-budget integration test in server.test.ts to open three concurrent measured clients (thread-only, shell-only, second-client), capture per-socket WebSocket transfer and server-wide sql.execute deltas, then close and reconnect the second client to measure replay-or-snapshot catch-up
  • Adds openMeasuredWsClient, a factory that forks a per-client child scope, builds a counting WebSocket protocol, waits for open (10s timeout defect), and returns an explicit close effect
  • Updates makeWebSocketTransferRecorder to retain the underlying transport at open time so wire-byte totals remain readable after socket closure
  • Adds makeSqlStatementCounter, a tracer that increments a counter for spans named exactly sql.execute while returning native spans for all operations
  • Extends formatTransferBudgetReport with informational (uncapped) rows for shell snapshot, shell-only and second-client WebSocket diagnostics, aggregate server egress, SQL counts, and reconnect catch-up modes alongside existing capped thread rows
  • Adds subscription helpers subscribeThreadItems, subscribeShellItems, and awaitSubscriptionSynchronized in TransferBudgetScenario.integration.ts that run scoped subscriptions and classify initial catch-up as replay or snapshot
  • Risk: makeWebSocketTransferRecorder open wait fails with a timeout defect after 10 seconds; awaitSubscriptionSynchronized similarly defects after 10 seconds if the synchronization marker never arrives

Macroscope summarized 7aff2b1.

The transfer budget measured one thread subscription. Real clients also hold
a sidebar subscription, often run on two devices, and reconnect. Measure all
three on the same turn and print them next to the capped thread rows, plus a
SQL statement count from sql.execute spans.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Sep 2, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ProviderMetricMain baselineThis PRImpactPR ceiling
CodexTotal thread wire13.3 KiB13.3 KiB+15 B (+0.1%)15.1 KiB
CodexThread snapshot wire6.9 KiB6.9 KiB+6 B (+0.1%)7.3 KiB
CodexLive turn WebSocket wire6.4 KiB6.4 KiB+9 B (+0.1%)7.8 KiB
CodexLive turn WebSocket decoded55.6 KiB55.6 KiB0 B (0.0%)66.4 KiB
CodexLive turn messages10100 (0.0%)21
ClaudeTotal thread wire13.3 KiB13.3 KiB+13 B (+0.1%)15.1 KiB
ClaudeThread snapshot wire6.9 KiB6.9 KiB−6 B (−0.1%)7.3 KiB
ClaudeLive turn WebSocket wire6.4 KiB6.4 KiB+19 B (+0.3%)7.8 KiB
ClaudeLive turn WebSocket decoded56.4 KiB56.4 KiB0 B (0.0%)66.4 KiB
ClaudeLive turn messages10100 (0.0%)21

Baseline: 80c708a · PR result: 7aff2b1 · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 109.4 KiB
  • Claude decoded thread snapshot: 110.1 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 7aff2b1

Macroscope's review found this PR approvable — This PR expands a server integration test to measure shell traffic, multiple clients, reconnects, and SQL activity. All changes are confined to test and reporting infrastructure, with no shipped production behavior or product-default changes.

Notes:

  • No code objects were reviewed. Approvability was decided on eligibility alone.

You can add or adjust custom eligibility rules. Learn more.

@t3dotgg
t3dotgg merged commit c37fd13 into mainSep 2, 2026
22 checks passed
@t3dotgg
t3dotgg deleted the t3code/transfer-budget-shell-and-multi-client branch September 2, 2026 02:16
github-actionsBot added a commit to omarcresp/t3code-flake that referenced this pull request Sep 2, 2026
## What's Changed
* perf(client-runtime): keep turn and checkpoint refs stable while streaming by @t3dotgg in pingdotgg/t3code#9145
* perf(clients): lease sidebar status by visibility by @StiensWout in pingdotgg/t3code#9052
* fix(desktop): show newest changes in nightly previews by @t3dotgg in pingdotgg/t3code#9138
* fix(settings): sync auto-settle and other shared preferences across environments by @t3dotgg in pingdotgg/t3code#9147
* fix(server): prevent accidental service downgrades by @t3dotgg in pingdotgg/t3code#5302
* fix(server): keep attachments until the command commits by @t3dotgg in pingdotgg/t3code#7941
* fix(claude): preview images read from the workspace by @t3dotgg in pingdotgg/t3code#9119
* fix(web): keep generated muted foreground dimmer than entered text by @flamboh in pingdotgg/t3code#9113
* fix(clients): stop repeating expanded commands by @t3dotgg in pingdotgg/t3code#9120
* fix(grok): health check, model selection, and stop all work against the real CLI by @t3dotgg in pingdotgg/t3code#9154
* perf(web): halve the cold-start bundle by splitting Clerk and cold routes by @StiensWout in pingdotgg/t3code#9058
* feat(desktop): update the desktop app on remote Macs from the Update button by @t3dotgg in pingdotgg/t3code#6554
* test(server): measure shell, second client, and reconnect transfer by @t3dotgg in pingdotgg/t3code#9157
* fix(web): project default model works on the hosted app by @juliusmarminge in pingdotgg/t3code#9142
* fix(web): darken neutral control surfaces by @maria-rcks in pingdotgg/t3code#9064
* fix(web): preserve panel state across workspace refreshes by @maria-rcks in pingdotgg/t3code#8968
* feat(files): open markdown, HTML, and PDF files outside the workspace by @juliusmarminge in pingdotgg/t3code#9140
* feat(web): render HTML and PDF files in the file viewer by @juliusmarminge in pingdotgg/t3code#9143
* fix(web): compact project settings actions by @maria-rcks in pingdotgg/t3code#9160
* fix(web): browse folders from file breadcrumbs by @404khai in pingdotgg/t3code#8910
## New Contributors
* @404khai made their first contribution in pingdotgg/t3code#8910
**Full Changelog**: pingdotgg/t3code@v0.0.39-nightly.20260902.1252...v0.0.39-nightly.20260902.1253
Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.39-nightly.20260902.1253
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

test(server): measure shell, second client, and reconnect transfer - #9157

Merged
t3dotgg merged 1 commit into
mainfrom
t3code/transfer-budget-shell-and-multi-client
Sep 2, 2026
Merged

test(server): measure shell, second client, and reconnect transfer#9157
t3dotgg merged 1 commit into
mainfrom
t3code/transfer-budget-shell-and-multi-client

Conversation

@t3dotgg

@t3dotggt3dotgg commented Sep 2, 2026

Copy link
Copy Markdown
Member

The transfer budget measured one thread subscription during one turn. Real clients also hold the sidebar (shell) subscription, users often have a desktop and a phone connected at once, and clients reconnect. Nobody had measured those, and the larger perf proposals (sharing the sidebar projector across clients, sharing git services across connections, incremental history) are gated on knowing whether they matter.

This PR measures them in the same test and prints them next to the existing capped rows. The single-thread measurement and its caps are unchanged.

What it adds:

  • A shell-only socket and a second client socket holding both the thread and shell subscriptions during the measured turn. The report shows per-socket wire bytes, decoded bytes, message counts, and total server egress.
  • A reconnect after the turn. The second client disconnects and resubscribes each subscription from the cursor it held before the turn. The report shows catch-up bytes and whether the server chose replay or a snapshot reset.
  • A SQL statement count from sql.execute spans. A counting tracer is installed on the harness runtime and the HTTP/WS app so reactor writes and subscription reads land in one total. No new instrumentation in src/.
  • openMeasuredWsClient opens each RPC socket on its own child scope so clients disconnect independently.

The new rows have no caps. The shell stream coalesces on a 50 ms window, so the second client's message count moved between 9 and 10 across runs and its wire bytes between 6.7 and 7.1 KiB. SQL statement counts moved between 1096 and 1167 for the same reason. The capped thread rows stayed within a few bytes.

Measured (local, one run):

ProviderPhaseMetricObservedBudgetResult
codexthread snapshotHTTP wire6.9 KiB (7,049 B)7.3 KiB (7,500 B)PASS
codexmeasured turnWebSocket wire6.3 KiB (6,401 B)7.8 KiB (8,000 B)PASS
codexmeasured turnWebSocket decoded54.7 KiB (55,974 B)66.4 KiB (68,000 B)PASS
codexmeasured turnWebSocket messages821PASS
codexshell snapshotHTTP wire829 BnoneINFO
codexmeasured turn, shellWebSocket wire628 BnoneINFO
codexmeasured turn, shellWebSocket decoded3.7 KiB (3,793 B)noneINFO
codexmeasured turn, shellWebSocket messages3noneINFO
codexmeasured turn, second clientWebSocket wire7.0 KiB (7,144 B)noneINFO
codexmeasured turn, second clientWebSocket decoded58.3 KiB (59,723 B)noneINFO
codexmeasured turn, second clientWebSocket messages10noneINFO
codexmeasured turnserver egress wire13.8 KiB (14,173 B)noneINFO
codexmeasured turnSQL statements1096noneINFO
codexreconnect, thread (replay)WebSocket wire6.2 KiB (6,325 B)noneINFO
codexreconnect, thread (replay)WebSocket decoded54.4 KiB (55,707 B)noneINFO
codexreconnect, thread (replay)WebSocket messages2noneINFO
codexreconnect, shell (replay)WebSocket wire386 BnoneINFO
codexreconnect, shell (replay)WebSocket decoded1.3 KiB (1,355 B)noneINFO
codexreconnect, shell (replay)WebSocket messages2noneINFO
codexreconnectSQL statements10noneINFO
claudeAgentthread snapshotHTTP wire6.9 KiB (7,059 B)7.3 KiB (7,500 B)PASS
claudeAgentmeasured turnWebSocket wire6.3 KiB (6,409 B)7.8 KiB (8,000 B)PASS
claudeAgentmeasured turnWebSocket decoded55.5 KiB (56,806 B)66.4 KiB (68,000 B)PASS
claudeAgentmeasured turnWebSocket messages821PASS
claudeAgentshell snapshotHTTP wire829 BnoneINFO
claudeAgentmeasured turn, shellWebSocket wire626 BnoneINFO
claudeAgentmeasured turn, shellWebSocket decoded3.8 KiB (3,877 B)noneINFO
claudeAgentmeasured turn, shellWebSocket messages3noneINFO
claudeAgentmeasured turn, second clientWebSocket wire7.0 KiB (7,161 B)noneINFO
claudeAgentmeasured turn, second clientWebSocket decoded59.2 KiB (60,602 B)noneINFO
claudeAgentmeasured turn, second clientWebSocket messages10noneINFO
claudeAgentmeasured turnserver egress wire13.9 KiB (14,196 B)noneINFO
claudeAgentmeasured turnSQL statements1096noneINFO
claudeAgentreconnect, thread (replay)WebSocket wire6.2 KiB (6,342 B)noneINFO
claudeAgentreconnect, thread (replay)WebSocket decoded55.2 KiB (56,539 B)noneINFO
claudeAgentreconnect, thread (replay)WebSocket messages2noneINFO
claudeAgentreconnect, shell (replay)WebSocket wire379 BnoneINFO
claudeAgentreconnect, shell (replay)WebSocket decoded1.4 KiB (1,383 B)noneINFO
claudeAgentreconnect, shell (replay)WebSocket messages2noneINFO
claudeAgentreconnectSQL statements10noneINFO

Reading the numbers:

  • The sidebar costs about 630 B wire and 3 messages per turn, about 10% of the thread stream. A second device costs one more thread stream plus one more shell stream, about 7 KiB. Egress scales linearly with connected clients and there is no hidden multiplier.
  • Reconnecting from the pre-turn cursor replays about the same bytes as live delivery (6.3 KiB thread, 380 B shell) in 2 messages each and 10 SQL statements total. Replay was chosen every time at this gap size. Snapshot fallback did not trigger.
  • This fixture mocks git, so it says nothing about sharing git services across connections.

Change authored by Claude Fable 5.1 running in Claude Code.


Note

Low Risk
Changes are confined to integration tests and reporting helpers; production server code is not modified.

Overview
Extends the thread transfer budget integration test so CI reports more than a single thread WebSocket during one turn. Existing capped thread snapshot and measured-turn rows are unchanged.

The scenario now opens three measured WebSocket clients (thread-only, shell-only, and a second device with both subscriptions), records shell HTTP snapshot size, and sums server egress across the three sockets. After the turn, the second client closes and resubscribes from its pre-turn cursors; the report records catch-up wire/decoded/message totals and whether catch-up used replay or snapshot.

Test harness plumbing adds openMeasuredWsClient (per-client forked scope + close), WebSocket recorder improvements (awaitOpen, wire totals after close), shared SQL statement counting via a counting Tracer on the orchestration harness and HTTP/WS app (sql.execute spans), and helpers moved into TransferBudgetScenario for thread/shell subscribe and sync detection. New report fields are INFO-only (no new budgets).

Reviewed by Cursor Bugbot for commit 7aff2b1. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Expand transfer-budget test to measure shell, second client, and reconnect transfer

  • Reworks the live transfer-budget integration test in server.test.ts to open three concurrent measured clients (thread-only, shell-only, second-client), capture per-socket WebSocket transfer and server-wide sql.execute deltas, then close and reconnect the second client to measure replay-or-snapshot catch-up
  • Adds openMeasuredWsClient, a factory that forks a per-client child scope, builds a counting WebSocket protocol, waits for open (10s timeout defect), and returns an explicit close effect
  • Updates makeWebSocketTransferRecorder to retain the underlying transport at open time so wire-byte totals remain readable after socket closure
  • Adds makeSqlStatementCounter, a tracer that increments a counter for spans named exactly sql.execute while returning native spans for all operations
  • Extends formatTransferBudgetReport with informational (uncapped) rows for shell snapshot, shell-only and second-client WebSocket diagnostics, aggregate server egress, SQL counts, and reconnect catch-up modes alongside existing capped thread rows
  • Adds subscription helpers subscribeThreadItems, subscribeShellItems, and awaitSubscriptionSynchronized in TransferBudgetScenario.integration.ts that run scoped subscriptions and classify initial catch-up as replay or snapshot
  • Risk: makeWebSocketTransferRecorder open wait fails with a timeout defect after 10 seconds; awaitSubscriptionSynchronized similarly defects after 10 seconds if the synchronization marker never arrives

Macroscope summarized 7aff2b1.

The transfer budget measured one thread subscription. Real clients also hold
a sidebar subscription, often run on two devices, and reconnect. Measure all
three on the same turn and print them next to the capped thread rows, plus a
SQL statement count from sql.execute spans.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Sep 2, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ProviderMetricMain baselineThis PRImpactPR ceiling
CodexTotal thread wire13.3 KiB13.3 KiB+15 B (+0.1%)15.1 KiB
CodexThread snapshot wire6.9 KiB6.9 KiB+6 B (+0.1%)7.3 KiB
CodexLive turn WebSocket wire6.4 KiB6.4 KiB+9 B (+0.1%)7.8 KiB
CodexLive turn WebSocket decoded55.6 KiB55.6 KiB0 B (0.0%)66.4 KiB
CodexLive turn messages10100 (0.0%)21
ClaudeTotal thread wire13.3 KiB13.3 KiB+13 B (+0.1%)15.1 KiB
ClaudeThread snapshot wire6.9 KiB6.9 KiB−6 B (−0.1%)7.3 KiB
ClaudeLive turn WebSocket wire6.4 KiB6.4 KiB+19 B (+0.3%)7.8 KiB
ClaudeLive turn WebSocket decoded56.4 KiB56.4 KiB0 B (0.0%)66.4 KiB
ClaudeLive turn messages10100 (0.0%)21

Baseline: 80c708a · PR result: 7aff2b1 · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 109.4 KiB
  • Claude decoded thread snapshot: 110.1 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 7aff2b1

Macroscope's review found this PR approvable — This PR expands a server integration test to measure shell traffic, multiple clients, reconnects, and SQL activity. All changes are confined to test and reporting infrastructure, with no shipped production behavior or product-default changes.

Notes:

  • No code objects were reviewed. Approvability was decided on eligibility alone.

You can add or adjust custom eligibility rules. Learn more.

@t3dotgg
t3dotgg merged commit c37fd13 into mainSep 2, 2026
22 checks passed
@t3dotgg
t3dotgg deleted the t3code/transfer-budget-shell-and-multi-client branch September 2, 2026 02:16
github-actionsBot added a commit to omarcresp/t3code-flake that referenced this pull request Sep 2, 2026
## What's Changed
* perf(client-runtime): keep turn and checkpoint refs stable while streaming by @t3dotgg in pingdotgg/t3code#9145
* perf(clients): lease sidebar status by visibility by @StiensWout in pingdotgg/t3code#9052
* fix(desktop): show newest changes in nightly previews by @t3dotgg in pingdotgg/t3code#9138
* fix(settings): sync auto-settle and other shared preferences across environments by @t3dotgg in pingdotgg/t3code#9147
* fix(server): prevent accidental service downgrades by @t3dotgg in pingdotgg/t3code#5302
* fix(server): keep attachments until the command commits by @t3dotgg in pingdotgg/t3code#7941
* fix(claude): preview images read from the workspace by @t3dotgg in pingdotgg/t3code#9119
* fix(web): keep generated muted foreground dimmer than entered text by @flamboh in pingdotgg/t3code#9113
* fix(clients): stop repeating expanded commands by @t3dotgg in pingdotgg/t3code#9120
* fix(grok): health check, model selection, and stop all work against the real CLI by @t3dotgg in pingdotgg/t3code#9154
* perf(web): halve the cold-start bundle by splitting Clerk and cold routes by @StiensWout in pingdotgg/t3code#9058
* feat(desktop): update the desktop app on remote Macs from the Update button by @t3dotgg in pingdotgg/t3code#6554
* test(server): measure shell, second client, and reconnect transfer by @t3dotgg in pingdotgg/t3code#9157
* fix(web): project default model works on the hosted app by @juliusmarminge in pingdotgg/t3code#9142
* fix(web): darken neutral control surfaces by @maria-rcks in pingdotgg/t3code#9064
* fix(web): preserve panel state across workspace refreshes by @maria-rcks in pingdotgg/t3code#8968
* feat(files): open markdown, HTML, and PDF files outside the workspace by @juliusmarminge in pingdotgg/t3code#9140
* feat(web): render HTML and PDF files in the file viewer by @juliusmarminge in pingdotgg/t3code#9143
* fix(web): compact project settings actions by @maria-rcks in pingdotgg/t3code#9160
* fix(web): browse folders from file breadcrumbs by @404khai in pingdotgg/t3code#8910
## New Contributors
* @404khai made their first contribution in pingdotgg/t3code#8910
**Full Changelog**: pingdotgg/t3code@v0.0.39-nightly.20260902.1252...v0.0.39-nightly.20260902.1253
Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.39-nightly.20260902.1253
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

test(server): measure shell, second client, and reconnect transfer - #9157

Merged
t3dotgg merged 1 commit into
mainfrom
t3code/transfer-budget-shell-and-multi-client
Sep 2, 2026
Merged

test(server): measure shell, second client, and reconnect transfer#9157
t3dotgg merged 1 commit into
mainfrom
t3code/transfer-budget-shell-and-multi-client

Conversation

@t3dotgg

@t3dotggt3dotgg commented Sep 2, 2026

Copy link
Copy Markdown
Member

The transfer budget measured one thread subscription during one turn. Real clients also hold the sidebar (shell) subscription, users often have a desktop and a phone connected at once, and clients reconnect. Nobody had measured those, and the larger perf proposals (sharing the sidebar projector across clients, sharing git services across connections, incremental history) are gated on knowing whether they matter.

This PR measures them in the same test and prints them next to the existing capped rows. The single-thread measurement and its caps are unchanged.

What it adds:

  • A shell-only socket and a second client socket holding both the thread and shell subscriptions during the measured turn. The report shows per-socket wire bytes, decoded bytes, message counts, and total server egress.
  • A reconnect after the turn. The second client disconnects and resubscribes each subscription from the cursor it held before the turn. The report shows catch-up bytes and whether the server chose replay or a snapshot reset.
  • A SQL statement count from sql.execute spans. A counting tracer is installed on the harness runtime and the HTTP/WS app so reactor writes and subscription reads land in one total. No new instrumentation in src/.
  • openMeasuredWsClient opens each RPC socket on its own child scope so clients disconnect independently.

The new rows have no caps. The shell stream coalesces on a 50 ms window, so the second client's message count moved between 9 and 10 across runs and its wire bytes between 6.7 and 7.1 KiB. SQL statement counts moved between 1096 and 1167 for the same reason. The capped thread rows stayed within a few bytes.

Measured (local, one run):

ProviderPhaseMetricObservedBudgetResult
codexthread snapshotHTTP wire6.9 KiB (7,049 B)7.3 KiB (7,500 B)PASS
codexmeasured turnWebSocket wire6.3 KiB (6,401 B)7.8 KiB (8,000 B)PASS
codexmeasured turnWebSocket decoded54.7 KiB (55,974 B)66.4 KiB (68,000 B)PASS
codexmeasured turnWebSocket messages821PASS
codexshell snapshotHTTP wire829 BnoneINFO
codexmeasured turn, shellWebSocket wire628 BnoneINFO
codexmeasured turn, shellWebSocket decoded3.7 KiB (3,793 B)noneINFO
codexmeasured turn, shellWebSocket messages3noneINFO
codexmeasured turn, second clientWebSocket wire7.0 KiB (7,144 B)noneINFO
codexmeasured turn, second clientWebSocket decoded58.3 KiB (59,723 B)noneINFO
codexmeasured turn, second clientWebSocket messages10noneINFO
codexmeasured turnserver egress wire13.8 KiB (14,173 B)noneINFO
codexmeasured turnSQL statements1096noneINFO
codexreconnect, thread (replay)WebSocket wire6.2 KiB (6,325 B)noneINFO
codexreconnect, thread (replay)WebSocket decoded54.4 KiB (55,707 B)noneINFO
codexreconnect, thread (replay)WebSocket messages2noneINFO
codexreconnect, shell (replay)WebSocket wire386 BnoneINFO
codexreconnect, shell (replay)WebSocket decoded1.3 KiB (1,355 B)noneINFO
codexreconnect, shell (replay)WebSocket messages2noneINFO
codexreconnectSQL statements10noneINFO
claudeAgentthread snapshotHTTP wire6.9 KiB (7,059 B)7.3 KiB (7,500 B)PASS
claudeAgentmeasured turnWebSocket wire6.3 KiB (6,409 B)7.8 KiB (8,000 B)PASS
claudeAgentmeasured turnWebSocket decoded55.5 KiB (56,806 B)66.4 KiB (68,000 B)PASS
claudeAgentmeasured turnWebSocket messages821PASS
claudeAgentshell snapshotHTTP wire829 BnoneINFO
claudeAgentmeasured turn, shellWebSocket wire626 BnoneINFO
claudeAgentmeasured turn, shellWebSocket decoded3.8 KiB (3,877 B)noneINFO
claudeAgentmeasured turn, shellWebSocket messages3noneINFO
claudeAgentmeasured turn, second clientWebSocket wire7.0 KiB (7,161 B)noneINFO
claudeAgentmeasured turn, second clientWebSocket decoded59.2 KiB (60,602 B)noneINFO
claudeAgentmeasured turn, second clientWebSocket messages10noneINFO
claudeAgentmeasured turnserver egress wire13.9 KiB (14,196 B)noneINFO
claudeAgentmeasured turnSQL statements1096noneINFO
claudeAgentreconnect, thread (replay)WebSocket wire6.2 KiB (6,342 B)noneINFO
claudeAgentreconnect, thread (replay)WebSocket decoded55.2 KiB (56,539 B)noneINFO
claudeAgentreconnect, thread (replay)WebSocket messages2noneINFO
claudeAgentreconnect, shell (replay)WebSocket wire379 BnoneINFO
claudeAgentreconnect, shell (replay)WebSocket decoded1.4 KiB (1,383 B)noneINFO
claudeAgentreconnect, shell (replay)WebSocket messages2noneINFO
claudeAgentreconnectSQL statements10noneINFO

Reading the numbers:

  • The sidebar costs about 630 B wire and 3 messages per turn, about 10% of the thread stream. A second device costs one more thread stream plus one more shell stream, about 7 KiB. Egress scales linearly with connected clients and there is no hidden multiplier.
  • Reconnecting from the pre-turn cursor replays about the same bytes as live delivery (6.3 KiB thread, 380 B shell) in 2 messages each and 10 SQL statements total. Replay was chosen every time at this gap size. Snapshot fallback did not trigger.
  • This fixture mocks git, so it says nothing about sharing git services across connections.

Change authored by Claude Fable 5.1 running in Claude Code.


Note

Low Risk
Changes are confined to integration tests and reporting helpers; production server code is not modified.

Overview
Extends the thread transfer budget integration test so CI reports more than a single thread WebSocket during one turn. Existing capped thread snapshot and measured-turn rows are unchanged.

The scenario now opens three measured WebSocket clients (thread-only, shell-only, and a second device with both subscriptions), records shell HTTP snapshot size, and sums server egress across the three sockets. After the turn, the second client closes and resubscribes from its pre-turn cursors; the report records catch-up wire/decoded/message totals and whether catch-up used replay or snapshot.

Test harness plumbing adds openMeasuredWsClient (per-client forked scope + close), WebSocket recorder improvements (awaitOpen, wire totals after close), shared SQL statement counting via a counting Tracer on the orchestration harness and HTTP/WS app (sql.execute spans), and helpers moved into TransferBudgetScenario for thread/shell subscribe and sync detection. New report fields are INFO-only (no new budgets).

Reviewed by Cursor Bugbot for commit 7aff2b1. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Expand transfer-budget test to measure shell, second client, and reconnect transfer

  • Reworks the live transfer-budget integration test in server.test.ts to open three concurrent measured clients (thread-only, shell-only, second-client), capture per-socket WebSocket transfer and server-wide sql.execute deltas, then close and reconnect the second client to measure replay-or-snapshot catch-up
  • Adds openMeasuredWsClient, a factory that forks a per-client child scope, builds a counting WebSocket protocol, waits for open (10s timeout defect), and returns an explicit close effect
  • Updates makeWebSocketTransferRecorder to retain the underlying transport at open time so wire-byte totals remain readable after socket closure
  • Adds makeSqlStatementCounter, a tracer that increments a counter for spans named exactly sql.execute while returning native spans for all operations
  • Extends formatTransferBudgetReport with informational (uncapped) rows for shell snapshot, shell-only and second-client WebSocket diagnostics, aggregate server egress, SQL counts, and reconnect catch-up modes alongside existing capped thread rows
  • Adds subscription helpers subscribeThreadItems, subscribeShellItems, and awaitSubscriptionSynchronized in TransferBudgetScenario.integration.ts that run scoped subscriptions and classify initial catch-up as replay or snapshot
  • Risk: makeWebSocketTransferRecorder open wait fails with a timeout defect after 10 seconds; awaitSubscriptionSynchronized similarly defects after 10 seconds if the synchronization marker never arrives

Macroscope summarized 7aff2b1.

The transfer budget measured one thread subscription. Real clients also hold
a sidebar subscription, often run on two devices, and reconnect. Measure all
three on the same turn and print them next to the capped thread rows, plus a
SQL statement count from sql.execute spans.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Sep 2, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ProviderMetricMain baselineThis PRImpactPR ceiling
CodexTotal thread wire13.3 KiB13.3 KiB+15 B (+0.1%)15.1 KiB
CodexThread snapshot wire6.9 KiB6.9 KiB+6 B (+0.1%)7.3 KiB
CodexLive turn WebSocket wire6.4 KiB6.4 KiB+9 B (+0.1%)7.8 KiB
CodexLive turn WebSocket decoded55.6 KiB55.6 KiB0 B (0.0%)66.4 KiB
CodexLive turn messages10100 (0.0%)21
ClaudeTotal thread wire13.3 KiB13.3 KiB+13 B (+0.1%)15.1 KiB
ClaudeThread snapshot wire6.9 KiB6.9 KiB−6 B (−0.1%)7.3 KiB
ClaudeLive turn WebSocket wire6.4 KiB6.4 KiB+19 B (+0.3%)7.8 KiB
ClaudeLive turn WebSocket decoded56.4 KiB56.4 KiB0 B (0.0%)66.4 KiB
ClaudeLive turn messages10100 (0.0%)21

Baseline: 80c708a · PR result: 7aff2b1 · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 109.4 KiB
  • Claude decoded thread snapshot: 110.1 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 7aff2b1

Macroscope's review found this PR approvable — This PR expands a server integration test to measure shell traffic, multiple clients, reconnects, and SQL activity. All changes are confined to test and reporting infrastructure, with no shipped production behavior or product-default changes.

Notes:

  • No code objects were reviewed. Approvability was decided on eligibility alone.

You can add or adjust custom eligibility rules. Learn more.

@t3dotgg
t3dotgg merged commit c37fd13 into mainSep 2, 2026
22 checks passed
@t3dotgg
t3dotgg deleted the t3code/transfer-budget-shell-and-multi-client branch September 2, 2026 02:16
github-actionsBot added a commit to omarcresp/t3code-flake that referenced this pull request Sep 2, 2026
## What's Changed
* perf(client-runtime): keep turn and checkpoint refs stable while streaming by @t3dotgg in pingdotgg/t3code#9145
* perf(clients): lease sidebar status by visibility by @StiensWout in pingdotgg/t3code#9052
* fix(desktop): show newest changes in nightly previews by @t3dotgg in pingdotgg/t3code#9138
* fix(settings): sync auto-settle and other shared preferences across environments by @t3dotgg in pingdotgg/t3code#9147
* fix(server): prevent accidental service downgrades by @t3dotgg in pingdotgg/t3code#5302
* fix(server): keep attachments until the command commits by @t3dotgg in pingdotgg/t3code#7941
* fix(claude): preview images read from the workspace by @t3dotgg in pingdotgg/t3code#9119
* fix(web): keep generated muted foreground dimmer than entered text by @flamboh in pingdotgg/t3code#9113
* fix(clients): stop repeating expanded commands by @t3dotgg in pingdotgg/t3code#9120
* fix(grok): health check, model selection, and stop all work against the real CLI by @t3dotgg in pingdotgg/t3code#9154
* perf(web): halve the cold-start bundle by splitting Clerk and cold routes by @StiensWout in pingdotgg/t3code#9058
* feat(desktop): update the desktop app on remote Macs from the Update button by @t3dotgg in pingdotgg/t3code#6554
* test(server): measure shell, second client, and reconnect transfer by @t3dotgg in pingdotgg/t3code#9157
* fix(web): project default model works on the hosted app by @juliusmarminge in pingdotgg/t3code#9142
* fix(web): darken neutral control surfaces by @maria-rcks in pingdotgg/t3code#9064
* fix(web): preserve panel state across workspace refreshes by @maria-rcks in pingdotgg/t3code#8968
* feat(files): open markdown, HTML, and PDF files outside the workspace by @juliusmarminge in pingdotgg/t3code#9140
* feat(web): render HTML and PDF files in the file viewer by @juliusmarminge in pingdotgg/t3code#9143
* fix(web): compact project settings actions by @maria-rcks in pingdotgg/t3code#9160
* fix(web): browse folders from file breadcrumbs by @404khai in pingdotgg/t3code#8910
## New Contributors
* @404khai made their first contribution in pingdotgg/t3code#8910
**Full Changelog**: pingdotgg/t3code@v0.0.39-nightly.20260902.1252...v0.0.39-nightly.20260902.1253
Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.39-nightly.20260902.1253
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

test(server): measure shell, second client, and reconnect transfer - #9157

Merged
t3dotgg merged 1 commit into
mainfrom
t3code/transfer-budget-shell-and-multi-client
Sep 2, 2026
Merged

test(server): measure shell, second client, and reconnect transfer#9157
t3dotgg merged 1 commit into
mainfrom
t3code/transfer-budget-shell-and-multi-client

Conversation

@t3dotgg

@t3dotggt3dotgg commented Sep 2, 2026

Copy link
Copy Markdown
Member

The transfer budget measured one thread subscription during one turn. Real clients also hold the sidebar (shell) subscription, users often have a desktop and a phone connected at once, and clients reconnect. Nobody had measured those, and the larger perf proposals (sharing the sidebar projector across clients, sharing git services across connections, incremental history) are gated on knowing whether they matter.

This PR measures them in the same test and prints them next to the existing capped rows. The single-thread measurement and its caps are unchanged.

What it adds:

  • A shell-only socket and a second client socket holding both the thread and shell subscriptions during the measured turn. The report shows per-socket wire bytes, decoded bytes, message counts, and total server egress.
  • A reconnect after the turn. The second client disconnects and resubscribes each subscription from the cursor it held before the turn. The report shows catch-up bytes and whether the server chose replay or a snapshot reset.
  • A SQL statement count from sql.execute spans. A counting tracer is installed on the harness runtime and the HTTP/WS app so reactor writes and subscription reads land in one total. No new instrumentation in src/.
  • openMeasuredWsClient opens each RPC socket on its own child scope so clients disconnect independently.

The new rows have no caps. The shell stream coalesces on a 50 ms window, so the second client's message count moved between 9 and 10 across runs and its wire bytes between 6.7 and 7.1 KiB. SQL statement counts moved between 1096 and 1167 for the same reason. The capped thread rows stayed within a few bytes.

Measured (local, one run):

ProviderPhaseMetricObservedBudgetResult
codexthread snapshotHTTP wire6.9 KiB (7,049 B)7.3 KiB (7,500 B)PASS
codexmeasured turnWebSocket wire6.3 KiB (6,401 B)7.8 KiB (8,000 B)PASS
codexmeasured turnWebSocket decoded54.7 KiB (55,974 B)66.4 KiB (68,000 B)PASS
codexmeasured turnWebSocket messages821PASS
codexshell snapshotHTTP wire829 BnoneINFO
codexmeasured turn, shellWebSocket wire628 BnoneINFO
codexmeasured turn, shellWebSocket decoded3.7 KiB (3,793 B)noneINFO
codexmeasured turn, shellWebSocket messages3noneINFO
codexmeasured turn, second clientWebSocket wire7.0 KiB (7,144 B)noneINFO
codexmeasured turn, second clientWebSocket decoded58.3 KiB (59,723 B)noneINFO
codexmeasured turn, second clientWebSocket messages10noneINFO
codexmeasured turnserver egress wire13.8 KiB (14,173 B)noneINFO
codexmeasured turnSQL statements1096noneINFO
codexreconnect, thread (replay)WebSocket wire6.2 KiB (6,325 B)noneINFO
codexreconnect, thread (replay)WebSocket decoded54.4 KiB (55,707 B)noneINFO
codexreconnect, thread (replay)WebSocket messages2noneINFO
codexreconnect, shell (replay)WebSocket wire386 BnoneINFO
codexreconnect, shell (replay)WebSocket decoded1.3 KiB (1,355 B)noneINFO
codexreconnect, shell (replay)WebSocket messages2noneINFO
codexreconnectSQL statements10noneINFO
claudeAgentthread snapshotHTTP wire6.9 KiB (7,059 B)7.3 KiB (7,500 B)PASS
claudeAgentmeasured turnWebSocket wire6.3 KiB (6,409 B)7.8 KiB (8,000 B)PASS
claudeAgentmeasured turnWebSocket decoded55.5 KiB (56,806 B)66.4 KiB (68,000 B)PASS
claudeAgentmeasured turnWebSocket messages821PASS
claudeAgentshell snapshotHTTP wire829 BnoneINFO
claudeAgentmeasured turn, shellWebSocket wire626 BnoneINFO
claudeAgentmeasured turn, shellWebSocket decoded3.8 KiB (3,877 B)noneINFO
claudeAgentmeasured turn, shellWebSocket messages3noneINFO
claudeAgentmeasured turn, second clientWebSocket wire7.0 KiB (7,161 B)noneINFO
claudeAgentmeasured turn, second clientWebSocket decoded59.2 KiB (60,602 B)noneINFO
claudeAgentmeasured turn, second clientWebSocket messages10noneINFO
claudeAgentmeasured turnserver egress wire13.9 KiB (14,196 B)noneINFO
claudeAgentmeasured turnSQL statements1096noneINFO
claudeAgentreconnect, thread (replay)WebSocket wire6.2 KiB (6,342 B)noneINFO
claudeAgentreconnect, thread (replay)WebSocket decoded55.2 KiB (56,539 B)noneINFO
claudeAgentreconnect, thread (replay)WebSocket messages2noneINFO
claudeAgentreconnect, shell (replay)WebSocket wire379 BnoneINFO
claudeAgentreconnect, shell (replay)WebSocket decoded1.4 KiB (1,383 B)noneINFO
claudeAgentreconnect, shell (replay)WebSocket messages2noneINFO
claudeAgentreconnectSQL statements10noneINFO

Reading the numbers:

  • The sidebar costs about 630 B wire and 3 messages per turn, about 10% of the thread stream. A second device costs one more thread stream plus one more shell stream, about 7 KiB. Egress scales linearly with connected clients and there is no hidden multiplier.
  • Reconnecting from the pre-turn cursor replays about the same bytes as live delivery (6.3 KiB thread, 380 B shell) in 2 messages each and 10 SQL statements total. Replay was chosen every time at this gap size. Snapshot fallback did not trigger.
  • This fixture mocks git, so it says nothing about sharing git services across connections.

Change authored by Claude Fable 5.1 running in Claude Code.


Note

Low Risk
Changes are confined to integration tests and reporting helpers; production server code is not modified.

Overview
Extends the thread transfer budget integration test so CI reports more than a single thread WebSocket during one turn. Existing capped thread snapshot and measured-turn rows are unchanged.

The scenario now opens three measured WebSocket clients (thread-only, shell-only, and a second device with both subscriptions), records shell HTTP snapshot size, and sums server egress across the three sockets. After the turn, the second client closes and resubscribes from its pre-turn cursors; the report records catch-up wire/decoded/message totals and whether catch-up used replay or snapshot.

Test harness plumbing adds openMeasuredWsClient (per-client forked scope + close), WebSocket recorder improvements (awaitOpen, wire totals after close), shared SQL statement counting via a counting Tracer on the orchestration harness and HTTP/WS app (sql.execute spans), and helpers moved into TransferBudgetScenario for thread/shell subscribe and sync detection. New report fields are INFO-only (no new budgets).

Reviewed by Cursor Bugbot for commit 7aff2b1. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Expand transfer-budget test to measure shell, second client, and reconnect transfer

  • Reworks the live transfer-budget integration test in server.test.ts to open three concurrent measured clients (thread-only, shell-only, second-client), capture per-socket WebSocket transfer and server-wide sql.execute deltas, then close and reconnect the second client to measure replay-or-snapshot catch-up
  • Adds openMeasuredWsClient, a factory that forks a per-client child scope, builds a counting WebSocket protocol, waits for open (10s timeout defect), and returns an explicit close effect
  • Updates makeWebSocketTransferRecorder to retain the underlying transport at open time so wire-byte totals remain readable after socket closure
  • Adds makeSqlStatementCounter, a tracer that increments a counter for spans named exactly sql.execute while returning native spans for all operations
  • Extends formatTransferBudgetReport with informational (uncapped) rows for shell snapshot, shell-only and second-client WebSocket diagnostics, aggregate server egress, SQL counts, and reconnect catch-up modes alongside existing capped thread rows
  • Adds subscription helpers subscribeThreadItems, subscribeShellItems, and awaitSubscriptionSynchronized in TransferBudgetScenario.integration.ts that run scoped subscriptions and classify initial catch-up as replay or snapshot
  • Risk: makeWebSocketTransferRecorder open wait fails with a timeout defect after 10 seconds; awaitSubscriptionSynchronized similarly defects after 10 seconds if the synchronization marker never arrives

Macroscope summarized 7aff2b1.

The transfer budget measured one thread subscription. Real clients also hold
a sidebar subscription, often run on two devices, and reconnect. Measure all
three on the same turn and print them next to the capped thread rows, plus a
SQL statement count from sql.execute spans.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Sep 2, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ProviderMetricMain baselineThis PRImpactPR ceiling
CodexTotal thread wire13.3 KiB13.3 KiB+15 B (+0.1%)15.1 KiB
CodexThread snapshot wire6.9 KiB6.9 KiB+6 B (+0.1%)7.3 KiB
CodexLive turn WebSocket wire6.4 KiB6.4 KiB+9 B (+0.1%)7.8 KiB
CodexLive turn WebSocket decoded55.6 KiB55.6 KiB0 B (0.0%)66.4 KiB
CodexLive turn messages10100 (0.0%)21
ClaudeTotal thread wire13.3 KiB13.3 KiB+13 B (+0.1%)15.1 KiB
ClaudeThread snapshot wire6.9 KiB6.9 KiB−6 B (−0.1%)7.3 KiB
ClaudeLive turn WebSocket wire6.4 KiB6.4 KiB+19 B (+0.3%)7.8 KiB
ClaudeLive turn WebSocket decoded56.4 KiB56.4 KiB0 B (0.0%)66.4 KiB
ClaudeLive turn messages10100 (0.0%)21

Baseline: 80c708a · PR result: 7aff2b1 · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 109.4 KiB
  • Claude decoded thread snapshot: 110.1 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 7aff2b1

Macroscope's review found this PR approvable — This PR expands a server integration test to measure shell traffic, multiple clients, reconnects, and SQL activity. All changes are confined to test and reporting infrastructure, with no shipped production behavior or product-default changes.

Notes:

  • No code objects were reviewed. Approvability was decided on eligibility alone.

You can add or adjust custom eligibility rules. Learn more.

@t3dotgg
t3dotgg merged commit c37fd13 into mainSep 2, 2026
22 checks passed
@t3dotgg
t3dotgg deleted the t3code/transfer-budget-shell-and-multi-client branch September 2, 2026 02:16
github-actionsBot added a commit to omarcresp/t3code-flake that referenced this pull request Sep 2, 2026
## What's Changed
* perf(client-runtime): keep turn and checkpoint refs stable while streaming by @t3dotgg in pingdotgg/t3code#9145
* perf(clients): lease sidebar status by visibility by @StiensWout in pingdotgg/t3code#9052
* fix(desktop): show newest changes in nightly previews by @t3dotgg in pingdotgg/t3code#9138
* fix(settings): sync auto-settle and other shared preferences across environments by @t3dotgg in pingdotgg/t3code#9147
* fix(server): prevent accidental service downgrades by @t3dotgg in pingdotgg/t3code#5302
* fix(server): keep attachments until the command commits by @t3dotgg in pingdotgg/t3code#7941
* fix(claude): preview images read from the workspace by @t3dotgg in pingdotgg/t3code#9119
* fix(web): keep generated muted foreground dimmer than entered text by @flamboh in pingdotgg/t3code#9113
* fix(clients): stop repeating expanded commands by @t3dotgg in pingdotgg/t3code#9120
* fix(grok): health check, model selection, and stop all work against the real CLI by @t3dotgg in pingdotgg/t3code#9154
* perf(web): halve the cold-start bundle by splitting Clerk and cold routes by @StiensWout in pingdotgg/t3code#9058
* feat(desktop): update the desktop app on remote Macs from the Update button by @t3dotgg in pingdotgg/t3code#6554
* test(server): measure shell, second client, and reconnect transfer by @t3dotgg in pingdotgg/t3code#9157
* fix(web): project default model works on the hosted app by @juliusmarminge in pingdotgg/t3code#9142
* fix(web): darken neutral control surfaces by @maria-rcks in pingdotgg/t3code#9064
* fix(web): preserve panel state across workspace refreshes by @maria-rcks in pingdotgg/t3code#8968
* feat(files): open markdown, HTML, and PDF files outside the workspace by @juliusmarminge in pingdotgg/t3code#9140
* feat(web): render HTML and PDF files in the file viewer by @juliusmarminge in pingdotgg/t3code#9143
* fix(web): compact project settings actions by @maria-rcks in pingdotgg/t3code#9160
* fix(web): browse folders from file breadcrumbs by @404khai in pingdotgg/t3code#8910
## New Contributors
* @404khai made their first contribution in pingdotgg/t3code#8910
**Full Changelog**: pingdotgg/t3code@v0.0.39-nightly.20260902.1252...v0.0.39-nightly.20260902.1253
Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.39-nightly.20260902.1253
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

test(server): measure shell, second client, and reconnect transfer - #9157

Merged
t3dotgg merged 1 commit into
mainfrom
t3code/transfer-budget-shell-and-multi-client
Sep 2, 2026
Merged

test(server): measure shell, second client, and reconnect transfer#9157
t3dotgg merged 1 commit into
mainfrom
t3code/transfer-budget-shell-and-multi-client

Conversation

@t3dotgg

@t3dotggt3dotgg commented Sep 2, 2026

Copy link
Copy Markdown
Member

The transfer budget measured one thread subscription during one turn. Real clients also hold the sidebar (shell) subscription, users often have a desktop and a phone connected at once, and clients reconnect. Nobody had measured those, and the larger perf proposals (sharing the sidebar projector across clients, sharing git services across connections, incremental history) are gated on knowing whether they matter.

This PR measures them in the same test and prints them next to the existing capped rows. The single-thread measurement and its caps are unchanged.

What it adds:

  • A shell-only socket and a second client socket holding both the thread and shell subscriptions during the measured turn. The report shows per-socket wire bytes, decoded bytes, message counts, and total server egress.
  • A reconnect after the turn. The second client disconnects and resubscribes each subscription from the cursor it held before the turn. The report shows catch-up bytes and whether the server chose replay or a snapshot reset.
  • A SQL statement count from sql.execute spans. A counting tracer is installed on the harness runtime and the HTTP/WS app so reactor writes and subscription reads land in one total. No new instrumentation in src/.
  • openMeasuredWsClient opens each RPC socket on its own child scope so clients disconnect independently.

The new rows have no caps. The shell stream coalesces on a 50 ms window, so the second client's message count moved between 9 and 10 across runs and its wire bytes between 6.7 and 7.1 KiB. SQL statement counts moved between 1096 and 1167 for the same reason. The capped thread rows stayed within a few bytes.

Measured (local, one run):

ProviderPhaseMetricObservedBudgetResult
codexthread snapshotHTTP wire6.9 KiB (7,049 B)7.3 KiB (7,500 B)PASS
codexmeasured turnWebSocket wire6.3 KiB (6,401 B)7.8 KiB (8,000 B)PASS
codexmeasured turnWebSocket decoded54.7 KiB (55,974 B)66.4 KiB (68,000 B)PASS
codexmeasured turnWebSocket messages821PASS
codexshell snapshotHTTP wire829 BnoneINFO
codexmeasured turn, shellWebSocket wire628 BnoneINFO
codexmeasured turn, shellWebSocket decoded3.7 KiB (3,793 B)noneINFO
codexmeasured turn, shellWebSocket messages3noneINFO
codexmeasured turn, second clientWebSocket wire7.0 KiB (7,144 B)noneINFO
codexmeasured turn, second clientWebSocket decoded58.3 KiB (59,723 B)noneINFO
codexmeasured turn, second clientWebSocket messages10noneINFO
codexmeasured turnserver egress wire13.8 KiB (14,173 B)noneINFO
codexmeasured turnSQL statements1096noneINFO
codexreconnect, thread (replay)WebSocket wire6.2 KiB (6,325 B)noneINFO
codexreconnect, thread (replay)WebSocket decoded54.4 KiB (55,707 B)noneINFO
codexreconnect, thread (replay)WebSocket messages2noneINFO
codexreconnect, shell (replay)WebSocket wire386 BnoneINFO
codexreconnect, shell (replay)WebSocket decoded1.3 KiB (1,355 B)noneINFO
codexreconnect, shell (replay)WebSocket messages2noneINFO
codexreconnectSQL statements10noneINFO
claudeAgentthread snapshotHTTP wire6.9 KiB (7,059 B)7.3 KiB (7,500 B)PASS
claudeAgentmeasured turnWebSocket wire6.3 KiB (6,409 B)7.8 KiB (8,000 B)PASS
claudeAgentmeasured turnWebSocket decoded55.5 KiB (56,806 B)66.4 KiB (68,000 B)PASS
claudeAgentmeasured turnWebSocket messages821PASS
claudeAgentshell snapshotHTTP wire829 BnoneINFO
claudeAgentmeasured turn, shellWebSocket wire626 BnoneINFO
claudeAgentmeasured turn, shellWebSocket decoded3.8 KiB (3,877 B)noneINFO
claudeAgentmeasured turn, shellWebSocket messages3noneINFO
claudeAgentmeasured turn, second clientWebSocket wire7.0 KiB (7,161 B)noneINFO
claudeAgentmeasured turn, second clientWebSocket decoded59.2 KiB (60,602 B)noneINFO
claudeAgentmeasured turn, second clientWebSocket messages10noneINFO
claudeAgentmeasured turnserver egress wire13.9 KiB (14,196 B)noneINFO
claudeAgentmeasured turnSQL statements1096noneINFO
claudeAgentreconnect, thread (replay)WebSocket wire6.2 KiB (6,342 B)noneINFO
claudeAgentreconnect, thread (replay)WebSocket decoded55.2 KiB (56,539 B)noneINFO
claudeAgentreconnect, thread (replay)WebSocket messages2noneINFO
claudeAgentreconnect, shell (replay)WebSocket wire379 BnoneINFO
claudeAgentreconnect, shell (replay)WebSocket decoded1.4 KiB (1,383 B)noneINFO
claudeAgentreconnect, shell (replay)WebSocket messages2noneINFO
claudeAgentreconnectSQL statements10noneINFO

Reading the numbers:

  • The sidebar costs about 630 B wire and 3 messages per turn, about 10% of the thread stream. A second device costs one more thread stream plus one more shell stream, about 7 KiB. Egress scales linearly with connected clients and there is no hidden multiplier.
  • Reconnecting from the pre-turn cursor replays about the same bytes as live delivery (6.3 KiB thread, 380 B shell) in 2 messages each and 10 SQL statements total. Replay was chosen every time at this gap size. Snapshot fallback did not trigger.
  • This fixture mocks git, so it says nothing about sharing git services across connections.

Change authored by Claude Fable 5.1 running in Claude Code.


Note

Low Risk
Changes are confined to integration tests and reporting helpers; production server code is not modified.

Overview
Extends the thread transfer budget integration test so CI reports more than a single thread WebSocket during one turn. Existing capped thread snapshot and measured-turn rows are unchanged.

The scenario now opens three measured WebSocket clients (thread-only, shell-only, and a second device with both subscriptions), records shell HTTP snapshot size, and sums server egress across the three sockets. After the turn, the second client closes and resubscribes from its pre-turn cursors; the report records catch-up wire/decoded/message totals and whether catch-up used replay or snapshot.

Test harness plumbing adds openMeasuredWsClient (per-client forked scope + close), WebSocket recorder improvements (awaitOpen, wire totals after close), shared SQL statement counting via a counting Tracer on the orchestration harness and HTTP/WS app (sql.execute spans), and helpers moved into TransferBudgetScenario for thread/shell subscribe and sync detection. New report fields are INFO-only (no new budgets).

Reviewed by Cursor Bugbot for commit 7aff2b1. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Expand transfer-budget test to measure shell, second client, and reconnect transfer

  • Reworks the live transfer-budget integration test in server.test.ts to open three concurrent measured clients (thread-only, shell-only, second-client), capture per-socket WebSocket transfer and server-wide sql.execute deltas, then close and reconnect the second client to measure replay-or-snapshot catch-up
  • Adds openMeasuredWsClient, a factory that forks a per-client child scope, builds a counting WebSocket protocol, waits for open (10s timeout defect), and returns an explicit close effect
  • Updates makeWebSocketTransferRecorder to retain the underlying transport at open time so wire-byte totals remain readable after socket closure
  • Adds makeSqlStatementCounter, a tracer that increments a counter for spans named exactly sql.execute while returning native spans for all operations
  • Extends formatTransferBudgetReport with informational (uncapped) rows for shell snapshot, shell-only and second-client WebSocket diagnostics, aggregate server egress, SQL counts, and reconnect catch-up modes alongside existing capped thread rows
  • Adds subscription helpers subscribeThreadItems, subscribeShellItems, and awaitSubscriptionSynchronized in TransferBudgetScenario.integration.ts that run scoped subscriptions and classify initial catch-up as replay or snapshot
  • Risk: makeWebSocketTransferRecorder open wait fails with a timeout defect after 10 seconds; awaitSubscriptionSynchronized similarly defects after 10 seconds if the synchronization marker never arrives

Macroscope summarized 7aff2b1.

The transfer budget measured one thread subscription. Real clients also hold
a sidebar subscription, often run on two devices, and reconnect. Measure all
three on the same turn and print them next to the capped thread rows, plus a
SQL statement count from sql.execute spans.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Sep 2, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ProviderMetricMain baselineThis PRImpactPR ceiling
CodexTotal thread wire13.3 KiB13.3 KiB+15 B (+0.1%)15.1 KiB
CodexThread snapshot wire6.9 KiB6.9 KiB+6 B (+0.1%)7.3 KiB
CodexLive turn WebSocket wire6.4 KiB6.4 KiB+9 B (+0.1%)7.8 KiB
CodexLive turn WebSocket decoded55.6 KiB55.6 KiB0 B (0.0%)66.4 KiB
CodexLive turn messages10100 (0.0%)21
ClaudeTotal thread wire13.3 KiB13.3 KiB+13 B (+0.1%)15.1 KiB
ClaudeThread snapshot wire6.9 KiB6.9 KiB−6 B (−0.1%)7.3 KiB
ClaudeLive turn WebSocket wire6.4 KiB6.4 KiB+19 B (+0.3%)7.8 KiB
ClaudeLive turn WebSocket decoded56.4 KiB56.4 KiB0 B (0.0%)66.4 KiB
ClaudeLive turn messages10100 (0.0%)21

Baseline: 80c708a · PR result: 7aff2b1 · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 109.4 KiB
  • Claude decoded thread snapshot: 110.1 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 7aff2b1

Macroscope's review found this PR approvable — This PR expands a server integration test to measure shell traffic, multiple clients, reconnects, and SQL activity. All changes are confined to test and reporting infrastructure, with no shipped production behavior or product-default changes.

Notes:

  • No code objects were reviewed. Approvability was decided on eligibility alone.

You can add or adjust custom eligibility rules. Learn more.

@t3dotgg
t3dotgg merged commit c37fd13 into mainSep 2, 2026
22 checks passed
@t3dotgg
t3dotgg deleted the t3code/transfer-budget-shell-and-multi-client branch September 2, 2026 02:16
github-actionsBot added a commit to omarcresp/t3code-flake that referenced this pull request Sep 2, 2026
## What's Changed
* perf(client-runtime): keep turn and checkpoint refs stable while streaming by @t3dotgg in pingdotgg/t3code#9145
* perf(clients): lease sidebar status by visibility by @StiensWout in pingdotgg/t3code#9052
* fix(desktop): show newest changes in nightly previews by @t3dotgg in pingdotgg/t3code#9138
* fix(settings): sync auto-settle and other shared preferences across environments by @t3dotgg in pingdotgg/t3code#9147
* fix(server): prevent accidental service downgrades by @t3dotgg in pingdotgg/t3code#5302
* fix(server): keep attachments until the command commits by @t3dotgg in pingdotgg/t3code#7941
* fix(claude): preview images read from the workspace by @t3dotgg in pingdotgg/t3code#9119
* fix(web): keep generated muted foreground dimmer than entered text by @flamboh in pingdotgg/t3code#9113
* fix(clients): stop repeating expanded commands by @t3dotgg in pingdotgg/t3code#9120
* fix(grok): health check, model selection, and stop all work against the real CLI by @t3dotgg in pingdotgg/t3code#9154
* perf(web): halve the cold-start bundle by splitting Clerk and cold routes by @StiensWout in pingdotgg/t3code#9058
* feat(desktop): update the desktop app on remote Macs from the Update button by @t3dotgg in pingdotgg/t3code#6554
* test(server): measure shell, second client, and reconnect transfer by @t3dotgg in pingdotgg/t3code#9157
* fix(web): project default model works on the hosted app by @juliusmarminge in pingdotgg/t3code#9142
* fix(web): darken neutral control surfaces by @maria-rcks in pingdotgg/t3code#9064
* fix(web): preserve panel state across workspace refreshes by @maria-rcks in pingdotgg/t3code#8968
* feat(files): open markdown, HTML, and PDF files outside the workspace by @juliusmarminge in pingdotgg/t3code#9140
* feat(web): render HTML and PDF files in the file viewer by @juliusmarminge in pingdotgg/t3code#9143
* fix(web): compact project settings actions by @maria-rcks in pingdotgg/t3code#9160
* fix(web): browse folders from file breadcrumbs by @404khai in pingdotgg/t3code#8910
## New Contributors
* @404khai made their first contribution in pingdotgg/t3code#8910
**Full Changelog**: pingdotgg/t3code@v0.0.39-nightly.20260902.1252...v0.0.39-nightly.20260902.1253
Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.39-nightly.20260902.1253
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@t3dotgg