---
name: sqlite-graphrag
description: Esta skill DEVE ativar para toda operação da CLI sqlite-graphrag cobrindo memória persistente, grafo de conhecimento GraphRAG, ligação de entidades, hybrid-search, recall, deep-research, remember, remember-batch, ingest, edit, restore, enrich, forget, purge, link, rename-entity e manutenção de grafo. Esta skill ensina a LLM a embedar via backend REST do OpenRouter com seleção explícita de modelo e preço, a rodar extração de entidades e enrichment como etapa SEPARADA através dos backends headless codex, claude-code ou opencode com escolha explícita de modelo, a adicionar e verificar chaves de API OpenRouter, a honrar regras OAuth-only de subprocesso, isolamento preflight, fusão FTS5 mais cosine BLOB, relações canônicas, estratégia de retry por exit-code e isolamento de namespace. Esta skill ativa nas palavras-chave sqlite-graphrag GraphRAG memory embedding openrouter codex claude opencode remember recall hybrid-search ingest enrich deep-research forget purge link rename-entity
---
## Quando Esta Skill Ativa
- ATIVE quando o usuário pede para lembrar, salvar, recordar, recuperar, buscar ou persistir algo entre sessões
- ATIVE para contexto de longo prazo, grafo de conhecimento, GraphRAG, RAG, ligação de entidades, gestão de memória
- ATIVE quando sqlite-graphrag, embedding, FTS5, hybrid-search, OpenRouter ou memória LLM for mencionado
- NUNCA ATIVE para dados efêmeros pontuais, I/O simples de arquivo ou tarefas sem relação a contexto persistente
## Modelo Mental Central — Três Backends Independentes
- SAIBA que a CLI tem TRÊS seletores separados; NUNCA os confunda
- USE `--embedding-backend` para escolher COMO os vetores são produzidos: `openrouter` (REST, rápido) ou `llm` (subprocesso) ou `auto`
- USE `--llm-backend` para escolher QUAL subprocesso roda o embedding LLM quando `--embedding-backend llm`: `codex`, `claude`, `opencode`, `none`
- USE `--extraction-backend` (e `enrich --mode`) para escolher QUAL CLI headless extrai entidades e relações: `codex`, `claude-code`, `opencode`
- SEPARE escrita de enrichment SEMPRE: uma escrita produz embeddings; uma invocação SEPARADA de `enrich` extrai o grafo
- PASSE `--llm-backend none` em TODA escrita (`remember`, `remember-batch`, `ingest`, `edit`, `restore`) para PULAR o embedding inline de entidades e evitar o timeout do subprocesso codex
- RODE `enrich` somente DEPOIS que a escrita retornar exit 0, como comando DISTINTO, NUNCA encadeado na escrita
- PARSEIE `backend_invoked` em todo envelope de embedding para CONFIRMAR qual backend realmente rodou
## Regras de Instrução para LLMs
- QUANDO o usuário diz "lembre disso" → EXECUTE `remember --force-merge` com `--graph-stdin` carregando entidades curadas e relações canônicas, depois um `enrich` SEPARADO
- QUANDO o usuário pergunta "o que você sabe sobre X" → EXECUTE `hybrid-search "X" --k 10 --json` PRIMEIRO, depois EXPANDA os top resultados com `read --name <name> --json`
- QUANDO o usuário pergunta "como X se relaciona com Y" → EXECUTE `graph traverse --from X --depth 2 --json` ou `related X --hops 2 --json`
- QUANDO o usuário pede "pesquise profundamente sobre X" → EXECUTE `deep-research "X" --k 20 --max-hops 3 --json`
- ANTES de criar QUALQUER memória → EXECUTE `hybrid-search "<name>" --k 5 --json` para VERIFICAR duplicatas; se encontrar USE `--force-merge`
- APÓS criar ou atualizar memória → VERIFIQUE com `read --name <name> --json | jaq '{name, description, body_length}'`
- APÓS CADA turno com achados novos → AVALIE se deve persistir; se nada novo DECLARE "Nenhum achado novo para persistir"
- QUANDO o exit code for não-zero → LEIA o envelope de erro JSON do stdout via `jaq '{code, message, error_class}'`, REPORTE a remediação
- SEMPRE parseie a saída JSON com `jaq` (NUNCA `jq`)
- SEMPRE passe `--json` em toda invocação de `sqlite-graphrag`
- SEMPRE capture o stdout em uma variável PRIMEIRO, depois parseie; NUNCA pipe `sqlite-graphrag ... | jaq` direto porque NDJSON multilinha mascara falhas como nulls silenciosos
- SEMPRE use APENAS relações canônicas: `applies-to`, `uses`, `depends-on`, `causes`, `fixes`, `contradicts`, `supports`, `follows`, `related`, `mentions`, `replaces`, `tracked-in`
- SEMPRE mapeie relações não-canônicas ANTES de persistir: `adds|creates → causes`, `implements → supports`, `blocks → contradicts`, `tested-by → related`, `part-of → applies-to`
- SEMPRE normalize nomes de entidade para kebab-case ASCII lowercase ANTES de passar à CLI
- NUNCA use MCP Serena ou arquivos `.md` de memória para persistência; NUNCA escreva MEMORY.md
- NUNCA inicie ou referencie um daemon; NUNCA passe `ANTHROPIC_API_KEY` ou `OPENAI_API_KEY` aos backends de subprocesso
- PREFIRA `remember --force-merge` sobre `edit` para updates; PREFIRA `--graph-stdin` sobre extração inline de entidades
- LIMITE entidades a conceitos de domínio; REJEITE palavras genéricas, pronomes, UUIDs, timestamps
## Arquitetura e Princípios
- INVOQUE sempre como subprocesso; LEIA stdout para JSON/NDJSON; LEIA stderr para logs; CHEQUE o exit code ANTES de parsear
- SAIBA que o binário NÃO tem daemon, NÃO tem ONNX runtime, NÃO tem cache de modelo
- SAIBA que a similaridade cosine é pure Rust sobre `memory_embeddings`, `entity_embeddings`, `chunk_embeddings` backed por BLOB
- SAIBA que o schema é v15 após `init` ou `migrate` em banco fresco
- ENFORCE OAUTH-ONLY para os backends de subprocesso codex e claude: o spawn ABORTA exit 1 se `ANTHROPIC_API_KEY` ou `OPENAI_API_KEY` estiver definida
- SAIBA que `ANTHROPIC_AUTH_TOKEN`, `ANTHROPIC_BASE_URL`, `OPENAI_BASE_URL` são PRESERVADAS para providers customizados
- SAIBA que o CWD do subprocesso é ISOLADO; diretórios órfãos são limpos automaticamente
- SAIBA que 7 guards preflight rodam ANTES de cada fork de subprocesso LLM; exit 16 é a falha preflight universal
- SAIBA que o subprocesso de extração headless herda o diretório de trabalho atual e qualquer `.mcp.json` presente, o que pode quebrar `claude -p`; ISOLE com um diretório de config vazio ao extrair via claude-code
- DEFINA `SQLITE_GRAPHRAG_SKIP_PREFLIGHT=1` APENAS em emergências
- ISOLE NAMESPACE por projeto via `--namespace <ns>` ou env; padrão é `global`
- NUNCA exponha o binário como servidor MCP ou serviço HTTP
- NUNCA escreva o arquivo `.sqlite` em paralelo a partir de outra ferramenta
## Modelos de Embedding OpenRouter e Preços
- PASSE `--embedding-model <MODEL>` quando `--embedding-backend openrouter`; NÃO existe modelo padrão, então a omissão dispara exit 78
- SAIBA que os preços abaixo são por um milhão de tokens; ESCOLHA o modelo por custo e qualidade para a tarefa
- USE `nvidia/llama-nemotron-embed-vl-1b-v2:free` para embedding GRATUITO de custo zero (padrão RECOMENDADO)
- USE `perplexity/pplx-embed-v1-0.6b` para a opção paga MAIS BARATA em cerca de 0.004 USD
- USE `qwen/qwen3-embedding-8b` em cerca de 0.01 USD
- USE `baai/bge-m3` em cerca de 0.01 USD
- USE `qwen/qwen3-embedding-4b` em cerca de 0.02 USD
- USE `openai/text-embedding-3-small` em cerca de 0.02 USD
- USE `mistralai/mistral-embed-2312` em cerca de 0.10 USD
- USE `google/gemini-embedding-2` em cerca de 0.12 USD
- USE `openai/text-embedding-3-large` em cerca de 0.13 USD
- USE `google/gemini-embedding-001` em cerca de 0.15 USD
- MANTENHA `--embedding-dim 384` consistente entre escritas e leituras; uma dimensão divergente colide com o índice armazenado e falha o knn com exit 11
- SAIBA que o truncamento MRL é aplicado server-side ao `--embedding-dim` requisitado, então uma dimensão maior continua barata no path REST do OpenRouter
- VERIFIQUE a whitelist de modelos de embedding com `sqlite-graphrag codex-models --json`
- SAIBA que `--embedding-backend openrouter` se propaga a TODOS os paths de embedding: `remember`, `remember-batch`, `ingest`, `recall`, `edit`, `restore`, `hybrid-search`, `deep-research`, `enrich`, `init`, `rename-entity`
## Gestão de Chave de API OpenRouter
- ADICIONE uma chave via stdin: `echo "sk-or-v1-..." | sqlite-graphrag config add-key --provider openrouter --from-stdin`
- LISTE chaves armazenadas: `sqlite-graphrag config list-keys --json`
- REMOVA uma chave por fingerprint: `sqlite-graphrag config remove-key <fingerprint> --json`
- RODE o doctor de diagnóstico: `sqlite-graphrag config doctor --json`
- INSPECIONE o caminho da config: `sqlite-graphrag config path`
- SAIBA que as chaves vivem na config XDG `~/.config/sqlite-graphrag/config.toml` com `chmod 600` e são zeroizadas no drop, JAMAIS logadas
- SAIBA a precedência: variável de ambiente `OPENROUTER_API_KEY` > config.toml > flag CLI `--openrouter-api-key`
- NUNCA passe a chave de API como argumento CLI em produção; PREFIRA stdin ou variável de ambiente para evitar exposição no histórico do shell
## Backends LLM Headless — Codex, Claude, OpenCode
- ESCOLHA codex com `--llm-backend codex --llm-model gpt-5.4-mini` para embedding e `--mode codex --codex-model gpt-5.4-mini` para extração; refresque OAuth com `codex login`
- ESCOLHA claude com `--llm-backend claude --llm-model claude-sonnet-4-6` para embedding e `--mode claude-code --claude-model claude-sonnet-4-6` para extração via o path OAuth zero-token
- ESCOLHA opencode com `--llm-backend opencode --llm-model opencode/big-pickle` para embedding e `--mode opencode --opencode-model opencode/big-pickle` para extração via seu próprio auth (NÃO OAuth)
- SAIBA os modelos DEFAULT: codex `gpt-5.5`, claude `claude-sonnet-4-6`, opencode `opencode/big-pickle`
- SAIBA os modelos opencode gratuitos: `opencode/big-pickle`, `opencode/deepseek-v4-flash-free`, `opencode/mimo-v2.5-free`, `opencode/nemotron-3-ultra-free`, `opencode/north-mini-code-free`
- SOBRESCREVA os paths dos binários com `--codex-binary`, `--claude-binary`, `--opencode-binary` quando a CLI não estiver no PATH
- AJUSTE os timeouts por backend no `ingest` com `--codex-timeout`, `--claude-timeout`, `--opencode-timeout` (segundos)
- VALIDE modelos codex com `--codex-model-validate` e auto-substitua com `--codex-model-fallback <MODEL>`
- TROQUE de backend mid-job em rate limit com `--fallback-mode codex` no `enrich`, ou `--llm-fallback codex,claude,none` globalmente
- AVISE que a extração `claude-code` spawna `claude -p`, que herda o `.mcp.json` do CWD e pode falhar; PREFIRA extração codex ou isole o diretório de config
## Referência de Flags Globais
- `--db <PATH>` — sobrescrever localização do banco (aceito por subcomando)
- `--namespace <ns>` — escopar operações para um namespace
- `--json` — saída JSON estruturada (SEMPRE passe)
- `--lang en|pt` — forçar idioma do stderr
- `--tz <TIMEZONE>` — localizar timestamps
- `--embedding-backend auto|openrouter|llm` — seletor de produção de vetor
- `--embedding-model <MODEL>` — modelo de embedding OpenRouter
- `--embedding-dim N` — dimensionalidade de embedding [8, 4096], padrão 384 MRL
- `--openrouter-api-key <KEY>` — chave de API OpenRouter
- `--llm-backend codex|claude|opencode|none|auto` — backend de embedding de subprocesso, cadeia separada por vírgula permitida
- `--llm-model <MODEL>` — modelo para o backend LLM ativo
- `--llm-fallback <chain>` — cadeia de fallback separada por vírgula quando o primário falha
- `--extraction-backend codex|claude-code|opencode` — seletor de subprocesso de extração de entidades
- `--llm-parallelism N` — fan-out de subprocessos de embedding, padrão 4, clamp [1, 32]
- `--max-concurrency N` — cap de invocações pesadas concorrentes, clamp [1, 2×nCPUs]
- `--llm-max-host-concurrency N` — cap de slots de subprocesso LLM em todo o host
- `--llm-slot-wait-secs N` — esperar por um slot livre antes de abortar; `--llm-slot-no-wait` para falhar rápido
- `--wait-lock SECS` — ampliar a janela de aquisição de lock
- `--low-memory` — paralelismo unitário para containers restritos
- `--strict-env-clear` — preservar apenas PATH no subprocesso para compliance
- `--graceful-shutdown-secs N` — orçamento de cleanup antes do SIGKILL
- `--skip-embedding-on-failure` — armazenar sem vetor quando a cadeia termina em `none`
- `--codex-binary`, `--claude-binary`, `--opencode-binary` — sobrescrever paths dos binários
- `-v`/`-vv`/`-vvv` — logging info/debug/trace no stderr
## Operações CRUD de Escrita
- INVOQUE `remember --name <kebab> --type <kind> --description <text>` com `--body <text>` ou `--body-file <path>` ou `--body-stdin` ou `--graph-stdin`
- INVOQUE `remember --graph-stdin` para anexar `{body, entities, relationships}` em um único documento JSON
- PASSE entities como `[{name, entity_type}]` em kebab-case ASCII; PASSE relationships como `[{source, target, relation, strength}]` onde strength está em [0.0, 1.0]
- PASSE `--force-merge` para updates idempotentes e restauração de soft-deleted
- PASSE `--dry-run` para validar inputs sem persistir
- VALORES válidos de `--type`: `user`, `feedback`, `project`, `reference`, `decision`, `incident`, `skill`, `document`, `note`
- INVOQUE `remember-batch` para 10 ou mais memórias via NDJSON stdin; PASSE `--transaction` para all-or-nothing
- INVOQUE `ingest <DIR> --recursive --pattern "*.md" --mode none` para importar um diretório como body-only, depois enriqueça SEPARADAMENTE
- SAIBA que `ingest --mode` aceita `none` (padrão body-only), `claude-code`, `codex`; opencode NÃO é um modo de ingest, então enriqueça com opencode em uma etapa SEPARADA
- USE `--resume` para continuar da fila após interrupção; `--retry-failed` apenas para itens falhados; `--auto-describe` para sintetizar descrições
- RESPEITE o limite de 512000 bytes e 512 chunks por corpo
- NUNCA misture `--body`, `--body-file`, `--body-stdin`, `--graph-stdin` em única invocação
- NUNCA use `fd | xargs remember`; INVOQUE `ingest` em vez disso
- NUNCA passe `--llm-backend codex` em qualquer escrita; o path de entidades forçaria o subprocesso codex e travaria no timeout dele; SEMPRE passe `--llm-backend none`
## CRUD Leitura Atualização Deleção
- INVOQUE `read --name <kebab> --json` para fetch O(1); PASSE `--with-graph` para incluir entidades vinculadas
- INVOQUE `list --type <kind> --limit N --offset N --json` para filtrar e paginar
- INVOQUE `history --name <n> --diff --json` para histórico de versões com estatísticas de diff de caracteres
- INVOQUE `edit --name <n> --body-file <path>` para atualizar o corpo, ou `--description <text>` e `--memory-type <kind>` para metadados
- USE `--force-reembed` para regenerar o embedding sem mudar o corpo
- USE `--expected-updated-at <ts>` para locking otimista; TRATE exit 3 como conflito, recarregue e retente
- INVOQUE `rename --name <old> --new-name <new>` para renomear uma memória preservando histórico
- INVOQUE `restore --name <n> --version <N>` para restaurar uma versão antiga
- INVOQUE `forget --name <n>` para um soft-delete reversível
- INVOQUE `purge --retention-days <N> --yes --dry-run` para preview, depois remova `--dry-run` para o hard delete
- INVOQUE `cleanup-orphans --yes` após bulk forget, depois `vacuum --json`
- NUNCA pule locking otimista em pipelines concorrentes; NUNCA delete manualmente via shell `sqlite3`
## Operações de Grafo de Entidades
- INVOQUE `link --from <a> --to <b> --relation <type> --create-missing --weight <float>` para criar uma aresta
- INVOQUE `unlink --from <a> --to <b> --relation <type>` para remover uma aresta, ou `--entity <name> --all` para dropar todas as arestas de uma entidade
- INVOQUE `graph entities --json` para listar entidades via `.entities[]` (NÃO `.items[]`); ORDENE com `--sort-by degree|name|created_at`; PAGINE com `--limit N --offset N`
- INVOQUE `graph stats --json` para inspecionar `node_count`, `edge_count`, `avg_degree`, `max_degree`
- INVOQUE `graph traverse --from <root> --depth <N> --json` para travessia de subgrafo; EXPORTE com `--format json|dot|mermaid --output <path>`
- INVOQUE `rename-entity --name <old> --new-name <new>` para renomear uma entidade preservando arestas
- INVOQUE `delete-entity --name <n> --cascade` para deletar uma entidade e suas arestas
- INVOQUE `merge-entities --names "a,b,c" --into <target>` para mesclar duplicatas
- INVOQUE `reclassify --name <n> --new-type <kind>` para uma entidade, ou `--from-type <old> --to-type <new> --batch` para migração de tipo em massa
- INVOQUE `reclassify-relation --from-relation <old> --to-relation <new> --batch` para migração de tipo de relação em massa; FILTRE com `--filter-source-type` e `--filter-target-type`
- INVOQUE `prune-relations --relation mentions --dry-run` para preview de arestas de baixo valor, depois remova `--dry-run` com `--yes`
- INVOQUE `normalize-entities --yes` para normalizar todos os nomes para kebab-case ASCII
- INVOQUE `prune-ner --entity <n>` para remover bindings NER; `prune-ner --all --yes` para todo o namespace
- INVOQUE `memory-entities --name <memory>` para lookup forward, ou `--entity <name>` para lookup reverso
- PASSE `--max-entity-degree N` no `link` para avisar quando uma entidade exceder N conexões
- TIPOS canônicos de entidade: `project`, `tool`, `person`, `file`, `concept`, `incident`, `decision`, `memory`, `dashboard`, `issue_tracker`, `organization`, `location`, `date`
- VALIDE nomes de entidade: mínimo 2 chars, sem newlines, sem ALL_CAPS curto de 4 chars ou menos
- NUNCA use `mentions` como relação padrão
## Operações de Busca GraphRAG
- USE o padrão canônico de três camadas: `hybrid-search` depois `read --name` depois `related|graph traverse`
- INVOQUE `recall <query> --k N` para KNN semântico puro; PASSE `--no-graph` para desabilitar expansão de grafo, `--precise` para scoring exato, `--max-distance <f>`, `--max-graph-results N`, `--all-namespaces`
- INVOQUE `hybrid-search <query> --k N` para fusão FTS5 mais KNN via RRF
- PASSE `--rrf-k 60` para fusão padrão; `--weight-vec 1.0 --weight-fts 1.0` para fusão balanceada
- PASSE `--fallback-fts-only` para pular embedding ao vivo e servir apenas FTS5 BM25 em modo offline
- USE `--with-graph --max-hops 2 --min-weight 0.3` para expansão de grafo; LEIA AMBOS `results[]` E `graph_matches[]`
- INVOQUE `related <name> --hops N --relation <type>` para travessia multi-hop a partir de uma memória
- INVOQUE `deep-research "<query>" --k 20 --max-hops 3 --max-sub-queries 7 --max-results 50 --with-bodies` para pesquisa paralela multi-hop
- AJUSTE deep-research com `--graph-decay <f>`, `--graph-min-score <f>`, `--max-neighbors-per-hop N`, `--max-cost-usd <f>`, `--timeout <secs>`
- PARSEIE `recall` retorna `results[].{name, snippet, distance, score, source}`
- PARSEIE `hybrid-search` retorna `results[].{name, combined_score, vec_rank, fts_rank}`
- PARSEIE `deep-research` retorna `sub_queries[]`, `results[]`, `evidence_chains[]`, `graph_context`, `stats`
- NUNCA confunda `distance` com `combined_score` em ranking; NUNCA aumente `--hops` sem inspecionar `graph stats` antes
## Operações de Enrich
- INVOQUE `enrich --operation <op> --mode <backend>` onde AMBAS as flags são OBRIGATÓRIAS; omitir `--mode` é rejeitado pelo parser com exit 2
- VALORES válidos de `--operation`: `memory-bindings`, `entity-descriptions`, `body-enrich`, `re-embed`
- VALORES válidos de `--mode`: `codex`, `claude-code`, `opencode`
- PASSE `--codex-model`, `--claude-model` ou `--opencode-model` para escolher o modelo de extração compatível com o modo escolhido
- PASSE `--limit N --resume` para `re-embed`; `--retry-failed` para reprocessar apenas itens falhados; `--dry-run` para preview
- PASSE `--min-output-chars N` para proteger o comprimento de saída do `body-enrich`; `--fallback-mode codex` para sobreviver a um rate limit do Claude
- NUNCA rode `enrich` em paralelo contra o mesmo banco; ele adquire um singleton por namespace
## Escrita e Depois Enrich — Duas Etapas Separadas
- TRATE toda escrita como ETAPA 1 (embedar via OpenRouter, `--llm-backend none`) seguida de uma ETAPA 2 DISTINTA (`enrich`); NUNCA as encadeie com `&&`
- ESCOLHA o modelo OpenRouter da tabela de preços; ESCOLHA o backend e modelo de enrich independentemente
- REMEMBER etapa 1: `echo '{"body":"text","entities":[{"name":"jwt","entity_type":"concept"}],"relationships":[{"source":"jwt","target":"auth-svc","relation":"uses","strength":0.8}]}' | sqlite-graphrag --embedding-backend openrouter --embedding-model nvidia/llama-nemotron-embed-vl-1b-v2:free --embedding-dim 384 --openrouter-api-key $OPENROUTER_API_KEY --llm-backend none remember --name <n> --type decision --description "desc" --graph-stdin --force-merge --json`
- REMEMBER etapa 2 codex: `sqlite-graphrag --llm-backend codex --llm-model gpt-5.4-mini enrich --operation memory-bindings --mode codex --codex-model gpt-5.4-mini --json`
- REMEMBER etapa 2 claude: `sqlite-graphrag --llm-backend claude --llm-model claude-sonnet-4-6 enrich --operation memory-bindings --mode claude-code --claude-model claude-sonnet-4-6 --json`
- REMEMBER etapa 2 opencode: `sqlite-graphrag --llm-backend opencode --llm-model opencode/big-pickle enrich --operation memory-bindings --mode opencode --opencode-model opencode/big-pickle --json`
- REMEMBER-BATCH etapa 1: `sqlite-graphrag --embedding-backend openrouter --embedding-model qwen/qwen3-embedding-8b --embedding-dim 384 --openrouter-api-key $OPENROUTER_API_KEY --llm-backend none remember-batch --transaction --json`
- REMEMBER-BATCH etapa 2 codex: `sqlite-graphrag --llm-backend codex --llm-model gpt-5.4-mini enrich --operation memory-bindings --mode codex --codex-model gpt-5.4-mini --json`
- REMEMBER-BATCH etapa 2 claude: `sqlite-graphrag --llm-backend claude --llm-model claude-sonnet-4-6 enrich --operation memory-bindings --mode claude-code --claude-model claude-sonnet-4-6 --json`
- REMEMBER-BATCH etapa 2 opencode: `sqlite-graphrag --llm-backend opencode --llm-model opencode/big-pickle enrich --operation memory-bindings --mode opencode --opencode-model opencode/big-pickle --json`
- INGEST etapa 1: `sqlite-graphrag --embedding-backend openrouter --embedding-model nvidia/llama-nemotron-embed-vl-1b-v2:free --embedding-dim 384 --openrouter-api-key $OPENROUTER_API_KEY --llm-backend none ingest ./docs --mode none --recursive --pattern "*.md" --type document --resume --json`
- INGEST etapa 2 codex: `sqlite-graphrag --llm-backend codex --llm-model gpt-5.4-mini enrich --operation memory-bindings --mode codex --codex-model gpt-5.4-mini --json`
- INGEST etapa 2 claude: `sqlite-graphrag --llm-backend claude --llm-model claude-sonnet-4-6 enrich --operation memory-bindings --mode claude-code --claude-model claude-sonnet-4-6 --json`
- INGEST etapa 2 opencode: `sqlite-graphrag --llm-backend opencode --llm-model opencode/big-pickle enrich --operation memory-bindings --mode opencode --opencode-model opencode/big-pickle --json`
- EDIT etapa 1: `sqlite-graphrag --embedding-backend openrouter --embedding-model perplexity/pplx-embed-v1-0.6b --embedding-dim 384 --openrouter-api-key $OPENROUTER_API_KEY --llm-backend none edit --name <n> --body-file new.md --json`
- EDIT etapa 2 codex: `sqlite-graphrag --llm-backend codex --llm-model gpt-5.4-mini enrich --operation memory-bindings --mode codex --codex-model gpt-5.4-mini --json`
- EDIT etapa 2 claude: `sqlite-graphrag --llm-backend claude --llm-model claude-sonnet-4-6 enrich --operation memory-bindings --mode claude-code --claude-model claude-sonnet-4-6 --json`
- EDIT etapa 2 opencode: `sqlite-graphrag --llm-backend opencode --llm-model opencode/big-pickle enrich --operation memory-bindings --mode opencode --opencode-model opencode/big-pickle --json`
- RESTORE etapa 1: `sqlite-graphrag --embedding-backend openrouter --embedding-model nvidia/llama-nemotron-embed-vl-1b-v2:free --embedding-dim 384 --openrouter-api-key $OPENROUTER_API_KEY --llm-backend none restore --name <n> --version 2 --json`
- RESTORE etapa 2 codex: `sqlite-graphrag --llm-backend codex --llm-model gpt-5.4-mini enrich --operation memory-bindings --mode codex --codex-model gpt-5.4-mini --json`
- RESTORE etapa 2 claude: `sqlite-graphrag --llm-backend claude --llm-model claude-sonnet-4-6 enrich --operation memory-bindings --mode claude-code --claude-model claude-sonnet-4-6 --json`
- RESTORE etapa 2 opencode: `sqlite-graphrag --llm-backend opencode --llm-model opencode/big-pickle enrich --operation memory-bindings --mode opencode --opencode-model opencode/big-pickle --json`
## Fórmulas OpenRouter Somente-Leitura
- INIT: `sqlite-graphrag --embedding-backend openrouter --embedding-model nvidia/llama-nemotron-embed-vl-1b-v2:free --embedding-dim 384 --openrouter-api-key $OPENROUTER_API_KEY init --namespace <ns>`
- RECALL: `sqlite-graphrag --embedding-backend openrouter --embedding-model nvidia/llama-nemotron-embed-vl-1b-v2:free --embedding-dim 384 --openrouter-api-key $OPENROUTER_API_KEY recall "query" --k 10 --json`
- HYBRID-SEARCH: `sqlite-graphrag --embedding-backend openrouter --embedding-model nvidia/llama-nemotron-embed-vl-1b-v2:free --embedding-dim 384 --openrouter-api-key $OPENROUTER_API_KEY hybrid-search "query" --k 10 --with-graph --max-hops 2 --min-weight 0.3 --rrf-k 60 --json`
- DEEP-RESEARCH: `sqlite-graphrag --embedding-backend openrouter --embedding-model nvidia/llama-nemotron-embed-vl-1b-v2:free --embedding-dim 384 --openrouter-api-key $OPENROUTER_API_KEY deep-research "question" --k 20 --max-hops 3 --max-sub-queries 7 --max-results 50 --with-bodies --json`
- RENAME-ENTITY: `sqlite-graphrag --embedding-backend openrouter --embedding-model nvidia/llama-nemotron-embed-vl-1b-v2:free --embedding-dim 384 --openrouter-api-key $OPENROUTER_API_KEY rename-entity --name <old> --new-name <new> --json`
- ENRICH re-embed: `sqlite-graphrag --embedding-backend openrouter --embedding-model nvidia/llama-nemotron-embed-vl-1b-v2:free --embedding-dim 384 --openrouter-api-key $OPENROUTER_API_KEY --llm-backend codex --llm-model gpt-5.4-mini enrich --operation re-embed --limit 100 --resume --mode codex --codex-model gpt-5.4-mini --json`
- HYBRID-SEARCH offline: `sqlite-graphrag hybrid-search "query" --k 10 --fallback-fts-only --json`
## Diagnóstico e Manutenção
- INIT: `sqlite-graphrag init --namespace <ns>`; HEALTH: `sqlite-graphrag health --json | jaq '{integrity_ok, schema_version}'`
- MIGRATE: `sqlite-graphrag migrate --dry-run --json` para preview, depois `migrate --json` após um upgrade do binário
- OPTIMIZE: `sqlite-graphrag optimize --json` para refrescar estatísticas do planner; VACUUM: `sqlite-graphrag vacuum --json` após um purge grande
- FTS: `fts check --json` para integridade, `fts stats --json` para contagens, `fts rebuild --json` quando `health.fts_degraded` for true
- VEC: `vec orphan-list --json` depois `vec purge-orphan --yes`; `vec stats --json` para saúde de vetor
- EMBEDDING: `embedding --status --json` para contagens; `pending-embeddings --status --json` depois `pending-embeddings process --json` para reprocessar falhas
- SLOTS: `slots status --json` para inspecionar o semáforo do host; `slots release --slot-id <N> --yes` para órfãos
- PENDING: `pending list --filter-status queued --json`; `pending show <id>`; `pending cleanup --yes`
- EXPORT: `export --namespace <ns> --type <kind> --json` como NDJSON; STATS: `stats --json` para contagens e tamanhos
- BACKUP: `backup --output backup.sqlite --json`; SNAPSHOT: `sync-safe-copy --dest <path>` sem adquirir lock
- INSPECT: `namespace-detect --json`, `debug-schema --json`, `cache list --json`, `cache clear-models --yes`
- COMPLETIONS: `completions bash|zsh|fish|elvish|powershell`
- AGENDE semanal: `purge` depois `cleanup-orphans` depois `prune-relations --relation mentions` depois `vacuum` depois `optimize` depois `sync-safe-copy`
- SE corrupção: `sqlite3 broken.sqlite ".recover" | sqlite3 repaired.sqlite`
## Códigos de Saída e Estratégia de Retry
- EXIT 0 sucesso; EXIT 1 erro de validação; EXIT 2 parsing de argumento (flag obrigatória ausente); EXIT 3 conflito de lock otimista, recarregue e retente
- EXIT 4 não encontrado; EXIT 5 erro de namespace; EXIT 6 payload grande demais; EXIT 9 duplicada, use `--force-merge`
- EXIT 10 erro de banco, execute `vacuum` mais `health`; EXIT 11 falha de embedding, verifique backend, dimensão e OAuth
- EXIT 13 falha parcial de batch, reprocesse apenas falhados; EXIT 14 erro de I/O; EXIT 15 banco ocupado, amplie `--wait-lock`
- EXIT 16 falha preflight, corrija config MCP, NUNCA trate como transitório
- EXIT 19 SHUTDOWN, retry OBRIGATÓRIO, trabalho parcial descartado
- EXIT 20 erro interno; EXIT 75 slots esgotados ou singleton locked, respeite cooldown, NUNCA retente imediatamente
- EXIT 77 pressão de RAM, aguarde memória livre; EXIT 78 erro de config, chave ou modelo OpenRouter ausente
- NUNCA ignore um exit não-zero; NUNCA reprocesse um batch inteiro após exit 13; NUNCA confunda exit 1 com exit 9
## Concorrência
- RESPEITE o teto rígido `2 x nCPUs` para comandos pesados: `init`, `remember`, `ingest`, `recall`, `hybrid-search`
- DEFINA `--llm-parallelism N` padrão 4 em `remember` e `edit`, padrão 2 em `ingest`, clamp [1, 32]
- SAIBA do JOB SINGLETON: `enrich` e `ingest --mode codex|claude-code` adquirem um singleton por namespace
- USE `--wait-job-singleton SECS` ou `--force-job-singleton` para quebrar um lock stale
- HABILITE `SQLITE_GRAPHRAG_LOW_MEMORY=1` para paralelismo unitário, 3 a 4 vezes mais lento
- NUNCA rode `enrich` em paralelo contra o mesmo banco
## Variáveis de Ambiente
- `SQLITE_GRAPHRAG_DB_PATH` — override do path do banco
- `SQLITE_GRAPHRAG_NAMESPACE` — namespace persistente
- `SQLITE_GRAPHRAG_LLM_BACKEND` — backend LLM persistente
- `SQLITE_GRAPHRAG_LLM_MODEL` — modelo LLM persistente
- `SQLITE_GRAPHRAG_EMBEDDING_BACKEND` — backend de embedding persistente
- `SQLITE_GRAPHRAG_EMBEDDING_MODEL` — modelo de embedding OpenRouter persistente
- `SQLITE_GRAPHRAG_EMBEDDING_DIM` — dimensão de embedding [8, 4096], padrão 384
- `OPENROUTER_API_KEY` — chave de API OpenRouter, zeroizada no drop
- `SQLITE_GRAPHRAG_CODEX_BINARY`, `SQLITE_GRAPHRAG_CLAUDE_BINARY`, `SQLITE_GRAPHRAG_OPENCODE_BINARY` — overrides de path de binário
- `SQLITE_GRAPHRAG_OPENCODE_MODEL`, `SQLITE_GRAPHRAG_OPENCODE_TIMEOUT` — overrides opencode
- `SQLITE_GRAPHRAG_LOW_MEMORY` — habilitar paralelismo unitário
- `SQLITE_GRAPHRAG_LOG_FORMAT` — `json` para agregadores de log
- `SQLITE_GRAPHRAG_SKIP_PREFLIGHT` — bypass preflight, APENAS EMERGÊNCIAS
## Regras Ativas
- SEMPRE passe `--json` em toda invocação
- SEMPRE passe `--embedding-backend openrouter --embedding-model <MODEL> --embedding-dim 384` em toda operação de embedding, com a chave via env ou `--openrouter-api-key`
- SEMPRE passe `--llm-backend none` nas escritas; SEMPRE rode `enrich` como etapa SEPARADA com `--mode` e o modelo correspondente
- SEMPRE parseie `backend_invoked` para confirmar qual backend rodou
- SEMPRE refresque OAuth com `codex login`, ou o OAuth do claude, quando stale
- NUNCA passe chaves de API aos backends de subprocesso codex ou claude, OAuth-only, exit 1
- NUNCA passe `--llm-backend codex` em `remember`, `remember-batch`, `ingest`, `edit`, `restore`
- NUNCA rode `enrich` em paralelo contra o mesmo banco; NUNCA escreva o `.sqlite` fora do binário
- NUNCA ignore exit 19 (retry obrigatório) ou exit 16 (corrija config MCP)
- NUNCA passe `--embedding-backend openrouter` sem `--embedding-model` e uma chave — exit 78 garantido