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,281 +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 — Track A.3 (LLD-10 §5)
|
|
4
|
-
|
|
5
|
-
"""Post-promotion watch + auto-rollback (LLD-10 §5).
|
|
6
|
-
|
|
7
|
-
After promotion flips ``is_active`` to the new row, the next 200
|
|
8
|
-
recalls are measured against the pre-promotion baseline. If mean
|
|
9
|
-
NDCG@10 drops by ≥ REGRESSION_THRESHOLD (2%), auto-rollback fires:
|
|
10
|
-
|
|
11
|
-
* Current active → ``is_rollback=1``, ``is_active=0``,
|
|
12
|
-
``rollback_reason=<reason>``.
|
|
13
|
-
* Former ``is_previous`` → ``is_active=1``, ``is_previous=0``.
|
|
14
|
-
* ``metadata_json.retrain_disabled_until`` set to now+24h; counter
|
|
15
|
-
reset to 0.
|
|
16
|
-
|
|
17
|
-
All three flag flips happen inside one ``BEGIN IMMEDIATE`` transaction.
|
|
18
|
-
The partial unique indexes ``idx_model_active_one`` and
|
|
19
|
-
``idx_model_candidate_one`` (M009) enforce single-active and
|
|
20
|
-
single-candidate per profile.
|
|
21
|
-
|
|
22
|
-
Failure-mode handling (LLD-10 §5.4 "missing is_previous"):
|
|
23
|
-
If the is_previous row is absent, we do NOT demote the current
|
|
24
|
-
active — that would leave the profile with no active model.
|
|
25
|
-
Instead we log an error, set ``metadata_json.safe_mode=1`` on the
|
|
26
|
-
active row, and let AdaptiveRanker fall back to Phase-2 heuristic.
|
|
27
|
-
"""
|
|
28
|
-
|
|
29
|
-
from __future__ import annotations
|
|
30
|
-
|
|
31
|
-
import json
|
|
32
|
-
import logging
|
|
33
|
-
import sqlite3
|
|
34
|
-
from datetime import datetime, timedelta, timezone
|
|
35
|
-
from typing import Final
|
|
36
|
-
|
|
37
|
-
from superlocalmemory.learning.model_cache import invalidate as invalidate_model_cache
|
|
38
|
-
|
|
39
|
-
logger = logging.getLogger(__name__)
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
_WATCH_WINDOW: Final[int] = 200
|
|
43
|
-
_REGRESSION_THRESHOLD: Final[float] = 0.02
|
|
44
|
-
_RETRAIN_DISABLED_HOURS: Final[int] = 24
|
|
45
|
-
|
|
46
|
-
#: Baseline floor below which the ratio ``(baseline - current) / baseline``
|
|
47
|
-
#: is numerically meaningless (division explodes; a 1pp drop on a 0.5%
|
|
48
|
-
#: baseline looks like 200% regression). Below this floor we switch to
|
|
49
|
-
#: an ABSOLUTE-drop comparison against ``_REGRESSION_THRESHOLD``. Stage 8
|
|
50
|
-
#: F4.B H-04 fix — previously baseline ≤ 0 silently disarmed the
|
|
51
|
-
#: watchdog, which meant a freshly-promoted-but-broken model with a
|
|
52
|
-
#: sparse-data baseline of 0 would never auto-rollback.
|
|
53
|
-
_BASELINE_RATIO_FLOOR: Final[float] = 0.05
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
def _iso_now() -> str:
|
|
57
|
-
return datetime.now(timezone.utc).isoformat()
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
def _iso_in_hours(hours: int) -> str:
|
|
61
|
-
return (
|
|
62
|
-
datetime.now(timezone.utc) + timedelta(hours=hours)
|
|
63
|
-
).isoformat()
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
class ModelRollback:
|
|
67
|
-
"""Watch post-promotion NDCG@10 and flip lineage on regression."""
|
|
68
|
-
|
|
69
|
-
WATCH_WINDOW: Final[int] = _WATCH_WINDOW
|
|
70
|
-
REGRESSION_THRESHOLD: Final[float] = _REGRESSION_THRESHOLD
|
|
71
|
-
RETRAIN_DISABLED_HOURS: Final[int] = _RETRAIN_DISABLED_HOURS
|
|
72
|
-
|
|
73
|
-
def __init__(
|
|
74
|
-
self,
|
|
75
|
-
*,
|
|
76
|
-
learning_db_path: str,
|
|
77
|
-
profile_id: str,
|
|
78
|
-
baseline_ndcg: float,
|
|
79
|
-
) -> None:
|
|
80
|
-
self._db = str(learning_db_path)
|
|
81
|
-
self._profile_id = profile_id
|
|
82
|
-
self._baseline = float(baseline_ndcg)
|
|
83
|
-
self._observations: list[float] = []
|
|
84
|
-
|
|
85
|
-
# ------------------------------------------------------------------
|
|
86
|
-
# Observation ingestion
|
|
87
|
-
# ------------------------------------------------------------------
|
|
88
|
-
|
|
89
|
-
def record_post_promotion(
|
|
90
|
-
self, *, query_id: str, ndcg_at_10: float,
|
|
91
|
-
) -> None:
|
|
92
|
-
"""Record one post-promotion NDCG@10 sample (at most WATCH_WINDOW)."""
|
|
93
|
-
if len(self._observations) >= self.WATCH_WINDOW:
|
|
94
|
-
return
|
|
95
|
-
self._observations.append(float(ndcg_at_10))
|
|
96
|
-
|
|
97
|
-
def should_rollback(self) -> bool:
|
|
98
|
-
"""Return True iff ≥ WATCH_WINDOW samples and regression detected.
|
|
99
|
-
|
|
100
|
-
Regression is detected by whichever of these is true:
|
|
101
|
-
* **Ratio path** (baseline ≥ ``_BASELINE_RATIO_FLOOR``, i.e. 0.05):
|
|
102
|
-
``(baseline - current) / baseline ≥ REGRESSION_THRESHOLD``.
|
|
103
|
-
Existing v3.4.22 pre-fix semantics preserved at normal
|
|
104
|
-
baselines.
|
|
105
|
-
* **Absolute path** (baseline below the ratio floor — includes
|
|
106
|
-
zero and negative baselines which can happen on sparse data):
|
|
107
|
-
``(baseline - current) ≥ REGRESSION_THRESHOLD`` in absolute
|
|
108
|
-
units. Stage 8 F4.B H-04 fix — a zero baseline is a valid
|
|
109
|
-
observation, not "no baseline".
|
|
110
|
-
|
|
111
|
-
Invariants:
|
|
112
|
-
* Watch window minimum is always enforced — we will NOT fire
|
|
113
|
-
before ``WATCH_WINDOW`` samples land.
|
|
114
|
-
* ``REGRESSION_THRESHOLD`` is the same 0.02 for both paths, so
|
|
115
|
-
the fix is not stricter for typical baselines.
|
|
116
|
-
"""
|
|
117
|
-
if len(self._observations) < self.WATCH_WINDOW:
|
|
118
|
-
return False
|
|
119
|
-
current = sum(self._observations) / len(self._observations)
|
|
120
|
-
drop_abs = self._baseline - current
|
|
121
|
-
# S9-SKEP-10: smooth the ratio/absolute boundary.
|
|
122
|
-
#
|
|
123
|
-
# Before this fix there was a step discontinuity at
|
|
124
|
-
# ``baseline == _BASELINE_RATIO_FLOOR`` (0.05):
|
|
125
|
-
# * baseline=0.049 → abs path fires at drop≥0.02
|
|
126
|
-
# * baseline=0.050 → ratio path fires at drop≥0.001 (0.02*0.05)
|
|
127
|
-
# So a 0.001 baseline drift produced a 20× sensitivity change,
|
|
128
|
-
# and new-user profiles near 0.05 oscillated between "never
|
|
129
|
-
# rollback" and "rollback on any noise". We now linearly blend
|
|
130
|
-
# the two thresholds across a ±`_BLEND_BAND` neighbourhood
|
|
131
|
-
# around the floor, so the derivative of the threshold with
|
|
132
|
-
# respect to baseline stays bounded.
|
|
133
|
-
#
|
|
134
|
-
# Asymptotic equivalence:
|
|
135
|
-
# baseline ≥ floor + band → pure ratio (prior behaviour).
|
|
136
|
-
# baseline ≤ floor - band → pure absolute (prior behaviour).
|
|
137
|
-
_BLEND_BAND = 0.02
|
|
138
|
-
hi = _BASELINE_RATIO_FLOOR + _BLEND_BAND
|
|
139
|
-
lo = max(0.0, _BASELINE_RATIO_FLOOR - _BLEND_BAND)
|
|
140
|
-
# The "drop needed to fire" in each regime.
|
|
141
|
-
# ratio regime: drop ≥ baseline * REGRESSION_THRESHOLD
|
|
142
|
-
# abs regime: drop ≥ REGRESSION_THRESHOLD
|
|
143
|
-
ratio_drop = self._baseline * self.REGRESSION_THRESHOLD
|
|
144
|
-
abs_drop = self.REGRESSION_THRESHOLD
|
|
145
|
-
if self._baseline >= hi:
|
|
146
|
-
needed = ratio_drop
|
|
147
|
-
elif self._baseline <= lo:
|
|
148
|
-
needed = abs_drop
|
|
149
|
-
else:
|
|
150
|
-
# Linear blend — at baseline=lo weight=0, at baseline=hi weight=1.
|
|
151
|
-
weight = (self._baseline - lo) / (hi - lo)
|
|
152
|
-
needed = weight * ratio_drop + (1.0 - weight) * abs_drop
|
|
153
|
-
return drop_abs >= needed
|
|
154
|
-
|
|
155
|
-
# ------------------------------------------------------------------
|
|
156
|
-
# Lineage flip
|
|
157
|
-
# ------------------------------------------------------------------
|
|
158
|
-
|
|
159
|
-
def execute_rollback(self, reason: str) -> bool:
|
|
160
|
-
"""Flip lineage atomically — return True on success.
|
|
161
|
-
|
|
162
|
-
Transaction shape (all under one BEGIN IMMEDIATE):
|
|
163
|
-
1. Confirm an ``is_previous=1`` row exists for profile.
|
|
164
|
-
If missing → abort, set ``safe_mode`` on active, return False.
|
|
165
|
-
2. Current active row: set ``is_active=0, is_rollback=1,
|
|
166
|
-
rollback_reason=?``.
|
|
167
|
-
3. Previous row: set ``is_active=1, is_previous=0``.
|
|
168
|
-
4. Patch ``metadata_json`` on the new active with
|
|
169
|
-
``retrain_disabled_until`` (+24h) and
|
|
170
|
-
``last_rollback_at``, counter reset.
|
|
171
|
-
"""
|
|
172
|
-
with sqlite3.connect(self._db, timeout=10) as conn:
|
|
173
|
-
conn.row_factory = sqlite3.Row
|
|
174
|
-
try:
|
|
175
|
-
conn.execute("BEGIN IMMEDIATE")
|
|
176
|
-
prev = conn.execute(
|
|
177
|
-
"SELECT id FROM learning_model_state "
|
|
178
|
-
"WHERE profile_id = ? AND is_previous = 1 LIMIT 1",
|
|
179
|
-
(self._profile_id,),
|
|
180
|
-
).fetchone()
|
|
181
|
-
if prev is None:
|
|
182
|
-
conn.rollback()
|
|
183
|
-
self._set_safe_mode(conn)
|
|
184
|
-
logger.error(
|
|
185
|
-
"rollback: missing is_previous row for profile=%s "
|
|
186
|
-
"reason=%s — entering safe_mode",
|
|
187
|
-
self._profile_id, reason,
|
|
188
|
-
)
|
|
189
|
-
return False
|
|
190
|
-
|
|
191
|
-
# Step 2 — demote current active (unset is_active FIRST so
|
|
192
|
-
# the partial unique index on is_active=1 never has two rows).
|
|
193
|
-
conn.execute(
|
|
194
|
-
"UPDATE learning_model_state "
|
|
195
|
-
"SET is_active = 0, is_rollback = 1, "
|
|
196
|
-
" rollback_reason = ? "
|
|
197
|
-
"WHERE profile_id = ? AND is_active = 1",
|
|
198
|
-
(reason, self._profile_id),
|
|
199
|
-
)
|
|
200
|
-
|
|
201
|
-
# Step 3 — promote previous to active.
|
|
202
|
-
conn.execute(
|
|
203
|
-
"UPDATE learning_model_state "
|
|
204
|
-
"SET is_active = 1, is_previous = 0 "
|
|
205
|
-
"WHERE id = ?",
|
|
206
|
-
(prev["id"],),
|
|
207
|
-
)
|
|
208
|
-
|
|
209
|
-
# Step 4 — patch metadata on the new active.
|
|
210
|
-
new_meta_row = conn.execute(
|
|
211
|
-
"SELECT metadata_json FROM learning_model_state "
|
|
212
|
-
"WHERE id = ?",
|
|
213
|
-
(prev["id"],),
|
|
214
|
-
).fetchone()
|
|
215
|
-
try:
|
|
216
|
-
meta = json.loads(new_meta_row["metadata_json"] or "{}")
|
|
217
|
-
except (TypeError, ValueError):
|
|
218
|
-
meta = {}
|
|
219
|
-
meta.update({
|
|
220
|
-
"retrain_disabled_until": _iso_in_hours(
|
|
221
|
-
self.RETRAIN_DISABLED_HOURS,
|
|
222
|
-
),
|
|
223
|
-
"last_rollback_at": _iso_now(),
|
|
224
|
-
"new_outcomes_since_last_retrain": 0,
|
|
225
|
-
})
|
|
226
|
-
conn.execute(
|
|
227
|
-
"UPDATE learning_model_state "
|
|
228
|
-
"SET metadata_json = ? WHERE id = ?",
|
|
229
|
-
(json.dumps(meta), prev["id"]),
|
|
230
|
-
)
|
|
231
|
-
conn.commit()
|
|
232
|
-
except sqlite3.Error as exc:
|
|
233
|
-
conn.rollback()
|
|
234
|
-
logger.error(
|
|
235
|
-
"rollback: sqlite error profile=%s reason=%s: %s",
|
|
236
|
-
self._profile_id, reason, exc,
|
|
237
|
-
)
|
|
238
|
-
return False
|
|
239
|
-
|
|
240
|
-
invalidate_model_cache(self._profile_id)
|
|
241
|
-
logger.warning(
|
|
242
|
-
"AUTO-ROLLBACK profile=%s reason=%s observations=%d "
|
|
243
|
-
"baseline_ndcg=%.4f current_ndcg=%.4f",
|
|
244
|
-
self._profile_id, reason, len(self._observations),
|
|
245
|
-
self._baseline,
|
|
246
|
-
(sum(self._observations) / len(self._observations))
|
|
247
|
-
if self._observations else 0.0,
|
|
248
|
-
)
|
|
249
|
-
return True
|
|
250
|
-
|
|
251
|
-
# ------------------------------------------------------------------
|
|
252
|
-
# Safe-mode helper (is_previous missing)
|
|
253
|
-
# ------------------------------------------------------------------
|
|
254
|
-
|
|
255
|
-
def _set_safe_mode(self, conn: sqlite3.Connection) -> None:
|
|
256
|
-
try:
|
|
257
|
-
row = conn.execute(
|
|
258
|
-
"SELECT metadata_json FROM learning_model_state "
|
|
259
|
-
"WHERE profile_id = ? AND is_active = 1",
|
|
260
|
-
(self._profile_id,),
|
|
261
|
-
).fetchone()
|
|
262
|
-
meta: dict
|
|
263
|
-
if row is None:
|
|
264
|
-
meta = {"safe_mode": 1}
|
|
265
|
-
else:
|
|
266
|
-
try:
|
|
267
|
-
meta = json.loads(row["metadata_json"] or "{}")
|
|
268
|
-
except (TypeError, ValueError):
|
|
269
|
-
meta = {}
|
|
270
|
-
meta["safe_mode"] = 1
|
|
271
|
-
conn.execute(
|
|
272
|
-
"UPDATE learning_model_state SET metadata_json = ? "
|
|
273
|
-
"WHERE profile_id = ? AND is_active = 1",
|
|
274
|
-
(json.dumps(meta), self._profile_id),
|
|
275
|
-
)
|
|
276
|
-
conn.commit()
|
|
277
|
-
except sqlite3.Error as exc: # pragma: no cover — defensive
|
|
278
|
-
logger.debug("safe_mode set failed: %s", exc)
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
__all__ = ("ModelRollback",)
|
|
@@ -1,306 +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 — Stage 9 DASH-02
|
|
4
|
-
|
|
5
|
-
"""Background queue for producer-side engagement-reward recording.
|
|
6
|
-
|
|
7
|
-
**Why this module exists.** Before v3.4.22, ``EngagementRewardModel.record_recall``
|
|
8
|
-
had zero production callers. Every recall path (CLI, MCP, dashboard, daemon
|
|
9
|
-
HTTP) returned results without ever creating a ``pending_outcomes`` row. The
|
|
10
|
-
closed-loop learning pipeline therefore had no producer — its consumers
|
|
11
|
-
(PostToolUse hook, Stop hook, finalize_outcome, action_outcomes, retrain,
|
|
12
|
-
shadow, rollback) were all consuming an empty stream.
|
|
13
|
-
|
|
14
|
-
This module wires the producer as a non-blocking enqueue + background drain.
|
|
15
|
-
The I1 invariant is absolute — recall wall time must NOT regress. So we:
|
|
16
|
-
|
|
17
|
-
1. ``enqueue_recall`` is ``queue.put_nowait`` — microseconds.
|
|
18
|
-
2. A single daemon thread drains the queue and calls
|
|
19
|
-
``EngagementRewardModel.record_recall`` (one SQLite INSERT per recall).
|
|
20
|
-
3. Queue is bounded; a full queue drops the oldest entry and bumps a
|
|
21
|
-
counter. Signal quality is NEVER load-bearing on recall correctness.
|
|
22
|
-
|
|
23
|
-
The worker lives for the daemon's lifetime and is stopped on shutdown
|
|
24
|
-
by ``unified_daemon.py``'s lifespan hook.
|
|
25
|
-
"""
|
|
26
|
-
|
|
27
|
-
from __future__ import annotations
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
from superlocalmemory.core.session_identity import is_conversation
|
|
31
|
-
import logging
|
|
32
|
-
import queue
|
|
33
|
-
import threading
|
|
34
|
-
from dataclasses import dataclass, field
|
|
35
|
-
from pathlib import Path
|
|
36
|
-
from typing import Optional
|
|
37
|
-
|
|
38
|
-
logger = logging.getLogger(__name__)
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
# ---------------------------------------------------------------------------
|
|
42
|
-
# Public dataclass — the enqueue payload
|
|
43
|
-
# ---------------------------------------------------------------------------
|
|
44
|
-
|
|
45
|
-
@dataclass(frozen=True)
|
|
46
|
-
class RecallEvent:
|
|
47
|
-
"""One recall event awaiting pending_outcomes persistence.
|
|
48
|
-
|
|
49
|
-
Fields mirror ``EngagementRewardModel.record_recall`` arguments.
|
|
50
|
-
``session_id`` is REQUIRED for hook-based signal matching; if the
|
|
51
|
-
caller can't produce one, pass a stable synthetic like
|
|
52
|
-
``f"cli:{os.getpid()}"`` or ``"dashboard:<profile>"``.
|
|
53
|
-
"""
|
|
54
|
-
session_id: str
|
|
55
|
-
profile_id: str
|
|
56
|
-
query: str
|
|
57
|
-
fact_ids: tuple[str, ...]
|
|
58
|
-
query_id: str = ""
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
# ---------------------------------------------------------------------------
|
|
62
|
-
# Module state — bounded queue + counters
|
|
63
|
-
# ---------------------------------------------------------------------------
|
|
64
|
-
|
|
65
|
-
#: S9-DASH-02: cap at 1000 pending recalls. At ~50 ms per row drain, even
|
|
66
|
-
#: a full queue drains in 50 s. Bigger than realistic daemon burst (p99
|
|
67
|
-
#: recalls/sec < 20). Fuller queue → drop oldest, bump counter.
|
|
68
|
-
_MAX_QUEUE = 1000
|
|
69
|
-
|
|
70
|
-
_queue: "queue.Queue[RecallEvent]" = queue.Queue(maxsize=_MAX_QUEUE)
|
|
71
|
-
_worker_thread: Optional[threading.Thread] = None
|
|
72
|
-
_stop_event = threading.Event()
|
|
73
|
-
_counters: dict[str, int] = {
|
|
74
|
-
"recall_enqueued": 0,
|
|
75
|
-
"recall_dropped_queue_full": 0,
|
|
76
|
-
"recall_persisted": 0,
|
|
77
|
-
"recall_persist_failed": 0,
|
|
78
|
-
"recall_reaped": 0,
|
|
79
|
-
}
|
|
80
|
-
_counters_lock = threading.Lock()
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
def _bump(name: str, n: int = 1) -> None:
|
|
84
|
-
with _counters_lock:
|
|
85
|
-
_counters[name] = _counters.get(name, 0) + n
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
def get_counters() -> dict[str, int]:
|
|
89
|
-
"""Snapshot of queue counters for dashboards / tests."""
|
|
90
|
-
with _counters_lock:
|
|
91
|
-
return dict(_counters)
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
def queue_size() -> int:
|
|
95
|
-
"""Current queue depth (approximate, no lock)."""
|
|
96
|
-
return _queue.qsize()
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
# ---------------------------------------------------------------------------
|
|
100
|
-
# Public API — called from the recall hot path
|
|
101
|
-
# ---------------------------------------------------------------------------
|
|
102
|
-
|
|
103
|
-
def enqueue_recall(event: RecallEvent) -> None:
|
|
104
|
-
"""Non-blocking enqueue for later ``record_recall`` persistence.
|
|
105
|
-
|
|
106
|
-
Hot-path cost: one ``put_nowait`` — ~1 µs. Drops the event if the
|
|
107
|
-
queue is full; never raises. Signal quality is not load-bearing on
|
|
108
|
-
recall correctness (S9-DASH-02 contract).
|
|
109
|
-
"""
|
|
110
|
-
if not isinstance(event, RecallEvent):
|
|
111
|
-
return
|
|
112
|
-
if not event.session_id or not event.profile_id:
|
|
113
|
-
# S9-DASH-02: session_id is mandatory — hooks key by it.
|
|
114
|
-
# If the caller can't name a session, we silently drop: this
|
|
115
|
-
# is a recall whose outcome cannot match to a signal anyway.
|
|
116
|
-
return
|
|
117
|
-
if not is_conversation(event.session_id, event.profile_id):
|
|
118
|
-
# Same reason, one step further. A front that invents an id names
|
|
119
|
-
# itself, not a caller: ``engine:<pid>`` is the daemon every client
|
|
120
|
-
# shares, ``cli:<pid>`` a process that exits before any follow-on
|
|
121
|
-
# action, ``http:<ms>`` a single request. No tool event can ever
|
|
122
|
-
# carry one, so the outcome is unmatchable the moment it is written.
|
|
123
|
-
# Recording it anyway is not free: a play that is never settled from
|
|
124
|
-
# evidence is eventually settled from nothing, and a neutral update
|
|
125
|
-
# tightens a Beta posterior around its prior instead of leaving it
|
|
126
|
-
# movable.
|
|
127
|
-
_bump("recall_dropped_synthetic_session")
|
|
128
|
-
return
|
|
129
|
-
try:
|
|
130
|
-
_queue.put_nowait(event)
|
|
131
|
-
_bump("recall_enqueued")
|
|
132
|
-
except queue.Full:
|
|
133
|
-
# Drop oldest-first so newer recalls always make it in.
|
|
134
|
-
try:
|
|
135
|
-
_queue.get_nowait()
|
|
136
|
-
except queue.Empty:
|
|
137
|
-
pass
|
|
138
|
-
try:
|
|
139
|
-
_queue.put_nowait(event)
|
|
140
|
-
_bump("recall_dropped_queue_full")
|
|
141
|
-
except queue.Full: # pragma: no cover — defensive
|
|
142
|
-
_bump("recall_dropped_queue_full")
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
# ---------------------------------------------------------------------------
|
|
146
|
-
# Worker — persists to pending_outcomes
|
|
147
|
-
# ---------------------------------------------------------------------------
|
|
148
|
-
|
|
149
|
-
def _drain_once(memory_db_path: Path, max_batch: int = 50) -> int:
|
|
150
|
-
"""Drain up to ``max_batch`` events, persisting each via
|
|
151
|
-
``EngagementRewardModel.record_recall``. Returns count persisted.
|
|
152
|
-
"""
|
|
153
|
-
from superlocalmemory.learning.reward import EngagementRewardModel
|
|
154
|
-
|
|
155
|
-
model = EngagementRewardModel(memory_db_path)
|
|
156
|
-
persisted = 0
|
|
157
|
-
try:
|
|
158
|
-
for _ in range(max_batch):
|
|
159
|
-
try:
|
|
160
|
-
event = _queue.get_nowait()
|
|
161
|
-
except queue.Empty:
|
|
162
|
-
break
|
|
163
|
-
try:
|
|
164
|
-
model.record_recall(
|
|
165
|
-
profile_id=event.profile_id,
|
|
166
|
-
session_id=event.session_id,
|
|
167
|
-
recall_query_id=event.query_id or "",
|
|
168
|
-
fact_ids=list(event.fact_ids),
|
|
169
|
-
query_text=event.query,
|
|
170
|
-
)
|
|
171
|
-
_bump("recall_persisted")
|
|
172
|
-
persisted += 1
|
|
173
|
-
except Exception as exc:
|
|
174
|
-
_bump("recall_persist_failed")
|
|
175
|
-
logger.debug(
|
|
176
|
-
"outcome_queue: record_recall failed: %s (session=%s)",
|
|
177
|
-
exc, event.session_id,
|
|
178
|
-
)
|
|
179
|
-
finally:
|
|
180
|
-
try:
|
|
181
|
-
model.close()
|
|
182
|
-
except Exception:
|
|
183
|
-
pass
|
|
184
|
-
return persisted
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
#: S9-DASH-02: reaper cadence — force-finalize pending_outcomes older
|
|
188
|
-
#: than this so CLI/dashboard recalls (no Stop hook) still land in
|
|
189
|
-
#: action_outcomes with a neutral reward. One hour keeps slow-moving
|
|
190
|
-
#: interactive sessions alive while still draining abandoned recalls.
|
|
191
|
-
_REAP_INTERVAL_S = 300.0 # check every 5 minutes
|
|
192
|
-
_REAP_AGE_MS = 3_600_000 # 1 hour
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
def _reap_stale(memory_db_path: Path) -> int:
|
|
196
|
-
"""Force-finalize pending_outcomes older than ``_REAP_AGE_MS``.
|
|
197
|
-
|
|
198
|
-
Uses ``EngagementRewardModel.reap_stale`` which computes the label
|
|
199
|
-
from whatever signals accumulated (``0.5`` if none, which is the
|
|
200
|
-
intended neutral for CLI/dashboard recalls without hook coverage).
|
|
201
|
-
"""
|
|
202
|
-
try:
|
|
203
|
-
from superlocalmemory.learning.reward import EngagementRewardModel
|
|
204
|
-
model = EngagementRewardModel(memory_db_path)
|
|
205
|
-
try:
|
|
206
|
-
return int(model.reap_stale(older_than_ms=_REAP_AGE_MS))
|
|
207
|
-
finally:
|
|
208
|
-
try:
|
|
209
|
-
model.close()
|
|
210
|
-
except Exception:
|
|
211
|
-
pass
|
|
212
|
-
except Exception as exc: # pragma: no cover — defensive
|
|
213
|
-
logger.debug("reap_stale failed: %s", exc)
|
|
214
|
-
return 0
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
def _worker_loop(memory_db_path: Path, interval_s: float) -> None:
|
|
218
|
-
logger.info(
|
|
219
|
-
"outcome_queue worker started (db=%s interval=%.2fs)",
|
|
220
|
-
memory_db_path, interval_s,
|
|
221
|
-
)
|
|
222
|
-
import time as _time
|
|
223
|
-
next_reap = _time.monotonic() + _REAP_INTERVAL_S
|
|
224
|
-
# Adaptive idle back-off: poll at interval_s under load, but relax the wait
|
|
225
|
-
# (doubling, capped) when the queue drains empty so an idle daemon stops
|
|
226
|
-
# contending on the shared SQLite file every 0.25s (issue #53). Snaps back
|
|
227
|
-
# to interval_s the instant there is work again.
|
|
228
|
-
_idle_cap = max(interval_s, 2.0)
|
|
229
|
-
cur_wait = interval_s
|
|
230
|
-
while not _stop_event.wait(cur_wait):
|
|
231
|
-
try:
|
|
232
|
-
drained = _drain_once(memory_db_path)
|
|
233
|
-
except Exception as exc: # pragma: no cover — defensive
|
|
234
|
-
logger.warning("outcome_queue drain crashed: %s", exc)
|
|
235
|
-
drained = 0
|
|
236
|
-
cur_wait = interval_s if drained else min(cur_wait * 2.0, _idle_cap)
|
|
237
|
-
# Periodic reaper for CLI/dashboard outcomes that no Stop hook
|
|
238
|
-
# will ever finalize. Runs OFF the drain path so a busy queue
|
|
239
|
-
# doesn't starve the reaper.
|
|
240
|
-
now = _time.monotonic()
|
|
241
|
-
if now >= next_reap:
|
|
242
|
-
try:
|
|
243
|
-
reaped = _reap_stale(memory_db_path)
|
|
244
|
-
if reaped:
|
|
245
|
-
logger.info(
|
|
246
|
-
"outcome_queue reaper: finalized %d stale rows",
|
|
247
|
-
reaped,
|
|
248
|
-
)
|
|
249
|
-
_bump("recall_reaped", reaped)
|
|
250
|
-
except Exception: # pragma: no cover
|
|
251
|
-
pass
|
|
252
|
-
next_reap = now + _REAP_INTERVAL_S
|
|
253
|
-
# Final drain on graceful shutdown.
|
|
254
|
-
try:
|
|
255
|
-
_drain_once(memory_db_path, max_batch=1000)
|
|
256
|
-
except Exception:
|
|
257
|
-
pass
|
|
258
|
-
logger.info("outcome_queue worker stopped")
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
def start_worker(memory_db_path: Path, *, interval_s: float = 0.25) -> None:
|
|
262
|
-
"""Start the drain thread (idempotent)."""
|
|
263
|
-
global _worker_thread
|
|
264
|
-
if _worker_thread is not None and _worker_thread.is_alive():
|
|
265
|
-
return
|
|
266
|
-
_stop_event.clear()
|
|
267
|
-
_worker_thread = threading.Thread(
|
|
268
|
-
target=_worker_loop,
|
|
269
|
-
args=(Path(memory_db_path), interval_s),
|
|
270
|
-
name="slm-outcome-queue",
|
|
271
|
-
daemon=True,
|
|
272
|
-
)
|
|
273
|
-
_worker_thread.start()
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
def stop_worker(*, timeout_s: float = 2.0) -> int:
|
|
277
|
-
"""Signal the worker to stop and wait up to ``timeout_s`` for flush."""
|
|
278
|
-
global _worker_thread
|
|
279
|
-
_stop_event.set()
|
|
280
|
-
if _worker_thread is not None and _worker_thread.is_alive():
|
|
281
|
-
_worker_thread.join(timeout=timeout_s)
|
|
282
|
-
remaining = _queue.qsize()
|
|
283
|
-
_worker_thread = None
|
|
284
|
-
return remaining
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
# ---------------------------------------------------------------------------
|
|
288
|
-
# Test helpers
|
|
289
|
-
# ---------------------------------------------------------------------------
|
|
290
|
-
|
|
291
|
-
def _reset_for_testing() -> None:
|
|
292
|
-
"""TEST-ONLY: drain queue and zero counters. Never called in prod."""
|
|
293
|
-
global _worker_thread
|
|
294
|
-
_stop_event.set()
|
|
295
|
-
if _worker_thread is not None and _worker_thread.is_alive():
|
|
296
|
-
_worker_thread.join(timeout=1.0)
|
|
297
|
-
_worker_thread = None
|
|
298
|
-
while True:
|
|
299
|
-
try:
|
|
300
|
-
_queue.get_nowait()
|
|
301
|
-
except queue.Empty:
|
|
302
|
-
break
|
|
303
|
-
with _counters_lock:
|
|
304
|
-
for k in _counters:
|
|
305
|
-
_counters[k] = 0
|
|
306
|
-
_stop_event.clear()
|