Stories and acceptance criteria
A story is a small, verifiable piece of work with acceptance criteria and a Demonstrate block that shows the outcome.
A story is the piece of work kanman takes on: one issue in your tracker, small enough for one pull request, with acceptance criteria that say exactly when it is done. kanman only picks up stories that are ready, and it proves each finished story against its criteria before anyone reviews the code.
Where stories come from
Stories come from two places:
- Your tracker. An issue in the connected project becomes a story on the team page once it is marked for kanman: it carries the pickup label (
kanmanby default) or is assigned to the account set in the team’s tracker settings. Unmarked issues never appear on the team page. - Intake. Describe a requirement on the team’s Intake page (or click New intake on the team page), or mention kanman in a Slack thread. kanman drafts stories for you to edit, approve or reject. Approved stories are written to your tracker in one batch, with the pickup label.
Triage comes first
Every message kanman receives on intake is classified as exactly one of four kinds:
| Kind | What happens |
|---|---|
| Reply to an open decision | The answer is applied to that decision |
| Status question | kanman answers in the conversation. The answer is never committed to the repository |
| Operational request: pause or resume the team (admins only), cancel a run, expedite or deprioritise a story | kanman carries it out and confirms |
| Work request | kanman drafts stories |
Only work requests become stories, so a question like “what is blocking SBX-12?” never turns into a ticket. If a request is too vague, kanman asks up to three questions first; answer them on the request page and kanman drafts again.
Anatomy of a story
| Part | Description |
|---|---|
| Title and context | What and why, in plain words |
| Acceptance criteria | Numbered criteria in Given / When / Then form |
| Demonstrate block | A concrete, runnable way to show the outcome. Required |
| Test plan | Which tests the change needs, for example “unit: CSV serializer”, “e2e: download flow” |
| Size | S, M or L. L stories should be split before they are written |
| Affected areas | Paths or modules the change will touch, for example src/invoices/** |
| Open questions | Anything still unclear. A story with open questions is not ready |
| Class of service | standard, expedite, fixed_date or maintenance |
Acceptance criteria
Each criterion is written as Given / When / Then and has a stable id (ac-1, ac-2, …) that is never reused within the story:
ac-1 Given a customer with 3 invoices in March
When they export March as CSV
Then the file has 3 rows and the columns date,number,amount
During verification every criterion gets a status: pending, passed, failed or unknown. A passed criterion carries evidence: the file and line that implement it. You see this table in the evidence pack.
The Demonstrate block
The Demonstrate block says how a person would see that the story works. It ends the acceptance criteria and is required for every story. It has a kind, steps and an expected outcome:
| Field | Values |
|---|---|
| Kind | ui, api, cli or config |
| Steps | What to do, in order |
| Expected | What you see when it works |
A good Demonstrate block:
Kind: ui
Steps: open /invoices, pick 2026-03-01 to 2026-03-31, click "Download CSV"
Expected: a CSV downloads with the columns date,number,amount
“Tests pass” is not a Demonstrate block. It names no outcome a person could check. A story without a Demonstrate block shows Add a Demonstrate step on the intake page and cannot be approved.
Readiness
Every story gets a readiness score from 0 to 100, built from five checks:
| Check | Passes when |
|---|---|
| Clear acceptance criteria | There is at least one criterion, and every criterion has a Given, a When and a Then |
| Testable | The story has a test plan and every criterion has an observable Then |
| Small | The size is S or M |
| No open questions | The open questions list is empty |
| Has Demonstrate | The Demonstrate block has steps and an expected outcome |
Each check is worth 20 points. At 100 the story shows Ready for kanman; only such stories can be approved and written to the tracker from intake.
The acceptance spec
If your repository has an acceptance manifest, kanman goes one step further before a story is ready. It writes an executable acceptance spec from the Demonstrate block, on a protected path in your repository (.kanman/acceptance/SBX-12/), and runs it. The story moves to Ready only when the spec runs and currently fails: a spec that already passes does not test the new behaviour. The story page shows the spec state:
| State | Meaning |
|---|---|
missing |
No spec yet. Shown as Spec: not written yet |
authored |
Written, not run yet |
red |
Runs and fails, as expected before the change. Shown as Spec: red (expected) |
green |
Passes, after the change |
invalid |
Rejected, shown as Spec: needs a fix with a reason such as “Spec passes before implementation, it does not test the new behaviour” or “Spec mocks its own target: route interception of /api/invoices” |
The details are in The outcome gate and evidence.
Splitting stories
kanman keeps stories small instead of tracking checklists inside them. When kanman drafts a large requirement, it writes several stories, each with its own criteria and Demonstrate block. A story of size L does not pass the readiness check; split it on the intake page before you approve it.
Coming in a later release
kanman splitting stories on its own as a NOTIFY action, with a one-line note you can undo, arrives in a later release. If you want to approve splits first once it is available, raise split_story to ESCALATE in the policy (see authority levels).
The test plan replaces the old subtask checklist: it lists the concrete checks the change needs, and the run’s evidence pack shows which ones ran.
Classes of service and complexity
Two classifications steer how a story is handled:
- Class of service decides urgency.
expeditework (for example a CI regression, an outage or a security fix) is never stopped by budgets, working hours or the concurrency limit.fixed_date,standardandmaintenancefollow the normal rules. To expedite a story, ask on the team’s intake page, for example “expedite SBX-12”; “deprioritise SBX-12” sets it back to standard. Critical maintenance findings are filed as expedite automatically. - Complexity (
trivial,routineorcomplex) follows from the story size: S is trivial, M routine, L complex. It picks the model tier, the turn budget and how much planning a run does. Complex stories get several scored approaches before the plan. See Runs.
Related
Last updated: January 1, 0001
Open kanman