Skip to main content

Runtime logs contract

Each recorded workflow run writes two append-only JSONL files:

.loom/.runtime/runs/<run_id>/
state.jsonl
events.jsonl

Each line is one JSON object. Both files carry run_id and timestamp. Context may additionally include workflow_id, job_id, step_id and command_id. These IDs connect output to the operation that produced it.

State records​

state.jsonl records lifecycle transitions in append order. A record contains:

FieldMeaning
kindWorkflow, job, step or command scope.
nameReadable operation name.
statusRecorded lifecycle status.
exit_codeOptional integer result, including zero when available.
errorOptional protected error message.

Read the records for an operation in file order to follow its state. A final workflow state records the run outcome when finalization completes. An interrupted run can end with a running state.

Event records​

events.jsonl stores contextual messages and process output. Records contain level, stream and message, with optional exit_code. message preserves its string contents, including embedded newlines, blank lines, carriage returns and output without a terminating newline. A record need not be one output line. The order is the order in which recording accepted events; timestamps do not establish an independent cross-process chronology.

Declared workflow secrets and known run redaction values are protected before recording. Review excerpts before sharing them because undeclared or generated secrets may appear in tool output.

Reading a run​

Discover saved runs, then select an exact run ID:

loom runs
loom logs <run_id> --state
loom logs <run_id> --tail 30
loom logs <run_id> --json

MCP exposes loom_list_runs, loom_read_run and loom_read_events; see the tools reference.

Discovery summarizes only complete workflow records from state.jsonl: the directory run ID, latest workflow ID/status/optional exit and first/last workflow timestamps in append order. Missing or zero timestamps stay unavailable. Rows sort by first recorded timestamp descending, run ID ascending for ties, with unavailable starts last. Empty/no-workflow state still lists the ID. Recorded pending/running states are not process-liveness claims.

A missing runs directory is an empty result. Non-directory entries, symlink aliases and invalid run-ID directories are ignored. A candidate with missing, unreadable, nonregular, escaping or malformed state data fails discovery without a partial successful list. A nonempty workflow run ID must match its directory. Discovery writes no index or other run files. See loom runs.

Readers accept a complete final JSON object without a newline. They ignore an incomplete final object left by an interrupted append and reject malformed complete lines. They read these files directly. There are no hash inventories, manifest-selected histories or separate stdout/stderr segment files in this recording format.

Job artifacts​

Declared artifact files are separate from workflow recording. Local runs publish them beneath .loom/.runtime/artifacts/<run_id>/jobs/<job-id>/. Artifact messages and failures use the same contextual event stream; the recording directory still contains only the two JSONL files.