diff --git a/.coderabbit.yaml b/.coderabbit.yaml new file mode 100644 index 00000000..8e4c1c03 --- /dev/null +++ b/.coderabbit.yaml @@ -0,0 +1,85 @@ +# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json +# +# CodeRabbit reviews every pull request against the review standard in +# .github/instructions/code-review.instructions.md. That file is the only copy of the standard; +# this one only points at it and turns off the output the standard says not to produce. + +language: en-US + +reviews: + # Judgement over style. The standard delegates the mechanical layer to ESLint. + profile: chill + # The standard: comment only, never approve or request changes. The human decides. + request_changes_workflow: false + + # The pull request template already carries Why and What. The walkthrough itself cannot be turned off, so it is collapsed and everything optional inside it is off. + high_level_summary: false + collapse_walkthrough: true + changed_files_summary: false + sequence_diagrams: false + estimate_code_review_effort: false + suggested_reviewers: false + suggested_labels: false + poem: false + in_progress_fortune: false + review_status: true + + auto_review: + enabled: true + drafts: false + base_branches: + - trunk + + # Tests are a reviewer finding; the author writes them. Generated tests are the "green while proving nothing" shape the standard warns about. + finishing_touches: + docstrings: + enabled: false + unit_tests: + enabled: false + + # The description check reads .github/pull_request_template.md, which AGENTS.md already requires authors to follow. + pre_merge_checks: + description: + mode: warning + title: + mode: off + docstrings: + mode: off + issue_assessment: + mode: off + + path_filters: + - "!package-lock.json" + - "!dist/**" + - "!node_modules/**" + + path_instructions: + - path: "**" + instructions: | + The review standard is .github/instructions/code-review.instructions.md, loaded as a code guideline. Apply it from its "Scope" section onward; the "Running the review" section assumes a shell and does not apply here. + Review the five dimensions in its priority order: architecture, security, performance, cross-platform, tests. Do not report style or formatting; ESLint covers that in CI. + Begin every finding with its dimension, severity (🔴 high, 🟡 medium, 🔵 low) and scope ([fix here] or [follow-up]) as the standard defines them. Use [follow-up] for anything the pull request did not introduce. + Verify a finding against the surrounding files before asserting it. When there is nothing to report, say so in one line and stop. + + tools: + # ESLint runs repo-wide in .github/workflows/lint.yml; repeating it here buries the findings that matter. + eslint: + enabled: false + # This repository deliberately does not hard-wrap Markdown. Every long line would be a false positive. + markdownlint: + enabled: false + +chat: + auto_reply: true + +knowledge_base: + code_guidelines: + enabled: true + # Not in CodeRabbit's default pattern list, so it has to be named. The content is injected at review time; nothing is copied. + filePatterns: + - ".github/instructions/code-review.instructions.md" + # Learnings live in CodeRabbit's dashboard, outside the repository. Keep them to this repository so they cannot drift into an org-wide second standard. + learnings: + scope: local + web_search: + enabled: false diff --git a/.github/instructions/code-review.instructions.md b/.github/instructions/code-review.instructions.md index 67128dc0..3ffb7e39 100644 --- a/.github/instructions/code-review.instructions.md +++ b/.github/instructions/code-review.instructions.md @@ -6,11 +6,11 @@ applyTo: "**" What an automated reviewer should look for in this repo, and how to run that review. Written to be read by any agent, not one in particular — this is the single source of truth for the review standard, and it is deliberately the only copy of it. -`AGENTS.md` and `.claude/skills/self-review/SKILL.md` point here rather than restate it. Copilot needs no pointer: it reads `.github/instructions/*.instructions.md` natively, selecting them by matching the `applyTo` glob above against the files in a pull request, so `**` means every PR gets this. That is the whole reason the file lives at this path and not somewhere better-named — a pointer would not have reached it, and a second condensed copy would have drifted. +`AGENTS.md` and `.claude/skills/self-review/SKILL.md` point here rather than restate it. Copilot needs no pointer: it reads `.github/instructions/*.instructions.md` natively, selecting them by matching the `applyTo` glob above against the files in a pull request, so `**` means every PR gets this. That is the whole reason the file lives at this path and not somewhere better-named — a pointer would not have reached it, and a second condensed copy would have drifted. CodeRabbit reaches it through `.coderabbit.yaml`, which loads this file as a code guideline for every non-draft pull request to `trunk`. -The procedure below assumes an agent that can run commands. Copilot cannot; it should skip to **Scope** and treat the rest as the standard to review against. +The procedure below assumes an agent that can run commands. Copilot and CodeRabbit cannot; they should skip to **Scope** and treat the rest as the standard to review against. -Nothing runs this automatically. It is the author's pass, before a human reads the diff — which is the point: a finding fixed now costs one message, the same finding on the PR costs a review cycle. The producer is responsible for handing over a reviewable change, not the reviewer for reconstructing the context. +CodeRabbit runs this on every non-draft pull request to `trunk`. It is still the author's pass first, before a human or a bot reads the diff — which is the point: a finding fixed now costs one message, the same finding on the PR costs a review cycle. The producer is responsible for handing over a reviewable change, not the reviewer for reconstructing the context. ## Running the review @@ -37,7 +37,7 @@ If ESLint fails, `npm run lint:fix` handles the mechanical part. Check what it r **3. Review the five dimensions below.** Read the surrounding files, not just the diff — a diff rarely shows that a helper already handles the case, and the reporting bar requires verifying a finding before asserting it. -Where the tool allows it, run this pass with fresh context — a subagent given the diff and this file, rather than the session that wrote the code. Nothing runs this review independently any more, so a reviewer that already believes the change is correct is the main way it stops working. +Where the tool allows it, run this pass with fresh context — a subagent given the diff and this file, rather than the session that wrote the code. CodeRabbit will run it again on the pull request, but a reviewer that already believes the change is correct is still the main way this pass stops working. **4. Report, then offer.** Format below. Ask before changing anything: the author decides what is a real finding, which is the whole reason this happens before the PR rather than after. diff --git a/AGENTS.md b/AGENTS.md index 444f1781..9b4babe5 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -8,7 +8,7 @@ Two files, and neither is specific to one tool despite what their paths suggest: **The review standard** — [`.github/instructions/code-review.instructions.md`](.github/instructions/code-review.instructions.md). The five dimensions, this project's invariants, the procedure to run them, and the reporting format. Read it directly if your agent has not already. -It sits under `.github/instructions/` because Copilot code review reads that directory natively and follows no links out of it. Anywhere better-named would have meant maintaining a condensed second copy for Copilot, which would drift. Every other agent reaches it from here. +It sits under `.github/instructions/` because Copilot code review reads that directory natively and follows no links out of it. Anywhere better-named would have meant maintaining a condensed second copy for Copilot, which would drift. CodeRabbit is pointed at the same file by `.coderabbit.yaml`. Every other agent reaches it from here. **The review as a skill** — a thin `SKILL.md` wrapper over the file above, in two locations because no single skills directory is read by every agent: @@ -31,7 +31,7 @@ Run the review in `.github/instructions/code-review.instructions.md` against the Before reporting a GitHub workflow complete, verify every requested final state on GitHub — for example, distinguish a merged pull request from one that is merely closed, and confirm that an issue was closed by the intended pull request rather than only by a comment. -Nothing enforces this. There is no automated review on pull requests, by design: it would mean storing an AI provider credential as a secret in a public repository. This pass is what stands in its place, so skipping it means a human reviewer is the first reader of the diff. +CodeRabbit reviews every non-draft pull request to `trunk` against the same file, configured in `.coderabbit.yaml`. It comments only and never approves. That does not replace the author's pass: a finding fixed before the PR costs one message, the same finding on the PR costs a review cycle, and a human reviewer should not be the first reader of a diff the author never checked. That file carries the procedure as well as the standard. Follow it rather than improvising a review. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 90db9dc3..ad3a1572 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -31,11 +31,11 @@ There is **one** source of truth for how a change is reviewed: **[`.github/instr Two things consume that one file: -### Copilot code review — assign it to a PR +### AI review on pull requests -Copilot code review reads `.github/instructions/*.instructions.md` **natively**, selecting files by their `applyTo` glob (this one is `**`, so it applies to every PR). That is the entire reason the standard lives at this path and not somewhere better-named — Copilot follows no links, so a pointer would not have reached it. +**CodeRabbit** reviews every non-draft pull request to `trunk` automatically. It is a GitHub App installed on the WordPress organisation, so it needs no secret in this repository. [`.coderabbit.yaml`](.coderabbit.yaml) points it at the same review standard the author runs, [`code-review.instructions.md`](.github/instructions/code-review.instructions.md), asks for that file's labelling on every finding, and keeps it to comments: it never approves or requests changes. Talk to it with `@coderabbitai` in a PR comment; `@coderabbitai help` lists the commands. Its "Learnings" live in CodeRabbit's dashboard, not in the repository, so anything worth keeping from there goes into the instructions file. -Copilot is **assigned manually** as a reviewer on a pull request; it is **not** an automatic bot that fires on every PR. That is by design: an always-on AI review would mean storing an AI provider credential as a secret in a public repository, which this project will not do. What exists is the *capability* — assign Copilot and it reviews against the same standard the author already ran. +**Copilot code review** reads `.github/instructions/*.instructions.md` **natively**, selecting files by their `applyTo` glob (this one is `**`, so it applies to every PR). That is the entire reason the standard lives at this path and not somewhere better-named — Copilot follows no links, so a pointer would not have reached it. Copilot is **assigned manually** as a reviewer when a second reader is wanted; it is not automatic. ### The author's own pass — before you open the PR @@ -62,7 +62,7 @@ In an agent-assisted change your agent runs steps 1–3 — it invokes the revie 2. **Fix or consciously defer** every finding — a deferral is a decision, not an omission. 3. **Summarise the outcome in the PR description**: what the checks reported, what you fixed, and what you left as a follow-up and why. 4. **Write a "How to test this" section** — a starting state, numbered steps naming what to click, the expected result of each, and what must *not* have happened. Required on every PR, including ones with green tests: this app fails in places the suite cannot reach, and a reviewer should never have to guess how to drive the change. The shape is spelled out in [AGENTS.md](AGENTS.md#every-pull-request-says-how-to-test-it-by-hand). -5. Optionally **assign Copilot** as a second reader against the same standard. +5. Open the PR. CodeRabbit reviews it against the same standard; optionally **assign Copilot** as a further reader. GitHub fills every new pull request with [the template](.github/pull_request_template.md); steps 3 and 4 have their place in it already. It is built so a reviewer gets the change in five minutes — Why, What changes, How to test this, Risks, Related stay visible and everything deeper goes in a collapsed `
` block. Move detail out of the way rather than dropping it. The same template covers a fix, a feature and a process change; it flags the few places where the three want different things.