# Coverage is derived

> Rule coverage is a set derived over the grid the architecture page builds in what can drift, seen through how it drifts.

Page: Methodology · Verify
Canonical: https://banes-lab.com/disciplined-methodology/verify#coverage-is-derived

This section is stop 49 of 102 in the learning route. Previous: [34 - Moves and renames](https://banes-lab.com/disciplined-methodology/verify/moves-and-renames.md). Next: [01 - Validation gates](https://banes-lab.com/pag/validation/validation-gates.md). It builds on [18 - The gate holds the line](https://banes-lab.com/disciplined-methodology/build/the-gate-holds-the-line.md), [30 - One correct answer](https://banes-lab.com/disciplined-methodology/verify/one-correct-answer.md).

Rule coverage is a set derived over the grid the architecture page builds in [what can drift, seen through how it drifts](https://banes-lab.com/software-architecture/coverage/what-can-drift-seen-through-how-it-drifts.md). Each cell pairs a dimension of the ontology axis, such as [identity](https://banes-lab.com/records/reason/node-ont-identity.md), [structure](https://banes-lab.com/records/reason/node-ont-structure.md), [relation](https://banes-lab.com/records/reason/node-ont-relation.md), [state](https://banes-lab.com/records/reason/node-ont-state.md) or [behaviour](https://banes-lab.com/records/reason/node-ont-behaviour.md), with a lens of the analysis axis, such as [structural](https://banes-lab.com/records/reason/node-ana-structural.md), [causal](https://banes-lab.com/records/reason/node-ana-causal.md) or [temporal](https://banes-lab.com/records/reason/node-ana-temporal.md). The walk that finds an empty cell is described in [a cell that resists an invariant](https://banes-lab.com/software-architecture/coverage/a-cell-that-resists-an-invariant.md). What this section adds is the rule side, shown in [J1·b one cell per rule](https://banes-lab.com/disciplined-methodology/verify#coverage-is-derived-panel-b): every rule declares the gate that observes it, or declares conduct together with the evidence a check would need, as shown in [J1·c gate or conduct](https://banes-lab.com/disciplined-methodology/verify#coverage-is-derived-panel-c). The conduct roster, whose vocabulary is typed in [J1·a the conduct roster](https://banes-lab.com/disciplined-methodology/verify#coverage-is-derived-panel-a), shrinks whenever a mechanism starts observing in an artifact what the developer or the model previously had to keep in mind. That shrinking is how this method defines progress.

### The grid and the roster

Coverage claimed from a count of rules says nothing about which drift classes the rules reach. A team believes its architecture is covered because it has many rules, and the failure that ships lives in a dimension no rule ever named. A rule stated without its cell has no address, so neither you nor the model can tell which drift it watches and which drift nothing watches.

For this reason coverage is a set derived over the grid of drift dimensions and lenses, and every rule declares either its gate or its conduct. The empty cells are counted, rather than the rules. In practice, every rule declares the check that observes it, or that no check can, and every conduct rule names the half of it that is decidable and whether that half has been built. The unbuilt halves are worked down to zero, and a gap found while building a gate is gated in the same run.

To check this, take any rule and name its dimension and its lens; a rule that fits no cell watches nothing in particular. Then find an empty cell and ask what would drift there unseen. A cell is watched only by a predicate that can fail, as described in [the check comes first](https://banes-lab.com/disciplined-methodology/build/the-check-comes-first.md).

Conduct is a closed question, not a softer state. A rule declares conduct when no construct in any artifact observes it, and the declaration stays falsifiable because each entry names what would have to become observable for the rule to gain a check. Many such rules have a half that is decidable, such as whether a surface conforms to its template, whether a set of readers resolves, or whether a report states the boundary of its own negative result. That half is recorded in a cell with a [closed vocabulary](https://banes-lab.com/records/arch/closed-vocabulary.md) of four values: observed, naming its gates; unbuilt, which counts as debt rather than a paragraph of explanation; none, with a reason taken from a closed set; and null, which means unassessed and is also a declared state. There are three reasons a half can be none: the subject is an act, no declared surface holds it, or the property cannot be evaluated on a member. The coverage report is then derived over the whole set: the gated rules with their gates, the conduct entries, the unassessed rows, which are exactly the entries whose cell is null, and the debt, which is exactly the unbuilt halves. No count is written by hand. Every number a reader wants is the length of one of those lists on the run that produced it.

The cell is filled by walking through questions, never by reading the entry. Does the half name a declared surface, or an imagined one? Is its subject an artifact or an act? Is the population non-empty, given that a check over an empty set is a green result that measures nothing? Can the property be evaluated on a member? Three of these questions take one search each, and only the fourth needs judgement. That changes how the roster reads: every entry looks like a judgement, yet most of them turn on a fact. The cell also holds the value while the entry holds the range, because an observing check is often narrower than the rule whose half it answers, and a bare id would claim more than the check covers.

Projected onto [correctness](https://banes-lab.com/records/arch/correctness.md), the same grid becomes the catalogue of test surfaces described in what can drift, seen through how it drifts, and the unknown verdict that an unmeasured surface receives, described in [unknown is not pass](https://banes-lab.com/disciplined-methodology/verify/unknown-is-not-pass.md), rests on it. A fresh walk of the roster compares against the kinds of finding the checks emit rather than against the list of checks, because a half gains an observer far more often as a new kind than as a new rule.

J1·a the conduct roster

```typescript
export type CheckableHalf =
| { readonly kind: "observed"; readonly by: readonly GateId[] }
| { readonly kind: "unbuilt" }
| { readonly kind: "none"; readonly because: "subject-is-an-act" | "no-declared-surface" | "not-evaluable" };

export interface ConductEntry {
readonly slug: RuleSlug;
readonly whatACheckWouldNeed: string;
readonly half: CheckableHalf | null;
}

export interface Coverage {
readonly gated: readonly { readonly slug: RuleSlug; readonly gate: GateId }[];
readonly conduct: readonly ConductEntry[];
readonly unassessed: readonly RuleSlug[];
readonly debt: readonly RuleSlug[];
}
```

J1·b one cell per rule

```mermaid
flowchart TB
dimensions["What can drift · identity, structure, relation, state, behaviour, and the rest"]
lenses["How it drifts · structural, causal, temporal, invariant, and the rest"]
cell["One cell · an invariant that must hold"]
watched["A predicate enforces it"]
unwatched["Declared unwatched, with the reason"]
empty["An empty cell · a drift class nothing watches"]
dimensions --> cell
lenses --> cell
cell --> watched
cell --> unwatched
cell -. never walked .-> empty
```

J1·c gate or conduct

```mermaid
flowchart TB
rule["A rule"]
gate{"Does an artifact observe it?"}
check["Names its check"]
conduct["Declared conduct · with the evidence a check would need"]
half{"Is a half of it decidable?"}
built["The half is gated, and the entry names its range"]
debt["The half is unbuilt · counted as debt"]
none["No checkable half · an act, not an artifact"]
rule --> gate
gate -- yes --> check
gate -- no --> conduct --> half
half -- built --> built
half -- unbuilt --> debt
half -- no --> none
debt -. worked to zero .-> built
```

## Links to

- [What can drift, seen through how it drifts](https://banes-lab.com/software-architecture/coverage/what-can-drift-seen-through-how-it-drifts.md)
- [Ont Identity](https://banes-lab.com/records/reason/node-ont-identity.md)
- [Ont Structure](https://banes-lab.com/records/reason/node-ont-structure.md)
- [Ont Relation](https://banes-lab.com/records/reason/node-ont-relation.md)
- [Ont State](https://banes-lab.com/records/reason/node-ont-state.md)
- [Ont Behaviour](https://banes-lab.com/records/reason/node-ont-behaviour.md)
- [Ana Structural](https://banes-lab.com/records/reason/node-ana-structural.md)
- [Ana Causal](https://banes-lab.com/records/reason/node-ana-causal.md)
- [Ana Temporal](https://banes-lab.com/records/reason/node-ana-temporal.md)
- [A cell that resists an invariant](https://banes-lab.com/software-architecture/coverage/a-cell-that-resists-an-invariant.md)
- [The check comes first](https://banes-lab.com/disciplined-methodology/build/the-check-comes-first.md)
- [Closed Vocabulary](https://banes-lab.com/records/arch/closed-vocabulary.md)
- [Correctness](https://banes-lab.com/records/arch/correctness.md)
- [Unknown is not pass](https://banes-lab.com/disciplined-methodology/verify/unknown-is-not-pass.md)

## Linked from

- [Well-formedness](https://banes-lab.com/pag/guide/well-formedness.md)
- [Rules with names](https://banes-lab.com/disciplined-methodology/start/rules-with-names.md)
