> ## Documentation Index
> Fetch the complete documentation index at: https://docs.codewarden.co/llms.txt
> Use this file to discover all available pages before exploring further.

# .codewarden.yml reference

> Every key of the file a repository uses to tell CodeWarden its own rules: type, default, and an example.

`.codewarden.yml` is an optional file at the root of a repository. It states how that repository wants to be reviewed: which paths to skip, which rules apply in which paths, which facts the model tends to get wrong, and which pull requests not to review at all.

With no file, a repository gets every default on this page. Every key is optional.

## Where it is read from

CodeWarden reads `.codewarden.yml` from the pull request's **base branch**, at its current tip. It never reads the copy in the pull request under review, including when the pull request is the one that adds or edits the file.

This is on purpose. If the edited copy were read, anyone who can open a pull request could rewrite the reviewer's instructions, or switch the review off, in the same commit that hides a defect. A change to `.codewarden.yml` takes effect on pull requests into a branch once it is merged into that branch.

## A bad file never fails a review

| Situation | What happens |
| - | - |
| No file | Defaults. |
| GitHub does not serve the file | Defaults, and the review runs. |
| Not valid YAML, or not a mapping | Defaults, and the review runs. |
| One key has the wrong shape | That key uses its default. Every other key still applies. |
| One entry in a list is malformed | That entry is dropped. The rest of the list applies. |
| A key CodeWarden does not know | Ignored. A key from a newer version is safe to write. |
| Text over a length limit | That item is dropped. |

What was in force for each review, and anything that was dropped, is shown on the review's page in the [console](/console/review-history) under **What was in force**. The setup checklist on the console's home page also says whether the file was found and could be used.

## A complete example

```yaml .codewarden.yml theme={null}
language: en
profile: balanced
tone: "Be direct. Skip the preamble."

ignore:
  - "legacy/**"
  - "priv/static/**"
unignore:
  - "docs/architecture.md"

instructions:
  - path: "lib/**/workers/**"
    text: |
      These run in a job queue with retries. Flag anything that is not safe
      to run twice on the same input.

errata:
  - "URI.parse/1 fills in the scheme's default port, so .port is 443 for https, never nil."

skip:
  labels: ["no-review"]
  authors: ["dependabot[bot]", "renovate[bot]"]
  base_branches: []

jira:
  projects: ["PROJ"]
  public_repositories: false

sentry:
  projects: ["widgets-api"]
  public_repositories: false

accepted:
  - path: lib/widgets/clicks.ex
    problem: "read-modify-write on the click counter"
    category: bug
    code: |
      |> Ecto.Changeset.change(clicks: link.clicks + 1)
    reason: "the counter is advisory and the nightly job recomputes it"
```

## What CodeWarden writes

### language

<ResponseField name="language" type="string" default="en">
  The language of the summary and the comments, as an ISO code such as `en`, `es` or `pt-BR` (2 to 8 characters).
</ResponseField>

### profile

<ResponseField name="profile" type="quiet | balanced | strict" default="balanced">
  The most comments one review may carry: `quiet` is 4, `balanced` is 8, `strict` is 15.

  That is all it sets. Findings are sorted worst first, so a smaller cap keeps the most serious ones. It does not filter by severity, and there is no minimum-confidence setting: see [How a review works](/how-a-review-works#what-decides-which-comments-are-published).
</ResponseField>

### tone

<ResponseField name="tone" type="string" default="none">
  One or two sentences about the voice of the comments, up to 200 characters. Longer text is dropped.

  ```yaml theme={null}
  tone: "Be direct. Skip the preamble."
  ```
</ResponseField>

## What CodeWarden reads

### ignore

<ResponseField name="ignore" type="list of globs" default="[]">
  Paths never to review, on top of the [built-in list](/how-a-review-works#which-files-are-read).

  ```yaml theme={null}
  ignore:
    - "legacy/**"
    - "**/*_generated.ex"
  ```
</ResponseField>

### unignore

<ResponseField name="unignore" type="list of globs" default="[]">
  Paths to review even though the built-in list or `ignore` would skip them. `unignore` wins over both.

  It cannot rescue a file with no diff, or one with more than 1,500 changed lines.

  ```yaml theme={null}
  unignore:
    - "docs/architecture.md"
  ```
</ResponseField>

### Globs

Globs match the whole path from the repository root, case-sensitively. `**` crosses directory boundaries, `*` and `?` do not. `lib/**` matches files under `lib/` and not `vendor/lib/x.ex`. A pattern that matches nothing is not an error.

## What CodeWarden knows

### instructions

<ResponseField name="instructions" type="list of { path, text }" default="[]">
  Rules for particular paths. The text is added to the review only for files whose path matches `path`, so a controller can be held to rules a helper module is not.

  Use it to say what counts as a defect there: a rule your team decided in a design document, a spec, or someone's head, which the reviewer cannot see otherwise.

  Each `text` is limited to 2,000 characters; an entry with an empty `path` or `text`, or over the limit, is dropped. The instructions that match the files of one review share 8,000 characters, so a repository cannot crowd its own code out of the review. When they do not all fit, the ones that match the most files go first.

  ```yaml theme={null}
  instructions:
    - path: "lib/**_web/live/**"
      text: |
        Every handle_event must load records through the caller's scope.
        A record loaded by id alone is an authorization hole, not a style issue.
  ```
</ResponseField>

`instructions` cannot:

* make CodeWarden comment on a line the pull request did not add;
* turn on comments about style, naming, formatting, import order, missing tests, missing documentation, or anything phrased as "consider";
* reach a file the pull request did not touch, or a file the filters skipped;
* replace the rules the reviewer is given. It only adds to them.

### errata

<ResponseField name="errata" type="list of strings" default="[]">
  Facts about your libraries that the model gets wrong. One sentence each, stating what is true, up to 300 characters. They are kept in the order you write them.

  Add one the day CodeWarden publishes a confidently wrong claim about a library you use.

  ```yaml theme={null}
  errata:
    - "An Oban {:snooze, n} does not spend an attempt; Oban raises max_attempts with it."
  ```
</ResponseField>

## Which pull requests to review

### skip

<ResponseField name="skip" type="mapping">
  Pull requests CodeWarden should not review. A skipped pull request costs no AI turn, posts nothing, and appears in the console with the status `skipped` and the reason.

  <Expandable title="skip keys">
    <ResponseField name="drafts" type="boolean" default="true">
      Skip draft pull requests. With the default, a draft is reviewed once, when it is marked ready for review, and its earlier pushes cost nothing and leave no entry in the console. Set it to `false` to review drafts like any other pull request: when one is opened and on every push. Marking a reviewed draft ready then reviews only what is new since.
    </ResponseField>

    <ResponseField name="labels" type="list of strings" default="[]">
      Skip a pull request that carries any of these labels.
    </ResponseField>

    <ResponseField name="authors" type="list of strings" default="[]">
      Skip pull requests opened by these GitHub accounts, for example `dependabot[bot]`.
    </ResponseField>

    <ResponseField name="base_branches" type="list of strings" default="[] (every branch)">
      Review only pull requests into these branches. Empty means every branch.
    </ResponseField>
  </Expandable>

  ```yaml theme={null}
  skip:
    labels: ["dependencies", "no-review"]
    authors: ["dependabot[bot]", "renovate[bot]"]
    base_branches: ["main"]
  ```
</ResponseField>

To stop reviewing a whole repository, switch it off in the console instead. See [Repository switches](/configure/repositories).

## Integrations

### jira

<ResponseField name="jira" type="mapping">
  Which Jira projects a pull request may link a ticket from. Without this key, no ticket is ever read. See [Jira](/integrations/jira).

  <Expandable title="jira keys">
    <ResponseField name="projects" type="list of project keys" default="[]">
      Upper-case project keys, such as `PROJ` in `PROJ-123`.
    </ResponseField>

    <ResponseField name="public_repositories" type="boolean" default="false">
      On a public repository, no ticket is read unless this is `true`, so a private ticket is not quoted in a public review.
    </ResponseField>
  </Expandable>
</ResponseField>

### sentry

<ResponseField name="sentry" type="mapping">
  Which Sentry projects a pull request may link an issue from. Without this key, no issue is ever read. See [Sentry](/integrations/sentry).

  <Expandable title="sentry keys">
    <ResponseField name="projects" type="list of project slugs" default="[]">
      Lower-case Sentry project slugs, such as `widgets-api`.
    </ResponseField>

    <ResponseField name="public_repositories" type="boolean" default="false">
      On a public repository, no issue is read unless this is `true`.
    </ResponseField>
  </Expandable>
</ResponseField>

## Findings already decided

### accepted

<ResponseField name="accepted" type="list of { path, code, problem, category, reason }" default="[]">
  Findings your team looked at and decided are not defects here. A finding that matches one is not published. You rarely write these by hand: CodeWarden proposes the exact lines when it concedes in a conversation. See [Accepted findings](/configure/accepted-findings).

  `path` and `code` are required, and `code` (up to 2,000 characters) must be text that is really in the file. `problem`, `category` and `reason` are optional.
</ResponseField>

## What the file deliberately cannot do

* **Run tools.** There is no `tools` section for linters or static analysers. Running them means running code from the repository, and a linter configuration is code.
* **Choose the model or its cost.** Which model reviews a pull request is CodeWarden's responsibility.
* **Set a minimum confidence.** It was measured, and it did not change what gets published.
* **Turn off incremental review.** See [Incremental review](/how-a-review-works#incremental-review).
* **Replace the review prompt.** Everything in the file adds to the rules; nothing replaces them.

The console does not hold review rules either. They live in this file, in your repository, where they are reviewed like any other change.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.