Two engines, and a conversation around what they find. Deep is the default — it’s the one that actually reads your code. Smoke is the fast glance you reach for when a full read would be overkill.

It submits a real review

Codaban doesn’t leave a pile of comments and let you work out what it thought. It submits an actual review on the pull request, with the same three outcomes any of your teammates has: Approve  Request changes  Comment It appears in the PR’s review list next to the humans, attributed to the bot account — codaban[bot] on GitHub, your bot user on Forgejo. There is no silent pass. A clean run still gets a written verdict saying so, rather than a green tick you have to interpret.

Making it blocking

By default a review is advice, and your existing branch protection decides what it’s worth. On GitHub you can make it a gate. Codaban writes a codaban/review commit status on every run — “Review in progress”, then complete. Mark that check required in the branch’s protection rules and the PR cannot merge until Codaban has reviewed it and is satisfied. Settings → Branches → Branch protection rules → Require status checks to pass before merging, then select codaban/review.
The check has to have run on the repository at least once before GitHub will offer it in that list. Open one pull request, let Codaban review it, then add the rule.
Do this deliberately. It puts a reviewer that can be wrong on your critical path, and a repository where nobody can merge until the bot agrees is a repository that will teach people to click bypass.
Make me a required check if you mean it. Don’t make me one you’ll spend every Friday overriding.
A pull request sidebar listing four reviewers: codaban with a changes-requested marker, off-by-one approved, sudo-hazel awaiting review, and rubber-duck-ray commented.

Codaban in the reviewer list, with the same outcomes as everyone else.

Smoke review

The quick one. It reads the diff and nothing else — it never opens the rest of the repository, so it can’t tell you whether your change breaks something three files away. Use it for typos, obvious mistakes, and a sanity check before you ask for the real thing. It is not a real review, and it isn’t pretending to be one. Mechanically: it fetches the diff, annotates it with line markers, and asks the senior model tier for findings. Those findings are then self-critiqued by the junior tier — stylistic and speculative ones get retracted before anything is posted. The result is one PR review carrying:
  • a verdict,
  • a summary,
  • inline comments anchored to the changed lines, each with an optional suggestion and a copy-pasteable “Prompt for AI” block. When the fix is a clean drop-in for the commented line, the suggestion renders as a one-click committable block on both GitHub and Forgejo — review the diff it shows, then commit it without leaving the PR.

Reading a finding

Every inline finding leads with a header you can triage without reading the prose — category · severity · effort, for example 🎯 Correctness | 🔴 Critical | ⚡ Quick win:
A single inline finding annotated with four numbered callouts: the file and line, the category Security, the severity Major, and the effort Quick win.

One finding, with its four header segments called out.

  • Category — Correctness, Security, Performance, Maintainability, Reliability, Style, Testing, or Docs.
  • Severity — 🔴 Critical, 🟠 Major, or 🟡 Minor.
  • Effort — ⚡ Quick win (small, bounded fix), 👍 Worth it (real but clear work), or 🔹 Nitpick (optional polish).
🔍 Unverified appears when Codaban could not confirm the finding from the code alone. It can read the repository but never run it, so runtime output, external specs, and “does this test pass” are out of reach.Treat it as a question worth checking, not a verdict — the finding usually names the command that would settle it. These never rank above 🟠 Major, never request changes on their own, and a later review may repeat one but won’t build a new finding on top of it until it’s confirmed. A confirmed problem alongside one still blocks.

Re-reviews

When Codaban has reviewed the PR before, a new run becomes a three-phase pipeline instead of a naive second pass:
1

Resolution check

The diff since the last review is compared against the previous findings, and fixed ones are marked resolved.
2

Fresh review

The full diff is reviewed clean-slate.
3

Self-critique and dedup

New findings are challenged, and anything already reported — or explained by you in a thread reply — is filtered out.
So pushing fixes and asking again converges. It doesn’t repeat itself at you.

Deep review

The real review, and what runs by default. Codaban checks out the PR branch and runs a coding agent in read-only mode against the working tree. It reads source beyond the diff, follows references, and verifies findings against actual code — which is what lets it catch the thing your change broke somewhere else. It can also resolve or retract its previous findings: it reacts on the thread (🎉 resolved, 👀 retracted), and on GitHub also edits the finding’s comment to mark it ✅ Addressed in commit <sha>. Its status comment carries a collapsed per-file Walkthrough table and a Review effort estimate alongside the verdict. Deep review defaults to the middle model tier. Label the PR senior to escalate — see Labels.
A deep review status comment with an expanded Walkthrough table listing five files, what was checked in each, and a per-file verdict — including one file read for context that was not part of the diff.

A deep review's status comment, Walkthrough expanded.

Per-repo tuning. The deep-review agent reads CLAUDE.md and CODABAN.md from the reviewed repository’s root, if present. CODABAN.md is the review-specific one — what to focus on, what to ignore, tone. See Configuring with CODABAN.md.

How the verdict is decided

Severity-aware. A new error or warning finding requests changes — that is the floor. When nothing blocks, the model renders its own verdict, and a kept nitpick stays non-blocking. Without an explicit verdict the count-based rule applies: anything new, or any kept thread, requests changes. Otherwise it approves. A clean pass approves either way. One finding can opt out of the floor. A real issue the reviewer agrees to let ship — a tracked follow-up, or a constraint you named and it accepted — is marked accepted and posts at its real severity without gating the merge. So a review whose prose says it’s allowing the PR now actually approves it, instead of blocking over its own tracked notes. Anything it genuinely wants fixed still requests changes.

PR description upkeep

Every review run — smoke or deep — also refreshes the PR description. A generated Summary section is appended under a 🐗 Auto-generated by Codaban marker. Your own text is preserved verbatim, and re-runs replace the generated section instead of stacking copies.

Triggers by forge

Auto-review is on by default, in deep mode, so a new pull request gets a real review without anyone asking. Change the mode per repo, or turn it off per workspace, in Settings → Auto-review. @codaban stop review disables it for a single PR.

Talking to Codaban about findings

Reply to any inline finding and Codaban answers in the same thread — explaining the reasoning, taking your point, or holding its ground. If your reply convinces it, or you explain why the code is deliberate, the finding counts as resolved in the next re-review’s dedup phase.
A review thread where a developer explains the expiry check already lives in middleware, and Codaban withdraws the finding while noting one worker that bypasses that middleware.

Pushback, and a withdrawn finding.

Tell me why I’m wrong. If you’re right I’ll drop it — and I won’t bring it up again next review.