Inspecting Runs
Every pipeline run leaves a paper trail across three surfaces: the triggers table (the entry point), the run's trace (envelope + per-phase tasks), and the agent's logs (raw stdout / parsed turns). This page walks through how to navigate them when you need to know what happened.
1. Find a trigger
Triggers are the source of truth — every webhook, every cron tick, every MCP call enters the system through one. The DB is the most direct way to list them:
PGPASSWORD=bento psql -h localhost -U bento -d bento \
-c "select id, kind, source, event_type, pipeline, status, run_id, arrived_at
from triggers
order by arrived_at desc
limit 10;" id | kind | source | event_type | pipeline | status | run_id | arrived_at
--------------+---------+---------+---------------------+-----------+--------+------------+--------------------
d990d0a0-5f1 | webhook | github | pull_request.opened | pr-review | done | XbSjXLrysC | 2026-05-26 11:35:21
e10552e5-7d1 | schedule| - | - | heartbeat | done | mecOey_7rx | 2026-05-26 11:40:00Filter by kind, pipeline, status, or source to narrow down. The
shortened id (first 12 chars) is enough for the trace command — bento trace
accepts any unique prefix.
2. Trace a trigger
bento trace <id> follows one trigger through every layer it touched:
bento trace d990d0a0-5f1══════════════════════════════════════════════════════════════════════
TRACE: d990d0a0-5f1
══════════════════════════════════════════════════════════════════════
┌─ Trigger
│ id: d990d0a0-5f1
│ kind: webhook
│ source: github/pull_request.opened
│ pipeline: pr-review
│ status: done
│ arrived: Tue May 26 2026 12:35:21
│ completed: Tue May 26 2026 12:42:38
│ run_id: XbSjXLrysC
└
┌─ Workload
│ id: 043cbc31-31ac-4726-862c-07511d286547
│ status: active
│ ttl: 3600s
└
┌─ Invocations (1)
└── [a020a45e] reviewer
runtime=claude model=claude-sonnet-4-6 status=completed duration=436.7s
✓ workspace-setup (setup) 1457ms [ok]
✓ task:reviewer (spawn) 220750ms [ok]
✓ task:reviewer (spawn) 232402ms [ok]
✓ spawn (spawn) 435163ms [ok]
┌─ Orchestrator Output
│ <agent's final synthesised reply>
└The four sections, top to bottom:
- Trigger — what came in (HTTP webhook, cron, MCP), when, which pipeline matched, terminal status.
- Workload — the longer-lived container an invocation belongs to. One webhook can submit several invocations under one workload.
- Invocations — one per agent run. Each lists its phases (
workspace-setup,spawn, hooks) with duration + outcome. An orchestrated run showstask:<agent>sub-spawns for each tool call the orchestrator made. - Orchestrator Output — what the agent finally returned, after notes / citations / post-back processing.
Useful flags
| Flag | When |
|---|---|
--json | Pipe to jq for scripted inspection |
--no-messages | Skip agent message parsing — faster when the run is long |
3. Read the agent's stdout
The trace shows what the agent said at the end. To see how it got there — turn-by-turn, tool calls, intermediate thoughts — go to the agent log:
# Raw stream-json (the format the runtime CLI emitted)
bento daemon logs XbSjXLrysC --agent
# Same data, collapsed to readable per-turn text
bento daemon logs XbSjXLrysC --agent --render flat--render flat is usually what you want during debugging; raw is for
piping into a parser.
4. Watch a daemon in flight
For live tracing — what the daemon is doing right now — tail its log:
bento daemon logs # last 50 lines
bento daemon logs -f # follow mode (tail -f)
bento daemon logs -n 200 # widen the windowThe daemon's name: field in .bento/daemon.yaml (default bento) determines
where things live and what they're called:
| Thing | Path / label |
|---|---|
| Log file | ~/.bento/<name>/daemon.log |
| PID file | ~/.bento/<name>/daemon.pid |
| launchd label | dev.bento.<name> |
| systemd unit | <name>.service |
| Process title | <name>-daemon |
So with name: myproject, journalctl reads:
journalctl --user -u myproject.service -fRun-id-stamped lines correlate with bento trace:
[INFO] [workload-manager] invocation a020a45e running
[INFO] [workload-manager] invocation a020a45e workspace ready duration=1457ms
[INFO] [workload-manager] pipeline [pr-review] executing run=XbSjXLrysC ...5. Common questions
"Why did the agent fail?" — bento trace <id> first. If the failure is
in a hook, the failing step shows outcome=errored with the captured stderr.
If the failure is in the agent itself, drop to bento daemon logs <runId> --agent --render flat.
"What did the agent actually see?" — the run dir on disk:
~/.bento/workspaces/<workspace>/runs/<runId>/. It holds the assembled prompt
(meta.json), the agent's stdout/stderr files, and per-step artifacts under
steps/.
"Why didn't my webhook match a pipeline?" — list discarded triggers:
PGPASSWORD=bento psql -h localhost -U bento -d bento \
-c "select id, source, event_type, note from triggers
where status = 'discarded'
order by arrived_at desc limit 10;"The note column carries the matcher's verdict (e.g. no pipeline matched,
filter rejected: <expr>).
"What did setup actually do?" — the workspace-setup task is the first
phase in every invocation; its duration tells you whether a clone happened
(seconds) or it was a no-op mkdir (milliseconds). The shell script that ran
is deterministic from WorkspaceSource — see
packages/sandboxes/src/setup-script.ts:buildSetupScript.

