.coderabbit.yaml
# CodeRabbit review configuration for Birdbrain.
# Schema: https://storage.googleapis.com/coderabbit_public_assets/schema.v2.json
# Reference: https://docs.coderabbit.ai/reference/configuration
#
# Ask CodeRabbit to echo back the resolved config on any PR with:
# @coderabbitai configuration
language: en-US
# Applied to every comment CodeRabbit writes. Hard limit: 250 characters.
tone_instructions: >-
Be direct and concrete. Skip praise and restatement of what the diff does. Prettier
and ESLint enforce formatting here — never comment on style they already handle.
Prefer one specific, actionable comment over three general ones.
reviews:
# chill = flag real problems, skip stylistic nitpicks. (quiet | chill | assertive)
profile: chill
# Solo-maintained repo: a blocking "changes requested" review would stall every PR.
request_changes_workflow: false
# Off: the PR body Summary section is the one summary a PR carries (post-pr-body skill).
high_level_summary: false
review_status: true
review_details: true
# Playful output off.
poem: false
in_progress_fortune: false
# ---------------------------------------------------------------------------
# What gets reviewed at all.
#
# IMPORTANT: positive globs are RESTRICTIVE. Once any include pattern is listed,
# a file that matches none of them is skipped entirely. Adding a new top-level
# directory to this repo means adding it here, or it silently goes unreviewed.
# ---------------------------------------------------------------------------
path_filters:
# --- include: application, extension, tests ---
- "src/**"
- "extension/**"
- "tests/**"
- "e2e/**"
# --- include: author-time docs (specs, plans, ADRs, agent docs) ---
- "docs/**"
# --- include: the Fumadocs site (content + integration). Not covered by docs/**. ---
- "website/**"
# --- include: build/release tooling and CI ---
- "scripts/**"
- ".github/**"
# --- include: the agent contracts. These are process code, not local tooling:
# the dispatch routine, the implementer/reviewer contracts, the session-start
# hook, and the shared permission set. A defect here reaches every unattended
# run, and until 2026-08-17 this directory was the one place a contract bug
# could ship unreviewed. ---
- ".claude/**"
# --- include: root-level config and prose ---
- "*.md"
- "*.ts"
- "*.js"
- "*.mjs"
- "*.json"
# Root YAML. These filters are minimatch, where `*` does not match a leading
# dot, so the config file needs its own literal entry -- the glob alone would
# leave a change to the review config as the one change CodeRabbit never
# sees. pnpm-lock.yaml is excluded below.
- "*.yaml"
- "*.yml"
- ".coderabbit.yaml"
- "LICENSE"
# A change here weakens secret scanning or shifts the toolchain — worth a look.
- ".gitleaksignore"
- ".gitignore"
- ".prettierrc"
- ".nvmrc"
# Not included, deliberately: .design-sync/** is local design tooling, not shipped code.
# --- exclude: dependencies ---
- "!node_modules/**"
- "!**/node_modules/**"
# --- exclude: build output and test artifacts ---
- "!dist/**"
- "!out/**"
- "!coverage/**"
- "!test-results/**"
- "!playwright-report/**"
- "!website/.next/**"
- "!website/out/**"
# --- exclude: lockfiles. pnpm-lock.yaml is not a *.lock file, so both patterns
# are needed; **/ also catches website/pnpm-lock.yaml (isolated sub-project). ---
- "!**/pnpm-lock.yaml"
- "!**/*.lock"
# --- exclude: vendored third-party skill (metadata.author: superdesign), dropped in
# whole rather than authored here. Reviewing a vendor bump is noise. ---
- "!.claude/skills/superdesign/**"
# --- exclude: binary and asset directories ---
- "!resources/**"
- "!website/public/assets/**"
- "!**/*.png"
- "!**/*.jpg"
- "!**/*.jpeg"
- "!**/*.gif"
- "!**/*.svg"
- "!**/*.ico"
- "!**/*.icns"
- "!**/*.mhtml"
# ---------------------------------------------------------------------------
# Area-specific review criteria. These supplement CodeRabbit's built-in review;
# they are not a replacement for it. Keep each block short and concrete.
# ---------------------------------------------------------------------------
path_instructions:
- path: "src/**"
instructions: |
- TypeScript is strict. Flag `any` without an eslint-disable and a stated reason,
and flag non-null assertions used in place of a real narrowing check.
- Every `await` needs a rejection path. Flag swallowed errors — a `catch` that
logs and continues where the caller needs to know the operation failed.
- IPC payloads crossing the preload bridge are untrusted input. Validate at the
handler in `src/main/ipcHandlers.ts` rather than deep in a service.
- Privacy: captured page content, capture URLs, operator name, and installationId
must not reach logs, error messages, or any outbound request. See `SECURITY.md`
for the loopback-bind and per-install-token model.
- New SQL belongs in a repo module under `src/main/services/db/`. Importing
`getDb` elsewhere under `src/main/` is lint-enforced — flag new exceptions.
- path: "src/main/services/db/migrations.ts"
instructions: |
- Migrations are append-only. A change that edits an existing `if (version < N)`
block rewrites history for already-migrated installs — flag it.
- A new block must run its DDL inside the transaction and end by setting
`user_version = N`.
- A new block also requires bumping `LATEST_SCHEMA_VERSION` in `core.ts`. Flag a
new migration that does not.
- path: "src/main/services/**"
instructions: |
- Evidence-affecting paths (hashing, manifest writes, signing, trusted time,
verification, redaction, export, reporting) must preserve the immutable original
and keep derivatives separate from assertions. See `CONTEXT.md`,
"Assurance baseline".
- Flag any wording in code, comments, or user-facing strings that overstates what
verification proves. Say what a check establishes and what it does not.
- Use the `CONTEXT.md` vocabulary: Case, Capture, Capture Lifecycle, Manifest,
Operator, Persisted Match. Flag the listed synonyms to avoid.
- path: "extension/**"
instructions: |
- The content script runs on pages we do not control. Flag selectors that assume a
specific class name, DOM depth, or element order, and any `querySelector` result
used without a null check.
- Flag assumptions that a page is single-frame, same-origin, static, or fully
loaded at injection time.
- Manifest V3: the background service worker is suspended without warning. Flag
module-scope mutable state expected to survive between events — it must go to
`chrome.storage`.
- Requests to the capture server must target `http://127.0.0.1:19845` and carry the
per-install token. Flag hardcoded alternatives or a dropped token.
- path: "tests/**"
instructions: |
- Assertions must describe behaviour a user or caller depends on, not restate the
implementation. Flag tests that would still pass if the function returned a
constant, and tests asserting on private internals.
- On a `fix(...)` PR, ask for a test that fails without the fix.
- Flag mocking so broad that the unit under test no longer runs.
- path: "e2e/**"
instructions: |
- Flag fixed timeouts used where a Playwright web-first assertion or `waitFor`
would be deterministic.
- Selectors should be role- or testid-based. Flag brittle text or CSS chains.
- path: "docs/**"
instructions: |
- Audience is investigators, activists, and researchers — plain language, and
honest about limits. Flag marketing register and hedged non-claims.
- Check factual claims against `README.md`, `SECURITY.md`, and the specs under
`docs/specs/`. Flag statements that contradict them or describe behaviour that
does not exist yet.
- Flag claims of legal admissibility, tamper-proofing, or standards compliance that
do not name the standard and version.
- Terminology follows the `CONTEXT.md` glossary, including its "_Avoid_" lists.
- Naming: `docs/specs/` and `docs/plans/` files take a `YYYY-MM-DD-` prefix;
`docs/adr/` takes `NNNN-`. See `docs/README.md`.
- path: "website/content/docs/**"
instructions: |
- Bare `{...}` in prose is an MDX compile error — braces must be inside backticks.
- Internal doc links must use the `./name.mdx` form. A bare slug is emitted as-is
and resolves wrong under `trailingSlash: true`.
- Image paths are `public/`-relative (`/assets/x.png`). Flag a hardcoded
`/birdbrain/` prefix — `basePath` is applied automatically.
- A new page needs a `title`/`description` frontmatter pair and an entry in
`website/content/docs/meta.json`, or it is silently dropped from the sidebar.
- path: "website/{source.config.ts,next.config.mjs,lib/**,components/**,app/**}"
instructions: |
- The site is statically exported (`output: 'export'`, `trailingSlash: true`).
Flag anything that assumes a server runtime: route handlers with dynamic
behaviour, `headers()`/`cookies()`, or unbounded `generateStaticParams`.
- Code that builds a URL by hand must import `basePath` from `lib/base-path.mjs`.
- Flag brittle assumptions about slug shape or the content tree that will break as
pages are added, and untyped access to Fumadocs page/meta objects.
- `website/` is an isolated sub-project with its own lockfile. Flag imports that
reach outside it or new dependencies added to the root `package.json`.
- path: ".claude/**"
instructions: |
- These are contracts executed unattended. Review them for defects that would make an
agent take a wrong action, not for prose that could be worded more precisely. A step
you would tighten is not a finding; a step that produces a wrong action is. Prose
about a review process is still prose — do not audit it as if it were code.
- Shell commands in a contract are load-bearing. Flag a count or decision derived
through a pipe whose exit status is unchecked (`| tail -1` swallows a `gh` failure),
`gh api --jq` given `-r`, or `gh issue comment` given `-q` — all three fail rather
than error visibly.
- The label-filtered issue search (`issues?labels=…`) reads GitHub's search index and
lags a direct label read. Flag it used as authoritative for a dispatch decision.
- Subagents never post their own comments and never relabel (ADR-0006). Flag a step
that hands a subagent the write path.
- The merge and concurrency gates come from
`docs/adr/0014-tier-the-evidence-backstop-and-widen-the-dispatch-slot.md`, which
amends ADR-0005: three concurrent agent PRs, and a non-evidence agent PR may merge
with no human on all required checks green plus an `agent/pre-pass` success verdict.
Read ADR-0014 before asserting any merge or slot rule — ADR-0005 read alone says
agents never merge and allows one open agent PR, and both of those are superseded.
- Evidence-affecting PRs never auto-merge under any policy. Flag a step that would
merge one, or that would treat an unreadable check state as passing.
- `.claude/hooks/*.sh` runs under bash while the agent tool shell is zsh. Flag
shell-specific syntax whose behaviour differs between them.
- In `.claude/settings.json`, flag a new permission entry that broadens write or
network access beyond what the change needs.
# ---------------------------------------------------------------------------
# When reviews run. Drafts are excluded (ADR-0025): the draft phase of an agent
# PR belongs to the reviewer pre-pass, and the dispatcher marks the PR ready on
# an approve verdict, which is when a human reads it and when this review is
# useful. Reviewing drafts previously silenced CodeRabbit on exactly the PRs
# that needed a second reader: the pause below tripped on long pre-pass loops
# before the PR was ever ready. The pause stays for ready PRs — unbounded
# incremental review is what turned PR #1062 (48 net lines of one markdown
# file) into 7 commits, 6 reviews and 22 review comments.
# ---------------------------------------------------------------------------
auto_review:
enabled: true
drafts: false
auto_incremental_review: true
auto_pause_after_reviewed_commits: 4
base_branches:
- "main"
ignore_title_keywords:
- "WIP"
- "DO NOT MERGE"
# No `reviews.tools` block: every linter integration defaults to enabled, so ESLint,
# markdownlint, actionlint, yamllint, and gitleaks are already on.
chat:
auto_reply: true
art: false
knowledge_base:
code_guidelines:
enabled: true
# Setting this array REPLACES the built-in defaults, so CLAUDE.md and AGENTS.md are
# re-listed here. `applyTo` scopes a guideline to the files it actually governs.
filePatterns:
- "**/CLAUDE.md"
- "**/AGENTS.md"
# Domain vocabulary and the OSINT assurance baseline.
- files: "CONTEXT.md"
applyTo: "src/**,docs/**,website/content/docs/**,*.md"
# Threat model, network egress, and the known-limitations list.
- files: "SECURITY.md"
applyTo: "src/main/**,src/preload/**,extension/**,.github/workflows/**"
# Where each kind of doc lives and how it is named.
- files: "docs/README.md"
applyTo: "docs/**,website/content/docs/**"
# Audience, tone, claim discipline, and per-doc-type structure.
- files: "docs/agents/writing-guide.md"
applyTo: "docs/**,website/content/docs/**,*.md"