Skip to content

feat(updates): add release settings page - #844

Merged
mcharles-square merged 8 commits into
mainfrom
codex/release-updates-04-settings
Aug 1, 2026
Merged

feat(updates): add release settings page#844
mcharles-square merged 8 commits into
mainfrom
codex/release-updates-04-settings

Conversation

@mcharles-square

@mcharles-square mcharles-square commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

Reviewable diff: +370/-2 across 7 files (excludes generated, test, and story files).

Summary

Adds Settings → Updates for permission holders, showing the running server version, eligible release, exact manual install command, and Stable + RC opt-in. Update discovery failures remain distinct from the up-to-date state, while request sequencing and bounded mutation lifecycle coordination prevent stale channels or install commands during saves, navigation, and ambiguous network failures. If update authority is revoked, the page reports it, removes the stale client permission, and redirects to a settings route the operator can access; delayed failures perform global auth cleanup only for the session that originated them.

Stack: #841, #842, and #843 are merged; this PR is relative to main. Remaining notification and host-execution work continues in #845, #835, #836, #837, #838, #839, and #840.

How it works

The permission-gated route loads GetUpdateStatus. Available status renders either the eligible release and command or the up-to-date state; unavailable discovery gets a neutral state. A channel change persists through SetReleaseChannel with a 30-second deadline, keeps channel and copy controls disabled, and then refetches authoritative status. Request sequence numbers ignore late status responses, while a route remount waits for any save started by its predecessor; the deadline guarantees that shared barrier settles. Ambiguous non-auth save failures, including deadlines, refetch because the server may have committed before the response was lost. Each request captures the auth session installed at login. Same-session failures still pass through global auth handling after unmount or request replacement, while obsolete page state and toasts remain suppressed; failures from a replaced session are discarded so they cannot log out or remove permissions from its successor. Mounted permission denial also shows a revocation notice and redirects through the permission-aware settings landing helper.

sequenceDiagram
  participant O as Operator
  participant U1 as Updates page
  participant S as InstanceUpdateService
  participant U2 as Remounted page
  O->>U1: Choose Stable or RC
  U1->>U1: Disable channel and copy controls
  U1->>S: SetReleaseChannel with 30s deadline
  U1--xU1: Unmount
  U2->>U2: Wait for bounded in-flight save
  S-->>U2: Save settles or deadline expires
  U2->>S: GetUpdateStatus
  S-->>U2: Authoritative channel and command
Loading

Areas of the code involved

Area / package / file What changed Why it matters for review
features/settings/components/Updates.tsx Status states, request sequencing, bounded save lifecycle coordination, reconciliation, session-bound auth cleanup, permission invalidation, safe fallback routing, release notes, and command copy Primary operator workflow, authorization response, and concurrency boundary
features/updates/copyInstallCommand.ts Shared clipboard feedback Manual fallback behavior
api/clients.ts InstanceUpdateService client Backend connection
navItems.ts, router.tsx, routePrefetch.ts Permission-gated lazy route and idle-time prefetch Route completeness
docs/plans/...release-update-notifications-plan.md Documents request ordering, bounded remount behavior, reconciliation, and session-bound auth handling Keeps the implementation plan aligned
Tests and visual snapshot Cover rendering, permissions, protobuf fixtures, mutation/refetch ordering, deadline recovery, remounts, late and cross-session auth failures, denial handling, fallback routing, and layout Regression coverage; snapshot is generated test output

Key technical decisions & trade-offs

  • Sequence status requests in the component so stale success and ordinary error responses cannot replace the fresh UI.
  • Bind every request to the login-installed session-expiry object so delayed session-A failures cannot mutate session B, even for the same username.
  • Process same-session authentication and permission failures globally after unmount while suppressing obsolete component state and toast work.
  • Read current permissions when processing same-session delayed denial so an old request cannot overwrite newer authority changes.
  • Coordinate the single in-flight channel save across route instances so remounts cannot load an obsolete command, and bound it with a 30-second RPC deadline so a stuck request cannot block the page for the tab lifetime.
  • Reconcile non-auth save failures because a lost response cannot prove the server rejected the mutation; skip the extra request for auth or permission failures.
  • Invalidate only instance:update after permission denial so stale update controls disappear without discarding unrelated cached authority.
  • Use the shared settings landing helper after permission loss so Network is selected only with fleet:read; otherwise Preferences is the safe fallback.
  • Keep channel and copy controls disabled through persistence and refetch so displayed commands always match confirmed server state.
  • Show unavailable separately from up to date rather than treating failed discovery as success.

Testing & validation

  • npm run test -- --run src/protoFleet/features/settings/components/Updates.test.tsx (28 tests)
  • npm exec eslint -- src/protoFleet/features/settings/components/Updates.tsx src/protoFleet/features/settings/components/Updates.test.tsx
  • npm exec --no -- tsc --noEmit
  • Pre-commit formatting and pre-push client typecheck

@github-actions github-actions Bot added javascript Pull requests that update javascript code client labels Jul 30, 2026
@github-actions github-actions Bot added the review-policy: needs-review Managed by the Review Policy workflow. label Jul 30, 2026
@github-actions

github-actions Bot commented Jul 30, 2026

Copy link
Copy Markdown

🔐 Codex Security Review

Note: This is an automated security-focused code review generated by Codex.
It should be used as a supplementary check alongside human review.
False positives are possible - use your judgment.

Scope summary

  • Reviewed pull request diff only (4d23941482fda8fe8126d7b1cf66f86dd5e704b0...d9faa6058f3988375940f6bdf07502f64d12c61c, exact PR three-dot diff)
  • Model: gpt-5.5

💡 Click "edited" above to see previous reviews for this PR.


Review Summary

Overall Risk: NONE

Findings

No security, correctness, or reliability findings met the bar in the reviewed diff.

Notes

Reviewed .git/codex-review.diff as the authoritative scope for commit d9faa6058f3988375940f6bdf07502f64d12c61c. The changes add the ProtoFleet Updates settings route, permission-gated navigation, status rendering, release-channel mutation handling, copy-to-clipboard behavior, route prefetching, tests, and a visual snapshot update.


Generated by Codex Security Review |
Triggered by: @mcharles-square |
Review workflow run

@mcharles-square
mcharles-square force-pushed the codex/release-updates-04-settings branch from 93e7d47 to 355ee5f Compare July 31, 2026 18:30
Base automatically changed from codex/release-updates-03-backend to main August 1, 2026 04:36
@mcharles-square
mcharles-square force-pushed the codex/release-updates-04-settings branch from 355ee5f to c89c567 Compare August 1, 2026 04:44
@github-actions github-actions Bot added the documentation Improvements or additions to documentation label Aug 1, 2026
@mcharles-square
mcharles-square marked this pull request as ready for review August 1, 2026 04:46
Copilot AI review requested due to automatic review settings August 1, 2026 04:46
@mcharles-square
mcharles-square requested a review from a team as a code owner August 1, 2026 04:46

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds a new permission-gated Settings → Updates surface in the ProtoFleet client that lets instance:update holders view the running server version, see an eligible release (with release notes + manual install command), and opt into Stable vs Stable+RC with stale-response protection during channel persistence/refetch.

Changes:

  • Adds the /settings/updates route with lazy loading and idle-time prefetch wiring.
  • Introduces the Updates settings page UI (status states, channel mutation/refetch sequencing, and stale-response guard).
  • Centralizes install-command clipboard + toast feedback in a shared (ProtoFleet-local) helper and adds focused unit tests.

Reviewed changes

Copilot reviewed 9 out of 10 changed files in this pull request and generated no comments.

Show a summary per file
File Description
docs/plans/2026-07-27-001-feat-release-update-notifications-plan.md Updates the implementation plan to reflect request ordering + disabled-controls behavior.
client/src/protoFleet/router.tsx Registers the new Settings → Updates route with lazy loading.
client/src/protoFleet/routePrefetch.ts Adds the Updates page importer to the settings prefetch tier.
client/src/protoFleet/features/updates/copyInstallCommand.ts Adds a shared helper for copying the install command with consistent toast feedback.
client/src/protoFleet/features/settings/components/Updates.tsx Implements the Updates settings page (status rendering, channel save + refetch flow, stale-response guard).
client/src/protoFleet/features/settings/components/Updates.test.tsx Adds unit tests covering rendering, permissions, copy behavior, request ordering, and pending-control disabling.
client/src/protoFleet/config/navItems.ts Adds a nav entry for Settings → Updates gated by instance:update.
client/src/protoFleet/config/navItems.test.ts Verifies the Updates nav item permission gate.
client/src/protoFleet/api/clients.ts Adds the InstanceUpdateService client export used by the Updates page.

Comment thread client/src/protoFleet/features/settings/components/Updates.test.tsx Outdated
Comment thread client/src/protoFleet/features/settings/components/Updates.test.tsx
Comment thread client/src/protoFleet/features/settings/components/Updates.test.tsx Outdated
Comment thread client/src/protoFleet/features/settings/components/Updates.tsx Outdated
Comment thread client/src/protoFleet/features/settings/components/Updates.tsx Outdated
@github-actions github-actions Bot added review-policy: human-approved Managed by the Review Policy workflow. and removed review-policy: needs-review Managed by the Review Policy workflow. labels Aug 1, 2026
@github-actions github-actions Bot added review-policy: needs-review Managed by the Review Policy workflow. and removed review-policy: human-approved Managed by the Review Policy workflow. labels Aug 1, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bf402be4f9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread client/src/protoFleet/features/settings/components/Updates.tsx Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f18196ecb1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread client/src/protoFleet/features/settings/components/Updates.tsx Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9124a111d3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread client/src/protoFleet/features/settings/components/Updates.tsx
@mcharles-square
mcharles-square merged commit 43a7f44 into main Aug 1, 2026
69 of 73 checks passed
@mcharles-square
mcharles-square deleted the codex/release-updates-04-settings branch August 1, 2026 11:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

client documentation Improvements or additions to documentation javascript Pull requests that update javascript code review-policy: needs-review Managed by the Review Policy workflow.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants