**Related issue:** N/A
# Checklist for submitter
- [x] N/A: this is a `.claude/skills` addition (Claude Code tooling),
not a user-visible product change. No `changes/` entry, tests,
migrations, config settings, or fleetd/orbit changes apply.
## Summary
Adds a `fleet-guide-formatting` skill that captures the concise,
step-by-step structure established across Fleet's best how-to guides
(`articles/` with `category: guides`): short problem statement,
prerequisites, inline gotcha callouts, task-based or numbered steps,
optional verify/troubleshoot sections, and endmatter. It gives:
- A skeleton and checklist for writing new guides.
- An audit checklist for retrofitting existing guides, including a
litmus test for content mistagged as `guides` when it's structurally an
article (no prerequisites, no concrete steps).
- A fill-in `references/template.md` to start new guides from.
- A `references/canonical-examples.md` breakdown of the structural
choices made in several existing guides.
This is scoped to structure only. Voice, grammar, and word choice remain
the responsibility of the existing `content-style` skill;
`content-types.md`'s "Guides and tutorials" section now points to this
skill for the full skeleton and audit checklist.
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#48486
# 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
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Apple MDM devices manually re-enrolled during a pending SCEP renewal
are now handled as a fresh enrollment, so enrollment steps run
correctly.
* Renewal and re-enrollment flows are now better distinguished, reducing
cases where profile or app setup could be skipped.
* Enrollment certificates now carry clearer markers to help the system
apply the right lifecycle 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:** Relates to #43544
The Fleet MCP server runs multi-host live queries by creating an ad-hoc
campaign via `POST /api/v1/fleet/reports/run`, but that route is missing
from the API endpoints catalog. An api-only user restricted to a
specific endpoint allowlist therefore cannot be granted it and receives
a 403, so multi-host live queries fail under a least-privilege setup.
This adds the route to the catalog so it can be granted; it stays gated
by observer_plus RBAC and does not match any allowlist-bypass blocklist
rule.
# 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.
## Testing
- [x] QA'd all new/changed functionality manually
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added support for an asynchronous live report run endpoint.
* API-only users on restricted allowlists can now be granted access to
run reports.
* **Changes**
* Updated the live report endpoint path and display name to reflect the
async behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Follow up PR for community PR:
https://github.com/fleetdm/fleet/pull/45712.
- [X] QA'd all new/changed functionality manually
<img width="1574" height="827" alt="Screenshot 2026-07-06 at 1 54 44 PM"
src="https://github.com/user-attachments/assets/672d7b84-155f-4dab-8246-fe88e391e416"
/>
<img width="1235" height="827" alt="Screenshot 2026-07-06 at 1 54 01 PM"
src="https://github.com/user-attachments/assets/51df3344-b002-45df-9cda-afa573652944"
/>
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* OS settings and disk-encryption views now correctly include Zorin
devices in Linux-related results.
* Host filtering counts now account for Zorin alongside other supported
Linux platforms.
* Updated related checks so Zorin devices are handled consistently in
status and encryption reporting.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
**Related issue:** Resolves#48077
Removes the admin/maintainer role gate from the "Show managed account"
host action so observers see it too. The backend
(`GetHostManagedAccountPassword`) authorizes any user who can read the
host, so observers can already retrieve the managed local account
password via the API — the UI gate only hid the action.
`canShowManagedAccount` now matches the other "show secret" host actions
(disk encryption key, Recovery Lock password), which are not role-gated;
the premium / macOS / connected-to-Fleet-MDM / ADE-enrollment /
managed-account-status conditions are unchanged.
Before (global observer, ADE-enrolled macOS host with a verified managed
account):
<img
src="https://raw.githubusercontent.com/raju249/fleet/screenshots-48077/before.png"
width="900" alt="Before: observer's Actions menu without Show managed
account" />
After (same host, same observer):
<img
src="https://raw.githubusercontent.com/raju249/fleet/screenshots-48077/after.png"
width="900" alt="After: observer's Actions menu with Show managed
account" />
# 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.
## Testing
- [x] Added/updated automated tests — two cases in the existing "Show
managed account action" block asserting the action renders for a global
observer and a team observer (they fail against the old gate).
- [x] QA'd all new/changed functionality manually — ran a local server
with a seeded ADE-enrolled macOS host carrying a verified managed local
account row; logged in as a global observer: the action was absent
before the change and present after (screenshots above), and opening the
modal shows the managed account credentials, matching what the API
already returns to observers.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Expanded access to the **Show managed account** action for users with
observer-level host read permissions.
* The managed account option now appears correctly for global observers
and team observers when other eligibility checks are met.
* Improved consistency between what the interface shows and what backend
permissions allow.
<!-- 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#41056
Follow-up documentation change for #41056. The unused Windows MDM STS
auth endpoint (`/api/mdm/microsoft/auth`) was removed in #48734, so this
removes it from the "what API endpoints to expose to the public
internet" guide:
- The "endpoints to expose" bullet in the Windows section, along with
its now-orphaned MS-MDE2 section 3.2 reference.
- The entry in the "these endpoints don't use mTLS" list.
Supersedes #41058, which removes the same two references but leaves the
section 3.2 sub-bullet dangling under `/api/mdm/microsoft/tos`.
# Checklist for submitter
- [x] QA'd all new/changed functionality manually (verified no remaining
`/api/mdm/microsoft/auth` references in the article and that the
surrounding lists render correctly).
Documentation-only change: no code, automated tests, database
migrations, Fleet configuration settings, or fleetd/orbit/Fleet Desktop
impact.
[Slack
thread](https://fleetdm.slack.com/archives/C072L58U878/p1783362669331309?thread_ts=1783362528.927249&cid=C072L58U878)
for context.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Updated the `Get /learn-more-about/uninstall-fleetd` redirect to send
visitors to the new uninstall guide location.
<!-- 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#48760
# 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.
## Testing
- [x] Added/updated automated tests
- [x] QA'd all new/changed functionality manually
## fleetd/orbit/Fleet Desktop
Note: changes are Windows only; only verified/tested these items for
Linux and Windows
- [x] 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))
- [x] If the change applies to only one platform, confirmed that
`runtime.GOOS` is used as needed to isolate changes
- [x] Verified that fleetd runs on macOS, Linux and Windows
- [x] Verified auto-update works from the released version of component
to the new version (see [tools/tuf/test](../tools/tuf/test/README.md))
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Fixed an issue where some Windows MDM enrollment sessions could stay
queued or fail to start on certain devices.
* Improved detection of active Windows MDM enrollment, helping commands
run more reliably when enrollment is already present.
* **Tests**
* Added coverage for Windows enrollment detection to prevent
regressions.
<!-- 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**
* Updated app installation metadata for several maintained apps on macOS
and Windows, including AWS VPN Client, Beekeeper Studio, Discord, Loom,
MacWhisper, and Superwhisper.
* Improved version detection and download references so supported app
records point to the latest available releases.
* Refreshed package checksums to match the updated installers.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: allenhouchins <32207388+allenhouchins@users.noreply.github.com>
Changes:
- updated the URL for the /gitops-workshop page to be /workshops, and
added a redirect
- Updated the workshops page to render cards for "Apple administrator
workshop" events
- Updated the content and layout of the /workshops page to match the
latest wireframes
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Launched a new **Workshops** page with a refreshed hero and
carousel-driven experience.
* Updated upcoming workshops to label event type (e.g., GitOps vs Apple
administrator) and display event details with correct links.
* **Bug Fixes**
* Updated routing so the new Workshops page is the primary destination.
* Kept the old workshop URL working by redirecting it to the new page
(and ensured the page remains accessible without needing to be signed
in).
<!-- 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 -->
Follow-up to #48817 (Gemini → Google Gemini rename).
Renames MacPaw's Gemini maintained app to "Gemini 2" (matching the
actual app, which installs as `Gemini 2.app`) and fixes the app icons
for both Gemini apps:
- `ee/maintained-apps/inputs/homebrew/gemini.json` and
`ee/maintained-apps/outputs/apps.json`: name and description updated to
"Gemini 2". The slug/token stays `gemini`.
- The existing `Gemini.tsx` frontend icon and the website's
`app-icon-gemini-60x60@2x.png` were actually Google's sparkle icon, so
MacPaw's app showed the wrong icon, and after #48817 "Google Gemini"
matched no icon key and fell back to the generic package icon.
- `Gemini.tsx` is renamed to `GoogleGemini.tsx`, and a new `Gemini2.tsx`
(generated from MacPaw's app bundle via
`tools/software/icons/generate-icons.sh`) is added.
- Icon map now resolves: `"gemini 2"` → MacPaw icon (FMA list + host
inventory), `"google gemini"` → Google sparkle (FMA list), `gemini` →
Google sparkle (host inventory, since Google's app installs as
`Gemini.app`).
- The website PNG for the `gemini` slug is replaced with MacPaw's icon;
`app-icon-google-gemini-60x60@2x.png` was already correct.
# Checklist for submitter
If some of the following don't apply, delete the relevant line.
- [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.
## Testing
- [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 the app listing to show **Gemini 2** instead of Gemini.
* Added support for the new Gemini 2 branding across app icons and
display labels.
* **Bug Fixes**
* Improved icon matching so Gemini-related entries display the correct
artwork and naming.
<!-- 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#48102
Changes:
- Renames `ExtractIPAMetadata` to `ExtractZIPMetadata` because the magic
bytes for zip based installers (.ipa, .msix, .zip, etc) are the same so
any zip file reaches it. If the zip does not contain an `Info.plist`
file it will now fail with `ErrInvalidType`.
- Did **NOT** make typeFromBytes return "zip" instead of "ipa" because
meta.Extension is set from that which has downstream effects.
- Added test files
The actual error message is still just "invalid file type".
# 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
- Tested adding a valid `.ipa`, a macos FMA that uses a .zip file
(alt-tab/darwin), and a windows FMA that uses a .zip file
(vnc-server/windows).
- Tested an msix file (renamed or not) cannot be uploaded or edited for
an existing msi installer
- Also tested the same things via GitOps
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Improved installer type detection so ZIP-based packages are less
likely to be misidentified.
* Fixed an error message that incorrectly referred to the wrong file
type when detection fails.
* MSIX packages are now reported more accurately when they don’t match
IPA parsing rules.
* **Refactor**
* Cleaned up installer metadata handling for ZIP-based archives.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
**Related issue:** Resolves#47977
# Checklist for submitter
- [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.
## 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
* **Bug Fixes**
* Updated the checkerboard chart so all future-timeframe cells render
with the “No data” styling, and their outlines align with the intended
visual treatment (including partially populated future slots).
* Ensured accessibility labels and tooltip/context for non-graded future
slots no longer suggest they are graded data.
* **Tests**
* Added regression coverage to verify “No data” styling and labeling for
the current “now” slot and the final future slot.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Updates the maintained app name from "Gemini" to "Google Gemini" in both
the input config and generated apps.json output, including the app
description.
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 release metadata for Cursor, Hive, OpenCode Desktop,
Postman, and Wavebox to reflect the latest available versions, download
links, and checksums.
* Adjusted installation status checks so these apps are detected
correctly after upgrading.
* Refreshed uninstall handling for Docker Desktop and Nova to use the
latest removal instructions.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: allenhouchins <32207388+allenhouchins@users.noreply.github.com>
**Related issue:** Resolves#43518
Adds a cross-platform alias `FLEET_MDM_ENABLE_DISK_ENCRYPTION`
(`mdm.enable_disk_encryption`) for the existing
`FLEET_MDM_ENABLE_CUSTOM_FILEVAULT` server configuration. When either
option is set, Fleet allows both custom Apple MDM profiles for FileVault
and custom Windows configuration profiles for BitLocker. Behavior
matches FileVault: no special conflict handling between Fleet's built-in
disk encryption controls and a custom profile. The setting remains Fleet
Premium only.
Both the single-add API/UI path and the batch/GitOps path are covered.
The existing `FLEET_MDM_ENABLE_CUSTOM_FILEVAULT` name continues to work
for backward compatibility.
Demo: https://www.youtube.com/watch?v=5naGaZKLZ8o
Docs: https://github.com/fleetdm/fleet/pull/48738/changes
# 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.
- [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.
## Testing
- [x] Added/updated automated tests
- [x] QA'd all new/changed functionality manually
## New Fleet configuration settings
- [x] Setting(s) is/are explicitly excluded from GitOps
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added a cross-platform disk encryption setting that can enable custom
management for both macOS FileVault and Windows BitLocker profiles.
* **Bug Fixes**
* Windows BitLocker profile uploads are now accepted when custom disk
encryption is enabled.
* Startup now disables custom disk encryption management when the
license does not support it, and logs a warning.
* **Tests**
* Added coverage for BitLocker profile handling with custom disk
encryption enabled and disabled.
<!-- 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#48805
# 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
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Preserve a user’s BYOD selection through IdP authentication so it no
longer gets lost mid-flow.
* Enrollment redirects to IdP SSO now retain the correct enrollment
query settings (including BYOD and fully managed) for consistent
enrollment behavior.
* **Tests**
* Added coverage to ensure the SSO initiation redirect preserves the
expected query parameters and returns the correct redirect response.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
**Related issue:** Resolves#48528
This keys the count, pagination, and the frontend row-combining on the
app's slug token (the prefix before `/`, shared across an app's platform
entries but distinct across apps). The count now equals the rows shown
in every view (macOS, Windows, All), and name-colliding apps stay as
separate rows.
# Checklist for submitter
- [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.
## Testing
- [x] Added/updated automated tests
- [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
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Software listings now group platform-specific installers into a single
app row based on the app identifier, improving how macOS and Windows
entries appear together.
* **Bug Fixes**
* Apps with the same display name but different identifiers now stay
separate instead of being merged incorrectly.
* List counts and pagination now match the combined app view more
accurately across the software pages.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This pull request improves the reliability and efficiency of the Winget
ingester by introducing robust retry logic for fetching manifest files
and directory contents, switching to CDN-backed raw file downloads, and
updating tests to cover these changes. The main focus is on handling
transient errors (like rate limits and server errors) gracefully,
preventing ingestion failures due to temporary issues with GitHub's API
or file servers.
**Reliability improvements for manifest fetching:**
* Added `getRawManifestFile` method to fetch manifest files directly
from `raw.githubusercontent.com` (or a testable override), avoiding
GitHub API rate limits and using CDN-backed downloads. This method
implements retry logic for transient HTTP errors (e.g., 429, 5xx), with
exponential backoff, and returns a specific error for missing files.
(`ee/maintained-apps/ingesters/winget/ingester.go`)
* Introduced `getRepoDirContents` method to list repository directories
via the GitHub API with retry logic for transient errors, improving
resilience against API throttling.
(`ee/maintained-apps/ingesters/winget/ingester.go`)
**Ingestion logic updates:**
* Updated `ingestOne` to use the new retry-enabled methods for both
directory listing and manifest file fetching, ensuring that only true
missing files are skipped and transient errors cause a controlled
failure, not silent downgrades.
(`ee/maintained-apps/ingesters/winget/ingester.go`)
[[1]](diffhunk://#diff-eb6c4ae7be41e61a2292c4240de750809d40c0686fb01f80f52df056ebc9c2a8L143-R270)
[[2]](diffhunk://#diff-eb6c4ae7be41e61a2292c4240de750809d40c0686fb01f80f52df056ebc9c2a8L182-R324)
**Test enhancements:**
* Modified test server and test cases to simulate the new raw file
fetching logic, including scenarios for retries, maximum attempts, and
handling of 404 errors. Added comprehensive tests for both
`getRawManifestFile` and `getRepoDirContents` retry behavior.
(`ee/maintained-apps/ingesters/winget/ingester_test.go`)
[[1]](diffhunk://#diff-c68f0564df3c6e38ad333d4ca6e1040305eb079eb0d168d29c95b1b250463055L509-R512)
[[2]](diffhunk://#diff-c68f0564df3c6e38ad333d4ca6e1040305eb079eb0d168d29c95b1b250463055L529-R678)
* Improved test reliability by reducing retry intervals for faster test
execution and using assertions for YAML marshaling and writing.
(`ee/maintained-apps/ingesters/winget/ingester_test.go`)
**Dependency and setup changes:**
* Added necessary imports for new functionality (`io`, `net/http`,
`net/url`, `time`, and `github.com/fleetdm/fleet/v4/pkg/retry`) and
updated struct initialization to support the new fields.
(`ee/maintained-apps/ingesters/winget/ingester.go`,
`ee/maintained-apps/ingesters/winget/ingester_test.go`)
[[1]](diffhunk://#diff-eb6c4ae7be41e61a2292c4240de750809d40c0686fb01f80f52df056ebc9c2a8R7-R25)
[[2]](diffhunk://#diff-eb6c4ae7be41e61a2292c4240de750809d40c0686fb01f80f52df056ebc9c2a8R52-R53)
[[3]](diffhunk://#diff-c68f0564df3c6e38ad333d4ca6e1040305eb079eb0d168d29c95b1b250463055R474-R475)
These changes make the Winget ingestion process more robust against
transient infrastructure issues and provide better test coverage for
error handling and retry logic.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Improved app ingestion resilience when GitHub returns transient
rate-limit or server errors, so a single failure no longer stops the
full import run.
* Added clearer handling for missing installer data: only genuine “not
found” responses now fall back to an older version, while other errors
are surfaced properly.
* **Tests**
* Added coverage for version fallback behavior and transient error
handling during ingestion.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Resolves#46461.
- [X] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
---
Verification command (checks how many times /proc/stat is read):
```
sudo bpftrace -e '
tracepoint:syscalls:sys_enter_openat
/str(args->filename) == "/proc/stat" || str(args->filename) == "/proc/uptime"/
{ @[comm, str(args->filename)] = count(); }
interval:s:60 { exit(); }'
```
1.57.0 outputs:
```
@[orbit, /proc/stat]: 1084
```
fleetd built with changes in this PR (and I had to trigger a restart,
otherwise it's 0):
```
@[orbit, /proc/stat]: 3
[...]
@[fleet-desktop, /proc/stat]: 6
```
## Testing
- [X] QA'd all new/changed functionality manually
## fleetd/orbit/Fleet Desktop
- [x] 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))
- [X] If the change applies to only one platform, confirmed that
`runtime.GOOS` is used as needed to isolate changes
- [X] Verified that fleetd runs on macOS, Linux and Windows
- [X] Verified auto-update works from the released version of component
to the new version (see [tools/tuf/test](../tools/tuf/test/README.md))
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Improved process listing performance on Linux by reducing repeated
system boot-time reads.
* Prevented unnecessary refreshes during frequent process checks,
helping watchdog-style polling run more efficiently.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
**Related issue:** Resolves#48418
Fixes the missing download button for custom software packages on the
software details page by gating the button on whether the package has a
downloadable installer file, rather than on the package's source URL
(which is empty for directly-uploaded custom packages).
# Checklist for submitter
## Testing
- [x] Added/updated automated tests
- [x] QA'd all new/changed functionality manually
<img width="1400" height="1000" alt="FIXED-custom-package-receipts"
src="https://github.com/user-attachments/assets/7be76a27-3f2f-463e-8cdd-481e6058be53"
/>
<img width="1400" height="1000" alt="FIXED-fma-010editor"
src="https://github.com/user-attachments/assets/5ba0aaa9-c15c-4e4a-bd5a-342e100d164e"
/>
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Updated library item download visibility to rely on an explicit
download permission, so the download button now appears only when
downloading is allowed.
* Aligned software page rows and stories with the new download behavior
across active library items.
* Refined related test coverage and examples to match the updated
download-button logic.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#41056
Docs: https://github.com/fleetdm/fleet/pull/48735/changes
# 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.
## Testing
- [x] QA'd all new/changed functionality manually
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Summary
* **Bug Fixes**
* Removed the obsolete Windows MDM authentication (unauthenticated STS)
endpoint; it now returns **HTTP 404**.
* Streamlined the Windows enrollment flow so only the supported
Microsoft MDM endpoints are exposed.
* **Testing**
* Added an integration test to confirm the removed endpoint remains
inaccessible.
* Removed now-irrelevant unit tests and helpers related to the deleted
authentication behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Surface the existing "Certificates" card on the host details page for
Windows hosts, with parity to macOS. Requires osquery 5.23.1 or higher.
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#31294
Demo video: https://www.youtube.com/watch?v=kGRp-YtnnJc
Docs: https://github.com/fleetdm/fleet/pull/48493/changes
# 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.
## 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
## 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.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Summary by CodeRabbit
* **New Features**
* Windows host certificates now display on the host details page (gated
by minimum agent/osquery version), including scope (**System** vs
**User**) and improved scope-aware certificates list details.
* **Bug Fixes**
* Certificate table labeling and help text are now platform-appropriate
(with “Keychain” renamed to “Scope”).
* Windows certificate reconciliation is more resilient, preserving
certificates for scopes not observed during a collection run and
preventing row collapsing when ids repeat across scopes.
* **Tests**
* Expanded coverage for Windows/malformed DN parsing and scope-aware
reconciliation.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
**Related issue:** Resolves#48530
Fixes wrong platform-title capitalization in the "Filtered" tag tooltip
on the Hosts and Vulnerabilities dashboard charts.
# Checklist for submitter
- [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.
## 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
* **Bug Fixes**
* Improved chart tooltip text for host/platform filters, ensuring
branded platform names keep correct capitalization and combined lists
use correct punctuation.
* Refined chart tooltip/platform display mapping to avoid incorrect
capitalization variants.
* **New Features**
* Updated browser chart category labeling to show “Browsers” with
consistent capitalization.
* **Tests**
* Expanded ChartCard tests to validate platform tooltip line formatting
for single and multiple selections.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Moves opening context paragraphs in several articles to follow the key
takeaways section for a more consistent structure. Also refines a few
takeaway phrases for clarity and updates calls to action, including
linking the Managed Migration Assistant article to the setup guide and
simplifying the closing CTA in the config-as-code article.
Fixes data race detected in
https://github.com/fleetdm/fleet/actions/runs/28769705097/job/85300822820.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Improved reliability of log delivery by ensuring buffered log data is
copied before being sent, preventing intermittent issues when batches
are processed.
* Reduced the risk of log entries being corrupted or lost during
transmission.
<!-- 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#45650
# 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.
## Testing
- [x] QA'd all new/changed functionality manually
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Summary by CodeRabbit
* **Bug Fixes**
* Improved MySQL migration handling for MDM command results by safely
removing an outdated foreign key when present, preventing issues during
upgrade and re-run scenarios.
* Updated the database schema definition to keep related response
foreign key behavior consistent.
* **Chores**
* Added the latest migration version to the migration status seed data
to ensure version tracking stays in sync.
<!-- 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.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Documentation**
* Added a new customer testimonial highlighting Fleet’s device
management experience, including the customer quote, role, and profile
link.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Eric <eashaw@sailsjs.com>
- [x] QA'd all new/changed functionality manually
- Enrollment methods: ADE, profile-based manual, Managed Apple Account
- Also, update Controls > Setup experience copy. "Automatically" only
applies to macOS:
<img width="505" height="168" alt="Screenshot 2026-07-02 at 9 41 17 AM"
src="https://github.com/user-attachments/assets/ff46682f-e87b-4d2e-9889-7d0382b0d3d5"
/>
- Every other platform:
<img width="517" height="174" alt="Screenshot 2026-07-02 at 9 41 31 AM"
src="https://github.com/user-attachments/assets/0ab115fb-76fb-4080-afb4-52edcf4900b7"
/>
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Updated the setup guidance text for platform-specific enrollment so
macOS now shows “automatically enroll to Fleet.”
* Other platforms continue to show “enroll to Fleet,” improving clarity
in the install experience.
* **Tests**
* Adjusted the Android empty-state test to match the updated enrollment
wording.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
**Related issue:** NA
# Checklist for submitter
If some of the following don't apply, delete the relevant line.
- [x] QA'd all new/changed functionality manually
---
Brings `articles/control-apple-beta-programs-with-ddm.md` up to the
current article format:
- Moved the "Key takeaways" section and CTA button directly under the
dek, ahead of the intro, so the full argument sits at the top of the
page.
- Reworded two takeaways ("Beta control is no longer all-or-nothing" and
the token-fetching bullet) that echoed body sentences nearly verbatim —
takeaways now preview the body instead of repeating it.
No changes to metadata, links, or the substance of the article.
@headmin can you give this a review? The intention was not to rewrite
your article but to have it follow the new article format.
---
Reframes the opening to focus on operational cost and team dependency
tradeoffs, adds a new "Key takeaways" section, and inserts an early CTA
link. Also normalizes capitalization in the closing demo bullet for
consistency.
Fixes:
https://github.com/fleetdm/fleet/actions/runs/28775213423/job/85317520154.
New run: https://github.com/fleetdm/fleet/actions/runs/28779783653.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Chores**
* Added vulnerability status information for a known issue affecting
`fleetctl`, clarifying that it is not impacted by the reported problem.
* Included a note explaining why the affected code path is not reached
in typical use.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
**Related issue:** Resolves#45710
# Checklist for submitter
- [x] Changes file added (`changes/45710-zorin-os-support`).
- [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 —
`server/vulnerabilities/oval/oval_platform_test.go` extended with Zorin
→ Ubuntu LTS mapping cases (16/17/18) plus an unknown-version case
(`Zorin OS 99` → `zorin_99`, which `IsSupported()` rejects).
- [x] QA'd all new/changed functionality manually — Zorin OS 17.0 and
18.1 hosts enrolled against a patched Fleet server, host details show
`platform=zorin`, software inventory populates, and OVAL CVE matching
produces results against the corresponding `ubuntu_2204` / `ubuntu_2404`
feeds.
## Database migrations
- N/A. No schema changes.
## New Fleet configuration settings
- N/A. No new settings.
## fleetd/orbit/Fleet Desktop
- N/A. Server + frontend only; no fleetd/orbit changes.
---
## Summary
Fleet previously logged `unrecognized platform` for Zorin OS hosts
(osquery reports `platform=zorin` from `/etc/os-release` `ID=zorin`).
The common workaround was running osquery with
`--force_platform=ubuntu`, which masquerades the host. This change adds
`zorin` as a first-class Linux platform alongside Ubuntu:
- **`server/fleet/hosts.go`** — register `zorin` in `HostLinuxOSs` and
`HostDebPackageOSs`
- **`server/datastore/mysql/linux_mdm.go`** — include Zorin in the Linux
disk-encryption summary query
- **`server/vulnerabilities/oval/oval_platform.go`** — map Zorin major
version to the underlying Ubuntu LTS OVAL feed (16 → 20.04, 17 → 22.04,
18 → 24.04). Unknown future versions fall through to an unsupported
`zorin_<major>` identifier so vulnerability scanning is skipped rather
than served stale data from an aging LTS feed.
- **frontend** — add `zorin` to `HOST_LINUX_PLATFORMS`, the
disk-encryption support list and type guard, the label platform
dropdown, and the icon mapping (Ubuntu icon, since no Zorin-specific
asset exists in the repo).
No new dependency, schema migration, or config setting. Reuses existing
Ubuntu OVAL feeds and the existing Ubuntu icon.
Diff is ~30 lines net across 9 files (8 patched + 1 `changes/` file).
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added Zorin OS as a supported Linux platform.
* Zorin hosts included in Linux disk-encryption summaries and treated as
disk-encryption capable.
* Zorin OS available as a selectable/filterable platform label and
considered DEB-install compatible.
* Vulnerability scanning enabled for Zorin 16→Ubuntu 20.04, 17→22.04,
18→24.04; unknown/future Zorin versions are marked unsupported and
skipped for CVE matching.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45712?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Reworks the article opening with a stronger headline, intro framing, and
a new key takeaways section plus CTA. It also tightens product language
(agent/query-based verification, Premium benchmark availability),
simplifies the “what changes” section into a clearer narrative, and
updates metadata by moving the category from `security` to `articles`.
**Related issue:** N/A
New article: "Take control of Apple beta programs with declarative
device management."
Covers the `com.apple.configuration.softwareupdate.settings` DDM
declaration for controlling Apple beta program enrollment, automating
AppleSeed for IT token retrieval from Apple Business Manager using the
Microsoft/HCS `betaTokens.sh` script, and deploying the declaration
through Fleet's custom OS settings (UI upload or GitOps) with
label-based scoping.
Follows the Fleet article format: dek, key takeaways above the fold,
post-takeaways CTA button, and closing "See it live" block.
Notes for reviewers:
- Verified `com.apple.configuration.softwareupdate.settings` is not in
Fleet's `ForbiddenDeclTypes` (`server/fleet/apple_mdm.go`), so the
"deploy with Fleet" section is accurate.
- CTA routes (`/try-fleet`, `/gitops-workshop`,
`/guides/custom-os-settings`) verified against
`website/config/routes.js`.
- Please click-check the Apple developer docs link for the
`SoftwareUpdateSettings` schema.
# Checklist for submitter
If some of the following don't apply, delete the relevant line.
- [x] Article-only change; no changes file, tests, migrations, or config
changes needed.
---------
Co-authored-by: Harrison Ravazzolo <38767391+harrisonravazzolo@users.noreply.github.com>
Adds WinDirStat to maintained apps for Windows by introducing the winget
input metadata, generated app output entries, and installer/uninstaller
version data. Also adds the WinDirStat icon asset and wires it into the
SoftwarePage icon map so the app displays with the correct branding in
the UI.
- Clarified the absence of a Refetch button for Android hosts
- Removed "Sync policies" header because the term policies could be
confusing. After that, just decided to remove the headers because the
article is short.
- Piece of the following request:
https://github.com/fleetdm/fleet/issues/42755
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 the Windows release metadata for Cursor to version 3.10.11,
including the download link and checksum.
* Updated the Windows release metadata for DBeaver Community to version
26.1.2, including the download link and checksum.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: allenhouchins <32207388+allenhouchins@users.noreply.github.com>
**Related issue:** Resolves#46235
# 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.
## Testing
- [x] Added/updated automated tests
- [ ] QA'd all new/changed functionality manually: Pending if possible
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Fixed DEP sync so progress is only saved after device data is written
successfully, preventing missed enrollment events during interrupted
syncs.
* Improved handling of sync errors so the next run can safely replay
affected devices instead of skipping them.
* Added end-to-end and scenario coverage to verify cursor behavior after
successful syncs, errors, and expired cursors.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
**Related issue:** Resolves#48277
## What & why
Running a live report/query (or live policy) on some machines throws a
full error page once results start streaming in:
```
NotFoundError: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.
```
**Root cause:** Chrome's built-in auto-translate (Google Translate)
wraps text nodes in `<font>` elements, detaching the original DOM nodes
React holds references to. As live results stream in over the websocket,
table cells (and the responded-count heading) unmount rapidly; React
then calls `parentNode.removeChild(node)` on a node Translate has
already moved, throwing `NotFoundError`. The app's error boundary
catches it and renders the error page (facebook/react#11538).
This is why it's machine-dependent: it only reproduces when Chrome is
translating the page. It surfaces on live results specifically because
that's one of the few surfaces that unmounts DOM rapidly while
displaying translatable text.
**Fix:** Exclude the live-results subtrees from translation via the
`notranslate` class on the top-level containers of `QueryResults` (live
report/query) and `PolicyResults` (live policy). These wrappers cover
the `LiveResultsHeading` counts, the results table, and (policy) the
errors table. Translation stays enabled everywhere else in the app.
## How to reproduce / QA
1. In Chrome, enable translation of the live results page (right-click →
Translate to English, or set a non-English preferred language so the
Translate banner activates and choose "Always translate").
2. Run a live query/report or live policy targeting several hosts so
results stream in.
3. Before the fix: error page appears after a few results. After the
fix: results render normally.
# Checklist for submitter
- [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.
## Testing
- [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
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Prevented browser auto-translation from modifying live results areas
in the policy and query editors.
* Reduces the chance of display errors during live streaming/remounting
of results.
* Addressed a related Google Translate browser extension issue that
could lead to incorrect live-run behavior.
* **Chores**
* Added a changelog entry for the live results translation fix.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
**Related issue:** Fully resolves
https://github.com/fleetdm/fleet/issues/34591.
## Testing
- [X] QA'd all new/changed functionality manually.
<img width="533" height="454" alt="Screenshot 2026-07-03 at 10 40 37 AM"
src="https://github.com/user-attachments/assets/892fb548-21c6-467c-b270-65f1c9338fdc"
/>
<img width="1287" height="259" alt="Screenshot 2026-07-03 at 10 41
55 AM"
src="https://github.com/user-attachments/assets/d3528b0c-0d05-4ace-8512-ab363241b97c"
/>
<img width="1077" height="123" alt="Screenshot 2026-07-03 at 10 41
46 AM"
src="https://github.com/user-attachments/assets/249e80de-320c-48f3-962a-59c98c736c54"
/>
<img width="725" height="208" alt="Screenshot 2026-07-03 at 10 41 32 AM"
src="https://github.com/user-attachments/assets/361764cf-26fc-4a44-b5d6-489d883a392b"
/>
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added CachyOS Linux to rolling-release OS detection and reporting.
* Added a CachyOS fleetd package/image variant and a new CachyOS fleetd
service for local testing.
* **Bug Fixes**
* Improved rolling-release OS version labeling for host “Vitals”
display.
* Updated OS inventory normalization so CachyOS is aggregated with Arch
Linux, including correct “rolling” version handling.
* **Tests**
* Expanded OS version ingest test coverage for rolling-release and
CachyOS scenarios.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->