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

CommitBrief docs · v1.x · Reviewing

Canonical URL: https://commitbrief.com/docs/1.x/signal-control

---

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`](/docs/1.x/severity) and no longer
appears in [`--json findings[]`](/docs/1.x/output-formats#json-schema-v1).
That makes them stronger than `--min-severity` — see
[How this differs from `--min-severity`](#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

```sh
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

```sh
# Per-run: ignore the baseline for this invocation (review everything).
commitbrief --staged --no-baseline
```

```yaml
# Per-config: disable baseline reads entirely.
review:
  baseline: false   # default true; --no-baseline is the per-run equivalent
```

```sh
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:

```js
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:

```js
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`](/docs/1.x/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:

  ```text
  3 baselined · 1 suppressed
  ```

- The `--json` payload carries additive optional **`meta.baselined`**
  and **`meta.suppressed`** counts. These are additive — the JSON
  schema stays **v1**, so existing consumers are unaffected and new
  ones can read the counts:

  ```json
  {
    "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](/docs/1.x/severity) — `--fail-on`,
  `--min-severity`, and how removed findings change the exit code.
- [Output formats](/docs/1.x/output-formats) — the JSON schema v1 and
  where `meta.*` counts live.
- [Review rules](/docs/1.x/review-rules) — `COMMITBRIEF.md`, the other
  way to steer what gets flagged.
- [Configuration](/docs/1.x/configuration) — `review.baseline` in the
  config reference.