Repository navigation
fix(server): reject pairing with an incompatible server protocol - #23789
Conversation
…le server's database Adds a failing pair test: a discovered server reporting protocol 1 / version 0.0.45 must be rejected with an exact `npx t3@0.0.45 pair` hint before the CLI opens or migrates its database. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An older CLI discovered a protocol 2 server, minted into a database that server never reads, and printed a token it rejects. Pair now compares the discovered descriptor's protocol before opening any local database and points at the matching `npx t3@<serverVersion> pair`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ApprovabilityVerdict: Needs Human Approval Macroscope's review found this PR requires human approval — This narrowly scoped fix rejects protocol-incompatible servers before pairing setup can initialize authentication storage or mint an unusable credential, while preserving matching and legacy paths. Because it changes authentication-related runtime behavior, human review is warranted. You can add or adjust custom eligibility rules. Learn more. |
Thread transfer impact✅ Thread transfer remains within every enforced ceiling.
Baseline: Scenario and decoded snapshot size10 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.
Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Merge Risk: ⚪ Minimal · up to
|
## What's Changed * fix(web): clear stale resource monitor errors after retry by @juliusmarminge in pingdotgg/t3code#24229 * fix(mobile): align draft workspace controls with the composer by @PixPMusic in pingdotgg/t3code#24239 * feat(mobile): thread header minimizes on the Duo while reading back through history by @juliusmarminge in pingdotgg/t3code#24235 * fix(web): center pull request timeline actions by @PixPMusic in pingdotgg/t3code#24259 * fix(server): find the resource monitor when the server runs from its build output by @yordis in pingdotgg/t3code#23965 * fix(pull-requests): list filters narrow on every host that can by @juliusmarminge in pingdotgg/t3code#23922 * fix(pull-requests): a filtered list fills its page instead of waiting for a scroll by @juliusmarminge in pingdotgg/t3code#23923 * feat(pull-requests): label and author filters search the host by @juliusmarminge in pingdotgg/t3code#23924 * fix(mobile): chat and composer chips stay readable in light mode by @flamboh in pingdotgg/t3code#22585 * fix(web): review thread avatars no longer clip in collapsed activity rows by @flamboh in pingdotgg/t3code#23545 * ci: close "needs more info" issues after 7 days without a reply by @juliusmarminge in pingdotgg/t3code#22628 * fix(server): Codex accounts show ChatGPT's current plan names by @flamboh in pingdotgg/t3code#24200 * fix(observability): desktop dev version and web environment match the other services by @yordis in pingdotgg/t3code#23975 * fix(observability): custom resource attributes use the t3code prefix by @yordis in pingdotgg/t3code#23974 * fix(mobile): Home and pull request lists let UIKit own their top inset by @juliusmarminge in pingdotgg/t3code#24284 * fix(mobile): keep the Duo's Home and pull request headers fixed by @juliusmarminge in pingdotgg/t3code#24295 * fix(server): interrupts started by an agent no longer say "by user" in the timeline by @juliusmarminge in pingdotgg/t3code#24299 * ci(relay): deploy labeled PRs to relay preview stages by @juliusmarminge in pingdotgg/t3code#23872 * fix(mobile): HTML links in pull request comments open when tapped by @flamboh in pingdotgg/t3code#22110 * perf(client): avoid full ordering scans for streamed replacements by @juliusmarminge in pingdotgg/t3code#24264 * fix(server): a fork's first /compact compacts its inherited history by @juliusmarminge in pingdotgg/t3code#24172 * fix(server): agent recordings honor the browser frame rate setting by @juliusmarminge in pingdotgg/t3code#23895 * fix(client-runtime): Stop clears commands already finished on the server by @juliusmarminge in pingdotgg/t3code#23814 * fix(web): SSH environments on an older reused remote server explain the version mismatch instead of reconnecting forever by @juliusmarminge in pingdotgg/t3code#23647 * fix(web): keep usage-limit wake action visible by @juliusmarminge in pingdotgg/t3code#23803 * fix(server): reject pairing with an incompatible server protocol by @juliusmarminge in pingdotgg/t3code#23789 **Full Changelog**: pingdotgg/t3code@v0.1.3-nightly.20261023.3592...v0.1.3-nightly.20261024.3604 Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.1.3-nightly.20261024.3604
* test: delete low-value tests and dead test-only exports (pingdotgg#24058) * test(server): restore DST scheduling tests deleted in the test snap (pingdotgg#23991) * test(web): restore project settings permission tests deleted in the test snap (pingdotgg#24011) * test(mobile): restore clipboard secret-redaction test deleted in the test snap (pingdotgg#23980) * fix(web): Cmd+B toggles the sidebar unless text is selected (pingdotgg#24063) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(server): agent-browser and Chrome no longer outlive the agent that started them (pingdotgg#21299) Co-authored-by: Julius Marminge <julius0216@outlook.com> Co-authored-by: Theo Browne <me@theo.li> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * test(client-runtime): restore render scheduler tests deleted in the test snap (pingdotgg#23977) * fix(web): cmd+k search hides subagents and favors recent, whole-word matches (pingdotgg#24032) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * test(lint): new polling loops in tests now fail lint (pingdotgg#23983) * ci: unused dependency patches fail in check:changed, not after push (pingdotgg#23988) * fix(desktop): PDFs in the preview can be annotated (pingdotgg#24022) Co-authored-by: PR Batch Tester <agent@local.test> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(web): instructed compact runs without a bare compaction first (pingdotgg#24008) Co-authored-by: fixfon <12512757+fixfon@users.noreply.github.com> Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> * fix(desktop): reduce app crashes when a preview tab's renderer dies during agent screenshots (pingdotgg#24056) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(server): Stop stops a thread's subagents again (pingdotgg#23886) Co-authored-by: PR Batch Tester <agent@local.test> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): a stuck quit no longer leaves the app unkillable (pingdotgg#23873) Co-authored-by: PR Batch Tester <agent@local.test> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(web): keep blockquote text readable in every theme (pingdotgg#24036) * fix(bitbucket): stop the startup sweep from flooding Bitbucket with 429s (pingdotgg#23889) Co-authored-by: PR Batch Tester <agent@local.test> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(web): screen readers hear when the open thread starts, needs you or finishes (pingdotgg#23752) Co-authored-by: PR Batch Tester <agent@local.test> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * perf(web): reduce allocations in streaming timeline scans (pingdotgg#23739) * perf(web): reuse a collator when sorting changed-file trees (pingdotgg#23776) * perf(scripts): check:changed finishes in about 10 s (pingdotgg#23581) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(web): size Usage header controls to the available width (pingdotgg#24123) * perf(server): speed up large terminal clipboard sequences (pingdotgg#23819) Co-authored-by: Julius Marminge <julius0216@outlook.com> * fix(server): make stale CLI service recovery actionable (pingdotgg#23541) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(web): pasted images show their upload tile instantly (pingdotgg#23832) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Julius Marminge <julius0216@outlook.com> * fix(server): clean up deleted threads worktrees with subagents (pingdotgg#23900) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(server): pause periodic PR discovery without foreground clients (pingdotgg#23852) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(server): meter checkpoint git subprocess attempts (pingdotgg#24218) Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com> Co-authored-by: Yordis Prieto <yordis.prieto@gmail.com> * fix(web): clear stale resource monitor errors after retry (pingdotgg#24229) Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com> Co-authored-by: Yordis Prieto <yordis.prieto@gmail.com> * fix(mobile): align draft workspace controls with the composer (pingdotgg#24239) * feat(mobile): thread header minimizes on the Duo while reading back through history (pingdotgg#24235) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(web): center pull request timeline actions (pingdotgg#24259) * fix(server): find the resource monitor when the server runs from its build output (pingdotgg#23965) Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com> Co-authored-by: Theo Browne <me@t3.gg> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Victor Vogel <satsdev@only21mil.xyz> Co-authored-by: Julius Marminge <julius0216@outlook.com> Co-authored-by: Yash Singh <saiansh2525@gmail.com> Co-authored-by: Joseph Vidal <135430578+josephv123@users.noreply.github.com> Co-authored-by: Theo Browne <me@theo.li> Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com> Co-authored-by: PR Batch Tester <agent@local.test> Co-authored-by: fixfon <12512757+fixfon@users.noreply.github.com> Co-authored-by: Utkarsh Patil <73941998+UtkarshUsername@users.noreply.github.com> Co-authored-by: Yukun Shan <92423096+nateEc@users.noreply.github.com> Co-authored-by: Akshar Patel <123344143+AksharP5@users.noreply.github.com> Co-authored-by: Ben Davis <45952064+bmdavis419@users.noreply.github.com> * fix(pull-requests): list filters narrow on every host that can (pingdotgg#23922) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(pull-requests): a filtered list fills its page instead of waiting for a scroll (pingdotgg#23923) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * feat(pull-requests): label and author filters search the host (pingdotgg#23924) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(mobile): chat and composer chips stay readable in light mode (pingdotgg#22585) Co-authored-by: Julius Marminge <julius0216@outlook.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(web): review thread avatars no longer clip in collapsed activity rows (pingdotgg#23545) * ci: close "needs more info" issues after 7 days without a reply (pingdotgg#22628) Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> * fix(server): Codex accounts show ChatGPT's current plan names (pingdotgg#24200) * fix(observability): desktop dev version and web environment match the other services (pingdotgg#23975) Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com> * fix(observability): custom resource attributes use the t3code prefix (pingdotgg#23974) Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com> * fix(mobile): Home and pull request lists let UIKit own their top inset (pingdotgg#24284) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(mobile): keep the Duo's Home and pull request headers fixed (pingdotgg#24295) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(server): interrupts started by an agent no longer say "by user" in the timeline (pingdotgg#24299) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * feat(relay): deploy on-demand preview stages for labeled PRs Labeled same-repo PRs deploy stage pr-<n> behind the relay-preview environment reviewer gate. Unlabel or close tears the stage down, and a nightly job retries failed teardowns. Runtime-created managed endpoint tunnels and CNAMEs are swept by a PreviewTunnelSweep resource. Known gaps, tracked as follow-ups: an interrupted preview deploy can leave runtime tunnels behind; repo-level relay secrets still bypass the environment gate until moved. 🤖 Generated with [Claude Code](https://claude.com/claude-code) * fix(mobile): HTML links in pull request comments open when tapped (pingdotgg#22110) * perf(client): avoid full ordering scans for streamed replacements (pingdotgg#24264) * fix(server): a fork's first /compact compacts its inherited history (pingdotgg#24172) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(server): agent recordings honor the browser frame rate setting (pingdotgg#23895) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(client-runtime): Stop clears commands already finished on the server (pingdotgg#23814) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(web): SSH environments on an older reused remote server explain the version mismatch instead of reconnecting forever (pingdotgg#23647) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(web): keep usage-limit wake action visible (pingdotgg#23803) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(server): reject pairing with an incompatible server protocol (pingdotgg#23789) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(mobile): Live Activity stops shouting the running-agent count (pingdotgg#24329) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * feat(usage): include Muse Code session history (pingdotgg#22443) Co-authored-by: Theo Browne <me@theo.li> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * feat(mobile): add Usage and Settings to workspace navigation (pingdotgg#23841) * fix(mobile): keep iPad workspace columns aligned while resizing (pingdotgg#24182) * fix(mobile): no-project threads show a chat bubble instead of a monogram (pingdotgg#21546) * fix(mobile): stabilize Duo search and portrait navigation (pingdotgg#24206) Co-authored-by: Julius Marminge <julius0216@outlook.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(mobile): the unfolded Duo keeps its header in portrait (pingdotgg#24339) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(client-runtime): avoid duplicate handoff previews during startup (pingdotgg#24349) * fix(mobile): Usage and Settings use the glass header and the Duo rail (pingdotgg#24348) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * perf(server): coalesce superseded streaming text updates (pingdotgg#24267) * fix(server): stop flooding analytics with successful MCP tool calls (pingdotgg#24287) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * feat(search): Cmd+K finds the right thread first, with indexed message search (pingdotgg#24343) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> --------- Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com> Co-authored-by: Theo Browne <me@t3.gg> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Joseph Vidal <135430578+josephv123@users.noreply.github.com> Co-authored-by: Julius Marminge <julius0216@outlook.com> Co-authored-by: Theo Browne <me@theo.li> Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com> Co-authored-by: PR Batch Tester <agent@local.test> Co-authored-by: fixfon <12512757+fixfon@users.noreply.github.com> Co-authored-by: Yash Singh <saiansh2525@gmail.com> Co-authored-by: Utkarsh Patil <73941998+UtkarshUsername@users.noreply.github.com> Co-authored-by: Yukun Shan <92423096+nateEc@users.noreply.github.com> Co-authored-by: Akshar Patel <123344143+AksharP5@users.noreply.github.com> Co-authored-by: Ben Davis <45952064+bmdavis419@users.noreply.github.com> Co-authored-by: Yordis Prieto <yordis.prieto@gmail.com> Co-authored-by: Alex <me@pixp.cc> Co-authored-by: Victor Vogel <satsdev@only21mil.xyz> Co-authored-by: oliver <97427849+flamboh@users.noreply.github.com> Co-authored-by: Wiktor Golicz <56449542+Wiktor102@users.noreply.github.com>
…gdotgg#23789) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 3f3a1bf)
Problem
Running
t3 pairagainst a server on another orchestration protocol prints a token that the server cannot use. For example, stable0.0.45writesstate.sqlitewhile a V2 server readsstatev2.sqlite; the reverse direction also creates an unnecessary V2 database before returning an unusable token.Change
Check the discovered server's orchestration protocol before Tailscale setup or database/auth initialization. Refuse mismatches with both protocol versions and the exact server-version pairing command. Missing protocol metadata uses the existing V1 compatibility default; matching protocols retain the existing pairing path.
Scope and approval
Fixes #15492
Triaged bug via the automated issue flow: #15492. Limited to the pairing CLI compatibility check and its regression test.
Verification
server-runtime.json; actual also containedenvironment-id,secrets, andstatev2.sqlite.vp test run apps/server/src/cli/pair.test.ts: 14/14 passed on c502579298.issue-15492-runtime.md
Independent sanitized evidence audit
Server/CLI-only change; render matrix empty. Runtime verified on Linux x64, Node 26.12.1, isolated real V1/V2 servers. macOS desktop and Tailscale wrapping were not run. The already-published immutable
0.0.45package remains affected; the source fix protects future CLI releases.Models: Claude Opus 5.5 (Claude Agent harness), GPT-6.1-Sol (Codex harness).
Verification log
Review + omitted-protocol evidence at c502579298, against merge-base 044f07257c. No source changes or fixes applied; these are delegated review results, not posted forge reviews.
gpt-6.1-sol: MERGE. Full diff and discovery/config/auth paths traced: guard precedes database/migrations, secrets, environment-id and Tailscale writes; failed/unreachable discovery cannot reach token minting. No pairing acceptance, scope or grant changes. Static review; diff check passed.claude-opus-5-5: MERGE. Full diff and descriptor history traced: omitted metadata uses the established V1 default; production V2 producers always include the field. Focused pairing suite passed 14/14. Nonblocking caveats: retain original CLI flags with the suggested command; unpublished server versions may not have a matching npm release. No auth acceptance/grant change beyond refusing unusable token issuance, so neither reviewer triggered NEEDS_JULIUS.orchestrationProtocolVersion; real source CLI, isolated fresh and existing homesenvironment-id,secrets/server-signing-key.bin,statev2.sqlite, one pairing row. Existing: database hash changes, pairing rows 1→2.npx t3@0.0.45 pair. Fresh: no files created or changed. Existing: all file hashes unchanged, pairing rows remain 1.Sanitized transcripts, file inventories, and exact driver. Driver SHA-256:
4c008957f981f4a2cb7812cd5067f23fa2ccf8b34861975e6e26a5ceb96e1226.This row uses a descriptor fixture advertising
0.0.45, not a full production server; no exchange result is claimed. All runtime homes were under/tmp/ev-23789; no real T3 database was accessed. No Tailscale command was run. Server port-owner PIDs were recorded and their cwd checked before stopping. An initial Vite+ shim bootstrap was discarded and the row rerun using the installed Node binary directly. Missing metadata on a hypothetical modified V2 server would also be treated as V1; shipped V2 descriptor constructors emit the field. No correction to the existing PR-body evidence claims was found.