Reference
Execution Receipt
The machine-readable record of what ota actually executed.
referenceautomation buildersintermediatestable2026-05-30
Recommended next
What a receipt is for
Read the receipt after a command runs if you need to audit what happened.
Use it when you want to compare runs, debug failures, or prove which backend and env values were used.
- the receipt is the machine-readable record of execution, not diagnosis
- the receipt tells you what ota chose, what ran, what succeeded, and what was blocked
- the receipt is what automation should read after execution, not before it
- the receipt makes the execution trail reviewable while failure output keeps
WhyandNextbefore the trailingRUN SUMMARYblock, and the compact summary now leads withStatusfor faster scanning - repo receipts can include a
Policy:section when policy-backed provisioning selected a source or backend-specific config - receipts can also include
host_service_cleanupwhen ota attempted host-managed service shutdown during interrupt cleanup - receipts can also include
execution_conflict.reasons[]when active execution ownership blocked the run path
Receipt fields
oktells you whether the command completed successfullypathtells you which repo or workspace file ota resolved for the runscopetells you whether the receipt came from a repo command or a workspace commandcontracttells you which contract governed the executionbackendtells you where the work ran, such as native, container, or remotelifecycletells you whether container execution was persistent or ephemeralstepsshows the ordered execution steps and their statussummarygives the roll-up counts for errors, warnings, info, and stepsnextgives the safest follow-up action when ota can suggest onenext_stepsgives that same follow-up lane as an ordered machine-readable array when ota can break it into explicit stepsenv_sourcesshows which env values won and where they came fromnative_prerequisitesshows the selected native prerequisite evidence for the executed native path, including additive check, activation, provisioning, and note detail when presentnative_prerequisites[*].activation.appliedtells you whether ota actually ran inside that activation for this command or only reported the declared activation shapepolicyshows which effective approved provisioning source ota resolved for the run and any backend-specific source confighost_service_cleanupshows first-class host-managed service cleanup evidence when ota owned the stop pathexecution_conflict.reasons[]shows typed active-execution conflict ownership such ashost_service,compose_project, orservice_task
How to read it
- Check
okfirst to see whether execution succeeded - Then check
scopeandcontractto confirm what ota ran against - Then check
backendandlifecycleto understand the execution model - Then read
stepsto see what actually ran and where the run stopped - Then read
summary,next, and optionalnext_stepsfor the roll-up and safest follow-up - Then inspect
env_sourcesif you need provenance for the values that won - Then inspect
native_prerequisiteswhen the selected path depended on host-native build tooling or task-scoped shell activation - Then inspect
policyif you need the approved provisioning source or source config - Then inspect
host_service_cleanupwhen the run was interrupted and ota owned host-managed service shutdown - Then inspect
execution_conflict.reasons[]when the run was blocked by another active execution in the same repo - If a step failed, the receipt should let you tell whether the failure was from setup, the task body, or the backend itself
Repo example
A repo receipt should be enough to tell you what happened in that repo run without opening the terminal output again.
Repo task runjson
{ ok: true, path: "/workspace/acme/app/ota.yaml", scope: "repo", contract: "/workspace/acme/app/ota.yaml", backend: "container", lifecycle: "ephemeral", steps: [ { "order": 1, "label": "setup", "status": "ok" }, { "order": 2, "label": "test", "status": "ok" } ], summary: { "error_count": 0, "warn_count": 0, "info_count": 0, "step_count": 2 }, next: "run `ota run test` again after your code changes", env_sources: [ { "name": "NODE_ENV", "source": "task.env", "value": "test" } ], policy: [ "tool node (package: nodejs) 22 via choco (source_config: feed=internal-choco)" ]}Workspace example
A workspace receipt should tell you which member blocked the rollout and which members finished cleanly.
Workspace runjson
{ ok: false, path: "/workspace/acme/ota.workspace.yaml", scope: "workspace", contract: "/workspace/acme/ota.workspace.yaml", backend: "native", lifecycle: "persistent", steps: [ { "order": 1, "label": "api", "status": "ok" }, { "order": 2, "label": "web", "status": "blocked" } ], summary: { "error_count": 1, "warn_count": 0, "info_count": 0, "step_count": 2 }, next: "run `ota workspace doctor` to inspect the blocked member"}How to use it
- use
ota execution plan --jsonwhen you need to inspect backend, lifecycle, image, or target selection without running setup or tasks - workflow-aware planning follows the selected workflow run path first and only falls back to setup when the workflow has no run phase
prepare.taskstays additive workflow context rather than the concrete execution task- use
ota execution plan --json --mode containeror--mode remotewhen you want the same backend-configuration gate thatota runandota upwould enforce before execution starts - use
ota workspace execution plan --jsonwhen you need the same read-only execution decision across selected workspace repos instead of one repo at a time, including workspace-pinned or repo-default workflow paths - use
ota workspace execution plan --json --repo <name>when the decision boundary is the selected repo set, not the full required/optional workspace roll-up - use
ota receipt --jsonwhen you want the same repo readiness scan as an archive-ready receipt artifact without provisioning, setup, or writes - repo receipts can now include additive
receipt.toolchains[]evidence for the selected provider-backed ecosystem path, alongside the existing readiness findings and execution identity - when ota actually runs provider fulfillment commands on the recorded execution path, the same toolchain entry can also include additive
fulfilledandcommands[]evidence - every successful repo receipt now includes a normalized
receipt.contract_snapshot_hash, and--archivealso materializes that normalized contract JSON under.ota/contractsso the receipt can point at the exact semantic contract truth it used - every successful repo receipt now also includes additive
receipt.assumption_set_hash, derived from the canonical extracted semantic path/value map instead of the raw snapshot blob - add
--archiveto persist the JSON receipt under.ota/receipts(keeps the newest 50) and readarchive_pathplusreceipt.contract_snapshot_reffrom the output - use
ota receipt --json --historywhen you need the archived repo receipt index without rerunning diagnosis - history reads valid archives newest first and surfaces malformed archived files as skipped entries instead of failing the whole read
- use
ota receipt --json --baseline latestwhen you need introduced, resolved, unchanged, and semantic contract-drift evidence against the newest valid archived receipt for the same contract - use
ota receipt --json --baseline <file>when the baseline should come from an explicit repo receipt JSON artifact instead of.ota/receipts - when that baseline carries
receipt.contract_snapshot_ref, readsummary.comparison.contract_snapshot_changed,contract_changes[], andlikely_related_changes[]to connect new blockers to contract drift - read
summary.comparison.correlationfirst for the top-level advisory posture;possibly_relatedis reserved for coarse same-family overlap, while unrelated drift staysno_clear_correlation - use
ota receipt --json --snapshot latestor--snapshot promotedwhen you need the archived normalized semantic contract JSON itself rather than just drift evidence --snapshot <file>accepts either an archived receipt JSON artifact or an archived.ota/contracts/...snapshot JSON file and reports the resolvedselection_kind,snapshot_hash,assumption_set_hash,summary.assumption_count, andsnapshot_path- receipt diff stays read-only and exits
0when the comparison succeeds, even if the current or baseline receipt is blocked - use
ota run <task> --dry-run --jsonfor task-level execution previews without starting the run path; the published schema isrun-preview.json, and blocked previews still stay on the same stdout preview envelope so automation can readsummary.primary_blockerdirectly - use
ota up --jsonfor readiness roll-ups and receipts - use
ota workspace run --json,ota workspace up --json,ota workspace refresh --json, andota workspace status --jsonfor workspace records; refresh stays read-only in preview mode and can also reflect stricter sync choices when those flags are used - use
ota workspace receipt --jsonwhen you want the same workspace scan as an archive-ready receipt artifact - read receipts after execution, not before it
- compare receipts across runs when you need to prove what changed
- use receipts when you need the execution trail, not the readiness diagnosis
What it is not
- not live logs
- not a diagnosis report
- not a contract inference result
- not a replacement for
doctor - not a replacement for
detect - not the place to discover new contract fields
Use cases
- confirm what ota actually executed after a successful
ota run - debug a failed
ota upwithout guessing which backend or lifecycle was used - inspect which steps were blocked before a task could finish
- compare a native run and a container-backed run
- feed a machine-readable execution trail into CI or agent workflows
- review workspace roll-ups after multi-repo bootstrap or execution