skills/verifying-change-coverage/SKILL.md
Verifies that the lines and branches a change actually touched are executed by tests, using LCOV or Cobertura diff coverage instead of whole-repo percentages, and escalates uncovered high-risk changes into a blocking finding. Use when a pull request needs a coverage gate that unrelated tests cannot satisfy, when total coverage looks healthy but the diff is untested, when wiring diff coverage into CI, or when someone claims a change is covered because the suite is green.
npx skillsauth add jaktestowac/awesome-copilot-for-testers verifying-change-coverageInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Use this skill to answer one question honestly: were the lines this change introduced actually executed by a test?
Repo-wide coverage cannot answer it. A repo at 84% can merge an untested payment path and stay at 84%, because a big denominator absorbs a small numerator. Diff coverage changes the denominator to the lines you just wrote, which is the only denominator that maps to the risk you just added.
The distinction that runs through this skill: configured is not verified. A test runner in package.json proves the practice exists. Executed lines prove this change was tested. Report which of the two you measured.
if never taken is half-tested.unslop-tests - a diff-coverage gate is exactly the pressure that produces coverage theatre.The changed lines.
git diff <base>...HEAD --unified=0 -- '***.ts' '***.tsx'
--unified=0 gives added-line ranges with no context, which is what you want to intersect against coverage. Keep the file → line-numbers map; discard removed lines, generated files, and anything the contract excludes.
The coverage artifact. Produce one if it does not exist:
npx vitest run --coverage --coverage.reporter=lcov # → coverage/lcov.info
npx jest --coverage --coverageReporters=lcov
npx playwright test # + c8/istanbul instrumentation for E2E coverage
See ./resources/coverage-artifacts.md for the formats, the merge problem across suites, and the monorepo path pitfalls.
If no artifact can be produced: stop and say so. Report static linkage instead, labelled as static linkage, and state what it cannot tell you. Then make producing an artifact the first remediation item - this is the single highest-leverage change to a coverage story.
For each changed source file, intersect its added-line numbers with the executed lines in the report. Produce, per file:
import statements)Diff coverage = covered ÷ changed executable lines, per file and overall. Compute branch coverage on changed lines separately; do not average it into the line number.
The exclusions matter and are the most common source of a wrong figure - see ./resources/coverage-artifacts.md for what counts as an executable line in TypeScript once it has been compiled or transformed.
Never hand over a raw list. Group contiguous uncovered lines and judge each group:
| Class | What it is | Action |
| --- | --- | --- |
| Untested logic | branches, calculations, validation, error paths | write the test - this is the finding |
| Untested integration | code only reachable with a real dependency | integration test, or a documented exception |
| Defensive | default: on an exhaustive switch, never guards, invariant throws | acceptable; record why |
| Instrumentation | logging, metrics, tracing calls | acceptable |
| Unreachable | dead code | delete it rather than test it |
| Hard to reach | needs an exotic environment or a failure that cannot be simulated | exception with an owner and an expiry |
The first two are findings. The rest are exceptions and must be recorded, not silently subtracted - see ./resources/exceptions-and-thresholds.md.
Combine diff coverage with the risk tags from scoping-change-relevance:
| Condition | Verdict |
| --- | --- |
| Changed lines below threshold and the file carries an escalation tag (auth, critical-path, db-migration, new-endpoint) | BLOCK |
| Changed lines below threshold on ordinary source | WARN |
| Threshold met but changed branches materially uncovered | WARN |
| Threshold met, uncovered lines all classified as acceptable exceptions | OK with the exceptions listed |
| No coverage artifact available | INFO - static linkage only, artifact required |
The escalation rule is the reason this beats a flat percentage: 70% on a logging module and 70% on session handling are not the same result, and one number cannot say so.
Report per file, worst first: changed lines, diff coverage, branch coverage on changed lines, and the uncovered groups with their class and a one-line judgement. Point at exact line ranges - src/pricing.ts:142-149 - so the fix needs no hunting.
Finish with the two sentences that make the report honest:
<artifact>, produced by <which suites>../resources/ci-wiring.md has working GitHub Actions and GitLab CI jobs, the base-ref fetch depth that trips everyone up on the first attempt, artifact merging across suites, and the sticky-PR-comment pattern.
Three rules for the gate itself:
|| true on a coverage step is worse than no gate, because it reports green.unslop-tests before celebrating./* istanbul ignore */. An exclusion with no reason and no owner is a waiver that skipped the register../resources/coverage-artifacts.md - LCOV and Cobertura formats, generating them per runner, merging across suites, what counts as an executable line, monorepo path pitfalls./resources/exceptions-and-thresholds.md - thresholds by profile, legitimate exception classes, how to record an exclusion with an owner and an expiry./resources/ci-wiring.md - GitHub Actions and GitLab CI jobs, base-ref fetching, artifact merge, sticky PR comment, warn-then-block rolloutscoping-change-relevance - supplies the risk tags that turn a below-threshold result into BLOCK rather than WARNunslop-tests - the necessary counterweight: coverage proves execution, this proves the tests assert somethingwriting-unit-tests - when the finding is untested logic and tests have to be writtenderiving-a-quality-contract - where the diff-coverage threshold for this project is setgoverning-quality-waivers - when an uncovered area needs a recorded, dated exceptionanalyzing-quality-metrics - for coverage's caveats as a metric and what to report alongside itThis skill is complete when:
testing
Tests the customization assets themselves - skills, prompts, custom agents, instructions - the way a product is tested: activation cases that check an asset fires when it should and stays quiet when it should not, output-contract cases, safety cases, collision cases between assets competing for the same trigger, a weighted rubric scored blind, and a baseline-versus-candidate gate before an edit ships. Use when a skill is edited and nobody knows whether behaviour changed, when two skills fight over the same request, when a description is being tuned for discoverability, when a collection has grown past manual spot-checking, or when the request mentions skill evals, prompt regression, or "does this skill actually work".
development
Shapes QA output for the person who has to act on it: result and blocker in the first two lines, one decision per report, findings ordered by what they cost, the long artifact in a file and the decisions in the message, and magnitude stated in units the reader can count. Use when a report is accurate but nobody acts on it, when a finding set is too long to read under time pressure, when the same findings must be retold for a developer, a release manager, and an on-call engineer, or when the request mentions "too long", "make this readable", "just tell me what to do", "so what", or "summarize this for stakeholders". Pairs with unslop-answers, which makes the same report honest.
development
Cuts AI tells from test code: tests that pass without proving anything, tautological assertions, mock-only tests, hardcoded waits, coverage theater, vague names, swallowed errors, retries used as fixes. Use whenever test code is written, changed, or reviewed, including tests produced as a side effect of a feature task, and when the request mentions "review these tests", "are these tests any good", "this test always passes", "this suite is flaky", or "clean up these tests". Must always apply to test code.
development
Cuts AI tells from what the agent says about its own work: completion claimed without a run, invented file paths and API names, terminal output that was never produced, findings with no location, percentages with no denominator, absence claimed from one grep, effort narration instead of results, hedge stacking, buried blockers, puffery in a bug title. Use whenever reporting a result, a fix, a review finding, a test outcome, a coverage or flake number, a root cause, or a release recommendation, and when the request mentions "prove it", "did you actually run it", "be specific", "no fluff", "stop hedging", or "is this real". Must always apply to answers about your own work.