Illustrative Case: Verifiable .NET API Change with a Coding Agent

Naturaleza del caso

Este caso es ficticio y trabajado con fines didácticos. No describe un cambio ejecutado en un repositorio real, no incluye resultados de tests observados y no mide productividad de un agente. Los fragmentos y caminos son ilustrativos; no se creó ni compiló una aplicación .NET para escribirlo.

La situación muestra cómo un coding-agent puede colaborar en una modificación pequeña con aceptación verificable. El producto del ejemplo es una API convencional de órdenes, sin funcionalidades AI. Es una aplicación de AI-Assisted Software Engineering, distinta de construir una aplicación cuyo comportamiento de producto utiliza un modelo.

El entorno supuesto es ASP.NET Core 10 con controllers y [ApiController], una convención existente de errores y pruebas de integración ya disponibles. Las referencias de framework se consultaron el 2026-11-09. No se traslada este comportamiento automáticamente a Minimal APIs o a otra configuración.

Problema y contrato de aceptación

Se supone que POST /orders acepta una colección de líneas vacía y el procesamiento posterior falla. El DTO ya declara Lines como array con default vacío y utiliza [Required], pero el caso vacío necesita una regla adicional. Una entrada mínima ficticia es:

{
  "customerId": "customer-demo",
  "lines": []
}

El objetivo se acuerda antes de editar: rechazar una orden sin líneas en la frontera HTTP, conservando la convención de validación y el comportamiento de órdenes válidas. Quedan fuera cambiar la persistencia, modificar rutas, agregar dependencias o publicar el resultado.

Entrada o condiciónResultado esperado en este escenario
lines vacíoHTTP 400, error de validación correspondiente al campo y ningún intento de persistencia.
lines explícitamente nullHTTP 400 según el contrato de validación existente.
lines omitidoHTTP 400 al conservar el default vacío y aplicar la regla de longitud.
Orden válida con una línea válidaMantener el HTTP 201 y el contrato de respuesta ya establecidos.
Otros errores de líneasConservar las reglas y respuestas previas pertinentes.

Los códigos son decisiones del caso, no una política universal de APIs. La forma exacta de las claves, mensajes y detalles debe derivarse de la convención del repositorio supuesto.

Encargo y contexto inicial

Un prompt de trabajo podría ser:

Investigá por qué POST /orders acepta lines vacío.
Conservá rutas, respuestas válidas y convención de errores.
Buscá el DTO, el controller y las pruebas de validación pertinentes.
Proponé el cambio mínimo y una prueba que discrimine el defecto.
No agregues dependencias, no hagas commit ni publiques.
Informá qué comprobaste, qué no pudiste ejecutar y qué revisión verificaste.

repository-exploration-and-task-framing y context-engineering-for-software-development orientan la selección de archivos. El agente debería comprobar instrucciones aplicables y estado del working tree, localizar el contrato de entrada y mirar pruebas semejantes. No necesita comenzar leyendo todo el repositorio.

La hipótesis inicial debe mantenerse separada de la evidencia. Si el endpoint real utilizara otra representación o ya tuviera una regla equivalente, correspondería revisar el diagnóstico. El encargo no autoriza imponer la solución del artículo frente a evidencia contraria.

El mismo flujo con Claude Code y Cursor

La referencia de subagentes de Claude Code admite una lista de herramientas en el perfil. En una etapa de revisión, un archivo .claude/agents/api-reviewer.md podría declarar:

---
name: api-reviewer
description: Revisa el contrato HTTP y las pruebas de validación sin editar.
tools: Read, Grep, Glob
model: inherit
---
 
Inspecciona el DTO, el endpoint y las pruebas relacionadas con POST /orders.
Comprueba cada condición de la matriz de aceptación y cita evidencia.
Devuelve dudas y hallazgos al agente principal; no propongas cambios fuera del alcance.

Al excluir Edit, Write y Bash, este perfil expresa una allowlist de herramientas para ese subagente. La skill de revisión puede contener el procedimiento común, pero allowed-tools dentro de la skill de Claude Code solo preaprueba herramientas durante su turno; no sustituye el límite del perfil ni la política de sesión.

En Cursor, el archivo .cursor/agents/api-reviewer.md ofrece otra forma:

---
name: api-reviewer
description: Revisa el contrato HTTP y las pruebas de validación sin editar.
model: inherit
readonly: true
---
 
Inspecciona el DTO, el endpoint y las pruebas relacionadas con POST /orders.
Comprueba cada condición de la matriz de aceptación y cita evidencia.
Devuelve dudas y hallazgos al agente principal; no amplíes el alcance.

La documentación de Cursor describe readonly: true para restringir ediciones de archivos y comandos shell que cambian estado. Las skills de Cursor conservan el procedimiento en SKILL.md; no reciben por ello el permiso de solo lectura. Estos dos formatos documentan intenciones comparables, pero sus campos no son portables entre productos.

En ambos productos, primero se pide al revisor que informe diagnóstico, evidencia y prueba que distinguiría el defecto. El responsable humano contrasta ese informe con el contrato. Luego se realiza un encargo de edición separado que autoriza modificar el DTO y las pruebas necesarias. Esa separación deja claro qué participante revisa y cuál puede cambiar archivos; el readonly de Cursor y la allowlist de Claude Code pertenecen al subagente revisor, no al coding agent que implementa.

Hooks y verificación del cambio

Las guías oficiales permiten asociar hooks a eventos de edición. En Claude Code, PostToolUse con Write|Edit ocurre después de una herramienta exitosa. En Cursor, afterFileEdit se ejecuta después de que Agent edita un archivo. Un ejemplo ilustrativo para Cursor en .cursor/hooks.json es:

{
  "version": 1,
  "hooks": {
    "afterFileEdit": [
      {
        "command": "dotnet test tests/Orders.Api.Tests/Orders.Api.Tests.csproj --no-restore"
      }
    ]
  }
}

La forma correspondiente en Claude Code usa .claude/settings.json:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "dotnet test tests/Orders.Api.Tests/Orders.Api.Tests.csproj --no-restore"
          }
        ]
      }
    ]
  }
}

El camino y comando proceden del proyecto ficticio de este caso. El evento y el formato de configuración son diferentes entre productos; no se deben copiar entre sí. La referencia de hooks de Claude Code señala que PostToolUse no bloquea la operación que ya ocurrió. La referencia de hooks de Cursor describe afterFileEdit como evento posterior. Ninguno convierte automáticamente un resultado fallido en autorización para publicar.

Ejecutar una suite completa después de cada edición puede desperdiciar tiempo. Un equipo puede hacer que el hook aplique una comprobación rápida y reservar la suite pertinente para el final. El resultado del hook aporta observación; todavía hacen falta pruebas que atraviesen el pipeline HTTP, revisión del diff y aceptación humana. Si el hook o su script no se descubre, no corre o falla, ese resultado debe declararse: la mera presencia del archivo de configuración no demuestra ejecución.

Propuesta de cambio delimitado

En las condiciones supuestas, un fragmento del DTO puede conservar [Required] y añadir una restricción de longitud:

[Required]
[MinLength(1)]
public CreateOrderLineRequest[] Lines { get; init; } =
    Array.Empty<CreateOrderLineRequest>();

Es un miembro ilustrativo, no una clase compilable aislada; se supone el tipo de línea y los imports existentes. La referencia de MinLengthAttribute describe su uso para longitud mínima de arrays o strings. [Required] y longitud mínima atienden condiciones distintas; conservar ambas evita sustituir la comprobación de ausencia por la de cantidad.

La documentación de controllers explica que [ApiController] convierte errores de model validation en HTTP 400 mediante un filtro. Para este escenario se supone que ese comportamiento sigue habilitado y que la convención de errores existente lo integra. Antes de aplicar el fragmento, comprobar personalizaciones y reglas de negocio.

La validación de entrada tampoco reemplaza invariantes del dominio si existen otros caminos para crear órdenes. El cambio delimitado debe respetar los controles ya presentes y señalar cualquier brecha descubierta como una decisión aparte, sin expandir silenciosamente el encargo.

Verificación que atraviesa la frontera correcta

Una llamada directa a un método del controller no recorre automáticamente model binding y filtros HTTP. Si el comportamiento esperado depende de ese pipeline, una prueba limitada al método puede dejarlo sin comprobar. La guía de integración de ASP.NET Core documenta hosting de pruebas y WebApplicationFactory para ejercitar la aplicación.

En el repositorio ficticio se reutilizaría su host de pruebas para enviar las entradas de la matriz, inspeccionar status y errores, y observar que los rechazos no invoquen persistencia. Una prueba de atributos puede aportar evidencia adicional, pero no sustituye por sí sola el contrato HTTP.

Para discriminar el defecto, comprobar que el caso de colección vacía falla con el comportamiento anterior y pasa con la corrección, usando un entorno aislado y la misma configuración relevante. Eso es un criterio propuesto; este artículo no afirma haber observado esa transición.

Un comando posible, si ese fuera el proyecto existente y sus dependencias ya estuvieran restauradas, sería:

dotnet test tests/Orders.Api.Tests/Orders.Api.Tests.csproj --no-restore

El camino pertenece al ejemplo. En trabajo real debe obtenerse del repositorio; un comando no ejecutado no debe presentarse como prueba verde. Un bloqueo de SDK o restauración debe registrarse sin confundirse con un resultado del test.

Revisión, evidencia y cierre

El revisor contrasta diff y aceptación: comprueba el DTO real, las pruebas, el camino de respuesta y ausencia de cambios ajenos. También revisa si el agente deshabilitó una prueba o alteró datos para ocultar el fallo. generated-code-verification y ai-assisted-code-review conservan esas responsabilidades.

Un cierre real debería identificar revisión del código, comandos y resultados observados, archivos afectados, límites y pendientes. Aquí el estado de la evidencia es:

ElementoEvidencia disponible en este artículo
Contrato, propuesta y matriz de pruebasConstrucción editorial explícita.
Comportamiento del frameworkDocumentación primaria enlazada, bajo los supuestos indicados.
Compilación, tests y ausencia de efectosNo ejecutados ni demostrados por este caso.
Ahorro, velocidad o calidad comparada del agenteNo medidos.

El caso ilustra una disciplina: pasar de un síntoma y una hipótesis a una propuesta delimitada y a verificaciones que cubran el contrato. No atribuye corrección al agente por producir un diff plausible ni convierte la documentación del framework en un resultado del repositorio. ai-assisted-software-engineering ofrece el recorrido y coding-agent-prompting-and-context-recipes aporta ejemplos complementarios de encargo y handoff.