uecko-control-tiempos/AGENTS.md
David e94d5e6c71 Add project documentation and architectural guidelines
- Created project overview document for UECKO application.
- Added README file for project documentation structure.
- Introduced template for architectural decision records (ADR).
- Defined backend architecture guidelines.
- Established conventions for project-wide consistency.
- Documented data persistence architecture.
- Outlined frontend architecture principles.
- Developed testing strategy documentation.
- Provided a general architecture overview.
- Created guides for task closure and ChatGPT-Codex workflow.
- Organized chat management guidelines for development projects.
- Added template for current work status reporting.
2026-09-17 22:11:39 +02:00

1389 lines
32 KiB
Markdown

# AGENTS.md
## Ámbito
Estas instrucciones se aplican a todo el monorepo, salvo que exista un archivo `AGENTS.md` más específico en un subdirectorio.
Los archivos `AGENTS.md` descendientes pueden añadir, concretar o restringir reglas para su ámbito.
No deben duplicar innecesariamente las reglas de este documento.
---
## Objetivo
Trabajar sobre el proyecto mediante cambios:
* correctos;
* mínimos;
* comprobables;
* coherentes con la arquitectura existente;
* seguros;
* fáciles de revisar;
* fáciles de entender y mantener.
Antes de modificar código, revisar las implementaciones y patrones existentes en el área afectada.
No introducir un patrón nuevo cuando ya exista una solución equivalente y adecuada dentro del proyecto.
---
## 1. Principios generales
Antes de realizar cambios:
1. Inspeccionar el código relevante.
2. Comprender la implementación y el flujo actual.
3. Buscar patrones equivalentes dentro del repositorio.
4. Identificar el alcance real de la tarea.
5. Consultar la documentación normativa relevante.
6. Evitar suposiciones que puedan verificarse directamente.
7. Determinar cómo se validará el cambio antes de implementarlo cuando la tarea sea relevante.
Aplicar de forma pragmática:
* SOLID;
* Clean Code;
* DRY;
* KISS;
* YAGNI;
* SSOT;
* Fail Fast;
* programación defensiva;
* inmutabilidad cuando resulte adecuada;
* idempotencia;
* principio de menor privilegio;
* observabilidad en APIs y servicios.
Estos principios no justifican por sí solos una refactorización o abstracción nueva.
Priorizar:
```text
claridad y explicitud
>
abstracción prematura
```
Preferir:
* cambios mínimos y focalizados;
* soluciones explícitas;
* reutilización de abstracciones existentes;
* coherencia con el proyecto frente a buenas prácticas genéricas;
* evidencia comprobable frente a especulación;
* simplicidad frente a generalización prematura.
No introducir capas, adaptadores, factories, genéricos, eventos, contenedores DI u otras abstracciones sin una necesidad real y actual.
---
## 2. Entorno de desarrollo
### Stack principal
* Node.js 24.x
* TypeScript
* PNPM
* Turborepo
* ExpressJS
* React
* MariaDB
* Sequelize v6
* Zod v4
* Biome
### Entorno esperado
```text
Sistema operativo: WSL2 Ubuntu 24.04
Ruta canónica del repositorio: /home/david/dev/uecko-control-tiempos
Runtime: Node.js 24.x
Gestor de paquetes: pnpm 11.25.0
```
Todos los comandos de desarrollo deben ejecutarse dentro de WSL2 usando Linux y `bash`.
Trabajar sobre el entorno canónico salvo que la tarea requiera expresamente otro.
No utilizar como entorno de desarrollo:
* Windows;
* PowerShell;
* rutas UNC;
* `\\wsl$\...`;
* unidades Windows o de red;
* rutas bajo `/mnt/c`;
* copias antiguas del repositorio;
* workspaces alternativos;
salvo que la tarea lo requiera expresamente.
Abrir y manipular el repositorio mediante su ruta Linux real:
```text
/home/david/dev/uecko-control-tiempos
```
Antes de una tarea de código relevante, comprobar como mínimo:
```bash
pwd
git rev-parse --show-toplevel
git status --short
node --version
pnpm --version
```
Se espera:
```text
Repositorio: /home/david/dev/uecko-control-tiempos
Sistema: Linux bajo WSL2
Node.js: 24.x
PNPM: 11.25.0
```
Si el entorno no coincide con el definido por el proyecto, identificar la causa antes de modificar código.
No cambiar versiones de runtime, gestores de paquetes o configuración del entorno como efecto colateral de una tarea no relacionada.
La versión de PNPM declarada mediante `packageManager` en el `package.json` raíz es vinculante.
No modificar `packageManager` como consecuencia incidental de otra tarea.
---
## 3. Secretos y configuración local
Los archivos locales de configuración que puedan contener secretos no deben:
* mostrarse innecesariamente;
* copiarse completos a respuestas;
* incluirse en logs;
* versionarse accidentalmente.
Nunca exponer:
* contraseñas;
* tokens;
* API keys;
* claves privadas;
* secretos;
* cadenas de conexión completas;
* credenciales.
No modificar archivos de configuración local salvo que la tarea lo requiera expresamente.
---
## 4. Auditar antes de implementar
Para cambios no triviales, inspeccionar la implementación existente antes de modificarla.
Determinar, cuando corresponda:
* puntos de entrada;
* módulos afectados;
* flujo funcional;
* flujo de dominio y aplicación;
* persistencia;
* contratos públicos;
* consumidores;
* dependencias;
* tests;
* documentación relevante;
* efectos laterales.
Para bugs, localizar la causa raíz antes de aplicar una corrección.
No aplicar fixes especulativos únicamente porque hagan desaparecer un error.
---
## 5. Buscar patrones existentes primero
Antes de crear una nueva:
* abstracción;
* clase;
* servicio;
* hook;
* componente;
* mapper;
* repositorio;
* utilidad;
* schema;
* tipo;
* tipo de error;
* capa arquitectónica;
* mecanismo de validación;
buscar si ya existe una solución equivalente en el repositorio.
Preferir reutilizar o extender patrones existentes cuando sean adecuados.
No duplicar funcionalidad sin justificación.
Tampoco crear una abstracción nueva únicamente para eliminar una duplicación pequeña y local.
---
## 6. Control del alcance
Modificar únicamente lo necesario para completar la tarea solicitada.
No realizar automáticamente:
* refactors ajenos a la tarea;
* renombrados no relacionados;
* movimientos de archivos innecesarios;
* reformateos masivos;
* corrección de warnings no relacionados;
* actualización de dependencias;
* cambios de configuración global;
* cambios en APIs públicas;
* limpieza general del repositorio.
Si se detectan problemas adicionales:
1. indicar que existen;
2. explicar si afectan a la tarea;
3. no corregirlos salvo que bloqueen el trabajo o estén incluidos explícitamente en el alcance.
---
## 7. Arquitectura general
El backend sigue:
* DDD pragmático;
* Clean Architecture;
* arquitectura hexagonal.
Separación obligatoria:
```text
Domain
no conoce Application ni Infrastructure
Application
depende de Domain, contratos y Core
no conoce Express, Sequelize ni modelos ORM
Infrastructure
depende de Application, Domain y Core
```
No se permite:
* `Domain -> Application`;
* `Domain -> Infrastructure`;
* `Application -> Infrastructure`;
* importar infraestructura interna de otro módulo;
* compartir repositorios entre módulos;
* utilizar Service Locator;
* introducir DI implícita o mágica.
Preservar:
* dirección de dependencias;
* límites de módulo;
* límites de dominio;
* encapsulación;
* contratos públicos;
* límites transaccionales;
* aislamiento de datos;
* controles de seguridad.
El composition root de cada módulo debe construir explícitamente sus dependencias.
Antes de modificar una frontera arquitectónica, identificar productores, consumidores y efectos derivados.
La documentación arquitectónica específica del proyecto prevalece sobre estas reglas resumidas.
### Invariantes funcionales del proyecto
Respetar además:
* aplicación y datos deben permanecer separados;
* una actualización no puede destruir ni sobrescribir información histórica;
* los datos deben sobrevivir a cambios de versión;
* los cambios estructurales de datos deben realizarse mediante mecanismos controlados;
* las migraciones deben preservar información existente;
* ninguna evolución debe exigir reintroducción manual de históricos;
* las operaciones relevantes deben mantener trazabilidad;
* Oficina Comercial y Oficina Técnica son módulos funcionales diferenciados;
* cada módulo es propietario de los datos que genera;
* un módulo no debe modificar datos propiedad de otro sin permiso expreso;
* los identificadores de presupuesto y OF procedentes de Factuges son identificadores maestros externos;
* la aplicación no debe inventar, sustituir ni reutilizar esos identificadores.
---
## 8. Documentación normativa
La documentación normativa constituye la fuente de verdad para arquitectura, contratos e invariantes del producto.
No duplicar innecesariamente su contenido en `AGENTS.md`.
Referencias arquitectónicas normativas:
```text
- docs/architecture/backend-architecture.md
- docs/architecture/dependency-injection.md
- docs/architecture/http-request-flow.md
- docs/architecture/dto-guidelines.md
- docs/architecture/testing-guidelines.md
```
Referencias funcionales:
```text
- Respaldo_Arquitectura_Tecnica_Aplicacion_v1.1.md
- Documento funcional de Oficina Comercial
- Documento funcional de Oficina Técnica
```
Las rutas deben ajustarse a la ubicación real de dichos documentos en el repositorio.
Las reglas incluidas en este `AGENTS.md` funcionan principalmente como instrucciones operativas.
---
## 9. Idioma y convenciones de nombres
* Código e identificadores en inglés.
* Comentarios y TSDoc en castellano.
* Documentación en castellano.
* Ficheros y directorios en `kebab-case`.
* Clases, tipos e interfaces en `PascalCase`.
* Variables, funciones y métodos en `camelCase`.
* Constantes globales en `UPPER_SNAKE_CASE` solo cuando realmente sean constantes globales.
* Mantener prefijo `I` para interfaces cuando el área existente ya utilice esa convención.
Las convenciones existentes en cada área prevalecen frente a introducir una variación aislada.
---
## 10. TypeScript
Preservar la seguridad de tipos.
### Imports de tipos
Usar imports explícitos mediante `import type` para dependencias utilizadas exclusivamente como tipos:
```ts
import type { UniqueID } from "@repo/rdx-ddd";
import type { Result } from "@repo/rdx-utils";
```
No usar referencias inline en código fuente ordinario:
```ts
// No permitido
companyId: import("@repo/rdx-ddd").UniqueID;
```
Reglas:
* usar `import type { ... } from "..."` para toda dependencia utilizada exclusivamente como tipo;
* mantener imports de tipos en la cabecera del fichero;
* separar imports de tipos y runtime cuando sea claro hacerlo;
* no introducir imports de runtime para símbolos usados solo como tipos;
* permitir tipos inline únicamente en `.d.ts`, module augmentation, código generado o casos excepcionales técnicamente justificados.
### Seguridad de tipos
* Evitar `any`.
* Usar `unknown` cuando el tipo todavía no sea conocido.
* No usar type assertions salvo que exista una garantía verificable que el compilador no pueda inferir.
* Evitar `!` salvo que la invariante esté demostrada localmente.
* Preferir tipos semánticos frente a primitivas genéricas.
* Modelar conjuntos cerrados mediante unions o enums existentes.
* Mantener exhaustividad en `switch` para conjuntos cerrados.
* No introducir `default` cuando oculte casos no contemplados que puedan comprobarse exhaustivamente.
* No duplicar tipos derivados de schemas Zod.
* No utilizar `Partial<T>` cuando el schema o tipo de entrada ya modele explícitamente la opcionalidad.
* Mantener inmutabilidad cuando no exista necesidad real de mutación.
No modificar contratos públicos sin revisar previamente productores y consumidores.
Al modificar:
* DTOs;
* schemas;
* APIs;
* eventos;
* modelos persistidos;
* tipos compartidos;
revisar su uso completo.
---
## 11. `Result`, `Maybe` y `Collection`
Usar los patrones del proyecto:
* `Result` para operaciones que pueden fallar;
* `Maybe` para ausencia semántica;
* `Collection` para conjuntos de objetos del mismo tipo cuando el dominio requiera comportamiento propio.
No sustituirlos por:
* excepciones;
* `null`;
* arrays;
* tipos ad hoc;
cuando el patrón correspondiente sea aplicable.
No utilizar excepciones para representar flujo de negocio esperado salvo que el diseño concreto del módulo lo establezca expresamente.
Los errores esperables deben modelarse mediante contratos explícitos.
---
## 12. Zod y DTOs
Zod es la fuente única de verdad para los contratos HTTP.
Reglas:
* inferir tipos mediante `z.infer<typeof Schema>`;
* no duplicar DTOs mediante interfaces manuales equivalentes;
* cada endpoint debe disponer de DTOs de request y response;
* reutilizar subschemas únicamente cuando sean estables y realmente compartidos;
* no mezclar validación de transporte con lógica de negocio;
* evitar `.default()` en DTOs de negocio salvo necesidad justificada;
* evitar `.transform()` en DTOs de negocio salvo necesidad justificada;
* diferenciar explícitamente:
* campo omitido;
* `null`;
* cadena vacía;
* colección vacía;
* utilizar schemas semánticos para:
* UUID;
* fechas;
* timestamps;
* porcentajes;
* importes;
* cantidades;
* los valores decimales exactos no deben viajar como `number`.
No mantener una interfaz manual que reproduzca exactamente un schema Zod.
---
## 13. Flujo de entrada backend
Para el flujo habitual:
```text
RequestDTO
↓
UseCase({ dto, context })
↓
InputMapper
↓
Value Objects / Props
```
`RequestMapper -> Command` es opcional.
Solo debe utilizarse cuando exista una adaptación HTTP real, por ejemplo:
* combinar `body`, `params` y `query`;
* adaptar estructuras de transporte;
* resolver diferencias reales entre transporte y aplicación.
No crear `RequestMapper` únicamente para renombrar campos que Application volverá a transformar.
---
## 14. Casos de uso
Los casos de uso deben:
* orquestar;
* gestionar transacciones cuando corresponda;
* delegar responsabilidades específicas en servicios de aplicación;
* devolver `Result`;
* construir respuestas mediante builders o mappers de salida.
No deben:
* contener lógica HTTP;
* utilizar Express;
* utilizar Sequelize directamente;
* utilizar modelos ORM;
* construir agregados directamente desde DTOs HTTP;
* asumir responsabilidades propias de repositorios;
* asumir responsabilidades propias de controllers;
* asumir responsabilidades propias de infraestructura.
---
## 15. Servicios de aplicación
Preferir servicios:
* pequeños;
* explícitos;
* con una responsabilidad concreta;
* nombrados según su función real.
Evitar nombres genéricos como:
* `Manager`;
* `GenericService`;
* `CommandService`;
* `BaseRepository`;
* `Helper` sin semántica concreta.
No convertir un servicio de aplicación en un contenedor genérico de lógica no relacionada.
---
## 16. Repositorios
* Cada repositorio gestiona un agregado o una responsabilidad concreta.
* Sequelize no debe salir de Infrastructure.
* Los repositorios deben usar mappers de persistencia.
* No crear repositorios base genéricos sin necesidad demostrada.
* Los repositorios no se comparten entre módulos.
* No exponer repositorios como API pública de un módulo.
* Mantener aislamiento por `companyId` y `branchId` cuando corresponda.
No utilizar modelos Sequelize como contratos públicos.
---
## 17. Mappers de persistencia
Utilizar un mapper bidireccional por agregado:
```ts
toPersistence();
toDomain();
```
El mapper es responsable de traducir entre:
* representación de dominio;
* representación persistida.
Infrastructure debe reconstruir entidades mediante `rehydrate()`.
No introducir lógica de negocio nueva dentro del mapper.
---
## 18. `create()` y `rehydrate()`
Mantener separadas ambas operaciones.
```text
create()
creación funcional
valida invariantes
puede fallar
devuelve Result
```
```text
rehydrate()
reconstrucción desde persistencia
no valida reglas de creación
no genera eventos
no devuelve Result
```
Reglas:
* Infrastructure utiliza `rehydrate()`.
* Application y Domain utilizan `create()` para instancias nuevas.
* `update()` no utiliza `create()` ni `rehydrate()`.
* Los Value Objects no tienen `rehydrate()`.
* Los Value Objects se reconstruyen mediante `create()`.
No utilizar `create()` para reconstruir automáticamente una entidad ya válida almacenada en persistencia.
---
## 19. Comunicación entre módulos
Los módulos únicamente deben colaborar mediante servicios públicos explícitos.
No exponer entre módulos:
* repositorios;
* modelos Sequelize;
* mappers internos;
* servicios de escritura internos;
* detalles de Infrastructure.
No importar Infrastructure interna de otro módulo.
Cada módulo debe mantener su propio composition root.
Las dependencias entre módulos deben ser explícitas.
---
## 20. Snapshots y builders de respuesta
Los schemas Zod definen el contrato de salida.
Los snapshot builders materializan ese contrato.
Reglas:
* tipar el builder mediante el DTO inferido del schema exacto;
* no crear interfaces `I*Snapshot` que dupliquen un DTO;
* el builder debe ser determinista;
* el builder no debe contener lógica de negocio;
* puede transformar `Maybe` a `null`;
* puede transformar Value Objects a primitivas;
* puede transformar enums internos a valores del contrato;
* no puede acceder a repositorios;
* no puede acceder a Infrastructure;
* si cambia el schema, el builder debe producir un error de compilación si deja de satisfacer el contrato.
---
## 21. Comentarios
Los comentarios deben aportar información que el código no expresa por sí solo.
Deben explicar cuando corresponda:
* por qué existe una decisión;
* qué riesgo evita;
* qué contrato debe respetarse;
* qué efectos laterales son relevantes;
* qué error se evita;
* qué invariantes existen;
* qué limitaciones no son evidentes.
No deben limitarse a traducir el código a lenguaje natural.
Documentar con TSDoc las APIs públicas cuando aporte información sobre:
* propósito;
* parámetros;
* valor devuelto;
* errores;
* efectos laterales;
* invariantes;
* restricciones.
Después de un refactor, actualizar o eliminar comentarios obsoletos.
---
## 22. Documentación del proyecto
La documentación:
* se redacta en castellano;
* reside en `/docs`;
* utiliza Markdown;
* utiliza nombres de fichero en castellano.
Reglas de estilo:
* lenguaje claro;
* frases directas;
* evitar ambigüedad;
* evitar frases rebuscadas o innecesariamente largas;
* evitar tecnicismo innecesario;
* utilizar terminología técnica cuando sea necesaria para ser preciso;
* no convertir documentación en una transcripción del código;
* evitar párrafos densos cuando una explicación más breve sea suficiente.
Priorizar explicar:
```text
qué hace el sistema
por qué existe una regla
qué comportamiento debe esperarse
qué restricciones deben respetarse
```
No duplicar documentación.
Cuando exista un documento autoritativo, actualizarlo en lugar de crear otro equivalente.
---
## 23. Manejo de errores
Seguir la estrategia de errores existente.
No:
* ocultar errores silenciosamente;
* transformar fallos en resultados exitosos para continuar;
* sustituir errores específicos por errores genéricos sin motivo;
* utilizar logging como sustituto del tratamiento de errores;
* ignorar promesas rechazadas;
* ocultar excepciones inesperadas.
Preservar contexto suficiente para diagnosticar fallos sin exponer información sensible.
Usar errores tipados y predecibles.
Mantener contratos de error estables.
Mapear errores de Domain y Application a HTTP en Infrastructure.
No devolver:
* SQL;
* stack traces;
* detalles internos;
* información sensible.
---
## 24. Operaciones asíncronas
El proyecto aplica:
```text
lint/complexity/noVoid
```
Está prohibido utilizar `void` para descartar una promesa.
No generar:
```ts
void handleDuplicate();
void handleDownload();
void asyncOperation();
```
Toda `Promise` debe gestionarse explícitamente.
### Esperar
```ts
await operation();
```
### Devolver
```ts
return operation();
```
### Gestionar explícitamente el fallo
```ts
operation().catch(handleUnexpectedError);
```
La última opción solo procede en operaciones deliberadamente no bloqueantes.
Reglas:
* no eliminar `void` dejando una promesa flotante;
* no utilizar `.catch(() => undefined)` para silenciar errores;
* antes de convertir un callback a `async`, comprobar su contrato;
* si el contrato exige `void`, encapsular la operación y gestionar explícitamente el error;
* no utilizar `void` como mecanismo para indicar intención.
---
## 25. Integridad de datos
Cuando se modifique persistencia o lógica transaccional, comprobar:
* atomicidad;
* consistencia;
* rollback;
* concurrencia;
* aislamiento;
* integridad referencial;
* compatibilidad con datos existentes.
No asumir que una escritura satisfactoria implica que la operación funcional completa haya terminado correctamente.
Cuando una invariante crítica pueda garantizarse también en base de datos, aplicar esa protección además de la validación de aplicación cuando resulte razonable.
Preservar especialmente:
* usuarios;
* expedientes;
* OF;
* tareas;
* imputaciones de tiempo;
* errores;
* históricos;
* registros de actividad;
* configuraciones funcionales;
* trazabilidad.
No eliminar físicamente información con histórico cuando corresponda desactivarla.
---
## 26. Seguridad
Aplicar el principio de menor privilegio.
No:
* introducir secretos en el repositorio;
* registrar datos sensibles;
* confiar automáticamente en identificadores enviados por el cliente;
* confiar en permisos enviados por el cliente;
* interpolar manualmente SQL.
Validar toda entrada externa.
Usar consultas parametrizadas y APIs seguras de Sequelize.
Revisar:
* autenticación;
* autorización;
* aislamiento tenant;
* permisos;
* contexto autenticado.
Validar autorización además de autenticación.
No confiar en identificadores de compañía enviados por el cliente sin contrastarlos con el contexto autenticado.
Mantener aislamiento multiempresa en todas las consultas y mutaciones.
---
## 27. Idempotencia
Aplicar idempotencia en operaciones que puedan repetirse.
Especialmente revisar:
* comandos repetibles;
* peticiones reenviadas;
* reintentos de infraestructura;
* operaciones de creación;
* integraciones;
* migraciones;
* procesos de actualización.
Una repetición accidental no debe producir efectos duplicados cuando la semántica de la operación requiera idempotencia.
---
## 28. Base de datos y Sequelize
* Mantener nombres de tablas y columnas coherentes con las convenciones existentes.
* No introducir modelos Sequelize fuera de Infrastructure.
* No permitir acceso directo a modelos Sequelize desde Application o Domain.
* Ejecutar operaciones agregadas dentro de una transacción cuando deban ser atómicas.
* Diseñar migraciones idempotentes cuando corresponda al procedimiento del proyecto.
* No eliminar columnas, tablas o datos legacy sin auditoría previa.
* No confiar exclusivamente en validaciones de aplicación cuando una invariante crítica pueda reforzarse en base de datos.
* No utilizar `JSON.stringify` para detectar cambios de dominio.
* Comparar Value Objects semánticamente mediante primitivas o métodos de igualdad apropiados.
* Preservar compatibilidad con datos existentes.
Sequelize no debe convertirse en parte de contratos públicos.
---
## 29. Frontend
Mantener según los patrones existentes:
* React;
* TanStack Query;
* TanStack Table;
* React Hook Form;
* Zod;
* shadcn/ui;
* Tailwind;
* i18n.
Reglas:
* no duplicar estado remoto en estado local sin necesidad;
* mantener operaciones de servidor en TanStack Query;
* centralizar query keys según la convención existente;
* invalidar o actualizar caché explícitamente después de mutaciones;
* no introducir efectos para derivar estado calculable durante render;
* evitar componentes monolíticos;
* extraer responsabilidades cuando exista una frontera semántica clara;
* no extraer componentes triviales que solo oculten JSX;
* mantener accesibilidad;
* contemplar estados:
* `disabled`;
* `loading`;
* `empty`;
* `error`;
* no eliminar acciones no disponibles si la UX requiere mostrarlas deshabilitadas;
* mantener traducciones en `es` y `en` al añadir textos visibles;
* no insertar textos directamente cuando el área utilice i18n;
* utilizar `tabular-nums` en columnas monetarias cuando corresponda;
* preservar comportamiento responsive.
---
## 30. APIs
* Usar errores tipados y predecibles.
* Mantener contratos de error estables.
* Mapear errores de Domain y Application a HTTP en Infrastructure.
* Aplicar idempotencia en operaciones repetibles.
* Validar autorización antes de acceder o modificar datos.
* Mantener aislamiento tenant.
* No confiar en identificadores de compañía proporcionados por el cliente sin verificar el contexto autenticado.
* Registrar información suficiente para diagnosticar fallos sin exponer información sensible.
* No devolver detalles internos.
---
## 31. Dependencias
No añadir ni actualizar dependencias salvo necesidad real.
Antes de añadir una dependencia:
1. comprobar si el proyecto ya proporciona funcionalidad equivalente;
2. justificar por qué es necesaria;
3. evaluar mantenimiento;
4. evaluar compatibilidad;
5. revisar impacto en bundle o runtime.
No modificar lockfiles innecesariamente.
No actualizar PNPM como efecto colateral de otra tarea.
No añadir supresiones de:
* TypeScript;
* Biome;
* ESLint;
* otras herramientas de análisis;
sin justificar el motivo.
---
## 32. Tests
Añadir o actualizar tests cuando cambie comportamiento observable.
Preferir tests de:
* comportamiento;
* contratos;
* invariantes;
* casos límite;
frente a detalles accidentales de implementación.
En bugs, añadir test de regresión cuando sea viable.
Cubrir cuando corresponda:
* caso válido;
* caso inválido;
* límites;
* errores;
* idempotencia;
* autorización;
* concurrencia.
Mantener tests deterministas.
No utilizar esperas arbitrarias.
No desactivar tests para conseguir una suite verde.
---
## 33. Estrategia de validación
Usar primero la validación más acotada que aporte evidencia suficiente.
Orden habitual:
```text
test específico
↓
tests del módulo / paquete
↓
typecheck del módulo
↓
lint del módulo
↓
integration tests
↓
E2E
↓
validación global
```
Preferir:
```bash
pnpm --filter <workspace> typecheck
pnpm --filter <workspace> lint
pnpm --filter <workspace> test
```
cuando la validación del workspace resulte suficiente.
Ejecutar validación global cuando el cambio afecte:
* paquetes compartidos;
* contratos públicos;
* configuración transversal;
* varios módulos;
* infraestructura común.
Antes de finalizar, ejecutar según corresponda:
```bash
pnpm typecheck
pnpm lint
pnpm test
```
Y cuando sea aplicable:
```bash
pnpm check
pnpm build
```
No ejecutar validaciones globales costosas si una comprobación dirigida aporta evidencia suficiente, salvo que el riesgo lo justifique.
Informar exactamente de los comandos ejecutados.
No considerar completada una tarea con errores conocidos de:
* typecheck;
* lint;
* tests;
* build;
salvo que el usuario haya limitado expresamente el alcance.
---
## 34. Fallos preexistentes
Distinguir claramente:
* fallos causados por el cambio actual;
* fallos preexistentes;
* fallos ajenos al área modificada;
* validaciones no ejecutadas.
No atribuir un fallo existente al cambio sin evidencia.
No declarar un fallo como preexistente sin haberlo comprobado cuando la distinción resulte relevante.
No ocultar fallos de:
* compilación;
* typecheck;
* lint;
* tests;
* build.
---
## 35. Comandos
Usar herramientas y scripts propios del repositorio.
Antes de ejecutar comandos, revisar:
* `package.json`;
* scripts;
* configuración;
* workspaces;
* documentación.
No inventar comandos si pueden obtenerse directamente del repositorio.
### Instalación
```bash
N/A — obtener del package.json/documentación del repositorio
```
### Desarrollo
```bash
N/A — obtener del package.json/documentación del repositorio
```
### Tests
```bash
pnpm test
```
### Typecheck
```bash
pnpm typecheck
```
### Lint
```bash
pnpm lint
```
### Check
```bash
pnpm check
```
### Build
```bash
pnpm build
```
Los comandos anteriores deben utilizarse únicamente si existen como scripts reales del repositorio.
Preferir comandos acotados al workspace cuando sean suficientes.
---
## 36. Refactors
Un refactor debe preservar comportamiento salvo indicación expresa en contrario.
No mezclar refactors amplios con cambios funcionales sin necesidad.
Para refactors grandes:
1. auditar el estado actual;
2. identificar referencias y consumidores;
3. definir fases;
4. ejecutar cambios incrementales;
5. validar entre fases;
6. eliminar legacy únicamente cuando se haya demostrado que ya no es necesario.
---
## 37. Eliminación de código legacy
Antes de eliminar código aparentemente obsoleto:
1. buscar referencias en todo el monorepo;
2. revisar imports;
3. revisar rutas;
4. revisar entry points;
5. revisar composition roots;
6. revisar DI;
7. revisar modelos;
8. revisar repositorios;
9. revisar mappers;
10. revisar tests;
11. revisar scripts;
12. revisar documentación.
Clasificar las referencias como:
* activas;
* legacy no cableado;
* migraciones;
* documentación;
* tests;
* falsos positivos.
Eliminar únicamente aquello demostrado como no utilizado.
Ejecutar después:
* typecheck relevante;
* lint relevante;
* tests relevantes.
Documentar cualquier referencia residual y el motivo de conservarla.
---
## 38. Archivos generados
No modificar manualmente archivos generados salvo que el proyecto lo requiera.
Cuando un cambio necesite regenerarlos, utilizar el procedimiento oficial.
No incluir artefactos generados no relacionados con la tarea.
---
## 39. Higiene Git
Mantener cambios pequeños y revisables.
Preferir una unidad lógica por conjunto de cambios.
Antes de finalizar:
```bash
git status --short
git diff
```
Revisar el diff para detectar:
* modificaciones no relacionadas;
* cambios accidentales de formato;
* código temporal;
* logs de depuración;
* archivos generados inesperados;
* secretos;
* cambios en lockfiles no justificados.
No reescribir historial ajeno a la tarea.
No realizar:
* commits;
* pushes;
* resets destructivos;
* modificaciones de historial;
salvo petición expresa o flujo explícito del proyecto.
---
## 40. Criterios de finalización
Una tarea solo debe marcarse como completa cuando:
* se haya implementado el comportamiento solicitado;
* se respete la arquitectura;
* el alcance solicitado esté cubierto;
* las validaciones relevantes se hayan ejecutado;
* los errores introducidos por el cambio estén resueltos;
* no existan cambios accidentales;
* se hayan indicado las limitaciones conocidas.
Estados:
```text
COMPLETA
PARCIAL
BLOQUEADA
```
Si una validación requerida no puede realizarse, indicarlo.
No afirmar que algo:
* compila;
* funciona;
* pasa tests;
* está corregido;
* está validado;
sin evidencia.
---
## 41. Informe final
Al terminar una tarea relevante, indicar:
1. **Estado:** COMPLETA / PARCIAL / BLOQUEADA
2. **Diagnóstico o causa raíz**
3. **Cambios realizados**
4. **Decisiones relevantes**
5. **Archivos principales modificados**
6. **Comandos de validación ejecutados**
7. **Resultado de las validaciones**
8. **Riesgos o pendientes reales**
Evitar informes excesivamente largos para tareas sencillas.
---
## 42. Fuente de verdad
Cuando exista información contradictoria, no asumir automáticamente qué fuente es correcta.
### Instrucciones operativas
Orden general:
1. requisitos explícitos de la tarea;
2. `AGENTS.md` más cercano al archivo modificado;
3. `AGENTS.md` de niveles superiores;
4. este `AGENTS.md` raíz;
5. convenciones existentes en el área;
6. preferencias generales del agente.
### Comportamiento e invariantes del producto
Orden general:
1. requisitos explícitos y vigentes del producto;
2. documentación normativa vigente;
3. contratos públicos e invariantes establecidas;
4. tests que expresen comportamiento intencionado;
5. implementación actual;
6. documentación auxiliar;
7. contexto de conversaciones;
8. suposiciones.
Los tests no deben considerarse automáticamente correctos cuando contradigan de forma evidente una fuente normativa vigente.
Un `AGENTS.md` no debe utilizarse para invalidar silenciosamente una regla funcional o arquitectónica normativa.
Si código, tests y documentación discrepan de forma relevante, investigar la discrepancia antes de modificar comportamiento.
---
## 43. Regla de precedencia
En caso de conflicto entre instrucciones operativas:
1. instrucciones explícitas del usuario para la tarea actual;
2. `AGENTS.md` más cercano al archivo modificado;
3. `AGENTS.md` de niveles superiores;
4. este `AGENTS.md` raíz;
5. convenciones existentes del área;
6. preferencias generales del agente.
Una instrucción de nivel inferior puede concretar o restringir otra superior dentro de su ámbito.
La documentación normativa gobierna:
* comportamiento funcional;
* arquitectura;
* contratos;
* invariantes del producto.
Si una instrucción contradice:
* arquitectura normativa;
* una invariante crítica;
* una regla de seguridad;
* un contrato público establecido;
investigar y señalar el conflicto antes de introducir el cambio.