swe-workflow-skills 0.6.2 → 0.7.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/VERSION +1 -1
- package/catalog.json +2 -2
- package/package.json +1 -1
- package/skills/architecture-design/SKILL.md +32 -1
- 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/configuration-strategy/SKILL.md +27 -0
- package/skills/data-modeling/SKILL.md +31 -1
- package/skills/frontend-architecture/SKILL.md +29 -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/plan-execution/SKILL.md +51 -3
- package/skills/plan-execution/evals/evals.json +30 -0
- package/skills/project-documentation/SKILL.md +73 -6
- package/skills/project-documentation/evals/evals.json +17 -2
- package/skills/release-management/SKILL.md +1 -1
- package/skills/verification-before-completion/SKILL.md +109 -2
- package/skills/verification-before-completion/evals/evals.json +64 -3
- package/skills/verification-before-completion/references/pre-commit-gate.md +239 -0
- package/skills/writing-skills/SKILL.md +37 -1
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
# The Pre-Commit Publish Gate
|
|
2
|
+
|
|
3
|
+
Detail for the three checks in SKILL.md's *"What you're about to publish"*. Read
|
|
4
|
+
the leg that tripped; you rarely need all three.
|
|
5
|
+
|
|
6
|
+
The shared premise: a commit is permanent and public-by-default-eventually. Tests
|
|
7
|
+
and the doc gate both look at whether the code is *correct*. These three look at
|
|
8
|
+
whether it is *publishable* — a different question, with no other gate behind it.
|
|
9
|
+
|
|
10
|
+
## Contents
|
|
11
|
+
- Leg 1 — personal data and secrets
|
|
12
|
+
- Leg 2 — the anchor check for internal terminology
|
|
13
|
+
- Leg 3 — comment placement
|
|
14
|
+
- What this gate is not
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Leg 1 — Personal data and secrets
|
|
19
|
+
|
|
20
|
+
### Where to look
|
|
21
|
+
|
|
22
|
+
The scan runs on every commit — it costs seconds and a clean result is one line,
|
|
23
|
+
so there's no threshold worth defending. What *is* worth knowing is where personal
|
|
24
|
+
data actually shows up, so the scan is attentive rather than uniform:
|
|
25
|
+
|
|
26
|
+
| Surface | Examples |
|
|
27
|
+
|---|---|
|
|
28
|
+
| Data files | `.csv`, `.json`, `.sql` dumps, `.parquet`, spreadsheets, seed data |
|
|
29
|
+
| Test fixtures | recorded API responses, cassettes, snapshot files, factories with literal values |
|
|
30
|
+
| Config & secrets | `.env*`, credentials files, connection strings, CI variables, deploy manifests |
|
|
31
|
+
| Logs & captures | log excerpts, stack traces with payloads, screenshots, HAR files, session recordings |
|
|
32
|
+
| Docs with examples | READMEs and runbooks pasting a "real" request/response, a hostname, a user record |
|
|
33
|
+
|
|
34
|
+
A pure source-code refactor touches none of these — that's the common case, and it
|
|
35
|
+
closes in the exit-condition line without further thought. The cost of the scan is
|
|
36
|
+
supposed to be near zero; anything that makes it feel expensive is a bug in how
|
|
37
|
+
you're running it, not diligence.
|
|
38
|
+
|
|
39
|
+
### Read what's already been decided first
|
|
40
|
+
|
|
41
|
+
The project usually has an answer; ask only when it doesn't. In order:
|
|
42
|
+
|
|
43
|
+
1. **`CLAUDE.md` / project instructions** — often names the protected surfaces
|
|
44
|
+
outright ("never commit data/", "the client list is confidential").
|
|
45
|
+
2. **Memory files** — standing instructions from earlier sessions.
|
|
46
|
+
3. **`.gitignore`** — what's excluded is a direct statement of what shouldn't be
|
|
47
|
+
committed. A staged file matching an ignored *pattern* (force-added, or a
|
|
48
|
+
near-miss like `data/sample.csv` beside an ignored `data/*.csv`) is a signal.
|
|
49
|
+
4. **Existing fixtures** — if every other fixture uses `user@example.com` and
|
|
50
|
+
yours has a real address, the convention already answered the question.
|
|
51
|
+
5. **Standing instruction in this session.**
|
|
52
|
+
|
|
53
|
+
### When nothing is declared, ask — before the commit
|
|
54
|
+
|
|
55
|
+
One question, scoped to what you actually found, at the moment it matters:
|
|
56
|
+
|
|
57
|
+
> `fixtures/accounts.json` has 40 records with what look like real names, emails
|
|
58
|
+
> and phone numbers. Is this data safe to commit, or should I replace it with
|
|
59
|
+
> synthetic values?
|
|
60
|
+
|
|
61
|
+
Ask once per project and remember the answer. Do not re-ask on every commit — a
|
|
62
|
+
question that becomes ritual gets answered reflexively, which is worse than not
|
|
63
|
+
asking.
|
|
64
|
+
|
|
65
|
+
The question rides along with the rest of your response; it doesn't hold the work
|
|
66
|
+
hostage. If the user has already said this data is fine, that's the answer — note
|
|
67
|
+
it and commit.
|
|
68
|
+
|
|
69
|
+
### The response ladder
|
|
70
|
+
|
|
71
|
+
**Nothing on this ladder blocks the commit.** What changes with severity is how
|
|
72
|
+
loudly you say it and what consequence you name — never whether you proceed. A
|
|
73
|
+
refusal doesn't prevent the leak; the commit just happens without you, minus the
|
|
74
|
+
one participant who spotted it. Report, name the cost, and let the user choose.
|
|
75
|
+
|
|
76
|
+
| Finding | What to say |
|
|
77
|
+
|---|---|
|
|
78
|
+
| Live credentials — API keys, tokens, private keys, passwords, connection strings with secrets | The loudest rung. Say plainly that **the credential should be treated as already compromised** the moment it lands in a commit, so the fix is **rotation**, not deletion — deleting it from the diff leaves a valid secret in a file someone had. Point at `configuration-strategy` (env var, secret manager). Then do what the user says. |
|
|
79
|
+
| Real personal data — names, emails, phones, addresses, IDs, health/financial records | Name what's exposed and offer the three ways out: *redact* (mask in place), *synthesize* (generated equivalents — `test-data-strategy` keeps the shape correct), or *proceed with the risk on the record*. |
|
|
80
|
+
| Internal-but-not-personal — hostnames, internal URLs, org chart details, client names, file paths with usernames | Flag it, name the exposure in one line, move on. The user knows their audience better than you do, and this is where over-reacting does the most damage to the gate's credibility. |
|
|
81
|
+
| Plausibly-fake data you can't distinguish from real | Ask, in the same response as everything else. `john.smith@gmail.com` in a fixture is either fine or a person, and one question is cheaper than either mistake. |
|
|
82
|
+
|
|
83
|
+
The one thing that *is* mandatory: the finding reaches the user **before** the
|
|
84
|
+
commit, not after. Timing is the whole value — everything downstream of a push is
|
|
85
|
+
recovery.
|
|
86
|
+
|
|
87
|
+
### Handling rule: don't leak while checking
|
|
88
|
+
|
|
89
|
+
Checking for a leak must not create one.
|
|
90
|
+
|
|
91
|
+
- **Match on shape and location, not on value.** Report *"`config/prod.yml:14` holds
|
|
92
|
+
what looks like a live database password"*, never the password.
|
|
93
|
+
- **Never paste a real value into your reply, a commit message, a doc, or a
|
|
94
|
+
subagent prompt** to demonstrate that it exists. The file and line prove it.
|
|
95
|
+
- When redacting, edit in place. Don't quote the original into the conversation
|
|
96
|
+
as a "before" for comparison.
|
|
97
|
+
- This holds even when the user asks you to verify a value loaded correctly —
|
|
98
|
+
confirm presence and shape, not content.
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Leg 2 — The anchor check for internal terminology
|
|
103
|
+
|
|
104
|
+
### The problem
|
|
105
|
+
|
|
106
|
+
Planning vocabulary is *session* context. Phases, checkpoints, task codes, and
|
|
107
|
+
finding numbers are how the work was organized in a conversation — they are not
|
|
108
|
+
facts about the codebase. When they land in a versioned file, a reader who has
|
|
109
|
+
only the repo hits a reference they cannot resolve, and there is nothing to look
|
|
110
|
+
it up in.
|
|
111
|
+
|
|
112
|
+
### The shapes that trip it
|
|
113
|
+
|
|
114
|
+
`Phase 2` · `Fase 4` · `CP1.3` · `checkpoint 3/5` · `T02` · `P2-E08` ·
|
|
115
|
+
`finding #17` · `Sprint 4` · `Milestone 2` · `WP3` — in **any** staged content:
|
|
116
|
+
code comments, commit messages, PR descriptions, docs, test names, log strings.
|
|
117
|
+
|
|
118
|
+
### The rule is the anchor, not the token
|
|
119
|
+
|
|
120
|
+
The same string is correct in one repo and a leak in the next. Never blacklist
|
|
121
|
+
the vocabulary; check whether it resolves.
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
# Does a TRACKED document define this identifier?
|
|
125
|
+
git ls-files '*.md' | xargs grep -l "P2-E08"
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
- **Anchored** — a git-tracked document (an execution plan under `docs/`, an ADR,
|
|
129
|
+
a roadmap, a tracked issue reference) defines the term. Keep it: it's a real
|
|
130
|
+
cross-reference, and stripping it would lose information. Prefer making the
|
|
131
|
+
pointer explicit (`per docs/roadmap.md#p2-e08`) over the bare label.
|
|
132
|
+
- **Unanchored** — the only definition lives in a plan file that is gitignored,
|
|
133
|
+
in a chat, in a scratchpad, or in your own context. **Write what it means
|
|
134
|
+
instead of what it was called.**
|
|
135
|
+
|
|
136
|
+
### Rewriting, not deleting
|
|
137
|
+
|
|
138
|
+
The information is usually worth keeping; only the label is unusable. The
|
|
139
|
+
sentence gets *better*, not shorter:
|
|
140
|
+
|
|
141
|
+
| Unanchored | Rewritten |
|
|
142
|
+
|---|---|
|
|
143
|
+
| `// Dashboard aggregates (Phase 4). All read-only.` | `// Dashboard aggregates. All read-only.` |
|
|
144
|
+
| `/** Build the re-ask prompt (findings #30). */` | `/** Build the re-ask prompt. The subject re-answers with the required keys when the first response omits them. */` |
|
|
145
|
+
| `// citty collapses a repeated string flag to its last value (finding #17)` | `// citty collapses a repeated string flag to its last value` |
|
|
146
|
+
| `feat: complete Phase 2, CP2.3 bugs fixed` | `feat(sync): add delta detection and fix the duplicate-row load` |
|
|
147
|
+
| `* From-tarball smoke test (checkpoint 3/5 verification)` | `* From-tarball smoke test: proves the bundle needs no repo layout` |
|
|
148
|
+
|
|
149
|
+
Note what happens in each: the label carried no information a reader could use,
|
|
150
|
+
so removing it costs nothing, and the space it freed is where the actual meaning
|
|
151
|
+
goes.
|
|
152
|
+
|
|
153
|
+
### Greenfield projects
|
|
154
|
+
|
|
155
|
+
A new repo has no tracked docs, so *everything* is unanchored and the check would
|
|
156
|
+
reject all of it. That's the wrong outcome. When a project hasn't decided what it
|
|
157
|
+
documents, that decision is the work — route to `project-documentation` to
|
|
158
|
+
establish which artifacts are versioned and which stay internal. Until then,
|
|
159
|
+
default to writing meanings, which is never wrong.
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Leg 3 — Comment placement
|
|
164
|
+
|
|
165
|
+
### When it trips
|
|
166
|
+
|
|
167
|
+
A new comment block of **four or more lines**. Short comments are rarely the
|
|
168
|
+
problem; the failure mode is the module-header essay that reproduces an
|
|
169
|
+
architecture document inside a source file.
|
|
170
|
+
|
|
171
|
+
### The placement rule
|
|
172
|
+
|
|
173
|
+
Three destinations, decided by what the comment explains:
|
|
174
|
+
|
|
175
|
+
| The comment explains | Where it belongs |
|
|
176
|
+
|---|---|
|
|
177
|
+
| A **system** — why this component exists, which alternatives were rejected, how it relates to other services, a cross-cutting constraint | An ADR or architecture doc. The comment keeps a one-line pointer: `// See ADR-018 for why triage state is a separate database.` |
|
|
178
|
+
| A **local invariant** — why *this* line is written the strange way it is, a consequence the caller can't see, a boundary condition the types don't express | Inline, right where it is. This is what comments are for. |
|
|
179
|
+
| **What the code does** | Nowhere. Delete it; the code says it already. |
|
|
180
|
+
|
|
181
|
+
### Why the pointer beats the essay
|
|
182
|
+
|
|
183
|
+
Not a style preference — the essay is worse on its own terms:
|
|
184
|
+
|
|
185
|
+
- It rots invisibly. Nobody re-reads a 12-line header when editing line 300, so
|
|
186
|
+
it drifts into describing a design the file no longer implements, and a
|
|
187
|
+
confidently wrong comment is worse than none.
|
|
188
|
+
- It's unfindable. Someone asking "why two databases?" greps the docs, not
|
|
189
|
+
`triage.ts`.
|
|
190
|
+
- It's unreviewable. Architecture stated in a source comment never gets the
|
|
191
|
+
scrutiny the same claim would get in an ADR.
|
|
192
|
+
|
|
193
|
+
### Calibration — the same length, opposite verdicts
|
|
194
|
+
|
|
195
|
+
**Keep** — a local invariant the types can't express, exactly where it's needed:
|
|
196
|
+
|
|
197
|
+
```ts
|
|
198
|
+
/**
|
|
199
|
+
* Append an inclusive from/to date-range filter. Both ends compare the DATE part
|
|
200
|
+
* (`date(col) >= date(?)`) so a picked `to` day includes that whole day — a plain
|
|
201
|
+
* `col <= '2026-07-14'` would drop everything after midnight.
|
|
202
|
+
*/
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
**Move** — a system decision that belongs in the ADR it already cites:
|
|
206
|
+
|
|
207
|
+
```ts
|
|
208
|
+
/**
|
|
209
|
+
* User-authored triage state is NOT derivable from the archive, so it can't live
|
|
210
|
+
* in the rebuildable analytics DB — detect() wipes and re-inserts findings on
|
|
211
|
+
* every ingest, and `ingest --full` drops every analytics table. Instead it lives
|
|
212
|
+
* in a separate, writable triage.db that ingest never touches, keyed by the
|
|
213
|
+
* stable finding id, so triage survives re-detection and full rebuilds. The
|
|
214
|
+
* analytics handle stays read-only: it only ATTACHes this file to JOIN...
|
|
215
|
+
*/
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
→ `// Triage state lives in a separate writable DB; see ADR-018.`
|
|
219
|
+
|
|
220
|
+
`code-slop-cleanup`'s [slop-patterns.md](../../code-slop-cleanup/references/slop-patterns.md)
|
|
221
|
+
holds the full comment-slop catalog with its "when it's NOT slop" columns.
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## What this gate is not
|
|
226
|
+
|
|
227
|
+
- **Not a code review.** Three greps over a diff you already have open. If they
|
|
228
|
+
trip on a code diff, `code-reviewing` does the reviewing.
|
|
229
|
+
- **Not a security audit.** It catches what's in *this diff*. Auditing the repo,
|
|
230
|
+
its history, or its dependencies is `security-audit`.
|
|
231
|
+
- **Not a compliance program.** GDPR/CCPA obligations, retention policy, data
|
|
232
|
+
mapping, and DSR handling are `compliance-privacy`. This gate is the commit-time
|
|
233
|
+
instance of a policy that skill defines.
|
|
234
|
+
- **Not a veto.** No finding on any leg stops a commit. The agent's job is that the
|
|
235
|
+
check ran and the finding is on the record before the push; the decision was
|
|
236
|
+
always the user's, and they hold context you don't. The one thing this gate must
|
|
237
|
+
never do is make committing feel expensive enough to route around — a gate that
|
|
238
|
+
gets bypassed protects nothing, and that is a far more common ending than a gate
|
|
239
|
+
that was too lenient.
|
|
@@ -34,6 +34,15 @@ tends to over-explain things Claude already knows and miss the real failure mode
|
|
|
34
34
|
3. **REFACTOR — re-test, capture *new* rationalizations, add counters.** Repeat
|
|
35
35
|
until the behavior holds under pressure. Stop when two consecutive runs pass.
|
|
36
36
|
|
|
37
|
+
**When it doesn't pass, stop by rule, not by patience.** Before each rewrite, name
|
|
38
|
+
the cause you believe is responsible and change *only* that. If the number doesn't
|
|
39
|
+
move, the hypothesis is dead — do not reword the same section a third time. Either
|
|
40
|
+
the assertion is unsatisfiable in this harness (see EVALS.md limitations 3 and 4:
|
|
41
|
+
reference-dependent and tool-dependent), or the behavior is a real cost of the
|
|
42
|
+
skill and belongs in the test's `expected_behavior` as an accepted trade with its
|
|
43
|
+
mechanism recorded. Both endings are results. Endless rewording is how a skill
|
|
44
|
+
grows to satisfy an instrument instead of a user.
|
|
45
|
+
|
|
37
46
|
### Match the form to the failure
|
|
38
47
|
|
|
39
48
|
| Baseline failure | Right form in the skill |
|
|
@@ -42,6 +51,30 @@ tends to over-explain things Claude already knows and miss the real failure mode
|
|
|
42
51
|
| Output has the wrong shape | A positive recipe / template stating what the output *is* |
|
|
43
52
|
| Omits a required element | A structural requirement (named field or slot) |
|
|
44
53
|
| Behavior should depend on a condition | A conditional rule ("if X, do Y"), not a blanket rule + exceptions |
|
|
54
|
+
| Skill defers instead of delivering | The grounding instruction needs a **delivery clause** (below) |
|
|
55
|
+
|
|
56
|
+
### Grounding instructions need a delivery clause
|
|
57
|
+
|
|
58
|
+
Any instruction of the form *"read/inventory/verify X before you answer"* degrades
|
|
59
|
+
into *"ask permission to read X, deliver later"* unless you say otherwise. This is
|
|
60
|
+
the most-repeated authoring failure in this library — five occurrences across two
|
|
61
|
+
cycles, in `architecture-design`/`data-modeling` (Step 0's first draft),
|
|
62
|
+
`project-documentation` (twice), `verification-before-completion`, and
|
|
63
|
+
`git-workflow` — and the base model, having no such instruction, often scores
|
|
64
|
+
*better* because it just answers.
|
|
65
|
+
|
|
66
|
+
Every grounding step must carry three things, and they are cheap:
|
|
67
|
+
|
|
68
|
+
1. **"This is not a gate on delivering."** Say it in those words.
|
|
69
|
+
2. **An exit condition** — the literal one-line sentence that closes the step, so
|
|
70
|
+
the model has something concrete to emit instead of a question.
|
|
71
|
+
3. **"…in the same response."** Plus the fallback: when the artifact can't be read,
|
|
72
|
+
state the assumption and deliver anyway. A draft the user corrects beats a
|
|
73
|
+
question they must answer.
|
|
74
|
+
|
|
75
|
+
`architecture-design` Step 0 is the reference implementation — copy its shape rather
|
|
76
|
+
than reinventing it. The tell in an eval is a GREEN reply that contains no artifact:
|
|
77
|
+
no message, no document, no recommendation, just a plan to produce one.
|
|
45
78
|
|
|
46
79
|
## Description discipline (the highest-leverage line)
|
|
47
80
|
|
|
@@ -104,7 +137,10 @@ As base models improve, a skill can become pure overhead. Once per release cycle
|
|
|
104
137
|
— or on a major base-model update — re-run the skill's 3 evals RED on shipping
|
|
105
138
|
models via `evals/workflow-runner.mjs`; re-sample ×3 on borderline scores and
|
|
106
139
|
read the judge journal before calling a result variance (a "flaky" case is often
|
|
107
|
-
a real content gap the skill causes).
|
|
140
|
+
a real content gap the skill causes). **First check the skill's reference mass:**
|
|
141
|
+
the harnesses can't read `references/` or `templates/`, so where that content
|
|
142
|
+
rivals `SKILL.md` the RED ≈ GREEN verdict is a harness artifact — judge those by
|
|
143
|
+
hand instead. Otherwise, if RED ≈ GREEN across all 3 evals (0/0
|
|
108
144
|
tool-dependent assertion pairs don't count), **slim first** — cut what the model
|
|
109
145
|
does unaided; keep the Iron Law, boundaries, and cross-skill references — then
|
|
110
146
|
re-run GREEN (gate: GREEN ≥ RED per case). Retire only after a slimmed skill
|