code0Vörr AIContactDocs
Book a Demo

Review a pull request

Use caseIntermediate15 min

A diff shows what changed, not who depends on it. The decisions that matter in a review, such as a renamed field, a new environment variable or a different error path, sit inside the changed lines, while the code they affect is often in a repository the reviewer has not opened. This page covers the whole review: sizing the change, reading the plan behind it, tracing impact across repositories, checking contracts, config, tests and history, weighing runtime risk, writing comments grounded in evidence, and following up after merge.

When you'd do this

  • A pull request changes an API route, response shape, event payload or shared type that other services use.
  • A branch is large enough that you need to size it and decide where to look before reading every file.
  • A pull request was written mostly by an agent, and you want to review the decisions it made, not only the code it produced.
  • A change touches config, environment variables or deployment files, and you need to know which environments it reaches.
  • You are the tech lead, and reviews arrive as large diffs with design decisions already made inside them.
  • The change touches an area with recent incidents or deploys, and you want to know its current health before approving.

CodeZero is not a pull request review bot. It does not post comments on your pull requests or block merges. It gives you and your agent the context a review needs, and you write the review. Your agent can read the pull request itself with gh, if gh is installed and authenticated.

Before you start

  • CodeZero installed in VS Code with Claude Code, Codex, GitHub Copilot or Cursor as the agent, signed in to your organisation.
  • The repositories that might consume the change connected and indexed, not only the repository the pull request is in.
  • The pull request branch checked out locally. The organisation index covers committed code on the default branch; your local working tree adds the branch under review, so CodeZero reads the new code from your checkout and the rest of the organisation from the index.
  • Optional: gh installed and authenticated, so the agent can read the pull request description, review comments and CI checks.
  • For runtime risk: Vörr connected to Claude, ChatGPT or another MCP assistant, with your repositories, observability tools and CI/CD sources connected. Vörr shows each repository's workspace and branch-to-environment mapping; telemetry and deploys are matched to services by name, with a match label. ChatGPT needs a paid plan with Developer mode turned on.

1. Read the pull request and its checks

  1. Ask the agent to read the pull request with gh: the description, the linked issue, the existing review comments and the state of the CI checks. This uses the agent's own tools, not CodeZero.
  2. If a check has failed, ask the agent to read the failing job's log before you read any code. A red build changes what the review is about.
  3. Note what the author says the change does. The rest of the review tests that claim.
Read the PRUse gh to read pull request 214 in orders-api: the description, linked issue, review comments so far and the CI check results. Summarise what the author says it changes and anything reviewers have already raised.
Failing checkOne check on PR 214 is failing. Read the failing job's log with gh and tell me whether the failure is caused by this change or is unrelated.

A good result separates what the author claims from what has already been checked by CI and by other reviewers.

2. Size the change

  1. In Git Tree, open Compare. Set the base branch as Base and the pull request branch as Target.
  2. Read the commits present in the target but not the base. Their messages often show how the change evolved, including a direction that was later reversed.
  3. Read the changed-file list with additions and deletions. Group the files: source, tests, config and deployment, migrations, generated files.
  4. Decide where to spend your time. A 900-line change that is mostly a lockfile is smaller than a 40-line change to a response serializer and a Helm values file.
Group the changesCompare feature/tax-amount with main. Group the changed files into source, tests, config or deployment, migrations and generated files, with additions and deletions per group. Which files change behaviour other services could see?

A good result tells you which few files deserve close reading. Open a changed file from Compare when you need its diff.

3. Review the plan before the diff

If the change was made with CodeZero, it has a plan: the goal, the repositories it names, the phases, the verification commands, and the answers given to the clarification questions. The plan is where the decisions are written down. Reviewing it first is faster than reconstructing those decisions from the diff.

  1. Open the plan behind the change in CodeZero, or ask the author to share it.
  2. Check the goal against the pull request description. A diff that does more than the goal is a review finding.
  3. Check the repositories the plan names. If the change affects a consumer in a repository the plan does not name, either the consumer is covered elsewhere or the plan missed it.
  4. Read the clarification answers. A compatibility choice such as serving both field names for two releases is a decision to agree with or challenge, not a detail of the code.
  5. Check the verification commands. They are what proved each repository's part works; if they do not exercise the changed behaviour, the green result says little.
Plan against diffCompare the approved plan for the tax-amount work with the changes on this branch. List anything the branch changes that the plan does not mention, and anything the plan promises that the branch does not contain.
Decisions madeList the decisions recorded with this plan, including the clarification answers, and point to the files where each decision is implemented.

If there is no plan, ask the author what was decided and why, and write the answers into the pull request description. The rest of this page still applies.

4. Check the diff's changed components against their dependents

  1. Take the source files from your grouping in step 2, and for each component they change, open it in Graph and read Depended on by. This includes dependents in other indexed repositories, cloned or not.
  2. Match each dependent to the specific change in the diff it is exposed to. A dependent that only uses an unchanged export is not a review concern.
  3. Compare the result with the repositories the plan names, or with what the description claims. A dependent of a changed line that nobody mentioned is a review finding.
Dependents of the diffFor each component this branch changes in orders-api, list the dependents in other repositories that use the changed part specifically, not the component as a whole. Give file and line for each, and mark any the PR description does not mention.

For the full consumer search, see Ship a cross-repository change.

5. Verify only the edges the review relies on

  1. Verify an inferred HTTP edge in Graph only if it would turn into a review comment. The agent reads the call site and records a verdict: confirmed, wrong, or retargeted.
  2. Leave the rest as stated. A review does not need every edge into the repository confirmed, only the ones you will cite.
Verify before commentingI am about to write a blocking comment that cites the edge from billing-worker into this change. Verify it, and tell me what billing-worker does with the changed value as this branch now serves it.

Verdicts are kept for the organisation, so the comment can cite a confirmed edge rather than a guess.

6. Check contract changes

Contracts are what other code relies on without importing anything. They are the changes most likely to break a consumer the diff never mentions.

Routes
Routes added, removed or changed. CodeZero lists the HTTP routes each repository declares, so you can compare them with the routes other repositories call.
Response and request shapes
Fields renamed, removed, retyped or made optional. Trace each to the consumers that read it.
Events and messages
Payload changes on a queue or topic, checked against its consumers.
Tables and collections
Columns or collections that other repositories read or write directly. The data layer of Graph shows which code reads and writes each one.
Settings
Settings added, renamed or no longer used, such as an environment variable the code now expects. CodeZero finds where each setting is defined in code, in .env.example and in deployment config such as Helm values or manifests.
Contract diffCompare this branch with main for contract changes only: routes, response and request fields, event payloads, tables or columns, and settings. For each one, list the consumers in other repositories.
Data readersThis branch adds a migration to the orders table. Which repositories read or write that table directly, and which columns does each use?

A good result lists each contract change with its consumers. A contract change with no compatibility plan, for example a field removed in the same release that consumers stop reading it, deserves a blocking comment.

7. Check config and deployment changes

  1. From Compare, open every config, environment and deployment file the branch changes: .env.example, Helm values, Kubernetes manifests, Compose files, CI workflows.
  2. For each environment variable the code now reads, ask where it is set. A variable added to the code but missing from one environment's config fails at start-up or, worse, falls back silently.
  3. For a renamed variable, check every repository that sets or references the old name, including services that point at this one through it.
  4. Ask Vörr which environments the target branch maps to, so you know where this change lands on merge.
Settings (CodeZero)This branch starts reading TAX_SERVICE_URL and stops reading PRICING_URL. Where is each set across our repositories and deployment config, and which services still reference PRICING_URL?
Where it lands (Vörr)Using Vörr, which environments does the main branch of orders-api map to, and which services run from it in each?

A good result names each variable, where it is set and where it is missing, and the environments the branch reaches.

8. Check which tests protect the behaviour

  1. Ask Chat which tests exercise the changed behaviour, in this repository and in consumer repositories.
  2. Check that new tests cover the decision the change makes, for example a fallback when a field is missing, not only the happy path.
  3. List the consumers from step 4 that have no test of the changed behaviour. Those are where a break would only show up after deploy.
  4. If the branch is checked out, ask the agent to run the relevant tests. Running them uses the agent's own shell.
Tests that protect itWhich tests exercise the order response shape and the order.created payload, in orders-api and in its consumers? Which consumers have no test that would fail if total disappeared?

This is reasoning from code, not measured coverage. Neither product runs a coverage tool for you. Treat the answer as a list of places to check, and use your coverage tool if you need numbers.

For the method, see Write and run tests.

9. Read the history of surprising lines and find who else should review

  1. For a changed line, enable Blame in Git Tree and select it; it shows who last changed it, when, and the commit it came from. For a removed line, open blame or file history at the base commit.
  2. Open file history to see when the behaviour changed and read the diff that changed it. A removed check is often the fix for an old incident.
  3. Ask CodeZero who owns the affected paths, by commit history, in this repository and in each consumer repository. These are the people who should also review, or at least know.
Why was it like thisThis branch removes the null check on discount in OrderSerializer. Using blame and file history, when was that check added, in which commit, and what did that commit say?
Who should reviewWho owns src/invoices in billing-worker and app/services in mobile-backend by commit history? I want to add them as reviewers for the consumer side of this change.

Ownership by commit history shows who has worked on the code, not who is formally responsible. Check it against your team's own ownership rules.

10. Weigh the runtime risk with Vörr

  1. Ask Vörr which services and environments sit behind the changed components. It resolves names through the service map, then confirmed aliases and catalogue names, and reports the source and match quality of each result.
  2. Ask for the current error rate, latency and SLO status of those services, per source, so you know whether you are changing something healthy or something already burning its error budget.
  3. Ask what depends on those services at runtime: callers in the service graph and the cloud resources they use. Runtime dependents can show a consumer the code index did not find.
  4. Ask for recent deploys and incidents in the same area. A service that regressed after its last two deploys deserves a slower rollout.
Services and healthUsing Vörr, which services and environments run orders-api and billing-worker? For each, give the current error rate and p95 latency per source, and SLO error budget remaining. Say where a mapping is inferred.
Runtime dependentsUsing Vörr, what calls orders-api in production according to the service graph, and which of those callers are not in this list: billing-worker, mobile-backend, notifications?
Recent historyUsing Vörr, list deploys of orders-api and billing-worker in the last 14 days, the regression windows Vörr detects around them (with Grafana connected), and recurring incident patterns for these services.

A good answer gives each fact with its source and environment. "No connector" or an unmapped service is a gap in coverage, not a clean result. Vörr runs from your assistant, alongside CodeZero in VS Code; the two are used side by side.

Illustrative example

11. Write review comments grounded in evidence

Each comment should point at something the author can open: a file and line, a verified edge, an environment, a metric with its source. A comment that says "this might break billing" invites a debate. A comment that names the call site that breaks invites a fix.

  1. Write each finding as: what changes, who is affected (with evidence), what happens, and what you suggest.
  2. Mark which findings block the merge and which are follow-ups.
  3. Ask the agent to draft the comments from the findings, then edit them yourself. If you want them posted, the agent can post them with gh after you approve the text.
Blocking: src/orders/orders.serializer.ts:57 removes total.
billing-worker src/invoices/fetchOrder.ts:18 reads total (edge verified).
If it is missing, amount becomes undefined and invoices are written as 0.
Suggest: serve total and totalAmount together until billing-worker reads totalAmount.
Draft commentsDraft review comments for PR 214 from these findings. For each: the file and line in this PR, the affected consumer with file and line, whether the edge is verified, the consequence, and a suggested fix. Mark each as blocking or follow-up. Do not post anything.

12. Follow up after merge

  1. Ask Vörr for the deploy feed for the affected services across your CI/CD sources, so you see when the change actually reached each environment.
  2. Compare error rate, latency and top errors since the deploy with a baseline window, for example the same window 7 days ago. Vörr reports each source separately and flags when they disagree.
  3. For any follow-up agreed in review, such as removing a deprecated field, record it and re-run the consumer search before it is done.
After deployUsing Vörr, show deploys of orders-api in the last 24 hours, then compare its error rate, p95 and top errors since that deploy with the same window 7 days ago. Do the same for billing-worker.

For tech leads: review the decisions, not only the text

A lead often becomes the team's only map of who depends on what. Every review routes through one person because only they remember that billing reads that field. That does not scale, and it fails when the lead is away.

  • Review the plan first. Agree the repositories, the compatibility choice and the verification before code is written, so the pull request confirms decisions rather than introducing them.
  • Review impact, not text. Ask for the consumer list and the verified edges with the pull request, and let the diff review focus on correctness.
  • Sequence the work. Producer changes that serve old and new together merge before consumer changes; cleanups come later as their own small plans.
  • Spread ownership. Use owners by commit history to bring the right people into a review, and let verified edges and feature maps hold the knowledge that used to sit with you.

Without CodeZero or Vörr

Claude Code with gh can give a solid local review on its own. It can read the pull request, its diff, its comments and its CI checks, check out the branch, read and search the repository, run the tests and linters, read blame and history with git, and draft comments. With vendor MCP servers or CLIs for your error tracker or monitoring, it can also look at runtime data. The gaps are what lies outside the checkout and what is not written in source.

OperationClaude Code / ChatGPT on their ownWith CodeZero and Vörr
Read the PR, diff, comments and checksFully achievable with gh, including failing job logs.Same; this stays with the agent's own tools.
Size the changegit diff --stat and gh pr view give the numbers.Git Tree Compare shows commits and changed files with additions and deletions in VS Code.
Review the decisions behind itOnly what the author wrote in the description; the agent's own reasoning from the session that wrote the code is gone.The CodeZero plan records the goal, repositories, phases, verification and clarification answers.
Consumers in other repositoriesOnly in repositories you cloned; an empty search looks the same as a clean one.CodeZero searches every indexed repository, cloned or not.
HTTP, queue and config consumersGrep for paths, topics and variable names per clone, then match them up yourself. Misses base URLs from config.Inferred edges in Graph with file:line evidence, a confidence on HTTP and config edges, and Verify verdicts kept for the organisation.
Data contractGrep for table and column names; ORMs make this unreliable.The data layer shows which code reads and writes each table or collection.
Ownersgit log and blame in each clone.Owners by commit history for any indexed path, including repositories not cloned.
Runtime riskPossible with an MCP server or CLI per tool, each credentialed on your machine, with service names matched by hand and no organisation-wide deploy timeline.Vörr answers across connected tools with resolved service names, source, match quality and environment, plus a deploy feed across CI/CD sources.

ChatGPT or Claude chat can review a diff you paste, or one its GitHub connector can read, and reason well about it. It cannot see repositories it has no connector for, or what runs in production.

With CodeZero and Vörr

Sizing and history (CodeZero)
Git Tree Compare, commit details, blame and file history in VS Code.
Decisions on record (CodeZero)
The plan behind a change: goal, repositories, phases, verification and clarification answers.
Impact beyond the checkout (CodeZero)
Depended on by, references, callers, HTTP route matches, queue consumers, config references and data readers and writers across every indexed repository.
Evidence (CodeZero)
File:line evidence on inferred edges, a confidence on HTTP and config edges, and Verify verdicts shared with the organisation.
Contracts and config (CodeZero)
Declared routes, settings and where they are set, and owners by commit history, per repository.
Runtime (Vörr)
Services and environments behind each repository, branch-to-environment mapping, current health and SLOs, runtime dependents, recent deploys with the regression windows Vörr detects alongside them (with Grafana connected), and incident patterns.
Together
CodeZero shows who depends on the change in code; Vörr shows which of those services are live, where they run and how healthy they are, before merge and after deploy.
Illustrative example

Worked example: a field rename in a small, green pull request

Pull request 214 in orders-api renames total to totalAmount in the order response, to make room for taxAmount. It changes 6 files, the tests pass and the description says "all usages updated". The agent that wrote it searched orders-api and found every use there. Reviewed on the diff alone, it looks fine. The billing worker, in a repository nobody had open, reads total from the API and would write zero-value invoices after deploy.

The reviewer sizes the change in Compare, then asks for the plan. There is none: the change was made without one. So the reviewer checks the two changed source files against their dependents. The same consumers are found as in Ship a cross-repository change.

Compare main...feature/tax-amount
  3 commits, 6 files, +84 -31
  source  src/orders/orders.serializer.ts       +12 -9
  source  src/events/publish.ts                  +4 -4
  tests   test/orders.serializer.spec.ts        +41 -12
  config  .env.example                           +1 -0   TAX_SERVICE_URL
  ...

Depended on by the removed total field
  billing-worker, mobile-backend, notifications   (reads total)
  admin-web                                       (low confidence)
  None mentioned in the PR description
Illustrative example

Verify confirms billing-worker and mobile-backend and returns wrong for admin-web, whose call reaches catalog-api. The text search finds one more use: a fixture in notifications that will keep its tests green while the handler breaks. TAX_SERVICE_URL is in .env.example but not in the staging Helm values.

Vörr adds the runtime side. The main branch maps to production. billing-worker is healthy, but Vörr shows a regression window after a deploy nine days ago, and the service graph shows a caller nobody listed: a reconciliation job.

Vörr, orders-api and dependents (production)
  orders-api      Datadog  error rate 0.3%  p95 180 ms  SLO OK            match explicit
  billing-worker  Datadog  error rate 0.4%  p95 420 ms  SLO OK            match explicit
  Deploys         billing-worker  #471  regression window after it (Grafana, 9 days ago)
  Callers of orders-api  billing-worker, mobile-backend, notifications,
                         recon-job (match name)
Illustrative example

The review asks for an expand-and-contract change: serve total and totalAmount together, publish both in order.created, add TAX_SERVICE_URL to staging and production values, and update the notifications fixture. Consumer changes follow as their own pull requests, with owners of billing-worker and mobile-backend added as reviewers. The recon-job match is by name only, so the reviewer asks its owner to confirm.

After merge and deploy, Vörr shows the orders-api deploy in the feed and an unchanged error rate for billing-worker against 7 days ago. Removing total is recorded as a follow-up, to run once every consumer reads totalAmount.

Verify and follow up

  • Provenance: every finding in a comment should have a file and line, an edge, or a Vörr fact with its source and environment.
  • Match quality: low-confidence edges are questions until verified, and name, suggested or unmapped service matches in Vörr deserve a second look.
  • Coverage: confirm that the repositories you expect are indexed and that observability and CI tools are connected for each affected service. An absent result from an unconnected source means nothing.
  • Plan: if there is a plan, every consumer from the impact check is either in it or deliberately excluded, with the reason recorded.
  • Tests: the pull request's checks pass, and the behaviour the change decides is tested, in the producer and in the consumers that matter.
  • Follow-ups: record deprecations and cleanups, re-run the consumer search before removing anything, and check each service after deploy.

Limits

  • CodeZero is not a review bot. It does not comment on pull requests, approve them or gate merges. Posting comments is something your agent does with gh, if you ask it to.
  • The organisation index covers committed code on the default branch. The branch under review is visible through your local checkout; other unmerged branches, and repositories that are not connected, are not.
  • Inferred edges come from matching paths, names and config. URLs built at runtime, gateway rewrites and dynamically named queues can be missed or matched with low confidence.
  • References are matched by name and callers are heuristic; neither is compiler-accurate.
  • Test answers are reasoning over code, not measured coverage.
  • A plan exists only if the change was made with CodeZero. Changes made elsewhere carry only what their author wrote down.
  • Vörr is read-only and depends on the service map and connected tools. It reports health, dependents and deploys; it does not deploy, roll back or change infrastructure.
  • Neither product decides whether a change should merge. The reviewer does.

Related