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,194 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
|
|
2
|
-
# Licensed under AGPL-3.0-or-later - see LICENSE file
|
|
3
|
-
# Part of SuperLocalMemory V3 — RBAC / teams (C3)
|
|
4
|
-
|
|
5
|
-
"""RBAC enforcement boundary for HTTP routes.
|
|
6
|
-
|
|
7
|
-
This is the single place that turns "who is calling" + "what are they trying to
|
|
8
|
-
do" into an allow/deny decision, on top of the existing machine-auth layer
|
|
9
|
-
(write_identity). It is deliberately small so every mutation route calls the
|
|
10
|
-
same code path — the research warning was explicit: an RBAC layer that is
|
|
11
|
-
defined but not consistently called is worse than none.
|
|
12
|
-
|
|
13
|
-
Principal model
|
|
14
|
-
---------------
|
|
15
|
-
* **user** — a logged-in dashboard user (valid session token). Always enforced
|
|
16
|
-
against their role on the active profile.
|
|
17
|
-
* **owner** — the machine operator (already proved machine auth via
|
|
18
|
-
write_identity; no user session). In personal mode the owner bypasses RBAC
|
|
19
|
-
(all permissions). When the org turns on *require_login* (company mode) the
|
|
20
|
-
owner bypass is disabled and a user session is mandatory.
|
|
21
|
-
"""
|
|
22
|
-
|
|
23
|
-
from __future__ import annotations
|
|
24
|
-
|
|
25
|
-
from typing import Any
|
|
26
|
-
|
|
27
|
-
from fastapi import HTTPException, Request
|
|
28
|
-
|
|
29
|
-
from superlocalmemory.access.rbac import Permission, Role, permissions_for_role
|
|
30
|
-
import logging
|
|
31
|
-
|
|
32
|
-
logger = logging.getLogger(__name__)
|
|
33
|
-
|
|
34
|
-
_SESSION_HEADER = "X-SLM-User-Session"
|
|
35
|
-
_SESSION_COOKIE = "slm_session"
|
|
36
|
-
|
|
37
|
-
OWNER_PRINCIPAL = {
|
|
38
|
-
"kind": "owner",
|
|
39
|
-
"user_id": "owner",
|
|
40
|
-
"username": "owner",
|
|
41
|
-
"display_name": "Machine Owner",
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
def get_rbac_engine(app_state: Any) -> Any | None:
|
|
46
|
-
return getattr(app_state, "rbac", None)
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
def _session_token(request: Request) -> str:
|
|
50
|
-
tok = request.headers.get(_SESSION_HEADER, "")
|
|
51
|
-
if tok:
|
|
52
|
-
return tok
|
|
53
|
-
try:
|
|
54
|
-
return request.cookies.get(_SESSION_COOKIE, "") or ""
|
|
55
|
-
except Exception:
|
|
56
|
-
return ""
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
def resolve_principal(request: Request) -> dict:
|
|
60
|
-
"""Resolve the caller to a user (valid session) or the machine owner."""
|
|
61
|
-
rbac = get_rbac_engine(request.app.state)
|
|
62
|
-
token = _session_token(request)
|
|
63
|
-
if rbac is not None and token:
|
|
64
|
-
user = rbac.resolve_session(token)
|
|
65
|
-
if user:
|
|
66
|
-
return {"kind": "user", **user}
|
|
67
|
-
return dict(OWNER_PRINCIPAL)
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
def _active_profile() -> str:
|
|
71
|
-
from superlocalmemory.server.routes.helpers import get_active_profile
|
|
72
|
-
|
|
73
|
-
return get_active_profile()
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
def require_permission(
|
|
77
|
-
request: Request,
|
|
78
|
-
permission: Permission,
|
|
79
|
-
*,
|
|
80
|
-
profile: str | None = None,
|
|
81
|
-
) -> dict:
|
|
82
|
-
"""Authorize ``permission`` on ``profile`` (default: active profile).
|
|
83
|
-
|
|
84
|
-
Returns the principal on success. Raises 401 when a login is required but
|
|
85
|
-
absent, or 403 when the user's role does not grant the permission.
|
|
86
|
-
"""
|
|
87
|
-
rbac = get_rbac_engine(request.app.state)
|
|
88
|
-
principal = resolve_principal(request)
|
|
89
|
-
require_login = bool(rbac is not None and rbac.require_login())
|
|
90
|
-
prof = profile or _active_profile()
|
|
91
|
-
|
|
92
|
-
if principal["kind"] == "owner":
|
|
93
|
-
# The machine operator is root — they always retain MANAGE (they have
|
|
94
|
-
# shell access to the box regardless), so company mode can never lock
|
|
95
|
-
# administration out of the dashboard. require_login only gates the
|
|
96
|
-
# owner's DATA operations, forcing per-user login for read/write/etc.
|
|
97
|
-
if require_login and permission != Permission.MANAGE:
|
|
98
|
-
raise HTTPException(
|
|
99
|
-
401,
|
|
100
|
-
detail="Login required: this workspace enforces per-user access.",
|
|
101
|
-
)
|
|
102
|
-
return principal # personal mode — operator is owner
|
|
103
|
-
|
|
104
|
-
# Logged-in user: always enforced against their role.
|
|
105
|
-
if rbac is not None and rbac.has_permission(principal["user_id"], prof, permission):
|
|
106
|
-
return principal
|
|
107
|
-
raise HTTPException(
|
|
108
|
-
403,
|
|
109
|
-
detail=(
|
|
110
|
-
f"Your role does not allow '{permission.value}' on this workspace."
|
|
111
|
-
),
|
|
112
|
-
)
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
def require_manage(request: Request, *, profile: str | None = None) -> dict:
|
|
116
|
-
"""Guard for user/role administration (MANAGE permission)."""
|
|
117
|
-
return require_permission(request, Permission.MANAGE, profile=profile)
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
def resolve_actor_roles(request: Request, *, profile: str | None = None):
|
|
121
|
-
"""Resolve the caller to concrete ActorContext roles (server-derived).
|
|
122
|
-
|
|
123
|
-
The machine operator (owner) is root. A logged-in user is mapped from their
|
|
124
|
-
persisted RBAC role on ``profile``. This must be called only after
|
|
125
|
-
``require_permission`` has already authorized the operation, so the returned
|
|
126
|
-
role always includes the permission the caller was admitted with.
|
|
127
|
-
"""
|
|
128
|
-
from superlocalmemory.core.actor_context import ActorRole
|
|
129
|
-
|
|
130
|
-
principal = resolve_principal(request)
|
|
131
|
-
if principal.get("kind") == "owner":
|
|
132
|
-
return frozenset({ActorRole.OWNER})
|
|
133
|
-
rbac = get_rbac_engine(request.app.state)
|
|
134
|
-
role = None
|
|
135
|
-
if rbac is not None:
|
|
136
|
-
try:
|
|
137
|
-
role = rbac.get_role(principal["user_id"], profile or _active_profile())
|
|
138
|
-
except Exception as exc: # noqa: BLE001
|
|
139
|
-
# A lookup that failed is not a lookup that said yes.
|
|
140
|
-
#
|
|
141
|
-
# This used to return MEMBER, on the reasoning that the caller had
|
|
142
|
-
# already passed a coarser permission check so a transient database
|
|
143
|
-
# error should not deny an authorised write. The effect was that any
|
|
144
|
-
# error in the role lookup -- a write-lock timeout, a checkpoint, a
|
|
145
|
-
# corrupt page -- promoted a viewer to a role that can write, at
|
|
146
|
-
# exactly the moment the store was under stress. A caller able to
|
|
147
|
-
# provoke lock contention could provoke the promotion.
|
|
148
|
-
#
|
|
149
|
-
# "Ask again in a moment" is the honest answer and the one the
|
|
150
|
-
# caller can act on. It is neither a denial nor a grant.
|
|
151
|
-
from fastapi import HTTPException
|
|
152
|
-
|
|
153
|
-
logger.warning(
|
|
154
|
-
"rbac: the role for this caller could not be read (%s); "
|
|
155
|
-
"answering 503 rather than assuming one", exc,
|
|
156
|
-
)
|
|
157
|
-
raise HTTPException(
|
|
158
|
-
status_code=503,
|
|
159
|
-
detail="the workspace's roles are temporarily unreadable; retry",
|
|
160
|
-
) from exc
|
|
161
|
-
mapped = {
|
|
162
|
-
Role.ADMIN: ActorRole.ADMIN,
|
|
163
|
-
Role.MEMBER: ActorRole.MEMBER,
|
|
164
|
-
Role.VIEWER: ActorRole.VIEWER,
|
|
165
|
-
}.get(role)
|
|
166
|
-
return frozenset({mapped}) if mapped is not None else frozenset({ActorRole.ANONYMOUS})
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
def principal_info(request: Request) -> dict:
|
|
170
|
-
"""Rich identity for /whoami: principal + role + effective permissions on
|
|
171
|
-
the active profile. Never raises — used by the dashboard to render UI."""
|
|
172
|
-
rbac = get_rbac_engine(request.app.state)
|
|
173
|
-
principal = resolve_principal(request)
|
|
174
|
-
prof = _active_profile()
|
|
175
|
-
info = {
|
|
176
|
-
"kind": principal["kind"],
|
|
177
|
-
"user_id": principal["user_id"],
|
|
178
|
-
"username": principal["username"],
|
|
179
|
-
"display_name": principal.get("display_name", principal["username"]),
|
|
180
|
-
"profile": prof,
|
|
181
|
-
"rbac_active": bool(rbac is not None and rbac.user_count() > 0),
|
|
182
|
-
"require_login": bool(rbac is not None and rbac.require_login()),
|
|
183
|
-
}
|
|
184
|
-
if principal["kind"] == "owner":
|
|
185
|
-
# Owner has every permission (personal mode) unless login is required.
|
|
186
|
-
info["role"] = "owner"
|
|
187
|
-
info["permissions"] = [p.value for p in Permission]
|
|
188
|
-
return info
|
|
189
|
-
role = rbac.get_role(principal["user_id"], prof) if rbac is not None else None
|
|
190
|
-
info["role"] = role.value if role else None
|
|
191
|
-
info["permissions"] = (
|
|
192
|
-
[p.value for p in permissions_for_role(role)] if role else []
|
|
193
|
-
)
|
|
194
|
-
return info
|
|
@@ -1,343 +0,0 @@
|
|
|
1
|
-
"""Runtime recall-health monitor — keep the full recall path warm,
|
|
2
|
-
detect a "warm-but-broken" embedder at runtime, and self-heal it (v3.6.8).
|
|
3
|
-
|
|
4
|
-
Why this exists
|
|
5
|
-
---------------
|
|
6
|
-
On a long-running daemon the cold full-fusion recall could exceed the MCP
|
|
7
|
-
pool's 30s timeout, and ``session_init`` then silently fell back to FTS5/BM25
|
|
8
|
-
("DEGRADED MODE") — observed 7×/2 days in production logs. Two root causes:
|
|
9
|
-
|
|
10
|
-
1. **Page-cache eviction.** The ~100 MB ``association_edges`` / graph table is
|
|
11
|
-
evicted under memory pressure, so the first recall after idle re-reads it
|
|
12
|
-
from disk (15-24 s+), blowing the pool timeout.
|
|
13
|
-
2. **Silent embedder death.** ``OllamaEmbedder.embed`` returns ``None`` on a
|
|
14
|
-
transient Ollama failure, while the boot-set ``_embedding_warm`` flag still
|
|
15
|
-
reports ``True``. With ``q_emb is None`` the engine skips the semantic,
|
|
16
|
-
hopfield and spreading_activation channels — recall silently degrades to
|
|
17
|
-
keyword-only (``semantic`` score ``0.0`` on every result).
|
|
18
|
-
|
|
19
|
-
The boot warmup (``_warmup_recall``) runs ONCE and never again, so neither
|
|
20
|
-
condition is repaired in-life.
|
|
21
|
-
|
|
22
|
-
The fix — an industry-standard 3-tier monitor, validated against Ollama
|
|
23
|
-
keep-alive, Chroma's active heartbeat, LangChain's circuit breaker and the
|
|
24
|
-
Kubernetes liveness/readiness split:
|
|
25
|
-
|
|
26
|
-
* **Tier 1 — RE-WARM.** Fire a real ``engine.recall`` every ``interval_s`` to
|
|
27
|
-
keep the graph page cache hot and nomic-embed resident.
|
|
28
|
-
* **Tier 2 — READINESS PROBE.** Assert the semantic channel actually fired
|
|
29
|
-
(``max semantic > 0``). Rows returned with ``semantic == 0`` everywhere is the
|
|
30
|
-
warm-but-broken signature → the embedder is returning ``None``.
|
|
31
|
-
* **Tier 3 — CIRCUIT-BREAKER SELF-HEAL.** Reset the embedder's cached
|
|
32
|
-
``_available`` flag (the "available once, cached forever" bug), re-exercise
|
|
33
|
-
``embed()``, track consecutive failures, and log **CRITICAL** so the
|
|
34
|
-
degradation is never silent.
|
|
35
|
-
|
|
36
|
-
All logic is fail-soft: a crash in the monitor never takes down the daemon.
|
|
37
|
-
"""
|
|
38
|
-
from __future__ import annotations
|
|
39
|
-
|
|
40
|
-
import logging
|
|
41
|
-
import threading
|
|
42
|
-
import time
|
|
43
|
-
from contextlib import nullcontext
|
|
44
|
-
from dataclasses import dataclass
|
|
45
|
-
|
|
46
|
-
logger = logging.getLogger(__name__)
|
|
47
|
-
|
|
48
|
-
# A stable probe query. Content-agnostic: we only assert that *some* result
|
|
49
|
-
# carries a non-zero semantic score, which proves the embedder + semantic
|
|
50
|
-
# channel are alive end-to-end.
|
|
51
|
-
DEFAULT_PROBE = "memory recall health probe"
|
|
52
|
-
# A distinct string for the heal embed() call so it is obvious in thread dumps
|
|
53
|
-
# / Ollama logs and never collides with a real cached query embedding.
|
|
54
|
-
HEAL_PROBE = "__recall_health_rewarm__"
|
|
55
|
-
|
|
56
|
-
# Default cadence. 5 min keeps nomic-embed resident (Ollama default unload is
|
|
57
|
-
# 5 min) and the page cache warm without meaningful load.
|
|
58
|
-
DEFAULT_INTERVAL_S = 300
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
@dataclass
|
|
62
|
-
class RecallHealth:
|
|
63
|
-
"""Mutable health state for the recall path."""
|
|
64
|
-
|
|
65
|
-
healthy: bool = True
|
|
66
|
-
consecutive_failures: int = 0
|
|
67
|
-
total_heals: int = 0
|
|
68
|
-
checks: int = 0
|
|
69
|
-
last_semantic_score: float = 0.0
|
|
70
|
-
last_error: str = ""
|
|
71
|
-
#: When the last tick finished, as a unix timestamp. A tick that finds
|
|
72
|
-
#: nothing wrong logs nothing, which is correct -- a monitor that narrates
|
|
73
|
-
#: every success is a monitor whose real warnings get skimmed past. But it
|
|
74
|
-
#: left no way to tell a monitor that is ticking quietly from a thread that
|
|
75
|
-
#: died or never started, and that ambiguity cost someone an hour of looking
|
|
76
|
-
#: for log lines that were never going to appear. So the fact of the tick is
|
|
77
|
-
#: recorded here and surfaced on /health, where it can be checked instead of
|
|
78
|
-
#: inferred.
|
|
79
|
-
last_tick_at: float = 0.0
|
|
80
|
-
#: Whether the embedder could produce a vector at the last tick.
|
|
81
|
-
embedder_alive: bool = True
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
def _max_semantic(results) -> float:
|
|
85
|
-
"""Largest semantic channel score across results (0.0 if none)."""
|
|
86
|
-
best = 0.0
|
|
87
|
-
for r in results:
|
|
88
|
-
cs = getattr(r, "channel_scores", None) or {}
|
|
89
|
-
try:
|
|
90
|
-
best = max(best, float(cs.get("semantic", 0.0) or 0.0))
|
|
91
|
-
except (TypeError, ValueError):
|
|
92
|
-
continue
|
|
93
|
-
return best
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
def _get_embedder(engine):
|
|
97
|
-
"""Locate the engine's embedder (full mode: engine._embedder; some paths
|
|
98
|
-
hang it off the retrieval engine)."""
|
|
99
|
-
emb = getattr(engine, "_embedder", None)
|
|
100
|
-
if emb is None:
|
|
101
|
-
re_eng = getattr(engine, "_retrieval_engine", None)
|
|
102
|
-
emb = getattr(re_eng, "_embedder", None) if re_eng is not None else None
|
|
103
|
-
return emb
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
def _embedder_is_dead(engine) -> bool:
|
|
107
|
-
"""Can the embedder produce a vector right now?
|
|
108
|
-
|
|
109
|
-
Asked directly, because it cannot be inferred from a recall. The monitor
|
|
110
|
-
used to decide the embedder was fine whenever the probe recall came back
|
|
111
|
-
with no results at all -- and a dead embedder is one of the reasons a recall
|
|
112
|
-
comes back with no results, so the one symptom that should have triggered a
|
|
113
|
-
heal was read as proof that none was needed.
|
|
114
|
-
|
|
115
|
-
That is not hypothetical. An idle-timeout kill leaves no worker; the next
|
|
116
|
-
probe finds nothing by meaning, finds nothing by keyword either because the
|
|
117
|
-
probe phrase appears in nobody's memories, and returns zero results. The
|
|
118
|
-
monitor then recorded "healthy", logged nothing, and never respawned the
|
|
119
|
-
worker -- so ``readiness.embedding`` stayed false and the daemon sat in
|
|
120
|
-
``warming`` until someone restarted it by hand, with not one line in the log
|
|
121
|
-
to say why.
|
|
122
|
-
|
|
123
|
-
Fails safe in the opposite direction from before: an embedder this cannot
|
|
124
|
-
reach is reported dead, so the worst case is one unnecessary re-warm rather
|
|
125
|
-
than a silent outage.
|
|
126
|
-
"""
|
|
127
|
-
emb = _get_embedder(engine)
|
|
128
|
-
if emb is None:
|
|
129
|
-
return False # BM25-only by configuration; nothing to heal.
|
|
130
|
-
warm = getattr(emb, "is_warm", None)
|
|
131
|
-
if warm is not None and not warm:
|
|
132
|
-
return True
|
|
133
|
-
if getattr(emb, "_available", True) is False:
|
|
134
|
-
return True
|
|
135
|
-
return False
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
def _heal_embedder(engine, *, log) -> bool:
|
|
139
|
-
"""Tier 3: reset the cached availability flag and re-exercise the embedder.
|
|
140
|
-
|
|
141
|
-
``OllamaEmbedder.is_available`` caches its first result forever, so once
|
|
142
|
-
Ollama blips the flag can stay stale. Clearing ``_available`` forces a
|
|
143
|
-
re-probe; ``embed()`` itself always re-attempts the HTTP call, so a single
|
|
144
|
-
successful embed proves recovery. Returns True iff the embedder produced a
|
|
145
|
-
vector.
|
|
146
|
-
"""
|
|
147
|
-
emb = _get_embedder(engine)
|
|
148
|
-
if emb is None:
|
|
149
|
-
log.critical("recall-health: no embedder on engine — cannot self-heal")
|
|
150
|
-
return False
|
|
151
|
-
# Reset the "available once, cached forever" flag if present.
|
|
152
|
-
if hasattr(emb, "_available"):
|
|
153
|
-
try:
|
|
154
|
-
emb._available = None
|
|
155
|
-
except Exception: # pragma: no cover - defensive
|
|
156
|
-
pass
|
|
157
|
-
try:
|
|
158
|
-
vec = emb.embed(HEAL_PROBE)
|
|
159
|
-
except Exception as exc:
|
|
160
|
-
log.warning("recall-health: heal embed() raised: %s", exc)
|
|
161
|
-
return False
|
|
162
|
-
return vec is not None and bool(vec)
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
def run_health_tick(engine, state: RecallHealth, *, probe: str = DEFAULT_PROBE,
|
|
166
|
-
log=logger, runtime=None) -> RecallHealth:
|
|
167
|
-
"""One monitor tick: re-warm (Tier 1), probe (Tier 2), self-heal (Tier 3).
|
|
168
|
-
|
|
169
|
-
Mutates and returns ``state``. Never raises — a timed-out / failing recall
|
|
170
|
-
marks the path unhealthy instead of propagating.
|
|
171
|
-
|
|
172
|
-
Uses ``operation_nowait()`` when a runtime is supplied so that a pending
|
|
173
|
-
profile switch is not blocked by the health-probe recall. If a transition
|
|
174
|
-
is in progress the tick is skipped entirely — the next scheduled tick will
|
|
175
|
-
re-warm once the switch has committed.
|
|
176
|
-
"""
|
|
177
|
-
state.checks += 1
|
|
178
|
-
|
|
179
|
-
# Tier 1: re-warm. A real full-fusion recall keeps the graph page cache hot
|
|
180
|
-
# and the embedder resident.
|
|
181
|
-
# Cooperative preemption: use operation_nowait() so a pending profile switch
|
|
182
|
-
# is not held hostage by a slow full-fusion recall (2–10s with fast=False).
|
|
183
|
-
try:
|
|
184
|
-
if runtime is not None:
|
|
185
|
-
lease = runtime.operation_nowait()
|
|
186
|
-
else:
|
|
187
|
-
lease = nullcontext()
|
|
188
|
-
with lease as _snap:
|
|
189
|
-
if runtime is not None and _snap is None:
|
|
190
|
-
# A profile transition is in progress — skip this tick so we
|
|
191
|
-
# do not hold the drain window. Health state is unchanged;
|
|
192
|
-
# the next tick fires after the switch commits.
|
|
193
|
-
log.debug(
|
|
194
|
-
"recall-health: tick skipped — profile transition in progress"
|
|
195
|
-
)
|
|
196
|
-
return state
|
|
197
|
-
# fast=True: a health probe must release its operation lease well
|
|
198
|
-
# within the 5s profile-switch drain window (fast=False is 2-10s and
|
|
199
|
-
# would make every profile switch time out while a tick is in flight).
|
|
200
|
-
from superlocalmemory.core.recall_gate import background_work
|
|
201
|
-
with background_work():
|
|
202
|
-
resp = engine.recall(probe, limit=3, fast=True)
|
|
203
|
-
except Exception as exc:
|
|
204
|
-
state.healthy = False
|
|
205
|
-
state.consecutive_failures += 1
|
|
206
|
-
state.last_error = f"recall raised: {exc}"
|
|
207
|
-
log.critical(
|
|
208
|
-
"recall-health: re-warm recall FAILED (%s) — recall path unhealthy",
|
|
209
|
-
exc,
|
|
210
|
-
)
|
|
211
|
-
return state
|
|
212
|
-
|
|
213
|
-
results = list(getattr(resp, "results", []) or [])
|
|
214
|
-
sem = _max_semantic(results)
|
|
215
|
-
state.last_semantic_score = sem
|
|
216
|
-
state.last_tick_at = time.time()
|
|
217
|
-
|
|
218
|
-
# Tier 2: readiness. Two independent signatures, and the second one is why
|
|
219
|
-
# this monitor exists.
|
|
220
|
-
#
|
|
221
|
-
# * rows present but semantic never fired -> warm-but-broken
|
|
222
|
-
# * the embedder cannot produce a vector -> dead, whatever the recall said
|
|
223
|
-
#
|
|
224
|
-
# The second used to be missing, and its absence was load-bearing: zero
|
|
225
|
-
# results was treated as "not this signature", so the case where the embedder
|
|
226
|
-
# is dead AND the probe matches nothing by keyword -- which is the normal
|
|
227
|
-
# shape of an idle-timeout kill -- came out as healthy, silently.
|
|
228
|
-
dead = _embedder_is_dead(engine)
|
|
229
|
-
state.embedder_alive = not dead
|
|
230
|
-
broken = dead or (bool(results) and sem <= 0.0)
|
|
231
|
-
if dead:
|
|
232
|
-
log.critical(
|
|
233
|
-
"recall-health: embedder cannot produce a vector (%d probe results) "
|
|
234
|
-
"— attempting self-heal",
|
|
235
|
-
len(results),
|
|
236
|
-
)
|
|
237
|
-
if not broken:
|
|
238
|
-
if not state.healthy:
|
|
239
|
-
log.warning(
|
|
240
|
-
"recall-health: RECOVERED (semantic=%.3f, %d results)",
|
|
241
|
-
sem, len(results),
|
|
242
|
-
)
|
|
243
|
-
state.healthy = True
|
|
244
|
-
state.consecutive_failures = 0
|
|
245
|
-
state.last_error = ""
|
|
246
|
-
return state
|
|
247
|
-
|
|
248
|
-
# Tier 3: self-heal. The dead-embedder case already said so above; saying
|
|
249
|
-
# "semantic channel DEAD (max semantic=0.0)" as well would be a second,
|
|
250
|
-
# differently-worded CRITICAL about the same tick, and one of the two would
|
|
251
|
-
# be describing a symptom the reader does not have.
|
|
252
|
-
if not dead:
|
|
253
|
-
log.critical(
|
|
254
|
-
"recall-health: semantic channel DEAD (%d results, max semantic=0.0) "
|
|
255
|
-
"— embedder returning None; attempting self-heal",
|
|
256
|
-
len(results),
|
|
257
|
-
)
|
|
258
|
-
if _heal_embedder(engine, log=log):
|
|
259
|
-
state.total_heals += 1
|
|
260
|
-
state.healthy = True
|
|
261
|
-
state.consecutive_failures = 0
|
|
262
|
-
state.last_error = ""
|
|
263
|
-
log.warning("recall-health: embedder self-heal SUCCEEDED (re-warmed)")
|
|
264
|
-
else:
|
|
265
|
-
state.healthy = False
|
|
266
|
-
state.consecutive_failures += 1
|
|
267
|
-
state.last_error = "semantic channel dead; embedder heal failed"
|
|
268
|
-
log.critical(
|
|
269
|
-
"recall-health: self-heal FAILED — recall DEGRADED to keyword-only "
|
|
270
|
-
"(consecutive_failures=%d)", state.consecutive_failures,
|
|
271
|
-
)
|
|
272
|
-
return state
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
def health_monitor_loop(engine, *, interval_s: int, stop_event: threading.Event,
|
|
276
|
-
state: RecallHealth, probe: str = DEFAULT_PROBE,
|
|
277
|
-
log=logger, runtime=None) -> None:
|
|
278
|
-
"""Background loop. Sleeps ``interval_s`` between ticks; exits promptly when
|
|
279
|
-
``stop_event`` is set. An initial short delay avoids racing boot warmup."""
|
|
280
|
-
# Initial delay (bounded) so we don't pile onto the boot warmup threads.
|
|
281
|
-
if stop_event.wait(min(interval_s, 60)):
|
|
282
|
-
return
|
|
283
|
-
while not stop_event.is_set():
|
|
284
|
-
try:
|
|
285
|
-
run_health_tick(
|
|
286
|
-
engine, state, probe=probe, log=log, runtime=runtime,
|
|
287
|
-
)
|
|
288
|
-
except Exception as exc: # pragma: no cover - belt & suspenders
|
|
289
|
-
log.warning("recall-health: tick crashed (non-fatal): %s", exc)
|
|
290
|
-
if stop_event.wait(interval_s):
|
|
291
|
-
break
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
# Module-level state so /health can surface the latest verdict without holding
|
|
295
|
-
# a reference to the thread.
|
|
296
|
-
_GLOBAL_STATE = RecallHealth()
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
def start_recall_health_monitor(engine, *, interval_s: int = DEFAULT_INTERVAL_S,
|
|
300
|
-
probe: str = DEFAULT_PROBE, log=None,
|
|
301
|
-
runtime=None):
|
|
302
|
-
"""Start the monitor as a daemon thread. Returns ``(thread, stop_event,
|
|
303
|
-
state)``. The state is the shared module-level state read by
|
|
304
|
-
:func:`get_recall_health`."""
|
|
305
|
-
log = log or logger
|
|
306
|
-
state = _GLOBAL_STATE
|
|
307
|
-
stop = threading.Event()
|
|
308
|
-
t = threading.Thread(
|
|
309
|
-
target=health_monitor_loop,
|
|
310
|
-
kwargs=dict(
|
|
311
|
-
engine=engine, interval_s=interval_s, stop_event=stop,
|
|
312
|
-
state=state, probe=probe, log=log, runtime=runtime,
|
|
313
|
-
),
|
|
314
|
-
daemon=True,
|
|
315
|
-
name="recall-health",
|
|
316
|
-
)
|
|
317
|
-
t.start()
|
|
318
|
-
return t, stop, state
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
def get_recall_health() -> dict:
|
|
322
|
-
"""Snapshot for /health surfacing (visibility — never silent degradation)."""
|
|
323
|
-
s = _GLOBAL_STATE
|
|
324
|
-
now = time.time()
|
|
325
|
-
return {
|
|
326
|
-
"recall_healthy": s.healthy,
|
|
327
|
-
"consecutive_failures": s.consecutive_failures,
|
|
328
|
-
"total_heals": s.total_heals,
|
|
329
|
-
"checks": s.checks,
|
|
330
|
-
"last_semantic_score": round(s.last_semantic_score, 4),
|
|
331
|
-
"last_error": s.last_error,
|
|
332
|
-
# Proof of life. A tick that finds nothing wrong logs nothing, so there
|
|
333
|
-
# was no way to tell this monitor apart from a thread that never started
|
|
334
|
-
# -- someone spent an hour reading logs for lines that were never going
|
|
335
|
-
# to be written. These two answer that without needing the log at all:
|
|
336
|
-
# if seconds_since_last_tick keeps climbing past the interval, the thread
|
|
337
|
-
# is gone.
|
|
338
|
-
"last_tick_at": round(s.last_tick_at, 3) if s.last_tick_at else None,
|
|
339
|
-
"seconds_since_last_tick": (
|
|
340
|
-
round(now - s.last_tick_at, 1) if s.last_tick_at else None
|
|
341
|
-
),
|
|
342
|
-
"embedder_alive": s.embedder_alive,
|
|
343
|
-
}
|