Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Read the relevant standard *before* making changes that touch CI, repo settings,
| **Workflow templates** | [`standards/workflows/`](https://github.com/petry-projects/.github/tree/main/standards/workflows) | Copy-paste-ready templates: `agent-shield.yml`, `dev-lead.yml`, `dependabot-automerge.yml`, `dependabot-rebase.yml`, `dependency-audit.yml`, `feature-ideation.yml` |
| **Agent configuration** | [`standards/agent-standards.md`](https://github.com/petry-projects/.github/blob/main/standards/agent-standards.md) | CLAUDE.md / AGENTS.md / SKILL.md required structure, frontmatter rules, cross-references |
| **Repo settings + labels** | [`standards/github-settings.md`](https://github.com/petry-projects/.github/blob/main/standards/github-settings.md) | Required settings, label set with exact colors, code-quality ruleset, branch protection |
| **Rulesets** | [`standards/rulesets/`](https://github.com/petry-projects/.github/tree/main/standards/rulesets) | Codified source-of-truth JSON for the org-wide `pr-quality` + `code-quality` rulesets (applied by `apply-rulesets.sh`). `release-channel-tags` stays repo-local in `.github-private` |
| **Dependabot config** | [`standards/dependabot-policy.md`](https://github.com/petry-projects/.github/blob/main/standards/dependabot-policy.md) and [`standards/dependabot/`](https://github.com/petry-projects/.github/tree/main/standards/dependabot) | Per-ecosystem dependabot.yml templates and policy |
| **Advanced Security (GHAS)** | [`standards/advanced-security.md`](https://github.com/petry-projects/.github/blob/main/standards/advanced-security.md) | Org-wide GHAS enablement via the "GitHub recommended" code security configuration, licensing model, and how to verify push protection actually enforces |
| **Push protection** | [`standards/push-protection.md`](https://github.com/petry-projects/.github/blob/main/standards/push-protection.md) | Secret scanning + push protection, local gitleaks hooks, CI secret-scan job, incident response |
Expand Down
9 changes: 9 additions & 0 deletions standards/github-settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,15 @@ silently drops a merge gate. `check_legacy_rulesets()` in
legacy ruleset and reports the exact migration delta (checks to move into
`code-quality` first, or "safe to delete").

**Source of truth.** The codified `pr-quality` and `code-quality` ruleset JSONs
live in this repo at [`standards/rulesets/`](rulesets/) — `.github` owns org-wide
compliance policy (see [`AGENTS.md`](../AGENTS.md#organization-standards) for the
repo-boundary rule, codified in #576). Run `apply-rulesets.sh` to converge each
repo's live ruleset to the desired state documented here. The one ruleset that stays in
`petry-projects/.github-private` is `release-channel-tags` — it protects that
repo's own `pr-review/**` and `dev-lead/**` agent-release tags and is therefore
correctly repo-local.

> **Remediating ruleset findings is a manual, admin-token procedure** —
> `compliance-remediate.sh` skips the `rulesets` category. Follow the
> [Ruleset Remediation Runbook](ruleset-remediation-runbook.md) (snapshot →
Expand Down
43 changes: 43 additions & 0 deletions standards/rulesets/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Repository Rulesets — codified source of truth

This directory holds the **org-wide compliance ruleset JSONs** for `petry-projects`.
`.github` owns org-wide standards and compliance policy; its canonical home is
`standards/`. See [`AGENTS.md`](../../AGENTS.md#organization-standards) for the
repo-boundary rule (codified in petry-projects/.github#576) and
[`standards/github-settings.md`](../github-settings.md#repository-rulesets) for how
these rulesets are enforced.

| File | Ruleset | Target | Enforces |
|------|---------|--------|----------|
| [`pr-quality.json`](pr-quality.json) | `pr-quality` | `~DEFAULT_BRANCH` | 1 approval, code-owner review, thread resolution, dismiss-stale, squash-only merge |
| [`code-quality.json`](code-quality.json) | `code-quality` | `~DEFAULT_BRANCH` | Required status checks (SonarCloud, CodeQL, agent-shield, dependency-audit) |

Both carry the two mandatory bypass actors — `OrganizationAdmin` and the
`dependabot-automerge-petry` Integration app (id `3167543`), both `bypass_mode: always`.

## Applying

These files are the **desired-state source of truth**. `scripts/apply-rulesets.sh`
creates/updates the named ruleset on a target repo to match — re-running is a no-op
when already in sync. Rulesets live **on each repo**; editing a file here changes the
desired state, not any live ruleset, until the applier runs.

```bash
# Preview the payload for one repo (no writes):
GH_TOKEN=<admin-token> bash scripts/apply-rulesets.sh <repo> --dry-run
```

## Scope boundary

- **Fleet-wide → here.** `pr-quality` / `code-quality` are org-wide policy.
- **Protects an agent/skill's own assets → stays in `.github-private`.**
`release-channel-tags` lives in `petry-projects/.github-private` because it
protects that repo's own `pr-review/**` and `dev-lead/**` release tags.

## Changing the required-check set

Adding a required status-check context to `code-quality.json` makes it a **merge
gate on every repo the ruleset targets**. A repo that does not *produce* that check
is bricked (the required check never reports). Sequence any additions safely: ship
the producing CI job fleet-wide first, then add the context here. Keep stricter sets
scoped to the template / new repos until the fleet backfill lands.
37 changes: 37 additions & 0 deletions standards/rulesets/code-quality.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"name": "code-quality",
"target": "branch",
"enforcement": "active",
"bypass_actors": [
{
"actor_type": "OrganizationAdmin",
"bypass_mode": "always"
},
{
"actor_id": 3167543,
"actor_type": "Integration",
"bypass_mode": "always"
}
],
"conditions": {
"ref_name": {
"include": ["~DEFAULT_BRANCH"],
"exclude": []
}
},
"rules": [
{
"type": "required_status_checks",
"parameters": {
"required_status_checks": [
{"context": "SonarCloud"},
{"context": "CodeQL"},
{"context": "agent-shield / AgentShield"},
{"context": "dependency-audit / Detect ecosystems"}
],
"strict_required_status_checks_policy": true,
"do_not_enforce_on_create": false
}
}
]
}
36 changes: 36 additions & 0 deletions standards/rulesets/pr-quality.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"name": "pr-quality",
"target": "branch",
"enforcement": "active",
"bypass_actors": [
{
"actor_type": "OrganizationAdmin",
"bypass_mode": "always"
},
{
"actor_id": 3167543,
"actor_type": "Integration",
"bypass_mode": "always"
}
],
"conditions": {
"ref_name": {
"include": ["~DEFAULT_BRANCH"],
"exclude": []
}
},
"rules": [
{
"type": "pull_request",
"parameters": {
"required_approving_review_count": 1,
"require_code_owner_review": true,
"required_review_thread_resolution": true,
"dismiss_stale_reviews_on_push": true,
"require_last_push_approval": true,
"automatic_copilot_code_review_enabled": false,
"allowed_merge_methods": ["squash"]
}
}
]
}
Loading