# 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-.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 " o `/flow create `: 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 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/.yaml` con `schedule:` cron. Step usa `function: ` 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 ` directo | ### Storage / Artefacto | Tipo | Donde vive | |---|---| | BD app-local | `apps//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//` declarado en `projects/

/vaults/vault.yaml` | | Sub-repo Gitea (codigo/artefacto) | `dataforge/` | | 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 ` 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-.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`).