feat(infra): auto-commit con 29 cambios

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-14 02:06:44 +02:00
parent 47fac22230
commit ca1bf5a59b
29 changed files with 2148 additions and 11 deletions
+1
View File
@@ -33,3 +33,4 @@ Reglas operativas del proyecto. Cada archivo es una regla independiente.
| 27 | [registry_calls.md](registry_calls.md) | Patrones canonicos para invocar funciones del registry (MCP inspect / MCP run / heredoc compose), antipatrones, excepciones, telemetria. Issue 0085 |
| 28 | [delegation.md](delegation.md) | Si vas a escribir logica reutilizable inline -> spawn fn-constructor inmediato + tag de grupo + usar en mismo turno. Issue 0086 |
| 29 | [capability_groups.md](capability_groups.md) | Tags planos + paginas madre `docs/capabilities/<grupo>.md` para desbloquear clusters de funciones en un read. Issue 0086 |
| 30 | [function_growth_and_self_docs.md](function_growth_and_self_docs.md) | Contrato self-doc de cada `.md` (Ejemplo + Cuando usarla + Gotchas + Growth log) + crecimiento del registry por **promocion de composiciones** a pipelines, NO por inflado de funciones. Issue 0087 |
@@ -0,0 +1,115 @@
## Function growth + self-documenting capability
Dos doctrinas hermanas. Una define **como deben ser** las funciones (auto-descubribles y lanzables sin segunda lectura). La otra define **como crece** el registry (no inflando funciones — promoviendo composiciones a pipelines).
Issue 0087.
---
### Parte A — `.md` autosuficiente (contrato OBLIGATORIO)
Cuando Claude (o un humano) encuentra una funcion via FTS / fuzzy match / capability page / TOP block, el `.md` debe bastar para **lanzarla sin abrir el codigo**. Esto es lo que hace que descubrir = lanzar y elimina el coste del second lookup.
**Secciones obligatorias** en cada `.md` del registry (functions + pipelines + types con uso practico):
| Seccion | Contenido | Tamaño |
|---|---|---|
| Frontmatter | `name`, `signature`, `params` (con `desc` por param), `output`, `tags`, `uses_functions`, etc. Lo de hoy. | — |
| `## Ejemplo` | Bloque de codigo lanzable con args **concretos**. Copiar+pegar produce ejecucion real. NO placeholders abstractos. | 3-10 lineas |
| `## Cuando usarla` | 1-2 frases con triggers: "cuando hagas X / antes de Y / si necesitas Z". Verbos imperativos. Ayuda al fuzzy match y a Claude a saber sin leer el codigo. | 1-3 lineas |
| `## Gotchas` | Problemas conocidos / no-go cases. Obligatoria para funciones impuras o con efectos (Windows-side, red, FS write, GPU). Omisible para funciones puras triviales. | 0-5 puntos |
| `## Capability growth log` | Solo SI la funcion ha crecido. Una linea por version: `v1.1.0 (YYYY-MM-DD) — anade --build flag para skip build`. No se rellena en v1.0.0. | crece con el tiempo |
**Anti-patrones del .md:**
- Ejemplo con `<arg1>`, `<arg2>` placeholders abstractos — NO. Ejemplos con valores reales (`registry_dashboard`, `/home/lucas/...`).
- "Cuando usarla" vacio o "ver descripcion arriba" — NO. Frase nueva con trigger explicito.
- `notes` lleno + `## Gotchas` vacio cuando la funcion tiene efectos — mover de `notes` a `## Gotchas`.
- Capability growth log inventado (sin que la funcion haya cambiado) — NO. Solo se rellena cuando hay version bump real.
**Verificacion** (TBD: convertir a check de `fn doctor`): cada .md de `functions/`/`pipelines/` debe tener `## Ejemplo` y `## Cuando usarla`. `## Gotchas` obligatoria solo si `purity: impure`. `## Capability growth log` libre.
---
### Parte B — Crecimiento por composicion (no por inflado)
**Principio:** una funcion que hace bien UNA cosa NO necesita crecer. Anadir params "por si acaso" la hace peor (Inner Platform Effect). Lo que crece es el **registry**: pipelines nuevos que componen funciones existentes.
#### Ejemplo del principio
- **Hoy:** Claude para hacer una transferencia bancaria llama `bank_login` -> `bank_list_accounts` -> `bank_make_transfer`. 3 calls, 3 decisiones, 3 puntos de fallo.
- **Manana:** pipeline `bank_transfer_oneshot(account, amount, target)` que compone las 3 internamente. 1 call, 1 decision.
Misma capacidad, 3x menos pasos. **Esto es lo que multiplica la velocidad de Claude**, no anadir flags a `bank_login`.
#### Como se promueve una composicion
Senal detectable en `call_monitor.operations.db`: secuencia A→B(→C) con
- **Mismo session_id**.
- **Intervalo entre calls < N segundos** (default 30s).
- **Occurrences > K** (default 5) en ventana de **D dias** (default 30).
- **Success rate > S** (default 0.9 — falla < 10%).
- **No existe ya un pipeline** que la cubra (validar con FTS sobre `uses_functions`).
Cuando se cumple → **proposal `new_pipeline`** con evidencia (sequence_ids, session_ids, occurrence count). Humano (o `fn-orquestador` autonomo) decide promover.
#### Implementacion (issue 0087 tanda A)
- `call_monitor sequences --detect` subcomando: escanea `calls` table, agrupa por session+window, computa secuencias, upserta en tabla `function_sequences`.
- Cron diario que ejecuta el detector + genera proposals automaticas.
- Visible en Monitor tab del `registry_dashboard`: sub-tab "Promotion candidates".
#### Cuando SI inflar una funcion
Casos legitimos para anadir feature a una funcion existente:
1. **Generalizar firma** sin romper consumidores (anadir param opcional con default sensato).
2. **Mejor manejo de error** (mensajes mas claros, retry sensible).
3. **Default mas inteligente** (autodetectar lo que antes era arg obligatorio).
4. **Eliminar gotcha conocido** (fix de bug que estaba en `## Gotchas`).
NO infles para casos hipoteticos. NO anadas params "por flexibilidad". Si dudas, separa la responsabilidad en una funcion nueva o un pipeline.
#### Capability growth log — cuando se rellena
- Se rellena **solo cuando la funcion crece** (alguno de los 4 casos arriba).
- Cada bump de `version` -> 1 linea en `## Capability growth log` con fecha y resumen 1-frase.
- Una funcion estable de hace 6 meses puede seguir en v1.0.0 sin log: indica madurez, no abandono.
- Telemetria (call_monitor) decide si una funcion estable es huerfana (`calls_90d=0`) o usada-y-buena (`calls_30d>10, error_rate<0.05`). Las primeras se deprecan; las segundas se respetan.
---
### Parte C — Output de discovery
Cuando un mecanismo de discovery (fuzzy match / FRESH hook / TOP block / capability page) surfacea una funcion, el payload **minimo** es:
```
<id> → <signature> → <ejemplo de 1 linea>
```
Ejemplo concreto:
```
redeploy_cpp_app_windows_bash_pipelines
./fn run redeploy_cpp_app_windows registry_dashboard /path/to/app [--build]
use: tras compilar cpp/build/windows, antes de smoke test manual
```
Si Claude necesita mas (gotchas, params completos, codigo), un `mcp__registry__fn_show <id>` adicional. Pero el primer hit ya basta para el 80% de casos.
---
### Parte D — Relacion con otras reglas
- [[registry_first]] dice CUANDO buscar/usar/delegar. Esta regla dice **COMO** debe ser la funcion para que esa busqueda valga.
- [[ids_naming]] hace ID predictible. Esta regla hace metadata predictible.
- [[delegation]] dice cuando spawnar fn-constructor. Esta regla es lo que fn-constructor debe producir.
- [[capability_groups]] agrupa funciones afines. Las paginas madre de cada grupo deben respetar el mismo contrato self-doc (mejor con su propio ejemplo end-to-end por grupo).
### Resumen TL;DR
1. Cada `.md` autosuficiente: Ejemplo + Cuando usarla + Gotchas (si impura) + Growth log (si crecio).
2. Las funciones que hacen bien una cosa NO necesitan crecer.
3. El registry crece **promoviendo composiciones repetidas a pipelines**, no inflando funciones.
4. Telemetria de `call_monitor` detecta secuencias candidatas y abre proposals automaticas.
5. Discovery devuelve siempre: `id + signature + 1-line example`. Resto on-demand.
+15
View File
@@ -33,6 +33,21 @@ Casos donde el MCP no aplica y `sqlite3 registry.db` es legitimo:
El hook `PreToolUse` (`.claude/scripts/hook_registry_mcp.sh`) ya deja pasar estas excepciones y solo avisa cuando ve `sqlite3 registry.db "SELECT ..."` plano.
### Excepcion: hooks e infraestructura de telemetria (issue 0087)
Los **hooks** (`PreToolUse`, `PostToolUse`, `UserPromptSubmit`, etc.) y los **binarios de infraestructura** que sirven al agente (`fn_match`, `fn doctor`, `call_monitor`) **pueden leer `registry.db` directo** via `sqlite3` o `database/sql` con conexion read-only. NO estan sujetos a la regla MCP-first porque:
- No son acciones del agente — son inspeccion automatizada del entorno.
- El MCP requiere tool invocation por Claude; un hook no puede invocar tools.
- Latencia objetivo (50-200ms) incompatible con round-trip MCP.
**Restricciones:**
- SOLO lectura. Conexion debe abrirse con `?mode=ro` o `?_query_only=1`.
- NUNCA escritura a `registry.db` desde hooks.
- Si un hook necesita escribir (cache, telemetria propia), usa su propia DB (`operations.db` del app de hooks, o `~/.fn_hooks/cache.db`).
Esta excepcion es **explicita y acotada** — no aplica al agente, que sigue regido por la regla MCP-first.
### Verificacion previa — `fn doctor`
Antes de empezar trabajo no trivial sobre el registry, ejecutar `fn doctor` para confirmar que el ecosistema esta sano: