Deploy a preset to an Agent

The Deploy to Agent workflow takes a preset you've authored on Hub and ships it across the trust boundary to a paired Agent — preset, custom types, build, flash, set-active — in one click. It's the recommended path once you have a stable wireless or USB pairing between Hub and Agent. For air-gapped or one-shot transfer, see the legacy Share a preset howto.


Prerequisites


The flow

Hub side

  1. Open Studio → Presets on Hub.
  2. Right-click the preset you want to deploy → Deploy to Agent….
  3. The picker lists every paired+TRUSTED agent. Pick one.
  4. Decide whether to tick Set as active stanza set on arrival:
  5. Click Deploy.

A small non-modal toast shows progress (chunk count). You can cancel mid-flight; the Agent times out and cleans up its half-buffered state within ~30 seconds.

Agent side

The Agent's user sees a permission dialog the first time a given Hub tries to deploy:

┌────────────────────────────────────────────┐
│  Deploy request                            │
│                                            │
│  Hub "<sourceName>" wants to deploy preset │
│  "<presetName>" to this Agent.             │
│                                            │
│  This will:                                │
│   - install <N> custom types               │
│   - replace the active firmware            │
│                                            │
│  [ ] Always allow deploys from this Hub    │
│                                            │
│       [Reject]              [Accept]       │
└────────────────────────────────────────────┘

Tick Always allow deploys from this Hub to skip the prompt for all future deploys from the same Hub. The setting is stored in AgentConfig.trustedDeploySources and persists across restarts.

After acceptance the Agent runs the pipeline:

  1. Unzip into a staging area
  2. Validate (preset JSON parses, manifest hash matches, custom types resolve)
  3. Commit (copy preset + customs into <personality>/fixo/)
  4. Build firmware via the same BuildManager the Agent uses for local edits
  5. Flash via Controller::flashFirmware
  6. If "Set as active" was ticked, switch active to the new preset

The Hub then receives a status reply (deployed_ok, build_failed, flash_failed, custom_type_conflict, validation_failed, or rejected) and shows it as a toast.


Why didn't my deploy land?

Symptom on Hub Likely cause Fix
Agent not in picker Pair-trust isn't TRUST Promote in Pairing menu
BlobTransferFailed after delay Agent offline or unpaired mid-flight Check Agent's connectivity, retry
validation_failed Hub-side preset bundle missing customs Make sure all referenced custom types are present on Hub before deploying
custom_type_conflict Agent already has a same-named custom type with different contents Either edit the Agent's copy to match, or delete it before re-deploying
build_failed Agent's firmware compiler couldn't build the preset Check the Agent's logs for compiler diagnostics; the preset may rely on something the Agent's board doesn't support
flash_failed Serial / programming issue Check the Agent's wiring and the board's bootloader
rejected Agent's user clicked Reject in the prompt Ask them to accept or tick "Always allow" next time

Skipping rebuilds

If the Agent already has a preset with the exact same content hash already live, the deploy is detected as redundant — the build step is skipped and the Agent just re-confirms the active state. This keeps "deploy a fresh copy" cheap when nothing has actually changed.


Trust gate, in two places

Two separate checks gate every deploy:

  1. Comms-level: the Agent's BlobCourier rejects any incoming blob whose source isn't at TrustLevel::TRUST in the AddressBook. The blob never reaches the deploy pipeline.
  2. Picker-level: the Hub's deploy picker filters its agent list to TRUST-only peers, so you don't see un-deployable targets in the first place.

Both gates use the same binary TrustLevel::TRUST check — there is no "minimum trust level" knob.


See also