3.8 KiB
3.8 KiB
0. Pre-flight (non-negotiable)
- 0.1 Confirm clean working tree (
git statusreports nothing) and no in-flight worktrees with uncommitted work (git worktree listthengit statusin each) - 0.2 If any worktrees exist under
.claude/worktrees/, account for each one: still-active agent, work-pending-merge, or stale-and-prune. Stale worktrees MUST be removed (git worktree remove) before opening a new one — code that has been lost twice on main is the failure mode this guards against. - 0.3 Confirm the package set in
MANIFEST.mdmatchesfind packages -maxdepth 3 -name package.jsoncount. Drift here means a prior change archived without regenerating the manifest.
1. Catalog and tooling setup
- 1.1 Add
@stryker-mutator/coreand@stryker-mutator/vitest-runnerto rootpackage.jsoncatalogs.testing(no bare versions peropenspec/AGENTS.md§1) - 1.2 Run
bun install; confirm lockfile updates cleanly - 1.3 Add
test:mutationtask to rootturbo.jsonwithdependsOn: ["test:coverage"]so 100% line coverage is a precondition - 1.4 Document the foundation-package set in
openspec/specs/testing/spec.mdonce this change is folded; the same enumeration appears in the spec delta in this folder
2. Per-package Stryker configuration
- 2.1 Author a reusable
stryker.base.conf.cjstemplate undertooling/stryker/(path TBD) that every package extends — testRunner:vitest, reporters:html, json, clear-text, mutate exclusions per design D4 - 2.2 For every
@suaveplan/*package, createstryker.conf.jsonat the package root extending the base template, declaringmutate: ["src/**/*.ts"]and the package-specific exclusions - 2.3 For every package, add a
test:mutationscript inpackage.jsoninvoking Stryker against the package'svitest.config.ts
3. Threshold enforcement
- 3.1 Encode the foundation-package list in the base config via a tiered
thresholdsblock (≥ 85% for foundation, ≥ 70% otherwise) - 3.2 Wire a CI step that fails the build on
mutationScorebelow the package's tier threshold - 3.3 Wire the PR-scoped mutation run via
--mutatefiltered to files changed in the PR (resolved throughgit diff --name-only origin/main...HEAD)
4. Reporter and artefacts
- 4.1 Configure HTML + JSON reporters; archive both as CI artefacts per nightly run
- 4.2 Author a
scripts/report-mutants.tsthat reads the JSON report and emits a Markdown table (path, line, mutator, status) for the PR comment - 4.3 Wire the PR-comment step to post the table via
gh pr comment(or workflow equivalent)
5. Custom-mutator hook (extension point)
- 5.1 If a custom Stryker mutator or runner adapter is required (e.g. once a bun-test runner exists), package it as
@suaveplan/testing-mutationunderpackages/testing/ - 5.2 Errors thrown by the adapter MUST extend
TestingErrorwith codes prefixedTESTING.MUTATION.*(e.g.TESTING.MUTATION.RUNNER_FAILED,TESTING.MUTATION.CONFIG_INVALID) - 5.3 The adapter package itself MUST meet 100% Istanbul coverage and pass the same mutation-score tier it advertises
6. Spec delta and validation
- 6.1
openspec validate enterprise-testing-mutation --type changepasses - 6.2 Fold
specs/testing/spec.mdADDED Requirements intoopenspec/specs/testing/spec.md - 6.3 Move this change folder to
openspec/archive/<yyyy-mm-dd>-enterprise-testing-mutation/
7. Rollout
- 7.1 Run baseline mutation analysis across every existing genesis package; record current scores
- 7.2 For each package below its tier threshold, file a triage issue listing surviving mutants by mutator class
- 7.3 Land assertion-strengthening fixes per package until every existing package meets its tier threshold
- 7.4 Flip the CI gate from advisory to enforcing once every package is green