User Stories skill for Codex
Thin vertical slices a team can finish in a sprint. Codex turns epics and PRDs into backlog-ready user stories with real roles and outcomes, checks each against INVEST, and splits oversized ones by workflow step, rule or data variation rather than by frontend and backend. It orders the backlog around a walking skeleton, leaves estimates to the team, and files issues with gh only after you approve the list.
curl -fsSL codexskills.dev/install.sh \ | sh -s -- user-stories Installs to ~/.agents/skills/user-stories/ for every project on this machine.
curl -fsSL codexskills.dev/cli.mjs -o codex-skills.mjsnode codex-skills.mjs install user-stories 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 user-stories Installs to .agents/skills/user-stories/ in the current repository. Commit it and everyone who runs Codex there gets it.
curl -fsSLO codexskills.dev/downloads/user-stories.zipunzip -o user-stories.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))) user-stories 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 $user-stories, 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, splits and refines agile user stories that pass INVEST - a named user role, a capability and a reason, sized to finish inside one sprint - using vertical slicing patterns (workflow steps, business rule variations, data variations, happy path first, CRUD operations, spikes) instead of splitting by technical layer. Produces backlog-ready stories with acceptance criteria hooks and can file them to GitHub Issues after approval. Use when asked to write user stories, break an epic or PRD into a backlog, split a story that is too big, or review stories before refinement.
Use it when
- An epic or PRD needs to become a refinement-ready backlog
- A story is too big to estimate or finish in one sprint
- Stories keep getting split into frontend and backend halves
- You want to file a batch of stories as GitHub issues
Use something else when
- You only need the Given/When/Then criteria for an existing story: use acceptance-criteria
- You are planning sprint capacity and commitments: use sprint-planning
How to check the result
For every story you can write two acceptance tests and a one-line demo script, and the first few stories together form an end-to-end walking skeleton.
The mistake it prevents
Splitting a story by technical layer, which produces pieces nobody can demo or ship on their own.
A good story is a thin vertical slice of user-visible value that one team can finish, test and demo inside a sprint. Every story names a real role, says why the role wants it, and is small enough that the team agrees on its size within two minutes of discussion.
Format
As a <specific role>,
I want <capability expressed as behaviour>,
so that <outcome the role cares about>.
- Role: a real segment (“workspace admin”, “first-time buyer”), never “the user” or “the system”. If the beneficiary is a developer or operator, say so; technical work that no person benefits from directly is a task, not a story.
- Capability: behaviour, not a UI widget. “Filter invoices by status” not “add dropdown”.
- Reason: the outcome, not a restatement. “so that I can filter invoices” is circular.
INVEST check
| Letter | Test question | Fix when it fails |
|---|---|---|
| Independent | Can it ship without another story in this batch? | Merge dependent pair, or reorder and note the dependency |
| Negotiable | Does it leave room for the team to choose how? | Remove implementation detail from the story text |
| Valuable | Would a user or the business notice it shipped? | Combine with the slice that makes it visible |
| Estimable | Can the team size it now? | Add a time-boxed spike story first |
| Small | Fits in half a sprint or less? | Split (patterns below) |
| Testable | Can you write Given/When/Then for it? | Clarify the outcome, then use $acceptance-criteria |
Splitting patterns
Always split vertically: each piece touches every layer it needs (UI, API, data) and is demoable. Never split into “frontend story” and “backend story”.
Try these in order and stop at the first that yields 2-5 sensible pieces:
| Pattern | Use when | Example for “export reports” |
|---|---|---|
| Workflow steps | Story describes a multi-step process | Choose report; configure columns; download |
| Happy path first | Error and edge handling dominates effort | Export succeeds; then handle >100k rows; then retry on failure |
| Business rule variations | Several rules or policies apply | Export own reports; then team reports with permission check |
| Data variations | Several input types or formats | CSV first; XLSX later; PDF later |
| Interface variations | Several entry points or devices | Web export; then scheduled email export; then API |
| Operations (CRUD) | “Manage X” stories | Create; view; edit; delete |
| Defer performance | Speed is a separate concern | Works for 1k rows; then streams for 1M rows |
| Spike | The team cannot estimate due to unknowns | 1-day spike: can the PDF lib render our charts? |
After splitting, check each piece still has a “so that”. If one piece has no value on its own (e.g. “set up export table”), fold it into the first slice that uses it.
Workflow
- [ ] 1. Read the source (PRD, epic, issue) and AGENTS.md for ticket conventions
- [ ] 2. List roles and the outcomes each needs; ask if a role is unclear
- [ ] 3. Draft one story per outcome; ignore size for now
- [ ] 4. Run INVEST on each; split anything not Small or not Estimable
- [ ] 5. Add 2-6 acceptance criteria per story (or link to them)
- [ ] 6. Order the backlog: walking skeleton first, then by value and risk
- [ ] 7. Present the backlog; file to the tracker only after the user approves
Walking skeleton first
The first story should be the thinnest end-to-end path through the whole feature, even if ugly: it proves the architecture, gives a demo, and de-risks integration. For a “team invites” epic: “As an admin, I want to invite one person by email so that they can join my workspace”, with no roles, no bulk, no resend.
Story card template
### <ID> <short imperative title>
As a <role>, I want <capability>, so that <outcome>.
**Acceptance criteria**
- Given <context>, when <action>, then <observable result>.
- ...
**Notes:** <constraints, links to designs, PRD requirement IDs (R3, R7)>
**Out of scope:** <what the next slice will add>
**Dependencies:** <story IDs or none>
**Estimate:** <points or T-shirt, filled in by the team, not by you>
Never fill in estimates yourself. Effort belongs to the team that will do the work; you may flag stories that look large relative to their siblings.
Filing stories to a tracker
Filing creates shared, visible tickets, so show the full list and get a clear yes first.
With the GitHub CLI (needs network and gh auth):
gh issue create --title "Invite one member by email" \
--body-file /tmp/story-01.md --label "story" --label "epic:invites"
For Jira, Linear or other trackers, produce a CSV or markdown file the user can import, unless an MCP connector or CLI for that tracker is configured in this Codex session.
Reviewing an existing backlog
For each story, report: INVEST failures, missing role or reason, horizontal splits, stories over half a sprint, and duplicates. Then propose the rewritten story, not just the critique.
Red flags to call out:
- “As a developer, I want a database table…” - task, not story; fold into a slice.
- “As a user, I want the system to be fast” - non-functional requirement; becomes an acceptance criterion or a constraint with a threshold.
- Stories that say “and” in the capability usually hide two stories.
- Ten stories with identical “so that” text usually means one story split horizontally.
- A story nobody can demo at sprint review is not done-able.
Gotchas
- Stories are a placeholder for a conversation, not a contract. Keep detail in acceptance criteria and notes, and keep the story sentence short.
- Do not write stories for refactors or upgrades that users never see; track them as
technical tasks with a stated reason (see
$technical-debt-triage). - Splitting by sprint (“part 1”, “part 2”) is not splitting; each part must deliver something usable on its own.
- Bugs are not stories; file them with reproduction steps.
Verification
For each story: read only the card and try to write two acceptance tests and one demo script line (“open X, do Y, see Z”). If either is impossible, the story is not ready. Count the backlog: if the first three stories together do not produce a demoable end-to-end flow, reorder around a walking skeleton.
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: "User Stories"
short_description: "Thin vertical slices a team can finish in a sprint"
default_prompt: "$user-stories Break this invites epic into user stories we can pull into next sprint" 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.