fix(server): prevent accidental service downgrades - #5302
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
One finding: a wrapper error's message now interpolates cause.message, which the Effect error conventions disallow. Everything else in the changed service/error code (new ServiceDowngradeRefusedError, catchTags handling, relay endpoint reconcile handler, RPC schema-defect mapping) follows the conventions.
Posted via Macroscope — Effect Service Conventions
ApprovabilityVerdict: Not approved Macroscope's review found this PR not approvable — The PR changes the default behavior of background-service installation and updates by refusing downgrades unless an explicit override is supplied. The implementation is localized and well covered by tests, but this product-default change warrants human review. You can add or adjust custom eligibility rules. Learn more. |
b400658 to
a94e3ca
Compare
c23ddca to
68db573
Compare
c11fc14 to
2896676
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 2896676. Configure here.
21ef91a to
1b02641
Compare
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. |
## 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
…5302 tests Upstream's new desktop-app CLI tests and service-downgrade tests hardcode upstream identity (default home .t3, txcode->t3code service names); port them to the fork's deliberate divergence (.txcode, txcode.service, net.coriou.txcode.service) so fork-intent behavior is what's verified.
…dotgg#8824/pingdotgg#5302 Auto-merged upstream files introduced user-facing 'T3 Code' strings describing our own desktop app and CLI UX. Ported to 'Tx Code' in lockstep with their test assertions (app.test, DesktopAppUpdate.test).
… commits) Daily sync 2026-09-02 (main pass + top-up) plus CTO identity-port amendment: fork 'Tx Code' strings ported into 11 new desktop-app/CLI surfaces from pingdotgg#8824/pingdotgg#5302. Gates green per sync report; focused identity tests re-run.

An older CLI can replace a newer background service during install, update, or T3 Connect setup.
This reports the installed version and requires
--allow-downgradebefore replacing it with an older version. It checks again before writing service files, so a completed remote update cannot bypass the guard. Onboarding leaves newer services unchanged. The existing systemd, launchd, and pending-update behavior stays intact.Verified with 41 focused service tests, the server typecheck, changed-file lint, formatting, and
git diff --check. Tests use temporary files and fake service/process runners. No real service was changed.This retains Theo Browne's service guard. The broader original work is preserved on an archive branch.
Made with GPT-5.6 Sol in the Codex harness.
Note
Medium Risk
Changes install/update/onboarding paths for systemd and launchd with a new guard that could block legitimate repairs if version detection is wrong; extensive tests mitigate this.
Overview
Prevents an older CLI from replacing a newer installed background service during
service install,service update, or T3 Connect onboarding unless the user passes--allow-downgrade.Service status now surfaces
installedVersionand, when the service is newer than the CLI, points to an exact-version repair command instead oft3@latest.reconcileServiceandBootService.installcompare versions withcompareExactServiceVersions; a second check runs after stopping the unit (viaserviceStateActiveVersion) so a remote update that finishes during shutdown cannot be overwritten. Onboarding skips prompts and leaves a newer service unchanged;BootServiceDowngradeRefusedErroris handled like other non-fatal setup failures. User docs describe version pinning and downgrade behavior.Reviewed by Cursor Bugbot for commit 1b02641. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Prevent accidental
BootServicedowngrades in CLI install and updateBootService.installnow reads the final service state after stopping the unit and refuses to install if the active version is newer than the CLI, returningBootServiceDowngradeRefusedError; the stopped service is restarted on refusal.--allow-downgradeflag to the service install and update commands so users can explicitly authorize a downgrade.BootServiceStatusnow includes a validatedinstalledVersion; the status formatter prints an exact-version repair command instead of the generic latest command when a newer service is detected.false.installchanged from anEffectproperty to an optional-options function in bootService.ts — all in-tree call sites are updated, but out-of-tree consumers calling the oldEffectform will break.Macroscope summarized 1b02641.