# Coverage Sprint Backlog — #76 Follow-up Work
**Generated:** 2026-05-25
**Baseline source:** [`coverage-baseline-2026-05-25.md`](./coverage-baseline-2026-05-25.md)
**Current overall coverage:** 77.68% statements / 79.34% branches / 75.46% functions / 77.68% lines
**2026-05-29 closeout check:** `pnpm run verify:test-coverage` passes with
the current per-module gates. The historical baseline remains useful for
trend context, but the active closeout state is now "no positive sprint
gaps".
**Rule:** Every entry in the "Critical-path positive-gap" table below must
reach its `sprintTarget` before a future coverage ratchet can be treated as
done. There are no positive-gap rows in the latest baseline, so #76 is closed;
remaining work is gate maintenance and opportunistic threshold ratcheting
rather than broad test writing.
## Pick-the-next-module workflow
For a follow-up session that wants to pick mechanically:
1. Read this file.
2. Grab the top row of the "Critical-path positive-gap" table.
3. Open the HTML coverage report (`coverage/lcov-report/index.html`) and
drill into that module.
4. Identify uncovered lines/branches; write tests against real code paths
(no mocks-only padding).
5. Re-run `pnpm exec vitest run --coverage --exclude ...` (see baseline doc
for the exclude flags). Confirm achievement.
6. Bump the entry in `scripts/coverage-targets.json` for that module to the
new achieved level (round DOWN by 0.5-1pp for headroom). Never weaken
existing thresholds.
7. Commit with `test(): close coverage gap for `. Move the
row to the "Graduated" table below.
## Critical-path positive-gap modules — priority order
Sorted by sprint-priority (per detail-MD section d): Auth > Tenant-Isolation
> Billing > Permissions > Entitlements > DB.
No critical-path modules currently have a positive sprint gap.
## Standard-tier modules with positive gap
No standard-tier runtime modules currently have a positive sprint gap.
## Graduated modules (already at or past sprintTarget)
Where the gap is negative the module has met or exceeded the sprintTarget.
Rows marked `(raised)` had their active gate raised on 2026-05-25 to lock
the achievement in.
| Module | stmt now | br now | sprint | Active gate now |
| ------------------------------------- | -------: | -----: | -----: | --------------: |
| `apps/api/src/auth/**` (raised) | 99.2 | 92.2 | 90/85 | **99/92** |
| `apps/web/app/services/auth/**` (raised) | 97.4 | 88.5 | 90/85 | **97/88** |
| `apps/web/app/utils/session.server.ts` (raised) | 100.0 | 99.1 | 95/90 | **99/98** |
| `apps/web/app/utils/auth/**` (raised) | 97.7 | 92.7 | 90/85 | **97/92** |
| `apps/web/app/utils/stripe.server.ts` (raised) | 95.4 | 91.1 | 85/75 | **95/90** |
| `apps/web/app/utils/db/tenants.db.server.ts` (raised) | 98.5 | 96.1 | 95/90 | **98/95** |
| `apps/web/app/utils/db/permissions/**` (raised) | 99.8 | 99.0 | 90/80 | **99/98** |
| `apps/api/src/billing/**` (raised) | 99.3 | 98.0 | 99/95 | **99/97** |
| `packages/entitlements/**` (raised) | 97.0 | 89.9 | 90/80 | **96/89** |
| `apps/api/src/isolation/**` (raised) | 100.0 | 100.0 | 95/90 | **99/99** |
| `packages/db/src/outbox*` (raised) | 93.0 | 88.6 | 90/80 | **92/88** |
| `packages/shared-store/**` (raised) | 91.3 | 90.7 | 90/80 | **91/90** |
| `packages/error-reporter/**` (raised) | 81.5 | 86.9 | 80/70 | **81/86** |
| `apps/mobile/src/**` (raised) | 79.2 | 80.2 | 70/60 | **79/79** |
| `apps/hocuspocus/src/**` (raised) | 89.2 | 92.9 | 70/60 | **88/90** |
| `packages/cli/src/**` (raised) | 80.4 | 83.6 | 80/70 | **80/83** |
| `packages/ui-app/src/**` (raised) | 95.1 | 73.7 | 70/60 | **94/73** |
| `packages/api-client-ts/src/**` (raised) | 70.9 | 80.9 | 70/60 | **70/80** |
| `packages/plugins/src/**` (raised) | 100.0 | 86.8 | 98/80 | **99/86** |
| `packages/ai/src/**` (raised) | 81.6 | 81.0 | 80/70 | **81/81** |
| `packages/config/src/**` (raised) | 99.0 | 95.4 | 80/70 | **98/95** |
| `packages/feature-flags/src/**` (raised) | 94.3 | 86.4 | 80/70 | **94/86** |
| `packages/i18n/src/**` (raised) | 95.2 | 75.7 | 80/70 | **95/75** |
| `packages/plugin-runtime/src/**` (raised) | 92.7 | 88.5 | 80/70 | **92/88** |
| `packages/queue/src/**` (raised) | 93.5 | 96.0 | 80/70 | **93/95** |
| `packages/exports/src/**` (raised) | 90.7 | 83.6 | 80/70 | **90/83** |
| `packages/imports/src/**` (raised) | 91.8 | 87.5 | 80/70 | **91/87** |
| `packages/realtime/src/**` (raised) | 91.6 | 85.3 | 80/70 | **91/85** |
| `packages/search/src/**` (raised) | 88.6 | 71.7 | 80/70 | **88/71** |
| `packages/storage/src/**` (raised) | 82.8 | 84.2 | 80/70 | **82/84** |
| `packages/vector-store/src/**` (raised) | 94.6 | 90.4 | 80/70 | **94/90** |
| `packages/metrics/src/**` (raised) | 98.9 | 90.2 | 80/70 | **98/90** |
| `packages/form-widget/src/**` (raised) | 96.7 | 86.5 | 80/70 | **96/86** |
| `packages/email-sequences/src/**` (raised) | 84.5 | 78.0 | 80/70 | **84/77** |
| `packages/email-templates/src/**` (raised) | 96.9 | 86.5 | 70/60 | **96/86** |
| `packages/observability/src/**` (raised) | 100.0 | 100.0 | 80/70 | **99/99** |
| `packages/marketing-outbound/src/**` (raised) | 85.8 | 65.9 | 70/60 | **85/65** |
| `packages/plugin-sdk/src/**` (raised) | 100.0 | 100.0 | 75/65 | **99/99** |
| `packages/ui-mock/src/**` (raised) | 97.9 | 68.6 | 70/60 | **97/68** |
| `packages/view-models/src/**` (raised) | 86.7 | 71.4 | 75/65 | **86/71** |
| `packages/url/src/**` (raised) | 98.3 | 95.9 | 80/70 | **98/95** |
| `packages/logger/src/**` (raised) | 100.0 | 100.0 | 80/70 | **99/99** |
| `packages/brand/src/**` (raised) | 100.0 | 93.8 | 80/70 | **99/93** |
| `packages/api-types/src/**` (type-only) | 0.0 | 100.0 | 0/0 | **0/0** |
## Out-of-scope notes
- `packages/ui-subframe/**` keeps an active 30/20 gate while its sprint
target remains 50/40 by design; visual confidence lives in Storybook
lost-pixel (#62). Do NOT force the active gate to 50/40 with shallow
unit tests; close that gap with the visual regression contract.
- **The latest full coverage run puts
`apps/web/app/utils/stripe.server.ts` past both sprint targets**. The
active gate is raised to 95/90 so future changes cannot drop back to the
old mock-only baseline.
- **The latest full coverage run graduates `packages/cli/src/**` at
80.4% statements / 83.6% branches**. The active gate is raised to 80/83
so the new AI-cost, feature-flag, chatbot, backup-create, DSGVO,
sequence, leads, and KB article coverage does not regress.
- **The latest full coverage run graduates `packages/ui-app/src/**` at
95.1% statements / 73.7% branches**. The active gate is raised to 94/73
after covering the public a11y-template test factory.
- **The latest full coverage run graduates `packages/api-client-ts/src/**`
at 70.9% statements / 80.9% branches**. The active gate is raised to
70/80 after covering generated body/path/query/auth/client/SSE helpers and
catching a cookie header separator regression.
- **The latest full coverage run graduates `packages/plugins/src/**` at
100.0% statements / 86.8% branches**. The active gate is raised to 99/86
after adding branch-edge coverage for manifest schema and loader behavior.
- `packages/api-types/src/**` reports 0% statements because the source
contains only `export type ... = ...` aliases (no runtime code). Its
sprint target is intentionally 0/0 and guarded by `expectTypeOf` tests plus
package typecheck instead of fake runtime assertions.
- **The latest `pnpm run verify:test-coverage` execution had 399 passing
files, 2 skipped files, 3597 passing tests, and 50/50 passing coverage
targets**.
- **2026-05-27 focused recon:** the four historical coverage-scope failures
called out in `coverage-baseline-2026-05-25.md` now pass when run together:
`apps/web/app/application/ui/uiInventory.test.ts`, `apps/api/src/app.test.ts`,
`packages/config/src/env-examples.test.ts`, and
`packages/cli/src/commands/tenant/json-codec.test.ts` (193 tests passing).
- **2026-05-29 closeout verification:** `pnpm run verify:test-coverage`
passes with the current gate set; #76 is closed in
`docs/improvement-plan/PROGRESS.md`.
## References
- Spec: `docs/improvement-plan/10-compliance-polish/test-coverage.md`
- Policy: `docs/architecture/test-coverage.md`
- Baseline: `docs/testing/coverage-baseline-2026-05-25.md`
- Gate runner: `scripts/verify-test-coverage.mjs`
- Targets data: `scripts/coverage-targets.json`