Skip to content

PR Review Skill - #1318

Open
Aditya Krishnan (arkrishn94) wants to merge 4 commits into
mainfrom
u/adkrishnan/pr-review-skill
Open

PR Review Skill#1318
Aditya Krishnan (arkrishn94) wants to merge 4 commits into
mainfrom
u/adkrishnan/pr-review-skill

Conversation

@arkrishn94

Copy link
Copy Markdown
Contributor

This PR introduces a pull request review skill dedicated to this repo.

Why

There's two main reasons for why this is useful -

  • With coding agents becoming better, as we all have noticed, a significant amount of admin's bandwidth is being spent reviewing lengthy diffs. This level of commitment reduces the available time for admin to actually produce output.
  • Many PRs have recurring bugs/comments because feedback left on one author's PR is not necessarily easily visible to another. This wastes the time of reviewers since they need to repeatedly flag the same incorrect patterns, elongating the review cycle and wasting bandwidth.

Review Agent

  • This PR mainly introduces a skill (diskann-pr-review) for GitHub Copilot to use to review PR.
  • This is not meant to be a substitute for a comprehensive human review but hopes to at least catch the initial set of low-hanging feedback.

The PR introduces a skill captured in .github/skills/diskann-pr-review. The main flow for the review is in the SKILL.md and is accompanied with a file rules.md that is a repository for the kind of errors/rules we would want enforced by the review agent.

This file is meant to be a living document and is meant to evolve as we observe more patterns that can be codified and as we learn how effective this agent is.

The file was created using an agent: I got an agent to look at all the human feedback given to PRs in the last 3 months, triage them based on their importance and try to list down the repeated/codifiable offenses. I have then done a manual check of every rule in that file. Feedback and edits to this file are welcome and encouraged!

Integration with CI

One interesting bug in out GHCP CI integration that surfaced from this effort was that GHCP expects very specific filenames to pick up instructions and the agents md file. Hence the renaming of instructions.md -> copilot-instructions.md and agents.md -> AGENTS.md.

We still need to manually:

  • Set code review effort to "Balanced"
  • Confirm the custom-instructions toggle
  • Set rereview on push

Adds .github/skills/diskann-pr-review/, a review skill distilled from the last three months of review history (152 PRs, ~1,560 human review comments). SKILL.md carries the review workflow and a blocking checklist, rules.md is the detailed catalog of 62 rules, and MAINTENANCE.md documents how to refresh it against newer PRs.

Adds .github/copilot-instructions.md, loaded by every Copilot surface, stating the rules that must hold even when the skill is not invoked: crate tiers, the three error-handling regimes, unsafe documentation, the 90% patch coverage gate, and hygiene requirements.

Removes .github/instructions.md, which sat at a path no tool reads. Its four rules (no silent test deletion, dependency justification, build times, license header) are preserved in the new files.

Renames agents.md to AGENTS.md to match the name agent tooling looks for. No tracked file referenced the old spelling.

Rules are identified by a stable slug rather than a number, so entries can be added and deleted without renumbering and references do not rot. Human contributors may ground a rule in maintainer judgement; an agent updating the file may only cite a review quote or a repo source, so anything it adds stays independently checkable.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a repository-specific GitHub Copilot PR review skill (diskann-pr-review) plus supporting documentation (rules.md, AGENTS.md) and updates Copilot instruction filenames to match GitHub Copilot’s expected conventions.

Changes:

  • Introduces .github/skills/diskann-pr-review/ with a review workflow guide (SKILL.md) and a detailed rule catalog (rules.md).
  • Adds a repo-root AGENTS.md onboarding guide for coding agents.
  • Replaces the previous .github/instructions.md with .github/copilot-instructions.md for Copilot custom instructions.

Reviewed changes

Copilot reviewed 4 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
AGENTS.md Adds agent onboarding / repo workflow guidance.
.github/skills/diskann-pr-review/SKILL.md Defines the PR review skill workflow and blocking checklist.
.github/skills/diskann-pr-review/rules.md Adds an evidence-backed rules catalog for reviews.
.github/instructions.md Removes the old Copilot instructions filename.
.github/copilot-instructions.md Adds Copilot custom instructions under the expected filename.
Suppressed comments (1)

.github/skills/diskann-pr-review/SKILL.md:67

  • This checklist item says license headers are required for "every new file", but the repository contains many non-Rust files without such headers. Narrowing this to Rust source files helps prevent noisy/incorrect review comments.
| 9 | License header present on every new file | `.github/copilot-instructions.md` |

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.


## Hygiene

- Every new file carries the license header:
Comment thread .github/skills/diskann-pr-review/SKILL.md Outdated

### license-header `BLOCK`

**License header on every new file.**

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is mostly correct, but we would want a license on code in other languages if it was ever committed. What we don't want is licenses on data files, test inputs, or Markdown files

@codecov-commenter

Codecov Comments Bot (codecov-commenter) commented Aug 10, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.30%. Comparing base (027d834) to head (332f17b).

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #1318      +/-   ##
==========================================
+ Coverage   91.31%   92.30%   +0.98%     
==========================================
  Files         517      517              
  Lines       98518    98518              
==========================================
+ Hits        89965    90938     +973     
+ Misses       8553     7580     -973     
Flag Coverage Δ
miri 92.30% <ø> (+0.98%) ⬆️
unittests 92.27% <ø> (+1.27%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.
see 40 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

@wuw92 Wei Wu (wuw92) left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for contributing this skill, it helps lot to reduce review effort. I’d keep skill focused on semantic review:

  • Rely on CI and Lint for deterministic violations, such as coverage thresholds, missing SAFETY comments, and disallowed unwrap/expect/panic! calls.
  • Use the skill for higher-level issues involving soundness, API contracts, and architectural invariants.


## Review workflow

### 1. Orient before reading the diff

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this skill stay focused on DiskANN-specific review lenses, evidence requirements, and calibration? The mandatory fetch workflow seems to take over agent orchestration and may duplicate or conflict with context acquisition already handled by hosted Copilot review or other skills

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great point Wei, that makes sense.


These are the items that stop a merge. Verify each explicitly — do not assume.

| # | Blocking check | Where it's enforced |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we separate CI-owned merge gates from agent-owned semantic review here? “These items stop a merge” and “verify each explicitly” ask the reviewer to duplicate Codecov/Clippy and imply merge authority that hosted Copilot review does not have

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for contributing this!

I think my main comment is that we could use some crate-specific standards in addition to the general standards laid out here. For example, we're okay with untested code in diskann-tools. In diskann-benchmark, new algorithm submissions require example .json files. Within test-data, large files must use git lfs (and don't put data files anywhere else). We could have a section with special instructions for each crate, and add to them over time even if they're sparse at first.

Okay also.... would it be feasible to ask the reviewing agent to look at human-written comments and suggest new additions to the reviewing instructions if it finds any during review? This would be interesting to experiment with and could help things evolve over time.

Also complete the checklist in [PULL_REQUEST_TEMPLATE.md](../../PULL_REQUEST_TEMPLATE.md): release-
note-worthy title, new dependencies, API modifications, backward compatibility, docs impact.

### rfc-for-significant-change `MAJOR`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't say this one is a hard and fast rule. Maybe better to leave this to human judgment.


### license-header `BLOCK`

**License header on every new file.**

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is mostly correct, but we would want a license on code in other languages if it was ever committed. What we don't want is licenses on data files, test inputs, or Markdown files

- Reviewers state their stake and priority openly ("I have a vested interest in seeing something like
this merged ASAP. That said, there is a lot of work needed…"). Transparency about trade-offs beats
false neutrality.
- Praise for good design choices is normal and expected.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lol


| # | Blocking check | Where it's enforced |
|---|---|---|
| 1 | **Patch coverage ≥ 90%** on changed lines | `.codecov.yml` (`informational: false`) |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't true in every crate, is it?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did one pass against some of the earlier rules.


**Struct fields stay private; invariants live in constructors.**
Public fields silently void every check the constructor performs, and the invariant can never be
reinstated without a breaking change.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a little nuance here: types that are just data aggregates with no invariants can have public members. Maybe more nuanced: "fields with invariants must be private".


### no-duplicate-abstraction `MAJOR`

**Don't duplicate an abstraction across index types.**

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A corollary here: often sharing properly require refactoring in order to work. This is often the best time to do the refactor because hopefully the additional requirements are clear.

Om the other hand: don't try to make something work just for the sake of sharing. If it's truly a bad fit, don't lean into it.

That said, taking the time to fortify/refactor something in a more generally useable direction will often pay off in the future.


**Question new top-level crates.**
Prefer a feature-gated module inside an existing crate. Crate proliferation hurts discoverability
and build times.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I completely agree: feature proliferation is not great either because it's harder to test (do we test all feature combos? Build the crate both with and without the feature etc). I think the diagram is more like:

  1. Can the feature be added without a feature gate and without significantly impacting (1) transitive dependencies, (2) compile times, (3) API surface? If so, do that.
  2. If a feature benefits greatly from existing internals and is cleanly additive, use a feature gate.
  3. Make new crates as a last resort.

Additionally, internal tools (eg vectorset) that pull in a bunch of dependencies but that otherwise have minimal dependence on diskann-* can live in their own workspace.

### no-module-name-in-type `NIT`

**Don't repeat the module name in the type name.**
`flat::SearchStrategy`, not `flat::FlatSearchStrategy`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is some nuance here as this can be taken too far. However, if names get longer the deeper in the hierarchy you go, it's probably a sign to reevaluate.

Maybe something like "consider using module names as part of the identity of a type"?


### document-benign-races `MAJOR`

**Document benign races explicitly, with the reasoning.**

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's not bring up "benign races". They don't exist since unsynchronized concurrent access (with at least one mutator) is always UB.


### fail-at-load-time `MAJOR`

**Fail at load/parse/match time, not mid-run.**

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe more generally: "fail as early as is reasonable". And an add-on: "use types to encode invariants that have already been checked".

### checked-conversions `MAJOR`

**Prefer checked conversions to `as`.**
Silent truncation is a recurring source of ID-space bugs.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Treat narrowing as conversions with great skepticism.


**Every `unsafe` block carries a `// SAFETY:` comment.**
Enforced by the workspace clippy lint `undocumented_unsafe_blocks`. The comment must name the
invariant that makes the operation sound, in the same units as the operation (element counts vs.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few words on invariants:

  • Invariants can rely on known and documented properties of concrete types (e.g. slices don't lie about their length)

  • Invariants can rely on properties established locally (e.g. via assert! or other check)

  • Invariants may not rely on unchecked properties of an argument or between arguments of a safe function that only exist as part of the function contract. Either check the property, make the property inherent to the argument type, or make the function unsafe.

  • Invariants must not depend on generic arguments implementing safe traits responsibly. Assume pathological cases exist. For example:

    • T: Deref<Target = &[f32]>: Unsafe code cannot rely on the same slice being returned on every deref for a generic T.
    • ExactSizeIterator: Implementations can by incorrect and the trait explicitly documents this.

    Either restructure the code to remove this dependence or make the necessary trait unsafe.


---

## 3. Unsafe code

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Unsafe code should be exercised under Miri."


### watch-monomorphization `MAJOR`

**Watch monomorphization and code bloat.**

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't be afraid to use trait objects, especially in higher level code where the cost of dynamic dispatch is negligible.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another round from me. One thing to keep in mind is that redundant or overly long skills can dilute the context window. Items that are already in copilot-instructions hopefully don't need to be repeated. But I'm not an LLM expert.

are frequently negotiated in-thread, and a review that re-litigates a settled decision costs the
author time and undermines the reviewer's credibility.

```powershell

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suspect agents already know how to do this with the github MCP.

body itself (rule `patch-coverage`) and skim bot findings for genuine correctness bugs before
discarding them.

#1269 is the cautionary case. The module is named `views` while the PR description says `matrix`,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be condensed? e.g. "#1269 is a cautionary case. A reviewer requested deferring a module rename to simplify the diff, leaving the PR description stale. Here, an AI reviewer should flag the description not the code."


## 9. Interaction norms

### read-existing-review-threads `BLOCK`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not necessarily blocking?

### rfc-for-significant-change `MAJOR`

**RFC required for architecturally significant change.**
Per [rfcs/README.md](../../../rfcs/README.md): new crates, cross-crate traits/abstractions, new

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My (maybe hot) take is that RFCs without implementations are not very useful.

> "These are still being referenced in some internal tests… please double check they are indeed safe
> to remove" — #1185, @hildebrandmw

### no-build-time-regression `MAJOR`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already covered in copilot-instructions?


### valid-intra-doc-links `NIT`

**Keep intra-doc links valid.**

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should really turn this into a CI lint.

### no-dead-code-in-tests `MAJOR`

**`#[allow(dead_code)]` in tests is a smell.**
Either the helper is used (write the test) or it isn't (delete it).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exceptions are allowed if the code is nontrivial and logically belongs with an API.


**Explicit non-goals.**
Per AGENTS.md — **do not** request tests for derived traits (`Clone`, `Debug`, `PartialEq`) or for
enums without explicit functionality. And duplication inside unit tests is acceptable:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some code duplication. Too much compromises maintainability. Often it's worth investing in test infra.


### no-deleting-tests `BLOCK`

**Don't delete tests without justification.**

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already in copilot-instructions?


### smoke-test-new-public-api `MAJOR`

**New public methods get at least a smoke test.**

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like this is table stakes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants