Skip to content

Fleet-wide stub drift auto-remediation: DRY_RUN-gated, pilot-first PRs that re-sync consumer stubs to canon #1148

Closed
4 of 4 issues completed

Description

@github-actions

Close the detect→remediate gap in the fleet stub-drift reconciliation loop. Drift detection (fleet_stub_drift.sh, driven by fleet_monitor.sh) and CI-time drift-guard (#983) already exist and emit the DRIFTED set; the drift-guard on the template (#983) and the bootstrap wrapper (#972) landed the detect and initial-scaffold steps. What is missing is automated remediation: when a consumer repo's thin-caller stub (today: initiative-planner.yml, initiative-driver.yml) drifts from the canonical org template, a human must manually open a fix PR (#863, #910, #944 are current open cases). This initiative adds a remediation driver that, for each DRIFTED stub, opens an auditable PR in the consumer repo carrying the canonical bytes — as a proposal through the normal PR-review pipeline, never a direct push.

Built from existing components: the DRIFTED set (fleet_stub_drift.json), the canonical source of record (petry-projects/.github standards/workflows/.yml — the exact bytes/SHA drift is measured against), the cross-repo branch+contents-PUT+PR pattern already in seed-repo-template.sh, and a never-overwrite allowlist mirroring template_stub_drift.sh's TEMPLATE_DRIFT_ALLOWLIST. Because the tracked fleet stubs are deployed verbatim, PUTting the canonical bytes makes the consumer blob SHA equal canon — remediation is deterministic and reproducible.

Success metrics (how we know it worked): (1) for the pilot repo, 100% of its DRIFTED tracked stubs are corrected by a single auto-opened PR within one monitor cycle, and re-running the monitor reports them ALIGNED; (2) manual toil per drift issue drops from ~30 min (branch, copy content, open PR) to zero human effort to author the PR; (3) zero allowlisted / intentionally-customized files are ever modified; and, once fleet-wide is enabled, (4) a fleet-wide steady-state metric — mean time-to-ALIGNED across the fleet after a stub drifts — trends down versus the manual baseline.

Cost cap / blast-radius bound: DRY_RUN is the default at every layer; live remediation is restricted to a single named pilot repo until an explicit human go/no-go, with a per-run cap of at most one PR per consumer repo and a small REMEDIATE_MAX_REPOS ceiling on repos touched per run. Scheduled monitor runs never remediate live — going live requires an explicit workflow_dispatch input.

Safety posture (per the idea's adversarial review): no new attack surface beyond existing cross-repo dev-lead ops; PRs are deterministic, auditable proposals reviewed by the normal pipeline; the allowlist protects customized files; pilot-first + human go/no-go bound the rollout.

Related: #983 (drift-guard CI, landed), #972 (bootstrap wrapper, landed), #1008/#1036 (canary-rollout onboarding of the same reusables). Current DRIFTED cases usable as validation targets: #863, #910, #944.

Untracked prerequisites

  • Confirm the credential the remediation step runs under has cross-repo contents:write + pull_requests:write on target consumer repos. seed-repo-template.sh assumes a GH_TOKEN with repo scope, but actions-fleet-monitor.yml runs fleet_monitor.sh under a read-oriented GH_TOKEN (with GH_PAT_FALLBACK) and only uses GH_PAT_WORKFLOWS for repository_dispatch — not cross-repo file writes. Identify/confirm the GitHub App or PAT with write on consumers before live remediation.

Planned from idea discussion #1043 by the BMAD Scrum Master initiative-planner. Inert until a maintainer adds initiative:auto.

Activity

  1. don-petry commented on Jul 14, 2026

    @don-petry
    Collaborator

    Reconciled + activated (2026-07-13)

    Verified against main: detection (fleet_stub_drift.sh, template_stub_drift.sh) exists; no remediation driver exists — all 4 phases are genuine. Activating.

    [DEFERRED-Q for maintainer] — the untracked prerequisite: which credential runs the live remediation step? fleet_monitor.sh runs under a read-oriented GH_TOKEN (+ GH_PAT_FALLBACK) and only uses GH_PAT_WORKFLOWS for repository_dispatch, not cross-repo file writes. Live remediation needs a GitHub App or PAT with contents:write + pull_requests:write on consumer repos. This blocks only Phase 3/4 (live pilot); Phase 1 (#1149 pure plan builder) and Phase 2 (#1150 DRY_RUN driver, idempotent) proceed without it. Please confirm the write credential before the Phase-4 go/no-go.

    Activated for dev-lead (DRY_RUN-safe): #1149, #1150. #1151 (pilot scope) and #1152 (live wiring behind human go/no-go) will queue behind them and are gated on the credential above.

    Adding initiative:auto. — Claude Code

  2. added
    initiative:autoDriver may auto-release this epic's ready sub-issues to dev-lead
    on Jul 14, 2026
  3. don-petry commented on Jul 14, 2026

    @don-petry
    Collaborator

    [DEFERRED-Q RESOLVED] Live-remediation credential = ${{ secrets.GH_PAT }}

    Maintainer decision (2026-07-13): the Phase 3/4 live cross-repo remediation step runs under ${{ secrets.GH_PAT }}, which carries contents:write + pull_requests:write on the consumer repos (the same class of PAT seed-repo-template.sh assumes). This replaces the read-oriented GH_TOKEN / GH_PAT_FALLBACK that scheduled fleet_monitor.sh runs under.

    Wiring guidance for #1152 (the fleet-monitor wiring): pass GH_PAT only into the opt-in, workflow_dispatch-gated live-remediation job — scheduled monitor runs stay read-only and never remediate. Phase 1 (#1149) and Phase 2 (#1150, DRY_RUN) need no write credential and can proceed now. The Phase-4 go/no-go remains a human decision. — Claude Code

  4. don-petry commented on Jul 16, 2026

    @don-petry
    Collaborator

    Epic complete — fleet-wide stub-drift auto-remediation delivered (Phases 1–4)

    All four phases merged:

    Safety posture (delivered, DRY-run-safe): the loop proposes canonical stub bytes as one PR per repo (never direct-push), and is dormant by default. Live remediation requires ALL of — an explicit workflow_dispatch remediate=live + the GH_PAT_WORKFLOWS credential + a configured vars.FLEET_REMEDIATE_PILOT_REPO — with a per-run cap; any missing precondition degrades to dry-run with a ::warning::, and continue-on-error means it can never fail the daily monitor. Scheduled/workflow_call runs are DRY_RUN unconditionally.

    Still gated (separate human step, not part of this epic): enabling an actual live pilot run — set vars.FLEET_REMEDIATE_PILOT_REPO and dispatch the monitor with remediate=live. That first live pilot is its own go decision. Go/no-go for the wiring recorded on #1152.

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

    initiativeEpic / initiative tracking issueinitiative:autoDriver may auto-release this epic's ready sub-issues to dev-lead

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions