On this page

Release publication and the active executable

Release publication authority

The publisher command reads the bearer named by release_api.publishers through its selected credential store and configured WC_SKARBIEC_CONSUMER grant. When owner credentials are available, Stado adds only that item's token read to the same grant before reading it; an already authorized read does not depend on that repair being available.

The release server uses release_api.skarbiec.url and its separate stado-release-api-verifier grant to verify the publisher bearer. Release signing uses the same declared authority with stado-release-coordinator, which reads only the signing key. The publisher command never authenticates its credential read as the server verifier, and STADO_API_TOKEN remains a generic object API credential, never a product release bearer.

The public release route accepts exactly one uri query field. Exact GET /api/release/object?uri=stado://releases/... reads and byte ranges are public so a damaged credential plane cannot make signed recovery artifacts unreachable; duplicate uri, versioned, and unknown query fields are rejected before storage access. Release writes and exact release listings remain authenticated by the product publisher contract above and do not require the generic object credential first.

Before any platform artifact is written, every publisher create-only claims stado://releases/<product>/<version>/source-revision.json. That version record is the single arbitration point across changing platform sets; platform claim records are written only after it agrees. Older platform-only coordinates are backfilled only when every existing platform claim names the same full source commit. Release workers set both WISENT_SOURCE_COMMIT and STADO_SOURCE_REVISION from that verified request, and the Stado build rejects missing-shape or mismatched overrides.

The object API recovery helper treats a release target's legacy launchd plist and label as an optional pair. A healthy handoff or a host with no exact orphan does not need that pair. Recovery validates and bootstraps it only when stopping an exact dead release-proxy orphan; without a declared pair, that branch refuses before sending TERM because it has no known service to restore. Only the pair on the release target authorizes that restore; a similarly named entry under targets[].services is never inferred as a fallback.

Wait for the stable release endpoint

A blue-green candidate is not active merely because its own port answers. Stado also checks the stable proxy's process, immutable release identity, generation, upstream port, and declared readiness endpoint before routing is reported as complete. Activation, reconciliation, and rollback allow that endpoint to become ready within the product's strategy.readiness_timeout_seconds; they do not assume a newly spawned proxy has bound its socket after a fixed delay.

An exited proxy fails immediately. When the deadline expires, the refusal names the stable URL, allowed seconds, and last connection error or HTTP status. Identity and generation mismatches still fail without waiting.

Read the proxy's own output separately from the candidate's output:

stado release logs brama --target <host> --version proxy --stream both --json
stado release logs brama --target <host> --version <version> --stream both --json
stado release quarantine list brama --target <host> --json

A product whose policy strategy is replace runs as a managed unit restarted in place onto each release, never as a separate candidate process. The unit is the one the policy's logical service runs as on the target — the route's managed_service, or the unit its placement profile declares there — the same rule the rollout itself restarts by. It writes to that unit's own StandardOutPath and StandardErrorPath, so release logs reads those, the same read stado service logs makes, and prints each as --- <host> <unit> stdout (<file>) and stderr (<file>); --json names both service and unit. --lines N tails each file; without it each is read whole; --head is refused by name, because a unit log has no head worth reading.

stado release logs weles-worker --target <host> --lines 80 --stream err

A replace that fails its readiness gate is rolled back, and the failure the run records carries what the unit wrote while the gate waited: the gate reads the unit's log whole before the restart and again after the failure, and the lines the second read carries beyond the first are the window's output — readiness timed out after 90s: http://127.0.0.1:8788/healthz never answered; rolled back to <previous> and restored the prior unit; <unit> wrote to <file> in the readiness window: followed by those lines, or <unit> wrote nothing to <file> in the readiness window. No line count is chosen: the window is the difference of the two reads, and a log rotated between them is reported whole as the second read found it. A log that cannot be read does not stop the release; the failure says which read failed and why. stado release status prints the failure whole, so the cause is read there.

After repairing the recorded cause, release quarantine clear retires only the exact digest named by --digest and records the required --reason. It does not rebuild or replace the signed release.

Resolve the executable that is actually active

stado release active binary skarbiec --json

release active binary resolves the local registry target unless --target names that same host. It reads observed rollout state, not policy.desired: a newer quarantined candidate cannot displace the healthy predecessor that still serves the stable bind. The command succeeds only when one live release process matches the recorded PID, version, candidate port, and immutable release directory; the exact Stado proxy executable and argument vector target that port at the recorded generation; and the installed marker, qualification, artifact digest, manifest digest, platform, directory, and executable all agree. The executable must be a regular, non-symlink, executable file.

The policy-derived path uses the same canonical helper as the release agent: {home} expands to the target's declared home, and a relative install root is resolved beneath that home before the immutable release directory is appended.

JSON output includes state, product, target, version, platform, artifact_sha256, manifest_sha256, and the absolute path; human output is the path alone for direct command substitution. If release control declares the product and target but no release is observably active, the command fails instead of falling back to an old file. Stado's authenticator-seed freshness reader and Weles use this same contract for SKARBIEC_BIN, so they cannot select desired, quarantined, or merely present Skarbiec bytes independently.

Source: this website