Architecture
PR Quality Gate
Stages fan out in parallel per pull request instead of running serially per repo. Advisory mode reports without blocking until a team opts in.
What you're looking at
A push opens a pull request, which fires a webhook at the dispatcher. The dispatcher fans the work out — lint, test, coverage and SAST all start at once rather than queueing. Each reports back independently, and the verdict node aggregates them. The dashed edge from the artifact registry is credential flow, not code: the gate mints a short-lived token so private packages resolve without a long-lived secret sitting in CI.
Why parallel matters more than it sounds
Serially, gate time is the sum of every stage. In parallel it is the slowest single stage. On a 200-repo estate that is the difference between a gate people wait for and a gate people route around — and a gate that gets routed around protects nothing.
What goes wrong here
Three things, in order of frequency. The registry token expires mid-build on long runs, producing a 401 that looks like a dependency problem. A SAST scan with no per-PR cap runs on every push to a busy branch and the bill arrives at the end of the month. And a gate switched from advisory to blocking before teams have fixed their existing findings blocks every merge on day one, which is how gates get disabled entirely.
Inspect it yourself
Is the gate actually parallel?
# compare wall-clock against the sum of stage durations gh run view RUN_ID --json jobs -q '[.jobs[] | {name, started: .startedAt, ended: .completedAt}]'If total elapsed ≈ sum of stages, they are running one after another regardless of what the config claims.
Find repos not covered by the gate
gh repo list ORG --limit 500 --json name,defaultBranchRef -q '.[].name' | while read r; do gh api repos/ORG/$r/branches/main/protection >/dev/null 2>&1 || echo "unprotected: $r"; doneCoverage is the number that matters. A gate on 70 of 200 repos is a gate with a 130-repo hole in it.
Read the source
Components
- DEVELOPER— git push
- PULL REQUEST— webhook
- DISPATCHER— fan-out
- LINT
- TEST
- COVERAGE
- SAST— per-PR cap
- VERDICT— advisory / blocking
- ARTIFACT REGISTRY— short-lived token
Flows
- dev→prpush
- pr→dispwebhook
- disp→lint
- disp→test
- disp→cov
- disp→sast
- registry⇢dispauth
- lint→verdict
- test→verdict
- cov→verdict
- sast→verdict