tulving 0.0.1__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 (55) hide show
  1. tulving-0.0.1/.claude/scheduled_tasks.lock +1 -0
  2. tulving-0.0.1/CLAUDE.md +136 -0
  3. tulving-0.0.1/PKG-INFO +45 -0
  4. tulving-0.0.1/README.md +28 -0
  5. tulving-0.0.1/docs/README.md +30 -0
  6. tulving-0.0.1/docs/adrs/README.md +28 -0
  7. tulving-0.0.1/docs/adrs/adr-001-python-first.md +16 -0
  8. tulving-0.0.1/docs/adrs/adr-002-sdk-plus-mcp.md +20 -0
  9. tulving-0.0.1/docs/adrs/adr-003-sqlite-default.md +21 -0
  10. tulving-0.0.1/docs/adrs/adr-004-local-embeddings-default.md +20 -0
  11. tulving-0.0.1/docs/adrs/adr-005-four-retrieval-modes.md +23 -0
  12. tulving-0.0.1/docs/adrs/adr-006-decisions-never-decay.md +20 -0
  13. tulving-0.0.1/docs/adrs/adr-007-json-serializable-content.md +16 -0
  14. tulving-0.0.1/docs/adrs/adr-008-agent-id-trust-model.md +21 -0
  15. tulving-0.0.1/docs/adrs/adr-009-summarization-archives-not-deletes.md +21 -0
  16. tulving-0.0.1/docs/adrs/adr-010-security-first.md +31 -0
  17. tulving-0.0.1/docs/adrs/adr-011-kairos-as-sibling-not-dependency.md +21 -0
  18. tulving-0.0.1/docs/adrs/adr-012-mcp-tool-design.md +30 -0
  19. tulving-0.0.1/docs/adrs/adr-013-session-detection.md +32 -0
  20. tulving-0.0.1/docs/adrs/adr-014-contradiction-detection.md +30 -0
  21. tulving-0.0.1/docs/adrs/adr-015-concurrency-model.md +31 -0
  22. tulving-0.0.1/docs/adrs/adr-016-v01-scope.md +51 -0
  23. tulving-0.0.1/docs/adrs/adr-017-project-name.md +44 -0
  24. tulving-0.0.1/docs/architecture/architecture.md +279 -0
  25. tulving-0.0.1/docs/architecture/database-strategy.md +164 -0
  26. tulving-0.0.1/docs/legacy_docs/CLAUDE.md +273 -0
  27. tulving-0.0.1/docs/legacy_docs/architecture.md +407 -0
  28. tulving-0.0.1/docs/legacy_docs/kairos-tulving-integration.md +258 -0
  29. tulving-0.0.1/docs/legacy_docs/phase2-module1-entity-extractor.md +69 -0
  30. tulving-0.0.1/docs/legacy_docs/phase2-module2-relationship-store.md +73 -0
  31. tulving-0.0.1/docs/legacy_docs/phase2-module3-graph-query.md +53 -0
  32. tulving-0.0.1/docs/legacy_docs/phase3-module4-working-context.md +39 -0
  33. tulving-0.0.1/docs/legacy_docs/phase4-module1-memory-scoping.md +52 -0
  34. tulving-0.0.1/docs/legacy_docs/phase4-module2-conflict-resolution.md +42 -0
  35. tulving-0.0.1/docs/legacy_docs/phase4-module3-subscriptions.md +49 -0
  36. tulving-0.0.1/docs/legacy_docs/phase4-module4-agent-registry.md +61 -0
  37. tulving-0.0.1/docs/legacy_docs/phase5-module1-kairos-integration.md +81 -0
  38. tulving-0.0.1/docs/project-management/market-research.md +123 -0
  39. tulving-0.0.1/docs/project-management/revision-plan.md +139 -0
  40. tulving-0.0.1/docs/specs/adapters-embeddings.md +110 -0
  41. tulving-0.0.1/docs/specs/adapters-llm.md +80 -0
  42. tulving-0.0.1/docs/specs/adapters-storage.md +109 -0
  43. tulving-0.0.1/docs/specs/context-curator.md +208 -0
  44. tulving-0.0.1/docs/specs/context-decay-eviction.md +137 -0
  45. tulving-0.0.1/docs/specs/context-lifecycle.md +338 -0
  46. tulving-0.0.1/docs/specs/context-summarizer.md +98 -0
  47. tulving-0.0.1/docs/specs/core-entry-model.md +163 -0
  48. tulving-0.0.1/docs/specs/core-kv-index.md +93 -0
  49. tulving-0.0.1/docs/specs/core-memory-store.md +228 -0
  50. tulving-0.0.1/docs/specs/core-semantic-index.md +160 -0
  51. tulving-0.0.1/docs/specs/export-import.md +99 -0
  52. tulving-0.0.1/docs/specs/mcp-server.md +307 -0
  53. tulving-0.0.1/docs/v0.1-overview.md +130 -0
  54. tulving-0.0.1/pyproject.toml +27 -0
  55. tulving-0.0.1/tulving/__init__.py +12 -0
@@ -0,0 +1 @@
1
+ {"sessionId":"f5b5d2a0-03e6-446c-903b-19003d524a39","pid":65688,"procStart":"639186885348535720","acquiredAt":1783117493637}
@@ -0,0 +1,136 @@
1
+ # CLAUDE.md — Tulving Project Instructions
2
+
3
+ > Project instructions for Claude Code. Scope: **v0.1.0 only** (ADR-016).
4
+
5
+ ---
6
+
7
+ ## Current State — READ FIRST
8
+
9
+ **Pre-development.** No source code exists yet. **Do not start coding until the owner gives the green light.**
10
+
11
+ Document authority order (when they disagree, higher wins):
12
+ 1. `docs/project-management/revision-plan.md` — audit corrections, decisions D1–D12
13
+ 2. `docs/architecture/architecture.md` + `docs/adrs/adr-015`, `adr-016`
14
+ 3. `docs/specs/*.md` — module specs (predate the audit; apply D1–D12 when implementing)
15
+ 4. `docs/legacy_docs/` — **superseded; never implement from these**
16
+
17
+ Reader-friendly scope tour: `docs/v0.1-overview.md`.
18
+
19
+ **Pending owner decisions (do not act without instruction):**
20
+ - Green light to begin coding.
21
+
22
+ **Naming (resolved 2026-07-03, ADR-017):** the project is **Tulving** — named after Endel Tulving, the psychologist who established that memory has types (episodic vs semantic), mirroring this SDK's typed-memory model. Formerly "Engram" (dropped: collision with the funded engram.org). PyPI name `tulving` verified available — register early. The future Kairos integration package will be `kairos-ai-tulving`.
23
+
24
+ ---
25
+
26
+ ## Project Overview
27
+
28
+ A model-agnostic Python SDK giving a single AI agent persistent, structured, searchable working memory, with **token-budget context curation (`curate(query, token_budget)`) as the headline primitive**. Also runs as a local MCP server for Claude Code. Zero infrastructure: one SQLite file; vectors optional.
29
+
30
+ **v0.1.0 ships:** core engine (store/get/search, typed memories, key-supersede) · curation + orient mode · lazy decay & eviction · per-agent sessions with summarization · MCP server (6 tools) · embedding/LLM adapters + JSON export.
31
+ **Deferred (one line):** knowledge graph, all multi-agent machinery, semantic contradiction detection, extra formats/backends — see ADR-016.
32
+
33
+ ## Kairos (sibling project)
34
+
35
+ Reference implementation for patterns, security stance, and testing methodology: `C:\Users\abrah\OneDrive\Documents\Projects\ClaudeCode\Kairos\kairos` · https://github.com/govanxa/kairos
36
+
37
+ - PyPI package is **`kairos-ai`** (never `kairos-sdk`); core is zero-dependency — match that discipline.
38
+ - Plugins ship as separate packages in a `plugins/` monorepo; **`kairos-ai-evidence`** (0.2.0) is the worked example and the packaging model for the future Tulving↔Kairos integration.
39
+ - Integration facts for later: `Workflow(hooks=[...])` with `ExecutorHooks` subclasses (there is no `plugins=` kwarg for hooks; `ctx.memory` injection is impossible); `kairos-ai-evidence` verdicts (verified/conflicting/insufficient) are the candidate backend for v0.2 contradiction detection.
40
+
41
+ ---
42
+
43
+ ## Non-Negotiable Design Decisions (from the audit — full detail in revision-plan.md)
44
+
45
+ 1. **Upsert (D1):** `store()` on an existing key supersedes — archive old (`SUPERSEDED`), back-link, insert new. Never raise on duplicate key.
46
+ 2. **Lazy decay (D2):** importance computed on read: `base_importance * 0.5^(hours_since_last_access / half_life[type])`. No startup decay pass. `evict()` exempts `pinned` and `DECISION`.
47
+ 3. **Data model (D3):** `last_accessed_at` (updated on get/search-hit/curate-inclusion), `archive_reason` enum, partial unique index `UNIQUE(key) WHERE archived=0`, `memory_tags` junction table, `meta` table `{schema_version, embedding_model_id, dimension, distance_metric}`, `source_entry_ids` on summaries.
48
+ 4. **Concurrency (ADR-015):** one process/many threads; advisory lock file refuses a second writer; SQLite embedding BLOBs are source of truth, `.hnsw` is a rebuildable cache; DB write first, reconcile at `startup()`; warn on OneDrive/network paths.
49
+ 5. **hnswlib realities:** int-label↔UUID mapping; `mark_deleted` + rebuild-on-threshold compaction; `max_elements` resize policy; `space='cosine'`, `score = 1 - distance`; exclusive lock on index writes; over-fetch to survive post-filtering.
50
+ 6. **Exceptions (D6):** `TulvingError` → `MemoryStoreError`, `StorageError`, `SecurityError`, `ConfigError`, `VectorIndexError`, `ScopeError`. **Never** define `MemoryError` or `IndexError` (builtin shadows).
51
+ 7. **Identity (D7):** `agent_id` bound at `Memory(...)` construction.
52
+ 8. **Cheap `__init__` (D8):** lifecycle work lives in explicit `startup()` — time-boxed, non-fatal, single-runner. Constructors never call LLMs or full-table scan.
53
+ 9. **Per-agent sessions:** active-session checks and abandonment detection scoped by `agent_id`, per-session `last_activity_at`.
54
+ 10. **MCP server:** thin wrapper; tools = `store`, `get`, `search`, `curate`, `forget`, `list_keys` (orient = `curate(mode="orient")`); async handlers offload to a thread pool; `llm=None` degrades loudly, never silently; SIGTERM flush is best-effort — startup recovery is primary.
55
+
56
+ ---
57
+
58
+ ## Quick Reference
59
+
60
+ ```bash
61
+ pip install -e ".[dev]"
62
+ pytest
63
+ pytest --cov=tulving --cov-report=term-missing
64
+ mypy tulving/ # strict
65
+ ruff check tulving/ tests/ && ruff format tulving/ tests/
66
+ tulving-mcp --memory-path ./test_memory
67
+ ```
68
+
69
+ ## Project Structure (v0.1.0)
70
+
71
+ ```
72
+ tulving/
73
+ ├── CLAUDE.md ← you are here
74
+ ├── pyproject.toml
75
+ ├── docs/ ← see docs/README.md for the map
76
+ ├── tulving/
77
+ │ ├── __init__.py ← public API exports
78
+ │ ├── enums.py ← MemoryType, MatchType, ArchiveReason, SessionStatus
79
+ │ ├── exceptions.py ← TulvingError hierarchy (decision 6)
80
+ │ ├── security.py ← redact (keys + content), leaf-name sanitize, path containment
81
+ │ ├── memory.py ← Memory (primary API) + startup()
82
+ │ ├── entry.py ← MemoryEntry, SourceInfo, Relationship
83
+ │ ├── store.py ← MemoryStore (CRUD engine)
84
+ │ ├── kv_index.py ← exact match + prefix scan (no namespaces)
85
+ │ ├── semantic_index.py ← label mapping, mark_deleted, compaction
86
+ │ ├── context/
87
+ │ │ ├── curator.py ← ContextCurator (token-budget curation, orient mode)
88
+ │ │ ├── summarizer.py ← call-budgeted, source back-links
89
+ │ │ ├── decay.py ← lazy decay + reason-aware eviction
90
+ │ │ └── lifecycle.py ← per-agent sessions, gap detection
91
+ │ ├── adapters/
92
+ │ │ ├── embeddings.py ← protocol + LocalEmbedder (extra) + OpenAIEmbedder
93
+ │ │ ├── llm.py ← protocol + one adapter, call budget
94
+ │ │ └── storage.py ← protocol + SQLiteBackend + InMemoryBackend
95
+ │ ├── mcp/server.py ← 6 MCP tools, thread-pool offload
96
+ │ └── export/formats.py ← JSON round-trip (re-embed on import, ID remap)
97
+ ├── tests/ ← mirrors source
98
+ └── examples/
99
+ ```
100
+
101
+ ## Build Order (TDD)
102
+
103
+ 1. `enums.py`, `exceptions.py`
104
+ 2. `tests/test_security.py` → `security.py`
105
+ 3. `tests/test_entry.py` → `entry.py`
106
+ 4. `adapters/storage.py` (SQLite WAL + InMemory; D3 schema; `PRAGMA user_version` migrations)
107
+ 5. `tests/test_store.py` → `store.py`
108
+ 6. `tests/test_kv_index.py` → `kv_index.py`
109
+ 7. `adapters/embeddings.py`
110
+ 8. `tests/test_semantic_index.py` → `semantic_index.py`
111
+ 9. `tests/test_memory.py` → `memory.py` (integration; `startup()`; lock file)
112
+ 10. `tests/test_curator.py` → `context/curator.py`
113
+ 11. `tests/test_decay.py` → `context/decay.py`
114
+ 12. `tests/test_summarizer.py` → `context/summarizer.py`
115
+ 13. `tests/test_lifecycle.py` → `context/lifecycle.py`
116
+ 14. `tests/test_mcp_server.py` → `mcp/server.py`
117
+ 15. `tests/test_export.py` → `export/formats.py`
118
+
119
+ **Mandatory regression tests from the audit:** decay idempotency across repeated startups · supersede against an archived row holding the same key · search excludes archived vectors · curate with oversize/tiny/empty budgets · startup never abandons another agent's session · adapter swap (any model change) forces rebuild · batch-created entries are searchable · purge refuses summarization sources unless explicit · DECISION/pinned survive evict at importance ~0 · second process on same path is refused.
120
+
121
+ ## Coding Standards
122
+
123
+ - Python 3.11+; `str | None`; `@dataclass` for data, `Protocol` for interfaces
124
+ - `ruff format` / `ruff check`; `mypy` strict; line length 100; Google docstrings
125
+ - pytest, TDD; 90%+ coverage on core; InMemoryBackend in tests; mock all LLM/embedding calls
126
+ - **Dependencies:** core = stdlib + `hnswlib`. Extras: `[local]` (sentence-transformers/torch — never core), `[mcp]`, `[openai]`, `[postgres]`, `[kairos]` → `kairos-ai`. Token counting: `tiktoken` if available, `len/4` fallback with safety margin — never block on it.
127
+
128
+ ## Security Requirements
129
+
130
+ 1. Redaction covers key names **and** content (token-shape regexes, word-boundary patterns) in exports, MCP responses, curated context.
131
+ 2. `[a-zA-Z0-9_-]` whitelist for leaf names only; directories via realpath containment (Windows-aware).
132
+ 3. Credentials from environment only; adapters reject inline API keys.
133
+ 4. `ScopeError` ≠ `SecurityError` (decision 6).
134
+ 5. MCP server local-only; no network binding.
135
+ 6. No encryption at rest in v0.1 — documented warning; don't store secrets.
136
+ 7. 100% coverage on security functions.
tulving-0.0.1/PKG-INFO ADDED
@@ -0,0 +1,45 @@
1
+ Metadata-Version: 2.4
2
+ Name: tulving
3
+ Version: 0.0.1
4
+ Summary: The context-budget engine for AI agents — persistent typed memory with token-budget curation. Name-holding pre-release; v0.1 in active development.
5
+ Project-URL: Author, https://github.com/govanxa
6
+ Author-email: Abraham <abraham@fscoder.dev>
7
+ Keywords: agents,ai,context,curation,llm,mcp,memory
8
+ Classifier: Development Status :: 1 - Planning
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.11
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Classifier: Programming Language :: Python :: 3.13
14
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
15
+ Requires-Python: >=3.11
16
+ Description-Content-Type: text/markdown
17
+
18
+ # Tulving
19
+
20
+ > *The context-budget engine for AI agents.*
21
+
22
+ **Status: pre-release (0.0.1) — name-holding release; v0.1 is in active development.**
23
+
24
+ Tulving is a model-agnostic Python SDK that gives an AI agent persistent, structured, searchable working memory — and, as its headline capability, curates that memory back into a fixed token budget:
25
+
26
+ ```python
27
+ ctx = memory.curate("resuming work on the auth refactor", token_budget=4000)
28
+ ```
29
+
30
+ Named after **Endel Tulving**, the psychologist who established that memory has types (episodic vs semantic). Typed memories — facts, decisions, observations, plans, summaries, each with its own lifecycle — are Tulving's core data model.
31
+
32
+ ## What v0.1 will ship
33
+
34
+ - **Core memory engine** — store / get / semantic search over typed memories; zero infrastructure (one SQLite file, local vectors optional, no API key required)
35
+ - **Token-budget context curation** — `curate(query, token_budget)` selects, ranks, and trims memories into a prompt-ready block; `orient` mode for cold starts
36
+ - **Lazy decay & eviction** — importance fades per-type over time; decisions never decay; nothing is destroyed, only archived
37
+ - **Sessions** — per-agent session tracking, end-of-session summarization, abandoned-session recovery
38
+ - **MCP server** — six tools for Claude Code and other MCP clients, with single-writer safety
39
+ - **Adapters & export** — pluggable embeddings/LLM, JSON round-trip export
40
+
41
+ By the same author: [Kairos](https://github.com/govanxa/kairos) (`kairos-ai`) — contract-enforced AI workflows. A `kairos-ai-tulving` integration plugin is planned.
42
+
43
+ ## License
44
+
45
+ TBD (MIT or Apache 2.0) — will be finalized with the v0.1 release.
@@ -0,0 +1,28 @@
1
+ # Tulving
2
+
3
+ > *The context-budget engine for AI agents.*
4
+
5
+ **Status: pre-release (0.0.1) — name-holding release; v0.1 is in active development.**
6
+
7
+ Tulving is a model-agnostic Python SDK that gives an AI agent persistent, structured, searchable working memory — and, as its headline capability, curates that memory back into a fixed token budget:
8
+
9
+ ```python
10
+ ctx = memory.curate("resuming work on the auth refactor", token_budget=4000)
11
+ ```
12
+
13
+ Named after **Endel Tulving**, the psychologist who established that memory has types (episodic vs semantic). Typed memories — facts, decisions, observations, plans, summaries, each with its own lifecycle — are Tulving's core data model.
14
+
15
+ ## What v0.1 will ship
16
+
17
+ - **Core memory engine** — store / get / semantic search over typed memories; zero infrastructure (one SQLite file, local vectors optional, no API key required)
18
+ - **Token-budget context curation** — `curate(query, token_budget)` selects, ranks, and trims memories into a prompt-ready block; `orient` mode for cold starts
19
+ - **Lazy decay & eviction** — importance fades per-type over time; decisions never decay; nothing is destroyed, only archived
20
+ - **Sessions** — per-agent session tracking, end-of-session summarization, abandoned-session recovery
21
+ - **MCP server** — six tools for Claude Code and other MCP clients, with single-writer safety
22
+ - **Adapters & export** — pluggable embeddings/LLM, JSON round-trip export
23
+
24
+ By the same author: [Kairos](https://github.com/govanxa/kairos) (`kairos-ai`) — contract-enforced AI workflows. A `kairos-ai-tulving` integration plugin is planned.
25
+
26
+ ## License
27
+
28
+ TBD (MIT or Apache 2.0) — will be finalized with the v0.1 release.
@@ -0,0 +1,30 @@
1
+ # Tulving Documentation
2
+
3
+ > **Scope:** v0.1.0 — single-agent, local-first memory SDK with token-budget context curation, plus an MCP server for Claude Code.
4
+
5
+ ## Start here
6
+
7
+ 1. **[v0.1-overview.md](v0.1-overview.md)** — plain-language tour of the six capability areas. Read this first.
8
+ 2. **[architecture/architecture.md](architecture/architecture.md)** — the canonical v0.1.0 architecture: API surface, storage model, concurrency, security, future roadmap.
9
+ 3. **[specs/](specs/)** — per-module specifications (subject to the corrections in the revision plan).
10
+
11
+ ## Folder map
12
+
13
+ | Folder | Contents |
14
+ |---|---|
15
+ | [architecture/](architecture/) | v0.1.0 architecture + [database strategy](architecture/database-strategy.md) |
16
+ | [adrs/](adrs/) | Architecture Decision Records 001–016 ([index](adrs/README.md)) |
17
+ | [specs/](specs/) | Module specs in play for v0.1.0 (Phase 1 core, Phase 3 context, Phase 5 adapters/MCP) |
18
+ | [project-management/](project-management/) | [Revision plan](project-management/revision-plan.md) (audit corrections D1–D12, authoritative over specs) · [Market research](project-management/market-research.md) |
19
+ | [legacy_docs/](legacy_docs/) | ⚠️ **Superseded — do not implement from these.** Old architecture, deferred Phase 2/4 specs, and Kairos integration docs written against APIs that don't exist. Reference material for future redesigns only. |
20
+
21
+ ## Authority order (when documents disagree)
22
+
23
+ 1. `project-management/revision-plan.md` (decisions D1–D12)
24
+ 2. `architecture/architecture.md` + ADR-015/016
25
+ 3. Module specs in `specs/`
26
+ 4. Anything in `legacy_docs/` — historical only
27
+
28
+ ## Naming
29
+
30
+ - **Tulving** (final, 2026-07-03) — after Endel Tulving, who established that memory has types; see [ADR-017](adrs/adr-017-project-name.md). Formerly "Engram" (dropped: collision with the unrelated, funded engram.org).
@@ -0,0 +1,28 @@
1
+ # Architecture Decision Records (ADRs)
2
+
3
+ > **Project:** Tulving
4
+ > **Convention:** ADRs are numbered sequentially. Once accepted, they are immutable; superseding decisions get a new ADR.
5
+
6
+ ---
7
+
8
+ ## Index
9
+
10
+ | ADR | Title | Status | Notes |
11
+ |---|---|---|---|
12
+ | [001](adr-001-python-first.md) | Python as primary language | Accepted | |
13
+ | [002](adr-002-sdk-plus-mcp.md) | SDK library + MCP server distribution | Accepted | |
14
+ | [003](adr-003-sqlite-default.md) | SQLite + hnswlib as default backends | Accepted | Concurrency boundaries defined in ADR-015 |
15
+ | [004](adr-004-local-embeddings-default.md) | Local embeddings by default | Accepted | Revised: `[local]` extra (torch never in core); "no network" softened to "after first-run model fetch" — see revision plan D9 |
16
+ | [005](adr-005-four-retrieval-modes.md) | Four retrieval modes | Partially deferred | Graph retrieval deferred with Phase 2 (ADR-016); v0.1 = key, semantic, temporal |
17
+ | [006](adr-006-decisions-never-decay.md) | Decision memories never auto-decay or auto-evict | Accepted | |
18
+ | [007](adr-007-json-serializable-content.md) | String content, JSON-serializable metadata | Accepted | |
19
+ | [008](adr-008-agent-id-trust-model.md) | Agent identity trusted from orchestrator | Accepted | Reframed: cooperative isolation, not authZ — scope violations raise `ScopeError`, not `SecurityError` |
20
+ | [009](adr-009-summarization-archives-not-deletes.md) | Summarization archives originals, never destroys | Accepted | Enforced via `source_entry_ids` back-links (revision plan D3) |
21
+ | [010](adr-010-security-first.md) | Security as a first-class concern | Accepted | Revised per revision plan D10: content scanning, word-boundary patterns, path containment, no-encryption position |
22
+ | [011](adr-011-kairos-as-sibling-not-dependency.md) | Kairos is a sibling, not a dependency | Accepted | Dependency name is `kairos-ai` (not `kairos-sdk`); integration deferred, will follow the `kairos-ai-evidence` plugin packaging pattern |
23
+ | [012](adr-012-mcp-tool-design.md) | MCP tools designed for agent ergonomics | Accepted | Tool set trimmed to six in v0.1 (see ADR-016) |
24
+ | [013](adr-013-session-detection.md) | Three-layer session detection with graceful degradation | Accepted | Sessions are per-agent; startup recovery is the primary mechanism |
25
+ | [014](adr-014-contradiction-detection.md) | Contradiction detection flags, not blocks | Partially deferred | v0.1 keeps only deterministic key-collision supersede; semantic detection deferred (similarity ≠ contradiction) — candidate backend: `kairos-ai-evidence` |
26
+ | [015](adr-015-concurrency-model.md) | Single-writer concurrency model for Tier-1 | Accepted | **New** — one process/many threads; advisory lock file; index as rebuildable cache |
27
+ | [016](adr-016-v01-scope.md) | v0.1.0 scope: single-agent core, curation-first | Accepted | **New** — the in/out table; defers Phase 2, Phase 4, semantic contradiction |
28
+ | [017](adr-017-project-name.md) | Project name: Tulving | Accepted | **New** — replaces working title "Engram"; future Kairos plugin: `kairos-ai-tulving` |
@@ -0,0 +1,16 @@
1
+ # ADR-001: Python as Primary Language
2
+
3
+ **Status:** Accepted
4
+ **Date:** 2026-05-04
5
+ **Modules affected:** All
6
+
7
+ ## Context
8
+ Tulving must ship in the language its target users work in. The AI agent ecosystem is overwhelmingly Python.
9
+
10
+ ## Decision
11
+ **Python first. Same rationale as Kairos ADR-001.** TypeScript port considered for future phases.
12
+
13
+ ## Consequences
14
+ - Immediate adoption by the agent developer community.
15
+ - Consistent with Kairos — both SDKs in the same language simplifies integration.
16
+ - Modern Python (3.11+) with type hints, `@dataclass`, `Protocol`.
@@ -0,0 +1,20 @@
1
+ # ADR-002: SDK Library + MCP Server Distribution
2
+
3
+ **Status:** Accepted
4
+ **Date:** 2026-05-04
5
+ **Modules affected:** All, 5.6
6
+
7
+ ## Context
8
+ Tulving needs to be usable both as a Python library imported into code AND as a standalone server that Claude Code or other MCP clients can connect to.
9
+
10
+ ## Decision
11
+ **Tulving ships as both: `pip install tulving` for SDK use, `pip install tulving[mcp]` for MCP server.**
12
+
13
+ - The SDK is the primary distribution. Developers import it directly.
14
+ - The MCP server wraps the SDK and exposes it as tools via the Model Context Protocol.
15
+ - Both use the same underlying `Memory` class. The MCP server is a thin transport layer.
16
+
17
+ ## Consequences
18
+ - Claude Code users get Tulving without writing Python — just configure the MCP server.
19
+ - Python developers get a clean import API without MCP overhead.
20
+ - The MCP dependency (`mcp` package) is optional — core SDK has no dependency on it.
@@ -0,0 +1,21 @@
1
+ # ADR-003: SQLite + hnswlib as Default Backends
2
+
3
+ **Status:** Accepted
4
+ **Date:** 2026-05-04
5
+ **Modules affected:** 1.1, 1.3, 5.4
6
+
7
+ ## Context
8
+ Tulving needs persistence and vector search. The default must require zero infrastructure — no separate database server, no cloud service, no Docker.
9
+
10
+ ## Decision
11
+ **SQLite for structured storage, hnswlib for vector indexing. Both are file-based, zero-config, and embedded.**
12
+
13
+ - SQLite in WAL mode for concurrent read support.
14
+ - hnswlib for approximate nearest neighbor search (HNSW algorithm).
15
+ - Both persist to the same directory: `./tulving_memory/tulving.db` and `./tulving_memory/tulving.hnsw`.
16
+ - Production backends (Postgres, Redis, Pinecone, Qdrant) available via Phase 5 adapters.
17
+
18
+ ## Consequences
19
+ - `pip install tulving` → works immediately. No infrastructure setup.
20
+ - Performance is sufficient for single-agent and small multi-agent workloads (thousands to low millions of entries).
21
+ - Large-scale production deployments switch backends without code changes.
@@ -0,0 +1,20 @@
1
+ # ADR-004: Local Embeddings by Default, No API Key Required
2
+
3
+ **Status:** Accepted
4
+ **Date:** 2026-05-04
5
+ **Modules affected:** 1.3, 5.2
6
+
7
+ ## Context
8
+ Semantic search requires embedding vectors. Cloud embedding APIs (OpenAI, Cohere) are higher quality but require API keys and network access. Local models are lower quality but zero-friction.
9
+
10
+ ## Decision
11
+ **Default: local `sentence-transformers/all-MiniLM-L6-v2` (384 dims). No API key required.**
12
+
13
+ - `pip install tulving` includes the local embedder. Semantic search works immediately.
14
+ - Cloud embedders available as optional extras: `pip install tulving[openai]`.
15
+ - Switching embedders requires re-embedding existing memories (handled by `rebuild()` command).
16
+
17
+ ## Consequences
18
+ - Zero-friction first experience. No account, no API key, no network.
19
+ - Lower embedding quality than cloud models — acceptable for working memory use cases.
20
+ - The `sentence-transformers` dependency adds ~500MB for the model. Documented in install notes.
@@ -0,0 +1,23 @@
1
+ # ADR-005: Four Retrieval Modes, Not One
2
+
3
+ **Status:** Accepted
4
+ **Date:** 2026-05-04
5
+ **Modules affected:** 1.2, 1.3, 2.3, 3.1
6
+
7
+ ## Context
8
+ Most memory systems default to one retrieval mode — usually vector search. But agents ask different kinds of questions that demand different access patterns.
9
+
10
+ ## Decision
11
+ **Four retrieval modes, each optimized for a different query pattern:**
12
+
13
+ 1. **Key-Value** — "What did I decide about X?" → exact match, deterministic, instant.
14
+ 2. **Semantic** — "What do I know about pricing?" → similarity search, fuzzy, ranked.
15
+ 3. **Graph** — "What's related to Acme Corp?" → traversal, structured relationships.
16
+ 4. **Temporal** — "What did I learn yesterday?" → time-filtered scan.
17
+
18
+ The Context Curator (3.1) combines all four and ranks results by a weighted score.
19
+
20
+ ## Consequences
21
+ - More complex curation logic than a single-mode system.
22
+ - Each mode has its own index (KV, vector, graph, timestamp), increasing storage.
23
+ - Agents get the right answer from the right access pattern instead of one-size-fits-all semantic search.
@@ -0,0 +1,20 @@
1
+ # ADR-006: Decision Memories Never Auto-Decay or Auto-Evict
2
+
3
+ **Status:** Accepted
4
+ **Date:** 2026-05-04
5
+ **Modules affected:** 1.4, 3.3
6
+
7
+ ## Context
8
+ The decay system reduces importance over time. But some memories are architecturally important to preserve indefinitely — particularly decisions and their reasoning.
9
+
10
+ ## Decision
11
+ **Memories with `type=DECISION` are exempt from automatic decay and automatic eviction. They can only be manually deleted by the agent or developer.**
12
+
13
+ - Decisions are also exempt from auto-summarization. They are preserved verbatim.
14
+ - An agent can still manually reduce a decision's importance or delete it.
15
+ - This ensures that an agent can always answer "why did I choose X?" even weeks later.
16
+
17
+ ## Consequences
18
+ - Decision entries accumulate over time. For very long-running projects, this could become large.
19
+ - The developer can explicitly archive old decisions if storage is a concern.
20
+ - The curation system still ranks decisions by relevance — old irrelevant decisions won't dominate the context window.
@@ -0,0 +1,16 @@
1
+ # ADR-007: Memory Content is Always String, Metadata is JSON-Serializable
2
+
3
+ **Status:** Accepted
4
+ **Date:** 2026-05-04
5
+ **Modules affected:** 1.4, 1.1
6
+
7
+ ## Context
8
+ Memories need to be embeddable (for semantic search), serializable (for export/import), and displayable (in curated context). Binary data, Python objects, and non-text content break all three.
9
+
10
+ ## Decision
11
+ **`MemoryEntry.content` is always `str`. All metadata fields (tags, relationships, source) are JSON-serializable.** No binary data, no Python objects, no file references.
12
+
13
+ ## Consequences
14
+ - Simple, predictable data model. Every memory can be embedded, exported, and displayed.
15
+ - Agents that need to reference files store the path/URL as a string, not the file itself.
16
+ - Structured data should be serialized to a readable string format before storing (e.g., JSON dump of a dict).
@@ -0,0 +1,21 @@
1
+ # ADR-008: Agent Identity Trusted from Orchestrator, Not Authenticated
2
+
3
+ **Status:** Accepted
4
+ **Date:** 2026-05-04
5
+ **Modules affected:** 4.4, 4.1
6
+
7
+ ## Context
8
+ Multi-agent memory requires knowing which agent is reading/writing. But Tulving is a library, not a service — it has no login system, no tokens, no auth server.
9
+
10
+ ## Decision
11
+ **Tulving trusts the `agent_id` provided by the caller. It does not authenticate agents.**
12
+
13
+ - The orchestrator (Kairos, custom code, MCP server) is responsible for providing the correct agent_id.
14
+ - Tulving enforces scoping rules based on the provided agent_id, but does not verify identity.
15
+ - All operations are logged in the audit trail with the provided agent_id.
16
+
17
+ ## Consequences
18
+ - Simple integration: no auth overhead.
19
+ - A malicious caller can impersonate any agent by providing a fake agent_id.
20
+ - This is acceptable because Tulving runs locally or within a trusted environment. If the caller is compromised, auth wouldn't help — they're already in the process.
21
+ - For hosted/remote deployments (future), a token-based auth layer should be added at the transport level (MCP server or API gateway), not at the Memory class level.
@@ -0,0 +1,21 @@
1
+ # ADR-009: Summarization Archives Originals, Never Destroys
2
+
3
+ **Status:** Accepted
4
+ **Date:** 2026-05-04
5
+ **Modules affected:** 3.2, 3.3
6
+
7
+ ## Context
8
+ When old memories are summarized into a digest, what happens to the originals? Deleting them saves space but is irreversible. Keeping them doubles storage.
9
+
10
+ ## Decision
11
+ **Summarized entries are archived (soft-deleted), never hard-deleted. Archived entries are excluded from search and curation but remain in storage for recovery.**
12
+
13
+ - The summary entry links to its source entries via `relationships`.
14
+ - Archived entries can be unarchived manually.
15
+ - Hard-delete is available but must be explicitly called: `memory.delete(key, hard=True)`.
16
+ - A `purge_archived` CLI command handles bulk cleanup when storage is a concern.
17
+
18
+ ## Consequences
19
+ - No data loss from automatic processes. All summarization is recoverable.
20
+ - Storage grows over time. For very long-running projects, periodic purging may be needed.
21
+ - Archived entries do not appear in search results, curated context, or key listings.
@@ -0,0 +1,31 @@
1
+ # ADR-010: Security as a First-Class Concern
2
+
3
+ **Status:** Accepted
4
+ **Date:** 2026-05-04
5
+ **Modules affected:** All
6
+
7
+ ## Context
8
+ Memory content may include sensitive data: API keys observed during work, personal information, credentials in error messages, proprietary business logic. Tulving must handle this safely.
9
+
10
+ ## Decision
11
+ **Security controls are mandatory, enforced in code, never deferred. Same stance as Kairos ADR-016.**
12
+
13
+ ### Mandatory Controls
14
+
15
+ 1. **Sensitive key redaction.** Keys matching `DEFAULT_SENSITIVE_PATTERNS` (password, secret, token, key, credential, auth, api_key, private) are redacted in all exports, MCP tool responses, and curated context output. Raw values accessible only via direct `memory.get()`.
16
+
17
+ 2. **Content sanitization.** Memory content is always `str` (ADR-007). No executable objects in storage.
18
+
19
+ 3. **Path sanitization.** Memory paths, export file paths, and any file I/O validate against traversal attacks. Same rules as Kairos.
20
+
21
+ 4. **Credential security.** Embedding and LLM adapter credentials from environment variables only. Inline credentials raise `SecurityError`.
22
+
23
+ 5. **MCP server security.** Local-only binding. No network exposure. Memory path validated.
24
+
25
+ 6. **Scope enforcement.** Multi-agent scoping raises `SecurityError` on unauthorized access, not silent empty results.
26
+
27
+ 7. **Audit trail.** All store/read/update/delete operations logged with agent_id and timestamp.
28
+
29
+ ## Consequences
30
+ - Every security control has tests in `tests/test_security.py`.
31
+ - Secure defaults. Insecure modes (e.g., disabling redaction) require explicit opt-in.
@@ -0,0 +1,21 @@
1
+ # ADR-011: Kairos is a Sibling, Not a Dependency
2
+
3
+ **Status:** Accepted
4
+ **Date:** 2026-05-04
5
+ **Modules affected:** 5.1
6
+
7
+ ## Context
8
+ Tulving and Kairos are natural complements. But making Tulving depend on Kairos (or vice versa) would force users to install both even if they only want one.
9
+
10
+ ## Decision
11
+ **Tulving has zero dependency on Kairos. The Kairos integration (Module 5.1) is an optional extra: `pip install tulving[kairos]`.**
12
+
13
+ - Tulving works standalone. It doesn't need Kairos to function.
14
+ - Kairos works standalone. It doesn't need Tulving to function.
15
+ - When both are installed, `TulvingPlugin` provides seamless integration.
16
+ - The integration code lives in `tulving/integrations/kairos.py` and imports Kairos conditionally.
17
+
18
+ ## Consequences
19
+ - Users can adopt one without the other.
20
+ - The integration module must handle the case where Kairos is not installed (graceful import error).
21
+ - Both SDKs share the same design philosophy (model-agnostic, security-first, Python-first) but have independent release cycles.
@@ -0,0 +1,30 @@
1
+ # ADR-012: MCP Tools Designed for Agent Ergonomics
2
+
3
+ **Status:** Accepted
4
+ **Date:** 2026-05-04
5
+ **Modules affected:** 5.6
6
+
7
+ ## Context
8
+ The MCP server exposes Tulving as tools that Claude Code (or any MCP client) calls. Tool design directly impacts how naturally an agent uses memory.
9
+
10
+ ## Decision
11
+ **Tools are designed for how agents think, not how the SDK is structured.**
12
+
13
+ ### Design Principles
14
+
15
+ 1. **Descriptive names.** `memory_store`, `memory_search`, `memory_curate` — not `create_entry`, `vector_search`, `build_context`. The names match what an agent would naturally say: "let me store this" / "let me search for that."
16
+
17
+ 2. **Minimal required parameters.** Only `content` + `type` required for `memory_store`. Everything else is optional with sensible defaults. An agent shouldn't need to think about importance scores or tags for a quick note.
18
+
19
+ 3. **Rich optional parameters.** When the agent wants precision — specific tags, importance, key — the parameters are available but not forced.
20
+
21
+ 4. **Context-ready output.** `memory_curate` returns formatted text ready to use as context, not raw JSON that the agent must parse and format. `memory_search` returns entries with relevance scores.
22
+
23
+ 5. **One tool per intent.** `memory_store` and `memory_get` are separate tools, not one `memory_crud` tool with an `action` parameter. Each tool maps to one thing the agent wants to do.
24
+
25
+ 6. **Tool descriptions guide agent behavior.** Descriptions include when and why to use the tool, not just what it does. Example: "Store a memory — a fact, decision, observation, or plan — for later retrieval."
26
+
27
+ ## Consequences
28
+ - Tool count is higher (8 tools) than a minimal API would require.
29
+ - Each tool is simple and single-purpose — the agent doesn't need to read complex schemas.
30
+ - Claude Code and other MCP clients will naturally discover and use the right tool for the right situation.
@@ -0,0 +1,32 @@
1
+ # ADR-013: Three-Layer Session Detection with Graceful Degradation
2
+
3
+ **Status:** Accepted
4
+ **Date:** 2026-05-04
5
+ **Modules affected:** 3.5, 5.1, 5.6, Memory class
6
+
7
+ ---
8
+
9
+ ## Context
10
+
11
+ Tulving is used in three modes: as a standalone Python SDK, as a Kairos plugin, and as an MCP server for Claude Code. Each mode has different session boundary signals. A standalone SDK has no natural "session ended" event — the developer's process might exit without warning.
12
+
13
+ Without session management, memory grows unbounded and end-of-session summarization never triggers.
14
+
15
+ ## Decision
16
+
17
+ **Three session boundary mechanisms, layered from most reliable to least:**
18
+
19
+ 1. **Explicit API** — `memory.session_start()` / `session.end()` or `with memory.session():` context manager. Works in all modes. The developer controls the boundary.
20
+
21
+ 2. **Integration hooks** — MCP server shutdown (SIGTERM/SIGINT) and Kairos `on_workflow_complete` call `session.end()` internally. Automatic for those modes.
22
+
23
+ 3. **Activity-gap detection** — On next `Memory.__init__`, detect unclosed sessions by checking for `status=ACTIVE` sessions with no recent activity (configurable `inactivity_threshold`, default 30 minutes). Run end-of-session summarization on the abandoned session's memories. Automatic fallback for ungraceful exits.
24
+
25
+ Each layer degrades gracefully to the next. If the developer calls `session.end()`, that's the boundary. If they don't but the MCP server shuts down cleanly, the hook handles it. If the process crashes, activity-gap detection catches it on next startup.
26
+
27
+ ## Consequences
28
+
29
+ - Every mode gets session management — no mode is left without lifecycle support.
30
+ - Explicit API is the preferred path, documented prominently.
31
+ - Activity-gap detection introduces a small delay on startup (scanning for abandoned sessions). Acceptable for the reliability it provides.
32
+ - The 30-minute default threshold may misidentify long pauses during active work as session boundaries. Configurable via `LifecycleConfig.inactivity_threshold`.
@@ -0,0 +1,30 @@
1
+ # ADR-014: Contradiction Detection Flags, Not Blocks
2
+
3
+ **Status:** Accepted
4
+ **Date:** 2026-05-04
5
+ **Modules affected:** 3.5, 1.2
6
+
7
+ ---
8
+
9
+ ## Context
10
+
11
+ Agents store facts that may later become incorrect or contradicted by new information. The system needs to handle the case where "Acme has 3 products" is stored on Monday and "Acme has 5 products" is stored on Thursday.
12
+
13
+ Two approaches: block the conflicting store and force resolution, or accept the store and flag the contradiction.
14
+
15
+ ## Decision
16
+
17
+ **Contradictions are detected and flagged, not blocked.** The default policy is `flag`.
18
+
19
+ - **Key collisions** (same key, new value): the old entry is archived with a `superseded` tag, the new entry is stored with a `supersedes:{old_id}` relationship. This is an upsert — deterministic, no ambiguity.
20
+
21
+ - **Semantic contradictions** (different keys, conflicting content): detected by checking semantic similarity on store. If similarity > 0.85 and content diverges, both entries are tagged `contradiction:unresolved`. The agent or developer resolves manually.
22
+
23
+ - **Staleness**: memories not accessed for `staleness_threshold_days` (default 30) are tagged `potentially_stale`. The curator annotates them with age when included in curated context. The agent sees the warning and can verify, update, or discard.
24
+
25
+ ## Consequences
26
+
27
+ - Stores never fail due to contradictions — the system is always accepting.
28
+ - Contradictions surface as tags, not errors — the agent or developer decides resolution.
29
+ - Staleness is a soft signal, not a hard rule — old memories are deprioritized, not deleted.
30
+ - The `ask` contradiction policy is available for high-stakes scenarios where the developer wants the store to pause and return the contradiction for explicit resolution.