Expand description
Intent coverage: which work makes which intent criterion true, derived from the plan.
An intent names the milestones that realise it and the criteria that settle it; an issue
names, in serves, the <intent>#<criterion> it exists to make true. Neither side stores
the join. This module derives it on every read and refuses the shapes that mean the plan
does not carry the intent (ADR 0073):
- a criterion no live issue serves is uncovered — nothing will make it true;
- an issue under an intent’s milestone that serves nothing has no purpose under it;
- an issue that serves a criterion of an intent whose milestones do not include its own milestone serves it from outside the intent’s plan;
- a reference to an intent or a criterion that does not exist is a dangling link.
Three weaker shapes are warnings, because they are sometimes right and always worth a look: a criterion whose every serving issue requires no evidence is only weakly covered; a milestone an intent names that serves none of its criteria contributes nothing yet; two live issues serving one criterion over overlapping scope are duplicate work.
An issue under a milestone no intent names is maintenance work. It is reported with that origin, never invented an intent, and never a finding.
The derivation is pure over an IntentOutline per intent and the derived Plan, so a
test can walk every branch without an index, and the intent engine converts its own record
into an outline rather than this module reading intent files a second way.
use majordomus_cli::intent_plan::{coverage, CoverageStrength, IntentOutline};
use majordomus_cli::plan::Plan;
let intent = IntentOutline {
id: "x".into(),
criteria: vec!["a".into(), "b".into()],
milestones: vec!["m".into()],
..Default::default()
};
let covered = coverage(&[intent], &plan);
// I1 serves x#a, so that criterion is carried; x#b is not, and that is a failure.
assert_eq!(covered.criterion("x", "a").unwrap().strength, CoverageStrength::Covered);
assert_eq!(covered.criterion("x", "b").unwrap().strength, CoverageStrength::Uncovered);
assert_eq!(covered.failures(), 1);Structs§
- Covering
Issue - One issue as coverage sees it: which milestone carries it, the status the plan derived for it, and how much evidence it owes before it may be DONE.
- Criterion
Coverage - One criterion of one intent, and the work that carries it: the live issues that serve it, the milestones those issues sit under, and the strength derived from them.
- Intent
Coverage - The whole derived coverage: every criterion of every live intent, every issue with the reason it exists, and every finding the two produced. Nothing here is stored; it is derived on each read from the intents and the plan.
- Intent
Outline - What coverage needs of one intent: its identity, its criterion ids, its milestones, and whether it is retired (cancelled or superseded) and so owes nothing.
- Issue
Purpose - The answer to “why does this issue exist?”: the criteria it declares it serves, the intents whose milestones contain it, and which of the three origins that adds up to.
Enums§
- Coverage
Strength - How well a criterion is carried by the plan: whether work exists for it, whether that work is gated by evidence, and whether the recorded gap already saw it true.
- Issue
Origin - Why an issue exists: because it serves a criterion, because it is maintenance under a milestone no intent names, or because nobody said — which is a failure under an intent.
Functions§
- coverage
- Derive the coverage of
intentsbyplan. - serves_
token - Is
tokenan<intent-id>#<criterion-id>reference: two lowercase slugs joined by one#? The same pattern the issue schema declares forserves.