Compare commits

..
Author SHA1 Message Date
Matt PocockandClaude Opus 4.8 178d84849f refactor(to-plan,to-issues): prune no-ops in vertical-slice framing
Fold the redundant 'thin vertical slice cuts through all layers, NOT
horizontal' intro sentence into vertical-slice-rules bullet 1 (it was
duplicating the bullet), and cut to-plan's 'no parallelism / top-to-bottom'
restatement — 'sequential' is already anchored as the leading word. Keeps
the shared core identical across the two sibling skills.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 16:47:28 +01:00
Matt PocockandClaude Opus 4.8 90945a1969 feat(to-plan): add sequential plan skill
Add a user-invoked `to-plan` skill — the sequential, HITL sibling of
`to-issues`. Both slice work into tracer-bullet vertical slices, but
`to-plan` produces one ordered sequence you drive by hand, one phase per
fresh context, rather than parallel independently-grabbable issues.

It publishes to the tracker `/setup-matt-pocock-skills` configured, shaped
to it: a single sequential `plan.md` for a local tracker, or a parent
issue with ordered sub-issues (native sub-issues where supported) for a
real one.

Registers the skill everywhere CLAUDE.md requires (plugin.json, top-level
and bucket READMEs, docs page), updates the `ask-matt` router's main-flow
fork to offer both to-issues and to-plan, and adds a changeset.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 16:41:17 +01:00
Matt PocockandGitHub b38badf709 Merge pull request #408 from mattpocock/chore/implement-public-skill
chore: add implement skill to public plugin set
2026-07-01 16:30:41 +01:00
Matt PocockandClaude Opus 4.8 b3b1d8d1fd chore: add implement skill to public plugin set
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 16:26:13 +01:00
Matt PocockandGitHub 21f59763be Merge pull request #393 from mattpocock/tdd-reference-only-seams
tdd: reshape into reference-only with pre-agreed seams
2026-07-01 12:51:40 +01:00
Matt PocockandGitHub ec4ebab4f0 Merge pull request #406 from mattpocock/ask-matt-full-skill-map
ask-matt: map the full skill set, add router maintenance rule
2026-07-01 12:29:16 +01:00
Matt PocockandClaude Opus 4.8 930a450089 Add changeset for ask-matt full skill map
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 12:28:34 +01:00
Matt PocockandClaude Opus 4.8 770a0504db ask-matt: map the full skill set, add router maintenance rule
Ask Matt was missing five skills that now exist and are user-reachable:
tdd (the red-green engine implement drives), diagnosing-bugs (there was
no route for "something's broken"), domain-modeling and codebase-design
(the two vocabulary references), and grilling (the shared primitive).

- SKILL.md: add a "Something's broken" on-ramp for diagnosing-bugs, a
  "Vocabulary underneath" section for domain-modeling/codebase-design,
  weave tdd into the main flow, flesh out prototype, broaden the
  description from "user-invoked skills" to "the skills".
- docs/engineering/ask-matt.md: re-sync the framing to match.
- CLAUDE.md: add a maintenance rule so any future skill change triggers
  an Ask Matt re-check, beside the existing docs-page re-sync rule.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 12:25:31 +01:00
Matt PocockandGitHub 26512d74b1 Merge pull request #405 from mattpocock/rename/review-to-code-review
Rename review skill to code-review, promote to engineering
2026-07-01 12:06:56 +01:00
Matt PocockandClaude Opus 4.8 80e9dcc685 tdd: drop the refactor stage — red → green, not red → green → refactor
Refactoring belongs to the review stage, not the implementation loop.
Remove the refactor rule and the now-orphaned refactoring.md (its home is
the review skill), and point the loop's rule at the review skill so it
isn't re-added.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 09:48:57 +01:00
Matt PocockandClaude Opus 4.8 e81f97660a tdd: reshape into reference-only with pre-agreed seams
The red → green → refactor loop is anchored by leading words the model
already holds, so the step-by-step Workflow mostly restated the loop and
duplicated the horizontal-slicing anti-pattern. Drop the Workflow and
per-cycle checklist; fold their durable idea (vertical slices / tracer
bullets) into Anti-patterns and a short Rules-of-the-loop list.

Introduce **seam** as the leading word for where tests go, collapsing the
old Philosophy "public interfaces" prose and the Planning "confirm
interface / behaviors" handshake into one rule: test only at pre-agreed
seams, confirmed with the user before any test is written.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 09:43:49 +01:00
14 changed files with 226 additions and 111 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"mattpocock-skills": minor
---
Bring the **`ask-matt`** router up to date with the full skill set. It now maps five skills it was missing: **`tdd`** (woven into the main flow as the red-green engine `implement` drives), **`diagnosing-bugs`** (a new "Something's broken" on-ramp — there was previously no route for a bug), **`domain-modeling`** and **`codebase-design`** (a new "Vocabulary underneath" section), and **`grilling`** (the shared interview primitive). `prototype` is fleshed out as a standalone and the description broadens from "user-invoked skills" to "the skills". A maintenance rule is added to `CLAUDE.md` so any future skill add/rename/remove or flow change triggers an `ask-matt` re-check, beside the existing docs-page re-sync rule.
+7
View File
@@ -0,0 +1,7 @@
---
"mattpocock-skills": patch
---
Reshape the `tdd` skill into reference-only. The red → green → refactor loop is anchored by leading words the model already holds, so the step-by-step Workflow was largely restating the loop and duplicating the horizontal-slicing anti-pattern. Dropped the Workflow and per-cycle checklist; folded their one durable idea — vertical slices / tracer bullets — into the Anti-patterns section and a short Rules-of-the-loop list. Introduced **seam** as the leading word for where tests go, collapsing the old Philosophy "public interfaces" prose and the Planning "confirm interface / behaviors" handshake into one rule: test only at pre-agreed seams, confirmed with the user before any test is written.
Also dropped the refactor stage — TDD is now red → green, not red → green → refactor. Refactoring belongs to the review stage, not the implementation loop, so the refactor rule and `refactoring.md` were removed (its home is the `review` skill).
+5
View File
@@ -0,0 +1,5 @@
---
"mattpocock-skills": minor
---
Add a new user-invoked **`to-plan`** skill to the `engineering/` bucket — the sequential, HITL sibling of **`to-issues`**. Both slice work into tracer-bullet vertical slices, but where `to-issues` produces independently-grabbable issues for parallel agents, `to-plan` produces one ordered sequence you drive by hand, one phase per fresh context. It publishes to the tracker `/setup-matt-pocock-skills` configured, shaped to it: a single sequential `plan.md` for a local tracker, or a parent issue with ordered sub-issues (native sub-issues where the platform supports them) for a real one. The `to-*` fork in `ask-matt`'s main flow now offers both, and there's a human-facing docs page at `docs/engineering/to-plan.md`.
+2
View File
@@ -9,7 +9,9 @@
"./skills/engineering/setup-matt-pocock-skills", "./skills/engineering/setup-matt-pocock-skills",
"./skills/engineering/tdd", "./skills/engineering/tdd",
"./skills/engineering/to-issues", "./skills/engineering/to-issues",
"./skills/engineering/to-plan",
"./skills/engineering/to-prd", "./skills/engineering/to-prd",
"./skills/engineering/implement",
"./skills/engineering/prototype", "./skills/engineering/prototype",
"./skills/engineering/domain-modeling", "./skills/engineering/domain-modeling",
"./skills/engineering/codebase-design", "./skills/engineering/codebase-design",
+2
View File
@@ -17,4 +17,6 @@ Skills in `engineering/` and `productivity/` also have a human-facing docs page
Every `SKILL.md` is either user-invoked (`disable-model-invocation: true`, reachable only by the human) or model-invoked (model- or user-reachable). See [.agents/invocation.md](./.agents/invocation.md). Every `SKILL.md` is either user-invoked (`disable-model-invocation: true`, reachable only by the human) or model-invoked (model- or user-reachable). See [.agents/invocation.md](./.agents/invocation.md).
[`ask-matt`](./skills/engineering/ask-matt/SKILL.md) is the router that maps every user-reachable skill and how they relate. The same trigger that re-syncs a docs page applies to it: whenever you add, rename, remove, or change how a user-reachable skill fits the flows, re-read `ask-matt`'s `SKILL.md` and update it so the map stays accurate — a new skill it never mentions, or a stale one it still routes to, is a router that lies.
To (re)link every skill into the local harness skill directories (`~/.claude/skills`, `~/.agents/skills`), run `scripts/link-skills.sh`. Each entry is a symlink into this repo, so a `git pull` keeps installed skills current; re-run the script after adding, removing, or renaming a skill. To (re)link every skill into the local harness skill directories (`~/.claude/skills`, `~/.agents/skills`), run `scripts/link-skills.sh`. Each entry is a symlink into this repo, so a `git pull` keeps installed skills current; re-run the script after adding, removing, or renaming a skill.
+1
View File
@@ -155,6 +155,7 @@ Skills I use daily for code work.
- **[improve-codebase-architecture](./skills/engineering/improve-codebase-architecture/SKILL.md)** — Scan a codebase for deepening opportunities, present them as a visual HTML report, then grill through whichever one you pick. - **[improve-codebase-architecture](./skills/engineering/improve-codebase-architecture/SKILL.md)** — Scan a codebase for deepening opportunities, present them as a visual HTML report, then grill through whichever one you pick.
- **[setup-matt-pocock-skills](./skills/engineering/setup-matt-pocock-skills/SKILL.md)** — Configure this repo for the engineering skills (issue tracker, triage labels, domain doc layout). Run once per repo before using the other engineering skills. - **[setup-matt-pocock-skills](./skills/engineering/setup-matt-pocock-skills/SKILL.md)** — Configure this repo for the engineering skills (issue tracker, triage labels, domain doc layout). Run once per repo before using the other engineering skills.
- **[to-issues](./skills/engineering/to-issues/SKILL.md)** — Break any plan, spec, or PRD into independently-grabbable issues using vertical slices. - **[to-issues](./skills/engineering/to-issues/SKILL.md)** — Break any plan, spec, or PRD into independently-grabbable issues using vertical slices.
- **[to-plan](./skills/engineering/to-plan/SKILL.md)** — Turn any plan, spec, or PRD into a sequential set of tracer-bullet phases worked one at a time — a single ordered file for a local tracker, or parent-and-sub-issues for a real one.
- **[to-prd](./skills/engineering/to-prd/SKILL.md)** — Turn the current conversation into a PRD and publish it to the issue tracker. No interview — just synthesizes what you've already discussed. - **[to-prd](./skills/engineering/to-prd/SKILL.md)** — Turn the current conversation into a PRD and publish it to the issue tracker. No interview — just synthesizes what you've already discussed.
**Model-invoked** **Model-invoked**
+2 -2
View File
@@ -12,9 +12,9 @@ npx skills update ask-matt
## What it does ## What it does
`ask-matt` is the router over every user-invoked skill in this repo. You describe the situation you're in; it tells you which skill or flow fits and in what order to run them. `ask-matt` is the router over the skills in this repo. You describe the situation you're in; it tells you which skill or flow fits and in what order to run them.
It **does no work itself**. It doesn't grill, write a PRD, or fix anything — it only orients. Because these skills are user-invoked, nothing fires them for you, so *you* have to remember they exist; `ask-matt` is the memory you offload that to. It answers "which one, and when", then hands you off to the skill that actually does the job. It **does no work itself**. It doesn't grill, write a PRD, or fix anything — it only orients. It exists for the **user-invoked** skills above all: nothing fires those for you, so *you* have to remember they exist, and `ask-matt` is the memory you offload that to. It also points at the model-invoked skills you'd reach for by name — `/tdd`, `/diagnosing-bugs`, `/prototype`, `/code-review`, and the two vocabulary references, `/domain-modeling` and `/codebase-design`. It answers "which one, and when", then hands you off to the skill that actually does the job.
## When to reach for it ## When to reach for it
+53
View File
@@ -0,0 +1,53 @@
Quickstart:
```bash
npx skills add mattpocock/skills --skill=to-plan
```
```bash
npx skills update to-plan
```
[Source](https://github.com/mattpocock/skills/tree/main/skills/engineering/to-plan)
## What it does
`to-plan` turns a PRD, spec, or the current conversation into a **sequential** plan — an ordered list of phases you work through one at a time, in a fresh context per phase.
Every phase is a **tracer bullet** — a thin *vertical* slice that cuts through all integration layers end-to-end (schema, API, UI, tests), never a horizontal slice of one layer. A completed slice is demoable or verifiable on its own, and is sized to fit a single fresh context window.
## When to reach for it
You invoke this by typing `/to-plan` — the agent won't reach for it on its own.
Reach for it once you have an agreed plan or a written spec and you want it turned into a sequence of phases you'll build **by hand, one at a time**. Point it at the conversation, or pass a PRD or issue reference and it reads that first. If the change hasn't been written up as a spec yet, produce one first — for that, use [to-prd](https://aihero.dev/skills-to-prd).
## Sequential, not parallel
`to-plan` is the sequential, HITL sibling of [to-issues](https://aihero.dev/skills-to-issues). Both slice work into tracer bullets, but they're for different workflows:
- **`to-issues`** produces *independently-grabbable* issues, so parallel agents can pick them up at once (it applies the ready-for-agent label).
- **`to-plan`** produces one *ordered sequence* you drive yourself, phase by phase, staying in the loop — no ready-for-agent label.
## Publishes to your configured tracker
Like the other skills, `to-plan` publishes through the tracker [setup-matt-pocock-skills](https://aihero.dev/skills-setup-matt-pocock-skills) configured, and it adapts the shape to that tracker:
- **Local files** → a single sequential `plan.md` in the repo root, all phases in order.
- **A real issue tracker (GitHub, Linear)** → a parent issue for the whole plan, with one sub-issue per phase, in order — using the platform's native sub-issue relationship where it has one, otherwise sequential issues each blocked by the previous.
## Vertical slices, not horizontal ones
The whole skill turns on one distinction. A **horizontal** slice ships one layer of the change — all the schema, or all the API — and nothing works until every layer lands. A **vertical** slice, the tracer bullet, ships one narrow path through *every* layer at once, so it can be demoed the moment it's done.
Before slicing, `to-plan` looks for prefactoring — "make the change easy, then make the easy change" — and orders that work first. It then quizzes you on the breakdown (granularity, ordering, what to merge or split) before publishing anything.
## Where it fits
`to-plan` is the sequential branch of the main build chain:
```txt
grill-with-docs → to-prd → to-plan → implement → code-review
```
It sits between [to-prd](https://aihero.dev/skills-to-prd), which hands it a settled spec to slice against, and [implement](https://aihero.dev/skills-implement), which builds each phase, driving [tdd](https://aihero.dev/skills-tdd) internally to write the tests test-first, before its [code-review](https://aihero.dev/skills-code-review) pass. Work one phase per fresh context, clearing between them. When you're unsure which skill or flow fits, [ask-matt](https://aihero.dev/skills-ask-matt) routes you.
+1
View File
@@ -12,6 +12,7 @@ Reachable only when you type them (`disable-model-invocation: true`).
- **[improve-codebase-architecture](./improve-codebase-architecture/SKILL.md)** — Scan a codebase for deepening opportunities, present them as a visual HTML report, then grill through whichever one you pick. - **[improve-codebase-architecture](./improve-codebase-architecture/SKILL.md)** — Scan a codebase for deepening opportunities, present them as a visual HTML report, then grill through whichever one you pick.
- **[setup-matt-pocock-skills](./setup-matt-pocock-skills/SKILL.md)** — Configure this repo for the engineering skills (issue tracker, triage labels, domain doc layout). Run once per repo. - **[setup-matt-pocock-skills](./setup-matt-pocock-skills/SKILL.md)** — Configure this repo for the engineering skills (issue tracker, triage labels, domain doc layout). Run once per repo.
- **[to-issues](./to-issues/SKILL.md)** — Break any plan, spec, or PRD into independently-grabbable issues using vertical slices. - **[to-issues](./to-issues/SKILL.md)** — Break any plan, spec, or PRD into independently-grabbable issues using vertical slices.
- **[to-plan](./to-plan/SKILL.md)** — Turn any plan, spec, or PRD into a sequential set of tracer-bullet phases worked one at a time — a single ordered file for a local tracker, or parent-and-sub-issues for a real one.
- **[to-prd](./to-prd/SKILL.md)** — Turn the current conversation into a PRD and publish it to the issue tracker. - **[to-prd](./to-prd/SKILL.md)** — Turn the current conversation into a PRD and publish it to the issue tracker.
## Model-invoked ## Model-invoked
+18 -6
View File
@@ -1,6 +1,6 @@
--- ---
name: ask-matt name: ask-matt
description: Ask which skill or flow fits your situation. A router over the user-invoked skills in this repo. description: Ask which skill or flow fits your situation. A router over the skills in this repo.
disable-model-invocation: true disable-model-invocation: true
--- ---
@@ -8,22 +8,24 @@ disable-model-invocation: true
You don't remember every skill, so ask. You don't remember every skill, so ask.
A **flow** is a path through the skills. Most paths run along one **main flow**, and two **on-ramps** merge onto it. Everything else is standalone. A **flow** is a path through the skills. Most paths run along one **main flow**, and two **on-ramps** merge onto it. Everything else is standalone, or a vocabulary layer that runs underneath.
## The main flow: idea → ship ## The main flow: idea → ship
The route most work travels. You have an idea and want it built. The route most work travels. You have an idea and want it built.
1. **`/grill-with-docs`** — sharpen the idea by interview. Start here when you **have a codebase**: it's stateful, retaining what it learns in `CONTEXT.md` and ADRs. (No codebase? Use `/grill-me` — see Standalone.) 1. **`/grill-with-docs`** — sharpen the idea by interview. Start here when you **have a codebase**: it's stateful, retaining what it learns in `CONTEXT.md` and ADRs. (No codebase? Use `/grill-me` — see Standalone. Both run the same `/grilling` primitive; `grill-with-docs` is the one that leaves a paper trail.)
2. **Branch — can you settle every question in conversation?** If a question needs a runnable answer (state, business logic, a UI you have to see), detour through a prototype, bridged by **`/handoff`** in both directions (see Crossing sessions): 2. **Branch — can you settle every question in conversation?** If a question needs a runnable answer (state, business logic, a UI you have to see), detour through a prototype, bridged by **`/handoff`** in both directions (see Crossing sessions):
- **`/handoff`** out, then open a fresh session against that file, - **`/handoff`** out, then open a fresh session against that file,
- **`/prototype`** to answer the question with throwaway code, - **`/prototype`** to answer the question with throwaway code,
- **`/handoff`** back what you learned, and reference it from the original idea thread. - **`/handoff`** back what you learned, and reference it from the original idea thread.
3. **Branch — is this a multi-session build?** 3. **Branch — is this a multi-session build?**
- **Yes** → **`/to-prd`** (turn the thread into a PRD)**`/to-issues`** (split the PRD into independently-grabbable issues). Because the issues are independent, **clear context between each one**: start a fresh session per issue and kick off **`/implement`** by passing it the PRD and the single issue to work on. - **Yes** → **`/to-prd`** (turn the thread into a PRD), then split it into tracer-bullet slices one of two ways:
- **`/to-issues`** — independently-grabbable issues on your tracker, for **parallel/AFK** agents. Because the issues are independent, **clear context between each one** and kick off **`/implement`** per issue.
- **`/to-plan`** — a **sequential** plan you drive **by hand**, staying in the loop. Publishes to the same tracker, shaped to it: a single ordered `plan.md` for a local tracker, or a parent issue with ordered sub-issues for a real one. Work one phase per fresh context, clearing between them, with **`/implement`**.
- **No** → **`/implement`** right here, in the same context window. - **No** → **`/implement`** right here, in the same context window.
Either way, `/implement` closes out by running **`/code-review`** a two-axis review (Standards + Spec) of the diff before committing. Reach for **`/code-review`** on its own whenever you want to review a branch or PR against a fixed point. Either way, **`/implement`** builds each issue by driving **`/tdd`** internally — one red-green slice at a time — then closes out by running **`/code-review`**, a two-axis review (Standards + Spec) of the diff, before committing. Reach for **`/tdd`** on its own when you just want to build a concrete behaviour test-first without a full spec, and **`/code-review`** on its own whenever you want to review a branch or PR against a fixed point.
### Context hygiene ### Context hygiene
@@ -39,11 +41,20 @@ A starting situation that generates work, then merges onto the main flow.
Triage is only for issues **you didn't create** — bug reports, incoming feature requests, anything that arrives raw. Issues that `/to-issues` produced are already agent-ready, so **don't triage them**. Triage is only for issues **you didn't create** — bug reports, incoming feature requests, anything that arrives raw. Issues that `/to-issues` produced are already agent-ready, so **don't triage them**.
- **Something's broken** → **`/diagnosing-bugs`**. For the hard ones: the bug that resists a first glance, the intermittent flake, the regression that crept in between two known-good states. It refuses to theorise until it has a **tight feedback loop** — one command that already goes red on *this* bug — then fixes with a regression test. Its post-mortem hands off to **`/improve-codebase-architecture`** when the real finding is that there's no good seam to lock the bug down.
## Codebase health ## Codebase health
Not feature work — upkeep. Not feature work — upkeep.
- **`/improve-codebase-architecture`** — run whenever you have a spare moment to keep the codebase good for agents to operate in. It surfaces deepening opportunities; picking one _generates an idea_ you can take into the main flow at `/grill-with-docs`. - **`/improve-codebase-architecture`** — run whenever you have a spare moment to keep the codebase good for agents to operate in. It surfaces **deepening opportunities**; picking one _generates an idea_ you can take into the main flow at `/grill-with-docs`. It's the survey that finds the candidates; **`/codebase-design`** (below) is the bench you design the chosen one on.
## Vocabulary underneath
Two model-invoked references that run *beneath* the other skills — each the single source of truth for its vocabulary. Reach for them directly when the **words**, not the process, are the problem; or let the skills above pull them in.
- **`/domain-modeling`** — sharpen the project's *domain* language: challenge a fuzzy term, resolve an overloaded word ("account" doing three jobs), record a hard-to-reverse decision as an ADR. It's the active discipline `/grill-with-docs` drives to keep `CONTEXT.md` a clean glossary.
- **`/codebase-design`** — the deep-module vocabulary (module, interface, depth, seam, adapter, leverage, locality) for designing a module's *shape*: a lot of behaviour behind a small interface at a clean seam. `/tdd` and `/improve-codebase-architecture` both speak it.
## Crossing sessions ## Crossing sessions
@@ -55,6 +66,7 @@ Not feature work — upkeep.
Off the main flow entirely. Off the main flow entirely.
- **`/grill-me`** — the same relentless interview as `/grill-with-docs`, but for when you have **no codebase**. Stateless: it saves nothing locally, builds no `CONTEXT.md`. Reach for it to sharpen any plan or design that doesn't live in a repo. - **`/grill-me`** — the same relentless interview as `/grill-with-docs`, but for when you have **no codebase**. Stateless: it saves nothing locally, builds no `CONTEXT.md`. Reach for it to sharpen any plan or design that doesn't live in a repo.
- **`/prototype`** — a small, throwaway program that answers one design question: does this state model feel right, or what should this UI look like. Throwaway from day one — keep the answer, delete the code. It's the detour in step 2 of the main flow, but reach for it any time a design question is hard to settle on paper.
- **`/teach`** — learn a concept over multiple sessions, using the current directory as a stateful workspace. - **`/teach`** — learn a concept over multiple sessions, using the current directory as a stateful workspace.
- **`/writing-great-skills`** — reference for writing and editing skills well. - **`/writing-great-skills`** — reference for writing and editing skills well.
+16 -91
View File
@@ -5,107 +5,32 @@ description: Test-driven development. Use when the user wants to build features
# Test-Driven Development # Test-Driven Development
## Philosophy TDD is the red → green loop. This skill is the reference that makes that loop produce tests worth keeping: what a good test is, where tests go, the anti-patterns, and the rules of the loop. Every section applies on every cycle — consult them before and during the loop, not after.
**Core principle**: Tests should verify behavior through public interfaces, not implementation details. Code can change entirely; tests shouldn't. When exploring the codebase, read `CONTEXT.md` (if it exists) so test names and interface vocabulary match the project's domain language, and respect ADRs in the area you're touching.
**Good tests** are integration-style: they exercise real code paths through public APIs. They describe _what_ the system does, not _how_ it does it. A good test reads like a specification - "user can checkout with valid cart" tells you exactly what capability exists. These tests survive refactors because they don't care about internal structure. ## What a good test is
**Bad tests** are coupled to implementation. They mock internal collaborators, test private methods, or verify through external means (like querying a database directly instead of using the interface). The warning sign: your test breaks when you refactor, but behavior hasn't changed. If you rename an internal function and tests fail, those tests were testing implementation, not behavior. Tests verify behavior through public interfaces, not implementation details. Code can change entirely; tests shouldn't. A good test reads like a specification — "user can checkout with valid cart" tells you exactly what capability exists — and survives refactors because it doesn't care about internal structure.
**Tautological tests** restate the implementation inside the assertion, so they pass by construction and give zero confidence. When the expected value is computed the way the code computes it — `expect(add(a, b)).toBe(a + b)`, snapshotting a figure you derived by hand the same way the code does, asserting a constant equals itself — the test can never disagree with the code: break the code wrong and the assertion breaks wrong with it. The expected value must come from an independent source of truth — a known-good literal, a worked example, the spec.
See [tests.md](tests.md) for examples and [mocking.md](mocking.md) for mocking guidelines. See [tests.md](tests.md) for examples and [mocking.md](mocking.md) for mocking guidelines.
## Anti-Pattern: Horizontal Slices ## Seams — where tests go
**DO NOT write all tests first, then all implementation.** This is "horizontal slicing" - treating RED as "write all tests" and GREEN as "write all code." A **seam** is the public boundary you test at: the interface where you observe behavior without reaching inside. Tests live at seams, never against internals.
This produces **crap tests**: **Test only at pre-agreed seams.** Before writing any test, write down the seams under test and confirm them with the user. No test is written at an unconfirmed seam. You can't test everything — agreeing the seams up front is how testing effort lands on the critical paths and complex logic instead of every edge case.
- Tests written in bulk test _imagined_ behavior, not _actual_ behavior Ask: "What's the public interface, and which seams should we test?"
- You end up testing the _shape_ of things (data structures, function signatures) rather than user-facing behavior
- Tests become insensitive to real changes - they pass when behavior breaks, fail when behavior is fine
- You outrun your headlights, committing to test structure before understanding the implementation
**Correct approach**: Vertical slices via tracer bullets. One test → one implementation → repeat. Each test responds to what you learned from the previous cycle. Because you just wrote the code, you know exactly what behavior matters and how to verify it. ## Anti-patterns
``` - **Implementation-coupled** — mocks internal collaborators, tests private methods, or verifies through a side channel (querying the database instead of using the interface). The tell: the test breaks when you refactor but behavior hasn't changed.
WRONG (horizontal): - **Tautological** — the assertion recomputes the expected value the way the code does (`expect(add(a, b)).toBe(a + b)`, a snapshot derived by hand the same way, a constant asserted equal to itself), so it passes by construction and can never disagree with the code. Expected values must come from an independent source of truth — a known-good literal, a worked example, the spec.
RED: test1, test2, test3, test4, test5 - **Horizontal slicing** — writing all tests first, then all implementation. Bulk tests verify _imagined_ behavior: you test the _shape_ of things rather than user-facing behavior, the tests go insensitive to real changes, and you commit to test structure before understanding the implementation. Work in **vertical slices** instead — one test → one implementation → repeat, each test a **tracer bullet** that responds to what the last cycle taught you.
GREEN: impl1, impl2, impl3, impl4, impl5
RIGHT (vertical): ## Rules of the loop
RED→GREEN: test1→impl1
RED→GREEN: test2→impl2
RED→GREEN: test3→impl3
...
```
## Workflow - **Red before green.** Write the failing test first, then only enough code to pass it. Don't anticipate future tests or add speculative features.
- **One slice at a time.** One seam, one test, one minimal implementation per cycle.
### 1. Planning - **Refactoring is not part of the loop.** It belongs to the review stage (see the `review` skill), not the red → green implementation cycle.
When exploring the codebase, read `CONTEXT.md` (if it exists) so that test names and interface vocabulary match the project's domain language, and respect ADRs in the area you're touching.
Before writing any code:
- [ ] Confirm with user what interface changes are needed
- [ ] Confirm with user which behaviors to test (prioritize)
- [ ] Identify opportunities for deep modules (small interface, deep implementation) — run the `/codebase-design` skill for the vocabulary and the testability checks
- [ ] List the behaviors to test (not implementation steps)
- [ ] Get user approval on the plan
Ask: "What should the public interface look like? Which behaviors are most important to test?"
**You can't test everything.** Confirm with the user exactly which behaviors matter most. Focus testing effort on critical paths and complex logic, not every possible edge case.
### 2. Tracer Bullet
Write ONE test that confirms ONE thing about the system:
```
RED: Write test for first behavior → test fails
GREEN: Write minimal code to pass → test passes
```
This is your tracer bullet - proves the path works end-to-end.
### 3. Incremental Loop
For each remaining behavior:
```
RED: Write next test → fails
GREEN: Minimal code to pass → passes
```
Rules:
- One test at a time
- Only enough code to pass current test
- Don't anticipate future tests
- Keep tests focused on observable behavior
### 4. Refactor
After all tests pass, look for [refactor candidates](refactoring.md):
- [ ] Extract duplication
- [ ] Deepen modules (move complexity behind simple interfaces)
- [ ] Apply SOLID principles where natural
- [ ] Consider what new code reveals about existing code
- [ ] Run tests after each refactor step
**Never refactor while RED.** Get to GREEN first.
## Checklist Per Cycle
```
[ ] Test describes behavior, not implementation
[ ] Test uses public interface only
[ ] Test would survive internal refactor
[ ] Expected values are independent literals, not recomputed from the code
[ ] Code is minimal for this test
[ ] No speculative features added
```
-10
View File
@@ -1,10 +0,0 @@
# Refactor Candidates
After TDD cycle, look for:
- **Duplication** → Extract function/class
- **Long methods** → Break into private helpers (keep tests on public interface)
- **Shallow modules** → Combine or deepen
- **Feature envy** → Move logic to where data lives
- **Primitive obsession** → Introduce value objects
- **Existing code** the new code reveals as problematic
+2 -2
View File
@@ -24,11 +24,11 @@ Look for opportunities to prefactor the code to make the implementation easier.
### 3. Draft vertical slices ### 3. Draft vertical slices
Break the plan into **tracer bullet** issues. Each issue is a thin vertical slice that cuts through ALL integration layers end-to-end, NOT a horizontal slice of one layer. Break the plan into **tracer bullet** issues.
<vertical-slice-rules> <vertical-slice-rules>
- Each slice delivers a narrow but COMPLETE path through every layer (schema, API, UI, tests) - Each slice cuts a narrow but COMPLETE path through every layer (schema, API, UI, tests) — vertical, NOT a horizontal slice of one layer
- A completed slice is demoable or verifiable on its own - A completed slice is demoable or verifiable on its own
- Any prefactoring should be done first - Any prefactoring should be done first
+112
View File
@@ -0,0 +1,112 @@
---
name: to-plan
description: Turn a PRD, spec, or the current conversation into a sequential plan of tracer-bullet vertical slices, published to the configured tracker — one ordered file for local, or parent-and-sub-issues for a real tracker.
disable-model-invocation: true
---
# To Plan
Turn a plan, spec, or PRD into a **sequential** plan of vertical slices (tracer bullets) — an ordered list of phases you work through one at a time, in a fresh context per phase.
This is the sequential, HITL sibling of `/to-issues`. Where `to-issues` produces independently-grabbable issues for parallel agents, `to-plan` produces one ordered sequence you drive by hand, top to bottom.
The issue tracker and triage label vocabulary should have been provided to you — run `/setup-matt-pocock-skills` if not.
## Process
### 1. Gather context
Work from whatever is already in the conversation context. If the user passes a reference (a PRD path, an issue number or URL) as an argument, fetch it and read its full body.
### 2. Explore the codebase (optional)
If you have not already explored the codebase, do so to understand the current state of the code. Phase titles and descriptions should use the project's domain glossary vocabulary, and respect ADRs in the area you're touching.
Look for opportunities to prefactor the code to make the implementation easier. "Make the change easy, then make the easy change."
### 3. Draft vertical slices
Break the work into **tracer bullet** phases.
<vertical-slice-rules>
- Each slice cuts a narrow but COMPLETE path through every layer (schema, API, UI, tests) — vertical, NOT a horizontal slice of one layer
- A completed slice is demoable or verifiable on its own
- Each slice is sized to fit in a single fresh context window
- Any prefactoring should be done first
</vertical-slice-rules>
Order the phases in dependency order — each builds on the ones before it.
### 4. Quiz the user
Present the proposed breakdown as a numbered list. For each phase, show:
- **Title**: short descriptive name
- **What it delivers**: the end-to-end behaviour this phase makes work
Ask the user:
- Does the granularity feel right? (too coarse / too fine)
- Is the ordering correct — does each phase build on the ones before it?
- Should any phases be merged or split further?
Iterate until the user approves the breakdown.
### 5. Publish the plan to the configured tracker
Publish the approved phases in order. **How** depends on the tracker `/setup-matt-pocock-skills` configured:
- **Local files** → write one sequential `plan.md` in the repo root, all phases in order, using the file template below.
- **A real issue tracker (GitHub, Linear, …)** → create **one parent issue** for the whole plan, then **one sub-issue per phase, in order**. Use the platform's native sub-issue / child-issue relationship if it supports one; otherwise create sequential issues and set each phase's "Blocked by" to the previous phase. Use the issue template below for the parent and each phase.
These are worked **sequentially by hand**, not handed to parallel agents, so do NOT apply the ready-for-agent triage label.
<plan-file-template>
# Plan: <short name of the work>
A one-line summary of what this plan builds. Reference the source PRD or spec if there is one.
## Phases
Each phase is one tracer bullet — a vertical slice worked in a fresh context, top to bottom.
### 1. <Phase title>
**Delivers:** the end-to-end behaviour this phase makes work, from the user's perspective — not a layer-by-layer implementation list.
- [ ] Acceptance criterion 1
- [ ] Acceptance criterion 2
### 2. <Phase title>
...
</plan-file-template>
<issue-template>
**Parent issue** — title: the plan's short name. Body: the one-line summary, a reference to the source PRD/spec, and the ordered list of phase titles.
**Each phase sub-issue:**
## What to build
The end-to-end behaviour this phase makes work, from the user's perspective — not layer-by-layer implementation.
## Acceptance criteria
- [ ] Criterion 1
- [ ] Criterion 2
## Blocked by
The previous phase (omit for the first phase).
</issue-template>
In either form, avoid specific file paths or code snippets — they go stale fast. Exception: if a prototype produced a snippet that encodes a decision more precisely than prose can (state machine, reducer, schema, type shape), inline it and note briefly that it came from a prototype. Trim to the decision-rich parts — not a working demo, just the important bits.
Work the plan one phase at a time with `/implement`, clearing context between phases.