AbstractMemory 0.5.0__tar.gz → 0.5.1__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.5.0 → abstractmemory-0.5.1}/CHANGELOG.md +41 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/PKG-INFO +6 -1
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/README.md +5 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/api.md +3 -2
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/overview.md +6 -1
- abstractmemory-0.5.1/docs/backlog/planned/0069_runtime_recall_stamps_use_community_keys_of.md +51 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/memory-system.md +1 -1
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/llms-full.txt +9 -3
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/pyproject.toml +1 -1
- abstractmemory-0.5.1/release-notes.md +38 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/communities.py +183 -23
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/community_index.py +136 -5
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/memory_tasks.py +30 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/understanding.py +11 -2
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_communities.py +168 -0
- abstractmemory-0.5.1/tests/test_community_keys_of.py +426 -0
- abstractmemory-0.5.0/release-notes.md +0 -188
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/.github/workflows/ci.yml +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/.github/workflows/release.yml +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/.gitignore +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/ACKNOWLEDGMENTS.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/CODE_OF_CONDUCT.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/CONTRIBUTING.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/LICENSE +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/SECURITY.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/README.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/adr/0001-altered-memories-ripple.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/adr/0002-abstractmemory-owns-the-memory-graph.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/adr/0003-one-graph-ledger-provenance-and-revisions.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/adr/README.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/architecture.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/completed/0008_gateway_memory_install_and_config_boundary.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/completed/002_sqlite_database_compatibility_and_store_capabilities.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/completed/004_recall_trace_and_access_events_contract.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/completed/005_source_linked_summaries_and_derived_assertion_lineage.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/completed/007_read_only_memory_observer_contract.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/completed/extension_wave/0037_familiarity_metamemory_read.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/completed/extension_wave/0038_open_commitments_and_triggers.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/completed/extension_wave/0039_tend_election_grammar.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/completed/extension_wave/0049_stable_shelf_order_for_prefix_reuse.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/completed/knowledge_graph_convergence/0059_record_understanding_rewrites_in_place_with_versions.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/completed/knowledge_graph_convergence/0060_memory_task_queue.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/completed/knowledge_graph_convergence/0061_ripple_v1_over_the_task_queue.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/completed/memory_system_v1/0009_assertion_identity_and_batch_read_contract.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/completed/memory_system_v1/0010_append_only_closure_records_for_retract_and_supersede.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/completed/memory_system_v1/0011_cross_backend_parity_conformance_suite.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/completed/memory_system_v1/0013_store_concurrency_and_thread_safety_contract.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/completed/memory_system_v1/0014_embedding_space_integrity_manifest.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/completed/memory_system_v1/0017_memory_journal_and_scope_bindings_layer.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/completed/memory_system_v1/0018_neurotransmitter_attention_strengthen_weaken_decay.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/completed/memory_system_v1/0019_hybrid_retrieval_channels_fts_vector_exact.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/completed/memory_system_v1/0020_reconstruction_shelf_and_selection_traces.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/completed/memory_system_v1/0021_memory_records_and_remember_api.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/completed/memory_system_v1/0022_probe_and_bounded_source_expansion.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/completed/memory_system_v1/0023_maintenance_sleep_consolidate_dream.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/completed/memory_system_v1/0024_memory_system_facade_and_consumer_migration.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/completed/memory_system_v1/0025_graph_backend_decision_record_memgraph_rejected.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/completed/memory_system_v1/0026_spreading_activation_and_working_set.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/completed/memory_system_v1/0027_runtime_seam_contract_v1.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/completed/memory_system_v1/0029_sleep_reactivity_dreams_as_reaction.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/completed/memory_system_v1/0030_fork_comparison_adoption_wave.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/completed/memory_system_v1/0031_second_fork_pass_and_lifecycle_closure.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/completed/memory_system_v1/0036_third_pass_extension_wave.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/completed/subconscious_wave/0032_dream_subconscious_lifecycle.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/completed/subconscious_wave/0033_world_model_orientation_cards.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/completed/subconscious_wave/0034_situate_temporal_relational_reconstruction.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/completed/subconscious_wave/0035_lessons_layer_conventions.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/deprecated/001_semantics_aligned_memory_record_conventions.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/deprecated/003_bounded_graph_traversal_over_triples.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/deprecated/006_deterministic_anchor_and_facet_index.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/planned/extension_wave/README.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/planned/knowledge_graph_convergence/0050_entity_registry_identity_and_reversible_merges.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/planned/knowledge_graph_convergence/0051_claim_lifecycle_and_revision_log.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/planned/knowledge_graph_convergence/0052_document_knowledge_retrieval.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/planned/knowledge_graph_convergence/0053_self_organisation_communities_consolidation_reflection.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/planned/knowledge_graph_convergence/0054_ripple_propagation_and_activation.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/planned/knowledge_graph_convergence/0055_notes_and_diary_layer_for_consumers.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/planned/knowledge_graph_convergence/0056_ledger_provenance_contract_and_revision_log.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/planned/knowledge_graph_convergence/0057_one_mind_per_plane_sqlite_home.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/planned/knowledge_graph_convergence/0058_home_store_performance_indexes_vectors.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/planned/knowledge_graph_convergence/0059_record_understanding_rewrites_in_place_with_versions.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/planned/knowledge_graph_convergence/0060_memory_task_queue.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/planned/knowledge_graph_convergence/0061_ripple_v1_over_the_task_queue.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/planned/knowledge_graph_convergence/README.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/planned/subconscious_wave/README.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/proposed/0062_write_barrier_residual_windows.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/proposed/0064_community_facts_merged_into.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/proposed/0065_embed_missing_vector_generation_bump_batching.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/proposed/0066_placement_index_misses_dissolve_only_versions.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/proposed/0067_communities_read_is_not_one_snapshot.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/proposed/0068_api_doc_queue_less_list_omits_communities.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/proposed/extension_wave/0040_recurrence_probe_and_presentation_fold.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/proposed/extension_wave/0041_loss_absence_anchors.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/proposed/extension_wave/0042_explain_recall_serving_contract.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/proposed/extension_wave/0043_mind_health_report.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/proposed/extension_wave/0044_origin_time_axis_for_imports.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/proposed/extension_wave/0045_n_party_memory_contract.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/proposed/extension_wave/0046_transcript_adoption_verb.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/proposed/extension_wave/0047_cue_hygiene_at_recall_boundary.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/proposed/extension_wave/0048_writer_forensics_for_homes.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/proposed/extension_wave/README.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/proposed/memory_system_v1/0012_lancedb_backend_hardening_and_explicit_schema.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/proposed/memory_system_v1/0015_capabilities_extensions_and_deterministic_export_import.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/proposed/memory_system_v1/0016_semantics_vocabulary_validation_and_aliasing_module.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/proposed/memory_system_v1/0028_lateral_inhibition_theory.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/proposed/memory_system_v1/README.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/proposed/ripple_wave/0001_change_records_and_ripple_primitives.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/backlog/proposed/ripple_wave/0063_ripple_v1_consumer_seam.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/development.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/faq.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/getting-started.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/operator.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/stores.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/docs/troubleshooting.md +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/examples/entity_home_maintenance_proof.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/examples/realistic_session.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/llms.txt +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/__init__.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/activation_gate.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/alive_drives.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/archive_import.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/attention.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/candidate_miner.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/canonical_text.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/channels.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/cognition_health.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/commit_guard.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/concept_anchor.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/consolidation.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/diary.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/disposal.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/doctoring.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/dream_resolution.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/dream_signals.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/drive_grouping.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/drive_pressure.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/embedding_pin.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/embeddings.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/embeddings_openai_compat.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/engine_manifest.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/engram.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/entity_card.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/feelings_reads.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/folds.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/formation_authoring.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/gradation.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/graph/__init__.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/graph/backend.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/graph/graph.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/graph/lancedb_backend.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/graph/provenance.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/graph/revisions.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/identity_review.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/in_memory_store.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/journal.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/journal_common.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/journal_memory.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/journal_sqlite.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/journal_sqlite_rows.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/lancedb_store.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/maintenance.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/mind_mass.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/models.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/origin_diversity.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/probe.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/recall_reads.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/recent_records.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/reconstruct.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/records.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/redigestion.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/reembed.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/render_order.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/replay.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/ripple.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/seam.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/selection.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/self_component.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/shelf.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/situate.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/sleep_cadence.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/sleep_policy.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/spark.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/spreading.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/sqlite_store.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/store.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/store_tuning.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/system.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/system_access.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/system_understanding.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/system_valence.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/tend.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/text_tokens.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/vector_matrix.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/vector_scoring.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/world_model.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/world_model_alias.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/src/abstractmemory/write_barrier.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/bench/bench_graph.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/bench/bench_store.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/conftest.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/golden/pre_identity_wave_result.json +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/graph_support.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/realistic_fixtures.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_access_counts.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_alive_drives.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_anchored_summon.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_archive_import.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_atomic_formation.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_attention.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_audit_wave.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_binding_visibility.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_cadence_cursor.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_candidate_miner.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_clean_owner_keys.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_close_assertion.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_co_use_trails.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_cognition_health.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_commit_guard.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_commitments.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_communities_embed_missing.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_communities_never_recalled.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_communities_rounds.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_communities_scale.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_community_placement.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_consolidation.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_declare_pending.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_diary_summary_authored.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_disposal.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_doctoring.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_dream_pass_signals.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_dream_resolution.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_dream_signals.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_drive_grouping.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_drive_pressure.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_embedding_pin.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_engine_manifest.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_engram.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_entity_card.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_explain_recall.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_familiarity.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_feelings_reads.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_formation_authoring.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_formation_concurrency.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_gradation.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_graph_conformance.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_graph_e2e.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_graph_performance.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_graph_provenance.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_graph_revisions.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_home_lease_contract.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_home_open_is_a_read.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_identical_authoring_settles.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_identity_review.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_identity_self.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_in_memory_query_text_fallback.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_journal_backends.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_keyword_fts.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_lancedb_triple_store.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_lessons_layer.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_maintenance.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_memory_task_queue.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_mind_mass.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_narrow_assertion.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_origin_diversity.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_participants_channel.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_pending_formations.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_phase_artifact_pin.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_probe.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_reading_provenance.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_realistic_lmstudio.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_rearm_pending.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_recall_reads.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_recent_records.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_reconstruct.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_records.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_records_since_maintenance.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_redigestion.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_render_order.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_replay.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_replay_idempotency.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_retitle.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_review_wave.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_rewrite_digest_in_place.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_ripple_v1.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_seam_addendum.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_seam_contracts.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_situate.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_spark.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_spreading.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_sqlite_triple_store.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_stm_union.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_store_performance.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_store_vectors.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_stored_text_whole.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_system.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_tend.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_term_canonicalization.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_titles_whole.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_triple_store_limits.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_two_sided_visit_contract.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_untitled_records.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_valence_gradation.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_vector_encoding_marker.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_vector_matrix.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_vector_matrix_footprint.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_world_model.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_world_model_alias.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_world_model_rekey.py +0 -0
- {abstractmemory-0.5.0 → abstractmemory-0.5.1}/tests/test_write_barrier.py +0 -0
|
@@ -5,6 +5,47 @@ 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
|
+
## [0.5.1] - 2026-11-10
|
|
9
|
+
|
|
10
|
+
### Added: `community_keys_of`, the membership-only read for recall stamping
|
|
11
|
+
|
|
12
|
+
The runtime stamps every recalled record with its topic by reading the whole `communities()` payload per recall, which
|
|
13
|
+
computes every topic's facts: 19 ms at 2,000 records and 190 ms at 20,000 on its synthetic home.
|
|
14
|
+
|
|
15
|
+
- `community_index.community_keys_of(system, record_ids, *, scopes, owner_id) -> {record_id: key | None}` and
|
|
16
|
+
`community_memberships_of(...)` -> `{record_id: {key, provisional} | None}`: the answer `communities()` gives for
|
|
17
|
+
those records (member, provisional since the version, or none), read from the in-memory community index. The hot
|
|
18
|
+
path is the formation's catch-up compare (`MAX(rowid)` on the open connection against the index's mark) and a dict
|
|
19
|
+
lookup per id: no fold, no facts, no file opened, stat'ed or locked. Measured for 50 ids (54 topics, SQLite home):
|
|
20
|
+
20 µs per call at 2,000 records, 22 µs at 20,000 (`communities()` on the same homes: 12 ms and 65 ms). After a
|
|
21
|
+
formation, the `placed` events above the last read are fetched once per scope pair; a new version reloads the
|
|
22
|
+
index. A dissolve-only version is seen at the next version, as at placement (backlog 0066).
|
|
23
|
+
- The runtime switches its recall stamps to it: backlog 0069.
|
|
24
|
+
|
|
25
|
+
Upgrading from 0.5.0: a host that stamps recalled records with their topic should call `community_keys_of` (or
|
|
26
|
+
`community_memberships_of`) with the records' graph ids instead of reading the whole `communities()` payload per
|
|
27
|
+
recall; nothing else changes. Known limits, carried in the backlog: a version that only dissolves communities (no
|
|
28
|
+
new community record) is seen by the membership reads and by placement at the next version that writes one (0066);
|
|
29
|
+
`communities()` read while a version is being written may serve one empty read (0067).
|
|
30
|
+
|
|
31
|
+
### Fixed: a standing topic still pending is authored, and its old tasks move up
|
|
32
|
+
|
|
33
|
+
Castor's second topics night (2026-11-10): 10 of 11 topics got titles; the 11th stood unchanged, its title and
|
|
34
|
+
summary tasks queued on the first night at the old priority 5 behind ~267 repair tasks, so the pass skipped it with 6
|
|
35
|
+
calls of its budget unused, and its receipt said `pending: 0` while the topics route showed it pending.
|
|
36
|
+
|
|
37
|
+
- `communities_pass` spends what its `budget` leaves after the new and changed topics on the STANDING topics still
|
|
38
|
+
pending (unchanged tonight), largest first, one call each for the fields still pending, from tonight's briefing.
|
|
39
|
+
Each is written in place on its current record after the version (`rewrite_digest`, with the title when both are
|
|
40
|
+
pending, or `retitle`), which completes its live `title.author` / `digest.author` tasks; the record keeps its
|
|
41
|
+
`title_basis` (with the sample its author saw) and the author's verdict. The receipt's `pending` now counts every
|
|
42
|
+
topic still without a title or summary after the pass, read back; new keys `authored_in_place`, `reprioritized`
|
|
43
|
+
and `ids.authored_in_place`; a refused in-place write is a failure line with reason `write_refused`.
|
|
44
|
+
- Every standing topic's live authoring task that waits at a later priority than `COMMUNITY_PRIORITY` (3) is moved up
|
|
45
|
+
to it, in the version's transaction (its own when no version is written): a topic's legacy priority-5 tasks no
|
|
46
|
+
longer wait behind the repair tail. New `MemoryTaskQueue.prioritize(target_ids, *, kinds, priority, reason,
|
|
47
|
+
dry_run=False)`: one UPDATE, never demotes a task already ahead, one `prioritized` log row each.
|
|
48
|
+
|
|
8
49
|
## [0.5.0] - 2026-11-10
|
|
9
50
|
|
|
10
51
|
Every memory now carries an authored title and summary, a home keeps a persistent queue of what still needs
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: AbstractMemory
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.1
|
|
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
|
|
@@ -55,6 +55,11 @@ Storage never decays and nothing is ever deleted; only retrieval strength change
|
|
|
55
55
|
- The authoritative export list is [`src/abstractmemory/__init__.py`](src/abstractmemory/__init__.py); [`docs/api.md`](docs/api.md) documents it.
|
|
56
56
|
- Requires Python 3.10+.
|
|
57
57
|
|
|
58
|
+
## What's new in 0.5.1
|
|
59
|
+
|
|
60
|
+
- `community_keys_of` / `community_memberships_of`: the membership-only topic read for every recalled record, tens of microseconds per call from the in-memory community index (the runtime's recall stamps use it).
|
|
61
|
+
- A standing topic still pending its title or summary is authored in place by `communities_pass` with the budget the changed topics leave, and its queued tasks move up to the topics' priority.
|
|
62
|
+
|
|
58
63
|
## What's new in 0.5.0
|
|
59
64
|
|
|
60
65
|
- 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`).
|
|
@@ -13,6 +13,11 @@ 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.1
|
|
17
|
+
|
|
18
|
+
- `community_keys_of` / `community_memberships_of`: the membership-only topic read for every recalled record, tens of microseconds per call from the in-memory community index (the runtime's recall stamps use it).
|
|
19
|
+
- A standing topic still pending its title or summary is authored in place by `communities_pass` with the budget the changed topics leave, and its queued tasks move up to the topics' priority.
|
|
20
|
+
|
|
16
21
|
## What's new in 0.5.0
|
|
17
22
|
|
|
18
23
|
- 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`).
|
|
@@ -383,7 +383,7 @@ Enqueue sites: `remember_many` (a `title.author` / `digest.author` per pending f
|
|
|
383
383
|
- `ack(task_id, *, holder, result, now=None) -> {acked, reason?, task?}` — settle a leased task as done (for example `{"outcome": "unchanged", "seconds": 41.2, "tokens": 3120, "run_id": ...}`); a task a verb already settled returns `reason="already_done"`.
|
|
384
384
|
- `release(task_id, *, holder, outcome, reason, until=None, detail=None, now=None) -> {released, task?}` — `outcome="retry"` (attempt spent; failed at `max_attempts`), `"defer"` (no attempt spent; not before `until`, for an unreachable endpoint or embedder), `"skip"` (terminal, for example `reason="over_context"` with the measured tokens in `detail`).
|
|
385
385
|
- `left_out(*, holder=None, window=None) -> list[dict]` — what the last claimed window of each `(holder, window)` left out, and why.
|
|
386
|
-
- `task(task_id)`, `tasks(*, status=None, kind=None, target_id=None, ripple_id=None, limit=0)`, `log(task_id)`, `counts()`, `cost_of(task)`, `supersede_stale(system)`, `supersede_target(target_id, *, reason)
|
|
386
|
+
- `task(task_id)`, `tasks(*, status=None, kind=None, target_id=None, ripple_id=None, limit=0)`, `log(task_id)`, `counts()`, `cost_of(task)`, `supersede_stale(system)`, `supersede_target(target_id, *, reason)`, `prioritize(target_ids, *, kinds, priority, reason, dry_run=False)` (moves the live tasks of `kinds` on these targets that wait at a later priority up to `priority`, never demoting one already ahead, one `prioritized` log row each; returns the task ids).
|
|
387
387
|
|
|
388
388
|
On `MemorySystem` (and as module functions taking the system first):
|
|
389
389
|
|
|
@@ -539,7 +539,8 @@ Communities are eventually consistent. A record formed after the last sleep is p
|
|
|
539
539
|
- `communities(system, *, scopes, owner_id, version=None) -> dict` — PURE READ, the payload a host serves (version 2): `{version: 2, version_seq, first_sleep_pending, algorithm, communities: [...], links: [{a, b, weight}]}`. Each community is `{id (this version's record id), key (stable across versions), title, summary, pending, verdict, size, kinds, members: [{id, via}], provisional_ids, cohesion, layout: {xy, radius, seats}, centroid_stale, facts}`, largest first; `links` name community keys. `title` and `summary` are `None` while pending (`pending` names the fields still being written). `provisional_ids` are the records placed at formation since the version (their newest `placed` event), not yet members; `size`, `kinds` and `members` are the version's. `version` reads an earlier version (the newest record of each community at or before that seq, viewed up to the next version); a seq older than the first version raises `ValueError`. A community record missing a field the read serves raises `CommunitySchemaError`.
|
|
540
540
|
- `facts` (read from the store and journal as they are now, one query each): `span: {first, last}` (when its first and newest members formed), `activity` (its members' uses, `selected` events, in the last `FACTS_WINDOW_DAYS` = 7 days), `hub` (the member used most, all time; `None` when none was ever used), `bridges` (members with an engraved edge to a member of another community), `paths` (the `FACTS_PATHS_TOP` = 5 member pairs most often used together, `co_selected`, in the last 7 days: `[{from, to, count}]`), `changed_since_last_sleep: {added, moved, split_from}` (members that joined and left at this version, and the community it was split from, when its version is the newest; zeros otherwise). Not served yet: which community a dissolved one merged into.
|
|
541
541
|
- `community_of(system, record_id) -> dict` — `{record_id, community_key, community_id, provisional, via, how, score, version_seq, first_sleep_pending}`: a member of the current version (`provisional: false`, `via` as the version names it), a provisional placement (`provisional: true`, `via: "provisional"`, `how`, `score`), or no community (`community_key: None`). An unknown record or a community record raises `ValueError`.
|
|
542
|
-
- `
|
|
542
|
+
- `community_keys_of(system, record_ids, *, scopes, owner_id) -> dict` and `community_memberships_of(system, record_ids, *, scopes, owner_id) -> dict` — the membership-only read a host stamps on every recalled record: `{record_id: key | None}` and `{record_id: {key, provisional} | None}` for record graph ids (the ids members carry: a recalled record's `provenance.record_id`). Each answer is the one `communities(system, scopes=, owner_id=)` gives for that record: a member of a current community of these pairs (`provisional: false`), a record placed at formation since the version (`provisional: true`), else `None` (unplaced, unknown, a community record, another owner's record, no version yet). It is served from the in-memory community index under the store's lock: one `MAX(rowid)` compare with the index's mark (the formation's catch-up) and a dict lookup per id, no facts, no layout, no vector, no file opened or stat'ed; measured 20 µs per call for 50 ids at 2,000 records and 22 µs at 20,000 (54 topics; `communities()` on the same homes: 12 ms and 65 ms). After a formation the `placed` events above the last read are fetched once per scope pair; a new version reloads the index (once a night). Like placement, it sees a version that only dissolves communities (no new community record) at the next version. An unreadable version raises `CommunitySchemaError`; a store other than SQLite or in-memory raises `TypeError`.
|
|
543
|
+
- `communities_pass(system, *, scopes, owner_id, author, cancelled, budget=None, seed_previous=True, detect_kinds=None) -> dict` — one night's communities. It reads the graph (the formed records, their engraved edges and the store's vectors), detects communities over every vectored record (a deterministic Louvain warm-started from the previous version, at most `MAX_DETECTION_ROUNDS` = 5 rounds; `written_amid` never drives detection), attaches the vector-less records through their engraved neighbours, carries each community's `community_key` across versions by membership overlap, computes the layout, has the changed communities' titles and summaries written by `author` (the same callable as the other passes, see [the `author` callable](#authored-with-the-record-the-author-callable); `budget` = the most author calls, all of them for the topics, largest first: one call per new or changed topic writes both its title and its summary, so the pass spends at most `min(budget, n)` and never more than one call per topic; `None` authors every topic; the topics past the budget form pending, their tasks at `COMMUNITY_PRIORITY`, ahead of every other pending record; what the budget leaves goes to the STANDING topics, unchanged tonight but still pending, largest first, one call each for the fields still pending), calls `cancelled()` once, and writes the new versions, their bindings, the closures of the previous versions and their tasks in ONE commit-guarded transaction, which also moves every standing topic's live `title.author` / `digest.author` task that waits at a later priority (queued before topics came first) up to `COMMUNITY_PRIORITY`. The standing pending topics are then written IN PLACE on their current record (`rewrite_digest`, with the title when both are pending, or `retitle`; each its own guarded transaction), which completes their live tasks. An unchanged home with no pending topic to author and no task to move writes nothing. A home opened without `task_queue=True` is refused; without numpy (`abstractmemory[fast]`) the pass is skipped with its reason. The receipt carries `version_seq`, `new` / `kept` / `renamed` / `dissolved` / `unchanged`, `written`, `unvectored`, `unplaced` and `unplaced_closed` (the vector-less records whose every live engraved relation names a closed record: no edge can place them), `authored` (the topics whose title and summary this pass wrote, in a new version or in place), `authored_in_place`, `pending` (every topic with a field still pending after the pass, written tonight or standing, read back: what the topics route serves as pending), `failed` (a refused in-place write is reason `write_refused`), `reprioritized` (the standing topics' tasks moved up), `budget` (as given) and `budget_spent` (the author calls made: a host that shares one authoring budget between this pass and its drainer runs the pass first and gives the drainer `budget - budget_spent`), `authoring` (`{authored, failures}`; a topic left pending by the budget is no failure), `cancelled`, `skipped` and per-step `timings_ms`. What the author reads is the topic's briefing: its size, the kinds, the previous title, the sibling titles it must differ from (at most 40), and a stable kind-mixed sample of whole member lines within 1500 tokens (a line that does not fit is left out): under 2.3k tokens in all, about 1.5-1.9k for a home of a dozen topics.
|
|
543
544
|
- `embed_missing(system, *, scopes, owner_id, record_ids=None, cancelled) -> dict` — embeds the open formed records of these scopes that have no vector (`record_ids=None`: every one of them, which needs numpy; a list: those only) with the store's own embedder, one small commit-guarded commit per vector, so partial progress stands. `cancelled` is checked before each record. An embedder failure is never raised: that record and the rest are skipped (`embedder_unavailable`; `no_embedder` without one); a vector of the wrong dimension is `failed` (`dimension_mismatch`) and never written. Community records are never embedded. Returns `{pass_name, embedded, skipped, failed: [{id, reason}], reasons, cancelled}`.
|
|
544
545
|
- `place_record(system, prepared, *, cur) -> dict | None` with `PreparedPlacement(record_id, assertion_id, scope, owner_id, vector=None, neighbours=())` — the per-record step formation runs inside its transaction (`cur`: the open transaction on the journal's file, or `None`). Returns the event's provenance plus `event_id`, `seq` and `stored`, or `None` (no version, already placed or a member, nothing to place by). Idempotent: the event id derives from the record and the version.
|
|
545
546
|
- `COMMUNITIES_PAYLOAD_VERSION` (2), `COMMUNITY_KIND` (`"community"`), `PLACED_EVENT_KIND` (`"placed"`), `FACTS_WINDOW_DAYS` (7), `FACTS_PATHS_TOP` (5).
|
|
@@ -9,7 +9,8 @@ inspect the current code first, then update the item if reality has changed.
|
|
|
9
9
|
|
|
10
10
|
## Current Status (counts recounted on disk 2026-11-10, after the 0.5.0 closure; first reconciled 2026-07-20 — the shipped tree audited item by item)
|
|
11
11
|
|
|
12
|
-
- Planned:
|
|
12
|
+
- Planned: 10 — `planned/0069` (runtime recall stamps use `community_keys_of`, added 2026-11-10) and
|
|
13
|
+
`planned/knowledge_graph_convergence/` 0050-0058 (0050-0055 added
|
|
13
14
|
2026-10-27, ADR 0002; 0056-0058, ADR 0003; 0056 in progress, first slice
|
|
14
15
|
on `feat/memory-graph-provenance`; 0053 has its communities slice shipped in
|
|
15
16
|
0.5.0). The track folder also holds three one-line pointer files (0059-0061,
|
|
@@ -173,6 +174,10 @@ The 2026-07-20 reconciliation moved every earlier planned item to
|
|
|
173
174
|
extension_wave 0037-0039) or `deprecated/` (001/003/006, each with the
|
|
174
175
|
superseding pointer).
|
|
175
176
|
|
|
177
|
+
| Item | Priority | Notes |
|
|
178
|
+
| --- | --- | --- |
|
|
179
|
+
| [`0069_runtime_recall_stamps_use_community_keys_of.md`](planned/0069_runtime_recall_stamps_use_community_keys_of.md) | P1 | Memory side shipped on `main` (0.5.1 material); the runtime's `_stamp_recall_topics` switches from the full `communities()` read (190 ms at 20k records) to `community_keys_of` (22 µs). |
|
|
180
|
+
|
|
176
181
|
### Knowledge graph convergence track (`planned/knowledge_graph_convergence/`, 0050-0061)
|
|
177
182
|
|
|
178
183
|
Operator ruling 2026-10-27 ([ADR 0002](../adr/0002-abstractmemory-owns-the-memory-graph.md)); see the
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Planned: the runtime's recall stamps use `community_keys_of` instead of the full topics read
|
|
2
|
+
|
|
3
|
+
## Metadata
|
|
4
|
+
- Created: 2026-11-10
|
|
5
|
+
- Status: Planned
|
|
6
|
+
- Completed: N/A
|
|
7
|
+
- Target: abstractmemory 0.5.1 (the read, shipped on `main`) + the next AbstractRuntime release (the switch)
|
|
8
|
+
- Priority: P1 (a hidden per-recall cost that grows with the home)
|
|
9
|
+
- Owner: AbstractRuntime (`abstractruntime/src/abstractruntime/integrations/abstractmemory/seam_handlers.py`)
|
|
10
|
+
|
|
11
|
+
## ADR status
|
|
12
|
+
- Governing ADRs: None (communities are a slice of planned
|
|
13
|
+
[0053](knowledge_graph_convergence/0053_self_organisation_communities_consolidation_reflection.md))
|
|
14
|
+
- ADR impact: None
|
|
15
|
+
|
|
16
|
+
## Context
|
|
17
|
+
AbstractRuntime `1afbf68` stamps every recalled handle of a visit with its topic (`result.handles[i].topic`, the
|
|
18
|
+
community key, read by the Entity app's live activity panel, root backlog 1196).
|
|
19
|
+
`seam_handlers._stamp_recall_topics` reads memory's whole `communities()` payload once per recall
|
|
20
|
+
(`identity.topics.entity_communities`) and looks each handle up by `provenance.record_id`. That payload computes
|
|
21
|
+
every topic's `facts`, so the read is linear in the home: 19 ms at 2,000 records and 190 ms at 20,000 on the
|
|
22
|
+
runtime's synthetic home (54 topics, 44 handles), on the passive recall of every turn.
|
|
23
|
+
|
|
24
|
+
## Current code reality (2026-11-10)
|
|
25
|
+
- Memory now serves the membership-only read: `community_index.community_keys_of(system, record_ids, *, scopes,
|
|
26
|
+
owner_id) -> {record_id: key | None}` (and `community_memberships_of`, with `provisional`), the same answer as
|
|
27
|
+
`communities()` for those records, from the in-memory community index. Measured for 50 ids, 54 topics, SQLite
|
|
28
|
+
home: 20 µs per call at 2,000 records, 22 µs at 20,000 (`tests/test_community_keys_of.py`, run with `-s`).
|
|
29
|
+
- The runtime still calls `entity_communities` in `_stamp_recall_topics`.
|
|
30
|
+
|
|
31
|
+
## Problem or opportunity
|
|
32
|
+
The stamp costs up to a fifth of a second per recall on a 20k home, for a key a dict lookup can give.
|
|
33
|
+
|
|
34
|
+
## Proposed direction
|
|
35
|
+
In `_stamp_recall_topics`, collect the handles' graph ids (`provenance.record_id`) and call
|
|
36
|
+
`community_keys_of(memory_system, ids, scopes=scopes, owner_id=owner_id)` once; `handle["topic"] =
|
|
37
|
+
keys.get(graph_id)`. Raise the runtime's `abstractmemory` floor to the release that ships it (0.5.1). Keep the
|
|
38
|
+
existing failure path (a read that raises leaves the recall whole, without `topic`, with its `#FALLBACK` line).
|
|
39
|
+
|
|
40
|
+
## Promotion criteria
|
|
41
|
+
abstractmemory 0.5.1 published with `community_keys_of`.
|
|
42
|
+
|
|
43
|
+
## Validation ideas
|
|
44
|
+
The runtime's existing stamp tests unchanged in outcome; its synthetic-home measurement repeated (expect the stamp
|
|
45
|
+
under 1 ms at 20,000 records); a counter test that the stamp no longer calls `communities()`.
|
|
46
|
+
|
|
47
|
+
## Non-goals
|
|
48
|
+
Changing what `topic` means or the prompt.
|
|
49
|
+
|
|
50
|
+
## Guidance for future agents
|
|
51
|
+
Pass graph ids, not digest assertion ids: the read does no store lookup per id, so an assertion id answers None.
|
|
@@ -93,7 +93,7 @@ One full night (`sleep_pass`) runs FOUR sub-phases in canonical order — **reso
|
|
|
93
93
|
|
|
94
94
|
### Topics: communities
|
|
95
95
|
|
|
96
|
-
The home's topics are records of kind `community`, formed by `communities_pass`, which the host runs during its sleep: it detects communities over the vectored records (a deterministic, warm-started Louvain), attaches vector-less records through their engraved relations, keeps each topic's stable `community_key` across versions, lays the topics out for an app to draw, and has each changed topic's title and summary authored. Each version is a new record that `refines` the previous one. A record formed between two sleeps is placed in its nearest topic at formation, provisionally, and the next sleep confirms or moves it. Communities are engine state: they are never embedded and never recalled. `communities(...)` and `community_of(...)` read them (see [`api.md`](api.md#communities-topics)).
|
|
96
|
+
The home's topics are records of kind `community`, formed by `communities_pass`, which the host runs during its sleep: it detects communities over the vectored records (a deterministic, warm-started Louvain), attaches vector-less records through their engraved relations, keeps each topic's stable `community_key` across versions, lays the topics out for an app to draw, and has each changed topic's title and summary authored. Each version is a new record that `refines` the previous one. A record formed between two sleeps is placed in its nearest topic at formation, provisionally, and the next sleep confirms or moves it. Communities are engine state: they are never embedded and never recalled. `communities(...)` and `community_of(...)` read them, and `community_keys_of(...)` answers which topic each of a few records is in, cheaply enough for every recall (see [`api.md`](api.md#communities-topics)).
|
|
97
97
|
|
|
98
98
|
## Understanding: a reading can change, its history stays
|
|
99
99
|
|
|
@@ -39,6 +39,11 @@ Storage never decays and nothing is ever deleted; only retrieval strength change
|
|
|
39
39
|
- The authoritative export list is [`src/abstractmemory/__init__.py`](src/abstractmemory/__init__.py); [`docs/api.md`](docs/api.md) documents it.
|
|
40
40
|
- Requires Python 3.10+.
|
|
41
41
|
|
|
42
|
+
## What's new in 0.5.1
|
|
43
|
+
|
|
44
|
+
- `community_keys_of` / `community_memberships_of`: the membership-only topic read for every recalled record, tens of microseconds per call from the in-memory community index (the runtime's recall stamps use it).
|
|
45
|
+
- A standing topic still pending its title or summary is authored in place by `communities_pass` with the budget the changed topics leave, and its queued tasks move up to the topics' priority.
|
|
46
|
+
|
|
42
47
|
## What's new in 0.5.0
|
|
43
48
|
|
|
44
49
|
- 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`).
|
|
@@ -585,7 +590,7 @@ One full night (`sleep_pass`) runs FOUR sub-phases in canonical order — **reso
|
|
|
585
590
|
|
|
586
591
|
### Topics: communities
|
|
587
592
|
|
|
588
|
-
The home's topics are records of kind `community`, formed by `communities_pass`, which the host runs during its sleep: it detects communities over the vectored records (a deterministic, warm-started Louvain), attaches vector-less records through their engraved relations, keeps each topic's stable `community_key` across versions, lays the topics out for an app to draw, and has each changed topic's title and summary authored. Each version is a new record that `refines` the previous one. A record formed between two sleeps is placed in its nearest topic at formation, provisionally, and the next sleep confirms or moves it. Communities are engine state: they are never embedded and never recalled. `communities(...)` and `community_of(...)` read them (see [`api.md`](docs/api.md#communities-topics)).
|
|
593
|
+
The home's topics are records of kind `community`, formed by `communities_pass`, which the host runs during its sleep: it detects communities over the vectored records (a deterministic, warm-started Louvain), attaches vector-less records through their engraved relations, keeps each topic's stable `community_key` across versions, lays the topics out for an app to draw, and has each changed topic's title and summary authored. Each version is a new record that `refines` the previous one. A record formed between two sleeps is placed in its nearest topic at formation, provisionally, and the next sleep confirms or moves it. Communities are engine state: they are never embedded and never recalled. `communities(...)` and `community_of(...)` read them, and `community_keys_of(...)` answers which topic each of a few records is in, cheaply enough for every recall (see [`api.md`](docs/api.md#communities-topics)).
|
|
589
594
|
|
|
590
595
|
## Understanding: a reading can change, its history stays
|
|
591
596
|
|
|
@@ -1028,7 +1033,7 @@ Enqueue sites: `remember_many` (a `title.author` / `digest.author` per pending f
|
|
|
1028
1033
|
- `ack(task_id, *, holder, result, now=None) -> {acked, reason?, task?}` — settle a leased task as done (for example `{"outcome": "unchanged", "seconds": 41.2, "tokens": 3120, "run_id": ...}`); a task a verb already settled returns `reason="already_done"`.
|
|
1029
1034
|
- `release(task_id, *, holder, outcome, reason, until=None, detail=None, now=None) -> {released, task?}` — `outcome="retry"` (attempt spent; failed at `max_attempts`), `"defer"` (no attempt spent; not before `until`, for an unreachable endpoint or embedder), `"skip"` (terminal, for example `reason="over_context"` with the measured tokens in `detail`).
|
|
1030
1035
|
- `left_out(*, holder=None, window=None) -> list[dict]` — what the last claimed window of each `(holder, window)` left out, and why.
|
|
1031
|
-
- `task(task_id)`, `tasks(*, status=None, kind=None, target_id=None, ripple_id=None, limit=0)`, `log(task_id)`, `counts()`, `cost_of(task)`, `supersede_stale(system)`, `supersede_target(target_id, *, reason)
|
|
1036
|
+
- `task(task_id)`, `tasks(*, status=None, kind=None, target_id=None, ripple_id=None, limit=0)`, `log(task_id)`, `counts()`, `cost_of(task)`, `supersede_stale(system)`, `supersede_target(target_id, *, reason)`, `prioritize(target_ids, *, kinds, priority, reason, dry_run=False)` (moves the live tasks of `kinds` on these targets that wait at a later priority up to `priority`, never demoting one already ahead, one `prioritized` log row each; returns the task ids).
|
|
1032
1037
|
|
|
1033
1038
|
On `MemorySystem` (and as module functions taking the system first):
|
|
1034
1039
|
|
|
@@ -1184,7 +1189,8 @@ Communities are eventually consistent. A record formed after the last sleep is p
|
|
|
1184
1189
|
- `communities(system, *, scopes, owner_id, version=None) -> dict` — PURE READ, the payload a host serves (version 2): `{version: 2, version_seq, first_sleep_pending, algorithm, communities: [...], links: [{a, b, weight}]}`. Each community is `{id (this version's record id), key (stable across versions), title, summary, pending, verdict, size, kinds, members: [{id, via}], provisional_ids, cohesion, layout: {xy, radius, seats}, centroid_stale, facts}`, largest first; `links` name community keys. `title` and `summary` are `None` while pending (`pending` names the fields still being written). `provisional_ids` are the records placed at formation since the version (their newest `placed` event), not yet members; `size`, `kinds` and `members` are the version's. `version` reads an earlier version (the newest record of each community at or before that seq, viewed up to the next version); a seq older than the first version raises `ValueError`. A community record missing a field the read serves raises `CommunitySchemaError`.
|
|
1185
1190
|
- `facts` (read from the store and journal as they are now, one query each): `span: {first, last}` (when its first and newest members formed), `activity` (its members' uses, `selected` events, in the last `FACTS_WINDOW_DAYS` = 7 days), `hub` (the member used most, all time; `None` when none was ever used), `bridges` (members with an engraved edge to a member of another community), `paths` (the `FACTS_PATHS_TOP` = 5 member pairs most often used together, `co_selected`, in the last 7 days: `[{from, to, count}]`), `changed_since_last_sleep: {added, moved, split_from}` (members that joined and left at this version, and the community it was split from, when its version is the newest; zeros otherwise). Not served yet: which community a dissolved one merged into.
|
|
1186
1191
|
- `community_of(system, record_id) -> dict` — `{record_id, community_key, community_id, provisional, via, how, score, version_seq, first_sleep_pending}`: a member of the current version (`provisional: false`, `via` as the version names it), a provisional placement (`provisional: true`, `via: "provisional"`, `how`, `score`), or no community (`community_key: None`). An unknown record or a community record raises `ValueError`.
|
|
1187
|
-
- `
|
|
1192
|
+
- `community_keys_of(system, record_ids, *, scopes, owner_id) -> dict` and `community_memberships_of(system, record_ids, *, scopes, owner_id) -> dict` — the membership-only read a host stamps on every recalled record: `{record_id: key | None}` and `{record_id: {key, provisional} | None}` for record graph ids (the ids members carry: a recalled record's `provenance.record_id`). Each answer is the one `communities(system, scopes=, owner_id=)` gives for that record: a member of a current community of these pairs (`provisional: false`), a record placed at formation since the version (`provisional: true`), else `None` (unplaced, unknown, a community record, another owner's record, no version yet). It is served from the in-memory community index under the store's lock: one `MAX(rowid)` compare with the index's mark (the formation's catch-up) and a dict lookup per id, no facts, no layout, no vector, no file opened or stat'ed; measured 20 µs per call for 50 ids at 2,000 records and 22 µs at 20,000 (54 topics; `communities()` on the same homes: 12 ms and 65 ms). After a formation the `placed` events above the last read are fetched once per scope pair; a new version reloads the index (once a night). Like placement, it sees a version that only dissolves communities (no new community record) at the next version. An unreadable version raises `CommunitySchemaError`; a store other than SQLite or in-memory raises `TypeError`.
|
|
1193
|
+
- `communities_pass(system, *, scopes, owner_id, author, cancelled, budget=None, seed_previous=True, detect_kinds=None) -> dict` — one night's communities. It reads the graph (the formed records, their engraved edges and the store's vectors), detects communities over every vectored record (a deterministic Louvain warm-started from the previous version, at most `MAX_DETECTION_ROUNDS` = 5 rounds; `written_amid` never drives detection), attaches the vector-less records through their engraved neighbours, carries each community's `community_key` across versions by membership overlap, computes the layout, has the changed communities' titles and summaries written by `author` (the same callable as the other passes, see [the `author` callable](#authored-with-the-record-the-author-callable); `budget` = the most author calls, all of them for the topics, largest first: one call per new or changed topic writes both its title and its summary, so the pass spends at most `min(budget, n)` and never more than one call per topic; `None` authors every topic; the topics past the budget form pending, their tasks at `COMMUNITY_PRIORITY`, ahead of every other pending record; what the budget leaves goes to the STANDING topics, unchanged tonight but still pending, largest first, one call each for the fields still pending), calls `cancelled()` once, and writes the new versions, their bindings, the closures of the previous versions and their tasks in ONE commit-guarded transaction, which also moves every standing topic's live `title.author` / `digest.author` task that waits at a later priority (queued before topics came first) up to `COMMUNITY_PRIORITY`. The standing pending topics are then written IN PLACE on their current record (`rewrite_digest`, with the title when both are pending, or `retitle`; each its own guarded transaction), which completes their live tasks. An unchanged home with no pending topic to author and no task to move writes nothing. A home opened without `task_queue=True` is refused; without numpy (`abstractmemory[fast]`) the pass is skipped with its reason. The receipt carries `version_seq`, `new` / `kept` / `renamed` / `dissolved` / `unchanged`, `written`, `unvectored`, `unplaced` and `unplaced_closed` (the vector-less records whose every live engraved relation names a closed record: no edge can place them), `authored` (the topics whose title and summary this pass wrote, in a new version or in place), `authored_in_place`, `pending` (every topic with a field still pending after the pass, written tonight or standing, read back: what the topics route serves as pending), `failed` (a refused in-place write is reason `write_refused`), `reprioritized` (the standing topics' tasks moved up), `budget` (as given) and `budget_spent` (the author calls made: a host that shares one authoring budget between this pass and its drainer runs the pass first and gives the drainer `budget - budget_spent`), `authoring` (`{authored, failures}`; a topic left pending by the budget is no failure), `cancelled`, `skipped` and per-step `timings_ms`. What the author reads is the topic's briefing: its size, the kinds, the previous title, the sibling titles it must differ from (at most 40), and a stable kind-mixed sample of whole member lines within 1500 tokens (a line that does not fit is left out): under 2.3k tokens in all, about 1.5-1.9k for a home of a dozen topics.
|
|
1188
1194
|
- `embed_missing(system, *, scopes, owner_id, record_ids=None, cancelled) -> dict` — embeds the open formed records of these scopes that have no vector (`record_ids=None`: every one of them, which needs numpy; a list: those only) with the store's own embedder, one small commit-guarded commit per vector, so partial progress stands. `cancelled` is checked before each record. An embedder failure is never raised: that record and the rest are skipped (`embedder_unavailable`; `no_embedder` without one); a vector of the wrong dimension is `failed` (`dimension_mismatch`) and never written. Community records are never embedded. Returns `{pass_name, embedded, skipped, failed: [{id, reason}], reasons, cancelled}`.
|
|
1189
1195
|
- `place_record(system, prepared, *, cur) -> dict | None` with `PreparedPlacement(record_id, assertion_id, scope, owner_id, vector=None, neighbours=())` — the per-record step formation runs inside its transaction (`cur`: the open transaction on the journal's file, or `None`). Returns the event's provenance plus `event_id`, `seq` and `stored`, or `None` (no version, already placed or a member, nothing to place by). Idempotent: the event id derives from the record and the version.
|
|
1190
1196
|
- `COMMUNITIES_PAYLOAD_VERSION` (2), `COMMUNITY_KIND` (`"community"`), `PLACED_EVENT_KIND` (`"placed"`), `FACTS_WINDOW_DAYS` (7), `FACTS_PATHS_TOP` (5).
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "AbstractMemory"
|
|
7
|
-
version = "0.5.
|
|
7
|
+
version = "0.5.1"
|
|
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,38 @@
|
|
|
1
|
+
### Added: `community_keys_of`, the membership-only read for recall stamping
|
|
2
|
+
|
|
3
|
+
The runtime stamps every recalled record with its topic by reading the whole `communities()` payload per recall, which
|
|
4
|
+
computes every topic's facts: 19 ms at 2,000 records and 190 ms at 20,000 on its synthetic home.
|
|
5
|
+
|
|
6
|
+
- `community_index.community_keys_of(system, record_ids, *, scopes, owner_id) -> {record_id: key | None}` and
|
|
7
|
+
`community_memberships_of(...)` -> `{record_id: {key, provisional} | None}`: the answer `communities()` gives for
|
|
8
|
+
those records (member, provisional since the version, or none), read from the in-memory community index. The hot
|
|
9
|
+
path is the formation's catch-up compare (`MAX(rowid)` on the open connection against the index's mark) and a dict
|
|
10
|
+
lookup per id: no fold, no facts, no file opened, stat'ed or locked. Measured for 50 ids (54 topics, SQLite home):
|
|
11
|
+
20 µs per call at 2,000 records, 22 µs at 20,000 (`communities()` on the same homes: 12 ms and 65 ms). After a
|
|
12
|
+
formation, the `placed` events above the last read are fetched once per scope pair; a new version reloads the
|
|
13
|
+
index. A dissolve-only version is seen at the next version, as at placement (backlog 0066).
|
|
14
|
+
- The runtime switches its recall stamps to it: backlog 0069.
|
|
15
|
+
|
|
16
|
+
Upgrading from 0.5.0: a host that stamps recalled records with their topic should call `community_keys_of` (or
|
|
17
|
+
`community_memberships_of`) with the records' graph ids instead of reading the whole `communities()` payload per
|
|
18
|
+
recall; nothing else changes. Known limits, carried in the backlog: a version that only dissolves communities (no
|
|
19
|
+
new community record) is seen by the membership reads and by placement at the next version that writes one (0066);
|
|
20
|
+
`communities()` read while a version is being written may serve one empty read (0067).
|
|
21
|
+
|
|
22
|
+
### Fixed: a standing topic still pending is authored, and its old tasks move up
|
|
23
|
+
|
|
24
|
+
Castor's second topics night (2026-11-10): 10 of 11 topics got titles; the 11th stood unchanged, its title and
|
|
25
|
+
summary tasks queued on the first night at the old priority 5 behind ~267 repair tasks, so the pass skipped it with 6
|
|
26
|
+
calls of its budget unused, and its receipt said `pending: 0` while the topics route showed it pending.
|
|
27
|
+
|
|
28
|
+
- `communities_pass` spends what its `budget` leaves after the new and changed topics on the STANDING topics still
|
|
29
|
+
pending (unchanged tonight), largest first, one call each for the fields still pending, from tonight's briefing.
|
|
30
|
+
Each is written in place on its current record after the version (`rewrite_digest`, with the title when both are
|
|
31
|
+
pending, or `retitle`), which completes its live `title.author` / `digest.author` tasks; the record keeps its
|
|
32
|
+
`title_basis` (with the sample its author saw) and the author's verdict. The receipt's `pending` now counts every
|
|
33
|
+
topic still without a title or summary after the pass, read back; new keys `authored_in_place`, `reprioritized`
|
|
34
|
+
and `ids.authored_in_place`; a refused in-place write is a failure line with reason `write_refused`.
|
|
35
|
+
- Every standing topic's live authoring task that waits at a later priority than `COMMUNITY_PRIORITY` (3) is moved up
|
|
36
|
+
to it, in the version's transaction (its own when no version is written): a topic's legacy priority-5 tasks no
|
|
37
|
+
longer wait behind the repair tail. New `MemoryTaskQueue.prioritize(target_ids, *, kinds, priority, reason,
|
|
38
|
+
dry_run=False)`: one UPDATE, never demotes a task already ahead, one `prioritized` log row each.
|