← liffy
Liffy — How It Works

Architecture, explained without the jargon

Liffy

AI-powered peer code review

Liffy reads a programmer's proposed change to a piece of software and writes back the kind of feedback a senior engineer would give — except it has already read the entire project, and it never runs out of time.

Built by Nafees S & S Gaja Lakshmi

Report v2.0

Status All fifteen steps running

The situation

Before new code joins a project, another programmer is supposed to read it and catch the mistakes. This is called code review. It is the single best moment to catch a bug — and the one everybody is too busy to do properly.

The gap

Automated checkers already exist, but they only catch spelling-level problems. They cannot tell you "this contradicts how the rest of your project works." For that you need something that has read the whole project.

What Liffy does

It reads the entire codebase once and remembers it. Then, every time someone proposes a change, it pulls up the parts of the project that are relevant, reads the change against them, and writes specific, line-by-line feedback.

Why it is not just "ask an AI"

An AI asked cold gives generic advice. Liffy hands the AI the surrounding code first. That is the whole product — and it is the difference between "consider adding error handling" and "this breaks the pattern in line 40."

PLATE 01 The cast — who does what

Six parts, each with one job

Liffy is not one program. It is six pieces that hand work to each other, and none of them knows how the others are built internally — they only know what to pass along. That is deliberate: any one piece can be swapped out without touching the rest.

A

The front desk

FastAPI · Nginx

Every request from a browser or from GitHub arrives here first. It checks who is asking, then passes the work to whoever handles it.

B

The doorman

GitHub OAuth 2.0 · JWT

Nobody creates a Liffy password. You sign in with the GitHub account you already have, and Liffy is handed a permission slip for exactly the repositories you approve.

C

The receiving dock

Webhook · Diff parser

GitHub knocks here the instant someone proposes a change. This piece verifies the knock is genuinely from GitHub, then breaks the change into readable pieces.

D

The librarian

Tree-sitter · ChromaDB

Reads the whole codebase and files every function away by meaning, so it can later be asked "show me the code most similar to this" and answer in milliseconds.

E

The reviewer

LangChain · Claude Opus 5

Gets the change plus the relevant surrounding code, and writes the actual review. It is required to answer in a strict format so nothing downstream has to guess.

F

The examiner

Scoring engine · Feedback store

Collects the thumbs-up and thumbs-down a developer gives each comment, and turns them into a score for how good Liffy's reviews actually are.

Supporting cast

Three more pieces do the unglamorous work: PostgreSQL is the filing cabinet where every review is permanently stored; Redis is the ticket queue holding jobs waiting to be done; Celery is the back-room worker that picks tickets off that queue. They exist because a review takes up to a minute, and nobody should stare at a spinner while it happens.

Act I
PLATE 02 Signing in

Where it starts

Liffy never sees your password

A code review tool has to be trusted with private source code, so the sign-in has to be beyond question. Liffy sidesteps the problem entirely: it has no accounts and no passwords of its own. GitHub vouches for you.

You click
"Sign in"
Browser
GitHub asks
your permission
GitHub
Liffy swaps
the receipt
Doorman
You are
signed in
Dashboard
1

You click "Sign in with GitHub"

Doorman

Liffy sends your browser to GitHub, attaching a one-time random string it also stores in a cookie.

That random string is an anti-forgery measure. If the reply that comes back doesn't carry the same string, Liffy knows the reply was manufactured by somebody else and throws it away.

2

GitHub asks you to approve

GitHub

GitHub shows its own consent screen listing what Liffy is asking for: permission to read your repositories, and your username.

This screen is GitHub's, not Liffy's. Your password is typed into GitHub and never travels anywhere near Liffy.

3

Liffy trades the receipt for a key

Doorman

GitHub sends your browser back to Liffy carrying a short-lived code. Liffy exchanges that code, server to server, for an access key tied to your account.

4

Liffy issues you two passes

Doorman

A short-lived day pass that expires after fifteen minutes, and a long-lived membership card good for thirty days that can be traded for a fresh day pass at any time.

Two passes instead of one because of what happens if a pass leaks. A stolen day pass is worthless in fifteen minutes. The membership card is stored in Liffy's own database, so if it is ever stolen it can be cancelled immediately — and it is replaced with a new one every single time it is used, so a copied card stops working the moment the real owner uses theirs.

Act II
PLATE 03 Reading the codebase — "indexing"

The part that makes Liffy different

Studying the whole book before the exam

When you connect a repository, Liffy sits down and reads every file in it. This happens once, in the background, and takes a few minutes. Everything Liffy ever says afterwards is grounded in what it learned here.

Source files01 · fetch
Grammar tree02 · parse
One chunk
per function
03 · split
384 numbers
per chunk
04 · embed
Searchable
library
05 · store
1

Download every file worth reading

Librarian

Liffy walks the repository through GitHub's API, skipping images, compiled binaries and anything over 200 KB — those are almost always machine-generated bundles, not code a human wrote.

2

Parse each file into a grammar tree

Tree-sitter

A parser called Tree-sitter reads the file the way a linguist diagrams a sentence — identifying which lines form a function, which form a class, where each one begins and ends.

This is the same technology code editors use to colour your code. Liffy uses it to find the natural seams in a file.

3

Cut along the seams, never through them

Librarian

The file is split into chunks — one complete function or class each. A file in a language Liffy has no grammar for still gets chunked, just by fixed line windows instead.

This is the decision the whole system rests on. Chopping code every 50 lines regardless of content would cut functions in half, and half a function means nothing to anybody. Cutting at the seams means every chunk is a complete thought.

4

Turn each chunk into coordinates

Embedding model

Every chunk is passed through a model that converts it into a list of 384 numbers. Chunks that do similar things end up with similar numbers.

Think of it as giving every function a position on a map, where distance means "how alike are these two pieces of code." Two functions that both validate an email address land near each other even if they share not one word. This model runs on Liffy's own machine — nothing is sent anywhere to do it.

5

File them in the library

ChromaDB

The coordinates go into ChromaDB, a database built for exactly one question: given this position, what are the nearest neighbours? Every repository gets its own private shelf.

Separate shelves per repository, deliberately. Letting one project's code turn up while reviewing another's would produce confident, irrelevant advice — and would be impossible to debug.

6

Remember a fingerprint of each chunk

PostgreSQL

Liffy records a fingerprint of every chunk's contents. Next time it re-reads the repository, anything whose fingerprint is unchanged is skipped.

So the first read is slow and every read after it is nearly instant — only what actually changed gets re-read.

Act III
PLATE 04 Reviewing a change — the main event

Thirteen steps, about a minute, nobody watching

A developer proposes a change

On GitHub, a proposed change is called a pull request — "please pull my work into the main project." Everything below happens automatically, in the seconds after that button is pressed.

01–03GitHub knocks, Liffy checks the knock is real
04–06Fetch the change, cut it up, take a ticket
07–08Look up the most similar code in the library
09–10Brief the AI and let it write the review
11–12Check the answer, pin it to line numbers, file it
13The review appears on the dashboard
01

Someone opens a pull request

GitHub

A developer finishes a piece of work and asks for it to be merged into the project.

02

GitHub knocks on Liffy's door

Receiving dock

GitHub immediately sends a message to a dedicated address on Liffy's server. This is called a webhook — GitHub pushing news out, rather than Liffy repeatedly asking "anything new?"

03

Liffy verifies the knock is really GitHub

Receiving dock

The address is public, so anyone could send it a fake message. GitHub signs every message with a shared secret; Liffy recomputes that signature and compares. Anything that doesn't match is discarded unread.

Like a wax seal. Only someone who holds the same stamp can produce a matching impression — and the comparison is done in a way that gives an attacker no clue how close a guess was.

04

Fetch the change itself

Receiving dock

The knock carries only headline details, so Liffy calls GitHub back for the full diff — the exact list of lines added and removed.

05

Break the diff into per-file pieces

Diff parser

The raw diff is one long block of text. Liffy parses it into structured pieces — which file, which lines, added or removed — keeping a map back to the real line numbers.

That map matters at step 11. A comment is only useful if it lands on the right line of the right file.

06

Take a ticket and let GitHub go

Redis · Celery

The job is put on a queue and Liffy answers GitHub instantly. A separate background worker picks the ticket up and does the slow part.

Reviews take tens of seconds. If Liffy held the line until it was finished, GitHub would give up waiting and the review would be lost. The queue also means a crash costs nothing: the ticket is still there when the worker restarts.

07

Convert the changed code into coordinates

Embedding model

Each changed piece goes through the same model used during indexing, producing a position on the same map.

08

Ask the library for the nearest neighbours

ChromaDB

For each changed piece, Liffy pulls the five most similar pieces of existing code from that repository's shelf.

This is the retrieval step — the "R" in RAG, and the reason Liffy can say "you've written this before, over here" instead of guessing.

09

Write the briefing

LangChain

Liffy assembles one document for the AI: who it is meant to be (a senior engineer), exactly what shape its answer must take, the change under review, and the retrieved surrounding code.

The order is fixed on purpose — the unchanging part goes first so it can be cached between reviews, which cuts both cost and waiting time.

10

The AI writes the review

Claude Opus 5

The model returns an overall summary, a verdict, and a list of comments — each pinned to a file and line, tagged with a category and a severity.

Liffy is not tied to one AI. The same slot accepts Claude, OpenAI, or a model running on your own laptop for free — the rest of the system doesn't change.

11

Check the answer, then pin it to real lines

Pydantic

The reply is validated field by field against a strict schema. Anything malformed is rejected and the model is asked again. Then each comment's line numbers are translated from diff coordinates back to real file line numbers.

An AI can produce beautifully-worded nonsense. This step makes structural nonsense literally unable to enter the database.

12

File it permanently

PostgreSQL

Review and comments are written to the database, along with which model was used, how many tokens it consumed and how long it took — the raw material for measuring quality later.

13

It appears on screen

React · Monaco

The dashboard has been checking for updates the whole time. The finished review renders over the code diff in the same editor component that powers VS Code, each comment attached to the line it is about.

The clock

Liffy's target is under 90 seconds from GitHub's knock to a finished review. Measuring that honestly is harder than it sounds: the knock arrives at one program and the review finishes in a different one, so the time spent waiting in the queue sits between them and is easy to accidentally leave out. Liffy now stamps the arrival time onto the ticket itself so the full wait is counted, not just the working time.

PLATE 05 The core idea, in one comparison

Steps 08 and 09, and why they exist

The same AI, briefed two different ways

Every AI code review tool sends the change to a model. The question is what else it sends. On the left, nothing. On the right, the five most relevant pieces of the project's existing code. Same model, same change.

Without retrieval generic

"Consider adding error handling to this function, and make sure the variable names are descriptive."

True of almost any code ever written. Nothing here required reading this project, so nothing here tells the developer something they did not already know.

With retrieval grounded

"The macOS script replaces the whole line here; this one replaces only the prefix, so the generated secret gets written in front of the placeholder instead of over it."

Only possible because the other script was retrieved and put in front of the model. This is a real comment Liffy wrote — and the bug was real. See Plate 06.

Where the name comes from

RAG — retrieval-augmented generation. Retrieve the relevant material first, then generate the answer with it in hand. It is the difference between an open-book exam and a closed-book one, and it is why Liffy is a system rather than a wrapper around somebody else's model.

PLATE 06 Evidence — a real review, on this project

Pull request #58 · lucenity0/Liffy

Liffy reviewing its own codebase

The change added one-command setup scripts for macOS and Windows. Liffy read it with no human help and returned eight comments. Every one was then checked by hand.

Verdict request changes
Comments 8
Model claude-opus-5
Tokens read 25,043
Time taken 2m 07s

Note the clock: two minutes, against a target of ninety seconds. That gap is the honest reason the timing measurement described in Plate 04 exists — a target nobody measures properly is a target nobody misses. Liffy now records both numbers on every review, the working time and the full wait, and reports the median of each.

The one that mattered

Liffy rated this critical — its highest severity. It was correct, and the bug was already sitting in the project's main branch where nobody had noticed it.

critical logic error setup-windows.bat · line 125

"This replaces the substring JWT_SECRET_KEY= with JWT_SECRET_KEY=<hex>, which prepends the generated secret to whatever placeholder value is already there. The macOS script correctly replaces the whole line. Rewrite the line, not the key prefix."

In plain terms: the Windows setup script was supposed to write a freshly generated security key into a settings file. Instead of replacing the placeholder text, it wrote the new key in front of it — producing a key with the word changeme stuck on the end. Every Windows user would have got a silently broken installation. Liffy caught it by comparing the Windows script against the macOS one, which does it correctly.

Scored honestly

All eight comments were verified by hand. This is the real result, not a highlight reel.

Verified correct 3
Plausible, unchecked 4
Verified wrong 1

What kinds of problem it found

Logic errors 5
Improvements 2
Conventions 1

Liffy sorts every comment into one of six categories — logic error, security, performance, architecture, convention, improvement. Tracking that spread is how the team will notice if it starts obsessing over one kind of problem and going blind to the others.

Act IV
PLATE 07 Learning from the humans

Steps 14 and 15 — the loop that closes

A review nobody scores cannot improve

Everything up to here produces a review. This last act is what stops the quality being a matter of opinion. Without it, there would be no way to answer the only question that matters: is Liffy actually any good?

Developer rates
each comment
Dashboard
Stored against
the comment
Database
Weekly job
scores reviews
Celery beat
Bad reviews
flagged
Examiner
Briefing
rewritten
Humans
14

The developer votes on every comment

Dashboard

Each comment carries a thumbs up and a thumbs down. One click, stored immediately against that specific comment and that specific person.

Deliberately the smallest possible ask. A feedback form nobody fills in produces no data, and no data means no way to improve.

15

A weekly job turns votes into scores

Examiner

Once a week, a scheduled task walks every completed review and computes its approval rate. Reviews scoring below 50% are flagged for a human to read.

16

The patterns rewrite the briefing

Humans

The flagged reviews get read. If the same kind of wrong comment keeps appearing, the instructions given to the AI at step 09 are rewritten to prevent it — and the next week's scores show whether that worked.

This is the loop that closes. Liffy does not learn on its own; it produces the evidence its builders need in order to improve it deliberately.

The five things measured

How often developers agree with a commentUser approval rate
target > 70%
How often Liffy raises a non-issueFalse positive rate · the complement of the above
not the operative target
Whether "critical" really means criticalSeverity calibration
monthly audit
Whether it is over-focused on one kind of problemCategory distribution
even spread
How much value per unit of AI costToken efficiency
tracked as trend

A contradiction found in our own specification — and settled

The first two targets cannot both be met as written. If a developer's only options are thumbs up and thumbs down, then "comments marked as not an issue" is exactly "comments not given a thumbs up" — so the second number is always 100% minus the first. Asking for above 70% and below 20% asks for 70 + 80 = 150%. It was caught while writing the code, and written down rather than quietly implemented wrong.

The resolution: both numbers are still stored, because they are the two columns the schema promises, but approval rate is the operative target and false-positive rate is recorded as its arithmetic complement, not as a second opinion. Telling the two genuinely apart needs a third answer in the vote — "wrong" as distinct from "not useful" — which is a schema change worth making when there is enough feedback for the finer number to mean anything.

PLATE 08 Where everything is kept

Eight drawers in the filing cabinet

Nothing in Liffy is held in memory and hoped for. Every drawer below is a real table in the database, and each one links to the next so a single comment can always be traced back to the person, project and change it came from.

01

People

users

Everyone who has signed in through GitHub.

02

Projects

repositories

Which repositories are connected, who connected them, and when each was last read.

03

Proposed changes

pull_requests

Every pull request Liffy has been asked to look at.

04

Reviews

reviews

One per attempt: the summary, the verdict, which AI wrote it, what it cost, how long it took.

05

Comments

review_comments

The individual remarks — file, line, category, severity, the text, and any suggested fix.

06

Votes

comment_feedback

Who gave which comment a thumbs up or down.

07

Reading log

repo_embeddings

The chunk fingerprints, so re-reading a project only touches what changed.

08

Scores

eval_scores

The weekly quality result for each review.

PLATE 09 What is built, and what is not

All fifteen steps run today

Steps 1 to 13 — sign in, connect a project, read it, receive a pull request, retrieve context, write the review, display it — all work end to end against real repositories and a real AI. So do steps 14 and 15: comments are rated, a weekly job turns those ratings into scores, and an analytics page shows them.

Sign in with GitHub, with rotating passesAct I · steps 1–4
done
Read and index a whole repositoryAct II · Python and TypeScript parsed semantically
done
Receive and verify GitHub webhooksAct III · steps 02–03
done
Retrieve context and generate a real reviewAct III · steps 07–12
done
Dashboard with inline comments on the diffAct III · step 13
done
Thumbs up / down on every commentAct IV · step 14
done
Weekly scoring job and an analytics pageAct IV · step 15
done
Posting the review back onto the GitHub pull requestDeliberately last — see below
done
Settings, model providers and themes inside the appNo .env editing, and a subscription plan works as a provider
done
Teams, organisation accounts, anything outside a GitHub pull requestNot built — and not planned
not built

Why posting to GitHub was left until last

Liffy could have posted its comments straight onto the pull request from day one. It deliberately did not. An automated reviewer that starts commenting on people's work before anyone has established whether it is any good is just noise — and noise gets muted permanently. The dashboard came first so the quality could be judged privately. Only once a real review had been checked comment by comment did posting go in — and it ships switched off. Turn it on and it still only leaves a comment; approving a pull request or formally blocking a merge is a second, separate opt-in. An automated reviewer that can hold up a human's work uninvited is the kind of tool people mute permanently.

1,347Automated tests
274Commits
68Pull requests merged
2People

Every one of those 1,347 tests runs automatically before any change is allowed into the project. Nothing merges red.