Skip to main content
Suppression is how you keep accepted exceptions visible without letting them disappear. Charter treats suppressions as governance artifacts — they are audited on every scan, not silently honored.

When to suppress

Confirmed false positive

The finding doesn’t reflect a real problem in your repo — Charter’s detection doesn’t apply to your specific setup.

Accepted risk with justification

The risk is real but intentionally accepted, documented, and has an owner and a time horizon.

Genuine issue not yet addressed

Don’t suppress findings you just haven’t gotten around to fixing. Fix them, or leave them in the active findings list until you do.

Score inflation

Don’t suppress to hit a threshold. A suppressed finding still represents real repo state — suppressions don’t make problems go away.
If you can fix the underlying problem cleanly, do that first.
1

Run the suppression command

The standard suppression path is a time-bounded waiver:
charter suppress AE-CC-001 \
  --reason "Claude hook config lives in a separate infra repo" \
  --expires 90d
2

Review what was written

charter suppress appends an entry to .charter-suppress.yml:
suppressions:
  - rule: AE-CC-001
    reason: Claude hook config lives in a separate infra repo
    expires: 2026-09-07
Commit this file — it is part of your repo’s governance record, not a local override.
3

Re-scan to confirm

charter doctor
AE-CC-001 should no longer appear in the active findings list. It will appear in the “suppressed” section of the scan output instead, so it’s still visible.

Expiry values

ValueMeaning
30d30 days from today
90d90 days from today (recommended default)
1yOne year from today
2026-12-31Explicit calendar date
permanentNo expiry — requires --approver
Permanent suppressions require --approver. Without it, AE-SUPPRESS-002 fires as a High finding on every scan — which costs you points and makes the suppression effectively ungoverned.
charter suppress AE-CC-002 \
  --reason "legacy accepted risk" \
  --expires permanent \
  --approver security-team
A permanent suppression with an approver looks like this in .charter-suppress.yml:
suppressions:
  - rule: AE-CC-002
    reason: legacy accepted risk
    expires: permanent
    approver: security-team

Inline suppression

For single-line, line-anchored findings in source files, you can suppress inline instead of writing to .charter-suppress.yml:
Place the directive on the same line as the triggering content, using the file’s native comment syntax:
# charter:ignore AE-ENV-001 reason="mise managed externally for this workspace"
// charter:ignore AE-SEC-001 reason="fixture secret for detector test"
<!-- charter:ignore AE-CTX-001 reason="context file lives at monorepo root" -->
Supported comment forms: #, //, <!-- -->
Inline suppression does not work for:
  • file-level findings (no single line to anchor to)
  • strict JSON configs like .mcp.json (no comment syntax)
  • multi-line findings
For those cases, use .charter-suppress.yml as the primary suppression path.

Governance rules Charter enforces

Charter audits every suppression on each scan:
RuleWhat it checks
AE-SUPPRESS-001Suppression is missing a reason
AE-SUPPRESS-002Permanent suppression has no approver
AE-SUPPRESS-003Suppression rate across the repo is high
A high suppression rate (AE-SUPPRESS-003) is informational — it tells you the repo may be muting more than it’s fixing.

Good suppression hygiene

  • Prefer a real fix when the repo state is genuinely wrong
  • Use finite --expires windows rather than permanent
  • Write reasons that explain the decision, not just "false positive"
  • Add --approver for any long-lived accepted risk
  • Review .charter-suppress.yml periodically — don’t let it grow silently