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.
IGNORE, BLOCK, REMOVE, or unpaired) is
silently filtered out of the picker — you won't see the agent at
all. Promote via the Pairing menu first.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.
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:
<personality>/fixo/)BuildManager the Agent uses for
local editsController::flashFirmwareThe 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.
| 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 |
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.
Two separate checks gate every deploy:
BlobCourier rejects any incoming
blob whose source isn't at TrustLevel::TRUST in the AddressBook.
The blob never reaches the deploy pipeline.Both gates use the same binary TrustLevel::TRUST check — there is
no "minimum trust level" knob.
TrustLevel::TRUST