npx skills add ...
npx skills add brave/brave-core --skill review
npx skills add brave/brave-core --skill review
'Review code for quality, root cause analysis, and fix confidence. Supports PR review and local review of uncommitted/branch changes. Default mode is local (reviews current branch changes). Triggers on: review pr, review this pr, /review <pr_url>, /review local, /review, check bot pr quality.'
Perform a comprehensive review of code changes. Supports two modes:
Parse the arguments to determine the mode:
/review or /review local → Local mode/review <pr_url> or /review <pr_number> → PR modeIf no argument is provided or the argument is local, use local mode.
This skill runs from the src/brave (brave-core) directory.
src/) is at ../ relative to this repoWhen reviewing local changes, gather the diff from two sources:
The base branch is what this branch's changes should be compared against. Do NOT
assume master — the branch may depend on another feature branch.
Detect the base branch in this order:
Check for an existing PR: If a PR exists for this branch, use its base branch:
Check the upstream tracking branch: If no PR exists, check what the branch tracks:
Fall back to master: If neither method yields a result, use master.
Combine these diffs to form the complete set of changes to review. The combined
diff represents what would be in a PR against $BASE_BRANCH if one were created
right now.
Report the base branch at the start of the review so it's clear what the
changes are compared against (e.g., "Reviewing against base branch:
branch-A").
Check the branch name for hints about what the change does:
Check recent commit messages on this branch for context:
Read the modified files in full to understand the surrounding code context
Then proceed to the Common Analysis Steps below (Step 3 onward), using the gathered diff instead of a PR diff.
Note: For local reviews, skip Steps 1-2 (PR-specific steps) and the filtering scripts step (Step 4), since there is no PR or GitHub data to filter.
When reviewing a PR, follow Steps 1-3 below, then continue with the Common Analysis Steps.
Extract PR information from the provided URL:
Get PR details:
CRITICAL: Before evaluating the current fix, understand what has been tried before. If previous attempts exist, the current fix MUST prove it is materially different or the review is an AUTOMATIC FAIL.
Where to search: Previous fix attempts live as pull requests in the target
repository (typically brave/brave-core). Search by issue number AND by test
name/keywords, since not all PRs reference the issue directly:
For each previous attempt found:
Document findings:
When previous fix attempts exist, you MUST compare the current PR's diff against each previous attempt's diff and answer:
Is the approach materially different? Compare the actual code changes, not just the PR description. Look at:
If the approach IS different, explain HOW:
RunUntilIdle() call. This PR instead uses
TestFuture to synchronize on the specific callback."If the approach is the same or substantially similar → AUTOMATIC FAIL:
The burden of proof is on the current fix. If you cannot clearly articulate why this fix is different from previous failed attempts, the review MUST FAIL with the reason: "Fix is not materially different from previous attempt(s) #XXXX."
The following steps apply to both local and PR mode reviews.
For PR mode, fetch the full diff once and save it for subagent use:
For local mode, the diff was already gathered in Step L2. Combine the
committed + uncommitted diffs into PR_DIFF.
Extract the file list from the diff:
File classification is handled automatically by the discovery script in Step 6.1 — no manual classification needed.
For the associated issue (if any):
For PR reviews and comments:
Analyze the code in context:
Read the modified files from the repo:
Read related files to understand the module:
For chromium_src overrides, also read the upstream file:
Questions to answer:
IMPORTANT: The main context does NOT load best practices docs directly. Each review is performed by subagents — one per chunk of ~3 rules — running in parallel. Large best-practice documents are split into evenly-sized chunks by a preprocessing script, so each subagent handles a focused set of rules. This ensures every rule is systematically checked rather than relying on a single pass to hold many rules in mind.
ZERO-TOLERANCE RULE: You MUST launch a subagent for EVERY chunk from EVERY discovered document. No exceptions. No filtering. No "focusing on key areas." No commentary about the number of chunks. Just launch them all.
CRITICAL — NO SHORTCUTS FOR LARGE DIFFS: Regardless of diff size (even 100KB+), you MUST pass the complete, untruncated diff to every subagent and review ALL changed files. Do NOT skip files, truncate the diff, selectively review "key chunks", or take any other shortcut based on diff size. The chunked subagent architecture is specifically designed to handle large diffs — each subagent only checks ~3 rules, so the diff size is not a constraint. If the diff is large, that means MORE subagents are needed, not fewer.
CRITICAL — LAUNCH ALL DISCOVERED DOCS: You MUST launch subagents for ALL documents returned by the discovery script — not just the ones you consider "most relevant." The discovery script already filters out inapplicable categories (e.g., iOS docs when no iOS files changed). If a document appears in the discovery output, it MUST get a subagent. Do NOT second-guess the discovery script or selectively skip documents. The only filtering happens in the script; you do not apply additional filtering.
CRITICAL — NO COMMENTARY ABOUT CHUNK COUNT: Do NOT output any text commenting on the number of chunks, expressing concern about the volume of work, or announcing that you will "focus on key areas" or "launch focused subagents for the most relevant areas." Just launch ALL subagents silently. The number of chunks is irrelevant — launch them all in parallel without editorializing. Any message like "Given the large number of chunks (N total), I'll focus on..." is WRONG and violates this skill's requirements. You must launch every single chunk subagent regardless of how many there are.
For each applicable best-practice document, run the chunking script to split it
into groups of ~3 rules, then launch one subagent per chunk. Use multiple
Agent tool calls in a single message so they run in parallel. Pass the
PR_DIFF content (fetched in Step 3) directly in each subagent's prompt so they
don't need to fetch it again.
Discovery step: First, determine which best-practice docs apply to this change. The discovery script auto-detects applicable documents based on changed file types — no hardcoded document list needed:
The script outputs JSON with each applicable doc's path and category. Documents
are matched to file types by naming convention (e.g., testing-*.md applies
when test files are changed, android.md when .java/.kt files are changed).
Documents that don't match any specific category (like architecture.md,
documentation.md) are always included.
Chunking step: For each discovered document, run:
This outputs JSON with one or more chunks per document. Each chunk contains:
doc: the source document filenamechunk_index / total_chunks: position within the documentrule_count: number of ## rules in this chunkheadings: list of rule heading texts (for the audit trail)content: the full text to pass to the subagent (includes the doc header +
the chunk's rules)Small documents (<=5 rules) produce 1 chunk. Large documents are split evenly (e.g., 25 rules → 5 chunks of 5). Launch one subagent per chunk.
Each subagent prompt MUST include:
content field from the chunking script
output directly in the prompt. The subagent does NOT read any files — all
rules are provided inline. Include it like:
gh pr diff or
git diff — the diff is already provided. Embed it in the prompt like:
+
prefix) or in unchanged code visible in the diff, do NOT comment on it or
suggest fixing it -- unless the changes directly affect or break that
surrounding code#if guard)+ line imports or calls a function/class/variable from another
module, and that symbol's definition is NOT in a file changed by the diff,
do not comment on the symbol's naming. Only flag naming issues on symbols
that are defined or renamed within the changed files.<a id="CS-001"></a>) on the line before the
heading. For each violation, the subagent MUST include a direct link using
that ID. The link format is:
rule_link fragment MUST be an exact <a id="..."> value
from the rules provided in the chunk. Do NOT invent IDs, guess ID numbers,
or construct anchors from heading text. If no <a id> tag exists for the
rule, omit the rule_link field entirely.CRITICAL — this is what prevents the subagent from stopping after finding a few violations.
The subagent MUST work through its chunk heading by heading, checking every
## rule against the diff. It must output an audit trail listing EVERY ##
heading in the chunk with a verdict:
Verdicts:
This forces the model to explicitly consider every rule rather than satisficing after a few findings.
Each subagent MUST return this structured format:
After ALL chunk subagents return:
Aggregate violations from all chunk subagents into a single list. Sort by severity: high → medium → low.
Validate rule links — for each violation with a rule_link, extract the
fragment ID and validate it exists in the target doc:
If the ID is invalid, strip the link from the comment text. Violations
missing rule_link that are not genuine bug/correctness/security findings
should be dropped.
Deep-dive validation — before including in the report, validate every remaining violation by reading the actual source code:
Present violations one at a time and offer to fix each. After validation, walk through the remaining violations sequentially. For each violation, present it to the user and ask whether they want it fixed:
Fix guidelines:
Include all violations (fixed and unfixed) in the review report under the Best Practices section. Mark each as (fixed) or (unfixed) so the user knows what remains.
Read the PR body and any issue analysis carefully.
Check for RED FLAGS indicating insufficient root cause analysis:
These words are acceptable ONLY if followed by concrete investigation:
Watch for generic explanations that could apply to any bug:
Demand specifics:
If a test fails in Brave but passes in Chrome (or is flaky in Brave but stable in Chrome), the root cause analysis MUST explain what Brave-specific factors contribute:
Without this explanation, the analysis is incomplete even if the general mechanism is understood.
These checks are performed directly by the main context (not subagents) because they require PR-level reasoning rather than per-rule checking:
If the fix works by altering execution timing rather than adding proper synchronization:
BANNED patterns:
RunUntilIdle() (explicitly forbidden by Chromium)ACCEPTABLE patterns:
base::test::RunUntil() with a proper conditionTestFuture for callback synchronizationEvalJs() or ExecJs() inside RunUntil() lambdasIf the fix is disabling a test:
CRITICAL: Use the most specific filter file possible.
Filter files follow the pattern: {test_suite}-{platform}-{variant}.filter
Available specificity levels (prefer most specific):
browser_tests-windows-asan.filter - Platform + sanitizer specific (MOST
SPECIFIC)browser_tests-windows.filter - Platform specificbrowser_tests.filter - All platforms (LEAST SPECIFIC - avoid if possible)Before accepting a test disable, verify:
Examples:
browser_tests-windows-asan.filterbrowser_tests-linux.filterbrowser_tests.filterIs the test flaky upstream? (Chromium tests only) — This check only
applies to upstream Chromium tests (defined in src/ but NOT in
src/brave/). Brave-specific tests won't appear in the Chromium database.
For Chromium tests, check the LUCI Analysis database:
The script queries analysis.api.luci.app and returns a verdict:
Use --days 60 for a wider lookback window if the default 30 days has
insufficient data.
Red flags (overly broad disables):
browser_tests.filter when failure is only reported on one platformFor flaky tests, the root cause analysis must explain why the failure is intermittent - not just why it fails, but why it doesn't fail every time:
Questions to answer:
Examples of good intermittency explanations:
Red flags (incomplete analysis):
Rate confidence level:
CRITICAL: Avoid Redundancy
CRITICAL: Fill Informational Gaps Yourself
CRITICAL: No Vague Language in YOUR Analysis
DO report:
DO NOT report:
src/brave/ and src/. Do not make assertions about APIs,
patterns, deprecations, or behavior without first confirming them in the
actual codebase. Look at how the API/pattern is used elsewhere, check header
files for documentation, and read upstream Chromium code when relevant. Every
comment you make should be grounded in what the code actually says, not
assumptions.If the user asks you to post the review as a comment on GitHub, always prefix the review body with:
I generated this review about the changes, sharing here. It should be used for informational purposes only and not as proof of review.
This disclaimer must appear at the very beginning of the review body (as plain text, not as a blockquote).
Post as inline code comments when possible. When the review identifies specific issues tied to files and lines, post them as inline review comments on the actual code rather than as a single general comment. Use the GitHub review API to submit a single review with:
Key details:
side: "RIGHT" targets the new version of the file (changed lines)line is the line number in the new fileReview local changes (default - no argument needed):
Review a specific PR by URL:
Review a PR by number (assumes brave/brave-core):