# Как писать критерии приёмки, которые проверит ИИ-агент

Canonical: https://specscore.md/ru/articles/acceptance-criteria/

Обновлено 3 ноября 2026.

[Критерии приёмки](https://specscore.md/acceptance-criteria-specification) (AC, acceptance criteria) — условия, которые должны быть истинными, прежде чем изменение считается готовым. Given/When/Then — форма шагов в [Gherkin](https://cucumber.io/docs/gherkin/reference/), языке, который [Cucumber](https://cucumber.io/docs/bdd/) использует для разработки через поведение (BDD, behaviour-driven development): Given — исходное состояние, When — происходит одно действие, Then — следует наблюдаемый результат. Документ требований к продукту (PRD, product requirements document) — проза, которая называет проблему и задуманный продукт. [Разработка по спецификациям](https://specscore.md/ru/spec-driven-development/) (SDD, spec-driven development) считает структурированную спецификацию, а не одну только эту прозу, источником, относительно которого проверяется реализация. [EARS](https://alistairmavin.com/ears/) (Easy Approach to Requirements Syntax) — способ так ограничить предложение требования, чтобы его части стояли в фиксированном порядке. Непрерывная интеграция (CI, continuous integration) — автоматическая проверка каждого предложенного изменения; этот сайт описывает две проверки SpecScore на [странице валидаторов](https://specscore.md/ru/validators/). Эта страница показывает, как писать проверяемые критерии приёмки, которые может проверить агент для написания кода на основе искусственного интеллекта (ИИ, artificial intelligence), с примерами критериев приёмки, и что на самом деле проверяет интерфейс командной строки (CLI, command-line interface) SpecScore.

## Что такое критерии приёмки

Критерий приёмки отвечает на вопрос «что должно быть истинным?». Он называет условие, которое рецензент, тест или агент может принять или отклонить. Он не называет функцию, которую нужно вызвать, и не называет файл, который нужно править. Эти решения принадлежат реализации.

Требование — это правило. В [спецификации требований](https://github.com/specscore/specscore/blob/main/spec/features/requirement/README.md) SpecScore требование — это заголовок `#### REQ:` внутри функции: одно обязательство со своим идентификатором. Критерий приёмки собирает связанные требования в одно условие. Сценарий — один конкретный случай, который показывает, что условие выполняется. [Спецификация критериев приёмки](https://specscore.md/acceptance-criteria-specification) говорит так: критерии отвечают на вопрос «что должно быть истинным?», а сценарии — на вопрос «как мы это докажем?».

PRD может содержать то же намерение абзацами. Абзацы помогают человеку. Агенту всё равно приходится угадывать, какое предложение является проверкой «пройдено или нет». Запись критерия отдельным утверждением убирает эту догадку.

## Что делает критерии приёмки проверяемыми

ИИ-агент для написания кода может следовать критерию только тогда, когда позднейший читатель может указать на свидетельство и сказать «пройдено» или «не пройдено». Пять привычек делают это возможным. Ни одна из них не является шаблоном предложения. Это проверки, которые можно применить к любому шаблону, включая Given/When/Then и чеклист.

### Наблюдаемый

Результат — это то, что может увидеть сторонний человек: сообщение на странице, запись, которая была сохранена или не была, перенаправление, отклонённая форма. «Система понимает покупателя» не наблюдаемо. «Страница показывает Enter a valid email address рядом с полем электронной почты» наблюдаемо.

### Конкретный

Назовите действующее лицо, ввод и результат. «Плохой ввод обрабатывается» не говорит, какой ввод и какая обработка. «Покупатель отправляет адрес not-an-email» говорит. Конкретность не значит вставлять каждое производственное значение. Она значит, что читатель может придумать фикстуру и знать, что должно произойти.

### Одно поведение

Один критерий — одно поведение. «Покупатель может войти, сбросить пароль и увидеть сообщение о блокировке» — это три критерия в одном предложении. Агент, который реализует первое и пропускает третье, всё ещё может объявить предложение сделанным. Разделите их.

### Пройдено или нет

У проверяемого критерия приёмки два исхода. «Форма должна ощущаться быстрой» — это наклон, а не результат. Если нужна граница, напишите границу: «страница оформления заказа показывает ошибку без ещё одного запроса к серверу». Если вы не можете сказать, как выглядит неудача, предложение ещё не критерий.

### Без расплывчатых слов

Уберите слова, которые прячут результат: изящный, интуитивный, надёжный, удобный, бесшовный, быстрый, «следует» и уместный. Замените каждое свидетельством, которое вы бы приняли. «Обрабатывать ошибки изящно» становится «показать Enter a valid email address рядом с полем и не оформлять заказ».

## Given/When/Then и чеклист

Две формы покрывают большинство примеров критериев приёмки, которые команды действительно хранят. Given/When/Then — это сценарий. Чеклист — это список результатов. Берите сценарий, когда важен порядок состояния, действия и результата. Берите чеклист, когда перечисляете независимые результаты одного действия.

[Справочник Gherkin](https://cucumber.io/docs/gherkin/reference/) от Cucumber даёт шагам ключевые слова Given, When, Then, And и But. Справочник использует английский; у Gherkin есть и переводы этих слов. Текст после ключевого слова сопоставляется с кодом, который называется step definition, когда Cucumber выполняет файл. SpecScore не использует этот слой step definition. Пример ниже — Gherkin, чтобы форма была знакомой. Это не файл SpecScore.

### Given/When/Then

```gherkin
Scenario: Reject an email that is not a valid address
  Given the shopper is on the checkout form
  When the shopper submits the email "not-an-email"
  Then the page shows "Enter a valid email address" beside the email field
  And the order is not placed
```

### Чеклист

```markdown
- Submitting the email "not-an-email" shows "Enter a valid email address" beside the email field.
- The order is not placed.
```

Оставьте один When. Второе действие — это второй сценарий. And продолжает то же ключевое слово: ещё один Given или ещё один Then. Не используйте And, чтобы протащить второе поведение.

Чеклист — тот же договор без ключевых слов. Каждая строка по-прежнему один наблюдаемый результат. Чеклист выше — это Then сценария, записанный как проверки.

## Как это связано с требованиями EARS

Шаблоны предложений описаны в [Синтаксис требований EARS с объяснением и примерами](https://specscore.md/ru/articles/ears-requirements/).

[Руководство Alistair Mavin](https://alistairmavin.com/ears/) определяет EARS (Easy Approach to Requirements Syntax) как механизм, который мягко ограничивает текстовые требования. Части остаются в одном порядке. Руководство даёт общую форму: While <optional pre-condition>, when <optional trigger>, the <system name> shall <system response>. У требования ноль или больше предусловий, ноль или один триггер, одно имя системы и один или больше ответов системы.

Это предложение — обязательство: правило, которое система должна выполнить. Критерий приёмки — условие, которое должно быть истинным, чтобы обязательство считалось выполненным. Сценарий Given/When/Then — один конкретный случай этого условия. Можно написать требование предложением EARS и всё равно держать критерий свободным от примеров входных данных.

В функции SpecScore требование может быть предложением в стиле EARS под заголовком `#### REQ:`. Критерий остаётся абстрактным условием. Сценарий несёт пример. EARS не заменяет ни то, ни другое. Он только ограничивает предложение требования.

## Примеры критериев приёмки: расплывчатые и проверяемые

### Назвать свидетельство

**Расплывчатый**

```text
The checkout form should handle bad input gracefully and feel fast.
```

**Проверяемый**

```text
When the shopper submits the email "not-an-email", the checkout page shows "Enter a valid email address" beside that field and does not place the order.
```

Расплывчатая строка прячет два требования (ошибки, скорость) и не даёт свидетельства. Проверяемая строка содержит одно действие и два результата, которые человек или агент может проверить. Примеры оставлены на английском, потому что ключевые слова формата английские.

### Одно поведение

**Расплывчатый**

```text
Users can sign in, reset a password, and see an error if the account is locked.
```

**Проверяемый**

```text
When a visitor submits a known email and the matching password, the app sets a session cookie and redirects to /dashboard.
```

Вход, сброс пароля и блокировка — три поведения. Проверяемая строка оставляет вход. Сброс и блокировка получают каждый свой критерий, со своими вводами и результатами.

### Результат, а не имя функции

**Расплывчатый**

```text
The handler returns 400 from validateEmail().
```

**Проверяемый**

```text
When the shopper submits an email that is not a valid address, the checkout page shows "Enter a valid email address" and does not place the order.
```

Имя функции и код состояния привязывают критерий к сегодняшнему коду. Результат остаётся верным, если проверка переедет в другую функцию. Оставляйте коды состояния, когда код состояния и есть обещанное поведение, и называйте его наблюдаемым результатом.

## Как SpecScore их хранит и что проверяет CI

SpecScore публикует формат в репозитории [specscore/specscore](https://github.com/specscore/specscore), а CLI — в [specscore/specscore-cli](https://github.com/specscore/specscore-cli). Эти два документа описывают критерии приёмки не совсем в одной и той же форме. Оба актуальны. Этот раздел говорит, какой документ какой форме соответствует, а затем — что именно отклоняет `specscore spec lint`.

[Спецификация критериев приёмки](https://specscore.md/acceptance-criteria-specification) (README функции по этому URL) помещает критерии прямо в README функции. У каждой функции есть раздел `## Acceptance Criteria`. Каждый критерий — это заголовок `### AC: {slug}`. Slug пишется строчными буквами и через дефис. Следующая строка — `**Requirements:**`, и она перечисляет требования, которые критерий собирает, в виде `{feature-id}#req:{slug}`. Затем идёт проза: составное условие. Спецификация говорит, что эта проза остаётся абстрактной. В ней не должно быть шагов Given/When/Then, примеров входных данных и подробностей реализации. Если критериев ещё нет, раздел читается как «Not defined yet.», а раздел Open Questions говорит «Acceptance criteria not yet defined for this feature.». Критерии — необязательная группировка: спецификация велит добавить критерий, когда он собирает два или более требований, и пропустить его, когда он лишь повторил бы одно требование.

Конкретное доказательство — файл сценария в каталоге `_tests/` этой функции. [Спецификация сценариев](https://github.com/specscore/specscore/blob/main/spec/features/scenario/README.md) требует заголовок `# Scenario:`, раздел `## Steps`, прописные `GIVEN`, `WHEN`, `THEN` и `AND`, и ровно один WHEN. Необязательная строка `**Validates:**` связывает сценарий с `{feature-path}#ac:{slug}` или с требованием. Раздел `## Rehearse` может содержать исполняемый скрипт в блоке `rehearse`, который начинается с shebang.

CLI также читает тонкие файлы критериев, по одному на критерий, по пути `_acs/<slug>.ac.md`. [Пример входа](https://specscore.md/example-login) и [руководство Rehearse](https://specscore.md/rehearse) описывают эту форму: `# AC: <slug>`, необязательные `**Status:**`, `**Verifies:**` и `**Applies-to:**`, и условие под `## Statement`. `specscore rehearse acs <feature-dir>` печатает сводную таблицу по этим файлам. `specscore rehearse acs --write` заменяет раздел Acceptance Criteria в README функции этой таблицей и комментарием о том, что раздел сгенерирован и его не следует править вручную. Файл без заголовка `# AC:` — ошибка этой команды.

CI в этом репозитории — это [воркфлоу dogfood](https://github.com/specscore/specscore/blob/main/.github/workflows/dogfood.yml). Он устанавливает CLI v0.39.1 и запускает `specscore spec lint` для pull request и для push в main. На 3 ноября 2026 года проверено: этот релиз и ветка по умолчанию CLI оба содержат правила ниже. Линтер проверяет структуру. Он не оценивает английский текст.

Правило `ac-heading-format` — это ошибка. В README функции (файле, заголовок которого — `# Feature:`) строка, которая выглядит как заголовок критерия приёмки, должна быть в точности `### AC: <id>`, с одним пробелом после двоеточия и идентификатором в kebab-case. Заголовок вида `### AC: <id> (verifies ...)` тоже принимается. `--fix` исправляет только пробелы. Идентификатор с прописными буквами или подчёркиваниями сообщается и оставляется человеку. Правило не требует строку `**Requirements:**`, не требует заполнитель «Not defined yet.» и не предупреждает, если проза содержит Given, When или Then. Собственный сценарий спецификации для этого предупреждения в этом CLI не является правилом lint.

В плане, который называет исходную функцию, линтер читает заголовки `### AC:` внутри раздела Acceptance Criteria этой функции. Правило `P-002` сообщает значение `**Verifies:**` задачи, которое не равно `<feature-slug>#ac:<ac-slug>` для одного из этих заголовков. Правило `P-001` сообщает заголовок, который не покрывает ни одна задача и который не перечислен в `## Deferred AC Coverage`. Эти два правила не открывают `_acs/*.ac.md`. У сводной таблицы из `rehearse acs --write` нет заголовков `### AC:`, поэтому правила плана не видят тонкие файлы.

Та же команда lint не проверяет ключевые слова шагов сценария. `specscore rehearse` запускает файлы сценариев: руководство Rehearse использует заголовок вроде `## Given` или `## When` над командой в блоке кода и `**Use:**`, чтобы вызвать повторно используемую проверку. Файл с одним Given и несколькими ветками When выполняется как отдельные случаи. `specscore rehearse new <feature-slug>#ac:<ac-slug>` читает README функции и извлекает строки Given/When/Then из этого критерия в `spec/features/<feature-slug>/_tests/<ac-slug>.md`. Ничто из этого не выполняется в воркфлоу dogfood. Воркфлоу запускает `specscore spec lint`.

### Встроенный критерий, из спецификации критериев приёмки

```markdown
## Acceptance Criteria

### AC: invalid-email-rejected

**Requirements:** checkout#req:reject-invalid-email

An email that is not a valid address is rejected, and the order is not placed.
```

### Тонкий файл критерия, форма, которую читает rehearse acs

```markdown
# AC: invalid-email-rejected

**Status:** accepted
**Verifies:** checkout#req:reject-invalid-email

## Statement

An email that is not a valid address is rejected, and the order is not placed.
```

### Файл сценария, из спецификации сценариев

```markdown
# Scenario: Reject an invalid email

**Validates:** [checkout#ac:invalid-email-rejected](../README.md#ac-invalid-email-rejected)

## Steps

GIVEN the shopper is on the checkout form
WHEN the shopper submits the email "not-an-email"
THEN the page shows "Enter a valid email address" beside the email field
AND the order is not placed
```

### Сценарий Rehearse, форма из руководства Rehearse

~~~~markdown
# Rehearse: Reject an invalid email

## Given a submitted email that is not a valid address
```bash
printf 'email=not-an-email\n' > form.txt
```

## When the response is recorded
```bash
printf 'Enter a valid email address\n' > out.txt
```

## Then the message is the invalid-email text
```bash
grep -q 'Enter a valid email address' out.txt
```
~~~~

Четыре образца иллюстрируют эти формы. Они не являются полным деревом функций, и эта страница не утверждает, что они сами по себе проходят `specscore spec lint`. README функции нужны и другие обязательные разделы, прежде чем эта команда завершится чисто.

Если нужен список вопросов, чтобы вытянуть критерий из расплывчатого запроса, возьмите [Как задавать хорошие вопросы](https://specscore.md/asking-good-questions). Разбор входа показывает один тонкий критерий, `session-hardened`, на своём месте среди других артефактов.

## Вопросы и ответы

### Что такое критерии приёмки?

Критерии приёмки (AC) — условия, которые должны быть истинными, прежде чем изменение считается готовым. В спецификации критериев приёмки SpecScore они абстрактны: они говорят, что должно быть истинным, и оставляют конкретные шаги сценарию.

### Что такое Given/When/Then?

Given/When/Then — форма шагов в Gherkin: Given — исходное состояние, When — происходит одно действие, Then — следует наблюдаемый результат. Cucumber документирует ключевые слова в справочнике Gherkin. Спецификация сценариев SpecScore использует прописные ключевые слова GIVEN, WHEN, THEN и AND, с ровно одним WHEN на файл сценария.

### Как писать критерии приёмки для ИИ-агента, который пишет код?

Напишите одно наблюдаемое поведение, с действующим лицом, вводом и результатом, и без расплывчатых слов. Пример данных кладите в сценарий, а не в абстрактный критерий. Тогда агент может реализовывать по критерию и проверять сценарий.

### Критерии приёмки — это то же самое, что тестовые случаи?

Нет. Критерий называет условие. Тестовый случай, или сценарий SpecScore, — это один прогон с конкретными вводами, который показывает, что условие выполняется или не выполняется. Несколько сценариев могут поддерживать один критерий.

### Оценивает ли specscore spec lint расплывчатые формулировки?

Нет. В CLI v0.39.1, релизе, который устанавливает CI этого репозитория, ac-heading-format проверяет заголовок ### AC:. Он не оценивает слова вроде «graceful» или «fast» и не предупреждает, если критерий содержит Given/When/Then. Формулировка — это задача письма. [Страница валидаторов](https://specscore.md/ru/validators/) отделяет этот детерминированный lint от ручной проверки ИИ.

### Куда в SpecScore помещать шаги Given/When/Then?

В сценарий, а не в критерий приёмки. Спецификация критериев приёмки запрещает шаги Given/When/Then внутри критерия. Спецификация сценариев помещает их в _tests/, под ## Steps. Rehearse выполняет родственную форму: заголовки и команды в блоках кода под _tests/, описанную в руководстве Rehearse. Линтер не принуждает к ключевым словам шагов.

## Источники

Прочитано 3 ноября 2026 года. Сторонние страницы цитируются только за определения, которые они публикуют.

- [Cucumber — справочник Gherkin](https://cucumber.io/docs/gherkin/reference/)
- [Cucumber — разработка через поведение](https://cucumber.io/docs/bdd/)
- [Alistair Mavin — EARS](https://alistairmavin.com/ears/)
- [Синтаксис требований EARS с объяснением и примерами](https://specscore.md/ru/articles/ears-requirements/)
- [SpecScore — спецификация критериев приёмки](https://specscore.md/acceptance-criteria-specification)
- [specscore/specscore — функция критериев приёмки](https://github.com/specscore/specscore/blob/main/spec/features/acceptance-criteria/README.md)
- [specscore/specscore — функция сценария](https://github.com/specscore/specscore/blob/main/spec/features/scenario/README.md)
- [specscore/specscore — функция требования](https://github.com/specscore/specscore/blob/main/spec/features/requirement/README.md)
- [SpecScore — спецификация функции](https://specscore.md/feature-specification)
- [SpecScore — Rehearse](https://specscore.md/rehearse)
- [SpecScore — пример входа](https://specscore.md/example-login)
- [SpecScore — Как задавать хорошие вопросы](https://specscore.md/asking-good-questions)
- [specscore/specscore-cli](https://github.com/specscore/specscore-cli)
- [specscore/specscore](https://github.com/specscore/specscore)
- [Воркфлоу dogfood (CLI v0.39.1)](https://github.com/specscore/specscore/blob/main/.github/workflows/dogfood.yml)
- [specscore-cli — ac-heading-format](https://github.com/specscore/specscore-cli/blob/main/pkg/lint/ac_heading.go)
- [specscore-cli — правила плана P-001 и P-002](https://github.com/specscore/specscore-cli/blob/main/pkg/lint/plan_rules.go)

## Связанное

- [Шаблон PRD в Markdown для программирования с ИИ](https://specscore.md/ru/articles/feature-spec-template/)
- [Линтовать спецификации в CI линтером спецификаций](https://specscore.md/ru/articles/lint-specs-in-ci/)
- [Синтаксис требований EARS с объяснением и примерами](https://specscore.md/ru/articles/ears-requirements/)
- [Разработка по спецификациям](https://specscore.md/ru/spec-driven-development/)
- [Инструменты разработки по спецификациям](https://specscore.md/ru/spec-driven-development/tools/)
- [Спецификация критериев приёмки](https://specscore.md/acceptance-criteria-specification)
- [Как задавать хорошие вопросы](https://specscore.md/asking-good-questions)
- [Функция входа на примере](https://specscore.md/example-login)
- [Rehearse](https://specscore.md/rehearse)
- [Что проверяет SpecScore](https://specscore.md/ru/validators/)
- [CLI](https://specscore.md/ru/cli/)
