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,90 +0,0 @@
|
|
|
1
|
-
"""Process-safe, durable read/modify/write access to ``config.json``."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
import json
|
|
6
|
-
import os
|
|
7
|
-
import tempfile
|
|
8
|
-
import threading
|
|
9
|
-
from contextlib import contextmanager
|
|
10
|
-
from pathlib import Path
|
|
11
|
-
from typing import Callable, Iterator
|
|
12
|
-
|
|
13
|
-
_PROCESS_LOCK = threading.RLock()
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
@contextmanager
|
|
17
|
-
def _file_lock(path: Path) -> Iterator[None]:
|
|
18
|
-
"""Serialize config access across daemon, CLI, and worker processes."""
|
|
19
|
-
lock_path = path.with_name(f".{path.name}.lock")
|
|
20
|
-
lock_path.parent.mkdir(parents=True, exist_ok=True)
|
|
21
|
-
with _PROCESS_LOCK, lock_path.open("a+b") as handle:
|
|
22
|
-
if os.name == "nt":
|
|
23
|
-
import msvcrt
|
|
24
|
-
|
|
25
|
-
handle.seek(0)
|
|
26
|
-
handle.write(b"\0")
|
|
27
|
-
handle.flush()
|
|
28
|
-
handle.seek(0)
|
|
29
|
-
msvcrt.locking(handle.fileno(), msvcrt.LK_LOCK, 1)
|
|
30
|
-
else:
|
|
31
|
-
import fcntl
|
|
32
|
-
|
|
33
|
-
fcntl.flock(handle.fileno(), fcntl.LOCK_EX)
|
|
34
|
-
try:
|
|
35
|
-
yield
|
|
36
|
-
finally:
|
|
37
|
-
if os.name == "nt":
|
|
38
|
-
handle.seek(0)
|
|
39
|
-
msvcrt.locking(handle.fileno(), msvcrt.LK_UNLCK, 1)
|
|
40
|
-
else:
|
|
41
|
-
fcntl.flock(handle.fileno(), fcntl.LOCK_UN)
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
def _read_unlocked(path: Path) -> dict:
|
|
45
|
-
if not path.exists():
|
|
46
|
-
return {}
|
|
47
|
-
value = json.loads(path.read_text(encoding="utf-8"))
|
|
48
|
-
if not isinstance(value, dict):
|
|
49
|
-
raise ValueError("config root must be a JSON object")
|
|
50
|
-
return value
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
def read_config(path: Path) -> dict:
|
|
54
|
-
"""Return one coherent config snapshot under the interprocess lock."""
|
|
55
|
-
with _file_lock(path):
|
|
56
|
-
return _read_unlocked(path)
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
def update_config(path: Path, update: Callable[[dict], None]) -> dict:
|
|
60
|
-
"""Atomically update and durably replace a config JSON object."""
|
|
61
|
-
with _file_lock(path):
|
|
62
|
-
data = _read_unlocked(path)
|
|
63
|
-
update(data)
|
|
64
|
-
path.parent.mkdir(parents=True, exist_ok=True)
|
|
65
|
-
descriptor, temp_name = tempfile.mkstemp(
|
|
66
|
-
prefix=f".{path.name}.",
|
|
67
|
-
suffix=".tmp",
|
|
68
|
-
dir=path.parent,
|
|
69
|
-
)
|
|
70
|
-
temp_path = Path(temp_name)
|
|
71
|
-
try:
|
|
72
|
-
with os.fdopen(descriptor, "w", encoding="utf-8") as stream:
|
|
73
|
-
json.dump(data, stream, indent=2)
|
|
74
|
-
stream.write("\n")
|
|
75
|
-
stream.flush()
|
|
76
|
-
os.fsync(stream.fileno())
|
|
77
|
-
os.chmod(temp_path, 0o600)
|
|
78
|
-
os.replace(temp_path, path)
|
|
79
|
-
if hasattr(os, "O_DIRECTORY"):
|
|
80
|
-
directory_fd = os.open(path.parent, os.O_RDONLY | os.O_DIRECTORY)
|
|
81
|
-
try:
|
|
82
|
-
os.fsync(directory_fd)
|
|
83
|
-
finally:
|
|
84
|
-
os.close(directory_fd)
|
|
85
|
-
finally:
|
|
86
|
-
temp_path.unlink(missing_ok=True)
|
|
87
|
-
return data
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
__all__ = ("read_config", "update_config")
|
|
@@ -1,140 +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 | https://qualixar.com
|
|
4
|
-
|
|
5
|
-
"""One implementation of full consolidation, shared by every trigger.
|
|
6
|
-
|
|
7
|
-
WHY THIS EXISTS
|
|
8
|
-
---------------
|
|
9
|
-
Steps 8-11 of ``ConsolidationEngine.consolidate()`` — behavioural assertion
|
|
10
|
-
mining, soft prompts, skill performance, skill evolution — only run on the
|
|
11
|
-
``lightweight=False`` path. Before 4.0.8 **nothing automatic ever took that
|
|
12
|
-
path**:
|
|
13
|
-
|
|
14
|
-
* ``consolidation_engine.py`` self-triggers with ``lightweight=True`` only.
|
|
15
|
-
* The session-end hook shelled out to ``slm consolidate --cognitive``, which
|
|
16
|
-
runs ``CognitiveConsolidator.run_pipeline()`` — a different class that does
|
|
17
|
-
not contain steps 8-11 at all.
|
|
18
|
-
* ``POST /consolidation/trigger`` did run the full path, but only when a human
|
|
19
|
-
called it.
|
|
20
|
-
|
|
21
|
-
The measurable consequence on a real store: ``behavioral_assertions`` sat at 0
|
|
22
|
-
rows while the miner, run once by hand against the same data, produced 9
|
|
23
|
-
assertions immediately. The Behaviour tab was empty because the miner had never
|
|
24
|
-
executed, not because there was nothing to mine.
|
|
25
|
-
|
|
26
|
-
DESIGN
|
|
27
|
-
------
|
|
28
|
-
Two triggers, one implementation, one lock:
|
|
29
|
-
|
|
30
|
-
* the daemon's periodic timer (the correctness guarantee), and
|
|
31
|
-
* the session-end hook posting to ``/consolidation/trigger`` (the fast path).
|
|
32
|
-
|
|
33
|
-
``_LOCK`` serialises them. A second trigger arriving while one is running is
|
|
34
|
-
**skipped, not queued** — consolidation is idempotent catch-up work, so running
|
|
35
|
-
it twice back to back buys nothing and doubles the write pressure.
|
|
36
|
-
|
|
37
|
-
HOT PATH
|
|
38
|
-
--------
|
|
39
|
-
Never called from store or recall. The engine call is CPU/IO bound for seconds
|
|
40
|
-
to minutes, so it runs inside ``asyncio.to_thread`` — blocking a worker thread
|
|
41
|
-
is fine, blocking the event loop is not. The periodic trigger additionally
|
|
42
|
-
refuses to start unless the daemon has been idle (see ``unified_daemon``), so
|
|
43
|
-
scheduled consolidation cannot land in the middle of a burst of remember/recall
|
|
44
|
-
traffic.
|
|
45
|
-
"""
|
|
46
|
-
|
|
47
|
-
from __future__ import annotations
|
|
48
|
-
|
|
49
|
-
import asyncio
|
|
50
|
-
import logging
|
|
51
|
-
from typing import Any
|
|
52
|
-
|
|
53
|
-
logger = logging.getLogger("superlocalmemory.consolidation_runner")
|
|
54
|
-
|
|
55
|
-
#: Serialises the timer and the hook. Module-level: there is one daemon.
|
|
56
|
-
_LOCK = asyncio.Lock()
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
def is_running() -> bool:
|
|
60
|
-
"""True when a consolidation pass currently holds the lock."""
|
|
61
|
-
return _LOCK.locked()
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
def _consolidate_blocking(app_state: Any, profile_id: str, lightweight: bool) -> dict:
|
|
65
|
-
"""Run the engine synchronously. Caller must put this in a thread.
|
|
66
|
-
|
|
67
|
-
Lifted verbatim from ``POST /consolidation/trigger`` so the endpoint and the
|
|
68
|
-
timer cannot drift apart — two copies of this would be two different
|
|
69
|
-
definitions of "consolidated".
|
|
70
|
-
"""
|
|
71
|
-
from superlocalmemory.core.config import SLMConfig
|
|
72
|
-
from superlocalmemory.core.consolidation_engine import ConsolidationEngine
|
|
73
|
-
from superlocalmemory.server.profile_runtime import get_profile_runtime
|
|
74
|
-
from superlocalmemory.storage import schema as _schema
|
|
75
|
-
from superlocalmemory.storage.database import DatabaseManager
|
|
76
|
-
|
|
77
|
-
runtime = get_profile_runtime(app_state)
|
|
78
|
-
# Rule 18: hold the operation lease so a concurrent profile switch cannot
|
|
79
|
-
# commit halfway through a consolidation.
|
|
80
|
-
with runtime.operation():
|
|
81
|
-
config = SLMConfig.load()
|
|
82
|
-
db = DatabaseManager(config.db_path)
|
|
83
|
-
db.initialize(_schema)
|
|
84
|
-
engine = ConsolidationEngine(
|
|
85
|
-
db=db, config=config.consolidation, slm_config=config,
|
|
86
|
-
)
|
|
87
|
-
res = engine.consolidate(profile_id=profile_id, lightweight=lightweight)
|
|
88
|
-
|
|
89
|
-
# Behavioural pattern mining writes learning.db rather than memory.db, so
|
|
90
|
-
# it sits outside the engine. Kept non-fatal: a pattern-mining failure
|
|
91
|
-
# must not discard a completed consolidation.
|
|
92
|
-
try:
|
|
93
|
-
from superlocalmemory.learning.consolidation_worker import (
|
|
94
|
-
ConsolidationWorker,
|
|
95
|
-
)
|
|
96
|
-
learning_db = config.base_dir / "learning.db"
|
|
97
|
-
cw = ConsolidationWorker(str(config.db_path), str(learning_db))
|
|
98
|
-
res["patterns_mined"] = cw._generate_patterns(profile_id, False)
|
|
99
|
-
except Exception as exc:
|
|
100
|
-
logger.warning("pattern mining after consolidation failed: %s", exc)
|
|
101
|
-
# -1, not 0: "it broke" and "there was nothing to mine" are
|
|
102
|
-
# different answers and the dashboard must not conflate them.
|
|
103
|
-
res["patterns_mined"] = -1
|
|
104
|
-
return res
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
async def run_full_consolidation(
|
|
108
|
-
app_state: Any,
|
|
109
|
-
profile_id: str,
|
|
110
|
-
*,
|
|
111
|
-
lightweight: bool = False,
|
|
112
|
-
trigger: str = "manual",
|
|
113
|
-
) -> dict:
|
|
114
|
-
"""Run one consolidation pass, or skip if one is already in flight.
|
|
115
|
-
|
|
116
|
-
Returns the engine result dict, plus ``trigger``. When a pass is already
|
|
117
|
-
running the result is ``{"skipped": True, "reason": "already running"}`` —
|
|
118
|
-
an explicit skip rather than a silent no-op, so a caller can tell "did not
|
|
119
|
-
need to run" from "ran and found nothing".
|
|
120
|
-
"""
|
|
121
|
-
if _LOCK.locked():
|
|
122
|
-
logger.info("consolidation skipped (%s): a pass is already running", trigger)
|
|
123
|
-
return {"skipped": True, "reason": "already running", "trigger": trigger}
|
|
124
|
-
|
|
125
|
-
async with _LOCK:
|
|
126
|
-
logger.info(
|
|
127
|
-
"consolidation starting (trigger=%s, profile=%s, lightweight=%s)",
|
|
128
|
-
trigger, profile_id, lightweight,
|
|
129
|
-
)
|
|
130
|
-
result = await asyncio.to_thread(
|
|
131
|
-
_consolidate_blocking, app_state, profile_id, lightweight,
|
|
132
|
-
)
|
|
133
|
-
logger.info(
|
|
134
|
-
"consolidation finished (trigger=%s): assertions=%s patterns=%s",
|
|
135
|
-
trigger,
|
|
136
|
-
(result.get("assertions") or {}).get("created", "n/a"),
|
|
137
|
-
result.get("patterns_mined", "n/a"),
|
|
138
|
-
)
|
|
139
|
-
result["trigger"] = trigger
|
|
140
|
-
return result
|
|
@@ -1,258 +0,0 @@
|
|
|
1
|
-
"""SSRF-safe egress validation for outbound provider requests.
|
|
2
|
-
|
|
3
|
-
Pre-admission, stateless validation for outbound HTTP fetches (embedding test,
|
|
4
|
-
provider test, local model probe). It enforces three protections:
|
|
5
|
-
|
|
6
|
-
* Cloud-metadata endpoints are blocked unconditionally and after hostname
|
|
7
|
-
normalization (trailing dot / case / IDNA), so ``metadata.google.internal.``
|
|
8
|
-
cannot slip past — including on the loopback path.
|
|
9
|
-
* The full DNS answer set is validated (all A/AAAA records), not just the first
|
|
10
|
-
resolved address, which defeats mixed public/private answers (DNS rebinding).
|
|
11
|
-
* DNS resolution failure fails closed (deny) for untrusted callers rather than
|
|
12
|
-
deferring the decision to the HTTP client.
|
|
13
|
-
|
|
14
|
-
Trusted callers (the local dashboard on loopback, or an allowlisted LAN
|
|
15
|
-
dashboard) keep the latitude to probe local/LAN model endpoints; metadata
|
|
16
|
-
endpoints are denied for everyone.
|
|
17
|
-
"""
|
|
18
|
-
from __future__ import annotations
|
|
19
|
-
|
|
20
|
-
import ipaddress
|
|
21
|
-
import socket
|
|
22
|
-
from dataclasses import dataclass
|
|
23
|
-
from enum import Enum
|
|
24
|
-
from urllib.parse import urlparse
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
class EgressVerdict(str, Enum):
|
|
28
|
-
ALLOW = "allow"
|
|
29
|
-
DENY_SCHEME = "deny_scheme"
|
|
30
|
-
DENY_CREDENTIALS = "deny_credentials"
|
|
31
|
-
DENY_FRAGMENT = "deny_fragment"
|
|
32
|
-
DENY_HOST = "deny_host"
|
|
33
|
-
DENY_METADATA = "deny_metadata"
|
|
34
|
-
DENY_PRIVATE = "deny_private"
|
|
35
|
-
DENY_DNS_FAILURE = "deny_dns_failure"
|
|
36
|
-
DENY_MIXED_DNS = "deny_mixed_dns"
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
# Cloud metadata endpoints — always blocked regardless of caller trust.
|
|
40
|
-
METADATA_HOSTS: frozenset[str] = frozenset(
|
|
41
|
-
{
|
|
42
|
-
"169.254.169.254",
|
|
43
|
-
"metadata.google.internal",
|
|
44
|
-
"metadata",
|
|
45
|
-
"metadata.azure.internal",
|
|
46
|
-
"169.254.170.2", # AWS ECS task metadata
|
|
47
|
-
"fd00:ec2::254", # AWS IMDS over IPv6
|
|
48
|
-
}
|
|
49
|
-
)
|
|
50
|
-
|
|
51
|
-
_ALLOWED_SCHEMES: frozenset[str] = frozenset({"http", "https"})
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
@dataclass(frozen=True, slots=True)
|
|
55
|
-
class EgressPolicy:
|
|
56
|
-
"""Configurable egress constraints (safe defaults)."""
|
|
57
|
-
|
|
58
|
-
allowed_schemes: frozenset[str] = _ALLOWED_SCHEMES
|
|
59
|
-
allow_private_for_local_actor: bool = True
|
|
60
|
-
allow_private_for_lan_actor: bool = True
|
|
61
|
-
reject_credentials: bool = True
|
|
62
|
-
reject_fragment: bool = True
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
@dataclass(frozen=True, slots=True)
|
|
66
|
-
class EgressActor:
|
|
67
|
-
"""Minimal trust descriptor for the caller.
|
|
68
|
-
|
|
69
|
-
``is_local`` — request originated from the loopback dashboard.
|
|
70
|
-
``is_lan`` — request originated from an allowlisted LAN dashboard
|
|
71
|
-
(remote mode ON *and* client IP in the allowlist).
|
|
72
|
-
A caller with neither flag is an untrusted/remote caller.
|
|
73
|
-
"""
|
|
74
|
-
|
|
75
|
-
is_local: bool = False
|
|
76
|
-
is_lan: bool = False
|
|
77
|
-
|
|
78
|
-
@property
|
|
79
|
-
def is_trusted(self) -> bool:
|
|
80
|
-
return self.is_local or self.is_lan
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
@dataclass(frozen=True, slots=True)
|
|
84
|
-
class ResolvedTarget:
|
|
85
|
-
addresses: tuple[str, ...] = ()
|
|
86
|
-
has_private: bool = False
|
|
87
|
-
has_public: bool = False
|
|
88
|
-
error: str = ""
|
|
89
|
-
|
|
90
|
-
@property
|
|
91
|
-
def is_mixed(self) -> bool:
|
|
92
|
-
return self.has_private and self.has_public
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
@dataclass(frozen=True, slots=True)
|
|
96
|
-
class EgressResult:
|
|
97
|
-
verdict: EgressVerdict
|
|
98
|
-
resolved_ip: str = ""
|
|
99
|
-
error: str = ""
|
|
100
|
-
hostname: str = ""
|
|
101
|
-
|
|
102
|
-
@property
|
|
103
|
-
def allowed(self) -> bool:
|
|
104
|
-
return self.verdict is EgressVerdict.ALLOW
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
def _normalize_host(hostname: str) -> str:
|
|
108
|
-
"""Lowercase, strip a trailing dot, IDNA-encode non-ASCII hosts.
|
|
109
|
-
|
|
110
|
-
IDNA encoding is only attempted for hosts containing non-ASCII characters,
|
|
111
|
-
so IP literals and ordinary ASCII hostnames are left untouched (the ``idna``
|
|
112
|
-
codec rejects some all-ASCII inputs).
|
|
113
|
-
"""
|
|
114
|
-
host = hostname.strip().lower().rstrip(".")
|
|
115
|
-
if host and any(ord(ch) > 127 for ch in host):
|
|
116
|
-
try:
|
|
117
|
-
host = host.encode("idna").decode("ascii")
|
|
118
|
-
except (UnicodeError, UnicodeDecodeError):
|
|
119
|
-
pass # keep the raw host — classification below still applies
|
|
120
|
-
return host
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
def _is_dangerous_ip(
|
|
124
|
-
addr: ipaddress.IPv4Address | ipaddress.IPv6Address,
|
|
125
|
-
) -> bool:
|
|
126
|
-
return (
|
|
127
|
-
addr.is_private
|
|
128
|
-
or addr.is_loopback
|
|
129
|
-
or addr.is_link_local
|
|
130
|
-
or addr.is_reserved
|
|
131
|
-
or addr.is_multicast
|
|
132
|
-
or addr.is_unspecified
|
|
133
|
-
)
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
def _coerce_ip(
|
|
137
|
-
ip_str: str,
|
|
138
|
-
) -> ipaddress.IPv4Address | ipaddress.IPv6Address | None:
|
|
139
|
-
try:
|
|
140
|
-
addr = ipaddress.ip_address(ip_str)
|
|
141
|
-
except ValueError:
|
|
142
|
-
return None
|
|
143
|
-
# Unwrap IPv4-mapped IPv6 (``::ffff:127.0.0.1``) before classification.
|
|
144
|
-
if isinstance(addr, ipaddress.IPv6Address) and addr.ipv4_mapped:
|
|
145
|
-
return addr.ipv4_mapped
|
|
146
|
-
return addr
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
def resolve_and_validate_dns(
|
|
150
|
-
hostname: str, policy: EgressPolicy = EgressPolicy()
|
|
151
|
-
) -> ResolvedTarget:
|
|
152
|
-
"""Resolve every A/AAAA record and classify each address.
|
|
153
|
-
|
|
154
|
-
Fails closed: any resolution error, or an empty answer set, returns a
|
|
155
|
-
``ResolvedTarget`` carrying a non-empty ``error``.
|
|
156
|
-
"""
|
|
157
|
-
try:
|
|
158
|
-
infos = socket.getaddrinfo(
|
|
159
|
-
hostname, None, socket.AF_UNSPEC, socket.SOCK_STREAM
|
|
160
|
-
)
|
|
161
|
-
except (socket.gaierror, OSError, UnicodeError) as exc:
|
|
162
|
-
return ResolvedTarget(error=f"dns resolution failed: {exc}")
|
|
163
|
-
|
|
164
|
-
addresses: list[str] = []
|
|
165
|
-
has_private = False
|
|
166
|
-
has_public = False
|
|
167
|
-
for info in infos:
|
|
168
|
-
sockaddr = info[4]
|
|
169
|
-
addr = _coerce_ip(sockaddr[0])
|
|
170
|
-
if addr is None:
|
|
171
|
-
continue
|
|
172
|
-
addresses.append(str(addr))
|
|
173
|
-
if _is_dangerous_ip(addr):
|
|
174
|
-
has_private = True
|
|
175
|
-
else:
|
|
176
|
-
has_public = True
|
|
177
|
-
|
|
178
|
-
if not addresses:
|
|
179
|
-
return ResolvedTarget(error="no addresses resolved")
|
|
180
|
-
return ResolvedTarget(
|
|
181
|
-
addresses=tuple(addresses),
|
|
182
|
-
has_private=has_private,
|
|
183
|
-
has_public=has_public,
|
|
184
|
-
)
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
def validate_egress_url(
|
|
188
|
-
url: str,
|
|
189
|
-
actor: EgressActor = EgressActor(),
|
|
190
|
-
policy: EgressPolicy = EgressPolicy(),
|
|
191
|
-
) -> EgressResult:
|
|
192
|
-
"""Full SSRF-safe validation of an outbound URL for a given caller."""
|
|
193
|
-
parsed = urlparse(url)
|
|
194
|
-
|
|
195
|
-
if parsed.scheme not in policy.allowed_schemes:
|
|
196
|
-
return EgressResult(
|
|
197
|
-
verdict=EgressVerdict.DENY_SCHEME, error=f"scheme {parsed.scheme!r}"
|
|
198
|
-
)
|
|
199
|
-
if policy.reject_credentials and (parsed.username or parsed.password):
|
|
200
|
-
return EgressResult(verdict=EgressVerdict.DENY_CREDENTIALS)
|
|
201
|
-
if policy.reject_fragment and parsed.fragment:
|
|
202
|
-
return EgressResult(verdict=EgressVerdict.DENY_FRAGMENT)
|
|
203
|
-
|
|
204
|
-
hostname = _normalize_host(parsed.hostname or "")
|
|
205
|
-
if not hostname:
|
|
206
|
-
return EgressResult(verdict=EgressVerdict.DENY_HOST, error="empty host")
|
|
207
|
-
|
|
208
|
-
# Metadata block — unconditional, before any trust short-circuit or DNS
|
|
209
|
-
# (defeats the trailing-dot / loopback-path bypass and DNS rebinding).
|
|
210
|
-
if hostname in METADATA_HOSTS:
|
|
211
|
-
return EgressResult(verdict=EgressVerdict.DENY_METADATA, hostname=hostname)
|
|
212
|
-
literal = _coerce_ip(hostname)
|
|
213
|
-
if literal is not None and str(literal) in METADATA_HOSTS:
|
|
214
|
-
return EgressResult(verdict=EgressVerdict.DENY_METADATA, hostname=hostname)
|
|
215
|
-
|
|
216
|
-
trusted = (
|
|
217
|
-
actor.is_local and policy.allow_private_for_local_actor
|
|
218
|
-
) or (actor.is_lan and policy.allow_private_for_lan_actor)
|
|
219
|
-
|
|
220
|
-
# Literal IP target: classify directly, no DNS needed.
|
|
221
|
-
if literal is not None:
|
|
222
|
-
if _is_dangerous_ip(literal) and not trusted:
|
|
223
|
-
return EgressResult(
|
|
224
|
-
verdict=EgressVerdict.DENY_PRIVATE,
|
|
225
|
-
resolved_ip=str(literal),
|
|
226
|
-
hostname=hostname,
|
|
227
|
-
)
|
|
228
|
-
return EgressResult(
|
|
229
|
-
verdict=EgressVerdict.ALLOW, resolved_ip=str(literal), hostname=hostname
|
|
230
|
-
)
|
|
231
|
-
|
|
232
|
-
# Trusted callers may probe local/LAN endpoints by name without a forced
|
|
233
|
-
# DNS lookup — preserving pre-V4 loopback/LAN dashboard behaviour. Metadata
|
|
234
|
-
# was already denied above for everyone.
|
|
235
|
-
if trusted:
|
|
236
|
-
return EgressResult(verdict=EgressVerdict.ALLOW, hostname=hostname)
|
|
237
|
-
|
|
238
|
-
# Untrusted caller: resolve the full answer set and fail closed on error.
|
|
239
|
-
resolved = resolve_and_validate_dns(hostname, policy)
|
|
240
|
-
if resolved.error:
|
|
241
|
-
return EgressResult(
|
|
242
|
-
verdict=EgressVerdict.DENY_DNS_FAILURE,
|
|
243
|
-
error=resolved.error,
|
|
244
|
-
hostname=hostname,
|
|
245
|
-
)
|
|
246
|
-
if resolved.has_private:
|
|
247
|
-
verdict = (
|
|
248
|
-
EgressVerdict.DENY_MIXED_DNS
|
|
249
|
-
if resolved.is_mixed
|
|
250
|
-
else EgressVerdict.DENY_PRIVATE
|
|
251
|
-
)
|
|
252
|
-
return EgressResult(verdict=verdict, hostname=hostname)
|
|
253
|
-
|
|
254
|
-
return EgressResult(
|
|
255
|
-
verdict=EgressVerdict.ALLOW,
|
|
256
|
-
resolved_ip=resolved.addresses[0],
|
|
257
|
-
hostname=hostname,
|
|
258
|
-
)
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
|
|
2
|
-
# Licensed under AGPL-3.0-or-later
|
|
3
|
-
|
|
4
|
-
"""Centralized loopback-address predicate for the SLM server.
|
|
5
|
-
|
|
6
|
-
Replaces every ``frozenset({"127.0.0.1", "::1", "localhost"})`` auth check
|
|
7
|
-
with a semantic helper that correctly handles IPv4-mapped IPv6 addresses
|
|
8
|
-
(``::ffff:127.0.0.1``) — the root cause of issue #90.
|
|
9
|
-
|
|
10
|
-
Issue #90 root cause
|
|
11
|
-
--------------------
|
|
12
|
-
When the daemon is started with ``SLM_DAEMON_HOST=0.0.0.0`` on a dual-stack
|
|
13
|
-
Linux host (common in LXC/Docker containers), the OS creates an IPv6 socket
|
|
14
|
-
that accepts IPv4 connections via the IPv4-mapped IPv6 address mechanism
|
|
15
|
-
(RFC 4291 §2.5.5.2). A client connecting to ``localhost`` on such a host
|
|
16
|
-
may have its peer address reported as ``::ffff:127.0.0.1`` by
|
|
17
|
-
uvicorn/Starlette. The literal set ``("127.0.0.1", "::1", "localhost")``
|
|
18
|
-
does not include this form, causing a spurious 403 for install-token and
|
|
19
|
-
uncredentialed-loopback callers.
|
|
20
|
-
|
|
21
|
-
``ipaddress.ip_address("::ffff:127.0.0.1").is_loopback`` already returns
|
|
22
|
-
``True`` in CPython. This module uses that fact.
|
|
23
|
-
|
|
24
|
-
SECURITY INVARIANTS (non-negotiable):
|
|
25
|
-
- Empty/None host → False. SEC-L-02: a missing peer is never trusted.
|
|
26
|
-
- No proxy header trust. Callers MUST pass ``request.client.host`` only,
|
|
27
|
-
never X-Forwarded-For or any other spoofable header.
|
|
28
|
-
- All 127.0.0.0/8 is loopback per RFC 5735 (includes 127.0.0.2, etc.).
|
|
29
|
-
- ``"localhost"`` is accepted as a hostname alias. Callers that need the
|
|
30
|
-
stricter no-hostname check (``prewarm_auth``) keep their own predicate.
|
|
31
|
-
- ``"testclient"`` is NOT in the loopback set — that bypass must be wired
|
|
32
|
-
explicitly alongside ``_TEST_ISOLATION_ALLOWED`` so it cannot appear in
|
|
33
|
-
production paths.
|
|
34
|
-
- ``"0.0.0.0"`` is NOT loopback — it is a bind address, not a peer address.
|
|
35
|
-
"""
|
|
36
|
-
|
|
37
|
-
from __future__ import annotations
|
|
38
|
-
|
|
39
|
-
import ipaddress as _ipa
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
def is_loopback(host: str) -> bool:
|
|
43
|
-
"""Return ``True`` iff ``host`` is a loopback address in any standard form.
|
|
44
|
-
|
|
45
|
-
Handles:
|
|
46
|
-
* ``"127.0.0.1"`` and the full 127.0.0.0/8 range (RFC 5735).
|
|
47
|
-
* ``"::1"`` (IPv6 loopback).
|
|
48
|
-
* ``"::ffff:127.0.0.1"`` and all ``::ffff:127.x.x.x`` (IPv4-mapped IPv6,
|
|
49
|
-
fixes issue #90).
|
|
50
|
-
* ``"localhost"`` (hostname alias, case-insensitive).
|
|
51
|
-
|
|
52
|
-
Returns ``False`` for:
|
|
53
|
-
* Empty string or ``None`` (SEC-L-02: missing peer is never trusted).
|
|
54
|
-
* Any non-loopback IP (192.168.x.x, 10.x.x.x, public IPs, etc.).
|
|
55
|
-
* ``"::ffff:192.168.x.x"`` and other IPv4-mapped non-loopback addresses.
|
|
56
|
-
* ``"testclient"`` — callers that need the test-client exemption must
|
|
57
|
-
wire it explicitly alongside ``_TEST_ISOLATION_ALLOWED``.
|
|
58
|
-
* ``"0.0.0.0"`` — bind address, not a peer address.
|
|
59
|
-
|
|
60
|
-
Args:
|
|
61
|
-
host: The ``request.client.host`` string from an incoming HTTP
|
|
62
|
-
request. Must be the TCP-observed peer address only.
|
|
63
|
-
|
|
64
|
-
Returns:
|
|
65
|
-
``True`` if the host is any recognised loopback form; ``False``
|
|
66
|
-
otherwise.
|
|
67
|
-
"""
|
|
68
|
-
if not isinstance(host, str) or not host:
|
|
69
|
-
return False # SEC-L-02
|
|
70
|
-
if host.lower() == "localhost":
|
|
71
|
-
return True
|
|
72
|
-
try:
|
|
73
|
-
ip = _ipa.ip_address(host)
|
|
74
|
-
except ValueError:
|
|
75
|
-
return False
|
|
76
|
-
if ip.is_loopback:
|
|
77
|
-
return True
|
|
78
|
-
# CPython's handling of IPv4-mapped IPv6 changed across supported
|
|
79
|
-
# runtimes. Normalize through the embedded IPv4 address so a dual-stack
|
|
80
|
-
# socket reporting ::ffff:127.x.x.x retains the equivalent IPv4 decision.
|
|
81
|
-
mapped_ipv4 = getattr(ip, "ipv4_mapped", None)
|
|
82
|
-
return bool(mapped_ipv4 is not None and mapped_ipv4.is_loopback)
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
__all__ = ("is_loopback",)
|
|
@@ -1,11 +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-04 §4.2
|
|
4
|
-
|
|
5
|
-
"""FastAPI middleware — strict security headers for the Brain UI (LLD-04 v2).
|
|
6
|
-
|
|
7
|
-
The existing ``server/security_middleware.py`` is kept for legacy routes
|
|
8
|
-
that still rely on permissive CSP (``'unsafe-inline'`` + CDNs). The
|
|
9
|
-
middleware in this subpackage enforces the v3.4.22 policy: no inline
|
|
10
|
-
scripts / styles, no nonces, no CDN sources.
|
|
11
|
-
"""
|