Reconnecting
Restoring connection…
Reconnecting
Restoring connection…
Docs navigation
Get started
Connect an LLM
Operate
Build packs
Runs & history
The Runs page is where you see what your fleet actually did — every action dispatched to a host, newest first, with who or what asked for it, what it returned, and the policy decision behind it.
The Runs list#
Each row is one invocation against one host: when it ran, the action id, the target runner, who dispatched it, its status, and how long it took. Rows update in place as a run moves through its lifecycle, so you can watch a dispatch go from queued to finished without reloading. On a phone the row collapses to a two-line card — the action and its status on top, then origin, runner, and time below.
Four filters narrow the feed, and each one lives in the URL — so the back button, a refresh, and a shared link all land on the same view:
- — Status. One or more lifecycle states, so you can pull up just the failures, just what's awaiting approval, or just what's still in flight.
-
—
Action.
A substring match on the action id — typing
postgresfindspostgres.vacuumandpostgres.uptime— and it's case-insensitive. - — Runner. A searchable list of your runners, to scope the feed to one host.
- — Dispatched by. The origin: Operator, LLM agent, Runbook, or Scheduled. Pick Operator, LLM agent, or Runbook and a second picker appears beside it to narrow to a specific team member, agent, or runbook.
A runner's page links straight to its own runs, and an agent's page links to the runs dispatched with its key — so the common "what did this host, or this agent, do" question is one filtered link, not a hand-built query.
Run statuses#
A run moves through a small state machine. It starts pending, becomes sent, then running. From there it settles on exactly one terminal outcome. Policy can settle a run before it ever reaches a host: a require-approval decision parks it at pending approval, and a deny decision ends it at denied.
| Status | What it means |
|---|---|
| Pending | Created and queued. Waiting to be handed to its runner — or waiting for an offline runner to reconnect. |
| Pending approval | Policy required a human approval. The run is held until an approver decides; a denial cancels it. |
| Sent | Handed to the runner over its connection, not yet acknowledged. |
| Running | The runner acknowledged the dispatch and is executing. Output is streaming. |
| Cancelling | You asked to cancel an in-flight run. Waiting for the runner to stop and report its final outcome. |
| Success | The action ran and the runner reported success. Any declared structured output validated. |
| Failed | The action ran and exited non-zero. |
| Error | The run could not complete — its runner went offline, was disabled or removed, dropped mid-run, or never acknowledged the send before the dispatch timeout. The reason is on the run. |
| Timed out | The action ran past its time limit and the runner stopped it. |
| Validation failed | The runner's structured output did not match the action's declared output schema. |
| Unknown action | The runner reported it does not have the dispatched action. |
| Refused | The runner rejected the dispatch on a pre-execution trust check — a bad, missing, or stale signature, a pack-hash mismatch, or a local admission block. Nothing executed. |
| Denied | Policy rejected the dispatch at creation. The run was never sent to a runner; the matched rule and reason are recorded. |
| Cancelled | You, or a denied approval, pulled the run back. The reason is recorded. |
Three terminal statuses look alike and mean different things — and the difference tells you what to do next: for Denied the fix is a policy change, for Refused it's usually re-trusting the pack or the signing setup, and Failed is a real result to read, not a gate.
A single run#
Open a row for the full record of that one invocation. A fact strip leads with the outcome and the essentials: Status, the Runner it targeted (a link to that host), Dispatched by, Duration, the process Exit code, and the Started time.
Dispatched by
names the accountable person first. An operator run shows the team member who ran it; an
agent run shows the human who owns the API key the agent used, with the client as secondary
context — jordan@example.com via Claude Code. A
run from a runbook or a schedule names that source instead. This is the same human-first
attribution the audit trail uses, so "who ran this, and through what" is answered on the row
itself.
A Why
section carries the justification. Every dispatch requires a
reason
— the operator's or agent's short "why I'm running this" — and an agent may add an optional
evidence-and-expected chain: what it already observed, and the outcome it expected to
confirm. When policy intervened, the run also shows the matched rules and the exact policy
version the decision was made under; a routine allow is left off, because a run that
dispatched at all already cleared policy.
Below that are the arguments
the action was called with — carrying a
sha256
fingerprint of the exact bytes — and the executed command, the real shell
line the runner ran. Sensitive argument values are redacted before either is stored, and the
command is marked secrets redacted
(and truncated
when the stored copy was clipped). Redaction happens on the host, on the way out, so the
control plane never receives the raw secret — see the
security model
for how the redaction pipeline works.
Live output and caps#
The output panel streams the run's stdout and stderr as the runner produces them, line by line. stderr is tinted so errors stand out in a noisy stream, and a streaming marker shows while the run is still in flight; a run that produced nothing says so instead of showing an empty terminal.
The terminal renders the most recent 500 chunks. A run that streamed more shows a note that earlier output was trimmed. This is a display limit that keeps a chatty run from growing the page without bound — it caps what's on screen, not what the runner sent or what's recorded.
Truncation can also happen at the source. The runner bounds the output it captures per the action's output settings; when it hits that limit it clips the stream and flags the run as truncated. Each run also records whether every progress chunk arrived, so a gap left by a mid-run disconnect is visible rather than silent.
Every run carries a durable output budget: up to 50,000 progress chunks and 64 MiB in total, with any single chunk capped at 256 KiB. A run that would exceed the budget stops accepting further chunks. The cap is charged under the run's row lock, so it holds across runner reconnects — a runaway or hostile runner can't flood the control plane by streaming without end.
To watch a runner from the host itself — its service log and its local event journal — tail them over SSH:
# the runner's service log and its local event journal, live $ journalctl -u emisar -f $ sudo emisar events tail -f
Cancelling a run#
You can stop a run that hasn't finished. Open it and use Cancel run — available while the run is pending, sent, or running, to operators and above. What happens depends on where the run is:
- — Queued (pending). The run hasn't reached the runner yet, so it's cancelled immediately and never dispatches.
- — In flight (sent or running). The control plane signals the runner to stop — SIGTERM, then SIGKILL if it doesn't — and the run sits at cancelling until the runner reports its final outcome. The runner stays the authority on what actually stopped.
Cancellation is recorded in the audit trail and is idempotent — asking to cancel a run that already finished does nothing. A run that's awaiting approval isn't cancelled here; deny its approval instead, which pulls the run back and records the denial reason. See policies and approvals.
Operations and retries#
Each run is one invocation, and each stays a faithful record of one attempt. Re-running an action — from a runner's page, a runbook, or an agent — creates a new run; emisar never silently retries a finished one. An in-flight run does survive a runner reconnect, and a queued run dispatches once its runner returns, so a brief disconnect doesn't lose work — the reconnect and stuck-run semantics are covered under the runner fleet.
When one dispatch targets several hosts at once — an agent fanning an action across a runner group over MCP — each host gets its own run, and those runs are grouped under one operation. A fan-out reaches up to 16 runners and reads as a single action with a result per host. Grouping is also what makes a retry safe: replaying the same operation returns the original runs instead of dispatching duplicates, so a lost response never becomes a double execution.
A runbook works the same way. One execution groups every run its steps produced, in dispatch order, so a multi-step sequence reads as one unit rather than a scatter of unrelated rows — see runbooks. For recovering an exact operation after an ambiguous response, the MCP reference covers the idempotency and recovery contract.