Skip to content

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.

  • A run on this machine with a ledger. bugb resume lists what is available.

With no policy file, bugb ci uses a built-in one:

Terminal window
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_severity

Read 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.

.bugb/policy.toml
fail_on_severity = "critical"
max_confirmed = 5
Terminal window
bugb 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 breaches

Truncated: 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.

  1. 0 — passed.

    Terminal window
    bugb ci --run 20260818-120316-nodegoat --policy pass.toml
    echo $?
    PASS 20260818-120316-nodegoat
    policy pass.toml
    fail_on_severity critical · max_confirmed none · fail_on mitigation_held
    124 threats tracked · 0 counted · 0 breaches
    0

    That policy counts only mitigation_held, of which this run has none. It is a demonstration of the exit code, not a policy to copy.

  2. 1 — the policy was breached. The default run above exits 1.

  3. 2 — the gate could not evaluate.

    Terminal window
    bugb ci --run does-not-exist
    echo $?
    bugb: unknown run 'does-not-exist' (run_id='does-not-exist')
    2

    Distinguishing 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.

Terminal window
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.