trw-memory 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. trw_memory-0.3.0/.env.example +43 -0
  2. trw_memory-0.3.0/.github/workflows/ci.yml +37 -0
  3. trw_memory-0.3.0/.github/workflows/release.yml +39 -0
  4. trw_memory-0.3.0/.gitignore +36 -0
  5. trw_memory-0.3.0/CHANGELOG.md +124 -0
  6. trw_memory-0.3.0/CLAUDE.md +42 -0
  7. trw_memory-0.3.0/LICENSE +41 -0
  8. trw_memory-0.3.0/PKG-INFO +457 -0
  9. trw_memory-0.3.0/README.md +391 -0
  10. trw_memory-0.3.0/benchmarks/__init__.py +1 -0
  11. trw_memory-0.3.0/benchmarks/__main__.py +6 -0
  12. trw_memory-0.3.0/benchmarks/bench_latency.py +152 -0
  13. trw_memory-0.3.0/benchmarks/bench_memory.py +132 -0
  14. trw_memory-0.3.0/benchmarks/bench_quality.py +253 -0
  15. trw_memory-0.3.0/benchmarks/bench_throughput.py +134 -0
  16. trw_memory-0.3.0/benchmarks/corpus.py +424 -0
  17. trw_memory-0.3.0/benchmarks/fixtures/__init__.py +1 -0
  18. trw_memory-0.3.0/benchmarks/fixtures/dedup_set.json +544 -0
  19. trw_memory-0.3.0/benchmarks/fixtures/golden_set.json +1154 -0
  20. trw_memory-0.3.0/benchmarks/runner.py +467 -0
  21. trw_memory-0.3.0/pyproject.toml +216 -0
  22. trw_memory-0.3.0/requirements.lock +92 -0
  23. trw_memory-0.3.0/src/trw_memory/__init__.py +41 -0
  24. trw_memory-0.3.0/src/trw_memory/_logging.py +121 -0
  25. trw_memory-0.3.0/src/trw_memory/_version.py +5 -0
  26. trw_memory-0.3.0/src/trw_memory/adapters/__init__.py +17 -0
  27. trw_memory-0.3.0/src/trw_memory/adapters/openai_compat.py +186 -0
  28. trw_memory-0.3.0/src/trw_memory/cli.py +340 -0
  29. trw_memory-0.3.0/src/trw_memory/cli_formatters.py +156 -0
  30. trw_memory-0.3.0/src/trw_memory/cli_parser.py +92 -0
  31. trw_memory-0.3.0/src/trw_memory/client.py +518 -0
  32. trw_memory-0.3.0/src/trw_memory/decorators.py +22 -0
  33. trw_memory-0.3.0/src/trw_memory/embeddings/__init__.py +6 -0
  34. trw_memory-0.3.0/src/trw_memory/embeddings/interface.py +64 -0
  35. trw_memory-0.3.0/src/trw_memory/embeddings/local.py +169 -0
  36. trw_memory-0.3.0/src/trw_memory/exceptions.py +40 -0
  37. trw_memory-0.3.0/src/trw_memory/graph.py +397 -0
  38. trw_memory-0.3.0/src/trw_memory/integrations/__init__.py +22 -0
  39. trw_memory-0.3.0/src/trw_memory/integrations/_backend.py +121 -0
  40. trw_memory-0.3.0/src/trw_memory/integrations/_mixin.py +32 -0
  41. trw_memory-0.3.0/src/trw_memory/integrations/crewai.py +168 -0
  42. trw_memory-0.3.0/src/trw_memory/integrations/factory.py +117 -0
  43. trw_memory-0.3.0/src/trw_memory/integrations/langchain.py +134 -0
  44. trw_memory-0.3.0/src/trw_memory/integrations/llamaindex.py +210 -0
  45. trw_memory-0.3.0/src/trw_memory/integrations/vscode.py +202 -0
  46. trw_memory-0.3.0/src/trw_memory/lifecycle/__init__.py +48 -0
  47. trw_memory-0.3.0/src/trw_memory/lifecycle/_utils.py +49 -0
  48. trw_memory-0.3.0/src/trw_memory/lifecycle/consolidation.py +521 -0
  49. trw_memory-0.3.0/src/trw_memory/lifecycle/dedup.py +325 -0
  50. trw_memory-0.3.0/src/trw_memory/lifecycle/scoring.py +568 -0
  51. trw_memory-0.3.0/src/trw_memory/lifecycle/tiers/__init__.py +19 -0
  52. trw_memory-0.3.0/src/trw_memory/lifecycle/tiers/_cold.py +195 -0
  53. trw_memory-0.3.0/src/trw_memory/lifecycle/tiers/_manager.py +226 -0
  54. trw_memory-0.3.0/src/trw_memory/lifecycle/tiers/_scoring.py +112 -0
  55. trw_memory-0.3.0/src/trw_memory/lifecycle/tiers/_sweep.py +214 -0
  56. trw_memory-0.3.0/src/trw_memory/lifecycle/tiers/_warm.py +234 -0
  57. trw_memory-0.3.0/src/trw_memory/migration/__init__.py +5 -0
  58. trw_memory-0.3.0/src/trw_memory/migration/from_trw.py +290 -0
  59. trw_memory-0.3.0/src/trw_memory/models/__init__.py +14 -0
  60. trw_memory-0.3.0/src/trw_memory/models/config.py +103 -0
  61. trw_memory-0.3.0/src/trw_memory/models/events.py +35 -0
  62. trw_memory-0.3.0/src/trw_memory/models/memory.py +89 -0
  63. trw_memory-0.3.0/src/trw_memory/namespace.py +14 -0
  64. trw_memory-0.3.0/src/trw_memory/namespaces/__init__.py +18 -0
  65. trw_memory-0.3.0/src/trw_memory/namespaces/manager.py +71 -0
  66. trw_memory-0.3.0/src/trw_memory/namespaces/path_mapping.py +35 -0
  67. trw_memory-0.3.0/src/trw_memory/namespaces/validation.py +45 -0
  68. trw_memory-0.3.0/src/trw_memory/py.typed +0 -0
  69. trw_memory-0.3.0/src/trw_memory/retrieval/__init__.py +25 -0
  70. trw_memory-0.3.0/src/trw_memory/retrieval/bm25.py +128 -0
  71. trw_memory-0.3.0/src/trw_memory/retrieval/dense.py +134 -0
  72. trw_memory-0.3.0/src/trw_memory/retrieval/fusion.py +64 -0
  73. trw_memory-0.3.0/src/trw_memory/retrieval/pipeline.py +125 -0
  74. trw_memory-0.3.0/src/trw_memory/security/__init__.py +80 -0
  75. trw_memory-0.3.0/src/trw_memory/security/audit.py +202 -0
  76. trw_memory-0.3.0/src/trw_memory/security/encryption.py +141 -0
  77. trw_memory-0.3.0/src/trw_memory/security/keys.py +215 -0
  78. trw_memory-0.3.0/src/trw_memory/security/pii.py +303 -0
  79. trw_memory-0.3.0/src/trw_memory/security/poisoning.py +251 -0
  80. trw_memory-0.3.0/src/trw_memory/security/rbac.py +101 -0
  81. trw_memory-0.3.0/src/trw_memory/server.py +37 -0
  82. trw_memory-0.3.0/src/trw_memory/storage/__init__.py +23 -0
  83. trw_memory-0.3.0/src/trw_memory/storage/_parsing.py +92 -0
  84. trw_memory-0.3.0/src/trw_memory/storage/_shared.py +112 -0
  85. trw_memory-0.3.0/src/trw_memory/storage/interface.py +170 -0
  86. trw_memory-0.3.0/src/trw_memory/storage/persistence.py +219 -0
  87. trw_memory-0.3.0/src/trw_memory/storage/sqlite_backend.py +814 -0
  88. trw_memory-0.3.0/src/trw_memory/storage/yaml_backend.py +433 -0
  89. trw_memory-0.3.0/src/trw_memory/sync/__init__.py +24 -0
  90. trw_memory-0.3.0/src/trw_memory/sync/conflict.py +122 -0
  91. trw_memory-0.3.0/src/trw_memory/sync/remote.py +185 -0
  92. trw_memory-0.3.0/src/trw_memory/sync/retry_queue.py +148 -0
  93. trw_memory-0.3.0/src/trw_memory/sync/subscriber.py +106 -0
  94. trw_memory-0.3.0/src/trw_memory/tools/__init__.py +30 -0
  95. trw_memory-0.3.0/src/trw_memory/tools/_types.py +28 -0
  96. trw_memory-0.3.0/src/trw_memory/tools/consolidate.py +181 -0
  97. trw_memory-0.3.0/src/trw_memory/tools/forget.py +146 -0
  98. trw_memory-0.3.0/src/trw_memory/tools/recall.py +223 -0
  99. trw_memory-0.3.0/src/trw_memory/tools/search.py +146 -0
  100. trw_memory-0.3.0/src/trw_memory/tools/status.py +131 -0
  101. trw_memory-0.3.0/src/trw_memory/tools/store.py +145 -0
  102. trw_memory-0.3.0/tests/CLAUDE.md +114 -0
  103. trw_memory-0.3.0/tests/conftest.py +198 -0
  104. trw_memory-0.3.0/tests/test_audit.py +283 -0
  105. trw_memory-0.3.0/tests/test_benchmarks.py +617 -0
  106. trw_memory-0.3.0/tests/test_cli.py +974 -0
  107. trw_memory-0.3.0/tests/test_cli_formatters.py +216 -0
  108. trw_memory-0.3.0/tests/test_client.py +388 -0
  109. trw_memory-0.3.0/tests/test_concurrent.py +273 -0
  110. trw_memory-0.3.0/tests/test_consolidation.py +647 -0
  111. trw_memory-0.3.0/tests/test_decorators.py +188 -0
  112. trw_memory-0.3.0/tests/test_dedup.py +531 -0
  113. trw_memory-0.3.0/tests/test_dense_edge_cases.py +80 -0
  114. trw_memory-0.3.0/tests/test_embeddings.py +270 -0
  115. trw_memory-0.3.0/tests/test_encryption.py +430 -0
  116. trw_memory-0.3.0/tests/test_graph.py +726 -0
  117. trw_memory-0.3.0/tests/test_integrations.py +922 -0
  118. trw_memory-0.3.0/tests/test_keys.py +513 -0
  119. trw_memory-0.3.0/tests/test_lifecycle_utils.py +159 -0
  120. trw_memory-0.3.0/tests/test_migration.py +349 -0
  121. trw_memory-0.3.0/tests/test_models.py +348 -0
  122. trw_memory-0.3.0/tests/test_namespace.py +81 -0
  123. trw_memory-0.3.0/tests/test_namespace_migration.py +200 -0
  124. trw_memory-0.3.0/tests/test_openai_compat.py +158 -0
  125. trw_memory-0.3.0/tests/test_package.py +112 -0
  126. trw_memory-0.3.0/tests/test_persistence.py +279 -0
  127. trw_memory-0.3.0/tests/test_pii.py +393 -0
  128. trw_memory-0.3.0/tests/test_poisoning.py +331 -0
  129. trw_memory-0.3.0/tests/test_rbac.py +556 -0
  130. trw_memory-0.3.0/tests/test_retrieval.py +569 -0
  131. trw_memory-0.3.0/tests/test_scoring.py +496 -0
  132. trw_memory-0.3.0/tests/test_security.py +524 -0
  133. trw_memory-0.3.0/tests/test_server.py +122 -0
  134. trw_memory-0.3.0/tests/test_storage_sqlite.py +616 -0
  135. trw_memory-0.3.0/tests/test_storage_yaml.py +339 -0
  136. trw_memory-0.3.0/tests/test_sync.py +1053 -0
  137. trw_memory-0.3.0/tests/test_team_memory.py +222 -0
  138. trw_memory-0.3.0/tests/test_tier_thread_safety.py +144 -0
  139. trw_memory-0.3.0/tests/test_tiers.py +834 -0
  140. trw_memory-0.3.0/tests/test_tools.py +222 -0
  141. trw_memory-0.3.0/tests/test_tools_lifecycle.py +233 -0
  142. trw_memory-0.3.0/vulture_whitelist.py +22 -0
@@ -0,0 +1,43 @@
1
+ # TRW Memory Engine — Environment Variables
2
+ # All settings use MEMORY_ prefix (case-insensitive via pydantic-settings).
3
+ # Copy to .env and uncomment/fill values as needed.
4
+
5
+ # ── API Authentication (optional) ─────────────────────────────────────────
6
+ # Disabled if not set — enables X-API-Key header validation
7
+ # MEMORY_API_KEY=your-api-key-here
8
+
9
+ # ── Field-Level Encryption (optional) ─────────────────────────────────────
10
+ # Disabled if not set — hex-encoded 32-byte key
11
+ # Generate with: python -c "import secrets; print(secrets.token_hex(32))"
12
+ # MEMORY_MASTER_KEY=
13
+
14
+ # ── Storage Backend ────────────────────────────────────────────────────────
15
+ # MEMORY_STORAGE_BACKEND=sqlite # sqlite (default) or yaml
16
+ # MEMORY_STORAGE_PATH=.memory
17
+ # MEMORY_SQLITE_DB_NAME=memory.db
18
+
19
+ # ── Encryption Settings ───────────────────────────────────────────────────
20
+ # MEMORY_ENCRYPTION_ENABLED=false
21
+ # MEMORY_KEY_SOURCE=env # env, keyring, or file
22
+ # MEMORY_KEY_FILE_PATH=~/.trw-memory/master.key
23
+
24
+ # ── Retrieval Tuning ──────────────────────────────────────────────────────
25
+ # MEMORY_BM25_CANDIDATES=50
26
+ # MEMORY_VECTOR_CANDIDATES=50
27
+ # MEMORY_RRF_K=60
28
+
29
+ # ── Deduplication ─────────────────────────────────────────────────────────
30
+ # MEMORY_DEDUP_ENABLED=true
31
+ # MEMORY_DEDUP_SKIP_THRESHOLD=0.95
32
+ # MEMORY_DEDUP_MERGE_THRESHOLD=0.85
33
+
34
+ # ── Tier Lifecycle ────────────────────────────────────────────────────────
35
+ # MEMORY_HOT_MAX_ENTRIES=50
36
+ # MEMORY_HOT_TTL_DAYS=7
37
+ # MEMORY_COLD_THRESHOLD_DAYS=90
38
+ # MEMORY_RETENTION_DAYS=365
39
+
40
+ # ── Scoring Weights (must sum to 1.0) ────────────────────────────────────
41
+ # MEMORY_SCORE_RELEVANCE_WEIGHT=0.4
42
+ # MEMORY_SCORE_RECENCY_WEIGHT=0.3
43
+ # MEMORY_SCORE_IMPORTANCE_WEIGHT=0.3
@@ -0,0 +1,37 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ python-version: ["3.10", "3.11", "3.12", "3.13"]
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ - uses: actions/setup-python@v5
18
+ with:
19
+ python-version: ${{ matrix.python-version }}
20
+ - name: Cache pip packages
21
+ uses: actions/cache@v4
22
+ with:
23
+ path: ~/.cache/pip
24
+ key: ${{ runner.os }}-pip-${{ matrix.python-version }}-${{ hashFiles('pyproject.toml') }}
25
+ restore-keys: |
26
+ ${{ runner.os }}-pip-${{ matrix.python-version }}-
27
+ - name: Install dependencies
28
+ run: |
29
+ python -m pip install --upgrade pip
30
+ pip install -e ".[dev,vectors,bm25,mcp]"
31
+ pip install cryptography keyring sentence-transformers
32
+ - name: Lint
33
+ run: ruff check src/
34
+ - name: Type check
35
+ run: mypy --strict src/trw_memory/
36
+ - name: Test
37
+ run: pytest tests/ -x --timeout=120 -q
@@ -0,0 +1,39 @@
1
+ name: Release to PyPI
2
+
3
+ on:
4
+ push:
5
+ tags: ["v*"]
6
+
7
+ permissions:
8
+ id-token: write # Required for trusted publishing
9
+
10
+ jobs:
11
+ build:
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+ - uses: actions/setup-python@v5
16
+ with:
17
+ python-version: "3.12"
18
+ - name: Install build tools
19
+ run: pip install build
20
+ - name: Build package
21
+ run: python -m build
22
+ - name: Upload artifacts
23
+ uses: actions/upload-artifact@v4
24
+ with:
25
+ name: dist
26
+ path: dist/
27
+
28
+ publish:
29
+ needs: build
30
+ runs-on: ubuntu-latest
31
+ environment: pypi
32
+ permissions:
33
+ id-token: write
34
+ steps:
35
+ - uses: actions/download-artifact@v4
36
+ with:
37
+ name: dist
38
+ path: dist/
39
+ - uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,36 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ *.egg
6
+ dist/
7
+ build/
8
+ .eggs/
9
+
10
+ # Virtual environments
11
+ .venv/
12
+ venv/
13
+
14
+ # Testing
15
+ .pytest_cache/
16
+ .hypothesis/
17
+ .coverage
18
+ htmlcov/
19
+ coverage.xml
20
+ .mypy_cache/
21
+
22
+ # IDE
23
+ .vscode/
24
+ .idea/
25
+
26
+ # TRW runtime state
27
+ .trw/
28
+
29
+ # Internal Claude Code settings — not for public consumption
30
+ .claude/
31
+
32
+ # Internal PRD/sprint docs — development artefacts, not part of the public package
33
+ docs/
34
+
35
+ # Scratch workspace
36
+ scratch/
@@ -0,0 +1,124 @@
1
+ # Changelog
2
+
3
+ All notable changes to the TRW Memory package.
4
+
5
+ ## [0.3.0] — 2026-03-19
6
+
7
+ ### Added
8
+
9
+ - **Structured logging** — new `trw_memory/_logging.py` module with `configure_logging()`, `-v/-q/--log-level` CLI flags, `NullHandler` in `__init__.py` (library best practice), and `exc_info=True` added to exception handlers in `embeddings/local.py` and `migration/from_trw.py`. All 28 source files normalized to `structlog.get_logger(__name__)`. 10 sentence-style log messages converted to snake_case event names.
10
+ - **BSL 1.1 license** — `pyproject.toml` updated from CC BY-NC-SA to `BUSL-1.1` (Change Date 2030-03-21, Change License Apache 2.0) in preparation for open-source publication.
11
+ - **CI hardening** — ruff format checks now blocking in the memory CI workflow; pre-existing ruff lint issues resolved. mypy `--strict` fully clean across all 77 files.
12
+
13
+ ### Changed
14
+
15
+ - **Version aligned to monorepo v24.4_TRW release** — package version bumped from 0.2.0 to 0.3.0 at the v24.4 framework release (`98608d2a`).
16
+
17
+ ---
18
+
19
+ ## [0.2.0] — 2026-03-19
20
+
21
+ ### Added
22
+
23
+ - **Structured logging foundation** — `_logging.py` introduced as part of the monorepo-wide logging overhaul. Library stays silent by default (`NullHandler`); CLI configures logging at startup only.
24
+ - **CLI verbosity flags** — `-v/--verbose`, `-q/--quiet`, `--log-level` added to all CLI subcommands.
25
+
26
+ ### Changed
27
+
28
+ - **Logger normalization** — all 28 source files migrated from bare `structlog.get_logger()` to `structlog.get_logger(__name__)` for module-level filtering.
29
+ - **Log event naming** — 10 sentence-style event strings converted to snake_case.
30
+
31
+ ---
32
+
33
+ ## [0.1.3] — 2026-03-17
34
+
35
+ ### Fixed
36
+
37
+ - **WAL mode reliability** — enabled `PRAGMA journal_mode=WAL; PRAGMA synchronous=NORMAL;` on `SQLiteBackend` with a warning log if WAL activation fails. Allows concurrent reads without write serialization.
38
+ - **Decay loop `datetime.now()` per-iteration** — captured once before the loop instead of calling it on every iteration.
39
+ - **`graph.py` thread-safe commits** — `conn.commit()` calls now accept an optional `threading.Lock` parameter; wired in from all callers.
40
+
41
+ ---
42
+
43
+ ## [0.1.2] — 2026-03-15
44
+
45
+ ### Changed
46
+
47
+ - **mypy `--strict` clean** — resolved all 13 pre-existing type errors: fixed `type: ignore` codes in `sqlite_backend.py`, `local.py`, and `client.py`; widened formatter params to `Sequence[Mapping]` for TypedDict covariance in `cli_formatters.py`; added `_backend_or_raise` property for None safety in `llamaindex.py`. Zero errors across 77 files.
48
+ - **Ruff expanded** — rule set expanded from 14 to 26 categories (matching monorepo standard). 244 violations fixed, 0 remaining.
49
+ - **`delete_by_namespace` cursor fix** — `cursor.rowcount` moved inside the write lock to prevent a race condition with concurrent deletes.
50
+
51
+ ---
52
+
53
+ ## [0.1.1] — 2026-03-10
54
+
55
+ ### Changed
56
+
57
+ - **Standalone REST API removed** — the orphaned `trw-memory/api/` package (8 files, ~1,428 LOC) and its 5 matching test files were deleted. The API was superseded by the backend package and was unreachable without a running platform instance. The removal cleans up dead code and reduces confusion for consumers.
58
+ - **`_parsing.py` shared helpers** — `storage/_parsing.py` introduced with `parse_dt`, `parse_json_list`, `parse_json_dict_str`, `parse_json_dict_int` to replace duplicated parsing in `sqlite_backend.py` and `yaml_backend.py`. Fixes a subtle UTC normalization bug in `yaml_backend`.
59
+ - **Sprint 39/40 quality review** — CLI import merge check fixed (keyword recall replaced with `backend.get(eid)` for reliable ID-based dedup during `--merge` imports); `BackendOwnerMixin` extracted to eliminate identical `close/__enter__/__exit__` boilerplate across LangChain, CrewAI, and VSCode integration adapters; `corpus.py` docstrings corrected (said "YAML" but writes JSON).
60
+
61
+ ---
62
+
63
+ ## [0.1.0] — 2026-02-27
64
+
65
+ ### Added
66
+
67
+ - **Initial release** — `trw-memory` introduced as a standalone persistent memory engine extracted from `trw-mcp`. Shipped as part of the monorepo alongside trw-mcp's knowledge topology and hybrid retrieval work (commit `b28c2490`).
68
+
69
+ #### Storage backends
70
+
71
+ - **SQLite primary backend** — `storage/sqlite_backend.py` with FTS5 full-text search, WAL journal mode, and `check_same_thread=False` for concurrent HTTP client access.
72
+ - **YAML secondary backend** — `storage/yaml_backend.py` for backward compatibility with pre-migration entries.
73
+
74
+ #### Retrieval
75
+
76
+ - **BM25 sparse retrieval** — `retrieval/bm25.py` via `rank-bm25` with hyphenated-tag expansion and zero-IDF fallback.
77
+ - **Dense vector retrieval** — `retrieval/dense.py` via `sqlite-vec` (384-dim all-MiniLM-L6-v2).
78
+ - **Hybrid search with RRF** — `retrieval/hybrid.py` combines BM25 and dense rankings via Reciprocal Rank Fusion (k=60). Gracefully degrades to BM25-only when vectors are unavailable.
79
+
80
+ #### Lifecycle
81
+
82
+ - **Tiered storage** — `lifecycle/tiers.py`: hot tier (in-memory LRU), warm tier (sqlite-vec + JSONL sidecar), cold tier (YAML archive). Four automatic transitions: Hot→Warm (TTL/overflow), Warm→Cold (idle+low-impact), Cold→Warm (on access), Cold→Purge (365d+low-impact). Purge audit trail at `.trw/memory/purge_audit.jsonl`.
83
+ - **Scoring engine** — `lifecycle/scoring.py`: Q-learning with EMA updates, Ebbinghaus forgetting curve, Bayesian MACLA calibration. Stanford Generative Agents importance formula: `w1*relevance + w2*recency + w3*importance`.
84
+ - **LLM consolidation** — `lifecycle/consolidation.py`: embedding-based cluster detection (single-linkage agglomerative, pairwise cosine threshold), LLM-powered summarization via `anthropic` SDK (claude-haiku), original entry archival to cold tier with atomic rollback.
85
+ - **Semantic dedup** — `lifecycle/dedup.py`: three-tier write-time dedup (skip ≥0.95, merge ≥0.85, store <0.85) via cosine similarity. `merge_entries()` with union tags/evidence, max impact, recurrence increment, and `merged_from` audit trail.
86
+
87
+ #### Knowledge graph
88
+
89
+ - **`graph.py`** — similarity, tag co-occurrence, and consolidation edges; BFS traversal; importance boost/decay with outcome history.
90
+
91
+ #### Remote sync
92
+
93
+ - **`sync/remote.py`** — publish/fetch with anonymization and fail-open design.
94
+ - **`sync/conflict.py`** — vector clock comparison, merge, and conflict resolution.
95
+ - **`sync/retry_queue.py`** — thread-safe JSONL queue with 500-entry depth cap.
96
+ - **`sync/subscriber.py`** — SSE real-time stream with automatic reconnection.
97
+
98
+ #### Security
99
+
100
+ - **`security/`** — AES-256-GCM field-level encryption, PII detection and redaction, memory poisoning detection, RBAC, and full audit trail.
101
+
102
+ #### Integrations
103
+
104
+ - **LangChain** — `TRWChatMessageHistory` and `TRWVectorStore` adapters.
105
+ - **LlamaIndex** — reader and writer components.
106
+ - **CrewAI** — `TRWCrewStorage` component.
107
+ - **OpenAI-compatible** — `LocalMemoryAdapter` with 4 function-call operations (store, recall, search, forget).
108
+
109
+ #### CLI
110
+
111
+ - **`trw-memory` CLI** — 8 subcommands (`store`, `recall`, `search`, `forget`, `consolidate`, `export`, `import`, `status`) with JSON, table, and YAML output formats. `cli_parser.py` extracted for line-count compliance.
112
+
113
+ #### MCP tools
114
+
115
+ - **6 MCP tools** (`tools/`) — `store`, `recall`, `search`, `consolidate`, `forget`, `status` for direct integration into Claude Code sessions.
116
+
117
+ #### Client SDK
118
+
119
+ - **`MemoryClient`** (`client.py`) — high-level async Python client with `store()`, `recall()`, `forget()`, and `search()` methods.
120
+ - **TypeScript SDK** — `@trw/memory-sdk` with `MemoryClient` class and full TypeScript types.
121
+
122
+ #### Benchmarks
123
+
124
+ - **`benchmarks/`** — 4 benchmark modules (latency, throughput, memory, quality) with configurable thresholds and `python -m benchmarks` entry point.
@@ -0,0 +1,42 @@
1
+ # trw-memory
2
+
3
+ Standalone persistent memory engine for AI agents — hybrid retrieval (BM25 + dense vectors), tiered storage (SQLite primary, YAML secondary), semantic dedup, and knowledge-graph traversal. Used by trw-mcp as its memory backend via `memory_adapter.py`.
4
+
5
+ ## Build & Test
6
+
7
+ ```bash
8
+ cd trw-memory
9
+ .venv/bin/python -m pytest tests/test_specific_file.py -v # Single file (preferred)
10
+ .venv/bin/python -m pytest tests/ -v # Full suite (delivery only)
11
+ .venv/bin/python -m mypy --strict src/trw_memory/ # Type check
12
+ pip install -e ".[dev]" # Dev install
13
+ pip install -e ".[dev,vectors,bm25]" # With optional deps
14
+ ```
15
+
16
+ ## Architecture
17
+
18
+ | Module | Purpose |
19
+ |--------|---------|
20
+ | `storage/` | SQLite + YAML dual backends (`sqlite_backend.py`, `yaml_backend.py`) |
21
+ | `retrieval/` | BM25 keyword + dense vector hybrid search |
22
+ | `lifecycle/` | Tier promotion/demotion, utility scoring, dedup, consolidation |
23
+ | `graph.py` | Knowledge graph with BFS traversal |
24
+ | `sync/` | Remote publish/fetch with vector clocks |
25
+ | `security/` | Field-level encryption, PII detection, RBAC |
26
+ | `tools/` | MCP tool wrappers (optional `[mcp]` dep) |
27
+ | `client.py` | Public `MemoryClient` — primary consumer API |
28
+
29
+ ## Testing Patterns
30
+
31
+ - **In-memory SQLite**: `SQLiteBackend(":memory:")` — use for unit tests, no `tmp_path` needed
32
+ - **Disk SQLite**: `SQLiteBackend(tmp_path / "test.db")` — use for integration tests
33
+ - **Shared fixtures**: `tests/conftest.py` provides `sqlite_backend`, `sqlite_memory_backend`, `memory_client`, `make_entry()`, `make_entry_dict()`
34
+ - `asyncio_mode = "auto"` — write `async def test_foo():` without `@pytest.mark.asyncio`
35
+
36
+ ## Key Gotchas
37
+
38
+ - `sqlite-vec` is an optional dep (`[vectors]`) — skip dense vector tests with `pytest.importorskip("sqlite_vec")`
39
+ - `sentence-transformers` is optional (`[embeddings]`) — embeddings fail gracefully when unavailable
40
+ - Pydantic v2: `use_enum_values=True` required for YAML round-trip; `populate_by_name=True` when using `Field(alias=...)`
41
+ - structlog: never use `event=` as a kwarg — it's reserved; use `action=` or `operation=`
42
+ - Coverage threshold: 85% (fail_under in pyproject.toml)
@@ -0,0 +1,41 @@
1
+ Business Source License 1.1
2
+
3
+ Licensor: Tyler Wall
4
+ Licensed Work: TRW Framework
5
+ The Licensed Work is (c) 2026 Tyler Wall.
6
+
7
+ Additional Use Grant:
8
+ You may use the Licensed Work for any purpose other than offering
9
+ a commercial product or service that competes with the Licensed Work.
10
+
11
+ "Compete" means providing a substantially similar product or service
12
+ that replaces or substitutes for the Licensed Work's core functionality:
13
+ persistent memory with scoring and decay, sprint orchestration,
14
+ requirements lifecycle management, phase gates, or agent team
15
+ coordination for AI coding agents.
16
+
17
+ For clarity, the following uses are always permitted:
18
+ - Using TRW in your own software development projects
19
+ - Integrating TRW into your development workflow
20
+ - Building applications, tools, or services that use TRW internally
21
+ - Modifying TRW for your own non-competing use
22
+ - Evaluating, testing, and benchmarking TRW
23
+
24
+ Change Date: 2030-03-21
25
+
26
+ Change License: Apache License, Version 2.0
27
+
28
+ Notice:
29
+
30
+ The Business Source License (this document, or the "License") is not
31
+ an Open Source license. However, the Licensed Work will eventually be
32
+ made available under the Change License, as stated in this License.
33
+
34
+ License text copyright (c) 2017 MariaDB Corporation Ab, All Rights
35
+ Reserved. "Business Source License" is a trademark of MariaDB
36
+ Corporation Ab.
37
+
38
+ For the full BSL 1.1 license text, see:
39
+ https://mariadb.com/bsl11/
40
+
41
+ SPDX-License-Identifier: BUSL-1.1