superlocalmemory 4.1.13 → 4.1.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +2 -2
- package/CHANGELOG.md +48 -0
- package/README.md +3 -3
- package/package.json +1 -8
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/CLAUDE.md +3 -3
- package/plugin/agents/slm-governance-advisor.md +1 -1
- package/plugin/agents/slm-loop-runner.md +1 -1
- package/plugin/agents/slm-memory-advisor.md +1 -1
- package/plugin/agents/slm-optimize-advisor.md +1 -1
- package/plugin/requirements.txt +1 -1
- package/plugin/skills/slm-cache/SKILL.md +1 -1
- package/plugin/skills/slm-compress/SKILL.md +1 -1
- package/plugin/skills/slm-governance/SKILL.md +1 -1
- package/plugin/skills/slm-graph/SKILL.md +1 -1
- package/plugin/skills/slm-loop/SKILL.md +1 -1
- package/plugin/skills/slm-mesh/SKILL.md +1 -1
- package/plugin/skills/slm-profile/SKILL.md +1 -1
- package/plugin/skills/slm-recall/SKILL.md +1 -1
- package/plugin/skills/slm-remember/SKILL.md +1 -1
- package/plugin/skills/slm-scope/SKILL.md +1 -1
- package/plugin/skills/slm-session/SKILL.md +1 -1
- package/plugin/skills/slm-status/SKILL.md +1 -1
- package/plugin-src/agents/slm-memory-advisor.md +1 -1
- package/plugin-src/agents/slm-optimize-advisor.md +1 -1
- package/plugin-src/rules/AGENTS.md +1 -1
- package/plugin-src/skills/slm-cache/SKILL.md +1 -1
- package/plugin-src/skills/slm-compress/SKILL.md +1 -1
- package/plugin-src/skills/slm-governance/SKILL.md +1 -1
- package/plugin-src/skills/slm-graph/SKILL.md +1 -1
- package/plugin-src/skills/slm-loop/SKILL.md +1 -1
- package/plugin-src/skills/slm-mesh/SKILL.md +1 -1
- package/plugin-src/skills/slm-profile/SKILL.md +1 -1
- package/plugin-src/skills/slm-recall/SKILL.md +1 -1
- package/plugin-src/skills/slm-remember/SKILL.md +1 -1
- package/plugin-src/skills/slm-scope/SKILL.md +1 -1
- package/plugin-src/skills/slm-session/SKILL.md +1 -1
- package/plugin-src/skills/slm-status/SKILL.md +1 -1
- package/scripts/postinstall.js +71 -2
- package/pyproject.toml +0 -250
- package/src/superlocalmemory/__init__.py +0 -82
- package/src/superlocalmemory/access/__init__.py +0 -3
- package/src/superlocalmemory/access/rbac.py +0 -575
- package/src/superlocalmemory/attribution/__init__.py +0 -9
- package/src/superlocalmemory/attribution/signer.py +0 -173
- package/src/superlocalmemory/attribution/watermark.py +0 -189
- package/src/superlocalmemory/brain/__init__.py +0 -5
- package/src/superlocalmemory/brain/truth.py +0 -418
- package/src/superlocalmemory/cli/__init__.py +0 -5
- package/src/superlocalmemory/cli/__main__.py +0 -17
- package/src/superlocalmemory/cli/_lazy_init.py +0 -115
- package/src/superlocalmemory/cli/cache_cmd.py +0 -198
- package/src/superlocalmemory/cli/commands.py +0 -4710
- package/src/superlocalmemory/cli/compress_cmd.py +0 -151
- package/src/superlocalmemory/cli/context_commands.py +0 -193
- package/src/superlocalmemory/cli/daemon.py +0 -909
- package/src/superlocalmemory/cli/db_migrate.py +0 -150
- package/src/superlocalmemory/cli/diagnostics_cmd.py +0 -101
- package/src/superlocalmemory/cli/escape_hatch.py +0 -220
- package/src/superlocalmemory/cli/evidence_cmd.py +0 -103
- package/src/superlocalmemory/cli/gdpr_cmd.py +0 -792
- package/src/superlocalmemory/cli/gdpr_io.py +0 -109
- package/src/superlocalmemory/cli/help_cmd.py +0 -197
- package/src/superlocalmemory/cli/host_upgrades.py +0 -189
- package/src/superlocalmemory/cli/ingest_cmd.py +0 -327
- package/src/superlocalmemory/cli/json_output.py +0 -81
- package/src/superlocalmemory/cli/loop_cmd.py +0 -187
- package/src/superlocalmemory/cli/main.py +0 -1145
- package/src/superlocalmemory/cli/mesh_cmd.py +0 -38
- package/src/superlocalmemory/cli/migrate_cmd.py +0 -55
- package/src/superlocalmemory/cli/ops_cmd.py +0 -281
- package/src/superlocalmemory/cli/optimize_cmd.py +0 -179
- package/src/superlocalmemory/cli/optimize_constants.py +0 -31
- package/src/superlocalmemory/cli/pending_store.py +0 -296
- package/src/superlocalmemory/cli/proxy_cmd.py +0 -108
- package/src/superlocalmemory/cli/scale_engine_cmd.py +0 -56
- package/src/superlocalmemory/cli/service_installer.py +0 -373
- package/src/superlocalmemory/cli/setup_wizard.py +0 -1162
- package/src/superlocalmemory/cli/summary_cmd.py +0 -215
- package/src/superlocalmemory/cli/version_banner.py +0 -202
- package/src/superlocalmemory/cli/wizard_v3426_options.py +0 -129
- package/src/superlocalmemory/code_graph/__init__.py +0 -46
- package/src/superlocalmemory/code_graph/blast_radius.py +0 -177
- package/src/superlocalmemory/code_graph/bridge/__init__.py +0 -36
- package/src/superlocalmemory/code_graph/bridge/entity_resolver.py +0 -490
- package/src/superlocalmemory/code_graph/bridge/event_listeners.py +0 -206
- package/src/superlocalmemory/code_graph/bridge/fact_enricher.py +0 -159
- package/src/superlocalmemory/code_graph/bridge/hebbian_linker.py +0 -170
- package/src/superlocalmemory/code_graph/bridge/maintenance.py +0 -220
- package/src/superlocalmemory/code_graph/bridge/temporal_checker.py +0 -152
- package/src/superlocalmemory/code_graph/changes.py +0 -363
- package/src/superlocalmemory/code_graph/communities.py +0 -299
- package/src/superlocalmemory/code_graph/config.py +0 -154
- package/src/superlocalmemory/code_graph/database.py +0 -526
- package/src/superlocalmemory/code_graph/extractors/__init__.py +0 -95
- package/src/superlocalmemory/code_graph/extractors/python.py +0 -413
- package/src/superlocalmemory/code_graph/extractors/typescript.py +0 -556
- package/src/superlocalmemory/code_graph/flows.py +0 -350
- package/src/superlocalmemory/code_graph/git_hooks.py +0 -226
- package/src/superlocalmemory/code_graph/graph_engine.py +0 -295
- package/src/superlocalmemory/code_graph/graph_store.py +0 -335
- package/src/superlocalmemory/code_graph/incremental.py +0 -200
- package/src/superlocalmemory/code_graph/models.py +0 -130
- package/src/superlocalmemory/code_graph/parser.py +0 -687
- package/src/superlocalmemory/code_graph/resolver.py +0 -321
- package/src/superlocalmemory/code_graph/search.py +0 -460
- package/src/superlocalmemory/code_graph/service.py +0 -95
- package/src/superlocalmemory/code_graph/watcher.py +0 -207
- package/src/superlocalmemory/compliance/__init__.py +0 -0
- package/src/superlocalmemory/compliance/abac.py +0 -204
- package/src/superlocalmemory/compliance/audit.py +0 -385
- package/src/superlocalmemory/compliance/eu_ai_act.py +0 -101
- package/src/superlocalmemory/compliance/gdpr.py +0 -1479
- package/src/superlocalmemory/compliance/lifecycle.py +0 -158
- package/src/superlocalmemory/compliance/retention.py +0 -415
- package/src/superlocalmemory/compliance/scheduler.py +0 -217
- package/src/superlocalmemory/contracts/__init__.py +0 -1
- package/src/superlocalmemory/contracts/schemas/agent-experience-v1.schema.json +0 -92
- package/src/superlocalmemory/contracts/schemas/agent-integration-contract-v2.schema.json +0 -46
- package/src/superlocalmemory/contracts/schemas/cognitive-turn-receipt-v1.schema.json +0 -59
- package/src/superlocalmemory/contracts/v402.py +0 -62
- package/src/superlocalmemory/core/__init__.py +0 -0
- package/src/superlocalmemory/core/actor_context.py +0 -166
- package/src/superlocalmemory/core/admission.py +0 -769
- package/src/superlocalmemory/core/backend_orchestrator.py +0 -637
- package/src/superlocalmemory/core/block_hygiene.py +0 -147
- package/src/superlocalmemory/core/community_summary.py +0 -267
- package/src/superlocalmemory/core/component_healer.py +0 -144
- package/src/superlocalmemory/core/component_registry.py +0 -514
- package/src/superlocalmemory/core/config.py +0 -2204
- package/src/superlocalmemory/core/consolidation_engine.py +0 -983
- package/src/superlocalmemory/core/context_cache.py +0 -574
- package/src/superlocalmemory/core/derivation_lineage.py +0 -246
- package/src/superlocalmemory/core/embedding_worker.py +0 -208
- package/src/superlocalmemory/core/embeddings.py +0 -1052
- package/src/superlocalmemory/core/engine.py +0 -1395
- package/src/superlocalmemory/core/engine_capabilities.py +0 -24
- package/src/superlocalmemory/core/engine_ingestion.py +0 -983
- package/src/superlocalmemory/core/engine_lock.py +0 -75
- package/src/superlocalmemory/core/engine_wiring.py +0 -776
- package/src/superlocalmemory/core/entity_community.py +0 -178
- package/src/superlocalmemory/core/error_envelope.py +0 -60
- package/src/superlocalmemory/core/evidence_bundle.py +0 -528
- package/src/superlocalmemory/core/fact_consolidator.py +0 -812
- package/src/superlocalmemory/core/file_lock.py +0 -92
- package/src/superlocalmemory/core/graph_analyzer.py +0 -456
- package/src/superlocalmemory/core/graph_metrics.py +0 -597
- package/src/superlocalmemory/core/graph_pruner.py +0 -939
- package/src/superlocalmemory/core/health_monitor.py +0 -338
- package/src/superlocalmemory/core/hooks.py +0 -65
- package/src/superlocalmemory/core/ingest_gate.py +0 -133
- package/src/superlocalmemory/core/ingest_policy.py +0 -38
- package/src/superlocalmemory/core/ingestion_command.py +0 -1042
- package/src/superlocalmemory/core/injection.py +0 -434
- package/src/superlocalmemory/core/install_detector.py +0 -131
- package/src/superlocalmemory/core/key_expander.py +0 -138
- package/src/superlocalmemory/core/lifecycle_state.py +0 -153
- package/src/superlocalmemory/core/maintenance.py +0 -777
- package/src/superlocalmemory/core/maintenance_scheduler.py +0 -507
- package/src/superlocalmemory/core/materialization_control.py +0 -20
- package/src/superlocalmemory/core/mcp_embedder_proxy.py +0 -89
- package/src/superlocalmemory/core/memory_health.py +0 -266
- package/src/superlocalmemory/core/mode_capability.py +0 -111
- package/src/superlocalmemory/core/modes.py +0 -168
- package/src/superlocalmemory/core/mutations.py +0 -688
- package/src/superlocalmemory/core/ollama_embedder.py +0 -266
- package/src/superlocalmemory/core/ollama_validator.py +0 -315
- package/src/superlocalmemory/core/operation_policy.py +0 -92
- package/src/superlocalmemory/core/operation_policy_registry.py +0 -542
- package/src/superlocalmemory/core/operation_request.py +0 -127
- package/src/superlocalmemory/core/ops_remediation.py +0 -542
- package/src/superlocalmemory/core/pii.py +0 -105
- package/src/superlocalmemory/core/platform_utils.py +0 -138
- package/src/superlocalmemory/core/profiles.py +0 -234
- package/src/superlocalmemory/core/progressive_abstraction.py +0 -208
- package/src/superlocalmemory/core/projection_drain.py +0 -380
- package/src/superlocalmemory/core/queue_consumer.py +0 -168
- package/src/superlocalmemory/core/ram_lock.py +0 -160
- package/src/superlocalmemory/core/rate_limit.py +0 -151
- package/src/superlocalmemory/core/recall_gate.py +0 -95
- package/src/superlocalmemory/core/recall_pipeline.py +0 -1337
- package/src/superlocalmemory/core/recall_queue.py +0 -377
- package/src/superlocalmemory/core/recall_worker.py +0 -414
- package/src/superlocalmemory/core/registry.py +0 -121
- package/src/superlocalmemory/core/remember_admission.py +0 -161
- package/src/superlocalmemory/core/remember_runtime.py +0 -1190
- package/src/superlocalmemory/core/remote_mode.py +0 -214
- package/src/superlocalmemory/core/reranker_worker.py +0 -338
- package/src/superlocalmemory/core/safe_fs.py +0 -108
- package/src/superlocalmemory/core/scale_autopromote.py +0 -196
- package/src/superlocalmemory/core/scale_engine.py +0 -915
- package/src/superlocalmemory/core/score_contract.py +0 -82
- package/src/superlocalmemory/core/security_primitives.py +0 -672
- package/src/superlocalmemory/core/session_identity.py +0 -98
- package/src/superlocalmemory/core/shadow_router.py +0 -319
- package/src/superlocalmemory/core/slm_disabled.py +0 -85
- package/src/superlocalmemory/core/status_contract.py +0 -108
- package/src/superlocalmemory/core/store_pipeline.py +0 -1404
- package/src/superlocalmemory/core/summarizer.py +0 -200
- package/src/superlocalmemory/core/tier_manager.py +0 -461
- package/src/superlocalmemory/core/topic_signature.py +0 -156
- package/src/superlocalmemory/core/transactions/__init__.py +0 -78
- package/src/superlocalmemory/core/transactions/concrete_owners.py +0 -604
- package/src/superlocalmemory/core/transactions/erasure.py +0 -825
- package/src/superlocalmemory/core/transactions/manifest.py +0 -255
- package/src/superlocalmemory/core/transactions/manifest_key.py +0 -155
- package/src/superlocalmemory/core/transactions/obligations.py +0 -272
- package/src/superlocalmemory/core/transactions/owners.py +0 -114
- package/src/superlocalmemory/core/transactions/reconciler.py +0 -285
- package/src/superlocalmemory/core/transactions/service.py +0 -330
- package/src/superlocalmemory/core/worker_pool.py +0 -377
- package/src/superlocalmemory/core/working_memory.py +0 -288
- package/src/superlocalmemory/dynamics/__init__.py +0 -0
- package/src/superlocalmemory/dynamics/activation_guided_quantization.py +0 -374
- package/src/superlocalmemory/dynamics/eap_scheduler.py +0 -294
- package/src/superlocalmemory/dynamics/ebbinghaus_langevin_coupling.py +0 -171
- package/src/superlocalmemory/dynamics/fisher_langevin_coupling.py +0 -227
- package/src/superlocalmemory/encoding/__init__.py +0 -0
- package/src/superlocalmemory/encoding/auto_linker.py +0 -308
- package/src/superlocalmemory/encoding/cognitive_consolidator.py +0 -899
- package/src/superlocalmemory/encoding/consolidator.py +0 -472
- package/src/superlocalmemory/encoding/context_generator.py +0 -175
- package/src/superlocalmemory/encoding/emotional.py +0 -189
- package/src/superlocalmemory/encoding/entity_reflexion.py +0 -200
- package/src/superlocalmemory/encoding/entity_resolver.py +0 -687
- package/src/superlocalmemory/encoding/entropy_gate.py +0 -101
- package/src/superlocalmemory/encoding/fact_extractor.py +0 -877
- package/src/superlocalmemory/encoding/foresight.py +0 -93
- package/src/superlocalmemory/encoding/graph_builder.py +0 -346
- package/src/superlocalmemory/encoding/observation_builder.py +0 -177
- package/src/superlocalmemory/encoding/prospective_markers.py +0 -262
- package/src/superlocalmemory/encoding/scene_builder.py +0 -410
- package/src/superlocalmemory/encoding/signal_inference.py +0 -90
- package/src/superlocalmemory/encoding/temporal_parser.py +0 -432
- package/src/superlocalmemory/encoding/temporal_validator.py +0 -572
- package/src/superlocalmemory/encoding/type_router.py +0 -237
- package/src/superlocalmemory/evaluation/__init__.py +0 -13
- package/src/superlocalmemory/evaluation/calibration.py +0 -308
- package/src/superlocalmemory/evolution/__init__.py +0 -29
- package/src/superlocalmemory/evolution/blind_verifier.py +0 -122
- package/src/superlocalmemory/evolution/budget.py +0 -356
- package/src/superlocalmemory/evolution/evolution_store.py +0 -619
- package/src/superlocalmemory/evolution/llm_dispatch.py +0 -559
- package/src/superlocalmemory/evolution/model_selection.py +0 -175
- package/src/superlocalmemory/evolution/mutation_generator.py +0 -226
- package/src/superlocalmemory/evolution/skill_activator.py +0 -270
- package/src/superlocalmemory/evolution/skill_evolver.py +0 -928
- package/src/superlocalmemory/evolution/triggers.py +0 -376
- package/src/superlocalmemory/evolution/types.py +0 -114
- package/src/superlocalmemory/graph/__init__.py +0 -9
- package/src/superlocalmemory/graph/cozo_adjacency.py +0 -122
- package/src/superlocalmemory/graph/cozo_backend.py +0 -751
- package/src/superlocalmemory/hooks/__init__.py +0 -3
- package/src/superlocalmemory/hooks/_outcome_common.py +0 -523
- package/src/superlocalmemory/hooks/adapter_base.py +0 -347
- package/src/superlocalmemory/hooks/antigravity_adapter.py +0 -171
- package/src/superlocalmemory/hooks/auto_capture.py +0 -133
- package/src/superlocalmemory/hooks/auto_invoker.py +0 -521
- package/src/superlocalmemory/hooks/auto_parameterize.py +0 -147
- package/src/superlocalmemory/hooks/auto_recall.py +0 -191
- package/src/superlocalmemory/hooks/auto_recall_hook.py +0 -251
- package/src/superlocalmemory/hooks/before_web_hook.py +0 -131
- package/src/superlocalmemory/hooks/claude_code_hooks.py +0 -637
- package/src/superlocalmemory/hooks/codex_assets.py +0 -251
- package/src/superlocalmemory/hooks/codex_hooks.py +0 -186
- package/src/superlocalmemory/hooks/context_payload.py +0 -311
- package/src/superlocalmemory/hooks/copilot_adapter.py +0 -208
- package/src/superlocalmemory/hooks/cross_platform_connector.py +0 -90
- package/src/superlocalmemory/hooks/cursor_adapter.py +0 -173
- package/src/superlocalmemory/hooks/hook_daemon.py +0 -295
- package/src/superlocalmemory/hooks/hook_handlers.py +0 -822
- package/src/superlocalmemory/hooks/ide_connector.py +0 -246
- package/src/superlocalmemory/hooks/memory_protocol.py +0 -158
- package/src/superlocalmemory/hooks/portable_kit.py +0 -755
- package/src/superlocalmemory/hooks/post_tool_async_hook.py +0 -183
- package/src/superlocalmemory/hooks/post_tool_outcome_hook.py +0 -351
- package/src/superlocalmemory/hooks/prewarm_auth.py +0 -187
- package/src/superlocalmemory/hooks/rules_engine.py +0 -99
- package/src/superlocalmemory/hooks/session_registry.py +0 -330
- package/src/superlocalmemory/hooks/stop_outcome_hook.py +0 -138
- package/src/superlocalmemory/hooks/sync_loop.py +0 -114
- package/src/superlocalmemory/hooks/topic_shift_hook.py +0 -302
- package/src/superlocalmemory/hooks/user_prompt_hook.py +0 -131
- package/src/superlocalmemory/hooks/user_prompt_rehash_hook.py +0 -210
- package/src/superlocalmemory/infra/__init__.py +0 -3
- package/src/superlocalmemory/infra/auth_middleware.py +0 -145
- package/src/superlocalmemory/infra/backup.py +0 -974
- package/src/superlocalmemory/infra/backup_obligations.py +0 -423
- package/src/superlocalmemory/infra/cache_manager.py +0 -267
- package/src/superlocalmemory/infra/cloud_backup.py +0 -788
- package/src/superlocalmemory/infra/daemon_identity.py +0 -300
- package/src/superlocalmemory/infra/data_root.py +0 -238
- package/src/superlocalmemory/infra/event_bus.py +0 -637
- package/src/superlocalmemory/infra/local_diagnostics.py +0 -327
- package/src/superlocalmemory/infra/pid_manager.py +0 -193
- package/src/superlocalmemory/infra/process_identity.py +0 -180
- package/src/superlocalmemory/infra/process_reaper.py +0 -624
- package/src/superlocalmemory/infra/rate_limiter.py +0 -228
- package/src/superlocalmemory/infra/self_heal.py +0 -401
- package/src/superlocalmemory/infra/version_integrity.py +0 -229
- package/src/superlocalmemory/ingestion/__init__.py +0 -13
- package/src/superlocalmemory/ingestion/adapter_manager.py +0 -255
- package/src/superlocalmemory/ingestion/base_adapter.py +0 -171
- package/src/superlocalmemory/ingestion/calendar_adapter.py +0 -349
- package/src/superlocalmemory/ingestion/credentials.py +0 -125
- package/src/superlocalmemory/ingestion/gmail_adapter.py +0 -378
- package/src/superlocalmemory/ingestion/parsers.py +0 -100
- package/src/superlocalmemory/ingestion/transcript_adapter.py +0 -161
- package/src/superlocalmemory/integrations/__init__.py +0 -1
- package/src/superlocalmemory/integrations/bounded_loops_mcp.py +0 -431
- package/src/superlocalmemory/integrations/bounded_loops_v051.py +0 -236
- package/src/superlocalmemory/learning/__init__.py +0 -0
- package/src/superlocalmemory/learning/adaptive.py +0 -172
- package/src/superlocalmemory/learning/arm_catalog.py +0 -97
- package/src/superlocalmemory/learning/assertion_miner.py +0 -403
- package/src/superlocalmemory/learning/bandit.py +0 -654
- package/src/superlocalmemory/learning/bandit_cache.py +0 -131
- package/src/superlocalmemory/learning/behavioral.py +0 -542
- package/src/superlocalmemory/learning/bootstrap.py +0 -298
- package/src/superlocalmemory/learning/consolidation_cycle.py +0 -398
- package/src/superlocalmemory/learning/consolidation_quantization_worker.py +0 -115
- package/src/superlocalmemory/learning/consolidation_worker.py +0 -261
- package/src/superlocalmemory/learning/cross_project.py +0 -408
- package/src/superlocalmemory/learning/database.py +0 -698
- package/src/superlocalmemory/learning/dedup_hnsw.py +0 -413
- package/src/superlocalmemory/learning/engagement.py +0 -487
- package/src/superlocalmemory/learning/engagement_features.py +0 -279
- package/src/superlocalmemory/learning/ensemble.py +0 -309
- package/src/superlocalmemory/learning/entity_compiler.py +0 -356
- package/src/superlocalmemory/learning/fact_outcome_joins.py +0 -207
- package/src/superlocalmemory/learning/features.py +0 -138
- package/src/superlocalmemory/learning/feedback.py +0 -724
- package/src/superlocalmemory/learning/forgetting_scheduler.py +0 -375
- package/src/superlocalmemory/learning/hnsw_dedup.py +0 -69
- package/src/superlocalmemory/learning/labeler.py +0 -85
- package/src/superlocalmemory/learning/legacy_migration.py +0 -316
- package/src/superlocalmemory/learning/lightgbm_subprocess.py +0 -236
- package/src/superlocalmemory/learning/memory_merge.py +0 -175
- package/src/superlocalmemory/learning/model_cache.py +0 -267
- package/src/superlocalmemory/learning/model_rollback.py +0 -281
- package/src/superlocalmemory/learning/outcome_queue.py +0 -306
- package/src/superlocalmemory/learning/outcomes.py +0 -286
- package/src/superlocalmemory/learning/pattern_miner.py +0 -465
- package/src/superlocalmemory/learning/pattern_miner_constants.py +0 -90
- package/src/superlocalmemory/learning/pcos.py +0 -291
- package/src/superlocalmemory/learning/project_context.py +0 -366
- package/src/superlocalmemory/learning/propensity.py +0 -131
- package/src/superlocalmemory/learning/ranker.py +0 -300
- package/src/superlocalmemory/learning/ranker_common.py +0 -163
- package/src/superlocalmemory/learning/ranker_retrain_legacy.py +0 -210
- package/src/superlocalmemory/learning/ranker_retrain_online.py +0 -423
- package/src/superlocalmemory/learning/reward.py +0 -888
- package/src/superlocalmemory/learning/reward_archive.py +0 -223
- package/src/superlocalmemory/learning/reward_boost.py +0 -211
- package/src/superlocalmemory/learning/reward_from_outcomes.py +0 -365
- package/src/superlocalmemory/learning/reward_model.py +0 -144
- package/src/superlocalmemory/learning/reward_proxy.py +0 -578
- package/src/superlocalmemory/learning/shadow_test.py +0 -524
- package/src/superlocalmemory/learning/signal_kinds.py +0 -79
- package/src/superlocalmemory/learning/signal_worker.py +0 -268
- package/src/superlocalmemory/learning/signals.py +0 -646
- package/src/superlocalmemory/learning/skill_performance_miner.py +0 -422
- package/src/superlocalmemory/learning/source_quality.py +0 -828
- package/src/superlocalmemory/learning/trigram_index.py +0 -548
- package/src/superlocalmemory/learning/workflows.py +0 -309
- package/src/superlocalmemory/llm/__init__.py +0 -0
- package/src/superlocalmemory/llm/backbone.py +0 -364
- package/src/superlocalmemory/loops/__init__.py +0 -58
- package/src/superlocalmemory/loops/budget.py +0 -58
- package/src/superlocalmemory/loops/engine.py +0 -174
- package/src/superlocalmemory/loops/ledger.py +0 -298
- package/src/superlocalmemory/loops/models.py +0 -152
- package/src/superlocalmemory/loops/rules.py +0 -52
- package/src/superlocalmemory/math/__init__.py +0 -0
- package/src/superlocalmemory/math/ebbinghaus.py +0 -352
- package/src/superlocalmemory/math/fisher.py +0 -356
- package/src/superlocalmemory/math/fisher_quantized.py +0 -255
- package/src/superlocalmemory/math/hopfield.py +0 -282
- package/src/superlocalmemory/math/langevin.py +0 -411
- package/src/superlocalmemory/math/polar_quant.py +0 -414
- package/src/superlocalmemory/math/qjl.py +0 -115
- package/src/superlocalmemory/math/sheaf.py +0 -261
- package/src/superlocalmemory/math/turbo_quant.py +0 -318
- package/src/superlocalmemory/mcp/__init__.py +0 -0
- package/src/superlocalmemory/mcp/_daemon_proxy.py +0 -203
- package/src/superlocalmemory/mcp/_pool_adapter.py +0 -181
- package/src/superlocalmemory/mcp/_stdin_guard.py +0 -60
- package/src/superlocalmemory/mcp/agent_context.py +0 -115
- package/src/superlocalmemory/mcp/cli_fallback.py +0 -602
- package/src/superlocalmemory/mcp/http_transport.py +0 -85
- package/src/superlocalmemory/mcp/profiles.py +0 -154
- package/src/superlocalmemory/mcp/resources.py +0 -281
- package/src/superlocalmemory/mcp/server.py +0 -480
- package/src/superlocalmemory/mcp/session_binding.py +0 -98
- package/src/superlocalmemory/mcp/shared.py +0 -112
- package/src/superlocalmemory/mcp/tools.py +0 -18
- package/src/superlocalmemory/mcp/tools_active.py +0 -958
- package/src/superlocalmemory/mcp/tools_brain.py +0 -298
- package/src/superlocalmemory/mcp/tools_code_graph.py +0 -1717
- package/src/superlocalmemory/mcp/tools_context.py +0 -239
- package/src/superlocalmemory/mcp/tools_core.py +0 -1112
- package/src/superlocalmemory/mcp/tools_evolution.py +0 -343
- package/src/superlocalmemory/mcp/tools_learning.py +0 -393
- package/src/superlocalmemory/mcp/tools_loops.py +0 -345
- package/src/superlocalmemory/mcp/tools_mesh.py +0 -429
- package/src/superlocalmemory/mcp/tools_ops.py +0 -115
- package/src/superlocalmemory/mcp/tools_optimize.py +0 -322
- package/src/superlocalmemory/mcp/tools_summaries.py +0 -147
- package/src/superlocalmemory/mcp/tools_v28.py +0 -292
- package/src/superlocalmemory/mcp/tools_v3.py +0 -398
- package/src/superlocalmemory/mcp/tools_v33.py +0 -507
- package/src/superlocalmemory/mesh/__init__.py +0 -12
- package/src/superlocalmemory/mesh/broker.py +0 -812
- package/src/superlocalmemory/mesh/broker_security.py +0 -470
- package/src/superlocalmemory/mesh/discovery.py +0 -365
- package/src/superlocalmemory/mesh/lock_protocol.py +0 -313
- package/src/superlocalmemory/mesh/node_identity.py +0 -97
- package/src/superlocalmemory/mesh/outbox_remote.py +0 -429
- package/src/superlocalmemory/mesh/remote_sync.py +0 -829
- package/src/superlocalmemory/mesh/state_sync.py +0 -286
- package/src/superlocalmemory/migrations/__init__.py +0 -5
- package/src/superlocalmemory/migrations/v3_4_25_to_v3_4_26.py +0 -144
- package/src/superlocalmemory/optimize/NOTICE +0 -6
- package/src/superlocalmemory/optimize/__init__.py +0 -0
- package/src/superlocalmemory/optimize/adapters/__init__.py +0 -68
- package/src/superlocalmemory/optimize/adapters/_agent_registry.py +0 -120
- package/src/superlocalmemory/optimize/adapters/anthropic_adapter.py +0 -112
- package/src/superlocalmemory/optimize/adapters/openai_adapter.py +0 -122
- package/src/superlocalmemory/optimize/adapters/wrap.py +0 -228
- package/src/superlocalmemory/optimize/cache/__init__.py +0 -31
- package/src/superlocalmemory/optimize/cache/boundary_store.py +0 -488
- package/src/superlocalmemory/optimize/cache/centroid_store.py +0 -199
- package/src/superlocalmemory/optimize/cache/context_key.py +0 -67
- package/src/superlocalmemory/optimize/cache/exact.py +0 -88
- package/src/superlocalmemory/optimize/cache/invalidation.py +0 -36
- package/src/superlocalmemory/optimize/cache/key_builder.py +0 -111
- package/src/superlocalmemory/optimize/cache/manager.py +0 -737
- package/src/superlocalmemory/optimize/cache/semantic.py +0 -637
- package/src/superlocalmemory/optimize/cache/stampede.py +0 -50
- package/src/superlocalmemory/optimize/compress/__init__.py +0 -17
- package/src/superlocalmemory/optimize/compress/align.py +0 -159
- package/src/superlocalmemory/optimize/compress/ccr.py +0 -116
- package/src/superlocalmemory/optimize/compress/prose_llmlingua.py +0 -71
- package/src/superlocalmemory/optimize/compress/router.py +0 -667
- package/src/superlocalmemory/optimize/config/__init__.py +0 -56
- package/src/superlocalmemory/optimize/config/defaults.py +0 -43
- package/src/superlocalmemory/optimize/config/schema.py +0 -327
- package/src/superlocalmemory/optimize/config/store.py +0 -270
- package/src/superlocalmemory/optimize/metrics/__init__.py +0 -8
- package/src/superlocalmemory/optimize/metrics/counters.py +0 -155
- package/src/superlocalmemory/optimize/metrics/estimator.py +0 -87
- package/src/superlocalmemory/optimize/metrics/exporters.py +0 -77
- package/src/superlocalmemory/optimize/metrics/persistence.py +0 -115
- package/src/superlocalmemory/optimize/proxy/__init__.py +0 -28
- package/src/superlocalmemory/optimize/proxy/_helpers.py +0 -730
- package/src/superlocalmemory/optimize/proxy/anthropic_surface.py +0 -375
- package/src/superlocalmemory/optimize/proxy/capture.py +0 -550
- package/src/superlocalmemory/optimize/proxy/gemini_surface.py +0 -528
- package/src/superlocalmemory/optimize/proxy/lifecycle.py +0 -126
- package/src/superlocalmemory/optimize/proxy/openai_surface.py +0 -465
- package/src/superlocalmemory/optimize/proxy/server.py +0 -199
- package/src/superlocalmemory/optimize/proxy/vertex_surface.py +0 -246
- package/src/superlocalmemory/optimize/storage/__init__.py +0 -0
- package/src/superlocalmemory/optimize/storage/db.py +0 -1185
- package/src/superlocalmemory/optimize/storage/schema.py +0 -205
- package/src/superlocalmemory/parameterization/__init__.py +0 -47
- package/src/superlocalmemory/parameterization/cross_project.py +0 -12
- package/src/superlocalmemory/parameterization/pattern_extractor.py +0 -584
- package/src/superlocalmemory/parameterization/pii_filter.py +0 -106
- package/src/superlocalmemory/parameterization/prompt_injector.py +0 -219
- package/src/superlocalmemory/parameterization/prompt_lifecycle.py +0 -281
- package/src/superlocalmemory/parameterization/soft_prompt_generator.py +0 -542
- package/src/superlocalmemory/parameterization/workflow_miner.py +0 -17
- package/src/superlocalmemory/reliability/__init__.py +0 -45
- package/src/superlocalmemory/reliability/join_liveness.py +0 -301
- package/src/superlocalmemory/reliability/prior_distance.py +0 -243
- package/src/superlocalmemory/retrieval/__init__.py +0 -0
- package/src/superlocalmemory/retrieval/agentic.py +0 -367
- package/src/superlocalmemory/retrieval/ann_index.py +0 -235
- package/src/superlocalmemory/retrieval/bm25_channel.py +0 -451
- package/src/superlocalmemory/retrieval/bridge_discovery.py +0 -253
- package/src/superlocalmemory/retrieval/channel_registry.py +0 -154
- package/src/superlocalmemory/retrieval/channel_status.py +0 -117
- package/src/superlocalmemory/retrieval/engine.py +0 -1615
- package/src/superlocalmemory/retrieval/entity_channel.py +0 -994
- package/src/superlocalmemory/retrieval/forgetting_filter.py +0 -160
- package/src/superlocalmemory/retrieval/fusion.py +0 -81
- package/src/superlocalmemory/retrieval/graph_adjacency.py +0 -219
- package/src/superlocalmemory/retrieval/hopfield_channel.py +0 -465
- package/src/superlocalmemory/retrieval/profile_channel.py +0 -105
- package/src/superlocalmemory/retrieval/quantization_aware_search.py +0 -147
- package/src/superlocalmemory/retrieval/remote_reranker.py +0 -758
- package/src/superlocalmemory/retrieval/reranker.py +0 -674
- package/src/superlocalmemory/retrieval/scope_policy.py +0 -126
- package/src/superlocalmemory/retrieval/semantic_channel.py +0 -638
- package/src/superlocalmemory/retrieval/spreading.py +0 -288
- package/src/superlocalmemory/retrieval/spreading_activation.py +0 -616
- package/src/superlocalmemory/retrieval/strategy.py +0 -248
- package/src/superlocalmemory/retrieval/temporal_channel.py +0 -433
- package/src/superlocalmemory/retrieval/temporal_frame.py +0 -102
- package/src/superlocalmemory/retrieval/temporal_utils.py +0 -122
- package/src/superlocalmemory/retrieval/temporal_validity_filter.py +0 -499
- package/src/superlocalmemory/retrieval/time_window.py +0 -181
- package/src/superlocalmemory/retrieval/vector_store.py +0 -863
- package/src/superlocalmemory/server/__init__.py +0 -1
- package/src/superlocalmemory/server/api.py +0 -310
- package/src/superlocalmemory/server/asset_versions.py +0 -171
- package/src/superlocalmemory/server/bandit_loops.py +0 -158
- package/src/superlocalmemory/server/config_file.py +0 -90
- package/src/superlocalmemory/server/consolidation_runner.py +0 -140
- package/src/superlocalmemory/server/egress_policy.py +0 -258
- package/src/superlocalmemory/server/loopback.py +0 -85
- package/src/superlocalmemory/server/middleware/__init__.py +0 -11
- package/src/superlocalmemory/server/middleware/security_headers.py +0 -144
- package/src/superlocalmemory/server/origin.py +0 -55
- package/src/superlocalmemory/server/profile_runtime.py +0 -515
- package/src/superlocalmemory/server/rbac_enforce.py +0 -194
- package/src/superlocalmemory/server/recall_health.py +0 -343
- package/src/superlocalmemory/server/recall_serializer.py +0 -320
- package/src/superlocalmemory/server/route_mutations.py +0 -104
- package/src/superlocalmemory/server/routes/__init__.py +0 -4
- package/src/superlocalmemory/server/routes/abstraction.py +0 -314
- package/src/superlocalmemory/server/routes/adapters.py +0 -63
- package/src/superlocalmemory/server/routes/agents.py +0 -303
- package/src/superlocalmemory/server/routes/backup.py +0 -869
- package/src/superlocalmemory/server/routes/behavioral.py +0 -659
- package/src/superlocalmemory/server/routes/brain.py +0 -1892
- package/src/superlocalmemory/server/routes/chat.py +0 -393
- package/src/superlocalmemory/server/routes/compliance.py +0 -533
- package/src/superlocalmemory/server/routes/config_api.py +0 -703
- package/src/superlocalmemory/server/routes/data_io.py +0 -329
- package/src/superlocalmemory/server/routes/entity.py +0 -237
- package/src/superlocalmemory/server/routes/events.py +0 -214
- package/src/superlocalmemory/server/routes/evolution.py +0 -510
- package/src/superlocalmemory/server/routes/helpers.py +0 -499
- package/src/superlocalmemory/server/routes/ingest.py +0 -137
- package/src/superlocalmemory/server/routes/insights.py +0 -366
- package/src/superlocalmemory/server/routes/learning.py +0 -834
- package/src/superlocalmemory/server/routes/learning_telemetry.py +0 -154
- package/src/superlocalmemory/server/routes/lifecycle.py +0 -184
- package/src/superlocalmemory/server/routes/memories.py +0 -1661
- package/src/superlocalmemory/server/routes/mesh.py +0 -517
- package/src/superlocalmemory/server/routes/mesh_lock.py +0 -54
- package/src/superlocalmemory/server/routes/mesh_state.py +0 -63
- package/src/superlocalmemory/server/routes/optimize.py +0 -197
- package/src/superlocalmemory/server/routes/prewarm.py +0 -173
- package/src/superlocalmemory/server/routes/profiles.py +0 -292
- package/src/superlocalmemory/server/routes/ratelimit.py +0 -132
- package/src/superlocalmemory/server/routes/rbac.py +0 -366
- package/src/superlocalmemory/server/routes/stats.py +0 -385
- package/src/superlocalmemory/server/routes/tiers.py +0 -222
- package/src/superlocalmemory/server/routes/timeline.py +0 -258
- package/src/superlocalmemory/server/routes/token.py +0 -90
- package/src/superlocalmemory/server/routes/v3_api.py +0 -3023
- package/src/superlocalmemory/server/routes/ws.py +0 -171
- package/src/superlocalmemory/server/security_middleware.py +0 -89
- package/src/superlocalmemory/server/ui.py +0 -354
- package/src/superlocalmemory/server/unified_daemon.py +0 -6326
- package/src/superlocalmemory/server/write_identity.py +0 -195
- package/src/superlocalmemory/storage/__init__.py +0 -0
- package/src/superlocalmemory/storage/_migration_internals.py +0 -638
- package/src/superlocalmemory/storage/_schema_version.py +0 -174
- package/src/superlocalmemory/storage/access_log.py +0 -170
- package/src/superlocalmemory/storage/admission_codec.py +0 -129
- package/src/superlocalmemory/storage/admission_journal.py +0 -843
- package/src/superlocalmemory/storage/agent_experience.py +0 -546
- package/src/superlocalmemory/storage/backup.py +0 -531
- package/src/superlocalmemory/storage/correction_cases.py +0 -670
- package/src/superlocalmemory/storage/database.py +0 -3180
- package/src/superlocalmemory/storage/deferred_writes.py +0 -209
- package/src/superlocalmemory/storage/embedding_codec.py +0 -200
- package/src/superlocalmemory/storage/embedding_migrator.py +0 -672
- package/src/superlocalmemory/storage/erasure_fence.py +0 -45
- package/src/superlocalmemory/storage/execution_learning.py +0 -285
- package/src/superlocalmemory/storage/external_evidence.py +0 -359
- package/src/superlocalmemory/storage/generation_fence.py +0 -63
- package/src/superlocalmemory/storage/lineage_retention.py +0 -236
- package/src/superlocalmemory/storage/logical_edges.py +0 -86
- package/src/superlocalmemory/storage/memory_write.py +0 -115
- package/src/superlocalmemory/storage/migration_runner.py +0 -895
- package/src/superlocalmemory/storage/migration_v33.py +0 -140
- package/src/superlocalmemory/storage/migrations/M001_add_signal_features_columns.py +0 -67
- package/src/superlocalmemory/storage/migrations/M002_model_state_history.py +0 -107
- package/src/superlocalmemory/storage/migrations/M003_migration_log.py +0 -38
- package/src/superlocalmemory/storage/migrations/M004_cross_platform_sync_log.py +0 -46
- package/src/superlocalmemory/storage/migrations/M005_bandit_tables.py +0 -75
- package/src/superlocalmemory/storage/migrations/M006_action_outcomes_reward.py +0 -75
- package/src/superlocalmemory/storage/migrations/M007_pending_outcomes.py +0 -63
- package/src/superlocalmemory/storage/migrations/M009_model_lineage.py +0 -94
- package/src/superlocalmemory/storage/migrations/M010_evolution_config.py +0 -80
- package/src/superlocalmemory/storage/migrations/M011_archive_and_merge.py +0 -87
- package/src/superlocalmemory/storage/migrations/M012_shadow_observations.py +0 -72
- package/src/superlocalmemory/storage/migrations/M013_bi_temporal_columns.py +0 -55
- package/src/superlocalmemory/storage/migrations/M014_v345_scale_ready.py +0 -45
- package/src/superlocalmemory/storage/migrations/M015_add_pinned_column.py +0 -58
- package/src/superlocalmemory/storage/migrations/M016_add_scope_support.py +0 -120
- package/src/superlocalmemory/storage/migrations/M017_ccq_scope_column.py +0 -79
- package/src/superlocalmemory/storage/migrations/M018_ingestion_operations.py +0 -120
- package/src/superlocalmemory/storage/migrations/M019_derivation_lineage.py +0 -54
- package/src/superlocalmemory/storage/migrations/M020_model_state_integrity.py +0 -52
- package/src/superlocalmemory/storage/migrations/M021_ingestion_log_profile.py +0 -108
- package/src/superlocalmemory/storage/migrations/M022_entity_aliases_profile.py +0 -86
- package/src/superlocalmemory/storage/migrations/M023_mesh_profile_isolation.py +0 -194
- package/src/superlocalmemory/storage/migrations/M024_rbac_users_roles.py +0 -87
- package/src/superlocalmemory/storage/migrations/M025_perf_indexes.py +0 -90
- package/src/superlocalmemory/storage/migrations/M026_rbac_memberships_fk.py +0 -136
- package/src/superlocalmemory/storage/migrations/M027_transferable_patterns_profile.py +0 -163
- package/src/superlocalmemory/storage/migrations/M028_fact_entity_associations.py +0 -305
- package/src/superlocalmemory/storage/migrations/M029_behavioral_history_indexes.py +0 -137
- package/src/superlocalmemory/storage/migrations/M030_entity_explorer_indexes.py +0 -93
- package/src/superlocalmemory/storage/migrations/M031_dead_letter_operations.py +0 -80
- package/src/superlocalmemory/storage/migrations/M032_write_coordinator_admission.py +0 -188
- package/src/superlocalmemory/storage/migrations/M033_projection_transactions.py +0 -148
- package/src/superlocalmemory/storage/migrations/M034_obligation_integrity.py +0 -58
- package/src/superlocalmemory/storage/migrations/M035_erasure_receipts.py +0 -113
- package/src/superlocalmemory/storage/migrations/M036_vector_row_map.py +0 -107
- package/src/superlocalmemory/storage/migrations/M037_manifest_hmac_version.py +0 -162
- package/src/superlocalmemory/storage/migrations/M038_learning_feedback_channel.py +0 -77
- package/src/superlocalmemory/storage/migrations/M039_scene_fact_members.py +0 -137
- package/src/superlocalmemory/storage/migrations/M040_agent_experience_receipts.py +0 -254
- package/src/superlocalmemory/storage/migrations/M041_external_evidence_receipts.py +0 -189
- package/src/superlocalmemory/storage/migrations/M042_correction_case_ledger.py +0 -245
- package/src/superlocalmemory/storage/migrations/M043_quarantine_display_summaries.py +0 -512
- package/src/superlocalmemory/storage/migrations/M044_play_carries_its_own_evidence.py +0 -127
- package/src/superlocalmemory/storage/migrations/M045_fact_outcome_score.py +0 -158
- package/src/superlocalmemory/storage/migrations/M046_prospective_memory_has_its_own_name.py +0 -620
- package/src/superlocalmemory/storage/migrations/M047_fisher_vectors_are_stored_like_every_other_vector.py +0 -306
- package/src/superlocalmemory/storage/migrations/M048_upcoming_holds_only_what_is_upcoming.py +0 -229
- package/src/superlocalmemory/storage/migrations/M049_a_schema_version_marker_is_one_row.py +0 -201
- package/src/superlocalmemory/storage/migrations/M050_execution_learning_v2.py +0 -70
- package/src/superlocalmemory/storage/migrations/__init__.py +0 -103
- package/src/superlocalmemory/storage/migrations.py +0 -333
- package/src/superlocalmemory/storage/models.py +0 -500
- package/src/superlocalmemory/storage/projection_outbox.py +0 -346
- package/src/superlocalmemory/storage/quantized_store.py +0 -280
- package/src/superlocalmemory/storage/read_connection.py +0 -115
- package/src/superlocalmemory/storage/retention_policy.py +0 -860
- package/src/superlocalmemory/storage/schema.py +0 -1108
- package/src/superlocalmemory/storage/schema_code_graph.py +0 -282
- package/src/superlocalmemory/storage/schema_v32.py +0 -382
- package/src/superlocalmemory/storage/schema_v3410.py +0 -159
- package/src/superlocalmemory/storage/schema_v3411.py +0 -149
- package/src/superlocalmemory/storage/schema_v343.py +0 -315
- package/src/superlocalmemory/storage/schema_v345.py +0 -109
- package/src/superlocalmemory/storage/schema_v347.py +0 -140
- package/src/superlocalmemory/storage/sqlite_vectors.py +0 -169
- package/src/superlocalmemory/storage/v2_migrator.py +0 -466
- package/src/superlocalmemory/storage/write_coordinator.py +0 -949
- package/src/superlocalmemory/storage/write_lock.py +0 -88
- package/src/superlocalmemory/summaries/__init__.py +0 -37
- package/src/superlocalmemory/summaries/base.py +0 -267
- package/src/superlocalmemory/summaries/daily_reflection.py +0 -340
- package/src/superlocalmemory/summaries/non_answer.py +0 -223
- package/src/superlocalmemory/summaries/project_work_log.py +0 -440
- package/src/superlocalmemory/summaries/session_summary.py +0 -311
- package/src/superlocalmemory/trust/__init__.py +0 -0
- package/src/superlocalmemory/trust/gate.py +0 -171
- package/src/superlocalmemory/trust/provenance.py +0 -124
- package/src/superlocalmemory/trust/scorer.py +0 -413
- package/src/superlocalmemory/trust/signals.py +0 -153
- package/src/superlocalmemory/ui/assets/slm-icon-white.svg +0 -64
- package/src/superlocalmemory/ui/assets/slm-icon.svg +0 -36
- package/src/superlocalmemory/ui/css/brain.css +0 -409
- package/src/superlocalmemory/ui/css/design-system.css +0 -696
- package/src/superlocalmemory/ui/css/legacy-dashboard.css +0 -663
- package/src/superlocalmemory/ui/css/neural-glass.css +0 -1599
- package/src/superlocalmemory/ui/css/od-bridge.css +0 -158
- package/src/superlocalmemory/ui/favicon.svg +0 -36
- package/src/superlocalmemory/ui/index.html +0 -1638
- package/src/superlocalmemory/ui/js/agents.js +0 -192
- package/src/superlocalmemory/ui/js/auto-settings.js +0 -624
- package/src/superlocalmemory/ui/js/brain.js +0 -1400
- package/src/superlocalmemory/ui/js/clusters.js +0 -326
- package/src/superlocalmemory/ui/js/compliance.js +0 -307
- package/src/superlocalmemory/ui/js/core.js +0 -566
- package/src/superlocalmemory/ui/js/dashboard.js +0 -503
- package/src/superlocalmemory/ui/js/event-delegation.js +0 -113
- package/src/superlocalmemory/ui/js/events.js +0 -178
- package/src/superlocalmemory/ui/js/fact-detail.js +0 -142
- package/src/superlocalmemory/ui/js/feedback.js +0 -339
- package/src/superlocalmemory/ui/js/graph-event-bus.js +0 -83
- package/src/superlocalmemory/ui/js/graph-filters.js +0 -220
- package/src/superlocalmemory/ui/js/graph-ui.js +0 -214
- package/src/superlocalmemory/ui/js/ide-status.js +0 -115
- package/src/superlocalmemory/ui/js/init.js +0 -54
- package/src/superlocalmemory/ui/js/knowledge-graph.js +0 -945
- package/src/superlocalmemory/ui/js/lifecycle.js +0 -387
- package/src/superlocalmemory/ui/js/math-health.js +0 -114
- package/src/superlocalmemory/ui/js/memories.js +0 -394
- package/src/superlocalmemory/ui/js/memory-chat.js +0 -371
- package/src/superlocalmemory/ui/js/memory-timeline.js +0 -265
- package/src/superlocalmemory/ui/js/modal.js +0 -733
- package/src/superlocalmemory/ui/js/ng-entities.js +0 -298
- package/src/superlocalmemory/ui/js/ng-health.js +0 -208
- package/src/superlocalmemory/ui/js/ng-ingestion.js +0 -203
- package/src/superlocalmemory/ui/js/ng-mesh.js +0 -374
- package/src/superlocalmemory/ui/js/ng-shell.js +0 -524
- package/src/superlocalmemory/ui/js/ng-skills.js +0 -663
- package/src/superlocalmemory/ui/js/od-agents.js +0 -588
- package/src/superlocalmemory/ui/js/od-auth-gate.js +0 -257
- package/src/superlocalmemory/ui/js/od-backup.js +0 -878
- package/src/superlocalmemory/ui/js/od-boundedloops.js +0 -324
- package/src/superlocalmemory/ui/js/od-brain.js +0 -1095
- package/src/superlocalmemory/ui/js/od-compliance-ext.js +0 -301
- package/src/superlocalmemory/ui/js/od-components.js +0 -147
- package/src/superlocalmemory/ui/js/od-entities.js +0 -622
- package/src/superlocalmemory/ui/js/od-graph.js +0 -776
- package/src/superlocalmemory/ui/js/od-health.js +0 -579
- package/src/superlocalmemory/ui/js/od-mcp.js +0 -508
- package/src/superlocalmemory/ui/js/od-memories.js +0 -1499
- package/src/superlocalmemory/ui/js/od-mesh.js +0 -645
- package/src/superlocalmemory/ui/js/od-operations.js +0 -1268
- package/src/superlocalmemory/ui/js/od-ops-health.js +0 -417
- package/src/superlocalmemory/ui/js/od-optimize.js +0 -828
- package/src/superlocalmemory/ui/js/od-settings.js +0 -1275
- package/src/superlocalmemory/ui/js/od-shell.js +0 -819
- package/src/superlocalmemory/ui/js/od-skills.js +0 -600
- package/src/superlocalmemory/ui/js/od-team.js +0 -265
- package/src/superlocalmemory/ui/js/optimize.js +0 -191
- package/src/superlocalmemory/ui/js/profiles.js +0 -362
- package/src/superlocalmemory/ui/js/quick-actions.js +0 -334
- package/src/superlocalmemory/ui/js/recall-lab.js +0 -373
- package/src/superlocalmemory/ui/js/search.js +0 -86
- package/src/superlocalmemory/ui/js/settings.js +0 -556
- package/src/superlocalmemory/ui/js/timeline.js +0 -62
- package/src/superlocalmemory/ui/js/trust-dashboard.js +0 -225
- package/src/superlocalmemory/ui/vendor/bootstrap-icons/bootstrap-icons.css +0 -2018
- package/src/superlocalmemory/ui/vendor/bootstrap-icons/fonts/bootstrap-icons.woff +0 -0
- package/src/superlocalmemory/ui/vendor/bootstrap-icons/fonts/bootstrap-icons.woff2 +0 -0
- package/src/superlocalmemory/ui/vendor/bootstrap.bundle.min.js +0 -7
- package/src/superlocalmemory/ui/vendor/bootstrap.min.css +0 -6
- package/src/superlocalmemory/ui/vendor/d3.v7.min.js +0 -2
- package/src/superlocalmemory/ui/vendor/graphology-library.min.js +0 -2
- package/src/superlocalmemory/ui/vendor/graphology.umd.min.js +0 -2
- package/src/superlocalmemory/ui/vendor/inter-ui/inter-variable.min.css +0 -8
- package/src/superlocalmemory/ui/vendor/inter-ui/variable/InterVariable-Italic.woff2 +0 -0
- package/src/superlocalmemory/ui/vendor/inter-ui/variable/InterVariable.woff2 +0 -0
- package/src/superlocalmemory/ui/vendor/sigma.min.js +0 -1
- package/src/superlocalmemory/vector/__init__.py +0 -9
- package/src/superlocalmemory/vector/lancedb_backend.py +0 -366
|
@@ -1,158 +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 | https://qualixar.com | https://varunpratap.com
|
|
4
|
-
|
|
5
|
-
"""SuperLocalMemory V3 — Memory Lifecycle Management.
|
|
6
|
-
|
|
7
|
-
Implements Active → Warm → Cold → Archived state machine.
|
|
8
|
-
Coupled with Langevin dynamics: positions naturally create lifecycle states.
|
|
9
|
-
|
|
10
|
-
Ported from V2.8 with Langevin coupling (Innovation's unique feature).
|
|
11
|
-
|
|
12
|
-
Part of Qualixar | Author: Varun Pratap Bhardwaj
|
|
13
|
-
"""
|
|
14
|
-
|
|
15
|
-
from __future__ import annotations
|
|
16
|
-
|
|
17
|
-
import logging
|
|
18
|
-
from datetime import UTC, datetime, timedelta
|
|
19
|
-
|
|
20
|
-
from superlocalmemory.storage.models import AtomicFact, MemoryLifecycle
|
|
21
|
-
|
|
22
|
-
logger = logging.getLogger(__name__)
|
|
23
|
-
|
|
24
|
-
# Lifecycle transition thresholds (days since last access)
|
|
25
|
-
_ACTIVE_MAX_DAYS = 7 # Active for 7 days after last access
|
|
26
|
-
_WARM_MAX_DAYS = 30 # Warm for 30 days
|
|
27
|
-
_COLD_MAX_DAYS = 90 # Cold for 90 days, then archived
|
|
28
|
-
|
|
29
|
-
# Langevin weight thresholds (if Langevin is available)
|
|
30
|
-
_ACTIVE_WEIGHT_MIN = 0.7
|
|
31
|
-
_WARM_WEIGHT_MIN = 0.4
|
|
32
|
-
_COLD_WEIGHT_MIN = 0.1
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
class LifecycleManager:
|
|
36
|
-
"""Manage memory lifecycle states.
|
|
37
|
-
|
|
38
|
-
Two complementary strategies:
|
|
39
|
-
1. Time-based: days since last access → state transition
|
|
40
|
-
2. Langevin-based: position on Poincaré ball → lifecycle weight → state
|
|
41
|
-
|
|
42
|
-
When Langevin is available, it takes precedence (more nuanced).
|
|
43
|
-
Time-based is the fallback for Mode A (no dynamics).
|
|
44
|
-
"""
|
|
45
|
-
|
|
46
|
-
def __init__(self, db, langevin=None) -> None:
|
|
47
|
-
self._db = db
|
|
48
|
-
self._langevin = langevin
|
|
49
|
-
|
|
50
|
-
def get_lifecycle_state(self, fact: AtomicFact) -> MemoryLifecycle:
|
|
51
|
-
"""Determine current lifecycle state for a fact."""
|
|
52
|
-
# Strategy 1: Langevin-based (if available and position exists)
|
|
53
|
-
if self._langevin is not None and fact.langevin_position:
|
|
54
|
-
weight = self._langevin.compute_lifecycle_weight(fact.langevin_position)
|
|
55
|
-
return self._langevin.get_lifecycle_state(weight)
|
|
56
|
-
|
|
57
|
-
# Strategy 2: Time-based fallback
|
|
58
|
-
return self._time_based_state(fact)
|
|
59
|
-
|
|
60
|
-
def update_lifecycle(self, fact_id: str, profile_id: str) -> MemoryLifecycle:
|
|
61
|
-
"""Recompute and persist lifecycle state for a fact."""
|
|
62
|
-
rows = self._db.execute(
|
|
63
|
-
"SELECT lifecycle, access_count, created_at FROM atomic_facts "
|
|
64
|
-
"WHERE fact_id = ? AND profile_id = ?",
|
|
65
|
-
(fact_id, profile_id),
|
|
66
|
-
)
|
|
67
|
-
if not rows:
|
|
68
|
-
return MemoryLifecycle.ACTIVE
|
|
69
|
-
|
|
70
|
-
d = dict(rows[0])
|
|
71
|
-
days = self._days_since(d.get("created_at", ""))
|
|
72
|
-
access = d.get("access_count", 0)
|
|
73
|
-
|
|
74
|
-
if access > 10 or days < _ACTIVE_MAX_DAYS:
|
|
75
|
-
state = MemoryLifecycle.ACTIVE
|
|
76
|
-
elif days < _WARM_MAX_DAYS:
|
|
77
|
-
state = MemoryLifecycle.WARM
|
|
78
|
-
elif days < _COLD_MAX_DAYS:
|
|
79
|
-
state = MemoryLifecycle.COLD
|
|
80
|
-
else:
|
|
81
|
-
state = MemoryLifecycle.ARCHIVED
|
|
82
|
-
|
|
83
|
-
current = d.get("lifecycle", "active")
|
|
84
|
-
if current != state.value:
|
|
85
|
-
self._db.update_fact(fact_id, {"lifecycle": state})
|
|
86
|
-
logger.debug("Fact %s: %s → %s", fact_id, current, state.value)
|
|
87
|
-
|
|
88
|
-
return state
|
|
89
|
-
|
|
90
|
-
def run_maintenance(self, profile_id: str) -> dict[str, int]:
|
|
91
|
-
"""Run lifecycle maintenance on all facts in a profile.
|
|
92
|
-
|
|
93
|
-
If Langevin is available, evolve positions and update states.
|
|
94
|
-
Otherwise, use time-based transitions.
|
|
95
|
-
"""
|
|
96
|
-
facts = self._db.get_all_facts(profile_id)
|
|
97
|
-
counts: dict[str, int] = {s.value: 0 for s in MemoryLifecycle}
|
|
98
|
-
transitions = 0
|
|
99
|
-
|
|
100
|
-
for fact in facts:
|
|
101
|
-
old_state = fact.lifecycle
|
|
102
|
-
|
|
103
|
-
if self._langevin is not None and fact.langevin_position:
|
|
104
|
-
# Langevin step
|
|
105
|
-
age = self._days_since(fact.created_at)
|
|
106
|
-
new_pos, weight = self._langevin.step(
|
|
107
|
-
fact.langevin_position, fact.access_count, age, fact.importance
|
|
108
|
-
)
|
|
109
|
-
new_state = self._langevin.get_lifecycle_state(weight)
|
|
110
|
-
# Persist position + state
|
|
111
|
-
self._db.update_fact(fact.fact_id, {
|
|
112
|
-
"langevin_position": new_pos,
|
|
113
|
-
"lifecycle": new_state,
|
|
114
|
-
})
|
|
115
|
-
else:
|
|
116
|
-
new_state = self._time_based_state(fact)
|
|
117
|
-
if new_state != old_state:
|
|
118
|
-
self._db.update_fact(fact.fact_id, {"lifecycle": new_state})
|
|
119
|
-
|
|
120
|
-
counts[new_state.value] = counts.get(new_state.value, 0) + 1
|
|
121
|
-
if new_state != old_state:
|
|
122
|
-
transitions += 1
|
|
123
|
-
|
|
124
|
-
counts["transitions"] = transitions
|
|
125
|
-
logger.info("Lifecycle maintenance for '%s': %s", profile_id, counts)
|
|
126
|
-
return counts
|
|
127
|
-
|
|
128
|
-
def get_archived_facts(self, profile_id: str) -> list[AtomicFact]:
|
|
129
|
-
"""Get all archived facts (candidates for deletion/export)."""
|
|
130
|
-
rows = self._db.execute(
|
|
131
|
-
"SELECT * FROM atomic_facts WHERE profile_id = ? AND lifecycle = 'archived'",
|
|
132
|
-
(profile_id,),
|
|
133
|
-
)
|
|
134
|
-
return [self._db._row_to_fact(r) for r in rows]
|
|
135
|
-
|
|
136
|
-
# -- Internal ----------------------------------------------------------
|
|
137
|
-
|
|
138
|
-
def _time_based_state(self, fact: AtomicFact) -> MemoryLifecycle:
|
|
139
|
-
"""Determine lifecycle state from time since creation + access count."""
|
|
140
|
-
days = self._days_since(fact.created_at)
|
|
141
|
-
if fact.access_count > 10 or days < _ACTIVE_MAX_DAYS:
|
|
142
|
-
return MemoryLifecycle.ACTIVE
|
|
143
|
-
if days < _WARM_MAX_DAYS:
|
|
144
|
-
return MemoryLifecycle.WARM
|
|
145
|
-
if days < _COLD_MAX_DAYS:
|
|
146
|
-
return MemoryLifecycle.COLD
|
|
147
|
-
return MemoryLifecycle.ARCHIVED
|
|
148
|
-
|
|
149
|
-
@staticmethod
|
|
150
|
-
def _days_since(iso_date: str) -> float:
|
|
151
|
-
"""Days since an ISO date string."""
|
|
152
|
-
if not iso_date:
|
|
153
|
-
return 0.0
|
|
154
|
-
try:
|
|
155
|
-
dt = datetime.fromisoformat(iso_date)
|
|
156
|
-
return (datetime.now(UTC) - dt).total_seconds() / 86400.0
|
|
157
|
-
except (ValueError, TypeError):
|
|
158
|
-
return 0.0
|
|
@@ -1,415 +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 | https://qualixar.com | https://varunpratap.com
|
|
4
|
-
|
|
5
|
-
"""Named retention rules engine for compliance (GDPR, HIPAA, custom).
|
|
6
|
-
|
|
7
|
-
Rules are bound to profiles. Each rule specifies a retention period
|
|
8
|
-
in days. The engine can identify expired facts and enforce deletion.
|
|
9
|
-
|
|
10
|
-
Retention rules are stored in a dedicated SQLite table and operate
|
|
11
|
-
independently of the main memory lifecycle system.
|
|
12
|
-
"""
|
|
13
|
-
|
|
14
|
-
from __future__ import annotations
|
|
15
|
-
|
|
16
|
-
import json
|
|
17
|
-
import logging
|
|
18
|
-
import sqlite3
|
|
19
|
-
from datetime import datetime, timezone
|
|
20
|
-
from typing import Any
|
|
21
|
-
|
|
22
|
-
logger = logging.getLogger(__name__)
|
|
23
|
-
|
|
24
|
-
_RETENTION_RULES_TABLE = """
|
|
25
|
-
CREATE TABLE IF NOT EXISTS retention_rules (
|
|
26
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
27
|
-
profile_id TEXT NOT NULL,
|
|
28
|
-
rule_name TEXT NOT NULL,
|
|
29
|
-
days INTEGER NOT NULL,
|
|
30
|
-
description TEXT DEFAULT '',
|
|
31
|
-
framework TEXT NOT NULL DEFAULT 'custom',
|
|
32
|
-
action TEXT NOT NULL DEFAULT 'archive',
|
|
33
|
-
applies_to TEXT NOT NULL DEFAULT '{}',
|
|
34
|
-
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
35
|
-
UNIQUE(profile_id, rule_name)
|
|
36
|
-
)
|
|
37
|
-
"""
|
|
38
|
-
|
|
39
|
-
# Terminal lifecycle zone each action moves an expired fact into. 'notify'
|
|
40
|
-
# changes nothing — it only surfaces the count so an operator can act.
|
|
41
|
-
# atomic_facts.lifecycle CHECK allows only active/warm/cold/archived, so both
|
|
42
|
-
# retention actions land in the 'archived' lifecycle zone. 'tombstone' is
|
|
43
|
-
# additionally flagged purgeable via archive_status so a purge job can find it —
|
|
44
|
-
# this avoids a risky rebuild of the (large) atomic_facts CHECK constraint.
|
|
45
|
-
_ACTION_LIFECYCLE = {"archive": "archived", "tombstone": "archived"}
|
|
46
|
-
_TOMBSTONE_ACTIONS = frozenset({"tombstone"})
|
|
47
|
-
_VALID_ACTIONS = ("archive", "tombstone", "notify")
|
|
48
|
-
_SUPPORTED_APPLIES_TO = frozenset({"scope", "fact_type", "signal_type", "session_id"})
|
|
49
|
-
|
|
50
|
-
_FACTS_TABLE_CHECK = """
|
|
51
|
-
SELECT name FROM sqlite_master
|
|
52
|
-
WHERE type='table' AND name='atomic_facts'
|
|
53
|
-
"""
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
class RetentionEngine:
|
|
57
|
-
"""Named retention rules for compliance (GDPR, HIPAA, custom).
|
|
58
|
-
|
|
59
|
-
Rules are bound to profiles. Each rule specifies a retention period.
|
|
60
|
-
The engine can identify expired facts and enforce deletion.
|
|
61
|
-
"""
|
|
62
|
-
|
|
63
|
-
def __init__(self, db: sqlite3.Connection, *, autocommit: bool = True) -> None:
|
|
64
|
-
self._db = db
|
|
65
|
-
self._autocommit = autocommit
|
|
66
|
-
self._ensure_table()
|
|
67
|
-
|
|
68
|
-
# ------------------------------------------------------------------
|
|
69
|
-
# Internal helpers
|
|
70
|
-
# ------------------------------------------------------------------
|
|
71
|
-
|
|
72
|
-
def _ensure_table(self) -> None:
|
|
73
|
-
"""Create the retention_rules table, self-migrating older schemas.
|
|
74
|
-
|
|
75
|
-
Pre-GDPR-model tables had only (rule_name, days, description). Add the
|
|
76
|
-
framework/action/applies_to columns in place so existing rules keep
|
|
77
|
-
working (defaults: framework='custom', action='archive').
|
|
78
|
-
"""
|
|
79
|
-
self._db.execute(_RETENTION_RULES_TABLE)
|
|
80
|
-
cols = {r[1] for r in self._db.execute(
|
|
81
|
-
"PRAGMA table_info(retention_rules)").fetchall()}
|
|
82
|
-
for col, ddl in (
|
|
83
|
-
("framework", "framework TEXT NOT NULL DEFAULT 'custom'"),
|
|
84
|
-
("action", "action TEXT NOT NULL DEFAULT 'archive'"),
|
|
85
|
-
("applies_to", "applies_to TEXT NOT NULL DEFAULT '{}'"),
|
|
86
|
-
):
|
|
87
|
-
if col not in cols:
|
|
88
|
-
self._db.execute(f"ALTER TABLE retention_rules ADD COLUMN {ddl}")
|
|
89
|
-
self._commit_if_owned()
|
|
90
|
-
|
|
91
|
-
def _commit_if_owned(self) -> None:
|
|
92
|
-
"""Commit only when this engine owns the transaction boundary."""
|
|
93
|
-
if self._autocommit:
|
|
94
|
-
self._db.commit()
|
|
95
|
-
|
|
96
|
-
def _has_facts_table(self) -> bool:
|
|
97
|
-
"""Check if atomic_facts table exists in the database."""
|
|
98
|
-
row = self._db.execute(_FACTS_TABLE_CHECK).fetchone()
|
|
99
|
-
return row is not None
|
|
100
|
-
|
|
101
|
-
@staticmethod
|
|
102
|
-
def _age_in_days(created_at_str: str) -> float:
|
|
103
|
-
"""Calculate age from an ISO timestamp string to now, in days."""
|
|
104
|
-
try:
|
|
105
|
-
created = datetime.fromisoformat(created_at_str)
|
|
106
|
-
if created.tzinfo is None:
|
|
107
|
-
created = created.replace(tzinfo=timezone.utc)
|
|
108
|
-
now = datetime.now(timezone.utc)
|
|
109
|
-
return (now - created).total_seconds() / 86400.0
|
|
110
|
-
except (ValueError, TypeError):
|
|
111
|
-
return 0.0
|
|
112
|
-
|
|
113
|
-
# ------------------------------------------------------------------
|
|
114
|
-
# Rule management
|
|
115
|
-
# ------------------------------------------------------------------
|
|
116
|
-
|
|
117
|
-
def add_rule(
|
|
118
|
-
self,
|
|
119
|
-
profile_id: str,
|
|
120
|
-
rule_name: str,
|
|
121
|
-
days: int,
|
|
122
|
-
description: str = "",
|
|
123
|
-
) -> None:
|
|
124
|
-
"""Add a retention rule to a profile.
|
|
125
|
-
|
|
126
|
-
Args:
|
|
127
|
-
profile_id: Profile this rule applies to.
|
|
128
|
-
rule_name: Human-readable name (e.g. 'GDPR-30d').
|
|
129
|
-
days: Retention period in days.
|
|
130
|
-
description: Optional description of the rule.
|
|
131
|
-
|
|
132
|
-
Raises:
|
|
133
|
-
sqlite3.IntegrityError: If rule_name already exists for profile.
|
|
134
|
-
"""
|
|
135
|
-
self._db.execute(
|
|
136
|
-
"INSERT OR REPLACE INTO retention_rules "
|
|
137
|
-
"(profile_id, rule_name, days, description) "
|
|
138
|
-
"VALUES (?, ?, ?, ?)",
|
|
139
|
-
(profile_id, rule_name, days, description),
|
|
140
|
-
)
|
|
141
|
-
self._commit_if_owned()
|
|
142
|
-
logger.info(
|
|
143
|
-
"Added retention rule '%s' (%d days) to profile '%s'",
|
|
144
|
-
rule_name, days, profile_id,
|
|
145
|
-
)
|
|
146
|
-
|
|
147
|
-
def remove_rule(self, profile_id: str, rule_name: str) -> None:
|
|
148
|
-
"""Remove a retention rule.
|
|
149
|
-
|
|
150
|
-
Args:
|
|
151
|
-
profile_id: Profile the rule belongs to.
|
|
152
|
-
rule_name: Name of the rule to remove.
|
|
153
|
-
"""
|
|
154
|
-
self._db.execute(
|
|
155
|
-
"DELETE FROM retention_rules "
|
|
156
|
-
"WHERE profile_id = ? AND rule_name = ?",
|
|
157
|
-
(profile_id, rule_name),
|
|
158
|
-
)
|
|
159
|
-
self._commit_if_owned()
|
|
160
|
-
logger.info(
|
|
161
|
-
"Removed retention rule '%s' from profile '%s'",
|
|
162
|
-
rule_name, profile_id,
|
|
163
|
-
)
|
|
164
|
-
|
|
165
|
-
def get_rules(self, profile_id: str) -> list[dict[str, Any]]:
|
|
166
|
-
"""Get all retention rules for a profile (full GDPR shape)."""
|
|
167
|
-
rows = self._db.execute(
|
|
168
|
-
"SELECT id, rule_name, days, description, framework, action, "
|
|
169
|
-
"applies_to, created_at FROM retention_rules "
|
|
170
|
-
"WHERE profile_id = ? ORDER BY id",
|
|
171
|
-
(profile_id,),
|
|
172
|
-
).fetchall()
|
|
173
|
-
out: list[dict[str, Any]] = []
|
|
174
|
-
for r in rows:
|
|
175
|
-
try:
|
|
176
|
-
applies = json.loads(r[6]) if r[6] else {}
|
|
177
|
-
except (ValueError, TypeError):
|
|
178
|
-
applies = {}
|
|
179
|
-
out.append({
|
|
180
|
-
"id": r[0],
|
|
181
|
-
"name": r[1],
|
|
182
|
-
"rule_name": r[1], # legacy alias
|
|
183
|
-
"retention_days": r[2],
|
|
184
|
-
"days": r[2], # legacy alias
|
|
185
|
-
"description": r[3],
|
|
186
|
-
"framework": r[4],
|
|
187
|
-
"action": r[5],
|
|
188
|
-
"applies_to": applies,
|
|
189
|
-
"created_at": r[7],
|
|
190
|
-
})
|
|
191
|
-
return out
|
|
192
|
-
|
|
193
|
-
# ------------------------------------------------------------------
|
|
194
|
-
# GDPR-model API (used by the compliance route + dashboard)
|
|
195
|
-
# ------------------------------------------------------------------
|
|
196
|
-
|
|
197
|
-
def create_rule(
|
|
198
|
-
self,
|
|
199
|
-
*,
|
|
200
|
-
name: str,
|
|
201
|
-
framework: str,
|
|
202
|
-
retention_days: int,
|
|
203
|
-
action: str,
|
|
204
|
-
applies_to: dict | None,
|
|
205
|
-
profile_id: str,
|
|
206
|
-
) -> int:
|
|
207
|
-
"""Create a retention rule and return its row id.
|
|
208
|
-
|
|
209
|
-
``action`` is one of archive | tombstone | notify. Raises ValueError on
|
|
210
|
-
an invalid action so the route returns a clear 4xx rather than storing
|
|
211
|
-
an unenforceable rule.
|
|
212
|
-
"""
|
|
213
|
-
if action not in _VALID_ACTIONS:
|
|
214
|
-
raise ValueError(f"action must be one of {_VALID_ACTIONS}")
|
|
215
|
-
selectors = applies_to or {}
|
|
216
|
-
if not isinstance(selectors, dict):
|
|
217
|
-
raise ValueError("applies_to must be an object")
|
|
218
|
-
unsupported = set(selectors) - _SUPPORTED_APPLIES_TO
|
|
219
|
-
if unsupported:
|
|
220
|
-
raise ValueError(
|
|
221
|
-
"unsupported applies_to selectors: " + ", ".join(sorted(unsupported))
|
|
222
|
-
)
|
|
223
|
-
cur = self._db.execute(
|
|
224
|
-
"INSERT OR REPLACE INTO retention_rules "
|
|
225
|
-
"(profile_id, rule_name, days, description, framework, action, applies_to) "
|
|
226
|
-
"VALUES (?, ?, ?, ?, ?, ?, ?)",
|
|
227
|
-
(profile_id, name, int(retention_days), "", framework, action,
|
|
228
|
-
json.dumps(selectors, sort_keys=True)),
|
|
229
|
-
)
|
|
230
|
-
self._commit_if_owned()
|
|
231
|
-
logger.info(
|
|
232
|
-
"Created retention rule '%s' (%dd, %s/%s) for profile '%s'",
|
|
233
|
-
name, retention_days, framework, action, profile_id,
|
|
234
|
-
)
|
|
235
|
-
return int(cur.lastrowid or 0)
|
|
236
|
-
|
|
237
|
-
def list_rules(self, profile_id: str | None = None) -> list[dict[str, Any]]:
|
|
238
|
-
"""List rules for one profile, or all rules when profile_id is None."""
|
|
239
|
-
if profile_id is not None:
|
|
240
|
-
return self.get_rules(profile_id)
|
|
241
|
-
rows = self._db.execute(
|
|
242
|
-
"SELECT DISTINCT profile_id FROM retention_rules"
|
|
243
|
-
).fetchall()
|
|
244
|
-
out: list[dict[str, Any]] = []
|
|
245
|
-
for r in rows:
|
|
246
|
-
out.extend(self.get_rules(r[0]))
|
|
247
|
-
return out
|
|
248
|
-
|
|
249
|
-
def delete_rule(self, profile_id: str, name: str) -> bool:
|
|
250
|
-
"""Delete a rule by (profile_id, name). Returns True if a row was removed."""
|
|
251
|
-
cur = self._db.execute(
|
|
252
|
-
"DELETE FROM retention_rules WHERE profile_id = ? AND rule_name = ?",
|
|
253
|
-
(profile_id, name),
|
|
254
|
-
)
|
|
255
|
-
self._commit_if_owned()
|
|
256
|
-
return cur.rowcount > 0
|
|
257
|
-
|
|
258
|
-
# ------------------------------------------------------------------
|
|
259
|
-
# Expiration detection
|
|
260
|
-
# ------------------------------------------------------------------
|
|
261
|
-
|
|
262
|
-
def get_expired_facts(self, profile_id: str) -> list[str]:
|
|
263
|
-
"""Get fact IDs that have exceeded their retention period.
|
|
264
|
-
|
|
265
|
-
Checks each fact's created_at against the profile's shortest
|
|
266
|
-
retention rule. A fact is expired if its age exceeds the
|
|
267
|
-
minimum retention days across all rules for the profile.
|
|
268
|
-
|
|
269
|
-
Args:
|
|
270
|
-
profile_id: Profile to check facts for.
|
|
271
|
-
|
|
272
|
-
Returns:
|
|
273
|
-
List of expired fact IDs (as strings).
|
|
274
|
-
"""
|
|
275
|
-
rules = self.get_rules(profile_id)
|
|
276
|
-
if not rules:
|
|
277
|
-
return []
|
|
278
|
-
|
|
279
|
-
# Use the shortest retention period (most restrictive)
|
|
280
|
-
min_days = min(r["retention_days"] for r in rules)
|
|
281
|
-
|
|
282
|
-
if not self._has_facts_table():
|
|
283
|
-
return []
|
|
284
|
-
|
|
285
|
-
# atomic_facts is keyed by fact_id (TEXT hex), NOT an integer id.
|
|
286
|
-
rows = self._db.execute(
|
|
287
|
-
"SELECT fact_id, created_at FROM atomic_facts WHERE profile_id = ?",
|
|
288
|
-
(profile_id,),
|
|
289
|
-
).fetchall()
|
|
290
|
-
|
|
291
|
-
expired: list[str] = []
|
|
292
|
-
for row in rows:
|
|
293
|
-
fact_id = str(row[0])
|
|
294
|
-
created_at = row[1] if len(row) > 1 else None
|
|
295
|
-
if created_at and self._age_in_days(created_at) > min_days:
|
|
296
|
-
expired.append(fact_id)
|
|
297
|
-
|
|
298
|
-
return expired
|
|
299
|
-
|
|
300
|
-
# ------------------------------------------------------------------
|
|
301
|
-
# Enforcement
|
|
302
|
-
# ------------------------------------------------------------------
|
|
303
|
-
|
|
304
|
-
def enforce(self, profile_id: str) -> dict[str, Any]:
|
|
305
|
-
"""Atomically enforce all rules for one profile."""
|
|
306
|
-
if not self._autocommit and not self._db.in_transaction:
|
|
307
|
-
self._db.execute("BEGIN")
|
|
308
|
-
savepoint = "slm_retention_profile"
|
|
309
|
-
self._db.execute(f"SAVEPOINT {savepoint}")
|
|
310
|
-
try:
|
|
311
|
-
result = self._enforce_uncommitted(profile_id)
|
|
312
|
-
self._db.execute(f"RELEASE SAVEPOINT {savepoint}")
|
|
313
|
-
if self._autocommit:
|
|
314
|
-
self._db.commit()
|
|
315
|
-
return result
|
|
316
|
-
except Exception:
|
|
317
|
-
self._db.execute(f"ROLLBACK TO SAVEPOINT {savepoint}")
|
|
318
|
-
self._db.execute(f"RELEASE SAVEPOINT {savepoint}")
|
|
319
|
-
raise
|
|
320
|
-
|
|
321
|
-
def _enforce_uncommitted(self, profile_id: str) -> dict[str, Any]:
|
|
322
|
-
"""Enforce every retention rule for a profile, honoring each action.
|
|
323
|
-
|
|
324
|
-
For each rule, facts in the profile older than its retention_days are
|
|
325
|
-
moved to the rule's terminal lifecycle zone:
|
|
326
|
-
* archive → lifecycle 'archived' (retained, hidden from recall)
|
|
327
|
-
* tombstone → lifecycle 'tombstoned' (soft-deleted, purgeable)
|
|
328
|
-
* notify → unchanged (only counted, so an operator can act)
|
|
329
|
-
|
|
330
|
-
GDPR-safe: soft-state transitions, never a raw DELETE — erasure is an
|
|
331
|
-
explicit separate operation. All updates are scoped to ``profile_id``
|
|
332
|
-
and keyed by ``fact_id`` (TEXT), fixing the prior ``id``/int() bug that
|
|
333
|
-
made enforcement crash outright.
|
|
334
|
-
|
|
335
|
-
Returns per-action counts + the affected fact ids.
|
|
336
|
-
"""
|
|
337
|
-
rules = self.get_rules(profile_id)
|
|
338
|
-
result: dict[str, Any] = {
|
|
339
|
-
"profile_id": profile_id,
|
|
340
|
-
"archived": 0, "tombstoned": 0, "notified": 0,
|
|
341
|
-
"deleted_count": 0, # legacy alias (== tombstoned)
|
|
342
|
-
"affected_ids": [],
|
|
343
|
-
}
|
|
344
|
-
if not rules or not self._has_facts_table():
|
|
345
|
-
return result
|
|
346
|
-
|
|
347
|
-
fact_columns = {
|
|
348
|
-
row[1] for row in self._db.execute("PRAGMA table_info(atomic_facts)").fetchall()
|
|
349
|
-
}
|
|
350
|
-
selector_columns = sorted(_SUPPORTED_APPLIES_TO & fact_columns)
|
|
351
|
-
selected_columns = ["fact_id", "created_at", *selector_columns]
|
|
352
|
-
rows = self._db.execute(
|
|
353
|
-
f"SELECT {', '.join(selected_columns)} FROM atomic_facts "
|
|
354
|
-
"WHERE profile_id = ?",
|
|
355
|
-
(profile_id,),
|
|
356
|
-
).fetchall()
|
|
357
|
-
facts = [dict(zip(selected_columns, row, strict=True)) for row in rows]
|
|
358
|
-
|
|
359
|
-
affected: set[str] = set()
|
|
360
|
-
for rule in rules:
|
|
361
|
-
action = rule.get("action", "archive")
|
|
362
|
-
days = rule.get("retention_days", rule.get("days", 0))
|
|
363
|
-
selectors = rule.get("applies_to") or {}
|
|
364
|
-
if set(selectors) - set(selector_columns):
|
|
365
|
-
logger.warning(
|
|
366
|
-
"Retention rule %r skipped unsupported/unavailable selectors: %s",
|
|
367
|
-
rule.get("name"),
|
|
368
|
-
sorted(set(selectors) - set(selector_columns)),
|
|
369
|
-
)
|
|
370
|
-
continue
|
|
371
|
-
expired = []
|
|
372
|
-
for fact in facts:
|
|
373
|
-
created_at = fact.get("created_at")
|
|
374
|
-
if not created_at or self._age_in_days(created_at) <= days:
|
|
375
|
-
continue
|
|
376
|
-
matches = True
|
|
377
|
-
for field, expected in selectors.items():
|
|
378
|
-
accepted = expected if isinstance(expected, list) else [expected]
|
|
379
|
-
if fact.get(field) not in accepted:
|
|
380
|
-
matches = False
|
|
381
|
-
break
|
|
382
|
-
if matches:
|
|
383
|
-
expired.append(str(fact["fact_id"]))
|
|
384
|
-
if not expired:
|
|
385
|
-
continue
|
|
386
|
-
if action == "notify":
|
|
387
|
-
result["notified"] += len(expired)
|
|
388
|
-
affected.update(expired)
|
|
389
|
-
continue
|
|
390
|
-
zone = _ACTION_LIFECYCLE.get(action)
|
|
391
|
-
if zone is None:
|
|
392
|
-
continue
|
|
393
|
-
placeholders = ",".join("?" for _ in expired)
|
|
394
|
-
self._db.execute(
|
|
395
|
-
f"UPDATE atomic_facts SET lifecycle = ? "
|
|
396
|
-
f"WHERE profile_id = ? AND fact_id IN ({placeholders})",
|
|
397
|
-
[zone, profile_id, *expired],
|
|
398
|
-
)
|
|
399
|
-
if action in _TOMBSTONE_ACTIONS:
|
|
400
|
-
# Flag purgeable without violating the lifecycle CHECK.
|
|
401
|
-
self._db.execute(
|
|
402
|
-
f"UPDATE atomic_facts SET archive_status = 'tombstoned' "
|
|
403
|
-
f"WHERE profile_id = ? AND fact_id IN ({placeholders})",
|
|
404
|
-
[profile_id, *expired],
|
|
405
|
-
)
|
|
406
|
-
result["archived" if action == "archive" else "tombstoned"] += len(expired)
|
|
407
|
-
affected.update(expired)
|
|
408
|
-
|
|
409
|
-
result["affected_ids"] = sorted(affected)
|
|
410
|
-
result["deleted_count"] = result["tombstoned"] # legacy alias
|
|
411
|
-
logger.info(
|
|
412
|
-
"Retention enforcement for '%s': archived=%d tombstoned=%d notified=%d",
|
|
413
|
-
profile_id, result["archived"], result["tombstoned"], result["notified"],
|
|
414
|
-
)
|
|
415
|
-
return result
|