FND-001: Arquitectura intencional: Transición al microkernel de ZeroClaw
A partir de v0.7.0 · Tipo: Arquitectura · Rev. 10
Referencia canónica · Ratificada por el equipo · Rev. 10 Discusión original del RFC e historial de borradores: #5574
Una nota para el equipo antes de que lean esto.
Este documento fue escrito para ayudarnos a pasar de una base de código que creció de forma reactiva a una construida con intención. Si algunos de los conceptos aquí presentados son nuevos para ti, no hay ningún problema. Significa que este documento está cumpliendo su propósito. Todos los ingenieros sénior con los que llegarás a trabajar han aprendido estas lecciones por las malas, en una base de código que creció demasiado para poder entenderla. Tenemos la rara oportunidad de reconocer el patrón a tiempo y corregir el rumbo antes de que se vuelva doloroso. Esto es algo bueno. Tómate tu tiempo con ello.
Tabla de contenidos
- Una filosofía de desarrollo: visión primero
- La visión: qué es ZeroClaw
- Evaluación honesta: dónde estamos hoy
- La arquitectura objetivo
- Estándares que deberíamos adoptar
- Hoja de ruta por fases: v0.7.0 → v1.0.0
- Medidas de código y complejidad
- Lo que esto significa para los colaboradores
Historial de revisiones
| Revisar | Fecha | Resumen |
|---|---|---|
| 1 | 2026-04-09 | Borrador inicial |
| 2 | 2026-04-09 | Se ha añadido la §4.4.1 Política de versionado (herencia unificada del espacio de trabajo, niveles de estabilidad, definición de cambios incompatibles a nivel de producto); se ha añadido la §4.4.2 Artefactos de lanzamiento (destino de las banderas de función, perfil canónico del binario de lanzamiento, matriz de artefactos de lanzamiento); se han añadido Preguntas de discusión sobre la estrategia de versionado y los valores predeterminados de observabilidad |
| 3 | 2026-04-10 | Corrección de terminología según la retroalimentación de implementación del PR #5559: “kernel” → “runtime” para la capa de orquestación del agente en todo el documento; “kernel” ahora se refiere específicamente a la base irreducible (compilación con --no-default-features); §4.1 actualizado para describir la arquitectura explícita de dos capas (base + runtime); §4.2–§4.3 diagrama de dependencias y mapa de componentes actualizados para mostrar zeroclaw-runtime; Fase 2 renombrada de “The Kernel” a “The Runtime”; objetivos de tamaño binario reformulados como estrellas norte aspiracionales con seguimiento de progreso medido en lugar de umbrales estrictos; §7 actualizado con la medición real de la Fase 1 (compilación de base de 6.6 MB) y nota explícita de que la descomposición arquitectónica permite la optimización, pero la optimización es una segunda pasada dedicada |
| 4 | 2026-06-02 | Se actualizó §5.2 para apuntar a wasm32-wasip2 y habilitar archivos WIT. Se actualizó la Fase 2 §D2 para reemplazar Extism con wasmtime y habilitar destinos ARM32 y archivos WIT |
| 5 | 2026-06-29 | Se modificó §4.4.2 para reemplazar la única fila siempre activa de plugins-wasm con la taxonomía de backend de ejecución de tres banderas (plugins-wasm host más los backends plugins-wasm-cranelift / plugins-wasm-pulley), completando la desambiguación del RFC #6943 |
| 6 | 2026-06-30 | Se eliminó el instalador de escritorio de la matriz de artefactos de lanzamiento, la arquitectura de destino, la hoja de ruta y los criterios de éxito (#8544) |
| 7 | 2026-07-04 | Se restauraron el instalador de escritorio y sus compromisos de lanzamiento, arquitectura, hoja de ruta y criterios de éxito (#8565). |
| 8 | 2026-07-20 | Se convirtió el AGENTS.md raíz en el contrato compacto del proyecto, se canalizaron los detalles mantenidos mediante el mapa de arquitectura y las directrices para agentes de programación, y se evitó que la política de los crates debilitara los requisitos de seguridad, privacidad o autorización del proyecto (#9050). |
| 9 | 2026-08-11 | Se eliminó WATI del inventario actual de gateways y del objetivo de migración de plugins de v0.9.0 después de que el canal se retirara en #9571; el límite genérico entre webhooks y plugins permanece sin cambios |
| 10 | 2026-08-19 | Se eliminaron aardvark-sys y zeroclaw-robot-kit de las directrices sobre la herencia del espacio de trabajo y las versiones independientes después de retirar ambos crates en #9853; las versiones 0.1.0 publicadas permanecen en crates.io y no se ven afectadas |
Los números de revisión de este documento canónico siguen el historial ratificado del repositorio. La incidencia RFC enlazada también etiqueta una modificación sobre la disciplina de configuración como borrador Rev. 4, pero ese texto no se incluyó cuando este documento fundacional fue ratificado en #5911. La autoridad vigente sobre la configuración y el comportamiento de las sobrescrituras del entorno se documentan en Ciclo de vida de la configuración y Variables de entorno.
1. Una filosofía de desarrollo: visión primero
Cada decisión que tomamos en software, qué construir, cómo construirlo, qué omitir, debe fluir hacia abajo desde una jerarquía de intención:
Vision
└── Architecture
└── Design
└── Implementation
└── Testing
└── Documentation
└── Release
Este no es un proceso en cascada. Es una jerarquía de decisiones. Esto significa que, al escribir una función, deberías poder trazar una línea recta hacia arriba: esta función existe debido a esta decisión de diseño, que existe debido a esta elección arquitectónica, que existe debido a esta visión. Si no puedes trazar esa línea, es probable que el código no deba existir.
Qué significa cada capa en la práctica:
| Capa | La pregunta que responde | Qué sale mal sin ello |
|---|---|---|
| Visión | ¿Por qué existe este proyecto? ¿Para quién está dirigido? ¿Cómo se ve el éxito? | Construyes cosas que nadie necesita, o te contradices entre versiones |
| Arquitectura | ¿Cuáles son las decisiones estructurales que hacen posible la visión? | Terminas con una “Gran Bola de Lodo”: código que funciona pero que no puede modificarse sin romper algo más |
| Diseño | ¿Cómo se relacionan los componentes? ¿Cuáles son las interfaces entre ellos? | Obtienes un acoplamiento fuerte: componentes que conocen demasiado sobre los detalles internos de los demás |
| Implementación | ¿Cómo construimos este componente específico? | Errores, problemas de rendimiento, vulnerabilidades de seguridad |
| Pruebas | ¿La implementación coincide con el diseño? ¿El diseño sirve a la arquitectura? | Envías cosas rotas y no sabes por qué |
| Documentación | ¿Cómo transferimos este conocimiento a la siguiente persona? | Cada colaborador tiene que redescubrir todo desde cero. |
| Lanzamiento | ¿Cómo podemos entregar esto a los usuarios de manera segura y sostenible? | Los usuarios obtienen software roto o confuso |
El problema con omitir la parte superior
ZeroClaw fue creado mediante herramientas de IA que trabajaron a partir de la base de código de TypeScript de OpenClaw. La generación de código por IA opera en la capa de Implementación. Escribe funciones, estructuras y módulos que realizan acciones. No establece la Visión. No toma decisiones de Arquitectura. No define contratos de Diseño.
El resultado es una base de código impresionantemente funcional pero arquitectónicamente accidental. El código hace lo que necesita hacer hoy, pero no fue diseñado. Se acumuló. Este patrón tiene un nombre en nuestra industria: the Big Ball of Mud. Es la arquitectura más común en el software, no porque alguien la haya elegido, sino porque es lo que se obtiene cuando se omite la parte superior de la jerarquía.
Este RFC es nuestra oportunidad de arreglar eso, no descartando lo que funciona, sino haciendo crecer una arquitectura intencional a su alrededor usando una técnica llamada el Strangler Fig Pattern: construimos la nueva estructura alrededor de los bordes de la antigua, migrando hacia el interior con el tiempo, hasta que la estructura antigua desaparece. Sin reescrituras “big bang”. Sin descartar código que funciona. Solo una mejora constante e intencional.
2. La visión: qué es ZeroClaw
Antes de hablar sobre la arquitectura, debemos ser precisos sobre lo que estamos construyendo. Esta es la capa de Visión. Todo lo que sigue debe servir a esto.
ZeroClaw es un runtime de asistente de IA personal que cualquier persona puede ejecutar en cualquier hardware, desde una placa embebida de $10 hasta un servidor en la nube, sin sobrecarga de configuración, sin requisitos de servicios externos y sin compromisos en capacidad ni seguridad.
Desglosando esto en compromisos concretos:
Cero sobrecarga. El agente principal se inicia en milisegundos y usa menos memoria que una pestaña del navegador. Esto no es una afirmación de marketing. Es una restricción arquitectónica. Cada decisión que tomamos debe ser evaluada en función de ella.
Cero requisitos externos. Un usuario que descarga ZeroClaw y tiene un proveedor de LLM configurado debería tener un asistente de IA funcional y útil sin instalar nada más. Los canales, los paneles de control y las integraciones son cosas que agregas cuando las quieres, no cosas que necesitas antes de que funcione.
Cero compromisos. Lean no significa débil. ZeroClaw debe tener un modelo de seguridad sólido, observabilidad real y extensibilidad genuina. La tensión entre “binario pequeño” y “capacidad completa” se resuelve mediante la composición: un núcleo pequeño, extendido por componentes que tú eliges.
Para todos los niveles de experiencia. Un estudiante con una Raspberry Pi de $10 y un equipo ejecutando un despliegue en producción deberían sentir que ZeroClaw fue diseñado para ellos. Esto significa que la experiencia predeterminada debe ser simple, y la experiencia avanzada debe ser potente, no dos productos diferentes.
Propiedad del usuario. Tus datos, tu hardware, tu configuración. ZeroClaw no requiere una cuenta, no envía datos a servidores externos y no te limita a una plataforma.
3. Evaluación honesta: dónde estamos hoy
Esta sección no es una crítica al trabajo de nadie. Es un diagnóstico, y no puedes arreglar lo que no nombras.
3.1 El problema estructural
El código completo de ZeroClaw actualmente reside en un único crate de Rust. Esto significa:
- Un canal de Telegram y el bucle principal del agente se compilan desde el mismo árbol de código fuente, ya sea que uses Telegram o no.
- El panel de control web (una aplicación completa de React) está incrustado en el binario mediante
rust-embed, lo que hace que cada binario incluya la interfaz de usuario web incluso para los usuarios que solo utilizan la CLI. - El servidor HTTP de la puerta de enlace contiene controladores de webhook para WhatsApp, Linq, Nextcloud Talk y Gmail, lo que significa que las integraciones específicas de los canales están incorporadas en el servidor web
- Cada una de las 70+ herramientas se compila en el binario, independientemente de las herramientas que un usuario pueda llegar a llamar.
- El único mecanismo para excluir código es una bandera de característica de Cargo, lo que requiere que los usuarios tengan un entorno de desarrollo de Rust y recompilen desde el código fuente.
La consecuencia para los usuarios: El objetivo declarado es un binario ligero para hardware de $10. Pero el binario se distribuye con código para 27 canales de mensajería, más de 70 herramientas, un servidor web completo, una aplicación React e integraciones con Jira, Notion, Google Workspace, LinkedIn y más, la mayoría de las cuales un usuario cualquiera nunca llegará a usar.
La consecuencia para los contribuyentes: Cuando un archivo tiene 9.500 líneas, no es posible entenderlo. Cuando todas las funcionalidades están en un solo crate, tocar cualquier cosa arriesga romper todo.
3.2 La Evidencia
Estos son hechos medidos del código actual, no estimaciones:
| Archivo | Líneas | Qué hace | Lo que debería hacer |
|---|---|---|---|
src/agent/loop_.rs | ~9.500 | Análisis de llamadas de herramientas, transmisión, historial, seguimiento de costos, enrutamiento de modelos, memoria, eliminación de credenciales, construcción de contexto | Orquestar un turno de un solo agente |
src/gateway/mod.rs | ~2.260 | Servidor web + servidor de la aplicación React + webhooks de WhatsApp + webhooks de Linq + webhooks de Nextcloud + webhooks de Gmail + emparejamiento + limitación de velocidad + WebAuthn | Servir la API del panel web |
src/providers/mod.rs | ~3.750 | Factory + 40+ implementaciones de proveedores + flujos de OAuth + resolución de credenciales + limpieza de errores | Enrutamiento a un proveedor |
src/tools/mod.rs | all_tools_with_runtime() en L387–L1066 | Instanciar todas las 70+ herramientas de forma incondicional | Registrar las herramientas que el usuario configuró |
Un archivo de 9.500 líneas no es un módulo. Es un monolito que simplemente tiene una extensión .rs.
3.3 Qué es bueno
Este diagnóstico no debe oscurecer lo que está genuinamente bien diseñado:
- La capa de rasgos es excelente.
Provider,Channel,Tool,Memory,Observer,RuntimeAdapteryPeripheralson rasgos de Rust limpios y bien documentados. Estas son las uniones adecuadas. El problema es que no corresponden a los límites de los crates, por lo que el compilador no puede imponer la capa. - El sistema de plugins WASM está parcialmente implementado.
PluginHost,WasmTool,WasmChannel,PluginManifesty la verificación de firmas Ed25519 ya existen ensrc/plugins/. El puente de ejecución es un esqueleto, pero la estructura es correcta. - El sistema de observabilidad es maduro. OpenTelemetry, Prometheus y las métricas DORA están implementados en función de un trait
Observerlimpio. Este es un trabajo de calidad de producción. - El modelo de seguridad es cuidadoso. La combinación de códigos de emparejamiento, niveles de autonomía, aislamiento y aplicación de políticas muestra una clara intención de diseño.
No estamos reescribiendo ZeroClaw. Estamos dando a sus buenas ideas existentes una estructura en la que puedan crecer.
4. La arquitectura objetivo
4.1 El modelo de microkernel
Una arquitectura de microkernel separa un núcleo mínimo y estable de los subsistemas opcionales que lo extienden. En los sistemas operativos, el ejemplo clásico es un kernel que solo gestiona la memoria y la planificación, mientras que todo lo demás —sistemas de archivos, controladores de dispositivos, pilas de red— se ejecuta como procesos separados que se comunican a través de una interfaz bien definida.
Para un entorno de ejecución de agentes de IA, el mapeo revela dos capas internas distintas que la analogía del sistema operativo confunde:
| Concepto de Microkernel del Sistema Operativo | Equivalente de ZeroClaw |
|---|---|
| Núcleo | Capa de fundación: traits de API, configuración, proveedores, backends de memoria, infraestructura, analizador de llamadas a herramientas. El núcleo irreducible: compila con --no-default-features. Puede intercambiar mensajes con un LLM y almacenar memoria. Nada más. |
| Sistema de inicio / tiempo de ejecución | Capa de tiempo de ejecución del agente: Bucle de orquestación, aplicación de políticas de seguridad, host de plugins, herramientas principales, API de IPC. El crate zeroclaw-runtime, condicionado por la característica agent-runtime. Esto es lo que hace que ZeroClaw sea un agente, no solo una biblioteca. |
| IPC | API de socket local / IPC entre el entorno de ejecución y los componentes externos |
| Controladores de dispositivo | Plugins de canales (Telegram, Discord, etc.) |
| Controladores de Filesystem | Plugins de backend de memoria (SQLite, Markdown) |
| Procesos de usuario | Binario de la puerta de enlace, aplicación de escritorio de Tauri |
La distinción es importante: la base es lo mínimo que debe existir para que cualquier binario de ZeroClaw funcione. El tiempo de ejecución es lo mínimo que debe existir para que funcione como un agente. Todo lo demás se compone.
Esta división en dos capas se identificó durante la descomposición del espacio de trabajo de la Fase 1 (PR #5559) y se refleja en la nomenclatura de los crates: zeroclaw-runtime (el crate) está condicionado por agent-runtime (la característica). Las revisiones anteriores de este RFC utilizaban “kernel” de manera imprecisa para referirse a lo que ahora se denomina correctamente la capa de runtime. Esta revisión corrige dicha terminología en todo el documento.
4.2 La Regla de Dependencia
La regla arquitectónica más importante de este diseño, aquella que, si se rompe, derrumba toda la estructura, es esta:
Las dependencias fluyen hacia adentro. El tiempo de ejecución no sabe nada sobre los complementos. Los complementos conocen la API. Nada sabe de todo.
zeroclaw-api ← defines all traits (Provider, Channel, Tool, ...)
▲ no implementations, no heavy dependencies
│ depends on
foundation crates ← zeroclaw-config, zeroclaw-providers, zeroclaw-memory,
▲ zeroclaw-infra, zeroclaw-tool-call-parser
│ depends on all depend on zeroclaw-api; no cross-dependencies
zeroclaw-runtime ← implements the agent loop (agent-runtime feature)
▲ depends on zeroclaw-api + foundation crates
│ depends on knows nothing about specific channels or tools
plugin crates ← zeroclaw-channel-discord, zeroclaw-tools-web, ...
▲ depend on zeroclaw-api (not the runtime)
│ depends on
zeroclaw binary ← thin wiring layer
reads config, registers plugins, starts runtime
Si zeroclaw-runtime llega a importar TelegramChannel, se habrá violado la arquitectura. El compilador hará cumplir esto una vez que se definan los límites de los crates.
4.3 Mapa de componentes
┌─────────────────────────────────────────────────────────────────────┐
│ zeroclaw (binary crate) │
│ Reads config → registers only configured components → starts │
│ │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ zeroclaw-runtime (agent-runtime feature) │ │
│ │ │ │
│ │ Agent Loop · CLI Channel · Security Policy │ │
│ │ Plugin Host · Local IPC API │ │
│ │ Core Tools: shell, file, git, memory recall/store │ │
│ │ │ │
│ │ ┌──────────────────────────────────────────────────────┐ │ │
│ │ │ Foundation (--no-default-features) │ │ │
│ │ │ │ │ │
│ │ │ zeroclaw-api · zeroclaw-config · zeroclaw-infra │ │ │
│ │ │ zeroclaw-providers · zeroclaw-memory │ │ │
│ │ │ zeroclaw-tool-call-parser │ │ │
│ │ │ │ │ │
│ │ │ Vision target: <5 MB RAM at runtime │ │ │
│ │ └──────────────────────────────────────────────────────┘ │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ ▲ │
│ zeroclaw-api (traits only) │
│ ▲ │
│ ┌──────────────┐ ┌────────┴────────┐ ┌─────────────────────┐ │
│ │ zeroclaw-gw │ │ Channel plugins│ │ Tool plugins │ │
│ │ (opt-in │ │ │ │ │ │
│ │ binary) │ │ channel-discord│ │ tools-web │ │
│ │ │ │ channel-slack │ │ tools-integrations │ │
│ │ HTTP/WS/SSE │ │ channel-tg │ │ tools-hardware │ │
│ │ Web UI │ │ channel-email │ │ tools-mcp │ │
│ │ REST API │ │ ... │ │ ... │ │
│ └──────┬───────┘ └─────────────────┘ └─────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ zeroclaw-desktop│ ← Tauri app (already exists in apps/tauri) │
│ │ System tray app │ bundles zeroclaw-gw as a sidecar │
│ │ Native GUI │ │
│ └─────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
4.4 El modelo de distribución
La arquitectura permite una distribución limpia que no requiere que los usuarios finales tengan el toolchain de Rust:
| El usuario quiere | Lo que descargan | Qué hace zeroclaw onboard |
|---|---|---|
| Solo CLI | zeroclaw binario de tiempo de ejecución | Configurar proveedor, hecho |
| CLI + Discord | zeroclaw binario de tiempo de ejecución | Descargar e instalar channel-discord.wasm |
| Interfaz web local | zeroclaw + zeroclaw-gw | Configurar ambos, abrir el navegador |
| Aplicación de escritorio | zeroclaw-desktop instalador | Bundles runtime + gateway + UI |
| Todo | zeroclaw-desktop o zeroclaw --profile full | Descarga todos los complementos |
El comando zeroclaw plugin install (respaldado por PluginHost, que ya existe) se convierte en el gestor de paquetes. El asistente zeroclaw onboard lo integra para que los usuarios no técnicos nunca vean cargo.
4.4.1 Política de versionado
A medida que ZeroClaw pasa de ser un único crate a un espacio de trabajo con múltiples crates, dos aspectos deben mantenerse separados desde el inicio:
- La versión del producto: lo que reporta
zeroclaw --version, lo que rastrean GitHub Releases, los changelogs y los gestores de paquetes (Homebrew, apt, cargo-binstall). Esta es la versión sobre la que razonan los operadores y usuarios. - Estabilidad de componentes: qué tan maduro y confiable es un componente determinado. Un solo número de versión no puede transmitir esta señal por sí mismo.
Estos son ortogonales. Confundirlos genera ruido semver engañoso y erosiona la confianza en el número de versión. Esta política define ambos.
Versionado de crates: unificado con excepciones intencionales
Todos los crates de aplicación, el kernel, el gateway, los crates de plugins de herramientas, los crates de plugins de canales y la CLI usan la herencia de paquetes del workspace de Cargo: una única versión en el Cargo.toml raíz es la versión autoritativa del producto. Este es el modelo correcto porque:
- Los usuarios, operadores y empaquetadores trabajan con una versión, no con doce.
- La automatización de lanzamientos mediante
release-plzes sencilla: una PR, un incremento y una entrada en el registro de cambios. - Refleja la identidad de ZeroClaw como un producto, no como un ecosistema de bibliotecas.
- La versión de la interfaz WIT, no la versión del crate de Rust, es el contrato ABI real del plugin (consulte §5.2)
Dos clases de crates se excluyen intencionadamente de la herencia del espacio de trabajo y mantienen versiones independientes según su propio ritmo:
| Caja | Razón de independencia |
|---|---|
zeroclaw-api | Comienza en 0.1.0; su versión 1.0.0 es un entregable formal de hito de v1.0.0, que señala una superficie de rasgos de Rust estable para los autores del SDK de plugins. |
Archivos de interfaz WIT (wit/*.wit) | Versionado mediante las anotaciones @since y @unstable según la especificación del modelo de componentes WASI; estas son el contrato principal de la ABI del plugin y son independientes de la semántica de versiones de Cargo. |
Qué significa “breaking” para la versión del producto
Debido a que los crates de aplicación comparten una versión unificada, el equipo necesita una definición a nivel de producto de un cambio incompatible (breaking change), distinta de un cambio incompatible dentro de la implementación interna de un único crate. Un cambio incompatible dentro de un crate de plugin que no cruza ninguno de los límites indicados a continuación no es un cambio incompatible a nivel de producto y no justifica un incremento MAJOR.
| Actualizar | Garantizado cuando |
|---|---|
| MAJOR | Cambios incompatibles en la interfaz WIT (los plugins existentes deben recompilarse); cambios incompatibles en la API de IPC del kernel (el gateway o los clientes externos se romperán); el esquema del archivo de configuración requiere una migración; se eliminan o renombran comandos o indicadores de la CLI |
| MENOR | Nuevas capacidades en cualquier parte del espacio de trabajo; nuevos complementos disponibles en el registro; nuevas APIs estables; promociones de nivel de estabilidad; anuncios de desuso (no eliminaciones) |
| PATCH | Corrección de errores; parches de seguridad; correcciones de documentación; sin nuevas capacidades ni deprecaciones |
Niveles de estabilidad
La versión del producto responde “¿qué lanzamiento es este?” Un nivel de estabilidad responde “¿cuánto puedo confiar en este componente?” Cada componente, kernel, gateway, crate de plugin e interfaz WIT lleva uno de tres niveles. Los archivos AGENTS.md locales de componente y los manifiestos del registro de plugins son el modelo de propiedad objetivo. Hasta que esa migración esté completa, las asignaciones actuales canónicas viven en Guías del agente de codificación.
| Nivel | Significado | Implicación |
|---|---|---|
| Estable | Cubierto por la política de cambios incompatibles del producto. No se realizarán cambios incompatibles sin un aumento de la versión MAYOR y una guía de migración publicada. | Kernel (objetivo: v0.8.0), interfaz WIT de zeroclaw-api (objetivo: v0.9.0), API IPC del kernel (objetivo: v1.0.0) |
| Beta | Funcional y probado. Los cambios incompatibles están permitidos en las versiones MINOR, pero se anuncian en el registro de cambios con notas de actualización. | zeroclaw-gw (v0.9.0 → v1.0.0), complementos de canal y herramientas maduros |
| Experimental | Sin garantía de estabilidad. Puede romperse en las versiones PATCH. Debe estar claramente marcado como experimental en la documentación y en los manifiestos del registro de complementos. | Nuevas integraciones de herramientas, nuevas implementaciones de canales, complementos de hardware tempranos |
Los niveles de estabilidad se promueven, nunca se degradan mediante una decisión deliberada del equipo. Las promociones se registran en el registro de cambios y, para los componentes arquitectónicos, en un ADR. Un componente debe mantener su nivel actual durante al menos un ciclo completo de lanzamiento antes de que se considere una promoción.
Automatización de versiones
Las versiones usan release-plz, que abre una PR de publicación al hacer push a master, actualiza la versión del workspace y genera un registro de cambios a partir de los títulos de commits convencionales. release-plz entiende de forma nativa la herencia del workspace y gestiona automáticamente el orden de publicación de los crates. El crate zeroclaw-api, versionado de forma independiente, se gestiona por separado mediante la configuración por crate de la misma herramienta.
4.4.2 Artefactos de la versión
La transición al microkernel cambia la naturaleza fundamental de la pregunta “¿qué características se compilan?”. Hoy en día, esa pregunta tiene una sola respuesta: las banderas de características que pasaste a cargo build. Después de la transición, se divide en dos preocupaciones separadas:
- Qué hay en el binario del kernel: fijado en tiempo de compilación, determinado por plataforma, publicado en GitHub Releases
- Qué capacidades están disponibles: se determinan en tiempo de ejecución según qué plugins están instalados mediante
zeroclaw plugin install
Estas ya no son la misma pregunta, y la sección actual [features] de Cargo.toml debe interpretarse desde esa perspectiva.
Destino de los flags de características actuales en tiempo de compilación
Las más de 20 banderas de características en el actual Cargo.toml se dividen en tres categorías a medida que la arquitectura madura:
| Cubo | Banderas | Resultado |
|---|---|---|
| Retirar → plugin | channel-nostr, channel-matrix, channel-lark, whatsapp-web, browser-native | Eliminado del núcleo. Cada uno se convierte en un crate de plugin WASM publicado en el registro de plugins. No se requiere una decisión en tiempo de compilación. |
| Siempre activo | plugins-wasm, skill-creation | Compilado incondicionalmente en cada binario del kernel. plugins-wasm es el mecanismo central del kernel; skill-creation es una ruta de código sin sobrecarga. Ninguno de ellos pertenece detrás de una bandera. |
| Mantener → indicador de plataforma/infraestructura | peripheral-rpi, hardware, sandbox-landlock, sandbox-bubblewrap, voice-wake, probe | Mantenerse como indicadores de compilación porque requieren vinculación de bibliotecas nativas o acceso a nivel del sistema operativo que no puede ser proporcionado por un complemento WASM. peripheral-rpi y hardware aparecen únicamente en objetivos de lanzamiento específicos de la plataforma. |
plugins-wasm está siempre activado, pero no es una sola bandera: es una taxonomía de tres banderas. La maquinaria del host es incondicional; el backend de ejecución es una decisión a nivel de plataforma que se toma en tiempo de compilación. plugins-wasm sin una subbandera de backend no produce un entorno de ejecución de plugins utilizable, porque wasmtime necesita o bien un compilador o bien un intérprete para ejecutar un componente.
| Bandera | Predeterminado | Propósito |
|---|---|---|
plugins-wasm | Siempre activo | Habilita el host de componentes WASM; carga y ejecuta archivos de componentes .wasm |
plugins-wasm-cranelift | En (donde se admita) | Compilación JIT de Cranelift; usado en x86_64, aarch64 y otros destinos compatibles con Cranelift |
plugins-wasm-pulley | En (donde Cranelift no está disponible) | Intérprete de Pulley; usado en ARM de 32 bits y cualquier otro destino donde no se pueda usar Cranelift |
Cada objetivo de lanzamiento habilita exactamente un backend: cranelift donde es compatible, pulley donde no lo es. Se mantiene la intención siempre activa: cada binario incluye el host de plugins y puede ejecutar plugins en su plataforma.
Dos indicadores requieren una decisión deliberada del equipo antes de la versión v0.8.0 y se presentan aquí en lugar de resolverse unilateralmente:
observability-prometheus: actualmente endefault. Las métricas de Prometheus añaden una sobrecarga medible en el tamaño del binario. La pregunta es si un runtime de producción debería incluir la observabilidad activada por defecto, o si los operadores deberían optar por activarla. Recomendación: mantener endefaultpara la versión estándar; los operadores en entornos con restricciones severas de tamaño pueden compilar con--no-default-features.observability-otel: La exportación OTLP conlleva una huella de dependencias mayor (opentelemetry + cliente bloqueante reqwest). Recomendación: permanece como opcional, no endefault. Los despliegues en producción que necesiten exportación de trazas lo habilitan explícitamente.
La metafuncionalidad ci-all se simplifica considerablemente a medida que se retiran las banderas de canal y herramienta. Para la versión 1.0.0, solo abarcará las banderas restantes de plataforma e infraestructura.
El binario del kernel de la versión canónica
El binario publicado en GitHub Releases para cada plataforma objetivo se compila con el siguiente perfil:
| Compilado en | No compilado |
|---|---|
| Bucle principal del agente | Cualquier implementación de canal |
| 10–12 herramientas principales (ver Fase 2 D2) | Cualquier herramienta no esencial |
| Backends de memoria SQLite + Markdown | Automatización del navegador |
Host de complementos (plugins-wasm, siempre activo) | observability-otel (selección opcional del operador) |
observability-prometheus | voice-wake (dependencia de libasound2) |
skill-creation (sin sobrecarga) | probe (depuración de hardware especializado) |
| Servidor IPC | Activos web (movidos a zeroclaw-gw) |
| Entorno de prueba de la plataforma donde sea compatible | peripheral-rpi (compilación de hardware separada) |
Ya no existe un binario “build with everything”. Ese modelo mental se ha reemplazado por zeroclaw plugin install --profile full, que descarga el catálogo completo de complementos después de instalar el binario del núcleo ligero.
Matriz de artefactos de lanzamiento
Cada versión de GitHub publica los siguientes artefactos:
| Artefacto | Objetivos | Notas |
|---|---|---|
zeroclaw binario del núcleo | x86_64-unknown-linux-musl, aarch64-unknown-linux-gnu, armv7-unknown-linux-gnueabihf, x86_64-apple-darwin, aarch64-apple-darwin, x86_64-pc-windows-msvc | Compilación estática de musl para Linux x86_64; GNU para objetivos ARM |
zeroclaw binario del kernel (hardware) | aarch64-unknown-linux-gnu, armv7-unknown-linux-gnueabihf | Mismos objetivos, compilados con las banderas peripheral-rpi y hardware para implementaciones en Raspberry Pi |
zeroclaw-gw binario de puerta de enlace | Misma matriz de plataforma que el kernel | Publicado junto con el kernel; los usuarios lo instalan por separado |
| Archivos de complementos WASM | wasm32-wasip2 | Publicado en el registro de complementos (no en GitHub Releases); instalable mediante zeroclaw plugin install |
zeroclaw-desktop instalador | x86_64 y aarch64 para macOS, Windows, Linux (AppImage/deb) | Incluye el núcleo, la puerta de enlace y el conjunto completo de complementos; construido mediante el flujo de trabajo de Tauri |
Las compilaciones del plugin wasm32-wasip2 se ejecutan en un job de CI separado y se publican en el registro de plugins según su propia cadencia. Una versión del plugin no requiere una versión del kernel.
4.5 La separación de la puerta de enlace
El gateway actual confunde dos cosas que deben separarse:
Current (wrong):
zeroclaw binary
└── gateway
├── Web UI server (serves React app)
├── REST/WS/SSE API
├── WhatsApp webhook handler ← this is a channel, not a web server
├── Linq webhook handler ← this is a channel, not a web server
├── Nextcloud webhook handler ← this is a channel, not a web server
└── Gmail push handler ← this is a channel, not a web server
Target (correct):
zeroclaw-kernel
└── Local IPC API (Unix socket / 127.x HTTP)
zeroclaw-gw (separate binary, optional)
└── Connects to kernel IPC API
└── Web UI server
└── REST/WS/SSE API
└── Generic webhook proxy → routes to channel plugins
channel-whatsapp.wasm
└── Registers its own webhook route with the gateway
└── Handles WhatsApp-specific message parsing
Por qué esto es importante: Cuando el gateway es un proceso separado, puede fallar, reiniciarse o estar ausente sin afectar al agente. El kernel sigue ejecutándose. Esto es especialmente importante para el caso de uso de hardware edge: una Raspberry Pi que ejecuta el kernel puede tener su interfaz web servida desde un VPS, con el kernel conectándose hacia el exterior mediante un plugin de canal. No se necesitan reglas de firewall para conexiones entrantes.
5. Estándares que deberíamos adoptar
Los estándares son acuerdos que han sido establecidos por muchas personas inteligentes a lo largo de muchos años. Adoptarlos significa que obtenemos esos años de reflexión de forma gratuita, y que nuestro software se integra de manera natural con el resto del ecosistema. Aquí están los que se aplican directamente a ZeroClaw.
5.1 Observabilidad: OpenTelemetry
Qué es: OpenTelemetry (OTel) es el estándar de la industria para recopilar trazas, métricas y registros de sistemas de software. Es mantenido por la Cloud Native Computing Foundation y está respaldado por todos los principales proveedores de nube y herramientas de monitoreo.
Por qué es importante para ZeroClaw: Ya hemos implementado OtelObserver con nuestro trait Observer. Tenemos métricas de Prometheus y métricas DORA. El problema es que esto aún no está estandarizado en todo el código base: algunos módulos registran con tracing::info!, otros emiten ObserverEvents, y ambos no están conectados.
Lo que debemos hacer:
- Adoptar OpenTelemetry como la única interfaz de observabilidad para todos los componentes
- Asegúrate de que cada plugin emita trazas de OTel cuando se ejecute, para que un usuario pueda ver una traza completa desde “mensaje recibido en Discord” hasta “agente que llamó a la herramienta de shell” y “respuesta enviada”.
- Adoptar el contexto de trazado W3C (cabeceras
traceparent/tracestate) para propagar los IDs de trazado a través del límite kernel ↔ gateway ↔ plugin - La salida de registros estructurados debe estar en formato JSON cuando se establezca
ZEROCLAW_LOG_FORMAT=json(ya se está utilizando el cratetracing, solo necesita un suscriptor JSON).
Estándares: Especificación de OpenTelemetry · W3C Trace Context (REC) · RFC 5424 (Syslog, para integración con registros del sistema)
5.2 Interfaz de Plugin: WASI y WIT
Qué es: WASI (WebAssembly System Interface) es la API estándar que los módulos de WebAssembly utilizan para interactuar con el sistema anfitrión. WIT (WebAssembly Interface Types) es el lenguaje de definición de interfaces para describir lo que un componente WASM exporta e importa: piénselo como un archivo .proto pero para plugins de WASM.
Por qué es importante para ZeroClaw: Nuestros puentes WasmTool y WasmChannel actualmente no tienen un contrato formal sobre lo que debe exportar un binario WASM de un plugin. Esto significa que el autor de un plugin tiene que adivinar. Los archivos WIT definen ese contrato con precisión y permiten la generación automática de código para los autores de plugins en cualquier lenguaje.
Lo que debemos hacer:
- Defina archivos de interfaz WIT para los tipos de plugin
Tool,ChannelyMemory(un directoriowit/en la raíz del espacio de trabajo) - Utiliza
wit-bindgenpara generar los enlaces del lado del host en Rust a partir de esos archivos WIT. - Documentar las interfaces WIT como el SDK oficial de plugins
- Un autor de plugins escribe Rust (o Go, o C, o Python) contra la interfaz WIT y ejecuta
cargo build --target wasm32-wasip2: el resultado se coloca en~/.zeroclaw/plugins/
Estándares: WASI 0.2 · Modelo de Componentes de W3C WebAssembly · WIT IDL
5.3 API local: OpenAPI 3.1
Qué es: OpenAPI es el estándar para describir APIs HTTP. La versión 3.1 se alinea con JSON Schema Draft 2020-12.
Por qué es importante para ZeroClaw: La API de IPC local del kernel (el socket al que se conectan la puerta de enlace y otros componentes) necesita un contrato estable y documentado. Sin una especificación formal, la puerta de enlace y el kernel se desincronizarán silenciosamente con el tiempo.
Lo que debemos hacer:
- Escribir una especificación OpenAPI 3.1 para la API de IPC local del kernel antes de implementarla
- Genera los stubs del servidor en Rust a partir de la especificación utilizando
utoipaoaide. - Publica la especificación como
docs/reference/api/kernel-ipc-api.yaml - La API externa de la puerta de enlace también debe tener una especificación OpenAPI
Estándares: OpenAPI 3.1 · JSON Schema Draft 2020-12
5.4 Seguridad: OWASP ASVS
Qué es: El Estándar de Verificación de Seguridad de Aplicaciones de OWASP es una lista de requisitos de seguridad organizados por nivel de riesgo (L1 básico, L2 estándar, L3 avanzado).
Por qué es importante para ZeroClaw: El gateway maneja webhooks de servicios externos, procesa entrada de usuario no confiable y gestiona secretos. El sistema de emparejamiento, el soporte de WebAuthn y la limitación de tasa existen, pero no hay un framework para verificar que estén completos o sean correctos.
Lo que debemos hacer:
- Nivel ASVS 2 para la puerta de enlace y el módulo de seguridad
- Revisa la lista de verificación de Nivel 2 y documenta cuáles requisitos cumplimos, cuáles cumplimos parcialmente y cuáles están fuera del alcance.
- Utiliza esto como base para problemas y solicitudes de extracción (PRs) relacionados con la seguridad.
Estándares: OWASP ASVS 4.0 · OWASP Top 10
5.5 Modelo de Calidad: ISO/IEC 25010
Qué es: ISO/IEC 25010 define un modelo para la calidad del producto de software con ocho características principales: adecuación funcional, eficiencia del rendimiento, compatibilidad, usabilidad, fiabilidad, seguridad, mantenibilidad y portabilidad.
Por qué es importante para ZeroClaw: Cuando alguien pregunta “¿es esto lo suficientemente bueno para fusionar?”, la respuesta actualmente es subjetiva. ISO 25010 nos proporciona un vocabulario para esa conversación. Los compromisos de visión se mapean directamente: “cero sobrecarga” → eficiencia de rendimiento; “cualquier hardware” → portabilidad; “sin compromisos” → seguridad + confiabilidad.
Lo que debemos hacer:
- Utiliza las ocho características de calidad como una lente en las revisiones de PR para cambios significativos.
- Incluye una breve declaración sobre el impacto en la calidad en la plantilla de la solicitud de extracción (PR) para los cambios arquitectónicos (por ejemplo, “Este cambio mejora la mantenibilidad al reducir el acoplamiento entre las implementaciones de la puerta de enlace y los canales, sin afectar la eficiencia del rendimiento”).
Estándares: ISO/IEC 25010:2023
5.6 Ya adoptados: consérvelos
Estos ya están en su lugar y deben mantenerse:
| Estándar | Estado | Dónde |
|---|---|---|
| Versionado Semántico 2.0.0 | ✅ Adoptado | Cargo.toml, versiones |
| Commits convencionales | ✅ Adoptado | AGENTS.md, historial de commits |
| Marcas de tiempo RFC 3339 / ISO 8601 | ✅ Adoptado | MemoryEntry, todas las marcas de tiempo |
| Especificación de Directorio Base XDG | ✅ Adoptado | crate directories en uso |
| Mantén un registro de cambios | ✅ Adoptado | CHANGELOG.md |
| Guías de la API de Rust | ✅ Parcialmente | La configuración de Clippy aplica muchas |
6. Hoja de ruta por fases: v0.7.0 → v1.0.0
Cada fase sigue la jerarquía Visión → Arquitectura → Diseño → Implementación → Pruebas → Documentación → Lanzamiento. Ninguna fase comienza la implementación hasta que su diseño sea revisado y aprobado.
La estrategia general de migración es el Patrón de Higuera Parásita: hacemos crecer la nueva arquitectura alrededor de los bordes del código existente, migrando de forma constante hacia el interior, hasta que la estructura antigua sea completamente reemplazada. Nunca realizamos una reescritura que detenga el mundo. La aplicación siempre es entregable.
Fase 1 · v0.7.0: “The Seams”
Tema: Hacer que la arquitectura sea visible sin cambiar ningún comportamiento. Dibuja las líneas primero.
Por qué esta fase: No puedes migrar a una arquitectura en capas hasta que las capas existan como límites reales. Ahora mismo, los traits definen separaciones lógicas pero el compilador no las aplica: todo está en un solo crate, por lo que cualquier cosa puede importar cualquier otra. Esta fase hace que las separaciones sean reales.
Alineación de la visión: Ninguna de las propiedades de la visión cambia para los usuarios. Esto es completamente interno. El valor radica en que cada contribución futura ahora tiene un lugar estructural, y los nuevos colaboradores pueden comprender la base de código por partes en lugar de todo a la vez.
Entregables de la Fase 1
D1: Extraer el crate zeroclaw-api
Crea un nuevo crate crates/zeroclaw-api que contenga únicamente definiciones de rasgos (traits) y sus tipos de soporte. Sin implementaciones. Sin dependencias pesadas. Este crate debe compilarse en menos de dos segundos.
Moverse a este crate:
src/providers/traits.rs→Provider,ChatMessage,ChatResponse,ToolCall,StreamChunk,ProviderCapabilitiessrc/channels/traits.rs→Channel,ChannelMessage,SendMessagesrc/tools/traits.rs→Tool,ToolResult,ToolSpecsrc/memory/traits.rs→Memory,MemoryEntry,MemoryCategorysrc/observability/traits.rs→Observer,ObserverEvent,ObserverMetricsrc/runtime/traits.rs→RuntimeAdaptersrc/peripherals/traits.rs→Peripheral
Cada otro crate en el espacio de trabajo que necesita estos tipos añade zeroclaw-api como dependencia. El compilador ahora garantiza que ningún crate de implementación pueda importar otro crate de implementación sin pasar por la capa de API.
D2: Extraer el crate zeroclaw-tool-call-parser
La lógica de análisis de llamadas a herramientas en src/agent/loop_.rs consta de aproximadamente 1.400 líneas de transformación pura de texto: toma una cadena del LLM y devuelve una lista de llamadas a herramientas estructuradas. No depende del estado del agente, la memoria, los proveedores ni los canales. Maneja una docena de formatos de salida de LLM diferentes (JSON, XML, estilo GLM, MiniMax, estilo Perl, bloques de código markdown, entre otros).
Esta lógica es:
- Autocontenido: perfecto para su propio crate
- El código más apto para fuzz testing del proyecto: las pruebas basadas en propiedades van aquí
- Una contribución genuina al ecosistema de Rust: ningún otro crate hace esto de manera tan completa
Crea crates/zeroclaw-tool-call-parser con una API pública aproximada de:
#![allow(unused)]
fn main() {
pub fn parse(text: &str, specs: &[ToolSpec]) -> ParseResult
pub struct ParseResult {
pub calls: Vec<ParsedToolCall>,
pub remaining_text: Option<String>,
}
pub struct ParsedToolCall {
pub name: String,
pub arguments: serde_json::Value,
pub tool_call_id: Option<String>,
}
}
Las ~300 pruebas de análisis que actualmente están en loop_.rs se mueven a este crate. loop_.rs se reduce en aproximadamente 1.400 líneas.
D3: Adoptar OpenTelemetry como el estándar de observabilidad
Formalizar lo ya implementado: documentar que ObserverEvent y ObserverMetric constituyen el bus de eventos interno, y que OtelObserver es el backend de producción canónico. Adoptar un suscriptor de registro estructurado en JSON para ZEROCLAW_LOG_FORMAT=json. Adoptar el contexto de trazado W3C para el trazado futuro entre componentes.
D4: Escribir archivos de interfaz WIT
Antes de implementar la ejecución de complementos WASM, definamos los contratos. Crea un directorio wit/ en la raíz del espacio de trabajo con las definiciones de interfaz para:
zeroclaw:tool/tool.wit: la interfaz del plugin Toolzeroclaw:channel/channel.wit: la interfaz del plugin Channel
Estos se convertirán en el SDK oficial del plugin. La implementación en la versión 0.8.0 se generará a partir de estos archivos.
Métricas de éxito para v0.7.0
zeroclaw-apise compila en menos de 2 segundos con cero dependencias de implementaciónzeroclaw-tool-call-parsertiene ≥ 95% de cobertura de pruebas (la lógica es completamente testeable de forma aislada)loop_.rstiene menos de 8.000 líneas- Cero cambios en el comportamiento visible para el usuario
- Cero regresiones de rendimiento (el conjunto de pruebas de referencia pasa)
Fase 2 · v0.8.0: “The Runtime”
Tema: Formalizar el tiempo de ejecución del agente como una unidad limpia e independiente desplegable. Todo lo que no sea el tiempo de ejecución se convierte en un invitado.
Por qué esta fase: Una vez que existen las separaciones (v0.7.0), podemos trazar explícitamente el límite del runtime. Esta fase extrae zeroclaw-runtime como un crate independiente, completa el puente de ejecución de plugins WASM y conecta el cliente del registro de plugins: el mecanismo mediante el cual todo lo que está fuera del runtime se conecta a él.
Alineación con la visión: Aquí es donde el modelo de composición se vuelve real para los usuarios. Un usuario que solo quiere un agente CLI descarga un único binario, ejecuta zeroclaw onboard y listo: sin toolchain de Rust, sin compilación. El asistente zeroclaw onboard adquiere la capacidad de descargar componentes de plugins bajo demanda.
Entregables de la Fase 2
D1: Formalizar el crate zeroclaw-runtime
Extrae el bucle de orquestación del agente, el canal CLI, la política de seguridad, el host de complementos y la API de IPC en crates/zeroclaw-runtime, protegido por la función agent-runtime. Este crate depende de zeroclaw-api y de los crates fundamentales. No tiene conocimiento de Telegram, Discord, Anthropic ni de ninguna implementación específica de herramientas.
El tiempo de ejecución exporta una API pública limpia:
#![allow(unused)]
fn main() {
pub struct Runtime { ... }
pub struct Registry {
pub fn register_channel(&mut self, ch: Arc<dyn Channel>);
pub fn register_tool(&mut self, t: Box<dyn Tool>);
pub fn set_provider(&mut self, p: Arc<dyn Provider>);
pub fn set_memory(&mut self, m: Arc<dyn Memory>);
pub fn set_observer(&mut self, o: Arc<dyn Observer>);
}
pub async fn run(runtime: Runtime, registry: Registry) -> anyhow::Result<()>;
}
El crate binario se convierte en una capa de conexión delgada que lee la configuración y llama a run.
D2: Completar el puente de ejecución WASM
La dependencia extism es incompatible con el Modelo de Componentes de WASM (archivos .wit) y requiere la característica cranelift de wasmtime, lo que impide que los targets ARM32 compilen. Elimine Extism y reemplácelo con el uso directo de wasmtime. Durante la transición, Extism debe dejarse como una opción hasta el PR final de obsolescencia.
Integra wasmtime en zeroclaw-plugins con dependencias opcionales de cranelift (para la mayoría de los destinos de compilación) o pulley (para ARM32). Con las interfaces WIT definidas en la v0.7.0, usa wit-bindgen para generar los bindings del lado del host.
Una implementación completa del puente de ejecución WASM define las funciones host WASI que los plugins WASM pueden invocar (solicitudes HTTP, acceso a memoria, registro de logs) dentro del modelo de permisos ya definido en PluginPermission. Cuando sea posible, se deben usar las APIs de WASI Preview 2 (wasi:io, wasi:http, wasi:filesystem, etc.) para proporcionar una API consistente basada en estándares para los plugins.
D3: Cliente del registro de componentes
Agrega un subcomando zeroclaw plugin respaldado por un cliente de registro simple:
zeroclaw plugin list # list installed plugins
zeroclaw plugin search <query> # search the component registry
zeroclaw plugin install <name> # download, verify, and install a plugin
zeroclaw plugin remove <name> # remove an installed plugin
zeroclaw plugin update # update all installed plugins
El registro es un archivo de índice JSON servido desde una URL conocida (p. ej., https://plugins.zeroclaw.com/index.json). Cada entrada incluye el nombre, la versión, la URL de descarga, la suma de comprobación SHA-256 y la clave pública Ed25519 del editor. La verificación de firmas de PluginHost ya gestiona el modelo de seguridad.
D4: Integrar zeroclaw onboard con el sistema de plugins
El asistente de configuración debe preguntar al usuario qué canales e integraciones desea, y luego llamar a PluginRegistry::install para cada uno. No se requiere compilación. El usuario descarga un binario, ejecuta zeroclaw onboard y tiene un agente configurado y funcional en menos de dos minutos.
D5: Reducir all_tools_with_runtime solo a las herramientas principales
El núcleo incluye exactamente las herramientas que un usuario necesita para un agente útil sin plugins instalados: shell, file_read, file_write, file_edit, git_operations, glob_search, content_search, memory_recall, memory_store, memory_forget y web_fetch. Todo lo demás se registra mediante los plugins instalados.
Métricas de éxito para v0.8.0
zeroclaw-runtimese compila de forma independiente sin código de implementación de canales ni de herramientaszeroclaw plugin install channel-discordfunciona de extremo a extremozeroclaw onboardinstala complementos sin necesidad de un entorno de herramientas de Rust.- El tamaño binario en tiempo de ejecución se rastrea y reporta en las notas de la versión; la aspiración es lograr un progreso descendente hacia el objetivo visionado (véase §7).
- Un complemento de herramienta WASM escrito en Rust utilizando la interfaz WIT se ejecuta correctamente
Fase 3 · v0.9.0: “The Gateway”
Tema: Separar la superficie web del núcleo del agente.
Por qué esta fase: El gateway es actualmente el mayor acoplamiento estructural en el código base. Incrusta una aplicación React compilada, maneja la lógica de webhooks específica de cada canal y se compila en cada binario, incluidos los binarios destinados a hardware perimetral de $10 que nunca servirán una página web.
Alineación de la visión: Esta fase cumple completamente con la promesa de “cero requisitos externos”. Un usuario en una Raspberry Pi obtiene un binario del kernel sin servidor web, sin aplicación React y sin oyente HTTP. Un usuario que desea el panel de control web instala zeroclaw-gw por separado.
Entregables de la Fase 3
D1: Definir la API de IPC del kernel
Antes de extraer la puerta de enlace, define la especificación OpenAPI 3.1 para la API local que el kernel expone en un socket Unix o un puerto de bucle invertido. Esta API es a la que se conectan la puerta de enlace, la aplicación Tauri y cualquier cliente futuro. Es el contrato estable entre el kernel y el mundo exterior.
Los endpoints incluyen: enviar un mensaje, recibir una respuesta en streaming, listar sesiones activas, listar plugins instalados, obtener el estado del agente, gestionar la memoria, activar trabajos cron. Este es ante todo un documento de diseño: la especificación debe revisarse y acordarse antes de escribir una sola línea de implementación.
D2: Implementar el servidor IPC del kernel
Agregue el servidor IPC a zeroclaw-kernel detrás de una marca de función (--features ipc). En las plataformas que lo admiten, el kernel escucha en un socket Unix en ~/.zeroclaw/kernel.sock. En Windows, use un pipe con nombre. El comando zeroclaw gateway (el punto de entrada actual del servidor web) se convierte en zeroclaw-gw conectándose a este socket.
D3: Extraer zeroclaw-gw como un binario independiente
Mueve src/gateway/ a un nuevo crate crates/zeroclaw-gw/ con su propio binario. Depende de zeroclaw-api y se conecta al kernel mediante la API de IPC. La aplicación React embebida mediante rust-embed se traslada por completo a este crate: el binario del kernel ya no contiene ningún recurso web.
D4: Migrar los manejadores de webhooks de canal fuera del gateway
Los controladores de webhook de WhatsApp, Linq, Nextcloud Talk y Gmail que actualmente se encuentran en gateway/mod.rs se trasladan a sus respectivos complementos de canal. La pasarela proporciona una API genérica de registro de webhooks: al cargarse, un complemento de canal registra el prefijo de la ruta de su webhook y su función controladora. La pasarela enruta los webhooks entrantes al controlador registrado. La pasarela ya no tiene conocimiento de WhatsApp.
D5: Formalizar la relación de sidecar de Tauri
Actualiza apps/tauri/ para empaquetar zeroclaw-gw como un binario sidecar de Tauri. La aplicación Tauri se convierte en la distribución “completa”: inicia automáticamente el kernel y la pasarela, y abre la interfaz web. Los usuarios que descargan la aplicación Tauri obtienen todo funcionando sin necesidad de tocar una terminal.
Métricas de éxito para v0.9.0
- El binario del kernel (versión de lanzamiento) no contiene activos web ni código de servidor HTTP.
zeroclaw-gwse inicia, se conecta al kernel a través de IPC y sirve el panel de control web.- Eliminar
zeroclaw-gwno rompe el kernel ni ningún plugin de canal - El código de los canales de WhatsApp, Linq, Nextcloud Talk y Gmail se ha trasladado a crates de plugins
- Los paquetes de la aplicación de escritorio de Tauri inician y ejecutan correctamente ambos binarios.
Fase 4 · v1.0.0: “La Plataforma”
Tema: ZeroClaw se convierte en una plataforma componible, no en una aplicación monolítica.
Por qué esta fase: Con el núcleo estable, la puerta de enlace separada y el sistema de complementos funcionando, la versión 1.0.0 es la versión en la que la arquitectura se convierte en el producto. Los desarrolladores externos pueden escribir y publicar complementos. Los usuarios pueden ensamblar exactamente el ZeroClaw que deseen. El binario puede reclamar con credibilidad el perfil ligero que la visión promete.
Entregables de la Fase 4
D1: Migrar todos los canales restantes a plugins
Cada una de las 27+ implementaciones de canales se convierte en un crate de plugin WASM independiente. Se publican en el registro de componentes con versiones firmadas. El binario del kernel no contiene ninguna implementación de canales, excepto la CLI.
D2: Migrar herramientas de cola larga a plugins
Aproximadamente 60 de las más de 70 herramientas se trasladan a crates de plugins, agrupadas por dominio: zeroclaw-tools-web (navegador, búsqueda, captura de pantalla, PDF), zeroclaw-tools-integrations (Jira, Notion, Google Workspace, MS365, LinkedIn), zeroclaw-tools-hardware (información de la placa, GPIO) y zeroclaw-tools-cloud (operaciones en la nube, operaciones de seguridad). El núcleo conserva únicamente las 10–12 herramientas principales identificadas en v0.8.0.
D3: SDK de plugins y documentación para desarrolladores
Publica una guía de desarrollo de plugins. Un desarrollador debería poder escribir un nuevo plugin de herramienta en una tarde:
- Agrega
zeroclaw-plugin-sdkcomo dependencia - Implementa el rasgo generado por WIT
cargo build --target wasm32-wasip2zeroclaw plugin install ./my-plugin/
El SDK gestiona las vinculaciones de funciones del host, el formato del manifiesto y el modelo de permisos.
D4: Estabilizar la API de IPC del kernel en la v1.0
La API de IPC del kernel recibe un prefijo de versión (/v1/) y una garantía de estabilidad. No se permiten cambios incompatibles en v1.x para esta API. Este es el contrato en el que dependen los clientes de terceros y la puerta de enlace.
D5: Extraer la política de versionado y las definiciones de niveles de estabilidad a docs/book/src/maintainers/stability-tiers.md
La política de versionado y la tabla de niveles de estabilidad definidos en §4.4.1 de este RFC se convierten en un documento de referencia permanente para los colaboradores en docs/book/src/maintainers/stability-tiers.md. Este documento es la referencia diaria que utilizan los colaboradores al asignar un nivel a un nuevo crate de plugin, y la que consultan los mantenedores al tomar decisiones de lanzamiento. El propio RFC sigue siendo el registro histórico de por qué se tomaron estas decisiones; el documento extraído es qué consultan los colaboradores.
Métricas de éxito para v1.0.0
- El tamaño binario en tiempo de ejecución se monitorea en relación con el objetivo de visión (ver §7); se espera un pase de optimización dedicado a través de cada crate como parte del flujo de trabajo de la versión 1.0.0
- Un desarrollador de terceros puede publicar un complemento funcional utilizando únicamente la documentación pública.
- Todas las implementaciones de los 27+ canales están disponibles como complementos descargables en el registro
zeroclaw onboardcompleta una configuración completa en menos de 2 minutos en una Raspberry Pi Zero 2W sin ninguna herramienta de Rust instalada- El catálogo completo de complementos se puede instalar con
zeroclaw plugin install --profile full
7. Métricas de código y complejidad
Estas son estimaciones basadas en el análisis directo del código de la base de código actual. Están destinadas a dar una idea de la escala, no a ser predicciones exactas.
Líneas de código que salen del entorno de ejecución
| Qué se mueve | Líneas aproximadas | Destino |
|---|---|---|
Analizador de llamadas de herramientas (desde loop_.rs) | ~1.400 | zeroclaw-tool-call-parser crate |
| Más de 60 implementaciones de herramientas no principales | ~30.000 | Cajas de complementos |
| Más de 24 implementaciones de canales no principales | ~7.200 | Cajas de complementos |
| Servidor HTTP de la puerta de enlace | ~2.260 | crate zeroclaw-gw |
| Aplicación React embebida (peso binario) | N/A | crate zeroclaw-gw |
| Manejadores de webhook de canal desde el gateway | ~500 | Cajas de complementos de canal |
| Total estimado eliminado del tiempo de ejecución | ~41.000 líneas | N/A |
Reducción de la complejidad a nivel de archivo
| Archivo | Líneas actuales | Objetivo después de la migración | Reducción |
|---|---|---|---|
src/agent/loop_.rs | ~9.500 | ~5.000 | ~47% |
src/gateway/mod.rs | ~2.260 | Se mueve a zeroclaw-gw | 100% |
src/tools/mod.rs | all_tools_with_runtime tiene aproximadamente 680 líneas | ~80 líneas (solo herramientas principales) | ~88% |
src/providers/mod.rs | ~3.750 | ~1.200 (proveedores de registro propio) | ~68% |
src/channels/mod.rs | ~200 + 44 archivos de canales | Canal solo CLI | ~90% |
Tamaño del binario: progreso medido y objetivo de la visión
La visión del proyecto se expresa en términos de ejecución: <5 MB de RAM en hardware de $10. El tamaño del binario en disco y la huella de memoria en tiempo de ejecución (RSS) están relacionados, pero no son idénticos: la paginación bajo demanda implica que solo las rutas de código ejecutadas residen en memoria. Ambos se monitorizan.
Modelo de dos fases: La descomposición arquitectónica (Fases 1–3) y la optimización del tamaño binario son flujos de trabajo independientes. La descomposición permite la optimización al aislar las dependencias en sus crates correspondientes. Maximizar la eficiencia crate por crate es la segunda fase esperada, no un entregable del trabajo estructural en sí.
| Configuración | Pre-descomposición (v0.6.x) | Resultado de la fase 1 (v0.7.0) | Objetivo de visión |
|---|---|---|---|
| Binario monolítico completo | ~8,8 MB | N/A (reemplazado por el modelo de complementos) | N/A |
Solo la base (--no-default-features) | N/A | 6.6 MB (medido, sin símbolos) | TBD después de la pasada de optimización |
Binario de ejecución (fundación + agent-runtime) | N/A | rastreado | aspiración: ≤ 5 MB de RAM en tiempo de ejecución |
| Tiempo de ejecución + puerta de enlace | N/A | rastreado | ~5–7 MB en disco |
| Tiempo de ejecución + puerta de enlace + los 5 principales canales | N/A | rastreado | ~8–10 MB (los complementos son archivos separados) |
| Aplicación de escritorio Tauri (incluye todo) | N/A | rastreado | ~20–25 MB de instalador |
La compilación base de la Fase 1 de 6.6 MB representa un progreso real respecto al monolito de 8.8 MB y demuestra que la descomposición está funcionando. Alcanzar el objetivo previsto requiere una pasada dedicada de auditoría de dependencias y optimización en cada crate una vez completada la descomposición estructural: revisar el Cargo.toml de cada crate en busca de dependencias innecesarias o con demasiadas características habilitadas, validar los perfiles de LTO y strip, y auditar qué feature flags de tokio/serde son realmente necesarias.
El cambio estructural clave: el tamaño del binario deja de ser una función de las “características compiladas en tiempo de compilación” y se convierte en una función de los “plugins instalados en tiempo de ejecución”, que el usuario controla. Ese cambio es el objetivo arquitectónico de las Fases 1–3. Los números de tamaño son el objetivo de optimización de la fase que sigue.
Mejora del tiempo de compilación
Actualmente, una compilación completa con cargo build --release en esta base de código compila todos los canales, todas las herramientas, todos los proveedores y la aplicación React integrada en una única unidad de compilación. La descomposición de crates significa:
- El kernel se compila de forma independiente y su salida compilada se almacena en caché.
- Un cambio en
channel-discordno recompila el kernel - Los colaboradores que trabajan en un complemento solo recompilan su complemento
- CI puede paralelizar la compilación de crates entre trabajos
Mejora estimada del tiempo de ejecución para compilaciones incrementales: reducción del 60–75% para cambios que no tocan el kernel.
8. Qué significa esto para los colaboradores
Para nuevos colaboradores
La queja más común de los nuevos colaboradores en grandes bases de código es: “No sé por dónde empezar”. Con la arquitectura actual, la respuesta a “¿a dónde va un mensaje de Discord?” requiere rastrear a través de channels/discord.rs → channels/mod.rs → gateway/mod.rs → agent/loop_.rs → docenas de otros archivos.
Con la arquitectura de microkernel, la respuesta es: “va al receptor Channel del kernel, a través del plugin channel-discord”. Un nuevo colaborador puede comprender completamente el canal de Discord leyendo un solo crate de plugin. Puede entender el bucle completo del agente leyendo zeroclaw-kernel sin tener en cuenta ningún código de canal o herramienta.
Una buena regla general para nuevos colaboradores: si puedes describir tu cambio en una oración sin mencionar más de un componente, estás trabajando en el nivel correcto. “Corregir un error en cómo el canal de Discord maneja las respuestas en hilos” es un componente. “Refactorizar el bucle del agente y actualizar el canal de Discord y además corregir el backend de memoria” son tres componentes: deberían ser tres PRs.
Para los mantenedores
Cada informe de error tendrá un lugar claro. “El agente está llamando a las herramientas incorrectamente” → zeroclaw-tool-call-parser o zeroclaw-runtime. “La integración de Discord está rota” → plugin channel-discord. “El panel web no se está cargando” → zeroclaw-gw. Ahora mismo, cualquiera de esos errores podría estar en cualquier lugar de más de 50.000 líneas.
Para el proceso de lanzamiento
El modelo de plugins permite que los canales y las herramientas tengan ciclos de lanzamiento independientes. Una corrección de errores en el canal de Telegram no requiere un nuevo lanzamiento del kernel. La estabilidad del kernel se convierte en la base sobre la que se construye todo lo demás. La iteración rápida en los plugins no pone en riesgo la estabilidad del kernel.
Para la comunidad
Una interfaz WIT publicada y un SDK de plugins significan que cualquiera puede extender ZeroClaw sin necesidad de bifurcarlo. Una empresa que necesite una integración específica puede escribir un plugin basado en la interfaz pública. Así es como se construyen los ecosistemas.
Apéndice A: Glosario
Términos utilizados en este documento que pueden ser desconocidos:
Big Ball of Mud: Una arquitectura (o ausencia de ella) en la que la base de código ha crecido de forma orgánica sin planificación estructural. El nombre proviene de un artículo de 1997 de Brian Foote y Joseph Yoder. Es la arquitectura más común en el software, no porque alguien la elija, sino porque es lo que se obtiene por defecto.
Ley de Conway: “Cualquier organización que diseña un sistema producirá un diseño cuya estructura es una imagen espejo de la estructura de comunicación de la organización.” (Mel Conway, 1968) Si los colaboradores trabajan en silos aislados sin hablar entre sí, el código lo reflejará. Si los colaboradores colaboran con interfaces claras entre su trabajo, el código también lo reflejará.
Principio de Inversión de Dependencias: Los módulos de alto nivel no deben depender de módulos de bajo nivel. Ambos deben depender de abstracciones. Por eso zeroclaw-runtime depende de zeroclaw-api (abstracciones) y no de channel-discord (una implementación específica).
Microkernel: Una arquitectura en la que el sistema central contiene únicamente la funcionalidad mínima necesaria, y todas las demás capacidades son proporcionadas por componentes separados que se comunican con el núcleo a través de interfaces bien definidas.
Patrón Strangler Fig: Una estrategia de migración en la que reemplazas incrementalmente partes de un sistema existente construyendo nuevos componentes junto a los antiguos. Recibe su nombre de la planta higuera estranguladora, que crece alrededor de un árbol existente hasta que el árbol original ha sido completamente reemplazado. La propiedad clave: el sistema siempre está en funcionamiento y siempre es desplegable durante la migración.
Deuda técnica: El costo acumulado de tomar atajos en el diseño de software. Como la deuda financiera, una pequeña cantidad puede ser productiva (entregas más rápido ahora). Una cantidad grande se vuelve paralizante (pasas todo tu tiempo pagando intereses, es decir, corrigiendo errores y aplicando soluciones provisionales, en lugar de desarrollar nuevas funcionalidades).
WIT (WebAssembly Interface Types): Un lenguaje de definición de interfaces para describir lo que los componentes WASM exportan e importan. Piénselo como un contrato: “un plugin Tool debe exportar una función llamada execute que recibe JSON y devuelve JSON.” WIT hace que ese contrato sea preciso y legible por máquina.
Apéndice B: Lecturas adicionales
Estos son recursos que el equipo puede encontrar valiosos. No son lecturas obligatorias, pero cada uno ha influido directamente en esta propuesta.
-
“A Philosophy of Software Design”: John Ousterhout. El mejor libro breve sobre la gestión de la complejidad en el software. Su concepto de “módulos profundos” (interfaces simples, implementaciones potentes) es exactamente lo que busca el modelo de microkernel.
-
“Clean Architecture”: Robert C. Martin. La Regla de Dependencia descrita en la Sección 4.2 de este documento proviene de este libro.
-
“Release It!”: Michael Nygard. Patrones prácticos para construir software que se mantiene en funcionamiento en producción. Los patrones de separación de gateway y circuit-breaker que se analizan aquí provienen de este libro.
-
The Rust API Guidelines: La guía oficial para diseñar bibliotecas idiomáticas de Rust. Nuestras interfaces de traits deben seguir estas convenciones.
-
El Modelo de Componentes de WebAssembly: La base técnica para el sistema de plugins propuesto en este RFC.
-
Especificación de OpenTelemetry: La especificación completa del estándar de observabilidad que estamos adoptando.
Esta propuesta se desarrolló a partir de un análisis detallado de la base de código de ZeroClaw en la versión v0.6.8. Las métricas de código citadas se basan en la medición directa de los archivos fuente. Las recomendaciones arquitectónicas reflejan patrones establecidos en el diseño de software de sistemas aplicados a las restricciones y objetivos específicos del proyecto ZeroClaw.
Los comentarios, las correcciones y las contrapropuestas son bienvenidos. La mejor arquitectura es la que el equipo comprende y en la que cree, no la que una sola persona dictó.