ADR 0003 — Coverage policy: 100%, honestly
Status: accepted (2026-08)
Decision
CI enforces 100% line and 100% branch coverage on shipped libraries
(build/check-coverage.ps1 over ReportGenerator's JsonSummary, filtered to +Emissary*;-*.Tests).
Permitted exclusions, and nothing else:
- Compiler-generated code without sequence points.
[ExcludeFromCodeCoverage]with a justification comment on the attribute — reviewed like code. Legitimate uses: defensive throws that are unreachable by construction, platform-specific branches CI cannot execute, thin network-I/O shells exercised by the live smoke suite.- Compiler-artifact branches baselined in
build/coverage-baseline.json— each entry names the exact source line and the reason, and is reviewed like code. Only branches proven unreachable from source qualify (e.g. async-iterator dispose-mode resume checks); line coverage is never baselined.
Coverage proves code ran; it does not prove tests assert anything. Mutation testing is the intended
quality guard, but Stryker.NET cannot run Microsoft.Testing.Platform (TUnit) tests
(stryker-mutator/stryker-net#3094), so no Stryker tooling is kept in the repo — dead config rots.
Re-adopt when that issue closes (tool install + config + a PR-only CI job with
thresholds.break = 100 is ~20 minutes of work). Until then, reviews watch for assertion-free
tests manually.
Consequences
- A single uncovered line fails the build — by design, from the first commit.
- Samples and test projects are outside the gates.
- New code ships with its tests in the same PR; there is no "add tests later" state.