Skip to content

Command Palette

Search for a command to run...

Reference

Machine contract (--json)

The single, versioned JSON envelope every core command emits on stdout with --json. Additive-only: breaking changes bump schema_version.

Every core command accepts --json and emits a single, versioned JSON envelope on stdout. This is the contract coding agents and scripts consume; it is additive-only, so breaking changes bump schema_version. The matrix (matrix list/show/status) and webhook (webhook status/history) JSON outputs predate this contract and keep their own schemas for backward compatibility.

Envelope

envelopejson
{  "schema_version": "1",  "operation_id": "op_1a2b3c4d5e6f7081",  "status": "succeeded",  "result": {},  "error": null}
FieldPresence
schema_versionAlways
operation_idMutation commands only - the durable operation identifier; read-only commands never fabricate one
status"succeeded" on success, "failed" on failure
resultSuccess only; shape documented per command
errorFailure only

stdout / stderr discipline

stdout carries the envelope and nothing else - no banners, progress, colors, warnings, or debug output. stderr carries progress and diagnostics (what a non-JSON run prints to stdout). Exit codes are unchanged by --json. The MCP adapter reuses this exact envelope: each tool returns one envelope as its result content, keeping the process’s real stdout reserved for the MCP protocol.

Commands

Commandoperation_idresult
buildop_… (matrix: the mx_… run ID){app, app_id, version, path} / matrix run summary
rebuildop_… (correlated with the dep-… deployment ID){app, app_id, version, port, strategy}
rollbackop_…{app, from_version, to_version, strategy, port, verification}
status / list / doctor-app view / fleet view / {checks[], summary} (doctor exits 3 on failing checks)
operation status / listthe queried idoperation view / {operations[], count}
inspect / context-targeted inspection / one bounded composite snapshot
plan create- (the plan is the artifact)immutable execution plan
plan apply <plan-id>the produced op_…execution result + correlation
authz status / check / approve / revoke-posture / decision / approval artifact / {plan_id, revoked}
session create / show / list / checkpoint / …- (the session is the artifact)the session record (+ resolved on show)

Plans

Plans are first-class, immutable, content-addressed execution artifacts. The invariant: the thing that was planned is the thing that gets executed, or execution fails closed. A plan_id (pln_ + 16 hex) names the artifact; a plan_hash (sha256: over a canonical preimage of the execution-relevant fields) names what it will do. Every load recomputes and verifies the hash - a mismatch fails closed with PLAN_HASH_MISMATCH.

Only created → applied | failed are stored; staleness is never stored - it is computed from current state at show/apply time against typed preconditions (app exists, current version, version exists, deploy mode, config fingerprint, source commit, toolchain available). Plan files are create-only; there is no edit - a different plan means a new plan. Plans never contain secrets: the schema has no environment-value fields, and the only free-text field (a rollback reason) is validated and redacted.

source_commit is a precondition only when the source is a git work tree - the config fingerprint covers configuration, not source content. A plan built from a non-git source has no source-content precondition, so its applicability carries source_drift_unprotected: true (and plan show prints a “not drift-protected” line): the source tree may change between create and apply without the plan going stale. Git-backed plans never carry it.

Applying a plan is idempotent and fail-safe. Concurrent applies serialize - a cross-process begin/complete file lock rejects a duplicate started while the first is in flight with UNAVAILABLE. After a failure the plan is marked failed and re-applying it is refused with PLAN_STALE (“plan already ran; create a new plan to retry”) - a gate driven by the plan’s durable status, so a failed plan can never silently re-execute later, independent of ledger eviction. The first apply still surfaces the real execution error (BUILD_FAILED, DEPLOY_FAILED, …).

Execution authorization

Plan application passes one gate between a validated plan and the engine: load + hash-verify → preconditions / capabilities → re-resolve + verify equivalence → AUTHORIZE → request-key idempotency → execute. Authorization is the last gate before mutation (so a refusal is provably zero-mutation) and runs before the request-key ledger (so a refusal consumes no idempotency key - the same plan applies once approved). It binds to plan_id and plan_hash, and selected by a host-owned authz/policy.json: absent means legacy_local, present and enforced means plan-bound execution only. Errors use exit 11 (AUTHZ_DENIED, AUTHZ_UNAVAILABLE, AUTHZ_INVALID, APPROVAL_REQUIRED, APPROVAL_STALE, APPROVAL_INVALID). The full model is in Execution authorization.

Agent sessions

A session (ses_ + 16 hex) is a durable tracking record that groups one unit of agent work and references the plans, operations, and deployments it touched. Session commands are not operations - their success envelope is read-shaped and carries no operation_id, and the session’s own lifecycle status lives in result.status (active → completed | failed | cancelled). Session-specific codes: SESSION_INVALID, SESSION_CORRUPT, SESSION_INVALID_TRANSITION (exit 3), and SESSION_CONFLICT (exit 1, retryable). See Agent execution sessions.

Errors

errorjson
{  "schema_version": "1",  "operation_id": "op_1a2b3c4d5e6f7081",  "status": "failed",  "error": {    "code": "DEPLOY_FAILED",    "message": "…redacted…",    "exit_code": 21,    "retryable": true,    "operation_id": "op_1a2b3c4d5e6f7081"  }}

code is the stable structured category; message is redacted; exit_code is the exit code the process returns; retryable is omitted when the failure cannot be classified. Usage errors (unknown flags, missing args) occur before a command runs and are rendered human-readable on stderr with exit 2 - they never produce JSON.

Request-key idempotency

rebuild and rollback accept --request-key <key>. First use records the key durably with a fingerprint of the operation-defining inputs and executes; the same key with the same inputs replays the stored terminal envelope byte-for-byte without executing again (across process restarts); the same key with different inputs is rejected with IDEMPOTENCY_CONFLICT (exit 1). An interrupted key is closed as indeterminate - the mutation is never re-executed under an unknown outcome. The ledger is fail-closed: a corrupt ledger answers UNAVAILABLE for every keyed operation rather than executing without idempotency. build deliberately does not accept a request key - a build is naturally repeatable and version-minting.