On this page

Host connections

Every Stado host operation reaches its target over one of the routes that host's registry declaration names. The declaration is ordered, the product tries the routes in that order, and the receipt says which one carried the command. No connection provider is built into the product: tailscale, lan, nebula and primary are names an operator declares, and a host that loses one of them keeps working over the next.

Declaration

The routes live on the registry target in canonical registry.json:

  • targets[].ssh is the preferred destination and is always the path named primary.
  • The target's alternate-route array holds the rest, read top to bottom. Each entry carries name (a lowercase identifier other than primary) and destination ([user@]host[:port]). At most sixteen are accepted, and a duplicate name or destination is refused by registry validation.
  • stado registry host path list <host> --json is the read contract: one connections array with name, destination, order and preferred.

A host that declares one destination behaves exactly as before: one route, tried once. The Mac mini in this fleet declares two — primary on its Tailscale address and lan on 10.0.0.253 — so an operation survives the Tailscale path going down.

Choosing and changing the provider

stado registry host path list <host> [--json]
stado registry host path set <host> <path> --ssh <[user@]host[:port]> [--priority <n>] [--json]
stado registry host path remove <host> <path> [--json]

list prints the preferred path and the ordered alternates with their positions. set adds or replaces one path: --priority places an alternate (counting from 1); omitting it keeps an existing position or appends. Passing --priority for primary is refused with the primary path is always preferred and does not take --priority, and removing it is refused with the primary path cannot be removed; replace it with registry host path set. Every write goes through the canonical registry's compare-and-swap and validates the whole document first, so a refused declaration changes nothing.

How a connection is chosen

stado-rs/src/deploy/host_channel.rs owns the selection. A target that is this machine is answered locally without any ssh at all. A target with one declared route uses it. A target with several probes them in declared order and takes the first that answers, so a dead preferred route costs one probe rather than the operation. A target with no declared route is refused with target "<name>" has no registry-managed SSH connection path.

The route that carried the work is reported, not inferred: host command receipts carry used_connection with the path's own name, or local for the machine itself. A receipt that published only the declared routes could not distinguish a healthy preferred path from a dead one whose alternate rescued the read.

Where it is visible

  • stado registry host path list <host> --json — the declaration.
  • stado host link <host> — the probe of every declared route, and the silences recorded against them.
  • stado host exec and the other host commands — used_connection in the receipt.
  • Stado Desktop, Hosts inspector: the routes sheet lists the preferred route and its alternates with their probe results, and its editor writes exactly the registry host path set and remove calls above, showing the command line before it runs.

Real tests

stado-rs/tests/connection_provider/main.rs drives the shipped binary against an isolated registry: a local target reports the local channel, a duplicate route is a typed refusal that changes nothing, and — against a registered fleet host named in STADO_CONNECTION_PROVIDER_HOST, run with --ignored — an unroutable preferred path hands over to the declared alternate and the receipt names the route that answered.

Source: this website