Run Lineage and the Local Dashboard: A Full Audit Trail You Can Actually Read
Run Lineage and the Local Dashboard
CodeLoop's verify loop is fast and quiet by design — the agent calls a tool, the tool returns structured JSON, the loop continues. But "fast and quiet" is not what you want when something *did* go wrong three commits ago and you need to know exactly when. This post is about the audit trail CodeLoop records under the hood, and the local dashboard that turns it into something you can read.
The shape of a run
Every call to codeloop_verify produces a run. A run is a directory under .codeloop/runs/ containing:
- run.json — the typed metadata: timestamps, agent, command, exit codes, gate results.
- build.log, test.json, lint.json — raw outputs from each runner.
- screenshots/ — every screenshot captured during the run, with their viewport metadata.
- video.mp4 (when interactions ran) — motion-validated, key frames extracted.
- diagnose.json — the categorised repair tasks, if the run failed.
- gate.json — the confidence breakdown, if a gate check ran.
The directory layout is stable across versions: tooling that read it last release will still read it next release.
The lineage triple
What makes a run *useful* later is its lineage. Each run.json carries three identifiers:
- run_id — the unique ULID for this verify call.
- commit_sha — captured at the start of the run, before any agent edits.
- branch — the git branch the run was launched from.
This triple is enough to reproduce any historical decision. "What did the gate look like on main at commit abc123?" becomes a one-line lookup. "Which run captured the screenshot we shipped to the customer?" becomes a grep on run.json files. There is no separate database to keep in sync — the lineage lives next to the evidence.
The lineage is also passed back to the agent on every tool call: run_id and commit_sha are part of the response so the agent can cite them in its own messages. When you read a Claude Code transcript later, the run identifiers are sitting right there, ready to click through.
The local dashboard
codeloop dashboard
That is the entire setup. The CLI starts a small local server (default http://localhost:7890) that reads from .codeloop/runs/ and renders three views:
tail -f.The dashboard is read-only. It does not write to the run directory, does not start new runs, does not require a login. It is a window into evidence that already exists on disk. You can run it on any machine that has access to the .codeloop folder — including a CI worker after the fact.
Why local
There is no SaaS dashboard. CodeLoop is local-first by design: your build logs, your screenshots, your video footage, your AI agent's behaviour — none of it leaves your machine. If you want to share a run, you commit .codeloop/runs/ to git or rsync it elsewhere; either way the data is yours.
The trade-off is that you do not get cross-machine aggregation out of the box. We think that is the right trade-off for the v1 — codeloop is a developer tool, not an observability product. If your team needs aggregation later, the dashboard's source is small and the data layout is documented; pointing a Grafana or Metabase instance at the run files is straightforward.
What this means in practice
The lineage and dashboard combine into a simple property: every CodeLoop decision is later defensible. When a customer asks why a feature shipped, when a teammate asks how the gate passed, when you ask yourself why the agent gave up — the answer is one click away, with full evidence.