On this page

Command surface: capabilities, not one verb per incident

Measured 2026-09-06 against stado 0.16.42 built from main at 544dc63b, by walking --help to its leaves.

The binary answers 382 leaf invocations across 52 groups. host alone carries 93, service 46, fleet 26, release 18, inference 17. That is not a wide product. It is a narrow product with a verb per incident, and the cost is measurable in three places: 116 of those 382 invocations have no prose page at all, the 62 test areas cannot be addressed by command (see test suite), and every new product arrives as another verb instead of another declaration.

Two commands, read from the binary

stado host jeden-connect <WORKSPACE> places an interactive Jeden RPC session on a live registry host and attaches it to the calling process's stdin and stdout. --target reconnects to the host that owns a durable session and --resume requires the selected host to own a named ~/.jeden/sessions ledger.

stado host weles-capture <TARGET> --plan <PLAN> enqueues one batch of generic_capture actions on that host's Weles admission API from a checked-in plan of schema wisent.weles-capture-plan.v1, refusing the plan in full before enqueueing any of it.

Read them next to each other and they are one thing: place work on the host the fleet chooses, then hand back a stream or a batch receipt. One is spelled as an interactive session for one product, the other as a batch for another. Neither goes through the queue that already exists for exactly this, and neither can be asked for by a workload that is not Jeden or Weles.

The declaration is already there and nothing reads it

The registry validates targets[].weles.actions on write — validate_action_list in stado-rs/src/targets.rs:902 — and that validator is its only reader in the crate. So the fleet already declares which actions a host may run, and nine host weles-* verbs exist beside that declaration instead of one capability that consumes it. ARCHITECTURE.md names this shape outright: a declaration must not be writable without a typed consumer that reads it. The inverse is the rule this page adds: a consumer must not need a new verb per declaration.

The same is true of the product catalog. stado-rs/data/products.json declares three products with name, version, source, platforms, install, units, why, compiled in through include_str! in deploy/products/mod.rs. What it does not declare is a product's operations — so every operation became a host verb.

The 93 host subcommands are seven capabilities and nineteen primitives

Counted from the walk, not sorted by hand:

Capability Replaces Reads
Workload placement and attach (15) jeden-connect, weles-capture, weles-capture-status, weles-browser-task, weles-browser-runtime, weles-run-diagnostics, weles-image-inspect, weles-activity, weles-api-runtime, weles-recordings-dir, mobile-runtime, `gui-automation enable disable
Declared repair (13) recover, recover-object-api, recover-skarbiec-audit, recover-skarbiec-crypto, recover-skarbiec-acquisition-state, repair-link, repair-release-store, reconcile, reconcile-agent-skarbiec, reconcile-object-verifier, reconcile-release-verifier, reconcile-service-verifier, storage-root-reconcile each service's own declared repair in the service catalog: what wedges, what restores it, what proves it
Runner as a fleet capability (12) `precheck-runner install status
Credential operations (11) vault-item-put, vault-item-show, vault-token-mint, vaults, retag-vault-item, sync-vault, sync-acquisition-scopes, grant-item-read, grant-show, backup-audit, authenticator-seed-freshness Skarbiec's own surface, addressed per host — the credentials group already carries 13 invocations for this
Host space (9) disk, disk-cleanup, cleanup, reclaim, `build-caches report prune, object-relocate, remove-file, retire-file`
Routing (7) forward-local, forward-remote, forward-close, capability-route, resolver-key, publish-placement-policy, mobile-placement the service directory, which already owns who serves a name and at which endpoint
Host release state (7) declare-version, promote-version, activate-staged-release, verify-release-platform, release, software, provenance the release manifest and the host's delivery history — the release group already owns this vocabulary

The nineteen that stay are host primitives, because each answers one fact nothing else can: health, inventory, link, ping, uptime, exec, gates, unit-log, reboot, publish-beacon, beacon-units, cron, gpu-power-limit, config-show|set|unset, user create|delete, render-spis-admission-trust.

What makes a new verb correct

A new command is right when no declaration can express the thing and no existing capability can consume it. That is the whole test, and it is failed by every verb in the table above: each one names a product, a vendor or an incident, and each one would have been a row in a declaration the fleet already carries.

Two consequences follow, and they are the point of the plan:

  • Adding a product must not add a command. Weles, Jeden, Skarbiec and the publisher each got their own verbs. The next product gets a declaration.
  • A capability gets one test area. Seven capabilities are seven areas with a story each; 93 verbs cannot be tested at all, which is why 20 of the 49 command groups have no test area today.

Migration, one capability at a time

Each capability lands with the declaration it reads, every caller moves to it, and the verbs it replaces are removed in the same change — a superseded command left beside its replacement is a second source of truth, and the one nobody calls is the one that rots. The order follows the cost of being wrong: workload placement first, because it is the one an operator reaches for daily and the one where a wrong host is a silently wasted run; then declared repair, because it runs when something is already broken; then runners, credentials, space, routing, host release state.

Nothing on this page is a promise that the verb count drops on its own. It drops when a capability ships and takes its verbs with it.

Source: this website