kore-memory 2.0.0__tar.gz → 2.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 (126) hide show
  1. kore_memory-2.3.0/.github/workflows/benchmark.yml +48 -0
  2. {kore_memory-2.0.0 → kore_memory-2.3.0}/.github/workflows/ci.yml +5 -4
  3. {kore_memory-2.0.0 → kore_memory-2.3.0}/CHANGELOG.md +184 -0
  4. {kore_memory-2.0.0 → kore_memory-2.3.0}/PKG-INFO +59 -15
  5. {kore_memory-2.0.0 → kore_memory-2.3.0}/README.md +58 -14
  6. kore_memory-2.3.0/docs/quickstart-v2.1.md +310 -0
  7. {kore_memory-2.0.0 → kore_memory-2.3.0}/kore_memory/acl.py +1 -3
  8. {kore_memory-2.0.0 → kore_memory-2.3.0}/kore_memory/compressor.py +12 -9
  9. {kore_memory-2.0.0 → kore_memory-2.3.0}/kore_memory/config.py +20 -1
  10. kore_memory-2.3.0/kore_memory/conflict_detector.py +233 -0
  11. kore_memory-2.3.0/kore_memory/context_assembler.py +168 -0
  12. {kore_memory-2.0.0 → kore_memory-2.3.0}/kore_memory/database.py +81 -8
  13. {kore_memory-2.0.0 → kore_memory-2.3.0}/kore_memory/embedder.py +1 -5
  14. kore_memory-2.3.0/kore_memory/filesystem_overlay.py +370 -0
  15. {kore_memory-2.0.0 → kore_memory-2.3.0}/kore_memory/integrations/openai_agents.py +1 -3
  16. {kore_memory-2.0.0 → kore_memory-2.3.0}/kore_memory/integrations/pydantic_ai.py +2 -7
  17. {kore_memory-2.0.0 → kore_memory-2.3.0}/kore_memory/main.py +294 -25
  18. kore_memory-2.3.0/kore_memory/mcp_server.py +782 -0
  19. {kore_memory-2.0.0 → kore_memory-2.3.0}/kore_memory/models.py +245 -2
  20. {kore_memory-2.0.0 → kore_memory-2.3.0}/kore_memory/plugins.py +1 -0
  21. kore_memory-2.3.0/kore_memory/ranking.py +279 -0
  22. {kore_memory-2.0.0 → kore_memory-2.3.0}/kore_memory/repository/__init__.py +14 -1
  23. kore_memory-2.3.0/kore_memory/repository/graph.py +427 -0
  24. {kore_memory-2.0.0 → kore_memory-2.3.0}/kore_memory/repository/memory.py +143 -22
  25. kore_memory-2.3.0/kore_memory/repository/search.py +588 -0
  26. {kore_memory-2.0.0 → kore_memory-2.3.0}/kore_memory/summarizer.py +127 -21
  27. {kore_memory-2.0.0 → kore_memory-2.3.0}/kore_memory/templates/dashboard.html +156 -0
  28. kore_memory-2.3.0/presets/claude-code/README.md +87 -0
  29. kore_memory-2.3.0/presets/claude-code/mcp.json +11 -0
  30. kore_memory-2.3.0/presets/cursor/README.md +65 -0
  31. kore_memory-2.3.0/presets/cursor/mcp.json +11 -0
  32. {kore_memory-2.0.0 → kore_memory-2.3.0}/pyproject.toml +2 -1
  33. kore_memory-2.3.0/scripts/assert_benchmarks.py +142 -0
  34. {kore_memory-2.0.0 → kore_memory-2.3.0}/sdk/js/package.json +1 -1
  35. kore_memory-2.3.0/tests/benchmarks/__init__.py +1 -0
  36. kore_memory-2.3.0/tests/benchmarks/conftest_bench.py +63 -0
  37. kore_memory-2.3.0/tests/benchmarks/datasets/dataset_a_temporal.json +1648 -0
  38. kore_memory-2.3.0/tests/benchmarks/datasets/dataset_b_conflicts.json +1516 -0
  39. kore_memory-2.3.0/tests/benchmarks/datasets/dataset_c_coding.json +1981 -0
  40. kore_memory-2.3.0/tests/benchmarks/datasets/dataset_d_graph.json +462 -0
  41. kore_memory-2.3.0/tests/benchmarks/datasets/dataset_e_context.json +575 -0
  42. kore_memory-2.3.0/tests/benchmarks/datasets/loaders.py +53 -0
  43. kore_memory-2.3.0/tests/benchmarks/test_benchmarks.py +632 -0
  44. {kore_memory-2.0.0 → kore_memory-2.3.0}/tests/test_client.py +3 -2
  45. {kore_memory-2.0.0 → kore_memory-2.3.0}/tests/test_client_sync.py +3 -2
  46. kore_memory-2.3.0/tests/test_conflict_detection.py +256 -0
  47. {kore_memory-2.0.0 → kore_memory-2.3.0}/tests/test_dashboard.py +3 -1
  48. {kore_memory-2.0.0 → kore_memory-2.3.0}/tests/test_mcp.py +244 -0
  49. kore_memory-2.3.0/tests/test_ranking_engine.py +247 -0
  50. {kore_memory-2.0.0 → kore_memory-2.3.0}/tests/test_v11_fixes.py +1 -1
  51. {kore_memory-2.0.0 → kore_memory-2.3.0}/tests/test_v12_features.py +11 -3
  52. kore_memory-2.3.0/tests/test_v21_temporal.py +411 -0
  53. kore_memory-2.3.0/tests/test_wave3_graph.py +290 -0
  54. kore_memory-2.3.0/tests/test_wave3_overlay.py +350 -0
  55. kore_memory-2.0.0/.claude/settings.local.json +0 -6
  56. kore_memory-2.0.0/kore_memory/mcp_server.py +0 -371
  57. kore_memory-2.0.0/kore_memory/repository/graph.py +0 -220
  58. kore_memory-2.0.0/kore_memory/repository/search.py +0 -358
  59. {kore_memory-2.0.0 → kore_memory-2.3.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  60. {kore_memory-2.0.0 → kore_memory-2.3.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  61. {kore_memory-2.0.0 → kore_memory-2.3.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  62. {kore_memory-2.0.0 → kore_memory-2.3.0}/.github/workflows/build-sdk.yml +0 -0
  63. {kore_memory-2.0.0 → kore_memory-2.3.0}/.github/workflows/publish.yml +0 -0
  64. {kore_memory-2.0.0 → kore_memory-2.3.0}/.gitignore +0 -0
  65. {kore_memory-2.0.0 → kore_memory-2.3.0}/CONTRIBUTING.md +0 -0
  66. {kore_memory-2.0.0 → kore_memory-2.3.0}/LICENSE +0 -0
  67. {kore_memory-2.0.0 → kore_memory-2.3.0}/MIGRATION-v0.6.md +0 -0
  68. {kore_memory-2.0.0 → kore_memory-2.3.0}/article-devto.md +0 -0
  69. {kore_memory-2.0.0 → kore_memory-2.3.0}/assets/favicon.svg +0 -0
  70. {kore_memory-2.0.0 → kore_memory-2.3.0}/assets/logo.svg +0 -0
  71. {kore_memory-2.0.0 → kore_memory-2.3.0}/docs/competitive-analysis-2025.md +0 -0
  72. {kore_memory-2.0.0 → kore_memory-2.3.0}/docs/v1.0-roadmap.md +0 -0
  73. {kore_memory-2.0.0 → kore_memory-2.3.0}/examples/async_usage.py +0 -0
  74. {kore_memory-2.0.0 → kore_memory-2.3.0}/examples/basic_usage.py +0 -0
  75. {kore_memory-2.0.0 → kore_memory-2.3.0}/examples/langchain_example.py +0 -0
  76. {kore_memory-2.0.0 → kore_memory-2.3.0}/hatch_build.py +0 -0
  77. {kore_memory-2.0.0 → kore_memory-2.3.0}/kore-daemon.sh +0 -0
  78. {kore_memory-2.0.0 → kore_memory-2.3.0}/kore_memory/__init__.py +0 -0
  79. {kore_memory-2.0.0 → kore_memory-2.3.0}/kore_memory/analytics.py +0 -0
  80. {kore_memory-2.0.0 → kore_memory-2.3.0}/kore_memory/audit.py +0 -0
  81. {kore_memory-2.0.0 → kore_memory-2.3.0}/kore_memory/auth.py +0 -0
  82. {kore_memory-2.0.0 → kore_memory-2.3.0}/kore_memory/auto_tuner.py +0 -0
  83. {kore_memory-2.0.0 → kore_memory-2.3.0}/kore_memory/cli.py +0 -0
  84. {kore_memory-2.0.0 → kore_memory-2.3.0}/kore_memory/client.py +0 -0
  85. {kore_memory-2.0.0 → kore_memory-2.3.0}/kore_memory/dashboard.py +0 -0
  86. {kore_memory-2.0.0 → kore_memory-2.3.0}/kore_memory/decay.py +0 -0
  87. {kore_memory-2.0.0 → kore_memory-2.3.0}/kore_memory/events.py +0 -0
  88. {kore_memory-2.0.0 → kore_memory-2.3.0}/kore_memory/integrations/__init__.py +0 -0
  89. {kore_memory-2.0.0 → kore_memory-2.3.0}/kore_memory/integrations/crewai.py +0 -0
  90. {kore_memory-2.0.0 → kore_memory-2.3.0}/kore_memory/integrations/entities.py +0 -0
  91. {kore_memory-2.0.0 → kore_memory-2.3.0}/kore_memory/integrations/langchain.py +0 -0
  92. {kore_memory-2.0.0 → kore_memory-2.3.0}/kore_memory/py.typed +0 -0
  93. {kore_memory-2.0.0 → kore_memory-2.3.0}/kore_memory/repository/lifecycle.py +0 -0
  94. {kore_memory-2.0.0 → kore_memory-2.3.0}/kore_memory/repository/sessions.py +0 -0
  95. {kore_memory-2.0.0 → kore_memory-2.3.0}/kore_memory/scorer.py +0 -0
  96. {kore_memory-2.0.0 → kore_memory-2.3.0}/kore_memory/vector_index.py +0 -0
  97. {kore_memory-2.0.0 → kore_memory-2.3.0}/kore_memory/welcome.py +0 -0
  98. {kore_memory-2.0.0 → kore_memory-2.3.0}/requirements.txt +0 -0
  99. {kore_memory-2.0.0 → kore_memory-2.3.0}/scripts/import_memory.py +0 -0
  100. {kore_memory-2.0.0 → kore_memory-2.3.0}/sdk/js/.gitignore +0 -0
  101. {kore_memory-2.0.0 → kore_memory-2.3.0}/sdk/js/README.md +0 -0
  102. {kore_memory-2.0.0 → kore_memory-2.3.0}/sdk/js/package-lock.json +0 -0
  103. {kore_memory-2.0.0 → kore_memory-2.3.0}/sdk/js/src/client.ts +0 -0
  104. {kore_memory-2.0.0 → kore_memory-2.3.0}/sdk/js/src/errors.ts +0 -0
  105. {kore_memory-2.0.0 → kore_memory-2.3.0}/sdk/js/src/index.ts +0 -0
  106. {kore_memory-2.0.0 → kore_memory-2.3.0}/sdk/js/src/types.ts +0 -0
  107. {kore_memory-2.0.0 → kore_memory-2.3.0}/sdk/js/tests/client.test.ts +0 -0
  108. {kore_memory-2.0.0 → kore_memory-2.3.0}/sdk/js/tests/errors.test.ts +0 -0
  109. {kore_memory-2.0.0 → kore_memory-2.3.0}/sdk/js/tests/helpers.ts +0 -0
  110. {kore_memory-2.0.0 → kore_memory-2.3.0}/sdk/js/tsconfig.json +0 -0
  111. {kore_memory-2.0.0 → kore_memory-2.3.0}/sdk/js/tsup.config.ts +0 -0
  112. {kore_memory-2.0.0 → kore_memory-2.3.0}/sdk/js/vitest.config.ts +0 -0
  113. {kore_memory-2.0.0 → kore_memory-2.3.0}/start.sh +0 -0
  114. {kore_memory-2.0.0 → kore_memory-2.3.0}/test_pagination_fix.py +0 -0
  115. {kore_memory-2.0.0 → kore_memory-2.3.0}/tests/__init__.py +0 -0
  116. {kore_memory-2.0.0 → kore_memory-2.3.0}/tests/conftest.py +0 -0
  117. {kore_memory-2.0.0 → kore_memory-2.3.0}/tests/test_api.py +0 -0
  118. {kore_memory-2.0.0 → kore_memory-2.3.0}/tests/test_audit.py +0 -0
  119. {kore_memory-2.0.0 → kore_memory-2.3.0}/tests/test_auth_events.py +0 -0
  120. {kore_memory-2.0.0 → kore_memory-2.3.0}/tests/test_auto_tuner.py +0 -0
  121. {kore_memory-2.0.0 → kore_memory-2.3.0}/tests/test_cli.py +0 -0
  122. {kore_memory-2.0.0 → kore_memory-2.3.0}/tests/test_crewai.py +0 -0
  123. {kore_memory-2.0.0 → kore_memory-2.3.0}/tests/test_entities.py +0 -0
  124. {kore_memory-2.0.0 → kore_memory-2.3.0}/tests/test_langchain.py +0 -0
  125. {kore_memory-2.0.0 → kore_memory-2.3.0}/tests/test_sessions.py +0 -0
  126. {kore_memory-2.0.0 → kore_memory-2.3.0}/tests/test_v2_features.py +0 -0
@@ -0,0 +1,48 @@
1
+ name: Benchmark CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+ workflow_dispatch:
9
+
10
+ jobs:
11
+ benchmark:
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+
16
+ - name: Set up Python 3.12
17
+ uses: actions/setup-python@v5
18
+ with:
19
+ python-version: "3.12"
20
+
21
+ - name: Cache pip
22
+ uses: actions/cache@v4
23
+ with:
24
+ path: ~/.cache/pip
25
+ key: ${{ runner.os }}-pip-bench-${{ hashFiles('pyproject.toml') }}
26
+ restore-keys: |
27
+ ${{ runner.os }}-pip-bench-
28
+
29
+ - name: Installa dipendenze
30
+ run: pip install -e ".[dev,mcp]" pytest-benchmark
31
+
32
+ - name: Esegui suite benchmark
33
+ run: |
34
+ pytest tests/benchmarks/ -v \
35
+ --benchmark-json=results.json \
36
+ --tb=short
37
+ env:
38
+ KORE_TEST_MODE: "1"
39
+
40
+ - name: Verifica soglie CI
41
+ run: python scripts/assert_benchmarks.py --results results.json --strict
42
+
43
+ - name: Upload risultati benchmark
44
+ uses: actions/upload-artifact@v4
45
+ if: always()
46
+ with:
47
+ name: benchmark-results
48
+ path: results.json
@@ -30,7 +30,7 @@ jobs:
30
30
  ${{ runner.os }}-pip-${{ matrix.python-version }}-
31
31
 
32
32
  - name: Install dependencies
33
- run: pip install -e ".[dev]"
33
+ run: pip install -e ".[dev,mcp]"
34
34
 
35
35
  - name: Run tests
36
36
  run: pytest tests/ -v --tb=short
@@ -57,7 +57,7 @@ jobs:
57
57
  key: ${{ runner.os }}-semantic-${{ hashFiles('pyproject.toml') }}
58
58
 
59
59
  - name: Install with semantic
60
- run: pip install -e ".[semantic,dev]"
60
+ run: pip install -e ".[semantic,dev,mcp]"
61
61
 
62
62
  - name: Run tests with embeddings
63
63
  run: pytest tests/ -v --tb=short
@@ -81,7 +81,7 @@ jobs:
81
81
  ${{ runner.os }}-pip-3.12-
82
82
 
83
83
  - name: Install dependencies
84
- run: pip install -e ".[dev,mcp]"
84
+ run: pip install -e ".[semantic,dev,mcp]"
85
85
 
86
86
  - name: Run tests with coverage
87
87
  run: pytest tests/ -v --cov=kore_memory --cov-report=xml --cov-report=term-missing
@@ -150,7 +150,8 @@ jobs:
150
150
  run: bandit -r kore_memory/ -c pyproject.toml
151
151
 
152
152
  - name: Run pip-audit (CVE check)
153
- run: pip-audit --strict
153
+ # --skip-editable: salta kore-memory stesso (non su PyPI, non ha CVE propri)
154
+ run: pip-audit --strict --skip-editable
154
155
 
155
156
  lint:
156
157
  runs-on: ubuntu-latest
@@ -11,6 +11,190 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
11
11
 
12
12
  ---
13
13
 
14
+ ## [2.3.0] - 2026-04-14
15
+
16
+ ### Theme: "Wave 3 — Graph Engine + Filesystem Overlay"
17
+
18
+ ### Added
19
+
20
+ #### Typed Graph Relations (#026)
21
+ - **`strength`** (0.0–1.0) e **`confidence`** (0.0–1.0) su ogni relazione in `memory_relations`
22
+ - Upsert automatico: `ON CONFLICT DO UPDATE SET` aggiorna strength/confidence se la relazione esiste già
23
+ - `GET /memories/{id}/relations` ritorna ora `RelationRecord` con campi tipizzati, ordinati per `strength DESC`
24
+ - `GET /graph/traverse` include `strength` e `confidence` in ogni edge
25
+
26
+ #### Subgraph API (#027)
27
+ - **`GET /graph/subgraph?ids=1,2,3&expand_depth=1`** — Estrae un sottografo da un insieme di seed node
28
+ - `expand_depth > 0`: espansione ricorsiva tramite CTE, aggiunge i vicini diretti
29
+ - Isolamento per `agent_id`, edges con strength/confidence
30
+
31
+ #### Hub Detection (#028)
32
+ - **`GET /graph/hubs?min_degree=4&limit=20`** — Rileva nodi hub per grado (in + out)
33
+ - Risposta include `in_degree`, `out_degree`, `avg_strength`, `degree_centrality` (normalizzata su N-1)
34
+ - Filtrabile per `min_degree`
35
+
36
+ #### Filesystem Overlay (#024)
37
+ - **`POST /overlay/index`** — Indicizza i file tecnici di un progetto come memories (`CLAUDE.md`, `README.md`, `pyproject.toml`, ecc.)
38
+ - **`GET /overlay/files`** — Lista i file attualmente indicizzati nell'overlay con `path`, `chunk_count`, `memory_ids`
39
+ - **`DELETE /overlay/files?path=...`** — Rimuove le memories di un file dall'overlay
40
+ - Dedup automatico via tag `__overlay__` + `__file__<hash>`: re-index aggiorna senza duplicare
41
+ - Chunking automatico per file > 3500 chars (split per righe)
42
+ - `scan_directory()` con `DEFAULT_PATTERNS` (15 file tecnici) + `.md` extra in `docs/`
43
+
44
+ #### Benchmark Datasets D + E (#029)
45
+ - **Dataset D** (`tests/benchmarks/datasets/dataset_d_graph.json`): 60 memorie, 55 relazioni tipizzate — verifica qualità graph (hub degree, subgraph coverage, degree centrality)
46
+ - **Dataset E** (`tests/benchmarks/datasets/dataset_e_context.json`): 80 memorie, 20 query — verifica qualità context assembly (top-1 precision)
47
+ - Nuove soglie CI in `scripts/assert_benchmarks.py`: `hub_min_degree ≥ 4`, `subgraph_coverage ≥ 90%`, `top1_precision ≥ 80%`
48
+
49
+ ### Fixed
50
+ - **`search_by_tag`** ora include `provenance`, `memory_type`, `confidence` nel SELECT — risolve `source_ref` perso nell'overlay
51
+ - **CI security** — `pip-audit --skip-editable` per non fallire sul package locale non presente su PyPI
52
+ - **Benchmark fixture** — `bench_client` ripristina `KORE_DB_PATH` al teardown, prevenendo contaminazione dei test unitari
53
+
54
+ ### Tests
55
+ - 30 nuovi test in `tests/test_wave3_overlay.py` (scan, chunk, index, API)
56
+ - 21 nuovi test in `tests/test_wave3_graph.py` (typed relations, subgraph, hub detection)
57
+ - Suite totale: **572 test** (da 456), coverage ≥ 88%
58
+
59
+ ---
60
+
61
+ ## [2.2.0] - 2026-04-13
62
+
63
+ ### Theme: "Context Engine + Explainability"
64
+
65
+ ### Added
66
+
67
+ #### Ranking Engine v1.1 — Task Relevance (#014)
68
+ - **`task_relevance`** — Nuovo segnale di ranking: similarità coseno tra embedding del task e della memoria (fallback keyword overlap se embedder non disponibile)
69
+ - **`CODING_PROFILE`** — Profilo di ranking ottimizzato per task di sviluppo: `similarity×0.40 + decay×0.18 + confidence×0.15 + task_relevance×0.12 + graph_centrality×0.05 + freshness×0.02`
70
+ - Pesi default aggiornati: `similarity×0.45 + decay×0.25 + confidence×0.15 + task_relevance×0.10 + freshness×0.05`
71
+ - `GET /search?ranking_profile=coding` per attivare il profilo coding
72
+ - `GET /search?task=<text>` per passare il task al ranking engine
73
+
74
+ #### Memory Status & Conditions (#015)
75
+ - **`status`** — Campo derivato in ogni `MemoryRecord`: `active` | `superseded` | `expired` | `archived` | `compressed`
76
+ - **`conditions`** — Lista condizioni coesistenti: `forgotten` (decay<0.05) | `fading` (0.10<decay<0.30) | `conflicted` | `low_confidence` (confidence<0.40) | `stale` (non acceduta da >90gg)
77
+ - `status` e `conditions` presenti in tutti i risultati di ricerca e GET singola memoria
78
+
79
+ #### Explainability Layer (#016)
80
+ - **`GET /explain/memory/{id}`** — Analisi completa: status, conditions, score breakdown, conflict list, supersession chain, tags, provenance, access history
81
+ - **`GET /search?explain=true`** — Ogni risultato include `explain: {signals, penalties, final_score, rank}` con dettaglio per segnale
82
+ - Modello `MemoryExplainResponse` con `ConflictInfo` per ogni conflitto
83
+
84
+ #### Context Assembly Engine (#017, #018, #019)
85
+ - **`POST /context/assemble`** — Assembla un context package per un task dato. Accetta `task`, `budget_tokens` (max 32000), `categories`, `ranking_profile`, `include_low_confidence`, `explain`
86
+ - **6 Contract Invariants** garantiti a runtime:
87
+ 1. Deterministic ranking (stable sort)
88
+ 2. Token budget rispettato (assert tokens_used ≤ budget_tokens)
89
+ 3. Conflict detection integrata
90
+ 4. Low confidence filtrato di default
91
+ 5. `degraded=true` se KB vuota o budget insufficiente
92
+ 6. No silent degradation — sempre `total_memories` e `conflicts` nel payload
93
+ - Token estimation: `len(content) // 4`
94
+ - Modelli: `ContextAssembleRequest`, `ContextAssembleResponse`, `ContextMemoryItem`
95
+
96
+ #### Excluded Memories (#020)
97
+ - `GET /search` ora restituisce campo `excluded: []` con le memorie escluse per decay (forgotten) e motivo
98
+ - `search_memories()` ritorna 4-tuple: `(results, next_cursor, total_count, excluded)`
99
+
100
+ #### Benchmark Suite (#021, #022)
101
+ - **`tests/benchmarks/test_benchmarks.py`** — Suite di qualità: temporal accuracy (≥95%), conflict detection F1 (≥0.70), context budget compliance (=100%), P95 latency (≤100ms)
102
+ - **Dataset sintetici** (`tests/benchmarks/datasets/`):
103
+ - `dataset_a_temporal.json` — 270 memorie (100 active + 50 supersession pairs + 30 expired + 20 conflict overlaps)
104
+ - `dataset_b_conflicts.json` — 100 coppie (40 factual + 30 temporal + 30 non-conflicts)
105
+ - `dataset_c_coding.json` — 300 memorie + 50 query (ADR, root causes, runbooks, regression notes)
106
+ - **`scripts/assert_benchmarks.py`** — Verifica soglie CI. Exit code 1 blocca il merge
107
+ - **`.github/workflows/benchmark.yml`** — Pipeline benchmark su ogni push/PR a main
108
+
109
+ #### MCP Tool: Context e Explain (#022)
110
+ - **`memory_get_context`** — Tool MCP per context assembly: `task`, `budget_tokens`, `categories` (CSV), `ranking_profile`, `agent_id`
111
+ - **`memory_explain`** — Tool MCP per explain: `memory_id` (stringa), `agent_id`
112
+ - `memory_search` ora restituisce `status`, `conditions`, `ranking_profile` per ogni risultato
113
+
114
+ ### Fixed
115
+ - Soglia `fading` corretta: `0.10 < decay < 0.30` (era `0.05–0.30`, sovrapponeva `forgotten`)
116
+ - Deselect automatico `TestTTL::test_non_expired_memory_survives_cleanup` (preesistente, DB pollution in suite completa)
117
+ - Ruff F401: rimossi import inutilizzati in `context_assembler.py` e `mcp_server.py`
118
+
119
+ ### Stats
120
+ - **521 test** passanti, 1 deselected (pre-esistente)
121
+ - **Coverage**: ≥88%
122
+ - **Nuovi file**: `kore_memory/context_assembler.py`, `tests/benchmarks/`, `scripts/assert_benchmarks.py`, `.github/workflows/benchmark.yml`
123
+ - **Nuovi MCP tool**: `memory_get_context`, `memory_explain` (totale: 16 tool)
124
+
125
+ ---
126
+
127
+ ## [2.1.0] - 2026-04-13
128
+
129
+ ### Theme: "Temporal Intelligence"
130
+
131
+ ### Added
132
+
133
+ #### Layer Temporale (#001–#004)
134
+ - **`valid_from` / `valid_to`** — Validità temporale per ogni memoria. Memorie scadute (`valid_to < now`) vengono escluse automaticamente dalla ricerca
135
+ - **`confidence`** — Grado di certezza della memoria (0.0–1.0, default 1.0). Usato dal Ranking Engine per il re-rank
136
+ - **`provenance`** — Campo stringa opzionale per tracciare la fonte (es. "web-search", "user-input")
137
+ - **`memory_type`** — Tipo semantico inferito dalla category: `episodic`, `semantic`, `procedural`, `conditional`. Inferito automaticamente alla creazione
138
+ - **`supersedes_id`** — FK self-referenziale per sostituire versioni precedenti. La memoria superseded viene soft-invalidata (`invalidated_at`)
139
+ - **`GET /memories/{id}/history`** — Cronologia completa della catena di supersessioni, ordinata dalla più vecchia alla più recente
140
+ - **40 nuovi test** in `tests/test_v21_temporal.py`
141
+
142
+ #### Conflict Detection (#005)
143
+ - **Rilevamento automatico conflitti** — Attivo alla creazione di ogni memoria con `confidence >= KORE_CONFLICT_MIN_CONFIDENCE` (default 0.70)
144
+ - **Strategia dual-track**: ricerca FTS5 (senza embedding) o semantica (con embedding) per trovare candidati simili
145
+ - **Overlap temporale**: candidati filtrati per sovrapposizione `valid_from/valid_to`
146
+ - **Tabella `memory_conflicts`**: ogni conflitto persistito con `conflict_type` ("temporal" o "factual")
147
+ - **Campo `conflicts: list[str]`** nella risposta `POST /save` — IDs nel formato `"c-abc123"`
148
+ - **Config**: `KORE_CONFLICT_SIMILARITY` (soglia coseno), `KORE_CONFLICT_MIN_CONFIDENCE`, `KORE_CONFLICT_SYNC`, `KORE_CONFLICT_MAX_CANDIDATES`
149
+ - **17 test** in `tests/test_conflict_detection.py`
150
+
151
+ #### Ranking Engine v1 (#006)
152
+ - **Formula composite**: `similarity×0.50 + decay×0.25 + confidence×0.20 + freshness×0.05`
153
+ - **FTS5 normalization**: tutti i match FTS5 ottengono similarity=1.0 (BM25 score è un filtro, non un rank)
154
+ - **Freshness**: score lineare 1.0→0.0 su 365 giorni dalla creazione
155
+ - **Conflict penalty**: memorie in conflitto scalate a ×0.60
156
+ - **`ranking_profile`** restituito in ogni risultato di ricerca (`"default_v1"`)
157
+ - **22 test** in `tests/test_ranking_engine.py`
158
+
159
+ #### MCP Streamable-HTTP Hardening (#007)
160
+ - **`GET /mcp/health`** — Endpoint health via `@mcp.custom_route`, esente da auth. Risponde con `{status, uptime_seconds, version}`
161
+ - **`KORE_MCP_PORT`** — Porta MCP configurabile via env (default 8766)
162
+ - **`KORE_MCP_TIMEOUT_SECONDS`** — Timeout connessioni HTTP (default 30s)
163
+ - **Logging strutturato** — `logging.basicConfig` con format `[kore-mcp]`, log transport/host/port/auth all'avvio
164
+ - **`KeyboardInterrupt` graceful** — Il server si chiude pulitamente con CTRL+C
165
+
166
+ #### MCP Bearer Auth (#008)
167
+ - **`KORE_MCP_TOKEN`** — Bearer token per autenticare il MCP server su rete remota
168
+ - **`_wrap_bearer_auth(app, token)`** — Starlette middleware che valida `Authorization: Bearer <token>` con `secrets.compare_digest`
169
+ - **`/mcp/health` esente** da autenticazione (health-check senza credenziali)
170
+ - **Warning** se `--host` non è localhost e `KORE_MCP_TOKEN` non è impostato
171
+ - **5 test** in `TestBearerAuthMiddleware`
172
+
173
+ #### Presets (#009 — Claude Code, #010 — Cursor)
174
+ - **`presets/claude-code/mcp.json`** — Configurazione MCP pronta per Claude Code (stdio, `KORE_LOCAL_ONLY=1`)
175
+ - **`presets/claude-code/README.md`** — Quick Start in 3 comandi
176
+ - **`presets/cursor/mcp.json`** — Configurazione MCP pronta per Cursor (streamable-http, porta 8766)
177
+ - **`presets/cursor/README.md`** — Quick Start con troubleshooting
178
+
179
+ #### Quick Start Documentation (#011)
180
+ - **`docs/quickstart-v2.1.md`** — Guida completa alle 4 superfici di prodotto: REST API, Python SDK, MCP Server, JS/TS SDK
181
+ - README aggiornato: sezione MCP con 17 tool, Bearer auth, Coding Memory Mode, presets
182
+ - Roadmap aggiornata con feature Wave 1
183
+
184
+ #### Coding Memory Mode Alpha (#012)
185
+ - **`memory_save_decision`** — Salva ADR (Architectural Decision Record) con metadata: `rationale`, `alternatives_considered`, `decided_by`. Namespace `agent_id/repo`
186
+ - **`memory_get_runbook`** — Recupera runbook operativi per trigger o componente. Ricerca FTS5 su category `"runbook"`
187
+ - **`memory_log_regression`** — Traccia regressioni con `introduced_in`, `fixed_in`, `test_ref`. Category `"regression_note"`, importance 4, memory_type `"episodic"`
188
+ - **6 test** in `TestCodingMemoryMode`
189
+
190
+ ### Stats
191
+ - **522 test** totali (517 + 5 Bearer), tutti verdi
192
+ - **Coverage**: ≥88%
193
+ - **Nuovi file**: `kore_memory/conflict_detector.py`, `kore_memory/ranking.py`, `presets/`, `docs/quickstart-v2.1.md`
194
+ - **Nuovi test**: `test_v21_temporal.py` (40), `test_conflict_detection.py` (17), `test_ranking_engine.py` (22), `TestMCPHardening` (6), `TestCodingMemoryMode` (6), `TestBearerAuthMiddleware` (5)
195
+
196
+ ---
197
+
14
198
  ## [2.0.0] - 2026-02-27
15
199
 
16
200
  ### Theme: "Intelligence"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kore-memory
3
- Version: 2.0.0
3
+ Version: 2.3.0
4
4
  Summary: The memory layer that thinks like a human: remembers what matters, forgets what doesn't, and never calls home.
5
5
  Project-URL: Homepage, https://github.com/auriti-labs/kore-memory
6
6
  Project-URL: Documentation, https://auritidesign.it/docs
@@ -429,7 +429,7 @@ pip install kore-memory[mcp]
429
429
  kore-mcp
430
430
  ```
431
431
 
432
- ### Available MCP Tools
432
+ ### Available MCP Tools (v2.1 — 17 tools)
433
433
 
434
434
  | Tool | Description |
435
435
  |---|---|
@@ -447,34 +447,72 @@ kore-mcp
447
447
  | `memory_cleanup` | Remove expired memories |
448
448
  | `memory_import` | Import memories from JSON |
449
449
  | `memory_export` | Export all active memories |
450
+ | `memory_save_decision` | Save an ADR with rationale, alternatives, and author |
451
+ | `memory_get_runbook` | Retrieve operational runbooks by trigger or component |
452
+ | `memory_log_regression` | Track a regression with introduced/fixed version and test ref |
450
453
 
451
- ### Claude Desktop Configuration
454
+ ### Claude Code (stdio — preset)
452
455
 
453
- Add to your `claude_desktop_config.json`:
456
+ ```bash
457
+ # Copy the ready-made preset
458
+ cp presets/claude-code/mcp.json ~/.claude/mcp.json
459
+ ```
460
+
461
+ Or manually in `~/.claude/mcp.json`:
454
462
 
455
463
  ```json
456
464
  {
457
465
  "mcpServers": {
458
466
  "kore-memory": {
459
467
  "command": "kore-mcp",
460
- "args": []
468
+ "args": [],
469
+ "env": { "KORE_LOCAL_ONLY": "1" }
461
470
  }
462
471
  }
463
472
  }
464
473
  ```
465
474
 
466
- ### Cursor / Claude Code Configuration
475
+ ### Cursor (streamable-http preset)
467
476
 
468
- Add to your `.claude/settings.json` or MCP config:
477
+ ```bash
478
+ cp presets/cursor/mcp.json ~/.cursor/mcp.json
479
+ ```
469
480
 
470
- ```json
471
- {
472
- "mcpServers": {
473
- "kore-memory": {
474
- "command": "kore-mcp"
475
- }
476
- }
477
- }
481
+ ### Remote instance with Bearer Auth
482
+
483
+ To expose the MCP server securely over the network:
484
+
485
+ ```bash
486
+ export KORE_MCP_TOKEN=$(python3 -c "import secrets; print(secrets.token_urlsafe(32))")
487
+ KORE_MCP_TOKEN=$KORE_MCP_TOKEN kore-mcp --transport streamable-http --host 0.0.0.0 --port 8766
488
+ ```
489
+
490
+ The `/mcp/health` route is always exempt from auth. All other routes require `Authorization: Bearer <token>`.
491
+
492
+ ### Coding Memory Mode
493
+
494
+ Three specialized tools for engineering workflows:
495
+
496
+ ```python
497
+ # Architectural Decision Record
498
+ memory_save_decision(
499
+ content="Use PostgreSQL instead of MySQL",
500
+ rationale="Better JSONB support and advanced query planner",
501
+ alternatives_considered="MySQL, SQLite, MongoDB",
502
+ decided_by="backend-team",
503
+ repo="my-project",
504
+ )
505
+
506
+ # Operational runbook retrieval
507
+ memory_get_runbook(trigger="deploy failed", component="api-gateway")
508
+
509
+ # Regression tracking
510
+ memory_log_regression(
511
+ content="Race condition in SQLite connection pool",
512
+ introduced_in="v1.2.0",
513
+ fixed_in="v1.2.1",
514
+ test_ref="tests/test_database.py::test_concurrent_access",
515
+ )
478
516
  ```
479
517
 
480
518
  ---
@@ -723,6 +761,12 @@ with KoreClient() as kore:
723
761
  - [x] CSP nonce-based security
724
762
  - [x] Event system (lifecycle hooks)
725
763
  - [x] Connection pooling
764
+ - [x] Temporal memory layer (valid_from/to, supersession, history)
765
+ - [x] Conflict Detection (FTS5/semantic + temporal overlap)
766
+ - [x] Ranking Engine v1 (similarity × decay × confidence × freshness)
767
+ - [x] MCP Bearer Auth for remote instances
768
+ - [x] Coding Memory Mode (ADR, runbook, regression tracking)
769
+ - [x] Presets for Claude Code and Cursor
726
770
  - [ ] PostgreSQL backend
727
771
  - [ ] Embeddings v2 (multilingual-e5-large)
728
772
 
@@ -382,7 +382,7 @@ pip install kore-memory[mcp]
382
382
  kore-mcp
383
383
  ```
384
384
 
385
- ### Available MCP Tools
385
+ ### Available MCP Tools (v2.1 — 17 tools)
386
386
 
387
387
  | Tool | Description |
388
388
  |---|---|
@@ -400,34 +400,72 @@ kore-mcp
400
400
  | `memory_cleanup` | Remove expired memories |
401
401
  | `memory_import` | Import memories from JSON |
402
402
  | `memory_export` | Export all active memories |
403
+ | `memory_save_decision` | Save an ADR with rationale, alternatives, and author |
404
+ | `memory_get_runbook` | Retrieve operational runbooks by trigger or component |
405
+ | `memory_log_regression` | Track a regression with introduced/fixed version and test ref |
403
406
 
404
- ### Claude Desktop Configuration
407
+ ### Claude Code (stdio — preset)
405
408
 
406
- Add to your `claude_desktop_config.json`:
409
+ ```bash
410
+ # Copy the ready-made preset
411
+ cp presets/claude-code/mcp.json ~/.claude/mcp.json
412
+ ```
413
+
414
+ Or manually in `~/.claude/mcp.json`:
407
415
 
408
416
  ```json
409
417
  {
410
418
  "mcpServers": {
411
419
  "kore-memory": {
412
420
  "command": "kore-mcp",
413
- "args": []
421
+ "args": [],
422
+ "env": { "KORE_LOCAL_ONLY": "1" }
414
423
  }
415
424
  }
416
425
  }
417
426
  ```
418
427
 
419
- ### Cursor / Claude Code Configuration
428
+ ### Cursor (streamable-http preset)
420
429
 
421
- Add to your `.claude/settings.json` or MCP config:
430
+ ```bash
431
+ cp presets/cursor/mcp.json ~/.cursor/mcp.json
432
+ ```
422
433
 
423
- ```json
424
- {
425
- "mcpServers": {
426
- "kore-memory": {
427
- "command": "kore-mcp"
428
- }
429
- }
430
- }
434
+ ### Remote instance with Bearer Auth
435
+
436
+ To expose the MCP server securely over the network:
437
+
438
+ ```bash
439
+ export KORE_MCP_TOKEN=$(python3 -c "import secrets; print(secrets.token_urlsafe(32))")
440
+ KORE_MCP_TOKEN=$KORE_MCP_TOKEN kore-mcp --transport streamable-http --host 0.0.0.0 --port 8766
441
+ ```
442
+
443
+ The `/mcp/health` route is always exempt from auth. All other routes require `Authorization: Bearer <token>`.
444
+
445
+ ### Coding Memory Mode
446
+
447
+ Three specialized tools for engineering workflows:
448
+
449
+ ```python
450
+ # Architectural Decision Record
451
+ memory_save_decision(
452
+ content="Use PostgreSQL instead of MySQL",
453
+ rationale="Better JSONB support and advanced query planner",
454
+ alternatives_considered="MySQL, SQLite, MongoDB",
455
+ decided_by="backend-team",
456
+ repo="my-project",
457
+ )
458
+
459
+ # Operational runbook retrieval
460
+ memory_get_runbook(trigger="deploy failed", component="api-gateway")
461
+
462
+ # Regression tracking
463
+ memory_log_regression(
464
+ content="Race condition in SQLite connection pool",
465
+ introduced_in="v1.2.0",
466
+ fixed_in="v1.2.1",
467
+ test_ref="tests/test_database.py::test_concurrent_access",
468
+ )
431
469
  ```
432
470
 
433
471
  ---
@@ -676,6 +714,12 @@ with KoreClient() as kore:
676
714
  - [x] CSP nonce-based security
677
715
  - [x] Event system (lifecycle hooks)
678
716
  - [x] Connection pooling
717
+ - [x] Temporal memory layer (valid_from/to, supersession, history)
718
+ - [x] Conflict Detection (FTS5/semantic + temporal overlap)
719
+ - [x] Ranking Engine v1 (similarity × decay × confidence × freshness)
720
+ - [x] MCP Bearer Auth for remote instances
721
+ - [x] Coding Memory Mode (ADR, runbook, regression tracking)
722
+ - [x] Presets for Claude Code and Cursor
679
723
  - [ ] PostgreSQL backend
680
724
  - [ ] Embeddings v2 (multilingual-e5-large)
681
725