## Registry-first: reutilizar antes que escribir, delegar antes que escribir inline **OBLIGATORIO para todos los artefactos** (apps, analyses, projects, playgrounds, services). El registry existe para que las apps se compongan a partir de funciones probadas. No respetar esto convierte cada app en una isla con codigo duplicado y bugs unicos. ### Flujo obligatorio antes de escribir codigo en un artefacto 1. **Consultar registry.db con FTS5** para encontrar funciones existentes que cubran el caso. No es opcional. Buscar por `name`, `description`, `tags`, `signature`, `code` y `params_schema`. Probar varios sinonimos (`http`, `serve`, `router`; `id`, `uuid`, `random_hex`; etc.). 2. **Reutilizar lo que existe**. Importar la funcion del registry y declararla en `uses_functions` del `app.md`. NO reescribir logica inline cuando ya hay una funcion. 3. **Si falta una pieza reutilizable → delegar a `fn-constructor`** (subagent_type `fn-constructor`). NO escribir la funcion inline en el artefacto. El agente construye la funcion en su sitio (`functions/{domain}/`, `python/functions/{domain}/`, etc.) con `.go/.py/.sh/.ts` + `.md` correctos, tests, y respetando las reglas de pureza/firma. 4. **Solo despues** se escribe el codigo del artefacto, que orquesta funciones del registry y aporta unicamente la logica especifica del dominio (CRUD de tablas concretas, layout de UI, flujo de la app). ### Que va al registry vs que va al artefacto | Tipo de codigo | Donde | |---|---| | Logica reutilizable, primitiva, generica (parser, helper http, abrir SQLite, generar IDs, formatear timestamps con politica fija, middleware, etc.) | `functions/{domain}/` — delegar a `fn-constructor` si no existe | | Composicion de varias funciones del registry para un flujo concreto | `pipelines` (registry) o codigo del artefacto segun reusabilidad | | Schema SQL especifico del artefacto | Migraciones del artefacto | | Handlers HTTP que solo hacen sentido para este artefacto (ej. `/api/board` de un kanban) | Codigo del artefacto, pero usando `http_json_response_go_infra`, `http_parse_body_go_infra`, etc. del registry | | Layout/components especificos de la UI del artefacto | Codigo del artefacto, pero consumiendo componentes de `frontend/functions/ui/` (`@fn_library`) | Regla practica: **si dos artefactos ya hacen o haran lo mismo, es funcion del registry**. One-liners idiomaticos de la stdlib (`time.Now().UTC().Format(...)`) NO necesitan ser registry — se ven en cualquier sitio. Pero un patron como "abrir SQLite con WAL + foreign keys + ping" SI (y por eso existe `sqlite_open_go_infra`). ### Cuando delegar a `fn-constructor` Delegar SIEMPRE que se necesite una funcion reutilizable que no existe. El prompt del subagente debe incluir: - Lenguaje, dominio, nombre propuesto. - Firma esperada (params + return). - Pureza (`pure` o `impure`). - Una breve descripcion del proposito y del comportamiento. - Si hay funciones similares en el registry, listarlas para evitar duplicados. El agente construye la funcion siguiendo las reglas del registry (`purity.md`, `ids_naming.md`, `types_in_signatures.md`, etc.) y deja `fn index` listo para ejecutar. ### Auditoria Despues de implementar el artefacto, verificar que `uses_functions` del `app.md` (o equivalente) declara TODAS las funciones del registry consumidas. Esto se puede cruzar con los `import` reales del codigo: ```bash # Para Go: grep -rh '"fn-registry/functions/' apps// | sort -u # Cada paquete importado tiene que tener al menos una funcion declarada en uses_functions. ``` ### Por que esta regla Sin esta regla cada app reinventa: helpers SQLite, middleware HTTP, generacion de IDs, parsers, validadores, formateo de fechas. El registry pierde su razon de ser. Con esta regla, una funcion bien hecha se reutiliza en N apps; un bug se arregla una vez; la velocidad de cada app nueva crece a medida que el registry crece.