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
package/LICENSE ADDED
@@ -0,0 +1,27 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Matt Pocock
4
+ Copyright (c) 2025 Jesse Vincent
5
+ Copyright (c) 2026 Frad LEE
6
+
7
+ # Forked from mattpocock/skills v1.2.0 (MIT) — https://github.com/mattpocock/skills
8
+ # Retained superpowers code (lib/jsonl-emit.sh, lib/seed-checklists.sh,
9
+ # retrospective references) carries Jesse Vincent's copyright per MIT.
10
+
11
+ Permission is hereby granted, free of charge, to any person obtaining a copy
12
+ of this software and associated documentation files (the "Software"), to deal
13
+ in the Software without restriction, including without limitation the rights
14
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
+ copies of the Software, and to permit persons to whom the Software is
16
+ furnished to do so, subject to the following conditions:
17
+
18
+ The above copyright notice and this permission notice shall be included in all
19
+ copies or substantial portions of the Software.
20
+
21
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,38 @@
1
+ # Matt Pocock for Pi
2
+
3
+ `pi-matt-pocock` is a Pi extension that provides `/matt-pocock`: a persisted
4
+ workflow harness for BDD-first engineering and productivity procedures adapted
5
+ from `mattpocock/skills`.
6
+
7
+ ## Installation
8
+
9
+ This package has not yet been released to npm. Install it from a local checkout:
10
+
11
+ ```bash
12
+ pi install /path/to/pi-packages/packages/matt-pocock
13
+ ```
14
+
15
+ It will be published as `pi-matt-pocock` after its first-release bootstrap.
16
+
17
+ ## Workflow harness
18
+
19
+ `/matt-pocock` opens one routing menu:
20
+
21
+ - Start an idea-to-ship flow
22
+ - Diagnose a hard bug
23
+ - Triage incoming work
24
+ - Map a large ambiguous initiative
25
+ - Improve codebase architecture
26
+ - View, transition, or end the current workflow
27
+
28
+ The harness injects only the chosen procedure, persists its current route and
29
+ phase in the Pi session, restores that state on restart, and adds concise
30
+ phase guidance to agent turns. Its structured interview tool is available only
31
+ while a workflow is active, so ordinary questions remain in the conversation.
32
+ When a procedure's done condition makes its next procedure clear, the agent transitions with `matt_pocock_workflow` and continues without waiting for permission. It pauses only for a user-owned decision, unavailable fact, or required external action. The menu's transition option remains available for an explicit user override.
33
+
34
+ Procedures are internal Markdown resources rather than Pi skills, so generic
35
+ workflow names such as `tdd`, `code-review`, and `research` never collide with
36
+ an installed skill collection.
37
+
38
+ See [TODO.md](TODO.md) for lifecycle automation that remains deliberately deferred.
package/TODO.md ADDED
@@ -0,0 +1,11 @@
1
+ # Deferred automation
2
+
3
+ The harness already directs the agent to transition immediately when a
4
+ procedure's done condition makes the next applicable procedure clear. These
5
+ remaining lifecycle capabilities need dedicated runtime support:
6
+
7
+ - [ ] Automatically create a new Pi session for a workflow phase.
8
+ - [ ] Automatically create teammates for workflow research or review.
9
+ - [ ] Enforce BDD/TDD through tool-level production-write blocking.
10
+ - [ ] Add one Pi command per workflow.
11
+ - [ ] Add a second public `/skill:matt-pocock` surface.
package/index.ts ADDED
@@ -0,0 +1 @@
1
+ export { default } from "./src/index.ts";
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "pi-matt-pocock",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "description": "BDD-first engineering and productivity skills adapted from Matt Pocock's skills",
6
+ "keywords": [
7
+ "pi-package",
8
+ "bdd",
9
+ "tdd",
10
+ "engineering",
11
+ "code-review",
12
+ "planning",
13
+ "productivity"
14
+ ],
15
+ "author": "Frad LEE <fradser@gmail.com>",
16
+ "license": "MIT",
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "https://github.com/FradSer/pi-packages.git"
20
+ },
21
+ "publishConfig": {
22
+ "access": "public"
23
+ },
24
+ "files": [
25
+ "index.ts",
26
+ "src",
27
+ "procedures",
28
+ "TODO.md",
29
+ "LICENSE",
30
+ "README.md"
31
+ ],
32
+ "peerDependencies": {
33
+ "@earendil-works/pi-coding-agent": "*",
34
+ "@earendil-works/pi-tui": "*"
35
+ },
36
+ "dependencies": {
37
+ "@fradser/pi-kit": "workspace:*"
38
+ },
39
+ "pi": {
40
+ "extensions": [
41
+ "./index.ts"
42
+ ]
43
+ }
44
+ }
@@ -0,0 +1,47 @@
1
+ # ADR Format
2
+
3
+ ADRs live in `docs/adr/` and use sequential numbering: `0001-slug.md`, `0002-slug.md`, etc.
4
+
5
+ Create the `docs/adr/` directory lazily — only when the first ADR is needed.
6
+
7
+ ## Template
8
+
9
+ ```md
10
+ # {Short title of the decision}
11
+
12
+ {1-3 sentences: what's the context, what did we decide, and why.}
13
+ ```
14
+
15
+ That's it. An ADR can be a single paragraph. The value is in recording *that* a decision was made and *why* — not in filling out sections.
16
+
17
+ ## Optional sections
18
+
19
+ Only include these when they add genuine value. Most ADRs won't need them.
20
+
21
+ - **Status** frontmatter (`proposed | accepted | deprecated | superseded by ADR-NNNN`) — useful when decisions are revisited
22
+ - **Considered Options** — only when the rejected alternatives are worth remembering
23
+ - **Consequences** — only when non-obvious downstream effects need to be called out
24
+
25
+ ## Numbering
26
+
27
+ Scan `docs/adr/` for the highest existing number and increment by one.
28
+
29
+ ## When to offer an ADR
30
+
31
+ All three of these must be true:
32
+
33
+ 1. **Hard to reverse** — the cost of changing your mind later is meaningful
34
+ 2. **Surprising without context** — a future reader will look at the code and wonder "why on earth did they do it this way?"
35
+ 3. **The result of a real trade-off** — there were genuine alternatives and you picked one for specific reasons
36
+
37
+ If a decision is easy to reverse, skip it — you'll just reverse it. If it's not surprising, nobody will wonder why. If there was no real alternative, there's nothing to record beyond "we did the obvious thing."
38
+
39
+ ### What qualifies
40
+
41
+ - **Architectural shape.** "We're using a monorepo." "The write model is event-sourced, the read model is projected into Postgres."
42
+ - **Integration patterns between contexts.** "Ordering and Billing communicate via domain events, not synchronous HTTP."
43
+ - **Technology choices that carry lock-in.** Database, message bus, auth provider, deployment target. Not every library — just the ones that would take a quarter to swap out.
44
+ - **Boundary and scope decisions.** "Customer data is owned by the Customer context; other contexts reference it by ID only." The explicit no-s are as valuable as the yes-s.
45
+ - **Deliberate deviations from the obvious path.** "We're using manual SQL instead of an ORM because X." Anything where a reasonable reader would assume the opposite. These stop the next engineer from "fixing" something that was deliberate.
46
+ - **Constraints not visible in the code.** "We can't use AWS because of compliance requirements." "Response times must be under 200ms because of the partner API contract."
47
+ - **Rejected alternatives when the rejection is non-obvious.** If you considered GraphQL and picked REST for subtle reasons, record it — otherwise someone will suggest GraphQL again in six months.
@@ -0,0 +1,207 @@
1
+ # Writing Agent Briefs
2
+
3
+ An agent brief is a structured comment posted on a GitHub issue or PR when it moves to `ready-for-agent`. It is the authoritative specification that an AFK agent will work from. The original body and discussion are context — the agent brief is the contract.
4
+
5
+ The brief states **what the agent should do**, which stretches to both surfaces: for an issue, that's building the change from nothing; for a PR, it's what's left to do *to the existing diff* — finish it, close gaps, address review points. Same principles either way; the PR example below shows the difference.
6
+
7
+ ## Principles
8
+
9
+ ### Durability over precision
10
+
11
+ The issue may sit in `ready-for-agent` for days or weeks. The codebase will change in the meantime. Write the brief so it stays useful even as files are renamed, moved, or refactored.
12
+
13
+ - **Do** describe interfaces, types, and behavioral contracts
14
+ - **Do** name specific types, function signatures, or config shapes that the agent should look for or modify
15
+ - **Don't** reference file paths — they go stale
16
+ - **Don't** reference line numbers
17
+ - **Don't** assume the current implementation structure will remain the same
18
+
19
+ ### Behavioral, not procedural
20
+
21
+ Describe **what** the system should do, not **how** to implement it. The agent will explore the codebase fresh and make its own implementation decisions.
22
+
23
+ - **Good:** "The `SkillConfig` type should accept an optional `schedule` field of type `CronExpression`"
24
+ - **Bad:** "Open src/types/skill.ts and add a schedule field on line 42"
25
+ - **Good:** "When a user runs [triage](triage.md) with no arguments, they should see a summary of issues needing attention"
26
+ - **Bad:** "Add a switch statement in the main handler function"
27
+
28
+ ### Complete acceptance criteria
29
+
30
+ The agent needs to know when it's done. Every agent brief must have concrete, testable acceptance criteria. Each criterion should be independently verifiable.
31
+
32
+ - **Good:** "Running `gh issue list --label needs-triage` returns issues that have been through initial classification"
33
+ - **Bad:** "Triage should work correctly"
34
+
35
+ ### Explicit scope boundaries
36
+
37
+ State what is out of scope. This prevents the agent from gold-plating or making assumptions about adjacent features.
38
+
39
+ ## Template
40
+
41
+ ```markdown
42
+ ## Agent Brief
43
+
44
+ **Category:** bug / enhancement
45
+ **Summary:** one-line description of what needs to happen
46
+
47
+ **Current behavior:**
48
+ Describe what happens now. For bugs, this is the broken behavior.
49
+ For enhancements, this is the status quo the feature builds on.
50
+
51
+ **Desired behavior:**
52
+ Describe what should happen after the agent's work is complete.
53
+ Be specific about edge cases and error conditions.
54
+
55
+ **Key interfaces:**
56
+ - `TypeName` — what needs to change and why
57
+ - `functionName()` return type — what it currently returns vs what it should return
58
+ - Config shape — any new configuration options needed
59
+
60
+ **Acceptance criteria:**
61
+ - [ ] Specific, testable criterion 1
62
+ - [ ] Specific, testable criterion 2
63
+ - [ ] Specific, testable criterion 3
64
+
65
+ **Out of scope:**
66
+ - Thing that should NOT be changed or addressed in this issue
67
+ - Adjacent feature that might seem related but is separate
68
+ ```
69
+
70
+ ## Examples
71
+
72
+ ### Good agent brief (bug)
73
+
74
+ ```markdown
75
+ ## Agent Brief
76
+
77
+ **Category:** bug
78
+ **Summary:** Skill description truncation drops mid-word, producing broken output
79
+
80
+ **Current behavior:**
81
+ When a skill description exceeds 1024 characters, it is truncated at exactly
82
+ 1024 characters regardless of word boundaries. This produces descriptions
83
+ that end mid-word (e.g. "Use when the user wants to confi").
84
+
85
+ **Desired behavior:**
86
+ Truncation should break at the last word boundary before 1024 characters
87
+ and append "..." to indicate truncation.
88
+
89
+ **Key interfaces:**
90
+ - The `SkillMetadata` type's `description` field — no type change needed,
91
+ but the validation/processing logic that populates it needs to respect
92
+ word boundaries
93
+ - Any function that reads triage.md frontmatter and extracts the description
94
+
95
+ **Acceptance criteria:**
96
+ - [ ] Descriptions under 1024 chars are unchanged
97
+ - [ ] Descriptions over 1024 chars are truncated at the last word boundary
98
+ before 1024 chars
99
+ - [ ] Truncated descriptions end with "..."
100
+ - [ ] The total length including "..." does not exceed 1024 chars
101
+
102
+ **Out of scope:**
103
+ - Changing the 1024 char limit itself
104
+ - Multi-line description support
105
+ ```
106
+
107
+ ### Good agent brief (enhancement)
108
+
109
+ ```markdown
110
+ ## Agent Brief
111
+
112
+ **Category:** enhancement
113
+ **Summary:** Add `.out-of-scope/` directory support for tracking rejected feature requests
114
+
115
+ **Current behavior:**
116
+ When a feature request is rejected, the issue is closed with a `wontfix` label
117
+ and a comment. There is no persistent record of the decision or reasoning.
118
+ Future similar requests require the maintainer to recall or search for the
119
+ prior discussion.
120
+
121
+ **Desired behavior:**
122
+ Rejected feature requests should be documented in `.out-of-scope/<concept>.md`
123
+ files that capture the decision, reasoning, and links to all issues that
124
+ requested the feature. When triaging new issues, these files should be
125
+ checked for matches.
126
+
127
+ **Key interfaces:**
128
+ - Markdown file format in `.out-of-scope/` — each file should have a
129
+ `# Concept Name` heading, a `**Decision:**` line, a `**Reason:**` line,
130
+ and a `**Prior requests:**` list with issue links
131
+ - The triage workflow should read all `.out-of-scope/*.md` files early
132
+ and match incoming issues against them by concept similarity
133
+
134
+ **Acceptance criteria:**
135
+ - [ ] Closing a feature as wontfix creates/updates a file in `.out-of-scope/`
136
+ - [ ] The file includes the decision, reasoning, and link to the closed issue
137
+ - [ ] If a matching `.out-of-scope/` file already exists, the new issue is
138
+ appended to its "Prior requests" list rather than creating a duplicate
139
+ - [ ] During triage, existing `.out-of-scope/` files are checked and surfaced
140
+ when a new issue matches a prior rejection
141
+
142
+ **Out of scope:**
143
+ - Automated matching (human confirms the match)
144
+ - Reopening previously rejected features
145
+ - Bug reports (only enhancement rejections go to `.out-of-scope/`)
146
+ ```
147
+
148
+ ### Good agent brief (PR)
149
+
150
+ For a PR, "Current behavior" describes the state of the diff, and the brief asks the agent to finish or fix it rather than build from scratch.
151
+
152
+ ```markdown
153
+ ## Agent Brief
154
+
155
+ **Category:** enhancement
156
+ **Summary:** Finish the contributor's `--json` output flag for `triage list`
157
+
158
+ **Current behavior:**
159
+ The PR adds a `--json` flag that serializes the issue list to JSON. The happy
160
+ path works and the diff matches the project's command structure. Two gaps
161
+ remain: errors are still printed as human text (not JSON), and the new flag has
162
+ no test coverage.
163
+
164
+ **Desired behavior:**
165
+ With `--json`, all output — including errors — is well-formed JSON on stdout,
166
+ and the command's exit codes are unchanged. The existing human-readable output
167
+ is untouched when the flag is absent.
168
+
169
+ **Key interfaces:**
170
+ - The command's error path should emit `{ "error": string }` under `--json`
171
+ instead of the plain-text error
172
+ - Reuse the existing serializer the PR already added; don't introduce a second
173
+
174
+ **Acceptance criteria:**
175
+ - [ ] `triage list --json` emits valid JSON for both success and error cases
176
+ - [ ] Exit codes match the non-JSON command
177
+ - [ ] A test covers the `--json` success output and one error case
178
+ - [ ] Default (non-JSON) output is byte-for-byte unchanged
179
+
180
+ **Out of scope:**
181
+ - Adding `--json` to any other command
182
+ - Changing the JSON shape of the success payload the PR already defined
183
+ ```
184
+
185
+ ### Bad agent brief
186
+
187
+ ```markdown
188
+ ## Agent Brief
189
+
190
+ **Summary:** Fix the triage bug
191
+
192
+ **What to do:**
193
+ The triage thing is broken. Look at the main file and fix it.
194
+ The function around line 150 has the issue.
195
+
196
+ **Files to change:**
197
+ - src/triage/handler.ts (line 150)
198
+ - src/types.ts (line 42)
199
+ ```
200
+
201
+ This is bad because:
202
+ - No category
203
+ - Vague description ("the triage thing is broken")
204
+ - References file paths and line numbers that will go stale
205
+ - No acceptance criteria
206
+ - No scope boundaries
207
+ - No description of current vs desired behavior
@@ -0,0 +1,60 @@
1
+ # CONTEXT.md Format
2
+
3
+ ## Structure
4
+
5
+ ```md
6
+ # {Context Name}
7
+
8
+ {One or two sentence description of what this context is and why it exists.}
9
+
10
+ ## Language
11
+
12
+ **Order**:
13
+ {A one or two sentence description of the term}
14
+ _Avoid_: Purchase, transaction
15
+
16
+ **Invoice**:
17
+ A request for payment sent to a customer after delivery.
18
+ _Avoid_: Bill, payment request
19
+
20
+ **Customer**:
21
+ A person or organization that places orders.
22
+ _Avoid_: Client, buyer, account
23
+ ```
24
+
25
+ ## Rules
26
+
27
+ - **Be opinionated.** When multiple words exist for the same concept, pick the best one and list the others under `_Avoid_`.
28
+ - **Keep definitions tight.** One or two sentences max. Define what it IS, not what it does.
29
+ - **Only include terms specific to this project's context.** General programming concepts (timeouts, error types, utility patterns) don't belong even if the project uses them extensively. Before adding a term, ask: is this a concept unique to this context, or a general programming concept? Only the former belongs.
30
+ - **Group terms under subheadings** when natural clusters emerge. If all terms belong to a single cohesive area, a flat list is fine.
31
+
32
+ ## Single vs multi-context repos
33
+
34
+ **Single context (most repos):** One `CONTEXT.md` at the repo root.
35
+
36
+ **Multiple contexts:** A `CONTEXT-MAP.md` at the repo root lists the contexts, where they live, and how they relate to each other:
37
+
38
+ ```md
39
+ # Context Map
40
+
41
+ ## Contexts
42
+
43
+ - [Ordering](./src/ordering/CONTEXT.md) — receives and tracks customer orders
44
+ - [Billing](./src/billing/CONTEXT.md) — generates invoices and processes payments
45
+ - [Fulfillment](./src/fulfillment/CONTEXT.md) — manages warehouse picking and shipping
46
+
47
+ ## Relationships
48
+
49
+ - **Ordering → Fulfillment**: Ordering emits `OrderPlaced` events; Fulfillment consumes them to start picking
50
+ - **Fulfillment → Billing**: Fulfillment emits `ShipmentDispatched` events; Billing consumes them to generate invoices
51
+ - **Ordering ↔ Billing**: Shared types for `CustomerId` and `Money`
52
+ ```
53
+
54
+ The skill infers which structure applies:
55
+
56
+ - If `CONTEXT-MAP.md` exists, read it to find contexts
57
+ - If only a root `CONTEXT.md` exists, single context
58
+ - If neither exists, create a root `CONTEXT.md` lazily when the first term is resolved
59
+
60
+ When multiple contexts exist, infer which one the current topic relates to. If unclear, ask.
@@ -0,0 +1,37 @@
1
+ # Deepening
2
+
3
+ How to deepen a cluster of shallow modules safely, given its dependencies. Assumes the vocabulary in [codebase-design.md](codebase-design.md) — **module**, **interface**, **seam**, **adapter**.
4
+
5
+ ## Dependency categories
6
+
7
+ When assessing a candidate for deepening, classify its dependencies. The category determines how the deepened module is tested across its seam.
8
+
9
+ ### 1. In-process
10
+
11
+ Pure computation, in-memory state, no I/O. Always deepenable — merge the modules and test through the new interface directly. No adapter needed.
12
+
13
+ ### 2. Local-substitutable
14
+
15
+ Dependencies that have local test stand-ins (PGLite for Postgres, in-memory filesystem). Deepenable if the stand-in exists. The deepened module is tested with the stand-in running in the test suite. The seam is internal; no port at the module's external interface.
16
+
17
+ ### 3. Remote but owned (Ports & Adapters)
18
+
19
+ Your own services across a network boundary (microservices, internal APIs). Define a **port** (interface) at the seam. The deep module owns the logic; the transport is injected as an **adapter**. Tests use an in-memory adapter. Production uses an HTTP/gRPC/queue adapter.
20
+
21
+ Recommendation shape: *"Define a port at the seam, implement an HTTP adapter for production and an in-memory adapter for testing, so the logic sits in one deep module even though it's deployed across a network."*
22
+
23
+ ### 4. True external (Mock)
24
+
25
+ Third-party services (Stripe, Twilio, etc.) you don't control. The deepened module takes the external dependency as an injected port; tests provide a mock adapter.
26
+
27
+ ## Seam discipline
28
+
29
+ - **One adapter means a hypothetical seam. Two adapters means a real one.** Don't introduce a port unless at least two adapters are justified (typically production + test). A single-adapter seam is just indirection.
30
+ - **Internal seams vs external seams.** A deep module can have internal seams (private to its implementation, used by its own tests) as well as the external seam at its interface. Don't expose internal seams through the interface just because tests use them.
31
+
32
+ ## Testing strategy: replace, don't layer
33
+
34
+ - Old unit tests on shallow modules become waste once tests at the deepened module's interface exist — delete them.
35
+ - Write new tests at the deepened module's interface. The **interface is the test surface**.
36
+ - Tests assert on observable outcomes through the interface, not internal state.
37
+ - Tests should survive internal refactors — they describe behaviour, not implementation. If a test has to change when the implementation changes, it's testing past the interface.
@@ -0,0 +1,44 @@
1
+ # Design It Twice
2
+
3
+ When the user wants to explore alternative interfaces for a chosen deepening candidate, compare distinct designs. Use parallel teammates only when the teammate facility is available; otherwise work through the designs sequentially. Based on "Design It Twice" (Ousterhout) — your first idea is unlikely to be the best.
4
+
5
+ Uses the vocabulary in [codebase-design.md](codebase-design.md) — **module**, **interface**, **seam**, **adapter**, **leverage**.
6
+
7
+ ## Process
8
+
9
+ ### 1. Frame the problem space
10
+
11
+ Before beginning the design comparisons, write a user-facing explanation of the problem space for the chosen candidate:
12
+
13
+ - The constraints any new interface would need to satisfy
14
+ - The dependencies it would rely on, and which category they fall into (see [DEEPENING.md](DEEPENING.md))
15
+ - A rough illustrative code sketch to ground the constraints — not a proposal, just a way to make the constraints concrete
16
+
17
+ Show this to the user, then immediately proceed to Step 2. The user reads and thinks while the comparisons are prepared.
18
+
19
+ ### 2. Produce distinct designs
20
+
21
+ Produce 3+ **radically different** interfaces for the deepened module. If the teammate facility is available, delegate the independent briefs to separate teammates and compare their reports; otherwise produce the designs sequentially in the current context.
22
+
23
+ Give each design brief the file paths, coupling details, dependency category from [DEEPENING.md](DEEPENING.md), and what sits behind the seam. Keep it independent of the user-facing problem-space explanation in Step 1. Use a different constraint for each design:
24
+
25
+ - Design 1: "Minimize the interface — aim for 1–3 entry points max. Maximise leverage per entry point."
26
+ - Design 2: "Maximise flexibility — support many use cases and extension."
27
+ - Design 3: "Optimise for the most common caller — make the default case trivial."
28
+ - Design 4 (if applicable): "Design around ports & adapters for cross-seam dependencies."
29
+
30
+ Include both [codebase-design.md](codebase-design.md) vocabulary and CONTEXT.md vocabulary in each brief so the designs name things consistently with the architecture language and the project's domain language.
31
+
32
+ Each design outputs:
33
+
34
+ 1. Interface (types, methods, params — plus invariants, ordering, error modes)
35
+ 2. Usage example showing how callers use it
36
+ 3. What the implementation hides behind the seam
37
+ 4. Dependency strategy and adapters (see [DEEPENING.md](DEEPENING.md))
38
+ 5. Trade-offs — where leverage is high, where it's thin
39
+
40
+ ### 3. Present and compare
41
+
42
+ Present designs sequentially so the user can absorb each one, then compare them in prose. Contrast by **depth** (leverage at the interface), **locality** (where change concentrates), and **seam placement**.
43
+
44
+ After comparing, give your own recommendation: which design you think is strongest and why. If elements from different designs would combine well, propose a hybrid. Be opinionated — the user wants a strong read, not a menu.
@@ -0,0 +1,35 @@
1
+ # GLOSSARY.md Format
2
+
3
+ `GLOSSARY.md` is the canonical language for this teaching workspace. All explainers, exercises, and learning records should adhere to its terminology. Building it is itself part of learning: compressing a concept into a tight definition is evidence the user understands it.
4
+
5
+ ## Structure
6
+
7
+ ```md
8
+ # {Topic} Glossary
9
+
10
+ {One or two sentence description of the topic this glossary covers.}
11
+
12
+ ## Terms
13
+
14
+ **Hypertrophy**:
15
+ Muscle growth driven by mechanical tension and metabolic stress over repeated training sessions.
16
+ _Avoid_: Bulking, getting big
17
+
18
+ **Progressive overload**:
19
+ Systematically increasing the demand on a muscle over time — via load, volume, or intensity.
20
+ _Avoid_: Pushing harder, levelling up
21
+
22
+ **RPE (Rate of Perceived Exertion)**:
23
+ A 1–10 self-rating of how hard a set felt, where 10 is failure and 8 means two reps left in the tank.
24
+ _Avoid_: Effort score, intensity rating
25
+ ```
26
+
27
+ ## Rules
28
+
29
+ - **Add a term only when the user understands it.** The glossary is a record of compressed knowledge, not a dictionary the user reads to learn. If the user has just been introduced to a concept, wait until they can use it correctly before promoting it here.
30
+ - **Be opinionated.** When several words exist for the same concept, pick the best one and list the rest as aliases to avoid. This is how language compresses.
31
+ - **Keep definitions tight.** One or two sentences. Define what the term IS, not what it does or how to do it.
32
+ - **Use the glossary's own terms inside definitions.** Once a term is in the glossary, prefer it everywhere — including inside other definitions. This is what makes complex terms easier to grasp later.
33
+ - **Group under subheadings** when natural clusters emerge (e.g. `## Anatomy`, `## Programming`). A flat list is fine when terms cohere.
34
+ - **Flag ambiguities explicitly.** If a term is used loosely in the wider field, note the resolution: "In this workspace, 'set' always means a working set — warm-ups are tracked separately."
35
+ - **Revise as understanding deepens.** A definition the user wrote in week one may be wrong by week six. Update in place; do not leave stale entries.