Reference
JSON Output
Stable machine-readable payloads for commands, workspace flows, and CI adapters.
Recommended next
When to use JSON
Use JSON when automation needs stable contract data instead of reading terminal prose.
The JSON surface is the integration contract for CI, editors, AI agents, and scripts.
- CI, editors, and agents should read JSON rather than scrape terminal text
- human text output can change without breaking machine consumers
- the same payload shapes are reused across repo and workspace flows
- JSON mode is the right choice when you need stable parsing, not terminal polish
Common payload fields
oktells you whether ota completed the command successfullypathtells you which contract or workspace file ota resolvedsemver,version,source_build,commit, anddirtyidentify the current ota binary when you callota --version --jsonschema_versionis the coarse contract-generation marker;contract_capabilitiesis the additive feature-support catalog for compatibility-aware automationcontract_capabilitiesnow calls out high-signal task features such astasks.effects.writes,tasks.effects.adapter_state,tasks.effects.network,tasks.effects.external_state, first-class bootstrap actions liketasks.action.ensure_git_checkout,tasks.action.ensure_git_template,tasks.action.ensure_container_network, andtasks.action.reset_compose_service_volume, bootstrap orchestration (tasks.action.ensure_bundle), and execution guards (tasks.when.checks) when the binary supports them- minimum-version compatibility failures should point back to
ota --version --jsonafter install or rebuild so operators can confirm the new binary identity and capability surface modetells you which command path or execution context ota used, such as preview, write, merge, rewrite, native, or containerwrittentells you whether ota actually wrote a file or applied changesoperation,subject,assumptions,changes, andvalidationare the stable reviewed-mutation fields forota assistpayloadssummarygives you the roll-up counts that hosted gates care about firstnext,reason, anddetailscarry structured recovery guidance when ota can classify a failureengine,resource_kind, andresource_nameidentify the failing cleanup or backend resource when that context exists- generic repo-state failures still fall back to stable
summarypluserror findingscarries readiness, policy, and validation issues in a stable list; findings may also include human-readableprovenanceplus stableprovenance_keywhen ota can trace the diagnosis back to repo contract, org policy, or repo signals- native runtime and tool probe findings can add
evidence.commandandevidence.pathwhen ota resolved an executable and attempted a concrete version probe envcarries read-only environment inspection output fromota env --jsonsourcescarries declared env-source status such as loaded, missing, parse-failed, or invalid structured source filesfinding_groupsadds grouped remediation summaries without changingfindings; each summary carries a stable semanticaction_keyfor the grouped action classreceiptrecords what ota actually executed and what context it usedreceipt.host_service_cleanuprecords first-class host-managed service cleanup attempts when ota owned shutdown, including the service, action, status, trigger, and any captured detailconfigis the generated or detected contract content when ota is previewing or writingpackappears onota init --jsonwhen an explicit starter pack seeded the contract instead of detector-led initpack_optionscarries selected pack overrides such as Node package manager or Python test runnerpack_advisoryappears when strong detected repo signals disagree with the selected pack without auto-switching itmode: "catalog"pluspacksappears onota init --packs --jsonwhen ota lists the built-in starter-pack catalog instead of previewing one contractcomparisonis the detected-versus-existing diff for init and detect flows; detect comparison entries now include stable machine ownership plusowner_kindso automation can tell detected adds, hand-authored fields, and ota-managed fields apart without scraping proseinferredexplains what ota learned from repo signals and how confident it wasinferred[].typeandinferred[].signalclassify the detected signal without forcing automation to parse prose- task-shaped inference entries can also add
agent_safeandagent_signalwhen ota can justify agent-safety metadata provenanceis the per-field source map when ota is generating explainable contract content, such asota init --jsonstarter output orota workspace init --jsonscaffold outputerrorsorerrorappears when validation or loading fails before the normal payload can be produced
Canonical source
- the canonical machine-readable contract lives in the ota repo spec and the published JSON schemas, not in this summary page alone
- treat
docs/spec/json-output-reference.mdin the ota repo and the published schema artifacts as source of truth when this site page is lagging - use this page as the public guide, but use the repo spec and schemas when automation needs exact field truth
What to use
versionfor machine-readable ota build identity and contract capability supportagentsfor repo-localAGENTS.mdexport preview or sync reports, including approved ota bootstrap guidance when the contract declares itservicesfor declared managed-service inventory, including manager shape, readiness declaration, endpoint projections, and dependenciestasksfor repo task inventory and AI-agent-safe task hints- for the newer contract-owned env/config surfaces, keep
env.profiles,render.dotenv,render.dotenv.template,render.files,tasks.<name>.env_files,ensure_env_file,checks[].kind: env, andservices.<name>.manager.env_file/services.<name>.manager.profileson the public docs path instead of teaching shell glue as the default validateandcheckfor contract gatingassist declare-readiness,assist declare-service,assist bind-task,assist wire-setup,assist declare-env,assist add-task, andassist normalizefor deterministic reviewed mutation output, including machine-readable assumptions, exact field changes, and follow-up validation guidanceinitfor starter-contract preview or write output, including per-field provenance, starter defaults, pack metadata, pack options, and pack advisoriesota init --packs --jsonfor pack discovery across Node, Python, Ruby, Go, Rust, .NET, PHP Composer, and Java starter packsdetectfor contract comparison, merge, and write decisions; ota records detect-managed fields undermetadata.ota.detect.field_ownership, records detect-write admission undermetadata.ota.detect.field_admission, records additive detector source governance undermetadata.ota.detect.field_source_class, and treats existing fields without that metadata as manual by defaultdoctorandworkspace doctorfor readiness diagnosis and blockers; workspace doctor/check payloads can also carry workspace-levelsummary.primary_blocker, repo-ownedprimary_blocker, and additive blockercodewhen the blocker came from explicit stable finding identity, and policy-backed provisioning entries can addnormalized_requirement,resolved_version, andpolicy_matchwhen ota made a semver-aware authorization decisionproof runtimewhen CI, an agent, or a reviewer needs end-to-end evidence that one selected workflow really started and reached readiness on a clean boundary; it captures the canonical topology, doctor, up-log, and proof metadata artifacts for that runtime path, with cleanup scoped to the selected workflow/runtime boundarypolicy initfor conservative org-policy scaffolding preview or write output, including explicit starter presetsreceiptfor a read-only repo receipt artifact from the current readiness scanworkspace tasksandworkspace listfor workspace inventory and availabilityup,workspace up, andworkspace refreshfor preparation, readiness roll-up, and receiptsworkspace difffor read-only drift inspection before refreshworkspace statusfor the operational readiness-and-drift scan- workspace lifecycle payloads may add
next,next_steps,drift_kind, andtarget_sourcewhen ota can name the safer follow-up lane directly workspace receiptfor the same scan packaged as an archive-ready receipt artifactrunandworkspace runfor execution receipts and repo-owned execution follow-up lanesdiffandexplainfor change impact and remediation planningworkspace initandworkspace detectfor workspace scaffolding and comparison, including per-field provenance for workspace-derived repo entries, preserved merge fields, and scaffold defaults
Canonical schema URLs
These are the live schema URLs behind the public machine-readable reference, including the published repo contract schema.
The ota release gate publishes them as generated artifacts and now checks them against both authored examples and Rust-owned authoring projections before release.
Click a card to open the schema in a new tab. Use the command example when you want to inspect the payload locally.
Workspace schema URLs
Use these when the workspace contract coordinates multiple repos and you need either the workspace contract schema itself or workspace-level machine output.
The published workspace schema is release-gated alongside the repo contract schema and is checked against both authored examples and Rust-owned authoring projections.
Change and remediation URLs
Use these when you are comparing contracts or turning findings into step-by-step fixes.
Read the payload in the right order
- Check
okfirst to see whether the command completed cleanly - Then read
pathto confirm which contract or workspace ota resolved - Then read
summaryorfindingsdepending on whether you are gating, diagnosing, or annotating - Then read
receiptwhen you need to know what ota actually executed - Then read
comparisonorinferredwhen you are reviewing writes or previewing inference
Repo and workspace surfaces
ota validate --jsonfor contract gatingota workflows --jsonfor workflow inventory and selected-path discoveryota tasks --jsonfor task inventory and safe-agent hintsota tasks --jsonandota workspace tasks --jsonalso carry additive structuredpreparesummaries, including nestedsteps[]when a task usesprepare.kind: sequenceinstead of shell setupota tasks --jsonandota workflows --jsonnow carry structured launch additively when the selected task path useslaunchinstead of shellrunorscriptota tasks --jsonandota workspace tasks --jsonalso carry additive taskeffectsso automation can see declared repo writes, network dependence, and out-of-repo state mutation without scraping notesota doctor --jsonfor readiness diagnosis and blockersota doctor --json --fix --dry-runwhen automation needs the same readiness diagnosis plus the planned contract-aware safe fix set; today that fix surface is.gitignoreprotection for.ota/state/on repos with a validota.yamlota execution plan --jsonfor a read-only execution decision with declared contract intent plus resolved backend, lifecycle, image, and target strategy; when the repo declares workflows, planning follows the canonical workflow run path first instead of guessing from repo-wide setup fallbackota execution plan --jsonfails when the selected container or remote path is not actually runnable from the current contract, instead of inventing a resolved planota policy init --jsonfor conservative org-policy scaffold preview or write output, including the selected starter preset when one is usedota receipt --jsonfor a read-only repo receipt artifact from the current readiness scanota receipt --jsonnow also emits a normalizedreceipt.contract_snapshot_hashso automation can tie a receipt back to the exact semantic contract truth that produced itota receipt --jsonalso emits additivereceipt.assumption_set_hashso automation can fingerprint the canonical extracted semantic assumption map separately from whole-snapshot identityota receipt --json,ota proof runtime --json,ota up --json,ota up --dry-run --json, and the workspace receipt/status/up/run/refresh JSON lanes now publish additiveartifact_routing[]so automation can follow the same typed next-artifact path without scraping human follow-up textota execution topology --jsonfor declared launch sources, surfaces, normalized listeners, and attached runtime publication intent without starting anythingota proof runtime --jsonwhen automation needs machine-readable proof that a selected workflow actually booted and reached readiness, plus the artifact paths for the captured topology, doctor, and runtime logs; proof cleanup is scoped to the selected runtime path and non-blocking informational findings are preserved without forcingok: falseby themselves; when the selected run task is a successful launcher such asdocker compose up -d, proof keeps probing until the declared readiness budget expires instead of collapsing the launcher exit into an immediate failure; timeout lanes normalize tophase: timeout/failure_class: readiness_timeout, signal-terminated lanes normalize tophase: interrupted/failure_class: interrupted, cleanup-classified proof failures now publish additive structuredcleanup_failureevidence, high-confidence runtime target mismatches can now publishfailure_class: readiness_target_mismatchwith structured declared/observed target evidence, high-confidence dns/service-name resolution failures can now publishfailure_class: dns_service_name_resolution_failure, high-confidence auth/credential failures can now publishfailure_class: auth_credential_failure, high-confidence runtime config drift can normalize tofailure_class: config_drift, bind/address-in-use collisions can normalize tofailure_class: bind_conflict, missing-config failures can now publish structuredlikely_cause_evidence.kind: missing_env, install/toolchain breaks can now publish structuredlikely_cause_evidence.kind: install_or_toolchain_failure, andlikely_cause_evidencepublishes the structured root-cause signal behind any advisorylikely_causetext.ota receipt --json --baseline latestfor receipt-to-receipt comparison against the newest valid archived baseline for the same contractota receipt --json --baseline <file>for comparison against an explicit repo receipt JSON artifact- when the selected baseline receipt carries
receipt.contract_snapshot_ref, receipt diff JSON also adds semanticcontract_changes[], correlatedlikely_related_changes[], andsummary.comparison.contract_snapshot_changedso automation can connect new blockers to contract drift instead of only seeing finding deltas - receipt diff JSON now also carries
summary.comparison.correlationso automation can distinguishlikely_related, coarse same-familypossibly_related, and unrelated-driftno_clear_correlationwithout reverse-engineering correlation posture from array emptiness ota receipt --json --snapshot latestwhen automation needs the archived normalized contract truth directly instead of only seeing it indirectly through diff or receipt correlationota receipt --json --snapshot <file>accepts either an archived repo receipt JSON artifact or an archived.ota/contracts/...snapshot JSON artifact and reports which archive-backed lane was selected- snapshot JSON now also publishes additive
assumption_set_hashplussummary.assumption_count, so automation can read semantic snapshot identity directly instead of deriving it from the raw normalized JSON payload ota receipt --jsonemits the sharedValidateFailureJSON on stdout when contract load or validation fails before the receipt can be builtota up --dry-run --jsonfor read-only preparation previewsota up --jsonfor preparation and readiness receipts on repo targets; monorepo aggregate output keeps grouped member results instead of inventing a top-level aggregate receiptota clean --jsonfor repo, member, and workspace cleanup counters on success, for classified cleanup failures that name either the engine/resource lane or the active-execution barrier lane, and for generic repo-state failures that still stay machine-readable throughsummarypluserrorota clean --stale --jsonfor contract-free stale container cleanup results; classified stale cleanup failures use the sameclean.jsonschema and expose stale engine-query failures without scraping textota diff --jsonfor semantic contract comparisonota explain --jsonfor remediation planningota workspace doctor --jsonfor workspace readiness and roll-ups, includingsummary.verdict,summary.agent_verdict, and additivesummary.primary_blockerwhen ota can name the current workspace headline blockerota workspace check --jsonfor checks-only workspace readiness; add--progress-jsonwhen you also need live NDJSON workspace progress on stderr while the final JSON roll-up stays on stdout, including additivephaseandstage_familyon each progress eventota workspace execution plan --jsonfor per-repo execution resolution across a workspace without running setup or tasks; when workflow-aware planning selects a canonical repo path, the output now carries both the effective workflow and taskota workspace execution plan --jsonfails when any selected repo cannot actually produce a runnable execution plan, even if that repo is optional in the full workspace contractota workspace up --jsonfor workspace preparation and receipts; add--progress-jsonwhen you also need live NDJSON workspace progress on stderr, including additivephaseandstage_familyon each eventota workspace refresh --jsonfor workspace re-sync and receipt output; add--progress-jsonwhen you also need live NDJSON workspace progress on stderr, including additivephaseandstage_familyon each eventota workspace diff --jsonfor read-only workspace drift inspection, including additive lifecyclenext/next_stepsand per-repodrift_kind/target_sourcewhen ota can name the safer follow-up lane directly; add--progress-jsonwhen you also need live NDJSON workspace progress on stderr, with additivephase/stage_family, the repo diff verdict instatus, and machinedrift_kindintailota workspace status --jsonfor the operational readiness-and-drift roll-up, including additive lifecyclenext/next_stepsand per-repodrift_kind/target_sourcewhen ota can name the safer follow-up lane directly; add--progress-jsonwhen you also need live NDJSON workspace progress on stderr, with additivephase/stage_familyand repo drift state carried intailota workspace receipt --jsonfor the same scan as an archive-ready receipt artifact; add--progress-jsonwhen you also need live NDJSON workspace progress on stderr, with additivephase/stage_familyand repo drift state carried intailbecause receipt reuses the same scan as workspace statusota workspace run --jsonfor coordinated multi-repo execution; add--progress-jsonwhen you also need live NDJSON workspace progress on stderr, including additivephase/stage_familyplustaskand resolvedrepo_taskon both dispatch and terminal repo-task events when workspace bindings rewrite the local task name
Example payloads
{ ok: true, path: "/workspace/acme/ota.yaml", tasks: [ { name: "setup", kind: "sequence", description: "Prepare mixed repo dependencies", prepare: { kind: "sequence", steps: [ { kind: "dependency_hydration", medium: "package_dependencies", source_kind: "node_package_manager", cwd: ".", manager: "pnpm", mode: "install", frozen_lockfile: true }, { kind: "dependency_hydration", medium: "package_dependencies", source_kind: "uv", cwd: "api", manager: "uv", mode: "sync" } ] }, effects: { writes: ["node_modules", ".venv"], network: true, network_kind: "dependency_hydration" }, depends_on: [], requires_services: [], safe_for_agent: false } ]}{ ok: false, path: "/workspace/acme/ota.yaml", mode: "container", summary: { error_count: 1, warn_count: 1, info_count: 0 }, findings: [ { code: "OTA_TASKS_MISSING", category: "contract", owner: "repo_contract", severity: "error", summary: "No tasks defined in contract", why: "The repo is not runnable until it declares at least one task.", next: "Add a setup or test task to ota.yaml.", evidence: { path: "/workspace/acme/ota.yaml" } } ]}{ ok: false, path: "./ota.yaml", summary: "Container engine unavailable", error: "cleanup `list` failed for dependency-isolation volume state `dev.ota.repo=repo-1` using podman", why: "`ota clean` needs Podman to remove dependency-isolation repo state for `dev.ota.repo=repo-1`, but Podman is not reachable.", next: [ "start Podman and rerun `ota clean`", "run `podman system connection list`", "if needed, run `podman machine init` and `podman machine start`" ], reason: "engine_unavailable", engine: "podman", action: "list", resource_kind: "dependency_isolation_volume", resource_name: "dev.ota.repo=repo-1", details: "unable to connect to Podman socket: dial tcp 127.0.0.1:57990: connect: connection refused"}{ ok: true, mode: "receipt", path: "/workspace/acme/ota.workspace.yaml", summary: { error_count: 0, warn_count: 0, info_count: 0, step_count: 2, repo_count: 2, ready_count: 2, not_ready_count: 0 }, receipt: { ok: true, path: "/workspace/acme/ota.workspace.yaml", scope: "workspace", contract: "/workspace/acme/ota.workspace.yaml", workspace: "acme-dev" }, repos: [ { name: "api", ok: true, status: "READY", readiness_status: "READY", drift_status: "MATCH" }, { name: "web", ok: true, status: "READY", readiness_status: "READY", drift_status: "MATCH" } ]}What JSON is not
- not live logs
- not a replacement for the human status line
- not a text parsing target
- not the only output mode ota provides
Use cases
- a CI job runs
ota doctor --json, fails on errors, and posts warnings as annotations - an editor shows the primary finding without parsing text output
- an agent reads the receipt to see what ota actually did
- a workspace gate surfaces per-repo readiness instead of flattening everything into one string
- a release pipeline compares contract changes through
ota diff --jsonbefore writing updates - a repo author previews a new
AGENTS.mdwithota agents --jsonbefore writing it