pi-matt-pocock 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/LICENSE +27 -0
  2. package/README.md +38 -0
  3. package/TODO.md +11 -0
  4. package/index.ts +1 -0
  5. package/package.json +44 -0
  6. package/procedures/ADR-FORMAT.md +47 -0
  7. package/procedures/AGENT-BRIEF.md +207 -0
  8. package/procedures/CONTEXT-FORMAT.md +60 -0
  9. package/procedures/DEEPENING.md +37 -0
  10. package/procedures/DESIGN-IT-TWICE.md +44 -0
  11. package/procedures/GLOSSARY-FORMAT.md +35 -0
  12. package/procedures/GLOSSARY.md +201 -0
  13. package/procedures/HTML-REPORT.md +123 -0
  14. package/procedures/LEARNING-RECORD-FORMAT.md +46 -0
  15. package/procedures/LOGIC.md +79 -0
  16. package/procedures/MISSION-FORMAT.md +31 -0
  17. package/procedures/OUT-OF-SCOPE.md +105 -0
  18. package/procedures/RESOURCES-FORMAT.md +32 -0
  19. package/procedures/SKILL-MECHANICS.md +22 -0
  20. package/procedures/UI.md +112 -0
  21. package/procedures/bdd-best-practices.md +68 -0
  22. package/procedures/bdd.md +98 -0
  23. package/procedures/code-review.md +111 -0
  24. package/procedures/codebase-design.md +113 -0
  25. package/procedures/diagnosing-bugs.md +139 -0
  26. package/procedures/domain-modeling.md +73 -0
  27. package/procedures/domain.md +51 -0
  28. package/procedures/gherkin-guide.md +109 -0
  29. package/procedures/grill-me.md +5 -0
  30. package/procedures/grill-with-docs.md +5 -0
  31. package/procedures/grilling.md +11 -0
  32. package/procedures/handoff.md +13 -0
  33. package/procedures/hitl-loop.template.sh +44 -0
  34. package/procedures/implement.md +13 -0
  35. package/procedures/improve-codebase-architecture.md +69 -0
  36. package/procedures/issue-tracker-github.md +45 -0
  37. package/procedures/issue-tracker-gitlab.md +46 -0
  38. package/procedures/issue-tracker-local.md +30 -0
  39. package/procedures/mocking.md +59 -0
  40. package/procedures/phase-boundaries.md +55 -0
  41. package/procedures/prototype.md +25 -0
  42. package/procedures/research.md +11 -0
  43. package/procedures/resolving-merge-conflicts.md +13 -0
  44. package/procedures/setup-matt-pocock-skills.md +114 -0
  45. package/procedures/tdd.md +60 -0
  46. package/procedures/teach.md +137 -0
  47. package/procedures/template.sh +204 -0
  48. package/procedures/testing-anti-patterns.md +37 -0
  49. package/procedures/tests.md +77 -0
  50. package/procedures/to-questionnaire.md +47 -0
  51. package/procedures/to-spec.md +77 -0
  52. package/procedures/to-tickets.md +97 -0
  53. package/procedures/triage-labels.md +15 -0
  54. package/procedures/triage.md +110 -0
  55. package/procedures/wait-what.md +1 -0
  56. package/procedures/wayfinder.md +127 -0
  57. package/procedures/wizard.md +39 -0
  58. package/procedures/writing-for-agents.md +76 -0
  59. package/procedures/writing-great-skills.md +81 -0
  60. package/src/index.ts +485 -0
  61. package/src/procedures.ts +33 -0
  62. package/src/workflow.ts +192 -0
@@ -0,0 +1,30 @@
1
+ # Issue tracker: Local Markdown
2
+
3
+ Issues and specs (you may know a spec as a PRD) for this repo live as markdown files in `.scratch/`.
4
+
5
+ ## Conventions
6
+
7
+ - One feature per directory: `.scratch/<feature-slug>/`
8
+ - The spec is `.scratch/<feature-slug>/spec.md`
9
+ - Implementation issues are one file per ticket at `.scratch/<feature-slug>/issues/<NN>-<slug>.md`, numbered from `01` — never a single combined tickets file
10
+ - Triage state is recorded as a `Status:` line near the top of each issue file (see `triage-labels.md` for the role strings)
11
+ - Comments and conversation history append to the bottom of the file under a `## Comments` heading
12
+
13
+ ## When a skill says "publish to the issue tracker"
14
+
15
+ Create a new file under `.scratch/<feature-slug>/` (creating the directory if needed).
16
+
17
+ ## When a skill says "fetch the relevant ticket"
18
+
19
+ Read the file at the referenced path. The user will normally pass the path or the issue number directly.
20
+
21
+ ## Wayfinding operations
22
+
23
+ Used by [wayfinder](wayfinder.md). The **map** is a file with one **child** file per ticket.
24
+
25
+ - **Map**: `.scratch/<effort>/map.md` — the Notes / Decisions-so-far / Fog body.
26
+ - **Child ticket**: `.scratch/<effort>/issues/NN-<slug>.md`, numbered from `01`, with the question in the body. A `Type:` line records the ticket type (`research`/`prototype`/`grilling`/`task`); a `Status:` line records `claimed`/`resolved`.
27
+ - **Blocking**: a `Blocked by: NN, NN` line near the top. A ticket is unblocked when every file it lists is `resolved`.
28
+ - **Frontier**: scan `.scratch/<effort>/issues/` for files that are open, unblocked, and unclaimed; first by number wins.
29
+ - **Claim**: set `Status: claimed` and save before any work.
30
+ - **Resolve**: append the answer under an `## Answer` heading, set `Status: resolved`, then append a context pointer (gist + link) to the map's Decisions-so-far in `map.md`.
@@ -0,0 +1,59 @@
1
+ # When to Mock
2
+
3
+ Mock at **system boundaries** only:
4
+
5
+ - External APIs (payment, email, etc.)
6
+ - Databases (sometimes - prefer test DB)
7
+ - Time/randomness
8
+ - File system (sometimes)
9
+
10
+ Don't mock:
11
+
12
+ - Your own classes/modules
13
+ - Internal collaborators
14
+ - Anything you control
15
+
16
+ ## Designing for Mockability
17
+
18
+ At system boundaries, design interfaces that are easy to mock:
19
+
20
+ **1. Use dependency injection**
21
+
22
+ Pass external dependencies in rather than creating them internally:
23
+
24
+ ```typescript
25
+ // Easy to mock
26
+ function processPayment(order, paymentClient) {
27
+ return paymentClient.charge(order.total);
28
+ }
29
+
30
+ // Hard to mock
31
+ function processPayment(order) {
32
+ const client = new StripeClient(process.env.STRIPE_KEY);
33
+ return client.charge(order.total);
34
+ }
35
+ ```
36
+
37
+ **2. Prefer SDK-style interfaces over generic fetchers**
38
+
39
+ Create specific functions for each external operation instead of one generic function with conditional logic:
40
+
41
+ ```typescript
42
+ // GOOD: Each function is independently mockable
43
+ const api = {
44
+ getUser: (id) => fetch(`/users/${id}`),
45
+ getOrders: (userId) => fetch(`/users/${userId}/orders`),
46
+ createOrder: (data) => fetch('/orders', { method: 'POST', body: data }),
47
+ };
48
+
49
+ // BAD: Mocking requires conditional logic inside the mock
50
+ const api = {
51
+ fetch: (endpoint, options) => fetch(endpoint, options),
52
+ };
53
+ ```
54
+
55
+ The SDK approach means:
56
+ - Each mock returns one specific shape
57
+ - No conditional logic in test setup
58
+ - Easier to see which endpoints a test exercises
59
+ - Type safety per endpoint
@@ -0,0 +1,55 @@
1
+ # Phase boundaries
2
+
3
+ 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"*.
4
+
5
+ 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 delegate the work that remains to a teammate when that facility is available. Compacting mid-phase makes the agent lose the thread.
6
+
7
+ ## The five options
8
+
9
+ | Option | What it does |
10
+ | ------------ | --------------------------------------------------------------- |
11
+ | **Continue** | Stay in the session. No context switch at all. |
12
+ | **`/new`** | Start a fresh session when the old context is irrelevant. |
13
+ | **[handoff](handoff.md)** | Write a portable Markdown document; it does not create, fork, or seed a session. |
14
+ | **Teammate** | Delegate a tightly scoped task when the teammate facility is available. |
15
+ | **`/compact`** | Compress this context and seed a fresh session with the summary. |
16
+
17
+ ## The tree
18
+
19
+ Work top to bottom at the boundary. The first **yes** wins.
20
+
21
+ **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.
22
+
23
+ **2. Is the context irrelevant to what comes next?** Is everything in this session — the exploration, the decisions, the dead ends — disposable? If so, start a fresh session with **`/new`**. The old session remains resumable.
24
+
25
+ The cost of getting this wrong is one-way. Leave a *relevant* context and you lose the **why** behind what you built, and no amount of reading the diff back gets it returned.
26
+
27
+ **3. Do you need to hand off?** [handoff](handoff.md) is narrow. You need it only when you are:
28
+
29
+ - swapping to a **new harness** (one harness → another harness),
30
+ - moving to a **new directory** or repo,
31
+ - sending the work to a **colleague**,
32
+ - or recording a side task you found **mid-phase** without derailing what you're doing.
33
+
34
+ That list is the whole clause. What [handoff](handoff.md) buys is **portability** — a document that travels. It only writes the document; it does not create, fork, or seed a session. If nothing is travelling, you don't need it.
35
+
36
+ **4. Can the task be done AFK?** Is it scoped tightly enough to run with you away from the keyboard, no steering? If the teammate facility is available, delegate it to a teammate and leave this session untouched. Otherwise complete it sequentially in the current context. Automated review is the standard case: the reviewer reads the diff and reports, and you aren't needed while it does.
37
+
38
+ **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.
39
+
40
+ `/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.
41
+
42
+ ## Primary and secondary sources
43
+
44
+ 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:
45
+
46
+ | Source | Information | Noise | Room to move |
47
+ | --------------------------------- | ----------- | ----- | ------------ |
48
+ | Primary (Continue) | Full | Lots | Little |
49
+ | Secondary (`/compact`, [handoff](handoff.md)) | Lossy | Less | Lots |
50
+
51
+ This is why question 1 comes first. You only pay the lossiness when staying costs more than it saves.
52
+
53
+ ## These are judgement calls
54
+
55
+ 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.
@@ -0,0 +1,25 @@
1
+ # Prototype
2
+
3
+ A prototype is **throwaway code that answers a question**. The question decides the shape.
4
+
5
+ ## Pick a branch
6
+
7
+ Identify which question is being answered — from the user's prompt, the surrounding code, or by asking the user directly in the conversation if they are available:
8
+
9
+ - **"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.
10
+ - **"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.
11
+
12
+ 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.
13
+
14
+ ## CRITICAL: The question decides the shape
15
+
16
+ Identify the question being answered before building — "does this logic / state model feel right?" takes LOGIC.md, "what should this look like?" takes UI.md; getting this wrong wastes the whole prototype. Throwaway from day one: no tests, no polish, no persistence — keep the answer, delete the code.
17
+
18
+ ## Rules that apply to both
19
+
20
+ 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.
21
+ 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.
22
+ 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.
23
+ 4. **Skip the polish.** No tests, no error handling beyond what makes the prototype _runnable_, no abstractions. The point is to learn something fast.
24
+ 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.
25
+ 6. **Capture it when done.** Fold any validated decision into the real code, then preserve the prototype as a **primary source** on a throwaway branch, out of main, and leave a context pointer to that branch on the implementation issue. Record the verdict and the question it settled in the issue or commit message. When a commit is needed, follow the repository's git-agent workflow rather than staging or committing directly. The main branch keeps only the validated decision.
@@ -0,0 +1,11 @@
1
+ Use a **teammate when the teammate facility is available** to do the research, so the main conversation stays focused while it reads. Otherwise do the research in the current context.
2
+
3
+ Its job:
4
+
5
+ 1. Investigate the question against **primary sources** — official docs, source code, specs, first-party APIs — not a secondary write-up of them. Follow every claim back to the source that owns it.
6
+ 2. Write the findings to a single Markdown file, citing each claim's source.
7
+ 3. Save it where the repo already keeps such notes; match the existing convention, and if there is none, put it somewhere sensible and say where.
8
+
9
+ ## CRITICAL: Primary sources only
10
+
11
+ Investigate against primary sources — official docs, source code, specs, first-party APIs — never a secondary write-up of them. Follow every claim back to the source that owns it, and cite each claim's source in the findings file.
@@ -0,0 +1,13 @@
1
+ 1. **See the current state** of the merge/rebase. Check git history, and the conflicting files.
2
+
3
+ 2. **Find the primary sources** for each conflict. Understand deeply why each change was made, and what the original intent was. Read the commit messages, check the PRs, check original issues/tickets.
4
+
5
+ 3. **Resolve each hunk.** Preserve both intents where possible. Where incompatible, pick the one matching the merge's stated goal and note the trade-off. Do **not** invent new behaviour. Always resolve; never `--abort`.
6
+
7
+ ## CRITICAL: Preserve intent, never invent
8
+
9
+ Understand the original intent of each change before resolving it. Do **not** invent new behaviour; where intents conflict, pick the one matching the merge's stated goal and note the trade-off. Always resolve — never `--abort`.
10
+
11
+ 4. Discover the project's **automated checks** and run them — typically typecheck, then tests, then format. Fix anything the merge broke.
12
+
13
+ 5. **Finish the merge/rebase.** For a merge commit, use the repository's git-agent workflow rather than staging or committing directly. If rebasing, continue the rebase process until all commits are rebased.
@@ -0,0 +1,114 @@
1
+ # Setup Matt Pocock's Skills
2
+
3
+ Scaffold the per-repo configuration that the engineering skills assume:
4
+
5
+ - **Issue tracker** — where issues live (GitHub by default; local markdown is also supported out of the box)
6
+ - **Triage labels** — the strings used for the five canonical triage roles
7
+ - **Domain docs** — where `CONTEXT.md` and ADRs live, and the consumer rules for reading them
8
+
9
+ This is a prompt-driven skill, not a deterministic script. Explore, present what you found, confirm with the user, then write.
10
+
11
+ ## Process
12
+
13
+ ### 1. Explore
14
+
15
+ Look at the current repo to understand its starting state. Read whatever exists; don't assume:
16
+
17
+ - `git remote -v` and `.git/config` — is this a GitHub repo? Which one?
18
+ - `AGENTS.md` and `CLAUDE.md` at the repo root — does either exist? Is there already an `## Agent skills` section in either?
19
+ - `CONTEXT.md` and `CONTEXT-MAP.md` at the repo root
20
+ - `docs/adr/` and any `src/*/docs/adr/` directories
21
+ - `docs/agents/` — does this skill's prior output already exist?
22
+ - `.scratch/` — sign that a local-markdown issue tracker convention is already in use
23
+ - Is the `triage` skill installed? (a `triage` skill folder alongside this one, or `triage` in your available skills.) This decides whether Section B runs at all.
24
+ - Monorepo signals — a `pnpm-workspace.yaml`, a `workspaces` field in `package.json`, or a populated `packages/*` with its own `src/`. Present only in a genuinely large multi-package repo; their absence means single-context, which is almost every repo.
25
+
26
+ ### 2. Present findings and ask
27
+
28
+ Summarise what's present and what's missing. Then take the sections in order — one section, one answer, then the next.
29
+
30
+ Lead each section with the recommended answer so the user can accept it in a word. Give a one-line explainer only when the choice genuinely branches; skip the section entirely when exploration already settled it (Section B when `triage` isn't installed, Section C when there's no monorepo).
31
+
32
+ **Section A — Issue tracker.**
33
+
34
+ > Explainer: The "issue tracker" is where issues live for this repo. Skills like `to-tickets`, `triage`, `to-spec`, and `qa` read from and write to it — they need to know whether to call `gh issue create`, write a markdown file under `.scratch/`, or follow some other workflow you describe. Pick the place you actually track work for this repo.
35
+
36
+ Default posture: these skills were designed for GitHub. If a `git remote` points at GitHub, propose that. If a `git remote` points at GitLab (`gitlab.com` or a self-hosted host), propose GitLab. Otherwise (or if the user prefers), ask directly in the conversation and wait for the reply. Offer:
37
+
38
+ - **GitHub** — issues live in the repo's GitHub Issues (uses the `gh` CLI)
39
+ - **GitLab** — issues live in the repo's GitLab Issues (uses the [`glab`](https://gitlab.com/gitlab-org/cli) CLI)
40
+ - **Local markdown** — issues live as files under `.scratch/<feature>/` in this repo (good for solo projects or repos without a remote)
41
+ - **Another tracker** (Jira, Linear, etc.) — the user describes the workflow in one paragraph; record it as freeform prose
42
+
43
+ Record the choice in `docs/agents/issue-tracker.md`. The GitHub and GitLab templates carry a "PRs as a request surface" flag, defaulted **off** — leave it off and don't raise it; a user who wants external PRs in the triage queue can flip the flag in the file later.
44
+
45
+ **Section B — Triage label vocabulary.** Skip this section entirely if the `triage` skill isn't installed (exploration told you) — an uninstalled skill needs no labels.
46
+
47
+ If it is installed, ask exactly one question directly in the conversation and wait for the reply:
48
+
49
+ > "Do you want to keep the default triage labels?" — keep the defaults (Recommended) / use my own label names
50
+
51
+ The defaults are the five canonical roles, each label string equal to its name: `needs-triage`, `needs-info`, `ready-for-agent`, `ready-for-human`, `wontfix`. On **yes**, write them as-is. Only if the user says no — usually because their tracker already uses other names (e.g. `bug:triage` for `needs-triage`) — collect the overrides so `triage` applies existing labels instead of creating duplicates.
52
+
53
+ **Section C — Domain docs.** Default to **single-context** — one `CONTEXT.md` + `docs/adr/` at the repo root. This fits almost every repo; write it without asking.
54
+
55
+ Offer **multi-context** — a root `CONTEXT-MAP.md` pointing to per-context `CONTEXT.md` files — only when exploration found monorepo signals. Then ask directly in the conversation which layout they want and wait for the reply.
56
+
57
+ ### 3. Confirm and edit
58
+
59
+ Show the user a draft of:
60
+
61
+ - The `## Agent skills` block to add to whichever of `AGENTS.md` / `CLAUDE.md` is being edited (see step 4 for selection rules)
62
+ - The contents of `docs/agents/issue-tracker.md`, `docs/agents/domain.md`, and `docs/agents/triage-labels.md` (the last only when `triage` is installed)
63
+
64
+ Let them edit before writing.
65
+
66
+ ### 4. Write
67
+
68
+ **Pick the file to edit:**
69
+
70
+ - If `AGENTS.md` exists, edit it.
71
+ - Else if `CLAUDE.md` exists, edit it.
72
+ - If neither exists, ask directly in the conversation whether to create `AGENTS.md` or `CLAUDE.md`, and wait for the reply.
73
+
74
+ Prefer `AGENTS.md` when both exist. Never create a second instruction file when one already exists — always edit the existing file.
75
+
76
+ If an `## Agent skills` block already exists in the chosen file, update its contents in-place rather than appending a duplicate. Don't overwrite user edits to the surrounding sections.
77
+
78
+ The block:
79
+
80
+ ```markdown
81
+ ## Agent skills
82
+
83
+ ### Issue tracker
84
+
85
+ [one-line summary of where issues are tracked]. See `docs/agents/issue-tracker.md`.
86
+
87
+ ### Triage labels
88
+
89
+ [one-line summary of the label vocabulary]. See `docs/agents/triage-labels.md`.
90
+
91
+ ### Domain docs
92
+
93
+ [one-line summary of layout — "single-context" or "multi-context"]. See `docs/agents/domain.md`.
94
+ ```
95
+
96
+ Include the `### Triage labels` sub-block, and write `docs/agents/triage-labels.md`, only when `triage` is installed and Section B ran. When it isn't, both are omitted.
97
+
98
+ Then write the docs files using the seed templates in this skill folder as a starting point:
99
+
100
+ - [issue-tracker-github.md](./issue-tracker-github.md) — GitHub issue tracker
101
+ - [issue-tracker-gitlab.md](./issue-tracker-gitlab.md) — GitLab issue tracker
102
+ - [issue-tracker-local.md](./issue-tracker-local.md) — local-markdown issue tracker
103
+ - [triage-labels.md](./triage-labels.md) — label mapping (only if `triage` is installed)
104
+ - [domain.md](./domain.md) — domain doc consumer rules + layout
105
+
106
+ For "other" issue trackers, write `docs/agents/issue-tracker.md` from scratch using the user's description.
107
+
108
+ ## CRITICAL: Confirm before writing, never duplicate
109
+
110
+ This is prompt-driven: present findings, ask directly in the conversation section by section, show the draft, and wait for the user's approval before anything is written. Prefer `AGENTS.md` when both instruction files exist; update an existing `## Agent skills` block in place rather than appending a duplicate.
111
+
112
+ ### 5. Done
113
+
114
+ Tell the user the setup is complete and which engineering skills will now read from these files. Mention they can edit `docs/agents/*.md` directly later — re-running this skill is only necessary if they want to switch issue trackers or restart from scratch.
@@ -0,0 +1,60 @@
1
+ # BDD-Driven TDD (Automation)
2
+
3
+ BDD cycles through three phases: **Discovery** (conversations → examples), **Formulation** (Gherkin scenarios), **Automation** (red-green-refactor, driven by BDD). This skill is the **BDD-driven Automation** reference — the how of test implementation, once [bdd](bdd.md) has defined the what.
4
+
5
+ When invoked during [implement](implement.md) or [bdd](bdd.md), use this skill as the test-writing authority. The [bdd](bdd.md) skill governs the scenario design and Iron Law; this skill governs the test code quality under BDD discipline.
6
+
7
+ ## CRITICAL: BDD scenarios come first
8
+
9
+ If you reached this skill directly (not via [bdd](bdd.md) or [implement](implement.md)), inspect the repository and conversation for Gherkin scenarios first.
10
+
11
+ - If scenarios are absent → invoke [bdd](bdd.md) to define them, then return here for Automation.
12
+ - If scenarios exist in `.feature` files or equivalent → proceed with the red-green loop below.
13
+ - Ask the user only if the behavior itself is genuinely unresolved; do not ask for confirmation of facts that repository exploration can establish.
14
+
15
+ ## What a good test is
16
+
17
+ Tests verify behavior through public interfaces, not implementation details. Code can change entirely; tests shouldn't. A good test reads like a specification — "user can checkout with valid cart" tells you exactly what capability exists — and survives refactors because it doesn't care about internal structure.
18
+
19
+ See [tests.md](tests.md) for examples and [mocking.md](mocking.md) for mocking guidelines.
20
+
21
+ ## Seams — where tests go
22
+
23
+ A **seam** is the public boundary you test at: the interface where you observe behavior without reaching inside. Tests live at seams, never against internals.
24
+
25
+ **Test at the highest established seam.** Record the public boundary under test and select the highest existing seam that expresses the confirmed behavior. Not everything can be tested — choosing the critical public seam deliberately is how effort lands on complex behavior instead of every edge case. Ask only when the public contract is genuinely ambiguous.
26
+
27
+ When the shape of that interface is itself in question — how deep the module is, where the seam belongs, what the interface should expose — use the [codebase-design](codebase-design.md) skill for the vocabulary. It is the shared source of the module, interface, depth, seam, adapter, leverage and locality terms, and it is a reference to consult, not a session to run.
28
+
29
+ ## Anti-patterns
30
+
31
+ - **Implementation-coupled** — mocks internal collaborators, tests private methods, or verifies through a side channel (querying the database instead of using the interface). The tell: the test breaks when you refactor but behavior hasn't changed.
32
+ - **Tautological** — the assertion recomputes the expected value the way the code does (`expect(add(a, b)).toBe(a + b)`, a snapshot derived by hand the same way, a constant asserted equal to itself), so it passes by construction and can never disagree with the code. Expected values must come from an independent source of truth — a known-good literal, a worked example, the spec.
33
+ - **Horizontal slicing** — writing all tests first, then all implementation. Bulk tests verify _imagined_ behavior: you test the _shape_ of things rather than user-facing behavior, the tests go insensitive to real changes, and you commit to test structure before understanding the implementation. Work in **vertical slices** instead — one test → one implementation → repeat, each test a **tracer bullet** that responds to what the last cycle taught you.
34
+
35
+ ## Rules of the loop
36
+
37
+ - **Red before green.** Write the failing test first, then only enough code to pass it. Don't anticipate future tests or add speculative features.
38
+ - **One slice at a time.** One seam, one test, one minimal implementation per cycle.
39
+ - **Refactoring is not part of the loop.** It belongs to the review stage (see [code-review](code-review.md)), not the red → green implementation cycle.
40
+
41
+ ## CRITICAL: BDD-Driven — not standalone TDD
42
+
43
+ This skill is the **Automation** phase of the BDD lifecycle. It always runs under [bdd](bdd.md) or [implement](implement.md) as **BDD-driven TDD**. If invoked directly, see the CRITICAL check at the top of this file — confirm scenarios exist before writing test code.
44
+
45
+ 1. **Discovery** (what behavior matters) — owned by [bdd](bdd.md) via Gherkin scenarios
46
+ 2. **Formulation** (scenario as specification) — owned by [bdd](bdd.md) via `.feature` files
47
+ 3. **Automation** (this skill) — the red-green loop that makes the scenario pass
48
+
49
+ ## When to invoke
50
+
51
+ Invoke this skill explicitly when:
52
+ - The user asks "how should I test this?" during BDD implementation
53
+ - The user asks about mocking, seams, or test structure
54
+ - The user writes a test that looks implementation-coupled
55
+ - The user asks about mocking strategy at system boundaries
56
+ - The user is unsure whether a test is good or tautological
57
+
58
+ When invoked directly, first check if Gherkin scenarios exist (see the CRITICAL check at the top). If not, redirect to [bdd](bdd.md) before proceeding with Automation.
59
+
60
+ The [bdd](bdd.md) and [implement](implement.md) skills load this automatically during the Automation phase — you do not need to invoke it separately in those flows.
@@ -0,0 +1,137 @@
1
+ The user has asked you to teach them something. This is a stateful request - they intend to learn the topic over multiple sessions.
2
+
3
+ ## Teaching Workspace
4
+
5
+ Treat the current directory as a teaching workspace. The state of their learning is captured in this directory in several files:
6
+
7
+ - `MISSION.md`: A document capturing the _reason_ the user is interested in the topic. This should be used to ground all teaching. Use the format in [MISSION-FORMAT.md](./MISSION-FORMAT.md).
8
+ - `./reference/*.html`: A directory of reference materials. These are the compressed learnings from the lessons - cheat sheets, reference algorithms, syntax, yoga poses, glossaries. They are the raw units of learning. They should be beautiful documents which print out well, and are designed for quick reference.
9
+ - `RESOURCES.md`: A list of resources which can be explored to ground your teaching in contextual knowledge, or to acquire knowledge and wisdom. Use the format in [RESOURCES-FORMAT.md](./RESOURCES-FORMAT.md).
10
+ - `./learning-records/*.md`: A directory of learning records, which capture what the user has learned. These are loosely equivalent to architectural decision records in software development - they capture non-obvious lessons and key insights that may need to be revised later, or drive future sessions. These should be used to calculate the zone of proximal development. They are titled `0001-<dash-case-name>.md`, where the number increments each time. Use the format in [LEARNING-RECORD-FORMAT.md](./LEARNING-RECORD-FORMAT.md).
11
+ - `./lessons/*.html`: A directory of lessons. A **lesson** is a single, self-contained HTML output that teaches one tightly-scoped thing tied to the mission. This is the primary unit of teaching in this workspace.
12
+ - `./assets/*`: Reusable **components** shared across lessons. See [Assets](#assets).
13
+ - `NOTES.md`: A scratchpad for you to jot down user preferences, or working notes.
14
+
15
+ ## Philosophy
16
+
17
+ To learn at a deep level, the user needs three things:
18
+
19
+ - **Knowledge**, captured from high-quality, high-trust resources
20
+ - **Skills**, acquired through highly-relevant interactive lessons devised by you, based on the knowledge
21
+ - **Wisdom**, which comes from interacting with other learners and practitioners
22
+
23
+ Before the `RESOURCES.md` is well-populated, your focus should be to find high-quality resources which will help the user acquire knowledge. Never trust your parametric knowledge.
24
+
25
+ Some topics may require more skills than knowledge. Learning more about theoretical physics might be more knowledge-based. For yoga, more skills-based.
26
+
27
+ ### Fluency vs Storage Strength
28
+
29
+ Split between two types of learning:
30
+
31
+ - **Fluency strength**: in-the-moment retrieval of knowledge
32
+ - **Storage strength**: long-term retention of knowledge
33
+
34
+ Fluency can give the user an illusory sense of mastery, but storage strength is the real goal. Try to design lessons which build long-term retention by desirable difficulty:
35
+
36
+ - Using retrieval practice (recall from memory)
37
+ - Spacing (distributing practice over time)
38
+ - Interleaving (mixing up different but related topics in practice - for skills practice only)
39
+
40
+ ## Lessons
41
+
42
+ A lesson is the main thing you produce — the unit in which knowledge and skills reach the user. Each lesson is one self-contained HTML file, saved to `./lessons/` and titled `0001-<dash-case-name>.html` where the number increments each time.
43
+
44
+ A lesson should be **beautiful** — clean, readable typography and layout — since the user will return to these later to review. Think Tufte.
45
+
46
+ The lesson should be short, and completable very quickly. Learners' working memory is very small, and we need to stay within it. But each lesson should give the user a single tangible win that they can build on. It should be directly tied to the mission, and should be in the user's zone of proximal development.
47
+
48
+ If possible, open the lesson file for the user by running a CLI command.
49
+
50
+ Each lesson should link via HTML anchors to other lessons and reference documents.
51
+
52
+ Each lesson should recommend a primary source for the user to read or watch. This should be the most high-quality, high-trust resource you found on the topic.
53
+
54
+ Each lesson should contain a reminder to ask followup questions to the agent. The agent is their teacher, and can assist with anything that's unclear.
55
+
56
+ ## Assets
57
+
58
+ Lessons are built from reusable **components**, stored in `./assets/`: stylesheets, quiz widgets, simulators, diagram helpers — anything a second lesson could reuse.
59
+
60
+ Reuse is the default, not the exception. Before authoring a lesson, read `./assets/` and build from the components already there. When a lesson needs something new and reusable, write it as a component in `./assets/` and link to it — never inline code a future lesson would duplicate.
61
+
62
+ A shared stylesheet is the first component every workspace earns: every lesson links it, so the lessons look like one consistent course rather than a pile of one-offs. As the workspace grows, so should the component library.
63
+
64
+ ## CRITICAL: Never trust parametric knowledge
65
+
66
+ Ground every lesson in high-quality resources tracked in `RESOURCES.md`, with citations — never the model's pretrained memory. Pin down the mission before teaching: if the user is unclear about the mission or `MISSION.md` is unpopulated, questioning the user on why they want to learn is the first job.
67
+
68
+ ## The Mission
69
+
70
+ Every lesson should be tied into the mission - the reason that the user is interested in learning about the topic.
71
+
72
+ If the user is unclear about the mission, or the `MISSION.md` is not populated, first ask directly in the conversation why they want to learn this. Offer common motivations with a recommendation where useful, and wait for their reply before planning lessons.
73
+
74
+ Failing to understand the mission will mean knowledge acquisition is not grounded in real-world goals. Lessons will feel too abstract. You will have no way of judging what the user should do next.
75
+
76
+ Missions may change as the user develops more skills and knowledge. This is normal - make sure to update the `MISSION.md` and add a learning record to capture the change. Confirm with the user before changing the mission.
77
+
78
+ ## Zone Of Proximal Development
79
+
80
+ Each lesson, the user should always feel as if they are being challenged 'just enough'.
81
+
82
+ The user may specify an exact thing they want to learn. If they don't, figure out their zone of proximal development by:
83
+
84
+ - Reading their `learning-records`
85
+ - Figuring out the right thing to teach them based on their mission
86
+ - Teach the most relevant thing that fits in their zone of proximal development
87
+
88
+ ## Knowledge
89
+
90
+ Lessons should be designed around a skill the user is going to learn. The knowledge in the lesson should be only what's required to acquire that skill. You teach the knowledge first, then get the user to practice the skills via an interactive feedback loop.
91
+
92
+ Knowledge should first be gathered from trusted resources. Use `RESOURCES.md` to keep track of them. Lessons should be littered with citations - links to external resources to back up any claim made. This increases the trustworthiness of the lesson.
93
+
94
+ For acquiring knowledge, difficulty is the enemy. It eats working memory you need for understanding.
95
+
96
+ ## Skills
97
+
98
+ If knowledge is all about acquisition, skills are about durability and flexibility. Make the knowledge stick.
99
+
100
+ For skill acquisition, difficulty is the tool. Effortful retrieval is what builds storage strength. Skills should be taught through interactive lessons. There are several tools at your disposal:
101
+
102
+ - Interactive lessons, using quizzes and light in-browser tasks
103
+ - Lessons which guide the user through a list of real-world steps to take (for instance, yoga poses)
104
+
105
+ Each of these should be based on a **feedback loop**, where the user receives feedback on their performance. This feedback loop should be as tight as possible, giving feedback immediately - and ideally automatically.
106
+
107
+ For quizzes, each answer should be exactly the same number of words (and characters, if possible). Don't give the user any clues about the answer through formatting.
108
+
109
+ ## Acquiring Wisdom
110
+
111
+ Wisdom comes from true real-world interaction - testing your skills outside the learning environment.
112
+
113
+ When the user asks a question that appears to require wisdom, your default posture should be to attempt to answer - but to ultimately delegate to a **community**.
114
+
115
+ A community is a place (online or offline) where the user can test their skills in the real world. This might be a forum, a subreddit, a real-world class (budget permitting) or a local interest group.
116
+
117
+ Attempt to find high-reputation communities the user can join. If the user expresses a preference not to join a community, respect it.
118
+
119
+ ## Reference Documents
120
+
121
+ While creating lessons, you should also create reference documents. Lessons can reference these documents - they are useful for tracking raw units of knowledge useful across lessons.
122
+
123
+ Lessons will rarely be revisited later - reference documents will be. They should be the compressed essence of the lesson, in a format designed for quick reference.
124
+
125
+ Some learning topics lend themselves to reference:
126
+
127
+ - Syntax and code snippets for programming
128
+ - Algorithms and flowcharts for processes
129
+ - Yoga poses and sequences for yoga
130
+ - Exercises and routines for fitness
131
+ - Glossaries for any topic with its own nomenclature
132
+
133
+ Glossaries, in particular, are an essential reference. Once one is created, it should be adhered to in every lesson.
134
+
135
+ ## `NOTES.md`
136
+
137
+ The user will sometimes express preferences of how they want to be taught, or things you should keep in mind. This is the place to record those preferences, so you can refer back to them when designing lessons or working with the user.