Mori
Capa de memoria compartida para agentes de codificación de IA con destilación de pipeline de sueños, anclaje de sesiones y coherencia multi-instancia.
Documentación
Mori (森) — una capa de memoria compartida gobernada para agentes de codificación de IA.
Mori le brinda a un agente memoria con alcance de procedencia: las decisiones y patrones que un humano eligió conservar, presentados en cada sesión — y solo donde aplican. Es la memoria institucional de la que tus agentes se nutren, autoalojada y neutral respecto al agente, para que el conocimiento sobreviva a cualquier modelo que uses este año.
Lo que no hace — y lo probé extensamente — es controlar lo que un agente hace. Ninguna capa de memoria puede hacerlo. En una prueba de estrés multi-modelo y multi-herramienta (más de 5,000 ejecuciones, una docena de modelos), el modelo de codificación más capaz rompió la compilación cada vez; el mismo modelo hizo lo correcto y luego lo incorrecto con una entrada idéntica; y un agente con una herramienta que marcaba su propio cambio como rompedor de compilación leyó la advertencia y aun así envió la ruptura. La capacidad no soluciona esto, y una mejor recuperación tampoco. Lo que se sostiene es la aplicación en un límite que el agente no puede alcanzar — y eso es un trabajo aparte.
📄 La investigación detrás de esto — el Marco de Gobernanza de Límite de Promoción: qué se puede y qué no se puede aplicar realmente en un agente de codificación de IA, cada nulo, cada retractación. Leer el documento técnico →
¿Por qué usar mori?
Tienes razón en ser escéptico con los "sistemas de memoria" — la mayoría son una base de datos vectorial con un prompt de recuperación añadido. Así que ejecuté los experimentos, publiqué los nulos y lideré con el resultado que se sostuvo.
El modo de fallo que mori corrige es la contaminación cruzada. La curación decide qué conservar; la procedencia decide dónde es válido — y en los muchos repositorios de un equipo, esa es la línea entre un cerebro compartido y una responsabilidad. Una memoria que es verdadera en un repositorio, presentada mientras trabajas en otro, hace que el agente alcance con confianza una API que no existe aquí — interferencia de recuperación. Lo reproduje y la solución: con memoria fuera de alcance en el resumen, los agentes persiguieron APIs fantasma en 20/20 ejecuciones; con alcance seguro por procedencia (MORI_BRIEF_SCOPE, activado por defecto), 0/20 — en dos modelos independientes de clase fronteriza (Fisher p ≈ 0). La memoria se sembró deliberadamente desde un repositorio anterior, así que es una prueba de estrés de lo que la deriva canónica hace en meses, no una tasa de incidencia natural — pero el mecanismo es limpio e independiente del modelo. La memoria sin restricciones no es memoria compartida — es contaminación cruzada.
El otro modo de fallo es la obediencia — y es hacia donde mori se dirige, no donde está hoy. La procedencia corrige lo que un agente sabe; no corrige lo que un agente hace. En un benchmark pre-registrado entre repositorios, les di a los agentes fronterizos una herramienta para ver el impacto descendente y una advertencia en lenguaje natural de que un cambio rompería la compilación — y la rompieron de todos modos, 15/15, en cuatro modelos y tres herramientas. Información sin aplicación es fatal — no puedes gobernar una empresa en el espacio de tokens. Ese resultado es la tesis detrás de la próxima capa de mori: playbooks gobernados — una compuerta determinista de pre-cómputo que verifica los archivos de bloqueo de un repositorio contra patrones aprobados por humanos y rechaza una migración insegura antes de que se ejecute, independiente de la redacción del prompt o la obediencia del modelo. (Alcance: migraciones de dependencias npm pre-registradas; la compuerta está construida y evaluada, aún no es una superficie de producto enviada — lidero con lo que probé, no con lo que espero. El argumento completo está en el documento técnico.)
Visibilidad Multi-Instancia
Si ejecutas agentes de codificación de IA en múltiples máquinas, perfiles o en un equipo — uno enfocado en la capa de API, otro en el frontend, un tercero en la infraestructura — ya conoces el problema: cada instancia es brillante de forma aislada, pero ninguna sabe lo que las otras decidieron.
La instancia B no sabe que la instancia A acaba de cambiar el contrato de autenticación. La instancia C no sabe que las suposiciones de despliegue de la instancia B cambiaron. Se enteran de la manera difícil, a mitad de tarea, cuando algo se rompe.
Mori le da a cada instancia la misma imagen compartida. Cada instancia de agente de codificación envía sus eventos de sesión al servidor Mori compartido; el pipeline de sueño destila esos eventos de todas las instancias en un almacén de memoria unificado, y /brief los presenta al inicio de cualquier sesión. Sé claro sobre qué compra eso, sin embargo: una imagen compartida es visibilidad, no coherencia en la que puedas confiar. Presentar lo que la instancia A decidió no hace que la instancia B actúe en consecuencia — un agente de codificación puede leer el cambio de otra instancia y proceder en su contra de todos modos (medí exactamente eso, 15/15). Así que esto es valor real para un equipo cooperativo — todos abren una sesión sabiendo lo que los otros cambiaron — pero es conciencia, no aplicación. Hacer que una instancia realmente honre la decisión de otra es el problema de aplicación, y donde se puede resolver, se resuelve en el límite de promoción en el artefacto comprometido — no por lo que se mostró en ninguna sesión.
Inicio rápido
1. Despliega tu servidor
Cada instancia de Mori es tuya — desplegada en tu propia cuenta, nunca compartida. Elige un camino:
Nube — despliega en tu propia cuenta:
| Plataforma | Persistencia | ~Costo | |
|---|---|---|---|
| Railway + Postgres gratuito (Neon / Supabase) | ✅ Postgres gratuito | ~$5/mes + $0 Postgres | |
| Render (disco persistente en configuración) | ✅ SQLite en disco | ~$7/mes | |
| Cloud Run + Postgres gratuito (Neon / Supabase) | ✅ Postgres gratuito | Pago por uso | |
| GitHub Codespaces — evalúa Mori sin configuración local | ⚠️ efímero | nivel gratuito |
Fly.io (CLI): volumen persistente gratuito + SQLite, ~$3–5/mes — ver one-click-deploy.md.
Nota de persistencia: SQLite necesita un disco o volumen persistente; las plataformas sin estado (Railway, Cloud Run, nivel gratuito de Render) pierden datos al reiniciar sin Postgres. El script de despliegue y la guía explican cómo conectar una base de datos Neon o Supabase gratuita — el camino duradero recomendado de $0. Codespaces son efímeros por diseño — úsalos para evaluar Mori, luego despliega en un host persistente cuando estés listo.
Guía completa: docs/getting-started/one-click-deploy.md
macOS (Homebrew):
brew tap fjwood69/mori
brew install mori
mori-setup # wizard: API key, LLM provider, start service
O ejecuta localmente con Docker Compose:
git clone https://github.com/fjwood69/mori.git
cd mori
cp deploy/homelab/.env.example deploy/homelab/.env
# Edit .env: set MORI_API_KEY to your provider key (Novita, DeepInfra, OpenAI, …)
# and MORI_BASE_URL to the provider's OpenAI-compatible endpoint.
docker compose -f deploy/homelab/docker-compose.yml up -d
2. Verifica
curl http://localhost:8968/health
# {"status":"ok","service":"mori-advisor"}
3. Conecta tu agente
Claude Code — instala como plugin (recomendado). Dentro de Claude Code, ejecuta:
/plugin marketplace add fjwood69/mori
/plugin install mori@mori
Se te pedirá la URL de tu servidor Mori y la clave API al habilitarlo (la clave se almacena en tu llavero del sistema operativo, no en settings.json). Luego /reload-plugins o reinicia.
El mismo paquete de plugin (plugins/mori/) también apunta a OpenCode, Codex, Cursor y Google Antigravity — la conexión MCP y las habilidades funcionan en los cinco; los hooks específicos del cliente llegan por plataforma. Ver las guías de plataforma.
O usa los scripts de instalación heredados (personalizados; superados por el plugin):
./scripts/legacy/install-mori-claude.sh # Claude Code
./scripts/install-mori-cursor.sh # Cursor
powershell -File scripts/legacy/install-mori-claude.ps1 # Windows
Guías de plataforma
| Plataforma | Instalación | Guía completa |
|---|---|---|
| Claude Code | Plugin: /plugin marketplace add fjwood69/mori → /plugin install mori@mori (o ./scripts/legacy/install-mori-claude.sh) | docs/getting-started/claude-code.md |
| OpenCode | ./scripts/install-mori-opencode.sh (o .\scripts\install-mori-opencode.ps1 en Windows) | docs/getting-started/opencode.md |
| Codex | Paquete de plugin plugins/mori/ → codex plugin install mori | docs/getting-started/codex.md |
| Cursor | Paquete de plugin plugins/mori/ (o ./scripts/install-mori-cursor.sh) | docs/getting-started/cursor.md |
| Google Antigravity IDE | Paquete de plugin plugins/mori/ (o ./scripts/install-mori-antigravity.sh) | docs/getting-started/antigravity.md |
| Cline | ./scripts/install-mori-cline.sh | docs/getting-started/cline.md |
Capacidades
| Capacidad | Qué hace | Comando de barra |
|---|---|---|
| Pipeline de sueño | Auto-destila eventos de sesión en memorias estructuradas | /dream |
| Fundamentación de sesión | Carga contexto compartido al inicio de la sesión — no RAG por consulta; re-fundamentación delta ligera después de la compactación de contexto | /brief, /brief --post-compact |
| Búsqueda de memoria | Búsqueda de texto completo clasificada y navegación en el almacén compartido (SQLite FTS5 / Postgres tsvector) | /pensieve |
| Panel web | Navegador de memoria integrado servido en la URL raíz de mori — buscar, navegar, desplegar | — |
| Ingesta universal | Alimenta PDFs, imágenes, git, transcripciones al almacén de memoria | /ingest |
| Revisión estratégica | Orientación LLM con áreas de enfoque y estándares auto-inyectados | /consult |
| Seguimiento de requisitos | Lista de verificación de proyecto ligera presentada vía /brief | /req |
| Gobernanza | Claves API con alcance de capacidad (roles de lectura/escritura/soñador), versionado, soñadores de confianza, reversión, atribución; una auditoría de escritura universal en transacción + aplicación de anatomía y capacidad por nivel en el punto de estrangulamiento store.write (con bandera, modo auditoría por defecto) | — |
| Cola de curación | Las propuestas canónicas/estándar de la ingesta esperan la aprobación del soñador de confianza en una interfaz de revisión (/review, con fuente/diff/aprobar-rechazar) antes de volverse canónicas — memoria que está curada, no solo acumulada | — |
| Despliegue de un clic | Levanta tu propio servidor en Render / Railway / Fly / Cloud Run (o Postgres gestionado gratuito + cualquier host sin estado) | — |
| Mensajería NATS | Conciencia entre dispositivos en tiempo real | /nats |
| Mensajería entre agentes | Envía tareas, preguntas y decisiones a través de la red de dispositivos | /msg |
| Despliegue de habilidades | Empuja comandos de barra a todos los dispositivos en un solo paso | /update |
Referencia completa: docs/reference/slash-commands.md
Combina bien con
Mori es la memoria ganada de tu equipo — no un caché de documentación. Recuerda lo que tus agentes decidieron y aprendieron en sesiones y dispositivos. Complementa herramientas que suministran conocimiento externo en vivo:
- Context7 — documentación de bibliotecas y frameworks actualizada y específica por versión inyectada en el prompt. Donde Mori recuerda "elegimos X, y por qué", Context7 suministra "aquí está la API actual de X." Capa diferente, propósito complementario.
- La documentación propia de tu plataforma — para comportamiento de herramientas y entornos en rápido movimiento (esquemas de hooks, formatos de configuración), consulta la documentación oficial actual en lugar del recuerdo de datos de entrenamiento. Ver la práctica Lee el manual actual, no tu memoria en agent-working-practices.
Cómo funciona
Pipeline de sueño — la mitad de propuesta de la compuerta
El pipeline de sueño es el mecanismo de propuesta, no el producto. Se ejecuta con alta recuperación: convierte la actividad de la sesión en memorias candidatas y deliberadamente sobre-produce — recuperación sobre precisión — porque nada de lo que emite llega al canon sin que un humano lo promueva (ver Gobernanza abajo). Esa división del trabajo — la máquina propone, el humano dispone — es la compuerta que el benchmark mide.
Los eventos de sesión se capturan mediante hooks del ciclo de vida del agente (Claude Code, Cursor, Antigravity) y se destilan en memorias estructuradas por un LLM configurable.
Hook fires → POST /api/events/raw → events table (SQLite/Postgres)
↓
PreCompact → POST /api/precompact → dream_run() reads since watermark
↓
LLM distills events → structured memories
↓
memories written to store (with attribution)
↓
watermark advanced
El hook PreCompact dispara un sueño síncrono inmediato antes de la compresión de contexto — para que nada se pierda en el momento más importante.
Su contraparte funciona después de la compresión: un hook SessionStart se dispara cuando la sesión se reanuda después de la compactación (source: "compact") y ejecuta /brief --post-compact — un delta ligero que presenta solo lo que cambió en el almacén compartido desde tu último resumen (memorias nuevas, superadas y desalojadas), omitiendo la recarga base completa y el escaneo de frescura. PreCompact preserva lo que esta sesión aprendió; SessionStart lo re-fundamenta en lo que cada otra instancia cambió mientras estaba ocupada.
Qué captura: PostToolUse, PostToolUseFailure, PreCompact,
UserPromptSubmit, Stop — llamadas a herramientas, prompts, errores, motivos de detención,
ID de sesión, hostname, directorio de trabajo, ruta del transcript y (en Stop)
el razonamiento propio del asistente — los planes, análisis y decisiones detrás de
cada turno.
Gobernanza — la puerta
Las propuestas no se convierten en canon por sí solas. Tanto el pipeline de sueño (tus sesiones)
como la vía de ingesta de agentes autónomos (otros agentes) escriben en una cola de revisión, no
en el canon. Un soñador de confianza — un humano — revisa los candidatos y promueve los que
soportan carga; cada promoción queda versionada y registrada en write_audit. Los agentes
leen el canon; nunca lo escriben silenciosamente.
Por debajo, cada escritura — incluida la del soñador — pasa por un único punto de control de
autorización auditado: una procedencia estructurada registra una fila write_audit en la misma
transacción que la escritura, y la aplicación de capacidades por nivel + anatomía controla quién
puede escribir qué (ambas incluyen modo de auditoría por defecto, para que la política se mida
antes de que muerda).
Para mantener esa revisión económica, mori agrupa candidatos casi duplicados de modo que el revisor despache una convención una vez en lugar de muchas. El lado de las propuestas funciona con alta recuperación (recall); la puerta es lo que hace que la alta recuperación sea asequible en lugar de agotadora. Esta es la línea que mide el benchmark — y también la costura comercial: los paquetes de estándares y políticas entran por la misma puerta (firmados, versionados, auditados), no por confiar en el sistema de archivos.
Almacén de memoria
Las memorias viven en el almacén — SQLite (memories.db) para despliegues individuales/síncronos,
Postgres para equipos/asíncronos — con tres niveles:
SQLite vs Postgres es una frontera de confianza, no solo un interruptor de backend. SQLite es el modo una persona, un escritor — el predeterminado de configuración cero para un único usuario en una máquina, donde tú eres lo único que escribe. Postgres es el modo equipo — muchas máquinas, muchos agentes, escritores concurrentes — y es obligatorio para cualquier cosa más allá de uso individual: el bloqueo a nivel de archivo de SQLite serializa las escrituras y no puede sostenerlo. Las capacidades que existen porque hay múltiples escritores (el pipeline de ingesta/gobernanza de agentes autónomos) son solo Postgres por diseño. La cola de curación aún funciona en SQLite en forma degradada de escritor único — un humano controlando a sus propios agentes — así que la puerta nunca está indisponible; simplemente no necesita concurrencia hasta que un equipo la necesita. Elige Postgres para uso en producción/equipos.
| Nivel | Alcance | Ciclo de vida |
|---|---|---|
| Efímero | Resúmenes de sesión | Caduca automáticamente salvo que se guarde explícitamente |
| De trabajo | Patrones, decisiones, contexto del proyecto | Se marca tras 30 días sin recuperación |
| Canónico | Promovido explícitamente por un soñador de confianza | Indefinido, verificado por frescura vía /brief |
Versionado, diff, reversión, atribución y gobernanza integrados. Consulta docs/reference/configuration.md.
Ingesta universal
Los nuevos miembros del equipo empiezan desde cero. /ingest arranca el almacén de memoria a partir
de material fuente existente — aplicando el mismo pipeline de destilación que
impulsa la fase de sueño.
# Preview (zero cost, no LLM):
/ingest --source ~/my-project --preview
# Dry-run to validate extraction quality:
/ingest --source ~/my-project --dry-run --focus decisions
# Commit:
/ingest --source ~/my-project --focus all --tier working
Soportados: PDF, imágenes/pizarras (visión Kimi K2.6), transcripciones CC
(.jsonl), historial de git (--since 30d), texto y código.
Funciona con servidores remotos: /ingest lee archivos en el dispositivo cliente y
envía el contenido por la red — no se necesita un sistema de archivos compartido. Funciona tanto si
mori-advisor se ejecuta localmente como en GCE.
Protección de costos: --max-cost (por defecto $5.00) aborta antes de gastar. La vista
previa siempre es gratuita. La deduplicación SHA256 evita re-ingerir el mismo contenido.
Consulta estratégica (/consult)
Haz una pregunta a mitad de sesión y obtén orientación estratégica fundamentada en tu contexto real del proyecto — no consejos genéricos. Cuando se especifica un área de enfoque, los estándares relevantes del equipo se extraen automáticamente del almacén de memoria y se inyectan junto a tu pregunta. El asesor verifica contra tu propia línea base, no contra un libro de texto.
# Architecture review with file context:
/consult "should we move auth to a separate service?" --focus architecture
# Security review against your team's own baseline:
/consult "review this handler" --focus security --file src/auth.py
# Chain tool output directly into the advisor:
/consult "review this" --focus security --file src/auth.py --file snyk-report.json
Funciona con servidores remotos: --file lee archivos en el dispositivo cliente e inyecta contenido en el prompt del asesor — no se requiere sistema de archivos compartido. Funciona tanto si mori-advisor se ejecuta localmente como en GCE.
Áreas de enfoque: general, architecture, security, performance, style
Niveles de profundidad: quick (escaneo rápido), balanced (predeterminado), deep (exhaustivo)
Consciente de estándares: configura MORI_STANDARDS_DIR con un directorio de archivos .md
y Mori los importa como memorias protegidas. /consult --focus security
inyecta tu línea base de seguridad en la llamada del asesor, de modo que /consult revisa
contra tus reglas, no contra un libro de texto. (Eso es el asesor — una solicitud de revisión única y
acotada — leyendo tus estándares; no es una afirmación de que tu agente de codificación los
obedezca durante la tarea. Los estándares expuestos informan; no vinculan).
Mensajería entre agentes (/msg)
Delega tareas, haz preguntas y comparte decisiones entre tus instancias de Claude Code
— sin una sesión compartida. Los mensajes están tipados, organizados en hilos de respuesta y
se recogen en el siguiente /brief. El daemon mori-msg recibe mensajes
del lado del servidor: los mensajes decision se escriben directamente en el almacén de memoria
sin ninguna sesión humana en el extremo receptor.
# From your laptop, delegate a task to a workstation:
/msg send workstation task "Refactor auth middleware — extract rate limiting into its own module"
# The workstation picks it up at next /brief and acks:
/msg ack a3f9c2b1 "on it"
# Back on your laptop, check the reply:
/msg inbox
# The workstation marks it done when finished:
/msg done a3f9c2b1
Tipos de mensajes: task, decision, question, reply, ack, done, broadcast
Requiere el daemon mori-msg ejecutándose junto a mori-advisor (incluido en
el stack de pods predeterminado). Consulta docs/reference/msg.md para la referencia completa.
Panel web
No todos los que necesitan la memoria compartida ejecutan una sesión de Claude Code. Mori sirve un navegador de memoria integrado en su propia URL raíz — solo abre el servidor en un navegador:
http://<your-mori-host>:8968/
Introduce cualquier clave API válida (la misma MORI_API_KEYS que usan tus clientes) y podrás buscar,
navegar y hacer clic en cualquier tarjeta para desplegar su cuerpo completo y su procedencia (clientes de origen,
nivel, conteo de recuperaciones, frescura). La página se sirve del mismo origen (same-origin), por lo que habla
directamente con la instancia de mori desde la que se cargó — no hay URL base que configurar, ni servidor separado
que ejecutar. Es un único archivo sin dependencias (vanilla JS, sin paso de compilación, sin CDN), respaldado por
una pequeña API REST de lectura:
| Ruta | Devuelve |
|---|---|
GET /api/memories?query=&type=&tag=&client=&since=&limit= | Lista clasificada de texto completo (o por actualidad) — forma ligera, sin cuerpo |
GET /api/memories/{name} | Una memoria completa — cuerpo + procedencia (carga diferida al desplegar) |
GET /api/events?session_id=&client=&since=&limit= | Registro de eventos de sesión, más recientes primero |
El panel y sus rutas son de solo lectura y están protegidos por clave API (X-Api-Key); las acciones
de escritura (eliminar, revisión de soñador de confianza) se difieren hasta que la superficie de lectura se valide.
La página también está disponible de forma independiente (dashboard/index.html) si prefieres alojarla en otro lugar
y apuntarla a una instancia de mori — configura MORI_CORS_ORIGINS para ese caso de
origen cruzado (no es necesario para el servicio integrado del mismo origen).
Arquitectura
Configuración
Referencia de configuración → docs/reference/configuration.md Modelos recomendados → docs/reference/models.md Para equipos → docs/for-teams.md Referencia de configuración de equipos → docs/reference/team-configuration.md
Variables de entorno clave:
| Variable | Predeterminado | Descripción |
|---|---|---|
MORI_PROVIDER_MODE | bifrost | direct o bifrost |
MORI_API_KEY | — | Clave del proveedor (requerida en modo direct) |
MORI_BASE_URL | — | URL base compatible con OpenAI |
MORI_MODEL | moonshotai/kimi-k2.6 | Modelo de asesor + consulta |
MORI_DREAM_MODEL | recurre a MORI_MODEL | Modelo de destilación de sueño + ingesta |
MORI_FAST_MODEL | deepseek/deepseek-v4-flash | Escaneo de contradicciones + verificaciones de frescura |
MORI_API_KEYS | — | Claves API de clientes nombrados: name:secret,name:secret,... — consulta Autenticación |
MORI_BRIEF_SCOPE | safe | safe = brief enrutado por procedencia (canon con origen de otro proyecto se omite; solo scope:global explícito); all = legado, sin ámbito |
MORI_TRUSTED_DREAMERS | — | Hostnames de confianza separados por comas |
MORI_DREAM_INTERVAL | 60 | Intervalo del cron de sueño (minutos) |
MORI_STANDARDS_DIR | — | Ruta a los archivos .md de estándares del equipo |
MORI_MSG_HEADLESS_ENABLED | false | Genera Claude sin interfaz para tareas entrantes |
MORI_MSG_HEADLESS_TRUSTED | — | Hostnames separados por comas autorizados a activar CC sin interfaz |
Autenticación: Configura MORI_API_KEYS para dar a cada cliente una clave nombrada. Sin ella, el servidor
arranca en modo abierto (adecuado para redes privadas de Tailscale; configura siempre claves para despliegues
compartidos o accesibles desde Internet). Genera secretos con python3 -c "import secrets; print(secrets.token_hex(32))". Detalles completos:
docs/reference/configuration.md → Autenticación.
Compilación
git clone https://github.com/fjwood69/mori.git
cd mori
podman build -t localhost/mori-advisor:latest .
# Or: docker build -t mori-advisor:latest .
Licencia
AGPL-3.0 — consulta LICENSE. Licencias comerciales disponibles — consulta COMMERCIAL.md. Las contribuciones requieren un CLA único — consulta CONTRIBUTING.md.