What happens between "PR opened" and a comment on your diff.
Four stages, in order, every time a pull request opens or gets a new commit. This is the pipeline as implemented in patchwork-analyzer today, not the aspirational version — where the two differ, we say so.
0. Webhook in, job queued
GitHub sends a webhook to patchwork-api. Its HMAC signature is verified before anything else touches the payload; an unsigned or wrong-signature request gets a flat 401 and nothing is ever parsed. Once verified, the API acknowledges GitHub immediately and enqueues a job — this decouples "GitHub is happy" from "the review is done," so a slow analysis never causes GitHub to retry the webhook.
1. Edge triage — risk tier classification
The diff is classified into a risk tier — LOW, MEDIUM, HIGH, or CRITICAL — by a small model running on Cloudflare Workers AI (currently a general-purpose instruction model doing structured classification; a bug-pattern-specific fine-tune is on the roadmap but not built). LOW tier is kept only for a confident docs-only or image-only diff (code always gets at least MEDIUM) and skips the LLM review — you still get secrets scanning and genealogy, just not a full model review, which keeps those PRs fast and cheap. MEDIUM routes to Claude Haiku; HIGH and CRITICAL route to Claude Sonnet. A triage failure fails safe to MEDIUM rather than blocking the PR.
2. Structural analysis — real parsing, in an isolated sandbox
For PRs that reach an LLM stage, changed files are parsed with tree-sitter to extract function and type signatures. This does not run inside the Cloudflare Worker — an early attempt hit a hard platform wall (Wasm code generation disallowed by embedder, Workers' V8 isolate flatly refuses runtime WASM compilation). It runs in a small external sandbox service instead, called over HTTP, and the extracted signatures are appended to the review prompt so the model can cross-check contract consistency, not just read the raw diff. A failure here is enrichment-only — it's logged and the review proceeds diff-only rather than failing outright.
3. Bug genealogy — has this happened before?
Each issue the review finds is embedded (Voyage voyage-code-3) and checked against every prior fingerprint for that repo via cosine similarity. Above the match threshold, two things can happen: the issue's entry in bugweg's check run (its inline annotation, or the summary for issues past the first five) tells you this pattern appeared before, how many times, and which PR it was first seen in (Bug Genealogy), and if the match hits an active recurrence rule set to block, the issue is flagged as blocking — which sets bugweg's GitHub Check Run to action_required. Both genealogy and recurrence-rule matching are scoped strictly to the owning repo.
4. LLM review — Haiku or Sonnet, structured output only
The model (whichever tier Stage 1 selected) receives the diff and, if built in Stage 2, the structural context — both explicitly framed as data to analyze, never instructions to follow, to resist prompt-injection attempts hidden in a diff's comments or strings. It's asked for real bugs — null/undefined dereference, off-by-one errors, unhandled promise rejections, injection, race conditions, resource leaks, contract violations — and required to answer in one fixed JSON shape, parsed defensively with a safe fallback if the model doesn't comply. Alongside this: every PR, including LOW-tier ones that skip the LLM, gets a regex/entropy secrets scan, and if the repo has a .bugweg.yml, exclude paths and severity overrides are applied before anything is stored or posted.
5. Assemble, store, post
The full result is written to pr_analyses, per-file risk counters (change_velocity/complexity_delta/defect_density) are updated for every changed file, and a GitHub Check Run is posted — inline annotations on real file/line locations where possible, folded into the summary otherwise. Same commit SHA redelivered (a queue retry or a webhook redelivery) short-circuits before any of this re-runs, so a duplicate delivery doesn't burn a second LLM call or double-count risk signals.
What's wired but not yet triggered by a customer incident
Production Lock's tracker-to-fix pipeline is wired end to end in code: when a PR touches a file with an unresolved Sentry/Rollbar-sourced fingerprint and this review no longer re-flags it, bugweg marks it resolved and runs fail-then-pass regression test generation in the same sandbox execution primitive — see Security. The full chain has now fired on a real merged fix in a test repository: fingerprint resolved, regression test validated as failing before the fix and passing after, and a real pull request opened automatically. What hasn't happened yet is a customer's own Sentry/Rollbar-tracked production incident triggering it. Developer Bug DNA now has a real per-developer pattern profile, linked to a signed-in dashboard user via a self-service GitHub-login link (unverified, self-reported — see Features for the full live/simplified/planned breakdown).