redesign-tests
Skill bundle for phil:redesign-tests command — human-approved, behaviour-changing test redesign loop with a coverage-equivalence claim per rewrite
Skill by pmvanev
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/pmvanev-redesign-tests
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: testing
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
- Runs as
- Python package
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/redesign-tests
What's inside
- Skill name
redesign-tests- Description
- Skill bundle for phil:redesign-tests command — human-approved, behaviour-changing test redesign loop with a coverage-equivalence claim per rewrite
- License
- MIT
- Instructions
- 262 lines in SKILL.md · view on GitHub
Before installing
- Ships executable scripts
Files (36)
- SKILL.md
- acceptance.feature
- expected.md · self-test/01-baseline-red-stop/
- manifest.json · self-test/01-baseline-red-stop/
- orders.py · self-test/01-baseline-red-stop/
- test_orders.py · self-test/01-baseline-red-stop/
- expected.md · self-test/02-postapply-red-autorevert/
- manifest.json · self-test/02-postapply-red-autorevert/
- move.patch · self-test/02-postapply-red-autorevert/
- orders.py · self-test/02-postapply-red-autorevert/
- test_orders.py · self-test/02-postapply-red-autorevert/
- expected.md · self-test/03-approve-commit-on-green/
- manifest.json · self-test/03-approve-commit-on-green/
- move.patch · self-test/03-approve-commit-on-green/
- orders.py · self-test/03-approve-commit-on-green/
- test_orders.py · self-test/03-approve-commit-on-green/
- expected.md · self-test/04-reject-reverts-clean/
- manifest.json · self-test/04-reject-reverts-clean/
- move.patch · self-test/04-reject-reverts-clean/
- orders.py · self-test/04-reject-reverts-clean/
- test_orders.py · self-test/04-reject-reverts-clean/
- expected-backlog.md · self-test/05-review-seeds-backlog/
- expected.md · self-test/05-review-seeds-backlog/
- manifest.json · self-test/05-review-seeds-backlog/
- orders.py · self-test/05-review-seeds-backlog/
- test_orders_smells.py · self-test/05-review-seeds-backlog/
- expected.md · self-test/06-missing-fake-skips/
- manifest.json · self-test/06-missing-fake-skips/
- orders.py · self-test/06-missing-fake-skips/
- test_orders.py · self-test/06-missing-fake-skips/
- expected-backlog.md · self-test/07-unmanaged-mock-is-behaviour/
- expected.md · self-test/07-unmanaged-mock-is-behaviour/
- manifest.json · self-test/07-unmanaged-mock-is-behaviour/
- orders.py · self-test/07-unmanaged-mock-is-behaviour/
- test_orders_boundaries.py · self-test/07-unmanaged-mock-is-behaviour/
- README.md · self-test/
SKILL.md (first lines)
# Redesign Tests
Rewrite tests that verify **how** the code works into tests that verify **what** it does — turning
implementation-coupled, over-mocked and flaky tests into behaviour-focused ones. Work a prioritized
backlog one item at a time; **every rewrite is committed only after the developer approves the diff *and*
its coverage-equivalence claim**, reviewing it applied in their editor.
**This is behaviour-CHANGING, human-gated work — the opposite pole from `phil:refactor-tests`.**
`refactor-tests` is structure-only and can promise coverage never shrank. This skill deliberately
changes *what a test asserts*, so it **cannot** make that promise automatically. The test is the
oracle, and this skill changes the test — so **the human is the sole oracle**. A green
suite is only a secondary sanity check; it can never prove a rewrite preserved coverage. That is
why every proposal carries a **coverage-equivalence claim** and why nothing is committed without
per-diff human approval.
> **Relationship to `phil:refactor-tests`.** If the smell is a structure-only one (duplicated setup,
> missing AAA, vague name, long test), that is `refactor-tests`' job — do not handle it here. This
> skill handles only behaviour-changing smells (below). The two use **separate** backlog files and
> never collide.
## The behavioural smells in scope (and their moves)
Only these three families. If a smell is not one of these, do **not** report or rewrite it.
Each family groups rows of the Smell Catalogue in `${CLAUDE_PLUGIN_ROOT}/rules/test-patterns.md` —
the rows whose route is `/phil:redesign-tests`. Read that rule before detecting: it names the smells,
and its stance section decides which mocks are smells at all.
| Smell family | Signal | Named move(s) | What the rewrite does |
|--------------|--------|---------------|------------------------|
| **Implementation-coupling** (Overspecified Software, Sensitive Equality, Private Access) | asserts on a mock interaction with an in-process collaborator (`mock.x.assert_called`), a private member (`obj._field`), an internal call, or a `str()`/`repr()`/serialized form — not on an observable outcome | **Assert on observable outcome** | replace the how-assertion with one on the public result / persisted state / returned value |
| **Excessive-mocking** (Mock Inside a Boundary) | mocks a collaborator that could be real (or a fake exists) and asserts only on the mock | **Replace mock with real collaborator**, **Replace mock with fake** | drive the real collaborator/fake; assert on the resulting state |
| **Flakiness / determinism** (Erratic Test) | depends on `datetime.now()`, unseeded RNG, UUIDs, wall-clock, ordering, or hidden shared state | **Inject clock / static timestamp**, **Seed RNG**, **Isolate shared state** | make the test deterministic while preserving what it checks |
**A mock at an unmanaged dependency is not implementation-coupling and not excessive-mocking.** An
email gateway, a bus another team reads, a third-party API: the message the code sends it is observable
behaviour, so asserting that message *is* the observable outcome. Rewriting it to assert on state would
discard the one thing the test exists to check. **Judge by what the mock stands in for, not who owns its
type** — your own `EmailSender` port wrapping a gateway is the gateway. A mock of an owned collaborator
that stands for nothing outside the process stays in scope, and so does the flakiness family: a gateway
mock asserting a wall-clock value is still an Erratic Test.
(Fixture `07-unmanaged-mock-is-behaviour`.)
**Never in scope:** structure-only cleanup (that is `refactor-tests`); deleting dead/duplicate
tests; splitting or merging test files; changing non-test (SUT) code; concurrency-race fixes that
require production changes. When unsure whether a flag is a true behavioural smell, **skip it** —
false positives erode trust (the precision target: at most 20% rejected on first review).
## Detection (reuse `review-code` Priority 6)
Detect against the catalogue rows routed here — a subset of the rows `review-code`'s **Priority 6 —
Test Quality** names — and do not fork a divergent list. Detect only test
files matching the globs in `${CLAUDE_PLUGIN_ROOT}/rules/testing.md` frontmatter (the same set
`testing.md` scopes itself to). Non-test files (the SUT) are never scanned or rewritten. Act on
**Python + TypeScript/React only**; files matched by other globs are recognized as tests but skipped with
a one-line note.
## Parse the argument
| Pattern | Mode | Action |
|---------|------|--------|
| `--review <path>` | Review | Detect behavioural smells under `<path>`, write `.test-redesign-backlog.md`, **stop** (no changes). |
| A file path or `test-id` | Scoped loop | Run the approval loop scoped to that file/test only. |
| No argument | Backlog loop | Work the existing `.test-redesign-backlog.md` one approved item at a time. |
---
## Prerequisites (all modes except review-only detection)
Run these three checks once, **in this order**, before the loop starts.
### 1. Locate the test runner
Follow `${CLAUDE_PLUGIN_ROOT}/skills/shared/test-runner-detection.md` (reuse). Prefer the `CLAUDE.md` test command; else
auto-detect. Run it once to confirm it works before touching anything. If none is found, warn and
use AskUserQuestion before proceeding — redesigning tests without a runnable suite removes even the
secondary sanity check.
### 2. Confirm a clean working tree
The loop applies changes to the working tree and relies on `git checkout` to revert. A rewrite can
write beyond the target test file — `conftest.py`, a new helper module — so check that `git status
--porcelain` shows no change outside the backlog files; otherwise ask the developer to commit or stash
first, since a revert could discard their work. Do this **before** the baseline run.
### 3. Establish a green baseline (safety rule — never redesign on red)
Run the suite **before** proposing any rewrite. **If the baseline is red, STOP and report — do not
propose or apply anything.** (Fixture `01-baseline-red-stop`.)
---
## Review mode — `--review <path>` (seeds the backlog)
1. Enumerate test files under `<path>` matching the `testing.md` globs. Ignore non-test files.
2. Detect only the three behavioural smell families (above), reusing `review-code` Priority 6. One
backlog item per smell instance.
3. Write `.test-redesign-backlog.md` in the project root, in `review-code`'s backlog **format** (by
convention — do not modify `review-code`). Keep it **separate** from `.test-refactoring-backlog.md`
so the two tools never collide. Use this shape:
```markdown
# Test Redesign Backlog
Generated: {date}
Scope: --review {path}
## Summary
- **Total items**: {count}
- **Implementation-coupling**: {count}
- **Excessive-mocking**: {count}
- **Flakiness/determinism**: {count}
## Backlog
### [RD001] {smell family} — {one-line description}
- **File**: `{file-path}`
- **Lines**: {start}-{end}
- **Priority**: {1-3}
- **Smell**: {smell family} — {catalogue smell from test-patterns.md}From pmvanev/phil-claude-plugin, MIT.
More from pmvanev/phil-claude-plugin
- 0.570score
issue-board
pmvanev
Use when driving a GitLab or GitHub issue tracker or board from the command line with `glab` or `gh` — moving a card between board columns, reordering a…
SkillAFreshness: AClaude Code +9 - 0.570score
board-setup
pmvanev
Use when recording a repo's issue-board constants in its `CLAUDE.md` — the forge and repo, the project and Status field ids, every option id, the enabled…
SkillAFreshness: AClaude Code +9 - 0.570score
board-snapshot
pmvanev
Use when asked where an issue board stands right now rather than what is wrong with it — "summarise my board", "what's on the board", "where does the board…
SkillAFreshness: AClaude Code +9 - 0.570score
nwave-slice-status
pmvanev
Use when the user asks where an nWave feature stands — "how many steps are in this slice", "which ones are done", "which one are we on", "what's next", "is…
SkillAFreshness: AClaude Code +9 - 0.566score
nwave-wave-summary
pmvanev
Use when asked what finished work decided, rather than where it stands or what you were doing — "what did DISCUSS decide", "what did that stage settle"…
SkillAFreshness: AClaude Code +9 - 0.566score
groom-issues
pmvanev
Skill bundle for the phil:groom-issues, phil:groom-fix, phil:groom-set and phil:groom-ask commands — reads a whole issue board in one list call per forge —…
SkillAFreshness: AClaude Code +9 - 0.566score
nwave-issue-board
pmvanev
Use for any GitLab or GitHub board or tracker work in an nWave repo — one holding `.nwave/` or `docs/feature/` — including putting a feature on the tracker as…
SkillAFreshness: AClaude Code +9 - 0.565score
adversarial-review
pmvanev
Skill bundle for phil:adversarial-review command — a general-purpose independent adversarial critic.
SkillAFreshness: AClaude Code +9 - 0.565score
edd
pmvanev
Skill bundle for phil:edd command — Expectation-Driven Development front-door.
SkillAFreshness: AClaude Code +9 - 0.565score
red-team-prose
pmvanev
Skill bundle for phil:red-team-prose command — reviews a doc, README, or release note for AI-generated tells, Elements of Style clarity, and fitness for its…
SkillAFreshness: AClaude Code +9 - 0.561score
ai-eos
pmvanev
Skill bundle for phil:ai-eos command — detects the stylistic tells that mark technical prose as AI-generated, with a density verdict and ranked findings.
SkillAFreshness: AClaude Code +9 - 0.561score
refactor-loop
pmvanev
Skill bundle for phil:refactor-loop command — gated closed-loop refactoring with a separate proposer and correctness critic, hard test gates, and a DAG ledger
SkillAFreshness: AClaude Code +9
Signals
- Stars
- 0
- Forks
- 0
- Open issues
- 10
- Last commit (this folder)
- Oct 13, 2026 (15 days ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- Repository
- github.com/pmvanev/phil-claude-plugin
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from pmvanev
- 0.570score
nwave-slice-status
pmvanev
Use when the user asks where an nWave feature stands — "how many steps are in this slice", "which ones are done", "which one are we on", "what's next", "is…
SkillAFreshness: AClaude Code +9 - 0.570score
board-snapshot
pmvanev
Use when asked where an issue board stands right now rather than what is wrong with it — "summarise my board", "what's on the board", "where does the board…
SkillAFreshness: AClaude Code +9 - 0.570score
board-setup
pmvanev
Use when recording a repo's issue-board constants in its `CLAUDE.md` — the forge and repo, the project and Status field ids, every option id, the enabled…
SkillAFreshness: AClaude Code +9 - 0.570score
issue-board
pmvanev
Use when driving a GitLab or GitHub issue tracker or board from the command line with `glab` or `gh` — moving a card between board columns, reordering a…
SkillAFreshness: AClaude Code +9 - 0.566score
groom-issues
pmvanev
Skill bundle for the phil:groom-issues, phil:groom-fix, phil:groom-set and phil:groom-ask commands — reads a whole issue board in one list call per forge —…
SkillAFreshness: AClaude Code +9 - 0.566score
nwave-issue-board
pmvanev
Use for any GitLab or GitHub board or tracker work in an nWave repo — one holding `.nwave/` or `docs/feature/` — including putting a feature on the tracker as…
SkillAFreshness: AClaude Code +9
Cite this page
redesign-tests skill. Agent Mart. https://agentmart.dev/skills/pmvanev-redesign-tests (last updated 2026-10-24)