Breeze RMM v0.115.0 — automatic network topology mapping, a single unified alert-delivery resolver, and billing profiles land as connected infrastructure, alongside disk cleanup that actually frees space and a broad bare-metal recovery hardening pass.
⚠️ Two behavior changes to read before upgrading:
POST /devices/:id/move-orgnow requires a step-up MFA grant while two-factor authentication is enabled (#6310, #6400, #6309). See Self-Hosting below.- Billing Profiles automatically converts every partner's legacy labour-rate configuration into billing profiles on upgrade — this can change what is billable for existing partners (#6393, #6422). Run the dry-run report before upgrading. See Self-Hosting below.
Summary
Network devices now assemble themselves into a live logical topology map from passive agent evidence — interfaces, routes, neighbor tables — with shared config templates and on-demand diagnostics (#5996/#5997 W01–M1). Alerting consolidation replaces the old per-channel "send to everything enabled" fallback with a single delivery resolver, a real Delivery page (Channels · Routing · Escalation policies), and the first pass of a legacy-alert-to-monitor converter (#6367 W05a–W05c1). Disk Cleanup v2 finishes: cleanup now permanently deletes and actually frees space, scans any fixed volume, and gains OS-native cleaners (Windows Disk Cleanup/DISM, macOS snapshots/Homebrew, Linux caches/journal) reachable from the UI and a new AI tool (#6326 W01–W05). Billing Profiles + Work Types replace scattered legacy rate fields with one Rates screen, minimums, and rounding (#4628/#4615 W01–W03). Partner Sending Domains let a partner send customer email from their own domain, ships dark until configured (#6180 W01–W06). Bare-metal recovery gets a Restore-as-VM VHDX path, a fix for cross-snapshot incremental recovery, and a 24-hour restore timeout ceiling. Device move-org now requires an interactive session and, with 2FA on, a step-up grant (#6301 W01–W03). A broad fix sweep (SNMP, monitors, backup, DR races, tenant-isolation edges) rounds out the release, alongside a five-PR hardening pass and helper-auth / script-parameter security fixes.
Added
- Network topology mapping (#5996/#5997 W01, W02/M1): automatic logical site maps built from passive agent evidence, shared configuration templates appliable across many sites at once, automatic layout, and on-demand ping/traceroute-style diagnostics from the map. Ships agent-side collection code — full effect needs the updated agent. (#6028, #6115)
- Disk Cleanup v2, W01–W05 (#6326): cleanup now permanently deletes instead of moving files into agent-local trash, so reclaimed space is real (#6346); scans and cleans any fixed volume, not just the system drive (#6360); the Disk Cleanup tab becomes a full select/execute/history workflow (#6366); new OS-native cleaners — Windows Disk Cleanup handlers and DISM component cleanup, macOS local snapshots and Homebrew, Linux package caches and journal — reachable from the tab and from a new
system_cleanupAI/MCP tool, needs the updated agent (#6386, #6442). - Alerting consolidation, W05a–W05c1 (#6367): legacy alert-rule authoring frozen in favor of Monitors, with a "Create monitor" shortcut and a Recommended strip (#6381, #6392); one delivery resolver replaces the old implicit all-channels fallback, with a new Delivery page (Channels · Routing · Escalation policies) and a delivery preview (#6385, #6387, #6390); a
compositemonitor kind, conversion-ledger foundation, and the first legacy-rule-to-monitor converter (preview, equivalence check, convert/revert/retire) (#6394, #6395, #6416). - Partner sending domains (#6180 W01–W06): a partner can configure a custom sending domain and per-stream sender identities so customer email comes from their own domain, with DNS verification, test-send, delivery health, bounce/complaint webhook handling, and automatic suspension on sustained bounce/complaint rates. Dark until
EMAIL_DOMAINS_PROVIDERis set. (#6194, #6196, #6199, #6211, #6208, #6217) - Branded transactional email: quote, invoice, portal-invite and ticket-notice emails now render as editable HTML templates instead of bare stubs. (#6088, #6089)
- Billing Profiles + Work Types (#4628/#4615 W01–W03): one Rates screen replaces scattered legacy category/org rate fields; time entries can be tagged with a Work Type; billed time now reflects per-profile minimums and rounding. (#6347, #6393, #6422)
- Bare-metal recovery: Restore-as-VM and DR rehearsal/failover can target a VHDX image directly, including Linux guest images, with a new DR plan step type (#6320, #6321); server-side manifest indexing lets recovery resolve cross-snapshot object references, superseding the interim hard-refusal guard shipped as a stopgap (#6487, #6469).
- Device move-org step-up (#6301 W01–W03): moving a device between organizations now requires an interactive session, and, while 2FA is enabled, a single-use step-up MFA grant. See breaking-change note above. (#6310, #6400, #6309)
- MFA required by default for new partners (#6305 W01), with an
MfaPolicyOffBannernudging existing partner admins who have it off. Existing partners are unchanged on upgrade. (#6308) - Admin → Users MFA status column (Enrolled / Pending / Overdue). (#5690 — #6257)
- AI tool efficiency program, A-W01/A-W02/A-W06 + MCP B-W01: tool-selection capture/eval harness and baseline, registry metadata driving the system prompt, 13 new Tier-1 read tools closing API/AI-tool coverage gaps, and an MCP protocol refresh (version negotiation, tool titles/annotations, structured results, pagination). (#6345, #6341, #6414, #6406)
- Fleet Designer one-click enable — sets itself up instead of requiring a manual detour through Settings → AI Agents. (#6218)
- Curated device detail tabs: a focused primary tab row with items like Anomalies/Tickets surfacing automatically when they need attention, count badges, and a grouped "More" menu for the rest. (#6259)
- QuickBooks: confirmed mappings now sync automatically in the background instead of requiring a manual click (#6082); confirming a mapping now pulls the customer's address into the org/site when Breeze has none on file (#6080); an "Owed QuickBooks operations" panel surfaces stuck-pending payment syncs (#6083).
- Settings consolidation, W01/W02: Ticketing gets its own settings page; Billing splits into Defaults/Documents/Connections; tax-rate and invoice-footer resolution consolidated to one resolver each. (#6233, #6231)
Improved
- Site and organization picker dropdowns now load every match instead of silently truncating around 50–100 rows — most consequentially in the "move device" dialog, where an unreachable target site previously blocked the move outright. (#6412 — #6459)
- Disk Cleanup preview and history now show reclaimable bytes, not just a candidate count. (#6454)
- Fleet Designer reports show "Not measured" for evidence sections it couldn't collect, instead of silently omitting them. (#5735 — #6079)
- Consecutive-failure ceiling for service/process/network_check monitors raised from 20 to 100; policy-link inheritance gains cumulative/replace semantics. (part of #6370 — #6394)
Fixed
- Bare-metal / DR: cross-snapshot incremental recovery no longer fails partway through after the target disk is already wiped (#6487, superseding #6469); a system-image rebuild can no longer report "completed" with no OS state applied (#6316); whole-machine restore/rebuild commands get a 24-hour timeout ceiling instead of being killed at 60 minutes (#5415 — #6434); DR execute failures now name the actual missing prerequisite instead of a generic error, and plan saves no longer partially apply (#6382 — #6440); bare-metal restore failures report a specific reason, and the post-restore health probe no longer flags template/one-shot systemd units as failures (#5479 — #6431); Windows bare-metal restores preserve Hidden/System/Sparse file attributes (#5407 — #6430); lab-found defects fixed — unsized VHDX target, refused-result surfacing, no longer converting a still-mounted disk image (#6404); closed two DR/bare-metal race conditions around stale-worker resurrection of terminal executions (#6322 — #6451); recovery session refresh is now bounded and single-flight instead of retrying per failed file (#5635 — #6256).
- Backup: incremental backups were silently going full every time due to an unsatisfiable base-selection condition — now correctly pick a small delta (#6351 — #6439); retention could delete the full snapshot an active chain's differentials/logs still depend on — now held until no longer needed (#5421 — #6433); backup jobs that fail server-side schema validation now fail loudly instead of hanging in "running" (#5413 — #6424); uploads between 16 MiB and 100 MB to MinIO/S3-compatible storage over HTTPS now succeed, and a partial run no longer verifies as fully passed (#6350 — #6427); the file Restore Wizard is now reachable from the UI instead of requiring a raw API call (#6349 — #6453); backup helper processes that exit on their own or get replaced by a respawn are properly reaped instead of leaking as zombies (#5980 — #6255).
- Monitors: a
network_checkmonitor could raise duplicate alerts, or none if its alert device was offline — now raises exactly one (#6353 — #6410);http_checkmonitors ignored their configured expected status code (#6352 — #6409);restart_serviceactions lost their restart configuration on save (#6343 — #6380); monitors of kind "offline" never fired (#6342 — #6378); role/OS filters on monitor policy assignments were ignored (#6344 — #6377); editing a script-check monitor could silently lose the selected script (#6207 — #6254). - SNMP: GetMulti now surfaces packet-level errors instead of null values (#6020 — #6069); agent honors SNMPv3 profile credentials in network discovery instead of falling back to v2c (#6234 — #6250); a template change now enqueues an immediate poll instead of waiting for the next interval (#6209 — #6245).
- AI / agents: a budget-enforcement race let two concurrent client-AI requests both pass the budget check before either was charged (#5557 — #6458); MCP tool calls returning an error payload were logged as successes, hiding real failure rates (#6408 — #6420); agent-proposed fleet writes approved by a technician failed to execute because they were mis-attributed to the AI agent instead of the approving human (#6200 — #6205); a newly created patch schedule could fire a backdated catch-up run before its own creation time (#6201 — #6204); a tool-output redactor was wiping legitimate non-secret data such as session counts and credential-presence flags (#6140 — #6324); organization-scoped roles could hold every AI permission and still be blocked from opening AI chat at all — added a dedicated
ai_sessions:usepermission (#6396 — #6399). - Network proxy now correctly rewrites root-relative and same-host links instead of breaking out of the proxy mid-navigation. (#5906 — #6067)
- Remote desktop launcher now explains why a session was revoked instead of silently dropping to idle. (#6120 — #6240)
- Login fails closed with 503 instead of a server error when Redis is unavailable at the MFA gate. (#6177 — #6241)
- QuickBooks mapping picker shows the organization's name immediately after "Create new" instead of only after reload. (#6221 — #6236)
- Organizations board: clicking a name opens its detail pane instead of navigating away. (#6215 — #6242)
- Backup verification list surfaces the actual failure reason instead of a bare "failed". (#6146 — #6239)
- Occurrences drawer shows a proper empty state (with next planned date) instead of a blank panel before the first sweep. (#6219 — #6237)
- Automations can no longer be created with a newly-requested elevated run-as privilege; existing elevated automations are flagged with an "Elevated" badge. (#4918 — #6070)
- AI Assistant no longer fails importing loose
.ps1scripts with no category; bundle imports show a proper success screen. (#6005) - Script library import can target "All orgs" (partner-wide), not just one organization. (#5002 — #6074)
- A new hourly sweeper recovers script-verification proposals stuck in "executed" without completing verification. (#5641 — #6076)
- Report edit page no longer caps at a narrow fixed width on wide screens. (#6210 — #6244)
- Remote tool launcher no longer fails on devices with a numeric custom-field identifier. (#6191 — #6238)
Security
- Helper (device) authentication now enforces the device-credential lifecycle, and partner trust review requests require partner-wide manage access (#6507).
- Script parameter values are now rendered as data — never code — consistently across bash, PowerShell, and Python interpreter frames on the agent, including nested constructs (command substitutions, heredocs, f-string fields) (#6508).
- PAM actuator gate scoped to its own route: an unmatched
/devices/:id/*request now correctly returns 404, and the homebrew-bootstrap endpoint (previously unreachable on any stack withoutPAM_ACTUATOR_ENABLEDset) is reachable again (#6504). - Resource-agnostic copy for the partner-wide write-denial message, so it no longer misleadingly says "policy" for non-policy partner-wide state like branding or trust review (#6293).
- Persisted device-memory text read by the AI agent is now routed through the same untrusted-data sanitizer/delimiter used elsewhere, so it reads as data rather than instructions (#6294).
- The startup check that the API's request-pool database role is unprivileged (no SUPERUSER/BYPASSRLS) now runs unconditionally in every environment instead of only when
NODE_ENV=production, with an explicit, logged, production-refused break-glass opt-out for local dev (#6295). - Non-routable/private IP-range classification (SSRF guards on integration endpoints, outbound connect-time resolution) is now driven from one shared table instead of two hand-maintained lists that had drifted apart. (#6296)
- CSV/TSV export escaping is consolidated to one implementation and now applied to header rows too, closing a header-injection gap in custom-field/SQL-alias-derived headers. (#6297)
- Four dispatch paths (backup, software remediation, backup test-restore, sensitive-data scan) now re-check a device's current organization at dispatch time, closing a window where a device moved between orgs mid-flight could dispatch against the wrong tenant. (#5567 — #6073)
- Automation dispatch now re-checks device organization at dispatch time and cancels in-flight CIS remediation on an org move. (SEC-118 — #5562)
- Tenant offboarding: aborting a drain now locks queued uninstall commands before flipping tenant status, closing a race that could leave a stale uninstall command deliverable fleet-wide after an abort; the credential-mint path was also removed from the offboarding drain surface so a draining tenant's agent cannot mint a fresh, never-revoked credential set via rotation. (#3996 — #6222; #3997 — #6216)
- Moving a device to a new organization now correctly follows its tickets'
partner_id, and ticket assignees are re-validated after the move so a ticket cannot stay assigned to someone who has lost access. (#5551 — #6075) - Site-restricted monitoring routes no longer distinguish "exists but you can't see it" (403) from "doesn't exist" (404) — both now 404, closing an existence-oracle leak. (#5777 — #6133)
- The MFA-assured-session contract is pinned, and partner-scope user invites can no longer reference organization IDs outside the caller's own partner (Strix scan finding). (#6299)
- Dependency hardening and open Dependabot/Trivy/CodeQL cleanup. (#5938)
Self-Hosting / Upgrade Notes
Upgrade: bump BREEZE_VERSION in .env, then docker compose pull api web portal && docker compose up -d (or pnpm install when running from source).
⚠️ Before you upgrade — Billing Profiles conversion. The 2026-10-24-200200-labour-pricing-conversion.sql migration automatically converts every partner's existing legacy category/org labour-rate configuration into billing profiles at migration time. There is no toggle to defer this. It can change what is billable for existing partners: an org that had a rate configured but no explicit billable flag was previously silently non-billable and becomes billable at that rate after conversion, and orgs with no org-settings row move from "excluded from billing" to "billable, no rate" (surfaces as missingRate at invoice time rather than being silently skipped). Run pnpm --filter @breeze/api dry-run:labour-pricing before upgrading and review the "WILL START BILLING" section. A new time_entries:manage_billing permission is now required to hand-edit a rate or billable flag on a time entry from any surface; Partner Admin (*:*) is unaffected, other roles that previously did this need it granted explicitly.
⚠️ Breaking — POST /devices/:id/move-org now requires a step-up grant while two-factor authentication is enabled. The request must carry stepUpGrant, a single-use grant minted by POST /auth/mfa/step-up with operation: "device_move_org" and a resource of { deviceId, targetOrgId, targetSiteId, acceptCurrencyMismatch }. Requests without it receive 403 { code: "STEP_UP_REQUIRED" }. API keys and MCP tokens are refused outright (403 Interactive user session required) whether or not 2FA is on. Accounts with no enrolled MFA factor cannot move devices — enroll an authenticator app or passkey first. There are no web, mobile, AI-tool, or MCP callers of this route as of this release, so nothing in the product itself is affected; only scripted/API callers.
Site-restricted technicians (intentional): a technician limited to certain sites now loses an entire parent software deployment, not just its out-of-ceiling child results, when any target device sits outside their site ceiling — including multi-site deployments they created themselves. (#5545/#5777)
Migrations: 39 new migration files, all idempotent and auto-applying on boot via autoMigrate (unless AUTO_MIGRATE=false). Two worth calling out beyond the billing conversion above:
2026-10-21-110000-filesystem-multi-volume.sql(Disk Cleanup v2 W02) changesdevice_filesystem_scan_state's primary key from(device_id)to(device_id, scan_path), backfilling from existing scan data. It ships paired with its writer-code change in the same release. Hosted Breeze replaces its single API container, so this is a non-issue there. On a multi-replica self-host, any old replica still draining after the migration applies will fail its scan-state upsert with42P10until it drains (the snapshot insert itself still succeeds); re-running the scan once every replica is on the new build repairs the state. Single-replica self-hosts are unaffected. The follow-up migration2026-10-22-160000-filesystem-scan-path-not-null.sqlcontracts the column toNOT NULLand promotes the composite key.2026-10-24-110100-topology-m1-runtime.sqlbackfillssite_idonnetwork_monitorsfrom discovered-asset data, and deactivates any monitor whose device/asset association no longer resolves to a valid site — a small number of orphaned network monitors can go inactive on upgrade. Row counts are logged.
No new required environment variables. New optional env vars, all defaulted/off unless explicitly configured:
EMAIL_DOMAINS_PROVIDER(+EMAIL_DOMAINS_STATIC_ALLOWED,EMAIL_DOMAINS_RESEND_API_KEY,EMAIL_DOMAINS_RESEND_SENDING_KEY,EMAIL_DOMAINS_REGION,EMAIL_DOMAINS_MAX_PER_PARTNER,EMAIL_DOMAINS_DAILY_SEND_CAP,EMAIL_DOMAINS_PARTNER_ALLOWLIST,EMAIL_DOMAINS_DENYLIST,EMAIL_DOMAINS_WEBHOOK_SECRET,EMAIL_DOMAINS_AUTOSUSPEND_*) — unset (the default everywhere, hosted and self-hosted) means the sending-domains feature is fully dark: the settings tab is hidden, its routes 404, its worker never registers, and every email sends exactly as before.BREEZE_ALLOW_UNSAFE_DB_ROLE— a break-glass opt-out for the now-unconditional (previously production-only) startup check that the API's request-pool database role is unprivileged. Prints an unmissable banner on every boot when set, and is ignored entirely whenNODE_ENV=production. Deliberately absent from.env.exampleand every compose file.
Disk Cleanup v2's new OS-native cleaners and the system_cleanup AI/MCP tool need an agent at v0.115.0 or newer; older agents return 409 agent_update_required. Network topology mapping's collection needs the updated agent for full effect.
No other breaking changes.
Full Changelog: v0.114.0...v0.115.0
What's Changed
- ci(release): dispatchable image promotion — a stalled asset upload cannot strand a release's image tags by @ToddHebebrand in #6174
- ci: cut a CI run from ~40 min to ~15 — QEMU gated on agent changes, Test API sharded, 8 integration shards, tooling-only class by @ToddHebebrand in #6178
- docs(email): partner sending domains — approved spec + W01–W06 implementation plans (#6180) by @ToddHebebrand in #6187
- docs(release): v0.114.0 shipped — pre-tag sweep addendum, Windows hosted first-install PASS, draft notes cleared by @ToddHebebrand in #6188
- docs(plans): placeholder email domains — unbreak Security Audit on main by @ToddHebebrand in #6193
- fix(monitoring,groups): canonical role/os policy filtering and group policy assignment display by @mvthul in #5857
- feat(email): W01 sender contract — purpose registry, resolveSender, deliverRaw (#6181) by @ToddHebebrand in #6194
- docs: v0.114.0 technical docs sync by @ToddHebebrand in #6190
- ci: QEMU gate follows the backup/recovery dependency set, not all of agent/ by @ToddHebebrand in #6189
- docs: Monitoring nav → Network Monitor; device monitors under Alerts → Monitors (v0.114.0) by @ToddHebebrand in #6198
- fix(backup): scheduled sweep honours role/OS targeting and never dispatches an empty path list (#6001) by @ToddHebebrand in #6197
- feat(email): W02 sending domains data model, config and provider adapters (#6182) by @ToddHebebrand in #6196
- ci: docs-check runs the customer-PII guard so a docs-only PR cannot bypass it by @ToddHebebrand in #6195
- fix(web,api): dedupe variables org-switch GETs; recompute baseline next-run on interval change (#6103) by @ToddHebebrand in #6135
- fix(api): syncBinaries fetches no longer hold a DB context (#6098) by @ToddHebebrand in #6128
- fix(api): pin Fleet Design runs to their own wall clock, not the shared 600s default (#5870) by @ToddHebebrand in #6134
- fix(api): distinguish unhealthy tool sources from missing tools (#6102) by @ToddHebebrand in #6127
- fix(api): self-heal stale scripts.origin on the update path (#5948) by @ToddHebebrand in #6123
- fix(api): stop pinning a pooled connection across eventlogs forwarding (#6097) by @ToddHebebrand in #6124
- fix(web): SNMP template auto-apply on save is unreachable (#6099) by @ToddHebebrand in #6125
- fix(portal): trim the internal "Service evidence —" prefix from report names (#6101) by @ToddHebebrand in #6122
- fix(ai/tools): no cross-site or cross-role overreach through AI tools — site axis + route-parity permissions (#6086) by @ToddHebebrand in #6110
- fix(monitors): revalidate scoped executors before dispatch (#5987) by @ToddHebebrand in #6085
- feat(accounting): surface owed QuickBooks payment operations; warn when a void leaves the QuickBooks payment standing (#5130) by @ToddHebebrand in #6083
- fix(api): skip the generic route-derived audit row when a semantic audit was written in the same request (#5316) by @ToddHebebrand in #6081
- feat(scripts): library import offers an All orgs (partner-wide) target (#5002) by @ToddHebebrand in #6074
- feat(web): Fleet Designer viewer renders Not measured panels for unavailable evidence sections (#5735) by @ToddHebebrand in #6079
- fix(security): four dispatch paths re-check the device's current org at dispatch (#5567) by @ToddHebebrand in #6073
- fix(ai-agents): sweep Act mode cannot be armed when BREEZE_AI_AGENTS_SWEEP_ACT_ENABLED is off (#5960) by @ToddHebebrand in #6062
- fix(api): network proxy rewrites root-relative and same-host URLs; proxy cookie is SameSite=None (#5906) by @ToddHebebrand in #6067
- fix(automations): refuse newly requested elevated runAs on script actions; Elevated badge (#4918) by @ToddHebebrand in #6070
- fix(agent): StopShipper no longer holds the logging lock during flush; shutdown is bounded (#5334) by @ToddHebebrand in #6071
- chore(deps): Bump the github-actions group with 5 updates by @dependabot[bot] in #6037
- docs(ai): agent tool efficiency + MCP modernization program design by @ToddHebebrand in #6161
- docs(ai): Operator Recipe Library — spec + W01–W07 plans (feature #6165) by @ToddHebebrand in #6173
- docs(web-ui): billing + ticketing settings audit, W01/W02 plans, Wave 2 design positions (#6164) by @ToddHebebrand in #6179
- docs(integrations): backup provider integration (Cove) — design spec + W01–W05 plans (feature #6008) by @ToddHebebrand in #6018
- docs(specs): breeze-ctl — integration controller for the PR-to-landing loop by @ToddHebebrand in #5909
- docs(plans): dependency major-upgrade plan by @ToddHebebrand in #5826
- docs(specs): push nine specs sitting on unpushed local branches by @ToddHebebrand in #5893
- fix(ai-agents): shadow mode still executes on approval (#6202) by @ToddHebebrand in #6203
- chore(commands): remove offline-queue flag and W1 compatibility aliases (#5128 W5) by @ToddHebebrand in #6072
- fix(api): block artifact-backed ticket_attachments inserts with no artifact_id (#5955) by @ToddHebebrand in #6132
- fix(api): site-scope follow-ups from #5545 review (#5777) by @ToddHebebrand in #6133
- fix(agent): SNMP GetMulti surfaces packet-level errors instead of null values (#6020) by @ToddHebebrand in #6069
- fix(portal): lifecycle report returns the partner contact for the closing line (#5787) by @ToddHebebrand in #6078
- feat(email): W03 sending domains service, worker and routes (#6183) by @ToddHebebrand in #6199
- feat(api): settings consolidation W02-API — one tax resolver, one invoice-footer resolver, shared partner-settings schemas by @ToddHebebrand in #6231
- feat(email): W04 partner lane — resolveSender partner branch, fallback semantics, daily cap, loop prevention (#6184) by @ToddHebebrand in #6211
- Settings consolidation W01: placement (billing + ticketing) by @ToddHebebrand in #6233
- feat(email): W06 delivery feedback and abuse controls — Resend webhook, daily stats, auto-suspend, abuse signals (#6186) by @ToddHebebrand in #6217
- docs(research): feature velocity write-up — where #6180's time went, six structural fixes by @ToddHebebrand in #6213
- docs(ai): wave plans — agent tool efficiency A-W01/02/03/06 + MCP modernization B-W01 by @ToddHebebrand in #6230
- fix(ai-agents): sweep tick never catches up on an occurrence that predates the schedule (#6201) by @ToddHebebrand in #6204
- fix(ai-agents): release agent-originated fleet writes as the approving user (#6200) by @ToddHebebrand in #6205
- fix(api): take the credential mint off the tenant offboarding drain surface (#3997) by @ToddHebebrand in #6216
- fix(api): lock the drain uninstalls before an abort flips the tenant status (#3996) by @ToddHebebrand in #6222
- feat(fleet-design): one-click Enable Fleet Designer; designer mode picker hides Shadow and calls act "On" (#6214) by @ToddHebebrand in #6218
- chore(deps): bump @types/node from 26.4.1 to 26.5.1 in /e2e-tests by @dependabot[bot] in #5794
- chore(deps): bump node from
e67514eto50c8e8cin /apps/api by @dependabot[bot] in #5828 - chore(deps): bump node from
e67514eto50c8e8cin /docker by @dependabot[bot] in #5829 - chore(deps): bump node from
e67514eto50c8e8cin /apps/m365-communications-executor by @dependabot[bot] in #5831 - chore(deps): Bump github.com/pion/webrtc/v4 from 4.2.19 to 4.2.20 in /agent by @dependabot[bot] in #5924
- chore(deps): Bump cloud.google.com/go/storage from 1.67.0 to 1.67.1 in /agent by @dependabot[bot] in #5925
- chore(test): pin clearMocks:false ahead of Vitest 5 (prep, no bump) by @ToddHebebrand in #5848
- chore(deps): Bump golang.org/x/net from 0.58.0 to 0.59.0 in /agent by @dependabot[bot] in #5926
- chore(deps): bump office-addin-dev-certs 2 -> 3, office-addin-manifest 2 -> 3 by @ToddHebebrand in #5843
- chore(deps): pdfkit 0.19 → 0.20 by @ToddHebebrand in #5846
- chore(m365): bump @azure/msal-node 3 -> 6 by @ToddHebebrand in #5849
- chore(api): bump googleapis majors + google-auth-library 11 by @ToddHebebrand in #5852
- chore(deps): raise adm-zip override floor to 0.6.1 (GHSA-7q85-xj36-vmfc, blocks the queue) by @ToddHebebrand in #6262
- fix(web): QBO mapping picker shows org name after Create new (#6221) by @ToddHebebrand in #6236
- fix(web): Occurrences drawer empty state before the first sweep (#6219) by @ToddHebebrand in #6237
- fix(api): accept numeric custom-field identifiers in remote tool launcher (#6191) by @ToddHebebrand in #6238
- ci(typecheck): raise tsc heap to 12 GB (OOM flake) by @ToddHebebrand in #6261
- chore(deps): Bump playwright from 1.62.1 to 1.63.0 in /e2e-tests by @dependabot[bot] in #5795
- chore(deps): bump node from
e67514eto50c8e8cin /apps/m365-graph-read-executor by @dependabot[bot] in #5830 - chore(deps): Bump the aws-sdk group in /agent with 5 updates by @dependabot[bot] in #5923
- chore(deps): nodemailer 9 → 10 by @ToddHebebrand in #5836
- chore(deps): bump @testing-library/jest-dom 6 -> 7 by @ToddHebebrand in #5837
- chore(deps): dotenv 16 → 17, quiet:true everywhere by @ToddHebebrand in #5854
- fix(api): surface bounded failure reason on backup verification list (#6146) by @ToddHebebrand in #6239
- fix(auth): fail closed with 503 when Redis is unavailable at the login MFA branch (#6177) by @ToddHebebrand in #6241
- fix(web): org-board name click opens the pane (#6215) by @ToddHebebrand in #6242
- fix(web): drop max-w-4xl cap on report edit page (#6210) by @ToddHebebrand in #6244
- fix(ticketing): surface Graph probe error into mailbox verification failures (#6192) by @ToddHebebrand in #6243
- fix(patching): bind rollback targets to the device's own installed observation (#5565) by @ToddHebebrand in #6246
- fix(billing): checkout-revocation follow-ups from the #5556 review (#5611) by @ToddHebebrand in #6247
- fix(agent): honor SNMPv3 profile credentials in network discovery (#6234) by @ToddHebebrand in #6250
- fix(api): enqueue an immediate SNMP poll on template change (#6209) by @ToddHebebrand in #6245
- fix(remote): surface the revocation reason in the desktop launcher (#6120) by @ToddHebebrand in #6240
- fix(agent): reap backup helpers that exit on their own and on respawn (#5980) by @ToddHebebrand in #6255
- fix(monitoring): retain selected script on script-check monitors (#6207) by @ToddHebebrand in #6254
- fix(bmr): bounded, single-flight recovery session refresh + proactive refresh before expiresAt (#5635) by @ToddHebebrand in #6256
- fix(agents): keep the agent rate limiter out of the held request transaction (#6130) by @ToddHebebrand in #6258
- feat(auth): Admin → Users MFA status column (enrolled/pending/overdue) (#5690) by @ToddHebebrand in #6257
- chore(redis): pin ioredis clients to RESP2 wire protocol by @ToddHebebrand in #5838
- chore(deps): bump monaco-editor 0.55 -> 0.56 by @ToddHebebrand in #5840
- chore(deps): bump Anthropic SDKs and add dependabot anthropic group by @ToddHebebrand in #5821
- chore(deps): firebase-admin 13 → 14 by @ToddHebebrand in #5851
- chore(deps): bump @playwright/test from 1.62.1 to 1.63.0 in /e2e-tests by @dependabot[bot] in #5793
- chore(api): bump @peculiar/x509 1 -> 2 by @ToddHebebrand in #5839
- chore(deps): cron-parser 4 → 5 (devDependency) by @ToddHebebrand in #5858
- chore(deps): archiver 7 → 8 (+ @types/archiver 8) by @ToddHebebrand in #5845
- feat(scripts): reconciliation sweeper for proposals stuck in executed (#5641) by @ToddHebebrand in #6076
- refactor(api): resource-agnostic copy for the partner-wide write denial by @ToddHebebrand in #6293
- refactor(api): render device memory through the shared untrusted-text helpers by @ToddHebebrand in #6294
- fix(api): verify the request database role on every startup by @ToddHebebrand in #6295
- feat(web): W05 sending domains settings tab, E2E and docs (#6185) by @ToddHebebrand in #6208
- feat(portal): hardware lifecycle as a tab on Devices; square quarter timeline with shared today rule by @ToddHebebrand in #5984
- fix(scripts): AI assistant fails on imported .ps1 (null category); import success screen by @ToddHebebrand in #6005
- feat(accounting): pull QuickBooks addresses into the org and default site on mapping confirm+sync (#5073) by @ToddHebebrand in #6080
- fix(auth): pin the MFA-assured-session contract; bound invite orgIds to the caller partner (Strix scan) by @ToddHebebrand in #6299
- docs(security): MFA-by-default for new partners + device move-org step-up specs and plans by @ToddHebebrand in #6307
- refactor(api): one shared table for non-routable IP ranges by @ToddHebebrand in #6296
- chore(security): resolve open Dependabot/Trivy alerts and clean up CodeQL noise by @ToddHebebrand in #5938
- refactor(exports): single CSV escaper, applied to header rows too by @ToddHebebrand in #6297
- ci: gate the iOS simulator build on the mobile dependency closure; shard Test Web 4 ways by @ToddHebebrand in #6300
- test(web): fix the TenantVariablesPage coalesced-callers merge-queue flake by @ToddHebebrand in #6311
- fix(tickets): partner_id follows the org on device move; assignee re-validated; header-path requester binding (#5551) by @ToddHebebrand in #6075
- feat(auth): mfa_src assurance-source JWT claim across all mint and carry-forward sites by @ToddHebebrand in #6309
- chore(deps): group dependabot docker digest and Go agent bumps by @ToddHebebrand in #6313
- fix(automation): re-check device organization at dispatch and cancel CIS remediation on org move (SEC-118) by @ToddHebebrand in #5562
- feat(auth): require MFA by default for new partners + MfaPolicyOffBanner (#6306) by @ToddHebebrand in #6308
- feat(accounting): sync confirmed QuickBooks mappings server-side via a queue job and a 15-minute sweep (#5098) by @ToddHebebrand in #6082
- ci: shard integration tests 8→16, Test API 4→8 by @ToddHebebrand in #6314
- fix(bmr/rebuild): a system_image rebuild can no longer report completed with no OS state applied by @ToddHebebrand in #6316
- feat(devices): move-org requires an interactive session and a device_move_org step-up grant (W01 #6302) by @ToddHebebrand in #6310
- ci: gate heavy jobs per application area via the changes classifier by @ToddHebebrand in #6315
- D18 W04: reclamation proven on MinIO (R4/R5/R6), lease floor above helper margin, compose knob mapping by @ToddHebebrand in #6323
- feat(devices): curated device tab row with attention counts and grouped More menu by @ToddHebebrand in #6259
- chore(deps): bump the go-minor-patch group in /agent with 4 updates by @dependabot[bot] in #6318
- feat(bare-metal): W05a — vhdx engine target, bare_metal_rebuild command, recovery service, Restore-as-VM Linux guest images by @ToddHebebrand in #6320
- chore(deps): bump the github-actions group across 1 directory with 2 updates by @dependabot[bot] in #6277
- chore(deps): bump vitest from 5.0.0 to 5.0.1 in /e2e-tests by @dependabot[bot] in #6271
- chore(deps): bump @types/node from 26.5.1 to 26.6.1 in /e2e-tests by @dependabot[bot] in #6272
- chore(deps): bump the aws-sdk group across 1 directory with 3 updates by @dependabot[bot] in #6273
- feat(api): stable error codes on auth + users routes (i18n phase 3, wave E1) by @fabicarvano in #6317
- docs(security): YARA IOC scanning and live security policy design spec (#6263) by @ToddHebebrand in #6269
- feat(mobile): Android release signing, versionCode, and Google Play submission runbook by @ToddHebebrand in #5969
- feat(api): let partner service principals write contract contents by @advenimus in #6087
- feat(bare-metal): W05b — DR BARE_METAL_REBUILD step (rehearsal to VHDX, failover by code), DR editor step types by @ToddHebebrand in #6321
- feat(ticketing): laid-out HTML templates for customer ticket emails by @advenimus in #6088
- docs(billing): billing profiles + work types — approved spec and W01–W04 plans (#4628, #4615) by @ToddHebebrand in #6325
- docs: Disk Cleanup v2 spec + plan index + five wave plans (#6326) by @ToddHebebrand in #6336
- feat(email): customizable quote, invoice, and portal-invite templates by @advenimus in #6089
- feat(ai): A-W02 registry metadata — domain/searchHint/alwaysLoad, SDK meta from the registry, generated prompt tool index by @ToddHebebrand in #6341
- feat(ai): A-W01 baseline and harness — per-surface SDK capture, golden tool-selection eval, tool-usage report, baseline doc by @ToddHebebrand in #6345
- qa: pre-release sweep v0.114.0 → main pass 1 — 2 fixes, 17 paper cuts, tracking doc by @ToddHebebrand in #6340
- Disk Cleanup v2 W01: correctness and hardening (#6326) by @ToddHebebrand in #6346
- feat(billing): W01 — work types + dry-run conversion report (#4628, #4615) by @ToddHebebrand in #6347
- Disk Cleanup v2 W02: multi-volume (#6326) by @ToddHebebrand in #6360
- fix(ai): stop tool-output redactor wiping non-secret keys (#6140) by @ToddHebebrand in #6324
- docs(monitoring): alerting consolidation — spec, diagrams and six wave plans (#6367) by @ToddHebebrand in #6374
- feat(topology): add canonical graph foundation (#5996) by @ToddHebebrand in #6028
- qa: pre-release sweep v0.114.0 → main pass 2 — tracking doc (no code changes) by @ToddHebebrand in #6383
- docs(monitoring): alerting consolidation D21 — delivery eligibility without SECURITY DEFINER by @ToddHebebrand in #6384
- fix(monitors): resolveMonitorsForDevice honours assignment role/OS filters (#6344) by @ToddHebebrand in #6377
- fix(monitors): monitors of kind offline fire through the offline-transition path (#6342) by @ToddHebebrand in #6378
- fix(monitors): restart_service response survives normalization and drives the agent watch (#6343) by @ToddHebebrand in #6380
- Disk Cleanup v2 W03: tab completion and consolidation (#6326) by @ToddHebebrand in #6366
- feat(alerts): W05a PR 1 — freeze legacy alert authoring, Create monitor + Recommended on the policy Monitors tab (#6368) by @ToddHebebrand in #6381
- docs(monitoring): alerting consolidation D22–D27 — contracts as implemented after the W05b review rounds by @ToddHebebrand in #6388
- test(web): MonitorsListPage waits for a fetched row, not the page shell (flake) by @ToddHebebrand in #6389
- feat(alerts): W05b PR 1 — one delivery resolver, explicit "Everything else" routing rows, all-channels fallback removed (#6369) by @ToddHebebrand in #6385
- feat(alerts): W05b PR 2 — Delivery page (Channels · Routing · Escalation policies), old URLs redirect (#6369) by @ToddHebebrand in #6387
- feat(alerts): W05b PR 3 — delivery preview, Notify shows the resolved answer, manage_delivery AI tool, docs (#6369) by @ToddHebebrand in #6390
- feat(alerts): W05a PR 2 — routing API rejection pinned, legacy docs notices, 09-08 spec superseded (#6368) by @ToddHebebrand in #6392
- feat(monitors): W05c1 PR 1 — composite kind, restart parameters, consecutiveFailures 100, monitors-link inheritance, resolver honours replace (#6370) by @ToddHebebrand in #6394
- feat(monitors): W05c1 PR 2 — conversion ledger tables, retirement columns, retired rows excluded everywhere (#6370) by @ToddHebebrand in #6395
- feat(topology): logical maps, shared templates, layout and explicit diagnostics (#5997) by @ToddHebebrand in #6115
- docs(monitoring): alerting consolidation D28–D29 + CLAUDE.md org-merge registry row by @ToddHebebrand in #6402
- feat(web): Move to Organization dialog with server-driven step-up (W02 #6303) by @ToddHebebrand in #6400
- fix(topology): purge a deleted device's collection evidence once its withdrawal is published (#6116) by @ToddHebebrand in #6129
- Disk Cleanup v2 W04: OS-native cleaners (#6326) by @ToddHebebrand in #6386
- ci(topology): run the production-browser gate when topology or web build files change (#6117) by @ToddHebebrand in #6119
- fix(ai): tool capture/eval harness sends each surface's production system prompt by @ToddHebebrand in #6405
- fix(monitors): network_check compiler writes expectedStatus, the key the agent reads (#6352) by @ToddHebebrand in #6409
- fix(monitors): network_check raises one alert per check on its alert device, online or not (#6353) by @ToddHebebrand in #6410
- feat(billing): W02 — billing profiles cut-over: Rates screen, resolver, stamping, conversion, override gate (#4628) by @ToddHebebrand in #6393
- fix(web): move-org site picker asks for the route's full page of sites by @ToddHebebrand in #6411
- feat(mcp): B-W01 additive spec catch-up — version negotiation, title/annotations/_meta, structuredContent, dormant pagination by @ToddHebebrand in #6406
- fix(auth): dedicated ai_sessions:use permission so org roles can open AI chat (#6396) by @ToddHebebrand in #6399
- chore(deps): bump @sentry/cli 2.58.4 -> 3.7.0 (apps/mobile) by @ToddHebebrand in #5844
- feat(ai-tools): A-W06 agent-first coverage burn-down — 13 Tier-1 reads + MCP_COVERAGE contract by @ToddHebebrand in #6414
- docs(mobile): link the iOS App Store listing (#3892) by @ToddHebebrand in #6417
- fix(bare-metal): W05 lab-proof defects — mounted-image convert, unsized VHDX target, refused status by @ToddHebebrand in #6404
- chore(mobile): bump the marketing version to 1.0.1 by @ToddHebebrand in #6419
- fix(web): show device names instead of {{device}} in alert titles by @advenimus in #6114
- chore(auth): bump @simplewebauthn/server + /browser 13 -> 14 by @ToddHebebrand in #5847
- chore(mobile): bump @sentry/react-native 7 to 8 by @ToddHebebrand in #5841
- feat(monitors): W05c1 PR 3 — the converter: preview, equivalence, ledger lifecycle, routes, onboarding (#6370) by @ToddHebebrand in #6416
- fix(helper): derive status path from session config and add agent fallback by @mvthul in #6032
- Billing Profiles W03: minimums and rounding land on time entries (#4628) by @ToddHebebrand in #6422
- fix(bare-metal): refuse recovery for snapshots that reference older snapshots' objects (interim guard for #6403) by @ToddHebebrand in #6469
- fix(agent): resolve the trash directory without depending on $HOME (#6413) by @ToddHebebrand in #6418
- fix(mcp): flag pure returned tool errors as isError and ledger them as failures (#6408) by @ToddHebebrand in #6420
- fix(web): stop the MonitorEditor owner-scope hydration mismatch (#6391) by @ToddHebebrand in #6421
- fix(api): fail a backup job loudly when the strict queue schema rejects its result (#5413) by @ToddHebebrand in #6424
- fix(agent/backup): stop duplicating the system-state failure reason in errorLog (#5415) by @ToddHebebrand in #6425
- fix(agent): 16 MiB+ uploads to MinIO over HTTPS, and verification of an incomplete snapshot (#6350) by @ToddHebebrand in #6427
- fix(config-policy): schema-validate
maintenanceinlineSettings on the feature-link route (#6312) by @ToddHebebrand in #6428 - fix(agent): skip the doomed HTTP result submission for WS-direct backup_run (#5414) by @ToddHebebrand in #6429
- fix(agent): preserve and restore Windows Hidden/System/Sparse file attributes (#5407) by @ToddHebebrand in #6430
- fix(agent,web): persist a terminal BMR failure reason; filter template/oneshot units in the service probe (#5479) by @ToddHebebrand in #6431
- fix(deploy): give the bundled coturn a certificate so TURNS on 5349 works (#6163) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/6432
- fix(backup): hold an active chain's full snapshot against retention (#5421) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/6433
- fix(dr): name the missing prerequisite on execute; stop half-applying plan saves (#6382) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/6440
- fix(agent): anchor fully-literal cleanup rules above the target (#6375) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/6448
- docs(redis): keep noeviction, correct the allkeys-lru claim, document recovery (#6249) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/6450
- fix(web): mount the file Restore Wizard so restores are not API-only (#6349) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/6453
- fix(web): surface reclaimable size and scan confirmation in disk cleanup (#6376) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/6454
- fix(ai-agents): refuse tier-2 fleet users-FK writes for agent principals (#6206) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/6455
- fix(ai): atomic budget reservations for /client-ai and warm technician sessions (#5557) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/6458
- fix(web): page site and org pickers to exhaustion instead of one server page (#6412) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/6459
- fix(billing): preview the inherited tax rate on draft invoices (#6338) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/6423
- fix(api): enqueue the SNMP immediate poll after the request transaction commits (#6337) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/6426
- fix(api): give whole-machine restores a 24h ceiling instead of a 60-minute reap (#6415) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/6434
- feat(ai): Disk Cleanup v2 W05 — system_cleanup AI/MCP tool, docs parity, release notes by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/6442
- fix(api): close the DR reconcile and bare-metal in-flight races (#6322) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/6451
- docs(plans): W09 — token-mode recovery follows cross-snapshot object references (#6464) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/6481
- fix(api): let incremental backups pick a base that expires inside the publish lease (#6351) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/6439
- feat(bare-metal): server-side manifest index + exact-membership authorization for cross-snapshot references (W09a, part of #6464) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/6487
- qa: pre-release sweep v0.114.0 → main pass 3 — 9 fixes + tracking doc by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/6502
- fix(api): helper auth honours device-credential lifecycle; partner trust review requires partner-wide manage access by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/6507
- fix(agent): render script parameters as data in every shell and interpreter frame by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/6508
- qa: v0.114.0 → main live-agent lab pass — 2 fixes (BMR hydration jobId, PAM gate scope), What's New 0.115.0, tracking doc by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/6512
New Contributors
- @advenimus made their first contribution in #6087
Full Changelog: v0.114.0...v0.115.0