fix(contracts): older clients connect to servers with idle compaction modes#23213

open3
main
fix/issue-23109
opened2d agobyJJulius Marminge
View on GitHubTwo-way sync enabledPR last imported 1d ago

Problem

The desktop nightly's web client at 680152e27b cannot connect to servers with idle compaction modes: it expects a boolean compactIdleThreads, receives a string, and repeatedly closes the config subscription. Reproduced with the unchanged historical web client against the real server at 2333f16884.

Change

Keep compactIdleThreads boolean on the wire and carry the full mode in an additive idleCompactionMode field. Use that codec for config snapshots, config/settings updates and settings RPC responses. Accept legacy boolean settings patches while preserving the existing string storage model and string patches from current clients.

New clients decode boolean-only, string-only and additive server responses. Old clients cannot distinguish off from onReturn; explicitly writing their legacy false selects onReturn. New mode-string patches to old boolean-only servers remain unsupported, as before.

Scope and approval

Fixes #23109 GitCafe: https://git.cafe/pingdotgg/t3code/issues/23109 Triaged bug via the automated issue flow: #23109. One protocol compatibility fix; no rendering, transport, authentication, permissions, provider or MCP changes. Label: via-triage. Dispatcher owns merging.

Verification

Post-merge head de75c79a56, with main merged via a merge commit:

  • packages/contracts: vp test run src/settings.test.ts src/server.test.ts src/rpc.test.ts — 36 passed.
  • apps/server: vp test run src/serverSettings.test.ts src/ws.test.ts — 52 passed.
  • packages/client-runtime: vp test run src/state/server.test.ts src/rpc/client.test.ts — 27 passed.
  • Contracts tsc-rs --noEmit — passed. Focused lint and formatting — passed; three existing lint warnings outside the changed lines.
  • Implementation-step server typecheck passed; an independent review repeat timed out. Earlier web typecheck found two unrelated errors in useChatShortcuts.browser.test.tsx; not rerun here.
  • Independent GPT-6.1 Sol and Claude Opus 5.5 reviews returned MERGE for the six-file fix.

Evidence: index and empty visual fixture matrix. This changes server contracts, so proof is the red test plus the real runtime transcript; visual matrix is empty (0/0 rows). The screenshots below supplement the protocol proof and do not claim pixel or interaction coverage.

Before: server 2333f16884After: server ba8da1f771
Runtime transcript: old decoder rejects "onReturn"; WebSocket closes/retries; subscription interrupted.Runtime transcript: old decoder accepts false plus "onReturn"; workspace/composer opens and remains connected.
Before: old client stuck connectingAfter: unchanged old client opens workspace

Both captures use the unchanged historical web client, localhost port 7761 proxying server port 15527, isolated state, light theme, 1280×800. DPR and font scaling were not recorded. Runtime proof predates the clean main merge; the six-file fix diff is unchanged. Incidental differences: provider-update toast and git card appear after connecting. No UI code changes.

Original red output: four behavior failures. These assertions initially targeted the storage schema and moved to the separate wire codec in the fix; final tests are not unchanged tests runnable against main, which lacks that export. Runtime before/after independently verifies the failure boundary.

Unverified: native desktop/Electron (cannot-verify desktop), mobile, real SSH/relay/tunnel connections and historical server binaries. Shared contract coverage does not claim native-client verification.

Models: Claude Opus 5.5 (implementation), GPT-6.1 Sol and Claude Opus 5.5 (reviews); Codex and Claude Code harnesses through T3 Code.

Checks

All checks passed

Added 3 commits

  • test(contracts): cover compactIdleThreads wire compatibility with older clients1241654
  • fix(contracts): older clients connect to servers with idle compaction modesba8da1f
  • Merge remote-tracking branch 'origin/main' into fix/issue-23109de75c79
Synced from GitHub

Approvability

Verdict: Approved at de75c79

Macroscope's review found this PR approvable — This is a contained protocol-compatibility fix that keeps the legacy boolean field while carrying the full idle-compaction mode additively, without changing product defaults or stored settings semantics. Contract and persistence tests cover the affected paths.

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

Synced from GitHub

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ProviderMetricMain baselineThis PRImpactPR ceiling
CodexTotal thread wire5.0 KiB5.0 KiB+7 B (+0.1%)6.8 KiB✅
CodexThread snapshot wire3.8 KiB3.8 KiB0 B (0.0%)4.9 KiB✅
CodexLive turn WebSocket wire1.2 KiB1.2 KiB+7 B (+0.6%)2.0 KiB✅
CodexLive turn WebSocket decoded20.9 KiB20.9 KiB0 B (0.0%)29.3 KiB✅
CodexLive turn messages220 (0.0%)8✅
ClaudeTotal thread wire5.0 KiB5.0 KiB−24 B (−0.5%)6.8 KiB✅
ClaudeThread snapshot wire3.8 KiB3.8 KiB0 B (0.0%)4.9 KiB✅
ClaudeLive turn WebSocket wire1.2 KiB1.2 KiB−24 B (−2.0%)2.0 KiB✅
ClaudeLive turn WebSocket decoded21.2 KiB21.2 KiB−41 B (−0.2%)29.3 KiB✅
ClaudeLive turn messages21−1 (−50.0%)8✅

Baseline: 89fe509 · PR result: de75c79 · 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: 108.5 KiB
  • Claude decoded thread snapshot: 108.8 KiB

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

Synced from GitHub

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Path: .coderabbit.config.ts
  • Review profile: CHILL
  • Plan: Team
  • Run ID: f4adca4f-2a1d-461a-9653-13b009bd7f0e
📥 Commits

Reviewing files that changed from the base of the PR and between 89fe509232e787b51d0cf695861afe73316ce85b and de75c79a56bc5cc6b2e8da37e6c7be7ff5e612ee.

📒 Files selected for processing: 6
  • apps/server/src/serverSettings.test.ts
  • packages/contracts/src/rpc.test.ts
  • packages/contracts/src/rpc.ts
  • packages/contracts/src/server.ts
  • packages/contracts/src/settings.test.ts
  • packages/contracts/src/settings.ts

Limit details: You’ve used all 10 included reviews currently available.

📝 Walkthrough

The change adds a wire adapter for idle-compaction settings. The adapter supports legacy boolean values and mode strings. Server configuration and settings RPC schemas use the adapter, and tests cover encoding, decoding, and persistence.

Changes: Idle-compaction settings compatibility

Layer / File(s)Summary
Wire adapter and patch compatibility
packages/contracts/src/settings.ts, packages/contracts/src/settings.test.ts
ServerSettingsWire maps legacy booleans and mode strings. It encodes both idleCompactionMode and a compatibility boolean. Settings patches accept boolean or mode values. Tests cover decoding and round-tripping.
Server configuration and RPC wiring
packages/contracts/src/server.ts, packages/contracts/src/rpc.ts, packages/contracts/src/rpc.test.ts, apps/server/src/serverSettings.test.ts
Server configuration and settings RPC schemas use ServerSettingsWire. Tests check that "off" encodes as compactIdleThreads: false, and that an unrelated settings update preserves "off" in returned and persisted settings.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix · Severity of issue fixed: Medium

Possibly related issues

  • pingdotgg/t3code#23109: The issue describes older clients closing the config subscription when they receive a mode string. This change preserves the legacy boolean field and adds idleCompactionMode.

Suggested reviewers: maria-rcks, t3dotgg

Merge Risk: ⚪ Minimal · up to de75c

The compatibility paths reviewed preserve mode-string storage and send the boolean expected by older clients. No actionable issue remains before normal merge checks.

Pre-merge checks: Passed 4
Check nameStatusExplanation
Title checkPassedThe title clearly and concisely describes the primary compatibility fix for older clients and idle compaction modes.
Linked Issues checkPassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes checkPassedCheck skipped because no linked issues were found for this pull request.
Description checkPassedThe pull request description includes all required sections. It clearly explains the compatibility problem, the implementation, scope and issue approval, focused verification results, limitations, and…
Full details: Description check

Explanation

The pull request description includes all required sections. It clearly explains the compatibility problem, the implementation, scope and issue approval, focused verification results, limitations, and agent details. It also provides concrete reproduction evidence and test outcomes.

✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.