On this page
Target
What is a registry target, and why is it not the same thing as a hostname? A target is one routable box the fleet has written down; a hostname is one of the several names that box may answer to.
What it is
A target is one entry in the targets[] array of the canonical
registry — "one routable box", in the words of
stado-rs/src/targets/target.rs. The registry is the single source of truth for
every box the queue can route to: workstations, GCP zonal dispatchers,
vast.ai pools. A target carries, among other fields:
| Field | Meaning |
|---|---|
name |
The fleet's word for the box. Lowercase [a-z0-9._-], validated by the registry-v2 contract. |
kind |
local, gcp, or vast. |
hostnames[] |
Every name the machine itself answers to. |
ssh |
The channel destination ([user@]host[:port]), stored verbatim. |
role, host_heuristic |
Stable placement class and the declarative selector that resolves to exactly one local target. |
services[] |
The units Stado must keep running there — see service. |
managed_versions |
The version each stado-managed binary is required to be at; optional, and a target that omits it is reported undeclared, not agreeing. |
Unknown per-target keys round-trip through the target's extra map, so a
writer built from an older checkout cannot delete a field a newer one added
(targets.rs, ComputeTarget).
Who declares it
An operator, through stado registry host add HOST --ssh DEST --release-platform PLATFORM or by editing the document and running
stado registry push. Declaration reads nothing from the machine — it is an
assertion, and stado registry doctor is what later diffs the assertion
against reality (cli).
The same operator changes what add declared with stado registry host edit HOST [--ssh DEST] [--kind KIND] [--release-platform PLATFORM] [--json], and
retires a machine with stado registry host remove HOST [--json]. Both write
under the generation they read, so a registry that moved in between is
refused with exit 75. A field add does not write is changed with stado registry set --path targets.<host>.<field> --value VALUE.
Refusals, word for word:
name at least one of --ssh, --kind or --release-platform to change(exit 2):editwas given nothing to change.--ssh must not be empty(exit 2).registry target "<host>" not found: no target answers to that name;stado registry pull --path targetslists the names that do.<host> is still named at <paths> in <registry>; move or remove those entries first (stado registry set --path <path> --value <other host>), then remove <host>:removefound a service, database or other entry still pointing at the host, and lists every such path.
edit that changes nothing writes nothing and says so: <host>: already declares those values in <registry>; nothing written.
Who observes it
Everything that routes or repairs. The scheduler admits jobs only against
targets whose declared capabilities match (architecture).
stado host inventory <target> reconciles the declaration against the live
host. Beacon readers resolve a target to its host_health/<slug>.json object.
The coordinator's rogue-daemon kill switch exits when a successfully read
registry omits this machine's entry (targets.rs).
Where it lives in the store
registry.json, in the backend STADO_CONFIG selects — one document for the
whole fleet (architecture, canonical object layout).
A target is not a hostname
The fleet knows the box by name; the machine knows itself by whatever
hostname returns, and the two are routinely different spellings of one
machine. The beacon writer (stado host beacon collect, which the host
process runs on its health period) publishes under the machine's own short
hostname, lowercased — so the target and its beacon file are spelled
differently on a machine named twice, and every reader must try the name and
every hostname the registry declares for it.
The matching rule is beacon_slugs in
stado-rs/src/monitor/host_health/load.rs: for each identity — the declared
hostnames[], the target name, the identity the
caller asked for, and the hostname inside the ssh destination — take both
the first dot-label and the full normalized form (trimmed, lowercased,
trailing dot stripped), skip empty or /-containing candidates, and
deduplicate preserving order. The beacon script applies the same idea from
the other side: it matches the local hostname against the target name and
declared hostnames "with the local suffix dropped", so some-mac.local and
some-mac are one identity.
The practical rule: when a machine's self-reported hostname differs from its
target name, put every spelling in hostnames[]. A spelling the registry
does not declare is a beacon nobody can find.
Commands that act on it
stado registry host add HOST --ssh DEST --release-platform PLATFORM
stado registry host show HOST [--path FIELD]
stado registry host edit HOST [--ssh DEST] [--kind KIND] [--release-platform PLATFORM] [--json]
stado registry host remove HOST [--json]
stado registry self [--local] [--name-only | --json]
stado registry pull
stado registry doctor
stado host inventory <target>
stado host health <target>
Full flags in the cli reference.
Which target is this machine
stado registry self reads the canonical registry, from the registry
authority when the store is another host's object API. stado registry self --local answers from this machine's own record instead and never asks
another host: the store itself when it is a local directory, otherwise the
last-known-good copy ~/.stado/cache/registry-last-good.json that this host's
resolver rewrites on every refresh. A local stado product install decides
whether a receipt's host is this machine with stado registry self --local --json, so an installation here finishes while the host that keeps the
registry does not answer.
--json prints {"name", "kind", "hostname", "source"}; a machine the
record does not carry is answered with "name": null. Without --json that
machine is refused as host <hostname> is not in <record>. A machine that
keeps no record is refused:
this machine keeps no usable local registry record: <home>/.stado/cache/registry-last-good.json and its .meta.json sidecar are not both there and readable; this host's resolver writes them on every refresh, and `stado registry self` without --local writes them once the registry authority answers
tests/install/local_identity.rs runs the real stado in an isolated home
against a real OpenSSH server standing for the authority, which answers one
read and is then stopped with SIGSTOP, so it accepts connections and never
answers; it checks that no --local read announced a connection to it.
Observing GUI automation
stado workload run gui-automation --target <target> with a status plan reads the selected Mac's installed
driver, login session, managed runtime and serving CuaDriver socket. It calls
check_permissions with prompt: false; this status command does not request
macOS consent or open System Settings.
accessibility-record describes the stored TCC entries. accessibility
describes what the serving driver actually reports: granted, denied, or
unobserved. An unreadable reply or missing socket also produces
accessibility-error with the failed operation and its cause. A stored grant
does not prove the running driver can use it.
gui-ready: yes requires the declared login session, the running managed
driver, its socket, and an observed Accessibility grant. A driver reporting
denied therefore produces gui-ready: no, even when the stored entries say
granted. Do not treat that state as permission to run GUI actions or bypass
macOS consent.
Not to be confused with
- A hostname. One target may carry several; matching uses the stem rule above, never string equality on the raw name.
- An SSH destination.
sshis one field of the target, stored verbatim; the target name is what every command takes. - A service. A target is a box; a service is a unit declared on a box.
- A beacon. The target is the declaration; the beacon is what the box itself reports.
Source: this website