brainstorming
brainstorming
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or planning anything new, in software or out of it (a talk, a business, a renovation).
test-auditPrunes low-value tests across a whole suite to a measured target while holding coverage. Use when asked to "remove useless tests", "prune the test suite", "we have too many tests", "agents keep writing pointless tests", or "cut 20% of tests without losing coverage".
Independent GitHub snapshot · Automated classification · Original documentation governs
Tests earn their place by catching a credible regression that nothing else catches. Agents write a test for every small change, and most of those re-assert the source, replay a stronger test through a mock, or pin a private call shape. Coverage barely moves when they go; maintenance cost and suite time do.
tidy), making CI faster by splitting or sharding (ci-speedup), or writing tests for untested code.| Mode | When | Done means |
|---|---|---|
| Audit | A focused sweep of named files or a directory | A handful of high-confidence candidates with full evidence, deleted in one coherent batch with validation green |
| Campaign | A subsystem's or repo's whole test surface, or any request with a target ("remove 20%") | The target is met or the ledger shows why it cannot be, coverage held within tolerance, and the preservation review passed. Read references/campaign.md first |
An open-ended "clean up the tests" stops after a few obvious deletions, because every remaining candidate looks defensible in isolation. Audit and Campaign need a number to work against. When the user gave one, use it. When they did not, propose one and proceed on it rather than waiting:
Remove the least useful 20% of test declarations in
<scope>, keeping line and branch coverage within 2 percentage points of the baseline and every retained test green.
Measure the baseline first (references/coverage.md), then keep deleting in order of lowest value until the target is met or the coverage budget is spent. Stopping short is a valid result only with a ledger showing that the remaining candidates each guard a named contract. The target is a floor on effort, not permission to cut uncertain tests: the retention bar below still wins over the number.
What an audit or campaign hunts for:
toHaveBeenCalledWith on an internal) duplicated at a real boundaryTwo more finding kinds. Neither is a removal candidate on that fact alone, and a move or an unskip is not a deletion toward the target.
routes/posts.test.ts that never touches the route and only calls lib/slug.ts. Move it to the canonical owner's suite, as "Edit shape" says for retained regressions.it.skip('prorates refunds on downgrade'), xit, @pytest.mark.skip, or t.Skip(). Unskip it and run it first; never remove it on sight. If it passes, leave it enabled and judge it like any other test. If it fails, treat it as a possible product bug under the retention bar: reproduce it and fix the owner. A conditional skip with a real platform or environment reason is not a finding.Keep a test when it independently enforces a public API, protocol, config, migration, storage, security, platform, default value, generated cross-language, package, release, or architecture contract. Also keep:
Static or slow is not a reason to delete. A test that resembles implementation may still be the only proof of a contract; show otherwise before removing it.
Before judging, read the complete test, the production owner, its callers and callees, sibling implementations, overlapping tests, and the history that explains why the test exists. Record for each deletion:
A missing field means the candidate is not ready. Prefer a few high-confidence deletions over a long speculative list; do not convert uncertain candidates into deletions to reach the number.
Delete in coherent owner-boundary batches. With each batch, delete the test-only exports, globals, wrappers, reset hooks, and dead production paths it unlocks instead of keeping aliases. Move retained regressions to their canonical owner and fold duplicated setup into shared fixtures. Aim for net-negative production lines as well as test lines. Do not add replacement tests that restate the same implementation.
git diff --numstat with production and tooling lines separate from test lines.Running tests and coverage locally, and deleting tests and test-only seams in the working tree, are the task: do them without asking. Commit, push, or open a PR only when asked. A test that meets the retention bar stays; deleting one anyway is the user's call, as is changing coverage thresholds or CI gates.
AGENTS.md, drawn from the patterns this audit actually found, so agents stop writing themreferences/coverage.md).| File | Read when |
|---|---|
references/campaign.md | Campaign mode, or any target-driven prune larger than one directory |
references/coverage.md | Measuring the baseline, per-file and per-test coverage, the budget check, and mutation spot checks |
Maintenance only: evals/evals.json holds scenarios and routing prompts for changing this skill; it never loads during a task.
tidy: gates a test the moment a diff adds or changes it, and reviews the rest of the diff alongside it. This skill only sweeps or campaign-prunes the existing suite; "audit these tests in my PR" routes to tidy, not here.Adapted from OpenClaw's test-audit skill (openclaw/openclaw, MIT). Provenance lives in the repository's maintenance notes.