Repository navigation
[Phase 1] Move all scheduled workflows off the top of the hour #723
Copy link
Copy link
Closed
Labels
dev-leadFor dev-lead agent pickupFor dev-lead agent pickupinitiativeEpic / initiative tracking issueEpic / initiative tracking issue
Description
Story
As a maintainer of petry-projects/.github-private's scheduled automation,
I want change every schedule.cron that fires at minute 0 to a staggered off-peak minute, touching only the minute field,
so that scheduled runs land outside GitHub's most congested slot (the top of the hour), directly targeting the #1 documented cause of dropped/delayed cron runs.
Acceptance Criteria
- No schedule.cron entry in .github/workflows/.yml or in agentic .github/workflows/.md sources uses minute 0 (i.e. the leading cron field is no longer
0). - Only the minute (first) field of each cron is changed; the hour, day-of-month, month, and day-of-week fields are preserved exactly so every workflow's cadence and any date guards remain unchanged (e.g. standards-sync.yml must still fire on Mondays so its first-Monday guard still works; idea-triage must still be Monday 13:xx UTC).
- Minutes are staggered across the edited workflows (not all set to one shared minute) and avoid :00 and its immediate neighborhood, so the change does not create a new self-inflicted burst at a single minute.
- agent-shield.yml is not modified at all, and thin-caller stubs are not changed beyond their cron minute; no behavior other than the cron minute is altered in any file.
- shellcheck/lint passes and
gh aw compilesucceeds for any edited agentic .md source (e.g. stale-manager.md).
Tasks / Subtasks
- Enumerate every minute-0 scheduled cron in this repo and confirm the target set (AC: test issue from agent #1)
- The 10 .yml workflows at minute 0: feature-ideation.yml (0 7 * * 5), standards-sync.yml (0 9 * * 1), daily-pr-review-health.yml (0 6 * * *), content-twin-audit.yml (0 7 * * *), docs-health-check.yml (0 0 * * 0), actions-fleet-monitor.yml (0 6 * * *), stale-manager.yml (0 9 * * 1), token-report.yml (0 8 * * 1), idea-enhancer.yml (0 7 * * 3), idea-triage.yml (0 13 * * 1)
- The agentic source stale-manager.md (its cron: '0 9 * * 1' header) -- keep it in sync with stale-manager.yml
- Note docs/aw/standards-sync.md carries an illustrative cron in a code block; update it for documentation consistency if it implies minute 0
- Assign each enumerated cron a distinct off-peak minute, editing only the minute field (AC: test issue from agent #1, Go-live improvements for PR review agent #2, Add @claude delegation, auto-merge, and rebase handling #3)
- Spread chosen minutes across the hour (e.g. picks drawn from :07 :11 :13 :19 :23 :29 :31 :37 :41 :43 :47 :53) so no two edited workflows share a minute
- Keep stale-manager.yml and stale-manager.md identical after the edit
- Leave already-off-peak crons as-is (pr-review-sweep.yml :17, dev-lead-retry.yml :15, initiative-driver.yml :23), re-staggering only if a collision is introduced (AC: Add @claude delegation, auto-merge, and rebase handling #3)
- Verify no protected/thin-caller file changed beyond its cron minute; run shellcheck and gh aw compile (AC: Optimize review: small-PR and incremental fast paths #4, feat: add Copilot engine support via REVIEW_ENGINE toggle #5)
Dev Notes
- Per GitHub docs (quoted in Improving reliability of scheduled GitHub Actions runs (cron is best-effort) #656): the schedule event is delayed during high load, and 'high load times include the start of every hour' -- moving off
0 * * * *is the lowest-cost, highest-leverage mitigation. Scheduled workflows run only on the default branch's latest commit (already satisfied here). - Changing only the minute keeps each workflow's intended time-of-day/day-of-week, which several workflows depend on: standards-sync.yml has a 'first Monday of month only' guard that re-derives the day from the run date, so the cron must still be a Monday; idea-triage is meant to land after Friday ideation; token-report is the weekly Monday report.
- Do NOT touch agent-shield.yml (exempt from agent modification per AGENTS.md / standards/agent-standards.md). Thin-caller stubs noted in CLAUDE.md/AGENTS.md (claude.yml, agent-shield.yml, auto-rebase.yml, dependabot-automerge.yml) have no minute-0 schedule, so none are in the target set -- but if any cron is edited in a thin caller, limit the change to the minute field only.
- This is a mechanical, low-risk edit. The complementary CI guard that prevents regressions and the standard that documents the convention are Story 2, which depends on this one landing first.
Project Structure Notes
All edits are confined to existing .github/workflows/*.yml and the stale-manager.md agentic source; no new files, scripts, or jobs. No script behavior changes.
References
- .github/workflows/feature-ideation.yml
- .github/workflows/standards-sync.yml#first-monday-guard
- .github/workflows/daily-pr-review-health.yml
- .github/workflows/content-twin-audit.yml
- .github/workflows/docs-health-check.yml
- .github/workflows/actions-fleet-monitor.yml
- .github/workflows/stale-manager.yml
- .github/workflows/stale-manager.md
- .github/workflows/token-report.yml
- .github/workflows/idea-enhancer.yml
- .github/workflows/idea-triage.yml
- AGENTS.md#workflow-files
- CLAUDE.md#key-guidelines
Likely target surface
.github/workflows/feature-ideation.yml.github/workflows/standards-sync.yml.github/workflows/daily-pr-review-health.yml.github/workflows/content-twin-audit.yml.github/workflows/docs-health-check.yml.github/workflows/actions-fleet-monitor.yml.github/workflows/stale-manager.yml.github/workflows/stale-manager.md.github/workflows/token-report.yml.github/workflows/idea-enhancer.yml.github/workflows/idea-triage.yml
Story prepared by the BMAD Scrum Master (Bob) for epic #722. Status: ready-for-dev.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
dev-leadFor dev-lead agent pickupFor dev-lead agent pickupinitiativeEpic / initiative tracking issueEpic / initiative tracking issue
Activity
don-petry commentedon Jul 14, 2026
Dev-Lead Implementation Plan
Issue: #723 — [Phase 1] Move all scheduled workflows off the top of the hour
Scope
Change the minute (first) field of every
schedule.cronthat fires at minute0to a distinct, staggered off-peak minute, preserving each cron's hour/day-of-month/month/day-of-week exactly so cadence and date guards are unchanged.Enumeration note (target set differs from the story's list)
The story's task list predates repo changes. Verified against current
main:idea-enhancer.ymlno longer exists — dropped from the set.readme-refresh.yml,auto-rebase-health.yml,premature-closure-audit.yml,skill-eval-report.yml..mdsource with a cron isstale-manager.md(spec doc). The realgh awsources (ci-failure-analyst.md,issue-triage.md,release-notes.md) have no schedule.agent-shield.ymlis exempt and untouched. No thin-caller stub other thanfeature-ideation.yml(minute-field-only edit) is in the set.Minute assignments (only the first field changes)
0 7 * * 57 7 * * 50 9 * * 111 9 * * 10 6 * * *13 6 * * *0 7 * * *19 7 * * *0 0 * * 021 0 * * 00 6 * * *27 6 * * *0 9 * * 129 9 * * 10 8 * * 134 8 * * 10 13 * * 137 13 * * 10 9 * * 141 9 * * 10 7 * * *43 7 * * *0 8 * * 149 8 * * 10 7 * * *51 7 * * *0 9 * * 129 9 * * 1All 13 minutes are distinct; none collide at a shared hour, none collide with the already-off-peak crons (pr-review-sweep 2/17/32/47, dev-lead-retry :15, initiative-driver :23, initiative-planner-canary :30, initiative-driver-canary :40); all avoid the :00 neighborhood.
Documentation consistency (illustrative crons in docs/aw mirrors)
docs/aw/standards-sync.md0 9 1-7 * 1→11 9 1-7 * 1docs/aw/docs-health-check.md0 0 * * 0→21 0 * * 0docs/aw/content-twin-audit.md0 7 * * *→19 7 * * *Adjacent human-readable time comments (e.g.
# Every Monday at 09:00 UTC) are updated to the new minute so they stay accurate; no other content changes.Tests
No test asserts a specific cron minute (verified:
test_skill_eval_report.batsonly checks a cron exists). This is a behavior-preserving configuration change, so per the dev-lead Phase-2 exception no new test is added; verification is by lint + a repo-wide check that no- cron: '0 ...'remains.Test / Verify Command
bash .dev-lead/scripts/dev-lead-lint.shplusbats tests/and a grep guard for residual minute-0 crons.don-petry commentedon Jul 14, 2026
Dev-Lead: Implementation Complete
Plan Execution
stale-manager.md(spec doc) in sync withstale-manager.ymldocs/awillustrative-cron mirrors for documentation consistencypr-review-sweep2/17/32/47,dev-lead-retry:15,initiative-driver:23,initiative-planner-canary:30,initiative-driver-canary:40) untouched — no collisions introducedagent-shield.ymlnot modifiedAcceptance Criteria
schedule.cronat minute 0 in.github/workflows/*.ymlor.md: verified by grep + parse (0 matches).standards-syncstays Monday (first-Monday guard intact),idea-triagestays Mon 13:xx.{7,11,13,19,21,27,29,34,37,41,43,49,51}, all clear of the :00 neighborhood and of the existing off-peak minutes; no two edited workflows (and none at a shared hour) collide.agent-shield.ymluntouched; thin-callerfeature-ideation.ymlchanged in the minute field only; no non-cron behavior altered in any file.dev-lead-lint.sh(shellcheck + profile validation) passes.gh aw compile: the only cron-bearing agentic.mdisstale-manager.md, a spec document — not a compilablegh awsource (real sourcesci-failure-analyst.md/issue-triage.md/release-notes.mdcarry no schedule and are unchanged), so no compile output changes.Enumeration note (story list was out of date vs.
main)idea-enhancer.ymlno longer exists — dropped.readme-refresh.yml,auto-rebase-health.yml,premature-closure-audit.yml,skill-eval-report.yml.Minute assignments
0 7 * * 5→7 7 * * 50 9 * * 1→11 9 * * 10 6 * * *→13 6 * * *0 7 * * *→19 7 * * *0 0 * * 0→21 0 * * 00 6 * * *→27 6 * * *0 9 * * 1→29 9 * * 10 8 * * 1→34 8 * * 10 13 * * 1→37 13 * * 10 9 * * 1→41 9 * * 10 7 * * *→43 7 * * *0 8 * * 1→49 8 * * 10 7 * * *→51 7 * * *0 9 1-7 * 1→11 9 1-7 * 10 0 * * 0→21 0 * * 00 7 * * *→19 7 * * *Verification output
Note:
batsis not installed in this environment, so thetests/suite runs in CI. No test asserts a specific cron minute (test_skill_eval_report.batsonly checks that a cron exists), so this behavior-preserving config change does not affect any assertion.Files Changed
16 files (14 minute edits +
stale-manager.mdsync + 3docs/awmirrors → 17 lines total). Each is a single-line change touching only the cron minute field.Notes
feat: implement issue #723 — [Phase 1] Move all scheduled workflows o…
feat: implement issue #723 — [Phase 1] Move all scheduled workflows o…
feat: implement issue #723 — [Phase 1] Move all scheduled workflows o…
feat: implement issue #723 — [Phase 1] Move all scheduled workflows o…
feat: implement issue #723 — [Phase 1] Move all scheduled workflows o…
feat: implement issue #723 — [Phase 1] Move all scheduled workflows o…
feat: implement issue #723 — [Phase 1] Move all scheduled workflows o…
feat: implement issue #723 — [Phase 1] Move all scheduled workflows o…
feat: implement issue #723 — [Phase 1] Move all scheduled workflows o…
feat: implement issue #723 — [Phase 1] Move all scheduled workflows o…
feat: implement issue #723 — [Phase 1] Move all scheduled workflows o…
feat: implement issue #723 — [Phase 1] Move all scheduled workflows o…
feat: implement issue #723 — [Phase 1] Move all scheduled workflows o…
feat: implement issue #723 — [Phase 1] Move all scheduled workflows o…
feat: implement issue #723 — [Phase 1] Move all scheduled workflows o…
feat: implement issue #723 — [Phase 1] Move all scheduled workflows o…
feat: implement issue #723 — [Phase 1] Move all scheduled workflows o…
feat: implement issue #723 — [Phase 1] Move all scheduled workflows o…
feat: implement issue #723 — [Phase 1] Move all scheduled workflows o…
feat: implement issue #723 — [Phase 1] Move all scheduled workflows o…