Files
agentic-dev-template/scripts/coverage/__fixtures__/sample-diff.patch
Danijel Martinek 412d994733 feat(coverage): pnpm coverage:diff script + L1 implementation
Lands L1 of the agent-first coverage architecture (ADR-020) — the
cover-the-diff gate. Reads a merged lcov + git diff against a base
ref, asserts every changed *executable* line was exercised.

Script: scripts/coverage/diff.mjs (zero-dep Node ESM)
  - parseLcov: SF -> Map<line, count>; only DA records read
  - parseGitDiff: parses --unified=0 output into Map<file, Set<line>>
  - computeDiffCoverage: cross-references both, emits result tree
  - Allowlist of paths that don't gate (tests, configs, docs, .sh,
    DI bootstrap, interfaces, CMS, factories, contracts, UI)
  - Path matching handles three lcov path conventions: absolute,
    repo-relative, and per-package relative
  - CLI flags: --base (default origin/main), --lcov (default
    coverage/lcov.info), --json (suppress stderr summary)
  - stdout: machine-readable JSON for the dispatch loop
  - stderr: human summary
  - Exit 0 on pass, 1 on fail or error

Test surface: scripts/coverage/diff.test.mjs (14 tests, all green)
  - Fixtures at scripts/coverage/__fixtures__/{sample.lcov,sample-diff.patch}
  - Covers: lcov parsing, diff parsing, pass path, uncovered lines,
    non-executable line skipping, no-coverage-data detection,
    allowlist filtering, end-to-end mixed case, path matching

Wired:
  - root package.json adds "coverage:diff" script
  - .gitignore anchored so per-package coverage/ stays ignored but
    scripts/coverage/ stays tracked

Smoke-tested end-to-end against packages/auth/coverage/lcov.info —
correctly skips shell scripts + manifest files (via allowlist + path
suffix match), correctly flags files not present in the per-package
lcov (which is expected; full repo coverage needs the L2 aggregate
that the next story lands).

CI integration deferred to the L2 aggregate story (the merged
coverage/lcov.info this script reads doesn't exist yet — pnpm
coverage:aggregate produces it).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 14:04:09 +02:00

50 lines
1.8 KiB
Diff

diff --git a/packages/auth/src/application/use-cases/sign-in.use-case.ts b/packages/auth/src/application/use-cases/sign-in.use-case.ts
index abc..def 100644
--- a/packages/auth/src/application/use-cases/sign-in.use-case.ts
+++ b/packages/auth/src/application/use-cases/sign-in.use-case.ts
@@ -1,0 +2,2 @@
+const a = 1;
+const b = 2;
@@ -4,1 +5,2 @@
-old
+const c = 3;
+const d = 4;
diff --git a/packages/auth/src/application/use-cases/sign-in.use-case.test.ts b/packages/auth/src/application/use-cases/sign-in.use-case.test.ts
index abc..def 100644
--- a/packages/auth/src/application/use-cases/sign-in.use-case.test.ts
+++ b/packages/auth/src/application/use-cases/sign-in.use-case.test.ts
@@ -10,0 +11 @@
+new test line
diff --git a/packages/auth/src/entities/models/user.ts b/packages/auth/src/entities/models/user.ts
index abc..def 100644
--- a/packages/auth/src/entities/models/user.ts
+++ b/packages/auth/src/entities/models/user.ts
@@ -2,1 +2,1 @@
-old
+modified
diff --git a/packages/blog/src/application/use-cases/get-article.use-case.ts b/packages/blog/src/application/use-cases/get-article.use-case.ts
index abc..def 100644
--- a/packages/blog/src/application/use-cases/get-article.use-case.ts
+++ b/packages/blog/src/application/use-cases/get-article.use-case.ts
@@ -11,0 +12 @@
+const uncovered = true;
diff --git a/packages/media/src/application/use-cases/upload.use-case.ts b/packages/media/src/application/use-cases/upload.use-case.ts
new file mode 100644
index 0000000..abc
--- /dev/null
+++ b/packages/media/src/application/use-cases/upload.use-case.ts
@@ -0,0 +1,5 @@
+export const uploadUseCase = () => {
+ return "uploaded";
+};
+// Line 4
+// Line 5
diff --git a/CLAUDE.md b/CLAUDE.md
index abc..def 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -1,1 +1,2 @@
-old text
+new text
+more text