On this page
Desktop host operations
Storage root reconciliation and Apple code capture in Stado Desktop.
Reconcile storage roots
In Hosts → Reconcile storage roots…, choose Run, Resume, Status, Rollback, or Finalize for one transaction ID. The sheet initially selects Status; opening it or editing a field sends no request. The app retains the ID for the host, shows the equivalent CLI command, and requires a review of every mutating phase.
The sheet captures the selected dashboard address and host when it opens. Its confirmation and every retained result show that address. Changing the source elsewhere neither redirects this sheet nor cancels a request already sent; a result from another address is not shown as this source's receipt.
Status calls
GET /api/host/storage-root-reconcile?target=<host>&transaction=<id>&phase=status.
The other four phases use POST on the same path with their selected phase.
Neither method accepts a request body. Desktop calls the configured API, not a
local CLI subprocess or a second reconciliation implementation.
The server requires storage-reconcile-read for GET and
storage-reconcile-apply for POST in the client's registry_api.clients action
list. Policy and convergence permissions do not grant these actions. The
endpoint-bound credential comes from Settings → Registry API access.
A product result returns HTTP 200 with exit_code, refusal, and the complete
report, including when that report represents a refused operation.
Unauthorized clients receive 401; unavailable authorization or an operation
that failed before producing a report receives 503. The latter names
STORAGE_RECONCILIATION_FAILED and its cause. A malformed, duplicate, empty or
unknown query field, an invalid method/phase combination, or a body receives
400.
The sheet retains the actual HTTP status, product exit code, complete raw API response and every decoded report field. A decoding error or later refusal does not discard those bytes or an earlier result. Status reads have a 120-second deadline; mutations use the product's own bounded stages.
An accepted Run, Resume, Rollback, or Finalize response only confirms that the resident operation accepted the request. Select Status explicitly to read its durable result; the app never advances a transaction automatically. Resume reuses the same ID. Rollback is limited to the pre-data-commit path; after that boundary the recorded activation must be completed instead. After activation, ordinary lifecycle cleanup must finish before explicitly selecting Finalize, and Finalize's accepted response still needs a later Status receipt to prove completion. The checkpoint's actual serving root decides which conflicting bytes remain authoritative, as described in Storage root handoff and space reclaim.
Prepare Apple code capture
The Apple-only workflow below requires Stado 0.16.38 or later.
In Hosts > Apple code capture, Read Apple readiness sends the read-only command below through the configured native API and displays its fresh receipt. It needs no mutation confirmation and changes no host settings:
stado workload status gui-automation --target <target> --json
Its JSON receipt contains target, ssh_target, an ordered items array of
[name, value] pairs, and error. apple-challenge-ready: yes is observed
readiness: the signed dialog-structure helper passed its prompt-free --preflight in
the registry-bound user's exact Aqua session. A TCC row by itself is not ready.
Apple readiness is independent of gui-ready. The Apple helper can be ready
while CuaDriver reports accessibility: denied and gui-ready: no.
accessibility-record: granted describes the stored CuaDriver entry, whereas
accessibility reports the serving driver's prompt-free permission response.
Apple-only preparation does not change either CuaDriver state.
Prepare Apple code capture shows and submits exactly:
stado workload run gui-automation --target <target> --plan apple-only.json --json
The plan it submits is exactly:
{"schema":"wisent.gui-automation-plan.v1","operation":"grant-accessibility","apple_only":true}
apple_only installs or reuses only the signed Apple challenge helper and
reconciles only that helper's Accessibility grant. It leaves CuaDriver, its
Accessibility grants and runtime, autologin, and remote-management settings
unchanged. The command does not open a browser, request Apple authorization, or
sign in to Apple. A plan without apple_only retains the separate full
GUI-automation behavior.
The host it prepares carries no signing certificate of its own. Stado installs the pinned shared signer from the fleet's object namespace, verifies its digest, and signs the compiled helper with the Apple certificate, key and issuer it reads for that command only; see Native macOS code signatures.
Privileged preparation is noninteractive. Stado reads the host account's
registered password and supplies it to remote sudo -S over stdin; if no
password is available it uses noninteractive sudo -n and reports refusal
instead of displaying a password or consent prompt. After writing the grant,
Stado invokes the helper's prompt-free --preflight in the declared Aqua
session. Only that successful observation adds apple-challenge-ready: yes.
Credential reads are bounded independently of host execution. Stado allows 15 seconds to connect to Skarbiec and 120 seconds for the complete HTTP request. The existing owner-vault password fallback has a 90-second deadline and its child is terminated if that wait is cancelled. A failure before host execution names the account field, the broker error, and the owner-vault error; it is not an Accessibility refusal and does not prove that preparation reached the host.
Each readiness or preparation command acquires the registered host key and chooses a declared connection once, before its host operations begin. It keeps that key and connection only for that command, so every individual read does not repeat credential acquisition or probe an unavailable preferred path. The command releases its key when it finishes or is cancelled. A failed host operation is reported, not repeated on another connection.
After an interrupted preparation, the Probierz journey
apple-challenge-readiness reads the existing state through both the CLI and
native API without repeating preparation. It also checks the API's refusal of
an unconfirmed preparation request; it never submits a confirmed preparation.
Select it with PROBIERZ_JOURNEY=apple-challenge-readiness and
name the host with STADO_APPLE_PREPARATION_HOST. The separate
apple-challenge-preparation journey performs the CLI and native API changes.
Both journeys retain the source revision, compiled executables, compilation
result, and per-command JSON receipts with stdout and stderr files. A missing
final command result or an incomplete run is not evidence that preparation
succeeded or that it is safe to repeat it.
Desktop's configured FleetControlStore sends the displayed argv array and
mutation confirmation to the native POST /api/operator/run API at the
configured Stado endpoint. Desktop neither assembles a shell command nor spawns
the CLI. The loopback endpoint retains local trust; a remote endpoint requires
operator authorization. The server executes the allowlisted argv and returns
stdout, stderr, and exit status.
Desktop decodes the command's JSON stdout before judging that status, so the
receipt keeps target, ssh_target, every completed items entry, and error
even after a later step fails. The failure receipt and refusal remain visible;
a refused database write or failed helper preflight is never presented as
ready.
Preparation does not capture a code or issue a certificate. Certificate issuance is a separate, explicitly authorized trajectory that may open Apple sign-in or system-consent UI and require 2FA; preparation neither starts nor proves that trajectory. See the Weles Apple account workflow.
Source: this website