> ## Documentation Index
> Fetch the complete documentation index at: https://tashfiq.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# suppress

> Record a governed suppression in .charter-suppress.yml.

`charter suppress <RULE-ID>` writes a suppression entry to `.charter-suppress.yml`. Use it when a finding is a confirmed false positive or an accepted risk that still needs an audit trail. The rule ID is positional. Suppressed findings disappear from the active score and are listed separately in scan output.

## Usage

<CodeGroup>
  ```bash Time-bounded suppression with reason and expiry theme={null}
  charter suppress AE-CC-001 \
    --reason "Claude config lives in the infra repo" \
    --expires 90d
  ```

  ```bash Permanent suppression (requires approver) theme={null}
  charter suppress AE-TEST-001 \
    --reason "Backend-only repo; no test framework applies" \
    --expires permanent \
    --approver "@tashfiqul"
  ```

  ```bash Preview without writing theme={null}
  charter suppress AE-CI-002 --reason "..." --dry-run
  ```
</CodeGroup>

<Frame caption="charter suppress --dry-run — preview the suppression entry before writing">
  <img src="https://mintcdn.com/tashfiq/uHoRNuLkLShRQ253/images/screenshots/suppress-output.webp?fit=max&auto=format&n=uHoRNuLkLShRQ253&q=85&s=e51d3ea1348e39e9331fdac185723b13" alt="charter suppress dry run output" width="1728" height="768" data-path="images/screenshots/suppress-output.webp" />
</Frame>

## Flags

<ResponseField name="--reason" type="string" required>
  Human-readable explanation of why this finding is acceptable. Required — a suppression without a reason triggers [`AE-SUPPRESS-001`](/rules/AE-SUPPRESS-001).
</ResponseField>

<ResponseField name="--expires" type="string">
  Time-to-live for the suppression. Accepts a day duration (`30d`, `90d`), an ISO date (`2026-12-31`), or `permanent`. Durations are stored as an absolute `YYYY-MM-DD` date. Defaults to `90d`.
</ResponseField>

<ResponseField name="--approver" type="string">
  Approver handle. Required for a `permanent` waiver to be honored — without it, [`AE-SUPPRESS-002`](/rules/AE-SUPPRESS-002) fires as a High finding.
</ResponseField>

<ResponseField name="--path" type="string">
  Explicit repository root. Defaults to the current working directory.
</ResponseField>

<ResponseField name="--dry-run" type="boolean">
  Print the suppression entry that would be written without modifying `.charter-suppress.yml`.
</ResponseField>

<ResponseField name="--color" type="auto | always | never">
  Color output mode for text rendering. Defaults to `auto`.
</ResponseField>

<ResponseField name="--no-color" type="boolean">
  Disable color. Equivalent to `--color=never` and wins over `--color` when both are set.
</ResponseField>

## What Gets Written

`charter suppress` updates `.charter-suppress.yml` in the target repository. Each entry records:

```yaml theme={null}
suppressions:
  - rule: AE-CC-001
    reason: "Claude config lives in the infra repo"
    expires: "2026-09-07"
```

For a permanent suppression with an approver:

```yaml theme={null}
suppressions:
  - rule: AE-TEST-001
    reason: "Backend-only repo; no test framework applies"
    expires: permanent
    approver: "@tashfiqul"
```

An optional `path` field scopes an entry to a specific file or glob.

<Warning>
  Permanent suppressions (`--expires permanent`) require an `--approver` field to be honored. Without it, [`AE-SUPPRESS-002`](/rules/AE-SUPPRESS-002) fires as a High finding on every subsequent scan.
</Warning>

## Governance Rules

Three governance rules run on every `charter doctor` scan to keep the suppression file honest:

* [`AE-SUPPRESS-001`](/rules/AE-SUPPRESS-001) (Medium) — fires if any suppression entry is missing a `reason` field. Every suppression must carry a human-readable justification.
* [`AE-SUPPRESS-002`](/rules/AE-SUPPRESS-002) (High) — fires if any permanent suppression has no `approver` field. Permanent waivers require an explicit owner on record.
* [`AE-SUPPRESS-003`](/rules/AE-SUPPRESS-003) (Informational) — fires when the suppression rate across the repository is high. This is a signal-only finding and does not deduct from the score. It surfaces when a large proportion of findings are suppressed rather than fixed.

These rules cannot themselves be suppressed without triggering further governance findings.

## Exit codes

| Code | Meaning | When                                                                                                                            |
| ---- | ------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `0`  | Pass    | The suppression entry was written, or a `--dry-run` preview rendered without error                                              |
| `2`  | Error   | A missing `--reason`, an unknown rule ID, an invalid `--expires` value, a write failure, or a malformed `.charter-suppress.yml` |

## Related

<CardGroup cols={2}>
  <Card title="Suppression governance" icon="gavel" href="/docs/concepts/suppression-governance">
    How the suppression file is policed and why waivers expire.
  </Card>

  <Card title="Suppress a finding" icon="eye-off" href="/docs/how-to/suppress-a-finding">
    The end-to-end workflow for accepting a risk on the record.
  </Card>

  <Card title="AE-SUPPRESS-001" icon="shield" href="/rules/AE-SUPPRESS-001">
    The rule that requires every suppression to carry a reason.
  </Card>
</CardGroup>
