github LanternOps/breeze v0.109.0

latest releases: v0.124.0, v0.123.0, v0.122.1...
one month ago

Breeze RMM v0.109.0 — complete MFA, AI agents that act, ticketing on mobile, and org lifecycle.

This is the largest Breeze release to date: 184 commits, ~2,000 files and 52 migrations since v0.108.0. Most of it is five multi-wave programs landing together, plus a long tail of hardening from a pre-release sweep. Read the upgrade notes before you pull — two migrations take blocking locks on tables that can be large, and there is one soft-breaking change for bare-metal self-hosters running a local LLM.

Summary

  • MFA is complete — TOTP, SMS and passkey enrolment for every account type, recovery codes shown once at enrolment, and a login challenge that renders a wrong code instead of logging you out (#4237, #4439).
  • AI agents phase 2 — act mode — agents can now act, not just propose: a closed operation manifest with revalidate/verify, policy-decided unattended Tier-3, safety controls (per-org circuit breaker, kill state), alert verdicts, scheduled sweeps, weekly org narratives, and ticket triage with AI drafts you send as yourself. Everything stays off by default behind BREEZE_AI_AGENTS_ENABLED and per-agent autonomy settings.
  • Ticketing on mobile — comment attachments, a running timer with a weekly timesheet, offline time-entry queue, push categories and preferences, and auto-suggested time entries from remote sessions (#3206 program).
  • Org lifecycle — archive an organization (read-only, with restore) or merge two, with a durable merge engine and cross-extension registry (#4082, #4111, #4114, #4128, #4132).
  • BYO-LLM phase 2 — provider catalog, partner endpoint selection and an LLM egress enforcement layer (#4113–#4118).
  • Worker split — a BREEZE_ROLE=worker process for monitors, SNMP, backup, discovery and event dispatch, with its own /metrics; optional, off unless you opt in (#4140, #4145, #4423).
  • QuickBooks customer and item mapping (Phase B) (#4372).

Added

  • Auth — complete MFA clients and enrolment across web and mobile (#4237); guided password/MFA confirm ceremony when an SSO identity first links to an existing account (#4080); lockout preflight and confirm-through before Enforce SSO goes live (#4071); Phase 1 browser transition foundation for durable sessions (#4097).
  • AI agents (phase 2) — act-mode foundations and closed operation manifest (#4146, #4148); policy-decide lane for unattended Tier-3 (#4154, #4155); supervision UI with execution traces and exposure readout (#4157); safety controls: fix-held watch, per-org circuit breaker, kill-state admin API (#4168); ticket helpdesk shadow with a transactional outbox (#4195); metric-anomaly pilot (#4203); alert verdicts (#4220, #4222); scheduled sweeps with batch approve/decline (#4232, #4233); weekly org narrative reports (#4249, #4250); ticket triage — profile, ticket-scoped intents, AI drafts with send-as-me / discard / resolve prefill, autonomy toggle (#4300, #4301).
  • Ticketing — comment attachments on API, web and portal (#4282); auto-suggested time entries from remote sessions, off by default (#4290); push categories (#4281).
  • Mobile — time-entry client and running timer (#4235), offline queue for time-entry writes (#4252), timer bar and weekly timesheet (#4259), suggested time entries (#4338), ticket push routing and notification preferences (#4383), comment attachments (#4385).
  • Org lifecycle — status values and deferrable FKs (#4082), merge engine and UI (#4111, #4114), archive backend and UI (#4128, #4132).
  • BYO-LLM — provider catalog (#4113), egress enforcement (#4115), partner catalog endpoint selection (#4116), partner endpoint UI (#4118).
  • Enrollment — installer and enrollment keys now default to 30 days / 50 devices (#4126); the Windows install one-liner downloads through your server, not GitHub (#4453).
  • Agent lifecycle — self-host → hosted edition transition with edition-aware update gating (#4091), the edition-migration script in the system library (#4102), and auto-dispatch for stranded agents, flag off by default (#4382).
  • Ops — worker /metrics, event-loop and DB-pool monitors, breeze_role Sentry tag (#4423); retention and rollup job outcomes as Prometheus metrics (#4348).
  • Accounting — QuickBooks customer and item mapping (#4372).

Improved

  • Remote desktop — Viewer Paste Text now delivers the literal string (Unicode injection) instead of US-layout keystrokes, so paths and operators survive on any keyboard layout (#4352); the macOS desktop helper reconnects with backoff instead of exiting on IPC failure, so Desktop no longer greys out after sleep (#4353); the helper no longer re-prompts Screen Recording on every start (#4367); Viewer falls back gracefully when the WebView has no WebRTC (#4363).
  • Remote terminal — the Terminal tab connects on first open (no more File-Browser round-trip), and the "Connected Bang" welcome string is fixed in all locales (#4161).
  • Retention — index-driven audit-retention cutoff with batched deletes (#4366); five previously unbounded retention DELETEs now batch (#4365); metric rollups use one short-lived DB context per statement (#4285).
  • Devices list — scoped to the selected org on first load after login (#4274); in-page hash links switch device tabs without a refresh (#4243); paginated lists clamp the page when rows shrink (#4242); organization order survives pagination (#4326).
  • Patching — the reboot policy is honoured when a patch job partially fails (#4265); per-patch status is recorded instead of collapsing to the batch result (#4407).
  • Time display — the browser's hour-cycle preference is respected everywhere (#4266).
  • Reporting — the FX approximate-total line now reports why it is unavailable instead of vanishing (#4440).
  • Operations — ordered graceful shutdown with sequential phases (#4138); durable event dispatch with per-subscriber delivery receipts (#4117); webhook deliveries recorded but never enqueued are recovered (#4095).

Fixed

  • Auth — MFA enrolment no longer fails silently on a mistyped code, and View codes no longer regenerates (and invalidates) your saved recovery codes (#4439); a self-host reached through an SSH tunnel or LAN address no longer bounces every login to "session expired" — same-origin cookie requests are accepted and an origin rejection is explained on the login page (#4475, #4476); an IdP re-verification returns to the card it started from (#4321).
  • Self-hosting — the guided-setup reboot-startup systemd unit was never installable (Type=oneshot + Restart=, then a quoted WorkingDirectory=); both fixed and now verified with systemd-analyze in CI (#4387, #4473).
  • Tenancy / GDPR — webhook_deliveries no longer blocks organization erasure (#4412); ticket-scoped AI runs are detached on device org-move (#4436); SELF_UNINSTALL is dispatched only after the device delete commits (#4357); an RLS-bypassing user-name resolver is no longer exported (#4404).
  • Alerts — every acknowledge, suppress, resolve and dismiss path is now a compare-and-swap, closing lost-update races (#4288, #4099, #4369).
  • Configuration policies — recurring maintenance windows have a start time; previously every recurrence fired at local midnight (#4323).
  • Agent — component binaries are served from the promoted agent_versions row (#4364); manual and AI agent-update dispatch is gated on the artifact edition (#4295).
  • Tickets — the seeded Partner Technician can work tickets and log time (#4334); inbound email-to-ticket defaults to off for new partners (existing partners unchanged) (#4420).
  • Billing — a created quote block is no longer invisible in the editor (#4284); invoice notes edits survive a deferred prop sync (#4294); the reprice error speaks operator language (#4474); quote PDF header fonts follow the document theme (#4435).
  • API — System Tools routes no longer report an agent timeout as success (#4361); a disabled built-in extension can no longer fail boot (#4277); decommissioned and ephemeral devices are excluded from backup fan-out (#4275); postgres.js teardown can no longer poison a pool slot (#4279).
  • Plus ~40 further fixes across CI, mobile, and the workspace extension.

Security

  • Self-hosters are encouraged to upgrade. SSRF hardening: release-manifest and binary-sync fetches (#4255, #4360) and the OpenAI-compatible LLM provider (#4324) now go through the guarded fetch path with redirect refusal and private-network filtering. An exported RLS-bypassing name oracle was removed (#4404). CI now Trivy-scans the api/web images that actually ship (#4359) and enforces the credential-boundary Dockerfile policy on the Graph actions executor (#4422). The LLM egress enforcement layer (#4115) bounds where partner keys can send data.
  • No advisories are pending for this range.

Self-Hosting / Upgrade Notes

One soft-breaking change (below). No new required environment variables.

Upgrade command — bump BREEZE_VERSION in /opt/breeze/.env, then:

docker compose pull api web portal && docker compose up -d binaries-init api web portal

(portal is a separate container — include it. If you have opted into the worker split, add worker.)

Database — 53 migrations. Take a snapshot first. All are idempotent and auto-apply on API boot via autoMigrate (unless AUTO_MIGRATE=false). They create the phase-2 AI-agent tables, org-lifecycle columns, LLM catalog, ticket attachments/push/time-entry tables, QuickBooks mappings and agent-health observations. Lock hazards to plan around:

  • 2026-09-25-time-entry-source-and-suggestion-decisions.sql builds an index on remote_sessions with a plain CREATE INDEX (writes to that table block for the build) and validates a CHECK on time_entries (full scan under ACCESS EXCLUSIVE). Check SELECT count(*) FROM remote_sessions; and ... time_entries; first; if either is in the millions, upgrade in a maintenance window.
  • 2026-09-25-ai-agents-ticket-triage.sql adds a unique index on tickets (id, org_id) with a plain CREATE INDEX — a short write block on very large ticket tables; the accompanying jsonb column add is metadata-only and fast.
  • 2026-09-29-100000-automation-policy-compliance-unique.sql dedupes and builds two unique indexes on automation_policy_compliance in one transaction (deliberately not CONCURRENTLY); brief write block on that table.
  • Partial indexes on software_inventory / device_vulnerabilities key on a new all-NULL column — fast.

Privileged statements were audited against a non-superuser role before tagging: no CREATE ROLE, ALTER … OWNER TO, CREATE EXTENSION, or schema GRANTs in the range. Two earlier backfills (incidents timeline markers; recovery-authorization subjects) ran without breeze.scope=system and would have matched zero rows on managed Postgres — 2026-09-30-100000-rls-scoped-backfill-replay.sql replays them correctly; expect its rls-scoped replay warnings in the API boot log with real counts.

⚠️ Soft-breaking — bare-metal self-hosts running a local LLM over loopback (#4324). MCP_LLM_PROVIDER=openai-compatible egress now goes through the guarded fetch path, which never permits loopback. A bare-metal install with MCP_LLM_BASE_URL=http://localhost:8000/v1 (the default) or 127.0.0.1 will stop reaching the model — the refusal is explicit and names the fix. Point MCP_LLM_BASE_URL at the model host's container service name or a LAN (RFC1918/ULA) address. Containerised deployments are unaffected.

Behaviour changes

  • Recurring maintenance windows now honour a start time (#4323). Existing policies keep their schedule (NULL still means midnight); a policy you edit to set a start time will fire at that time.
  • New partners get inbound email-to-ticket off (#4420). Existing partners are unchanged.
  • Installer/enrollment keys default to 30 days and 50 devices (#4126). Existing keys are unchanged.
  • Same-origin cookie requests are accepted even when the origin is not in CORS_ALLOWED_ORIGINS (#4475) — this is what fixes the SSH-tunnel login loop. Cross-origin requests are still rejected; SameSite cookies remain the primary CSRF control.
  • Auto-suggested time entries ship off — enable per partner under Settings → Ticketing → Time Tracking. The technician-facing suggestion list is a mobile-app screen.
  • AI agents remain off by default (BREEZE_AI_AGENTS_ENABLED, defaults false); act mode is additionally gated per agent and per permission. Nothing acts unattended unless a policy explicitly allows it.
  • Stranded-agent auto-remediation (#4382) ships behind a flag that defaults off.
  • Worker split is opt-in via the compose worker-split profile and BREEZE_ROLE; the single-process default is unchanged.

Known issues (fixes queued for 0.110): regenerating MFA recovery codes evicts the current session before the new codes are shown (#4480); draft quotes/invoices have no currency-change UI yet (#4416); MFA proof endpoints answer a wrong code with 401 (the web client handles it; other clients should not treat that 401 as session expiry) (#4470).

Full Changelog: v0.108.0...v0.109.0


What's Changed

  • chore(deps): bump the github-actions group with 4 updates by @dependabot[bot] in #4066
  • fix(agent,api): self-host→hosted update transition + edition-aware offer gating (#4072) by @ToddHebebrand in #4091
  • feat(api,web): lockout preflight + confirm-through before Enforce SSO goes live (#4068) by @ToddHebebrand in #4071
  • fix(api): delivery idempotency and atomic winners (AI agents wave 3.5a) by @ToddHebebrand in #4083
  • docs(release-skill): pre-tag What's New entry step so the upgrade splash actually fires by @ToddHebebrand in #4070
  • [Auth][SSO] Link-on-first-SSO-login: password/MFA confirm ceremony replaces the sso_link_required dead end (#4067) by @ToddHebebrand in #4080
  • fix(api): route every alert-resolve path through the compare-and-swap (#4094) by @ToddHebebrand in #4099
  • fix(api): recover webhook deliveries recorded but never enqueued (#4095) by @ToddHebebrand in #4098
  • feat(api): wave 3.5c — durable event dispatch (BullMQ ingress + per-subscriber delivery receipts) by @ToddHebebrand in #4117
  • docs: v0.108.0 sweep — AI agents page and the gaps the release left by @ToddHebebrand in #4087
  • docs: land the 2026-08-24 UI QA sweep, the #2994 catalog spike, and the docs-citation rule by @ToddHebebrand in #4096
  • docs(plans): BYO-LLM phase 2 + workspace enrichment BYOK implementation plans by @ToddHebebrand in #4110
  • feat: workspace enrichment honors partner BYOK (#3917) by @ToddHebebrand in #4112
  • feat: llm provider catalog foundations (#3922 W01) by @ToddHebebrand in #4113
  • feat: llm egress enforcement layer (#3922 W02) by @ToddHebebrand in #4115
  • feat(enrollment): default installer keys to 30 days / 50 devices by @ToddHebebrand in #4126
  • feat(api): wave 3.5b — socket-affinity command relay (fenced presence + api-role BullMQ relay) by @ToddHebebrand in #4133
  • fix(api): ordered graceful shutdown — sequential phases, EventBus stops quitting the shared Redis connection (3.5d part A) by @ToddHebebrand in #4138
  • fix(api,workspace): review round 2 — permanent-vs-transient AI errors, billing/stamp telemetry, teardown guard by @ToddHebebrand in #4129
  • fix(api,web): review round 2 — self-managed revisions route, egress-blocked verdicts, authoring audit, listing-gate tests by @ToddHebebrand in #4130
  • feat(api): org lifecycle wave 1 — status values, columns, deferrable FKs, org_merge_events by @ToddHebebrand in #4082
  • fix(api): review round 2 — proxy audit completeness, recorder observability, shutdown drain, surface-drift contract by @ToddHebebrand in #4131
  • feat: partner catalog endpoint selection (#3922 W03) by @ToddHebebrand in #4116
  • feat: byo-llm partner endpoint UI + docs (#3922 W04) by @ToddHebebrand in #4118
  • feat(api,web): org lifecycle wave 2 — merge engine by @ToddHebebrand in #4111
  • feat(web): org lifecycle wave 3 — merge UI by @ToddHebebrand in #4114
  • feat(api): wave 3.5d — BREEZE_ROLE split: worker entrypoint, lazy placed registry, compose worker-split profile by @ToddHebebrand in #4140
  • feat(api): org lifecycle wave 4 — archive backend by @ToddHebebrand in #4128
  • feat(api): relay lazy agentWs import — monitor/snmp/backup/discovery move to the worker container by @ToddHebebrand in #4145
  • feat(web): org lifecycle wave 5 — archive UI by @ToddHebebrand in #4132
  • feat(api): wave 4 part A — act-mode foundations (execution ledger, agent attribution, durable notify, caps v2, device pinning) by @ToddHebebrand in #4146
  • feat(api,web): wave 4 part B — act mode: closed rule-equivalent operation manifest with revalidate, verify, always-notify by @ToddHebebrand in #4148
  • feat(api): wave 5 part A — policy-decide foundations (decision-state lifecycle, exposure ledger, kill state) by @ToddHebebrand in #4154
  • feat(api,web): wave 5 part B — policy-satisfied unattended Tier-3 (dark): the policy-decide lane by @ToddHebebrand in #4155
  • feat(api,web): wave 6.1 — supervision: execution-trace runs UI + exposure readout by @ToddHebebrand in #4157
  • feat(api): edition-migration script in the shared system script library (#4072 follow-up) by @ToddHebebrand in #4102
  • fix(api): realign the act-mode integration assertion with wave 4 Part B (main red) by @ToddHebebrand in #4158
  • fix(web): RemoteTerminal double-init/dead-terminal race + connectedBang locale by @ToddHebebrand in #4161
  • feat(auth): add Phase 1 browser transition foundation (#3852) by @ToddHebebrand in #4097
  • chore(web): What's New entry for v0.109.0 by @ToddHebebrand in #4163
  • feat(api): wave 6.2 — safety controls: fix-held watch, per-org circuit breaker, kill-state admin API by @ToddHebebrand in #4168
  • fix: pre-release sweep v0.108.0 → main — org-switch logout regression (#4167) + 12 sweep fixes, tracking doc, pre-release-sweep skill by @ToddHebebrand in #4172
  • docs(specs): location-aware time suggestions for the mobile app by @ToddHebebrand in #4185
  • feat(api): wave 6.3 — ticket helpdesk shadow: transactional outbox, forced-shadow runs, ticketProposal outcomes by @ToddHebebrand in #4195
  • feat(api,web): wave 6.4 — metric-anomaly pilot: first-class anomaly trigger, canonical incidents, deviceGroupIds filter by @ToddHebebrand in #4203
  • feat(api): P2-1a — alert-verdict foundations: Tier-2 agent intents, outcome tools, verdict profile (#4187) by @ToddHebebrand in #4220
  • feat(api,web): P2-1b — alert-verdict triggers (group-created, auto-resolve, ungrouped delay), alerts API aiVerdict, badge UI (#4187) by @ToddHebebrand in #4222
  • refactor(web): reorganize left nav — split Settings/Operations, rename ambiguous items by @ToddHebebrand in #4202
  • fix(agent): let the pinned config directory accept atomic renames (backport #4184) by @ToddHebebrand in #4197
  • feat(api): P2-2a — scheduled sweeps foundations: intent target scope, sweep profile, evidence + outcome tool, schedules API, fixed-tick sweeper (#4187) by @ToddHebebrand in #4232
  • feat(api,web): P2-2b — schedules editor, sweep run surfaces, batch approve/decline with one ceremony per batch (#4187) by @ToddHebebrand in #4233
  • feat(api,shared): P2-3a — weekly org narrative: schedule kind + narrative profile, bounded context, submit_narrative, system-authored report artifact, jsPDF arm by @ToddHebebrand in #4249
  • feat(web): P2-3b — weekly org narrative web: system-managed report rows, run-detail narrative, schedule kind selector (8 locales) by @ToddHebebrand in #4250
  • fix(ci): make migration baselines release-lineage aware by @ToddHebebrand in #4236
  • fix(api): honor the reboot policy when a patch job partially fails (#4228) by @ToddHebebrand in #4265
  • fix(web): respect browser hour-cycle fallthrough + migrate ad-hoc time formatting (#4231) by @ToddHebebrand in #4266
  • fix: complete S0 device control lifecycle by @ToddHebebrand in #4035
  • fix(authz): split S0 authorization integrity track by @ToddHebebrand in #4062
  • fix(db): patch postgres.js 3.4.9 — null nextWriteTimer/chunk on teardown so a dead socket can't poison a pool slot (#3225) by @ToddHebebrand in #4279
  • fix(web): stop a created quote block from being invisible in the editor (#3519) by @ToddHebebrand in #4284
  • fix(api): metric rollups run one short-lived labeled DB context per statement (#4276) by @ToddHebebrand in #4285
  • fix(mobile): fail the build when EXPO_PUBLIC_API_URL cannot reach a server (#3943) by @ToddHebebrand in #4287
  • fix(api): close the check-then-act race in every single-alert acknowledge and suppress path (#4101) by @ToddHebebrand in #4288
  • docs(ai-agents): document the ticket-helpdesk and anomaly trigger lanes (#4213) by @ToddHebebrand in #4289
  • fix(api): guard created_by at the queueCommand insert site (#3978) by @ToddHebebrand in #4292
  • fix(web): stop a deferred prop-sync effect from discarding an invoice notes edit (#3277) by @ToddHebebrand in #4294
  • feat(api,shared): P2-4a — ticket triage (act): triage profile, ticket-scoped intents with creation-transaction autonomy, ticket_drafts, provenance-guarded field writes by @ToddHebebrand in #4300
  • feat(mobile): Time-entry API client and running-timer state (#3206 W03) by @ToddHebebrand in #4235
  • fix(web): clamp the paginated list page when rows shrink underneath it (#4008) by @ToddHebebrand in #4242
  • fix(api): route release-manifest fetches through the SSRF-guarded redirect helper (#3649) by @ToddHebebrand in #4255
  • fix(api): return 404, not 403, for an unusable Mcp-Session-Id (#3744) by @ToddHebebrand in #4256
  • docs(security): document the api_data volume and Redis on the backup page (#3958) by @ToddHebebrand in #4268
  • fix(api): pin the partner-API provisioning 23505 to the org slug index (#3982) by @ToddHebebrand in #4269
  • fix(web): scope the devices list to the selected org on first load after login (#4147) by @ToddHebebrand in #4274
  • fix(api): exclude decommissioned and ephemeral devices from backup fan-out and the low-readiness gauge (#3968, #3969) by @ToddHebebrand in #4275
  • fix(extensions): lazy BUILTINS manifest resolution so a disabled built-in cannot fail boot (#3470) by @ToddHebebrand in #4277
  • fix(api): surface per-command Redis errors from the shadow-mode multi() pipeline (#4125) by @ToddHebebrand in #4238
  • fix(api): clear discovered_assets.link_source when a device hard-delete detaches the link (#3952) by @ToddHebebrand in #4241
  • fix(web): make in-page hash links switch device tabs without a refresh (#4229) by @ToddHebebrand in #4243
  • feat(mobile): Offline queue for time-entry writes (#3206 W04) by @ToddHebebrand in #4252
  • fix(ci): make test-mobile a blocking check in ci-success (#3941) by @ToddHebebrand in #4254
  • feat(mobile): Timer bar, ticket-detail start/stop, and weekly timesheet (#3206 W05) by @ToddHebebrand in #4259
  • fix(pam): make actuation lifecycle durable and restart-safe by @ToddHebebrand in #4105
  • chore(ci): repin Swatinem/rust-cache to the v2.9.2 release commit (#3748) by @ToddHebebrand in #4319
  • fix(api): register the event-dispatch maintenance repeatables unconditionally (#4124) by @ToddHebebrand in #4320
  • fix(web): return an IdP re-verification to the card it started from (#4055) by @ToddHebebrand in #4321
  • fix(web,api): give recurring maintenance windows a start time (#4224) by @ToddHebebrand in #4323
  • fix(api): apply organizationOrder in SQL so it survives pagination (#4004) by @ToddHebebrand in #4326
  • fix(api): gate manual/AI agent-update dispatch on the artifact edition (#4093) by @ToddHebebrand in #4295
  • fix(api): unwrap DrizzleQueryError when reading SQLSTATE in networkBaselines and aiAgents (#4020) by @ToddHebebrand in #4240
  • docs(mobile): #3206 W02 scope & permission findings by @ToddHebebrand in #4234
  • docs(mobile): #3206 W06-W08 specs and plans by @ToddHebebrand in #4258
  • feat: Ticket push categories — API (#3206 W07-A) by @ToddHebebrand in #4281
  • refactor(api): consolidate the thirteen hand-rolled row-count readers onto db/rowCount (#3894) by @ToddHebebrand in #4244
  • docs(api): attribute SSO state-cookie protection to the HMAC binding, not SameSite (#4054) by @ToddHebebrand in #4253
  • feat: Auto-suggested time entries — backend, web parity and docs (#3206 W06-A) by @ToddHebebrand in #4290
  • fix(ci): discriminate ESRCH from EPERM in the ee boot-step kill handler (#3471) by @ToddHebebrand in #4333
  • feat: Ticket comment attachments — API, web, portal and docs (#3206 W08-A) by @ToddHebebrand in #4282
  • test(security): pin the credential-boundary executor apk policy (#4246) by @ToddHebebrand in #4328
  • fix(api): let the seeded Partner Technician work tickets and log time (#4251) by @ToddHebebrand in #4334
  • fix(api): route openaiCompatibleProvider egress through guarded safeFetch (#4121) by @ToddHebebrand in #4324
  • chore(deps): bump @types/node from 26.2.0 to 26.4.0 in /e2e-tests by @dependabot[bot] in #4302
  • chore(deps): bump the expo-sdk group across 1 directory with 9 updates by @dependabot[bot] in #4303
  • chore(deps): bump react-native-reanimated from 4.5.3 to 4.6.0 in the react-native-animation group by @dependabot[bot] in #4304
  • chore(deps): bump @tanstack/react-query from 5.101.4 to 5.102.8 in the tanstack group by @dependabot[bot] in #4309
  • chore(deps): bump the testing group with 2 updates by @dependabot[bot] in #4311
  • chore(deps): bump node from d32cdf6 to e67514e in /apps/api by @dependabot[bot] in #4313
  • chore(deps): bump node from d32cdf6 to e67514e in /apps/web by @dependabot[bot] in #4314
  • chore(deps): bump node from d32cdf6 to e67514e in /docker by @dependabot[bot] in #4315
  • chore(deps): bump node from d32cdf6 to e67514e in /apps/m365-graph-read-executor by @dependabot[bot] in #4316
  • chore(deps): bump node from d32cdf6 to e67514e in /apps/m365-graph-actions-executor by @dependabot[bot] in #4317
  • chore(deps): bump node from d32cdf6 to e67514e in /apps/m365-communications-executor by @dependabot[bot] in #4318
  • feat(mobile): auto-suggested time entries — client, queue, slice and screens (#3206 W06-B) by @ToddHebebrand in #4338
  • chore(deps): bump react-native from 0.87.0 to 0.87.1 in the mobile group across 1 directory by @dependabot[bot] in #4305
  • chore(deps): bump the typescript-tooling group across 1 directory with 2 updates by @dependabot[bot] in #4306
  • chore(deps): bump the astro group across 1 directory with 2 updates by @dependabot[bot] in #4307
  • chore(deps): bump the react group across 1 directory with 2 updates by @dependabot[bot] in #4308
  • chore(deps): bump hono from 4.13.3 to 4.13.5 in the hono group across 1 directory by @dependabot[bot] in #4310
  • chore(deps): bump eslint from 10.9.0 to 10.9.1 in the linting group across 1 directory by @dependabot[bot] in #4312
  • fix(deps): dedupe pnpm-lock after dependabot sweep by @ToddHebebrand in #4346
  • fix(deps): dedupe hono@4.13.5 lockfile keys — unbreaks all CI on main by @ToddHebebrand in #4349
  • test(web): deterministic ordering for the QuoteWorkspace superseded-GET flake by @ToddHebebrand in #4344
  • docs(release-notes): next-release draft — #4324 loopback refusal + #4323 maintenance-window start times by @ToddHebebrand in #4358
  • fix(agent,macos): desktop helper self-reconnects instead of exiting on IPC failure (#4194) by @ToddHebebrand in #4353
  • fix(fleet): split S0 execution-truth track by @ToddHebebrand in #4064
  • fix(viewer,agent): deliver Paste Text as literal Unicode, not US-layout keystrokes (#4089) by @ToddHebebrand in #4352
  • chore: gitignore local AI-assistant state and sandbox env files by @ToddHebebrand in #4350
  • docs(integrations): QuickBooks hosted registration + customer/item mapping plans by @ToddHebebrand in #4351
  • fix(ops): repoint verify-monitoring.sh at the real prod compose files (#4278) by @ToddHebebrand in #4354
  • docs(ai-agents): act mode has shipped — correct the 'later release' claim (#4291) by @ToddHebebrand in #4355
  • feat(abuse): corroborated-watch promotion + origin-IP recidivism detector by @ToddHebebrand in #4356
  • fix(api): dispatch SELF_UNINSTALL only after the device delete commits (#3817) by @ToddHebebrand in #4357
  • fix(api): route binarySync's release fetches through the SSRF-guarded redirect helper (#4262) by @ToddHebebrand in #4360
  • fix(api): stop System Tools routes reporting an agent timeout as success (#4025) by @ToddHebebrand in #4361
  • fix(api): batch five unbounded retention DELETEs (#4343) by @ToddHebebrand in #4365
  • perf(api): index-driven audit retention cutoff + batched deletes (#4239) by @ToddHebebrand in #4366
  • fix(agent): stop re-prompting Screen Recording on every helper start (#4327) by @ToddHebebrand in #4367
  • fix(api): make POST /alerts/:id/dismiss a compare-and-swap (#4293) by @ToddHebebrand in #4369
  • chore(deps): bump the aws-sdk group in /agent with 5 updates by @dependabot[bot] in #4374
  • feat(accounting): QuickBooks customer and item mapping (Phase B) by @ToddHebebrand in #4372
  • fix(security): Trivy-scan the api/web images we actually ship (#4273) by @ToddHebebrand in #4359
  • feat(api): export retention and rollup job outcomes as Prometheus metrics (#4345) by @ToddHebebrand in #4348
  • fix(viewer): fall back gracefully when the WebView has no WebRTC (#3410) by @ToddHebebrand in #4363
  • fix(api): serve component binaries from the promoted agent_versions row (#3499) by @ToddHebebrand in #4364
  • test(api): stop asserting ephemeral-port inequality in llmEgressProxy restart test by @ToddHebebrand in #4381
  • feat(auth): complete MFA clients and enrollment (#2489) by @ToddHebebrand in #4237
  • chore(deps): bump github.com/pion/webrtc/v4 from 4.2.18 to 4.2.19 in /agent by @dependabot[bot] in #4375
  • chore(deps): bump cloud.google.com/go/storage from 1.65.0 to 1.66.0 in /agent by @dependabot[bot] in #4376
  • chore(deps): bump github.com/getsentry/sentry-go from 0.48.0 to 0.49.0 in /agent by @dependabot[bot] in #4377
  • chore(deps): bump google.golang.org/api from 0.293.0 to 0.295.0 in /agent by @dependabot[bot] in #4378
  • ci: give apt a transport deadline in the Tauri dependency install (#3730) by @ToddHebebrand in #4386
  • feat(web,api): P2-4b — ticket triage web: AI-draft send-as-me/discard/resolve prefill, autonomy toggle, triage run surfaces (8 locales) by @ToddHebebrand in #4301
  • feat(api): auto-dispatch edition migration for stranded self-host agents (#4072 follow-up) by @ToddHebebrand in #4382
  • fix(selfhost): drop invalid Restart= from the oneshot reboot-startup unit (#4201) by @ToddHebebrand in #4387
  • fix(abuse): close #4356 review findings — scan gate, axis map, IP normalization by @ToddHebebrand in #4380
  • feat(mobile): ticket push routing, notification prefs and Settings controls (#4336) by @ToddHebebrand in #4383
  • feat(mobile): ticket comment attachments (#4337 W11) by @ToddHebebrand in #4385
  • fix(security): enforce credential-boundary Dockerfile policy on actions executor (#4272) by @ToddHebebrand in #4422
  • fix(api): default new partners' inbound email-to-ticket to off (#3608) by @ToddHebebrand in #4420
  • fix(docker): route portal dev island module URLs to portal in Caddy (#3906) by @ToddHebebrand in #4425
  • feat(worker): /metrics endpoint, event-loop + DB-pool monitors, breeze_role Sentry tag (#4143) by @ToddHebebrand in #4423
  • fix(web): resolve typed lib/api mutation wrappers in no-silent-mutations guard (#3503) by @ToddHebebrand in #4427
  • fix(ci): warn on dpkg recovery failure, surface main-red-alert write failures (#3754) by @ToddHebebrand in #4426
  • fix(clientAi): use isPgUniqueViolation helper for tenant-mapping conflict (#4325) by @ToddHebebrand in #4424
  • fix(test): stop alertRuleOwnershipMigration replay from clobbering export function (#3818) by @ToddHebebrand in #4428
  • test(security): exercise the 'upgrade present' half of the apk hardening guard (#4271) by @ToddHebebrand in #4432
  • fix(agent/ipc): replace flaky wall-clock margins with deterministic write observation (#4322) by @ToddHebebrand in #4430
  • fix(devices): detach ai_agent_runs.ticket_id on device org-move (#4215) by @ToddHebebrand in #4436
  • docs(billing): document contract templates and quote contract blocks (#3487) by @ToddHebebrand in #4431
  • fix(quotes): theme PDF header fonts, tighten docTheme type, fix vacuous test (#3546) by @ToddHebebrand in #4435
  • fix(web): Windows install one-liner downloads via the server, not GitHub by @ToddHebebrand in #4453
  • test(api): pin the offboarding repair's FOR UPDATE with a lock barrier (#4036) by @ToddHebebrand in #4433
  • fix(web): surface MFA enrollment failures and stop 'View codes' regenerating recovery codes (#4413, #4414) by @ToddHebebrand in #4439
  • fix(web): make the FX approximate line report failure instead of vanishing (#4415) by @ToddHebebrand in #4440
  • fix(billing): reword the reprice CURRENCY_LOCKED error for operators (#4417) by @ToddHebebrand in #4474
  • fix(api): unique index + atomic upserts for automation_policy_compliance (#4122) by @ToddHebebrand in #4421
  • refactor(web): split UnifiIntegration.tsx into per-card components + state hook (#2382) by @ToddHebebrand in #4437
  • test(tickets): real-Postgres integration test for ticket_outbox rollback atomicity (#4219) by @ToddHebebrand in #4434
  • docs: correct self-hosted server sizing table with real baseline (#3959) by @ToddHebebrand in #4429
  • fix(api): un-export resolveUserDisplayNames RLS-bypassing name oracle (#3983) by @ToddHebebrand in #4404
  • fix(web,docs): surface origin-rejected refresh as its own login notice; fix SSH-tunnel recipe by @ToddHebebrand in #4476
  • fix(api): webhook_deliveries blocks GDPR org erasure — add ON DELETE CASCADE (#4100) by @ToddHebebrand in #4412
  • fix(auth): accept same-origin cookie requests outside CORS_ALLOWED_ORIGINS (self-host SSH-tunnel / LAN login loop) by @ToddHebebrand in #4475
  • fix(selfhost): reboot-startup unit still rejected — unquote WorkingDirectory=, verify with systemd-analyze in CI (#4201) by @ToddHebebrand in #4473
  • docs(web): refresh the 0.109.0 What's New entry for the final cut by @ToddHebebrand in #4482
  • docs(testing): log the 2026-09-01 pre-0.109.0 UI QA sweep and re-verify by @ToddHebebrand in #4481
  • docs(release-notes): clear the next-release draft after folding it into v0.109.0 by @ToddHebebrand in #4485
  • fix(db): replay the incidents and recovery-authorization backfills under system scope (#4483) by @ToddHebebrand in #4484

Full Changelog: v0.108.0...v0.109.0

Don't miss a new breeze release

NewReleases is sending notifications on new releases.