Skip to content

Release notes: BoB 1.281.0

Released: 2026-10-11 · Tag: v1.281.0 · Previous: 1.280.0 (2026-10-05)

  • Master can be protected. A stable release, a promotion and an attended Level 3 run now land through a pull request, and one CI check (ci-passed) reports on every pull request, so master can require it. A permission profile that changed reaches projects already at that level the next time bob ready runs. (#3719, #3718, #3717, #3702, #3696)
  • BoB learns from its own runs. A wiki/ of failure patterns built from loop notes, decisions and harness defects (bob wiki maintain), eval suites that accept a skill change only when it scores strictly better (bob eval run, bob eval gate), and a proposer that opens one skill change at a time as a pull request for you to merge (bob wiki propose). (#2388, #2389, #2390, #2391)
  • The product names no client. Client material, the project registry (projects.json) and the brief pages now live in your operator repo, and the docs, tests and scripts use neutral example names. (#3430, #3431, #3432, #4263)
  • Your to-dos close themselves. A to-do can carry a check the machine runs; when it passes, the to-do closes before you ever see it. bob asks done and bob asks snooze answer one from a shell. (#3986, #3807)
  • Model roles with failover. Agents name a role (default, reasoning, fast, cheap) instead of a model, and bob route run moves a headless command to the next model when one hits a usage limit or an outage (bob route roles, bob route failovers). (#1231)
  • Safer Cloudflare and deploys. A command that would delete a Cloudflare database, bucket, prod Worker, zone or DNS record waits for you (on Telegram when RDB is on), and bob deploy takes a D1 backup before it migrates. (#3588, #3087)
  • Seeing the fleet. bob viz has an Activity pane (projects by last commit, with a 30-day sparkline), bob warp reap finds stale Claude Code sessions in any tmux session, and bob fork windows show each run’s state. The GitHub Projects integration (cdproj / bob project) is retired. (#2154, #3302, #3549, #1752)
  • Token cost figures were 1.5–2× too high: each API response was counted once per content block. Past ledger records are marked and recounted, and the 5.5 models are priced. (#4204)
  • Master CI is green on the farm runner again, and bob release is no longer refused over a client name in a test. (#4115, #4131)
  • The retired session-summary-reminder hook is gone, and bob init no longer adds a duplicate Stop hook on every run, which was blocking branch switches. (#4124, #4117, #4129)
  • Warp-drive: an item with no agent-side work can leave coding without aborting the run; bob warp stop --hard really removes the state file; a squash finalize commits the squash; the redeploy hand-off never asks you to /exit; the commit and docs detectors no longer report a false hook miss. (#3476, #4080, #4012, #3163, #4119, #4120)
  • tmux suites and the dashboard work on macOS: short socket paths, and every tmux listing runs in UTF-8. (#4091, #4082, #3973, #4086, #4019)
  • Provisioning keeps a declined item declined, and a worktree’s project is named by its project, not its folder. (#3468, #4069)
  • Promotion ladder: a test deploy no longer claims the production routes and crons, promote.yml authenticates GitHub Packages installs, and bob dev up reads the seed D1 name correctly from wrangler.jsonc. (#4192, #4193, #4123)
  • Smaller fixes: the preflight to-do names the fleet id; the terminal hand-off leaves out ask-waiting records; check-retired-items reads only the checked-out branch; the doc-keeper auditor runs report-only. (#4126, #4202, #4280, #4001)

Close every Claude Code window on the machine first. A deploy refuses while a session is live (it would switch off the hooks in running sessions); a refused deploy is queued and runs when the last session ends.

Terminal window
bob update --to v1.281.0
bob doctor
Terminal window
bob update --to v1.281.0
bob doctor
systemctl --user list-timers | grep -E 'bob-(tick|snapshot)'

The last command should list both the tick timer and the snapshot timer.

Terminal window
bob update --to v1.281.0
bob doctor

Expected: bob doctor ends green, and its version line names v1.281.0.

In each project checkout on each machine:

Terminal window
cd <project> && bob ready

Expected: READY — <project> is warp-drive-ready on this machine.

On every machine, after bob update, put the operator repo on its up-to-date default branch. projects.json now lives there, and make repair-fleet / bob ready stop with projects.json not found until it does. (#3432)

Terminal window
cd ~/projects/bob-operator && git checkout master && git pull
ls projects.json

Expected: projects.json is printed. If your operator repo has no projects.json yet, generate it with node ~/projects/bigbrain/scripts/fleet/projects-derive.js --write and commit it there.

If a project manifest in your operator repo still has a gh_project key, delete the key: the GitHub Projects integration is retired, and check-operator now rejects it (#1752).

None.

  • bob serve’s always-on HTTPS address for each machine needs tailnet HTTPS certificates turned on first; until then the dashboards stay on their loopback ports. (#2407, to-do #4286)
  • The strip-ai-boilerplate hook script is still on disk, unwired, until every machine’s project settings are clean. (#2718)
Full change list — 126 commit(s)
  • retire the GitHub Projects v2 integration (cdproj / bob project) (#1752) (26104e1)
  • bob provision decline records a durable decline (#3468) (6c7a326)
  • a Level 3 run on a branch protected for admins merges through a PR (#3718) (2bceffa)
  • the merging phase and /finish-work land a protected branch through merge-on-green (#3718) (a95efe9)
  • work_skipped leaves chunking and coding until the item has a commit (#3476) (94ecc50)
  • ci.yml always reports, and its ci-passed job is the one check master can require (#3717) (385affe)
  • the route report reaches master under ci-passed; the manifest and docs name it (#3717) (8a280f8)
  • bob ready re-applies a permission profile that changed since the level was set (#3702) (c1f9d76)
  • bob ready tells an unattended project its default branch names no required check (#3696) (c57c7a0)
  • deploy.sh takes a D1 backup before migrating (#3087) (8309eef)
  • the promote workflow and the restore runbook carry the pre-migrate backup (#3087) (291bf3b)
  • the client-farm explanation and the tooling/data decision (#2277) (d04cdf4)
  • the client-farm cloud-provider layer and client-supplied inputs (#2277) (2df2884)
  • bob update and bob tick refuse a live session only when the target rewrites hooks (AC-05) (#2746) (70a5bb9)
  • retire the orphaned until:#2270 allow-list entries; a closed until fails the lint (#3405, #2270) (c687c41)
  • the brief-tick Worker serves a declared repo list and answers Done and Snooze on to-dos (AC-01, AC-02) (#3807) (cbb59e7)
  • bob asks done and snooze answer one ask from a shell; a snoozed ask leaves the list until its date (AC-03, AC-04) (#3807) (9c40967)
  • a to-do declares a machine-runnable Done-check the gate accepts; a pass closes it, a new failure reason goes into its body (#3986) (c91d410)
  • bob asks, Control and the briefing run a to-do’s done-check before listing it; bob tick runs every one (#3986) (6e32c99)
  • the standard label set declares risk-status:* and phase-0..3 (#1054) (cc06f13)
  • wiki pages have a schema, and make check-wiki lints them with the release gate’s client-data rules (#2388) (d080a78)
  • wiki/ lands with a derived index and fixed-format logs and skill-impact tables (#2388) (6cfb860)
  • wiki pages retire when their defect closes, stale pages are reported, and nothing a session loads may name wiki/ (#2388) (13b9586)
  • the stale todo sweep reads its links 40 per call and comments only where the verdict turns on them (#3219) (d1c49f2)
  • the dashboard notices build reuses decision comments while the issue’s updatedAt holds (#3219) (b54aa6d)
  • a filed advisory is a task — task label, a Trigger: line and a Verification checklist the task loop judges (#3406) (0b66594)
  • advisories.js relabel brings open pre-task advisory issues up to the task shape once, and the advisories reference describes it (#3406) (1cd2ce4)
  • eloqua-dev names no tenant — the client’s as-built notes move to the operator repo (#3430) (3f924dd)
  • projects.json is operator data — the deriver writes it into the operator repo and bob ready reads it there (#3432) (1b7464c)
  • every JS reader finds projects.json through the operator resolver (#3432) (1364ef1)
  • the shell readers resolve projects.json through bob_operator_path, and the lint keeps a direct path out (#3432) (a3dbd65)
  • projects.json leaves the product repo — untracked here, retired from BOB_HOME, its release allow-list entries gone (#3432) (53e16df)
  • a stable release and a promotion land through a pull request on a branch protected for admins (#3719) (406b838)
  • branch-protection grades the release as a pull-request route, the workflow passes a release token, and the docs describe the path (#3719) (6667da5)
  • the wiki maintainer collects a scrubbed, bounded trace packet from six stores (#2389) (19ab579)
  • the maintainer turns the packet into patch edits on a branch of BOB_SOURCE and opens one PR (#2389) (b21378a)
  • /trace-mining and bob tick run the wiki maintainer as bob wiki maintain, and the docs describe the run (#2389) (282ef94)
  • run.js wraps claude plugin eval with a with/without ablation and prints a schema-valid skill-eval/1 result that bob u exam reads (#2390) (3cd4728)
  • gate.js accepts a skill change only on a strict improvement over the recorded best per model and records the outcome (#2390) (7a75415)
  • eval suites for commit and tdd-flow, each with a fire and a stay-quiet trigger case, and an opt-in make test-evals (#2390) (6acb026)
  • skill proposer agent and propose.js — one change to one item, gated, opened as a skill-proposal PR (#2391) (1536fe2)
  • bob wiki propose route, /trace-mining’s last step, and bob tick runs the proposer on bigbrain only (#2391) (3ec9c74)
  • scripts and tests name no client — the group rule and cdb’s fallback list drop the tenant (#3431) (19d28d2)
  • no dev environment is n-a from both dev-up entrypoints (#853) (1d006ef)
  • hold a destructive Cloudflare command for the operator (#3588) (102876a)
  • answer a held Cloudflare delete on Telegram when RDB is on (#3588) (1b810b1)
  • bob warp reap lists and grades Claude Code in every tmux session (#3302) (b5549de)
  • bob warp reap –force stops stale Claude panes; –idle-shells kills idle shells (#3302) (ae86cc3)
  • bob fork windows show each run’s warp state and raise a terminal notification when it waits (#3549) (ae5a7bb)
  • bob ibob check and attach grade the declared iPhone terminal kit (#2291) (3fce6b2)
  • declare the iPhone and iPad keys and probe this machine locally (#2291) (657b298)
  • bob decompose and bob do append a priced session record to the token ledger (#4101) (92ecd6f)
  • bob groom and interactive sessions write their session record to the token ledger (#4101) (2b0603a)
  • sweep scrap archives each path to a declared drive and verifies it before deleting (#3706) (62ba00d)
  • the fleet snapshot carries per-project commit activity (#2154) (813db5f)
  • bob viz Activity pane lists projects by last commit with a 30-day sparkline (#2154) (655ead6)
  • gh-inventory.js reads every gh call from the tree, executable and prompt-text apart (#1753) (343bdd0)
  • the gh adapter contract and its make check gate (#1753) (bf7bd98)
  • brief pages are generated in the operator repo (#4263) (8762b53)
  • a dashboard unit per serve-routed project (#2407) (517b403)
  • bob serve keeps every routed project’s dashboard always on; bob doctor reports it (#2407) (4e24bdc)
  • a routing file maps model roles to an ordered list of route + model (#1231) (cd631fe)
  • failover.js run restarts a headless command on the next candidate when the model fails (#1231) (83314af)
  • bob route roles|run|failovers, bob groom –role, and agents name a role, not a model (#1231) (7f05229)
  • bob init never adds a template hook the project already runs (#4118) (#4117, #4118) (0e04e54)
  • retire the session-summary-reminder Stop hook (#4125) (#4124, #4125) (959f1c0)
  • the three static guards pass again (#4115) (e5e5d2c)
  • test-route runs on a machine without zsh; two page assertions follow #4034 (#4115, #4034) (edbafa6)
  • the bridge and terminal suites pass on farm-01 (#4115, #4104) (29129cd)
  • suites pass on a runner with no ~/.claude, operator or git identity (#4115) (e76f958)
  • the cdi settings-merge test names no client project (#4131) (cda6a90)
  • settings-hooks-reconcile run from ~/.claude no longer compares settings.json with itself (#4129) (32d03e3)
  • bob provision refuses the retired gh-project action by name (#1752) (f717bcd)
  • bob warp stop –hard removes the state file whatever its contents (#4080) (1d70b07)
  • a squash finalize commits the squash before pushing (#4012) (911b646)
  • secondary callers name a worktree’s project, not its folder (#4069) (4b218d3)
  • a declined item in the manifest stays declined (#3468) (810aed4)
  • the doc-keeper auditor names each finding and its fix, and runs report-only (#4001) (bd8153e)
  • commands/warp-drive.md names the work_skipped exit in its coding section (#3476) (4d7a8ff)
  • preflight todo names the fleet id, and a refused todo is shown (#4126) (2460134)
  • a committed fired inside the commit call is too early, not a hook miss (#4119) (8cd6760)
  • a docs_updated fired inside the tick’s call is too early, not a hook miss (#4120) (639178a)
  • give run-tests.sh a short tmux socket dir (#4091) (984afd6)
  • test-dispatch-endpoint uses a short tmux socket dir (#4082) (33e48a3)
  • every dashboard tmux listing runs tmux -u through one helper (#4086) (bd391f0)
  • test-bob-chat-page uses a short tmux socket dir (#3973) (9333fd0)
  • host-drift resolves the channel hermetically; brace $ev in the degraded-loop test (#4019) (b4ee85f)
  • dev-up reads the seed D1 name with the JSONC reader, not sed (#4123) (a39d79a)
  • env.test claims no production routes or crons (#4192) (ccaed42)
  • promote.yml authenticates installs from GitHub Packages (#4193) (95cc21a)
  • token snapshot counts each API response once (#4204) (7829878)
  • mark over-counted ledger records, recount them, price 5.5 models (#4204) (01db925)
  • the redeploy hand-off never asks the operator to /exit (#3163) (d46c73a)
  • check-retired-items reads the checked-out line, not every branch (#4281) (#4280, #4281) (21f8894)
  • rename make test-evals to make evals (#2390) (26651bf)
  • terminal handoff leaves out ask-waiting records, as the banners do (#4203) (#4202, #4203) (a563f66)
  • the gh-projects retirement record tells operators to drop gh_project (#1752) (a86742e)
  • the first seven-day refusal and CI baseline (AC-04) (#2745) (051a845)
  • risk status and rollout phase are documented standard labels, with the thefarm mapping (#1054) (0e38837)
  • the wiki store reference, and wiki/ in the CLAUDE.md architecture tree (#2388) (0daf6d1)
  • bob eval run and bob eval gate routes, the skill evals reference, and the BobU how-to runs them (#2390) (557903e)
  • skill-proposal label on BOB_SOURCE, tracker-labels entry, SkillClaw pass recorded, gate gap linked (#2391) (96b452a)
  • docs, commands, registry and runbooks name no client — neutral example-co names replace the tenant literals (#3431) (d5568f5)
  • bob warp reap help, CLI reference and how-to cover the Claude survey (#3302) (4864951)
  • the cdfork how-to covers window labels, the attention notification and bob fork watch (#3549) (d74700b)
  • the sweep how-to and reference cover the archive drive (#3706) (ea62987)
  • Worker-with-assets walkthrough for the promotion ladder, proven on nanaawards (#3069) (2f5f6c6)
  • the GraphQL batched reads stay GraphQL, listed as known-unsupported; a new caller fails the gate (#1753) (aa7523f)
  • regenerate the reference index for the gh adapter contract page (#1753) (40610a6)
  • the lastseen #63 shape end to end; a pending CI re-run is always probed again (#3986, #63) (bec8dee)
  • test-wiki fixtures name a neutral owner, not the operator (#2389) (03b3009)
  • test-wiki fixtures name a neutral owner, not the operator (#2389) (78ce14d)
  • fleet-audit derives its sandbox projects.json and points at the checkout (#3432) (43ad643)
  • the release fixture’s gh shim closes a PR with perl, portable to macOS (#3719) (d9372e5)
  • four suites that failed only on the isolated CI runner pass there (#4115) (bf54a63)
  • the last three CI-only failures — brief, release-protected, asks done-check (#4115) (45017ce)
  • recorded Jev answers for the tracer labelled set (#3765) (#2738, #3765) (d204ca6)
  • a red pull request run reports at once instead of waiting for the docs build (#4115) (650be61)