{"id":50522234,"url":"https://github.com/thrillmade/reporulez","last_synced_at":"2026-06-03T05:04:10.120Z","repository":{"id":357991029,"uuid":"1239400859","full_name":"thrillmade/reporulez","owner":"thrillmade","description":"Default rule sets for ai driven dev","archived":false,"fork":false,"pushed_at":"2026-05-27T02:07:58.000Z","size":102,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-27T03:26:55.380Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thrillmade.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-05-15T03:59:01.000Z","updated_at":"2026-05-27T02:08:01.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/thrillmade/reporulez","commit_stats":null,"previous_names":["thrillmot/reporulez","thrillmade/reporulez"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/thrillmade/reporulez","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thrillmade%2Freporulez","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thrillmade%2Freporulez/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thrillmade%2Freporulez/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thrillmade%2Freporulez/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thrillmade","download_url":"https://codeload.github.com/thrillmade/reporulez/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thrillmade%2Freporulez/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33848882,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-03T02:00:06.370Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-03T05:04:09.182Z","updated_at":"2026-06-03T05:04:10.113Z","avatar_url":"https://github.com/thrillmade.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# reporulez\n\nDrop-in GitHub repository rulesets tuned for AI-driven development.\n\nThe goal: let an AI agent branch → push → open a PR → wait for checks → merge, without\nbypassing safety.\n\n**What the ruleset alone enforces (always on):** PRs are required (no direct pushes to\nthe default branch), force pushes and default-branch deletions are blocked, linear history\nrequired, squash-only merges, stale reviews dismissed on push, last-push approval required,\n**any** review thread that gets created must be resolved before merge.\n\n**What it does *not* enforce until you configure more:** that a review actually happens,\nand that CI checks pass. The `copilot` variant adds GitHub Copilot auto-review (advisory\ncomments) so threads get created on every PR. The `external` variant assumes you've\ninstalled a non-Copilot AI reviewer App that does the same — without one, the\nthread-resolution gate has nothing to gate on. Status checks: the ruleset deliberately\n**does not include a `required_status_checks` rule** (GitHub's API rejects that rule\nwith an empty list, and we can't know your CI workflow names). Add it yourself after\ninstall via the GitHub UI. Until you do (and until your AI reviewer is installed for the\n`external` variant), the structural rules above are the only merge gates, and an empty\nPR can be self-merged.\n\nThe `--human-review` flag layers on a required human approval if you want a person in the\nloop as well.\n\n## Quickstart\n\n```sh\n# Default: Copilot auto-review enabled, no human approval required (full AI auto-mode).\ncurl -fsSL https://raw.githubusercontent.com/thrillmade/reporulez/main/bin/apply.sh \\\n  | bash -s -- owner/repo\n\n# With a human-in-the-loop approval gate:\ncurl -fsSL https://raw.githubusercontent.com/thrillmade/reporulez/main/bin/apply.sh \\\n  | bash -s -- owner/repo copilot --human-review\n\n# If you already use a non-Copilot AI reviewer (Claude Code Review, CodeRabbit, Cursor, …):\ncurl -fsSL https://raw.githubusercontent.com/thrillmade/reporulez/main/bin/apply.sh \\\n  | bash -s -- owner/repo external\n\n# Full clud-bug + logmind stack (canonical 4 contexts ship in the variant;\n# Repository admin bypass for clud-bug self-mod PRs is ON BY DEFAULT for\n# this variant), plus your project's pytest matrix as extra required checks:\ncurl -fsSL https://raw.githubusercontent.com/thrillmade/reporulez/main/bin/apply.sh \\\n  | bash -s -- owner/repo clud-bug-logmind \\\n      --extra-check 'pytest (ubuntu-latest / py3.10)' \\\n      --extra-check 'pytest (ubuntu-latest / py3.12)'\n```\n\n`--extra-check 'CONTEXT NAME'` is repeatable and appends project-specific status\ncheck contexts to the variant's `required_status_checks` list at apply time. Lets\na single command match a project's actual CI without forking the variant JSON.\nOnly works against variants that ship `required_status_checks` (currently\n`clud-bug-logmind`); errors cleanly on `copilot`/`external` since they deliberately\nomit that rule.\n\n`--bypass-admin` adds the **Repository admin** role to `bypass_actors`. **Default\nON for `clud-bug-logmind`** (the self-mod use case practically always needs it);\ndefault OFF for `copilot`/`external`. Override the per-variant default with\n`--no-bypass-admin` to force off, or `--bypass-admin` to force on. See\n[Admin bypass flag](#admin-bypass-flag) below for the rationale.\n\nRequires the [`gh`](https://cli.github.com) CLI authenticated against the target repo, and `jq`.\n\n## Variants\n\n| Variant | Copilot auto-review | Required status checks | Use when |\n|---|---|---|---|\n| `copilot` (default) | enabled via the `copilot_code_review` ruleset rule | none — add manually after install | You want GitHub's built-in reviewer to comment on every PR. |\n| `external` | not included | none — add manually after install | You've installed a non-Copilot AI reviewer GitHub App that already comments on every PR — e.g. [**clud-bug**](https://github.com/thrillmade/clud-bug) (Claude-powered, project-aware, one-command install), CodeRabbit, Cursor, or Anthropic's Claude Code Review App. |\n| `clud-bug-logmind` | not included | `clud-bug-review`, `check-derived-docs`, `check-decisions`, `check-links` — **strict** (branches must be up to date) | Canonical bundle for repos with **both** [**clud-bug**](https://github.com/thrillmade/clud-bug) and [**logmind**](https://logmind.dev) installed. Extends `external` with the four well-known check contexts both tools ship + strict-mode so logmind v0.2's derived-file conflict-free property stays sound. |\n\n\u003e 💡 Pairs nicely with [**clud-bug**](https://github.com/thrillmade/clud-bug): a one-command (`npx clud-bug init`) install of a Claude PR-review GitHub Action that auto-discovers project-aware review skills from [skills.sh](https://skills.sh) and resolves its own review threads when issues are fixed — which is exactly what the `required_review_thread_resolution` gate in this ruleset is designed to lean on. This repo itself uses clud-bug; see PR #2 / #3 for live review examples.\n\nAll three variants share the structural rules: PR required, force push and deletion blocked,\nlinear history, squash-only merges, dismiss stale reviews, all threads must resolve.\nThe `copilot` and `external` variants **deliberately omit** a `required_status_checks` rule\n(GitHub's API rejects an empty list, and we can't know your CI workflow names) — add the\nrule with your contexts manually after install. The `clud-bug-logmind` variant skips that\nmanual step because we *do* know the canonical contexts when both tools are installed.\n\n\u003e **Note on `clud-bug-logmind`'s strict mode:** `strict_required_status_checks_policy: true`\n\u003e in this variant is load-bearing for logmind v0.2's per-PR derived-file model (`docs/timeline.md`\n\u003e regenerated on every PR). Without rebase-before-merge, two concurrent PRs can each pass\n\u003e `check-derived-docs` independently and then deadlock on conflicting regens at merge time.\n\u003e If logmind ever changes that model (e.g. v0.3 auto-merges `timeline.md`), revisit whether\n\u003e strict mode is still required here.\n\n`require_last_push_approval` defaults to `false`. It would deadlock merges in 0-approval\nmode (`require_last_push_approval: true` + `required_approving_review_count: 0` means\n\"the last push must be approved by a non-pusher, but no one is required to approve\" —\nGitHub blocks merge forever). `--human-review` flips both fields together (count → 1,\nlast-push-approval → true) so the human approver requirement and the non-pusher\nrequirement stay consistent.\n\n### Human approval flag\n\n`--human-review` patches `required_approving_review_count` from `0` to `1`. Approvals\nmust come from a **human** — both GitHub Copilot code review and Anthropic's Claude\nCode Review GitHub App submit *Comment* reviews only, never *Approve*, so they cannot\nsatisfy this count. (Bots that *can* approve, like CodeRabbit's auto-approve, do.)\n\nThe default `required_approving_review_count: 0` is intentional for AI-driven flows:\nthe merge gate is the **thread-resolution + status-check** combination, not an approval\ncount. An AI reviewer (clud-bug, Claude Code Review, Copilot, CodeRabbit) creates\nreview threads that must be resolved, plus the required status checks must be green\n— there's no count to satisfy because no approvals were ever required to begin with.\nPass `--human-review` only if you want to layer a human approver on top.\n\n### Admin bypass flag\n\n`--bypass-admin` pre-populates `bypass_actors` with the **Repository admin** role\n(`actor_type: RepositoryRole`, `actor_id: 5`, `bypass_mode: always`).\n\n**Per-variant default:**\n- `clud-bug-logmind` → **ON by default** (the variant's self-mod use case practically\n  always needs the bypass — without it every routine clud-bug self-mod deadlocks).\n  Use `--no-bypass-admin` to opt out.\n- `copilot`, `external` → **OFF by default** (no built-in self-mod use case).\n  Pass `--bypass-admin` to opt in.\n\n**Why it matters for clud-bug:** `clud-bug`'s reviewer action (`anthropics/claude-code-action`)\ndeliberately refuses (HTTP 401) to review pull requests that modify its own workflow\nfiles under `.github/workflows/clud-bug-*.yml`. This is a self-mod guard — without it,\na malicious PR could rewrite the reviewer to rubber-stamp itself. The cost is that\n*legitimate* self-mod PRs (e.g. routine `npx clud-bug upgrade` version bumps) also\nfail the required `clud-bug-review` check and deadlock against `required_status_checks`.\n\nThree ways out:\n1. **`--bypass-admin` (default ON for `clud-bug-logmind`):** a repo admin can merge\n   the stuck PR via \"Bypass branch protections\" without touching the ruleset.\n2. **Hand-PATCH `bypass_actors` mid-merge** via `gh api --method PUT repos/$REPO/rulesets/$ID`\n   — works once, but every fresh install needs the same manual setup.\n3. **Toggle `enforcement: disabled` globally**, merge, re-enable — opens a real\n   policy-gap window where the ruleset doesn't protect *anything*.\n\nThe flag works with any variant; we made it the default ONLY for `clud-bug-logmind`\nbecause that's the variant whose required-checks list is opinionated about clud-bug\nspecifically, and clud-bug's self-mod ceremony is a normal recurring flow there.\n\n**Org repos:** the `RepositoryRole` admin role exists on both personal and org-managed\nrepos, so `--bypass-admin` works in both contexts. Org owners on an org-managed repo\nalready inherit admin access to the repo and can use the same bypass. If you want a\n*separate* org-administrator bypass entry (`actor_type: OrganizationAdmin`, `actor_id: 1`),\nadd it manually after install — including it by default would 404 on personal repos.\n\n## What gets configured\n\nThe installer applies two things:\n\n1. **A repository ruleset** (`reporulez-default`) targeting the default branch:\n   - PR required, with last-push approval, thread resolution, stale-review dismissal\n   - Block default-branch deletion\n   - Block force pushes\n   - Require linear history\n   - Allowed merge methods: `squash`\n   - (copilot variant only) Copilot code review on every push, not on drafts\n\n   The ruleset deliberately **does not include a `required_status_checks` rule**.\n   GitHub's API rejects that rule with an empty list, and we can't know your CI\n   workflow names — you add the rule yourself after install (see step 1 below).\n2. **Repository settings** that rulesets can't control:\n   - Auto-merge enabled\n   - Squash-only merging\n   - Delete head branch on merge\n   - Squash commit title = PR title, message = PR body\n\nThe script is idempotent — running it twice updates the existing ruleset instead of creating a duplicate.\n\n## After install — manual steps\n\n1. **Add a `Require status checks to pass` rule** with your CI workflow names.\n   - **`copilot` / `external` variants:** the ruleset ships without this rule\n     (GitHub's API rejects an empty list, and we can't know your workflow names).\n     Add it via Settings → Rules → Rulesets → `reporulez-default` → \"Require\n     status checks to pass\".\n   - **`clud-bug-logmind` variant: skip this step.** The ruleset already ships\n     this rule with the four canonical contexts (`clud-bug-review`,\n     `check-derived-docs`, `check-decisions`, `check-links`) and strict mode on.\n     Editing the rule manually here will clobber those contexts.\n2. **Drop in templates** if you want:\n   ```sh\n   curl -fsSL https://raw.githubusercontent.com/thrillmade/reporulez/main/templates/CODEOWNERS \\\n     -o .github/CODEOWNERS\n   curl -fsSL https://raw.githubusercontent.com/thrillmade/reporulez/main/templates/pull_request_template.md \\\n     -o .github/pull_request_template.md\n   ```\n\n   **Dependabot templates** under `templates/dependabot/` cover the realistic\n   shapes thrillmade-org repos land on. Pick one and curl it into\n   `.github/dependabot.yml`:\n\n   | Template | Ecosystems | Use when |\n   |---|---|---|\n   | `python.yml` | pip + github-actions | Python projects (pyproject.toml / requirements.txt at repo root). |\n   | `typescript.yml` | npm + github-actions | TS/JS projects (package.json at repo root; duplicate the npm entry per workspace for a monorepo). |\n   | `github-actions-only.yml` | github-actions only | Repos with no runtime package manifest — shell-script repos, docs-only repos, config-only repos. (reporulez itself ships this one.) |\n\n   All three use a weekly Monday cadence with an `open-pull-requests-limit` of\n   5 per ecosystem. Edit the file after curling if you need a different cadence,\n   subdirectory, or label set.\n\n   ```sh\n   # Pick the one that matches your repo:\n   curl -fsSL https://raw.githubusercontent.com/thrillmade/reporulez/main/templates/dependabot/python.yml \\\n     -o .github/dependabot.yml\n   ```\n\n   Or skip the curl: `apply.sh` will write the chosen template directly to the\n   target repo if you pass `--with-dependabot=\u003cecosystem\u003e` on the same invocation:\n\n   ```sh\n   ./bin/apply.sh owner/repo clud-bug-logmind --with-dependabot=python\n   ```\n\n   Idempotent — re-running with the same flag is a no-op when the file is\n   already current. Silently overwrites a different existing\n   `.github/dependabot.yml` (consistent with how `--extra-check` and the\n   other flags overwrite the ruleset on re-apply).\n\n   \u003e **Known limitation** (ecosystem switch on re-apply, copilot/external\n   \u003e only): switching the `--with-dependabot=\u003ceco\u003e` value on a repo\n   \u003e that already has the ruleset applied will fail the contents PUT\n   \u003e because the existing ruleset's `pull_request` rule blocks direct\n   \u003e default-branch writes. The `--bypass-admin` flag does **not** help\n   \u003e here — it only mutates the in-memory ruleset JSON that step 3\n   \u003e applies; it does not patch the existing ruleset that step 2's\n   \u003e PUT runs against. The actual prerequisite is that the target\n   \u003e repo's *existing* ruleset already contains Repository admin in\n   \u003e `bypass_actors`. For `clud-bug-logmind` that's the variant\n   \u003e default, so first-time AND ecosystem-switching applies both\n   \u003e work. For `copilot`/`external`, only first-apply and idempotent\n   \u003e re-apply work without manual intervention; ecosystem-switching\n   \u003e requires either temporarily editing the existing ruleset on\n   \u003e GitHub (Settings → Rules → Rulesets → `reporulez-default` →\n   \u003e add Repository admin to `Bypass list`) or temporarily deleting\n   \u003e the existing ruleset before re-applying.\n3. **Verify entitlement / app install:**\n   - `copilot` variant: the repo must have Copilot code review available (Pro / Pro+ / Business).\n   - `external` variant: an AI reviewer GitHub App must be installed and configured.\n   - `clud-bug-logmind` variant: **both** [clud-bug](https://github.com/thrillmade/clud-bug)\n     **and** [logmind](https://logmind.dev) must be installed on the target repo\n     (run `npx clud-bug init` and `logmind init --all-agents --install-hook`).\n     The shipped `required_status_checks` rule pins four contexts that come from\n     those tools' workflows; if either tool is missing, those checks will never\n     report and every PR will block forever (`strict_required_status_checks_policy: true`).\n\n## Auditing drift across repos\n\nOnce `apply.sh` has run on a repo, its canonical settings (auto-merge,\nsquash-only, delete-on-merge, etc.) can still be flipped from the\nGitHub UI or via a direct `gh api PATCH`. `bin/audit.sh` is a\nread-only drift detector that surfaces those flips without touching\nanything:\n\n```sh\n# Audit one or a few repos:\n./bin/audit.sh thrillmade/logmind thrillmade/clud-bug\n\n# Audit every non-archived repo under an org:\n./bin/audit.sh --all thrillmade\n\n# Also check ruleset coverage (org or repo-level rulesets, with the\n# structural rules every reporulez variant ships):\n./bin/audit.sh --all thrillmade --include-ruleset\n\n# Quieter: only print rows that drifted, hide ✓ matches\n./bin/audit.sh --all thrillmade --quiet\n\n# CI-gate mode: exit 1 when ANY drift detected\n./bin/audit.sh --all thrillmade --strict\n```\n\nEach repo's seven canonical settings (the same ones `apply.sh`\nPATCHes) are checked against the expected values. Output: one ✓ or ✗\nper setting per repo, with a final summary.\n\n**With `--include-ruleset`**, the audit also queries each repo's\nactive rulesets (org-level inherited or repo-level) and verifies the\nstructural rule types every reporulez variant ships:\n\n- `deletion` rule (no default-branch deletion)\n- `non_fast_forward` rule (no force-push to default)\n- `required_linear_history` rule (squash-only merge history)\n- `pull_request` rule (PRs required for default-branch writes)\n\nVariant-specific bits (`required_status_checks` contents,\n`bypass_actors` content, `copilot_code_review`) are intentionally\nnot checked — too variant-specific to flag generically.\n\n**Limitation**: `--all \u003cowner\u003e` uses `GET orgs/\u003cowner\u003e/repos`, which\n404s on personal accounts. Works for any GitHub org. For personal\naccounts, pass explicit positional `\u003cuser\u003e/\u003crepo\u003e` arguments.\n\n**Drift is INFORMATIONAL by default** — the audit always exits 0,\nbecause repos may legitimately diverge (e.g. a docs repo with\nauto-merge disabled during active editing, or a repo running a\ndifferent merge policy on purpose). The script surfaces divergence;\nthe human decides whether each instance is intentional or stale.\n\nUse `--strict` to flip the policy when you do want an enforcement\ngate (e.g. a scheduled CI workflow that fails on any drift).\n\n**Remediation when drift is unintentional**: re-run `apply.sh \u003crepo\u003e\n\u003cvariant\u003e` to reset everything to the canonical values. `apply.sh` is\nidempotent, so a re-apply is safe.\n\n## Upgrading logmind\n\nAfter bumping the logmind CLI, re-run `logmind init` to refresh the shipped\nworkflow templates:\n\n```sh\npipx install --force logmind     # or: pip install --upgrade logmind\nlogmind init                     # idempotent refresh in v0.2.1+ — rewrites\n                                 # workflow templates in place, leaves\n                                 # docs/ and .logmind/ untouched\n```\n\nFor clud-bug, see [thrillmade/clud-bug](https://github.com/thrillmade/clud-bug)'s\nREADME for the current upgrade flow.\n\n## Hand-import without the script\n\nIf you don't want to run a shell script (e.g. inside CI), import the JSON directly:\n\n```sh\ngh api --method POST repos/owner/repo/rulesets \\\n  --input rulesets/copilot.json\n```\n\nTo require a human approval in this path, edit the JSON's `required_approving_review_count` to `1` first.\n\n## Out of scope (for now)\n\n- Org-level rulesets (use repo-level for now; org-level lives at a different API path)\n- Tag protection\n- Push rulesets (file paths, file sizes, etc.)\n- Required signed commits — high friction for AI agents without signing keys\n- Environment / deployment protection rules\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthrillmade%2Freporulez","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthrillmade%2Freporulez","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthrillmade%2Freporulez/lists"}