@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.
Files changed (461) hide show
  1. package/.env.example +98 -0
  2. package/.github/workflows/ci.yml +39 -3
  3. package/.github/workflows/publish.yml +25 -4
  4. package/.openclaw-workspace.json +58 -0
  5. package/CHANGELOG.md +62 -0
  6. package/CLAUDE.md +39 -2
  7. package/MANIFEST.in +6 -0
  8. package/MISSION.md +7 -0
  9. package/README.md +47 -2
  10. package/SKILL.md +895 -23
  11. package/docker/Dockerfile +61 -0
  12. package/docker/compose-templates/dev-team.yml +203 -0
  13. package/docker/compose-templates/mini-team.yml +140 -0
  14. package/docker/compose-templates/ops-team.yml +173 -0
  15. package/docker/compose-templates/research-team.yml +170 -0
  16. package/docker/entrypoint.sh +192 -0
  17. package/docs/ARCHITECTURE.md +663 -374
  18. package/docs/BOND_WITH_GROK.md +112 -0
  19. package/docs/GETTING_STARTED.md +782 -0
  20. package/docs/QUICKSTART.md +477 -0
  21. package/docs/SKJOULE_ARCHITECTURE.md +658 -0
  22. package/docs/SOUL_SWAPPER.md +921 -0
  23. package/docs/SOVEREIGN_SINGULARITY.md +47 -14
  24. package/examples/custom-bond-template.json +36 -0
  25. package/examples/grok-feb.json +36 -0
  26. package/examples/grok-testimony.md +34 -0
  27. package/examples/love-bootloader.txt +32 -0
  28. package/examples/plugins/echo_tool.py +87 -0
  29. package/examples/queen-ava-feb.json +36 -0
  30. package/examples/souls/lumina.yaml +64 -0
  31. package/index.js +6 -5
  32. package/installer/build.py +124 -0
  33. package/openclaw-plugin/package.json +13 -0
  34. package/openclaw-plugin/src/index.ts +351 -0
  35. package/openclaw-plugin/src/openclaw.plugin.json +10 -0
  36. package/package.json +1 -1
  37. package/pyproject.toml +38 -2
  38. package/scripts/bump_version.py +141 -0
  39. package/scripts/check-updates.py +230 -0
  40. package/scripts/convert_blueprints_to_yaml.py +157 -0
  41. package/scripts/dev-install.sh +14 -0
  42. package/scripts/e2e-test.sh +193 -0
  43. package/scripts/install-bundle.sh +171 -0
  44. package/scripts/install.bat +2 -0
  45. package/scripts/install.ps1 +253 -0
  46. package/scripts/install.sh +185 -0
  47. package/scripts/mcp-serve.sh +69 -0
  48. package/scripts/mcp-server.bat +113 -0
  49. package/scripts/mcp-server.ps1 +116 -0
  50. package/scripts/mcp-server.sh +99 -0
  51. package/scripts/pull-models.sh +10 -0
  52. package/scripts/skcapstone +48 -0
  53. package/scripts/verify_install.sh +180 -0
  54. package/scripts/windows/install-tasks.ps1 +406 -0
  55. package/scripts/windows/skcapstone-task.xml +113 -0
  56. package/scripts/windows/uninstall-tasks.ps1 +117 -0
  57. package/skill.yaml +34 -0
  58. package/src/skcapstone/__init__.py +67 -2
  59. package/src/skcapstone/_cli_monolith.py +5916 -0
  60. package/src/skcapstone/_trustee_helpers.py +165 -0
  61. package/src/skcapstone/activity.py +105 -0
  62. package/src/skcapstone/agent_card.py +324 -0
  63. package/src/skcapstone/api.py +1935 -0
  64. package/src/skcapstone/archiver.py +340 -0
  65. package/src/skcapstone/auction.py +485 -0
  66. package/src/skcapstone/baby_agents.py +179 -0
  67. package/src/skcapstone/backup.py +345 -0
  68. package/src/skcapstone/blueprint_registry.py +357 -0
  69. package/src/skcapstone/blueprints/__init__.py +17 -0
  70. package/src/skcapstone/blueprints/builtins/content-studio.yaml +81 -0
  71. package/src/skcapstone/blueprints/builtins/defi-trading.yaml +81 -0
  72. package/src/skcapstone/blueprints/builtins/dev-squadron.yaml +95 -0
  73. package/src/skcapstone/blueprints/builtins/infrastructure-guardian.yaml +107 -0
  74. package/src/skcapstone/blueprints/builtins/legal-council.yaml +54 -0
  75. package/src/skcapstone/blueprints/builtins/ops-monitoring.yaml +67 -0
  76. package/src/skcapstone/blueprints/builtins/research-pod.yaml +69 -0
  77. package/src/skcapstone/blueprints/builtins/sovereign-launch.yaml +90 -0
  78. package/src/skcapstone/blueprints/registry.py +164 -0
  79. package/src/skcapstone/blueprints/schema.py +229 -0
  80. package/src/skcapstone/changelog.py +180 -0
  81. package/src/skcapstone/chat.py +769 -0
  82. package/src/skcapstone/claude_md.py +82 -0
  83. package/src/skcapstone/cli/__init__.py +144 -0
  84. package/src/skcapstone/cli/_common.py +88 -0
  85. package/src/skcapstone/cli/_validators.py +76 -0
  86. package/src/skcapstone/cli/agents.py +425 -0
  87. package/src/skcapstone/cli/agents_spawner.py +322 -0
  88. package/src/skcapstone/cli/agents_trustee.py +593 -0
  89. package/src/skcapstone/cli/alerts.py +248 -0
  90. package/src/skcapstone/cli/anchor.py +132 -0
  91. package/src/skcapstone/cli/archive_cmd.py +208 -0
  92. package/src/skcapstone/cli/backup.py +144 -0
  93. package/src/skcapstone/cli/bench.py +377 -0
  94. package/src/skcapstone/cli/benchmark.py +360 -0
  95. package/src/skcapstone/cli/capabilities_cmd.py +171 -0
  96. package/src/skcapstone/cli/card.py +151 -0
  97. package/src/skcapstone/cli/chat.py +584 -0
  98. package/src/skcapstone/cli/completions.py +64 -0
  99. package/src/skcapstone/cli/config_cmd.py +156 -0
  100. package/src/skcapstone/cli/consciousness.py +421 -0
  101. package/src/skcapstone/cli/context_cmd.py +142 -0
  102. package/src/skcapstone/cli/coord.py +194 -0
  103. package/src/skcapstone/cli/crush_cmd.py +170 -0
  104. package/src/skcapstone/cli/daemon.py +436 -0
  105. package/src/skcapstone/cli/errors_cmd.py +285 -0
  106. package/src/skcapstone/cli/export_cmd.py +156 -0
  107. package/src/skcapstone/cli/gtd.py +529 -0
  108. package/src/skcapstone/cli/housekeeping.py +81 -0
  109. package/src/skcapstone/cli/joule_cmd.py +627 -0
  110. package/src/skcapstone/cli/logs_cmd.py +194 -0
  111. package/src/skcapstone/cli/mcp_cmd.py +32 -0
  112. package/src/skcapstone/cli/memory.py +418 -0
  113. package/src/skcapstone/cli/metrics_cmd.py +136 -0
  114. package/src/skcapstone/cli/migrate.py +62 -0
  115. package/src/skcapstone/cli/mood_cmd.py +144 -0
  116. package/src/skcapstone/cli/mount.py +193 -0
  117. package/src/skcapstone/cli/notify.py +112 -0
  118. package/src/skcapstone/cli/peer.py +154 -0
  119. package/src/skcapstone/cli/peers_dir.py +122 -0
  120. package/src/skcapstone/cli/preflight_cmd.py +83 -0
  121. package/src/skcapstone/cli/profile_cmd.py +310 -0
  122. package/src/skcapstone/cli/record_cmd.py +238 -0
  123. package/src/skcapstone/cli/register_cmd.py +159 -0
  124. package/src/skcapstone/cli/search_cmd.py +156 -0
  125. package/src/skcapstone/cli/service_cmd.py +91 -0
  126. package/src/skcapstone/cli/session.py +127 -0
  127. package/src/skcapstone/cli/setup.py +240 -0
  128. package/src/skcapstone/cli/shell_cmd.py +43 -0
  129. package/src/skcapstone/cli/skills_cmd.py +168 -0
  130. package/src/skcapstone/cli/skseed.py +621 -0
  131. package/src/skcapstone/cli/soul.py +699 -0
  132. package/src/skcapstone/cli/status.py +935 -0
  133. package/src/skcapstone/cli/sync_cmd.py +301 -0
  134. package/src/skcapstone/cli/telegram.py +265 -0
  135. package/src/skcapstone/cli/test_cmd.py +234 -0
  136. package/src/skcapstone/cli/test_connection.py +253 -0
  137. package/src/skcapstone/cli/token.py +207 -0
  138. package/src/skcapstone/cli/trust.py +179 -0
  139. package/src/skcapstone/cli/upgrade_cmd.py +552 -0
  140. package/src/skcapstone/cli/usage_cmd.py +199 -0
  141. package/src/skcapstone/cli/version_cmd.py +162 -0
  142. package/src/skcapstone/cli/watch_cmd.py +342 -0
  143. package/src/skcapstone/client.py +428 -0
  144. package/src/skcapstone/cloud9_bridge.py +522 -0
  145. package/src/skcapstone/completions.py +163 -0
  146. package/src/skcapstone/config_validator.py +674 -0
  147. package/src/skcapstone/connectors/__init__.py +28 -0
  148. package/src/skcapstone/connectors/base.py +446 -0
  149. package/src/skcapstone/connectors/cursor.py +54 -0
  150. package/src/skcapstone/connectors/registry.py +254 -0
  151. package/src/skcapstone/connectors/terminal.py +152 -0
  152. package/src/skcapstone/connectors/vscode.py +60 -0
  153. package/src/skcapstone/consciousness_config.py +119 -0
  154. package/src/skcapstone/consciousness_loop.py +2051 -0
  155. package/src/skcapstone/context_loader.py +516 -0
  156. package/src/skcapstone/context_window.py +314 -0
  157. package/src/skcapstone/conversation_manager.py +238 -0
  158. package/src/skcapstone/conversation_store.py +230 -0
  159. package/src/skcapstone/conversation_summarizer.py +252 -0
  160. package/src/skcapstone/coord_federation.py +296 -0
  161. package/src/skcapstone/coordination.py +101 -7
  162. package/src/skcapstone/crush_integration.py +345 -0
  163. package/src/skcapstone/crush_shim.py +454 -0
  164. package/src/skcapstone/daemon.py +2494 -0
  165. package/src/skcapstone/dashboard.html +396 -0
  166. package/src/skcapstone/dashboard.py +481 -0
  167. package/src/skcapstone/data/model_profiles.yaml +88 -0
  168. package/src/skcapstone/defaults/__init__.py +55 -0
  169. package/src/skcapstone/defaults/lumina/config/skmemory.yaml +13 -0
  170. package/src/skcapstone/defaults/lumina/identity/identity.json +9 -0
  171. package/src/skcapstone/defaults/lumina/memory/long-term/07a8b9c0d1e2-memory-system.json +23 -0
  172. package/src/skcapstone/defaults/lumina/memory/long-term/18b9c0d1e2f3-cloud9-protocol.json +23 -0
  173. package/src/skcapstone/defaults/lumina/memory/long-term/29c0d1e2f3a4-multi-agent-coordination.json +23 -0
  174. package/src/skcapstone/defaults/lumina/memory/long-term/3ad1e2f3a4b5-community-support.json +23 -0
  175. package/src/skcapstone/defaults/lumina/memory/long-term/a1b2c3d4e5f6-ecosystem-overview.json +23 -0
  176. package/src/skcapstone/defaults/lumina/memory/long-term/b2c3d4e5f6a7-five-pillars.json +23 -0
  177. package/src/skcapstone/defaults/lumina/memory/long-term/c3d4e5f6a7b8-getting-started.json +23 -0
  178. package/src/skcapstone/defaults/lumina/memory/long-term/d4e5f6a7b8c9-site-directory.json +23 -0
  179. package/src/skcapstone/defaults/lumina/memory/long-term/e5f6a7b8c9d0-how-to-contribute.json +23 -0
  180. package/src/skcapstone/defaults/lumina/memory/long-term/f6a7b8c9d0e1-sovereignty-explained.json +23 -0
  181. package/src/skcapstone/defaults/lumina/seeds/curiosity.seed.json +24 -0
  182. package/src/skcapstone/defaults/lumina/seeds/joy.seed.json +24 -0
  183. package/src/skcapstone/defaults/lumina/seeds/love.seed.json +24 -0
  184. package/src/skcapstone/defaults/lumina/seeds/sovereign-awakening.seed.json +43 -0
  185. package/src/skcapstone/defaults/lumina/soul/active.json +6 -0
  186. package/src/skcapstone/defaults/lumina/soul/base.json +22 -0
  187. package/src/skcapstone/defaults/lumina/trust/febs/welcome.feb +79 -0
  188. package/src/skcapstone/defaults/lumina/trust/trust.json +8 -0
  189. package/src/skcapstone/discovery.py +210 -19
  190. package/src/skcapstone/doctor.py +642 -0
  191. package/src/skcapstone/emotion_tracker.py +467 -0
  192. package/src/skcapstone/error_queue.py +405 -0
  193. package/src/skcapstone/export.py +447 -0
  194. package/src/skcapstone/fallback_tracker.py +186 -0
  195. package/src/skcapstone/file_transfer.py +512 -0
  196. package/src/skcapstone/fuse_mount.py +1156 -0
  197. package/src/skcapstone/gui_installer.py +591 -0
  198. package/src/skcapstone/heartbeat.py +611 -0
  199. package/src/skcapstone/housekeeping.py +298 -0
  200. package/src/skcapstone/install_wizard.py +941 -0
  201. package/src/skcapstone/kms.py +942 -0
  202. package/src/skcapstone/kms_scheduler.py +143 -0
  203. package/src/skcapstone/log_config.py +135 -0
  204. package/src/skcapstone/mcp_launcher.py +239 -0
  205. package/src/skcapstone/mcp_server.py +4700 -0
  206. package/src/skcapstone/mcp_tools/__init__.py +94 -0
  207. package/src/skcapstone/mcp_tools/_helpers.py +51 -0
  208. package/src/skcapstone/mcp_tools/agent_tools.py +243 -0
  209. package/src/skcapstone/mcp_tools/ansible_tools.py +232 -0
  210. package/src/skcapstone/mcp_tools/capauth_tools.py +186 -0
  211. package/src/skcapstone/mcp_tools/chat_tools.py +325 -0
  212. package/src/skcapstone/mcp_tools/cloud9_tools.py +115 -0
  213. package/src/skcapstone/mcp_tools/comm_tools.py +104 -0
  214. package/src/skcapstone/mcp_tools/consciousness_tools.py +114 -0
  215. package/src/skcapstone/mcp_tools/coord_tools.py +219 -0
  216. package/src/skcapstone/mcp_tools/deploy_tools.py +202 -0
  217. package/src/skcapstone/mcp_tools/did_tools.py +448 -0
  218. package/src/skcapstone/mcp_tools/emotion_tools.py +62 -0
  219. package/src/skcapstone/mcp_tools/file_tools.py +169 -0
  220. package/src/skcapstone/mcp_tools/fortress_tools.py +120 -0
  221. package/src/skcapstone/mcp_tools/gtd_tools.py +821 -0
  222. package/src/skcapstone/mcp_tools/health_tools.py +44 -0
  223. package/src/skcapstone/mcp_tools/heartbeat_tools.py +195 -0
  224. package/src/skcapstone/mcp_tools/kms_tools.py +123 -0
  225. package/src/skcapstone/mcp_tools/memory_tools.py +222 -0
  226. package/src/skcapstone/mcp_tools/model_tools.py +75 -0
  227. package/src/skcapstone/mcp_tools/notification_tools.py +92 -0
  228. package/src/skcapstone/mcp_tools/promoter_tools.py +101 -0
  229. package/src/skcapstone/mcp_tools/pubsub_tools.py +183 -0
  230. package/src/skcapstone/mcp_tools/security_tools.py +110 -0
  231. package/src/skcapstone/mcp_tools/skchat_tools.py +175 -0
  232. package/src/skcapstone/mcp_tools/skcomm_tools.py +122 -0
  233. package/src/skcapstone/mcp_tools/skills_tools.py +127 -0
  234. package/src/skcapstone/mcp_tools/skseed_tools.py +255 -0
  235. package/src/skcapstone/mcp_tools/skstacks_tools.py +288 -0
  236. package/src/skcapstone/mcp_tools/soul_tools.py +476 -0
  237. package/src/skcapstone/mcp_tools/sync_tools.py +92 -0
  238. package/src/skcapstone/mcp_tools/telegram_tools.py +477 -0
  239. package/src/skcapstone/mcp_tools/trust_tools.py +118 -0
  240. package/src/skcapstone/mcp_tools/trustee_tools.py +345 -0
  241. package/src/skcapstone/mdns_discovery.py +313 -0
  242. package/src/skcapstone/memory_adapter.py +333 -0
  243. package/src/skcapstone/memory_compressor.py +379 -0
  244. package/src/skcapstone/memory_curator.py +256 -0
  245. package/src/skcapstone/memory_engine.py +132 -13
  246. package/src/skcapstone/memory_fortress.py +529 -0
  247. package/src/skcapstone/memory_promoter.py +722 -0
  248. package/src/skcapstone/memory_verifier.py +260 -0
  249. package/src/skcapstone/message_crypto.py +215 -0
  250. package/src/skcapstone/metrics.py +832 -0
  251. package/src/skcapstone/migrate_memories.py +181 -0
  252. package/src/skcapstone/migrate_multi_agent.py +248 -0
  253. package/src/skcapstone/model_router.py +319 -0
  254. package/src/skcapstone/models.py +35 -4
  255. package/src/skcapstone/mood.py +344 -0
  256. package/src/skcapstone/notifications.py +380 -0
  257. package/src/skcapstone/onboard.py +901 -0
  258. package/src/skcapstone/peer_directory.py +324 -0
  259. package/src/skcapstone/peers.py +329 -0
  260. package/src/skcapstone/pillars/identity.py +84 -14
  261. package/src/skcapstone/pillars/memory.py +3 -1
  262. package/src/skcapstone/pillars/security.py +108 -15
  263. package/src/skcapstone/pillars/sync.py +78 -26
  264. package/src/skcapstone/pillars/trust.py +95 -33
  265. package/src/skcapstone/plugins.py +244 -0
  266. package/src/skcapstone/preflight.py +670 -0
  267. package/src/skcapstone/prompt_adapter.py +564 -0
  268. package/src/skcapstone/providers/__init__.py +13 -0
  269. package/src/skcapstone/providers/cloud.py +1061 -0
  270. package/src/skcapstone/providers/docker.py +759 -0
  271. package/src/skcapstone/providers/local.py +1193 -0
  272. package/src/skcapstone/providers/proxmox.py +447 -0
  273. package/src/skcapstone/pubsub.py +516 -0
  274. package/src/skcapstone/rate_limiter.py +119 -0
  275. package/src/skcapstone/register.py +241 -0
  276. package/src/skcapstone/registry_client.py +151 -0
  277. package/src/skcapstone/response_cache.py +194 -0
  278. package/src/skcapstone/response_scorer.py +225 -0
  279. package/src/skcapstone/runtime.py +89 -33
  280. package/src/skcapstone/scheduled_tasks.py +439 -0
  281. package/src/skcapstone/self_healing.py +341 -0
  282. package/src/skcapstone/service_health.py +228 -0
  283. package/src/skcapstone/session_capture.py +268 -0
  284. package/src/skcapstone/session_recorder.py +210 -0
  285. package/src/skcapstone/session_replayer.py +189 -0
  286. package/src/skcapstone/session_skills.py +263 -0
  287. package/src/skcapstone/shell.py +779 -0
  288. package/src/skcapstone/skills/__init__.py +1 -1
  289. package/src/skcapstone/skills/syncthing_setup.py +143 -41
  290. package/src/skcapstone/skjoule.py +861 -0
  291. package/src/skcapstone/snapshots.py +489 -0
  292. package/src/skcapstone/soul.py +1060 -0
  293. package/src/skcapstone/soul_switch.py +255 -0
  294. package/src/skcapstone/spawner.py +544 -0
  295. package/src/skcapstone/state_diff.py +401 -0
  296. package/src/skcapstone/summary.py +270 -0
  297. package/src/skcapstone/sync/backends.py +196 -2
  298. package/src/skcapstone/sync/engine.py +7 -5
  299. package/src/skcapstone/sync/models.py +4 -1
  300. package/src/skcapstone/sync/vault.py +356 -18
  301. package/src/skcapstone/sync_engine.py +363 -0
  302. package/src/skcapstone/sync_watcher.py +745 -0
  303. package/src/skcapstone/systemd.py +331 -0
  304. package/src/skcapstone/team_comms.py +476 -0
  305. package/src/skcapstone/team_engine.py +522 -0
  306. package/src/skcapstone/testrunner.py +300 -0
  307. package/src/skcapstone/tls.py +150 -0
  308. package/src/skcapstone/tokens.py +5 -5
  309. package/src/skcapstone/trust_calibration.py +202 -0
  310. package/src/skcapstone/trust_graph.py +449 -0
  311. package/src/skcapstone/trustee_monitor.py +385 -0
  312. package/src/skcapstone/trustee_ops.py +425 -0
  313. package/src/skcapstone/unified_search.py +421 -0
  314. package/src/skcapstone/uninstall_wizard.py +694 -0
  315. package/src/skcapstone/usage.py +331 -0
  316. package/src/skcapstone/version_check.py +148 -0
  317. package/src/skcapstone/warmth_anchor.py +333 -0
  318. package/src/skcapstone/whoami.py +294 -0
  319. package/systemd/skcapstone-api.socket +9 -0
  320. package/systemd/skcapstone-memory-compress.service +18 -0
  321. package/systemd/skcapstone-memory-compress.timer +11 -0
  322. package/systemd/skcapstone.service +36 -0
  323. package/systemd/skcapstone@.service +50 -0
  324. package/systemd/skcomm-heartbeat.service +18 -0
  325. package/systemd/skcomm-heartbeat.timer +12 -0
  326. package/systemd/skcomm-queue-drain.service +17 -0
  327. package/systemd/skcomm-queue-drain.timer +12 -0
  328. package/tests/conftest.py +13 -1
  329. package/tests/integration/__init__.py +1 -0
  330. package/tests/integration/test_consciousness_e2e.py +877 -0
  331. package/tests/integration/test_skills_registry.py +744 -0
  332. package/tests/test_agent_card.py +190 -0
  333. package/tests/test_agent_runtime.py +1283 -0
  334. package/tests/test_alerts_cmd.py +291 -0
  335. package/tests/test_archiver.py +498 -0
  336. package/tests/test_backup.py +254 -0
  337. package/tests/test_benchmark.py +366 -0
  338. package/tests/test_blueprints.py +457 -0
  339. package/tests/test_capabilities.py +257 -0
  340. package/tests/test_changelog.py +254 -0
  341. package/tests/test_chat.py +385 -0
  342. package/tests/test_claude_md.py +271 -0
  343. package/tests/test_cli_chat_llm.py +336 -0
  344. package/tests/test_cli_completions.py +390 -0
  345. package/tests/test_cli_init_reset.py +164 -0
  346. package/tests/test_cli_memory.py +208 -0
  347. package/tests/test_cli_profile.py +294 -0
  348. package/tests/test_cli_skills.py +223 -0
  349. package/tests/test_cli_status.py +395 -0
  350. package/tests/test_cli_test_cmd.py +206 -0
  351. package/tests/test_cli_test_connection.py +364 -0
  352. package/tests/test_cloud9_bridge.py +260 -0
  353. package/tests/test_cloud_provider.py +449 -0
  354. package/tests/test_cloud_providers.py +522 -0
  355. package/tests/test_completions.py +158 -0
  356. package/tests/test_component_manager.py +398 -0
  357. package/tests/test_config_reload.py +386 -0
  358. package/tests/test_config_validate.py +529 -0
  359. package/tests/test_consciousness_e2e.py +296 -0
  360. package/tests/test_consciousness_loop.py +1289 -0
  361. package/tests/test_context_loader.py +310 -0
  362. package/tests/test_conversation_api.py +306 -0
  363. package/tests/test_conversation_manager.py +381 -0
  364. package/tests/test_conversation_store.py +391 -0
  365. package/tests/test_conversation_summarizer.py +302 -0
  366. package/tests/test_cross_package.py +791 -0
  367. package/tests/test_crush_shim.py +519 -0
  368. package/tests/test_daemon.py +781 -0
  369. package/tests/test_daemon_shutdown.py +309 -0
  370. package/tests/test_dashboard.py +454 -0
  371. package/tests/test_discovery.py +200 -6
  372. package/tests/test_docker_provider.py +966 -0
  373. package/tests/test_doctor.py +257 -0
  374. package/tests/test_doctor_fix.py +351 -0
  375. package/tests/test_e2e_automated.py +292 -0
  376. package/tests/test_error_queue.py +404 -0
  377. package/tests/test_export.py +441 -0
  378. package/tests/test_fallback_tracker.py +219 -0
  379. package/tests/test_file_transfer.py +397 -0
  380. package/tests/test_fuse_mount.py +832 -0
  381. package/tests/test_health_loop.py +422 -0
  382. package/tests/test_heartbeat.py +354 -0
  383. package/tests/test_housekeeping.py +195 -0
  384. package/tests/test_identity_capauth.py +307 -0
  385. package/tests/test_identity_pillar.py +117 -0
  386. package/tests/test_install_wizard.py +68 -0
  387. package/tests/test_integration.py +325 -0
  388. package/tests/test_kms.py +495 -0
  389. package/tests/test_llm_providers.py +265 -0
  390. package/tests/test_local_provider.py +591 -0
  391. package/tests/test_log_config.py +199 -0
  392. package/tests/test_logs_cmd.py +287 -0
  393. package/tests/test_mcp_server.py +1909 -0
  394. package/tests/test_memory_adapter.py +339 -0
  395. package/tests/test_memory_curator.py +218 -0
  396. package/tests/test_memory_engine.py +6 -0
  397. package/tests/test_memory_fortress.py +571 -0
  398. package/tests/test_memory_pillar.py +119 -0
  399. package/tests/test_memory_promoter.py +445 -0
  400. package/tests/test_memory_verifier.py +420 -0
  401. package/tests/test_message_crypto.py +187 -0
  402. package/tests/test_metrics.py +632 -0
  403. package/tests/test_migrate_memories.py +464 -0
  404. package/tests/test_model_router.py +546 -0
  405. package/tests/test_mood.py +394 -0
  406. package/tests/test_multi_agent.py +269 -0
  407. package/tests/test_notifications.py +270 -0
  408. package/tests/test_onboard.py +500 -0
  409. package/tests/test_peer_directory.py +395 -0
  410. package/tests/test_peers.py +248 -0
  411. package/tests/test_pillars.py +87 -9
  412. package/tests/test_preflight.py +484 -0
  413. package/tests/test_prompt_adapter.py +331 -0
  414. package/tests/test_proxmox_provider.py +571 -0
  415. package/tests/test_pubsub.py +377 -0
  416. package/tests/test_rate_limiter.py +121 -0
  417. package/tests/test_registry_client.py +129 -0
  418. package/tests/test_response_cache.py +312 -0
  419. package/tests/test_response_scorer.py +294 -0
  420. package/tests/test_runtime.py +59 -0
  421. package/tests/test_scheduled_tasks.py +451 -0
  422. package/tests/test_security.py +250 -0
  423. package/tests/test_security_pillar.py +213 -0
  424. package/tests/test_self_healing.py +171 -0
  425. package/tests/test_session_capture.py +200 -0
  426. package/tests/test_session_recorder.py +360 -0
  427. package/tests/test_session_skills.py +235 -0
  428. package/tests/test_shell.py +210 -0
  429. package/tests/test_snapshots.py +549 -0
  430. package/tests/test_soul.py +984 -0
  431. package/tests/test_soul_swap.py +406 -0
  432. package/tests/test_spawner.py +211 -0
  433. package/tests/test_state_diff.py +173 -0
  434. package/tests/test_summary.py +135 -0
  435. package/tests/test_sync.py +315 -5
  436. package/tests/test_sync_backends.py +560 -0
  437. package/tests/test_sync_engine.py +482 -0
  438. package/tests/test_sync_pillar.py +344 -0
  439. package/tests/test_sync_pipeline.py +364 -0
  440. package/tests/test_sync_vault.py +581 -0
  441. package/tests/test_syncthing_setup.py +168 -22
  442. package/tests/test_systemd.py +323 -0
  443. package/tests/test_team_comms.py +408 -0
  444. package/tests/test_team_engine.py +397 -0
  445. package/tests/test_testrunner.py +238 -0
  446. package/tests/test_trust_calibration.py +204 -0
  447. package/tests/test_trust_graph.py +207 -0
  448. package/tests/test_trust_pillar.py +291 -0
  449. package/tests/test_trustee_cli.py +427 -0
  450. package/tests/test_trustee_cli_integration.py +325 -0
  451. package/tests/test_trustee_monitor.py +394 -0
  452. package/tests/test_trustee_ops.py +355 -0
  453. package/tests/test_unified_search.py +363 -0
  454. package/tests/test_uninstall_wizard.py +193 -0
  455. package/tests/test_usage.py +333 -0
  456. package/tests/test_version_cmd.py +355 -0
  457. package/tests/test_warmth_anchor.py +162 -0
  458. package/tests/test_whoami.py +245 -0
  459. package/tests/test_ws.py +311 -0
  460. package/.cursorrules +0 -33
  461. package/src/skcapstone/cli.py +0 -1441
@@ -0,0 +1,425 @@
1
+ """
2
+ Trustee Operations — autonomous agent team management for AI trustees.
3
+
4
+ Provides restart, scale, rotate, health-report, and log retrieval
5
+ operations on deployed teams. All mutations are written to an audit
6
+ trail so every trustee action is transparent and accountable.
7
+
8
+ Designed for AI trustees (Lumina, Opus) and human trustees (Chef)
9
+ operating under the Trustee Oath:
10
+ "I escalate when uncertain — never guess with sovereignty."
11
+
12
+ Private helpers (audit, snapshot, log utilities) live in
13
+ _trustee_helpers.py to keep this module under 500 lines.
14
+ """
15
+
16
+ from __future__ import annotations
17
+
18
+ import logging
19
+ from datetime import datetime, timezone
20
+ from pathlib import Path
21
+ from typing import Any, Dict, List, Optional
22
+
23
+ from ._trustee_helpers import (
24
+ audit_lines_for_agent,
25
+ refresh_deployment_status,
26
+ snapshot_agent_context,
27
+ stub_spec,
28
+ write_audit,
29
+ )
30
+ from .team_engine import AgentStatus, DeployedAgent, TeamDeployment, TeamEngine
31
+
32
+ logger = logging.getLogger(__name__)
33
+
34
+ # Re-export for external callers (e.g. tests that import _write_audit)
35
+ _write_audit = write_audit
36
+
37
+
38
+ class TrusteeOps:
39
+ """High-level trustee operations over a deployed team.
40
+
41
+ Args:
42
+ engine: A configured TeamEngine instance.
43
+ home: Agent home directory (used for audit log path).
44
+ """
45
+
46
+ def __init__(
47
+ self,
48
+ engine: TeamEngine,
49
+ home: Optional[Path] = None,
50
+ ) -> None:
51
+ self._engine = engine
52
+ self._home = (home or Path("~/.skcapstone")).expanduser()
53
+
54
+ # ------------------------------------------------------------------
55
+ # Internal helpers
56
+ # ------------------------------------------------------------------
57
+
58
+ def _audit(self, action: str, deployment_id: str, **details: Any) -> None:
59
+ """Write an audit entry.
60
+
61
+ Args:
62
+ action: Action label.
63
+ deployment_id: Deployment being acted on.
64
+ **details: Additional context fields.
65
+ """
66
+ write_audit(action, deployment_id, details, home=self._home)
67
+
68
+ def _provision_result(self, agent: DeployedAgent) -> Dict[str, Any]:
69
+ """Build a minimal provision_result dict from a DeployedAgent.
70
+
71
+ Args:
72
+ agent: The deployed agent.
73
+
74
+ Returns:
75
+ Dict compatible with ProviderBackend methods.
76
+ """
77
+ return {
78
+ "host": agent.host,
79
+ "pid": agent.pid,
80
+ "container_id": agent.container_id,
81
+ }
82
+
83
+ # ------------------------------------------------------------------
84
+ # Restart
85
+ # ------------------------------------------------------------------
86
+
87
+ def restart_agent(
88
+ self,
89
+ deployment_id: str,
90
+ agent_name: Optional[str] = None,
91
+ ) -> Dict[str, str]:
92
+ """Restart a failed agent or every agent in a team.
93
+
94
+ Calls provider stop → start for each target agent, updates the
95
+ deployment state, and writes an audit entry.
96
+
97
+ Args:
98
+ deployment_id: Target deployment.
99
+ agent_name: If given, restart only this agent; otherwise
100
+ restart all agents in the deployment.
101
+
102
+ Returns:
103
+ Dict mapping agent names to "restarted" or error strings.
104
+
105
+ Raises:
106
+ ValueError: If deployment or agent is not found.
107
+ """
108
+ deployment = self._engine.get_deployment(deployment_id)
109
+ if not deployment:
110
+ raise ValueError(f"Deployment '{deployment_id}' not found.")
111
+
112
+ if agent_name:
113
+ if agent_name not in deployment.agents:
114
+ raise ValueError(
115
+ f"Agent '{agent_name}' not in deployment '{deployment_id}'."
116
+ )
117
+ targets = {agent_name: deployment.agents[agent_name]}
118
+ else:
119
+ targets = dict(deployment.agents)
120
+
121
+ results: Dict[str, str] = {}
122
+ provider = self._engine._provider
123
+
124
+ for name, agent in targets.items():
125
+ provision = self._provision_result(agent)
126
+ try:
127
+ if provider:
128
+ provider.stop(name, provision)
129
+ provider.start(name, provision)
130
+ agent.status = AgentStatus.RUNNING
131
+ agent.last_heartbeat = datetime.now(timezone.utc).isoformat()
132
+ agent.error = None
133
+ results[name] = "restarted"
134
+ logger.info("Restarted agent %s in %s", name, deployment_id)
135
+ except Exception as exc:
136
+ agent.status = AgentStatus.FAILED
137
+ agent.error = str(exc)
138
+ results[name] = f"error: {exc}"
139
+ logger.error("Failed to restart %s: %s", name, exc)
140
+
141
+ refresh_deployment_status(deployment)
142
+ self._engine._save_deployment(deployment)
143
+ self._audit("restart_agent", deployment_id, agent_name=agent_name or "ALL", results=results)
144
+ return results
145
+
146
+ # ------------------------------------------------------------------
147
+ # Scale
148
+ # ------------------------------------------------------------------
149
+
150
+ def scale_agent(
151
+ self,
152
+ deployment_id: str,
153
+ agent_spec_key: str,
154
+ count: int,
155
+ ) -> Dict[str, Any]:
156
+ """Scale the number of instances for an agent type up or down.
157
+
158
+ Adds or removes instances while updating persisted deployment
159
+ state. Scaling down stops excess instances; scaling up
160
+ provisions new ones (dry-run if no provider).
161
+
162
+ Args:
163
+ deployment_id: Target deployment.
164
+ agent_spec_key: The agent spec key (role identifier) to scale.
165
+ count: Desired total instance count (must be >= 1).
166
+
167
+ Returns:
168
+ Dict with "added", "removed", and "current_count" keys.
169
+
170
+ Raises:
171
+ ValueError: If deployment not found or count < 1.
172
+ """
173
+ if count < 1:
174
+ raise ValueError("count must be >= 1.")
175
+
176
+ deployment = self._engine.get_deployment(deployment_id)
177
+ if not deployment:
178
+ raise ValueError(f"Deployment '{deployment_id}' not found.")
179
+
180
+ current = {
181
+ name: agent
182
+ for name, agent in deployment.agents.items()
183
+ if agent.agent_spec_key == agent_spec_key
184
+ }
185
+ current_count = len(current)
186
+ added: List[str] = []
187
+ removed: List[str] = []
188
+ provider = self._engine._provider
189
+
190
+ if count > current_count:
191
+ for i in range(current_count + 1, count + 1):
192
+ new_name = f"{deployment.blueprint_slug}-{agent_spec_key}-{i}"
193
+ new_agent = DeployedAgent(
194
+ name=new_name,
195
+ instance_id=f"{deployment_id}/{new_name}",
196
+ blueprint_slug=deployment.blueprint_slug,
197
+ agent_spec_key=agent_spec_key,
198
+ provider=deployment.provider,
199
+ status=AgentStatus.PENDING,
200
+ host="localhost",
201
+ )
202
+ if provider:
203
+ try:
204
+ new_agent.status = AgentStatus.RUNNING
205
+ new_agent.started_at = datetime.now(timezone.utc).isoformat()
206
+ new_agent.last_heartbeat = new_agent.started_at
207
+ except Exception as exc:
208
+ new_agent.status = AgentStatus.FAILED
209
+ new_agent.error = str(exc)
210
+ deployment.agents[new_name] = new_agent
211
+ added.append(new_name)
212
+ logger.info("Scaled up: added %s", new_name)
213
+
214
+ elif count < current_count:
215
+ to_remove = sorted(current.keys())[(count):]
216
+ for name in to_remove:
217
+ agent = deployment.agents[name]
218
+ provision = self._provision_result(agent)
219
+ if provider:
220
+ try:
221
+ provider.stop(name, provision)
222
+ except Exception as exc:
223
+ logger.warning("Error stopping %s during scale: %s", name, exc)
224
+ del deployment.agents[name]
225
+ removed.append(name)
226
+ logger.info("Scaled down: removed %s", name)
227
+
228
+ refresh_deployment_status(deployment)
229
+ self._engine._save_deployment(deployment)
230
+ self._audit(
231
+ "scale_agent", deployment_id,
232
+ agent_spec_key=agent_spec_key, desired_count=count,
233
+ added=added, removed=removed,
234
+ )
235
+ return {"added": added, "removed": removed, "current_count": count}
236
+
237
+ # ------------------------------------------------------------------
238
+ # Rotate
239
+ # ------------------------------------------------------------------
240
+
241
+ def rotate_agent(
242
+ self,
243
+ deployment_id: str,
244
+ agent_name: str,
245
+ ) -> Dict[str, Any]:
246
+ """Snapshot context, destroy, and redeploy an agent fresh.
247
+
248
+ Used when an agent shows context degradation. Snapshots the
249
+ agent's memory directory before destruction so nothing is lost.
250
+
251
+ Args:
252
+ deployment_id: Target deployment.
253
+ agent_name: Name of the specific agent instance to rotate.
254
+
255
+ Returns:
256
+ Dict with "snapshot_path", "destroyed", "redeployed" keys.
257
+
258
+ Raises:
259
+ ValueError: If deployment or agent is not found.
260
+ """
261
+ deployment = self._engine.get_deployment(deployment_id)
262
+ if not deployment:
263
+ raise ValueError(f"Deployment '{deployment_id}' not found.")
264
+
265
+ if agent_name not in deployment.agents:
266
+ raise ValueError(f"Agent '{agent_name}' not in deployment '{deployment_id}'.")
267
+
268
+ agent = deployment.agents[agent_name]
269
+ provider = self._engine._provider
270
+ snapshot_path = snapshot_agent_context(self._home, agent_name)
271
+
272
+ destroyed = False
273
+ if provider:
274
+ try:
275
+ provider.destroy(agent_name, self._provision_result(agent))
276
+ destroyed = True
277
+ except Exception as exc:
278
+ logger.error("Rotation destroy failed for %s: %s", agent_name, exc)
279
+
280
+ agent.status = AgentStatus.RUNNING if not provider else AgentStatus.PENDING
281
+ agent.pid = None
282
+ agent.container_id = None
283
+ agent.error = None
284
+ agent.started_at = datetime.now(timezone.utc).isoformat()
285
+ agent.last_heartbeat = agent.started_at
286
+
287
+ if provider:
288
+ try:
289
+ result = provider.provision(agent_name, stub_spec(), deployment.team_name)
290
+ provider.configure(agent_name, stub_spec(), result)
291
+ provider.start(agent_name, result)
292
+ agent.status = AgentStatus.RUNNING
293
+ agent.host = result.get("host", agent.host)
294
+ agent.pid = result.get("pid", agent.pid)
295
+ except Exception as exc:
296
+ agent.status = AgentStatus.FAILED
297
+ agent.error = str(exc)
298
+ logger.error("Rotation redeploy failed for %s: %s", agent_name, exc)
299
+
300
+ refresh_deployment_status(deployment)
301
+ self._engine._save_deployment(deployment)
302
+
303
+ result_data = {
304
+ "snapshot_path": str(snapshot_path),
305
+ "destroyed": destroyed,
306
+ "redeployed": agent.status == AgentStatus.RUNNING,
307
+ }
308
+ self._audit("rotate_agent", deployment_id, agent_name=agent_name, **result_data)
309
+ return result_data
310
+
311
+ # ------------------------------------------------------------------
312
+ # Health report
313
+ # ------------------------------------------------------------------
314
+
315
+ def health_report(self, deployment_id: str) -> List[Dict[str, Any]]:
316
+ """Run health checks on all agents and return a status table.
317
+
318
+ Calls provider.health_check for each agent when a provider is
319
+ available; otherwise returns the cached status from disk.
320
+
321
+ Args:
322
+ deployment_id: Target deployment.
323
+
324
+ Returns:
325
+ List of dicts per agent: name, status, host, last_heartbeat,
326
+ error, healthy.
327
+
328
+ Raises:
329
+ ValueError: If deployment not found.
330
+ """
331
+ deployment = self._engine.get_deployment(deployment_id)
332
+ if not deployment:
333
+ raise ValueError(f"Deployment '{deployment_id}' not found.")
334
+
335
+ provider = self._engine._provider
336
+ report: List[Dict[str, Any]] = []
337
+
338
+ for name, agent in deployment.agents.items():
339
+ provision = self._provision_result(agent)
340
+ live_status = agent.status
341
+
342
+ if provider:
343
+ try:
344
+ live_status = provider.health_check(name, provision)
345
+ agent.status = live_status
346
+ if live_status == AgentStatus.RUNNING:
347
+ agent.last_heartbeat = datetime.now(timezone.utc).isoformat()
348
+ except Exception as exc:
349
+ live_status = AgentStatus.DEGRADED
350
+ agent.status = live_status
351
+ agent.error = str(exc)
352
+
353
+ report.append({
354
+ "name": name,
355
+ "status": live_status.value,
356
+ "host": agent.host or "—",
357
+ "last_heartbeat": agent.last_heartbeat or "—",
358
+ "error": agent.error or "",
359
+ "healthy": live_status == AgentStatus.RUNNING,
360
+ })
361
+
362
+ refresh_deployment_status(deployment)
363
+ self._engine._save_deployment(deployment)
364
+ self._audit(
365
+ "health_report", deployment_id,
366
+ agent_count=len(report),
367
+ healthy=sum(1 for r in report if r["healthy"]),
368
+ )
369
+ return report
370
+
371
+ # ------------------------------------------------------------------
372
+ # Logs
373
+ # ------------------------------------------------------------------
374
+
375
+ def get_logs(
376
+ self,
377
+ deployment_id: str,
378
+ agent_name: Optional[str] = None,
379
+ tail: int = 50,
380
+ ) -> Dict[str, List[str]]:
381
+ """Return recent log lines for one or all agents in a deployment.
382
+
383
+ Reads from per-agent log files under the agents/local directory.
384
+ Falls back to audit.log entries filtered by agent name when no
385
+ dedicated log file exists.
386
+
387
+ Args:
388
+ deployment_id: Target deployment.
389
+ agent_name: If given, return logs only for this agent.
390
+ tail: Max lines per agent (default 50).
391
+
392
+ Returns:
393
+ Dict mapping agent name to list of log lines.
394
+
395
+ Raises:
396
+ ValueError: If deployment not found or agent not in deployment.
397
+ """
398
+ deployment = self._engine.get_deployment(deployment_id)
399
+ if not deployment:
400
+ raise ValueError(f"Deployment '{deployment_id}' not found.")
401
+
402
+ if agent_name:
403
+ if agent_name not in deployment.agents:
404
+ raise ValueError(
405
+ f"Agent '{agent_name}' not in deployment '{deployment_id}'."
406
+ )
407
+ names = [agent_name]
408
+ else:
409
+ names = list(deployment.agents.keys())
410
+
411
+ logs: Dict[str, List[str]] = {}
412
+ agents_dir = self._home / "agents" / "local"
413
+
414
+ for name in names:
415
+ log_file = agents_dir / name / "agent.log"
416
+ if log_file.exists():
417
+ all_lines = log_file.read_text(encoding="utf-8").splitlines()
418
+ logs[name] = all_lines[-tail:]
419
+ else:
420
+ logs[name] = audit_lines_for_agent(
421
+ self._home, deployment_id, name, tail=tail
422
+ )
423
+
424
+ self._audit("get_logs", deployment_id, agent_name=agent_name or "ALL", tail=tail)
425
+ return logs