Reference

Execution Receipt

The machine-readable record of what ota actually executed.

referenceautomation buildersintermediatestable2026-05-30

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 Why and Next before the trailing RUN SUMMARY block, and the compact summary now leads with Status for 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_cleanup when 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

  • ok tells you whether the command completed successfully
  • path tells you which repo or workspace file ota resolved for the run
  • scope tells you whether the receipt came from a repo command or a workspace command
  • contract tells you which contract governed the execution
  • backend tells you where the work ran, such as native, container, or remote
  • lifecycle tells you whether container execution was persistent or ephemeral
  • steps shows the ordered execution steps and their status
  • summary gives the roll-up counts for errors, warnings, info, and steps
  • next gives the safest follow-up action when ota can suggest one
  • next_steps gives that same follow-up lane as an ordered machine-readable array when ota can break it into explicit steps
  • env_sources shows which env values won and where they came from
  • native_prerequisites shows the selected native prerequisite evidence for the executed native path, including additive check, activation, provisioning, and note detail when present
  • native_prerequisites[*].activation.applied tells you whether ota actually ran inside that activation for this command or only reported the declared activation shape
  • policy shows which effective approved provisioning source ota resolved for the run and any backend-specific source config
  • host_service_cleanup shows first-class host-managed service cleanup evidence when ota owned the stop path
  • execution_conflict.reasons[] shows typed active-execution conflict ownership such as host_service, compose_project, or service_task

How to read it

  • Check ok first to see whether execution succeeded
  • Then check scope and contract to confirm what ota ran against
  • Then check backend and lifecycle to understand the execution model
  • Then read steps to see what actually ran and where the run stopped
  • Then read summary, next, and optional next_steps for the roll-up and safest follow-up
  • Then inspect env_sources if you need provenance for the values that won
  • Then inspect native_prerequisites when the selected path depended on host-native build tooling or task-scoped shell activation
  • Then inspect policy if you need the approved provisioning source or source config
  • Then inspect host_service_cleanup when 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 --json when 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.task stays additive workflow context rather than the concrete execution task
  • use ota execution plan --json --mode container or --mode remote when you want the same backend-configuration gate that ota run and ota up would enforce before execution starts
  • use ota workspace execution plan --json when 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 --json when 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 fulfilled and commands[] evidence
  • every successful repo receipt now includes a normalized receipt.contract_snapshot_hash, and --archive also materializes that normalized contract JSON under .ota/contracts so 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 --archive to persist the JSON receipt under .ota/receipts (keeps the newest 50) and read archive_path plus receipt.contract_snapshot_ref from the output
  • use ota receipt --json --history when 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 latest when 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, read summary.comparison.contract_snapshot_changed, contract_changes[], and likely_related_changes[] to connect new blockers to contract drift
  • read summary.comparison.correlation first for the top-level advisory posture; possibly_related is reserved for coarse same-family overlap, while unrelated drift stays no_clear_correlation
  • use ota receipt --json --snapshot latest or --snapshot promoted when 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 resolved selection_kind, snapshot_hash, assumption_set_hash, summary.assumption_count, and snapshot_path
  • receipt diff stays read-only and exits 0 when the comparison succeeds, even if the current or baseline receipt is blocked
  • use ota run <task> --dry-run --json for task-level execution previews without starting the run path; the published schema is run-preview.json, and blocked previews still stay on the same stdout preview envelope so automation can read summary.primary_blocker directly
  • use ota up --json for readiness roll-ups and receipts
  • use ota workspace run --json, ota workspace up --json, ota workspace refresh --json, and ota workspace status --json for 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 --json when 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 up without 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