Notices
Notices
Section titled “Notices”scripts/dashboard/notices.js builds one bob-notices/1 document: BoB’s
inbox (#2071). Each notice is something only Paul can act on, and each carries
the one command or link that acts on it. Nothing is stored. Every build reads
each source again, so a notice is gone on the first build after its source
clears.
One notice is a hint rather than a wait: did-you-know (#2077) names one tool
provisioned in the project in view that has never been invoked there, taken
from bob tour. It is never counted as needing Paul.
Commands
Section titled “Commands”node scripts/dashboard/notices.js # one block per notice, then each source's statusnode scripts/dashboard/notices.js --json # the bob-notices/1 documentnode scripts/dashboard/notices.js --project <dir> # the did-you-know for <dir> (default: the current directory)Document
Section titled “Document”{ "schema": "bob-notices/1", "generated_at": "2026-09-13T22:00:00.000Z", "refresh_s": null, "machine": "farm-01", "sources": { "todo": { "status": "ok", "reason": null, "count": 1, "truncated": false }, "blocked": { "status": "ok", "reason": null, "count": 1, "not_measured_machines": ["macbook-air"] }, "decision": { "status": "unavailable", "reason": "rate-limited" }, "bridge-question": { "status": "not-measured", "reason": "pending bridge questions live in the remote-decision-bridge worker, …" }, "release": { "status": "ok", "reason": null, "count": 0, "deployed": "1.273.0", "newest": "v1.273.0" }, "did-you-know": { "status": "ok", "reason": null, "count": 1, "project": "bigbrain", "unknown": 32 } }, "notices": [ { "kind": "blocked", "project": "bigbrain", "machine": "farm-01", "title": "warp run blocked: preflight failed (host)", "ref": "paulirv/bigbrain#2400", "since": "2026-09-13T20:00:00Z", "stale": false, "action": { "command": "bob update", "url": "https://github.com/paulirv/bigbrain/issues/2400" } }, { "kind": "did-you-know", "project": "bigbrain", "machine": "farm-01", "title": "bob-mirror: Reconcile and publish to each repo's declared second git host (mirrors.json): …", "ref": "bob-mirror", "since": null, "stale": false, "action": { "command": "bob mirror --help", "dismiss": "bob tour --park bob-mirror" } } ]}Notice keys
Section titled “Notice keys”| Key | Meaning |
|---|---|
kind |
todo, blocked, decision, release or did-you-know (see below). |
priority |
todo and decision: p1 … p4, from the source issue’s priority label (p1-critical … p4-low, #2477). null means not measured: the issue has no priority label. /bob pins a p1 notice, like every blocked notice, above the Notices fold (#2922), and filters the column by it. Other kinds carry no priority. |
project |
The projects.json name the notice belongs to. For did-you-know, the project directory’s name as bob tour reports it. |
machine |
The machine id for blocked, release and did-you-know. null for todo and decision, which live on the forge, not on a machine. |
title |
One line: the issue title, the failed checks, the release, or the item and when to reach for it. |
ref |
owner/repo#N for an issue, the tag for a release, the item name for a hint, null when there is none. |
since |
When the wait began: the issue’s creation, the decision comment, the failed preflight, the tag. null when not measured, and always null for did-you-know, which is not a wait. |
handoff |
On a todo or blocked notice that has a handoff record (#3058): {kind, what, why, command, text, todo, plan}, the engine’s own words, taken from the fleet feed’s handoffs and matched by todo (owner/repo#N) or, for a blocked run, by machine and project. Absent when there is no record. The needs-you banner renders it. |
age_s |
Seconds from since to generated_at, measured on the document’s clock so a renderer never reads one. null when since is null. |
stale |
true for a blocked notice read from a snapshot older than the fleet feed’s stale_after_s. |
action |
{command}, {url}, or both. A command runs on machine, in the project. did-you-know adds dismiss, the command that parks the item. |
Notices are ordered oldest since first, so the longest wait leads. Undated
notices come last, and did-you-know after every other kind.
| Kind | Source | Action | Clears when |
|---|---|---|---|
todo |
Open issues labelled todo without completed in any registered project’s repo: one gh search issues --label todo --state open over the registry’s owners, filtered to repos a projects.json entry on this machine has as its origin. |
url: the todo. command: gh issue edit N --repo R --add-label completed, the done-signal, once the action is done. |
completed is added, or the todo is closed. |
blocked |
A project whose warp phase is blocked on any machine in the fleet feed, with the feed’s preflight. |
command: the failed checks’ fixes, de-duplicated and joined with &&. bob preflight when no fix was recorded (it re-grades and prints them). url: the todo the gate filed. |
The run leaves blocked. A remote machine’s notice clears with its next snapshot. |
decision |
Open issues whose latest comment is a ## Decision Needed. Candidates come from gh search issues "Decision Needed" --match comments, then each one’s comments are read (at most 20 per build). |
url: the decision comment. |
Any later comment, answer or status update, since the question has moved on. The issue closing clears it too. |
release |
The newest vX.Y.Z tag in BOB_SOURCE (as last fetched) is newer than the version in this machine’s BOB_HOME/.bob-version (#2046). |
command: bob update. |
The machine is updated to that version. |
did-you-know |
One unknown item from bob tour --json --no-backfill for the project in view: never invoked in that project’s session ledger, and neither tried nor parked. The unknown items, in name order, are indexed by the UTC day number of generated_at, so every build in a day shows the same item and the next day shows the next. A parked or in-use item is never shown. The project in view is the dashboard server’s project, or --project (default: the current directory) on the command line. |
command: the item’s try-it command from the tour. dismiss: bob tour --park <item>, run in the project, which records the item as parked in <project>/.claude/.tour.json, the state file bob tour owns. |
The next day, when the rotation moves on. A dismissed item is never shown again, and the next build shows another. |
Sources
Section titled “Sources”Every source reports a status next to the notices it produced. An empty
notices list with every source ok means nothing needs Paul. A source that
could not be read is never shown as an empty list.
status |
Meaning |
|---|---|
ok |
Read. count is how many notices it produced. truncated: true means a search returned a full page of 100, so there may be more. |
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. decision with partial: true read some issues and kept their notices. |
not-measured |
There is nothing to read. bridge-question is always this: pending bridge questions live in the remote-decision-bridge worker, which has no read endpoint yet, and .claude/.decisions.jsonl records only answered decisions (decision log). release is this when .bob-version is absent or has no version, or there is no stable tag. todo and decision are this when no project on this machine has a GitHub origin. did-you-know is this when the project’s session ledger holds no events: a cold ledger grades everything unknown, so run bob tour in the project once to backfill it from transcripts. A notices build never backfills. |
did-you-know is unavailable when bob tour fails, with its message as the
reason. When it is ok, the source also carries project and unknown, the
size of the rotation pool.
blocked also lists not_measured_machines: registry machines that published
no snapshot, so their runs were never looked at.
- gh goes through the shim. Every gh call runs on
PATH, where the gh shim records its outcome and cachessearch issuesandissue viewreads (the forge cache, #1749). When the forge is down, a recent cached read is served instead of a failure. - Two searches, then up to 20 views. A build costs two search API calls
plus one
gh issue viewper registered decision candidate. - Local reads only for the rest.
blockedcomes from the fleet feed,releasefromgit for-each-refand.bob-version, anddid-you-knowfrom onescripts/tour/tour.jsrun (the ledger, the registry and.claude/.tour.json, written by nothing but--triedand--park). None of them makes a 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 /notices.json. bob viz
renders it as the Notices column on /bob.
| Behaviour | Detail |
|---|---|
| Refresh | Rebuilt at most once every refresh_s seconds (DASH_NOTICES_REFRESH_S, default 60), however many tabs poll it. A request that arrives during a build waits for that build instead of starting another. |
| Page | /bob re-reads /notices.json every 10 s, or every refresh_s when that is shorter. A notice is gone from the page within one rebuild and one poll after its source clears. |
| gh | The forge reads use the server’s own gh runner, so they count toward its gh liveness tracker (#1968). An unreadable todo or decision source carries the server’s reason, which can also be server-cannot-run-gh or gh-failing. The document then gains the same gh evidence block as the /warp panes. |
| Render | scripts/dashboard/bob-notices.js, served as /bob/notices.js, is a pure function of the document. tests/test-notices.js snapshots its output (tests/fixtures/bob-viz/notices.html). |
| Failure | If the document cannot be built at all, the response has notices: [] and an error, and the column shows the error. |
| Did you know | Drawn from the server’s own project (the directory bob dash serve was started for). The column shows it below the list and leaves it out of the “need you” count, with its try-it command and its dismiss command. |
See also
Section titled “See also”- Fleet Feed: the
preflighta blocked run carries - bob viz: the page these notices are for
- Todo format contract: what a
todoissue holds tests/test-notices.js: each kind, clear-on-source-change, typed reasons