Runtime bundles

Persistent unYOLO services are deployed as one signed runtime bundle. The unyolo host command stages each separately released broker and ingress binary under an immutable release directory, verifies its digest and its exact Agent and Operator contract identities, then activates the complete set together.

The reason for the ceremony is narrow. A host running hf-broker, gh-broker, sudo-broker, and unyolo-telegram has four processes that speak generated contracts to each other. Upgrading them one at a time creates a window where two of them disagree about the wire format, and the Telegram ingress in particular can consume an update it cannot correctly route.

Commands

unyolo system plan    --manifest manifest.json --signature manifest.sig --public-key release.pub
unyolo system install --manifest manifest.json --signature manifest.sig --public-key release.pub
unyolo system upgrade --manifest manifest.json --signature manifest.sig --public-key release.pub
unyolo system status
unyolo system doctor
unyolo system rollback

Release layout

Linux uses /opt/unyolo/releases/<bundle-id> and macOS uses /Library/Application Support/unyolo/releases/<bundle-id>. A current symlink points at the active release and is switched atomically.

Native service definitions use exact component paths below that root-controlled pointer, and production setup rejects standalone mutable executables. Each started process is then verified against the selected immutable release, so a unit file that quietly points somewhere else does not survive activation.

Activation order

Providers stop after consumers and start before consumers. In practice that means the Telegram ingress stops first and starts last, because it is the process that calls into the brokers.

Exact readiness is checked before the activation record commits. Any failure restores the previous release pointer, the state replacement, the service order, and readiness before Telegram resumes.

Before stopping a service, the host writes a private activation transaction. An interrupted install, upgrade, or rollback is reconciled under the host lock before another lifecycle command can run: a committed and healthy candidate is kept, and an uncommitted transaction restores its recorded previous release.

That reconciliation is what makes a power loss mid-upgrade a recoverable event rather than a manual repair.

The manifest

The closed unyolo.io/runtime-bundle/v1 manifest is defined by protocol/runtime-bundle.schema.json. A production manifest requires a detached Ed25519 signature.

--development permits unsigned local fixtures, but development build identities cannot enter a signed production bundle. Development activation also requires explicit isolated root and state directories and cannot write the production activation paths, so the two modes cannot be confused at runtime.

The public key supplied for the first production install is pinned under the private host state directory. Later plans and upgrades use that pinned key and reject an attempted key replacement.

Each required provider component names its local Operator endpoint and the absolute path of its Operator token file. The token itself is never stored in the manifest. Activation and doctor use that local credential to verify the running provider’s exact contract and build identity without exposing it.

State format replacement

unYOLO does not run migrations, and it has no runtime compatibility readers. A state-format change is an explicit replacement: the old service stops, its state directory is archived beside the original, and the candidate starts with fresh current-format state.

Rollback restores the archived directory together with the old executable. Mixed-format state is not a supported condition.

This trade is deliberate. Compatibility readers accumulate, they are hard to test against every historical shape, and they turn a rollback into a question of whether the new code wrote something the old code will misread. Replacing the directory makes rollback a file move.

Host health

unyolo system doctor compares the activation record, the immutable artifact digests, the native service state, the process executable paths, and the active bundle.

A host is unhealthy when an artifact digest changes, a required service is inactive, a process executable differs from the immutable active release, a Linux executable is marked (deleted), or a rollback did not complete.

The (deleted) check catches a specific and easy-to-miss failure. Replacing a binary on disk while its old process keeps running leaves a service that reports as active while executing code nobody can inspect. Linux marks that executable path as deleted, and the host doctor treats it as unhealthy rather than as a running service.

unyolo system status --json
unyolo system doctor --json

Both produce a closed report containing bundle IDs, release build IDs, artifact digest results, native service names, PIDs, executable paths, active state, and recovery-required state. Neither contains credentials, Telegram destinations, decision authority, reasons, or provider payloads.

Contract identity

Exact Agent and Operator digests are exposed by discovery and health responses, so clients can report contract drift without logging response bodies.

A version label alone is never treated as compatibility evidence. The Telegram ingress compares each route’s exact digest before every poll batch, and a mismatch makes it exit without consuming another update, which leaves the service manager or a bundle rollback to repair the host.

Esc

Type to search across every documentation page.