# Local code review without letting the diff leave the machine

> A provider-agnostic Go CLI that has a model review my diff without the diff leaving the machine; it became CommitBrief.

- What it does today: Reviews code locally, with the diff never leaving the machine; the `Provider` interface lets Anthropic, OpenAI, Gemini and Ollama plug into one contract. Signed binaries are published — anyone who does not want to hand their diff to a cloud provider can install it.
- Form: Open source
- State: Became a product
- Focus: AI-assisted development
- Started: 2026-01-01
- Left Labs: 2026-04-07
- Technologies: Go, Cobra, go-git, Anthropic Claude, OpenAI, Google Gemini, Ollama
- Tags: #ai, #cli, #code-review
- Source code: https://github.com/CommitBrief/commitbrief
- Website: https://commitbrief.com
- This one became a product: CommitBrief (https://www.muhammetsafak.com.tr/en/portfolio/commitbrief/)
- Source: https://www.muhammetsafak.com.tr/en/labs/commitbrief-lab/
- Language: en-US
- Author: Muhammet Şafak

---
You do not have to let the diff leave the machine to have a model read it. The
one outbound call goes to the provider you picked — and the real work is in
making that provider pluggable.

## A review that never leaves the terminal

The problem was this: before a code change goes to another person (or to my
future self), it should be possible to get a structured "second pair of eyes"
review without leaving the terminal. The diff should not leave the machine, and
neither should the review.

## What fits in one command

The scope fit into a single command: staged diff, one commit, the working tree,
or a PR-style three-dot range. Project rules can be customised through
`COMMITBRIEF.md`, and the output can be produced as a coloured terminal card,
as markdown or as a strict JSON schema.

## Making the provider pluggable

The shortest-lived part of an LLM tool is the provider it talks to. Two
decisions came out of that assumption.

**`Provider` is a registry in the `database/sql` style.** Calling the provider
directly would have been the shortest path; you pay for that path with the
second provider. With a registry, adding a new provider means one package and
one blank import. Anthropic, OpenAI, Gemini and Ollama are API-based;
`claude-cli` and `gemini-cli` are subprocess-based providers that reuse the
user's existing subscription — all of them implement the same interface.

**Git is not read through one path.** `go-git` is pure Go and needs no
installation; it covers every commit-based operation, plus `status` and `diff`.
Its coverage ends at the edges of the working tree: `add` is supported only in
its plain form, and multiple worktrees and index v1/v3 are not supported at all.
The pure solution would have been to never fall back to the binary, and then
every one of those edges would have been a blind spot for the tool. A hybrid
path was chosen: `go-git` first, the `git` binary beyond its coverage, both
behind the same `Repo` interface.

## Not paying twice for the same diff

The third decision is about cost. An LLM call is billed, and a developer has
the same diff reviewed several times a day — before the commit, after the fix,
when opening the PR.

If the cache key were the diff alone, the cache would return the wrong answer: the
same diff under a different provider, model or language is a different review.
So the key has five parts — diff, system prompt, provider, model and language —
hashed with SHA256. When the same five arrive again, the call drops to a single
disk read, and each call reports what it saved on a `Saved: $X` line.

The same discipline applies to what gets sent: a three-layer filter narrows
what reaches the model — built-in defaults, `.commitbriefignore` and the
semantic filter in `COMMITBRIEF.md`. "The diff never leaves the machine" meant
this; what does leave is also something you choose.

## The road to signed binaries

The Labs stage is closed: CommitBrief is now a product with its own domain,
signed binaries and a release contract. Details in the portfolio.
