Skip to content

Relocate org-wide compliance rulesets (code-quality, pr-quality) from .github-private to .github/standards/rulesets/ #575

Closed

Description

@don-petry

Summary

Relocate the org-wide compliance ruleset JSONs (code-quality.json, pr-quality.json) from
petry-projects/.github-private/.github/rulesets/ to their correct canonical home,
petry-projects/.github/standards/rulesets/, and repoint the tooling. .github-private is reserved for
agents, skills, and their reusable workflows/assets — it must not be the source of truth for org-wide
compliance policy. This is a governance/placement cleanup that also unblocks safely evolving the
required-check set (coverage / secret-scan) for the repo-template initiative (epic #964).

Background — how this happened

Discovered during epic #964 (repo-template): a Copilot review flagged that adding coverage to the
shared code-quality.json would brick every repo lacking a coverage job — surfacing that this shared
org policy sits in the wrong repo.

Decision (the governance rule — now documented in .github/AGENTS.md)

  • Org-wide standards and compliance policy (CI/workflow templates, repo settings, labels, Dependabot
    policy, security config, and the codified compliance rulesets code-quality / pr-quality) are
    owned by petry-projects/.github; their canonical home is standards/.
  • petry-projects/.github-private is scoped to agents, skills, and their reusable workflows/assets.
    The one ruleset that legitimately stays there is release-channel-tags — it protects
    .github-private's own pr-review/** and dev-lead/** agent-release tags.
  • Rule of thumb: fleet-wide → .github/standards/; protects an agent/skill's own assets in
    .github-private → stays there. When in doubt, put it in .github and have .github-private consume it.

Scope of work

  1. Relocate JSONs — move code-quality.json + pr-quality.json to
    petry-projects/.github/standards/rulesets/. Leave release-channel-tags.json in .github-private.
  2. Repoint tooling
    • apply-rulesets.sh: change RULESETS_REPO / RULESETS_DIR defaults so the fleet rulesets resolve
      from .github; keep a path for the .github-private-local release-channel-tags.
    • bootstrap-new-repo.sh: read the fleet rulesets from .github.
    • Dedupe the two apply-rulesets.sh copies (.github/scripts/ vs .github-private/scripts/) —
      pick the canonical owner (the applier is org tooling → .github), or clearly delineate roles.
  3. Docs — standards/github-settings.md: point the code-quality / pr-quality "source of truth" refs
    at the new standards/rulesets/ location; add a Rulesets row to the AGENTS.md standards index.
  4. Migration safety — moving the source JSON does not change any repo's live ruleset (rulesets
    live on each repo). Verify: after relocation, apply-rulesets.sh --dry-run against a sample repo
    produces the identical payload it does today (no drift), and re-running is a no-op. No live ruleset is
    deleted/recreated as part of the move.
  5. Fold-in (epic Org Status — 2026-08-09 #964 / repo-template) — decide and implement the required-check set for the
    relocated code-quality:
    • Template + new repos should require the full producible set (incl. Secret scan (gitleaks) and the
      stack-aware coverage).
    • Fleet-wide addition of coverage requires backfilling a coverage job into existing repos first (they
      currently lack one) — otherwise it bricks them. Sequence: (a) ship the jobs via the template ci.yml
      and backfill existing repos, (b) then add the contexts to the shared ruleset. Until backfilled, keep
      the stricter set scoped to the template / new repos.

Acceptance criteria

  • code-quality.json + pr-quality.json live under petry-projects/.github/standards/rulesets/;
    removed from .github-private/.github/rulesets/ (only release-channel-tags.json remains there).
  • apply-rulesets.sh + bootstrap-new-repo.sh resolve fleet rulesets from .github by default;
    apply-rulesets.sh is de-duplicated (single canonical owner).
  • apply-rulesets.sh --dry-run on a sample repo yields a byte-identical payload pre/post move (proof
    of no live drift); re-run is a no-op.
  • standards/github-settings.md + AGENTS.md reference the new location; AGENTS.md carries the
    repo-boundary rule (done in the guidance PR).
  • Required-check-set change for code-quality is sequenced safely (no existing repo bricked); coverage
    is not added fleet-wide until repos produce it.

Out of scope

  • The fleet-wide coverage backfill itself (its own migration, referenced above).
  • release-channel-tags.json (correctly stays in .github-private).
  • Any change to what the checks do — this is a placement + sequencing cleanup.

Activity

  1. don-petry commented on Jul 2, 2026

    @don-petry
    ContributorAuthor

    Folded in from now-closed PRs #569 (.github) and #1001 (.github-private)

    Consolidating here so the check-set work happens in the right place (against the relocated ruleset), sequenced safely:

    Template ci.yml (produces the new required checks) — from #569, with review fixes to apply:

    • Add secret-scan job → check Secret scan (gitleaks) (canonical gitleaks job; free on public repos, GITLEAKS_LICENSE on private). Fix 1: drop security-events: write (no SARIF upload → over-privileged). Fix 2: run gitleaks with --config .gitleaks.toml per push-protection.md — which also means seeding a .gitleaks.toml baseline into the template (add to seed-repo-template.sh).
    • Add stack-aware coverage job → check coverage (default shell/bats via kcov; green-until-tests; per-stack expansion blocks). Forward-compatible: the template produces the check so the ruleset can require it once the fleet backfill lands.

    Ruleset check-set (against the relocated standards/rulesets/code-quality.json) — from #1001:

    • Add Secret scan (gitleaks) and coverage contexts only after existing repos produce them (fleet backfill), OR scope the stricter set to the template + new repos. Do NOT add coverage to the shared ruleset while existing repos lack a coverage job (would brick them — the original finding).

    github-settings.md §243 required-checks table reconciliation (SonarCloud, CodeQL, AgentShield, dependency-audit as codified; Dev-Lead per-PR; CI Pipeline repo-specific) moves here too, to land against the relocated ruleset rather than the .github-private copy.

  2. don-petry commented on Jul 2, 2026

    @don-petry
    ContributorAuthor

    Related tooling bug found during epic #964 — apply-repo-settings.sh check-suite precheck

    While applying settings to repo-template, scripts/apply-repo-settings.sh could not set the check-suite auto-trigger preferences even with a valid org-admin classic PAT (ghp_, repo + admin:org). Its read precheck bails before writing:

    [warn] petry-projects/repo-template: could not read check-suite preferences —
    verify GH_TOKEN has 'repo' scope (classic PAT) and the repo is accessible
    

    Impact: the standard path can't disable the Claude/CodeRabbit check-suite auto-trigger (the queued-but-never-completed suites that permanently block auto-merge) for anyone — the script always skips the write. This is separate from the known OAuth limitation: it fails on the check-suites API even with the correct classic PAT.

    Root cause (likely): the REST API has no plain GET for check-suite preferences, so the script's "read current prefs" precheck can't succeed; it then treats that as "cannot proceed" and returns before the PATCH.

    Workaround used: wrote directly via
    gh api -X PATCH repos/<owner>/<repo>/check-suites/preferences --input - with the classic PAT — succeeded and flipped Claude (app 1236702) + CodeRabbit (347564) auto-trigger to false, verified by API read-back.

    Fix: drop/replace the failing read-precheck so the script performs the PATCH directly (it's idempotent) and reports the resulting prefs from the PATCH response, rather than a separate read. Note apply-repo-settings.sh is duplicated in .github/scripts/ and .github-private/scripts/ — fix the canonical copy and dedupe alongside the apply-rulesets.sh dedup in this issue. Originally recorded on combsmith/.github-private#965.

  3. don-petry commented on Jul 3, 2026

    @don-petry
    ContributorAuthor

    ✅ Delivered — closing

    All acceptance criteria met; the relocation, tooling repoint, docs, and the folded-in check-set work are merged.

    Merged PRs

    PR What
    #577 Relocate code-quality + pr-quality JSON → standards/rulesets/ (byte-identical) + README + docs
    #582 pr-quality: require_last_push_approval: true (align codified with org policy; safe per #895)
    #578 Template ci.yml: secret-scan (gitleaks CLI, --config .gitleaks.toml, no security-events: write) + green-until-tests coverage
    combsmith/.github-private#1014 Seed .gitleaks.toml into repo-template (fetch:<standards-path>)
    #579 Reconcile §243 required-checks table to the codified set
    #590 Retire the detection-based apply-rulesets.sh → codified file-driven applier canonical in .github (closed #580)
    combsmith/.github-private#1013 Repoint applier + bootstrap-new-repo.sh to the .github fleet source

    AC status

    • JSONs in .github/standards/rulesets/; only release-channel-tags remains in .github-private
    • apply-rulesets.sh + bootstrap resolve fleet rulesets from .github; applier de-duplicated (detection-based one retired in feat(rulesets): retire detection-based apply-rulesets.sh; codified applier canonical in .github (#580) #590)
    • --dry-run byte-identical / update-in-place proven (no live drift, no recreate)
    • github-settings.md + AGENTS.md reference the new location
    • Required-check-set sequenced safely — coverage/secret-scan not added fleet-wide (would brick repos)

    Follow-ups (tracked separately, out of #575 scope)

    Closing.

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions