Skip to Content
GuidesManage Waivers

Manage Waivers

A waiver exempts a specific rule from gate enforcement for a given scope. Unlike tuning thresholds, waivers preserve your global policy while acknowledging specific, justified exceptions.

Scope Ladder

Each waiver has a scope. Most-specific match wins during evaluation:

  1. PR-scoped(org_id, repo_id, pr_number, rule) — applies only to that one PR
  2. Repo-scoped(org_id, repo_id, rule) — applies across all PRs in that repo
  3. Org-scoped(org_id, rule) — applies across all repos in the org

Missing fields = broader scope. Create an org waiver by leaving repo_id and pr_number null. Create a repo waiver by setting repo_id only.

Creating a Waiver

Example Waivers

PR-specific — emergency merge

POST /api/quality/gates/waivers { "rule": "new_critical_max", "reason": "Hotfix for PROD-5512. Vulnerability in third-party SDK, upstream fix tracked in #7812. Rolling back to previous version via separate PR immediately after merge.", "repo_id": 42, "pr_number": 1087, "expires_at": "2026-04-20T00:00:00Z" }

Repo-specific — known issue, scheduled remediation

{ "rule": "duplication_pct_max", "reason": "Legacy monolith has 12% duplication. Refactor to shared utilities tracked in Q2 OKR. Gate disabled until 2026-07-01 scheduled review.", "repo_id": 42, "expires_at": "2026-07-01T00:00:00Z" }

Org-wide — temporarily lenient during rollout

{ "rule": "new_coverage_min", "reason": "Org-wide testing push in progress. Coverage gates suspended until coverage baseline is established across all repos. Revisit 2026-06-01.", "expires_at": "2026-06-01T00:00:00Z" }

How Waivers Affect Evaluation

When the gate runs, waived rules’ violations are stripped from the primary violations list and moved into a separate waived_violations field. The gate still passed if only waived rules are violating:

{ "status": "passed", "violations": [], "waived_violations": [ { "rule": "duplication_pct_max", "threshold": 3, "actual": 4.2, "severity": "high", "waived": true } ] }

The PR comment, Check Run, and dashboard widget all surface waived violations separately — with the reason — so reviewers know the exception is active and deliberate.

Viewing + Revoking

  • List active: GET /api/quality/gates/waivers — default hides expired + revoked
  • List all: GET /api/quality/gates/waivers?include_expired=true&include_revoked=true
  • By repo: GET /api/quality/gates/waivers?repo_id=42
  • Revoke: POST /api/quality/gates/waivers/{id}/revoke — soft-delete; stops honoring on next scan

In the UI: Settings → Policies → Quality Gates → Manage Waivers → toggle “Include expired/revoked” to see history. Trash icon on each row revokes.

Audit Trail

Every waiver stores:

  • created_by_user_id — who created it
  • created_at — when created
  • revoked_at — when revoked (null if active or expired)
  • expires_at — scheduled expiry (null if permanent)
  • reason — required text

No delete path. Revocation is soft. Records are preserved for audit.

Common Patterns

SituationScopeExpiry
One-off emergency mergePR24h
Known repo-level tech debtRepoTied to remediation deadline
Awaiting upstream CVE fixRepo or orgTied to upstream release ETA
Vendor-mandated compensating controlRepoPermanent (no expiry) + documented
Policy rollout easingOrgTied to full-enforcement date