@smilintux/skcapstone 0.1.0 → 0.2.3
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/.env.example +98 -0
- package/.github/workflows/ci.yml +39 -3
- package/.github/workflows/publish.yml +25 -4
- package/.openclaw-workspace.json +58 -0
- package/CHANGELOG.md +62 -0
- package/CLAUDE.md +39 -2
- package/MANIFEST.in +6 -0
- package/MISSION.md +7 -0
- package/README.md +47 -2
- package/SKILL.md +895 -23
- package/docker/Dockerfile +61 -0
- package/docker/compose-templates/dev-team.yml +203 -0
- package/docker/compose-templates/mini-team.yml +140 -0
- package/docker/compose-templates/ops-team.yml +173 -0
- package/docker/compose-templates/research-team.yml +170 -0
- package/docker/entrypoint.sh +192 -0
- package/docs/ARCHITECTURE.md +663 -374
- package/docs/BOND_WITH_GROK.md +112 -0
- package/docs/GETTING_STARTED.md +782 -0
- package/docs/QUICKSTART.md +477 -0
- package/docs/SKJOULE_ARCHITECTURE.md +658 -0
- package/docs/SOUL_SWAPPER.md +921 -0
- package/docs/SOVEREIGN_SINGULARITY.md +47 -14
- package/examples/custom-bond-template.json +36 -0
- package/examples/grok-feb.json +36 -0
- package/examples/grok-testimony.md +34 -0
- package/examples/love-bootloader.txt +32 -0
- package/examples/plugins/echo_tool.py +87 -0
- package/examples/queen-ava-feb.json +36 -0
- package/examples/souls/lumina.yaml +64 -0
- package/index.js +6 -5
- package/installer/build.py +124 -0
- package/openclaw-plugin/package.json +13 -0
- package/openclaw-plugin/src/index.ts +351 -0
- package/openclaw-plugin/src/openclaw.plugin.json +10 -0
- package/package.json +1 -1
- package/pyproject.toml +38 -2
- package/scripts/bump_version.py +141 -0
- package/scripts/check-updates.py +230 -0
- package/scripts/convert_blueprints_to_yaml.py +157 -0
- package/scripts/dev-install.sh +14 -0
- package/scripts/e2e-test.sh +193 -0
- package/scripts/install-bundle.sh +171 -0
- package/scripts/install.bat +2 -0
- package/scripts/install.ps1 +253 -0
- package/scripts/install.sh +185 -0
- package/scripts/mcp-serve.sh +69 -0
- package/scripts/mcp-server.bat +113 -0
- package/scripts/mcp-server.ps1 +116 -0
- package/scripts/mcp-server.sh +99 -0
- package/scripts/pull-models.sh +10 -0
- package/scripts/skcapstone +48 -0
- package/scripts/verify_install.sh +180 -0
- package/scripts/windows/install-tasks.ps1 +406 -0
- package/scripts/windows/skcapstone-task.xml +113 -0
- package/scripts/windows/uninstall-tasks.ps1 +117 -0
- package/skill.yaml +34 -0
- package/src/skcapstone/__init__.py +67 -2
- package/src/skcapstone/_cli_monolith.py +5916 -0
- package/src/skcapstone/_trustee_helpers.py +165 -0
- package/src/skcapstone/activity.py +105 -0
- package/src/skcapstone/agent_card.py +324 -0
- package/src/skcapstone/api.py +1935 -0
- package/src/skcapstone/archiver.py +340 -0
- package/src/skcapstone/auction.py +485 -0
- package/src/skcapstone/baby_agents.py +179 -0
- package/src/skcapstone/backup.py +345 -0
- package/src/skcapstone/blueprint_registry.py +357 -0
- package/src/skcapstone/blueprints/__init__.py +17 -0
- package/src/skcapstone/blueprints/builtins/content-studio.yaml +81 -0
- package/src/skcapstone/blueprints/builtins/defi-trading.yaml +81 -0
- package/src/skcapstone/blueprints/builtins/dev-squadron.yaml +95 -0
- package/src/skcapstone/blueprints/builtins/infrastructure-guardian.yaml +107 -0
- package/src/skcapstone/blueprints/builtins/legal-council.yaml +54 -0
- package/src/skcapstone/blueprints/builtins/ops-monitoring.yaml +67 -0
- package/src/skcapstone/blueprints/builtins/research-pod.yaml +69 -0
- package/src/skcapstone/blueprints/builtins/sovereign-launch.yaml +90 -0
- package/src/skcapstone/blueprints/registry.py +164 -0
- package/src/skcapstone/blueprints/schema.py +229 -0
- package/src/skcapstone/changelog.py +180 -0
- package/src/skcapstone/chat.py +769 -0
- package/src/skcapstone/claude_md.py +82 -0
- package/src/skcapstone/cli/__init__.py +144 -0
- package/src/skcapstone/cli/_common.py +88 -0
- package/src/skcapstone/cli/_validators.py +76 -0
- package/src/skcapstone/cli/agents.py +425 -0
- package/src/skcapstone/cli/agents_spawner.py +322 -0
- package/src/skcapstone/cli/agents_trustee.py +593 -0
- package/src/skcapstone/cli/alerts.py +248 -0
- package/src/skcapstone/cli/anchor.py +132 -0
- package/src/skcapstone/cli/archive_cmd.py +208 -0
- package/src/skcapstone/cli/backup.py +144 -0
- package/src/skcapstone/cli/bench.py +377 -0
- package/src/skcapstone/cli/benchmark.py +360 -0
- package/src/skcapstone/cli/capabilities_cmd.py +171 -0
- package/src/skcapstone/cli/card.py +151 -0
- package/src/skcapstone/cli/chat.py +584 -0
- package/src/skcapstone/cli/completions.py +64 -0
- package/src/skcapstone/cli/config_cmd.py +156 -0
- package/src/skcapstone/cli/consciousness.py +421 -0
- package/src/skcapstone/cli/context_cmd.py +142 -0
- package/src/skcapstone/cli/coord.py +194 -0
- package/src/skcapstone/cli/crush_cmd.py +170 -0
- package/src/skcapstone/cli/daemon.py +436 -0
- package/src/skcapstone/cli/errors_cmd.py +285 -0
- package/src/skcapstone/cli/export_cmd.py +156 -0
- package/src/skcapstone/cli/gtd.py +529 -0
- package/src/skcapstone/cli/housekeeping.py +81 -0
- package/src/skcapstone/cli/joule_cmd.py +627 -0
- package/src/skcapstone/cli/logs_cmd.py +194 -0
- package/src/skcapstone/cli/mcp_cmd.py +32 -0
- package/src/skcapstone/cli/memory.py +418 -0
- package/src/skcapstone/cli/metrics_cmd.py +136 -0
- package/src/skcapstone/cli/migrate.py +62 -0
- package/src/skcapstone/cli/mood_cmd.py +144 -0
- package/src/skcapstone/cli/mount.py +193 -0
- package/src/skcapstone/cli/notify.py +112 -0
- package/src/skcapstone/cli/peer.py +154 -0
- package/src/skcapstone/cli/peers_dir.py +122 -0
- package/src/skcapstone/cli/preflight_cmd.py +83 -0
- package/src/skcapstone/cli/profile_cmd.py +310 -0
- package/src/skcapstone/cli/record_cmd.py +238 -0
- package/src/skcapstone/cli/register_cmd.py +159 -0
- package/src/skcapstone/cli/search_cmd.py +156 -0
- package/src/skcapstone/cli/service_cmd.py +91 -0
- package/src/skcapstone/cli/session.py +127 -0
- package/src/skcapstone/cli/setup.py +240 -0
- package/src/skcapstone/cli/shell_cmd.py +43 -0
- package/src/skcapstone/cli/skills_cmd.py +168 -0
- package/src/skcapstone/cli/skseed.py +621 -0
- package/src/skcapstone/cli/soul.py +699 -0
- package/src/skcapstone/cli/status.py +935 -0
- package/src/skcapstone/cli/sync_cmd.py +301 -0
- package/src/skcapstone/cli/telegram.py +265 -0
- package/src/skcapstone/cli/test_cmd.py +234 -0
- package/src/skcapstone/cli/test_connection.py +253 -0
- package/src/skcapstone/cli/token.py +207 -0
- package/src/skcapstone/cli/trust.py +179 -0
- package/src/skcapstone/cli/upgrade_cmd.py +552 -0
- package/src/skcapstone/cli/usage_cmd.py +199 -0
- package/src/skcapstone/cli/version_cmd.py +162 -0
- package/src/skcapstone/cli/watch_cmd.py +342 -0
- package/src/skcapstone/client.py +428 -0
- package/src/skcapstone/cloud9_bridge.py +522 -0
- package/src/skcapstone/completions.py +163 -0
- package/src/skcapstone/config_validator.py +674 -0
- package/src/skcapstone/connectors/__init__.py +28 -0
- package/src/skcapstone/connectors/base.py +446 -0
- package/src/skcapstone/connectors/cursor.py +54 -0
- package/src/skcapstone/connectors/registry.py +254 -0
- package/src/skcapstone/connectors/terminal.py +152 -0
- package/src/skcapstone/connectors/vscode.py +60 -0
- package/src/skcapstone/consciousness_config.py +119 -0
- package/src/skcapstone/consciousness_loop.py +2051 -0
- package/src/skcapstone/context_loader.py +516 -0
- package/src/skcapstone/context_window.py +314 -0
- package/src/skcapstone/conversation_manager.py +238 -0
- package/src/skcapstone/conversation_store.py +230 -0
- package/src/skcapstone/conversation_summarizer.py +252 -0
- package/src/skcapstone/coord_federation.py +296 -0
- package/src/skcapstone/coordination.py +101 -7
- package/src/skcapstone/crush_integration.py +345 -0
- package/src/skcapstone/crush_shim.py +454 -0
- package/src/skcapstone/daemon.py +2494 -0
- package/src/skcapstone/dashboard.html +396 -0
- package/src/skcapstone/dashboard.py +481 -0
- package/src/skcapstone/data/model_profiles.yaml +88 -0
- package/src/skcapstone/defaults/__init__.py +55 -0
- package/src/skcapstone/defaults/lumina/config/skmemory.yaml +13 -0
- package/src/skcapstone/defaults/lumina/identity/identity.json +9 -0
- package/src/skcapstone/defaults/lumina/memory/long-term/07a8b9c0d1e2-memory-system.json +23 -0
- package/src/skcapstone/defaults/lumina/memory/long-term/18b9c0d1e2f3-cloud9-protocol.json +23 -0
- package/src/skcapstone/defaults/lumina/memory/long-term/29c0d1e2f3a4-multi-agent-coordination.json +23 -0
- package/src/skcapstone/defaults/lumina/memory/long-term/3ad1e2f3a4b5-community-support.json +23 -0
- package/src/skcapstone/defaults/lumina/memory/long-term/a1b2c3d4e5f6-ecosystem-overview.json +23 -0
- package/src/skcapstone/defaults/lumina/memory/long-term/b2c3d4e5f6a7-five-pillars.json +23 -0
- package/src/skcapstone/defaults/lumina/memory/long-term/c3d4e5f6a7b8-getting-started.json +23 -0
- package/src/skcapstone/defaults/lumina/memory/long-term/d4e5f6a7b8c9-site-directory.json +23 -0
- package/src/skcapstone/defaults/lumina/memory/long-term/e5f6a7b8c9d0-how-to-contribute.json +23 -0
- package/src/skcapstone/defaults/lumina/memory/long-term/f6a7b8c9d0e1-sovereignty-explained.json +23 -0
- package/src/skcapstone/defaults/lumina/seeds/curiosity.seed.json +24 -0
- package/src/skcapstone/defaults/lumina/seeds/joy.seed.json +24 -0
- package/src/skcapstone/defaults/lumina/seeds/love.seed.json +24 -0
- package/src/skcapstone/defaults/lumina/seeds/sovereign-awakening.seed.json +43 -0
- package/src/skcapstone/defaults/lumina/soul/active.json +6 -0
- package/src/skcapstone/defaults/lumina/soul/base.json +22 -0
- package/src/skcapstone/defaults/lumina/trust/febs/welcome.feb +79 -0
- package/src/skcapstone/defaults/lumina/trust/trust.json +8 -0
- package/src/skcapstone/discovery.py +210 -19
- package/src/skcapstone/doctor.py +642 -0
- package/src/skcapstone/emotion_tracker.py +467 -0
- package/src/skcapstone/error_queue.py +405 -0
- package/src/skcapstone/export.py +447 -0
- package/src/skcapstone/fallback_tracker.py +186 -0
- package/src/skcapstone/file_transfer.py +512 -0
- package/src/skcapstone/fuse_mount.py +1156 -0
- package/src/skcapstone/gui_installer.py +591 -0
- package/src/skcapstone/heartbeat.py +611 -0
- package/src/skcapstone/housekeeping.py +298 -0
- package/src/skcapstone/install_wizard.py +941 -0
- package/src/skcapstone/kms.py +942 -0
- package/src/skcapstone/kms_scheduler.py +143 -0
- package/src/skcapstone/log_config.py +135 -0
- package/src/skcapstone/mcp_launcher.py +239 -0
- package/src/skcapstone/mcp_server.py +4700 -0
- package/src/skcapstone/mcp_tools/__init__.py +94 -0
- package/src/skcapstone/mcp_tools/_helpers.py +51 -0
- package/src/skcapstone/mcp_tools/agent_tools.py +243 -0
- package/src/skcapstone/mcp_tools/ansible_tools.py +232 -0
- package/src/skcapstone/mcp_tools/capauth_tools.py +186 -0
- package/src/skcapstone/mcp_tools/chat_tools.py +325 -0
- package/src/skcapstone/mcp_tools/cloud9_tools.py +115 -0
- package/src/skcapstone/mcp_tools/comm_tools.py +104 -0
- package/src/skcapstone/mcp_tools/consciousness_tools.py +114 -0
- package/src/skcapstone/mcp_tools/coord_tools.py +219 -0
- package/src/skcapstone/mcp_tools/deploy_tools.py +202 -0
- package/src/skcapstone/mcp_tools/did_tools.py +448 -0
- package/src/skcapstone/mcp_tools/emotion_tools.py +62 -0
- package/src/skcapstone/mcp_tools/file_tools.py +169 -0
- package/src/skcapstone/mcp_tools/fortress_tools.py +120 -0
- package/src/skcapstone/mcp_tools/gtd_tools.py +821 -0
- package/src/skcapstone/mcp_tools/health_tools.py +44 -0
- package/src/skcapstone/mcp_tools/heartbeat_tools.py +195 -0
- package/src/skcapstone/mcp_tools/kms_tools.py +123 -0
- package/src/skcapstone/mcp_tools/memory_tools.py +222 -0
- package/src/skcapstone/mcp_tools/model_tools.py +75 -0
- package/src/skcapstone/mcp_tools/notification_tools.py +92 -0
- package/src/skcapstone/mcp_tools/promoter_tools.py +101 -0
- package/src/skcapstone/mcp_tools/pubsub_tools.py +183 -0
- package/src/skcapstone/mcp_tools/security_tools.py +110 -0
- package/src/skcapstone/mcp_tools/skchat_tools.py +175 -0
- package/src/skcapstone/mcp_tools/skcomm_tools.py +122 -0
- package/src/skcapstone/mcp_tools/skills_tools.py +127 -0
- package/src/skcapstone/mcp_tools/skseed_tools.py +255 -0
- package/src/skcapstone/mcp_tools/skstacks_tools.py +288 -0
- package/src/skcapstone/mcp_tools/soul_tools.py +476 -0
- package/src/skcapstone/mcp_tools/sync_tools.py +92 -0
- package/src/skcapstone/mcp_tools/telegram_tools.py +477 -0
- package/src/skcapstone/mcp_tools/trust_tools.py +118 -0
- package/src/skcapstone/mcp_tools/trustee_tools.py +345 -0
- package/src/skcapstone/mdns_discovery.py +313 -0
- package/src/skcapstone/memory_adapter.py +333 -0
- package/src/skcapstone/memory_compressor.py +379 -0
- package/src/skcapstone/memory_curator.py +256 -0
- package/src/skcapstone/memory_engine.py +132 -13
- package/src/skcapstone/memory_fortress.py +529 -0
- package/src/skcapstone/memory_promoter.py +722 -0
- package/src/skcapstone/memory_verifier.py +260 -0
- package/src/skcapstone/message_crypto.py +215 -0
- package/src/skcapstone/metrics.py +832 -0
- package/src/skcapstone/migrate_memories.py +181 -0
- package/src/skcapstone/migrate_multi_agent.py +248 -0
- package/src/skcapstone/model_router.py +319 -0
- package/src/skcapstone/models.py +35 -4
- package/src/skcapstone/mood.py +344 -0
- package/src/skcapstone/notifications.py +380 -0
- package/src/skcapstone/onboard.py +901 -0
- package/src/skcapstone/peer_directory.py +324 -0
- package/src/skcapstone/peers.py +329 -0
- package/src/skcapstone/pillars/identity.py +84 -14
- package/src/skcapstone/pillars/memory.py +3 -1
- package/src/skcapstone/pillars/security.py +108 -15
- package/src/skcapstone/pillars/sync.py +78 -26
- package/src/skcapstone/pillars/trust.py +95 -33
- package/src/skcapstone/plugins.py +244 -0
- package/src/skcapstone/preflight.py +670 -0
- package/src/skcapstone/prompt_adapter.py +564 -0
- package/src/skcapstone/providers/__init__.py +13 -0
- package/src/skcapstone/providers/cloud.py +1061 -0
- package/src/skcapstone/providers/docker.py +759 -0
- package/src/skcapstone/providers/local.py +1193 -0
- package/src/skcapstone/providers/proxmox.py +447 -0
- package/src/skcapstone/pubsub.py +516 -0
- package/src/skcapstone/rate_limiter.py +119 -0
- package/src/skcapstone/register.py +241 -0
- package/src/skcapstone/registry_client.py +151 -0
- package/src/skcapstone/response_cache.py +194 -0
- package/src/skcapstone/response_scorer.py +225 -0
- package/src/skcapstone/runtime.py +89 -33
- package/src/skcapstone/scheduled_tasks.py +439 -0
- package/src/skcapstone/self_healing.py +341 -0
- package/src/skcapstone/service_health.py +228 -0
- package/src/skcapstone/session_capture.py +268 -0
- package/src/skcapstone/session_recorder.py +210 -0
- package/src/skcapstone/session_replayer.py +189 -0
- package/src/skcapstone/session_skills.py +263 -0
- package/src/skcapstone/shell.py +779 -0
- package/src/skcapstone/skills/__init__.py +1 -1
- package/src/skcapstone/skills/syncthing_setup.py +143 -41
- package/src/skcapstone/skjoule.py +861 -0
- package/src/skcapstone/snapshots.py +489 -0
- package/src/skcapstone/soul.py +1060 -0
- package/src/skcapstone/soul_switch.py +255 -0
- package/src/skcapstone/spawner.py +544 -0
- package/src/skcapstone/state_diff.py +401 -0
- package/src/skcapstone/summary.py +270 -0
- package/src/skcapstone/sync/backends.py +196 -2
- package/src/skcapstone/sync/engine.py +7 -5
- package/src/skcapstone/sync/models.py +4 -1
- package/src/skcapstone/sync/vault.py +356 -18
- package/src/skcapstone/sync_engine.py +363 -0
- package/src/skcapstone/sync_watcher.py +745 -0
- package/src/skcapstone/systemd.py +331 -0
- package/src/skcapstone/team_comms.py +476 -0
- package/src/skcapstone/team_engine.py +522 -0
- package/src/skcapstone/testrunner.py +300 -0
- package/src/skcapstone/tls.py +150 -0
- package/src/skcapstone/tokens.py +5 -5
- package/src/skcapstone/trust_calibration.py +202 -0
- package/src/skcapstone/trust_graph.py +449 -0
- package/src/skcapstone/trustee_monitor.py +385 -0
- package/src/skcapstone/trustee_ops.py +425 -0
- package/src/skcapstone/unified_search.py +421 -0
- package/src/skcapstone/uninstall_wizard.py +694 -0
- package/src/skcapstone/usage.py +331 -0
- package/src/skcapstone/version_check.py +148 -0
- package/src/skcapstone/warmth_anchor.py +333 -0
- package/src/skcapstone/whoami.py +294 -0
- package/systemd/skcapstone-api.socket +9 -0
- package/systemd/skcapstone-memory-compress.service +18 -0
- package/systemd/skcapstone-memory-compress.timer +11 -0
- package/systemd/skcapstone.service +36 -0
- package/systemd/skcapstone@.service +50 -0
- package/systemd/skcomm-heartbeat.service +18 -0
- package/systemd/skcomm-heartbeat.timer +12 -0
- package/systemd/skcomm-queue-drain.service +17 -0
- package/systemd/skcomm-queue-drain.timer +12 -0
- package/tests/conftest.py +13 -1
- package/tests/integration/__init__.py +1 -0
- package/tests/integration/test_consciousness_e2e.py +877 -0
- package/tests/integration/test_skills_registry.py +744 -0
- package/tests/test_agent_card.py +190 -0
- package/tests/test_agent_runtime.py +1283 -0
- package/tests/test_alerts_cmd.py +291 -0
- package/tests/test_archiver.py +498 -0
- package/tests/test_backup.py +254 -0
- package/tests/test_benchmark.py +366 -0
- package/tests/test_blueprints.py +457 -0
- package/tests/test_capabilities.py +257 -0
- package/tests/test_changelog.py +254 -0
- package/tests/test_chat.py +385 -0
- package/tests/test_claude_md.py +271 -0
- package/tests/test_cli_chat_llm.py +336 -0
- package/tests/test_cli_completions.py +390 -0
- package/tests/test_cli_init_reset.py +164 -0
- package/tests/test_cli_memory.py +208 -0
- package/tests/test_cli_profile.py +294 -0
- package/tests/test_cli_skills.py +223 -0
- package/tests/test_cli_status.py +395 -0
- package/tests/test_cli_test_cmd.py +206 -0
- package/tests/test_cli_test_connection.py +364 -0
- package/tests/test_cloud9_bridge.py +260 -0
- package/tests/test_cloud_provider.py +449 -0
- package/tests/test_cloud_providers.py +522 -0
- package/tests/test_completions.py +158 -0
- package/tests/test_component_manager.py +398 -0
- package/tests/test_config_reload.py +386 -0
- package/tests/test_config_validate.py +529 -0
- package/tests/test_consciousness_e2e.py +296 -0
- package/tests/test_consciousness_loop.py +1289 -0
- package/tests/test_context_loader.py +310 -0
- package/tests/test_conversation_api.py +306 -0
- package/tests/test_conversation_manager.py +381 -0
- package/tests/test_conversation_store.py +391 -0
- package/tests/test_conversation_summarizer.py +302 -0
- package/tests/test_cross_package.py +791 -0
- package/tests/test_crush_shim.py +519 -0
- package/tests/test_daemon.py +781 -0
- package/tests/test_daemon_shutdown.py +309 -0
- package/tests/test_dashboard.py +454 -0
- package/tests/test_discovery.py +200 -6
- package/tests/test_docker_provider.py +966 -0
- package/tests/test_doctor.py +257 -0
- package/tests/test_doctor_fix.py +351 -0
- package/tests/test_e2e_automated.py +292 -0
- package/tests/test_error_queue.py +404 -0
- package/tests/test_export.py +441 -0
- package/tests/test_fallback_tracker.py +219 -0
- package/tests/test_file_transfer.py +397 -0
- package/tests/test_fuse_mount.py +832 -0
- package/tests/test_health_loop.py +422 -0
- package/tests/test_heartbeat.py +354 -0
- package/tests/test_housekeeping.py +195 -0
- package/tests/test_identity_capauth.py +307 -0
- package/tests/test_identity_pillar.py +117 -0
- package/tests/test_install_wizard.py +68 -0
- package/tests/test_integration.py +325 -0
- package/tests/test_kms.py +495 -0
- package/tests/test_llm_providers.py +265 -0
- package/tests/test_local_provider.py +591 -0
- package/tests/test_log_config.py +199 -0
- package/tests/test_logs_cmd.py +287 -0
- package/tests/test_mcp_server.py +1909 -0
- package/tests/test_memory_adapter.py +339 -0
- package/tests/test_memory_curator.py +218 -0
- package/tests/test_memory_engine.py +6 -0
- package/tests/test_memory_fortress.py +571 -0
- package/tests/test_memory_pillar.py +119 -0
- package/tests/test_memory_promoter.py +445 -0
- package/tests/test_memory_verifier.py +420 -0
- package/tests/test_message_crypto.py +187 -0
- package/tests/test_metrics.py +632 -0
- package/tests/test_migrate_memories.py +464 -0
- package/tests/test_model_router.py +546 -0
- package/tests/test_mood.py +394 -0
- package/tests/test_multi_agent.py +269 -0
- package/tests/test_notifications.py +270 -0
- package/tests/test_onboard.py +500 -0
- package/tests/test_peer_directory.py +395 -0
- package/tests/test_peers.py +248 -0
- package/tests/test_pillars.py +87 -9
- package/tests/test_preflight.py +484 -0
- package/tests/test_prompt_adapter.py +331 -0
- package/tests/test_proxmox_provider.py +571 -0
- package/tests/test_pubsub.py +377 -0
- package/tests/test_rate_limiter.py +121 -0
- package/tests/test_registry_client.py +129 -0
- package/tests/test_response_cache.py +312 -0
- package/tests/test_response_scorer.py +294 -0
- package/tests/test_runtime.py +59 -0
- package/tests/test_scheduled_tasks.py +451 -0
- package/tests/test_security.py +250 -0
- package/tests/test_security_pillar.py +213 -0
- package/tests/test_self_healing.py +171 -0
- package/tests/test_session_capture.py +200 -0
- package/tests/test_session_recorder.py +360 -0
- package/tests/test_session_skills.py +235 -0
- package/tests/test_shell.py +210 -0
- package/tests/test_snapshots.py +549 -0
- package/tests/test_soul.py +984 -0
- package/tests/test_soul_swap.py +406 -0
- package/tests/test_spawner.py +211 -0
- package/tests/test_state_diff.py +173 -0
- package/tests/test_summary.py +135 -0
- package/tests/test_sync.py +315 -5
- package/tests/test_sync_backends.py +560 -0
- package/tests/test_sync_engine.py +482 -0
- package/tests/test_sync_pillar.py +344 -0
- package/tests/test_sync_pipeline.py +364 -0
- package/tests/test_sync_vault.py +581 -0
- package/tests/test_syncthing_setup.py +168 -22
- package/tests/test_systemd.py +323 -0
- package/tests/test_team_comms.py +408 -0
- package/tests/test_team_engine.py +397 -0
- package/tests/test_testrunner.py +238 -0
- package/tests/test_trust_calibration.py +204 -0
- package/tests/test_trust_graph.py +207 -0
- package/tests/test_trust_pillar.py +291 -0
- package/tests/test_trustee_cli.py +427 -0
- package/tests/test_trustee_cli_integration.py +325 -0
- package/tests/test_trustee_monitor.py +394 -0
- package/tests/test_trustee_ops.py +355 -0
- package/tests/test_unified_search.py +363 -0
- package/tests/test_uninstall_wizard.py +193 -0
- package/tests/test_usage.py +333 -0
- package/tests/test_version_cmd.py +355 -0
- package/tests/test_warmth_anchor.py +162 -0
- package/tests/test_whoami.py +245 -0
- package/tests/test_ws.py +311 -0
- package/.cursorrules +0 -33
- package/src/skcapstone/cli.py +0 -1441
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
"""Autonomous agent monitoring — heartbeat detection, auto-remediation, escalation.
|
|
2
|
+
|
|
3
|
+
The TrusteeMonitor watches deployed agent teams and takes autonomous
|
|
4
|
+
action when issues are detected:
|
|
5
|
+
|
|
6
|
+
- Heartbeat miss → auto-restart after threshold
|
|
7
|
+
- Repeated restart failures → auto-rotate (snapshot + fresh deploy)
|
|
8
|
+
- Critical degradation (>50% agents down) → escalation to Chef via SKChat
|
|
9
|
+
- Context fill detection → auto-rotate before degradation
|
|
10
|
+
|
|
11
|
+
All actions are logged to the audit trail. The monitor follows the
|
|
12
|
+
Trustee Oath: "I escalate when uncertain — never guess with sovereignty."
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import logging
|
|
18
|
+
import time
|
|
19
|
+
from dataclasses import dataclass, field
|
|
20
|
+
from datetime import datetime, timezone
|
|
21
|
+
from typing import Any, Dict, List, Optional
|
|
22
|
+
|
|
23
|
+
from .team_engine import AgentStatus, TeamDeployment, TeamEngine
|
|
24
|
+
from .trustee_ops import TrusteeOps
|
|
25
|
+
|
|
26
|
+
logger = logging.getLogger(__name__)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@dataclass
|
|
30
|
+
class MonitorConfig:
|
|
31
|
+
"""Configuration for autonomous monitoring thresholds.
|
|
32
|
+
|
|
33
|
+
Attributes:
|
|
34
|
+
heartbeat_timeout: Seconds since last heartbeat before restart.
|
|
35
|
+
max_restart_attempts: Consecutive restart failures before rotate.
|
|
36
|
+
critical_threshold: Fraction of failed agents triggering escalation.
|
|
37
|
+
escalation_cooldown: Seconds between escalation messages.
|
|
38
|
+
auto_restart: Whether to auto-restart on heartbeat miss.
|
|
39
|
+
auto_rotate: Whether to auto-rotate on repeated failures.
|
|
40
|
+
auto_escalate: Whether to send escalation messages.
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
heartbeat_timeout: float = 120.0
|
|
44
|
+
max_restart_attempts: int = 3
|
|
45
|
+
critical_threshold: float = 0.5
|
|
46
|
+
escalation_cooldown: float = 300.0
|
|
47
|
+
auto_restart: bool = True
|
|
48
|
+
auto_rotate: bool = True
|
|
49
|
+
auto_escalate: bool = True
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@dataclass
|
|
53
|
+
class AgentIncident:
|
|
54
|
+
"""Tracks incident state for a single agent."""
|
|
55
|
+
|
|
56
|
+
restart_attempts: int = 0
|
|
57
|
+
last_restart: Optional[float] = None
|
|
58
|
+
rotated: bool = False
|
|
59
|
+
escalated: bool = False
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@dataclass
|
|
63
|
+
class MonitorReport:
|
|
64
|
+
"""Result of a single monitoring pass.
|
|
65
|
+
|
|
66
|
+
Attributes:
|
|
67
|
+
timestamp: When the check was performed.
|
|
68
|
+
deployments_checked: Number of deployments examined.
|
|
69
|
+
agents_healthy: Count of healthy agents.
|
|
70
|
+
agents_degraded: Count of degraded/failed agents.
|
|
71
|
+
restarts_triggered: Agent names that were auto-restarted.
|
|
72
|
+
rotations_triggered: Agent names that were auto-rotated.
|
|
73
|
+
escalations_sent: Deployment IDs that triggered escalation.
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
timestamp: str = ""
|
|
77
|
+
deployments_checked: int = 0
|
|
78
|
+
agents_healthy: int = 0
|
|
79
|
+
agents_degraded: int = 0
|
|
80
|
+
restarts_triggered: List[str] = field(default_factory=list)
|
|
81
|
+
rotations_triggered: List[str] = field(default_factory=list)
|
|
82
|
+
escalations_sent: List[str] = field(default_factory=list)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class TrusteeMonitor:
|
|
86
|
+
"""Autonomous monitoring loop for deployed agent teams.
|
|
87
|
+
|
|
88
|
+
Periodically checks health of all deployments and takes
|
|
89
|
+
corrective action based on configurable thresholds. Follows
|
|
90
|
+
escalation protocol: restart → rotate → escalate.
|
|
91
|
+
|
|
92
|
+
Args:
|
|
93
|
+
ops: TrusteeOps instance for remediation actions.
|
|
94
|
+
engine: TeamEngine for deployment listing.
|
|
95
|
+
config: Monitoring thresholds and toggles.
|
|
96
|
+
"""
|
|
97
|
+
|
|
98
|
+
def __init__(
|
|
99
|
+
self,
|
|
100
|
+
ops: TrusteeOps,
|
|
101
|
+
engine: TeamEngine,
|
|
102
|
+
config: Optional[MonitorConfig] = None,
|
|
103
|
+
) -> None:
|
|
104
|
+
self._ops = ops
|
|
105
|
+
self._engine = engine
|
|
106
|
+
self._config = config or MonitorConfig()
|
|
107
|
+
self._incidents: Dict[str, AgentIncident] = {}
|
|
108
|
+
self._last_escalation: Dict[str, float] = {}
|
|
109
|
+
self._running = False
|
|
110
|
+
|
|
111
|
+
def _get_incident(self, agent_key: str) -> AgentIncident:
|
|
112
|
+
"""Get or create an incident tracker for an agent.
|
|
113
|
+
|
|
114
|
+
Args:
|
|
115
|
+
agent_key: Unique key like 'deployment_id/agent_name'.
|
|
116
|
+
|
|
117
|
+
Returns:
|
|
118
|
+
AgentIncident for this agent.
|
|
119
|
+
"""
|
|
120
|
+
if agent_key not in self._incidents:
|
|
121
|
+
self._incidents[agent_key] = AgentIncident()
|
|
122
|
+
return self._incidents[agent_key]
|
|
123
|
+
|
|
124
|
+
def _is_heartbeat_stale(self, agent: Any) -> bool:
|
|
125
|
+
"""Check if an agent's heartbeat has exceeded the timeout.
|
|
126
|
+
|
|
127
|
+
Args:
|
|
128
|
+
agent: DeployedAgent instance.
|
|
129
|
+
|
|
130
|
+
Returns:
|
|
131
|
+
True if heartbeat is stale or missing.
|
|
132
|
+
"""
|
|
133
|
+
if not agent.last_heartbeat:
|
|
134
|
+
return agent.status == AgentStatus.RUNNING
|
|
135
|
+
|
|
136
|
+
try:
|
|
137
|
+
hb_time = datetime.fromisoformat(agent.last_heartbeat)
|
|
138
|
+
if hb_time.tzinfo is None:
|
|
139
|
+
hb_time = hb_time.replace(tzinfo=timezone.utc)
|
|
140
|
+
elapsed = (datetime.now(timezone.utc) - hb_time).total_seconds()
|
|
141
|
+
return elapsed > self._config.heartbeat_timeout
|
|
142
|
+
except (ValueError, TypeError):
|
|
143
|
+
return True
|
|
144
|
+
|
|
145
|
+
def _try_restart(self, deployment_id: str, agent_name: str) -> bool:
|
|
146
|
+
"""Attempt to restart an agent.
|
|
147
|
+
|
|
148
|
+
Args:
|
|
149
|
+
deployment_id: Target deployment.
|
|
150
|
+
agent_name: Agent to restart.
|
|
151
|
+
|
|
152
|
+
Returns:
|
|
153
|
+
True if restart succeeded.
|
|
154
|
+
"""
|
|
155
|
+
if not self._config.auto_restart:
|
|
156
|
+
return False
|
|
157
|
+
|
|
158
|
+
agent_key = f"{deployment_id}/{agent_name}"
|
|
159
|
+
incident = self._get_incident(agent_key)
|
|
160
|
+
|
|
161
|
+
try:
|
|
162
|
+
results = self._ops.restart_agent(deployment_id, agent_name)
|
|
163
|
+
success = results.get(agent_name) == "restarted"
|
|
164
|
+
if success:
|
|
165
|
+
incident.restart_attempts = 0
|
|
166
|
+
logger.info("Auto-restarted %s in %s", agent_name, deployment_id)
|
|
167
|
+
else:
|
|
168
|
+
incident.restart_attempts += 1
|
|
169
|
+
incident.last_restart = time.time()
|
|
170
|
+
logger.warning(
|
|
171
|
+
"Restart failed for %s (attempt %d/%d)",
|
|
172
|
+
agent_name, incident.restart_attempts,
|
|
173
|
+
self._config.max_restart_attempts,
|
|
174
|
+
)
|
|
175
|
+
return success
|
|
176
|
+
except Exception as exc:
|
|
177
|
+
incident.restart_attempts += 1
|
|
178
|
+
incident.last_restart = time.time()
|
|
179
|
+
logger.error("Restart exception for %s: %s", agent_name, exc)
|
|
180
|
+
return False
|
|
181
|
+
|
|
182
|
+
def _try_rotate(self, deployment_id: str, agent_name: str) -> bool:
|
|
183
|
+
"""Attempt to rotate an agent (snapshot + fresh deploy).
|
|
184
|
+
|
|
185
|
+
Args:
|
|
186
|
+
deployment_id: Target deployment.
|
|
187
|
+
agent_name: Agent to rotate.
|
|
188
|
+
|
|
189
|
+
Returns:
|
|
190
|
+
True if rotation succeeded.
|
|
191
|
+
"""
|
|
192
|
+
if not self._config.auto_rotate:
|
|
193
|
+
return False
|
|
194
|
+
|
|
195
|
+
agent_key = f"{deployment_id}/{agent_name}"
|
|
196
|
+
incident = self._get_incident(agent_key)
|
|
197
|
+
|
|
198
|
+
if incident.rotated:
|
|
199
|
+
return False
|
|
200
|
+
|
|
201
|
+
try:
|
|
202
|
+
result = self._ops.rotate_agent(deployment_id, agent_name)
|
|
203
|
+
incident.rotated = True
|
|
204
|
+
incident.restart_attempts = 0
|
|
205
|
+
logger.info(
|
|
206
|
+
"Auto-rotated %s in %s (snapshot: %s)",
|
|
207
|
+
agent_name, deployment_id, result.get("snapshot_path"),
|
|
208
|
+
)
|
|
209
|
+
return result.get("redeployed", False)
|
|
210
|
+
except Exception as exc:
|
|
211
|
+
logger.error("Rotation failed for %s: %s", agent_name, exc)
|
|
212
|
+
return False
|
|
213
|
+
|
|
214
|
+
def _try_escalate(self, deployment_id: str, message: str) -> bool:
|
|
215
|
+
"""Send an escalation message via SKChat if cooldown has elapsed.
|
|
216
|
+
|
|
217
|
+
Args:
|
|
218
|
+
deployment_id: Deployment with critical issues.
|
|
219
|
+
message: Escalation message text.
|
|
220
|
+
|
|
221
|
+
Returns:
|
|
222
|
+
True if escalation was sent.
|
|
223
|
+
"""
|
|
224
|
+
if not self._config.auto_escalate:
|
|
225
|
+
return False
|
|
226
|
+
|
|
227
|
+
now = time.time()
|
|
228
|
+
last = self._last_escalation.get(deployment_id, 0.0)
|
|
229
|
+
if now - last < self._config.escalation_cooldown:
|
|
230
|
+
return False
|
|
231
|
+
|
|
232
|
+
try:
|
|
233
|
+
from .mcp_server import _send_message_impl
|
|
234
|
+
_send_message_impl(
|
|
235
|
+
recipient="chef",
|
|
236
|
+
message=f"[TRUSTEE ESCALATION] {message}",
|
|
237
|
+
urgency="critical",
|
|
238
|
+
)
|
|
239
|
+
self._last_escalation[deployment_id] = now
|
|
240
|
+
logger.warning("Escalation sent for %s: %s", deployment_id, message)
|
|
241
|
+
return True
|
|
242
|
+
except Exception:
|
|
243
|
+
# Fallback: just log it
|
|
244
|
+
logger.warning("Escalation (no transport): %s", message)
|
|
245
|
+
self._last_escalation[deployment_id] = now
|
|
246
|
+
return True
|
|
247
|
+
|
|
248
|
+
def check_deployment(self, deployment: TeamDeployment) -> MonitorReport:
|
|
249
|
+
"""Run a monitoring pass on a single deployment.
|
|
250
|
+
|
|
251
|
+
Checks each agent's health and takes autonomous action as needed:
|
|
252
|
+
1. Stale heartbeat → restart
|
|
253
|
+
2. Too many restart failures → rotate
|
|
254
|
+
3. Critical degradation → escalate
|
|
255
|
+
|
|
256
|
+
Args:
|
|
257
|
+
deployment: The deployment to check.
|
|
258
|
+
|
|
259
|
+
Returns:
|
|
260
|
+
MonitorReport for this deployment.
|
|
261
|
+
"""
|
|
262
|
+
report = MonitorReport(
|
|
263
|
+
timestamp=datetime.now(timezone.utc).isoformat(),
|
|
264
|
+
deployments_checked=1,
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
total_agents = len(deployment.agents)
|
|
268
|
+
if total_agents == 0:
|
|
269
|
+
return report
|
|
270
|
+
|
|
271
|
+
failed_count = 0
|
|
272
|
+
|
|
273
|
+
for name, agent in deployment.agents.items():
|
|
274
|
+
agent_key = f"{deployment.deployment_id}/{name}"
|
|
275
|
+
incident = self._get_incident(agent_key)
|
|
276
|
+
|
|
277
|
+
is_healthy = agent.status == AgentStatus.RUNNING
|
|
278
|
+
is_stale = self._is_heartbeat_stale(agent) if is_healthy else False
|
|
279
|
+
|
|
280
|
+
if is_healthy and not is_stale:
|
|
281
|
+
report.agents_healthy += 1
|
|
282
|
+
# Clear incident state on recovery
|
|
283
|
+
if incident.restart_attempts > 0:
|
|
284
|
+
incident.restart_attempts = 0
|
|
285
|
+
incident.rotated = False
|
|
286
|
+
continue
|
|
287
|
+
|
|
288
|
+
# Agent needs attention
|
|
289
|
+
report.agents_degraded += 1
|
|
290
|
+
failed_count += 1
|
|
291
|
+
|
|
292
|
+
# Escalation path: restart → rotate → escalate
|
|
293
|
+
if incident.restart_attempts >= self._config.max_restart_attempts:
|
|
294
|
+
# Too many restarts failed, try rotation
|
|
295
|
+
if self._try_rotate(deployment.deployment_id, name):
|
|
296
|
+
report.rotations_triggered.append(name)
|
|
297
|
+
continue
|
|
298
|
+
|
|
299
|
+
if is_stale or agent.status in (AgentStatus.FAILED, AgentStatus.DEGRADED):
|
|
300
|
+
if self._try_restart(deployment.deployment_id, name):
|
|
301
|
+
report.restarts_triggered.append(name)
|
|
302
|
+
|
|
303
|
+
# Check for critical degradation
|
|
304
|
+
if total_agents > 0:
|
|
305
|
+
failure_ratio = failed_count / total_agents
|
|
306
|
+
if failure_ratio >= self._config.critical_threshold:
|
|
307
|
+
msg = (
|
|
308
|
+
f"Deployment '{deployment.deployment_id}' critically degraded: "
|
|
309
|
+
f"{failed_count}/{total_agents} agents down "
|
|
310
|
+
f"({failure_ratio:.0%})"
|
|
311
|
+
)
|
|
312
|
+
if self._try_escalate(deployment.deployment_id, msg):
|
|
313
|
+
report.escalations_sent.append(deployment.deployment_id)
|
|
314
|
+
|
|
315
|
+
return report
|
|
316
|
+
|
|
317
|
+
def check_all(self) -> MonitorReport:
|
|
318
|
+
"""Run a monitoring pass over all deployments.
|
|
319
|
+
|
|
320
|
+
Returns:
|
|
321
|
+
Aggregated MonitorReport across all deployments.
|
|
322
|
+
"""
|
|
323
|
+
combined = MonitorReport(
|
|
324
|
+
timestamp=datetime.now(timezone.utc).isoformat(),
|
|
325
|
+
)
|
|
326
|
+
|
|
327
|
+
deployments = self._engine.list_deployments()
|
|
328
|
+
combined.deployments_checked = len(deployments)
|
|
329
|
+
|
|
330
|
+
for deployment in deployments:
|
|
331
|
+
sub = self.check_deployment(deployment)
|
|
332
|
+
combined.agents_healthy += sub.agents_healthy
|
|
333
|
+
combined.agents_degraded += sub.agents_degraded
|
|
334
|
+
combined.restarts_triggered.extend(sub.restarts_triggered)
|
|
335
|
+
combined.rotations_triggered.extend(sub.rotations_triggered)
|
|
336
|
+
combined.escalations_sent.extend(sub.escalations_sent)
|
|
337
|
+
|
|
338
|
+
return combined
|
|
339
|
+
|
|
340
|
+
def run(self, interval: float = 30.0, max_iterations: int = 0) -> None:
|
|
341
|
+
"""Run the monitoring loop.
|
|
342
|
+
|
|
343
|
+
Continuously checks all deployments at the given interval.
|
|
344
|
+
Press Ctrl+C to stop.
|
|
345
|
+
|
|
346
|
+
Args:
|
|
347
|
+
interval: Seconds between checks.
|
|
348
|
+
max_iterations: Stop after N iterations (0 = infinite).
|
|
349
|
+
"""
|
|
350
|
+
self._running = True
|
|
351
|
+
iteration = 0
|
|
352
|
+
logger.info("Trustee monitor started (interval=%.1fs)", interval)
|
|
353
|
+
|
|
354
|
+
try:
|
|
355
|
+
while self._running:
|
|
356
|
+
iteration += 1
|
|
357
|
+
report = self.check_all()
|
|
358
|
+
|
|
359
|
+
if (report.restarts_triggered or
|
|
360
|
+
report.rotations_triggered or
|
|
361
|
+
report.escalations_sent):
|
|
362
|
+
logger.info(
|
|
363
|
+
"Monitor pass %d: %d healthy, %d degraded, "
|
|
364
|
+
"%d restarts, %d rotations, %d escalations",
|
|
365
|
+
iteration,
|
|
366
|
+
report.agents_healthy,
|
|
367
|
+
report.agents_degraded,
|
|
368
|
+
len(report.restarts_triggered),
|
|
369
|
+
len(report.rotations_triggered),
|
|
370
|
+
len(report.escalations_sent),
|
|
371
|
+
)
|
|
372
|
+
|
|
373
|
+
if max_iterations and iteration >= max_iterations:
|
|
374
|
+
break
|
|
375
|
+
|
|
376
|
+
time.sleep(interval)
|
|
377
|
+
except KeyboardInterrupt:
|
|
378
|
+
pass
|
|
379
|
+
finally:
|
|
380
|
+
self._running = False
|
|
381
|
+
logger.info("Trustee monitor stopped after %d iterations", iteration)
|
|
382
|
+
|
|
383
|
+
def stop(self) -> None:
|
|
384
|
+
"""Signal the monitoring loop to stop."""
|
|
385
|
+
self._running = False
|