a03675113a
- .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>
241 lines
12 KiB
Markdown
241 lines
12 KiB
Markdown
---
|
|
description: "Auto-auditoria: verifica que la sesion registra uso de funciones, detecta gaps (patrones inline repetidos, wrappers saltados, heredocs sin function_id), lanza fn-constructor en paralelo para crear las funciones que faltan, y valida que Claude usara las nuevas en el siguiente turno"
|
|
---
|
|
|
|
# /fn_claude — auto-auditoria + auto-construccion del registry
|
|
|
|
Comando meta: Claude se audita a si mismo. Verifica que su comportamiento en esta sesion (y las recientes) deja rastro en `call_monitor.operations.db`, detecta gaps reales del registry para el trabajo actual, lanza sub-agentes `fn-constructor` en paralelo para cerrar esos gaps, y verifica que la proxima vez usara las funciones nuevas.
|
|
|
|
## Objetivos del registry (Norte) — Issues 0086 + 0087
|
|
|
|
Cada corrida de `/fn_claude` optimiza 4 metricas visibles en Monitor tab del `registry_dashboard`:
|
|
|
|
1. **MAXIMIZAR `Reg %`** — % de calls con `function_id != ''`. Cada heredoc/bash que reescribe logica baja el ratio. Target: subir cada semana.
|
|
2. **MEJORAR uso del registry por Claude** — Claude busca y reusa antes de escribir. `MCP` (mcp/heredoc/fn run) sube, `violations` baja. Si una funcion existe pero Claude no la encuentra, mejorar su `description`/`tags`/`params_schema` (FTS indexa todo).
|
|
3. **ACELERAR tareas comunes** — patrones inline repetidos >2x -> `fn-constructor` los convierte en funcion, Claude las usa el siguiente turno. Menos pasos por tarea = mas valor.
|
|
4. **PROMOVER COMPOSICIONES A PIPELINES** (issue 0087) — el registry crece **promoviendo secuencias A->B(->C) que se repiten con exito** a pipelines one-shot. Una funcion que hace bien una cosa NO necesita crecer. Pattern detection: `call_monitor sequences --detect --propose` (cron 6h activo) + tab `Promotion candidates` del dashboard.
|
|
|
|
Si `/fn_claude` no mueve estas 4 metricas, no esta haciendo su trabajo.
|
|
|
|
## Infraestructura de discovery activa (issue 0087)
|
|
|
|
Cada turno tienes capacidades ya cargadas SIN buscar. Si no las usas estas pagando el coste de FTS innecesariamente:
|
|
|
|
| Senal | Donde | Que hacer |
|
|
|---|---|---|
|
|
| Linea `CAPABILITIES (cache 1h): TOP: ... FRESH (7d): ... PIPELINES: ...` en cada UserPromptSubmit | hook `hook_capabilities_inject.sh` | Antes de buscar con `mcp__registry__fn_search`, mira si la funcion que necesitas esta en TOP/FRESH/PIPELINES. Si si, ve directo a `fn show <id>` (1 read) o `./fn run <id>` (0 reads). |
|
|
| `<system-reminder>FUZZY-MATCH (issue 0087): your Bash command may already be a function. USE: ./fn run <id> -> <signature>` aparecido mid-flight | hook `hook_fn_match.sh` (PreToolUse, Bash matcher) | El hook detecto que tu Bash inline coincide con una funcion del registry. **NO ignores el reminder** — abandona el inline, llama a `./fn run <id>` o `mcp__registry__fn_run id="<id>"`. Si crees que la sugerencia es falso positivo, justifica brevemente antes de seguir inline (queda en violations). |
|
|
| Hint AUSENTE para una query corta (`rsi sma` < 3 tokens) | threshold `raw_score >= 4.0` no alcanzado | NO interpretar la ausencia de hint como "no existe funcion". Usa `mcp__registry__fn_search` con query mas rica (3+ tokens del dominio). |
|
|
| Falso positivo conocido: `agent` token | `robots.txt user-agent` matchea `agent_scaffold` | Ignora el reminder y sigue. Cost = 1 reminder ignorable. |
|
|
|
|
## Como combinar la 3 senales para minimizar pasos
|
|
|
|
1. **User prompt llega** -> lees `CAPABILITIES` line. Si la tarea encaja claramente con TOP/FRESH -> usa directo.
|
|
2. **Vas a escribir Bash inline** -> el hook PreToolUse lo intercepta. Si dispara FUZZY-MATCH -> usa `./fn run <id>`.
|
|
3. **No hay match y necesitas codigo** -> `mcp__registry__fn_search` con 3+ tokens. Si sigue sin hit -> delega a `fn-constructor` (no escribas inline). Patron repetido detectado por `call_monitor sequences` se promovera a pipeline en proximas iteraciones.
|
|
|
|
## Las 4 metricas norte (donde vigilarlas)
|
|
|
|
- `Reg %` (Monitor KPI) — % calls con function_id no vacio. Sube cuando el registry se usa.
|
|
- `MCP` (Monitor KPI) — count calls con tools registry-aware (mcp*/heredoc*/fn_cli_run). Adopcion de patrones canonicos.
|
|
- `Errors` / `Violations` (Monitor KPI) — bajan cuando el bucle cierra.
|
|
- `Failed Functions` (Monitor sub-tab) — registry-functions que fallaron: diagnostico de bugs prioritarios.
|
|
|
|
Issue 0085 fase autocompleta. Reemplaza el flujo manual de "veo un patron, decido si extraer, escribo proposal, espero humano, fn-mejorador genera, fn-orquestador opera". Con `/fn_claude` Claude hace todo eso solo, **autonomamente para si mismo**.
|
|
|
|
---
|
|
|
|
## Comportamiento (ejecutalo en este orden)
|
|
|
|
### 1. AUDIT — ¿estoy siendo registrado?
|
|
|
|
```bash
|
|
ROOT="/home/lucas/fn_registry"
|
|
MON="$ROOT/projects/fn_monitoring/apps/call_monitor/operations.db"
|
|
|
|
# Pre-condiciones
|
|
[ -f "$MON" ] || { echo "call_monitor.operations.db NO existe — issue 0085a no aplicado"; exit 1; }
|
|
[ "$FN_TELEMETRY" = "1" ] || echo "WARNING: FN_TELEMETRY != 1 — wrappers Python/Bash inactivos"
|
|
|
|
# Metricas de la sesion actual + ultimas 24h
|
|
sqlite3 "$MON" <<SQL
|
|
SELECT 'calls_session', COUNT(*) FROM calls WHERE session_id = '${CLAUDE_SESSION_ID:-unknown}'
|
|
UNION ALL SELECT 'calls_24h', COUNT(*) FROM calls WHERE ts >= CAST(strftime('%s','now','-1 day') AS INTEGER)
|
|
UNION ALL SELECT 'violations_24h', COUNT(*) FROM violations WHERE ts >= CAST(strftime('%s','now','-1 day') AS INTEGER)
|
|
UNION ALL SELECT 'tool_used_distribution_24h', NULL;
|
|
SELECT tool_used, COUNT(*) FROM calls WHERE ts >= CAST(strftime('%s','now','-1 day') AS INTEGER) GROUP BY tool_used ORDER BY 2 DESC;
|
|
SQL
|
|
```
|
|
|
|
Si `calls_session = 0` → algo esta mal (hook PostToolUse no fire o BD no escribible). Reporta y para.
|
|
|
|
Si `mcp_*` / total < 0.4 → estas usando demasiado heredoc/sqlite directo. Reporta como warning.
|
|
|
|
### 2. GAP — ¿que funciones faltan?
|
|
|
|
Dos fuentes:
|
|
|
|
#### 2a. Patrones repetidos en heredocs/Edit
|
|
|
|
```sql
|
|
-- En call_monitor.operations.db
|
|
SELECT tool_used, COUNT(*) AS hits
|
|
FROM calls
|
|
WHERE function_id = ''
|
|
AND ts >= CAST(strftime('%s','now','-7 days') AS INTEGER)
|
|
AND tool_used IN ('heredoc_py', 'heredoc_bash', 'sqlite_direct')
|
|
GROUP BY tool_used;
|
|
```
|
|
|
|
Si `heredoc_py > 5` sin function_id → Claude esta componiendo logica que probablemente debe ser pipeline. Investigar el ultimo heredoc del transcript: si reescribe algo que ya es funcion del registry → violation candidate. Si no, es candidato a pipeline nuevo.
|
|
|
|
#### 2b. Trabajo actual de la sesion — gap inferido del contexto
|
|
|
|
Lee el ultimo prompt del usuario y los ultimos 10 turnos. Lista funciones que:
|
|
|
|
- Has llamado inline (sed/awk/jq custom, transformaciones de datos, parsing).
|
|
- Has reinventado (HTTP client raw, SQLite open con flags, FS walks).
|
|
- Has compuesto >2 veces con el mismo shape.
|
|
|
|
Para cada candidato:
|
|
|
|
```bash
|
|
# Verifica si ya existe algo similar en el registry
|
|
mcp__registry__fn_search "<keyword del candidato>"
|
|
```
|
|
|
|
Si NO existe match relevante → candidato a `fn-constructor`.
|
|
Si existe pero firma incompleta → candidato a `improve_function` (proposal, NO auto-construccion).
|
|
|
|
### 3. PROPOSE — lista candidatos
|
|
|
|
Genera tabla:
|
|
|
|
```
|
|
| Candidato | Razon | Lenguaje | Dominio | Evidencia (snippet) |
|
|
|---|---|---|---|---|
|
|
| <name> | inline_repeated/wrapper_skip/new | go/py/bash | core/infra/... | <heredoc fragment> |
|
|
```
|
|
|
|
Si lista vacia → "no gaps detected, sesion saludable" + reporta metricas. Para.
|
|
|
|
### 4. CONSTRUCT — lanza fn-constructor en paralelo
|
|
|
|
Para cada candidato, dispara un sub-agente `fn-constructor` con prompt autocontenido:
|
|
|
|
```
|
|
Agent(subagent_type="fn-constructor", prompt=...)
|
|
```
|
|
|
|
Prompts en PARALELO en un mismo mensaje (varios Agent calls). Pasar:
|
|
- nombre propuesto, lang, domain
|
|
- firma esperada (params + return)
|
|
- pureza
|
|
- descripcion + ejemplo de uso (heredoc real detectado)
|
|
- nota: "esta funcion la necesita Claude para auto-uso futuro"
|
|
|
|
### 5. VALIDATE — ¿la proxima sesion la usara?
|
|
|
|
Despues de que fn-constructor termine:
|
|
|
|
```bash
|
|
./fn index 2>&1 | tail -2
|
|
# Verifica que las nuevas funciones existen
|
|
for fn in <lista>; do
|
|
mcp__registry__fn_show "$fn" >/dev/null && echo "OK: $fn" || echo "FAIL: $fn"
|
|
done
|
|
```
|
|
|
|
Tambien actualiza `call_monitor.copied_code` + `function_stats` corriendo:
|
|
|
|
```bash
|
|
cd "$ROOT/projects/fn_monitoring/apps/call_monitor" && ./call_monitor copied-code && ./call_monitor propose
|
|
```
|
|
|
|
### 5b. MEMORIZE — anadir cada funcion nueva a MEMORY.md (issue 0087 pieza 6)
|
|
|
|
Por cada funcion creada con exito, llama:
|
|
|
|
```bash
|
|
bash "$ROOT/.claude/scripts/append_fn_to_memory.sh" "<fn_id>" "<one-line purpose>"
|
|
```
|
|
|
|
El script es idempotente (si la fn ya esta linkeada, no duplica). Crea `reference_fn_<id>.md` con metadata `type: reference` e indexa la entrada en `MEMORY.md` como linea `- [fn-<id>](reference_fn_<id>.md) — <purpose>`. Asi proximas sesiones cargan MEMORY.md y ven el catalogo de funciones recien creadas sin segunda lookup.
|
|
|
|
`purpose` = 1 frase derivada del `description` del .md de la funcion (max 80 chars). Si description es larga, recorta. Ejemplo:
|
|
- fn_id: `parse_http_log_go_infra`
|
|
- purpose: "parsea log Apache/Nginx a struct; pure"
|
|
|
|
Reporta:
|
|
- N funciones nuevas creadas (con IDs)
|
|
- N proposals nuevas en `registry.db.proposals`
|
|
- Recomendacion al usuario: "proximo turno mencionar/usar `<fn_id>` para validar que el wrapper se invoca correctamente"
|
|
|
|
### 6. SELF-TEST — telemetria del propio /fn_claude
|
|
|
|
`/fn_claude` mismo debe quedar registrado. Tras ejecutar, query final:
|
|
|
|
```bash
|
|
sqlite3 "$MON" "SELECT COUNT(*) FROM calls WHERE session_id = '${CLAUDE_SESSION_ID:-unknown}' AND ts >= <inicio_comando>"
|
|
```
|
|
|
|
Si la cuenta no aumento → el comando esta operando fuera de la telemetria (bug). Reportar.
|
|
|
|
---
|
|
|
|
## Reglas duras
|
|
|
|
1. **NO ejecutar fn-constructor para algo que ya existe.** Buscar primero via `mcp__registry__fn_search`. Si match relevante → NO crear duplicado.
|
|
2. **NO crear funciones especulativas.** Cada candidato debe tener evidencia real (snippet de heredoc o llamada inline detectada en esta sesion o en `call_monitor.calls` reciente).
|
|
3. **PARALELO**: si hay >1 candidato, lanza todos los `fn-constructor` en un solo mensaje con multiples `Agent` calls. NO secuencial.
|
|
4. **No autonomous merge**: las funciones nuevas viven en el branch local. NO push automatico. Humano revisa y push manual.
|
|
5. **Limites duros**: max 5 funciones nuevas por invocacion. Si detectas mas, prioriza por evidence weight (`occurrences * recency`) y reporta el resto como pending.
|
|
6. **Si la sesion no esta siendo registrada (`calls_session = 0`)**: ABORT antes de fase 2. No tiene sentido auto-construir sin telemetria.
|
|
|
|
---
|
|
|
|
## Output canonico
|
|
|
|
```
|
|
=== /fn_claude — auto-auditoria ===
|
|
session_id: <id>
|
|
calls_session: N
|
|
calls_24h: M (mcp_ratio: 0.XX)
|
|
violations_24h: K
|
|
pending_proposals: P (existentes en registry.db)
|
|
|
|
GAPS DETECTADOS:
|
|
1. <name>_<lang>_<domain> — razon — evidencia
|
|
2. ...
|
|
|
|
LANZADOS (en paralelo):
|
|
fn-constructor #1: <name1> → en progreso
|
|
fn-constructor #2: <name2> → en progreso
|
|
...
|
|
|
|
VALIDADAS tras ./fn index:
|
|
✓ <name1>_<lang>_<domain>
|
|
✓ <name2>_<lang>_<domain>
|
|
|
|
PROPOSALS NUEVAS: <count>
|
|
|
|
PROXIMO TURNO: menciona `<name1>` para validar wrapper.
|
|
```
|
|
|
|
---
|
|
|
|
## Cuando usar
|
|
|
|
- Al inicio de una sesion larga, para verificar telemetria activa.
|
|
- A media sesion, cuando notes que estas reescribiendo el mismo bloque.
|
|
- Antes de cerrar sesion, para capitalizar lo aprendido como funciones reutilizables.
|
|
- Tras `/autonomous-task` para validar que el orquestador no genero ruido (proposals/funciones huerfanas).
|
|
|
|
---
|
|
|
|
## Cuando NO usar
|
|
|
|
- En sesiones cortas (<5 turnos) — no hay datos suficientes.
|
|
- Si `call_monitor.operations.db` no esta inicializado (`call_monitor init` primero).
|
|
- Si el usuario quiere control manual del proceso de extraccion. Este comando es agresivo.
|