Oliver Kieselbach 9615b4c902 feat(agent-v2): M4.6.ε backend kill-switch + device-block + admin-action plumbing
Closes the last peripheral-parity gap flagged by the user: Legacy's admin
kill-switch / device-block / admin-mark-failed signals flow through the
batch-upload response and drive the same termination / pause paths. Without
this the V2 agent had no way to be remotely stopped or quarantined — it
could only be self-destructed by its own decision engine.

UploadResult extended
- New optional fields on success: DeviceBlocked, UnblockAt, DeviceKillSignal,
  AdminAction, Actions. Factory OkWithSignals(...) for success-with-control.
- Legacy-parity: same semantic as IngestEventsResponse's quarantine / kill /
  admin surface, just riding on the new /api/telemetry/batch response body.

BackendTelemetryUploader.TryReadControlSignalsAsync
- Parses the 2xx response body as JSON (defensive — empty body or malformed
  JSON degrades cleanly to plain Ok). Accepts both camelCase and PascalCase
  field names so an M5 backend can choose either without breaking V2
  agents in the wild.
- Recognises deviceBlocked (bool) + unblockAt (ISO-8601 UTC) + deviceKillSignal
  (bool) + adminAction (string) + actions (ServerAction[]).

TelemetryUploadOrchestrator
- New public event ServerResponseReceived fires on successful uploads that
  carry any control signal. Handlers run after the cursor has moved, so a
  handler exception does not abort or re-run the batch.
- New public IsPaused property — DeviceBlocked sets an internal
  _pausedUntilUtc; subsequent DrainAllAsync calls short-circuit with a
  "device blocked" LastErrorReason until UnblockAt elapses (or indefinitely
  when UnblockAt is null). UnblockAt=null maps to DateTime.MaxValue so the
  comparison stays deterministic without a null branch per tick.

EnrollmentOrchestrator.Transport property
- Exposes the live TelemetryUploadOrchestrator so Program.cs can subscribe
  to ServerResponseReceived without leaking transport internals through
  public orchestrator API.

Program.cs WireTelemetryServerResponse
- Routes ServerResponseReceived through the existing ServerActionDispatcher:
  • DeviceKillSignal → synthesises terminate_session with forceSelfDestruct=
    true + gracePeriodSeconds=0 (kill overrides local SelfDestructOnComplete
    config — Legacy parity, the operator's decision wins)
  • AdminAction → synthesises soft terminate_session respecting local config
  • Actions[] → dispatched directly
  • DeviceBlocked → logged (the transport already paused itself)
- onTerminateRequested extended: reads params["forceSelfDestruct"] and
  flips agentConfig.SelfDestructOnComplete at runtime when set, so the
  cleanup service actually runs.

Tests (+15 in V2.Core.Tests → 384)
- BackendTelemetryUploaderControlSignalsTests: empty body, malformed JSON,
  DeviceBlocked + UnblockAt, PascalCase accepted, DeviceKillSignal,
  AdminAction, Actions array round-trip, non-2xx does not parse signals,
  body with only unknown fields.
- TelemetryUploadOrchestratorServerResponseTests: plain Ok is silent,
  kill-signal raises event once, admin-action forwards field, actions
  forward list, DeviceBlocked pauses → unblock lifts pause → next drain
  uploads the queued item, handler exceptions do not break cursor.

All 4 suites green: 88 DecisionCore + 384 V2.Core + 507 Agent.Core + 557 Functions
= 1536 tests green.

With this commit M4.6 closes all known Legacy-vs-V2 peripheral-parity gaps:
agent_kill (DeviceKillSignal → synthesized terminate_session), agent_blocked
(DeviceBlocked → paused drain), portal Mark-Failed/Mark-Succeeded (AdminAction
→ synthesized terminate_session), plus the generic server-queued Actions[].

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 01:56:44 +02:00
2026-03-17 18:24:01 +01:00
2026-03-26 07:02:33 +01:00
2026-04-04 19:17:01 +02:00

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.

S
Description
Windows Autopilot & Intune enrollment monitoring: live session timelines, fleet health, diagnostics, and an MCP server for AI-assisted troubleshooting.
Readme AGPL-3.0 60 MiB
Languages
C# 72.7%
TypeScript 25.7%
PowerShell 1%
JavaScript 0.5%