Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1900,11 +1900,13 @@ Detectado por el **spike Fase-0b de ADR-0109** al validar el workspace de monore
- **Principal:** `L` · **Interés:** `MED` · **Base:** `estimate`

- **Acceptance criteria:**
- [ ] Los tests de integración del circuit breaker ejercitan las transiciones abierto, semiabierto y cerrado contra una dependencia que falla, y fallan sin el breaker.
- [x] Los tests de integración del circuit breaker ejercitan las transiciones abierto, semiabierto y cerrado contra una dependencia que falla, y fallan sin el breaker.
- [ ] Un perfil de carga K6 corre en CI y publica rendimiento, latencia p95 y tasa de error contra umbrales declarados.
- [ ] Un simulacro de caos mata una dependencia a mitad de ejecución y el comportamiento registrado coincide con lo que declara ADR-0011.
- [ ] RTO y RPO se MIDEN en una restauración DR real y se escriben en ADR-0013, sustituyendo la afirmación no cuantificada actual.

- **Avance (2026-08-01):** El criterio de circuit breaker queda satisfecho por la suite de integración de agent-runtime, no por un test unitario aislado de la máquina de estados. `src/packages/agent-runtime/src/adapters/resilience/circuit-breaker.integration.spec.ts` levanta un sustituto real de Core con `node:http`, lo ejecuta mediante `HttpCoreEvaluationAdapter`, y afirma cerrado -> abierto, abierto -> semiabierto -> cerrado, semiabierto -> abierto, y timeout de una dependencia colgada. Cada camino protegido tiene un control sin breaker que prueba que la dependencia todavía recibe llamadas o sigue pendiente sin esa protección. Verificado localmente con `npm --prefix src/packages/agent-runtime test -- --runTestsByPath src/adapters/resilience/circuit-breaker.integration.spec.ts` (5/5 tests).

#### GT-444

**Título:** Pen-test externo
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1910,11 +1910,13 @@ Discovered by the **ADR-0109 Phase-0b spike** while validating the prospective m
- **Principal:** `L` · **Interest:** `MED` · **Basis:** `estimate`

- **Acceptance criteria:**
- [ ] Circuit-breaker integration tests exercise open, half-open and closed transitions against a failing dependency, and fail without the breaker.
- [x] Circuit-breaker integration tests exercise open, half-open and closed transitions against a failing dependency, and fail without the breaker.
- [ ] A K6 load profile runs in CI and publishes throughput, p95 latency and error rate against declared thresholds.
- [ ] One chaos drill kills a dependency mid-run and the recorded behaviour matches what ADR-0011 declares.
- [ ] RTO and RPO are MEASURED on a real DR restore and written into ADR-0013, replacing the current unquantified claim.

- **Progress (2026-08-01):** The circuit-breaker criterion is satisfied by the agent-runtime integration suite rather than by a unit-only state-machine test. `src/packages/agent-runtime/src/adapters/resilience/circuit-breaker.integration.spec.ts` boots a real `node:http` Core stand-in, drives it through `HttpCoreEvaluationAdapter`, and asserts closed -> open, open -> half-open -> closed, half-open -> open, and a hanging dependency timeout. Each protected path has an unprotected control proving the dependency is still called or still pending without the breaker. Verified locally with `npm --prefix src/packages/agent-runtime test -- --runTestsByPath src/adapters/resilience/circuit-breaker.integration.spec.ts` (5/5 tests).

#### GT-444

**Title:** External penetration test
Expand Down
2 changes: 1 addition & 1 deletion reference/core/control-center/gaps/gap-tracking.es.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ Este tablero es la única fuente de verdad para deuda técnica, gaps, oportunida
| [`GT-440`](./gap-reference-catalog.es.md#gt-440) | Completar observabilidad: añadir `/metrics` (Prometheus) a `mcp-server` + `agent-runtime-api`; `OTEL_EXPORTER_OTLP_ENDPOINT` configurable; split liveness/readiness. **HECHO (b3c6557f): `/metrics` en los 3 servicios (core-api existente + mcp `evolith_mcp_*` + agent-runtime `evolith_agent_runtime_*`), `/health/live`+`/health/ready` en mcp+agent-runtime, OTEL endpoint por env. Verificado en el stack local (todos 200).** | `Observability` | Cross | P1 | M | `COMPLETADO` |
| [`GT-441`](./gap-reference-catalog.es.md#gt-441) | El sistema puede pedir aprobación humana para una acción sensible, pero todavía no existe nada que reciba la petición **Qué significa:** Antes de hacer algo sensible el sistema debe detenerse y esperar a una persona. Se detiene bien, pero la petición no le llega a nadie, así que siempre termina rechazada **Ejemplo:** Toda acción marcada como que requiere aprobación vuelve rechazada con «no se pudo preguntar», porque el lugar elegido para responder aún no se ha construido. **Cierre (`a299ab89`):** el receptor ya existe. El Tracker embarcó el endpoint (CD-23, migración `AddRuntimeApprovals`, 2026-07-19) y el Core embarcó el `TrackerApprovalHttpClient` concreto tras el seam de GT-441 — POST `/runtime-approvals` con la clave CoreMachine (el tenant se deriva de QUÉ clave hizo match, nunca del body); un non-2xx lanza para que el adapter deniegue fail-closed como «unavailable» — wireado opt-in en `runtime.factory` (`AGENT_RUNTIME_APPROVAL_TRACKER_URL`/`_KEY`, mandatorio en production). Live-smoke contra el Tracker corriendo: submit → pending (persistido en Postgres) → el adapter deniega fail-closed → idempotente por `correlationId` → un rechazo humano vuelve como denegación `tracker-decision`. El camino approve→grant exige un aprobador UMS designado (CD-31; el dev-bypass deliberadamente no puede serlo), así que queda cubierto por unit + tests del lado Tracker. package 249/249 + app 81/81 verdes. | `Agent Runtime` | Cross | P1 | M | `COMPLETADO` |
| [`GT-442`](./gap-reference-catalog.es.md#gt-442) | Estrategia de secrets + conectividad a DB de producción: documentar/cablear un secret store (Coolify vault / K8s secrets) para `EVOLITH_API_KEY` etc., y aclarar `DATABASE_URL`/config de conexión (ausente en el deploy config hoy). **Cierre (accepted-scope) — ambas mitades del enunciado estaban desalineadas con el código.** (1) *Secret store: sustancialmente ya entregado* — los tres charts toman credenciales de un Secret de K8s pre-creado **por nombre** vía `secretKeyRef`, gated por `auth.existingSecretName` (`core-api-auth`, `mcp-auth`, `agent-runtime-auth`; más `opa-bundle-credentials` / `opa-bundle-signing-key` en mcp). Ningún chart incrusta un literal. El gap real era que estaba sin documentar y disperso → ahora consolidado en `product/infra/README.md`(+`.es.md`) §*Secretos y Conectividad de Datos*, con el equivalente Coolify (variable de entorno cifrada). (2) *Conectividad a DB: **NO APLICA al Core*** — `core-api` y `agent-runtime-api` declaran **cero** dependencias de DB (sin driver/ORM/cadena de conexión, verificado contra ambos `package.json`). Es **ADR-0101 por diseño**: el Core es un motor de evaluación stateless (`EvaluationContext`→`EvaluationResult`; producto/tenant/iniciativa son contexto opaco, nunca persistidos). Así que `DATABASE_URL` no está "faltando" — no hay a qué conectarse, y añadirla *contradiría* ADR-0101. Las cadenas `postgresql` en `projects.controller.ts`/`core-domain.module.ts` son el **generador de scaffolding** eligiendo DB para el proyecto *generado*. La persistencia vive en el **Tracker** (su propio Postgres `tracker_governance`) → trabajo de conectividad de DB delegado al board de ese repo. **Pendiente (owner-gated, no código):** aprovisionar los valores reales de los secretos en el VPS/cluster — mismo bloqueo que [`GT-324`](./gap-reference-catalog.es.md#gt-324)/[`GT-437`](./gap-reference-catalog.es.md#gt-437). | `Infra` | Cross | P1 | S | `COMPLETADO` |
| [`GT-443`](./gap-reference-catalog.es.md#gt-443) | Nunca se midió en un despliegue real cómo se comporta el sistema ante fallos y bajo carga alta **2026-07-28: por fin tiene criterios de aceptación.** Esta fila llevaba EN-PROGRESO con CERO criterios de aceptación — su sección solo tenía prosa ("Closure: breaker integration tests + K6 load/chaos + DR deploy with measured RTO/RPO"), así que nadie podía cerrarla, porque nada definía qué era estar hecho. `08-validate-tracking` no lo detectaba: verifica que una fila DONE tenga sus criterios marcados, y no dice nada sobre que una fila EN-PROGRESO tenga criterios siquiera. La prosa son ahora cuatro criterios comprobables; el hueco del guard queda registrado como `GT-629`. **Qué significa:** Decimos que el sistema sigue funcionando cuando algo se rompe o cuando llega mucho tráfico. Eso solo se comprobó en pruebas aisladas, nunca sobre algo realmente en marcha **Ejemplo:** Nadie sabe cuánto tardaría el servicio en volver tras una caída total, porque ese tiempo de recuperación nunca se ha cronometrado | `Reliability` | Cross | P2 | L | `EN-PROGRESO` |
| [`GT-443`](./gap-reference-catalog.es.md#gt-443) | Nunca se midió en un despliegue real cómo se comporta el sistema ante fallos y bajo carga alta **2026-07-28: por fin tiene criterios de aceptación.** Esta fila llevaba EN-PROGRESO con CERO criterios de aceptación — su sección solo tenía prosa ("Closure: breaker integration tests + K6 load/chaos + DR deploy with measured RTO/RPO"), así que nadie podía cerrarla, porque nada definía qué era estar hecho. `08-validate-tracking` no lo detectaba: verifica que una fila DONE tenga sus criterios marcados, y no dice nada sobre que una fila EN-PROGRESO tenga criterios siquiera. La prosa son ahora cuatro criterios comprobables; el hueco del guard queda registrado como `GT-629`. **Avance 2026-08-01:** el criterio de integración del circuit breaker ya queda marcado: el test de agent-runtime levanta una dependencia HTTP real, cubre transiciones cerrado/abierto/semiabierto más timeout, y lleva controles sin protección. K6, chaos y DR siguen abiertos. **Qué significa:** Decimos que el sistema sigue funcionando cuando algo se rompe o cuando llega mucho tráfico. Eso solo se comprobó en pruebas aisladas, nunca sobre algo realmente en marcha **Ejemplo:** Nadie sabe cuánto tardaría el servicio en volver tras una caída total, porque ese tiempo de recuperación nunca se ha cronometrado | `Reliability` | Cross | P2 | L | `EN-PROGRESO` |
| [`GT-444`](./gap-reference-catalog.es.md#gt-444) | Ningún tercero externo ha intentado nunca entrar por la fuerza al sistema en marcha **Qué significa:** Hay herramientas automáticas que buscan debilidades ya catalogadas. Nadie ha sido contratado para atacar el sistema en vivo como lo haría un intruso real, así que los agujeros desconocidos siguen siendo desconocidos **Ejemplo:** Toda la postura de seguridad se apoya en dos escáneres automáticos; no existe ningún informe de un atacante humano | `Security` | Cross | P2 | S | `PENDIENTE` |
| [`GT-552`](./gap-reference-catalog.es.md#gt-552) | **`release-please` apunta a archivos de configuración que ya no existen, así que nunca puede cortar una versión.** `sdk-cli-release.yml` pasa `config-file: release-please-config.json` y `manifest-file: .release-please-manifest.json`, ambos BORRADOS en `aed33ba9` ("versioning managed manually"), ausentes tanto en `main` como en `develop` y no gitignorados. En consecuencia `release_created` nunca puede ser `true`: los jobs de publicación npm, empaquetado de binarios, smoke-test y subida de assets son inalcanzables, y el ÚNICO workflow del repositorio que crea un Issue automáticamente (`failure-notification`) es código muerto condicionado a esa misma salida. Fix: restaurar los dos archivos de config o migrar el workflow a la realidad de versionado manual que declara. **Cierre (`38db17bf`):** el workflow ya no referencia `release-please-config.json` / `.release-please-manifest.json` (ambos borrados en `aed33ba9`), y el job huérfano `release-please` fue reemplazado por un job `release-gate`, de modo que el workflow ya no declara que puede cortar una versión automáticamente. **Corrección al enunciado original:** el job `failure-notification` NO es código muerto inalcanzable -- SE EJECUTÓ Y TUVO ÉXITO en la corrida 29641024724. El pipeline de release sigue fallando por motivos no relacionados, ahora rastreados por [`GT-561`](./gap-reference-catalog.es.md#gt-561), [`GT-562`](./gap-reference-catalog.es.md#gt-562) y [`GT-563`](./gap-reference-catalog.es.md#gt-563); este gap trataba del CABLEADO roto, que está arreglado. | `Infra` | Cross | P1 | S | `COMPLETADO` |
| [`GT-553`](./gap-reference-catalog.es.md#gt-553) | **`09-reconcile-maturity.mjs` arrastra constantes de ruta muertas y cuenta mal los rulesets.** CUATRO constantes derivan del borrado `reference/core/sdlc/standards/vision/` — `VISION_DIR` y las tres construidas desde ella (`BOARD`, `REGISTRY`, `RUNTIME_EVIDENCE`); estas tres se referencian solo en su propia declaración, así que el clúster es inerte (el guard funciona por lecturas hardcodeadas correctas a `control-center/`). Aparte, `rulesetCount` escanea `rulesets/` en vez de `src/rulesets/`, y por eso el snapshot commiteado de `maturity-reconciliation.json` reporta `"rulesetCount": 0`. Fix: borrar las constantes muertas y reapuntar el escaneo de rulesets a `src/rulesets/`. **Cierre (`35ea46e1`):** el criterio 1 quedó satisfecho por [`GT-556`](./gap-reference-catalog.es.md#gt-556) -- todas las constantes resuelven ahora vía `resolveKey`, y la única mención restante de `vision/` es un comentario explicativo; el criterio 2 está satisfecho y el snapshot regenerado, con `rulesetCount` reportando **145**, coincidiendo con `find src/rulesets -name "*.rules.json" \| wc -l`. **Corrección:** el snapshot commiteado sí llevaba el campo, como `0` -- no estaba ausente, y ese cero era el síntoma. | `Governance` | Cross | P2 | S | `COMPLETADO` |
Expand Down
Loading
Loading