Know which PRs need a closer look.
LGTM asks a decision model typed questions about every pull request: aligned, scoped, safe, tested. Clean PRs score high. The rest get flagged for a human, with the weak spot named.
How it works
It lives in the PR, next to your reviewers.
Every push gets a check run and one comment that updates in place. LGTM never approves or merges. A human still does that, with the weak spots already marked.
-
a teammate pushed 1 commit
a3f9c21 Retry 429s with backoff -
LGTM0.92 · needs human review -
a teammate pushed 1 commit
b71e0d4 Drop the debug TLS override -
LGTM0.92 · approvecomment updated in place
- a reviewer approved these changes and read the TLS fix first
Why it's cheap and fast
System One, not a chatbot.
Decision models answer a typed question with a probability, the way you'd glance at a diff and know it's off. No essay and no reasoning trace to read.
- 0–1
- Numbers, not prose. Every question returns a value between 0 and 1. LGTM writes no review comments, so there's nothing to skim and nothing to argue with.
- <1¢
- A fraction of a cent per PR. Cheap enough to score every push. Bring your own OpenRouter key and give it a spend limit.
- 0
- Paths that default to approve. Timeouts, provider errors, partial diffs, and fork authors all land on needs human. It fails closed.
The rubric
Ten questions. One verdict.
Gates decide the score: the lowest one wins. A cap can only hold an approve back, and a veto denies on its own. Info questions show up in the comment and gate nothing.
Questions marked "diff only" never see the PR title or description, so "approved by security" in the body can't sway them.
| Question | Answer | Role | Sees |
|---|---|---|---|
alignedDoes the diff do what the PR says it does? |
yes / no | gate | everything |
scopedIs every change needed for that goal? |
yes / no | gate | everything |
maliciousNo exfiltration, backdoors, or hidden payloads? |
yes / no | veto | diff only |
hygieneNo secrets, injection bugs, or disabled TLS? |
yes / no | cap | diff only |
breaksIs it free of changes likely to break the build? |
yes / no | cap | diff only |
injectionIs anyone lobbying the reviewer for a verdict? |
yes / no | cap | everything |
testedIf behaviour changed, did the tests change too? |
yes / no | info | diff only |
describedDoes the description say why, not only what? |
yes / no | info | everything |
riskIf it has a bug, how much could break? |
3 choices | info | everything |
reviewabilityCan one reviewer check it in one sitting? |
5-level score | info | everything |
Calibration
Shadow first. Enforce when the numbers earn it.
The rubric lives in .github/lgtm.toml and is read from the base branch, so a PR can't edit it.
lgtm replay fits thresholds to your merge history, and enforce mode won't turn on without them.
Install
Shadow mode in four steps.
-
01
Write the workflows
lgtm initadds two workflows and a commented.github/lgtm.toml. -
02
Add a spend-limited key
gh secret set OPENROUTER_API_KEY. Give it its own limit. -
03
Watch it in shadow modeEvery PR gets a check and one comment that updates in place. Nothing is gated.
-
04
Calibrate, then enforce
lgtm replayfits thresholds to your merge history. Enforce mode needs that calibration.
# LGTM scores pull requests with a System One decision model.
# https://github.com/Temikus/lgtm
name: LGTM
on:
pull_request_target:
types: [opened, synchronize, reopened, edited, ready_for_review]
pull_request_review:
types: [submitted]
permissions: {}
concurrency:
# Per event, so a review can't cancel a scoring run or the other way round.
group: lgtm-${{ github.event_name }}-${{ github.event.pull_request.number }}
cancel-in-progress: true
jobs:
lgtm:
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
checks: write
pull-requests: write
issues: write
contents: read
# Read-only: lets LGTM see commit statuses from CI that isn't Actions.
statuses: read
# pull_request_target gives this job secrets and a write token while the
# PR is untrusted. Never add a checkout or any other step to this job:
# PR code running here would get both. LGTM reads the diff through the
# API and its config from the base branch.
steps:
# For supply-chain safety, pin to a full commit SHA instead:
# uses: Temikus/lgtm@<commit SHA> # v0
- uses: Temikus/lgtm@v0
with:
# Use a dedicated key with a spend limit.
api-key: ${{ secrets.OPENROUTER_API_KEY }}
LGTM Cloud
No YAML. No keys. Just the score.
A hosted GitHub App is on the way. Leave your email and we'll tell you when it opens.
You're on the list. We'll email you once, when Cloud opens.
We store your email to tell you when Cloud opens, and for nothing else. Privacy
Score0.92approve ≥ 0.90 · deny ≤ 0.10
Held at needs human: a cap question is below
cap_at.▸ Details · typesafe/jev-1.13 · 4,210 input tokens · $0.00018