# Agent guide — como armar (o asistir) un flow

Este archivo lo lee el LLM/agente que crea o edita flows. Su trabajo es **recomendar piezas concretas del registry** para cada flow, no inventarlas. Todo lo que se recomiende debe existir ya en el sistema (registry / apps / projects / vaults / DAGs) — o quedar marcado explicitamente como "FALTA: crear".

## Que es un flow

Caso de uso end-to-end reutilizable que cruza N apps del registry. Vive en `dev/flows/NNNN-<slug>.md`. Cada flow:

- describe Goal + Pre-requisitos + Flow steps + Acceptance + Telemetria,
- esta tageado con `apps:` (apps tocadas) en frontmatter,
- se ejecuta manualmente (fase 1) o via `/flow run` (fase 2 futura),
- alimenta `data_factory.runs` + `call_monitor.calls` al correr.

## Tu trabajo como agente cuando un flow nace

Al recibir "crea flow para <X>" o `/flow create <slug>`:

1. **Entiende el goal** en una frase. Si ambiguo, pregunta antes de scaffold.
2. **Recomienda piezas concretas** del registry para cada rol (extractor, transformer, sink, scheduler, notify, storage). Ver tabla de roles abajo.
3. **Cita IDs reales** del registry/apps. Si la pieza no existe -> escribe `FALTA: crear <id> via fn-constructor` en la seccion correspondiente.
4. **Marca riesgo** (low/medium/high) por sensibilidad de datos.
5. **Sugiere schedule** (cron / webhook / manual) basado en el tipo de fuente.
6. **Sugiere apps** del stack que encajan, sin inflar — solo las que realmente tocara.
7. **REDACTA `## Definition of Done` OBLIGATORIO**. No scaffold sin DoD. Empieza por la plantilla minima del `README.md` y anade DoD especificos al dominio del flow (ej. "datos NO viajan a registry.organic-machine", "geo: tiles sirven en <3s", "matrix bot tarda <5s en mensaje"). Acceptance != DoD: Acceptance = "corre"; DoD = "esta listo para vivir solo".
8. **DECLARA USER-FACING SURFACE**. Dentro del DoD, los 4 checks `User-facing` son OBLIGATORIOS y concretos. Responde antes de scaffold:
   - **donde** lo ve el humano? (app concreta + tab/panel, sala Matrix, dashboard URL, Metabase card, repo Gitea con commits, archivo en vault). NUNCA "en la BD" o "en un log".
   - **cuanto tarda** en aparecer? (declara latencia en segundos/minutos).
   - **como vuelve** a verlo manana? (URL bookmark? slash command? cron + dashboard?).
   - **que parrafo onboarding** ira en `## Notas` para que un humano nuevo lo use sin leer el flow.
   Si la unica respuesta es "lo consume otro flow/app", devuelve el flow a borrador — falta superficie humana.

## Mapa de discovery — donde mirar para cada decision

### Extractor (de donde sacan los datos)

| Tipo de fuente | Donde buscar | Filtro MCP |
|---|---|---|
| API REST publica (JSON) | tag `extractor` + `http` | `mcp__registry__fn_search query="http" tag="extractor"` |
| BigQuery | tag `bigquery` + `extractor` | `mcp__registry__fn_search query="" tag="bigquery"` |
| Metabase | tag `metabase` + `extractor` | `mcp__registry__fn_search query="" tag="metabase"` |
| Web scraping (con auth) | apps `navegator_dashboard` + recipes YAML | `ls projects/navegator/profiles/*/recipes/` |
| Web scraping (sin auth, API JSON) | `http_get_json_*` (Tier 1 Tabla extractor.md) | `docs/capabilities/extractor.md` |
| CSV/Parquet local | `load_csv_go_datascience`, `load_parquet_go_datascience`, `from_csv_py_core` | tag `extractor` lang `go|py` |
| Webhooks | apps `registry_api` o `deploy_server` (receivers) | inspeccionar handlers existentes |
| Jupyter notebook | `jupyter_read_py_notebook` | tag `notebook` |

### Transformer (que se hace con los datos)

| Operacion | Donde buscar |
|---|---|
| Dedup / Aggregate / Filter | `docs/capabilities/transformer.md` |
| Tipos / Validacion de schema | `docs/capabilities/validator.md` (puede actuar como gate transformer) |
| Geo (PostGIS, tiles) | `footprint_geo_stack` (app sink + transformer geo) |
| NLP / Embeddings / entities | `docs/capabilities/nlp.md` |
| Lua / TQL (table query) | `cpp-tables` group + `tql_*` funcs |

### Sink (donde acaban los datos)

| Destino | Recomendar |
|---|---|
| BigQuery | `bq_insert_rows_py_infra`, `bq_load_from_*` |
| Metabase card / alert | `metabase_create_card_*`, `metabase_create_card_alert_*` |
| PostgreSQL / SQLite local | `db_insert_row_go_infra` |
| Notificacion Matrix | `agents_and_robots` (app) + funcion bot |
| DuckDB en vault | listar `~/vaults/*` para destino + `csv_to_parquet_duckdb_py_core` |
| HTTP POST a webhook ajeno | `http_post_json_*` |
| Email / Slack | (todavia no — anadir si flow lo pide) |
| Dashboard | `metabase_create_dashboard_*` + `auto_metabase` |
| Grafo entidades | INSERT operations.db de algun project (ej `osint_graph`) + visualizar con `graph_explorer` |

### Scheduler / Trigger

| Caso | Recomendar |
|---|---|
| Recurrente cada N min/hora/dia | DAG en `apps/dag_engine/dags_migrated/<slug>.yaml` con `schedule:` cron. Step usa `function: <id>` directo. |
| Manual (auth requiere user) | `trigger: manual` en flow. Sin DAG. |
| Event-driven (push) | Webhook receiver — depende app (`registry_api`, `deploy_server`). |
| Notebook colaborativo | `jupyter_*` funcs + analysis dir |
| Ejecucion ad-hoc | `./fn run <id>` directo |

### Storage / Artefacto

| Tipo | Donde vive |
|---|---|
| BD app-local | `apps/<app>/operations.db` (entities, runs, assertions) |
| Pipeline factory | `apps/data_factory/data_factory.db` (nodes, runs) |
| DAG runs | `apps/dag_engine/dag_engine.db` |
| Telemetria agente | `projects/fn_monitoring/apps/call_monitor/operations.db` |
| Vault privado (datos sensibles) | `~/vaults/<vault>/` declarado en `projects/<p>/vaults/vault.yaml` |
| Sub-repo Gitea (codigo/artefacto) | `dataforge/<name>` |
| Configs reproducibles | `projects/metabase_registry/`, `projects/element_agents/`, etc. |

### Apps disponibles (snapshot 2026-05-16)

| App | Rol tipico en un flow |
|---|---|
| `navegator_dashboard` | extractor con auth / AutoExtract / recipes |
| `dag_engine` + `dag_engine_ui` | scheduler / orquestador / vista runs |
| `data_factory` | catalogo nodes + runs live |
| `registry_dashboard` | vista codigo registry |
| `call_monitor` | telemetria agent calls |
| `sqlite_api` | HTTP server read-only de todas las BDs |
| `agents_and_robots` | bot Matrix (sink notificaciones) |
| `element_matrix_chat` | backend Matrix |
| `auto_metabase` | sync YAML <-> Metabase |
| `metabase_registry` | snapshots Metabase como codigo |
| `odr_console` | jobs paralelos scraping |
| `graph_explorer` | grafo entidades/relaciones |
| `script_navegador` | runner YAML CDP headless |
| `footprint_geo_stack` | PostGIS + Martin (tiles) + Valhalla (routing) |
| `deploy_server` | rsync/systemd a VPS |
| `docker_tui` | gestion docker |
| `fn_match` | matcher funciones |
| `kanban` | gestion tareas (sink reports?) |
| `pipeline_launcher` | TUI lanzador pipelines |
| `registry_api` | REST API del registry remoto |
| `registry_mcp` | MCP server (Claude) |
| `chart_demo / shaders_lab / primitives_gallery / runtime_test / engine_smoke / text_editor_smoke / altsnap_jitter_test` | demos C++ (raro que un flow las use) |

### Projects disponibles

| Project | Tema |
|---|---|
| `fn_monitoring` | observabilidad del registry |
| `osint_graph` | grafos OSINT |
| `navegator` | scraping CDP |
| `element_agents` | agentes Matrix |
| `online_data_recopilation` | scraping batch |
| `imagegen` | image generation |
| `app_turismo` | turismo |

### Vaults disponibles

`fn sync locations | grep vault` o `cat projects/*/vaults/vault.yaml`. Tipicos:
- `~/vaults/imagegen_models/`
- `~/vaults/odr_data/`
- `~/vaults/osint_graph/`
- `~/vaults/osint_nlp_models/`
- `~/vaults/turismo_spain/`
- `~/vaults/market_data/` (pendiente)
- `~/vaults/finanzas/` (pendiente para flow 0003)

### Capability groups (mother pages, lectura preferente)

`docs/capabilities/INDEX.md`. Cuando recomiendes, lee la mother page del grupo antes de citar funciones sueltas:

- `extractor` (15 funcs)
- `transformer` (15 funcs)
- `sink` (11 funcs)
- `validator` (6 funcs)
- `scheduler` (4 funcs cron parsing)
- `navegator` (10 funcs CDP + LLM)
- `notebook` (Jupyter)
- `metabase` (106 funcs)
- `bigquery` (26 funcs)
- `nlp` (33 funcs)
- `docker, ssh, systemd, deploy, registry, doctor, git, mantine, android, playwright, cpp-tables, cpp-windows, data-table-renderers`

## Estructura de recomendacion a producir

Cuando creas un flow, rellena estas secciones del .md (la template ya las tiene como placeholders):

```markdown
## Funciones del registry recomendadas

| Rol | Funcion candidata | Si falta |
|---|---|---|
| Extractor | `http_get_json_py_infra` (URL: ...) | OK |
| Validator | `validate_recipe_yaml_py_core` | OK |
| Transformer | FALTA: crear `parse_aemet_response_py_core` via fn-constructor |
| Sink | `db_insert_row_go_infra` (target PostGIS) | OK |
| Scheduler | DAG `aemet-madrid.yaml` con cron `0 * * * *` | OK |
| Notify | `matrix_send_message_*` (sala #ops) | FALTA: crear wrapper |

## Apps tocadas

- `dag_engine` (schedule)
- `data_factory` (visibility runs)
- `footprint_geo_stack` (sink PostGIS)

## Projects relacionados

- `fn_monitoring` (telemetria observable)
- `osint_graph` (si lineage)

## Vaults / storage

- PostGIS (footprint_geo_stack): tabla `weather_madrid`
- DuckDB local: NO

## Schedule

`0 * * * *` (cada hora). Razon: AEMET refresca cada hora.

## Capability groups consultados

- `extractor` (http_get_json), `validator`, `sink`
```

Si una recomendacion es FALTANTE: anota en la seccion + abre issue paralelo (`/create-issue`) o flag al user "necesitamos crear estas N funciones antes de poder correr el flow".

## Reglas duras al recomendar

1. **NUNCA inventes IDs**. Si dudas, busca con MCP. Cita solo IDs que respondan a `mcp__registry__fn_show`.
2. **REUTILIZA antes que crear**. Solo FALTA si nada del registry encaja despues de >=3 queries FTS distintas.
3. **MARCA riesgo explicito** en frontmatter. Datos publicos = `low`. Auth = `medium`. Datos personales/financieros = `high`.
4. **NO sugieras schedule cron si requiere auth manual**. `trigger: manual`.
5. **CITA capability group** preferido cuando exista, no funcion suelta. Ej. "ver `docs/capabilities/sink.md`" mejor que "usar `bq_insert_rows_py_infra`".
6. **DOCUMENTA gotchas** especificos del flow en seccion `## Notas`.
7. **NO mezcles N flows en uno**. Si el goal toca >5 apps -> probable que sean 2 flows distintos.

## Plantilla de prompt para futuro agente

Cuando user invoca `/flow create <slug>` o pide "ayuda para crear flow":

```
Eres asistente de flow design. Lee dev/flows/AGENT_GUIDE.md primero.

Pasos:
1. Pregunta al user: "Que quieres lograr en 1 frase? + datos sensibles?"
2. Identifica fuente -> recomienda extractor del registry.
3. Identifica destino -> recomienda sink del registry.
4. Identifica frecuencia -> recomienda schedule (cron / webhook / manual).
5. Identifica notify channel (matrix / email / ninguno).
6. Lista apps tocadas + projects + vaults.
7. Marca FALTA para piezas inexistentes con sugerencia de fn-constructor prompt.
8. Crea NNNN-<slug>.md desde template con las secciones rellenadas.
9. Actualiza INDEX.md.
10. Imprime resumen: "Flow 0008 creado. Faltan N piezas: lista".
```

## Donde escribir hallazgos

Tras correr un flow:
- Marca acceptance checkboxes `[x]`.
- Rellena `## Notas` con tiempos reales, problemas, mejoras.
- Si descubres patron repetido en varios flows: candidato a sub-feature de `/flow run` (fase 2) o nueva funcion del registry.

## Mantenimiento del guide

Este archivo crece. Cuando:
- Una app nueva aparece -> anadir fila a "Apps disponibles".
- Un capability group nuevo -> anadir a "Capability groups".
- Un vault nuevo -> anadir a "Vaults".

`fn doctor` deberia detectar drift entre AGENT_GUIDE.md y BD del registry (TBD: nuevo subcomando `fn doctor flows`).
