Mori
Camada de memória compartilhada para agentes de codificação de IA com destilação de pipeline de sonhos, ancoragem de sessão e coerência multi-instância.
Documentação
Mori (森) — uma camada de memória compartilhada e governada para agentes de codificação de IA.
Mori dá ao agente uma memória com escopo de proveniência: as decisões e padrões que um humano escolheu manter, exibidos para cada sessão — e somente onde eles se aplicam. É a memória institucional da qual seus agentes extraem, auto-hospedada e neutra em relação ao agente, para que o conhecimento sobreviva a qualquer modelo que você esteja usando este ano.
O que ela não faz — e testei isso extensivamente — é controlar o que um agente faz. Nenhuma camada de memória consegue. Em um teste de estresse multi-modelo e multi-harness (mais de 5.000 execuções, uma dúzia de modelos), o modelo de codificação mais capaz quebrou o build todas as vezes; o mesmo modelo fez a coisa certa, depois a coisa errada, com entrada idêntica; e um agente que recebeu uma ferramenta que sinalizava sua própria mudança como quebra de build leu o aviso e enviou a quebra mesmo assim. Capacidade não resolve isso, e recuperação melhor também não. O que se sustenta é aplicação em uma fronteira que o agente não consegue alcançar — e isso é um trabalho separado.
📄 A pesquisa por trás disso — o Promotion-Boundary Governance Framework: o que pode e o que não pode ser realmente aplicado em um agente de codificação de IA, cada nulo, cada retração. Leia o whitepaper →
Por que usar mori?
Você está certo em ser cético em relação a "sistemas de memória" — a maioria é um banco de dados vetorial com um prompt de recuperação acoplado. Então executei os experimentos, publiquei os nulos e liderei com o resultado que se sustentou.
O modo de falha que mori corrige é a contaminação cruzada. Curadoria decide o que manter;
proveniência decide onde é válido — e entre os muitos repositórios de uma equipe, essa é a linha
entre um cérebro compartilhado e um passivo. Uma memória que é verdadeira em um repositório, exibida enquanto você trabalha
em outro, faz o agente buscar com confiança uma API que não existe aqui —
interferência de recuperação. Reproduzi isso e a correção: com memória fora do escopo no briefing,
os agentes perseguiram APIs fantasma em 20/20 execuções; com escopo seguro por proveniência (MORI_BRIEF_SCOPE,
ativado por padrão), 0/20 — em dois modelos independentes de classe frontier (Fisher p ≈ 0). A
memória foi deliberadamente semeada de um repositório anterior, então é um teste de estresse do que a deriva de cânone
faz ao longo de meses, não uma taxa de incidência natural — mas o mecanismo é limpo e
independente de modelo. Memória sem portão não é memória compartilhada — é contaminação cruzada.
O outro modo de falha é a obediência — e é para onde mori está indo, não onde está hoje. Proveniência corrige o que um agente sabe; não corrige o que um agente faz. Em um benchmark pré-registrado entre repositórios, dei aos agentes frontier uma ferramenta para ver o impacto downstream e um aviso em linguagem simples de que uma mudança quebraria um build — e eles quebraram mesmo assim, 15/15, em quatro modelos e três harnesses. Informação sem aplicação é fatal — você não pode governar uma empresa no espaço de tokens. Esse resultado é a tese por trás da próxima camada de mori: playbooks governados — um portão determinístico de pré-computação que verifica os lockfiles de um repositório contra padrões aprovados por humanos e recusa uma migração insegura antes de executá-la, independente da formulação do prompt ou da obediência do modelo. (Escopo: migrações de dependências npm pré-registradas; o portão está construído e benchmarkado, ainda não é uma superfície de produto enviada — lidero com o que provei, não com o que espero. O argumento completo está no whitepaper.)
Visibilidade Multi-Instância
Se você executa agentes de codificação de IA em várias máquinas, perfis ou em uma equipe — um focado na camada de API, outro no frontend, um terceiro na infraestrutura — você já conhece o problema: cada instância é brilhante isoladamente, mas nenhuma sabe o que as outras decidiram.
A Instância B não sabe que a Instância A acabou de mudar o contrato de autenticação. A Instância C não sabe que as suposições de implantação da Instância B mudaram. Elas descobrem da pior forma, no meio da tarefa, quando algo quebra.
Mori dá a cada instância o mesmo quadro compartilhado. Cada instância de agente de codificação envia
seus eventos de sessão para o servidor Mori compartilhado; o pipeline de sonho destila esses eventos de
todas as instâncias em um armazenamento de memória unificado, e /brief os exibe no início de
qualquer sessão. Seja claro sobre o que isso compra, no entanto: um quadro compartilhado é visibilidade, não
coerência em que você pode confiar. Exibir o que a Instância A decidiu não faz a Instância B agir
sobre isso — um agente de codificação pode ler a mudança de outra instância e prosseguir contra ela mesmo assim (eu
medi exatamente isso, 15/15). Então isso é valor real para uma equipe cooperativa — todos
abrem uma sessão sabendo o que os outros mudaram — mas é consciência, não aplicação.
Fazer uma instância realmente honrar a decisão de outra é o problema de aplicação, e onde
isso pode ser resolvido, é resolvido na fronteira de promoção no artefato comprometido —
não pelo que qualquer sessão foi mostrada.
Início Rápido
1. Implante seu servidor
Cada instância Mori é sua — implantada na sua própria conta, nunca compartilhada. Escolha um caminho:
Nuvem — implante na sua própria conta:
| Plataforma | Persistência | ~Custo | |
|---|---|---|---|
| Railway + Postgres gratuito (Neon / Supabase) | ✅ Postgres gratuito | ~$5/mês + $0 Postgres | |
| Render (disco persistente na configuração) | ✅ SQLite em disco | ~$7/mês | |
| Cloud Run + Postgres gratuito (Neon / Supabase) | ✅ Postgres gratuito | Pague conforme o uso | |
| GitHub Codespaces — avalie Mori sem configuração local | ⚠️ efêmero | camada gratuita |
Fly.io (CLI): volume persistente gratuito + SQLite, ~$3–5/mês — veja one-click-deploy.md.
Nota sobre persistência: SQLite precisa de um disco ou volume persistente; plataformas sem estado (Railway, Cloud Run, camada gratuita do Render) perdem dados na reinicialização sem Postgres. O script de implantação e o guia explicam como conectar um banco de dados Neon ou Supabase gratuito — o caminho durável recomendado de $0. Codespaces são efêmeros por design — use-os para avaliar Mori, depois implante em um host persistente quando estiver pronto.
Guia completo: 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
Ou execute localmente com 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. Verifique
curl http://localhost:8968/health
# {"status":"ok","service":"mori-advisor"}
3. Conecte seu agente
Claude Code — instale como um plugin (recomendado). Dentro do Claude Code, execute:
/plugin marketplace add fjwood69/mori
/plugin install mori@mori
Você será solicitado a fornecer a URL do seu servidor Mori e a chave de API na ativação (a chave é armazenada
no chaveiro do seu sistema operacional, não em settings.json). Depois, /reload-plugins ou reinicie.
O mesmo pacote de plugin (plugins/mori/) também tem como alvo OpenCode, Codex,
Cursor e Google Antigravity — a conexão MCP e as habilidades funcionam em todos os cinco;
hooks específicos do cliente chegam por plataforma. Veja os guias de plataforma.
Ou use os scripts de instalação legados (personalizados; substituídos pelo plugin):
./scripts/legacy/install-mori-claude.sh # Claude Code
./scripts/install-mori-cursor.sh # Cursor
powershell -File scripts/legacy/install-mori-claude.ps1 # Windows
Guias de plataforma
| Plataforma | Instalação | Guia completo |
|---|---|---|
| Claude Code | Plugin: /plugin marketplace add fjwood69/mori → /plugin install mori@mori (ou ./scripts/legacy/install-mori-claude.sh) | docs/getting-started/claude-code.md |
| OpenCode | ./scripts/install-mori-opencode.sh (ou .\scripts\install-mori-opencode.ps1 no Windows) | docs/getting-started/opencode.md |
| Codex | Pacote de plugin plugins/mori/ → codex plugin install mori | docs/getting-started/codex.md |
| Cursor | Pacote de plugin plugins/mori/ (ou ./scripts/install-mori-cursor.sh) | docs/getting-started/cursor.md |
| Google Antigravity IDE | Pacote de plugin plugins/mori/ (ou ./scripts/install-mori-antigravity.sh) | docs/getting-started/antigravity.md |
| Cline | ./scripts/install-mori-cline.sh | docs/getting-started/cline.md |
Capacidades
| Capacidade | O que faz | Comando de barra |
|---|---|---|
| Pipeline de sonho | Auto-destila eventos de sessão em memórias estruturadas | /dream |
| Fundamentação de sessão | Carrega contexto compartilhado no início da sessão — não RAG por consulta; re-fundamentação leve por delta após compactação de contexto | /brief, /brief --post-compact |
| Busca de memória | Busca de texto completo classificada e navegação no armazenamento compartilhado (SQLite FTS5 / Postgres tsvector) | /pensieve |
| Painel web | Navegador de memória integrado servido na URL raiz do mori — busca, navegação, desdobramento | — |
| Ingestão universal | Alimente PDFs, imagens, git, transcrições no armazenamento de memória | /ingest |
| Revisão estratégica | Orientação LLM com áreas de foco e padrões injetados automaticamente | /consult |
| Rastreamento de requisitos | Checklist de projeto leve exibido via /brief | /req |
| Governança | Chaves de API com escopo de capacidade (funções leitura/escrita/sonhador), versionamento, sonhadores confiáveis, reversão, atribuição; auditoria de escrita universal em transação + aplicação de capacidade de camada e anatomia no ponto de estrangulamento store.write (controlado por flag, modo de auditoria por padrão) | — |
| Fila de curadoria | Propostas canônicas/padrão da ingestão aguardam aprovação de sonhador confiável em uma UI de revisão (/review, com fonte/diff/aprovar-rejeitar) antes de se tornarem canônicas — memória curada, não apenas acumulada | — |
| Implantação com um clique | Configure seu próprio servidor em Render / Railway / Fly / Cloud Run (ou Postgres gerenciado gratuito + qualquer host sem estado) | — |
| Mensagens NATS | Consciência entre dispositivos em tempo real | /nats |
| Mensagens entre agentes | Envie tarefas, perguntas e decisões pela rede de dispositivos | /msg |
| Implantação de habilidades | Envie comandos de barra para todos os dispositivos em uma única etapa | /update |
Referência completa: docs/reference/slash-commands.md
Combina bem com
Mori é a memória conquistada da sua equipe — não um cache de documentação. Ela lembra o que seus agentes decidiram e aprenderam entre sessões e dispositivos. Ela complementa ferramentas que fornecem conhecimento externo ao vivo:
- Context7 — documentação de biblioteca e framework atualizada e específica por versão injetada no prompt. Onde Mori lembra "escolhemos X, e por quê", Context7 fornece "aqui está a API atual de X." Camada diferente, propósito complementar.
- A documentação da sua própria plataforma — para comportamento de ferramentas e harness em rápida evolução (esquemas de hooks, formatos de configuração), consulte a documentação oficial atual em vez de recuperação de dados de treinamento. Veja a prática Leia o manual atual, não sua memória em agent-working-practices.
Como funciona
Pipeline de sonho — a metade de proposta do portão
O pipeline de sonho é o mecanismo de proposta, não o produto. Ele roda com alta recall: transforma atividade de sessão em memórias candidatas e deliberadamente superproduz — recall sobre precisão — porque nada que ele emite chega ao cânone sem um humano promovê-lo (veja Governança abaixo). Essa divisão de trabalho — máquina propõe, humano dispõe — é o portão que o benchmark mede.
Eventos de sessão são capturados via hooks de ciclo de vida do agente (Claude Code, Cursor, Antigravity) e destilados em memórias estruturadas por um LLM configurável.
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
O hook PreCompact dispara um sonho síncrono imediato antes da compactação
de contexto — para que nada seja perdido no momento mais importante.
Sua contraparte funciona depois da compactação: um hook SessionStart dispara quando a
sessão retoma pós-compactação (source: "compact") e executa /brief --post-compact
— um delta leve que exibe apenas o que mudou no armazenamento compartilhado desde
seu último briefing (memórias novas, substituídas e removidas), pulando o recarregamento
completo da base e a varredura de frescor. PreCompact preserva o que esta sessão aprendeu;
SessionStart re-fundamenta no que todas as outras instâncias mudaram enquanto estava ocupada.
O que ele captura: PostToolUse, PostToolUseFailure, PreCompact,
UserPromptSubmit, Stop — chamadas de ferramentas, prompts, erros, motivos de parada,
ID da sessão, hostname, diretório de trabalho, caminho do transcript e (em Stop)
o raciocínio do próprio assistente — os planos, análises e decisões por trás de
cada turno.
Governança — o portão
Propostas não se tornam cânone por conta própria. Tanto o pipeline de sonho (suas sessões)
quanto o caminho de ingestão de agentes autônomos (outros agentes) escrevem em uma fila de revisão, não
no cânone. Um sonhador confiável — um humano — revisa os candidatos e promove os que são
essenciais; cada promoção é versionada e registrada em write_audit. Agentes leem
cânone; eles nunca o escrevem silenciosamente.
Por baixo, toda escrita — incluindo a do sonhador — passa por um ponto de verificação de autorização
auditado: uma proveniência estruturada gera uma linha write_audit na mesma transação da
escrita, e a aplicação de capacidade por camada + anatomia controla quem pode escrever o quê
(ambos vêm com modo de auditoria por padrão, então a política é medida antes de causar impacto).
Para manter essa revisão barata, o mori agrupa candidatos quase duplicados para que o revisor lide com uma convenção uma vez em vez de muitas vezes. O lado da proposta opera com alta revocação; o portão é o que torna a alta revocação acessível em vez de exaustiva. Esta é a linha que o benchmark mede — e também a costura comercial: pacotes de padrões e políticas entram pelo mesmo portão (assinados, versionados, auditados), não confiando no sistema de arquivos.
Armazenamento de memória
As memórias vivem no armazenamento — SQLite (memories.db) para implantações solo/síncronas,
Postgres para equipe/assíncrono — com três camadas:
SQLite vs Postgres é uma fronteira de confiança, não apenas uma opção de backend. SQLite é o modo um humano, um escritor — o padrão de configuração zero para um único usuário em uma máquina, onde você é a única coisa que escreve. Postgres é o modo equipe — muitas máquinas, muitos agentes, escritores concorrentes — e é obrigatório para qualquer coisa além de solo: o bloqueio em nível de arquivo do SQLite serializa escritas e não consegue sustentar isso. Capacidades que existem porque múltiplos escritores existem (o pipeline de ingestão / governança de agentes autônomos) são somente Postgres por design. A fila de curadoria ainda roda em SQLite em forma degradada de escritor único — um humano controlando seus próprios agentes — então o portão nunca fica indisponível; ele só não precisa de concorrência até que uma equipe precise. Escolha Postgres para produção/uso em equipe.
| Camada | Escopo | Ciclo de vida |
|---|---|---|
| Efêmero | Resumos de sessão | Expira automaticamente a menos que seja explicitamente salvo |
| Trabalho | Padrões, decisões, contexto do projeto | Sinalizado após 30 dias sem recuperação |
| Canônico | Promovido explicitamente por um sonhador confiável | Indefinido, verificação de atualidade via /brief |
Versionamento, diff, rollback, atribuição e governança integrados. Veja docs/reference/configuration.md.
Ingestão universal
Novos membros da equipe começam do zero. /ingest inicializa o armazenamento de memória a partir de
material de origem existente — aplicando o mesmo pipeline de destilação que alimenta a fase de sonho.
# 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
Suportados: PDF, imagens/quadros brancos (visão Kimi K2.6), transcrições CC
(.jsonl), histórico do git (--since 30d), texto e código.
Funciona com servidores remotos: /ingest lê arquivos no dispositivo do cliente e
envia conteúdo pela rede — sem necessidade de sistema de arquivos compartilhado. Funciona tanto se o
mori-advisor estiver rodando localmente quanto no GCE.
Proteção de custo: --max-cost (padrão $5,00) aborta antes de gastar. A pré-visualização
é sempre gratuita. A deduplicação SHA256 evita re-ingestão do mesmo conteúdo.
Consulta estratégica (/consult)
Faça uma pergunta no meio da sessão e obtenha orientação estratégica baseada no contexto real do seu projeto — não conselhos genéricos. Quando uma área de foco é especificada, os padrões relevantes da equipe são automaticamente puxados do armazenamento de memória e injetados junto com sua pergunta. O consultor verifica em relação à sua própria linha de base, não a um livro-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 com servidores remotos: --file lê arquivos no dispositivo do cliente e injeta conteúdo no prompt do consultor — sem necessidade de sistema de arquivos compartilhado. Funciona tanto se o mori-advisor rodar localmente quanto no GCE.
Áreas de foco: general, architecture, security, performance, style
Níveis de profundidade: quick (varredura rápida), balanced (padrão), deep (completo)
Ciente de padrões: defina MORI_STANDARDS_DIR para um diretório de arquivos .md
e o Mori os importa como memórias protegidas. /consult --focus security
injeta sua linha de base de segurança na chamada do consultor, então /consult revisa de acordo com suas regras, não um livro-texto. (Isso é o consultor — uma única solicitação de revisão com escopo — lendo seus padrões; não é uma afirmação de que seu agente de codificação os obedece durante a tarefa. Padrões exibidos informam; eles não vinculam.)
Mensagens entre agentes (/msg)
Delegue tarefas, faça perguntas e compartilhe decisões entre suas instâncias do Claude Code
— sem uma sessão compartilhada. As mensagens são tipadas, com threads de resposta, e são
coletadas no próximo /brief. O daemon mori-msg recebe mensagens no lado do servidor:
mensagens decision são escritas diretamente no armazenamento de memória sem nenhuma sessão humana no lado 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 mensagem: task, decision, question, reply, ack, done, broadcast
Requer o daemon mori-msg rodando junto com mori-advisor (incluído na
pilha padrão de pods). Veja docs/reference/msg.md para referência completa.
Painel web
Nem todo mundo que precisa da memória compartilhada executa uma sessão do Claude Code. O Mori serve um navegador de memória integrado em sua própria URL raiz — basta abrir o servidor em um navegador:
http://<your-mori-host>:8968/
Insira qualquer chave de API válida (a mesma MORI_API_KEYS que seus clientes usam) e você pode pesquisar,
navegar e clicar em qualquer cartão para desdobrar seu corpo completo e proveniência (clientes de origem, camada,
contagem de recuperação, atualidade). A página é servida mesma origem, então ela fala com a própria
instância do mori de onde foi carregada — sem URL base para configurar, sem servidor separado para executar. É um
único arquivo sem dependências (vanilla JS, sem etapa de build, sem CDN), apoiado por uma pequena API REST de leitura:
| Rota | Retorna |
|---|---|
GET /api/memories?query=&type=&tag=&client=&since=&limit= | Lista classificada por texto completo (ou recência) — formato enxuto, sem corpo |
GET /api/memories/{name} | Uma memória completa — corpo + proveniência (carregada sob demanda ao desdobrar) |
GET /api/events?session_id=&client=&since=&limit= | Log de eventos da sessão, mais recentes primeiro |
O painel e suas rotas são somente leitura e protegidos por chave de API (X-Api-Key); ações
de escrita (excluir, revisão de sonhador confiável) são adiadas até que a superfície de leitura seja validada.
A página também está disponível de forma autônoma (dashboard/index.html) se você preferir hospedá-la
em outro lugar e apontá-la para uma instância do mori — defina MORI_CORS_ORIGINS para esse caso
de origem cruzada (é desnecessário para a veiculação integrada de mesma origem).
Arquitetura
Configuração
Referência de configuração → docs/reference/configuration.md Modelos recomendados → docs/reference/models.md Para equipes → docs/for-teams.md Referência de configuração para equipes → docs/reference/team-configuration.md
Principais variáveis de ambiente:
| Variável | Padrão | Descrição |
|---|---|---|
MORI_PROVIDER_MODE | bifrost | direct ou bifrost |
MORI_API_KEY | — | Chave do provedor (obrigatória no modo direct) |
MORI_BASE_URL | — | URL base compatível com OpenAI |
MORI_MODEL | moonshotai/kimi-k2.6 | Modelo de consultor + consulta |
MORI_DREAM_MODEL | recai em MORI_MODEL | Modelo de destilação de sonho + ingestão |
MORI_FAST_MODEL | deepseek/deepseek-v4-flash | Verificação de contradição + verificações de atualidade |
MORI_API_KEYS | — | Chaves de API nomeadas do cliente: name:secret,name:secret,... — veja Autenticação |
MORI_BRIEF_SCOPE | safe | safe = resumo roteado por proveniência (cânone vinculado à origem entre projetos retido; apenas scope:global explícito); all = legado, sem escopo |
MORI_TRUSTED_DREAMERS | — | Hostnames confiáveis separados por vírgula |
MORI_DREAM_INTERVAL | 60 | Intervalo do cron de sonho (minutos) |
MORI_STANDARDS_DIR | — | Caminho para arquivos .md de padrões da equipe |
MORI_MSG_HEADLESS_ENABLED | false | Gerar Claude headless para tarefas recebidas |
MORI_MSG_HEADLESS_TRUSTED | — | Hostnames separados por vírgula permitidos para acionar CC headless |
Autenticação: Defina MORI_API_KEYS para dar a cada cliente uma chave nomeada. Sem isso o servidor inicia em modo aberto (ok para redes privadas Tailscale; sempre defina chaves para implantações compartilhadas ou acessíveis pela internet). Gere segredos com python3 -c "import secrets; print(secrets.token_hex(32))". Detalhes completos: docs/reference/configuration.md → Autenticação.
Compilação
git clone https://github.com/fjwood69/mori.git
cd mori
podman build -t localhost/mori-advisor:latest .
# Or: docker build -t mori-advisor:latest .
Licença
AGPL-3.0 — veja LICENSE. Licenças comerciais disponíveis — veja COMMERCIAL.md. Contribuições exigem um CLA único — veja CONTRIBUTING.md.