# How to tune findings for local dev (`severity_overrides`)

> **You want to:** run an apiprobe `Suite` against a local dev
> stack (e.g. `http://localhost:8000`) without drowning in
> "missing HSTS" findings that don't apply to non-HTTPS endpoints.
> **You have:** a `Suite` with `DEFAULT_CHECKS` and probes
> pointed at a non-HTTPS host.
> **You'll end up with:** the same Suite emitting WARN findings
> as INFO (or suppressing them entirely) for checks that don't
> conceptually apply, while still surfacing the ones that do.

This recipe closes
[PAPER-41](https://codeberg.org/magogi-admin/mgf-common/src/branch/main/FEEDBACK.md)
(filed by inthewords during its starter-Suite adoption — the
local dev stack tripped `MissingHsts` × N probes on first run).

## Steps

1. **Identify which checks fire spuriously.** Run the Suite
   once. The HumanReportWriter groups findings by code; the
   noisy ones are usually the headers-based checks
   (`security.headers.missing-hsts`,
   `observability.headers.missing-request-id`,
   `quality.headers.missing-rate-limit`) plus the
   `security.headers.server-disclosure` family.

2. **Pass `severity_overrides` to the `Suite`** to demote the
   ones that don't apply to your environment:

   ```python
   from mgf.apiprobe import (
       DEFAULT_CHECKS,
       Probe,
       Severity,
       Suite,
   )
   from mgf.apiprobe.transport import HttpxTransport

   suite = Suite(
       probes=[
           Probe.get("/api/v1/me/").base("http://localhost:8000"),
           # ... other probes ...
       ],
       checks=list(DEFAULT_CHECKS),
       severity_overrides={
           # Local dev runs over HTTP — HSTS doesn't apply.
           "security.headers.missing-hsts": Severity.INFO,
           # Only the auth endpoint is rate-limited in dev; demote
           # the global expectation for the rest.
           "quality.headers.missing-rate-limit": Severity.INFO,
       },
   )

   transport = HttpxTransport()
   report = await suite.run(transport=transport)
   ```

3. **Keep CI on the unmodified Suite.** The override dict is
   environment-shaped — fine for `make apiprobe` against the
   local dev stack, but production / staging runs should see
   the full WARN signal. Build the Suite in two places (or
   conditionally apply the overrides) so the noisy dev shape
   doesn't quietly become the prod baseline.

## Verify

```bash
python -m my_app.apiprobe_suite | grep -c "missing-hsts"
# Should print 0 if you overrode to INFO and your writer
# filters INFO out, or N if INFO is still shown — either way
# the finding is now INFO, not WARN.
```

## Common pitfalls

- **Severity, not visibility.** `severity_overrides` changes
  the severity label, not whether the finding is reported.
  The HumanReportWriter shows all findings; the exit-code
  driver typically filters on CRITICAL. INFO and WARN
  findings still appear in the report — just at a different
  severity tier.
- **Don't override `CRITICAL` away.** If you find yourself
  needing to demote a `CRITICAL` finding to silence noise,
  that's almost always the wrong move. Either the check is
  genuinely broken (file a `[mgf-apiprobe]` paper in
  `mgf-common/FEEDBACK.md`) or your stack has a real problem.
- **HSTS makes no sense over plain HTTP.** Per RFC 6797 §7.2,
  HSTS headers from non-HTTPS responses MUST be ignored by
  browsers. The `MissingHsts` check still flags them by
  default because most consumers run against HTTPS; the
  override is the right move when you don't.

## Cross-references

- [`mgf-standard/docs/standards/API_DESIGN.md`](https://codeberg.org/magogi-admin/mgf-standard/src/branch/main/docs/standards/API_DESIGN.md)
  — the `Severity` enum + lifecycle.
- [`mgf-common/FEEDBACK.md` PAPER-41](https://codeberg.org/magogi-admin/mgf-common/src/branch/main/FEEDBACK.md)
  — the consumer feedback this recipe closes.
- [`mgf-apiprobe/PUBLIC_API.md`](../../PUBLIC_API.md) — the
  full check catalogue + their default severities.
