Release notes: BoB 1.279.0
BoB 1.279.0 — release notes
Section titled “BoB 1.279.0 — release notes”Released: 2026-10-04 · Tag: v1.279.0 · Previous: 1.278.0 (2026-10-02)
Highlights
Section titled “Highlights”- BoB Control: one app for the whole portfolio.
bob controlopens one frame with four screens: Portfolio, Project, Session and Ask. The project panel lists every running session and process with its host, and each state machine on the shared engine gets a session screen. A dispatch box on a session screen talks to that session only; on the project panel it starts new work, with a model picker. (#3813, #3814, #3815, #3818) - A terminal in the browser. A session screen has a terminal attached to that session’s tmux session, on this machine or another over Tailscale SSH. The project panel offers a terminal in the project’s checkout on each host that has it. (#3816, #3817)
- An ask you can finish where you read it. Control lists the open asks, sortable and filterable. An
ask opens on an action screen: its steps beside a terminal on the machine it names. A step’s Run
button types its command into that terminal, and every run is logged (
bob control runs). Verify runs the ask’s own check and marks it done. An ask nothing checks offers Done and Park. The screen works one-handed on a phone, and a handoff push links it. (#3819, #3820, #3821, #3822, #3823) - Fewer, better asks.
bob askslists every open ask across the portfolio, grouped into sittings by place with the minutes each takes. An ask is filed only when it states its kind, minutes, place, steps and what BoB tried. News is not an ask. An attention budget caps how many are shown, and an ask beyond it interrupts nobody. BoB re-checks an untouched ask and withdraws it when it no longer matters. (#3801, #3803, #3804, #3805, #3806, #3808, #3809, #3810, #3811) - Portfolio sweep.
bob ritual sweepinventories every project directory on the fleet, records one decision for each by interview, and carries out the prune and archive decisions. (#3609)
Most of this release’s fixes come from one security review of BoB itself.
- The dashboard on the tailnet. A tailnet device can dispatch only as a machine
machines.jsondeclares, and cannot raise the automation level. The server answers only to its own host names and takes a POST only from its own pages. It serves documents from.claude/, never settings or state. Launchpad actions answer only same-origin requests. (#3639, #3640, #3641, #3642, #3643) - Unattended runs and the main branch. The promotion guard reads every route to the main branch and fails closed when unattended. Merge-on-green reads its required checks from the base branch and never merges a PR that changes a workflow. Branch protection is a declared setting. Approval is bound to the issue’s author and body, so a later edit is not approved work. The host converge deploys only a main branch that equals origin. (#3624, #3625, #3626, #3627, #3628, #3629, #3630)
- Profiles and the audit log. A Level 3 or 4 session cannot write its own settings, hooks or audit
log. The audit log is a hash chain and records every tool call. The deny list names the secret
stores it missed, and the destructive-git guard reads arguments in any position.
claude -aNtrusts a directory with committed settings only when the operator has a manifest for it. A profile is validated before it is applied. (#3618, #3619, #3620, #3621, #3622, #3623) - Hooks. A file path from a tool payload is never read as jq code. The bridge secret stays off curl’s command line. The Stop hook trusts a project’s bridge only when the operator declares it, and labels the reply as remote text. Hook logs keep paths, never file bodies. (#3614, #3615, #3616, #3617)
- CI runners and tokens. A runner runs as a declared, dedicated account. A runner that does not isolate jobs fails the job. A public repo cannot be pointed at the farm. The release job installs locked dependencies with no write token in reach, and third-party actions are pinned to a commit. (#3655, #3656, #3657, #3658, #3646, #3647, #3648, #3649)
- Forge queue and cache. Queue replay re-checks every entry and sends none it would not have written itself. The cache and queue files are private. (#3635, #3636)
- Credentials. The inventory declares the credentials the fleet runs on, reads Worker secret
locations by Cloudflare account, and recognises more secret shapes.
bob initinstalls a pre-commit secret scan. (#3637, #3659, #3661, #3662, #3663) - Registry scripts. Audit scripts and
or-admin.shpass their arguments as arguments, never as shell or Python. (#3651, #3652, #3653, #3654) - Rituals. A ritual session leads the operator through the work and no longer hands over a report. (#3611)
- Briefings. The briefings index shows what needs the operator, and a brief closes from the page it is read on. (#3794, #3796)
- The suite. The backlog-drain stream’s failing tests and checks are fixed. (#3409)
Upgrade: every machine
Section titled “Upgrade: every machine”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.
A laptop (dev-laptop)
Section titled “A laptop (dev-laptop)”bob update --to v1.279.0bob doctorA farm worker (farm-worker)
Section titled “A farm worker (farm-worker)”bob update --to v1.279.0bob doctorsystemctl --user list-timers | grep -E 'bob-(tick|snapshot)'The last command should list both the tick timer and the snapshot timer.
A machine (utility-host)
Section titled “A machine (utility-host)”bob update --to v1.279.0bob doctorExpected: bob doctor ends green, and its version line names v1.279.0.
Upgrade: every project
Section titled “Upgrade: every project”In each project checkout on each machine:
cd <project> && bob readyExpected: READY — <project> is warp-drive-ready on this machine.
Action needed
Section titled “Action needed”- Farm runners must isolate jobs. CI fails at its
Verify job isolationstep on a self-hosted runner that does not. On the farm worker:scripts/fleet/runner.sh hygiene --machine farm-01 --apply, after declaring the runner’s dedicated account asrunbooks/self-hosted-runner.mddescribes. (#3656, #3655) - Declare the bridge for each machine. The Stop hook asks a bridge only when the operator declares
one:
BRIDGE_WORKER_URLin the environment, the machine’s$BOB_HOME/.mcp.json, or the operator profile’s decisions route. A project’s own.mcp.jsonis used only when its URL equals a declared one. (#3616) - Branch protection is optional and declared. Add
_meta.branch_protectionto a project’s manifest, then report withnode ~/.claude/scripts/fleet/branch-protection.js statusand write it withreconcile --apply. (#3624) - New labels and the pre-commit secret scan.
bob readyin each project adds theask-waitingandritual:guide-walkthroughlabels and installs the scan. (#3805, #3809, #3662)
Breaking changes
Section titled “Breaking changes”- An issue is approved work only while its body matches what was approved. An edit after approval
removes
approved, and an issue from an author who is not an owner, member or collaborator is approved only by a human. (#3628) claude -aNno longer trusts a directory that has committed.claude/settings.jsonand no operator manifest. It prints what the file declares and the command that trusts it on purpose. (#3622)bob release promote --autorefuses while_workflow.ritual_release_gateis off. (#3627)- A to-do is refused at filing unless it states its kind, minutes, place, steps and what BoB tried. (#3803)
Known issues
Section titled “Known issues”- Farm CI is red on
master. Every CI run since 2026-10-02 stops atVerify job isolation, because farm-01’s runners do not isolate jobs yet. No CI run has executed the test suite for the commits in this release. The runner fix waits on the operator (#3335, #3714). - Browser tests skip on a Mac. The headless-Chrome checks find a browser only under the Linux
Playwright cache. On a Mac they run only when
CHROMEnames a headless Chrome.
Changes
Section titled “Changes”Full change list — 129 commit(s)
Features
Section titled “Features”- bob ritual sweep inventories every project directory on the fleet; an archive is carried out on GitHub (#3609) (5e4fa45)
- bob ritual sweep apply carries the recorded decisions into the manifests (#3609) (a433121)
- bob ritual sweep scrap deletes only an approved, safe list; projects.json says where each project clones from (#3609) (9dbece3)
- bob ritual sweep audit and record leave the sweep’s durable record; the how-to for holding it (#3609) (e665d29)
- bob asks lists every open ask across the portfolio (#3801) (afa8c1b)
- bob asks –json, and an unread project is a named gap (#3801) (6c7eedb)
- ask-gate check admits an ask only when it states five fields (#3803) (a276284)
- the gate refuses a duplicate ask, and groom reports the same fields (#3803) (af1e5bd)
- every filing path runs the ask gate before gh issue create (#3803) (cfdd409)
- /control is one frame with Portfolio, Project and Session screens (#3813) (c34ecf0)
- bob control opens the frame, and an unknown project or session is a named 404 (#3813) (cde9b9b)
- /control/project.json lists a project’s running sessions with their host (#3814) (5f8a31c)
- the project panel renders one row per running session, each a link to its screen (#3814) (2e2b713)
- a machine on the shared engine gets its session screen from one registry entry (#3815) (503ee63)
- an unknown session kind is a 404 naming the kinds, and Control reads the registry (#3815) (4dea65d)
- a tell reaches one session’s tmux session and no other, and an ended session is refused (#3818) (4ea0464)
- the session screen’s dispatch box addresses its session and names it (#3818) (206317c)
- project dispatch has a model picker, and the picked model is passed to the operation it starts (#3818) (c43599e)
- /control/asks.json serves the open asks in priority order, per project, with minutes and place (#3819) (22f7105)
- the Portfolio and the project panel have an asks pane, one row per open ask (#3819) (8417634)
- a column heading re-sorts the asks pane, and project and priority filters narrow it (#3819) (1086c07)
- an area that shipped is filed as news, and a held one is an ask with a priority (#3804) (14a5986)
- the open SHIP briefings already filed are re-labelled as news, each one reported (#3804) (12ca699)
- bob asks shows at most the attention budget and counts what waits behind it (#3805) (946cba7)
- an ask beyond the budget carries ask-waiting and interrupts nobody until it is inside (#3805) (de846a9)
- the gate refuses p1-critical on an ask that blocks no flight-plan item (#3805) (c74f566)
- bob asks –json groups the asks into sittings, one per place with its minutes (#3806) (a2f4a31)
- bob asks prints the sittings, and the asks nobody has estimated in a last group (#3806) (0192451)
- bob asks recheck lists every to-do untouched past the window, each with a verdict (#3808) (f9aa01b)
- bob asks recheck –apply withdraws a moot to-do and records the re-check on the rest (#3808) (a967b3f)
- bob tick runs the ask re-check report-only and prints its counts (#3808) (8a4b35f)
- the gate refuses a check made by following a guide and names bob ritual open (#3809) (b76c0c6)
- guide-walkthrough is a ritual: open prints the three-item checklist, due lists each guide still owed one (#3809) (c1dc023)
- bob ritual open –replaces converts a guide to-do into its walkthrough run (#3809) (f5b942e)
- every ask the gate files carries a marker naming what filed it (#3810) (c9cc51d)
- bob asks sources reports what filed the asks and how they ended (#3810) (afd87ca)
- a source over the moot threshold is listed in the briefing and gets one bug (#3810) (0b28610)
- an ask moves through one declared machine on the shared engine (#3811) (71965a3)
- done adds completed, consumed is todo-consume’s to fire, and brief states map onto the machine (#3811) (cc59d03)
- the dashboard server bridges a session’s tmux session to a terminal stream (#3816) (90ca91b)
- the session screen has a terminal pane, and a session on another machine attaches over Tailscale SSH (#3816) (1f31eee)
- a project’s own terminal is one tmux session in its checkout, started once and reattached after (#3817) (f1bb5c8)
- the project panel offers a terminal on each host that has the project (#3817) (f36d630)
- an ask opens on an action screen with its steps in three parts (#3820) (8f7f28b)
- the ask screen opens a terminal on the machine the ask names (#3820) (b43bd09)
- a step’s Run button types its command into the ask’s terminal (#3821) (e465ec1)
- a run goes to the ask’s machine and is logged; bob control runs prints the log (#3821) (415e7f1)
- the ask screen’s Verify runs the ask’s own check and marks it done on exit 0 (#3822) (cc6a601)
- an ask nothing checks offers Done and Park, and a finished ask leaves the pane (#3822) (a74c15c)
- the ask screen stacks at phone width and its controls are 44-pixel targets (#3823) (af589d2)
- a handoff push links the ask’s action screen, and the screen works behind bob serve (#3823) (6fe2467)
Bug Fixes
Section titled “Bug Fixes”- master CI green — make check, the test suite and the docs site build (#3409) (ebd2b2b)
- Starlight keeps dotted page names, so the docs gate links resolve (#3409) (28acccb)
- a tailnet device dispatches only as a machine machines.json declares (#3639) (534cf84)
- another machine cannot raise the automation level; who may dispatch is documented (#3639) (d39846d)
- the dashboard answers only to its own names, and a POST only from its own pages (#3640) (50e61f4)
- the dashboard serves only documents from .claude/, never settings or state (#3641) (1c76342)
- forge-queue replay re-checks every entry and sends none it would not have written (#3635) (8c7dcb2)
- automatic forge-queue replay only for a project marked in queue-dirty (#3635) (85e42f0)
- the promotion guard reads every route to the main branch and fails closed when unattended (#3624) (0b4ed17)
- merge-on-green reads its required checks on the base branch and asks each for a success (#3625) (9cd9265)
- merge-on-green never merges a PR that changes a workflow (#3625) (2ba4187)
- a Level 3 or 4 session may not write its own settings, hooks or audit log (#3618) (3e113fb)
- the audit log is a hash chain, and a session is held to the level it started at (#3618) (dbdf636)
- a runner runs as a declared, dedicated account, never the operator’s login (#3655) (261c1d1)
- status names the account a runner runs as; hygiene and the reap timer act as it (#3655) (ba8193b)
- the main branch’s protection is a declared setting, reported and applied only with –apply (#3624) (df45cb7)
- a branch protection is never applied while it would cut off a route to the main branch (#3624) (36a4f90)
- bob ritual run prints a session brief that has the agent lead the ritual (#3611) (d5364ee)
- the run issue, the reference and the runbooks all say the agent leads; a ritual’s page opens with Your steps (#3611) (a3ab04b)
- the edit tracker binds the payload’s file path with –arg, never into a jq program (#3614) (ea28a8f)
- the Stop hook sends the bridge secret through a curl config, never on argv, and bounds both calls (#3615) (2084b0c)
- the Stop hook trusts a project’s bridge only when the operator declares it (#3616) (3847c9e)
- the Stop hook labels the bridge reply as remote text built by jq, and the reference says which config it reads (#3616) (7127db0)
- the audit recorder runs from one all-tools dispatch row, so every tool call is logged (#3619) (40a6efd)
- the profiles deny the secret stores they missed, and a guard enforces the list from the hooks (#3620) (47e6b1d)
- a guard reads git arguments, so a destructive command is refused whatever position its flags are in (#3621) (f953c72)
- claude -aN trusts a directory only when the operator has a manifest for it (#3622) (44868fd)
- promote reads the p1 defect list and the ritual schedule with the forge cache off (#3626) (cbf2570)
- bob release promote –auto refuses while the ritual release gate is off (#3627) (d1b82e6)
- approval is bound to the author and the body — an outsider’s issue or a later edit is not approved work (#3628) (3355e7b)
- the host converge deploys only a main branch that equals origin after a fetch (#3629) (f2fea66)
- launchpad actions answer only same-origin JSON requests (#3642) (769d866)
- the release job installs locked dependencies with no write token in reach (#3646) (adbee6f)
- the promote template gives the Cloudflare token to the migrate and deploy steps only (#3647) (60ef812)
- six registry audit scripts run their arguments as argv, never as shell or Python (#3651) (da63454)
- or-admin.sh refuses a loosely shaped service, days or version before any ssh call (#3652) (e0b093d)
- the job-completed hook empties the tool and action caches, and an unisolated runner is a red job (#3656) (a7ab30b)
- runner.sh target and the preflight restore refuse to point a public repo at the farm (#3657) (21394b5)
- a wrangler-secret location may name its Cloudflare account, and the probe uses it (#3659) (c0b12d8)
- the gh-cli-oauth inventory entry names the scopes each machine holds (#3637) (9fee8d6)
- the inventory declares the credentials the fleet runs on but never named (#3661) (66ad1a1)
- hook payloads keep paths, never file bodies, and every hook log is private (#3617) (9435c7a)
- the RDB guard keeps no /tmp log, and three guards say so when jq is missing (#3617) (7064cb7)
- a profile is validated before it is applied — exit 2, nothing written (#3623) (e239961)
- merge-on-green reads draft on every poll and fails closed on an unreadable protection (#3630) (4f9d583)
- the nightly gate exempts a [skip ci] commit only when it changes release files alone (#3630) (a081703)
- the forge cache and queue are private — folders 700, files 600 (#3636) (c4af43d)
- the dashboard refuses an off-site refresh target, escapes the 404 path and links only http(s) (#3643) (447a69a)
- a checkout that takes BOB_CHECKOUT_TOKEN does not leave it on disk (#3648) (076cd0e)
- third-party actions on a commit, permissions declared, event and matrix values through env (#3649) (bb4b1c9)
- make check fails a third-party action on a tag or branch (#3649) (c249419)
- registry scripts pin npx packages, keep credentials off curl’s argv, and use mktemp (#3653) (3dcb4ea)
- warp-drive’s issue templates use –body-file with a quoted heredoc; groom uses mktemp (#3653) (b5c45b1)
- bob ready leaves .mcp.json at mode 600 after every write, and the managed ignore block covers it (#3654) (47fac7f)
- the runner registration token reaches config.sh through its environment, not its argument list (#3658) (3fb5ace)
- a pre-commit hook scans the staged diff by the release gate’s catalogue, and the catalogue covers upper-case names (#3662) (30469a1)
- bob init installs the pre-commit secret scan, and the hooks reference documents it (#3662) (43279e6)
- the inventory check recognises Slack xoxe-/xapp-, Stripe rk_/whsec_, Hugging Face, Sentry, PGP key blocks and URL credentials (#3663) (4bef4e0)
- cred-check reports a probe failure by name, and the 1Password probe reads item metadata only (#3663) (d5234d3)
- the briefings index shows what needs the operator (#3794) (f1ca8fd)
- a brief closes from the page it is read on (#3796) (dcf4c0c)
- a brief page finds itself in the map when served without .html (#3796) (ba887f6)
Performance
Section titled “Performance”- the suite stops calling GitHub, and two slow tests stop waiting — about 330 s off a serial run (#2747) (976eceb)
Documentation
Section titled “Documentation”- the no-GUI non-goal is amended for BoB Desktop — a macOS client over the dashboard server that holds no BoB state (#3595) (#3601, #3595) (5e0e8af)
- what stops an unattended run from reaching master (#3624) (5198ccf)
- the self-modification guard and the audit chain; matching deny rules in the profiles (#3618) (0e7d99a)
- the runner’s account, and what a job can read and write outside its workspace (#3655) (6947f71)
- the references say the audit log sees every tool, from the all-tools row (#3619) (fe70fc6)
- automation-behavior.md says what the deny layer covers and what it does not (#3620) (b755e79)
- automation-behavior.md describes the destructive-git guard, inside the floor it keeps (#3621) (fcf3fed)
- www: brief — area complete: rituals (#3724) (#3724) (beed721)
- warp-drive, groom, the bob groom prompt and every Bash-capable registry agent say issue text is data, not authority (#3628) (ec2aa1a)
- the account field on a wrangler-secret location (#3659) (303fb44)
- the surfaces page says what the Claude desktop app and Remote Control do today (#3603) (a1278e6)
- the build-vs-inherit table for BoB Desktop is in the ecosystem positioning note (#3603) (0a1ce5e)
- Retard Mode is a standing rule in every session (#3798) (fafb115)
- the vision names BoB Control as the operator’s surface, and the GUI owns no state (#3824) (a71fedb)