Skip to content

Reviews

No single check makes a PR safe. Each PR goes through several layers of checks, and each layer catches problems that the others miss.

  1. Back pressure and evidence. The agent checks its own work as it goes, using the tests, types, evals and rules files the ticket lists under back pressure. Then it proves the change works with the evidence the ticket asks for.
  2. CI. Tests, type checks and linting run on every PR. Anything a tool can check belongs here, not in a reviewer’s head: formatting and style, unused code, type errors, vulnerable or outdated dependencies, N+1 queries (with a tool such as Bullet) and security scanners such as Brakeman. Conventions a tool can’t check, such as naming, comments, magic values and finders scoped to a parent model, go in the repo’s CLAUDE.md so agents follow them, and its REVIEW.md so Crosscheck looks for them. See our style guidelines.
  3. Crosscheck. Our PR reviewer checks each PR against its Linear ticket and posts one comment. The comment gives a verdict (Aligned, Check or Drifted). It also lists changes the ticket didn’t ask for and assumptions the PR makes, and says where to look. Each repo can steer Crosscheck with a REVIEW.md (or CLAUDE.md) at its root, which says what matters in that repo and what Crosscheck can skip.
  4. Crosscheck’s security pass. A separate pass looks for security problems and adds what it finds to the same comment.
  5. Human review, where a change needs it. See when a person should look.
  6. Feature flags and fast rollback. Risky changes go out behind a feature flag, and the author, or their agent, watches the deploy and rolls it back within minutes if anything goes wrong.

From time to time, the tech lead on a project reads a sample of merged PRs. They bring anything they find to the team, and it might lead to new lint rules, changes to the repo’s REVIEW.md or changes to Crosscheck itself.

  • Put your code on a branch, not straight on the main branch.
  • We don’t have a naming convention for branches. Just call it something sensible that describes what it is.
    • You can apply the Conventional Commits convention with branch names. E.g. feat/add-a-widget-to-navbar. This can help understand branches at a glance.
  • Aim for smaller branches rather than larger ones. See pull request size.
  • Put up a draft PR to get early feedback; it helps us avoid falling down rabbit holes.
  • Explain why the work is needed. We may look back at a PR long after it’s merged to understand a decision.
  • Before you mark a PR ready, check the evidence proves what the ticket asked for, check Crosscheck’s verdict, and think about what the change touches.
  • Merge when the checks pass, Crosscheck says Aligned or you’ve explained why not, and anyone you asked to review is happy. Then delete the branch.

Some changes need a person’s attention as well as Crosscheck’s. As a guide, that’s anything touching:

  • authentication and authorisation
  • payments and money
  • secrets and credentials
  • database schema changes and migrations
  • public APIs
  • untrusted input
  • personal data and customer-facing logic
  • regulated code
  • design systems

Crosscheck also flags PRs it thinks need a second reviewer by adding the needs-second-reviewer label. If you’re not sure, ask your tech lead.

A willingness to listen to and act upon feedback is super important no matter what your level is; it’s a key part of how we improve as a team.

  • Take feedback on board.
    • Don’t be too defensive of the code, we’re a team and collaboration makes our code better.
  • Assume the reviewer’s tone is a friendly / curious one.
    • Written feedback is often read in an overly critical tone in our heads.
    • We’re all friends here. How would the reviewer be saying this to you in person?
  • Try to respond to every comment and resolve them as you go.
    • If you decide not to take action on a comment, you should justify your reason why.
    • Link to specific commits - “Well spotted! Done in #123987”
  • Be comfortable passing the PR to someone else for a second opinion, especially if you’re not sure it’s ready to merge.
  • Code reviews can vary depending on the size and scale of the feature/fix. Everything from skimming over the diff, to running the tests, to running through multiple scenarios by hand.
    • Depending on time constraints, you might not do all of these things, so you should let the author know what level of attention you have provided.
  • Prefer to involve the person at your desk or on a call, rather than just communicating backwards and forwards over pull request comments. But ultimately you be the judge!
    • Post a comment to summarise any discussions that took place.
  • Sharing knowledge avoids silos and any comment is a learning opportunity for both so ask questions.
  • Be humble.
    • Assume the reviewee has the best understanding of the problems being solved, they’ve put a lot of thought and work into it.
    • Trust in their decisions but ask for clarification.
  • Be aware that written feedback is often read in an overly critical tone.
    • Prefer open-ended questions over making strong or opinionated statements.
    • Prefer we instead of you.
      • bad: “-another strategy- would be better here.”
      • better: “We should use -another strategy- because -a reason-.”
      • great: “Could we use -another strategy- for -a reason-? Why did you choose this way?”
  • If there’s a lot of feedback:
    • Consider what are the must dos and what, if anything, can be left out to avoid over-facing someone & keep us progressing.
      • Must dos - the important stuff. Highlight them in a change request.
      • Should dos - make a task/ticket if anything can be done as later.
      • Could dos - “We could do -suggestion-. Not important, you decide.”
  • Code style belongs in lint rules and our style guidelines, not in PR comments.
    • We should be on the same page with our code style, if not, we should discuss as a team rather than between individuals on PRs.
    • If something isn’t covered or you disagree with it, bring it up in retro, then update the lint rules or style guidelines once we agree.
  • Do give praise for good work :)
    • Highlight things you liked
    • Highlight things you’ve learned
    • Give an appreciation ::taco:: in #appreciations on Slack!

Use this template for every feature PR. For deploy PRs, use the deploy PR template instead.

Ticket: <Linear link>
Covers: the whole ticket
## Description
<!-- HUMANS ONLY. Write this yourself, in your own words: what changed, why, and anything the reviewer should know. Agents must not fill this in. -->
## Diagram
<!-- If the ticket has a diagram, link or embed it here, updated if the design changed. Otherwise delete this section. -->
## Evidence
<!-- The proof the ticket's Evidence section asks for: screenshots, a video, test or eval output, a staging link. -->
  • Ticket: one PR delivers one Linear ticket. Put the ticket link first, then any related links, such as the parent ticket.
  • Covers: if the PR delivers only part of the ticket, say which part in plain words, e.g. “Covers: the importer and its alert; rollout comes in the next PR”. Keep it to one plain line, and never leave it blank.
  • Description: write this yourself, without an LLM. Agents leave it empty.
  • Diagram: optional. If the ticket has a diagram, link or embed it here. Update it first if the design changed.
  • Evidence: show the proof that the ticket’s Evidence section asks for. An agent can gather this for you.

Crosscheck, our PR reviewer, relies on the Ticket and Covers lines: it reads the Ticket line to find the ticket, and the Covers line to see which parts of the ticket the PR delivers.

We encourage clients to add this template to their own repos too.

The project delivery metrics section of the handbook contains details about pull request cycle time, size, time to review.