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