Mon 2026.10.26
farol: checking the risk of a pull request before the merge
Today's pick: farol
farol is a product that uses static analysis to find which pages and endpoints use the code a pull request changes. It shows a merge risk score and the files to read first.
It is today’s pick because it lets the person who approves the merge notice a change that affects many pages, even after an AI review.

- Found on
- Show HN
- Built with
- TypeScript, Python, Go
The problem
Even when an AI agent writes a pull request and an AI reviewer checks it, a person still approves the merge. Erich Oliveira, the maker of farol, says in the README that a person who spends the same time on every pull request ends up skimming. He says they then miss a one-line change to shared code, and that change breaks forty pages. In the README he compares farol with AI review agents in general. This entry uses GitHub’s Copilot code review as the example of an AI review.
According to GitHub’s docs for Copilot code review, Copilot finds issues in a pull request and suggests fixes. After the review, Copilot leaves an overview comment that says whether Copilot judged the pull request ready to approve. In the same docs, GitHub says Copilot is not guaranteed to spot all problems and recommends a human review as well.
How it solves it
farol was posted as a Show HNA post on Hacker News, a developer community, in which someone presents what they made. Its title starts with "Show HN:". on Hacker News on October 25, 2026. It runs after the AI review. It shows the person who approves the merge how risky the pull request is and which files to read first. It reads the code on both the base branch and the pull request branch. Then it finds which pages and endpoints call the changed functions.
A pull request that only adds new code gets the label isolated. One that changes existing code gets touches-existing. One that affects the whole project gets global. If farol cannot read part of the code, it classifies the change as unknown. It also computes a merge risk score from 0 to 100 and picks a review level: fast track, quick review or careful review. The results go into a pull request comment and an HTML report. farol never blocks or approves a merge.
What is different
The first difference is what the judgment rests on. According to GitHub’s docs, Copilot code review uses a mix of models and prompts. farol uses static analysisFinding the structure and errors of a program by reading its source code, without running it. instead of an LLMA large language model. It is an AI model trained on large amounts of text to understand and generate text.. It reads TypeScript and Go with their type checkers, and Python with the ASTAbstract syntax tree: a tree that shows the structure of source code. Compilers and analysis tools build it to read code. parser in the standard library. So its results are deterministicAlways giving the same result for the same input. LLM output, in contrast, can differ from run to run.. Each finding also shows the call chain from the changed file to the endpoint. The tradeoff is that it cannot read values that are known only when the code runs, such as a route path computed by a function.
The second difference is what each tool tells you. Unlike Copilot, farol does not look for bugs in the code. It shows how far the change reaches, which files to read first and which endpoints to test by hand. When the type of an endpoint parameter changes, it marks a breaking changeA change to an API that can make clients built for the old version fail.. The maker’s README recommends running an AI review first and farol after it.
The third difference is cost. According to GitHub’s docs, one Copilot review uses about $0.05–$5 of AI credits. farol is a free CLI under the MIT license, and it runs locally or in CIContinuous integration: a setup that builds and tests code automatically every time it is pushed.. But it cannot apply a fix in a few clicks the way Copilot can.
How it was built
- The public commit history starts on October 21, 2026, with a first commit named "farol 0.1.0". That commit adds 504 files, so the development before the release is not visible in the repository. There are 9 commits up to October 24.
- All 9 commits have a Co-authored-by trailer for Claude.
- The src directory has 13,300 lines of TypeScript. The test directory has 333 files.
- In an HN comment, the maker said he built farol at a company called Winnin, which open-sourced it. A commenter said the UI design looked like it was made by AI. The maker replied that he did make it with AI and that he lacks design skills.
Running it
I wrote a FastAPI service with 5 Python files. For each step below, I made a branch and analyzed it against the base branch.
- Installation and setup. Installing farol 0.1.3 from npm added only the farol package. In
farol.config.jsonI set the language and the kind of project. - A change to existing code. I added a filter to the list function
fetch_items. I also changed the type ofitem_idinGET /items/{item_id}from int to str. The verdict was careful review, with a merge risk score of 75/100.db.pyholdsfetch_items, and 2 of the 3 endpoints use it. farol rated this file high risk, on a scale of high, medium and low. The type change ofitem_idwas marked as a breaking change. - A computed path. The README says farol classifies the change as unknown when it cannot read an entry point. When paths overlap, FastAPI sends the request to the route registered first. So I added a route before the existing
GET /reports/summary. Its path comes from the function callpath("summary"). farol read it as a new endpoint,GET /reports{path('summary')}, and classified the change as isolated. It gave a fast track verdict and a score of 2/100. The list of unreadable routes in the diagnostics was empty. I sentGET /reports/summarywith FastAPI’s test client, and the new route answered instead of the old one. - A computed prefix. I changed the router’s prefix from a string to a function that returns the same prefix. farol read this as if an existing endpoint was removed and a new one was added. It classified the change as touches-existing. The verdict was careful review, with a score of 42/100. The paths did not change, so this verdict was too strict. But unlike in step 3, it did not understate the risk.
- Speed. With the network blocked, I ran the analysis five times. The median wall-clock time was 0.55 seconds.
Two other claims from the README held up: the same pull request gets the same answer, and the analysis never runs the analyzed code. Two runs of the same analysis differed only in the analysis time and the step timings. I made the first line of db.py create a file on import. The file did not appear after the analysis.
"detail": "new entry point GET /reports{path('summary')} (registered in app/reports.py)"
- **Merge risk score:** 2/100 (low; higher is riskier)
{'count': 0}


Not checked
- Speed on a large repository. According to the README, a 300-file Python service takes about 3 seconds. Measure it on a real service repository.
- TypeScript and Go projects. Analyze a Next.js branch that changes a shared component, and check the list of pages it reaches.
- Pull request comments.
farol commentneeds GITHUB_TOKEN. Push a new commit to a pull request in a test repository, and check that farol edits the comment it left before.
Verdict
It works. Without running the code, it found the high-risk files and a changed parameter type. But it could not read a route path computed by a function. That route changed an existing response, and farol still gave fast track. It is worth trying if you approve pull requests after an AI review and your service sets its route paths as plain strings. In a repository that builds many route paths with functions, a change to an existing response can still get fast track, the lightest review level, as it did today. This product is not a good fit there.
Getting started
npm install @winninjs/farol@0.1.3node_modules/.bin/farol analyze --base main --head feature --out farol.json && node_modules/.bin/farol html --in farol.json --out farol.html
- You need
- Node.js 22 or later, and git · python3 3.11 or later for Python projects, go for Go projects · A farol.config.json at the repository root. For a Python service, use { "language": "python", "surface": "backend" }
- Cost
- Free under the MIT license. According to the README, there is no account, hosted service or paid tier.
If you do not give a coverage report, farol computes the merge risk score as if no changed line were tested.
Steps select 1 ran.
Progress
- Day 3Upcoming
- Day 7Upcoming
- Day 15Upcoming
- Day 30Upcoming
- Day 90Upcoming
- Day 180Upcoming
- Day 365Upcoming