⚠️ Do not deploy this release
The
breeze/web:0.98.0container image is missing. The web image build failed
after the rest of the release had already published, so pulling this version brings up
a v0.98.0 API against your previous web image. The API, portal and binaries-init images
and all 40 binary artifacts (agent, helper, viewer, installers, signed manifest) are
complete and valid — only the web container is absent.Use v0.97.2, or wait for
v0.98.1, which carries this same changelog plus the build fix. Tracking: #2661.
Breeze RMM v0.98.0 — a runtime extension platform, durable approvals, and a rebuilt quote builder.
Summary
- Runtime extension platform — Breeze can now load signed, versioned extensions at runtime: artifacts and operations, web pages with navigation and named slots, a testkit, and a v1 SDK staging contract (#2617, #2633, #2648, #2650).
- Durable action intents & Tier-3 approvals — approval decisions are now durable intents with an outbox, so they survive an API restart instead of being lost mid-flight (#2625, #2628).
- Quote builder overhaul — a document-styled editor, a 30-second undo-send window, and quote duplication (#2623).
- Agent reliability — credential-rotation ordering, PAM deny-gate correctness, and full script stdout/stderr/exit codes (#2647, #2644, #2629).
Added
- Runtime extension artifact & operations (#2617) — the packaging, staging and operations layer for runtime extensions.
- Runtime web pages, navigation & named slots (#2633) — extensions can contribute pages, nav entries and slot content to the web app, served from the extension registry.
- Extension testkit (#2648) — a conformance harness for extension authors.
- Signed bundles staged through the v1 SDK contract (#2650) — extension bundles are staged and validated against the v1 manifest.
- Durable action-intents & Tier-3 approval layer (#2625) — approvals modelled as durable intents with an outbox and immutability trigger.
- Durable approval follow-ups + headless executors (#2628) — Phase 2 Google and Phase 3 M365 headless executors for approved actions.
- Quote builder overhaul (#2623) — document-styled editor, 30-second undo-send window, and quote duplication.
- Helper shell refresh (#2636) — a single header over one main region, chat as a 340px side panel on wide windows, and window size/position that persist across relaunches.
- Client-declared session tools (#2637) — chat sessions may declare client-side tools (validated, capped at 8); calls bridge over SSE and results persist so sessions reload faithfully. Sessions that declare no client tools are byte-identical to before.
- Optional customer M365 Graph-actions (write) executor — gated behind
M365_GRAPH_ACTIONS_TOOLS_ENABLED, disabled by default, and deliberately not deployed by the generic Compose stack.
Improved
- Job scheduling (#2640) — the scan-orgs job now enqueues outside a held DB context, and #1105 tripwire captures are deduplicated.
Fixed
- Agent credential rotation (#2647, #2621) — the agent persists rotated credentials before the server commits the rotation, closing a window where a badly-timed restart could strand a device.
- Script results (#2629, #2474) — stdout, stderr and exit code are carried through the WebSocket command result instead of being dropped.
- PAM deny gate (#2644, #2610) — the deny gate now releases only on proven dismissal, with bounded recovery.
- Linux viewer (#2645, #2614) — the AppImage registers the
breeze://scheme, so viewer links actually connect. - AI tools (#2646, #2603) — repaired the
get_cis_compliancequery. - Migrations (#2627, #2622) — healed the v0.97.0 migration checksums for the eight files edited in place.
Security
- Extension route namespaces reserved (#2641, #2634, #2635) — seven hijackable route namespaces are now reserved and
CORE_NAMESPACESis auto-derived, so an extension cannot shadow a core/api/v1mount. - AI tool errors sanitized before streaming (#2646) — tool errors are scrubbed before they reach the client stream.
- Approvals permission cleanup — a migration revokes
approvals:decidefrom any non-system organization role named "Org Admin". An earlier revision of the seed granted this to custom roles as well as the built-in one; that revision never shipped in a release, so on an up-to-date deployment this is defensive and will report zero rows. It logs its row count either way. - Non-superuser migration guard in CI (#2626) — migrations are now exercised as an unprivileged role, catching the class of failure that only appears against managed Postgres.
Self-hosters are encouraged to upgrade.
Self-Hosting / Upgrade Notes
Upgrade. Bump BREEZE_VERSION to 0.98.0, then:
docker compose pull api web && docker compose up -d(If you build from source, run pnpm install first.)
Database — 8 migrations, applied automatically. They auto-apply on API boot via autoMigrate (unless you set AUTO_MIGRATE=false) and are idempotent. No large-table rewrites or backfills: every new column is nullable with no default, both new indexes are partial, and the one new CHECK constraint runs a row-count preflight first. Expect a fast boot.
One migration performs a cleanup DELETE (the approvals:decide revoke described above) and reports its row count as a WARNING in the Postgres log even when zero.
No new required environment variables. Nothing added here will refuse to boot. The release does add an optional customer M365 Graph-actions (write) executor block; it is off by default (M365_GRAPH_ACTIONS_TOOLS_ENABLED=false) and needs no action unless you deliberately enable it. That executor is intentionally not deployed by the generic Compose stack — it expects a separately released, digest-pinned image running with a workload identity, private ingress and controlled egress. Do not expose it through Caddy or point it at a plaintext URL.
If you maintain your own docker-compose.yml rather than tracking the repo's, note that the upstream file gained a secrets: entry for the executor signing key which defaults to /dev/null when unused — harmless, but you will not inherit it automatically.
Behavior changes & feature flags. No defaults changed. The runtime extension platform ships enabled but is inert until you install an extension. Helper chat sessions behave identically unless a client declares session tools.
No breaking changes.
Full Changelog: v0.97.2...v0.98.0
Note: the auto-generated link at the bottom of this page compares against
v0.97.1. The correct previous release isv0.97.2— use the link above.
What's Changed
- ci(migrations): non-superuser migration guard (prevents the v0.97.0 class) by @ToddHebebrand in #2626
- Quote builder overhaul: document-styled editor, 30s undo-send window, duplication by @ToddHebebrand in #2623
- fix(migrations): heal v0.97.0 checksums for the 8 migrations #2622 edited in place (v0.97.2) by @ToddHebebrand in #2627
- feat(approvals): durable action-intents & Tier-3 approval layer (Plan 1) by @ToddHebebrand in #2625
- feat(helper): Workspace Files — finder UI, content preview, and the Workspace Reshape by @ToddHebebrand in #2631
- feat(helper): files-first shell — one header, chat side panel, window-state persistence (W8) by @ToddHebebrand in #2636
- feat(w7): chat over the estate — client-declared session tools, cited RAG answers in helper chat by @ToddHebebrand in #2637
- fix(jobs): scan-orgs enqueues outside held DB context + dedupe #1105 tripwire Sentry captures by @ToddHebebrand in #2640
- feat(extensions): runtime extension artifact & operations (Plan 02) by @ToddHebebrand in #2617
- feat(extensions): runtime web pages, navigation & named slots (Plan 03) by @ToddHebebrand in #2633
- feat(extensions): add extension testkit (Plan 04, Task 1) by @ToddHebebrand in #2648
- fix(extensions): stage signed bundles through the v1 SDK contract by @ToddHebebrand in #2650
- fix(agent): PAM deny gate releases only on proven dismissal + bounded recovery (#2610) by @ToddHebebrand in #2644
- fix(ai): repair get_cis_compliance query + sanitize tool errors before streaming (#2603) by @ToddHebebrand in #2646
- fix(viewer): register breeze:// on Linux so the AppImage actually connects (#2614) by @ToddHebebrand in #2645
- feat(intents): durable approval follow-ups + Phase 2 Google + Phase 3 M365 headless executors by @ToddHebebrand in #2628
- fix(extensions): reserve 7 hijackable route namespaces + auto-derive CORE_NAMESPACES (#2634, #2635) by @ToddHebebrand in #2641
- fix(agent): persist credentials before the server commits rotation (#2621) by @ToddHebebrand in #2647
- fix(agent): carry stdout/stderr/exitCode through the WS command result (#2474) by @bdunncompany in #2629
Full Changelog: v0.97.1...v0.98.0