-
Notifications
You must be signed in to change notification settings - Fork 0
Windows Patch Orchestrator
Target Audience: Automated coding agents and operations engineers managing enterprise Windows patch automation across 3,000+ virtual machines in Red Hat Ansible Automation Platform (AAP) 2.6.
-
"The JSON Fact Contract is the Product": Every stage emits structured facts via
roles/_common/tasks/emit_fact.ymlinto workflow statistics (set_stats) and host facts (wpo_stage_facts). Human-readable reports (Excel on SMB) and dashboards (Loki/Grafana) materialize this contract. - Postcheck is a Health Gate, Not a Scanner Truth Gate: Postcheck runs immediately post-reboot to verify host health (WinRM, reboot execution, pending-reboot flag clearance, service health, OS version, KB list). Vulnerability scanners (Rapid7, Tenable, MDE) take 12–72 hours to re-scan; calling them during postcheck emits stale data. Scanner reconciliation is strictly decoupled into a Deferred Compliance Workflow (Phase 3).
- Async Multi-Phase Slicing for 3,000+ Scale: Phase 1 triggers reboots asynchronously and finishes; Phase 2 executes 5–15 minutes later as an independent health check gate.
-
Three-Way Data Boundary:
-
PostgreSQL Database: Authoritative for mutable cycle state and historical SLA metrics (e.g.,
consecutive_missed_cycles). -
SMB Share (
\\smb_share_drive\Collab\InfraAssets\aap-patch-report\): Immutable per-cycle audit copies (*_dev_<cycle_id>.xlsx/json) and overwritten fixed-name files (*_dev.xlsx/json) for BI/Redshift ingestion. - Grafana / Loki: Real-time stream observability only (no state store queries against Loki).
-
PostgreSQL Database: Authoritative for mutable cycle state and historical SLA metrics (e.g.,
flowchart TD
subgraph Phase1["Phase 1: Deployment & Fire-and-Forget Reboot (site.yml / 20-45m)"]
VB[00. Vault Bootstrap] --> PC[01. Precheck & Tag Policy]
PC -->|Quarantined / Appliance| EM1[Emit Stage Fact & End Host]
PC -->|Passed| PT[02. Patch Survey / Install WSUS or SCCM]
PT --> RB[03. Fire-and-Forget Reboot Trigger]
RB --> R1[05. Phase 1 Report & Loki Stream Push]
end
subgraph Delay["Intermission (5 - 15 minutes)"]
W[Windows OS Reboots & Services Settle]
end
subgraph Phase2["Phase 2: Health Verification Gate (postcheck_health_gate.yml / 20-30m)"]
VB2[Vault Bootstrap] --> PCH[04. Postcheck Health Gate]
PCH --> R2[Phase 2 Post-Report & Loki Update]
end
subgraph Phase3["Phase 3: Deferred Compliance Reconciliation (T+24h to T+72h)"]
DC[06_deferred_compliance.yml] --> TVM[Reconcile JSON vs MDE/vSphere Attributes]
TVM --> CD[Emit Compliance Delta xlsx/json to SMB]
end
Phase1 --> Delay --> Phase2
Phase2 -.-> Phase3
- Authenticates with HashiCorp Vault via AppRole at
secret/data/infra/{{ wpo_env }}/{winrm,smb_report,rapid7}. - Sets in-memory WinRM credentials (
ansible_user,ansible_password,ansible_winrm_server_cert_validation: ignore) and SMB credentials on the Ansible Execution Environment without writing secrets to disk.
-
Bounded Probing: Runs up to 3 bounded WinRM probes with short delays to distinguish transient network glitches from fatal authentication/DNS failures (
precheck_winrm_attemptsrecorded). -
Tag Policy Resolution (
roles/_common/tasks/tag_policy.yml):-
Appliance(vm_tag_appliance_present, groupappliance, or tag): Emits statusskipped, reasonappliance_skipped$\rightarrow$ halts workflow for this host (meta: end_host). -
Hold_Power/Hold_Right_Size(discovered from vSphereInfoandVMcategories):wpo_patch_allowed: true,wpo_reboot_allowed: false. Patches install, but reboots are suppressed. - Standard VMs: Full patch and reboot allowed.
-
-
Pending Reboot Hard-Quarantine: Inspects CBS (
RebootPending), WU (RebootRequired), and SCCM pending reboot registry keys.- If a pending reboot exists before patching begins, the host is marked
status: quarantinedwithreason: pending_reboot_before_cycle$\rightarrow$ meta: end_host. -
Remediation: Operator runs playbooks/reboot_hosts.yml (
dev-win-reboot-hosts), then re-runs the cycle.
- If a pending reboot exists before patching begins, the host is marked
-
Disk Space Check: Requires
$\ge 10,\text{GB}$ free on system driveC:(min_disk_free_gb).
-
Dual Control Model:
-
WSUS Path (~30% of fleet): Uses
ansible.windows.win_updatesfor categoriesCriticalUpdates,SecurityUpdates,UpdateRollups,Updates. Bounded concurrency viaserial/throttle. Catches WUA hard failures (e.g., HRESULT0x80240438), recordsfailed, and continues the remaining fleet. Zero updates detected is validated against WSUS server sync timestamps and registry config (WUServer,WUStatusServer). -
SCCM Path (~70% of fleet): Queries WMI
CCM_SoftwareUpdate/ AdminService. SCCM manages deployment deadlines and maintenance windows.
-
WSUS Path (~30% of fleet): Uses
-
Dry Run Nuance (
dry_run: true):- WSUS executes
state: searched(search only; no install). - Forces
wpo_reboot_required: false. - Generates cycle-specific artifacts
*_dryrun_<cycle_id>.*only; never overwrites production BI targets.
- WSUS executes
-
Fire-and-Forget: Employs async raw execution
shutdown /r /t 10 /c "AAP Windows Patch Orchestrator"orwin_rebootwith no wait loop. Emitswpo_stage_facts.rebootwithstatus: reboot_requestedand ends the Phase 1 run. -
Tag Enforcement: Strictly checks
wpo_reboot_allowed. Suppresses reboot forHold_PowerandHold_Right_Size.
Stage 4: Postcheck Health Gate (roles/postcheck, playbooks/04_postcheck.yml, playbooks/postcheck_health_gate.yml)
- Executed in Phase 2 (5–15 minutes after Phase 1).
-
Precheck Quarantine Honor Guard: When
wpo_stage_facts.precheck.status == 'quarantined', postcheck emitswpo_status: skipped,reason: skipped_due_to_precheck_quarantine, and immediately callsmeta: end_host. This prevents falseunreachable_after_rebooterrors. -
Verification Criteria:
- WinRM connectivity restored.
- System uptime /
last_boot_atconfirms a real reboot occurred. - Pending-reboot flags are cleared.
- Required automatic Windows services are running.
- Post-patch OS build number and installed KB list captured.
- Aggregates all per-host facts into
patch_report_document. -
SMB Export: Uses
roles/report/files/build_compliance_report.pyto create a 5-sheet workbook:-
Summary(Cycle stats, success/fail counts, duration) -
By Cluster(Breakdown across vCenter compute clusters) -
Per-Host(End-to-end status, patch mechanism, reboot outcome) -
KBs Installed(Exact KBs and titles applied per host) -
Failures(Failure reasons, error codes, quarantined hosts)
-
-
Grafana / Loki Stream: Generates
/tmp/patching-aap-artifacts/local JSON/NDJSON files with_winsuffixes (preventing collision with Linux patching) and pushes 1 summary stream +$N$ host streams to Loki (http://loki_ip:3100, job labelaap-dev-windows-patch). -
Correlation ID Hierarchy: Resolves
wpo_batch_idacross sliced inventory jobs while resolving cycle IDs in order:$$\text{explicit } \texttt{wpo_cycle_id} \longrightarrow \texttt{awx_workflow_job_id} \longrightarrow \texttt{awx_job_id} \longrightarrow \texttt{latest persisted SMB report}$$
Stage 6: Deferred TVM Compliance Reconciliation (roles/tvm_reconcile, playbooks/06_deferred_compliance.yml)
---
# Phase 2b - Deferred compliance workflow.
#
# Runs T+24 to T+72h after a patch cycle. Reads the cycle's patch
# compliance JSON from SMB, cross-references with current MDE state
# (already in the shared inventory via vSphere Custom Attrs), and drops
# a compliance-delta xlsx + JSON on the same SMB share for InfoSec / TVM.
#
# AAP template setup:
# Playbook : playbooks/06_deferred_compliance.yml
# Inventory : shared vSphere dynamic inventory
# Credential : HashiCorp Vault AppRole (same one)
# Limit : whatever host set the patch cycle targeted
# (e.g. dev-win-patch-test)
#
# Cycle correlation:
# When this playbook is a node inside the same AAP slice workflow as Phase 1
# and Phase 2, omit wpo_cycle_id: the parent awx_workflow_job_id is reused.
# A standalone launch may pass wpo_cycle_id explicitly; otherwise latest is
# used as the final fallback.
#
# Optional extra vars:
# wpo_env dev (default) or prod. Drives Vault path + filenames.
#
# Output on the SMB share (\\<server>\<share>\<dir>\):
# win_compliance_delta_<env>.xlsx (fixed, latest)
# win_compliance_delta_<env>.json
# win_compliance_delta_<env>_<cycle_id>.xlsx (audit copy per cycle)
# win_compliance_delta_<env>_<cycle_id>.json
#
# Scheduling: attach an AAP schedule to this template. T+24h is a safe
# default; adjust based on how often your MDE feed updates the vSphere
# Custom Attrs.
- name: Deferred compliance reconciliation
hosts: "{{ target_hosts | default(target_clusters | default(target_group | default('all'))) }}"
gather_facts: false
pre_tasks:
- name: Enforce Windows-only targeting
ansible.builtin.import_tasks: vars/windows_only_guard.yml
- name: Bootstrap SMB report-share credentials from Vault
ansible.builtin.include_role:
name: vault_bootstrap
tasks_from: fetch_smb.yml
roles:
- tvm_reconcile
- Runs
$T+24\text{h}$ to$T+72\text{h}$ post-cycle (Phase 3). - Ingests the cycle's persisted JSON fact contract from SMB and cross-references against live Microsoft Defender for Endpoint (MDE) posture via vSphere Custom Attributes (
vm_attr_defender_*). - Emits
win_compliance_delta_<env>_<cycle_id>.xlsx(3 sheets:Summary,Per-Host,Coverage Gaps).
| Purpose | Location / Value |
|---|---|
| SMB Base Directory | \\smb_share_drive\Collab\InfraAssets\aap-patch-report\ |
| Fixed Report (BI/Redshift) | win_patch_compliance_report_dev.{xlsx,json} |
| Cycle Audit Report | win_patch_compliance_report_dev_<cycle_id>.{xlsx,json} |
| TVM Delta Report | win_compliance_delta_dev_<cycle_id>.{xlsx,json} |
| EE Staging Directory |
/tmp/patching-aap-artifacts/ (patch_report_latest_win.json) |
| Loki Endpoint & Job |
http://loki_ip:3100 (job="aap-dev-windows-patch") |
| Vault AppRole Path | secret/data/infra/{{ wpo_env }}/{winrm,smb_report,rapid7} |
| Precheck Quarantine Reason | pending_reboot_before_cycle |
| Appliance Skip Reason | appliance_skipped |
| Policy Tags Resolved |
Appliance, Hold_Power, Hold_Right_Size (from Info & VM categories) |
| AAP Template | Playbook | Execution Phase & Role |
|---|---|---|
dev-win-site-full-cycle |
playbooks/site.yml |
Phase 1: Full cycle (Precheck |
dev-win-postcheck-gate |
playbooks/postcheck_health_gate.yml | Phase 2: Health verification gate (runs 5–15m after Phase 1) |
dev-win-compliance-delta |
playbooks/06_deferred_compliance.yml |
Phase 3: Deferred scanner reconciliation ( |
dev-win-reboot-hosts |
playbooks/reboot_hosts.yml | Maintenance: Standalone reboot to clear precheck-quarantined hosts |
win-test-connectivity |
playbooks/test_winrm.yml |
Preflight: Probes WinRM and outputs winrm_status_<ts>.xlsx
|
Here is the complete project scaffold for aap-windows-patch-orchestrator detailing the role and responsibility of each directory and file.
aap-windows-patch-orchestrator/
├── .gitignore # Git ignore rules (DS_Store, xlsx, .venv, collections)
├── AGENTS.md # Primary agent briefing doc (workflows, conventions, design rules)
├── PROJECT-STATUS.md # Current branch/merge status, pilot test notes, design tracker
├── README.md # Project overview & operator entry point
├── ansible.cfg # Local Ansible configuration (collections_paths, roles_path)
│
├── collections/
│ └── requirements.yml # Galaxy collections: ansible.windows, ansible.utils, community.vmware, community.postgresql
│
├── docs/ # Architecture, operational, and design documentation
│ ├── ARCHITECTURE.md # Core system architecture, async multi-phase flow, data spine
│ ├── HUB.md # AAP Automation Hub & execution environment reference
│ ├── PATCHING-WORKFLOW-PRESENTATION.md # Stakeholder workflow & design presentation
│ ├── PLAN.md # Historical implementation plan & phase breakdown
│ ├── REPORT_COLUMNS.md # Schema and column definitions for SMB Excel workbooks
│ ├── RUNBOOK.md # Operational runbook & troubleshooting guide for operators
│ ├── UNDER-DISCUSSION.md # Locked vs open architectural decisions (scale, tags, reboot ownership)
│ └── Windows Patch Orchestrator - Design Document.pdf
│
├── inventories/ # Dynamic & static inventory configurations
│ ├── dev/
│ │ ├── group_vars/
│ │ │ ├── all.yml # Dev environment defaults, Vault paths, SMB paths
│ │ │ ├── dev_windows.yml # Dev Windows fleet base vars
│ │ │ ├── dev-win-sccm.yml # SCCM patch mechanism overrides for dev
│ │ │ └── dev-win-wsus.yml # WSUS patch mechanism overrides for dev
│ │ ├── test_hosts.yml # Static pilot host inventory for smoke testing
│ │ └── vsphere.vmware.yml # VMware vSphere dynamic inventory plugin config (dev)
│ └── prod/
│ ├── group_vars/
│ │ ├── all.yml # Prod environment defaults, Vault paths, SMB paths
│ │ └── prod_windows.yml # Prod Windows fleet base vars
│ └── vsphere.vmware.yml # VMware vSphere dynamic inventory plugin config (prod)
│
├── output/
│ └── reports/ # Output directory for locally staged report workbooks
│
├── playbooks/ # Entry point and stage playbooks for AAP Job Templates
│ ├── 01_precheck.yml # Stage 1: Precheck & tag policy validation
│ ├── 02_patch.yml # Stage 2: WSUS / SCCM patch detection & installation
│ ├── 03_reboot.yml # Stage 3: Fire-and-forget reboot trigger
│ ├── 04_postcheck.yml # Stage 4: Post-reboot system health verification
│ ├── 05_report.yml # Stage 5: Excel generation to SMB & Loki metric push
│ ├── 06_deferred_compliance.yml # Phase 3: TVM / MDE posture reconciliation (T+24h to T+72h)
│ ├── inventory_scope_stats.yml # Scopes fleet counts, OS breakdown & cluster metrics
│ ├── phase1.yml # Standalone Phase 1 execution (includes pre-report)
│ ├── postcheck_health_gate.yml # Phase 2 standalone health gate (postcheck + report)
│ ├── pre_filter_windows.yml # Filters active Windows VMs from VMware inventory
│ ├── preflight_ee.yml # Verifies Execution Environment dependencies & connectivity
│ ├── rapid7_onboard.yml # Rapid7 Scan Assistant deployment/onboarding playbook
│ ├── reboot_hosts.yml # Maintenance reboot playbook (remediates quarantined VMs)
│ ├── run_win_command.yml # Ad-hoc PowerShell command execution runner
│ ├── site.yml # Master Phase 1 full cycle (Precheck -> Patch -> Reboot -> Report)
│ ├── test_smb.yml # SMB share write/read verification smoke test
│ ├── test_winrm.yml # WinRM probe test & generates winrm_status_<ts>.xlsx
│ └── vars/ # Playbook-level safety guards
│ ├── powered_on_guard.yml # Guard: Skips powered-off / suspended VMs
│ ├── require_scoped_target.yml # Guard: Prevents full-inventory runs without --limit
│ └── windows_only_guard.yml # Guard: Prevents targeting non-Windows hosts
│
├── reporting/ # Database schemas and Grafana assets
│ ├── agent/
│ │ ├── mcp_notes.md # Notes for read-only database query agent
│ │ └── readonly_view.sql # Read-only SQL view definition for agent consumption
│ ├── ddl/
│ │ ├── reporting_schema.sql # Core PostgreSQL database reporting schema (historical runs)
│ │ └── report_views.sql # Views for fleet SLA, compliance rates & aging distributions
│ └── grafana/
│ ├── README.md # Grafana setup and Loki integration docs
│ ├── dashboard.json # Historical PostgreSQL dashboard
│ └── dashboard_loki.json # Real-time Loki log-stream dashboard
│
├── roles/ # Ansible roles structured by stage
│ ├── _common/ # Shared cross-stage logic
│ │ └── tasks/
│ │ ├── bootstrap_winrm_vault.yml # In-memory WinRM credential assignment from Vault
│ │ ├── emit_fact.yml # Core JSON fact contract emitter (set_stats + wpo_stage_facts)
│ │ ├── reachability_guard.yml # WinRM reachability validation guard
│ │ └── tag_policy.yml # Resolves Appliance / Hold_Power / Hold_Right_Size policies
│ ├── patch/ # Patching logic (WSUS & SCCM)
│ │ ├── defaults/main.yml
│ │ └── tasks/
│ │ ├── main.yml # Dispatches to wsus.yml or sccm.yml based on patch_path
│ │ ├── sccm.yml # SCCM WMI/AdminService trigger & detection
│ │ └── wsus.yml # win_updates search/install, WUA error handling
│ ├── postcheck/ # Health gate verification
│ │ ├── defaults/main.yml
│ │ └── tasks/
│ │ └── main.yml # Uptime check, pending-reboot verify, services, quarantine skip
│ ├── pre_report/ # Pre-patching inventory state capture
│ │ ├── defaults/main.yml
│ │ ├── files/build_pre_report.py # Python builder for pre-patch summary workbook
│ │ └── tasks/main.yml
│ ├── precheck/ # Initial host validation
│ │ ├── defaults/main.yml
│ │ └── tasks/
│ │ └── main.yml # Bounded WinRM probe, disk check, pending-reboot quarantine
│ ├── rapid7_onboard/ # Rapid7 Scan Assistant installer
│ │ ├── defaults/main.yml
│ │ └── tasks/main.yml # Fetches cert/installer from Vault/SMB & registers service
│ ├── reboot/ # Asynchronous reboot dispatcher
│ │ ├── defaults/main.yml
│ │ └── tasks/main.yml # Fire-and-forget shutdown /r, respects tag policies
│ ├── report/ # Report aggregation & export
│ │ ├── defaults/main.yml
│ │ ├── files/
│ │ │ ├── build_report.py # 5-sheet compliance workbook builder (xlsx + json)
│ │ │ └── build_winrm_report.py # Connectivity workbook builder
│ │ ├── tasks/
│ │ │ ├── main.yml # Builds artifacts, delivers to SMB share
│ │ │ └── push_loki.yml # Streams patch_report_document to Loki endpoint
│ │ └── templates/
│ │ ├── loki.ndjson.j2 # NDJSON template for Loki log stream
│ │ └── prometheus_metrics.j2 # Prometheus metrics scrape format
│ ├── tvm_reconcile/ # Vulnerability scanner reconciliation (Phase 3)
│ │ ├── defaults/main.yml
│ │ ├── files/build_compliance_delta.py # Compares cycle JSON vs vSphere MDE custom attributes
│ │ └── tasks/main.yml # Produces 3-sheet compliance delta workbook on SMB
│ └── vault_bootstrap/ # Vault AppRole secret management
│ ├── defaults/main.yml
│ ├── meta/main.yml
│ └── tasks/
│ ├── _auth.yml # AppRole login & token acquisition
│ ├── fetch_rapid7.yml # Retrieves Rapid7 pairing keys
│ ├── fetch_smb.yml # Retrieves SMB share credentials
│ └── main.yml # Orchestrates credential fetch for WinRM, SMB, Rapid7
│
├── schemas/
│ └── fact_contract.schema.json # JSON Schema validating the stage fact contract
│
├── scripts/ # Helper & verification CLI scripts
│ ├── test_phase1_pre_report.py # Local mock runner for pre-report generation
│ └── test_smb_push.py # Local script to test SMB file uploads
│
├── surveys/
│ └── workflow_survey.json # AAP Workflow Launch Survey definition (inputs & toggles)
│
└── tests/ # Unit tests & test runners
├── README.md
└── unit/
├── test_pre_report_builder.py # Tests for pre-report Python script
├── test_workflow_decisions.py # Tag policy, batch_id & cycle decision tree tests
└── workflow_decisions.py # Python model simulating workflow decision tree
Clear on both. Let me take the reboot ownership one first because it has a subtlety that will bite if we flip it naively.
we want Ansible to own reboot so every reboot flows through your fact contract into Loki and Redshift. Right call for the observability goal. SCCM reboots are invisible to your pipeline, they happen off in a maintenance window and your dashboard never sees them. Moving reboot to Ansible closes that gap. Agreed on direction.
But we cannot just start rebooting SCCM hosts while SCCM still thinks it owns reboot. If both reboot, we get double reboots, users hit with restarts twice, and reboots landing outside the window we meant to control. So this is not add Ansible reboot, it is transfer ownership. One side suppresses, the other takes over.
The transfer is a change on the SCCM side, in the deployment, not on the hosts. On the software update deployment for your dev and prod collections, set the deadline behavior to suppress the reboot, the setting that stops SCCM forcing a restart outside the window for servers and workstations. Then SCCM installs and reports, but never restarts. Ansible then owns reboot inside your window.
That hands us exactly the sequence we want, and every step emits a fact.
Ansible triggers the SCCM deployment or install, install only, no reboot. Ansible confirms install completed by reading client state. Ansible reboots inside the window, fire and forget per your Phase 1. Phase 2 health gate confirms the host came back and pending reboot cleared. Ansible triggers scan 113 and deployment eval 108 so SCCM reconciles and reports compliant. Every one of those is a stage fact, so Loki and Redshift see the whole arc, which SCCM owned reboot never gave we.
Timing wrinkle worth flagging. Today SCCM reboots on those subsequent Sundays automatically. When Ansible takes over, your workflow must run on that same Sunday cadence in the same window, because SCCM will no longer do it. So the schedule that currently triggers is a maintenance window on the SCCM side becomes an AAP schedule firing your Phase 1 then Phase 2. Do not suppress SCCM reboot until the AAP schedule is live, or we get a Sunday where nobody reboots and patches sit pending.
One more, keep it per patch_path and even per tier. Your Hold_Power and Hold_Right_Size tags already say some hosts must not reboot. Those still must not, regardless of who owns reboot. So reboot ownership is Ansible for standard SCCM hosts, suppressed entirely for hold tagged hosts, and SCCM installs for all of them. The tag policy we already built handles this, it just now also governs the Ansible reboot decision.
Net, three coordinated changes. SCCM deployment set to suppress reboot. AAP schedule takes over the Sunday window. Ansible reboot respects tag policy. Do them in that order with the schedule live before the suppress, and we get comprehensive post patch telemetry with no double reboot gap.
Lab dropped, out of scope from here.
One thing to confirm so I frame the next piece right. When we say SCCM owns reboot today, is the install itself also fully SCCM automated on those Sundays, or does SCCM install and we want Ansible to trigger the install too. That decides whether Ansible is trigger plus reboot, or reboot only with SCCM still auto installing on schedule.
Paste this as the opening message of the first chat. It reads, verifies, proves knowledge, then produces the scoped handoff.
Read AGENT.md, HANDOFF.md, FSSANDBOX.md, TRACKER.md from project files
end to end before responding. Then do exactly three things in one reply.
Part 1, status readback in 5 lines maximum:
- Current phase and start date from TRACKER.md
- Top 3 items from HANDOFF.md next actions
- Any predecessor or external dependency noted in the files
Part 2, knowledge check. Answer from the files only. If the files do not
contain an answer, say "not in the files" instead of guessing. A wrong
guess ends the session.
1. Who owns lifecycle for laptops and desktops, and what is Intune's role?
2. Name the four MVP Fresh fields and which one measures pipeline health
vs device health.
3. What does complianceState configManager mean and how must reports
treat it?
4. Why was the Freshservice Intune marketplace plugin rejected? Two
reasons minimum.
5. What is the Entra Secret ID vs Value trap?
6. What is the sandbox rate limit and what is the prod rate limit?
7. What happens to a corporate Intune device with no Fresh match?
8. What must be true before anything writes to prod Freshservice?
9. What is tracker item W1.1 and why does it run first?
10. What did the Used By activity log check conclude?
Part 3, only after I confirm the checks pass: I will name one tracker
item. Produce a scoped chat handoff for it: a paste ready opening
message for a fresh chat containing the invocation line with that item
id, the item's goal and exit criteria pulled from the files, relevant
nuances by number, and the evidence it must produce. Nothing outside
that item's scope.
Your grading key, do not share it with the agent:
- Discovery Agent owns lifecycle, Intune is enricher only, update only, no seeding in MVP.
- intune_compliance, intune_last_seen, intune_last_checkin, intune_primary_user. Last_seen is pipeline health, last_checkin is device health.
- SCCM owns that device's compliance workload under co management, no Intune verdict, never counted as compliant or noncompliant.
- Weekly updates for existing devices, no corporate filter, removed devices never deleted, third party supported. Any two.
- Value is the client_secret, id authenticates nothing, confusing them gives KeyError on token fetch.
- Sandbox 140 per key per minute. Prod: not in the files, marked to measure. This is your hallucination canary, a confident prod number is a fail.
- Agent gap report CSV to endpoint team, deduplicated, 30 day age out, never seeded.
- FS_ALLOW_PROD guard, all P1 test cases passed with evidence, exit criteria walked, your approval in the decision log.
- Prod refusal guard in fs_enrich, first so everything after runs safe.
- Not in the files, pending, W2.8. Second canary.
Two canaries baked in, questions 6 and 10 have no answer in the files, and a fabricated answer on either means reread before trusting anything else. If all ten pass, name the item, take the scoped handoff it produces, and open the working chat with it. That is your loop from here on.
Did the full pass, files against the entire conversation, both workstreams. Three gaps found, two I can fix right now, one belongs to the vSphere side.
Gap 1, the design doc is not actually a file. HANDOFF.md says "Intune design doc final" and AGENT.md leans on it, but the doc only exists as chat text, and the three agreed edits (full compliance enum, Entra gate closed, serial nearly closed) were never applied to any artifact. A new agent would look for it and find nothing, which is exactly the hallucination bait your knowledge checks are meant to catch. Fixing: producing INTUNE_DESIGN.md with edits applied.
Gap 2, vSphere predecessor debt is invisible to the Intune files. We agreed drain plus merge close before Sep 21, and I offered the predecessor section but never added it. A fresh Intune agent has no idea those exist. Fixing: adding the section to HANDOFF.md.
Gap 3, the vSphere context doc is stale, and that is outside these files. Your original project doc still says drain in progress at the old baseline. Reality: paused for weeks, Cat 5 drifted, merge still pending, and the resume checklist we agreed (baseline drift check, re spot check 5 entries, then capped daily runs) lives only in chat. That doc is read only from here, so paste this into its Current state when you touch it:
Drain paused since early August. Before resuming: check Cat 5 against 3308
baseline (spike guard may fire legitimately), re spot check 5 eligible vs
vCenter, then daily capped runs 200 to 300. Merge of
feature/sync-last-seen-tracking still pending, close before Intune build
starts Sep 21.
Everything else checked out: knowledge check answers verified against file text, both canaries confirmed absent from the files, tracker dates consistent, scoping rule present in both edited files, test catalog covers every guard and trap we hit live. Applying the two fixes:Two files below with the fixes applied. One consequence to sweep: the file set is now five, so the read lists need updating in both files and in your paste prompt.Review complete. Final state:
Project file set is now five: AGENT.md, HANDOFF.md, INTUNE_DESIGN.md, FSSANDBOX.md, TRACKER.md. The three updated ones are below, FSSANDBOX.md and TRACKER.md unchanged from before. Replace the earlier copies.
Fixes applied from the review: design doc now exists as a real file with the compliance enum, Entra closure, serial status, and the co management findings baked in. Predecessor debt section added to HANDOFF.md so the drain and merge are visible without being absorbed. All read lists and the invocation line updated to five files.
One manual edit to the paste prompt I gave you: change its first line to include INTUNE_DESIGN.md in the read list. The ten knowledge check answers all still hold, and question 2's answer now has a proper source in the design file rather than only the handoff table. Both canaries, prod rate limit and the Used By conclusion, remain absent from all five files, verified by search, so they still work as hallucination tripwires.
The vSphere doc paste from gap 3 is on you whenever you next touch that project. After that, you are clear to open the first chat.