Skip to content

The log, IDs and names

.itero/itero.log holds everything the daemon does, one JSON object per line:

{"time":"2026-10-21T13:43:24Z","workspace":"01a0f3…","daemon":"01a15f2c…","event":"run.started","workflow":"order","run":"01a15eb3…","run_name":"misty-lake","message":"01a15eb2…"}
{"time":"2026-10-21T13:43:25Z","workspace":"01a0f3…","daemon":"01a15f2c…","event":"step.waiting","workflow":"order","run":"01a15eb3…","run_name":"misty-lake","step":"#check-payment","output":{"payment_ref":"pay-1"}}

Every line has time, workspace, daemon and event. A line about a run has workflow, run and run_name, and "internal": true when its workflow is internal.

eventAlso
daemon.startedevery field of the workspace and the daemon
daemon.stopped
messagemessage, type, data, and what it did: started and reached (runs), or nothing
run.startedmessage, or schedule
step.startedstep
step.done, step.waitingstep, output
step.failedstep, why
step.skippedstep, why (its on did not hold)
run.notenote: what the run did with a message or a timer
run.endedstatus (done, failed, error, split), why
run.skippeda schedule came due and the workflow’s on did not hold
source.started, source.ended, source.gave-upsource, why
paths.watchedpaths: every path watched now
errorwhy: what went wrong in the daemon itself

It holds what steps printed, never their environment, so no secret. Reading it is jq’s job:

Terminal window
jq 'select(.run_name == "misty-lake")' .itero/itero.log # one run
jq 'select(.event == "step.failed")' .itero/itero.log # what broke
jq -r '"\(.time) \(.event) \(.workflow // "") \(.step // "")"' .itero/itero.log
tail -f .itero/itero.log | jq . # live

Past its log limit (10 MB) the log is rolled: itero.log becomes itero.log.1, and so on, keeping logs of them (3). See The daemon’s own workflows.

itero gives each of these an identity nobody edits, kept in the journal:

idnamealso
the workspacea UUIDv7, made with its journaltwo random words: quiet-riverwhen it was made, its folder, the itero that made it
a daemon’s lifea UUIDv7, at each starttwo random wordswhen it started, its pid, host and itero version
a workflowa UUIDv7, the first time its file is seenits file nameits runs so far, its last run
a runa UUIDv7, at its starttwo random words: misty-lakeits workflow and status

A name is to say aloud and type; the id stays the identity, and two with one name are told apart by it. A workflow keeps its id while its file name stays, through any edit. Deleting .itero/ starts a new history, with a new workspace id.

Terminal window
itero workflows # each workflow: what starts it, its runs, the last; the daemon
itero info # the workspace: id, name, [meta], limits; and its daemon
itero runs # every run: id, name, workflow, status, started, ended
itero runs misty-lake # one run, by name or id, step by step
itero check # each workflow: its id, meta, runs so far, last run

itero runs <run> tells a run’s story from the journal: how it started, each step and how it went, the messages it took, where it waits, and its state at the end. Of two runs with one name it shows the newest, and says so.