2026.08.05-rc
Pre-releaseThis release turns a self-hosted hivemind into a server for the upcoming desktop companion app — device pairing, a full chat API with token-authenticated streaming, per-user notifications, and a guided Remote Access wizard for getting a public tunnel URL — alongside major delegation guardrails, LLM failover chains, and an in-app skill marketplace.
Features
Desktop companion support
- Desktop pairing: authorize page, code exchange, revoke-self (#427) — Browser-approval pairing for desktop clients: the app opens a Devise-protected authorize page showing an editable device name, approval mints a one-time five-minute exchange code (never the raw token) delivered to a 127.0.0.1 loopback callback, and a PKCE-style code exchange redeems it for a device-named
ApiToken. Codes are single-use with an atomic replay guard, paired devices appear on the existing API tokens page, and a bearer-authenticated revoke-self endpoint backs the app's sign-out. - Desktop chat API: session endpoints + bearer cable auth (#428) —
api/v1/sessionsgainscreate, full-transcriptshowwith aprocessingflag (the client's single hydration call), multipartmessages(routed throughSessions::ResolvePendingQuestionso ask_user replies work unchanged),interrupt(cancel/redirect/inject with sub-agent propagation), and rename withtitle_updatebroadcast. ActionCable now acceptsAuthorization: Beareron the WebSocket handshake alongside the existing cookie auth. Shared session logic was extracted into aSessionChatActionsconcern used by the web, mobile, and API controllers — and this fixes a pre-existing bug where bearer-onlyapi/v1requests without a session cookie were rejected by Devise before token auth ran. - Per-user NotificationChannel + needs_input/errors categories (#426) — A new
NotificationChannelstreamsnotifications_user_#{id}; everyWebPush::NotificationTriggersnotification now broadcasts there alongside web push with a{category, title, body, session_id, agent_id, tag, timestamp}payload. Two new categories with settings toggles:needs_input(agent asked a question) anderrors(session failed). - Remote Access: tunnel wizard, Cloudflare provisioning, cloudflared sidecar (#429) — An admin/owner-only Remote Access settings page for getting a public URL: bring-your-own-tunnel verification (HTTP health check plus a real
/cableWebSocket handshake before setting the canonical host), or fully guided Cloudflare setup that creates the tunnel, ingress, and DNS CNAME via the API and runscloudflaredas a compose sidecar behind atunnelprofile controlled through docker-proxy. A recurring health check feeds an always-on status card with re-verify/restart/reconfigure/disconnect, secrets live in the encrypted vault store, andinstall.shnow asks about remote access and prints the wizard URL.
Delegation and orchestration
- Spawn-time delegation guardrails behind
Delegations::Request(#433) — All delegation guardrails consolidated into one service enforced before any LLM spend: a real depth limit (thedelegatetool is stripped from a child's schema at max depth, replacing the old post-hoc callback suppression), a fan-out cap per parent session, duplicate-pending rejection, and team scoping. Limits configured via thedelegationSetting key and clamped to hard ceilings so a bad setting can never disable runaway protection. - Shared orchestration budget across delegation trees (#434) — Per-agent budgets couldn't bound a fan-out's total cost. Each delegation tree now carries an
orchestration_id,Delegations::OrchestrationBudgetsums usage across the whole tree, and both choke points enforce it: over-budget trees can't spawn new delegations and their sessions are blocked from further LLM calls. Default $5 per tree, configurable and clamped to $100. - Remove dead TeamMessage delegation path (#430) — Deletes
Agents::Orchestrate/Delegate/Communicate/HandoffandAgentTaskJob, none of which had live callers —AgentTaskJobwas a stub that marked delegated tasks completed without executing anything. Real delegation viaSubAgentTask/SubAgentJobis untouched; the orphanedteam_messagestable is dropped reversibly.
LLM reliability
- Model/provider failover chains for LLM calls (#423) — When an LLM call fails with an unavailability-class error (auth, 429, 5xx, timeout, connection), it falls back through an ordered chain configured in
agent.model_config["fallback_models"]— same-provider model strings or explicit{provider, model}entries. Implemented as aProviders::FailoverAdapterat the single resolver choke point, so chat, ToolLoop, and background jobs all get failover with no call-site changes. Content/validation errors and prompt-too-long still propagate untouched; every failover is logged, audit-logged, and tagged in usage.
Skills
- In-app skill marketplace (browse & install from ClawHub) (#424) — Browse and search ClawHub's ~13k public skills from the Skills page and install with one click. Every install runs through the same
SkillSecurityScannerpipeline as manual file import — flagged skills park in the existing review flow. Registry outages degrade to a friendly alert.
Integrations
- Remove Nango and Composio integrations (#425) — Pipedream now covers third-party app integrations, making both aggregators redundant. Removes their executors, routes, and UI sections, with a data migration cleaning up seeded tool rows and vault credentials.
Fixes
-
Production boot crash from redundant
authenticate_user!skip (#436) — A cross-PR interaction between the pairing and chat-API changes leftApi::V1::DesktopPairingControllerskipping a Devise callback its parent had already removed, which raised at eager load and crashed the server at boot in production. Fixed, with a new eager-load spec so this class of error fails CI instead of taking down a deploy. -
Desktop pairing approve never reached the loopback callback (#437) —
form_withdefaults to Turbo, which followed the 302 to the app'shttp://127.0.0.1callback with fetch — blocked by the browser, so the exchange code never arrived. Both pairing forms now opt out of Turbo so the redirect is a plain top-level navigation. -
Stale version string in the sidebar (#439) — The image bakes its version as an env var at build time, but the compose deploy passes the operator's
.envinto containers viaenv_file, so a staleHIVEMIND_VERSIONpin there overrode it and the sidebar misreported what was running. The version is now baked into a file inside the image, which always wins; env var and git-describe remain as dev fallbacks. -
Removed the Beta pill from the Team Chat nav item (#435)
-
Memory extraction stored the agent's name as the user's (#438) — Greeting an agent by name ("hey marty") was extracted as "the user's name is Marty": the extraction prompts never told the model who the agent was, so vocatives aimed at the agent accumulated as high-importance facts about the user's identity — until agents started greeting the user by their own name. Both extraction prompts now name the agent, treat vocatives as addressing the agent, and only record the user's name when stated about themselves. Verified against the live LLM in both directions.
Full Changelog: 2026.07.01...2026.08.05-rc