mirror of
https://github.com/mattpocock/skills.git
synced 2026-09-12 18:38:06 +07:00
Compare commits
155
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
71eb50346f | ||
|
|
6b46e5c474 | ||
|
|
f4dd5e4976 | ||
|
|
a3065f1b7b | ||
|
|
3314257466 | ||
|
|
c64fa7ecf6 | ||
|
|
248fd6935b | ||
|
|
50777fcc09 | ||
|
|
c66bdeeee0 | ||
|
|
006ca0546b | ||
|
|
355fa7420b | ||
|
|
f958fa17c1 | ||
|
|
3e18e04260 | ||
|
|
4f6e25d91e | ||
|
|
fa1e3227fb | ||
|
|
ad98b80dbd | ||
|
|
c474642895 | ||
|
|
a621cc4f75 | ||
|
|
b3376f8d39 | ||
|
|
b405fe0a2e | ||
|
|
d53cabc383 | ||
|
|
a2f9333669 | ||
|
|
bfdaef8e98 | ||
|
|
1495d01430 | ||
|
|
5626acd11a | ||
|
|
32af39b277 | ||
|
|
294a2c97c5 | ||
|
|
f054defc3f | ||
|
|
38d62e71ed | ||
|
|
0f2bdbdb06 | ||
|
|
1fc6573e0e | ||
|
|
6bcbcb09e2 | ||
|
|
a4b2009a1a | ||
|
|
14b92236dd | ||
|
|
950dc79bb0 | ||
|
|
781efca60a | ||
|
|
4b2d9a8a8a | ||
|
|
a557705dcb | ||
|
|
9c470b321d | ||
|
|
f1df19e6b0 | ||
|
|
41283677d6 | ||
|
|
d4e8664be2 | ||
|
|
2ab958093e | ||
|
|
369c264e23 | ||
|
|
6e742d6441 | ||
|
|
ad5ee1e12f | ||
|
|
fa3b2a6b35 | ||
|
|
17f22a371b | ||
|
|
ed37663cc5 | ||
|
|
9c32629965 | ||
|
|
b8fd9afa42 | ||
|
|
9603c1cc81 | ||
|
|
fde4cd58cf | ||
|
|
c70cb09193 | ||
|
|
e9fcdf95b4 | ||
|
|
7f68c06dcb | ||
|
|
bbce2f91d6 | ||
|
|
66898f60e8 | ||
|
|
0ac3f3fbf1 | ||
|
|
697d4ce974 | ||
|
|
8f4952b6a3 | ||
|
|
d3275456a4 | ||
|
|
04fee67571 | ||
|
|
33dfc9b28f | ||
|
|
8eb8f58f0f | ||
|
|
3bb587fa5c | ||
|
|
170ad48655 | ||
|
|
2602257241 | ||
|
|
45afd8074a | ||
|
|
6704a52ac4 | ||
|
|
7d694b7ae9 | ||
|
|
f15b4dca01 | ||
|
|
e74fee89fe | ||
|
|
42a5b70fca | ||
|
|
391a2701dd | ||
|
|
2ee14df19c | ||
|
|
fa460cbf09 | ||
|
|
3687fb4f38 | ||
|
|
3ea30afc68 | ||
|
|
f947f93b92 | ||
|
|
d80ff7a840 | ||
|
|
0375c88bfb | ||
|
|
30a9c7447f | ||
|
|
89d370d181 | ||
|
|
19c50d50fd | ||
|
|
e4722b8e65 | ||
|
|
371b9c9c94 | ||
|
|
44eed54518 | ||
|
|
cdec9f6eb2 | ||
|
|
d6274600ab | ||
|
|
d574778f94 | ||
|
|
47845ac1e1 | ||
|
|
cc1e24891d | ||
|
|
d6e21b661d | ||
|
|
0557d57579 | ||
|
|
639df6e738 | ||
|
|
d29732e49f | ||
|
|
09a72ba465 | ||
|
|
386d4ff719 | ||
|
|
c5a4a8c2e9 | ||
|
|
93f73198e3 | ||
|
|
896f14d9c2 | ||
|
|
d869d45afc | ||
|
|
8515a080a7 | ||
|
|
f219e66379 | ||
|
|
aa591116bf | ||
|
|
a0329ba957 | ||
|
|
16a2a5cd00 | ||
|
|
ce908a6220 | ||
|
|
d05f2fb5b5 | ||
|
|
e5932a7a47 | ||
|
|
af6d6922c3 | ||
|
|
30afefecc9 | ||
|
|
acf55d88b7 | ||
|
|
0847bb31bc | ||
|
|
7be28cf5e6 | ||
|
|
80f29a4f29 | ||
|
|
5a7f7e5c2a | ||
|
|
9b43c3359b | ||
|
|
ad99c73a2d | ||
|
|
55511cea24 | ||
|
|
d11147daaf | ||
|
|
0172e61e57 | ||
|
|
66f92b61f5 | ||
|
|
97dca07b64 | ||
|
|
7d34a8dc38 | ||
|
|
3ea01314c1 | ||
|
|
299eb0c017 | ||
|
|
4691566bbb | ||
|
|
913a105881 | ||
|
|
c808f64f92 | ||
|
|
53c6219cd2 | ||
|
|
272f99b225 | ||
|
|
6f9e9956fd | ||
|
|
efa058a349 | ||
|
|
8c2a4c554a | ||
|
|
b289481499 | ||
|
|
e9dea692fd | ||
|
|
bd453a6742 | ||
|
|
aed86f6b35 | ||
|
|
e1c025eaee | ||
|
|
0e9a072792 | ||
|
|
1445797da5 | ||
|
|
8cc3328633 | ||
|
|
5f45f2e35a | ||
|
|
728826c9d2 | ||
|
|
1f16ea9499 | ||
|
|
a83f22b60f | ||
|
|
b25e2b3787 | ||
|
|
e0d0d84274 | ||
|
|
5a7ee93f01 | ||
|
|
8347a41614 | ||
|
|
8f3401d1a1 | ||
|
|
f8d12710f7 | ||
|
|
0d74d01cbc |
@@ -4,7 +4,7 @@ Engineering skills depend on per-repo config (issue tracker, triage label vocabu
|
|||||||
|
|
||||||
We split these into **hard-dependency** and **soft-dependency** skills:
|
We split these into **hard-dependency** and **soft-dependency** skills:
|
||||||
|
|
||||||
- **Hard dependency** (`to-issues`, `to-prd`, `triage`) — include an explicit one-liner: _"… should have been provided to you — run `/setup-matt-pocock-skills` if not."_ Without the mapping, output is wrong, not just fuzzy.
|
- **Hard dependency** (`to-tickets`, `to-spec`, `triage`) — include an explicit one-liner: _"… should have been provided to you — run `/setup-matt-pocock-skills` if not."_ Without the mapping, output is wrong, not just fuzzy.
|
||||||
- **Soft dependency** (`diagnose`, `tdd`, `improve-codebase-architecture`) — reference "the project's domain glossary" and "ADRs in the area you're touching" in vague prose only. If the docs aren't there, the skill still works; output is just less sharp.
|
- **Soft dependency** (`diagnose`, `tdd`, `improve-codebase-architecture`) — reference "the project's domain glossary" and "ADRs in the area you're touching" in vague prose only. If the docs aren't there, the skill still works; output is just less sharp.
|
||||||
|
|
||||||
The split keeps soft-dependency skills token-light and avoids cargo-culting the setup pointer into places where it isn't load-bearing.
|
The split keeps soft-dependency skills token-light and avoids cargo-culting the setup pointer into places where it isn't load-bearing.
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
# Ship the skill set as a native Claude Code plugin; defer a native Codex plugin
|
||||||
|
|
||||||
|
These skills have always been installable via [skills.sh](https://skills.sh/mattpocock/skills) (`npx skills add mattpocock/skills`), which copies editable skill files into a user's project across Claude Code, Codex, and other Agent-Skills-standard harnesses. A recurring request is a **plug-and-play** distribution: subscribe to the set as a read-only, always-current bundle you don't edit, rather than a fork you own. That is exactly what native plugin systems provide.
|
||||||
|
|
||||||
|
We ship a native **Claude Code plugin** and, for now, **defer** a native **Codex plugin**. The split is forced by how each ecosystem's plugin manifest selects skills, against this repo's bucketed layout.
|
||||||
|
|
||||||
|
## The constraint: bucketed skills vs. single-path selection
|
||||||
|
|
||||||
|
Skills live in bucket folders under `skills/` — `engineering/` and `productivity/` are **promoted** (shipped); `misc/`, `personal/`, `in-progress/`, and `deprecated/` are **not**. A plugin must expose only the promoted set, which spans two of those bucket folders.
|
||||||
|
|
||||||
|
- **Claude Code** — `.claude-plugin/plugin.json` accepts `skills` as an **array of explicit skill-directory paths**. We list the promoted skills one by one, exclude everything else with zero ambiguity, and add `.claude-plugin/marketplace.json` so the repo is its own single-plugin marketplace. Verified end to end: `claude plugin validate . --strict` passes, and `marketplace add` → `install` resolves all promoted skills.
|
||||||
|
|
||||||
|
- **Codex** — `.codex-plugin/plugin.json` accepts `skills` only as a **single path string** (arrays are rejected with `missing or invalid plugin.json`), and Codex discovers `SKILL.md` files recursively under it. There is no way to name two bucket folders, or to curate a subset, from one path. Two escape hatches were tested and rejected:
|
||||||
|
- Pointing at `./skills/` would also ship `deprecated/`, `in-progress/`, `personal/`, and `misc/` — retired, draft, and personal skills we deliberately don't promote.
|
||||||
|
- A curated flat directory of **symlinks** into the buckets does not survive install: Codex copies the plugin tree into its cache and **drops symlinks**, so the skills arrive empty.
|
||||||
|
|
||||||
|
The only robust ways to give Codex a single promoted-only path are (a) **restructure** so `skills/` contains only promoted skills (moving the non-promoted buckets out — a large blast radius across `CLAUDE.md`, `scripts/link-skills.sh`, the bucket READMEs, and the local dev workflow that relies on `in-progress/` and `personal/`), or (b) **commit duplicate copies** of promoted skills into a flat directory (a sync burden and a second source of truth). Both are structural decisions, not something to bundle into shipping the Claude plugin. This is very likely the original, half-remembered reason a plugin wasn't shipped earlier: the manifest formats didn't cleanly express a curated subset of a bucketed repo.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
- Ship the **Claude Code plugin** now (`.claude-plugin/plugin.json` + `.claude-plugin/marketplace.json`), curated to the promoted set, as the headline v1.2 deliverable.
|
||||||
|
- Keep **skills.sh** as the universal installer — it already serves Codex and other harnesses today, so no Codex user is left without an install path.
|
||||||
|
- **Defer** the native Codex plugin until we decide between restructuring `skills/` to promoted-only vs. committing a generated flat copy. Revisit when Codex either supports a `skills` array / include-list or preserves symlinks on install.
|
||||||
|
|
||||||
|
## Invariants this creates
|
||||||
|
|
||||||
|
- Every promoted skill has an entry in `.claude-plugin/plugin.json`'s `skills` array (this already stood as a `CLAUDE.md` rule; it now also gates the plugin's contents).
|
||||||
|
- `.claude-plugin/plugin.json`'s `version` tracks `package.json`'s version — bump both together on release. Claude uses the plugin `version` to decide when installed users see an update.
|
||||||
|
|
||||||
|
## Update, 2026-08-05
|
||||||
|
|
||||||
|
`mattpocock-skills` was accepted into **Claude Code's official marketplace** — configured name `claude-plugins-official`, source repo `anthropics/claude-plugins-official` — which every Claude Code install has by default. `claude plugins install mattpocock-skills` is now the documented route, and the `marketplace add` → `install` path above is superseded. The install wording lives in [.agents/install-block.md](../install-block.md).
|
||||||
|
|
||||||
|
The official listing points at this repo's git URL and reads `.claude-plugin/plugin.json` directly, so it does not depend on `.claude-plugin/marketplace.json`. That file is retained only as a fallback for installing the repo directly (an unreleased commit, or a fork).
|
||||||
|
|
||||||
|
Verified 2026-08-05, on Claude Code 2.1.222, against the live listing:
|
||||||
|
|
||||||
|
- `claude plugins install mattpocock-skills` resolves with no marketplace added first, and reports `mattpocock-skills@claude-plugins-official`.
|
||||||
|
- `claude plugin details mattpocock-skills` then reports version 1.2.0 and loads the promoted skills.
|
||||||
|
- The listing's `source` is `{"source": "url", "url": "https://github.com/mattpocock/skills.git", "sha": …}` — the **sha is pinned**, so a release reaches installed users when that pin moves, not the moment we tag. At the time of writing the pin sits two commits behind `main`, which is why it lists 22 skills rather than the 24 in `plugin.json`.
|
||||||
|
- The in-session `/plugin install mattpocock-skills` was **not** exercised — `/plugin` is unavailable in headless (`claude -p`) sessions. It runs the same resolver as the CLI, and the documented example form is `/plugin install <name>@claude-plugins-official`.
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
# The canonical install block
|
||||||
|
|
||||||
|
One install story, one wording. `README.md`, `.changeset/*`, and every page under `docs/` must say **this** and nothing else. Change it here first, then propagate.
|
||||||
|
|
||||||
|
`mattpocock-skills` is listed in **Claude Code's official marketplace** — configured name `claude-plugins-official`, source repo `anthropics/claude-plugins-official` — which every Claude Code install has out of the box. There is no marketplace to add first. Official Anthropic marketplaces have auto-update enabled by default ([discover-plugins](https://code.claude.com/docs/en/discover-plugins)), so "updates arrive automatically" is a true claim, not a hope.
|
||||||
|
|
||||||
|
## Claude Code — the plugin
|
||||||
|
|
||||||
|
<canonical-block name="claude-code">
|
||||||
|
|
||||||
|
```bash
|
||||||
|
claude plugins install mattpocock-skills
|
||||||
|
```
|
||||||
|
|
||||||
|
Or, from inside a session:
|
||||||
|
|
||||||
|
```
|
||||||
|
/plugin install mattpocock-skills
|
||||||
|
```
|
||||||
|
|
||||||
|
It's in Claude Code's official marketplace, so there's nothing to add first, and updates arrive automatically.
|
||||||
|
|
||||||
|
</canonical-block>
|
||||||
|
|
||||||
|
## Codex, and other agents — skills.sh
|
||||||
|
|
||||||
|
The plugin is Claude Code only. Everywhere else, [skills.sh](https://skills.sh/mattpocock/skills) copies editable skill files into the project. Use the whole-set form on `README.md`:
|
||||||
|
|
||||||
|
<canonical-block name="skills-sh-whole-set">
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx skills@latest add mattpocock/skills
|
||||||
|
```
|
||||||
|
|
||||||
|
Pick the skills you want, and which coding agents to install them on. **The installer lets you choose which skills to take — make sure `setup-matt-pocock-skills` is one of them.**
|
||||||
|
|
||||||
|
</canonical-block>
|
||||||
|
|
||||||
|
…and the single-skill form wherever one skill is named on its own. Note that **`docs/` pages are not a consumer of this block**: ai-hero renders the install widget above the body, so a page that writes the commands out duplicates it. See [writing-docs.md](./writing-docs.md).
|
||||||
|
|
||||||
|
<canonical-block name="skills-sh-one-skill">
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx skills@latest add mattpocock/skills --skill=<name>
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx skills@latest update <name>
|
||||||
|
```
|
||||||
|
|
||||||
|
</canonical-block>
|
||||||
|
|
||||||
|
`skills@latest` is the pinned spelling in all three. The pages under `docs/` used to carry their own copy of these commands; those blocks are now deleted rather than corrected, because the site renders the install commands itself.
|
||||||
|
|
||||||
|
## The two routes are exclusive
|
||||||
|
|
||||||
|
The plugin is a managed, read-only bundle you subscribe to. skills.sh writes files you own and edit. Installing both leaves the user with every skill twice — always say "pick one".
|
||||||
|
|
||||||
|
## Not the install story
|
||||||
|
|
||||||
|
`.claude-plugin/marketplace.json` makes the repo its own single-plugin marketplace (`/plugin marketplace add mattpocock/skills`, then `/plugin install mattpocock-skills@mattpocock`). The official listing supersedes it. It is kept as a fallback for installing the repo directly — an unreleased commit, or a fork — and is **not** documented to users.
|
||||||
@@ -2,10 +2,12 @@
|
|||||||
|
|
||||||
Every `SKILL.md` in this repo is a skill. The one axis that splits them is **invocation** — who can reach it:
|
Every `SKILL.md` in this repo is a skill. The one axis that splits them is **invocation** — who can reach it:
|
||||||
|
|
||||||
- **User-invoked** — reachable **only by the human typing its name**. Set `disable-model-invocation: true` in the frontmatter. The `description` is **human-facing**: a one-line summary read by a person browsing slash-commands. Strip trigger lists ("Use when the user says…").
|
- **User-invoked** — reachable **only by the human typing its name**. Set `disable-model-invocation: true` in the frontmatter (Claude Code) and `policy.allow_implicit_invocation: false` in `agents/openai.yaml` (Codex). The `description` is **human-facing**: a one-line summary read by a person browsing slash-commands. Strip trigger lists ("Use when the user says…").
|
||||||
- **Model-invoked** — reachable by **model or user**. The default: omit `disable-model-invocation`. The `description` is **model-facing** and keeps rich trigger phrasing ("Use when the user wants…, mentions…, asks for…") so auto-invocation fires. The test for whether a skill should stay model-invoked: _could the model usefully reach for this autonomously?_ (Reuse is the reason to extract a skill, not the test.)
|
- **Model-invoked** — reachable by **model or user**. The default: omit `disable-model-invocation` and the `policy` block from `agents/openai.yaml`. The `description` is **model-facing** and keeps rich trigger phrasing ("Use when the user wants…, mentions…, asks for…") so auto-invocation fires. The test for whether a skill should stay model-invoked: _could the model usefully reach for this autonomously?_ (Reuse is the reason to extract a skill, not the test.)
|
||||||
|
|
||||||
Because a user-invoked skill has no description, nothing but the human can reach it — no other skill can fire it. So a user-invoked skill may invoke model-invoked skills, but it can never reach another user-invoked skill.
|
Each harness excludes a user-invoked skill from the model's reach in its own way, so nothing but the human can fire it — no other skill can. A user-invoked skill may invoke model-invoked skills, but it can never reach another user-invoked skill.
|
||||||
|
|
||||||
|
Every skill also carries an `agents/openai.yaml` beside its `SKILL.md`. It holds Codex UI metadata — `interface.display_name` and `interface.short_description` for the skill picker — and, for user-invoked skills, the `policy.allow_implicit_invocation: false` that pairs with `disable-model-invocation`. Keep the two in sync: a skill is user-invoked in both harnesses or neither.
|
||||||
|
|
||||||
Bucket `README.md`s and the top-level `README.md` group entries into **User-invoked** and **Model-invoked**.
|
Bucket `README.md`s and the top-level `README.md` group entries into **User-invoked** and **Model-invoked**.
|
||||||
|
|
||||||
|
|||||||
+10
-20
@@ -1,10 +1,10 @@
|
|||||||
# Writing docs pages
|
# Writing docs pages
|
||||||
|
|
||||||
Every skill in `engineering/` and `productivity/` has a human-facing **docs page** at `docs/<bucket>/<skill-name>.md` — the docs tree mirrors those two bucket folders under `skills/`. It is published at `https://aihero.dev/skills-<skill-name>`; the URL is always `skills-<skill-name>` regardless of bucket, so the docs path is repo organisation only. The page is not the skill and not a copy of `SKILL.md`. Only these two buckets are promoted; the rest (`misc/`, `personal/`, `in-progress/`, `deprecated/`) ship no docs page.
|
Every skill in `engineering/` and `productivity/` has a human-facing **docs page** at `docs/<bucket>/<skill-name>.md` — the docs tree mirrors those two bucket folders under `skills/`. It is published at `https://aihero.dev/skills-<skill-name>`; the URL is always `skills-<skill-name>` regardless of bucket, so the docs path is repo organisation only. The page is not the skill and not a copy of `SKILL.md`. Only these two buckets are promoted; the rest (`misc/`, `in-progress/`, `deprecated/`) ship no docs page.
|
||||||
|
|
||||||
Most of these skills are **user-invoked**: the agent will never fire them for you, so *you* are the index that has to remember they exist and when to reach for them. That memory is **cognitive load**. The job of a docs page is to relieve it — to orient one reader around one skill so they can hold it in their head, know when to reach for it, and see where it sits in the system. The pages are collectively a distributed router; each is a node.
|
Most of these skills are **user-invoked**: the agent will never fire them for you, so *you* are the index that has to remember they exist and when to reach for them. That memory is **cognitive load**. The job of a docs page is to relieve it — to orient one reader around one skill so they can hold it in their head, know when to reach for it, and see where it sits in the system. The pages are collectively a distributed router; each is a node.
|
||||||
|
|
||||||
Act whenever a promoted skill is added, renamed, or has its behaviour changed: create or re-sync its docs page. A rename moves the file too (`docs/<bucket>/<old>.md` → `docs/<bucket>/<new>.md`), because the published URL tracks the name; a skill that moves between `engineering/` and `productivity/` moves its docs file to the matching folder. Skills in `misc/`, `personal/`, `in-progress/`, and `deprecated/` get no page — none of those buckets is promoted. A skill moving *out* of one of them into `engineering/` or `productivity/` gains a page; one moving the other way loses it.
|
Act whenever a promoted skill is added, renamed, or has its behaviour changed: create or re-sync its docs page. A rename moves the file too (`docs/<bucket>/<old>.md` → `docs/<bucket>/<new>.md`), because the published URL tracks the name; a skill that moves between `engineering/` and `productivity/` moves its docs file to the matching folder. Skills in `misc/`, `in-progress/`, and `deprecated/` get no page — none of those buckets is promoted. A skill moving *out* of one of them into `engineering/` or `productivity/` gains a page; one moving the other way loses it.
|
||||||
|
|
||||||
Because these pages are published on `aihero.dev`, **every link is absolute** — never a repo-relative path. A link to another skill points at `https://aihero.dev/skills-<name>`; a link into the repo points at its full `https://github.com/mattpocock/skills/...` URL. A relative link that works in the repo breaks once published.
|
Because these pages are published on `aihero.dev`, **every link is absolute** — never a repo-relative path. A link to another skill points at `https://aihero.dev/skills-<name>`; a link into the repo points at its full `https://github.com/mattpocock/skills/...` URL. A relative link that works in the repo breaks once published.
|
||||||
|
|
||||||
@@ -12,25 +12,15 @@ There is no H1 — the published page takes its title from the slug.
|
|||||||
|
|
||||||
## Page structure
|
## Page structure
|
||||||
|
|
||||||
Fill the template below. The **fixed frame** (Quickstart block, source link, `## What it does`, `## When to reach for it`, `## Where it fits`) appears on every page. The **adaptable middle** — `## Prerequisites` and the free-form substance sections — carries only what this particular skill earns; delete the rest.
|
Fill the template below. The **fixed frame** (`## What it does`, `## When to reach for it`, `## Where it fits`) appears on every page. The **adaptable middle** — `## Prerequisites` and the free-form substance sections — carries only what this particular skill earns; delete the rest.
|
||||||
|
|
||||||
|
**A page carries no install commands.** The ai-hero page template renders the install widget itself — a copy button, the single-skill command, the whole-set command, and the update line — above the body. A page that also writes them out shows the reader the same command twice, and the two copies drift: the hand-written pair on every page went stale against the widget beside it. Install wording is a property of the site, not of the page. If it needs changing, change it in ai-hero; the canonical wording lives in [the install block](./install-block.md).
|
||||||
|
|
||||||
<page-template>
|
<page-template>
|
||||||
|
|
||||||
Quickstart:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx skills add mattpocock/skills --skill=<name>
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx skills update <name>
|
|
||||||
```
|
|
||||||
|
|
||||||
[Source](https://github.com/mattpocock/skills/tree/main/skills/<bucket>/<name>)
|
|
||||||
|
|
||||||
## What it does
|
## What it does
|
||||||
|
|
||||||
One or two plain-language paragraphs. Lead with the skill's one-sentence job, then state the **defining constraint** — the single fact that makes this skill behave differently from the obvious default (for `to-prd`: it does not interview the user again, it synthesises what is already known). Write it as a plain declarative sentence — never a labelled aside like "The defining constraint:" or "The key thing:"; the formula reads as filler. This line is the most valuable on the page; never omit it.
|
One or two plain-language paragraphs. Lead with the skill's one-sentence job, then state the **defining constraint** — the single fact that makes this skill behave differently from the obvious default (for `to-spec`: it does not interview the user again, it synthesises what is already known). Write it as a plain declarative sentence — never a labelled aside like "The defining constraint:" or "The key thing:"; the formula reads as filler. This line is the most valuable on the page; never omit it.
|
||||||
|
|
||||||
## When to reach for it
|
## When to reach for it
|
||||||
|
|
||||||
@@ -41,7 +31,7 @@ How and when you reach for the skill — two beats, both effectively always pres
|
|||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
Optional — include only when the skill needs something in place to be functional; omit the heading entirely otherwise. Covers: a **workspace it writes into** (a stateful skill like `grill-with-docs` writes `CONTEXT.md` and ADRs; `teach` builds a whole directory — say what it writes and where), **prior setup** (`triage`/`to-prd`/`to-issues` need `setup-matt-pocock-skills` to have configured an issue tracker), or **repo-specific tooling**. A stateless skill that runs anywhere has no prerequisites — drop the section.
|
Optional — include only when the skill needs something in place to be functional; omit the heading entirely otherwise. Covers: a **workspace it writes into** (a stateful skill like `grill-with-docs` writes `CONTEXT.md` and ADRs; `teach` builds a whole directory — say what it writes and where), **prior setup** (`triage`/`to-spec`/`to-tickets` need `setup-matt-pocock-skills` to have configured an issue tracker), or **repo-specific tooling**. A stateless skill that runs anywhere has no prerequisites — drop the section.
|
||||||
|
|
||||||
## <free-form middle>
|
## <free-form middle>
|
||||||
|
|
||||||
@@ -51,13 +41,13 @@ The single non-negotiable: **surface the skill's leading word / defining idea**
|
|||||||
|
|
||||||
## It's working if
|
## It's working if
|
||||||
|
|
||||||
Optional. A short, checkable list of the observable signals that tell the reader the skill is actually doing its job — what they should see when it fires, and by absence when it hasn't. Include it when a skill has crisp tells (e.g. `to-prd` writes without re-interviewing you; a leading word reappearing in the trace); omit the heading when the signals are vague. A few bullets, no more.
|
Optional. A short, checkable list of the observable signals that tell the reader the skill is actually doing its job — what they should see when it fires, and by absence when it hasn't. Include it when a skill has crisp tells (e.g. `to-spec` writes without re-interviewing you; a leading word reappearing in the trace); omit the heading when the signals are vague. A few bullets, no more.
|
||||||
|
|
||||||
## Where it fits
|
## Where it fits
|
||||||
|
|
||||||
Always present. Situate the skill in the system in a sentence or two:
|
Always present. Situate the skill in the system in a sentence or two:
|
||||||
|
|
||||||
- **Role.** Name it: a **chain step** (`grill-with-docs → to-prd → to-issues → implement → code-review`), a **run-once setup** (`setup-matt-pocock-skills`), **periodic maintenance** (`improve-codebase-architecture`, "every few days"), or a **reach-for-it-anytime standalone** (`diagnosing-bugs`, `prototype`, `handoff`). A standalone's map is one honest sentence — far better than omitting the section.
|
- **Role.** Name it: a **chain step** (`grill-with-docs → to-spec → to-tickets → implement → code-review`), a **run-once setup** (`setup-matt-pocock-skills`), **periodic maintenance** (`improve-codebase-architecture`, "every few days"), or a **reach-for-it-anytime standalone** (`diagnosing-bugs`, `prototype`, `handoff`). A standalone's map is one honest sentence — far better than omitting the section.
|
||||||
- **Neighbours.** The one or two siblings that matter, each with a because-clause, linked absolutely.
|
- **Neighbours.** The one or two siblings that matter, each with a because-clause, linked absolutely.
|
||||||
- **The map.** Point to [ask-matt](https://aihero.dev/skills-ask-matt), the router over the whole set, so this page stays a node and never has to redraw the graph.
|
- **The map.** Point to [ask-matt](https://aihero.dev/skills-ask-matt), the router over the whole set, so this page stays a node and never has to redraw the graph.
|
||||||
|
|
||||||
@@ -72,7 +62,7 @@ Always present. Situate the skill in the system in a sentence or two:
|
|||||||
## Done when
|
## Done when
|
||||||
|
|
||||||
- The page exists at `docs/<bucket>/<name>.md`, and no stale page survives a rename or bucket move.
|
- The page exists at `docs/<bucket>/<name>.md`, and no stale page survives a rename or bucket move.
|
||||||
- The Quickstart block and source link name the correct bucket and skill; the update line names the skill.
|
- The page carries no source link and writes no install command of its own.
|
||||||
- `## What it does` states the defining constraint, as plain prose rather than a labelled aside.
|
- `## What it does` states the defining constraint, as plain prose rather than a labelled aside.
|
||||||
- `## When to reach for it` states invocation mode and the trigger boundary.
|
- `## When to reach for it` states invocation mode and the trigger boundary.
|
||||||
- `## Where it fits` names the role and links to `ask-matt`.
|
- `## Where it fits` names the role and links to `ask-matt`.
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
"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.
|
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
"mattpocock-skills": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Give `/ask-matt` the **phase boundary** decision tree, replacing the two-bullet `Crossing sessions` section.
|
||||||
|
|
||||||
|
A **phase** is a chunk of work inside a session — the grilling, the implementation, the QA — and the boundary between two of them is where you decide what to do with the context you've built. The router now carries all five options in order (**continue**, `/clear`, `/handoff`, **subagent**, `/compact`), with the ordered tree and its reasoning disclosed in a new `PHASE-BOUNDARIES.md`. Three fixes come with it:
|
||||||
|
|
||||||
|
- **`/handoff` was oversold.** It read as the general bridge between context windows. It's narrow: you need it only when something has to *travel* — a new harness, a new directory, a colleague, or a side task forked mid-phase. What it buys is portability.
|
||||||
|
- **`/compact` is the default, not the first reach.** It sits at the bottom of the tree, after the four cheaper or more precise questions above it. Starting there produces a session that's confidently wrong about whatever the summary flattened.
|
||||||
|
- **Two branches were missing entirely.** **Continue** is the one to rule out first — it's the only move that keeps the conversation as a primary source rather than a summary of one — and a **subagent** handles anything scoped tightly enough to run AFK.
|
||||||
|
|
||||||
|
Context hygiene's escape hatch now says `/compact` rather than `/handoff` (same harness, same directory, at a boundary — the handoff clause doesn't apply), and the smart zone figure is updated from ~120k to ~150k tokens.
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
"mattpocock-skills": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Make `/ask-matt` clued-up about `/wayfinder` — the heaviest, most cognitively demanding flow.
|
||||||
|
|
||||||
|
The router now sharpens the two routing mistakes people most often make with wayfinder:
|
||||||
|
|
||||||
|
- **Over-reaching for it.** It's slower and denser than a single grill, so it's flagged as the heaviest flow and reserved for the idea that genuinely won't fit one session — a well-scoped feature belongs on `/grill-with-docs`, not here.
|
||||||
|
- **Losing the way at the handoff.** When the map clears, wayfinder hands off, it doesn't build: merge onto the main flow at `/to-spec` (which collapses the map's linked decisions into a buildable plan) rather than looping the map straight into `/implement`. Straight-to-`/implement` is only for efforts that turned out genuinely small.
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
"mattpocock-skills": minor
|
|
||||||
---
|
|
||||||
|
|
||||||
Rename the in-progress **`review`** skill to **`code-review`** and promote it from `in-progress/` to the `engineering/` bucket. It now ships in the plugin, is listed in the top-level and Engineering READMEs (Model-invoked), and has a human-facing docs page at `docs/engineering/code-review.md`. The `/implement` skill and docs now point at `/code-review`.
|
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
"mattpocock-skills": minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Add Codex metadata alongside each skill's Claude Code frontmatter so the set works in both harnesses without generated copies.
|
||||||
|
|
||||||
|
- Add an `agents/openai.yaml` beside every `SKILL.md` with Codex UI metadata (`interface.display_name`, `interface.short_description`).
|
||||||
|
- Mark every user-invoked skill with `policy.allow_implicit_invocation: false`, the Codex analog of `disable-model-invocation: true`, so Codex excludes it from implicit invocation while explicit `$skill` invocation still works.
|
||||||
|
- Document the dual-harness invocation model in `.agents/invocation.md`, `CLAUDE.md`, and the promoted-bucket READMEs.
|
||||||
|
- Add `AGENTS.md` as a symlink to `CLAUDE.md` so Codex reads the same repo instructions.
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
"mattpocock-skills": minor
|
|
||||||
---
|
|
||||||
|
|
||||||
Add a fourth **Task** ticket type to the **`decision-mapping`** skill. Some blockers are neither a decision, a prototype, nor research — just literal manual work that has to happen before the discussion can move forward (moving data, signing up for a third-party service, provisioning access). The agent automates it where it can, otherwise hands the human a precise checklist, and records any resulting facts later tickets depend on.
|
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
"mattpocock-skills": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Drop the hand-written Quickstart block from all 25 docs pages.
|
||||||
|
|
||||||
|
aihero.dev already renders an install widget above every skill page — a copy button, the single-skill command, the whole-set command, and the update line. Each page then wrote the same two commands out again immediately below it. The reader saw the install command twice.
|
||||||
|
|
||||||
|
The two copies had also drifted apart. The widget renders the current `npx skills@latest …` wording; the hand-written blocks still carried the older bare `npx skills …`, so most pages showed the correct command and a stale one, one after the other.
|
||||||
|
|
||||||
|
Deleting the block removes those stale copies and leaves the site's own. `.agents/writing-docs.md` now states the rule directly — install wording is a property of the site, not of the page — and its template no longer carries a Quickstart to copy.
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
---
|
||||||
|
"mattpocock-skills": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Rewrite the `grill-me` docs page around what people actually get wrong.
|
||||||
|
|
||||||
|
The old page explained the mechanism — rounds, the frontier, the decision tree — and stopped there. Every recurring question from the last few months went unanswered on it: which of the three grilling skills to reach for, how many questions is normal, what to do when a question can't be answered by talking, and whether to start a fresh session before writing the spec.
|
||||||
|
|
||||||
|
The rewrite keeps the mechanism short and spends the page on the judgement calls instead:
|
||||||
|
|
||||||
|
- **Sibling routing** is now a three-way list keyed on what you have in front of you — no codebase, a codebase, or too big for one session — rather than a paragraph.
|
||||||
|
- **"It's a conversation, not an interview"** names passivity as the main failure mode. A session where you answer "agreed" forty times produces a plan you didn't write and can't defend.
|
||||||
|
- **"Grillable and ungrillable"** gives readers the move for a question that talking cannot settle: stop, prototype, come back. This is where long sessions come from.
|
||||||
|
- **A "Common questions" section** answers the six highest-volume ones directly, including how to restore one-question-at-a-time and why you should not clear context before `to-spec`.
|
||||||
|
- **"It's working if"** added, led by the sharpest signal: if you never disagreed, you didn't need the session.
|
||||||
|
|
||||||
|
Also drops the "plan mode" ambiguity by saying plainly to leave it off.
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
"mattpocock-skills": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Make `/setup-matt-pocock-skills` friendlier and align the local-markdown tracker with the current spec.
|
||||||
|
|
||||||
|
- **Triage labels** are now asked about only when the `triage` skill is installed, and then as a single recommended-yes question ("keep the default triage labels?") instead of an override interrogation. When `triage` isn't installed, the section — and `docs/agents/triage-labels.md` — are skipped.
|
||||||
|
- **External PRs as a request surface** is no longer a setup question. The GitHub/GitLab templates still carry the flag, defaulted off; a user can flip it in `docs/agents/issue-tracker.md` later.
|
||||||
|
- **Domain docs** default to single-context without asking; multi-context is only offered when the repo shows monorepo signals.
|
||||||
|
- **Local-markdown tickets** are now one file per ticket under `.scratch/<feature>/issues/<NN>-<slug>.md` — never a single combined `tickets.md`. `/to-tickets` and the local issue-tracker template now agree, and the spec file is `spec.md` (not `PRD.md`) to match `/to-spec`.
|
||||||
|
|
||||||
|
Docs pages for `setup-matt-pocock-skills` and `to-tickets` re-synced.
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
"mattpocock-skills": minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Graduate **`to-questionnaire`** out of `in-progress/` into the **Productivity** bucket, so it ships in the plugin. It turns a decision you can't answer alone into a Markdown questionnaire for the one person who can — filled in async, or worked through together in a meeting.
|
||||||
|
|
||||||
|
Its defining move is that it grills you about the **send**, not the subject: a normal grilling session interrogates the topic, which is exactly what you can't answer here, so the interview asks only who the questionnaire is going to and what you need back, then aims every question at the gap between the two.
|
||||||
|
|
||||||
|
Now wired as a promoted skill — plugin entry, top-level + Productivity READMEs under **User-invoked**, a docs page at `docs/productivity/to-questionnaire.md`, and a Standalone route in `ask-matt` framing it as the inverse of `/grill-me` (mine someone else, not yourself).
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
"mattpocock-skills": minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Graduate **`wizard`** out of `in-progress/` into the **Engineering** bucket, so it ships in the plugin. It generates an interactive bash script that walks a human through a manual procedure — third-party setup, a one-off migration, an A→B state transition — opening each URL, saying what to click, capturing the values, and writing them into `.env` files and GitHub Actions secrets.
|
||||||
|
|
||||||
|
The delightful UX is pre-solved by the bundled `template.sh` (progress with time-remaining, confirmation gates, cross-platform URL opening including WSL, hidden secret entry, idempotent `.env` upserts, `gh secret`/`gh variable` writes with graceful degradation, closing skip summary). Everything above the `STAGES` marker is a fixed library that's never hand-edited — the skill's job is only to scope the procedure and author its **stages**.
|
||||||
|
|
||||||
|
Engineering rather than Productivity: it reads `.env*`, `docker-compose*`, framework config and every `secrets.*`/`vars.*` reference in `.github/workflows/` to scope itself, writes CI secrets, and verifies its output with `bash -n` and `shellcheck`.
|
||||||
|
|
||||||
|
Now wired as a promoted skill — plugin entry, top-level + Engineering READMEs under **User-invoked**, a docs page at `docs/engineering/wizard.md`, and a Standalone route in `ask-matt` for the steps only a human can take.
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"mattpocock-skills": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Reword **`grilling`** for general use. Its description and body no longer scope the interview to a software plan: "this plan" → "this", "enact the plan" → "act on it", and "exploring the codebase" → "exploring the environment". The technique is unchanged; it now reads as a stress-test of any plan, decision, or idea.
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"mattpocock-skills": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Pin the question format in **`grilling`**. Every question in a round is now emitted in one fixed shape — `❓ **Q1** - **<title>**`, then the body (prose or multiple choices), then the recommendation on its own `➡️` line. A round reads as a scannable numbered list with each recommendation visually separated from the question, so you can answer by number instead of quoting questions back.
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"mattpocock-skills": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Rework **`grilling`** from one-question-at-a-time to round-by-round. It now maps the decision tree and asks the whole **frontier** — every question whose prerequisites are already settled — in a single numbered round, then recomputes the frontier from the user's answers and asks the next round. Same 13 questions land in ~3 rounds instead of 13. Facts the environment can answer are dispatched to background sub-agents so research never blocks the round: only questions downstream of a running exploration wait for it. The session ends when the frontier is empty.
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"mattpocock-skills": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Sync the skills and docs that still described grilling as a **one-question-at-a-time** interview. Since the round-by-round rework, `grill-me`, `grill-with-docs` and `triage` all run the frontier a round at a time — their pages, `triage`'s grill step and `grilling`'s Codex `short_description` now say so. The opt-out for the old rhythm (a line in your global `CLAUDE.md`) is unchanged.
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"mattpocock-skills": minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Reshape the **`prototype`** skill's logic branch to produce a **single shareable HTML file** instead of a terminal app. The demo is one self-contained file (plain HTML/CSS/JS, no build, no server) a non-developer can open by double-click and drive in their own domain language: a labelled state panel, always-available free-play buttons, and a set of tabbed **guided walkthroughs** — each a scenario with the ordered buttons to press underneath it. The portable pure-logic module still lifts into the real code; the HTML shell is the throwaway primary source.
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
"mattpocock-skills": minor
|
|
||||||
---
|
|
||||||
|
|
||||||
Make the **`prototype`** skill model-invoked, so the agent can reach for it autonomously (and other skills can too). Its description is rewritten around the leading word _prototype_ — throwaway code that answers a design question — with one trigger per branch (state/logic sanity-check, or UI exploration).
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"mattpocock-skills": minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Reword how the **`prototype`** skill handles its artifacts around a single idea: **the prototype is a primary source**. Rather than being deleted once it's answered its question, the prototype is captured as runnable evidence on a throwaway branch (`prototype/<name>`) out of main, with a context pointer to it left on the implementation issue — so the main branch keeps only the validated decision while the exploration stays findable. The answer (verdict + question) is still captured durably in an issue/ADR/commit.
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
---
|
||||||
|
"mattpocock-skills": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Remove six skills from the repo. None of them was in the Claude Code plugin, but all six were installable through [skills.sh](https://skills.sh/mattpocock/skills), which serves every skill in the repo — so this is what leaves that listing, and where each one went.
|
||||||
|
|
||||||
|
Four retired skills, each already absorbed by a skill that does the job better:
|
||||||
|
|
||||||
|
- **`ubiquitous-language`** → **`/domain-modeling`**, which builds and maintains the whole domain model rather than dumping a glossary from one conversation.
|
||||||
|
- **`design-an-interface`** → **`/codebase-design`**. Nothing is lost: the "design it twice" technique — parallel sub-agents generating radically different designs, from Ousterhout — ships inside that skill as `DESIGN-IT-TWICE.md`.
|
||||||
|
- **`qa`** → **`/triage`** and **`/to-tickets`**.
|
||||||
|
- **`request-refactor-plan`** → **`/to-spec`** and **`/improve-codebase-architecture`**.
|
||||||
|
|
||||||
|
And two that were only ever mine — tied to my own machine and never meant for anyone else. The `personal/` bucket goes with them:
|
||||||
|
|
||||||
|
- **`edit-article`**
|
||||||
|
- **`obsidian-vault`**, which hardcoded a path to my own Obsidian vault.
|
||||||
|
|
||||||
|
`skills/deprecated/` stays as a bucket, now empty. `skills/in-progress/` is unchanged and is now described for what it actually is: a beta channel, published on purpose, installable one skill at a time through skills.sh.
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
"mattpocock-skills": patch
|
|
||||||
---
|
|
||||||
|
|
||||||
Give the in-progress **`code-review`** skill an always-on Fowler smell baseline on its Standards axis. A curated ~12 high-signal "Bad Smells in Code" (Mysterious Name, Duplicated Code, Feature Envy, Data Clumps, Primitive Obsession, Repeated Switches, Shotgun Surgery, Divergent Change, Speculative Generality, Message Chains, Middle Man, Refused Bequest) are inlined into `SKILL.md` as a fixed baseline alongside whatever the repo documents — not a new third axis. Two binding rules keep it safe: a documented repo standard overrides the baseline, and every smell is reported as a judgement call, never a hard violation.
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
---
|
||||||
|
"mattpocock-skills": minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Ship the skill set as a native **Claude Code plugin**, listed in Claude Code's official marketplace. You can now subscribe to the promoted skills as a managed, read-only bundle instead of copying editable files:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
claude plugins install mattpocock-skills
|
||||||
|
```
|
||||||
|
|
||||||
|
Or, from inside a session:
|
||||||
|
|
||||||
|
```
|
||||||
|
/plugin install mattpocock-skills
|
||||||
|
```
|
||||||
|
|
||||||
|
There is no marketplace to add first — the official marketplace is configured by default.
|
||||||
|
|
||||||
|
`.claude-plugin/plugin.json` carries the full plugin metadata (version, description, author, license, keywords) and the explicit list of promoted skills. `skills.sh` remains the universal installer (and the path for Codex and other harnesses today); a native Codex plugin is deferred — see `.agents/adr/0002-ship-as-a-claude-code-plugin.md` for why.
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
"mattpocock-skills": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Finish the `to-prd` → `to-spec` rename: "spec" is now the only term in the shipped text.
|
||||||
|
|
||||||
|
- **`to-spec`** no longer opens with "you may know this document as a PRD" — the parenthetical is dropped from the skill and its docs page. The local-markdown tracker template drops the same hedge.
|
||||||
|
- **`code-review`** talks about the originating issue/spec rather than issue/PRD, in its frontmatter description, its two-axis summary, and the spec-source search order. Both READMEs re-synced.
|
||||||
|
- **The GitHub and GitLab tracker templates** now say "Issues and specs for this repo live as GitHub/GitLab issues" — they had been left on "PRDs" when the local template was updated, so the stale term propagated into every repo they were written into.
|
||||||
|
- **`docs/engineering/research.md`** pointed at `https://aihero.dev/skills-to-prd`, a dead slug for the renamed skill; it now links `to-spec` like the other nineteen docs pages do.
|
||||||
|
|
||||||
|
The CHANGELOG and existing changesets still name PRDs where they document the rename itself, which is correct.
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
---
|
|
||||||
"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).
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
"mattpocock-skills": patch
|
|
||||||
---
|
|
||||||
|
|
||||||
Add the **tautological test** anti-pattern to the `tdd` skill. Tests whose assertion is recomputed the way the code computes it pass by construction and give zero confidence — distinct from the implementation-coupling anti-pattern already covered. Added as a peer at the same three sites: a Philosophy principle (expected values must come from an independent source of truth), a per-cycle checklist gate, and a BAD/GOOD example pair in `tests.md`.
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
"mattpocock-skills": patch
|
|
||||||
---
|
|
||||||
|
|
||||||
Extend the **`triage`** skill to triage external pull requests, treating a PR as an issue with attached code that runs through the same roles and state machine. PRs flow inline alongside issues (gated by a per-repo setup toggle), discovery surfaces only external PRs, the bug-only "reproduce" step is generalized into a single "verify the claim" step, and a redundancy check resolves already-implemented requests to `wontfix` without polluting the out-of-scope knowledge base. `setup-matt-pocock-skills` gains the PRs-as-a-request-surface toggle for GitHub/GitLab.
|
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
"mattpocock-skills": minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Add **`wait-what`** — a fire extinguisher for model verbosity. Fire it the moment a message doesn't land, and the agent re-pitches it: a little context, ASD-STE100 Simplified Technical English, and the ubiquitous language from your `CONTEXT.md`. User-invoked, three lines long.
|
||||||
|
|
||||||
|
The mechanism is the name. Concision skills fail by growing — a 400-line skill still leaves the model verbose — so this one is a single precise leading word and nothing else. Names that describe the *output* (`/tldr`, `/no-fluff`) make the model clip words and lose you further; naming the *listener's* state asks for both halves at once, fewer words **and** the context you were missing. It also reuses the leading words already in your global `CLAUDE.md`, so the skill, `CLAUDE.md` and every `CONTEXT.md` reach for the same tokens.
|
||||||
|
|
||||||
|
It's the extinguisher, not the sprinkler. The cure for jargon is a shared language built upfront with `/grill-with-docs`; this is the in-the-moment corrective for when you don't have one yet.
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
---
|
|
||||||
"mattpocock-skills": minor
|
|
||||||
---
|
|
||||||
|
|
||||||
Make **`wayfinder`** collaborative by moving the map off a local Markdown file and onto the repo's issue tracker.
|
|
||||||
|
|
||||||
The map is now a single `wayfinder:map` issue whose tickets are its child issues — one shared URL the whole team can watch and comment on. Blocking, claiming (`wayfinder:claimed`), and the frontier query all use native tracker semantics, so a session loads the map at low resolution (Notes + one context pointer per closed ticket + Fog prose) and zooms into individual tickets on demand, instead of loading the whole map every time.
|
|
||||||
|
|
||||||
Wayfinder stays tracker-agnostic: the per-tracker mechanics live behind a pointer in `docs/agents/issue-tracker.md`, so `setup-matt-pocock-skills` now seeds a "Wayfinding operations" section for GitHub, GitLab, and local-markdown. Absent that doc, Wayfinder defaults to local-markdown.
|
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
"mattpocock-skills": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Name the `/wayfinder` unit a **decision ticket**.
|
||||||
|
|
||||||
|
People kept reading a wayfinder ticket as an ordinary *implementation* ticket — a slice of a build to execute — when wayfinder uses them as **decision tickets**: questions whose resolution is a decision. The skill description and its opening line now introduce "decision ticket" (and say what makes it one), and the `ask-matt` / engineering README wayfinder blurbs and the docs page match — while "ticket" stays the everyday word once the term is established. `CONTEXT.md` records **Decision ticket** as a domain term so the "avoid: ticket" guidance no longer contradicts wayfinder's deliberate use of the word.
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
---
|
|
||||||
"mattpocock-skills": minor
|
|
||||||
---
|
|
||||||
|
|
||||||
Make **`wayfinder`**'s no-duplication contract explicit: the map is an **index**, not a store.
|
|
||||||
|
|
||||||
Adopting "index" as the leading word for the map's role fixes two duplication risks. The map now states up front that a decision lives in exactly one place — its ticket — so it only ever gists and links, never restates the answer (previously this rule was implied inside an HTML comment in the map-body template). And graduating fog into a ticket now clears the graduated patch from the Fog, so a suspected question can't linger in both places at once.
|
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
"mattpocock-skills": minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Wayfinder now burns research tickets down with subagents instead of leaving them parked for a separately-launched session.
|
||||||
|
|
||||||
|
Research stays a real ticket type — it's a genuine shared blocker that downstream decisions hang on, and that dependency is exactly what the frontier's blocking edges exist to render. What changes is how it's resolved: because research is AFK, charting doesn't stop and read it. After creating the tickets, the charting session fires a `/research` subagent for each research ticket to burn it down in parallel, capturing the findings on a throwaway `research/<name>` branch with a context pointer. Research tickets are the one exception to *one ticket per session*.
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
---
|
|
||||||
"mattpocock-skills": minor
|
|
||||||
---
|
|
||||||
|
|
||||||
Rename the **`decision-mapping`** skill to **`wayfinder`**, invoked as `/wayfinder`.
|
|
||||||
|
|
||||||
"Decision map" was jargony and inaccurate — only one of the skill's four ticket types (Grilling) is actually a decision. The reframe charts a route through a foggy problem, resolving investigation tickets one at a time until the way to the goal is clear. This makes one coherent leading-word frame (fog of war / frontier / the map) instead of mixing an invented term on top of it.
|
|
||||||
|
|
||||||
Also a pruning pass: unified `node`→`ticket`, bound "the frontier" to the unblocked tickets, dropped the duplicated "one question at a time" (owned by `/grilling`), and trimmed intro no-ops.
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"mattpocock-skills": minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Extend **`writing-for-agents`**' pruning section with a new leading word: **cache**. Single source of truth now reaches past the document into the environment — `package.json` scripts, config files, directory layout, `--help` output are themselves authoritative, so a doc that restates them is a cache of a lookup, earning its load only when the lookup is expensive. The positive target: cache what the agent cannot find by looking (unwritten conventions, the reason behind a choice, gotchas no config confesses), and leave one-file, one-command lookups to the environment, where they cannot go stale.
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"mattpocock-skills": minor
|
||||||
|
---
|
||||||
|
|
||||||
|
**Breaking:** rename **`writing-great-skills`** → **`writing-for-agents`** and restructure it. The reference now covers any document an agent consumes — skills, `AGENTS.md` / `CLAUDE.md`, docs reached by a pointer — not just skills. `GLOSSARY.md` is merged into `SKILL.md` (one authoritative treatment per term; the `_Avoid_` synonym lists and the standalone Predictability definition are gone); the skill-only mechanics (frontmatter, model- vs user-invoked, router skills, the invocation cut of splitting) are disclosed to a new `SKILL-MECHANICS.md`. The skill is now **model-invoked**: it fires when creating or editing skills or modifying `AGENTS.md`/`CLAUDE.md`. `ask-matt`'s pointer updated. Reinstall under the new name; the old name is gone (no alias).
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"mattpocock-skills": minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Add a YAGNI scoping filter to the **`improve-codebase-architecture`** skill's Explore step. Instead of scanning the whole repo evenly, it now scopes to where change is actually landing: if you name a direction it takes it, otherwise it reads the last ~20 commit messages to bias exploration toward actively-developed paths. A deepening opportunity in code nobody touches is a refactor you'll never cash in — the leverage only pays off where you keep editing — so the report stops tidying dormant corners of the repo.
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"name": "mattpocock",
|
||||||
|
"owner": {
|
||||||
|
"name": "Matt Pocock",
|
||||||
|
"url": "https://www.aihero.dev"
|
||||||
|
},
|
||||||
|
"description": "Matt Pocock's skills for real engineering, as an installable Claude Code plugin.",
|
||||||
|
"plugins": [
|
||||||
|
{
|
||||||
|
"name": "mattpocock-skills",
|
||||||
|
"source": "./",
|
||||||
|
"description": "Matt Pocock's agent skills for real engineering — grilling, spec/ticket flows, TDD, code review, domain modelling and more.",
|
||||||
|
"category": "engineering",
|
||||||
|
"keywords": [
|
||||||
|
"engineering",
|
||||||
|
"skills",
|
||||||
|
"tdd",
|
||||||
|
"code-review",
|
||||||
|
"grilling"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -1,5 +1,23 @@
|
|||||||
{
|
{
|
||||||
"name": "mattpocock-skills",
|
"name": "mattpocock-skills",
|
||||||
|
"version": "1.2.0",
|
||||||
|
"description": "Matt Pocock's agent skills for real engineering — grilling, spec/ticket flows, TDD, code review, domain modelling and more. Plug-and-play, not vibe coding.",
|
||||||
|
"author": {
|
||||||
|
"name": "Matt Pocock",
|
||||||
|
"url": "https://www.aihero.dev"
|
||||||
|
},
|
||||||
|
"homepage": "https://www.aihero.dev/s/skills-newsletter",
|
||||||
|
"repository": "https://github.com/mattpocock/skills",
|
||||||
|
"license": "MIT",
|
||||||
|
"keywords": [
|
||||||
|
"engineering",
|
||||||
|
"skills",
|
||||||
|
"tdd",
|
||||||
|
"code-review",
|
||||||
|
"grilling",
|
||||||
|
"domain-modeling",
|
||||||
|
"productivity"
|
||||||
|
],
|
||||||
"skills": [
|
"skills": [
|
||||||
"./skills/engineering/ask-matt",
|
"./skills/engineering/ask-matt",
|
||||||
"./skills/engineering/diagnosing-bugs",
|
"./skills/engineering/diagnosing-bugs",
|
||||||
@@ -8,17 +26,23 @@
|
|||||||
"./skills/engineering/improve-codebase-architecture",
|
"./skills/engineering/improve-codebase-architecture",
|
||||||
"./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-spec",
|
||||||
"./skills/engineering/to-prd",
|
"./skills/engineering/to-tickets",
|
||||||
|
"./skills/engineering/wayfinder",
|
||||||
"./skills/engineering/implement",
|
"./skills/engineering/implement",
|
||||||
"./skills/engineering/prototype",
|
"./skills/engineering/prototype",
|
||||||
|
"./skills/engineering/research",
|
||||||
"./skills/engineering/domain-modeling",
|
"./skills/engineering/domain-modeling",
|
||||||
"./skills/engineering/codebase-design",
|
"./skills/engineering/codebase-design",
|
||||||
"./skills/engineering/code-review",
|
"./skills/engineering/code-review",
|
||||||
|
"./skills/engineering/resolving-merge-conflicts",
|
||||||
|
"./skills/engineering/wizard",
|
||||||
"./skills/productivity/grill-me",
|
"./skills/productivity/grill-me",
|
||||||
"./skills/productivity/grilling",
|
"./skills/productivity/grilling",
|
||||||
"./skills/productivity/handoff",
|
"./skills/productivity/handoff",
|
||||||
"./skills/productivity/teach",
|
"./skills/productivity/teach",
|
||||||
"./skills/productivity/writing-great-skills"
|
"./skills/productivity/to-questionnaire",
|
||||||
|
"./skills/productivity/wait-what",
|
||||||
|
"./skills/productivity/writing-for-agents"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
## Why this is out of scope
|
## Why this is out of scope
|
||||||
|
|
||||||
Every issue-tracker backend hard-codes a CLI shape into the skills (commands, flags, output parsing). Each new backend is permanent maintenance surface — it has to keep working as the tool's CLI evolves, and it has to keep being tested against `/to-prd`, `/to-issues`, `/triage`, and friends. That cost is only worth paying for trackers a meaningful fraction of users actually have.
|
Every issue-tracker backend hard-codes a CLI shape into the skills (commands, flags, output parsing). Each new backend is permanent maintenance surface — it has to keep working as the tool's CLI evolves, and it has to keep being tested against `/to-spec`, `/to-tickets`, `/triage`, and friends. That cost is only worth paying for trackers a meaningful fraction of users actually have.
|
||||||
|
|
||||||
"Mainstream" is a judgment call, not a numeric bar:
|
"Mainstream" is a judgment call, not a numeric bar:
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,67 @@
|
|||||||
# mattpocock-skills
|
# mattpocock-skills
|
||||||
|
|
||||||
|
## 1.1.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- [#406](https://github.com/mattpocock/skills/pull/406) [`930a450`](https://github.com/mattpocock/skills/commit/930a450089f77a49af09001d955db8452a4b867d) Thanks [@mattpocock](https://github.com/mattpocock)! - 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.
|
||||||
|
|
||||||
|
- [#464](https://github.com/mattpocock/skills/pull/464) [`639df6e`](https://github.com/mattpocock/skills/commit/639df6e7386dfddc739b2aecdeff37a876f2483b) Thanks [@mattpocock](https://github.com/mattpocock)! - Promote and harden **`code-review`**. The in-progress **`review`** skill is renamed to **`code-review`** and moved from `in-progress/` into `engineering/`: it now ships in the plugin, is listed in the top-level and Engineering READMEs (Model-invoked), and has a docs page at `docs/engineering/code-review.md`. The `/implement` skill and docs point at `/code-review`.
|
||||||
|
|
||||||
|
It also gains an always-on **Fowler smell baseline** on its Standards axis — a curated ~12 high-signal "Bad Smells in Code" (Mysterious Name, Duplicated Code, Feature Envy, Data Clumps, Primitive Obsession, Repeated Switches, Shotgun Surgery, Divergent Change, Speculative Generality, Message Chains, Middle Man, Refused Bequest) inlined into `SKILL.md` as a fixed baseline alongside whatever the repo documents, not a new third axis. Two binding rules keep it safe: a documented repo standard overrides the baseline, and every smell is reported as a judgement call, never a hard violation.
|
||||||
|
|
||||||
|
- [#464](https://github.com/mattpocock/skills/pull/464) [`639df6e`](https://github.com/mattpocock/skills/commit/639df6e7386dfddc739b2aecdeff37a876f2483b) Thanks [@mattpocock](https://github.com/mattpocock)! - Sharpen **`grilling`** on two fronts.
|
||||||
|
|
||||||
|
**A confirmation gate.** The agent won't enact the plan until you confirm the shared understanding has been reached — turning the skill's existing "shared understanding" completion criterion into an explicit stop-gate. The `description` also recruits the pretrained **`grill`** leading word ("Grill the user relentlessly") to sharpen invocation, and the docs page is re-synced.
|
||||||
|
|
||||||
|
**Facts vs. decisions.** Grilling now splits _facts_ (look them up — explore the codebase) from _decisions_ (put each one to the human and wait for their answer). The old blanket line — "if a question can be answered by exploring the codebase, explore the codebase instead" — was written for the live-human case, but once another skill runs grilling inside a resolve-the-ticket frame it read as license to answer _decisions_ autonomously too. Separating the two keeps a grilling agent from racing ahead and answering its own questions.
|
||||||
|
|
||||||
|
- [#463](https://github.com/mattpocock/skills/pull/463) [`af6d692`](https://github.com/mattpocock/skills/commit/af6d6922c3e2b5288eef155346cbe319e4ed3bd0) Thanks [@mattpocock](https://github.com/mattpocock)! - Add two adjacent Steering failure modes to **`writing-great-skills`**, both about how language you think of as "off" still steers the agent. **Negation** — the _elephant_ — is steering by prohibition: naming what _not_ to do drags the forbidden behaviour into context and makes it _more_ available, not less (_don't think of an elephant_), so the cure is to prompt the **positive**. **Negative Space** — the void — is blindness to the steering done by what you leave _out_: every decision a skill declines is delegated to the agent's priors rather than left neutral, so the cure is to read a draft for its silences and decide each omission deliberately (fill it, or leave it open as a real **branch**). Kept as two entries, not one — they carry different diagnostics and different cures — each a full `GLOSSARY.md` entry plus a `SKILL.md` failure-mode bullet, matching how every other failure mode is carried.
|
||||||
|
|
||||||
|
- [`850873c`](https://github.com/mattpocock/skills/commit/850873cd73d5f81826ebf512ad35d2b1e113001f) Thanks [@mattpocock](https://github.com/mattpocock)! - Make the **`prototype`** skill model-invoked, so the agent can reach for it autonomously (and other skills can too). Its description is rewritten around the leading word _prototype_ — throwaway code that answers a design question — with one trigger per branch (state/logic sanity-check, or UI exploration).
|
||||||
|
|
||||||
|
- [#409](https://github.com/mattpocock/skills/pull/409) [`0d74d01`](https://github.com/mattpocock/skills/commit/0d74d01cbc64ca27778a49b38599f70c534e76a0) Thanks [@mattpocock](https://github.com/mattpocock)! - Add the **`research`** skill — a small, model-invoked skill that spins up a **background agent** to investigate a question against **primary sources** (official docs, source code, specs, first-party APIs), then leaves a single cited Markdown file wherever the repo keeps such notes. It's delegable reading legwork: you keep working while it reads, and get back a document to grill, plan, or design against. Listed in the top-level and Engineering READMEs (Model-invoked), added to `.claude-plugin/plugin.json`, given a docs page at `docs/engineering/research.md`, and routed as a Standalone in `ask-matt`.
|
||||||
|
|
||||||
|
- [#469](https://github.com/mattpocock/skills/pull/469) [`a0329ba`](https://github.com/mattpocock/skills/commit/a0329ba95751f58566ed7ab484475917a68f1629) Thanks [@mattpocock](https://github.com/mattpocock)! - Split the **`to-issues`** skill into a lean **Process** and a **Reference** section, and teach it to handle a **wide refactor** — a single mechanical change (like renaming a column) whose **blast radius** fans across the whole codebase, breaking thousands of call sites at once so no vertical slice can land green. The drafting step now points at two co-located reference blocks: the **Vertical slice rules** for ordinary tracer bullets, and **Wide refactors**, which slices the change by **expand–contract** (expand the new form beside the old, migrate call sites in batches sized by blast radius, then contract the old form away) so CI stays green batch to batch — or, when it can't, only at a final integrate-and-verify issue. The issue body template moves into Reference too.
|
||||||
|
|
||||||
|
- [#464](https://github.com/mattpocock/skills/pull/464) [`386d4ff`](https://github.com/mattpocock/skills/commit/386d4ff719a7c420ad1454232d0436b01f1b8c17) Thanks [@mattpocock](https://github.com/mattpocock)! - Unify the planning skills. **`to-prd` is renamed to `to-spec`** — "spec" is now the single through-line term (it still opens with "you may know this document as a PRD" for discoverability). **`to-plan` and `to-issues` are merged into one `to-tickets` skill, and `to-issues` is deleted.**
|
||||||
|
|
||||||
|
`to-tickets` breaks a plan, spec, or conversation into a set of **tickets** — tracer-bullet vertical slices, each declaring its **blocking edges**. That one artifact reads two ways depending on the tracker `/setup-matt-pocock-skills` configured: a **local file** (`tickets.md`) writes the edges as text and you work it top-to-bottom by hand; a **real tracker** writes them as native blocking links, so any ticket whose blockers are done is on the frontier and several agents can run at once. The edges live in the ticket either way — the medium only decides whether anything acts on them in parallel.
|
||||||
|
|
||||||
|
Publishing prefers the tracker's **native sub-issues** for parent → slice and **native blocking edges** for `Blocked by` where the tracker supports them, keeping the `## Parent` / `## Blocked by` body sections as the fallback. The "What to build" template points at where a `/prototype`'s code lives rather than inlining a snippet from it.
|
||||||
|
|
||||||
|
`ask-matt`'s main flow now routes `idea → /to-spec → /to-tickets → /implement`, and there are human-facing docs pages at `docs/engineering/to-spec.md` and `docs/engineering/to-tickets.md`.
|
||||||
|
|
||||||
|
- [#464](https://github.com/mattpocock/skills/pull/464) [`0557d57`](https://github.com/mattpocock/skills/commit/0557d57579d9b3d39839fdaf8d4a6542b17539ce) Thanks [@mattpocock](https://github.com/mattpocock)! - Settle wayfinder's place in the docs as a **situational on-ramp**, not the new main entry flow — the grill-led _idea → ship_ chain stays the front door (crowning wayfinder as the default spine is a v2-sized move, not a 1.1). The **`ask-matt`** router now names wayfinder's concrete triggers — a greenfield project or a huge feature build, too big for one session — and the two grill front doors (**`grill-me`**, **`grill-with-docs`**) signpost _up_ to wayfinder for the effort that's too big to hold in one session, so the on-ramp is discoverable from where a reader actually starts.
|
||||||
|
|
||||||
|
- [#464](https://github.com/mattpocock/skills/pull/464) [`639df6e`](https://github.com/mattpocock/skills/commit/639df6e7386dfddc739b2aecdeff37a876f2483b) Thanks [@mattpocock](https://github.com/mattpocock)! - Graduate and reframe **`wayfinder`** — the skill for planning a huge chunk of work, more than one agent session can hold. It moves out of `in-progress/` into `engineering/` (plugin entry, top-level + Engineering READMEs under **User-invoked**, a docs page at `docs/engineering/wayfinder.md`, and a route in `ask-matt`), landing as a mature skill. The rename and reframe that got it there:
|
||||||
|
|
||||||
|
- **`decision-mapping` is renamed to `wayfinder`**, invoked as `/wayfinder`. "Decision map" was jargony and inaccurate — only one ticket type is actually a decision. The reframe charts a route through a foggy problem instead, giving one coherent leading-word frame — **fog of war**, **frontier**, **the map** — rather than an invented term layered on top.
|
||||||
|
- **Destination as the leading word.** Wayfinding finds the _way_ to a destination; it doesn't charge at building it. Naming the destination is the first act of charting — it fixes the scope and shapes every ticket — so the map gains a `## Destination` field every session orients to, and triage pins it before any ticket exists.
|
||||||
|
- **Plan, don't do.** The map produces **decisions, not deliverables**; it's done when nothing is left to decide before someone builds the thing. An effort can override this in its Notes.
|
||||||
|
- **The map is an index, not a store.** A decision lives in exactly one place — its ticket — so the map only gists and links, never restates; graduating fog into a ticket clears the graduated patch so nothing lingers in two places.
|
||||||
|
- **Collaborative by default.** The map moves off a local Markdown file onto the repo's issue tracker: a single `wayfinder:map` issue whose tickets are its child issues — one shared URL the team can watch. Sessions load the map at low resolution and zoom into tickets on demand. Wayfinder stays tracker-agnostic (GitHub, GitLab, local-markdown) behind a pointer in `docs/agents/issue-tracker.md`, and `setup-matt-pocock-skills` seeds the "Wayfinding operations" section.
|
||||||
|
- **Claim by assignment, not a label.** A session claims a ticket by assigning it to the driving dev — the assignee _is_ the claim — freeing the label vocabulary to `wayfinder:<type>` alone.
|
||||||
|
- **Native blocking.** Blocking prefers the tracker's native dependency relationship, which renders the frontier visually in the tracker's own UI so the human sees what's takeable without opening the map. GitHub and GitLab templates spell out the native recipe, with a body-convention fallback.
|
||||||
|
- **Fog vs. out of scope, split.** Two plainly-named map sections — `## Not yet specified` (in-scope fog that graduates as the frontier advances) and `## Out of scope` (work ruled beyond the destination, closed, never graduating) — so beyond-destination work no longer reads as takeable frontier.
|
||||||
|
- **A fourth `task` ticket type.** For literal manual work that blocks a decision (provisioning access, moving data, signing up for a service) — the one type that _does_ rather than decides, earning its place by unblocking a decision.
|
||||||
|
- **HITL / AFK ticket classification.** Every ticket type is **HITL** (human in the loop — grilling, prototype) or **AFK** (agent alone — research; task is either). A HITL ticket only resolves through the live exchange, so "wait for the human" falls out of the label — a grilling agent that answers its own questions has, by definition, broken HITL. (This fixes students' reports of `/wayfinder` grilling _itself_ instead of the human.)
|
||||||
|
- **No-fog early exit restored.** If the opening breadth-first grilling surfaces no fog, the journey is small enough for one session — so it stops and asks how you'd like to proceed rather than building a map nobody needs.
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- [#464](https://github.com/mattpocock/skills/pull/464) [`639df6e`](https://github.com/mattpocock/skills/commit/639df6e7386dfddc739b2aecdeff37a876f2483b) Thanks [@mattpocock](https://github.com/mattpocock)! - Reshape **`tdd`** into a reference-only skill and add a missing anti-pattern.
|
||||||
|
|
||||||
|
**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. 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: 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; refactoring belongs to the review stage, so the refactor rule and `refactoring.md` moved out (its home is `code-review`).
|
||||||
|
|
||||||
|
**Tautological tests.** Added the tautological-test anti-pattern: a test whose assertion is recomputed the way the code computes it passes by construction and gives zero confidence — distinct from the implementation-coupling anti-pattern already covered. Added as a peer at the same sites: a Philosophy principle (expected values must come from an independent source of truth), a checklist gate, and a BAD/GOOD example pair in `tests.md`.
|
||||||
|
|
||||||
|
- [`e00eadb`](https://github.com/mattpocock/skills/commit/e00eadb4bb32c3d5a631ead1a5ed5d6a7c5f74e2) Thanks [@mattpocock](https://github.com/mattpocock)! - Extend the **`triage`** skill to triage external pull requests, treating a PR as an issue with attached code that runs through the same roles and state machine. PRs flow inline alongside issues (gated by a per-repo setup toggle), discovery surfaces only external PRs, the bug-only "reproduce" step is generalized into a single "verify the claim" step, and a redundancy check resolves already-implemented requests to `wontfix` without polluting the out-of-scope knowledge base. `setup-matt-pocock-skills` gains the PRs-as-a-request-surface toggle for GitHub/GitLab.
|
||||||
|
|
||||||
|
- [#472](https://github.com/mattpocock/skills/pull/472) [`d869d45`](https://github.com/mattpocock/skills/commit/d869d45afc32beab1c2d1350f8de5e81589512cd) Thanks [@mattpocock](https://github.com/mattpocock)! - Fix **`wayfinder`** hardcoding the issue-tracker doc path, which broke the indirection the rest of the suite relies on.
|
||||||
|
|
||||||
|
`to-issues`, `to-prd`, and `triage` never name a path — they resolve the tracker through the `### Issue tracker` block that `setup-matt-pocock-skills` writes into `CLAUDE.md` / `AGENTS.md`, which points at the tracker doc wherever it lives. Wayfinder instead pinned the literal `docs/agents/issue-tracker.md`, so in a repo that keeps its agent docs elsewhere it silently fell back to the local-markdown tracker — even one whose `CLAUDE.md` clearly declares GitHub issues. It now resolves the doc via that same pointer and reads its "Wayfinding operations" section by name, keeping the indirection consistent across the suite.
|
||||||
|
|
||||||
## 1.0.1
|
## 1.0.1
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|||||||
@@ -3,19 +3,20 @@ Skills are organized into bucket folders under `skills/`:
|
|||||||
- `engineering/` — daily code work
|
- `engineering/` — daily code work
|
||||||
- `productivity/` — daily non-code workflow tools
|
- `productivity/` — daily non-code workflow tools
|
||||||
- `misc/` — kept around but rarely used, not promoted
|
- `misc/` — kept around but rarely used, not promoted
|
||||||
- `personal/` — tied to my own setup, not promoted
|
- `in-progress/` — beta: public on purpose, feedback wanted, not shipped in the plugin
|
||||||
- `in-progress/` — drafts not yet ready to ship
|
|
||||||
- `deprecated/` — no longer used
|
- `deprecated/` — no longer used
|
||||||
|
|
||||||
Every skill in `engineering/` or `productivity/` (the **promoted** buckets) must have a reference in the top-level `README.md` and an entry in `.claude-plugin/plugin.json`. Skills in `misc/`, `personal/`, `in-progress/`, and `deprecated/` must not appear in either.
|
Every skill in `engineering/` or `productivity/` (the **promoted** buckets) must have a reference in the top-level `README.md` and an entry in `.claude-plugin/plugin.json`'s `skills` array (the Claude Code plugin ships exactly the promoted set). Skills in `misc/`, `in-progress/`, and `deprecated/` must not appear in either.
|
||||||
|
|
||||||
|
Install commands are copied verbatim from [.agents/install-block.md](./.agents/install-block.md). `.claude-plugin/marketplace.json` makes the repo its own single-plugin marketplace — a fallback the install block explains, not the documented route. When bumping the release version, keep `.claude-plugin/plugin.json`'s `version` in sync with `package.json`'s — Claude uses the plugin `version` to decide when installed users see an update. Run `claude plugin validate . --strict` after touching either manifest. Why a Claude plugin but not (yet) a Codex one lives in [.agents/adr/0002-ship-as-a-claude-code-plugin.md](./.agents/adr/0002-ship-as-a-claude-code-plugin.md).
|
||||||
|
|
||||||
Each skill entry in the top-level `README.md` must link the skill name to its `SKILL.md`.
|
Each skill entry in the top-level `README.md` must link the skill name to its `SKILL.md`.
|
||||||
|
|
||||||
Each bucket folder has a `README.md` that lists every skill in the bucket with a one-line description, with the skill name linked to its `SKILL.md`. The promoted buckets' `README.md`s and the top-level `README.md` group entries into **User-invoked** and **Model-invoked**; non-promoted bucket `README.md`s (`misc/`, `personal/`) use a flat list.
|
Each bucket folder has a `README.md` that lists every skill in the bucket with a one-line description, with the skill name linked to its `SKILL.md`. The promoted buckets' `README.md`s and the top-level `README.md` group entries into **User-invoked** and **Model-invoked**; non-promoted bucket `README.md`s (`misc/`, `in-progress/`) use a flat list.
|
||||||
|
|
||||||
Skills in `engineering/` and `productivity/` also have a human-facing docs page at `docs/<bucket>/<skill-name>.md` (the docs tree mirrors those two bucket folders under `skills/`). The published URL is `https://aihero.dev/skills-<skill-name>` regardless of bucket — the docs path is repo organisation only. When you add, rename, or change the behaviour of a skill in `engineering/` or `productivity/`, create or re-sync its docs page following [.agents/writing-docs.md](./.agents/writing-docs.md). Skills in the non-promoted buckets (`misc/`, `personal/`, `in-progress/`, `deprecated/`) get **no** docs page.
|
Skills in `engineering/` and `productivity/` also have a human-facing docs page at `docs/<bucket>/<skill-name>.md` (the docs tree mirrors those two bucket folders under `skills/`). The published URL is `https://aihero.dev/skills-<skill-name>` regardless of bucket — the docs path is repo organisation only. When you add, rename, or change the behaviour of a skill in `engineering/` or `productivity/`, create or re-sync its docs page following [.agents/writing-docs.md](./.agents/writing-docs.md). Skills in the non-promoted buckets (`misc/`, `in-progress/`, `deprecated/`) get **no** 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` plus `policy.allow_implicit_invocation: false` in `agents/openai.yaml`, 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.
|
[`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.
|
||||||
|
|
||||||
|
|||||||
+7
-3
@@ -5,12 +5,15 @@ A collection of agent skills (slash commands and behaviors) loaded by Claude Cod
|
|||||||
## Language
|
## Language
|
||||||
|
|
||||||
**Issue tracker**:
|
**Issue tracker**:
|
||||||
The tool that hosts a repo's issues — GitHub Issues, Linear, a local `.scratch/` markdown convention, or similar. Skills like `to-issues`, `to-prd`, `triage`, and `qa` read from and write to it.
|
The tool that hosts a repo's issues — GitHub Issues, Linear, a local `.scratch/` markdown convention, or similar. Skills like `to-tickets`, `to-spec`, and `triage` read from and write to it.
|
||||||
_Avoid_: backlog manager, backlog backend, issue host
|
_Avoid_: backlog manager, backlog backend, issue host
|
||||||
|
|
||||||
**Issue**:
|
**Issue**:
|
||||||
A single tracked unit of work inside an **Issue tracker** — a bug, task, PRD, or slice produced by `to-issues`.
|
A single tracked unit of work inside an **Issue tracker** — a bug, task, spec, or slice produced by `to-tickets`.
|
||||||
_Avoid_: ticket (use only when quoting external systems that call them tickets)
|
_Avoid_: ticket (use only when quoting external systems that call them tickets, or for a **Decision ticket** — see below)
|
||||||
|
|
||||||
|
**Decision ticket**:
|
||||||
|
A `wayfinder` unit — a child **Issue** of a `wayfinder:map` holding a *question* whose resolution is a decision, not a slice of a build to execute. The **decision** qualifier is what keeps it distinct from an implementation ticket; `wayfinder` introduces the term, then uses "ticket".
|
||||||
|
|
||||||
**Triage role**:
|
**Triage role**:
|
||||||
A canonical state-machine label applied to an **Issue** during triage (e.g. `needs-triage`, `ready-for-afk`). Each role maps to a real label string in the **Issue tracker** via `docs/agents/triage-labels.md`.
|
A canonical state-machine label applied to an **Issue** during triage (e.g. `needs-triage`, `ready-for-afk`). Each role maps to a real label string in the **Issue tracker** via `docs/agents/triage-labels.md`.
|
||||||
@@ -19,6 +22,7 @@ A canonical state-machine label applied to an **Issue** during triage (e.g. `nee
|
|||||||
|
|
||||||
- An **Issue tracker** holds many **Issues**
|
- An **Issue tracker** holds many **Issues**
|
||||||
- An **Issue** carries one **Triage role** at a time
|
- An **Issue** carries one **Triage role** at a time
|
||||||
|
- A **Decision ticket** is an **Issue** (a child of a `wayfinder:map`)
|
||||||
|
|
||||||
## Flagged ambiguities
|
## Flagged ambiguities
|
||||||
|
|
||||||
|
|||||||
@@ -22,22 +22,64 @@ If you want to keep up with changes to these skills, and any new ones I create,
|
|||||||
|
|
||||||
[Sign Up To The Newsletter](https://www.aihero.dev/s/skills-newsletter)
|
[Sign Up To The Newsletter](https://www.aihero.dev/s/skills-newsletter)
|
||||||
|
|
||||||
## Quickstart (30-second setup)
|
## Installation (30-second setup)
|
||||||
|
|
||||||
1. Run the skills.sh installer:
|
Two ways in, two philosophies. **The [Claude Code plugin](https://code.claude.com/docs/en/plugins)** installs the whole set as a managed, read-only bundle that updates when I ship — you subscribe rather than fork. **[skills.sh](https://skills.sh/mattpocock/skills)** copies editable skill files into your project, so you can hack on them and make them your own. Pick one — installing both leaves you with every skill twice.
|
||||||
|
|
||||||
|
### 1. Get the skills
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><strong>Claude Code</strong></summary>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
claude plugins install mattpocock-skills
|
||||||
|
```
|
||||||
|
|
||||||
|
Or, from inside a session:
|
||||||
|
|
||||||
|
```
|
||||||
|
/plugin install mattpocock-skills
|
||||||
|
```
|
||||||
|
|
||||||
|
It's in Claude Code's official marketplace, so there's nothing to add first, and updates arrive automatically.
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><strong>Codex, and other agents</strong></summary>
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npx skills@latest add mattpocock/skills
|
npx skills@latest add mattpocock/skills
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Pick the skills you want, and which coding agents you want to install them on. **Make sure you select `/setup-matt-pocock-skills`**.
|
Pick the skills you want, and which coding agents to install them on. **The installer lets you choose which skills to take — make sure `setup-matt-pocock-skills` is one of them.**
|
||||||
|
|
||||||
3. Run `/setup-matt-pocock-skills` in your agent. It will:
|
A native Codex plugin is on the roadmap — see [`.agents/adr/0002-ship-as-a-claude-code-plugin.md`](./.agents/adr/0002-ship-as-a-claude-code-plugin.md).
|
||||||
- Ask you which issue tracker you want to use (GitHub, Linear, or local files)
|
|
||||||
- Ask you what labels you apply to tickets when you triage them (`/triage` uses labels)
|
|
||||||
- Ask you where you want to save any docs we create
|
|
||||||
|
|
||||||
4. Bam - you're ready to go.
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><strong>For tinkerers</strong></summary>
|
||||||
|
|
||||||
|
Use the same installer, on any agent — including Claude Code:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx skills@latest add mattpocock/skills
|
||||||
|
```
|
||||||
|
|
||||||
|
It writes the skills into your repo as ordinary files you own and can edit. Nothing updates behind your back; pull my latest changes when you want them with `npx skills update`.
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
### 2. Run `/setup-matt-pocock-skills`
|
||||||
|
|
||||||
|
In your agent, run it once per repo. It will:
|
||||||
|
|
||||||
|
- Ask you which issue tracker you want to use (GitHub, Linear, or local files)
|
||||||
|
- Ask you what labels you apply to tickets when you triage them (`/triage` uses labels)
|
||||||
|
- Ask you where you want to save any docs we create
|
||||||
|
|
||||||
|
### 3. Bam - you're ready to go.
|
||||||
|
|
||||||
## Why These Skills Exist
|
## Why These Skills Exist
|
||||||
|
|
||||||
@@ -131,7 +173,7 @@ For debugging, I've also built a **[`/diagnosing-bugs`](./skills/engineering/dia
|
|||||||
|
|
||||||
This is built in to every layer of these skills:
|
This is built in to every layer of these skills:
|
||||||
|
|
||||||
- [`/to-prd`](./skills/engineering/to-prd/SKILL.md) quizzes you about which modules you're touching before creating a PRD
|
- [`/to-spec`](./skills/engineering/to-spec/SKILL.md) quizzes you about which modules you're touching before creating a spec
|
||||||
|
|
||||||
And crucially, [`/improve-codebase-architecture`](./skills/engineering/improve-codebase-architecture/SKILL.md) helps you rescue a codebase that has become a ball of mud. I recommend running it on your codebase once every few days.
|
And crucially, [`/improve-codebase-architecture`](./skills/engineering/improve-codebase-architecture/SKILL.md) helps you rescue a codebase that has become a ball of mud. I recommend running it on your codebase once every few days.
|
||||||
|
|
||||||
@@ -154,17 +196,22 @@ Skills I use daily for code work.
|
|||||||
- **[triage](./skills/engineering/triage/SKILL.md)** — Move issues through a state machine of triage roles.
|
- **[triage](./skills/engineering/triage/SKILL.md)** — Move issues through a state machine of triage roles.
|
||||||
- **[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-spec](./skills/engineering/to-spec/SKILL.md)** — Turn the current conversation into a spec 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.
|
- **[to-tickets](./skills/engineering/to-tickets/SKILL.md)** — Break any plan, spec, or conversation into a set of tracer-bullet tickets, each declaring its blocking edges — written as text in a local file, or as native blocking links on a real tracker.
|
||||||
|
- **[implement](./skills/engineering/implement/SKILL.md)** — Build the work described by a spec or set of tickets, driving `/tdd` at pre-agreed seams and closing out with `/code-review` before committing.
|
||||||
|
- **[wayfinder](./skills/engineering/wayfinder/SKILL.md)** — Plan a huge chunk of work, more than one agent session can hold, as a shared map of investigation tickets on the issue tracker — resolve them one at a time until the way to the destination is clear.
|
||||||
|
- **[wizard](./skills/engineering/wizard/SKILL.md)** — Generate an interactive bash wizard that walks a human through a manual procedure — third-party setup, a one-off migration, an A→B state transition — opening each URL, capturing values, confirming every step, and writing `.env` files and GitHub Actions secrets.
|
||||||
|
|
||||||
**Model-invoked**
|
**Model-invoked**
|
||||||
|
|
||||||
- **[prototype](./skills/engineering/prototype/SKILL.md)** — Build a throwaway prototype to answer a design question — a runnable terminal app for state/logic questions, or several radically different UI variations toggleable from one route.
|
- **[prototype](./skills/engineering/prototype/SKILL.md)** — Build a throwaway prototype to answer a design question — a runnable terminal app for state/logic questions, or several radically different UI variations toggleable from one route.
|
||||||
- **[diagnosing-bugs](./skills/engineering/diagnosing-bugs/SKILL.md)** — Disciplined diagnosis loop for hard bugs and performance regressions: reproduce → minimise → hypothesise → instrument → fix → regression-test.
|
- **[diagnosing-bugs](./skills/engineering/diagnosing-bugs/SKILL.md)** — Disciplined diagnosis loop for hard bugs and performance regressions: reproduce → minimise → hypothesise → instrument → fix → regression-test.
|
||||||
|
- **[research](./skills/engineering/research/SKILL.md)** — Investigate a question against high-trust primary sources and capture the findings as a cited Markdown file in the repo, run as a background agent.
|
||||||
- **[tdd](./skills/engineering/tdd/SKILL.md)** — Test-driven development with a red-green-refactor loop. Builds features or fixes bugs one vertical slice at a time.
|
- **[tdd](./skills/engineering/tdd/SKILL.md)** — Test-driven development with a red-green-refactor loop. Builds features or fixes bugs one vertical slice at a time.
|
||||||
- **[domain-modeling](./skills/engineering/domain-modeling/SKILL.md)** — Actively build and sharpen a project's domain model — challenge terms against the glossary, stress-test with edge-case scenarios, and update `CONTEXT.md` and ADRs inline.
|
- **[domain-modeling](./skills/engineering/domain-modeling/SKILL.md)** — Actively build and sharpen a project's domain model — challenge terms against the glossary, stress-test with edge-case scenarios, and update `CONTEXT.md` and ADRs inline.
|
||||||
- **[codebase-design](./skills/engineering/codebase-design/SKILL.md)** — Shared discipline and vocabulary for designing deep modules: a lot of behaviour behind a small interface, placed at a clean seam, testable through that interface.
|
- **[codebase-design](./skills/engineering/codebase-design/SKILL.md)** — Shared discipline and vocabulary for designing deep modules: a lot of behaviour behind a small interface, placed at a clean seam, testable through that interface.
|
||||||
- **[code-review](./skills/engineering/code-review/SKILL.md)** — Two-axis review of the diff since a fixed point: **Standards** (does it follow the repo's coding standards, plus a Fowler smell baseline?) and **Spec** (does it faithfully implement the originating issue/PRD?), run as parallel sub-agents so neither pollutes the other.
|
- **[code-review](./skills/engineering/code-review/SKILL.md)** — Two-axis review of the diff since a fixed point: **Standards** (does it follow the repo's coding standards, plus a Fowler smell baseline?) and **Spec** (does it faithfully implement the originating issue/spec?), run as parallel sub-agents so neither pollutes the other.
|
||||||
|
- **[resolving-merge-conflicts](./skills/engineering/resolving-merge-conflicts/SKILL.md)** — Work through an in-progress git merge or rebase conflict hunk by hunk, resolving by intent traced to each side's primary source, then finish the operation — never `--abort`.
|
||||||
|
|
||||||
### Productivity
|
### Productivity
|
||||||
|
|
||||||
@@ -175,8 +222,10 @@ General workflow tools, not code-specific.
|
|||||||
- **[grill-me](./skills/productivity/grill-me/SKILL.md)** — Get relentlessly interviewed about a plan or design until every branch of the decision tree is resolved.
|
- **[grill-me](./skills/productivity/grill-me/SKILL.md)** — Get relentlessly interviewed about a plan or design until every branch of the decision tree is resolved.
|
||||||
- **[handoff](./skills/productivity/handoff/SKILL.md)** — Compact the current conversation into a handoff document so another agent can continue the work.
|
- **[handoff](./skills/productivity/handoff/SKILL.md)** — Compact the current conversation into a handoff document so another agent can continue the work.
|
||||||
- **[teach](./skills/productivity/teach/SKILL.md)** — Teach the user a new skill or concept over multiple sessions, using the current directory as a stateful teaching workspace.
|
- **[teach](./skills/productivity/teach/SKILL.md)** — Teach the user a new skill or concept over multiple sessions, using the current directory as a stateful teaching workspace.
|
||||||
- **[writing-great-skills](./skills/productivity/writing-great-skills/SKILL.md)** — Reference for writing and editing skills well: the vocabulary and principles that make a skill predictable.
|
- **[to-questionnaire](./skills/productivity/to-questionnaire/SKILL.md)** — Turn a decision you can't answer alone into a Markdown questionnaire for the one person who can — filled in async, or together over a meeting. It grills you about the send (who it's for, what you need back), not the subject.
|
||||||
|
- **[wait-what](./skills/productivity/wait-what/SKILL.md)** — Fire this the moment a message doesn't land. The agent re-pitches it with the context you're missing, in plain English, using your `CONTEXT.md` vocabulary.
|
||||||
|
- **[writing-for-agents](./skills/productivity/writing-for-agents/SKILL.md)** — Writing documents for agents: skills, AGENTS.md/CLAUDE.md, and any doc an agent reaches by a pointer.
|
||||||
|
|
||||||
**Model-invoked**
|
**Model-invoked**
|
||||||
|
|
||||||
- **[grilling](./skills/productivity/grilling/SKILL.md)** — Interview the user relentlessly about a plan or design until every branch of the decision tree is resolved. The reusable loop behind `grill-me` and `grill-with-docs`.
|
- **[grilling](./skills/productivity/grilling/SKILL.md)** — Interview the user relentlessly about a plan, decision, or idea until every branch of the decision tree is resolved. The reusable loop behind `grill-me` and `grill-with-docs`.
|
||||||
|
|||||||
@@ -1,20 +1,8 @@
|
|||||||
Quickstart:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx skills add mattpocock/skills --skill=ask-matt
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx skills update ask-matt
|
|
||||||
```
|
|
||||||
|
|
||||||
[Source](https://github.com/mattpocock/skills/tree/main/skills/engineering/ask-matt)
|
|
||||||
|
|
||||||
## What it does
|
## What it does
|
||||||
|
|
||||||
`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.
|
`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. 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.
|
It **does no work itself**. It doesn't grill, write a spec, 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
|
||||||
|
|
||||||
@@ -24,8 +12,12 @@ Reach for it whenever you're unsure which skill or flow a situation calls for: y
|
|||||||
|
|
||||||
## Flows, not just skills
|
## Flows, not just skills
|
||||||
|
|
||||||
The idea `ask-matt` gives you to think with is the **flow** — a path *through* the skills rather than a single one. Most work runs along one **main flow** (idea → ship: grill → PRD → issues → implement → review), two **on-ramps** merge onto it (a triage lane for incoming bugs and requests; a codebase-health lane that generates ideas), and everything else is a **standalone** you reach for on its own. Ask a question and you get placed on the right flow, at the right step — not just handed a tool.
|
The idea `ask-matt` gives you to think with is the **flow** — a path *through* the skills rather than a single one. Most work runs along one **main flow** (idea → ship: grill → spec → tickets → implement → review), two **on-ramps** merge onto it (a triage lane for incoming bugs and requests; a codebase-health lane that generates ideas), and everything else is a **standalone** you reach for on its own. Ask a question and you get placed on the right flow, at the right step — not just handed a tool.
|
||||||
|
|
||||||
|
## Phase boundaries
|
||||||
|
|
||||||
|
The other idea it hands you is the **phase boundary**. A **phase** is a chunk of work inside a session — the grilling, the implementation, the QA — and the boundary between two of them is where you decide what to do with the context you've built up. You have five options: **continue**, **`/clear`**, **`/handoff`**, a **subagent**, or **`/compact`**. `ask-matt` carries the decision tree that orders them, and the two corrections most people need: `/handoff` is narrow — it earns its keep only when something has to *travel* (a new harness, a new directory, a colleague, a side task forked mid-phase) — and `/compact` is the tree's default at the bottom, not its first reach. Reach for the tree at a boundary; mid-phase there's nothing to decide.
|
||||||
|
|
||||||
## Where it fits
|
## Where it fits
|
||||||
|
|
||||||
`ask-matt` is the **router** — the standalone map that sits over the whole set. It is the node every other docs page links back to as [ask-matt](https://aihero.dev/skills-ask-matt), so it never sits *in* a chain; it points *into* every chain. From here you'll most often land on [grill-with-docs](https://aihero.dev/skills-grill-with-docs), the head of the main flow, or [triage](https://aihero.dev/skills-triage), the on-ramp for work you didn't create. When even the router's own picture is stale, its [Source](https://github.com/mattpocock/skills/tree/main/skills/engineering/ask-matt) is the map of record.
|
`ask-matt` is the **router** — the standalone map that sits over the whole set. It is the node every other docs page links back to as [ask-matt](https://aihero.dev/skills-ask-matt), so it never sits *in* a chain; it points *into* every chain. From here you'll most often land on [grill-with-docs](https://aihero.dev/skills-grill-with-docs), the head of the main flow, or [triage](https://aihero.dev/skills-triage), the on-ramp for work you didn't create. When even the router's own picture is stale, the skill itself is the map of record.
|
||||||
|
|||||||
@@ -1,18 +1,6 @@
|
|||||||
Quickstart:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx skills add mattpocock/skills --skill=code-review
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx skills update code-review
|
|
||||||
```
|
|
||||||
|
|
||||||
[Source](https://github.com/mattpocock/skills/tree/main/skills/engineering/code-review)
|
|
||||||
|
|
||||||
## What it does
|
## What it does
|
||||||
|
|
||||||
`code-review` reviews the diff between `HEAD` and a fixed point you supply — a commit, branch, tag, or merge-base — along two separate axes: **Standards** (does the code follow this repo's documented conventions?) and **Spec** (does it implement what the originating issue or PRD asked for?). It runs each axis as its own parallel sub-agent and reports them side by side. It never merges or re-ranks the two sets of findings — keeping them separate is the whole point, because a change can pass one axis and fail the other, and a single blended verdict lets one mask the other.
|
`code-review` reviews the diff between `HEAD` and a fixed point you supply — a commit, branch, tag, or merge-base — along two separate axes: **Standards** (does the code follow this repo's documented conventions?) and **Spec** (does it implement what the originating issue or spec asked for?). It runs each axis as its own parallel sub-agent and reports them side by side. It never merges or re-ranks the two sets of findings — keeping them separate is the whole point, because a change can pass one axis and fail the other, and a single blended verdict lets one mask the other.
|
||||||
|
|
||||||
## When to reach for it
|
## When to reach for it
|
||||||
|
|
||||||
@@ -22,11 +10,11 @@ Reach for this when there is a diff to judge against a known-good point and you
|
|||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
The **Spec** axis needs somewhere to find the originating spec — an issue reference in the commit messages, a path you pass in, or a PRD under `docs/`/`specs/`. That issue-tracker wiring comes from [setup-matt-pocock-skills](https://aihero.dev/skills-setup-matt-pocock-skills); without a spec the Spec axis simply skips and says so. The **Standards** axis needs nothing set up — it always carries a built-in Fowler smell baseline even in a repo that documents no conventions.
|
The **Spec** axis needs somewhere to find the originating spec — an issue reference in the commit messages, a path you pass in, or a spec under `docs/`/`specs/`. That issue-tracker wiring comes from [setup-matt-pocock-skills](https://aihero.dev/skills-setup-matt-pocock-skills); without a spec the Spec axis simply skips and says so. The **Standards** axis needs nothing set up — it always carries a built-in Fowler smell baseline even in a repo that documents no conventions.
|
||||||
|
|
||||||
## Two axes, never merged
|
## Two axes, never merged
|
||||||
|
|
||||||
The defining idea is the **two axes**. **Standards** asks whether the diff conforms to how this repo writes code — its `CODING_STANDARDS.md` or `CONTRIBUTING.md`, plus a fixed baseline of ~12 Fowler code smells (Mysterious Name, Duplicated Code, Feature Envy, Data Clumps, …). Two rules keep the baseline safe: a documented repo standard always overrides it, and every smell is a judgement call, never a hard violation. **Spec** asks the orthogonal question — does the code do what the issue or PRD actually asked, without missing requirements or smuggling in scope creep?
|
The defining idea is the **two axes**. **Standards** asks whether the diff conforms to how this repo writes code — its `CODING_STANDARDS.md` or `CONTRIBUTING.md`, plus a fixed baseline of ~12 Fowler code smells (Mysterious Name, Duplicated Code, Feature Envy, Data Clumps, …). Two rules keep the baseline safe: a documented repo standard always overrides it, and every smell is a judgement call, never a hard violation. **Spec** asks the orthogonal question — does the code do what the issue or spec actually asked, without missing requirements or smuggling in scope creep?
|
||||||
|
|
||||||
They run as parallel sub-agents so neither pollutes the other's context, and the final report presents them under separate `## Standards` and `## Spec` headings with a per-axis summary. There is deliberately no single winner across axes.
|
They run as parallel sub-agents so neither pollutes the other's context, and the final report presents them under separate `## Standards` and `## Spec` headings with a per-axis summary. There is deliberately no single winner across axes.
|
||||||
|
|
||||||
@@ -41,7 +29,7 @@ They run as parallel sub-agents so neither pollutes the other's context, and the
|
|||||||
`code-review` is the review step at the tail of the main build chain:
|
`code-review` is the review step at the tail of the main build chain:
|
||||||
|
|
||||||
```txt
|
```txt
|
||||||
grill-with-docs → to-prd → to-issues → implement → code-review
|
grill-with-docs → to-spec → to-tickets → implement → code-review
|
||||||
```
|
```
|
||||||
|
|
||||||
Its closest neighbour is [implement](https://aihero.dev/skills-implement), which drives the build and calls this as its own review pass before committing; upstream, the spec it checks against is produced by [to-prd](https://aihero.dev/skills-to-prd) and [to-issues](https://aihero.dev/skills-to-issues). When you're unsure which skill or flow fits, [ask-matt](https://aihero.dev/skills-ask-matt) routes you.
|
Its closest neighbour is [implement](https://aihero.dev/skills-implement), which drives the build and calls this as its own review pass before committing; upstream, the spec it checks against is produced by [to-spec](https://aihero.dev/skills-to-spec) and [to-tickets](https://aihero.dev/skills-to-tickets). When you're unsure which skill or flow fits, [ask-matt](https://aihero.dev/skills-ask-matt) routes you.
|
||||||
|
|||||||
@@ -1,15 +1,3 @@
|
|||||||
Quickstart:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx skills add mattpocock/skills --skill=codebase-design
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx skills update codebase-design
|
|
||||||
```
|
|
||||||
|
|
||||||
[Source](https://github.com/mattpocock/skills/tree/main/skills/engineering/codebase-design)
|
|
||||||
|
|
||||||
## What it does
|
## What it does
|
||||||
|
|
||||||
`codebase-design` gives you a shared, precise vocabulary for designing **deep modules** — a lot of behaviour hidden behind a small interface, placed at a clean seam, testable through that interface.
|
`codebase-design` gives you a shared, precise vocabulary for designing **deep modules** — a lot of behaviour hidden behind a small interface, placed at a clean seam, testable through that interface.
|
||||||
@@ -34,7 +22,7 @@ Callers and tests cross the same seam, so a well-placed interface gives tests so
|
|||||||
|
|
||||||
## Pulled out on purpose
|
## Pulled out on purpose
|
||||||
|
|
||||||
`codebase-design` is the **single source of truth** for the deep-module vocabulary, split out as its own model-invoked skill so anything can reach it. Other skills point at it rather than restating the words: [tdd](https://aihero.dev/skills-tdd) borrows it to place a seam before writing the test, [improve-codebase-architecture](https://aihero.dev/skills-improve-codebase-architecture) leans on it while restructuring existing code, and [to-prd](https://aihero.dev/skills-to-prd) speaks it when it sketches seams and deepening opportunities before writing a spec.
|
`codebase-design` is the **single source of truth** for the deep-module vocabulary, split out as its own model-invoked skill so anything can reach it. Other skills point at it rather than restating the words: [tdd](https://aihero.dev/skills-tdd) borrows it to place a seam before writing the test, [improve-codebase-architecture](https://aihero.dev/skills-improve-codebase-architecture) leans on it while restructuring existing code, and [to-spec](https://aihero.dev/skills-to-spec) speaks it when it sketches seams and deepening opportunities before writing a spec.
|
||||||
|
|
||||||
The point of keeping it standalone is that you can also reach for it on its own — as a **reference** for how to think about module design — without triggering the larger process any of those skills mandate. Fix the words once, in one place, and every design conversation inherits them.
|
The point of keeping it standalone is that you can also reach for it on its own — as a **reference** for how to think about module design — without triggering the larger process any of those skills mandate. Fix the words once, in one place, and every design conversation inherits them.
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,3 @@
|
|||||||
Quickstart:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx skills add mattpocock/skills --skill=diagnosing-bugs
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx skills update diagnosing-bugs
|
|
||||||
```
|
|
||||||
|
|
||||||
[Source](https://github.com/mattpocock/skills/tree/main/skills/engineering/diagnosing-bugs)
|
|
||||||
|
|
||||||
## What it does
|
## What it does
|
||||||
|
|
||||||
`diagnosing-bugs` runs a disciplined diagnosis loop for hard bugs and performance regressions — building a repro, minimising it, ranking hypotheses, instrumenting, then fixing with a regression test.
|
`diagnosing-bugs` runs a disciplined diagnosis loop for hard bugs and performance regressions — building a repro, minimising it, ranking hypotheses, instrumenting, then fixing with a regression test.
|
||||||
|
|||||||
@@ -1,15 +1,3 @@
|
|||||||
Quickstart:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx skills add mattpocock/skills --skill=domain-modeling
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx skills update domain-modeling
|
|
||||||
```
|
|
||||||
|
|
||||||
[Source](https://github.com/mattpocock/skills/tree/main/skills/engineering/domain-modeling)
|
|
||||||
|
|
||||||
## What it does
|
## What it does
|
||||||
|
|
||||||
`domain-modeling` builds and sharpens a project's **ubiquitous language** as you design — challenging fuzzy terms, stress-testing relationships with concrete scenarios, and writing the glossary and decisions down the moment they crystallise.
|
`domain-modeling` builds and sharpens a project's **ubiquitous language** as you design — challenging fuzzy terms, stress-testing relationships with concrete scenarios, and writing the glossary and decisions down the moment they crystallise.
|
||||||
@@ -43,4 +31,4 @@ Keeping it standalone means you can also reach for it directly — as a **refere
|
|||||||
|
|
||||||
## Where it fits
|
## Where it fits
|
||||||
|
|
||||||
`domain-modeling` is a **reach-for-it-anytime standalone** that runs *underneath* other skills as often as at a fixed step. Its closest neighbour is [codebase-design](https://aihero.dev/skills-codebase-design), because a shared language is what lets you name a deep module and its seam precisely; downstream, a settled glossary is exactly what [to-prd](https://aihero.dev/skills-to-prd) synthesises into a spec written in the project's own words. When you're unsure which skill or flow fits, [ask-matt](https://aihero.dev/skills-ask-matt) routes you.
|
`domain-modeling` is a **reach-for-it-anytime standalone** that runs *underneath* other skills as often as at a fixed step. Its closest neighbour is [codebase-design](https://aihero.dev/skills-codebase-design), because a shared language is what lets you name a deep module and its seam precisely; downstream, a settled glossary is exactly what [to-spec](https://aihero.dev/skills-to-spec) synthesises into a spec written in the project's own words. When you're unsure which skill or flow fits, [ask-matt](https://aihero.dev/skills-ask-matt) routes you.
|
||||||
|
|||||||
@@ -1,18 +1,6 @@
|
|||||||
Quickstart:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx skills add mattpocock/skills --skill=grill-with-docs
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx skills update grill-with-docs
|
|
||||||
```
|
|
||||||
|
|
||||||
[Source](https://github.com/mattpocock/skills/tree/main/skills/engineering/grill-with-docs)
|
|
||||||
|
|
||||||
## What it does
|
## What it does
|
||||||
|
|
||||||
`grill-with-docs` interviews you relentlessly about a plan or design, one question at a time, until you and the agent reach a shared understanding — and it writes the vocabulary and decisions down as you go.
|
`grill-with-docs` interviews you relentlessly about a plan or design, a round of questions at a time, until you and the agent reach a shared understanding — and it writes the vocabulary and decisions down as you go.
|
||||||
|
|
||||||
The grilling **leaves a paper trail**. A plain interview sharpens your thinking and then evaporates when the session ends; this one captures each term the moment it's resolved into a `CONTEXT.md` glossary, and records the hard, one-way decisions as ADRs. The alignment survives the conversation instead of living only in your head.
|
The grilling **leaves a paper trail**. A plain interview sharpens your thinking and then evaporates when the session ends; this one captures each term the moment it's resolved into a `CONTEXT.md` glossary, and records the hard, one-way decisions as ADRs. The alignment survives the conversation instead of living only in your head.
|
||||||
|
|
||||||
@@ -20,7 +8,7 @@ The grilling **leaves a paper trail**. A plain interview sharpens your thinking
|
|||||||
|
|
||||||
You invoke this by typing `/grill-with-docs` — the agent won't reach for it on its own.
|
You invoke this by typing `/grill-with-docs` — the agent won't reach for it on its own.
|
||||||
|
|
||||||
Reach for it at the very start of a change, when the plan is still fuzzy and the domain language isn't settled, and you want to stress-test both before any code exists. If you only want the interview and don't need the artifacts, use [grilling](https://aihero.dev/skills-grilling); if the plan is already clear and you just need to pin down or record terminology, use [domain-modeling](https://aihero.dev/skills-domain-modeling).
|
Reach for it at the very start of a change, when the plan is still fuzzy and the domain language isn't settled, and you want to stress-test both before any code exists. If you only want the interview and don't need the artifacts, use [grilling](https://aihero.dev/skills-grilling); if the plan is already clear and you just need to pin down or record terminology, use [domain-modeling](https://aihero.dev/skills-domain-modeling). And if the change is too big to hold in one session and its route is still foggy — a greenfield project, a huge feature build — start upstream with [wayfinder](https://aihero.dev/skills-wayfinder): it charts the effort as a map of decisions, then hands back to this main flow once the way is clear.
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
@@ -28,13 +16,13 @@ This skill is stateful — it writes into your repo as it grills. Resolved terms
|
|||||||
|
|
||||||
## The grill
|
## The grill
|
||||||
|
|
||||||
The engine is a **grill**: a relentless, one-question-at-a-time walk down the design tree, resolving dependencies between decisions before moving on, with a recommended answer offered for every question. Questions the codebase can answer are answered by reading the codebase, not by asking you.
|
The engine is a **grill**: a relentless, round-by-round walk down the decision tree. Each round asks the whole **frontier** — every decision whose prerequisites are already settled — and waits, so dependencies between decisions are resolved before the questions that hang off them are asked, with a recommended answer offered for every question. Questions the codebase can answer are answered by reading the codebase, not by asking you.
|
||||||
|
|
||||||
What makes this variant its own skill is where the answers go. As the grill runs, fuzzy language gets sharpened into canonical terms and written to the glossary inline — not batched at the end. The glossary stays a glossary: pure vocabulary, no implementation details, no spec. ADRs are offered sparingly, only when a decision is hard to reverse, surprising without context, and the result of a real trade-off. Most sessions produce a sharper glossary and few or no ADRs, and that's the intended shape.
|
What makes this variant its own skill is where the answers go. As the grill runs, fuzzy language gets sharpened into canonical terms and written to the glossary inline — not batched at the end. The glossary stays a glossary: pure vocabulary, no implementation details, no spec. ADRs are offered sparingly, only when a decision is hard to reverse, surprising without context, and the result of a real trade-off. Most sessions produce a sharper glossary and few or no ADRs, and that's the intended shape.
|
||||||
|
|
||||||
## It's working if
|
## It's working if
|
||||||
|
|
||||||
- It asks one question at a time and waits, rather than dumping a questionnaire.
|
- It asks a round of independent questions and waits, rather than dumping the whole questionnaire at you.
|
||||||
- Terms get written to `CONTEXT.md` the moment they resolve, in your project's own words.
|
- Terms get written to `CONTEXT.md` the moment they resolve, in your project's own words.
|
||||||
- It reaches into the codebase to answer its own questions where it can.
|
- It reaches into the codebase to answer its own questions where it can.
|
||||||
- ADRs stay rare — you're not asked to rubber-stamp reversible choices.
|
- ADRs stay rare — you're not asked to rubber-stamp reversible choices.
|
||||||
@@ -44,7 +32,7 @@ What makes this variant its own skill is where the answers go. As the grill runs
|
|||||||
`grill-with-docs` is the opening step of the main build chain:
|
`grill-with-docs` is the opening step of the main build chain:
|
||||||
|
|
||||||
```txt
|
```txt
|
||||||
grill-with-docs → to-prd → to-issues → implement → code-review
|
grill-with-docs → to-spec → to-tickets → implement → code-review
|
||||||
```
|
```
|
||||||
|
|
||||||
It comes first, before anything is written down as a spec: it produces the shared understanding and settled vocabulary that [to-prd](https://aihero.dev/skills-to-prd) then synthesises into a PRD without re-interviewing you. Its close neighbours are [grilling](https://aihero.dev/skills-grilling), the same interview without the docs, and [domain-modeling](https://aihero.dev/skills-domain-modeling), the glossary-and-ADR discipline it drives. When you're unsure which skill or flow fits, [ask-matt](https://aihero.dev/skills-ask-matt) routes you.
|
It comes first, before anything is written down as a spec: it produces the shared understanding and settled vocabulary that [to-spec](https://aihero.dev/skills-to-spec) then synthesises into a spec without re-interviewing you. Its close neighbours are [grilling](https://aihero.dev/skills-grilling), the same interview without the docs, and [domain-modeling](https://aihero.dev/skills-domain-modeling), the glossary-and-ADR discipline it drives. When you're unsure which skill or flow fits, [ask-matt](https://aihero.dev/skills-ask-matt) routes you.
|
||||||
|
|||||||
@@ -1,18 +1,6 @@
|
|||||||
Quickstart:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx skills add mattpocock/skills --skill=implement
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx skills update implement
|
|
||||||
```
|
|
||||||
|
|
||||||
[Source](https://github.com/mattpocock/skills/tree/main/skills/engineering/implement)
|
|
||||||
|
|
||||||
## What it does
|
## What it does
|
||||||
|
|
||||||
`implement` builds the work described in a PRD or a set of issues — driving it through test-driven development, typechecking, and the full test suite, then handing off to review and committing to the current branch.
|
`implement` builds the work described in a spec or a set of tickets — driving it through test-driven development, typechecking, and the full test suite, then handing off to review and committing to the current branch.
|
||||||
|
|
||||||
It does **not** decide what to build. The spec is already settled and the seams are already agreed; `implement` executes that plan rather than reopening it. It is the hands, not the head — the thinking happened upstream.
|
It does **not** decide what to build. The spec is already settled and the seams are already agreed; `implement` executes that plan rather than reopening it. It is the hands, not the head — the thinking happened upstream.
|
||||||
|
|
||||||
@@ -20,11 +8,11 @@ It does **not** decide what to build. The spec is already settled and the seams
|
|||||||
|
|
||||||
You invoke this by typing `/implement` — the agent won't reach for it on its own.
|
You invoke this by typing `/implement` — the agent won't reach for it on its own.
|
||||||
|
|
||||||
Reach for it once the work is written down as a PRD or split into issues and you're ready to turn that into code. If the spec doesn't exist yet, write it first — for that, use [to-prd](https://aihero.dev/skills-to-prd), or [to-issues](https://aihero.dev/skills-to-issues) to break a PRD into tickets. If you just want to build something test-first without a full spec, drop to [tdd](https://aihero.dev/skills-tdd) directly.
|
Reach for it once the work is written down as a spec or split into tickets and you're ready to turn that into code. If the spec doesn't exist yet, write it first — for that, use [to-spec](https://aihero.dev/skills-to-spec), or [to-tickets](https://aihero.dev/skills-to-tickets) to break a spec into tickets. If you just want to build something test-first without a full spec, drop to [tdd](https://aihero.dev/skills-tdd) directly.
|
||||||
|
|
||||||
## Pre-agreed seams
|
## Pre-agreed seams
|
||||||
|
|
||||||
The idea `implement` runs on is the **seam** — the stable interface a feature is tested at, chosen before any code is written. It doesn't invent seams mid-build; it uses the ones already picked (during [to-prd](https://aihero.dev/skills-to-prd)) and writes tests against them via [tdd](https://aihero.dev/skills-tdd). Working at pre-agreed seams is what keeps the implementation honest: the tests target something durable, so the code underneath can move without the tests moving.
|
The idea `implement` runs on is the **seam** — the stable interface a feature is tested at, chosen before any code is written. It doesn't invent seams mid-build; it uses the ones already picked (during [to-spec](https://aihero.dev/skills-to-spec)) and writes tests against them via [tdd](https://aihero.dev/skills-tdd). Working at pre-agreed seams is what keeps the implementation honest: the tests target something durable, so the code underneath can move without the tests moving.
|
||||||
|
|
||||||
Around that core it keeps the loop tight — typecheck often, run single test files as it goes, run the whole suite once at the end — then closes out with a review pass and a commit to the current branch.
|
Around that core it keeps the loop tight — typecheck often, run single test files as it goes, run the whole suite once at the end — then closes out with a review pass and a commit to the current branch.
|
||||||
|
|
||||||
@@ -33,7 +21,7 @@ Around that core it keeps the loop tight — typecheck often, run single test fi
|
|||||||
`implement` is the build step near the end of the main chain, just before the review:
|
`implement` is the build step near the end of the main chain, just before the review:
|
||||||
|
|
||||||
```txt
|
```txt
|
||||||
grill-with-docs → to-prd → to-issues → implement → code-review
|
grill-with-docs → to-spec → to-tickets → implement → code-review
|
||||||
```
|
```
|
||||||
|
|
||||||
Reach for it after the work has been specced and sequenced, not before. Its key neighbours are [to-issues](https://aihero.dev/skills-to-issues), which produces the independently-grabbable tickets it works through, and [tdd](https://aihero.dev/skills-tdd), which it drives internally to write the tests at each seam before running its own [code-review](https://aihero.dev/skills-code-review) pass and committing. When you're unsure which skill or flow fits, [ask-matt](https://aihero.dev/skills-ask-matt) routes you.
|
Reach for it after the work has been specced and sequenced, not before. Its key neighbours are [to-tickets](https://aihero.dev/skills-to-tickets), which produces the tickets — each declaring its blocking edges — that it works through, and [tdd](https://aihero.dev/skills-tdd), which it drives internally to write the tests at each seam before running its own [code-review](https://aihero.dev/skills-code-review) pass and committing. When you're unsure which skill or flow fits, [ask-matt](https://aihero.dev/skills-ask-matt) routes you.
|
||||||
|
|||||||
@@ -1,21 +1,11 @@
|
|||||||
Quickstart:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx skills add mattpocock/skills --skill=improve-codebase-architecture
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx skills update improve-codebase-architecture
|
|
||||||
```
|
|
||||||
|
|
||||||
[Source](https://github.com/mattpocock/skills/tree/main/skills/engineering/improve-codebase-architecture)
|
|
||||||
|
|
||||||
## What it does
|
## What it does
|
||||||
|
|
||||||
`improve-codebase-architecture` scans a codebase for **deepening opportunities** — places where a shallow module (an interface nearly as complex as the thing it hides) could become a deep one — presents them as a self-contained visual HTML report, then grills through whichever one you pick.
|
`improve-codebase-architecture` scans a codebase for **deepening opportunities** — places where a shallow module (an interface nearly as complex as the thing it hides) could become a deep one — presents them as a self-contained visual HTML report, then grills through whichever one you pick.
|
||||||
|
|
||||||
It does **not** hand you a flat list of refactors. Every candidate has to pass the **deletion test** — would removing this module *concentrate* complexity behind a smaller interface, or just move it around? Only the "concentrates" cases earn a card. That filter is what stops the report from becoming generic cleanup advice.
|
It does **not** hand you a flat list of refactors. Every candidate has to pass the **deletion test** — would removing this module *concentrate* complexity behind a smaller interface, or just move it around? Only the "concentrates" cases earn a card. That filter is what stops the report from becoming generic cleanup advice.
|
||||||
|
|
||||||
|
Unless you point it at a specific area, it also scopes itself to where development is actually landing — reading the recent commits to bias toward the code you're still changing. Deepening a module pays off by making future changes to it easier, so it puts extra weight on the parts of the repo that have recently changed.
|
||||||
|
|
||||||
## When to reach for it
|
## When to reach for it
|
||||||
|
|
||||||
You invoke this by typing `/improve-codebase-architecture` — the agent won't reach for it on its own.
|
You invoke this by typing `/improve-codebase-architecture` — the agent won't reach for it on its own.
|
||||||
@@ -36,4 +26,4 @@ Then it stops and asks which one you want to explore. Pick one and it runs the [
|
|||||||
|
|
||||||
## Where it fits
|
## Where it fits
|
||||||
|
|
||||||
`improve-codebase-architecture` is **periodic maintenance** — run it every few days, not as a step in a chain. Its neighbours are [codebase-design](https://aihero.dev/skills-codebase-design), which owns the depth-and-seam vocabulary every candidate is written in, [grilling](https://aihero.dev/skills-grilling), which walks the design tree once you've chosen a candidate, and [domain-modeling](https://aihero.dev/skills-domain-modeling), which keeps `CONTEXT.md` and the ADRs current as the redesign settles. When you're unsure which skill or flow fits, [ask-matt](https://aihero.dev/skills-ask-matt) routes you.
|
`improve-codebase-architecture` is **periodic maintenance** — run it every few days, not as a step in a chain. Its neighbours are [codebase-design](https://aihero.dev/skills-codebase-design), which owns the depth-and-seam vocabulary every candidate is written in, [grilling](https://aihero.dev/skills-grilling), which walks the decision tree once you've chosen a candidate, and [domain-modeling](https://aihero.dev/skills-domain-modeling), which keeps `CONTEXT.md` and the ADRs current as the redesign settles. When you're unsure which skill or flow fits, [ask-matt](https://aihero.dev/skills-ask-matt) routes you.
|
||||||
|
|||||||
@@ -1,15 +1,3 @@
|
|||||||
Quickstart:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx skills add mattpocock/skills --skill=prototype
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx skills update prototype
|
|
||||||
```
|
|
||||||
|
|
||||||
[Source](https://github.com/mattpocock/skills/tree/main/skills/engineering/prototype)
|
|
||||||
|
|
||||||
## What it does
|
## What it does
|
||||||
|
|
||||||
`prototype` builds a small, disposable program whose only job is to answer one design question — does this state model feel right, or what should this UI look like.
|
`prototype` builds a small, disposable program whose only job is to answer one design question — does this state model feel right, or what should this UI look like.
|
||||||
@@ -26,15 +14,17 @@ Reach for it when you have a design question that's hard to settle on paper —
|
|||||||
|
|
||||||
The question decides the shape, and there are two shapes:
|
The question decides the shape, and there are two shapes:
|
||||||
|
|
||||||
- **"Does this logic / state model feel right?"** — a tiny interactive terminal app that pushes the state machine through the awkward cases, printing the full state after every action so you can watch what changes.
|
- **"Does this logic / state model feel right?"** — a single shareable HTML file, free-play buttons plus tabbed guided walkthroughs, that pushes the state machine through the awkward cases and shows the full state after every click, so anyone — including a non-developer — can watch what changes.
|
||||||
- **"What should this look like?"** — several radically different UI variations on one route, switchable from a floating bar, so you compare real renders instead of imagining them.
|
- **"What should this look like?"** — several radically different UI variations on one route, switchable from a floating bar, so you compare real renders instead of imagining them.
|
||||||
|
|
||||||
Picking the wrong branch wastes the whole prototype, so the question comes first. Both branches keep state in memory, run from one command, and surface the full state on every step.
|
Picking the wrong branch wastes the whole prototype, so the question comes first. Both branches keep state in memory, are trivial to run, and surface the full state on every step.
|
||||||
|
|
||||||
## The answer is the artifact
|
## Keep the prototype as a primary source
|
||||||
|
|
||||||
The code is disposable; the **answer** is the only thing worth keeping. When the prototype has settled its question, capture the verdict somewhere durable — a commit message, an ADR, an issue, or a `NOTES.md` next to it — alongside the question it answered, then delete or absorb the code. A prototype left rotting in the repo has outlived its purpose.
|
A finished prototype leaves two things. The **answer** — the verdict plus the question it settled — is what you capture durably (a commit message, an ADR, an issue). The **prototype itself is a primary source** — the runnable evidence the answer came from.
|
||||||
|
|
||||||
|
The prototype doesn't belong in the main branch: no tests, no error handling, nothing to maintain. But that's not a reason to destroy it. Once the answer is captured, fold any validated decision into the real code, then capture the prototype on a throwaway branch — out of main, never merged — and leave a context pointer to it on the implementation issue. The main branch stays clean; the raw exploration stays one click away for anyone who wants to re-run it. A prototype left rotting in the main branch has outlived its purpose — a prototype captured as a primary source on a side branch hasn't.
|
||||||
|
|
||||||
## Where it fits
|
## Where it fits
|
||||||
|
|
||||||
`prototype` is a reach-for-it-anytime standalone: you drop into it to resolve a design question, then drop back out. Its answer often feeds the next step — a validated state model or UI direction becomes settled input for [to-prd](https://aihero.dev/skills-to-prd) to write up, or an architectural decision worth recording via [domain-modeling](https://aihero.dev/skills-domain-modeling). When you're unsure which skill or flow fits, [ask-matt](https://aihero.dev/skills-ask-matt) routes you.
|
`prototype` is a reach-for-it-anytime standalone: you drop into it to resolve a design question, then drop back out. Its answer often feeds the next step — a validated state model or UI direction becomes settled input for [to-spec](https://aihero.dev/skills-to-spec) to write up, or an architectural decision worth recording via [domain-modeling](https://aihero.dev/skills-domain-modeling). When you're unsure which skill or flow fits, [ask-matt](https://aihero.dev/skills-ask-matt) routes you.
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
## What it does
|
||||||
|
|
||||||
|
`research` answers a question by reading the sources that own the answer and leaving a cited Markdown file behind. It works only from **primary sources** — official docs, source code, specs, first-party APIs — never a secondary write-up of them, so what it saves is traceable back to something authoritative rather than a summary of a summary.
|
||||||
|
|
||||||
|
## When to reach for it
|
||||||
|
|
||||||
|
Type `/research`, or the agent reaches for it automatically when a task turns into reading legwork.
|
||||||
|
|
||||||
|
Reach for it when the next step is *finding something out* — how an API behaves, what a spec actually says, whether a claim holds — and you'd rather not stall your own thread doing the reading. For sharpening a plan by interview instead of by reading, use [grilling](https://aihero.dev/skills-grilling); for exploring what to build with throwaway code, use [prototype](https://aihero.dev/skills-prototype).
|
||||||
|
|
||||||
|
## Delegated legwork
|
||||||
|
|
||||||
|
The defining move is that the reading runs as a **background agent**. You keep working; it goes off, follows each claim back to its primary source, and drops a single cited Markdown file into wherever the repo keeps such notes. Research is legwork you delegate, not thinking you outsource — you get back a document to react to, with its sources attached.
|
||||||
|
|
||||||
|
## Where it fits
|
||||||
|
|
||||||
|
A reach-for-it-anytime standalone that feeds the thinking skills: the file it produces is something to grill, plan, or design against, so it sits upstream of work like [grilling](https://aihero.dev/skills-grilling) and [to-spec](https://aihero.dev/skills-to-spec) rather than in the build chain. For the whole map, see [ask-matt](https://aihero.dev/skills-ask-matt).
|
||||||
@@ -1,15 +1,3 @@
|
|||||||
Quickstart:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx skills add mattpocock/skills --skill=resolving-merge-conflicts
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx skills update resolving-merge-conflicts
|
|
||||||
```
|
|
||||||
|
|
||||||
[Source](https://github.com/mattpocock/skills/tree/main/skills/engineering/resolving-merge-conflicts)
|
|
||||||
|
|
||||||
## What it does
|
## What it does
|
||||||
|
|
||||||
`resolving-merge-conflicts` works through an in-progress git merge or rebase conflict, hunk by hunk, and finishes the operation — resolved, checked, and committed.
|
`resolving-merge-conflicts` works through an in-progress git merge or rebase conflict, hunk by hunk, and finishes the operation — resolved, checked, and committed.
|
||||||
|
|||||||
@@ -1,15 +1,3 @@
|
|||||||
Quickstart:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx skills add mattpocock/skills --skill=setup-matt-pocock-skills
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx skills update setup-matt-pocock-skills
|
|
||||||
```
|
|
||||||
|
|
||||||
[Source](https://github.com/mattpocock/skills/tree/main/skills/engineering/setup-matt-pocock-skills)
|
|
||||||
|
|
||||||
## What it does
|
## What it does
|
||||||
|
|
||||||
`setup-matt-pocock-skills` teaches one repo how the engineering skills should behave in it — where issues live, what the triage labels are called, and where the domain docs sit — and records those answers as **config** the other skills read.
|
`setup-matt-pocock-skills` teaches one repo how the engineering skills should behave in it — where issues live, what the triage labels are called, and where the domain docs sit — and records those answers as **config** the other skills read.
|
||||||
@@ -20,24 +8,24 @@ It writes config, it does not hard-code behaviour. The engineering chain assumes
|
|||||||
|
|
||||||
You invoke this by typing `/setup-matt-pocock-skills` — the agent won't reach for it on its own.
|
You invoke this by typing `/setup-matt-pocock-skills` — the agent won't reach for it on its own.
|
||||||
|
|
||||||
Reach for it **once per repo, before the first use of any other engineering skill**. If [triage](https://aihero.dev/skills-triage), [to-prd](https://aihero.dev/skills-to-prd), or [to-issues](https://aihero.dev/skills-to-issues) start guessing where your issues live or applying labels that don't exist, they haven't been set up here yet. Re-run it only to switch issue trackers or start over — day-to-day tweaks are just edits to `docs/agents/*.md`.
|
Reach for it **once per repo, before the first use of any other engineering skill**. If [triage](https://aihero.dev/skills-triage), [to-spec](https://aihero.dev/skills-to-spec), or [to-tickets](https://aihero.dev/skills-to-tickets) start guessing where your issues live or applying labels that don't exist, they haven't been set up here yet. Re-run it only to switch issue trackers or start over — day-to-day tweaks are just edits to `docs/agents/*.md`.
|
||||||
|
|
||||||
## The three decisions
|
## The three decisions
|
||||||
|
|
||||||
It walks you through three choices, one at a time, each with a plain-language explainer (it assumes you don't already know the terms):
|
It leads each with a recommended answer you can accept in a word, and skips whatever it can already infer — so most runs are a couple of quick confirmations:
|
||||||
|
|
||||||
- **Issue tracker** — where work is tracked, so `triage`/`to-prd`/`to-issues` know whether to call `gh`, `glab`, write markdown under `.scratch/`, or follow a workflow you describe. GitHub, GitLab, local markdown, or other.
|
- **Issue tracker** — where work is tracked, so `triage`/`to-spec`/`to-tickets` know whether to call `gh`, `glab`, write markdown under `.scratch/`, or follow a workflow you describe. GitHub, GitLab, local markdown, or other. (It proposes the one that matches your `git remote`.)
|
||||||
- **Triage labels** — the strings behind the five canonical roles (`needs-triage`, `needs-info`, `ready-for-agent`, `ready-for-human`, `wontfix`), mapped to labels you've actually configured so `triage` applies real ones instead of creating duplicates.
|
- **Triage labels** — asked only if the `triage` skill is installed, and then just: keep the default labels (`needs-triage`, `needs-info`, `ready-for-agent`, `ready-for-human`, `wontfix`)? Say no only if your tracker already uses other names, so `triage` applies real ones instead of creating duplicates.
|
||||||
- **Domain docs** — whether the repo has one `CONTEXT.md` or a multi-context map, so skills that read domain language look in the right place.
|
- **Domain docs** — assumed single-context (one `CONTEXT.md` + `docs/adr/` at the root), which fits almost every repo; it only raises a multi-context map when it spots monorepo signals.
|
||||||
|
|
||||||
The output is three files — `docs/agents/issue-tracker.md`, `docs/agents/triage-labels.md`, `docs/agents/domain.md` — plus an `## Agent skills` block pointing to them in whichever of `CLAUDE.md` / `AGENTS.md` the repo already uses. Those files are the shared substrate the rest of the toolkit stands on.
|
The output is a set of files under `docs/agents/` — `issue-tracker.md`, `domain.md`, and `triage-labels.md` when `triage` is installed — plus an `## Agent skills` block pointing to them in whichever of `CLAUDE.md` / `AGENTS.md` the repo already uses. Those files are the shared substrate the rest of the toolkit stands on.
|
||||||
|
|
||||||
## It's working if
|
## It's working if
|
||||||
|
|
||||||
- Three files land under `docs/agents/`, and an `## Agent skills` section appears in your `CLAUDE.md` or `AGENTS.md`.
|
- `issue-tracker.md` and `domain.md` land under `docs/agents/` (plus `triage-labels.md` when `triage` is installed), and an `## Agent skills` section appears in your `CLAUDE.md` or `AGENTS.md`.
|
||||||
- The tracker it proposes matches your real `git remote`, and the labels match strings that already exist in your repo.
|
- The tracker it proposes matches your real `git remote`, and the labels match strings that already exist in your repo.
|
||||||
- Afterwards, `triage` and `to-issues` act on the right place with the right labels instead of asking or guessing.
|
- Afterwards, `triage` and `to-tickets` act on the right place with the right labels instead of asking or guessing.
|
||||||
|
|
||||||
## Where it fits
|
## Where it fits
|
||||||
|
|
||||||
`setup-matt-pocock-skills` is a **run-once setup** — the foundation the whole engineering set stands on, not a step you repeat. Its neighbours are the skills that read what it writes: [triage](https://aihero.dev/skills-triage), because it applies the label vocabulary configured here, and [to-prd](https://aihero.dev/skills-to-prd) / [to-issues](https://aihero.dev/skills-to-issues), because they publish into the issue tracker configured here. Run it first; everything downstream assumes it has. When you're unsure which skill or flow fits, [ask-matt](https://aihero.dev/skills-ask-matt) routes you.
|
`setup-matt-pocock-skills` is a **run-once setup** — the foundation the whole engineering set stands on, not a step you repeat. Its neighbours are the skills that read what it writes: [triage](https://aihero.dev/skills-triage), because it applies the label vocabulary configured here, and [to-spec](https://aihero.dev/skills-to-spec) / [to-tickets](https://aihero.dev/skills-to-tickets), because they publish into the issue tracker configured here. Run it first; everything downstream assumes it has. When you're unsure which skill or flow fits, [ask-matt](https://aihero.dev/skills-ask-matt) routes you.
|
||||||
|
|||||||
+2
-14
@@ -1,15 +1,3 @@
|
|||||||
Quickstart:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx skills add mattpocock/skills --skill=tdd
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx skills update tdd
|
|
||||||
```
|
|
||||||
|
|
||||||
[Source](https://github.com/mattpocock/skills/tree/main/skills/engineering/tdd)
|
|
||||||
|
|
||||||
## What it does
|
## What it does
|
||||||
|
|
||||||
`tdd` builds a feature or fixes a bug test-first, one behaviour at a time, driving the code out through a red-green loop.
|
`tdd` builds a feature or fixes a bug test-first, one behaviour at a time, driving the code out through a red-green loop.
|
||||||
@@ -20,7 +8,7 @@ It will **not** write all the tests up front. Batching the tests first ("horizon
|
|||||||
|
|
||||||
Type `/tdd`, or the agent reaches for it automatically when a task fits — building a feature or fixing a bug test-first, or when you say "red-green-refactor".
|
Type `/tdd`, or the agent reaches for it automatically when a task fits — building a feature or fixing a bug test-first, or when you say "red-green-refactor".
|
||||||
|
|
||||||
Reach for it when there's a concrete behaviour to build and you want tests that survive a refactor. If the behaviour isn't pinned down yet, settle the spec first — for that, use [to-prd](https://aihero.dev/skills-to-prd). When the work is really about the shape of the interface rather than the tests, use [codebase-design](https://aihero.dev/skills-codebase-design); `tdd` calls into it for the deep-module vocabulary during planning.
|
Reach for it when there's a concrete behaviour to build and you want tests that survive a refactor. If the behaviour isn't pinned down yet, settle the spec first — for that, use [to-spec](https://aihero.dev/skills-to-spec). When the work is really about the shape of the interface rather than the tests, use [codebase-design](https://aihero.dev/skills-codebase-design); `tdd` calls into it for the deep-module vocabulary during planning.
|
||||||
|
|
||||||
## Red-green, one slice at a time
|
## Red-green, one slice at a time
|
||||||
|
|
||||||
@@ -41,7 +29,7 @@ Refactoring only happens once the suite is green; never while red.
|
|||||||
`tdd` is the red-green loop the main build chain runs to write code:
|
`tdd` is the red-green loop the main build chain runs to write code:
|
||||||
|
|
||||||
```txt
|
```txt
|
||||||
grill-with-docs → to-prd → to-issues → implement → code-review
|
grill-with-docs → to-spec → to-tickets → implement → code-review
|
||||||
```
|
```
|
||||||
|
|
||||||
[implement](https://aihero.dev/skills-implement) is the chain's build step, and it drives `tdd` internally to build each ticket test-first before handing off to [code-review](https://aihero.dev/skills-code-review) — so `tdd` is the engine inside that step rather than a step of its own. You can also reach for it directly, whenever there's a concrete behaviour to build without a full spec. Its other neighbour is [codebase-design](https://aihero.dev/skills-codebase-design), which it leans on to find deep-module seams worth testing at. When you're unsure which skill or flow fits, [ask-matt](https://aihero.dev/skills-ask-matt) routes you.
|
[implement](https://aihero.dev/skills-implement) is the chain's build step, and it drives `tdd` internally to build each ticket test-first before handing off to [code-review](https://aihero.dev/skills-code-review) — so `tdd` is the engine inside that step rather than a step of its own. You can also reach for it directly, whenever there's a concrete behaviour to build without a full spec. Its other neighbour is [codebase-design](https://aihero.dev/skills-codebase-design), which it leans on to find deep-module seams worth testing at. When you're unsure which skill or flow fits, [ask-matt](https://aihero.dev/skills-ask-matt) routes you.
|
||||||
|
|||||||
@@ -1,43 +0,0 @@
|
|||||||
Quickstart:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx skills add mattpocock/skills --skill=to-issues
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx skills update to-issues
|
|
||||||
```
|
|
||||||
|
|
||||||
[Source](https://github.com/mattpocock/skills/tree/main/skills/engineering/to-issues)
|
|
||||||
|
|
||||||
## What it does
|
|
||||||
|
|
||||||
`to-issues` breaks a plan, spec, or PRD into a set of independently-grabbable issues and publishes them to your project's issue tracker, in dependency order.
|
|
||||||
|
|
||||||
Every issue 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, which is what makes the resulting tickets safe to hand to independent agents.
|
|
||||||
|
|
||||||
## When to reach for it
|
|
||||||
|
|
||||||
You invoke this by typing `/to-issues` — 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 split into tickets an agent can pick up. Point it at the conversation, or pass an existing issue reference and it fetches the body and comments 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).
|
|
||||||
|
|
||||||
## Prerequisites
|
|
||||||
|
|
||||||
`to-issues` publishes into your issue tracker, so [setup-matt-pocock-skills](https://aihero.dev/skills-setup-matt-pocock-skills) must have configured the tracker and its triage label vocabulary for this repo first. It applies the ready-for-agent triage label itself as it publishes.
|
|
||||||
|
|
||||||
## 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-issues` 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, dependencies, what to merge or split) before writing anything, and publishes blockers first so each issue's "Blocked by" field can reference a real ticket.
|
|
||||||
|
|
||||||
## Where it fits
|
|
||||||
|
|
||||||
`to-issues` is a step in the main build chain:
|
|
||||||
|
|
||||||
```txt
|
|
||||||
grill-with-docs → to-prd → to-issues → implement → code-review
|
|
||||||
```
|
|
||||||
|
|
||||||
It sits between [to-prd](https://aihero.dev/skills-to-prd), which hands it a settled spec with user stories to slice against, and [implement](https://aihero.dev/skills-implement), which builds each independently-grabbable issue, 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. When you're unsure which skill or flow fits, [ask-matt](https://aihero.dev/skills-ask-matt) routes you.
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
Quickstart:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx skills add mattpocock/skills --skill=to-prd
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx skills update to-prd
|
|
||||||
```
|
|
||||||
|
|
||||||
[Source](https://github.com/mattpocock/skills/tree/main/skills/engineering/to-prd)
|
|
||||||
|
|
||||||
## What it does
|
|
||||||
|
|
||||||
`to-prd` turns the current conversation and your codebase understanding into a product requirements document, then publishes it to your issue tracker.
|
|
||||||
|
|
||||||
It does **not** interview you again. By the time you reach for it, the alignment work is done — `to-prd` synthesises what is already known rather than asking a fresh round of questions.
|
|
||||||
|
|
||||||
## When to reach for it
|
|
||||||
|
|
||||||
You invoke this by typing `/to-prd` — the agent won't reach for it on its own.
|
|
||||||
|
|
||||||
Reach for it once a change has been talked through and the domain language is settled, and you want that shared understanding written down as a spec before any code is written. If you *haven't* aligned yet, grill first — for that, use [grill-with-docs](https://aihero.dev/skills-grill-with-docs). To split the finished PRD into tickets, use [to-issues](https://aihero.dev/skills-to-issues).
|
|
||||||
|
|
||||||
## Prerequisites
|
|
||||||
|
|
||||||
`to-prd` publishes into your issue tracker, so [setup-matt-pocock-skills](https://aihero.dev/skills-setup-matt-pocock-skills) must have configured the tracker and triage labels for this repo first. It applies the `ready-for-agent` label itself — no separate triage pass needed.
|
|
||||||
|
|
||||||
## What the PRD includes
|
|
||||||
|
|
||||||
- **Problem statement** — what is broken or missing, and why it's worth solving, in the project's own vocabulary.
|
|
||||||
- **Solution** — the shape of the fix at a high level, before any implementation detail.
|
|
||||||
- **User stories** — an extensive, numbered list of the concrete behaviours the change must support, each one independently checkable.
|
|
||||||
- **Implementation decisions** — the choices already settled during the conversation, so they aren't relitigated later.
|
|
||||||
- **Testing decisions** — the seams the feature will be tested at, and what "done" looks like.
|
|
||||||
- **Out-of-scope items** — what this change deliberately does *not* cover, to keep the ticket bounded.
|
|
||||||
- **Further notes** — anything else worth carrying forward that doesn't fit the sections above.
|
|
||||||
|
|
||||||
## Deep modules
|
|
||||||
|
|
||||||
Before writing the PRD, `to-prd` sketches the **seams** at which the feature will be tested and looks for **deep module** opportunities — a lot of functionality hidden behind a small, stable interface. It prefers existing seams to new ones and the highest seam possible, ideally just one across the whole change.
|
|
||||||
|
|
||||||
That matters for agentic development: a good interface gives tests something durable to target, so the code underneath can change without the tests moving.
|
|
||||||
|
|
||||||
## It's working if
|
|
||||||
|
|
||||||
- It starts writing the PRD instead of asking you a fresh round of questions.
|
|
||||||
- It checks the seams with you before writing, and proposes as few as possible.
|
|
||||||
- The PRD comes back in your project's domain vocabulary, not generic boilerplate.
|
|
||||||
|
|
||||||
## Where it fits
|
|
||||||
|
|
||||||
`to-prd` is a step in the main build chain:
|
|
||||||
|
|
||||||
```txt
|
|
||||||
grill-with-docs → to-prd → to-issues → implement → code-review
|
|
||||||
```
|
|
||||||
|
|
||||||
Reach for it after the plan and domain language are resolved, and before you break the work into implementation tickets. Its key neighbours are [grill-with-docs](https://aihero.dev/skills-grill-with-docs), which sharpens the context so the PRD is precise, and [to-issues](https://aihero.dev/skills-to-issues), which turns the PRD into independently-grabbable issues for [implement](https://aihero.dev/skills-implement) to build. When you're unsure which skill or flow fits, [ask-matt](https://aihero.dev/skills-ask-matt) routes you.
|
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
## What it does
|
||||||
|
|
||||||
|
`to-spec` turns the current conversation and your codebase understanding into a spec, then publishes it to your issue tracker.
|
||||||
|
|
||||||
|
It does **not** interview you again. By the time you reach for it, the alignment work is done — `to-spec` synthesises what is already known rather than asking a fresh round of questions.
|
||||||
|
|
||||||
|
## When to reach for it
|
||||||
|
|
||||||
|
You invoke this by typing `/to-spec` — the agent won't reach for it on its own.
|
||||||
|
|
||||||
|
Reach for it once a change has been talked through and the domain language is settled, and you want that shared understanding written down before any code is written. If you *haven't* aligned yet, grill first — for that, use [grill-with-docs](https://aihero.dev/skills-grill-with-docs). To split the finished spec into tickets, use [to-tickets](https://aihero.dev/skills-to-tickets).
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
`to-spec` publishes into your issue tracker, so [setup-matt-pocock-skills](https://aihero.dev/skills-setup-matt-pocock-skills) must have configured the tracker and triage labels for this repo first. It applies the `ready-for-agent` label itself — no separate triage pass needed.
|
||||||
|
|
||||||
|
## What the spec includes
|
||||||
|
|
||||||
|
- **Problem statement** — what is broken or missing, and why it's worth solving, in the project's own vocabulary.
|
||||||
|
- **Solution** — the shape of the fix at a high level, before any implementation detail.
|
||||||
|
- **User stories** — an extensive, numbered list of the concrete behaviours the change must support, each one independently checkable.
|
||||||
|
- **Implementation decisions** — the choices already settled during the conversation, so they aren't relitigated later.
|
||||||
|
- **Testing decisions** — the seams the feature will be tested at, and what "done" looks like.
|
||||||
|
- **Out-of-scope items** — what this change deliberately does *not* cover, to keep the ticket bounded.
|
||||||
|
- **Further notes** — anything else worth carrying forward that doesn't fit the sections above.
|
||||||
|
|
||||||
|
## Deep modules
|
||||||
|
|
||||||
|
Before writing the spec, `to-spec` sketches the **seams** at which the feature will be tested and looks for **deep module** opportunities — a lot of functionality hidden behind a small, stable interface. It prefers existing seams to new ones and the highest seam possible, ideally just one across the whole change.
|
||||||
|
|
||||||
|
That matters for agentic development: a good interface gives tests something durable to target, so the code underneath can change without the tests moving.
|
||||||
|
|
||||||
|
## It's working if
|
||||||
|
|
||||||
|
- It starts writing the spec instead of asking you a fresh round of questions.
|
||||||
|
- It checks the seams with you before writing, and proposes as few as possible.
|
||||||
|
- The spec comes back in your project's domain vocabulary, not generic boilerplate.
|
||||||
|
|
||||||
|
## Where it fits
|
||||||
|
|
||||||
|
`to-spec` is a step in the main build chain:
|
||||||
|
|
||||||
|
```txt
|
||||||
|
grill-with-docs → to-spec → to-tickets → implement → code-review
|
||||||
|
```
|
||||||
|
|
||||||
|
Reach for it after the plan and domain language are resolved, and before you break the work into implementation tickets. Its key neighbours are [grill-with-docs](https://aihero.dev/skills-grill-with-docs), which sharpens the context so the spec is precise, and [to-tickets](https://aihero.dev/skills-to-tickets), which turns the spec into a set of tickets for [implement](https://aihero.dev/skills-implement) to build. When you're unsure which skill or flow fits, [ask-matt](https://aihero.dev/skills-ask-matt) routes you.
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
## What it does
|
||||||
|
|
||||||
|
`to-tickets` breaks a plan, spec, or the current conversation into a set of **tickets** — each a tracer-bullet vertical slice — and publishes them to your configured tracker, with every ticket declaring the tickets that block it.
|
||||||
|
|
||||||
|
Every ticket 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, which is what makes each ticket safe to hand to an agent.
|
||||||
|
|
||||||
|
## When to reach for it
|
||||||
|
|
||||||
|
You invoke this by typing `/to-tickets` — 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 split into tickets. Point it at the conversation, or pass a spec or issue reference and it fetches the body and comments first. If the change hasn't been written up as a spec yet, produce one first — for that, use [to-spec](https://aihero.dev/skills-to-spec).
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
`to-tickets` publishes into your issue tracker, so [setup-matt-pocock-skills](https://aihero.dev/skills-setup-matt-pocock-skills) must have configured the tracker and its triage label vocabulary for this repo first. On a real tracker it applies the ready-for-agent label as it publishes.
|
||||||
|
|
||||||
|
## One artifact, two readings
|
||||||
|
|
||||||
|
The blocking edges are the whole point. They make one set of tickets read two ways, depending on the tracker:
|
||||||
|
|
||||||
|
- **Local files** → one file per ticket under `.scratch/<feature>/issues/`, numbered blockers-first, the edges written as text. You work them top-to-bottom, by hand, staying in the loop.
|
||||||
|
- **A real tracker (GitHub, Linear)** → one issue per ticket, the edges as native blocking links (or sub-issues). Any ticket whose blockers are all done is on the **frontier** and can be grabbed — so several agents can run at once.
|
||||||
|
|
||||||
|
The edges live in the ticket regardless of medium; the medium only decides whether anything acts on them in parallel. `to-tickets` produces the artifact — how you run it (sequential by hand, or a parallel fleet) is up to you.
|
||||||
|
|
||||||
|
## 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-tickets` 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, blocking edges, what to merge or split) before publishing anything, and publishes blockers first so each ticket's "Blocked by" can reference a real ticket.
|
||||||
|
|
||||||
|
## The wide-refactor exception
|
||||||
|
|
||||||
|
One shape breaks the tracer-bullet rule: a **wide refactor** — a single mechanical change (rename a column, retype a shared symbol) whose **blast radius** fans across the whole codebase, so one edit breaks thousands of call sites at once and no vertical slice can land green. `to-tickets` slices it as **expand–contract** instead: expand (add the new form beside the old so nothing breaks), migrate (move call sites over in batches sized by blast radius, one ticket per batch, CI green throughout because the old form still exists), then contract (delete the old form once no caller remains). When even the batches can't stay green alone, they share an integration branch that all block a final integrate-and-verify ticket, and green is promised only there.
|
||||||
|
|
||||||
|
## Where it fits
|
||||||
|
|
||||||
|
`to-tickets` is a step in the main build chain:
|
||||||
|
|
||||||
|
```txt
|
||||||
|
grill-with-docs → to-spec → to-tickets → implement → code-review
|
||||||
|
```
|
||||||
|
|
||||||
|
It sits between [to-spec](https://aihero.dev/skills-to-spec), which hands it a settled spec with user stories to slice against, and [implement](https://aihero.dev/skills-implement), which builds each ticket, 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 the frontier one ticket 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,15 +1,3 @@
|
|||||||
Quickstart:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx skills add mattpocock/skills --skill=triage
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx skills update triage
|
|
||||||
```
|
|
||||||
|
|
||||||
[Source](https://github.com/mattpocock/skills/tree/main/skills/engineering/triage)
|
|
||||||
|
|
||||||
## What it does
|
## What it does
|
||||||
|
|
||||||
`triage` moves issues on your project's tracker through a small **state machine** of triage roles — categorise them, verify the claim, grill them into shape if needed, and leave a ready-for-agent brief.
|
`triage` moves issues on your project's tracker through a small **state machine** of triage roles — categorise them, verify the claim, grill them into shape if needed, and leave a ready-for-agent brief.
|
||||||
@@ -20,7 +8,7 @@ It never labels blind. Every triaged item carries exactly one **category** role
|
|||||||
|
|
||||||
You invoke this by typing `/triage` and describing what you want in natural language — the agent won't reach for it on its own. "Show me anything that needs my attention", "let's look at #42", "move #42 to ready-for-agent".
|
You invoke this by typing `/triage` and describing what you want in natural language — the agent won't reach for it on its own. "Show me anything that needs my attention", "let's look at #42", "move #42 to ready-for-agent".
|
||||||
|
|
||||||
Reach for it when your issue tracker has raw, unevaluated reports and you want them sorted, verified, and turned into work an agent or human can pick up. To turn a settled conversation into a fresh spec instead, use [to-prd](https://aihero.dev/skills-to-prd); to split an existing PRD into tickets, use [to-issues](https://aihero.dev/skills-to-issues). `triage` is the reverse direction — it processes what's *already* landed in the tracker.
|
Reach for it when your issue tracker has raw, unevaluated reports and you want them sorted, verified, and turned into work an agent or human can pick up. To turn a settled conversation into a fresh spec instead, use [to-spec](https://aihero.dev/skills-to-spec); to split an existing spec into tickets, use [to-tickets](https://aihero.dev/skills-to-tickets). `triage` is the reverse direction — it processes what's *already* landed in the tracker.
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
@@ -43,4 +31,4 @@ The step that separates `triage` from ad-hoc labelling is verification. It repro
|
|||||||
|
|
||||||
## Where it fits
|
## Where it fits
|
||||||
|
|
||||||
`triage` is the **periodic maintenance** pass over your issue tracker — run it whenever reports pile up, to keep the queue sorted and the `ready-for-agent` column trustworthy. It sits at the front of the tracker, upstream of the build chain: the briefs it writes are what [tdd](https://aihero.dev/skills-tdd) later picks up to implement. When a request needs sharpening it leans on [grilling](https://aihero.dev/skills-grilling) and [domain-modeling](https://aihero.dev/skills-domain-modeling) to grill it into shape one question at a time. Its close neighbour is [to-prd](https://aihero.dev/skills-to-prd), which populates the tracker from a fresh conversation where `triage` processes what's already there. When you're unsure which skill or flow fits, [ask-matt](https://aihero.dev/skills-ask-matt) routes you.
|
`triage` is the **periodic maintenance** pass over your issue tracker — run it whenever reports pile up, to keep the queue sorted and the `ready-for-agent` column trustworthy. It sits at the front of the tracker, upstream of the build chain: the briefs it writes are what [tdd](https://aihero.dev/skills-tdd) later picks up to implement. When a request needs sharpening it leans on [grilling](https://aihero.dev/skills-grilling) and [domain-modeling](https://aihero.dev/skills-domain-modeling) to grill it into shape a round of questions at a time. Its close neighbour is [to-spec](https://aihero.dev/skills-to-spec), which populates the tracker from a fresh conversation where `triage` processes what's already there. When you're unsure which skill or flow fits, [ask-matt](https://aihero.dev/skills-ask-matt) routes you.
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
## What it does
|
||||||
|
|
||||||
|
`wayfinder` takes an effort too big for one agent session — wrapped in fog, where the way from here to the goal isn't visible yet — and charts it as a **shared map** of **decision tickets** on your issue tracker, then resolves them one at a time until the way is clear. It **plans, it doesn't do**: every ticket resolves a decision — a question to settle, not a slice of a build to execute — and the map is done when nothing is left to decide before someone goes and builds the thing — so it produces decisions, not deliverables.
|
||||||
|
|
||||||
|
## When to reach for it
|
||||||
|
|
||||||
|
You invoke this by typing `/wayfinder` — the agent won't reach for it on its own.
|
||||||
|
|
||||||
|
Reach for it when an effort is **more than one agent session can hold** and the route to its **destination** is still foggy — you can feel the shape of the work but can't yet write it down as a spec or a plan. For turning an *already-clear* thread into a spec, use [to-spec](https://aihero.dev/skills-to-spec); for slicing an already-understood plan into buildable tickets, use [to-tickets](https://aihero.dev/skills-to-tickets). Wayfinder sits upstream of both: it's what you run when there's too much fog to spec directly.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
The map and its tickets live on the repo's issue tracker, so wayfinder needs the tracker wiring that [setup-matt-pocock-skills](https://aihero.dev/skills-setup-matt-pocock-skills) lays down — it seeds a "Wayfinding operations" section describing how the map, child tickets, blocking, and frontier queries are expressed for GitHub, GitLab, or local-markdown. Absent that doc, wayfinder defaults to a local-markdown map.
|
||||||
|
|
||||||
|
## The map is an index, fog is the frontier
|
||||||
|
|
||||||
|
The **map** is a single `wayfinder:map` issue whose tickets are its child issues — one shared URL the whole team can watch. It's an **index, not a store**: each decision lives in exactly one place (its ticket), and the map only gists and links, never restates. A session loads the map at low resolution and zooms into individual tickets on demand.
|
||||||
|
|
||||||
|
Beyond the live tickets lies the **fog of war** — decisions you can tell are coming but can't yet pin down. The test for whether something is a ticket or still fog is whether you can *state the question precisely now*, not whether you can answer it. Resolving a ticket clears the fog ahead of it, **graduating** whatever's now specifiable into fresh tickets. The **frontier** is the open, unblocked, unclaimed tickets — the edge of the known — and it's what the tracker's native blocking renders visually, so you see what's takeable without opening the map. Fog only gathers *toward* the **destination**; work past it is ruled **out of scope**, closed, never graduating.
|
||||||
|
|
||||||
|
Every ticket is **HITL** (human in the loop — grilling, prototype) or **AFK** (agent alone — research); a HITL ticket only resolves through a live exchange, so the agent never answers its own questions. Research stays a real ticket — a shared blocker downstream decisions hang on — but because it's AFK, a session doesn't stop and read: it fires a `/research` **subagent** to burn the ticket down in parallel, keeping the frontier fast, and captures the findings on a throwaway `research/<name>` branch.
|
||||||
|
|
||||||
|
## It's working if
|
||||||
|
|
||||||
|
- Naming the **destination** is the first act — before any ticket exists — because it fixes the scope every ticket is measured against.
|
||||||
|
- One map is one `wayfinder:map` issue; tickets are its child issues, referred to by **name**, never a bare `#42`.
|
||||||
|
- A session resolves **at most one ticket** (research tickets excepted), records the answer as a resolution comment, closes the ticket, and appends a one-line pointer to *Decisions so far*.
|
||||||
|
- If the opening grill surfaces **no fog**, it stops and tells you the journey is small enough to skip the map.
|
||||||
|
|
||||||
|
## Where it fits
|
||||||
|
|
||||||
|
`wayfinder` is a big-idea **on-ramp**: an effort too large and foggy to spec in one sitting generates a cleared map of decisions, which then merges onto the main build flow. When the fog is pushed back and the way is clear, hand off to [to-spec](https://aihero.dev/skills-to-spec) to schedule the multi-session build (or, if the effort turned out small, implement directly). It leans on [grilling](https://aihero.dev/skills-grilling) and [domain-modeling](https://aihero.dev/skills-domain-modeling) to resolve individual tickets, and on [prototype](https://aihero.dev/skills-prototype) and [research](https://aihero.dev/skills-research) for the ticket types that need them. When you're unsure which skill or flow fits, [ask-matt](https://aihero.dev/skills-ask-matt) routes you.
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
## What it does
|
||||||
|
|
||||||
|
`wizard` generates an interactive bash script that walks a human, step by step, through a manual procedure that's tedious to do by hand and tedious to re-explain to an agent every time — wiring up third-party services, running a one-off migration, moving a project from state A to state B. It opens each URL, says what to click and copy, captures what comes back, and writes it where it belongs.
|
||||||
|
|
||||||
|
The UX is not yours to design. A [template](https://github.com/mattpocock/skills/blob/main/skills/engineering/wizard/template.sh) already solves it — progress with time-remaining, confirmation gates, cross-platform URL opening (WSL included), hidden entry for secrets, idempotent `.env` upserts, `gh secret` / `gh variable` writes, and a closing summary of anything it had to skip. Everything above the `STAGES` marker is a fixed library that is identical in every wizard and never hand-edited. Your job is only to scope the procedure and author its **stages**.
|
||||||
|
|
||||||
|
## When to reach for it
|
||||||
|
|
||||||
|
You invoke this by typing `/wizard` — the agent won't reach for it on its own.
|
||||||
|
|
||||||
|
Reach for this when the next thing blocking you is a human clicking through a dashboard: a new dev needs six services configured before the app boots, a migration needs someone to flip switches in the right order, or you're about to write those steps into a README that will rot. If the procedure is something the *agent* can just do, it should do it — a wizard is specifically for the steps only a human can take.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
None to generate one. The wizard it writes runs on bash, and reaches for `gh` when a stage sets a GitHub secret or variable — if `gh` is missing or unauthenticated, that stage degrades to a warning and the closing summary tells the human what to set by hand, rather than failing the run.
|
||||||
|
|
||||||
|
## Stages
|
||||||
|
|
||||||
|
A **stage** is the unit of authoring and the unit of attention: one focused task, one screen. The script clears between stages, so anything that doesn't fit is anything the human loses. You author them in dependency order and set an honest `TOTAL_STAGES` and `TOTAL_MINUTES`, which is what drives the time-remaining display — the estimate is a promise to the person running it.
|
||||||
|
|
||||||
|
Getting there is three steps of scoping before a line is written. The skill reads the repo first rather than asking cold — `.env*`, `docker-compose*`, framework config, and every `secrets.*` / `vars.*` reference in `.github/workflows/`, each of which is a value the wizard must produce — then shows you the ordered stage list to confirm, then maps each stage to the precise path a human follows ("Dashboard → Developers → API keys → Reveal test key → copy"). Where it doesn't know the current UI, it asks or checks the docs; it does not invent clicks that may not exist.
|
||||||
|
|
||||||
|
## Ephemeral by default
|
||||||
|
|
||||||
|
A wizard is built for one run — saved to a scratch or `scripts/` path, deleted when the job is done. Commit it only when it's a repeatable setup path that should live in the repo, in which case link it from the README so the next person runs the script instead of re-asking an agent.
|
||||||
|
|
||||||
|
It's also never run end-to-end by the agent that wrote it: it opens browsers and blocks on human input. Verification is static instead — `bash -n`, `shellcheck` where available, and a trace that every value lands where scoping said it would, with every `set_secret` name matching a real `secrets.*` reference in CI.
|
||||||
|
|
||||||
|
## It's working if
|
||||||
|
|
||||||
|
- You're shown an ordered list of stages and the values each produces, and asked to confirm, before any script exists.
|
||||||
|
- The generated file's library section is byte-identical to `template.sh` — only the block below the `STAGES` marker is yours.
|
||||||
|
- Every URL is opened before the value it produces is asked for, secrets use hidden entry, and irreversible actions sit behind a confirmation.
|
||||||
|
|
||||||
|
## Where it fits
|
||||||
|
|
||||||
|
`wizard` is a reach-for-it-anytime standalone, sitting where automation stops and a human has to click. Its nearest neighbour is [setup-matt-pocock-skills](https://aihero.dev/skills-setup-matt-pocock-skills), because both are run-once setup — that one configures this skill set for a repo, while `wizard` generates setup paths for everything else. It also pairs with [implement](https://aihero.dev/skills-implement): when a build lands a feature that needs credentials or a manual cutover, a wizard is how the human half gets done. When you're unsure which skill fits the moment, [ask-matt](https://aihero.dev/skills-ask-matt) routes you.
|
||||||
@@ -1,33 +1,76 @@
|
|||||||
Quickstart:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx skills add mattpocock/skills --skill=grill-me
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx skills update grill-me
|
|
||||||
```
|
|
||||||
|
|
||||||
[Source](https://github.com/mattpocock/skills/tree/main/skills/productivity/grill-me)
|
|
||||||
|
|
||||||
## What it does
|
## What it does
|
||||||
|
|
||||||
`grill-me` runs a relentless interview about a plan or design, walking every branch of the decision tree until you and the agent reach a **shared understanding**.
|
`grill-me` takes a **loose idea** and interviews you until it has real decisions in it. You do not need a worked-out plan to start — producing one is what the session is for. It asks in **rounds**: each round is the whole **frontier** — every question whose prerequisites you have already settled — so you are never asked something that hinges on an answer it hasn't heard yet.
|
||||||
|
|
||||||
It asks **one question at a time** and waits. It never dumps a batch of questions at you — that is bewildering — and where a question can be answered by reading the codebase, it goes and reads rather than asking. Each question comes with the agent's own recommended answer, so you are reacting to a proposal, not staring at a blank prompt.
|
It is **stateless**. It writes no files and leaves no workspace behind. The only thing it leaves is a sharper version of the idea, in your own head.
|
||||||
|
|
||||||
## When to reach for it
|
## When to reach for it
|
||||||
|
|
||||||
You invoke this by typing `/grill-me` — the agent won't reach for it on its own.
|
You invoke this by typing `/grill-me` — the agent won't reach for it on its own. Start it in a **fresh conversation**, not on top of a plan you already had an agent write.
|
||||||
|
|
||||||
Reach for it before you build, when a plan feels roughly right but you can sense unresolved decisions hiding in it — the moment you want the soft spots found and forced into the open. If you want that same interrogation to also leave a paper trail of ADRs and a glossary behind, use [grill-with-docs](https://aihero.dev/skills-grill-with-docs) instead.
|
Reach for it as soon as you have an idea worth taking seriously — a feature, a product direction, a business call, a piece of writing — and long before you have worked out what it involves. Vagueness is not a reason to wait; it is the thing the session eats. If you can already specify the thing precisely, you don't need to grill it.
|
||||||
|
|
||||||
## The design tree
|
Which of the three grilling skills you want depends on what is in front of you:
|
||||||
|
|
||||||
The session walks the plan as a tree of decisions, resolving dependencies between them one by one — a parent decision settled before the choices that hang off it. The point is not to reach agreement quickly; it is to make every implicit call explicit, so nothing important is left silently assumed. You come out the other side with a plan whose branches have all been visited.
|
- **Anything, anywhere** — `grill-me`. It needs no repo and writes no files, and the subject doesn't have to be code.
|
||||||
|
- **A codebase to align against** — [grill-with-docs](https://aihero.dev/skills-grill-with-docs). The same interview, but stateful: it reads your code and keeps what it learns in `CONTEXT.md` and ADRs.
|
||||||
|
- **Too big for one session** — [wayfinder](https://aihero.dev/skills-wayfinder). It charts the effort as a map and runs grilling sessions inside it.
|
||||||
|
|
||||||
`grill-me` is **stateless**: it writes nothing and leaves no workspace behind. It runs anywhere, and the only artifact is the sharpened understanding in the conversation itself. That is the deliberate contrast with [grill-with-docs](https://aihero.dev/skills-grill-with-docs), which captures the same interview as durable ADRs and a glossary.
|
Leave plan mode off. Plan mode primes the agent to rush toward producing a plan, which is the opposite of staying in inquiry.
|
||||||
|
|
||||||
|
## It's a conversation, not an interview
|
||||||
|
|
||||||
|
The skill asks the questions, but **you** own the scope. That is the part people miss, and it separates a session that turns an idea into decisions from one that produces confident nonsense.
|
||||||
|
|
||||||
|
The failure mode is **passivity** — answering "agreed, agreed, agreed" for forty questions and coming out with a plan the agent wrote and you nodded at. It feels productive because it was long. Nothing was actually decided, and the result carries a certainty it hasn't earned.
|
||||||
|
|
||||||
|
Being active means steering. Push back on a question pitched beneath the fidelity you need. Say when the scope is drifting. Answer "I don't know" and mean it. This skill is built to aid an engineer, not to replace one: what comes out tracks the quality of your answers, not the number of questions asked.
|
||||||
|
|
||||||
|
The opposite error is real but rarer — staying in the interview so long you never reach code.
|
||||||
|
|
||||||
|
## Grillable and ungrillable
|
||||||
|
|
||||||
|
Some questions can be answered by talking. Others can't, and no amount of grilling will get you there.
|
||||||
|
|
||||||
|
"One long form or three pages?" and "how should this interaction feel?" are **ungrillable** — they need something to react to. When you hit one, stop grilling. Build the throwaway version with [prototype](https://aihero.dev/skills-prototype), look at it, then come back and answer in one line.
|
||||||
|
|
||||||
|
Talking your way through an ungrillable question is where sessions balloon. The agent keeps rephrasing, you keep guessing, and the scope grows to fill the uncertainty.
|
||||||
|
|
||||||
|
## It's working if
|
||||||
|
|
||||||
|
- You disagree with something. A session with no pushback from you is a session you didn't need.
|
||||||
|
- Questions arrive in a few rounds rather than one long drip, and later rounds clearly build on what you said earlier.
|
||||||
|
- You end up somewhere you didn't expect, because a question surfaced a decision you had been making implicitly.
|
||||||
|
- At the end you could defend each choice to someone who wasn't there.
|
||||||
|
|
||||||
|
## Common questions
|
||||||
|
|
||||||
|
**How many questions should I expect, and how do I know when it ends?**
|
||||||
|
Count rounds, not questions. Forty-six questions across four rounds is an ordinary session. It ends when the frontier is empty — every branch visited, nothing left silently assumed.
|
||||||
|
|
||||||
|
**It asked me two hundred questions. What went wrong?**
|
||||||
|
Usually the scope was too large. Ask the agent to break the work into smaller pieces first, then grill each one. Very long sessions also drift into the **dumb zone**, where the context window is full enough that the questions get worse.
|
||||||
|
|
||||||
|
**Can I go back to one question at a time?**
|
||||||
|
Yes. Add this to your global `CLAUDE.md`:
|
||||||
|
|
||||||
|
```
|
||||||
|
When grilling, ask one question at a time.
|
||||||
|
```
|
||||||
|
|
||||||
|
**What if I genuinely don't know the answer?**
|
||||||
|
Say so. "I don't know" is a real answer, and a question you can't answer is usually a sign to prototype rather than to guess.
|
||||||
|
|
||||||
|
**Do I start a fresh session before writing the spec?**
|
||||||
|
No. The value of the session is the context you just built. Hand the same conversation straight to [to-spec](https://aihero.dev/skills-to-spec).
|
||||||
|
|
||||||
|
**Does the model matter?**
|
||||||
|
More than for most skills. Grilling leans on the model's own sense of how systems break, so give it your best one. Implementation mostly follows context and tolerates a cheaper model.
|
||||||
|
|
||||||
## Where it fits
|
## Where it fits
|
||||||
|
|
||||||
`grill-me` is a reach-for-it-anytime standalone — the pre-build stress test you run whenever a plan needs hardening. It is the stateless, user-invoked front door to the [grilling](https://aihero.dev/skills-grilling) primitive; its closest neighbour is [grill-with-docs](https://aihero.dev/skills-grill-with-docs), the stateful sibling that runs the same interview but additionally records the decisions as ADRs and a glossary. If the outcome is a spec you want written down, hand off to [to-prd](https://aihero.dev/skills-to-prd), which synthesises the settled understanding into a PRD without re-interviewing you. When you're unsure which flow fits, [ask-matt](https://aihero.dev/skills-ask-matt) routes you.
|
`grill-me` is a **standalone you can run anywhere, on anything**. Being stateless is what makes it portable: no repo, no workspace, no setup, and no assumption that the idea is even about software. People point it at business decisions, at writing, at what to do next — anything that won't sit still in their head.
|
||||||
|
|
||||||
|
That portability is the whole difference from [grill-with-docs](https://aihero.dev/skills-grill-with-docs), which runs the same interview but reads a codebase to align against and records what it learns as `CONTEXT.md` and ADRs. Both sit on the [grilling](https://aihero.dev/skills-grilling) primitive; `grill-me` is the user-invoked front door that carries nothing with it.
|
||||||
|
|
||||||
|
If what you grilled does turn out to be software, you can hand the same conversation to [to-spec](https://aihero.dev/skills-to-spec) and carry on into the build flow — an option, not the point of the skill. When you're unsure which flow fits, [ask-matt](https://aihero.dev/skills-ask-matt) routes you.
|
||||||
|
|||||||
@@ -1,20 +1,16 @@
|
|||||||
Quickstart:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx skills add mattpocock/skills --skill=grilling
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx skills update grilling
|
|
||||||
```
|
|
||||||
|
|
||||||
[Source](https://github.com/mattpocock/skills/tree/main/skills/productivity/grilling)
|
|
||||||
|
|
||||||
## What it does
|
## What it does
|
||||||
|
|
||||||
`grilling` is the relentless interview that stress-tests a plan or design before you build it. It walks down the design tree branch by branch, resolving the dependencies between decisions one at a time until you and the agent share the same understanding.
|
`grilling` is the relentless interview that stress-tests a plan or design before you build it. It maps the plan as a **design tree** — every decision branches into the decisions that hang off it — and works that tree in **rounds** until you and the agent share the same understanding.
|
||||||
|
|
||||||
It asks **one question at a time** and waits for your answer before the next — never a bulk list, which is bewildering. Each question comes with the agent's own recommended answer, and any question the codebase can settle it explores instead of asking you.
|
Each round asks the whole **frontier**: every decision whose prerequisites are already settled — the questions it can put to you *now* without guessing at answers it hasn't heard yet. Your answers reshape the tree, pushing the frontier outward, and the next round asks whatever that unblocks. Thirteen questions land in a handful of rounds instead of thirteen. Every question arrives in a fixed shape — numbered and titled behind a `❓` (`❓ **Q1** - **Storage backend**`), then the body, then the agent's recommendation on its own `➡️` line — so a round reads as a scannable list and you can answer it by number rather than by quoting it back; any *fact* the environment can settle it dispatches to a background sub-agent rather than asking you — and it doesn't block on that research, only the questions downstream of it wait. It won't act on the plan until you confirm the shared understanding has been reached.
|
||||||
|
|
||||||
|
### Prefer one question at a time?
|
||||||
|
|
||||||
|
If the old one-at-a-time rhythm suited you better, keep it. Add a line to your global `CLAUDE.md`:
|
||||||
|
|
||||||
|
```
|
||||||
|
When grilling, ask one question at a time.
|
||||||
|
```
|
||||||
|
|
||||||
## When to reach for it
|
## When to reach for it
|
||||||
|
|
||||||
@@ -22,9 +18,9 @@ Type `/grilling`, or the agent reaches for it automatically when a task fits —
|
|||||||
|
|
||||||
Reach for it when a plan or design still has soft spots and you want them surfaced before code is written. In practice you usually invoke it through one of its two wrappers rather than by name: for a plain grilling session use [grill-me](https://aihero.dev/skills-grill-me); to have the session also write ADRs and a glossary as it goes, use [grill-with-docs](https://aihero.dev/skills-grill-with-docs).
|
Reach for it when a plan or design still has soft spots and you want them surfaced before code is written. In practice you usually invoke it through one of its two wrappers rather than by name: for a plain grilling session use [grill-me](https://aihero.dev/skills-grill-me); to have the session also write ADRs and a glossary as it goes, use [grill-with-docs](https://aihero.dev/skills-grill-with-docs).
|
||||||
|
|
||||||
## The design tree
|
## The decision tree
|
||||||
|
|
||||||
The mental model is a **design tree**: every plan branches into decisions, and decisions depend on each other. `grilling` descends that tree one node at a time, so an early answer can reshape which questions come next. That is why the questions arrive singly and in dependency order — a firehose of parallel questions loses the structure that makes the interview converge on a shared understanding.
|
The mental model is a **design tree**: every plan branches into decisions, and decisions depend on each other. The **frontier** is the set of decisions whose prerequisites are all settled — the only questions that can be asked without guessing. `grilling` asks the whole frontier at once, then recomputes it from your answers, so a round is exactly the batch of questions that *don't* depend on each other. A question whose answer hinges on another still open this round waits for a later round. Asking in frontier-sized rounds keeps the dependency structure intact while sparing you a question-at-a-time drip.
|
||||||
|
|
||||||
## Pulled out on purpose
|
## Pulled out on purpose
|
||||||
|
|
||||||
@@ -34,4 +30,4 @@ Keeping the technique in one place means you can also reach for it directly when
|
|||||||
|
|
||||||
## Where it fits
|
## Where it fits
|
||||||
|
|
||||||
`grilling` is the interview **primitive** under the main build chain: [grill-with-docs](https://aihero.dev/skills-grill-with-docs) runs it to sharpen context before [to-prd](https://aihero.dev/skills-to-prd) writes the spec. When you're unsure which entry point fits, [ask-matt](https://aihero.dev/skills-ask-matt) routes you.
|
`grilling` is the interview **primitive** under the main build chain: [grill-with-docs](https://aihero.dev/skills-grill-with-docs) runs it to sharpen context before [to-spec](https://aihero.dev/skills-to-spec) writes the spec. When you're unsure which entry point fits, [ask-matt](https://aihero.dev/skills-ask-matt) routes you.
|
||||||
|
|||||||
@@ -1,20 +1,8 @@
|
|||||||
Quickstart:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx skills add mattpocock/skills --skill=handoff
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx skills update handoff
|
|
||||||
```
|
|
||||||
|
|
||||||
[Source](https://github.com/mattpocock/skills/tree/main/skills/productivity/handoff)
|
|
||||||
|
|
||||||
## What it does
|
## What it does
|
||||||
|
|
||||||
`handoff` compacts the current conversation into a **handoff document** — a single write-up a fresh agent can read to pick up the work where you left off.
|
`handoff` compacts the current conversation into a **handoff document** — a single write-up a fresh agent can read to pick up the work where you left off.
|
||||||
|
|
||||||
It does **not** re-state what already lives elsewhere. Anything captured in a PRD, plan, ADR, issue, commit, or diff is referenced by path or URL, never copied. The document carries only the live thread — what you were doing, why, and what's next — and it's saved to your OS's temporary directory, not into the workspace, so it never becomes another artifact to maintain.
|
It does **not** re-state what already lives elsewhere. Anything captured in a spec, plan, ADR, issue, commit, or diff is referenced by path or URL, never copied. The document carries only the live thread — what you were doing, why, and what's next — and it's saved to your OS's temporary directory, not into the workspace, so it never becomes another artifact to maintain.
|
||||||
|
|
||||||
## When to reach for it
|
## When to reach for it
|
||||||
|
|
||||||
@@ -26,11 +14,11 @@ Reach for this when a conversation has gone long enough that its context is at r
|
|||||||
|
|
||||||
- **The live thread** — what's in flight and why, in the conversation's own terms, minus anything already written down elsewhere.
|
- **The live thread** — what's in flight and why, in the conversation's own terms, minus anything already written down elsewhere.
|
||||||
- **Suggested skills** — a pointer to the skills the next agent should reach for to continue.
|
- **Suggested skills** — a pointer to the skills the next agent should reach for to continue.
|
||||||
- **References, not copies** — links and paths to the PRDs, plans, ADRs, issues, and diffs that hold the settled detail.
|
- **References, not copies** — links and paths to the specs, plans, ADRs, issues, and diffs that hold the settled detail.
|
||||||
- **Redacted secrets** — API keys, passwords, and PII stripped before the document is written.
|
- **Redacted secrets** — API keys, passwords, and PII stripped before the document is written.
|
||||||
|
|
||||||
The idea to hold onto is **compaction**: a handoff is the conversation squeezed down to just its resumable core, so a fresh agent inherits the momentum, not the noise.
|
The idea to hold onto is **compaction**: a handoff is the conversation squeezed down to just its resumable core, so a fresh agent inherits the momentum, not the noise.
|
||||||
|
|
||||||
## Where it fits
|
## Where it fits
|
||||||
|
|
||||||
`handoff` is a reach-for-it-anytime standalone — it sits at the seam between two sessions rather than inside a build chain. It pairs naturally with the artifact-producing skills whose output it points at: [to-prd](https://aihero.dev/skills-to-prd), because a finished PRD is exactly the kind of settled detail a handoff references instead of repeating. When you're unsure which skill fits the moment, [ask-matt](https://aihero.dev/skills-ask-matt) routes you.
|
`handoff` is a reach-for-it-anytime standalone — it sits at the seam between two sessions rather than inside a build chain. It pairs naturally with the artifact-producing skills whose output it points at: [to-spec](https://aihero.dev/skills-to-spec), because a finished spec is exactly the kind of settled detail a handoff references instead of repeating. When you're unsure which skill fits the moment, [ask-matt](https://aihero.dev/skills-ask-matt) routes you.
|
||||||
|
|||||||
@@ -1,15 +1,3 @@
|
|||||||
Quickstart:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx skills add mattpocock/skills --skill=teach
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx skills update teach
|
|
||||||
```
|
|
||||||
|
|
||||||
[Source](https://github.com/mattpocock/skills/tree/main/skills/productivity/teach)
|
|
||||||
|
|
||||||
## What it does
|
## What it does
|
||||||
|
|
||||||
`teach` turns the current directory into a standing teaching workspace and teaches you one topic across many sessions — devising short, beautiful, interactive lessons tied to *why* you want to learn.
|
`teach` turns the current directory into a standing teaching workspace and teaches you one topic across many sessions — devising short, beautiful, interactive lessons tied to *why* you want to learn.
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
## What it does
|
||||||
|
|
||||||
|
`to-questionnaire` turns a decision you can't settle on your own into a **questionnaire** — a Markdown document you hand to the one person who holds what you're missing, to fill in async or work through together in a meeting.
|
||||||
|
|
||||||
|
It grills you about the **send**, never the subject. A normal grilling session interrogates the topic, which is exactly what you can't answer here — that's why you're writing to someone else. So the interview asks only the two things you can always answer: who this is going to, and what you need back from them. The questions in the document are then aimed at the **gap** between the two.
|
||||||
|
|
||||||
|
## When to reach for it
|
||||||
|
|
||||||
|
You invoke this by typing `/to-questionnaire` — the agent won't reach for it on its own.
|
||||||
|
|
||||||
|
Reach for this when a decision is blocked on knowledge that lives in someone else's head — a client, a domain expert, a colleague on another team — and you want a document that pulls it out of them in one pass. When the knowledge is in *your* head and just needs sharpening, use [grill-me](https://aihero.dev/skills-grill-me) instead; when it's in the codebase, use [grill-with-docs](https://aihero.dev/skills-grill-with-docs).
|
||||||
|
|
||||||
|
## The send, not the subject
|
||||||
|
|
||||||
|
The interview is two exchanges, and it stops there:
|
||||||
|
|
||||||
|
- **Who is it going to?** Their role, expertise, and relationship to you. This fixes the tone and how much context the document has to carry — an outside client needs orienting; a teammate does not.
|
||||||
|
- **What do you need back?** The concrete decisions or facts you can't resolve alone. This becomes the checklist the finished questionnaire is measured against: every item you named has a question aimed at it.
|
||||||
|
|
||||||
|
Everything after that is drafting. The output is written to `to-questionnaire-<slug>.md` in the current directory.
|
||||||
|
|
||||||
|
## The document
|
||||||
|
|
||||||
|
It's a **discovery questionnaire**: you lack the context, the recipient holds it. That framing drives its shape — a purpose line and the decision riding on it, a short context section for a recipient who wasn't in your head, and questions ordered **most-important-first**, because async means you may only get one pass. Each question is one idea, never compound, with an answer stub beneath it and a *why this matters* line only where the question could be misread. It closes with a catch-all: anything we didn't ask that we should know?
|
||||||
|
|
||||||
|
## It's working if
|
||||||
|
|
||||||
|
- It asks you about the recipient and the deliverable, then stops asking — no interrogation of the topic itself.
|
||||||
|
- Every item you named as "what I need back" is traceable to a question in the file.
|
||||||
|
- The questions read as aimed at what the *recipient* knows, not as your own open questions copied down.
|
||||||
|
|
||||||
|
## Where it fits
|
||||||
|
|
||||||
|
`to-questionnaire` is a reach-for-it-anytime standalone — it sits at the boundary of your own knowledge, where the next step is another person rather than another skill. Its neighbour is [grill-me](https://aihero.dev/skills-grill-me), because the two split on where the answers live: grilling mines you, a questionnaire mines someone else. What comes back typically feeds the main flow at [grill-with-docs](https://aihero.dev/skills-grill-with-docs) or [to-spec](https://aihero.dev/skills-to-spec). When you're unsure which skill fits the moment, [ask-matt](https://aihero.dev/skills-ask-matt) routes you.
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
## What it does
|
||||||
|
|
||||||
|
`wait-what` is the fire extinguisher for a message that didn't land. You fire it the moment you lose the thread, and the agent re-pitches what it just said: a little of the context you were missing, plain English, and the vocabulary from your project's `CONTEXT.md`.
|
||||||
|
|
||||||
|
It is three lines long, and that is the design rather than an unfinished draft. Skills that fight verbosity fail by growing — a four-hundred-line concision skill still leaves the model verbose, because the model reads the volume, not the plea. This one carries a single precise leading word and nothing else.
|
||||||
|
|
||||||
|
## When to reach for it
|
||||||
|
|
||||||
|
You invoke this by typing `/wait-what` — the agent won't reach for it on its own, and it shouldn't: only you know when you stopped following.
|
||||||
|
|
||||||
|
Reach for it the second you notice you're skimming — the agent has drifted into jargon it invented, stacked five acronyms, or explained a decision whose premise you never saw. It's a one-shot corrective on the conversation you're already in. To stop the jargon arriving in the first place, use [grill-with-docs](https://aihero.dev/skills-grill-with-docs) instead, which builds the shared language upfront.
|
||||||
|
|
||||||
|
## The name is the mechanism
|
||||||
|
|
||||||
|
The leading word is **wait**. Not "be concise" — an instruction about the agent's output, which the model satisfies by clipping words and losing you further. **Wait** is about *your* state: it says comprehension failed here. An agent that hears "be brief" writes telegrams. An agent that hears "wait, you lost me" backs up and explains.
|
||||||
|
|
||||||
|
That distinction is the whole skill. Every popular fix for verbosity — `/tldr`, `/no-fluff`, `/talk-normal` — names the *output*, so the model over-corrects into a caveman register that's shorter and no clearer. Naming the *listener* asks for both halves at once: fewer words **and** the context you were missing.
|
||||||
|
|
||||||
|
The re-pitch is deliberately vague about its own scope. It says re-pitch **that**, not "that last message", because what lost you is usually bigger than one paragraph — the agent decides how far back to go.
|
||||||
|
|
||||||
|
## It plugs into the language you already have
|
||||||
|
|
||||||
|
The body reuses the leading words already sitting in your global `CLAUDE.md` and your project's `CONTEXT.md`: ASD-STE100 Simplified Technical English for the register, ubiquitous language for the nouns. Skill, `CLAUDE.md` and `CONTEXT.md` reach for the same tokens, so firing it isn't a new instruction — it's a reminder of one the agent already agreed to.
|
||||||
|
|
||||||
|
If you have no `CONTEXT.md`, it still works; you just lose the domain-vocabulary half.
|
||||||
|
|
||||||
|
## It's working if
|
||||||
|
|
||||||
|
- The re-pitch is **shorter and clearer**, not shorter and blunter.
|
||||||
|
- It adds the premise you were missing rather than just deleting words.
|
||||||
|
- Project nouns replace invented ones — the terms in your `CONTEXT.md` come back.
|
||||||
|
- You can fire it twice in a row without it degrading into terseness.
|
||||||
|
|
||||||
|
## Where it fits
|
||||||
|
|
||||||
|
`wait-what` is a reach-for-it-anytime standalone — it sits inside whatever conversation you're already having, in any skill, at any point. It's the extinguisher; [grill-with-docs](https://aihero.dev/skills-grill-with-docs) is the sprinkler system, because a shared language agreed upfront is the real cure for jargon, and [domain-modeling](https://aihero.dev/skills-domain-modeling) is what you reach for when the *words themselves* are the problem rather than one bad message. When you're unsure which skill fits the moment, [ask-matt](https://aihero.dev/skills-ask-matt) routes you.
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
## What it does
|
||||||
|
|
||||||
|
`writing-for-agents` is the reference you write agent-facing documents against — skills, `AGENTS.md` / `CLAUDE.md`, and any doc an agent reaches by a pointer. The packaging differs; the writing does not: the same levers make each one predictable, so the agent takes the same *process* every run rather than producing the same output.
|
||||||
|
|
||||||
|
Formerly `writing-great-skills`. The rename tracks what the reference always was underneath: almost none of it is skill-specific. The universal core — context pointers, the two loads, the information hierarchy, completion criteria, leading words, pruning — applies to any document an agent consumes; the genuinely skill-only mechanics (frontmatter, the model- vs user-invoked choice, router skills) are disclosed to a linked `SKILL-MECHANICS.md` you read only when the document you're writing is a skill.
|
||||||
|
|
||||||
|
## When to reach for it
|
||||||
|
|
||||||
|
The agent reaches for it on its own whenever you're creating or editing a skill, or modifying `AGENTS.md` or `CLAUDE.md` — and you can still type `/writing-for-agents` to pull it up directly.
|
||||||
|
|
||||||
|
## The two loads
|
||||||
|
|
||||||
|
The concept the whole reference turns on is a pair of budgets every document and pointer spends:
|
||||||
|
|
||||||
|
- **Context load** — the cost of always-loaded material on the agent's window: an `AGENTS.md` line, a skill description, anything sitting in context every turn whether or not it fires.
|
||||||
|
- **Cognitive load** — the cost on the human: which documents exist and when to reach for each. You are the index. Not a cost to minimise — it's the price of human agency.
|
||||||
|
|
||||||
|
Once you're thinking in these two loads, most authoring decisions — split or don't, inline or disclose, point or push — become the same trade made in different places.
|
||||||
|
|
||||||
|
## The other levers
|
||||||
|
|
||||||
|
- **Context pointers** — the reference held in context that names out-of-context material and encodes when to reach it. A skill description and an `AGENTS.md` line pointing at a doc are the same object; the pointer's *wording*, not its target, decides when and how reliably the agent reaches through it.
|
||||||
|
- **Information hierarchy** — the ladder from in-file step, to in-file reference, to disclosed reference behind a pointer. **Progressive disclosure** is the move down that ladder so the top stays legible; **co-location** decides what sits beside each piece once placed.
|
||||||
|
- **Completion criteria** — the clarity and demand of each step's done-condition, and the **legwork** it drives; the defence against **premature completion**.
|
||||||
|
- **Leading words** — a compact concept already in the model's pretraining (*tight*, *red*, *tracer bullet*) that the agent thinks with while running the document; hunt restatements a single word can retire.
|
||||||
|
- **Pruning** — single source of truth, relevance, and the no-op test applied sentence by sentence, against **sediment** and **sprawl**. Single source of truth reaches past the document into the environment: a doc restating what's already in `package.json`, a config file, or `--help` output is a **cache** of a lookup that was never expensive, and it's the copy that goes stale. Cache what the agent can't find by looking — the unwritten convention, the reason behind a choice.
|
||||||
|
|
||||||
|
## Where it fits
|
||||||
|
|
||||||
|
This is a reach-for-it-anytime standalone reference — the meta-skill you consult while building the rest of the set, not a step in a chain. When you're unsure which skill or flow fits a task, [ask-matt](https://aihero.dev/skills-ask-matt) routes you over the whole set.
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
Quickstart:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx skills add mattpocock/skills --skill=writing-great-skills
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx skills update writing-great-skills
|
|
||||||
```
|
|
||||||
|
|
||||||
[Source](https://github.com/mattpocock/skills/tree/main/skills/productivity/writing-great-skills)
|
|
||||||
|
|
||||||
## What it does
|
|
||||||
|
|
||||||
`writing-great-skills` is the reference you write and edit skills against — the shared vocabulary and principles that make a skill predictable.
|
|
||||||
|
|
||||||
A skill's job is to wrangle determinism out of a stochastic system, so the goal is not the same *output* every run but the same *process*. **Predictability** is the root virtue, and every design choice is judged against it — not against how clever, complete, or exhaustive the skill reads.
|
|
||||||
|
|
||||||
## When to reach for it
|
|
||||||
|
|
||||||
You invoke this by typing `/writing-great-skills` — the agent won't reach for it on its own.
|
|
||||||
|
|
||||||
Reach for it whenever you're authoring a new skill or editing an existing one and want it to behave the same way every time: deciding invocation mode, writing a description, choosing what lives in `SKILL.md` versus a linked file, or diagnosing why a skill misfires.
|
|
||||||
|
|
||||||
## Cognitive load
|
|
||||||
|
|
||||||
The concept the whole reference turns on is **cognitive load** — and its counterpart, **context load**. Every skill spends one or the other:
|
|
||||||
|
|
||||||
- A **model-invoked** skill keeps a description in the window every turn, so it costs **context load** but fires on its own.
|
|
||||||
- A **user-invoked** skill strips that description; it costs zero context load, but now *you* are the index that has to remember it exists — that's **cognitive load**.
|
|
||||||
|
|
||||||
Most of these skills are user-invoked, which is why cognitive load is the pressure the whole system is built to manage: when user-invoked skills multiply past what you can hold in your head, the cure is a **router skill** that names the others and when to reach for each. Once you're thinking in these two loads, most authoring decisions — split or don't, inline or disclose, model- or user-invoked — become the same trade made in different places.
|
|
||||||
|
|
||||||
## The other levers
|
|
||||||
|
|
||||||
The rest of the reference is the toolkit for spending those loads well:
|
|
||||||
|
|
||||||
- **Leading words** — a compact concept already in the model's pretraining (_tight_, _red_, _tracer bullet_) that the agent thinks with while running the skill. It anchors execution *and* invocation in the fewest tokens; hunt restatements that a single word can retire.
|
|
||||||
- **Information hierarchy** — the ladder from in-skill step, to in-skill reference, to external reference behind a **context pointer**. **Progressive disclosure** is the move down that ladder so the top stays legible.
|
|
||||||
- **Pruning** — single source of truth, relevance, and the no-op test applied sentence by sentence, against **sediment** and **sprawl**.
|
|
||||||
- **Failure modes** — **premature completion**, **duplication**, **sediment**, **sprawl**, **no-op** — to diagnose a skill that isn't behaving.
|
|
||||||
|
|
||||||
## Where it fits
|
|
||||||
|
|
||||||
This is a reach-for-it-anytime standalone reference — the meta-skill you consult while building the rest of the set, not a step in a chain. Its natural neighbour is any router you maintain, because a router is the direct cure for the cognitive load that user-invoked skills pile up; when you're unsure which skill or flow fits a task, [ask-matt](https://aihero.dev/skills-ask-matt) routes you over the whole set.
|
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "mattpocock-skills",
|
"name": "mattpocock-skills",
|
||||||
"version": "1.0.1",
|
"version": "1.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"description": "Matt Pocock's agent skills for real engineering",
|
"description": "Matt Pocock's agent skills for real engineering",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ set -euo pipefail
|
|||||||
# Links all skills in the repository into the local skill directories used by
|
# Links all skills in the repository into the local skill directories used by
|
||||||
# each agent harness:
|
# each agent harness:
|
||||||
# - ~/.claude/skills — Claude Code
|
# - ~/.claude/skills — Claude Code
|
||||||
# - ~/.agents/skills — pi and other Agent-Skills-standard harnesses
|
# - ~/.agents/skills — Codex and other Agent Skills-compatible harnesses
|
||||||
# Each entry is a symlink into this repo, so a `git pull` is all that's needed
|
# Each entry is a symlink into this repo, so a `git pull` is all that's needed
|
||||||
# to keep installed skills up to date.
|
# to keep installed skills up to date.
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,3 @@
|
|||||||
# Deprecated
|
# Deprecated
|
||||||
|
|
||||||
Skills I no longer use.
|
Skills I no longer use. This bucket is currently empty — a retired skill is deleted, and the changeset that removes it names whatever replaced it.
|
||||||
|
|
||||||
- **[design-an-interface](./design-an-interface/SKILL.md)** — Generate multiple radically different interface designs for a module using parallel sub-agents.
|
|
||||||
- **[qa](./qa/SKILL.md)** — Interactive QA session where user reports bugs conversationally and the agent files GitHub issues.
|
|
||||||
- **[request-refactor-plan](./request-refactor-plan/SKILL.md)** — Create a detailed refactor plan with tiny commits via user interview, then file it as a GitHub issue.
|
|
||||||
- **[ubiquitous-language](./ubiquitous-language/SKILL.md)** — Extract a DDD-style ubiquitous language glossary from the current conversation.
|
|
||||||
|
|||||||
@@ -1,94 +0,0 @@
|
|||||||
---
|
|
||||||
name: design-an-interface
|
|
||||||
description: Generate multiple radically different interface designs for a module using parallel sub-agents. Use when user wants to design an API, explore interface options, compare module shapes, or mentions "design it twice".
|
|
||||||
---
|
|
||||||
|
|
||||||
# Design an Interface
|
|
||||||
|
|
||||||
Based on "Design It Twice" from "A Philosophy of Software Design": your first idea is unlikely to be the best. Generate multiple radically different designs, then compare.
|
|
||||||
|
|
||||||
## Workflow
|
|
||||||
|
|
||||||
### 1. Gather Requirements
|
|
||||||
|
|
||||||
Before designing, understand:
|
|
||||||
|
|
||||||
- [ ] What problem does this module solve?
|
|
||||||
- [ ] Who are the callers? (other modules, external users, tests)
|
|
||||||
- [ ] What are the key operations?
|
|
||||||
- [ ] Any constraints? (performance, compatibility, existing patterns)
|
|
||||||
- [ ] What should be hidden inside vs exposed?
|
|
||||||
|
|
||||||
Ask: "What does this module need to do? Who will use it?"
|
|
||||||
|
|
||||||
### 2. Generate Designs (Parallel Sub-Agents)
|
|
||||||
|
|
||||||
Spawn 3+ sub-agents simultaneously using Task tool. Each must produce a **radically different** approach.
|
|
||||||
|
|
||||||
```
|
|
||||||
Prompt template for each sub-agent:
|
|
||||||
|
|
||||||
Design an interface for: [module description]
|
|
||||||
|
|
||||||
Requirements: [gathered requirements]
|
|
||||||
|
|
||||||
Constraints for this design: [assign a different constraint to each agent]
|
|
||||||
- Agent 1: "Minimize method count - aim for 1-3 methods max"
|
|
||||||
- Agent 2: "Maximize flexibility - support many use cases"
|
|
||||||
- Agent 3: "Optimize for the most common case"
|
|
||||||
- Agent 4: "Take inspiration from [specific paradigm/library]"
|
|
||||||
|
|
||||||
Output format:
|
|
||||||
1. Interface signature (types/methods)
|
|
||||||
2. Usage example (how caller uses it)
|
|
||||||
3. What this design hides internally
|
|
||||||
4. Trade-offs of this approach
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Present Designs
|
|
||||||
|
|
||||||
Show each design with:
|
|
||||||
|
|
||||||
1. **Interface signature** - types, methods, params
|
|
||||||
2. **Usage examples** - how callers actually use it in practice
|
|
||||||
3. **What it hides** - complexity kept internal
|
|
||||||
|
|
||||||
Present designs sequentially so user can absorb each approach before comparison.
|
|
||||||
|
|
||||||
### 4. Compare Designs
|
|
||||||
|
|
||||||
After showing all designs, compare them on:
|
|
||||||
|
|
||||||
- **Interface simplicity**: fewer methods, simpler params
|
|
||||||
- **General-purpose vs specialized**: flexibility vs focus
|
|
||||||
- **Implementation efficiency**: does shape allow efficient internals?
|
|
||||||
- **Depth**: small interface hiding significant complexity (good) vs large interface with thin implementation (bad)
|
|
||||||
- **Ease of correct use** vs **ease of misuse**
|
|
||||||
|
|
||||||
Discuss trade-offs in prose, not tables. Highlight where designs diverge most.
|
|
||||||
|
|
||||||
### 5. Synthesize
|
|
||||||
|
|
||||||
Often the best design combines insights from multiple options. Ask:
|
|
||||||
|
|
||||||
- "Which design best fits your primary use case?"
|
|
||||||
- "Any elements from other designs worth incorporating?"
|
|
||||||
|
|
||||||
## Evaluation Criteria
|
|
||||||
|
|
||||||
From "A Philosophy of Software Design":
|
|
||||||
|
|
||||||
**Interface simplicity**: Fewer methods, simpler params = easier to learn and use correctly.
|
|
||||||
|
|
||||||
**General-purpose**: Can handle future use cases without changes. But beware over-generalization.
|
|
||||||
|
|
||||||
**Implementation efficiency**: Does interface shape allow efficient implementation? Or force awkward internals?
|
|
||||||
|
|
||||||
**Depth**: Small interface hiding significant complexity = deep module (good). Large interface with thin implementation = shallow module (avoid).
|
|
||||||
|
|
||||||
## Anti-Patterns
|
|
||||||
|
|
||||||
- Don't let sub-agents produce similar designs - enforce radical difference
|
|
||||||
- Don't skip comparison - the value is in contrast
|
|
||||||
- Don't implement - this is purely about interface shape
|
|
||||||
- Don't evaluate based on implementation effort
|
|
||||||
@@ -1,130 +0,0 @@
|
|||||||
---
|
|
||||||
name: qa
|
|
||||||
description: Interactive QA session where user reports bugs or issues conversationally, and the agent files GitHub issues. Explores the codebase in the background for context and domain language. Use when user wants to report bugs, do QA, file issues conversationally, or mentions "QA session".
|
|
||||||
---
|
|
||||||
|
|
||||||
# QA Session
|
|
||||||
|
|
||||||
Run an interactive QA session. The user describes problems they're encountering. You clarify, explore the codebase for context, and file GitHub issues that are durable, user-focused, and use the project's domain language.
|
|
||||||
|
|
||||||
## For each issue the user raises
|
|
||||||
|
|
||||||
### 1. Listen and lightly clarify
|
|
||||||
|
|
||||||
Let the user describe the problem in their own words. Ask **at most 2-3 short clarifying questions** focused on:
|
|
||||||
|
|
||||||
- What they expected vs what actually happened
|
|
||||||
- Steps to reproduce (if not obvious)
|
|
||||||
- Whether it's consistent or intermittent
|
|
||||||
|
|
||||||
Do NOT over-interview. If the description is clear enough to file, move on.
|
|
||||||
|
|
||||||
### 2. Explore the codebase in the background
|
|
||||||
|
|
||||||
While talking to the user, kick off an Agent (subagent_type=Explore) in the background to understand the relevant area. The goal is NOT to find a fix — it's to:
|
|
||||||
|
|
||||||
- Learn the domain language used in that area (check UBIQUITOUS_LANGUAGE.md)
|
|
||||||
- Understand what the feature is supposed to do
|
|
||||||
- Identify the user-facing behavior boundary
|
|
||||||
|
|
||||||
This context helps you write a better issue — but the issue itself should NOT reference specific files, line numbers, or internal implementation details.
|
|
||||||
|
|
||||||
### 3. Assess scope: single issue or breakdown?
|
|
||||||
|
|
||||||
Before filing, decide whether this is a **single issue** or needs to be **broken down** into multiple issues.
|
|
||||||
|
|
||||||
Break down when:
|
|
||||||
|
|
||||||
- The fix spans multiple independent areas (e.g. "the form validation is wrong AND the success message is missing AND the redirect is broken")
|
|
||||||
- There are clearly separable concerns that different people could work on in parallel
|
|
||||||
- The user describes something that has multiple distinct failure modes or symptoms
|
|
||||||
|
|
||||||
Keep as a single issue when:
|
|
||||||
|
|
||||||
- It's one behavior that's wrong in one place
|
|
||||||
- The symptoms are all caused by the same root behavior
|
|
||||||
|
|
||||||
### 4. File the GitHub issue(s)
|
|
||||||
|
|
||||||
Create issues with `gh issue create`. Do NOT ask the user to review first — just file and share URLs.
|
|
||||||
|
|
||||||
Issues must be **durable** — they should still make sense after major refactors. Write from the user's perspective.
|
|
||||||
|
|
||||||
#### For a single issue
|
|
||||||
|
|
||||||
Use this template:
|
|
||||||
|
|
||||||
```
|
|
||||||
## What happened
|
|
||||||
|
|
||||||
[Describe the actual behavior the user experienced, in plain language]
|
|
||||||
|
|
||||||
## What I expected
|
|
||||||
|
|
||||||
[Describe the expected behavior]
|
|
||||||
|
|
||||||
## Steps to reproduce
|
|
||||||
|
|
||||||
1. [Concrete, numbered steps a developer can follow]
|
|
||||||
2. [Use domain terms from the codebase, not internal module names]
|
|
||||||
3. [Include relevant inputs, flags, or configuration]
|
|
||||||
|
|
||||||
## Additional context
|
|
||||||
|
|
||||||
[Any extra observations from the user or from codebase exploration that help frame the issue — e.g. "this only happens when using the Docker layer, not the filesystem layer" — use domain language but don't cite files]
|
|
||||||
```
|
|
||||||
|
|
||||||
#### For a breakdown (multiple issues)
|
|
||||||
|
|
||||||
Create issues in dependency order (blockers first) so you can reference real issue numbers.
|
|
||||||
|
|
||||||
Use this template for each sub-issue:
|
|
||||||
|
|
||||||
```
|
|
||||||
## Parent issue
|
|
||||||
|
|
||||||
#<parent-issue-number> (if you created a tracking issue) or "Reported during QA session"
|
|
||||||
|
|
||||||
## What's wrong
|
|
||||||
|
|
||||||
[Describe this specific behavior problem — just this slice, not the whole report]
|
|
||||||
|
|
||||||
## What I expected
|
|
||||||
|
|
||||||
[Expected behavior for this specific slice]
|
|
||||||
|
|
||||||
## Steps to reproduce
|
|
||||||
|
|
||||||
1. [Steps specific to THIS issue]
|
|
||||||
|
|
||||||
## Blocked by
|
|
||||||
|
|
||||||
- #<issue-number> (if this issue can't be fixed until another is resolved)
|
|
||||||
|
|
||||||
Or "None — can start immediately" if no blockers.
|
|
||||||
|
|
||||||
## Additional context
|
|
||||||
|
|
||||||
[Any extra observations relevant to this slice]
|
|
||||||
```
|
|
||||||
|
|
||||||
When creating a breakdown:
|
|
||||||
|
|
||||||
- **Prefer many thin issues over few thick ones** — each should be independently fixable and verifiable
|
|
||||||
- **Mark blocking relationships honestly** — if issue B genuinely can't be tested until issue A is fixed, say so. If they're independent, mark both as "None — can start immediately"
|
|
||||||
- **Create issues in dependency order** so you can reference real issue numbers in "Blocked by"
|
|
||||||
- **Maximize parallelism** — the goal is that multiple people (or agents) can grab different issues simultaneously
|
|
||||||
|
|
||||||
#### Rules for all issue bodies
|
|
||||||
|
|
||||||
- **No file paths or line numbers** — these go stale
|
|
||||||
- **Use the project's domain language** (check UBIQUITOUS_LANGUAGE.md if it exists)
|
|
||||||
- **Describe behaviors, not code** — "the sync service fails to apply the patch" not "applyPatch() throws on line 42"
|
|
||||||
- **Reproduction steps are mandatory** — if you can't determine them, ask the user
|
|
||||||
- **Keep it concise** — a developer should be able to read the issue in 30 seconds
|
|
||||||
|
|
||||||
After filing, print all issue URLs (with blocking relationships summarized) and ask: "Next issue, or are we done?"
|
|
||||||
|
|
||||||
### 5. Continue the session
|
|
||||||
|
|
||||||
Keep going until the user says they're done. Each issue is independent — don't batch them.
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
---
|
|
||||||
name: request-refactor-plan
|
|
||||||
description: Create a detailed refactor plan with tiny commits via user interview, then file it as a GitHub issue. Use when user wants to plan a refactor, create a refactoring RFC, or break a refactor into safe incremental steps.
|
|
||||||
---
|
|
||||||
|
|
||||||
This skill will be invoked when the user wants to create a refactor request. You should go through the steps below. You may skip steps if you don't consider them necessary.
|
|
||||||
|
|
||||||
1. Ask the user for a long, detailed description of the problem they want to solve and any potential ideas for solutions.
|
|
||||||
|
|
||||||
2. Explore the repo to verify their assertions and understand the current state of the codebase.
|
|
||||||
|
|
||||||
3. Ask whether they have considered other options, and present other options to them.
|
|
||||||
|
|
||||||
4. Interview the user about the implementation. Be extremely detailed and thorough.
|
|
||||||
|
|
||||||
5. Hammer out the exact scope of the implementation. Work out what you plan to change and what you plan not to change.
|
|
||||||
|
|
||||||
6. Look in the codebase to check for test coverage of this area of the codebase. If there is insufficient test coverage, ask the user what their plans for testing are.
|
|
||||||
|
|
||||||
7. Break the implementation into a plan of tiny commits. Remember Martin Fowler's advice to "make each refactoring step as small as possible, so that you can always see the program working."
|
|
||||||
|
|
||||||
8. Create a GitHub issue with the refactor plan. Use the following template for the issue description:
|
|
||||||
|
|
||||||
<refactor-plan-template>
|
|
||||||
|
|
||||||
## Problem Statement
|
|
||||||
|
|
||||||
The problem that the developer is facing, from the developer's perspective.
|
|
||||||
|
|
||||||
## Solution
|
|
||||||
|
|
||||||
The solution to the problem, from the developer's perspective.
|
|
||||||
|
|
||||||
## Commits
|
|
||||||
|
|
||||||
A LONG, detailed implementation plan. Write the plan in plain English, breaking down the implementation into the tiniest commits possible. Each commit should leave the codebase in a working state.
|
|
||||||
|
|
||||||
## Decision Document
|
|
||||||
|
|
||||||
A list of implementation decisions that were made. This can include:
|
|
||||||
|
|
||||||
- The modules that will be built/modified
|
|
||||||
- The interfaces of those modules that will be modified
|
|
||||||
- Technical clarifications from the developer
|
|
||||||
- Architectural decisions
|
|
||||||
- Schema changes
|
|
||||||
- API contracts
|
|
||||||
- Specific interactions
|
|
||||||
|
|
||||||
Do NOT include specific file paths or code snippets. They may end up being outdated very quickly.
|
|
||||||
|
|
||||||
## Testing Decisions
|
|
||||||
|
|
||||||
A list of testing decisions that were made. Include:
|
|
||||||
|
|
||||||
- A description of what makes a good test (only test external behavior, not implementation details)
|
|
||||||
- Which modules will be tested
|
|
||||||
- Prior art for the tests (i.e. similar types of tests in the codebase)
|
|
||||||
|
|
||||||
## Out of Scope
|
|
||||||
|
|
||||||
A description of the things that are out of scope for this refactor.
|
|
||||||
|
|
||||||
## Further Notes (optional)
|
|
||||||
|
|
||||||
Any further notes about the refactor.
|
|
||||||
|
|
||||||
</refactor-plan-template>
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
---
|
|
||||||
name: ubiquitous-language
|
|
||||||
description: Extract a DDD-style ubiquitous language glossary from the current conversation, flagging ambiguities and proposing canonical terms. Saves to UBIQUITOUS_LANGUAGE.md. Use when user wants to define domain terms, build a glossary, harden terminology, create a ubiquitous language, or mentions "domain model" or "DDD".
|
|
||||||
disable-model-invocation: true
|
|
||||||
---
|
|
||||||
|
|
||||||
# Ubiquitous Language
|
|
||||||
|
|
||||||
Extract and formalize domain terminology from the current conversation into a consistent glossary, saved to a local file.
|
|
||||||
|
|
||||||
## Process
|
|
||||||
|
|
||||||
1. **Scan the conversation** for domain-relevant nouns, verbs, and concepts
|
|
||||||
2. **Identify problems**:
|
|
||||||
- Same word used for different concepts (ambiguity)
|
|
||||||
- Different words used for the same concept (synonyms)
|
|
||||||
- Vague or overloaded terms
|
|
||||||
3. **Propose a canonical glossary** with opinionated term choices
|
|
||||||
4. **Write to `UBIQUITOUS_LANGUAGE.md`** in the working directory using the format below
|
|
||||||
5. **Output a summary** inline in the conversation
|
|
||||||
|
|
||||||
## Output Format
|
|
||||||
|
|
||||||
Write a `UBIQUITOUS_LANGUAGE.md` file with this structure:
|
|
||||||
|
|
||||||
```md
|
|
||||||
# Ubiquitous Language
|
|
||||||
|
|
||||||
## Order lifecycle
|
|
||||||
|
|
||||||
| Term | Definition | Aliases to avoid |
|
|
||||||
| ----------- | ------------------------------------------------------- | --------------------- |
|
|
||||||
| **Order** | A customer's request to purchase one or more items | Purchase, transaction |
|
|
||||||
| **Invoice** | A request for payment sent to a customer after delivery | Bill, payment request |
|
|
||||||
|
|
||||||
## People
|
|
||||||
|
|
||||||
| Term | Definition | Aliases to avoid |
|
|
||||||
| ------------ | ------------------------------------------- | ---------------------- |
|
|
||||||
| **Customer** | A person or organization that places orders | Client, buyer, account |
|
|
||||||
| **User** | An authentication identity in the system | Login, account |
|
|
||||||
|
|
||||||
## Relationships
|
|
||||||
|
|
||||||
- An **Invoice** belongs to exactly one **Customer**
|
|
||||||
- An **Order** produces one or more **Invoices**
|
|
||||||
|
|
||||||
## Example dialogue
|
|
||||||
|
|
||||||
> **Dev:** "When a **Customer** places an **Order**, do we create the **Invoice** immediately?"
|
|
||||||
> **Domain expert:** "No — an **Invoice** is only generated once a **Fulfillment** is confirmed. A single **Order** can produce multiple **Invoices** if items ship in separate **Shipments**."
|
|
||||||
> **Dev:** "So if a **Shipment** is cancelled before dispatch, no **Invoice** exists for it?"
|
|
||||||
> **Domain expert:** "Exactly. The **Invoice** lifecycle is tied to the **Fulfillment**, not the **Order**."
|
|
||||||
|
|
||||||
## Flagged ambiguities
|
|
||||||
|
|
||||||
- "account" was used to mean both **Customer** and **User** — these are distinct concepts: a **Customer** places orders, while a **User** is an authentication identity that may or may not represent a **Customer**.
|
|
||||||
```
|
|
||||||
|
|
||||||
## Rules
|
|
||||||
|
|
||||||
- **Be opinionated.** When multiple words exist for the same concept, pick the best one and list the others as aliases to avoid.
|
|
||||||
- **Flag conflicts explicitly.** If a term is used ambiguously in the conversation, call it out in the "Flagged ambiguities" section with a clear recommendation.
|
|
||||||
- **Only include terms relevant for domain experts.** Skip the names of modules or classes unless they have meaning in the domain language.
|
|
||||||
- **Keep definitions tight.** One sentence max. Define what it IS, not what it does.
|
|
||||||
- **Show relationships.** Use bold term names and express cardinality where obvious.
|
|
||||||
- **Only include domain terms.** Skip generic programming concepts (array, function, endpoint) unless they have domain-specific meaning.
|
|
||||||
- **Group terms into multiple tables** when natural clusters emerge (e.g. by subdomain, lifecycle, or actor). Each group gets its own heading and table. If all terms belong to a single cohesive domain, one table is fine — don't force groupings.
|
|
||||||
- **Write an example dialogue.** A short conversation (3-5 exchanges) between a dev and a domain expert that demonstrates how the terms interact naturally. The dialogue should clarify boundaries between related concepts and show terms being used precisely.
|
|
||||||
|
|
||||||
<example>
|
|
||||||
|
|
||||||
## Example dialogue
|
|
||||||
|
|
||||||
> **Dev:** "How do I test the **sync service** without Docker?"
|
|
||||||
|
|
||||||
> **Domain expert:** "Provide the **filesystem layer** instead of the **Docker layer**. It implements the same **Sandbox service** interface but uses a local directory as the **sandbox**."
|
|
||||||
|
|
||||||
> **Dev:** "So **sync-in** still creates a **bundle** and unpacks it?"
|
|
||||||
|
|
||||||
> **Domain expert:** "Exactly. The **sync service** doesn't know which layer it's talking to. It calls `exec` and `copyIn` — the **filesystem layer** just runs those as local shell commands."
|
|
||||||
|
|
||||||
</example>
|
|
||||||
|
|
||||||
## Re-running
|
|
||||||
|
|
||||||
When invoked again in the same conversation:
|
|
||||||
|
|
||||||
1. Read the existing `UBIQUITOUS_LANGUAGE.md`
|
|
||||||
2. Incorporate any new terms from subsequent discussion
|
|
||||||
3. Update definitions if understanding has evolved
|
|
||||||
4. Re-flag any new ambiguities
|
|
||||||
5. Rewrite the example dialogue to incorporate new terms
|
|
||||||
@@ -4,15 +4,18 @@ Skills I use daily for code work.
|
|||||||
|
|
||||||
## User-invoked
|
## User-invoked
|
||||||
|
|
||||||
Reachable only when you type them (`disable-model-invocation: true`).
|
Reachable only when you type them (Claude Code: `disable-model-invocation: true`; Codex: `policy.allow_implicit_invocation: false` in `agents/openai.yaml`).
|
||||||
|
|
||||||
- **[ask-matt](./ask-matt/SKILL.md)** — Ask which skill or flow fits your situation. A router over the user-invoked skills in this repo.
|
- **[ask-matt](./ask-matt/SKILL.md)** — Ask which skill or flow fits your situation. A router over the user-invoked skills in this repo.
|
||||||
- **[grill-with-docs](./grill-with-docs/SKILL.md)** — Grilling session that also builds your project's domain model, sharpening terminology and updating `CONTEXT.md` and ADRs inline.
|
- **[grill-with-docs](./grill-with-docs/SKILL.md)** — Grilling session that also builds your project's domain model, sharpening terminology and updating `CONTEXT.md` and ADRs inline.
|
||||||
- **[triage](./triage/SKILL.md)** — Move issues through a state machine of triage roles.
|
- **[triage](./triage/SKILL.md)** — Move issues through a state machine of triage roles.
|
||||||
- **[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-spec](./to-spec/SKILL.md)** — Turn the current conversation into a spec 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.
|
- **[to-tickets](./to-tickets/SKILL.md)** — Break any plan, spec, or conversation into a set of tracer-bullet tickets, each declaring its blocking edges — text in a local file, or native blocking links on a real tracker.
|
||||||
|
- **[implement](./implement/SKILL.md)** — Build the work described by a spec or set of tickets, driving `/tdd` at pre-agreed seams and closing out with `/code-review` before committing.
|
||||||
|
- **[wayfinder](./wayfinder/SKILL.md)** — Plan a huge chunk of work — more than one agent session can hold — as a shared map of decision tickets on the issue tracker, resolved one at a time until the way to the destination is clear.
|
||||||
|
- **[wizard](./wizard/SKILL.md)** — Generate an interactive bash wizard that walks a human through a manual procedure — third-party setup, a one-off migration, an A→B state transition — opening URLs, capturing values, and writing `.env` files and GitHub Actions secrets.
|
||||||
|
|
||||||
## Model-invoked
|
## Model-invoked
|
||||||
|
|
||||||
@@ -21,7 +24,9 @@ Model- or user-reachable (rich trigger phrasing so the model can reach for them)
|
|||||||
- **[prototype](./prototype/SKILL.md)** — Build a throwaway prototype to answer a design question: a runnable terminal app for state/logic, or several toggleable UI variations.
|
- **[prototype](./prototype/SKILL.md)** — Build a throwaway prototype to answer a design question: a runnable terminal app for state/logic, or several toggleable UI variations.
|
||||||
|
|
||||||
- **[diagnosing-bugs](./diagnosing-bugs/SKILL.md)** — Disciplined diagnosis loop for hard bugs and performance regressions: reproduce → minimise → hypothesise → instrument → fix → regression-test.
|
- **[diagnosing-bugs](./diagnosing-bugs/SKILL.md)** — Disciplined diagnosis loop for hard bugs and performance regressions: reproduce → minimise → hypothesise → instrument → fix → regression-test.
|
||||||
|
- **[research](./research/SKILL.md)** — Investigate a question against high-trust primary sources and capture the findings as a cited Markdown file in the repo, run as a background agent.
|
||||||
- **[tdd](./tdd/SKILL.md)** — Test-driven development with a red-green-refactor loop. Builds features or fixes bugs one vertical slice at a time.
|
- **[tdd](./tdd/SKILL.md)** — Test-driven development with a red-green-refactor loop. Builds features or fixes bugs one vertical slice at a time.
|
||||||
- **[domain-modeling](./domain-modeling/SKILL.md)** — Actively build and sharpen a project's domain model — challenge terms, stress-test with scenarios, update `CONTEXT.md` and ADRs inline.
|
- **[domain-modeling](./domain-modeling/SKILL.md)** — Actively build and sharpen a project's domain model — challenge terms, stress-test with scenarios, update `CONTEXT.md` and ADRs inline.
|
||||||
- **[codebase-design](./codebase-design/SKILL.md)** — Shared discipline and vocabulary for designing deep modules: small interfaces, clean seams, testable through the interface.
|
- **[codebase-design](./codebase-design/SKILL.md)** — Shared discipline and vocabulary for designing deep modules: small interfaces, clean seams, testable through the interface.
|
||||||
- **[code-review](./code-review/SKILL.md)** — Two-axis review of the diff since a fixed point: **Standards** (does it follow the repo's coding standards, plus a Fowler smell baseline?) and **Spec** (does it faithfully implement the originating issue/PRD?), run as parallel sub-agents.
|
- **[code-review](./code-review/SKILL.md)** — Two-axis review of the diff since a fixed point: **Standards** (does it follow the repo's coding standards, plus a Fowler smell baseline?) and **Spec** (does it faithfully implement the originating issue/spec?), run as parallel sub-agents.
|
||||||
|
- **[resolving-merge-conflicts](./resolving-merge-conflicts/SKILL.md)** — Work through an in-progress git merge or rebase conflict hunk by hunk, resolving by intent traced to each side's primary source, then finish the operation — never `--abort`.
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
# Phase boundaries
|
||||||
|
|
||||||
|
A **phase** is a chunk of work inside a session — the grilling, the implementation, the QA. The definition is fuzzy on purpose: a phase ends when you think *"ok, we're done with that"*.
|
||||||
|
|
||||||
|
The **phase boundary** is the gap between two phases, and it is the only place this decision belongs. Mid-phase there is no decision to make — continue, or split the work that's left into subagents. Compacting mid-phase makes the agent lose the thread.
|
||||||
|
|
||||||
|
## The five options
|
||||||
|
|
||||||
|
| Option | What it does |
|
||||||
|
| ------------ | --------------------------------------------------------------- |
|
||||||
|
| **Continue** | Stay in the session. No context switch at all. |
|
||||||
|
| **`/clear`** | Empty the context window and start from nothing. |
|
||||||
|
| **`/handoff`** | Write a portable markdown file and seed a session anywhere with it. |
|
||||||
|
| **Subagent** | Send the task to its own context window and get a report back. |
|
||||||
|
| **`/compact`** | Compress this context and seed a fresh session with the summary. |
|
||||||
|
|
||||||
|
## The tree
|
||||||
|
|
||||||
|
Work top to bottom at the boundary. The first **yes** wins.
|
||||||
|
|
||||||
|
**1. Can you continue in this session?** Two things make the answer yes: the next phase needs this phase as a **primary source**, or you have enough [smart zone](https://www.aihero.dev/ai-coding-dictionary/smart-zone) left (~150k tokens) for the next phase to fit. Grilling → implementation is the standard yes: the implementation wants the reasoning verbatim, not a summary of it. Continue costs nothing and loses nothing, so rule it out before anything else.
|
||||||
|
|
||||||
|
**2. Is the context irrelevant to what comes next?** Is everything in this session — the exploration, the decisions, the dead ends — disposable? If so, **`/clear`**. It is the cheapest move on the board: it takes no time and hands back the whole window. `/clear` also isn't terminal — the old session stays resumable.
|
||||||
|
|
||||||
|
The cost of getting this wrong is one-way. Clear a *relevant* context and you lose the **why** behind what you built, and no amount of reading the diff back gets it returned.
|
||||||
|
|
||||||
|
**3. Do you need to hand off?** `/handoff` is narrow. You need it only when you are:
|
||||||
|
|
||||||
|
- swapping to a **new harness** (Claude → Codex),
|
||||||
|
- moving to a **new directory** or repo,
|
||||||
|
- sending the work to a **colleague**,
|
||||||
|
- or forking a side task you found **mid-phase** without derailing what you're doing.
|
||||||
|
|
||||||
|
That list is the whole clause. What `/handoff` buys is **portability** — a file that travels. If nothing is travelling, you don't need it.
|
||||||
|
|
||||||
|
**4. Can the task be done AFK?** Is it scoped tightly enough to run with you away from the keyboard, no steering? Then send it to a **subagent** and leave this session untouched. Automated review is the standard case: the agent reads the diff and reports, and you aren't needed while it does.
|
||||||
|
|
||||||
|
**5. Otherwise, `/compact`.** Relevant context, same harness, same directory, and you need to stay in the loop — this is where the tree lands, and it lands here often. Pass it an instruction (`/compact we're going to QA this area`) so the summary keeps what the next phase needs.
|
||||||
|
|
||||||
|
`/compact` is the **default, not the first reach**. It sits at the bottom because the four questions above it are all cheaper or more precise. The failure mode when people start here is a fresh session that is confidently wrong about a decision the summary flattened.
|
||||||
|
|
||||||
|
## Primary and secondary sources
|
||||||
|
|
||||||
|
Every move except **Continue** turns a **primary source** into a **secondary source** — the session as it happened, replaced by a summary of it. The trade is always the same shape:
|
||||||
|
|
||||||
|
| Source | Information | Noise | Room to move |
|
||||||
|
| --------------------------------- | ----------- | ----- | ------------ |
|
||||||
|
| Primary (Continue) | Full | Lots | Little |
|
||||||
|
| Secondary (`/compact`, `/handoff`) | Lossy | Less | Lots |
|
||||||
|
|
||||||
|
This is why question 1 comes first. You only pay the lossiness when staying costs more than it saves.
|
||||||
|
|
||||||
|
## These are judgement calls
|
||||||
|
|
||||||
|
The questions are not objective — each has taste in it, and the same boundary can go two ways on two days. The value is in asking them **in order**, at the boundary rather than in the middle of the work.
|
||||||
@@ -15,21 +15,21 @@ A **flow** is a path through the skills. Most paths run along one **main flow**,
|
|||||||
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. Both run the same `/grilling` primitive; `grill-with-docs` is the one that leaves a paper trail.)
|
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 (a prototype lives in its own directory, which is exactly what `/handoff` is for — see Phase boundaries):
|
||||||
- **`/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-spec`** (turn the thread into a spec), then **`/to-tickets`** to split it into tracer-bullet tickets, each declaring its **blocking edges**. On a local tracker that's one file per ticket under `.scratch/<feature>/issues/`, worked blockers-first by hand; on a real tracker the edges become native blocking links, so any ticket whose blockers are done can be grabbed — kick off **`/implement`** per ticket, **`/clear`ing context between each one**. Each ticket is self-contained, so the last one's context is disposable.
|
||||||
- **No** → **`/implement`** right here, in the same context window.
|
- **No** → **`/implement`** right here, in the same context window.
|
||||||
|
|
||||||
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.
|
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
|
||||||
|
|
||||||
Keep steps 1–3 in **one unbroken context window** — don't compact or clear until after `/to-issues` — so the grilling, PRD, and issues all build on the same thinking. Each `/implement` then starts fresh, working from the issue.
|
Keep steps 1–3 in **one unbroken context window** — don't compact or clear until after `/to-tickets` — so the grilling, spec, and tickets all build on the same thinking. Each `/implement` then starts fresh, working from the ticket.
|
||||||
|
|
||||||
The limit on this is the **[smart zone](https://www.aihero.dev/ai-coding-dictionary/smart-zone)**: the window (~120k tokens on state-of-the-art models) within which the model still reasons sharply. If a session approaches it before `/to-issues`, don't push on degraded — `/handoff` and continue in a fresh thread.
|
The limit on this is the **[smart zone](https://www.aihero.dev/ai-coding-dictionary/smart-zone)**: the window (~150k tokens on state-of-the-art models) within which the model still reasons sharply. If a session approaches it before `/to-tickets`, don't push on degraded — `/compact` at the nearest phase boundary and carry on (see Phase boundaries).
|
||||||
|
|
||||||
## On-ramps
|
## On-ramps
|
||||||
|
|
||||||
@@ -37,10 +37,14 @@ A starting situation that generates work, then merges onto the main flow.
|
|||||||
|
|
||||||
- **Bugs and requests piling up** → **`/triage`**. It moves issues through triage roles and produces agent-ready issues, which **`/implement`** later picks up.
|
- **Bugs and requests piling up** → **`/triage`**. It moves issues through triage roles and produces agent-ready issues, which **`/implement`** later picks up.
|
||||||
|
|
||||||
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. Tickets that `/to-tickets` 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.
|
- **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.
|
||||||
|
|
||||||
|
- **A huge, foggy effort — a greenfield project or a huge feature build, too big for one session** → **`/wayfinder`**, the most cognitively demanding flow here. When the way from here to the destination isn't visible yet, it charts a **shared map** of **decision tickets** on the issue tracker and resolves them one at a time — producing **decisions, not deliverables** — until the fog is pushed back and the way is clear. Where **`/grill-with-docs`** sharpens an idea you can hold in one session, wayfinder is for the idea you can't — and it's slower and denser, so save it for exactly that, never a well-scoped feature.
|
||||||
|
|
||||||
|
When the map clears, **it hands off, it doesn't build**: merge onto the main flow at **`/to-spec`**, which collapses the map's linked decisions into a buildable plan, then `/to-tickets` and `/implement` as usual. Looping the map straight into `/implement` skips that collapse and throws the linked detail away — go straight to `/implement` only when the effort turned out genuinely small.
|
||||||
|
|
||||||
## Codebase health
|
## Codebase health
|
||||||
|
|
||||||
Not feature work — upkeep.
|
Not feature work — upkeep.
|
||||||
@@ -54,10 +58,17 @@ Two model-invoked references that run *beneath* the other skills — each the si
|
|||||||
- **`/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.
|
- **`/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.
|
- **`/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
|
## Phase boundaries
|
||||||
|
|
||||||
- **`/handoff`** — when a thread is full or you need to branch off (e.g. into a `/prototype` session), this compacts the conversation into a markdown file. You don't continue in place — you **open a new session and reference that file** to carry the context across. It's the bridge between context windows, in either direction. Use it when you want a **fresh session** but need the **current conversation preserved**.
|
A **phase** is a chunk of work inside a session — the grilling, the implementation, the QA. At the **boundary** between two of them you have five options, and picking between them is the fuzziest decision in this whole map:
|
||||||
- **`/compact`** (built-in) — stay in the **same conversation**, letting the earlier turns be summarized. Use it at **intentional breaks between phases**, when you don't mind losing the verbatim history. Don't compact mid-phase — the agent can lose its way. `/handoff` forks; `/compact` continues.
|
|
||||||
|
- **Continue** — stay put. Costs nothing, loses nothing.
|
||||||
|
- **`/clear`** — empty the window, when nothing here matters to what's next.
|
||||||
|
- **`/handoff`** — write a portable markdown file. Narrow: only for a **new harness**, a **new directory**, a **colleague**, or forking a side task **mid-phase**. What it buys is portability.
|
||||||
|
- **Subagent** — send a tightly-scoped task to its own window and get a report back.
|
||||||
|
- **`/compact`** — compress this context and seed a fresh session with it. The **default**, at the bottom of the tree rather than the first reach.
|
||||||
|
|
||||||
|
Read [PHASE-BOUNDARIES.md](PHASE-BOUNDARIES.md) for the ordered tree — the five questions, the reasoning behind each branch, and why the primary-source cost makes **Continue** the one to rule out first. Make the decision **at** a boundary; mid-phase, continue or split the rest into subagents.
|
||||||
|
|
||||||
## Standalone
|
## Standalone
|
||||||
|
|
||||||
@@ -65,8 +76,12 @@ 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.
|
- **`/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.
|
||||||
|
- **`/research`** — delegate reading legwork to a **background agent**: it investigates a question against **primary sources**, then leaves a cited Markdown file in the repo. Keep working while it reads. The file it produces is something to take *into* the main flow at `/grill-with-docs` — research feeds the thinking, it doesn't replace it.
|
||||||
|
- **`/to-questionnaire`** — when the thing blocking you isn't in your head or the codebase but in **someone else's**, this writes them a questionnaire to fill in. It's the inverse of `/grill-me`: instead of interviewing you about the subject, it interviews you about the **send** — who it's going to, what you need back — and aims the questions at the gap. What comes back is material for `/grill-with-docs` or `/to-spec`.
|
||||||
|
- **`/wizard`** — for the steps only a **human** can take: clicking through a third-party dashboard, running a one-off migration, moving the project from state A to state B. It generates an interactive bash script that opens each URL, captures each value, and writes it into `.env` and GitHub secrets — so the procedure stops being something you re-explain to an agent every time. If the agent could just do it itself, it should; reach for this only where a human is genuinely in the loop.
|
||||||
|
- **`/wait-what`** — the fire extinguisher for a message that didn't land. Fire it mid-conversation, inside any other skill, and the agent re-pitches what it just said with the context you were missing, in plain English, using the `CONTEXT.md` vocabulary. It's the in-the-moment corrective; `/grill-with-docs` and `/domain-modeling` are the upfront cure, because a shared language agreed early is what stops the jargon arriving at all.
|
||||||
- **`/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-for-agents`** — reference for writing documents agents consume: skills, AGENTS.md, pointed-at docs.
|
||||||
|
|
||||||
## Precondition
|
## Precondition
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Ask Matt"
|
||||||
|
short_description: "Find the right skill or workflow"
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: false
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
---
|
---
|
||||||
name: code-review
|
name: code-review
|
||||||
description: Review the changes since a fixed point (commit, branch, tag, or merge-base) along two axes — Standards (does the code follow this repo's documented coding standards?) and Spec (does the code match what the originating issue/PRD asked for?). Runs both reviews in parallel sub-agents and reports them side by side. Use when the user wants to review a branch, a PR, work-in-progress changes, or asks to "review since X".
|
description: Review the changes since a fixed point (commit, branch, tag, or merge-base) along two axes — Standards (does the code follow this repo's documented coding standards?) and Spec (does the code match what the originating issue/spec asked for?). Runs both reviews in parallel sub-agents and reports them side by side. Use when the user wants to review a branch, a PR, work-in-progress changes, or asks to "review since X".
|
||||||
---
|
---
|
||||||
|
|
||||||
Two-axis review of the diff between `HEAD` and a fixed point the user supplies:
|
Two-axis review of the diff between `HEAD` and a fixed point the user supplies:
|
||||||
|
|
||||||
- **Standards** — does the code conform to this repo's documented coding standards?
|
- **Standards** — does the code conform to this repo's documented coding standards?
|
||||||
- **Spec** — does the code faithfully implement the originating issue / PRD / spec?
|
- **Spec** — does the code faithfully implement the originating issue / spec?
|
||||||
|
|
||||||
Both axes run as **parallel sub-agents** so they don't pollute each other's context, then this skill aggregates their findings.
|
Both axes run as **parallel sub-agents** so they don't pollute each other's context, then this skill aggregates their findings.
|
||||||
|
|
||||||
@@ -28,7 +28,7 @@ Look for the originating spec, in this order:
|
|||||||
|
|
||||||
1. Issue references in the commit messages (`#123`, `Closes #45`, GitLab `!67`, etc.) — fetch via the workflow in `docs/agents/issue-tracker.md`.
|
1. Issue references in the commit messages (`#123`, `Closes #45`, GitLab `!67`, etc.) — fetch via the workflow in `docs/agents/issue-tracker.md`.
|
||||||
2. A path the user passed as an argument.
|
2. A path the user passed as an argument.
|
||||||
3. A PRD/spec file under `docs/`, `specs/`, or `.scratch/` matching the branch name or feature.
|
3. A spec file under `docs/`, `specs/`, or `.scratch/` matching the branch name or feature.
|
||||||
4. If nothing is found, ask the user where the spec is. If they say there isn't one, the **Spec** sub-agent will skip and report "no spec available".
|
4. If nothing is found, ask the user where the spec is. If they say there isn't one, the **Spec** sub-agent will skip and report "no spec available".
|
||||||
|
|
||||||
### 3. Identify the standards sources
|
### 3. Identify the standards sources
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Code Review"
|
||||||
|
short_description: "Review a diff on standards and spec"
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Codebase Design"
|
||||||
|
short_description: "Vocabulary for deep-module design"
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Diagnosing Bugs"
|
||||||
|
short_description: "Diagnose hard bugs and regressions"
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Domain Modeling"
|
||||||
|
short_description: "Build and sharpen a domain model"
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Grill with Docs"
|
||||||
|
short_description: "Grill a design and write its docs"
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: false
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
---
|
---
|
||||||
name: implement
|
name: implement
|
||||||
description: "Implement a piece of work based on a PRD or set of issues."
|
description: "Implement a piece of work based on a spec or set of tickets."
|
||||||
disable-model-invocation: true
|
disable-model-invocation: true
|
||||||
---
|
---
|
||||||
|
|
||||||
Implement the work described by the user in the PRD or issues.
|
Implement the work described by the user in the spec or tickets.
|
||||||
|
|
||||||
Use /tdd where possible, at pre-agreed seams.
|
Use /tdd where possible, at pre-agreed seams.
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Implement"
|
||||||
|
short_description: "Build work from a spec or tickets"
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: false
|
||||||
@@ -17,6 +17,11 @@ This command is _informed_ by the project's domain model and built on a shared d
|
|||||||
|
|
||||||
### 1. Explore
|
### 1. Explore
|
||||||
|
|
||||||
|
**Scope before you scan — YAGNI.** Deepening a module pays off by making future changes to it easier, so put extra weight on the parts of the codebase that have recently changed. Decide *where* to look before you look:
|
||||||
|
|
||||||
|
- If the user named a direction — a module, a subsystem, a pain point — take it, and skip the inference below.
|
||||||
|
- Otherwise, walk back a good stretch of the commit history (`git log --oneline`) to find the codebase's hot spots — the files and areas that keep coming up — and let those paths pull your attention first. If the changes are scattered with no clear hot spot, widen the net.
|
||||||
|
|
||||||
Read the project's domain glossary (`CONTEXT.md`) and any ADRs in the area you're touching first.
|
Read the project's domain glossary (`CONTEXT.md`) and any ADRs in the area you're touching first.
|
||||||
|
|
||||||
Then use the Agent tool with `subagent_type=Explore` to walk the codebase. Don't follow rigid heuristics — explore organically and note where you experience friction:
|
Then use the Agent tool with `subagent_type=Explore` to walk the codebase. Don't follow rigid heuristics — explore organically and note where you experience friction:
|
||||||
@@ -56,7 +61,7 @@ Do NOT propose interfaces yet. After the file is written, ask the user: "Which o
|
|||||||
|
|
||||||
### 3. Grilling loop
|
### 3. Grilling loop
|
||||||
|
|
||||||
Once the user picks a candidate, run the `/grilling` skill to walk the design tree with them — constraints, dependencies, the shape of the deepened module, what sits behind the seam, what tests survive.
|
Once the user picks a candidate, run the `/grilling` skill to walk the decision tree with them — constraints, dependencies, the shape of the deepened module, what sits behind the seam, what tests survive.
|
||||||
|
|
||||||
Side effects happen inline as decisions crystallize — run the `/domain-modeling` skill to keep the domain model current as you go:
|
Side effects happen inline as decisions crystallize — run the `/domain-modeling` skill to keep the domain model current as you go:
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Improve Codebase Architecture"
|
||||||
|
short_description: "Find and grill architecture improvements"
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: false
|
||||||
@@ -1,13 +1,15 @@
|
|||||||
# Logic Prototype
|
# Logic Prototype
|
||||||
|
|
||||||
A tiny interactive terminal app that lets the user drive a state model by hand. Use this when the question is about **business logic, state transitions, or data shape** — the kind of thing that looks reasonable on paper but only feels wrong once you push it through real cases.
|
A single, self-contained HTML file — a **shareable demo** — that lets anyone drive a state model by clicking buttons. Use this when the question is about **business logic, state transitions, or data shape** — the kind of thing that looks reasonable on paper but only feels wrong once you push it through real cases.
|
||||||
|
|
||||||
|
Because it's one file with nothing to install, you can hand it to a non-developer — a designer, a PM, a domain expert — and let them feel the model for themselves. So it speaks their language, not the code's.
|
||||||
|
|
||||||
## When this is the right shape
|
## When this is the right shape
|
||||||
|
|
||||||
- "I'm not sure if this state machine handles the edge case where X then Y."
|
- "I'm not sure if this state machine handles the edge case where X then Y."
|
||||||
- "Does this data model actually let me represent the case where..."
|
- "Does this data model actually let me represent the case where..."
|
||||||
- "I want to feel out what the API should look like before writing it."
|
- "I want to feel out what the API should look like before writing it."
|
||||||
- Anything where the user wants to **press buttons and watch state change**.
|
- Anything where someone wants to **press buttons and watch state change**.
|
||||||
|
|
||||||
If the question is "what should this look like" — wrong branch. Use [UI.md](UI.md).
|
If the question is "what should this look like" — wrong branch. Use [UI.md](UI.md).
|
||||||
|
|
||||||
@@ -15,17 +17,11 @@ If the question is "what should this look like" — wrong branch. Use [UI.md](UI
|
|||||||
|
|
||||||
### 1. State the question
|
### 1. State the question
|
||||||
|
|
||||||
Before writing code, write down what state model and what question you're prototyping. One paragraph, in the prototype's README or a comment at the top of the file. A logic prototype that answers the wrong question is pure waste — make the question explicit so it can be checked later, whether the user is watching now or returning to it AFK.
|
Before writing code, write down what state model and what question you're prototyping. One paragraph, at the top of the demo (in a visible intro, not just a comment). A logic prototype that answers the wrong question is pure waste — make the question explicit so it can be checked later, whether the user is watching now or returning to it AFK.
|
||||||
|
|
||||||
### 2. Pick the language
|
### 2. Isolate the logic in a portable module
|
||||||
|
|
||||||
Use whatever the host project uses. If the project has no obvious runtime (e.g. a docs repo), ask.
|
Put the actual logic — the bit that's answering the question — in a single `<script>` block written as a small, pure module that could be lifted out and dropped into the real codebase later. The page around it is throwaway; this module isn't.
|
||||||
|
|
||||||
Match the project's existing conventions for tooling — don't add a new package manager or runtime just for the prototype.
|
|
||||||
|
|
||||||
### 3. Isolate the logic in a portable module
|
|
||||||
|
|
||||||
Put the actual logic — the bit that's answering the question — behind a small, pure interface that could be lifted out and dropped into the real codebase later. The TUI around it is throwaway; the logic module shouldn't be.
|
|
||||||
|
|
||||||
The right shape depends on the question:
|
The right shape depends on the question:
|
||||||
|
|
||||||
@@ -34,46 +30,38 @@ The right shape depends on the question:
|
|||||||
- **A small set of pure functions** over a plain data type. Good when there's no implicit current state — just transformations.
|
- **A small set of pure functions** over a plain data type. Good when there's no implicit current state — just transformations.
|
||||||
- **A class or module with a clear method surface** when the logic genuinely owns ongoing internal state.
|
- **A class or module with a clear method surface** when the logic genuinely owns ongoing internal state.
|
||||||
|
|
||||||
Pick whichever shape best fits the question being asked, *not* whichever is easiest to wire to a TUI. Keep it pure: no I/O, no terminal code, no `console.log` for control flow. The TUI imports it and calls into it; nothing flows the other direction.
|
Pick whichever shape best fits the question being asked, *not* whichever is easiest to wire to a page. Keep it pure: no DOM, no `document`, no button handlers reaching inside it. The page calls into it; nothing flows the other direction. This is what makes the prototype useful past its own lifetime: once the question's answered, the validated reducer / machine / function set lifts into the real module on its own.
|
||||||
|
|
||||||
This is what makes the prototype useful past its own lifetime. When the question's been answered, the validated reducer / machine / function set can be lifted into the real module — the TUI shell gets deleted.
|
### 3. Build the shareable HTML file
|
||||||
|
|
||||||
### 4. Build the smallest TUI that exposes the state
|
One file, plain HTML/CSS/JS — no framework, no bundler, no server, everything inline so it opens by double-click and survives being emailed around. Anyone should be able to run it by opening it.
|
||||||
|
|
||||||
Build it as a **lightweight TUI** — on every tick, clear the screen (`console.clear()` / `print("\033[2J\033[H")` / equivalent) and re-render the whole frame. The user should always see one stable view, not an ever-growing scrollback.
|
Write it for a non-developer. Every label is in **domain language**, not code — buttons and state read like the business, not the reducer. Explain in plain words what's happening.
|
||||||
|
|
||||||
Each frame has two parts, in this order:
|
Lay it out with a clean hierarchy, top to bottom:
|
||||||
|
|
||||||
1. **Current state**, pretty-printed and diff-friendly (one field per line, or formatted JSON). Use **bold** for field names or section headers and **dim** for less important context (timestamps, IDs, derived values). Native ANSI escape codes are fine — `\x1b[1m` bold, `\x1b[2m` dim, `\x1b[0m` reset. No need to pull in a styling library unless one is already in the project.
|
1. **Title and one-line explanation** of what this demo lets you explore (the question from step 1).
|
||||||
2. **Keyboard shortcuts**, listed at the bottom: `[a] add user [d] delete user [t] tick clock [q] quit`. Bold the key, dim the description, or vice-versa — whatever reads cleanly.
|
2. **Current state** — the full relevant state, rendered as a readable panel (labelled fields, not a raw JSON dump), re-rendered after every click so the change is visible. Where it helps a non-developer follow, call out what just changed.
|
||||||
|
3. **Free-play buttons** — one button per action, always available, so anyone can poke at the model in any order. Each click dispatches its action and re-renders the state.
|
||||||
|
4. **Guided walkthroughs** — a set of **scenarios**, one per tab. Each tab holds a short plain-language description of the scenario — the situation it sets up and what to watch for — and underneath it, the ordered **buttons to press** for that scenario. Each step is a real button: clicking it performs that action and moves to the next step. Starting a walkthrough resets to a known initial state so the scenario runs the same way every time.
|
||||||
|
|
||||||
Behaviour:
|
Choose scenarios that demonstrate the awkward cases — the happy path, a tricky edge case, an attempt at something that should be illegal — the ones hard to reason about on paper.
|
||||||
|
|
||||||
1. **Initialise state** — a single in-memory object/struct. Render the first frame on start.
|
Keep it beautiful but restrained: clean typography, generous spacing, one accent colour. No animations, no gimmicks — nothing that competes with the state and the buttons.
|
||||||
2. **Read one keystroke (or one line)** at a time, dispatch to a handler that mutates state.
|
|
||||||
3. **Re-render** the full frame after every action — don't append, replace.
|
|
||||||
4. **Loop until quit.**
|
|
||||||
|
|
||||||
The whole frame should fit on one screen.
|
### 4. Hand it over
|
||||||
|
|
||||||
### 5. Make it runnable in one command
|
Send them the file, or open it for them. They'll click through the walkthroughs and free-play whenever they get to it; the interesting moments are when they say "wait, that shouldn't be possible" or "huh, I assumed X would be different" — those are the bugs in the _idea_, which is the whole point. If they want new actions or a new scenario, add them. Prototypes evolve.
|
||||||
|
|
||||||
Add a script to the project's existing task runner (`package.json` scripts, `Makefile`, `justfile`, `pyproject.toml`). The user should run `pnpm run <prototype-name>` or equivalent — never need to remember a path.
|
### 5. Capture the answer and the prototype
|
||||||
|
|
||||||
If the host project has no task runner, just put the command at the top of the prototype's README.
|
Once the prototype has answered its question, capture the answer, then capture the prototype the way the [SKILL](SKILL.md) describes. The logic-specific mapping: the validated reducer / machine / function set lifts into the real module (the decision, absorbed); the HTML shell rides along to the throwaway branch that keeps the prototype as a primary source — and being one self-contained file, it stays trivially re-runnable there.
|
||||||
|
|
||||||
### 6. Hand it over
|
|
||||||
|
|
||||||
Give the user the run command. They'll drive it themselves; the interesting moments are when they say "wait, that shouldn't be possible" or "huh, I assumed X would be different" — those are the bugs in the _idea_, which is the whole point. If they want new actions added, add them. Prototypes evolve.
|
|
||||||
|
|
||||||
### 7. Capture the answer
|
|
||||||
|
|
||||||
When the prototype has done its job, the answer to the question is the only thing worth keeping. If the user is around, ask what it taught them. If not, leave a `NOTES.md` next to the prototype so the answer can be filled in (or filled in by you, if you've watched the session) before the prototype gets deleted.
|
|
||||||
|
|
||||||
## Anti-patterns
|
## Anti-patterns
|
||||||
|
|
||||||
- **Don't add tests.** A prototype that needs tests is no longer a prototype.
|
- **Don't add tests.** A prototype that needs tests is no longer a prototype.
|
||||||
- **Don't wire it to the real database.** Use an in-memory store unless the question is specifically about persistence.
|
- **Don't wire it to the real database.** Use in-memory state unless the question is specifically about persistence.
|
||||||
- **Don't generalise.** No "what if we wanted to support X later." The prototype answers one question.
|
- **Don't generalise.** No "what if we wanted to support X later." The prototype answers one question.
|
||||||
- **Don't blur the logic and the TUI together.** If the reducer / state machine references `console.log`, prompts, or terminal escape codes, it's no longer portable. Keep the TUI as a thin shell over a pure module.
|
- **Don't blur the logic and the page together.** If the pure module references the DOM, `document`, or button handlers, it's no longer liftable. Keep the page as a thin shell over a pure module.
|
||||||
- **Don't ship the TUI shell into production.** The shell is optimised for being driven by hand from a terminal. The logic module behind it is the bit worth keeping.
|
- **Don't reach for a framework, bundler, or server.** One file the recipient double-clicks; a React app or a dev server defeats "shareable".
|
||||||
|
- **Don't ship the HTML shell into production.** The page is optimised for being clicked through by hand. The logic module behind it is the bit worth keeping.
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ A prototype is **throwaway code that answers a question**. The question decides
|
|||||||
|
|
||||||
Identify which question is being answered — from the user's prompt, the surrounding code, or by asking if the user is around:
|
Identify which question is being answered — from the user's prompt, the surrounding code, or by asking if the user is around:
|
||||||
|
|
||||||
- **"Does this logic / state model feel right?"** → [LOGIC.md](LOGIC.md). Build a tiny interactive terminal app that pushes the state machine through cases that are hard to reason about on paper.
|
- **"Does this logic / state model feel right?"** → [LOGIC.md](LOGIC.md). Build a single shareable HTML file — free-play buttons plus tabbed guided walkthroughs — that pushes the state machine through cases that are hard to reason about on paper, and that a non-developer can drive.
|
||||||
- **"What should this look like?"** → [UI.md](UI.md). Generate several radically different UI variations on a single route, switchable via a URL search param and a floating bottom bar.
|
- **"What should this look like?"** → [UI.md](UI.md). Generate several radically different UI variations on a single route, switchable via a URL search param and a floating bottom bar.
|
||||||
|
|
||||||
The two branches produce very different artifacts — getting this wrong wastes the whole prototype. If the question is genuinely ambiguous and the user isn't reachable, default to whichever branch better matches the surrounding code (a backend module → logic; a page or component → UI) and state the assumption at the top of the prototype.
|
The two branches produce very different artifacts — getting this wrong wastes the whole prototype. If the question is genuinely ambiguous and the user isn't reachable, default to whichever branch better matches the surrounding code (a backend module → logic; a page or component → UI) and state the assumption at the top of the prototype.
|
||||||
@@ -19,12 +19,8 @@ The two branches produce very different artifacts — getting this wrong wastes
|
|||||||
## Rules that apply to both
|
## Rules that apply to both
|
||||||
|
|
||||||
1. **Throwaway from day one, and clearly marked as such.** Locate the prototype code close to where it will actually be used (next to the module or page it's prototyping for) so context is obvious — but name it so a casual reader can see it's a prototype, not production. For throwaway UI routes, obey whatever routing convention the project already uses; don't invent a new top-level structure.
|
1. **Throwaway from day one, and clearly marked as such.** Locate the prototype code close to where it will actually be used (next to the module or page it's prototyping for) so context is obvious — but name it so a casual reader can see it's a prototype, not production. For throwaway UI routes, obey whatever routing convention the project already uses; don't invent a new top-level structure.
|
||||||
2. **One command to run.** Whatever the project's existing task runner supports — `pnpm <name>`, `python <path>`, `bun <path>`, etc. The user must be able to start it without thinking.
|
2. **Trivial to run.** A UI prototype starts from one command in the project's task runner — `pnpm <name>`, `python <path>`, `bun <path>`, etc. A logic demo is a single HTML file the user double-clicks. Either way, no thinking required to start it.
|
||||||
3. **No persistence by default.** State lives in memory. Persistence is the thing the prototype is _checking_, not something it should depend on. If the question explicitly involves a database, hit a scratch DB or a local file with a clear "PROTOTYPE — wipe me" name.
|
3. **No persistence by default.** State lives in memory. Persistence is the thing the prototype is _checking_, not something it should depend on. If the question explicitly involves a database, hit a scratch DB or a local file with a clear "PROTOTYPE — wipe me" name.
|
||||||
4. **Skip the polish.** No tests, no error handling beyond what makes the prototype _runnable_, no abstractions. The point is to learn something fast and then delete it.
|
4. **Skip the polish.** No tests, no error handling beyond what makes the prototype _runnable_, no abstractions. The point is to learn something fast.
|
||||||
5. **Surface the state.** After every action (logic) or on every variant switch (UI), print or render the full relevant state so the user can see what changed.
|
5. **Surface the state.** After every action (logic) or on every variant switch (UI), print or render the full relevant state so the user can see what changed.
|
||||||
6. **Delete or absorb when done.** When the prototype has answered its question, either delete it or fold the validated decision into the real code — don't leave it rotting in the repo.
|
6. **Capture it when done.** Fold any validated decision into the real code, then capture the prototype itself as a **primary source**: commit it to a throwaway branch, out of main, and leave a context pointer to that branch on the implementation issue. Capture the answer too — the verdict and the question it settled — in the issue or a commit. The main branch keeps only the validated decision.
|
||||||
|
|
||||||
## When done
|
|
||||||
|
|
||||||
The _answer_ is the only thing worth keeping from a prototype. Capture it somewhere durable (commit message, ADR, issue, or a `NOTES.md` next to the prototype) along with the question it was answering. If the user is around, that capture is a quick conversation; if not, leave the placeholder so they (or you, on the next pass) can fill in the verdict before deleting the prototype.
|
|
||||||
|
|||||||
@@ -97,12 +97,12 @@ Surface the URL (and the `?variant=` keys). The user will flip through whenever
|
|||||||
|
|
||||||
### 6. Capture the answer and clean up
|
### 6. Capture the answer and clean up
|
||||||
|
|
||||||
Once a variant has won, write down which one and why (commit message, ADR, issue, or a `NOTES.md` next to the prototype if running AFK and the user hasn't responded yet). Then:
|
Once a variant has won, capture the answer — which variant and why — then capture the prototype the way the [SKILL](SKILL.md) describes. Fold the winner into the real code and move the rest onto the throwaway branch, not into main:
|
||||||
|
|
||||||
- **Sub-shape A** — delete the losing variants and the switcher; fold the winner into the existing page.
|
- **Sub-shape A** — fold the winner into the existing page; drop the losing variants and the switcher from main.
|
||||||
- **Sub-shape B** — promote the winning variant to a real route, delete the throwaway route and the switcher.
|
- **Sub-shape B** — promote the winning variant to a real route; drop the throwaway route and the switcher from main.
|
||||||
|
|
||||||
Don't leave variant components or the switcher lying around. They rot fast and confuse the next reader.
|
The full set of variants is the primary source, so it lands on the throwaway branch, not the bin — variant components and the switcher left in the main branch rot fast and confuse the next reader.
|
||||||
|
|
||||||
## Anti-patterns
|
## Anti-patterns
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Prototype"
|
||||||
|
short_description: "Prototype to answer a design question"
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user