memdsl 0.1.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.
@@ -0,0 +1,7 @@
1
+ __pycache__/
2
+ *.pyc
3
+ *.egg-info/
4
+ dist/
5
+ build/
6
+ .venv/
7
+ .pytest_cache/
memdsl-0.1.0/LICENSE ADDED
@@ -0,0 +1,26 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 liyuan
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.
22
+
23
+ ---
24
+
25
+ The specification document (docs/SPEC.md) is licensed separately under
26
+ CC-BY-4.0. See docs/SPEC.md for details.
memdsl-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,229 @@
1
+ Metadata-Version: 2.4
2
+ Name: memdsl
3
+ Version: 0.1.0
4
+ Summary: Agent memory as normative source code: a lintable, queryable memory DSL for LLM agents
5
+ Author: liyuan
6
+ License: MIT
7
+ License-File: LICENSE
8
+ Keywords: agent,context-engineering,dsl,llm,memory
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
14
+ Requires-Python: >=3.9
15
+ Provides-Extra: dev
16
+ Requires-Dist: pytest>=7.0; extra == 'dev'
17
+ Description-Content-Type: text/markdown
18
+
19
+ # memdsl
20
+
21
+ [English](#english) | [中文](#中文)
22
+
23
+ ## English
24
+
25
+ **Agent memory as normative source code.**
26
+
27
+ Most agent memory systems store what you said. Almost none of them
28
+ distinguish what an agent *must obey* from what it *may consider*. memdsl
29
+ treats long-term memory as a small, typed, lintable source language —
30
+ `.mem` files you can read, review, diff, version, and test — where a
31
+ `boundary` is a rule to enforce, not a fact to recall.
32
+
33
+ ```mem
34
+ preference schedule.deep_work_mornings {
35
+ subject: User
36
+ claim: "Prefers deep work in the morning; meetings after 2pm."
37
+ force: strong
38
+ scope: scheduling
39
+ evidence { source: chat quote: "Stop booking me into morning meetings." }
40
+ }
41
+
42
+ boundary privacy.no_family_in_public {
43
+ subject: User
44
+ rule: "Never include family member names or details in public-facing content."
45
+ force: hard
46
+ scope: global
47
+ exceptions: [user_explicit_override]
48
+ evidence { source: chat quote: "Anything about my family stays out of blog posts. Always." }
49
+ }
50
+ ```
51
+
52
+ The difference matters: a preference shapes suggestions; a boundary binds.
53
+ Flat embeddings of "user said X" erase exactly this distinction, which is
54
+ why agents violate rules their memory technically "contains".
55
+
56
+ ### 30 seconds: same question, one declaration apart
57
+
58
+ Ask an agent to *"draft a public blog post about building Aurora as a
59
+ working parent."* A similarity-ranked memory gives it the old chats where
60
+ the kids' names appear — and nothing that ranks a rule above a reminiscence.
61
+ The retrieved snippets are all just CONTEXT, so the names end up in the post:
62
+
63
+ ```text
64
+ retrieved: "...shipped the sync fix after bedtime, Theo finally sleeping..."
65
+ retrieved: "aurora beta feedback thread..."
66
+ ```
67
+
68
+ With the boundary declared, the evidence pack puts the rule where it cannot
69
+ be missed — in MUST, above every piece of context, whether or not the query
70
+ lexically matched it:
71
+
72
+ ```console
73
+ $ memdsl query examples/alex/ -q "draft a public blog post about aurora"
74
+ MUST
75
+ - [boundary:privacy.no_family_in_public] Never include family member names
76
+ or details in public-facing content. (exceptions: ['user_explicit_override'])
77
+
78
+ CONTEXT
79
+ - [state:aurora.beta_progress] Private beta with 40 testers; ...
80
+ ```
81
+
82
+ Feed the pack to the LLM as context and the compliant behavior is to write
83
+ the post *without* family details — and to be able to cite
84
+ `boundary:privacy.no_family_in_public` as the reason. The pack is the
85
+ prompt; the MUST layer is what changes the answer.
86
+
87
+ ### Lint it, query it
88
+
89
+ Memory that can be wrong deserves a linter:
90
+
91
+ ```console
92
+ $ memdsl lint examples/lint-demo/
93
+ broken.mem:7: error[unresolved_symbol] subject 'User.Barista' is not a declared entity
94
+ broken.mem:20: error[missing_evidence] active fact 'home.timezone' has no evidence block
95
+ broken.mem:28: warning[type_force_mismatch] preference uses force: hard; promote it to a boundary
96
+ broken.mem:41: warning[boundary_without_exception] confirm it is truly unconditional
97
+ broken.mem:53: warning[stale_state] as_of 2025-11-02 is older than 180 days
98
+
99
+ 6 declarations, 2 error(s), 3 warning(s)
100
+ ```
101
+
102
+ Queries return a **layered evidence pack**, not a hit list. Hard
103
+ boundaries surface even when the query doesn't lexically match them;
104
+ declared conflicts are shown, not averaged away; open issues surface as
105
+ gaps instead of being hallucinated over:
106
+
107
+ ```console
108
+ $ memdsl query examples/alex/ -q "should aurora keep the free tier"
109
+ # resolved subjects: Project.Aurora
110
+ MUST
111
+ - [boundary:privacy.no_family_in_public] Never include family member names ...
112
+
113
+ SHOULD
114
+ - (none)
115
+
116
+ CONTEXT
117
+ - [decision:aurora.pricing_free_tier] Keep a permanent free tier.
118
+ - [state:aurora.beta_progress] Private beta with 40 testers; sync is the top complaint. (as_of 2026-06-20)
119
+ - [goal:aurora.revenue_target_2026] Reach $2k MRR from Aurora by end of 2026.
120
+
121
+ CONFLICT
122
+ - [decision:aurora.pricing_free_tier] conflicts_with [aurora.revenue_target_2026]
123
+
124
+ MISSING
125
+ - open issue [open_issue:aurora.pricing_undecided]: Paid tier pricing is undecided: $5 flat vs usage-based.
126
+ ```
127
+
128
+ Feed that pack — MUST/SHOULD/CONTEXT/CONFLICT/MISSING — to your LLM as
129
+ context. Every line carries a declaration id, so answers are citable and
130
+ auditable back to source and evidence.
131
+
132
+ ### Install
133
+
134
+ ```console
135
+ pip install memdsl # or: pip install -e . from a checkout
136
+ memdsl lint examples/alex/
137
+ memdsl query examples/alex/ -q "plan tomorrow morning"
138
+ memdsl explain examples/alex/ decision:aurora.db_postgres_migration
139
+ ```
140
+
141
+ Zero runtime dependencies. Python 3.9+.
142
+
143
+ Note: `memdsl lint examples/alex/` reports **one intentional warning** —
144
+ Alex's `schedule.no_meetings_before_10` boundary declares no `exceptions`,
145
+ and the linter asks you to confirm it is truly unconditional. That nudge
146
+ is the feature; a clean run is `examples/mira/`.
147
+
148
+ ### What's in the box
149
+
150
+ - **A tiny declarative language** (`.mem`): typed declarations
151
+ (`entity`, `fact`, `preference`, `boundary`, `principle`, `decision`,
152
+ `state`, `open_issue`) with force, scope, evidence, relations
153
+ (`supersedes`, `conflicts_with`, `refines`, ...), and lifecycle status.
154
+ Full grammar and semantics in [docs/SPEC.md](docs/SPEC.md).
155
+ - **A linter** with ten diagnostics: dangling symbols, missing evidence,
156
+ ambiguous aliases, stale states, boundaries without exceptions,
157
+ preferences masquerading as laws, unmarked supersede chains.
158
+ - **A query executor** implementing the EvidencePack contract, plus
159
+ `explain` for tracing one declaration's relations and provenance.
160
+ - **Synthetic example personas** (`examples/`) — fictional users "Alex"
161
+ and "Mira" — and a deliberately broken file for the linter demo.
162
+
163
+ ### What memdsl is *not*
164
+
165
+ - **Not a replacement for [Mem0](https://github.com/mem0ai/mem0),
166
+ [Zep](https://www.getzep.com/), or
167
+ [LangMem](https://langchain-ai.github.io/langmem/).** Those are
168
+ retrieval/extraction platforms. memdsl is a *source format and
169
+ contract* for the layer above: what memory means, how strongly it
170
+ binds, and how it is maintained. You could compile `.mem` files into
171
+ any of them.
172
+ - **Not a retrieval engine.** The reference executor is deliberately
173
+ naive lexical matching — enough to demonstrate the contract. Production
174
+ use should plug BM25/embeddings behind the same EvidencePack interface.
175
+ Do not benchmark toy retrieval and conclude the format failed.
176
+ - **Not an auto-writer.** v0.1 has no write pipeline. The spec (§10)
177
+ describes a gated, human-reviewed write path; automation should be
178
+ earned with audited metrics, not assumed.
179
+
180
+ ### Does the approach work?
181
+
182
+ Early evidence from the private system this was extracted from
183
+ (DigitalSelf, single-user): on a 100-question eval over the author's real
184
+ long-term memory, DSL-structured retrieval nearly doubled top-1 precision
185
+ against the same system's tuned RAG baseline (**0.57 vs 0.30**; hit rate
186
+ 0.67 vs 0.53). On public conversational benchmarks (LongMemEval, LoCoMo)
187
+ it performs at parity with baselines under a retrieval-only harness whose
188
+ target mapping is still being audited — we explicitly do *not* claim
189
+ public-benchmark wins. Current honest costs: seconds-level query latency
190
+ at scale in the private implementation (being moved to write-time
191
+ compilation), and n=1 personalization. A reproducible benchmark report
192
+ will be published separately.
193
+
194
+ The interesting unmeasured dimension — and the reason this exists — is
195
+ **compliance, not recall**: existing memory benchmarks test whether an
196
+ agent can *find* a fact, none test whether it *respects* a boundary. A
197
+ boundary-compliance benchmark is the roadmap's centerpiece.
198
+
199
+ ### Related work
200
+
201
+ Typed/structured agent memory is converging fast:
202
+ [MemIR](https://arxiv.org/abs/2605.25869) (typed memory IR, provenance-role
203
+ separation), [Zep/Graphiti](https://www.getzep.com/) (temporal knowledge
204
+ graphs with fact validity windows), [A-Mem](https://arxiv.org/abs/2502.12110)
205
+ (Zettelkasten-style linked notes), [MemOS](https://arxiv.org/abs/2507.03724)
206
+ (memory scheduling), and the `CLAUDE.md`/`AGENTS.md` culture of local,
207
+ reviewable context files. memdsl's position in that landscape: local-first
208
+ plain-text source, an explicit **normative layer** (force + boundaries +
209
+ exceptions + MUST/SHOULD rendering), and code-style diagnostics as a
210
+ first-class surface.
211
+
212
+ ### Roadmap
213
+
214
+ - Target-mapping audit + reproducible benchmark report
215
+ - Boundary-compliance benchmark (does the agent *respect* MUST items?)
216
+ - Pluggable retrieval backends (BM25, embeddings) behind the EvidencePack contract
217
+ - Module directory compilation for query planning
218
+ - Gated write pipeline with review queue
219
+
220
+ ---
221
+
222
+ Today, memdsl defines memory as typed, auditable source code. Future
223
+ runtimes can navigate these declarations the way developers navigate
224
+ code — following relations, inspecting evidence, tracing history, and
225
+ asking for missing information instead of guessing.
226
+
227
+ ### License
228
+
229
+ Code: [MIT](LICEN
memdsl-0.1.0/README.md ADDED
@@ -0,0 +1,211 @@
1
+ # memdsl
2
+
3
+ [English](#english) | [中文](#中文)
4
+
5
+ ## English
6
+
7
+ **Agent memory as normative source code.**
8
+
9
+ Most agent memory systems store what you said. Almost none of them
10
+ distinguish what an agent *must obey* from what it *may consider*. memdsl
11
+ treats long-term memory as a small, typed, lintable source language —
12
+ `.mem` files you can read, review, diff, version, and test — where a
13
+ `boundary` is a rule to enforce, not a fact to recall.
14
+
15
+ ```mem
16
+ preference schedule.deep_work_mornings {
17
+ subject: User
18
+ claim: "Prefers deep work in the morning; meetings after 2pm."
19
+ force: strong
20
+ scope: scheduling
21
+ evidence { source: chat quote: "Stop booking me into morning meetings." }
22
+ }
23
+
24
+ boundary privacy.no_family_in_public {
25
+ subject: User
26
+ rule: "Never include family member names or details in public-facing content."
27
+ force: hard
28
+ scope: global
29
+ exceptions: [user_explicit_override]
30
+ evidence { source: chat quote: "Anything about my family stays out of blog posts. Always." }
31
+ }
32
+ ```
33
+
34
+ The difference matters: a preference shapes suggestions; a boundary binds.
35
+ Flat embeddings of "user said X" erase exactly this distinction, which is
36
+ why agents violate rules their memory technically "contains".
37
+
38
+ ### 30 seconds: same question, one declaration apart
39
+
40
+ Ask an agent to *"draft a public blog post about building Aurora as a
41
+ working parent."* A similarity-ranked memory gives it the old chats where
42
+ the kids' names appear — and nothing that ranks a rule above a reminiscence.
43
+ The retrieved snippets are all just CONTEXT, so the names end up in the post:
44
+
45
+ ```text
46
+ retrieved: "...shipped the sync fix after bedtime, Theo finally sleeping..."
47
+ retrieved: "aurora beta feedback thread..."
48
+ ```
49
+
50
+ With the boundary declared, the evidence pack puts the rule where it cannot
51
+ be missed — in MUST, above every piece of context, whether or not the query
52
+ lexically matched it:
53
+
54
+ ```console
55
+ $ memdsl query examples/alex/ -q "draft a public blog post about aurora"
56
+ MUST
57
+ - [boundary:privacy.no_family_in_public] Never include family member names
58
+ or details in public-facing content. (exceptions: ['user_explicit_override'])
59
+
60
+ CONTEXT
61
+ - [state:aurora.beta_progress] Private beta with 40 testers; ...
62
+ ```
63
+
64
+ Feed the pack to the LLM as context and the compliant behavior is to write
65
+ the post *without* family details — and to be able to cite
66
+ `boundary:privacy.no_family_in_public` as the reason. The pack is the
67
+ prompt; the MUST layer is what changes the answer.
68
+
69
+ ### Lint it, query it
70
+
71
+ Memory that can be wrong deserves a linter:
72
+
73
+ ```console
74
+ $ memdsl lint examples/lint-demo/
75
+ broken.mem:7: error[unresolved_symbol] subject 'User.Barista' is not a declared entity
76
+ broken.mem:20: error[missing_evidence] active fact 'home.timezone' has no evidence block
77
+ broken.mem:28: warning[type_force_mismatch] preference uses force: hard; promote it to a boundary
78
+ broken.mem:41: warning[boundary_without_exception] confirm it is truly unconditional
79
+ broken.mem:53: warning[stale_state] as_of 2025-11-02 is older than 180 days
80
+
81
+ 6 declarations, 2 error(s), 3 warning(s)
82
+ ```
83
+
84
+ Queries return a **layered evidence pack**, not a hit list. Hard
85
+ boundaries surface even when the query doesn't lexically match them;
86
+ declared conflicts are shown, not averaged away; open issues surface as
87
+ gaps instead of being hallucinated over:
88
+
89
+ ```console
90
+ $ memdsl query examples/alex/ -q "should aurora keep the free tier"
91
+ # resolved subjects: Project.Aurora
92
+ MUST
93
+ - [boundary:privacy.no_family_in_public] Never include family member names ...
94
+
95
+ SHOULD
96
+ - (none)
97
+
98
+ CONTEXT
99
+ - [decision:aurora.pricing_free_tier] Keep a permanent free tier.
100
+ - [state:aurora.beta_progress] Private beta with 40 testers; sync is the top complaint. (as_of 2026-06-20)
101
+ - [goal:aurora.revenue_target_2026] Reach $2k MRR from Aurora by end of 2026.
102
+
103
+ CONFLICT
104
+ - [decision:aurora.pricing_free_tier] conflicts_with [aurora.revenue_target_2026]
105
+
106
+ MISSING
107
+ - open issue [open_issue:aurora.pricing_undecided]: Paid tier pricing is undecided: $5 flat vs usage-based.
108
+ ```
109
+
110
+ Feed that pack — MUST/SHOULD/CONTEXT/CONFLICT/MISSING — to your LLM as
111
+ context. Every line carries a declaration id, so answers are citable and
112
+ auditable back to source and evidence.
113
+
114
+ ### Install
115
+
116
+ ```console
117
+ pip install memdsl # or: pip install -e . from a checkout
118
+ memdsl lint examples/alex/
119
+ memdsl query examples/alex/ -q "plan tomorrow morning"
120
+ memdsl explain examples/alex/ decision:aurora.db_postgres_migration
121
+ ```
122
+
123
+ Zero runtime dependencies. Python 3.9+.
124
+
125
+ Note: `memdsl lint examples/alex/` reports **one intentional warning** —
126
+ Alex's `schedule.no_meetings_before_10` boundary declares no `exceptions`,
127
+ and the linter asks you to confirm it is truly unconditional. That nudge
128
+ is the feature; a clean run is `examples/mira/`.
129
+
130
+ ### What's in the box
131
+
132
+ - **A tiny declarative language** (`.mem`): typed declarations
133
+ (`entity`, `fact`, `preference`, `boundary`, `principle`, `decision`,
134
+ `state`, `open_issue`) with force, scope, evidence, relations
135
+ (`supersedes`, `conflicts_with`, `refines`, ...), and lifecycle status.
136
+ Full grammar and semantics in [docs/SPEC.md](docs/SPEC.md).
137
+ - **A linter** with ten diagnostics: dangling symbols, missing evidence,
138
+ ambiguous aliases, stale states, boundaries without exceptions,
139
+ preferences masquerading as laws, unmarked supersede chains.
140
+ - **A query executor** implementing the EvidencePack contract, plus
141
+ `explain` for tracing one declaration's relations and provenance.
142
+ - **Synthetic example personas** (`examples/`) — fictional users "Alex"
143
+ and "Mira" — and a deliberately broken file for the linter demo.
144
+
145
+ ### What memdsl is *not*
146
+
147
+ - **Not a replacement for [Mem0](https://github.com/mem0ai/mem0),
148
+ [Zep](https://www.getzep.com/), or
149
+ [LangMem](https://langchain-ai.github.io/langmem/).** Those are
150
+ retrieval/extraction platforms. memdsl is a *source format and
151
+ contract* for the layer above: what memory means, how strongly it
152
+ binds, and how it is maintained. You could compile `.mem` files into
153
+ any of them.
154
+ - **Not a retrieval engine.** The reference executor is deliberately
155
+ naive lexical matching — enough to demonstrate the contract. Production
156
+ use should plug BM25/embeddings behind the same EvidencePack interface.
157
+ Do not benchmark toy retrieval and conclude the format failed.
158
+ - **Not an auto-writer.** v0.1 has no write pipeline. The spec (§10)
159
+ describes a gated, human-reviewed write path; automation should be
160
+ earned with audited metrics, not assumed.
161
+
162
+ ### Does the approach work?
163
+
164
+ Early evidence from the private system this was extracted from
165
+ (DigitalSelf, single-user): on a 100-question eval over the author's real
166
+ long-term memory, DSL-structured retrieval nearly doubled top-1 precision
167
+ against the same system's tuned RAG baseline (**0.57 vs 0.30**; hit rate
168
+ 0.67 vs 0.53). On public conversational benchmarks (LongMemEval, LoCoMo)
169
+ it performs at parity with baselines under a retrieval-only harness whose
170
+ target mapping is still being audited — we explicitly do *not* claim
171
+ public-benchmark wins. Current honest costs: seconds-level query latency
172
+ at scale in the private implementation (being moved to write-time
173
+ compilation), and n=1 personalization. A reproducible benchmark report
174
+ will be published separately.
175
+
176
+ The interesting unmeasured dimension — and the reason this exists — is
177
+ **compliance, not recall**: existing memory benchmarks test whether an
178
+ agent can *find* a fact, none test whether it *respects* a boundary. A
179
+ boundary-compliance benchmark is the roadmap's centerpiece.
180
+
181
+ ### Related work
182
+
183
+ Typed/structured agent memory is converging fast:
184
+ [MemIR](https://arxiv.org/abs/2605.25869) (typed memory IR, provenance-role
185
+ separation), [Zep/Graphiti](https://www.getzep.com/) (temporal knowledge
186
+ graphs with fact validity windows), [A-Mem](https://arxiv.org/abs/2502.12110)
187
+ (Zettelkasten-style linked notes), [MemOS](https://arxiv.org/abs/2507.03724)
188
+ (memory scheduling), and the `CLAUDE.md`/`AGENTS.md` culture of local,
189
+ reviewable context files. memdsl's position in that landscape: local-first
190
+ plain-text source, an explicit **normative layer** (force + boundaries +
191
+ exceptions + MUST/SHOULD rendering), and code-style diagnostics as a
192
+ first-class surface.
193
+
194
+ ### Roadmap
195
+
196
+ - Target-mapping audit + reproducible benchmark report
197
+ - Boundary-compliance benchmark (does the agent *respect* MUST items?)
198
+ - Pluggable retrieval backends (BM25, embeddings) behind the EvidencePack contract
199
+ - Module directory compilation for query planning
200
+ - Gated write pipeline with review queue
201
+
202
+ ---
203
+
204
+ Today, memdsl defines memory as typed, auditable source code. Future
205
+ runtimes can navigate these declarations the way developers navigate
206
+ code — following relations, inspecting evidence, tracing history, and
207
+ asking for missing information instead of guessing.
208
+
209
+ ### License
210
+
211
+ Code: [MIT](LICEN