@bi-analytics/arness-back 0.0.0-stage → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/CHANGELOG.md +85 -0
  2. package/README.md +156 -2
  3. package/bin/arness.mjs +710 -0
  4. package/harness/AGENTS.md +238 -0
  5. package/harness/agents/implementador.md +42 -0
  6. package/harness/agents/lider.md +72 -0
  7. package/harness/agents/revisor.md +62 -0
  8. package/harness/decisiones/README.md +17 -0
  9. package/harness/decisiones/_plantilla.md +24 -0
  10. package/harness/init.sh +743 -0
  11. package/harness/playbooks/add-database.md +16 -0
  12. package/harness/playbooks/new-endpoint.md +88 -0
  13. package/harness/playbooks/new-module.md +21 -0
  14. package/harness/playbooks/new-monitor-widget.md +31 -0
  15. package/harness/playbooks/review.md +41 -0
  16. package/harness/playbooks/update-node-lts.md +46 -0
  17. package/harness/reference/configuracion.md +111 -0
  18. package/harness/reference/contrato-http.md +169 -0
  19. package/harness/reference/novedades.json +158 -0
  20. package/harness/reference/progress-plantilla.md +50 -0
  21. package/harness/skills/commit-hygiene/SKILL.md +137 -0
  22. package/harness/skills/nest-base/SKILL.md +168 -0
  23. package/harness/skills/nest-base/templates/config/auth.spec.ts +32 -0
  24. package/harness/skills/nest-base/templates/config/auth.ts +80 -0
  25. package/harness/skills/nest-base/templates/config/configuration.spec.ts +85 -0
  26. package/harness/skills/nest-base/templates/config/configuration.ts +137 -0
  27. package/harness/skills/nest-base/templates/cors/cors.spec.ts +53 -0
  28. package/harness/skills/nest-base/templates/cors/cors.ts +75 -0
  29. package/harness/skills/nest-base/templates/docs/EVOLUTIVO.md +27 -0
  30. package/harness/skills/nest-base/templates/docs/PENDIENTES.md +20 -0
  31. package/harness/skills/nest-base/templates/docs/TECNICO.md +43 -0
  32. package/harness/skills/nest-base/templates/e2e/cors.e2e-spec.ts +60 -0
  33. package/harness/skills/nest-base/templates/e2e/monitor.e2e-spec.ts +151 -0
  34. package/harness/skills/nest-base/templates/editorconfig +12 -0
  35. package/harness/skills/nest-base/templates/eslint.boundaries.mjs +65 -0
  36. package/harness/skills/nest-base/templates/eslint.config.mjs +82 -0
  37. package/harness/skills/nest-base/templates/logging/logger-options.spec.ts +57 -0
  38. package/harness/skills/nest-base/templates/logging/logger-options.ts +85 -0
  39. package/harness/skills/nest-base/templates/monitor/monitor-login-redirect.filter.ts +16 -0
  40. package/harness/skills/nest-base/templates/monitor/monitor-login.dto.ts +8 -0
  41. package/harness/skills/nest-base/templates/monitor/monitor-page.spec.ts +41 -0
  42. package/harness/skills/nest-base/templates/monitor/monitor-page.ts +190 -0
  43. package/harness/skills/nest-base/templates/monitor/monitor-session.guard.spec.ts +46 -0
  44. package/harness/skills/nest-base/templates/monitor/monitor-session.guard.ts +36 -0
  45. package/harness/skills/nest-base/templates/monitor/monitor-session.service.spec.ts +57 -0
  46. package/harness/skills/nest-base/templates/monitor/monitor-session.service.ts +77 -0
  47. package/harness/skills/nest-base/templates/monitor/monitor-widget.interface.ts +18 -0
  48. package/harness/skills/nest-base/templates/monitor/monitor.constants.ts +25 -0
  49. package/harness/skills/nest-base/templates/monitor/monitor.controller.ts +84 -0
  50. package/harness/skills/nest-base/templates/monitor/monitor.decorators.ts +11 -0
  51. package/harness/skills/nest-base/templates/monitor/monitor.module.ts +30 -0
  52. package/harness/skills/nest-base/templates/monitor/monitor.service.spec.ts +55 -0
  53. package/harness/skills/nest-base/templates/monitor/monitor.service.ts +49 -0
  54. package/harness/skills/nest-base/templates/monitor/widgets/endpoints-total.widget.spec.ts +51 -0
  55. package/harness/skills/nest-base/templates/monitor/widgets/endpoints-total.widget.ts +53 -0
  56. package/harness/skills/nest-base/templates/prettierignore +6 -0
  57. package/harness/skills/nest-base/templates/prettierrc.json +8 -0
  58. package/harness/skills/nest-base/templates/security/login-attempts.spec.ts +48 -0
  59. package/harness/skills/nest-base/templates/security/login-attempts.ts +90 -0
  60. package/harness/skills/nest-base/templates/security/security-headers.spec.ts +27 -0
  61. package/harness/skills/nest-base/templates/security/security-headers.ts +21 -0
  62. package/harness/skills/nest-base/templates/security/security.module.ts +20 -0
  63. package/harness/skills/nest-base/templates/security/session-lifetime.spec.ts +21 -0
  64. package/harness/skills/nest-base/templates/security/session-lifetime.ts +28 -0
  65. package/package.json +44 -3
package/CHANGELOG.md ADDED
@@ -0,0 +1,85 @@
1
+ # Changelog
2
+
3
+ Formato basado en [Keep a Changelog](https://keepachangelog.com/es-ES/1.1.0/) y [SemVer](https://semver.org/lang/es/):
4
+ - **major:** cambios de estructura o rutas del harness, con migración en `arness sync`;
5
+ - **minor:** reglas, playbooks, skills o checks nuevos compatibles;
6
+ - **patch:** correcciones.
7
+
8
+ ## [Sin publicar]
9
+
10
+ ### Agregado
11
+ - **Última LTS de Node** (ADR 0015): `init.sh` compara `.nvmrc` con la última LTS de `nodejs.org` y advierte `toolchain.node-lts` si hay un major más nuevo; sin red lo omite. `NODE_LTS_VERSION` fija la LTS de referencia (`off` desactiva). Playbook `update-node-lts.md`: el agente analiza el impacto, lo presenta y actualiza solo con aprobación humana. AGENTS.md §0 y §16, agente `lider` y pistas de `doctor`.
12
+ - **Endurecimiento de la autenticación** (ADR 0017), sin dependencias nuevas:
13
+ - plantillas `templates/security/` (`LoginAttemptLimiter`, `securityHeaders()`, `sessionClaims` / `isSessionExpired` y `SecurityModule`) y `templates/config/auth.ts` (`parseAuthConfig`, bloque `auth` de la configuración), con specs;
14
+ - límite de intentos por IP en `/auth/login` y `/monitor/login` (`429 TOO_MANY_ATTEMPTS` con `Retry-After`);
15
+ - vida máxima de la sesión con `auth_time` (`401 SESSION_EXPIRED`);
16
+ - cabeceras de seguridad en toda respuesta;
17
+ - variables `AUTH_LOGIN_MAX_ATTEMPTS`, `AUTH_LOGIN_WINDOW_SECONDS`, `AUTH_SESSION_MAX_AGE_SECONDS` y `HTTP_TRUST_PROXY_HOPS`;
18
+ - `init.sh`: `security.headers`, `security.trust-proxy`, `security.login-rate-limit`, y `security.session-max-age`; tres novedades de seguridad en `doctor`;
19
+ - `auth.e2e-spec.ts` exige que la cookie del monitor y el refresh token no sirvan como `Bearer`.
20
+
21
+ ### Cambiado
22
+ - El monitor comparte el límite de intentos del login: `templates/monitor/monitor.controller.ts` y `templates/e2e/monitor.e2e-spec.ts` usan `LoginAttemptLimiter`.
23
+ - `arness sync` solo anuncia las novedades hasta la versión que instala (antes también mostraba las de versiones posteriores presentes en el catálogo).
24
+ - **Evolutivo con hora y responsable** (ADR 0016): cada entrada de `docs/EVOLUTIVO.md` lleva fecha, hora y zona de Bogotá (`AAAA-MM-DD HH:mm -0500`) y el responsable (`git config user.name`). Plantilla, AGENTS.md §12, `new-endpoint`, `review.md`, `revisor` y `nest-base`.
25
+
26
+ ### Para proyectos existentes
27
+ - `init.sh` puede mostrar la advertencia nueva `toolchain.node-lts`. No rompe nada: el agente propone el análisis y solo actualiza Node si lo apruebas. Si no, queda en `docs/PENDIENTES.md`.
28
+ - Las entradas existentes de `docs/EVOLUTIVO.md` no se reescriben: el formato nuevo aplica desde la siguiente entrega. Verifica que cada persona tenga `git config user.name`.
29
+ - **Seguridad:** `init.sh` mostrará `security.*` nuevos como advertencias y `pnpm arness doctor` los lista con sus pasos. Ninguna impide arrancar: los secretos actuales siguen sirviendo. Al adoptar la vida máxima de la sesión, los usuarios con un refresh token anterior deberán volver a iniciar sesión. Detrás de Azure App Service, define `HTTP_TRUST_PROXY_HOPS=1`. Avisa a frontend de `429 TOO_MANY_ATTEMPTS` y `401 SESSION_EXPIRED`.
30
+
31
+ ## [0.2.0] - 2026-10-23
32
+
33
+ ### Cambiado
34
+ - **Distribución por npm** (ADR 0013 y 0014, reemplaza a 0004): el paquete se publica en el registro público de npm como `@bi-analytics/arness-back`. Se instala con `pnpm add -D @bi-analytics/arness-back@X.Y.Z` (o `pnpm dlx @bi-analytics/arness-back@X.Y.Z init` en un repo sin `package.json`), sin acceso al repo de GitHub. La skill `nest-base` y el mensaje de `arness init` usan el nombre del paquete.
35
+ - `init.sh` ya no bloquea por defecto: los hallazgos son **advertencias** y termina en 0, con un resumen por categoría. Cada chequeo tiene un id (`categoria.nombre`).
36
+ - Única excepción crítica: `.env` o `.env.local` versionado en git sigue terminando en 1 y no se puede silenciar.
37
+ - AGENTS.md §0 y §15, agentes `lider`, `implementador` y `revisor`, y `review.md`: el agente reporta las advertencias y continúa, sin corregir lo que está fuera de alcance ni introducir advertencias nuevas.
38
+ - `arness sync` respalda la base anterior en `harness/.arness-backup/` antes de escribir y ya no modifica `.gitignore`. Sin cambios no crea respaldo.
39
+ - La skill `nest-base` verifica el proyecto nuevo con `./harness/init.sh --strict`. El CI del paquete también usa `--strict`.
40
+ - La detección de SQL fuera de `*.sql.ts` (ESLint e `init.sh`) reconoce consultas tras saltos de línea o `(` y las escrituras `INSERT INTO`, `UPDATE … SET`, `DELETE FROM` y `MERGE INTO`, sin marcar enums como `SELECT = 'x'` ni `'DELETE'` como método HTTP.
41
+ - AGENTS.md §5: la regla de agrupación cuenta archivos del mismo tipo **en una misma carpeta**, y los specs mínimos por endpoint son de controller, service, repository, sql y query DTO.
42
+ - El repo del paquete tiene `eslint` como devDependency para sus pruebas; el CI ejecuta `pnpm install --frozen-lockfile` antes de los tests. No afecta a los proyectos instalados.
43
+
44
+ ### Agregado
45
+ - `init.sh --strict` (comportamiento anterior) y `--json` (salida para agentes y pipelines).
46
+ - `harness/arness.config.json` (opcional, del repo; `sync` no lo toca): `strict`, `ignore` con motivo y `required`.
47
+ - `arness rollback [--dry-run] [--force]`: restaura la base desde el último respaldo.
48
+ - `arness doctor [--full]`: qué le falta al proyecto para cumplir la versión instalada, sin modificar nada.
49
+ - `arness sync --diff`: diff línea a línea de cada archivo de la base.
50
+ - Tests de compatibilidad: sincronizar un proyecto instalado no cambia ningún archivo fuera de la base, `init.sh` sigue en 0 y `rollback` restaura la base exacta.
51
+ - ADR 0005.
52
+ - **CORS con allowlist por entorno** (ADR 0006): regla en AGENTS.md §9 y §13, detalle en `contrato-http.md`, variables `CORS_ORIGINS` (obligatoria en proyectos nuevos) y `CORS_MAX_AGE_SECONDS` en `configuracion.md`, plantilla `templates/cors/` (`cors.ts` + spec) y e2e `templates/e2e/cors.e2e-spec.ts` en `nest-base`. `init.sh`: `security.cors-env`, `security.cors` y `security.cors-open`. `review.md`: CORS abierto o con comodín es bloqueante.
53
+ - **Fronteras de arquitectura verificadas** (ADR 0007): plantilla `eslint.boundaries.mjs` (`@typescript-eslint/no-restricted-imports`, sin dependencias nuevas) que impide importar `modules/` desde `common/` y entre módulos o clientes. `init.sh`, sección Arquitectura: `architecture.eslint-boundaries`, `architecture.common-imports-modules`, `architecture.module-imports`, `architecture.grouping` y `architecture.endpoint-files`. Prueba `test/eslint-boundaries.test.mjs` con casos de imports prohibidos y permitidos.
54
+ - **Tablero monitor** (ADR 0008): `GET /monitor` renderizado en el servidor con React, sin JavaScript en el cliente, protegido por `ACCESS_TOKEN` con cookie de sesión y `MonitorSessionGuard`, cabeceras CSP, widgets `MonitorWidget` con el multi-provider `MONITOR_WIDGETS` y widget base `endpoints-total`. Plantillas `templates/monitor/` y `templates/e2e/monitor.e2e-spec.ts`, variables `MONITOR_ENABLED` y `MONITOR_SESSION_EXPIRES_IN`, playbook `new-monitor-widget.md`. `init.sh`: `security.monitor-env` y `security.monitor-guard`. `react` y `react-dom` pasan a dependencias aprobadas, solo para el monitor.
55
+ - **Configuración centralizada** (ADR 0009): `process.env` se lee solo en `src/config/configuration.ts` (plantilla `templates/config/` con `AppConfig`, `buildConfiguration` y spec; secretos sin valor por defecto). Regla §13.12 y §14 en AGENTS.md, sección "Dónde se leen las variables" en `configuracion.md`, `NODE_ENV` documentada. ESLint: `configBoundaries` en `eslint.boundaries.mjs` (`no-restricted-properties`). `init.sh`, sección Variables de entorno: `env.configuration-file`, `env.process-env` y `env.eslint`.
56
+ - **Formato de logs por entorno** (ADR 0010): `LOG_FORMAT=json|pretty` (default `json`; `pretty` rechazado con `NODE_ENV=production`). Plantilla `templates/logging/logger-options.ts` con spec: `buildLoggerParams`, `parseLogFormat`, `REDACT_PATHS` comunes, mensaje `MÉTODO ruta status duración` y `X-Request-Id` entrante solo si es seguro. `pino-pretty` aprobado solo como devDependency (AGENTS.md §2 y §10). `init.sh`, sección Logging: `logging.format-env` y `logging.pretty-production`.
57
+ - **Documentación del proyecto en `docs/`** (ADR 0011): plantillas `templates/docs/` con `TECNICO.md`, `EVOLUTIVO.md` (solo avance, una entrada por entrega) y `PENDIENTES.md` (pendientes, bloqueos, recomendaciones). AGENTS.md §4, §12 y §15, playbooks `new-endpoint`, `new-module`, `add-database` y `new-monitor-widget`, agentes y `review.md`. `FRONT.md` no cambia. `init.sh`: `docs.files`.
58
+ - **`arness doctor` con novedades por versión** (ADR 0012): catálogo `harness/reference/novedades.json` (tipo seguridad/recomendada/opcional, checks de `init.sh`, pasos, ADR y aprobación). `doctor` muestra versión instalada frente a la disponible, novedades por adoptar, adoptadas y declinadas, y el resto de los hallazgos; `--json` y `--since <versión>`. `harness/arness.config.json` acepta `declined` con motivo. `sync` anuncia las novedades de la versión destino. AGENTS.md §0 y agente `lider`: tras un `sync`, informar las novedades sin implementarlas.
59
+
60
+ ### Para proyectos existentes
61
+ - **Instalación desde npm con nombre nuevo** (ADR 0014): quita la devDependency `@linktic/arness-back` (`git+https://...#vX.Y.Z`) con `pnpm remove @linktic/arness-back`, instala `pnpm add -D @bi-analytics/arness-back@0.2.0` y ejecuta `pnpm arness sync`.
62
+ - **No hay cambios obligatorios.** Después de `pnpm arness sync`, `./harness/init.sh` puede mostrar advertencias que antes eran fallos: el proyecto sigue funcionando igual.
63
+ - Ejecuta `pnpm arness doctor`: lista las novedades de esta versión por adoptar, con sus pasos. Adóptalas cuando convenga o declínalas con motivo en `harness/arness.config.json` → `declined`.
64
+ - Si tienes `.env` o `.env.local` en git, `init.sh` terminará en 1: sácalo del índice (`git rm --cached .env`) y rota los secretos.
65
+ - Si quieres el comportamiento anterior, crea `harness/arness.config.json` con `{ "strict": true }`.
66
+ - Si algo no te convence: `pnpm arness rollback`.
67
+ - **CORS:** `init.sh` advertirá `security.cors-env` / `security.cors` hasta que lo adoptes. Copia `harness/skills/nest-base/templates/cors/cors.ts` (y su spec) a `src/config/`, valida `CORS_ORIGINS` al arrancar, cambia `app.enableCors(...)` en `src/main.ts` por `app.enableCors(buildCorsOptions(...))` y agrega `CORS_ORIGINS` y `CORS_MAX_AGE_SECONDS` a `.env.example` y `.env.local`. Antes de desplegar, define en cada entorno los orígenes de los frontends que consumen la API: con la allowlist, un origen no listado deja de funcionar desde el navegador.
68
+ - **Fronteras:** copia `templates/eslint.boundaries.mjs` a la raíz e impórtala en `eslint.config.mjs` (`...architectureBoundaries`). Si aparecen imports entre módulos, mueve lo compartido a `src/common/`. Los hallazgos de `architecture.*` son advertencias: corrígelos cuando toques ese módulo.
69
+ - **Configuración centralizada:** copia `harness/skills/nest-base/templates/config/` (`configuration.ts` y su spec) a `src/config/`, regístrala con `ConfigModule.forRoot({ ..., load: [configuration] })` y cambia, módulo por módulo, cada `process.env.X` por `ConfigService<AppConfig, true>`. Actualiza `eslint.boundaries.mjs` desde la plantilla y agrega `...configBoundaries` en `eslint.config.mjs`. Mientras tanto, `init.sh` muestra `env.*` como advertencias.
70
+ - **Logs (opcional):** sin `LOG_FORMAT` todo sigue en JSON. Para el formato legible en desarrollo: `pnpm add -D pino-pretty` (aprobado como devDependency en AGENTS.md §2 desde esta versión), copia `templates/logging/` a `src/common/logging/`, usa `buildLoggerParams` en `LoggerModule.forRootAsync`, agrega `LOG_FORMAT=json` a `.env.example` y `LOG_FORMAT=pretty` a `.env.local`. El mensaje por request pasa a `MÉTODO ruta status duración`: revisa alertas que busquen el texto "request completed".
71
+ - **`docs/`:** copia `harness/skills/nest-base/templates/docs/` a `docs/`, completa `TECNICO.md` con lo que ya existe y, si quieres, resume en `EVOLUTIVO.md` lo entregado hasta hoy. `sync` no lo crea; hasta entonces `init.sh` muestra `docs.files` como advertencia.
72
+ - **Monitor (opcional):** requiere aprobar `react` y `react-dom` en el proyecto. Copia `templates/monitor/` a `src/common/monitor/`, registra `MonitorModule`, excluye `monitor` del prefijo global, haz que `JwtAuthGuard` omita `IS_MONITOR_ROUTE_KEY` y agrega `MONITOR_ENABLED=false` y `MONITOR_SESSION_EXPIRES_IN=15m`. Sin `src/common/monitor/`, `init.sh` no verifica nada del monitor.
73
+
74
+ ## [0.1.0] - 2026-09-25
75
+
76
+ ### Agregado
77
+ - CLI `arness`: `init`, `sync`, `status`, `verify` y `decision new`.
78
+ - Base del harness en `harness/`:
79
+ - `AGENTS.md` e `init.sh`;
80
+ - agentes `lider`, `implementador` y `revisor`;
81
+ - skill `nest-base`;
82
+ - playbooks, referencias y plantilla de `progress.md`.
83
+ - Esqueleto de `harness/decisiones/`, que pertenece al repo instalador.
84
+ - Puentes para Claude Code, Codex, Gemini CLI y Cursor, con copia automática donde no hay symlinks.
85
+ - Instalación desde git con tags `vX.Y.Z` (sin registro npm).
package/README.md CHANGED
@@ -1,3 +1,157 @@
1
- # Temporary Holding Version
1
+ # @bi-analytics/arness-back
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Harness de agentes IA para los **backends NestJS de analítica**. Funciona con Claude Code, Codex, Gemini CLI y Cursor, e incluye:
4
+ - reglas (`AGENTS.md`);
5
+ - verificación de estado (`init.sh`);
6
+ - agentes `lider`, `implementador` y `revisor`;
7
+ - la skill `nest-base`;
8
+ - playbooks y referencias.
9
+
10
+ Se publica en el **registro público de npm** como `@bi-analytics/arness-back` (ADR 0013); cada versión tiene además su tag git `vX.Y.Z`. Las **decisiones de cada proyecto** (`harness/decisiones/`) quedan en el repo que lo instala, y el paquete nunca las modifica.
11
+
12
+ ## Requisitos
13
+
14
+ - Node.js ≥ 20, pnpm y git.
15
+
16
+ Para ver la última versión publicada:
17
+
18
+ ```bash
19
+ pnpm view @bi-analytics/arness-back version
20
+ ```
21
+
22
+ ## Instalación
23
+
24
+ Elige el caso según el estado del repo donde vas a instalarlo. En los comandos, `0.2.0` es la versión; usa la última de [CHANGELOG.md](CHANGELOG.md).
25
+
26
+ ### A. Repo nuevo, antes de crear el proyecto NestJS (sin `package.json`)
27
+
28
+ `pnpm add` crearía un `package.json` antes que Nest. Por eso el harness se instala con `pnpm dlx`, que ejecuta el CLI sin agregarlo al proyecto:
29
+
30
+ ```bash
31
+ cd mi-backend # carpeta del nuevo backend (con git init hecho)
32
+
33
+ pnpm dlx @bi-analytics/arness-back@0.2.0 init
34
+
35
+ ./harness/init.sh # debe quedar en verde (modo solo harness)
36
+ ```
37
+
38
+ Después, pide a tu agente **"crea la base del proyecto NestJS"** (skill `nest-base`). Por ejemplo en Claude Code: `claude --agent lider`, o `/nest-base`. La skill crea el proyecto en la raíz y agrega el harness como devDependency con la misma versión.
39
+
40
+ ### B. Proyecto que ya tiene `package.json`
41
+
42
+ ```bash
43
+ pnpm add -D @bi-analytics/arness-back@0.2.0
44
+ pnpm arness init
45
+ ./harness/init.sh
46
+ ```
47
+
48
+ Si el proyecto lo tenía instalado desde git (`git+https://...#vX.Y.Z`), basta con el `pnpm add` de arriba y `pnpm arness sync`.
49
+
50
+ ### Qué hace `arness init`
51
+
52
+ - Copia la base a `harness/` y crea `harness/decisiones/` con el README y la plantilla.
53
+ - Crea los puentes de la raíz: `AGENTS.md`, `CLAUDE.md`, `GEMINI.md`, `.cursor/rules/`, `.claude/` y `.agents/`.
54
+ - Escribe `harness/.arness.json` con la versión instalada y el hash de cada archivo de la base.
55
+ - Agrega `harness/progress.md` al `.gitignore`.
56
+
57
+ Luego haz commit de todo. El harness queda versionado y funciona recién clonado, antes de `pnpm install`.
58
+
59
+ ```
60
+ harness/
61
+ ├── .arness.json manifiesto: versión + hash de cada archivo gestionado
62
+ ├── AGENTS.md, init.sh, agents/, skills/, playbooks/, reference/ ← del paquete (no editar)
63
+ ├── decisiones/ ← del repo: se crea una vez y sync nunca la toca
64
+ ├── arness.config.json ← del repo, opcional: strict / ignore / required de init.sh
65
+ ├── .arness-backup/ ← respaldos de sync para arness rollback (ignorados en git)
66
+ └── progress.md ← del repo, no versionado
67
+ AGENTS.md → harness/AGENTS.md · CLAUDE.md · GEMINI.md · .cursor/rules/ · .claude/{agents,skills} · .agents/skills
68
+ ```
69
+
70
+ ## Uso diario
71
+
72
+ ```bash
73
+ ./harness/init.sh # o: pnpm arness verify
74
+ pnpm arness doctor # novedades por adoptar y hallazgos (no modifica nada)
75
+ pnpm arness decision new "Usar réplica de lectura" # nueva decisión en harness/decisiones/
76
+ pnpm arness status # versión instalada e integridad de la base
77
+ ```
78
+
79
+ ### `init.sh`: advertencias por defecto
80
+
81
+ Los hallazgos se muestran como advertencias (`⚠`) y el script termina en 0: el proyecto sigue funcionando. Al final aparece un resumen por categoría.
82
+
83
+ - **Crítico (siempre exit 1):** `.env` o `.env.local` versionado en git.
84
+ - `--strict`: los hallazgos fallan (exit 1). Recomendado en CI y en proyectos nuevos.
85
+ - `--json`: resultado para agentes y pipelines (`{ mode, exitCode, summary, issues: [{ level, id, section, message }] }`).
86
+
87
+ Configuración opcional del repo en `harness/arness.config.json` (sync no la toca):
88
+
89
+ ```json
90
+ {
91
+ "strict": false,
92
+ "ignore": { "toolchain.nvmrc": "La versión de Node la fija la plataforma de despliegue" },
93
+ "required": ["sql.write"]
94
+ }
95
+ ```
96
+
97
+ `ignore` silencia un chequeo y exige un motivo. `required` hace que un chequeo falle aunque no haya `--strict`. Los ids aparecen entre corchetes en la salida de `init.sh`. `declined` (`{ "monitor": "No aplica a este cliente" }`) marca una novedad que el repo decidió no adoptar; también exige motivo.
98
+
99
+ ### `arness doctor`: novedades por adoptar
100
+
101
+ Cada versión declara sus novedades en `harness/reference/novedades.json` (tipo **seguridad**, **recomendada** u **opcional**, con pasos, ADR y si requieren aprobación). `doctor` las cruza con `init.sh` y muestra, sin modificar nada:
102
+
103
+ - versión instalada frente a la del paquete, y aviso si hay una más nueva;
104
+ - novedades **por adoptar**, de seguridad a opcionales, con lo que falta y sus pasos;
105
+ - novedades ya adoptadas y declinadas (`declined` en `harness/arness.config.json`);
106
+ - el resto de los hallazgos de `init.sh`, por categoría.
107
+
108
+ `--json` da el mismo resultado para agentes y pipelines; `--since 0.2.0` muestra solo lo posterior a esa versión; `--full` incluye lint, build, tests y health. Nunca termina en 1 por novedades sin adoptar, solo por críticos.
109
+
110
+ ## Actualizar a una versión nueva
111
+
112
+ `pnpm outdated @bi-analytics/arness-back` muestra si hay una versión nueva.
113
+
114
+ ```bash
115
+ pnpm add -D @bi-analytics/arness-back@0.3.0
116
+ pnpm arness sync --dry-run --diff # ver qué cambiaría, línea a línea
117
+ pnpm arness sync # aplicar (respalda la versión anterior)
118
+ pnpm arness doctor # novedades de la versión nueva y cómo adoptarlas
119
+ ./harness/init.sh
120
+ git add -A && git commit -m "chore(harness): update to v0.3.0"
121
+ ```
122
+
123
+ Actualizar **no rompe un proyecto que funciona**: las reglas nuevas aparecen como advertencias y cada versión trae una sección "Para proyectos existentes" en el CHANGELOG. Para volver atrás: `pnpm arness rollback`.
124
+
125
+ `arness sync`:
126
+ - solo escribe los archivos del manifiesto (`harness/` y puentes). Nunca toca el código del proyecto (`src/`, `test/`, `package.json`, `.env*`, `.gitignore`, `Dockerfile`, pipelines), `harness/decisiones/`, `harness/arness.config.json` ni `harness/progress.md`;
127
+ - antes de escribir guarda la base anterior en `harness/.arness-backup/` (los últimos 3, ignorados en git), que `arness rollback` restaura;
128
+ - si alguien editó un archivo de la base, **se detiene**. Ese cambio debe registrarse como decisión del repo o proponerse a este paquete (`--force` sobrescribe);
129
+ - con `--copy` crea copias en lugar de enlaces simbólicos, útil en Windows sin symlinks. `init` lo hace solo si no puede crear el enlace.
130
+
131
+ ## Desarrollo del paquete
132
+
133
+ ```bash
134
+ pnpm test # tests del CLI (node --test)
135
+ ./harness/init.sh # en este repo verifica el harness y el CLI, no un proyecto NestJS
136
+ pnpm pack:check # archivos que se instalan
137
+ ```
138
+
139
+ - La base que se distribuye es todo `harness/`, salvo las decisiones numeradas y `progress.md`. **El paquete es público:** nada de secretos, datos de clientes ni información interna sensible.
140
+ - Las decisiones de diseño **del harness** están en `docs/adr/` y no se instalan.
141
+
142
+ ### Publicar una versión
143
+
144
+ Requiere una cuenta npm con permiso de escritura en el scope `@bi-analytics` (`pnpm login`; comprueba con `pnpm whoami`).
145
+
146
+ 1. Actualiza `CHANGELOG.md` y, si aplica, `harness/reference/novedades.json`.
147
+ 2. Verifica: `pnpm test`, `./harness/init.sh --strict` y `pnpm pack:check` (revisa la lista: todo lo que aparece será público).
148
+ 3. Sube la versión con `pnpm version <patch|minor|major>`, que crea el commit y el tag `vX.Y.Z`:
149
+ - **patch:** correcciones;
150
+ - **minor:** reglas, playbooks o skills compatibles;
151
+ - **major:** cambios de estructura o rutas.
152
+ 4. Publica en npm con `pnpm publish` (desde `main`, con el árbol limpio; `publishConfig` ya fija `access: public`).
153
+ 5. Sube el commit y el tag con `git push --follow-tags`.
154
+
155
+ Una versión publicada no se puede reemplazar: si algo sale mal, publica una nueva.
156
+
157
+ El CI (`azure-pipelines.yml`) corre los tests y valida que el tag coincida con `package.json`.