인수 기준(AC, acceptance criteria)은 변경이 완료로 치려면 참이어야 하는 조건입니다. Given/When/Then은 Gherkin 안의 단계 형태입니다. 이 언어를 Cucumber는 행위 주도 개발(BDD, behaviour-driven development)에 씁니다. Given은 시작 상태, When은 동작이 하나 일어나는 것, Then은 그에 이어 관찰할 수 있는 결과입니다. 제품 요구사항 문서(PRD, product requirements document)는 문제와 의도한 제품을 이름으로 적는 산문 요약입니다. 스펙 주도 개발(SDD, spec-driven development)은 그 산문만을 정본으로 두지 않고, 구조화된 명세를 구현을 대조하는 정본으로 둡니다. EARS(Easy Approach to Requirements Syntax)는 요구사항 문장을 제약해 절이 고정된 순서로 있게 하는 방법입니다. 지속적 통합(CI, continuous integration)은 제안된 변경마다 도는 자동 검사입니다. 이 사이트는 SpecScore의 두 검사를 검증기 페이지에서 설명합니다. 이 페이지는 인공지능(AI) 코딩 에이전트가 검증할 수 있는 인수 기준을 쓰는 방법과 인수 기준 예시, 그리고 SpecScore 명령줄 인터페이스(CLI, command-line interface)가 실제로 검사하는 것을 보여 줍니다.
2026년 11월 3일 업데이트.
인수 기준이란
인수 기준은 「무엇이 참이어야 하는가」에 답합니다. 리뷰어, 테스트, 또는 에이전트가 받아들이거나 거절할 수 있는 조건을 이름 붙입니다. 호출할 함수나 고칠 파일은 이름 붙이지 않습니다. 그 선택은 구현에 속합니다.
요구사항은 규칙입니다. SpecScore 요구사항 명세에서 요구사항은 기능 안의 #### REQ: 제목입니다. 의무가 하나이고, 식별자가 따로 있습니다. 인수 기준은 관련된 요구사항을 하나의 조건으로 묶습니다. 시나리오는 그 조건이 성립함을 보여 주는 구체적인 사례 하나입니다. 인수 기준 명세는 이렇게 말합니다. 기준은 「무엇이 참이어야 하는가」에 답하고, 시나리오는 「어떻게 증명하는가」에 답합니다.
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 레퍼런스는 단계에 Given, When, Then, And, But이라는 키워드를 줍니다. 레퍼런스는 영어를 씁니다. Gherkin에는 그 키워드의 번역도 있습니다. 키워드 뒤의 말은 Cucumber가 파일을 실행할 때 step definition이라는 코드에 맞춰집니다. SpecScore는 그 step definition 층을 쓰지 않습니다. 아래 예는 Gherkin이며, 형태가 익숙해 보이도록 둔 것입니다. SpecScore 파일이 아닙니다.
Given/When/Then
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
체크리스트
- 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을 확인 항목으로 쓴 것입니다.
Alistair Mavin의 가이드는 EARS(Easy Approach to Requirements Syntax)를, 글로 된 요구사항을 부드럽게 제약하는 장치로 정의합니다. 절은 하나의 순서로 있습니다. 가이드가 주는 일반 형태는 While <optional pre-condition>, when <optional trigger>, the <system name> shall <system response>입니다. 요구사항에는 사전 조건이 0개 이상, 트리거가 0개 또는 1개, 시스템 이름이 하나, 시스템 응답이 하나 이상 있습니다.
그 문장은 의무입니다. 시스템이 지켜야 하는 규칙입니다. 인수 기준은 그 의무가 충족된 것으로 치려면 참이어야 하는 조건입니다. Given/When/Then 시나리오는 그 조건의 구체적인 사례 하나입니다. 요구사항을 EARS 문장으로 쓰고도, 기준에는 예시 입력을 넣지 않은 채로 둘 수 있습니다.
SpecScore 기능에서 요구사항은 #### REQ: 제목 아래의 EARS풍 문장일 수 있습니다. 기준은 추상적인 조건으로 남습니다. 시나리오가 예시를 가집니다. EARS는 둘 중 어느 것도 대체하지 않습니다. 요구사항 문장만 제약합니다.
인수 기준 예시: 모호한 것과 검증 가능한 것
증거를 이름 붙이기
모호함
The checkout form should handle bad input gracefully and feel fast.
검증 가능
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.
모호한 줄에는 숨은 요구가 둘(오류와 속도) 있고 증거는 없습니다. 검증할 수 있는 줄에는 동작이 하나, 사람이나 에이전트가 검사할 수 있는 결과가 둘 있습니다. 예문은 영어로 둡니다. 형식의 키워드가 영어이기 때문입니다.
행위 하나
모호함
Users can sign in, reset a password, and see an error if the account is locked.
검증 가능
When a visitor submits a known email and the matching password, the app sets a session cookie and redirects to /dashboard.
로그인, 재설정, 잠금은 행위가 셋입니다. 검증할 수 있는 줄은 로그인만 남깁니다. 재설정과 잠금은 각각 자신의 입력과 결과를 가진 자신의 기준을 받습니다.
함수 이름이 아닌 결과
모호함
The handler returns 400 from validateEmail().
검증 가능
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 저장소에, CLI를 specscore/specscore-cli에 공개합니다. 두 문서는 인수 기준을 정확히 같은 형태로 서술하지 않습니다. 둘 다 현재의 것입니다. 이 절은 어느 쪽이 어느 쪽인지 말한 다음, specscore spec lint가 실제로 거부하는 것을 말합니다.
그 인수 기준 명세, 곧 그 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/ 디렉터리에 있는 시나리오 파일입니다. 시나리오 명세는 # Scenario: 제목, ## Steps 절, 대문자 GIVEN, WHEN, THEN, AND, 그리고 WHEN이 정확히 하나를 요구합니다. 선택인 **Validates:** 줄은 시나리오를 {feature-path}#ac:{slug} 또는 요구사항에 연결합니다. ## Rehearse 절은 rehearse 펜스 안에 shebang으로 시작하는 실행 가능한 스크립트를 둘 수 있습니다.
CLI는 기준마다 하나인 얇은 기준 파일도 _acs/<slug>.ac.md에서 읽습니다. 로그인 예와 Rehearse 가이드가 이 형태를 문서화합니다. # AC: <slug>, 선택인 **Status:**, **Verifies:**, **Applies-to:**(이 셋은 모두 선택), 그리고 ## Statement 아래의 조건입니다. specscore rehearse acs <feature-dir>는 그 파일들에서 요약 표를 출력합니다. specscore rehearse acs --write는 기능 README의 Acceptance Criteria 절을 그 표와, 절이 생성되었으며 손으로 고치지 말라는 주석으로 바꿉니다. # AC: 제목이 없는 파일은 그 명령의 오류입니다.
이 저장소의 CI는 dogfood 워크플로입니다. 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입니다.
인라인 기준, 인수 기준 명세에서
## 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가 읽는 형태
# 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.
시나리오 파일, 시나리오 명세에서
# 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 가이드에 있는 형태
# 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는 그 명령이 깨끗해지려면 다른 필수 절도 필요합니다.
모호한 요청에서 기준을 끌어낼 질문 목록이 필요하면 좋은 질문 하기를 쓰세요. 로그인 둘러보기는 얇은 기준 하나, 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이 있어도 경고하지 않습니다. 문장은 쓰는 일입니다. 검증기 페이지는 그 결정적인 lint를 수동 AI 검토와 나눕니다.
Given/When/Then 단계는 SpecScore에서 어디에 둡니까?
시나리오에 두고, 인수 기준 안에는 두지 않습니다. 인수 기준 명세는 기준 안의 Given/When/Then 단계를 금합니다. 시나리오 명세는 그것을 _tests/ 아래 ## Steps에 둡니다. Rehearse는 관련된 형태를 실행합니다. _tests/ 아래의 제목과 펜스로 감싼 명령이며, Rehearse 가이드에 문서화되어 있습니다. 린터는 단계 키워드를 강제하지 않습니다.
출처
2026년 11월 3일에 읽었습니다. 제3자 페이지는 그곳에 공개된 정의에 대해서만 인용합니다.