# V8 Coverage Counter Contract Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Publish risk-coverage artifact schema version 3 and continuously verify the installed Vitest/V8 producer's counter-bearing/counterless row semantics in an isolated child run. **Architecture:** A real CLI contract test owns the serialized artifact assertion. A standalone producer checker copies fixed source templates into one OS-temp root, creates its child config and report there, validates an exact JSON summary, bounds child diagnostics, and removes the owned root in `finally`. `test:coverage` invokes the checker before repository coverage, which also carries it into CI and sample removal. **Tech Stack:** TypeScript 7, Node.js 24 child processes and filesystem APIs, Vitest 4, V8 coverage. ## Global Constraints - Policy schema remains version 2; serialized risk-coverage artifact schema becomes version 3. - Child root, config, and reports directory are all below one owned OS temporary directory. - Main Vitest must not discover the child `.fixture.ts` file. - Child exit, summary absence, malformed/missing/additional rows, counterless nonzero drift, and runtime all-zero drift fail closed. - Child stdout/stderr included in diagnostics is bounded. - Cleanup uses `finally` and targets only the exact owned temporary root. - Source edits use `apply_patch`; behavior changes follow RED-GREEN TDD. --- ### Task 1: Version the real serialized artifact **Files:** - Modify: `tests/unit/risk-coverage.test.ts` - Modify: `scripts/check-risk-coverage.ts` **Interfaces:** - Consumes: the real `check-risk-coverage.ts` CLI, current policy structure, and an exact temporary coverage summary. - Produces: serialized artifact schema version 3 with `counterBearingTotal`, `instrumentedCounterBearingTotal`, `counterlessTotal`, and `counterlessModules` only. - [x] **Step 1: Add the actual CLI serialization contract test.** Create a temporary repository with the 19 current policy paths, write each as `export const covered = true`, set the cloned policy baseline to 19, write one full counter row per module, run the CLI with `process.execPath`, and assert: ```ts expect(artifact).toMatchObject({ schemaVersion: 3, counterBearingTotal: 19, instrumentedCounterBearingTotal: 19, counterlessTotal: 0, counterlessModules: [], }); expect(artifact).not.toHaveProperty("executableTotal"); expect(artifact).not.toHaveProperty("instrumentedExecutableTotal"); expect(artifact).not.toHaveProperty("nonExecutableTotal"); expect(artifact).not.toHaveProperty("nonExecutableModules"); ``` - [x] **Step 2: Run the single test and verify RED.** Run: `./node_modules/.bin/vitest run tests/unit/risk-coverage.test.ts -t "publishes artifact schema version 3" --reporter=dot` Expected: FAIL because the actual artifact contains `schemaVersion: 2`. - [x] **Step 3: Change only the serialized envelope to version 3.** Change `schemaVersion: 2` to `schemaVersion: 3` in the value passed to `writeRiskCoverageArtifactAtomic`; do not change policy parsing. - [x] **Step 4: Re-run the single test and verify GREEN.** Run the Step 2 command and expect one passing test. ### Task 2: Lock actual Vitest/V8 counter semantics **Files:** - Create: `tests/fixtures/v8-coverage-counter-semantics/counter-semantics.fixture.ts` - Create: `tests/fixtures/v8-coverage-counter-semantics/src/runtime.ts` - Create: `tests/fixtures/v8-coverage-counter-semantics/src/import-type-empty.ts` - Create: `tests/fixtures/v8-coverage-counter-semantics/src/import-empty.ts` - Create: `tests/fixtures/v8-coverage-counter-semantics/src/import-side-effect.ts` - Create: `tests/fixtures/v8-coverage-counter-semantics/src/import-value.ts` - Create: `tests/fixtures/v8-coverage-counter-semantics/src/reexport-named.ts` - Create: `tests/fixtures/v8-coverage-counter-semantics/src/reexport-star.ts` - Create: `tests/fixtures/v8-coverage-counter-semantics/src/type-only.ts` - Create: `tests/unit/v8-coverage-counter-semantics.test.ts` - Create: `scripts/lib/v8-coverage-counter-semantics.ts` - Create: `scripts/check-v8-coverage-counter-semantics.ts` - Modify: `vitest.config.ts` **Interfaces:** - Produces: `assertV8CoverageCounterSemantics(summary, fixtureRoot)` and `checkV8CoverageCounterSemantics(options?)`. - Consumes: fixed fixture templates, owned temp paths, a shell-free Vitest child result, and `coverage-summary.json`. - [x] **Step 1: Add fixture templates and failing checker tests.** The fixture test imports the seven counterless modules and observes the direct/named/star runtime values. The unit tests use literal summaries to require exact rows and mutate them for missing row, extra row, counterless nonzero, and runtime all-zero failures. Runner tests inject child exit and successful-without-summary results and require bounded diagnostics plus removal of the owned root. - [x] **Step 2: Run the new unit file and verify RED.** Run: `./node_modules/.bin/vitest run tests/unit/v8-coverage-counter-semantics.test.ts --reporter=dot` Expected: FAIL because `scripts/lib/v8-coverage-counter-semantics.ts` does not exist. - [x] **Step 3: Implement exact summary validation and owned child execution.** The default runner executes: ```ts execFile(process.execPath, [ path.join(repositoryRoot, "node_modules/vitest/vitest.mjs"), "run", "--config", configPath, "--coverage", "--reporter=dot", "--no-color", ], { cwd: ownedRoot, timeout: 30_000, maxBuffer: 256 * 1024 }); ``` The generated config has `root`, `include`, `coverage.reportsDirectory`, and `coverage.include` paths inside the owned root. Always remove the root in `finally`. - [x] **Step 4: Add a behavioral main-discovery assertion.** Run main `vitest list` filtered to the fixture directory with `--filesOnly --passWithNoTests`; require empty stdout. Add an explicit fixture-directory exclude in `vitest.config.ts`. - [x] **Step 5: Run the new unit file and standalone checker for GREEN.** Run: ```sh ./node_modules/.bin/vitest run tests/unit/v8-coverage-counter-semantics.test.ts --reporter=dot node scripts/check-v8-coverage-counter-semantics.ts ``` Expected checker output: `V8 coverage counter semantics: PASS (1 counter-bearing, 7 counterless)`. ### Task 3: Wire coverage/CI and refresh documentation **Files:** - Modify: `package.json` - Modify: `docs/testing/frontend-platform-testing-strategy.md` - Modify: `.superpowers/sdd/2026-08-01-quality-architecture-remediation/task-1-report.md` - Modify: `.superpowers/sdd/2026-08-01-quality-architecture-remediation/progress.md` **Interfaces:** - Consumes: `check:v8-coverage-counter-semantics` and existing FE-GATE-005 `test:coverage` step. - Produces: package/CI/sample-removal execution and current 19-module/80-threshold documentation. - [x] **Step 1: Add the package checker and prepend it to `test:coverage`.** ```json "check:v8-coverage-counter-semantics": "node scripts/check-v8-coverage-counter-semantics.ts", "test:coverage": "corepack pnpm check:v8-coverage-counter-semantics && vitest run ..." ``` - [x] **Step 2: Synchronize documentation.** Replace stale `12개 high-risk module` and `52개 scoped threshold` with `19개` and `80개`; document artifact schema 3 and policy schema 2 separately. - [x] **Step 3: Run full relevant verification.** ```sh ./node_modules/.bin/vitest run tests/unit/risk-coverage.test.ts tests/unit/risk-coverage-files.test.ts tests/unit/v8-coverage-counter-semantics.test.ts tests/unit/bounded-body-reader.test.ts --reporter=dot ./node_modules/.bin/tsc --noEmit -p tsconfig.node.json ./node_modules/.bin/tsc --noEmit -p tsconfig.test.json ./node_modules/.bin/eslint scripts/check-risk-coverage.ts scripts/check-v8-coverage-counter-semantics.ts scripts/lib/v8-coverage-counter-semantics.ts tests/unit/risk-coverage.test.ts tests/unit/v8-coverage-counter-semantics.test.ts vitest.config.ts --max-warnings=0 corepack pnpm check:v8-coverage-counter-semantics node scripts/check-risk-coverage.ts corepack pnpm test:sample-removal git diff --check ``` - [x] **Step 4: Commit the verified closeout.** ```sh git add package.json vitest.config.ts scripts/check-risk-coverage.ts scripts/check-v8-coverage-counter-semantics.ts scripts/lib/v8-coverage-counter-semantics.ts tests/fixtures/v8-coverage-counter-semantics tests/unit/risk-coverage.test.ts tests/unit/v8-coverage-counter-semantics.test.ts docs/testing/frontend-platform-testing-strategy.md docs/superpowers/plans/2026-08-02-v8-coverage-counter-contract.md git commit -m "test: lock V8 coverage counter semantics" ``` ## Self-review - Spec coverage: artifact versioning, actual producer rows, discovery isolation, every fail-closed path, bounded diagnostics, cleanup, coverage/CI linkage, sample-removal preservation, and documentation counts are assigned. - Placeholder scan: no deferred implementation remains. - Type consistency: parser and runner names match in tests, script, and plan.