On this page

Workloads

stado workload places declared work on an eligible registry host and returns either the interactive stream or the workload's report/receipt. Workload names, product ownership, interaction mode, registry gates, accepted plan schemas, and report fields are data rather than CLI variants. A new product workload is one row in the declaration.

Invocations

  • stado workload list [--json]
    • Lists every compiled workload kind. --json returns {schema_version, workloads} and each workload carries kind, product, interactive, registry_allowance, plan_schema, and report.
  • stado workload run <KIND> [--target <TARGET>] [--plan <FILE>] [--json]
    • Runs a non-interactive kind. --target pins placement; without it Stado chooses an eligible local registry target. --plan supplies the declared JSON schema. --json returns the workload report or receipt. A workload whose process failed reports that process's own last output: weles-browser-task carries stdout_tail and stderr_tail in its report, and its refusal sentence quotes both, so the failing browser step is read instead of the newest warning line.
  • stado workload status <KIND|ID> [--target <TARGET>] [--json]
    • Reads a kind report. Capture and diagnostic receipts may be addressed as weles-capture:<batch> and weles-diagnostics:<run-id>; a bare receipt ID is treated as a capture batch. --target pins the report host. --json returns the full report.
  • stado workload attach <KIND> [--target <TARGET>] [--workspace <WORKSPACE>] [--resume <SESSION>]
    • Attaches inherited stdin/stdout/stderr to an interactive kind. jeden-session derives the workspace from the current directory, selects by live capacity when unpinned, and attaches to the managed Jeden runtime whose durable ledger is ~/.jeden/sessions. --resume requires the selected host to own that named ledger. Nothing but the managed jeden and stado binaries is required on the host: the attachment runs the managed Jeden with ~/.stado/bin ahead of its PATH, and Jeden reads its own credentials through Stado.

Native API

GET /api/operator/workload/attach upgrades one authenticated request to a WebSocket that owns one interactive attachment. It answers to the same authorization as POST /api/operator/run: loopback callers are trusted by the Host guard, and every other caller presents an operator bearer.

  • The first client frame is the attachment request: {"kind", "target", "workspace", "resume", "confirmation"}, and confirmation must be RUN_MUTATION because an interactive attachment can change the target.
  • The server answers {"type":"attached","protocol":"stado.workload.v1"} once the workload process is running.
  • Server binary frames carry one channel byte and then bytes: 1 is the workload's standard output, 2 is its standard error. Client text and binary frames are that process's standard input, byte for byte; an empty binary frame closes it.
  • The final server frame is {"type":"exit","code","ok"}, or {"type":"error","message"} when the attachment was refused. The refusal is the CLI's own sentence.
  • Closing the socket ends the process group of the attached workload, so a disconnected operator leaves nothing running on the host.

Declaration

The declaration is stado-rs/data/workloads.json, compiled into Stado with include_str!. It currently declares:

  • jeden-session: product jeden; interactive; no Weles action gate; stream report carries target, workspace, stdio stream, and durable session ledger.
  • weles-capture: product weles-worker; gated by targets[].weles.actions entry generic_capture; plan schema wisent.weles-capture-plan.v1; receipt carries target, batch, accepted actions, and artifact prefixes. The whole plan is validated before target admission is contacted, so enqueue is all-or-nothing.
  • weles-browser-task: product weles-worker; gated by the plan's action in targets[].weles.actions; plan schema wisent.weles-browser-task-plan.v1; report carries target, action, run ID, outcome, profile, result, and the run process's own retained standard output and standard error.
  • weles-diagnostics: product weles-worker; no action gate; plan schema wisent.weles-diagnostics-plan.v1; report carries target, run ID, artifact inventory, or exact artifact content.
  • weles-image-inspect: product weles-worker; gated by generic_browser_task; plan schema wisent.weles-image-inspect-plan.v1; report carries target, run ID, source URL, and image diagnostics.
  • weles-activity: product weles-worker; no action gate; no plan; report carries target, worker release, API runtime, and recorded runs.
  • weles-recordings: product weles-worker; no action gate; plan schema wisent.weles-recordings-plan.v1; report carries target, recordings directory, registry generation, and updated LaunchAgents.
  • weles-api-runtime: product weles-worker; no action gate; plan schema wisent.weles-api-runtime-plan.v1; report carries target, revision, and managed-service restart.
  • weles-browser-runtime: product weles-worker; no action gate; plan schema wisent.weles-browser-runtime-plan.v1; report carries required/observed Playwright components, browser-engine readiness, and repairs.
  • gui-automation: product cua-driver; no action gate; plan schema wisent.gui-automation-plan.v1; operations are enable, disable, and grant-accessibility; report carries autologin, remote management, Accessibility, and runtime state.
  • mobile-runtime: product weles-worker; gated by the target's mobile_runtime registry declaration; plan schema wisent.mobile-runtime-plan.v1; report carries Appium, drivers, platform-tools, and repairs.

A Weles workload with an action gate is declared on a target only when weles.enabled is true and that target's weles.actions contains the resolved action. Other Weles reports require a weles declaration but do not invent an action gate. mobile-runtime requires targets[].mobile_runtime; gui-automation requires a local Darwin target; jeden-session requires a local target. With no target Stado chooses the first eligible declared host, except jeden-session, which retains its live-capacity scoring and durable-session host probing.

Exact declaration refusals

  • workload kind '<KIND>' is not declared; add it to stado-rs/data/workloads.json
  • <TARGET> declares no <KIND>; add it to stado-rs/data/workloads.json
  • the fleet declares no <KIND>; add it to stado-rs/data/workloads.json
  • <KIND> plan declares schema <OBSERVED>, not <EXPECTED>; fix the whole plan before any work is enqueued
  • <KIND> requires --plan FILE with schema <SCHEMA>; add the plan declared by stado-rs/data/workloads.json
  • <KIND> accepts no plan; remove --plan because stado-rs/data/workloads.json declares none
  • " is interactive and cannot produce JSON; use stado workload attach <KIND>"
  • " is interactive; use stado workload attach <KIND>"
  • " is not interactive; use stado workload run <KIND>"
  • <TARGET> declares no recordings directory; add it to the canonical registry
  • <TARGET> declares no mobile-runtime; add it to the canonical registry

Kind-specific plan refusals name the missing field and the plan that must be fixed. Host/runtime refusals retain the target, missing runtime component or credential, and the declaration or repair command the operator must change.

Replaced host verbs

The workload capability removes all 15 incident verbs and their dispatch/entry-point implementations:

  1. stado host jeden-connect
  2. stado host weles-capture
  3. stado host weles-capture-status
  4. stado host weles-browser-task
  5. stado host weles-browser-runtime
  6. stado host weles-run-diagnostics
  7. stado host weles-image-inspect
  8. stado host weles-activity
  9. stado host weles-api-runtime
  10. stado host weles-recordings-dir
  11. stado host mobile-runtime
  12. stado host gui-automation enable
  13. stado host gui-automation disable
  14. stado host gui-automation status
  15. stado host gui-automation grant-accessibility

Stado Desktop

The selected host inspector includes a Workloads section. It reads stado workload list --json, lists every declared kind with its product, stream/receipt mode, and report fields, and offers a read-only Read status action for non-interactive kinds. The last CLI report is shown verbatim in a bounded, selectable monospace view; the CLI's refusal sentence is shown when the selected target does not declare the kind or its report cannot be read.

Every interactive kind carries an Attach… button beside it. The sheet states the target, the selected Stado endpoint, the workspace, and an optional existing session ledger, then connects the stream through GET /api/operator/workload/attach. Output and diagnostics arrive live in two selectable views, Send input writes one line to the attached process's standard input, Finish input closes it, and the sheet reports the workload's own exit status or its refusal sentence. Changing the selected endpoint or closing the sheet disconnects the stream, which ends the attached process on the host.

Source: this website