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.
- package/LICENSE +27 -0
- package/README.md +38 -0
- package/TODO.md +11 -0
- package/index.ts +1 -0
- package/package.json +44 -0
- package/procedures/ADR-FORMAT.md +47 -0
- package/procedures/AGENT-BRIEF.md +207 -0
- package/procedures/CONTEXT-FORMAT.md +60 -0
- package/procedures/DEEPENING.md +37 -0
- package/procedures/DESIGN-IT-TWICE.md +44 -0
- package/procedures/GLOSSARY-FORMAT.md +35 -0
- package/procedures/GLOSSARY.md +201 -0
- package/procedures/HTML-REPORT.md +123 -0
- package/procedures/LEARNING-RECORD-FORMAT.md +46 -0
- package/procedures/LOGIC.md +79 -0
- package/procedures/MISSION-FORMAT.md +31 -0
- package/procedures/OUT-OF-SCOPE.md +105 -0
- package/procedures/RESOURCES-FORMAT.md +32 -0
- package/procedures/SKILL-MECHANICS.md +22 -0
- package/procedures/UI.md +112 -0
- package/procedures/bdd-best-practices.md +68 -0
- package/procedures/bdd.md +98 -0
- package/procedures/code-review.md +111 -0
- package/procedures/codebase-design.md +113 -0
- package/procedures/diagnosing-bugs.md +139 -0
- package/procedures/domain-modeling.md +73 -0
- package/procedures/domain.md +51 -0
- package/procedures/gherkin-guide.md +109 -0
- package/procedures/grill-me.md +5 -0
- package/procedures/grill-with-docs.md +5 -0
- package/procedures/grilling.md +11 -0
- package/procedures/handoff.md +13 -0
- package/procedures/hitl-loop.template.sh +44 -0
- package/procedures/implement.md +13 -0
- package/procedures/improve-codebase-architecture.md +69 -0
- package/procedures/issue-tracker-github.md +45 -0
- package/procedures/issue-tracker-gitlab.md +46 -0
- package/procedures/issue-tracker-local.md +30 -0
- package/procedures/mocking.md +59 -0
- package/procedures/phase-boundaries.md +55 -0
- package/procedures/prototype.md +25 -0
- package/procedures/research.md +11 -0
- package/procedures/resolving-merge-conflicts.md +13 -0
- package/procedures/setup-matt-pocock-skills.md +114 -0
- package/procedures/tdd.md +60 -0
- package/procedures/teach.md +137 -0
- package/procedures/template.sh +204 -0
- package/procedures/testing-anti-patterns.md +37 -0
- package/procedures/tests.md +77 -0
- package/procedures/to-questionnaire.md +47 -0
- package/procedures/to-spec.md +77 -0
- package/procedures/to-tickets.md +97 -0
- package/procedures/triage-labels.md +15 -0
- package/procedures/triage.md +110 -0
- package/procedures/wait-what.md +1 -0
- package/procedures/wayfinder.md +127 -0
- package/procedures/wizard.md +39 -0
- package/procedures/writing-for-agents.md +76 -0
- package/procedures/writing-great-skills.md +81 -0
- package/src/index.ts +485 -0
- package/src/procedures.ts +33 -0
- 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.
|