Say a PR changes one line in formatCurrency. The diff is tiny, but the function is called by the checkout API, the cart page and a nightly report job. A reviewer reading only the diff cannot see that. Farol aims at exactly this gap: after an AI code review, show how far the changed code reaches.

This is based on the official repository README. The GitHub API shows the repo was created on 2026-10-21, and the README's release list is empty. The October 25 Hacker News attention was only the discovery path; everything below is what the README claims. I did not run Farol. Only a toy model I wrote to illustrate the idea was executed.

What it says it computes

According to the README, Farol is a CLI and GitHub Action that analyses statically and never executes the repository's code. It produces a PR comment and a single-file HTML report, and does not block merges.

Section README description What it gives a reviewer
Must check Breaking API contract changes, security findings, lint errors, vulnerable dependencies Things to resolve before reading
Can affect Existing pages or jobs that run the changed code, with the call chain Impact outside the diff
Diff coverage Share of changed executable lines that tests ran Repo-wide coverage can be high while this change is untested
Files by risk High/Medium/Skim/test tiers, with lines no test ran A reading order

Supported scope per the README: TypeScript (React Router, Next.js, file-based TanStack Router, GraphQL, REST, CLI), Go (chi, gin, echo, net/http, gRPC) and Python (FastAPI, Flask, Django URLs, MCP, Celery, Temporal, Prefect). It needs Node.js 22+ and git, plus Go or Python for those projects. You can run it without installing: npx @winninjs/farol analyze --base origin/main --head HEAD --out farol.json.

Why "reaches more, never less" matters

The key sentence in the README's limitations: when a call cannot be resolved, Farol assumes it reaches more, not less. It also states that runtime-built values (getattr, importlib, DI containers, computed routes) are invisible.

For a review tool this is a sound bias: a false alarm is cheaper than a missed impact. The cost is that in codebases full of unresolvable calls, warnings spread and the signal dilutes. The following is my own teaching model, not Farol's code. It runs on Node.js 18+ with no install.

const calls = {
  "route:POST /checkout": ["checkout"],
  "route:GET /cart": ["cartTotal"],
  "job:nightly-report": ["cartTotal", "formatCurrency"],
  checkout: ["cartTotal", "chargeCard"],
  cartTotal: ["applyDiscount"],
  applyDiscount: ["formatCurrency"],
  chargeCard: [], formatCurrency: [],
  "route:GET /plugin/:name": ["loadPlugin"],
  loadPlugin: ["UNRESOLVED"],
};
// Walk from the changed node toward callers and collect route/job entry points.

Output of the full script (reach_demo.mjs):

changed formatCurrency -> [ 'route:POST /checkout', 'route:GET /cart', 'job:nightly-report' ]
changed chargeCard     -> [ 'route:POST /checkout' ]
changed applyDiscount, unresolved treated as 'reaches more' -> 4 entries (plugin route added)
diff coverage: 75.0%

A change to formatCurrency reaches three entry points; chargeCard reaches one. Same one-line edit, different reading depth. The last line assumes tests ran 9 of 12 changed lines — a metric distinct from repo-wide coverage.

Reading the 0–100 score

The README builds the score from reach, diff coverage, security findings, contract breaks and dependency changes, describing it as the chance that at least one risky part of the change breaks something. It also says the score and verdict thresholds are heuristics checked on a few repositories and should be calibrated on yours. A 60 does not mean 60% failure probability. To use it for real, compare scores of past PRs with actual regressions and set thresholds from that.

The score reportedly falls as reviewers clear items. That means "I read it" lowers the number, so a falling score is not evidence the code got better.

Before adopting

  • Unsupported stacks: the README says it does not read Django REST Framework routers, Remix, Vue, Svelte or code-built TanStack trees. On such stacks reach may look empty.
  • JS files and TypeScript backends: these use module-level reach, coarser than function-level.
  • Action separation: the README's example workflow keeps a test job (no secrets, read-only token) apart from the Farol job that comments on the PR, and never runs PR code. Repos accepting fork PRs should keep that split.
  • Optional data: Datadog traffic and errors are informational and do not change the score.

Not established here: real Farol output, false-positive/negative rates, run time, behaviour on large repositories.

Conclusion for developers

When an AI writes the code and an AI reviews it first, what should the human read? Farol's value is less the score than the reading order: which entry points a change reaches and which lines no test touched. It is a poor fit for heavily dynamic codebases, unsupported frameworks, or teams that want to turn the score into a merge gate. A sensible start is running it on 20–30 past PRs and checking whether the changes that actually caused trouble landed in the top tiers. For the underlying PR workflow, see practical version control.

The Git course below is a paid-course promotional link. It reinforces PR and branch collaboration basics; it is not presented as a Farol-specific course.