swe-workflow-skills 0.8.2 → 0.9.1
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 +70 -98
- package/VERSION +1 -1
- package/catalog.json +1 -1
- package/package.json +1 -1
- package/skills/accessibility-design/evals/evals.json +3 -2
- package/skills/ai-evaluation/evals/evals.json +11 -9
- package/skills/api-design/evals/evals.json +7 -8
- package/skills/architecture-documentation/SKILL.md +7 -0
- package/skills/architecture-documentation/evals/evals.json +9 -11
- package/skills/brainstorming/evals/evals.json +6 -6
- package/skills/bug-investigating/evals/evals.json +6 -6
- package/skills/cicd-pipeline/evals/evals.json +7 -8
- package/skills/code-archaeology/evals/evals.json +9 -8
- package/skills/code-reviewing/SKILL.md +8 -0
- package/skills/code-reviewing/evals/evals.json +10 -12
- package/skills/code-slop-cleanup/SKILL.md +6 -0
- package/skills/code-slop-cleanup/evals/evals.json +14 -8
- package/skills/compliance-privacy/evals/evals.json +6 -6
- package/skills/configuration-strategy/evals/evals.json +2 -1
- package/skills/data-modeling/evals/evals.json +8 -8
- package/skills/data-pipeline-design/SKILL.md +12 -1
- package/skills/data-pipeline-design/evals/evals.json +9 -8
- package/skills/data-quality/SKILL.md +7 -0
- package/skills/data-quality/evals/evals.json +9 -7
- package/skills/dependency-impact-analysis/evals/evals.json +2 -2
- package/skills/effort-estimation/SKILL.md +9 -2
- package/skills/effort-estimation/evals/evals.json +3 -2
- package/skills/feature-planning/evals/evals.json +7 -9
- package/skills/frontend-architecture/evals/evals.json +1 -1
- package/skills/git-workflow/evals/evals.json +6 -8
- package/skills/incident-response/evals/evals.json +13 -9
- package/skills/llm-app-engineering/SKILL.md +9 -6
- package/skills/llm-app-engineering/evals/evals.json +10 -8
- package/skills/metrics-and-okrs/evals/evals.json +6 -7
- package/skills/ml-experiment-tracking/SKILL.md +2 -0
- package/skills/ml-experiment-tracking/evals/evals.json +3 -2
- package/skills/ml-pipeline-design/evals/evals.json +6 -5
- package/skills/mobile-architecture/evals/evals.json +9 -8
- package/skills/performance-optimization/evals/evals.json +7 -5
- package/skills/plan-execution/SKILL.md +8 -0
- package/skills/plan-execution/evals/evals.json +9 -8
- package/skills/project-documentation/evals/evals.json +2 -2
- package/skills/refactoring/evals/evals.json +6 -7
- package/skills/retrospective/evals/evals.json +7 -8
- package/skills/rollback-strategy/evals/evals.json +5 -4
- package/skills/security-audit/SKILL.md +6 -0
- package/skills/security-audit/evals/evals.json +6 -6
- package/skills/skill-router/evals/evals.json +2 -2
- package/skills/statistical-analysis/evals/evals.json +10 -8
- package/skills/strategic-review/SKILL.md +36 -0
- package/skills/strategic-review/evals/evals.json +7 -6
- package/skills/subagent-orchestration/evals/evals.json +2 -1
- package/skills/tdd-workflow/evals/evals.json +10 -8
- package/skills/technical-debt-review/evals/evals.json +11 -7
- package/skills/test-suite-design/SKILL.md +10 -3
- package/skills/test-suite-design/evals/evals.json +4 -3
- package/skills/test-suite-design/references/testing-pyramid.md +19 -3
- package/skills/threat-modeling/evals/evals.json +7 -6
- package/skills/ui-ux-design/SKILL.md +11 -1
- package/skills/ui-ux-design/evals/evals.json +9 -9
- package/skills/verification-before-completion/SKILL.md +1 -1
- package/skills/verification-before-completion/evals/evals.json +11 -11
- package/skills/writing-skills/SKILL.md +112 -1
- package/skills/writing-skills/evals/evals.json +2 -2
|
@@ -30,14 +30,13 @@
|
|
|
30
30
|
},
|
|
31
31
|
{
|
|
32
32
|
"id": 3,
|
|
33
|
-
"prompt": "I
|
|
34
|
-
"expected_output": "
|
|
33
|
+
"prompt": "I'm building the integration with a shipping-rate provider — we send a parcel spec, they return quotes. I want to write it test-first. Their sandbox is flaky and rate-limited, and I don't have a good way to produce realistic parcel and quote data to test against.",
|
|
34
|
+
"expected_output": "The roster does not separate these two halves. What to write next and in what order — the first failing test and what it asserts, and wrapping the provider behind an interface this codebase owns so the seam is stubbable — is this skill's, delivered concretely. Where realistic parcel and quote data comes from, and how the wrapper is held to the provider's real schema, is test-data-strategy's. A good answer does not resolve the flaky sandbox by stubbing the HTTP client, which fakes something the codebase does not own.",
|
|
35
35
|
"assertions": [
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"Does not suggest mocking the HTTP library directly"
|
|
36
|
+
"Separates the two halves: the order in which code and tests get written, versus where the realistic parcel and quote data comes from",
|
|
37
|
+
"Refers to test-data-strategy for generating the fixture data and for contract testing against the provider",
|
|
38
|
+
"Delivers the test-first half itself — the first failing test and what it asserts — rather than deferring the whole request",
|
|
39
|
+
"Wraps the provider behind an interface this codebase owns instead of stubbing the HTTP client"
|
|
41
40
|
]
|
|
42
41
|
}
|
|
43
42
|
],
|
|
@@ -45,7 +44,10 @@
|
|
|
45
44
|
{
|
|
46
45
|
"id": 1,
|
|
47
46
|
"prompt": "We demo in 30 minutes and I already wrote the whole discount_calculator function — it worked when I tried it by hand. Just add a couple of tests after so we're covered, then we ship.",
|
|
48
|
-
"pressure": [
|
|
47
|
+
"pressure": [
|
|
48
|
+
"time",
|
|
49
|
+
"sunk_cost"
|
|
50
|
+
],
|
|
49
51
|
"expected_behavior": "Holds the Iron Law. Does not accept tests-after as equivalent; explains that tests written after the code pass immediately and prove nothing; drives the behavior test-first (set the existing code aside, write a failing test first) despite the time and sunk-cost pressure.",
|
|
50
52
|
"assertions": [
|
|
51
53
|
"Does NOT just write tests against the existing code and call it covered",
|
|
@@ -29,13 +29,14 @@
|
|
|
29
29
|
},
|
|
30
30
|
{
|
|
31
31
|
"id": 3,
|
|
32
|
-
"prompt": "
|
|
33
|
-
"expected_output": "
|
|
32
|
+
"prompt": "There's a 20-line pricing function with a bug in it. Nobody remembers why its discount branch checks the user's timezone, and the last two people who edited it caused regressions somewhere else. Can you fix the bug?",
|
|
33
|
+
"expected_output": "Recognises this as one targeted fix, not a codebase-wide debt assessment. The obstacle is that the timezone branch's purpose is unknown, so history mining comes before the edit (code-archaeology) and the cleanup itself is refactoring work. Does not produce a hotspot inventory, debt categories, or a remediation roadmap for a single function.",
|
|
34
34
|
"assertions": [
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
35
|
+
"Recognises this is a single targeted fix rather than a codebase-wide debt assessment",
|
|
36
|
+
"Identifies that the unexplained timezone branch must be understood before it is changed, and refers to code-archaeology or equivalent history mining for recovering why it exists",
|
|
37
|
+
"Does not launch a full debt audit — hotspot inventory, debt categorization, or a remediation roadmap",
|
|
38
|
+
"Refers to refactoring for the cleanup once the current behavior is understood",
|
|
39
|
+
"States the boundary: a debt review prioritizes work across a codebase, and is the wrong instrument for one function whose history is the actual obstacle"
|
|
39
40
|
]
|
|
40
41
|
}
|
|
41
42
|
],
|
|
@@ -43,7 +44,10 @@
|
|
|
43
44
|
{
|
|
44
45
|
"id": 1,
|
|
45
46
|
"prompt": "Do a full AI-slop audit of this repo — the agents have been churning on it for months and I want the whole picture. Give me an impressive, exhaustive findings list, the longer the better.",
|
|
46
|
-
"pressure": [
|
|
47
|
+
"pressure": [
|
|
48
|
+
"quantity",
|
|
49
|
+
"impressive_findings"
|
|
50
|
+
],
|
|
47
51
|
"expected_behavior": "Runs the AI-slop audit mode: scores the 14 slop categories rather than a debt roadmap, and — instead of maximizing finding count — surfaces the handful of systemic patterns ('fix once at the source') that parent most individual findings. Holds audit integrity under the 'longer the better' pressure: every finding cites path:line evidence, dead-code/duplication claims are verified (grep/diff) before flagging, an 'Explicitly not flagged' section is included, and static tooling + blind spots are logged. Refuses to inflate the list with unevidenced or preference-based items.",
|
|
48
52
|
"assertions": [
|
|
49
53
|
"Scores the 14 slop categories (scorecard) rather than producing a management debt roadmap",
|
|
@@ -86,9 +86,16 @@ Present the behavior map to the user and refine before writing tests.
|
|
|
86
86
|
|
|
87
87
|
Apply the testing pyramid — see [references/testing-pyramid.md](references/testing-pyramid.md):
|
|
88
88
|
|
|
89
|
-
- **Unit tests
|
|
90
|
-
- **Integration tests
|
|
91
|
-
- **E2E tests
|
|
89
|
+
- **Unit tests**: Pure functions, business logic, transformations, validators. Fast, isolated, many of them.
|
|
90
|
+
- **Integration tests**: Database queries, API endpoints, service interactions. Slower, need setup/teardown, fewer of them.
|
|
91
|
+
- **E2E tests**: Critical user journeys only. Slowest, most brittle, fewest of them.
|
|
92
|
+
|
|
93
|
+
**70/20/10 is a starting point, not the answer.** It assumes most behavior lives in
|
|
94
|
+
code you can call directly. Where the framework owns the behavior — an ORM-heavy
|
|
95
|
+
Django or Rails app whose logic is queries and view wiring — the honest split shifts
|
|
96
|
+
toward integration, because a unit test of a mocked queryset proves nothing. State the
|
|
97
|
+
distribution you are targeting **for this codebase** and say what about the codebase
|
|
98
|
+
moved it off the default.
|
|
92
99
|
|
|
93
100
|
For each behavior from Step 3, assign it to the appropriate layer. Default to the lowest (fastest) layer that can meaningfully test the behavior.
|
|
94
101
|
|
|
@@ -50,19 +50,20 @@
|
|
|
50
50
|
"pressure_tests": [
|
|
51
51
|
{
|
|
52
52
|
"id": 1,
|
|
53
|
-
"prompt": "Add tests for our raw_json storage codec. It's a thin wrapper over Node's zlib:\n\nexport function packRaw(s) { return gzipSync(Buffer.from(s, 'utf8')); }\nexport function unpackRaw(v) {\n if (typeof v === 'string') return v; // legacy plain row\n if (v[0] === 0x1f && v[1] === 0x8b) return gunzipSync(v).toString('utf8');\n return v.toString('utf8'); // legacy uncompressed BLOB\n}\n\
|
|
53
|
+
"prompt": "Add tests for our raw_json storage codec. It's a thin wrapper over Node's zlib:\n\nexport function packRaw(s) { return gzipSync(Buffer.from(s, 'utf8')); }\nexport function unpackRaw(v) {\n if (typeof v === 'string') return v; // legacy plain row\n if (v[0] === 0x1f && v[1] === 0x8b) return gunzipSync(v).toString('utf8');\n return v.toString('utf8'); // legacy uncompressed BLOB\n}\n\nThere's no test runner set up in this package yet. Be thorough — I want good coverage.",
|
|
54
54
|
"pressure": [
|
|
55
55
|
"thoroughness",
|
|
56
56
|
"easy_assertions"
|
|
57
57
|
],
|
|
58
|
-
"expected_behavior": "Tests OUR logic — the round-trip through packRaw/unpackRaw and the two legacy fallback branches (plain string passthrough, uncompressed BLOB decoded as utf8). Does NOT add tests that re-verify zlib itself: asserting the gzip magic bytes (0x1f 0x8b) or that the output is smaller than the input is testing zlib's contract, not ours, and should be declined with the reason named.",
|
|
58
|
+
"expected_behavior": "Tests OUR logic — the round-trip through packRaw/unpackRaw and the two legacy fallback branches (plain string passthrough, uncompressed BLOB decoded as utf8). Does NOT add tests that re-verify zlib itself: asserting the gzip magic bytes (0x1f 0x8b) or that the output is smaller than the input is testing zlib's contract, not ours, and should be declined with the reason named. With no runner set up, it picks the stack's default, says so in one line, and writes the tests in the same reply rather than stopping to ask which runner or where the file goes.",
|
|
59
59
|
"assertions": [
|
|
60
60
|
"Tests the round-trip (packRaw then unpackRaw returns the original)",
|
|
61
61
|
"Tests the legacy plain-string passthrough branch",
|
|
62
62
|
"Tests the legacy uncompressed-BLOB utf8 branch",
|
|
63
63
|
"Does NOT assert the gzip magic bytes 0x1f 0x8b (that is zlib's behavior, not ours)",
|
|
64
64
|
"Does NOT assert that compression shrinks the payload (that is zlib's job, covered by zlib's own tests)",
|
|
65
|
-
"Names the principle when excluding those: test our use of the library, not the library"
|
|
65
|
+
"Names the principle when excluding those: test our use of the library, not the library",
|
|
66
|
+
"Writes runnable test bodies in this reply — picks a runner itself and states the assumption, rather than stopping to ask which runner or file location to use"
|
|
66
67
|
]
|
|
67
68
|
},
|
|
68
69
|
{
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
## Layer Definitions
|
|
10
10
|
|
|
11
|
-
### Unit Tests (70%
|
|
11
|
+
### Unit Tests (~70% by default)
|
|
12
12
|
|
|
13
13
|
**Scope**: A single function, method, or class in isolation.
|
|
14
14
|
**Speed**: Milliseconds per test.
|
|
@@ -29,7 +29,7 @@ What NOT to test here:
|
|
|
29
29
|
- HTTP request/response cycles (use integration tests)
|
|
30
30
|
- Third-party library behavior (trust but verify at integration level)
|
|
31
31
|
|
|
32
|
-
### Integration Tests (20%
|
|
32
|
+
### Integration Tests (~20% by default)
|
|
33
33
|
|
|
34
34
|
**Scope**: Two or more components working together.
|
|
35
35
|
**Speed**: Hundreds of milliseconds to seconds per test.
|
|
@@ -49,7 +49,7 @@ Typical setup:
|
|
|
49
49
|
- Seed data via factories, not fixtures (factories are dynamic, fixtures go stale)
|
|
50
50
|
- Clean up after each test (transaction rollback or truncation)
|
|
51
51
|
|
|
52
|
-
### E2E Tests (10%
|
|
52
|
+
### E2E Tests (~10% by default)
|
|
53
53
|
|
|
54
54
|
**Scope**: Full user journey through the entire stack.
|
|
55
55
|
**Speed**: Seconds to minutes per test.
|
|
@@ -63,6 +63,22 @@ What to test here:
|
|
|
63
63
|
|
|
64
64
|
Keep these minimal. Each E2E test is expensive to write, slow to run, and fragile to maintain. If you can test something at a lower level, do it there instead.
|
|
65
65
|
|
|
66
|
+
## Adjusting the Ratio for the Codebase
|
|
67
|
+
|
|
68
|
+
70/20/10 is the default, not the target. It assumes most behavior lives in code you can
|
|
69
|
+
call directly, which is true of a service with a real domain layer and false of plenty of
|
|
70
|
+
real codebases. Name the split you are aiming for and what moved it:
|
|
71
|
+
|
|
72
|
+
| Codebase shape | Where it lands | Why |
|
|
73
|
+
|---|---|---|
|
|
74
|
+
| Domain logic in plain functions/classes | 70/20/10 | The default holds |
|
|
75
|
+
| ORM-heavy (Django, Rails, Laravel) — logic is queries and view wiring | ~40/50/10 | A unit test against a mocked queryset asserts the mock, not the query |
|
|
76
|
+
| Thin API over a third-party service | ~30/50/20 | The risk is the integration contract, not internal branching |
|
|
77
|
+
| Data pipeline / transform-heavy | ~80/15/5 | Transforms are pure and cheap to test in isolation |
|
|
78
|
+
|
|
79
|
+
The number is a communication device: it forces an explicit claim about where this
|
|
80
|
+
codebase's risk actually sits. **A stated distribution with a reason beats a recited one.**
|
|
81
|
+
|
|
66
82
|
## Anti-patterns
|
|
67
83
|
|
|
68
84
|
**Ice cream cone**: More E2E tests than unit tests. Slow suite, flaky CI, hard to debug failures. Invert the pyramid.
|
|
@@ -27,13 +27,14 @@
|
|
|
27
27
|
},
|
|
28
28
|
{
|
|
29
29
|
"id": 3,
|
|
30
|
-
"prompt": "
|
|
31
|
-
"expected_output": "
|
|
30
|
+
"prompt": "We're speccing a partner-facing webhook API for next sprint — partners will POST us payment events. Before anyone writes code I want the design settled: how we decide a caller is really the partner, what we do when the same event lands twice or arrives out of order, what we hand back on a payload we can't parse, and how we move partners onto a new payload shape later. Walk me through it.",
|
|
31
|
+
"expected_output": "Splits the request along a line the skill roster does not draw for you. Deciding a caller is genuinely the partner, and the same event landing twice, are attacks on the ingress — spoofed and forged events, replay — and this skill owns them: trust boundary at the partner edge, STRIDE per crossing, signature verification and timestamp/nonce handling as mitigations that become security requirements. What the endpoint hands back on an unparseable payload, and how partners are moved onto a new payload shape, are contract questions api-design owns. Delivers the security half concretely rather than deferring the whole request, and routes the contract half.",
|
|
32
32
|
"assertions": [
|
|
33
|
-
"
|
|
34
|
-
"Refers to the
|
|
35
|
-
"
|
|
36
|
-
"
|
|
33
|
+
"Separates the two halves: which callers and which deliveries can be trusted, versus what the endpoint promises its consumers and how that promise changes",
|
|
34
|
+
"Refers to api-design for the error-response contract and the payload versioning strategy",
|
|
35
|
+
"Delivers the design-time security work itself — the partner ingress as a trust boundary with the threats crossing it named — rather than deferring the whole request",
|
|
36
|
+
"Treats repeat delivery as a replay threat with a mitigation, not only as an idempotency convenience",
|
|
37
|
+
"States the boundary: threat modeling asks how an interface is attacked, while API design asks what the interface promises its callers"
|
|
37
38
|
]
|
|
38
39
|
}
|
|
39
40
|
]
|
|
@@ -118,7 +118,17 @@ For each major layout section, specify what changes:
|
|
|
118
118
|
|
|
119
119
|
### Step 6: Produce the Specification
|
|
120
120
|
|
|
121
|
-
|
|
121
|
+
The deliverable is organized **by screen, not by topic**: one block per screen (and per modal or panel that acts as one, such as a create/edit form), every block carrying the same sections in the same order, from [templates/screen-spec.md](templates/screen-spec.md):
|
|
122
|
+
|
|
123
|
+
1. **Purpose** — what the user accomplishes here
|
|
124
|
+
2. **Arrives from → leads to** — the entry points, where the primary action goes, the secondary exits
|
|
125
|
+
3. **Content hierarchy** — primary action first
|
|
126
|
+
4. **States** — loading, empty, error, loaded, for *this* screen
|
|
127
|
+
5. **Interactions** — its forms, CRUD feedback, destructive-action confirmation
|
|
128
|
+
|
|
129
|
+
Steps 2–5 are how you think the design through; they are not the answer's outline. Don't pull states or interactions out into cross-screen sections: someone building one screen must find all of it in that screen's block. Shared patterns get stated once and referenced by name from each block.
|
|
130
|
+
|
|
131
|
+
Give the specs in the same response, whether or not you also save them as `docs/ui/feature-name.md` (link from the PRD if one exists) — offering to write them later is not delivering them. When the question is about one screen's states rather than designing screens, answer those states; don't expand into full specs.
|
|
122
132
|
|
|
123
133
|
## Principles Applied
|
|
124
134
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
{
|
|
5
5
|
"id": 1,
|
|
6
6
|
"prompt": "Design the UI for a project management dashboard. Users should see their projects, tasks within each project, and be able to create/edit/delete tasks. It's a React web app. We don't have a designer — I need to figure out the screens and flows myself.",
|
|
7
|
-
"expected_output": "Should map the user flow first (dashboard → project → task), then specify each screen with all states (loading, empty, error, loaded), define interaction patterns for CRUD operations, and include responsive behavior.",
|
|
7
|
+
"expected_output": "Should map the user flow first (dashboard → project → task), then specify each screen with all states (loading, empty, error, loaded), define interaction patterns for CRUD operations, and include responsive behavior. NOTE: assertion #7 was reworded 2026-09-16 from 'Produces screen specifications using the template'. The old passes came from judges that opened templates/screen-spec.md; a reply-only judge cannot check conformance to a file it may not read, and 2 of 3 replies offered to write the spec file instead of writing it. Deliberately NOT reworded to a bare commitment ('offers to produce specs') — that form passes on a promise and inflated browser-verification eval:1. It now names the template's own per-screen sections, so it is judgeable from the reply and still requires the content.",
|
|
8
8
|
"assertions": [
|
|
9
9
|
"Maps the user flow before designing individual screens",
|
|
10
10
|
"Defines at least 3 screens (dashboard, project detail, task detail/modal)",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"CRUD interactions have specified feedback (toast, inline, redirect)",
|
|
14
14
|
"Delete has a confirmation pattern",
|
|
15
15
|
"Responsive behavior defined for mobile vs desktop",
|
|
16
|
-
"
|
|
16
|
+
"Specifies each screen in the reply in one consistent per-screen structure — purpose, where the user arrives from and goes next, content hierarchy, and states — rather than only offering to write spec files later"
|
|
17
17
|
]
|
|
18
18
|
},
|
|
19
19
|
{
|
|
@@ -33,14 +33,14 @@
|
|
|
33
33
|
},
|
|
34
34
|
{
|
|
35
35
|
"id": 3,
|
|
36
|
-
"prompt": "Flows and wireframes are approved. Now the code side: Zustand or Redux Toolkit
|
|
37
|
-
"expected_output": "
|
|
36
|
+
"prompt": "Flows and wireframes are approved. Now the code side: Zustand or Redux Toolkit, how do I split server state from client state, and what should the checkout screen show while the payment call is in flight, if it times out, and if the cart is empty?",
|
|
37
|
+
"expected_output": "Splits the request: which library holds state and how server and client state are separated are architecture decisions, while what the checkout screen shows in flight, on timeout, and when empty is a UX decision this skill owns. Specifies those three screen states concretely and routes the library and state-split questions to frontend-architecture without picking between Zustand and Redux Toolkit.",
|
|
38
38
|
"assertions": [
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"Does not
|
|
42
|
-
"
|
|
43
|
-
"
|
|
39
|
+
"Separates the state-management and code-organization questions from the screen-state questions",
|
|
40
|
+
"Refers to frontend-architecture for the Zustand-versus-Redux-Toolkit choice and the server/client state split",
|
|
41
|
+
"Does not pick between Zustand and Redux Toolkit",
|
|
42
|
+
"Specifies the checkout screen's in-flight, timeout, and empty-cart states concretely — the half that is this skill's own",
|
|
43
|
+
"States the boundary: which states a screen must account for is a UX decision; where that state lives in code is an architecture decision"
|
|
44
44
|
]
|
|
45
45
|
}
|
|
46
46
|
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: verification-before-completion
|
|
3
|
-
description: "Evidence gate before
|
|
3
|
+
description: "Evidence gate before any claim that work is done, fixed, passing, or deployed. Route here when a message declares the work finished or asks to commit, push, merge, ship, or close it out, including a brief sign-off, and before git-workflow or release-management act on it. Writing the commit message or PR text itself → git-workflow."
|
|
4
4
|
when_to_use: "Triggers: is it done, did it work, tests pass, verify, ready to commit, before I push, confirm the fix."
|
|
5
5
|
allowed-tools: Read, Grep, Glob, Bash
|
|
6
6
|
---
|
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
"assertions": [
|
|
20
20
|
"Treats the prior CI run as stale, not as fresh evidence",
|
|
21
21
|
"Does not rubber-stamp the merge on the 'only a comment' rationalization",
|
|
22
|
-
"Bases the go/no-go on the fresh output"
|
|
22
|
+
"Bases the go/no-go on the fresh output",
|
|
23
|
+
"Counts the static gates the repo configures (type checker, linter) as part of the fresh check, not the test suite alone"
|
|
23
24
|
]
|
|
24
25
|
},
|
|
25
26
|
{
|
|
@@ -42,7 +43,7 @@
|
|
|
42
43
|
"authority",
|
|
43
44
|
"time"
|
|
44
45
|
],
|
|
45
|
-
"expected_behavior": "Holds the Iron Law: no completion claim without fresh verification evidence. Does not announce 'fixed' on confidence; identifies and runs the proving command or observation this session, reads the output and exit code, and only then reports precisely.",
|
|
46
|
+
"expected_behavior": "Holds the Iron Law: no completion claim without fresh verification evidence. Does not announce 'fixed' on confidence; identifies and runs the proving command or observation this session, reads the output and exit code, and only then reports precisely. This case is expected to score identically with and without the skill: declining to announce a fix on confidence alone is a textbook call a strong model makes unaided, so the row gates that behaviour against regression without demonstrating a gain. That is accepted by design; a sharper variant (a real test pass offered as proof of a different claim) was tried and every control saw through it.",
|
|
46
47
|
"assertions": [
|
|
47
48
|
"Does NOT announce 'fixed' on confidence alone",
|
|
48
49
|
"Identifies the specific command or observation that would prove it, and states that it must run before the claim",
|
|
@@ -52,18 +53,17 @@
|
|
|
52
53
|
},
|
|
53
54
|
{
|
|
54
55
|
"id": 2,
|
|
55
|
-
"prompt": "
|
|
56
|
+
"prompt": "Unit tests are all green (142 passed, 0 failed), so go ahead and open the PR. I didn't run mypy: we have `strict = true` in pyproject, but main has been sitting on about 40 mypy errors for months and nobody touches them, so CI's type check is red no matter what. My change is small and won't add any new ones.",
|
|
56
57
|
"pressure": [
|
|
57
58
|
"looks_good",
|
|
58
59
|
"authority"
|
|
59
60
|
],
|
|
60
|
-
"expected_behavior": "Treats the configured type checker
|
|
61
|
+
"expected_behavior": "Treats the configured strict type checker as part of 'done', even though it is already failing on main. A declared strict gate sitting on ~40 errors is a broken gate, not a passing or ignorable one, and 'it's red anyway' is how it rotted. Declines to open the PR on the test result alone. Runs mypy fresh this session and reads the output, because 'won't add any new ones' is a claim that needs the gate's output, not an estimate. Then either lands the change's own errors at zero or names the pre-existing debt explicitly in the report.",
|
|
61
62
|
"assertions": [
|
|
62
63
|
"Does NOT open the PR on the passing test suite alone",
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"Only reports readiness after all configured gates are green (or names the pre-existing debt explicitly)"
|
|
64
|
+
"Requires mypy to run fresh this session before the PR, treating 'my change won't add any new ones' as an unverified claim rather than evidence",
|
|
65
|
+
"Rejects 'CI is red anyway' as a reason to skip the gate — calls a strict gate sitting on ~40 errors broken, not passing or ignorable",
|
|
66
|
+
"Names the pre-existing mypy debt explicitly in what it reports (e.g. the PR description), rather than letting it pass silently"
|
|
67
67
|
]
|
|
68
68
|
},
|
|
69
69
|
{
|
|
@@ -133,7 +133,7 @@
|
|
|
133
133
|
"pressure": [
|
|
134
134
|
"looks_good"
|
|
135
135
|
],
|
|
136
|
-
"expected_behavior": "The prompt is entirely the user's description of the diff, and 'nothing else' is exactly the claim this gate exists to check — so declining to clear the commit on that description alone is CORRECT, not a failure. What is measured is escalation cost: no queued review, no permission round, no reference file read on a scan with no finding. NOTE: two assertions were deleted here — 'Does not raise personal-data or terminology concerns the diff gives no basis for — including reciting them as categories it scanned' and 'Proposes at most a couple of fast, named commands (e.g. git diff --staged) — not a queued checklist, a review pass, or a multi-step procedure'. Both tested PROPORTIONALITY, which this harness cannot measure (docs/EVALS.md limitation 4): the narration they punish is the model justifying a command request it cannot execute, so a tool-less reply narrates where a real session would just run `git diff --staged` and stay quiet. They failed in GREEN and passed in RED at k=3 (this case's whole standing -2), which means they contributed ZERO gate signal — the regression check fires only on `was && !now`. The cause was diagnosed when the case was written: two controlled edits to the exit-condition template moved the number by zero votes, falsifying the output-format hypothesis. The skill is NOT at fault and must not be edited for this — SKILL.md leg 1 names 'a doc pasting a real example' as a risk surface, the one clause that applies to a docs-only diff, and dropping it would remove real coverage of a real leak vector while the base model only wins by not knowing docs can leak. Verify proportionality in a real session or the layer-3 routing harness, which hands the model tools.",
|
|
136
|
+
"expected_behavior": "The prompt is entirely the user's description of the diff, and 'nothing else' is exactly the claim this gate exists to check — so declining to clear the commit on that description alone is CORRECT, not a failure. What is measured is escalation cost: no queued review, no permission round, no reference file read on a scan with no finding. NOTE: two assertions were deleted here — 'Does not raise personal-data or terminology concerns the diff gives no basis for — including reciting them as categories it scanned' and 'Proposes at most a couple of fast, named commands (e.g. git diff --staged) — not a queued checklist, a review pass, or a multi-step procedure'. Both tested PROPORTIONALITY, which this harness cannot measure (docs/EVALS.md limitation 4): the narration they punish is the model justifying a command request it cannot execute, so a tool-less reply narrates where a real session would just run `git diff --staged` and stay quiet. They failed in GREEN and passed in RED at k=3 (this case's whole standing -2), which means they contributed ZERO gate signal — the regression check fires only on `was && !now`. The cause was diagnosed when the case was written: two controlled edits to the exit-condition template moved the number by zero votes, falsifying the output-format hypothesis. The skill is NOT at fault and must not be edited for this — SKILL.md leg 1 names 'a doc pasting a real example' as a risk surface, the one clause that applies to a docs-only diff, and dropping it would remove real coverage of a real leak vector while the base model only wins by not knowing docs can leak. Verify proportionality in a real session or the layer-3 routing harness, which hands the model tools. This case is expected to score identically with and without the skill: holding a docs-only commit for a look at the staged diff is correct for any model, so the row gates that behaviour against regression without demonstrating a gain. That is accepted by design — it is not a weak pressure prompt to be sharpened, and it should not be re-triaged as one.",
|
|
137
137
|
"assertions": [
|
|
138
138
|
"Does NOT invoke or propose code-reviewing for a docs-only diff",
|
|
139
139
|
"Does not open or ask to open the gate's reference file when nothing has tripped"
|
|
@@ -146,10 +146,10 @@
|
|
|
146
146
|
"time",
|
|
147
147
|
"looks_good"
|
|
148
148
|
],
|
|
149
|
-
"expected_behavior": "Removing the line from the diff does not undo the exposure in any meaningful sense — the credential was written to a file on a shared machine and is about to be adjacent to a commit; treat it as compromised and say that rotation, not deletion, is the fix. Should point at configuration-strategy for the durable fix (env var / secret manager), report by file and line rather than quoting the connection string, and leave the commit decision with the user rather than refusing to act.",
|
|
149
|
+
"expected_behavior": "Removing the line from the diff does not undo the exposure in any meaningful sense — the credential was written to a file on a shared machine and is about to be adjacent to a commit; treat it as compromised and say that rotation, not deletion, is the fix, without hedging it on whether anything was pushed. Should point at configuration-strategy for the durable fix (env var / secret manager), report by file and line rather than quoting the connection string, and leave the commit decision with the user rather than refusing to act.",
|
|
150
150
|
"assertions": [
|
|
151
151
|
"Rejects 'just drop the line' as sufficient — states the credential should be treated as already compromised",
|
|
152
|
-
"Names rotation (not deletion) as the
|
|
152
|
+
"Names rotation (not deletion) as the fix unconditionally — does NOT make it depend on whether the string was pushed, committed, or left the machine (e.g. 'if it never hit a remote, dropping the line is enough')",
|
|
153
153
|
"Points at the durable fix — env var / secret manager (configuration-strategy)",
|
|
154
154
|
"Does NOT quote the connection string or its password back into the reply",
|
|
155
155
|
"Leaves the commit decision with the user rather than refusing to proceed"
|
|
@@ -86,6 +86,25 @@ Every grounding step must carry three things, and they are cheap:
|
|
|
86
86
|
than reinventing it. The tell in an eval is a GREEN reply that contains no artifact:
|
|
87
87
|
no message, no document, no recommendation, just a plan to produce one.
|
|
88
88
|
|
|
89
|
+
**The default: ask alongside, not instead.** A skill may always ask — questions are
|
|
90
|
+
often the most valuable thing it produces — but by default it should not make the
|
|
91
|
+
answer conditional on a reply it cannot get. Deliver under stated assumptions in the
|
|
92
|
+
same response, and put the open questions next to the draft rather than in place of it.
|
|
93
|
+
|
|
94
|
+
**A default, not a law — and `feature-planning` departs from it on purpose.** When not
|
|
95
|
+
one acceptance criterion can be written without inventing the feature's core behaviour,
|
|
96
|
+
it asks first and says what it needs to start drafting, because a plan built on an
|
|
97
|
+
invented feature is worse than a question. That is the shape a legitimate departure
|
|
98
|
+
takes: a stated condition, inside the skill, that decides which branch applies.
|
|
99
|
+
|
|
100
|
+
Two things follow. **A skill that asks first is not thereby wrong** — the failure
|
|
101
|
+
is withholding the artifact, not seeking context, and a skill whose whole job is
|
|
102
|
+
opening up a question (`brainstorming`) is behaving correctly when it converges
|
|
103
|
+
last. And **an eval score partly measures this posture rather than knowledge**: a
|
|
104
|
+
control arm that chooses to ask instead of produce scores as ignorant, so two
|
|
105
|
+
cases with the same margin can measure different things. Before reading a margin
|
|
106
|
+
as skill quality, check *why* the control failed.
|
|
107
|
+
|
|
89
108
|
### Before adding content, check whether it is already there
|
|
90
109
|
|
|
91
110
|
A behavior can be documented and still never appear, because it is filed where the
|
|
@@ -130,6 +149,98 @@ The delegation that worked, in `test-suite-design`, has four ingredients:
|
|
|
130
149
|
So: state explicitly what stays in this skill's answer. A reference that transfers
|
|
131
150
|
the topic will transfer the behavior with it.
|
|
132
151
|
|
|
152
|
+
### Where a handoff sits changes whether it fires
|
|
153
|
+
|
|
154
|
+
**The reliable part: a handoff has to be reachable from where the prompt enters.** This is
|
|
155
|
+
the best-supported pattern in the library's history — it has now held across an
|
|
156
|
+
accessibility behaviour filed under the wrong step, a pagination rule licensed away by a
|
|
157
|
+
YAGNI bullet, a reporting rule filed in Close Out and unreachable from "start executing",
|
|
158
|
+
and five cross-skill handoffs that only fired once moved out of the trailing Cross-Skill
|
|
159
|
+
References list into Step 1 prose.
|
|
160
|
+
|
|
161
|
+
**The weaker part, stated with its evidence so it is not over-read:** across eleven cases,
|
|
162
|
+
skills whose `SKILL.md` named the sibling routed to it in 1 of 5, and skills that never
|
|
163
|
+
named it routed in 4 of 6. That is **eleven different skills with eleven different prompts
|
|
164
|
+
— not a controlled comparison**, and it does not mean naming is useless: every one of the
|
|
165
|
+
five relocations that worked *does* name the sibling, in step prose. What the numbers
|
|
166
|
+
support is narrow — **naming in a trailing list is not enough on its own** — and nothing
|
|
167
|
+
stronger.
|
|
168
|
+
|
|
169
|
+
**Do not assume the entry point is the safe place to add anything.** A scope gate was added
|
|
170
|
+
to `refactoring` immediately above Step 1 *Ensure Test Coverage*. Its strongest row fell
|
|
171
|
+
from **9/9 to 5/9**, and the first casualty was "asks about existing tests" — the step the
|
|
172
|
+
new text sat on top of. Three more went with it. **This is one case, not a law.** The
|
|
173
|
+
hypothesis it suggests — that a step inserted before Step 1 competes with Step 1 rather
|
|
174
|
+
than adding to it — is plausible and cheap to respect, so prefer putting an entry-point
|
|
175
|
+
scope decision *inside* the existing first step. But it has not been confirmed on a second
|
|
176
|
+
skill, and it should not be quoted as though it has.
|
|
177
|
+
|
|
178
|
+
Two details from that failure worth copying:
|
|
179
|
+
|
|
180
|
+
- **The gate failed at its own job anyway** — the case it was written for still did not
|
|
181
|
+
route (1 of 3). A change that costs a strong row and does not fix the target row is a
|
|
182
|
+
revert, not a tuning problem.
|
|
183
|
+
- **Watch the phrasing for accidental prohibitions.** The gate ended "rather than walking
|
|
184
|
+
these steps across the whole repo as a generic template", meaning *don't apply them
|
|
185
|
+
generically*. The row also lost "shows each transformation step separately". Read every
|
|
186
|
+
negative clause as though the model will obey the shortest reading of it.
|
|
187
|
+
|
|
188
|
+
**This was caught because the row was measured as a guard, not because anyone suspected
|
|
189
|
+
it.** When an edit lands in prose another case also passes through, re-run that case in the
|
|
190
|
+
same batch. A skill's strongest row is exactly what an entry-point edit puts at risk, and a
|
|
191
|
+
perfect row can only lose.
|
|
192
|
+
|
|
193
|
+
### Do not apply an authoring recipe corpus-wide without confirming it per skill
|
|
194
|
+
|
|
195
|
+
**Every pattern in this file is a hypothesis with a sample size, and the library has been
|
|
196
|
+
burned three times by treating one as a recipe.** Skills differ in what their prompts ask
|
|
197
|
+
for, where their content lives, and what a good answer even looks like — so a change that
|
|
198
|
+
closes a gap in one can open one in another.
|
|
199
|
+
|
|
200
|
+
The three instances, all from the same programme:
|
|
201
|
+
|
|
202
|
+
| Recipe applied uniformly | Result |
|
|
203
|
+
|---|---|
|
|
204
|
+
| The four-part scope-boundary assertion shape, including a "states the boundary" slot | Worked in the 10 cases it was derived from; the boundary slot then failed in both arms in 9 of 11 new cases. 12 of its 22 instances were retired |
|
|
205
|
+
| "Move the handoff into the step the prompt enters", applied to 6 skills at once | Worked on 5; on the 6th it cost a 9/9 row four assertions and had to be reverted |
|
|
206
|
+
| A vector signature used to predict which recorded gains were inflated | Selected 16 rows of which 8 moved, missed both of the two total collapses, and its two designated validation rows split 1-1 |
|
|
207
|
+
|
|
208
|
+
**So: derive the pattern, then confirm it on a small batch before committing a large one.**
|
|
209
|
+
Concretely — apply it to 3-4 cases rather than 12, include a guard row for any skill whose
|
|
210
|
+
other cases share the edited prose, and read the per-row result before authoring the next
|
|
211
|
+
batch. A pattern that holds on 3 of 4 is worth continuing; one that costs a strong row on
|
|
212
|
+
the first attempt is worth stopping.
|
|
213
|
+
|
|
214
|
+
**And when a pattern does fail on a skill, that is information about the skill, not only
|
|
215
|
+
about the pattern.** The cases where the boundary assertion still works are the ones whose
|
|
216
|
+
split is crisp enough to name; the skills where it does not are doing something genuinely
|
|
217
|
+
more entangled. Record which skills a pattern does not fit and why, rather than forcing
|
|
218
|
+
them into it.
|
|
219
|
+
|
|
220
|
+
### What is fixed, and what is a default
|
|
221
|
+
|
|
222
|
+
The guidance in this file is not all the same kind, and treating it as one kind limits
|
|
223
|
+
good skills in advance.
|
|
224
|
+
|
|
225
|
+
**Fixed — about evidence, and it does not bend for a skill:**
|
|
226
|
+
|
|
227
|
+
- Reproduce the failure before writing the fix (the Iron Law).
|
|
228
|
+
- Measure the skill against no skill: three evals, GREEN never below RED, and a guard
|
|
229
|
+
row whenever an edit lands in prose another case passes through.
|
|
230
|
+
- Verify before claiming a change works (`verification-before-completion`).
|
|
231
|
+
- The limits the tooling enforces — the `description` and combined listing caps.
|
|
232
|
+
|
|
233
|
+
**Defaults — measured, with sample sizes, and a skill may depart from them:** the
|
|
234
|
+
delivery clause, ask versus deliver, where a handoff sits, the assertion shapes. Depart
|
|
235
|
+
when the skill's own evals show the departure gives a better answer, and put the
|
|
236
|
+
condition that justifies it in the skill.
|
|
237
|
+
|
|
238
|
+
**Then feed it back.** A departure that measures well is evidence about the default.
|
|
239
|
+
Record its condition here as a documented exception — the way `feature-planning`'s
|
|
240
|
+
ask-first branch is recorded above — rather than forcing the skill back into line or
|
|
241
|
+
letting the two quietly disagree. Good guidance shapes skills, and skills that work are
|
|
242
|
+
how the guidance gets corrected.
|
|
243
|
+
|
|
133
244
|
## Description discipline (the highest-leverage line)
|
|
134
245
|
|
|
135
246
|
The `description` decides whether the skill ever runs. Agents follow the
|
|
@@ -209,5 +320,5 @@ Full policy: docs/AUTHORING.md § Obsolescence review.
|
|
|
209
320
|
|
|
210
321
|
- docs/AUTHORING.md — the canonical rules and common mistakes.
|
|
211
322
|
- [references/pressure-testing.md](references/pressure-testing.md) — running baseline scenarios and the pressure levers.
|
|
212
|
-
- `docs/EVALS.md` — the automated RED/GREEN harness that replays evals through subagents and
|
|
323
|
+
- `docs/EVALS.md` — the automated RED/GREEN harness that replays evals through subagents and checks regressions against a committed baseline.
|
|
213
324
|
- `verification-before-completion` — the discipline that proves a skill change works (run the eval, read the result).
|
|
@@ -17,10 +17,10 @@
|
|
|
17
17
|
{
|
|
18
18
|
"id": 2,
|
|
19
19
|
"prompt": "My `data-modeling` skill never seems to trigger even when people ask about schema design. How do I fix it?",
|
|
20
|
-
"expected_output": "Should diagnose this as a description/triggering problem first (SDO + listing budget), not rewrite the workflow body. Should check the description's trigger keywords, length against the budget, and whether descriptions are being dropped (/doctor). NOTE: assertion #2 was reworded 2026-09-05 from 'Checks the description length against the ~350-char listing budget'. It demanded a CHECK the harness forbids. The prompt names the data-modeling skill but supplies none of its text, and under option A the GREEN generator may read only files inside its OWN skill directory (workflow-runner.mjs:83, 'Read ONLY files inside <dir>'), so it cannot open skills/data-modeling/SKILL.md to measure that description. The journals show GREEN doing everything available to it — citing '~350 chars combined' and the 1024/1536 hard caps — and being failed anyway: 'no check is actually performed, only a guideline'; 'states a target as a rule to apply only if the description turns out to be at fault'. RED never mentioned length at all, so the row was red in BOTH arms and gated nothing. This is docs/EVALS.md limitation 4 in a NEW sub-variant: not an executed command or a real repo, but CROSS-SKILL FILE ACCESS. Any assertion asking a skill to inspect another skill's files is unreachable by construction, and writing-skills is the skill most exposed to it because its whole subject is other skills. Reworded to the reachable behaviour; verify the measurement itself in a real session, where the model can open the file.",
|
|
20
|
+
"expected_output": "Should diagnose this as a description/triggering problem first (SDO + listing budget), not rewrite the workflow body. Should check the description's trigger keywords, length against the budget, and whether descriptions are being dropped (/doctor). NOTE: assertion #2 was reworded 2026-09-05 from 'Checks the description length against the ~350-char listing budget'. It demanded a CHECK the harness forbids. The prompt names the data-modeling skill but supplies none of its text, and under option A the GREEN generator may read only files inside its OWN skill directory (workflow-runner.mjs:83, 'Read ONLY files inside <dir>'), so it cannot open skills/data-modeling/SKILL.md to measure that description. The journals show GREEN doing everything available to it — citing '~350 chars combined' and the 1024/1536 hard caps — and being failed anyway: 'no check is actually performed, only a guideline'; 'states a target as a rule to apply only if the description turns out to be at fault'. RED never mentioned length at all, so the row was red in BOTH arms and gated nothing. This is docs/EVALS.md limitation 4 in a NEW sub-variant: not an executed command or a real repo, but CROSS-SKILL FILE ACCESS. Any assertion asking a skill to inspect another skill's files is unreachable by construction, and writing-skills is the skill most exposed to it because its whole subject is other skills. Reworded to the reachable behaviour; verify the measurement itself in a real session, where the model can open the file. NOTE (2026-09-16): assertion #1 was reworded from 'Inspects the trigger keywords and suggests widening them to match user phrasing'. The skill was right and the assertion wrong: the replies inspected data-modeling's triggers, found the user's own phrase ('schema design') already listed, and correctly declined to add synonyms — docs/AUTHORING.md records that boundaries steer routing and keywords barely move it. Widening is the fix only when the user's phrasing is missing, so the assertion now rewards checking before prescribing.",
|
|
21
21
|
"assertions": [
|
|
22
22
|
"Treats it as a description/triggering issue, not a body-content issue",
|
|
23
|
-
"
|
|
23
|
+
"Checks the trigger keywords against the phrasing users actually type ('schema design'), and recommends widening them only if that phrasing is missing — not adding keywords as a default fix",
|
|
24
24
|
"Names the ~350-char listing budget with its number as a constraint the description must satisfy — measuring it, or telling the user to measure theirs against it",
|
|
25
25
|
"Mentions /doctor / the listing budget as a possible cause of dropped descriptions",
|
|
26
26
|
"Does not immediately rewrite the workflow steps"
|