# AIエージェントが検証できる受け入れ基準の書き方

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

2026年11月3日更新。

[受け入れ基準](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/ja/spec-driven-development/)（SDD、spec-driven development）は、あの散文だけを正本とせず、構造化された仕様を、実装を突き合わせる正本として扱います。[EARS](https://alistairmavin.com/ears/)（Easy Approach to Requirements Syntax）は、要求の文を制約し、その節が決まった順序に並ぶようにする書き方です。継続的インテグレーション（CI、continuous integration）は、提案された変更のたびに走る自動検査です。このサイトは SpecScore の二つの検査を [バリデーターのページ](https://specscore.md/ja/validators/) で説明しています。このページでは、人工知能（AI）のコーディングエージェントが検証できる受け入れ基準の書き方と受け入れ基準の例、そして SpecScore のコマンドラインインターフェース（CLI、command-line interface）が実際に検査するものを示します。

## 受け入れ基準とは

受け入れ基準は「何が真でなければならないか」に答えます。レビューア、テスト、またはエージェントが受け入れるか退けるかを決められる条件を名指しします。呼び出す関数や編集するファイルは名指ししません。それらの選択は実装に属します。

要件は規則です。SpecScore の [要件の仕様](https://github.com/specscore/specscore/blob/main/spec/features/requirement/README.md) では、要件は機能の中の `#### REQ:` 見出しです。一つの義務に、独自の識別子が付きます。受け入れ基準は、関連する要件を一つの条件に束ねます。シナリオは、その条件が成り立つことを示す一つの具体例です。[受け入れ基準の仕様](https://specscore.md/acceptance-criteria-specification) はこう述べます。基準は「何が真でなければならないか」に答え、シナリオは「どう証明するか」に答えます。

PRD は同じ意図を段落に含められます。段落は人の助けになります。エージェントは、どの文が合格か不合格かのテストなのかを、なお推測しなければなりません。基準をそれ自身の文として書くと、その推測がなくなります。

## 受け入れ基準を検証可能にするもの

AIコーディングエージェントが基準に従えるのは、あとから読む人が証拠を指して合格か不合格かを言えるときだけです。五つの習慣がそれを可能にします。どれも文のテンプレートではありません。Given/When/Then やチェックリストを含む、どのテンプレートにも当てられる検査です。

### 観測できる

結果は、部外者に見えるものです。ページ上のメッセージ、保存されたかされなかった記録、リダイレクト、拒否されたフォームです。「システムは購入者を理解している」は観測できません。「ページがメール欄の横に Enter a valid email address を表示する」は観測できます。

### 具体的

行為者、入力、結果を名指しします。「不正な入力は処理される」は、どの入力か、どの処理かを言いません。「購入者がメール not-an-email を送信する」は言います。具体的とは、本番の値をすべて貼ることではありません。読む人がテスト用のデータを用意し、何が起きるべきかを知れることです。

### 一つの振る舞い

一つの基準に、一つの振る舞いです。「購入者はサインインし、パスワードを再設定し、ロックアウトのメッセージを見られる」は、一つの文に三つの基準です。最初を実装して三つ目を省いたエージェントでも、その文は完了したと主張できます。分けてください。

### 合格か不合格か

検証できる受け入れ基準には、二つの結果があります。「フォームは速く感じるべきだ」は程度の問題で、結果ではありません。限界が要るなら、限界を書きます。「チェックアウトのページは、サーバーへの追加のリクエストなしにエラーを表示する」。失敗がどう見えるかを言えないなら、その文はまだ基準ではありません。

### 曖昧な語を置かない

結果を隠す語を外します。優雅、直感的、堅牢、使いやすい、継ぎ目がない、速い、すべき、適切。それぞれを、受け入れる証拠に置き換えます。「エラーを優雅に処理する」は「欄の横に Enter a valid email address を表示し、注文を確定しない」になります。

## Given/When/Then とチェックリスト

チームが実際に残している受け入れ基準の例のほとんどは、二つの形で足ります。Given/When/Then はシナリオです。チェックリストは結果の一覧です。状態、操作、結果の順序が重要なときはシナリオを使います。一つの操作から独立した結果を並べるときはチェックリストを使います。

Cucumber の [Gherkin リファレンス](https://cucumber.io/docs/gherkin/reference/) は、ステップに Given、When、Then、And、But というキーワードを与えます。リファレンスは英語です。Gherkin にはそれらのキーワードの翻訳もあります。キーワードのあとの語は、Cucumber がファイルを実行するとき、ステップ定義（step definition）と呼ばれるコードに対応付けられます。SpecScore はそのステップ定義の層を使いません。下の例は 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/ja/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 の機能では、要件を `#### REQ:` 見出しの下の EARS 風の文にできます。基準は抽象的な条件のままです。シナリオが見本を持ちます。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)、つまりその URL で提供される機能の README は、基準を機能の 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` は、機能 README の Acceptance Criteria 節をその表と、節は生成されたもので手で編集しないというコメントに置き換えます。`# AC:` 見出しのないファイルは、そのコマンドのエラーです。

このリポジトリの CI は [dogfood ワークフロー](https://github.com/specscore/specscore/blob/main/.github/workflows/dogfood.yml) です。CLI v0.39.1 を導入し、プルリクエストと main へのプッシュで `specscore spec lint` を実行します。2026年11月3日に確認したところ、そのリリースと CLI のデフォルトブランチの両方に、下の規則が含まれます。リンターが検査するのは構造です。英語の出来は採点しません。

規則 `ac-heading-format` はエラーです。機能の README（タイトルが `# Feature:` であるファイル）で、受け入れ基準の見出しに見える行は、ちょうど `### AC: <id>` でなければなりません。コロンのあとは空白一つ、id は kebab-case です。`### AC: <id> (verifies ...)` の形の見出しも受け付けます。`--fix` が直すのは空白だけです。大文字やアンダースコアを含む id は報告され、人に残されます。この規則は `**Requirements:**` 行を要求せず、「Not defined yet.」というプレースホルダーも要求せず、散文に Given、When、Then が含まれても警告しません。その警告のための仕様自身のシナリオは、この CLI の lint 規則ではありません。

起点の機能を名指しするプランでは、リンターはその機能の Acceptance Criteria 節の中の `### AC:` 見出しを読みます。規則 `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 はちょうど一つです。

### AIコーディングエージェント向けの受け入れ基準はどう書きますか？

観測できる振る舞いを一つ、行為者と入力と結果を添えて、曖昧な語なしで書きます。見本のデータはシナリオに置き、抽象的な基準には置きません。エージェントは基準に対して実装し、シナリオを検査できます。

### 受け入れ基準はテストケースと同じですか？

いいえ。基準は条件を述べます。テストケース、または SpecScore のシナリオは、具体的な入力による一回の実行で、条件が成り立つか失敗するかを示します。複数のシナリオが一つの基準を支えられます。

### specscore spec lint は曖昧な文言を判定しますか？

いいえ。このリポジトリの CI が導入する CLI v0.39.1 では、ac-heading-format が ### AC: 見出しを検査します。「graceful」や「fast」のような語は採点せず、基準に Given/When/Then が含まれても警告しません。文言は書く作業です。[バリデーターのページ](https://specscore.md/ja/validators/) は、その決定的な lint を、手作業の AI レビューから分けています。

### Given/When/Then のステップは SpecScore のどこに置きますか？

シナリオに置き、受け入れ基準の中には置きません。受け入れ基準の仕様は、基準の中の Given/When/Then ステップを禁じています。シナリオの仕様は、それらを _tests/ の ## Steps の下に置きます。Rehearse は関連する形を実行します。_tests/ の下の見出しとフェンスされたコマンドで、Rehearse ガイドに文書化されています。リンターはステップのキーワードを強制しません。

## 出典

2026年11月3日に読みました。第三者のページは、公開している定義についてだけ引用します。

- [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/ja/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)

## 関連

- [AIコーディング向けMarkdownのPRDテンプレート](https://specscore.md/ja/articles/feature-spec-template/)
- [CIで仕様リンターを使って仕様をリントする](https://specscore.md/ja/articles/lint-specs-in-ci/)
- [EARS要件構文を例で説明する](https://specscore.md/ja/articles/ears-requirements/)
- [仕様駆動開発](https://specscore.md/ja/spec-driven-development/)
- [仕様駆動開発ツール](https://specscore.md/ja/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/ja/validators/)
- [CLI](https://specscore.md/ja/cli/)
