fix(#4656): expose coverage.unclassified and widen the zero-applicable guards (#4800)

* fix(#4656): expose coverage.unclassified and widen the zero-applicable guards

* fix(#4656): regenerate golden coverage fixtures and update the rollup pin

Emitted-Drift-Ack-Growth: spec-phase.md — #4656: guard widened to the all-unclassified case, doc claim corrected
Emitted-Drift-Ack-Growth: ui-phase.md — #4656: guard widened identically

* fix(#4656): sync edge-probe doc blocks and coverage pins with the new field

* fix(#4656): key the mandatory confirmation on the widened guard

* docs(#4656): backfill changeset PR number

---------

Co-authored-by: sim <sim@local>
This commit is contained in:
Tom Boucher
2026-09-16 10:33:32 -04:00
committed by GitHub
parent caecaec62e
commit 3014775a3f
14 changed files with 515 additions and 53 deletions

View File

@@ -69,6 +69,11 @@ export interface CoverageReport<V extends string = string> {
applicable: number;
resolved: number;
unresolved: number;
/** #4656: items in the soft-signal `unclassified` category. Subset of
* `applicable`; a spec where every requirement is unclassified reports
* `unclassified === applicable`, which is the signal the zero-applicable
* guards in spec-phase/ui-phase widen on. */
unclassified: number;
byVerification: Record<string, number>;
};
}
@@ -281,6 +286,12 @@ export function analyzeCoverage<V extends string>(
const unresolved = merged.filter((i) => i.status === 'unresolved').length;
const applicable = merged.length;
const resolved = applicable - unresolved; // closed set: resolved-status + dismissed
// #4656: the unclassified soft-signal rows count toward `applicable` (the
// rollup is count-preserving and `resolved = applicable - unresolved` is a
// documented identity), so the count is exposed as a SIBLING field — the
// zero-applicable guards can then also fire when EVERY requirement is
// unclassified, the case the spec-phase/ui-phase docs promise to catch.
const unclassified = merged.filter((i) => i.category === 'unclassified').length;
const byVerification: Record<string, number> = {};
for (const tier of validators.verification) byVerification[tier] = 0;
for (const i of merged) {
@@ -288,7 +299,7 @@ export function analyzeCoverage<V extends string>(
byVerification[i.verification] = (byVerification[i.verification] ?? 0) + 1;
}
}
return { items: merged, coverage: { applicable, resolved, unresolved, byVerification } };
return { items: merged, coverage: { applicable, resolved, unresolved, unclassified, byVerification } };
}
/* ------------------------------------------------------------------------- *