ShadowGraph
Prévia técnica: memória de decisão local-first para agentes de IA que armazena escolhas, motivos de rejeição, tentativas falhas e condições de revisão em um arquivo local para revisão invocada pelo chamador.
Documentação
ShadowGraph
Memória de decisões local-first para agentes de IA. O ShadowGraph lembra o que um agente decidiu, o que rejeitou, por que rejeitou e quando essa decisão deve ser reconsiderada.
Status: Prévia Técnica / Acesso Antecipado. Instale pelo GitHub — não está no npm. Veja Limitações e status da Prévia Técnica.
Por que isso importa
A memória de chat lembra da conversa. Ela perde a decisão.
Pergunte a um agente três meses depois por que o projeto usa SQLite e a parte útil já se foi:
- A escolha pode sobreviver em um resumo. A alternativa rejeitada e o motivo da rejeição não sobrevivem.
- Um fato muda — a implantação passa de usuário único para multiusuário — e nada reabre a decisão.
- A mesma abordagem falha de novo, porque a tentativa fracassada nunca foi registrada como uma tentativa fracassada.
O ShadowGraph armazena esse raciocínio como dados estruturados e inspecionáveis, em vez de prosa: o que foi escolhido, o que foi rejeitado, o porquê, as premissas e evidências por trás disso, tentativas fracassadas, resultados, procedência, histórico de confiança e as condições que devem acionar uma reconsideração.
A promessa é deliberadamente restrita: decisões importantes de IA devem sobreviver às sessões e permanecer explicáveis, revisáveis e reconsideráveis.
Para quem é: desenvolvedores que criam agentes com MCP, CLI ou uma API HTTP local e precisam que decisões consequentes sobrevivam à sessão. É um armazenamento de decisões, não um armazenamento de transcrições, e mantém tudo na sua máquina.
Início Rápido — 5 minutos
Requisitos
- Node.js 20+ (o backend SQLite opcional precisa de Node 22.5+ para
node:sqlite) - Sem dependências npm em tempo de execução, sem etapa de build, sem conta, sem chamadas de rede
1. Instalação
O ShadowGraph não é publicado no npm. Durante a Prévia Técnica, instale-o a partir deste
repositório. Uma instalação global coloca shadowgraph no seu PATH, que é o que os clientes MCP precisam:
npm install --global github:LiLara-AI/shadowgraph
Ou clone e execute a partir do código-fonte
git clone https://github.com/LiLara-AI/shadowgraph.git
cd shadowgraph
npm install
node src/cli.js setup
node src/cli.js doctor
Substitua shadowgraph por node src/cli.js em todos os comandos abaixo.
npm install shadowgraph-unified-pluginnão funciona e falha comE404. O pacote éprivate: truee não publicado, e o nome no registro não está reservado. Este README mudará se a publicação for aprovada algum dia.
2. Argumentos JSON e seu shell
Todo comando do ShadowGraph recebe um único argumento JSON, então as aspas dependem do seu shell. Escolha a linha do shell que você está realmente usando — este é o motivo mais comum de um primeiro comando falhar:
| Shell | Forma | Exemplo |
|---|---|---|
| bash / zsh / Git Bash (macOS, Linux, WSL) | aspas simples, JSON puro | shadowgraph recall '{"project":"demo"}' |
| Windows PowerShell | aspas simples, \" dentro | shadowgraph recall '{\"project\":\"demo\"}' |
Windows cmd.exe | aspas duplas, \" dentro | shadowgraph recall "{\"project\":\"demo\"}" |
Os exemplos abaixo usam a forma do bash. As três são testadas em todos os comandos deste README.
3. Inicialize um armazenamento
mkdir shadowgraph-demo
cd shadowgraph-demo
shadowgraph setup
shadowgraph doctor
setup cria .shadowgraph/data.json no diretório atual, então execute-o onde você quiser que o
armazenamento fique. Ele nunca reescreve um armazenamento existente. doctor então verifica a compatibilidade do Node, a legibilidade e
gravação do armazenamento, a validade do grafo e o ponto de entrada do MCP.
Execute setup antes de doctor: em um diretório novo, doctor reporta Storage is not initialized
e sai com 1 até que um armazenamento exista. Isso é esperado, não uma instalação falha.
4. Registre uma decisão, reinicie e recupere-a
shadowgraph decision '{"project":"checkout-service","title":"Choose the datastore","chosen":"SQLite","confidence":0.8,"alternatives":[{"label":"PostgreSQL","reasonRejected":"Single-user local deployment does not justify running a server","reopenWhen":[{"key":"deployment","operator":"equals","value":"multi-user"}]}]}'
shadowgraph fact '{"project":"checkout-service","key":"deployment","value":"single-user","sourceClass":"human_confirmed","confidence":1}'
shadowgraph search '{"query":"datastore","project":"checkout-service"}'
Cada comando é executado em um novo processo e reabre o armazenamento do disco, então o resultado de search volta
através de uma reinicialização real, não de estado em memória. Agora você tem uma decisão que carrega sua
alternativa rejeitada, o motivo da rejeição e a condição que deve reabri-la.
A demonstração: uma decisão que se reabre
Este é o ponto central do ShadowGraph, em três comandos. Continue no mesmo diretório.
A decisão está resolvida, então ainda não há nada para reconsiderar:
shadowgraph review '{"project":"checkout-service"}'
[]
Agora o mundo muda. A implantação se torna multiusuário:
shadowgraph fact '{"project":"checkout-service","key":"deployment","value":"multi-user","sourceClass":"human_confirmed","confidence":1}'
Reinicie e pergunte novamente — passando apenas o projeto, nunca o fato que acionou:
shadowgraph review '{"project":"checkout-service"}'
[
{
"decisionId": "decision_1788079304730_yjawcg",
"title": "Choose the datastore",
"reason": "deployment",
"alternativesToReconsider": [
"PostgreSQL"
]
}
]
O ShadowGraph leu o fato armazenado, comparou-o com a regra salva junto com a decisão e trouxe à tona a alternativa que havia sido rejeitada por um motivo que não vale mais. Seus IDs de decisão serão diferentes; nada mais muda.
Isso é memória de decisão: não "sobre o que conversamos", mas "o que decidimos, o que descartamos e isso ainda se sustenta?"
Para a mesma história via MCP, API HTTP e API JavaScript — além de registrar tentativas fracassadas e resultados — veja a demonstração de memória de decisão.
Capacidades principais
Memória de decisão. Decisões carregam a abordagem escolhida, alternativas rejeitadas com seus motivos,
premissas, evidências e regras estruturadas de reopenWhen. Resultados (bem-sucedidos, mistos, fracassados,
desconhecidos) alimentam a confiança.
Reconsideração. review() avalia regras de reabertura contra fatos armazenados, então funciona após uma
reinicialização sem que o chamador reenvie o que mudou. Sinais de revisão são persistidos e podem ser
reconhecidos.
Memória de tentativas fracassadas. Tentativas registram a abordagem, o resultado, o ambiente e a lição, para que um agente possa descobrir que algo já foi tentado e por que não funcionou.
Procedência auditável. Cada afirmação carrega um sourceClass — agent_claimed,
tool_observed, human_confirmed ou production_verified — que registra o que foi afirmado
sobre a origem de uma observação, nunca prova disso. Entrada comum de ferramenta não pode criar verified; isso
exige um verificador Ed25519 configurado separadamente.
Memória com escopo e recordação temporal. remember() / recall() armazenam preferências, perfis, metas,
instruções, procedimentos, episódios e notas sob um projeto, mais userId / agentId /
runId opcionais. Fatos, memórias e relações são bitemporais, então você pode perguntar o que era verdade asOf em um momento
passado. A recuperação combina sinais lexicais, vetoriais, de distância no grafo e temporais, e declara quais
sinais estavam indisponíveis em vez de degradar silenciosamente.
Isolamento de projeto e escopo. Projeto e escopo omitidos significam o projeto default e escopo todo-nulo —
nunca todos os projetos ou todos os usuários. A limpeza é pré-visualizável, lógica por padrão e explicitamente
irreversível no modo rígido.
Recuperação explicável. Resultados expõem pontuações brutas, classificações e motivos, e toda resposta limitada declara seu total, páginas e escopo omitido. Nada é resumido silenciosamente.
Local-first e privacidade
Tudo é um arquivo local. O servidor HTTP vincula-se a 127.0.0.1 e rejeita origens de navegador não locais.
Não há serviço em nuvem, conta, telemetria ou analytics — o ShadowGraph não faz
nenhuma requisição de rede de saída, a menos que você configure explicitamente uma.
As duas opções que podem enviar dados para fora da máquina estão ambas desativadas por padrão:
- Embeddings. Nenhum endpoint está configurado. Um servidor localhost compatível com OpenAI funciona uma vez
configurado; um endpoint remoto adicionalmente exige
SHADOWGRAPH_ALLOW_REMOTE_EMBEDDINGS=1, porque isso significa que memória e texto de consulta saem da sua máquina. - Exportação Markdown.
markdown-syncgrava cópias em texto puro que você controla. O ShadowGraph não consegue encontrar ou excluir essas cópias depois — veja Armazenamento, backup e exclusão.
Para uso local compartilhado, defina um token Bearer:
SHADOWGRAPH_API_TOKEN="use-a-random-token-at-least-16-characters" shadowgraph serve
Então envie Authorization: Bearer use-a-random-token-at-least-16-characters com cada requisição. Isso
é defesa em profundidade para uma implantação local, não um modelo de segurança para internet pública. Veja
SECURITY.md.
Interfaces
MCP
shadowgraph mcp
O modo compacto é recomendado: ele anuncia 12 ferramentas de fluxo de trabalho enquanto o grafo completo, memórias, fatos, alternativas e resultados permanecem armazenados com fidelidade total. O modo compacto é uma escolha de anúncio de ferramentas, não armazenamento com perdas.
SHADOWGRAPH_MCP_COMPACT=1 shadowgraph mcp
As 12 ferramentas compactas são shadowgraph_context, shadowgraph_remember, shadowgraph_recall,
shadowgraph_record_decision, shadowgraph_record_attempt, shadowgraph_record_fact,
shadowgraph_record_outcome, shadowgraph_retrieve, shadowgraph_search, shadowgraph_review,
shadowgraph_validate e shadowgraph_maintain. O modo completo anuncia 27 — veja o
guia de compatibilidade MCP para o inventário completo, ambas as revisões de
protocolo e o comportamento verificado do cliente.
Configuração de ferramentas de IA
Instale globalmente primeiro para que o cliente encontre shadowgraph no seu PATH:
npm install --global github:LiLara-AI/shadowgraph
shadowgraph setup
shadowgraph doctor
Claude Code (escopo do usuário):
claude mcp add --scope user --env SHADOWGRAPH_MCP_COMPACT=1 --transport stdio shadowgraph -- shadowgraph mcp
Cursor (.cursor/mcp.json ou ~/.cursor/mcp.json):
{"mcpServers":{"shadowgraph":{"type":"stdio","command":"shadowgraph","args":["mcp"],"env":{"SHADOWGRAPH_MCP_COMPACT":"1"}}}}
Codex:
codex mcp add shadowgraph --env SHADOWGRAPH_MCP_COMPACT=1 -- shadowgraph mcp
Hermes Agent:
hermes mcp add shadowgraph --command shadowgraph --connect-timeout 30 --env SHADOWGRAPH_MCP_COMPACT=1 --args mcp
Formas de arquivo verificadas para todos os quatro estão em integrations/. Defina um
SHADOWGRAPH_FILE absoluto no ambiente do cliente quando um armazenamento precisar ser compartilhado entre diretórios
de trabalho.
CLI
Os comandos que você realmente usará:
shadowgraph setup
shadowgraph doctor
shadowgraph context '{"project":"my-app"}'
shadowgraph decision '{"project":"my-app","title":"Choose the datastore","chosen":"SQLite"}'
shadowgraph fact '{"project":"my-app","key":"deployment","value":"local","sourceClass":"human_confirmed"}'
shadowgraph attempt '{"solution":"Rewrite everything","result":"Regression"}'
shadowgraph outcome '{"decisionId":"DECISION_ID","outcome":{"status":"failed","lessons":["Assumption was wrong"]}}'
shadowgraph review '{"project":"my-app"}'
shadowgraph search '{"query":"database","project":"my-app"}'
shadowgraph remember '{"project":"my-app","memoryType":"preference","key":"editor","text":"Prefers VS Code"}'
shadowgraph recall '{"project":"my-app","query":"development environment"}'
Lista completa de comandos
setup · doctor · serve · mcp · stats · list · search · retrieve · recall ·
remember · markdown-sync · context · review · maintain · signals · ack · validate ·
repair-plan · backup · restore · decision · attempt · fact · outcome · status ·
link · traverse · redact · supersede · purge-preview · purge · journal · rebuild ·
confidence-evidence
As formas completas dos argumentos estão na referência da API.
API HTTP
shadowgraph serve
curl http://127.0.0.1:8787/health
Um painel somente leitura é servido em http://127.0.0.1:8787/dashboard. Ele fala apenas com a mesma
origem local, e um token inserido lá é mantido apenas na memória da página — nunca em cookies, armazenamento
local ou dados do ShadowGraph.
Todos os endpoints HTTP
GET /health GET /stats GET /records
GET /search?q=&project= GET /review-signals GET /validate
GET /journal
POST /decisions POST /attempts POST /memories
POST /recall POST /facts POST /outcomes
POST /review POST /context POST /status
POST /relationships POST /traverse POST /redact
POST /supersede POST /maintain POST /retrieve
POST /review-signals/ack POST /repair-plan POST /backup
POST /restore POST /rebuild POST /confidence-evidence
POST /projects/purge-preview
DELETE /projects
/redact retorna uma exportação segura para privacidade e nunca muta. /repair-plan é sempre não destrutivo
e retorna {apply:false, actions:[...]}. /projects/purge-preview mostra contagens de exclusão sem
alterar o armazenamento. O servidor retorna 401 quando a autenticação por token está habilitada e ausente, 403 para
origens de navegador não permitidas, 404 para decisões ou rotas ausentes e 413 para corpos excessivamente grandes.
JavaScript
import { createShadowGraph } from 'shadowgraph-unified-plugin';
const graph = createShadowGraph();
graph.addDecision({
project: 'checkout-service',
title: 'Choose the datastore',
chosen: 'SQLite',
confidence: 0.8,
alternatives: [{
label: 'PostgreSQL',
reasonRejected: 'Single-user local deployment does not justify running a server',
reopenWhen: [{ key: 'deployment', operator: 'equals', value: 'multi-user' }]
}]
});
graph.addFact({
project: 'checkout-service',
key: 'deployment',
value: 'multi-user',
sourceClass: 'human_confirmed',
confidence: 1
});
// review() reads stored facts, so this also works in a fresh process after an
// export/save and load. Do not pass the triggering fact again.
console.log(graph.review({ project: 'checkout-service' }));
A importação com especificador simples resolve quando o ShadowGraph é uma dependência do seu projeto
(npm install github:LiLara-AI/shadowgraph). Com uma instalação --global, use as superfícies CLI, HTTP ou MCP
em vez disso, ou importe do caminho instalado.
Armazenamento, backup e exclusão
JSON é o padrão sem dependências e armazena um grafo versionado em .shadowgraph/data.json. Defina
SHADOWGRAPH_FILE para realocá-lo. Defina SHADOWGRAPH_STORAGE=sqlite no Node 22.5+ para o adaptador
relacional com WAL. Exportações atuais usam o esquema 5; esquemas 1 a 4 permanecem importáveis.
Estado e diário são gravados em uma única operação atômica, todo salvamento e restauração para um destino
compartilha uma cerca de bloqueio entre processos, e uma gravação obsoleta é rejeitada com um conflito de revisão em vez
de ser perdida silenciosamente. backup tira um instantâneo consistente; restore valida a consistência do domínio e do diário
antes de substituir o estado ativo e reverte em caso de falha. Isso é segurança de reversão em nível de processo,
não uma afirmação de durabilidade contra falhas ou perda de energia. As garantias completas — tempos limite de bloqueio,
recuperação de bloqueio obsoleto, aritmética de revisão e relatórios de artefatos de restauração — estão na
referência da API e no
contrato de restauração SQLite.
A exclusão é explícita e pré-visualizável:
shadowgraph purge-preview '{"project":"release-demo"}'
shadowgraph purge '{"project":"release-demo"}'
shadowgraph purge '{"project":"another-project","mode":"hard"}'
Purga lógica (o padrão) remove o conteúdo do projeto da projeção ativa e mantém um esqueleto de purga auditável e sem payload. A purga física exclui fisicamente entradas do diário, cria uma lacuna declarada e não pode ser desfeita.
A purga não pode excluir exportações Markdown externas. O ShadowGraph não tem como encontrar cópias em texto simples em workspaces arbitrários, histórico do Git, sincronização em nuvem, backups ou mídias removíveis. Exclua essas cópias separadamente.
Limitações e status de Technical Preview
O ShadowGraph 0.40.0 é um lançamento de Technical Preview / Early Access. Não é Beta e não é estável.
- As interfaces e o esquema de armazenamento podem mudar. Não use para dados que você não possa reproduzir.
- Não está no npm. O pacote é deliberadamente
private: true. Nenhuma publicação no npm, tag Git ou release no GitHub foi criada, e nenhuma é autorizada. - Nenhum benchmark comparativo foi medido. A infraestrutura de benchmark comparativo foi executada, mas nenhum braço foi medido porque não havia endpoint comum de LLM e embedding local/gratuito disponível. Nenhuma alegação comparativa de desempenho, qualidade, tokens, custo ou "melhor" é suportada. O ShadowGraph não afirma ser mais rápido, mais barato, com menos tokens, mais preciso ou melhor do que qualquer outro sistema de memória. Veja o relatório de benchmark.
- Status de revisão de segurança. Uma revisão de segurança independente assistida por IA do commit
4a5e076(árvore62c1918e) foi concluída em 30/08/2026 pelo Antigravity Assistant (Gemini 3.7 Flash), com resultado APROVADO e nenhuma pendência não resolvida. Nenhuma auditoria de segurança humana de terceiros foi realizada. Veja SECURITY.md. - Sem extrator padrão, observador em segundo plano ou sincronização hospedada. O ShadowGraph registra o que você diz para ele registrar.
- Mantenedor único. Sem suporte pago, sem SLA de correção e sem programa de recompensas por bugs.
Feedback e suporte
O feedback do Technical Preview é o objetivo deste lançamento. Por favor, nos avise quando algo quebrar.
| O quê | Onde |
|---|---|
| Bug ou comportamento incorreto | Abrir um relatório de bug |
| Solicitação de recurso ou capacidade | Abrir uma solicitação de recurso |
| Vulnerabilidade de segurança | Reportar em privado — nunca em uma issue pública |
| Perguntas, ideias, "isso é útil?" | Discussões |
Durante a prévia, estes relatórios são os mais valiosos:
- Problemas de instalação — qualquer coisa entre
npm install --globale umdoctorverde. - Compatibilidade com clientes MCP — qual cliente, qual modo e o que ele descobriu ou não.
- Utilidade da memória — o contexto recuperado realmente mudou o que seu agente fez?
- Fluxos de trabalho confusos — onde a documentação ou um formato de comando te direcionou para o caminho errado.
- Casos de uso ausentes de memória de decisão — decisões que você queria armazenar e não conseguiu.
- Desempenho — onde parecia lento e aproximadamente qual era o tamanho do armazenamento.
O ShadowGraph não tem telemetria e não coleta nada automaticamente, então um relatório seu é o único sinal que existe. Ao colar saídas, remova qualquer coisa privada: o conteúdo de decisões e memórias são seus dados, e a saída de shadowgraph doctor geralmente é suficiente.
Documentação
| Documento | O que cobre |
|---|---|
| Demonstração de memória de decisão | O exemplo completo trabalhado via CLI, MCP, HTTP e JavaScript |
| Referência da API | Superfícies JavaScript, CLI, HTTP e MCP |
| Guia de memória unificada | remember / recall, escopo, recuperação temporal, sincronização Markdown |
| Compatibilidade MCP | Revisões de protocolo, inventário de ferramentas, comportamento verificado de clientes |
| Contratos | Garantias autoritativas: proveniência, ciclo de vida, diário, completude, busca, confiança, restauração SQLite |
| Decisões de arquitetura | ADR-0006 (kernel de memória), ADR-0007 (posicionamento da linha de base do diário) |
| Visão e princípios | Para que serve o ShadowGraph e o que ele deliberadamente não fará |
| Relatório de benchmark | Resultados honestos — nenhum braço foi medido; nenhuma alegação comparativa é suportada |
| Política de segurança | Modelo de ameaças, status de revisão e como reportar uma vulnerabilidade em privado |
| Contribuindo | Configuração de desenvolvimento e expectativas para pull requests |
| Changelog | Histórico de lançamentos |
Verificações
npm run check
npm test
npm run check:integrations
npm run check:mcp
npm audit --omit=dev
npm run check:package
npm run smoke:package
O GitHub Actions cobre Ubuntu e Windows no Node 20, 22 e 24. As portas SQLite são executadas apenas onde node:sqlite existe. O inspetor MCP oficial estrito executa portas completas e compactas, e o teste de fumaça do pacote é executado a partir de uma instalação limpa real em cada célula da matriz.
Licença
MIT. Veja LICENSE.