# DoD Quality Triada **Definition of Done no es un checkbox que se marca a mano. Es un contrato de calidad con 3 capas obligatorias + evidencia ejecutable + uso real >=7 dias.** Aplica a todos los `dev/flows/` y, por extension, a issues que cierran capabilities user-facing (`dev/issues/`). El registry mismo (funciones puras, tipos) queda exento: su DoD vive en sus tests unitarios. --- ## Por que existe esta regla El antipatron a eliminar: "tarea hecha porque pase los tests una vez". Despues: - El flow funciona en `home-wsl` pero falla en `pc-aurgi`. - El error path declarado nunca se ejercito y cuando ocurre en produccion no esta manejado. - El dashboard de observabilidad lleva 30 dias sin abrirse. - El proceso muere cada noche y nadie lo ve hasta que el operador intenta usarlo. - El approval flow se salta porque "para test es mas comodo". Resultado: deuda invisible. Cada flow "done" se rompe al primer uso real, el operador pierde confianza en el sistema, y el bucle reactivo no detecta nada porque la telemetria esta verde (los tests sintenticos pasan). DoD Quality Triada cambia las reglas: cerrar = probar comportamiento + sobrevivir uso real, no = compilar verde. --- ## Las 3 capas ### Capa 1: Mecanica (pre-requisito, NO es DoD por si misma) Compilar verde, tests verdes, indexado limpio, `fn doctor` verde, `uses_functions` sin drift. **Regla**: la mecanica NO basta. Es la base para empezar a probar comportamiento. Si te quedas aqui, el flow no esta hecho. ### Capa 2: Cobertura de comportamiento Cada escenario relevante con prueba ejecutable y assert material. NO smoke "el comando no peto". Minimo: - **1 golden path** — el caso feliz documentado con assert sobre output concreto. - **>=2 edge cases** — inputs limite, estados raros, condiciones de borde. - **>=1 error path** — fallo provocado intencionalmente, manejado y observable (sin crash, sin silent-fail). Formato canonico (tabla en `## Definition of Done` del flow/issue): ```markdown | Escenario | Tipo | Comando / evidencia | Resultado esperado | |---|---|---|---| | Golden: | unit / e2e | `` | | | Edge 1: | unit / e2e | `` | | | Error 1: | e2e | `` | | ``` Cuando aplique, cada fila genera un `e2e_check` en el `app.md` correspondiente (issue 0068). `fn-analizador` los corre periodicamente y deja entry en `e2e_runs`. ### Capa 3: Vida util validada El flow no esta hecho hasta que sobrevive **uso real durante >=7 dias** sin romperse silenciosamente. Cada metrica con umbral medible y dashboard observable. Formato canonico: ```markdown | Metrica | Umbral | Donde se observa | Ventana | |---|---|---|---| | | `>=N` | `` | 7 dias | | crashes | `0` | `journalctl -u ` | 7 dias | | huecos audit chain | `0` | `cmd: ` | continuo | ``` Reglas: - Metricas NO se auto-reportan; las lee el operador del dashboard real. - Si el dashboard no existe o no se ha abierto en 30 dias, el item se invalida. - Crashes del proceso = 0, huecos en audit = 0, error_rate < umbral declarado. ### Capa transversal: User-facing reforzado - Surface concreta NO BD ni log (UI app, room Matrix, dashboard, archivo en vault). - Usage real: humano usa en su PC, su contexto, >=N veces variadas en >=7 dias. - Variado: >=3 capabilities/casos distintos (no solo "abre dashboard y mira"). - Onboarding: parrafo en `## Notas` que explica como usar la cosa sin leer el flow. - Latencia medida (no declarada). --- ## Reglas duras para marcar `status: done` `/flow done` (y por extension cierres de issues user-facing) DEBE rechazar el cierre si: 1. Falta cualquiera de las 3 capas (mecanica + cobertura + vida). 2. Cobertura tiene <1 golden, <2 edge, o <1 error path con evidencia. 3. Vida util tiene tabla vacia o sin dashboard observable real. 4. User-facing usage real <7 dias o =7 dias de uso real | | Checkbox sin evidencia ejecutable | DoD se convierte en placebo | Cada item con `cmd:` / URL / log query | | Test que solo verifica camino feliz | El error path es donde se pierden datos | Capa 2: >=1 error path ejercitado | | Observabilidad declarada pero dashboard no abierto en 30 dias | Telemetria muerta = ceguera | Capa 3: dashboard real, operador lo abre | | "Repetible 3 veces consecutivas" con BD efimera | No prueba sobre datos reales acumulados | Capa 3: PC real del operador, datos vivos | | Approval saltado en algun camino | Security gate roto pero invisible | Anti-criterio explicito: `audit_log` lo prueba | | Error path manejado solo "en teoria" | Cuando ocurra en produccion el manejo no existe | Capa 2: entry real en `e2e_runs` o audit | | Solo-en-mi-PC | Falla en otra maquina del operador | Anti-criterio explicito, probar >=2 PCs | | Self-test que retorna `pass` sin asserts materiales | False positive sistemico | Asserts sobre output concreto, no exit-0 | | Silent-fail (proceso muere sin alerta) | Operador no se entera hasta intentar usar | Capa 3: crashes=0 + alerta visible | --- ## Relacion con otras reglas - [[e2e_validation]] — los escenarios de Capa 2 cuando aplican a apps se materializan como `e2e_checks` en `app.md`. `fn-analizador` (fase 4 del bucle reactivo) los corre. - [[registry_calls]] — la evidencia de uso (`call_monitor.calls`) alimenta los umbrales de Capa 3. - [[function_growth_and_self_docs]] — cada funcion del registry tiene su propio contrato self-doc (Ejemplo + Cuando usarla + Gotchas). DoD del flow NO sustituye al self-doc de la funcion; lo complementa para el nivel sistema. - [[autonomous_loop]] — `fn-orquestador` autonomo NO puede marcar `done` sin que se cumplan las 3 capas. Su criterio de convergencia incluye DoD Quality. - [[apps_tbd]] — TBD garantiza master desplegable; DoD garantiza que lo desplegado funciona en uso real. --- ## TL;DR 1. **Mecanica** = compilar verde (pre-requisito, NO suficiente). 2. **Cobertura** = golden + >=2 edge + >=1 error path con evidencia ejecutable. 3. **Vida util** = >=7 dias de uso real sin romper silenciosamente, dashboard observable abierto. 4. **User-facing reforzado** = humano usa en PC real, >=N veces variadas. 5. **Anti-criterios** invalidan la DoD aunque todo este verde. 6. Sin evidencia ejecutable (cmd/URL/log), NO es DoD: es deseo.