docs · one topic per page
v0.9.0

events what happened, and when

The head writes every task, job, machine and orchestrator event to a log, one JSON record per line. Read it to see what happened overnight, or feed it to a script. Connector hooks get the same records.

read it #

$ pastor events                # every record, oldest first
$ pastor events --task t-12    # one task's records
$ pastor events --follow       # keep printing new ones
$ pastor events --json         # the records as stored
flagdoes
--taskonly records about this task, like t-12 or 12
--followkeep printing records as they are written
--jsonone JSON record per line, the shape hooks get on stdin
2026-09-29 09:00:04  task.queued        t-12  queued  job=morning
2026-09-29 09:00:09  task.running       t-12  server-1  running  job=morning
2026-09-29 09:41:30  task.done          t-12  server-1  done  job=morning
2026-09-29 10:02:11  machine.lost       laptop  reconnecting  connection refused

On the head’s machine, pastor events reads the file, so it works with pastor serve down. With a remote head it asks the head instead, and --follow asks again every second.

For the changes you would act on, one line each, use pastor watch.

the log #

The log is ~/.local/state/pastor/events.jsonl. Past 10 MiB it moves to events.jsonl.1, replacing the one before, so at most two files are kept. pastor events reads both, oldest first.

event types #

A task’s state change is task. and the new state.

typewhendetail
task.queueda task was created: run, job, retry or orchestrator
task.runningits agent took the prompt, or picked the work back up
task.blockedits agent waits on a personquestion, when it ended its turn on one
task.pauseda critical task took its slot; it resumes later
task.limitedits agent stopped on a usage limitas agent.exhausted
task.rate_limitedits agent stopped on a 429 or 529 past its own retries; pastor retries it in the paneline, attempt (from 1), retry_at
task.waitingit waits for that limit to reset, its pane closed and its worktree keptwhy (no_fallback, reset_soon or all_exhausted), until, shown (waiting 03:00); account, model and waited (reset in 12m, under wait_under 30m) for a wait on its own model, models (each account, model, until) for one on every model of its list
task.agent_switchedit moved to its next model after a usage limit, in the same worktreefrom and to (each agent, model), why (limit or rate_limit), until (the old model’s reset), handover (session or pane_tail)
task.doneit finished
task.failedit failed
task.staleits timeout passed, or its pull machine was lost
task.closedits pane was closed
task.inputsomeone ran pastor task send, or pastor answered Claude’s limit picker with “Stop and wait”keys, text_len, trust with --trust, limit_picker from the picker, rate_retry from a short-limit retry; never the text
task.trustedthe head answered a folder-trust prompt from saved trustkeys
job.faileda job run failed
connector.finish_faileda connector’s finish command failedconnector, reason
machine.losta machine stopped answering; once per outage
machine.connecteda lost machine answers again
agent.exhaustedthe head recorded an account (or one model of it) as out of usageaccount, model, agent, until, retry_at, hard, no_credit, what, line
agent.resetan exhausted account can be used againaccount, model, agent, retry_at, by (time or hand)

Orchestrator events all carry orchestrator, its name, in detail. See orchestrators.

typewhenmore in detail
orchestrator.starteda run started an agentscheduled: lines; session: by (hours or hand), until
orchestrator.skippeda run was skippedreason: busy or post_pending
orchestrator.helda run was held backreason: max_orchestrators (with max), quota (with until) or restarts (with max, until)
orchestrator.quotaits agent stopped on a usage limituntil
orchestrator.faileda script failed, its agent could not start or failed, or its saved state could not be readstage (pre, agent, post or state), error; failures on pre
orchestrator.restarteda session’s agent ended early and a new one took overafter, the old task; restarts in the last hour
orchestrator.stoppinga session’s agent got its last messagereason (hours or hand), grace
orchestrator.stoppedthe session endedreason

a record #

{
  "seq": 812,
  "at": "2026-09-29T09:41:30.123Z",
  "type": "task.done",
  "task": {"id": 12, "job": "morning", "state": "done", "machine": "server-1", "...": "..."},
  "model": "sonnet",
  "job": "morning",
  "machine": null,
  "summary": {"round": 1, "outcome": "done", "text": "done: PR #42", "source": "agent", "at": "2026-09-29T09:41:29.900Z"}
}
fieldholds
seqthe record’s number; it only grows, across restarts and rotations; 0 on old lines
atwhen the head got the event, RFC 3339 UTC
typeone of the types above
taskthe full task row, as pastor task describe --json prints it, on events about a task; else null
modelthe [models] name the task runs; absent when it runs none
jobthe job’s name; run for a one-off task; null on events with no job
machineon machine.* events, the machine’s status as in pastor machine list --json; else null
detailmore, on the types that carry it; absent otherwise
summaryon task.done and task.failed: how the round ended, with round, outcome, text, source (agent or pane) and at

outcome is done, partial, blocked, nothing to do, unknown or no summary. See how it ended.

Fields may be added; none are renamed or removed. A line that does not parse is skipped.

hooks #

A connector can run a command on the head for the event types it names, with the record on stdin: a notifier for task.blocked, say. A hook that does not own a task’s job gets the task without its item, prompt or summary text. See connectors.

leave pastor?

Open in a new tab?

h/l choose · enter confirm · esc stay