feat(machine-health): add workstation health-audit plugin#95
Conversation
Port the machine-health skill to a marketplace plugin (category: monitoring): 17 Windows checks + orchestrator with trend-aware severity, approval-gated remediations, and CISA KEV correlation; macOS/Linux stay honest-UNKNOWN stubs. Plugin-form changes vs the in-repo skill: - Split state from reports: new -StateBase (explicit > CLAUDE_PLUGIN_DATA > OutputBase) holds state/, logs/, proposals; report dir is a report_dir userConfig option (default Documents\MachineHealth). - Machine-local catalog overlay (checks.local.jsonc under the state base, merged by id via new Merge-CatalogOverlay lib + tests) replaces in-place catalog self-edits, which a plugin update would overwrite. - New /machine-health:setup skill manages the overlay, custom checks, and remediation approvals. - Bundle the Pester workflow-annotation helper; drop the medley-coupled Apply-DefenderDevExclusions remediation (onboard-owned, never dispatched by the orchestrator) and medley path/doc references; scrub example PII. Validation: claude plugin validate (plugin + --strict catalog) clean; Pester 339 passed / 0 failed; dry-run smoke verifies the report/state split and overlay merge; --plugin-dir load registers both skills.
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_702c17f5-e5c2-4019-82ea-98a683e5175f) |
There was a problem hiding this comment.
Stale comment
Risk: high. Did not approve: Cursor Bugbot completed as skipped (usage limit reached) with no successful automated review, and this large new plugin adds workstation PowerShell execution and remediation with meaningful security blast radius. Human review is required before merge.
Sent by Cursor Approval Agent: Pull Request Router and Approver
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_4b1bbd7a-d870-4880-8db8-f44d0738017f) |
There was a problem hiding this comment.
Stale comment
Risk: high. Did not approve: Cursor Bugbot completed as skipped (usage limit reached), so automated review did not finish successfully. Human review is required for this large new plugin with PowerShell execution and remediation.
Sent by Cursor Approval Agent: Pull Request Router and Approver
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7befbce4b9
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…health # Conflicts: # .claude-plugin/marketplace.json # README.md
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_c186eebb-1c33-435d-935f-7fca6987bddc) |
|
Claude finished @kyle-sexton's task in 4m 26s —— View job PR Review:
|
There was a problem hiding this comment.
Stale comment
Risk: high. Did not approve: Cursor Bugbot completed as skipped (usage limit reached), so automated review did not finish successfully. Human review is required for this large new plugin with PowerShell execution and remediation.
Sent by Cursor Approval Agent: Pull Request Router and Approver
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f52e0d524a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Align 'unparseable' to 'unparsable', reword one 'mis-detect' comment, and silence the official Win32_PnP* CIM class names via the config-blessed inline spellchecker directives (this repo's _typos.toml is a managed standards materialization — allow-word additions go upstream, and inline directives rank first in the false-positive hierarchy anyway).
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_3ca52a3b-a890-4fdd-81ee-d5c08f6e0af4) |
|
Claude finished @kyle-sexton's task in 4m 36s —— View job PR Review:
|
There was a problem hiding this comment.
Stale comment
Risk: high. Did not approve: Cursor Bugbot completed as skipped (usage limit reached), so automated review did not finish successfully. Human review is required for this large new plugin with PowerShell execution and remediation; no reviewers were assigned.
Sent by Cursor Approval Agent: Pull Request Router and Approver
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 73a0fe673d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Codex review finding on the new state/report split: the elevation banner's printed rerun command carried only -OutputBase, and an elevated terminal usually lacks CLAUDE_PLUGIN_DATA — the rerun would fall back to OutputBase and split state across two roots. Pass the resolved StateBase through and print it in the command.
|
Claude finished @kyle-sexton's task in 3m 3s —— View job PR Review:
|
| Finding | Status |
|---|---|
Elevation banner missing -StateBase |
✅ FIXED (87cbc4f) |
| Battery capacity always skipped | 🔴 OPEN |
| Event log misses events (volume cap + localization) | 🔴 OPEN |
CISA KEV egress not logged (missing -LogPath + double-timestamp) |
🔴 OPEN |
Invoke-TrendAnalysis emits last_severity (schema violation) |
🔴 OPEN |
| PS 5.1 degrade path dead code | 🟡 OPEN (doc correctness) |
Disk used_pct not scalar for trend tracking |
🟡 OPEN |
Get-CisaKevCache bypasses Invoke-AllowlistedWeb |
🟡 OPEN (low severity) |
| Elevation banner test doesn't cover non-elevated path | 🟡 OPEN (new, minor) |
Bugs 1–4 are the blocking items before merge. Findings 5–6 and the design note are clean-up candidates.
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_b17bffc6-5cd7-4faa-8acf-9d17784248d7) |
There was a problem hiding this comment.
Stale comment
Risk: high. Did not approve: Cursor Bugbot completed as skipped (usage limit reached), so automated review did not finish successfully. Human review is required for this large new plugin with PowerShell execution and remediation; no reviewers were assigned.
Sent by Cursor Approval Agent: Pull Request Router and Approver
|
Codex review disposition:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 87cbc4f6d4
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_c9f30d83-6991-4ea3-8fd3-199097b45111) |
|
Claude finished @kyle-sexton's task in 1m 35s —— View job PR Review:
|
| Finding | Severity | Status |
|---|---|---|
Elevation banner missing -StateBase |
— | ✅ FIXED (87cbc4f) |
| Battery capacity analysis always skipped on laptops | 🔴 Bug | retrofit |
| Event log misses in-window events (volume cap + localization) | 🔴 Bug | retrofit |
CISA KEV egress not logged (-LogPath omitted + double-timestamp) |
🔴 Bug | retrofit |
Invoke-TrendAnalysis emits last_severity (schema violation) |
🔴 Bug | retrofit |
PS 5.1 degrade path dead code (#Requires -Version 7.4) |
🟡 Doc | retrofit |
Disk used_pct not scalar for trend tracking |
🟡 Logic | retrofit |
Get-CisaKevCache bypasses Invoke-AllowlistedWeb |
🟡 Design | retrofit |
| Windows Update degraded-query severity masks unknown state | 🟡 Logic | retrofit |
| Cadence filter ignored in check selection | 🟡 Logic | retrofit |
| Same-day report overwrite on back-to-back runs | 🟡 Correctness | retrofit |
Elevation banner test missing non-elevated + -StateBase assertion |
🟡 Test | retrofit |
Merge readiness
This PR is a clean, behavior-preserving publish of the upstream machine-health skill into plugin form. The plugin-form-specific work (StateBase/report split, catalog overlay, approvals gate, dry-run default, PII scrub, no hardcoded paths) is sound. The open findings are inherited behaviors scoped to a follow-up versioned update.
No objections to merge from this review pass.
Codex finding: the orchestrator's check selection ignores cadence (as the in-repo original did), but the new overlay reference presented the monthly demotion patch as taking effect. State the advisory status until cadence-aware selection ships.
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_5c142574-6ea1-42e3-845e-925b5060c50f) |
|
Claude finished @kyle-sexton's task in 1m 31s —— View job PR Review:
|
| Finding | Status |
|---|---|
Elevation banner missing -StateBase |
✅ FIXED (87cbc4f) |
| Cadence field not enforced by orchestrator | ✅ DOC FIXED (436ec92) |
| Battery capacity analysis always skipped on laptops | 🔴 retrofit |
| Event log misses in-window events (volume cap + localization) | 🔴 retrofit |
CISA KEV egress not logged (-LogPath omitted + double-timestamp) |
🔴 retrofit |
Invoke-TrendAnalysis emits last_severity (schema violation) |
🔴 retrofit |
PS 5.1 degrade path dead code (#Requires -Version 7.4) |
🟡 retrofit |
Disk used_pct not scalar for trend tracking |
🟡 retrofit |
Get-CisaKevCache bypasses Invoke-AllowlistedWeb |
🟡 retrofit |
| Windows Update degraded-query severity masks unknown state | 🟡 retrofit |
| Same-day report overwrite on back-to-back runs | 🟡 retrofit |
Elevation banner test missing non-elevated + -StateBase assertion |
🟡 retrofit |
All remaining items are pre-existing behaviors from the upstream in-repo skill, accepted by the author as retrofit work (tracked in the migration issue per the @kyle-sexton comment on 87cbc4f).
Merge readiness
No change to the prior conclusion: this is a clean, behavior-preserving publish. The plugin-form-specific work (StateBase/report split, catalog overlay, approvals gate, dry-run default, PII scrub, no hardcoded paths) is sound. The documentation now honestly describes the current state of cadence enforcement. No objections to merge.
|
Second-round Codex disposition: the overlay doc's monthly-cadence claim is corrected in 436ec92 (cadence is recorded but advisory — the orchestrator's selection ignores it, exactly as the in-repo original did); the same-day report-overwrite behavior is pre-existing upstream ( |
There was a problem hiding this comment.
Stale comment
Risk: high. Did not approve: Cursor Bugbot completed as skipped (usage limit reached), so automated review did not finish successfully. Human review is required for this large new plugin with PowerShell execution and remediation; no reviewers were assigned.
Sent by Cursor Approval Agent: Pull Request Router and Approver
…health # Conflicts: # .claude-plugin/marketplace.json # README.md
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_490d3bdf-897f-4f67-87c5-4a9f430b2797) |
|
Claude finished @kyle-sexton's task in 1m 19s —— View job PR Review:
|
| Finding | Status |
|---|---|
Elevation banner missing -StateBase |
✅ FIXED (87cbc4f) |
| Cadence field advisory documentation | ✅ DOC FIXED (436ec92) |
| Battery capacity analysis always skipped on laptops | 🔴 retrofit |
| Event log misses in-window events (volume cap + localization) | 🔴 retrofit |
CISA KEV egress not logged (-LogPath omitted + double-timestamp) |
🔴 retrofit |
Invoke-TrendAnalysis emits last_severity (schema violation) |
🔴 retrofit |
PS 5.1 degrade path dead code (#Requires -Version 7.4) |
🟡 retrofit |
Disk used_pct not scalar for trend tracking |
🟡 retrofit |
Get-CisaKevCache bypasses Invoke-AllowlistedWeb |
🟡 retrofit |
| Windows Update degraded-query severity masks unknown state | 🟡 retrofit |
| Same-day report overwrite on back-to-back runs | 🟡 retrofit |
Elevation banner test missing non-elevated + -StateBase assertion |
🟡 retrofit |
Merge readiness
No change to the prior conclusion. This merge is clean — the machine-health plugin-form work (StateBase/report split, catalog overlay, approvals gate, dry-run default, PII scrub, no hardcoded paths) is sound and the conflict resolution is correct. No objections to merge.
There was a problem hiding this comment.
Risk: high. Did not approve: Cursor Bugbot completed as skipped, so automated review did not finish successfully. Human review is required for this large new plugin with PowerShell execution and remediation; no reviewers were assigned because no eligible reviewers were identifiable outside the author.
Sent by Cursor Approval Agent: Pull Request Router and Approver
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7b78b74a64
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| $restartApproved = Test-ApprovalGranted -State $approvalState -RemediationId 'restart-stopped-service' | ||
| if ($servicesFinding -and $servicesFinding.severity -eq 'WARN' -and $restartApproved) { | ||
| $findingJson = $servicesFinding | ConvertTo-Json -Depth 10 -Compress | ||
| $out = Invoke-Remediation -Script 'remediations\Restart-StoppedService.ps1' -FindingJson $findingJson |
There was a problem hiding this comment.
Honor per-host service exclusions
When approvals.json includes check_overrides.services.service_exclusions, this path still serializes the entire services finding and the remediation targets every detail.stopped_auto_services entry. In that configured environment, a service the user explicitly excluded is still passed to Start-Service, violating the remediation policy's abort condition; filter the finding or pass the exclusions before invoking the remediation.
Useful? React with 👍 / 👎.
|
|
||
| $diskFinding = $checkResults | Where-Object id -EQ 'disk-space' | Select-Object -First 1 | ||
| $clearApproved = Test-ApprovalGranted -State $approvalState -RemediationId 'clear-temp-files' | ||
| if ($diskFinding -and $diskFinding.severity -in @('WARN', 'CRIT') -and $clearApproved) { |
There was a problem hiding this comment.
Gate temp cleanup on the C: volume
This triggers Clear-TempFiles for any disk-space WARN/CRIT, including SMART wear/temperature warnings or low space on a non-C: volume. The remediation policy authorizes it only when C: free space is below 15% and says to abort once C: is above that threshold, so approved runs can delete temp files even when the system volume is not low; check the C: volume detail before dispatching.
Useful? React with 👍 / 👎.
| $unsignedInStore = @($driverStore | Where-Object { | ||
| -not $_.PSObject.Properties['SignerName'] -or | ||
| [string]::IsNullOrWhiteSpace($_.SignerName) |
There was a problem hiding this comment.
Treat missing SignerName as unknown
On non-English Windows, pnputil /enum-drivers localizes field labels, so parsed records may not contain an English SignerName property at all. This predicate counts that absence as unsigned, causing every driver-store record to be reported as unsigned/WARN on localized systems; only present-but-empty signer values should count as unsigned, while missing signer fields should degrade as unknown.
Useful? React with 👍 / 👎.
…or fixes (v0.2.0) (#103) Retrofit of the `machine-health` plugin addressing the 11 findings triaged during the publish PR #95 (all dispositioned there as pre-existing behavior or deferred implementation; threads resolved). Bumps the plugin to **0.2.0** with a `CHANGELOG.md` entry. ## New capability - **Cadence-aware check selection.** A `weekly` run now defers a `cadence: monthly` check that ran within the last ~4 weeks, using a new per-check `checks_ran` field on each `state/history.jsonl` line and a pure `Get-CheckSelection` helper. `on-demand`/`first-run` run every enabled check. The monthly demotion in the catalog overlay is no longer advisory-only. ## Behavior fixes - **event-log-errors** — filter the 7-day window (`StartTime`) and numeric `Level` 1,2 inside the `Get-WinEvent` query, instead of reading the newest 500 records then filtering (dropped in-window errors on busy hosts; numeric level is locale-independent, unlike `LevelDisplayName`). - **disk-space** — emit a scalar worst-volume `used_pct` so the history flattener persists it; disk trend deltas/escalation now fire. - **trend object** — emit `{ last_run, delta, adjusted_from }` (was a non-schema `last_severity`), matching `check-result.schema.json` (`additionalProperties: false`); `Assert-CheckResult` now enforces the trend sub-shape. `last_run` is per-check and normalized to ISO 8601. - **battery** — the dispatcher passes a run-scoped `-ReportPath`, so `powercfg /batteryreport` runs and wear/capacity are analyzed. - **winget / CISA KEV** — forward the run `-LogPath` to `Get-CisaKevCache`, and emit the KEV egress line via the canonical single-timestamp writer so `Read-EgressLog` parses it; the CISA fetch now appears in `urls_called`. - **windows-update** — a failed `Get-WUList` enumeration surfaces as INFO (degraded), not a misleading OK "no pending updates". - **PowerShell version** — reconciled docs/header to the real **PowerShell 7.4+** requirement (the code uses 7.x-only syntax throughout); removed the unreachable "degrade to 5.1" claim and dead branch. Windows PowerShell 5.1 is not supported. _(Direction was left open by the finding; reconciled toward the real 7.4 requirement rather than porting to 5.1.)_ - **reports** — per-run filename `reports/health-<UTC-timestamp>.md`, so a same-day rerun no longer overwrites the earlier report. ## Notes - New dispatcher plumbing splats per-check arguments across `Start-Job`. New pure, unit-tested helpers: `Get-CheckSelection`, `Get-CheckArgument`, `Get-CheckLastRun`. - Cadence-deferred monthly checks are recorded in the run log (`check_skipped ... reason=cadence`) and simply do not run that week — they are not rendered in the report. - Full Pester suite green (365 passing, +25 new); `PSScriptAnalyzer` and `markdownlint` clean. Verified end-to-end via live orchestrator runs (cadence skip, per-run report files, battery capacity, `urls_called` egress, ISO `trend.last_run`). Refs melodic-software/medley#1419 <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Touches orchestration, history schema (`checks_ran`), trend severity, and several security-adjacent checks (event log, updates, KEV egress); behavior changes are well-tested but affect weekly run composition and report deltas. > > **Overview** > Bumps **machine-health** to **0.2.0** with a changelog and doc updates (per-run `health-<UTC-timestamp>.md` reports, PowerShell **7.4+** only). > > **Cadence-aware runs:** Weekly mode now skips `monthly` catalog checks that already ran within ~27 days, using new `checks_ran` on each `history.jsonl` line and helpers `Get-CheckSelection`, `Get-CheckLastRun`, and `Get-CheckArgument`. The orchestrator splats per-check args into `Start-Job`, reads a deeper history tail for cadence (100 lines) while trend still uses the last ~8 runs, and the report delta line notes cadence-deferred checks so fewer totals are not mistaken for regressions. > > **Trend and history:** `Invoke-TrendAnalysis` emits schema-aligned `trend` (`last_run`, `delta`, `adjusted_from`); `Assert-CheckResult` enforces that shape. `disk-space` adds top-level `detail.used_pct` so disk trends persist. Failed checks are excluded from `checks_ran` so monthly checks retry instead of being deferred. > > **Check fixes:** Event log query uses `FilterHashtable` with `StartTime` and numeric levels plus locale-safe empty-result handling. Windows Update reports INFO when `Get-WUList` fails (`pending_update_count` null). Winget forwards `-LogPath` to KEV fetch; egress uses `Write-EgressLogLine` so CISA appears in `urls_called`. Battery gets a run-scoped `-ReportPath` for `powercfg /batteryreport`. > > Pester coverage expanded for the new libs and changed checks. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 9e13086. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->



Refs melodic-software/medley#1378
Ships the
machine-healthplugin (category: monitoring) from medley's.claude/skills/machine-health/: 17 Windows checks + orchestrator (trend-aware severity, approval-gated remediations, CISA KEV correlation), macOS/Linux honest-UNKNOWN stubs, Pester suite bundled.Plugin-form changes vs the in-repo skill
-StateBaseorchestrator parameter (explicit >CLAUDE_PLUGIN_DATA>OutputBase) holdsstate/,logs/, proposals; the report directory is areport_diruserConfig option (defaultDocuments\MachineHealth).<StateBase>/catalog/checks.local.jsonc, merged by id (newMerge-CatalogOverlaylib + unit tests). Replaces the in-repo skill's in-place catalog self-edits, which cache isolation would lose on plugin update; custom checks resolve against the state base with the samescripts/<os>/checks/shape (no validator change)./machine-health:setup— new skill managing the overlay, custom checks, and remediation approvals (nothing approved by default).Apply-DefenderDevExclusions.ps1(onboard-owned, hardcodes~/.local/state/medley/+ a repo-root schema reach-out, never dispatched by the orchestrator — it stays in medley); swept medley paths/doc cites; scrubbed example PII fromapprovals.md.artifacts/to.gitignore(Pester runner output when run from a repo clone).Validation evidence
claude plugin validate ./plugins/machine-healthandclaude plugin validate --strict .— both PASS-RunMode first-run -DryRunwith split roots + a battery-disabling overlay): report under the report root, state/logs under the state root,catalog_overlay_mergedlogged, battery not dispatched (15/16 checks ran)claude --plugin-dirheadless load from a non-source directory: both skills register (machine-health:machine-health,machine-health:setup)The medley-side removal is cutover issue melodic-software/medley#1383 (blocked on this publish). Note for that cutover:
Apply-DefenderDevExclusions.ps1must stay in medley (the onboard skill consumes it).Note
Medium Risk
New local automation can restart services and delete aged temp files when explicitly approved, and performs allowlisted outbound fetches; guardrails (dry first-run, no elevation prompts, schema validation) limit blast radius but the footprint is large.
Overview
Adds the
machine-healthmarketplace plugin: a Windows-first workstation audit that runs a versioned check catalog, adjusts severity using history, optionally applies approval-gated remediations, correlates findings (including CISA KEV), and writes dated markdown reports plus append-only state under plugin data paths.Marketplace wiring: registers the plugin in
.claude-plugin/marketplace.json, documents it in the rootREADME.md, and ignores Pesterartifacts/in.gitignore.Plugin packaging vs an in-repo skill: splits report root (
report_diruser option, defaultDocuments\MachineHealth) from state root (-StateBase/${CLAUDE_PLUGIN_DATA}for history, logs,approvals.json, andcatalog/checks.local.jsonc). The shippedchecks.jsoncstays read-only; machine tuning merges via overlay. Skills/machine-health:machine-healthand/machine-health:setupdrive runs and local configuration. macOS/Linux are explicitNOT_IMPLEMENTEDstubs (UNKNOWN report, no Windows script execution).Implementation surface: JSON schemas, shared reference docs,
Invoke-MachineHealthCheck.ps1orchestrator (timeouts, trend/correlation, remediation dispatch, report render), manyTest-*.ps1checks, narrow remediations (Restart-StoppedService,Clear-TempFiles), allowlisted egress, and a bundled Windows Pester suite.Reviewed by Cursor Bugbot for commit 7b78b74. Bugbot is set up for automated code reviews on this repo. Configure here.