Use when reviewing DISTILL artefacts (Gherkin scenarios, test plans, implementation plans) for quality, completeness, and alignment. Contains the gate definitions and scoring rubric for the acceptance-designer-reviewer lenses.
Installs into .claude/skills of the current project.
Are you the author of Acceptance Review Criteria?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/sebastiendegodez-acceptance-review-criteria)
---
name: acceptance-review-criteria
description: Use when reviewing DISTILL artefacts (Gherkin scenarios, test plans, implementation plans) for quality, completeness, and alignment. Contains the gate definitions and scoring rubric for the acceptance-designer-reviewer lenses.
---
# Acceptance Review Criteria
## Overview
Formal gate definitions and verdict rubric for the `acceptance-designer-reviewer`. Applied across 4 lenses (coverage, business-alignment, testability, boundary-enforcement).
---
## Gate Definitions (G1–G11)
### Lens 1: coverage-lens
| Gate | ID | Definition | Pass condition | Fail severity |
|---|---|---|---|---|
| AC–Scenario bijection | G1 | Every AC in `ac-draft-{story}.md` maps to ≥1 scenario. No scenario exists without a traceable AC. | All ACs covered, no orphan scenarios. | BLOCKER |
| Edge case representation | G2 | Boundary conditions and negative cases from the domain examples in the story are represented as scenarios. | ≥1 edge case or boundary condition scenario per business rule. | HIGH |
**Checking G1:**
1. List all ACs from `ac-draft-{story}.md`
2. List all scenarios from `*.feature`
3. Build a trace matrix: AC → scenario(s)
4. Flag any AC with no scenario (missing) and any scenario with no AC (orphan)
---
### Lens 2: business-alignment-lens
| Gate | ID | Definition | Pass condition | Fail severity |
|---|---|---|---|---|
| Business vocabulary | G3 | All nouns, verbs, and adjectives in Given/When/Then steps appear in the domain vocabulary of the stories or the business lexicon. No class names, method names, HTTP verbs, or framework names. | Zero technical identifiers in `.feature` files. | HIGH |
| No technical jargon | G4 | Given/When/Then steps contain zero implementation details: no HTTP status codes, no ORM terms, no database language, no DI container references. | Zero implementation leaks. | BLOCKER |
**G4 red flags (auto-fail):**
- `POST`, `GET`, `HTTP 200`, `HTTP 422`
- `Repository`, `Service`, `Handler`, `Controller`, `UseCase`
- `null`, `true`, `false` as business values (unless they are genuine domain terms)
- SQL, JSON, XML, YAML in scenario text
- Class names (Pascal case identifiers)
---
### Lens 3: testability-lens
| Gate | ID | Definition | Pass condition | Fail severity |
|---|---|---|---|---|
| Step unambiguity | G5 | Every step can be implemented without asking the designer for clarification. The step's meaning is unambiguous within the domain vocabulary. | Every step maps uniquely to a domain action or state. | HIGH |
| Implementation plan completeness | G6 | Every scenario listed in the `.feature` files has a corresponding entry in `impl-plan-{story}.md` with a file path and a use case boundary. | Bijection feature scenarios ↔ impl-plan entries. | HIGH |
| Inner-loop boundary presence | G11 | For every use case named in the coverage matrix that is NEW to this story (not reused from a prior story), the outer acceptance test enters at the Application layer (`<Context>.UnitTest`, per `clean-architecture-testing`) — not solely via an Integration/HTTP test — and an Application/UseCase-level test file for it physically exists in the repo, referenced from `impl-plan-{story}.md`. | Every NEW use case has a real `<Context>.UnitTest` acceptance test file on disk; no NEW use case is covered only by `<Context>.IntegrationTest`. | BLOCKER |
**Checking G5:** For each step, ask "could two engineers implement this differently and both be correct?" If yes, the step is ambiguous.
**Checking G11:**
1. From the boundary-enforcement coverage matrix (G7), list every use case boundary and mark which are NEW to this story vs reused from a prior story/epic.
2. For each NEW use case, search the repo (`search/codebase`) for a test file matching it under `tests/**/*.UnitTest/**`.
3. Missing file, or the only match lives under `tests/**/*.IntegrationTest/**` → BLOCKER: the outer loop skipped the Application-layer inner circle (`outside-in-tdd` Concentric Circle Expansion Phase 1) and jumped straight to the API/Infrastructure circle.
4. A reused use case with no new test file is NOT a violation — G11 only applies to use cases introduced by this story.
---
### Lens 4: boundary-enforcement-lens
| Gate | ID | Definition | Pass condition | Fail severity |
|---|---|---|---|---|
| Layer boundary compliance | G7 | Each row in the coverage matrix targets an Application layer use case named in `contracts-{story}.md`. No scenario targets an Infrastructure adapter directly as its primary entry point. | All coverage matrix entries reference a use case boundary from the contracts. | BLOCKER |
| Walking skeleton coverage | G8 | At least one walking skeleton scenario per major feature flow is identified in the test plan (tagged `@smoke` or marked Walking Skeleton in the matrix). | ≥1 walking skeleton entry per feature flow. | HIGH |
| Visual AC evidence | G9 | Every `@visual` scenario has ≥1 Playwright E2E spec in `tests/e2e/` per `impl-plan-{story}.md`. jsdom/unit entry invalid. | Bijection `@visual` scenarios ↔ Playwright E2E spec entries. | HIGH |
| Comparable contract consistency | G10 | When `impl-plan-{story}.md` plans a component (hook/adapter/client) that is comparable to one already implemented for a similar responsibility in a prior story, its planned state/return/error convention matches the existing component's, unless the plan notes an explicit, justified divergence. | Every comparable pair of planned components shares its convention, or the divergence is explicitly noted and justified in the impl-plan. | HIGH |
**Checking G9:**
1. List all scenarios tagged `@visual` in the `.feature` files
2. List all `tests/e2e/` spec entries in `impl-plan-{story}.md`
3. Verify each `@visual` scenario maps to ≥1 E2E spec performing a real measurement (`boundingBox()`, computed colour/style)
4. Flag any `@visual` scenario whose only planned coverage is a unit/jsdom test
**Checking G10:**
1. List every client-side consumer (hook or client wrapper) named in `impl-plan-{story}.md` and the interface it wraps.
2. Scan sibling `impl-plan-*.md` files (other stories in the same or prior milestones) for a consumer wrapping a comparable interface (same shape class: list query, single-item query, command with optimistic update, ...).
3. When a comparable prior consumer exists, confirm `impl-plan-{story}.md` names it and states either "same convention as `{prior}`" or cites the `contracts-{story}.md` divergence note.
4. No comparable prior consumer in scope → gate is vacuously satisfied (nothing to compare against).
5. A named prior consumer with no convention statement, or a silent state-shape difference undetected by the plan → G10 HIGH fail.
---
## Severity Definitions
| Severity | Definition | Impact |
|---|---|---|
| **BLOCKER** | Fundamental correctness violation. The artefact cannot be used by DELIVER as-is. | Always triggers `rejected` verdict. |
| **HIGH** | Significant quality gap. Increases implementation risk or causes rework in DELIVER. | Triggers `changes_requested` unless no other severity exists. |
| **MEDIUM** | Quality improvement. Can be implemented but suboptimal. | Triggers `changes_requested`. |
| **LOW** | Style or consistency issue. Does not affect DELIVER. | `approved` with recommendation. |
---
## Verdict Derivation
| Condition | Verdict |
|---|---|
| ≥1 BLOCKER in ANY lens | `rejected` |
| ≥1 HIGH, 0 BLOCKER (across ALL lenses) | `changes_requested` |
| MEDIUM only (across ALL lenses) | `changes_requested` |
| LOW only, or all lenses pass | `approved` |
**Confidence:**
- `high` — all artefacts present, clear findings, no ambiguity
- `medium` — some artefacts missing, or findings require interpretation
- `low` — critical artefacts missing, review is incomplete
---
## Dissent Handling
When 3 lenses pass and 1 fails:
1. Document the minority finding explicitly in `dissent`
2. Assess whether the minority finding independently triggers BLOCKER/HIGH severity
3. If BLOCKER/HIGH → **uphold** the minority. Verdict = `changes_requested` or `rejected`.
4. If MEDIUM/LOW → **override** the minority. Verdict = `approved` with recommendation.
5. NEVER silently override. Document the reasoning.
Example dissent entry:
```
dissent: "business-alignment-lens flagged 'driver ID' in step text (G3 HIGH).
Overridden: 'driver ID' is a genuine domain term used consistently in the story
vocabulary. Not a technical identifier. Verdict remains approved."
```
---
## Scoring Rubric (per lens)
| Score | Meaning |
|---|---|
| `pass` | All gates in this lens pass. No findings. |
| `fail` | ≥1 gate in this lens has a finding. |
Each finding includes:
- `gate` — G1 through G11
- `severity` — BLOCKER / HIGH / MEDIUM / LOW
- `finding` — plain-language description of the problem
- `location` — file path and line/scenario reference
- `suggestion` — (optional) how to fix it
---
## References
- [gate-definitions.md](references/gate-definitions.md) — detailed gate checklist with examples
- [verdict-rubric.md](references/verdict-rubric.md) — decision table with example scenarios