Gate a build on a run
bugb ci reads a run’s ledger, applies a policy, and exits with a code your
pipeline can branch on. This page writes a policy, sees it pass and fail, and
covers the third exit code — the one that means the gate could not evaluate at
all.
Before you start
Section titled “Before you start”- A run on this machine with a ledger.
bugb resumelists what is available.
The default policy
Section titled “The default policy”With no policy file, bugb ci uses a built-in one:
bugb ci --run 20260818-120316-nodegoat FAIL 20260818-120316-nodegoat policy built-in default fail_on_severity high · max_confirmed none · fail_on confirmed
124 threats tracked · 3 counted · 3 breaches
critical App.Allocations #idor app/routes/index.js:63 breached fail_on_severity critical App.Router #missing-authz app/routes/index.js:66 breached fail_on_severity critical Data.AllocationsDAO #nosql-injection app/data/allocations-dao.js:57 breached fail_on_severityRead the second line before the verdict. fail_on confirmed is why 124 tracked
threats produced only 3 counted: everything the run could not prove is ignored
by the gate. A build that passes has not been told the run tested everything —
the ledger is where the untested
threats are.
Omit --run and it uses the latest run for the repository you are in.
Write your own
Section titled “Write your own”fail_on_severity = "critical"max_confirmed = 5bugb ci --run 20260818-120316-nodegoat --policy .bugb/policy.toml FAIL 20260818-120316-nodegoat policy policy.toml fail_on_severity critical · max_confirmed 5 · fail_on confirmed
124 threats tracked · 3 counted · 3 breachesTruncated: the three breached findings follow, as above.
bugb ci reads .bugb/policy.toml from the repository by default, so
committing it there is enough — --policy is for pointing at a different one.
| Key | Default | Effect |
|---|---|---|
fail_on_severity |
high |
a counted finding at or above this severity fails the build |
max_confirmed |
none | budget for counted findings before the build fails |
fail_on |
["confirmed"] |
which verdicts count at all |
fail_on is the one to think about. It takes ledger verdicts, so a team that
wants a run’s operational failures to break the build rather than pass quietly
can say so:
fail_on = ["confirmed", "error"]On the run above that widens the gate from 3 counted findings to 10, and from 3 breaches to 8: every threat whose probe never reached the target now counts against the build instead of passing quietly.
The three exit codes
Section titled “The three exit codes”-
0 — passed.
Terminal window bugb ci --run 20260818-120316-nodegoat --policy pass.tomlecho $?PASS 20260818-120316-nodegoatpolicy pass.tomlfail_on_severity critical · max_confirmed none · fail_on mitigation_held124 threats tracked · 0 counted · 0 breaches0That policy counts only
mitigation_held, of which this run has none. It is a demonstration of the exit code, not a policy to copy. -
1 — the policy was breached. The default run above exits
1. -
2 — the gate could not evaluate.
Terminal window bugb ci --run does-not-existecho $?bugb: unknown run 'does-not-exist' (run_id='does-not-exist')2Distinguishing 2 from 0 is the point. A gate that cannot find its ledger has proven nothing, and a pipeline that treats “could not evaluate” as “passed” is a green light with nothing behind it.
Machine-readable output
Section titled “Machine-readable output”bugb ci --run 20260818-120316-nodegoat --format json{ "schema": "bugb.ci/v1", "run_id": "20260818-120316-nodegoat", "codebase": "/Users/you/nodegoat", "policy": { "source": null, "fail_on_severity": "high", "max_confirmed": null, "fail_on": [ "confirmed" ] }, "passed": false, "exit_code": 1, "counts": { "total": 124, "counted": 3, "by_severity": { "critical": 3 }, "breaches": 3 },Truncated after counts — a breaches array follows, one object per breach,
each carrying the rule, a sentence explaining it, and the finding itself.
"source": null is the built-in policy; with --policy it names the file.
exit_code is in the payload as well as on the process, so a step that captured
stdout does not have to have kept $?.
--reporter github renders the verdict onto GitHub Actions’ own surfaces, and
is the default when bugb detects it is running inside Actions.
Related
Section titled “Related”- Read a run — the ledger this gate reads.
- Verdicts and the ledger — what
fail_onis choosing between.

