superlocalmemory 4.1.13 → 4.1.14
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.
- package/.claude-plugin/marketplace.json +2 -2
- package/CHANGELOG.md +48 -0
- package/README.md +3 -3
- package/package.json +1 -8
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/CLAUDE.md +3 -3
- package/plugin/agents/slm-governance-advisor.md +1 -1
- package/plugin/agents/slm-loop-runner.md +1 -1
- package/plugin/agents/slm-memory-advisor.md +1 -1
- package/plugin/agents/slm-optimize-advisor.md +1 -1
- package/plugin/requirements.txt +1 -1
- package/plugin/skills/slm-cache/SKILL.md +1 -1
- package/plugin/skills/slm-compress/SKILL.md +1 -1
- package/plugin/skills/slm-governance/SKILL.md +1 -1
- package/plugin/skills/slm-graph/SKILL.md +1 -1
- package/plugin/skills/slm-loop/SKILL.md +1 -1
- package/plugin/skills/slm-mesh/SKILL.md +1 -1
- package/plugin/skills/slm-profile/SKILL.md +1 -1
- package/plugin/skills/slm-recall/SKILL.md +1 -1
- package/plugin/skills/slm-remember/SKILL.md +1 -1
- package/plugin/skills/slm-scope/SKILL.md +1 -1
- package/plugin/skills/slm-session/SKILL.md +1 -1
- package/plugin/skills/slm-status/SKILL.md +1 -1
- package/plugin-src/agents/slm-memory-advisor.md +1 -1
- package/plugin-src/agents/slm-optimize-advisor.md +1 -1
- package/plugin-src/rules/AGENTS.md +1 -1
- package/plugin-src/skills/slm-cache/SKILL.md +1 -1
- package/plugin-src/skills/slm-compress/SKILL.md +1 -1
- package/plugin-src/skills/slm-governance/SKILL.md +1 -1
- package/plugin-src/skills/slm-graph/SKILL.md +1 -1
- package/plugin-src/skills/slm-loop/SKILL.md +1 -1
- package/plugin-src/skills/slm-mesh/SKILL.md +1 -1
- package/plugin-src/skills/slm-profile/SKILL.md +1 -1
- package/plugin-src/skills/slm-recall/SKILL.md +1 -1
- package/plugin-src/skills/slm-remember/SKILL.md +1 -1
- package/plugin-src/skills/slm-scope/SKILL.md +1 -1
- package/plugin-src/skills/slm-session/SKILL.md +1 -1
- package/plugin-src/skills/slm-status/SKILL.md +1 -1
- package/scripts/postinstall.js +71 -2
- package/pyproject.toml +0 -250
- package/src/superlocalmemory/__init__.py +0 -82
- package/src/superlocalmemory/access/__init__.py +0 -3
- package/src/superlocalmemory/access/rbac.py +0 -575
- package/src/superlocalmemory/attribution/__init__.py +0 -9
- package/src/superlocalmemory/attribution/signer.py +0 -173
- package/src/superlocalmemory/attribution/watermark.py +0 -189
- package/src/superlocalmemory/brain/__init__.py +0 -5
- package/src/superlocalmemory/brain/truth.py +0 -418
- package/src/superlocalmemory/cli/__init__.py +0 -5
- package/src/superlocalmemory/cli/__main__.py +0 -17
- package/src/superlocalmemory/cli/_lazy_init.py +0 -115
- package/src/superlocalmemory/cli/cache_cmd.py +0 -198
- package/src/superlocalmemory/cli/commands.py +0 -4710
- package/src/superlocalmemory/cli/compress_cmd.py +0 -151
- package/src/superlocalmemory/cli/context_commands.py +0 -193
- package/src/superlocalmemory/cli/daemon.py +0 -909
- package/src/superlocalmemory/cli/db_migrate.py +0 -150
- package/src/superlocalmemory/cli/diagnostics_cmd.py +0 -101
- package/src/superlocalmemory/cli/escape_hatch.py +0 -220
- package/src/superlocalmemory/cli/evidence_cmd.py +0 -103
- package/src/superlocalmemory/cli/gdpr_cmd.py +0 -792
- package/src/superlocalmemory/cli/gdpr_io.py +0 -109
- package/src/superlocalmemory/cli/help_cmd.py +0 -197
- package/src/superlocalmemory/cli/host_upgrades.py +0 -189
- package/src/superlocalmemory/cli/ingest_cmd.py +0 -327
- package/src/superlocalmemory/cli/json_output.py +0 -81
- package/src/superlocalmemory/cli/loop_cmd.py +0 -187
- package/src/superlocalmemory/cli/main.py +0 -1145
- package/src/superlocalmemory/cli/mesh_cmd.py +0 -38
- package/src/superlocalmemory/cli/migrate_cmd.py +0 -55
- package/src/superlocalmemory/cli/ops_cmd.py +0 -281
- package/src/superlocalmemory/cli/optimize_cmd.py +0 -179
- package/src/superlocalmemory/cli/optimize_constants.py +0 -31
- package/src/superlocalmemory/cli/pending_store.py +0 -296
- package/src/superlocalmemory/cli/proxy_cmd.py +0 -108
- package/src/superlocalmemory/cli/scale_engine_cmd.py +0 -56
- package/src/superlocalmemory/cli/service_installer.py +0 -373
- package/src/superlocalmemory/cli/setup_wizard.py +0 -1162
- package/src/superlocalmemory/cli/summary_cmd.py +0 -215
- package/src/superlocalmemory/cli/version_banner.py +0 -202
- package/src/superlocalmemory/cli/wizard_v3426_options.py +0 -129
- package/src/superlocalmemory/code_graph/__init__.py +0 -46
- package/src/superlocalmemory/code_graph/blast_radius.py +0 -177
- package/src/superlocalmemory/code_graph/bridge/__init__.py +0 -36
- package/src/superlocalmemory/code_graph/bridge/entity_resolver.py +0 -490
- package/src/superlocalmemory/code_graph/bridge/event_listeners.py +0 -206
- package/src/superlocalmemory/code_graph/bridge/fact_enricher.py +0 -159
- package/src/superlocalmemory/code_graph/bridge/hebbian_linker.py +0 -170
- package/src/superlocalmemory/code_graph/bridge/maintenance.py +0 -220
- package/src/superlocalmemory/code_graph/bridge/temporal_checker.py +0 -152
- package/src/superlocalmemory/code_graph/changes.py +0 -363
- package/src/superlocalmemory/code_graph/communities.py +0 -299
- package/src/superlocalmemory/code_graph/config.py +0 -154
- package/src/superlocalmemory/code_graph/database.py +0 -526
- package/src/superlocalmemory/code_graph/extractors/__init__.py +0 -95
- package/src/superlocalmemory/code_graph/extractors/python.py +0 -413
- package/src/superlocalmemory/code_graph/extractors/typescript.py +0 -556
- package/src/superlocalmemory/code_graph/flows.py +0 -350
- package/src/superlocalmemory/code_graph/git_hooks.py +0 -226
- package/src/superlocalmemory/code_graph/graph_engine.py +0 -295
- package/src/superlocalmemory/code_graph/graph_store.py +0 -335
- package/src/superlocalmemory/code_graph/incremental.py +0 -200
- package/src/superlocalmemory/code_graph/models.py +0 -130
- package/src/superlocalmemory/code_graph/parser.py +0 -687
- package/src/superlocalmemory/code_graph/resolver.py +0 -321
- package/src/superlocalmemory/code_graph/search.py +0 -460
- package/src/superlocalmemory/code_graph/service.py +0 -95
- package/src/superlocalmemory/code_graph/watcher.py +0 -207
- package/src/superlocalmemory/compliance/__init__.py +0 -0
- package/src/superlocalmemory/compliance/abac.py +0 -204
- package/src/superlocalmemory/compliance/audit.py +0 -385
- package/src/superlocalmemory/compliance/eu_ai_act.py +0 -101
- package/src/superlocalmemory/compliance/gdpr.py +0 -1479
- package/src/superlocalmemory/compliance/lifecycle.py +0 -158
- package/src/superlocalmemory/compliance/retention.py +0 -415
- package/src/superlocalmemory/compliance/scheduler.py +0 -217
- package/src/superlocalmemory/contracts/__init__.py +0 -1
- package/src/superlocalmemory/contracts/schemas/agent-experience-v1.schema.json +0 -92
- package/src/superlocalmemory/contracts/schemas/agent-integration-contract-v2.schema.json +0 -46
- package/src/superlocalmemory/contracts/schemas/cognitive-turn-receipt-v1.schema.json +0 -59
- package/src/superlocalmemory/contracts/v402.py +0 -62
- package/src/superlocalmemory/core/__init__.py +0 -0
- package/src/superlocalmemory/core/actor_context.py +0 -166
- package/src/superlocalmemory/core/admission.py +0 -769
- package/src/superlocalmemory/core/backend_orchestrator.py +0 -637
- package/src/superlocalmemory/core/block_hygiene.py +0 -147
- package/src/superlocalmemory/core/community_summary.py +0 -267
- package/src/superlocalmemory/core/component_healer.py +0 -144
- package/src/superlocalmemory/core/component_registry.py +0 -514
- package/src/superlocalmemory/core/config.py +0 -2204
- package/src/superlocalmemory/core/consolidation_engine.py +0 -983
- package/src/superlocalmemory/core/context_cache.py +0 -574
- package/src/superlocalmemory/core/derivation_lineage.py +0 -246
- package/src/superlocalmemory/core/embedding_worker.py +0 -208
- package/src/superlocalmemory/core/embeddings.py +0 -1052
- package/src/superlocalmemory/core/engine.py +0 -1395
- package/src/superlocalmemory/core/engine_capabilities.py +0 -24
- package/src/superlocalmemory/core/engine_ingestion.py +0 -983
- package/src/superlocalmemory/core/engine_lock.py +0 -75
- package/src/superlocalmemory/core/engine_wiring.py +0 -776
- package/src/superlocalmemory/core/entity_community.py +0 -178
- package/src/superlocalmemory/core/error_envelope.py +0 -60
- package/src/superlocalmemory/core/evidence_bundle.py +0 -528
- package/src/superlocalmemory/core/fact_consolidator.py +0 -812
- package/src/superlocalmemory/core/file_lock.py +0 -92
- package/src/superlocalmemory/core/graph_analyzer.py +0 -456
- package/src/superlocalmemory/core/graph_metrics.py +0 -597
- package/src/superlocalmemory/core/graph_pruner.py +0 -939
- package/src/superlocalmemory/core/health_monitor.py +0 -338
- package/src/superlocalmemory/core/hooks.py +0 -65
- package/src/superlocalmemory/core/ingest_gate.py +0 -133
- package/src/superlocalmemory/core/ingest_policy.py +0 -38
- package/src/superlocalmemory/core/ingestion_command.py +0 -1042
- package/src/superlocalmemory/core/injection.py +0 -434
- package/src/superlocalmemory/core/install_detector.py +0 -131
- package/src/superlocalmemory/core/key_expander.py +0 -138
- package/src/superlocalmemory/core/lifecycle_state.py +0 -153
- package/src/superlocalmemory/core/maintenance.py +0 -777
- package/src/superlocalmemory/core/maintenance_scheduler.py +0 -507
- package/src/superlocalmemory/core/materialization_control.py +0 -20
- package/src/superlocalmemory/core/mcp_embedder_proxy.py +0 -89
- package/src/superlocalmemory/core/memory_health.py +0 -266
- package/src/superlocalmemory/core/mode_capability.py +0 -111
- package/src/superlocalmemory/core/modes.py +0 -168
- package/src/superlocalmemory/core/mutations.py +0 -688
- package/src/superlocalmemory/core/ollama_embedder.py +0 -266
- package/src/superlocalmemory/core/ollama_validator.py +0 -315
- package/src/superlocalmemory/core/operation_policy.py +0 -92
- package/src/superlocalmemory/core/operation_policy_registry.py +0 -542
- package/src/superlocalmemory/core/operation_request.py +0 -127
- package/src/superlocalmemory/core/ops_remediation.py +0 -542
- package/src/superlocalmemory/core/pii.py +0 -105
- package/src/superlocalmemory/core/platform_utils.py +0 -138
- package/src/superlocalmemory/core/profiles.py +0 -234
- package/src/superlocalmemory/core/progressive_abstraction.py +0 -208
- package/src/superlocalmemory/core/projection_drain.py +0 -380
- package/src/superlocalmemory/core/queue_consumer.py +0 -168
- package/src/superlocalmemory/core/ram_lock.py +0 -160
- package/src/superlocalmemory/core/rate_limit.py +0 -151
- package/src/superlocalmemory/core/recall_gate.py +0 -95
- package/src/superlocalmemory/core/recall_pipeline.py +0 -1337
- package/src/superlocalmemory/core/recall_queue.py +0 -377
- package/src/superlocalmemory/core/recall_worker.py +0 -414
- package/src/superlocalmemory/core/registry.py +0 -121
- package/src/superlocalmemory/core/remember_admission.py +0 -161
- package/src/superlocalmemory/core/remember_runtime.py +0 -1190
- package/src/superlocalmemory/core/remote_mode.py +0 -214
- package/src/superlocalmemory/core/reranker_worker.py +0 -338
- package/src/superlocalmemory/core/safe_fs.py +0 -108
- package/src/superlocalmemory/core/scale_autopromote.py +0 -196
- package/src/superlocalmemory/core/scale_engine.py +0 -915
- package/src/superlocalmemory/core/score_contract.py +0 -82
- package/src/superlocalmemory/core/security_primitives.py +0 -672
- package/src/superlocalmemory/core/session_identity.py +0 -98
- package/src/superlocalmemory/core/shadow_router.py +0 -319
- package/src/superlocalmemory/core/slm_disabled.py +0 -85
- package/src/superlocalmemory/core/status_contract.py +0 -108
- package/src/superlocalmemory/core/store_pipeline.py +0 -1404
- package/src/superlocalmemory/core/summarizer.py +0 -200
- package/src/superlocalmemory/core/tier_manager.py +0 -461
- package/src/superlocalmemory/core/topic_signature.py +0 -156
- package/src/superlocalmemory/core/transactions/__init__.py +0 -78
- package/src/superlocalmemory/core/transactions/concrete_owners.py +0 -604
- package/src/superlocalmemory/core/transactions/erasure.py +0 -825
- package/src/superlocalmemory/core/transactions/manifest.py +0 -255
- package/src/superlocalmemory/core/transactions/manifest_key.py +0 -155
- package/src/superlocalmemory/core/transactions/obligations.py +0 -272
- package/src/superlocalmemory/core/transactions/owners.py +0 -114
- package/src/superlocalmemory/core/transactions/reconciler.py +0 -285
- package/src/superlocalmemory/core/transactions/service.py +0 -330
- package/src/superlocalmemory/core/worker_pool.py +0 -377
- package/src/superlocalmemory/core/working_memory.py +0 -288
- package/src/superlocalmemory/dynamics/__init__.py +0 -0
- package/src/superlocalmemory/dynamics/activation_guided_quantization.py +0 -374
- package/src/superlocalmemory/dynamics/eap_scheduler.py +0 -294
- package/src/superlocalmemory/dynamics/ebbinghaus_langevin_coupling.py +0 -171
- package/src/superlocalmemory/dynamics/fisher_langevin_coupling.py +0 -227
- package/src/superlocalmemory/encoding/__init__.py +0 -0
- package/src/superlocalmemory/encoding/auto_linker.py +0 -308
- package/src/superlocalmemory/encoding/cognitive_consolidator.py +0 -899
- package/src/superlocalmemory/encoding/consolidator.py +0 -472
- package/src/superlocalmemory/encoding/context_generator.py +0 -175
- package/src/superlocalmemory/encoding/emotional.py +0 -189
- package/src/superlocalmemory/encoding/entity_reflexion.py +0 -200
- package/src/superlocalmemory/encoding/entity_resolver.py +0 -687
- package/src/superlocalmemory/encoding/entropy_gate.py +0 -101
- package/src/superlocalmemory/encoding/fact_extractor.py +0 -877
- package/src/superlocalmemory/encoding/foresight.py +0 -93
- package/src/superlocalmemory/encoding/graph_builder.py +0 -346
- package/src/superlocalmemory/encoding/observation_builder.py +0 -177
- package/src/superlocalmemory/encoding/prospective_markers.py +0 -262
- package/src/superlocalmemory/encoding/scene_builder.py +0 -410
- package/src/superlocalmemory/encoding/signal_inference.py +0 -90
- package/src/superlocalmemory/encoding/temporal_parser.py +0 -432
- package/src/superlocalmemory/encoding/temporal_validator.py +0 -572
- package/src/superlocalmemory/encoding/type_router.py +0 -237
- package/src/superlocalmemory/evaluation/__init__.py +0 -13
- package/src/superlocalmemory/evaluation/calibration.py +0 -308
- package/src/superlocalmemory/evolution/__init__.py +0 -29
- package/src/superlocalmemory/evolution/blind_verifier.py +0 -122
- package/src/superlocalmemory/evolution/budget.py +0 -356
- package/src/superlocalmemory/evolution/evolution_store.py +0 -619
- package/src/superlocalmemory/evolution/llm_dispatch.py +0 -559
- package/src/superlocalmemory/evolution/model_selection.py +0 -175
- package/src/superlocalmemory/evolution/mutation_generator.py +0 -226
- package/src/superlocalmemory/evolution/skill_activator.py +0 -270
- package/src/superlocalmemory/evolution/skill_evolver.py +0 -928
- package/src/superlocalmemory/evolution/triggers.py +0 -376
- package/src/superlocalmemory/evolution/types.py +0 -114
- package/src/superlocalmemory/graph/__init__.py +0 -9
- package/src/superlocalmemory/graph/cozo_adjacency.py +0 -122
- package/src/superlocalmemory/graph/cozo_backend.py +0 -751
- package/src/superlocalmemory/hooks/__init__.py +0 -3
- package/src/superlocalmemory/hooks/_outcome_common.py +0 -523
- package/src/superlocalmemory/hooks/adapter_base.py +0 -347
- package/src/superlocalmemory/hooks/antigravity_adapter.py +0 -171
- package/src/superlocalmemory/hooks/auto_capture.py +0 -133
- package/src/superlocalmemory/hooks/auto_invoker.py +0 -521
- package/src/superlocalmemory/hooks/auto_parameterize.py +0 -147
- package/src/superlocalmemory/hooks/auto_recall.py +0 -191
- package/src/superlocalmemory/hooks/auto_recall_hook.py +0 -251
- package/src/superlocalmemory/hooks/before_web_hook.py +0 -131
- package/src/superlocalmemory/hooks/claude_code_hooks.py +0 -637
- package/src/superlocalmemory/hooks/codex_assets.py +0 -251
- package/src/superlocalmemory/hooks/codex_hooks.py +0 -186
- package/src/superlocalmemory/hooks/context_payload.py +0 -311
- package/src/superlocalmemory/hooks/copilot_adapter.py +0 -208
- package/src/superlocalmemory/hooks/cross_platform_connector.py +0 -90
- package/src/superlocalmemory/hooks/cursor_adapter.py +0 -173
- package/src/superlocalmemory/hooks/hook_daemon.py +0 -295
- package/src/superlocalmemory/hooks/hook_handlers.py +0 -822
- package/src/superlocalmemory/hooks/ide_connector.py +0 -246
- package/src/superlocalmemory/hooks/memory_protocol.py +0 -158
- package/src/superlocalmemory/hooks/portable_kit.py +0 -755
- package/src/superlocalmemory/hooks/post_tool_async_hook.py +0 -183
- package/src/superlocalmemory/hooks/post_tool_outcome_hook.py +0 -351
- package/src/superlocalmemory/hooks/prewarm_auth.py +0 -187
- package/src/superlocalmemory/hooks/rules_engine.py +0 -99
- package/src/superlocalmemory/hooks/session_registry.py +0 -330
- package/src/superlocalmemory/hooks/stop_outcome_hook.py +0 -138
- package/src/superlocalmemory/hooks/sync_loop.py +0 -114
- package/src/superlocalmemory/hooks/topic_shift_hook.py +0 -302
- package/src/superlocalmemory/hooks/user_prompt_hook.py +0 -131
- package/src/superlocalmemory/hooks/user_prompt_rehash_hook.py +0 -210
- package/src/superlocalmemory/infra/__init__.py +0 -3
- package/src/superlocalmemory/infra/auth_middleware.py +0 -145
- package/src/superlocalmemory/infra/backup.py +0 -974
- package/src/superlocalmemory/infra/backup_obligations.py +0 -423
- package/src/superlocalmemory/infra/cache_manager.py +0 -267
- package/src/superlocalmemory/infra/cloud_backup.py +0 -788
- package/src/superlocalmemory/infra/daemon_identity.py +0 -300
- package/src/superlocalmemory/infra/data_root.py +0 -238
- package/src/superlocalmemory/infra/event_bus.py +0 -637
- package/src/superlocalmemory/infra/local_diagnostics.py +0 -327
- package/src/superlocalmemory/infra/pid_manager.py +0 -193
- package/src/superlocalmemory/infra/process_identity.py +0 -180
- package/src/superlocalmemory/infra/process_reaper.py +0 -624
- package/src/superlocalmemory/infra/rate_limiter.py +0 -228
- package/src/superlocalmemory/infra/self_heal.py +0 -401
- package/src/superlocalmemory/infra/version_integrity.py +0 -229
- package/src/superlocalmemory/ingestion/__init__.py +0 -13
- package/src/superlocalmemory/ingestion/adapter_manager.py +0 -255
- package/src/superlocalmemory/ingestion/base_adapter.py +0 -171
- package/src/superlocalmemory/ingestion/calendar_adapter.py +0 -349
- package/src/superlocalmemory/ingestion/credentials.py +0 -125
- package/src/superlocalmemory/ingestion/gmail_adapter.py +0 -378
- package/src/superlocalmemory/ingestion/parsers.py +0 -100
- package/src/superlocalmemory/ingestion/transcript_adapter.py +0 -161
- package/src/superlocalmemory/integrations/__init__.py +0 -1
- package/src/superlocalmemory/integrations/bounded_loops_mcp.py +0 -431
- package/src/superlocalmemory/integrations/bounded_loops_v051.py +0 -236
- package/src/superlocalmemory/learning/__init__.py +0 -0
- package/src/superlocalmemory/learning/adaptive.py +0 -172
- package/src/superlocalmemory/learning/arm_catalog.py +0 -97
- package/src/superlocalmemory/learning/assertion_miner.py +0 -403
- package/src/superlocalmemory/learning/bandit.py +0 -654
- package/src/superlocalmemory/learning/bandit_cache.py +0 -131
- package/src/superlocalmemory/learning/behavioral.py +0 -542
- package/src/superlocalmemory/learning/bootstrap.py +0 -298
- package/src/superlocalmemory/learning/consolidation_cycle.py +0 -398
- package/src/superlocalmemory/learning/consolidation_quantization_worker.py +0 -115
- package/src/superlocalmemory/learning/consolidation_worker.py +0 -261
- package/src/superlocalmemory/learning/cross_project.py +0 -408
- package/src/superlocalmemory/learning/database.py +0 -698
- package/src/superlocalmemory/learning/dedup_hnsw.py +0 -413
- package/src/superlocalmemory/learning/engagement.py +0 -487
- package/src/superlocalmemory/learning/engagement_features.py +0 -279
- package/src/superlocalmemory/learning/ensemble.py +0 -309
- package/src/superlocalmemory/learning/entity_compiler.py +0 -356
- package/src/superlocalmemory/learning/fact_outcome_joins.py +0 -207
- package/src/superlocalmemory/learning/features.py +0 -138
- package/src/superlocalmemory/learning/feedback.py +0 -724
- package/src/superlocalmemory/learning/forgetting_scheduler.py +0 -375
- package/src/superlocalmemory/learning/hnsw_dedup.py +0 -69
- package/src/superlocalmemory/learning/labeler.py +0 -85
- package/src/superlocalmemory/learning/legacy_migration.py +0 -316
- package/src/superlocalmemory/learning/lightgbm_subprocess.py +0 -236
- package/src/superlocalmemory/learning/memory_merge.py +0 -175
- package/src/superlocalmemory/learning/model_cache.py +0 -267
- package/src/superlocalmemory/learning/model_rollback.py +0 -281
- package/src/superlocalmemory/learning/outcome_queue.py +0 -306
- package/src/superlocalmemory/learning/outcomes.py +0 -286
- package/src/superlocalmemory/learning/pattern_miner.py +0 -465
- package/src/superlocalmemory/learning/pattern_miner_constants.py +0 -90
- package/src/superlocalmemory/learning/pcos.py +0 -291
- package/src/superlocalmemory/learning/project_context.py +0 -366
- package/src/superlocalmemory/learning/propensity.py +0 -131
- package/src/superlocalmemory/learning/ranker.py +0 -300
- package/src/superlocalmemory/learning/ranker_common.py +0 -163
- package/src/superlocalmemory/learning/ranker_retrain_legacy.py +0 -210
- package/src/superlocalmemory/learning/ranker_retrain_online.py +0 -423
- package/src/superlocalmemory/learning/reward.py +0 -888
- package/src/superlocalmemory/learning/reward_archive.py +0 -223
- package/src/superlocalmemory/learning/reward_boost.py +0 -211
- package/src/superlocalmemory/learning/reward_from_outcomes.py +0 -365
- package/src/superlocalmemory/learning/reward_model.py +0 -144
- package/src/superlocalmemory/learning/reward_proxy.py +0 -578
- package/src/superlocalmemory/learning/shadow_test.py +0 -524
- package/src/superlocalmemory/learning/signal_kinds.py +0 -79
- package/src/superlocalmemory/learning/signal_worker.py +0 -268
- package/src/superlocalmemory/learning/signals.py +0 -646
- package/src/superlocalmemory/learning/skill_performance_miner.py +0 -422
- package/src/superlocalmemory/learning/source_quality.py +0 -828
- package/src/superlocalmemory/learning/trigram_index.py +0 -548
- package/src/superlocalmemory/learning/workflows.py +0 -309
- package/src/superlocalmemory/llm/__init__.py +0 -0
- package/src/superlocalmemory/llm/backbone.py +0 -364
- package/src/superlocalmemory/loops/__init__.py +0 -58
- package/src/superlocalmemory/loops/budget.py +0 -58
- package/src/superlocalmemory/loops/engine.py +0 -174
- package/src/superlocalmemory/loops/ledger.py +0 -298
- package/src/superlocalmemory/loops/models.py +0 -152
- package/src/superlocalmemory/loops/rules.py +0 -52
- package/src/superlocalmemory/math/__init__.py +0 -0
- package/src/superlocalmemory/math/ebbinghaus.py +0 -352
- package/src/superlocalmemory/math/fisher.py +0 -356
- package/src/superlocalmemory/math/fisher_quantized.py +0 -255
- package/src/superlocalmemory/math/hopfield.py +0 -282
- package/src/superlocalmemory/math/langevin.py +0 -411
- package/src/superlocalmemory/math/polar_quant.py +0 -414
- package/src/superlocalmemory/math/qjl.py +0 -115
- package/src/superlocalmemory/math/sheaf.py +0 -261
- package/src/superlocalmemory/math/turbo_quant.py +0 -318
- package/src/superlocalmemory/mcp/__init__.py +0 -0
- package/src/superlocalmemory/mcp/_daemon_proxy.py +0 -203
- package/src/superlocalmemory/mcp/_pool_adapter.py +0 -181
- package/src/superlocalmemory/mcp/_stdin_guard.py +0 -60
- package/src/superlocalmemory/mcp/agent_context.py +0 -115
- package/src/superlocalmemory/mcp/cli_fallback.py +0 -602
- package/src/superlocalmemory/mcp/http_transport.py +0 -85
- package/src/superlocalmemory/mcp/profiles.py +0 -154
- package/src/superlocalmemory/mcp/resources.py +0 -281
- package/src/superlocalmemory/mcp/server.py +0 -480
- package/src/superlocalmemory/mcp/session_binding.py +0 -98
- package/src/superlocalmemory/mcp/shared.py +0 -112
- package/src/superlocalmemory/mcp/tools.py +0 -18
- package/src/superlocalmemory/mcp/tools_active.py +0 -958
- package/src/superlocalmemory/mcp/tools_brain.py +0 -298
- package/src/superlocalmemory/mcp/tools_code_graph.py +0 -1717
- package/src/superlocalmemory/mcp/tools_context.py +0 -239
- package/src/superlocalmemory/mcp/tools_core.py +0 -1112
- package/src/superlocalmemory/mcp/tools_evolution.py +0 -343
- package/src/superlocalmemory/mcp/tools_learning.py +0 -393
- package/src/superlocalmemory/mcp/tools_loops.py +0 -345
- package/src/superlocalmemory/mcp/tools_mesh.py +0 -429
- package/src/superlocalmemory/mcp/tools_ops.py +0 -115
- package/src/superlocalmemory/mcp/tools_optimize.py +0 -322
- package/src/superlocalmemory/mcp/tools_summaries.py +0 -147
- package/src/superlocalmemory/mcp/tools_v28.py +0 -292
- package/src/superlocalmemory/mcp/tools_v3.py +0 -398
- package/src/superlocalmemory/mcp/tools_v33.py +0 -507
- package/src/superlocalmemory/mesh/__init__.py +0 -12
- package/src/superlocalmemory/mesh/broker.py +0 -812
- package/src/superlocalmemory/mesh/broker_security.py +0 -470
- package/src/superlocalmemory/mesh/discovery.py +0 -365
- package/src/superlocalmemory/mesh/lock_protocol.py +0 -313
- package/src/superlocalmemory/mesh/node_identity.py +0 -97
- package/src/superlocalmemory/mesh/outbox_remote.py +0 -429
- package/src/superlocalmemory/mesh/remote_sync.py +0 -829
- package/src/superlocalmemory/mesh/state_sync.py +0 -286
- package/src/superlocalmemory/migrations/__init__.py +0 -5
- package/src/superlocalmemory/migrations/v3_4_25_to_v3_4_26.py +0 -144
- package/src/superlocalmemory/optimize/NOTICE +0 -6
- package/src/superlocalmemory/optimize/__init__.py +0 -0
- package/src/superlocalmemory/optimize/adapters/__init__.py +0 -68
- package/src/superlocalmemory/optimize/adapters/_agent_registry.py +0 -120
- package/src/superlocalmemory/optimize/adapters/anthropic_adapter.py +0 -112
- package/src/superlocalmemory/optimize/adapters/openai_adapter.py +0 -122
- package/src/superlocalmemory/optimize/adapters/wrap.py +0 -228
- package/src/superlocalmemory/optimize/cache/__init__.py +0 -31
- package/src/superlocalmemory/optimize/cache/boundary_store.py +0 -488
- package/src/superlocalmemory/optimize/cache/centroid_store.py +0 -199
- package/src/superlocalmemory/optimize/cache/context_key.py +0 -67
- package/src/superlocalmemory/optimize/cache/exact.py +0 -88
- package/src/superlocalmemory/optimize/cache/invalidation.py +0 -36
- package/src/superlocalmemory/optimize/cache/key_builder.py +0 -111
- package/src/superlocalmemory/optimize/cache/manager.py +0 -737
- package/src/superlocalmemory/optimize/cache/semantic.py +0 -637
- package/src/superlocalmemory/optimize/cache/stampede.py +0 -50
- package/src/superlocalmemory/optimize/compress/__init__.py +0 -17
- package/src/superlocalmemory/optimize/compress/align.py +0 -159
- package/src/superlocalmemory/optimize/compress/ccr.py +0 -116
- package/src/superlocalmemory/optimize/compress/prose_llmlingua.py +0 -71
- package/src/superlocalmemory/optimize/compress/router.py +0 -667
- package/src/superlocalmemory/optimize/config/__init__.py +0 -56
- package/src/superlocalmemory/optimize/config/defaults.py +0 -43
- package/src/superlocalmemory/optimize/config/schema.py +0 -327
- package/src/superlocalmemory/optimize/config/store.py +0 -270
- package/src/superlocalmemory/optimize/metrics/__init__.py +0 -8
- package/src/superlocalmemory/optimize/metrics/counters.py +0 -155
- package/src/superlocalmemory/optimize/metrics/estimator.py +0 -87
- package/src/superlocalmemory/optimize/metrics/exporters.py +0 -77
- package/src/superlocalmemory/optimize/metrics/persistence.py +0 -115
- package/src/superlocalmemory/optimize/proxy/__init__.py +0 -28
- package/src/superlocalmemory/optimize/proxy/_helpers.py +0 -730
- package/src/superlocalmemory/optimize/proxy/anthropic_surface.py +0 -375
- package/src/superlocalmemory/optimize/proxy/capture.py +0 -550
- package/src/superlocalmemory/optimize/proxy/gemini_surface.py +0 -528
- package/src/superlocalmemory/optimize/proxy/lifecycle.py +0 -126
- package/src/superlocalmemory/optimize/proxy/openai_surface.py +0 -465
- package/src/superlocalmemory/optimize/proxy/server.py +0 -199
- package/src/superlocalmemory/optimize/proxy/vertex_surface.py +0 -246
- package/src/superlocalmemory/optimize/storage/__init__.py +0 -0
- package/src/superlocalmemory/optimize/storage/db.py +0 -1185
- package/src/superlocalmemory/optimize/storage/schema.py +0 -205
- package/src/superlocalmemory/parameterization/__init__.py +0 -47
- package/src/superlocalmemory/parameterization/cross_project.py +0 -12
- package/src/superlocalmemory/parameterization/pattern_extractor.py +0 -584
- package/src/superlocalmemory/parameterization/pii_filter.py +0 -106
- package/src/superlocalmemory/parameterization/prompt_injector.py +0 -219
- package/src/superlocalmemory/parameterization/prompt_lifecycle.py +0 -281
- package/src/superlocalmemory/parameterization/soft_prompt_generator.py +0 -542
- package/src/superlocalmemory/parameterization/workflow_miner.py +0 -17
- package/src/superlocalmemory/reliability/__init__.py +0 -45
- package/src/superlocalmemory/reliability/join_liveness.py +0 -301
- package/src/superlocalmemory/reliability/prior_distance.py +0 -243
- package/src/superlocalmemory/retrieval/__init__.py +0 -0
- package/src/superlocalmemory/retrieval/agentic.py +0 -367
- package/src/superlocalmemory/retrieval/ann_index.py +0 -235
- package/src/superlocalmemory/retrieval/bm25_channel.py +0 -451
- package/src/superlocalmemory/retrieval/bridge_discovery.py +0 -253
- package/src/superlocalmemory/retrieval/channel_registry.py +0 -154
- package/src/superlocalmemory/retrieval/channel_status.py +0 -117
- package/src/superlocalmemory/retrieval/engine.py +0 -1615
- package/src/superlocalmemory/retrieval/entity_channel.py +0 -994
- package/src/superlocalmemory/retrieval/forgetting_filter.py +0 -160
- package/src/superlocalmemory/retrieval/fusion.py +0 -81
- package/src/superlocalmemory/retrieval/graph_adjacency.py +0 -219
- package/src/superlocalmemory/retrieval/hopfield_channel.py +0 -465
- package/src/superlocalmemory/retrieval/profile_channel.py +0 -105
- package/src/superlocalmemory/retrieval/quantization_aware_search.py +0 -147
- package/src/superlocalmemory/retrieval/remote_reranker.py +0 -758
- package/src/superlocalmemory/retrieval/reranker.py +0 -674
- package/src/superlocalmemory/retrieval/scope_policy.py +0 -126
- package/src/superlocalmemory/retrieval/semantic_channel.py +0 -638
- package/src/superlocalmemory/retrieval/spreading.py +0 -288
- package/src/superlocalmemory/retrieval/spreading_activation.py +0 -616
- package/src/superlocalmemory/retrieval/strategy.py +0 -248
- package/src/superlocalmemory/retrieval/temporal_channel.py +0 -433
- package/src/superlocalmemory/retrieval/temporal_frame.py +0 -102
- package/src/superlocalmemory/retrieval/temporal_utils.py +0 -122
- package/src/superlocalmemory/retrieval/temporal_validity_filter.py +0 -499
- package/src/superlocalmemory/retrieval/time_window.py +0 -181
- package/src/superlocalmemory/retrieval/vector_store.py +0 -863
- package/src/superlocalmemory/server/__init__.py +0 -1
- package/src/superlocalmemory/server/api.py +0 -310
- package/src/superlocalmemory/server/asset_versions.py +0 -171
- package/src/superlocalmemory/server/bandit_loops.py +0 -158
- package/src/superlocalmemory/server/config_file.py +0 -90
- package/src/superlocalmemory/server/consolidation_runner.py +0 -140
- package/src/superlocalmemory/server/egress_policy.py +0 -258
- package/src/superlocalmemory/server/loopback.py +0 -85
- package/src/superlocalmemory/server/middleware/__init__.py +0 -11
- package/src/superlocalmemory/server/middleware/security_headers.py +0 -144
- package/src/superlocalmemory/server/origin.py +0 -55
- package/src/superlocalmemory/server/profile_runtime.py +0 -515
- package/src/superlocalmemory/server/rbac_enforce.py +0 -194
- package/src/superlocalmemory/server/recall_health.py +0 -343
- package/src/superlocalmemory/server/recall_serializer.py +0 -320
- package/src/superlocalmemory/server/route_mutations.py +0 -104
- package/src/superlocalmemory/server/routes/__init__.py +0 -4
- package/src/superlocalmemory/server/routes/abstraction.py +0 -314
- package/src/superlocalmemory/server/routes/adapters.py +0 -63
- package/src/superlocalmemory/server/routes/agents.py +0 -303
- package/src/superlocalmemory/server/routes/backup.py +0 -869
- package/src/superlocalmemory/server/routes/behavioral.py +0 -659
- package/src/superlocalmemory/server/routes/brain.py +0 -1892
- package/src/superlocalmemory/server/routes/chat.py +0 -393
- package/src/superlocalmemory/server/routes/compliance.py +0 -533
- package/src/superlocalmemory/server/routes/config_api.py +0 -703
- package/src/superlocalmemory/server/routes/data_io.py +0 -329
- package/src/superlocalmemory/server/routes/entity.py +0 -237
- package/src/superlocalmemory/server/routes/events.py +0 -214
- package/src/superlocalmemory/server/routes/evolution.py +0 -510
- package/src/superlocalmemory/server/routes/helpers.py +0 -499
- package/src/superlocalmemory/server/routes/ingest.py +0 -137
- package/src/superlocalmemory/server/routes/insights.py +0 -366
- package/src/superlocalmemory/server/routes/learning.py +0 -834
- package/src/superlocalmemory/server/routes/learning_telemetry.py +0 -154
- package/src/superlocalmemory/server/routes/lifecycle.py +0 -184
- package/src/superlocalmemory/server/routes/memories.py +0 -1661
- package/src/superlocalmemory/server/routes/mesh.py +0 -517
- package/src/superlocalmemory/server/routes/mesh_lock.py +0 -54
- package/src/superlocalmemory/server/routes/mesh_state.py +0 -63
- package/src/superlocalmemory/server/routes/optimize.py +0 -197
- package/src/superlocalmemory/server/routes/prewarm.py +0 -173
- package/src/superlocalmemory/server/routes/profiles.py +0 -292
- package/src/superlocalmemory/server/routes/ratelimit.py +0 -132
- package/src/superlocalmemory/server/routes/rbac.py +0 -366
- package/src/superlocalmemory/server/routes/stats.py +0 -385
- package/src/superlocalmemory/server/routes/tiers.py +0 -222
- package/src/superlocalmemory/server/routes/timeline.py +0 -258
- package/src/superlocalmemory/server/routes/token.py +0 -90
- package/src/superlocalmemory/server/routes/v3_api.py +0 -3023
- package/src/superlocalmemory/server/routes/ws.py +0 -171
- package/src/superlocalmemory/server/security_middleware.py +0 -89
- package/src/superlocalmemory/server/ui.py +0 -354
- package/src/superlocalmemory/server/unified_daemon.py +0 -6326
- package/src/superlocalmemory/server/write_identity.py +0 -195
- package/src/superlocalmemory/storage/__init__.py +0 -0
- package/src/superlocalmemory/storage/_migration_internals.py +0 -638
- package/src/superlocalmemory/storage/_schema_version.py +0 -174
- package/src/superlocalmemory/storage/access_log.py +0 -170
- package/src/superlocalmemory/storage/admission_codec.py +0 -129
- package/src/superlocalmemory/storage/admission_journal.py +0 -843
- package/src/superlocalmemory/storage/agent_experience.py +0 -546
- package/src/superlocalmemory/storage/backup.py +0 -531
- package/src/superlocalmemory/storage/correction_cases.py +0 -670
- package/src/superlocalmemory/storage/database.py +0 -3180
- package/src/superlocalmemory/storage/deferred_writes.py +0 -209
- package/src/superlocalmemory/storage/embedding_codec.py +0 -200
- package/src/superlocalmemory/storage/embedding_migrator.py +0 -672
- package/src/superlocalmemory/storage/erasure_fence.py +0 -45
- package/src/superlocalmemory/storage/execution_learning.py +0 -285
- package/src/superlocalmemory/storage/external_evidence.py +0 -359
- package/src/superlocalmemory/storage/generation_fence.py +0 -63
- package/src/superlocalmemory/storage/lineage_retention.py +0 -236
- package/src/superlocalmemory/storage/logical_edges.py +0 -86
- package/src/superlocalmemory/storage/memory_write.py +0 -115
- package/src/superlocalmemory/storage/migration_runner.py +0 -895
- package/src/superlocalmemory/storage/migration_v33.py +0 -140
- package/src/superlocalmemory/storage/migrations/M001_add_signal_features_columns.py +0 -67
- package/src/superlocalmemory/storage/migrations/M002_model_state_history.py +0 -107
- package/src/superlocalmemory/storage/migrations/M003_migration_log.py +0 -38
- package/src/superlocalmemory/storage/migrations/M004_cross_platform_sync_log.py +0 -46
- package/src/superlocalmemory/storage/migrations/M005_bandit_tables.py +0 -75
- package/src/superlocalmemory/storage/migrations/M006_action_outcomes_reward.py +0 -75
- package/src/superlocalmemory/storage/migrations/M007_pending_outcomes.py +0 -63
- package/src/superlocalmemory/storage/migrations/M009_model_lineage.py +0 -94
- package/src/superlocalmemory/storage/migrations/M010_evolution_config.py +0 -80
- package/src/superlocalmemory/storage/migrations/M011_archive_and_merge.py +0 -87
- package/src/superlocalmemory/storage/migrations/M012_shadow_observations.py +0 -72
- package/src/superlocalmemory/storage/migrations/M013_bi_temporal_columns.py +0 -55
- package/src/superlocalmemory/storage/migrations/M014_v345_scale_ready.py +0 -45
- package/src/superlocalmemory/storage/migrations/M015_add_pinned_column.py +0 -58
- package/src/superlocalmemory/storage/migrations/M016_add_scope_support.py +0 -120
- package/src/superlocalmemory/storage/migrations/M017_ccq_scope_column.py +0 -79
- package/src/superlocalmemory/storage/migrations/M018_ingestion_operations.py +0 -120
- package/src/superlocalmemory/storage/migrations/M019_derivation_lineage.py +0 -54
- package/src/superlocalmemory/storage/migrations/M020_model_state_integrity.py +0 -52
- package/src/superlocalmemory/storage/migrations/M021_ingestion_log_profile.py +0 -108
- package/src/superlocalmemory/storage/migrations/M022_entity_aliases_profile.py +0 -86
- package/src/superlocalmemory/storage/migrations/M023_mesh_profile_isolation.py +0 -194
- package/src/superlocalmemory/storage/migrations/M024_rbac_users_roles.py +0 -87
- package/src/superlocalmemory/storage/migrations/M025_perf_indexes.py +0 -90
- package/src/superlocalmemory/storage/migrations/M026_rbac_memberships_fk.py +0 -136
- package/src/superlocalmemory/storage/migrations/M027_transferable_patterns_profile.py +0 -163
- package/src/superlocalmemory/storage/migrations/M028_fact_entity_associations.py +0 -305
- package/src/superlocalmemory/storage/migrations/M029_behavioral_history_indexes.py +0 -137
- package/src/superlocalmemory/storage/migrations/M030_entity_explorer_indexes.py +0 -93
- package/src/superlocalmemory/storage/migrations/M031_dead_letter_operations.py +0 -80
- package/src/superlocalmemory/storage/migrations/M032_write_coordinator_admission.py +0 -188
- package/src/superlocalmemory/storage/migrations/M033_projection_transactions.py +0 -148
- package/src/superlocalmemory/storage/migrations/M034_obligation_integrity.py +0 -58
- package/src/superlocalmemory/storage/migrations/M035_erasure_receipts.py +0 -113
- package/src/superlocalmemory/storage/migrations/M036_vector_row_map.py +0 -107
- package/src/superlocalmemory/storage/migrations/M037_manifest_hmac_version.py +0 -162
- package/src/superlocalmemory/storage/migrations/M038_learning_feedback_channel.py +0 -77
- package/src/superlocalmemory/storage/migrations/M039_scene_fact_members.py +0 -137
- package/src/superlocalmemory/storage/migrations/M040_agent_experience_receipts.py +0 -254
- package/src/superlocalmemory/storage/migrations/M041_external_evidence_receipts.py +0 -189
- package/src/superlocalmemory/storage/migrations/M042_correction_case_ledger.py +0 -245
- package/src/superlocalmemory/storage/migrations/M043_quarantine_display_summaries.py +0 -512
- package/src/superlocalmemory/storage/migrations/M044_play_carries_its_own_evidence.py +0 -127
- package/src/superlocalmemory/storage/migrations/M045_fact_outcome_score.py +0 -158
- package/src/superlocalmemory/storage/migrations/M046_prospective_memory_has_its_own_name.py +0 -620
- package/src/superlocalmemory/storage/migrations/M047_fisher_vectors_are_stored_like_every_other_vector.py +0 -306
- package/src/superlocalmemory/storage/migrations/M048_upcoming_holds_only_what_is_upcoming.py +0 -229
- package/src/superlocalmemory/storage/migrations/M049_a_schema_version_marker_is_one_row.py +0 -201
- package/src/superlocalmemory/storage/migrations/M050_execution_learning_v2.py +0 -70
- package/src/superlocalmemory/storage/migrations/__init__.py +0 -103
- package/src/superlocalmemory/storage/migrations.py +0 -333
- package/src/superlocalmemory/storage/models.py +0 -500
- package/src/superlocalmemory/storage/projection_outbox.py +0 -346
- package/src/superlocalmemory/storage/quantized_store.py +0 -280
- package/src/superlocalmemory/storage/read_connection.py +0 -115
- package/src/superlocalmemory/storage/retention_policy.py +0 -860
- package/src/superlocalmemory/storage/schema.py +0 -1108
- package/src/superlocalmemory/storage/schema_code_graph.py +0 -282
- package/src/superlocalmemory/storage/schema_v32.py +0 -382
- package/src/superlocalmemory/storage/schema_v3410.py +0 -159
- package/src/superlocalmemory/storage/schema_v3411.py +0 -149
- package/src/superlocalmemory/storage/schema_v343.py +0 -315
- package/src/superlocalmemory/storage/schema_v345.py +0 -109
- package/src/superlocalmemory/storage/schema_v347.py +0 -140
- package/src/superlocalmemory/storage/sqlite_vectors.py +0 -169
- package/src/superlocalmemory/storage/v2_migrator.py +0 -466
- package/src/superlocalmemory/storage/write_coordinator.py +0 -949
- package/src/superlocalmemory/storage/write_lock.py +0 -88
- package/src/superlocalmemory/summaries/__init__.py +0 -37
- package/src/superlocalmemory/summaries/base.py +0 -267
- package/src/superlocalmemory/summaries/daily_reflection.py +0 -340
- package/src/superlocalmemory/summaries/non_answer.py +0 -223
- package/src/superlocalmemory/summaries/project_work_log.py +0 -440
- package/src/superlocalmemory/summaries/session_summary.py +0 -311
- package/src/superlocalmemory/trust/__init__.py +0 -0
- package/src/superlocalmemory/trust/gate.py +0 -171
- package/src/superlocalmemory/trust/provenance.py +0 -124
- package/src/superlocalmemory/trust/scorer.py +0 -413
- package/src/superlocalmemory/trust/signals.py +0 -153
- package/src/superlocalmemory/ui/assets/slm-icon-white.svg +0 -64
- package/src/superlocalmemory/ui/assets/slm-icon.svg +0 -36
- package/src/superlocalmemory/ui/css/brain.css +0 -409
- package/src/superlocalmemory/ui/css/design-system.css +0 -696
- package/src/superlocalmemory/ui/css/legacy-dashboard.css +0 -663
- package/src/superlocalmemory/ui/css/neural-glass.css +0 -1599
- package/src/superlocalmemory/ui/css/od-bridge.css +0 -158
- package/src/superlocalmemory/ui/favicon.svg +0 -36
- package/src/superlocalmemory/ui/index.html +0 -1638
- package/src/superlocalmemory/ui/js/agents.js +0 -192
- package/src/superlocalmemory/ui/js/auto-settings.js +0 -624
- package/src/superlocalmemory/ui/js/brain.js +0 -1400
- package/src/superlocalmemory/ui/js/clusters.js +0 -326
- package/src/superlocalmemory/ui/js/compliance.js +0 -307
- package/src/superlocalmemory/ui/js/core.js +0 -566
- package/src/superlocalmemory/ui/js/dashboard.js +0 -503
- package/src/superlocalmemory/ui/js/event-delegation.js +0 -113
- package/src/superlocalmemory/ui/js/events.js +0 -178
- package/src/superlocalmemory/ui/js/fact-detail.js +0 -142
- package/src/superlocalmemory/ui/js/feedback.js +0 -339
- package/src/superlocalmemory/ui/js/graph-event-bus.js +0 -83
- package/src/superlocalmemory/ui/js/graph-filters.js +0 -220
- package/src/superlocalmemory/ui/js/graph-ui.js +0 -214
- package/src/superlocalmemory/ui/js/ide-status.js +0 -115
- package/src/superlocalmemory/ui/js/init.js +0 -54
- package/src/superlocalmemory/ui/js/knowledge-graph.js +0 -945
- package/src/superlocalmemory/ui/js/lifecycle.js +0 -387
- package/src/superlocalmemory/ui/js/math-health.js +0 -114
- package/src/superlocalmemory/ui/js/memories.js +0 -394
- package/src/superlocalmemory/ui/js/memory-chat.js +0 -371
- package/src/superlocalmemory/ui/js/memory-timeline.js +0 -265
- package/src/superlocalmemory/ui/js/modal.js +0 -733
- package/src/superlocalmemory/ui/js/ng-entities.js +0 -298
- package/src/superlocalmemory/ui/js/ng-health.js +0 -208
- package/src/superlocalmemory/ui/js/ng-ingestion.js +0 -203
- package/src/superlocalmemory/ui/js/ng-mesh.js +0 -374
- package/src/superlocalmemory/ui/js/ng-shell.js +0 -524
- package/src/superlocalmemory/ui/js/ng-skills.js +0 -663
- package/src/superlocalmemory/ui/js/od-agents.js +0 -588
- package/src/superlocalmemory/ui/js/od-auth-gate.js +0 -257
- package/src/superlocalmemory/ui/js/od-backup.js +0 -878
- package/src/superlocalmemory/ui/js/od-boundedloops.js +0 -324
- package/src/superlocalmemory/ui/js/od-brain.js +0 -1095
- package/src/superlocalmemory/ui/js/od-compliance-ext.js +0 -301
- package/src/superlocalmemory/ui/js/od-components.js +0 -147
- package/src/superlocalmemory/ui/js/od-entities.js +0 -622
- package/src/superlocalmemory/ui/js/od-graph.js +0 -776
- package/src/superlocalmemory/ui/js/od-health.js +0 -579
- package/src/superlocalmemory/ui/js/od-mcp.js +0 -508
- package/src/superlocalmemory/ui/js/od-memories.js +0 -1499
- package/src/superlocalmemory/ui/js/od-mesh.js +0 -645
- package/src/superlocalmemory/ui/js/od-operations.js +0 -1268
- package/src/superlocalmemory/ui/js/od-ops-health.js +0 -417
- package/src/superlocalmemory/ui/js/od-optimize.js +0 -828
- package/src/superlocalmemory/ui/js/od-settings.js +0 -1275
- package/src/superlocalmemory/ui/js/od-shell.js +0 -819
- package/src/superlocalmemory/ui/js/od-skills.js +0 -600
- package/src/superlocalmemory/ui/js/od-team.js +0 -265
- package/src/superlocalmemory/ui/js/optimize.js +0 -191
- package/src/superlocalmemory/ui/js/profiles.js +0 -362
- package/src/superlocalmemory/ui/js/quick-actions.js +0 -334
- package/src/superlocalmemory/ui/js/recall-lab.js +0 -373
- package/src/superlocalmemory/ui/js/search.js +0 -86
- package/src/superlocalmemory/ui/js/settings.js +0 -556
- package/src/superlocalmemory/ui/js/timeline.js +0 -62
- package/src/superlocalmemory/ui/js/trust-dashboard.js +0 -225
- package/src/superlocalmemory/ui/vendor/bootstrap-icons/bootstrap-icons.css +0 -2018
- package/src/superlocalmemory/ui/vendor/bootstrap-icons/fonts/bootstrap-icons.woff +0 -0
- package/src/superlocalmemory/ui/vendor/bootstrap-icons/fonts/bootstrap-icons.woff2 +0 -0
- package/src/superlocalmemory/ui/vendor/bootstrap.bundle.min.js +0 -7
- package/src/superlocalmemory/ui/vendor/bootstrap.min.css +0 -6
- package/src/superlocalmemory/ui/vendor/d3.v7.min.js +0 -2
- package/src/superlocalmemory/ui/vendor/graphology-library.min.js +0 -2
- package/src/superlocalmemory/ui/vendor/graphology.umd.min.js +0 -2
- package/src/superlocalmemory/ui/vendor/inter-ui/inter-variable.min.css +0 -8
- package/src/superlocalmemory/ui/vendor/inter-ui/variable/InterVariable-Italic.woff2 +0 -0
- package/src/superlocalmemory/ui/vendor/inter-ui/variable/InterVariable.woff2 +0 -0
- package/src/superlocalmemory/ui/vendor/sigma.min.js +0 -1
- package/src/superlocalmemory/vector/__init__.py +0 -9
- package/src/superlocalmemory/vector/lancedb_backend.py +0 -366
|
@@ -1,597 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
|
|
2
|
-
# Licensed under AGPL-3.0-or-later - see LICENSE file
|
|
3
|
-
|
|
4
|
-
"""Whole-graph structural metrics for ``fact_importance``.
|
|
5
|
-
|
|
6
|
-
WHAT THIS IS FOR
|
|
7
|
-
----------------
|
|
8
|
-
Recall multiplies a candidate's activation by ``min(1 + pagerank * 2, 2)`` at
|
|
9
|
-
every hop and biases it toward the communities its query seeds belong to. Both
|
|
10
|
-
numbers come from ``fact_importance``. A memory missing from that table is found
|
|
11
|
-
by the graph walk and then ranked as though it had no position in the graph at
|
|
12
|
-
all -- so the table's coverage is a recall-quality property, not a reporting
|
|
13
|
-
nicety.
|
|
14
|
-
|
|
15
|
-
WHY ONE WRITER
|
|
16
|
-
--------------
|
|
17
|
-
Two writers were filling this table with numbers that do not mean the same
|
|
18
|
-
thing. The whole-graph pass (``core/graph_analyzer.py``) computes PageRank over
|
|
19
|
-
every fact and edge. A second path compiled an entity's facts and, on finding no
|
|
20
|
-
PageRank for them, computed its own over a ``LIMIT 50`` slice of facts sharing
|
|
21
|
-
that one entity -- a near-clique of at most 50 nodes, which hands every member
|
|
22
|
-
roughly ``1/n``. Measured on the author's store: the whole-graph pass produced a
|
|
23
|
-
maximum of 0.008744 and a median of 0.000214, while the local pass wrote 0.1 --
|
|
24
|
-
**eleven times the largest real score, and roughly 470x the median**. Those facts
|
|
25
|
-
took the maximum hop boost the formula allows (1.2 against everyone else's
|
|
26
|
-
1.0004) for no reason other than having shared an entity with a few others, and
|
|
27
|
-
they were written with no community, so the community bias could not see them
|
|
28
|
-
either. The signal was not stale, it was wrong.
|
|
29
|
-
|
|
30
|
-
So: one function computes this table, and it computes it over the whole graph.
|
|
31
|
-
|
|
32
|
-
WHICH ENGINE, AND WHY IT IS NOT THE GRAPH ENGINE
|
|
33
|
-
-----------------------------------------------
|
|
34
|
-
Two adapters compute the same function of the same edge set. In-process wins on
|
|
35
|
-
measurement, so it is the default. Timed on a copy of the author's 208,151-edge
|
|
36
|
-
store, each algorithm alone, warmed:
|
|
37
|
-
|
|
38
|
-
algorithm in process graph engine winner
|
|
39
|
-
PageRank 0.36 s 0.38 s tie
|
|
40
|
-
Louvain 1.98 s 5.17 s in process, 2.6x
|
|
41
|
-
whole pass 2.33 s 5.56 s in process, 2.4x
|
|
42
|
-
|
|
43
|
-
An earlier reading of 1.88 s for ``nx.pagerank`` against 0.13 s was a cold scipy
|
|
44
|
-
import counted as compute -- the third time a first-call warm-up has been
|
|
45
|
-
misread as a backend difference in this release. Both engines are deterministic
|
|
46
|
-
across runs (checked, not assumed) and agree to Spearman rho 0.996, so the choice
|
|
47
|
-
is a cost decision and may be revisited by measurement, not by argument.
|
|
48
|
-
|
|
49
|
-
The graph engine still earns its keep, just not here: reading the adjacency for
|
|
50
|
-
one recall measured 395 ms against SQLite's 2,477 ms on the same store, 6.3x, and
|
|
51
|
-
the gap widens with edge count. Those two figures were measured by hand on a copy
|
|
52
|
-
of a 208,151-edge store and no test reproduces them -- see the table in
|
|
53
|
-
``graph/cozo_adjacency`` for what was run. That is a latency win on the recall path; this
|
|
54
|
-
pass is background work where 2 s versus 5 s buys nothing.
|
|
55
|
-
|
|
56
|
-
Its ``pagerank()``/``community_detect()`` helpers are NOT used and could not have
|
|
57
|
-
been: they take their node set from the ``entity`` relation and their edges from
|
|
58
|
-
``edge``, which hold canonical entity IDs and fact IDs respectively.
|
|
59
|
-
``pagerank()`` therefore indexes an entity-keyed dict with a fact ID, raises
|
|
60
|
-
KeyError, and returns ``{}`` -- verified against the real store, where it
|
|
61
|
-
returned nothing and ``community_detect`` returned 1,386 singleton communities of
|
|
62
|
-
entities and not one fact. The adapter here calls the native
|
|
63
|
-
``PageRank``/``CommunityDetectionLouvain`` fixed rules, which operate on whatever
|
|
64
|
-
relation they are handed.
|
|
65
|
-
|
|
66
|
-
WHAT COUNTS AS A NODE, AND AS AN EDGE
|
|
67
|
-
-------------------------------------
|
|
68
|
-
Nodes are the profile's *visible* facts, isolated ones included: a fact with no
|
|
69
|
-
edges still needs a row, or the ranker treats "no position in the graph" and "not
|
|
70
|
-
computed yet" as the same thing. Edges come from ``iter_logical_edges``, which
|
|
71
|
-
already excludes any edge with a withheld or soft-deleted endpoint -- the same
|
|
72
|
-
predicate the retrieval channel prunes its adjacency with. The previous
|
|
73
|
-
whole-graph pass read ``graph_edges`` and ``atomic_facts`` raw, so it ranked
|
|
74
|
-
1,299 unreturnable facts alongside real memories and diluted every real score.
|
|
75
|
-
|
|
76
|
-
PageRank runs on the edge-connected subgraph and the isolated facts are then
|
|
77
|
-
given the uniform teleport share ``(1 - damping) / N`` over the full node set,
|
|
78
|
-
with the connected scores scaled to leave room for it. That convention lives
|
|
79
|
-
here, in the port, so both engines produce numbers on one scale -- the ranker
|
|
80
|
-
reads absolute values, so an engine swap that shifted the scale would silently
|
|
81
|
-
re-tune every boost in the system.
|
|
82
|
-
"""
|
|
83
|
-
|
|
84
|
-
from __future__ import annotations
|
|
85
|
-
|
|
86
|
-
import logging
|
|
87
|
-
import sqlite3
|
|
88
|
-
import time
|
|
89
|
-
from dataclasses import dataclass, field
|
|
90
|
-
from typing import Any
|
|
91
|
-
|
|
92
|
-
from contextlib import contextmanager
|
|
93
|
-
|
|
94
|
-
from superlocalmemory.storage.logical_edges import iter_logical_edges
|
|
95
|
-
|
|
96
|
-
logger = logging.getLogger(__name__)
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
@contextmanager
|
|
100
|
-
def _short_connection(db: Any) -> Any:
|
|
101
|
-
"""A connection held for one read or one write, never across the compute.
|
|
102
|
-
|
|
103
|
-
``raw_connection`` takes the manager's write lock, so holding it around a
|
|
104
|
-
two-to-ten-second graph computation would stall every store for that long.
|
|
105
|
-
The pass therefore reads, releases, computes, and writes.
|
|
106
|
-
|
|
107
|
-
The consolidation cycle passes a minimal proxy that owns a bare sqlite3
|
|
108
|
-
connection and exposes ``execute`` only. Supporting it here is what keeps
|
|
109
|
-
this the single writer of the table; the alternative was a second
|
|
110
|
-
implementation for that one caller, which is how the two disagreeing
|
|
111
|
-
PageRanks happened in the first place.
|
|
112
|
-
"""
|
|
113
|
-
# Resolved on the TYPE, and the fallback is checked with isinstance, for the
|
|
114
|
-
# reason written up in retrieval/scope_policy.py: a MagicMock fabricates any
|
|
115
|
-
# attribute you ask for, so ``getattr(db, "raw_connection")`` returns a
|
|
116
|
-
# callable whose context manager yields another MagicMock -- and iterating
|
|
117
|
-
# that raises, which this module's error path then reports as "could not read
|
|
118
|
-
# the graph" for a store that is perfectly readable. The suite passes exactly
|
|
119
|
-
# such a mock, and it cost a debugging round to notice the pass had not run
|
|
120
|
-
# rather than found nothing.
|
|
121
|
-
raw = getattr(type(db), "raw_connection", None)
|
|
122
|
-
if callable(raw):
|
|
123
|
-
with raw(db) as conn:
|
|
124
|
-
yield conn
|
|
125
|
-
return
|
|
126
|
-
conn = getattr(db, "_conn", None)
|
|
127
|
-
if not isinstance(conn, sqlite3.Connection):
|
|
128
|
-
raise TypeError(
|
|
129
|
-
f"{type(db).__name__} exposes no connection to compute metrics on"
|
|
130
|
-
)
|
|
131
|
-
yield conn
|
|
132
|
-
conn.commit()
|
|
133
|
-
|
|
134
|
-
#: PageRank damping. Matches the previous whole-graph pass so scores stay
|
|
135
|
-
#: comparable across the version that introduced this module.
|
|
136
|
-
DEFAULT_DAMPING = 0.85
|
|
137
|
-
|
|
138
|
-
#: Betweenness centrality is O(V*E). At 4k facts and 130k edges that is minutes,
|
|
139
|
-
#: and at the 12k/208k store it is hours -- which is the likeliest reason the
|
|
140
|
-
#: whole-graph pass had run exactly once in nine days. Nothing in retrieval reads
|
|
141
|
-
#: ``bridge_score``; only the dashboard displays it. So it is computed under a
|
|
142
|
-
#: node ceiling and reported as skipped above it, rather than being the reason
|
|
143
|
-
#: PageRank never lands.
|
|
144
|
-
BRIDGE_NODE_LIMIT = 1500
|
|
145
|
-
|
|
146
|
-
#: Louvain returns a hierarchy of partitions per node. Level 0 is the coarsest,
|
|
147
|
-
#: and on the author's store it yields 13 communities against the 11
|
|
148
|
-
#: meaningfully-sized ones the previous pass found -- so the community bias keeps
|
|
149
|
-
#: the granularity it was tuned against instead of being handed 210 fragments.
|
|
150
|
-
LOUVAIN_LEVEL = 0
|
|
151
|
-
|
|
152
|
-
#: A projection is only trustworthy if it agrees with the store. If Cozo's edge
|
|
153
|
-
#: count for this profile differs from SQLite's by more than this fraction, the
|
|
154
|
-
#: pass computes on SQLite instead and says so, rather than ranking the store's
|
|
155
|
-
#: memories from a graph the store does not have.
|
|
156
|
-
MAX_PROJECTION_DRIFT = 0.02
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
@dataclass(frozen=True)
|
|
160
|
-
class GraphMetricsReport:
|
|
161
|
-
"""What one pass actually did. No field here is inferred from another."""
|
|
162
|
-
|
|
163
|
-
profile_id: str
|
|
164
|
-
engine: str = "none"
|
|
165
|
-
facts: int = 0
|
|
166
|
-
edges: int = 0
|
|
167
|
-
connected: int = 0
|
|
168
|
-
isolated: int = 0
|
|
169
|
-
communities: int = 0
|
|
170
|
-
written: int = 0
|
|
171
|
-
removed: int = 0
|
|
172
|
-
bridges_computed: bool = False
|
|
173
|
-
duration_ms: int = 0
|
|
174
|
-
error: str | None = None
|
|
175
|
-
notes: tuple[str, ...] = field(default_factory=tuple)
|
|
176
|
-
|
|
177
|
-
@property
|
|
178
|
-
def ok(self) -> bool:
|
|
179
|
-
return self.error is None
|
|
180
|
-
|
|
181
|
-
def summary(self) -> str:
|
|
182
|
-
if self.error:
|
|
183
|
-
return f"graph metrics for {self.profile_id} FAILED: {self.error}"
|
|
184
|
-
return (
|
|
185
|
-
f"graph metrics for {self.profile_id}: {self.written} facts "
|
|
186
|
-
f"({self.connected} connected, {self.isolated} isolated), "
|
|
187
|
-
f"{self.edges} edges, {self.communities} communities, "
|
|
188
|
-
f"engine={self.engine}, {self.duration_ms} ms"
|
|
189
|
-
)
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
# ----------------------------------------------------------------------
|
|
193
|
-
# Engines. Each returns metrics for the edge-connected nodes only; the
|
|
194
|
-
# isolated-node convention belongs to the caller, once, for both.
|
|
195
|
-
# ----------------------------------------------------------------------
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
def _cozo_metrics(
|
|
199
|
-
backend: Any, profile_id: str, damping: float
|
|
200
|
-
) -> tuple[dict[str, float], dict[str, int]]:
|
|
201
|
-
"""PageRank and Louvain from Cozo's native fixed rules.
|
|
202
|
-
|
|
203
|
-
Both queries filter on ``profile_id``: the projection holds every profile's
|
|
204
|
-
edges in one relation, and an unfiltered rule would rank one profile's
|
|
205
|
-
memories using another's graph.
|
|
206
|
-
"""
|
|
207
|
-
client = backend._db # the module-private client wrapper; no public accessor
|
|
208
|
-
pr_rows = client.run(
|
|
209
|
-
"rel[a, b, w] := *edge{from_id: a, to_id: b, weight: w, "
|
|
210
|
-
" profile_id: $pid}\n"
|
|
211
|
-
"?[node, score] <~ PageRank(rel[a, b, w], theta: $theta)",
|
|
212
|
-
{"pid": profile_id, "theta": damping},
|
|
213
|
-
)
|
|
214
|
-
pagerank = {str(r[0]): float(r[1]) for r in pr_rows.values.tolist()}
|
|
215
|
-
|
|
216
|
-
comm_rows = client.run(
|
|
217
|
-
"rel[a, b, w] := *edge{from_id: a, to_id: b, weight: w, "
|
|
218
|
-
" profile_id: $pid}\n"
|
|
219
|
-
"?[grp, node] <~ CommunityDetectionLouvain(rel[a, b, w])",
|
|
220
|
-
{"pid": profile_id},
|
|
221
|
-
)
|
|
222
|
-
communities: dict[str, int] = {}
|
|
223
|
-
for grp, node in comm_rows.values.tolist():
|
|
224
|
-
label = grp[LOUVAIN_LEVEL] if isinstance(grp, (list, tuple)) else grp
|
|
225
|
-
communities[str(node)] = int(label)
|
|
226
|
-
return pagerank, communities
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
def _networkx_metrics(
|
|
230
|
-
edges: list[tuple[str, str, float]], damping: float
|
|
231
|
-
) -> tuple[dict[str, float], dict[str, int]]:
|
|
232
|
-
"""The same two metrics without a graph projection to read."""
|
|
233
|
-
import networkx as nx
|
|
234
|
-
from networkx.algorithms.community import louvain_communities
|
|
235
|
-
|
|
236
|
-
digraph = nx.DiGraph()
|
|
237
|
-
for source, target, weight in edges:
|
|
238
|
-
if digraph.has_edge(source, target):
|
|
239
|
-
if weight > digraph[source][target].get("weight", 0.0):
|
|
240
|
-
digraph[source][target]["weight"] = weight
|
|
241
|
-
else:
|
|
242
|
-
digraph.add_edge(source, target, weight=weight)
|
|
243
|
-
if digraph.number_of_nodes() == 0:
|
|
244
|
-
return {}, {}
|
|
245
|
-
|
|
246
|
-
pagerank = nx.pagerank(digraph, alpha=damping, weight="weight")
|
|
247
|
-
communities: dict[str, int] = {}
|
|
248
|
-
try:
|
|
249
|
-
partitions = louvain_communities(
|
|
250
|
-
digraph.to_undirected(), weight="weight", seed=42,
|
|
251
|
-
)
|
|
252
|
-
for label, members in enumerate(partitions):
|
|
253
|
-
for node in members:
|
|
254
|
-
communities[str(node)] = label
|
|
255
|
-
except Exception as exc: # noqa: BLE001 -- a partition is optional, a score is not
|
|
256
|
-
logger.debug("Louvain partition unavailable: %s", exc)
|
|
257
|
-
return pagerank, communities
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
def _bridge_scores(
|
|
261
|
-
edges: list[tuple[str, str, float]], node_count: int
|
|
262
|
-
) -> dict[str, float] | None:
|
|
263
|
-
"""Sampled betweenness, or None when the graph is too big to afford it."""
|
|
264
|
-
if node_count > BRIDGE_NODE_LIMIT or node_count <= 2:
|
|
265
|
-
return None
|
|
266
|
-
try:
|
|
267
|
-
import networkx as nx
|
|
268
|
-
|
|
269
|
-
graph = nx.DiGraph()
|
|
270
|
-
for source, target, weight in edges:
|
|
271
|
-
graph.add_edge(source, target, weight=weight)
|
|
272
|
-
return nx.betweenness_centrality(graph, weight="weight", normalized=True)
|
|
273
|
-
except Exception as exc: # noqa: BLE001
|
|
274
|
-
logger.debug("Bridge scores unavailable: %s", exc)
|
|
275
|
-
return None
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
# ----------------------------------------------------------------------
|
|
279
|
-
# The pass
|
|
280
|
-
# ----------------------------------------------------------------------
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
def _visible_fact_ids(conn: sqlite3.Connection, profile_id: str) -> list[str]:
|
|
284
|
-
from superlocalmemory.storage.database import (
|
|
285
|
-
visible_fact_clause_for_connection,
|
|
286
|
-
)
|
|
287
|
-
|
|
288
|
-
clause = visible_fact_clause_for_connection(conn)
|
|
289
|
-
rows = conn.execute(
|
|
290
|
-
f"SELECT fact_id FROM atomic_facts WHERE profile_id = ?{clause}",
|
|
291
|
-
(profile_id,),
|
|
292
|
-
).fetchall()
|
|
293
|
-
return [str(row[0]) for row in rows]
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
def _projection_usable(
|
|
297
|
-
backend: Any, profile_id: str, sqlite_edges: int
|
|
298
|
-
) -> tuple[bool, str]:
|
|
299
|
-
"""Whether Cozo's edge set is close enough to the store's to rank from."""
|
|
300
|
-
if backend is None:
|
|
301
|
-
return False, "no graph projection"
|
|
302
|
-
try:
|
|
303
|
-
rows = backend._db.run(
|
|
304
|
-
"?[count(a)] := *edge{from_id: a, profile_id: $pid}",
|
|
305
|
-
{"pid": profile_id},
|
|
306
|
-
)
|
|
307
|
-
projected = int(rows.values.tolist()[0][0]) if len(rows) else 0
|
|
308
|
-
except Exception as exc: # noqa: BLE001
|
|
309
|
-
return False, f"projection unreadable: {exc}"
|
|
310
|
-
if sqlite_edges == 0:
|
|
311
|
-
return projected == 0, "both empty"
|
|
312
|
-
drift = abs(projected - sqlite_edges) / float(sqlite_edges)
|
|
313
|
-
if drift > MAX_PROJECTION_DRIFT:
|
|
314
|
-
return False, (
|
|
315
|
-
f"projection drifted {drift:.1%} "
|
|
316
|
-
f"({projected} projected vs {sqlite_edges} stored)"
|
|
317
|
-
)
|
|
318
|
-
return True, f"projection within {drift:.2%}"
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
def _projection_is_current(db: Any, profile_id: str) -> bool:
|
|
322
|
-
"""Whether every change SQLite has recorded has reached the projection.
|
|
323
|
-
|
|
324
|
-
Two engines ranking two different graphs is worse than one engine ranking
|
|
325
|
-
the right one, because the difference is invisible in the output: both
|
|
326
|
-
return a full table of plausible scores. The queue is the only place that
|
|
327
|
-
records a change the projection has not seen yet, so an outstanding row
|
|
328
|
-
means the projection is a graph the store no longer has.
|
|
329
|
-
|
|
330
|
-
Absent queue means an older store that never had one; there is nothing to
|
|
331
|
-
be behind on, so the projection is as current as it can be.
|
|
332
|
-
"""
|
|
333
|
-
try:
|
|
334
|
-
from superlocalmemory.storage import projection_outbox
|
|
335
|
-
|
|
336
|
-
if not projection_outbox.is_available(db):
|
|
337
|
-
return True
|
|
338
|
-
with _short_connection(db) as conn:
|
|
339
|
-
row = conn.execute(
|
|
340
|
-
"SELECT COUNT(*) FROM projection_outbox WHERE profile_id = ?",
|
|
341
|
-
(profile_id,),
|
|
342
|
-
).fetchone()
|
|
343
|
-
return int(row[0] if row else 0) == 0
|
|
344
|
-
except Exception as exc: # noqa: BLE001 -- unreadable means do not trust it
|
|
345
|
-
logger.debug("graph metrics: cannot check projection currency: %s", exc)
|
|
346
|
-
return False
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
def compute_graph_metrics(
|
|
350
|
-
db: Any,
|
|
351
|
-
profile_id: str,
|
|
352
|
-
*,
|
|
353
|
-
backend: Any = None,
|
|
354
|
-
damping: float = DEFAULT_DAMPING,
|
|
355
|
-
prefer: str = "networkx",
|
|
356
|
-
) -> GraphMetricsReport:
|
|
357
|
-
"""Recompute ``fact_importance`` for one profile. Returns what it did.
|
|
358
|
-
|
|
359
|
-
``backend`` is a live graph projection to compute on and ``prefer`` selects
|
|
360
|
-
the engine; the projection is used only when both point at it AND it agrees
|
|
361
|
-
with the store. Errors are returned in the report rather than swallowed: a
|
|
362
|
-
pass that writes nothing and a store with no facts are different events, and
|
|
363
|
-
the previous implementation reported both as ``node_count: 0``.
|
|
364
|
-
"""
|
|
365
|
-
started = time.monotonic()
|
|
366
|
-
notes: list[str] = []
|
|
367
|
-
try:
|
|
368
|
-
with _short_connection(db) as conn:
|
|
369
|
-
nodes = _visible_fact_ids(conn, profile_id)
|
|
370
|
-
edges = [
|
|
371
|
-
(str(source), str(target), float(weight))
|
|
372
|
-
for source, target, _etype, weight, _pid
|
|
373
|
-
in iter_logical_edges(conn, profile_id)
|
|
374
|
-
]
|
|
375
|
-
except Exception as exc: # noqa: BLE001
|
|
376
|
-
return GraphMetricsReport(
|
|
377
|
-
profile_id=profile_id,
|
|
378
|
-
error=f"could not read the graph: {exc}",
|
|
379
|
-
duration_ms=int((time.monotonic() - started) * 1000),
|
|
380
|
-
)
|
|
381
|
-
|
|
382
|
-
if not nodes:
|
|
383
|
-
return GraphMetricsReport(
|
|
384
|
-
profile_id=profile_id,
|
|
385
|
-
engine="none",
|
|
386
|
-
duration_ms=int((time.monotonic() - started) * 1000),
|
|
387
|
-
notes=("no visible facts",),
|
|
388
|
-
)
|
|
389
|
-
|
|
390
|
-
usable, why = _projection_usable(backend, profile_id, len(edges))
|
|
391
|
-
notes.append(why)
|
|
392
|
-
if usable and not _projection_is_current(db, profile_id):
|
|
393
|
-
usable = False
|
|
394
|
-
why = "projection has unapplied changes"
|
|
395
|
-
notes.append(why)
|
|
396
|
-
engine = "cozo" if (usable and prefer == "cozo") else "networkx"
|
|
397
|
-
try:
|
|
398
|
-
# On ``engine``, not on ``usable``. Branching on ``usable`` ran the
|
|
399
|
-
# projection whenever one was available, whatever the caller asked for,
|
|
400
|
-
# and then reported the engine the caller had asked for -- so a store
|
|
401
|
-
# with a projection was ranked by it while every log line said
|
|
402
|
-
# otherwise, and the fallback below could never be reached.
|
|
403
|
-
if engine == "cozo":
|
|
404
|
-
pagerank, communities = _cozo_metrics(backend, profile_id, damping)
|
|
405
|
-
else:
|
|
406
|
-
pagerank, communities = _networkx_metrics(edges, damping)
|
|
407
|
-
except Exception as exc: # noqa: BLE001
|
|
408
|
-
if engine == "cozo":
|
|
409
|
-
notes.append(f"cozo failed, fell back: {exc}")
|
|
410
|
-
engine = "networkx"
|
|
411
|
-
try:
|
|
412
|
-
pagerank, communities = _networkx_metrics(edges, damping)
|
|
413
|
-
except Exception as inner: # noqa: BLE001
|
|
414
|
-
return GraphMetricsReport(
|
|
415
|
-
profile_id=profile_id, engine="networkx",
|
|
416
|
-
facts=len(nodes), edges=len(edges),
|
|
417
|
-
error=f"both engines failed: {exc} / {inner}",
|
|
418
|
-
duration_ms=int((time.monotonic() - started) * 1000),
|
|
419
|
-
notes=tuple(notes),
|
|
420
|
-
)
|
|
421
|
-
else:
|
|
422
|
-
return GraphMetricsReport(
|
|
423
|
-
profile_id=profile_id, engine=engine,
|
|
424
|
-
facts=len(nodes), edges=len(edges),
|
|
425
|
-
error=f"metrics failed: {exc}",
|
|
426
|
-
duration_ms=int((time.monotonic() - started) * 1000),
|
|
427
|
-
notes=tuple(notes),
|
|
428
|
-
)
|
|
429
|
-
|
|
430
|
-
# An engine only sees nodes that appear in an edge. Everything else is a
|
|
431
|
-
# visible fact with no graph position, and it gets the teleport share -- the
|
|
432
|
-
# value PageRank would give a node nothing links to.
|
|
433
|
-
node_set = set(nodes)
|
|
434
|
-
total = len(node_set)
|
|
435
|
-
base = (1.0 - damping) / float(total)
|
|
436
|
-
connected = {fid for fid in pagerank if fid in node_set}
|
|
437
|
-
isolated = node_set - connected
|
|
438
|
-
# Leave room for the isolated mass so the whole table still sums to ~1 and
|
|
439
|
-
# the ranker's absolute thresholds keep meaning what they meant.
|
|
440
|
-
headroom = max(0.0, 1.0 - base * len(isolated))
|
|
441
|
-
connected_mass = sum(pagerank[fid] for fid in connected) or 1.0
|
|
442
|
-
|
|
443
|
-
degree: dict[str, int] = {}
|
|
444
|
-
for source, target, _weight in edges:
|
|
445
|
-
degree[source] = degree.get(source, 0) + 1
|
|
446
|
-
degree[target] = degree.get(target, 0) + 1
|
|
447
|
-
divisor = float(total - 1) if total > 1 else 1.0
|
|
448
|
-
|
|
449
|
-
bridges = _bridge_scores(edges, total)
|
|
450
|
-
if bridges is None:
|
|
451
|
-
notes.append(f"bridge scores skipped above {BRIDGE_NODE_LIMIT} facts")
|
|
452
|
-
|
|
453
|
-
rows: list[tuple[Any, ...]] = []
|
|
454
|
-
for fact_id in nodes:
|
|
455
|
-
if fact_id in connected:
|
|
456
|
-
score = pagerank[fact_id] / connected_mass * headroom
|
|
457
|
-
else:
|
|
458
|
-
score = base
|
|
459
|
-
community = communities.get(fact_id)
|
|
460
|
-
rows.append((
|
|
461
|
-
fact_id,
|
|
462
|
-
profile_id,
|
|
463
|
-
round(float(score), 9),
|
|
464
|
-
int(community) if community is not None else None,
|
|
465
|
-
round(degree.get(fact_id, 0) / divisor, 6),
|
|
466
|
-
round(float((bridges or {}).get(fact_id, 0.0)), 6),
|
|
467
|
-
))
|
|
468
|
-
|
|
469
|
-
try:
|
|
470
|
-
removed = _write(db, profile_id, rows)
|
|
471
|
-
except Exception as exc: # noqa: BLE001
|
|
472
|
-
return GraphMetricsReport(
|
|
473
|
-
profile_id=profile_id, engine=engine, facts=total,
|
|
474
|
-
edges=len(edges), connected=len(connected),
|
|
475
|
-
isolated=len(isolated),
|
|
476
|
-
error=f"metrics computed but not stored: {exc}",
|
|
477
|
-
duration_ms=int((time.monotonic() - started) * 1000),
|
|
478
|
-
notes=tuple(notes),
|
|
479
|
-
)
|
|
480
|
-
|
|
481
|
-
return GraphMetricsReport(
|
|
482
|
-
profile_id=profile_id,
|
|
483
|
-
engine=engine,
|
|
484
|
-
facts=total,
|
|
485
|
-
edges=len(edges),
|
|
486
|
-
connected=len(connected),
|
|
487
|
-
isolated=len(isolated),
|
|
488
|
-
communities=len({c for c in communities.values()}),
|
|
489
|
-
written=len(rows),
|
|
490
|
-
removed=removed,
|
|
491
|
-
bridges_computed=bridges is not None,
|
|
492
|
-
duration_ms=int((time.monotonic() - started) * 1000),
|
|
493
|
-
notes=tuple(notes),
|
|
494
|
-
)
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
def _write(db: Any, profile_id: str, rows: list[tuple[Any, ...]]) -> int:
|
|
498
|
-
"""Replace this profile's rows in one transaction.
|
|
499
|
-
|
|
500
|
-
Deleting first is what makes the table a projection rather than an
|
|
501
|
-
accumulation: a fact that has since been withheld or erased must lose its
|
|
502
|
-
row, or the ranker keeps scoring something recall will never return. The
|
|
503
|
-
delete and the insert share a transaction so no recall ever sees the
|
|
504
|
-
intermediate state where the profile has no metrics at all.
|
|
505
|
-
"""
|
|
506
|
-
removed = 0
|
|
507
|
-
with _short_connection(db) as conn:
|
|
508
|
-
_ensure_bridge_column(conn)
|
|
509
|
-
keep = {row[0] for row in rows}
|
|
510
|
-
existing = {
|
|
511
|
-
str(r[0]) for r in conn.execute(
|
|
512
|
-
"SELECT fact_id FROM fact_importance WHERE profile_id = ?",
|
|
513
|
-
(profile_id,),
|
|
514
|
-
).fetchall()
|
|
515
|
-
}
|
|
516
|
-
stale = existing - keep
|
|
517
|
-
for index in range(0, len(list(stale)), 800):
|
|
518
|
-
chunk = list(stale)[index:index + 800]
|
|
519
|
-
placeholders = ",".join("?" for _ in chunk)
|
|
520
|
-
conn.execute(
|
|
521
|
-
f"DELETE FROM fact_importance WHERE profile_id = ? "
|
|
522
|
-
f"AND fact_id IN ({placeholders})",
|
|
523
|
-
(profile_id, *chunk),
|
|
524
|
-
)
|
|
525
|
-
removed += len(chunk)
|
|
526
|
-
conn.executemany(
|
|
527
|
-
"INSERT INTO fact_importance "
|
|
528
|
-
"(fact_id, profile_id, pagerank_score, community_id, "
|
|
529
|
-
" degree_centrality, bridge_score, computed_at) "
|
|
530
|
-
"VALUES (?, ?, ?, ?, ?, ?, datetime('now')) "
|
|
531
|
-
"ON CONFLICT(fact_id) DO UPDATE SET "
|
|
532
|
-
" profile_id = excluded.profile_id, "
|
|
533
|
-
" pagerank_score = excluded.pagerank_score, "
|
|
534
|
-
" community_id = excluded.community_id, "
|
|
535
|
-
" degree_centrality = excluded.degree_centrality, "
|
|
536
|
-
" bridge_score = excluded.bridge_score, "
|
|
537
|
-
" computed_at = excluded.computed_at",
|
|
538
|
-
rows,
|
|
539
|
-
)
|
|
540
|
-
return removed
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
def _ensure_bridge_column(conn: sqlite3.Connection) -> None:
|
|
544
|
-
"""Idempotent: ``bridge_score`` arrived after the table did.
|
|
545
|
-
|
|
546
|
-
A store created before it exists in the wild, so the insert below cannot
|
|
547
|
-
assume the column. Adding it here rather than refusing keeps an upgrade from
|
|
548
|
-
silently losing its metrics on first run.
|
|
549
|
-
"""
|
|
550
|
-
try:
|
|
551
|
-
columns = {row[1] for row in conn.execute("PRAGMA table_info(fact_importance)")}
|
|
552
|
-
if "bridge_score" not in columns:
|
|
553
|
-
conn.execute(
|
|
554
|
-
"ALTER TABLE fact_importance ADD COLUMN bridge_score REAL DEFAULT 0.0"
|
|
555
|
-
)
|
|
556
|
-
except sqlite3.Error as exc:
|
|
557
|
-
logger.debug("bridge_score column check failed: %s", exc)
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
def metrics_are_stale(db: Any, profile_id: str) -> tuple[bool, str]:
|
|
561
|
-
"""Whether this profile's metrics no longer describe its graph.
|
|
562
|
-
|
|
563
|
-
Deliberately not a clock. "Recomputed 30 minutes ago" says nothing about
|
|
564
|
-
whether the store changed, and the failure this guards against is a memory
|
|
565
|
-
that has no row at all -- which the ranker cannot distinguish from a memory
|
|
566
|
-
with no graph position. So the test is coverage: is any visible fact
|
|
567
|
-
missing, or does the table describe facts that are gone.
|
|
568
|
-
|
|
569
|
-
Cheap enough to run every cycle: two counting queries against an indexed
|
|
570
|
-
column.
|
|
571
|
-
"""
|
|
572
|
-
try:
|
|
573
|
-
with _short_connection(db) as conn:
|
|
574
|
-
from superlocalmemory.storage.database import (
|
|
575
|
-
visible_fact_clause_for_connection,
|
|
576
|
-
)
|
|
577
|
-
|
|
578
|
-
clause = visible_fact_clause_for_connection(conn, prefix="f")
|
|
579
|
-
missing = conn.execute(
|
|
580
|
-
"SELECT COUNT(*) FROM atomic_facts f "
|
|
581
|
-
"LEFT JOIN fact_importance fi ON fi.fact_id = f.fact_id "
|
|
582
|
-
f"WHERE f.profile_id = ?{clause} AND fi.fact_id IS NULL",
|
|
583
|
-
(profile_id,),
|
|
584
|
-
).fetchone()[0]
|
|
585
|
-
if missing:
|
|
586
|
-
return True, f"{missing} visible fact(s) have no metrics"
|
|
587
|
-
surplus = conn.execute(
|
|
588
|
-
"SELECT COUNT(*) FROM fact_importance fi "
|
|
589
|
-
"LEFT JOIN atomic_facts f ON f.fact_id = fi.fact_id "
|
|
590
|
-
f"WHERE fi.profile_id = ? AND (f.fact_id IS NULL OR NOT (1=1{clause}))",
|
|
591
|
-
(profile_id,),
|
|
592
|
-
).fetchone()[0]
|
|
593
|
-
if surplus:
|
|
594
|
-
return True, f"{surplus} metric row(s) describe facts recall cannot return"
|
|
595
|
-
return False, "metrics cover the visible graph"
|
|
596
|
-
except Exception as exc: # noqa: BLE001 -- a failed check must not skip the pass
|
|
597
|
-
return True, f"staleness check failed ({exc}); recomputing"
|