Skip to content

Watching BoB Work

Four layers, one question each. A warp-drive run is the thing you watch first, but it is not the only thing that can go wrong. The project around it can be half set up, the machine under it can run an old BoB, and the fleet it belongs to can have a machine that stopped reporting. BoB has a view for each layer. This page explains what each view reads and which question it answers. The Watching BoB Work tutorial opens them all around one live run, and takes every command below from this page.

Every view on this page reads state that something else wrote: the run’s state file, the project’s last bob ready verdict, the machine’s deploy record, the snapshots each machine publishes. None of them fixes what it finds. That keeps watching safe: you can open any view, at any time, during a live run, and nothing moves. When a view finds a problem, it names the one command that fixes it, and you decide whether to run it.

It also means a view is only as fresh as what it reads. Each section below says where its data comes from, so you know how old an answer can be.

The views are easiest to learn with a run going. Start one in tmux so it keeps working while you look at it, on the hello-bob project from BoB in One Day, with one approved requirement:

Terminal window
bob warp start --level 3 --session hello-bob-watch

bob warp start runs the preflight gate first, then starts the run in a tmux session named hello-bob-watch and prints its viz URL. A Level 3 run works the requirement from start to finish without asking, which leaves you free to watch.

A warp-drive run writes one record, .claude/.warp-drive-state.json, at every phase change. The run views read that record and nothing else:

Terminal window
bob warp status
bob warp log
bob warp viz
  • bob warp status prints the current phase, the issue, the chunk, the preflight verdict, the forge state and the token use so far. Add --watch to redraw it in place.
  • bob warp log prints the phase history: one row per transition, with the event that caused it and when.
  • bob warp viz opens the live session graph in the browser: the same phases as nodes, the current one highlighted, served by the project’s dashboard server.

Because all three read the same file, they can never disagree about the phase. When they do not match what you expect, the state file is the truth.

The project: is it set up to be worked on?

Section titled “The project: is it set up to be worked on?”

A run can only be as good as the project it runs in. Missing links, an unprovisioned skill, no labels or no port band make a run stumble in ways the run views cannot explain. The project views answer “is this project ready?”:

Terminal window
bob status
bob status --scope project
bob dash status --projects-only
bob dash serve --list
  • bob status with no arguments is the front door. It prints one line each for the host, the project you are in and the fleet, from cached verdicts with no network call, then what is running here (the warp run, each dashboard and its URL), and ends with exactly one next: command.
  • bob status --scope project grades the project now: the same checks as bob ready --dry-run (repo, links, init, provisioning, labels, ports, manifests), plus informational sections for readiness, rituals and backups. It never changes anything; bob ready is the command that fixes what it finds.
  • bob dash status --projects-only shows every registered project on this machine: its links, its last bob ready verdict and any open harness defects (see below).
  • bob dash serve --list lists the dashboard servers on this machine with their ports. The one serving your run’s viz is the project’s dashboard server; bob dash serve starts it when it is not running.

Every command you run executes the BoB deployed on this machine (~/.claude), not the source checkout. If the deploy is broken or old, every project on the machine behaves oddly at once. The machine views answer “does this machine run the BoB it thinks it does?”:

Terminal window
bob status --scope host
bob doctor

Both run the same probe. It compares ~/.claude with the commit it was deployed from, checks every link, the toolchain and the hook wiring, and prints one PASS line per check. The INFO lines report without grading: the deployed version, how far the source has moved on since (behind source, which is never drift), and the snapshot timer. bob status --scope host wraps the probe in the same bob-status/1 document as the other scopes, so one reader can handle all three.

A fleet is every machine that runs BoB: your laptops and the farm. You cannot see a machine you are not on, so each machine publishes a snapshot of its projects, runs and health, and the fleet views read the snapshots:

Terminal window
bob status --scope fleet --no-live
bob viz
node ~/.claude/scripts/fleet/snapshot-timer.js status
  • bob status --scope fleet prints the fleet audit: one row per machine with its role, its snapshot’s status and age, and its projects. Then come tables for readiness, hook convergence and harness defects. --no-live reads only the cached snapshots; without it, this machine is re-measured first.
  • bob viz opens every project on every machine as small multiples in the browser, each tile linking to that project’s bob warp viz.
  • snapshot-timer.js status shows whether this machine publishes on a timer (a systemd user timer on Linux, a launchd agent on macOS) and how often.

A machine’s status tells you how much to trust its row:

Status Means
live Measured just now. Without --no-live, this machine is measured live, and another machine is live when its own snapshot generator was run over Tailscale because it had no fresh published copy.
published Read just now over Tailscale from the snapshot that machine last published to its own snapshot dir, because that copy is under 24 hours old. AGE is that snapshot’s age. See how a live pull reads a remote machine.
cached Read from its newest snapshot, which is under 24 hours old.
cached(stale) Its newest snapshot is older than 24 hours: the machine is off, or its timer stopped.
never It has no snapshot at all. Install the timer there with audit.js snapshot --install-timer.

A stale or never machine is not necessarily broken. It is unobserved, which is worse, because nothing it does reaches you.

The layer views say whether things are healthy. Three more views say why a run is struggling, even when every layer reports OK.

Harness defects: automatic steps done by hand

Section titled “Harness defects: automatic steps done by hand”

BoB drives a run with hooks: a commit advances the phase, an issue edit marks the docs updated. When a hook does not fire and the session does the step by hand, the run records a harness defect: which automatic behaviour was compensated, and a fingerprint for it. One defect is a hiccup. The same fingerprint across many runs is a BoB bug that every project is quietly working around.

Terminal window
bob dash status --projects-only
node ~/.claude/scripts/warp-drive/harness-defect-summary.js state .

bob dash status adds a ⚠ harness-defects: line under any project whose run recorded one, and prints nothing when there are none. The summary script prints the same line for one project (harness-defects: none when it is clean). The fleet view (bob status --scope fleet) rolls them up per machine in a Harness defects table: open fingerprints, recurrences, how many were never reported, and which projects.

Most of what BoB records lives on GitHub: issues, comments, labels, PRs. When GitHub is slow, rate-limited or down, a run keeps coding, testing and committing, and the writes it could not make wait in a queue:

Terminal window
bob forge health
echo $?
bob forge queue status

bob forge health classifies the forge from the outcomes of real gh calls on this machine, and prints the quota left and who spent it. Its exit code is the verdict, so a script can branch on it without parsing text:

Exit Verdict Means
0 operational Recent calls succeeded.
3 degraded Some calls fail or are rate-limited. An empty answer cannot be trusted.
4 unreachable Calls are not getting through at all.
5 unknown No recent evidence, and probing was suppressed.

bob forge queue status lists the writes waiting for the forge. Each one was counted as done by the run and is replayed at the next item boundary. An empty queue is the normal state.

Every run records its token use by chunk and, when it ends, its total, in ~/.claude/token-usage.jsonl. /token-report (a registry skill) and the script behind it read that file:

/token-report
Terminal window
node ~/.claude/scripts/warp-drive/token-report.js --last 1

Both print a table by project, then the most recent sessions, then totals, each with input, output and cache-read tokens and an estimated cost. Use the script when the skill is not provisioned in the project. A live run appears once it ends; until then, the Segment: line in bob warp status shows the tokens it has used so far.