memleaf 0.2.29__tar.gz → 0.2.31__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 (160) hide show
  1. {memleaf-0.2.29 → memleaf-0.2.31}/CHANGELOG.md +14 -0
  2. {memleaf-0.2.29/src/memleaf.egg-info → memleaf-0.2.31}/PKG-INFO +4 -4
  3. {memleaf-0.2.29 → memleaf-0.2.31}/README.en.md +3 -3
  4. {memleaf-0.2.29 → memleaf-0.2.31}/README.md +3 -3
  5. memleaf-0.2.31/docs/capture-budget-design.md +74 -0
  6. {memleaf-0.2.29 → memleaf-0.2.31}/docs/evidence-retention.md +11 -3
  7. memleaf-0.2.31/docs/gate-evidence-boundary.md +99 -0
  8. {memleaf-0.2.29 → memleaf-0.2.31}/docs/general-processing.md +40 -12
  9. {memleaf-0.2.29 → memleaf-0.2.31}/pyproject.toml +1 -1
  10. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/__init__.py +1 -1
  11. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/admission.py +109 -31
  12. memleaf-0.2.31/src/memleaf/evidence_budget.py +294 -0
  13. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/hermes_provider/__init__.py +28 -19
  14. memleaf-0.2.31/src/memleaf/hermes_provider/evidence_budget.py +294 -0
  15. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/hermes_provider/plugin.yaml +1 -1
  16. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/host_runtime.py +18 -3
  17. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/installer.py +1 -1
  18. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/mcp_server.py +1 -1
  19. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/memory_planner.py +30 -10
  20. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/model_execution.py +5 -1
  21. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/process_common.py +8 -1
  22. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/process_journal.py +4 -1
  23. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/prompts.py +7 -27
  24. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/provenance.py +61 -53
  25. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/validation.py +34 -7
  26. {memleaf-0.2.29 → memleaf-0.2.31/src/memleaf.egg-info}/PKG-INFO +4 -4
  27. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf.egg-info/SOURCES.txt +5 -0
  28. memleaf-0.2.31/tests/test_evidence_budget.py +381 -0
  29. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_evidence_retention_policy.py +2 -2
  30. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_general_evidence_admission.py +113 -1
  31. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_general_tool_provenance.py +2 -2
  32. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_maintenance_v2.py +1 -4
  33. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_processing_contract_v026.py +6 -6
  34. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_pypi_install.py +1 -0
  35. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_stage_b1.py +6 -8
  36. {memleaf-0.2.29 → memleaf-0.2.31}/IMPLEMENTATION_PLAN.md +0 -0
  37. {memleaf-0.2.29 → memleaf-0.2.31}/LICENSE +0 -0
  38. {memleaf-0.2.29 → memleaf-0.2.31}/MANIFEST.in +0 -0
  39. {memleaf-0.2.29 → memleaf-0.2.31}/RELEASE_CHECKLIST.md +0 -0
  40. {memleaf-0.2.29 → memleaf-0.2.31}/docs/config-migrations.md +0 -0
  41. {memleaf-0.2.29 → memleaf-0.2.31}/docs/core-refactor.md +0 -0
  42. {memleaf-0.2.29 → memleaf-0.2.31}/docs/hermes-mcp-runtime.md +0 -0
  43. {memleaf-0.2.29 → memleaf-0.2.31}/docs/performance.md +0 -0
  44. {memleaf-0.2.29 → memleaf-0.2.31}/docs/v0.2.26-processing-status.md +0 -0
  45. {memleaf-0.2.29 → memleaf-0.2.31}/examples/README.md +0 -0
  46. {memleaf-0.2.29 → memleaf-0.2.31}/examples/basic_usage.py +0 -0
  47. {memleaf-0.2.29 → memleaf-0.2.31}/examples/live_processing_acceptance.py +0 -0
  48. {memleaf-0.2.29 → memleaf-0.2.31}/examples/mcp_stdio.ndjson +0 -0
  49. {memleaf-0.2.29 → memleaf-0.2.31}/install.ps1 +0 -0
  50. {memleaf-0.2.29 → memleaf-0.2.31}/install.sh +0 -0
  51. {memleaf-0.2.29 → memleaf-0.2.31}/setup.cfg +0 -0
  52. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/__main__.py +0 -0
  53. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/adapters/__init__.py +0 -0
  54. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/adapters/antigravity.py +0 -0
  55. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/adapters/base.py +0 -0
  56. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/adapters/codex.py +0 -0
  57. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/adapters/hermes.py +0 -0
  58. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/budget.py +0 -0
  59. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/capture.py +0 -0
  60. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/cli.py +0 -0
  61. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/compaction.py +0 -0
  62. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/config.py +0 -0
  63. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/credentials.py +0 -0
  64. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/evidence_policy.py +0 -0
  65. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/frontmatter.py +0 -0
  66. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/hermes_provider/README.md +0 -0
  67. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/hermes_runtime.py +0 -0
  68. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/host_events.py +0 -0
  69. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/inbox.py +0 -0
  70. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/index.py +0 -0
  71. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/inspection.py +0 -0
  72. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/llm/__init__.py +0 -0
  73. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/llm/base.py +0 -0
  74. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/llm/claude_compatible.py +0 -0
  75. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/llm/gemini.py +0 -0
  76. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/llm/openai_compatible.py +0 -0
  77. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/llm/router.py +0 -0
  78. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/locking.py +0 -0
  79. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/memory_commit.py +0 -0
  80. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/memory_writer.py +0 -0
  81. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/model_discovery.py +0 -0
  82. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/models.py +0 -0
  83. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/native_index.py +0 -0
  84. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/native_registration.py +0 -0
  85. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/planning_context.py +0 -0
  86. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/process_owner.py +0 -0
  87. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/processing.py +0 -0
  88. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/recording_policy.py +0 -0
  89. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/redaction.py +0 -0
  90. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/retention.py +0 -0
  91. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/retrieval.py +0 -0
  92. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/retrieval_gate.py +0 -0
  93. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/scope_maintenance.py +0 -0
  94. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/scope_state.py +0 -0
  95. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/service.py +0 -0
  96. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/source_policy.py +0 -0
  97. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/state_layout.py +0 -0
  98. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/turn_audit.py +0 -0
  99. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/turn_plan.py +0 -0
  100. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/update_coordinator.py +0 -0
  101. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf/vault.py +0 -0
  102. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf.egg-info/dependency_links.txt +0 -0
  103. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf.egg-info/entry_points.txt +0 -0
  104. {memleaf-0.2.29 → memleaf-0.2.31}/src/memleaf.egg-info/top_level.txt +0 -0
  105. {memleaf-0.2.29 → memleaf-0.2.31}/tests/__init__.py +0 -0
  106. {memleaf-0.2.29 → memleaf-0.2.31}/tests/semantic_fixtures.py +0 -0
  107. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_admission_noise.py +0 -0
  108. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_codex_install.py +0 -0
  109. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_codex_native_cli.py +0 -0
  110. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_config_migrations_v028.py +0 -0
  111. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_context_budget.py +0 -0
  112. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_credential_safety.py +0 -0
  113. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_cross_host_acceptance.py +0 -0
  114. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_cross_turn_dedupe_regressions.py +0 -0
  115. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_email_actionable_coverage.py +0 -0
  116. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_extraction_quality_regressions.py +0 -0
  117. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_global_todo_acceptance.py +0 -0
  118. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_global_todo_query_no_write.py +0 -0
  119. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_global_todo_retrieval.py +0 -0
  120. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_hermes_native_registration.py +0 -0
  121. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_hermes_provider.py +0 -0
  122. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_hermes_runtime_install.py +0 -0
  123. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_hermes_stdio_transport.py +0 -0
  124. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_host_events.py +0 -0
  125. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_host_runtime_contract.py +0 -0
  126. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_inspection_state_v028.py +0 -0
  127. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_install.py +0 -0
  128. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_long_run_hygiene.py +0 -0
  129. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_model_discovery.py +0 -0
  130. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_model_owned_fields.py +0 -0
  131. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_phase2_model_decisions.py +0 -0
  132. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_process_owner_locking.py +0 -0
  133. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_retrieval_gate.py +0 -0
  134. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_retrieval_v2.py +0 -0
  135. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_session_lineage.py +0 -0
  136. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_shared_memory_refactor.py +0 -0
  137. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_source_neutral_todos_v028.py +0 -0
  138. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_stage_a.py +0 -0
  139. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_stage_b2a.py +0 -0
  140. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_stage_b2b.py +0 -0
  141. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_stage_b3a_commit.py +0 -0
  142. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_stage_b3a_contract.py +0 -0
  143. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_stage_b3b_native_context.py +0 -0
  144. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_stage_b3b_native_index.py +0 -0
  145. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_stage_b3b_scope.py +0 -0
  146. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_stage_b3c_retrieval.py +0 -0
  147. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_stage_b3d_scope_maintenance.py +0 -0
  148. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_stage_c1_mcp.py +0 -0
  149. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_stage_c2_init.py +0 -0
  150. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_stage_c3_packaging.py +0 -0
  151. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_state_layout_v028.py +0 -0
  152. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_todo_state_recovery.py +0 -0
  153. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_update_target_recovery.py +0 -0
  154. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_upgrade_preserves_vault.py +0 -0
  155. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_v023_scope_correction.py +0 -0
  156. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_v2_gate_limits.py +0 -0
  157. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_v2_host_flow.py +0 -0
  158. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_v2_mcp_flow.py +0 -0
  159. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_v2_nomatch_semantics.py +0 -0
  160. {memleaf-0.2.29 → memleaf-0.2.31}/tests/test_v2_search_gate_acceptance.py +0 -0
@@ -2,6 +2,20 @@
2
2
 
3
3
  All notable changes to memleaf are documented here.
4
4
 
5
+ ## 0.2.31 — 2026-09-07
6
+
7
+ - Unify Core and the copied Hermes provider on one idempotent UTF-8 evidence budget: at most 64 source records, 32 KiB per body, and 128 KiB of aggregate body text. Complete matched sources above the former 2,000-character/eight-record limits remain available within those bounds.
8
+ - Keep loss diagnostics bounded to 64 marker identities plus one aggregate marker. Per-record, aggregate, and marker overflow remains explicit incomplete evidence and cannot authorize a write or successful cleanup.
9
+ - Preserve metadata/off, attachment, redaction, and call-ID behavior, and consume metadata-mode pending evidence after a successful capture using the same effective policy on pending and inbox sides.
10
+ - Add provider-copy, capture-to-process, loss-defer, marker-capacity and lifecycle regressions. Deterministic tests do not claim real-model semantic quality, real-session replay, or customer acceptance.
11
+
12
+ ## 0.2.30 — 2026-09-07
13
+
14
+ - Add a physical evidence projection for the Gate: the complete local inventory remains available for provenance, replay and audit, while only user-origin units and complete external observations become bindable model evidence. Assistant synthesis, retrieved memory, incomplete observations and metadata-only records remain context or unresolved ledger state.
15
+ - Require one unified Gate response with `candidates`, `coverage` and `evidence_bindings`, including explicit per-unit coverage and bounded correction for missing physical units. Preserve legacy candidate-only compatibility when exact or validated bound support already accounts for a unit.
16
+ - Preserve the public `invalid_evidence` failure category while adding safe, allowlisted `evidence_check` diagnostics for distinguishable coverage, binding and span failures. Diagnostics do not retain raw model output or error text.
17
+ - Add regression coverage and documentation for the evidence boundary, metadata-only capture behavior and cleanup/watermark safety. This release does not claim reproduction or repair of any earlier real-model session.
18
+
5
19
  ## 0.2.29 — 2026-09-07
6
20
 
7
21
  - Clarify the source-neutral Gate contract for tool records retained as `metadata`: they are not evidence units, cannot be bound by metadata identifiers, and cannot authorize CREATE or UPDATE.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: memleaf
3
- Version: 0.2.29
3
+ Version: 0.2.31
4
4
  Summary: A local-first Markdown memory core for AI agents
5
5
  Author: memleaf contributors
6
6
  License-Expression: MIT
@@ -23,8 +23,8 @@ Dynamic: license-file
23
23
 
24
24
  [English](README.en.md) · [PyPI](https://pypi.org/project/memleaf/) · [GitHub](https://github.com/miffyblueboo/memleaf)
25
25
 
26
- > **版本:0.2.29。**
27
- > 核心库、Vault、stdio MCP Server、初始化 CLI、模型路由、提炼流程、受控检索协议和宿主适配器已经实现。本版补齐 metadata 工具证据的 Gate 覆盖协议,修复查询和助手复述误标 DEFERRED 的收口问题,同时保持 source-neutral 语义、Markdown 唯一事实源和无 SQLite 运行时依赖。真实模型语义效果仍需结合本地模型和代表性样本验收。
26
+ > **版本:0.2.31。**
27
+ > 核心库、Vault、stdio MCP Server、初始化 CLI、模型路由、提炼流程、受控检索协议和宿主适配器已经实现。本版统一 Core 与 Hermes Provider 的 UTF-8 证据留存预算:最多 64 条 source records、每条正文 32 KiB、正文总量 128 KiB,并保留有界 loss markers 与幂等规范化;同时将 metadata 模式下成功捕获的超限 pending 证据按相同有效策略消费。Gate 继续使用 physical evidence projection、`candidates`、`coverage`、`evidence_bindings` 和 allowlisted `evidence_check` 诊断,保持 source-neutral 语义、Markdown 唯一事实源和无 SQLite 运行时依赖。真实模型语义效果仍需结合本地模型和代表性样本验收。
28
28
  > **当前版本支持 Hermes 和 Codex。** Antigravity(反重力)不检测、不安装、不配置。
29
29
 
30
30
  ## 项目定位
@@ -490,7 +490,7 @@ MIT,见 [LICENSE](LICENSE)。
490
490
  *Your memories, in files you own.*
491
491
 
492
492
 
493
- ## 通用处理与只读验收(0.2.29)
493
+ ## 通用处理与只读验收(0.2.31)
494
494
 
495
495
  邮件、日历、工单、文件、浏览器与普通对话共用证据准入、覆盖检查和写入路径。
496
496
  自动摘要只能使用获准引用的原文;助手复述和旧记忆回读不能单独授权新增写入。
@@ -4,8 +4,8 @@
4
4
 
5
5
  [中文](README.md) · [PyPI](https://pypi.org/project/memleaf/) · [GitHub](https://github.com/miffyblueboo/memleaf)
6
6
 
7
- > **Version: 0.2.29.**
8
- > The core library, Vault, stdio MCP server, initialization CLI, model routing, memory extraction, controlled retrieval protocol, and host adapters are implemented. This release completes the metadata-only tool evidence Gate contract and prevents query or assistant restatement coverage from remaining DEFERRED, while preserving source-neutral semantics, Markdown as the sole source of truth, and zero SQLite runtime dependencies. Real-model semantics still require local acceptance with the selected model and representative inputs.
7
+ > **Version: 0.2.31.**
8
+ > The core library, Vault, stdio MCP server, initialization CLI, model routing, memory extraction, controlled retrieval protocol, and host adapters are implemented. This release unifies Core and the Hermes provider on an idempotent UTF-8 evidence budget: at most 64 source records, 32 KiB per body, and 128 KiB of aggregate body text, with bounded loss markers; metadata-mode pending evidence from an oversized observation is consumed after successful capture under the same effective policy. The Gate still uses the physical evidence projection, the `candidates`, `coverage`, and `evidence_bindings` contract, and allowlisted `evidence_check` diagnostics while preserving source-neutral semantics, Markdown as the sole source of truth, and zero SQLite runtime dependencies. Real-model semantics still require local acceptance with the selected model and representative inputs.
9
9
  > **The current release supports Hermes and Codex.** Antigravity is not detected, installed, or configured.
10
10
 
11
11
  ## Project scope
@@ -474,7 +474,7 @@ MIT; see [LICENSE](LICENSE).
474
474
  *Your memories, in files you own.*
475
475
 
476
476
 
477
- ## General processing and read-only inspection (0.2.29)
477
+ ## General processing and read-only inspection (0.2.31)
478
478
 
479
479
  Dialogue, calendars, tickets, files, web results and other tools share the evidence, coverage and write path.
480
480
  Models interpret semantics; Core validates physical provenance and exact original quotations.
@@ -4,8 +4,8 @@
4
4
 
5
5
  [English](README.en.md) · [PyPI](https://pypi.org/project/memleaf/) · [GitHub](https://github.com/miffyblueboo/memleaf)
6
6
 
7
- > **版本:0.2.29。**
8
- > 核心库、Vault、stdio MCP Server、初始化 CLI、模型路由、提炼流程、受控检索协议和宿主适配器已经实现。本版补齐 metadata 工具证据的 Gate 覆盖协议,修复查询和助手复述误标 DEFERRED 的收口问题,同时保持 source-neutral 语义、Markdown 唯一事实源和无 SQLite 运行时依赖。真实模型语义效果仍需结合本地模型和代表性样本验收。
7
+ > **版本:0.2.31。**
8
+ > 核心库、Vault、stdio MCP Server、初始化 CLI、模型路由、提炼流程、受控检索协议和宿主适配器已经实现。本版统一 Core 与 Hermes Provider 的 UTF-8 证据留存预算:最多 64 条 source records、每条正文 32 KiB、正文总量 128 KiB,并保留有界 loss markers 与幂等规范化;同时将 metadata 模式下成功捕获的超限 pending 证据按相同有效策略消费。Gate 继续使用 physical evidence projection、`candidates`、`coverage`、`evidence_bindings` 和 allowlisted `evidence_check` 诊断,保持 source-neutral 语义、Markdown 唯一事实源和无 SQLite 运行时依赖。真实模型语义效果仍需结合本地模型和代表性样本验收。
9
9
  > **当前版本支持 Hermes 和 Codex。** Antigravity(反重力)不检测、不安装、不配置。
10
10
 
11
11
  ## 项目定位
@@ -471,7 +471,7 @@ MIT,见 [LICENSE](LICENSE)。
471
471
  *Your memories, in files you own.*
472
472
 
473
473
 
474
- ## 通用处理与只读验收(0.2.29)
474
+ ## 通用处理与只读验收(0.2.31)
475
475
 
476
476
  邮件、日历、工单、文件、浏览器与普通对话共用证据准入、覆盖检查和写入路径。
477
477
  自动摘要只能使用获准引用的原文;助手复述和旧记忆回读不能单独授权新增写入。
@@ -0,0 +1,74 @@
1
+ # Tool evidence capture budget
2
+
3
+ ## Problem and ownership
4
+
5
+ Capture permissions and capture capacity are separate contracts. `metadata`
6
+ deliberately removes source bodies; `off` removes observations. Neither setting
7
+ can produce new external facts for extraction. Enabling `bounded` authorizes
8
+ bounded body retention, but does not reconstruct previously discarded data.
9
+
10
+ The previous implementation also applied independent eight-record and
11
+ 2,000-character limits in the Hermes adapter, provenance normalization and
12
+ pending-state processing. Early discovery and skill results could consume the
13
+ entire record allowance before later source results arrived. Larger plain-text
14
+ results were truncated before Core could account for their complete content.
15
+ This is an ingestion-capacity problem; changing Gate semantics cannot recover
16
+ those bytes.
17
+
18
+ ## Required implementation contract
19
+
20
+ - Keep one shared, deterministic budget implementation for Core and the copied
21
+ Hermes provider. The provider must continue to work without importing Core
22
+ from the host's Python environment.
23
+ - Bound record count, each body and aggregate body size. Publish the limits as
24
+ engineering capacity, not a guarantee of complete capture for arbitrary turns.
25
+ The implementation target is 64 source records, 32 KiB of UTF-8 text per body
26
+ and 128 KiB of total body text. Omission markers have a separate allowance of
27
+ 64 call identities and one aggregate marker. They do not consume source-record
28
+ capacity or count themselves as newly lost observations on a later normalization
29
+ pass. Marker bodies are fixed diagnostics, never retained source excerpts.
30
+ - Preserve complete, matched source results within those limits. Do not rank
31
+ business topics or tool names, infer facts from assistant text, split arbitrary
32
+ stdout into invented document records, or promote truncated prefixes to
33
+ complete observations.
34
+ - Normalize retained evidence idempotently. Cache, capture, inbox read and
35
+ planning must not each discard another part of an already bounded inventory.
36
+ - Keep explicit omission/incompleteness accounting when a limit is exceeded.
37
+ Policy-authorized but incomplete observations remain unresolved and cannot
38
+ authorize a write or successful source cleanup.
39
+ - Apply `metadata`, `off`, attachment exclusions and redaction before persistent
40
+ writes. A capacity increase must not silently change capture permission.
41
+ - Keep the existing Gate/Summarize semantic responsibility and Markdown storage
42
+ model. Larger source capacity is not a claim of successful model extraction.
43
+
44
+ ## Acceptance
45
+
46
+ Use synthetic host messages shaped like an ordinary discovery/read turn: early
47
+ tool discovery, skills and memory search followed by nine later results, with
48
+ individual bodies ranging from hundreds to tens of thousands of characters.
49
+ The old path loses all nine later results; the revised path must retain complete
50
+ results when the full input is within its declared capacity.
51
+
52
+ Verify the same evidence across adapter, pending cache, capture and inbox read;
53
+ then verify a supported later-source candidate can pass the actual processing
54
+ path in an isolated Vault. Check record/body/aggregate overflow separately,
55
+ including repeated reads, accurate loss accounting, no write from incomplete
56
+ evidence, and no cleanup of unresolved turns. Retain permission, redaction,
57
+ cross-turn isolation and standalone installation coverage.
58
+
59
+ Tests must use synthetic data and a deterministic backend. Live model semantics,
60
+ changes to a user's capture permission, installation and release are separate
61
+ operations with separately reported results.
62
+
63
+ ## Model capacity remains a separate limit
64
+
65
+ The capture limits bound retained source data, not the final prompt or model
66
+ token count. Evidence annotations, conversation context, retrieved context and
67
+ the output allowance also consume model capacity. The current `llm.context_window`
68
+ setting is not a pre-call tokenizer check. A source inventory within the capture
69
+ budget can still exceed a selected model's usable context.
70
+
71
+ Do not silently drop evidence to make that call succeed. Existing model-failure
72
+ handling must preserve the failed turn and prevent cleanup. Automatic batching
73
+ or model-specific token accounting needs its own design and is outside this
74
+ capture-budget change.
@@ -17,12 +17,20 @@ legacy boolean (false/absent -> metadata, true -> bounded). An explicit new mode
17
17
  wins over the legacy boolean. Invalid strings and non-boolean flags fail closed.
18
18
  Loading config does not rewrite it. Normal saves make the effective mode explicit.
19
19
 
20
- The inherited limits remain eight records, 2,000 characters per body, and 320 per
21
- metadata field. Oversized eligible evidence remains incomplete; its prefix is
22
- never promoted into a complete fact. Policy-excluded observations are marked
20
+ The shared capture budget allows 64 source records, 32 KiB of UTF-8 text per body,
21
+ 128 KiB of total body text, and 320 characters per metadata field. Loss markers
22
+ have a separate allowance of 64 call identities plus one aggregate marker, with
23
+ fixed diagnostic bodies. Reapplying normalization does not reduce an
24
+ already bounded inventory or count existing omissions again. Oversized eligible
25
+ evidence remains incomplete; its prefix is never promoted into a complete fact.
26
+ Policy-excluded observations are marked
23
27
  retention=metadata, have no content, and are not retried as missing evidence.
24
28
  No later relaxation recreates discarded original content.
25
29
 
30
+ These are source-retention limits, not a guarantee that every configured model
31
+ can process the resulting prompt. See [capture budget design](capture-budget-design.md)
32
+ for the ingestion boundary, model-capacity limitation and acceptance contract.
33
+
26
34
  Document/attachment bodies require include_attachments=true and bounded mode.
27
35
  HostRuntime and the standalone Hermes adapter classify structural file arguments
28
36
  using the same tested contract (path/file_path/file_id/attachment_id/file URI,
@@ -0,0 +1,99 @@
1
+ # Gate evidence boundary
2
+
3
+ ## Design decision
4
+
5
+ Keep Markdown as the permanent-memory source of truth, the shared Vault,
6
+ `_index/` / `_state/` separation, scope-directed retrieval, and the separate Gate
7
+ and Summarize stages. Do not repair extraction failures by accepting unverified
8
+ evidence or by adding business-specific classifiers.
9
+
10
+ The Gate owns semantic decisions. The host owns physical evidence authority and
11
+ accounting. A model must not be asked to re-decide a physical constraint the host
12
+ already knows, such as whether text was written by the assistant or whether an
13
+ external observation has retained source content.
14
+
15
+ ## Input and accounting responsibilities
16
+
17
+ Keep the complete evidence inventory for provenance, input digests, replay and
18
+ local audit. Project only physically admissible units to the model's evidence
19
+ list:
20
+
21
+ | Source | Model evidence | Local handling |
22
+ | --- | --- | --- |
23
+ | User text, including questions, examples and quotations | Yes | Model decides future value and coverage |
24
+ | Complete, matched external observation | Yes | Model decides future value and coverage |
25
+ | Assistant synthesis | No | Context only; no independent write authority |
26
+ | Retrieved memleaf/native memory | No | Context only; no new evidence |
27
+ | Missing, failed or incomplete external observation | No | Unresolved; retain the source turn |
28
+ | Intentionally metadata-only tool record | No | Honor capture policy; never fabricate source text |
29
+
30
+ Use the physical `can_support` boundary for this projection. `origin` and
31
+ `eligible` contain syntax hints and must not become semantic filters for user
32
+ text. A user can state a real fact inside a question or a code example; the Gate
33
+ must still see and evaluate that text. Conversely, an exact quote from user text
34
+ proves provenance, not the truth or future value of a proposed memory.
35
+
36
+ The Gate can retain user/assistant conversation context for pronouns and explicit
37
+ adoption of proposals. Context is not an additional source of bindable unit IDs.
38
+ Metadata call IDs, digests and tool names are not substitute source text.
39
+
40
+ ## One Gate contract
41
+
42
+ The documented response contains `candidates`, `coverage` and
43
+ `evidence_bindings`. Coverage accounts for every model-visible evidence unit,
44
+ including a decision that no candidate is warranted. An empty candidate list is
45
+ not, by itself, proof of complete coverage.
46
+
47
+ The three empty lists describe a complete response only when there are no
48
+ model-visible evidence units. With units present, no-admission still needs
49
+ explicit `NO_CHANGE` or `DEFERRED` accounting. Examples must obey the same rules
50
+ as the validator and must not preclassify the first real input as a worthy fact.
51
+
52
+ Legacy candidate-only responses use the same evidence checks. Exact support or
53
+ validated bindings account for the supported units; remaining units take the
54
+ bounded coverage-repair path. Missing accounting must not
55
+ silently become permission to clean the source turn. Unknown unit IDs,
56
+ contradictory coverage, invalid spans and unauthorized sources remain errors.
57
+
58
+ ## Diagnostics and recovery
59
+
60
+ Preserve the existing failure category, retry bound and watermark behavior.
61
+ Record a separate, allowlisted evidence-check identifier for the failing
62
+ constraint. Diagnostics must not contain raw model responses, message text,
63
+ credentials or arbitrary exception strings.
64
+
65
+ A failed Gate cannot advance the turn watermark or create a cleanup deadline.
66
+ A successful no-change decision can advance the watermark and start the normal
67
+ retention period. Incomplete physical observations remain deferred even if other
68
+ parts of the turn finish. Replaying an already completed operation must remain
69
+ idempotent.
70
+
71
+ ## Capture policy is a separate capability boundary
72
+
73
+ `metadata` intentionally excludes tool-result bodies from extraction. The host
74
+ having read a document does not mean the extraction model has its source text.
75
+ Do not change this policy implicitly, reconstruct removed bodies from assistant
76
+ prose, or re-read external systems merely to make a failed Gate pass.
77
+
78
+ `bounded` permits retained complete records; it does not promise complete
79
+ extraction from arbitrary bulk stdout. Record-count and body-size limits can
80
+ produce explicit omissions or partial observations. A large batch of results
81
+ inside one text blob is not equivalent to separately matched complete records.
82
+ That adapter/capture limitation must be reported independently of Gate success.
83
+
84
+ ## Verification
85
+
86
+ - A long assistant answer does not expand the model's evidence coverage list;
87
+ the full local audit inventory remains available.
88
+ - User questions, quotations and mixed question/assertion text remain in the
89
+ model projection. No local keyword rule decides their future value.
90
+ - Complete external facts can be admitted; assistant, retrieved, metadata and
91
+ incomplete observations cannot authorize independent writes.
92
+ - Missing coverage is corrected or retained as unresolved, not silently cleaned.
93
+ - Invalid unit IDs, duplicate coverage, invalid reasons, invalid spans and
94
+ binding/coverage conflicts produce safe distinguishable diagnostics.
95
+ - Failure, retry, watermark, cleanup eligibility and replay are verified together
96
+ in an isolated Vault without changing an existing user's Vault.
97
+ - Deterministic tests establish the protocol. Live synthetic tests establish
98
+ behavior only for those samples. A synthetic success does not identify the
99
+ cause of an earlier real-model failure; do not claim otherwise.
@@ -1,4 +1,4 @@
1
- # General processing reliability contract — 0.2.29
1
+ # General processing reliability contract — 0.2.30
2
2
 
3
3
  This is source-neutral processing, not a mail extractor. Dialogue, documents,
4
4
  calendars, issue trackers and terminal/tool observations use the same admission
@@ -27,6 +27,14 @@ quotation, in which case Core locates it without model character counting.
27
27
  Malformed/ambiguous references fail the contract. Matching a quote proves
28
28
  provenance, not semantic truth. This mechanism is not a universal NLP proof.
29
29
 
30
+ Core keeps the complete evidence inventory for audit, replay and input digests.
31
+ The Gate receives a bounded physical-source projection: all user-origin units
32
+ and complete current-turn external observations are included, while assistant
33
+ prose, retrieved memory and incomplete observations remain host-side context or
34
+ unresolved ledger entries. This is a provenance boundary, not a semantic
35
+ classification; query, example and quoted-document hints remain visible to the
36
+ Gate so it can judge them in context.
37
+
30
38
  Legacy candidate-only output has no n-gram or short-text authorization bypass.
31
39
  It must repeat a complete non-query source statement, or produce an explicit
32
40
  validated quotation via the bounded correction path. Automatic summarization
@@ -36,10 +44,24 @@ scope/type/target/date checks remain active.
36
44
 
37
45
  ## Coverage, limits and no-op behavior
38
46
 
39
- A Gate may map multiple facts in one evidence unit to several candidates, or
40
- one candidate to several units. Coverage is checked against real supplied IDs.
41
- One source-neutral correction can classify missing units; its candidates pass
42
- the same validator/deduplication path, never a post-Gate business-pattern writer.
47
+ A Gate response always has the top-level fields `candidates`, `coverage` and
48
+ `evidence_bindings`. When physical evidence units are supplied, `coverage` must
49
+ contain exactly one row for each supplied unit, including units the model marks
50
+ `NO_CHANGE` or `DEFERRED`; an omitted or empty coverage list is incomplete in
51
+ that case. With zero physical units, the complete no-admission object is
52
+ `{"candidates":[],"coverage":[],"evidence_bindings":[]}`. A Gate may map
53
+ multiple facts in one evidence unit to several candidates, or one candidate to
54
+ several units. Coverage is checked against real supplied IDs. One source-neutral
55
+ correction can classify missing units; its candidates pass the same
56
+ validator/deduplication path, never a post-Gate business-pattern writer.
57
+ Legacy candidate-only output remains compatible when a candidate already has
58
+ validated exact or bound physical support. Any remaining physical unit without
59
+ coverage or validated candidate support is sent through bounded correction and
60
+ remains unresolved; it cannot silently authorize inbox cleanup.
61
+ Evidence failures retain the public `invalid_evidence` category and may expose
62
+ an allowlisted `evidence_check` such as an unknown unit, duplicate row, invalid
63
+ span or incomplete coverage. Diagnostic state never stores raw model output or
64
+ error text.
43
65
  Tool records retained as `metadata` may remain visible in the event envelope for
44
66
  diagnostics, but they are not evidence units and cannot be bound by call ID,
45
67
  digest, tool name or other metadata. They therefore require no coverage row and
@@ -58,14 +80,20 @@ labels them NO_CHANGE. Incomplete turns retain their source instead of being
58
80
  cleaned after the usual grace period. Scope-filtered retries may revisit them;
59
81
  no endless automatic model retry or extra external tool call is introduced.
60
82
 
61
- Tool evidence is bounded to eight records with at most 2,000 content characters
62
- per captured result record and 320-character metadata fields, with redaction at
63
- Core capture. Large unambiguous top-level record collections retain complete
64
- records and enclosing context within that budget. Per-record provenance takes
65
- precedence over common source metadata. An overflow slot reports omitted
66
- records. Arbitrary large prose is not split into falsely complete facts;
83
+ Tool evidence uses one shared budget: 64 source records, at most 32 KiB of UTF-8
84
+ body text per record and 128 KiB of total body text, plus 320-character metadata
85
+ fields, with redaction at Core capture. Cache and inbox normalization are
86
+ idempotent under this budget. Large unambiguous top-level record collections
87
+ retain complete records and enclosing context within that budget. Per-record provenance takes
88
+ precedence over common source metadata. Separate loss markers report omitted
89
+ records, with at most 64 call identities plus one aggregate marker. These markers
90
+ have fixed diagnostic bodies and cannot supply external facts.
91
+ Arbitrary large prose is not split into falsely complete facts;
67
92
  unsupported/incomplete content needs a supported complete source excerpt or a
68
- later source input. Execution outcome and completeness are distinct.
93
+ later source input. Switching from `metadata` to `bounded` does not reconstruct
94
+ body content that was never captured; bounded retention can still produce an
95
+ unknown or overflow record when the adapter/result exceeds its capture limits.
96
+ Execution outcome and completeness are distinct.
69
97
 
70
98
  Codex pending tool data retains sixteen turns; bounded tombstones make evicted
71
99
  uncaptured evidence visible as incomplete. Older loss beyond 256 tombstones
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "memleaf"
7
- version = "0.2.29"
7
+ version = "0.2.31"
8
8
  description = "A local-first Markdown memory core for AI agents"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -1,6 +1,6 @@
1
1
  """Local-first Markdown memory core for AI agents."""
2
2
 
3
- __version__ = "0.2.29"
3
+ __version__ = "0.2.31"
4
4
 
5
5
  from .config import DEFAULT_CONFIG, default_config, load_config, save_config
6
6
  from .frontmatter import FrontmatterError, dump_frontmatter, dump_yaml, load_yaml, parse_frontmatter