Initial Commit

This commit is contained in:
2026-05-27 23:29:53 +01:00
commit fbc70f96e6
10000 changed files with 1102152 additions and 0 deletions

View File

@@ -0,0 +1,32 @@
## Why
The 2026-04-25 test-suite audit (`/mnt/s/web/genesis/docs/superpowers/specs/2026-04-25-test-suite-audit.md` §2) identifies mutation testing as a critical missing tier of the genesis test pyramid. The canonical `openspec/specs/testing/spec.md` enforces 100% Istanbul line/branch/function/statement coverage and a mitata 10% benchmark regression gate, but neither catches a whole class of defects: tests that execute a code path without actually asserting its behaviour. A mutated implementation that still passes the test suite is a silent gap in the contract.
CLAUDE.md (`/mnt/s/web/genesis/CLAUDE.md` §Critical and §Quality) mandates enterprise-grade quality on every package and explicitly forbids skipping or disabling tests. Foundation packages (`crypto-*`, `error`, `validation`, `serialize`, `datetime`, `timing`, `retry`, `pagination`, `env`, `config`, `mime`, `templates`, `i18n`, `idempotency`, `slsa`, `diff`) are the substrate for every downstream consumer; a surviving mutant in one of those packages is a latent defect propagated everywhere. Layering a mutation-score gate on top of the existing 100% line-coverage gate closes the assertion-quality hole without diluting either signal.
## What Changes
This change adds **mutation testing** as a quality gate on top of (not in place of) 100% Istanbul line coverage. 100% line coverage remains a precondition; mutation score is an additional, independent gate. Neither substitutes for the other.
### New requirements
- Stryker (`@stryker-mutator/core` + `@stryker-mutator/vitest-runner`) configured per-package via `stryker.conf.json` co-located at the package root, with external deps routed through the catalog (no bare versions per `openspec/AGENTS.md` §1).
- **Mutation score gate** — foundation packages SHALL achieve ≥ 85% mutants killed; all other `@suaveplan/*` packages SHALL achieve ≥ 70% mutants killed. Surviving mutants MUST be triaged (killed, equivalent-marked with justification, or covered by a follow-up issue) before the change lands.
- **Excluded paths** — barrel `index.ts`, `*.schemas.ts`, `*.bench.ts`, `__benchmarks__/`, and `*.stories.tsx` are excluded from mutation analysis (no behavioural assertions to mutate).
- **CI integration** — nightly per-package mutation runs publish HTML + JSON reports as artefacts; on-PR runs use Stryker's `--mutate` filter to score only changed files, keeping wall-clock under budget.
- **Reporter contract** — surviving mutants are enumerated in a structured PR comment (path, line, mutator, status) so reviewers can act without opening artefact links.
- **Error-code prefix** — any custom Stryker mutator or runner adapter Suaveplan ships throws `TESTING.MUTATION.*` codes via the local `TestingError` class, matching the existing `TESTING.<DOMAIN>.<REASON>` convention from `openspec/specs/testing/spec.md`.
- **Self-coverage** — any custom Suaveplan mutator or adapter SHALL itself meet 100% Istanbul coverage; mutation tooling does not exempt itself.
## Capabilities
### Modified Capabilities
- `testing` — adds normative requirements for the mutation-score gate, excluded paths, CI cadence, reporter contract, and `TESTING.MUTATION.*` error codes. Does not modify or relax the existing 100% line-coverage requirement or the mitata benchmark gate.
## Impact
- **Affected code:** every `@suaveplan/*` package gains a `stryker.conf.json` and a CI hook. No source code changes mandated; surviving mutants drive follow-up fixes per package.
- **Affected catalogs:** root `package.json` gains `@stryker-mutator/core` and `@stryker-mutator/vitest-runner` under `catalogs.testing`.
- **Pre-publish gate:** the existing pre-publish gate is unchanged. Mutation score is enforced by a separate `bunx turbo test:mutation --filter=@suaveplan/<pkg>` step that MUST also pass before publish.
- **Wall-clock budget:** PR runs scoped to changed files keep mutation analysis within the existing PR CI envelope; full runs move to nightly to absorb the higher cost.