# Acceptance Criteria Authoring

Turns a requirement into criteria that can be checked without argument — including the states a requirement usually forgets.

## Deliverable

One Markdown document, `acceptance-criteria.md`, in the structure set out under **Output** below. It is the input to **Test Case Specification**.

## Required inputs

- **The requirement, as written** — a story, a ticket, a specification paragraph or a written request, in the words of whoever wrote it.
- **A named accepter** — the person whose judgement settles whether a criterion is met. Without one, criteria are suggestions.

If either is absent, stop and report it. Never derive criteria from the implementation: code states what happens, not what was agreed.

## Optional inputs

- The existing behaviour the change sits beside
- The roles and permissions that apply to it
- Data rules: required fields, formats, limits, retention
- Interface designs, the copy, or a walkthrough of the flow
- Regulatory, contractual or accessibility obligations
- Defects raised before in the same area

Every absent optional input narrows what can be asserted, and each gap becomes an entry under **Questions**. A missing rule is never replaced by a sensible default; the default is agreed to in review and disputed after release.

## Execution

**1 — Restate the requirement in one sentence.** Who, what they can do, and what is different afterwards. If it will not fit in one sentence it carries more than one requirement: split it, and write criteria for each part separately.

**2 — List the words that cannot be checked.** Terms such as `quickly`, `valid`, `appropriate`, `as needed`, and any list ending in `etc.`, have no observable meaning. Each one becomes a question naming who can settle it. None of them is settled here by choosing the most likely reading.

**3 — Write the success path.** One criterion per behaviour, in given / when / then form. The `then` states something a person or a calling system can observe — a screen, a record, a response, a message. A `then` saying the system handles it asserts nothing.

**4 — Write the boundaries.** The smallest and largest accepted input, the first value rejected on each side, empty input, maximum length, and the limits of every field. Each boundary is expressed as the rule that governs it and cites the input that supplied that rule; where no input supplied a limit, the boundary becomes a question rather than a figure.

**5 — Write the error paths.** For each way the behaviour can fail: what the user sees, what the system records, and what state the data is left in. A requirement that describes only success has not been specified, it has been imagined.

**6 — Write the states the requirement forgot.** No permission. Not authenticated. No data yet. Partial data. A concurrent change by someone else. An interrupted flow resumed later. Each is either a criterion or an explicit out-of-scope line naming who decided that.

**7 — Check each criterion on its own.** One criterion asserts one thing, can be checked without running another first, and does not need the implementation read to be understood. Merge criteria that only mean something together; split criteria that assert two things; rewrite any criterion whose truth depends on how it was built.

## Output

`acceptance-criteria.md`, in this order:

- **1. Requirement and source** — the requirement verbatim, where it came from, who accepts it, and the date
- **2. Restatement** — the one-sentence form the criteria were written against, and the split if there was one
- **3. Success criteria** — numbered, each in given / when / then form
- **4. Boundary criteria** — per limit: the rule, the first value outside it, and the input that supplied the rule
- **5. Error criteria** — per failure: what the user sees, what is recorded, what state the data is in
- **6. State criteria** — permission, authentication, no data, partial data, concurrency, interruption: each covered or explicitly out of scope
- **7. Out of scope** — what this requirement deliberately does not cover, and who decided
- **8. Questions** — every uncheckable word and every rule no input supplied, with what it blocks and who can settle it

## Validation

The set is ready when all of these hold:

- Every criterion is in given / when / then form and names an observable outcome
- Every criterion can be checked on its own, without another criterion running first
- Sections 4, 5 and 6 are each non-empty, or state that the requirement has no such case and who confirmed that
- No limit, format or threshold appears that an input did not supply
- Every uncheckable word found in section 1 appears in section 8 or has been replaced by a rule
- Section 8 is either non-empty or states explicitly that nothing is outstanding

Fail the run if a criterion still contains a word listed in section 8, or if a value appears that no input supplied.

## Failure handling

- **No requirement supplied** — stop. Report that criteria cannot be written from an implementation, and name what is needed.
- **No accepter named** — produce all eight sections and mark section 1 `UNACCEPTED`. Criteria in that state may not be used to sign work off.
- **The requirement contradicts itself or a supplied rule** — write criteria for neither reading. Record both, name both sources, and raise the contradiction in section 8 as blocking.
- **No access to the existing behaviour** — write criteria for the change alone, and state in section 8 that its interaction with what already exists was not examined and remains unspecified.
- **Partial material** — write every criterion the material supports, mark the rest `INCOMPLETE — pending <question>`, and deliver. A set with named gaps can be reviewed; a set that filled them gets agreed to and then argued about.
