Host hardware inventory: CPU/RAM/GPU/NVIDIA-driver/Docker/disk detection + SMR probe (composes operations-drive-health)
| Tier | operations |
| Role | unclassified (baselined) |
| Path | crates/operations/host-inventory |
| Edition | 2021 |
| Targets | operations_host_inventory |
| Public items | 28 across 8 modules |
| Tests | 52 |
What it is for
Host hardware inventory library crate.
Detects OS, CPU, RAM, NVIDIA GPU + driver, Docker, and a disk inventory (with an SMR probe), composing operations_drive_health for SMART grading. Shared by multiple consumers (frigate-box, bootusb, rust-inventory-ai) so detection lives in one tested place instead of being re-hand-rolled per app.
Testability
All system access goes through the CommandRunner trait (subprocess calls use strict argument vectors — never a shell — and file reads are explicit paths). Unit tests drive detection with testkit::FixtureRunner and canned tool output, so no test touches real hardware. Production uses SystemCommandRunner.
Status
Skeleton: the shared types + per-domain module signatures exist and compile; each detect() is implemented (TDD, tests-first) in the Sprint 0 fan-out.
Capabilities
DetectError
Host hardware inventory library crate.
| Item |
|---|
pub enum DetectError |
HostReport
Host hardware inventory library crate.
| Item |
|---|
pub struct HostReport |
fn inventory(runner : & dyn CommandRunner) -> HostReport |
CpuInfo
CPU detection (parse /proc/cpuinfo).
| Item |
|---|
pub struct CpuInfo |
fn detect(runner : & dyn CommandRunner) -> Result <CpuInfo, DetectError> |
DiskInfo
Block-device inventory + SMR probe, composing operations_drive_health for
| Item |
|---|
pub struct DiskInfo |
fn detect(runner : & dyn CommandRunner) -> Result <Vec <DiskInfo>, DetectError> |
SmrStatus
Block-device inventory + SMR probe, composing operations_drive_health for
| Item |
|---|
pub enum SmrStatus |
DockerInfo
Docker / container-runtime detection (docker version, docker info).
| Item |
|---|
pub struct DockerInfo |
fn detect(runner : & dyn CommandRunner) -> Result <DockerInfo, DetectError> |
fingerprint (other)
Privacy-preserving host hardware fingerprint (ADR 0017).
| Item |
|---|
pub const ALGORITHM: & str |
fn raw_components(runner : & dyn CommandRunner) -> Vec <(& 'static str, Option <String>)> |
MachineFingerprint
Privacy-preserving host hardware fingerprint (ADR 0017).
| Item |
|---|
pub struct MachineFingerprint |
fn fingerprint(runner : & dyn CommandRunner, secret : & u8) -> MachineFingerprint |
Quality
Privacy-preserving host hardware fingerprint (ADR 0017).
| Item |
|---|
pub enum Quality |
GpuInfo
NVIDIA GPU + driver detection (nvidia-smi, lspci fallback).
| Item |
|---|
pub struct GpuInfo |
fn detect(runner : & dyn CommandRunner) -> Result <GpuInfo, DetectError> |
MemoryInfo
Memory detection (parse /proc/meminfo).
| Item |
|---|
pub struct MemoryInfo |
MemoryInfo :: const fn total_gib(self) -> u64 |
fn detect(runner : & dyn CommandRunner) -> Result <MemoryInfo, DetectError> |
OsInfo
OS identity detection (parse /etc/os-release).
| Item |
|---|
pub struct OsInfo |
fn detect(runner : & dyn CommandRunner) -> Result <OsInfo, DetectError> |
FixtureRunner
Test fixtures for driving detection without real hardware.
| Item |
|---|
pub struct FixtureRunner |
FixtureRunner :: fn new() -> Self |
FixtureRunner :: fn with_command(mut self, program : & str, args : & & str, output : CommandOutput) -> Self |
FixtureRunner :: fn with_file(mut self, path : & str, contents : & str) -> Self |
FixtureRunner :: fn run(& self, program : & str, args : & & str) -> Result <CommandOutput, DetectError> |
FixtureRunner :: fn read_file(& self, path : & str) -> Result <String, DetectError> |
How to use it
No examples/ target and no doctest in this crate's rustdoc. The tests listed under Verification are the closest executable usage.
Module structure
operations_host_inventory
cpudiskdockerfingerprintgpumemoryostestkit
flowchart TD n_operations_host_inventory["operations_host_inventory"] n_operations_host_inventory --> n_cpu["cpu"] n_operations_host_inventory --> n_disk["disk"] n_operations_host_inventory --> n_docker["docker"] n_operations_host_inventory --> n_fingerprint["fingerprint"] n_operations_host_inventory --> n_gpu["gpu"] n_operations_host_inventory --> n_memory["memory"] n_operations_host_inventory --> n_os["os"] n_operations_host_inventory --> n_testkit["testkit"]
Public surface
`crate root`
| Item | What it is |
|---|---|
pub enum DetectError | Error raised while probing the host |
pub struct HostReport | Aggregate host report |
fn inventory(runner : & dyn CommandRunner) -> HostReport | Probe the host through runner, collecting a best-effort HostReport |
`cpu`
| Item | What it is |
|---|---|
pub struct CpuInfo | CPU model + core counts. |
fn detect(runner : & dyn CommandRunner) -> Result <CpuInfo, DetectError> | Detect the CPU from /proc/cpuinfo |
`disk`
| Item | What it is |
|---|---|
pub enum SmrStatus | Zoned-storage classification from /sys/block/<dev>/queue/zoned |
pub struct DiskInfo | One block device. |
fn detect(runner : & dyn CommandRunner) -> Result <Vec <DiskInfo>, DetectError> | Enumerate block devices with transport, removable/rotational flags, SMR status, and mountpoints |
`docker`
| Item | What it is |
|---|---|
pub struct DockerInfo | Docker engine + compose + NVIDIA-runtime state. |
fn detect(runner : & dyn CommandRunner) -> Result <DockerInfo, DetectError> | Detect Docker + compose + the NVIDIA container runtime |
`fingerprint`
| Item | What it is |
|---|---|
pub const ALGORITHM: & str | Fingerprint algorithm/version tag (bump to rotate the recipe or secret). |
pub enum Quality | Confidence tier of the identity evidence (ADR 0017) |
pub struct MachineFingerprint | A privacy-preserving host fingerprint: HMAC digests + presence/quality metadata only. |
fn raw_components(runner : & dyn CommandRunner) -> Vec <(& 'static str, Option <String>)> | Collect and normalize each identity component, without hashing — the exact same set fingerprint uses internally, before the HMAC step |
fn fingerprint(runner : & dyn CommandRunner, secret : & u8) -> MachineFingerprint | Compute the host fingerprint via runner, keyed by secret |
`gpu`
| Item | What it is |
|---|---|
pub struct GpuInfo | NVIDIA GPU + driver state. |
fn detect(runner : & dyn CommandRunner) -> Result <GpuInfo, DetectError> | Detect the NVIDIA GPU(s) + driver |
`memory`
| Item | What it is |
|---|---|
pub struct MemoryInfo | Physical memory totals. |
MemoryInfo :: const fn total_gib(self) -> u64 | Total RAM rounded to whole gibibytes (useful for the 12 GB floor check). |
fn detect(runner : & dyn CommandRunner) -> Result <MemoryInfo, DetectError> | Detect total RAM from /proc/meminfo |
`os`
| Item | What it is |
|---|---|
pub struct OsInfo | Operating-system identity, from /etc/os-release. |
fn detect(runner : & dyn CommandRunner) -> Result <OsInfo, DetectError> | Detect the OS from /etc/os-release |
`testkit`
| Item | What it is |
|---|---|
pub struct FixtureRunner | A CommandRunner backed by canned command output and file contents |
FixtureRunner :: fn new() -> Self | A runner with no fixtures (every lookup misses). |
FixtureRunner :: fn with_command(mut self, program : & str, args : & & str, output : CommandOutput) -> Self | Register canned output for an exact program+args invocation. |
FixtureRunner :: fn with_file(mut self, path : & str, contents : & str) -> Self | Register canned contents for an exact file path. |
FixtureRunner :: fn run(& self, program : & str, args : & & str) -> Result <CommandOutput, DetectError> | — |
FixtureRunner :: fn read_file(& self, path : & str) -> Result <String, DetectError> | — |
Re-exports. Exported here, defined elsewhere.
| Export | Defined in |
|---|---|
{CommandOutput,CommandRunner,SystemCommandRunner} | runner::{CommandOutput,CommandRunner,SystemCommandRunner} |
{MediaVerdict,SmartSummary} | operations_drive_health::{MediaVerdict,SmartSummary} |
{fingerprint,raw_components,MachineFingerprint,Quality} | fingerprint::{fingerprint,raw_components,MachineFingerprint,Quality} |
Boundary
Depends on no other workspace tier.
Shares tier operations with 40 other crates: operations-approval-workflow, operations-assessments, operations-block-imaging, operations-boot-media, operations-browser-agent-worker, operations-camera-discovery, operations-camera-liveview, operations-camera-registry, … (40 total).
_What this crate deliberately does NOT own is a judgment. No committed registry records one for it, so none is stated here._
Where it sits
| Tier (ontology) | operations |
| Architectural role (taxonomy) | unclassified (baselined) |
| Location | crates/operations/host-inventory |
| Vocabulary in force (lexicon) | current |
Dependencies
Runtime, in this workspace.
| Crate | Tier | Optional | Only on |
|---|---|---|---|
| `operations-drive-health` | operations | no | always |
Runtime, from outside the workspace.
| Crate | Requirement | Features | Optional | Only on |
|---|---|---|---|---|
hex | ^0.4 | — | no | always |
hmac | ^0.12 | — | no | always |
serde | ^1 | derive | no | always |
serde_json | ^1 | — | no | always |
sha2 | ^0.10 | — | no | always |
thiserror | ^2 | — | no | always |
Development, from outside the workspace.
| Crate | Requirement | Features | Optional | Only on |
|---|---|---|---|---|
serde_json | ^1 | — | no | always |
Build. None.
Depended on by. 1 workspace crate.
Signal flow — what reaches this crate, and what it reaches.
flowchart LR n_infrastructure_hardware_forensics["infrastructure-hardware-forensics"] -->|uses| SELF SELF["operations-host-inventory"] SELF -->|runtime| n_operations_drive_health["operations-drive-health"] classDef self fill:#1f883d,stroke:#1f883d,color:#fff; class SELF self;
Feature flags
No Cargo features are defined: every capability is unconditional, so no consumer can receive a half-wired crate.
Targets
| Kind | Name | Source |
|---|---|---|
| lib | operations_host_inventory | `src/lib.rs` |
Error model
| Error type | Named by |
|---|---|
DetectError | detect |
Operational characteristics
| Property | Evidence |
|---|---|
| async public surface | none detected |
| async runtime | none detected |
| database access | none detected |
| network I/O | none detected |
| unsafe code | none detected |
| environment variables | none detected |
No unsafe block, unsafe fn, unsafe impl or unsafe trait was found by the parser anywhere in this crate's source.
Configuration
No environment variable is read with a literal name anywhere in this crate. A variable whose key is computed at run time cannot be listed here, and is not claimed to be absent.
Related capabilities
1 workspace crate depends on this one: infrastructure-hardware-forensics.
Verification
| Kind | Count |
|---|---|
| Unit tests | 52 |
| Integration tests | 0 |
| Examples | 0 |
| Doctests | 0 |
Evidence by module. How often each public module is named by something executable.
| Module | Tests | Examples | Consumers |
|---|---|---|---|
crate root | 3 | 0 | 2 |
cpu | 2 | 0 | 0 |
disk | 3 | 0 | 1 |
docker | 2 | 0 | 0 |
fingerprint | 5 | 0 | 2 |
gpu | 2 | 0 | 0 |
memory | 2 | 0 | 0 |
os | 2 | 0 | 0 |
testkit | 1 | 0 | 1 |
What the tests establish, by name:
empty_runner_errors—src/cpu.rsmissing_model_name_falls_back_to_unknown—src/cpu.rsno_processor_entries_is_parse_err—src/cpu.rsparses_2core_4thread—src/cpu.rsparses_single_core—src/cpu.rsempty_blockdevices_yields_empty_vec—src/disk.rsempty_runner_errors—src/disk.rsgarbage_json_is_parse_error—src/disk.rshandles_string_typed_flags_and_size—src/disk.rsmissing_blockdevices_key_is_parse_error—src/disk.rsmissing_zoned_file_is_unknown—src/disk.rsparses_usb_and_internal_disks_skipping_rom—src/disk.rszoned_attribute_maps_to_smr_status—src/disk.rsdaemon_unreachable_yields_none_engine_but_ok—src/docker.rsdocker_present_without_nvidia_runtime—src/docker.rsempty_runner_errors—src/docker.rsfull_docker_host_with_nvidia_runtime—src/docker.rsdeterministic_for_same_secret_and_host—src/fingerprint.rsempty_host_is_quality_d_not_panic—src/fingerprint.rsfilters_generic_oem_garbage—src/fingerprint.rsflags_vm_and_container—src/fingerprint.rsnever_leaks_raw_values—src/fingerprint.rsquality_tiers—src/fingerprint.rsraw_components_and_fingerprint_agree_on_which_components_are_present—src/fingerprint.rsraw_components_returns_the_actual_values_fingerprint_hashes_away—src/fingerprint.rssecret_domain_separates—src/fingerprint.rsempty_runner_errors—src/gpu.rslspci_fallback_gives_model_no_driver_no_uuid—src/gpu.rslspci_without_nvidia_is_absent_not_error—src/gpu.rsnvidia_smi_counts_multiple_gpus—src/gpu.rs- _… 22 more_
Documentation coverage
| Measure | Documented | Total |
|---|---|---|
| Public items with rustdoc | 26 | 28 |
Public modules with a //! block | 8 | 8 |
pie showData
title Public items with rustdoc
"Documented" : 26
"No rustdoc detected" : 2
Metrics
| Metric | Value |
|---|---|
| Rust source files | 10 |
| Source lines | 1974 |
| Code lines | 1497 |
| Public API items | 28 |
| Public modules | 8 |
| Tests | 52 |
| Examples | 0 |
| Cargo features | 0 |
| Direct runtime dependencies | 7 |
| Workspace reverse dependencies | 1 |
pie showData
title Public API by kind
"constant" : 1
"enum" : 3
"function" : 9
"method" : 6
"struct" : 9
pie showData
title Rust source composition
"Code" : 1497
"Blank or comment" : 477
Generation
Rendered by tools-corpus corpus readme from repository evidence alone, renderer schema 2, lexicon current. No model, network service or database was consulted. Regenerate with tools-corpus corpus readme --write; verify with --check.