Coverage Policy
| Field | Value |
|---|---|
| Type | Skill Resource |
| Source | ~/.copilot/skills/quality/references/coverage-policy.md |
| Description | Not specified |
Source Content
Coverage Policy
The single number this skill enforces is >=50% line coverage, one of ADR-005’s release gates. This file explains what that floor means, what it does not, and how to keep it from becoming theater.
Table of contents
The floor
Per ADR-005, the test gate requires at least 50% line coverage and must pass before any merge. Below the floor, the build fails and the PR cannot land.
It is deliberately a floor, not a goal. Fifty percent is the minimum at which a suite is doing meaningful work; it is not an aspiration to stop at, nor a ceiling to chase to 100%. Teams may set a higher per-package threshold where risk warrants — they may never set a lower one.
Read it as risk, not as a target
A coverage percentage is a proxy, and proxies are gameable. Read it correctly:
- Lines are the cheapest signal. Line coverage says a line ran, not that its behavior was checked. High line coverage with weak assertions is weak testing wearing a green badge.
- Direct coverage at code that breaks badly. Payments, auth, data integrity, and irreversible actions deserve coverage long before glue code does. Find the uncovered branches there first.
- A covered line with no assertion is uncovered in spirit. If removing the
expectwould not fail the test, the line is decorative. - 50% of the right code beats 90% of the wrong code. Use the report to find risky gaps, not to manufacture a number.
When asked “what’s our coverage gap?”, the answer is never “raise the threshold.” It is “here are the next N uncovered business-critical branches, ranked by the cost of them breaking.”
Anti-gaming rules
These keep the floor honest:
- No assertion-free tests to walk lines. A test that renders a component and asserts nothing is padding, not coverage.
- No snapshot-only suites for behavior. Snapshots catch unintended markup change; they do not verify behavior and should not be the only test for a component.
- No
/* istanbul ignore */to hide real logic. Ignore comments are for genuinely untestable lines (defensivedefault:on an exhaustive switch), not for skipping hard cases. - No coverage on the test files themselves, fixtures, or mocks counted toward the number.
Exclusions
Exclude code that produces noise rather than signal. Configure these out of the coverage denominator:
- Generated code —
*.gen.ts,routeTree.gen.ts, codegen output, OpenAPI/Zod-generated types. - Type-only files —
*.d.ts, pure type/interface modules with no runtime. - Barrel files —
index.tsre-exports. - Config and build scripts —
vite.config.ts,*.config.*, tooling. - Story files and test utilities —
*.stories.tsx,test/,__mocks__/. - Trivial constant maps and enums with no logic.
Excluding glue is not gaming — it focuses the percentage on code where a test could actually find a bug.
The full release gate
Coverage is one check among several. ADR-005 requires all of these to pass before merge:
| Gate | What it checks |
|---|---|
pnpm typecheck | No type errors |
pnpm build | Builds clean |
pnpm lint | Lint clean |
pnpm test | Tests pass, >=50% line coverage |
| jest-axe | No new WCAG 2.2 AA violations |
| Lost Pixel | No unreviewed visual regression (never Chromatic) |
| Bundle budget | Bundle size within budget |
| Docs gate | Story present + a docs page (ADR-021) |
A PR is releasable only when every row is green. The coverage floor is necessary, not sufficient — passing it while failing jest-axe or Lost Pixel still blocks the merge.
See the source of record: ADR-005: Accessibility & Release Gates.