Skip to content

feat(updates): bridge Fleet API to host updater - #837

Merged
mcharles-square merged 5 commits into
mainfrom
codex/one-click-updates-03-fleet-api-bridge
Aug 5, 2026
Merged

feat(updates): bridge Fleet API to host updater#837
mcharles-square merged 5 commits into
mainfrom
codex/one-click-updates-03-fleet-api-bridge

Conversation

@mcharles-square

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

Copy link
Copy Markdown
Collaborator

Reviewable diff: +537/-27 across 8 files (excludes generated, test, and story files).

Summary

Adds the permission-gated Fleet RPC contract and Unix-socket client that mediate access to the host updater. Trigger requests now use the idempotent operation-ID contract introduced by #836, so Fleet can safely recover from a lost acknowledgement without starting a duplicate upgrade. When the daemon socket is absent, Fleet reports one_click_available=false, preserving the manual update experience.

Stack: #841#842#843#844#845#835#836#837#838#839#840. This is 3/6 of the one-click phase; its diff is relative to #836. The parent supplies the privileged updater and accepts both legacy target-only and new ID-bearing requests. Client exposure remains in #838#840; unsupported hosts continue using the manual flow.

How it works

GetUpdateStatus performs a bounded status probe and advertises one-click only when the independent executor is reachable. TriggerUpgrade re-derives the organization’s currently eligible release, rejects stale or arbitrary targets, creates an operation ID, and sends only that ID plus the validated tag over the Unix socket. A lost or malformed acknowledgement is retried once with the same ID, then reconciled against exact durable status; an unconfirmed outcome remains Unavailable rather than encouraging a second upgrade path. Confirmed triggers are activity-audited once using a cancellation-detached bounded context.

sequenceDiagram
  participant C as "Future capability-gated client"
  participant F as "Fleet InstanceUpdateService"
  participant U as "Host updater from #836"
  C->>F: "TriggerUpgrade(target)"
  F->>F: "Authorize and revalidate eligible target"
  F->>U: "POST operation ID + target"
  alt "Acknowledgement received"
    U-->>F: "Durable operation"
  else "Outcome is ambiguous"
    F->>U: "Retry same operation ID"
    F->>U: "GET durable status if still unconfirmed"
    U-->>F: "Exact operation ID or no confirmation"
  end
  F-->>C: "Operation or conservative Unavailable"
Loading

Areas of the code involved

Area / package / file What changed Why it matters for review
proto/instance/v1 Added capability, trigger/status RPCs, phases, and durable operation model Public compatibility and lifecycle contract
server/generated, client generated API Regenerated Connect and protobuf bindings Generated — skip
server/internal/domain/updates Bounded Unix-socket client, exact-ID retry/reconciliation, target revalidation, audit, and status mapping Trust and reliability boundary between org policy and privileged execution
server/internal/handlers/updates RPC authorization, cancellation-code preservation, protobuf mapping, and explicit denial tests Permission and error-contract enforcement
server/internal/handlers/interceptors Redacts update and operation responses and keeps mutation RPCs session-only Prevents host details from entering debug logs or API-key paths
server/internal/handlers/middleware Classifies both RPCs under org-wide instance:update Prevents unclassified or site-scoped access
server/cmd/fleetd Supplies activity logging to the update service Makes confirmed privileged mutations auditable

Key technical decisions & trade-offs

  • Revalidate the eligible target at mutation time rather than trusting the browser’s version value.
  • Retry ambiguous triggers with the same operation ID and reconcile only an exact ID/target match rather than guessing by release tag.
  • Preserve an unknown outcome as Unavailable rather than suggesting the install command, which could launch a second upgrade path.
  • Derive capability from a bounded live socket probe rather than a static flag that can drift from host state.
  • Expose only a narrow Unix-socket protocol to Fleet rather than mounting the Docker socket into the application.

Testing & validation

  • Focused update-domain, updater, handler, interceptor, middleware-contract, fleetd, and updater API tests.
  • Race detector for the update domain and host updater, including concurrent same-ID admission.
  • Real Unix-socket tests for request shape, status mapping, response bounds, cancellation, lost acknowledgements, and delayed admission.
  • Targeted Updates component test: 28 passing; client TypeScript check passing.
  • Proto lint, generated-output verification, Go imports, canonical server lint, and pre-push hooks passing.

@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 (017daf71aaa1fc9e3cc364080916d021f7a0bf48...8f245c115f60a9cc625a6568e09380755bc9a368, exact PR three-dot diff)
  • Model: gpt-5.6-sol

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


Review Summary

Overall Risk: NONE

Findings

No concrete security, correctness, or reliability issues were identified in the changed hunks.

Notes

The authoritative diff was structurally valid. Authentication, authorization, version validation, bounded executor communication, sensitive-response redaction, and protobuf compatibility were reviewed.


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

@mcharles-square
mcharles-square force-pushed the codex/one-click-updates-03-fleet-api-bridge branch from c7947bd to e43e2e7 Compare July 31, 2026 16:08
@mcharles-square
mcharles-square force-pushed the codex/one-click-updates-03-fleet-api-bridge branch from e43e2e7 to 3a85af8 Compare July 31, 2026 16:18
@mcharles-square
mcharles-square force-pushed the codex/one-click-updates-03-fleet-api-bridge branch from 3a85af8 to 0c2c419 Compare July 31, 2026 18:27
@mcharles-square
mcharles-square force-pushed the codex/one-click-updates-03-fleet-api-bridge branch from 0c2c419 to 15049e3 Compare July 31, 2026 18:30
@mcharles-square
mcharles-square force-pushed the codex/one-click-updates-03-fleet-api-bridge branch from 15049e3 to 4386fad Compare August 5, 2026 11:09
Base automatically changed from codex/one-click-updates-02-host-updater-engine to main August 5, 2026 16:01
@mcharles-square
mcharles-square force-pushed the codex/one-click-updates-03-fleet-api-bridge branch from 4386fad to 6ffb136 Compare August 5, 2026 16:01
@mcharles-square
mcharles-square marked this pull request as ready for review August 5, 2026 16:06
Copilot AI lite review requested due to automatic review settings August 5, 2026 16:06
@mcharles-square
mcharles-square requested a review from a team as a code owner August 5, 2026 16:06

@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: 6ffb136618

ℹ️ 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 proto/instance/v1/updates.proto

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

This PR extends the Fleet updates surface to support one-click host upgrades by adding new InstanceUpdateService RPCs (TriggerUpgrade, GetUpgradeStatus) and wiring them through the server updates domain to a bounded Unix-socket HTTP client that talks to the privileged host updater.

Changes:

  • Add upgrade trigger + durable upgrade status RPCs to the updates proto contract (plus regenerated bindings).
  • Implement server handler + middleware/interceptor policy for the new procedures (session-only, permission-gated, response redaction).
  • Add updates-domain executor client + trigger/retry/reconcile logic and activity auditing for confirmed triggers.

Reviewed changes

Copilot reviewed 15 out of 18 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
server/internal/handlers/updates/handler.go Adds RPC handler methods for triggering and reading upgrade status; maps domain operation/phase to protobuf.
server/internal/handlers/updates/handler_test.go Adds coverage for upgrade phase enum mapping.
server/internal/handlers/updates/handler_perms_test.go Extends permission-gating tests to the new update RPCs and cancellation-code mapping.
server/internal/handlers/middleware/rpc_permissions.go Classifies new update procedures under instance:update.
server/internal/handlers/interceptors/config.go Adds new procedures to session-only and redacted-response lists.
server/internal/handlers/interceptors/config_test.go Ensures new procedures are session-only and redacted.
server/internal/domain/updates/service.go Implements one-click availability probing, trigger logic with same-ID retry + reconciliation, and durable status retrieval.
server/internal/domain/updates/service_test.go Adds executor fakes and tests for trigger mapping, retry/reconcile semantics, and upgrade status behavior.
server/internal/domain/updates/executor.go Introduces Unix-socket HTTP client with bounded JSON decoding and error typing.
server/internal/domain/updates/executor_test.go Adds integration-style tests around Unix-socket request/response shapes, bounds, and retry behavior.
server/internal/domain/updates/config.go Adds UpdaterSocketPath config and validates it is absolute when set.
server/internal/domain/updates/config_test.go Adds validation coverage for UpdaterSocketPath.
server/cmd/fleetd/main.go Wires activity logging into the updates domain service construction.
proto/instance/v1/updates.proto Adds upgrade RPCs/messages and one_click_available + upgrade phase/operation schema.
server/generated/grpc/instance/v1/updates.pb.go Generated Go protobuf output for the updated updates contract.
server/generated/grpc/instance/v1/instancev1connect/updates.connect.go Generated Connect-RPC bindings for new procedures.
client/src/protoFleet/features/settings/components/Updates.test.tsx Adjusts helper typing for generated message overrides.
client/src/protoFleet/api/generated/instance/v1/updates_pb.ts Generated TS protobuf output for the updated updates contract.

Comment thread server/internal/domain/updates/executor.go
Comment thread server/internal/domain/updates/service.go Outdated
Comment thread server/internal/domain/updates/service.go Outdated
@github-actions github-actions Bot added review-policy: human-approved Managed by the Review Policy workflow. review-policy: needs-review Managed by the Review Policy workflow. and removed review-policy: needs-review Managed by the Review Policy workflow. review-policy: human-approved Managed by the Review Policy workflow. labels Aug 5, 2026
@mcharles-square
mcharles-square force-pushed the codex/one-click-updates-03-fleet-api-bridge branch from 7c3aa70 to 8f245c1 Compare August 5, 2026 17:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

client javascript Pull requests that update javascript code review-policy: needs-review Managed by the Review Policy workflow. server shared

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants