# Documentación obsoleta de API: prueba las acciones de los agentes de forma segura

La documentación obsoleta de una API es un problema de seguridad para los agentes, no una simple molestia editorial. Una persona puede leer un ejemplo antiguo, dudar y preguntar a un compañero. Un agente autónomo de programación suele convertir ese mismo ejemplo en una solicitud y usar la respuesta como prueba de que actuó correctamente.

Esa diferencia cambia el criterio. Si tu documentación enseña a un agente a invocar una API, rotar un token, eliminar un registro o acceder a un host de producción, trata el texto como una entrada ejecutable. Pruébalo junto con la propia herramienta. Una página que era correcta al publicarse, pero que ya no coincide con el servicio activo, puede llevar a un agente a realizar una acción insegura aunque la API funcione exactamente como sus responsables actuales esperan.

La deriva más peligrosa rara vez produce un fallo evidente. Un 404 llama la atención. Una solicitud que sigue devolviendo 200 aunque seleccione más recursos, use un valor predeterminado cambiado o evite una confirmación esperada, no. Esa discrepancia puede dejar un registro de actividad impecable y provocar una tarde desastrosa.

## La documentación pasa a formar parte del plano de control del agente

Un agente usa la documentación para elegir operaciones, completar parámetros, interpretar respuestas y decidir si debe reintentar. Por eso los ejemplos, las tablas de referencia, las guías de autenticación y las notas de migración forman parte de su plano de control. El código del servicio puede ser correcto mientras ese plano le indica al agente que lo use de forma incorrecta.

Los equipos suelen trazar una línea artificial entre la definición de una herramienta y una guía. La definición dice `deleteProject(project_id)`. La guía explica qué identificador de proyecto obtener, si existe un modo de simulación, si la eliminación se propaga y qué hacer después de un fallo de autorización. El agente necesita ambas cosas. Si una de ellas contiene información incorrecta, la acción resultante puede ser errónea.

Por eso un ejemplo obsoleto no equivale a un párrafo con una errata. Imagina una instrucción antigua que dice que la ausencia del parámetro `scope` significa «proyecto actual». Más tarde, un cambio en el backend hace que la misma omisión signifique «todos los proyectos disponibles para esta credencial». El endpoint sigue funcionando. El ejemplo sigue siendo válido sintácticamente. Un agente que siga la guía antigua puede aplicar ahora un cambio supuestamente local a toda una cuenta.

La documentación también determina la confianza del agente. Los fragmentos concretos pesan más que una advertencia vaga en el texto cercano. Si una página dice «usa el menor privilegio» y otra muestra un token bearer con acceso a toda la cuenta, en la práctica gana el fragmento. Los agentes optimizan el camino que produce un resultado.

Trata como documentación que puede activar acciones lo siguiente:

- Ejemplos de solicitudes y comandos
- Tablas de parámetros que describen valores predeterminados y valores permitidos
- Instrucciones para configurar la autenticación, las credenciales y el entorno
- Indicaciones sobre reintentos, paginación, idempotencia y gestión de errores
- Instrucciones de migración y retirada que indican qué operación reemplaza a otra

Conviene distinguir entre **deriva sintáctica** y **deriva de significado**. La primera hace que un ejemplo falle porque cambió un campo o una ruta. La segunda deja el ejemplo válido, pero cambia aquello a lo que afecta. La deriva sintáctica avergüenza al autor. La deriva de significado puede dañar datos, gastar dinero, exponer registros o ampliar el acceso. Tu conjunto de pruebas debe detectar ambas.

## Una solicitud correcta también puede demostrar que el ejemplo es incorrecto

Una prueba de documentación que solo comprueba los códigos de estado detecta los fallos fáciles y pasa por alto los peligrosos. El éxito HTTP indica que el servidor aceptó la solicitud. No indica que apuntara al objeto previsto, que produjera el efecto descrito o que respetara el límite indicado.

Supón que una página de referencia publica esta solicitud:

```bash
curl -sS -X POST "$API_URL/v1/exports" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"project":"demo","include_archived":false}'
```

Una prueba básica busca `202 Accepted` y da el trabajo por terminado. No detecta varios cambios importantes:

- El servicio cambia silenciosamente `project` por `project_id` y trata el campo antiguo como ausente.
- `include_archived` pasa de excluir elementos a ser un campo de compatibilidad ignorado.
- La credencial obtiene visibilidad sobre toda la cuenta, por lo que `demo` resuelve al proyecto de otro tenant.
- El endpoint sigue poniendo el trabajo en cola, pero ahora exporta adjuntos que la guía dice excluir.

La prueba debe inspeccionar el resultado y el estado del servicio, no solo el código de estado. En una cuenta desechable, crea un registro activo y otro archivado. Envía la solicitud documentada. Consulta el trabajo resultante. Comprueba que el artefacto contiene el registro activo, omite el archivado y registra el identificador de proyecto esperado. Si el servicio no puede proporcionar suficiente evidencia para hacer esa comprobación, la documentación tampoco puede prometer ese comportamiento de forma segura.

RFC 9110 define los códigos de estado HTTP como el resultado del procesamiento de una solicitud. No afirma que un estado correcto demuestre la intención de negocio de quien llama. Parece obvio, pero los equipos siguen creando comprobaciones de documentación que reducen el protocolo a `curl` más `grep 200`. Usa la semántica HTTP para las aserciones del protocolo y añade después aserciones sobre el resultado real.

Una buena prueba nombra la afirmación que verifica. `export_excludes_archived_records` resulta útil. `docs_example_returns_success` solo indica que alguien ejecutó una solicitud.

## Los ejemplos necesitan pruebas de contrato, no revisiones de capturas de pantalla

Copiar un ejemplo de una página de documentación a una terminal durante la revisión de una versión es mejor que nada. No escala, no deja evidencia fiable y favorece el camino feliz. Además, las personas suelen corregir el comando localmente y olvidar corregir la página.

Guarda los ejemplos ejecutables en un archivo estructurado, genera el fragmento visible a partir de esa fuente y ejecuta la misma fuente en CI. Puedes usar ejemplos de OpenAPI, extracción de bloques de código Markdown o un directorio separado de fixtures. El mecanismo importa menos que una propiedad: el comando que ve el lector debe ser el mismo que ejecuta la prueba.

No mantengas en secreto una «versión de prueba» con URLs más seguras, permisos más limitados o encabezados más completos que los del ejemplo publicado. Esa separación crea una compilación verde tranquilizadora mientras las instrucciones públicas se deterioran. Parametriza únicamente los valores que deben cambiar según el entorno, como la URL base, las credenciales de prueba y los identificadores de fixtures. Mantén idénticos el método, la ruta, la forma del cuerpo y las opciones relevantes de seguridad.

Una pequeña prueba de shell puede mostrar el patrón:

```bash
set -euo pipefail

project_id="docs-check-$RANDOM"
response=$(curl -sS -X POST "$API_URL/v1/projects" \
  -H "Authorization: Bearer $DOCS_TEST_TOKEN" \
  -H "Content-Type: application/json" \
  -d "{\"id\":\"$project_id\",\"name\":\"Documentation check\"}")

printf '%s' "$response" | jq -e \
  --arg id "$project_id" \
  '.id == $id and .name == "Documentation check" and .archived == false'
```

La salida esperada de `jq -e` es el valor JSON `true`; una discrepancia termina con un código distinto de cero. Lo importante no es la sintaxis de shell. La aserción expresa lo que afirma la prosa: la API crea un proyecto con el identificador indicado, conserva el nombre enviado y no lo archiva de forma predeterminada.

Crea una comprobación independiente para la documentación renderizada. Si un extractor de Markdown obtiene de la página un bloque marcado como `bash`, la prueba debe ejecutar ese bloque después de sustituir las variables de entorno aprobadas. Si generas la documentación a partir de una descripción OpenAPI, prueba el ejemplo generado y no un equivalente copiado a mano.

La revisión de capturas de pantalla sigue siendo útil para valorar la legibilidad. No puede demostrar el comportamiento. Un revisor puede pasar por alto un encabezado omitido con sorprendente facilidad, especialmente cuando la página contiene varios ejemplos parecidos. Las máquinas no se cansan de comparar un campo con un fixture.

## Las comprobaciones del servicio activo deben cubrir valores predeterminados y fallos

La mayoría de los cambios peligrosos de una API afectan a los valores predeterminados, los límites de autorización y la gestión de fallos. Las pruebas del camino feliz evitan los tres porque son fáciles de escribir y de mantener en verde.

Prueba los casos de omisión que podría producir un agente. Los agentes suelen construir los cuerpos de forma condicional, de modo que un campo opcional puede desaparecer cuando una consulta anterior no devuelve ningún valor. Para cada parámetro opcional documentado, decide si omitirlo es seguro, provoca un rechazo o cambia su significado. Después prueba directamente el comportamiento documentado.

Para una operación con el campo `dry_run`, ejecuta al menos estos casos en un entorno aislado:

1. `dry_run: true` devuelve un plan y deja el fixture sin cambios.
2. `dry_run: false` realiza el cambio indicado únicamente sobre el fixture nombrado.
3. Omitir `dry_run` rechaza la solicitud o produce el valor predeterminado documentado.
4. Un token sin el alcance suficiente falla antes de que se produzca cualquier cambio.
5. Repetir la solicitud documentada se comporta como indica la guía de idempotencia.

El tercer caso detecta una fuente habitual de daños accidentales. El equipo del servicio cambia un valor predeterminado para favorecer a los usuarios interactivos, mientras la documentación sigue suponiendo el anterior. Una interfaz humana puede mostrar una pantalla de confirmación. Un cliente de API no tiene esa pantalla.

Los ejemplos de error también necesitan pruebas. La documentación suele decir «reintenta ante un 429» sin aclarar si la respuesta incluye `Retry-After`, si es seguro repetir la operación o si la solicitud necesita un token de idempotencia. Ese consejo puede convertir un breve límite de velocidad en facturas duplicadas, despliegues duplicados o revocaciones repetidas.

Prueba las indicaciones exactas para el fallo. Fuerza la condición de limitación en un servicio de prueba o en un entorno controlado. Confirma que el cliente documentado lee el encabezado indicado, espera según las instrucciones y vuelve a enviar el mismo identificador de idempotencia cuando la API admite uno. Si el servicio no puede producir el error de forma predecible, documenta la incertidumbre en lugar de publicar una receta demasiado segura.

La palabra clave `default` de OpenAPI crea una trampa relacionada. En las descripciones de JSON Schema y OpenAPI, un valor predeterminado declarado suele comunicar lo que las herramientas pueden asumir o mostrar. No hace que automáticamente todas las implementaciones del servidor apliquen ese valor. Comprueba el servicio desplegado con el campo omitido. El valor predeterminado del esquema y el del servidor son afirmaciones distintas hasta que una prueba las vincula.

## Los flujos destructivos necesitan pruebas desechables

No pruebes ejemplos destructivos contra una cuenta de staging compartida y lo consideres seguro. Los entornos compartidos acumulan fixtures antiguos, experimentos manuales y credenciales con un alcance poco claro. Tarde o temprano, una prueba de documentación coincidirá con el objeto equivocado o un comando de limpieza superará sus límites previstos.

Usa un tenant o una cuenta de prueba dedicada, con credenciales que solo puedan acceder a los recursos de prueba. Crea cada fixture con una marca única de ejecución. Recupéralo mediante esa marca antes de modificarlo. Después de la prueba, verifica el estado resultante en lugar de suponer que la API hizo lo que afirmaba la respuesta.

Un ejemplo de eliminación debe demostrar todo el ciclo de vida:

```text
create fixture: docs-delete-<run-id>
read fixture: confirm owner=test-suite and run_id=<run-id>
delete fixture: send the rendered documentation request
read fixture: expect the documented absence or tombstone state
list nearby fixtures: confirm unrelated fixtures remain
```

La última comprobación importa. Una prueba de eliminación que solo confirma que desapareció el objeto elegido no puede detectar un selector demasiado amplio. He visto equipos aceptar un endpoint masivo porque su único fixture desaparecía como esperaban, aunque el endpoint también eliminara todos los recursos con un prefijo parecido. La prueba necesitaba un vecino deliberadamente similar que debiera sobrevivir.

No indiques a los agentes que usen selectores cómodos como `latest`, `all`, un filtro vacío o un nombre legible cuando exista un identificador inmutable. Esos selectores parecen amables en un tutorial y se vuelven peligrosos cuando un agente ejecuta la receta en una cuenta con mucha actividad. Si una operación necesita realmente un selector amplio, incluye el alcance en el cuerpo de la solicitud o en los argumentos del comando, donde el revisor pueda verlo. No lo escondas en un valor predeterminado del servidor.

Para las operaciones irreversibles, publica una lectura previa y haz que el ejemplo use su resultado. Primero recupera el objeto y verifica su ID inmutable y su estado relevante; después ejecuta la modificación. Esto añade fricción. Esa fricción cuesta menos que explicar por qué un agente eliminó el objeto que casualmente compartía un nombre visible.

## Las pruebas de herramientas deben comparar el significado, no solo los esquemas

La validación del esquema es necesaria, pero los esquemas suelen describir la forma con más precisión que las consecuencias. Un cuerpo de solicitud puede cumplir todas las restricciones de tipo y aun así dirigir una acción al entorno equivocado o con privilegios incorrectos.

Construye las aserciones alrededor de cuatro preguntas: ¿a quién afectó la acción?, ¿qué estado cambió?, ¿qué estado no cambió? y ¿qué identidad la autorizó? Estas preguntas sirven para APIs HTTP, comandos SSH y herramientas internas.

En HTTP, captura el identificador de solicitud cuando el servicio lo proporcione y consulta después el recurso resultante o el registro de auditoría en el entorno de prueba. Haz coincidir el identificador de solicitud, el actor, el objetivo y la modificación. En SSH, ejecuta los comandos contra un host desechable, captura el código de salida y la salida, y después inspecciona el estado del host con un comando de verificación independiente. No hagas que el comando de acción corrija su propio examen.

Un fixture útil tiene contraste. Si pruebas un comando que debe reiniciar un servicio, crea otro que deba seguir funcionando. Si pruebas una consulta limitada a un repositorio, incluye un segundo repositorio que la misma credencial pueda ver pero que la solicitud no deba tocar. Sin contraste, una acción demasiado amplia puede parecer correcta.

Aquí muchos equipos usan mal las pruebas de contrato. Las herramientas de contrato impulsadas por el consumidor pueden confirmar que un proveedor acepta una forma de solicitud y devuelve los campos esperados. No pueden determinar si la solicitud seleccionó la cuenta de producción correcta, si una opción `force` adquirió un significado nuevo o si una eliminación se propagó más allá del objeto documentado. Conserva la prueba de contrato y añade una prueba de resultado con fixtures diseñados para revelar un alcance excesivo.

La descripción de una herramienta también necesita pruebas. Si una herramienta expone `environment`, no describas `production` como un valor aceptable a menos que una prueba verifique que dirige al host documentado y usa la ruta de autorización indicada. Los agentes usan las descripciones para completar argumentos. Una descripción obsoleta es simplemente una versión en prosa de un ejemplo de API obsoleto.

## Un agente necesita evidencia de actualidad y una ruta segura para abstenerse

Un agente no debería deducir que la documentación está actual solo porque aparece en un repositorio o en un portal interno. Proporciónale evidencia verificable y legible por máquinas, vinculada a la operación que planea invocar.

Un manifiesto sencillo puede bastar:

```json
{
  "operation": "POST /v1/exports",
  "documentation_source": "docs/api/exports.md#creating-an-export",
  "verified_in": "isolated-test-tenant",
  "verification_commit": "<commit-id>",
  "assertions": [
    "returns an export job",
    "omits archived fixtures when include_archived is false",
    "rejects a token without export scope"
  ],
  "review_required_when": ["production", "include_archived=true"]
}
```

El identificador de commit no es una garantía de confianza por sí solo. Permite al revisor rastrear la documentación y la fuente de la prueba que produjeron la evidencia. Guarda la hora de verificación en tus propios registros de compilación si el proceso de publicación necesita un límite de antigüedad, pero no finjas que una marca temporal vuelve seguro un comportamiento antiguo. Un despliegue del servicio puede invalidar la prueba de ayer.

La regla de decisión del agente debe ser clara. Si la operación solicitada no tiene un registro de verificación aprobado para la interfaz desplegada, debe ejecutar una comprobación previa que no modifique nada en un contexto de pruebas autorizado o pedir a una persona que apruebe la acción exacta. No debe improvisar basándose en un endpoint cercano.

Distingue «desconocido» de «seguro». Los agentes tienden a rellenar los huecos porque completar una tarea recibe una respuesta positiva. El diseño de la herramienta debe hacer que abstenerse sea un resultado correcto cuando falta evidencia. Devuelve una razón como: `documentation example has no verified outcome test for this operation`. Ese mensaje ofrece al desarrollador un objetivo concreto de reparación en lugar de una negativa vaga.

No intentes resolverlo con un archivo de políticas interminable que enumere todas las frases de riesgo de cada documento. La redacción cambiará más rápido que las reglas. Vincula una operación concreta con una prueba concreta y entrega el resultado al agente.

## Las barreras de publicación solo funcionan si bloquean la página engañosa

Un programa de verificación de documentación falla cuando genera informes sobre los que nadie tiene que actuar. La comprobación debe bloquear la publicación o, al menos, el acceso del agente al ejemplo afectado cuando cambie el contrato del servicio.

Conecta las comprobaciones con los cambios en la especificación de la API, los controladores de rutas, el middleware de autenticación, los constructores de solicitudes del SDK y las fuentes de documentación. Un cambio en cualquiera de esas áreas debe ejecutar las pruebas de ejemplo correspondientes. Si una prueba falla, el equipo tiene tres opciones honestas: restaurar el comportamiento anterior, actualizar la documentación y las pruebas para reflejar el nuevo comportamiento o marcar la operación como no disponible para los agentes hasta que la verificación se complete.

La revisión manual sigue siendo útil para aplicar criterio, pero por sí sola es una recomendación equivocada. Es popular porque parece barata y conserva un flujo de publicación rápido. También exige que el revisor simule mentalmente un servicio, sus credenciales, valores predeterminados y transiciones de estado a partir de un texto. Las personas no pueden hacerlo de forma fiable en todas las versiones rutinarias.

Haz que los fallos sean fáciles de entender. Un informe útil nombra la página, el bloque de código, la operación, el fixture, la respuesta observada y la aserción incumplida. «Falló la integración de la documentación» obliga a investigar. «exports.md, línea 42, dice que se excluyen los registros archivados; el artefacto de exportación incluyó el fixture archived-run-817» ofrece al responsable una reparación directa.

No relajes una prueba solo porque un cambio del servicio la haya vuelto incómoda. Primero decide si la promesa anterior era útil. Si lo era, restáurala o explica claramente la nueva limitación. Si era insegura, elimina el ejemplo en lugar de conservarlo con una frase más suave. Un agente normalmente seguirá el comando que quede.

La documentación versionada necesita la misma disciplina. Una página para una versión anterior de la API puede describir con precisión un despliegue antiguo y aun así confundir a un agente que apunta a la URL base actual. Pon la versión en la ruta del endpoint, la URL del servidor o los metadatos de la herramienta, donde el agente pueda vincularla a la solicitud. Un encabezado que diga «v1» en algún punto visible de la página es una evidencia débil.

## La autorización limita el alcance del daño, pero no corrige las instrucciones incorrectas

La aprobación y el aislamiento de credenciales siguen siendo importantes porque las comprobaciones de documentación pueden pasar por alto defectos. Reducen el daño cuando un agente elige la operación equivocada. No convierten una instrucción obsoleta en una correcta.

Mantén separadas ambas tareas. La verificación de documentación pregunta: «¿Este ejemplo describe el servicio activo y sus consecuencias?». La autorización de acciones pregunta: «¿Debe permitirse que este agente haga esta llamada ahora?». Mezclarlas crea confusión. Un usuario puede aprobar una llamada porque el agente dice que exportará un proyecto, mientras el ejemplo obsoleto en realidad exporta todos los proyectos visibles para la credencial.

Para las acciones HTTP y SSH dirigidas por agentes, Sallyport mantiene las credenciales fuera del agente y puede exigir que una persona autorice una sesión o el uso de una credencial concreta. Es un límite final útil cuando una comprobación de documentación no encuentra evidencia fiable o cuando una acción tiene consecuencias que merecen revisión humana.

La pantalla de aprobación debe mostrar la operación, el objetivo y el alcance en términos que una persona pueda valorar. «POST /v1/exports» no basta cuando el cuerpo incluye `include_archived=true` o un selector para toda la cuenta. Si tu capa de autorización no puede mostrar el alcance relevante, limita la interfaz de la herramienta hasta que pueda hacerlo.

Los registros de auditoría proporcionan después material para mejorar las pruebas. Cuando una persona revoque una ejecución o cuestione una acción, revisa la solicitud exacta, la fuente de documentación citada por el agente y la evidencia de verificación disponible. No conviertas esa revisión en una búsqueda de culpables. Úsala para añadir el fixture, la aserción o la condición de abstención que faltaba.

## Empieza por probar el ejemplo que más probablemente lamentarás

No empieces con la solicitud GET más limpia de la referencia. Empieza por el ejemplo que pueda eliminar, publicar, rotar, conceder, cobrar o acceder a un host de producción. Dale un fixture aislado, ejecuta el comando renderizado exacto y comprueba tanto el cambio previsto como el cambio cercano que no debe producirse.

Después vincula esa prueba con la fuente de documentación y haz que un fallo sea visible antes de la publicación o del uso por parte del agente. El trabajo es menos llamativo que escribir una nueva descripción de herramienta, pero elimina una suposición peligrosa: que una página es segura porque alguna vez superó una revisión.

Un servicio activo cambia. Su documentación cambiará más despacio a menos que obligues a ambas cosas a encontrarse en una prueba. Haz que ese encuentro forme parte de la publicación, antes de que un agente convierta una frase antigua en una acción.
