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

CI

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-plugin não funciona e falha com E404. O pacote é private: true e 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:

ShellFormaExemplo
bash / zsh / Git Bash (macOS, Linux, WSL)aspas simples, JSON puroshadowgraph recall '{"project":"demo"}'
Windows PowerShellaspas simples, \" dentroshadowgraph recall '{\"project\":\"demo\"}'
Windows cmd.exeaspas duplas, \" dentroshadowgraph 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 sourceClassagent_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-sync grava 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 (árvore 62c1918e) 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 incorretoAbrir um relatório de bug
Solicitação de recurso ou capacidadeAbrir uma solicitação de recurso
Vulnerabilidade de segurançaReportar 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 --global e um doctor verde.
  • 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

DocumentoO que cobre
Demonstração de memória de decisãoO exemplo completo trabalhado via CLI, MCP, HTTP e JavaScript
Referência da APISuperfícies JavaScript, CLI, HTTP e MCP
Guia de memória unificadaremember / recall, escopo, recuperação temporal, sincronização Markdown
Compatibilidade MCPRevisões de protocolo, inventário de ferramentas, comportamento verificado de clientes
ContratosGarantias autoritativas: proveniência, ciclo de vida, diário, completude, busca, confiança, restauração SQLite
Decisões de arquiteturaADR-0006 (kernel de memória), ADR-0007 (posicionamento da linha de base do diário)
Visão e princípiosPara que serve o ShadowGraph e o que ele deliberadamente não fará
Relatório de benchmarkResultados honestos — nenhum braço foi medido; nenhuma alegação comparativa é suportada
Política de segurançaModelo de ameaças, status de revisão e como reportar uma vulnerabilidade em privado
ContribuindoConfiguração de desenvolvimento e expectativas para pull requests
ChangelogHistó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.