## Delegacion: spawn fn-constructor en vez de escribir inline **REGLA DURA.** Si vas a escribir logica reutilizable inline en un artefacto (app, analysis, playground) o heredoc, STOP y delega a `fn-constructor`. La misma sesion debe crear + usar la funcion. No acumular huerfanas. ### Cuando un patron es candidato a funcion - Aparece >=2 veces en esta sesion o en heredocs recientes. - Firma generica (no depende de tipos internos del artefacto). - 1 responsabilidad clara (CRUD, parse, transform, http call, formato fijo, etc.). - No es one-liner idiomatico de stdlib (`time.Now().UTC().Format(...)` queda fuera). ### Flujo obligatorio (mismo turno) 1. **Detectar**. Si vas a escribir >=5 lineas de logica reutilizable inline -> STOP. 2. **Spawn `fn-constructor` inmediato** via `Agent(subagent_type="fn-constructor", ...)`: - **Sin preguntar al usuario** (autorizado por defecto). - Si hay >1 funcion independiente -> una sola llamada al Agent tool con **N tool_use blocks paralelos** en el mismo mensaje. NO serializar. 3. **Tagear con grupo de capacidad** al menos UN tag de grupo (`notebook`, `metabase`, `deploy`, etc.). Ver `capability_groups.md`. 4. **`fn index`** para registrar. 5. **Importar + invocar en el mismo turno** — no dejar funcion huerfana recien creada. 6. **Auto-verificar** con `fn doctor uses-functions` y `fn doctor unused` si tocas >=3 funciones nuevas. ### Anti-patrones auditables | Anti-patron | Consecuencia | Sustituir por | |---|---|---| | Escribir helper inline en artefacto en vez de delegar | Reinvento por sesion | Spawn fn-constructor | | Crear N funciones serialmente | Latencia x N | Multiples `Agent()` en mismo mensaje | | Crear funcion y no usarla en el turno | Huerfana desde dia 1 (`calls_90d=0`) | Importar + invocar antes de cerrar turno | | Crear funcion sin tag de grupo | Imposible descubrir en bloque proxima sesion | Anadir tag de grupo (capability group) | | Reescribir en heredoc logica que ya existe | Capitalizacion perdida | `mcp__registry__fn_search` antes de escribir | ### Excepciones - **Logica de dominio especifica del artefacto** (CRUD de tabla concreta, layout de UI, flujo unico de la app) -> queda en el artefacto. Solo lo reutilizable se delega. - **Stub temporal con `not implemented`**: aceptable si la dependencia externa no esta disponible. Documentar en `.md` (ver `stubs.md`). ### Telemetria Cada `code_writes` + `calls` se registra en `call_monitor/operations.db` (issue 0085). Vista `session_capability_growth` mide ratio creadas vs usadas por sesion. Hook `UserPromptSubmit` inyecta `CAPABILITY-GROWTH: created_this_session=X used=Y orphan=Z` en cada turno. Si `orphan>0` al cerrar la sesion -> revisar: o la funcion era especulativa (no debio crearse) o falta integrarla en el codigo del artefacto.