sqlite-graph-memory 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. sqlite_graph_memory-0.3.0/.gitignore +11 -0
  2. sqlite_graph_memory-0.3.0/CHANGELOG.md +150 -0
  3. sqlite_graph_memory-0.3.0/CITATION.cff +29 -0
  4. sqlite_graph_memory-0.3.0/LICENSE +21 -0
  5. sqlite_graph_memory-0.3.0/PKG-INFO +452 -0
  6. sqlite_graph_memory-0.3.0/README.md +403 -0
  7. sqlite_graph_memory-0.3.0/bench/README.md +170 -0
  8. sqlite_graph_memory-0.3.0/bench/requirements.txt +6 -0
  9. sqlite_graph_memory-0.3.0/docs/RELEASING.md +57 -0
  10. sqlite_graph_memory-0.3.0/docs/bitemporal.md +119 -0
  11. sqlite_graph_memory-0.3.0/eval/build_gold.py +225 -0
  12. sqlite_graph_memory-0.3.0/eval/run_eval.py +285 -0
  13. sqlite_graph_memory-0.3.0/examples/README.md +106 -0
  14. sqlite_graph_memory-0.3.0/examples/claude-code-stop-hook.json +17 -0
  15. sqlite_graph_memory-0.3.0/examples/mcp-config.json +13 -0
  16. sqlite_graph_memory-0.3.0/pyproject.toml +80 -0
  17. sqlite_graph_memory-0.3.0/requirements.txt +4 -0
  18. sqlite_graph_memory-0.3.0/src/sqlite_graph_memory/__init__.py +26 -0
  19. sqlite_graph_memory-0.3.0/src/sqlite_graph_memory/brain_ask.py +310 -0
  20. sqlite_graph_memory-0.3.0/src/sqlite_graph_memory/index_notes.py +151 -0
  21. sqlite_graph_memory-0.3.0/src/sqlite_graph_memory/mcp_server.py +271 -0
  22. sqlite_graph_memory-0.3.0/src/sqlite_graph_memory/schema.sql +45 -0
  23. sqlite_graph_memory-0.3.0/src/sqlite_graph_memory/turnstate_hook.py +243 -0
  24. sqlite_graph_memory-0.3.0/src/sqlite_graph_memory/turnstate_show.py +85 -0
  25. sqlite_graph_memory-0.3.0/tests/test_bench.py +67 -0
  26. sqlite_graph_memory-0.3.0/tests/test_brain_ask.py +111 -0
  27. sqlite_graph_memory-0.3.0/tests/test_eval.py +247 -0
  28. sqlite_graph_memory-0.3.0/tests/test_index_notes.py +71 -0
  29. sqlite_graph_memory-0.3.0/tests/test_mcp_server.py +269 -0
  30. sqlite_graph_memory-0.3.0/tests/test_optional_extra.py +91 -0
@@ -0,0 +1,11 @@
1
+ index/
2
+ turnstate.db
3
+ _brain_answer.txt
4
+ ab_last.json
5
+ .env
6
+ __pycache__/
7
+ *.pyc
8
+ eval/gold-*.jsonl
9
+ eval/scores-*.jsonl
10
+ dist/
11
+ *.egg-info/
@@ -0,0 +1,150 @@
1
+ # Changelog
2
+
3
+ What shipped, in plain words. Entries below v0.1.3 were written on 2026-09-05 from the tags and
4
+ release notes that already existed — the file itself did not exist until then, so those three are
5
+ recorded after the fact rather than backdated to look contemporaneous.
6
+
7
+ ## bench-v0.1 — 2026-10-09
8
+
9
+ **A benchmark other people can run.** Until now every retrieval number in this repo came from
10
+ one private vault, so nobody could check them. `bench/` ships a generated 202-note vault about a
11
+ fictional lab, 91 questions in seven classes (22 of them have no answer in the vault), and a
12
+ leaderboard. `python bench/run.py --system bm25` runs end to end with nothing installed.
13
+
14
+ **You submit outputs, not numbers.** Each result file carries every per-question output, and
15
+ `bench/validate.py` recomputes every metric with the same scorer. CI rejects any file whose
16
+ claimed numbers do not follow from its own outputs, and a self-test forges a real result thirteen
17
+ ways on every push to prove the gate still catches it.
18
+
19
+ **The baseline is honest about itself.** sqlite-graph-memory retrieves both the old and the new
20
+ decision on "current deadline" questions and quotes the old one 6 times out of 6. It also
21
+ abstains on every paraphrased question, and it answers 55% of questions whose fact is missing.
22
+ On this vault, vector-only ranks ahead of graph mode. All of it is written out in
23
+ `bench/README.md`. Closes #16.
24
+
25
+ ## v0.3.0 — 2026-10-07
26
+
27
+ **You can install it now.** For three months this was a repository you had to clone, and for
28
+ an engineer deciding whether to try something, a clone is a much bigger ask than a command.
29
+ There is now a `pyproject.toml`, the modules live in `src/sqlite_graph_memory/`, and
30
+ `pip install sqlite-graph-memory` gives you five commands: `sgm-index`, `sgm-ask`,
31
+ `sgm-mcp`, `sgm-turnstate-hook` and `sgm-turnstate-show`.
32
+
33
+ **The MCP server moved inside the package.** It used to sit in `examples/` and shell out to
34
+ `../brain_ask.py`, which meant the one integration most agents actually use — the MCP tool —
35
+ only worked from a checkout. It is now `sgm-mcp`, so the client config is a command name
36
+ instead of a path into someone's clone, and the Stop-hook snippet lost its `/path/to/` too.
37
+
38
+ **The heavy half is optional, and says so.** The base install is numpy and nothing else,
39
+ about 20 MB; `sentence-transformers` and `torch` (~2 GB) come from
40
+ `pip install 'sqlite-graph-memory[embeddings]'`. Running the indexer without the extra used
41
+ to end in a `ModuleNotFoundError` traceback through site-packages — which reads like a broken
42
+ package rather than a missing option — and now ends in one line naming the extra to install.
43
+ `tests/test_optional_extra.py` covers that path, including the case it must *not* swallow: an
44
+ unrelated missing module still surfaces as itself, instead of sending you after the wrong fix.
45
+
46
+ **CI now proves the package is installable, not just that the tests pass.** A wheel can break
47
+ without a single test failing — a bad entry point, a file left out of the build, a dependency
48
+ that only exists on the author's machine. The new `installable` job builds the distributions,
49
+ runs `twine check`, installs the wheel into a venv with nothing else in it, and checks that
50
+ all five commands start, that `schema.sql` travelled with the wheel, and that a base install
51
+ prints instructions rather than a traceback.
52
+
53
+ ## v0.2.1 — 2026-10-02
54
+
55
+ **The suite stopped being something a human remembers to run.** The 84 tests and the eval suite had
56
+ only ever been run by hand. `.github/workflows/tests.yml` now runs them on every push against
57
+ Python 3.11, 3.12 and 3.13, and carries one unusual step: it sets `EVAL_MUTANT=1`, which breaks the
58
+ retrieval pipeline on purpose, and fails the build if the eval suite still comes back green. A test
59
+ that has never been seen red is not evidence, so CI proves the red before it trusts the green.
60
+
61
+ - **Read this with AI**: a one-click entry point into Codex, ChatGPT or Claude with a prompt that
62
+ asks the agent to extract the reusable patterns, plus the raw prompt for any other model, and a
63
+ line pointing at the neighbouring repos in the memory layer.
64
+ - A date correction in the docs was reverted on 30 September: the original date was right, and the
65
+ machine that "fixed" it was the one with the wrong clock.
66
+
67
+ ## v0.2.0 — 2026-09-20
68
+
69
+ **An eval, and the seven upgrades it talked us out of.** `eval/build_gold.py` turns the vault's own
70
+ `[[wikilinks]]` into a retrieval test set — no hand labelling, no LLM calls — and `eval/run_eval.py`
71
+ scores it as Recall@12 / MRR / nDCG@12 in both retrieval modes, vector-only and vector+graph.
72
+
73
+ - **The eval imports the pipeline instead of copying it.** `brain_ask.py` keeps exactly the
74
+ behaviour it had (proven byte-for-byte on nine runs over a 10 918-chunk index), but its stages are
75
+ now importable functions — `load_index`, `query_sims`, `retrieve_candidates`, `index_by_basename`,
76
+ `expand_1hop`, `rerank_candidates` — and `main()` is a CLI over them. An eval that re-implements
77
+ the pipeline measures the re-implementation.
78
+ - **Four question classes**, because "does the graph help?" has four different answers: `title`,
79
+ `body`, `bridge` (the note's own links are the gold answers) and `temporal` (a `superseded_by`
80
+ frontmatter field points at the replacement).
81
+ - **The README now carries real numbers** from the home vault: what two changes improved (bridge
82
+ Recall@12 0.251 -> 0.451) and what seven changes that "obviously should have helped" measurably did
83
+ not — BGE-M3, two rerankers, a BM25 hybrid, a heading-path chunker, `sqlite-vec`, and more.
84
+ - **The ruler is testable too.** `EVAL_MUTANT=1` breaks nDCG deliberately, and `tests/test_eval.py`
85
+ must go red under it: a suite that stays green while the metric is broken never tested the metric.
86
+
87
+ - **An external review panel broke the ruler before anyone else could.** Two engines
88
+ independently found that `ndcg_at` credited the same gold note twice when one filename
89
+ appeared twice in the ranking — which, since wikilinks address notes by filename, happens as
90
+ soon as two folders hold a `foo.md`. `ndcg_at(['foo','foo'], ['foo'])` returned 1.63. Fixed,
91
+ with the published title/temporal numbers corrected downward (0.921 -> 0.890 and 0.638 ->
92
+ 0.531); the before/after deltas were unaffected, because the same four questions of 184
93
+ inflated both runs. Also from that review: ambiguous filenames are now excluded from gold
94
+ and reported, a truncated `bridge` gold set records how many links were cut (9 of 30
95
+ questions on our own vault), a run where the graph never fired says so instead of printing
96
+ "the graph adds nothing", and an `EVAL_MUTANT=1` run refuses to write history at all.
97
+
98
+ **The MCP server got a runtime, examples, and three fixes to how it reports nothing.**
99
+ `examples/` now carries a runnable MCP server and its own README, so the recall pipeline is
100
+ reachable from an agent harness without reading the source first
101
+ ([#5](https://github.com/tonydzi/sqlite-graph-memory/issues/5)).
102
+
103
+ - **The answer file was shared between calls.** Two recalls in flight wrote the same path, so one
104
+ could return the other's text. It is scoped per call now, and `tests/test_mcp_server.py` pins the
105
+ filename so the race can actually fail a test instead of passing on timing.
106
+ - **Empty is not an error, and an error is not empty.** An empty answer file used to fall back to
107
+ whatever was on stdout, which meant a log line could come back as a recall result; the server
108
+ returns `isError` instead
109
+ ([#9](https://github.com/tonydzi/sqlite-graph-memory/issues/9)). A file it could not read is now
110
+ reported separately from a recall that genuinely found nothing
111
+ ([#13](https://github.com/tonydzi/sqlite-graph-memory/issues/13)).
112
+ - **The paper is out.** A JOSS draft (`paper.md` and its bibliography) with a readiness checklist,
113
+ and `CITATION.cff` plus a cite section pointing at
114
+ [10.5281/zenodo.22639718](https://doi.org/10.5281/zenodo.22639718).
115
+ - `brain_ask.py`'s `looks_like_entity` and `_links_in` are covered by tests, and the README
116
+ describes its test coverage by shape instead of by a count that rots.
117
+
118
+ ## v0.1.3 — 2026-09-05
119
+
120
+ Two ways the indexer quietly answered with the wrong text. Both were found on a real synced vault,
121
+ not in review, and both now have tests that run with no model download and no network.
122
+
123
+ - **Not everything ending in `.md` is a note.** The walk was a plain `rglob('*.md')`, which descends
124
+ into dot-directories. On an Obsidian vault synced with Syncthing that pulled in `.stversions/`
125
+ (Syncthing's old revisions), `*.sync-conflict-*` copies, `.obsidian/` plugin cache and `.git/`
126
+ internals. This is worse than noise: a stale revision of a note is semantically almost identical
127
+ to the live one, so it lands next to it in the top-K and answers the question with outdated
128
+ content. Now skipped. `BRAIN_INDEX_HIDDEN=1` opts back in, because someone will legitimately
129
+ keep notes in a hidden folder.
130
+ - **A byte-order mark ate the frontmatter.** Notes were read as plain `utf-8`, so a BOM'd file kept
131
+ a leading U+FEFF and its first line was no longer `---`. The frontmatter regex then saw a note
132
+ with no frontmatter and dropped its date and title, silently. Reading as `utf-8-sig` fixes it.
133
+ - Closes [#1](https://github.com/tonydzi/sqlite-graph-memory/issues/1) and
134
+ [#2](https://github.com/tonydzi/sqlite-graph-memory/issues/2) (the smoke test that needs no model).
135
+
136
+ The two behaviours are now `iter_notes` and `read_note`, which is what made them testable at all —
137
+ `tests/test_index_notes.py`, seven cases shaped like a real synced vault.
138
+
139
+ ## v0.1.2 — 2026-08-25
140
+
141
+ The bilingual regex, explained.
142
+
143
+ ## v0.1.1 — 2026-08-04
144
+
145
+ The design note, and everything a stranger needs to run the pilot.
146
+
147
+ ## v0.1.0 — 2026-08-04
148
+
149
+ The pilot as first published on 3 July 2026. Tagged a month later; the code did not change in
150
+ between, the tag was simply never cut.
@@ -0,0 +1,29 @@
1
+ cff-version: 1.2.0
2
+ message: "If you use sqlite-graph-memory in research or software, please cite it as below."
3
+ title: "sqlite-graph-memory"
4
+ type: software
5
+ authors:
6
+ - family-names: Dziatkovskii
7
+ given-names: Anton
8
+ orcid: "https://orcid.org/0000-0001-7408-3054"
9
+ affiliation: "Palo Alto AI Research Lab"
10
+ repository-code: "https://github.com/tonydzi/sqlite-graph-memory"
11
+ url: "https://github.com/tonydzi/sqlite-graph-memory"
12
+ abstract: >-
13
+ Graph RAG on SQLite for AI agents: vector retrieval + hand-curated wikilink graph + cross-encoder rerank, with a zero-token per-turn memory ledger. Working pilot.
14
+ license: MIT
15
+ keywords:
16
+ - retrieval-augmented generation
17
+ - graph RAG
18
+ - SQLite
19
+ - personal knowledge management
20
+ - wikilinks
21
+ references:
22
+ - type: article
23
+ title: "When Does Graph Expansion Help Personal-Corpus Retrieval? A Query-Class-Stratified Evaluation Protocol for Retrieval over Human-Curated Wikilink Graphs, with Pilot Telemetry from a Production Deployment"
24
+ authors:
25
+ - family-names: Dziatkovskii
26
+ given-names: Anton
27
+ year: 2026
28
+ doi: "10.5281/zenodo.22639718"
29
+ notes: "The paper about this system and its evaluation protocol (preprint, CC BY 4.0)."
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Palo Alto AI Research Lab
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.