Como escrever critérios de aceitação que um agente de IA possa verificar
Os critérios de aceitação (AC, acceptance criteria) são as condições que devem ser verdadeiras antes de uma mudança contar como concluída. Given/When/Then é a forma dos passos em Gherkin, a linguagem que Cucumber usa para o desenvolvimento guiado por comportamento (BDD, behaviour-driven development): Given um estado inicial, When ocorre uma ação, Then segue um resultado observável. Um documento de requisitos do produto (PRD, product requirements document) é a descrição em prosa que nomeia o problema e o produto pretendido. O desenvolvimento baseado em especificações (SDD, spec-driven development) trata uma especificação estruturada, e não só essa prosa, como a fonte contra a qual a implementação é verificada. EARS (Easy Approach to Requirements Syntax) é um modo de restringir com suavidade uma frase de requisito para que suas cláusulas fiquem numa ordem fixa. A integração contínua (CI, continuous integration) é uma verificação automática em cada mudança proposta; este site descreve as duas verificações do SpecScore na página de validadores. Esta página mostra como escrever critérios de aceitação testáveis que um agente de inteligência artificial (IA, AI, artificial intelligence) possa verificar, com exemplos de critérios de aceitação, e o que a interface de linha de comando (CLI, command-line interface) do SpecScore de fato verifica.
Atualizado em 3 de novembro de 2026.
O que são critérios de aceitação
Um critério de aceitação responde “o que deve ser verdade?”. Ele nomeia uma condição que um revisor, um teste ou um agente pode aceitar ou rejeitar. Não nomeia a função a chamar nem o arquivo a editar. Essas escolhas pertencem à implementação.
Um requisito é a regra. Na especificação de requisitos do SpecScore, um requisito é um cabeçalho #### REQ: dentro de uma funcionalidade: uma obrigação, com o próprio identificador. Um critério de aceitação reúne requisitos relacionados numa condição. Um cenário é um caso concreto que mostra que a condição se mantém. A especificação de critérios de aceitação diz assim: os critérios respondem “o que deve ser verdade?” e os cenários respondem “como provamos isso?”.
Um PRD pode conter a mesma intenção em parágrafos. Parágrafos ajudam uma pessoa. Um agente ainda precisa adivinhar qual frase é o teste de aprovado ou reprovado. Escrever o critério como um enunciado próprio elimina esse palpite.
O que torna os critérios de aceitação testáveis
Um agente de código com IA só consegue seguir um critério quando alguém, depois, pode apontar uma evidência e dizer aprovado ou reprovado. Cinco hábitos tornam isso possível. Nenhum deles é um modelo de frase. São verificações que valem para qualquer modelo, inclusive Given/When/Then e uma lista de verificação.
Observável
O resultado é algo que uma pessoa de fora pode ver: uma mensagem na página, um registro que foi ou não armazenado, um redirecionamento, um formulário rejeitado. “O sistema entende o comprador” não é observável. “A página mostra Enter a valid email address ao lado do campo de e-mail” é.
Específico
Nomeie o ator, a entrada e o resultado. “Entrada ruim é tratada” não diz qual entrada nem qual tratamento. “O comprador envia o e-mail not-an-email” diz. Específico não significa colar cada valor de produção. Significa que um leitor pode inventar um exemplo de teste e saber o que deve acontecer.
Um comportamento
Um critério, um comportamento. “O comprador pode fazer login, redefinir uma senha e ver uma mensagem de bloqueio” são três critérios numa frase. Um agente que implementa o primeiro e pula o terceiro ainda pode dizer que a frase está pronta. Separe-os.
Aprovado ou reprovado
Um critério de aceitação testável tem dois resultados. “O formulário deveria parecer rápido” tem uma inclinação, não um resultado. Se você precisa de um limite, escreva o limite: “a página de checkout mostra o erro sem outra requisição ao servidor”. Se você não consegue dizer como a falha se parece, a frase ainda não é um critério.
Sem palavras vagas
Tire as palavras que escondem o resultado: elegante, intuitivo, robusto, amigável, fluido, rápido, deveria e apropriado. Troque cada uma pela evidência que você aceitaria. “Tratar erros com elegância” passa a “mostrar Enter a valid email address ao lado do campo e não fazer o pedido”.
Given/When/Then e uma lista de verificação
Duas formas cobrem a maioria dos exemplos de critérios de aceitação que as equipes de fato guardam. Given/When/Then é um cenário. Uma lista de verificação é uma lista de resultados. Use o cenário quando a ordem de estado, ação e resultado importa. Use a lista quando você enumera resultados independentes de uma só ação.
A referência de Gherkin do Cucumber dá aos passos as palavras-chave Given, When, Then, And e But. A referência usa inglês; o Gherkin também tem traduções dessas palavras. O texto depois da palavra-chave é associado a código, chamado de step definition, quando o Cucumber executa o arquivo. O SpecScore não usa essa camada de step definition. O exemplo abaixo é Gherkin, mostrado para a forma ficar familiar. Não é um arquivo 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
Lista de verificação
- Submitting the email "not-an-email" shows "Enter a valid email address" beside the email field.
- The order is not placed.
Mantenha um único When. Uma segunda ação é um segundo cenário. And continua a mesma palavra-chave: outro Given ou outro Then. Não use And para introduzir às escondidas um segundo comportamento.
Uma lista de verificação é o mesmo contrato sem as palavras-chave. Cada linha continua sendo um resultado observável. A lista acima é o Then do cenário, escrita como verificações.
O guia de Alistair Mavin define EARS (Easy Approach to Requirements Syntax) como um mecanismo para restringir com suavidade requisitos textuais. As cláusulas ficam numa única ordem. O guia dá a forma genérica: While <optional pre-condition>, when <optional trigger>, the <system name> shall <system response>. Um requisito tem zero ou mais pré-condições, zero ou um gatilho, um nome de sistema e uma ou mais respostas do sistema.
Essa frase é a obrigação: a regra que o sistema deve cumprir. Um critério de aceitação é a condição que deve ser verdadeira para a obrigação contar como cumprida. Um cenário Given/When/Then é um caso concreto dessa condição. Você pode escrever o requisito numa frase EARS e ainda manter o critério livre de entradas de exemplo.
Numa funcionalidade SpecScore, o requisito pode ser uma frase no estilo EARS sob um cabeçalho #### REQ:. O critério continua sendo a condição abstrata. O cenário carrega o exemplo. O EARS não substitui nenhum dos dois. Ele só restringe a frase do requisito.
Exemplos de critérios de aceitação: vagos e testáveis
Nomeie a evidência
Vago
The checkout form should handle bad input gracefully and feel fast.
Testável
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.
A linha vaga tem duas exigências escondidas (erros, velocidade) e nenhuma evidência. A linha testável tem uma ação e dois resultados que uma pessoa ou um agente pode verificar. Os exemplos ficam em inglês porque as palavras-chave do formato são em inglês.
Um comportamento
Vago
Users can sign in, reset a password, and see an error if the account is locked.
Testável
When a visitor submits a known email and the matching password, the app sets a session cookie and redirects to /dashboard.
Login, redefinição e bloqueio são três comportamentos. A linha testável fica com o login. Redefinição e bloqueio recebem cada um o próprio critério, com as próprias entradas e resultados.
O resultado, não o nome da função
Vago
The handler returns 400 from validateEmail().
Testável
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.
Um nome de função e um código de status prendem o critério ao código de hoje. O resultado continua valendo se a verificação mudar para outra função. Mantenha códigos de status quando o código de status é o comportamento que você prometeu, e diga isso como o resultado observável.
Como o SpecScore os guarda e o que a CI verifica
O SpecScore publica o formato no repositório specscore/specscore e a CLI em specscore/specscore-cli. Os dois documentos não descrevem os critérios de aceitação exatamente na mesma forma. Os dois estão vigentes. Esta seção diz qual documento é qual, e depois o que specscore spec lint de fato rejeita.
A especificação de critérios de aceitação — o README da funcionalidade servido nessa URL — coloca os critérios no corpo do README da funcionalidade. Toda funcionalidade tem uma seção ## Acceptance Criteria. Cada critério é um cabeçalho ### AC: {slug}. O slug fica em minúsculas e com hífens. A linha seguinte é **Requirements:** e lista os requisitos que ele reúne, como {feature-id}#req:{slug}. Depois vem a prosa: a condição composta. A especificação diz que essa prosa fica abstrata. Ela não pode conter passos Given/When/Then, entradas de exemplo nem detalhe de implementação. Quando ainda não há critérios, a seção diz “Not defined yet.” e a seção Open Questions diz “Acceptance criteria not yet defined for this feature.”. Os critérios são um agrupamento opcional: a especificação manda acrescentar um quando ele reúne dois ou mais requisitos, e omiti-lo quando ele só repetiria um único requisito.
A prova concreta é um arquivo de cenário no diretório _tests/ da funcionalidade. A especificação de cenários exige um título # Scenario:, uma seção ## Steps, as palavras GIVEN, WHEN, THEN e AND em maiúsculas, e exatamente um WHEN. Uma linha opcional **Validates:** liga o cenário a {feature-path}#ac:{slug} ou a um requisito. Uma seção ## Rehearse pode ter um script executável num bloco rehearse que começa com um shebang.
A CLI também lê arquivos finos de critério, um por critério, em _acs/<slug>.ac.md. O exemplo de login e o guia do Rehearse documentam esta forma: # AC: <slug>, **Status:**, **Verifies:** e **Applies-to:** opcionais, e a condição sob ## Statement. specscore rehearse acs <feature-dir> imprime uma tabela resumo a partir desses arquivos. specscore rehearse acs --write substitui a seção Acceptance Criteria do README da funcionalidade por essa tabela e um comentário de que a seção é gerada e não deve ser editada à mão. Um arquivo sem o cabeçalho # AC: é um erro desse comando.
A CI neste repositório é o fluxo dogfood. Ele instala a CLI v0.39.1 e executa specscore spec lint em pull requests e em pushes para a main. Verificado em 3 de novembro de 2026, esse lançamento e o branch padrão da CLI incluem as regras abaixo. O linter verifica a estrutura. Ele não avalia o inglês.
A regra ac-heading-format é um erro. Num README de funcionalidade (um arquivo cujo título é # Feature:), uma linha que parece um cabeçalho de critério de aceitação tem de ser exatamente ### AC: <id> com um espaço depois dos dois-pontos e um id em kebab-case. Um cabeçalho na forma ### AC: <id> (verifies ...) também é aceito. --fix corrige só o espaçamento. Um id com letras maiúsculas ou sublinhados é reportado e deixado para uma pessoa. A regra não exige a linha **Requirements:**, não exige o marcador “Not defined yet.” e não avisa quando a prosa contém Given, When ou Then. O cenário da própria especificação para esse aviso não é uma regra de lint nesta CLI.
Num plano que nomeia uma funcionalidade de origem, o linter lê os cabeçalhos ### AC: dentro da seção Acceptance Criteria dessa funcionalidade. A regra P-002 reporta um valor **Verifies:** de tarefa que não é <feature-slug>#ac:<ac-slug> para um desses cabeçalhos. A regra P-001 reporta um cabeçalho que nenhuma tarefa cobre e que não está listado sob ## Deferred AC Coverage. Essas duas regras não abrem _acs/*.ac.md. Uma tabela resumo de rehearse acs --write não tem cabeçalhos ### AC:, então as regras do plano não veem os arquivos finos.
O mesmo comando de lint não verifica as palavras-chave dos passos do cenário. specscore rehearse executa arquivos de cenário: o guia do Rehearse usa um cabeçalho como ## Given ou ## When acima de um comando num bloco, e **Use:** para chamar uma verificação reutilizável. Um arquivo com um Given e vários ramos When roda como casos separados. specscore rehearse new <feature-slug>#ac:<ac-slug> lê o README da funcionalidade e extrai as linhas Given/When/Then desse critério para spec/features/<feature-slug>/_tests/<ac-slug>.md. Nada disso roda no fluxo dogfood. O fluxo executa specscore spec lint.
Critério no corpo do texto, segundo a especificação de critérios de aceitação
## 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.
Arquivo fino de critério, a forma que rehearse acs lê
# 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.
Arquivo de cenário, segundo a especificação de cenários
# 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
Cenário do Rehearse, a forma do guia do 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
```
As quatro amostras ilustram essas formas. Elas não são uma árvore de funcionalidade completa, e esta página não afirma que elas passam specscore spec lint sozinhas. Um README de funcionalidade também precisa das outras seções obrigatórias antes de esse comando ficar limpo.
Se você quer uma lista de perguntas para extrair o critério de uma solicitação vaga, use Fazer boas perguntas. O passo a passo de login mostra um critério fino, session-hardened, no lugar, entre os outros artefatos.
Perguntas frequentes
O que são critérios de aceitação?
Critérios de aceitação (AC) são as condições que devem ser verdadeiras antes de uma mudança contar como concluída. Na especificação de critérios de aceitação do SpecScore eles são abstratos: dizem o que deve ser verdade e deixam os passos concretos para um cenário.
O que é Given/When/Then?
Given/When/Then é a forma dos passos em Gherkin: Given um estado inicial, When ocorre uma ação, Then segue um resultado observável. O Cucumber documenta as palavras-chave na referência de Gherkin. A especificação de cenários do SpecScore usa as palavras em maiúsculas GIVEN, WHEN, THEN e AND, com exatamente um WHEN por arquivo de cenário.
Como escrevo critérios de aceitação para um agente de código com IA?
Escreva um comportamento observável, com o ator, a entrada e o resultado, e sem palavras vagas. Coloque dados de exemplo num cenário, não no critério abstrato. O agente pode então implementar contra o critério e verificar o cenário.
Critérios de aceitação são a mesma coisa que casos de teste?
Não. Um critério enuncia a condição. Um caso de teste, ou um cenário do SpecScore, é uma execução com entradas concretas que mostra a condição se mantendo ou falhando. Vários cenários podem sustentar um critério.
specscore spec lint julga redação vaga?
Não. Na CLI v0.39.1, o lançamento que a CI deste repositório instala, ac-heading-format verifica o cabeçalho ### AC:. Ele não pontua palavras como “graceful” ou “fast”, e não avisa quando um critério contém Given/When/Then. A redação é uma tarefa de escrita. A página de validadores separa esse lint determinístico da revisão manual com IA.
Onde ficam os passos Given/When/Then no SpecScore?
Num cenário, não no critério de aceitação. A especificação de critérios de aceitação proíbe passos Given/When/Then dentro do critério. A especificação de cenários os coloca em _tests/, sob ## Steps. O Rehearse executa uma forma relacionada: cabeçalhos e comandos em blocos sob _tests/, documentada no guia do Rehearse. O linter não impõe as palavras-chave dos passos.
Fontes
Lido em 3 de novembro de 2026. Páginas de terceiros são citadas apenas pelas definições que publicam.