Document Phase 2 system telemetry

Records why rebootreasons is not redundant with pendingreboot, why bootinfo carries two facts that must not be collapsed, and why defender is stored unsurfaced.

Also corrects the notes: pending file-rename was already being collected and OR-ed into pendingreboot, so the gap was that the stronger signal was flattened into the weaker one rather than missing. Records that the columns landed as 0015 because 0014 was taken by disk health earlier in this phase.
This commit is contained in:
benjamin.baker
2026-09-05 06:41:28 -04:00
parent 2c4d8ab4cb
commit 9ab1b4f702
2 changed files with 61 additions and 12 deletions

View File

@@ -155,11 +155,18 @@ inventory-snapshot plumbing and one migration.
ManagementObjectSearcher, not the friendly strings `Get-PhysicalDisk` prints
(Health=0 Op=2 Media=4 Bus=17 for a healthy NVMe); the mapping lives in the
collector so the wire stays self-describing.
- **NIC link speed and duplex** - collect, pair into the existing Network
interfaces collection, NOT surfaced yet.
- **Boot type** - fast startup vs true cold boot. Explains why uptime lies and
why a "reboot" did not clear a fault. Collect now; UI placement undecided,
candidate for the Operating system or Hardware card.
- **NIC link speed and duplex** - DONE. Paired onto the existing interfaces
entries by MAC from `MSFT_NetAdapter` (`Win32_NetworkAdapterConfiguration`
carries no link state, so it is a second query). Both fields are null when
unreadable: verified on the live box that a DISCONNECTED adapter returns
empty Speed and FullDuplex, so defaulting would have reported every unplugged
NIC as half-duplex. Not surfaced.
- **Boot type** - DONE. Two facts kept separate: `hiberbootenabled` from the
registry (fast startup configured) and `lastboottype` from Kernel-Boot event
27 (what the last boot did). Neither substitutes for the other - the registry
cannot say what the last boot did, and the event can age out of the log.
Verified live: BootType=0 with HiberbootEnabled=0. Not surfaced; placement
still undecided.
- **Windows Update history, last 5** - PINNED, deferred out of Phase 2. The COM
update searcher is not cheap: it routinely takes seconds and sometimes tens of
seconds, which would make it the most expensive thing in an otherwise
@@ -170,20 +177,28 @@ inventory-snapshot plumbing and one migration.
interfering with collections - or with the hosted application itself. Needs
its own investigation before any implementation, and if it lands it wants its
own cadence (hourly/daily), never the every-cycle path.
- **Defender/AV health** - collect and persist, do NOT surface. Known to
produce false positives in this environment; stored for future wiring.
- **Defender/AV health** - DONE, collected and persisted, NOT surfaced, exactly
as specified. Note the ages are in days and a real 0 means updated today, so
the collector sends null rather than 0 when Defender did not report. A box
with third-party AV or a stripped image has no Defender WMI provider at all,
which is normal here and not a fault.
Explicitly dropped after discussion, do not collect:
certificates (corporate-managed), BitLocker (network join already requires it),
display topology (single monitor on the floor, trained users), session
type/RDP (RDP-in not permitted on the shop floor), logon server (local users).
**Pending file-rename operations** - CONFIRMED, collect. A stronger
reboot-required signal than the current `pendingreboot` key, and cheap.
**Pending file-rename operations** - DONE, but NOT as a new collection. It was
already being read: `GetPendingReboot()` OR-s it together with the CBS and
Windows Update keys into one bool. The gap was that the bool cannot say WHICH
signal fired, so the "stronger signal" was already being flattened into the
weaker one. Shipped as `rebootreasons`, a list naming the signals that fired,
leaving `pendingreboot` untouched for compatibility. Empty list = checked,
nothing pending; null = the check failed.
Schema: these add columns to `endpointstates`. One migration, `0014`, with
idempotent guards and a real downgrade, shipped in the SAME change as the model
edit (a model referencing an unapplied column 500s every query on the table).
Schema: these add columns to `endpointstates`. This landed as `0015`, not the
`0014` reserved here - `0014` was taken by the disk health column earlier in
Phase 2.
## Phase 3 - Service/Process Monitors tab split