openmnemex 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.
- openmnemex-0.1.0/LICENSE +21 -0
- openmnemex-0.1.0/PKG-INFO +426 -0
- openmnemex-0.1.0/README.md +397 -0
- openmnemex-0.1.0/config/mnemex.config.md +72 -0
- openmnemex-0.1.0/integrations/opencode/mnemex.ts +86 -0
- openmnemex-0.1.0/openmnemex.egg-info/PKG-INFO +426 -0
- openmnemex-0.1.0/openmnemex.egg-info/SOURCES.txt +156 -0
- openmnemex-0.1.0/openmnemex.egg-info/dependency_links.txt +1 -0
- openmnemex-0.1.0/openmnemex.egg-info/entry_points.txt +3 -0
- openmnemex-0.1.0/openmnemex.egg-info/requires.txt +6 -0
- openmnemex-0.1.0/openmnemex.egg-info/top_level.txt +1 -0
- openmnemex-0.1.0/pyproject.toml +94 -0
- openmnemex-0.1.0/scripts/__init__.py +36 -0
- openmnemex-0.1.0/scripts/mnx_binding.py +1078 -0
- openmnemex-0.1.0/scripts/mnx_common.py +593 -0
- openmnemex-0.1.0/scripts/mnx_compact.py +327 -0
- openmnemex-0.1.0/scripts/mnx_config.py +514 -0
- openmnemex-0.1.0/scripts/mnx_decay.py +136 -0
- openmnemex-0.1.0/scripts/mnx_doctor.py +447 -0
- openmnemex-0.1.0/scripts/mnx_er.py +328 -0
- openmnemex-0.1.0/scripts/mnx_glean.py +146 -0
- openmnemex-0.1.0/scripts/mnx_hooks.py +767 -0
- openmnemex-0.1.0/scripts/mnx_index.py +471 -0
- openmnemex-0.1.0/scripts/mnx_ingest.py +516 -0
- openmnemex-0.1.0/scripts/mnx_init.py +347 -0
- openmnemex-0.1.0/scripts/mnx_install.py +741 -0
- openmnemex-0.1.0/scripts/mnx_lock.py +259 -0
- openmnemex-0.1.0/scripts/mnx_mcp.py +1282 -0
- openmnemex-0.1.0/scripts/mnx_mesh.py +254 -0
- openmnemex-0.1.0/scripts/mnx_node.py +373 -0
- openmnemex-0.1.0/scripts/mnx_phonebook.py +352 -0
- openmnemex-0.1.0/scripts/mnx_procedures.py +202 -0
- openmnemex-0.1.0/scripts/mnx_promote.py +792 -0
- openmnemex-0.1.0/scripts/mnx_read.py +305 -0
- openmnemex-0.1.0/scripts/mnx_regen.py +199 -0
- openmnemex-0.1.0/scripts/mnx_resolve.py +208 -0
- openmnemex-0.1.0/scripts/mnx_simindex.py +194 -0
- openmnemex-0.1.0/scripts/mnx_stage.py +681 -0
- openmnemex-0.1.0/scripts/mnx_stamp.py +202 -0
- openmnemex-0.1.0/scripts/mnx_status.py +232 -0
- openmnemex-0.1.0/setup.cfg +4 -0
- openmnemex-0.1.0/templates/binding.template.md +23 -0
- openmnemex-0.1.0/templates/gitattributes.template +29 -0
- openmnemex-0.1.0/templates/gitignore.template +10 -0
- openmnemex-0.1.0/templates/index.template.md +20 -0
- openmnemex-0.1.0/templates/node.template.md +38 -0
- openmnemex-0.1.0/templates/procedures/capture.core.md +150 -0
- openmnemex-0.1.0/templates/procedures/curate.core.md +13 -0
- openmnemex-0.1.0/templates/procedures/fragments/_digests/capture.md +4 -0
- openmnemex-0.1.0/templates/procedures/fragments/_digests/ingest.md +9 -0
- openmnemex-0.1.0/templates/procedures/fragments/_digests/promote.md +4 -0
- openmnemex-0.1.0/templates/procedures/fragments/_digests/read.md +4 -0
- openmnemex-0.1.0/templates/procedures/fragments/capture/bind_status.claude.md +2 -0
- openmnemex-0.1.0/templates/procedures/fragments/capture/bind_status.mcp.md +1 -0
- openmnemex-0.1.0/templates/procedures/fragments/capture/capture_add.claude.md +14 -0
- openmnemex-0.1.0/templates/procedures/fragments/capture/capture_add.mcp.md +2 -0
- openmnemex-0.1.0/templates/procedures/fragments/capture/capture_drop_flag.claude.md +1 -0
- openmnemex-0.1.0/templates/procedures/fragments/capture/capture_drop_flag.mcp.md +1 -0
- openmnemex-0.1.0/templates/procedures/fragments/capture/capture_drop_flag2.claude.md +1 -0
- openmnemex-0.1.0/templates/procedures/fragments/capture/capture_drop_flag2.mcp.md +1 -0
- openmnemex-0.1.0/templates/procedures/fragments/capture/capture_status_budget.claude.md +1 -0
- openmnemex-0.1.0/templates/procedures/fragments/capture/capture_status_budget.mcp.md +1 -0
- openmnemex-0.1.0/templates/procedures/fragments/capture/capture_status_list.claude.md +3 -0
- openmnemex-0.1.0/templates/procedures/fragments/capture/capture_status_list.mcp.md +1 -0
- openmnemex-0.1.0/templates/procedures/fragments/capture/glean_step.claude.md +3 -0
- openmnemex-0.1.0/templates/procedures/fragments/capture/glean_step.mcp.md +1 -0
- openmnemex-0.1.0/templates/procedures/fragments/capture/init.claude.md +1 -0
- openmnemex-0.1.0/templates/procedures/fragments/capture/init.mcp.md +1 -0
- openmnemex-0.1.0/templates/procedures/fragments/capture/promote.claude.md +1 -0
- openmnemex-0.1.0/templates/procedures/fragments/capture/promote.mcp.md +1 -0
- openmnemex-0.1.0/templates/procedures/fragments/curate/capture_discard_all.claude.md +1 -0
- openmnemex-0.1.0/templates/procedures/fragments/curate/capture_discard_all.mcp.md +1 -0
- openmnemex-0.1.0/templates/procedures/fragments/curate/capture_drop.claude.md +1 -0
- openmnemex-0.1.0/templates/procedures/fragments/curate/capture_drop.mcp.md +1 -0
- openmnemex-0.1.0/templates/procedures/fragments/curate/capture_status_inline.claude.md +1 -0
- openmnemex-0.1.0/templates/procedures/fragments/curate/capture_status_inline.mcp.md +1 -0
- openmnemex-0.1.0/templates/procedures/fragments/curate/status.claude.md +1 -0
- openmnemex-0.1.0/templates/procedures/fragments/curate/status.mcp.md +1 -0
- openmnemex-0.1.0/templates/procedures/fragments/curate/trigger_condition.claude.md +3 -0
- openmnemex-0.1.0/templates/procedures/fragments/curate/trigger_condition.mcp.md +3 -0
- openmnemex-0.1.0/templates/procedures/fragments/promote/bulk_mode.claude.md +56 -0
- openmnemex-0.1.0/templates/procedures/fragments/promote/bulk_mode.mcp.md +28 -0
- openmnemex-0.1.0/templates/procedures/fragments/promote/consolidate_invoke.claude.md +2 -0
- openmnemex-0.1.0/templates/procedures/fragments/promote/consolidate_invoke.mcp.md +3 -0
- openmnemex-0.1.0/templates/procedures/fragments/promote/preflight.claude.md +18 -0
- openmnemex-0.1.0/templates/procedures/fragments/promote/preflight.mcp.md +10 -0
- openmnemex-0.1.0/templates/procedures/fragments/promote/retry_push.claude.md +11 -0
- openmnemex-0.1.0/templates/procedures/fragments/promote/retry_push.mcp.md +8 -0
- openmnemex-0.1.0/templates/procedures/fragments/promote/step1_flush.claude.md +4 -0
- openmnemex-0.1.0/templates/procedures/fragments/promote/step1_flush.mcp.md +4 -0
- openmnemex-0.1.0/templates/procedures/fragments/promote/step5_apply.claude.md +30 -0
- openmnemex-0.1.0/templates/procedures/fragments/promote/step5_apply.mcp.md +31 -0
- openmnemex-0.1.0/templates/procedures/fragments/read/bind_status.claude.md +2 -0
- openmnemex-0.1.0/templates/procedures/fragments/read/bind_status.mcp.md +1 -0
- openmnemex-0.1.0/templates/procedures/fragments/read/capture.claude.md +1 -0
- openmnemex-0.1.0/templates/procedures/fragments/read/capture.mcp.md +1 -0
- openmnemex-0.1.0/templates/procedures/fragments/read/empty_fork_check.claude.md +1 -0
- openmnemex-0.1.0/templates/procedures/fragments/read/empty_fork_check.mcp.md +1 -0
- openmnemex-0.1.0/templates/procedures/fragments/read/ingest.claude.md +1 -0
- openmnemex-0.1.0/templates/procedures/fragments/read/ingest.mcp.md +1 -0
- openmnemex-0.1.0/templates/procedures/fragments/read/init.claude.md +1 -0
- openmnemex-0.1.0/templates/procedures/fragments/read/init.mcp.md +1 -0
- openmnemex-0.1.0/templates/procedures/fragments/read/promote.claude.md +1 -0
- openmnemex-0.1.0/templates/procedures/fragments/read/promote.mcp.md +1 -0
- openmnemex-0.1.0/templates/procedures/fragments/read/read_cluster.claude.md +3 -0
- openmnemex-0.1.0/templates/procedures/fragments/read/read_cluster.mcp.md +1 -0
- openmnemex-0.1.0/templates/procedures/fragments/read/read_frontier.claude.md +3 -0
- openmnemex-0.1.0/templates/procedures/fragments/read/read_frontier.mcp.md +1 -0
- openmnemex-0.1.0/templates/procedures/fragments/read/read_nodes.claude.md +4 -0
- openmnemex-0.1.0/templates/procedures/fragments/read/read_nodes.mcp.md +1 -0
- openmnemex-0.1.0/templates/procedures/fragments/read/record_usage_revalidated.claude.md +4 -0
- openmnemex-0.1.0/templates/procedures/fragments/read/record_usage_revalidated.mcp.md +1 -0
- openmnemex-0.1.0/templates/procedures/fragments/read/record_usage_role.claude.md +4 -0
- openmnemex-0.1.0/templates/procedures/fragments/read/record_usage_role.mcp.md +1 -0
- openmnemex-0.1.0/templates/procedures/promote.core.md +141 -0
- openmnemex-0.1.0/templates/procedures/read.core.md +151 -0
- openmnemex-0.1.0/templates/registry.template.md +2 -0
- openmnemex-0.1.0/templates/user-config.template.md +15 -0
- openmnemex-0.1.0/tests/test_binding.py +974 -0
- openmnemex-0.1.0/tests/test_cli_guard.py +98 -0
- openmnemex-0.1.0/tests/test_common.py +168 -0
- openmnemex-0.1.0/tests/test_compact.py +385 -0
- openmnemex-0.1.0/tests/test_config.py +252 -0
- openmnemex-0.1.0/tests/test_decay.py +163 -0
- openmnemex-0.1.0/tests/test_doc_links.py +85 -0
- openmnemex-0.1.0/tests/test_doctor.py +313 -0
- openmnemex-0.1.0/tests/test_entrypoints.py +196 -0
- openmnemex-0.1.0/tests/test_er.py +250 -0
- openmnemex-0.1.0/tests/test_freshness.py +224 -0
- openmnemex-0.1.0/tests/test_glean.py +166 -0
- openmnemex-0.1.0/tests/test_hooks.py +552 -0
- openmnemex-0.1.0/tests/test_index.py +323 -0
- openmnemex-0.1.0/tests/test_ingest_e2e.py +138 -0
- openmnemex-0.1.0/tests/test_ingest_manifest.py +138 -0
- openmnemex-0.1.0/tests/test_ingest_walk.py +141 -0
- openmnemex-0.1.0/tests/test_install_emit.py +631 -0
- openmnemex-0.1.0/tests/test_lock.py +224 -0
- openmnemex-0.1.0/tests/test_mcp_binding_health.py +563 -0
- openmnemex-0.1.0/tests/test_mcp_concurrency.py +231 -0
- openmnemex-0.1.0/tests/test_mcp_ingest.py +306 -0
- openmnemex-0.1.0/tests/test_mcp_promote.py +402 -0
- openmnemex-0.1.0/tests/test_mcp_server.py +710 -0
- openmnemex-0.1.0/tests/test_mesh.py +315 -0
- openmnemex-0.1.0/tests/test_node.py +230 -0
- openmnemex-0.1.0/tests/test_packaging_imports.py +168 -0
- openmnemex-0.1.0/tests/test_phonebook.py +260 -0
- openmnemex-0.1.0/tests/test_procedure_sync.py +95 -0
- openmnemex-0.1.0/tests/test_promote.py +868 -0
- openmnemex-0.1.0/tests/test_read_frontier.py +316 -0
- openmnemex-0.1.0/tests/test_regen.py +173 -0
- openmnemex-0.1.0/tests/test_resolve.py +243 -0
- openmnemex-0.1.0/tests/test_scaffold_gitignore.py +76 -0
- openmnemex-0.1.0/tests/test_scaling_stress.py +366 -0
- openmnemex-0.1.0/tests/test_simindex.py +179 -0
- openmnemex-0.1.0/tests/test_stage.py +474 -0
- openmnemex-0.1.0/tests/test_stage_bulk.py +140 -0
- openmnemex-0.1.0/tests/test_stamp.py +258 -0
- openmnemex-0.1.0/tests/test_status.py +230 -0
openmnemex-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Kriti
|
|
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,426 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: openmnemex
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: OpenMnemex Context Graph — a self-pruning, human-memory-modeled knowledge context graph for AI agents. Markdown in git; no server, no database, no vector store.
|
|
5
|
+
Author: Kriti
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/kritird/OpenMnemex
|
|
8
|
+
Project-URL: Repository, https://github.com/kritird/OpenMnemex
|
|
9
|
+
Project-URL: Issues, https://github.com/kritird/OpenMnemex/issues
|
|
10
|
+
Keywords: agent-memory,llm-memory,long-term-memory,ai-agents,knowledge-graph,context-graph,context-engineering,self-pruning,claude-code,mcp
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
22
|
+
Requires-Python: >=3.9
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
License-File: LICENSE
|
|
25
|
+
Requires-Dist: pyyaml>=6.0
|
|
26
|
+
Provides-Extra: mcp
|
|
27
|
+
Requires-Dist: mcp>=1.2.0; python_version >= "3.10" and extra == "mcp"
|
|
28
|
+
Dynamic: license-file
|
|
29
|
+
|
|
30
|
+
<p align="center">
|
|
31
|
+
<img src="assets/logo.svg" alt="OpenMnemex logo" width="70" valign="middle">
|
|
32
|
+
<img src="assets/banner.svg" alt="OpenMnemex" width="420" valign="middle">
|
|
33
|
+
</p>
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
<p align="center"><b>Auto-memory for LLM agents — it decides what mattered and keeps it, so you don't have to. A self-pruning, human-memory-modeled knowledge context graph.</b></p>
|
|
37
|
+
|
|
38
|
+
<p align="center">
|
|
39
|
+
<img alt="status" src="https://img.shields.io/badge/status-v0.1.0-success">
|
|
40
|
+
<img alt="license" src="https://img.shields.io/badge/license-MIT-blue">
|
|
41
|
+
<img alt="python" src="https://img.shields.io/badge/python-3.9%2B-3776AB?logo=python&logoColor=white">
|
|
42
|
+
<img alt="claude code" src="https://img.shields.io/badge/Claude%20Code-plugin-8A2BE2">
|
|
43
|
+
<img alt="storage" src="https://img.shields.io/badge/storage-Markdown%20%2B%20git-181717?logo=git&logoColor=white">
|
|
44
|
+
<img alt="vectors" src="https://img.shields.io/badge/vectors-none-critical">
|
|
45
|
+
<img alt="token cost" src="https://img.shields.io/badge/reads-token--frugal-0e7a0d">
|
|
46
|
+
</p>
|
|
47
|
+
|
|
48
|
+
> 🧠 Self-curating, navigable, context-budget-aware **agent memory** that judges your session for
|
|
49
|
+
> what's worth keeping — with no vector database, no embedding pipeline, and no server. Just Markdown
|
|
50
|
+
> in a git repo. Works as a Claude Code plugin.
|
|
51
|
+
|
|
52
|
+
Mnemex (from *Mnemosyne*, the personification of memory, + the engineering suffix *-ex*) is a
|
|
53
|
+
specification **and** a Claude Code plugin for capturing the durable knowledge an agent produces —
|
|
54
|
+
the **what** (domain facts) and the **how** (the patterns and review decisions that govern good
|
|
55
|
+
work in a domain) — into a plain-Markdown graph that lives in a git repository, organizes itself
|
|
56
|
+
into human-like memory tiers (**🔥 hot / 🌤️ warm / ❄️ cold**), and forgets what stops being useful while
|
|
57
|
+
protecting what is structurally important.
|
|
58
|
+
|
|
59
|
+
It is designed to give agents long-term, navigable, *context-budget-aware* memory **without a vector
|
|
60
|
+
database, without an embedding pipeline, and without a server.** Routing is structural (folder +
|
|
61
|
+
index traversal), decay is lazy (computed, never swept), and every mutation is a reviewable git
|
|
62
|
+
commit.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
<div align="center">
|
|
67
|
+
|
|
68
|
+
### 🧭 Start here
|
|
69
|
+
|
|
70
|
+
**[✨ Features](FEATURES.md)** · **[🗺️ Overview](docs/overview.md)** · **[🏛️ Architecture](docs/architecture.md)** · **[🧭 User Journey](docs/user-journey.md)**
|
|
71
|
+
|
|
72
|
+
</div>
|
|
73
|
+
|
|
74
|
+
### ⏱️ 60-second quickstart
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
# Claude Code (the full plugin experience — auto-capture hooks, skills):
|
|
78
|
+
/plugin marketplace add kritird/OpenMnemex
|
|
79
|
+
/plugin install mnemex@mnemex-marketplace
|
|
80
|
+
/mnemex:mnx-init # scaffold or bind a graph (guided; a plain local folder by default)
|
|
81
|
+
|
|
82
|
+
# Any other agent (OpenCode / Gemini CLI / Codex / Copilot / Cursor) — one command,
|
|
83
|
+
# creates a local-folder graph, binds it, and pins it into the MCP entry, zero prompts:
|
|
84
|
+
uvx openmnemex install --agent <agent> --init-graph --yes
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Then just work: the first read on the empty graph offers to **seed it from a repo/docs** — or skip
|
|
88
|
+
that and it fills episodically as you go. Full detail: [Install](#-install) below,
|
|
89
|
+
[`docs/agent-setup.md`](docs/agent-setup.md) per agent, [`docs/user-journey.md`](docs/user-journey.md)
|
|
90
|
+
for the day-to-day loop.
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## 💡 Why this exists
|
|
95
|
+
|
|
96
|
+
Agents are excellent at producing knowledge inside a session and terrible at keeping it. The two
|
|
97
|
+
common fixes both have sharp costs:
|
|
98
|
+
|
|
99
|
+
| ❌ Common fix | 💸 The cost it carries |
|
|
100
|
+
|---|---|
|
|
101
|
+
| **Stuff everything into context** | Context bloat, cost, and attention dilution. |
|
|
102
|
+
| **Embed everything into a vector store** | Infrastructure, an embedding pipeline, an index to operate, and opaque retrieval you cannot read or diff. |
|
|
103
|
+
|
|
104
|
+
Mnemex takes a **third path**. Knowledge is **files**. Navigation is the **filesystem plus small index
|
|
105
|
+
files** you read in chunks. Relevance is a **number you compute on demand** from a usage log, modeled
|
|
106
|
+
on the *Ebbinghaus forgetting curve* and *spaced repetition*: things used often stay visible and
|
|
107
|
+
cheap to reach; things unused drift down the tiers and, eventually, die — unless something still
|
|
108
|
+
points at them. The result is a knowledge base that behaves like memory rather than a landfill.
|
|
109
|
+
|
|
110
|
+
```mermaid
|
|
111
|
+
flowchart LR
|
|
112
|
+
A([🤖 Agent builds<br/>something]) --> B{How to keep<br/>the knowledge?}
|
|
113
|
+
B -->|"Stuff context"| C[💸 Bloat + cost]
|
|
114
|
+
B -->|"Vector store"| D[🛠️ Infra + opacity]
|
|
115
|
+
B -->|"Mnemex"| E[📄 Markdown graph<br/>in git]
|
|
116
|
+
E --> F[🔥 Hot · 🌤️ Warm · ❄️ Cold<br/>self-tiering memory]
|
|
117
|
+
F --> G([🔮 Future agent<br/>navigates cheaply])
|
|
118
|
+
classDef good fill:#0e7a0d,stroke:#0a5,color:#fff;
|
|
119
|
+
classDef bad fill:#7a1f1f,stroke:#a33,color:#fff;
|
|
120
|
+
class C,D bad;
|
|
121
|
+
class E,F,G good;
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
The full reasoning behind each design choice is in
|
|
125
|
+
[`docs/rationale-and-concepts.md`](docs/rationale-and-concepts.md).
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## 🧠 It remembers like you do — automatically
|
|
130
|
+
|
|
131
|
+
You don't consciously decide to memorize everything that happens in a conversation. Your mind
|
|
132
|
+
quietly judges, in the background, what was *significant* and what was noise — and keeps the former
|
|
133
|
+
without you ever asking it to. **Mnemex is auto-memory in exactly that sense.** You do the work; it
|
|
134
|
+
watches the session and decides what is worth keeping.
|
|
135
|
+
|
|
136
|
+
When a session ends, Mnemex looks at what actually happened and asks the questions a person would:
|
|
137
|
+
|
|
138
|
+
- **Is this relevant?** — does it generalize beyond this one conversation, or was it throwaway scaffolding?
|
|
139
|
+
- **Is this significant?** — a durable domain fact or a hard-won review decision, versus an incidental detail?
|
|
140
|
+
- **Is this novel?** — something the graph doesn't already know, versus a restatement of what's there?
|
|
141
|
+
|
|
142
|
+
It **captures the knowledge that passes** and **ignores the rest.** Concretely, capture extracts
|
|
143
|
+
candidate atoms from the session and scores each one `now` / `later` / `not-needed` — the explicit
|
|
144
|
+
keep / defer / forget judgment. The author doesn't curate, tag, or decide what to file away; that
|
|
145
|
+
salience call is Mnemex's job, and what survives later rises or decays on its own through the
|
|
146
|
+
🔥 hot / 🌤️ warm / ❄️ cold tiers as it gets used or stops being used.
|
|
147
|
+
|
|
148
|
+
And just like your own memory, being *frequently recalled* is not the same as being *still true*. Mnemex
|
|
149
|
+
tracks that too, on a **separate axis**: every fact carries a `verified` clock, and when it hasn't been
|
|
150
|
+
re-confirmed within a horizon you set (`freshness_ttl_days`), it's flagged ⏳ **stale** the next time it's
|
|
151
|
+
read — even if it's hot — so the agent re-checks it against the source instead of confidently repeating
|
|
152
|
+
something outdated. Confirm it's unchanged and the clock resets for one cheap stamp; find it's wrong and
|
|
153
|
+
the correction flows back in through capture. (Full model:
|
|
154
|
+
[`docs/freshness-and-revalidation.md`](docs/freshness-and-revalidation.md).)
|
|
155
|
+
|
|
156
|
+
The author doesn't worry about any of this. You build; Mnemex remembers what mattered — and flags what may
|
|
157
|
+
have gone stale. 🧭
|
|
158
|
+
|
|
159
|
+
> The judgment is reviewable, not a black box: capture stages locally and you can inspect or
|
|
160
|
+
> un-stage anything (`mnx-status`, `mnx-capture --drop`) before a deliberate `mnx-promote` commits
|
|
161
|
+
> it to the shared graph. *Automatic, but never unaccountable.*
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## 🪙 Built to burn fewer tokens
|
|
166
|
+
|
|
167
|
+
A knowledge base is only worth having if *reading* it is cheap. The two usual approaches quietly tax
|
|
168
|
+
every single query: stuffing prior knowledge into the prompt pays for the whole pile on every turn, and
|
|
169
|
+
vector-RAG pastes the top-*k* retrieved chunks into context each time you ask. Both get **more** expensive
|
|
170
|
+
as the corpus grows.
|
|
171
|
+
|
|
172
|
+
Mnemex is architected the other way: **tier is literally read cost**, so the tokens a read spends scale
|
|
173
|
+
with the *path you take*, not the *size of the graph*. You navigate by reading tiny index heads and open
|
|
174
|
+
only the handful of node bodies you actually commit to.
|
|
175
|
+
|
|
176
|
+
| 🎯 Mechanism | 🪙 Why it spends fewer tokens |
|
|
177
|
+
|---|---|
|
|
178
|
+
| 🧭 **Route, don't retrieve** | You read one-line index heads to *pick a path* (org → team → cluster). Nothing is pasted into context on spec. |
|
|
179
|
+
| 🔥 **Hot = top-K, chunk 1** | The routing head is capacity-bounded — it stays small even in a huge graph, so the baseline read is bounded regardless of node count. |
|
|
180
|
+
| 📚 **Chunked tier reads, stop early** | Read **Hot** first; it's usually enough. **Warm/Cold** only on demand. You rarely load a whole index, never the whole graph. |
|
|
181
|
+
| 🏷️ **Match on denormalized summaries** | Each index row carries the node's `summary`+`aliases`, so you *match without opening a single node body*. |
|
|
182
|
+
| 🔎 **Expand only on commit** | Load only the bodies you'll actually use, within a per-hop token budget — beam search, not "load every neighbor". |
|
|
183
|
+
| 🗑️ **Self-pruning** | Decay + death keep the routing surface small over time — no landfill of dead knowledge to page through. |
|
|
184
|
+
| ⏳ **Trust the fresh, re-check only the stale** | A verified fact is used as-is; you don't re-derive known knowledge from scratch — only a *stale* atom triggers a re-check. |
|
|
185
|
+
|
|
186
|
+
> 💡 **The payoff:** a read is a few small index-head reads **plus only the node bodies you commit to** —
|
|
187
|
+
> not the corpus, not a wall of retrieved chunks. Retrieval stays cheap as the graph grows into the
|
|
188
|
+
> thousands of nodes, which is exactly where naive context-stuffing and RAG get most expensive.
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## 🗺️ The shape in one screen
|
|
193
|
+
|
|
194
|
+
```
|
|
195
|
+
your-knowledge-repo/ ← a normal git repo you point Mnemex at
|
|
196
|
+
index.md ← org router (which teams exist)
|
|
197
|
+
mnemex.config.md ← your tunable parameters (half-life, budgets, cadence …)
|
|
198
|
+
.mnemex/ ← protocol state (locks, high-water marks, version stamps)
|
|
199
|
+
team-payments/
|
|
200
|
+
index.md ← team router (which domains) + HOT / WARM / COLD sections
|
|
201
|
+
registry.md ← append-only usage log (the write buffer)
|
|
202
|
+
cross-links.md ← GENERATED: inter-cluster edges within this team
|
|
203
|
+
settlement/
|
|
204
|
+
index.md ← domain sub-index (chunked: routing head, then node table)
|
|
205
|
+
registry.md
|
|
206
|
+
iso8583-field124.md ← a NODE (pure knowledge; no bookkeeping inside)
|
|
207
|
+
ledger-routing.md
|
|
208
|
+
pat-settlement-recon.md ← a PATTERN node (a "how", with a trigger)
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### How the three file kinds relate
|
|
212
|
+
|
|
213
|
+
```mermaid
|
|
214
|
+
flowchart TD
|
|
215
|
+
subgraph TRUTH["🟢 TRUTH — authored by the LLM"]
|
|
216
|
+
N1[📄 Node<br/>iso8583-field124]
|
|
217
|
+
N2[📄 Node<br/>ledger-routing]
|
|
218
|
+
P1[🧭 Pattern<br/>pat-settlement-recon]
|
|
219
|
+
end
|
|
220
|
+
subgraph DERIVED["🔵 DERIVED — generated by code"]
|
|
221
|
+
IDX[(🗂️ index.md<br/>HOT / WARM / COLD)]
|
|
222
|
+
XL[(🔗 cross-links.md)]
|
|
223
|
+
end
|
|
224
|
+
subgraph TELEMETRY["🟠 TELEMETRY — append-only"]
|
|
225
|
+
REG[(📝 registry.md<br/>usage stamps)]
|
|
226
|
+
end
|
|
227
|
+
N1 -- routes-through --> N2
|
|
228
|
+
P1 -- governs --> N1
|
|
229
|
+
N1 & N2 & P1 -. regenerates .-> IDX
|
|
230
|
+
N1 & N2 & P1 -. boundary edges .-> XL
|
|
231
|
+
REG -. folded at gc .-> IDX
|
|
232
|
+
classDef truth fill:#0e7a0d,stroke:#0a5,color:#fff;
|
|
233
|
+
classDef derived fill:#14507a,stroke:#39c,color:#fff;
|
|
234
|
+
classDef tel fill:#7a4a0d,stroke:#d90,color:#fff;
|
|
235
|
+
class N1,N2,P1 truth;
|
|
236
|
+
class IDX,XL derived;
|
|
237
|
+
class REG tel;
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
Three kinds of file, three jobs (this separation is the core of the design):
|
|
241
|
+
|
|
242
|
+
| File | Holds | Mutated when |
|
|
243
|
+
|---|---|---|
|
|
244
|
+
| 📄 **Node** (`*.md`) | Pure knowledge: summary, body, edges, provenance. | Only on author / re-author / supersede / death / revalidation (`verified`). |
|
|
245
|
+
| 🗂️ **Index** (`index.md`) | Derived navigation + materialized memory state (strength, tier). | Only by the maintenance pass (and write-apply). |
|
|
246
|
+
| 📝 **Registry** (`registry.md`) | Append-only usage stamps. | Appended on confirmed use; truncated only by checkpointed compaction. |
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## ⚙️ The four operations
|
|
251
|
+
|
|
252
|
+
Four of Mnemex's skills are memory operations, each fronted by a slash command. They map to the verbs of
|
|
253
|
+
a memory system (two more skills, `mnx-init` and `mnx-status`, handle setup and status — see below).
|
|
254
|
+
Knowledge writing is split **capture / promote** — the `git commit` vs `git push`/PR of memory.
|
|
255
|
+
|
|
256
|
+
| 🎛️ Command | Skill | What it does | Mutates? |
|
|
257
|
+
|---|---|---|---|
|
|
258
|
+
| 🔍 `/mnemex:mnx-read` | `mnx-read` | Route → read tiered indexes in chunks → **overlay** local staged atoms → expand only needed nodes → **flag stale atoms** for revalidation → emit a **usage manifest** → append stamps for nodes actually used. | Registry append only (pure w.r.t. knowledge). |
|
|
259
|
+
| ✍️ `/mnemex:mnx-capture` | `mnx-capture` | Capture the **current session** (artifact + human review points) → extract atoms → **score** each `now/later/not-needed` → **stage** locally with self-sufficient provenance. Cheap, local, no lock. Also **curates** staging: `--drop <id>` / `--discard-all` un-stage (review via `mnx-status`) — the local un-stage and the hard-cap escape valve. | No — writes only the local staging tier. |
|
|
260
|
+
| 🚀 `/mnemex:mnx-promote` | `mnx-promote` | The deliberate merge: flush stamps → **reconcile + merge** staged atoms (clean-context sub-agent, HITL on contradictions) → **consolidate** the post-merge graph (decay/re-tier/death/edge-hygiene/budget) → doctor → push → clear staging. If a push fails after commit, `--retry-push` lands the existing commit (never re-merges). | Yes — gated, atomic, one commit. |
|
|
261
|
+
| 🩺 `/mnemex:mnx-doctor` | `mnx-doctor` | The validator: checks every invariant (edge targets exist, index matches nodes, denormalized copies are fresh, reverse map consistent, no dangling edges) and can self-heal derived files. | Repair mode only. |
|
|
262
|
+
|
|
263
|
+
The maintenance pass (`mnx-consolidate`) is **internal** — the back half of `mnx-promote`, with no
|
|
264
|
+
standalone slash command.
|
|
265
|
+
|
|
266
|
+
### 🏗️ Bootstrap a whole graph from an existing repo — in one command
|
|
267
|
+
|
|
268
|
+
**You don't start from an empty graph.** Point Mnemex at a repo you already have and it builds the memory
|
|
269
|
+
for you:
|
|
270
|
+
|
|
271
|
+
```bash
|
|
272
|
+
/mnemex:mnx-ingest github.com/acme/payments-service # or a local path
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
`mnx-ingest` reads an entire **code or documentation repository** — no live session needed — and turns years
|
|
276
|
+
of accumulated docs, ADRs, API contracts, and code comments into a live, connected knowledge graph. It does
|
|
277
|
+
**not** dump the repo into a vector store. It **distills**: an LLM mines each file for the durable *facts*
|
|
278
|
+
and *decisions* worth keeping, **collapses the same fact stated five different ways into one well-sourced
|
|
279
|
+
node** (entity resolution), and wires the `[[wiki-links]]` between them — so what lands is *distilled
|
|
280
|
+
memory*, not a RAG index over your source.
|
|
281
|
+
|
|
282
|
+
And it stays honest at scale:
|
|
283
|
+
|
|
284
|
+
- **Two gates, not a thousand.** Approve the scope + routing map once up front, then a single bulk summary at
|
|
285
|
+
the end — **never** per-atom review. A monorepo is one decision, not ten thousand.
|
|
286
|
+
- **Re-runnable and idempotent.** Run it again after the repo changes and it imports **only the diff**; a
|
|
287
|
+
deleted source file surfaces as an *orphan candidate* for you to judge — never silent auto-death.
|
|
288
|
+
- **Safe by construction.** Ingest **only stages** (promote stays the sole writer), **never reads secrets**,
|
|
289
|
+
and **never mutates the source**.
|
|
290
|
+
- **Higher recall for free.** A shared **gleaning** pass ("what did I miss?") lifts extraction completeness —
|
|
291
|
+
and it improves ordinary session capture too.
|
|
292
|
+
|
|
293
|
+
Everything downstream — reconcile, merge, the wiki mesh, consolidate, doctor, push — is the **same pipeline**
|
|
294
|
+
your daily captures already flow through. Full model: [`docs/corpus-ingestion.md`](docs/corpus-ingestion.md).
|
|
295
|
+
|
|
296
|
+
```mermaid
|
|
297
|
+
flowchart LR
|
|
298
|
+
R[🔍 mnx-read<br/><i>recall</i>] -.->|append stamps| REG[(📝 registry)]
|
|
299
|
+
C[✍️ mnx-capture<br/><i>stage locally</i>] -->|atoms| STG[(📥 staging tier)]
|
|
300
|
+
STG -->|reconcile + merge| P[🚀 mnx-promote<br/><i>commit + push</i>]
|
|
301
|
+
REG -->|flush| P
|
|
302
|
+
P -->|consolidate + commit| G[(🗃️ shared graph)]
|
|
303
|
+
G -->|validate / heal| D[🩺 mnx-doctor]
|
|
304
|
+
D --> G
|
|
305
|
+
classDef op fill:#4b2e83,stroke:#a98ce0,color:#fff;
|
|
306
|
+
classDef store fill:#14507a,stroke:#39c,color:#fff;
|
|
307
|
+
class R,C,P,D op;
|
|
308
|
+
class REG,STG,G store;
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
Two further skills round out the surface. `/mnemex:mnx-init` is the setup/preflight: it **binds** a
|
|
312
|
+
project (or your user account) to a graph repo — creating and scaffolding a new graph, or pointing at an
|
|
313
|
+
existing one — and is what every other command resolves first. For a git-remote graph it runs a
|
|
314
|
+
read-only reachability/auth pre-flight before binding and, on failure, offers a no-auth local-folder
|
|
315
|
+
fallback. `/mnemex:mnx-status` is a read-only at-a-glance status: what graph is bound, its kind,
|
|
316
|
+
node/tier counts per team, pending usage stamps, last gc, and a health summary. See
|
|
317
|
+
[`docs/binding-and-graph-sync.md`](docs/binding-and-graph-sync.md).
|
|
318
|
+
|
|
319
|
+
Phase-by-phase breakdowns are in
|
|
320
|
+
[`docs/skills-commands-hooks.md`](docs/skills-commands-hooks.md) and
|
|
321
|
+
[`docs/maintenance-pass-algorithm.md`](docs/maintenance-pass-algorithm.md).
|
|
322
|
+
|
|
323
|
+
---
|
|
324
|
+
|
|
325
|
+
## 📦 Install
|
|
326
|
+
|
|
327
|
+
```bash
|
|
328
|
+
# 1. Install the one runtime dependency (Python standard library covers everything else):
|
|
329
|
+
pip install pyyaml
|
|
330
|
+
|
|
331
|
+
# 2. In Claude Code, add this repo as a marketplace, then install the plugin:
|
|
332
|
+
/plugin marketplace add kritird/OpenMnemex
|
|
333
|
+
/plugin install mnemex@mnemex-marketplace
|
|
334
|
+
|
|
335
|
+
# 3. Scaffold or bind a knowledge repo (the binding step every other command resolves):
|
|
336
|
+
/mnemex:mnx-init
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
> [!TIP]
|
|
340
|
+
> Requirements: Claude Code and Python 3.9+. The only third-party Python package is
|
|
341
|
+
> [`PyYAML`](https://pypi.org/project/PyYAML/) (`pip install pyyaml`); everything else is the
|
|
342
|
+
> standard library. If `PyYAML` is missing, the Mnemex commands report it and tell you to install it
|
|
343
|
+
> rather than failing cryptically.
|
|
344
|
+
|
|
345
|
+
A complete walkthrough — from install to daily usage, with the hooks that fire automatically — is in
|
|
346
|
+
[`docs/user-journey.md`](docs/user-journey.md). 🧭
|
|
347
|
+
|
|
348
|
+
### Other agents
|
|
349
|
+
|
|
350
|
+
Claude Code gets the full plugin experience above (auto-capture hooks, skills). Every other MCP-capable
|
|
351
|
+
agent gets the same read/capture/promote loop over the stdio MCP server, wired up with one command.
|
|
352
|
+
For step-by-step, per-agent instructions (install → what changed → how to verify → which tier to
|
|
353
|
+
expect), see [`docs/agent-setup.md`](docs/agent-setup.md).
|
|
354
|
+
|
|
355
|
+
```bash
|
|
356
|
+
# 60-second start: create a local-folder graph, bind it, and pin it into the entry — zero prompts.
|
|
357
|
+
uvx openmnemex install --agent <agent> --init-graph --yes
|
|
358
|
+
|
|
359
|
+
# …or wire up the server against a graph you already have:
|
|
360
|
+
uvx openmnemex install --agent <agent> [--project|--user] [--pin-graph]
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
`--init-graph` is the no-decisions path: it proposes a plain local folder under your mnemex home
|
|
364
|
+
(no git remote, no credentials — it always succeeds), scaffolds it doctor-clean, binds it as your user
|
|
365
|
+
default, and pins that graph into the agent's MCP entry. Nothing to choose, no dead end on the first
|
|
366
|
+
read. `--pin-graph` **without** a graph now errors clearly instead of silently writing an unpinned
|
|
367
|
+
entry.
|
|
368
|
+
|
|
369
|
+
| `--agent` | Config written | Tier |
|
|
370
|
+
|---|---|---|
|
|
371
|
+
| `opencode` | `opencode.json` + `AGENTS.md` block + `.opencode/plugin/mnemex.ts` (auto-capture hook) | Full |
|
|
372
|
+
| `gemini-cli` | `.gemini/settings.json` / `~/.gemini/settings.json` + `GEMINI.md` block | Assisted |
|
|
373
|
+
| `codex` | `.codex/config.toml` / `~/.codex/config.toml` + `AGENTS.md` block | Assisted |
|
|
374
|
+
| `copilot` | VS Code `.vscode/mcp.json` (project scope only — no static user-scope file) | Assisted |
|
|
375
|
+
| `cursor` | `.cursor/mcp.json` + `.cursor/rules/mnemex.mdc` | Assisted |
|
|
376
|
+
| `claude-code` | `.mcp.json` (project) or `claude mcp add` (user) — an alternative to the plugin above | Full |
|
|
377
|
+
|
|
378
|
+
"Assisted" tier means the host has to be told the read/capture/promote judgment procedure via the
|
|
379
|
+
instruction file (`AGENTS.md`/`GEMINI.md`/rules block) rather than getting it as a Claude Code skill —
|
|
380
|
+
see [`LIMITATIONS.md`](LIMITATIONS.md) for exactly what differs. `--pin-graph` bakes the current
|
|
381
|
+
directory's resolved graph path into the server config so the agent doesn't need to `cd` there first;
|
|
382
|
+
add `--dry-run` to preview the diff or `--check` to verify an existing install; `--uninstall` removes
|
|
383
|
+
exactly the Mnemex entry/block and leaves everything else in the file untouched.
|
|
384
|
+
|
|
385
|
+
> [!NOTE]
|
|
386
|
+
> Not on PyPI yet — until then, `uvx --from git+https://github.com/kritird/OpenMnemex openmnemex
|
|
387
|
+
> install --agent <agent> ...` runs it straight from this repo.
|
|
388
|
+
|
|
389
|
+
JS-native users can skip `uv`/`pip` entirely once published: `npx openmnemex install --agent
|
|
390
|
+
<agent> ...` and `npx openmnemex-mcp` are thin shims that exec the same PyPI package underneath
|
|
391
|
+
(`integrations/npm/`, not yet published — same not-on-PyPI caveat above applies).
|
|
392
|
+
|
|
393
|
+
---
|
|
394
|
+
|
|
395
|
+
## 📚 Read the standard
|
|
396
|
+
|
|
397
|
+
The documents in [`docs/`](docs/) are written to be self-explanatory and read in order. Every acronym
|
|
398
|
+
is expanded on first use and collected in the appendix.
|
|
399
|
+
|
|
400
|
+
| Document | What it covers |
|
|
401
|
+
|---|---|
|
|
402
|
+
| [`overview.md`](docs/overview.md) | The thesis and the design goals, in brief. |
|
|
403
|
+
| [`rationale-and-concepts.md`](docs/rationale-and-concepts.md) | Every core concept and *why* it is shaped that way. |
|
|
404
|
+
| [`architecture.md`](docs/architecture.md) | The three-layer model, memory tiers, lazy-decay math, and *budget = ranking = forgetting*. |
|
|
405
|
+
| [`data-model-and-schemas.md`](docs/data-model-and-schemas.md) | Exact file formats for node, index, registry, cross-links, config, and staged atom. |
|
|
406
|
+
| [`skills-commands-hooks.md`](docs/skills-commands-hooks.md) | The skills, their command surfaces, and the hooks that do what skills cannot. |
|
|
407
|
+
| [`maintenance-pass-algorithm.md`](docs/maintenance-pass-algorithm.md) | The snapshot-then-apply algorithm in full, with ordering guarantees. |
|
|
408
|
+
| [`script-contracts.md`](docs/script-contracts.md) | Deterministic helper contracts (signatures, I/O, invariants). |
|
|
409
|
+
| [`configuration.md`](docs/configuration.md) | The config schema, derived half-life, and config-version re-normalization. |
|
|
410
|
+
| [`invariants-and-failure-modes.md`](docs/invariants-and-failure-modes.md) | The validator invariant list and the failure-mode register with mitigations. |
|
|
411
|
+
| [`appendix-glossary-acronyms.md`](docs/appendix-glossary-acronyms.md) | Glossary, acronym expansions, parameter reference, FAQ, references. |
|
|
412
|
+
| [`binding-and-graph-sync.md`](docs/binding-and-graph-sync.md) | How an author in any repo binds to a separate knowledge-graph repo. |
|
|
413
|
+
| [`staging-and-promotion.md`](docs/staging-and-promotion.md) | The **capture / promote** split: staging tier, atom schema, budgets, read overlay, atomic promote. |
|
|
414
|
+
| [`link-reconciliation.md`](docs/link-reconciliation.md) | 🕸️ The wiki mesh (Step 2b): inline `[[wiki-links]]`, phonebook resolution, red-links + backfill. |
|
|
415
|
+
| [`corpus-ingestion.md`](docs/corpus-ingestion.md) | 🏗️ **Bootstrapping the graph from an existing repo**: `mnx-ingest` as a source adapter — walk → distill → wikify → bulk promote; gleaning + entity resolution. |
|
|
416
|
+
| [`user-journey.md`](docs/user-journey.md) | 🧭 End-to-end journey: install → bind → daily read/capture/promote, with auto-hook touchpoints. |
|
|
417
|
+
| [`multi-graph-and-team-routing.md`](docs/multi-graph-and-team-routing.md) | 🔗 Working across many graphs, teams & orgs: which-graph vs which-team, per-graph staging, worked example. |
|
|
418
|
+
| [`freshness-and-revalidation.md`](docs/freshness-and-revalidation.md) | ⏳ The **freshness** axis: `verified` clock, `stale_after`, read-time refresh cue, `volatility`, timeless-never-dies. |
|
|
419
|
+
|
|
420
|
+
See also: [`FEATURES.md`](FEATURES.md) (feature showcase).
|
|
421
|
+
|
|
422
|
+
---
|
|
423
|
+
|
|
424
|
+
## 📄 License
|
|
425
|
+
|
|
426
|
+
MIT. See [`LICENSE`](LICENSE).
|