Skip to content

feat(fleet): desktop Fleet enrollment and live runner dashboard (RUN-8/RUN-9) - #280

Closed
KafuChino123 wants to merge 22 commits into
masterfrom
feat/fleet-runner-integration
Closed

feat(fleet): desktop Fleet enrollment and live runner dashboard (RUN-8/RUN-9)#280
KafuChino123 wants to merge 22 commits into
masterfrom
feat/fleet-runner-integration

Conversation

@KafuChino123

Copy link
Copy Markdown
Member

Summary

Turns the CI Runners section (RUN-9) into a live Fleet integration. Desktop now talks to the local arcbox-fleet-agent over its Unix-socket control API, exchanges the signed-in OIDC session for a workspace-scoped enrollment token via the Platform REST API (RUN-8), hands that token to the Agent, and renders the Agent's live Watch stream — including the RUN-31 macOS VM backend state (agent update state, VM settings, runner-image preparation progress).

Stacked as reviewable groups:

  1. FleetControlClient package (0ef52edc7a2a4b, e30cf62, 88865f9) — generated from the arcbox master control proto; the exact source commit and sha256 are recorded in Packages/FleetControlClient/PROTO_SOURCE (currently arcbox@224eedbd, reproducible via generate.sh). Hand-written facade for lifecycle (Enroll/Drain/Resume/Unenroll), the Watch stream, settings with field-presence semantics, and the image-prepare stream.
  2. FleetPlatformClient package (891bd7b, 87e135a) — authenticated REST client (GET /v1/workspaces, POST /v1/fleet/enrollment-token) consuming AccessTokenProviding; enrollment tokens stay in memory only. The contract was taken from the arcboxlabs/platform handler source and the live openapi.json, then confirmed with read-only probes against production.
  3. Enrollment orchestration (ec417a2, ccf6c85, 116ee9b) — FleetEnrollmentCoordinator treats Enroll as non-idempotent: baseline-snapshot gate before requesting a token, unknown-outcome reconciliation from the Watch stream, bounded attach timeout, app-scoped operation that survives window close, and a graceful settle pass on app termination.
  4. RUN-9 dashboard (0378091/4cd5936 — original commits by @AprilNEA, cherry-picked with authorship preserved — plus 9fa0f9c, 87f0db4, 40f168b, 893234f) — every UI state is explicit: connecting, agent-unavailable, signed-out, unenrolled onboarding with workspace picker, six enrollment-progress phases, three failure-recovery paths (retry / wait-for-agent / unenroll), and the live host view (status bar, in-flight jobs, image-prep progress).
  5. Fleet Settings pane (177d4e3, 570ee15) — participation, load ceiling, memory floor, Docker mode, macOS VM mode, and runner image with readiness + preparation progress.

Supersedes origin/feat/run-9-runner-section (left untouched).

Verification

  • 135 app tests + 18 package tests green locally; the coordinator state machine has ~800 lines of dedicated tests.
  • Exercised against a real arcbox-fleet-agent built from arcbox master (224eedbd) and installed via its own install-service: handshake, Watch stream, settings, and the unenrolled → UI state mapping all verified live.
  • Platform REST verified with read-only probes only (routes and AIP-193 error shapes confirmed); POST /v1/fleet/enrollment-token was deliberately not exercised against production because it rotates the live workspace secret.
  • Not yet verified end-to-end: a real production enrollment (blocked by item 1 below) and the full macOS-VM job round trip driven from the Desktop UI.

Blockers / asks — input wanted

  1. Platform — auth mismatch (blocks production e2e). api.arcbox.dev currently authenticates Better Auth session tokens; Desktop presents its OIDC access-token JWT. The API needs to accept the JWT (e.g. via JWKS verification) or define an exchange. Until then, sign-in works but Desktop cannot successfully call POST /v1/fleet/enrollment-token. (Xuan — this is the RUN-8 auth contract question.)
  2. arcbox — three Agent fixes need upstreaming (currently exist only as local commits on the machine this was developed on): idempotent/durable Unenroll; macOS image-preparation bootstrap (a clean machine can never pull its first image and falsely reports ready); verified image-readiness reporting. Desktop behavior here was validated against an Agent that includes them.
  3. arcbox — atomic Enrolling admission gate. Two concurrent Enroll calls can both reach gateway credential exchange; Desktop's Watch-based reconciliation only mitigates this. The real gate belongs in the Agent.
  4. Team decision — daemon lifecycle on quit. AppDelegate still calls disableDaemon() when Desktop quits, which can pull arcbox-daemon out from under a Fleet VM job. A fix was drafted and intentionally shelved pending team discussion.
  5. Agent first-install ownership. By design, Desktop never downloads, installs, launches, or updates the Agent (FleetAgentConnection maintains the channel only). A clean machine currently has no bootstrap path — proposal: Platform-provided manifest (version/URL/SHA-256) + an owned installer story.
  6. Release gating. This branch exposes the Runners section in Release builds, with guided empty/error states when the Agent or Platform isn't available. Given items 1 and 5, should it ship visible or stay gated until e2e works?

Follow-ups (non-blocking)

  • Enforce HTTPS-only in FleetPlatformConfiguration (Bearer token transport).
  • Scrub raw error bodies from OIDC client logs.
  • Adopt GET /v1/fleet/enrollment-token (status-only) for a "this will revoke the current token" confirmation before rotation.

KafuChino123 and others added 22 commits July 14, 2026 23:00
Add a FleetControlClient Swift package with generated protobuf and gRPC stubs for the fleet agent local control API.

Wire the local package into the ArcBox app target so phase 1 desktop integration can import the generated client types.
Wrap the generated fleet control stubs in a high-level client for lifecycle, state watch, and settings RPCs.

Map proto responses into desktop-facing models while preserving optional settings update presence semantics, and cover the mapping behavior with tests.
Add the local fleet control client to SwiftUI environment values and app scene injection.

Start the fleet control transport outside daemon startup, log through the fleet category, and close it during app termination.
Drive fleet agent state from the local control watch stream.

Add lifecycle actions, settings updates, reconnect backoff, and user-readable error handling for the runners dashboard.
Consume the signed-in OIDC session to list Platform workspaces and issue workspace-scoped Fleet enrollment tokens.

Wire token issuance into local Fleet Agent enrollment and configure the Platform endpoint for app and CI builds.
Replace RUN-9 sample data and stub actions with FleetViewModel watch snapshots, workspace enrollment, and local drain/resume controls.

Expose the runner section in release builds and cover the presentation-state mapping.
Let ArcBoxTests consume FleetControlClient through the hosted ArcBox target, avoiding Xcode’s duplicate dynamic gRPC package graph.

Handle runner item-selection deep links explicitly so navigation remains exhaustive.
- coordinate authenticated token handoff with local Agent state
- keep Fleet watch and client transport app-scoped
- reconcile unknown outcomes and graceful termination
On macOS 26, any state change inside a fixedSize(vertical: true)
subtree triggers a window-sizing pass that resizes the window — or the
NavigationSplitView content when the window cannot grow — to the
screen's visible-frame height, sliding the sidebar under the title bar
and pushing the account button off-screen. Drop the modifier from the
dynamic error label (it wraps identically without it) and document the
pitfall in AGENTS.md.
@linear-code

linear-code Bot commented Jul 15, 2026

Copy link
Copy Markdown

RUN-8

RUN-9

@KafuChino123

Copy link
Copy Markdown
Member Author

Superseded by #281, which carries the same integration stack rebased onto master v1.23.2+ on the original feat/run-9-runner-section branch.

@KafuChino123
KafuChino123 deleted the feat/fleet-runner-integration branch July 16, 2026 15:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants