feat(core-shared/conformance): manifest coverage schema + vitest helper
First implementation milestone of the agent-first coverage architecture (ADR-020, PRD 2026-05-13). Lands the keystone — coverage bands as a typed declaration in feature.manifest.ts plus a helper that derives vitest threshold shapes from them. New file packages/core-shared/src/conformance/coverage.ts (self- contained, no relative imports — loadable at vitest config time): - CoverageBand / CoverageBands / CoverageManifest / VitestThresholds types - DEFAULT_COVERAGE_BANDS (baseline 80/75/80/80; entities 100/100/100/ 100; use-cases + controllers 100/95/100/100) — matches ADR-011 - DEFAULT_MUTATION_SCORE (80) + DEFAULT_MUTATION_TARGETS (entities + use-cases) - getCoverageBands / getMutationConfig — manifest -> resolved bands, with default fallback for missing layers - vitestThresholdsFromBands / vitestThresholdsFromManifest — convert to vitest's coverage.thresholds shape with the layer-to-glob mapping define-feature.ts gains the optional coverage field on FeatureManifest (imports its type from coverage.ts to avoid a relative-import cycle at config-load time). Exposed via two subpaths: @repo/core-shared/conformance (re-exports for source/test code) and @repo/core-shared/conformance/coverage (direct subpath safe to load from vitest configs, bypasses the index re-export chain that Node ESM doesn't auto-extension-resolve). Auth wired as proof-of-concept: - packages/auth/src/feature.manifest.ts declares its coverage section - packages/auth/vitest.config.ts imports the helper + DEFAULT_COVERAGE_BANDS and emits thresholds via vitestThresholdsFromBands(DEFAULT_COVERAGE_BANDS) — no more hand-maintained per-glob thresholds block. Verified: 175/175 tests pass; 14/14 typechecks clean; auth coverage green (21 tests, 93.77% overall, all per-layer 100% bands hold). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
import type { CoverageManifest } from "./coverage";
|
||||
|
||||
/**
|
||||
* Per-use-case manifest entry. Declares what the use case does at the contract
|
||||
* level: whether it mutates state, what audit events it emits, what cross-feature
|
||||
@@ -14,6 +16,10 @@ export type UseCaseManifest = {
|
||||
/**
|
||||
* The feature-level manifest. One per feature package, conventionally exported
|
||||
* as `<featureName>Manifest` from `src/feature.manifest.ts`.
|
||||
*
|
||||
* `coverage` is optional for backward compatibility — features without a
|
||||
* declared coverage section fall back to `DEFAULT_COVERAGE_BANDS` via
|
||||
* `getCoverageBands(manifest)` (see `./coverage.ts`).
|
||||
*/
|
||||
export type FeatureManifest = {
|
||||
readonly name: string;
|
||||
@@ -21,6 +27,7 @@ export type FeatureManifest = {
|
||||
readonly useCases: { readonly [k: string]: UseCaseManifest };
|
||||
readonly realtimeChannels: readonly string[];
|
||||
readonly jobs: readonly string[];
|
||||
readonly coverage?: CoverageManifest;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user