Skip to content

machine-health: keep the installed monthly wrapper current #9253

Description

@kyle-sexton

/machine-health:setup schedule (#9243) copies the monthly wrapper into <StateBase>/scheduler/ with the plugin, state and report roots written in. A plugin update or a changed report_dir option leaves that copy stale: its exact allow rules no longer match the audit's commands, so later runs fail until the owner reruns schedule. Setup check reports the stale copy, but nothing refreshes it.

One smaller item on the same files:

  • Install-MonthlyRun writes the wrapper and scheduled-settings.json in place, not through a temp file and a rename, so an interrupted install can leave a half-written copy. check reports that state as stale.

Done when a stale copy is refreshed without a manual schedule rerun (for example, an audit run that finds it stale offers the refresh), and both files are written atomically.

🤖 Generated with Claude Code

Activity

  1. added
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Oct 22, 2026
  2. github-actions commented on Oct 22, 2026

    @github-actions
    Contributor

    Proposed work class: work-class: scoped
    Basis: automated intake triage; the lanes App applied this class.

    Size: Small
    Complexity: Low
    Uncertainty: Known
    Flags: none
    Blocked by: none

    Decision recorded. The owner answered in the Refinement and Issue Triage sessions (2026-10-25), deciding the open items below on the facts:

    go with whatever the facts/data/metrics + /discovery:research says and ensure we're aligned with SOLID, DRY/SSOT principles

    [quote truncated; the full decision is at the link]

    #9253 (comment)

    The decision settles the three open questions. The issue is rescoped to the wrapper copy only. check step 6 offers the refresh, and it runs only on the owner's yes. Install-MonthlyRun writes the wrapper through Write-StateFile. The acceptance criteria in that comment define the work.

    Automated triage, applied by the lanes App.

  3. added
    priority: lowNice-to-have, cosmetic, or speculative; opportunistic.
    and removed
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Oct 22, 2026
  4. github-actions commented on Oct 26, 2026

    @github-actions
    Contributor

    The triage sweep dispatched intake triage for this issue (attempt 1 of 2).

  5. added
    status: readyTriaged, unblocked, and fully specified; eligible to pick up.
    work-class: scopedA briefed fix or small feature; blast radius bounded by the brief, tests exist.
    status: confirmedA maintainer confirmed the item is real and in scope; ready to be worked.
    and removed
    status: readyTriaged, unblocked, and fully specified; eligible to pick up.
    on Oct 26, 2026
  6. melodic-automation-lanes commented on Oct 26, 2026

    @melodic-automation-lanes
    Contributor

    Not admitted to the issue lane: no trusted-human acceptance criteria: a listed human must put the confirmed - [ ] criteria in the body or post them as their own comment, or, on an issue a listed human filed, intake's newest refinement comment must hold them unedited. Admission takes the issue once each of those is met, when intake triages it again (.github/actions/resolve-config/admission-rules.json).

  7. melodic-automation-lanes commented on Oct 26, 2026

    @melodic-automation-lanes
    Contributor

    The latest triage verdict holds nothing: the issue is at status: ready.

  8. melodic-automation-lanes commented on Oct 26, 2026

    @melodic-automation-lanes
    Contributor

    Refinement. A read-only run explored this repository, searched its issues and pull requests, and read the allowed docs to draft what follows. On an issue a listed human filed, it counts as the issue's spec once posted, while unedited; it is still model text, so check it.

    Intended outcome: A stale installed monthly wrapper is refreshed from the template with an owner yes, and Install-MonthlyRun writes the wrapper through a temp file and a rename.

    Related work

    Open questions

    1. The issue says the wrapper has plugin, state and report roots written in and that Install-MonthlyRun writes scheduled-settings.json. Neither holds now. Should the issue be rescoped to the wrapper copy only, going stale after a plugin update?
      RECOMMENDED: Yes. Drop scheduled-settings.json and the report_dir trigger, and cover only wrapper drift from the template. Basis: plugins/machine-health/skills/setup/scripts/Install-MonthlyRun.ps1:23-28
    2. Which mechanism refreshes a stale copy: an audit run that offers it, setup check step 6 offering it, or the wrapper updating itself?
      RECOMMENDED: Have setup check step 6 offer the refresh on the owner's yes by calling Install-MonthlyRun, since the scheduled run is unattended and cannot ask. Basis: plugins/machine-health/skills/setup/SKILL.md:342-344
    3. Should a refresh ever run without an owner yes? The wrapper is code the scheduled task runs under the owner's allow rules.
      RECOMMENDED: No. Require an explicit owner yes, as the schedule action does. Basis: judgment

    Sources read

    • plugins/machine-health/skills/setup/scripts/Install-MonthlyRun.ps1:23-28: Install-MonthlyRun uses Copy-Item in place and only removes scheduled-settings.json
    • plugins/machine-health/skills/setup/scripts/Install-MonthlyRun.ps1:37-41: Test-MonthlyRunCurrent compares the copy text with the template
    • plugins/machine-health/skills/setup/SKILL.md:342-344: check step 6 FAILs a stale copy and rerunning schedule rewrites it
    • plugins/machine-health/skills/setup/templates/monthly-run.ps1:52: the wrapper has no roots written in and runs only from the scheduler folder

    Automated refinement by the lanes App. Answer with a comment whose first line is **Decision recorded.**.

  9. kyle-sexton commented on Oct 27, 2026

    @kyle-sexton
    MemberAuthor

    Decision recorded. The owner answered in the Refinement and Issue Triage sessions (2026-10-25), deciding the open items below on the facts:

    go with whatever the facts/data/metrics + /discovery:research says and ensure we're aligned with SOLID, DRY/SSOT principles

    I should only ever be in the loop ONLY when necessary (intent/vision changed, something came up during implementation that impacts trajectory/alignment, OR a high security risk) - I've covered this all before

    No owner ledger (.work/*/interview-checklist.md, .work/gh-monitor-owner-decisions/) names this issue.

    Questions from intake's refinement (#9253 (comment)):

    1. Rescope to the wrapper copy only?
      Decided: Yes. Two parts of the body no longer hold on origin/main. The copy has no roots written in: Install-MonthlyRun copies the template unchanged (plugins/machine-health/skills/setup/scripts/Install-MonthlyRun.ps1:25), and the wrapper derives its state base from its own folder (plugins/machine-health/skills/setup/templates/monthly-run.ps1:51-56). So a changed report_dir does not stale it. And scheduled-settings.json is only removed, never written (Install-MonthlyRun.ps1:26-27), so it needs no atomic write. What remains: the copy goes stale when a plugin update changes the template (plugins/machine-health/skills/setup/SKILL.md:342-344), and the copy is written in place by Copy-Item (Install-MonthlyRun.ps1:25).
    2. Which mechanism refreshes a stale copy?
      Decided: check step 6 offers it. Step 6 already detects the stale copy (SKILL.md:150-158). The scheduled audit runs unattended under claude -p (SKILL.md:339-341) and cannot ask. The offer runs only Install-MonthlyRun, not the schtasks command schedule runs (SKILL.md:365). check is declared read-only (SKILL.md:2, :93), so the declaration names this one write.
    3. Refresh without an owner yes?
      Decided: No. schedule writes the copy "only on the owner's yes" (SKILL.md:2), and the copy is code the scheduled task runs. The refresh keeps that gate.

    Existing control for the atomic write: Write-StateFile writes a temp file in the same folder and swaps it in, so a reader sees the old file or the new one (plugins/machine-health/skills/audit/scripts/windows/lib/Write-StateFile.ps1:16-19). The fix reuses it rather than adding a second recipe.

    Acceptance criteria:

    • Install-MonthlyRun writes the wrapper through Write-StateFile, not Copy-Item in place.
    • When step 6 of check finds WrapperCurrent false, it offers the refresh. On the owner's yes it runs Install-MonthlyRun alone, then Test-MonthlyRunCurrent, and reports the result. Without a yes it writes nothing.
    • The check heading and the skill description in plugins/machine-health/skills/setup/SKILL.md name that one write, done only on the owner's yes.
    • plugins/machine-health/skills/audit/tests/windows/scheduler/Install-MonthlyRun.Tests.ps1 has a case where a stale copy, after Install-MonthlyRun, reports current and no temp file is left in the scheduler folder.
  10. added
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    priority: mediumReal value, no hard deadline; normal backlog flow.
    and removed
    status: confirmedA maintainer confirmed the item is real and in scope; ready to be worked.
    priority: lowNice-to-have, cosmetic, or speculative; opportunistic.
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Oct 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent-readyFully specified and briefed; eligible for autonomous pickup from the frontier.priority: mediumReal value, no hard deadline; normal backlog flow.status: readyTriaged, unblocked, and fully specified; eligible to pick up.work-class: scopedA briefed fix or small feature; blast radius bounded by the brief, tests exist.

    Fields

    No fields configured for Feature.

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions