Baseline and suppressions
On a repository that has never run paranoid, verify
reports every finding in the range, not only the latest change.
A baseline snapshots those findings so only new ones fail CI.
.paranoid-baseline.json is the only file paranoid
reads besides command-line flags. It does not change which rules run or any threshold. It records which findings were already reviewed and carried forward, like a linter's baseline file.
Adopt paranoid on an existing repo
Run this once, from the repo root:
paranoid baseline --base <the oldest point you care about>
This runs the same checks as verify and
writes every finding it sees to .paranoid-baseline.json,
with no reason and no expiry. Commit that file.
From then on, verify auto-loads it: any finding
that still matches one of its entries moves out of the report's
findings and into a suppressed section instead, and
the score ignores it. New findings, the ones an agent introduces
after adoption, still fail the run. The suppressed section lists what was suppressed and why, in every format, even when it is empty.
A baseline entry is matched by rule ID, file, and a fingerprint of the finding's evidence text, not by line number, so it survives unrelated edits elsewhere in the file. It does not survive the evidence text itself changing, or the finding moving to a different file.
Flags that control it
| Flag | Meaning |
|---|---|
| --baseline <file> | Load this file instead of the auto-detected .paranoid-baseline.json at the repo root |
| --no-baseline | Ignore any baseline file, including the auto-detected one |
A baseline file that exists but cannot be parsed is always a
hard error (exit 3), whether it was auto-detected or named
explicitly. A missing file at the auto-detected path means there is nothing to suppress. A missing file named with --baseline is an error.
Hand-suppressing one finding
You can also hand-edit .paranoid-baseline.json to
suppress one specific finding you have reviewed and accept,
instead of baselining everything. Every entry may carry a
reason and an expires date (RFC 3339,
for example 2026-12-01).
{
"baseline_version": 1,
"tool_version": "v0.1.0",
"created_at": "2026-08-20T10:00:00Z",
"entries": [
{
"rule_id": "DEP003",
"file": "package.json",
"fingerprint": "a1b2c3...",
"reason": "internal package, low downloads expected",
"expires": "2026-12-01"
}
]
}
paranoid baseline never sets reason or
expires itself, so if you set expires
by hand you must also set reason, non-empty. A
permanent hand-added suppression (no expires) does not need one, but a reason is recommended.
Once expires passes, that entry stops suppressing:
the finding comes back into the report and the score, and the
report still lists the expired entry so you see it happened.
Re-running paranoid baseline writes a fresh, full
snapshot from scratch and discards any reason or expiry you
added by hand. It does not merge with the existing file.
What the report shows
The report's suppressed block has a count
(findings actually removed from scoring) and a list of
entries: every baseline entry that matched a finding
this run, whether it suppressed it or had already expired. An expired match is listed like an active one and is marked by one field. Its finding is back in findings and counted in the score. See
Report & schema for the
exact JSON shape.
A .paranoid.toml [[disable]] entry can
also add entries to the same suppressed block; each
entry's source field says which one matched it,
"baseline" or "policy", and text/markdown
output labels them suppressed-by-baseline and
suppressed-by-policy to tell the two apart.
See Team policy file.
baseline command flags
paranoid baseline [path] accepts the same
--base, --head, --offline,
--sandbox, --sandbox-image,
--sandbox-timeout, and --compare-base
flags as verify, so a baseline is generated from
exactly the range you would otherwise verify. It always writes
a full snapshot to .paranoid-baseline.json at the
repo root; there is no output path flag. It exits 0 on success
and 3 on any error; it has no score of its own, so nothing maps
to exit 1 or 2.
Using this in CI
Generate and commit .paranoid-baseline.json once,
locally, before turning on CI enforcement or the GitHub Action.
The Action needs no extra input for this: verify
auto-detects the committed file at the repo root the same way it
does outside CI. See
Exit codes & CI.