memory-unlocked 1.0.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 (61) hide show
  1. memory_unlocked-1.0.0/CHANGELOG.md +69 -0
  2. memory_unlocked-1.0.0/CODE_OF_CONDUCT.md +7 -0
  3. memory_unlocked-1.0.0/CONTRIBUTING.md +28 -0
  4. memory_unlocked-1.0.0/LICENSE +21 -0
  5. memory_unlocked-1.0.0/MANIFEST.in +10 -0
  6. memory_unlocked-1.0.0/PKG-INFO +247 -0
  7. memory_unlocked-1.0.0/README.md +221 -0
  8. memory_unlocked-1.0.0/ROADMAP.md +41 -0
  9. memory_unlocked-1.0.0/SECURITY.md +23 -0
  10. memory_unlocked-1.0.0/docs/architecture.md +86 -0
  11. memory_unlocked-1.0.0/docs/graph.md +112 -0
  12. memory_unlocked-1.0.0/docs/hermes.md +72 -0
  13. memory_unlocked-1.0.0/docs/install.md +98 -0
  14. memory_unlocked-1.0.0/docs/integrations.md +140 -0
  15. memory_unlocked-1.0.0/docs/privacy-and-redaction.md +93 -0
  16. memory_unlocked-1.0.0/docs/release-checklist.md +67 -0
  17. memory_unlocked-1.0.0/docs/schema.md +88 -0
  18. memory_unlocked-1.0.0/docs/student-quickstart.md +91 -0
  19. memory_unlocked-1.0.0/docs/threat-model.md +33 -0
  20. memory_unlocked-1.0.0/examples/evalset/README.md +13 -0
  21. memory_unlocked-1.0.0/examples/evalset/basic.json +28 -0
  22. memory_unlocked-1.0.0/examples/graph-basic/README.md +26 -0
  23. memory_unlocked-1.0.0/examples/hermes-basic/README.md +36 -0
  24. memory_unlocked-1.0.0/examples/sqlite-production/README.md +24 -0
  25. memory_unlocked-1.0.0/examples/team-memory/README.md +19 -0
  26. memory_unlocked-1.0.0/memory_unlocked/__init__.py +69 -0
  27. memory_unlocked-1.0.0/memory_unlocked/__main__.py +8 -0
  28. memory_unlocked-1.0.0/memory_unlocked/assembler.py +122 -0
  29. memory_unlocked-1.0.0/memory_unlocked/cli.py +502 -0
  30. memory_unlocked-1.0.0/memory_unlocked/evaluation.py +144 -0
  31. memory_unlocked-1.0.0/memory_unlocked/graph.py +570 -0
  32. memory_unlocked-1.0.0/memory_unlocked/mcp_server.py +458 -0
  33. memory_unlocked-1.0.0/memory_unlocked/models.py +145 -0
  34. memory_unlocked-1.0.0/memory_unlocked/ops.py +637 -0
  35. memory_unlocked-1.0.0/memory_unlocked/persistence.py +140 -0
  36. memory_unlocked-1.0.0/memory_unlocked/policy.py +208 -0
  37. memory_unlocked-1.0.0/memory_unlocked/ranking.py +208 -0
  38. memory_unlocked-1.0.0/memory_unlocked/render.py +91 -0
  39. memory_unlocked-1.0.0/memory_unlocked/serialize.py +88 -0
  40. memory_unlocked-1.0.0/memory_unlocked/sqlite_store.py +181 -0
  41. memory_unlocked-1.0.0/memory_unlocked/store.py +295 -0
  42. memory_unlocked-1.0.0/memory_unlocked.egg-info/PKG-INFO +247 -0
  43. memory_unlocked-1.0.0/memory_unlocked.egg-info/SOURCES.txt +59 -0
  44. memory_unlocked-1.0.0/memory_unlocked.egg-info/dependency_links.txt +1 -0
  45. memory_unlocked-1.0.0/memory_unlocked.egg-info/entry_points.txt +3 -0
  46. memory_unlocked-1.0.0/memory_unlocked.egg-info/requires.txt +4 -0
  47. memory_unlocked-1.0.0/memory_unlocked.egg-info/top_level.txt +1 -0
  48. memory_unlocked-1.0.0/pyproject.toml +48 -0
  49. memory_unlocked-1.0.0/scripts/smoke_release.py +202 -0
  50. memory_unlocked-1.0.0/setup.cfg +4 -0
  51. memory_unlocked-1.0.0/tests/test_assembler.py +90 -0
  52. memory_unlocked-1.0.0/tests/test_cli.py +148 -0
  53. memory_unlocked-1.0.0/tests/test_graph.py +212 -0
  54. memory_unlocked-1.0.0/tests/test_graph_public_surfaces.py +87 -0
  55. memory_unlocked-1.0.0/tests/test_mcp_server.py +282 -0
  56. memory_unlocked-1.0.0/tests/test_namespace_isolation.py +47 -0
  57. memory_unlocked-1.0.0/tests/test_persistence.py +153 -0
  58. memory_unlocked-1.0.0/tests/test_policy.py +121 -0
  59. memory_unlocked-1.0.0/tests/test_product_features.py +103 -0
  60. memory_unlocked-1.0.0/tests/test_release_contract.py +48 -0
  61. memory_unlocked-1.0.0/tests/test_serialize.py +81 -0
@@ -0,0 +1,69 @@
1
+ # Changelog
2
+
3
+ ## 1.0.0 - Stable Local MCP for Students
4
+
5
+ ### Added
6
+
7
+ - Stable local-per-installation contract: every new store starts with zero memories and has no connection to any maintainer or other student store.
8
+ - `memory-unlocked doctor` for version, backend, writability, scope, and aggregate-count diagnostics without exposing memory bodies.
9
+ - Student quickstart covering isolated SQLite setup, MCP binding, backup, restore, and deletion.
10
+ - Release-artifact smoke that verifies an empty initial store, nine MCP tools, same-scope recall, and cross-project isolation.
11
+ - MCP protocol negotiation through the official `2025-11-25` version while retaining support for `2024-11-05`, `2025-03-26`, and `2025-06-18` clients.
12
+ - Fail-closed JSON-RPC validation for malformed messages, invalid params, and notifications that must never receive responses.
13
+ - Linux Python 3.9-3.13, macOS Python 3.11, and Windows Python 3.11 CI coverage.
14
+ - Verified wheel/sdist publication workflow with checksums, GitHub release assets, and PyPI trusted publishing.
15
+ - Split, least-privilege release jobs with SHA-pinned GitHub Actions and a PyPI job that receives only verified wheel/sdist artifacts.
16
+
17
+ ### Security
18
+
19
+ - The public package ships no database, memory export, environment file, private namespace, or hosted-service connection.
20
+ - Tenant/project remain process-bound MCP configuration and are never model-controlled tool arguments.
21
+
22
+ ## 0.3.1 - Semantic Graph Layer
23
+
24
+ ### Added
25
+
26
+ - Deterministic public-safe semantic graph extraction.
27
+ - Relation vocabulary: `owns`, `routes_to`, `separate_from`, `uses_provider`, `fallback_provider`, `deploys_to`, `source_of_truth_for`, `sensitive_write`, `depends_on`, `supersedes`.
28
+ - Spanish/Spanglish extraction patterns including `usa`, `depende de`, `fuente de verdad`, `no mezclar`, `fallback a`.
29
+ - Nearest-subject fallback binding for `fallback_provider`.
30
+ - CLI commands: `graph` and `graph-context`.
31
+ - MCP tool: `memory_graph_context`.
32
+ - Graph docs and public example.
33
+
34
+ ### Security
35
+
36
+ - Graph reports/context omit memory bodies.
37
+ - Entity/relation names pass secret/PII filters before emission.
38
+ - Graph extraction remains namespace-scoped and deterministic.
39
+
40
+ ## 0.3.0 - Productization Preview
41
+
42
+ Memory Unlocked moves from an installable skeleton to a product-grade local agent memory toolkit.
43
+
44
+ ### Added
45
+
46
+ - SQLite backend via `--backend sqlite` / `MEMORY_UNLOCKED_BACKEND=sqlite`.
47
+ - Lifecycle states: `candidate`, `active`, `archived`, `rejected`.
48
+ - Governance commands: `audit`, `review`, `status`, `forget`.
49
+ - Token-budgeted context assembly via CLI `context --token-budget` and MCP `memory_context`.
50
+ - Offline eval harness: `memory-unlocked eval examples/evalset/basic.json`.
51
+ - Safer context rendering that treats memories as data, not instructions.
52
+ - Size limits and PII handling policy knobs.
53
+ - Public examples for Hermes, team memory, SQLite production, and evalsets.
54
+
55
+ ### Security
56
+
57
+ - Recall logs redact secret-shaped queries.
58
+ - Rejected writes never persist the rejected content.
59
+ - Memory bodies are omitted from governance reports.
60
+
61
+ ## 0.2.0
62
+
63
+ - CLI and MCP server.
64
+ - Durable JSONL storage.
65
+ - Secret policy gate and public docs.
66
+
67
+ ## 0.1.0
68
+
69
+ - Public architecture skeleton, schema, examples, and tests.
@@ -0,0 +1,7 @@
1
+ # Code of Conduct
2
+
3
+ Be respectful, practical, and security-minded.
4
+
5
+ This project exists to help people build safer AI-agent memory. Contributions that harass people, expose private data, add backdoors, or intentionally weaken privacy/security are not welcome.
6
+
7
+ If you see a problem, use the repository's GitHub moderation/reporting tools or contact the maintainers through GitHub.
@@ -0,0 +1,28 @@
1
+ # Contributing
2
+
3
+ Thanks for improving Memory Unlocked.
4
+
5
+ ## Local setup
6
+
7
+ ```bash
8
+ python -m venv .venv
9
+ . .venv/bin/activate
10
+ python -m pip install -e '.[dev]'
11
+ python -m pytest -q
12
+ ```
13
+
14
+ ## Rules
15
+
16
+ 1. Never commit `.env`, credentials, tokens, private customer data, internal domains, or realistic-looking secrets.
17
+ 2. Add tests for policy, namespace isolation, persistence, and CLI/MCP behavior when touching those areas.
18
+ 3. Keep core dependencies minimal; stdlib is preferred.
19
+ 4. Public docs must use placeholders like `acme`, `billing`, `MEMORY_UNLOCKED_HOME`, and `[REDACTED]`.
20
+ 5. Do not add telemetry or network calls to the core package without a clear opt-in.
21
+
22
+ ## Pull request checklist
23
+
24
+ - [ ] `python -m pytest -q` passes
25
+ - [ ] `python -m compileall -q memory_unlocked` passes
26
+ - [ ] examples still use fake/public data only
27
+ - [ ] no generated caches or build artifacts committed
28
+ - [ ] changelog updated for user-visible changes
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Memory Unlocked contributors
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,10 @@
1
+ include CHANGELOG.md
2
+ include CODE_OF_CONDUCT.md
3
+ include CONTRIBUTING.md
4
+ include LICENSE
5
+ include README.md
6
+ include ROADMAP.md
7
+ include SECURITY.md
8
+ recursive-include docs *.md
9
+ recursive-include examples *.md *.json
10
+ recursive-include scripts *.py
@@ -0,0 +1,247 @@
1
+ Metadata-Version: 2.4
2
+ Name: memory-unlocked
3
+ Version: 1.0.0
4
+ Summary: A privacy-first, scope-isolated local memory store for AI agents, with a CLI and an MCP server.
5
+ Author: Memory Unlocked contributors
6
+ License-Expression: MIT
7
+ Project-URL: Documentation, https://github.com/josenaicipa/memory-unlocked/tree/main/docs
8
+ Project-URL: Source, https://github.com/josenaicipa/memory-unlocked
9
+ Keywords: ai,agents,memory,privacy,namespace,mcp
10
+ Classifier: Development Status :: 5 - Production/Stable
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.9
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Topic :: Software Development :: Libraries
19
+ Requires-Python: >=3.9
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Provides-Extra: dev
23
+ Requires-Dist: pytest>=7.0; extra == "dev"
24
+ Requires-Dist: ruff<1,>=0.14; extra == "dev"
25
+ Dynamic: license-file
26
+
27
+ # Memory Unlocked
28
+
29
+ A **privacy-first, scoped local memory** for AI agents. Memory Unlocked gives
30
+ agents durable, project-scoped memory without leaking secrets or letting one
31
+ project's context bleed into another.
32
+
33
+ It is installable today as a dependency-free Python package with:
34
+
35
+ - durable local JSONL and SQLite stores,
36
+ - a practical CLI (`memory-unlocked`),
37
+ - a dependency-free MCP stdio server (`memory-unlocked-mcp`),
38
+ - lifecycle/governance commands for candidate review, archival, and forgetting,
39
+ - token-budgeted context assembly and offline recall/privacy evals,
40
+ - a deterministic semantic graph layer for typed agent context,
41
+ - audit events for writes, recalls, updates, forgets, and rejections,
42
+ - tests and CI for the privacy/scope guarantees.
43
+
44
+ The core stays deliberately small so teams can audit it, ship it locally, and
45
+ adapt it to their own database, vector index, or hosted service later.
46
+
47
+ **v1 local-isolation contract:** every installation starts with an empty local
48
+ store. It does not include sample memories, connect to a maintainer database, or
49
+ share data with any other installation. Each user owns their own JSONL/SQLite
50
+ files. See the [student quickstart](docs/student-quickstart.md).
51
+
52
+ ---
53
+
54
+ ## Why this exists
55
+
56
+ Long-running agents need to remember things between sessions — decisions,
57
+ conventions, gotchas, references. But naive "just dump everything into a vector
58
+ store" memory has two failure modes:
59
+
60
+ 1. **Secret leakage** — credentials, tokens, customer data, and PII end up
61
+ persisted and later surfaced in unrelated contexts.
62
+ 2. **Scope bleed** — memory from Project A contaminates answers about Project B.
63
+
64
+ Memory Unlocked treats both as first-class concerns. Every memory is scoped to a
65
+ namespace, every write passes a redaction/policy gate, and recall is filtered by
66
+ scope before anything reaches the model.
67
+
68
+ ---
69
+
70
+ ## Who it is for
71
+
72
+ - Builders of multi-project agent systems who need **isolated** memory per scope.
73
+ - Teams that want **auditable, reviewable** writes instead of a black-box store.
74
+ - Anyone who wants a **readable reference architecture** they can port to their
75
+ own database, vector index, or MCP server.
76
+
77
+ ---
78
+
79
+ ## Quickstart
80
+
81
+ ```bash
82
+ pipx install memory-unlocked
83
+ # or: uv tool install memory-unlocked
84
+ ```
85
+
86
+ From source:
87
+
88
+ ```bash
89
+ git clone https://github.com/josenaicipa/memory-unlocked.git
90
+ cd memory-unlocked
91
+ python -m pip install -e '.[dev]'
92
+ python -m pytest -q
93
+ ```
94
+
95
+ Write and recall a memory from the CLI:
96
+
97
+ ```bash
98
+ memory-unlocked --path ./mem init
99
+ memory-unlocked --path ./mem write \
100
+ --tenant acme --project billing \
101
+ --title "Refunds run through the async queue" \
102
+ --body "Refund requests are enqueued and processed by a worker, not inline." \
103
+ --source docs/refunds.md \
104
+ --tags billing,architecture
105
+ memory-unlocked --path ./mem context \
106
+ --tenant acme --project billing --query refund --token-budget 200
107
+ ```
108
+
109
+ Review candidate memories and run governance/eval checks:
110
+
111
+ ```bash
112
+ memory-unlocked --path ./mem write \
113
+ --tenant acme --project billing \
114
+ --title "Candidate fact" --body "Needs human approval." \
115
+ --source docs/review.md --status candidate
116
+ memory-unlocked --path ./mem review --tenant acme --project billing
117
+ memory-unlocked --path ./mem audit --json
118
+ memory-unlocked eval examples/evalset/basic.json
119
+ ```
120
+
121
+ Use SQLite for a more production-like local backend:
122
+
123
+ ```bash
124
+ memory-unlocked --backend sqlite --path ./mem-sqlite init
125
+ memory-unlocked --backend sqlite --path ./mem-sqlite doctor
126
+ ```
127
+
128
+ Extract semantic graph context and the public-safe graph reports:
129
+
130
+ ```bash
131
+ memory-unlocked --path ./mem write \
132
+ --tenant acme --project billing \
133
+ --title "Graph demo" \
134
+ --body "Billing service owns refunds. Worker depends on Redis." \
135
+ --source docs/graph.md
136
+ memory-unlocked --path ./mem graph-context \
137
+ --tenant acme --project billing --token-budget 200
138
+ memory-unlocked --path ./mem graph-temporal \
139
+ --tenant acme --project billing --json
140
+ memory-unlocked --path ./mem graph-lineage \
141
+ --tenant acme --project billing --json
142
+ memory-unlocked --path ./mem graph-effective-backend \
143
+ --tenant acme --project billing --json
144
+ ```
145
+
146
+ The extra graph reports are read-only and public-safe: `graph-lineage` emits
147
+ opaque handles instead of raw memory ids/source refs, `graph-temporal` derives
148
+ relation validity from source-memory timestamps, and `graph-effective-backend`
149
+ returns the scoped graph as the canonical `memory_unlocked` backend payload for
150
+ agent/MCP consumers.
151
+
152
+
153
+ Run the MCP server for an agent runner:
154
+
155
+ ```bash
156
+ MEMORY_UNLOCKED_TENANT=acme \
157
+ MEMORY_UNLOCKED_PROJECT=billing \
158
+ MEMORY_UNLOCKED_HOME="$HOME/.memory_unlocked" \
159
+ memory-unlocked-mcp
160
+ ```
161
+
162
+ Use the core package directly:
163
+
164
+ ```python
165
+ from memory_unlocked import (
166
+ Memory, Source, Namespace, MemoryStore, ContextAssembler, PolicyError,
167
+ )
168
+
169
+ store = MemoryStore()
170
+
171
+ store.add(Memory(
172
+ namespace=Namespace("acme", "billing"),
173
+ title="Refunds run through the async queue",
174
+ body="Refund requests are enqueued and processed by a worker, not inline.",
175
+ source=Source(kind="doc", ref="docs/refunds.md"),
176
+ tags=["billing", "architecture"],
177
+ ))
178
+
179
+ # Recall is scope-filtered: only memories in the requested namespace come back.
180
+ assembler = ContextAssembler(store)
181
+ context = assembler.assemble(Namespace("acme", "billing"), query="refund")
182
+ print(context)
183
+ ```
184
+
185
+ Writes that contain obvious secrets, or that lack a verifiable source, are
186
+ rejected at the gate:
187
+
188
+ ```python
189
+ store.add(Memory(
190
+ namespace=Namespace("acme", "billing"),
191
+ title="API key",
192
+ body="AWS_SECRET_ACCESS_KEY=AKIA...", # raises PolicyError
193
+ source=Source(kind="doc", ref="notes.md"),
194
+ ))
195
+ ```
196
+
197
+ ---
198
+
199
+ ## Core concepts
200
+
201
+ | Concept | What it is |
202
+ | --- | --- |
203
+ | **Memory** | One atomic fact, with a title, body, tags, and a required source. |
204
+ | **Source** | Provenance for a memory (a file, URL, ticket, or run id). No source → no write. |
205
+ | **Namespace** | A `tenant / project` scope. Recall never crosses namespaces. |
206
+ | **Policy / redaction** | A gate every write passes before it is stored. |
207
+ | **Context assembler** | Builds a scope-filtered, ranked context block for the agent. |
208
+ | **Event** | An append-only record of writes and recalls for auditability. |
209
+
210
+ ---
211
+
212
+ ## Privacy-first guardrails
213
+
214
+ These are the defaults, not opt-ins:
215
+
216
+ - **Never store secrets.** Writes are scanned for credential-shaped content and
217
+ rejected. See [`docs/privacy-and-redaction.md`](docs/privacy-and-redaction.md).
218
+ - **Every memory needs a source.** Unattributed claims are rejected so memory
219
+ stays verifiable.
220
+ - **Scope isolation by default.** A recall in `tenant/project` cannot return a
221
+ memory written under any other scope.
222
+ - **No raw transcripts, no PII, no customer/lead data.** Store durable, stable
223
+ facts — not transient progress or personal information.
224
+ - **Writes are reviewable.** Every write and recall emits an event so you can
225
+ audit what the memory fabric learned and surfaced.
226
+
227
+ ---
228
+
229
+ ## Documentation
230
+
231
+ - [Install & CLI](docs/install.md) — package install, JSONL/SQLite stores, CLI commands.
232
+ - [Student quickstart](docs/student-quickstart.md) — isolated local setup starting with zero memories.
233
+ - [Hermes / MCP](docs/hermes.md) — run the MCP server and bind it to a project scope.
234
+ - [Semantic graph](docs/graph.md) — typed relation extraction and graph context.
235
+ - [Threat model](docs/threat-model.md) — public security boundaries and residual risk.
236
+ - [Release checklist](docs/release-checklist.md) — repeatable PyPI/release process.
237
+ - [Architecture](docs/architecture.md) — components, data flow, scope policy.
238
+ - [Privacy & redaction](docs/privacy-and-redaction.md) — what never to store and
239
+ the write-review flow.
240
+ - [Schema](docs/schema.md) — the canonical memory, source, link, and event shapes.
241
+ - [Integrations](docs/integrations.md) — MCP / HTTP / CLI patterns for agent runners.
242
+
243
+ ---
244
+
245
+ ## License
246
+
247
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,221 @@
1
+ # Memory Unlocked
2
+
3
+ A **privacy-first, scoped local memory** for AI agents. Memory Unlocked gives
4
+ agents durable, project-scoped memory without leaking secrets or letting one
5
+ project's context bleed into another.
6
+
7
+ It is installable today as a dependency-free Python package with:
8
+
9
+ - durable local JSONL and SQLite stores,
10
+ - a practical CLI (`memory-unlocked`),
11
+ - a dependency-free MCP stdio server (`memory-unlocked-mcp`),
12
+ - lifecycle/governance commands for candidate review, archival, and forgetting,
13
+ - token-budgeted context assembly and offline recall/privacy evals,
14
+ - a deterministic semantic graph layer for typed agent context,
15
+ - audit events for writes, recalls, updates, forgets, and rejections,
16
+ - tests and CI for the privacy/scope guarantees.
17
+
18
+ The core stays deliberately small so teams can audit it, ship it locally, and
19
+ adapt it to their own database, vector index, or hosted service later.
20
+
21
+ **v1 local-isolation contract:** every installation starts with an empty local
22
+ store. It does not include sample memories, connect to a maintainer database, or
23
+ share data with any other installation. Each user owns their own JSONL/SQLite
24
+ files. See the [student quickstart](docs/student-quickstart.md).
25
+
26
+ ---
27
+
28
+ ## Why this exists
29
+
30
+ Long-running agents need to remember things between sessions — decisions,
31
+ conventions, gotchas, references. But naive "just dump everything into a vector
32
+ store" memory has two failure modes:
33
+
34
+ 1. **Secret leakage** — credentials, tokens, customer data, and PII end up
35
+ persisted and later surfaced in unrelated contexts.
36
+ 2. **Scope bleed** — memory from Project A contaminates answers about Project B.
37
+
38
+ Memory Unlocked treats both as first-class concerns. Every memory is scoped to a
39
+ namespace, every write passes a redaction/policy gate, and recall is filtered by
40
+ scope before anything reaches the model.
41
+
42
+ ---
43
+
44
+ ## Who it is for
45
+
46
+ - Builders of multi-project agent systems who need **isolated** memory per scope.
47
+ - Teams that want **auditable, reviewable** writes instead of a black-box store.
48
+ - Anyone who wants a **readable reference architecture** they can port to their
49
+ own database, vector index, or MCP server.
50
+
51
+ ---
52
+
53
+ ## Quickstart
54
+
55
+ ```bash
56
+ pipx install memory-unlocked
57
+ # or: uv tool install memory-unlocked
58
+ ```
59
+
60
+ From source:
61
+
62
+ ```bash
63
+ git clone https://github.com/josenaicipa/memory-unlocked.git
64
+ cd memory-unlocked
65
+ python -m pip install -e '.[dev]'
66
+ python -m pytest -q
67
+ ```
68
+
69
+ Write and recall a memory from the CLI:
70
+
71
+ ```bash
72
+ memory-unlocked --path ./mem init
73
+ memory-unlocked --path ./mem write \
74
+ --tenant acme --project billing \
75
+ --title "Refunds run through the async queue" \
76
+ --body "Refund requests are enqueued and processed by a worker, not inline." \
77
+ --source docs/refunds.md \
78
+ --tags billing,architecture
79
+ memory-unlocked --path ./mem context \
80
+ --tenant acme --project billing --query refund --token-budget 200
81
+ ```
82
+
83
+ Review candidate memories and run governance/eval checks:
84
+
85
+ ```bash
86
+ memory-unlocked --path ./mem write \
87
+ --tenant acme --project billing \
88
+ --title "Candidate fact" --body "Needs human approval." \
89
+ --source docs/review.md --status candidate
90
+ memory-unlocked --path ./mem review --tenant acme --project billing
91
+ memory-unlocked --path ./mem audit --json
92
+ memory-unlocked eval examples/evalset/basic.json
93
+ ```
94
+
95
+ Use SQLite for a more production-like local backend:
96
+
97
+ ```bash
98
+ memory-unlocked --backend sqlite --path ./mem-sqlite init
99
+ memory-unlocked --backend sqlite --path ./mem-sqlite doctor
100
+ ```
101
+
102
+ Extract semantic graph context and the public-safe graph reports:
103
+
104
+ ```bash
105
+ memory-unlocked --path ./mem write \
106
+ --tenant acme --project billing \
107
+ --title "Graph demo" \
108
+ --body "Billing service owns refunds. Worker depends on Redis." \
109
+ --source docs/graph.md
110
+ memory-unlocked --path ./mem graph-context \
111
+ --tenant acme --project billing --token-budget 200
112
+ memory-unlocked --path ./mem graph-temporal \
113
+ --tenant acme --project billing --json
114
+ memory-unlocked --path ./mem graph-lineage \
115
+ --tenant acme --project billing --json
116
+ memory-unlocked --path ./mem graph-effective-backend \
117
+ --tenant acme --project billing --json
118
+ ```
119
+
120
+ The extra graph reports are read-only and public-safe: `graph-lineage` emits
121
+ opaque handles instead of raw memory ids/source refs, `graph-temporal` derives
122
+ relation validity from source-memory timestamps, and `graph-effective-backend`
123
+ returns the scoped graph as the canonical `memory_unlocked` backend payload for
124
+ agent/MCP consumers.
125
+
126
+
127
+ Run the MCP server for an agent runner:
128
+
129
+ ```bash
130
+ MEMORY_UNLOCKED_TENANT=acme \
131
+ MEMORY_UNLOCKED_PROJECT=billing \
132
+ MEMORY_UNLOCKED_HOME="$HOME/.memory_unlocked" \
133
+ memory-unlocked-mcp
134
+ ```
135
+
136
+ Use the core package directly:
137
+
138
+ ```python
139
+ from memory_unlocked import (
140
+ Memory, Source, Namespace, MemoryStore, ContextAssembler, PolicyError,
141
+ )
142
+
143
+ store = MemoryStore()
144
+
145
+ store.add(Memory(
146
+ namespace=Namespace("acme", "billing"),
147
+ title="Refunds run through the async queue",
148
+ body="Refund requests are enqueued and processed by a worker, not inline.",
149
+ source=Source(kind="doc", ref="docs/refunds.md"),
150
+ tags=["billing", "architecture"],
151
+ ))
152
+
153
+ # Recall is scope-filtered: only memories in the requested namespace come back.
154
+ assembler = ContextAssembler(store)
155
+ context = assembler.assemble(Namespace("acme", "billing"), query="refund")
156
+ print(context)
157
+ ```
158
+
159
+ Writes that contain obvious secrets, or that lack a verifiable source, are
160
+ rejected at the gate:
161
+
162
+ ```python
163
+ store.add(Memory(
164
+ namespace=Namespace("acme", "billing"),
165
+ title="API key",
166
+ body="AWS_SECRET_ACCESS_KEY=AKIA...", # raises PolicyError
167
+ source=Source(kind="doc", ref="notes.md"),
168
+ ))
169
+ ```
170
+
171
+ ---
172
+
173
+ ## Core concepts
174
+
175
+ | Concept | What it is |
176
+ | --- | --- |
177
+ | **Memory** | One atomic fact, with a title, body, tags, and a required source. |
178
+ | **Source** | Provenance for a memory (a file, URL, ticket, or run id). No source → no write. |
179
+ | **Namespace** | A `tenant / project` scope. Recall never crosses namespaces. |
180
+ | **Policy / redaction** | A gate every write passes before it is stored. |
181
+ | **Context assembler** | Builds a scope-filtered, ranked context block for the agent. |
182
+ | **Event** | An append-only record of writes and recalls for auditability. |
183
+
184
+ ---
185
+
186
+ ## Privacy-first guardrails
187
+
188
+ These are the defaults, not opt-ins:
189
+
190
+ - **Never store secrets.** Writes are scanned for credential-shaped content and
191
+ rejected. See [`docs/privacy-and-redaction.md`](docs/privacy-and-redaction.md).
192
+ - **Every memory needs a source.** Unattributed claims are rejected so memory
193
+ stays verifiable.
194
+ - **Scope isolation by default.** A recall in `tenant/project` cannot return a
195
+ memory written under any other scope.
196
+ - **No raw transcripts, no PII, no customer/lead data.** Store durable, stable
197
+ facts — not transient progress or personal information.
198
+ - **Writes are reviewable.** Every write and recall emits an event so you can
199
+ audit what the memory fabric learned and surfaced.
200
+
201
+ ---
202
+
203
+ ## Documentation
204
+
205
+ - [Install & CLI](docs/install.md) — package install, JSONL/SQLite stores, CLI commands.
206
+ - [Student quickstart](docs/student-quickstart.md) — isolated local setup starting with zero memories.
207
+ - [Hermes / MCP](docs/hermes.md) — run the MCP server and bind it to a project scope.
208
+ - [Semantic graph](docs/graph.md) — typed relation extraction and graph context.
209
+ - [Threat model](docs/threat-model.md) — public security boundaries and residual risk.
210
+ - [Release checklist](docs/release-checklist.md) — repeatable PyPI/release process.
211
+ - [Architecture](docs/architecture.md) — components, data flow, scope policy.
212
+ - [Privacy & redaction](docs/privacy-and-redaction.md) — what never to store and
213
+ the write-review flow.
214
+ - [Schema](docs/schema.md) — the canonical memory, source, link, and event shapes.
215
+ - [Integrations](docs/integrations.md) — MCP / HTTP / CLI patterns for agent runners.
216
+
217
+ ---
218
+
219
+ ## License
220
+
221
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,41 @@
1
+ # Roadmap
2
+
3
+ Memory Unlocked is a safe, portable local memory layer for MCP-compatible AI agents.
4
+
5
+ ## v1.0 - Stable Local MCP
6
+
7
+ - [x] Dependency-free CLI and MCP package
8
+ - [x] JSONL and SQLite local backends
9
+ - [x] Empty-by-default, local-per-installation student model
10
+ - [x] Process-bound tenant/project isolation
11
+ - [x] Lifecycle, review, audit, export, import, and forgetting
12
+ - [x] Offline recall/privacy eval harness
13
+ - [x] Deterministic public-safe semantic graph
14
+ - [x] Current MCP protocol negotiation with backward compatibility
15
+ - [x] Cross-platform CI and exact release-artifact smoke
16
+ - [x] Student quickstart, threat model, and privacy documentation
17
+
18
+ ## v1.x - Optional Local Enhancements
19
+
20
+ - [ ] encrypted-at-rest local option
21
+ - [ ] signed export/import bundles
22
+ - [ ] richer duplicate merge workflow
23
+ - [ ] visual graph UI on top of the deterministic semantic graph
24
+ - [ ] additional MCP-client setup recipes
25
+
26
+ ## Future Team/Hosted Layer
27
+
28
+ These are separate products and are not implied by the local v1 contract:
29
+
30
+ - [ ] Postgres backend with migrations
31
+ - [ ] authenticated multi-user service
32
+ - [ ] tenant authorization, RBAC, quotas, and deletion controls
33
+ - [ ] hosted dashboard and organization governance reports
34
+
35
+ ## Non-goals
36
+
37
+ - Storing raw conversations by default.
38
+ - Becoming a generic vector database.
39
+ - Depending on paid embedding APIs for the core package.
40
+ - Connecting student installations to a maintainer/private database.
41
+ - Shipping private deployment details in the public repository.
@@ -0,0 +1,23 @@
1
+ # Security Policy
2
+
3
+ Memory Unlocked is designed to reject secrets and isolate agent memory by namespace.
4
+
5
+ ## Reporting vulnerabilities
6
+
7
+ Use GitHub private vulnerability reporting / security advisories for this repository. Do not open a public issue containing exploit details or sensitive data.
8
+
9
+ ## Supported versions
10
+
11
+ The latest minor release receives security fixes.
12
+
13
+ ## Security design promises
14
+
15
+ - Namespace is selected by the operator/runtime, not by the model.
16
+ - Rejected writes do not store the rejected content.
17
+ - Governance reports omit memory bodies.
18
+ - Secret-shaped queries are redacted in audit events.
19
+ - The core package does not call external services.
20
+
21
+ ## What not to submit
22
+
23
+ Please do not send real API keys, credentials, customer records, private internal URLs, or private conversation transcripts in issues, PRs, examples, or tests.