disk_actions
| What it does | Reports physical drive health and the mapping between drives and the logical volumes they back |
| Version | 1.0.0 |
| Kind | Collector · read-only · on-demand |
| Platforms | Windows ✅ · macOS 🟡 constrained · Linux 🟡 planned |
| Actions | partitions (definition crossplatform.storage.partitions) · smart (definition crossplatform.storage.smart) · topology (definition crossplatform.storage.topology) · volumes (definition crossplatform.storage.volumes) |
| Security | securable Inventory · operation Read · risk Low · dispatch ReadOnly · approval gate None |
| Roles | execute: endpoint-admin, endpoint-operator · author: content-author |
How it works
Both actions are reads and change nothing. smart lists the physical drives the OS exposes and reports each one’s model, transport (bus) and media type; on Windows, NVMe drives also answer a SMART/Health query whose critical-warning flags become a health verdict, with the raw wear and spare-capacity percentages alongside. volumes lists logical volumes and, for each, the physical drive that backs it and the mount points or drive letters it serves. On Windows smart probes PhysicalDrive0 to PhysicalDrive63; on macOS both actions walk the IOKit registry; Linux returns a single placeholder row and an UNAVAILABLE status.
volumes is deliberately not a third volume inventory: hardware.disks already lists physical devices and filesystem_posture.mounts already lists mounts. This action carries only the join between them, which is what lets a failing-drive alert name the drive letters or mount points it affects. Where a mechanism is unavailable (Linux) or is reachable only through a private OS interface (macOS health), the leg says so in its result rather than guessing.
partitions and topology read nothing yet: on every OS each answers with exactly one status|<action>|unsupported|<os>:planned row from the shared planned-leg reporter (agents/shared/planned_leg.hpp), until their leg PRs land (partitions on every OS; topology on Linux for LVM/md/multipath and on macOS for APFS containers; Windows has no topology source ruled yet).
flowchart LR
OP["Operator or workflow"] --> SRV["Server: Inventory Read, concurrency per device"]
SRV -- "gRPC mTLS" --> HOST["Agent plugin host"] --> EX["disk_actions.execute"]
EX --> WIN["Windows: storage IOCTLs on drive and volume handles"]
EX --> MAC["macOS: IOKit registry reads and getmntinfo_r_np"]
EX --> LIN["Linux: placeholder row and UNAVAILABLE"]
WIN & MAC & LIN --> ROWS["Pipe rows and typed result status"]
ROWS -- "CommandResponse" --> RS[("ResponseStore")]
RS --> API["REST /api/responses"]
What you can decide with it
| Question | Action and column | Windows | macOS | Linux |
|---|---|---|---|---|
| Is a drive reporting a failure or warning? | smart health | failing or warning for NVMe drives only (derivation below) | Never; health is always unknown | Nothing |
| How worn is the drive? | smart pct_used, spare_pct | NVMe drives only. pct_used runs 0 to 255 and can exceed 100 | - | Nothing |
| What kind of drive is it? | smart model, bus, media | All drives the OS lists | All block devices, disk images included (bus virtual) | Nothing |
| Which drive letters or mount points does this drive serve? | volumes device, mount_points | One row per volume; a spanned volume lists one entry per disk extent, comma-separated, so the same drive can appear more than once | One row per partition or container member that maps a mount or a drive; device is the physical disk, for example disk0 | Nothing |
| How full is it, or what is its filesystem usage? | not this plugin | Use crossplatform.storage.mounts | Use crossplatform.storage.mounts | n/a |
How health is derived. For an NVMe drive the plugin reads the SMART/Health log page and looks only at its critical-warning byte. If bit 0 (available spare below threshold) or bit 2 (reliability degraded) is set, health is failing. If any other bit is set (temperature, media read-only, volatile-memory backup failed, or a bit the plugin does not know), it is warning. If no bit is set it is ok. pct_used and spare_pct are reported but never change the verdict, so a drive at 100 percent or more of its rated endurance with no warning flag still reads ok; set your own wear threshold on pct_used if you want one.
What a missing failing does and does not prove. Only Windows NVMe drives are ever judged. SATA and USB drives, virtual machine disks and every drive on macOS report unknown, and Linux reports unsupported, so the absence of a failing row says nothing about those devices. Alert on failing and warning, and track the unknown and unsupported rows separately to see which devices the fleet cannot judge. ok means the drive reported no critical warning at read time, not that it will not fail.
Diagrams
From a drive to a health value
flowchart TD
S["smart: one row per drive"] --> O{"Which OS?"}
O -- "Linux" --> L["Placeholder row, health unsupported"]
O -- "macOS" --> M["health unknown, detail says whether the device advertises SMART"]
O -- "Windows" --> B{"Is the bus NVMe?"}
B -- "no: SATA, USB, SAS, virtual or unknown" --> U1["health unknown, no wear figures"]
B -- "yes" --> P{"Did the SMART/Health log page come back?"}
P -- "no" --> U2["health unknown, CONSTRAINED windows:nvme_health"]
P -- "yes" --> C{"Critical-warning byte"}
C -- "bit 0 or bit 2 set" --> F["failing"]
C -- "any other bit set" --> W["warning"]
C -- "no bit set" --> OK["ok"]
Wear (pct_used) and spare (spare_pct) come from the same log page and are printed on the row, but the decision uses the critical-warning byte alone. Every path that cannot read the page ends in unknown, never in ok.
How volumes joins volumes to drives
flowchart TD
WV["Windows: volume GUID path from FindFirstVolumeW"] --> WM["Drive letters and mount folders for the volume"]
WV --> WE["Disk extents of the volume"]
WE --> WD["PhysicalDriveN, several when the volume is spanned"]
MP["macOS: IOMedia partition, for example disk3s1"] --> MW["Walk the IOKit providers to the first whole IOMedia"]
MW --> MD["Physical disk, for example disk0, not the synthesized APFS container"]
MP --> MM["Mount points matched by BSD name through getmntinfo_r_np"]
WM & WD --> ROW["volume row: volume, mount_points, device, fstype, total_bytes"]
MM & MD --> ROW
On Windows the physical drive comes from the volume’s disk extents, so a spanned or striped volume names every drive it touches. On macOS the drive comes from walking the IOKit provider chain, because trimming the BSD name would stop at a synthesized APFS container that is not a physical device. A whole disk that serves no mount point is left out, since it carries no join.
OS capability
| Action | Windows | macOS | Linux |
|---|---|---|---|
partitions | 🟡 planned · rung 1 · Win32_DiskPartition + Win32_LogicalDisk | 🟡 planned · rung 1 · diskutil list + getmntinfo | 🟡 planned · rung 1 · /proc/self/mountinfo + /sys/block/*/ |
smart | ✅ supported · rung 1 · IOCTL_STORAGE_QUERY_PROPERTY (StorageDeviceProperty + StorageDeviceSeekPenaltyProperty + StorageDeviceProtocolSpecificProperty, NVMe log page 0x02) | 🟡 constrained · rung 1 · IOKit IOBlockStorageDevice device characteristics | ⛔ unsupported |
topology | 🟡 planned · rung 1 · no source ruled; stays planned | 🟡 planned · rung 1 · diskutil apfs list | 🟡 planned · rung 1 · /sys/block/dm-/dm/{name,uuid}, md/md, slaves |
volumes | 🟡 constrained · rung 1 · FindFirstVolumeW + IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS + GetVolumePathNamesForVolumeNameW | 🟡 constrained · rung 1 · IOKit IOMedia provider walk + getmntinfo_r_np(3) MNT_NOWAIT | ⛔ unsupported |
Declared limits per leg (descriptor fallback text, verbatim):
partitions/ Windows — not read yet: one unsupported status row, windows:plannedpartitions/ macOS — not read yet: one unsupported status row, macos:plannedpartitions/ Linux — not read yet: one unsupported status row, linux:plannedsmart/ Windows — the device handle is opened with zero access rights, which an unprivileged service account may do; wear and spare figures come from the NVMe SMART/Health log and are therefore reported only for NVMe devices, with SATA and USB drives reporting identity and media type but ‘unknown’ healthsmart/ macOS — reports device identity (model, medium type) and whether the device advertises NVMe SMART, but NOT the health attributes themselves: wear, available spare and the critical-warning flag are reachable only through Apple’s private IONVMeSMARTUserClient selector interface, which is undocumented and version-fragile, so health reports ‘unknown’ on this platform rather than a guesssmart/ Linux — not implemented in this change: no mechanism could be bound, because every Linux host available for the spike exposed virtualised disks only (WSL2 reports four ‘Virtual Disk’ SCSI nodes and no /dev/nvme* character devices), and shipping an NVME_IOCTL_ADMIN_CMD path written from documentation but never exercised is exactly how a dead leg reaches production. Binding it needs a Linux host with real storage, or a VM with disk passthrough; neither was reachable when this shippedtopology/ Windows — not read yet: one unsupported status row, windows:plannedtopology/ macOS — not read yet: one unsupported status row, macos:plannedtopology/ Linux — not read yet: one unsupported status row, linux:plannedvolumes/ Windows — maps volumes to the physical drives backing them; a volume spanning several drives (a spanned or striped dynamic volume) reports every drive it touches, and a volume with no assigned drive letter or mount point reports ’-’ for mount points rather than being omittedvolumes/ macOS — one row per IOMedia object, keyed on that object’s BSD name, carrying the physical whole disk that backs it and any mount points it serves; the physical disk is resolved by walking the IOKit provider chain, so a volume inside a synthesized APFS container correctly reports the underlying drive rather than the container; a media object that maps nothing — a whole disk serving no mount point — is omitted, because this action carries only the physical-to-logical join and such a row has no join to carryvolumes/ Linux — not implemented in this change: the physical-to-logical join is only meaningful alongside a bound smart leg, and the Linux smart leg is deferred with it
Privileges and prerequisites
| OS | Runs as | Extra grant needed | Measured | If the read is refused |
|---|---|---|---|---|
| Windows | agent service account (LocalSystem today; the packaged service has not yet moved to the virtual service account) | None measured for smart: the drive handle is opened with zero access rights, not GENERIC_READ, and both IOCTLs are FILE_ANY_ACCESS, so it keeps working when the agent runs as a lower-privileged account. volumes opens each volume handle the same way, but that has not been measured under an unprivileged account; a refusal there is reported as denied, never as “the device did not answer” | smart: 2026-09-03 on bare metal as NT AUTHORITY\LOCAL SERVICE. volumes: elevated only (2026-09-06) | PERMISSION_DENIED / partial, provenance windows:physicaldrive:denied (a drive handle) or windows:volume_enum:denied (a volume handle or the volume enumeration) |
| macOS | LaunchDaemon, root today (docs/agent-privilege-model.md) | None. IOKit property reads only; no user client is opened, so the leg needs nothing root has | 2026-09-03 and 2026-09-06 at euid 501 (an unprivileged user, a stricter test than the daemon’s) | never PERMISSION_DENIED: a refused or failed IOKit read, including a failed service match, is CONSTRAINED (partial, macos:iokit or macos:iomedia and their sub-tokens), and UNAVAILABLE only when the enumeration returned nothing at all |
| Linux | n/a | n/a, leg not implemented | n/a | always UNAVAILABLE |
The two planned actions read nothing on any OS and need no grant. No external binaries, no subprocesses, no network access. Do not change the Windows drive open to GENERIC_READ: that breaks the leg under an unprivileged account.
Data contract
Inputs
No action takes parameters.
Outputs
Pipe-delimited rows, one per drive or volume. Field 0 is a literal discriminator (smart or volume; the planned actions answer one status row, status|<action>|unsupported|<os>:planned, and their final partition and topology row schemas are declared in disk_actions_legs.hpp) that precedes the columns below; every row of a kind has the same field count, with - where a value is inapplicable or was not read. - never means zero, and a macOS smart row always has - for pct_used and spare_pct. Every free-text field (device, model, volume, mount points, filesystem, detail) passes through safe_output_field, which rewrites \ as /; bus, media and health are fixed vocabularies and the numeric fields are digits, so they need no escaping. Windows volume GUID paths read //?/Volume{…}/ and drive letters C:/. A leg that finds nothing still emits one placeholder row so zero rows can never be misread as “no disks”: a smart placeholder carries health=unsupported, a volume placeholder carries volume=-, and both are accompanied by a typed status, which is the authoritative signal.
crossplatform.storage.partitions — row_kind|disk|partition|size_bytes|type|mount_points|detail
| Field | Type | Values | Available | Example | Description |
|---|---|---|---|---|---|
row_kind | string | status partition | Windows, Linux, macOS | status | Row shape discriminator (the wire row’s leading tag). Values: status (exactly one per result, always first), partition (one per record read). |
disk | string | - | Windows, Linux, macOS | disk0 | Physical disk the partition belongs to. Status rows: the action name. |
partition | string | - | Windows, Linux, macOS | disk0s2 | Partition identifier. Status rows: the level (unsupported). |
size_bytes | string | - | Windows, Linux, macOS | 494384795648 | Partition size in bytes, or ”-” when unread. Status rows: the reason token ( |
type | string | - | Windows, Linux, macOS | apfs | Partition type or filesystem hint, or ”-”. Absent on status rows. |
mount_points | string | - | Windows, Linux, macOS | / | Comma-separated mount points or drive letters, or ”-”. Absent on status rows. |
detail | string | - | Windows, Linux, macOS | - | Free text, or ”-”. Absent on status rows. |
crossplatform.storage.smart — device|model|bus|media|health|pct_used|spare_pct|detail
| Field | Type | Values | Available | Example | Description |
|---|---|---|---|---|---|
device | string | - | Windows, macOS | PhysicalDrive0 | OS device name of the physical drive |
model | string | - | Windows, macOS | Samsung SSD 970 EVO Plus 1TB | Drive model string as reported by the OS, escaped |
bus | string | nvme sata usb sas virtual unknown | Windows, macOS | nvme | Transport, a closed vocabulary |
media | string | ssd hdd unknown | Windows, macOS | ssd | Media type, a closed vocabulary |
health | string | ok warning failing unknown unsupported | Windows | ok | Health verdict. unknown means the device did not say; unsupported means this OS leg cannot ask. Windows reports a verdict for NVMe drives only; macOS always reports unknown; Linux always unsupported. |
pct_used | string | - | Windows | 5 | NVMe “Percentage Used” (0-255 by specification, never clamped), or ”-” when not read. |
spare_pct | string | - | Windows | 100 | NVMe “Available Spare” (0-100), or ”-” when not read. |
detail | string | - | all | - | Free text, or ”-”. |
crossplatform.storage.topology — row_kind|kind|name|uuid|members|detail
| Field | Type | Values | Available | Example | Description |
|---|---|---|---|---|---|
row_kind | string | status topology | Windows, Linux, macOS | status | Row shape discriminator (the wire row’s leading tag). Values: status (exactly one per result, always first), topology (one per record read). |
kind | string | - | Windows, Linux, macOS | lvm_vg | Layer kind. Values: lvm_vg, lvm_lv, md, multipath, apfs_container. Status rows: the action name. |
name | string | - | Windows, Linux, macOS | vg0 | Layer name. Status rows: the level (unsupported). |
uuid | string | - | Windows, Linux, macOS | - | Layer UUID, or ”-”. Status rows: the reason token ( |
members | string | - | Windows, Linux, macOS | sda2,sdb2 | Comma-separated member devices, or ”-”. Absent on status rows. |
detail | string | - | Windows, Linux, macOS | - | Free text, or ”-”. Absent on status rows. |
crossplatform.storage.volumes — volume|mount_points|device|fstype|total_bytes|detail
| Field | Type | Values | Available | Example | Description |
|---|---|---|---|---|---|
volume | string | - | Windows, macOS | disk3s1s1 | Volume GUID path (Windows) or BSD name (macOS); ”-” only on the empty-result placeholder row. |
mount_points | string | - | Windows, macOS | /System/Volumes/Data | Comma-separated mount points or drive letters, or ”-” when the volume serves none. |
device | string | - | Windows, macOS | disk0 | Backing physical drive; several, comma-separated, on a spanned volume. |
fstype | string | - | Windows, macOS | apfs | Filesystem of the volume (NTFS, FAT32, apfs, …), or ”-” when unmounted or unknown. |
total_bytes | int64 | - | Windows, macOS | 494384795648 | Raw media capacity (sum of disk extents on Windows, IOMedia size on macOS), not filesystem capacity. Not comparable with crossplatform.storage.mounts.total_bytes. |
detail | string | - | all | - | Free text, or ”-”. |
Result status
Surfaced as plugin_result_status on the command response.
| Status | Completeness | Provenance | When |
|---|---|---|---|
OK (derived from UNDECLARED) | - | - | clean read: volumes on Windows and macOS, smart on Windows. A macOS smart run is never clean (next row) |
CONSTRAINED | partial | Windows: windows:physicaldrive · windows:physicaldrive_cap · windows:storage_device_property · windows:nvme_health · windows:volume_enum · windows:volume_extents:unread · windows:volume_extents:truncated · windows:volume_mount_paths · windows:volume_information. macOS: macos:iokit · macos:iokit:no_bsd_name · macos:iokit:health_unread · macos:iomedia · macos:iomedia:no_bsd_name · macos:provider_walk · macos:getmntinfo_r_np | a per-device read degraded and the row carries - for what was not read. Every macOS smart run reports macos:iokit:health_unread (identity read, health not) unless a stronger cause outranks it. windows:physicaldrive_cap means the probe of PhysicalDrive0 to PhysicalDrive63 did not end in a run of eight absent indices, so a host with more drives may be reported short. windows:volume_extents:truncated means a volume reported more disk extents than the reply could carry, so its device lists only some drives |
UNAVAILABLE | partial | linux:smart · linux:volumes · windows:physicaldrive · macos:iokit · macos:iomedia | Linux, always (placeholder row). Windows smart and macOS (both actions) when the enumeration ran but produced no device or mapping row at all. Windows volumes never reports it. On macOS, a failed IOKit service match is CONSTRAINED (macos:iokit or macos:iomedia), not UNAVAILABLE |
UNAVAILABLE | unknown | windows:planned · linux:planned · macos:planned | partitions or topology on any OS: a planned action, one unsupported status row, nothing read |
PERMISSION_DENIED | partial | windows:physicaldrive:denied · windows:volume_enum:denied | Windows only: a drive or volume handle open, or the volume enumeration, was refused; outranks every other degradation. The macOS legs never report it |
Where the data goes
- Instruction result only. Rows travel over the agent’s mTLS gRPC channel as the command response, land in the ResponseStore (90-day default retention), and are queryable at
/api/responses/{id}, aggregatable (smartbyhealth,volumesbydevice) and exportable as JSON from/api/responses/{id}/export. - Not consumed by daily-sync inventory, the Echo warehouse, DEX, or metrics. Nothing runs on a schedule.
- Sensitivity. Rows identify hardware, not people: drive models, volume GUIDs and BSD names are device-level identifiers (asset-inventory class, like
device_ci), and nothing in them names a user, a file or an application. - MCP / REST. Discover:
discover_plugins(summary) →yuzu://plugin-docs(this page as data) →discover_instructions/get_definition("crossplatform.storage.smart"). Run:execute_instruction {definition_id, parameters}. Read:/api/responses/{id}. - Siblings:
device.hardware.disks(physical inventory),crossplatform.storage.mounts(logical mounts, true filesystem capacity),crossplatform.storage.free.
Sample output
Windows — captured: windows Windows 11 Pro 10.0.26200 · bare-metal · 2026-09-07 · interactive user (elevated) · leg-hash 3abb2323b0be
== action=smart
smart|PhysicalDrive0|Samsung SSD 970 EVO Plus 250GB|nvme|ssd|ok|5|100|-
smart|PhysicalDrive1|Samsung SSD 970 EVO Plus 1TB|nvme|ssd|ok|1|100|-
[result_status] UNDECLARED / UNKNOWN
== action=volumes
volume|//?/Volume{0a35801e-3f40-4114-a073-3d7ea1dd7664}/|-|PhysicalDrive0|NTFS|524288000|-
volume|//?/Volume{c9a5f911-4689-41b2-b774-5b0e25b60e10}/|C:/|PhysicalDrive0|NTFS|248158093312|-
volume|//?/Volume{daa59534-884a-4ce4-8fc8-4244f7bbe7ae}/|-|PhysicalDrive0|NTFS|967835648|-
volume|//?/Volume{785383ef-b682-41d9-9b28-27c4b8882d65}/|D:/|PhysicalDrive1|NTFS|1000187363328|-
volume|//?/Volume{b188886e-39bb-4915-a893-d61a3ca3c707}/|-|PhysicalDrive0|FAT32|272629760|-
[result_status] UNDECLARED / UNKNOWN
macOS — captured: macos macOS 26.6.2 arm64 · bare-metal · 2026-09-07 · euid 501 · leg-hash 3abb2323b0be
== action=smart
smart|disk0|APPLE SSD AP0512Z|nvme|ssd|unknown|-|-|device advertises SMART; health attributes are not read on macOS (they require Apple's private IONVMeSMARTUserClient interface)
[result_status] CONSTRAINED / PARTIAL / macos:iokit:health_unread
== action=volumes
volume|disk0s1|-|disk0|-|524288000|-
volume|disk0s3|-|disk0|-|5368664064|-
volume|disk0s2|-|disk0|-|494384795648|-
volume|disk1|-|disk0|-|524288000|-
volume|disk2|-|disk0|-|5368664064|-
volume|disk3|-|disk0|-|494384795648|-
volume|disk1s1|/System/Volumes/iSCPreboot|disk0|apfs|524288000|-
volume|disk1s4|-|disk0|-|524288000|-
volume|disk1s2|/System/Volumes/xarts|disk0|apfs|524288000|-
volume|disk1s3|/System/Volumes/Hardware|disk0|apfs|524288000|-
volume|disk2s1|-|disk0|-|5368664064|-
volume|disk2s2|-|disk0|-|5368664064|-
… 12 of 19 rows shown
[result_status] UNDECLARED / UNKNOWN
Linux — captured: linux Debian GNU/Linux 13 (trixie) aarch64 · container · 2026-09-06 · euid 0 · leg-hash 3abb2323b0be
== action=smart
smart|-|-|unknown|unknown|unsupported|-|-|drive health is not implemented on Linux in this release; no mechanism was bound against real hardware
[result_status] UNAVAILABLE / PARTIAL / linux:smart
== action=volumes
volume|-|-|-|-|-|physical-to-logical volume mapping is not implemented on Linux in this release; it ships with the smart leg it exists to support
[result_status] UNAVAILABLE / PARTIAL / linux:volumes
Caveats and known gaps
healthis the drive’s own critical-warning flag, and only Windows NVMe drives have one. Wear and spare percentages never feed the verdict, so a heavily worn drive with no warning flag readsok. SATA, USB and virtual machine disks reportunknownbecauseIOCTL_STORAGE_PREDICT_FAILUREis deliberately not used as a fallback (it fails on NVMe), so a missingfailingis not evidence of a healthy drive.- macOS reports identity only.
healthis alwaysunknownandpct_usedandspare_pctare always-, because the attributes sit behind Apple’s privateIONVMeSMARTUserClientinterface, which the plugin does not use; every macOSsmartrun is alsoCONSTRAINEDwithmacos:iokit:health_unread. - Linux is declared, not implemented. Both actions return one placeholder row (
health=unsupported, orvolume=-) andUNAVAILABLE, and the definitions target Windows and macOS only. A Linux leg would bind the NVMe admin get-log-page call, whose log page the Windows decoder already reads, and has not been measured on real storage.partitionsandtopologyare advertisedplannedon all three OSes, though Windows has no LVM/md topology source and macOS has no multipath; the leg PRs move such legs to a typedunsupportedwith a reason, so until then<os>:plannedmeans “not read”, never “this host has no partitions”. - No deadline on Windows device I/O.
DeviceIoControlis synchronous with no timeout, so a wedged device or a disconnected network LUN can park the dispatch worker that called it. The 64-drive probe limit and suppression of the not-ready-volume dialog bound the ordinary case, not a driver that never returns. total_bytesis media capacity, not filesystem capacity. On macOS every APFS volume in a container reports the container’s size, and unmounted members and containers appear with-mount points; on Windows it is the sum of the volume’s disk extents. Usecrossplatform.storage.mountsfor real capacity.
Source and tests
- Plugin:
agents/plugins/disk_actions/src/disk_actions_legs.hpp·agents/plugins/disk_actions/src/disk_actions_linux.cpp·agents/plugins/disk_actions/src/disk_actions_macos.cpp·agents/plugins/disk_actions/src/disk_actions_parsers.hpp·agents/plugins/disk_actions/src/disk_actions_plugin.cpp·agents/plugins/disk_actions/src/disk_actions_win.cpp - Definitions:
content/definitions/disk_actions.yaml - Capability rows:
server/core/src/capability_decls/plugin_action_catalogue_disk_actions.hpp - Tests:
tests/test_disk_actions_definition.py·tests/unit/test_disk_actions_local_dispatcher.cpp - Privilege row:
docs/agent-privilege-model.md