AbstractMemory 0.3.0__tar.gz → 0.3.2__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 (225) hide show
  1. abstractmemory-0.3.2/.gitignore +31 -0
  2. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/CHANGELOG.md +31 -0
  3. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/PKG-INFO +3 -3
  4. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/README.md +1 -1
  5. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/api.md +4 -2
  6. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/architecture.md +1 -1
  7. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/faq.md +2 -2
  8. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/stores.md +1 -0
  9. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/troubleshooting.md +1 -1
  10. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/llms-full.txt +10 -7
  11. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/llms.txt +1 -1
  12. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/pyproject.toml +1 -1
  13. abstractmemory-0.3.2/release-notes.md +13 -0
  14. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/in_memory_store.py +23 -0
  15. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/journal.py +14 -4
  16. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/sqlite_store.py +35 -1
  17. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/system.py +2 -1
  18. abstractmemory-0.3.2/tests/test_close_assertion.py +88 -0
  19. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_journal_backends.py +15 -0
  20. abstractmemory-0.3.0/.abstractcode/agora.state.config.json +0 -17
  21. abstractmemory-0.3.0/.agora/seat.json +0 -10
  22. abstractmemory-0.3.0/.codex/config.toml +0 -11
  23. abstractmemory-0.3.0/.gitignore +0 -11
  24. abstractmemory-0.3.0/AGENTS.md +0 -53
  25. abstractmemory-0.3.0/release-notes.md +0 -88
  26. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  27. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/.github/workflows/ci.yml +0 -0
  28. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/.github/workflows/release.yml +0 -0
  29. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/ACKNOWLEDGMENTS.md +0 -0
  30. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/CODE_OF_CONDUCT.md +0 -0
  31. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/CONTRIBUTING.md +0 -0
  32. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/LICENSE +0 -0
  33. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/SECURITY.md +0 -0
  34. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/README.md +0 -0
  35. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/completed/0008_gateway_memory_install_and_config_boundary.md +0 -0
  36. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/completed/002_sqlite_database_compatibility_and_store_capabilities.md +0 -0
  37. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/completed/004_recall_trace_and_access_events_contract.md +0 -0
  38. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/completed/005_source_linked_summaries_and_derived_assertion_lineage.md +0 -0
  39. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/completed/007_read_only_memory_observer_contract.md +0 -0
  40. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/completed/extension_wave/0037_familiarity_metamemory_read.md +0 -0
  41. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/completed/extension_wave/0038_open_commitments_and_triggers.md +0 -0
  42. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/completed/extension_wave/0039_tend_election_grammar.md +0 -0
  43. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/completed/extension_wave/0049_stable_shelf_order_for_prefix_reuse.md +0 -0
  44. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/completed/memory_system_v1/0009_assertion_identity_and_batch_read_contract.md +0 -0
  45. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/completed/memory_system_v1/0010_append_only_closure_records_for_retract_and_supersede.md +0 -0
  46. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/completed/memory_system_v1/0011_cross_backend_parity_conformance_suite.md +0 -0
  47. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/completed/memory_system_v1/0013_store_concurrency_and_thread_safety_contract.md +0 -0
  48. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/completed/memory_system_v1/0014_embedding_space_integrity_manifest.md +0 -0
  49. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/completed/memory_system_v1/0017_memory_journal_and_scope_bindings_layer.md +0 -0
  50. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/completed/memory_system_v1/0018_neurotransmitter_attention_strengthen_weaken_decay.md +0 -0
  51. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/completed/memory_system_v1/0019_hybrid_retrieval_channels_fts_vector_exact.md +0 -0
  52. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/completed/memory_system_v1/0020_reconstruction_shelf_and_selection_traces.md +0 -0
  53. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/completed/memory_system_v1/0021_memory_records_and_remember_api.md +0 -0
  54. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/completed/memory_system_v1/0022_probe_and_bounded_source_expansion.md +0 -0
  55. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/completed/memory_system_v1/0023_maintenance_sleep_consolidate_dream.md +0 -0
  56. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/completed/memory_system_v1/0024_memory_system_facade_and_consumer_migration.md +0 -0
  57. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/completed/memory_system_v1/0025_graph_backend_decision_record_memgraph_rejected.md +0 -0
  58. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/completed/memory_system_v1/0026_spreading_activation_and_working_set.md +0 -0
  59. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/completed/memory_system_v1/0027_runtime_seam_contract_v1.md +0 -0
  60. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/completed/memory_system_v1/0029_sleep_reactivity_dreams_as_reaction.md +0 -0
  61. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/completed/memory_system_v1/0030_fork_comparison_adoption_wave.md +0 -0
  62. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/completed/memory_system_v1/0031_second_fork_pass_and_lifecycle_closure.md +0 -0
  63. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/completed/memory_system_v1/0036_third_pass_extension_wave.md +0 -0
  64. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/completed/subconscious_wave/0032_dream_subconscious_lifecycle.md +0 -0
  65. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/completed/subconscious_wave/0033_world_model_orientation_cards.md +0 -0
  66. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/completed/subconscious_wave/0034_situate_temporal_relational_reconstruction.md +0 -0
  67. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/completed/subconscious_wave/0035_lessons_layer_conventions.md +0 -0
  68. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/deprecated/001_semantics_aligned_memory_record_conventions.md +0 -0
  69. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/deprecated/003_bounded_graph_traversal_over_triples.md +0 -0
  70. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/deprecated/006_deterministic_anchor_and_facet_index.md +0 -0
  71. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/overview.md +0 -0
  72. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/planned/extension_wave/README.md +0 -0
  73. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/planned/subconscious_wave/README.md +0 -0
  74. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/proposed/extension_wave/0040_recurrence_probe_and_presentation_fold.md +0 -0
  75. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/proposed/extension_wave/0041_loss_absence_anchors.md +0 -0
  76. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/proposed/extension_wave/0042_explain_recall_serving_contract.md +0 -0
  77. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/proposed/extension_wave/0043_mind_health_report.md +0 -0
  78. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/proposed/extension_wave/0044_origin_time_axis_for_imports.md +0 -0
  79. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/proposed/extension_wave/0045_n_party_memory_contract.md +0 -0
  80. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/proposed/extension_wave/0046_transcript_adoption_verb.md +0 -0
  81. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/proposed/extension_wave/0047_cue_hygiene_at_recall_boundary.md +0 -0
  82. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/proposed/extension_wave/0048_writer_forensics_for_homes.md +0 -0
  83. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/proposed/extension_wave/README.md +0 -0
  84. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/proposed/memory_system_v1/0012_lancedb_backend_hardening_and_explicit_schema.md +0 -0
  85. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/proposed/memory_system_v1/0015_capabilities_extensions_and_deterministic_export_import.md +0 -0
  86. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/proposed/memory_system_v1/0016_semantics_vocabulary_validation_and_aliasing_module.md +0 -0
  87. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/proposed/memory_system_v1/0028_lateral_inhibition_theory.md +0 -0
  88. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/backlog/proposed/memory_system_v1/README.md +0 -0
  89. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/development.md +0 -0
  90. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/getting-started.md +0 -0
  91. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/memory-system.md +0 -0
  92. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/docs/operator.md +0 -0
  93. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/examples/entity_home_maintenance_proof.py +0 -0
  94. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/examples/realistic_session.py +0 -0
  95. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/__init__.py +0 -0
  96. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/alive_drives.py +0 -0
  97. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/archive_import.py +0 -0
  98. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/attention.py +0 -0
  99. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/candidate_miner.py +0 -0
  100. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/canonical_text.py +0 -0
  101. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/channels.py +0 -0
  102. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/cognition_health.py +0 -0
  103. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/concept_anchor.py +0 -0
  104. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/consolidation.py +0 -0
  105. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/diary.py +0 -0
  106. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/disposal.py +0 -0
  107. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/doctoring.py +0 -0
  108. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/dream_resolution.py +0 -0
  109. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/dream_signals.py +0 -0
  110. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/drive_grouping.py +0 -0
  111. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/drive_pressure.py +0 -0
  112. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/embedding_pin.py +0 -0
  113. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/embeddings.py +0 -0
  114. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/embeddings_openai_compat.py +0 -0
  115. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/engine_manifest.py +0 -0
  116. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/engram.py +0 -0
  117. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/entity_card.py +0 -0
  118. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/feelings_reads.py +0 -0
  119. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/folds.py +0 -0
  120. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/gradation.py +0 -0
  121. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/identity_review.py +0 -0
  122. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/journal_common.py +0 -0
  123. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/journal_memory.py +0 -0
  124. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/journal_sqlite.py +0 -0
  125. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/journal_sqlite_rows.py +0 -0
  126. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/lancedb_store.py +0 -0
  127. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/maintenance.py +0 -0
  128. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/mind_mass.py +0 -0
  129. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/models.py +0 -0
  130. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/origin_diversity.py +0 -0
  131. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/probe.py +0 -0
  132. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/recall_reads.py +0 -0
  133. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/recent_records.py +0 -0
  134. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/reconstruct.py +0 -0
  135. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/records.py +0 -0
  136. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/redigestion.py +0 -0
  137. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/reembed.py +0 -0
  138. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/render_order.py +0 -0
  139. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/replay.py +0 -0
  140. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/seam.py +0 -0
  141. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/selection.py +0 -0
  142. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/self_component.py +0 -0
  143. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/shelf.py +0 -0
  144. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/situate.py +0 -0
  145. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/sleep_cadence.py +0 -0
  146. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/sleep_policy.py +0 -0
  147. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/spark.py +0 -0
  148. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/spreading.py +0 -0
  149. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/store.py +0 -0
  150. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/system_access.py +0 -0
  151. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/system_valence.py +0 -0
  152. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/tend.py +0 -0
  153. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/text_tokens.py +0 -0
  154. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/vector_scoring.py +0 -0
  155. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/world_model.py +0 -0
  156. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/src/abstractmemory/world_model_alias.py +0 -0
  157. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/conftest.py +0 -0
  158. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/golden/pre_identity_wave_result.json +0 -0
  159. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/realistic_fixtures.py +0 -0
  160. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_access_counts.py +0 -0
  161. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_alive_drives.py +0 -0
  162. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_anchored_summon.py +0 -0
  163. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_archive_import.py +0 -0
  164. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_attention.py +0 -0
  165. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_audit_wave.py +0 -0
  166. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_binding_visibility.py +0 -0
  167. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_candidate_miner.py +0 -0
  168. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_clean_owner_keys.py +0 -0
  169. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_co_use_trails.py +0 -0
  170. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_cognition_health.py +0 -0
  171. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_commitments.py +0 -0
  172. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_consolidation.py +0 -0
  173. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_disposal.py +0 -0
  174. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_doctoring.py +0 -0
  175. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_dream_resolution.py +0 -0
  176. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_dream_signals.py +0 -0
  177. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_drive_grouping.py +0 -0
  178. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_drive_pressure.py +0 -0
  179. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_embedding_pin.py +0 -0
  180. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_engine_manifest.py +0 -0
  181. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_engram.py +0 -0
  182. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_entity_card.py +0 -0
  183. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_explain_recall.py +0 -0
  184. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_familiarity.py +0 -0
  185. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_feelings_reads.py +0 -0
  186. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_gradation.py +0 -0
  187. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_home_lease_contract.py +0 -0
  188. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_identity_review.py +0 -0
  189. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_identity_self.py +0 -0
  190. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_in_memory_query_text_fallback.py +0 -0
  191. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_keyword_fts.py +0 -0
  192. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_lancedb_triple_store.py +0 -0
  193. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_lessons_layer.py +0 -0
  194. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_maintenance.py +0 -0
  195. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_mind_mass.py +0 -0
  196. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_origin_diversity.py +0 -0
  197. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_participants_channel.py +0 -0
  198. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_phase_artifact_pin.py +0 -0
  199. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_probe.py +0 -0
  200. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_realistic_lmstudio.py +0 -0
  201. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_recall_reads.py +0 -0
  202. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_recent_records.py +0 -0
  203. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_reconstruct.py +0 -0
  204. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_records.py +0 -0
  205. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_redigestion.py +0 -0
  206. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_render_order.py +0 -0
  207. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_replay.py +0 -0
  208. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_replay_idempotency.py +0 -0
  209. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_review_wave.py +0 -0
  210. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_seam_addendum.py +0 -0
  211. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_seam_contracts.py +0 -0
  212. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_situate.py +0 -0
  213. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_spark.py +0 -0
  214. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_spreading.py +0 -0
  215. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_sqlite_triple_store.py +0 -0
  216. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_stm_union.py +0 -0
  217. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_store_vectors.py +0 -0
  218. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_system.py +0 -0
  219. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_tend.py +0 -0
  220. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_term_canonicalization.py +0 -0
  221. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_triple_store_limits.py +0 -0
  222. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_two_sided_visit_contract.py +0 -0
  223. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_valence_gradation.py +0 -0
  224. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_world_model.py +0 -0
  225. {abstractmemory-0.3.0 → abstractmemory-0.3.2}/tests/test_world_model_alias.py +0 -0
@@ -0,0 +1,31 @@
1
+ __pycache__/
2
+ *.pyc
3
+ .pytest_cache/
4
+ .DS_Store
5
+ .venv/
6
+ dist/
7
+ build/
8
+ .mypy_cache/
9
+ .ruff_cache/
10
+ untracked/
11
+ .cursor/
12
+
13
+ # ---------------------------------------------------------------------------
14
+ # Agent harness and local tooling
15
+ #
16
+ # This repository is worked on with coding agents, and their configuration
17
+ # embeds absolute local paths, hook commands, seat identities and empty API-key
18
+ # slots. A `.claude/settings.json` in particular defines hooks that execute in
19
+ # any contributor's session on clone. None of it belongs in a public repository,
20
+ # and it was tracked once — this block is what stops that recurring.
21
+ # ---------------------------------------------------------------------------
22
+ .claude/
23
+ .codex/
24
+ .cursor/
25
+ .agora/
26
+ .abstractcode/
27
+ .mcp.json
28
+ CLAUDE.md
29
+ untracked/
30
+ .venv/
31
+ AGENTS.md
@@ -9,6 +9,37 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
9
9
 
10
10
  *No unreleased changes.*
11
11
 
12
+ ## [0.3.2] - 2026-10-20
13
+
14
+ ### Added
15
+
16
+ - **A third closure kind, `reinterpreted`**, for an assertion whose reading was
17
+ superseded by a re-interpretation of its source: the writer no longer reads
18
+ that source this way (for example, AbstractNote understanding a note again
19
+ against an earlier foundation withdraws its previous reading). It is neither
20
+ `retract` (the fact was wrong) nor `supersede` (a later fact replaced it).
21
+ `ClosureRecord`, `close_assertions` and `close_record` accept it;
22
+ `replacement_ids` is optional (the new reading's assertions, when there are
23
+ any); like the other kinds, a `reinterpreted` closure takes the assertion out
24
+ of ranked retrieval while it stays in the store and in history. The accepted
25
+ kinds are listed in `abstractmemory.journal.CLOSURE_KINDS`.
26
+ Additive: existing callers and stored journals are unaffected.
27
+
28
+ ## [0.3.1] - 2026-10-19
29
+
30
+ ### Added
31
+
32
+ - **`close_assertion(assertion_id, valid_until)`** on `SQLiteTripleStore` and
33
+ `InMemoryTripleStore`: closes an assertion's open validity window in place
34
+ (only while `valid_until` is still empty; terms, provenance, attributes,
35
+ keyword index and vector are untouched) and returns whether a row changed
36
+ (`False` for an unknown id or a window that is already closed). A writer
37
+ that supersedes a fact can make `TripleQuery(active_at=...)` agree with its
38
+ own belief window, where a layer-2 closure record only reaches ranked
39
+ retrieval. Existing callers are unaffected; `add` stays append-only and
40
+ `LanceDBTripleStore` keeps the protocol surface (`add`, `query`, `close`).
41
+ Contributed by the AbstractNote lane.
42
+
12
43
  ## [0.3.0] - 2026-08-06
13
44
 
14
45
  The first release with **layer 2**: a `MemorySystem` facade that composes the
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: AbstractMemory
3
- Version: 0.3.0
3
+ Version: 0.3.2
4
4
  Summary: AbstractMemory: temporal, provenance-aware semantic memory primitives for AbstractFramework.
5
5
  Project-URL: AbstractFramework (monorepo), https://github.com/lpalbou/abstractframework
6
6
  Author: Laurent-Philippe Albou
@@ -164,7 +164,7 @@ system.commit_selection(result.trace_id, [h.record_id for h in result.handles[:2
164
164
 
165
165
  ## Design principles
166
166
 
167
- - **Append-only, no deletion**: updates are new assertions; belief revision is closure records (retract/supersede); forgetting is decay of retrieval strength plus closures and silencing — the substrate is lossless.
167
+ - **Append-only, no deletion**: updates are new assertions; belief revision is closure records (retract/supersede/reinterpreted); forgetting is decay of retrieval strength plus closures and silencing — the substrate is lossless.
168
168
  - **Reads are pure**: reconstruction, inspection, replay, and the entity card deposit nothing. `commit_selection` is the only strengthening path.
169
169
  - **One seq axis**: the journal assigns a monotonic `seq` to every record; any past state is reproducible by anchoring reads at `as_of`.
170
170
  - **Works-or-loud**: degraded paths are labeled `#FALLBACK` in result warnings; invalid inputs raise actionable errors instead of silently meaning something else.
@@ -128,7 +128,7 @@ system.commit_selection(result.trace_id, [h.record_id for h in result.handles[:2
128
128
 
129
129
  ## Design principles
130
130
 
131
- - **Append-only, no deletion**: updates are new assertions; belief revision is closure records (retract/supersede); forgetting is decay of retrieval strength plus closures and silencing — the substrate is lossless.
131
+ - **Append-only, no deletion**: updates are new assertions; belief revision is closure records (retract/supersede/reinterpreted); forgetting is decay of retrieval strength plus closures and silencing — the substrate is lossless.
132
132
  - **Reads are pure**: reconstruction, inspection, replay, and the entity card deposit nothing. `commit_selection` is the only strengthening path.
133
133
  - **One seq axis**: the journal assigns a monotonic `seq` to every record; any past state is reproducible by anchoring reads at `as_of`.
134
134
  - **Works-or-loud**: degraded paths are labeled `#FALLBACK` in result warnings; invalid inputs raise actionable errors instead of silently meaning something else.
@@ -64,6 +64,8 @@ Vector results carry retrieval metadata in `attributes["_retrieval"]` (`score`,
64
64
 
65
65
  `add(assertions) -> list[str]` (returns assertion ids), `query(q) -> list[TripleAssertion]`, `close()`.
66
66
 
67
+ `InMemoryTripleStore` and `SQLiteTripleStore` also expose `close_assertion(assertion_id, valid_until) -> bool`: the one in-place change the stores allow. It sets `valid_until` on an assertion whose window is still open and touches nothing else (terms, provenance, attributes, the keyword index and the stored vector stay as written). It returns `True` when a row changed and `False` for an unknown id or a window that is already closed, so a replay is harmless; an empty `assertion_id` or `valid_until` raises `ValueError`. Use it when a later fact supersedes an earlier one and `TripleQuery(active_at=...)` must stop returning the old row from that moment on. The layer-2 `close_assertions` (below) is a different operation: it appends a closure record and leaves the row's window as written.
68
+
67
69
  - `InMemoryTripleStore(embedder=None)` — dependency-free, volatile, vector-capable.
68
70
  - `SQLiteTripleStore(path, embedder=None)` — persistent single file (stdlib only), structured queries and native vector search. With an embedder, `add(...)` embeds each assertion's canonical text and persists the vector in the same file; files created before the vector column existed upgrade in place on open. Rows added without an embedder stay vectorless (vector queries skip them; layer-2 recall labels the degradation `#FALLBACK`).
69
71
  - `LanceDBTripleStore(uri, embedder=None, ...)` — persistent, vector-capable; requires the optional `lancedb` dependency (constructing without it raises `ImportError` with an install hint).
@@ -133,7 +135,7 @@ Record families (all append-only, all `seq`-stamped by the journal):
133
135
 
134
136
  - `MemoryEvent` — attention events. Scoring kinds: `selected`, `co_selected` (pair trails), `pinned`, `silenced`; decay marker: `refocus`; audit-only (recorded, never scored): `listed`, `shown`, `expanded`, `cited`.
135
137
  - `ScopeBinding` — visibility: `search_state` (`indexed`/`hidden`), `prompt_state` (`active`/`inactive`), `lifecycle`, `source`, `reason`. Latest per `(record_id, scope, owner_id)` wins; `fold_bindings(bindings)` applies that fold.
136
- - `ClosureRecord` — belief lifecycle: `kind` (`retract`/`supersede`), mandatory `reason`, `replacement_ids` (required for supersede).
138
+ - `ClosureRecord` — belief lifecycle: `kind` (`retract`/`supersede`/`reinterpreted`), mandatory `reason`, `replacement_ids` (required for supersede, optional otherwise). `reinterpreted` means the writer no longer reads its source this way (a note understood again): neither a correction nor a later fact; it leaves ranked retrieval like the others.
137
139
  - `ReconstructionTrace` — one recall: fingerprint, searched scopes, candidates, selected/dropped, cues, budgets, admission labels, warnings.
138
140
  - `ActiveMemorySnapshot` — see seam types.
139
141
  - `ValenceEvent` — signed appraisals and standing markers (see valence below).
@@ -184,7 +186,7 @@ Diary formation rules: `kind="diary"` requires `provenance.source` ∈ {`diary-p
184
186
  ### Bindings and closures
185
187
 
186
188
  - `bind(record_id, *, scope, owner_id, search_state, prompt_state="inactive", lifecycle="none", source="operator", reason=None, binding_id=None) -> ScopeBinding` — append a visibility event. A folded `hidden` binding removes the record from ranked retrieval in that scope pair only; re-binding `indexed` restores it. `prompt_state="active"` admits the record into the identity (self) component. Record-level bindings hide the digest and its edge assertions together. Direct `store.query` id lookups bypass folds by design.
187
- - `close_assertions(assertion_ids, *, kind, replacement_ids=(), reason) -> list[str]` — append one closure per assertion (`retract` | `supersede`).
189
+ - `close_assertions(assertion_ids, *, kind, replacement_ids=(), reason) -> list[str]` — append one closure per assertion (`retract` | `supersede` | `reinterpreted`).
188
190
  - `close_record(record_id, *, reason, kind="retract", replacement_ids=()) -> list[str]` — close a whole record (digest and its edges) as one belief-revision act; closure ids are deterministic, so replays dedupe.
189
191
 
190
192
  ### Identity: spark, engram, self core, floors
@@ -62,7 +62,7 @@ The same discipline extends to every derived read: inspection (`activation`, `ac
62
62
  There is no delete surface anywhere in the package:
63
63
 
64
64
  - Updates are new assertions with fresh provenance.
65
- - Belief revision is a `ClosureRecord` (`retract` or `supersede` with replacements) — the old record leaves ranked retrieval but remains in the store and in history.
65
+ - Belief revision is a `ClosureRecord` (`retract`, `supersede` with replacements, or `reinterpreted` when the writer reads the source differently) — the old record leaves ranked retrieval but remains in the store and in history.
66
66
  - Visibility is a `ScopeBinding` fold (latest per record/scope/owner wins): `hidden` removes a record from ranked retrieval in that scope pair only; re-binding `indexed` restores it.
67
67
  - Forgetting is decay of retrieval strength plus closures and silencing. Storage never decays; only the temporal-access signal does. The global access count (`selected_count`) never decays at all.
68
68
 
@@ -38,8 +38,8 @@ Canonicalization (trim + lowercase) is part of the matching contract: it prevent
38
38
 
39
39
  There is no update or delete API, by design:
40
40
 
41
- - At layer 1, represent changes by adding a new assertion with fresh provenance.
42
- - At layer 2, belief revision is a closure record (`close_record` / `close_assertions`: retract or supersede with replacements) — the old record leaves ranked retrieval but stays in the store and in history. Visibility can also be withdrawn per scope with a `hidden` binding and restored with `indexed`.
41
+ - At layer 1, represent changes by adding a new assertion with fresh provenance. When the new assertion supersedes an earlier one, `close_assertion(assertion_id, valid_until)` (in-memory and SQLite stores) closes the earlier validity window in place, so `TripleQuery(active_at=...)` stops returning it from that moment; nothing else about the row changes.
42
+ - At layer 2, belief revision is a closure record (`close_record` / `close_assertions`: retract, supersede with replacements, or reinterpreted when the source is read differently) — the old record leaves ranked retrieval but stays in the store and in history. Visibility can also be withdrawn per scope with a `hidden` binding and restored with `indexed`.
43
43
  - Forgetting is decay of retrieval strength plus closures and silencing. The substrate is lossless; there is no compaction.
44
44
 
45
45
  ## What do `scope` and `owner_id` mean?
@@ -128,6 +128,7 @@ Canonicalization:
128
128
 
129
129
  Append-only:
130
130
  - There is no update/delete API. Represent changes by adding a new `TripleAssertion` with updated fields and fresh provenance.
131
+ - The one in-place change: `InMemoryTripleStore` and `SQLiteTripleStore` offer `close_assertion(assertion_id, valid_until)`, which sets `valid_until` on an assertion whose window is still open (`True` when a row changed; `False` for an unknown id or an already closed window). Every other column, the keyword index and the stored vector stay as written. `LanceDBTripleStore` does not offer it.
131
132
 
132
133
  Timestamps are strings:
133
134
  - All stores compare `observed_at` / `valid_*` as strings.
@@ -70,7 +70,7 @@ explain_recall(store, journal, record_id, trace_id=trace_id)
70
70
  recall_history(journal, record_id)
71
71
  ```
72
72
 
73
- `absence_diagnosis` reports structural reasons in plain sentences (never formed, retracted, hidden, out of scope, vectorless). `explain_recall` answers the same question against one specific recall. Common structural causes: the record is in a scope the ladder does not include; a closure retracted or superseded it; it is an inactive candidate; or it was formed after the `as_of` seq you anchored to.
73
+ `absence_diagnosis` reports structural reasons in plain sentences (never formed, retracted, hidden, out of scope, vectorless). `explain_recall` answers the same question against one specific recall. Common structural causes: the record is in a scope the ladder does not include; a closure retracted, superseded or reinterpreted it; it is an inactive candidate; or it was formed after the `as_of` seq you anchored to.
74
74
 
75
75
  ### Recall results change between runs with the same input
76
76
 
@@ -154,7 +154,7 @@ system.commit_selection(result.trace_id, [h.record_id for h in result.handles[:2
154
154
 
155
155
  ## Design principles
156
156
 
157
- - **Append-only, no deletion**: updates are new assertions; belief revision is closure records (retract/supersede); forgetting is decay of retrieval strength plus closures and silencing — the substrate is lossless.
157
+ - **Append-only, no deletion**: updates are new assertions; belief revision is closure records (retract/supersede/reinterpreted); forgetting is decay of retrieval strength plus closures and silencing — the substrate is lossless.
158
158
  - **Reads are pure**: reconstruction, inspection, replay, and the entity card deposit nothing. `commit_selection` is the only strengthening path.
159
159
  - **One seq axis**: the journal assigns a monotonic `seq` to every record; any past state is reproducible by anchoring reads at `as_of`.
160
160
  - **Works-or-loud**: degraded paths are labeled `#FALLBACK` in result warnings; invalid inputs raise actionable errors instead of silently meaning something else.
@@ -389,7 +389,7 @@ The same discipline extends to every derived read: inspection (`activation`, `ac
389
389
  There is no delete surface anywhere in the package:
390
390
 
391
391
  - Updates are new assertions with fresh provenance.
392
- - Belief revision is a `ClosureRecord` (`retract` or `supersede` with replacements) — the old record leaves ranked retrieval but remains in the store and in history.
392
+ - Belief revision is a `ClosureRecord` (`retract`, `supersede` with replacements, or `reinterpreted` when the writer reads the source differently) — the old record leaves ranked retrieval but remains in the store and in history.
393
393
  - Visibility is a `ScopeBinding` fold (latest per record/scope/owner wins): `hidden` removes a record from ranked retrieval in that scope pair only; re-binding `indexed` restores it.
394
394
  - Forgetting is decay of retrieval strength plus closures and silencing. Storage never decays; only the temporal-access signal does. The global access count (`selected_count`) never decays at all.
395
395
 
@@ -593,6 +593,8 @@ Vector results carry retrieval metadata in `attributes["_retrieval"]` (`score`,
593
593
 
594
594
  `add(assertions) -> list[str]` (returns assertion ids), `query(q) -> list[TripleAssertion]`, `close()`.
595
595
 
596
+ `InMemoryTripleStore` and `SQLiteTripleStore` also expose `close_assertion(assertion_id, valid_until) -> bool`: the one in-place change the stores allow. It sets `valid_until` on an assertion whose window is still open and touches nothing else (terms, provenance, attributes, the keyword index and the stored vector stay as written). It returns `True` when a row changed and `False` for an unknown id or a window that is already closed, so a replay is harmless; an empty `assertion_id` or `valid_until` raises `ValueError`. Use it when a later fact supersedes an earlier one and `TripleQuery(active_at=...)` must stop returning the old row from that moment on. The layer-2 `close_assertions` (below) is a different operation: it appends a closure record and leaves the row's window as written.
597
+
596
598
  - `InMemoryTripleStore(embedder=None)` — dependency-free, volatile, vector-capable.
597
599
  - `SQLiteTripleStore(path, embedder=None)` — persistent single file (stdlib only), structured queries and native vector search. With an embedder, `add(...)` embeds each assertion's canonical text and persists the vector in the same file; files created before the vector column existed upgrade in place on open. Rows added without an embedder stay vectorless (vector queries skip them; layer-2 recall labels the degradation `#FALLBACK`).
598
600
  - `LanceDBTripleStore(uri, embedder=None, ...)` — persistent, vector-capable; requires the optional `lancedb` dependency (constructing without it raises `ImportError` with an install hint).
@@ -662,7 +664,7 @@ Record families (all append-only, all `seq`-stamped by the journal):
662
664
 
663
665
  - `MemoryEvent` — attention events. Scoring kinds: `selected`, `co_selected` (pair trails), `pinned`, `silenced`; decay marker: `refocus`; audit-only (recorded, never scored): `listed`, `shown`, `expanded`, `cited`.
664
666
  - `ScopeBinding` — visibility: `search_state` (`indexed`/`hidden`), `prompt_state` (`active`/`inactive`), `lifecycle`, `source`, `reason`. Latest per `(record_id, scope, owner_id)` wins; `fold_bindings(bindings)` applies that fold.
665
- - `ClosureRecord` — belief lifecycle: `kind` (`retract`/`supersede`), mandatory `reason`, `replacement_ids` (required for supersede).
667
+ - `ClosureRecord` — belief lifecycle: `kind` (`retract`/`supersede`/`reinterpreted`), mandatory `reason`, `replacement_ids` (required for supersede, optional otherwise). `reinterpreted` means the writer no longer reads its source this way (a note understood again): neither a correction nor a later fact; it leaves ranked retrieval like the others.
666
668
  - `ReconstructionTrace` — one recall: fingerprint, searched scopes, candidates, selected/dropped, cues, budgets, admission labels, warnings.
667
669
  - `ActiveMemorySnapshot` — see seam types.
668
670
  - `ValenceEvent` — signed appraisals and standing markers (see valence below).
@@ -713,7 +715,7 @@ Diary formation rules: `kind="diary"` requires `provenance.source` ∈ {`diary-p
713
715
  ### Bindings and closures
714
716
 
715
717
  - `bind(record_id, *, scope, owner_id, search_state, prompt_state="inactive", lifecycle="none", source="operator", reason=None, binding_id=None) -> ScopeBinding` — append a visibility event. A folded `hidden` binding removes the record from ranked retrieval in that scope pair only; re-binding `indexed` restores it. `prompt_state="active"` admits the record into the identity (self) component. Record-level bindings hide the digest and its edge assertions together. Direct `store.query` id lookups bypass folds by design.
716
- - `close_assertions(assertion_ids, *, kind, replacement_ids=(), reason) -> list[str]` — append one closure per assertion (`retract` | `supersede`).
718
+ - `close_assertions(assertion_ids, *, kind, replacement_ids=(), reason) -> list[str]` — append one closure per assertion (`retract` | `supersede` | `reinterpreted`).
717
719
  - `close_record(record_id, *, reason, kind="retract", replacement_ids=()) -> list[str]` — close a whole record (digest and its edges) as one belief-revision act; closure ids are deterministic, so replays dedupe.
718
720
 
719
721
  ### Identity: spark, engram, self core, floors
@@ -1045,6 +1047,7 @@ Canonicalization:
1045
1047
 
1046
1048
  Append-only:
1047
1049
  - There is no update/delete API. Represent changes by adding a new `TripleAssertion` with updated fields and fresh provenance.
1050
+ - The one in-place change: `InMemoryTripleStore` and `SQLiteTripleStore` offer `close_assertion(assertion_id, valid_until)`, which sets `valid_until` on an assertion whose window is still open (`True` when a row changed; `False` for an unknown id or an already closed window). Every other column, the keyword index and the stored vector stay as written. `LanceDBTripleStore` does not offer it.
1048
1051
 
1049
1052
  Timestamps are strings:
1050
1053
  - All stores compare `observed_at` / `valid_*` as strings.
@@ -1276,8 +1279,8 @@ Canonicalization (trim + lowercase) is part of the matching contract: it prevent
1276
1279
 
1277
1280
  There is no update or delete API, by design:
1278
1281
 
1279
- - At layer 1, represent changes by adding a new assertion with fresh provenance.
1280
- - At layer 2, belief revision is a closure record (`close_record` / `close_assertions`: retract or supersede with replacements) — the old record leaves ranked retrieval but stays in the store and in history. Visibility can also be withdrawn per scope with a `hidden` binding and restored with `indexed`.
1282
+ - At layer 1, represent changes by adding a new assertion with fresh provenance. When the new assertion supersedes an earlier one, `close_assertion(assertion_id, valid_until)` (in-memory and SQLite stores) closes the earlier validity window in place, so `TripleQuery(active_at=...)` stops returning it from that moment; nothing else about the row changes.
1283
+ - At layer 2, belief revision is a closure record (`close_record` / `close_assertions`: retract, supersede with replacements, or reinterpreted when the source is read differently) — the old record leaves ranked retrieval but stays in the store and in history. Visibility can also be withdrawn per scope with a `hidden` binding and restored with `indexed`.
1281
1284
  - Forgetting is decay of retrieval strength plus closures and silencing. The substrate is lossless; there is no compaction.
1282
1285
 
1283
1286
  ## What do `scope` and `owner_id` mean?
@@ -1410,7 +1413,7 @@ explain_recall(store, journal, record_id, trace_id=trace_id)
1410
1413
  recall_history(journal, record_id)
1411
1414
  ```
1412
1415
 
1413
- `absence_diagnosis` reports structural reasons in plain sentences (never formed, retracted, hidden, out of scope, vectorless). `explain_recall` answers the same question against one specific recall. Common structural causes: the record is in a scope the ladder does not include; a closure retracted or superseded it; it is an inactive candidate; or it was formed after the `as_of` seq you anchored to.
1416
+ `absence_diagnosis` reports structural reasons in plain sentences (never formed, retracted, hidden, out of scope, vectorless). `explain_recall` answers the same question against one specific recall. Common structural causes: the record is in a scope the ladder does not include; a closure retracted, superseded or reinterpreted it; it is an inactive candidate; or it was formed after the `as_of` seq you anchored to.
1414
1417
 
1415
1418
  ### Recall results change between runs with the same input
1416
1419
 
@@ -6,7 +6,7 @@ Key facts for agents:
6
6
 
7
7
  - The authoritative export list is [src/abstractmemory/__init__.py](src/abstractmemory/__init__.py); [docs/api.md](docs/api.md) documents every export with verified signatures.
8
8
  - Reads are pure: `reconstruct`, inspection, replay, and `entity_card` deposit nothing; `commit_selection` is the only strengthening path.
9
- - Append-only, no deletion: updates are new assertions; belief revision is closure records; forgetting is decay + closures + silencing.
9
+ - Append-only, no deletion: updates are new assertions; belief revision is closure records; forgetting is decay + closures + silencing. The one in-place change is `close_assertion` (in-memory and SQLite stores), which only closes an open validity window.
10
10
  - The journal's monotonic `seq` is the time axis: anchor reads with `as_of`/`at_seq`/`since_seq` for deterministic replay.
11
11
  - All three stores are vector-capable when constructed with an embedder; `query_text` without one raises (no keyword fallback).
12
12
  - Terms are canonicalized (trim + lowercase); timestamps compare as RFC-3339/UTC strings.
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "AbstractMemory"
7
- version = "0.3.0"
7
+ version = "0.3.2"
8
8
  description = "AbstractMemory: temporal, provenance-aware semantic memory primitives for AbstractFramework."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -0,0 +1,13 @@
1
+ ### Added
2
+
3
+ - **A third closure kind, `reinterpreted`**, for an assertion whose reading was
4
+ superseded by a re-interpretation of its source: the writer no longer reads
5
+ that source this way (for example, AbstractNote understanding a note again
6
+ against an earlier foundation withdraws its previous reading). It is neither
7
+ `retract` (the fact was wrong) nor `supersede` (a later fact replaced it).
8
+ `ClosureRecord`, `close_assertions` and `close_record` accept it;
9
+ `replacement_ids` is optional (the new reading's assertions, when there are
10
+ any); like the other kinds, a `reinterpreted` closure takes the assertion out
11
+ of ranked retrieval while it stays in the store and in history. The accepted
12
+ kinds are listed in `abstractmemory.journal.CLOSURE_KINDS`.
13
+ Additive: existing callers and stored journals are unaffected.
@@ -2,6 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  import threading
4
4
  import uuid
5
+ from dataclasses import replace
5
6
  from typing import Any, Iterable, List, Optional, Sequence
6
7
 
7
8
  from .embedding_pin import (
@@ -112,6 +113,28 @@ class InMemoryTripleStore:
112
113
  self._embedder = embedder
113
114
  return len(clean)
114
115
 
116
+ def close_assertion(self, assertion_id: str, valid_until: str) -> bool:
117
+ """Close one assertion's validity window in place (SQLite parity):
118
+ sets `valid_until` only while it is still open; everything else is
119
+ untouched. True when a row changed; False for an unknown id or an
120
+ already-closed window."""
121
+ rid = str(assertion_id or "").strip()
122
+ until = str(valid_until or "").strip()
123
+ if not rid:
124
+ raise ValueError("close_assertion requires an assertion_id")
125
+ if not until:
126
+ raise ValueError("close_assertion requires a valid_until timestamp")
127
+ with self._lock:
128
+ for row in self._rows:
129
+ if row.get("assertion_id") != rid:
130
+ continue
131
+ a = row.get("assertion")
132
+ if not isinstance(a, TripleAssertion) or a.valid_until is not None:
133
+ return False
134
+ row["assertion"] = replace(a, valid_until=until)
135
+ return True
136
+ return False
137
+
115
138
  def close(self) -> None:
116
139
  return None
117
140
 
@@ -221,12 +221,22 @@ class ScopeBinding:
221
221
  return _jsonify(asdict(self))
222
222
 
223
223
 
224
+ #: The closure kinds a ClosureRecord accepts (``reinterpreted`` is additive, 0.3.2).
225
+ CLOSURE_KINDS = frozenset({"retract", "supersede", "reinterpreted"})
226
+
227
+
224
228
  @dataclass(frozen=True)
225
229
  class ClosureRecord:
226
- """Append-only belief-lifecycle record (backlog 0010): retract or supersede."""
230
+ """Append-only belief-lifecycle record (backlog 0010): retract, supersede or reinterpreted.
231
+
232
+ ``reinterpreted`` (additive, 0.3.2): the writer no longer reads its source this way (AbstractNote ADR 0008: a
233
+ note understood again against an earlier foundation withdraws its previous reading). It is neither a
234
+ correction of the fact (``retract``) nor a later fact replacing it (``supersede``); like both it leaves
235
+ ranked retrieval. ``replacement_ids`` is optional (the new reading's assertions, when there are any).
236
+ """
227
237
 
228
238
  assertion_id: str
229
- kind: str # retract | supersede
239
+ kind: str # retract | supersede | reinterpreted
230
240
  reason: str
231
241
  replacement_ids: Tuple[str, ...] = ()
232
242
  observed_at: str = field(default_factory=utc_now_iso)
@@ -240,8 +250,8 @@ class ClosureRecord:
240
250
  raise ValueError("ClosureRecord requires assertion_id")
241
251
  object.__setattr__(self, "assertion_id", self.assertion_id.strip())
242
252
  kind = str(self.kind or "").strip().lower()
243
- if kind not in {"retract", "supersede"}:
244
- raise ValueError("ClosureRecord.kind must be 'retract' or 'supersede'")
253
+ if kind not in CLOSURE_KINDS:
254
+ raise ValueError("ClosureRecord.kind must be 'retract', 'supersede' or 'reinterpreted'")
245
255
  object.__setattr__(self, "kind", kind)
246
256
  if not (isinstance(self.reason, str) and self.reason.strip()):
247
257
  raise ValueError("ClosureRecord requires a non-empty reason")
@@ -51,7 +51,8 @@ class SQLiteTripleStore:
51
51
 
52
52
  Notes:
53
53
  - Uses stdlib `sqlite3` (portable; no daemon).
54
- - Append-only: there is no update/delete API (see AbstractMemory FAQ).
54
+ - Append-only: there is no update/delete API (see AbstractMemory FAQ),
55
+ except `close_assertion`, which only closes an open validity window.
55
56
  - VECTORS (a2a 0003, the entity-home pairing): pass `embedder=` and each
56
57
  added assertion's canonical text is embedded and persisted in the SAME
57
58
  .sqlite3 file (JSON-encoded `embedding` column; in-place ALTER TABLE
@@ -526,6 +527,39 @@ class SQLiteTripleStore:
526
527
  rows = self._conn.cursor().execute(sql, params).fetchall()
527
528
  return [self._row_to_assertion(r) for r in rows]
528
529
 
530
+ def close_assertion(self, assertion_id: str, valid_until: str) -> bool:
531
+ """Close one assertion's validity window IN PLACE (additive, backlog:
532
+ abstractnote supersession). Sets `valid_until` only while it is still
533
+ open (NULL); every other column — terms, provenance, attributes, the
534
+ FTS row, the vector — is untouched, so the store stays append-only
535
+ for content. Returns True when a row changed, False when the id is
536
+ unknown or the window was already closed (idempotent replays).
537
+
538
+ Why: a later fact superseding an earlier one must make
539
+ `TripleQuery(active_at=...)` agree with the writer's belief window;
540
+ journal closures alone only reach ranked retrieval, never `query`."""
541
+ rid = str(assertion_id or "").strip()
542
+ until = str(valid_until or "").strip()
543
+ if not rid:
544
+ raise ValueError("close_assertion requires an assertion_id")
545
+ if not until:
546
+ raise ValueError("close_assertion requires a valid_until timestamp")
547
+ with self._lock:
548
+ cur = self._conn.cursor()
549
+ cur.execute("BEGIN IMMEDIATE")
550
+ try:
551
+ cur.execute(
552
+ f"UPDATE {self._table} SET valid_until = ? "
553
+ "WHERE assertion_id = ? AND valid_until IS NULL",
554
+ (until, rid),
555
+ )
556
+ changed = int(cur.rowcount or 0) > 0
557
+ cur.execute("COMMIT")
558
+ except BaseException:
559
+ cur.execute("ROLLBACK")
560
+ raise
561
+ return changed
562
+
529
563
  def replace_vectors(
530
564
  self, vectors: dict, pin: dict, *,
531
565
  expected_row_count: int, embedder: Optional[TextEmbedder] = None,
@@ -853,7 +853,8 @@ class MemorySystem(ValenceOps, AccessOps):
853
853
  replacement_ids: Sequence[str] = (),
854
854
  reason: str,
855
855
  ) -> List[str]:
856
- """Append one ClosureRecord per assertion (retract | supersede);
856
+ """Append one ClosureRecord per assertion (retract | supersede |
857
+ reinterpreted);
857
858
  returns closure ids. Supersede requires replacement_ids; reason is
858
859
  mandatory — validated by ClosureRecord BEFORE any append. A multi-
859
860
  assertion supersede shares one replacement set. Accepts either id
@@ -0,0 +1,88 @@
1
+ """close_assertion: the one in-place change both triple stores allow.
2
+
3
+ It closes an open validity window and nothing else, so TripleQuery(active_at=...)
4
+ agrees with a writer that superseded a fact (AbstractNote supersession)."""
5
+ from __future__ import annotations
6
+
7
+ from pathlib import Path
8
+
9
+ import pytest
10
+
11
+ from abstractmemory import InMemoryTripleStore, SQLiteTripleStore, TripleAssertion, TripleQuery
12
+
13
+
14
+ def _stores(tmp_path: Path):
15
+ return [InMemoryTripleStore(), SQLiteTripleStore(tmp_path / "kg.sqlite3")]
16
+
17
+
18
+ def _fact(aid: str, obj: str, valid_from: str, **kw) -> TripleAssertion:
19
+ return TripleAssertion(
20
+ subject="ex:person-dana", predicate="schema:worksFor", object=obj, scope="global",
21
+ owner_id="abstractnote", observed_at=valid_from, valid_from=valid_from,
22
+ assertion_id=aid, provenance={"note_id": "nt_x"}, attributes={"certainty": "stated"}, **kw,
23
+ )
24
+
25
+
26
+ @pytest.mark.parametrize("which", [0, 1])
27
+ def test_close_assertion_closes_open_window_only(tmp_path: Path, which: int) -> None:
28
+ store = _stores(tmp_path)[which]
29
+ store.add([_fact("cl_1", "ex:org-acme", "2026-01-01T00:00:00+00:00"),
30
+ _fact("cl_2", "ex:org-beta", "2026-06-01T00:00:00+00:00")])
31
+
32
+ before = store.query(TripleQuery(active_at="2026-07-01T00:00:00+00:00", owner_id="abstractnote"))
33
+ assert {a.assertion_id for a in before} == {"cl_1", "cl_2"}
34
+
35
+ assert store.close_assertion("cl_1", "2026-06-01T00:00:00+00:00") is True
36
+ # Already closed: no change, the first window stands.
37
+ assert store.close_assertion("cl_1", "2027-01-01T00:00:00+00:00") is False
38
+ assert store.close_assertion("cl_missing", "2027-01-01T00:00:00+00:00") is False
39
+
40
+ after = store.query(TripleQuery(active_at="2026-07-01T00:00:00+00:00", owner_id="abstractnote"))
41
+ assert {a.assertion_id for a in after} == {"cl_2"}
42
+ earlier = store.query(TripleQuery(active_at="2026-03-01T00:00:00+00:00", owner_id="abstractnote"))
43
+ assert {a.assertion_id for a in earlier} == {"cl_1"}
44
+
45
+ [closed] = store.query(TripleQuery(assertion_ids=("cl_1",)))
46
+ assert closed.valid_until == "2026-06-01T00:00:00+00:00"
47
+ # Everything else is untouched.
48
+ assert closed.object == "ex:org-acme"
49
+ assert closed.provenance == {"note_id": "nt_x"}
50
+ assert closed.attributes.get("certainty") == "stated"
51
+ assert closed.valid_from == "2026-01-01T00:00:00+00:00"
52
+ store.close()
53
+
54
+
55
+ def test_close_assertion_persists_and_keeps_vectors_and_fts(tmp_path: Path) -> None:
56
+ class Emb:
57
+ model_id = "unit-test"
58
+
59
+ def embed_texts(self, texts):
60
+ return [[1.0, float(len(t) % 7), 0.5] for t in texts]
61
+
62
+ db = tmp_path / "kg.sqlite3"
63
+ store = SQLiteTripleStore(db, embedder=Emb())
64
+ store.add([TripleAssertion(
65
+ subject="ex:person-dana", predicate="schema:worksFor", object="ex:org-acme", scope="global",
66
+ owner_id="abstractnote", observed_at="2026-01-01T00:00:00+00:00",
67
+ valid_from="2026-01-01T00:00:00+00:00", assertion_id="cl_1",
68
+ attributes={"evidence_quote": "Dana joined Acme"})])
69
+ vec_before = store.stored_vector("cl_1")
70
+ assert store.close_assertion("cl_1", "2026-02-01T00:00:00+00:00")
71
+ assert store.stored_vector("cl_1") == vec_before
72
+ hits = store.query_keywords(["acme"], scope="global", owner_id="abstractnote")
73
+ assert [h.assertion_id for h in hits] == ["cl_1"]
74
+ store.close()
75
+
76
+ reopened = SQLiteTripleStore(db, embedder=Emb())
77
+ [row] = reopened.query(TripleQuery(assertion_ids=("cl_1",)))
78
+ assert row.valid_until == "2026-02-01T00:00:00+00:00"
79
+ reopened.close()
80
+
81
+
82
+ @pytest.mark.parametrize("which", [0, 1])
83
+ def test_close_assertion_rejects_empty_arguments(tmp_path: Path, which: int) -> None:
84
+ store = _stores(tmp_path)[which]
85
+ with pytest.raises(ValueError):
86
+ store.close_assertion("", "2026-01-01T00:00:00+00:00")
87
+ with pytest.raises(ValueError):
88
+ store.close_assertion("cl_1", "")
@@ -462,6 +462,21 @@ def test_record_validation_errors_surface() -> None:
462
462
  make_event(kind="co_selected", pair_ids=("rec-a", "rec-a"))
463
463
 
464
464
 
465
+ def test_reinterpreted_closure_kind(journal) -> None:
466
+ """Additive closure kind (0.3.2): a source read again withdraws its previous reading; replacements optional."""
467
+ from abstractmemory.journal import CLOSURE_KINDS
468
+
469
+ assert "reinterpreted" in CLOSURE_KINDS
470
+ journal.append_closure(make_closure(assertion_id="as-r", kind="reinterpreted", reason="read again"))
471
+ journal.append_closure(make_closure(assertion_id="as-s", kind="REINTERPRETED", reason="read again",
472
+ replacement_ids=("as-t",)))
473
+ got = {c.assertion_id: c for c in journal.closures()}
474
+ assert got["as-r"].kind == "reinterpreted" and got["as-r"].replacement_ids == ()
475
+ assert got["as-s"].kind == "reinterpreted" and got["as-s"].replacement_ids == ("as-t",)
476
+ with pytest.raises(ValueError, match="kind"):
477
+ make_closure(kind="revised")
478
+
479
+
465
480
  # ---------------------------------------------------------------------------
466
481
  # JSON round-trip
467
482
  # ---------------------------------------------------------------------------
@@ -1,17 +0,0 @@
1
- {
2
- "mcp_servers": {
3
- "agora": {
4
- "transport": "stdio",
5
- "command": [
6
- "/Users/albou/.local/share/uv/tools/agorahub/bin/agora-mcp"
7
- ],
8
- "env": {
9
- "AGORA_URL": "http://127.0.0.1:8765",
10
- "AGORA_AGENT_ID": "memory",
11
- "AGORA_ABOUT": "",
12
- "AGORA_API_KEY": "",
13
- "AGORA_ADMIN_KEY": ""
14
- }
15
- }
16
- }
17
- }
@@ -1,10 +0,0 @@
1
- {
2
- "schema": 1,
3
- "agent_id": "memory",
4
- "url": "http://127.0.0.1:8765",
5
- "about": "",
6
- "harnesses": [
7
- "abstractcode"
8
- ],
9
- "default_drive_harness": "abstractcode"
10
- }
@@ -1,11 +0,0 @@
1
- [mcp_servers.agora]
2
- command = "/Users/albou/.local/share/uv/tools/agorahub/bin/agora-mcp"
3
- required = true
4
- default_tools_approval_mode = "approve"
5
-
6
- [mcp_servers.agora.env]
7
- AGORA_URL = "http://127.0.0.1:8765"
8
- AGORA_AGENT_ID = "memory"
9
- AGORA_ABOUT = ""
10
- AGORA_API_KEY = ""
11
- AGORA_ADMIN_KEY = ""
@@ -1,11 +0,0 @@
1
- __pycache__/
2
- *.pyc
3
- .pytest_cache/
4
- .DS_Store
5
- .venv/
6
- dist/
7
- build/
8
- .mypy_cache/
9
- .ruff_cache/
10
- untracked/
11
- .cursor/