chore: auto-commit (286 archivos)
- .claude/agents/fn-orquestador/SKILL.md - .claude/commands/fn_claude.md - .claude/rules/INDEX.md - .claude/rules/cpp_apps.md - .claude/rules/ids_naming.md - CHANGELOG.md - apps/dag_engine/README.md - apps/dag_engine/api.go - apps/dag_engine/dags_migrated/example.yaml - apps/dag_engine/dags_migrated/example_lineage_tracking.yaml - ... Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
---
|
||||
name: hn-top-stories
|
||||
id: 0001
|
||||
status: pending
|
||||
created: 2026-05-16
|
||||
updated: 2026-05-16
|
||||
priority: high
|
||||
risk: low
|
||||
related_issues: [0097, 0098]
|
||||
apps:
|
||||
- navegator_dashboard
|
||||
- dag_engine
|
||||
- data_factory
|
||||
- agents_and_robots
|
||||
trigger: cron
|
||||
schedule: "*/30 * * * *"
|
||||
expected_runtime_s: 30
|
||||
tags: [scraping, news, smoke-test, multi-app]
|
||||
---
|
||||
|
||||
## Goal
|
||||
|
||||
Probar end-to-end el stack: navegator AutoExtract -> recipe -> dag_engine schedule -> data_factory.runs -> matrix bot. Pagina cero-auth + cero-coste. Si esto funciona, todo el plumbing es solido.
|
||||
|
||||
## Pre-requisitos
|
||||
|
||||
- Chrome lanzado con `--remote-debugging-port=9222` (via navegator_dashboard "Open visible browser").
|
||||
- `claude` CLI en PATH (auto-extract requiere LLM).
|
||||
- sqlite_api activo en `:8484`.
|
||||
- dag_engine activo en `:8090`.
|
||||
- (opcional) Bot Matrix en sala `#fn-registry-news` para el sink final.
|
||||
|
||||
## Flow
|
||||
|
||||
1. Lanzar Chrome via navegator (puerto 9222).
|
||||
2. AutoExtract panel: URL `https://news.ycombinator.com`. Click "Open & Analyze".
|
||||
3. Esperar ~10-20s. Verificar schema propuesto: `rank`, `title`, `url`, `points`, `comments`, `age`.
|
||||
4. Refinar selectors si IA proponen rotos. Test extraction -> preview rows >= 20.
|
||||
5. Save as recipe `hn_top.yaml` (en `projects/navegator/profiles/default/recipes/`).
|
||||
6. Crear DAG `~/.dagu/dags/hn-top.yaml` (manual o copy de `apps/dag_engine/dags_migrated/`):
|
||||
```yaml
|
||||
name: hn-top-stories
|
||||
description: Scrape HN top stories cada 30 min
|
||||
schedule: "*/30 * * * *"
|
||||
steps:
|
||||
- name: extract
|
||||
function: cdp_extract_recipe_py_pipelines
|
||||
args: ["projects/navegator/profiles/default/recipes/hn_top.yaml"]
|
||||
```
|
||||
7. Reload dag_engine + activar scheduler. Trigger Run Now una vez para probar.
|
||||
8. dag_engine_ui: verificar run con status=success + function_id correcto en step.
|
||||
9. data_factory: tab Extractors muestra nodo `hn_top_stories` (creado por save recipe). Tab "All Runs" muestra runs nuevos.
|
||||
10. (opcional) Anadir step transformer filtra `points > 100` -> sink matrix bot.
|
||||
|
||||
## Acceptance
|
||||
|
||||
- [ ] Recipe creada y validada (`validate_recipe_yaml_py_core` OK).
|
||||
- [ ] DAG corre OK 2 veces consecutivas via scheduler.
|
||||
- [ ] `data_factory.runs` tiene >=2 entries con `node_id='hn_top_stories'`.
|
||||
- [ ] `cdp_extract_recipe_py_pipelines` aparece en `call_monitor.calls`.
|
||||
- [ ] Schema extraido cubre 6/6 fields (rank, title, url, points, comments, age).
|
||||
- [ ] (opcional) Matrix bot recibe >=1 mensaje con top story filtrada.
|
||||
|
||||
## Telemetria esperada
|
||||
|
||||
- `function_stats.cdp_extract_recipe_py_pipelines`: calls_24h += 2.
|
||||
- `data_factory.runs`: 2 nuevas filas con `trigger='cron'`.
|
||||
- `dag_engine.dag_step_results`: step `extract` con `function_id='cdp_extract_recipe_py_pipelines'`.
|
||||
- `call_monitor.calls`: chain function call.
|
||||
|
||||
## Notas
|
||||
|
||||
(rellenas tras correr)
|
||||
@@ -0,0 +1,69 @@
|
||||
---
|
||||
name: aemet-madrid
|
||||
id: 0002
|
||||
status: pending
|
||||
created: 2026-05-16
|
||||
updated: 2026-05-16
|
||||
priority: medium
|
||||
risk: low
|
||||
related_issues: [0097]
|
||||
apps:
|
||||
- dag_engine
|
||||
- data_factory
|
||||
- footprint_geo_stack
|
||||
trigger: cron
|
||||
schedule: "0 * * * *"
|
||||
expected_runtime_s: 10
|
||||
tags: [api, weather, geo, http-only]
|
||||
---
|
||||
|
||||
## Goal
|
||||
|
||||
Probar path HTTP-only (sin Chrome/CDP). Extractor REST -> data_factory -> sink geo (PostGIS via footprint_geo_stack). Demuestra que el stack tambien sirve para APIs publicas + datos georeferenciados.
|
||||
|
||||
## Pre-requisitos
|
||||
|
||||
- API key AEMET (gratis, signup). Guardar en `pass insert aemet/api-key`.
|
||||
- `footprint_geo_stack` corriendo (PostGIS :5432 + Martin tiles :3000).
|
||||
- dag_engine activo.
|
||||
|
||||
## Flow
|
||||
|
||||
1. Crear funcion del registry `aemet_get_weather_py_infra` (o usar `http_get_json_py_infra` directamente si la API responde JSON simple).
|
||||
2. Endpoint AEMET observacion convencional: `GET https://opendata.aemet.es/opendata/api/observacion/convencional/datos/estacion/<id>` con header `api_key`.
|
||||
3. Schema esperado: `[{ts, temp, humidity, pressure, wind_speed, lat, lon}, ...]`.
|
||||
4. Sink: INSERT en PostGIS tabla `weather_madrid (ts, temp, humidity, pressure, geom geometry(Point, 4326))`.
|
||||
5. Crear node en data_factory: `{kind: 'database', label: 'postgis_weather'}` (sink declarado).
|
||||
6. DAG `aemet_madrid_hourly.yaml`:
|
||||
```yaml
|
||||
name: aemet-madrid
|
||||
schedule: "0 * * * *"
|
||||
steps:
|
||||
- name: extract
|
||||
function: aemet_get_weather_py_infra
|
||||
args: ["--station", "3195", "--out", "/tmp/aemet.json"]
|
||||
- name: load_postgis
|
||||
function: db_insert_row_go_infra
|
||||
args: ["--db", "postgres://...", "--table", "weather_madrid", "--from-json", "/tmp/aemet.json"]
|
||||
depends: [extract]
|
||||
```
|
||||
7. Verificar Martin tiles renderiza overlay (opcional).
|
||||
|
||||
## Acceptance
|
||||
|
||||
- [ ] Funcion AEMET extractor existe (creada o reusada `http_get_json_*`).
|
||||
- [ ] DAG corre 2x consecutivas via scheduler.
|
||||
- [ ] PostGIS tabla `weather_madrid` tiene >=2 filas.
|
||||
- [ ] data_factory muestra node `aemet_madrid` kind=extractor + node `postgis_weather` kind=database con `last_seen_at` reciente.
|
||||
- [ ] Martin tile server sirve overlay weather (opcional).
|
||||
|
||||
## Telemetria esperada
|
||||
|
||||
- `function_stats.http_get_json_py_infra` o `aemet_get_weather_py_infra`: calls_24h += 24 (1/hora).
|
||||
- `data_factory.runs`: 24 entries/dia.
|
||||
- `data_factory.databases.last_seen_at` actualizado por sink.
|
||||
|
||||
## Notas
|
||||
|
||||
- Sin LLM/CDP. Mas barato que flow 0001.
|
||||
- Caso minimal para servicios geo. Si funciona, sirve de plantilla para mas extractores API.
|
||||
@@ -0,0 +1,69 @@
|
||||
---
|
||||
name: bbva-movimientos
|
||||
id: 0003
|
||||
status: pending
|
||||
created: 2026-05-16
|
||||
updated: 2026-05-16
|
||||
priority: high
|
||||
risk: high
|
||||
related_issues: [0097, 0098]
|
||||
apps:
|
||||
- navegator_dashboard
|
||||
- dag_engine
|
||||
- data_factory
|
||||
- auto_metabase
|
||||
trigger: manual
|
||||
schedule: ""
|
||||
expected_runtime_s: 120
|
||||
tags: [scraping, banking, auth-required, sensitive-data]
|
||||
---
|
||||
|
||||
## Goal
|
||||
|
||||
Caso de uso REAL con auth + datos sensibles. Probar persistencia local (duckdb en vault privado) + visualizacion en Metabase. Demuestra que el stack funciona para finanzas personales sin exfiltrar datos a la nube.
|
||||
|
||||
## Pre-requisitos
|
||||
|
||||
- Vault `~/vaults/finanzas/` existe + symlink en `projects/finanzas_personales/vaults/` (crear projecto si no).
|
||||
- Chrome con sesion BBVA logueada manualmente (no automatizar login).
|
||||
- Metabase local en docker (`auto_metabase` provee).
|
||||
- `claude` CLI para AutoExtract.
|
||||
|
||||
## Flow
|
||||
|
||||
1. User abre Chrome + login BBVA + navega a "Movimientos cuenta principal".
|
||||
2. navegator_dashboard panel Pick: click sobre primera fila de la tabla movimientos. Verifica selector capturado.
|
||||
3. Panel AutoExtract: URL actual del tab. Click "Open & Analyze" (puede tardar, pagina compleja).
|
||||
4. Esperar schema propuesto. Refinar:
|
||||
- `date` (string DD/MM/YYYY o YYYY-MM-DD)
|
||||
- `concept` (string)
|
||||
- `amount` (float, parsea `,` -> `.`)
|
||||
- `balance` (float)
|
||||
5. Save recipe `bbva_movimientos.yaml`.
|
||||
6. **Trigger manual SOLO** (no schedule — requiere login activo).
|
||||
7. Sink: duckdb local en `~/vaults/finanzas/bbva.duckdb` (tabla `movimientos`).
|
||||
8. data_factory: node `bbva_movimientos` kind=extractor + node `vault_finanzas_duckdb` kind=database.
|
||||
9. Transformer: `aggregate_by_group_py_datascience` por mes -> tabla `mensual_summary`.
|
||||
10. Sink Metabase: `metabase_create_card_py_infra` con SQL contra duckdb (via attachment Metabase si soporta, o via parquet export).
|
||||
|
||||
## Acceptance
|
||||
|
||||
- [ ] Recipe creada y testeada.
|
||||
- [ ] Run manual extrae >=30 movimientos (1 mes).
|
||||
- [ ] DuckDB `~/vaults/finanzas/bbva.duckdb` tabla `movimientos` poblada.
|
||||
- [ ] data_factory muestra ambos nodos con runs.
|
||||
- [ ] Card Metabase creado con grafico "gasto mensual" via auto_metabase.
|
||||
- [ ] Datos NO viajan a registry.organic-machine (verificar: solo `pc_locations` registra que existe; el vault esta gitignored).
|
||||
|
||||
## Telemetria esperada
|
||||
|
||||
- `function_stats.cdp_extract_recipe_py_pipelines`: calls += 1 (manual).
|
||||
- `data_factory.runs`: 1 entry status=success.
|
||||
- `auto_metabase`: 1 card creado.
|
||||
|
||||
## Notas
|
||||
|
||||
- **NO commitear** `~/vaults/finanzas/` (gitignored por defecto).
|
||||
- Si la sesion expira: re-login manual + re-run.
|
||||
- Si BBVA cambia DOM: AutoExtract identifica nuevos selectors. Edit recipe + redeploy.
|
||||
- Privacidad: revisar `call_monitor.calls` que solo guarda `args_hash`, NUNCA valores concretos de movimientos.
|
||||
@@ -0,0 +1,68 @@
|
||||
---
|
||||
name: gitea-releases-monitor
|
||||
id: 0004
|
||||
status: pending
|
||||
created: 2026-05-16
|
||||
updated: 2026-05-16
|
||||
priority: medium
|
||||
risk: low
|
||||
related_issues: []
|
||||
apps:
|
||||
- registry_api
|
||||
- data_factory
|
||||
- agents_and_robots
|
||||
trigger: webhook
|
||||
schedule: ""
|
||||
expected_runtime_s: 5
|
||||
tags: [git, webhook, multi-repo, monitoring]
|
||||
---
|
||||
|
||||
## Goal
|
||||
|
||||
Probar webhooks como trigger (no cron, no manual). Cada push a un repo `dataforge/*` registra commit en data_factory + notifica via Matrix bot. Demuestra reactividad event-driven.
|
||||
|
||||
## Pre-requisitos
|
||||
|
||||
- `gitea_create_webhook_bash_infra` disponible.
|
||||
- Servidor HTTP receptor (reusar `registry_api` o `deploy_server`).
|
||||
- Bot Matrix en sala `#fn-registry-releases`.
|
||||
- GITEA_TOKEN en `pass registry/api-token`.
|
||||
|
||||
## Flow
|
||||
|
||||
1. Crear endpoint receptor `POST /webhook/gitea` en una app (probable: nueva mini-app `gitea_webhook_listener` o anadir a `deploy_server`).
|
||||
2. Iterar repos `dataforge/<name>` (35 apps + analyses). Instalar webhook en cada uno apuntando al receptor:
|
||||
```bash
|
||||
for app in $(ls apps/); do
|
||||
gitea_create_webhook "dataforge" "$app" "http://<vps>/webhook/gitea" "$secret"
|
||||
done
|
||||
```
|
||||
3. Receptor parsea payload Gitea (event `push`): `{ref, commits: [{id, message, author, url}]}`.
|
||||
4. INSERT en `data_factory.runs` con `node_id='gitea_push_<repo>'` (upsert node si no existe).
|
||||
5. Notifica Matrix:
|
||||
```
|
||||
[<repo>] <author>: <commit message>
|
||||
<url>
|
||||
```
|
||||
6. dag_engine recibe trigger `api` con info del run.
|
||||
7. data_factory tab Extractors muestra `gitea_push_<repo>` por cada repo con activity.
|
||||
|
||||
## Acceptance
|
||||
|
||||
- [ ] Webhook instalado en >=3 repos.
|
||||
- [ ] Push de prueba dispara recepcion + entry en `data_factory.runs`.
|
||||
- [ ] Matrix recibe mensaje formateado.
|
||||
- [ ] data_factory muestra nodos `gitea_push_<repo>` con last_run reciente.
|
||||
- [ ] Receptor maneja fallos (timeout, payload invalido) sin crash.
|
||||
|
||||
## Telemetria esperada
|
||||
|
||||
- `data_factory.runs` con `trigger='api'`.
|
||||
- Por repo: 1 nodo extractor.
|
||||
- Matrix: 1 msg por push.
|
||||
|
||||
## Notas
|
||||
|
||||
- Webhook secret debe estar en `pass gitea/webhook-secret` o env var.
|
||||
- Si el receptor se cae, los pushes se pierden (no hay queue). Mejora futura: redis/sqlite queue.
|
||||
- Cuidado con loops: commits que GENERA el bot pueden disparar webhooks.
|
||||
@@ -0,0 +1,65 @@
|
||||
---
|
||||
name: osint-person-lookup
|
||||
id: 0005
|
||||
status: pending
|
||||
created: 2026-05-16
|
||||
updated: 2026-05-16
|
||||
priority: medium
|
||||
risk: medium
|
||||
related_issues: [0098]
|
||||
apps:
|
||||
- navegator_dashboard
|
||||
- odr_console
|
||||
- graph_explorer
|
||||
- agents_and_robots
|
||||
trigger: manual
|
||||
schedule: ""
|
||||
expected_runtime_s: 300
|
||||
tags: [osint, multi-tab, parallel, graph]
|
||||
---
|
||||
|
||||
## Goal
|
||||
|
||||
Probar paralelismo (multiples scraping jobs concurrentes) + agregacion a grafo. Demuestra que graph_explorer cierra el circulo visualizando datos extraidos.
|
||||
|
||||
## Pre-requisitos
|
||||
|
||||
- odr_console activa (jobs queue).
|
||||
- Chrome con sesiones activas en LinkedIn / Twitter / GitHub (no automatizar login).
|
||||
- `projects/osint_graph/operations.db` accesible (graph_explorer la lee).
|
||||
- claude CLI para resumen final.
|
||||
|
||||
## Flow
|
||||
|
||||
1. Input: nombre + apellido (`Juan Perez`).
|
||||
2. odr_console crea 3 jobs concurrentes:
|
||||
- Job A: navegator recipe `osint_linkedin_search.yaml` con query `{name}`.
|
||||
- Job B: navegator recipe `osint_twitter_search.yaml` con query `{name}`.
|
||||
- Job C: navegator recipe `osint_github_search.yaml` con query `{name}`.
|
||||
3. Cada job extrae snippets: `{source, url, title, snippet, timestamp}`.
|
||||
4. Cada snippet -> insert en `projects/osint_graph/operations.db` como entity `Snippet` + relations `mentions(Person, Snippet)`.
|
||||
5. graph_explorer abre el operations.db -> renderiza red de menciones.
|
||||
6. `claude -p` resume hallazgos en Markdown: dada lista de snippets, devuelve `{summary, confidence, suggested_next_steps}`.
|
||||
7. Sink: report `.md` en `projects/osint_graph/reports/<person>-<date>.md`.
|
||||
8. Matrix bot envia link al report.
|
||||
|
||||
## Acceptance
|
||||
|
||||
- [ ] 3 recipes osint creadas (LinkedIn, Twitter, GitHub).
|
||||
- [ ] odr_console lanza 3 jobs paralelos sin race conditions.
|
||||
- [ ] >= 5 snippets totales en operations.db.
|
||||
- [ ] graph_explorer renderiza grafo con >=1 Person + N Snippets.
|
||||
- [ ] Claude resumen generado y valido (no error).
|
||||
- [ ] Report .md commiteado en repo osint_graph.
|
||||
|
||||
## Telemetria esperada
|
||||
|
||||
- 3 runs en `data_factory.runs` (uno por source).
|
||||
- `operations.db` de osint_graph: entities += N, relations += N.
|
||||
- `function_stats.claude_cli_prompt_py_infra`: calls += 1.
|
||||
|
||||
## Notas
|
||||
|
||||
- Consideracion legal: extracciones publicas (perfiles abiertos). NO bypassear paywalls/captchas.
|
||||
- LinkedIn detecta scraping agresivo -> usar rate-limit por job en navegator.
|
||||
- Caso ambicioso (5 apps + paralelismo + LLM). Reservar como hito.
|
||||
@@ -0,0 +1,78 @@
|
||||
---
|
||||
name: metabase-versioning
|
||||
id: 0006
|
||||
status: pending
|
||||
created: 2026-05-16
|
||||
updated: 2026-05-16
|
||||
priority: medium
|
||||
risk: medium
|
||||
related_issues: []
|
||||
apps:
|
||||
- auto_metabase
|
||||
- dag_engine
|
||||
- agents_and_robots
|
||||
trigger: cron
|
||||
schedule: "0 2 * * *"
|
||||
expected_runtime_s: 60
|
||||
tags: [metabase, sync, gitops, backup]
|
||||
---
|
||||
|
||||
## Goal
|
||||
|
||||
Probar flujo INVERSO al tipico: extraer estado de un servicio interno (Metabase) y persistirlo como codigo. Sirve de backup + auditoria + reproducibilidad.
|
||||
|
||||
## Pre-requisitos
|
||||
|
||||
- Metabase corriendo (local docker o produccion).
|
||||
- `auto_metabase` configurado con credenciales (`METABASE_URL`, `METABASE_TOKEN`).
|
||||
- `projects/metabase_registry/` existe con sub-repo git inicializado.
|
||||
|
||||
## Flow
|
||||
|
||||
1. DAG `metabase-snapshot.yaml` diario 02:00:
|
||||
```yaml
|
||||
name: metabase-snapshot
|
||||
schedule: "0 2 * * *"
|
||||
steps:
|
||||
- name: pull_metabase
|
||||
function: auto_metabase_pull_bash_pipelines
|
||||
args: ["--target", "projects/metabase_registry"]
|
||||
- name: git_diff_check
|
||||
command: cd projects/metabase_registry && git diff --stat
|
||||
- name: commit_if_changes
|
||||
command: |
|
||||
cd projects/metabase_registry
|
||||
git add -A
|
||||
if ! git diff --cached --quiet; then
|
||||
git commit -m "snapshot: $(date -u +%FT%TZ)"
|
||||
git push origin master
|
||||
echo "CHANGES_PUSHED"
|
||||
else
|
||||
echo "NO_CHANGES"
|
||||
fi
|
||||
depends: [pull_metabase]
|
||||
- name: notify
|
||||
function: matrix_send_message_<id>
|
||||
args: ["#fn-registry-ops", "Metabase snapshot: <stdout from prev step>"]
|
||||
depends: [commit_if_changes]
|
||||
```
|
||||
2. data_factory: node `metabase_snapshot` kind=extractor (source=metabase). Tag `gitops`.
|
||||
3. Verificar que YAML files generados son legibles y diff-friendly.
|
||||
|
||||
## Acceptance
|
||||
|
||||
- [ ] DAG corre 3 dias consecutivos sin error.
|
||||
- [ ] >=1 commit registrado en repo `metabase_registry`.
|
||||
- [ ] data_factory.runs muestra historico.
|
||||
- [ ] Matrix recibe 1 mensaje/dia (con "NO_CHANGES" o "CHANGES_PUSHED").
|
||||
- [ ] Si se rompe un dashboard manualmente en Metabase -> push de YAML viejo lo restaura (test).
|
||||
|
||||
## Telemetria esperada
|
||||
|
||||
- 1 run/dia en data_factory.
|
||||
- 7 commits en metabase_registry repo (1 semana baseline).
|
||||
|
||||
## Notas
|
||||
|
||||
- Riesgo: si Metabase token expira, el DAG falla silenciosamente. Anadir healthcheck pre-pull.
|
||||
- Restore es manual hoy. Futuro: comando `auto_metabase push --from-commit <SHA>`.
|
||||
@@ -0,0 +1,79 @@
|
||||
---
|
||||
name: matrix-telemetry-bot
|
||||
id: 0007
|
||||
status: pending
|
||||
created: 2026-05-16
|
||||
updated: 2026-05-16
|
||||
priority: high
|
||||
risk: low
|
||||
related_issues: [0085]
|
||||
apps:
|
||||
- data_factory
|
||||
- dag_engine
|
||||
- call_monitor
|
||||
- agents_and_robots
|
||||
trigger: webhook
|
||||
schedule: ""
|
||||
expected_runtime_s: 1
|
||||
tags: [observability, alerts, matrix, sink]
|
||||
---
|
||||
|
||||
## Goal
|
||||
|
||||
Probar agents_and_robots como sink universal de telemetria. Cada falla critica en cualquier app dispara un mensaje a sala Matrix `#fn-registry-ops`. Cierra el bucle observability del stack.
|
||||
|
||||
## Pre-requisitos
|
||||
|
||||
- Bot Matrix activo, joineado a `#fn-registry-ops`.
|
||||
- `agents_and_robots` con accion `matrix_send_message` operativa.
|
||||
- Variables expuestas como funcion del registry: `matrix_send_message_py_infra` o equivalente.
|
||||
|
||||
## Flow
|
||||
|
||||
Tres triggers distintos, mismo sink.
|
||||
|
||||
### Trigger 1: data_factory run failed
|
||||
|
||||
1. En `data_factory_record_run_py_pipelines`, si `status == 'failed'` -> tambien llama `matrix_send_message`.
|
||||
2. Formato:
|
||||
```
|
||||
:rotating_light: <node_id> FAILED in <duration_ms>ms
|
||||
error: <error[:200]>
|
||||
```
|
||||
|
||||
### Trigger 2: dag_engine DAG final status
|
||||
|
||||
1. En executor de dag_engine, handler `on_failure` invoca `matrix_send_message`.
|
||||
2. Formato:
|
||||
```
|
||||
:x: DAG <dag_name> run <run_id> FAILED
|
||||
step <step_name> exit <code>
|
||||
```
|
||||
|
||||
### Trigger 3: call_monitor anomaly
|
||||
|
||||
1. Cron 1h analiza `call_monitor.violations_24h`. Si > threshold (default 50):
|
||||
```
|
||||
:warning: violations_24h = <N> (threshold <T>) — top rules: <rule_ids>
|
||||
```
|
||||
2. Si `error_rate_7d > 0.1` para alguna funcion top -> alert.
|
||||
|
||||
## Acceptance
|
||||
|
||||
- [ ] `matrix_send_message_py_infra` existe en el registry (crear si no — usa agents_and_robots backend).
|
||||
- [ ] Trigger 1 dispara mensaje cuando un node de data_factory falla deliberadamente.
|
||||
- [ ] Trigger 2 dispara mensaje cuando un DAG falla (test con DAG que falla a proposito).
|
||||
- [ ] Trigger 3 dispara mensaje cuando se inyectan violations sinteticas.
|
||||
- [ ] Mensajes llegan en <3 segundos del evento.
|
||||
|
||||
## Telemetria esperada
|
||||
|
||||
- `function_stats.matrix_send_message_*`: calls dependientes de eventos reales.
|
||||
- Sala Matrix recibe mensajes de los 3 origenes.
|
||||
|
||||
## Notas
|
||||
|
||||
- Throttling: max 1 mensaje/minuto por origen para evitar spam.
|
||||
- Severidad: prefix emoji indica nivel.
|
||||
- Mejora futura: comandos en sala (`!status`, `!ack <run_id>`) para responder desde Matrix.
|
||||
- Pre-condicion: `agents_and_robots` necesita estar deployado + bot autenticado.
|
||||
@@ -0,0 +1,239 @@
|
||||
# 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.
|
||||
|
||||
## 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`).
|
||||
@@ -0,0 +1,22 @@
|
||||
# Flows Index
|
||||
|
||||
Tabla de casos de uso multi-app. Mantenida por `/flow create` y `/flow done`.
|
||||
|
||||
| ID | Slug | Apps | Status | Risk | Updated |
|
||||
|----|------|------|--------|------|---------|
|
||||
| [0001](0001-hn-top-stories.md) | hn-top-stories | navegator_dashboard, dag_engine, data_factory, agents_and_robots | pending | low | 2026-05-16 |
|
||||
| [0002](0002-aemet-madrid.md) | aemet-madrid | dag_engine, data_factory, footprint_geo_stack | pending | low | 2026-05-16 |
|
||||
| [0003](0003-bbva-movimientos.md) | bbva-movimientos | navegator_dashboard, dag_engine, data_factory, auto_metabase | pending | high | 2026-05-16 |
|
||||
| [0004](0004-gitea-releases-monitor.md) | gitea-releases-monitor | registry_api, data_factory, agents_and_robots | pending | low | 2026-05-16 |
|
||||
| [0005](0005-osint-person-lookup.md) | osint-person-lookup | navegator_dashboard, odr_console, graph_explorer | pending | medium | 2026-05-16 |
|
||||
| [0006](0006-metabase-versioning.md) | metabase-versioning | auto_metabase, dag_engine | pending | medium | 2026-05-16 |
|
||||
| [0007](0007-matrix-telemetry-bot.md) | matrix-telemetry-bot | data_factory, dag_engine, call_monitor, agents_and_robots | pending | low | 2026-05-16 |
|
||||
|
||||
## Leyenda
|
||||
|
||||
- **Status**: `pending` (no arrancado) / `running` / `done` / `failed` / `deferred`.
|
||||
- **Risk**: `low` (datos publicos), `medium` (auth pero no sensible), `high` (datos personales/financieros).
|
||||
|
||||
## Completados
|
||||
|
||||
Ver `completed/` para flows cerrados.
|
||||
@@ -0,0 +1,110 @@
|
||||
# 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.
|
||||
- Cerrados se mueven a `completed/`.
|
||||
|
||||
## 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.
|
||||
@@ -0,0 +1,87 @@
|
||||
---
|
||||
name: <slug>
|
||||
id: NNNN
|
||||
status: pending
|
||||
created: YYYY-MM-DD
|
||||
updated: YYYY-MM-DD
|
||||
priority: medium # low | medium | high
|
||||
risk: low # low | medium | high (sensibilidad datos)
|
||||
related_issues: []
|
||||
apps: [] # apps tocadas — usadas por /flow list --app
|
||||
projects: [] # projects relacionados
|
||||
vaults: [] # vaults sink/source
|
||||
capability_groups: [] # extractor, transformer, sink, navegator, ...
|
||||
trigger: manual # manual | cron | webhook
|
||||
schedule: "" # cron expr si trigger=cron
|
||||
expected_runtime_s: 60
|
||||
tags: []
|
||||
---
|
||||
|
||||
## Goal
|
||||
|
||||
Una frase: que prueba este flow del sistema multi-app.
|
||||
|
||||
## Pre-requisitos
|
||||
|
||||
- Lista de cosas manuales/externas que deben estar listas antes (Chrome logueado, vault montado, service corriendo, token en `pass`, ...).
|
||||
|
||||
## Funciones del registry recomendadas
|
||||
|
||||
Tabla rol -> funcion candidata (ver `AGENT_GUIDE.md` para discovery). Si falta una pieza: marca `FALTA: crear <id>` con prompt sugerido para fn-constructor.
|
||||
|
||||
| Rol | Funcion candidata | Estado |
|
||||
|---|---|---|
|
||||
| Extractor | `<id>` | OK / FALTA |
|
||||
| Validator | `<id>` | OK / FALTA |
|
||||
| Transformer | `<id>` | OK / FALTA |
|
||||
| Sink | `<id>` | OK / FALTA |
|
||||
| Scheduler | DAG `<path>.yaml` / webhook / manual | OK / FALTA |
|
||||
| Notify | `<id>` | OK / FALTA |
|
||||
|
||||
## Apps tocadas
|
||||
|
||||
- `<app>` (rol en el flow)
|
||||
|
||||
## Projects relacionados
|
||||
|
||||
- `<project>` (razon)
|
||||
|
||||
## Vaults / storage
|
||||
|
||||
- `<vault o BD>` (origin / sink)
|
||||
|
||||
## Capability groups consultados
|
||||
|
||||
- `<group>` (ver `docs/capabilities/<group>.md`)
|
||||
|
||||
## Flow
|
||||
|
||||
Pasos numerados. Cada paso puede ser:
|
||||
- texto libre (manual)
|
||||
- `function: <id>` (registry function)
|
||||
- `cmd: <bash>`
|
||||
- `js: <expression>` (en tab Chrome)
|
||||
- `dag: <name>` (DAG en `apps/dag_engine/dags_migrated/`)
|
||||
|
||||
1. Paso 1.
|
||||
2. Paso 2.
|
||||
|
||||
## Acceptance
|
||||
|
||||
- [ ] Criterio 1.
|
||||
- [ ] Criterio 2.
|
||||
|
||||
## Telemetria esperada
|
||||
|
||||
- `call_monitor.calls`: que aparece.
|
||||
- `data_factory.runs`: que aparece.
|
||||
- `<app>.operations.db`: que aparece.
|
||||
- Matrix / email / dashboard: que aparece visible.
|
||||
|
||||
## Riesgos / gotchas
|
||||
|
||||
- Lista de cosas que pueden romperse y como detectarlas.
|
||||
|
||||
## Notas
|
||||
|
||||
(rellenas tras correr o tras hallazgos)
|
||||
Reference in New Issue
Block a user