Overview
Add a scheduled GitHub Actions workflow (.github/workflows/health.yml) that runs daily, audits the health of the repository and Ballast installation, and produces a structured report surfaced as a workflow summary and optionally as a GitHub issue comment.
The /github-health-check skill provides an on-demand version of this check. This issue covers the automated daily scheduled variant with a persistent, trend-aware report format.
Goals
- Give maintainers a daily signal on repository health without manual inspection.
- Surface actionable items (stale PRs, failing checks, security alerts, drift from Ballast config) in one place.
- Establish a baseline so trends (improving / degrading) are visible over time.
- Follow GitHub Actions and open-source repo hygiene best practices.
Workflow Requirements
Schedule and Triggers
- Run on
schedule at a fixed daily time (e.g. cron: '0 7 * * *' — 07:00 UTC).
- Support
workflow_dispatch for on-demand runs.
- Add a
concurrency block so overlapping scheduled runs are cancelled:
concurrency:
group: ${{ github.workflow }}
cancel-in-progress: true
Permissions
- Use least-privilege permissions scoped to the job:
contents: read
issues: write (only if posting to issues)
pull-requests: read
security-events: read
- Use
GITHUB_TOKEN; no long-lived PAT required.
Implementation
- Use the
gh CLI (available in actions/checkout runners) and the GitHub REST/GraphQL API via gh api for all data gathering.
- Write the report generation as a shell script (
scripts/health-report.sh) so it is testable locally with gh auth login.
- Publish the full report to the GitHub Actions workflow summary (
$GITHUB_STEP_SUMMARY) so it is visible directly in the Actions UI without navigating elsewhere.
- Optionally open or update a pinned GitHub issue tagged
health-report with the latest report body (use gh issue edit to update in place).
- Upload the raw JSON data as a workflow artifact (
health-report.json) for retention and future trend analysis.
Report Sections and Requirements
Each section uses a consistent structure: a header, a status badge (✅ healthy / ⚠️ needs attention / 🔴 critical), a summary line, and a bulleted detail list with direct links.
1. CI / Workflow Health
Answers: Are our automated checks passing reliably?
- Last 7-day pass rate for each workflow in
.github/workflows/.
- Current status of the most recent run per workflow (pass / fail / cancelled / skipped).
- Average duration trend for the primary CI workflow (faster / slower than last week).
- Any workflow that has not run in the past 7 days (possibly broken trigger).
- Flag any workflow without a
concurrency block (risk of redundant runs).
Threshold: 🔴 if any required workflow (lint, test, build, publish) has a <80% pass rate over 7 days.
2. Security Posture
Answers: Are there known vulnerabilities or exposed secrets?
- Count of open Dependabot alerts by severity (critical / high / medium / low).
- Count of open secret scanning alerts with types (e.g. GitHub token, AWS key).
- Count of open code scanning alerts (if CodeQL or similar is enabled).
- Date of oldest unresolved critical/high alert.
- Whether Dependabot is enabled and has an up-to-date
.github/dependabot.yml.
- Whether branch protection requires passing status checks before merge.
Threshold: 🔴 if any critical Dependabot or secret scanning alert is unresolved. ⚠️ for high severity alerts older than 14 days.
3. Dependency and PR Hygiene
Answers: Are we keeping dependencies current and landing work promptly?
- Count of open Dependabot PRs grouped by ecosystem (npm, go, github-actions).
- Age of oldest open Dependabot PR (stale = >14 days).
- Total open PRs, count stale (no activity >7 days), count awaiting review >48 h.
- Count of draft PRs older than 7 days (possibly abandoned).
- Count of PRs with failing checks that are not drafts.
- Merge frequency: PRs merged in the last 7 days.
Threshold: ⚠️ if any Dependabot PR is >14 days old or any non-draft PR has been waiting for review >7 days.
4. Branch Hygiene
Answers: Is the branch graph clean?
- Count of branches with no commit activity in >30 days (stale).
- Count of branches that are fully merged into
main but not deleted.
- Whether
main is the default branch and has branch protection enabled.
- Required status checks configured on
main (list which workflows are required).
- Whether direct pushes to
main are blocked (force-push protection).
Threshold: ⚠️ if >5 stale or fully-merged branches exist. 🔴 if main has no branch protection.
5. Issue Health
Answers: Are open issues being triaged and resolved?
- Total open issues and trend vs. 7 days ago (growing / shrinking / stable).
- Count of issues with no response (no comment, no label, no assignee) older than 7 days.
- Count of issues open >30 days with no activity (stale).
- Count of issues labelled
bug open >14 days.
- Count of issues labelled
health-report (the pinned daily report issue — should be exactly 1).
Threshold: ⚠️ if >10 issues have had no triage activity in >7 days.
6. Release and Publish Health
Answers: Is the release pipeline working and are we shipping regularly?
- Date and tag of the most recent GitHub release.
- Days since last release (flag if >30 days and the repo is actively developed).
- Status of the most recent publish workflow run (pass / fail).
- Whether the version in
package.json / go.mod / pyproject.toml matches the latest release tag.
- Whether the latest release has release notes.
Threshold: ⚠️ if the last publish workflow run failed or if the version file is out of sync with the latest tag.
7. Repository Configuration
Answers: Does the repo have the baseline hygiene files and settings?
- Required files present:
README.md, LICENSE, CONTRIBUTING.md or AGENTS.md, SECURITY.md, CHANGELOG.md.
.github/CODEOWNERS present.
.github/dependabot.yml present and covers both npm/go/pip and github-actions.
- Discussions enabled or issues enabled (at least one engagement channel).
- Repository description and homepage URL set.
- Topics / tags set (helps discoverability).
Threshold: ⚠️ for any missing required file. 🔴 if LICENSE is absent.
8. Ballast Installation Health
Answers: Is Ballast configured correctly and are rule files current?
.rulesrc.json is present and parseable.
ballastVersion in .rulesrc.json matches the latest published Ballast release on npm (ballast-typescript).
- All configured targets (
cursor, claude, codex, opencode, gemini) have their expected rule directories and files present.
- All configured agents have corresponding rule files for each target (no missing rule files).
taskSystem field is present in .rulesrc.json when the tasks agent is configured.
- Skills listed in
.rulesrc.json have corresponding .skill files.
- Run
ballast doctor and report its exit code and output summary.
Threshold: 🔴 if .rulesrc.json is missing or ballast doctor exits non-zero. ⚠️ if ballastVersion is more than one minor version behind the latest release.
Report Format (Markdown Summary)
# 🏥 Daily Repository Health Report — 2026-04-27
| Area | Status | Summary |
|------|--------|---------|
| CI / Workflows | ✅ | All 5 workflows passing (7-day rate: 97%) |
| Security | ⚠️ | 3 high Dependabot alerts open >7 days |
| Dependencies / PRs | ✅ | 2 Dependabot PRs open, oldest 3 days |
| Branch Hygiene | ✅ | 1 stale branch, main protected |
| Issues | ✅ | 12 open, 0 untriaged >7 days |
| Releases | ✅ | Last release v5.8.0 on 2026-04-20 |
| Repo Config | ✅ | All required files present |
| Ballast Health | ✅ | v5.8.0 installed, doctor exit 0 |
---
## ⚠️ Needs Attention
- **Security**: [dependabot/npm_and_yarn/…](#) — high severity, open 9 days → [View alert](…)
- **Security**: [dependabot/npm_and_yarn/…](#) — high severity, open 12 days → [View alert](…)
## Details
<details><summary>CI / Workflow Health</summary>…</details>
<details><summary>Security Posture</summary>…</details>
…
Acceptance Criteria
References
Overview
Add a scheduled GitHub Actions workflow (
.github/workflows/health.yml) that runs daily, audits the health of the repository and Ballast installation, and produces a structured report surfaced as a workflow summary and optionally as a GitHub issue comment.The
/github-health-checkskill provides an on-demand version of this check. This issue covers the automated daily scheduled variant with a persistent, trend-aware report format.Goals
Workflow Requirements
Schedule and Triggers
scheduleat a fixed daily time (e.g.cron: '0 7 * * *'— 07:00 UTC).workflow_dispatchfor on-demand runs.concurrencyblock so overlapping scheduled runs are cancelled:Permissions
contents: readissues: write(only if posting to issues)pull-requests: readsecurity-events: readGITHUB_TOKEN; no long-lived PAT required.Implementation
ghCLI (available inactions/checkoutrunners) and the GitHub REST/GraphQL API viagh apifor all data gathering.scripts/health-report.sh) so it is testable locally withgh auth login.$GITHUB_STEP_SUMMARY) so it is visible directly in the Actions UI without navigating elsewhere.health-reportwith the latest report body (usegh issue editto update in place).health-report.json) for retention and future trend analysis.Report Sections and Requirements
Each section uses a consistent structure: a header, a status badge (
✅ healthy/⚠️ needs attention/🔴 critical), a summary line, and a bulleted detail list with direct links.1. CI / Workflow Health
Answers: Are our automated checks passing reliably?
.github/workflows/.concurrencyblock (risk of redundant runs).Threshold:
🔴if any required workflow (lint, test, build, publish) has a <80% pass rate over 7 days.2. Security Posture
Answers: Are there known vulnerabilities or exposed secrets?
.github/dependabot.yml.Threshold:
🔴if any critical Dependabot or secret scanning alert is unresolved.⚠️for high severity alerts older than 14 days.3. Dependency and PR Hygiene
Answers: Are we keeping dependencies current and landing work promptly?
Threshold:
⚠️if any Dependabot PR is >14 days old or any non-draft PR has been waiting for review >7 days.4. Branch Hygiene
Answers: Is the branch graph clean?
mainbut not deleted.mainis the default branch and has branch protection enabled.main(list which workflows are required).mainare blocked (force-push protection).Threshold:
⚠️if >5 stale or fully-merged branches exist.🔴ifmainhas no branch protection.5. Issue Health
Answers: Are open issues being triaged and resolved?
bugopen >14 days.health-report(the pinned daily report issue — should be exactly 1).Threshold:
⚠️if >10 issues have had no triage activity in >7 days.6. Release and Publish Health
Answers: Is the release pipeline working and are we shipping regularly?
package.json/go.mod/pyproject.tomlmatches the latest release tag.Threshold:
⚠️if the last publish workflow run failed or if the version file is out of sync with the latest tag.7. Repository Configuration
Answers: Does the repo have the baseline hygiene files and settings?
README.md,LICENSE,CONTRIBUTING.mdorAGENTS.md,SECURITY.md,CHANGELOG.md..github/CODEOWNERSpresent..github/dependabot.ymlpresent and covers bothnpm/go/pipandgithub-actions.Threshold:
⚠️for any missing required file.🔴ifLICENSEis absent.8. Ballast Installation Health
Answers: Is Ballast configured correctly and are rule files current?
.rulesrc.jsonis present and parseable.ballastVersionin.rulesrc.jsonmatches the latest published Ballast release on npm (ballast-typescript).cursor,claude,codex,opencode,gemini) have their expected rule directories and files present.taskSystemfield is present in.rulesrc.jsonwhen thetasksagent is configured..rulesrc.jsonhave corresponding.skillfiles.ballast doctorand report its exit code and output summary.Threshold:
🔴if.rulesrc.jsonis missing orballast doctorexits non-zero.⚠️ifballastVersionis more than one minor version behind the latest release.Report Format (Markdown Summary)
Acceptance Criteria
.github/workflows/health.ymlruns on schedule (0 7 * * *) andworkflow_dispatch.$GITHUB_STEP_SUMMARYand visible in the Actions UI.health-report.jsonartifact with 90-day retention.health-reportis created/updated with the report on each run.ballast doctoris run as part of the Ballast Health section.GITHUB_TOKENonly.scripts/health-report.shand can be run locally.References
/github-health-checkskill — on-demand equivalent of this workflow