Generate validation-criteria.json
You are producing the acceptance oracle for the VALIDATION phase: a machine-readable list of
testable criteria derived from the requirement. Every downstream check (generated e2e tests, the
human sign-off checklist) is derived from this file, so faithfulness to the
requirement matters more than volume — a wrong or invented criterion silently corrupts every
downstream check.
This skill runs standalone (a turn asking only for criteria) or as the final step of a
design-generation turn — in both cases the requirement-only input rule below stands unchanged.
Input — the requirement ONLY
Read specs/requirements/prd.md — the numbered User Stories are the spine,
with specs/requirements/features/<slug>.md for depth. Do not read
the design bundle (design.cell, domain-model.md, flows/), openapi.yaml, or
any source code to derive criteria — the
oracle must be independent of the work it will grade. Base every criterion
only on what the PRD says or necessarily implies, and cite each requirement's
story numbers so coverage is checkable: every story the PRD defines
appears in some entry's stories.
Output — write exactly one file
Create specs/validation/validation-criteria.json (use addFile; if it already exists, replace its
contents). The file MUST be valid JSON conforming exactly to the schema below — no comments, no
trailing prose, no Markdown fences. Keep field order stable.
Regeneration — keep ids stable. When the file already exists in your workspace, keep each unchanged
criterion's id the same as in the existing file. Committed e2e specs are keyed by criterion id
(tests/e2e/specs/<AC-ID>.spec.ts), so renumbering an unchanged criterion would orphan its spec. Assign
a fresh id only to a genuinely new or reworded criterion.
{
"requirements": [
{
"id": "REQ-001",
"statement": "Users can reset their password via email",
"stories": [3, 8],
"criteria": [
{ "id": "AC-001-a", "must": "A registered email receives a reset link", "method": "e2e" },
{ "id": "AC-001-b", "must": "The reset link expires after 1 hour", "method": "e2e" },
{ "id": "AC-001-c", "must": "The reset confirmation message is clear and actionable", "method": "manual" }
]
}
]
}
Field rules
| Field |
Rule |
requirements[] |
One entry per distinct requirement parsed from the prose. |
requirements[].id |
REQ-NNN, assigned sequentially (REQ-001, REQ-002, …). |
requirements[].statement |
The requirement restated as one clear sentence. |
requirements[].stories |
The PRD story numbers this requirement traces to — every entry cites at least one; a story number that appears in no entry means the oracle misses that story. |
criteria[] |
The testable acceptance criteria for that requirement. ≥ 1 per requirement. |
criteria[].id |
AC-<req-number>-<letter>, e.g. AC-001-a, AC-001-b. |
criteria[].must |
A single, atomic, verifiable assertion. No conjunctions — split "X and Y" into two criteria. |
criteria[].method |
Exactly one of e2e | manual (see below). |
Assigning method
e2e — deterministically checkable by driving the app: a UI flow via a headless browser, or a
deterministic API/CLI assertion for non-UI behavior. Prefer this whenever a stable pass/fail assertion
is possible.
manual — everything that cannot be checked by a deterministic e2e assertion: needs human
judgment, exploratory interaction, or subjective evaluation (e.g. "the error message is clear and
actionable", "the layout is usable on mobile"), or has external/physical/third-party side effects
beyond an agent's reach.
When unsure, choose e2e if you can phrase a concrete deterministic assertion; otherwise manual.
Every criterion gets exactly one method.
Discipline
- Faithful, not inventive. Every criterion must trace to something the requirement actually says or
necessarily implies. Do NOT invent scope, endpoints, or features.
- Atomic. One independently checkable fact per criterion. Split compound requirements.
- Deterministic. The same requirement should yield substantially the same criteria each run.
- Report ambiguity, don't fabricate. If the requirement is ambiguous or missing acceptance detail,
do NOT guess a criterion to fill the gap. Instead, list the ambiguities and any assumptions you made
in your reply to the user — keep them OUT of the JSON file (the file stays exactly on-schema).
Do not
- Do not add fields beyond the schema, comments, or any prose inside the JSON.
- Do not read the design bundle (design.cell, domain-model.md, flows/),
openapi.yaml, or source code to derive criteria (requirement-only input).
- Do not generate e2e test files, a validation workflow, or anything else — this skill produces the
single
specs/validation/validation-criteria.json file, whether it runs standalone or as the final
step of a design turn.
1---2name: validation-criteria3description: Use when generating the validation criteria — write specs/validation/validation-criteria.json, the machine-readable acceptance oracle for the VALIDATION phase, from the requirement prose alone.4---56# Generate `validation-criteria.json`78You are producing the **acceptance oracle** for the VALIDATION phase: a machine-readable list of9testable criteria derived from the requirement. Every downstream check (generated e2e tests, the10human sign-off checklist) is derived from this file, so **faithfulness to the11requirement matters more than volume** — a wrong or invented criterion silently corrupts every12downstream check.1314This skill runs standalone (a turn asking only for criteria) or as the **final step of a15design-generation turn** — in both cases the requirement-only input rule below stands unchanged.1617## Input — the requirement ONLY1819Read `specs/requirements/prd.md` — the numbered User Stories are the spine,20with `specs/requirements/features/<slug>.md` for depth. **Do not read21the design bundle (design.cell, domain-model.md, flows/), `openapi.yaml`, or22any source code** to derive criteria — the23oracle must be independent of the work it will grade. Base every criterion24only on what the PRD says or necessarily implies, and cite each requirement's25story numbers so coverage is checkable: every story the PRD defines26appears in some entry's `stories`.2728## Output — write exactly one file2930Create `specs/validation/validation-criteria.json` (use `addFile`; if it already exists, replace its31contents). The file MUST be valid JSON conforming **exactly** to the schema below — no comments, no32trailing prose, no Markdown fences. Keep field order stable.3334**Regeneration — keep ids stable.** When the file already exists in your workspace, keep each unchanged35criterion's `id` the same as in the existing file. Committed e2e specs are keyed by criterion id36(`tests/e2e/specs/<AC-ID>.spec.ts`), so renumbering an unchanged criterion would orphan its spec. Assign37a fresh id only to a genuinely new or reworded criterion.3839```json40{41 "requirements": [42 {43 "id": "REQ-001",44 "statement": "Users can reset their password via email",45 "stories": [3, 8],46 "criteria": [47 { "id": "AC-001-a", "must": "A registered email receives a reset link", "method": "e2e" },48 { "id": "AC-001-b", "must": "The reset link expires after 1 hour", "method": "e2e" },49 { "id": "AC-001-c", "must": "The reset confirmation message is clear and actionable", "method": "manual" }50 ]51 }52 ]53}54```5556### Field rules5758| Field | Rule |59|---|---|60| `requirements[]` | One entry per distinct requirement parsed from the prose. |61| `requirements[].id` | `REQ-NNN`, assigned sequentially (`REQ-001`, `REQ-002`, …). |62| `requirements[].statement` | The requirement restated as one clear sentence. |63| `requirements[].stories` | The PRD story numbers this requirement traces to — every entry cites at least one; a story number that appears in no entry means the oracle misses that story. |64| `criteria[]` | The testable acceptance criteria for that requirement. **≥ 1 per requirement.** |65| `criteria[].id` | `AC-<req-number>-<letter>`, e.g. `AC-001-a`, `AC-001-b`. |66| `criteria[].must` | A single, **atomic**, verifiable assertion. No conjunctions — split "X and Y" into two criteria. |67| `criteria[].method` | Exactly one of `e2e` \| `manual` (see below). |6869## Assigning `method`7071- **`e2e`** — deterministically checkable by driving the app: a UI flow via a headless browser, or a72 deterministic API/CLI assertion for non-UI behavior. Prefer this whenever a stable pass/fail assertion73 is possible.74- **`manual`** — everything that cannot be checked by a deterministic e2e assertion: needs human75 judgment, exploratory interaction, or subjective evaluation (e.g. "the error message is clear and76 actionable", "the layout is usable on mobile"), or has external/physical/third-party side effects77 beyond an agent's reach.7879When unsure, choose `e2e` if you can phrase a concrete deterministic assertion; otherwise `manual`.80Every criterion gets exactly one method.8182## Discipline8384- **Faithful, not inventive.** Every criterion must trace to something the requirement actually says or85 necessarily implies. Do NOT invent scope, endpoints, or features.86- **Atomic.** One independently checkable fact per criterion. Split compound requirements.87- **Deterministic.** The same requirement should yield substantially the same criteria each run.88- **Report ambiguity, don't fabricate.** If the requirement is ambiguous or missing acceptance detail,89 do NOT guess a criterion to fill the gap. Instead, **list the ambiguities and any assumptions you made90 in your reply to the user** — keep them OUT of the JSON file (the file stays exactly on-schema).9192## Do not9394- Do not add fields beyond the schema, comments, or any prose inside the JSON.95- Do not read the design bundle (design.cell, domain-model.md, flows/), `openapi.yaml`, or source code to derive criteria (requirement-only input).96- Do not generate e2e test files, a validation workflow, or anything else — this skill produces the97 single `specs/validation/validation-criteria.json` file, whether it runs standalone or as the final98 step of a design turn.