sqlite-graphrag 1.0.45

Local GraphRAG memory for LLMs in a single SQLite file
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
# sqlite-graphrag para Agentes de IA


> Memória persistente para 27 agentes de IA em um único binário Rust de 25 MB

- Leia a versão em inglês em [AGENTS.md]AGENTS.md


## Aliases de Flags CLI (desde v1.0.35)
- `recall` e `hybrid-search` aceitam `--limit` como alias de `-k`/`--k`. Os snippets abaixo usam `--k` e continuam válidos.
- `rename` aceita `--from`/`--to` como aliases de `--name`/`--new-name`.
- `rename` aceita argumentos posicionais: `rename <antigo> <novo>` (desde v1.0.44)
- `related` aceita argumento posicional de nome: `related <nome>` (desde v1.0.44)
- `graph entities` JSON response usa `entities` como chave de array top-level (renomeado de `items` em v1.0.44)
- Campos JSON `schema_version` (`init`, `stats`, `migrate`, `health`) são emitidos como números JSON desde v1.0.35.


## A Pergunta Que Nenhum Framework Responde
### Open Loop — Por Que 27 Agentes de IA Escolhem Esta Como Sua Camada de Memória
- Por que 27 agentes de IA escolhem sqlite-graphrag como sua camada de memória persistente?
- Três razões técnicas: memória local durável, zero dependências cloud, JSON determinístico
- Cada agente ganha memória persistente sem gastar um único token adicional
- Versus MCPs pesados, sqlite-graphrag entrega contrato stdin/stdout determinístico
- O segredo que os frameworks jamais documentam mora em um único arquivo SQLite portátil


## Por Que Agentes Amam Esta CLI
### Cinco Diferenciais — Projetados Para Loops Autônomos
- Saída JSON determinística elimina cada hack de parser no código de orquestração
- Exit codes seguem `sysexits.h` para sua lógica de retry funcionar sem casar string
- Nenhum runtime Python ou Node acompanha a binária Rust da CLI
- Stdin aceita payloads estruturados para seus agentes jamais escaparem argumentos shell
- Comandos pesados de embedding podem subir e reutilizar `sqlite-graphrag daemon` automaticamente em vez de pagar cold-start em cada loop
- Comportamento cross-platform permanece idêntico em Linux macOS e Windows desde o início
- O comportamento padrão sempre cria ou abre `graphrag.sqlite` no diretório atual


## Economia Que Converte
### Números Que Vendem A Troca
- Remova dependências recorrentes de bancos vetoriais cloud nos fluxos locais de agentes
- Mantenha o retrieval local na workstation ou no runner de CI em vez de uma stack RAG remota
- Reduza a superfície operacional para um arquivo SQLite e uma CLI
- Reuse o daemon nos comandos pesados em vez de pagar cold-start completo em cada loop
- Preserve a orquestração determinística com JSON estável e exit codes estáveis


## Soberania Como Vantagem Competitiva
### Por Que Memória Local Vence Em 2026
- Seus dados proprietários NUNCA saem da workstation do desenvolvedor ou do runner de CI
- Sua superfície de compliance encolhe para um arquivo SQLite sob sua própria criptografia
- Seu lock-in de fornecedor desaparece porque o schema é documentado e portátil
- Sua trilha de auditoria mora na tabela `memory_versions` com histórico imutável
- Sua indústria regulada ganha RAG offline-first sem cláusulas de dependência cloud


## Agentes e Orquestradores Compatíveis
### Catálogo — 27 Integrações Suportadas
| Agente | Fornecedor | Versão Mínima | Tipo de Integração | Exemplo |
| --- | --- | --- | --- | --- |
| Claude Code | Anthropic | 1.0+ | Subprocess | `sqlite-graphrag recall "query" --json` |
| Codex CLI | OpenAI | 0.5+ | AGENTS.md + subprocess | `sqlite-graphrag remember --name X --type user --description "..." --body "..."` |
| Gemini CLI | Google | recente | Subprocess | `sqlite-graphrag hybrid-search "query" --json --k 5` |
| Opencode | open source | recente | Subprocess | `sqlite-graphrag recall "auth flow" --json --k 3` |
| OpenClaw | comunidade | recente | Subprocess | `sqlite-graphrag recall "auth flow" --json --k 3` |
| Paperclip | comunidade | recente | Subprocess | `sqlite-graphrag read --name onboarding-note --json` |
| VS Code Copilot | Microsoft | 1.90+ | tasks.json | `{"command": "sqlite-graphrag", "args": ["recall", "$selection", "--json"]}` |
| Google Antigravity | Google | recente | Runner | `sqlite-graphrag hybrid-search "prompt" --k 10 --json` |
| Windsurf | Codeium | recente | Terminal | `sqlite-graphrag recall "plano refactor" --json` |
| Cursor | Cursor | 0.40+ | Terminal | `sqlite-graphrag remember --name cursor-ctx --type project --description "..." --body "..."` |
| Zed | Zed Industries | recente | Assistant Panel | `sqlite-graphrag recall "abas abertas" --json --k 5` |
| Aider | open source | 0.60+ | Shell | `sqlite-graphrag recall "alvo refactor" --k 5 --json` |
| Jules | Google Labs | preview | automação CI | `sqlite-graphrag stats --json` |
| Kilo Code | comunidade | recente | Subprocess | `sqlite-graphrag recall "tarefas recentes" --json` |
| Roo Code | comunidade | recente | Subprocess | `sqlite-graphrag hybrid-search "contexto repo" --json` |
| Cline | comunidade | extensão VS Code | Terminal | `sqlite-graphrag list --limit 20 --json` |
| Continue | open source | VS Code ou JetBrains | Terminal | `sqlite-graphrag recall "docstring" --json` |
| Factory | Factory | recente | API ou subprocess | `sqlite-graphrag recall "contexto pr" --json` |
| Augment Code | Augment | recente | IDE | `sqlite-graphrag hybrid-search "code review" --json` |
| JetBrains AI Assistant | JetBrains | 2024.2+ | IDE | `sqlite-graphrag recall "stacktrace" --json` |
| OpenRouter | OpenRouter | qualquer | Roteador multi-LLM | `sqlite-graphrag recall "regra roteamento" --json` |
| Minimax | Minimax | recente | Subprocess | `sqlite-graphrag recall "preferencias usuario" --json --k 5` |
| Z.ai | Z.ai | recente | Subprocess | `sqlite-graphrag hybrid-search "contexto tarefa" --json --k 10` |
| Ollama | Ollama | 0.1+ | Subprocess | `sqlite-graphrag remember --name ollama-ctx --type project --description "..." --body "..."` |
| Hermes Agent | comunidade | recente | Subprocess | `sqlite-graphrag recall "historico tool call" --json` |
| LangChain | LangChain | 0.3+ | Subprocess via tool | `sqlite-graphrag hybrid-search "contexto chain" --json --k 5` |
| LangGraph | LangChain | 0.2+ | Subprocess via node | `sqlite-graphrag recall "estado grafo" --json --k 3` |


## Detalhes de Integração por Agente
### Minimax
- Agente multimodal open-source com raciocínio em vídeo áudio e texto
- Invoque sqlite-graphrag como subprocess dentro de uma definição de tool Minimax:
```bash
sqlite-graphrag recall "user session context" --json --k 5
```
- Saída: JSON com entradas em `results` contendo `name`, `snippet`, `distance` e `source`

### Z.ai
- Plataforma de agentes hospedada com planejamento multi-etapa e orquestração de tools
- Invoque sqlite-graphrag para persistir memória entre sessões de planejamento:
```bash
sqlite-graphrag remember --name "task-plan-$(date +%s)" --type project --description "plano de tarefa Z.ai" --body "$PLAN"
sqlite-graphrag recall "previous task plan" --json --k 3
```
- Saída: JSON determinístico com `results`, `direct_matches` e `graph_matches`

### Ollama
- Servidor LLM local rodando modelos abertos em hardware consumer sem cloud
- Invoque sqlite-graphrag como tool para dar aos agentes Ollama conhecimento persistente:
```bash
sqlite-graphrag recall "conversation history" --json --k 5
sqlite-graphrag remember --name "ollama-session" --type project --description "sessão Ollama" --body "$CONTEXT"
```
- Saída: JSON determinístico de recall com `elapsed_ms` e campos estáveis de resultado

### Hermes Agent
- Framework de agente comunitário projetado para loops de tool-calling no estilo ReAct
- Invoque sqlite-graphrag no início de cada ciclo ReAct para carregar contexto anterior:
```bash
sqlite-graphrag hybrid-search "tool call results" --json --k 5
```
- Saída: JSON hybrid-search combinando BM25 full-text e ranking vetorial por cosseno

### LangChain
- Framework Python de orquestração LLM com abstrações de chains tools e retrievers
- Invoque sqlite-graphrag como tool de retriever customizado via subprocess do Python:
```bash
sqlite-graphrag hybrid-search "chain input query" --json --k 10 --lang en
```
- Saída: array JSON `results` consumível via `json.loads` no wrapper de tool LangChain

### LangGraph
- Framework de máquina de estado baseado em grafo para workflows multi-agente sobre LangChain
- Invoque sqlite-graphrag dentro de cada nó do grafo para persistir e recuperar estado:
```bash
sqlite-graphrag recall "graph node output" --json --k 3
sqlite-graphrag remember --name "node-result-$(date +%s)" --type project --description "resultado do nó LangGraph" --body "$OUTPUT"
```
- Saída: JSON estruturado para travessia stateful entre execuções de LangGraph


## Integrações com Crates Rust
### Crates de Agente e LLM — Chame sqlite-graphrag como Subprocess
- Todo crate Rust que spawna um agente LLM pode chamar sqlite-graphrag via `std::process::Command`
- Recall por subprocesso determinístico permite a crates Rust reutilizarem um contrato estável de memória
- Zero tokens adicionais: memória vive no SQLite não dentro da janela de contexto
- Cada crate ganha memória persistente sem importar nenhuma dependência do sqlite-graphrag

### rig-core
- Framework modular para construir pipelines LLM sistemas RAG e agentes autônomos
- Cargo.toml:
```toml
[dependencies]
rig-core = "0.35.0"
```
- Integração com sqlite-graphrag:
```rust
use std::process::Command;
let output = Command::new("sqlite-graphrag")
    .args(["recall", "project context", "--json"])
    .output()?;
```
- Caso de uso: persistir resultados de tools de agente entre invocações do pipeline rig

### swarms-rs
- Framework de orquestração multi-agente com suporte MCP nativo e topologias de swarm
- Cargo.toml:
```toml
[dependencies]
swarms-rs = "0.2.1"
```
- Integração com sqlite-graphrag:
```rust
use std::process::Command;
let output = Command::new("sqlite-graphrag")
    .args(["hybrid-search", "swarm task result", "--json", "--k", "5"])
    .output()?;
```
- Caso de uso: compartilhar contexto persistente entre agentes do swarm sem vector DB central

### autoagents
- Runtime multi-agente com atores Ractor loops ReAct e isolamento WASM sandbox
- Cargo.toml:
```toml
[dependencies]
autoagents = "0.3.7"
```
- Integração com sqlite-graphrag:
```rust
use std::process::Command;
let output = Command::new("sqlite-graphrag")
    .args(["remember", "--name", "react-step", "--type", "agent", "--body", "step output"])
    .output()?;
```
- Caso de uso: salvar checkpoint de etapas ReAct para replay e auditoria em loops autoagents

### agentai
- Camada de agente fina sobre genai com abstração ToolBox simples para registro de tools
- Cargo.toml:
```toml
[dependencies]
agentai = "0.1.5"
```
- Integração com sqlite-graphrag:
```rust
use std::process::Command;
let output = Command::new("sqlite-graphrag")
    .args(["recall", "tool call context", "--json", "--k", "3"])
    .output()?;
```
- Caso de uso: injetar histórico de tool calls anteriores no ToolBox antes de cada execução

### llm-agent-runtime
- Runtime completo de agente com memória episódica checkpointing e orquestração de tools
- Cargo.toml:
```toml
[dependencies]
llm-agent-runtime = "1.74.0"
```
- Integração com sqlite-graphrag:
```rust
use std::process::Command;
let output = Command::new("sqlite-graphrag")
    .args(["recall", "episode context", "--json"])
    .output()?;
```
- Caso de uso: estender memória episódica do llm-agent-runtime com persistência SQLite durável

### anda
- Framework de agentes para ambientes TEE e integrações blockchain com ICP
- Cargo.toml:
```toml
[dependencies]
anda = "0.4.10"
```
- Integração com sqlite-graphrag:
```rust
use std::process::Command;
let output = Command::new("sqlite-graphrag")
    .args(["read", "--name", "anda-agent-state", "--json"])
    .output()?;
```
- Caso de uso: persistir estado verificável do agente fora do TEE para continuidade entre sessões

### adk-rust
- Kit modular de desenvolvimento de agentes inspirado nos padrões LangChain e Autogen
- Cargo.toml:
```toml
[dependencies]
adk-rust = "0.6.0"
```
- Integração com sqlite-graphrag:
```rust
use std::process::Command;
let output = Command::new("sqlite-graphrag")
    .args(["hybrid-search", "agent memory query", "--json", "--k", "10"])
    .output()?;
```
- Caso de uso: substituir o store de contexto em memória do adk-rust por recall por grafo persistente

### genai
- Cliente API unificado para OpenAI Anthropic Gemini xAI e Ollama em um único crate
- Cargo.toml:
```toml
[dependencies]
genai = "0.6.0-beta.17"
```
- Integração com sqlite-graphrag:
```rust
use std::process::Command;
let output = Command::new("sqlite-graphrag")
    .args(["recall", "llm response cache", "--json"])
    .output()?;
```
- Caso de uso: armazenar respostas custosas do genai para reutilização em execuções seguintes

### liter-llm
- Cliente LLM universal com suporte a 143 ou mais provedores e rastreamento OpenTelemetry
- Cargo.toml:
```toml
[dependencies]
liter-llm = "1.2.1"
```
- Integração com sqlite-graphrag:
```rust
use std::process::Command;
let output = Command::new("sqlite-graphrag")
    .args(["remember", "--name", "litellm-trace", "--type", "agent", "--body", "trace payload"])
    .output()?;
```
- Caso de uso: armazenar snapshots de trace OpenTelemetry no sqlite-graphrag para replay de agente

### llm-cascade
- Cliente LLM em cascata com failover automático e circuit breaker entre provedores
- Cargo.toml:
```toml
[dependencies]
llm-cascade = "0.1.0"
```
- Integração com sqlite-graphrag:
```rust
use std::process::Command;
let output = Command::new("sqlite-graphrag")
    .args(["recall", "fallback provider result", "--json"])
    .output()?;
```
- Caso de uso: persistir decisões de cascata para que o circuit breaker aprenda com falhas anteriores

### async-openai
- Cliente async nativo Rust para a API REST completa da OpenAI com modelos type-safe
- Cargo.toml:
```toml
[dependencies]
async-openai = "0.34.0"
```
- Integração com sqlite-graphrag:
```rust
use std::process::Command;
let output = Command::new("sqlite-graphrag")
    .args(["hybrid-search", "openai assistant output", "--json", "--k", "5"])
    .output()?;
```
- Caso de uso: armazenar mensagens de thread de assistente para recall durável entre sessões

### anthropic-sdk
- Cliente Rust direto para a API Anthropic incluindo tool use e respostas streaming
- Cargo.toml:
```toml
[dependencies]
anthropic-sdk = "0.1.5"
```
- Integração com sqlite-graphrag:
```rust
use std::process::Command;
let output = Command::new("sqlite-graphrag")
    .args(["recall", "claude conversation context", "--json"])
    .output()?;
```
- Caso de uso: injetar turnos anteriores da conversa Claude antes de cada chamada à API

### ollama-rs
- Cliente Rust idiomático para a API do servidor de inferência local Ollama
- Cargo.toml:
```toml
[dependencies]
ollama-rs = "0.3.4"
```
- Integração com sqlite-graphrag:
```rust
use std::process::Command;
let output = Command::new("sqlite-graphrag")
    .args(["remember", "--name", "ollama-output", "--type", "agent", "--body", "generated text"])
    .output()?;
```
- Caso de uso: persistir outputs do ollama-rs para recuperação em chamadas de inferência seguintes

### llama-cpp-rs
- Bindings Rust para llama.cpp para inferência on-device com modelos quantizados
- Cargo.toml:
```toml
[dependencies]
llama-cpp-rs = "0.3.0"
```
- Integração com sqlite-graphrag:
```rust
use std::process::Command;
let output = Command::new("sqlite-graphrag")
    .args(["recall", "on-device inference context", "--json", "--k", "5"])
    .output()?;
```
- Caso de uso: carregar contexto persistente no prompt do llama-cpp-rs antes de cada inferência local

### mistralrs
- Engine de inferência local de alta performance para modelos Mistral com suporte a quantização
- Cargo.toml:
```toml
[dependencies]
mistralrs = "0.8.1"
```
- Integração com sqlite-graphrag:
```rust
use std::process::Command;
let output = Command::new("sqlite-graphrag")
    .args(["recall", "mistral inference context", "--json", "--k", "5"])
    .output()?;
```
- Caso de uso: injetar contexto persistente do sqlite-graphrag nos prompts do mistralrs antes da inferência

### graphbit
- Engine de workflow baseado em grafo para orquestração determinista de pipelines LLM em Rust
- Cargo.toml:
```toml
[dependencies]
graphbit = { git = "https://github.com/graphbit-rs/graphbit" }
```
- Integração com sqlite-graphrag:
```rust
use std::process::Command;
let output = Command::new("sqlite-graphrag")
    .args(["recall", "workflow node state", "--json", "--k", "3"])
    .output()?;
```
- Caso de uso: persistir outputs de nós do workflow graphbit para travessia stateful entre execuções

### rs-graph-llm
- Workflows de grafo tipados e interativos para pipelines LLM com segurança em tempo de compilação
- Cargo.toml:
```toml
[dependencies]
rs-graph-llm = { git = "https://github.com/rs-graph-llm/rs-graph-llm" }
```
- Integração com sqlite-graphrag:
```rust
use std::process::Command;
let output = Command::new("sqlite-graphrag")
    .args(["hybrid-search", "graph node output", "--json", "--k", "5"])
    .output()?;
```
- Caso de uso: armazenar resultados tipados do rs-graph-llm para memória persistente entre execuções


## Princípios Fundamentais
### OBRIGATÓRIO — Filosofia de Uso
- TRATAR sqlite-graphrag como camada local de memória persistente
- INVOCAR sempre como subprocesso via `std::process::Command`
- LER stdout para dados estruturados em JSON ou NDJSON
- LER stderr para logs de tracing e mensagens humanas
- VERIFICAR exit code antes de parsear stdout
- PRESERVAR contexto entre sessões via arquivo SQLite único
- DELEGAR memória de longo prazo ao binário sem reimplementar
### PROIBIDO — Anti-padrões
- NUNCA expor o binário como servidor MCP ou serviço HTTP
- NUNCA depender de vector DB cloud como Pinecone ou Weaviate
- NUNCA escrever direto no SQLite paralelo ao binário
- NUNCA editar o arquivo `.sqlite` com outra ferramenta
- NUNCA assumir saída sem validar exit code antes
- NUNCA confundir `distance` com `combined_score` no ranking
- NUNCA misturar stdout estruturado com logs humanos
- NUNCA usar `fd | xargs remember` quando `ingest` cobre o caso


## Inicialização e Verificação de Saúde
### OBRIGATÓRIO — Bootstrap do Banco
- EXECUTAR `sqlite-graphrag init --namespace <projeto>` no primeiro uso
- AGUARDAR download offline do modelo `multilingual-e5-small`
- VALIDAR com `sqlite-graphrag health --json` antes de operar
- TRATAR exit code 10 como erro de database ou banco corrompido
- TRATAR exit code 15 como lock pendente, ampliar `--wait-lock`
- ABORTAR pipeline quando `integrity_ok` retornar `false`
- RODAR `migrate --json` após cada upgrade do binário
### OBRIGATÓRIO — Verificação Contínua
- INSPECIONAR `wal_size_mb` no `health` para detectar fragmentação
- CONFERIR `journal_mode` igual a `wal` em produção
- RODAR `optimize --json` para refrescar estatísticas do planner
- DETECTAR deriva de schema via `__debug_schema` em troubleshooting
### Padrão Correto — Sequência de Bootstrap
- `sqlite-graphrag init --namespace meu-projeto`
- `sqlite-graphrag health --json | jaq '.integrity_ok'`
- `sqlite-graphrag migrate --json`
- `sqlite-graphrag stats --json | jaq '.memories'`


## Configuração Global
### OBRIGATÓRIO — Caminho do Banco
- USAR `--db <PATH>` quando o banco não está no diretório atual
- DEFINIR `SQLITE_GRAPHRAG_DB_PATH` para configuração persistente
- LEMBRAR que `--db` tem precedência sobre a variável de ambiente
- PADRÃO é `graphrag.sqlite` no diretório atual de invocação
### OBRIGATÓRIO — Namespace
- DEFINIR namespace via `--namespace` ou `SQLITE_GRAPHRAG_NAMESPACE`
- VALIDAR resolução com `namespace-detect --json`
- USAR `global` como namespace padrão quando ausente
- ISOLAR projetos via namespace por repositório
- ADOTAR `swarm-<agent_id>` para enxames multi-agente
### OBRIGATÓRIO — Idioma da Saída
- USAR `--lang en` ou `--lang pt` para forçar idioma
- DEFINIR `SQLITE_GRAPHRAG_LANG=pt` para override de sessão
- LEMBRAR que `--lang` afeta apenas stderr humano
- STDOUT JSON permanece determinístico independente do idioma
### OBRIGATÓRIO — Fuso Horário de Exibição
- APLICAR `--tz America/Sao_Paulo` em saídas localizadas
- USAR `SQLITE_GRAPHRAG_DISPLAY_TZ=<IANA>` para persistir
- AFETA apenas campos `*_iso` no JSON
- CAMPOS epoch inteiros permanecem em UTC
- ABORTAR quando nome IANA inválido retorna exit 1 (Validation)
### OBRIGATÓRIO — Formato de Logs
- ATIVAR `SQLITE_GRAPHRAG_LOG_FORMAT=json` para agregadores
- PADRÃO `pretty` serve apenas para humanos no terminal
- ELEVAR detalhe via `SQLITE_GRAPHRAG_LOG_LEVEL=debug` em diagnóstico
- USAR `-v`, `-vv`, `-vvv` para info, debug e trace nos subcomandos
### OBRIGATÓRIO — Controle de Memória RAM Global
- ATIVAR `SQLITE_GRAPHRAG_LOW_MEMORY=1` em containers restritos
- APLICAR em hosts com menos de 4 GB de RAM disponível
- HONRA cgroup constraints automaticamente quando definido
- TRADE-OFF é 3 a 4 vezes mais tempo de wall clock
- COMBINAR com flag `--low-memory` em `ingest` específico
### OBRIGATÓRIO — ONNX Runtime em ARM64 GNU
- DISTRIBUIR `libonnxruntime.so` ao lado da binária
- DEFINIR `ORT_DYLIB_PATH` explicitamente em CI e systemd
- AFETA comandos pesados de embedding em `aarch64-unknown-linux-gnu`
- FALHA na primeira operação de embedding sem o runtime acessível


## CRUD — Create com remember
### OBRIGATÓRIO — Escrita de Memórias Individuais
- USAR nome kebab-case único por memória
- DECLARAR `--type` entre `user`, `feedback`, `project`, `reference`, `decision`, `incident`, `skill`, `document`, `note`
- PREFERIR `--body-stdin` para corpos longos
- USAR `--body-file <PATH>` para evitar escape shell em Markdown
- PASSAR `--force-merge` em loops idempotentes
- NER desabilitado por padrão; passar `--enable-ner` para ativar extração BERT
- RESPEITAR limite de 512000 bytes e 512 chunks por body
### OBRIGATÓRIO — Anexar Grafo no remember
- USAR `--entities-file` com array JSON tipado
- USAR `--relationships-file` para arestas tipadas
- INCLUIR campo `entity_type` em cada objeto de entidade
- ACEITAR `type` como sinônimo, nunca os dois juntos
- USAR `strength` entre `0.0` e `1.0` em relationships
- MAPEAR `from`/`to` como aliases de `source`/`target`
- USAR `--graph-stdin` para JSON único com `body`, `entities` e `relationships`
### PROIBIDO — Erros de Escrita
- NUNCA enviar `entity_type` e `type` no mesmo objeto JSON
- NUNCA usar `strength` fora do intervalo `[0.0, 1.0]`
- NUNCA duplicar nome sem `--force-merge` explícito
- NUNCA misturar `--body`, `--body-file`, `--body-stdin`, `--graph-stdin`
- NUNCA depender de auto-extração BERT em CI sensível a RAM
- NUNCA exceder o cap de relações por memória sem ajustar env
- NUNCA usar `remember` em loop quando `ingest` cobre o caso
### Padrão Correto — Exemplos de remember
- `sqlite-graphrag remember --name design-auth --type decision --description "auth JWT" --body-stdin < doc.md`
- `sqlite-graphrag remember --name doc-readme --type document --description "import" --body-file README.md --force-merge`
- `sqlite-graphrag remember --name spec-x --type reference --description "spec" --body "..." --entities-file ents.json --relationships-file rels.json`
### Valores Válidos de --type
- `user`, `feedback`, `project`, `reference`
- `decision`, `incident`, `skill`, `document`, `note`


## CRUD — Bulk Ingest com ingest
### OBRIGATÓRIO — Quando Usar ingest
- USAR `ingest <DIR>` para importar diretórios inteiros como memórias
- PREFERIR sobre loop `fd | xargs remember` em qualquer caso
- CADA arquivo correspondente ao pattern vira memória individual
- NOME da memória deriva do basename do arquivo sem extensão em kebab-case
- NOMES com mais de 60 caracteres são TRUNCADOS automaticamente
- NDJSON inclui `truncated: true` e `original_name` quando trunca
- AGENTE deve usar `original_name` ou `name` do NDJSON para acessar a memória
- SAÍDA é NDJSON, uma linha JSON por arquivo mais uma linha summary final
- CONSUMIR linha a linha em streaming via `jaq -c` ou `while read`
### OBRIGATÓRIO — Padrão de Arquivos com --pattern
- PADRÃO é `*.md` apenas, mude conforme necessário
- ACEITA `*.<ext>` para extensão genérica
- ACEITA `<prefixo>*` para prefixo de basename
- ACEITA filename exato sem caracteres glob
- GLOB completo POSIX não é suportado pelo ingest
### OBRIGATÓRIO — Recursão e Limites
- LIGAR `--recursive` para descer em subdiretórios
- SEM `--recursive` apenas top-level é processado
- RESPEITAR `--max-files 10000` como cap padrão de segurança
- `--max-files` REJEITA a operação inteira com exit 1 se contagem exceder o cap
- `--max-files` NÃO limita aos primeiros N, é validação all-or-nothing
- AUMENTAR cap apenas após auditoria de volume real
- USAR `--fail-fast` para parar na primeira falha por arquivo
- SEM `--fail-fast` o loop continua e reporta cada erro no NDJSON
### OBRIGATÓRIO — Tipo de Memória em Massa
- DECLARAR `--type` aplicado a TODOS os arquivos da invocação
- PADRÃO é `document` quando omitido
- VALORES válidos: `user`, `feedback`, `project`, `reference`, `decision`, `incident`, `skill`, `document`, `note`
- INVOCAR `ingest` separadamente por tipo quando misturar
- AGRUPAR arquivos por diretório conforme o tipo desejado
### OBRIGATÓRIO — Controle de Memória RAM
- USAR `--low-memory` em containers com menos de 4 GB
- DEFINIR `SQLITE_GRAPHRAG_LOW_MEMORY=1` como override persistente
- `--low-memory` força `--ingest-parallelism 1` internamente
- TRADE-OFF é 3 a 4 vezes mais tempo de execução
- ESCOLHER quando RSS for restrição maior que latência
### OBRIGATÓRIO — Dois Eixos de Paralelismo
- `--max-concurrency <N>` controla CLI invocations simultâneas
- `--ingest-parallelism <N>` controla extract mais embed em paralelo
- PADRÃO de `--max-concurrency` é 4
- PADRÃO de `--ingest-parallelism` é `min(4, max(1, cpus/2))`
- DISTINGUIR claramente os dois eixos antes de ajustar
- AMPLIAR `--wait-lock <SECONDS>` para esperar slot antes de exit 75
### OBRIGATÓRIO — Performance e Extração
- NER desabilitado por padrão; passar `--enable-ner` para ativar extração BERT
- BERT NER adiciona aproximadamente 150 ms por arquivo com daemon ativo em hardware moderno
- BERT NER adiciona 2 a 30 segundos por arquivo em `--low-memory` ou sem daemon
- BERT NER adiciona aproximadamente 30 segundos no primeiro run para carregar modelo
- USAR `--enable-ner` apenas quando enriquecimento automático de entidades for valioso
- PREFERIR `--graph-stdin` com entidades curadas por LLM para melhor qualidade (NER desabilitado por padrão)
### PROIBIDO — Anti-padrões de ingest
- NUNCA usar `fd | xargs sqlite-graphrag remember` quando `ingest` existe
- NUNCA omitir `--recursive` esperando descida automática
- NUNCA passar pattern com glob complexo não suportado
- NUNCA ignorar exit 75 de slot exausto em loops automatizados
- NUNCA misturar tipos diferentes na mesma invocação
- NUNCA elevar `--max-files` sem medir RAM e disco antes
- NUNCA usar `--force-merge` no ingest (flag exclusiva do `remember`)
### Padrão Correto — Exemplos de ingest
- `sqlite-graphrag ingest ./docs --recursive --pattern "*.md" --json`
- `sqlite-graphrag ingest ./decisoes --type decision --json`
- `sqlite-graphrag ingest ./large-corpus --low-memory --max-files 50000 --json`
- `sqlite-graphrag ingest ./skills --type skill --recursive --fail-fast --json`
- `sqlite-graphrag ingest ./notas --type note --pattern "memo-*" --recursive --json`
### Padrão Correto — Consumo do NDJSON
- `sqlite-graphrag ingest ./docs --recursive --json | jaq -c 'select(.status == "indexed")'`
- `sqlite-graphrag ingest ./docs --recursive --json | tee resultados.ndjson`
- NDJSON contém `files_total + 1` linhas: uma por arquivo mais uma summary final
- FILTRAR por `select(.status)` para ignorar a summary line que não tem campo `status`
- `jaq -sc '[.[] | select(.status)] | group_by(.status) | map({status: .[0].status, count: length})' < resultados.ndjson`
### OBRIGATÓRIO — Schema NDJSON por Tipo de Linha
- Linha por arquivo: `file`, `name`, `status` (`"indexed"` `"skipped"` `"failed"`), `truncated`, `original_name?`, `memory_id?`, `action?`, `error?`
- Linha summary final: `summary` (true), `dir`, `pattern`, `recursive`, `files_total`, `files_succeeded`, `files_failed`, `files_skipped`, `elapsed_ms`
- Eventos de extração NER vão para stderr, NÃO stdout


## CRUD — Read com read e list
### OBRIGATÓRIO — Leitura Direta por Nome (read)
- USAR `read --name <kebab-case>` para fetch O(1) por nome
- PARSEAR campos `body`, `description`, `created_at_iso`, `updated_at_iso`
- TRATAR exit code 4 como memória inexistente no namespace
- APLICAR `--tz` para localizar timestamps na saída
### OBRIGATÓRIO — Enumeração com Filtros (list)
- USAR `list --type <kind>` para filtrar por tipo de memória
- AJUSTAR `--limit <N>` com padrão 50 conforme volume esperado
- PAGINAR via `--offset <N>` para datasets grandes
- INCLUIR memórias soft-deletadas via `--include-deleted`
- EXPORTAR full dump com `--limit 10000 --json` antes de backup
### Padrão Correto — Exemplos de Leitura
- `sqlite-graphrag read --name design-auth --json`
- `sqlite-graphrag list --type decision --limit 100 --json`
- `sqlite-graphrag list --include-deleted --json | jaq '.items[] | select(.deleted)'`


## CRUD — Update com edit, rename e restore
### OBRIGATÓRIO — Edição de Corpo e Descrição (edit)
- USAR `edit --name <nome> --body <texto>` para corpos curtos
- PREFERIR `--body-file` ou `--body-stdin` para corpos longos
- ALTERAR descrição via `--description <texto>`
- CADA edit cria nova versão imutável preservando histórico
- VALIDAR exit code 3 como conflito de locking otimista
- JSON response: `memory_id`, `name`, `action` ("updated"), `version`, `elapsed_ms`
### OBRIGATÓRIO — Renomeação Preservando Histórico (rename)
- USAR `rename --name <antigo> --new-name <novo>`
- ACEITAR `--old`/`--new` e `--from`/`--to` como aliases desde v1.0.35
- PRESERVAR todas as versões e conexões do grafo
- TRATAR exit code 4 como memória de origem ausente
- JSON response: `memory_id`, `name` (novo), `action` ("renamed"), `version`, `elapsed_ms`
### OBRIGATÓRIO — Restauração de Versão Antiga (restore)
- INSPECIONAR versões via `history --name <nome>` primeiro
- USAR `restore --name <nome> --version <N>` para versão específica
- OMITIR `--version` seleciona última versão não-restore automaticamente
- RESTORE cria nova versão sem sobrescrever histórico anterior
- RE-EMBED ocorre automaticamente para recall vetorial voltar a encontrar
### OBRIGATÓRIO — Locking Otimista
- PASSAR `--expected-updated-at <epoch_ou_RFC3339>` em pipelines concorrentes
- TRATAR exit code 3 como concorrência detectada
- RECARREGAR `read --json` para obter novo `updated_at` antes de retentar
- APLICAR locking em `edit`, `rename` e `restore`
### Padrão Correto — Fluxos de Update
- `sqlite-graphrag edit --name design-auth --body-file ./revisado.md --expected-updated-at "2026-04-19T12:00:00Z"`
- `sqlite-graphrag rename --from nome-antigo --to nome-novo`
- `sqlite-graphrag history --name design-auth --json && sqlite-graphrag restore --name design-auth --version 2`


## CRUD — Delete com forget, purge, unlink e cleanup-orphans
### OBRIGATÓRIO — Remoção Lógica (forget)
- USAR `forget --name <nome>` para soft-delete reversível
- MEMÓRIA desaparece de `recall` e `list` por padrão
- HISTÓRICO de versões permanece intacto no banco
- REVERSÍVEL via `restore` enquanto não houver purge
- JSON response: `action` (`"soft_deleted"` `"already_deleted"`), `forgotten`, `name`, `namespace`, `deleted_at?`, `deleted_at_iso?`, `elapsed_ms`
### OBRIGATÓRIO — Remoção Física (purge)
- USAR `purge --retention-days <N> --yes` em automação
- PADRÃO de retenção é 90 dias para memórias soft-deletadas
- EXECUTAR `--dry-run` primeiro para auditar contagem
- APAGA permanentemente linhas e reclama espaço em disco
### OBRIGATÓRIO — Remoção de Aresta (unlink)
- USAR `unlink --from <a> --to <b> --relation <tipo>`
- ACEITAR `--source`/`--target` como aliases de `--from`/`--to`
- TRATAR exit code 4 como aresta inexistente
- TODOS os três argumentos são obrigatórios sem exceção
### OBRIGATÓRIO — Limpeza de Entidades Órfãs (cleanup-orphans)
- EXECUTAR `cleanup-orphans --dry-run` para auditar
- APLICAR `--yes` em pipelines automatizados
- REMOVE entidades sem memórias vinculadas nem arestas
- RODAR periodicamente após operações `forget` em massa
### Padrão Correto — Round-Trip Forget e Restore
- `sqlite-graphrag forget --name decisao-x`
- `sqlite-graphrag history --name decisao-x --json | jaq '.deleted'`
- `sqlite-graphrag restore --name decisao-x`
- `sqlite-graphrag recall "decisão" --json`


## Histórico Imutável de Versões
### OBRIGATÓRIO — Inspeção com history
- USAR `history --name <nome> --json` para listar versões
- VERSÕES começam em 1 e incrementam a cada `edit` ou `restore`
- ORDEM cronológica reversa por padrão
- INCLUI memórias soft-deletadas com flag `deleted: true`
### OBRIGATÓRIO — Semântica de Versões
- CADA `edit` cria nova versão imutável preservando anteriores
- CADA `restore` cria nova versão com corpo de versão antiga
- AUDIT TRAIL completo de quem mudou o que e quando
- RETENTION POLICY controla quando purgar definitivamente
### Padrão Correto — Auditoria de Mudanças
- `sqlite-graphrag history --name design-auth --json | jaq '.versions[].created_at_iso'`


## Pesquisa GraphRAG
### OBRIGATÓRIO — Quatro Comandos de Busca
- USAR `recall` para busca KNN vetorial com expansão automática de grafo
- USAR `hybrid-search` para fusão de FTS5 e vetorial via RRF
- USAR `related` para travessia multi-hop a partir de memória conhecida
- USAR `graph traverse` para travessia a partir de entidade tipada
- COMBINAR os quatro no padrão de três camadas canônico
### OBRIGATÓRIO — Padrão de Três Camadas Canônico
- CAMADA 1 — `hybrid-search` para encontrar memórias seed por nome
- CAMADA 2 — `read --name` para expandir corpo completo da memória
- CAMADA 3 — `related` ou `graph traverse` para subgrafo multi-hop
- APLICAR camadas em ordem, parando quando contexto basta
- INJETAR resultados consolidados no prompt do LLM
### OBRIGATÓRIO — Camada 1 com hybrid-search
- USAR `hybrid-search <query> --k 10 --rrf-k 60 --json`
- COMBINA FTS5 textual e KNN vetorial via Reciprocal Rank Fusion
- AJUSTAR `--weight-vec` e `--weight-fts` apenas com evidência numérica
- PADRÃO de ambos os pesos é `1.0` com fusão equilibrada
- EXTRAIR apenas `name` via `jaq -r '.results[].name'` para next stage
### OBRIGATÓRIO — hybrid-search com Expansão de Grafo
- ATIVAR travessia de grafo via `--with-graph` para descobrir memórias conectadas
- AJUSTAR profundidade com `--max-hops <N>` (padrão 2)
- FILTRAR arestas fracas com `--min-weight <F>` (padrão 0.0)
- RESULTADOS do grafo ficam em `graph_matches[]`, SEPARADOS de `results[]`
- `graph_matches[]` usa schema RecallItem: `name`, `distance`, `source` ("graph"), `graph_depth`
- LER AMBOS `results[]` e `graph_matches[]` quando `--with-graph` ativo
- EXTRAIR via `jaq -r '(.results[] , .graph_matches[]) | .name'`
### OBRIGATÓRIO — Camada 1 Alternativa com recall
- USAR `recall <query> --k 5 --json` para queries semânticas puras
- ACEITAR `--limit` como alias de `--k` desde v1.0.35
- RECALL expande automaticamente via grafo por padrão
- DESLIGAR expansão automática de grafo via `--no-graph`
- INTERPRETAR `distance` crescente como similaridade decrescente
- INTERPRETAR `score` como `1.0 - distance`, clamped a `[0.0, 1.0]`
- CAMPO `source` indica origem: `"direct"` (KNN) ou `"graph"` (travessia)
- CAMPO `graph_depth` presente apenas em resultados com `source: "graph"`
- RecallResponse separa `direct_matches[]`, `graph_matches[]` e `results[]` (agregado)
- USAR quando query não mistura tokens exatos com linguagem natural
### OBRIGATÓRIO — Camada 2 com read --name
- USAR `read --name <nome>` para obter corpo completo da memória seed
- EXPANDIR contexto além do snippet retornado pela camada 1
- LOOP sobre os top-k nomes para construir bundle de contexto
- PARSEAR campos `body`, `description`, `created_at_iso`
### OBRIGATÓRIO — Camada 3 com related
- USAR `related <nome> --hops <N>` para travessia multi-hop
- DOIS hops revelam conhecimento transitivo invisível à busca vetorial
- DISTÂNCIA de hop entrega sinal explícito ao orquestrador
- USAR quando a query exige raciocínio multi-passo encadeado
### OBRIGATÓRIO — Camada 3 Alternativa com graph traverse
- USAR `graph traverse --from <raiz> --depth <N>` para subgrafo focado
- PADRÃO de profundidade é 2 quando omitido
- TRATAR exit code 4 como entidade raiz inexistente
- HOPS retornam `entity`, `relation`, `direction`, `weight`, `depth`
- PARTIR de entidade tipada, não de nome de memória
### OBRIGATÓRIO — Semântica dos Scores e Distâncias
- `recall` retorna `distance` (menor é mais similar) e `score` (1.0 - distance)
- `recall` retorna `source` (`"direct"` ou `"graph"`) e `graph_depth` (quando graph)
- `hybrid-search` retorna `combined_score`, maior é melhor ranking
- `hybrid-search` expõe `vec_rank` e `fts_rank` para auditar fusão
- `hybrid-search` com `--with-graph` adiciona `graph_matches[]` em campo separado
- `related` retorna `hop_distance`, profundidade explícita no grafo
- `graph traverse` retorna `depth` por hop visitado
- DESCARTAR hits fracos antes de gastar tokens no prompt
### OBRIGATÓRIO — Escolha do Comando por Tipo de Query
- QUERY conceitual ampla, `recall` com `--k 5`
- QUERY mista de tokens e linguagem natural, `hybrid-search` com `--rrf-k 60`
- QUERY mista com contexto de grafo, `hybrid-search --with-graph --max-hops 2`
- QUERY exploratória partindo de memória, `related --hops 2`
- QUERY exploratória partindo de entidade, `graph traverse --depth 2`
- QUERY de auditoria do grafo, `graph entities` ou `graph stats`
### PROIBIDO — Anti-padrões de Pesquisa
- NUNCA usar busca textual nativa SQLite paralela ao binário
- NUNCA confundir `distance` com `combined_score` no ranking
- NUNCA aumentar `--hops` sem inspecionar `graph stats` antes
- NUNCA injetar resultados sem filtrar por threshold de relevância
- NUNCA paralelizar buscas pesadas sem medir RSS do host
- NUNCA pular camada 2 quando o snippet for insuficiente
- NUNCA ler apenas `.results[]` quando `--with-graph` ativo (perderá `graph_matches[]`)
### Padrão Correto — Pipeline Canônico de Três Camadas
- `sqlite-graphrag hybrid-search "auth jwt design" --k 10 --json | jaq -r '.results[].name' > seeds.txt`
- `while read -r nome; do sqlite-graphrag read --name "$nome" --json; done < seeds.txt > corpos.ndjson`
- `sqlite-graphrag related "$(head -n1 seeds.txt)" --hops 2 --json > grafo.json`
- `paste -d '\n' corpos.ndjson <(cat grafo.json) | claude --print`
### Padrão Correto — Pipeline com Expansão de Grafo
- `sqlite-graphrag hybrid-search "auth" --k 5 --with-graph --json | jaq -r '(.results[], .graph_matches[]) | .name' | sort -u > seeds.txt`
### Padrão Correto — Ajuste Fino de Pesos no hybrid-search
- `--weight-vec 1.0 --weight-fts 1.0` igual peso, padrão recomendado
- `--weight-vec 1.0 --weight-fts 0.0` reproduz baseline recall puro
- `--weight-vec 0.0 --weight-fts 1.0` reproduz FTS5 puro
- `--weight-vec 0.7 --weight-fts 0.3` favorece semântica sobre tokens
- `--weight-vec 0.3 --weight-fts 0.7` favorece tokens sobre semântica
### Ganhos Mensurados do Padrão de Três Camadas
- REDUÇÃO de tokens de contexto em até 72x versus dump de markdown
- AUMENTO de accuracy em até 18% sobre vector retrieval puro
- AUMENTO de multi-hop accuracy de 30% a 50% segundo Microsoft
- LATÊNCIA aproximada de 1 segundo em hardware moderno com daemon


## Grafo — Construção e Inspeção
### OBRIGATÓRIO — Criação de Arestas (link)
- USAR `link --from <a> --to <b> --relation <tipo>`
- ENTIDADES devem existir como nós tipados antes do link, exceto com `--create-missing`
- USAR `--create-missing` para auto-criar entidades inexistentes durante o link
- USAR `--entity-type <tipo>` para definir tipo das entidades auto-criadas (padrão `concept`)
- JSON response inclui `created_entities: ["a", "b"]` quando entidades foram criadas
- ACEITAR `--source`/`--target` como aliases de `--from`/`--to`
- DEFINIR `--weight` opcional para peso da relação (padrão 0.5)
- TRATAR exit code 4 como entidade inexistente (sem `--create-missing`)
### OBRIGATÓRIO — Exportação com graph
- EXPORTAR snapshot via `graph --format json`
- USAR `--format dot` para Graphviz offline
- USAR `--format mermaid` para embutir em Markdown
- GRAVAR direto em arquivo via `--output <PATH>`
- INSPECIONAR `nodes` e `edges` no JSON exportado
### OBRIGATÓRIO — Enumeração de Entidades (graph entities)
- USAR `graph entities --json` para listar todas as entidades
- ACESSAR via `jaq -r '.entities[].name'` (campo é `entities`, NÃO `items`)
- FILTRAR por `--entity-type <tipo>` quando necessário
- PAGINAR com `--limit` e `--offset`
- USAR antes de planejar travessias ou links em lote
### OBRIGATÓRIO — Estatísticas (graph stats)
- USAR `graph stats --json` antes de travessias caras
- INSPECIONAR `node_count`, `edge_count`, `avg_degree`, `max_degree`
- ESCOLHER profundidade de travessia baseada em densidade real
- DETECTAR isolamento de subgrafos antes de planejar buscas
### Vocabulário Canônico de Relações
- `applies-to`, `uses`, `depends-on`, `causes`, `fixes`, `contradicts`
- `supports`, `follows`, `related`, `mentions`, `replaces`, `tracked-in`
### Tipos Válidos de Entidade
- `project`, `tool`, `person`, `file`, `concept`, `incident`
- `decision`, `memory`, `dashboard`, `issue_tracker`
- `organization`, `location`, `date`


## Daemon e Latência Reduzida
### OBRIGATÓRIO — Reuso do Modelo de Embeddings
- INICIAR `sqlite-graphrag daemon` em sessões longas de agente
- VERIFICAR saúde via `daemon --ping --json`
- ENCERRAR via `daemon --stop` ao fim da sessão
- DEIXAR `init`, `remember`, `ingest`, `recall`, `hybrid-search` reusarem automaticamente
- TRATAR daemon como opcional para invocações single-shot
- INSPECIONAR contador de embedding requests no `--ping`


## Cache — Gestão de Modelos
### OBRIGATÓRIO — Manutenção de Cache
- LISTAR modelos em cache via `cache list --json`
- REMOVER cache de modelos via `cache clear-models --json`
- `clear-models` força re-download na próxima operação de embedding
- USAR `cache list` para diagnosticar uso de disco por modelos ONNX


## Contrato JSON e Pipelines
### OBRIGATÓRIO — Saída Determinística
- USAR `--json` em todos os subcomandos antes de piping
- PREFERIR `--json` sobre `--format json` em one-liners
- FILTRAR campos via `jaq` em vez de regex sobre stdout
- LER apenas campos efetivamente retornados pelo subcomando
- TRATAR JSON como API versionada por SemVer
### OBRIGATÓRIO — Matriz --json versus --format json
- `--json` é aceito por TODOS os subcomandos
- `--format json` aceito apenas em subset com `--format`
- QUANDO ambos presentes, `--json` vence em conflito
- USAR `--json` por padrão em pipelines portáteis
### OBRIGATÓRIO — Distinção Entre JSON e NDJSON
- COMANDOS individuais emitem JSON envelope único no stdout
- `ingest` emite NDJSON, uma linha JSON por arquivo mais summary no stdout
- CONSUMIR NDJSON via `jaq -c` ou `while read -r linha`
- AGREGAR NDJSON em array via `jaq -s` quando necessário
### OBRIGATÓRIO — Campos Críticos por Comando
- `recall` retorna `results[].name`, `snippet`, `distance`, `score`, `source` (`"direct"`/`"graph"`), `graph_depth?`
- `recall` response-level: `query`, `k`, `direct_matches[]`, `graph_matches[]`, `results[]`, `elapsed_ms`
- `hybrid-search` retorna `results[].name`, `combined_score`, `score`, `vec_rank`, `fts_rank`, `source`, `body`
- `hybrid-search` response-level: `query`, `k`, `rrf_k`, `weights`, `results[]`, `graph_matches[]`, `elapsed_ms`
- `hybrid-search` `graph_matches[]` usa RecallItem: `name`, `distance`, `source` ("graph"), `graph_depth`
- `related` retorna `results[].name`, `hop_distance`, `relation`, `source_entity`, `target_entity`, `weight`
- `graph traverse` retorna `hops[].entity`, `relation`, `direction`, `weight`, `depth`
- `read` retorna `name`, `body`, `description`, `created_at_iso`, `updated_at_iso`
- `edit` retorna `memory_id`, `name`, `action` ("updated"), `version`, `elapsed_ms`
- `rename` retorna `memory_id`, `name` (novo), `action` ("renamed"), `version`, `elapsed_ms`
- `forget` retorna `action` (`"soft_deleted"`/`"already_deleted"`), `forgotten`, `name`, `namespace`, `elapsed_ms`
- `health` retorna `integrity_ok`, `schema_ok`, `vec_memories_ok`, `vec_entities_ok`, `vec_chunks_ok`, `fts_ok`, `model_ok`, `counts`, `wal_size_mb`, `journal_mode`, `db_path`, `db_size_bytes`, `checks[]`
- `health.counts` contém: `memories`, `entities`, `relationships`, `vec_memories`
- `stats` retorna dados GLOBAIS (sem filtro por namespace): `memories`, `entities`, `relationships`, `chunks_total`, `avg_body_len`, `namespaces[]`, `db_size_bytes`, `schema_version`, `elapsed_ms`
- `ingest` por arquivo: `file`, `name`, `status` (`"indexed"`/`"skipped"`/`"failed"`), `truncated`, `original_name?`, `memory_id?`, `action?`, `error?`
- `ingest` summary: `summary` (true), `files_total`, `files_succeeded`, `files_failed`, `files_skipped`, `elapsed_ms`
- `cache list` retorna modelos com tamanho em bytes e total de disco


## Códigos de Saída e Estratégia de Retry
### OBRIGATÓRIO — Tratamento Completo de Exit Codes
- `0` igual sucesso, parsear stdout
- `1` igual validação (peso inválido, self-link, timezone ruim, max-files excedido)
- `2` igual duplicata (memória já existe sem `--force-merge`)
- `3` igual conflito de locking otimista, recarregar e repetir
- `4` igual entidade, memória ou versão não encontrada
- `5` igual erro de namespace (nome inválido ou conflito)
- `6` igual payload acima do limite de tamanho
- `10` igual erro de database, executar `vacuum` e `health`
- `11` igual falha de embedding (modelo corrompido ou ORT ausente)
- `12` igual falha ao carregar `sqlite-vec`, verificar SQLite ≥ 3.40
- `13` igual falha parcial em batch, reprocessar apenas falhos
- `14` igual erro de I/O (arquivo inacessível, permissão, disco cheio)
- `15` igual banco ocupado (busy), ampliar `--wait-lock`
- `20` igual erro interno ou falha de serialização JSON
- `75` igual slots exauridos no ingest ou outro pesado
- `77` igual pressão de RAM, aguardar memória livre
### PROIBIDO — Anti-padrões de Erro
- NUNCA ignorar exit code não-zero como sucesso
- NUNCA reprocessar lote inteiro após exit 13
- NUNCA aumentar concorrência após receber 75 ou 77
- NUNCA tentar `restore` sem inspecionar `history` antes
- NUNCA culpar ambiguidade sem ler stderr primeiro
- NUNCA confundir exit 1 (validação) com exit 2 (duplicata)


## Concorrência e Recursos
### OBRIGATÓRIO — Controle de Carga
- INICIAR comandos pesados com `--max-concurrency 1`
- AUMENTAR apenas após medir RSS e swap do host
- RESPEITAR teto rígido de `2×nCPUs` em comandos pesados
- TRATAR `init`, `remember`, `ingest`, `recall`, `hybrid-search` como pesados
- AMPLIAR `--wait-lock <ms>` quando contenção for esperada
- LIMITAR ingestão paralela em CI sem daemon ativo
### OBRIGATÓRIO — Dois Eixos de Paralelismo no ingest
- `--max-concurrency` governa invocações CLI simultâneas
- `--ingest-parallelism` governa extract mais embed paralelos
- AJUSTAR ambos independentemente conforme RAM e CPU
- USAR `--low-memory` para forçar paralelismo unitário
- HONRAR `SQLITE_GRAPHRAG_LOW_MEMORY=1` em hosts restritos


## Manutenção e Backup
### OBRIGATÓRIO — Higiene Periódica
- AGENDAR `purge --retention-days 30 --yes` semanalmente
- EXECUTAR `vacuum` após purges grandes
- RODAR `optimize` para refrescar estatísticas do planner
- LIMPAR órfãos via `cleanup-orphans --yes` após forget em massa
### OBRIGATÓRIO — Backup Seguro
- USAR `sync-safe-copy --dest <path>` antes de sincronizar Dropbox ou iCloud
- COMPRIMIR snapshots via `ouch compress` para upload remoto
- EXPORTAR memórias via `list --limit 10000 --json` para NDJSON
- VERSIONAR banco com Git LFS quando viável
### OBRIGATÓRIO — Diagnóstico de Schema
- USAR `__debug_schema --json` para troubleshooting
- INSPECIONAR `schema_version`, `objects`, `migrations`
- COMANDO oculto do `--help`, invocar pelo nome exato
### Padrão Correto — Cron Semanal
- `sqlite-graphrag purge --retention-days 30 --yes`
- `sqlite-graphrag cleanup-orphans --yes`
- `sqlite-graphrag vacuum --json`
- `sqlite-graphrag optimize --json`
- `sqlite-graphrag sync-safe-copy --dest ~/Dropbox/graphrag.sqlite`


## Contrato: Stdin e Stdout
### Entrada — Apenas Argumentos Estruturados
- Flags da CLI aceitam argumentos tipados validados por `clap` com parsing estrito
- Stdin aceita body puro quando `--body-stdin` está ativo em `remember` ou `edit`
- Stdin aceita objeto JSON de grafo com `body` opcional, `entities` e `relationships` quando `--graph-stdin` está ativo em `remember`; JSON inválido falha em vez de virar body de memória
- Fontes de corpo como `--body`, `--body-file`, `--body-stdin` e `--graph-stdin` são rejeitadas quando combinadas de forma ambígua
- `remember` aceita payloads de body até `512000` bytes e até `512` chunks; payloads maiores retornam exit code `6`
- Variáveis de ambiente sobrescrevem defaults sem mutar o arquivo do banco de dados
- O caminho padrão do banco é sempre `./graphrag.sqlite` no diretório atual de invocação
- Idioma é controlado por `--lang <en|pt|pt-BR|portuguese|PT|pt-br>` para saída determinística


### Saída — Documentos JSON Determinísticos
- Cada subcomando emite exatamente um documento JSON quando `--json` está ativo
- Chaves permanecem estáveis entre releases dentro da mesma linha major corrente
- Timestamps seguem RFC 3339 com offset UTC sempre presente e explícito
- Campos opcionais podem ser omitidos ou serializados como `null`; agentes devem aceitar ambas as formas
- Arrays preservam ordem determinística por `score` ou `updated_at` descendente


## Tabela de Exit Codes
### Contrato — Mapeie Cada Status A Uma Decisão De Roteamento
| Código | Significado | Ação Recomendada |
| --- | --- | --- |
| `0` | Sucesso | Continue o loop do agente |
| `1` | Falha de validação ou runtime | Logue e exiba ao operador |
| `2` | Erro de uso CLI ou duplicata | Corrija argumentos e repita |
| `3` | Conflito de optimistic update | Releia `updated_at` e repita |
| `4` | Memória ou entidade não encontrada | Trate recurso ausente graciosamente |
| `5` | Limite de namespace ou não resolvido | Passe `--namespace` explicitamente |
| `6` | Payload excedeu os limites permitidos | Divida o body em chunks menores |
| `10` | Erro SQLite no banco de dados | Rode `health` para inspecionar integridade |
| `11` | Falha na geração de embedding | Verifique arquivos do modelo e repita |
| `12` | Extensão `sqlite-vec` falhou | Reinstale o binário com extensão embutida |
| `13` | Operação em batch parcialmente falhou | Inspecione resultados parciais e repita os itens falhos |
| `14` | Erro de I/O (arquivo, permissão, disco cheio) | Verifique acesso ao arquivo e espaço em disco disponível |
| `15` | Banco ocupado após tentativas | Aguarde e repita a operação |
| `20` | Erro interno ou falha de serialização | Reporte bug com saída completa do stderr |
| `75` | Lock advisory ocupado ou todos os slots preenchidos | Aguarde e repita, ou reduza a pressão dos comandos pesados em vez de elevar a concorrência cegamente |
| `77` | Limite de memória baixo acionado | Libere RAM antes de repetir |


## Formato De Saída JSON
### Recall — KNN Vetorial Puro
```json
{
  "query": "graphrag retrieval",
  "k": 3,
  "direct_matches": [
    { "memory_id": 1, "name": "graphrag-intro", "namespace": "global", "type": "user", "description": "intro doc", "snippet": "GraphRAG combines...", "distance": 0.09, "source": "vec" }
  ],
  "graph_matches": [],
  "results": [
    { "memory_id": 1, "name": "graphrag-intro", "namespace": "global", "type": "user", "description": "intro doc", "snippet": "GraphRAG combines...", "distance": 0.09, "source": "vec" }
  ],
  "elapsed_ms": 12
}
```


### Hybrid Search — FTS5 Mais Vetor Via RRF
```json
{
  "query": "postgres migration",
  "k": 5,
  "rrf_k": 60,
  "weights": { "vec": 1.0, "fts": 1.0 },
  "results": [
    { "memory_id": 1, "name": "postgres-migration-plan", "namespace": "global", "type": "project", "description": "migration plan", "body": "Step 1...", "combined_score": 0.96, "score": 0.96, "source": "hybrid", "vec_rank": 1, "fts_rank": 1 },
    { "memory_id": 2, "name": "db-migration-checklist", "namespace": "global", "type": "reference", "description": "checklist", "body": "Check indexes...", "combined_score": 0.88, "score": 0.88, "source": "hybrid", "vec_rank": 2, "fts_rank": 3 }
  ],
  "graph_matches": [],
  "elapsed_ms": 18
}
```


## Idempotência e Efeitos Colaterais
### Comandos Read-Only — Zero Mutação Garantida
- `recall` lê tabelas de vetor e metadados sem tocar o estado em disco
- `read` busca uma única linha por nome e emite JSON sem efeito colateral
- `list` pagina memórias ordenadas deterministicamente com cursores estáveis
- `health` roda `PRAGMA integrity_check` e reporta sem escrever em disco
- `stats` conta linhas em transações read-only seguras para agentes concorrentes


### Comandos Write — Optimistic Locking Protege Concorrência
- `remember` usa `ON CONFLICT(name)` então chamadas duplicadas retornam exit code `2`
- `rename` exige `--expected-updated-at` para detectar escrita stale via exit `3`
- `edit` cria nova linha em `memory_versions` preservando histórico imutável
- `restore` retrocede o conteúdo criando uma nova versão em vez de sobrescrever
- `forget` é soft-delete então repetir a chamada é seguro e idempotente por design


## Limites De Payload
### Tetos — Aplicados Pelo Binário
- `EMBEDDING_MAX_TOKENS` vale 512 tokens medidos pelo tokenizador do modelo
- `TEXT_BODY_PREVIEW_LEN` vale 200 caracteres em snippets de list e recall
- `MAX_CONCURRENT_CLI_INSTANCES` vale como teto rígido de 4 entre agentes subprocess cooperando, mas comandos pesados podem ser reduzidos dinamicamente pela RAM disponível
- `CLI_LOCK_DEFAULT_WAIT_SECS` vale 300 segundos antes do exit code `75`
- `PURGE_RETENTION_DAYS_DEFAULT` vale 90 dias antes do hard delete ficar permitido


## Controle De Idioma
### Saída Bilíngue — Uma Flag Troca O Locale
- Flag `--lang en` força mensagens em inglês independentemente do locale do sistema
- Flag `--lang pt` ou `--lang pt-BR` ou `--lang portuguese` ou `--lang PT` força mensagens em português
- Códigos curtos `en` e `pt` são as formas canônicas; os aliases mais longos são aceitos sem erro
- Env `SQLITE_GRAPHRAG_LANG=pt` sobrescreve locale do sistema quando falta `--lang`
- Sem flag e sem env cai no fallback por `sys_locale::get_locale()` do runtime
- Locales desconhecidos caem em inglês sem emitir warning algum no stderr
- Env `SQLITE_GRAPHRAG_DISPLAY_TZ=America/Sao_Paulo` define o fuso IANA aplicado a todos os campos `*_iso` no JSON de saída
- A flag `--tz <IANA>` tem prioridade sobre `SQLITE_GRAPHRAG_DISPLAY_TZ`; ambos caem para UTC quando ausentes
- Nomes IANA inválidos causam exit 2 com mensagem de erro `Validation` antes de qualquer comando executar
- Apenas campos string `*_iso` são afetados; campos epoch inteiros (`created_at`, `updated_at`) permanecem inalterados
- Env `SQLITE_GRAPHRAG_LOG_FORMAT=json` alterna saída de tracing para JSON delimitado por linha; padrão é `pretty`


## Contrato de Runtime em ARM64 GNU
### Carregamento Dinâmico do ONNX Runtime — O Que Agentes DEVEM Fornecer
- Em `aarch64-unknown-linux-gnu`, comandos de embedding NÃO dependem de linkedição do ONNX Runtime no build
- Agentes DEVEM tornar `libonnxruntime.so` alcançável via `ORT_DYLIB_PATH`, diretório do executável, `./lib/` ou diretório de cache de modelos
- Os comandos pesados afetados são `init`, `remember`, `recall` e `hybrid-search`
- Se a biblioteca compartilhada estiver ausente, a primeira operação de embedding falha em runtime mesmo com a binária iniciando corretamente


## Flag de Saída JSON
### Formato — `--json` É Universal e `--format json` É Específico por Comando
- Todos os subcomandos aceitam `--json` para JSON determinístico no stdout
- Apenas comandos que expõem `--format` no help aceitam `--format json`
- `--json` é a forma curta — preferida em one-liners e pipelines de agentes
- Se `--json` aparece com um `--format` não JSON, `--json` vence e stdout continua JSON
- `--format json` é a forma explícita — específica por comando, preferida onde também existem outros modos de saída


## Payloads de Entrada do Grafo
### Contrato — Arquivos do `remember`
- `--entities-file` aceita um array JSON de objetos de entidade
- Cada objeto de entidade DEVE incluir `name` e `entity_type`
- O campo alias `type` é aceito como sinônimo de `entity_type`
- Agentes NÃO DEVEM enviar `entity_type` e `type` no mesmo objeto de entidade
- Valores válidos para `entity_type` são `project`, `tool`, `person`, `file`, `concept`, `incident`, `decision`, `memory`, `dashboard`, `issue_tracker`, `organization`, `location` e `date`
- `--relationships-file` aceita um array JSON de objetos de relacionamento
- Cada objeto de relacionamento DEVE incluir `source`/`from`, `target`/`to`, `relation` e `strength`
- `strength` DEVE ser número de ponto flutuante no intervalo inclusivo `[0.0, 1.0]`
- As saídas do grafo expõem esse valor como `weight`
- Payloads de arquivo PODEM usar nomes canônicos persistidos com underscore como `applies_to`, `depends_on` e `tracked_in`; aliases com hífen são normalizados antes da gravação
- Flags CLI de `link` e `unlink` usam rótulos com hífen como `applies-to`, `depends-on` e `tracked-in`
- `--graph-stdin` aceita um único objeto com `body` opcional e os mesmos arrays `entities` e `relationships`
- `link --create-missing` cria automaticamente entidades inexistentes durante a linkagem, com tipo padrão `concept`; use `--entity-type` para sobrescrever (adicionado em v1.0.44)
- `hybrid-search --with-graph` habilita graph traversal a partir dos top resultados RRF; matches do grafo aparecem no array `graph_matches` junto ao array `results` (corrigido em v1.0.44 — era um no-op antes)
- `graph entities` JSON response usa chave top-level `entities` (renomeado de `items` em v1.0.44); atualize scripts `jaq` existentes de `.items[]` para `.entities[]`


## Schemas Legíveis por Máquina
### Arquivos JSON Schema Draft 2020-12 Para Cada Subcomando
- O diretório `docs/schemas/` contém um arquivo `.schema.json` por subcomando
- Todo schema declara `"additionalProperties": false` — chaves desconhecidas são violações de contrato
- Schemas usam `$defs` para subtipos compartilhados (ex: `RecallItem`, `HealthCheck`)
- Campos opcionais ficam fora do array `required` e são tipados com `["T", "null"]` quando anuláveis
- Validar resposta em tempo real com um validador JSON Schema real: `jsonschema --instance <(sqlite-graphrag stats) docs/schemas/stats.schema.json`
- O arquivo `docs/schemas/debug-schema.schema.json` cobre o subcomando diagnóstico oculto `__debug_schema`
- Schemas são atualizados a cada breaking change e seguem a versão major SemVer da CLI


## Resumo Dos Superpoderes
### Cinco Razões Para Seu Orquestrador Permanecer
- Saída determinística elimina parsing frágil por regex no código de glue do agente
- Exit codes roteiam decisões sem raspar stderr por mensagens legíveis a humanos
- Binário único implanta idêntico em Docker GitHub Actions e laptops de dev
- Durabilidade do SQLite sobrevive a kernel panic e kill de container sem corromper
- Retrieval por grafo revela contexto multi-hop que o vetor puro jamais devolve


## Comece Em 30 Segundos
### Instalação — Um Comando Instala A Stack Inteira
```bash
cargo install --path . && sqlite-graphrag init
```
- Flag `--locked` reusa o `Cargo.lock` enviado para proteger MSRV de drift transitivo
- Comando `init` cria `graphrag.sqlite` no diretório atual e baixa o modelo de embedding localmente
- Primeira invocação pode levar um minuto enquanto `fastembed` baixa `multilingual-e5-small`
- Invocações seguintes evitam apenas o primeiro download do modelo, mas comandos pesados ainda dependem da residência do modelo e do daemon
- Remova com `cargo uninstall sqlite-graphrag` deixando o arquivo de banco intacto