memleaf 0.2.65__tar.gz → 0.2.67__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 (243) hide show
  1. {memleaf-0.2.65 → memleaf-0.2.67}/CHANGELOG.md +129 -0
  2. {memleaf-0.2.65 → memleaf-0.2.67}/MANIFEST.in +3 -0
  3. {memleaf-0.2.65/src/memleaf.egg-info → memleaf-0.2.67}/PKG-INFO +15 -4
  4. {memleaf-0.2.65 → memleaf-0.2.67}/README.en.md +12 -1
  5. {memleaf-0.2.65 → memleaf-0.2.67}/README.md +14 -3
  6. memleaf-0.2.67/docs/acceptance-evidence-guide.md +129 -0
  7. memleaf-0.2.67/docs/automatic-processing-route.md +214 -0
  8. memleaf-0.2.67/docs/body-compaction.md +114 -0
  9. memleaf-0.2.67/docs/candidate-reconciliation.md +88 -0
  10. memleaf-0.2.67/docs/development-closeout.md +90 -0
  11. memleaf-0.2.67/docs/explicit-memory-update.md +75 -0
  12. memleaf-0.2.67/docs/hermes-provider-compatibility.md +109 -0
  13. memleaf-0.2.67/docs/host-acceptance-runbook.md +152 -0
  14. memleaf-0.2.67/docs/immutable-release-assets.md +55 -0
  15. memleaf-0.2.67/docs/incremental-commit-contract.md +157 -0
  16. memleaf-0.2.67/docs/incremental-execution.md +187 -0
  17. memleaf-0.2.67/docs/incremental-native-comparison.md +145 -0
  18. memleaf-0.2.67/docs/incremental-partial-recovery.md +144 -0
  19. memleaf-0.2.67/docs/incremental-planner-preview.md +181 -0
  20. memleaf-0.2.67/docs/incremental-runtime-contract.md +74 -0
  21. memleaf-0.2.67/docs/incremental-scope-registration.md +137 -0
  22. memleaf-0.2.67/docs/incremental-selected-retention.md +151 -0
  23. memleaf-0.2.67/docs/installed-artifact-verification.md +131 -0
  24. memleaf-0.2.67/docs/memory-state-contract.md +268 -0
  25. memleaf-0.2.67/docs/migration-preflight.md +237 -0
  26. memleaf-0.2.67/docs/processing-quality-acceptance.md +190 -0
  27. memleaf-0.2.67/docs/public-query-integrity.md +158 -0
  28. memleaf-0.2.67/docs/query-performance.md +102 -0
  29. memleaf-0.2.67/docs/remember-incremental-route.md +159 -0
  30. memleaf-0.2.67/docs/runtime-state-retention.md +190 -0
  31. memleaf-0.2.67/docs/source-work-contract.md +178 -0
  32. memleaf-0.2.67/examples/incremental_acceptance.json +748 -0
  33. memleaf-0.2.67/examples/query_benchmark.py +133 -0
  34. {memleaf-0.2.65 → memleaf-0.2.67}/pyproject.toml +1 -1
  35. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/__init__.py +1 -1
  36. memleaf-0.2.67/src/memleaf/acceptance.py +477 -0
  37. memleaf-0.2.67/src/memleaf/capture.py +593 -0
  38. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/cli.py +54 -5
  39. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/compaction.py +76 -140
  40. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/config.py +19 -0
  41. memleaf-0.2.67/src/memleaf/explicit_text_source.py +47 -0
  42. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/extraction_work_state.py +167 -38
  43. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/hermes_provider/_mcp_client.py +33 -0
  44. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/hermes_provider/_provider.py +104 -9
  45. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/hermes_provider/_shared.py +22 -1
  46. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/hermes_provider/plugin.yaml +1 -1
  47. memleaf-0.2.67/src/memleaf/hermes_provider/provider_compatibility.py +87 -0
  48. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/host_events.py +10 -0
  49. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/host_runtime.py +3 -1
  50. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/inbox.py +141 -9
  51. memleaf-0.2.67/src/memleaf/incremental_commit.py +384 -0
  52. memleaf-0.2.67/src/memleaf/incremental_dates.py +75 -0
  53. memleaf-0.2.67/src/memleaf/incremental_execution.py +381 -0
  54. memleaf-0.2.67/src/memleaf/incremental_journal.py +327 -0
  55. memleaf-0.2.67/src/memleaf/incremental_native.py +165 -0
  56. memleaf-0.2.67/src/memleaf/incremental_partial.py +177 -0
  57. memleaf-0.2.67/src/memleaf/incremental_preview.py +239 -0
  58. memleaf-0.2.67/src/memleaf/incremental_prompts.py +18 -0
  59. memleaf-0.2.67/src/memleaf/incremental_protocol.py +628 -0
  60. memleaf-0.2.67/src/memleaf/incremental_recovery.py +307 -0
  61. memleaf-0.2.67/src/memleaf/incremental_run_state.py +220 -0
  62. memleaf-0.2.67/src/memleaf/incremental_runtime.py +118 -0
  63. memleaf-0.2.67/src/memleaf/incremental_scopes.py +173 -0
  64. memleaf-0.2.67/src/memleaf/incremental_selection.py +67 -0
  65. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/inspection.py +47 -8
  66. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/installer.py +228 -9
  67. memleaf-0.2.67/src/memleaf/legacy_update_journal.py +232 -0
  68. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/llm/openai_compatible.py +6 -0
  69. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/mcp_server.py +165 -21
  70. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/memory_commit.py +80 -3
  71. memleaf-0.2.67/src/memleaf/memory_retraction.py +254 -0
  72. memleaf-0.2.67/src/memleaf/memory_update.py +514 -0
  73. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/memory_writer.py +90 -0
  74. memleaf-0.2.67/src/memleaf/migration.py +381 -0
  75. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/models.py +9 -0
  76. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/planning_context.py +45 -6
  77. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/process_common.py +43 -8
  78. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/process_jobs.py +93 -3
  79. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/process_journal.py +103 -17
  80. memleaf-0.2.67/src/memleaf/processing.py +22 -0
  81. memleaf-0.2.67/src/memleaf/processing_route.py +347 -0
  82. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/prompts.py +9 -14
  83. memleaf-0.2.67/src/memleaf/provider_compatibility.py +87 -0
  84. memleaf-0.2.67/src/memleaf/query_clock.py +42 -0
  85. memleaf-0.2.67/src/memleaf/query_progress.py +158 -0
  86. memleaf-0.2.67/src/memleaf/query_scan.py +245 -0
  87. memleaf-0.2.67/src/memleaf/receipt_codec.py +75 -0
  88. memleaf-0.2.67/src/memleaf/remember_route.py +135 -0
  89. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/retention.py +65 -34
  90. memleaf-0.2.67/src/memleaf/runtime_retention.py +267 -0
  91. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/semantic_maintenance.py +46 -23
  92. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/service.py +451 -113
  93. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/single_pass_memory_planner.py +5 -6
  94. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/state_layout.py +43 -0
  95. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/turn_plan.py +66 -8
  96. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/validation.py +27 -79
  97. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/vault.py +55 -0
  98. {memleaf-0.2.65 → memleaf-0.2.67/src/memleaf.egg-info}/PKG-INFO +15 -4
  99. memleaf-0.2.67/src/memleaf.egg-info/SOURCES.txt +237 -0
  100. memleaf-0.2.67/tests_public/acceptance_oracles.py +2 -0
  101. memleaf-0.2.67/tests_public/candidate_update_fixtures.py +8 -0
  102. memleaf-0.2.67/tests_public/incremental_test_support.py +62 -0
  103. memleaf-0.2.67/tests_public/platform_smoke.py +70 -0
  104. memleaf-0.2.67/tests_public/release_assets.py +176 -0
  105. memleaf-0.2.67/tests_public/run_contracts.py +102 -0
  106. memleaf-0.2.67/tests_public/test_a083_regressions.py +370 -0
  107. memleaf-0.2.67/tests_public/test_a47_regressions.py +440 -0
  108. memleaf-0.2.67/tests_public/test_acceptance.py +250 -0
  109. memleaf-0.2.67/tests_public/test_acceptance_boundaries.py +239 -0
  110. memleaf-0.2.67/tests_public/test_artifact_verification.py +178 -0
  111. memleaf-0.2.67/tests_public/test_body_compaction.py +287 -0
  112. memleaf-0.2.67/tests_public/test_candidate_reconciliation.py +161 -0
  113. memleaf-0.2.67/tests_public/test_contract_reporter.py +66 -0
  114. memleaf-0.2.67/tests_public/test_control_absence_contract.py +91 -0
  115. memleaf-0.2.67/tests_public/test_create_memory_contract.py +207 -0
  116. memleaf-0.2.67/tests_public/test_development_closeout.py +193 -0
  117. memleaf-0.2.67/tests_public/test_explicit_memory_update.py +553 -0
  118. memleaf-0.2.67/tests_public/test_explicit_update_contract.py +205 -0
  119. memleaf-0.2.67/tests_public/test_g1_memory_contract.py +171 -0
  120. memleaf-0.2.67/tests_public/test_g2_source_contract.py +402 -0
  121. memleaf-0.2.67/tests_public/test_hermes_native_provision.py +91 -0
  122. memleaf-0.2.67/tests_public/test_hermes_source_metadata.py +104 -0
  123. memleaf-0.2.67/tests_public/test_incremental_commit.py +194 -0
  124. memleaf-0.2.67/tests_public/test_incremental_configured_runtime.py +110 -0
  125. memleaf-0.2.67/tests_public/test_incremental_dates.py +119 -0
  126. memleaf-0.2.67/tests_public/test_incremental_execution.py +367 -0
  127. memleaf-0.2.67/tests_public/test_incremental_execution_recovery.py +302 -0
  128. memleaf-0.2.67/tests_public/test_incremental_native.py +428 -0
  129. memleaf-0.2.67/tests_public/test_incremental_partial.py +177 -0
  130. memleaf-0.2.67/tests_public/test_incremental_partial_boundaries.py +180 -0
  131. memleaf-0.2.67/tests_public/test_incremental_partial_recovery.py +277 -0
  132. memleaf-0.2.67/tests_public/test_incremental_preview.py +190 -0
  133. memleaf-0.2.67/tests_public/test_incremental_protocol.py +384 -0
  134. memleaf-0.2.67/tests_public/test_incremental_recovery.py +263 -0
  135. memleaf-0.2.67/tests_public/test_incremental_remember.py +231 -0
  136. memleaf-0.2.67/tests_public/test_incremental_remember_recovery.py +238 -0
  137. memleaf-0.2.67/tests_public/test_incremental_scope_recovery.py +332 -0
  138. memleaf-0.2.67/tests_public/test_incremental_scopes.py +203 -0
  139. memleaf-0.2.67/tests_public/test_inspection_read_budget.py +171 -0
  140. memleaf-0.2.67/tests_public/test_mcp_retrieval_fallback.py +140 -0
  141. memleaf-0.2.67/tests_public/test_migration_backup.py +374 -0
  142. memleaf-0.2.67/tests_public/test_migration_runtime.py +111 -0
  143. memleaf-0.2.67/tests_public/test_native_read_stability.py +196 -0
  144. memleaf-0.2.67/tests_public/test_planner_provenance_contract.py +117 -0
  145. memleaf-0.2.67/tests_public/test_platform_contracts.py +103 -0
  146. memleaf-0.2.67/tests_public/test_processed_state_contract.py +98 -0
  147. memleaf-0.2.67/tests_public/test_processing_entrypoints.py +266 -0
  148. memleaf-0.2.67/tests_public/test_processing_route.py +278 -0
  149. memleaf-0.2.67/tests_public/test_processing_route_recovery.py +159 -0
  150. memleaf-0.2.67/tests_public/test_provider_compatibility.py +567 -0
  151. memleaf-0.2.67/tests_public/test_public_query_integrity.py +267 -0
  152. memleaf-0.2.67/tests_public/test_query_benchmark.py +68 -0
  153. memleaf-0.2.67/tests_public/test_query_clock.py +89 -0
  154. memleaf-0.2.67/tests_public/test_query_progress.py +140 -0
  155. memleaf-0.2.67/tests_public/test_query_scan_reuse.py +234 -0
  156. memleaf-0.2.67/tests_public/test_release_assets.py +283 -0
  157. memleaf-0.2.67/tests_public/test_remember_route.py +274 -0
  158. memleaf-0.2.67/tests_public/test_remember_route_recovery.py +232 -0
  159. memleaf-0.2.67/tests_public/test_revision_target_integrity.py +262 -0
  160. memleaf-0.2.67/tests_public/test_runtime_retention.py +329 -0
  161. memleaf-0.2.67/tests_public/test_runtime_retention_observation.py +174 -0
  162. memleaf-0.2.67/tests_public/test_runtime_retention_recovery.py +230 -0
  163. memleaf-0.2.67/tests_public/test_source_followup_contract.py +160 -0
  164. memleaf-0.2.67/tests_public/test_vault_binding_contract.py +97 -0
  165. memleaf-0.2.67/tests_public/verify_distribution.py +363 -0
  166. memleaf-0.2.65/docs/processing-quality-acceptance.md +0 -81
  167. memleaf-0.2.65/src/memleaf/capture.py +0 -335
  168. memleaf-0.2.65/src/memleaf/processing.py +0 -474
  169. memleaf-0.2.65/src/memleaf.egg-info/SOURCES.txt +0 -115
  170. {memleaf-0.2.65 → memleaf-0.2.67}/LICENSE +0 -0
  171. {memleaf-0.2.65 → memleaf-0.2.67}/docs/capture-budget-design.md +0 -0
  172. {memleaf-0.2.65 → memleaf-0.2.67}/docs/config-migrations.md +0 -0
  173. {memleaf-0.2.65 → memleaf-0.2.67}/docs/core-refactor.md +0 -0
  174. {memleaf-0.2.65 → memleaf-0.2.67}/docs/evidence-retention.md +0 -0
  175. {memleaf-0.2.65 → memleaf-0.2.67}/docs/extraction-latency.md +0 -0
  176. {memleaf-0.2.65 → memleaf-0.2.67}/docs/gate-evidence-boundary.md +0 -0
  177. {memleaf-0.2.65 → memleaf-0.2.67}/docs/general-processing.md +0 -0
  178. {memleaf-0.2.65 → memleaf-0.2.67}/docs/hermes-mcp-runtime.md +0 -0
  179. {memleaf-0.2.65 → memleaf-0.2.67}/docs/semantic-extraction-protocol.md +0 -0
  180. {memleaf-0.2.65 → memleaf-0.2.67}/docs/v0.2.26-processing-status.md +0 -0
  181. {memleaf-0.2.65 → memleaf-0.2.67}/examples/README.md +0 -0
  182. {memleaf-0.2.65 → memleaf-0.2.67}/examples/basic_usage.py +0 -0
  183. {memleaf-0.2.65 → memleaf-0.2.67}/examples/mcp_stdio.ndjson +0 -0
  184. {memleaf-0.2.65 → memleaf-0.2.67}/install.ps1 +0 -0
  185. {memleaf-0.2.65 → memleaf-0.2.67}/install.sh +0 -0
  186. {memleaf-0.2.65 → memleaf-0.2.67}/setup.cfg +0 -0
  187. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/__main__.py +0 -0
  188. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/adapters/__init__.py +0 -0
  189. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/adapters/antigravity.py +0 -0
  190. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/adapters/base.py +0 -0
  191. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/adapters/codex.py +0 -0
  192. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/adapters/hermes.py +0 -0
  193. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/admission.py +0 -0
  194. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/batch_review.py +0 -0
  195. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/budget.py +0 -0
  196. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/create_coordinator.py +0 -0
  197. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/credentials.py +0 -0
  198. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/evidence_budget.py +0 -0
  199. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/evidence_policy.py +0 -0
  200. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/evidence_structure.py +0 -0
  201. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/evidence_syntax.py +0 -0
  202. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/extraction_budget.py +0 -0
  203. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/extraction_capability.py +0 -0
  204. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/frontmatter.py +0 -0
  205. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/hermes_provider/README.md +0 -0
  206. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/hermes_provider/__init__.py +0 -0
  207. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/hermes_provider/evidence_budget.py +0 -0
  208. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/hermes_runtime.py +0 -0
  209. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/index.py +0 -0
  210. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/llm/__init__.py +0 -0
  211. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/llm/base.py +0 -0
  212. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/llm/claude_compatible.py +0 -0
  213. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/llm/gemini.py +0 -0
  214. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/llm/router.py +0 -0
  215. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/llm/thinking.py +0 -0
  216. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/locking.py +0 -0
  217. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/memory_planner.py +0 -0
  218. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/model_capabilities.py +0 -0
  219. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/model_discovery.py +0 -0
  220. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/model_execution.py +0 -0
  221. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/native_index.py +0 -0
  222. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/native_registration.py +0 -0
  223. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/parallel_model.py +0 -0
  224. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/process_owner.py +0 -0
  225. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/provenance.py +0 -0
  226. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/recording_policy.py +0 -0
  227. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/redaction.py +0 -0
  228. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/retrieval.py +0 -0
  229. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/retrieval_gate.py +0 -0
  230. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/scope_maintenance.py +0 -0
  231. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/scope_state.py +0 -0
  232. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/semantic_protocol.py +0 -0
  233. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/single_pass_plan.py +0 -0
  234. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/source_policy.py +0 -0
  235. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/subprocess_flags.py +0 -0
  236. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/summary_batch.py +0 -0
  237. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/target_reconciliation.py +0 -0
  238. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/turn_audit.py +0 -0
  239. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/update_coordinator.py +0 -0
  240. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf/update_review.py +0 -0
  241. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf.egg-info/dependency_links.txt +0 -0
  242. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf.egg-info/entry_points.txt +0 -0
  243. {memleaf-0.2.65 → memleaf-0.2.67}/src/memleaf.egg-info/top_level.txt +0 -0
@@ -2,6 +2,135 @@
2
2
 
3
3
  All notable changes to memleaf are documented here.
4
4
 
5
+ ## Unreleased
6
+
7
+ ## 0.2.67 — 2026-09-20
8
+
9
+ ### Incremental-only processing and release integrity
10
+
11
+ - Remove the executable legacy processing/remember engine. New Vaults use the
12
+ incremental runner for automatic processing, explicit remember, MCP/CLI and
13
+ detached jobs; retained legacy settings/jobs remain inspectable but fail closed.
14
+ - Fix the v0.2.66 Hermes Provider manifest drift by aligning Core and Provider at
15
+ 0.2.67 and rejecting an internally inconsistent package before host/Vault changes.
16
+ - Gate source and wheel/sdist verification on one version identity across package
17
+ metadata, Core `__version__`, Hermes `plugin.yaml` and sdist project metadata.
18
+
19
+
20
+ ## 0.2.66 — 2026-09-20
21
+
22
+ ### Reconcile divergent local candidates
23
+
24
+ - Integrate the 1147-test closeout and 1128-test update candidates without losing
25
+ either test inventory, control-loss guards, binding, shared Writer or Forget.
26
+ - Use one explicit-update writer with strict scope/restore flags, caller source
27
+ time, canonical deadline forms, retained stale evidence and settlement recheck.
28
+ - Preserve exact recovery for both earlier v1 layouts; reject conflicting copies.
29
+ Expose pending counts and protect only proven retention dependencies when safe.
30
+ - Resolve provisional API/test disagreements explicitly; no release, default
31
+ route, production Vault or model-request-budget changes.
32
+
33
+
34
+ ### Development closeout contracts
35
+
36
+ - Add a bounded, exact Python `update_memory` with expected revision, field/scope
37
+ whitelist, explicit reopen/restore/type correction and forward recovery.
38
+ - Reuse strict target scans for shared writes; preserve newer edits and read
39
+ counters, protect pending journals from retention, and expose their freshness.
40
+ - Make logical-ID Forget/cancellation case-insensitive without treating a lone
41
+ fuzzy candidate as confirmation or damaged files as absent.
42
+ - Refuse lost durable authority as a fresh budget; bind genuinely new local
43
+ Vaults without guessing the owner of legacy data. Keep supported old capsules.
44
+ - Use bounded planner snapshots and explicit provenance status after direct
45
+ edits. No additional model phase, default-route switch, release or production
46
+ migration; external semantic and native-host final tests remain separate.
47
+
48
+
49
+ - Validate revision lookups and explicit retractions against bounded current-ID
50
+ scans; reject duplicate/unreadable ownership instead of silently skipping it.
51
+ Recheck before history/head writes, preserve recovery journals for unreadable
52
+ targets, keep read accounting on retry, and qualify interrupted-write results
53
+ using the full protected revision. Existing v1 recovery and raw APIs remain.
54
+
55
+
56
+ - Make `create_memory` create-only: reject existing frontmatter identities across
57
+ current/history files, renamed or case-variant IDs, occupied destinations and
58
+ unverifiable scans instead of silently replacing records. Keep trusted raw
59
+ `write_memory`/`save_memory`/`add_memory` overwrite compatibility, with an
60
+ explicit `overwrite=False` create-only option. No model or default pipeline
61
+ changes; general revision-checked raw updates are not introduced.
62
+
63
+ - Verify copied Hermes Provider behavior resources through the existing MCP handshake and explicit installer probe; reject mismatched/unverified bridge mutations while retaining local reads. Detect in-place copy changes without refreshing a live host, validate both copy paths, and preserve safe compatibility errors. No model calls, prompt/default/version changes or automatic activation.
64
+
65
+ - Restrict explicit memory compaction to independent body-only proposals. Preserve the complete original identity, state, deadlines, responsibility, provenance and custom fields; remove multi-ID merging and unrelated pre-compaction retention. Bound model inputs and keep existing rollback journals compatible.
66
+
67
+ - Compare native-file ctime stability within path and descriptor observations separately: Windows CPython 3.12 can report creation time and metadata-change time through different APIs. Preserve cross-API identity/size/mtime checks, whole-content guards, and per-file bounded reads. Repair the LF-to-CRLF test fixture without skipping native platforms or weakening change detection.
68
+
69
+ - Size inspection reads from each opened regular file, not the entire remaining Vault budget. Keep full-byte snapshot comparisons and reject detected growth, truncation or in-read metadata changes; avoid a roughly 256 MiB temporary allocation for tiny files during migration/audit/backup checks. No model calls, schema/default changes or release.
70
+
71
+ - Gate future releases on native installed-artifact contract checks: build once, bind wheel/sdist and test inventory, then verify independent installations on Ubuntu/Python 3.11-3.13 and Windows/macOS Python 3.12. Include packaged Provider resources, real stdio/lock/restart checks and explicit failure on skipped or source-shadowed tests. This is deterministic validation, not live-model or installed-Hermes acceptance; defaults, prompt and version stay unchanged.
72
+
73
+ - Avoid reparsing unchanged validated Markdown during public-query rechecks. Re-enumerate and re-read current bytes before reusing immutable request-local fingerprints; retain malformed/duplicate isolation and all existing change/bound checks. Add an isolated synthetic query benchmark without model calls, persistent cache or default changes.
74
+
75
+ - Add a plan-first, explicitly budgeted isolated multi-turn acceptance utility with twelve public synthetic regression trajectories. Keep expected assertions out of model inputs, preserve private evidence traces, and separate structural, semantic and host/migration gates; no default activation or live calls during delivery.
76
+ - Expose bounded returned-model metadata from the configured compatible adapter for acceptance without changing its request route or retaining hidden reasoning. Replace obsolete acceptance requirements for the legacy Gate/review chain with the current incremental contract.
77
+
78
+ - Add read-only migration preflight and explicit private local backup/verification through existing inspection and control contracts. Preserve exact source/authority bytes, publish the checksum manifest last, refuse stale or active snapshots, and keep backup integrity distinct from production readiness. No automatic switching, restore, model calls or default changes.
79
+ - Reuse strict processed-state reading in session lineage updates instead of overwriting damaged authority with an empty ledger. Surface managed-area enumeration and nonregular-file failures in bounded inspection.
80
+
81
+ - Preserve runtime-maintenance partial outcomes when dependency/final observation fails, verify the final intended control bytes instead of accepting any new revision, and report uncertain write outcomes explicitly. Reuse the existing lossless receipt codec, budget retirement and replay contracts; no extra cleanup policy or model calls.
82
+
83
+ - Add explicit, preview-first lossless terminal control-state compaction. Seal only proven completed run/commit receipts, preserve their exact decisions and cancellation behavior, and release active slots without deleting authorization. Keep bounded historical receipts readable through versioned, size-limited encoding; leave unresolved work and source/permission state intact.
84
+ - Retain completed source-work budget counts under capacity pressure instead of evicting them and reopening the same work. Preserve legacy job ambiguity and independent new authorization; bound retired counters and reject damaged or oversized state. Default extraction routes, main prompt and package version stay unchanged.
85
+
86
+ - Make public query completeness and Vault-wide pending progress explicit. Isolate malformed/duplicate records, use current Markdown for candidate lookup, freeze Todo query clocks across pages, and expose a read-only state-retention capacity inventory. No state collection, model calls, prompt changes or default pipeline activation.
87
+
88
+ - Add opt-in incremental routing to existing text remember and MCP remember, using one typed user source and the shared selected-retention runner. Preserve caller policy, stable intent, source time, scope, cleanup isolation and zero-call recovery; retain legacy defaults.
89
+ - Refuse damaged processed control state in both capture and execution instead of resetting authority and request evidence to an empty ledger.
90
+
91
+ - Integrate the existing process/CLI/MCP/job entry points with an opt-in incremental automatic route. Preserve legacy defaults, stable capture addressing, frozen queue controls, two-request source budgets and zero-call commit recovery; retain partial write outcomes and expose read-only runtime health. No default activation or release.
92
+
93
+ - Coordinate opt-in incremental scope discovery with frozen memory operations: preserve declared identities and explicit boundaries, write Markdown before missing registry nodes, and recover config/index/receipt failures without new model calls or duplicate writes. Version scope-dependent commit receipts while retaining legacy reads.
94
+
95
+ - Add explicit bounded partial continuation on the existing incremental runner: zero-call exact container repair or one remaining changed-context replan. Preserve accepted operation IDs, source/authorization boundaries and original budgets; carry cumulative recovery receipts, cancel retained partial plaintext on Forget, and release resolved parent context protection. Default routes and the fixed prompt remain unchanged.
96
+
97
+ - Add opt-in selected-source explicit retention on the canonical incremental runner: bind user intent and exact captured sources, keep unselected text as context, preserve automatic settlement, and recover with the shared two-request allowance. No default routing, prompt, model-setting or version change.
98
+
99
+ - Connect configured native notes to opt-in incremental comparison using existing fragment identities, read-only NO_CHANGE targets and content/sharing guards. Keep native files and shadow maps untouched; disclose bounded selection and unavailable sources instead of assuming deduplication.
100
+ - Protect pending incremental source context as well as its selected turn from cleanup, without claiming context as a new processing owner. No production-route, prompt, model-setting or version changes.
101
+
102
+ - Reconcile the configured `process_incremental()` facade with the committed run-ID API and existing receipt schema; preserve one source-work budget, explicit transport recovery and cached-response recovery without model configuration.
103
+
104
+ - Add an opt-in captured-turn incremental model runner on the shared G3b commit bridge. Persist request/response receipts, reuse source-work budgets with a two-dispatch ceiling, and recover saved responses without model regeneration. Do not switch production process/remember/MCP routes.
105
+ - Fence concurrent legacy/incremental model workers without holding a file lock across provider calls; cancel in-flight receipts on Forget and preserve unresolved decisions without a second semantic review. Keep permanent-error and partial replanning boundaries explicit.
106
+
107
+ - Stage explicit incremental apply/resume APIs on the shared MemoryWriter, freezing target groups, source/revision checks and NO_MEMORY/NO_CHANGE decisions. Default model routes remain unchanged.
108
+ - Recover interrupted history/head/index/source-receipt work without reallocating IDs; protect staged sources from legacy re-extraction/cleanup and cancel shared-source pending plaintext before Forget.
109
+ - Add 55 public commit/recovery regressions, including real process exit, concurrent replay and ten receipt-write fault boundaries. Preserve 187 existing tests; native comparison, new-scope transactions and model dispatch remain separate stages.
110
+
111
+ - Add the staged, read-only incremental-items-v1 request/response compiler and Python preview API. Preserve target state with grouped patches, explicit scope/lifecycle checks and evidence-anchored calendar conversion. This does not enable a new production planner, call models, settle evidence or change package version.
112
+
113
+ - Order known, non-overlapping source-turn windows before processing without changing capture IDs; advance only contiguous local receipt watermarks so capped batches and interrupted runs do not skip pending turns.
114
+ - Reject ambiguous legacy job-budget migration for metadata-bearing sources rather than granting fresh allowance; merge proven legacy consumption even when a source-work row already exists.
115
+ - Forward optional Hermes source metadata only from an exactly matched visible pair; keep missing timestamps unknown and bind revision-capable host IDs without reading tool or attachment content.
116
+ - Remove the legacy summary instruction equating a completion report timestamp with the actual completion time. No model call, model-setting, package-version or release changes.
117
+
118
+ - Repair source/intent contracts end to end: forward public remember intent, bind each authorization to immutable content/scope and original observation time, and keep separate authorizations in one host turn independent.
119
+ - Preserve out-of-order initial messages, require trusted final for new source envelopes, and validate all immutable revision metadata even after inbox body cleanup.
120
+ - Reconcile durable inbox receipts before selection/cleanup, fence commits against the actual source snapshot, retain revised evidence/coordination targets, and prevent duplicate retry selection.
121
+ - Keep partial work eligible within its remaining budget; migrate exhausted legacy job counters without reopening authority. Version frozen input digests and reject unprovable legacy explicit-remember bindings instead of inventing timestamps.
122
+ - Add 32 synthetic boundary regression tests. No extraction prompts, model settings, version, tags or release workflows changed.
123
+
124
+ - Fix cross-namespace maintenance disposition fallback, provenance-sensitive semantic duplicates, and withdrawn-head leakage through project/priority/contextual retrieval.
125
+ - Validate validity types before enum membership; keep malformed records from breaking unrelated reads. Retain pre-validity frozen UPDATE compatibility only for unchanged legacy-format targets.
126
+ - Journal explicit retractions for bounded, revision-checked forward recovery; finish failed index work without duplicate history, preserve later edits, and cancel pending plaintext on forget.
127
+ - Include public regressions in sdist, covering recovery boundaries, real subprocess exits, concurrency, old revisions and negative protocol cases. No model prompts, package version or release automation were changed.
128
+ - Separate original `source_time` from local `captured_at`, persist stable message/revision/order metadata, use trusted final signals for new capture envelopes, and fence stale plans when a host message is revised.
129
+ - Bind durable model-request budgets to source revisions plus explicit intent across synchronous/background transports. Completed authorization rows stay terminal, active rows are not age-evicted, and legacy over-limit counters remain exhausted instead of being reset.
130
+ - Keep `completed_at` unknown unless evidence establishes an actual completion time; a message timestamp records observation, not the business event time.
131
+ - Add a first-class `validity: valid|retracted` state. Deterministic retraction uses an expected revision, archives the previous valid body, keeps the stable current identity, and excludes retracted assertions from ordinary read/search/todo results while retaining explicit audit and forget paths.
132
+ - Preserve completed and cancelled todo heads in `knowledge/` instead of retiring their stable identities by age. Add public deterministic contract tests to CI for legacy compatibility, retraction, revision conflicts, and closed-todo retention.
133
+
5
134
  ## 0.2.65 — 2026-09-16
6
135
 
7
136
  - Ground maintenance todo deadlines in Core-validated candidate evidence and `reference_time`. Relative calendar ranges resolve deterministically to their last valid day, while the normalized deadline view removes only formatting and equivalent parenthetical restatements without losing conflicting dates.
@@ -7,5 +7,8 @@ include README.en.md
7
7
  recursive-include examples *.md *.ndjson *.py
8
8
  recursive-exclude examples *_acceptance.py
9
9
  prune tests
10
+ recursive-include tests_public *.py
10
11
 
11
12
  include docs/*.md
13
+
14
+ include examples/incremental_acceptance.json
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: memleaf
3
- Version: 0.2.65
3
+ Version: 0.2.67
4
4
  Summary: A local-first Markdown memory core for AI agents
5
5
  Author: memleaf contributors
6
6
  License-Expression: MIT
@@ -80,7 +80,8 @@ memleaf 不会把整个 Vault 或整段历史对话自动塞进模型上下文
80
80
  - search 候选单页最多 20 项、约 4000 字符;
81
81
  - read 单页正文最多 2000 字符;
82
82
  - 同一受管理轮次可继续读取所有与问题相关的记忆;`read_count`/`read_chars` 仅用于审计,不再作为阻断配额;
83
- - `retrieval_id` 必须属于当前轮次,且必须先有成功的 `search` 才能 `read`;
83
+ - 有宿主 Hook/Provider 时,`retrieval_id` 必须属于当前轮次;纯 MCP 客户端第一次 `search` / `list_todos` 可省略它,由 memleaf 返回短期 token,后续分页和 `read` 必须复用;
84
+ - 无论哪种接入方式,都必须先有成功的 `search` / `list_todos` 才能 `read`;
84
85
  - `found`、`no_match` 和工具错误是不同状态,错误不能被伪装成无匹配;
85
86
  - `context()` 和 Python `search(view="full")` 作为兼容接口保留,但不属于自动检索路径。
86
87
 
@@ -96,6 +97,8 @@ memleaf 不把每句话都保存为记忆。处理一轮完整的 user + assista
96
97
  - `UPDATE`:同一未来用途的现存记忆需要更新,沿用原 `memory_id`;旧内容进入 `history/`;
97
98
  - `NO_CHANGE`:只是重复、查询、临时状态、测试、审计、诊断或没有稳定复用价值,不新增记忆。
98
99
 
100
+ 普通事实被明确撤回但未要求彻底删除时,Core 可使用 `retract_memory()` 将同一 `memory_id` 标为 `validity: retracted`。旧有效正文进入 `history/`,普通 search/read/list_todos 不再把它作为当前事实;这与 `forget_memory()` 的物理删除合同不同。确定性撤回必须携带 `memory_revision()` 或 `read_page()` 返回的当前 `revision`,避免覆盖并发修改。完整边界见 [Memory state contract](docs/memory-state-contract.md)。
101
+
99
102
  额外约束:
100
103
 
101
104
  - 通常一轮产生 0~1 条记忆,而不是按句子拆分;
@@ -283,7 +286,7 @@ python -m memleaf.mcp_server --vault "$HOME/.memleaf"
283
286
  | `rebuild_index` | 重建可重建的本地派生索引 |
284
287
  | `stats` | 返回 Vault 计数和诊断统计 |
285
288
 
286
- `search` 的候选只是线索,标题不能单独作为事实依据。受管理检索必须使用同一轮的 `retrieval_id` 完成 `search → read`;工具错误、Scope 冲突或读取预算耗尽都应如实处理。
289
+ `search` 的候选只是线索,标题不能单独作为事实依据。受管理检索必须使用同一条检索链的 `retrieval_id` 完成 `search → read`。Hermes/Codex Hook 可直接提供该 token;只有 MCP 的客户端可在第一条 `search` / `list_todos` 省略 token,并使用返回值继续分页和读取。带 cursor 的后续页以及所有 `read` 都不能省略 `retrieval_id`。工具错误、Scope 冲突或读取失败都应如实处理。
287
290
 
288
291
  ## Python API
289
292
 
@@ -315,6 +318,8 @@ capture() 捕获可见事件
315
318
  process() 处理完整 inbox 轮次,需要模型路由
316
319
  remember() 显式保存,需要模型路由
317
320
  create_memory() 直接创建一条 Markdown 记忆
321
+ memory_revision() 读取受保护内容的并发版本
322
+ retract_memory() 撤回当前事实,保留同 ID 头和历史
318
323
  search() 本地检索,不更新命中统计
319
324
  context() 兼容接口,返回轻量目录
320
325
  read() / read_page() 读取记忆或分页正文
@@ -325,6 +330,12 @@ stats()
325
330
  compact() 按阈值整理低优先级记忆,需要模型路由
326
331
  ```
327
332
 
333
+ `capture()` 可接收 `message_id`、`message_revision`、`source_sequence`、
334
+ `previous_message_id`、`source_time` 和可信 `final` 信号。`source_time` 是带时区的
335
+ 原消息时间,缺失时保持未知,不会用本地 `captured_at` 冒充。`remember()` 的重试应
336
+ 复用同一 `intent_id`;新的明确保留授权使用新 ID。完整合同见
337
+ [`docs/source-work-contract.md`](docs/source-work-contract.md)。
338
+
328
339
  离线示例默认使用临时 Vault,不写入 `~/.memleaf`,也不访问网络:
329
340
 
330
341
  ```bash
@@ -440,7 +451,7 @@ history:
440
451
  ```
441
452
 
442
453
  - active Markdown 每条最多保留 16 个来源明细,同时记录累计 `source_count`、`source_digest` 和省略数量,避免 UPDATE 让 `sources` 无限膨胀;
443
- - 已完成/已取消 todo 默认在 30 天后退出 `knowledge/` 并进入 `history/`;`list_todos(status=completed|cancelled|all)` 仍可枚举这些历史待办;
454
+ - 已完成/已取消 todo 保留在 `knowledge/` 中作为稳定当前身份,默认 active 清单不展示,但 `list_todos(status=completed|cancelled|all)` 和后续维护仍可按原 ID 定位;`closed_todo_retention_days` 仅作为旧配置兼容项保留;
444
455
  - `history.policy: bounded` 默认每个稳定记忆身份最多保留 32 个完整历史版本,且超过 3650 天的版本可被维护流程淘汰;需要永久审计时可显式设置 `history.policy: keep_all`;
445
456
  - compaction 会保留一个既有 canonical `memory_id`,不会再为整理结果创建新的 `mem-compact-*` 身份;单条精简保持原 ID,多条合并选择一个稳定 survivor。
446
457
  - 这些维护动作在正常 `process()` / `remember()` / `compact()` 生命周期中执行,不需要 daemon;普通只读检索本身不触发维护写入。
@@ -75,6 +75,8 @@ memleaf does not save every sentence. When a complete visible user + assistant t
75
75
  - `UPDATE`: an active memory for the same future use needs new information, so keep its `memory_id` and move the old version to `history/`;
76
76
  - `NO_CHANGE`: the turn is a duplicate, query, temporary state, test, audit, diagnostic, or otherwise has no stable reuse value, so append nothing.
77
77
 
78
+ When an ordinary assertion is explicitly withdrawn without a request to erase it, Core can use `retract_memory()` to keep the same `memory_id` with `validity: retracted`. The prior valid body moves to `history/`, and ordinary search/read/list_todos no longer treats it as current fact. This is distinct from the physical-deletion contract of `forget_memory()`. A deterministic retraction must carry the current revision returned by `memory_revision()` or `read_page()` so it cannot overwrite a concurrent edit. See [Memory state contract](docs/memory-state-contract.md) for the complete boundary.
79
+
78
80
  Additional rules:
79
81
 
80
82
  - A normal turn typically produces 0–1 memory rather than one memory per sentence.
@@ -298,6 +300,8 @@ capture() Capture a visible event
298
300
  process() Process complete inbox turns; requires a model route
299
301
  remember() Explicitly save a memory; requires a model route
300
302
  create_memory() Directly create a Markdown memory
303
+ memory_revision() Read the protected-state concurrency revision
304
+ retract_memory() Retract an assertion while keeping its ID and history
301
305
  search() Local retrieval without updating hit counts
302
306
  context() Compatibility API returning a light directory
303
307
  read() / read_page() Read a memory or a body page
@@ -308,6 +312,13 @@ stats()
308
312
  compact() Compact low-priority memories; requires a model route
309
313
  ```
310
314
 
315
+ `capture()` accepts `message_id`, `message_revision`, `source_sequence`,
316
+ `previous_message_id`, `source_time`, and a trusted `final` signal. `source_time`
317
+ is the timezone-aware original message time; when absent it remains unknown and
318
+ local `captured_at` is never substituted. Retries of one explicit `remember()`
319
+ authorization should reuse its `intent_id`; a new authorization uses a new ID.
320
+ See [`docs/source-work-contract.md`](docs/source-work-contract.md).
321
+
311
322
  The offline example uses a temporary Vault by default. It does not write to `~/.memleaf` or access the network:
312
323
 
313
324
  ```bash
@@ -423,7 +434,7 @@ history:
423
434
  ```
424
435
 
425
436
  - Each active Markdown memory retains at most 16 detailed provenance rows while tracking cumulative `source_count`, `source_digest`, and omitted rows, so repeated UPDATEs cannot grow `sources` without bound.
426
- - Completed/cancelled todos leave `knowledge/` after 30 days by default and move to `history/`; `list_todos(status=completed|cancelled|all)` can still enumerate retired todos.
437
+ - Completed/cancelled todos remain in `knowledge/` as stable current identities. The default active view hides them, while `list_todos(status=completed|cancelled|all)` and later maintenance can still resolve the original ID. `closed_todo_retention_days` remains only as a legacy configuration key.
427
438
  - With `history.policy: bounded`, each stable memory identity keeps at most 32 full historical versions, and versions older than 3650 days are eligible for pruning. Set `history.policy: keep_all` explicitly when permanent audit retention is required.
428
439
  - Compaction preserves an existing canonical `memory_id` instead of creating a new `mem-compact-*` identity; a single-memory rewrite keeps its ID and a multi-memory merge chooses one stable survivor.
429
440
  - Maintenance runs through normal `process()` / `remember()` / `compact()` lifecycle calls and requires no daemon. Ordinary read-only retrieval does not trigger maintenance writes.
@@ -61,7 +61,8 @@ memleaf 不会把整个 Vault 或整段历史对话自动塞进模型上下文
61
61
  - search 候选单页最多 20 项、约 4000 字符;
62
62
  - read 单页正文最多 2000 字符;
63
63
  - 同一受管理轮次可继续读取所有与问题相关的记忆;`read_count`/`read_chars` 仅用于审计,不再作为阻断配额;
64
- - `retrieval_id` 必须属于当前轮次,且必须先有成功的 `search` 才能 `read`;
64
+ - 有宿主 Hook/Provider 时,`retrieval_id` 必须属于当前轮次;纯 MCP 客户端第一次 `search` / `list_todos` 可省略它,由 memleaf 返回短期 token,后续分页和 `read` 必须复用;
65
+ - 无论哪种接入方式,都必须先有成功的 `search` / `list_todos` 才能 `read`;
65
66
  - `found`、`no_match` 和工具错误是不同状态,错误不能被伪装成无匹配;
66
67
  - `context()` 和 Python `search(view="full")` 作为兼容接口保留,但不属于自动检索路径。
67
68
 
@@ -77,6 +78,8 @@ memleaf 不把每句话都保存为记忆。处理一轮完整的 user + assista
77
78
  - `UPDATE`:同一未来用途的现存记忆需要更新,沿用原 `memory_id`;旧内容进入 `history/`;
78
79
  - `NO_CHANGE`:只是重复、查询、临时状态、测试、审计、诊断或没有稳定复用价值,不新增记忆。
79
80
 
81
+ 普通事实被明确撤回但未要求彻底删除时,Core 可使用 `retract_memory()` 将同一 `memory_id` 标为 `validity: retracted`。旧有效正文进入 `history/`,普通 search/read/list_todos 不再把它作为当前事实;这与 `forget_memory()` 的物理删除合同不同。确定性撤回必须携带 `memory_revision()` 或 `read_page()` 返回的当前 `revision`,避免覆盖并发修改。完整边界见 [Memory state contract](docs/memory-state-contract.md)。
82
+
80
83
  额外约束:
81
84
 
82
85
  - 通常一轮产生 0~1 条记忆,而不是按句子拆分;
@@ -264,7 +267,7 @@ python -m memleaf.mcp_server --vault "$HOME/.memleaf"
264
267
  | `rebuild_index` | 重建可重建的本地派生索引 |
265
268
  | `stats` | 返回 Vault 计数和诊断统计 |
266
269
 
267
- `search` 的候选只是线索,标题不能单独作为事实依据。受管理检索必须使用同一轮的 `retrieval_id` 完成 `search → read`;工具错误、Scope 冲突或读取预算耗尽都应如实处理。
270
+ `search` 的候选只是线索,标题不能单独作为事实依据。受管理检索必须使用同一条检索链的 `retrieval_id` 完成 `search → read`。Hermes/Codex Hook 可直接提供该 token;只有 MCP 的客户端可在第一条 `search` / `list_todos` 省略 token,并使用返回值继续分页和读取。带 cursor 的后续页以及所有 `read` 都不能省略 `retrieval_id`。工具错误、Scope 冲突或读取失败都应如实处理。
268
271
 
269
272
  ## Python API
270
273
 
@@ -296,6 +299,8 @@ capture() 捕获可见事件
296
299
  process() 处理完整 inbox 轮次,需要模型路由
297
300
  remember() 显式保存,需要模型路由
298
301
  create_memory() 直接创建一条 Markdown 记忆
302
+ memory_revision() 读取受保护内容的并发版本
303
+ retract_memory() 撤回当前事实,保留同 ID 头和历史
299
304
  search() 本地检索,不更新命中统计
300
305
  context() 兼容接口,返回轻量目录
301
306
  read() / read_page() 读取记忆或分页正文
@@ -306,6 +311,12 @@ stats()
306
311
  compact() 按阈值整理低优先级记忆,需要模型路由
307
312
  ```
308
313
 
314
+ `capture()` 可接收 `message_id`、`message_revision`、`source_sequence`、
315
+ `previous_message_id`、`source_time` 和可信 `final` 信号。`source_time` 是带时区的
316
+ 原消息时间,缺失时保持未知,不会用本地 `captured_at` 冒充。`remember()` 的重试应
317
+ 复用同一 `intent_id`;新的明确保留授权使用新 ID。完整合同见
318
+ [`docs/source-work-contract.md`](docs/source-work-contract.md)。
319
+
309
320
  离线示例默认使用临时 Vault,不写入 `~/.memleaf`,也不访问网络:
310
321
 
311
322
  ```bash
@@ -421,7 +432,7 @@ history:
421
432
  ```
422
433
 
423
434
  - active Markdown 每条最多保留 16 个来源明细,同时记录累计 `source_count`、`source_digest` 和省略数量,避免 UPDATE 让 `sources` 无限膨胀;
424
- - 已完成/已取消 todo 默认在 30 天后退出 `knowledge/` 并进入 `history/`;`list_todos(status=completed|cancelled|all)` 仍可枚举这些历史待办;
435
+ - 已完成/已取消 todo 保留在 `knowledge/` 中作为稳定当前身份,默认 active 清单不展示,但 `list_todos(status=completed|cancelled|all)` 和后续维护仍可按原 ID 定位;`closed_todo_retention_days` 仅作为旧配置兼容项保留;
425
436
  - `history.policy: bounded` 默认每个稳定记忆身份最多保留 32 个完整历史版本,且超过 3650 天的版本可被维护流程淘汰;需要永久审计时可显式设置 `history.policy: keep_all`;
426
437
  - compaction 会保留一个既有 canonical `memory_id`,不会再为整理结果创建新的 `mem-compact-*` 身份;单条精简保持原 ID,多条合并选择一个稳定 survivor。
427
438
  - 这些维护动作在正常 `process()` / `remember()` / `compact()` 生命周期中执行,不需要 daemon;普通只读检索本身不触发维护写入。
@@ -0,0 +1,129 @@
1
+ # Acceptance evidence guide — fixed candidate, separate gates
2
+
3
+ This is an operator/evidence guide, not a new runtime, model prompt, test harness,
4
+ or permission to change a live Vault. Keep the exact acceptance commit and its
5
+ CI artifacts fixed while evaluating it. If an actual defect requires a code
6
+ change, record a new commit and rerun affected gates; do not mix their results.
7
+
8
+ ## Gates and completion evidence
9
+
10
+ | Gate | Evidence required | What it does not establish |
11
+ |---|---|---|
12
+ | Repository identity | Actual remote commit, full tree, parent, branch | Passing tests, installation or release |
13
+ | Source and native artifacts | Source report; each existing native CI cell's wheel/sdist reports; matching commit, manifest, full test inventory and payload hashes | Real Hermes/Codex lifecycle or model semantic fidelity |
14
+ | Deterministic requirement clauses | Original requirement, exact test method and assertions, executed evidence on the fixed candidate, explicit limitations | Entire requirement signed off merely because a related module ran |
15
+ | Real installed host | Executable/version, copied Provider build, actual test Vault and effective routes, capture/final/source-time flow, reconnect, privacy and shared retrieval | Model quality based only on a stub response or tool discovery |
16
+ | Live Flash semantics | Approved configured route, permitted suite and holdout provenance, total reservation limit, all attempted repetitions, structural results plus human/source-based semantic review | A JSON-only pass or exact provider billing from a reserved slot |
17
+ | Controlled migration/rollback | Known writers actually stopped, verified current backup, retained authority and latest Forget boundary, isolated rehearsal | Automated restore, distributed consistency or production authorization |
18
+
19
+ A test that intentionally expects a refusal validates that protection, not a
20
+ successful extraction. NO_MEMORY may be correct, but cannot be used as a blanket
21
+ way to eliminate necessary memories. Keep pending, scan completeness, semantic
22
+ quality and successful writes separate. Never mark all FS001–FS200 complete from
23
+ the suite count or from module-name references.
24
+
25
+ ## Current route semantics
26
+
27
+ The v0.2.67 candidate has one processing engine: incremental. New Vaults default
28
+ both `process.automatic_pipeline` and `process.remember_pipeline` to
29
+ `incremental`. A retained `legacy` value from an older Vault is not executable;
30
+ migration preflight reports it as `legacy_pipeline_configuration`, and runtime
31
+ entry points reject it with `legacy_pipeline_removed`.
32
+
33
+ A successfully installed candidate is still not proof that production migration is
34
+ safe. Existing legacy queue/control records retain their identity for diagnosis and
35
+ must be settled or explicitly reviewed; they are not reinterpreted as incremental
36
+ work. Do not erase old work, failed receipts or request counters to obtain a clean
37
+ preflight result.
38
+
39
+ ## Preparation with no paid calls
40
+
41
+ Use the existing entry point on a known candidate installation:
42
+
43
+ ```sh
44
+ python -m memleaf.acceptance --suite examples/incremental_acceptance.json --repeat 5
45
+ ```
46
+
47
+ This is plan-only: it validates the suite and reports hashes and request bounds;
48
+ it does not load a backend configuration or create a Vault. `process --dry-run`
49
+ is different and may call the configured model. Do not use it as a free preview.
50
+
51
+ The shipped suite is public synthetic regression material. Take case count, turn
52
+ count, repetitions, normalized suite hash, prompt hash and request bounds from
53
+ this command on the selected candidate; do not inherit numbers from an older
54
+ report. Also record the original suite file SHA-256: it is not the normalized
55
+ semantic suite hash. The reported bound is not a spending authorization. A private
56
+ held-out suite requires its own provenance, permission and count. Merely adding
57
+ a label `holdout` does not prove the examples were unseen in tuning.
58
+
59
+ Do not execute until the actual route/model, local credential reference, suite
60
+ hash, repeats and total allowance are approved. Keep credentials local. Do not
61
+ paste API keys or credential-bearing URLs into chat, public issues or logs. All
62
+ trials, including failed, interrupted and budget-limited ones, remain in the
63
+ report. Starting a new output directory is not an unmetered retry.
64
+
65
+ ## Bind evidence without manufacturing a pass
66
+
67
+ Keep an external acceptance record containing repository commit and tree, CI run
68
+ and attempt, manifest digest, wheel/sdist digests, executed test inventory, exact
69
+ requirement clauses, host identities, effective routes and suite/budget approval.
70
+ A rerun has a new attempt; an assertion change has a new source identity even
71
+ when test IDs/count are unchanged. Never substitute another attempt's missing
72
+ stage report. A green workflow summary is not a replacement for the reports.
73
+
74
+ A documentation-only follow-up still has a new repository tree and sdist bytes.
75
+ Previous CI remains evidence for its original commit. Record that the runtime and
76
+ test bytes are unchanged, but do not relabel that CI as a run of the follow-up.
77
+ Do not overwrite a published artifact with a same-version development artifact.
78
+
79
+ A requirement record should name its original assertion, tested subclause, exact
80
+ test method, source digest, execution report, result and remaining boundary. A
81
+ failed platform cell cannot be signed off because another platform passed.
82
+ Classify untested semantic/host assertions explicitly rather than converting them
83
+ to a static-code pass. Link any later repair to its new test evidence.
84
+
85
+ ## Host preparation and privacy
86
+
87
+ Read the installed host's actual help and configuration; do not invent isolation
88
+ flags. Inventory versions and safe effective settings before starting sessions.
89
+ A host may make model requests during a session, so no live session or extraction
90
+ is implied by a request for zero-call preparation. If host profiles cannot be
91
+ isolated without touching production, stop that part and report the limitation.
92
+
93
+ Prepare an independent environment and an empty synthetic test Vault only after
94
+ its path and isolation are clear. Do not copy a formal Vault, native notes or
95
+ real chat archive merely to make a fixture. Use synthetic native files for initial
96
+ share/read-only tests. Private incident material must be separately approved.
97
+
98
+ For real acceptance, source labels alone (`hermes`/`codex`) do not prove the actual
99
+ host ran. Record actual process/configuration and behavior. Test one complete
100
+ automatic turn as user input plus trusted final assistant reply; prove that a
101
+ previous settled turn is not silently copied into the normal prompt, while the
102
+ assistant's current-turn restatement can resolve a user's shorthand choice. Also
103
+ test a genuinely non-self-contained turn and require conservative deferral rather
104
+ than guessed history. Verify durable NO_MEMORY settlement, authentic available
105
+ source metadata, final versus intermediate messages, stop-recording and late
106
+ callbacks, shared search/read, repeat/new intent, same-ID state changes and
107
+ restarts. Missing original time stays unknown, not fabricated.
108
+
109
+ ## Migration and release boundaries
110
+
111
+ `migration_preflight()` is an observation. `writers_stopped=True` is an operator
112
+ attestation, not process-discovery proof. Preflight/backup verification do not
113
+ perform a full apply/restore or stop old programs. Known writer shutdown and
114
+ reopening must be verified independently on the isolated installation.
115
+
116
+ A valid old backup may contain content forgotten later. Do not restore it for
117
+ service without preserving and applying the available later Forget/authority
118
+ constraints under explicit permission. A code rollback that keeps current data
119
+ and uses a verified compatible read path is not a full snapshot restore.
120
+
121
+ Full destructive authority TTL, cross-Vault merge, general multi-ID semantic
122
+ merge, automatic native-conflict resolution and cross-machine coordination
123
+ remain outside the first-enabled scope. Keep those limits explicit; they cannot
124
+ be reported as implemented features. Release/tag/version changes, main merge
125
+ and production operations each retain their own authorization boundary.
126
+
127
+ The [host acceptance runbook](host-acceptance-runbook.md) separates inventory,
128
+ authorized sessions and cold-cutover rehearsal. It does not require a new
129
+ installer, adapter or verification framework.