Skip to content

fix(compliance): remove dev-lead workflow manipulation from re-trigger sweep (Step 1 is out of scope) #438

Closed

Description

@don-petry

Summary

The daily re-trigger sweep (scripts/compliance-retrigger.sh) does more than re-trigger stale issues: Step 1 (check_devlead_workflows) inspects every fleet repo's dev-lead.yml and silently re-enables it if it finds the workflow disabled_manually or disabled_inactivity. This is out of scope for a re-trigger sweep and should be removed.

Evidence

scripts/compliance-retrigger.sh (on main):

  • check_devlead_workflows() — defined at line 92; called from main() at line 359.
  • It enables workflows via the API at line 116:
    gh api -X PUT "repos/$ORG/$repo/actions/workflows/$wf_id/enable"
  • The summary even reports it: Workflows re-enabled: ${WORKFLOWS_DISABLED} (lines 132, 332, 345).

The job declares permissions: contents: read (.github/workflows/compliance-retrigger.yml:31) but performs this mutation through the ORG_SCORECARD_TOKEN PAT, bypassing the workflow's stated least-privilege boundary.

Why this is invalid

  1. Separation of concerns. A "re-trigger stale issues" sweep should re-fire issues:labeled events — nothing more. Mutating the enablement state of another workflow is a different responsibility with a different owner.
  2. Overrides deliberate intent. If a maintainer disables dev-lead in a repo on purpose (incident response, a noisy/looping agent, a repo being wound down), the next daily sweep silently turns it back on within 24h — an unwanted, surprising side effect.
  3. Least-privilege violation. The job advertises contents: read but performs actions: write-class mutations via a PAT. The visible permission contract understates what the job actually does.
  4. Hidden cross-repo writes. A governance sweep quietly changing config across the whole fleet is hard to audit and easy to forget exists.

Recommended Actions

  1. Remove check_devlead_workflows() and its call site from scripts/compliance-retrigger.sh, along with the WORKFLOWS_DISABLED / WORKFLOWS_ENABLED counters and their summary lines (console + step summary).
  2. Keep the sweep focused solely on Step 2 (re-trigger stale issues, one engagement per repo per run).
  3. If "dev-lead must stay enabled fleet-wide" is a real requirement, move that enforcement to a dedicated, clearly-named workflow (e.g. dev-lead-workflow-health) that:
    • declares the permission it actually needs,
    • logs/justifies each enable as its own auditable action,
    • and ideally reports a disabled workflow rather than auto-overriding a maintainer's deliberate disable.
  4. Update the script header docstring (the "What it does" section) to drop Step 1.

Acceptance Criteria

  • compliance-retrigger.sh no longer reads or modifies any repo's dev-lead.yml enablement state.
  • The sweep's behaviour is unchanged for issue re-triggering.
  • Dry-run output and step summary no longer mention "workflows re-enabled".

Context

Identified while documenting the daily sweep (follow-up to #431 / PR #432). Part of the Compliance program initiative (GH Project #1 Initiatives).

Activity

  1. added
    bugBug reports
    ciCI/CD pipeline issues
    automationAutomation improvements and gaps
    dev-leadFor dev-lead agent pickup
    and removed
    dev-leadFor dev-lead agent pickup
    on Jun 10, 2026
  2. don-petry commented on Jun 10, 2026

    @don-petry
    ContributorAuthor

    Dev-Lead Implementation Plan

    Issue: #438 — fix(compliance): remove dev-lead workflow manipulation from re-trigger sweep (Step 1 is out of scope)

    Scope

    Remove check_devlead_workflows() and all associated state (WORKFLOWS_DISABLED, WORKFLOWS_ENABLED) from scripts/compliance-retrigger.sh so the sweep only re-triggers stale issues and never reads or modifies workflow enablement state.

    Implementation Checklist

    • scripts/compliance-retrigger.sh: remove check_devlead_workflows() function (lines 92–133)
    • scripts/compliance-retrigger.sh: remove check_devlead_workflows call from main() (line 359)
    • scripts/compliance-retrigger.sh: remove WORKFLOWS_DISABLED=0 and WORKFLOWS_ENABLED=0 counters (lines 57–58)
    • scripts/compliance-retrigger.sh: remove WORKFLOWS_DISABLED/WORKFLOWS_ENABLED lines from print_summary() (console + GITHUB_STEP_SUMMARY sections)
    • scripts/compliance-retrigger.sh: update header docstring (remove Step 1 description, update one-liner)

    Tests to Write

    • test/scripts/compliance-retrigger/helpers/setup.bash — test setup helpers
    • test/scripts/compliance-retrigger/stubs/gh — smart gh stub routing responses by endpoint
    • test/scripts/compliance-retrigger/workflow-health.bats:
      • Static: check_devlead_workflows no longer defined in script
      • Static: WORKFLOWS_DISABLED counter no longer referenced
      • Static: WORKFLOWS_ENABLED counter no longer referenced
      • Static: dev-lead.yml no longer referenced (no workflow state reads)
      • Behavioral: running the script produces no workflow enable API calls
      • Behavioral: script output does not contain "Workflows re-enabled"

    Test Command

    bats test/scripts/compliance-retrigger/workflow-health.bats

  3. don-petry commented on Jun 10, 2026

    @don-petry
    ContributorAuthor

    Dev-Lead: Implementation Complete

    Plan Execution

    • scripts/compliance-retrigger.sh: removed check_devlead_workflows() function (was lines 92–133)
    • scripts/compliance-retrigger.sh: removed check_devlead_workflows call from main()
    • scripts/compliance-retrigger.sh: removed WORKFLOWS_DISABLED=0 and WORKFLOWS_ENABLED=0 counters
    • scripts/compliance-retrigger.sh: removed workflow count lines from print_summary() (console + GITHUB_STEP_SUMMARY)
    • scripts/compliance-retrigger.sh: updated header docstring (removed Step 1, updated one-liner)
    • test/scripts/compliance-retrigger/helpers/setup.bash: created test setup helpers
    • test/scripts/compliance-retrigger/stubs/gh: created smart routing gh stub
    • test/scripts/compliance-retrigger/workflow-health.bats: 8 tests covering static and behavioral assertions

    Test Results

    1..164
    ok 1 check_devlead_workflows function is not defined in the script
    ok 2 WORKFLOWS_DISABLED counter is not referenced in the script
    ok 3 WORKFLOWS_ENABLED counter is not referenced in the script
    ok 4 dev-lead.yml workflow state is not queried in the script
    ok 5 running the script does not call the workflow enable API
    ok 6 running the script does not read dev-lead.yml workflow state
    ok 7 script output does not mention Workflows re-enabled
    ok 8 script output does not mention Workflows already active
    [... 156 pre-existing tests all pass ...]
    

    All 164 tests pass. ShellCheck lint passes clean.

    Files Changed

    • scripts/compliance-retrigger.sh: removed check_devlead_workflows(), its call from main(), WORKFLOWS_DISABLED/WORKFLOWS_ENABLED counters, and all summary lines referencing workflow counts; updated docstring
    • test/scripts/compliance-retrigger/helpers/setup.bash: new — test helpers following the compliance-remediate pattern
    • test/scripts/compliance-retrigger/stubs/gh: new — smart gh stub that routes responses by endpoint and logs workflow enable calls separately
    • test/scripts/compliance-retrigger/workflow-health.bats: new — 8 tests (4 static, 4 behavioral) verifying the issue acceptance criteria

    Notes

    • The TDD tests fail before the fix (all 8 red) and pass after (all 8 green), confirming clean red→green coverage.
    • Issue re-triggering (Step 2) code is completely unchanged; behavior is preserved.
    • The GITHUB_STEP_SUMMARY block also had two workflow-count rows removed, ensuring dry-run step summaries are equally clean.
  4. added a commit that references this issue on Jun 11, 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

    automationAutomation improvements and gapsbugBug reportsciCI/CD pipeline issuesdev-leadFor dev-lead agent pickup

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions