engraphis 1.2.2__tar.gz → 1.2.5__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 (334) hide show
  1. {engraphis-1.2.2 → engraphis-1.2.5}/.env.example +4 -0
  2. engraphis-1.2.5/BENCHMARKS.md +291 -0
  3. {engraphis-1.2.2 → engraphis-1.2.5}/CHANGELOG.md +39 -0
  4. {engraphis-1.2.2 → engraphis-1.2.5}/MANIFEST.in +1 -0
  5. {engraphis-1.2.2 → engraphis-1.2.5}/PKG-INFO +155 -289
  6. {engraphis-1.2.2 → engraphis-1.2.5}/README.md +154 -288
  7. {engraphis-1.2.2 → engraphis-1.2.5}/docker-compose.yml +4 -2
  8. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/__init__.py +1 -1
  9. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/backends/extractor.py +141 -29
  10. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/backends/sync_folder.py +10 -6
  11. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/classic_assets/dashboard.js +4 -5
  12. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/commercial_manifest.json +1 -1
  13. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/config.py +3 -2
  14. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/core/consolidate.py +51 -25
  15. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/core/context.py +11 -0
  16. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/core/engine.py +7 -3
  17. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/core/grounded.py +12 -0
  18. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/core/interfaces.py +7 -0
  19. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/core/recall.py +31 -1
  20. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/core/retrieval_policy.py +39 -0
  21. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/core/store.py +140 -6
  22. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/core/sync.py +35 -1
  23. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/dashboard_assets/engraphis-graph.js +136 -11
  24. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/dashboard_assets/ledger.js +3 -4
  25. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/inspector/app.py +4 -0
  26. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/mcp_server.py +34 -2
  27. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/read_only_api.py +8 -0
  28. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/routes/v2_api.py +16 -1
  29. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/service.py +57 -11
  30. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/static/dashboard.js +4 -5
  31. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis.egg-info/PKG-INFO +155 -289
  32. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis.egg-info/SOURCES.txt +10 -0
  33. engraphis-1.2.5/eval/EVIDENCE.md +30 -0
  34. engraphis-1.2.5/eval/agent_benchmarks.py +630 -0
  35. {engraphis-1.2.2 → engraphis-1.2.5}/eval/benchmark.py +359 -12
  36. {engraphis-1.2.2 → engraphis-1.2.5}/eval/chunking_eval.py +34 -6
  37. engraphis-1.2.5/eval/code_agent_ab.py +238 -0
  38. engraphis-1.2.5/eval/context_economy.py +438 -0
  39. engraphis-1.2.5/eval/longmemeval_v2_evidence.py +256 -0
  40. {engraphis-1.2.2 → engraphis-1.2.5}/eval/performance.py +114 -4
  41. {engraphis-1.2.2 → engraphis-1.2.5}/pyproject.toml +2 -2
  42. {engraphis-1.2.2 → engraphis-1.2.5}/scripts/check_codeql_sarif.py +36 -5
  43. {engraphis-1.2.2 → engraphis-1.2.5}/scripts/externalize_dashboard_assets.py +14 -1
  44. {engraphis-1.2.2 → engraphis-1.2.5}/scripts/install_shortcuts.py +71 -7
  45. {engraphis-1.2.2 → engraphis-1.2.5}/scripts/sync.py +10 -2
  46. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_benchmark_evidence.py +191 -6
  47. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_chunking_eval.py +27 -0
  48. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_chunking_extractor.py +123 -2
  49. engraphis-1.2.5/tests/test_code_agent_ab.py +142 -0
  50. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_codeql_sarif_gate.py +23 -0
  51. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_consolidate.py +111 -0
  52. engraphis-1.2.5/tests/test_context_economy.py +255 -0
  53. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_context_packing.py +35 -0
  54. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_dashboard_auth_placement.py +6 -6
  55. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_dashboard_v2.py +16 -3
  56. engraphis-1.2.5/tests/test_eval_agent_benchmarks.py +357 -0
  57. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_eval_harness.py +4 -0
  58. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_eval_performance.py +53 -1
  59. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_externalize_dashboard_assets.py +15 -0
  60. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_graph_engine_asset.py +37 -3
  61. engraphis-1.2.5/tests/test_install_shortcuts.py +96 -0
  62. engraphis-1.2.5/tests/test_longmemeval_v2_evidence.py +157 -0
  63. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_mcp_server.py +10 -5
  64. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_packaging.py +5 -1
  65. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_read_only_api.py +33 -2
  66. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_receipts.py +121 -0
  67. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_release_infrastructure.py +8 -5
  68. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_retrieval_policy.py +56 -0
  69. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_sync.py +175 -6
  70. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_sync_cli.py +17 -0
  71. engraphis-1.2.2/BENCHMARKS.md +0 -147
  72. {engraphis-1.2.2 → engraphis-1.2.5}/Dockerfile +0 -0
  73. {engraphis-1.2.2 → engraphis-1.2.5}/LICENSE +0 -0
  74. {engraphis-1.2.2 → engraphis-1.2.5}/NOTICE +0 -0
  75. {engraphis-1.2.2 → engraphis-1.2.5}/docker-entrypoint.sh +0 -0
  76. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/ai_context.py +0 -0
  77. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/app.py +0 -0
  78. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/backends/__init__.py +0 -0
  79. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/backends/codegraph.py +0 -0
  80. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/backends/embedder_api.py +0 -0
  81. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/backends/embedder_deterministic.py +0 -0
  82. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/backends/embedder_st.py +0 -0
  83. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/backends/encrypted_db.py +0 -0
  84. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/backends/graph_extractor.py +0 -0
  85. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/backends/postgres_schema.py +0 -0
  86. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/backends/reranker.py +0 -0
  87. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/backends/resources.py +0 -0
  88. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/backends/retention.py +0 -0
  89. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/backends/sync_relay.py +0 -0
  90. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/backends/vector_numpy.py +0 -0
  91. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/backends/vector_sqlitevec.py +0 -0
  92. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/classic_assets/__init__.py +0 -0
  93. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/classic_assets/dashboard.css +0 -0
  94. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/classic_assets/engraphis-graph.js +0 -0
  95. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/classic_assets/engraphis-icon.png +0 -0
  96. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/classic_assets/engraphis.ico +0 -0
  97. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/classic_assets/favicon-32.png +0 -0
  98. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/classic_assets/index.html +0 -0
  99. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/classic_assets/vendor/d3.LICENSE +0 -0
  100. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/classic_assets/vendor/d3.min.js +0 -0
  101. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/classic_assets/vendor/force-graph.LICENSE +0 -0
  102. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/classic_assets/vendor/force-graph.min.js +0 -0
  103. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/classic_assets/vendor/marked.LICENSE +0 -0
  104. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/classic_assets/vendor/marked.min.js +0 -0
  105. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/classic_assets/vendor/purify.min.js +0 -0
  106. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/cloud_features.py +0 -0
  107. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/cloud_session.py +0 -0
  108. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/commercial.py +0 -0
  109. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/core/__init__.py +0 -0
  110. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/core/codegraph_export.py +0 -0
  111. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/core/conflicts.py +0 -0
  112. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/core/graph_layers.py +0 -0
  113. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/core/graph_scene.py +0 -0
  114. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/core/graphrank.py +0 -0
  115. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/core/ids.py +0 -0
  116. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/core/resolve.py +0 -0
  117. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/core/schema.py +0 -0
  118. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/core/scoring.py +0 -0
  119. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/core/textutil.py +0 -0
  120. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/core/user_model.py +0 -0
  121. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/dashboard_app.py +0 -0
  122. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/dashboard_assets/__init__.py +0 -0
  123. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/dashboard_assets/engraphis-graph-compat.js +0 -0
  124. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/dashboard_assets/engraphis-icon.png +0 -0
  125. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/dashboard_assets/engraphis.ico +0 -0
  126. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/dashboard_assets/favicon-32.png +0 -0
  127. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/dashboard_assets/index.html +0 -0
  128. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/dashboard_assets/ledger.css +0 -0
  129. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/dashboard_assets/vendor/d3.LICENSE +0 -0
  130. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/dashboard_assets/vendor/d3.min.js +0 -0
  131. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/dashboard_assets/vendor/force-graph.LICENSE +0 -0
  132. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/dashboard_assets/vendor/force-graph.min.js +0 -0
  133. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/device_connect.py +0 -0
  134. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/engines/__init__.py +0 -0
  135. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/engines/embedder.py +0 -0
  136. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/engines/ingest.py +0 -0
  137. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/engines/intelligence.py +0 -0
  138. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/engines/recall.py +0 -0
  139. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/engines/reweight.py +0 -0
  140. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/engines/thoughts.py +0 -0
  141. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/graphdata.py +0 -0
  142. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/hosted_client.py +0 -0
  143. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/http_security.py +0 -0
  144. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/inspector/__init__.py +0 -0
  145. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/licensing.py +0 -0
  146. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/llm/__init__.py +0 -0
  147. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/llm/client.py +0 -0
  148. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/local_auth.py +0 -0
  149. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/logging_setup.py +0 -0
  150. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/mcp_cli.py +0 -0
  151. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/models.py +0 -0
  152. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/netutil.py +0 -0
  153. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/observability.py +0 -0
  154. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/private_state.py +0 -0
  155. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/redirector.py +0 -0
  156. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/routes/__init__.py +0 -0
  157. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/routes/memory.py +0 -0
  158. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/routes/vault.py +0 -0
  159. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/static/__init__.py +0 -0
  160. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/static/dashboard.css +0 -0
  161. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/static/engraphis-graph.js +0 -0
  162. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/static/engraphis-icon.png +0 -0
  163. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/static/engraphis.ico +0 -0
  164. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/static/favicon-32.png +0 -0
  165. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/static/index.html +0 -0
  166. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/static/vendor/d3.LICENSE +0 -0
  167. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/static/vendor/d3.min.js +0 -0
  168. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/static/vendor/force-graph.LICENSE +0 -0
  169. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/static/vendor/force-graph.min.js +0 -0
  170. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/static/vendor/marked.LICENSE +0 -0
  171. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/static/vendor/marked.min.js +0 -0
  172. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/static/vendor/purify.min.js +0 -0
  173. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/stores/__init__.py +0 -0
  174. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/stores/graph.py +0 -0
  175. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/stores/ledger.py +0 -0
  176. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/stores/vaults.py +0 -0
  177. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/stores/vectors.py +0 -0
  178. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis/update_check.py +0 -0
  179. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis.egg-info/dependency_links.txt +0 -0
  180. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis.egg-info/entry_points.txt +0 -0
  181. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis.egg-info/requires.txt +0 -0
  182. {engraphis-1.2.2 → engraphis-1.2.5}/engraphis.egg-info/top_level.txt +0 -0
  183. {engraphis-1.2.2 → engraphis-1.2.5}/eval/BASELINES.md +0 -0
  184. {engraphis-1.2.2 → engraphis-1.2.5}/eval/__init__.py +0 -0
  185. {engraphis-1.2.2 → engraphis-1.2.5}/eval/ablation.py +0 -0
  186. {engraphis-1.2.2 → engraphis-1.2.5}/eval/configs/longmemeval_v2_engraphis.json +0 -0
  187. {engraphis-1.2.2 → engraphis-1.2.5}/eval/datasets/adversarial.jsonl +0 -0
  188. {engraphis-1.2.2 → engraphis-1.2.5}/eval/datasets/codemem.jsonl +0 -0
  189. {engraphis-1.2.2 → engraphis-1.2.5}/eval/datasets/graph_multihop.jsonl +0 -0
  190. {engraphis-1.2.2 → engraphis-1.2.5}/eval/datasets/longdoc.jsonl +0 -0
  191. {engraphis-1.2.2 → engraphis-1.2.5}/eval/datasets/sample.jsonl +0 -0
  192. {engraphis-1.2.2 → engraphis-1.2.5}/eval/external.py +0 -0
  193. {engraphis-1.2.2 → engraphis-1.2.5}/eval/grounded.py +0 -0
  194. {engraphis-1.2.2 → engraphis-1.2.5}/eval/harness.py +0 -0
  195. {engraphis-1.2.2 → engraphis-1.2.5}/eval/longmemeval_v2.py +0 -0
  196. {engraphis-1.2.2 → engraphis-1.2.5}/eval/metrics.py +0 -0
  197. {engraphis-1.2.2 → engraphis-1.2.5}/eval/run_longmemeval_v2.py +0 -0
  198. {engraphis-1.2.2 → engraphis-1.2.5}/railway.json +0 -0
  199. {engraphis-1.2.2 → engraphis-1.2.5}/requirements.txt +0 -0
  200. {engraphis-1.2.2 → engraphis-1.2.5}/scripts/__init__.py +0 -0
  201. {engraphis-1.2.2 → engraphis-1.2.5}/scripts/backfill_graph.py +0 -0
  202. {engraphis-1.2.2 → engraphis-1.2.5}/scripts/check_commercial_manifest.py +0 -0
  203. {engraphis-1.2.2 → engraphis-1.2.5}/scripts/cli.py +0 -0
  204. {engraphis-1.2.2 → engraphis-1.2.5}/scripts/connect.py +0 -0
  205. {engraphis-1.2.2 → engraphis-1.2.5}/scripts/consolidate.py +0 -0
  206. {engraphis-1.2.2 → engraphis-1.2.5}/scripts/entry.py +0 -0
  207. {engraphis-1.2.2 → engraphis-1.2.5}/scripts/graph_cli.py +0 -0
  208. {engraphis-1.2.2 → engraphis-1.2.5}/scripts/graph_server.py +0 -0
  209. {engraphis-1.2.2 → engraphis-1.2.5}/scripts/init.py +0 -0
  210. {engraphis-1.2.2 → engraphis-1.2.5}/scripts/inspector.py +0 -0
  211. {engraphis-1.2.2 → engraphis-1.2.5}/scripts/mcp_server_http.py +0 -0
  212. {engraphis-1.2.2 → engraphis-1.2.5}/scripts/migrate_to_v2.py +0 -0
  213. {engraphis-1.2.2 → engraphis-1.2.5}/scripts/release_evidence.py +0 -0
  214. {engraphis-1.2.2 → engraphis-1.2.5}/scripts/repair_embed_dim.py +0 -0
  215. {engraphis-1.2.2 → engraphis-1.2.5}/scripts/sdk_compat.py +0 -0
  216. {engraphis-1.2.2 → engraphis-1.2.5}/scripts/seed_from_obsidian.py +0 -0
  217. {engraphis-1.2.2 → engraphis-1.2.5}/scripts/start_dashboard.py +0 -0
  218. {engraphis-1.2.2 → engraphis-1.2.5}/scripts/start_server.py +0 -0
  219. {engraphis-1.2.2 → engraphis-1.2.5}/scripts/test_routes.py +0 -0
  220. {engraphis-1.2.2 → engraphis-1.2.5}/scripts/update.py +0 -0
  221. {engraphis-1.2.2 → engraphis-1.2.5}/scripts/verify_distribution_contents.py +0 -0
  222. {engraphis-1.2.2 → engraphis-1.2.5}/scripts/verify_release_artifacts.py +0 -0
  223. {engraphis-1.2.2 → engraphis-1.2.5}/setup.cfg +0 -0
  224. {engraphis-1.2.2 → engraphis-1.2.5}/setup.py +0 -0
  225. {engraphis-1.2.2 → engraphis-1.2.5}/tests/__init__.py +0 -0
  226. {engraphis-1.2.2 → engraphis-1.2.5}/tests/conftest.py +0 -0
  227. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_agent_connect.py +0 -0
  228. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_app_auth.py +0 -0
  229. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_backends_factories.py +0 -0
  230. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_benchmark_adversarial.py +0 -0
  231. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_benchmark_longmemeval_v2.py +0 -0
  232. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_bitemporal_recall.py +0 -0
  233. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_canonical_export.py +0 -0
  234. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_cli_entrypoints.py +0 -0
  235. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_client_launch.py +0 -0
  236. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_cloud_features.py +0 -0
  237. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_cloud_session.py +0 -0
  238. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_code_index_route_security.py +0 -0
  239. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_code_recall_arm.py +0 -0
  240. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_codegraph.py +0 -0
  241. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_commercial_hardening.py +0 -0
  242. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_compact_recall.py +0 -0
  243. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_config.py +0 -0
  244. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_conflicts.py +0 -0
  245. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_core_ids.py +0 -0
  246. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_core_store.py +0 -0
  247. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_cron_write_tools_workspace_default.py +0 -0
  248. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_customer_node_hardening.py +0 -0
  249. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_dashboard_button_regressions.py +0 -0
  250. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_dashboard_dream_ui.py +0 -0
  251. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_dashboard_security_headers_and_open_window.py +0 -0
  252. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_db_path_default.py +0 -0
  253. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_decay_idempotent.py +0 -0
  254. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_device_connect.py +0 -0
  255. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_embedder_threading.py +0 -0
  256. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_encrypted_store.py +0 -0
  257. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_encryption_dependency.py +0 -0
  258. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_engine.py +0 -0
  259. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_eval_ablation.py +0 -0
  260. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_eval_external.py +0 -0
  261. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_eval_grounded.py +0 -0
  262. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_extractor.py +0 -0
  263. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_graph_cli.py +0 -0
  264. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_graph_explorer_v2.py +0 -0
  265. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_graph_extractor.py +0 -0
  266. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_graph_scene_contract.py +0 -0
  267. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_graph_server.py +0 -0
  268. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_graphdata.py +0 -0
  269. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_graphrank.py +0 -0
  270. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_grounded.py +0 -0
  271. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_hosted_client.py +0 -0
  272. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_hosted_plan_resolution.py +0 -0
  273. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_http_security.py +0 -0
  274. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_import_chunking.py +0 -0
  275. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_import_error_redaction.py +0 -0
  276. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_ingest_entities.py +0 -0
  277. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_init.py +0 -0
  278. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_inspector.py +0 -0
  279. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_inspector_pro.py +0 -0
  280. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_intent_paywall.py +0 -0
  281. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_licensing_boundary_docs.py +0 -0
  282. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_licensing_launch.py +0 -0
  283. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_llm_config.py +0 -0
  284. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_llm_dashboard.py +0 -0
  285. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_local_auth_browser_session.py +0 -0
  286. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_logging_setup.py +0 -0
  287. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_mcp_annotation_idempotency.py +0 -0
  288. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_memory_routes_fixes.py +0 -0
  289. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_merge.py +0 -0
  290. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_metadata_activity_forgery.py +0 -0
  291. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_migration.py +0 -0
  292. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_netutil.py +0 -0
  293. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_observability.py +0 -0
  294. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_personal_folders.py +0 -0
  295. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_postgres_schema.py +0 -0
  296. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_private_state_boundaries.py +0 -0
  297. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_pro_cta.py +0 -0
  298. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_proactive_context.py +0 -0
  299. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_protocol_upgrades.py +0 -0
  300. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_provenance_flags.py +0 -0
  301. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_provider_error_redaction.py +0 -0
  302. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_public_research_boundary.py +0 -0
  303. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_ready.py +0 -0
  304. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_recall.py +0 -0
  305. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_recall_entity_workspace_widening.py +0 -0
  306. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_relay_device_credentials.py +0 -0
  307. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_release_artifacts.py +0 -0
  308. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_release_evidence.py +0 -0
  309. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_remember_atomicity.py +0 -0
  310. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_resolve.py +0 -0
  311. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_resources.py +0 -0
  312. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_retention.py +0 -0
  313. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_round17_fixes.py +0 -0
  314. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_scoring.py +0 -0
  315. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_security_fixes.py +0 -0
  316. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_service.py +0 -0
  317. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_service_graph.py +0 -0
  318. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_service_isolation.py +0 -0
  319. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_session_idempotent.py +0 -0
  320. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_start_dashboard.py +0 -0
  321. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_start_session_workspace_default.py +0 -0
  322. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_store_v4_migration.py +0 -0
  323. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_sync_dashboard.py +0 -0
  324. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_sync_e2ee.py +0 -0
  325. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_update.py +0 -0
  326. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_update_check.py +0 -0
  327. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_user_model.py +0 -0
  328. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_v1_auto_migrate.py +0 -0
  329. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_v1_hardening.py +0 -0
  330. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_v1_licensing.py +0 -0
  331. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_vector_numpy.py +0 -0
  332. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_vector_sqlitevec_backend.py +0 -0
  333. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_workspace_isolation.py +0 -0
  334. {engraphis-1.2.2 → engraphis-1.2.5}/tests/test_workspace_ops.py +0 -0
@@ -255,6 +255,10 @@ ENGRAPHIS_LLM_API_KEY=sk-your-key-here
255
255
  # ENGRAPHIS_CHUNK_TOKENS=512
256
256
  # ENGRAPHIS_CHUNK_MAX=2048
257
257
  # ENGRAPHIS_CHUNK_OVERLAP=64
258
+ # Optional reader-tokenizer parity for chunk sizes (requires transformers).
259
+ # Pin the revision when the resulting memories support reproducible evidence.
260
+ # ENGRAPHIS_CHUNK_TOKENIZER_MODEL=Qwen/Qwen3.5-9B
261
+ # ENGRAPHIS_CHUNK_TOKENIZER_REVISION=<immutable model commit>
258
262
  # ENGRAPHIS_LOOP_INTERVAL=300
259
263
  # ENGRAPHIS_LOOP_TOP_K=10
260
264
  # ENGRAPHIS_RERANK_MODEL=cross-encoder/ms-marco-MiniLM-L-6-v2
@@ -0,0 +1,291 @@
1
+ # Benchmarks
2
+
3
+ This file is the honest status of what Engraphis measures today, how to reproduce it, and what
4
+ it does **not** yet claim. It exists because the README linked a `BENCHMARKS.md` that had never
5
+ been written; when this and the code disagree, the code wins (CLAUDE.md).
6
+
7
+ ## What we measure today (all offline, no API key)
8
+
9
+ Engraphis's eval harness scores **retrieval**, not end-to-end QA. That distinction is deliberate
10
+ and stated everywhere the numbers appear (`eval/external.py`).
11
+
12
+ - **Correctness gate**: `eval/harness.py` over `eval/datasets/sample.jsonl` and
13
+ `codemem.jsonl` (conflict resolution) and `graph_multihop.jsonl` (multi-hop graph recall).
14
+ Runs on the deterministic embedder, so it is a plumbing/regression floor, not a public
15
+ performance claim. This is the gate CI enforces.
16
+ - **Ablation**: `eval/ablation.py`: vector-only vs. 1-hop graph vs. Personalized-PageRank arm,
17
+ to show the graph arm actually earns its place.
18
+ - **External benchmarks**: `eval/external.py` loads **LoCoMo** and **LongMemEval** and pushes
19
+ them through the *real* `MemoryEngine` write path (conflict resolution + evolution) and hybrid
20
+ recall with a real sentence-transformers embedder. It reports `recall_at_k` / `hit_at_k` /
21
+ `answer_token_recall`: i.e. *did the evidence come back*, not *did an LLM answer correctly*.
22
+ It retains source categories and abstention/no-evidence questions as explicit exclusions from
23
+ retrieval-only aggregates rather than silently dropping them. `eval.longmemeval_v2` is a local,
24
+ text-only adapter for the official LongMemEval-V2 `insert(trajectory)` / `query(query,
25
+ query_image=None)` memory interface; it does not download data or call a model.
26
+ - **Grounded**: `eval/grounded.py`: answerable → cite, off-topic → abstain.
27
+ - **Chunking (quality per token)**: `eval/chunking_eval.py` over `eval/datasets/longdoc.jsonl`
28
+ ingests a multi-topic corpus twice: once as one memory per document (`whole`) and once with
29
+ sub-file `ChunkingExtractor` (`chunked`), then queries both through the real recall pipeline. This is
30
+ the first cut of the context-reduction metric (item 3 below). On the deterministic embedder:
31
+ **recall@5 1.000 for both, at ~73% fewer context tokens (809 → 219) and ~4× smaller
32
+ tokens-to-evidence (162 → 42).** Pass `--embed-model sentence-transformers/all-MiniLM-L6-v2`
33
+ for a real retrieval number (recall should then favour chunked on larger corpora, not just
34
+ tie).
35
+ - **Full-pipeline latency + quality**: `eval/performance.py` times the shipped semantic +
36
+ lexical + graph + fusion + scoring + rerank + packing path after warmup, with reinforcement
37
+ disabled so repeated measurements do not mutate their corpus. It reports p50/p95/p99 latency,
38
+ retrieval quality, and packed context tokens in one JSON-safe schema. `--filler-memories`
39
+ provides deterministic corpus scaling, and every report records the runtime, architecture,
40
+ embedder, vector backend, corpus size, warmups, and iteration count. `--candidate-k` and
41
+ `--retrieval-profile` make adaptive-depth/routing experiments executable instead of changing
42
+ production defaults from an unmeasured hunch.
43
+ - **Workload context economy**: `eval/context_economy.py` compares three executable strategies
44
+ across every question in a workload: uncapped full-history replay, a contiguous recency window
45
+ at the same hard budget, and shipped Engraphis hybrid recall + packing. It reports evidence and
46
+ answer-token quality, cumulative reader-context tokens, a conservative total that charges one
47
+ complete source-token pass to indexing, and the query-count break-even point. The default is
48
+ deterministic/offline; `--embed-model` enables a real retrieval model, while
49
+ `--format locomo|longmemeval` reuses the established external loaders.
50
+
51
+ The workload benchmark is also allowed to say “this workload is too small for a memory layer.”
52
+ On the 44-memory / 26-question CodeMem regression fixture, every case already fits inside a
53
+ 64-token recency window. Full-history and recency therefore use the same 1,180 cumulative reader
54
+ tokens at perfect evidence/answer-token quality, while Engraphis uses 1,375–1,377 reader tokens
55
+ plus a conservative 631-token indexing pass. That is an honest no-break-even boundary result:
56
+ the benefit being measured begins when history is long or reused enough to outweigh retrieval
57
+ framing and indexing.
58
+
59
+ The complementary real-model LoCoMo workload diagnostic covers 10 conversations and 1,986
60
+ questions with `all-MiniLM-L6-v2`, `k=10`, a 512-token reader budget, and conflict resolution
61
+ disabled. Engraphis used **891,857** cumulative reader-context tokens versus **49,915,394** for
62
+ uncapped full history, **98.2133% lower**. Charging one complete 246,539-token corpus pass to
63
+ indexing produces a conservative Engraphis total of **1,138,396**, still **97.7193% lower**, with
64
+ a calculated break-even at query 10. The quality tradeoff is explicit:
65
+
66
+ | LoCoMo workload method | Retrieval recall | Hit rate | Answer-token recall | Mean reader context |
67
+ |---|---:|---:|---:|---:|
68
+ | Engraphis hybrid recall | **0.600457** | **0.657417** | **0.679614** | **449.07** tokens |
69
+ | Same-budget recency window | 0.011289 | 0.012614 | 0.339941 | 487.87 tokens |
70
+ | Uncapped full history | 0.996997 | 0.997477 | 0.917247 | 25,133.63 tokens |
71
+
72
+ This diagnostic supports a precise statement: Engraphis recovered much more useful evidence than
73
+ a same-budget recency window while using a small fraction of full-history context. It does not
74
+ support “same quality as full history,” provider-billing, or end-to-end answer-accuracy claims.
75
+ The embedding model revision was not pinned in that run, so rerun it with an immutable revision
76
+ before treating the numbers as canonical release evidence.
77
+
78
+ ### Reproduce
79
+
80
+ ```bash
81
+ # Correctness gate (deterministic, no download)
82
+ python -m pytest tests/ -q
83
+ python -m eval.harness --dataset eval/datasets/sample.jsonl --k 5
84
+ python -m eval.harness --dataset eval/datasets/codemem.jsonl --k 5
85
+ python -m eval.harness --dataset eval/datasets/graph_multihop.jsonl --k 5
86
+ python -m eval.ablation
87
+ python -m eval.performance --dataset eval/datasets/codemem.jsonl --k 5 --iterations 10
88
+ python -m eval.performance --dataset eval/datasets/codemem.jsonl --k 5 \
89
+ --candidate-k 25 --candidate-depth adaptive --retrieval-profile auto --iterations 10
90
+ python -m eval.context_economy --dataset eval/datasets/codemem.jsonl \
91
+ --token-budget 512 --k 5
92
+ python -m eval.performance --dataset eval/datasets/codemem.jsonl --k 5 \
93
+ --iterations 5 --filler-memories 1000
94
+ # Canonical latency/resource protocol: requires >=1,000 queries and five processes.
95
+ python -m eval.performance --dataset fixed-1000-plus.jsonl --acceptance-matrix --processes 5
96
+
97
+ # Real retrieval numbers (downloads all-MiniLM-L6-v2)
98
+ python -m eval.external --dataset longmemeval_s.json --format longmemeval --k 10
99
+ python -m eval.external --dataset locomo10.json --format locomo --k 10
100
+ python -m eval.context_economy --dataset locomo10.json --format locomo \
101
+ --embed-model sentence-transformers/all-MiniLM-L6-v2 --token-budget 512 --k 10 --no-resolve
102
+ ```
103
+
104
+ ## What we do NOT yet claim
105
+
106
+ - **No end-to-end QA accuracy.** Official LoCoMo / LongMemEval QA scores depend on an answering model and evaluator. Engraphis isolates retrieval and does not present that result as end-to-end answer accuracy.
107
+ - **No hosted-service latency comparison.** The in-repo p50/p95/p99 benchmark covers the local
108
+ reference pipeline and records its environment; unlike environments are not compared.
109
+ - **No neutral third-party ranking.** We have not run an external eval platform.
110
+ - **No provider bill estimate.** Context-economy counts reader evidence under its named counter.
111
+ It excludes system/tool prompts, questions, completions, prompt caching, provider pricing,
112
+ compute, and storage. Its indexing-inclusive total is a conservative text-volume proxy.
113
+
114
+ Every publishable run should emit the `engraphis-benchmark/v2` envelope: dataset/config hashes,
115
+ per-question records, explicit exclusions, fixed-budget context curves, and deterministic
116
+ stratified or paired bootstrap confidence intervals. Every run names its token counter.
117
+ Noncanonical offline fixtures may identify a deterministic estimate; canonical public evidence
118
+ requires the exact pinned reader tokenizer and immutable model revision. The lightweight CI
119
+ fixtures validate that machinery; they are not a claim about external benchmark performance.
120
+
121
+ The benchmark context metric reads strict recall usage fields rather than inferring prompt size:
122
+ `budget_tokens`, `context_tokens`, `source_tokens`, `saved_tokens`, `savings_ratio`,
123
+ `packed_count`, `omitted_count`, and `token_counter`. Use `engraphis_recall_context` for a
124
+ hard-budget prompt packet; legacy `engraphis_recall` remains available in full or compact response
125
+ mode for compatibility.
126
+
127
+ ### Canonical public artifacts
128
+
129
+ Use `python -m eval.benchmark --input report.json --output artifacts/run.json` to validate a
130
+ report and write sorted, immutable JSON plus `run.json.sha256`. The command permits an identical
131
+ retry but refuses to replace a different artifact at the same path. For an official
132
+ LongMemEval-V2 run, add `--canonical`: this requires a profile with an exact benchmark repository
133
+ revision, dataset revision, reader model revision, and embedding model revision. The checked-in
134
+ profile pins immutable upstream commits; replacing any revision with a mutable tag fails
135
+ validation. Canonical profiles label the baseline (`no_retrieval`, `lexical_only`, `dense_only`,
136
+ `dense_lexical_rrf`, `full_hybrid`, `full_history`, `no_graph`, `no_reranker`,
137
+ `no_temporal_resolution`, or `whole_document`) and declare the required fixed context-budget
138
+ matrix: 256, 512, 1024, 2048, and 4096 tokens. Canonical in-repo reports rerun every question at
139
+ all five budgets and validate each aggregate against its per-question evidence. The checked-in
140
+ LongMemEval-V2 memory-module configuration sets the official adapter's operating point to 1,024
141
+ tokens; that single official point must not be presented as a five-point curve.
142
+
143
+ `eval.external --canonical` refuses `--limit` and rejects a normalized output that omitted source
144
+ cases. Retrieval-only abstention/no-evidence records remain visible in the artifact's
145
+ `exclusions`; they are not counted as evidence-retrieval scores.
146
+
147
+ Official LongMemEval-V2 output can be converted into a public-safe QA artifact with
148
+ `python -m eval.longmemeval_v2_evidence`. The exporter keeps the official QA score, fixed-reader
149
+ context token count, latency, model revisions, source digests, repository state, and artifact
150
+ checksum. It removes raw questions, answers, prompts, reader output, and retrieved context before
151
+ the artifact can be written. See [`eval/EVIDENCE.md`](eval/EVIDENCE.md) for the exact command.
152
+
153
+ ### LongMemEval-V2 memory-module adapter
154
+
155
+ `eval.longmemeval_v2.EngraphisLongMemEvalV2Memory` follows the official
156
+ `memory_modules.memory.Memory` interface at LongMemEval-V2 commit
157
+ `6f020ac2fc3275e46c706d3406e02c3ed79b7be2`. When imported in that environment, its
158
+ `@register_memory` decorator registers `memory_type="engraphis"`; use the checked-in
159
+ [`eval/configs/longmemeval_v2_engraphis.json`](eval/configs/longmemeval_v2_engraphis.json)
160
+ with the official harness. The config pins `Qwen/Qwen3-Embedding-8B` to revision
161
+ `1d8ad4ca9b3dd8059ad90a75d4983776a23d44af`; mutable embedding revisions are rejected, and a
162
+ canonical adapter run fails instead of relabeling the deterministic offline fallback as Qwen.
163
+ Run `python -m eval.run_longmemeval_v2` with the official harness arguments and the pinned
164
+ checkout on `PYTHONPATH`. This wrapper performs the upstream registry import in the required order
165
+ before delegating to `evaluation.harness`; a direct upstream invocation must otherwise import
166
+ `eval.longmemeval_v2` before calling `build_memory`.
167
+
168
+ The checked-in configuration is canonical only when the adapter resolves the pinned Qwen reader
169
+ processor at `c202236235762e1c871ad0ccb60c8ee5ba337b9a`. The wrapper also forces the audited
170
+ official harness's otherwise-unpinned `AutoProcessor` call to that same revision. It refuses to
171
+ start if the optional processor dependency or immutable revision is unavailable; the local regex
172
+ counter is never silently relabeled as a reader budget. The recorded budget counts each returned
173
+ context item's content with that reader tokenizer (without prompt framing or inter-item
174
+ separators), so it is a hard **evidence-item content** budget, not a claim about total chat-prompt
175
+ tokens. Packed sources are returned as separate context items, preserving the largest fitting
176
+ evidence prefix instead of dropping one oversized monolithic item. The adapter does not download
177
+ benchmark data or call the reader/evaluator; the official harness owns those steps.
178
+
179
+ ## External evidence status and remaining executions
180
+
181
+ 1. **Run the official LongMemEval-V2 reader and evaluator.** The adapter, pinned runner, and
182
+ redacted evidence exporter are implemented. The exact upstream commit boots in an isolated
183
+ Python 3.11 environment and the wrapper reaches the official harness CLI. Dataset revision
184
+ `f152293e235517d504809563c833d7190b8c713b` publishes 7,120,369,667 bytes before the pinned
185
+ Qwen reader and embedding model assets. A full official run therefore still requires those
186
+ resources, sufficient compute, and evaluator configuration; no canonical QA score is claimed
187
+ until that run completes.
188
+ 2. **Publish production-backend latency.** Run `eval/performance.py` with the real embedder and
189
+ sqlite-vec/backend configuration on a fixed machine class and corpus scale.
190
+ 3. **Run the fixed-budget curve on the complete official datasets.** The v2 harness now measures
191
+ every question at 256, 512, 1,024, 2,048, and 4,096 evidence tokens and validates the
192
+ per-question records, aggregates, and pinned reader-tokenizer identity. Publish the curve only
193
+ after complete official runs produce immutable artifacts for every point.
194
+ 4. **Run an external evaluation platform** once (1)–(3) exist.
195
+
196
+ Do not make all evidence lanes variants of explicit factual recall. Executable offline adapters
197
+ now cover:
198
+
199
+ - [MemoryAgentBench](https://github.com/HUST-AI-HYZ/MemoryAgentBench): incremental multi-turn
200
+ learning, long-range understanding, and conflict/consolidation inputs.
201
+ - [LoCoMo-Plus](https://github.com/xjtuleeyf/Locomo-Plus): an old implicit constraint must affect
202
+ a later response even when the later cue does not restate the remembered fact.
203
+ - [Mem2ActBench](https://github.com/Cantaloupe-M/Mem2ActBench): memory must select a tool and
204
+ ground its arguments, not merely return a passage. The current adapter measures retrieval and
205
+ expected tool-argument context coverage, not generated tool-call success.
206
+
207
+ ```bash
208
+ python -m eval.agent_benchmarks --dataset memoryagentbench.json \
209
+ --format memoryagentbench
210
+ python -m eval.agent_benchmarks --dataset locomo_plus.json \
211
+ --format locomo_plus
212
+ python -m eval.agent_benchmarks --dataset qa_dataset.jsonl \
213
+ --conversations toolmem_conversation.jsonl --format mem2actbench \
214
+ --artifact artifacts/mem2actbench.json
215
+ ```
216
+
217
+ Use `--artifact` on any of these commands to write a redacted, immutable evidence envelope plus
218
+ an adjacent SHA256 file. The ordinary console/`--json` report is private run material and may
219
+ contain source questions for debugging.
220
+
221
+ ### Upstream-data diagnostic baseline (2026-07-30)
222
+
223
+ These runs use the dependency-free deterministic embedder on upstream data. They validate the
224
+ adapters and expose product gaps; they are noncanonical diagnostics, not leaderboard or marketing
225
+ claims. The artifact validator accepted every completed envelope.
226
+
227
+ | Upstream source | Executed scope | Result and boundary |
228
+ |---|---|---|
229
+ | LoCoMo-Plus commit `059f4e3d38f7f1f96765e8e2cb7de3097551bffb` | All 401 Cognitive cases, 40,270 source memories | Recall@10 **0.1259**, hit@10 **0.1272**, MRR@10 **0.0744**, answer-token context coverage **0.5095**. This is cue-evidence retrieval, not answer-judge accuracy. The low retrieval score is useful negative evidence: implicit-constraint recall remains a real product gap. |
230
+ | MemoryAgentBench commit `455306dcabc3842526eb83cd4e225e5d486c5c5d`, official Hugging Face `Accurate_Retrieval` first row | 100 questions | Recall@10 **0.5100**, hit@10 **0.8600**, answer-token context coverage **0.8500**. Gold evidence was derived only where an accepted answer occurred in a source chunk. |
231
+ | The same source, `Conflict_Resolution` first row | 100 questions | Recall@10 **0.4600**, hit@10 **0.6400**, answer-token context coverage **0.6800**. This plain-context export measures retrieval, not structured temporal invalidation. |
232
+ | The same source, `Long_Range_Understanding` first row | 1 question | Answer-token context coverage **0.2658**. The export supplied no evidence IDs and no accepted answer occurred verbatim in a source chunk, so retrieval was deliberately left unscored rather than reported as a false perfect score. |
233
+ | The same source, `Test_Time_Learning` first row | One 5.88 MB context | The no-resolution ingest did not complete within a five-minute local smoke ceiling. This is a measured large-ingest throughput gap, not a failed quality score; batch embedding and transaction work should precede a complete split run. |
234
+ | Mem2ActBench upstream smoke | 2 public rows | Recall@10, hit@10, MRR@10, and NDCG@10 **1.0000**; expected tool-call JSON token coverage **0.5714**. This is retrieval/context coverage, not generated action success. |
235
+
236
+ The MemoryAgentBench loader accepts both its aligned public JSON export and the Hugging Face
237
+ dataset-server `rows[].row` envelope. Rows without gold evidence remain useful for answer-token
238
+ coverage, but are excluded from retrieval aggregates and counted separately as
239
+ `retrieval_scored_questions`.
240
+
241
+ For paired code-agent runs, execute the same tasks with the same model, tools, machine, and
242
+ deterministic success oracle under `full_history` and `engraphis`. Then analyze the content-free
243
+ run records with:
244
+
245
+ ```bash
246
+ python -m eval.code_agent_ab --full-history full-history.jsonl \
247
+ --engraphis engraphis.jsonl --output paired-report.json
248
+ ```
249
+
250
+ The analyzer rejects unmatched task IDs and different success oracles, then reports paired
251
+ bootstrap intervals for task success, input/output/tool tokens, retries, latency, and optional
252
+ cost. Its aggregate output does not echo task IDs or oracle commands. It does not launch an agent
253
+ or invent a task-success oracle.
254
+
255
+ ## Optimization experiments to run before changing defaults
256
+
257
+ 1. **Budget-aware packing**: compare full source, safe summary, sentence-aligned safe summary
258
+ excerpt, and raw-source excerpt at fixed budgets. Gate on support/answer retention and
259
+ qualifier preservation, not token count alone.
260
+ 2. **Adaptive retrieval work**: `--candidate-depth adaptive` is now an opt-in performance
261
+ experiment. It keeps wider graph/code pools and reduces routine lexical/balanced pools while
262
+ reporting the requested and actual depth. Sample and CodeMem kept every offline quality metric
263
+ at 1.0 with balanced depth reduced from 50 to 15; CodeMem plus 1,000 fillers reduced local
264
+ median recall latency from 20.666 ms to 18.991 ms in a 260-recall comparison, an 8.1%
265
+ reduction. These are machine-specific regression results, not production latency claims. Keep
266
+ the default fixed until complete external categories meet predeclared quality margins.
267
+ 3. **Packing-pressure consolidation**: prioritize memory families that are frequently recalled,
268
+ repeatedly omitted, or costly per useful token. Count write/index/storage cost as well as later
269
+ reader-context savings.
270
+ 4. **Tokenizer-aware ingestion**: implemented behind the chunk extractor. The dependency-free
271
+ default remains `engraphis.chars4.v1`; an explicitly configured Hugging Face reader tokenizer
272
+ enforces prose chunk and overlap budgets and records its identity in chunk metadata. Continue
273
+ measuring tokens-to-evidence, recall, and storage/index growth together before recommending a
274
+ model-specific default.
275
+ 5. **Bulk ingestion**: add batch embedding plus a transaction-aware vector upsert path, then rerun
276
+ the 5.88 MB MemoryAgentBench Test-Time Learning row. Gate this on identical stored-memory,
277
+ provenance, graph-link, and temporal-resolution outcomes, not throughput alone.
278
+ 6. **Scoped caches**: benchmark query embeddings and repeat-recall results keyed by workspace,
279
+ repo, time anchors, profile, and corpus version. Test invalidation correctness before claiming
280
+ latency gains.
281
+ 7. **Privacy-safe real usage**: use `engraphis_context_savings` to let each workspace inspect
282
+ aggregate source/context/saved tokens already present in content-free receipts. Keep unlike
283
+ token counters separate and require a valid receipt chain before treating totals as auditable.
284
+
285
+ ## Evaluation question
286
+
287
+ The predeclared question is whether the full vector + lexical/BM25 + sparse PPR graph + calibrated
288
+ rerank pipeline, bi-temporal resolution, and grounded abstention produce higher evidence recall
289
+ per injected token than the registered baselines. The answer must come from a complete,
290
+ machine-readable artifact with paired confidence intervals; otherwise the release reports
291
+ “no demonstrated improvement.”
@@ -3,6 +3,45 @@
3
3
  All notable changes to Engraphis are documented here. Format loosely follows
4
4
  [Keep a Changelog](https://keepachangelog.com/); versions use SemVer.
5
5
 
6
+ ## [Unreleased]
7
+
8
+ ## [1.2.5] - 2026-07-31
9
+
10
+ ### Added
11
+
12
+ - `engraphis_context_savings` aggregates validated, content-free recall receipts by workspace,
13
+ repo, operation, and token-counter identity. The same read-only view is available through the
14
+ service, Inspector, v2/read-only APIs, and dashboard receipt panel.
15
+ - Recall supports an explicit adaptive candidate-depth experiment while retaining the historical
16
+ fixed depth by default. Performance reports record requested and actual candidate depths.
17
+ - Chunk ingestion can enforce budgets with an injected or explicitly configured Hugging Face
18
+ tokenizer and records the counter identity, target, and overlap in each chunk's metadata.
19
+ - Offline adapters now cover MemoryAgentBench, LoCoMo-Plus, and Mem2ActBench. A paired code-agent
20
+ analyzer compares full-history and Engraphis runs using identical tasks and success oracles.
21
+ - Public benchmark evidence can carry source hashes, repository state, environment and model
22
+ provenance, secret-redacted commands, content digests, and adjacent immutable SHA-256 files.
23
+
24
+ ### Changed
25
+
26
+ - Context-economy evaluation now compares uncapped full history, a same-budget recency window,
27
+ and shipped hybrid recall while charging an explicit one-time indexing token proxy.
28
+ - Official LongMemEval-V2 output has a dedicated redacted evidence exporter that retains the
29
+ official QA/token/latency measures without publishing prompts, answers, model output, or
30
+ retrieved context.
31
+ - Folder-sync dry runs no longer create a remote directory or persist a local device identity.
32
+
33
+ ### Fixed
34
+
35
+ - Sync rejects malformed scope/repo combinations and every peer-driven visibility change for an
36
+ existing memory, including malformed legacy rows. Scope promotion or repair remains a local,
37
+ explicit governance operation.
38
+ - Workspace consolidation excludes session-private memories and partitions digests and entity
39
+ profiles by their exact visibility owner, preventing cross-repo or cross-scope summaries.
40
+ - Tokenizer-aware chunk overlap can no longer exceed the configured prose budget or emit a
41
+ duplicate overlap-only record before an oversized paragraph. Invalid token counters fail
42
+ closed instead of silently producing mis-sized chunks.
43
+ - The new evidence guide is included in wheel and source distributions.
44
+
6
45
  ## [1.2.2] - 2026-07-30
7
46
 
8
47
  ### Fixed
@@ -15,6 +15,7 @@ include docker-entrypoint.sh Dockerfile docker-compose.yml
15
15
  include railway.json
16
16
  recursive-include eval *.py
17
17
  include eval/BASELINES.md
18
+ include eval/EVIDENCE.md
18
19
  recursive-include eval/configs *.json
19
20
  recursive-include eval/datasets *.jsonl
20
21
  recursive-include tests *.py