diffy

Configuration

.diffy.yaml

Per-repository review settings: what to look for, what to leave alone, and which documents to read

Create the file

  • Put a file named .diffy.yaml (or .diffy.yml) at the root of the repository. If both exist, .diffy.yaml is used.
  • Start small. Every setting is optional, and an empty file is the same as no file. Add a setting when a review shows you need it.
  • Merge it into the default branch. That is where diffy reads it from.

A wrong value never stops a review: the setting is reported and replaced by its default, and the others still apply. See Warnings.

Example

.diffy.yaml
# The language of the summary, titles and explanations: en (default) or th.
# Code, file paths and the "fix prompt for your coding agent" always stay English.
language: en
# assertive (default): also missing error handling, untested changes and maintainability problems.
# chill: only what matters.
profile: assertive
# What the reviewers of this project care about. Up to 20,000 characters together with instructions_file.
instructions: |
We use Drizzle for all database access. Flag any raw SQL.
Money is always stored in satang as an integer.
# A file of the repository (on the default branch) with longer instructions. Added after `instructions`.
instructions_file: docs/review-instructions.md
# Instructions for part of the code. Only sent when the pull request changes a matching file.
path_instructions:
- path: "src/server/**"
instructions: Every endpoint must check the signed-in user's permissions.
- path: "**/*.sql"
instructions: Migrations must be reversible.
# More documents to read before every review (on the default branch, up to 10).
context_files:
- docs/ARCHITECTURE.md
# Files that are never reviewed. Same pattern syntax as .gitattributes.
ignore:
- "public/**"
- "**/*.svg"

Settings

SettingWhat it doesDefault
languageThe language of the summary, titles and explanations: en or th. Code, file paths and the fix prompt stay in English.en
profileassertive also reports missing error handling or input validation on new code, changed behavior with no test, and maintainability problems, as low or medium findings. chill reports only what matters.assertive
instructionsWhat the reviewers of the project care about, in plain words, like a note to a new reviewer. Up to 20,000 characters together with instructions_file.none
instructions_fileA file in the repository, on the default branch, with longer instructions. Its text comes after instructions.none
path_instructionsA list of path and instructions. Sent only when the pull request changes a file that matches the path. Up to 50 entries of 5,000 characters.none
context_filesMore documents to read before every review, like architecture notes or a style guide. Up to 10. They are read before the files diffy finds by itself.none
ignoreFiles that are never reviewed. Up to 100 patterns.none

Lockfiles, build output, migration snapshots and other generated files are skipped without any setting, and so is anything marked linguist-generated in .gitattributes. Instructions can add things to look for and tell diffy what to leave alone. They cannot change the format of the review or the rules for line numbers.

Pattern syntax

ignore and the path of each path instruction use the pattern syntax of .gitattributes, which is close to .gitignore but smaller.

PatternMatches
*.svgAn .svg file in any folder (a pattern with no slash matches by name, anywhere)
public/**Everything under public/ at the root of the repository
**/*.sqlAn .sql file in any folder, including the root
docs/A folder named docs, at any depth, and everything in it (a trailing slash means the folder)
/package-lock.jsonOnly that file, at the root (a leading slash anchors it)
src/*.ts.ts files directly in src/, not deeper (a slash in the middle anchors it to the root)
file?.txtfile1.txt, fileA.txt: ? is one character that is not a slash
  • * matches within one folder level, ** across folders.
  • A pattern with a slash anywhere but the end is relative to the root of the repository.
  • Not supported: ! to take a file back in, [abc] classes and {a,b} alternatives. A pattern that uses them is read literally, so write two patterns instead of *.{ts,tsx}.
  • The paths of instructions_file and context_files are plain paths in the repository: no leading /, no .., no backslashes.

Writing instructions that work

  • Say what to flag, and what is fine. "Flag raw SQL; we use Drizzle" works. "Write good code" does nothing.
  • Give the reason when it is not obvious. "Money is an integer number of satang, so a float is a bug" lets the model judge a case you did not list.
  • Keep it short and specific. Ten sentences about the rules that matter beat a page of everything. Put long reference material in a file and name it in context_files.
  • Use path_instructions for rules that apply somewhere. They are sent only when a changed file matches, so they cost nothing on other pull requests.
  • Do not repeat what your AGENTS.md, CLAUDE.md or README already say: diffy reads those on its own.
  • Do not ask for style comments. diffy leaves formatting and naming to your linters.

More examples

The smallest useful file:

.diffy.yaml
instructions: |
This is a billing service. A bug that charges a customer twice, or not at all, is always critical.
ignore:
- "**/*.snap"

A TypeScript monorepo:

.diffy.yaml
language: en
profile: assertive
instructions: |
Follow AGENTS.md. Money is an integer number of satang, never a float.
A change to a public API needs a test that would fail without it.
path_instructions:
- path: "apps/api/src/**"
instructions: Every route needs an auth check. Another account's row must look like "not found".
- path: "apps/api/prisma/migrations/**"
instructions: Never edit a migration that is already merged. Flag anything that drops data.
- path: "apps/web/src/**"
instructions: Use the generated API client, never a hand-written fetch.
context_files:
- docs/ARCHITECTURE.md
ignore:
- "apps/api/openapi.json"
- "**/*.generated.ts"

A documentation repository:

.diffy.yaml
profile: chill
instructions: |
Check facts, commands and links. Ignore wording preferences.
ignore:
- "static/**"

Check that it works

  • Merge the file into the default branch, then open or update a pull request.
  • At the bottom of the review, diffy lists the documents it read. If the file has a problem, a collapsed section "problem(s) with the diffy settings of this repository" lists each one.
  • To see that an instruction is used, add one that is easy to spot, like "mention the word pineapple in the summary", open a pull request, and then remove it.

Warnings

Every message starts with the name of the file. Each setting is checked on its own, so one mistake does not cost you the rest.

MessageWhat it means and what to do
The file is not valid YAML, so it was ignoredThe whole file is skipped. Check indentation and quotes; a tab is not allowed.
The file must be a YAML mapping of settings, so it was ignoredThe top level must be setting: value lines, not a list or a single value.
Unknown setting "x" was ignoredA misspelled setting. The known ones are language, profile, instructions, instructions_file, path_instructions, ignore, context_files.
language must be "en" or "th", not …Fix the value. en is used.
profile must be "chill" or "assertive", not …Fix the value. assertive is used.
instructions must be text. It was ignoredUse a string, or a | block.
instructions_file must be a path in the repositoryUse a path like docs/review-instructions.md.
instructions_file "x" must be a path inside the repositoryNo leading /, no .., no backslashes.
instructions_file "x" was not found on the default branchThe file is not on the default branch yet. Merge it first, or fix the path.
the instructions are longer than 20000 characters. The rest was cutinstructions plus the file are over the limit. Shorten them.
path_instructions must be a list of { path, instructions }Use a list of items that each have both fields.
path_instructions[N] needs a "path" and "instructions", both textThe item at position N (counting from 0) is missing one. It was skipped.
path_instructions[N] is longer than 5000 characters. It was cutShorten it.
Only the first 50 path_instructions are usedMerge entries that share a rule.
ignore must be a list of path patterns (text)Use a list of strings.
Only the first 100 ignore patterns are usedUse broader patterns.
context_files must be a list of paths in the repository (text)Use a list of strings.
context_files "x" must be a path inside the repositoryNo leading /, no .., no backslashes.
context_files "x" was not found on the default branchThe document is not on the default branch.
Only the first 10 context_files are usedMerge documents, or keep the ones that matter.
Could not read the repository's diffy settings (…). Defaults were used.GitHub could not be asked. The review ran with the defaults.

Limits

WhatLimit
instructions and instructions_file together20,000 characters
One path_instructions entry5,000 characters
path_instructions entries50
ignore patterns100
context_files10
One document read by diffy10,000 characters
All documents together30,000 characters by default (a server setting)

The documents diffy reads on its own, and how much of a change the model sees, are on What diffy reads.