Codex review of merged PR3 + PR5 surfaced two correctness gaps that match real-world session traffic. Finding 1 — TableStorageService.Sessions.cs force-update path: The normal status-update path mirrors `update["CurrentPhase"] = Complete` whenever status flips to Succeeded (line ~1019), so V2 enrollment_complete events (which carry Phase=Unknown per feedback_phase_strategy) still land at CurrentPhase=Complete. The ETag-exhaustion / force-update block at line ~1224 was missing the same override, leaving CurrentPhase stuck at the prior in-flight value (or -1) when ETag retries are exhausted exactly at the completion update. 6-line fix mirrors the well-tested normal-path override. Finding 2 — ImeTrackerStateData.PhasePackageSnapshots persistence: GetAllKnownPackageStates() returns the union of live _packageStates and the _phasePackageSnapshots dict (DeviceSetup apps captured before _packageStates.Clear() on the AccountSetup transition). SaveState only persisted the live list, so an agent restart between phases — common on hybrid-join + multi-reboot enrollments — lost the DeviceSetup snapshot and dropped those apps from FinalStatus + app_tracking_summary. ImeTrackerStateData now carries `Dictionary<string, List<PackageStateData>> PhasePackageSnapshots`, SaveState serialises it, LoadState restores it tolerantly (null on old state files → empty dict, no crash). Refactor side-product: extracted ToPackageStateData / FromPackageStateData as private static helpers in ImeLogTracker so the mapping is single-source-of-truth across live + snapshot serialisation. Skipped: Finding 3 (DetectHelloPolicy first-match-wins between Device/User CSP scopes) not fixed — Intune CSPs are exclusive per setting (Device OR User, never both), CSP wins over GPO, the first-match iteration is correct in practice. Saved feedback_csp_scope_exclusive.md so a future review doesn't re-suggest the defensive-aggregation patch. Tests: V2.Core 729 (+2 new for save/load round-trip + old-snapshot backwards-compat), DecisionCore 231, Functions 736, vitest 179, solution build 0/0. No new test for Finding 1's force-update path — the method has no existing test infrastructure (no Azurite fixture, no mock TableClient); the fix mirrors a well-tested normal-path override and risk is essentially zero. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Autopilot Monitor
Advanced monitoring and troubleshooting solution for Windows Autopilot deployments. Gain full visibility into every enrollment session with a detailed event timeline, fleet health dashboards, and session reporting. Define custom analysis rules to automatically detect issues and gather rules to collect targeted evidence. Retrieve diagnostics packages on demand, configure agent settings like auto-reboot behavior and automatic timezone adjustment — all managed centrally from the web dashboard.
Private Preview
Autopilot Monitor is currently running as a Private Preview. Visit autopilotmonitor.com to request access and learn more.
Overview
Autopilot Monitor provides real-time tracking, intelligent diagnostics, and automated troubleshooting for Windows Autopilot enrollment processes. It consists of:
- Bootstrap Script — PowerShell script deployed via Intune that starts monitoring early in the enrollment process
- Monitoring Agent — Lightweight .NET application that collects telemetry and evidence during enrollment
- Backend API — Azure Functions-based ingestion and processing pipeline
- Web Dashboard — Next.js application for real-time monitoring and fleet analytics
Architecture
For detailed information about the system architecture, components, and data flow, see Architecture Documentation.
Documentation
Full documentation is available at autopilotmonitor.com/docs
License
This project uses a split licensing model:
- MIT License — Agent (
src/Agent/) and Shared library (src/Shared/) — unrestricted use on end-user devices - AGPL-3.0 — Backend (
src/Backend/), Web Dashboard (src/Web/), and MCP Server (src/McpServer/) — server-side components remain open source
See LICENSE for full details.



