AbstractMemory 0.3.2__tar.gz → 0.5.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/CHANGELOG.md +338 -2
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/PKG-INFO +29 -3
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/README.md +22 -2
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/README.md +1 -0
- abstractmemory-0.5.0/docs/adr/0001-altered-memories-ripple.md +152 -0
- abstractmemory-0.5.0/docs/adr/0002-abstractmemory-owns-the-memory-graph.md +92 -0
- abstractmemory-0.5.0/docs/adr/0003-one-graph-ledger-provenance-and-revisions.md +274 -0
- abstractmemory-0.5.0/docs/adr/README.md +10 -0
- abstractmemory-0.5.0/docs/api.md +642 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/architecture.md +13 -4
- abstractmemory-0.5.0/docs/backlog/completed/knowledge_graph_convergence/0059_record_understanding_rewrites_in_place_with_versions.md +169 -0
- abstractmemory-0.5.0/docs/backlog/completed/knowledge_graph_convergence/0060_memory_task_queue.md +154 -0
- abstractmemory-0.5.0/docs/backlog/completed/knowledge_graph_convergence/0061_ripple_v1_over_the_task_queue.md +123 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/overview.md +109 -22
- abstractmemory-0.5.0/docs/backlog/planned/knowledge_graph_convergence/0050_entity_registry_identity_and_reversible_merges.md +42 -0
- abstractmemory-0.5.0/docs/backlog/planned/knowledge_graph_convergence/0051_claim_lifecycle_and_revision_log.md +39 -0
- abstractmemory-0.5.0/docs/backlog/planned/knowledge_graph_convergence/0052_document_knowledge_retrieval.md +37 -0
- abstractmemory-0.5.0/docs/backlog/planned/knowledge_graph_convergence/0053_self_organisation_communities_consolidation_reflection.md +69 -0
- abstractmemory-0.5.0/docs/backlog/planned/knowledge_graph_convergence/0054_ripple_propagation_and_activation.md +47 -0
- abstractmemory-0.5.0/docs/backlog/planned/knowledge_graph_convergence/0055_notes_and_diary_layer_for_consumers.md +36 -0
- abstractmemory-0.5.0/docs/backlog/planned/knowledge_graph_convergence/0056_ledger_provenance_contract_and_revision_log.md +175 -0
- abstractmemory-0.5.0/docs/backlog/planned/knowledge_graph_convergence/0057_one_mind_per_plane_sqlite_home.md +69 -0
- abstractmemory-0.5.0/docs/backlog/planned/knowledge_graph_convergence/0058_home_store_performance_indexes_vectors.md +148 -0
- abstractmemory-0.5.0/docs/backlog/planned/knowledge_graph_convergence/0059_record_understanding_rewrites_in_place_with_versions.md +1 -0
- abstractmemory-0.5.0/docs/backlog/planned/knowledge_graph_convergence/0060_memory_task_queue.md +1 -0
- abstractmemory-0.5.0/docs/backlog/planned/knowledge_graph_convergence/0061_ripple_v1_over_the_task_queue.md +1 -0
- abstractmemory-0.5.0/docs/backlog/planned/knowledge_graph_convergence/README.md +108 -0
- abstractmemory-0.5.0/docs/backlog/proposed/0062_write_barrier_residual_windows.md +72 -0
- abstractmemory-0.5.0/docs/backlog/proposed/0064_community_facts_merged_into.md +55 -0
- abstractmemory-0.5.0/docs/backlog/proposed/0065_embed_missing_vector_generation_bump_batching.md +57 -0
- abstractmemory-0.5.0/docs/backlog/proposed/0066_placement_index_misses_dissolve_only_versions.md +51 -0
- abstractmemory-0.5.0/docs/backlog/proposed/0067_communities_read_is_not_one_snapshot.md +50 -0
- abstractmemory-0.5.0/docs/backlog/proposed/0068_api_doc_queue_less_list_omits_communities.md +41 -0
- abstractmemory-0.5.0/docs/backlog/proposed/ripple_wave/0001_change_records_and_ripple_primitives.md +37 -0
- abstractmemory-0.5.0/docs/backlog/proposed/ripple_wave/0063_ripple_v1_consumer_seam.md +60 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/faq.md +3 -2
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/getting-started.md +35 -0
- abstractmemory-0.5.0/docs/memory-system.md +148 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/operator.md +1 -1
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/stores.md +44 -6
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/troubleshooting.md +30 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/examples/entity_home_maintenance_proof.py +2 -2
- abstractmemory-0.5.0/llms-full.txt +1974 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/llms.txt +4 -1
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/pyproject.toml +11 -1
- abstractmemory-0.5.0/release-notes.md +188 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/__init__.py +89 -1
- abstractmemory-0.5.0/src/abstractmemory/activation_gate.py +174 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/alive_drives.py +4 -2
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/archive_import.py +5 -22
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/candidate_miner.py +51 -14
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/canonical_text.py +56 -18
- abstractmemory-0.5.0/src/abstractmemory/commit_guard.py +84 -0
- abstractmemory-0.5.0/src/abstractmemory/communities.py +1783 -0
- abstractmemory-0.5.0/src/abstractmemory/community_index.py +884 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/consolidation.py +45 -7
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/diary.py +25 -1
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/doctoring.py +73 -32
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/dream_signals.py +6 -29
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/engram.py +65 -17
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/entity_card.py +68 -15
- abstractmemory-0.5.0/src/abstractmemory/formation_authoring.py +199 -0
- abstractmemory-0.5.0/src/abstractmemory/graph/__init__.py +60 -0
- abstractmemory-0.5.0/src/abstractmemory/graph/backend.py +117 -0
- abstractmemory-0.5.0/src/abstractmemory/graph/graph.py +1372 -0
- abstractmemory-0.5.0/src/abstractmemory/graph/lancedb_backend.py +584 -0
- abstractmemory-0.5.0/src/abstractmemory/graph/provenance.py +323 -0
- abstractmemory-0.5.0/src/abstractmemory/graph/revisions.py +239 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/identity_review.py +3 -1
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/in_memory_store.py +164 -30
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/journal.py +96 -6
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/journal_memory.py +117 -7
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/journal_sqlite.py +196 -68
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/journal_sqlite_rows.py +56 -2
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/lancedb_store.py +22 -3
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/maintenance.py +87 -15
- abstractmemory-0.5.0/src/abstractmemory/memory_tasks.py +1494 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/probe.py +4 -4
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/recall_reads.py +3 -1
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/recent_records.py +2 -2
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/records.py +129 -9
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/redigestion.py +21 -1
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/reembed.py +3 -2
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/replay.py +160 -20
- abstractmemory-0.5.0/src/abstractmemory/ripple.py +561 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/seam.py +1 -1
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/shelf.py +13 -9
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/situate.py +2 -2
- abstractmemory-0.5.0/src/abstractmemory/sleep_cadence.py +687 -0
- abstractmemory-0.5.0/src/abstractmemory/sqlite_store.py +1206 -0
- abstractmemory-0.5.0/src/abstractmemory/store_tuning.py +71 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/system.py +49 -3
- abstractmemory-0.5.0/src/abstractmemory/system_understanding.py +197 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/tend.py +3 -1
- abstractmemory-0.5.0/src/abstractmemory/understanding.py +1728 -0
- abstractmemory-0.5.0/src/abstractmemory/vector_matrix.py +434 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/world_model.py +223 -34
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/world_model_alias.py +99 -4
- abstractmemory-0.5.0/src/abstractmemory/write_barrier.py +246 -0
- abstractmemory-0.5.0/tests/bench/bench_graph.py +210 -0
- abstractmemory-0.5.0/tests/bench/bench_store.py +329 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/conftest.py +3 -1
- abstractmemory-0.5.0/tests/graph_support.py +203 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_archive_import.py +5 -4
- abstractmemory-0.5.0/tests/test_atomic_formation.py +264 -0
- abstractmemory-0.5.0/tests/test_cadence_cursor.py +296 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_candidate_miner.py +4 -2
- abstractmemory-0.5.0/tests/test_commit_guard.py +862 -0
- abstractmemory-0.5.0/tests/test_communities.py +856 -0
- abstractmemory-0.5.0/tests/test_communities_embed_missing.py +187 -0
- abstractmemory-0.5.0/tests/test_communities_never_recalled.py +283 -0
- abstractmemory-0.5.0/tests/test_communities_rounds.py +157 -0
- abstractmemory-0.5.0/tests/test_communities_scale.py +273 -0
- abstractmemory-0.5.0/tests/test_community_placement.py +914 -0
- abstractmemory-0.5.0/tests/test_declare_pending.py +468 -0
- abstractmemory-0.5.0/tests/test_diary_summary_authored.py +444 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_disposal.py +1 -1
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_doctoring.py +42 -1
- abstractmemory-0.5.0/tests/test_dream_pass_signals.py +55 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_dream_resolution.py +1 -1
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_dream_signals.py +6 -19
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_engram.py +208 -27
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_entity_card.py +63 -0
- abstractmemory-0.5.0/tests/test_formation_authoring.py +349 -0
- abstractmemory-0.5.0/tests/test_formation_concurrency.py +296 -0
- abstractmemory-0.5.0/tests/test_graph_conformance.py +354 -0
- abstractmemory-0.5.0/tests/test_graph_e2e.py +197 -0
- abstractmemory-0.5.0/tests/test_graph_performance.py +193 -0
- abstractmemory-0.5.0/tests/test_graph_provenance.py +502 -0
- abstractmemory-0.5.0/tests/test_graph_revisions.py +620 -0
- abstractmemory-0.5.0/tests/test_home_open_is_a_read.py +91 -0
- abstractmemory-0.5.0/tests/test_identical_authoring_settles.py +166 -0
- abstractmemory-0.5.0/tests/test_memory_task_queue.py +466 -0
- abstractmemory-0.5.0/tests/test_narrow_assertion.py +142 -0
- abstractmemory-0.5.0/tests/test_pending_formations.py +507 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_phase_artifact_pin.py +5 -1
- abstractmemory-0.5.0/tests/test_reading_provenance.py +212 -0
- abstractmemory-0.5.0/tests/test_rearm_pending.py +380 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_reconstruct.py +3 -3
- abstractmemory-0.5.0/tests/test_records_since_maintenance.py +347 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_replay.py +9 -1
- abstractmemory-0.5.0/tests/test_retitle.py +431 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_review_wave.py +1 -1
- abstractmemory-0.5.0/tests/test_rewrite_digest_in_place.py +445 -0
- abstractmemory-0.5.0/tests/test_ripple_v1.py +331 -0
- abstractmemory-0.5.0/tests/test_store_performance.py +179 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_store_vectors.py +1 -1
- abstractmemory-0.5.0/tests/test_stored_text_whole.py +119 -0
- abstractmemory-0.5.0/tests/test_titles_whole.py +126 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_two_sided_visit_contract.py +1 -1
- abstractmemory-0.5.0/tests/test_untitled_records.py +423 -0
- abstractmemory-0.5.0/tests/test_vector_encoding_marker.py +51 -0
- abstractmemory-0.5.0/tests/test_vector_matrix.py +569 -0
- abstractmemory-0.5.0/tests/test_vector_matrix_footprint.py +88 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_world_model.py +40 -5
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_world_model_alias.py +1 -1
- abstractmemory-0.5.0/tests/test_world_model_rekey.py +368 -0
- abstractmemory-0.5.0/tests/test_write_barrier.py +690 -0
- abstractmemory-0.3.2/docs/api.md +0 -385
- abstractmemory-0.3.2/docs/memory-system.md +0 -96
- abstractmemory-0.3.2/llms-full.txt +0 -1532
- abstractmemory-0.3.2/release-notes.md +0 -13
- abstractmemory-0.3.2/src/abstractmemory/sleep_cadence.py +0 -74
- abstractmemory-0.3.2/src/abstractmemory/sqlite_store.py +0 -695
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/.github/workflows/ci.yml +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/.github/workflows/release.yml +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/.gitignore +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/ACKNOWLEDGMENTS.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/CODE_OF_CONDUCT.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/CONTRIBUTING.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/LICENSE +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/SECURITY.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/completed/0008_gateway_memory_install_and_config_boundary.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/completed/002_sqlite_database_compatibility_and_store_capabilities.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/completed/004_recall_trace_and_access_events_contract.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/completed/005_source_linked_summaries_and_derived_assertion_lineage.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/completed/007_read_only_memory_observer_contract.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/completed/extension_wave/0037_familiarity_metamemory_read.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/completed/extension_wave/0038_open_commitments_and_triggers.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/completed/extension_wave/0039_tend_election_grammar.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/completed/extension_wave/0049_stable_shelf_order_for_prefix_reuse.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/completed/memory_system_v1/0009_assertion_identity_and_batch_read_contract.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/completed/memory_system_v1/0010_append_only_closure_records_for_retract_and_supersede.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/completed/memory_system_v1/0011_cross_backend_parity_conformance_suite.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/completed/memory_system_v1/0013_store_concurrency_and_thread_safety_contract.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/completed/memory_system_v1/0014_embedding_space_integrity_manifest.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/completed/memory_system_v1/0017_memory_journal_and_scope_bindings_layer.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/completed/memory_system_v1/0018_neurotransmitter_attention_strengthen_weaken_decay.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/completed/memory_system_v1/0019_hybrid_retrieval_channels_fts_vector_exact.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/completed/memory_system_v1/0020_reconstruction_shelf_and_selection_traces.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/completed/memory_system_v1/0021_memory_records_and_remember_api.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/completed/memory_system_v1/0022_probe_and_bounded_source_expansion.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/completed/memory_system_v1/0023_maintenance_sleep_consolidate_dream.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/completed/memory_system_v1/0024_memory_system_facade_and_consumer_migration.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/completed/memory_system_v1/0025_graph_backend_decision_record_memgraph_rejected.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/completed/memory_system_v1/0026_spreading_activation_and_working_set.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/completed/memory_system_v1/0027_runtime_seam_contract_v1.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/completed/memory_system_v1/0029_sleep_reactivity_dreams_as_reaction.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/completed/memory_system_v1/0030_fork_comparison_adoption_wave.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/completed/memory_system_v1/0031_second_fork_pass_and_lifecycle_closure.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/completed/memory_system_v1/0036_third_pass_extension_wave.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/completed/subconscious_wave/0032_dream_subconscious_lifecycle.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/completed/subconscious_wave/0033_world_model_orientation_cards.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/completed/subconscious_wave/0034_situate_temporal_relational_reconstruction.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/completed/subconscious_wave/0035_lessons_layer_conventions.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/deprecated/001_semantics_aligned_memory_record_conventions.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/deprecated/003_bounded_graph_traversal_over_triples.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/deprecated/006_deterministic_anchor_and_facet_index.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/planned/extension_wave/README.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/planned/subconscious_wave/README.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/proposed/extension_wave/0040_recurrence_probe_and_presentation_fold.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/proposed/extension_wave/0041_loss_absence_anchors.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/proposed/extension_wave/0042_explain_recall_serving_contract.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/proposed/extension_wave/0043_mind_health_report.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/proposed/extension_wave/0044_origin_time_axis_for_imports.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/proposed/extension_wave/0045_n_party_memory_contract.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/proposed/extension_wave/0046_transcript_adoption_verb.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/proposed/extension_wave/0047_cue_hygiene_at_recall_boundary.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/proposed/extension_wave/0048_writer_forensics_for_homes.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/proposed/extension_wave/README.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/proposed/memory_system_v1/0012_lancedb_backend_hardening_and_explicit_schema.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/proposed/memory_system_v1/0015_capabilities_extensions_and_deterministic_export_import.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/proposed/memory_system_v1/0016_semantics_vocabulary_validation_and_aliasing_module.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/proposed/memory_system_v1/0028_lateral_inhibition_theory.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/backlog/proposed/memory_system_v1/README.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/docs/development.md +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/examples/realistic_session.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/attention.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/channels.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/cognition_health.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/concept_anchor.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/disposal.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/dream_resolution.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/drive_grouping.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/drive_pressure.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/embedding_pin.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/embeddings.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/embeddings_openai_compat.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/engine_manifest.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/feelings_reads.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/folds.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/gradation.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/journal_common.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/mind_mass.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/models.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/origin_diversity.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/reconstruct.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/render_order.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/selection.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/self_component.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/sleep_policy.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/spark.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/spreading.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/store.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/system_access.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/system_valence.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/text_tokens.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/src/abstractmemory/vector_scoring.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/golden/pre_identity_wave_result.json +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/realistic_fixtures.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_access_counts.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_alive_drives.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_anchored_summon.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_attention.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_audit_wave.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_binding_visibility.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_clean_owner_keys.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_close_assertion.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_co_use_trails.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_cognition_health.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_commitments.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_consolidation.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_drive_grouping.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_drive_pressure.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_embedding_pin.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_engine_manifest.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_explain_recall.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_familiarity.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_feelings_reads.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_gradation.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_home_lease_contract.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_identity_review.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_identity_self.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_in_memory_query_text_fallback.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_journal_backends.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_keyword_fts.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_lancedb_triple_store.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_lessons_layer.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_maintenance.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_mind_mass.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_origin_diversity.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_participants_channel.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_probe.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_realistic_lmstudio.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_recall_reads.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_recent_records.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_records.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_redigestion.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_render_order.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_replay_idempotency.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_seam_addendum.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_seam_contracts.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_situate.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_spark.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_spreading.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_sqlite_triple_store.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_stm_union.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_system.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_tend.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_term_canonicalization.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_triple_store_limits.py +0 -0
- {abstractmemory-0.3.2 → abstractmemory-0.5.0}/tests/test_valence_gradation.py +0 -0
|
@@ -5,9 +5,345 @@ All notable changes to this package will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) (pre-1.0).
|
|
7
7
|
|
|
8
|
-
##
|
|
8
|
+
## [0.5.0] - 2026-11-10
|
|
9
|
+
|
|
10
|
+
Every memory now carries an authored title and summary, a home keeps a persistent queue of what still needs
|
|
11
|
+
understanding, a record's understanding is rewritten in place with every earlier reading kept, the home's topics are
|
|
12
|
+
formed during sleep, and a host can fence every memory write behind its Stop (backlogs 0059, 0060, 0061;
|
|
13
|
+
[ADR 0001](docs/adr/0001-altered-memories-ripple.md),
|
|
14
|
+
[ADR 0003](docs/adr/0003-one-graph-ledger-provenance-and-revisions.md) decision 6a).
|
|
15
|
+
|
|
16
|
+
### Upgrading
|
|
17
|
+
|
|
18
|
+
- **Open homes that form records with `MemorySystem(..., task_queue=True)`.** A missing title or summary is always
|
|
19
|
+
stored beside the task that writes it, so these refuse a home without a task queue, before writing anything:
|
|
20
|
+
`world_model_pass`, `dream_pass`, `mine_candidates_pass`, `consolidation_pass`, `wake_cue_dedup_pass`,
|
|
21
|
+
`sleep_pass`, `communities_pass`, `embed_missing`, the ripple verbs, a `remember_many` record with `pending=...`,
|
|
22
|
+
and an `engram` whose unnamed spark items get no authored title (`report_only` reads still run). `declare_pending`
|
|
23
|
+
and `rearm_pending` answer `no_task_queue`. The queue adds its tables (`memq_*`) to the home's file on first open.
|
|
24
|
+
- **Pass an `author` callable.** Memory calls no model: `world_model_pass` / `world_model_update`, `dream_pass`,
|
|
25
|
+
`mine_candidates_pass`, `consolidation_pass`, `wake_cue_dedup_pass`, `sleep_pass`, `communities_pass` and `engram`
|
|
26
|
+
take `author(kind, body, context) -> {title, summary, author, reader, sources}`. Without it, or when it fails, the
|
|
27
|
+
records still form, pending, and every result's `authoring = {authored, failures}` names the failures
|
|
28
|
+
(`no_author_supplied`, `author_raised`, `invalid_result`).
|
|
29
|
+
- **Treat a title as optional while it is pending.** `MemoryRecordInput.title` may be `None` with
|
|
30
|
+
`pending=("title",)`, and every read serves a pending title as `None` (`MemoryHandle.title` is `Optional[str]`,
|
|
31
|
+
display blocks and `record_understanding` carry `pending`), never a placeholder or words from the body. A host's
|
|
32
|
+
drainer completes `title.author` / `digest.author` tasks with `retitle` / `rewrite_digest`; records stored before
|
|
33
|
+
0.5.0 without an authored title or summary are brought into the same state with `declare_pending`.
|
|
34
|
+
`MemoryRecordInput` raises `ValueError` for an empty title without `pending=("title",)`, and for a title given
|
|
35
|
+
with it.
|
|
36
|
+
- **Memory's passes no longer store their own titles or summaries.** Cards, dreams, offers, consolidation candidates
|
|
37
|
+
and the dedup day summary form authored or pending; their bookkeeping text ("World model: ...", "Dream: ...") is
|
|
38
|
+
only the provisional body their tasks author from. `world_model_pass` no longer queues `card.author` for new cards
|
|
39
|
+
(`digest.author` owns the body; `card.author` remains for legacy cards).
|
|
40
|
+
- **Hosts that fence writes** pass `commit_guard=` and wrap the moment they flip it in `system.write_barrier()`.
|
|
41
|
+
Two residual windows remain: a LanceDB store takes no write lock (a LanceDB write whose guard passed before the
|
|
42
|
+
flip may land after it, at most one per concurrent writer; `BarrierHold.uncovered` names it with a `#FALLBACK`
|
|
43
|
+
warning), and the two SQLite autocommit commit points (`SQLiteTripleStore._write_pin` without a cursor, the
|
|
44
|
+
off-file graph's `mark_journal_applied`) are covered only by a barrier taken on the same handle.
|
|
45
|
+
- **Community records are never embedded and never recalled**: a store's embedding paths, recall shelves, keyword
|
|
46
|
+
indexes and memory scans skip kind `community` (`canonical_text.NON_EMBEDDED_KINDS`).
|
|
47
|
+
- `CANONICAL_TEXT_VERSION` is 3 (stored text is never cut). Record digests render as before; a plain assertion
|
|
48
|
+
with an `original_context` longer than 400 characters keeps its earlier text and vector until `reembed_store`
|
|
49
|
+
re-derives it.
|
|
50
|
+
- `version_count` is 1 for a record that was never rewritten (was 0); `digest_version` stays 0.
|
|
51
|
+
- `apply_redigestion` is deprecated (it forms a new record with zero usage); use `rewrite_digest`.
|
|
52
|
+
|
|
53
|
+
### Added: titles and summaries are always authored
|
|
54
|
+
|
|
55
|
+
- `MemoryRecordInput(pending=(), pending_failure=None)`: `pending` is a subset of `PENDING_FIELDS`
|
|
56
|
+
(`{"title", "summary"}`). A pending record carries `attributes.pending = {title, summary, since, attempts}` (plus
|
|
57
|
+
`failure` when authoring failed) and `remember_many` queues its authoring task (`PENDING_TASK_KINDS`:
|
|
58
|
+
`title.author` / `digest.author`, capability `summaries`, `FORMATION_PRIORITY`). A pending summary is refused on
|
|
59
|
+
the entity's own words (`UNDERSTANDING_PROTECTED_KINDS`), except a public diary projection's summary.
|
|
60
|
+
- The host's `author` callable on every pass (`formation_authoring`): authored fields are stored with their
|
|
61
|
+
provenance (`title_provenance`, `understanding`, version 0, cause `formation`) and owe no task; a standing record is
|
|
62
|
+
never authored again.
|
|
63
|
+
- `engram(..., author=None)`: a spark item without a `name` has its title authored before it forms (it was
|
|
64
|
+
`<section>-<ordinal>`, such as `trait-0`), else it forms pending; a `name` stays the title. `EngramResult.authoring`.
|
|
65
|
+
- `retitle(record_id, *, title, author, cause, expected_version, ...)`: changes only a record's title, in place, for
|
|
66
|
+
every kind; the body and the reading stay byte-identical, the previous title is kept as a version, `title_version`
|
|
67
|
+
is the compare-and-set. Refusals: `empty_title`, `hash_chained` (an owner-direct diary entry whose `entry_hash`
|
|
68
|
+
attests its title), `closed`, `stale`, `embedder_unavailable`. A digest or card reading that changes the title
|
|
69
|
+
writes the title version too.
|
|
70
|
+
- `declare_pending(record_id, *, fields=("title", "summary"), cause="repair", reason=None)`: a stored record whose
|
|
71
|
+
title or summary was never authored gets exactly the state of a record formed pending (marker and tasks in one
|
|
72
|
+
transaction; a declared title is stored `None`, its old title kept as a version). Idempotent (`already_pending`).
|
|
73
|
+
- `rearm_pending(record_id, ...)` re-queues the authoring task of a pending field whose tasks all ran out, and
|
|
74
|
+
`pending_records(*, scopes=None, live_task=False)` lists the records still pending, with their live and unowned
|
|
75
|
+
fields.
|
|
76
|
+
- A public diary entry's summary is authored like any record's (at formation, or declared pending for an existing
|
|
77
|
+
entry); its body, the book's entry and every hash chain are untouched. Owner-direct, hash-chained and private
|
|
78
|
+
entries stay protected (`diary.diary_summary_refusal`).
|
|
79
|
+
- `rekey_world_model(old_key, new_key, *, scope, owner_id, author, cause, ...)`: moves a standing card to a new key
|
|
80
|
+
in place and keeps the old key as an alias, so a retitled interest's next `world_model_pass` forms no second card.
|
|
81
|
+
An untitled interest's card is keyed `topic:<graph id>` and `retitle` re-keys it when the title lands
|
|
82
|
+
(`card_rekey` in the result).
|
|
83
|
+
- `REWRITE_CAUSES` gains `repair` (a correction of what a process wrote wrong).
|
|
84
|
+
|
|
85
|
+
### Added: understanding rewritten in place (0059)
|
|
86
|
+
|
|
87
|
+
- `rewrite_digest`: replaces a record's digest, title and keywords in place. The record keeps its graph id, digest
|
|
88
|
+
assertion id, edges, usage counts and journal; its keyword entry and vector are replaced in the same transaction.
|
|
89
|
+
`expected_version` is a compare-and-set; each reading records `author` (`AUTHOR_KINDS`), `reader`
|
|
90
|
+
(`{provider, model, thinking}`), `sources` (mandatory for a model author) and `cause`. Refusals are named results
|
|
91
|
+
that write nothing. Results carry `cosine_distance` between the old and new vectors.
|
|
92
|
+
- `narrate_dream` (a narration beside a dream's summary), `revert_digest`, `versions`, `current_of`,
|
|
93
|
+
`record_understanding`, `understanding_fields`; `author_world_model` rewrites a card in place by default (accepts
|
|
94
|
+
`reader`, `sources`, `expected_fingerprint`; `in_place=False` keeps the revision path).
|
|
95
|
+
- The journal's version family `UnderstandingVersion`, and the opt-in replay family `revision`
|
|
96
|
+
(`OPT_IN_FAMILIES`; the default six families are unchanged). Display blocks carry the reading's provenance
|
|
97
|
+
(`digest_method`, `digest_version`, `version_count`, `authored_by`, `reader`, `understood_at`, `cause`).
|
|
98
|
+
- Every record says who wrote its words, when and why, even when its writer stamped nothing: a row without a stamp
|
|
99
|
+
reads as its formation reading, derived from its origin (`understanding.reading_provenance`); `remember_many`
|
|
100
|
+
records that reading at formation.
|
|
101
|
+
|
|
102
|
+
### Added: the memory task queue (0060) and ripple v1 (0061)
|
|
103
|
+
|
|
104
|
+
- `MemorySystem(task_queue=True)` keeps its queue in the home's file (`memq_tasks`, `memq_log`, `memq_windows`,
|
|
105
|
+
`memq_ripples`, `memq_ripple_gates`, `memq_maintenance`; a private in-memory database for the in-memory store). `system.tasks` (`MemoryTaskQueue`): `enqueue`, `select_for_window(budget_seconds, sensitivity)` (activation
|
|
106
|
+
through ADR 0001's logistic gate, strongest first, bounded by the window's time; every live task selected or left
|
|
107
|
+
out with a reason), `claim` / `ack` / `release` (leases, attempts, defer without spending an attempt), `left_out`.
|
|
108
|
+
`understanding_debt`, `enqueue_debt` (the backfill, dry-run by default) and `task_packet` on `MemorySystem`. The
|
|
109
|
+
understanding verbs accept `task_id=` and settle the task in their own transaction.
|
|
110
|
+
- A formed record and the tasks it owes commit together (`memory_tasks.form_with_tasks`): one transaction on the
|
|
111
|
+
SQLite home; on the in-memory pair a failure rolls back exactly that attempt's rows, bindings and tasks.
|
|
112
|
+
- `maintenance_due(..., tasks=)` reports pending tasks and is due when ripple or night-only work is pending.
|
|
113
|
+
- Ripple v1: `seed_ripple`, `settle_reconsideration`, `form_consolidation` (night only), `refresh_ripples`,
|
|
114
|
+
`revert_ripple`, and the reads `ripples` / `ripple`. Candidates by relation, by the cards built on a memory and by
|
|
115
|
+
vector similarity; impact decays per hop through the logistic gate (floor 0.1), at most 2 hops and 20
|
|
116
|
+
reconsiderations per ripple and per window; protected kinds are never reconsidered; every gate decision is stored
|
|
117
|
+
with its potential.
|
|
118
|
+
|
|
119
|
+
### Added: communities (topics)
|
|
120
|
+
|
|
121
|
+
- A community is a formed record of kind `community` (`abstractmemory.communities.COMMUNITY_KIND`), one record per
|
|
122
|
+
version, with a stable `attributes.community_key` across versions. `communities_pass(system, *, scopes, owner_id,
|
|
123
|
+
author, cancelled, ...)`, which a host runs during its sleep, detects them (deterministic warm-started Louvain over
|
|
124
|
+
the vectored records, at most 5 rounds), attaches vector-less records through their engraved relations, lays them
|
|
125
|
+
out, authors the changed ones and writes the version in one guarded transaction. `embed_missing(...)` embeds the
|
|
126
|
+
formed records that have no vector with the store's own embedder.
|
|
127
|
+
- Placement at formation: on a `task_queue=True` home, `remember_many` places every record it forms in its
|
|
128
|
+
provisional community inside the formation's transaction (nearest centroid, else the majority community of its
|
|
129
|
+
formation edges) and writes one `placed` journal event (an audit kind, never scored).
|
|
130
|
+
- Reads (`abstractmemory.community_index`): `communities(system, *, scopes, owner_id, version=None)` (the payload
|
|
131
|
+
version 2 a host serves, with each community's `facts`: span, activity, hub, bridges, paths,
|
|
132
|
+
`changed_since_last_sleep`) and `community_of(system, record_id)`. A community record replays like any formed
|
|
133
|
+
record; its binding envelope draws only `refines`.
|
|
134
|
+
- Topic titles come first: a community's `title.author` / `digest.author` tasks are queued at `COMMUNITY_PRIORITY`
|
|
135
|
+
(3, ahead of every other pending record's `FORMATION_PRIORITY` 5), so a drainer with a small budget names the
|
|
136
|
+
topics before a long repair tail. `communities_pass`'s `budget` goes to its topics, largest first, one call per
|
|
137
|
+
topic for both its title and its summary (`None` authors every topic); the receipt carries `budget` and
|
|
138
|
+
`budget_spent`. A topic's briefing keeps its member lines within 1500 tokens, the first line too.
|
|
139
|
+
|
|
140
|
+
### Added: sleep cadence
|
|
141
|
+
|
|
142
|
+
- `records_since_maintenance(system, *, scopes=None, after=None) -> {count, last_maintenance_at, since,
|
|
143
|
+
boundary_source, fragmented}`: the host's idle → sleep threshold. `sleep_pass` records when a whole night ran to
|
|
144
|
+
its end (a cancelled, `report_only` or anchored night records nothing; a cycle window is recorded as kind `cycle`
|
|
145
|
+
and does not reset the count); `after` is the host's own last maintenance, and the later of the two is the
|
|
146
|
+
boundary. `fragmented = {count, share, provisional, unvectored, pending}` says how much of the live home a sleep
|
|
147
|
+
would make whole. `MemoryTaskQueue.record_maintenance` / `last_maintenance`.
|
|
148
|
+
- `sleep_pass(..., cancelled=None)`: the host's Stop check, read at every sub-phase boundary and immediately before
|
|
149
|
+
the completion marker; a stopped night records no completion and carries `cancelled_after`.
|
|
150
|
+
|
|
151
|
+
### Added: the Stop fence hooks
|
|
152
|
+
|
|
153
|
+
- `MemorySystem(..., commit_guard=None)`: the host's `guard(where)` is installed on the store and journal and called
|
|
154
|
+
inside every write transaction immediately before its COMMIT, once per outermost transaction, whoever writes (the
|
|
155
|
+
facade, `MemoryGraph`, the task queue, the sleep passes). Raising rolls the write back; nothing of it lands and the
|
|
156
|
+
exception reaches the caller unchanged. A store or journal type whose writes do not call a guard is refused
|
|
157
|
+
(`TypeError`), and so is a second, different guard (`ValueError`).
|
|
158
|
+
- `MemorySystem.write_barrier(*, timeout=None)` / `write_barrier(system, *, timeout=None)`: a context manager the
|
|
159
|
+
host wraps around its flip of the guard. It holds this home's in-process locks in the writers' own order and one
|
|
160
|
+
`BEGIN IMMEDIATE` per distinct SQLite file, so every transaction whose guard passed commits before the block and
|
|
161
|
+
every later one calls its guard after it. It writes nothing; `WriteBarrierTimeout` names the lock or file still
|
|
162
|
+
held.
|
|
9
163
|
|
|
10
|
-
|
|
164
|
+
### Changed
|
|
165
|
+
|
|
166
|
+
- Stored text is never cut: a world-model card quotes its evidence whole, a dream signal's `fragment` is kept whole
|
|
167
|
+
(`dream_signals.FRAGMENT_CAP` is gone), an assertion's `original_context` renders whole in the canonical text, a
|
|
168
|
+
plain assertion's "s p o" display title and an imported file's prose are kept whole. Readers shorten text at
|
|
169
|
+
display time (`canonical_text.short_title`).
|
|
170
|
+
- Titles are explicit and whole: a card formed from an interest keeps the interest's whole subject head as its
|
|
171
|
+
target; lesson-candidate, interest-candidate and group-offer titles are no longer bounded.
|
|
172
|
+
- `world_model_pass`: an interest whose title heads to an alias of a card counts as an election of the card's
|
|
173
|
+
primary key.
|
|
174
|
+
- `dream_pass` returns `signals` and `signals_omitted`.
|
|
175
|
+
- `journal_cold_cut` copies the version family and the task queue.
|
|
176
|
+
- The identity card's `lessons` section also counts the lessons written in the diary (`diary_type='lesson'`), once
|
|
177
|
+
each when a lesson record derives from the entry.
|
|
178
|
+
- The identity card's record briefs carry the reading fields (`authored_by`, `understood_at`, `cause`,
|
|
179
|
+
`digest_version`, `version_count`); diary-redacted replay blocks carry `authored_by`, `understood_at` and `cause`,
|
|
180
|
+
never the entry's words.
|
|
181
|
+
|
|
182
|
+
### Fixed
|
|
183
|
+
|
|
184
|
+
- `records_since_maintenance(...)["fragmented"]["count"]` counts each live record once: a record both vector-less
|
|
185
|
+
and pending, or placed and pending, is one fragmented record, and a placement whose record has been closed since
|
|
186
|
+
counts in `provisional` only, so `share` never exceeds 1.0. The per-kind counts are unchanged.
|
|
187
|
+
- Identical authored words settle a pending field: an in-place write whose words equal the provisional ones clears
|
|
188
|
+
the marker, completes the task and records the reading (it answered `unchanged` and left the task leased).
|
|
189
|
+
- On the in-memory pair, formation and rewriting share one lock (they could deadlock), and a failed formation
|
|
190
|
+
removes only its own rows and bindings, never a concurrent writer's.
|
|
191
|
+
- `form_with_tasks` calls the commit guard immediately before its COMMITs, after the rows, bindings and tasks.
|
|
192
|
+
- A completed task no longer carries the error of an earlier failed attempt (the failure stays in the task log).
|
|
193
|
+
- The wake-cue dedup pass no longer tokenizes a missing title as "None".
|
|
194
|
+
|
|
195
|
+
### Deprecated
|
|
196
|
+
|
|
197
|
+
- `apply_redigestion` (emits `DeprecationWarning`): use `rewrite_digest`.
|
|
198
|
+
|
|
199
|
+
## [0.4.0] - 2026-10-27
|
|
200
|
+
|
|
201
|
+
The memory graph ([ADR 0003](docs/adr/0003-one-graph-ledger-provenance-and-revisions.md), backlogs 0056-0058):
|
|
202
|
+
`abstractmemory.graph.MemoryGraph` is the only manipulation surface of a mind; every change is a revision, every
|
|
203
|
+
memory points back to the ledger, and every database is a connector behind the graph (SQLite the default). The home
|
|
204
|
+
store holds a notebook-sized corpus. The API is additive: every 0.3.x call keeps working (`close_assertion` stays;
|
|
205
|
+
`ClosureRecord` gains only the `merged` kind). Operator decisions adopted (2026-10-27): visibility is strict
|
|
206
|
+
ownership (lineage never crosses owners; ADR 0003 decision 2); stores are connectors behind `MemoryGraph`, SQLite the
|
|
207
|
+
default (decision 3); the vector re-encoding below is a documented one-way migration with a `vector_encoding` marker.
|
|
208
|
+
|
|
209
|
+
### Upgrade notes: ONE-WAY migration
|
|
210
|
+
|
|
211
|
+
- Opening a SQLite home with 0.4.0 rewrites its JSON-text vectors as float32 BLOBs. A 0.3.x reader decodes JSON
|
|
212
|
+
vectors only: on a home a 0.4.0 process has written it silently finds no vectors (zero semantic hits, no error).
|
|
213
|
+
Every process sharing a home or a plane must move to 0.4.0 together; an entity home copied to a 0.3.x install
|
|
214
|
+
loses semantic recall. A 0.4.0 home declares it: `<table>_meta` key `vector_encoding` = `float32-blob`
|
|
215
|
+
(`abstractmemory.vector_matrix.VECTOR_ENCODING_KEY`), written by the first write or by the upgrade, never by a
|
|
216
|
+
plain open.
|
|
217
|
+
- Graph homes add four tables (`memg_revisions`, `memg_provenance`, `memg_derivations`, `memg_history`) on first
|
|
218
|
+
use; nothing else in an existing file changes shape.
|
|
219
|
+
|
|
220
|
+
### Added
|
|
221
|
+
|
|
222
|
+
- **Connectors** (ADR 0003 decision 3, operator decision 2026-10-27): `MemoryGraph` is the only manipulation
|
|
223
|
+
surface of a mind and every store is a connector behind it: `abstractmemory.graph.backend` (`GraphBackend`,
|
|
224
|
+
`GraphTx` Protocols with their invariants; `register_backend`, `backend_for`, `registered_backends`). SQLite (the
|
|
225
|
+
default for planes and entity homes) and in-memory are declared implementations; a new LanceDB connector
|
|
226
|
+
(`abstractmemory.graph.lancedb_backend`, over `LanceDBTripleStore`: explicit Arrow schemas, a staged transaction,
|
|
227
|
+
a log-first commit, `repair()` re-derives a half-projected revision from the log). One conformance suite,
|
|
228
|
+
`tests/test_graph_conformance.py`, runs every connector; the LanceDB connector cannot promise serialized writers
|
|
229
|
+
across processes nor invisibility of a half-projected revision before `repair()` (strict xfails).
|
|
230
|
+
- **`abstractmemory.graph`**, the one write path of a mind:
|
|
231
|
+
- `SourceRef` (`run`, `step` with the ledger row address `(run_id, seq)`, `seq` 1-based, `artifact`, `message`, `event`,
|
|
232
|
+
`diary_entry`; optional `runtime_id`; one canonical `key()`), validated per kind (`InvalidSourceRef`); a
|
|
233
|
+
`run` / `step` ref naming a synthetic run id (`SYNTHETIC_RUN_ID_PREFIXES`: `chat-`, `diary:`,
|
|
234
|
+
`session_memory_`, `global_memory`) is refused.
|
|
235
|
+
- `Provenance(sources, derived_from, actor, reader, reason, extra)`, strict about its shape;
|
|
236
|
+
`Provenance.from_legacy(...)` lifts the old flat keys (`run_id`, `span_id`, `payload_ref`, `entry_id`, ...)
|
|
237
|
+
in one place, never fabricates a reference (a synthetic run id stays in `extra`), and reads the mixed shape
|
|
238
|
+
the runtime stamps (flat keys plus `sources`: flat keys into `extra`).
|
|
239
|
+
- `Revision` (`revision_id`, `scope`, `owner_id`, `cause`, `occurred_at`, `recorded_at`, `ops`, `provenance`,
|
|
240
|
+
`summary`) with the ops `assert`, `close` (`retract` / `supersede` / `reinterpreted` / `merged`, replacement
|
|
241
|
+
ids, ripple source and hops) and `narrow`. Every time a revision carries is parsed and normalized to one
|
|
242
|
+
UTC text form; a non-timestamp is refused. A close ends the row at the earlier of its current end and the
|
|
243
|
+
close (so `TripleQuery(active_at=)` and ranked recall agree after every close); a close or narrow before the
|
|
244
|
+
claim's `valid_from` is refused.
|
|
245
|
+
- `MemoryGraph(store, journal).apply_revision(rev)`: refuses a memory that is neither sourced nor derived from a
|
|
246
|
+
grounded memory (`ProvenanceRequired`; chains that never reach a source and cycles included); applies all ops
|
|
247
|
+
in ONE SQLite transaction (triples and their keyword rows, window changes, the journal closure when the
|
|
248
|
+
journal shares the file, the revision, provenance, derivation and history rows), or not at all; idempotent on
|
|
249
|
+
the revision id; deterministic ids so the logged revision replays identically. A store row written outside
|
|
250
|
+
the graph is adopted only by an `import` / `migration` revision that carries it as stored (logged with its
|
|
251
|
+
previous provenance, so a replay reproduces it); a different claim under an id the graph holds is refused;
|
|
252
|
+
a close/narrow-only revision must name a cause other than the memories it changes; a `derived_from` across
|
|
253
|
+
owners is refused (other owners' knowledge enters as a source). Re-observation, not duplication: an open
|
|
254
|
+
assert of a claim the graph holds open records its sources on the held memory (`re_observed`, history
|
|
255
|
+
`re-observed`) instead of a second row. Record time is the store's: a fresh apply stamps `recorded_at` with
|
|
256
|
+
its clock (`apply_revision(rev, replay=True)`, used by `replay_into`, keeps the logged value). A revision
|
|
257
|
+
already in the log returns its logged outcome. Every memory is also indexed by the sources of the revision
|
|
258
|
+
that wrote it (`via`). `SourceRef.digest`: an optional sha256 of the verbatim, beside the address.
|
|
259
|
+
- Reads, all bounded index reads: `history(memory_id)` (asserted / closed / narrowed, by which revision, with
|
|
260
|
+
its cause), `sources_of(memory_id, transitive=True)`, `derived_from_source(ref)` (a `run` ref matches
|
|
261
|
+
everything stamped with that run), the lossless change feed `revisions(after=cursor)` (a cursor beyond the
|
|
262
|
+
log's head is refused), `replay_into(target)` (an empty home replays to the same file, adoptions included),
|
|
263
|
+
`names_ref(ref, owner_ids)` (the owner gate in one index probe), and `repair()` for closures a crash left
|
|
264
|
+
unwritten when the journal lives in another file (never needed for same-file plane and entity homes).
|
|
265
|
+
- Four tables in the home file: `memg_revisions`, `memg_provenance`, `memg_derivations`, `memg_history`.
|
|
266
|
+
- **`narrow_assertion(assertion_id, valid_until)`** on `SQLiteTripleStore` and `InMemoryTripleStore`: moves an
|
|
267
|
+
already-closed validity window earlier and never widens it (`ValueError` for an open window or a value that is
|
|
268
|
+
not a timestamp; `False` for an unknown id or a date at or after the current end, compared as instants). `LanceDBTripleStore.narrow_assertion` raises
|
|
269
|
+
`NotImplementedError` (on LanceDB a window changes through the graph's LanceDB connector). AbstractNote no longer
|
|
270
|
+
needs to write the store's private table.
|
|
271
|
+
- **Closure kind `merged`** (`abstractmemory.journal.CLOSURE_KINDS`): the memory was merged into another, named in
|
|
272
|
+
`replacement_ids`. `close_assertions` and `close_record` accept it.
|
|
273
|
+
- Docs: `api.md` (the graph section and its tables), `memory-system.md` ("Time axes", "Provenance").
|
|
274
|
+
- Measured at 50,000 assertions (`tests/bench/bench_graph.py`): `history` 0.02 ms, `sources_of` 0.04 ms,
|
|
275
|
+
`derived_from_source` by step 0.05 ms and by run 0.8 ms, a change-feed page of 100 revisions 4 ms; the 0.3
|
|
276
|
+
alternative (scanning provenance JSON) took 18 ms on vectorless rows and 38 ms with 384-d vectors in the rows.
|
|
277
|
+
|
|
278
|
+
### Performance (0058)
|
|
279
|
+
|
|
280
|
+
Backlog 0058 (ADR 0003 decisions 3 and 12): the SQLite home store holds a
|
|
281
|
+
notebook-sized corpus. Measured with `tests/bench/bench_store.py`, `main`
|
|
282
|
+
versus this release on the same machine, back to back: subject + owner query
|
|
283
|
+
at 50k rows 14.8 ms -> 0.33 ms; scope "latest 100" 377 ms -> 0.9 ms; scope
|
|
284
|
+
full scan 2.6 s -> 0.5 s; vector query at 50k 5.3 s -> 1.4 ms (first query of
|
|
285
|
+
a handle 0.44 s, it builds the matrix); file 449 MB -> 122 MB; MemorySystem
|
|
286
|
+
`reconstruct` at 20k records 2.7 s -> 0.2 s; `maintenance_due` at 20k 1.9 s ->
|
|
287
|
+
0.07 ms when nothing is new, 0.1 s after new records. Full table: backlog
|
|
288
|
+
0058's Report.
|
|
289
|
+
|
|
290
|
+
- **Owner-filtered reads use the indexes.** The owner filter is now
|
|
291
|
+
`owner_id = ?` instead of `COALESCE(owner_id, '') = ?` (same rows: the
|
|
292
|
+
filter only applies to a non-empty owner, which a NULL or empty stored owner
|
|
293
|
+
never equals). A new index `idx_<table>_scope_owner_observed (scope,
|
|
294
|
+
owner_id, observed_at, assertion_id)` serves "latest N in a (scope, owner)",
|
|
295
|
+
as-of windows and per-pair scans in query order without sorting the
|
|
296
|
+
partition; reads anchored on ids, a subject or an object use their own index
|
|
297
|
+
and check scope/owner per row. Existing homes gain the index when the store
|
|
298
|
+
is opened; no row is rewritten. `SQLiteTripleStore.query_plan(q)` returns
|
|
299
|
+
SQLite's `EXPLAIN QUERY PLAN` lines for a query (tests pin the plans).
|
|
300
|
+
- **Structured reads no longer fetch the vector column.** `query` (without
|
|
301
|
+
`query_text`/`query_vector`) and `query_keywords` select the assertion
|
|
302
|
+
columns only, instead of `SELECT *` dragging the stored embedding (several KB
|
|
303
|
+
per row) and the canonical text through every scan. They no longer read the
|
|
304
|
+
embedding pin either (it guards semantic queries only). Semantic queries and
|
|
305
|
+
`stored_vector` still read the vector; `TripleAssertion` is unchanged.
|
|
306
|
+
- **Vectors are float32 BLOBs.** `SQLiteTripleStore` stores vectors as float32
|
|
307
|
+
little-endian BLOBs (4 bytes per dimension instead of ~20 bytes of JSON
|
|
308
|
+
text). Homes holding JSON vectors are upgraded in place when the store opens:
|
|
309
|
+
rows above the `vector_blob_high_water` cursor are rewritten in bounded
|
|
310
|
+
transactions (idempotent; an interrupted upgrade resumes; ~5 s once for 50k
|
|
311
|
+
rows of 384-d vectors). Stored precision is float32: a score differs from
|
|
312
|
+
the float64 value an embedder returned by about 1e-7. A value float32 cannot
|
|
313
|
+
hold raises `ValueError` at write (zero rows written) instead of being
|
|
314
|
+
stored as infinity; `stored_vector` returns the float32 values. One-way: see
|
|
315
|
+
"Upgrade notes" above.
|
|
316
|
+
- **Opening a home is a read.** `SQLiteTripleStore` and `SQLiteJournal` take no write lock when opening an
|
|
317
|
+
up-to-date home (the keyword-index and vector backfills run only when there is work; every insert path keeps
|
|
318
|
+
their cursors at the head; the journal checks its schema in a deferred transaction), so a reader never waits
|
|
319
|
+
behind a writer (before: up to `busy_timeout`, then "database is locked").
|
|
320
|
+
- **Matrix cache footprint.** A (re)build reserves exactly the table's vector rows (one allocation); appends
|
|
321
|
+
grow by at most 10 % (`store_tuning.VECTOR_MATRIX_GROWTH`; no doubling). Per process that queries a home:
|
|
322
|
+
rows x dims x 4 B plus about 170 B per row (`store_tuning.py`). Measured at 100k x 1024: 424 MB held (552 MB
|
|
323
|
+
with doubling), build peak 460 MB (833 MB).
|
|
324
|
+
- **Vector queries from an in-process matrix cache.** With numpy installed
|
|
325
|
+
(new extra `abstractmemory[fast]`; also in `all`, `all-apple`, `all-gpu`
|
|
326
|
+
and `test`), vector queries are served from a float32 matrix built at a
|
|
327
|
+
handle's first semantic query, appended with rows written since by any
|
|
328
|
+
handle or process, and rebuilt when the vectors are rewritten
|
|
329
|
+
(`replace_vectors`, the upgrade; `vector_generation` in the meta sidecar).
|
|
330
|
+
Results are the reference scan's (`vector_scoring.rank_by_cosine`): same
|
|
331
|
+
rows, same order (ties in rowid order), bit-identical scores — a float32
|
|
332
|
+
pass picks the candidates with a margin above its error bound, and they are
|
|
333
|
+
re-scored with the reference arithmetic. Without numpy, or when a stored
|
|
334
|
+
vector cannot be scored exactly (mixed dimensions, non-finite values), the
|
|
335
|
+
Python scan answers, labelled once per handle with a `#FALLBACK`
|
|
336
|
+
`RuntimeWarning`. `SQLiteTripleStore.vector_engine` reports the path.
|
|
337
|
+
- **`maintenance_due` bounded by a cursor.** For the SQLite and in-memory
|
|
338
|
+
stores the answer is folded from the new store change feed
|
|
339
|
+
`assertions_after(cursor, *, scope, owner_id, limit)`: a check reads only the
|
|
340
|
+
rows written since the previous check of the same (store, journal, scopes)
|
|
341
|
+
and re-reads the journal's formation bindings only when the journal moved.
|
|
342
|
+
`last_maintenance_seq` uses the same fold. The answer is the full scan's
|
|
343
|
+
(other stores keep the scan).
|
|
344
|
+
- Tuning constants of the store (margins, batch and page sizes) live in
|
|
345
|
+
`abstractmemory.store_tuning`, each with its bound or measurement.
|
|
346
|
+
- The benchmark lives in the repository: `tests/bench/bench_store.py`.
|
|
11
347
|
|
|
12
348
|
## [0.3.2] - 2026-10-20
|
|
13
349
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: AbstractMemory
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
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
|
|
@@ -19,18 +19,24 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
19
19
|
Requires-Python: >=3.10
|
|
20
20
|
Provides-Extra: all
|
|
21
21
|
Requires-Dist: lancedb; extra == 'all'
|
|
22
|
+
Requires-Dist: numpy>=1.24; extra == 'all'
|
|
22
23
|
Provides-Extra: all-apple
|
|
23
24
|
Requires-Dist: lancedb; extra == 'all-apple'
|
|
25
|
+
Requires-Dist: numpy>=1.24; extra == 'all-apple'
|
|
24
26
|
Provides-Extra: all-gpu
|
|
25
27
|
Requires-Dist: lancedb; extra == 'all-gpu'
|
|
28
|
+
Requires-Dist: numpy>=1.24; extra == 'all-gpu'
|
|
26
29
|
Provides-Extra: apple
|
|
27
30
|
Provides-Extra: dev
|
|
28
31
|
Requires-Dist: pytest>=7.0.0; extra == 'dev'
|
|
32
|
+
Provides-Extra: fast
|
|
33
|
+
Requires-Dist: numpy>=1.24; extra == 'fast'
|
|
29
34
|
Provides-Extra: gpu
|
|
30
35
|
Provides-Extra: lancedb
|
|
31
36
|
Requires-Dist: lancedb; extra == 'lancedb'
|
|
32
37
|
Provides-Extra: test
|
|
33
38
|
Requires-Dist: lancedb; extra == 'test'
|
|
39
|
+
Requires-Dist: numpy>=1.24; extra == 'test'
|
|
34
40
|
Requires-Dist: pytest>=7.0.0; extra == 'test'
|
|
35
41
|
Description-Content-Type: text/markdown
|
|
36
42
|
|
|
@@ -49,6 +55,15 @@ Storage never decays and nothing is ever deleted; only retrieval strength change
|
|
|
49
55
|
- The authoritative export list is [`src/abstractmemory/__init__.py`](src/abstractmemory/__init__.py); [`docs/api.md`](docs/api.md) documents it.
|
|
50
56
|
- Requires Python 3.10+.
|
|
51
57
|
|
|
58
|
+
## What's new in 0.5.0
|
|
59
|
+
|
|
60
|
+
- Every memory's title and summary is authored: memory's passes take a host `author` callable, and a record whose authoring failed forms pending, with its task, until a reader completes it (`retitle`, `rewrite_digest`, `declare_pending`, `rearm_pending`).
|
|
61
|
+
- A persistent task queue per home (`MemorySystem(task_queue=True)`), ripple v1, and understanding rewritten in place with every earlier reading kept as a version.
|
|
62
|
+
- Topics: `community` records formed during sleep, with provisional placement of each new record at formation.
|
|
63
|
+
- The sleep cadence read `records_since_maintenance`, and the Stop fence hooks `commit_guard` and `write_barrier`.
|
|
64
|
+
|
|
65
|
+
Upgrading from 0.4.x: see the "Upgrading" notes in [`CHANGELOG.md`](CHANGELOG.md).
|
|
66
|
+
|
|
52
67
|
## Ecosystem (AbstractFramework)
|
|
53
68
|
|
|
54
69
|
AbstractMemory is a component of the **AbstractFramework** ecosystem. It has no dependency on AbstractCore or AbstractRuntime; embeddings for semantic retrieval can come from any OpenAI-compatible `/embeddings` endpoint (`OpenAICompatTextEmbedder`), from an AbstractGateway deployment (`AbstractGatewayTextEmbedder`), or from your own `TextEmbedder` implementation.
|
|
@@ -86,6 +101,13 @@ Optional LanceDB backend:
|
|
|
86
101
|
python -m pip install -e ".[lancedb]"
|
|
87
102
|
```
|
|
88
103
|
|
|
104
|
+
Fast vector search on the SQLite store (numpy; without it the store serves the
|
|
105
|
+
same results from a labelled Python scan):
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
python -m pip install -e ".[fast]"
|
|
109
|
+
```
|
|
110
|
+
|
|
89
111
|
PyPI (packaged release):
|
|
90
112
|
|
|
91
113
|
```bash
|
|
@@ -93,7 +115,7 @@ python -m pip install AbstractMemory
|
|
|
93
115
|
python -m pip install "AbstractMemory[lancedb]"
|
|
94
116
|
```
|
|
95
117
|
|
|
96
|
-
The distribution name is `AbstractMemory` (pip is case-insensitive); the import name is `abstractmemory`. The `[apple]`/`[gpu]` extras are no-op compatibility aliases; `[all]`, `[all-apple]`, and `[all-gpu]` install the LanceDB backend.
|
|
118
|
+
The distribution name is `AbstractMemory` (pip is case-insensitive); the import name is `abstractmemory`. The `[apple]`/`[gpu]` extras are no-op compatibility aliases; `[fast]` installs numpy for the SQLite store's vector matrix cache; `[all]`, `[all-apple]`, and `[all-gpu]` install the LanceDB backend and numpy.
|
|
97
119
|
|
|
98
120
|
## Quick example — layer 1 (triples)
|
|
99
121
|
|
|
@@ -141,6 +163,10 @@ result = system.reconstruct(Stimulus(cue_text="pool outage"), scopes=[("session"
|
|
|
141
163
|
system.commit_selection(result.trace_id, [h.record_id for h in result.handles[:2]])
|
|
142
164
|
```
|
|
143
165
|
|
|
166
|
+
## The memory graph: revisions and provenance
|
|
167
|
+
|
|
168
|
+
`abstractmemory.graph` is the write path of a mind (0.4.0): every change to the graph is one `Revision` (a cause such as `ingest`, `reinterpret` or `maintenance`, plus `assert` / `close` / `narrow` operations applied together and atomically, once per revision id), and every memory must name where it came from in AbstractRuntime's ledger (a `SourceRef` to a run, a step `(run_id, seq)`, an artifact, a message, an event or a diary entry) or the memories it was derived from; a write with neither is refused with `ProvenanceRequired`. `MemoryGraph(store, journal)` then answers `history(memory_id)` (asserted, closed, narrowed: by which revision and why), `sources_of(memory_id)`, `derived_from_source(ref)`, a lossless change feed `revisions(after=cursor)`, and `replay_into(...)`. The database is a connector behind the graph (`abstractmemory.graph.backend`): SQLite by default, LanceDB and in-memory held to the same conformance suite. See [`docs/api.md`](docs/api.md#the-memory-graph-revisions-and-provenance) and the "Time axes" and "Provenance" sections of [`docs/memory-system.md`](docs/memory-system.md).
|
|
169
|
+
|
|
144
170
|
## Documentation
|
|
145
171
|
|
|
146
172
|
- Getting started: [`docs/getting-started.md`](docs/getting-started.md)
|
|
@@ -164,7 +190,7 @@ system.commit_selection(result.trace_id, [h.record_id for h in result.handles[:2
|
|
|
164
190
|
|
|
165
191
|
## Design principles
|
|
166
192
|
|
|
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.
|
|
193
|
+
- **Append-only, no deletion**: updates are new assertions; belief revision is closure records (retract/supersede/reinterpreted/merged); forgetting is decay of retrieval strength plus closures and silencing — the substrate is lossless. The one mutable cell is a record's understanding: `rewrite_digest` and `retitle` rewrite a digest or a title in place and keep every earlier reading as a version.
|
|
168
194
|
- **Reads are pure**: reconstruction, inspection, replay, and the entity card deposit nothing. `commit_selection` is the only strengthening path.
|
|
169
195
|
- **One seq axis**: the journal assigns a monotonic `seq` to every record; any past state is reproducible by anchoring reads at `as_of`.
|
|
170
196
|
- **Works-or-loud**: degraded paths are labeled `#FALLBACK` in result warnings; invalid inputs raise actionable errors instead of silently meaning something else.
|
|
@@ -13,6 +13,15 @@ Storage never decays and nothing is ever deleted; only retrieval strength change
|
|
|
13
13
|
- The authoritative export list is [`src/abstractmemory/__init__.py`](src/abstractmemory/__init__.py); [`docs/api.md`](docs/api.md) documents it.
|
|
14
14
|
- Requires Python 3.10+.
|
|
15
15
|
|
|
16
|
+
## What's new in 0.5.0
|
|
17
|
+
|
|
18
|
+
- Every memory's title and summary is authored: memory's passes take a host `author` callable, and a record whose authoring failed forms pending, with its task, until a reader completes it (`retitle`, `rewrite_digest`, `declare_pending`, `rearm_pending`).
|
|
19
|
+
- A persistent task queue per home (`MemorySystem(task_queue=True)`), ripple v1, and understanding rewritten in place with every earlier reading kept as a version.
|
|
20
|
+
- Topics: `community` records formed during sleep, with provisional placement of each new record at formation.
|
|
21
|
+
- The sleep cadence read `records_since_maintenance`, and the Stop fence hooks `commit_guard` and `write_barrier`.
|
|
22
|
+
|
|
23
|
+
Upgrading from 0.4.x: see the "Upgrading" notes in [`CHANGELOG.md`](CHANGELOG.md).
|
|
24
|
+
|
|
16
25
|
## Ecosystem (AbstractFramework)
|
|
17
26
|
|
|
18
27
|
AbstractMemory is a component of the **AbstractFramework** ecosystem. It has no dependency on AbstractCore or AbstractRuntime; embeddings for semantic retrieval can come from any OpenAI-compatible `/embeddings` endpoint (`OpenAICompatTextEmbedder`), from an AbstractGateway deployment (`AbstractGatewayTextEmbedder`), or from your own `TextEmbedder` implementation.
|
|
@@ -50,6 +59,13 @@ Optional LanceDB backend:
|
|
|
50
59
|
python -m pip install -e ".[lancedb]"
|
|
51
60
|
```
|
|
52
61
|
|
|
62
|
+
Fast vector search on the SQLite store (numpy; without it the store serves the
|
|
63
|
+
same results from a labelled Python scan):
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
python -m pip install -e ".[fast]"
|
|
67
|
+
```
|
|
68
|
+
|
|
53
69
|
PyPI (packaged release):
|
|
54
70
|
|
|
55
71
|
```bash
|
|
@@ -57,7 +73,7 @@ python -m pip install AbstractMemory
|
|
|
57
73
|
python -m pip install "AbstractMemory[lancedb]"
|
|
58
74
|
```
|
|
59
75
|
|
|
60
|
-
The distribution name is `AbstractMemory` (pip is case-insensitive); the import name is `abstractmemory`. The `[apple]`/`[gpu]` extras are no-op compatibility aliases; `[all]`, `[all-apple]`, and `[all-gpu]` install the LanceDB backend.
|
|
76
|
+
The distribution name is `AbstractMemory` (pip is case-insensitive); the import name is `abstractmemory`. The `[apple]`/`[gpu]` extras are no-op compatibility aliases; `[fast]` installs numpy for the SQLite store's vector matrix cache; `[all]`, `[all-apple]`, and `[all-gpu]` install the LanceDB backend and numpy.
|
|
61
77
|
|
|
62
78
|
## Quick example — layer 1 (triples)
|
|
63
79
|
|
|
@@ -105,6 +121,10 @@ result = system.reconstruct(Stimulus(cue_text="pool outage"), scopes=[("session"
|
|
|
105
121
|
system.commit_selection(result.trace_id, [h.record_id for h in result.handles[:2]])
|
|
106
122
|
```
|
|
107
123
|
|
|
124
|
+
## The memory graph: revisions and provenance
|
|
125
|
+
|
|
126
|
+
`abstractmemory.graph` is the write path of a mind (0.4.0): every change to the graph is one `Revision` (a cause such as `ingest`, `reinterpret` or `maintenance`, plus `assert` / `close` / `narrow` operations applied together and atomically, once per revision id), and every memory must name where it came from in AbstractRuntime's ledger (a `SourceRef` to a run, a step `(run_id, seq)`, an artifact, a message, an event or a diary entry) or the memories it was derived from; a write with neither is refused with `ProvenanceRequired`. `MemoryGraph(store, journal)` then answers `history(memory_id)` (asserted, closed, narrowed: by which revision and why), `sources_of(memory_id)`, `derived_from_source(ref)`, a lossless change feed `revisions(after=cursor)`, and `replay_into(...)`. The database is a connector behind the graph (`abstractmemory.graph.backend`): SQLite by default, LanceDB and in-memory held to the same conformance suite. See [`docs/api.md`](docs/api.md#the-memory-graph-revisions-and-provenance) and the "Time axes" and "Provenance" sections of [`docs/memory-system.md`](docs/memory-system.md).
|
|
127
|
+
|
|
108
128
|
## Documentation
|
|
109
129
|
|
|
110
130
|
- Getting started: [`docs/getting-started.md`](docs/getting-started.md)
|
|
@@ -128,7 +148,7 @@ system.commit_selection(result.trace_id, [h.record_id for h in result.handles[:2
|
|
|
128
148
|
|
|
129
149
|
## Design principles
|
|
130
150
|
|
|
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.
|
|
151
|
+
- **Append-only, no deletion**: updates are new assertions; belief revision is closure records (retract/supersede/reinterpreted/merged); forgetting is decay of retrieval strength plus closures and silencing — the substrate is lossless. The one mutable cell is a record's understanding: `rewrite_digest` and `retitle` rewrite a digest or a title in place and keep every earlier reading as a version.
|
|
132
152
|
- **Reads are pure**: reconstruction, inspection, replay, and the entity card deposit nothing. `commit_selection` is the only strengthening path.
|
|
133
153
|
- **One seq axis**: the journal assigns a monotonic `seq` to every record; any past state is reproducible by anchoring reads at `as_of`.
|
|
134
154
|
- **Works-or-loud**: degraded paths are labeled `#FALLBACK` in result warnings; invalid inputs raise actionable errors instead of silently meaning something else.
|
|
@@ -19,6 +19,7 @@ AbstractMemory is a Python library for durable, append-only agent memory: tempor
|
|
|
19
19
|
- FAQ: [`faq.md`](faq.md) — common questions and current limits.
|
|
20
20
|
- Troubleshooting: [`troubleshooting.md`](troubleshooting.md) — symptom-oriented fixes for setup, retrieval, embedding-space, durability, and maintenance problems.
|
|
21
21
|
- Development: [`development.md`](development.md) — local setup, tests, and the design backlog.
|
|
22
|
+
- Architecture decisions: [`adr/README.md`](adr/README.md) — durable rules, including ADR 0001 (an altered memory ripples through the memories connected to it) and ADR 0002 (AbstractMemory owns the semantic temporal memory graph and all of its processing; applications build on it).
|
|
22
23
|
|
|
23
24
|
## Related
|
|
24
25
|
|