### Mode: coverage-check

<!-- opt-in-capability: none — a read-only gate entry; declaring the gate matrix is covered by gates-declaration -->

The **final-run checker** (strip-the-kit D3(c)+(d)) — two deterministic arms over ONE fixed artifact path, every refusal naming its locations `file:line`, never a bare count. It reads the lcov file the declared `unit-tests` gate cmd produced at `<git dir>/agent-workflow-lcov.info` (the constant this tool exports; `AW_LCOV_FILE` overrides, a test seam; the git dir is outside the fingerprint domain and never committable by construction) and prints `coverage-check: lcov-sha256=<hex|none>` — the sha of the EXACT bytes it consumed, which the `run-gates --final` receipt binds and re-hashes (exactly ONE such line attests).

Run `node ${CLAUDE_SKILL_DIR}/tools/coverage-check.mjs --check [--cwd <dir>]`:

0. **Attestation precondition (the provenance arm).** An lcov on disk carries no evidence of the tree it came from, so reading one and issuing a verdict certifies whatever happens to be there — the false GREEN direction is the dangerous one, because a line appended AFTER the suite ran has no `DA` entry and therefore reads non-executable ("nothing to cover"). Provenance is a CONSEQUENCE in exactly one context: a `run-gates --final` run deletes the artifact before any gate spawns. That runner mints a random nonce and writes `final-start.attempt` as a ONE-WAY COMMITMENT over `{nonce, tree fingerprint, base}`; the raw nonce rides the environment to this child, which recomputes the commitment and requires the record to carry it. Neither half suffices alone — a bare nonce is unverifiable, a persisted attempt id is reconstructible from public repo state — and the commitment is also the only place the BASE is bound, since no record stores it. The raw nonce is stripped from the red-proof probe environment so no descendant retains a live capability. `attested=` states whether a coverage VERDICT was ISSUED — pass **or** fail — never whether coverage passed: a valid handshake over an lcov that lists uncovered lines still reads `attested=yes` and still exits 1. Outcomes: **attested** → the coverage verdict is issued; **no handshake** → `attested=no` + `NO VERDICT` (exit 0, findings still printed, uncovered lines still exit 1 — the findings contract is unchanged); **a valid handshake over a run that read NO lcov BYTES** (the file is absent, or the path was refused as a non-regular file) → `attested=no` + `NO VERDICT`: the run owned the artifact's lifetime and read nothing, so it certifies NOTHING — reading `yes` there would be the false green this arm exists to close, one layer up. The predicate is the consumed bytes (`lcov-sha256` is a digest, not `none`), never the skip flag, so a refused path can never attest either. The two halves are independent: WITHHOLDING the verdict never changes an exit code — an absent file stays exit 0 (the loud `skipped-no-lcov`), and the refused non-regular path keeps its OWN fail-closed exit 1; **a handshake describing another tree or matching no recorded attempt** → `REFUSED` (exit 1), never a verdict in either direction. One fully anchored `coverage-check: attested=<yes|no>` machine line rides every run, on the same exactly-once contract as the sha line — and a withheld verdict TRAVELS: `run-gates` carries it as `coverage=not-run` on the summary line and names it on the checker's table row, and `core-evidence summary` never renders an unqualified GREEN over a final record that consumed no lcov. Stated residuals, both named rather than implied: (a) an operator who runs both processes can forge the store or the code — the kit's standing self-discipline posture, not a security boundary; (b) **"the run owns the artifact" is exclusive by CONVENTION over the fixed path, not enforced** — a writer outside the run (a second `run-gates`, a hand-run `--only unit-tests`, an orphaned test process) can place foreign evidence between the deletion and the checker's read, and every check then agrees. Closing (b) needs an attempt-unique artifact path, which the runner can name but the declared producer cmd must reference — queued as LCOV-EXCLUSIVE-OWNERSHIP. What this arm removes is the false green that needs no second process and nobody trying: evidence that predates the edit.
1. **Coverage arm (D3(d)):** every CHANGED executable Node line (`.mjs`/`.cjs`/`.js`, tracked working-vs-HEAD changes + untracked-not-ignored files) must be covered — uncovered lines are LISTED `file:line` and fail; a changed file ABSENT from the lcov map is a file-level red (never "non-executable" by silence); changed out-of-domain files (e.g. `.sh`) and unsupported-source files (e.g. `.ts`) are LISTED — the claim is narrowed honestly, not widened. NO lcov file at the path = a LOUD `skipped-no-lcov` (exit 0, stated — produce the file via the unit-tests gate's lcov reporters); a symlink at the path is a refusal (lstat, no-follow).
2. **Red-proof arm (D3(c)):** every authoritative current-base `red-proof` declaration must verify — the bound test file exists (deleted fails), its content sha256 matches the declaration (custody), the test resolves (zero-match fails) and runs green N/N NOW, and the declaration's pre-fix fingerprint differs from the current tree (equal = reuse/forgery, refused). A malformed evidence store fails CLOSED.

Wire it as the LAST declared gate in `docs/ai/gates.json` — `run-gates --final` REFUSES a declaration where the canonical coverage-check gate is not last (nothing may run after the checker consumed the lcov) or where its cmd is not ONE plain invocation of the kit's OWN tool (a masked form or a lookalike path never counts).

**Invariants:** writes nothing · spawns read-only `git` queries + the bound-test probes (`node --test`, shell-free) · no network · exit 0 pass / 1 fail (locations listed) / 2 usage.
