Fleet rollouts

Status: implemented for Linux Agents that advertise agent_update and locally configured release trust.

CommandCore fleet rollout is deliberately separate from release signing. The control plane may select an already-signed release manifest and coordinate a rollout, but it cannot create a trusted release signature or replace the root-owned signing key/origin policy on a device.

Trust boundary

A device is eligible only when all of these are true:

The control plane never sends a release public key to agent.update.stage.

State machine

planned
  |
  v
running ring 0 (canary)
  |
  +-- pending -> staging -> staged -> activating
  |                              |
  |                              +-- authenticated reconnect + committed local rollout
  |                                      -> committed
  |
  +-- failure -> paused (default stop_on_failure=true)
                 |
                 +-- operator resume / skip / cancel

all devices in ring satisfied
  -> next ring
  -> ...
  -> completed

Activation normally disconnects the network Agent because systemd restarts it. That disconnect is not treated as success or failure. The authoritative commit signal is the new Agent reconnecting with the target agent_version while its local rollout state advertises committed.

Why advance is one step at a time

POST /api/fleet-rollouts/{id}/advance performs at most one durable remote action. This keeps rollout state observable and crash-recoverable and avoids a hidden long-running loop inside the web process. An operator, automation, or a future dedicated controller can call advance repeatedly.

API

GET    /api/fleet-rollouts
POST   /api/fleet-rollouts
GET    /api/fleet-rollouts/{id}
POST   /api/fleet-rollouts/{id}/advance
POST   /api/fleet-rollouts/{id}/resume
POST   /api/fleet-rollouts/{id}/devices/{device_id}/skip
DELETE /api/fleet-rollouts/{id}

Example create payload:

{
  "target_version": "0.9.0-rc7",
  "manifest_url": "https://updates.example.org/commandcore/manifest.json",
  "device_ids": ["device-a", "device-b", "device-c"],
  "canary_count": 1,
  "ring_size": 2,
  "stop_on_failure": true
}

Per-device MCP tools

Fleet orchestration is built on the same device tools available to authorized MCP clients:

agent.update.status      READ_ONLY
agent.update.stage       FULL_CONTROL
agent.update.activate    FULL_CONTROL
agent.update.rollback    FULL_CONTROL

stage, activate, and rollback are critical-risk audited operations.

Local Linux policy

The trusted release key and manifest origin are local administration settings, not fleet-plan input. Example installation:

sudo ./agent/install-linux.sh \
  --max-profile FULL_CONTROL \
  --update-public-key-b64 '<ED25519_PUBLIC_KEY_BASE64>' \
  --update-manifest-origin 'https://updates.example.org'

The resulting /etc/commandcore/agent-policy.json is root-owned.

Current limits

Recovery behavior

Fleet state is designed to survive ordinary control-plane/transport interruptions: