# Cómo escribir criterios de aceptación que un agente de IA pueda verificar

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

Actualizado el 3 de noviembre de 2026.

Los [criterios de aceptación](https://specscore.md/acceptance-criteria-specification) (AC, acceptance criteria) son las condiciones que deben cumplirse para que un cambio cuente como terminado. Given/When/Then es la forma de los pasos en [Gherkin](https://cucumber.io/docs/gherkin/reference/), el lenguaje que [Cucumber](https://cucumber.io/docs/bdd/) usa para el desarrollo guiado por el comportamiento (BDD, behaviour-driven development): Given un estado inicial, When ocurre una acción, Then sigue un resultado observable. Un documento de requisitos de producto (PRD, product requirements document) es el texto que nombra el problema y el producto previsto. El [desarrollo basado en especificaciones](https://specscore.md/es/spec-driven-development/) (SDD, spec-driven development) trata una especificación estructurada, no solo esa prosa, como la fuente contra la que se comprueba la implementación. [EARS](https://alistairmavin.com/ears/) (Easy Approach to Requirements Syntax) es una forma de limitar una frase de requisito para que sus cláusulas queden en un orden fijo. La integración continua (CI, continuous integration) es una comprobación automática en cada cambio propuesto; este sitio describe las dos comprobaciones de SpecScore en la [página de validadores](https://specscore.md/es/validators/). Esta página muestra cómo escribir criterios de aceptación comprobables que un agente de inteligencia artificial (IA) pueda verificar, con ejemplos, y qué comprueba de verdad la interfaz de línea de comandos (CLI, command-line interface) de SpecScore.

## Qué son los criterios de aceptación

Un criterio de aceptación responde a «¿qué debe ser verdad?». Nombra una condición que un revisor, una prueba o un agente puede aceptar o rechazar. No nombra la función que hay que llamar ni el archivo que hay que editar. Esas decisiones pertenecen a la implementación.

Un requisito es la regla. En la [especificación de requisitos](https://github.com/specscore/specscore/blob/main/spec/features/requirement/README.md) de SpecScore, un requisito es un encabezado `#### REQ:` dentro de una funcionalidad: una obligación, con su propio identificador. Un criterio de aceptación agrupa requisitos relacionados en una condición. Un escenario es un caso concreto que muestra que la condición se cumple. La [especificación de criterios de aceptación](https://specscore.md/acceptance-criteria-specification) lo dice así: los criterios responden «¿qué debe ser verdad?» y los escenarios responden «¿cómo lo demostramos?».

Un PRD puede contener la misma intención en párrafos. Los párrafos ayudan a una persona. Un agente todavía tiene que adivinar qué frase es la prueba de aprobado o suspenso. Escribir el criterio como un enunciado propio elimina esa adivinanza.

## Qué hace comprobables los criterios de aceptación

Un agente de programación con IA solo puede seguir un criterio cuando alguien, después, puede señalar una evidencia y decir aprobado o suspenso. Cinco hábitos lo hacen posible. Ninguno es una plantilla de frase. Son comprobaciones que valen para cualquier plantilla, incluido Given/When/Then y una lista de control.

### Observable

El resultado es algo que un tercero puede ver: un mensaje en la página, un registro que se guardó o no, una redirección, un formulario rechazado. «El sistema entiende al comprador» no es observable. «La página muestra Enter a valid email address junto al campo de correo» sí lo es.

### Específico

Nombra al actor, la entrada y el resultado. «La entrada incorrecta se gestiona» no dice qué entrada ni qué gestión. «El comprador envía el correo not-an-email» sí. Específico no significa pegar cada valor de producción. Significa que un lector puede inventar un dato de prueba y saber qué debe ocurrir.

### Un comportamiento

Un criterio, un comportamiento. «El comprador puede iniciar sesión, restablecer una contraseña y ver un mensaje de bloqueo» son tres criterios en una frase. Un agente que implemente el primero y omita el tercero puede decir que la frase está hecha. Sepáralos.

### Aprobado o suspenso

Un criterio de aceptación comprobable tiene dos resultados. «El formulario debería sentirse rápido» tiene una pendiente, no un resultado. Si necesitas un límite, escríbelo: «la página de pago muestra el error sin otra petición al servidor». Si no puedes decir cómo se ve el fallo, la frase todavía no es un criterio.

### Sin palabras vagas

Quita las palabras que esconden el resultado: elegante, intuitivo, robusto, fácil de usar, fluido, rápido, debería y apropiado. Sustituye cada una por la evidencia que aceptarías. «Gestionar los errores con elegancia» pasa a ser «mostrar Enter a valid email address junto al campo y no crear el pedido».

## Given/When/Then y una lista de control

Dos formas cubren la mayoría de los ejemplos de criterios de aceptación que los equipos conservan. Given/When/Then es un escenario. Una lista de control es una lista de resultados. Usa el escenario cuando importa el orden de estado, acción y resultado. Usa la lista cuando enumeras resultados independientes de una sola acción.

La [referencia de Gherkin](https://cucumber.io/docs/gherkin/reference/) de Cucumber da a los pasos las palabras clave Given, When, Then, And y But. La referencia usa el inglés; Gherkin también traduce esas palabras. El texto que sigue a la palabra clave se empareja con código, llamado step definition, cuando Cucumber ejecuta el archivo. SpecScore no usa esa capa. El ejemplo de abajo es Gherkin, para que la forma resulte familiar. No es un archivo de 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
```

### Lista de control

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

Mantén un solo When. Una segunda acción es un segundo escenario. And continúa la misma palabra clave: otro Given u otro Then. No uses And para colar un segundo comportamiento.

Una lista de control es el mismo contrato sin las palabras clave. Cada línea sigue siendo un resultado observable. La lista de arriba es el Then del escenario, escrito como comprobaciones.

## Relación con los requisitos EARS

Los patrones de frase están descritos en [Sintaxis de requisitos EARS explicada, con ejemplos](https://specscore.md/es/articles/ears-requirements/).

La [guía de Alistair Mavin](https://alistairmavin.com/ears/) define EARS (Easy Approach to Requirements Syntax) como un mecanismo para limitar con suavidad los requisitos textuales. Las cláusulas quedan en un orden. La guía da la forma genérica: While <optional pre-condition>, when <optional trigger>, the <system name> shall <system response>. Un requisito tiene cero o más precondiciones, cero o un disparador, un nombre de sistema y una o más respuestas del sistema.

Esa frase es la obligación: la regla que el sistema debe cumplir. Un criterio de aceptación es la condición que debe ser verdad para que la obligación cuente como cumplida. Un escenario Given/When/Then es un caso concreto de esa condición. Puedes escribir el requisito como una frase EARS y dejar el criterio libre de datos de ejemplo.

En una funcionalidad de SpecScore, el requisito puede ser una frase al estilo EARS bajo un encabezado `#### REQ:`. El criterio sigue siendo la condición abstracta. El escenario lleva el ejemplo. EARS no sustituye a ninguno de los dos. Solo limita la frase del requisito.

## Ejemplos de criterios de aceptación: vagos y comprobables

### Nombra la evidencia

**Vago**

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

**Comprobable**

```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.
```

La línea vaga esconde dos exigencias (errores y velocidad) y no da evidencia. La línea comprobable tiene una acción y dos resultados que una persona o un agente pueden comprobar. Los ejemplos se dejan en inglés porque las palabras clave del formato también están en inglés.

### Un comportamiento

**Vago**

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

**Comprobable**

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

Iniciar sesión, restablecer y bloquear son tres comportamientos. La línea comprobable se queda con el inicio de sesión. El restablecimiento y el bloqueo reciben cada uno su criterio, con sus entradas y sus resultados.

### El resultado, no el nombre de la función

**Vago**

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

**Comprobable**

```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.
```

Un nombre de función y un código de estado atan el criterio al código de hoy. El resultado sigue valiendo si la comprobación se mueve a otra función. Conserva el código de estado cuando ese código es el comportamiento prometido, y dilo como resultado observable.

## Cómo los guarda SpecScore y qué comprueba la CI

SpecScore publica el formato en el repositorio [specscore/specscore](https://github.com/specscore/specscore) y la CLI en [specscore/specscore-cli](https://github.com/specscore/specscore-cli). Los dos documentos no describen los criterios de aceptación con exactamente la misma forma. Los dos están vigentes. Esta sección dice cuál es cuál, y después qué rechaza de verdad `specscore spec lint`.

La [especificación de criterios de aceptación](https://specscore.md/acceptance-criteria-specification) — el README de la funcionalidad servido en esa URL — pone los criterios dentro del README de la funcionalidad. Toda funcionalidad tiene una sección `## Acceptance Criteria`. Cada criterio es un encabezado `### AC: {slug}`. El slug va en minúsculas y con guiones. La línea siguiente es `**Requirements:**` y lista los requisitos que agrupa, como `{feature-id}#req:{slug}`. Después va la prosa: la condición compuesta. La especificación dice que esa prosa se queda abstracta. No debe contener pasos Given/When/Then, entradas de ejemplo ni detalle de implementación. Cuando todavía no hay criterios, la sección dice «Not defined yet.» y Open Questions dice «Acceptance criteria not yet defined for this feature.». Los criterios son una agrupación opcional: la especificación dice que se añaden cuando agrupan dos o más requisitos, y que se omiten cuando solo repetirían un requisito.

La prueba concreta es un archivo de escenario en el directorio `_tests/` de la funcionalidad. La [especificación de escenarios](https://github.com/specscore/specscore/blob/main/spec/features/scenario/README.md) exige un título `# Scenario:`, una sección `## Steps`, las palabras `GIVEN`, `WHEN`, `THEN` y `AND` en mayúsculas, y exactamente un WHEN. Una línea opcional `**Validates:**` enlaza el escenario con `{feature-path}#ac:{slug}` o con un requisito. Una sección `## Rehearse` puede llevar un script ejecutable en un bloque `rehearse` que empieza con un shebang.

La CLI también lee archivos de criterio finos, uno por criterio, en `_acs/<slug>.ac.md`. El [ejemplo de inicio de sesión](https://specscore.md/example-login) y la [guía de Rehearse](https://specscore.md/rehearse) documentan esta forma: `# AC: <slug>`, `**Status:**`, `**Verifies:**` y `**Applies-to:**` opcionales, y la condición bajo `## Statement`. `specscore rehearse acs <feature-dir>` imprime una tabla resumen a partir de esos archivos. `specscore rehearse acs --write` sustituye la sección Acceptance Criteria del README por esa tabla y un comentario que dice que la sección se genera y no debe editarse a mano. Un archivo sin encabezado `# AC:` es un error de ese comando.

La CI de este repositorio es el [flujo dogfood](https://github.com/specscore/specscore/blob/main/.github/workflows/dogfood.yml). Instala la CLI v0.39.1 y ejecuta `specscore spec lint` en las pull requests y en los pushes a main. Comprobado el 3 de noviembre de 2026, esa versión y la rama por defecto de la CLI incluyen las reglas de abajo. El linter comprueba la estructura. No califica el inglés.

La regla `ac-heading-format` es un error. En un README de funcionalidad (un archivo cuyo título es `# Feature:`), una línea que parece un encabezado de criterio debe ser exactamente `### AC: <id>` con un espacio después de los dos puntos y un id en kebab-case. También se acepta `### AC: <id> (verifies ...)`. `--fix` solo corrige el espaciado. Un id con mayúsculas o guiones bajos se informa y se deja a una persona. La regla no exige la línea `**Requirements:**`, no exige el marcador «Not defined yet.» y no avisa cuando la prosa contiene Given, When o Then. El escenario de la especificación que pide ese aviso no es una regla de lint en esta CLI.

En un plan que nombra una funcionalidad de origen, el linter lee los encabezados `### AC:` dentro de la sección Acceptance Criteria de esa funcionalidad. La regla `P-002` informa un `**Verifies:**` de tarea que no es `<feature-slug>#ac:<ac-slug>` para uno de esos encabezados. La regla `P-001` informa un encabezado que ninguna tarea cubre y que no está en `## Deferred AC Coverage`. Esas dos reglas no abren `_acs/*.ac.md`. Una tabla generada por `rehearse acs --write` no tiene encabezados `### AC:`, así que las reglas del plan no ven los archivos finos.

El mismo comando de lint no comprueba las palabras clave de los pasos del escenario. `specscore rehearse` ejecuta archivos de escenario: la guía de Rehearse usa un encabezado como `## Given` o `## When` sobre un comando en un bloque, y `**Use:**` para llamar a una comprobación reutilizable. Un archivo con un Given y varios When se ejecuta como casos separados. `specscore rehearse new <feature-slug>#ac:<ac-slug>` lee el README de la funcionalidad y extrae las líneas Given/When/Then de ese criterio hacia `spec/features/<feature-slug>/_tests/<ac-slug>.md`. Nada de eso corre en el flujo dogfood. El flujo ejecuta `specscore spec lint`.

### Criterio en línea, según la especificación de criterios de aceptación

```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.
```

### Archivo de criterio fino, la forma que lee 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.
```

### Archivo de escenario, según la especificación de escenarios

```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
```

### Escenario de Rehearse, la forma de la guía de 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
```
~~~~

Las cuatro muestras ilustran esas formas. No son un árbol de funcionalidad completo, y esta página no afirma que pasen `specscore spec lint` por sí solas. Un README de funcionalidad también necesita sus otras secciones obligatorias para que ese comando quede limpio.

Si quieres una lista de preguntas para sacar el criterio de un pedido vago, usa [Hacer buenas preguntas](https://specscore.md/asking-good-questions). El recorrido del inicio de sesión muestra un criterio fino, `session-hardened`, junto al resto de artefactos.

## Preguntas frecuentes

### ¿Qué son los criterios de aceptación?

Los criterios de aceptación (AC) son las condiciones que deben cumplirse para que un cambio cuente como terminado. En la especificación de criterios de aceptación de SpecScore son abstractos: dicen qué debe ser verdad y dejan los pasos concretos a un escenario.

### ¿Qué es Given/When/Then?

Given/When/Then es la forma de los pasos en Gherkin: Given un estado inicial, When ocurre una acción, Then sigue un resultado observable. Cucumber documenta las palabras clave en la referencia de Gherkin. La especificación de escenarios de SpecScore usa las palabras en mayúsculas GIVEN, WHEN, THEN y AND, con exactamente un WHEN por archivo de escenario.

### ¿Cómo escribo criterios de aceptación para un agente de programación con IA?

Escribe un comportamiento observable, con el actor, la entrada y el resultado, y sin palabras vagas. Pon los datos de ejemplo en un escenario, no en el criterio abstracto. El agente puede implementar contra el criterio y comprobar el escenario.

### ¿Los criterios de aceptación son lo mismo que los casos de prueba?

No. Un criterio enuncia la condición. Un caso de prueba, o un escenario de SpecScore, es una ejecución con entradas concretas que muestra la condición cumplida o fallida. Varios escenarios pueden sostener un criterio.

### ¿specscore spec lint juzga la redacción vaga?

No. En la CLI v0.39.1, la versión que instala la CI de este repositorio, ac-heading-format comprueba el encabezado ### AC:. No puntúa palabras como «graceful» o «fast», y no avisa cuando un criterio contiene Given/When/Then. La redacción es una tarea de escritura. La [página de validadores](https://specscore.md/es/validators/) separa ese lint determinista de la revisión manual con IA.

### ¿Dónde van los pasos Given/When/Then en SpecScore?

En un escenario, no en el criterio de aceptación. La especificación de criterios de aceptación prohíbe pasos Given/When/Then dentro del criterio. La especificación de escenarios los pone en _tests/, bajo ## Steps. Rehearse ejecuta una forma relacionada: encabezados y comandos en bloques bajo _tests/, documentada en la guía de Rehearse. El linter no impone las palabras clave de los pasos.

## Fuentes

Leído el 3 de noviembre de 2026. Las páginas de terceros se citan solo por las definiciones que publican.

- [Cucumber — referencia de Gherkin](https://cucumber.io/docs/gherkin/reference/)
- [Cucumber — desarrollo guiado por el comportamiento](https://cucumber.io/docs/bdd/)
- [Alistair Mavin — EARS](https://alistairmavin.com/ears/)
- [Sintaxis de requisitos EARS explicada, con ejemplos](https://specscore.md/es/articles/ears-requirements/)
- [SpecScore — especificación de criterios de aceptación](https://specscore.md/acceptance-criteria-specification)
- [specscore/specscore — funcionalidad de criterios de aceptación](https://github.com/specscore/specscore/blob/main/spec/features/acceptance-criteria/README.md)
- [specscore/specscore — funcionalidad de escenarios](https://github.com/specscore/specscore/blob/main/spec/features/scenario/README.md)
- [specscore/specscore — funcionalidad de requisitos](https://github.com/specscore/specscore/blob/main/spec/features/requirement/README.md)
- [SpecScore — especificación de funcionalidad](https://specscore.md/feature-specification)
- [SpecScore — Rehearse](https://specscore.md/rehearse)
- [SpecScore — ejemplo de inicio de sesión](https://specscore.md/example-login)
- [SpecScore — Hacer buenas preguntas](https://specscore.md/asking-good-questions)
- [specscore/specscore-cli](https://github.com/specscore/specscore-cli)
- [specscore/specscore](https://github.com/specscore/specscore)
- [Flujo 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 — reglas de plan P-001 y P-002](https://github.com/specscore/specscore-cli/blob/main/pkg/lint/plan_rules.go)

## Relacionado

- [Plantilla de PRD en Markdown para programar con IA](https://specscore.md/es/articles/feature-spec-template/)
- [Lintear especificaciones en CI con un linter de especificaciones](https://specscore.md/es/articles/lint-specs-in-ci/)
- [Sintaxis de requisitos EARS explicada, con ejemplos](https://specscore.md/es/articles/ears-requirements/)
- [Desarrollo basado en especificaciones](https://specscore.md/es/spec-driven-development/)
- [Herramientas de desarrollo basado en especificaciones](https://specscore.md/es/spec-driven-development/tools/)
- [Especificación de criterios de aceptación](https://specscore.md/acceptance-criteria-specification)
- [Hacer buenas preguntas](https://specscore.md/asking-good-questions)
- [Una funcionalidad de inicio de sesión, con ejemplo](https://specscore.md/example-login)
- [Rehearse](https://specscore.md/rehearse)
- [Qué valida SpecScore](https://specscore.md/es/validators/)
- [CLI](https://specscore.md/es/cli/)
