superlocalmemory 4.1.13 → 4.1.15
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 +103 -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,654 +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.4.22 — LLD-03 §3 + §5.3
|
|
4
|
-
|
|
5
|
-
"""Contextual Thompson-sampling bandit over discrete channel-weight arms.
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
Schema: ``bandit_arms`` + ``bandit_plays`` live in ``learning.db``, created by
|
|
9
|
-
LLD-07 M005. This module NEVER defines DDL — it only READs / WRITEs.
|
|
10
|
-
|
|
11
|
-
Hard rules:
|
|
12
|
-
- B1: ``secrets.SystemRandom`` used for Beta sampling (NOT ``random``).
|
|
13
|
-
- B2: α, β clamped at ``SLM_BANDIT_ALPHA_CAP`` (default 1000).
|
|
14
|
-
- B4: stratum cardinality == 48 (4 query_types × 3 entity bins × 4 buckets).
|
|
15
|
-
- B5: cache invalidated on every successful ``update``.
|
|
16
|
-
- B6: raw query text NEVER written to bandit tables.
|
|
17
|
-
- B7: ``choose`` p99 ≤ 10 ms.
|
|
18
|
-
- B8: ``retention_sweep`` only deletes settled rows older than cutoff.
|
|
19
|
-
|
|
20
|
-
All SQL is parameterised — grep guard in CI ensures no f-string SQL here.
|
|
21
|
-
"""
|
|
22
|
-
|
|
23
|
-
from __future__ import annotations
|
|
24
|
-
|
|
25
|
-
import json
|
|
26
|
-
import logging
|
|
27
|
-
import os
|
|
28
|
-
import secrets
|
|
29
|
-
import sqlite3
|
|
30
|
-
import threading
|
|
31
|
-
from dataclasses import dataclass, field
|
|
32
|
-
from datetime import datetime, timedelta, timezone
|
|
33
|
-
from pathlib import Path
|
|
34
|
-
from collections.abc import Sequence
|
|
35
|
-
from typing import Any
|
|
36
|
-
|
|
37
|
-
from superlocalmemory.learning.arm_catalog import ARM_CATALOG
|
|
38
|
-
from superlocalmemory.learning.bandit_cache import (
|
|
39
|
-
_BanditCache,
|
|
40
|
-
get_shared_cache,
|
|
41
|
-
)
|
|
42
|
-
|
|
43
|
-
logger = logging.getLogger(__name__)
|
|
44
|
-
|
|
45
|
-
#: How many shown fact_ids a play records. The settler reads the top 3; the
|
|
46
|
-
#: extra two are headroom for a reranker that reorders after the play is
|
|
47
|
-
#: written, and a bound so this cannot become an unread blob on a hot path.
|
|
48
|
-
_SHOWN_FACT_LIMIT = 5
|
|
49
|
-
|
|
50
|
-
_FALLBACK_ARM_ID = "fallback_default"
|
|
51
|
-
|
|
52
|
-
_DEFAULT_ALPHA_CAP = float(os.environ.get("SLM_BANDIT_ALPHA_CAP", "1000.0"))
|
|
53
|
-
|
|
54
|
-
# Query-type bins (must match features.py one-hot exactly).
|
|
55
|
-
_QUERY_TYPES: tuple[str, ...] = (
|
|
56
|
-
"single_hop",
|
|
57
|
-
"multi_hop",
|
|
58
|
-
"temporal",
|
|
59
|
-
"open_domain",
|
|
60
|
-
)
|
|
61
|
-
_ENTITY_BINS: tuple[str, ...] = ("0", "1-2", "3+")
|
|
62
|
-
_TIME_BUCKETS: tuple[str, ...] = ("morning", "afternoon", "evening", "night")
|
|
63
|
-
|
|
64
|
-
_UNKNOWN_QTYPE = "open_domain" # safe default if caller hands us a new label
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
# ---------------------------------------------------------------------------
|
|
68
|
-
# Data types
|
|
69
|
-
# ---------------------------------------------------------------------------
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
@dataclass(frozen=True, slots=True)
|
|
73
|
-
class BanditChoice:
|
|
74
|
-
"""Result of one ``choose`` call. Immutable (D8 channel-weight bundle)."""
|
|
75
|
-
|
|
76
|
-
stratum: str
|
|
77
|
-
arm_id: str
|
|
78
|
-
weights: dict[str, float] = field(default_factory=dict)
|
|
79
|
-
play_id: int | None = None
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
# ---------------------------------------------------------------------------
|
|
83
|
-
# Stratum computation
|
|
84
|
-
# ---------------------------------------------------------------------------
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
def _bin_entities(count: int) -> str:
|
|
88
|
-
if count <= 0:
|
|
89
|
-
return "0"
|
|
90
|
-
if count <= 2:
|
|
91
|
-
return "1-2"
|
|
92
|
-
return "3+"
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
def _time_bucket_from_hour(hour: int) -> str:
|
|
96
|
-
# wall-clock local: 05:00-11:59 morning, 12:00-16:59 afternoon,
|
|
97
|
-
# 17:00-20:59 evening, 21:00-04:59 night.
|
|
98
|
-
if 5 <= hour <= 11:
|
|
99
|
-
return "morning"
|
|
100
|
-
if 12 <= hour <= 16:
|
|
101
|
-
return "afternoon"
|
|
102
|
-
if 17 <= hour <= 20:
|
|
103
|
-
return "evening"
|
|
104
|
-
return "night"
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
def current_time_bucket(now: datetime | None = None) -> str:
|
|
108
|
-
"""Return the wall-clock time bucket for ``now`` (local timezone)."""
|
|
109
|
-
dt = now if now is not None else datetime.now().astimezone()
|
|
110
|
-
return _time_bucket_from_hour(dt.hour)
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
def compute_stratum(context: dict[str, Any]) -> str:
|
|
114
|
-
"""Compute the 3-tuple stratum from a context dict.
|
|
115
|
-
|
|
116
|
-
Context keys consumed:
|
|
117
|
-
- ``query_type`` — one of ``_QUERY_TYPES``; unknown → ``open_domain``.
|
|
118
|
-
- ``entity_count_bin`` — if present, used verbatim; else derived from
|
|
119
|
-
``entity_count`` (int).
|
|
120
|
-
- ``time_bucket`` — if present, used verbatim; else derived from clock.
|
|
121
|
-
|
|
122
|
-
B4: enumerating all Cartesian products yields exactly 48 strata.
|
|
123
|
-
"""
|
|
124
|
-
qtype = context.get("query_type")
|
|
125
|
-
if qtype not in _QUERY_TYPES:
|
|
126
|
-
qtype = _UNKNOWN_QTYPE
|
|
127
|
-
|
|
128
|
-
ebin = context.get("entity_count_bin")
|
|
129
|
-
if ebin not in _ENTITY_BINS:
|
|
130
|
-
try:
|
|
131
|
-
ecount = int(context.get("entity_count", 0))
|
|
132
|
-
except (TypeError, ValueError):
|
|
133
|
-
ecount = 0
|
|
134
|
-
ebin = _bin_entities(ecount)
|
|
135
|
-
|
|
136
|
-
tbucket = context.get("time_bucket")
|
|
137
|
-
if tbucket not in _TIME_BUCKETS:
|
|
138
|
-
tbucket = current_time_bucket()
|
|
139
|
-
|
|
140
|
-
return f"{qtype}|{ebin}|{tbucket}"
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
# ---------------------------------------------------------------------------
|
|
144
|
-
# Threadlocal sqlite connection (mirrors LLD-02 §4.2 recipe)
|
|
145
|
-
# ---------------------------------------------------------------------------
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
class _ConnHolder(threading.local):
|
|
149
|
-
conn: sqlite3.Connection | None = None
|
|
150
|
-
path: str | None = None
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
_holder = _ConnHolder()
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
def _conn_for(db_path: Path) -> sqlite3.Connection:
|
|
157
|
-
"""Return a WAL-configured threadlocal connection to ``db_path``.
|
|
158
|
-
|
|
159
|
-
Reused across calls on the same thread; reopened on path change.
|
|
160
|
-
"""
|
|
161
|
-
path_str = str(db_path)
|
|
162
|
-
existing = _holder.conn
|
|
163
|
-
if existing is not None and _holder.path == path_str:
|
|
164
|
-
return existing
|
|
165
|
-
if existing is not None:
|
|
166
|
-
try:
|
|
167
|
-
existing.close()
|
|
168
|
-
except sqlite3.Error: # pragma: no cover
|
|
169
|
-
pass
|
|
170
|
-
conn = sqlite3.connect(path_str, timeout=10.0, isolation_level=None)
|
|
171
|
-
try:
|
|
172
|
-
conn.execute("PRAGMA journal_mode=WAL")
|
|
173
|
-
conn.execute("PRAGMA synchronous=NORMAL")
|
|
174
|
-
conn.execute("PRAGMA busy_timeout=5000")
|
|
175
|
-
except sqlite3.Error: # pragma: no cover — best-effort
|
|
176
|
-
pass
|
|
177
|
-
conn.row_factory = sqlite3.Row
|
|
178
|
-
_holder.conn = conn
|
|
179
|
-
_holder.path = path_str
|
|
180
|
-
return conn
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
def close_threadlocal_conn() -> None:
|
|
184
|
-
"""Close the threadlocal bandit connection on the calling thread.
|
|
185
|
-
|
|
186
|
-
v3.4.33: background callers (asyncio.to_thread pool threads) MUST call
|
|
187
|
-
this after finishing bandit work. Without it, each pool thread keeps a
|
|
188
|
-
leaked connection to learning.db for the process lifetime — observed as
|
|
189
|
-
12+ open file descriptors and ~100 MB wasted page-cache RAM.
|
|
190
|
-
"""
|
|
191
|
-
if _holder.conn is not None:
|
|
192
|
-
try:
|
|
193
|
-
_holder.conn.close()
|
|
194
|
-
except sqlite3.Error: # pragma: no cover
|
|
195
|
-
pass
|
|
196
|
-
_holder.conn = None
|
|
197
|
-
_holder.path = None
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
def _now_iso() -> str:
|
|
201
|
-
return datetime.now(timezone.utc).isoformat(timespec="seconds")
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
# ---------------------------------------------------------------------------
|
|
205
|
-
# ContextualBandit
|
|
206
|
-
# ---------------------------------------------------------------------------
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
class ContextualBandit:
|
|
210
|
-
"""Thompson-sampling bandit over the 40-arm catalog.
|
|
211
|
-
|
|
212
|
-
One instance per ``(profile_id, db_path)`` is fine — stateless apart from
|
|
213
|
-
the shared posterior cache. ``choose`` is hot-path; ``update`` runs on
|
|
214
|
-
the reward settler worker (async).
|
|
215
|
-
"""
|
|
216
|
-
|
|
217
|
-
def __init__(
|
|
218
|
-
self,
|
|
219
|
-
db_path: Path | str,
|
|
220
|
-
profile_id: str,
|
|
221
|
-
*,
|
|
222
|
-
catalog: dict[str, dict[str, float]] | None = None,
|
|
223
|
-
cache: _BanditCache | None = None,
|
|
224
|
-
alpha_cap: float = _DEFAULT_ALPHA_CAP,
|
|
225
|
-
) -> None:
|
|
226
|
-
self._db_path = Path(db_path)
|
|
227
|
-
self._profile = str(profile_id)
|
|
228
|
-
self._catalog = catalog or ARM_CATALOG
|
|
229
|
-
self._cache = cache or get_shared_cache()
|
|
230
|
-
self._alpha_cap = float(alpha_cap)
|
|
231
|
-
# Fresh SystemRandom per instance; cheap, seeded from os.urandom.
|
|
232
|
-
self._rng = secrets.SystemRandom()
|
|
233
|
-
|
|
234
|
-
# ------------------------------------------------------------------
|
|
235
|
-
# choose
|
|
236
|
-
# ------------------------------------------------------------------
|
|
237
|
-
|
|
238
|
-
def choose(
|
|
239
|
-
self,
|
|
240
|
-
context: dict[str, Any],
|
|
241
|
-
query_id: str,
|
|
242
|
-
) -> BanditChoice:
|
|
243
|
-
"""Sample one arm under the context stratum; record play row.
|
|
244
|
-
|
|
245
|
-
Never raises. On DB error, returns a fallback_default choice with
|
|
246
|
-
``play_id=None`` and logs at WARN level (no PII).
|
|
247
|
-
"""
|
|
248
|
-
stratum = compute_stratum(context)
|
|
249
|
-
try:
|
|
250
|
-
posteriors = self._cache.get(
|
|
251
|
-
self._profile, stratum, self._load_stratum_posteriors,
|
|
252
|
-
)
|
|
253
|
-
except sqlite3.Error as exc:
|
|
254
|
-
logger.warning(
|
|
255
|
-
"bandit.choose: posterior load failed stratum=%s: %s",
|
|
256
|
-
stratum, exc,
|
|
257
|
-
)
|
|
258
|
-
posteriors = {}
|
|
259
|
-
|
|
260
|
-
arm_id = self._sample_best(posteriors)
|
|
261
|
-
play_id = self._insert_play(query_id, stratum, arm_id)
|
|
262
|
-
return BanditChoice(
|
|
263
|
-
stratum=stratum,
|
|
264
|
-
arm_id=arm_id,
|
|
265
|
-
weights=dict(self._catalog[arm_id]),
|
|
266
|
-
play_id=play_id,
|
|
267
|
-
)
|
|
268
|
-
|
|
269
|
-
def choose_readonly(self, context: dict[str, Any]) -> BanditChoice:
|
|
270
|
-
"""Sample an arm from a read-only snapshot without recording a play.
|
|
271
|
-
|
|
272
|
-
Recall uses this method so the established bandit weighting and
|
|
273
|
-
ensemble quality path remain available without turning a query into a
|
|
274
|
-
``bandit_plays`` write. It deliberately bypasses the writer-oriented
|
|
275
|
-
thread-local connection factory: that factory configures WAL mode and
|
|
276
|
-
is not a physical read-only guarantee.
|
|
277
|
-
"""
|
|
278
|
-
stratum = compute_stratum(context)
|
|
279
|
-
try:
|
|
280
|
-
posteriors = self._load_stratum_posteriors_readonly(stratum)
|
|
281
|
-
except sqlite3.Error as exc:
|
|
282
|
-
logger.warning(
|
|
283
|
-
"bandit.choose_readonly: posterior load failed stratum=%s: %s",
|
|
284
|
-
stratum,
|
|
285
|
-
exc,
|
|
286
|
-
)
|
|
287
|
-
posteriors = {}
|
|
288
|
-
arm_id = self._sample_best(posteriors)
|
|
289
|
-
return BanditChoice(
|
|
290
|
-
stratum=stratum,
|
|
291
|
-
arm_id=arm_id,
|
|
292
|
-
weights=dict(self._catalog[arm_id]),
|
|
293
|
-
play_id=None,
|
|
294
|
-
)
|
|
295
|
-
|
|
296
|
-
def _sample_best(
|
|
297
|
-
self,
|
|
298
|
-
posteriors: dict[str, tuple[float, float]],
|
|
299
|
-
) -> str:
|
|
300
|
-
"""Draw one Beta sample per arm, return argmax."""
|
|
301
|
-
rng = self._rng # B1: secrets.SystemRandom
|
|
302
|
-
best_arm = _FALLBACK_ARM_ID
|
|
303
|
-
best_sample = float("-inf")
|
|
304
|
-
for arm_id in self._catalog:
|
|
305
|
-
a, b = posteriors.get(arm_id, (1.0, 1.0))
|
|
306
|
-
# Defensive: reject non-positive (shouldn't happen; we clamp on
|
|
307
|
-
# write, but guard against external DB tampering).
|
|
308
|
-
if a <= 0 or b <= 0: # pragma: no cover — defensive
|
|
309
|
-
a = max(a, 1.0)
|
|
310
|
-
b = max(b, 1.0)
|
|
311
|
-
try:
|
|
312
|
-
sample = rng.betavariate(a, b)
|
|
313
|
-
except ValueError: # pragma: no cover — defensive
|
|
314
|
-
continue
|
|
315
|
-
if sample > best_sample:
|
|
316
|
-
best_sample = sample
|
|
317
|
-
best_arm = arm_id
|
|
318
|
-
return best_arm
|
|
319
|
-
|
|
320
|
-
# ------------------------------------------------------------------
|
|
321
|
-
# update
|
|
322
|
-
# ------------------------------------------------------------------
|
|
323
|
-
|
|
324
|
-
def update(
|
|
325
|
-
self,
|
|
326
|
-
play_id: int,
|
|
327
|
-
reward: float,
|
|
328
|
-
kind: str = "proxy_position",
|
|
329
|
-
weight: float = 1.0,
|
|
330
|
-
) -> bool:
|
|
331
|
-
"""Apply the reward to the (profile, stratum, arm) posterior.
|
|
332
|
-
|
|
333
|
-
``weight`` scales how much this one observation counts, and exists for
|
|
334
|
-
inverse-propensity correction: the policy chose what was shown, so an
|
|
335
|
-
arm it almost always shows produces weak evidence whatever happens to
|
|
336
|
-
it, while one it rarely shows produces strong evidence. Weighting by
|
|
337
|
-
the inverse of that probability is what keeps the posterior from
|
|
338
|
-
recording popularity the policy manufactured. See ``propensity.py``.
|
|
339
|
-
|
|
340
|
-
A weight of 1.0 is the uncorrected update and the default, so a caller
|
|
341
|
-
with no competitor posteriors to estimate against changes nothing.
|
|
342
|
-
|
|
343
|
-
Returns True on success. Never raises — DB failures logged at WARN.
|
|
344
|
-
Cache invalidated on success (B5).
|
|
345
|
-
"""
|
|
346
|
-
try:
|
|
347
|
-
reward_f = float(reward)
|
|
348
|
-
except (TypeError, ValueError):
|
|
349
|
-
logger.warning("bandit.update: non-numeric reward, ignoring")
|
|
350
|
-
return False
|
|
351
|
-
# Clamp reward ∈ [0, 1].
|
|
352
|
-
if reward_f < 0.0:
|
|
353
|
-
reward_f = 0.0
|
|
354
|
-
elif reward_f > 1.0:
|
|
355
|
-
reward_f = 1.0
|
|
356
|
-
|
|
357
|
-
try:
|
|
358
|
-
weight_f = float(weight)
|
|
359
|
-
except (TypeError, ValueError):
|
|
360
|
-
weight_f = 1.0
|
|
361
|
-
# A non-positive weight would either freeze the arm or subtract
|
|
362
|
-
# evidence; neither is a meaningful observation.
|
|
363
|
-
if weight_f <= 0.0:
|
|
364
|
-
weight_f = 1.0
|
|
365
|
-
|
|
366
|
-
try:
|
|
367
|
-
conn = _conn_for(self._db_path)
|
|
368
|
-
except sqlite3.Error as exc: # pragma: no cover — defensive
|
|
369
|
-
logger.warning("bandit.update: cannot open db: %s", exc)
|
|
370
|
-
return False
|
|
371
|
-
|
|
372
|
-
try:
|
|
373
|
-
row = conn.execute(
|
|
374
|
-
"SELECT profile_id, stratum, arm_id, settled_at "
|
|
375
|
-
"FROM bandit_plays WHERE play_id = ?",
|
|
376
|
-
(int(play_id),),
|
|
377
|
-
).fetchone()
|
|
378
|
-
except sqlite3.Error as exc:
|
|
379
|
-
logger.warning("bandit.update: lookup failed: %s", exc)
|
|
380
|
-
return False
|
|
381
|
-
|
|
382
|
-
if row is None:
|
|
383
|
-
logger.warning("bandit.update: play_id %s not found", play_id)
|
|
384
|
-
return False
|
|
385
|
-
if row["settled_at"] is not None:
|
|
386
|
-
# Idempotent no-op: already settled.
|
|
387
|
-
return False
|
|
388
|
-
|
|
389
|
-
profile_id = row["profile_id"]
|
|
390
|
-
stratum = row["stratum"]
|
|
391
|
-
arm_id = row["arm_id"]
|
|
392
|
-
now = _now_iso()
|
|
393
|
-
cap = self._alpha_cap
|
|
394
|
-
|
|
395
|
-
try:
|
|
396
|
-
# Ensure an arm row exists with prior (1,1). INSERT OR IGNORE is
|
|
397
|
-
# cheap — PK composite guarantees uniqueness.
|
|
398
|
-
conn.execute(
|
|
399
|
-
"INSERT OR IGNORE INTO bandit_arms "
|
|
400
|
-
"(profile_id, stratum, arm_id, alpha, beta, plays, "
|
|
401
|
-
" last_played_at) VALUES (?, ?, ?, 1.0, 1.0, 0, ?)",
|
|
402
|
-
(profile_id, stratum, arm_id, now),
|
|
403
|
-
)
|
|
404
|
-
# B2: MIN(cap, value) clamp.
|
|
405
|
-
conn.execute(
|
|
406
|
-
"UPDATE bandit_arms "
|
|
407
|
-
"SET alpha = MIN(?, alpha + ?), "
|
|
408
|
-
" beta = MIN(?, beta + ?), "
|
|
409
|
-
" plays = plays + 1, "
|
|
410
|
-
" last_played_at = ? "
|
|
411
|
-
"WHERE profile_id = ? AND stratum = ? AND arm_id = ?",
|
|
412
|
-
(cap, weight_f * reward_f, cap, weight_f * (1.0 - reward_f),
|
|
413
|
-
now, profile_id, stratum, arm_id),
|
|
414
|
-
)
|
|
415
|
-
conn.execute(
|
|
416
|
-
"UPDATE bandit_plays "
|
|
417
|
-
"SET reward = ?, settled_at = ?, settlement_type = ? "
|
|
418
|
-
"WHERE play_id = ?",
|
|
419
|
-
(reward_f, now, str(kind), int(play_id)),
|
|
420
|
-
)
|
|
421
|
-
except sqlite3.Error as exc:
|
|
422
|
-
logger.warning("bandit.update: write failed: %s", exc)
|
|
423
|
-
return False
|
|
424
|
-
|
|
425
|
-
# B5: invalidate the (profile, stratum) cache entry.
|
|
426
|
-
try:
|
|
427
|
-
self._cache.invalidate(profile_id, stratum)
|
|
428
|
-
except Exception: # pragma: no cover — defensive
|
|
429
|
-
pass
|
|
430
|
-
return True
|
|
431
|
-
|
|
432
|
-
def record_shown(self, play_id: int, fact_ids: Sequence[str]) -> bool:
|
|
433
|
-
"""Record which memories this play surfaced, for later settlement.
|
|
434
|
-
|
|
435
|
-
A play is settled from evidence — did anything downstream reference a
|
|
436
|
-
memory this query returned? The settler used to answer "which memories"
|
|
437
|
-
by reading ``learning_signals`` for the same ``query_id``, and those
|
|
438
|
-
rows are written by an enqueue that is deliberately off (it costs twenty
|
|
439
|
-
rows per query and inflated the ranking-phase counter 2,675x). With no
|
|
440
|
-
evidence to look for, every settlement fell through to the 120-second
|
|
441
|
-
neutral default of 0.5, which is why 165 arms all read alpha == beta.
|
|
442
|
-
|
|
443
|
-
So the play carries its own evidence. Best-effort by design: the reward
|
|
444
|
-
is a nicety and a recall is not. A failure here means this one play
|
|
445
|
-
settles as ``default``, exactly as before.
|
|
446
|
-
|
|
447
|
-
Bounded to the first few ids because the settler only ever reads the
|
|
448
|
-
top of the list, and an unbounded JSON blob on the recall path is a
|
|
449
|
-
write cost with no reader.
|
|
450
|
-
"""
|
|
451
|
-
if not play_id:
|
|
452
|
-
return False
|
|
453
|
-
ids = [str(f) for f in list(fact_ids)[:_SHOWN_FACT_LIMIT] if f]
|
|
454
|
-
if not ids:
|
|
455
|
-
return False
|
|
456
|
-
try:
|
|
457
|
-
conn = _conn_for(self._db_path)
|
|
458
|
-
conn.execute(
|
|
459
|
-
"UPDATE bandit_plays SET shown_fact_ids = ? WHERE play_id = ?",
|
|
460
|
-
(json.dumps(ids), int(play_id)),
|
|
461
|
-
)
|
|
462
|
-
return True
|
|
463
|
-
except sqlite3.Error as exc:
|
|
464
|
-
# Includes "no such column" on a store where M044 has not run.
|
|
465
|
-
logger.debug("bandit.record_shown: %s", exc)
|
|
466
|
-
return False
|
|
467
|
-
|
|
468
|
-
# ------------------------------------------------------------------
|
|
469
|
-
# snapshot (for dashboard — LLD-04 consumer)
|
|
470
|
-
# ------------------------------------------------------------------
|
|
471
|
-
|
|
472
|
-
def snapshot(self, top_n: int = 5) -> dict[str, list[dict[str, Any]]]:
|
|
473
|
-
"""Return ``{stratum → top-N arms by plays}``.
|
|
474
|
-
|
|
475
|
-
Lightweight read. Never raises — DB failures return ``{}``.
|
|
476
|
-
"""
|
|
477
|
-
try:
|
|
478
|
-
conn = _conn_for(self._db_path)
|
|
479
|
-
rows = conn.execute(
|
|
480
|
-
"SELECT stratum, arm_id, alpha, beta, plays "
|
|
481
|
-
"FROM bandit_arms WHERE profile_id = ? "
|
|
482
|
-
"ORDER BY stratum ASC, plays DESC",
|
|
483
|
-
(self._profile,),
|
|
484
|
-
).fetchall()
|
|
485
|
-
except sqlite3.Error as exc:
|
|
486
|
-
logger.debug("bandit.snapshot: %s", exc)
|
|
487
|
-
return {}
|
|
488
|
-
|
|
489
|
-
out: dict[str, list[dict[str, Any]]] = {}
|
|
490
|
-
for r in rows:
|
|
491
|
-
bucket = out.setdefault(r["stratum"], [])
|
|
492
|
-
if len(bucket) < int(top_n):
|
|
493
|
-
bucket.append({
|
|
494
|
-
"arm_id": r["arm_id"],
|
|
495
|
-
"alpha": float(r["alpha"]),
|
|
496
|
-
"beta": float(r["beta"]),
|
|
497
|
-
"plays": int(r["plays"]),
|
|
498
|
-
})
|
|
499
|
-
return out
|
|
500
|
-
|
|
501
|
-
# ------------------------------------------------------------------
|
|
502
|
-
# Loader for cache (executed outside the cache lock)
|
|
503
|
-
# ------------------------------------------------------------------
|
|
504
|
-
|
|
505
|
-
def _load_stratum_posteriors(
|
|
506
|
-
self,
|
|
507
|
-
profile_id: str,
|
|
508
|
-
stratum: str,
|
|
509
|
-
) -> dict[str, tuple[float, float]]:
|
|
510
|
-
"""Read ``{arm_id: (α, β)}`` for the given (profile, stratum)."""
|
|
511
|
-
try:
|
|
512
|
-
conn = _conn_for(self._db_path)
|
|
513
|
-
rows = conn.execute(
|
|
514
|
-
"SELECT arm_id, alpha, beta FROM bandit_arms "
|
|
515
|
-
"WHERE profile_id = ? AND stratum = ?",
|
|
516
|
-
(profile_id, stratum),
|
|
517
|
-
).fetchall()
|
|
518
|
-
except sqlite3.Error as exc:
|
|
519
|
-
logger.debug(
|
|
520
|
-
"bandit._load_stratum_posteriors: %s", exc,
|
|
521
|
-
)
|
|
522
|
-
return {}
|
|
523
|
-
return {
|
|
524
|
-
r["arm_id"]: (float(r["alpha"]), float(r["beta"]))
|
|
525
|
-
for r in rows
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
def _load_stratum_posteriors_readonly(
|
|
529
|
-
self,
|
|
530
|
-
stratum: str,
|
|
531
|
-
) -> dict[str, tuple[float, float]]:
|
|
532
|
-
"""Read posteriors through SQLite's URI read-only boundary."""
|
|
533
|
-
uri = f"{self._db_path.resolve().as_uri()}?mode=ro"
|
|
534
|
-
conn = sqlite3.connect(uri, uri=True, timeout=0.25)
|
|
535
|
-
try:
|
|
536
|
-
conn.row_factory = sqlite3.Row
|
|
537
|
-
conn.execute("PRAGMA query_only=ON")
|
|
538
|
-
conn.execute("PRAGMA busy_timeout=250")
|
|
539
|
-
rows = conn.execute(
|
|
540
|
-
"SELECT arm_id, alpha, beta FROM bandit_arms "
|
|
541
|
-
"WHERE profile_id = ? AND stratum = ?",
|
|
542
|
-
(self._profile, stratum),
|
|
543
|
-
).fetchall()
|
|
544
|
-
finally:
|
|
545
|
-
conn.close()
|
|
546
|
-
return {
|
|
547
|
-
row["arm_id"]: (float(row["alpha"]), float(row["beta"]))
|
|
548
|
-
for row in rows
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
def _insert_play(
|
|
552
|
-
self,
|
|
553
|
-
query_id: str,
|
|
554
|
-
stratum: str,
|
|
555
|
-
arm_id: str,
|
|
556
|
-
) -> int | None:
|
|
557
|
-
"""Insert a bandit_plays row; return lastrowid or None on failure.
|
|
558
|
-
|
|
559
|
-
B6: raw query text is NEVER stored — only ``query_id`` (opaque UUID).
|
|
560
|
-
"""
|
|
561
|
-
try:
|
|
562
|
-
conn = _conn_for(self._db_path)
|
|
563
|
-
cur = conn.execute(
|
|
564
|
-
"INSERT INTO bandit_plays "
|
|
565
|
-
"(profile_id, query_id, stratum, arm_id, played_at) "
|
|
566
|
-
"VALUES (?, ?, ?, ?, ?)",
|
|
567
|
-
(self._profile, str(query_id), stratum, arm_id, _now_iso()),
|
|
568
|
-
)
|
|
569
|
-
return int(cur.lastrowid) if cur.lastrowid is not None else None
|
|
570
|
-
except sqlite3.Error as exc:
|
|
571
|
-
logger.debug("bandit._insert_play: %s", exc)
|
|
572
|
-
return None
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
# ---------------------------------------------------------------------------
|
|
576
|
-
# Retention sweep (LLD-03 §3.6 — B8)
|
|
577
|
-
# ---------------------------------------------------------------------------
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
def retention_sweep(
|
|
581
|
-
db_path: Path | str,
|
|
582
|
-
retention_days: int = 7,
|
|
583
|
-
*,
|
|
584
|
-
now: datetime | None = None,
|
|
585
|
-
chunk_size: int = 1000,
|
|
586
|
-
) -> int:
|
|
587
|
-
"""Delete settled bandit_plays older than ``now - retention_days``.
|
|
588
|
-
|
|
589
|
-
Only rows with ``settled_at IS NOT NULL AND settled_at < cutoff`` are
|
|
590
|
-
removed. Unsettled rows are NEVER touched (B8).
|
|
591
|
-
|
|
592
|
-
Returns total number of rows deleted.
|
|
593
|
-
"""
|
|
594
|
-
if retention_days < 0:
|
|
595
|
-
raise ValueError("retention_days must be >= 0")
|
|
596
|
-
current = now if now is not None else datetime.now(timezone.utc)
|
|
597
|
-
cutoff_iso = (current - timedelta(days=int(retention_days))).isoformat(
|
|
598
|
-
timespec="seconds",
|
|
599
|
-
)
|
|
600
|
-
deleted_total = 0
|
|
601
|
-
path = Path(db_path)
|
|
602
|
-
|
|
603
|
-
# Fresh connection — sweeps may be called from arbitrary threads / the
|
|
604
|
-
# scheduler, not necessarily the hot-path thread.
|
|
605
|
-
conn = sqlite3.connect(str(path), timeout=10.0, isolation_level=None)
|
|
606
|
-
try:
|
|
607
|
-
try:
|
|
608
|
-
conn.execute("PRAGMA journal_mode=WAL")
|
|
609
|
-
conn.execute("PRAGMA busy_timeout=5000")
|
|
610
|
-
except sqlite3.Error: # pragma: no cover
|
|
611
|
-
pass
|
|
612
|
-
|
|
613
|
-
while True:
|
|
614
|
-
try:
|
|
615
|
-
cur = conn.execute(
|
|
616
|
-
"DELETE FROM bandit_plays "
|
|
617
|
-
"WHERE rowid IN ("
|
|
618
|
-
" SELECT rowid FROM bandit_plays "
|
|
619
|
-
" WHERE settled_at IS NOT NULL AND settled_at < ? "
|
|
620
|
-
" LIMIT ?"
|
|
621
|
-
")",
|
|
622
|
-
(cutoff_iso, int(chunk_size)),
|
|
623
|
-
)
|
|
624
|
-
except sqlite3.Error as exc:
|
|
625
|
-
logger.warning("retention_sweep: delete failed: %s", exc)
|
|
626
|
-
break
|
|
627
|
-
affected = cur.rowcount or 0
|
|
628
|
-
if affected <= 0:
|
|
629
|
-
break
|
|
630
|
-
deleted_total += affected
|
|
631
|
-
# Guard against infinite loop on drivers that return -1.
|
|
632
|
-
if affected < int(chunk_size) and cur.rowcount != -1:
|
|
633
|
-
break
|
|
634
|
-
finally:
|
|
635
|
-
try:
|
|
636
|
-
conn.close()
|
|
637
|
-
except sqlite3.Error: # pragma: no cover
|
|
638
|
-
pass
|
|
639
|
-
|
|
640
|
-
logger.info(
|
|
641
|
-
"bandit_plays_retention_sweep: deleted=%d, cutoff=%s",
|
|
642
|
-
deleted_total, cutoff_iso,
|
|
643
|
-
)
|
|
644
|
-
return deleted_total
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
__all__ = (
|
|
648
|
-
"BanditChoice",
|
|
649
|
-
"ContextualBandit",
|
|
650
|
-
"close_threadlocal_conn",
|
|
651
|
-
"compute_stratum",
|
|
652
|
-
"current_time_bucket",
|
|
653
|
-
"retention_sweep",
|
|
654
|
-
)
|