<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves #
- Adds hash_sha256 field to host installer result and install software
activity so they can be used in combination to cover past activities
with existing installers + all new activities even if their installer
will get deleted
# Checklist for submitter
## Testing
- [x] Added/updated automated tests
- [ ] Where appropriate, [automated tests simulate multiple hosts and
test for host
isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing)
(updates to one hosts's records do not affect another)
- [x] QA'd all new/changed functionality manually
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Software installation results now include the installer’s SHA-256 hash
when available.
* Installed-software activity records now include the corresponding
`hash_sha256` value.
* **Bug Fixes**
* Hash values are retained in activity history after an installer is
deleted, while live results correctly show the value as unavailable.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#48399
Summary:
- Allows multiple installers for the same title to be defined in a yaml
file
- `generate-gitops` generates a file like this if multiple installers
are available per title
- Allows labels, self_service, categories keys to be defined per package
- Inherits fleet-level keys only if they are not set at the
package-level
- Repoints policies.software_installer_id for a deleted installer to
either the first added installer for that title, or NULL if none are
available
# Checklist for submitter
If some of the following don't apply, delete the relevant line.
- [ ] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.
- [ ] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements), JS
inline code is prevented especially for url redirects, and untrusted
data interpolated into shell scripts/commands is validated against shell
metacharacters.
- [ ] Timeouts are implemented and retries are limited to avoid infinite
loops
- [ ] If paths of existing endpoints are modified without backwards
compatibility, checked the frontend/CLI for any necessary changes
## Testing
- [x] Added/updated automated tests
- [ ] Where appropriate, [automated tests simulate multiple hosts and
test for host
isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing)
(updates to one hosts's records do not affect another)
- [x] QA'd all new/changed functionality manually
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* GitOps output now supports software titles that contain multiple
packages, generating a dedicated package file plus related assets.
* Software imports and updates now preserve package order and handle
multi-package titles more consistently.
* **Bug Fixes**
* Improved inheritance and validation for software fields so
package-level settings are respected and conflicting settings are
flagged.
* Fixed installer batch updates to better handle added, removed, and
reordered packages without disrupting related policies or pending
installs.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
**Related issue:** Resolves#48398
Applies first-added-wins install precedence everywhere a host can match
more than one package of a software title: manual install, self-service,
policy auto-install, setup experience, and the host-software read all
resolve the first-added package the host is in label scope for. Policy
automations can now target a specific package (defaulting to
first-added), and deleting a package re-points its automations to the
first-added surviving package.
# Checklist for submitter
- [x] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements).
## Testing
- [x] Added/updated automated tests
- [x] Where appropriate, [automated tests simulate multiple hosts and
test for host
isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing)
(updates to one hosts's records do not affect another)
- [x] QA'd all new/changed functionality manually
**Related issue:** Resolves#48397
## Summary
Adds the REST API layer for multiple custom packages per software title
(backend only):
- `GET /software/titles` and `GET /software/titles/:id` return a new
`packages[]` array; `software_package` is retained as the first-added
package for backwards compatibility.
- `POST /software/package` adds a package to an existing title and
returns the added package.
- `PATCH /software/titles/:id/package` targets a specific `installer_id`
and rejects a replacement whose hash matches a sibling package (409).
- `DELETE /software/titles/:id/available_for_install?installer_id=`
deletes one package; omitting `installer_id` deletes them all.
Builds on the data-model foundation (#48396). Install-time precedence
and the host-software endpoint are out of scope (#48398).
# Checklist for submitter
- [ ] Changes file added for user-visible changes in `changes/`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.
- [x] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements).
- [x] If paths of existing endpoints are modified without backwards
compatibility, checked the frontend/CLI for any necessary changes.
## Testing
- [x] Added/updated automated tests
- [x] QA'd all new/changed functionality manually
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#48396
# Checklist for submitter
If some of the following don't apply, delete the relevant line.
- [ ] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.
- [ ] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements), JS
inline code is prevented especially for url redirects, and untrusted
data interpolated into shell scripts/commands is validated against shell
metacharacters.
- [ ] Timeouts are implemented and retries are limited to avoid infinite
loops
- [ ] If paths of existing endpoints are modified without backwards
compatibility, checked the frontend/CLI for any necessary changes
## Testing
- [x] Added/updated automated tests
- [ ] Where appropriate, [automated tests simulate multiple hosts and
test for host
isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing)
(updates to one hosts's records do not affect another)
- [x] QA'd all new/changed functionality manually
## Database migrations
- [x] Checked schema for all modified table for columns that will
auto-update timestamps during migration.
- [x] Confirmed that updating the timestamps is acceptable, and will not
cause unwanted side effects.
- shouldn't update timestamps unless the installer was a duplicate
- [x] Ensured the correct collation is explicitly set for character
columns (`COLLATE utf8mb4_unicode_ci`).
## New Fleet configuration settings
- [ ] Setting(s) is/are explicitly excluded from GitOps
If you didn't check the box above, follow this checklist for
GitOps-enabled settings:
- [ ] Verified that the setting is exported via `fleetctl
generate-gitops`
- [ ] Verified the setting is documented in a separate PR to [the GitOps
documentation](https://github.com/fleetdm/fleet/blob/main/docs/Configuration/yaml-files.md#L485)
- [ ] Verified that the setting is cleared on the server if it is not
supplied in a YAML file (or that it is documented as being optional)
- [ ] Verified that any relevant UI is disabled when GitOps mode is
enabled
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Software titles can now include multiple custom packages without
duplicating the title in lists.
* Added clearer package details when viewing software tied to a title or
team.
* **Bug Fixes**
* Improved installer conflict handling so uploads now show more specific
error messages.
* Prevented duplicate package entries from creating extra title rows or
incorrect counts.
* Fixed package counting and selection so the first-added package is
used consistently when multiple exist.
* **Chores**
* Added database changes to enforce the new package-deduplication
behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#48054
Changes:
- Changes batch add installer path to reuse
`getOrGenerateSoftwareInstallerTitleID`
- Adds migration to retroactively fix duplicate titles created by this
bug
# Checklist for submitter
If some of the following don't apply, delete the relevant line.
- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.
- [ ] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements), JS
inline code is prevented especially for url redirects, and untrusted
data interpolated into shell scripts/commands is validated against shell
metacharacters.
- [ ] Timeouts are implemented and retries are limited to avoid infinite
loops
- [ ] If paths of existing endpoints are modified without backwards
compatibility, checked the frontend/CLI for any necessary changes
## Testing
- [x] Added/updated automated tests
- [ ] Where appropriate, [automated tests simulate multiple hosts and
test for host
isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing)
(updates to one hosts's records do not affect another)
- [x] QA'd all new/changed functionality manually
## Database migrations
- [x] Checked schema for all modified table for columns that will
auto-update timestamps during migration.
- [x] Confirmed that updating the timestamps is acceptable, and will not
cause unwanted side effects.
- The tables will actually be updated, so it makes sense for that to
change if it happens
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Resolved a case where GitOps uploads of Windows software could create
duplicate software titles when a host had already reported the same
program.
* Improved deduplication and reassociation so related records
(installers and icons) are merged into the retained title, preserving
the correct upgrade code.
* **Tests**
* Added regression coverage for the duplicate-title scenario to prevent
future repeats.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Refines the opening to better frame the core argument, adds a new “Key
takeaways” section summarizing the main data-backed points, and
introduces stronger calls to action. This update improves scannability
and ties the article’s thesis to clear next steps around
code-first/GitOps workflows.
Reworked the article opening into a stronger narrative with a new key
takeaways section and an early CTA to deploy Santa with Fleet. Updated
wording to align on Fleet agent/Santa tables terminology, moved
deployment-series links into the setup section, and tightened copy
around monitoring guidance and telemetry setup. Added a new "See it
live" closing section with demo/training CTAs, and refined the meta
description text.
Automated ingestion of latest Fleet-maintained app data.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Updated app metadata for several maintained apps so install status
checks and download links point to the latest releases.
* Refreshed installer checksums to match the new versions.
* Bumped supported versions for Bruno, CLion, Dangerzone, Dot, IntelliJ
IDEA, Merlin Project, Raycast, Rider, and RubyMine.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: allenhouchins <32207388+allenhouchins@users.noreply.github.com>
- @noahtalerman: For the following quick win:
- #40074
---------
Co-authored-by: Kilo Code <kilo@fleetdm.com>
Co-authored-by: kiloconnect[bot] <240665456+kiloconnect[bot]@users.noreply.github.com>
## Summary
- Adds a new "Auto update [software name] on [platform]" section to
every software catalog detail page
- The heading and content are dynamically generated based on the app's
name and platform (macOS/Windows)
- Provides SEO-friendly `<h3>` headings with relevant
autopatch/auto-update keywords for each software title
- Includes a brief description explaining Fleet's automatic patching
capability and links to autopatch documentation
## Changes
- `website/views/pages/docs/app-details.ejs` — Added new `app-autopatch`
section with dynamic heading and two descriptive paragraphs
- `website/assets/styles/pages/docs/app-details.less` — Added styling
rule for the new section
## How it works
Since all software catalog pages (e.g.,
`/software-catalog/7-zip-windows`, `/software-catalog/1password-darwin`)
use the same EJS template, the new section automatically appears on
every page with the correct app name and platform filled in dynamically
via `thisApp.name` and `thisApp.platform`.
---
Built for [Mike
McNeil](https://fleetdm.slack.com/archives/C02TYJF11P0/p1782856622694079?thread_ts=1781135930.086429&cid=C02TYJF11P0)
by [Kilo for Slack](https://kilo.ai/slack)
---------
Co-authored-by: kiloconnect[bot] <240665456+kiloconnect[bot]@users.noreply.github.com>
Co-authored-by: Eric <eashaw@sailsjs.com>
**Related issue:** Resolves NA (release hygiene — migration ordering)
## What & why
The `4.88.0` patch cherry-picked two migrations,
`20260624210253_AddHostMDMAppleEnrollmentPermissions` and
`20260624210311_RenamePersonalEnrollmentStatus`. Eight migrations on
`main` were **not** cherry-picked into 4.88 but had **earlier**
timestamps than those two:
| Old timestamp | Migration |
|---|---|
| 20260611202649 | AddWindowsMDMConfigProfilesPendingDelete |
| 20260615135619 | AddSetupExperienceSoftwareInstallers |
| 20260617172853 | CreateSoftwareTitleTeamPins |
| 20260617194413 | AddAndroidProfileVariableTracking |
| 20260622124714 | AddPolicyGateToSetupExperienceResults |
| 20260622124734 | AddBYODFleetAndADUEEnrollment |
| 20260623140135 | AddSupportSoftwareCategory |
| 20260624152755 | AddCertAndAndroidAppVariableTracking |
This violates the rule in
`docs/Contributing/workflows/releasing-fleet.md`:
> Any migrations that are not cherry-picked in a patch must have a
_later_ timestamp than migrations that were cherry-picked.
Left as-is, a customer on `4.88.0` (who applied migrations through
`20260624210311`) upgrading to `4.89.0` would hit these 8 as
out-of-order/missing migrations older than their highest-applied
version.
## Fix
Bumped the 8 non-cherry-picked migrations to new timestamps
(`20260702013055`–`20260702013102`) using `tools/bump-migration`,
**preserving their relative order**, so they now sort after the
cherry-picked migrations and
`20260626120000_CompressWindowsMDMResponsesColumn`. Regenerated
`schema.sql`.
Verified `20260626120000_CompressWindowsMDMResponsesColumn` (the only
other non-cherry-picked migration, already correctly ordered) touches
only `windows_mdm_responses` — none of the 8 moved migrations touch that
table, so no dependency inversion is introduced by the reorder. None of
these 10 migrations shipped in `4.87.1`, so no released database is
affected.
`rc-patch-fleet-v4.88.0` needs no change. This lands on `main` and
should be reflected on `rc-minor-fleet-v4.89.0`.
# Checklist for submitter
## Database migrations
- [x] Migration files renamed via `tools/bump-migration`; function names
updated to match new timestamps.
- [x] Regenerated `schema.sql` via `make dump-test-schema`; migrations
apply cleanly in the new order.
- [x] No schema/content changes to the migrations themselves — timestamp
renumber only.
## Testing
- [x] `go build ./server/datastore/mysql/migrations/...` and `go vet`
pass; schema regeneration ran all migrations successfully in order.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added support for additional device/profile tracking across Android,
Apple, Windows, certificates, and apps.
* Added new setup and software management records, including support
software categories and team pins.
* Added a policy-gating flag for setup experience results.
* **Bug Fixes**
* Improved database consistency with stronger uniqueness and
cascade-delete behavior.
* Updated schema tracking so migrations apply cleanly with the latest
database state.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
**Related issue:** NA
# Checklist for submitter
Adds the four current product group tech leads as required reviewers
(CODEOWNERS) for the `.claude/` directory.
- MDM → @JordanMontgomery
- Software → @cdcme
- Orchestration → @lucasmrod
- Security & Compliance → @mostlikelee
## Testing
- [x] QA'd all new/changed functionality manually
CODEOWNERS-only change; no code, tests, migrations, config settings, or
fleetd changes.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Chores**
* Added explicit ownership and review coverage for the Claude Code
configuration area.
* Changes within the configuration directory now require designated
reviewers before being merged.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
- [x] QA'd all new/changed functionality manually
For the following bug:
- https://github.com/fleetdm/fleet/issues/48487
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Style**
* Updated dashboard chart card header tooltip styling for better
alignment and cleaner vertical centering.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Automated ingestion of latest Fleet-maintained app data.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Updates**
* Refreshed app package metadata for several maintained apps to the
latest versions on macOS and Windows.
* Included updated download links and checksums so installers match the
new releases.
* Improved version checks so the app status correctly reflects the newer
installed versions.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: allenhouchins <32207388+allenhouchins@users.noreply.github.com>
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#47388
I'll be doing some separate research on how agent options ends up as
`null` in the first place.
Obviously you can set `config:` in the agent options and hit `Save` and
the issue is reproduced but seems unlikely (one theory is GitOps doing
some overriding).
# Checklist for submitter
- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.
## Summary
`GetClientConfig` (`server/service/osquery.go`) panicked with
`assignment to entry in nil map` (returning 5XX on
`/api/v1/osquery/config`) when a host's resolved agent options had a
null `config`.
Root cause: `config` is initialized as an empty map, but
`json.Unmarshal([]byte("null"), &config)` silently sets the map to `nil`
(no error). When the host also had packs or scheduled queries, the later
`config["packs"] = ...` assignment panicked.
This adds a nil-guard that re-initializes the map after the unmarshal.
## Testing
- [x] Added/updated automated tests
Added `TestGetClientConfigNullConfig`, which sets `{"config":null}`
agent options plus a pack and asserts no panic/error and that `packs`
still serialize correctly.
- [x] QA'd all new/changed functionality manually
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Fixed a server crash that could occur when generating osquery
configuration for hosts with a null agent config.
* Improved config handling so hosts with packs and scheduled queries now
receive their configuration reliably, even when the base config is
empty.
* Added regression coverage to help prevent this issue from returning.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
…Fast-track responsibilities
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves #
# Checklist for submitter
If some of the following don't apply, delete the relevant line.
- [ ] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.
- [ ] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements), JS
inline code is prevented especially for url redirects, and untrusted
data interpolated into shell scripts/commands is validated against shell
metacharacters.
- [ ] Timeouts are implemented and retries are limited to avoid infinite
loops
- [ ] If paths of existing endpoints are modified without backwards
compatibility, checked the frontend/CLI for any necessary changes
## Testing
- [ ] Added/updated automated tests
- [ ] Where appropriate, [automated tests simulate multiple hosts and
test for host
isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing)
(updates to one hosts's records do not affect another)
- [ ] QA'd all new/changed functionality manually
For unreleased bug fixes in a release candidate, one of:
- [ ] Confirmed that the fix is not expected to adversely impact load
test results
- [ ] Alerted the release DRI if additional load testing is needed
## Database migrations
- [ ] Checked schema for all modified table for columns that will
auto-update timestamps during migration.
- [ ] Confirmed that updating the timestamps is acceptable, and will not
cause unwanted side effects.
- [ ] Ensured the correct collation is explicitly set for character
columns (`COLLATE utf8mb4_unicode_ci`).
## New Fleet configuration settings
- [ ] Setting(s) is/are explicitly excluded from GitOps
If you didn't check the box above, follow this checklist for
GitOps-enabled settings:
- [ ] Verified that the setting is exported via `fleetctl
generate-gitops`
- [ ] Verified the setting is documented in a separate PR to [the GitOps
documentation](https://github.com/fleetdm/fleet/blob/main/docs/Configuration/yaml-files.md#L485)
- [ ] Verified that the setting is cleared on the server if it is not
supplied in a YAML file (or that it is documented as being optional)
- [ ] Verified that any relevant UI is disabled when GitOps mode is
enabled
## fleetd/orbit/Fleet Desktop
- [ ] Verified compatibility with the latest released version of Fleet
(see [Must
rule](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/workflows/fleetd-development-and-release-strategy.md))
- [ ] If the change applies to only one platform, confirmed that
`runtime.GOOS` is used as needed to isolate changes
- [ ] Verified that fleetd runs on macOS, Linux and Windows
- [ ] Verified auto-update works from the released version of component
to the new version (see [tools/tuf/test](../tools/tuf/test/README.md))
Automated ingestion of latest Fleet-maintained app data.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Updated installer metadata and version checks for several maintained
apps on macOS and Windows.
* Refreshed download links and checksums to match the latest released
installers.
* Included version updates for AWS SAM CLI, Badgeify, BlueJ, Bruno,
Claude, CMake, Cyberduck, GitHub Desktop, Google Chrome, Opera, Postman,
Reqable, Rocket.Chat, and Splashtop Streamer.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: allenhouchins <32207388+allenhouchins@users.noreply.github.com>
Relates to #38670
The policies/:id/automation_activities endpoint derived the top-level
status for installed_software activities from the live
host_software_installs.status generated column. That column becomes NULL
when the install row is marked removed=1 (e.g. after the installer
package is edited/updated or the software is re-installed), so a
historically-successful install was miscategorized as "error".
Derive the outcome from the activity's recorded details.status instead,
which reflects the install result at the time the activity was created.
The install output still comes from host_software_installs. This applies
to both the displayed status and the ?status=error|success filter.
Also fixed alignment with the info icon on the policy automations table.
Fixes#48497
When a cron run's context was cancelled mid-flight (e.g. the instance
received SIGTERM during graceful shutdown), the stats row was left
"pending" because the terminal-status write failed on the cancelled
context. CleanupCronStats would later reap it to "expired", hiding the
fact that the run was interrupted and discarding the captured job
errors.
Record the terminal status on a context detached from cancellation
(context.WithoutCancel with a bounded timeout) so an interrupted run
persists its outcome. The run is marked "canceled" only when the context
was cancelled AND a job actually reported an error, so a run whose jobs
all finished cleanly is still "completed" even if cancellation merely
raced the end of the run.
Fixes#47303
GetQueryResultsCounts and IncrQueryResultsCounts pipelined commands
across multiple query_results_count:<id> keys on a single connection.
These keys have no hash tag, so in a Redis Cluster they scatter across
hash slots. A pipelined connection binds to the first key's slot, so
every other key returned a MOVED redirect, producing recurring error log
noise on host check-ins. IncrQueryResultsCounts additionally used
ConfigureDoer, whose RetryConn does not support Send, so increments
failed entirely in cluster mode.
Group the keys by hash slot with redis.SplitKeysBySlot and run one
pipeline per slot group, mirroring the existing QueriesForHost and
CleanupInactiveQueries patterns in the same file. The write path uses a
plain pooled connection (not ConfigureDoer) since all keys in a slot
group share a slot and no redirect handling is needed.
Automated ingestion of latest Fleet-maintained app data.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Updated package metadata for several maintained apps so the latest
versions are available on macOS and Windows.
* **Bug Fixes**
* Refreshed version checks, download links, and checksums across
multiple app entries to match newer releases.
* Included updates for AlDente, AWS CLI, ChatWise, Claude Desktop, DFU
Blaster Pro, Franz, GitHub Desktop, Google Gemini, Loom, OpenCode
Desktop, Signal, Unity Hub, WhatsApp, and Zed.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: allenhouchins <32207388+allenhouchins@users.noreply.github.com>
osquery [5.23.1](https://github.com/osquery/osquery/releases/tag/5.23.1)
was released by osquery publicly today, this updates our schema with the
changes in it.
- [X] QA'd all new/changed functionality manually
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Updated schema support for certificate `subject2` and `issuer2` fields
on Linux and macOS.
* Documentation generation and download tooling now target osquery
`5.23.1`.
* **Bug Fixes**
* Clarified the `process_open_handles` table behavior by removing
outdated default-process wording.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Automated ingestion of latest Fleet-maintained app data.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Improved uninstall reliability across many macOS apps, especially
where background services use wildcard-style launch service names.
* Uninstall cleanup now more accurately finds and removes matching
services and their related plist/config/log files.
* Added safer handling for cases like “no matching services found” and
more robust app shutdown during uninstall.
* **Updates**
* Updated maintained app definitions and installer/uninstaller script
references, including version refreshes for Dataflare, ElectronMail,
Granola, and JASP (and related Windows installer checksums).
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: allenhouchins <32207388+allenhouchins@users.noreply.github.com>
Co-authored-by: Allen Houchins <allenhouchins@mac.com>
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#48594
# Checklist for submitter
If some of the following don't apply, delete the relevant line.
- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.
- [x] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements), JS
inline code is prevented especially for url redirects, and untrusted
data interpolated into shell scripts/commands is validated against shell
metacharacters.
- [x] Timeouts are implemented and retries are limited to avoid infinite
loops
- [x] If paths of existing endpoints are modified without backwards
compatibility, checked the frontend/CLI for any necessary changes
## Testing
- [x] Added/updated automated tests
- [x] Where appropriate, [automated tests simulate multiple hosts and
test for host
isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing)
(updates to one hosts's records do not affect another)
- [x] QA'd all new/changed functionality manually
For unreleased bug fixes in a release candidate, one of:
- [x] Confirmed that the fix is not expected to adversely impact load
test results
- [x] Alerted the release DRI if additional load testing is needed
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Recovery-lock password checks now skip personally owned (BYOD) Apple
devices, avoiding failures on eligible hosts.
* Recovery-lock clear actions are no longer applied to personally owned
enrollments.
* **Tests**
* Added coverage to verify BYOD devices are excluded from both
recovery-lock enforcement and clear workflows.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Changes:
- Updated the ajax button component to support a `syncingMessage` prop,
a string that, when set, will be displayed with the button's loading
spinner.
- Updated the ajax button used on the "Talk to us" form to say "Looking
up availability…" when the form is submitted before a user is redirected
to a Calendly booking page.
- Product Designers attend respective product group retros instead
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Documentation**
* Updated the Product design sprint kickoff guidance to include clearer
steps for planning and capturing prioritized requests.
* Removed the end-of-sprint retro reminder from this ritual description.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Closes: https://github.com/fleetdm/confidential/issues/16603
Changes:
- Added a link going to the software catalog in the "Deploy software
your own way" section of the /software-management page.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added a new “View software” call-to-action on the software management
page, giving users a direct link to the software catalog.
* Updated the “Deploy software your own way” section to include an
additional way to explore available software options.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
**Related issue:** Resolves#48177
# Checklist for submitter
- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
## Testing
- [x] Added/updated automated tests
- [x] QA'd all new/changed functionality manually
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Style**
* Standardized action wording across the UI from “Create” to “Add” for
fleets, packs, users, and reports.
* Updated related labels in command palette items, empty states,
buttons, links, and modal titles to match the new terminology.
* **Tests**
* Updated UI tests to assert the revised button and link text in
affected fleet, host, and report flows.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
- [x] QA'd all new/changed functionality manually
For the following bug:
- https://github.com/fleetdm/fleet/issues/48564
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Style**
* Improved the alignment of an icon within a form field for more
consistent visual layout.
* Updated input text color to a darker tone for better readability and
contrast.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Update the remove_launchctl_service() function to properly handle
wildcard launchctl labels (e.g., 'com.elgato.StreamDeck*'). Wildcard
labels cannot be used directly with 'launchctl list' or as plist
filenames, so they must be expanded to concrete labels first. The
updated function matches the wildcard pattern as a regex against
currently-loaded services and removes each match individually, mirroring
Homebrew's approach. Adds test coverage for this behavior and
regenerates uninstall scripts for affected applications.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Improved uninstall reliability when apps use wildcard `launchctl`
service labels.
* Uninstall scripts now expand wildcard labels to the set of currently
loaded matching services, remove those services, and delete the related
LaunchAgents/LaunchDaemons plist files.
* If no matching services are found, cleanup exits gracefully.
* Applied to Stream Deck, Fantastical, Company Portal, Krisp,
Pearcleaner, and Wacom Tablet.
* **Tests**
* Added a regression test covering wildcard `launchctl` expansion during
uninstall.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
The Homebrew formulae API (served by GitHub Pages) intermittently
returns 5xx errors, which previously aborted the entire ingestion run.
This change adds smart retry logic with exponential backoff for
transient failures (network errors, 5xx/429 responses) while preserving
immediate failure for permanent errors (404, other 4xx).
Implementation:
- Created transientErr wrapper type to distinguish retryable from
permanent failures
- Wrapped fetchCask HTTP logic in retry.Do with configurable interval
and max attempts
- Added comprehensive tests verifying recovery after transient errors,
exhaustion of attempts, and non-retrying of 404s
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Improved reliability when fetching Homebrew casks by automatically
retrying temporary failures.
* Added smarter handling for rate limits and server/network errors,
while avoiding retries for missing apps.
* Made error messages from failed responses more concise and readable.
* **Tests**
* Added coverage to verify transient retry behavior, retry exhaustion
handling, and that “not found” responses are not retried.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Relates to #48549
The S3 carve cleanup (server/datastore/s3, run by the
cleanups_then_aggregation cron) advanced ListObjectsV2 pagination using
the response's ContinuationToken — an echo of the request token —
instead of NextContinuationToken. On any bucket with more than one page
of objects this looped forever, hanging the entire serial cleanup cron
and stalling every cleanup/aggregation job ordered after it.
Replace the bucket-listing reconciliation with a direct HeadObject probe
per carve, which is exact and independent of listing order or object
counts:
- Only carves older than 24h with a completed upload are reconciled
(mirrors the MySQL carve store's floor; skips in-flight multipart
uploads). A carve is expired only on a definitive not-found; transient
or other probe errors leave it for a future run, so a carve whose object
still exists is never expired.
- Probes run with bounded concurrency; expirations are written in one
batched, retryable UPDATE (new ExpireCarves datastore method) rather
than one per carve.
- The number of carves reconciled per run is capped so a large backlog
drains across runs without any single run making unbounded S3 requests.
Add S3-carve-store-only server settings (the MySQL carve store is
unaffected):
- s3.carves_cleanup_disabled — skip reconciliation entirely
- s3.carves_cleanup_max_per_run — per-run cap (default 1000)
- s3.carves_cleanup_concurrency — concurrent probes (default 32)
Also log the expired count per run and fix the test bucket cleanup
helper to paginate. Adds unit tests (transient-error safety, partial
failure, concurrency) and a MySQL integration test for ExpireCarves.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added new workstation labels for **Team: g-apple-at-work** and **Team:
g-auto-patching**.
* **Changes**
* Updated team label coverage by removing the older **Team: g-mdm** and
**Team: g-software** labels.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves #
# Checklist for submitter
If some of the following don't apply, delete the relevant line.
Unreleased bug, no changes file
- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.
- [x] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements), JS
inline code is prevented especially for url redirects, and untrusted
data interpolated into shell scripts/commands is validated against shell
metacharacters.
- [x] Timeouts are implemented and retries are limited to avoid infinite
loops
- [x] If paths of existing endpoints are modified without backwards
compatibility, checked the frontend/CLI for any necessary changes
## Testing
- [x] Added/updated automated tests
- [x] Where appropriate, [automated tests simulate multiple hosts and
test for host
isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing)
(updates to one hosts's records do not affect another)
- [ ] QA'd all new/changed functionality manually
For unreleased bug fixes in a release candidate, one of:
- [x] Confirmed that the fix is not expected to adversely impact load
test results
- [ ] Alerted the release DRI if additional load testing is needed
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Personal enrollment status is now preserved and updated correctly when
MDM device records change.
* macOS MDM ingestion now keeps the BYOD/personal enrollment flag for
Fleet devices instead of defaulting it away.
* Incoming server URLs continue to have query parameters removed while
still retaining the enrollment status used for processing.
* **Tests**
* Added coverage for personal enrollment updates and macOS ingestion
scenarios, including BYOD and non-BYOD cases.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
**Related issue:** N/A — internal update to the release-QA issue
template
# Description
Updates the **Release QA** issue template
(`.github/ISSUE_TEMPLATE/release-qa.md`) to match current product group
naming and to tighten the release-critical issue gate.
Changes:
- **Renamed product group sections** to match the working-group names in
`handbook/company/product-groups.md`: **MDM → Apple at Work** and
**Software → Auto Patching**.
- **Moved OS updates and disk encryption checks** out of Security &
Compliance to the platform-owning groups:
- macOS OS updates + disk encryption → **Apple at Work**
- Windows OS updates + disk encryption → **Power to PC**
- Linux disk encryption stays in **Security & Compliance**
- Per-section Fleet Free premium-gating lists updated to follow the
moves.
- **Consolidated the release-critical issue check** into a single "Ready
for release" gate covering both `~unreleased bug` (regressions
introduced during the cycle — the most critical to clear) and `~release
blocker` labels. Every such issue must have a milestone, an owner, and
be moved to "Ready for release" on its product group board before the
release can proceed.
- **Removed non-functional in-issue anchor links.** GitHub only
generates heading anchors when rendering Markdown as a repo
file/wiki/Discussion, not inside issue bodies, so the previous
`#notes`-style links silently did nothing once the template became an
issue.
# Checklist for submitter
- [ ] ~Changes file added for user-visible changes~ — N/A, internal QA
issue template only (no user-visible product change).
## Testing
This is a docs-only change to a GitHub issue template; no code paths are
affected.
- [x] QA'd all new/changed functionality manually (verified rendered
Markdown, section structure, and label-filter links).
Failures:
- WiX: https://github.com/fleetdm/fleet/actions/runs/28500663153
- fleetctl: https://github.com/fleetdm/fleet/actions/runs/28501229768
New runs:
- WiX: https://github.com/fleetdm/fleet/actions/runs/28521840457
- fleetctl: https://github.com/fleetdm/fleet/actions/runs/28521833124
Adds VEX exclusions for false-positive vulnerabilities flagged by the
scheduled Trivy scans of the `fleetdm/wix` and `fleetdm/fleetctl`
images.
**wix**
([run](https://github.com/fleetdm/fleet/actions/runs/28500663153)):
- `CVE-2026-8461` — ffmpeg libs (libavcodec61, libavformat61,
libavutil59, libswresample5); fleetctl does not process media files when
using fleetdm/wix.
- `CVE-2026-55199`, `CVE-2026-55200`, `CVE-2026-7598` — libssh2-1t64;
fleetctl does not establish SSH connections when generating MSI
packages.
**fleetctl**
([run](https://github.com/fleetdm/fleet/actions/runs/28501229768)):
- `CVE-2026-54512`, `CVE-2026-54513` —
com.fasterxml.jackson.core:jackson-databind; fleetctl does not use Java.
All statements are `not_affected` /
`vulnerable_code_not_in_execute_path`, consistent with existing VEX
entries in these directories. The scan workflows auto-glob the VEX
directories, so no workflow changes are needed.
# Checklist for submitter
- [x] QA'd all new/changed functionality manually (validated JSON;
mirrors existing VEX statements picked up by the scan workflow)
Automated ingestion of latest Fleet-maintained app data.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Updates**
* Updated the macOS app entries for Timing and WhatsApp to newer
versions.
* Refreshed the Timing download link and checksum to match the latest
release.
* Adjusted version checks so the apps are recognized correctly when
determining whether they need updates.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: allenhouchins <32207388+allenhouchins@users.noreply.github.com>