Policy gate — guard
A declarative merge gate that caps how many findings of each severity a change may carry, via an opt-in .commitbrief/policy.yml. Richer than a single --fail-on threshold; aimed at gating high-volume, often AI-authored, pull requests.
commitbrief guard is a declarative merge gate. Instead of one
severity cutoff, it evaluates a review’s actionable findings against a
.commitbrief/policy.yml and exits non-zero when the policy is
breached. Think of it as a per-severity budget rather than the single
--fail-on=<severity> threshold — useful when you’re gating
high-volume, often AI-authored, pull requests. New in v1.10.0
(ADR-0029).
The policy file
The gate is opt-in: with no .commitbrief/policy.yml there is no
gate. Create one to declare the budget:
# .commitbrief/policy.yml
version: 1
thresholds: # max findings allowed per severity (omit or ~ = unlimited)
critical: 0
high: 0
medium: 5
low: ~
total: 20 # optional overall cap across all severities
A severity you omit (or set to ~) is unlimited. total is an
optional cap on the combined count.
Two ways to run it
Run-mode — review, then evaluate
Run-mode reviews the diff (reusing the standard pipeline) and judges the result against the policy:
commitbrief guard # staged diff
commitbrief guard --unstaged
commitbrief guard --diff main...HEAD
Consume-mode — evaluate an existing review
--from-json evaluates a review you already produced, with no
provider call — so an agent’s MCP self-review
or a prior commitbrief --json run can be gated cheaply:
commitbrief --json --staged > review.json
commitbrief guard --from-json review.json
--from-json - reads the review from stdin.
What it evaluates
guard judges the findings that survive
baseline + suppression (signal control)
— exactly the set --json shows. Baselined and inline-suppressed
findings are already gone before the policy sees them.
Exit codes
The exit code is 0 (pass) or non-zero (blocked). Critically, a load or parse failure also blocks: a missing or malformed policy, or an unparseable review, fails the gate rather than passing it — a merge gate must not pass when it cannot prove the change is within policy.
--json emits a machine-readable verdict:
{
"passed": false,
"counts": { "critical": 0, "high": 2, "medium": 1 },
"total": 3,
"violations": ["high: 2 > 0"]
}
guard vs. --fail-on
--fail-on=<severity> is the simple
one-threshold gate — “fail if any finding meets or exceeds this
severity.” guard is the per-severity budget — “allow up to N of each.”
They complement each other; use either or both. A repo might run
--fail-on=critical on a developer’s pre-commit hook and the richer
guard policy on the CI merge gate.
Rule-id-scoped allow/deny lists are not yet supported — findings carry no stable rule id. The policy is severity- and total-count-based for now.
Flags
| Flag | Notes |
|---|---|
--policy <path> |
Policy file location. Default .commitbrief/policy.yml, resolved relative to the repo root. |
--from-json <file|-> |
Consume-mode: evaluate a prior schema-v1 review (no provider call). - reads stdin. |
--unstaged |
Run-mode: review the working tree instead of the staged diff. |
--diff <range> |
Run-mode: review an arbitrary git diff range. |
--json |
Emit the machine-readable verdict. |
--provider / --model / --no-flaky carry over from the persistent
flags in run-mode.
See also
- Severity and CI gating —
--fail-on, the simpler one-threshold gate guard complements. - Signal control — baseline + suppression, the filters applied before guard evaluates.
- MCP server — produce a review an agent can
feed to
guard --from-json. - Output formats — the JSON schema v1 that consume-mode reads.