Skip to main content

Receipts contract

Receipts are the stable entry point for Loom run diagnostics. Loom writes them under .loom/.runtime/receipts/ and prints the resulting file path to the terminal so you can jump directly into the right runtime artifacts without reconstructing paths by hand.

Where receipts live

.loom/.runtime/receipts/<filename>.json

Current loom run --local filenames use this pattern:

loom-run-local-<nanosecond-timestamp>.json

Example:

loom-run-local-1772865600000000000.json

Treat the filename as an implementation detail. Use the path printed by the CLI rather than constructing the name yourself.

What the CLI prints

At the end of a run, Loom prints the receipt path in this form:

receipt: /absolute/path/to/repo/.loom/.runtime/receipts/loom-run-local-1772865600000000000.json

The current implementation prints the absolute path.

Receipt schema (v1)

The receipt is JSON. The field list below describes the current loom run --local receipt shape. Other receipt kinds may use the same schema_version and kind pattern with a smaller field set.

Core fields

FieldTypeDescription
schema_versionstringAlways v1
kindstringCurrently loom-run-local for local runs
commandstring[]Exact CLI invocation
repo_rootstringAbsolute repository root
workflow_pathstringAbsolute workflow path
started_at, finished_atstringRFC 3339 timestamps
duration_msintegerWall-clock runtime in milliseconds
statusstringCurrent values are success or failure
exit_codeintegerProcess exit code
errorstringPresent when Loom surfaces a run error

Runtime pointer fields

FieldTypeDescription
logs_dirstringAbsolute path to .loom/.runtime/logs/<run_id>/
events_jsonl_pathstringAbsolute path to the run-scoped events.jsonl
phase_report_pathstringAbsolute path to phase-report.json for the run

Execution context fields

FieldTypeDescription
snapshot_pathstringSnapshot or isolated workspace path when present
snapshot_head_shastringGit revision used for the snapshot when present
graph_irobjectResolved graph IR when available
executor_receiptobjectExecutor order and per-node outcomes when available
warningsobject[]Validation or runtime warnings when present
cache_diffobjectCache-diff receipt block when that mode is enabled

Example

{
"schema_version": "v1",
"kind": "loom-run-local",
"command": ["loom", "run", "--local", "--workflow", ".loom/workflow.yml"],
"repo_root": "/Users/you/project",
"workflow_path": "/Users/you/project/.loom/workflow.yml",
"snapshot_path": "/private/var/folders/.../loom-run-local-1772865600000000000",
"snapshot_head_sha": "9304d9b815cae5c49ac4b5c987532d101c948408",
"logs_dir": "/Users/you/project/.loom/.runtime/logs/loom-run-local-1772865600000000000",
"events_jsonl_path": "/Users/you/project/.loom/.runtime/logs/loom-run-local-1772865600000000000/events.jsonl",
"phase_report_path": "/Users/you/project/.loom/.runtime/logs/loom-run-local-1772865600000000000/phase-report.json",
"started_at": "2026-03-07T12:00:00Z",
"finished_at": "2026-03-07T12:00:12Z",
"duration_ms": 12000,
"status": "success",
"exit_code": 0
}

Pointer-first usage

Follow these fields in order:

FieldWhat it answersNext step
status, exit_codeDid the run succeed?If not, open logs_dir
logs_dirWhere are the pipeline and job artifacts?Open pipeline/summary.json
phase_report_pathDid the phase timeline validate?Open when you need coverage or ordering detail
events_jsonl_pathWhere is the full run-scoped event stream?Use when narrower pointers are still insufficient
snapshot_head_shaWhich exact revision ran?Confirm you are debugging the right code

Receipts do not inline artifact pointers or failing-step pointers. Use logs_dir to move into the runtime logs contract:

  1. Open the receipt.
  2. Check status and exit_code.
  3. Follow logs_dir to pipeline/summary.json, then pipeline/manifest.json.
  4. Follow job-level pointers from there.
  5. Use phase_report_path when you need phase validation rather than failure output.

phase_report_path

The current loom run --local receipt surfaces phase_report_path as a first-class pointer to:

.loom/.runtime/logs/<run_id>/phase-report.json

Use it when you need to answer questions like:

  • Was a required phase boundary missing?
  • Did the current artifact_extract section emit and normalize to job.artifact_restore?
  • Was runtime coverage fully attributed?

phase-report.json is separate from the main failure ladder. It complements pipeline/manifest.json; it does not replace it.

Artifact navigation

Receipts point to artifacts indirectly:

  1. Receipt logs_dir
  2. pipeline/manifest.json
  3. A job entry's artifacts_path or artifacts_archive_path

That keeps the receipt small while still giving you a deterministic path to extracted job outputs.

Versioning and compatibility

Receipts carry schema_version: "v1".

During Alpha, Loom may add fields. Breaking changes should increment schema_version.

Privacy and sharing

Receipts contain machine-useful pointers, but many fields are sensitive enough to review before sharing outside your team.

FieldWhy it may be sensitive
repo_root, workflow_path, snapshot_path, logs_dir, events_jsonl_path, phase_report_pathReveal usernames, filesystem layout, and workspace structure
snapshot_head_shaReveals commit identity
commandShows exact flags and arguments

When asking for help, sharing the receipt path or a redacted receipt is usually enough to start. Expand to specific log or event pointers only when needed.

Stability guidance

Safe to build against

  • schema_version
  • kind
  • logs_dir
  • events_jsonl_path
  • phase_report_path
  • status
  • exit_code

Do not hardcode

  • The filename pattern alone
  • The exact set of optional execution-context fields
  • Whether every receipt kind carries the full run-local field set