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,431 +0,0 @@
|
|
|
1
|
-
"""Versioned, read-only contract boundary for Bounded Loops MCP evidence."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
import asyncio
|
|
6
|
-
import hashlib
|
|
7
|
-
import json
|
|
8
|
-
import os
|
|
9
|
-
import shutil
|
|
10
|
-
import stat
|
|
11
|
-
from collections.abc import Awaitable, Callable
|
|
12
|
-
from copy import deepcopy
|
|
13
|
-
from pathlib import Path
|
|
14
|
-
from typing import Any
|
|
15
|
-
|
|
16
|
-
from superlocalmemory.storage.execution_learning import (
|
|
17
|
-
VerifiedExecutionEvidence,
|
|
18
|
-
_seal_verified_execution_evidence,
|
|
19
|
-
)
|
|
20
|
-
|
|
21
|
-
CONTRACT_ID = "bounded-loops.dev/slm-bridge/v1"
|
|
22
|
-
CONTRACT_V2_ID = "bounded-loops.dev/slm-bridge/v2"
|
|
23
|
-
_OBSERVATION_TIMEOUT_SECONDS = 5.0
|
|
24
|
-
_MAX_MCP_TEXT_BYTES = 2 * 1024 * 1024
|
|
25
|
-
_ADVERTISEMENT = {
|
|
26
|
-
"id": CONTRACT_ID,
|
|
27
|
-
"tool": "bl_graph_evidence",
|
|
28
|
-
"operation": "observe_terminal_run",
|
|
29
|
-
}
|
|
30
|
-
_ADVERTISEMENT_V2 = {
|
|
31
|
-
"id": CONTRACT_V2_ID,
|
|
32
|
-
"tool": "bl_graph_execution_evidence",
|
|
33
|
-
"operation": "observe_verified_terminal_run",
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
class BridgeUnavailable(ValueError):
|
|
38
|
-
"""The installed producer does not advertise a compatible bridge contract."""
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
def supports_bridge(capabilities: dict[str, Any]) -> bool:
|
|
42
|
-
"""Negotiate on the declared public contract, never producer semver."""
|
|
43
|
-
advertised = capabilities.get("evidence_contracts")
|
|
44
|
-
return isinstance(advertised, list) and any(
|
|
45
|
-
isinstance(item, dict)
|
|
46
|
-
and all(item.get(key) == value for key, value in _ADVERTISEMENT.items())
|
|
47
|
-
for item in advertised
|
|
48
|
-
)
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
def supports_bridge_v2(capabilities: dict[str, Any]) -> bool:
|
|
52
|
-
"""Negotiate the additive v2 capability without altering v1 semantics."""
|
|
53
|
-
advertised = capabilities.get("evidence_contracts")
|
|
54
|
-
return isinstance(advertised, list) and any(
|
|
55
|
-
isinstance(item, dict)
|
|
56
|
-
and all(item.get(key) == value for key, value in _ADVERTISEMENT_V2.items())
|
|
57
|
-
for item in advertised
|
|
58
|
-
)
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
def _bridge_v2_payload(
|
|
62
|
-
evidence: dict[str, Any], *, profile_id: str, terminal_run: dict[str, Any]
|
|
63
|
-
) -> dict[str, Any]:
|
|
64
|
-
"""Bind v2 evidence to the terminal run independently enumerated this session.
|
|
65
|
-
|
|
66
|
-
A v2 producer cannot promote an arbitrary schema-shaped JSON object: the
|
|
67
|
-
evidence must agree exactly with the separately fetched terminal listing.
|
|
68
|
-
The resulting payload is sealed below before it can reach storage.
|
|
69
|
-
"""
|
|
70
|
-
if evidence.get("contract") != CONTRACT_V2_ID:
|
|
71
|
-
raise BridgeUnavailable("unsupported bounded-loops execution evidence contract")
|
|
72
|
-
required_listing = ("run_ref", "run_id", "run_state", "terminal_at")
|
|
73
|
-
if any(not isinstance(terminal_run.get(field), str) for field in required_listing):
|
|
74
|
-
raise BridgeUnavailable("bounded-loops terminal listing is malformed")
|
|
75
|
-
if any(evidence.get(field) != terminal_run[field] for field in required_listing):
|
|
76
|
-
raise BridgeUnavailable("bounded-loops execution evidence does not match terminal listing")
|
|
77
|
-
payload = deepcopy(evidence)
|
|
78
|
-
payload["profile_id"] = profile_id
|
|
79
|
-
return payload
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
def bridge_payload(evidence: dict[str, Any], *, profile_id: str) -> dict[str, Any]:
|
|
83
|
-
"""Attach active-profile identity after refusing incompatible evidence."""
|
|
84
|
-
if evidence.get("contract") != CONTRACT_ID:
|
|
85
|
-
raise BridgeUnavailable("unsupported bounded-loops evidence contract")
|
|
86
|
-
if evidence.get("eligible_for_learning") is not False:
|
|
87
|
-
raise BridgeUnavailable("bounded-loops evidence is not observation-only")
|
|
88
|
-
# The producer has organisation/project metadata for its own control plane.
|
|
89
|
-
# SLM stores only the v1 observation receipt needed by its profile-scoped
|
|
90
|
-
# learning database; retaining arbitrary producer extensions would turn a
|
|
91
|
-
# versioned contract into an unbounded schema sink.
|
|
92
|
-
fields = (
|
|
93
|
-
"contract",
|
|
94
|
-
"workspace_id",
|
|
95
|
-
"run_ref",
|
|
96
|
-
"run_id",
|
|
97
|
-
"outcome",
|
|
98
|
-
"run_state",
|
|
99
|
-
"demonstration",
|
|
100
|
-
"eligible_for_learning",
|
|
101
|
-
"terminal_at",
|
|
102
|
-
"graph_digest",
|
|
103
|
-
"plan_digest",
|
|
104
|
-
"policy_digest",
|
|
105
|
-
"receipt",
|
|
106
|
-
"nodes",
|
|
107
|
-
)
|
|
108
|
-
if any(field not in evidence for field in fields):
|
|
109
|
-
raise BridgeUnavailable("bounded-loops evidence is missing required v1 fields")
|
|
110
|
-
return {field: deepcopy(evidence[field]) for field in fields} | {"profile_id": profile_id}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
async def observe_terminal_runs(
|
|
114
|
-
call_tool: Callable[[str, dict[str, Any]], Awaitable[dict[str, Any]]], *, profile_id: str
|
|
115
|
-
) -> list[dict[str, Any]]:
|
|
116
|
-
"""Collect only producer-advertised terminal evidence over an injected MCP transport."""
|
|
117
|
-
discovery = await call_tool("bl_capabilities", {})
|
|
118
|
-
if discovery.get("status") != "ok" or not supports_bridge(discovery.get("capabilities", {})):
|
|
119
|
-
raise BridgeUnavailable("bounded-loops does not advertise slm-bridge/v1")
|
|
120
|
-
listing = await call_tool("bl_graph_terminal_runs", {"limit": 100})
|
|
121
|
-
if listing.get("status") != "ok" or listing.get("contract") != CONTRACT_ID:
|
|
122
|
-
raise BridgeUnavailable("bounded-loops terminal listing is unavailable")
|
|
123
|
-
runs = listing.get("runs")
|
|
124
|
-
if not isinstance(runs, list):
|
|
125
|
-
raise BridgeUnavailable("bounded-loops terminal listing is malformed")
|
|
126
|
-
# The producer's limit is advisory. Keep this explicit operation bounded
|
|
127
|
-
# even against a compatible but faulty/malicious producer.
|
|
128
|
-
runs = runs[:100]
|
|
129
|
-
observed: list[dict[str, Any]] = []
|
|
130
|
-
for run in runs:
|
|
131
|
-
if not isinstance(run, dict) or not isinstance(run.get("run_ref"), str):
|
|
132
|
-
raise BridgeUnavailable("bounded-loops terminal listing is malformed")
|
|
133
|
-
response = await call_tool("bl_graph_evidence", {"run_ref": run["run_ref"]})
|
|
134
|
-
if response.get("status") == "unavailable":
|
|
135
|
-
continue
|
|
136
|
-
if response.get("status") != "ok" or not isinstance(response.get("evidence"), dict):
|
|
137
|
-
raise BridgeUnavailable("bounded-loops evidence response is malformed")
|
|
138
|
-
observed.append(bridge_payload(response["evidence"], profile_id=profile_id))
|
|
139
|
-
return observed
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
async def observe_terminal_runs_v2(
|
|
143
|
-
call_tool: Callable[[str, dict[str, Any]], Awaitable[dict[str, Any]]], *, profile_id: str,
|
|
144
|
-
producer_identity: str,
|
|
145
|
-
) -> list[VerifiedExecutionEvidence]:
|
|
146
|
-
"""Collect v2 receipts only after verified local producer provenance.
|
|
147
|
-
|
|
148
|
-
The producer identity is measured by the stdio launcher, not supplied by
|
|
149
|
-
producer JSON. The capability and terminal-listing digests record the
|
|
150
|
-
exact independently observed control-plane statements that authorized
|
|
151
|
-
each sealed payload.
|
|
152
|
-
"""
|
|
153
|
-
if not isinstance(producer_identity, str) or not producer_identity:
|
|
154
|
-
raise BridgeUnavailable("bounded-loops execution producer identity is unavailable")
|
|
155
|
-
discovery = await call_tool("bl_capabilities", {})
|
|
156
|
-
if discovery.get("status") != "ok" or not supports_bridge_v2(discovery.get("capabilities", {})):
|
|
157
|
-
raise BridgeUnavailable("bounded-loops does not advertise slm-bridge/v2")
|
|
158
|
-
listing = await call_tool("bl_graph_terminal_runs", {"limit": 100})
|
|
159
|
-
if (
|
|
160
|
-
listing.get("status") != "ok"
|
|
161
|
-
or listing.get("contract") != CONTRACT_ID
|
|
162
|
-
or not isinstance(listing.get("runs"), list)
|
|
163
|
-
):
|
|
164
|
-
raise BridgeUnavailable("bounded-loops terminal listing is unavailable")
|
|
165
|
-
capability_digest = _canonical_digest(discovery["capabilities"])
|
|
166
|
-
listing_digest = _canonical_digest(listing["runs"])
|
|
167
|
-
observed: list[VerifiedExecutionEvidence] = []
|
|
168
|
-
for run in listing["runs"][:100]:
|
|
169
|
-
if not isinstance(run, dict) or any(
|
|
170
|
-
not isinstance(run.get(field), str)
|
|
171
|
-
for field in ("run_ref", "run_id", "run_state", "terminal_at")
|
|
172
|
-
):
|
|
173
|
-
raise BridgeUnavailable("bounded-loops terminal listing is malformed")
|
|
174
|
-
response = await call_tool("bl_graph_execution_evidence", {"run_ref": run["run_ref"]})
|
|
175
|
-
if response.get("status") == "unavailable":
|
|
176
|
-
continue
|
|
177
|
-
if response.get("status") != "ok" or not isinstance(response.get("evidence"), dict):
|
|
178
|
-
raise BridgeUnavailable("bounded-loops execution evidence response is malformed")
|
|
179
|
-
payload = _bridge_v2_payload(
|
|
180
|
-
response["evidence"], profile_id=profile_id, terminal_run=run
|
|
181
|
-
)
|
|
182
|
-
try:
|
|
183
|
-
observed.append(_seal_verified_execution_evidence(
|
|
184
|
-
payload,
|
|
185
|
-
producer_identity=producer_identity,
|
|
186
|
-
capability_digest=capability_digest,
|
|
187
|
-
terminal_listing_digest=listing_digest,
|
|
188
|
-
))
|
|
189
|
-
except ValueError as exc:
|
|
190
|
-
raise BridgeUnavailable("bounded-loops execution evidence is invalid") from exc
|
|
191
|
-
return observed
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
def _canonical_digest(value: Any) -> str:
|
|
195
|
-
"""Stable audit identity for a negotiated MCP control-plane document."""
|
|
196
|
-
encoded = json.dumps(value, sort_keys=True, separators=(",", ":"), ensure_ascii=False)
|
|
197
|
-
return "sha256:" + hashlib.sha256(encoded.encode("utf-8")).hexdigest()
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
def _file_digest(path: Path, digest: hashlib._Hash) -> None:
|
|
201
|
-
"""Feed one regular file into an already-bound identity hash."""
|
|
202
|
-
try:
|
|
203
|
-
with path.open("rb") as handle:
|
|
204
|
-
for chunk in iter(lambda: handle.read(64 * 1024), b""):
|
|
205
|
-
digest.update(chunk)
|
|
206
|
-
except OSError as exc:
|
|
207
|
-
raise BridgeUnavailable("bounded-loops producer source could not be identified") from exc
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
def _package_source_identity(executable: Path) -> str:
|
|
211
|
-
"""Digest the bounded_loops source loaded by the MCP launcher's venv.
|
|
212
|
-
|
|
213
|
-
The console script is only a shim. Its shebang identifies the interpreter
|
|
214
|
-
whose site-packages directory owns the running MCP server, so bind the
|
|
215
|
-
source files from that environment rather than whichever package happens
|
|
216
|
-
to be importable by SLM itself.
|
|
217
|
-
"""
|
|
218
|
-
try:
|
|
219
|
-
first_line = executable.open("rb").readline(4096).decode("utf-8").strip()
|
|
220
|
-
except (OSError, UnicodeDecodeError) as exc:
|
|
221
|
-
raise BridgeUnavailable("bounded-loops executable has no readable interpreter") from exc
|
|
222
|
-
if not first_line.startswith("#!"):
|
|
223
|
-
raise BridgeUnavailable("bounded-loops executable has no absolute interpreter")
|
|
224
|
-
interpreter = Path(first_line[2:])
|
|
225
|
-
if not interpreter.is_absolute() or not interpreter.is_file():
|
|
226
|
-
raise BridgeUnavailable("bounded-loops executable interpreter is unavailable")
|
|
227
|
-
if interpreter.parent.name not in {"bin", "Scripts"}:
|
|
228
|
-
raise BridgeUnavailable("bounded-loops executable is not an isolated environment launcher")
|
|
229
|
-
environment = interpreter.parent.parent
|
|
230
|
-
candidates = sorted(
|
|
231
|
-
candidate.resolve(strict=True)
|
|
232
|
-
for candidate in (environment / "lib").glob("python*/site-packages/bounded_loops")
|
|
233
|
-
if candidate.is_dir() and not candidate.is_symlink()
|
|
234
|
-
)
|
|
235
|
-
if len(candidates) != 1:
|
|
236
|
-
raise BridgeUnavailable("bounded-loops package source is unavailable or ambiguous")
|
|
237
|
-
package = candidates[0]
|
|
238
|
-
digest = hashlib.sha256()
|
|
239
|
-
source_files = sorted(
|
|
240
|
-
path for path in package.rglob("*.py") if path.is_file() and not path.is_symlink()
|
|
241
|
-
)
|
|
242
|
-
if not source_files:
|
|
243
|
-
raise BridgeUnavailable("bounded-loops package source is empty")
|
|
244
|
-
for path in source_files:
|
|
245
|
-
digest.update(path.relative_to(package).as_posix().encode("utf-8"))
|
|
246
|
-
digest.update(b"\0")
|
|
247
|
-
_file_digest(path, digest)
|
|
248
|
-
digest.update(b"\0")
|
|
249
|
-
return "sha256:" + digest.hexdigest()
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
def _producer_identity(executable: Path) -> str:
|
|
253
|
-
"""Bind the trusted launcher and actual bounded_loops package source."""
|
|
254
|
-
digest = hashlib.sha256()
|
|
255
|
-
digest.update(b"bounded-loops-launcher\0")
|
|
256
|
-
_file_digest(executable, digest)
|
|
257
|
-
digest.update(b"\0bounded-loops-package\0")
|
|
258
|
-
digest.update(_package_source_identity(executable).encode("ascii"))
|
|
259
|
-
return "sha256:" + digest.hexdigest()
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
def _assert_trusted_executable(executable: Path) -> None:
|
|
263
|
-
"""Raise BridgeUnavailable if executable does not pass the bridge trust checks."""
|
|
264
|
-
try:
|
|
265
|
-
st = executable.stat()
|
|
266
|
-
except OSError as exc:
|
|
267
|
-
raise BridgeUnavailable("bounded-loops bridge path is unavailable") from exc
|
|
268
|
-
mode = st.st_mode
|
|
269
|
-
if not stat.S_ISREG(mode) or (
|
|
270
|
-
os.name != "nt" and mode & (stat.S_IWGRP | stat.S_IWOTH)
|
|
271
|
-
):
|
|
272
|
-
raise BridgeUnavailable("bounded-loops executable is not a trusted regular file")
|
|
273
|
-
# Windows trust-check limitation: only S_ISREG applies on Windows.
|
|
274
|
-
# The mode-bit check above (group/other writable) and the uid/owner check
|
|
275
|
-
# below are both skipped because:
|
|
276
|
-
# - Python's os.stat() on Windows returns emulated Unix-style mode bits
|
|
277
|
-
# that do not reflect real ACL permissions; the check would be meaningless.
|
|
278
|
-
# - os.geteuid() does not exist on Windows (AttributeError); st_uid is
|
|
279
|
-
# always 0 there, so the ownership check cannot identify non-root owners.
|
|
280
|
-
# Proper Windows ownership verification requires Win32 ACL APIs (advapi32),
|
|
281
|
-
# which would introduce a heavy optional dependency. Scoped for a future release.
|
|
282
|
-
if os.name != "nt" and st.st_uid not in {0, os.geteuid()}:
|
|
283
|
-
raise BridgeUnavailable("bounded-loops executable owner is not trusted")
|
|
284
|
-
|
|
285
|
-
async def observe_from_stdio(*, command: str, cwd: str, profile_id: str) -> list[dict[str, Any]]:
|
|
286
|
-
"""Run one bounded, explicit MCP 2 observation; never call from recall or remember."""
|
|
287
|
-
executable, workspace = Path(command), Path(cwd)
|
|
288
|
-
if (
|
|
289
|
-
not executable.is_absolute()
|
|
290
|
-
or not executable.is_file()
|
|
291
|
-
or not workspace.is_absolute()
|
|
292
|
-
or not workspace.is_dir()
|
|
293
|
-
or workspace.is_symlink()
|
|
294
|
-
):
|
|
295
|
-
raise BridgeUnavailable(
|
|
296
|
-
"bounded-loops bridge requires an approved executable and workspace"
|
|
297
|
-
)
|
|
298
|
-
try:
|
|
299
|
-
executable = executable.resolve(strict=True)
|
|
300
|
-
workspace = workspace.resolve(strict=True)
|
|
301
|
-
except OSError as exc:
|
|
302
|
-
raise BridgeUnavailable("bounded-loops bridge path is unavailable") from exc
|
|
303
|
-
_assert_trusted_executable(executable)
|
|
304
|
-
|
|
305
|
-
from mcp import ClientSession, StdioServerParameters
|
|
306
|
-
from mcp.client.stdio import stdio_client
|
|
307
|
-
|
|
308
|
-
try:
|
|
309
|
-
parameters = StdioServerParameters(
|
|
310
|
-
command=str(executable), args=[], cwd=str(workspace)
|
|
311
|
-
)
|
|
312
|
-
async with stdio_client(parameters) as (read, write):
|
|
313
|
-
async with ClientSession(
|
|
314
|
-
read,
|
|
315
|
-
write,
|
|
316
|
-
# MCP 2.x passes this directly to AnyIO's timeout machinery,
|
|
317
|
-
# which accepts a numeric duration rather than timedelta.
|
|
318
|
-
read_timeout_seconds=_OBSERVATION_TIMEOUT_SECONDS,
|
|
319
|
-
) as session:
|
|
320
|
-
async def observe() -> list[dict[str, Any]]:
|
|
321
|
-
await session.initialize()
|
|
322
|
-
|
|
323
|
-
async def call(name: str, arguments: dict[str, Any]) -> dict[str, Any]:
|
|
324
|
-
result = await session.call_tool(name, arguments)
|
|
325
|
-
if result.is_error:
|
|
326
|
-
raise BridgeUnavailable(
|
|
327
|
-
"bounded-loops rejected the observation request"
|
|
328
|
-
)
|
|
329
|
-
texts = [item.text for item in result.content if hasattr(item, "text")]
|
|
330
|
-
if len(texts) != 1 or len(texts[0].encode("utf-8")) > _MAX_MCP_TEXT_BYTES:
|
|
331
|
-
raise BridgeUnavailable("bounded-loops returned an invalid MCP payload")
|
|
332
|
-
try:
|
|
333
|
-
payload = json.loads(texts[0])
|
|
334
|
-
except json.JSONDecodeError as exc:
|
|
335
|
-
raise BridgeUnavailable("bounded-loops returned invalid JSON") from exc
|
|
336
|
-
if not isinstance(payload, dict):
|
|
337
|
-
raise BridgeUnavailable("bounded-loops returned an invalid MCP payload")
|
|
338
|
-
return payload
|
|
339
|
-
|
|
340
|
-
return await observe_terminal_runs(call, profile_id=profile_id)
|
|
341
|
-
return await asyncio.wait_for(observe(), timeout=_OBSERVATION_TIMEOUT_SECONDS)
|
|
342
|
-
except BridgeUnavailable:
|
|
343
|
-
raise
|
|
344
|
-
except Exception as exc:
|
|
345
|
-
raise BridgeUnavailable("bounded-loops observation timed out or could not start") from exc
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
async def observe_v2_from_stdio(
|
|
349
|
-
*, command: str, cwd: str, profile_id: str
|
|
350
|
-
) -> list[VerifiedExecutionEvidence]:
|
|
351
|
-
"""Use the same trusted stdio boundary for additive v2 evidence."""
|
|
352
|
-
# Reuse the hardened v1 launcher while selecting only v2 after capability
|
|
353
|
-
# negotiation. The injected helper is intentionally local to this call.
|
|
354
|
-
executable, workspace = Path(command), Path(cwd)
|
|
355
|
-
if (
|
|
356
|
-
not executable.is_absolute()
|
|
357
|
-
or not executable.is_file()
|
|
358
|
-
or not workspace.is_absolute()
|
|
359
|
-
or not workspace.is_dir()
|
|
360
|
-
or workspace.is_symlink()
|
|
361
|
-
):
|
|
362
|
-
raise BridgeUnavailable("bounded-loops bridge requires an approved executable and workspace")
|
|
363
|
-
try:
|
|
364
|
-
executable = executable.resolve(strict=True)
|
|
365
|
-
workspace = workspace.resolve(strict=True)
|
|
366
|
-
except OSError as exc:
|
|
367
|
-
raise BridgeUnavailable("bounded-loops bridge path is unavailable") from exc
|
|
368
|
-
_assert_trusted_executable(executable)
|
|
369
|
-
producer_identity = _producer_identity(executable)
|
|
370
|
-
from mcp import ClientSession, StdioServerParameters
|
|
371
|
-
from mcp.client.stdio import stdio_client
|
|
372
|
-
try:
|
|
373
|
-
parameters = StdioServerParameters(command=str(executable), args=[], cwd=str(workspace))
|
|
374
|
-
async with stdio_client(parameters) as (read, write):
|
|
375
|
-
async with ClientSession(read, write, read_timeout_seconds=_OBSERVATION_TIMEOUT_SECONDS) as session:
|
|
376
|
-
await session.initialize()
|
|
377
|
-
async def call(name: str, arguments: dict[str, Any]) -> dict[str, Any]:
|
|
378
|
-
result = await session.call_tool(name, arguments)
|
|
379
|
-
texts = [item.text for item in result.content if hasattr(item, "text")]
|
|
380
|
-
if result.is_error or len(texts) != 1 or len(texts[0].encode("utf-8")) > _MAX_MCP_TEXT_BYTES:
|
|
381
|
-
raise BridgeUnavailable("bounded-loops returned an invalid MCP payload")
|
|
382
|
-
payload = json.loads(texts[0])
|
|
383
|
-
if not isinstance(payload, dict):
|
|
384
|
-
raise BridgeUnavailable("bounded-loops returned an invalid MCP payload")
|
|
385
|
-
return payload
|
|
386
|
-
return await asyncio.wait_for(
|
|
387
|
-
observe_terminal_runs_v2(
|
|
388
|
-
call,
|
|
389
|
-
profile_id=profile_id,
|
|
390
|
-
producer_identity=producer_identity,
|
|
391
|
-
),
|
|
392
|
-
_OBSERVATION_TIMEOUT_SECONDS,
|
|
393
|
-
)
|
|
394
|
-
except BridgeUnavailable:
|
|
395
|
-
raise
|
|
396
|
-
except Exception as exc:
|
|
397
|
-
raise BridgeUnavailable("bounded-loops execution observation timed out or could not start") from exc
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
async def observe_installed(*, workspace: str, profile_id: str) -> list[dict[str, Any]]:
|
|
401
|
-
"""Observe a user-installed producer without accepting an agent command.
|
|
402
|
-
|
|
403
|
-
Discovery deliberately resolves exactly the public ``bounded-loops-mcp``
|
|
404
|
-
executable. It does not accept a command, shell fragment, or arguments
|
|
405
|
-
from an MCP caller; the only caller-supplied value is the existing project
|
|
406
|
-
workspace whose Bounded Loops state is to be read.
|
|
407
|
-
"""
|
|
408
|
-
command = shutil.which("bounded-loops-mcp")
|
|
409
|
-
if command is None:
|
|
410
|
-
raise BridgeUnavailable("bounded-loops-mcp is not installed")
|
|
411
|
-
if not Path(command).is_absolute():
|
|
412
|
-
raise BridgeUnavailable("bounded-loops-mcp discovery returned an unsafe path")
|
|
413
|
-
if Path(command).resolve().name not in {"bounded-loops-mcp", "bounded-loops-mcp.exe"}:
|
|
414
|
-
raise BridgeUnavailable("bounded-loops-mcp discovery returned an unsafe executable")
|
|
415
|
-
return await observe_from_stdio(
|
|
416
|
-
command=str(Path(command).resolve()), cwd=workspace, profile_id=profile_id
|
|
417
|
-
)
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
async def observe_installed_v2(
|
|
421
|
-
*, workspace: str, profile_id: str
|
|
422
|
-
) -> list[VerifiedExecutionEvidence]:
|
|
423
|
-
"""Observe only from the installed bounded-loops MCP executable."""
|
|
424
|
-
command = shutil.which("bounded-loops-mcp")
|
|
425
|
-
if command is None or not Path(command).is_absolute():
|
|
426
|
-
raise BridgeUnavailable("bounded-loops-mcp is not installed")
|
|
427
|
-
executable = Path(command).resolve()
|
|
428
|
-
if executable.name not in {"bounded-loops-mcp", "bounded-loops-mcp.exe"}:
|
|
429
|
-
raise BridgeUnavailable("bounded-loops-mcp discovery returned an unsafe executable")
|
|
430
|
-
return await observe_v2_from_stdio(command=str(executable), cwd=workspace,
|
|
431
|
-
profile_id=profile_id)
|
|
@@ -1,236 +0,0 @@
|
|
|
1
|
-
"""Read-only public-CLI adapter for bounded-loops v0.5.1 graph receipts.
|
|
2
|
-
|
|
3
|
-
SLM deliberately neither imports bounded-loops nor reimplements its event-log
|
|
4
|
-
grammar. The optional, installed ``bl`` executable is the versioned protocol
|
|
5
|
-
port: its public ``graph status`` command reconstructs and validates a graph
|
|
6
|
-
receipt before SLM accepts the resulting projection.
|
|
7
|
-
|
|
8
|
-
v0.5.1's local receipt is explicitly unverified. Consequently every result
|
|
9
|
-
from this adapter is display/observation evidence only; it cannot promote a
|
|
10
|
-
memory, alter learning, or assert execution authority.
|
|
11
|
-
"""
|
|
12
|
-
|
|
13
|
-
from __future__ import annotations
|
|
14
|
-
|
|
15
|
-
import json
|
|
16
|
-
import os
|
|
17
|
-
import selectors
|
|
18
|
-
import shutil
|
|
19
|
-
import subprocess
|
|
20
|
-
import time
|
|
21
|
-
from dataclasses import dataclass
|
|
22
|
-
from pathlib import Path
|
|
23
|
-
from typing import Any
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
class BoundedLoopsReceiptError(ValueError):
|
|
27
|
-
"""Raised when a bounded-loops v0.5.1 receipt cannot be safely observed."""
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
_VERSION = "0.5.1"
|
|
31
|
-
_TIMEOUT_SECONDS = 15
|
|
32
|
-
_MAX_OUTPUT_BYTES = 2 * 1024 * 1024
|
|
33
|
-
_TERMINAL_STATES = frozenset({"SUCCEEDED", "FAILED", "CANCELLED"})
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
@dataclass(frozen=True)
|
|
37
|
-
class VerifiedBoundedLoopsReceipt:
|
|
38
|
-
"""A normalized, non-promotable projection of a local v0.5.1 receipt."""
|
|
39
|
-
|
|
40
|
-
organization_id: str
|
|
41
|
-
project_id: str
|
|
42
|
-
run_id: str
|
|
43
|
-
terminal_status: str
|
|
44
|
-
receipt_digest: str
|
|
45
|
-
artifact_digests: tuple[str, ...]
|
|
46
|
-
event_count: int
|
|
47
|
-
demonstration: bool
|
|
48
|
-
trust_level: str = "local_unverified"
|
|
49
|
-
eligible_for_learning: bool = False
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
def verify_v051_graph_receipt(
|
|
53
|
-
run_dir: str | Path,
|
|
54
|
-
*,
|
|
55
|
-
bl_executable: str | Path | None = None,
|
|
56
|
-
) -> VerifiedBoundedLoopsReceipt:
|
|
57
|
-
"""Read a v0.5.1 graph run validated by the bounded-loops public CLI.
|
|
58
|
-
|
|
59
|
-
``run_dir`` must be an existing local directory, not a symlink. The
|
|
60
|
-
executable is discovered from the local environment or supplied as an
|
|
61
|
-
absolute path for an explicitly configured integration. Arguments are
|
|
62
|
-
always passed as an argv list, never through a shell.
|
|
63
|
-
"""
|
|
64
|
-
directory = _safe_run_directory(run_dir)
|
|
65
|
-
executable = _resolve_v051_executable(bl_executable)
|
|
66
|
-
status = _command_json(executable, "graph", "status", "--run", str(directory), "--json")
|
|
67
|
-
return _normalize_projection(status)
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
def _safe_run_directory(run_dir: str | Path) -> Path:
|
|
71
|
-
supplied = Path(run_dir)
|
|
72
|
-
if not supplied.is_absolute():
|
|
73
|
-
raise BoundedLoopsReceiptError("run directory must be an absolute path")
|
|
74
|
-
try:
|
|
75
|
-
directory = supplied.resolve(strict=True)
|
|
76
|
-
except OSError as exc:
|
|
77
|
-
raise BoundedLoopsReceiptError("run directory is unavailable") from exc
|
|
78
|
-
if supplied.is_symlink() or not directory.is_dir():
|
|
79
|
-
raise BoundedLoopsReceiptError("run directory must be a real directory")
|
|
80
|
-
return directory
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
def _resolve_v051_executable(configured: str | Path | None) -> str:
|
|
84
|
-
if configured is None:
|
|
85
|
-
discovered = shutil.which("bl")
|
|
86
|
-
if discovered is None:
|
|
87
|
-
raise BoundedLoopsReceiptError("bounded-loops v0.5.1 is not installed")
|
|
88
|
-
executable = Path(discovered)
|
|
89
|
-
else:
|
|
90
|
-
executable = Path(configured)
|
|
91
|
-
if not executable.is_absolute():
|
|
92
|
-
raise BoundedLoopsReceiptError("configured bl executable must be an absolute path")
|
|
93
|
-
try:
|
|
94
|
-
resolved = executable.resolve(strict=True)
|
|
95
|
-
except OSError as exc:
|
|
96
|
-
raise BoundedLoopsReceiptError("configured bl executable is unavailable") from exc
|
|
97
|
-
if not resolved.is_file():
|
|
98
|
-
raise BoundedLoopsReceiptError("configured bl executable is not a file")
|
|
99
|
-
version = _run_command(str(resolved), "--version")
|
|
100
|
-
if version.strip() != f"bl {_VERSION}":
|
|
101
|
-
raise BoundedLoopsReceiptError("bounded-loops executable must be exactly v0.5.1")
|
|
102
|
-
return str(resolved)
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
def _command_json(executable: str, *arguments: str) -> Any:
|
|
106
|
-
output = _run_command(executable, *arguments)
|
|
107
|
-
try:
|
|
108
|
-
return json.loads(output)
|
|
109
|
-
except json.JSONDecodeError as exc:
|
|
110
|
-
raise BoundedLoopsReceiptError("bounded-loops returned invalid JSON") from exc
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
def _run_command(executable: str, *arguments: str) -> str:
|
|
114
|
-
try:
|
|
115
|
-
process = subprocess.Popen(
|
|
116
|
-
[executable, *arguments],
|
|
117
|
-
stdout=subprocess.PIPE,
|
|
118
|
-
stderr=subprocess.PIPE,
|
|
119
|
-
)
|
|
120
|
-
stdout = _read_bounded_output(process)
|
|
121
|
-
except (OSError, subprocess.TimeoutExpired) as exc:
|
|
122
|
-
raise BoundedLoopsReceiptError("bounded-loops command did not complete") from exc
|
|
123
|
-
if process.returncode != 0:
|
|
124
|
-
raise BoundedLoopsReceiptError("bounded-loops rejected the graph receipt")
|
|
125
|
-
try:
|
|
126
|
-
return stdout.decode("utf-8")
|
|
127
|
-
except UnicodeDecodeError as exc:
|
|
128
|
-
raise BoundedLoopsReceiptError("bounded-loops response is not UTF-8") from exc
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
def _read_bounded_output(process: subprocess.Popen[bytes]) -> bytes:
|
|
132
|
-
"""Read both pipes incrementally and terminate output that exceeds the cap."""
|
|
133
|
-
if process.stdout is None or process.stderr is None:
|
|
134
|
-
raise BoundedLoopsReceiptError("bounded-loops command pipes are unavailable")
|
|
135
|
-
selector = selectors.DefaultSelector()
|
|
136
|
-
selector.register(process.stdout, selectors.EVENT_READ, data="stdout")
|
|
137
|
-
selector.register(process.stderr, selectors.EVENT_READ, data="stderr")
|
|
138
|
-
deadline = time.monotonic() + _TIMEOUT_SECONDS
|
|
139
|
-
stdout = bytearray()
|
|
140
|
-
total = 0
|
|
141
|
-
try:
|
|
142
|
-
while selector.get_map():
|
|
143
|
-
remaining = deadline - time.monotonic()
|
|
144
|
-
if remaining <= 0:
|
|
145
|
-
process.kill()
|
|
146
|
-
process.wait()
|
|
147
|
-
raise subprocess.TimeoutExpired(process.args, _TIMEOUT_SECONDS)
|
|
148
|
-
for key, _ in selector.select(remaining):
|
|
149
|
-
descriptor = (
|
|
150
|
-
key.fileobj if isinstance(key.fileobj, int) else key.fileobj.fileno()
|
|
151
|
-
)
|
|
152
|
-
chunk = os.read(descriptor, 64 * 1024)
|
|
153
|
-
if not chunk:
|
|
154
|
-
selector.unregister(key.fileobj)
|
|
155
|
-
continue
|
|
156
|
-
total += len(chunk)
|
|
157
|
-
if total > _MAX_OUTPUT_BYTES:
|
|
158
|
-
process.kill()
|
|
159
|
-
process.wait()
|
|
160
|
-
raise BoundedLoopsReceiptError(
|
|
161
|
-
"bounded-loops response exceeds the import size limit"
|
|
162
|
-
)
|
|
163
|
-
if key.data == "stdout":
|
|
164
|
-
stdout.extend(chunk)
|
|
165
|
-
process.wait(timeout=max(0.001, deadline - time.monotonic()))
|
|
166
|
-
finally:
|
|
167
|
-
selector.close()
|
|
168
|
-
if process.poll() is None:
|
|
169
|
-
process.kill()
|
|
170
|
-
process.wait()
|
|
171
|
-
return bytes(stdout)
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
def _normalize_projection(status: Any) -> VerifiedBoundedLoopsReceipt:
|
|
175
|
-
if not isinstance(status, dict):
|
|
176
|
-
raise BoundedLoopsReceiptError("bounded-loops response has an invalid shape")
|
|
177
|
-
required_strings = (
|
|
178
|
-
"organization_id", "project_id", "run_id", "run_state", "receipt_head_hash",
|
|
179
|
-
)
|
|
180
|
-
if any(not isinstance(status.get(name), str) or not status[name] for name in required_strings):
|
|
181
|
-
raise BoundedLoopsReceiptError("bounded-loops status lacks required receipt fields")
|
|
182
|
-
if status["run_state"] not in _TERMINAL_STATES:
|
|
183
|
-
raise BoundedLoopsReceiptError("bounded-loops receipt is not terminal")
|
|
184
|
-
if status.get("verified") is not False:
|
|
185
|
-
raise BoundedLoopsReceiptError("unexpected bounded-loops receipt verification state")
|
|
186
|
-
sequence = status.get("receipt_sequence")
|
|
187
|
-
if isinstance(sequence, bool) or not isinstance(sequence, int) or sequence < 1:
|
|
188
|
-
raise BoundedLoopsReceiptError("bounded-loops receipt sequence is invalid")
|
|
189
|
-
if not _is_hash(status["receipt_head_hash"]):
|
|
190
|
-
raise BoundedLoopsReceiptError("bounded-loops receipt digest is invalid")
|
|
191
|
-
artifact_digests = _projection_artifact_digests(status.get("nodes"))
|
|
192
|
-
demonstration = status.get("demonstration")
|
|
193
|
-
if not isinstance(demonstration, bool):
|
|
194
|
-
raise BoundedLoopsReceiptError("bounded-loops demonstration marker is invalid")
|
|
195
|
-
return VerifiedBoundedLoopsReceipt(
|
|
196
|
-
organization_id=status["organization_id"],
|
|
197
|
-
project_id=status["project_id"],
|
|
198
|
-
run_id=status["run_id"],
|
|
199
|
-
terminal_status=status["run_state"],
|
|
200
|
-
receipt_digest=f"sha256:{status['receipt_head_hash']}",
|
|
201
|
-
artifact_digests=artifact_digests,
|
|
202
|
-
event_count=sequence,
|
|
203
|
-
demonstration=demonstration,
|
|
204
|
-
)
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
def _projection_artifact_digests(nodes: Any) -> tuple[str, ...]:
|
|
208
|
-
"""Read only event-log-bound artifacts from the verified arena projection."""
|
|
209
|
-
if not isinstance(nodes, list):
|
|
210
|
-
raise BoundedLoopsReceiptError("bounded-loops status lacks node projections")
|
|
211
|
-
digests: set[str] = set()
|
|
212
|
-
for node in nodes:
|
|
213
|
-
if not isinstance(node, dict):
|
|
214
|
-
raise BoundedLoopsReceiptError("bounded-loops node projection is invalid")
|
|
215
|
-
raw_digests = node.get("artifact_digests")
|
|
216
|
-
if not isinstance(raw_digests, list) or not all(_is_digest(value) for value in raw_digests):
|
|
217
|
-
raise BoundedLoopsReceiptError("bounded-loops node artifact digests are invalid")
|
|
218
|
-
digests.update(raw_digests)
|
|
219
|
-
return tuple(sorted(digests))
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
def _is_digest(value: object) -> bool:
|
|
223
|
-
return (
|
|
224
|
-
isinstance(value, str)
|
|
225
|
-
and value.startswith("sha256:")
|
|
226
|
-
and len(value) == 71
|
|
227
|
-
and all(character in "0123456789abcdef" for character in value[7:])
|
|
228
|
-
)
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
def _is_hash(value: object) -> bool:
|
|
232
|
-
return (
|
|
233
|
-
isinstance(value, str)
|
|
234
|
-
and len(value) == 64
|
|
235
|
-
and all(character in "0123456789abcdef" for character in value)
|
|
236
|
-
)
|
|
File without changes
|