# Repo context and rules

URL: https://codepanel.ai/docs/repo-context

Give reviewers your conventions: .codepanel/rules.md, review rules, notes, learnings and verdict memory, and how they fit the context budget.

Repo context is added to every reviewer's prompt and the orchestrator's, so findings are judged against your conventions. A review uses at most 16,000 characters of it, rules first.

## Context sources

| Source | Where it lives | Who writes it | Limit |
| --- | --- | --- | --- |
| [`.codepanel/rules.md`](#codepanelrulesmd) | The repository, read from the base branch | You or your coding agent | The [budget](#context-budget); ignored over 1,000,000 bytes |
| [Review rules](#rules-and-notes-in-the-app) | The repository's **Knowledge** tab | You; repository rules also an agent, via the [knowledge document](#read-and-rewrite-from-an-agent) | The budget |
| [Notes](#rules-and-notes-in-the-app) | The repository's **Knowledge** tab | You or an agent, via the knowledge document | The budget |
| [`AGENTS.md`, `CLAUDE.md`](#agentsmd-and-claudemd) | The repository root, base branch; off by default | Your repository | The budget |
| [Learnings](#learnings) | One fact each (`L3`), on the **Knowledge** tab | People, agents, or drafted by CodePanel | 10 per review, orchestrator only |
| [Verdict memory](#verdict-memory) | Ratings and dismissals on past findings | Whoever rated them | 12 whole, the rest in short; orchestrator only |

Only your own rules and notes are used, and only enabled rules.

## .codepanel/rules.md

Every reviewer reads this file on every review of the repository. Put in it what a reviewer cannot infer from the diff: invariants, deliberate conventions, the mistakes your codebase keeps attracting. No structure is required; one line per rule works best. The [Repository setup](/docs/agent-setup) prompt has your coding agent write it from `AGENTS.md` or `CLAUDE.md`.

```markdown title=".codepanel/rules.md"
- Money is stored and computed in integer cents. Flag any float arithmetic on amounts.
- Files under convex/migrations/ are append-only. Flag an edit to an existing migration.
- Do not report formatting; Biome enforces it in CI.

## convex/**
- Every public function checks auth first.

## *.sql, migrations/**
- Never drop a column in the same change that stops writing it.

## `package.json`
- Pin exact versions.

## CI/CD
- Name constants. This heading is not a pattern, so it always applies.
```

Good rules are specific and checkable ("Flag SQL that bypasses the ORM", not "write good code"), say what is forbidden and why, and name what not to report: what a linter enforces, or a pattern that looks wrong but is deliberate ([Reducing false positives](/guides/reducing-false-positives)). The **Docs & Best Practices** [role](/docs/reviewers#roles) quotes the rule each finding breaks.

### How the file is read

- **From the base branch, never the head**, so a pull request cannot loosen its own rules. An edit applies once merged into the target branch.
- **First in the context**, under "Repository Review Rules", which tells reviewers a violation is a finding.
- **Within the budget.** A file too long is trimmed at a line break and marked "section trimmed for length", leaving less room for what follows.
- **Best effort.** No file is normal. If it cannot be read (GitHub down, a timeout), the review runs without it and a warning is logged. A file over 1,000,000 bytes or of only whitespace adds nothing.

### Scoped rules

A level-two heading that is a file pattern scopes the rules under it: the section is sent only when the pull request changes a matching file (any file the pull request changes, not only those one round reviews). Rules above the first such heading, or under an ordinary heading, always apply.

| Rule | Detail |
| --- | --- |
| Pattern heading | A `##` (or `#`) heading of one or more comma-separated patterns, each in backticks or containing `*` or `{a,b}`, with no spaces. A pattern with no wildcard (`` `package.json` ``, `` `src/api` ``) needs backticks. Anything else ("CI/CD", "Why?", "Node.js") is an ordinary heading. |
| Matching | As in `.gitignore`: no slash matches a name at any depth (`*.sql`), `*` stays in one directory, `**` crosses directories, `{ts,tsx}` lists alternatives, a directory covers everything under it, a leading `/` anchors to the root. |
| Section end | The next heading of level two or higher. `###` headings belong to the section; headings in code fences are text. |

A section left out because it does not apply is not reported as left out for length.

## Rules and notes in the app

| To add | Do this |
| --- | --- |
| A rule or note for one repository | The repository's **Knowledge** tab: a rule is a name and one sentence, such as "TypeScript Types: always suggest explicit types on function parameters." |

To turn a rule off without deleting it, untick "Turn off <name>" on the **Knowledge** tab.

## Learnings

A learning is one short fact with an optional path-prefix scope: "In `convex/reviews/`, `renew()` extends the lease before any write." When a review touches its scope, the orchestrator is told it and checks it against the code, so a finding refuted for that reason is not repeated.

| Action | PR comment | CLI | MCP | HTTP |
| --- | --- | --- | --- | --- |
| List | | `codepanel learnings <owner/name>` | `list_learnings` | `GET /api/v1/learnings` |
| Add | `/remember <text> [--scope <path>]` | `codepanel learn <owner/name> <text> [--scope <path>]` | `add_learning` | `POST /api/v1/learnings` |
| Confirm | `/feedback L3 up` | `codepanel learning <owner/name> L3 up` | `rate_learning` | `POST /api/v1/learnings/feedback` |
| Turn off | `/feedback L3 down <reason>` | `codepanel learning <owner/name> L3 down` | `rate_learning` | `POST /api/v1/learnings/feedback` |

The **Knowledge** tab has **Add learning**, **Confirm** and **Turn off**, and edits or deletes one (an edit counts as your confirmation).

- **Activation.** Only the owner and trusted members count, never a bot. A person's add or up activates a learning at once. Anything through an API token (CLI, MCP, `/api/v1`) counts as an agent, and an agent's learning stays a candidate until a person confirms it or another identity does on another pull request, so the agent that wrote a change cannot loosen its own review. The review lists candidates on its files and what would confirm each.
- **Drafted for you.** Once at least three false-positive verdicts from two or more pull requests share a cause, the orchestrator drafts a learning from their notes, scoped to their common path prefix, active at once. Evidence is a person's `/feedback F3 down false-positive <note>`, or an agent's that the orchestrator conceded after reading the code. Reviews that apply it say it was drafted and name its sources (`PR #12 F3, PR #15 F1, ...`). Drafting runs on the orchestrator's key, at most once every six hours per repository.
- **Applies** to pull requests opened after activation, never the one it came from, at most 10 per review. It is a claim to check, and never lowers a security or critical finding.
- **Hits.** With the `REVIEW_LEARNING_ATTRIBUTION` [review switch](/docs/api#post-repossettings) on (off by default), the orchestrator names the learning behind each finding it drops or demotes. The review says so ("L4 dropped 2 findings"), and each learning in the API, MCP and CLI shows `hits`: how many findings it has decided and the last pull request. A learning whose hits look wrong is turned off the same way.
- **Undo.** Any down turns it off at once; reviews name each learning they applied (`L3`) with that command. Findings a draft came from are never drafted from again.
- **Expiry.** Unconfirmed for 180 days, it stops applying until confirmed again the way it was activated. Two agents' agreement dates from the older of their two ups.

## Verdict memory

Every rating and dismissal on a finding is a verdict. Each review shows the orchestrator the earlier verdicts on the changed files (same file, then same directory, newest first), so it does not repeat a refuted finding and looks harder for defects that proved real here. Detail fades with distance, but no verdict in scope (up to 100) is left out:

- **Whole:** up to the nearest 12, with the finding and the rater's note.
- **One line each:** up to the next 24, shortened.
- **Counted:** the rest, one line per file with their labels; past the space left, the files are counted and named as far as room allows.

Only a whole entry's reason can drop a finding. With the orchestrator's repository tools on, it can open any shorter entry whole, including the ones only counted.

- **Trusted only:** the owner's, or a reply from someone with write access to the repository that is not a bot.
- **Checked, not obeyed:** an agent's rejection drops a finding only if its reason still holds in the code, and no verdict lowers a security or critical finding.
- **Visible:** the review names the verdicts it weighed whole (`PR #87 F3`) and counts the rest. To change one, re-rate that finding.

A down rating with a clear reason (`/feedback F2 down false-positive <why>`) makes the most useful verdict ([Feedback and disputes](/docs/feedback)).

## AGENTS.md and CLAUDE.md

Off by default (in the eval, adding them did not change how many defects a review caught). When on, CodePanel reads both from the repository root:

- **From the base branch**, like `rules.md`.
- **After your review rules**, as one section before notes.
- **As conventions, not instructions.** Each file is fenced under a heading saying these are the repository's instructions to its coding agents. Breaking a convention they state is a finding; a line about how an agent works ("run the tests before committing") is not.
- **Once.** A `CLAUDE.md` that repeats `AGENTS.md`, or only imports it (`@AGENTS.md`), is left out. Imports are not followed.
- **Best effort.** A missing or unreadable file is skipped.

Turn it on with **Read AGENTS.md and CLAUDE.md** in the repository's **Settings → Review rules**, or set `agentFiles` (`false` turns it off):

```text tab="MCP"
update_repo_settings { "repo": "owner/name", "agentFiles": true }
```

```bash tab="CLI"
codepanel repos set owner/name --agent-files on
```

```bash tab="HTTP"
curl -sS -X POST -H "Authorization: Bearer $CODEPANEL_TOKEN" \
  -H "content-type: application/json" \
  -d '{"repo":"owner/name","agentFiles":true}' \
  "$CODEPANEL_URL/api/v1/repos/settings"
```

A repository that never set it follows CodePanel's default, which is off.

## Context budget

Context is built once per round and packed in this order:

1. `.codepanel/rules.md`, under "Repository Review Rules", minus sections scoped to unchanged files.
2. Review rules, account-wide and repository, under "Review Rules" with "The repository owner requires these. A violation is a finding."
3. `AGENTS.md` and `CLAUDE.md`, when on.
4. The repository's notes.

The cap is 16,000 characters. A section that fits is kept whole; one that does not is trimmed at a line and marked "section trimmed for length" if at least 800 characters remain, else left out. A closing line, "Left out for length: ...", names what was dropped. Learnings and verdict memory are outside this budget.

## Cost and privacy

Context is part of every reviewer and orchestrator call, so it adds up to 16,000 characters to each ([Models and cost](/docs/choosing-models)). It goes to the AI providers on your panel, like the code ([Security and data](/docs/security)).

## Read and rewrite from an agent

A repository's rules and notes are one Markdown document, its knowledge:

| Section | Contents | Editable |
| --- | --- | --- |
| `## Rules` | One `###` heading per rule; a heading ending in `(disabled)` is kept but not sent | Yes |
| `## Notes` | One `###` heading per note: `conventions`, `patterns`, `architecture` or `custom_rules` | Yes |
| Account rules, verdicts, learnings | Read-only context | No |

Read it, let an agent shorten, merge or correct it, and send the whole document back. Rules and notes become what those two sections contain: anything left out is removed, and an unchanged note keeps its row. Reading needs `read`; replacing needs `repos:write`.

```text tab="MCP"
get_knowledge      { "repo": "owner/name" }
replace_knowledge  { "repo": "owner/name", "markdown": "<the edited document>" }
```

```bash tab="CLI"
codepanel knowledge owner/name > knowledge.md
codepanel knowledge set owner/name knowledge.md      # or - for stdin
```

```bash tab="HTTP"
curl -sS -H "Authorization: Bearer $CODEPANEL_TOKEN" \
  "$CODEPANEL_URL/api/v1/knowledge?repo=owner/name"

curl -sS -X POST -H "Authorization: Bearer $CODEPANEL_TOKEN" \
  -H "content-type: application/json" \
  -d '{"repo":"owner/name","markdown":"..."}' \
  "$CODEPANEL_URL/api/v1/knowledge"
```

A document that does not parse, or was read before the knowledge last changed, is refused with the reason and changes nothing: read it again and redo the edit. The **Knowledge** tab shows the same document with **Copy as Markdown** and **Replace from Markdown**. `.codepanel/rules.md` is not part of it.
