homestead-memory 0.2.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 (68) hide show
  1. homestead_memory-0.2.0/LICENSE +21 -0
  2. homestead_memory-0.2.0/PKG-INFO +272 -0
  3. homestead_memory-0.2.0/README.md +242 -0
  4. homestead_memory-0.2.0/pyproject.toml +44 -0
  5. homestead_memory-0.2.0/setup.cfg +4 -0
  6. homestead_memory-0.2.0/src/homestead_memory/__init__.py +10 -0
  7. homestead_memory-0.2.0/src/homestead_memory/adapters/__init__.py +13 -0
  8. homestead_memory-0.2.0/src/homestead_memory/adapters/autogen_memory.py +118 -0
  9. homestead_memory-0.2.0/src/homestead_memory/adapters/crewai_memory.py +62 -0
  10. homestead_memory-0.2.0/src/homestead_memory/adapters/langgraph_store.py +304 -0
  11. homestead_memory-0.2.0/src/homestead_memory/adapters/litellm_memory.py +110 -0
  12. homestead_memory-0.2.0/src/homestead_memory/adapters/okf.py +147 -0
  13. homestead_memory-0.2.0/src/homestead_memory/adapters/openai_agents.py +81 -0
  14. homestead_memory-0.2.0/src/homestead_memory/adapters/openai_compat.py +110 -0
  15. homestead_memory-0.2.0/src/homestead_memory/adapters/tools.py +138 -0
  16. homestead_memory-0.2.0/src/homestead_memory/api/__init__.py +1 -0
  17. homestead_memory-0.2.0/src/homestead_memory/api/mcp_server.py +362 -0
  18. homestead_memory-0.2.0/src/homestead_memory/api/server.py +211 -0
  19. homestead_memory-0.2.0/src/homestead_memory/benchmarks/__init__.py +1 -0
  20. homestead_memory-0.2.0/src/homestead_memory/benchmarks/longmemeval.py +589 -0
  21. homestead_memory-0.2.0/src/homestead_memory/benchmarks/official_eval.py +103 -0
  22. homestead_memory-0.2.0/src/homestead_memory/cli.py +434 -0
  23. homestead_memory-0.2.0/src/homestead_memory/core/__init__.py +1 -0
  24. homestead_memory-0.2.0/src/homestead_memory/core/chunking.py +111 -0
  25. homestead_memory-0.2.0/src/homestead_memory/core/distill.py +346 -0
  26. homestead_memory-0.2.0/src/homestead_memory/core/index.py +385 -0
  27. homestead_memory-0.2.0/src/homestead_memory/core/portability.py +376 -0
  28. homestead_memory-0.2.0/src/homestead_memory/core/provenance.py +59 -0
  29. homestead_memory-0.2.0/src/homestead_memory/core/remember.py +86 -0
  30. homestead_memory-0.2.0/src/homestead_memory/core/resolve.py +235 -0
  31. homestead_memory-0.2.0/src/homestead_memory/core/signing.py +172 -0
  32. homestead_memory-0.2.0/src/homestead_memory/core/store.py +141 -0
  33. homestead_memory-0.2.0/src/homestead_memory/core/telemetry.py +68 -0
  34. homestead_memory-0.2.0/src/homestead_memory/core/temporal.py +258 -0
  35. homestead_memory-0.2.0/src/homestead_memory/core/tuning.py +103 -0
  36. homestead_memory-0.2.0/src/homestead_memory/core/vault.py +302 -0
  37. homestead_memory-0.2.0/src/homestead_memory/core/verify.py +549 -0
  38. homestead_memory-0.2.0/src/homestead_memory/sdk.py +129 -0
  39. homestead_memory-0.2.0/src/homestead_memory.egg-info/PKG-INFO +272 -0
  40. homestead_memory-0.2.0/src/homestead_memory.egg-info/SOURCES.txt +66 -0
  41. homestead_memory-0.2.0/src/homestead_memory.egg-info/dependency_links.txt +1 -0
  42. homestead_memory-0.2.0/src/homestead_memory.egg-info/entry_points.txt +3 -0
  43. homestead_memory-0.2.0/src/homestead_memory.egg-info/requires.txt +22 -0
  44. homestead_memory-0.2.0/src/homestead_memory.egg-info/top_level.txt +1 -0
  45. homestead_memory-0.2.0/tests/test_adapters.py +137 -0
  46. homestead_memory-0.2.0/tests/test_cli_bench.py +54 -0
  47. homestead_memory-0.2.0/tests/test_distill.py +201 -0
  48. homestead_memory-0.2.0/tests/test_hot_swap_demo.py +59 -0
  49. homestead_memory-0.2.0/tests/test_index.py +305 -0
  50. homestead_memory-0.2.0/tests/test_litellm_memory.py +47 -0
  51. homestead_memory-0.2.0/tests/test_mcp.py +218 -0
  52. homestead_memory-0.2.0/tests/test_multi_agent_demo.py +19 -0
  53. homestead_memory-0.2.0/tests/test_okf.py +218 -0
  54. homestead_memory-0.2.0/tests/test_openai_compat.py +128 -0
  55. homestead_memory-0.2.0/tests/test_portability.py +155 -0
  56. homestead_memory-0.2.0/tests/test_provenance.py +134 -0
  57. homestead_memory-0.2.0/tests/test_provenance_compat.py +41 -0
  58. homestead_memory-0.2.0/tests/test_remember.py +219 -0
  59. homestead_memory-0.2.0/tests/test_resolve.py +244 -0
  60. homestead_memory-0.2.0/tests/test_rotbench_integrity.py +213 -0
  61. homestead_memory-0.2.0/tests/test_sdk.py +67 -0
  62. homestead_memory-0.2.0/tests/test_signing.py +236 -0
  63. homestead_memory-0.2.0/tests/test_store_newlines.py +18 -0
  64. homestead_memory-0.2.0/tests/test_temporal_refresh.py +76 -0
  65. homestead_memory-0.2.0/tests/test_tuning.py +119 -0
  66. homestead_memory-0.2.0/tests/test_vault.py +121 -0
  67. homestead_memory-0.2.0/tests/test_verify_json.py +73 -0
  68. homestead_memory-0.2.0/tests/test_verify_temporal.py +192 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Kinetic Labs Inc.
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.
@@ -0,0 +1,272 @@
1
+ Metadata-Version: 2.4
2
+ Name: homestead-memory
3
+ Version: 0.2.0
4
+ Summary: Verifiable, local-first AI memory that catches rot, tampering, and poisoning. Plain markdown you own.
5
+ Author: Kinetic Labs
6
+ License: MIT
7
+ Keywords: ai,memory,local-first,agents,verification,rag,homestead
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.10
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Provides-Extra: api
15
+ Requires-Dist: fastapi>=0.110; extra == "api"
16
+ Requires-Dist: uvicorn>=0.27; extra == "api"
17
+ Provides-Extra: sign
18
+ Requires-Dist: cryptography>=42; extra == "sign"
19
+ Provides-Extra: langgraph
20
+ Requires-Dist: langgraph>=0.2; extra == "langgraph"
21
+ Provides-Extra: crewai
22
+ Requires-Dist: crewai>=0.70; extra == "crewai"
23
+ Provides-Extra: autogen
24
+ Requires-Dist: autogen-core>=0.4; extra == "autogen"
25
+ Provides-Extra: openai-agents
26
+ Requires-Dist: openai-agents>=0.0.1; extra == "openai-agents"
27
+ Provides-Extra: litellm
28
+ Requires-Dist: litellm>=1.40; extra == "litellm"
29
+ Dynamic: license-file
30
+
31
+ # homestead-memory
32
+
33
+ **Stop renting your mind.**
34
+
35
+ Local-first, verifiable AI memory. Your notes stay plain markdown you can read,
36
+ `git diff`, and own, and the memory **catches its own rot, tampering, and poisoning.**
37
+
38
+ Every other memory layer asks you to *hope* it remembers. This one lets you
39
+ *watch it catch the rot, live:*
40
+
41
+ ![hsm verify --demo: a clean vault scores MEMORY INTACT 100/100, then rot is planted and caught live: ROT DETECTED 0/100 with every finding named](docs/demo.gif)
42
+
43
+ ```bash
44
+ pip install homestead-memory # macOS / Linux / Windows (pure Python, zero deps)
45
+
46
+ hsm verify --demo
47
+ # ① a clean vault ✅ MEMORY INTACT — 100/100
48
+ # ② rot is planted… 🔴 ROT DETECTED — 0/100
49
+ # 🔴 [self_contradiction] the note argues with itself about its own status
50
+ # 🔴 [uncited_claim] a distilled claim has no source citation
51
+ # 🔴 [dangling_citation] a cited source no longer exists
52
+ # ⚠️ [broken_link] a reference points at a deleted note
53
+ ```
54
+
55
+ `hsm verify` exits non-zero on rot — it gates CI and cron like a test suite.
56
+
57
+ ## Quickstart (60 seconds)
58
+
59
+ ```bash
60
+ hsm init ./my-vault # scaffold or adopt any markdown folder
61
+ hsm ingest ./my-vault # index it (hybrid BM25+vector via qmd, optional)
62
+ hsm ask "what did I decide about X?"
63
+ hsm verify ./my-vault # the integrity gate — the whole point
64
+ hsm distill ./my-vault # optional: build the cited, verifiable fact layer
65
+ hsm history <note> --as-of 2026-06-01 # what was true THEN (temporal layer)
66
+ hsm serve # local HTTP API (auth'd, loopback-only)
67
+ ```
68
+
69
+ Python agents can use the SDK directly:
70
+
71
+ ```python
72
+ from homestead_memory import connect
73
+
74
+ memory = connect("~/my-vault", agent="my-agent")
75
+ memory.remember("user", "city", "Berlin")
76
+ memory.ask("what city is the user in?")
77
+ ```
78
+
79
+ The local HTTP API is documented in [`docs/openapi.yaml`](docs/openapi.yaml).
80
+
81
+ ## Memory under the router
82
+
83
+ Routers can swap the served model while homestead-memory keeps the same vault
84
+ underneath. The model name is just the runtime argument; provenance is stamped as
85
+ `name@model` in the `agent` field when a write happens.
86
+
87
+ ```python
88
+ from homestead_memory import connect
89
+ from homestead_memory.adapters.openai_compat import MemoryChat
90
+
91
+ memory = connect("~/my-vault")
92
+
93
+ def remember_reply(response, memory, agent):
94
+ memory.remember(
95
+ "conversation",
96
+ "last_reply",
97
+ response.choices[0].message.content,
98
+ source="chat",
99
+ agent=agent,
100
+ )
101
+
102
+ chat = MemoryChat(openai_compatible_client, memory, remember_fn=remember_reply)
103
+ chat.create(model="claude-sonnet-4.7", messages=[{"role": "user", "content": "brief me"}])
104
+ chat.create(model="glm-4.7", messages=[{"role": "user", "content": "continue"}])
105
+
106
+ memory.history("conversation") # agents include assistant@claude-sonnet-4.7 and assistant@glm-4.7
107
+ ```
108
+
109
+ LiteLLM can use the same pattern with a pre-call injection helper and a success
110
+ logger:
111
+
112
+ ```python
113
+ from homestead_memory import connect
114
+ from homestead_memory.adapters.litellm_memory import MemoryLogger, inject_memory
115
+
116
+ memory = connect("~/my-vault")
117
+ messages = inject_memory([{"role": "user", "content": "brief me"}], memory)
118
+
119
+ # LiteLLM callback registration style depends on your app setup.
120
+ logger = MemoryLogger(memory, agent_name="assistant")
121
+ ```
122
+
123
+ MCP already sits above harness-level routers. In a `claude-code-router`-style
124
+ setup that swaps the backend model, homestead-memory keeps working with
125
+ zero config because memory is external to the model. `history()` and `verify`
126
+ then attribute every recorded fact to the exact `name@model` that wrote it.
127
+
128
+ ## Integrations
129
+
130
+ Adapters target the public framework interfaces listed here as of the current
131
+ releases and may need version bumps as those APIs evolve. Core remains
132
+ stdlib-only; install only the extra for the framework you use.
133
+
134
+ Universal tools work with any orchestrator that can register callables or
135
+ JSON-schema function tools:
136
+
137
+ ```python
138
+ from homestead_memory import connect
139
+ from homestead_memory.adapters.tools import recall_tool, remember_tool, tool_specs, verify_tool
140
+
141
+ memory = connect("~/my-vault", agent="my-agent")
142
+ tools = [remember_tool(memory), recall_tool(memory), verify_tool(memory)]
143
+ specs = tool_specs(memory) # name, description, parameters
144
+ ```
145
+
146
+ LangGraph `BaseStore` (targets `langgraph>=0.2`):
147
+
148
+ ```python
149
+ from homestead_memory import connect
150
+ from homestead_memory.adapters.langgraph_store import HomesteadStore
151
+
152
+ store = HomesteadStore(connect("~/my-vault", agent="langgraph"))
153
+ graph = builder.compile(checkpointer=checkpointer, store=store)
154
+ ```
155
+
156
+ CrewAI storage/memory (targets `crewai>=0.70`, storage-style
157
+ `save/search/reset`):
158
+
159
+ ```python
160
+ from homestead_memory import connect
161
+ from homestead_memory.adapters.crewai_memory import HomesteadCrewAIStorage
162
+
163
+ storage = HomesteadCrewAIStorage(connect("~/my-vault", agent="crewai"))
164
+ storage.save("Researcher found the supplier shortlist", metadata={"task": "supplier_shortlist"})
165
+ ```
166
+
167
+ AutoGen `autogen_core` Memory protocol (targets `autogen-core>=0.4`):
168
+
169
+ ```python
170
+ from autogen_core.memory import MemoryContent, MemoryMimeType
171
+ from homestead_memory import connect
172
+ from homestead_memory.adapters.autogen_memory import HomesteadAutoGenMemory
173
+
174
+ memory = HomesteadAutoGenMemory(connect("~/my-vault", agent="autogen"))
175
+ await memory.add(MemoryContent(content="Use metric units", mime_type=MemoryMimeType.TEXT))
176
+ ```
177
+
178
+ OpenAI Agents SDK Session protocol or function tools (targets
179
+ `openai-agents>=0.0.1`):
180
+
181
+ ```python
182
+ from homestead_memory import connect
183
+ from homestead_memory.adapters.openai_agents import HomesteadSession, function_tools
184
+
185
+ memory = connect("~/my-vault", agent="openai-agents")
186
+ session = HomesteadSession(memory, session_id="user-123")
187
+ agent_tools = function_tools(memory)
188
+ ```
189
+
190
+ **Claude Code / Desktop / Cursor** (MCP):
191
+
192
+ ```bash
193
+ claude mcp add homestead-memory -- hsm mcp ~/my-vault
194
+ # tools: memory_ask · memory_search · memory_verify · memory_history ·
195
+ # memory_ingest · memory_distill
196
+ ```
197
+
198
+ ## Why this exists
199
+
200
+ "Runs on your device" is table stakes now — every memory tool stores locally.
201
+ **Nobody verifies.** Memory rots quietly: a note contradicts itself, an extracted
202
+ "fact" loses its source, a body drifts past its own changelog, the current value
203
+ gets shadowed by a stale one. You find out weeks later, when your agent confidently
204
+ tells you something that stopped being true in March.
205
+
206
+ And rot is only the *passive* failure. Memory also gets **tampered** with (a fact
207
+ edited after it was written) and **poisoned** (untrusted input injects a "memory"
208
+ that was never true — a named 2026 attack class). homestead-memory catches all
209
+ three mechanically: sign the vault and any edited byte breaks the signature; a
210
+ distilled claim must cite a source that resolves or it's dropped. Recall benchmarks
211
+ measure whether the model *remembers*; **RotBench measures whether the memory can be
212
+ trusted** — see [`benchmarks/ROTBENCH.md`](benchmarks/ROTBENCH.md).
213
+
214
+ homestead-memory is built around three commitments:
215
+
216
+ 1. **Markdown-primary.** The human-readable files ARE the memory. Indexes and
217
+ projections are derived and disposable. You can leave any time — it's your folder.
218
+ Import/export Google's **Open Knowledge Format** (`hsm export --format okf`) plus
219
+ Mem0/Zep: we're OKF, but signed and verifiable.
220
+ 2. **Verification over trust.** Integrity is a *number* (RotBench, 0–100), computed
221
+ by mechanical checks — no LLM judging its own homework. See
222
+ [`benchmarks/ROTBENCH.md`](benchmarks/ROTBENCH.md).
223
+ 3. **Auditable extraction.** The optional distilled layer ([`docs/DISTILL_SPEC.md`](docs/DISTILL_SPEC.md))
224
+ extracts entity facts *with verbatim quotes, checked in code* — a claim either
225
+ cites a real source or it's dropped. Contradictions append a changelog line
226
+ (`update current_crm: "Salesforce" -> "HubSpot" (source: chat-042.md)`) — never a
227
+ silent overwrite. Extraction you can audit is extraction you can trust.
228
+
229
+ ## The two camps (where this sits)
230
+
231
+ | | extraction camp (Mem0, Zep) | verbatim camp (MemPalace, **this**) |
232
+ |---|---|---|
233
+ | write cost | LLM call per turn/episode | **$0** (embed only; distill optional) |
234
+ | information | lossy summaries | **lossless** raw text |
235
+ | auditability | trust the extractor | **cite-or-drop, checked mechanically** |
236
+ | integrity score | — | **RotBench, published every run** |
237
+
238
+ ## Honest numbers (LongMemEval)
239
+
240
+ Measured on the full 500-question `_s` set (48-session haystacks with distractors),
241
+ scored with the **official per-type judge methodology**, reader `glm-5.2`,
242
+ independent judge `deepseek-v4-pro`. Reproduce: [`benchmarks/README.md`](benchmarks/README.md).
243
+ Full run history including the failures: [`benchmarks/RESULTS.md`](benchmarks/RESULTS.md).
244
+
245
+ | metric | value |
246
+ |---|---|
247
+ | retrieval recall@k | **85%** (evidence surfaced into top-k) |
248
+ | QA accuracy (official methodology) | **52.8%** |
249
+ | context tokens / query | **~5.2k** |
250
+ | RotBench | **99.4 / 100** |
251
+
252
+ What we will and won't claim: recall is elite and *reader-independent*; QA is honest
253
+ and mid — published systems self-report higher on their own harnesses (Mem0 94.4%,
254
+ Zep 63.8% independent); we publish the harness, the judge, and every failed
255
+ experiment instead. No number here is from a harness you can't run yourself.
256
+
257
+ ## Design
258
+
259
+ - **Cross-platform.** Pure Python, stdlib-only core. CI: ubuntu / macos / windows.
260
+ - **Degrades gracefully.** qmd (hybrid retrieval) is an optional dependency; without
261
+ it, retrieval falls back to a direct scan. Memory survives its index being down —
262
+ `verify --deep` *tests* that.
263
+ - **Local by default.** The HTTP API binds loopback with bearer auth + DNS-rebind
264
+ protection; the MCP server is stdio (client-spawned). Nothing phones home.
265
+ - **Temporal.** Changelog lines make history queryable: `hsm history note --as-of DATE`.
266
+
267
+ ## Status
268
+
269
+ v0.2, building in public. Roadmap: [`ROADMAP.md`](ROADMAP.md). Break our benchmark:
270
+ [`benchmarks/ROTBENCH.md`](benchmarks/ROTBENCH.md) — adversarial fixtures get merged.
271
+
272
+ MIT © Kinetic Labs Inc. · a [FuckBigTech](https://fuckbigtech.ai) / HOMESTEAD project.
@@ -0,0 +1,242 @@
1
+ # homestead-memory
2
+
3
+ **Stop renting your mind.**
4
+
5
+ Local-first, verifiable AI memory. Your notes stay plain markdown you can read,
6
+ `git diff`, and own, and the memory **catches its own rot, tampering, and poisoning.**
7
+
8
+ Every other memory layer asks you to *hope* it remembers. This one lets you
9
+ *watch it catch the rot, live:*
10
+
11
+ ![hsm verify --demo: a clean vault scores MEMORY INTACT 100/100, then rot is planted and caught live: ROT DETECTED 0/100 with every finding named](docs/demo.gif)
12
+
13
+ ```bash
14
+ pip install homestead-memory # macOS / Linux / Windows (pure Python, zero deps)
15
+
16
+ hsm verify --demo
17
+ # ① a clean vault ✅ MEMORY INTACT — 100/100
18
+ # ② rot is planted… 🔴 ROT DETECTED — 0/100
19
+ # 🔴 [self_contradiction] the note argues with itself about its own status
20
+ # 🔴 [uncited_claim] a distilled claim has no source citation
21
+ # 🔴 [dangling_citation] a cited source no longer exists
22
+ # ⚠️ [broken_link] a reference points at a deleted note
23
+ ```
24
+
25
+ `hsm verify` exits non-zero on rot — it gates CI and cron like a test suite.
26
+
27
+ ## Quickstart (60 seconds)
28
+
29
+ ```bash
30
+ hsm init ./my-vault # scaffold or adopt any markdown folder
31
+ hsm ingest ./my-vault # index it (hybrid BM25+vector via qmd, optional)
32
+ hsm ask "what did I decide about X?"
33
+ hsm verify ./my-vault # the integrity gate — the whole point
34
+ hsm distill ./my-vault # optional: build the cited, verifiable fact layer
35
+ hsm history <note> --as-of 2026-06-01 # what was true THEN (temporal layer)
36
+ hsm serve # local HTTP API (auth'd, loopback-only)
37
+ ```
38
+
39
+ Python agents can use the SDK directly:
40
+
41
+ ```python
42
+ from homestead_memory import connect
43
+
44
+ memory = connect("~/my-vault", agent="my-agent")
45
+ memory.remember("user", "city", "Berlin")
46
+ memory.ask("what city is the user in?")
47
+ ```
48
+
49
+ The local HTTP API is documented in [`docs/openapi.yaml`](docs/openapi.yaml).
50
+
51
+ ## Memory under the router
52
+
53
+ Routers can swap the served model while homestead-memory keeps the same vault
54
+ underneath. The model name is just the runtime argument; provenance is stamped as
55
+ `name@model` in the `agent` field when a write happens.
56
+
57
+ ```python
58
+ from homestead_memory import connect
59
+ from homestead_memory.adapters.openai_compat import MemoryChat
60
+
61
+ memory = connect("~/my-vault")
62
+
63
+ def remember_reply(response, memory, agent):
64
+ memory.remember(
65
+ "conversation",
66
+ "last_reply",
67
+ response.choices[0].message.content,
68
+ source="chat",
69
+ agent=agent,
70
+ )
71
+
72
+ chat = MemoryChat(openai_compatible_client, memory, remember_fn=remember_reply)
73
+ chat.create(model="claude-sonnet-4.7", messages=[{"role": "user", "content": "brief me"}])
74
+ chat.create(model="glm-4.7", messages=[{"role": "user", "content": "continue"}])
75
+
76
+ memory.history("conversation") # agents include assistant@claude-sonnet-4.7 and assistant@glm-4.7
77
+ ```
78
+
79
+ LiteLLM can use the same pattern with a pre-call injection helper and a success
80
+ logger:
81
+
82
+ ```python
83
+ from homestead_memory import connect
84
+ from homestead_memory.adapters.litellm_memory import MemoryLogger, inject_memory
85
+
86
+ memory = connect("~/my-vault")
87
+ messages = inject_memory([{"role": "user", "content": "brief me"}], memory)
88
+
89
+ # LiteLLM callback registration style depends on your app setup.
90
+ logger = MemoryLogger(memory, agent_name="assistant")
91
+ ```
92
+
93
+ MCP already sits above harness-level routers. In a `claude-code-router`-style
94
+ setup that swaps the backend model, homestead-memory keeps working with
95
+ zero config because memory is external to the model. `history()` and `verify`
96
+ then attribute every recorded fact to the exact `name@model` that wrote it.
97
+
98
+ ## Integrations
99
+
100
+ Adapters target the public framework interfaces listed here as of the current
101
+ releases and may need version bumps as those APIs evolve. Core remains
102
+ stdlib-only; install only the extra for the framework you use.
103
+
104
+ Universal tools work with any orchestrator that can register callables or
105
+ JSON-schema function tools:
106
+
107
+ ```python
108
+ from homestead_memory import connect
109
+ from homestead_memory.adapters.tools import recall_tool, remember_tool, tool_specs, verify_tool
110
+
111
+ memory = connect("~/my-vault", agent="my-agent")
112
+ tools = [remember_tool(memory), recall_tool(memory), verify_tool(memory)]
113
+ specs = tool_specs(memory) # name, description, parameters
114
+ ```
115
+
116
+ LangGraph `BaseStore` (targets `langgraph>=0.2`):
117
+
118
+ ```python
119
+ from homestead_memory import connect
120
+ from homestead_memory.adapters.langgraph_store import HomesteadStore
121
+
122
+ store = HomesteadStore(connect("~/my-vault", agent="langgraph"))
123
+ graph = builder.compile(checkpointer=checkpointer, store=store)
124
+ ```
125
+
126
+ CrewAI storage/memory (targets `crewai>=0.70`, storage-style
127
+ `save/search/reset`):
128
+
129
+ ```python
130
+ from homestead_memory import connect
131
+ from homestead_memory.adapters.crewai_memory import HomesteadCrewAIStorage
132
+
133
+ storage = HomesteadCrewAIStorage(connect("~/my-vault", agent="crewai"))
134
+ storage.save("Researcher found the supplier shortlist", metadata={"task": "supplier_shortlist"})
135
+ ```
136
+
137
+ AutoGen `autogen_core` Memory protocol (targets `autogen-core>=0.4`):
138
+
139
+ ```python
140
+ from autogen_core.memory import MemoryContent, MemoryMimeType
141
+ from homestead_memory import connect
142
+ from homestead_memory.adapters.autogen_memory import HomesteadAutoGenMemory
143
+
144
+ memory = HomesteadAutoGenMemory(connect("~/my-vault", agent="autogen"))
145
+ await memory.add(MemoryContent(content="Use metric units", mime_type=MemoryMimeType.TEXT))
146
+ ```
147
+
148
+ OpenAI Agents SDK Session protocol or function tools (targets
149
+ `openai-agents>=0.0.1`):
150
+
151
+ ```python
152
+ from homestead_memory import connect
153
+ from homestead_memory.adapters.openai_agents import HomesteadSession, function_tools
154
+
155
+ memory = connect("~/my-vault", agent="openai-agents")
156
+ session = HomesteadSession(memory, session_id="user-123")
157
+ agent_tools = function_tools(memory)
158
+ ```
159
+
160
+ **Claude Code / Desktop / Cursor** (MCP):
161
+
162
+ ```bash
163
+ claude mcp add homestead-memory -- hsm mcp ~/my-vault
164
+ # tools: memory_ask · memory_search · memory_verify · memory_history ·
165
+ # memory_ingest · memory_distill
166
+ ```
167
+
168
+ ## Why this exists
169
+
170
+ "Runs on your device" is table stakes now — every memory tool stores locally.
171
+ **Nobody verifies.** Memory rots quietly: a note contradicts itself, an extracted
172
+ "fact" loses its source, a body drifts past its own changelog, the current value
173
+ gets shadowed by a stale one. You find out weeks later, when your agent confidently
174
+ tells you something that stopped being true in March.
175
+
176
+ And rot is only the *passive* failure. Memory also gets **tampered** with (a fact
177
+ edited after it was written) and **poisoned** (untrusted input injects a "memory"
178
+ that was never true — a named 2026 attack class). homestead-memory catches all
179
+ three mechanically: sign the vault and any edited byte breaks the signature; a
180
+ distilled claim must cite a source that resolves or it's dropped. Recall benchmarks
181
+ measure whether the model *remembers*; **RotBench measures whether the memory can be
182
+ trusted** — see [`benchmarks/ROTBENCH.md`](benchmarks/ROTBENCH.md).
183
+
184
+ homestead-memory is built around three commitments:
185
+
186
+ 1. **Markdown-primary.** The human-readable files ARE the memory. Indexes and
187
+ projections are derived and disposable. You can leave any time — it's your folder.
188
+ Import/export Google's **Open Knowledge Format** (`hsm export --format okf`) plus
189
+ Mem0/Zep: we're OKF, but signed and verifiable.
190
+ 2. **Verification over trust.** Integrity is a *number* (RotBench, 0–100), computed
191
+ by mechanical checks — no LLM judging its own homework. See
192
+ [`benchmarks/ROTBENCH.md`](benchmarks/ROTBENCH.md).
193
+ 3. **Auditable extraction.** The optional distilled layer ([`docs/DISTILL_SPEC.md`](docs/DISTILL_SPEC.md))
194
+ extracts entity facts *with verbatim quotes, checked in code* — a claim either
195
+ cites a real source or it's dropped. Contradictions append a changelog line
196
+ (`update current_crm: "Salesforce" -> "HubSpot" (source: chat-042.md)`) — never a
197
+ silent overwrite. Extraction you can audit is extraction you can trust.
198
+
199
+ ## The two camps (where this sits)
200
+
201
+ | | extraction camp (Mem0, Zep) | verbatim camp (MemPalace, **this**) |
202
+ |---|---|---|
203
+ | write cost | LLM call per turn/episode | **$0** (embed only; distill optional) |
204
+ | information | lossy summaries | **lossless** raw text |
205
+ | auditability | trust the extractor | **cite-or-drop, checked mechanically** |
206
+ | integrity score | — | **RotBench, published every run** |
207
+
208
+ ## Honest numbers (LongMemEval)
209
+
210
+ Measured on the full 500-question `_s` set (48-session haystacks with distractors),
211
+ scored with the **official per-type judge methodology**, reader `glm-5.2`,
212
+ independent judge `deepseek-v4-pro`. Reproduce: [`benchmarks/README.md`](benchmarks/README.md).
213
+ Full run history including the failures: [`benchmarks/RESULTS.md`](benchmarks/RESULTS.md).
214
+
215
+ | metric | value |
216
+ |---|---|
217
+ | retrieval recall@k | **85%** (evidence surfaced into top-k) |
218
+ | QA accuracy (official methodology) | **52.8%** |
219
+ | context tokens / query | **~5.2k** |
220
+ | RotBench | **99.4 / 100** |
221
+
222
+ What we will and won't claim: recall is elite and *reader-independent*; QA is honest
223
+ and mid — published systems self-report higher on their own harnesses (Mem0 94.4%,
224
+ Zep 63.8% independent); we publish the harness, the judge, and every failed
225
+ experiment instead. No number here is from a harness you can't run yourself.
226
+
227
+ ## Design
228
+
229
+ - **Cross-platform.** Pure Python, stdlib-only core. CI: ubuntu / macos / windows.
230
+ - **Degrades gracefully.** qmd (hybrid retrieval) is an optional dependency; without
231
+ it, retrieval falls back to a direct scan. Memory survives its index being down —
232
+ `verify --deep` *tests* that.
233
+ - **Local by default.** The HTTP API binds loopback with bearer auth + DNS-rebind
234
+ protection; the MCP server is stdio (client-spawned). Nothing phones home.
235
+ - **Temporal.** Changelog lines make history queryable: `hsm history note --as-of DATE`.
236
+
237
+ ## Status
238
+
239
+ v0.2, building in public. Roadmap: [`ROADMAP.md`](ROADMAP.md). Break our benchmark:
240
+ [`benchmarks/ROTBENCH.md`](benchmarks/ROTBENCH.md) — adversarial fixtures get merged.
241
+
242
+ MIT © Kinetic Labs Inc. · a [FuckBigTech](https://fuckbigtech.ai) / HOMESTEAD project.
@@ -0,0 +1,44 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "homestead-memory"
7
+ version = "0.2.0"
8
+ description = "Verifiable, local-first AI memory that catches rot, tampering, and poisoning. Plain markdown you own."
9
+ readme = "README.md"
10
+ license = { text = "MIT" }
11
+ requires-python = ">=3.10"
12
+ authors = [{ name = "Kinetic Labs" }]
13
+ keywords = ["ai", "memory", "local-first", "agents", "verification", "rag", "homestead"]
14
+ classifiers = [
15
+ "License :: OSI Approved :: MIT License",
16
+ "Programming Language :: Python :: 3",
17
+ "Operating System :: OS Independent",
18
+ ]
19
+ # Core is stdlib-only. qmd (hybrid retrieval) is an optional external CLI dependency,
20
+ # invoked as a subprocess; the store degrades to a direct markdown scan without it.
21
+ dependencies = []
22
+
23
+ [project.optional-dependencies]
24
+ api = ["fastapi>=0.110", "uvicorn>=0.27"]
25
+ sign = ["cryptography>=42"]
26
+ langgraph = ["langgraph>=0.2"]
27
+ crewai = ["crewai>=0.70"]
28
+ autogen = ["autogen-core>=0.4"]
29
+ openai-agents = ["openai-agents>=0.0.1"]
30
+ litellm = ["litellm>=1.40"]
31
+
32
+ [project.scripts]
33
+ hsm = "homestead_memory.cli:main"
34
+ fbt = "homestead_memory.cli:main" # legacy alias, removed before 1.0
35
+
36
+ [tool.setuptools.packages.find]
37
+ where = ["src"]
38
+
39
+ [tool.pytest.ini_options]
40
+ # The example scripts under examples/ are imported by their tests
41
+ # (`from examples import hot_swap_demo`). Put the repo root on sys.path so the
42
+ # bare `pytest` console script (as CI runs it) behaves like `python -m pytest`.
43
+ pythonpath = ["."]
44
+ testpaths = ["tests"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,10 @@
1
+ """homestead-memory — verifiable, local-first AI memory.
2
+
3
+ Stop renting your mind. Own it, and catch it when it rots.
4
+ """
5
+
6
+ from .sdk import Memory, connect
7
+
8
+ __version__ = "0.2.0"
9
+
10
+ __all__ = ["Memory", "connect", "__version__"]
@@ -0,0 +1,13 @@
1
+ """Framework adapters for plugging homestead-memory into agent runtimes."""
2
+ from __future__ import annotations
3
+
4
+ __all__ = [
5
+ "tools",
6
+ "langgraph_store",
7
+ "crewai_memory",
8
+ "autogen_memory",
9
+ "openai_agents",
10
+ "openai_compat",
11
+ "litellm_memory",
12
+ "okf",
13
+ ]