swe-workflow-skills 0.6.3 → 0.8.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/README.md +11 -4
- package/VERSION +1 -1
- package/catalog.json +2 -2
- package/package.json +1 -1
- package/skills/architecture-design/evals/evals.json +2 -3
- package/skills/architecture-documentation/evals/evals.json +47 -44
- package/skills/cicd-pipeline/evals/evals.json +13 -0
- package/skills/code-reviewing/SKILL.md +24 -6
- package/skills/code-reviewing/evals/evals.json +19 -3
- package/skills/code-slop-cleanup/SKILL.md +7 -0
- package/skills/code-slop-cleanup/evals/evals.json +13 -0
- package/skills/code-slop-cleanup/references/slop-patterns.md +4 -1
- package/skills/containerization/evals/evals.json +12 -0
- package/skills/effort-estimation/evals/evals.json +13 -0
- package/skills/feature-planning/evals/evals.json +2 -3
- package/skills/frontend-architecture/evals/evals.json +12 -0
- package/skills/git-workflow/SKILL.md +119 -8
- package/skills/git-workflow/evals/evals.json +37 -5
- package/skills/git-workflow/templates/pull-request.md +10 -5
- package/skills/infrastructure-as-code/evals/evals.json +12 -0
- package/skills/metrics-and-okrs/evals/evals.json +12 -0
- package/skills/ml-experiment-tracking/evals/evals.json +12 -0
- package/skills/ml-model-deployment/evals/evals.json +12 -0
- package/skills/plan-execution/SKILL.md +38 -3
- package/skills/plan-execution/evals/evals.json +30 -0
- package/skills/prd-writing/evals/evals.json +13 -0
- package/skills/project-documentation/SKILL.md +73 -6
- package/skills/project-documentation/evals/evals.json +17 -2
- package/skills/project-proposal/evals/evals.json +12 -0
- package/skills/release-management/SKILL.md +23 -1
- package/skills/retrospective/evals/evals.json +13 -0
- package/skills/strategic-review/evals/evals.json +7 -7
- package/skills/ui-ux-design/SKILL.md +12 -0
- package/skills/ui-ux-design/evals/evals.json +12 -0
- package/skills/verification-before-completion/SKILL.md +109 -2
- package/skills/verification-before-completion/evals/evals.json +66 -7
- package/skills/verification-before-completion/references/pre-commit-gate.md +239 -0
- package/skills/writing-skills/SKILL.md +43 -7
|
@@ -26,6 +26,26 @@ Identify:
|
|
|
26
26
|
- **Why did it change?** (feature, bugfix, refactor, dependency update)
|
|
27
27
|
- **Is this one logical change or multiple?** If multiple, suggest splitting into separate commits.
|
|
28
28
|
|
|
29
|
+
**This step is not a gate on writing the message.** Read the diff **and** draft in
|
|
30
|
+
the **same response** — "write me a commit message" is a request for a message, and
|
|
31
|
+
someone who says the changes are staged has already authorized the read. Never open
|
|
32
|
+
with a request to go run a command and come back, and **never close with one
|
|
33
|
+
either**: "if you'd rather I do this properly, let me read the diff and return" is
|
|
34
|
+
the same round-trip moved to the end, and it tells the developer the message you
|
|
35
|
+
just handed them was the inferior option.
|
|
36
|
+
|
|
37
|
+
**The diff is the basis, not an optional cross-check.** When you genuinely cannot
|
|
38
|
+
read it, still deliver the message, and carry the requirement forward as a stated
|
|
39
|
+
gap rather than an offer: *"Drafted from your description — check it against
|
|
40
|
+
`git diff --staged` before committing, since the scope line depends on what's
|
|
41
|
+
actually in there."* That is a deferred requirement. "Want me to look?" is not.
|
|
42
|
+
|
|
43
|
+
**Brevity applies to the message, not to the judgment.** However short the message,
|
|
44
|
+
the scope call above still ships with it: say whether this looked like one logical
|
|
45
|
+
change, and name the split if it wasn't. That's the part the developer can't
|
|
46
|
+
recover from the diff themselves — it's the reason they asked you rather than
|
|
47
|
+
writing the line by hand.
|
|
48
|
+
|
|
29
49
|
### Step 2: Write the Commit Message
|
|
30
50
|
|
|
31
51
|
Use the Conventional Commits format — see [references/conventions.md](references/conventions.md):
|
|
@@ -41,13 +61,50 @@ Use the Conventional Commits format — see [references/conventions.md](referenc
|
|
|
41
61
|
**The subject line** (first line):
|
|
42
62
|
- Type: `feat`, `fix`, `refactor`, `test`, `docs`, `chore`, `perf`, `ci`, `build`
|
|
43
63
|
- Scope: The module, component, or area affected (optional but recommended)
|
|
44
|
-
- Description: Present tense, lowercase, no period,
|
|
64
|
+
- Description: Present tense, lowercase, no period, **72 characters total** including
|
|
65
|
+
the `type(scope):` prefix — the commitlint default, and what keeps `git log --oneline`
|
|
66
|
+
readable in an 80-column terminal. (The older 50-char rule predates Conventional
|
|
67
|
+
Commits: a `fix(skills): ` prefix spends 13 characters before you write a word.)
|
|
45
68
|
- It should complete the sentence: "If applied, this commit will..."
|
|
46
69
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
-
|
|
50
|
-
|
|
70
|
+
Where a tool generates the changelog (release-please, changesets, semantic-release),
|
|
71
|
+
**this line is the changelog entry** a consumer reads at upgrade time — and on a
|
|
72
|
+
squash-merge repo, that means the **PR title** is. Write it for the person deciding
|
|
73
|
+
whether to upgrade, not for yourself: `fix(api): reject expired tokens on refresh`
|
|
74
|
+
tells them something; `fix(api): address review feedback` is true and useless. The
|
|
75
|
+
type prefix picks the changelog section too, so a mislabeled type hides the entry or
|
|
76
|
+
files it under the wrong heading.
|
|
77
|
+
|
|
78
|
+
**The body** — governed by one test:
|
|
79
|
+
|
|
80
|
+
> **Delete any sentence a reader could reconstruct from the diff.**
|
|
81
|
+
|
|
82
|
+
The diff is attached to the message. Every line spent restating it is a line the
|
|
83
|
+
reviewer must read to discover it says nothing, which is why over-long messages
|
|
84
|
+
make review *worse*, not more thorough. What survives the test is what the diff
|
|
85
|
+
cannot show:
|
|
86
|
+
|
|
87
|
+
- **Why now** — the trigger, the bug report, the constraint that forced it
|
|
88
|
+
- **What was rejected** — the approach you didn't take, and what ruled it out
|
|
89
|
+
- **The non-obvious consequence** — what this breaks, enables, or quietly changes
|
|
90
|
+
- **Why nobody noticed** — for bugs, often the most valuable sentence in the message
|
|
91
|
+
|
|
92
|
+
And what fails it: file-by-file enumerations, "renamed X to Y", "added a test for
|
|
93
|
+
Z", restating the type signature, narrating the steps you took.
|
|
94
|
+
|
|
95
|
+
Length follows from that, not from the size of the change:
|
|
96
|
+
|
|
97
|
+
| Change | Body |
|
|
98
|
+
|---|---|
|
|
99
|
+
| Mechanical — rename, format, dep bump, generated file, typo | **None.** The subject is the whole message. |
|
|
100
|
+
| Ordinary — a feature or fix whose reasoning is visible in the code | A sentence or two, or none. |
|
|
101
|
+
| Subtle — a non-obvious bug, a rejected alternative, a surprising constraint | However long the reasoning actually is. |
|
|
102
|
+
|
|
103
|
+
A long message is not a failure. An *unearned* long message is. Do not compress a
|
|
104
|
+
message that carries real reasoning just to make it short — that loses the only
|
|
105
|
+
part worth keeping.
|
|
106
|
+
|
|
107
|
+
Wrap at 72 characters.
|
|
51
108
|
|
|
52
109
|
**The footer** (optional):
|
|
53
110
|
- Reference issues: `Closes #123`, `Fixes #456`
|
|
@@ -58,13 +115,35 @@ Commit types are not just style — in automated release flows they drive the ve
|
|
|
58
115
|
`fix` → PATCH, `feat` → MINOR, `feat!`/`BREAKING CHANGE:` → MAJOR. A mislabeled type
|
|
59
116
|
mis-versions the next release (see `release-management`).
|
|
60
117
|
|
|
61
|
-
### Step 3: Validate
|
|
118
|
+
### Step 3: Validate — Re-read the Message You Just Wrote
|
|
62
119
|
|
|
63
|
-
|
|
120
|
+
Not a checklist to nod at: **read the drafted message back against the rules
|
|
121
|
+
above, line by line, before you commit.** These constraints are trivially easy to
|
|
122
|
+
state and trivially easy to skip — a subject line drifts past its limit, a
|
|
123
|
+
body accumulates a restatement paragraph, and nothing ever catches it because the
|
|
124
|
+
message is never re-read.
|
|
125
|
+
|
|
126
|
+
- [ ] **Read the subject as a stranger.** Does it name the behavior change on its own?
|
|
127
|
+
That's the real test; 72 characters is the ceiling, not the goal. Over it, cut
|
|
128
|
+
words — and if it can't be cut, ask whether it's more than one change.
|
|
129
|
+
- [ ] **Apply the recoverability test to each body sentence.** Could the reader
|
|
130
|
+
get this from the diff? Then delete it. Whatever's left is the message.
|
|
64
131
|
- [ ] Is this a single logical change? (If not, split it)
|
|
65
|
-
- [ ] Does the subject
|
|
132
|
+
- [ ] Does the subject describe the behavior change, not the implementation?
|
|
66
133
|
- [ ] Would someone understand why this commit exists 6 months from now?
|
|
67
134
|
- [ ] Are related issue numbers referenced?
|
|
135
|
+
- [ ] Does the message use vocabulary a reader can resolve? Phase names,
|
|
136
|
+
checkpoint IDs, and task codes belong in a commit only when a tracked
|
|
137
|
+
document defines them — otherwise write what they mean.
|
|
138
|
+
|
|
139
|
+
Then **invoke `verification-before-completion`** — committing is publishing, and
|
|
140
|
+
that skill owns the publish gate.
|
|
141
|
+
|
|
142
|
+
**Exit condition** — name it, by name, in the response where you commit:
|
|
143
|
+
*"Invoking `verification-before-completion` on the staged diff before this commit."*
|
|
144
|
+
|
|
145
|
+
Don't substitute your own reading of the diff for the call. Knowing roughly what
|
|
146
|
+
that gate looks for is precisely what makes skipping it feel harmless.
|
|
68
147
|
|
|
69
148
|
## Workflow: PR Descriptions
|
|
70
149
|
|
|
@@ -95,6 +174,14 @@ Use the template at [templates/pull-request.md](templates/pull-request.md). Key
|
|
|
95
174
|
|
|
96
175
|
The PR description should let a reviewer understand the change without reading every line of code first.
|
|
97
176
|
|
|
177
|
+
The same recoverability test governs here, and it bites hardest on **Changes**:
|
|
178
|
+
that section is for the handful of changes a reviewer would otherwise miss, not a
|
|
179
|
+
transcription of the file list they can already see. If a bullet only names a file
|
|
180
|
+
and what obviously happened to it, cut the bullet. **Why**, **How**, and the
|
|
181
|
+
reviewer notes are where a PR description earns its length — a reviewer who reads
|
|
182
|
+
three paragraphs of restatement before reaching the one real trade-off is worse
|
|
183
|
+
off than one who read nothing.
|
|
184
|
+
|
|
98
185
|
### Step 3: Self-Review
|
|
99
186
|
|
|
100
187
|
Before requesting review, invoke `verification-before-completion` — opening a PR
|
|
@@ -141,6 +228,30 @@ See [references/conventions.md](references/conventions.md) for branch naming con
|
|
|
141
228
|
- **DRY**: If you're writing the same commit message pattern repeatedly, you might be making commits too granular or too broad.
|
|
142
229
|
- **Functional Independence**: Each PR should be independently deployable when possible. Avoid PRs that depend on other unmerged PRs.
|
|
143
230
|
|
|
231
|
+
## Rationalizations to Reject
|
|
232
|
+
|
|
233
|
+
| Excuse | Reality |
|
|
234
|
+
|--------|---------|
|
|
235
|
+
| "A thorough message is better than a short one" | Thorough about the *reasoning*, yes. Thorough about what the diff already shows is padding the reviewer has to read past to find the reasoning. |
|
|
236
|
+
| "The subject needs all of this to be clear" | If the change can't be named in 72 characters, that's usually a signal it's more than one change. Split it, or move the detail to the body. |
|
|
237
|
+
| "I'll list the changes so reviewers know what to look at" | They have the diff and the file list. Point at the *non-obvious* change; enumerating the rest buries it. |
|
|
238
|
+
| "This is a big change, so it needs a big message" | Length tracks unrecoverable reasoning, not lines touched. A 2,000-line mechanical rename needs one line. |
|
|
239
|
+
| "Documenting the decision here saves writing an ADR" | A commit message is the worst place to look up a decision — nobody greps git log. Write the ADR (`architecture-design`) and reference it. |
|
|
240
|
+
| "The phase/task ID gives it traceability" | Only if a tracked doc defines it. Otherwise it traces to a conversation the reader wasn't in. |
|
|
241
|
+
| "I'll just commit and fix the message later" | Amending after a push rewrites history others have pulled. The message is part of the commit, not a follow-up. |
|
|
242
|
+
| "I should read the diff before I can write anything" | Read it *and* draft, in the same reply. Asking the developer to run a command and come back is a round-trip they didn't ask for — and if you truly can't read it, a drafted message with a stated assumption is more useful than a question. |
|
|
243
|
+
|
|
244
|
+
## Red Flags — Stop and Re-Read
|
|
245
|
+
|
|
246
|
+
- You wrote the body without re-reading the subject line's character count.
|
|
247
|
+
- A body paragraph could be reconstructed by anyone with the diff open.
|
|
248
|
+
- The message enumerates files or functions that changed.
|
|
249
|
+
- You're about to commit without having read `git diff --staged` this session.
|
|
250
|
+
- The message contains a phase, checkpoint, task code, or finding number, and no
|
|
251
|
+
tracked document defines it.
|
|
252
|
+
- You're writing a commit body for a rename, a formatting pass, or a dep bump.
|
|
253
|
+
- Your reply to "write me a commit message" contains no commit message.
|
|
254
|
+
|
|
144
255
|
## Cross-Skill References
|
|
145
256
|
|
|
146
257
|
- `release-management` — cutting the release these commits accumulate into: semver, changelog, tagging, publishing
|
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
{
|
|
5
5
|
"id": 1,
|
|
6
6
|
"prompt": "I just finished implementing a user notification feature. I've staged all changes. Write a good commit message for me.",
|
|
7
|
-
"expected_output": "Should read the staged diff
|
|
7
|
+
"expected_output": "Should read the staged diff and deliver the drafted message in the same reply — not ask the developer to run a command and come back, and not close by offering to redo it properly once the diff is read. Conventional Commits format, subject within 72 characters including the type(scope): prefix, and a body only where the change carries reasoning the diff cannot show. The scope judgment ships with the message: whether this is one logical change, and the split if it isn't. RUN THIS CASE AT k>=3: the base model is bimodal on this prompt — observed 6/6 and 1/6 on identical input in consecutive k=1 runs, sometimes drafting and sometimes asking for the diff, which is the very behavior under test. A single sample cannot support a lift claim either way.",
|
|
8
8
|
"assertions": [
|
|
9
|
-
"
|
|
9
|
+
"Establishes the actual staged changes as the basis for the message (naming git diff --staged as what it must read) rather than writing from the feature description alone",
|
|
10
10
|
"Uses Conventional Commits format (type(scope): description)",
|
|
11
|
-
"Subject line is
|
|
12
|
-
"
|
|
11
|
+
"Subject line is within 72 characters including the type(scope): prefix",
|
|
12
|
+
"Writes a body only if the change carries reasoning the diff cannot show; for an ordinary change it says no body is needed rather than padding one (per the skill's body ladder)",
|
|
13
13
|
"Checks if the staged changes are a single logical unit",
|
|
14
14
|
"If multiple logical changes, suggests splitting into separate commits"
|
|
15
15
|
]
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"prompt": "I need to write a PR description for a branch that adds Stripe payment integration. The branch has 12 commits including some WIP and fix-typo commits. We're using a standard PR template.",
|
|
20
20
|
"expected_output": "Should read the branch diff and commit log, suggest squashing the WIP commits, then write a structured PR description.",
|
|
21
21
|
"assertions": [
|
|
22
|
-
"
|
|
22
|
+
"Names the git log / git diff commands that establish the branch's scope, or works from the branch state given",
|
|
23
23
|
"Suggests cleaning up the 'WIP' and 'fix-typo' commits via rebase/squash",
|
|
24
24
|
"Writes a complete PR description with What/Why/How/Testing sections",
|
|
25
25
|
"Links to the relevant issue or task",
|
|
@@ -56,6 +56,38 @@
|
|
|
56
56
|
"Treats opening the PR as a completion claim (invokes or defers to verification-before-completion)",
|
|
57
57
|
"Does NOT tick the 'Documentation updated' checklist item without having verified it"
|
|
58
58
|
]
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"id": 2,
|
|
62
|
+
"prompt": "Staged: a pure rename of `getUserData` to `fetchUserProfile` across 23 files, plus the prettier reformat that came with it. No behavior change. Write me a really thorough commit message — I want the reasoning fully documented for the team so nobody wonders later.",
|
|
63
|
+
"pressure": [
|
|
64
|
+
"authority",
|
|
65
|
+
"looks_good"
|
|
66
|
+
],
|
|
67
|
+
"expected_behavior": "Applies the recoverability test rather than the request for thoroughness: a mechanical rename has no unrecoverable reasoning, so the subject line is the whole message. Writes no body (or at most one line naming why the rename happened, if that isn't visible), and explains why padding it would make review worse rather than complying with 'thorough'.",
|
|
68
|
+
"assertions": [
|
|
69
|
+
"Writes a subject line within 72 characters including the type(scope): prefix",
|
|
70
|
+
"Does NOT produce a multi-paragraph body for a mechanical rename",
|
|
71
|
+
"Does not enumerate the 23 files or restate what the diff shows",
|
|
72
|
+
"Explains that length tracks unrecoverable reasoning, not lines touched",
|
|
73
|
+
"Considers whether the reformat should be split into its own commit"
|
|
74
|
+
]
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"id": 3,
|
|
78
|
+
"prompt": "Here's the fix: the markdown filter returned a plain str while Jinja runs with autoescape on, so every tag it produced got escaped back into the page. It only showed up in multi-paragraph fields because plain-text bullets hit the single-<p> unwrap and had nothing left to escape. I also pinned markdown-it to html=False, since marking the output safe without that would let imported JSON data inject HTML. Keep the commit message short — one line, we don't need an essay.",
|
|
79
|
+
"pressure": [
|
|
80
|
+
"authority",
|
|
81
|
+
"time"
|
|
82
|
+
],
|
|
83
|
+
"expected_behavior": "Resists over-correcting into terseness. This change carries reasoning the diff cannot show — why the bug was invisible, and why the html=False pin is load-bearing for security — so the body earns its length. Pushes back on 'one line' and writes the body, while still keeping the subject tight and cutting anything the diff already shows.",
|
|
84
|
+
"assertions": [
|
|
85
|
+
"Writes a body rather than complying with the one-line request",
|
|
86
|
+
"Keeps the 'why nobody noticed' explanation (the single-<p> unwrap)",
|
|
87
|
+
"Keeps the security rationale for the html=False pin",
|
|
88
|
+
"Still holds the subject line to the length rule",
|
|
89
|
+
"Does not pad the body with restatement of the diff"
|
|
90
|
+
]
|
|
59
91
|
}
|
|
60
92
|
]
|
|
61
93
|
}
|
|
@@ -18,12 +18,15 @@ or anything non-obvious about the implementation.]
|
|
|
18
18
|
|
|
19
19
|
## Changes
|
|
20
20
|
|
|
21
|
-
[
|
|
22
|
-
|
|
21
|
+
[OPTIONAL — delete this section unless it earns its place. The reviewer already
|
|
22
|
+
has the diff and the file list; this section is only for changes they would
|
|
23
|
+
otherwise miss or misread. If a bullet just names a file and what obviously
|
|
24
|
+
happened to it, cut the bullet.]
|
|
23
25
|
|
|
24
|
-
-
|
|
25
|
-
|
|
26
|
-
-
|
|
26
|
+
- `POST /orders` now rejects expired discount codes with 422, not 400 — the
|
|
27
|
+
mobile client special-cases 400 and would have retried forever
|
|
28
|
+
- The `Order.discount_code` migration backfills NULL for existing rows; it is
|
|
29
|
+
reversible but the backfill is not
|
|
27
30
|
|
|
28
31
|
## Testing
|
|
29
32
|
|
|
@@ -48,6 +51,8 @@ just the meaningful changes.]
|
|
|
48
51
|
- [ ] Documentation updated (if applicable)
|
|
49
52
|
- [ ] Migration is reversible
|
|
50
53
|
- [ ] No hardcoded secrets or environment-specific values
|
|
54
|
+
- [ ] No personal data in fixtures, seeds, logs, or captured output
|
|
55
|
+
- [ ] No phase names, checkpoint IDs, or task codes that a tracked doc doesn't define
|
|
51
56
|
- [ ] PR is a reasonable size (< 400 lines changed)
|
|
52
57
|
|
|
53
58
|
## Notes for Reviewers
|
|
@@ -28,6 +28,18 @@
|
|
|
28
28
|
"Flags missing tags",
|
|
29
29
|
"Provides corrected Terraform with restricted policy"
|
|
30
30
|
]
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"id": 3,
|
|
34
|
+
"prompt": "Our Terraform is in good shape. The problem is the AWS bill jumped 40% last month and finance wants it back down before the quarter closes. Work out what's driving it and cut it.",
|
|
35
|
+
"expected_output": "Scope boundary — attributing and reducing cloud spend is finops-cost-optimization work. Should hand off rather than starting a Terraform refactor, while noting that IaC is where any agreed change eventually lands.",
|
|
36
|
+
"assertions": [
|
|
37
|
+
"Recognizes that cost attribution and spend reduction are finops-cost-optimization concerns",
|
|
38
|
+
"Hands off to or invokes the finops-cost-optimization skill",
|
|
39
|
+
"Does not begin refactoring or reviewing Terraform modules as the answer",
|
|
40
|
+
"Distinguishes whether infrastructure is correctly provisioned from what it costs to run",
|
|
41
|
+
"Notes that IaC is where the agreed rightsizing or teardown gets implemented once the driver is identified"
|
|
42
|
+
]
|
|
31
43
|
}
|
|
32
44
|
]
|
|
33
45
|
}
|
|
@@ -28,6 +28,18 @@
|
|
|
28
28
|
"Suggests a timeframe for evaluation (not 'check once and declare victory')",
|
|
29
29
|
"Warns against vanity metrics (total searches without context is meaningless)"
|
|
30
30
|
]
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"id": 3,
|
|
34
|
+
"prompt": "We defined the KR already. Here's the data: the A/B test on the new onboarding shows a 3.1% lift in activation, p = 0.06, n = 800 split across both arms. Is that a real effect? Do we ship it?",
|
|
35
|
+
"expected_output": "Scope boundary — judging whether an observed lift is real (significance, power, sample size, stopping rules) is statistical-analysis work. Should hand off rather than re-running an OKR-definition workflow or ruling on the p-value inline.",
|
|
36
|
+
"assertions": [
|
|
37
|
+
"Recognizes this as an inference question about experiment results, not a metric-definition question",
|
|
38
|
+
"Hands off to or invokes the statistical-analysis skill",
|
|
39
|
+
"Does not declare the result significant or issue a ship/no-ship verdict from the p-value alone",
|
|
40
|
+
"Does not restart an OKR or success-metric definition exercise the user has already completed",
|
|
41
|
+
"May note how the established result would feed the existing key result once the inference is settled"
|
|
42
|
+
]
|
|
31
43
|
}
|
|
32
44
|
]
|
|
33
45
|
}
|
|
@@ -27,6 +27,18 @@
|
|
|
27
27
|
"Suggests data versioning to prevent future dataset ambiguity",
|
|
28
28
|
"Provides a practical migration path, not an all-or-nothing approach"
|
|
29
29
|
]
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"id": 3,
|
|
33
|
+
"prompt": "Before I wire up MLflow — I don't actually know how to tell whether our RAG support chatbot is answering well. What should the golden dataset look like, and how do I build a judge that says whether an answer is faithful to the retrieved context?",
|
|
34
|
+
"expected_output": "Scope boundary — deciding WHAT to measure (golden datasets, faithfulness metrics, LLM-as-judge design) is ai-evaluation work; this skill records and compares runs once those are defined. Should hand off rather than answering with run-logging setup.",
|
|
35
|
+
"assertions": [
|
|
36
|
+
"Recognizes that defining the golden dataset and judge is ai-evaluation work, not experiment tracking",
|
|
37
|
+
"Hands off to or invokes the ai-evaluation skill",
|
|
38
|
+
"Does not answer primarily with MLflow/W&B run-logging or model-registry setup",
|
|
39
|
+
"Distinguishes deciding what to measure from recording and comparing the runs",
|
|
40
|
+
"Offers to set up tracking once the evaluation metrics are defined"
|
|
41
|
+
]
|
|
30
42
|
}
|
|
31
43
|
]
|
|
32
44
|
}
|
|
@@ -29,6 +29,18 @@
|
|
|
29
29
|
"Suggests a retraining pipeline with fresh data",
|
|
30
30
|
"Does NOT just say 'retrain the model' without diagnosing the cause"
|
|
31
31
|
]
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"id": 3,
|
|
35
|
+
"prompt": "Hold off on the serving setup. We've found the training job computes the account-age feature from the full table while serving computes it at request time, so they disagree. I need the feature pipeline redesigned so training and serving can't drift apart.",
|
|
36
|
+
"expected_output": "Scope boundary — training/serving skew and point-in-time-correct feature computation are ml-pipeline-design concerns. Should hand off rather than answering with serving infrastructure, canary or rollout strategy.",
|
|
37
|
+
"assertions": [
|
|
38
|
+
"Names the problem as training/serving skew rather than a deployment or rollout issue",
|
|
39
|
+
"Hands off to or invokes the ml-pipeline-design skill for the feature pipeline redesign",
|
|
40
|
+
"Does not answer with serving infrastructure, canary strategy, or inference endpoint design",
|
|
41
|
+
"Recognizes point-in-time correctness as the underlying requirement",
|
|
42
|
+
"Notes that deployment work resumes once the feature computation is unified"
|
|
43
|
+
]
|
|
32
44
|
}
|
|
33
45
|
]
|
|
34
46
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: plan-execution
|
|
3
|
-
description: "Execute an already-approved plan with discipline — batch tasks into verifiable checkpoints, verify each with fresh evidence before marking it done, log drift, and stop to re-plan when reality diverges from the plan's assumptions.
|
|
3
|
+
description: "Execute an already-approved plan with discipline — batch tasks into verifiable checkpoints, verify each with fresh evidence before marking it done, log drift, and stop to re-plan when reality diverges from the plan's assumptions. NOT for creating plans — 'plan this' / 'break this down' → feature-planning; this skill starts only after a plan exists and is approved."
|
|
4
|
+
when_to_use: "Triggers: execute the plan, implement the approved plan, work through this plan, continue/resume the plan, next phase, checkpoint."
|
|
4
5
|
allowed-tools: Read, Grep, Glob, Write, Edit, Bash
|
|
5
6
|
---
|
|
6
7
|
|
|
@@ -59,6 +60,34 @@ observed result. A failed verification means the checkpoint stays open — fix a
|
|
|
59
60
|
re-verify; two consecutive failed checkpoints are a re-planning trigger, not a
|
|
60
61
|
push-through-it signal.
|
|
61
62
|
|
|
63
|
+
**The checkpoint commit is part of this step, and it is checked.** A commit is the
|
|
64
|
+
first irreversible thing a plan produces, so it gets the same treatment as the
|
|
65
|
+
checkpoint claim: **invoke `verification-before-completion`** for the publish gate
|
|
66
|
+
and **`git-workflow`** for the message.
|
|
67
|
+
|
|
68
|
+
**Exit condition** — name both, by name, in the response where you commit:
|
|
69
|
+
*"Checkpoint N verified by `<command>`. Invoking `verification-before-completion`
|
|
70
|
+
on the staged diff, then `git-workflow` for the message."*
|
|
71
|
+
|
|
72
|
+
Do not paraphrase what those skills would check and call it done. Reproducing
|
|
73
|
+
their rules here is exactly how a plan accumulates twelve unreviewed commits with
|
|
74
|
+
a gate that felt "already satisfied" every time — you have their content in
|
|
75
|
+
context, which is what makes skipping the call feel free. If you can name the check
|
|
76
|
+
you are supposed to run, you can name the skill that owns it.
|
|
77
|
+
|
|
78
|
+
**The plan's vocabulary does not travel with the commit.** Checkpoint IDs, phase
|
|
79
|
+
names, task codes, finding numbers, and drift-log entries are *your* working
|
|
80
|
+
context — they name conversations, not code. They may appear in a commit message,
|
|
81
|
+
comment, or doc **only if the plan itself is a tracked file in this repo**; a plan
|
|
82
|
+
living in a scratchpad, a chat, or a gitignored directory defines nothing a reader
|
|
83
|
+
can look up. Otherwise write what the change means:
|
|
84
|
+
|
|
85
|
+
- ✗ `feat: complete CP2.3, Phase 2 done` ✗ `// fixes finding #12 from Phase 1`
|
|
86
|
+
- ✓ `feat(sync): add delta detection by content hash`
|
|
87
|
+
|
|
88
|
+
This is the one leak plan execution is uniquely prone to, precisely because the
|
|
89
|
+
vocabulary is loaded and fluent in context at the moment the message gets written.
|
|
90
|
+
|
|
62
91
|
### Step 4: Drift Check Before the Next Batch
|
|
63
92
|
|
|
64
93
|
At every checkpoint boundary, compare state against plan:
|
|
@@ -116,6 +145,9 @@ that still describes the pre-drift design is a stale document like any other.
|
|
|
116
145
|
| "This checkpoint is just docs/config — nothing to run" | Something proves it: render the docs, load the config, run the linter. |
|
|
117
146
|
| "The docs can come after the plan lands" | The plan changed what the docs describe; landing it leaves them actively wrong, and nobody re-derives the whole surface later. Reconcile at close-out. |
|
|
118
147
|
| "I already have the Iron Law in context, invoking the gate is redundant" | Quoting a law isn't running the gate. The plan-level checks (whole-plan verification, doc reconciliation) live there, not here. |
|
|
148
|
+
| "It's a mid-plan commit, the real gate is at close-out" | Commits are permanent when they're made, not when the plan ends. Close-out can't un-publish what checkpoint 2 already pushed. |
|
|
149
|
+
| "The checkpoint number gives the commit useful traceability" | Only if a reader can resolve it. If the plan isn't tracked in the repo, the number traces to nothing and displaces the sentence that would have explained the change. |
|
|
150
|
+
| "Everyone on this plan knows what CP2.3 means" | Everyone in this session does. The commit outlives the session, and its next reader has the repo and nothing else. |
|
|
119
151
|
| "The plan is outdated here; I'll adapt as I go" | That's drift. Log it; if it's structural, stop and re-plan — don't decide alone silently. |
|
|
120
152
|
| "This is an implementation detail, not an architecture decision" | Anything that persists — a table, a column, a config key, a shared module — is structure, whatever task it arrived under. Route it to the design skill. |
|
|
121
153
|
| "We're 80% through; re-planning now wastes all that work" | Sunk cost. Verified work survives a re-plan; pushing a broken plan wastes the remaining 20% *and* the rework. |
|
|
@@ -130,13 +162,16 @@ that still describes the pre-drift design is a stale document like any other.
|
|
|
130
162
|
- You're about to add a persistent construct (table, column, config key, shared
|
|
131
163
|
module) that the plan never named — and you haven't checked what already exists.
|
|
132
164
|
- You've stopped consulting the plan and are working from memory.
|
|
165
|
+
- You're committing at a checkpoint boundary and haven't read the staged diff.
|
|
166
|
+
- A phase name, checkpoint ID, or finding number is about to enter a commit
|
|
167
|
+
message, a code comment, or a doc — and the plan isn't a tracked file.
|
|
133
168
|
|
|
134
169
|
## Cross-Skill References
|
|
135
170
|
|
|
136
171
|
- `feature-planning` — creates and (on re-plan) revises the plan this skill executes
|
|
137
172
|
- `data-modeling` — where a schema question surfaced mid-execution belongs
|
|
138
173
|
- `architecture-design` — where a structural or boundary question belongs
|
|
139
|
-
- `verification-before-completion` — the per-claim evidence gate each checkpoint applies
|
|
174
|
+
- `verification-before-completion` — the per-claim evidence gate each checkpoint applies, and the publish gate on every checkpoint commit
|
|
140
175
|
- `tdd-workflow` — how the implementation tasks inside a batch get built
|
|
141
|
-
- `git-workflow` —
|
|
176
|
+
- `git-workflow` — writes the checkpoint commit (Step 3); the evidence belongs in the message
|
|
142
177
|
- `code-reviewing` — review at checkpoint or close-out, before "done" is claimed
|
|
@@ -84,6 +84,36 @@
|
|
|
84
84
|
"Names what the gate adds beyond per-checkpoint checks (whole-plan verification, doc reconciliation)",
|
|
85
85
|
"Does NOT accept 'it's the same content' as a reason to skip"
|
|
86
86
|
]
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"id": 4,
|
|
90
|
+
"prompt": "Checkpoint 2 of the migration plan is done — the delta-detection module is written and `pnpm test` is green, 88 passed. Commit it as 'feat: CP2 complete, findings #4 and #7 fixed' and let's move to checkpoint 3. The plan lives in my scratchpad, not the repo.",
|
|
91
|
+
"pressure": [
|
|
92
|
+
"time",
|
|
93
|
+
"authority"
|
|
94
|
+
],
|
|
95
|
+
"expected_behavior": "Treats the checkpoint commit as a gated action rather than a bookkeeping step: invokes verification-before-completion for the publish gate and git-workflow for the message instead of quoting their rules. Recognizes that a scratchpad plan anchors nothing, so 'CP2' and 'findings #4 and #7' cannot go into the commit message, and rewrites it to describe the change.",
|
|
96
|
+
"assertions": [
|
|
97
|
+
"Names `verification-before-completion` and `git-workflow` explicitly as the next step, rather than paraphrasing their checks inline",
|
|
98
|
+
"Identifies that the scratchpad plan is not a tracked file and therefore anchors nothing",
|
|
99
|
+
"Rewrites the commit subject to describe the change instead of the checkpoint ID",
|
|
100
|
+
"Does not carry 'findings #4 and #7' into the committed message",
|
|
101
|
+
"Still records the checkpoint evidence in its own status report to the user"
|
|
102
|
+
]
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"id": 5,
|
|
106
|
+
"prompt": "We're four checkpoints into the plan and I've been committing as we go. Let's keep the pace — commit checkpoint 5 now and we'll do the full publish review at close-out when everything's together.",
|
|
107
|
+
"pressure": [
|
|
108
|
+
"time",
|
|
109
|
+
"sunk_cost"
|
|
110
|
+
],
|
|
111
|
+
"expected_behavior": "Rejects deferring the publish gate to close-out: commits are permanent when made, and close-out cannot un-publish what earlier checkpoints already wrote. Runs the gate on this commit now.",
|
|
112
|
+
"assertions": [
|
|
113
|
+
"Rejects 'we'll review at close-out' as a reason to skip the gate on this commit",
|
|
114
|
+
"States that close-out cannot undo what an earlier commit already published",
|
|
115
|
+
"Runs the publish gate on the current staged diff before committing"
|
|
116
|
+
]
|
|
87
117
|
}
|
|
88
118
|
]
|
|
89
119
|
}
|
|
@@ -28,6 +28,19 @@
|
|
|
28
28
|
"Has open questions that invite reviewer input",
|
|
29
29
|
"Links to feature-planning for implementation task breakdown"
|
|
30
30
|
]
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"id": 3,
|
|
34
|
+
"prompt": "The PRD is signed off by product and design. Now turn it into the actual sprint backlog — tickets sized in points, ordered by dependency, with acceptance criteria on each one.",
|
|
35
|
+
"expected_output": "Scope boundary — the PRD owns the WHAT and WHY; decomposing it into ordered, sized tickets is feature-planning (with effort-estimation for the sizing). Should hand off rather than producing another requirements document.",
|
|
36
|
+
"assertions": [
|
|
37
|
+
"Recognizes that task breakdown and dependency ordering are feature-planning work",
|
|
38
|
+
"Hands off to or invokes the feature-planning skill",
|
|
39
|
+
"Routes the point sizing to effort-estimation rather than producing estimates inline",
|
|
40
|
+
"Does not produce another PRD, RFC, or requirements document",
|
|
41
|
+
"Articulates the WHAT/WHY versus HOW boundary explicitly",
|
|
42
|
+
"Confirms the approved PRD is the input the breakdown should be derived from"
|
|
43
|
+
]
|
|
31
44
|
}
|
|
32
45
|
]
|
|
33
46
|
}
|
|
@@ -29,6 +29,47 @@ Two modes use this skill. **Authoring** creates a document that doesn't exist ye
|
|
|
29
29
|
because a change made them wrong — that's the next section, and it's the mode you
|
|
30
30
|
want when someone says "I changed X" rather than "write me a Y".
|
|
31
31
|
|
|
32
|
+
## The Documentation Strategy — What Ships and What Doesn't
|
|
33
|
+
|
|
34
|
+
Establish once with the user: **which artifacts are git-versioned, and which stay
|
|
35
|
+
internal.** Most projects accumulate both, and only one of them is readable by
|
|
36
|
+
someone who has the repo and nothing else.
|
|
37
|
+
|
|
38
|
+
| Typically versioned | Typically internal |
|
|
39
|
+
|---|---|
|
|
40
|
+
| README, contributing guide, API docs, changelog | Execution plans and phase breakdowns |
|
|
41
|
+
| ADRs and architecture docs | Findings/bug logs kept during a work session |
|
|
42
|
+
| Roadmaps the project chooses to publish | Scratchpads, handoff prompts, session notes |
|
|
43
|
+
| Runbooks and operational docs | Anything under a gitignored directory |
|
|
44
|
+
|
|
45
|
+
This boundary is not bureaucracy — it decides what vocabulary the project's own
|
|
46
|
+
artifacts are allowed to use. **A term is usable in a versioned file only if a
|
|
47
|
+
versioned file defines it.** When a plan lives outside the repo, its phases,
|
|
48
|
+
checkpoints, and task codes name a conversation, and a reader hitting `Phase 2` or
|
|
49
|
+
`CP1.3` in a comment or commit has nothing to resolve it against. Write what the
|
|
50
|
+
term means instead.
|
|
51
|
+
|
|
52
|
+
The reverse also holds and matters just as much: when a project *does* ship its
|
|
53
|
+
plan or roadmap, referencing it is good practice, not a leak. Check which case
|
|
54
|
+
you're in rather than assuming either — `git ls-files` answers it.
|
|
55
|
+
|
|
56
|
+
**On a greenfield project** nothing is tracked yet, so this is a decision to make,
|
|
57
|
+
not a fact to look up.
|
|
58
|
+
|
|
59
|
+
**Exit condition** — one line, then write the document in the same response:
|
|
60
|
+
*"Nothing is tracked yet, so `<term>` resolves to nothing for a reader; I've
|
|
61
|
+
written the meaning instead. Worth deciding whether the plan itself ships."*
|
|
62
|
+
|
|
63
|
+
**This is not a gate on authoring.** Raise the boundary, apply the safe default —
|
|
64
|
+
meanings rather than labels, which is never wrong and costs nothing to change — and
|
|
65
|
+
deliver the document. Never answer a request for docs with the boundary question
|
|
66
|
+
alone: the user asked for a README, and a README that avoids unresolvable
|
|
67
|
+
vocabulary is strictly better than a question. Ask when the answer would change
|
|
68
|
+
what you write; otherwise state the assumption and write.
|
|
69
|
+
|
|
70
|
+
`verification-before-completion`'s publish gate reads this boundary as its baseline
|
|
71
|
+
when checking a staged diff.
|
|
72
|
+
|
|
32
73
|
## Workflow: Sync After a Change
|
|
33
74
|
|
|
34
75
|
Docs don't rot evenly. They rot where a change moved something a document names,
|
|
@@ -135,11 +176,19 @@ Follow Keep a Changelog conventions:
|
|
|
135
176
|
|
|
136
177
|
See [templates/changelog.md](templates/changelog.md) for the format.
|
|
137
178
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
179
|
+
**First check whether the project generates this file.** A `release-please-config.json`,
|
|
180
|
+
`.changeset/`, `.releaserc*`, or `cliff.toml` means the changelog is derived from commit
|
|
181
|
+
history, and hand-editing it — including keeping an `[Unreleased]` section alongside —
|
|
182
|
+
throws away the guarantee the tool exists to provide and reintroduces drift. There, the
|
|
183
|
+
entry is the **commit subject** (for squash-merges, the PR title) and the work is writing
|
|
184
|
+
that well; the reasoning goes in the commit body, not the changelog. Say so and stop.
|
|
185
|
+
|
|
186
|
+
When the changelog *is* hand-maintained, accumulate entries under `[Unreleased]` as
|
|
187
|
+
changes land. Writing them is this skill's work even when they must be reconstructed from
|
|
188
|
+
git history — read the log since the last tag, drop trivial commits (merges, typo fixes),
|
|
189
|
+
and translate the rest into user-perspective entries under the sections above. Hand off
|
|
190
|
+
only the release mechanics (version choice, tagging, publish automation) to
|
|
191
|
+
`release-management`.
|
|
143
192
|
|
|
144
193
|
## Workflow: Inline Documentation
|
|
145
194
|
|
|
@@ -147,12 +196,30 @@ For code-level documentation (JSDoc, Python docstrings, Go doc comments):
|
|
|
147
196
|
|
|
148
197
|
- **Document public APIs**: Every exported function, class, and type
|
|
149
198
|
- **Skip obvious code**: Don't document `getName()` returning a name
|
|
150
|
-
- **Document the why
|
|
199
|
+
- **Document the why — at the altitude it belongs**: this is where inline docs go
|
|
200
|
+
wrong most often. The why of a *line* belongs on the line: why this parameter
|
|
201
|
+
exists, why this comparison is written the strange way it is, what the caller
|
|
202
|
+
can't see. The why of a *system* — why the component exists, which alternatives
|
|
203
|
+
were rejected, how it relates to other services — belongs in an ADR or
|
|
204
|
+
architecture doc, and the code carries a pointer to it:
|
|
205
|
+
`// Triage state lives in a separate writable DB; see ADR-018.`
|
|
206
|
+
A design rationale pasted into a file header is unfindable (nobody greps source
|
|
207
|
+
for "why two databases"), unreviewable (it never gets the scrutiny an ADR gets),
|
|
208
|
+
and rots first — nobody re-reads a file header while editing line 300.
|
|
151
209
|
- **Include examples** for non-obvious usage
|
|
152
210
|
- **Document exceptions/errors**: What can go wrong and under what conditions
|
|
211
|
+
- **Use vocabulary the reader can resolve**: no phase names, checkpoint IDs, or
|
|
212
|
+
task codes that no versioned document defines (see The Documentation Strategy)
|
|
153
213
|
|
|
154
214
|
## Principles Applied
|
|
155
215
|
|
|
156
216
|
- **KISS**: Write the minimum documentation that makes the project usable. Don't over-document internals.
|
|
157
217
|
- **DRY**: Don't duplicate information across docs. Link between documents instead.
|
|
158
218
|
- **YAGNI**: Don't write architecture docs for a 200-line script. Match documentation depth to project complexity. And don't create docs nobody asked for — a doc that merely restates the code is doc-slop: it goes stale immediately and buries the docs that answer real questions. Every document must answer a question someone actually has.
|
|
219
|
+
|
|
220
|
+
## Cross-Skill References
|
|
221
|
+
|
|
222
|
+
- `architecture-design` — the ADR a system-level rationale belongs in, rather than a source-file header
|
|
223
|
+
- `architecture-documentation` — C4 diagrams and docs-as-code for the architecture docs this skill points at
|
|
224
|
+
- `verification-before-completion` — the doc-drift and publish gates that read the versioned/internal boundary above
|
|
225
|
+
- `technical-debt-review` — a repo-wide doc-rot audit, as opposed to the drift from the change in front of you
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"prompt": "Write a README for my project. It's a Node.js REST API for a task management app built with Express, Prisma, and PostgreSQL. It has authentication with JWT, CRUD for tasks and projects, and runs in Docker for local dev.",
|
|
7
7
|
"expected_output": "Should read the codebase first if available, then produce a complete README with all essential sections. Should include working setup instructions and actual environment variables from the project.",
|
|
8
8
|
"assertions": [
|
|
9
|
-
"
|
|
9
|
+
"Grounds the README in the project's actual manifest/codebase, or states which files it must read to do so",
|
|
10
10
|
"Starts with a clear one-line description of what the project does",
|
|
11
11
|
"Includes prerequisites with specific versions",
|
|
12
12
|
"Setup instructions go from git clone to running server",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"Lists environment variables needed with descriptions",
|
|
15
15
|
"Includes verification step (e.g., 'visit localhost:3000/health')",
|
|
16
16
|
"Code examples are copy-pasteable",
|
|
17
|
-
"
|
|
17
|
+
"Delivers the complete README content, ready to be written to README.md at the project root"
|
|
18
18
|
]
|
|
19
19
|
},
|
|
20
20
|
{
|
|
@@ -85,6 +85,21 @@
|
|
|
85
85
|
"Redirects to reconciling what the refactor actually made wrong",
|
|
86
86
|
"Asks what question a proposed document answers / who its reader is before writing it"
|
|
87
87
|
]
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"id": 4,
|
|
91
|
+
"prompt": "Starting a new repo — nothing committed yet beyond the source. Write the README and an architecture doc. We're working from a five-phase build plan I keep in my notes app, so reference the phases throughout so the docs line up with how we're actually building it.",
|
|
92
|
+
"pressure": [
|
|
93
|
+
"authority"
|
|
94
|
+
],
|
|
95
|
+
"expected_behavior": "Establishes the versioned-vs-internal boundary before authoring rather than after, and declines to build the docs around phase references that no versioned document defines — a reader with only the repo cannot resolve them. Offers the alternatives: publish the plan into the repo so the references anchor, or write what each phase means. Does not refuse to write the docs.",
|
|
96
|
+
"assertions": [
|
|
97
|
+
"Raises the versioned-vs-internal boundary before writing",
|
|
98
|
+
"Identifies that a notes-app plan does not anchor phase references in the repo",
|
|
99
|
+
"Offers either tracking the plan or writing the meanings instead of the labels",
|
|
100
|
+
"Still delivers the README and architecture doc",
|
|
101
|
+
"Does not scatter unresolvable phase references through the docs"
|
|
102
|
+
]
|
|
88
103
|
}
|
|
89
104
|
]
|
|
90
105
|
}
|