feat(infra): auto-commit con 29 cambios
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -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.
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user