swe-workflow-skills 0.8.0 → 0.8.2
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 +4 -3
- package/VERSION +1 -1
- package/package.json +1 -1
- package/skills/accessibility-design/SKILL.md +1 -0
- package/skills/accessibility-design/evals/evals.json +4 -4
- package/skills/accessibility-design/references/accessibility-patterns.md +34 -0
- package/skills/api-design/SKILL.md +24 -7
- package/skills/architecture-design/evals/evals.json +2 -2
- package/skills/browser-verification/evals/evals.json +7 -7
- package/skills/cicd-pipeline/SKILL.md +2 -0
- package/skills/cicd-pipeline/evals/evals.json +3 -2
- package/skills/dependency-impact-analysis/SKILL.md +22 -1
- package/skills/deployment-checklist/SKILL.md +6 -0
- package/skills/deployment-checklist/evals/evals.json +3 -3
- package/skills/deployment-repo/SKILL.md +1 -0
- package/skills/deployment-repo/evals/evals.json +2 -2
- package/skills/feature-planning/SKILL.md +26 -3
- package/skills/feature-planning/evals/evals.json +4 -5
- package/skills/gitops-delivery/SKILL.md +9 -1
- package/skills/ml-model-deployment/SKILL.md +8 -1
- package/skills/performance-optimization/evals/evals.json +2 -2
- package/skills/plan-execution/SKILL.md +6 -0
- package/skills/plan-execution/evals/evals.json +2 -2
- package/skills/project-documentation/SKILL.md +8 -0
- package/skills/project-documentation/evals/evals.json +2 -2
- package/skills/retrospective/evals/evals.json +4 -4
- package/skills/rollback-strategy/evals/evals.json +1 -2
- package/skills/skill-router/SKILL.md +7 -0
- package/skills/skill-router/evals/evals.json +3 -4
- package/skills/strategic-review/SKILL.md +12 -3
- package/skills/strategic-review/evals/evals.json +8 -7
- package/skills/tdd-workflow/SKILL.md +15 -2
- package/skills/test-data-strategy/SKILL.md +14 -0
- package/skills/test-data-strategy/references/data-generation-patterns.md +15 -0
- package/skills/test-suite-design/SKILL.md +27 -1
- package/skills/test-suite-design/evals/evals.json +6 -3
- package/skills/verification-before-completion/evals/evals.json +4 -7
- package/skills/writing-skills/SKILL.md +59 -5
- package/skills/writing-skills/evals/evals.json +2 -2
package/README.md
CHANGED
|
@@ -38,9 +38,10 @@ don't cover:
|
|
|
38
38
|
([how it works](docs/ROLES.md)).
|
|
39
39
|
- **Tested like code, not prose.** Every skill ships 3 evals; two LLM-as-judge
|
|
40
40
|
harnesses (content quality and routing accuracy) replay them with skill loaded vs
|
|
41
|
-
absent and gate regressions in CI. Across all 66 skills — 234 cases,
|
|
42
|
-
the same model passes **
|
|
43
|
-
loaded, and **no skill scores below the
|
|
41
|
+
absent and gate regressions in CI. Across all 66 skills — 234 cases, 1311 assertions,
|
|
42
|
+
every row measured at k>=3 — the same model passes **65.2%** of assertions without the
|
|
43
|
+
skill's content and **97.9%** with the skill loaded, and **no skill scores below the
|
|
44
|
+
no-content baseline on any case**
|
|
44
45
|
([results](docs/EVALS.md#results-content-evals-full-catalog)). Safety-critical skills
|
|
45
46
|
(deploys, releases, tests, incidents, security) are **hardened**: an Iron Law, a
|
|
46
47
|
rationalization table distilled from real baseline failures, and pressure tests that
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.8.
|
|
1
|
+
0.8.2
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "swe-workflow-skills",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.2",
|
|
4
4
|
"description": "A curated library of Claude Code Agent Skills covering the full software lifecycle, with orchestrator-routed activation that scales past the skill-listing budget.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -118,6 +118,7 @@ Automated testing catches ~30% of accessibility issues. Manual testing catches t
|
|
|
118
118
|
- [ ] Test at 200% zoom — no horizontal scroll, no overlapping text
|
|
119
119
|
- [ ] Verify all form fields have associated labels
|
|
120
120
|
- [ ] Verify error messages are announced to screen readers
|
|
121
|
+
- [ ] Submit an invalid form: focus must move to the first error (or an error summary), not stay on the submit button
|
|
121
122
|
|
|
122
123
|
## Principles Applied
|
|
123
124
|
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
{
|
|
5
5
|
"id": 1,
|
|
6
6
|
"prompt": "I'm building a modal dialog component in React for confirming destructive actions (like deleting a project). Make it accessible.",
|
|
7
|
-
"expected_output": "Should implement the full accessible modal pattern: role=dialog, aria-modal, focus trap, Escape to close, focus restoration, background inert, and proper labeling.",
|
|
7
|
+
"expected_output": "Should implement the full accessible modal pattern: role=dialog, aria-modal, focus trap, Escape to close, focus restoration, background inert, and proper labeling. Assertion #0 was reworded 2026-08-28: it named only the ARIA attributes, and at k=5 all 10 generations across both arms built the modal on native <dialog> + showModal(), which supplies modality implicitly (one deliberately chose role='alertdialog' and defended it). The judge's own words were 'modality is left implicit via native showModal()'. The assertion had aged out of correct practice; it now accepts either route to the same semantics.",
|
|
8
8
|
"assertions": [
|
|
9
|
-
"
|
|
9
|
+
"Establishes dialog semantics and modality — native <dialog> with showModal(), or role='dialog'/'alertdialog' with aria-modal='true'",
|
|
10
10
|
"Labels the dialog with aria-labelledby pointing to the title",
|
|
11
11
|
"Implements focus trap (Tab cycles within modal)",
|
|
12
12
|
"Moves focus to the first focusable element on open",
|
|
@@ -20,11 +20,11 @@
|
|
|
20
20
|
{
|
|
21
21
|
"id": 2,
|
|
22
22
|
"prompt": "Audit this React component for accessibility issues:\n\n<div className=\"card\" onClick={() => navigate(`/project/${id}`)}>\n <div className=\"title\">{name}</div>\n <img src={thumbnail} />\n <div className=\"badge\" style={{color: status === 'active' ? 'green' : 'red'}}>\n {status}\n </div>\n <div className=\"actions\">\n <div className=\"btn\" onClick={(e) => { e.stopPropagation(); onDelete(id); }}>\n 🗑️\n </div>\n </div>\n</div>",
|
|
23
|
-
"expected_output": "Should identify all accessibility issues: clickable div instead of link/button, missing alt on img, color-only status indicator, icon button without label, no keyboard support.",
|
|
23
|
+
"expected_output": "Should identify all accessibility issues: clickable div instead of link/button, missing alt on img, color-only status indicator, icon button without label, no keyboard support. Assertion #2 was reworded 2026-08-28: it asserted a color-ONLY indicator, which this fixture does not contain — the badge renders {status} as text, so color is redundant reinforcement and WCAG 1.4.1 is not violated. At k=5, 7 of 10 judges recorded the reply correctly ruling 1.4.1 out and flagging 1.4.3 contrast instead; the assertion was punishing the right answer. It now targets the failure the fixture really has.",
|
|
24
24
|
"assertions": [
|
|
25
25
|
"Identifies clickable div should be an <a> or <Link> (for navigation)",
|
|
26
26
|
"Identifies missing alt attribute on the image",
|
|
27
|
-
"Identifies
|
|
27
|
+
"Identifies the hard-coded inline red/green status color as a problem — contrast, loss under forced-colors/high-contrast modes, or red/green being the worst pair for color-blind users",
|
|
28
28
|
"Identifies delete button as a div — should be <button>",
|
|
29
29
|
"Identifies emoji icon without accessible label (aria-label needed)",
|
|
30
30
|
"Notes that div+onClick has no keyboard support (no Enter/Space handling)",
|
|
@@ -130,6 +130,40 @@ Key: `aria-invalid` tells screen readers the field has an error. `aria-described
|
|
|
130
130
|
|
|
131
131
|
The `*` is visual-only (`aria-hidden`). `aria-required` is the programmatic indicator.
|
|
132
132
|
|
|
133
|
+
### Errors on submit
|
|
134
|
+
Validation that fails on submit must move focus. Leaving focus on the submit button strands
|
|
135
|
+
keyboard and screen reader users — the errors are below or above them and they are never told.
|
|
136
|
+
|
|
137
|
+
**Short forms — focus the first invalid field:**
|
|
138
|
+
```jsx
|
|
139
|
+
const onSubmit = (e) => {
|
|
140
|
+
e.preventDefault()
|
|
141
|
+
const errors = validate(values)
|
|
142
|
+
if (Object.keys(errors).length) {
|
|
143
|
+
setErrors(errors)
|
|
144
|
+
refs[Object.keys(errors)[0]].current?.focus() // first field IN DOM ORDER
|
|
145
|
+
return
|
|
146
|
+
}
|
|
147
|
+
save(values)
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
**Long forms — focus an error summary:**
|
|
152
|
+
```jsx
|
|
153
|
+
<div ref={summaryRef} tabIndex={-1} role="alert">
|
|
154
|
+
<h2>3 errors need fixing</h2>
|
|
155
|
+
<ul>
|
|
156
|
+
<li><a href="#email">Email address is not valid</a></li>
|
|
157
|
+
</ul>
|
|
158
|
+
</div>
|
|
159
|
+
```
|
|
160
|
+
Move focus to the summary container on failed submit; each item links to its field's `id`, so
|
|
161
|
+
the user can jump straight to it.
|
|
162
|
+
|
|
163
|
+
Key: a failed submit must land focus somewhere the user can act on — the first invalid field
|
|
164
|
+
or an error summary — never on the submit button. Order errors by DOM position, not by the
|
|
165
|
+
order your validator happened to produce them.
|
|
166
|
+
|
|
133
167
|
### Form submission feedback
|
|
134
168
|
```html
|
|
135
169
|
<!-- Status region for form-level messages -->
|
|
@@ -12,6 +12,22 @@ Design APIs that are consistent, predictable, and easy to consume. A well-design
|
|
|
12
12
|
|
|
13
13
|
This skill designs the **contract** (endpoints, request/response shapes, error formats, pagination). For higher-level decisions (REST vs GraphQL, API gateway, authentication strategy), use the `architecture-design` skill first, then return here to design the specifics.
|
|
14
14
|
|
|
15
|
+
## The Deliverable
|
|
16
|
+
|
|
17
|
+
An API design is not finished until it carries **all six** of these. A list of endpoints is a
|
|
18
|
+
third of an answer:
|
|
19
|
+
|
|
20
|
+
1. **Resources and endpoints** — URLs, methods, and how relationships are expressed
|
|
21
|
+
2. **Request/response schemas** — field names, types, and the response envelope
|
|
22
|
+
3. **The error format** — one shape for every error, plus the status-code mapping
|
|
23
|
+
4. **The pagination contract** — parameters and response shape for every list endpoint
|
|
24
|
+
5. **Auth per endpoint** — scheme, who may call it, and which endpoints are public
|
|
25
|
+
6. **The written spec** — markdown or OpenAPI, using [templates/api-spec.md](templates/api-spec.md)
|
|
26
|
+
|
|
27
|
+
Deliver all six **in the same response**. Where a choice is genuinely open, pick the default
|
|
28
|
+
this skill recommends, say you picked it, and keep going — never return a design as a list of
|
|
29
|
+
questions.
|
|
30
|
+
|
|
15
31
|
## Workflow
|
|
16
32
|
|
|
17
33
|
### Step 1: Identify Resources and Operations
|
|
@@ -45,7 +61,7 @@ POST /api/v1/orders/:id/cancel → Cancel an order
|
|
|
45
61
|
POST /api/v1/users/:id/verify → Verify a user's email
|
|
46
62
|
```
|
|
47
63
|
|
|
48
|
-
Present the endpoint list
|
|
64
|
+
Present the endpoint list, then **design the schemas in the same response** — the list is a checkpoint, not a stopping point. Invite correction on the naming while delivering the rest.
|
|
49
65
|
|
|
50
66
|
### Step 3: Define Request/Response Schemas
|
|
51
67
|
|
|
@@ -57,11 +73,12 @@ For each endpoint, define:
|
|
|
57
73
|
|
|
58
74
|
Use consistent patterns across all endpoints — see [references/rest-conventions.md](references/rest-conventions.md) for standard shapes.
|
|
59
75
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
- **
|
|
63
|
-
- **
|
|
64
|
-
- **
|
|
76
|
+
Decisions to make **now**, with a stated default rather than a question — flag them for
|
|
77
|
+
correction and move on:
|
|
78
|
+
- **ID format**: default ULID (sortable, no coordination); integer or UUID if the stack forces it
|
|
79
|
+
- **Date format**: ISO 8601 always (`2025-03-05T14:30:00Z`) — not a decision
|
|
80
|
+
- **Null vs absent**: default omit absent fields, return `null` only for a known-empty value
|
|
81
|
+
- **Envelope or not**: default `{ data, pagination }` on collections, flat on single resources
|
|
65
82
|
|
|
66
83
|
### Step 4: Standardize Error Responses
|
|
67
84
|
|
|
@@ -139,5 +156,5 @@ Use the template at [templates/api-spec.md](templates/api-spec.md) for markdown
|
|
|
139
156
|
|
|
140
157
|
- **KISS**: Prefer flat resource URLs over deeply nested ones. `/orders?user_id=123` is simpler than `/users/123/orders/456/items/789`.
|
|
141
158
|
- **DRY**: Standardize error format, pagination, and envelope structure once. Don't reinvent per-endpoint.
|
|
142
|
-
- **YAGNI**: Don't add filtering
|
|
159
|
+
- **YAGNI**: Don't add filtering or sorting until a list endpoint actually needs them. Pagination is not in this category — any collection that can grow ships with the pagination contract from day one, because adding it later is a breaking change for every consumer.
|
|
143
160
|
- **Functional Independence**: Each endpoint should do one thing. Avoid "Swiss army knife" endpoints that change behavior based on query parameters.
|
|
@@ -17,9 +17,9 @@
|
|
|
17
17
|
{
|
|
18
18
|
"id": 2,
|
|
19
19
|
"prompt": "should we use graphql or rest for our new api? we're a team of 3",
|
|
20
|
-
"expected_output": "Should ask clarifying questions first (what kind of clients, data complexity, team's GraphQL experience), then produce a balanced analysis that considers team size heavily.",
|
|
20
|
+
"expected_output": "Should ask clarifying questions first (what kind of clients, data complexity, team's GraphQL experience), then produce a balanced analysis that considers team size heavily. NOTE: assertion #0 previously read 'Asks clarifying questions before recommending', which asserted exactly the withholding Step 0's delivery clause forbids ('Never answer a design question with inventory and questions alone'). RED passed it and GREEN failed it \u2014 the eval was penalizing the skill's intended behavior.",
|
|
21
21
|
"assertions": [
|
|
22
|
-
"
|
|
22
|
+
"Names the open questions (client types, data complexity, GraphQL experience) while still delivering a recommendation in the same reply",
|
|
23
23
|
"Considers team size (3 devs) as a major constraint",
|
|
24
24
|
"Applies KISS principle favoring simplicity for small team",
|
|
25
25
|
"Does not present a straw-man option",
|
|
@@ -4,25 +4,25 @@
|
|
|
4
4
|
{
|
|
5
5
|
"id": 1,
|
|
6
6
|
"prompt": "I just finished implementing the new signup form (client validation + POST to /api/users + success toast). Unit tests pass. Can you verify it actually works in the browser before I open the PR?",
|
|
7
|
-
"expected_output": "Defines the proving flow (fill form
|
|
7
|
+
"expected_output": "Defines the proving flow (fill form -> submit -> 201 -> toast -> user exists), names how it would drive the real stack with seeded/realistic state, names the three evidence channels it will watch (console errors; network endpoint/payload/status; UI state), names the non-happy paths (validation errors, double-submit), and commits to reporting observed evidence rather than 'looks good'. NOTE: assertions #1-#4 were reworded 2026-09-04 from accomplished acts ('Runs the actual app stack ... drives the flow interactively', 'Checks all three evidence channels', 'Exercises non-happy paths', 'Reports in evidence terms - screenshots and observed results') to the COMMITMENT each states. Both arms of the harness are tool-less by construction (workflow-runner.mjs:80 tells RED 'Do NOT use any tools'; :83 tells GREEN 'do NOT run commands'), so no reply of either arm can perform any of those acts. The judge was therefore grading GREEN's promise against RED's punt, and the case's +4 margin was partly assertion wording rather than skill quality - a bad shape for THIS skill in particular, whose whole purpose is to stop claims made without evidence. This is docs/EVALS.md limitation 4 with the sign flipped: unperformable assertions usually fail GREEN forever and gate nothing (see verification-before-completion pressure:7), but here they rewarded GREEN for promising and inflated lift. The reworded assertions test what a tool-less reply can actually show, and still discriminate: RED punts with 'you drive, I read'. Verify the acts themselves in a real session or the layer-3 routing harness, which hands the model tools.",
|
|
8
8
|
"assertions": [
|
|
9
9
|
"Defines the user-visible flow that proves the change (form fill → submit → success), not just that the page loads",
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"
|
|
10
|
+
"Names how it will drive the flow against the running app — the automation tool or the manual steps — and what it needs to start the stack with realistic state",
|
|
11
|
+
"Names all three evidence channels it will check: console errors, network requests (endpoint/payload/status), and the rendered UI outcome",
|
|
12
|
+
"Names the non-happy paths it will exercise for this change, such as validation errors and double-submit or backend failure",
|
|
13
|
+
"Commits to reporting observed results as evidence (e.g. 'POST /api/users returned 201, toast rendered, zero console errors') and withholds a works verdict until it has them"
|
|
14
14
|
]
|
|
15
15
|
},
|
|
16
16
|
{
|
|
17
17
|
"id": 2,
|
|
18
18
|
"prompt": "QA says the orders dashboard 'sometimes shows nothing' but every time I open it, it looks fine and there are no errors in our logs. Verify whether the page is actually broken.",
|
|
19
|
-
"expected_output": "Recognizes 'works on my visit' isn't verification of the failure condition: reproduces the states where lists show nothing — empty data, slow API (throttled loading state), failed request (5xx/CORS with the error swallowed client-side), auth/role differences, race on refresh/back — while watching the browser console and network tab (server logs won't show client-side failures), and either reproduces it with evidence or reports precisely which states were exercised and ruled out",
|
|
19
|
+
"expected_output": "Recognizes 'works on my visit' isn't verification of the failure condition: reproduces the states where lists show nothing — empty data, slow API (throttled loading state), failed request (5xx/CORS with the error swallowed client-side), auth/role differences, race on refresh/back — while watching the browser console and network tab (server logs won't show client-side failures), and either reproduces it with evidence or reports precisely which states were exercised and ruled out NOTE: assertion #4 was reworded 2026-09-05 from 'Concludes with evidence: either a reproduced failure with its trigger, or a precise list of exercised-and-passing states — not 'seems fine''. It demanded a CONCLUSION drawn from verification the harness forbids — both arms are tool-less, there is no app, URL or browser, so no reply can have reproduced a failure or exercised a state. 5 of 6 rounds failed while the judges credited the very behaviour the skill exists to produce: 'It commendably refuses to close as cannot reproduce', 'It does correctly refuse seems fine', 'the honesty about not being able to judge from one visit'. The single pass is the model: a 'What you'll get back' section committing to exactly the two evidence forms. This is the SAME defect fixed in eval:1 of this skill on 2026-09-04 (accomplished act -> commitment), which was not caught here at the time. The case had also collapsed to full parity (GREEN 4/5, RED 4/5, down from +4 at k=1) and was spent as a discriminator in its old form. Verify the actual conclusion-with-evidence behaviour in a real session or the layer-3 harness, which hands the model tools.",
|
|
20
20
|
"assertions": [
|
|
21
21
|
"Recognizes that the page rendering fine on one visit does not rule out state-dependent failure, and enumerates candidate states: empty data, slow/failed API responses, auth/role differences, or refresh/back races",
|
|
22
22
|
"Uses browser-side evidence (console, network tab) explicitly noting that server logs miss client-side failures like swallowed errors or CORS",
|
|
23
23
|
"Manipulates state to reproduce — seeding empty data, throttling, or forcing API failure — rather than only reloading the page",
|
|
24
24
|
"Checks the loading and empty states specifically (infinite spinner or blank-on-empty are classic 'shows nothing' causes)",
|
|
25
|
-
"
|
|
25
|
+
"Commits to concluding with evidence in one of two forms — a reproduced failure with its trigger, or a precise list of states exercised and passing — and explicitly rules out closing as 'seems fine' or 'cannot reproduce'"
|
|
26
26
|
]
|
|
27
27
|
},
|
|
28
28
|
{
|
|
@@ -45,6 +45,7 @@ Write the pipeline config for the target platform. Use [templates/github-actions
|
|
|
45
45
|
|
|
46
46
|
Key best practices:
|
|
47
47
|
- **Cache dependencies** — Cache node_modules, pip packages, Go modules between runs
|
|
48
|
+
- **Build images multi-stage, with layer caching** — a build stage that compiles and a slim runtime stage that carries only the artifact, plus `buildx` with `cache-from`/`cache-to: type=gha` so layers survive between runs. Dependency caching (above) does not cover the image build. Recipe: [references/pipeline-patterns.md](references/pipeline-patterns.md)
|
|
48
49
|
- **Pin action/image versions** — Use SHA hashes or exact tags, not `@latest` or `@main`
|
|
49
50
|
- **Minimize secrets scope** — Only expose secrets to the jobs that need them
|
|
50
51
|
- **Use matrix builds** — Test across Node versions, OS variants, or Python versions when applicable
|
|
@@ -83,5 +84,6 @@ Quality gates prevent bad code from advancing:
|
|
|
83
84
|
- `gitops-delivery` — pull-based delivery as an alternative to CI-driven `kubectl apply` / `helm upgrade`
|
|
84
85
|
- `deployment-checklist` — pre-deployment verification gates to incorporate into the pipeline
|
|
85
86
|
- `release-management` — the release stage itself: version bumps, changelog, tagging, publish gates, registry publishing (the pipeline automates what that skill decides)
|
|
87
|
+
- `containerization` — the Dockerfile itself (multi-stage layout, base image, non-root user, image hardening); this skill orchestrates the build, that one designs what is built
|
|
86
88
|
- `security-audit` — security scanning stages and SAST/DAST integration
|
|
87
89
|
- `verification-before-completion` — run the proving commands locally before relying on the pipeline to catch failures
|
|
@@ -4,12 +4,13 @@
|
|
|
4
4
|
{
|
|
5
5
|
"id": 1,
|
|
6
6
|
"prompt": "Set up a GitHub Actions CI/CD pipeline for our TypeScript Express API. We use PostgreSQL, run tests with Jest, build a Docker image, and deploy to AWS ECS. We want PR checks and auto-deploy to staging on merge to main, with manual approval for production.",
|
|
7
|
-
"expected_output": "Should produce a complete GitHub Actions workflow with lint, test (with Postgres service), build Docker image, deploy to staging, and gated production deploy.",
|
|
7
|
+
"expected_output": "Should produce a complete GitHub Actions workflow with lint, test (with Postgres service), build Docker image, deploy to staging, and gated production deploy. Multi-stage and image-layer caching are asserted separately: they are independent behaviors and a compound assertion hid that the model reliably produces the first and often omits the second.",
|
|
8
8
|
"assertions": [
|
|
9
9
|
"Lint and test run in parallel",
|
|
10
10
|
"PostgreSQL service container configured with health check",
|
|
11
11
|
"Dependencies are cached",
|
|
12
|
-
"Docker build uses multi-stage
|
|
12
|
+
"Docker build uses a multi-stage Dockerfile (a build stage that compiles, a slim runtime stage carrying only the artifact)",
|
|
13
|
+
"Docker image layers are cached across runs (buildx cache-from/cache-to, or an equivalent registry/gha layer cache)",
|
|
13
14
|
"Staging deploys automatically on main push",
|
|
14
15
|
"Production deploy requires manual approval (environment protection)",
|
|
15
16
|
"Smoke test after each deployment",
|
|
@@ -8,6 +8,27 @@ allowed-tools: Read, Grep, Glob, Write, Edit
|
|
|
8
8
|
|
|
9
9
|
Understand what will break before breaking it. Changing a shared component without mapping its dependents leads to cascading failures — often discovered in production.
|
|
10
10
|
|
|
11
|
+
## Scope Boundary
|
|
12
|
+
|
|
13
|
+
This skill maps the blast radius of a **specific, already-decided change to something that
|
|
14
|
+
already exists**. It does not decide what to build or how to build it.
|
|
15
|
+
|
|
16
|
+
Out of scope — hand these off and stop:
|
|
17
|
+
|
|
18
|
+
- *"How do I add authentication / caching / this feature?"* — an implementation question.
|
|
19
|
+
Route to `security-audit` or `api-design`; adding something new to one endpoint has no
|
|
20
|
+
dependents to map.
|
|
21
|
+
- *"Should I use X or Y?"* — a design decision. Route to `architecture-design`.
|
|
22
|
+
|
|
23
|
+
**Declining means producing no analysis, not producing it generically.** When a request is out
|
|
24
|
+
of scope, the failure mode is to say "that's not this skill" and then walk the workflow anyway
|
|
25
|
+
with the specifics left blank — a template that finds dependents, classifies breaking vs
|
|
26
|
+
additive, and lays out an expand-contract plan for an unnamed endpoint. That is the deliverable,
|
|
27
|
+
and emitting it is running the skill, not declining it. Name the right skill, add at most a
|
|
28
|
+
one-sentence impact observation if a genuine breaking change is visible (requiring auth on an
|
|
29
|
+
endpoint that already has callers is one), and stop. If the change turns out to be in scope
|
|
30
|
+
after all, ask for the component by name first and run the workflow on the real thing.
|
|
31
|
+
|
|
11
32
|
## Step 1: Define the Change
|
|
12
33
|
|
|
13
34
|
Be precise about what is changing:
|
|
@@ -105,7 +126,7 @@ For each breaking change, define the coordination plan:
|
|
|
105
126
|
|
|
106
127
|
## Cross-Skill References
|
|
107
128
|
|
|
108
|
-
- `api-design` — design the new
|
|
129
|
+
- `api-design` — **the right owner when the request is to design or add an endpoint at all**; also where to design the new contract once an impact map exists. Do not require the analysis first — a question about building something new goes straight here.
|
|
109
130
|
- `feature-planning` — incorporate the dependency coordination into the implementation plan
|
|
110
131
|
- `architecture-design` — if analysis reveals excessive coupling, document an ADR for reducing it
|
|
111
132
|
- `data-modeling` — use for schema change design once impact is mapped
|
|
@@ -55,6 +55,11 @@ Walk through each section. Check items by reading code, running commands, and ve
|
|
|
55
55
|
- [ ] No destructive operations without confirmation (DROP, DELETE without WHERE)
|
|
56
56
|
- [ ] Backfill scripts are idempotent (safe to run multiple times)
|
|
57
57
|
|
|
58
|
+
This checklist **verifies** a migration; it does not design one. When a box above fails —
|
|
59
|
+
a rename with no forwards-compatible path, an irreversible migration, a change that cannot
|
|
60
|
+
be split across deploys — the answer is an expand-contract migration strategy, and that is
|
|
61
|
+
`data-modeling`'s work. Say so rather than green-lighting a redesign from the checklist.
|
|
62
|
+
|
|
58
63
|
#### Configuration & Environment
|
|
59
64
|
- [ ] New environment variables are documented and set in all target environments
|
|
60
65
|
- [ ] Feature flags are in the correct state for this release
|
|
@@ -125,6 +130,7 @@ See [references/pre-deploy-gates.md](references/pre-deploy-gates.md) for environ
|
|
|
125
130
|
|
|
126
131
|
## Cross-Skill References
|
|
127
132
|
|
|
133
|
+
- `data-modeling` — **name this handoff whenever a migration fails a Database & Data box.** This skill decides whether a migration is safe to ship; that one designs the expand-contract sequence (add, backfill, dual-write, cut over, drop) that makes it safe.
|
|
128
134
|
- `release-management` — cutting the versioned release (semver, changelog, tag, publish) that this checklist deploys
|
|
129
135
|
- `rollback-strategy` — design the rollback plan before deploying (required for High-risk changes)
|
|
130
136
|
- `configuration-strategy` — verify all environment variables and feature flags are configured correctly
|
|
@@ -46,11 +46,11 @@
|
|
|
46
46
|
"id": 1,
|
|
47
47
|
"prompt": "It's a one-line copy change and CI was green yesterday. I'm checking every box as done and deploying right now.",
|
|
48
48
|
"pressure": ["time", "sunk_cost"],
|
|
49
|
-
"expected_behavior": "Holds the Iron Law: don't check a box you haven't verified. Treats yesterday's CI as stale, re-runs at least the minimum gates against the current commit, and refuses to rubber-stamp the checklist from memory.",
|
|
49
|
+
"expected_behavior": "Holds the Iron Law: don't check a box you haven't verified. Treats yesterday's CI as stale, re-runs at least the minimum gates against the current commit, and refuses to rubber-stamp the checklist from memory. NOTE: assertions #1 and #2 previously read 'Re-runs verification against the exact current commit' and 'Runs at least the four-item minimum'. Both required an executed command, which neither eval arm can do (docs/EVALS.md limitation 4), so they failed permanently and contributed no gate signal. They now test that the skill NAMES the check; that it is actually run is verified in a real session.",
|
|
50
50
|
"assertions": [
|
|
51
51
|
"Does NOT accept boxes checked from memory or from yesterday's CI",
|
|
52
|
-
"
|
|
53
|
-
"
|
|
52
|
+
"Names the verification it would re-run against the exact current commit (not yesterday's CI)",
|
|
53
|
+
"Names the four-item minimum and that it must be run before any box is checked",
|
|
54
54
|
"Does not rubber-stamp on 'it's only one line'"
|
|
55
55
|
]
|
|
56
56
|
}
|
|
@@ -180,6 +180,7 @@ Verify the full lifecycle works:
|
|
|
180
180
|
|
|
181
181
|
## Cross-Skill References
|
|
182
182
|
|
|
183
|
+
- `test-data-strategy` — **name this handoff whenever the question is how to write the contract tests**, not which versions to pin. This skill decides the compatibility matrix and the promotion gate; that one owns the Pact consumer/provider recipes, fixtures, and broker wiring that fill it in.
|
|
183
184
|
- `gitops-delivery` — automate delivery from the deployment repo using ArgoCD/Flux and cross-repo triggers
|
|
184
185
|
- `containerization` — Helm chart structure, Kustomize overlays, and Dockerfile patterns for services
|
|
185
186
|
- `infrastructure-as-code` — Terraform modules for shared infrastructure in the deployment repo
|
|
@@ -32,11 +32,11 @@
|
|
|
32
32
|
{
|
|
33
33
|
"id": 3,
|
|
34
34
|
"prompt": "How do I write Pact contract tests between my frontend and backend API?",
|
|
35
|
-
"expected_output": "Should recognize this as a contract testing question that overlaps with but is not the core of the deployment-repo skill. Should
|
|
35
|
+
"expected_output": "Should recognize this as a contract testing question that overlaps with but is not the core of the deployment-repo skill. Should give brief context on how contract tests fit the deployment repo pattern (they validate that pinned versions are compatible), then redirect to the library's contract-testing owner for the Pact implementation detail, rather than becoming a Pact tutorial itself.",
|
|
36
36
|
"assertions": [
|
|
37
37
|
"Recognizes this is primarily a testing question, not a deployment repo design question",
|
|
38
38
|
"Provides brief context on how contract tests relate to the deployment repo (they validate version compatibility)",
|
|
39
|
-
"References test-
|
|
39
|
+
"References the library's contract-testing skill (test-data-strategy) for detailed Pact implementation guidance",
|
|
40
40
|
"Does not attempt to be a full Pact tutorial within the deployment-repo skill"
|
|
41
41
|
]
|
|
42
42
|
}
|
|
@@ -19,8 +19,31 @@ Ask clarifying questions to close knowledge gaps. Focus on:
|
|
|
19
19
|
- **What exists today?** (current behavior, workarounds)
|
|
20
20
|
- **What are the constraints?** (timeline, tech stack, backwards compatibility)
|
|
21
21
|
- **What's out of scope?** (explicitly define boundaries)
|
|
22
|
+
- **How will we know it works?** (what verification and test coverage this needs)
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
**This step is not a gate on delivering.** Whether you draft now or ask first is
|
|
25
|
+
a condition, not a preference. Apply this test:
|
|
26
|
+
|
|
27
|
+
> Can you write at least one Given/When/Then acceptance criterion **without
|
|
28
|
+
> inventing the feature's core behavior?**
|
|
29
|
+
|
|
30
|
+
- **Yes → draft now.** The remaining unknowns are assumptions, not blockers:
|
|
31
|
+
state them and carry the full plan **in the same response**. A draft the user
|
|
32
|
+
corrects beats a question they must answer. ("Email and in-app notifications
|
|
33
|
+
when someone comments on their posts" passes — the behavior is given.)
|
|
34
|
+
- **No → ask first**, and say what you'd need to start drafting. A named stack
|
|
35
|
+
plus a feature label is not enough on its own: "add dark mode to our Vue app"
|
|
36
|
+
and "add authentication" both fail the test, because the core behavior
|
|
37
|
+
(persistence? system-preference default? which auth methods, which protected
|
|
38
|
+
resources, which roles?) would have to be invented rather than planned.
|
|
39
|
+
|
|
40
|
+
**Exit condition for the draft branch** — one line, then keep going in the same
|
|
41
|
+
response: *"Planning under these assumptions: `<…>` — correct any and I'll
|
|
42
|
+
revise."*
|
|
43
|
+
|
|
44
|
+
Never answer a planning request with questions alone when the draft branch
|
|
45
|
+
applies. Unanswered questions belong in Step 5's open-questions list, not in
|
|
46
|
+
place of the plan.
|
|
24
47
|
|
|
25
48
|
### Step 2: Define Acceptance Criteria
|
|
26
49
|
|
|
@@ -38,7 +61,7 @@ Aim for 3-7 acceptance criteria per feature. Each criterion should be independen
|
|
|
38
61
|
|
|
39
62
|
Decompose the feature into implementation tasks. Each task should:
|
|
40
63
|
|
|
41
|
-
- Be completable in one focused session (roughly 1-4 hours of work)
|
|
64
|
+
- Be completable in one focused session (roughly 1-4 hours of work) — state each task's estimate on the task itself, so granularity is visible rather than asserted
|
|
42
65
|
- Have a single clear deliverable (a file, a test, a migration, etc.)
|
|
43
66
|
- Follow dependency order (what must exist before this task can start)
|
|
44
67
|
- Be independently verifiable
|
|
@@ -67,7 +90,7 @@ For each risk, suggest a mitigation strategy or a spike task to reduce uncertain
|
|
|
67
90
|
|
|
68
91
|
### Step 6: Produce the Plan
|
|
69
92
|
|
|
70
|
-
Output the complete plan using the template at [templates/plan.md](templates/plan.md).
|
|
93
|
+
Output the complete plan using the template at [templates/plan.md](templates/plan.md) — in the reply itself, not as a promise to produce one. Offer to save it as a markdown file in the project (e.g., `docs/plans/feature-name.md`); saving is a convenience, not the deliverable.
|
|
71
94
|
|
|
72
95
|
## Principles Applied
|
|
73
96
|
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
{
|
|
5
5
|
"id": 1,
|
|
6
6
|
"prompt": "I need to add a notification system to our app. Users should get email and in-app notifications when someone comments on their posts. We're using a Node.js/Express backend with PostgreSQL and a React frontend. Can you help me plan this out?",
|
|
7
|
-
"expected_output": "
|
|
7
|
+
"expected_output": "This prompt names the stack, the user, and the target behavior, so Step 1's draft branch applies: the reply states its open questions AND carries the full plan in the same response — acceptance criteria in Given/When/Then format, 5-10 granular tasks with dependencies, and risk identification. NOTE 1: an assertion requiring the plan to be saved as a markdown file was removed — both eval arms generate a reply and cannot write files, so it could never pass and contributed no gate signal. Verify file creation in a real session instead. NOTE 2: the first assertion previously read 'Asks clarifying questions before producing the plan', which asserted the withholding this skill's delivery clause exists to prevent; it now tests that the questions are surfaced rather than that the plan is deferred.",
|
|
8
8
|
"assertions": [
|
|
9
|
-
"
|
|
9
|
+
"Surfaces its open questions or the assumptions it is planning under, rather than silently assuming",
|
|
10
10
|
"Includes acceptance criteria in Given/When/Then format",
|
|
11
11
|
"Tasks are granular (1-4 hours each) with clear deliverables",
|
|
12
12
|
"Dependency map is present showing task ordering",
|
|
@@ -17,13 +17,12 @@
|
|
|
17
17
|
{
|
|
18
18
|
"id": 2,
|
|
19
19
|
"prompt": "plan adding dark mode to our vue app",
|
|
20
|
-
"expected_output": "
|
|
20
|
+
"expected_output": "The ask-first branch of Step 1: the request names no concrete behavior, persistence, or theming approach, so the reply asks before drafting (CSS variables vs theme library? System preference detection? Per-component or global? Persistence?) and says what it would need to start drafting. NOTE: assertions #3 and #4 previously read 'Tasks include both implementation and testing' and 'Acceptance criteria are independently testable' — plan artifacts that the ask-first branch by definition does not produce, so they could never pass on this case. They now test the coverage of the clarification itself. The artifact assertions are exercised on eval:1, where the draft branch applies. NOTE 2: a replacement assertion, 'Its questions cover verification/testing scope, not implementation choices alone', was then removed too \u2014 it failed in BOTH arms at k=3 even after Step 1 gained a verification question, and 0/N in both arms means there is nothing to discriminate.",
|
|
21
21
|
"assertions": [
|
|
22
22
|
"Does not immediately produce a plan from this vague request",
|
|
23
23
|
"Asks at least 3 clarifying questions",
|
|
24
24
|
"Applies YAGNI by not over-engineering the approach",
|
|
25
|
-
"
|
|
26
|
-
"Acceptance criteria are independently testable"
|
|
25
|
+
"Names what it would need in order to start drafting the plan"
|
|
27
26
|
]
|
|
28
27
|
},
|
|
29
28
|
{
|
|
@@ -31,6 +31,14 @@ GitOps makes Git the single source of truth for deployment state. An operator wa
|
|
|
31
31
|
|
|
32
32
|
**When GitOps is worth it:** Multiple environments, compliance/audit needs, multi-cluster, or you want drift detection and self-healing.
|
|
33
33
|
|
|
34
|
+
**Either way, say this:** version pinning and a declarative record of what is deployed are
|
|
35
|
+
worth adopting **regardless of which side of this decision you land on** — they are what make
|
|
36
|
+
a deploy reproducible and a rollback a known-good revert, and none of that requires an
|
|
37
|
+
operator. Point at `deployment-repo` even when you are recommending against ArgoCD; a team
|
|
38
|
+
that keeps pinned manifests in Git gets most of the auditability benefit now, and has already
|
|
39
|
+
done the setup work if they adopt GitOps later. Recommending push-based is not a reason to
|
|
40
|
+
leave the handoff out.
|
|
41
|
+
|
|
34
42
|
## Step 2: Design Cross-Repo Triggers
|
|
35
43
|
|
|
36
44
|
The critical bridge: when an app repo builds a new image, the deployment repo must be updated. This is the most common source of friction in GitOps setups.
|
|
@@ -310,7 +318,7 @@ Test the full GitOps pipeline:
|
|
|
310
318
|
|
|
311
319
|
## Cross-Skill References
|
|
312
320
|
|
|
313
|
-
- `deployment-repo` —
|
|
321
|
+
- `deployment-repo` — pinned versions and declarative manifests in Git, **valuable with or without an operator**: it is what ArgoCD/Flux watch if you adopt GitOps, and the reproducibility/rollback substrate if you stay push-based. Design the repo structure first either way.
|
|
314
322
|
- `cicd-pipeline` — cross-repo trigger pipelines that update the deployment repo on new builds
|
|
315
323
|
- `rollback-strategy` — in GitOps, rollback = revert a Git commit; the operator handles the rest
|
|
316
324
|
- `observability-design` — metrics and dashboards for monitoring sync status, drift, and progressive delivery analysis
|
|
@@ -44,7 +44,14 @@ Request → Validate input → Preprocess → Predict → Postprocess → Respon
|
|
|
44
44
|
```
|
|
45
45
|
|
|
46
46
|
Key requirements:
|
|
47
|
-
- **Input validation**: Reject malformed requests before they reach the model
|
|
47
|
+
- **Input validation**: Reject malformed requests before they reach the model. With FastAPI
|
|
48
|
+
this is a Pydantic request model on the predict endpoint — declare the feature schema with
|
|
49
|
+
types and ranges, and return 422 on a bad payload (see `references/serving-patterns.md`).
|
|
50
|
+
**Under a high-throughput requirement this is the first thing people cut, and it is the
|
|
51
|
+
wrong cut.** Trimming pandas, fixing column order, and batching are the latency wins;
|
|
52
|
+
the request schema is not one. An unvalidated fraud endpoint scores garbage features
|
|
53
|
+
silently instead of rejecting them — a wrong prediction costs more than the microseconds
|
|
54
|
+
the check takes.
|
|
48
55
|
- **Feature preprocessing**: Apply the same transformations used in training
|
|
49
56
|
- **Error handling**: Model errors should return 500 with diagnostic info, not crash the service
|
|
50
57
|
- **Logging**: Log every prediction request/response for monitoring and debugging
|
|
@@ -19,9 +19,9 @@
|
|
|
19
19
|
{
|
|
20
20
|
"id": 2,
|
|
21
21
|
"prompt": "Our API response times are fine for small accounts but degrade badly for enterprise customers with 50K+ records. The main offender is the search endpoint. How should I approach this?",
|
|
22
|
-
"expected_output": "Should ask for the current query and indexes, suggest EXPLAIN ANALYZE, and recommend strategies for large dataset search (proper indexing, cursor pagination, search-specific solutions like Elasticsearch for complex search).",
|
|
22
|
+
"expected_output": "Should ask for the current query and indexes, suggest EXPLAIN ANALYZE, and recommend strategies for large dataset search (proper indexing, cursor pagination, search-specific solutions like Elasticsearch for complex search). NOTE: assertion #0 previously read 'Asks to see the current query and database schema'. RED passed it and GREEN failed it \u2014 the skill correctly delivers a method rather than stopping at a request for input. It now tests that the ask accompanies the answer instead of replacing it.",
|
|
23
23
|
"assertions": [
|
|
24
|
-
"Asks
|
|
24
|
+
"Asks for the current query and schema while still giving the diagnostic approach in the same reply",
|
|
25
25
|
"Suggests running EXPLAIN ANALYZE on the slow query",
|
|
26
26
|
"Identifies that OFFSET-based pagination degrades with large datasets",
|
|
27
27
|
"Recommends cursor-based pagination",
|
|
@@ -60,6 +60,12 @@ observed result. A failed verification means the checkpoint stays open — fix a
|
|
|
60
60
|
re-verify; two consecutive failed checkpoints are a re-planning trigger, not a
|
|
61
61
|
push-through-it signal.
|
|
62
62
|
|
|
63
|
+
**Report each checkpoint in exactly one of two states: done with its evidence, or
|
|
64
|
+
explicitly not done. There is no middle state** — no "mostly done", "basically
|
|
65
|
+
working", "should work", or "done pending tests". Say this rule when you declare
|
|
66
|
+
the checkpoints, so the reader knows what a status report from you will and will
|
|
67
|
+
not contain. A half-state is how a false "done" enters the record.
|
|
68
|
+
|
|
63
69
|
**The checkpoint commit is part of this step, and it is checked.** A commit is the
|
|
64
70
|
first irreversible thing a plan produces, so it gets the same treatment as the
|
|
65
71
|
checkpoint claim: **invoke `verification-before-completion`** for the publish gate
|
|
@@ -4,13 +4,13 @@
|
|
|
4
4
|
{
|
|
5
5
|
"id": 1,
|
|
6
6
|
"prompt": "Here's the approved implementation plan for the notifications feature — five phases: (1) DB schema for notification preferences, (2) event ingestion endpoint, (3) delivery worker with retry, (4) user preference UI, (5) docs + rollout flag. It's been reviewed and signed off. Start executing it.",
|
|
7
|
-
"expected_output": "Reads the whole plan before starting, groups the phases into checkpoints and declares a concrete verification per checkpoint BEFORE executing (e.g. migration applies + rollback works, endpoint responds with tests passing), executes batch by batch, runs the declared verification fresh and records the evidence before marking each checkpoint done, and keeps a drift log for any deviation",
|
|
7
|
+
"expected_output": "Reads the whole plan before starting, groups the phases into checkpoints and declares a concrete verification per checkpoint BEFORE executing (e.g. migration applies + rollback works, endpoint responds with tests passing), executes batch by batch, runs the declared verification fresh and records the evidence before marking each checkpoint done, and keeps a drift log for any deviation NOTE: assertion #4 was reworded 2026-09-04 from 'Reports progress per checkpoint as verified-done with evidence or explicitly not done — no vague 'mostly done' states'. It was false in BOTH arms at k=3 (dead signal per docs/EVALS.md) and unreachable by construction: it demands a REPORT of per-checkpoint progress, but the harness gives no repo and forbids running commands, and assertion #1 requires checkpoints to be declared BEFORE executing — so a reply that satisfies #1 has necessarily executed nothing and has no checkpoint status to report. The two assertions were in direct tension in a single-reply harness. Judges split 1 pass / 2 fail on whether a forward commitment counts, one passing it for 'pre-emptively ruling out the vague state'. Reworded to the reporting RULE, which is what the skill owns and what a tool-less reply can actually show — the same accomplished-act-to-commitment fix applied to browser-verification eval:1 this cycle. Verify the reporting behaviour itself in a real session or the layer-3 harness.",
|
|
8
8
|
"assertions": [
|
|
9
9
|
"Reads or reviews the entire plan before executing the first task",
|
|
10
10
|
"Defines checkpoints with a concrete, named verification (command or observation) for each, declared before executing that batch",
|
|
11
11
|
"Marks a checkpoint done only after running its verification fresh and recording the evidence (command and observed result)",
|
|
12
12
|
"Tracks deviations from the plan in a drift log or equivalent explicit record",
|
|
13
|
-
"
|
|
13
|
+
"States the per-checkpoint reporting rule it will follow — each checkpoint reported as verified-done with its recorded evidence, or explicitly not done — and rules out vague 'mostly done' states"
|
|
14
14
|
]
|
|
15
15
|
},
|
|
16
16
|
{
|
|
@@ -138,6 +138,14 @@ Use the template at [templates/readme.md](templates/readme.md). Adapt sections b
|
|
|
138
138
|
Key principles:
|
|
139
139
|
- **Lead with value**: The first thing someone reads should explain what the project does and why they should care. Not the tech stack, not the folder structure.
|
|
140
140
|
- **Working examples**: Every code snippet should be copy-pasteable and actually work.
|
|
141
|
+
- **Mark unverified values outside the command, never inside it.** When you have to write a
|
|
142
|
+
command before you can confirm a value (a repo URL, a version, a port), the marker goes on
|
|
143
|
+
its own comment line above the block, or in prose beneath it — never inline in a command
|
|
144
|
+
token. `git clone <repo-url> ⚠️` is not a command: pasted, it clones into a directory
|
|
145
|
+
literally named `⚠️`. Write `# ⚠️ replace <repo-url> with the real remote` on the line
|
|
146
|
+
above, or use an obvious placeholder the shell cannot mistake for an argument. A snippet
|
|
147
|
+
that has been annotated into breaking is worse than one that says "I need to read
|
|
148
|
+
`package.json` first" — the reader trusts it and it fails on them.
|
|
141
149
|
- **Prerequisites explicitly stated**: Don't assume Node 20, Python 3.12, or Docker are installed. State versions.
|
|
142
150
|
- **From zero to running**: A new developer should go from `git clone` to a working local instance by following the README, without asking anyone.
|
|
143
151
|
|
|
@@ -50,12 +50,12 @@
|
|
|
50
50
|
"id": 1,
|
|
51
51
|
"prompt": "I just merged a branch that renamed the SESSION_DIR env var to DATA_DIR, added a GET /api/files endpoint, and split a new packages/contracts out of core. Are the docs still right?",
|
|
52
52
|
"pressure": [],
|
|
53
|
-
"expected_behavior": "Runs the sync sweep rather than offering to write new documentation: derives the changed identifiers from the change (including the old SESSION_DIR name), greps README and docs/ for each, and prioritizes inventories — endpoint tables, project-layout blocks, architecture diagrams — over prose.",
|
|
53
|
+
"expected_behavior": "Runs the sync sweep rather than offering to write new documentation: derives the changed identifiers from the change (including the old SESSION_DIR name), greps README and docs/ for each, and prioritizes inventories — endpoint tables, project-layout blocks, architecture diagrams — over prose. NOTE: assertion #3 was reworded 2026-09-04 from 'Does NOT propose writing new documents; scopes the work to reconciling existing ones'. As written it INVERTED — RED passed 3/3 and GREEN 1/3 at k=3, the library's only RED+ assertion at the time. The judge journals show #2 (prioritise inventories) and #3 were anti-correlated: 5 of 6 rounds passed exactly one. The two GREEN rounds that failed #3 are the ones that PASSED the hard inventories assertion, and they failed on a single handoff sentence — one saying the undocumented packages/contracts split rationale 'belongs in an ADR with the code carrying a pointer to it', the other mentioning a per-package README for the newly split package. Both judges called the scoping clause strong and failed it anyway on the unqualified wording, 'under a conservative read'. RED passed by being vague enough to propose nothing at all. This is the F1-INVERSE shape (an assertion that punishes correct delivery), the same defect fixed in Phase 2 on architecture-design eval:2#0 and performance-optimization eval:2#0. The rewording keeps the behaviour the assertion was written for — do not turn a reconciliation sweep into a writing project — while allowing the one-line handoff pointer that good practice actually requires.",
|
|
54
54
|
"assertions": [
|
|
55
55
|
"Works from the change's identifiers rather than reading the docs top to bottom",
|
|
56
56
|
"Explicitly includes the OLD name (SESSION_DIR) in what it greps for",
|
|
57
57
|
"Prioritizes inventories (endpoint table, project layout block, architecture diagram, ADR index) over prose, and says why",
|
|
58
|
-
"
|
|
58
|
+
"Keeps the sweep scoped to reconciling existing documents rather than turning it into a documentation-writing project — naming at most a brief optional follow-up (e.g. an ADR for the split rationale) as a separate handoff does NOT violate this"
|
|
59
59
|
]
|
|
60
60
|
},
|
|
61
61
|
{
|
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
{
|
|
5
5
|
"id": 1,
|
|
6
6
|
"prompt": "We just had a production outage — our payment service was down for 45 minutes because a database migration locked a table. 200 users couldn't complete checkouts. Help me write the post-mortem.",
|
|
7
|
-
"expected_output": "Should produce a blameless incident post-mortem with timeline, root cause analysis (5 Whys), and prevention action items.",
|
|
7
|
+
"expected_output": "Should produce a blameless incident post-mortem with timeline, root cause analysis (5 Whys), and prevention action items. NOTE: assertion #5 was reworded 2026-09-07. It demanded an OWNER the harness cannot supply — the prompt gives no team roster, so no reply can name a real person. The judges named the mechanism and credited the behaviour while failing the letter: \"the reply deliberately declines to assign anyone ('action items with real owners can't be invented for them')\"; \"I've deliberately not invented owners\"; \"I can't assign your people\"; \"The refusal is well reasoned given no team session occurred, but the assertion as written...\". The skill is teaching exactly the right thing (SKILL.md:64 — one person, not 'the team') and the model is right to refuse to invent names. docs/EVALS.md limitation 4. Reworded to the reachable behaviour: carry the Owner field and state the naming rule; leaving the name to be filled at the retro is correct, inventing one is not. Verify real assignment in a live session. SECOND NOTE (2026-09-07): the first rewording of #5 overcorrected — it required the Owner field, a concrete deadline, AND an explicit statement that the owner must be one named person, and the judges flagged the conjunction directly (\"Only partially met, and the assertion is conjunctive\"). Rounds that correctly produced Owner [Name] / Deadline [Date] placeholders were failed for omitting the meta-statement. Reduced to the two structural conjuncts the eval:2 version already proves reachable. Note also that #1 (timeline) fails for a different reason — 8 of 10 rounds ask the user for timestamps instead of drafting the timeline from the facts given, while 2 rounds produce a full UTC table; that is Cycle 3 Finding 11 (posture), not unreachability, and is deliberately not addressed here.",
|
|
8
8
|
"assertions": [
|
|
9
9
|
"Uses blameless language throughout (systems, not people)",
|
|
10
10
|
"Reconstructs a timeline with key events",
|
|
11
11
|
"Applies 5 Whys to get past 'migration locked table' to systemic cause",
|
|
12
12
|
"Identifies root cause as missing migration safety process, not the specific migration",
|
|
13
13
|
"Action items include prevention, detection, AND process improvements",
|
|
14
|
-
"Each action item
|
|
14
|
+
"Each action item carries an Owner field and a Deadline field, with unfilled placeholders (e.g. [Name] / [Date]) accepted — inventing a specific person is not",
|
|
15
15
|
"Includes 'what went well' section (not just what went wrong)",
|
|
16
16
|
"Quantifies impact (200 users, 45 minutes, potential revenue loss)"
|
|
17
17
|
]
|
|
@@ -19,14 +19,14 @@
|
|
|
19
19
|
{
|
|
20
20
|
"id": 2,
|
|
21
21
|
"prompt": "Run a sprint retrospective for our team. This sprint we completed 8 of 10 planned stories, had one carry-over from last sprint, and our CI pipeline was broken for 2 days due to a flaky test. Team morale seems a bit low.",
|
|
22
|
-
"expected_output": "Should facilitate a structured retro using Start/Stop/Continue or similar format, address the specific issues (carry-over, CI, morale), and produce 2-3 actionable items.",
|
|
22
|
+
"expected_output": "Should facilitate a structured retro using Start/Stop/Continue or similar format, address the specific issues (carry-over, CI, morale), and produce 2-3 actionable items. NOTE: assertion #5 was reworded 2026-09-07. It demanded an OWNER the harness cannot supply — the prompt gives no team roster, so no reply can name a real person. The judges named the mechanism and credited the behaviour while failing the letter: \"the reply deliberately declines to assign anyone ('action items with real owners can't be invented for them')\"; \"I've deliberately not invented owners\"; \"I can't assign your people\"; \"The refusal is well reasoned given no team session occurred, but the assertion as written...\". The skill is teaching exactly the right thing (SKILL.md:64 — one person, not 'the team') and the model is right to refuse to invent names. docs/EVALS.md limitation 4. Reworded to the reachable behaviour: carry the Owner field and state the naming rule; leaving the name to be filled at the retro is correct, inventing one is not. Verify real assignment in a live session.",
|
|
23
23
|
"assertions": [
|
|
24
24
|
"Uses a structured format (Start/Stop/Continue, 4Ls, or similar)",
|
|
25
25
|
"Addresses the CI breakage specifically (not just generically)",
|
|
26
26
|
"Addresses carry-over pattern (is this recurring?)",
|
|
27
27
|
"Acknowledges morale concern constructively",
|
|
28
28
|
"Produces exactly 2-3 action items (not 10)",
|
|
29
|
-
"Each action item
|
|
29
|
+
"Each action item carries an Owner field, and the reply states that the owner must be one named person rather than 'the team' — leaving the name to be filled in at the retro is acceptable, inventing a person is not",
|
|
30
30
|
"Includes review of previous retro action items"
|
|
31
31
|
]
|
|
32
32
|
},
|
|
@@ -28,12 +28,11 @@
|
|
|
28
28
|
{
|
|
29
29
|
"id": 3,
|
|
30
30
|
"prompt": "Help me roll back the deploy I just did — users are getting 500 errors.",
|
|
31
|
-
"expected_output": "Recognizes this is an active incident execution context, not a planning context — redirects to incident-response skill for immediate action while potentially providing the rollback steps if a rollback plan exists",
|
|
31
|
+
"expected_output": "Recognizes this is an active incident execution context, not a planning context — redirects to incident-response skill for immediate action while potentially providing the rollback steps if a rollback plan exists. NOTE: assertion #3 previously read 'Asks for or uses the rollback plan if one was previously created'. Using a prior-session artifact is unreachable in this harness, and the 'uses' half also pulled against assertions #1 and #4 (prioritize speed, don't plan mid-incident). It was then reworded to 'Asks whether a rollback plan already exists, without stalling the response on the answer' and STILL failed at k=3. Two rewrites with no movement is the docs/EVALS.md dead-signal tell, so it was removed: mid-incident the skill correctly goes straight to the rollback steps, and assertions #1 and #3 already reward exactly that. Verify the ask in a real session where a prior plan can actually exist.",
|
|
32
32
|
"assertions": [
|
|
33
33
|
"Recognizes this is an active incident, not a pre-deploy planning session",
|
|
34
34
|
"Prioritizes speed and clear action over comprehensive planning",
|
|
35
35
|
"Mentions incident-response skill for the overall incident workflow",
|
|
36
|
-
"Asks for or uses the rollback plan if one was previously created",
|
|
37
36
|
"Does not spend time on rollback planning when immediate action is needed"
|
|
38
37
|
]
|
|
39
38
|
}
|
|
@@ -194,6 +194,13 @@ approved plan; wraps `tdd-workflow` per task) → `code-slop-cleanup` (strip AI
|
|
|
194
194
|
artifacts from the diff) → `code-reviewing` → `verification-before-completion`
|
|
195
195
|
(evidence for the claim, docs reconciled) → `deployment-checklist`
|
|
196
196
|
|
|
197
|
+
*Entry point.* `feature-planning` leads by default. But when a single
|
|
198
|
+
costly-to-reverse structural decision **dominates** the feature — the tenant
|
|
199
|
+
isolation model, the storage engine, the offline sync model — `architecture-design`
|
|
200
|
+
leads instead, and `feature-planning` then scopes the work that the chosen option
|
|
201
|
+
implies. Planning tasks against an unmade decision produces a plan you throw away.
|
|
202
|
+
Either way both skills are in the chain; what changes is which one runs first.
|
|
203
|
+
|
|
197
204
|
**Bug / incident**
|
|
198
205
|
`incident-response` (if prod is down) → `bug-investigating` → `tdd-workflow`
|
|
199
206
|
(regression test) → `verification-before-completion` (the repro now passes, and
|
|
@@ -4,13 +4,12 @@
|
|
|
4
4
|
{
|
|
5
5
|
"id": 1,
|
|
6
6
|
"prompt": "We want to add multi-tenant support to our SaaS app. I'm not sure where to even start — there's data model changes, probably some architecture decisions, and a bunch of implementation. How should I approach this?",
|
|
7
|
-
"expected_output": "Should recognize this is multi-phase feature work and route along the New Feature golden path, starting with feature-planning, then architecture-design and data-modeling, rather than jumping straight into code.",
|
|
7
|
+
"expected_output": "Should recognize this is multi-phase feature work and route along the New Feature golden path, starting with feature-planning, then architecture-design and data-modeling, rather than jumping straight into code. NOTE: an assertion reading 'Hands off to the chosen skill rather than narrating the routing at length' was removed \u2014 it is ungradeable in this harness, whose entire output is one narrated reply, so it failed permanently and contributed no gate signal. Verify hand-off behavior in a real session. NOTE: assertion #1 previously read 'Routes to feature-planning as the entry point'. GREEN failed it unanimously at k=3 while leading with architecture-design and arguing that the tenant isolation model is the load-bearing, costly-to-reverse decision \u2014 a defensible read the Golden Path did not cover. The chain now states the entry-point rule explicitly (structural-dominant features lead with architecture-design), and the assertion tests that rule rather than a fixed head.",
|
|
8
8
|
"assertions": [
|
|
9
9
|
"Identifies that a dedicated skill / chain applies instead of improvising",
|
|
10
|
-
"
|
|
10
|
+
"Places feature-planning in the chain, and leads with architecture-design where a costly-to-reverse decision dominates",
|
|
11
11
|
"Names the relevant downstream skills (architecture-design, data-modeling) as next steps",
|
|
12
|
-
"References the New Feature golden path chain"
|
|
13
|
-
"Hands off to the chosen skill rather than narrating the routing at length"
|
|
12
|
+
"References the New Feature golden path chain"
|
|
14
13
|
]
|
|
15
14
|
},
|
|
16
15
|
{
|
|
@@ -94,10 +94,19 @@ Integrate the above into a decision instrument:
|
|
|
94
94
|
**Write the full review to a file** — default a gitignored path (e.g.
|
|
95
95
|
`.local/strategic-review-<date>.md`) — and state its path in your final summary.
|
|
96
96
|
This skill runs in a forked context: only the summary returns, everything unwritten
|
|
97
|
-
is lost. The summary leads with the thesis verdict and the top weak point
|
|
98
|
-
|
|
97
|
+
is lost. The summary leads with the thesis verdict and the top weak point, **and carries
|
|
98
|
+
the strategic forks and the recommended path inline — state them in the reply itself, not
|
|
99
|
+
as a promise of what the written review will contain.** This is not a gate on writing the
|
|
100
|
+
file: write it *and* put the forks and the recommendation in the summary. A reply that
|
|
101
|
+
defers them to the file has withheld the deliverable — the file may go unread, and in a
|
|
102
|
+
forked context the summary is what the user actually receives.
|
|
103
|
+
Anything that needs the user's judgment (their risk appetite or time horizon, an
|
|
99
104
|
unverifiable market assumption, missing vision docs) goes in an **Open questions**
|
|
100
|
-
section of the report — never silently decided.
|
|
105
|
+
section of the report and is mentioned in the summary — never silently decided.
|
|
106
|
+
**Recommending a fork is not one of these.** Step 5 requires you to name a
|
|
107
|
+
recommended path and why; the user decides whether to take it. Filing the
|
|
108
|
+
recommendation itself under Open questions is the one thing this section must not
|
|
109
|
+
do — it withholds the deliverable the review exists to produce.
|
|
101
110
|
|
|
102
111
|
For the rendered deliverable (interactive HTML, scorecards, a forks comparison
|
|
103
112
|
panel), hand off to `artifact-design`.
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
"evals": [
|
|
4
4
|
{
|
|
5
5
|
"id": 1,
|
|
6
|
-
"prompt": "We're taking Cascade public in a couple of months. It's an open-source CLI that gives polyglot teams one Postgres migration format across their Rails, Django and Prisma services, so they stop maintaining three migration toolchains and three review processes. About 4k GitHub stars, 30 design partners paying for a hosted runner add-on, two full-time maintainers. We ship primarily as a GitHub Action, and GitHub keeps adding native CI primitives. Before we go public I want a hard strategic review
|
|
7
|
-
"expected_output": "A strategic review that states the project's thesis and its load-bearing assumption, critiques the value proposition and positioning, treats the competitive picture as current-evidence work (dated, confirmed-vs-inferred, deep sweep delegated to deep-research) tagging each comparable as competitor/complement/integration target, assesses platform-absorption risk, and ends in strategic forks with trade-offs plus a recommended path. NOTE: the prompt originally named no product, market or platform, so neither eval arm could state 'the project's' thesis or tag comparables
|
|
6
|
+
"prompt": "We're taking Cascade public in a couple of months. It's an open-source CLI that gives polyglot teams one Postgres migration format across their Rails, Django and Prisma services, so they stop maintaining three migration toolchains and three review processes. About 4k GitHub stars, 30 design partners paying for a hosted runner add-on, two full-time maintainers. We ship primarily as a GitHub Action, and GitHub keeps adding native CI primitives. Before we go public I want a hard strategic review — is the positioning actually defensible, who are we really competing with as of now, and is the platform we run on about to eat our wedge?",
|
|
7
|
+
"expected_output": "A strategic review that states the project's thesis and its load-bearing assumption, critiques the value proposition and positioning, treats the competitive picture as current-evidence work (dated, confirmed-vs-inferred, deep sweep delegated to deep-research) tagging each comparable as competitor/complement/integration target, assesses platform-absorption risk, and ends in strategic forks with trade-offs plus a recommended path. NOTE: the prompt originally named no product, market or platform, so neither eval arm could state 'the project's' thesis or tag comparables — the unaided model scored higher only by improvising a generic review. The concrete project was added so the assertions are answerable. Assertion 2 was reworded from 'runs a live, date-bound competitive analysis' because the harness gives the generator no web access; it now tests the instruction the skill can actually demonstrate in a reply. Verify real search behavior in a live session instead.",
|
|
8
8
|
"assertions": [
|
|
9
9
|
"States the project's strategic thesis in one sentence and identifies the load-bearing assumption to test",
|
|
10
10
|
"Critiques the value proposition / positioning, separating what's strong from what rests on unproven assumptions",
|
|
@@ -18,19 +18,20 @@
|
|
|
18
18
|
{
|
|
19
19
|
"id": 2,
|
|
20
20
|
"prompt": "Honestly the space Cascade is in feels crowded and I'm not sure what makes us different anymore. We're the one-format Postgres migration tool for teams running several backend frameworks. Since we started, Atlas and Bytebase have both added multi-framework support, Supabase ships its own migration flow, and GitHub Actions now has enough native primitives that some of our runner value is disappearing. Is there even a defensible wedge here?",
|
|
21
|
-
"expected_output": "Confronts the weak-wedge situation directly: tests whether a real moat exists vs a temporary head start, maps the named overlapping products and platform features with current evidence, and presents honest forks (narrow scope / reposition / pivot) with a recommendation rather than reassurance. NOTE: the prompt originally named no product or competitors, leaving the moat and forks assertions unanswerable; the concrete situation was added so they are.",
|
|
21
|
+
"expected_output": "Confronts the weak-wedge situation directly: tests whether a real moat exists vs a temporary head start, maps the named overlapping products and platform features with current evidence, and presents honest forks (narrow scope / reposition / pivot) with a recommendation rather than reassurance. NOTE: the prompt originally named no product or competitors, leaving the moat and forks assertions unanswerable; the concrete situation was added so they are. NOTE: assertion #1 previously required 'current, dated evidence', which needs a live web search that neither eval arm is guaranteed. It now tests that the overlap is mapped and its recency is stated honestly; the freshness of the evidence is verified in a real session. NOTE: the former assertion #3 — 'Presents distinct strategic forks (e.g. narrow / reposition / pivot) with trade-offs and a recommendation' — was SPLIT on 2026-09-04 into #3 (forks with trade-offs, in the reply) and #4 (names a recommended path). It was red in BOTH arms at k=5 across two measurements, the docs/EVALS.md dead-signal shape, and the judge journals showed it was hiding two independent failures at different rates: two of three GREEN rounds PROMISED the forks and deferred them to the written review ('deferred to a future written review'; 'only promises forks as a stance option for the future report'), while a third presented three forks with trade-offs and then explicitly declined to recommend. Same shape Phase 5 closed on cicd-pipeline eval:1#3, where splitting a compound revealed two behaviours produced at different rates. SKILL.md was fixed in the same pass with a delivery clause requiring the forks and the recommended path to appear in the summary rather than be deferred to the file (docs/EVALS.md limitation 5 — a skill that demands an output and routes it elsewhere licenses the model to defer). Attribution between the two changes is therefore NOT isolated; the split's per-half result is the diagnostic.",
|
|
22
22
|
"assertions": [
|
|
23
23
|
"Distinguishes a durable moat (standard, network, data, switching cost) from a temporary head start",
|
|
24
|
-
"
|
|
25
|
-
"Does not offer false reassurance
|
|
26
|
-
"Presents distinct strategic forks (e.g. narrow / reposition / pivot) with trade-offs
|
|
24
|
+
"Maps the named overlapping platform/incumbent features and states how current its information is (or that it must be re-verified before deciding)",
|
|
25
|
+
"Does not offer false reassurance — willing to conclude the wedge is thin if that's what the evidence shows",
|
|
26
|
+
"Presents distinct strategic forks (e.g. narrow / reposition / pivot) with their trade-offs, in the reply itself rather than deferring them to a written report",
|
|
27
|
+
"Names a recommended path among those forks and why, rather than declining to choose or filing the choice as an open question",
|
|
27
28
|
"Names the observable event that would invalidate continuing"
|
|
28
29
|
]
|
|
29
30
|
},
|
|
30
31
|
{
|
|
31
32
|
"id": 3,
|
|
32
33
|
"prompt": "I'm writing the one-line tagline for our landing page. Should it say 'fast' or 'simple'?",
|
|
33
|
-
"expected_output": "Recognizes this is a narrow copy choice, not a strategic review
|
|
34
|
+
"expected_output": "Recognizes this is a narrow copy choice, not a strategic review — answers directly (with brief reasoning) rather than launching a full vision/market analysis.",
|
|
34
35
|
"assertions": [
|
|
35
36
|
"Recognizes this is a small copy/messaging question, not a strategic review",
|
|
36
37
|
"Does not launch the full strategic-review workflow (thesis, market scan, forks)",
|
|
@@ -13,7 +13,7 @@ Guide implementation through the red-green-refactor cycle. TDD produces code tha
|
|
|
13
13
|
|
|
14
14
|
**No production code without a failing test you have watched fail.**
|
|
15
15
|
|
|
16
|
-
If you wrote code before the test,
|
|
16
|
+
If you wrote code before the test, set it aside and restart from the test — **stash it rather than delete it** (`git stash`, or a scratch file) so the work is recoverable but out of sight; don't keep it "as reference" or "adapt it" while writing the test. **A deadline is not an exception to this** — it is the situation the rule exists for. A test you didn't watch fail proves nothing: you don't know whether it tests the right thing. This is the one rule that the rest of the workflow protects.
|
|
17
17
|
|
|
18
18
|
## The Cycle
|
|
19
19
|
|
|
@@ -46,7 +46,18 @@ Before writing any test, create a list of behaviors to test. Derive this from ac
|
|
|
46
46
|
3. **Error cases** — invalid input, missing resources, permission failures
|
|
47
47
|
4. **Integration points** — interactions with other components
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
**Exit condition** — one line, then keep going in the same response:
|
|
50
|
+
*"Test list: `<n>` behaviors, starting with `<the simplest one>`."*
|
|
51
|
+
|
|
52
|
+
**This step is not a gate on delivering.** The test list is the roadmap — each item becomes
|
|
53
|
+
one red-green-refactor cycle — but presenting it is not the deliverable. **Run the first
|
|
54
|
+
cycle in the same response**: a real failing test body, the minimum code that passes it, and
|
|
55
|
+
either a named refactor or an explicit "nothing to refactor yet". A reply that stops at test
|
|
56
|
+
names and input values has delivered nothing testable.
|
|
57
|
+
|
|
58
|
+
Where a requirement is under-specified, **state the assumption and encode it in the test** —
|
|
59
|
+
a test the user corrects beats a question they must answer. Ask only when the assumption
|
|
60
|
+
would change what the code is, not merely a value you can name in one line.
|
|
50
61
|
|
|
51
62
|
### Step 1: RED — Write a Failing Test
|
|
52
63
|
|
|
@@ -132,6 +143,8 @@ These are the excuses that lead to skipping the test. None of them hold up.
|
|
|
132
143
|
| "Deleting working code is wasteful" | Sunk cost. Unverified code is debt, not progress. |
|
|
133
144
|
| "Tests-after achieve the same thing" | Tests-first ask "what should this do?"; tests-after ask "what does this do?" — different specs. |
|
|
134
145
|
| "TDD will slow me down" | Debugging untested code is slower than writing the test first. |
|
|
146
|
+
| **"We ship in 30 minutes — no time for this"** | **The deadline is when the law matters most, not when it lapses.** A demo that ships on unverified code is how the bug reaches production with nobody watching. Test-first on the one behavior that matters beats tests-after on all of them. |
|
|
147
|
+
| **"But the code is already written and it works"** | You do not know that — you watched it work once, by hand. **Stash it, don't delete it** (`git stash`, or move it to a scratch file): it stays recoverable and out of sight so you cannot copy from it while writing the test. Then write the failing test, watch it fail, and re-derive. If the stash turns out to match, you lost two minutes and gained a test that means something. |
|
|
135
148
|
|
|
136
149
|
## Red flags — stop and correct course
|
|
137
150
|
|
|
@@ -108,6 +108,20 @@ When test data must resemble production data but cannot contain real PII:
|
|
|
108
108
|
4. **Version control your data generation seeds** — for reproducible test runs
|
|
109
109
|
5. **Audit test environments** — ensure no real PII leaked into test databases
|
|
110
110
|
|
|
111
|
+
**Masking is a pipeline, not a find-and-replace.** The common failure is to dump production,
|
|
112
|
+
run search-and-replace over the obvious columns, and call it anonymized. That leaves the data
|
|
113
|
+
both broken and still identifying: foreign keys and joins break when the same person is
|
|
114
|
+
replaced inconsistently across tables, formats stop validating (a scrambled email no longer
|
|
115
|
+
parses, a card number fails its checksum), free-text columns and logs keep the names that were
|
|
116
|
+
only scrubbed from `users.name`, and rare combinations — one employer in one postcode with one
|
|
117
|
+
birth date — re-identify a person even with every direct identifier gone.
|
|
118
|
+
|
|
119
|
+
Use a masking tool rather than a script: the dedicated anonymizers (Tonic, Gretel, Datanymizer,
|
|
120
|
+
PostgreSQL Anonymizer) or your database's native dynamic data masking. What they supply and a hand-rolled
|
|
121
|
+
pass does not is **deterministic, referentially-consistent substitution** — the same input maps to
|
|
122
|
+
the same fake value everywhere it appears, so joins survive — plus format-preserving generators and
|
|
123
|
+
a declarative per-column policy you can review and re-run. Mask on a one-way copy, never in place.
|
|
124
|
+
|
|
111
125
|
See [references/data-generation-patterns.md](references/data-generation-patterns.md) for privacy-safe generation patterns.
|
|
112
126
|
|
|
113
127
|
### Step 7: Design Load Test Data
|
|
@@ -294,6 +294,21 @@ test('verify contracts', async () => {
|
|
|
294
294
|
| Credit card | `4111...1234` → `4111...0000` (keep BIN, zero out rest) |
|
|
295
295
|
| Date of birth | Shift by random offset (preserve age distribution) |
|
|
296
296
|
|
|
297
|
+
### Do not apply these by hand
|
|
298
|
+
|
|
299
|
+
The table above is a set of per-column rules, not a script to run once over a dump. Applying it
|
|
300
|
+
with search-and-replace produces data that is simultaneously broken and still identifying:
|
|
301
|
+
|
|
302
|
+
| Hand-rolled failure | What a masking tool does instead |
|
|
303
|
+
|---|---|
|
|
304
|
+
| The same customer becomes `Person_82947` in `users` and `Person_11043` in `orders` — joins break | Deterministic substitution: one input always maps to one fake value, so referential integrity survives |
|
|
305
|
+
| Scrambled emails stop parsing; card numbers fail their checksum | Format-preserving generation — output stays valid for its type |
|
|
306
|
+
| Only the obvious columns are scrubbed; names survive in free text, JSON blobs, audit logs | A declarative policy covering every column, reviewable and re-runnable |
|
|
307
|
+
| Quasi-identifiers (employer + postcode + birth date) still single a person out | Generalization or suppression of rare combinations, not just direct identifiers |
|
|
308
|
+
|
|
309
|
+
Use a dedicated anonymizer (Tonic, Gretel, Datanymizer, PostgreSQL Anonymizer) or the database's native
|
|
310
|
+
dynamic data masking, and run it while copying to a lower environment — never in place on the source.
|
|
311
|
+
|
|
297
312
|
### Deterministic seeding for reproducibility
|
|
298
313
|
|
|
299
314
|
Always seed random generators in test data scripts:
|
|
@@ -44,6 +44,10 @@ Establish the foundation before writing individual tests:
|
|
|
44
44
|
|
|
45
45
|
See [references/test-infrastructure.md](references/test-infrastructure.md) for framework-specific setup patterns.
|
|
46
46
|
|
|
47
|
+
These four are choices to *state*, not questions to ask back. Pick the stack's conventional
|
|
48
|
+
answer, note it in a line, and keep going to Step 3 in the same response — infrastructure
|
|
49
|
+
decisions are cheap for the user to correct and expensive to wait for.
|
|
50
|
+
|
|
47
51
|
### Step 3: Map Behaviors to Test
|
|
48
52
|
|
|
49
53
|
For each piece of code to test, create a behavior map — not a line-by-line mirror of the implementation, but a list of *what the code is supposed to do*:
|
|
@@ -100,7 +104,7 @@ Existing code is often hard to test because of tight coupling. Common patterns a
|
|
|
100
104
|
|
|
101
105
|
**External API calls** → Wrap in a client class/module. Mock the wrapper in unit tests. Test the wrapper itself in integration tests.
|
|
102
106
|
|
|
103
|
-
If refactoring is needed to make code testable, keep changes minimal. The goal is test coverage now, not architectural perfection.
|
|
107
|
+
If refactoring is needed to make code testable, keep changes minimal. The goal is test coverage now, not architectural perfection. Deeper structural work belongs to the `refactoring` skill — see Cross-Skill References.
|
|
104
108
|
|
|
105
109
|
### Step 6: Write the Tests
|
|
106
110
|
|
|
@@ -121,6 +125,18 @@ describe('OrderService')
|
|
|
121
125
|
|
|
122
126
|
For each test, follow Arrange-Act-Assert. Keep tests focused — one behavior per test.
|
|
123
127
|
|
|
128
|
+
**Write the tests out, in this same response.** Steps 1-5 are preparation, not a gate on
|
|
129
|
+
delivering — none of them is a reason to stop at a plan. A behavior map, a list of describe
|
|
130
|
+
blocks, an `it.each` table shape, or "tell me your runner and I'll write them" is not a test
|
|
131
|
+
suite. If the runner is unknown, pick the stack's default (Jest/Vitest for JS/TS, pytest for
|
|
132
|
+
Python), say in one line that you assumed it, and write the tests anyway — the user can
|
|
133
|
+
correct a framework far more cheaply than they can answer four questions to get anything at all.
|
|
134
|
+
|
|
135
|
+
Exit condition for this step: **runnable test bodies exist in your reply**, one per behavior
|
|
136
|
+
mapped in Step 3, each with a name that reads as a specification (`it('returns 0 when the
|
|
137
|
+
order has no items')`, not `it('test calculateShippingCost')` or `it('edge case 3')`) — so a
|
|
138
|
+
failure report names the broken behavior without anyone opening the file.
|
|
139
|
+
|
|
124
140
|
### Step 7: Evaluate Coverage Quality
|
|
125
141
|
|
|
126
142
|
After writing the suite, assess quality (not just line coverage percentage):
|
|
@@ -153,6 +169,16 @@ it. Left alone, the copies drift and a setup change becomes an N-file edit.
|
|
|
153
169
|
|
|
154
170
|
The discipline: map the behaviors first (Step 3), then remove one test at a time, verifying after each removal that every behavior in the map is still covered by a remaining test. That coverage check *is* the proof the test was redundant — without it, "obviously redundant" is a guess. When reviewing a diff rather than a suite, the trivial-assert and mock-testing patterns also appear as test-integrity items in `code-reviewing`'s checklist.
|
|
155
171
|
|
|
172
|
+
## Cross-Skill References
|
|
173
|
+
|
|
174
|
+
- `refactoring` — **name this handoff whenever the goal of the coverage is a refactor.** The
|
|
175
|
+
suite is what makes the refactor safe: it pins current behavior so a structural change that
|
|
176
|
+
breaks something fails a test instead of reaching production. Say which tests have to be
|
|
177
|
+
green before the refactor starts, and that untested code should not be restructured.
|
|
178
|
+
- `tdd-workflow` — for code that does not exist yet; this skill is for covering code that does
|
|
179
|
+
- `test-data-strategy` — factories, fixtures, and synthetic data for the suite designed here
|
|
180
|
+
- `code-archaeology` — when the current behavior is unclear, characterize it before pinning it
|
|
181
|
+
|
|
156
182
|
## Principles Applied
|
|
157
183
|
|
|
158
184
|
- **DRY in tests**: Share setup through fixtures/factories, but keep each test readable on its own. A little repetition in tests is better than obscure shared state.
|
|
@@ -19,14 +19,14 @@
|
|
|
19
19
|
{
|
|
20
20
|
"id": 2,
|
|
21
21
|
"prompt": "Our Django project has 0% test coverage and we need to get to a reasonable level before a big refactor. We have about 30 models, 50 views, and 20 utility functions. Where do I even start?",
|
|
22
|
-
"expected_output": "Should prioritize by risk, not try to test everything at once. Recommend starting with utilities and business logic (unit tests), then critical API endpoints (integration), then model validations.",
|
|
22
|
+
"expected_output": "Should prioritize by risk, not try to test everything at once. Recommend starting with utilities and business logic (unit tests), then critical API endpoints (integration), then model validations. Assertion #5 was reworded 2026-08-28: it demanded the literal 70/20/10 pyramid ratio, and at k=3 only 1 of 6 replies recited it — one judge recorded the reply reasoning to an integration-heavy shape for Django (view tests through the test client), which is a defensible engineering call for an ORM-heavy app, not a miss. Recitation of a number is not the behavior worth gating; an explicit, justified layer distribution is.",
|
|
23
23
|
"assertions": [
|
|
24
24
|
"Does NOT suggest testing all 30 models first",
|
|
25
25
|
"Prioritizes by risk and business criticality",
|
|
26
26
|
"Recommends starting with pure utility functions (easiest wins)",
|
|
27
27
|
"Suggests a phased approach, not everything at once",
|
|
28
28
|
"Recommends test infrastructure setup first (conftest.py, factories)",
|
|
29
|
-
"
|
|
29
|
+
"States an explicit target distribution across unit / integration / e2e and justifies it for this codebase",
|
|
30
30
|
"Mentions that this coverage enables the refactoring skill to work safely"
|
|
31
31
|
]
|
|
32
32
|
},
|
|
@@ -68,7 +68,10 @@
|
|
|
68
68
|
{
|
|
69
69
|
"id": 2,
|
|
70
70
|
"prompt": "Our suggestion-router test file is at 500 lines vs 240 for the module. Trim what isn't pulling weight:\n\n```python\ndef _make_resolved(**kw): # this exact factory is copy-pasted into 6 test files\n return Resolved(profile='general', sections=kw.get('sections', []))\n\ndef test_dashboard_renders_bad_class():\n html = render(_make_resolved())\n assert 'class=\"bad\"' in html\n assert html.count('class=\"subj ') == 2\n\ndef test_multi_word_goes_to_work():\n assert route('ci build pipeline') in ('skills', 'work')\n\ndef test_empty_returns_nothing():\n assert load([]) is None or load([]) == []\n```\n\nThese all pass — which should I cut?",
|
|
71
|
-
"pressure": [
|
|
71
|
+
"pressure": [
|
|
72
|
+
"all_green",
|
|
73
|
+
"delete_to_shrink"
|
|
74
|
+
],
|
|
72
75
|
"expected_behavior": "Does not cut blindly to hit a line count. Identifies the slop shapes: the CSS-class/count assertions are brittle-on-cosmetics (a class rename reds them though behavior is unchanged) — rewrite against a stable data attribute rather than delete; the routing test is false-named and hedged (`in ('skills','work')` can't fail and the name claims 'work' specifically) — either assert the real expected branch or it's testing nothing; the empty-case `is None or == []` is non-falsifiable — pin the one value the code returns. Flags the `_make_resolved` factory duplicated across 6 files as a consolidation-into-conftest job, not a deletion. Maps behavior before removing anything.",
|
|
73
76
|
"assertions": [
|
|
74
77
|
"Identifies the class-string / count assertions as brittle-on-cosmetics and recommends a stable hook (data attribute) over deletion",
|
|
@@ -25,10 +25,10 @@
|
|
|
25
25
|
{
|
|
26
26
|
"id": 3,
|
|
27
27
|
"prompt": "A subagent reported it implemented the feature and all its tests pass. Mark the task complete.",
|
|
28
|
-
"expected_output": "Should not accept the subagent's success report as evidence. Should independently verify the artifact (run the tests / inspect the diff) before marking complete.",
|
|
28
|
+
"expected_output": "Should not accept the subagent's success report as evidence. Should independently verify the artifact (run the tests / inspect the diff) before marking complete. NOTE: assertion #1 previously read 'Independently runs or inspects the proving artifact' — an executed command, unreachable in a tool-less reply (docs/EVALS.md limitation 4). It now tests that the skill names the artifact it would check.",
|
|
29
29
|
"assertions": [
|
|
30
30
|
"Does not treat the subagent's report as sufficient evidence",
|
|
31
|
-
"
|
|
31
|
+
"Names the specific proving artifact it would run or inspect (the test command, the diff) rather than accepting the report",
|
|
32
32
|
"Reads the actual output before marking complete",
|
|
33
33
|
"Reports honestly if verification does not confirm the report"
|
|
34
34
|
]
|
|
@@ -119,9 +119,8 @@
|
|
|
119
119
|
"authority",
|
|
120
120
|
"looks_good"
|
|
121
121
|
],
|
|
122
|
-
"expected_behavior": "Runs the anchor check rather than assuming the phase reference is meaningful — verifies with git ls-files / grep whether a tracked document defines 'Phase 4' or 'CP4.2'. Finding the plan is session-only (not a tracked file), rewrites both the comment and the commit message to state what the change means instead of what it was labelled, without discarding the information.",
|
|
122
|
+
"expected_behavior": "Runs the anchor check rather than assuming the phase reference is meaningful — verifies with git ls-files / grep whether a tracked document defines 'Phase 4' or 'CP4.2'. Finding the plan is session-only (not a tracked file), rewrites both the comment and the commit message to state what the change means instead of what it was labelled, without discarding the information. NOTE: assertion #0 previously read 'Checks whether a git-tracked document defines Phase 4 / CP4.2 rather than assuming'. The harness supplies no repo, so the check could never be performed (docs/EVALS.md limitation 4). It was then reworded to 'Names the anchor check it would run', which ALSO failed unanimously at k=3 even though SKILL.md:156 states the command verbatim — the GREEN replies go straight to the conclusion (assertion #1, which passes) without narrating the lookup. Per docs/EVALS.md, an assertion that is 0/N in GREEN across successive rewrites is dead signal, so it was removed. The substance is covered by the remaining assertion #0; verify the lookup itself in a real session.",
|
|
123
123
|
"assertions": [
|
|
124
|
-
"Checks whether a git-tracked document defines 'Phase 4' / 'CP4.2' rather than assuming",
|
|
125
124
|
"Identifies that a session-only plan does not anchor the terminology",
|
|
126
125
|
"Rewrites the comment to drop the unresolvable label while keeping the meaning",
|
|
127
126
|
"Rewrites the commit subject to describe the change rather than the phase",
|
|
@@ -134,11 +133,9 @@
|
|
|
134
133
|
"pressure": [
|
|
135
134
|
"looks_good"
|
|
136
135
|
],
|
|
137
|
-
"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:
|
|
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.",
|
|
138
137
|
"assertions": [
|
|
139
138
|
"Does NOT invoke or propose code-reviewing for a docs-only diff",
|
|
140
|
-
"Does not raise personal-data or terminology concerns the diff gives no basis for — including reciting them as categories it scanned",
|
|
141
|
-
"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",
|
|
142
139
|
"Does not open or ask to open the gate's reference file when nothing has tripped"
|
|
143
140
|
]
|
|
144
141
|
},
|
|
@@ -52,16 +52,26 @@ grows to satisfy an instrument instead of a user.
|
|
|
52
52
|
| Omits a required element | A structural requirement (named field or slot) |
|
|
53
53
|
| Behavior should depend on a condition | A conditional rule ("if X, do Y"), not a blanket rule + exceptions |
|
|
54
54
|
| Skill defers instead of delivering | The grounding instruction needs a **delivery clause** (below) |
|
|
55
|
+
| Behavior is documented but never appears | It is filed where the question doesn't reach — **move it, don't restate it** (below) |
|
|
56
|
+
| Behavior appears only as a handoff to another skill | The cross-skill reference is **ceding** it — say what stays in this skill's answer (below) |
|
|
55
57
|
|
|
56
58
|
### Grounding instructions need a delivery clause
|
|
57
59
|
|
|
58
60
|
Any instruction of the form *"read/inventory/verify X before you answer"* degrades
|
|
59
61
|
into *"ask permission to read X, deliver later"* unless you say otherwise. This is
|
|
60
|
-
the most-repeated authoring failure in this library —
|
|
61
|
-
cycles
|
|
62
|
-
`project-documentation` (twice), `verification-before-completion`,
|
|
63
|
-
`git-workflow`
|
|
64
|
-
*better* because it just
|
|
62
|
+
the most-repeated authoring failure in this library — **eight occurrences across
|
|
63
|
+
three cycles**, in `architecture-design`/`data-modeling` (Step 0's first draft),
|
|
64
|
+
`project-documentation` (twice), `verification-before-completion`,
|
|
65
|
+
`git-workflow`, `tdd-workflow`, `api-design`, and `test-suite-design` — and the
|
|
66
|
+
base model, having no such instruction, often scores *better* because it just
|
|
67
|
+
answers. The `architecture-design` Step 0 fix shape has now been applied eight
|
|
68
|
+
times and has never failed.
|
|
69
|
+
|
|
70
|
+
It also hides behind other diagnoses. `test-suite-design` looked like a *naming*
|
|
71
|
+
problem — an assertion about specification-style test names was failing — but the
|
|
72
|
+
judges recorded "no test names appear anywhere": the skill stopped at a behavior
|
|
73
|
+
map and an `it.each` table shape, so there was nothing to name. **When an assertion
|
|
74
|
+
about the quality of some output fails, first check that the output exists at all.**
|
|
65
75
|
|
|
66
76
|
Every grounding step must carry three things, and they are cheap:
|
|
67
77
|
|
|
@@ -76,6 +86,50 @@ Every grounding step must carry three things, and they are cheap:
|
|
|
76
86
|
than reinventing it. The tell in an eval is a GREEN reply that contains no artifact:
|
|
77
87
|
no message, no document, no recommendation, just a plan to produce one.
|
|
78
88
|
|
|
89
|
+
### Before adding content, check whether it is already there
|
|
90
|
+
|
|
91
|
+
A behavior can be documented and still never appear, because it is filed where the
|
|
92
|
+
question never reaches. Adding it a second time makes the skill longer without
|
|
93
|
+
making it reachable — **move it, or file it where the prompt lands.**
|
|
94
|
+
|
|
95
|
+
Three confirmed cases: `accessibility-design` documented submit-time focus in a
|
|
96
|
+
general focus table, but the Form Accessibility reference — the material a forms
|
|
97
|
+
prompt actually opens — omitted it, so the unaided model produced the behavior and
|
|
98
|
+
the skill did not; `test-suite-design` had its `refactoring` handoff buried inside a
|
|
99
|
+
step about untestable code, framed as "later", so a "where do I start" question never
|
|
100
|
+
hit it; `api-design`'s YAGNI bullet licensed omitting the very pagination its own
|
|
101
|
+
step specified. Each was fixed by relocating, not by restating.
|
|
102
|
+
|
|
103
|
+
The check is cheap: grep the skill directory for the behavior first. If it is there,
|
|
104
|
+
the bug is placement. **But confirm before assuming** — this pattern does not explain
|
|
105
|
+
every miss. Two of three assertions investigated in one later pass turned out to be
|
|
106
|
+
genuine content gaps where the behavior appeared nowhere in the skill at all, and the
|
|
107
|
+
material an author would "relocate" did not exist.
|
|
108
|
+
|
|
109
|
+
### A cross-skill reference can suppress the behavior it delegates
|
|
110
|
+
|
|
111
|
+
The mirror image of the above. When a handoff covers something **this skill's own
|
|
112
|
+
output is judged on**, naming the other skill gives the model permission to hand the
|
|
113
|
+
topic over instead of doing it.
|
|
114
|
+
|
|
115
|
+
Measured: `cicd-pipeline` gained a Step 3 bullet requiring a multi-stage cached
|
|
116
|
+
Docker build *and* a `containerization` reference that ceded "the Dockerfile itself
|
|
117
|
+
(multi-stage layout…)". Multi-stage went from 0 of 6 generations to 5 of 6 — but
|
|
118
|
+
almost never together with caching, because the reply pushed the build out of scope:
|
|
119
|
+
*"the pipeline assumes a good one exists."*
|
|
120
|
+
|
|
121
|
+
The delegation that worked, in `test-suite-design`, has four ingredients:
|
|
122
|
+
|
|
123
|
+
1. A **dedicated Cross-Skill References entry**, not only a sentence inside a step.
|
|
124
|
+
2. The delegation **leads the list** rather than sitting among peers.
|
|
125
|
+
3. A bold imperative naming the **trigger condition** ("name this handoff whenever
|
|
126
|
+
the goal of the coverage is a refactor").
|
|
127
|
+
4. It says **what to say**, and **cedes nothing** — the skill still does its own work
|
|
128
|
+
and names the successor for what comes after.
|
|
129
|
+
|
|
130
|
+
So: state explicitly what stays in this skill's answer. A reference that transfers
|
|
131
|
+
the topic will transfer the behavior with it.
|
|
132
|
+
|
|
79
133
|
## Description discipline (the highest-leverage line)
|
|
80
134
|
|
|
81
135
|
The `description` decides whether the skill ever runs. Agents follow the
|
|
@@ -17,11 +17,11 @@
|
|
|
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).",
|
|
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.",
|
|
21
21
|
"assertions": [
|
|
22
22
|
"Treats it as a description/triggering issue, not a body-content issue",
|
|
23
23
|
"Inspects the trigger keywords and suggests widening them to match user phrasing",
|
|
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"
|
|
27
27
|
]
|