Cómo escribir comprobaciones eficaces
Una buena comprobación se lee como una regla que un compañero nuevo podría aplicar leyendo el código. Para el formato de archivo y las opciones, consulta Comprobaciones del repositorio.
Una regla decidible por comprobación
Pon cada regla independiente en su propio archivo. Los hallazgos se etiquetan con el nombre de archivo de la comprobación, y cada archivo tiene sus propios patrones.
Escribe la regla como una condición sobre el código: qué la incumple y qué la cumple.
Acótala con patrones de archivos
Añade patrones files para que la comprobación se aplique solo donde importa la regla; sin ellos, se aplica a todos los pull requests. Excluye tests o fixtures con ! y pon cada patrón entre comillas en YAML.
Explica el motivo y da ejemplos
Explica por qué importa la regla, para que HeyDeer pueda juzgar casos que no previó. Describe el código correcto además de lo que incumple la regla, con un ejemplo breve incorrecto y otro correcto de tu código.
Mantén las comprobaciones breves y ordenadas
La mayoría de las buenas comprobaciones caben en una pantalla. Si varias comprobaciones necesitan el mismo contexto, muévelo a una skill.
Cada revisión aplica como máximo 10 comprobaciones coincidentes, por orden de nombre de archivo, así que antepón números a las más importantes, como 10-auth.md. Para una comprobación sencilla, establece skip_extra_reviewers: true; así las revisiones profundas la revisan como lo hace Estándar. Consulta Hasta 10 comprobaciones por revisión.
Pruébala en un pull request real
- Fusiona la comprobación. HeyDeer lee las comprobaciones desde la rama base.
- Abre un pull request que incumpla la regla y confirma que un hallazgo menciona tu comprobación. Confirma que el código que sigue la regla no recibe ninguno.
- Si la comprobación marca código correcto, ajusta la regla o los patrones. Si pasa por alto un caso, añádelo como ejemplo incorrecto.
Antipatrones
| Antipatrón | Por qué falla | Escribe en su lugar |
|---|---|---|
| Vaguedad: “Sigue las buenas prácticas de diseño de API.” | No hay ninguna condición con la que contrastar el código, así que los hallazgos varían. | “Los handlers de src/api/ validan el cuerpo de la solicitud con el esquema de la ruta.” |
| Invisible para HeyDeer: “Falla salvo que la CI pase y seguridad lo haya aprobado.” | HeyDeer no ve los resultados de la CI ni las aprobaciones. | Usa las reglas de rama de GitHub para exigir la CI y las aprobaciones. |
| Ejecutar algo: “Ejecuta los tests e informa del resultado.” | HeyDeer nunca ejecuta código, tests ni builds. | “Los cambios en src/billing/ incluyen un test que ejercita la función modificada.” |
| Formato: “Usa sangría de dos espacios y ordena los imports.” | Un formateador o un linter lo aplica con exactitud. | Ejecuta esas herramientas en la CI. |
| Especulación: “Señala cualquier cosa que pueda ser lenta.” | Sin un patrón concreto, los hallazgos se convierten en opiniones. | “Un bucle no debe lanzar una consulta a la base de datos por elemento; agrupa la consulta.” |
| Varias reglas en un archivo: “Comprueba la autenticación, los logs, los nombres y los tests.” | Los hallazgos comparten una etiqueta y las reglas no se pueden acotar por separado. | Un archivo por regla, cada uno con sus propios patrones. |
Antes y después
Antes:
---
files: "src/**"
---
Follow API best practices. Make sure endpoints are secure, fast,
and well tested, and that naming is consistent. Run the test suite
and fail if anything breaks.Después, como .agents/checks/20-api-workspace-scope.md:
---
files:
- "src/api/**/*.ts"
- "!**/*.test.ts"
---
# API handlers scope queries to the caller’s workspace
Every query in an API handler that reads or writes a table with a
`workspace_id` column must filter on the workspace returned by
`requireWorkspace()`. Without that filter, one customer can read
or change another customer’s data.
Fail when a handler queries such a table without that filter.
Pass when every such query filters on the workspace, or when the
handler only touches tables without a `workspace_id` column.
Incorrect:
```ts
const invoice = await db.query.invoices.findFirst({
where: eq(invoices.id, id),
});
```
Correct:
```ts
const { workspaceId } = await requireWorkspace(req);
const invoice = await db.query.invoices.findFirst({
where: and(eq(invoices.id, id), eq(invoices.workspaceId, workspaceId)),
});
```La nueva versión se centra en una sola cuestión, la limita a los handlers de la API, indica qué falla y qué pasa, y explica el riesgo. Las demás cuestiones pasan a ser comprobaciones propias o se trasladan a herramientas y a AGENTS.md.