Signal control — baseline and suppression
Cut repeat noise without hiding findings from review — a user-private baseline that accepts a brownfield repo's existing findings, plus inline commitbrief-ignore comments with a visible reason.
A reviewer that re-reports the same pre-existing findings on every
run is a reviewer you start ignoring. Signal control gives you two
ways to drop findings you’ve already triaged — a baseline for
“accept everything this brownfield repo already has” and an inline
// commitbrief-ignore comment for “this one specific finding is
fine” — without ever hiding a finding from the next reviewer. New in
v1.8.0 (ADR-0027).
Both are true removals, not display filters: a dropped finding no
longer counts toward --fail-on and no longer
appears in --json findings[].
That makes them stronger than --min-severity — see
How this differs from --min-severity
below. And neither is silent: every removal is counted and reported.
Baseline
A baseline records the findings already present in your repo so that subsequent runs show only new ones. It’s the answer to “I just pointed CommitBrief at a 200k-line legacy repo and got 90 findings I already know about.”
Recording a baseline
commitbrief --update-baseline
This runs a review and writes the current findings to
.commitbrief/baseline.json instead of failing on them. From the
next run on, anything in the baseline is dropped from the output, and
only findings not in the baseline surface.
It’s user-private — it cannot hide a bug from review
.commitbrief/baseline.json is per-developer and gitignored
(the .commitbrief/ directory is auto-added to .gitignore on first
write). It is never committed and never propagates:
- CI still sees everything. A CI runner has no baseline file, so it reviews the full diff — the baseline can’t weaken the gate.
- The next reviewer still sees everything. Their checkout has no baseline either, or has their own.
So a baseline is local convenience only. A teammate cannot bake a bug into a shared baseline to slip it past review, because there is no shared baseline to bake it into. It quiets repeat noise for you without lowering the bar for anyone else.
Fingerprinting — survives code drift
A baselined finding is fingerprinted by file + severity + title — deliberately not by line number. Adding ten lines above a baselined finding shifts its line but not its fingerprint, so it stays baselined. A genuinely new problem in the same file gets a different title and surfaces as new.
Turning it off
# Per-run: ignore the baseline for this invocation (review everything).
commitbrief --staged --no-baseline
# Per-config: disable baseline reads entirely.
review:
baseline: false # default true; --no-baseline is the per-run equivalent
commitbrief config set review.baseline false
With review.baseline: false the file is ignored on read; it still
exists on disk until you remove it.
Inline suppression
When a single finding is a known false positive — or an accepted trade-off you don’t want re-flagged — drop a comment on the same line:
const id = items[0].id; // commitbrief-ignore: list is guaranteed non-empty here
That line’s findings are removed from the output. Scope the suppression to one severity with a bracket:
eval(userInput); // commitbrief-ignore[high]: sandboxed; tracked in TICKET-123
commitbrief-ignore[high]: … drops only high-severity findings on
that line; a critical finding on the same line still surfaces. A
bare commitbrief-ignore: … drops findings of any severity.
The reason is mandatory and visible
The : reason is part of the syntax and lands in the diff the next
reviewer reads — so a suppression is never a silent override. It’s a
note to the human reviewer explaining why this is fine, sitting
right next to the code, reviewable like any other line. A suppression
with no justification is one a reviewer can push back on in the same
PR.
How this differs from --min-severity
It’s easy to confuse three things that all “make a finding go away.” They are not the same:
| Mechanism | Removes the finding? | Affects --fail-on / --json? |
Scope |
|---|---|---|---|
--min-severity |
No — display only | No (the finding still counts and still appears in --json) |
Per run |
| Baseline | Yes — true removal | Yes | User-private, persists across runs |
Inline commitbrief-ignore |
Yes — true removal | Yes | One line, lives in the code |
--min-severity only hides lower-severity
findings from the rendered view; they still count toward CI gating and
still show up in JSON. Signal control genuinely removes the finding
from the result. Reach for the baseline or a commitbrief-ignore
comment when you want a finding gone from the gate, not just out of
sight.
Removals are reported, never silent
Whatever you drop, CommitBrief tells you it dropped it:
-
A one-line stderr footer summarizes the run:
3 baselined · 1 suppressed -
The
--jsonpayload carries additive optionalmeta.baselinedandmeta.suppressedcounts. These are additive — the JSON schema stays v1, so existing consumers are unaffected and new ones can read the counts:{ "meta": { "baselined": 3, "suppressed": 1 }, "findings": [ ... ] }
You always know how many findings were held back, even though the findings themselves are gone from the list. That visibility is the point: signal control trims noise loudly.
See also
- Severity and CI gating —
--fail-on,--min-severity, and how removed findings change the exit code. - Output formats — the JSON schema v1 and
where
meta.*counts live. - Review rules —
COMMITBRIEF.md, the other way to steer what gets flagged. - Configuration —
review.baselinein the config reference.