Skip to content

fix(desktop): Stable switch no longer tells policy-blocked nightly apps to reinstall by hand - #32609

Open
only21mil wants to merge 1 commit into
pingdotgg:mainfrom
only21mil:fix/desktop-update-state-channel-blocked
Open

only21mil wants to merge 1 commit into
pingdotgg:mainfrom
only21mil:fix/desktop-update-state-channel-blocked

Conversation

@only21mil

Copy link
Copy Markdown
Contributor

Problem

A nightly desktop app under a managed update policy that rules out nightly (allowNightly: false) should offer a one-step switch to Stable. The desktop update service marks that state with channelBlockedByPolicy: true, but DesktopUpdateStateSchema has no such key. IPC results are encoded through that schema (getUpdateState, and the state inside the check, download and install results), so the flag is dropped before it reaches the renderer.

In that state no later update-state push arrives to put it back, so localUpdaterStaysPut sees enabled: false without the flag. The Stable switch dialog then prepares no local reinstall and says "This app's updates are off here, so reinstall it yourself to switch.", which is false for this app.

Change

Add channelBlockedByPolicy: Schema.optionalKey(Schema.Literal(true)) to DesktopUpdateStateSchema, matching the DesktopUpdateState interface field added in #27197.

The existing test "holds a nightly install until its user switches to stable" in DesktopUpdates.test.ts now also encodes the held state through DesktopUpdateStateSchema and checks that the flag survives.

Compatibility: the key is optional. The IPC runs between the main and renderer processes of one app build. DesktopUpdateStatusReport reuses this schema for remote update status; older readers ignore the extra key, and newer readers accept reports without it.

Scope and approval

This is a focused fix for an obvious bug: the schema was missing a field its interface already declares. It needs no new behavior or settings. I found no issue or PR covering it; #32048, #32027, #27484 and #30804 touch the same dialog or updater for other causes.

Verification

  • cd apps/desktop && vp test run src/updates/DesktopUpdates.test.ts -t "holds a nightly install until its user switches to stable"
    • On main with the new assertion: fails at assert.isTrue((yield* encodeUpdateState(held)).channelBlockedByPolicy) (expected undefined to be true).
    • With the fix: passes.
  • node scripts/check-changed.ts 25bf84ab07f53f141c20239c63e383823a9d5ea0: format, lint, knip, typecheck (36 packages) and tests (2 files, 42 passed) all pass.

Terminal captures of these runs follow; the checkout path is shortened to t3code. Before, on main's schema with the new assertion: the encoded state drops the flag, so the test fails.

Terminal run of the nightly-hold test on main, failing because the encoded update state has no channelBlockedByPolicy

After, with the fix: the same test passes.

Terminal run of the same test with the fix, passing

No dialog capture is included. Development builds with an update feed configured report that updates are only available in packaged production builds, so they never reach the policy-blocked state. Reaching it needs a packaged nightly build (on Linux, the AppImage or .deb) with an update feed, plus a machine-wide managed policy file (/etc/t3code/policy.json on Linux) that rules out nightly. I did not build one or install that policy, so the dialog itself is not checked; the captures above show the flag the dialog reads.

Generated with Claude Opus 5.5 and GPT-6.1 Sol in T3 Code Nightly

DesktopUpdateStateSchema had no channelBlockedByPolicy key, so encoding the update state for IPC stripped it and the settings dialog told policy-blocked nightly installs to reinstall by hand instead of preparing the switch to stable.
Add the optional key to the schema so the flag reaches the renderer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XS 0-9 changed lines (additions + deletions). labels Nov 7, 2026
@macroscopeapp

macroscopeapp Bot commented Nov 7, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at d30de5d

Macroscope's review found this PR approvable — Preserves an existing policy-blocked update flag across IPC so the Stable-switch flow can distinguish it from updates being disabled. The optional schema addition leaves update policy and product defaults unchanged.

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

@coderabbitai

coderabbitai Bot commented Nov 7, 2026

Copy link
Copy Markdown
Contributor

Explain Change →

No actionable comments were generated in the recent review.

Walkthrough

The update state schema now accepts an optional channelBlockedByPolicy field with the literal value true. A managed-policy test checks that encoding the held state preserves this field.

Changes: Update state contract

Layer / File(s) Summary
Schema field and encoding test
packages/contracts/src/ipc.ts, apps/desktop/src/updates/DesktopUpdates.test.ts
DesktopUpdateStateSchema accepts the optional channelBlockedByPolicy: true field. The managed-policy test encodes the held state and checks that the field remains true.

Estimated code review effort: 1 (Trivial) | ~4 minutes

Change: Bug fix

Suggested reviewers: juliusmarminge

Merge Risk: Minimal · up to d30de

The update-state schema preserves the policy-blocked flag. No merge-blocking issue is identified.

Pre-merge checks: Passed 4

Check name Status Explanation
Title check Passed The title names the main change: the Stable switch in the desktop app no longer tells policy-blocked nightly apps to reinstall manually. The raw summary shows the schema gained an optional channelBloc…
Description check Passed The description follows the template's main sections: Problem, Change, Scope and approval, and Verification. The Problem section explains the dropped flag, the affected Stable switch dialog, and the e…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Title check

Explanation

The title names the main change: the Stable switch in the desktop app no longer tells policy-blocked nightly apps to reinstall manually. The raw summary shows the schema gained an optional channelBlockedByPolicy field and a test now checks that it survives encoding, which matches the title's fix. The title is long (92 characters) but specific and accurate, so it passes.

Full details: Description check

Explanation

The description follows the template's main sections: Problem, Change, Scope and approval, and Verification. The Problem section explains the dropped flag, the affected Stable switch dialog, and the expected behavior. The Change section names the schema field and the updated test. The Scope section explains why no prior issue is linked and why the fix is focused. The Verification section gives the exact commands, before and after results, and images. It also states what was not checked: the dialog itself. The description does not link a triaged issue, which the template asks for, but it gives a reasoned exemption for a small, focused fix. The template's 'Use a conventional commit title' guidance is met by the title. Overall the description is mostly complete, so it passes.

Finishing Touches

Generate unit tests (beta)

  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Recent review info

Run configuration

Commits

Reviewing files that changed from the base of the PR and between 25bf84a and d30de5d.

Files selected for processing: 2

  • apps/desktop/src/updates/DesktopUpdates.test.ts
  • packages/contracts/src/ipc.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 8 remain after this review.

@Wladefant Wladefant left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Independent exact-head desktop update-policy/IPC source review (COMMENT, not approval) — d30de5d8d4f148078d4edf9347cbc74c63261e5b → main@25bf84ab07f53f141c20239c63e383823a9d5ea0.

Reviewed both changed files and the DesktopUpdateActionResultSchema/update-state IPC composition. The managed-policy discriminator was previously available in the service object but omitted from DesktopUpdateStateSchema encoding; adding optional literal true preserves the true signal without changing absent-key compatibility, and the existing policy-held-nightly test now asserts post-serialization survival. No additional demonstrated P1/P2 defect in the bounded two-file change.

Real PR-event CI #42406039378 completed/SUCCESS; the Test job checked out generated merge 3e1f67dc535d95857f36a5d6d4419b847f4666a4 of this source head, with selected DesktopUpdates.test.ts 40/40 and DesktopRemoteUpdates.test.ts 26/26. Browser-install steps marked skipped do not count as acceptance.

Remaining gate is packaged-nightly, opt-in physical Windows/macOS policy application and actual Stable-switch dialog/installer behavior, including old report/no-flag compatibility and not disrupting existing sessions. Source serialization tests do not establish policy-filesystem privileges, updater installation success, installed binary identity or user consent. Original author retains source and release selection; COMMENTED, not APPROVED or merged by this review.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XS 0-9 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants