Reports
Reports
Section titled “Reports”scripts/dashboard/reports.js builds one bob-reports/1 document: every
report the fleet produced in the last 14 days, newest first (#2073). Reports
are a view, not a scroll through GitHub. Nothing is stored. Every build reads
each source again.
Commands
Section titled “Commands”node scripts/dashboard/reports.js # one block per report, then each source's statusnode scripts/dashboard/reports.js --json # the bob-reports/1 documentDocument
Section titled “Document”{ "schema": "bob-reports/1", "generated_at": "2026-09-13T22:00:00.000Z", "refresh_s": null, "machine": "macbook-air", "window_days": 14, "since": "2026-08-30T22:00:00.000Z", "sources": { "tick-digest": { "status": "ok", "reason": null, "count": 1, "machines": [ { "id": "macbook-air", "source": "local", "as_of": "2026-09-13T22:00:00.000Z", "stale": false, "count": 0, "reason": null }, { "id": "farm-01", "source": "snapshot", "as_of": "2026-09-13T21:30:00Z", "stale": false, "count": 1, "reason": null } ] }, "session-report": { "status": "unavailable", "reason": "rate-limited" }, "status-report": { "status": "ok", "reason": null, "count": 0, "truncated": false } }, "reports": [ { "kind": "tick-digest", "title": "bob tick 2026-09-13", "at": "2026-09-13T03:12:00Z", "project": "bigbrain", "machine": "farm-01", "ref": "paulirv/bigbrain#2311", "url": "https://github.com/paulirv/bigbrain/issues/2311", "verdict": "ok — 2 merged", "exit": 0, "markdown": "## bob tick — 2026-09-13 (live) on farm-01\n…", "stale": false } ]}Report keys
Section titled “Report keys”| Key | Meaning |
|---|---|
kind |
tick-digest, session-report or status-report. |
title |
The issue title. For a digest, bob tick <date>, with the mode in brackets when it was not live. |
at |
When the report was made: a digest’s finished_at (else started_at, else its date), an issue’s createdAt. |
project |
The projects.json name. A digest’s project is matched by its directory, then by basename (a remote machine’s path does not resolve here), else it is the basename. |
machine |
The machine a digest ran on. null for issues, which live on the forge. |
ref, url |
owner/repo#N and its link. A digest links the plan issue the tick ran, which carries the digest comment. Both are null for a digest with no plan; url is null when the plan’s repo is unknown. |
verdict, exit |
A digest’s verdict line and exit code. null for issues. |
markdown |
A digest’s rendered .md, as bob tick wrote it. null for issues, and for a digest whose .md is missing. |
stale |
true for a digest read from a snapshot older than BOB_FLEET_STALE_SECONDS (default 24 h). |
state |
An issue’s open or closed. Issues only. |
Reports are ordered newest at first. Anything older than since
(generated_at minus window_days) is left out.
Sources
Section titled “Sources”| Source | Read from |
|---|---|
tick-digest |
This machine: every tick-digest/1 in $BOB_HOME/fleet/ticks/ in the window, with its .md. Every other registry machine: its newest snapshot’s last_tick (Fleet Snapshot Timer), since bob tick writes a digest only where it ran (#2054). A remote machine therefore contributes its newest digest, and a new one within one snapshot interval. |
session-report |
gh search issues --label session-report --created >=<since> over the registry’s owners, newest first, filtered to repos a projects.json entry on this machine has as its origin. |
status-report |
The same search for status-report. An issue carrying both labels is listed once, as a session-report. |
Every source reports a status:
status |
Meaning |
|---|---|
ok |
Read. count is how many reports it produced. truncated: true means a search returned a full page of 100, so older reports may be missing. |
unavailable |
The read failed. reason is typed: for gh, the #1968 names (gh-missing, unauthenticated, rate-limited, and, from the dashboard server, server-cannot-run-gh and gh-failing), else unavailable. The digests still list. |
not-measured |
There is nothing to read: no project on this machine has a GitHub origin. |
tick-digest.machines says, per machine, where its digests came from: local,
snapshot (with as_of and stale), or null with a reason. A machine
that published no snapshot, or whose snapshot predates last_tick, is named
there, so a missing digest is never mistaken for a machine that ran no tick.
- gh goes through the shim. Both searches run on
PATH, where the gh shim cachessearch issuesreads (the forge cache, #1749). When the forge is down, a recent cached read is served instead of a failure. - Two searches. A build costs two search API calls.
- Local reads for digests. This machine’s tick directory and the snapshot directory. No network call.
Served by the dashboard
Section titled “Served by the dashboard”bob dash serve (the one dashboard server, scripts/dashboard/server.js)
serves the document at /reports.json. bob viz
renders it as the Reports pane on /bob.
| Behaviour | Detail |
|---|---|
| Refresh | Rebuilt at most once every refresh_s seconds (DASH_REPORTS_REFRESH_S, default 120), however many tabs poll it: a build runs two issue searches. A request that arrives during a build waits for that build instead of starting another. A digest published in a snapshot is on the page within one snapshot interval plus one rebuild and one poll. |
| Page | /bob re-reads /reports.json every refresh_s and repaints only when the pane changed, so a digest folded or opened by hand stays that way. Each entry shows its kind, machine and project, its date, and its title linked to its issue. A tick digest also shows its verdict and its markdown; the newest digest is open and the rest fold. |
| gh | The issue searches use the server’s own gh runner, so they count toward its gh liveness tracker (#1968). An unreadable session-report or status-report carries the server’s reason, which can also be server-cannot-run-gh or gh-failing, and the document gains the same gh evidence block as the /warp panes. The pane prints each reason with what to do about it, and still lists the digests. |
| Render | scripts/dashboard/bob-reports.js, served as /bob/reports.js, is a pure function of the document. It renders the markdown bob tick writes (headings, bold, code spans, pipe tables, - lists) from escaped text, so nothing inside a digest can inject markup. tests/test-reports-pane.js snapshots its output (tests/fixtures/bob-viz/reports.html). |
| Failure | If the document cannot be built at all, the response has reports: [] and an error, and the pane shows the error. “no reports in the last 14 days” appears only when every source was read. |
See also
Section titled “See also”- Notices: the
bob-notices/1inbox built the same way - Fleet Snapshot Timer:
last_tick, and what keeps it fresh - bob viz: the page these reports are for
tests/test-reports-pane.js: ordering, the 14-day window, gh unavailable