621e8895c9
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
265 lines
11 KiB
Markdown
265 lines
11 KiB
Markdown
# Flows
|
|
|
|
Casos de uso end-to-end **reutilizables** que prueban el sistema multi-app del registry.
|
|
|
|
Un flow describe una secuencia de pasos que atraviesa varias apps (`navegator_dashboard`, `dag_engine`, `data_factory`, `agents_and_robots`, ...) para producir valor real (extraer datos, sincronizar, notificar).
|
|
|
|
## Convencion
|
|
|
|
- Archivo por flow: `NNNN-<slug>.md` (numeracion zero-padded propia, NO comparte con `dev/issues/`).
|
|
- Estado vivo en frontmatter (`status`).
|
|
- Acceptance checkboxes `[ ]` en el body — `/flow status` calcula % completado.
|
|
- **Definition of Done OBLIGATORIA** — ver seccion abajo. Sin DoD el flow NO puede crearse.
|
|
- Cerrados se mueven a `completed/`.
|
|
|
|
## Definition of Done (OBLIGATORIA — triada)
|
|
|
|
Cada flow al crearse DEBE declarar un bloque `## Definition of Done` distinto de `## Acceptance`. Sin el, `/flow create` rechaza el scaffold y `/flow done` rechaza el cierre.
|
|
|
|
**Regla absoluta**: DoD no es checkbox que se marca a mano. Cada item lleva **evidencia ejecutable** (comando, e2e_check, dashboard URL con datos frescos, log query, screenshot link). Si no puedes probarlo, no es DoD: es deseo. Ver `.claude/rules/dod_quality.md` para la regla completa.
|
|
|
|
**Diferencia con `## Acceptance`:**
|
|
|
|
| `## Acceptance` | `## Definition of Done` |
|
|
|---|---|
|
|
| Checks task-level del flow (el flow corre una vez) | Contrato global de calidad: el flow sobrevive uso real |
|
|
| Pueden quedar `[ ]` mientras iteras | TODAS las capas verdes con evidencia antes de mover a `completed/` |
|
|
| Verifica que el flow CORRE | Verifica que el flow es REPETIBLE, OBSERVABLE, MANTENIBLE y USADO |
|
|
|
|
### Las 3 capas obligatorias
|
|
|
|
**1. Mecanica** (pre-requisito, NO es DoD por si misma):
|
|
Build verde, tests verdes, `fn index` limpio, `fn doctor` verde, `uses_functions` sin drift. Hacer compilar la cosa NO es haberla terminado.
|
|
|
|
**2. Cobertura de comportamiento**:
|
|
Tabla `escenario | tipo | comando | resultado esperado`. Minimo 1 golden + 2 edge + 1 error path con assert real, no smoke "no peto". Cuando aplique, las pruebas dejan entry en `e2e_runs` de la app afectada.
|
|
|
|
**3. Vida util validada**:
|
|
Tabla `metrica | umbral | dashboard | ventana`. El flow sobrevive **>=7 dias de uso real** sin romperse silenciosamente. Crashes = 0, huecos en audit chains = 0, error_rate < umbral declarado, dashboard observable abierto periodicamente. **El humano usa la cosa en su PC, en su contexto real, >=N veces variadas, no en sandbox aislado**.
|
|
|
|
### Plantilla obligatoria
|
|
|
|
Ver `template.md` para el esqueleto completo. Bloques:
|
|
|
|
```markdown
|
|
## Definition of Done
|
|
|
|
### Mecanica
|
|
- [ ] Build verde (`cmd: ...`)
|
|
- [ ] Tests verdes (`cmd: ...`)
|
|
- [ ] fn index limpio
|
|
- [ ] fn doctor verde
|
|
- [ ] uses_functions auditado
|
|
|
|
### Cobertura de comportamiento
|
|
| Escenario | Tipo | Comando | Resultado esperado |
|
|
|---|---|---|---|
|
|
| Golden: ... | unit/e2e | `cmd` | output concreto |
|
|
| Edge 1: ... | unit/e2e | `cmd` | comportamiento concreto |
|
|
| Error 1: ... | e2e | `cmd que rompe` | fallo manejado, no crash |
|
|
| Error 2: ... | e2e | `cmd` | degradacion graceful + log |
|
|
|
|
### Vida util validada
|
|
| Metrica | Umbral | Donde se observa | Ventana |
|
|
|---|---|---|---|
|
|
| <metrica> | `>=N` | `<dashboard URL>` | 7 dias |
|
|
| crashes | `0` | `journalctl ...` | 7 dias |
|
|
|
|
### User-facing (reforzado)
|
|
- [ ] User-facing surface (lugar concreto, NO BD ni log).
|
|
- [ ] User-facing usage real: >=N veces en >=7 dias, en PC real, con inputs reales.
|
|
- [ ] User-facing variado: >=3 capabilities/casos distintos.
|
|
- [ ] User-facing onboarding (parrafo en `## Notas`).
|
|
- [ ] User-facing latencia <X medida.
|
|
|
|
### Anti-criterios (invalidan DoD aunque checkboxes verdes)
|
|
- [ ] solo-en-mi-PC
|
|
- [ ] solo-en-sandbox-vacio
|
|
- [ ] camino feliz unico (error paths declarados pero nunca ejercitados)
|
|
- [ ] dashboard fantasma (no abierto en >30 dias)
|
|
- [ ] self-test sin asserts
|
|
- [ ] silent-fail
|
|
- [ ] approval saltado
|
|
```
|
|
|
|
### Reglas duras para marcar `status: done`
|
|
|
|
`/flow done` rechaza el cierre si:
|
|
|
|
1. Falta alguna de las 3 capas (mecanica + cobertura + vida).
|
|
2. En Cobertura: <1 golden, <2 edge, <1 error path con evidencia.
|
|
3. En Vida util: tabla vacia o sin dashboard observable real.
|
|
4. User-facing usage real <7 dias o <N usos declarados.
|
|
5. Cualquier anti-criterio marcado como cierto.
|
|
6. `## Notas` sin parrafo onboarding.
|
|
7. Algun item sin comando/URL/log query — solo texto.
|
|
|
|
Cada flow puede anadir DoD especificos al dominio. El bloque DoD se **versiona con el flow** — un cambio de DoD requiere bump de `updated:` en frontmatter.
|
|
|
|
### User-facing surface (regla complementaria)
|
|
|
|
Si la respuesta a "donde lo ves" es "en una BD" o "en un log" -> NO vale. Tiene que ser una superficie usada por el humano (UI de app, sala Matrix, dashboard, Metabase card, repo Gitea, archivo en vault abierto a mano). Si el output solo lo consume otra app/flow, esa app/flow declara su propia user-facing surface.
|
|
|
|
### Antipatrones documentados
|
|
|
|
| Antipatron | Por que es malo |
|
|
|---|---|
|
|
| Marcar `done` porque pasa una vez | Tarea "hecha" se rompe al primer uso real |
|
|
| Checkbox sin evidencia ejecutable | DoD se convierte en placebo, no en gate |
|
|
| Test que solo verifica camino feliz | El error path es donde se pierden datos en produccion |
|
|
| Observabilidad declarada pero dashboard no abierto en 30 dias | Telemetria muerta = ceguera |
|
|
| "Repetible 3 veces consecutivas" con BD efimera | No prueba comportamiento sobre datos reales acumulados |
|
|
| Aprobacion saltada en algun camino | Security gate roto pero invisible |
|
|
| Error path manejado solo "en teoria" | Cuando ocurra en produccion el manejo no existe |
|
|
|
|
### Validacion programatica de DoD (TBD)
|
|
|
|
`/flow done` ejecuta checks programaticos:
|
|
- Parsea bloques `### Mecanica`, `### Cobertura`, `### Vida util`, `### User-facing`, `### Anti-criterios`.
|
|
- Verifica que cada item tiene `cmd:` / URL / log query / e2e_check_id asociado.
|
|
- Cuenta filas en Cobertura: >=1 golden + >=2 edge + >=1 error.
|
|
- Cruza con `e2e_runs` y `call_monitor.calls` para confirmar evidencias en BDs reales.
|
|
- Aborta cierre si falta cobertura o algun anti-criterio esta marcado.
|
|
|
|
Hoy parte de esto es manual (revision humana). Ver `audit_dod_schema_go_infra` (issue 0114) + `fn doctor dod`.
|
|
|
|
### DoD evidence schema (issue 0114, opcional)
|
|
|
|
Ademas de los checkboxes humanos del bloque `## Definition of Done`, cada flow puede declarar en su frontmatter un bloque `dod_evidence_schema:` con la version maquinable de la DoD: lista de evidencias con id unico, `kind` cerrado, `expected` libre y `required` bool. Auditable con `fn doctor dod`.
|
|
|
|
```yaml
|
|
dod_evidence_schema:
|
|
- id: surface_dashboard
|
|
kind: url
|
|
expected: "https://metabase.organic-machine.com/dashboard/12 muestra ultimo refresh hoy"
|
|
required: true
|
|
- id: matrix_room_msg
|
|
kind: screenshot
|
|
expected: "sala matrix #flows recibe mensaje con resumen del run"
|
|
required: true
|
|
- id: data_factory_run
|
|
kind: cmd
|
|
expected: "sqlite3 data_factory.db 'SELECT count(*) FROM runs WHERE flow=NNNN' > 0"
|
|
required: true
|
|
- id: error_path_log
|
|
kind: log
|
|
expected: "fallar collector intencional deja entry status=error sin crash"
|
|
required: false
|
|
```
|
|
|
|
Reglas:
|
|
- `kind` ∈ {`screenshot`, `log`, `url`, `cmd`}.
|
|
- `id` unico por flow.
|
|
- `expected` no vacio.
|
|
- `required` default `true`.
|
|
|
|
Ejemplos por kind:
|
|
|
|
| kind | que pones en `expected` |
|
|
|---|---|
|
|
| `screenshot` | "frame de la app/sala mostrando estado Y" |
|
|
| `log` | "fichero <path> contiene linea con texto Z" |
|
|
| `url` | "GET <url> devuelve 200 con campo W" o "dashboard tal carga ultima fila < 24h" |
|
|
| `cmd` | comando shell con exit 0 (incluido SQL via sqlite3) |
|
|
|
|
Plantilla canonica: `docs/templates/flow.md`. Validador: `fn doctor dod` + `audit_dod_schema_go_infra`.
|
|
|
|
|
|
## Para agentes / LLMs
|
|
|
|
Antes de crear o editar un flow, lee `AGENT_GUIDE.md`. Define:
|
|
- donde buscar funciones (capability groups, MCP search por tag, etc.),
|
|
- mapa actual de apps / projects / vaults disponibles,
|
|
- reglas duras para recomendar piezas reales del registry,
|
|
- plantilla de prompt para el agente cuando recibe `/flow create`.
|
|
|
|
Cada flow debe citar IDs reales del registry. Si una pieza no existe, marcarla `FALTA: crear <id>` — NUNCA inventar nombres.
|
|
|
|
## Slash command `/flow`
|
|
|
|
| Subcomando | Que hace |
|
|
|---|---|
|
|
| `/flow create <slug>` | Scaffold `NNNN-<slug>.md` desde `template.md` con siguiente ID libre. |
|
|
| `/flow list` | Tabla resumen desde `INDEX.md` + checkbox %. |
|
|
| `/flow show <NNNN>` | Imprime el `.md`. |
|
|
| `/flow status <NNNN>` | Status + acceptance % + ultima run. |
|
|
| `/flow done <NNNN> [--notes "..."]` | Marca status=done, anade notas, mueve a `completed/`, actualiza INDEX. |
|
|
| `/flow run <NNNN>` | **Fase 2** (no implementado). Ejecuta steps automatizables. |
|
|
|
|
## Estructura archivo
|
|
|
|
```yaml
|
|
---
|
|
name: hn-top-stories
|
|
id: 0001
|
|
status: pending # pending | running | done | failed | deferred
|
|
created: 2026-05-16
|
|
updated: 2026-05-16
|
|
priority: high # low | medium | high
|
|
risk: low # low | medium | high (sensibilidad de datos)
|
|
related_issues: [0097, 0098]
|
|
apps: [navegator_dashboard, dag_engine, data_factory, agents_and_robots]
|
|
trigger: manual # manual | cron | webhook
|
|
schedule: ""
|
|
expected_runtime_s: 60
|
|
tags: [scraping, news]
|
|
---
|
|
|
|
## Goal
|
|
Una frase: que estamos probando.
|
|
|
|
## Pre-requisitos
|
|
- Lista de requisitos manuales (ej. Chrome con remote-debugging).
|
|
|
|
## Flow
|
|
Pasos numerados. Cada paso puede ser:
|
|
- texto libre (manual)
|
|
- `function: <id>` (registry function)
|
|
- `cmd: <bash>`
|
|
- `js: <expression>` (en tab Chrome)
|
|
|
|
## Acceptance
|
|
- [ ] Checklist
|
|
- [ ] ...
|
|
|
|
## Telemetria esperada
|
|
Que cambia en call_monitor / data_factory.runs / dag_engine.
|
|
|
|
## Notas
|
|
Hallazgos tras correr.
|
|
```
|
|
|
|
## Numeracion + status workflow
|
|
|
|
```
|
|
pending --create--> in-progress --run OK--> done --move--> completed/
|
|
| ^
|
|
v |
|
|
failed -----------fix-----+
|
|
```
|
|
|
|
`deferred` para flows fuera de scope actual pero que conservas.
|
|
|
|
## Trazabilidad
|
|
|
|
Cada `function: X` invocado dentro de un flow pasa por hook PostToolUse -> queda en `call_monitor.calls`. Si la funcion graba en `data_factory.runs` (ej. `cdp_extract_recipe_py_pipelines`), tienes cadena:
|
|
|
|
```
|
|
flow 0001 -> /flow run -> ./fn run cdp_extract_recipe -> call_monitor.calls
|
|
\-> data_factory.runs
|
|
```
|
|
|
|
Asi la observabilidad cross-app es gratis.
|
|
|
|
## Cuando crear flow vs issue
|
|
|
|
| Caso | Donde |
|
|
|---|---|
|
|
| Bug del registry / funcion | `dev/issues/NNNN-...` |
|
|
| Feature de una app | `dev/issues/NNNN-...` |
|
|
| Caso de uso real que cruza N apps | **`dev/flows/NNNN-...`** |
|
|
| Trabajo recurrente reutilizable | **`dev/flows/NNNN-...`** |
|
|
| Refactor de codigo | `dev/issues/NNNN-...` |
|
|
|
|
Un flow puede generar issues secundarios si descubres bugs corriendo el flow.
|