@epicparty/skills 0.0.0-stage → 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 +21 -0
- package/NOTICE +27 -0
- package/README.md +109 -2
- package/bin/cli.mjs +175 -0
- package/lib/transform.mjs +185 -0
- package/package.json +37 -4
- package/skills/architect/DESIGN-IT-TWICE.md +46 -0
- package/skills/architect/HTML-REPORT.md +126 -0
- package/skills/architect/SKILL.md +101 -0
- package/skills/babysit/SKILL.md +164 -0
- package/skills/code-review/SKILL.md +111 -0
- package/skills/copy/COPY.md +142 -0
- package/skills/copy/SKILL.md +87 -0
- package/skills/deliver/SKILL.md +259 -0
- package/skills/diagnose/SKILL.md +114 -0
- package/skills/diagnose/scripts/hitl-loop.template.sh +44 -0
- package/skills/explore/SKILL.md +78 -0
- package/skills/grill/SKILL.md +75 -0
- package/skills/implement/SKILL.md +132 -0
- package/skills/implement/TDD.md +131 -0
- package/skills/implement/TEST-VALUE.md +114 -0
- package/skills/outdated/SKILL.md +125 -0
- package/skills/research/SKILL.md +115 -0
- package/skills/router/BOARD.md +157 -0
- package/skills/router/DECISIONS.md +71 -0
- package/skills/router/GIT.md +70 -0
- package/skills/router/GLOSSARY-FORMAT.md +48 -0
- package/skills/router/SKILL.md +251 -0
- package/skills/setup/SKILL.md +99 -0
- package/skills/ship/SKILL.md +132 -0
- package/skills/to-pr/SKILL.md +88 -0
- package/skills/to-story/SEAMS.md +51 -0
- package/skills/to-story/SKILL.md +79 -0
- package/skills/to-story/SPLITTING.md +53 -0
- package/skills/to-story/STORIES.md +179 -0
- package/skills/triage/SKILL.md +179 -0
- package/skills/upgrade/SKILL.md +139 -0
- package/skills/writing-for-agents/SKILL-MECHANICS.md +24 -0
- package/skills/writing-for-agents/SKILL.md +88 -0
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: router
|
|
3
|
+
description: Ask what to do with a request, and get walked through it. The router over the ep-* skills. `/ep handoff` hands the thread to a fresh agent.
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
metadata:
|
|
6
|
+
pack: epicparty/skills
|
|
7
|
+
version: 0.1.0
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# EP
|
|
11
|
+
|
|
12
|
+
A request arrives — a feature, a bug, a half-formed idea, a question. `/ep` reads its **shape**, names the **route** through the `ep-*` skills, and walks that route to the end.
|
|
13
|
+
|
|
14
|
+
The user asked for their thing done. Routing is your job.
|
|
15
|
+
|
|
16
|
+
Called as `/ep handoff`, skip to [Hand off](#hand-off).
|
|
17
|
+
|
|
18
|
+
**The route's destination is one merged PR, deployed, and a clean default branch to start the next task from** — unless the request was a question. Everything below is sized to that.
|
|
19
|
+
|
|
20
|
+
## 1. Read the shape
|
|
21
|
+
|
|
22
|
+
Three facts decide the route, and all are cheap to establish:
|
|
23
|
+
|
|
24
|
+
- **Provenance** — does an issue already describe this work? The user may not know. When they named none, search the tracker with the request's own nouns, closed issues included. The tracker is the **Tracker** setting when the settings home has one — read it, never ask for it — or GitHub when `gh repo view` finds the repo; with neither, say no tracker was searched. On GitHub: `gh issue list --search "<keywords>" --state all`, then `gh issue view <n> --comments` on a hit. A hit describing the same work is the provenance; an adjacent one is context. An issue that already specs the work is a grilling you do not need to run.
|
|
25
|
+
- **Where it lands** — the product, package or area of the project the work belongs to, in the glossary's words. A request that names the wrong one, or none where several fit, gets that settled before anything else.
|
|
26
|
+
- **What is unsettled** — the decisions this work turns on that nobody has made. A request with none is buildable now. A request with a few gets them asked, one at a time ([Working rules](#working-rules)); only one whose decisions turn on each other has earned a grilling.
|
|
27
|
+
|
|
28
|
+
When the request touches code you have not read this session, run `/ep-explore` to establish them. It is the default first move, not an optional one, and its brief counts for the route: a route that starts at `/ep-explore` continues from that brief rather than running it again.
|
|
29
|
+
|
|
30
|
+
Done when you can name the issue this work came from or say it has none, name where it lands, and list what is still unsettled.
|
|
31
|
+
|
|
32
|
+
## 2. Pick the route
|
|
33
|
+
|
|
34
|
+
| What arrived | The route |
|
|
35
|
+
| --- | --- |
|
|
36
|
+
| An idea you want stress-tested before anyone builds it | `/ep-grill` → `/ep-to-story` → `/ep-triage` → `/ep-implement` → `/ep-to-pr` → `/ep-ship` |
|
|
37
|
+
| A feature understood well enough to build | `/ep-explore` → `/ep-to-story` → `/ep-triage` → `/ep-implement` → `/ep-to-pr` → `/ep-ship` |
|
|
38
|
+
| An issue already written and Ready | `/ep-implement` → `/ep-to-pr` → `/ep-ship` |
|
|
39
|
+
| An issue you are not sure is still right — old, thin, or mislabelled | `/ep-triage`, then the route its verdict names |
|
|
40
|
+
| Small and obvious — one seam, no decisions | `/ep-implement` → `/ep-to-pr` → `/ep-ship` |
|
|
41
|
+
| Something is broken, failing or slow | `/ep-diagnose` — a loop that goes **red** on the bug before any theorising — then `/ep-to-pr` → `/ep-ship` |
|
|
42
|
+
| A feature whose shape is the question — new modules, seams nobody has placed, a design to judge | `/ep-explore` → `/ep-architect` → `/ep-to-story` → `/ep-triage` → `/ep-implement` → `/ep-to-pr` → `/ep-ship` |
|
|
43
|
+
| Code in a named area that is hard to change or test | `/ep-architect`'s area scan, then the chosen refactor rejoins at `/ep-to-story` |
|
|
44
|
+
| A question about facts outside this repo | `/ep-research`. Ends in findings, and a published note when they are worth keeping, not a PR |
|
|
45
|
+
| A question about this codebase | `/ep-explore`, then answer. Ends in an answer, not a PR — say so rather than inventing work |
|
|
46
|
+
| What is outdated, or what a new release brings | `/ep-outdated`. Ends in a report, not a PR |
|
|
47
|
+
| Dependencies to upgrade — named packages, or all of them | `/ep-upgrade` → `/ep-to-pr` → `/ep-ship`. No story |
|
|
48
|
+
| A committed branch with no PR | `/ep-to-pr` → `/ep-ship` |
|
|
49
|
+
| An open PR that needs carrying to merged | `/ep-ship` |
|
|
50
|
+
| An idea to keep, not to build now — "save it as an idea" | A draft in the board's Ideas stage ([`BOARD.md`](./BOARD.md) `board_idea`). Ends in the draft, not a PR |
|
|
51
|
+
| "Check the board", "update the statuses" | [Checking the board](./BOARD.md#checking-the-board). Ends in a report of every card moved, not a PR |
|
|
52
|
+
| Several stories marked to start, or named together | `/ep-deliver` — the coordinator walks them in sequence or starts a worker per story, and prints where each one stands |
|
|
53
|
+
|
|
54
|
+
Where two rows fit, the unsettled decisions choose: decisions that turn on each other, and the request is an idea to grill; a few or none, and it is a feature to build, with the questions asked on the way. `/ep-triage` after `/ep-to-story` is quick — a story written to the bar earns its ready label in one pass — and it keeps the labels with the one skill that owns them.
|
|
55
|
+
|
|
56
|
+
Editing an existing issue needs no skill — the story rules in `/ep-to-story` govern it, and a story whose work is on the default branch is frozen.
|
|
57
|
+
|
|
58
|
+
Done when you can name the route and the property of the request that chose it.
|
|
59
|
+
|
|
60
|
+
A request that asks only for the route reads the shape from what is cheap — the tracker and the glossary, not a full `/ep-explore` — names the route, and stops. It asks no settings. Its report is § 5's shape at its smallest: the route and the property that chose it under **Details**, a one-line **TL;DR**, and **Your turn** with the open decisions, if any.
|
|
61
|
+
|
|
62
|
+
## 3. Tell the user the route
|
|
63
|
+
|
|
64
|
+
Before any of it starts, lay out what is about to happen to **their** request, in their terms: the stages in order, and where they have to be present live. A skill name is fine shorthand; reciting this file is not.
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
Here's the plan for the invite-links feature:
|
|
68
|
+
1. I'll ask you the three open decisions, one at a time, each with my recommendation.
|
|
69
|
+
2. Story from that conversation, published as one issue.
|
|
70
|
+
3. Implement it on a branch, test-first, and review the diff.
|
|
71
|
+
4. Open the PR, drive it to green, merge it, confirm the deploy landed, and put you back on a clean default branch.
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Name the settings the route's skills will ask for that are still unset, and ask them now, the way `/ep-setup` would for those skills: the walk then asks nothing, and the user is not called back mid-route for a one-line answer.
|
|
75
|
+
|
|
76
|
+
Flag the **HITL** stages hardest — the questions, and a grilling when the route has one, are worked *with* the user, and they stall silently when the user wanders off. An agent that answers its own questions has skipped the only part the user was needed for.
|
|
77
|
+
|
|
78
|
+
Done when every stage is named in order, the HITL ones are flagged as needing the user live, and the route's unset settings are answered or skipped.
|
|
79
|
+
|
|
80
|
+
## 4. Walk it
|
|
81
|
+
|
|
82
|
+
Follow the skills the route names, and keep the two rules that bind every route:
|
|
83
|
+
|
|
84
|
+
- **Context hygiene.** The questions, any grilling, and the story stay in one unbroken window, so both build on the same thinking. `/ep-implement` then starts fresh from the issue. [Hand off](#hand-off) when a thread fills before the story exists.
|
|
85
|
+
- **Re-route when the work says so.** A route is a reading of the request, and the request gets clearer as you work it. An "obvious" change that opens three decisions has earned its questions, and one whose decisions turn on each other has earned a grilling; fog that burns off in exploration drops straight to `/ep-to-story`. Say when you change route and why.
|
|
86
|
+
|
|
87
|
+
Every skill on a route reaches a skill by its name. Reading one off disk works too — following a skill you have read is the same as invoking it.
|
|
88
|
+
|
|
89
|
+
Done when every stage the route named has run, and any re-route is on the record with the property of the work that forced it.
|
|
90
|
+
|
|
91
|
+
## 5. Report
|
|
92
|
+
|
|
93
|
+
The shape is `/ep-ship` § 4 — **Details**, then **TL;DR**, then **Your turn** last, because the user reads the chat from the bottom — and a route that reached `/ep-ship` has already produced it. Add the route you walked and any re-route, then stop. The same report twice is one report and one restatement.
|
|
94
|
+
|
|
95
|
+
Every `ep-*` skill run alone that defines no report of its own ends in this shape too.
|
|
96
|
+
|
|
97
|
+
A route that ended anywhere else takes the same three sections at whatever size it earned: an answer, a research note's link, or a stage that stalled. Where it stalled, the details name the condition and who owns it, the TL;DR says so, and **Your turn** closes with what only they can unblock.
|
|
98
|
+
|
|
99
|
+
## Hand off
|
|
100
|
+
|
|
101
|
+
<!-- upstream: mattpocock/skills skills/productivity/handoff/SKILL.md -->
|
|
102
|
+
|
|
103
|
+
When a thread fills before the work reaches a durable home, write a **handoff document** a fresh agent can continue from. Words after `handoff` say what the next session is for; shape the document to that.
|
|
104
|
+
|
|
105
|
+
Read what the thread points at first — the issue, the branch — so you know what already lives somewhere durable. Where everything does, write nothing: say no handoff is needed, and name the next step.
|
|
106
|
+
|
|
107
|
+
- **Save it outside the checkout** — the session's scratch directory where the harness names one, else the OS temporary directory (`$TMPDIR`, else `/tmp`; `%TEMP%` on Windows).
|
|
108
|
+
- **Point, never copy.** An issue, a branch, a commit, an ADR or a brief already holds what it holds: reference it by URL or path.
|
|
109
|
+
- **Carry what lives only in this thread** — the decisions reached, the open questions, what was tried and ruled out, and the stage the route stopped at.
|
|
110
|
+
- **End with the next steps**: the remaining stages of the route, by skill name, so the next agent knows which to invoke. Where no route ran in this thread, take it from the table in § 2.
|
|
111
|
+
- **Redact** every key, password and piece of personal data.
|
|
112
|
+
|
|
113
|
+
Report in § 5's shape — the path, or why none was needed, and the next step — then stop.
|
|
114
|
+
|
|
115
|
+
Done when a fresh agent with only the document and the links in it could continue without asking what happened — or, with no document, with only the links you named.
|
|
116
|
+
|
|
117
|
+
## Vocabulary
|
|
118
|
+
|
|
119
|
+
Every `ep-*` skill on a route uses these four terms, and this is where they are defined.
|
|
120
|
+
|
|
121
|
+
- **Open question** — a call you made *for* the user: a trade-off you resolved on their behalf, a placement you would defend either way, an option they picked before you saw how it rendered, a line you drew around the work. It reaches the user before whatever ships the work. With a PR, it goes in your reply and in the PR body while the diff is open, and `/ep-babysit` holds the merge until it has an answer. Without one — a commit straight to the default branch — ask in your reply and hold the push until the user answers. After the ship it costs a whole PR to act on, so the same words read as commentary rather than a choice.
|
|
122
|
+
- **Sibling** — the same defect at a site the request did not name. It always raises an open question: whether it rides along is the user's scope call.
|
|
123
|
+
- **Small fix** — a fix that lands on the branch even when the branch did not cause the defect: it fixes a defect, adds no behaviour, needs no decision from the user, and fits in one commit the branch's own gate validates. It goes in as its own commit, and the PR body names it.
|
|
124
|
+
- **Found in passing** — the PR body's heading for every finding larger than a small fix, where the user sees it while the diff is open and decides whether it becomes a story. Off a branch, the finding goes in your reply before the push.
|
|
125
|
+
|
|
126
|
+
A finding earns a durable home in exactly four cases: the user asked for one, it becomes a story on the tracker, it is a decision that earns an ADR ([`DECISIONS.md`](./DECISIONS.md)), or it is context the project's agent files genuinely lack. Otherwise a new file or a new section is work nobody requested, nobody reviewed, and nobody maintains.
|
|
127
|
+
|
|
128
|
+
## Working rules
|
|
129
|
+
|
|
130
|
+
Every `ep-*` skill works by these, in every checkout.
|
|
131
|
+
|
|
132
|
+
- **Preserve work you did not write.** The tree may be dirty, and humans and other agents may write to it at the same time. A `git status` change after one of your commands does not prove you caused it. Before discarding any change you did not make — `git checkout --`, `git restore`, `git stash`, a reset — show that you caused it, show the diff, and ask. When in doubt, leave the tree alone.
|
|
133
|
+
- **Ask the decisions one at a time; grill only a tree.** Decisions only the user can make go to them **one question at a time**, through the harness's question tool where it has one — such as Claude Code's `AskUserQuestion` — and in plain chat where it has none. The user may answer one, leave, and come back to the next one waiting. Each question stands on its own: the context it needs inside the question, since the dialog may be all the user sees, and your recommended answer as the first option. The work waits for the answers, and that is the whole exchange. [`/ep-grill`](../grill/SKILL.md) runs only when the user asks for it, or when the decisions turn on each other so tightly that no list can be written up front — each answer would change the next questions.
|
|
134
|
+
- **Do not agree by default.** A flawed premise or a non-standard approach gets corrected when you see it, not after it is built.
|
|
135
|
+
- **No remote.** Where `git remote` lists none, the work ends in commits on a local branch, and `origin/<default>` reads as the local default branch. A skill that pushes, opens a PR, merges or deploys stops there and says so, and the settings only those skills read — **Merge strategy**, **Full suite**, **External reviewers** and **Deploy** — are not asked.
|
|
136
|
+
- **Git** — how work is committed, named, merged and caught up — is [`GIT.md`](./GIT.md).
|
|
137
|
+
- **Board** — how a project board's stages are kept, where the project has one — is [`BOARD.md`](./BOARD.md).
|
|
138
|
+
- **Decisions** — where a decision the work makes is written down, and how the glossary and the ADRs are read — are [`DECISIONS.md`](./DECISIONS.md).
|
|
139
|
+
|
|
140
|
+
## Settings
|
|
141
|
+
|
|
142
|
+
The skills on a route share the **settings** defined here. A skill that writes to what a setting names asks for it per these steps when it is missing; a skill that only looks something up reads it when it is set and never asks. Each `###` heading below is one setting: its topic, its question, and its options. `/ep-setup` reads the same headings to ask every setting up front.
|
|
143
|
+
|
|
144
|
+
1. **The settings home.** The `## Agent skills` block of the root `AGENTS.md` — or `CLAUDE.md`, whichever the project has — names where `ep-*` settings live and in what form. With neither file present, first ask which to create, recommending `AGENTS.md`, which most agents read. With no such line, ask the user where to keep them, the default first:
|
|
145
|
+
- **`docs/agents/<topic>.md`** (default) — one Markdown file per topic, one `##` heading per setting, named as the setting. Other headings in the file are the project's own notes.
|
|
146
|
+
- **One file** — at a path the user names.
|
|
147
|
+
- **Another form** — as the user describes it.
|
|
148
|
+
|
|
149
|
+
Write their answer as one line in that block, creating the block when it is missing — for the default, `` `ep-*` settings: `docs/agents/<topic>.md`, one heading per setting. ``
|
|
150
|
+
2. **The setting.** Read it at the settings home. Present: use it, and ask nothing.
|
|
151
|
+
3. **Missing.** Ask its question below, recommended answer first, with the follow-up its option needs. Write the answer at the settings home, tell the user where it went and that they can edit it there or through `/ep-setup`, then continue.
|
|
152
|
+
|
|
153
|
+
### Tracker
|
|
154
|
+
|
|
155
|
+
Topic `issue-tracker`. Question: *Where does the project track its work, how does its writing refer to an issue, and does a board follow the work?*
|
|
156
|
+
|
|
157
|
+
| Option | Follow-up | Recommend when |
|
|
158
|
+
| --- | --- | --- |
|
|
159
|
+
| **GitHub Issues** | An issue prefix, optional — such as `EP-`, so issue 42 reads `EP-42` and `#42` is always a PR. Recommend one when the agent files or recent commit messages use it (`git log --oneline -200`); otherwise none, and issues read `#<n>`. Then the board, optional — a GitHub Project linked to the repo, with its status name for each [stage](./BOARD.md#stages) and the automations it runs (add on create, done on close, review on a linked PR). Recommend it when the repo links one open project | `gh repo view` finds the repo |
|
|
160
|
+
| **Another tracker** | How to create, read with comments, search, comment on, label and close an issue there, and how a PR names the issue it closes. The issue key it numbers by, such as `ENG-` in Linear or `PROJ-` in Jira, where it has one. Its board, where the work moves through one: its status name for each [stage](./BOARD.md#stages), and how to read and set one | The work lives anywhere else |
|
|
161
|
+
| **None** | — | `gh repo view` fails, the user names no other tracker, and the request names no issue. A request that names one means the tracker exists: ask where it lives |
|
|
162
|
+
|
|
163
|
+
With **Another tracker**, every step that names a `gh issue` command does the same thing the way this setting describes.
|
|
164
|
+
|
|
165
|
+
With a board, [`BOARD.md`](./BOARD.md) is how the skills keep it. Without one, they skip every board step.
|
|
166
|
+
|
|
167
|
+
With **None**, the project tracks no issues, and nobody asks again. A skill that looks an issue up searches nothing and says no tracker was searched, even where `gh repo view` finds a repo. The skills skip every label and board step. **Labels** is never asked, and neither are `/ep-deliver`'s settings, because it does not run. A skill whose job is an issue says in its own steps what it does instead: `/ep-to-story` prints the story, and a route through `/ep-triage` skips it and builds from the printed story.
|
|
168
|
+
|
|
169
|
+
**Naming an issue in prose.** Every `ep-*` skill names an issue with the prefix in chat replies, reports, issue and PR bodies, and commit bodies. A form the tracker parses keeps the tracker's own syntax: on GitHub, `Closes #<n>`, `Part of #<n>` and `Refines #<n>` keep `#`, because GitHub closes the issue or writes the backlink from them, and an `EP-` string would be inert text. In a chat reply, a report or a PR body, an issue is a **link**, and its first mention carries its title in bold — `[EP-42](<url>) **"<title>"**` — read from the tracker, never from memory. Later mentions are the bare link. A fixed-width table that already has a title column is exempt.
|
|
170
|
+
|
|
171
|
+
### Labels
|
|
172
|
+
|
|
173
|
+
Topic `issue-tracker`. Question: *Which labels mark an issue's state, and which axes classify it?*
|
|
174
|
+
|
|
175
|
+
The skills name labels by **role**: triage (not yet evaluated), info (waiting on the reporter), discovery (a decision is unmade), ready for an agent, ready for a human, won't fix, and epic. An **axis** is a family of labels every issue carries one of — a type, a priority, a product.
|
|
176
|
+
|
|
177
|
+
| Option | Follow-up | Recommend when |
|
|
178
|
+
| --- | --- | --- |
|
|
179
|
+
| **The defaults** | — | The tracker uses none of these yet. Roles are `needs-triage`, `needs-info`, `needs-grilling`, `ready-for-agent`, `ready-for-human`, `wontfix` and `epic`; there are no axes. |
|
|
180
|
+
| **A document** | The file and heading that map the roles and define the axes | The agent files or a tracker document already do |
|
|
181
|
+
| **This mapping** | Each role's label, and each axis with its values | The tracker has labels that no document holds |
|
|
182
|
+
| **None** | — | The tracker has no labels: the skills skip labelling, and an issue's state lives where the **Tracker** setting says |
|
|
183
|
+
|
|
184
|
+
**Once answered**, compare the labels the answer names with the ones the tracker has. On GitHub, list the missing ones and ask whether to create them now; on yes, `gh label create` each. On another tracker, name the missing ones and ask the user how they want them made. A skill that later finds a label missing names it in its report, and never creates it.
|
|
185
|
+
|
|
186
|
+
### Scopes
|
|
187
|
+
|
|
188
|
+
Topic `naming`. Question: *Which scopes name a piece of work — the product or layer, and the area inside it?*
|
|
189
|
+
|
|
190
|
+
| Option | Follow-up | Recommend when |
|
|
191
|
+
| --- | --- | --- |
|
|
192
|
+
| **A document** | The file and heading that hold the vocabulary | The agent files or a commit standard already fix one |
|
|
193
|
+
| **This list** | The scopes, one per line | The project uses scopes that no document holds |
|
|
194
|
+
| **None** | — | One product, no areas: commit scopes are absent or free |
|
|
195
|
+
|
|
196
|
+
A document keeps the vocabulary in one place: the setting points at it rather than copying it.
|
|
197
|
+
|
|
198
|
+
### Merge strategy
|
|
199
|
+
|
|
200
|
+
Topic `git`. Question: *How does a PR merge into the default branch?*
|
|
201
|
+
|
|
202
|
+
| Option | Follow-up | Recommend when |
|
|
203
|
+
| --- | --- | --- |
|
|
204
|
+
| **Rebase** | — | The repository allows only rebase merges (`gh repo view --json rebaseMergeAllowed,squashMergeAllowed,mergeCommitAllowed`) |
|
|
205
|
+
| **Squash** | — | It allows only squash merges |
|
|
206
|
+
| **Merge commit** | — | It allows only merge commits |
|
|
207
|
+
|
|
208
|
+
Where the repository allows several, recommend the one its recent history shows (`git log --oneline -30 origin/<default>`). [`GIT.md`](./GIT.md) `## Merging` says what each one means for commits and PR bodies.
|
|
209
|
+
|
|
210
|
+
### Test levels
|
|
211
|
+
|
|
212
|
+
Topic `testing`. Question: *Which levels does the project test at, and what does each one prove?*
|
|
213
|
+
|
|
214
|
+
| Option | Follow-up | Recommend when |
|
|
215
|
+
| --- | --- | --- |
|
|
216
|
+
| **These levels** | One row per level: its name, what it proves, its tool, its run command, and the standard that governs it | Always: propose the rows from the test tools in `package.json` and their configs, the test scripts, and any testing standard the agent files route to |
|
|
217
|
+
|
|
218
|
+
The "proves" column decides the level, so write it as a kind of behaviour — "a pure function", "a journey across the UI" — never as a tool.
|
|
219
|
+
|
|
220
|
+
### Full suite
|
|
221
|
+
|
|
222
|
+
Topic `validation`. Question: *Which suite proves a branch before it merges, and who runs it?*
|
|
223
|
+
|
|
224
|
+
| Option | Follow-up | Recommend when |
|
|
225
|
+
| --- | --- | --- |
|
|
226
|
+
| **CI runs it** | — | The PR's required checks run the whole suite on every push (`gh api repos/{owner}/{repo}/branches/<default>/protection`, and the workflows they name) |
|
|
227
|
+
| **A document** | The file and heading that say what to run, by what the change touches | The agent files already say what runs before a push |
|
|
228
|
+
| **This table** | One row per kind of change — a package, a layer, root files — and the commands it runs, in order | The checks run locally, and no document holds them |
|
|
229
|
+
| **One command** | The command, such as `pnpm test:all` | One script runs everything |
|
|
230
|
+
|
|
231
|
+
This is the one run that proves the branch, on its head commit before the PR. **Scoped check** (`/ep-implement`) is the faster run while building, and **Full gate** (`/ep-upgrade`) covers every package at once.
|
|
232
|
+
|
|
233
|
+
Under **CI runs it**, the suite's evidence is the required checks passing on the PR's head commit. Under any other option, the skill runs the suite on the head commit itself, and the PR body carries a **suite report** — the commands, the commit SHA and the result — because nothing else proves that commit was tested.
|
|
234
|
+
|
|
235
|
+
### Checkout
|
|
236
|
+
|
|
237
|
+
Topic `checkout`. Question: *Which kinds of checkout does the work happen in, and how is each one set up and cleaned up?*
|
|
238
|
+
|
|
239
|
+
| Option | Follow-up | Recommend when |
|
|
240
|
+
| --- | --- | --- |
|
|
241
|
+
| **This checkout** | — | The project is worked in one clone that switches branches in place (`git worktree list` shows one) |
|
|
242
|
+
| **These kinds** | One row per kind: how to recognise it (a path, a directory name), its setup command, and its cleanup once the work merged — switch back to the default branch, or commands, and whether the user chooses among them. Then which kind a worker started in parallel gets (`/ep-deliver`) | The project works in worktrees, numbered clones, or a tool that prepares them |
|
|
243
|
+
|
|
244
|
+
Under **This checkout**, setup is a fresh branch off the default branch, and cleanup switches back to the default branch, pulls it, and deletes the merged branch locally and remotely.
|
|
245
|
+
|
|
246
|
+
## Guardrails
|
|
247
|
+
|
|
248
|
+
- **One goal, one story, one PR.** A story is as large as the outcome the user asked for, and one PR delivers it whole. A second story exists for a second goal and nothing else (`/ep-to-story`'s `SPLITTING.md`); a tracker of fragments hides the stories that matter.
|
|
249
|
+
- **The user owns the decisions.** Facts you look up in the codebase. Decisions you put to them and wait for.
|
|
250
|
+
- **The pull to start coding is strongest on the requests that least deserve it.** A big vague ask feels fastest to attack directly, and it is exactly the one where ten minutes of questions saves a week of building the wrong thing.
|
|
251
|
+
- **A request outside these routes just gets done.** Not everything is a feature. When no route fits, do the thing and say that is what you did.
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: setup
|
|
3
|
+
description: Walks every setting the installed ep-* skills declare and saves the project's answers. Use to configure the skills up front, or to change a setting.
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
metadata:
|
|
6
|
+
pack: epicparty/skills
|
|
7
|
+
version: 0.1.0
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Setup
|
|
11
|
+
|
|
12
|
+
Every `ep-*` skill asks for a **setting** the first time it needs one. Setup asks them all up front, in one sitting, so later runs ask nothing.
|
|
13
|
+
|
|
14
|
+
Setup owns no setting. Each skill declares its own in its `## Settings` section — the steps that find a setting, then one `###` heading per setting with its topic, its question and its options. Setup reads those headings, so a newly installed skill's settings reach setup with no edit here.
|
|
15
|
+
|
|
16
|
+
With no argument, setup asks every **unset** setting. Given a skill or a setting by name, it asks that one again even when it is set: that is how a user changes an answer.
|
|
17
|
+
|
|
18
|
+
## 1. Find the skills
|
|
19
|
+
|
|
20
|
+
List the skills of this pack installed for this project and for the user, following symlinks. A pack skill carries `pack: epicparty/skills` under `metadata` in its frontmatter, whatever prefix the project installed it with:
|
|
21
|
+
|
|
22
|
+
```sh
|
|
23
|
+
find -L .agents/skills .claude/skills ~/.agents/skills ~/.claude/skills \
|
|
24
|
+
-maxdepth 2 -name SKILL.md 2>/dev/null |
|
|
25
|
+
while read -r f; do
|
|
26
|
+
grep -Eq '^[[:space:]]+pack: epicparty/skills[[:space:]]*$' "$f" &&
|
|
27
|
+
echo "$(basename "$(dirname "$f")") $(realpath "$f")"
|
|
28
|
+
done |
|
|
29
|
+
sort -u -k2,2
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Where the shell cannot run the pipeline, search the same folders for that line with your search tool. Each line is a skill's installed name and its file. A skill reached twice — through `.claude/skills` and `.agents/skills`, say — resolves to one file and counts once.
|
|
33
|
+
|
|
34
|
+
Done when every installed skill of the pack is listed once.
|
|
35
|
+
|
|
36
|
+
## 2. Collect the settings
|
|
37
|
+
|
|
38
|
+
Read each skill's `## Settings` section. A skill without one has nothing to ask, and neither has a skill whose section only names settings another skill defines — `/ep-to-story`, `/ep-triage` and `/ep-to-pr` read only the ones `/ep` defines. Every `###` heading under a section is one setting, keyed by its **topic** and its heading.
|
|
39
|
+
|
|
40
|
+
Two skills that declare the same topic and heading share one setting: ask it once. Where their questions or options differ, name both skills and show the difference before asking, because one of them has drifted.
|
|
41
|
+
|
|
42
|
+
Compare the numbered steps at the top of each `## Settings` section that has them, too. They are copies of one procedure, so each skill runs alone. A copy that differs from the others is drift: name the skill and the step in the report.
|
|
43
|
+
|
|
44
|
+
Done when every setting is listed with its topic, its heading and the skills that declare it.
|
|
45
|
+
|
|
46
|
+
## 3. Find the settings home
|
|
47
|
+
|
|
48
|
+
The `## Agent skills` block of the root `AGENTS.md` — or `CLAUDE.md`, whichever the project has — names where `ep-*` settings live and in what form. With neither file present, first ask which to create, recommending `AGENTS.md`, which most agents read. With no such line, this is the first question, the default first:
|
|
49
|
+
|
|
50
|
+
- **`docs/agents/<topic>.md`** (default) — one Markdown file per topic, one `##` heading per setting, named as the setting. Other headings in the file are the project's own notes.
|
|
51
|
+
- **One file** — at a path the user names.
|
|
52
|
+
- **Another form** — as the user describes it.
|
|
53
|
+
|
|
54
|
+
Write the answer as one line in that block, creating the block when it is missing — for the default, `` `ep-*` settings: `docs/agents/<topic>.md`, one heading per setting. ``
|
|
55
|
+
|
|
56
|
+
Done when the settings home is named and recorded.
|
|
57
|
+
|
|
58
|
+
## 4. Show what is set
|
|
59
|
+
|
|
60
|
+
Read every setting at the settings home — the heading named as the setting, in its topic's file — then print one table before asking anything. **Skill** is the skill that declares the setting:
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
Skill Topic Setting Value
|
|
64
|
+
ep-research research Destination GitHub Discussion, category Research
|
|
65
|
+
ep-upgrade validation Full gate — unset
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
With **Labels** set, compare the labels it names with the tracker's, and name any missing one in the report.
|
|
69
|
+
|
|
70
|
+
Done when every setting has a row and a value or `— unset`.
|
|
71
|
+
|
|
72
|
+
## 5. Ask
|
|
73
|
+
|
|
74
|
+
Take the settings in scope — every unset one, or the one the user named — grouped by skill. Ask **one at a time**, as the skill that declares it would:
|
|
75
|
+
|
|
76
|
+
- Its question, and its options with the recommended one first. Settle the recommendation the way the setting's table says — a recommendation that reads the repo, reads it now.
|
|
77
|
+
- The follow-up the chosen option needs.
|
|
78
|
+
- A setting that `/ep` `## Settings` or `## Working rules` rules out — under **Tracker** at **None**, or in a repo with no remote — is not asked. List each in the report as ruled out, with its reason.
|
|
79
|
+
- **Skip** is always an answer. A skipped setting stays unset, and its skill asks for it when it first needs it.
|
|
80
|
+
|
|
81
|
+
Write each answer at the settings home as soon as it is given, in the form the home names, then run any step the setting attaches to its answer — **Labels** offers to create the labels the tracker lacks. An interrupted setup then keeps every answer already given.
|
|
82
|
+
|
|
83
|
+
Done when every setting in scope is answered or skipped.
|
|
84
|
+
|
|
85
|
+
## 6. Report
|
|
86
|
+
|
|
87
|
+
The table from § 4 again, with the values now set, then:
|
|
88
|
+
|
|
89
|
+
- **Skipped** — each one, and the skill that will ask for it later.
|
|
90
|
+
- **Ruled out** — each one, and the answer or the fact that ruled it out.
|
|
91
|
+
- **Drift** — each difference § 2 found, with the skills it names.
|
|
92
|
+
- Where the answers live, and that a user can edit them there or run `/ep-setup <setting>` to change one.
|
|
93
|
+
|
|
94
|
+
Done when the user can see every setting's value without opening a file.
|
|
95
|
+
|
|
96
|
+
## Guardrails
|
|
97
|
+
|
|
98
|
+
- **The skill's own words decide.** Ask each question and offer each option exactly as its skill declares them. A setting setup words differently is a second definition of it.
|
|
99
|
+
- **Answers are the user's.** A recommendation is offered, never written unasked.
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ship
|
|
3
|
+
description: Takes a PR to merged, confirms the production deploy landed, and returns the checkout to a clean slate. Use when asked to ship or deploy.
|
|
4
|
+
metadata:
|
|
5
|
+
pack: epicparty/skills
|
|
6
|
+
version: 0.1.0
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Ship
|
|
10
|
+
|
|
11
|
+
Merged is not shipped. `/ep-ship` drives the work to merged, then follows it into production and confirms it arrived.
|
|
12
|
+
|
|
13
|
+
Three stages. The second is the one everything else skips; the third is what leaves a **clean slate** for the next task.
|
|
14
|
+
|
|
15
|
+
## 1. Drive it to merged
|
|
16
|
+
|
|
17
|
+
A branch with no PR gets one first: [`/ep-to-pr`](../to-pr/SKILL.md) validates the head commit, writes the reviewer-facing body, and opens it.
|
|
18
|
+
|
|
19
|
+
Then run [`/ep-babysit`](../babysit/SKILL.md). One invocation is one **sweep**: read the PR's state, dispose of every finding, push the fixes, merge when the gate is clear.
|
|
20
|
+
|
|
21
|
+
A sweep that cannot merge ends by naming the gate condition that stopped it. Read that condition and act on it:
|
|
22
|
+
|
|
23
|
+
- **Waiting on a check, a queue, or the external review the sweep requested** — wait for it, then sweep again. Sweeps are cheap; a sweep over a PR that gained nothing ends in a no-op report.
|
|
24
|
+
- **Waiting on a human** — a review sitting on changes-requested, a thread you pushed back on, an **open question** the PR raised, a question about an external review that the user has not yet answered. Report and stop. Overruling a reviewer is theirs, not yours, and so is answering the question — ship it once they have, and it costs them one word instead of one PR.
|
|
25
|
+
- **Blocked on work outside the PR** — report it with what is holding it.
|
|
26
|
+
|
|
27
|
+
**Where the project keeps a board, set the Shipping stage once the gate is clear and immediately *before* the merge** (`/ep`'s [`BOARD.md`](../router/BOARD.md)). It covers step 2 as well as the merge, so the story stops reading as in review the moment nobody is reviewing it any more.
|
|
28
|
+
|
|
29
|
+
The ordering is the whole point. The PR's closing link closes the issue **on** the merge, and a board that moves closed issues to done does it then. A shipping write landing after the merge would sit on top of that done and stay there, because the trigger is spent and never fires again. Writing first costs nothing and cannot collide.
|
|
30
|
+
|
|
31
|
+
Done when the PR is merged, the board — where there is one — read shipping before it, or you have named the gate condition and who owns it.
|
|
32
|
+
|
|
33
|
+
## 2. Confirm the deploy
|
|
34
|
+
|
|
35
|
+
Read the **Deploy** setting now, per [Settings](#settings). A merge is a request to deploy; this step finds out what happened to it. Under **None**, nothing deploys on merge: say so, and go to step 3.
|
|
36
|
+
|
|
37
|
+
**Which deploys to watch.** Every deploy the merged change triggers. A change to code that several deployables share fans out to **all** of them, so watch each one — a shared change that breaks one deployable's build breaks that deploy alone, and nothing else will tell you.
|
|
38
|
+
|
|
39
|
+
```sh
|
|
40
|
+
gh run list --workflow=<workflow> --branch <default> --limit 3 \
|
|
41
|
+
--json databaseId,headSha,status,conclusion,createdAt
|
|
42
|
+
gh run watch <run-id>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Find the run whose `headSha` is your merge commit. A run against an older SHA is somebody else's deploy.
|
|
46
|
+
|
|
47
|
+
**Three outcomes, and two of them are success:**
|
|
48
|
+
|
|
49
|
+
- **Deployed.** The run is green, and the **receipt** the setting names exists — a release tag, a release commit, a version the live app reports. The receipt is the evidence the deploy finished rather than merely started.
|
|
50
|
+
- **Skipped.** The workflow decided nothing it ships changed, and skipped. That is the pipeline working. Report it as skipped, not as failed.
|
|
51
|
+
- **Failed.** Read the failing job's log (`gh run view <run-id> --log-failed`). The fix is a normal PR through `/ep-implement` and `/ep-ship` again, never a hand-push to the default branch.
|
|
52
|
+
|
|
53
|
+
Done when every triggered deploy has reached deployed, skipped, or failed, and you can say which.
|
|
54
|
+
|
|
55
|
+
## 3. Back to a clean slate
|
|
56
|
+
|
|
57
|
+
The next task starts wherever this one left the checkout. Leave it with nothing of this task still lying around.
|
|
58
|
+
|
|
59
|
+
This step runs **only after the merge landed**. A PR still sitting at a gate has work left on its branch, and the branch is where that work happens.
|
|
60
|
+
|
|
61
|
+
Read the **Checkout** setting now, per [Settings](#settings), and find which kind of checkout this is. Then carry out that kind's cleanup:
|
|
62
|
+
|
|
63
|
+
- **Switch back** — the default for **This checkout**:
|
|
64
|
+
|
|
65
|
+
```sh
|
|
66
|
+
git status --short # anything here that is not yours stops the switch
|
|
67
|
+
git checkout <default> && git pull --rebase
|
|
68
|
+
git branch -d <branch> && git fetch --prune
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
- **Commands** — run them. Where the user chooses among them, ask, and run their choice **last**: a cleanup that removes the checkout removes the directory this session works in. A command that refuses a checkout with uncommitted or unpushed work is reported to the user, and overridden only on their word.
|
|
72
|
+
|
|
73
|
+
Under [`/ep-deliver`](../deliver/SKILL.md) nobody is there to choose, so ask nothing. A checkout the coordinator reuses for the next story switches back. A checkout started for this story alone is kept as it is, and the report names it for the user to clean up.
|
|
74
|
+
|
|
75
|
+
Three things the commands do not tell you:
|
|
76
|
+
|
|
77
|
+
- **`-d` refusing is expected after a rebase or squash merge.** The commits reached the default branch under new SHAs, and git cannot see the old branch as merged. The merged PR is the authority; once you have confirmed it merged, `-D` is the correct delete.
|
|
78
|
+
- **Uncommitted work that is not yours stays put** (`/ep` `## Working rules`). Switch branches only when `git status` is clean or carries nothing but your own leftovers. Otherwise leave the checkout alone and name the files in the report.
|
|
79
|
+
- **Confirm the issue closed, and that the board followed** where there is one. Check both, because they fail differently: an issue still open means the closing link never landed — unless this PR was a stage that named the story as a part, and the story stays open by design until its last stage — while an issue closed with its board card still reading shipping means something overwrote the board's own move. Report either rather than setting done by hand. On GitHub:
|
|
80
|
+
|
|
81
|
+
```sh
|
|
82
|
+
read -r owner name < <(gh repo view --json owner,name --jq '"\(.owner.login) \(.name)"')
|
|
83
|
+
gh api graphql -f query='
|
|
84
|
+
query($o:String!,$r:String!,$n:Int!){ repository(owner:$o,name:$r){ issue(number:$n){
|
|
85
|
+
state projectItems(first:5){ nodes{
|
|
86
|
+
fieldValueByName(name:"Status"){ ... on ProjectV2ItemFieldSingleSelectValue { name } } } } } } }' \
|
|
87
|
+
-f o="$owner" -f r="$name" -F n=<issue>
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Done when the issue is closed with the board — where there is one — on done, and the checkout is settled: its kind's cleanup carried out, with `git status` clean and the shipped branch gone locally and remotely, or the user's choice carried out. Otherwise, name which of those stopped and why.
|
|
91
|
+
|
|
92
|
+
## 4. Report
|
|
93
|
+
|
|
94
|
+
Three sections, in this order. The message lands in a chat the user reads from the bottom up, so the last section is the first one they see. Evidence goes first and the ask goes last.
|
|
95
|
+
|
|
96
|
+
**Details** — the evidence: findings and their dispositions, each deploy run, anything skipped and why, the commands you ran.
|
|
97
|
+
|
|
98
|
+
**TL;DR** — five lines at most, one per thing that is true at the end: the issue, the PR and its merge commit, each deploy's outcome, the receipt now live, the state of the checkout.
|
|
99
|
+
|
|
100
|
+
**Your turn** — closes the message. The actions only a human can take, numbered, each naming the thing to do and where to do it. When the list is empty, write **"Nothing — merged, deployed, and the checkout is clean."** and mean it. A user who cannot tell an empty list from a forgotten one has to go and check for themselves. Anything you are asking them to weigh is an item on this list, and reaching this section means it is already too late to be one — a report that says `Nothing` here and offers opinions up in the details is naming work the merge just made expensive.
|
|
101
|
+
|
|
102
|
+
What earns a line in the last two sections is what **changes what the user does next**. A check that went red and that you fixed changed nothing for them — that is detail. A deferred issue they now own, a failed deploy, a decision waiting on them, a dirty file you left untouched: those are theirs, and they go at the bottom where the eye lands first.
|
|
103
|
+
|
|
104
|
+
## Guardrails
|
|
105
|
+
|
|
106
|
+
- **The default branch is deployed by the pipeline.** A red deploy is fixed by a PR, never by pushing to the default branch or re-running a workflow with edited inputs.
|
|
107
|
+
- **A green merge is not a green deploy.** The gate and the deploy are different runs against different things; walking away at merge is how a broken production build goes unnoticed until someone opens the app.
|
|
108
|
+
- **The receipt is the proof.** No receipt means no completed deploy, whatever the run's colour suggested.
|
|
109
|
+
- **Preserve work you did not write.** The clean slate is about *this* task's leftovers. Uncommitted changes you cannot account for get reported, never stashed, reset or checked out over.
|
|
110
|
+
|
|
111
|
+
## Settings
|
|
112
|
+
|
|
113
|
+
This skill reads one setting `/ep` `## Settings` defines — **Checkout** at § 3, shared with `/ep-deliver` — and one of its own, **Deploy** at § 2. It acts on what they name, so it asks for each one that is missing. Each `###` heading below is one setting: its topic, its question, and its options. `/ep-setup` reads the same headings to ask every setting up front.
|
|
114
|
+
|
|
115
|
+
1. **The settings home.** The `## Agent skills` block of the root `AGENTS.md` — or `CLAUDE.md`, whichever the project has — names where `ep-*` settings live and in what form. With neither file present, first ask which to create, recommending `AGENTS.md`, which most agents read. With no such line, ask the user where to keep them, the default first:
|
|
116
|
+
- **`docs/agents/<topic>.md`** (default) — one Markdown file per topic, one `##` heading per setting, named as the setting. Other headings in the file are the project's own notes.
|
|
117
|
+
- **One file** — at a path the user names.
|
|
118
|
+
- **Another form** — as the user describes it.
|
|
119
|
+
|
|
120
|
+
Write their answer as one line in that block, creating the block when it is missing — for the default, `` `ep-*` settings: `docs/agents/<topic>.md`, one heading per setting. ``
|
|
121
|
+
2. **The setting.** Read it at the settings home. Present: use it, and ask nothing.
|
|
122
|
+
3. **Missing.** Ask its question below, recommended answer first, with the follow-up its option needs. Write the answer at the settings home, tell the user where it went and that they can edit it there or through `/ep-setup`, then continue.
|
|
123
|
+
|
|
124
|
+
### Deploy
|
|
125
|
+
|
|
126
|
+
Topic `deploy`. Question: *How does a merge reach production, and what proves it arrived?*
|
|
127
|
+
|
|
128
|
+
| Option | Follow-up | Recommend when |
|
|
129
|
+
| --- | --- | --- |
|
|
130
|
+
| **A deploy workflow** | Which workflow deploys which part of the project, which changes trigger it, and the receipt that proves a deploy finished — a release tag, a release commit, a version the live app reports | A workflow in `.github/workflows/` deploys on a push to the default branch |
|
|
131
|
+
| **A document** | The file and heading that describe the deploys | The agent files route deploys to a pipeline document |
|
|
132
|
+
| **None** | — | Nothing deploys on merge — a library, or a deploy run by hand. Ship ends at the merge and says so |
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: to-pr
|
|
3
|
+
description: Opens a pull request from a committed branch, carrying its suite report and issue link. Use when a branch is ready for review.
|
|
4
|
+
metadata:
|
|
5
|
+
pack: epicparty/skills
|
|
6
|
+
version: 0.1.0
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# To PR
|
|
10
|
+
|
|
11
|
+
One branch in, one open PR out. The counterpart to [`/ep-to-story`](../to-story/SKILL.md): that one writes the issue a human reads before the work, this one writes the PR a human reads during it.
|
|
12
|
+
|
|
13
|
+
**Who reads the PR body depends on the merge.** Under a rebase or merge-commit merge, every commit lands on the default branch as itself, and the body is for reviewers and nothing else: anything a reader of `git log` will need has to be in a commit message already. Under a squash, the body becomes the commit body, and is written for that reader too (`/ep`'s [`GIT.md`](../router/GIT.md) `## Merging`).
|
|
14
|
+
|
|
15
|
+
## 1. Pin the branch
|
|
16
|
+
|
|
17
|
+
Establish the branch, its base, and that there is something to review:
|
|
18
|
+
|
|
19
|
+
- The base is the repo's default branch, unless the user asked to stack this on another.
|
|
20
|
+
- Commits exist on the branch that the base does not have.
|
|
21
|
+
- The working tree is clean. Uncommitted work is either part of this PR — commit it per `GIT.md` `## Commits` — or it is not yours, and it stays where it is.
|
|
22
|
+
- Check whether a PR is already open for this branch. There is, and this skill is done: hand to [`/ep-babysit`](../babysit/SKILL.md).
|
|
23
|
+
|
|
24
|
+
Done when you can name the branch, the base, and the commits the PR will carry.
|
|
25
|
+
|
|
26
|
+
## 2. Find the issue it closes
|
|
27
|
+
|
|
28
|
+
The user may have named it. `/ep-implement` will have. Where neither did, search the tracker for the work's provenance with the branch's own nouns — on GitHub, `gh issue list --search "<keywords>" --state all` — and judge each hit against the branch: the same work is the issue, adjacent work is context. The tracker is the **Tracker** setting when the settings home has one, or GitHub when `gh repo view` finds the repo.
|
|
29
|
+
|
|
30
|
+
An issue found here is named in the body so that merging the PR closes it — `Closes #<n>` on GitHub, or the form the **Tracker** setting gives — and the board, where there is one, follows on its own. A PR that lands one stage of a story that continues — a schema widen ahead of its narrow — names it as a part instead, `Part of #<n>` on GitHub, and the last stage closes it (`/ep-to-story`'s `STORIES.md` `## Splitting`). Work with genuinely no issue says so in the body rather than having one invented for it.
|
|
31
|
+
|
|
32
|
+
With an issue to name and no **Tracker** setting, ask for it now, per [Settings](#settings): the PR body is about to write the link.
|
|
33
|
+
|
|
34
|
+
Done when you have the issue, or have searched and can say there is none.
|
|
35
|
+
|
|
36
|
+
## 3. Validate the head commit
|
|
37
|
+
|
|
38
|
+
Read the **Full suite** setting now, per [Settings](#settings).
|
|
39
|
+
|
|
40
|
+
- **CI runs it** — nothing runs here. The required checks on the head commit are the evidence, and `/ep-babysit` reads them.
|
|
41
|
+
- **Any other option** — run what it names for what the branch touches, on the head commit. **You are the check**, and step 4 reports what you found.
|
|
42
|
+
|
|
43
|
+
Note the SHA you ran it against. A suite result belongs to one commit, and it stops being evidence the moment another lands.
|
|
44
|
+
|
|
45
|
+
Done when the suite has run and you can name its result and the SHA it judged, or state the concrete reason it could not run — or the setting leaves it to CI.
|
|
46
|
+
|
|
47
|
+
## 4. Write it
|
|
48
|
+
|
|
49
|
+
Read the **Scopes** setting when it is set, and the **Merge strategy** setting now, per [Settings](#settings): it decides who reads the body.
|
|
50
|
+
|
|
51
|
+
**Title** — the conventional-commit subject that summarises the whole branch, per `GIT.md` `## Naming an issue, a PR and a branch`: `type(<scope>): description`, the scope matching the issue's, the type the branch's dominant change. Individual commits keep their own narrower scopes.
|
|
52
|
+
|
|
53
|
+
**Body** — check for a template first (`.github/pull_request_template.md`, `.github/PULL_REQUEST_TEMPLATE/`) and fill its headings when one exists. Otherwise write prose covering:
|
|
54
|
+
|
|
55
|
+
- **Why this exists** — the problem, in the reviewer's terms. One or two sentences; the issue holds the long version.
|
|
56
|
+
- **What it does** — the change, at the level of behaviour rather than file-by-file. A reviewer reads this to know where to look.
|
|
57
|
+
- **What to look at** — the decision you are least sure of, the trade-off you made, the file that carries the risk. This is the section that gets you a useful review instead of an approval. Label as **Open question** each call you made *for* the user and would change on their word (`/ep` `## Vocabulary`); `/ep-babysit` holds the merge until each has an answer, so one left unlabelled ships as decided.
|
|
58
|
+
- **Found in passing** — each **small fix** the branch carries, named by commit, and each larger finding left for the user to make a story of (`/ep` `## Vocabulary`). Leave the heading out when there is neither.
|
|
59
|
+
- **The suite report** — the command you ran, the SHA, and the result. Say plainly when it could not run. Leave it out when CI runs the suite.
|
|
60
|
+
- **The issue link** from step 2.
|
|
61
|
+
|
|
62
|
+
Use the domain's own vocabulary ([`DECISIONS.md`](../router/DECISIONS.md)), name other issues with the **Tracker** setting's prefix, and follow the naming rules the project's agent files set for prose. Under a **Squash** merge, write the body as the commit body it becomes: lead with what `git log` needs, and keep the reviewer's notes — what to look at, the open questions — under their own headings below it.
|
|
63
|
+
|
|
64
|
+
Done when a reviewer who has not seen the issue would know why the branch exists and where to start reading.
|
|
65
|
+
|
|
66
|
+
## 5. Open it
|
|
67
|
+
|
|
68
|
+
Push the branch, then open the PR against the base — **ready for review, not a draft**. A draft can never reach the gate, and a PR nobody was asked to review is a PR that sits.
|
|
69
|
+
|
|
70
|
+
Then, where the project keeps a board, move the issue to the Review stage (`/ep`'s [`BOARD.md`](../router/BOARD.md)). Do it now rather than after CI goes green: review covers "PR open, awaiting CI and review", so an amber build belongs there too.
|
|
71
|
+
|
|
72
|
+
Report the PR number and URL, then hand to [`/ep-ship`](../ship/SKILL.md), which sweeps it to merged and follows it into production.
|
|
73
|
+
|
|
74
|
+
Done when the PR is open, non-draft, based correctly, linked to its issue, and the board — where there is one — reads review.
|
|
75
|
+
|
|
76
|
+
## Guardrails
|
|
77
|
+
|
|
78
|
+
- **A PR body is a summary, never a substitute.** The commits are the record that reaches the default branch; when the body is the only place something is explained, the explanation is in the wrong place.
|
|
79
|
+
- **The suite report names a commit.** A report without a SHA reads as reassurance rather than evidence, and where CI does not run the suite it is the only evidence the PR has.
|
|
80
|
+
- **The story's goal is the PR's scope.** Work you notice that the goal needs lands as a commit, and step 3 runs again on the new head. A **small fix** lands as a commit too, even when the goal does not need it. Anything larger goes under **Found in passing**, and the user decides whether it becomes a story. A **sibling** of the defect the branch fixes goes in the body as an **open question**, for the user to answer before the merge (`/ep` `## Vocabulary`).
|
|
81
|
+
|
|
82
|
+
## Settings
|
|
83
|
+
|
|
84
|
+
This skill reads four settings, all defined in `/ep` `## Settings` together with the steps that find them:
|
|
85
|
+
|
|
86
|
+
- **Full suite** at § 3 and **Merge strategy** at § 4. This skill runs the one and writes the body the other shapes, so it asks for each one that is missing.
|
|
87
|
+
- **Tracker** at § 2: read when set, and asked for only when there is an issue to link.
|
|
88
|
+
- **Scopes** at § 4, when it is set.
|