Skill: prune-test-suite
Review and prune the test suite for this project. For each test file, verify its logic against
the current production source, then apply all necessary changes.
Step 0 — Discover scope
Find all test files in this project:
glob **/*.test.{ts,tsx,js,jsx} **/*.spec.{ts,tsx,js,jsx} **/__tests__/**/*.{ts,tsx,js,jsx}
Exclude node_modules, dist, .next, and build output directories.
For each test file, determine which source file(s) it mirrors by examining:
- Import paths within the test (e.g.,
import { foo } from '../utils')
- Inline simulation functions that replicate logic from a source file (match function names,
regex patterns, or constants against the codebase via grep)
- File naming conventions (e.g.,
foo.test.ts tests foo.ts)
Build a scope table mapping each test file to its source file(s). Print the table before
proceeding.
Do not modify any source file. Do not touch node_modules, dist directories, or generated files.
Step 1 — Read both files
For each row in the scope table:
- Read the test file in full.
- Read every source file listed for that test.
Complete Steps 1-4 for each test file before moving to the next.
Step 2 — Audit
Check each of the following for every test or describe block:
Logic match — Does the test's logic (imported or inlined) exactly match the corresponding
production code? Flag any line in the test that copies a constant, regex, branch condition,
function body, or message string that differs from the current source.
Stale behaviour — Does the test assert something the source no longer does? (e.g., a branch
that was removed, a string that changed, a parameter that was renamed, a function signature
that was updated.)
Dead test — Does the test import or reference a symbol, function, or type that no longer
exists in the source? Does it test a code path that was deleted?
Missing coverage — Does the source contain pure, deterministic logic that has no
corresponding test? Count logic as "pure" only if it can be exercised without mocking
external services, databases, network calls, or framework internals. Examples:
- Regex patterns and validation functions
- Date/string/number formatting or parsing
- State machine transitions and boundary arithmetic
- Pure transform/filter/map logic
- Error message construction
If logic requires a database client, HTTP call, framework hook, or rendering context to
execute, it does not qualify — skip it.
Step 3 — Produce a change list
Write a numbered list of concrete changes. Each item must specify:
- The action: DELETE test / UPDATE test / ADD test
- The file,
describe block, and it(...) name affected
- One sentence explaining why
Do not apply changes yet. Print the list, then stop and ask the user to confirm
before proceeding. This list can include test deletions, which are only
recoverable through git history, not through this skill - do not apply any
change until the user approves the list, or has explicitly pre-approved
auto-apply for this session.
Step 4 — Apply changes
Only after the user has confirmed the change list (or pre-approved auto-apply):
- DELETE: Remove the individual
it(...) / test(...) block. If an entire describe block
becomes empty, remove it too.
- UPDATE: Edit only the specific lines that are wrong. Do not rewrite surrounding tests.
- ADD: Add new test blocks inside an appropriate
describe, or create a new describe if
none fits. Follow the style and conventions of the existing test file (import patterns, assertion
style, naming conventions). Do not introduce new testing libraries or dependencies.
Constraints
- Do not add test infrastructure (new configs, new packages, new scripts) unless the project has
no test runner at all — in that case, ask before proceeding.
- Preserve every test that is still correct. Do not rewrite passing tests for style.
- Match the exact regex literal, exact error message string, and exact arithmetic from the source.
Copy character-for-character; do not paraphrase.
- If a test file uses inline simulation functions (re-implementing source logic inside the test
rather than importing it), verify those inline functions match the source exactly.
- If a source function depends on
Date.now() or new Date(), use a fixed reference date in
the test and document the assumption in a comment.
- Edit the minimum number of lines necessary. If a diff would exceed 20 lines for a single test
update, explain why before proceeding.
Output
After applying all changes for all test files, print a summary table:
| Test file |
Tests deleted |
Tests updated |
Tests added |
Notes |
| ... |
... |
... |
... |
... |
Then run the project's test suite using whatever test command is configured (check package.json
scripts for test, test:unit, etc.). Report whether all tests pass. If any fail, read the
failure output, fix the cause, and re-run until the suite is green.
1---2name: prune-test-suite3description: Review the test suite for relevance against current source code, pruning stale tests and adding missing coverage4---56# Skill: prune-test-suite78Review and prune the test suite for this project. For each test file, verify its logic against9the current production source, then apply all necessary changes.1011---1213## Step 0 — Discover scope14151. Find all test files in this project:16 ```17 glob **/*.test.{ts,tsx,js,jsx} **/*.spec.{ts,tsx,js,jsx} **/__tests__/**/*.{ts,tsx,js,jsx}18 ```19 Exclude `node_modules`, `dist`, `.next`, and build output directories.20212. For each test file, determine which source file(s) it mirrors by examining:22 - Import paths within the test (e.g., `import { foo } from '../utils'`)23 - Inline simulation functions that replicate logic from a source file (match function names,24 regex patterns, or constants against the codebase via grep)25 - File naming conventions (e.g., `foo.test.ts` tests `foo.ts`)26273. Build a scope table mapping each test file to its source file(s). Print the table before28 proceeding.2930Do not modify any source file. Do not touch node_modules, dist directories, or generated files.3132---3334## Step 1 — Read both files3536For each row in the scope table:37- Read the test file in full.38- Read every source file listed for that test.3940Complete Steps 1-4 for each test file before moving to the next.4142---4344## Step 2 — Audit4546Check each of the following for every test or `describe` block:47481. **Logic match** — Does the test's logic (imported or inlined) exactly match the corresponding49 production code? Flag any line in the test that copies a constant, regex, branch condition,50 function body, or message string that differs from the current source.51522. **Stale behaviour** — Does the test assert something the source no longer does? (e.g., a branch53 that was removed, a string that changed, a parameter that was renamed, a function signature54 that was updated.)55563. **Dead test** — Does the test import or reference a symbol, function, or type that no longer57 exists in the source? Does it test a code path that was deleted?58594. **Missing coverage** — Does the source contain pure, deterministic logic that has no60 corresponding test? Count logic as "pure" only if it can be exercised without mocking61 external services, databases, network calls, or framework internals. Examples:62 - Regex patterns and validation functions63 - Date/string/number formatting or parsing64 - State machine transitions and boundary arithmetic65 - Pure transform/filter/map logic66 - Error message construction6768 If logic requires a database client, HTTP call, framework hook, or rendering context to69 execute, it does not qualify — skip it.7071---7273## Step 3 — Produce a change list7475Write a numbered list of concrete changes. Each item must specify:76- The action: **DELETE** test / **UPDATE** test / **ADD** test77- The file, `describe` block, and `it(...)` name affected78- One sentence explaining why7980Do not apply changes yet. Print the list, then stop and ask the user to confirm81before proceeding. This list can include test deletions, which are only82recoverable through git history, not through this skill - do not apply any83change until the user approves the list, or has explicitly pre-approved84auto-apply for this session.8586---8788## Step 4 — Apply changes8990Only after the user has confirmed the change list (or pre-approved auto-apply):9192- **DELETE**: Remove the individual `it(...)` / `test(...)` block. If an entire `describe` block93 becomes empty, remove it too.94- **UPDATE**: Edit only the specific lines that are wrong. Do not rewrite surrounding tests.95- **ADD**: Add new test blocks inside an appropriate `describe`, or create a new `describe` if96 none fits. Follow the style and conventions of the existing test file (import patterns, assertion97 style, naming conventions). Do not introduce new testing libraries or dependencies.9899---100101## Constraints102103- Do not add test infrastructure (new configs, new packages, new scripts) unless the project has104 no test runner at all — in that case, ask before proceeding.105- Preserve every test that is still correct. Do not rewrite passing tests for style.106- Match the exact regex literal, exact error message string, and exact arithmetic from the source.107 Copy character-for-character; do not paraphrase.108- If a test file uses inline simulation functions (re-implementing source logic inside the test109 rather than importing it), verify those inline functions match the source exactly.110- If a source function depends on `Date.now()` or `new Date()`, use a fixed reference date in111 the test and document the assumption in a comment.112- Edit the minimum number of lines necessary. If a diff would exceed 20 lines for a single test113 update, explain why before proceeding.114115---116117## Output118119After applying all changes for all test files, print a summary table:120121| Test file | Tests deleted | Tests updated | Tests added | Notes |122|---|---|---|---|---|123| ... | ... | ... | ... | ... |124125Then run the project's test suite using whatever test command is configured (check `package.json`126scripts for `test`, `test:unit`, etc.). Report whether all tests pass. If any fail, read the127failure output, fix the cause, and re-run until the suite is green.