Repository navigation
v0.109.0
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_ENABLEDand 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=workerprocess 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_roleSentry 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 quotedWorkingDirectory=); both fixed and now verified withsystemd-analyzein CI (#4387, #4473). - Tenancy / GDPR —
webhook_deliveriesno longer blocks organization erasure (#4412); ticket-scoped AI runs are detached on device org-move (#4436);SELF_UNINSTALLis 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_versionsrow (#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.sqlbuilds an index onremote_sessionswith a plainCREATE INDEX(writes to that table block for the build) and validates a CHECK ontime_entries(full scan underACCESS EXCLUSIVE). CheckSELECT 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.sqladds a unique index ontickets(id, org_id) with a plainCREATE 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.sqldedupes and builds two unique indexes onautomation_policy_compliancein one transaction (deliberately notCONCURRENTLY); brief write block on that table.- Partial indexes on
software_inventory/device_vulnerabilitieskey 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.
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;SameSitecookies 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, defaultsfalse); 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-splitprofile andBREEZE_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
d32cdf6toe67514ein /apps/api by @dependabot[bot] in #4313 - chore(deps): bump node from
d32cdf6toe67514ein /apps/web by @dependabot[bot] in #4314 - chore(deps): bump node from
d32cdf6toe67514ein /docker by @dependabot[bot] in #4315 - chore(deps): bump node from
d32cdf6toe67514ein /apps/m365-graph-read-executor by @dependabot[bot] in #4316 - chore(deps): bump node from
d32cdf6toe67514ein /apps/m365-graph-actions-executor by @dependabot[bot] in #4317 - chore(deps): bump node from
d32cdf6toe67514ein /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