Acceptance Criteria skill for Codex
Given/When/Then that testers cannot argue over. Codex writes acceptance criteria with concrete data and one action per scenario, then walks a coverage list of permissions, limits, empty states, failures and concurrency so unhappy paths are settled before coding. Assumptions it had to make are listed for the product owner, and it can emit feature files or pending test stubs that match the test stack already in the repository.
curl -fsSL codexskills.dev/install.sh \ | sh -s -- acceptance-criteria Installs to ~/.agents/skills/acceptance-criteria/ for every project on this machine.
curl -fsSL codexskills.dev/cli.mjs -o codex-skills.mjsnode codex-skills.mjs install acceptance-criteria The CLI also searches, updates and removes skills. Run it with no arguments to pick from a list. Needs Node 20.12+.
curl -fsSL codexskills.dev/install.sh \ | sh -s -- --project acceptance-criteria Installs to .agents/skills/acceptance-criteria/ in the current repository. Commit it and everyone who runs Codex there gets it.
curl -fsSLO codexskills.dev/downloads/acceptance-criteria.zipunzip -o acceptance-criteria.zip -d ~/.agents/skills/ The archive holds the skill folder with its generated agents/openai.yaml. Unzip into .agents/skills/ to scope it to a repo.
& ([scriptblock]::Create((irm codexskills.dev/install.ps1))) acceptance-criteria PowerShell 5.1 or 7. Installs to %USERPROFILE%\.agents\skills\. Add -Project for the current repo.
104-line POSIX script. No sudo, no telemetry. Read install.sh
Use it in Codex
Start a prompt with $acceptance-criteria, or pick it from /skills.
You can also just describe the task: Codex reads the description below and loads the playbook when your request matches.
What Codex reads before loading it
Writes precise Given/When/Then acceptance criteria and rule-based checklists for user stories and requirements - covering happy path, validation, permissions, limits, empty states and failure cases - with concrete example data, and can turn them into Gherkin feature files or test stubs (Cucumber, pytest-bdd, Playwright) that match the repo's test stack. Use when asked to write acceptance criteria, define done for a story, convert requirements to Gherkin scenarios, or find gaps in criteria before development starts.
Use it when
- A story is about to enter a sprint without a clear definition of done
- You want Gherkin scenarios or test stubs derived from requirements
- Criteria exist but only cover the happy path
Use something else when
- The story itself is too big or vague to write criteria for: use user-stories
- You are writing the end-to-end test implementation itself: use playwright-e2e
How to check the result
No two testers could disagree on any criterion's pass or fail result, and every coverage checklist item is either covered or explicitly marked not applicable.
The mistake it prevents
Writing click-by-click UI steps as criteria, which break on every redesign while saying nothing about the rule being tested.
Criteria are done when a developer, a tester and the product owner reading them would all build and check the same behaviour, each criterion passes or fails with no judgement call, and the unhappy paths are written down before code exists.
Choose the format
| Situation | Format |
|---|---|
| Behaviour depends on a starting state and a user action | Given/When/Then scenario |
| Static rules, constraints, or field validation lists | Rule checklist (“Email must …”) |
| Many input/output combinations of one rule | Scenario Outline with an Examples table |
| Non-functional (speed, accessibility, audit) | Rule with a numeric threshold |
Mixing is fine: a story usually has 2-5 scenarios plus a short rule list.
Writing scenarios
Scenario: Admin removes a member who owns projects
Given workspace "Acme" has admin "[email protected]"
And member "[email protected]" owns project "Q3 Launch"
When Dana removes Lee from the workspace
Then Lee can no longer open any "Acme" project
And ownership of "Q3 Launch" transfers to Dana
And Lee receives a removal email within 5 minutes
Rules for each line:
- Given sets state, not actions. Use concrete data (names, amounts, dates), never “some user” or “a valid input”.
- When is exactly one action by one actor. Two Whens means two scenarios.
- Then is observable from outside: what the user sees, receives, or what an API returns. Not “the database row is updated” unless the consumer is another system.
- Declarative, not imperative: “When Dana removes Lee” rather than “When Dana clicks the kebab menu and selects Remove”. UI steps belong in test code, not criteria.
- Every Then is binary. Replace “quickly”, “correctly”, “user-friendly” with numbers or exact messages.
Coverage checklist
Walk this list for every story. Each item is either covered by a criterion or written down as “not applicable because …”.
- Happy path with realistic data
- Validation: required, format, min/max length, duplicates
- Permissions: each role that can and cannot do it; unauthenticated access
- Limits: zero, one, maximum, maximum + 1
- Empty state: nothing exists yet
- Failure: downstream service down, timeout, partial success
- Concurrency: two people edit or act at once
- Undo, cancel, or delete path, and what happens to related data
- Time: time zones, daylight saving, expiry, scheduling boundaries
- Localization: long strings, non-Latin input, currency and date formats
- Accessibility: keyboard path and screen reader announcement for new UI
- Audit or notification side effects
Scenario outlines for rule tables
When one rule has many cases, a table beats ten near-identical scenarios:
Scenario Outline: Discount code validation at checkout
Given a cart totalling <cart_total>
When the shopper applies code "<code>"
Then the order total is <new_total>
And the message reads "<message>"
Examples:
| cart_total | code | new_total | message |
| $80.00 | SAVE10 | $72.00 | SAVE10 applied: 10% off |
| $80.00 | EXPIRED5 | $80.00 | This code expired on 30 Sep 2026 |
| $20.00 | BIG50 | $20.00 | BIG50 needs a cart of $50 or more |
| $80.00 | save10 | $72.00 | SAVE10 applied: 10% off |
The last row encodes a decision (codes are case-insensitive). Surfacing such decisions is the main value of writing criteria early; list each one you had to assume under “Decisions to confirm”.
Workflow
- [ ] 1. Read the story, linked PRD requirement and designs
- [ ] 2. Read AGENTS.md and the test directory to learn the repo's test stack
- [ ] 3. Write the happy-path scenario with concrete data
- [ ] 4. Walk the coverage checklist; add scenarios or rules
- [ ] 5. List assumptions as "Decisions to confirm" for the product owner
- [ ] 6. Optionally generate feature files or test stubs (below)
- [ ] 7. Check each criterion against the verification rules
From criteria to tests
Match the stack already in the repo; do not add a BDD framework the team does not use.
| Repo has | Output |
|---|---|
features/*.feature + Cucumber/Behave/pytest-bdd | Feature file plus pending step definitions |
| Playwright or Cypress, no Gherkin | One test() per scenario, named after it, with Given/When/Then as comments |
| pytest / Jest / Go tests only | Test names from scenarios; bodies skip/todo until implemented |
Playwright stub example:
import { test, expect } from '@playwright/test';
test.describe('Remove workspace member', () => {
test('admin removes a member who owns projects', async ({ page }) => {
// Given: seeded workspace Acme with admin Dana and member Lee owning "Q3 Launch"
// When: Dana removes Lee
// Then: Lee loses access, ownership moves to Dana, email queued
test.fixme(true, 'Pending implementation of story INV-12');
});
});
Installing a new test dependency needs network access in the Codex sandbox; ask first.
Output template
## Acceptance criteria: <story ID and title>
### Scenarios
<Gherkin blocks>
### Rules
- <rule with threshold or exact message>
### Not applicable
- Concurrency: single-user setting, cannot be edited by two people
### Decisions to confirm
1. Discount codes are case-insensitive (assumed yes)
Gotchas
- Criteria that restate the story (“user can export reports”) add nothing; they must describe the observable result with data.
- UI-click steps make criteria brittle; a redesign invalidates them without any change in behaviour.
- “Should” is ambiguous. Write “is”, “shows”, “returns”.
- Criteria are written before development, not reverse-engineered from the finished code; after-the-fact criteria only document what was built, bugs included.
- More than about 8 scenarios usually means the story needs splitting
(
$user-stories).
Verification
For each criterion ask: could two testers disagree on pass or fail? If yes, rewrite. Confirm every coverage checklist item is covered or marked not applicable, and every assumption appears in Decisions to confirm. If stubs were generated, run the test command from AGENTS.md and confirm they are collected and reported as pending, not failing.
What the zip contains
SKILL.md plus the interface file below. Nothing runs on install.
agents/openai.yaml
Gives the Codex app a display name, a one-line description and a starter prompt for this skill.
interface:
display_name: "Acceptance Criteria"
short_description: "Given/When/Then that testers cannot argue over"
default_prompt: "$acceptance-criteria Write acceptance criteria for the remove-member story, including edge cases" About this skill
Written and maintained by the Codex Skills editors to the same editorial standard as every skill here: a selective description, a real workflow, known pitfalls and a way to verify the work. First published , last updated . MIT licensed. Something wrong or out of date? Tell us.