Rendered from docs/obligations/0071-a-corpus-scoped-check-makes-the-coverage-rule-unreachable.md in the Headwater
corpus. Every document on this half of the site is typed by the taxonomy
the descriptor names: corpus.json.
A corpus-scoped check makes the coverage rule unreachable
Context
Spec 12 offers Corpus as a scope. It also rules that a classified document with zero instances is a finding, which is OB-COV-2 of spec 4. The two meet badly. A corpus-scoped instance reads every document, so coverage counts every document as checked, and that finding can never fire again.
Obligation
What is open is the rule for the first real corpus-scoped check. Either such an instance counts toward coverage for no document, or it counts only for the documents that its findings name.
Discharge
The first of the two options holds. A corpus-scoped instance counts toward coverage for no document.
Coverage counts routing, and routing is the generation step: a template, a declaration, and one instance per target. A document-scoped instance covers its document, and an edge-scoped one covers both endpoints. A corpus-scoped instance has one target, and that target is the corpus, so it accounts against no document whatever it read. Grain::routes in engine/crates/check/src/scope.rs carries the ruling. The match over the five grains is exhaustive, so a sixth grain answers this question rather than inherits an answer.
Spec 12 states it, and one test holds it. identifier.claimed_twice is the first corpus-scoped check, it reads check/spec/03-no-instance.md, and the coverage finding against that file survives.
The second option is refused. An instance that counted only for the documents its findings name makes coverage a function of the verdict. A rule that finds nothing then covers nothing, and a corpus with a defect reports higher coverage than a clean one.
The record is one instance larger, and the newest one is the first that took documents away from the account. link.fragment.unresolved moved from Document to Corpus when it widened to read a fragment on a resolving path (HW-OBL-0077). Its 312 document-routed instances became 1. Nothing became unchecked here, because facet.required.missing reports one instance against every classified document of this corpus and skips none. That is a fact about this corpus. A shelf in an adopting corpus whose kind requires no facet could lose its only routed check to a move of this shape. No instrument would say so before the coverage finding appeared.
One cost stands. A rule that instantiates over every typed document reaches the unreachable end by a shorter route. Such a rule routes every document to a check before anything is read. The generated Shape checks instantiate per kind for that reason, so a kind that forbids what a rule reads gets no instance.
What happens next is the closure of this record, which is why it reads build. The question is answered, Grain::routes carries the answer, spec 12 states it and one test holds it. Nothing further is owed by the engine or by the specification. What remains is the state movement of this record to discharged, and that is the owner's to take rather than an agent's.
This record is discharged. The roadmap review of 2026-09-30 read the tree again. Grain::routes in engine/crates/check/src/scope.rs returns false for the corpus grain, spec 12 states the rule, and a test holds it. The owner accepted the discharge on 2026-09-30, in the roadmap review of that day.