Runtime logs
Runtime logs are Loom's structured runtime record for loom run --local. They are designed for pointer-first diagnosis: start with a receipt, open a few small JSON documents, and land on the exact failing phase or step without scanning the whole run output.
What changed in the current runtime model
Loom now records runtime progress as phases, not just broad job or step markers.
That means the log tree can answer three different questions cleanly:
- What failed?
- Which phase did it fail in?
- Was the runtime timeline itself valid?
How the pieces fit together
Use the receipt and manifests to find the right file first. Use the event streams only after you know which unit to inspect.
The files that matter most
| File | Why you open it |
|---|---|
pipeline/summary.json | Confirm pass or fail at the pipeline level |
pipeline/manifest.json | Identify the first failing job and top-level artifact pointers |
jobs/<job_id>/manifest.json | Branch to either a failing step or a failing system section |
jobs/<job_id>/user/execution/script/<NN>/events.jsonl | Read the failing user-step evidence |
jobs/<job_id>/system/<section>/events.jsonl | Read provider, cache, artifact, or cleanup evidence |
phase-report.json | Validate phase coverage and ordering across the whole run |
What phase-driven logs buy you
| Need | Best artifact |
|---|---|
| Find the failing job quickly | pipeline/manifest.json |
| Find the failing command | failing_step_events_path in the job manifest |
| Understand provider or cache failure | system_sections[].events_path in the job manifest |
| See whether cache or artifact work was skipped | Section summary.json or the matching manifest entry |
| Check whether Loom emitted the expected phase boundaries | phase-report.json |
Runtime phases you can rely on
The current runtime contract uses a small set of stable phase identities:
| Scope | Phase code | Practical meaning |
|---|---|---|
run | run.bootstrap | Loom captured run context and workspace attribution |
pipeline | pipeline.execute | The pipeline body |
job | job.provider_prepare | Provider and pre-execution setup |
job | job.cache_restore | Optional restore work before execution |
job | job.artifact_restore | The current artifact_extract section, normalized into an artifact phase |
job | job.execution | User execution envelope for the job |
step | execution.script | One script step |
job | job.cache_save | Optional post-execution cache write |
job | job.cleanup | Job cleanup |
run | run.finalize | Final contract-artifact writeout |
Not every job emits every optional phase. The point is that when the work happens, it is named consistently.
How to read an event stream
Every events.jsonl file is newline-delimited JSON. The current runtime contract uses three core event kinds:
| Event | What it means |
|---|---|
phase_start | A phase boundary opened |
output | Loom captured output inside that phase |
phase_finish | A phase boundary closed, with status and duration_ms |
Typical fields to watch:
| Field | Why it matters |
|---|---|
scope | Tells you whether the record is run, pipeline, job, section, or step scoped |
phase_code | Stable identity such as job.execution or job.cache_restore |
phase_family | Broad family such as user, cache, or artifact |
message | The actual output line for output events |
status, exit_code | The outcome on phase_finish |
metrics | Structured skip or telemetry details on phase_finish |
Skip behavior is explicit
Loom records skips as data, not silence.
| Where to look | What you will see |
|---|---|
| System section summaries and manifest entries | status: "skipped" plus skip_reason and metrics.skipped: true when Loom explicitly skipped that work |
| Cache phases | Metrics such as hit, cache_name, cache_key, and skip_reason |
| Artifact phases | Metrics such as file_count, archive_path, and skip_reason |
| Jobs that never ran | A skipped cleanup boundary rather than an absent job record |
That makes it much easier to distinguish "not applicable", "skipped by policy", and "failed".
Fast triage path
For most failures, the shortest path is:
- Open the receipt and follow
logs_dir. - Open
pipeline/summary.json. - Open
pipeline/manifest.json. - Open the failing job's
manifest.json. - Read the pointed
events.jsonl. - Open
phase-report.jsononly if you need coverage or ordering detail.
Sharing guidance
When you need help:
- Share the receipt path first.
- Then share one pointed
events.jsonlpath, not the whole log tree. - Include
phase-report.jsononly if the issue is about missing or out-of-order phases.