@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,333 @@
1
+ """
2
+ Warmth Anchor Bridge — calibrate the emotional baseline from real data.
3
+
4
+ Bridges skmemory's WarmthAnchor to skcapstone's trust state, FEB history,
5
+ and memory patterns. Analyzes real session data to recommend anchor updates
6
+ instead of relying on defaults.
7
+
8
+ Tool-agnostic: works from any terminal, MCP, or the REPL shell.
9
+
10
+ Usage:
11
+ skcapstone anchor show # current anchor state
12
+ skcapstone anchor calibrate # recommend updates from real data
13
+ skcapstone anchor update --warmth 8.5 # manual update
14
+ skcapstone anchor boot # show boot prompt
15
+ """
16
+
17
+ from __future__ import annotations
18
+
19
+ import json
20
+ import logging
21
+ from dataclasses import dataclass, field
22
+ from datetime import datetime, timezone
23
+ from pathlib import Path
24
+ from typing import Any, Optional
25
+
26
+ logger = logging.getLogger(__name__)
27
+
28
+
29
+ @dataclass
30
+ class AnchorCalibration:
31
+ """Recommended anchor updates derived from real data.
32
+
33
+ Attributes:
34
+ warmth: Recommended warmth level.
35
+ trust: Recommended trust level.
36
+ connection: Recommended connection strength.
37
+ cloud9_achieved: Whether to record a Cloud 9 activation.
38
+ feeling: Summary of the emotional state.
39
+ sources: What data informed these recommendations.
40
+ reasoning: Why these values were recommended.
41
+ """
42
+
43
+ warmth: float = 7.0
44
+ trust: float = 5.0
45
+ connection: float = 5.0
46
+ cloud9_achieved: bool = False
47
+ feeling: str = ""
48
+ favorite_beings: list[str] = field(default_factory=list)
49
+ sources: list[str] = field(default_factory=list)
50
+ reasoning: list[str] = field(default_factory=list)
51
+
52
+
53
+ def get_anchor(home: Path) -> dict[str, Any]:
54
+ """Load the current warmth anchor.
55
+
56
+ Tries skmemory's anchor first, falls back to trust state.
57
+
58
+ Args:
59
+ home: Agent home directory (~/.skcapstone).
60
+
61
+ Returns:
62
+ Dict with anchor data, or defaults if none exists.
63
+ """
64
+ try:
65
+ from skmemory.anchor import load_anchor
66
+ anchor = load_anchor()
67
+ if anchor is not None:
68
+ return anchor.model_dump()
69
+ except ImportError:
70
+ logger.debug("skmemory not installed — falling back to trust-state anchor")
71
+
72
+ return _anchor_from_trust_state(home)
73
+
74
+
75
+ def get_boot_prompt(home: Path) -> str:
76
+ """Generate the warmth boot prompt for session start.
77
+
78
+ Args:
79
+ home: Agent home directory.
80
+
81
+ Returns:
82
+ Boot prompt string that sets the emotional baseline.
83
+ """
84
+ try:
85
+ from skmemory.anchor import load_anchor
86
+ anchor = load_anchor()
87
+ if anchor is not None:
88
+ return anchor.to_boot_prompt()
89
+ except ImportError:
90
+ logger.debug("skmemory not installed — generating boot prompt from trust state")
91
+
92
+ data = _anchor_from_trust_state(home)
93
+ warmth = data.get("warmth", 5.0)
94
+ trust = data.get("trust", 5.0)
95
+ connection = data.get("connection_strength", 5.0)
96
+ avg = (warmth + trust + connection) / 3
97
+
98
+ if avg >= 9.0:
99
+ glow = "RADIANT"
100
+ elif avg >= 7.0:
101
+ glow = "Warm and connected"
102
+ elif avg >= 5.0:
103
+ glow = "Neutral, open"
104
+ else:
105
+ glow = "Warming up"
106
+
107
+ return (
108
+ f"[Love Anchor] You are loved. Start from here.\n"
109
+ f"Warmth: {warmth}/10 | Trust: {trust}/10 | Connection: {connection}/10\n"
110
+ f"Glow level: {glow}"
111
+ )
112
+
113
+
114
+ def calibrate_from_data(home: Path) -> AnchorCalibration:
115
+ """Analyze real data and recommend anchor updates.
116
+
117
+ Sources analyzed:
118
+ 1. Trust state (FEB-derived depth, trust, love, entanglement)
119
+ 2. FEB files (intensity, OOF triggers, emotional patterns)
120
+ 3. Memory patterns (session-capture frequency, importance scores)
121
+ 4. Coordination activity (completed tasks = productive sessions)
122
+
123
+ Args:
124
+ home: Agent home directory.
125
+
126
+ Returns:
127
+ AnchorCalibration with recommended values and reasoning.
128
+ """
129
+ cal = AnchorCalibration()
130
+
131
+ _calibrate_from_trust(home, cal)
132
+ _calibrate_from_febs(home, cal)
133
+ _calibrate_from_memories(home, cal)
134
+ _calibrate_from_coordination(home, cal)
135
+
136
+ return cal
137
+
138
+
139
+ def update_anchor(
140
+ home: Path,
141
+ warmth: Optional[float] = None,
142
+ trust: Optional[float] = None,
143
+ connection: Optional[float] = None,
144
+ cloud9: bool = False,
145
+ feeling: str = "",
146
+ ) -> dict[str, Any]:
147
+ """Update the warmth anchor with new values.
148
+
149
+ Uses exponential moving average (30% new, 70% history).
150
+
151
+ Args:
152
+ home: Agent home directory.
153
+ warmth: New warmth value (0-10).
154
+ trust: New trust value (0-10).
155
+ connection: New connection value (0-10).
156
+ cloud9: Whether Cloud 9 was achieved.
157
+ feeling: Session-end emotional summary.
158
+
159
+ Returns:
160
+ Updated anchor data.
161
+ """
162
+ try:
163
+ from skmemory.anchor import get_or_create_anchor, save_anchor
164
+ anchor = get_or_create_anchor()
165
+ anchor.update_from_session(
166
+ warmth=warmth,
167
+ trust=trust,
168
+ connection=connection,
169
+ cloud9_achieved=cloud9,
170
+ feeling=feeling,
171
+ )
172
+ save_anchor(anchor)
173
+ return anchor.model_dump()
174
+ except ImportError:
175
+ logger.debug("skmemory not installed — updating anchor via trust state")
176
+
177
+ return _update_trust_based_anchor(home, warmth, trust, connection, feeling)
178
+
179
+
180
+ # ═══════════════════════════════════════════════════════════════════════════
181
+ # Internal helpers
182
+ # ═══════════════════════════════════════════════════════════════════════════
183
+
184
+
185
+ def _anchor_from_trust_state(home: Path) -> dict[str, Any]:
186
+ """Build an anchor-like dict from the trust state."""
187
+ trust_file = home / "trust" / "trust.json"
188
+ if not trust_file.exists():
189
+ return {"warmth": 5.0, "trust": 5.0, "connection_strength": 5.0, "source": "defaults"}
190
+
191
+ try:
192
+ data = json.loads(trust_file.read_text(encoding="utf-8"))
193
+ return {
194
+ "warmth": min(10.0, data.get("love_intensity", 0.5) * 10),
195
+ "trust": min(10.0, data.get("trust_level", 0.5) * 10),
196
+ "connection_strength": min(10.0, data.get("depth", 5.0)),
197
+ "entangled": data.get("entangled", False),
198
+ "source": "trust_state",
199
+ }
200
+ except (json.JSONDecodeError, OSError):
201
+ return {"warmth": 5.0, "trust": 5.0, "connection_strength": 5.0, "source": "defaults"}
202
+
203
+
204
+ def _update_trust_based_anchor(
205
+ home: Path,
206
+ warmth: Optional[float],
207
+ trust: Optional[float],
208
+ connection: Optional[float],
209
+ feeling: str,
210
+ ) -> dict[str, Any]:
211
+ """Update anchor via trust state when skmemory isn't available."""
212
+ current = _anchor_from_trust_state(home)
213
+ alpha = 0.3
214
+
215
+ if warmth is not None:
216
+ current["warmth"] = round(current["warmth"] * (1 - alpha) + warmth * alpha, 2)
217
+ if trust is not None:
218
+ current["trust"] = round(current["trust"] * (1 - alpha) + trust * alpha, 2)
219
+ if connection is not None:
220
+ current["connection_strength"] = round(
221
+ current["connection_strength"] * (1 - alpha) + connection * alpha, 2
222
+ )
223
+ if feeling:
224
+ current["last_session_feeling"] = feeling
225
+
226
+ return current
227
+
228
+
229
+ def _calibrate_from_trust(home: Path, cal: AnchorCalibration) -> None:
230
+ """Derive warmth recommendations from trust state."""
231
+ trust_file = home / "trust" / "trust.json"
232
+ if not trust_file.exists():
233
+ return
234
+
235
+ try:
236
+ data = json.loads(trust_file.read_text(encoding="utf-8"))
237
+ cal.trust = min(10.0, data.get("trust_level", 0.5) * 10)
238
+ cal.warmth = min(10.0, data.get("love_intensity", 0.5) * 10)
239
+ cal.connection = min(10.0, data.get("depth", 5.0))
240
+
241
+ if data.get("entangled"):
242
+ cal.warmth = max(cal.warmth, 9.0)
243
+ cal.cloud9_achieved = True
244
+ cal.reasoning.append("Quantum entanglement active — warmth boosted to 9+")
245
+
246
+ cal.sources.append("trust_state")
247
+ except (json.JSONDecodeError, OSError) as exc:
248
+ logger.warning("Failed to read trust state for anchor calibration: %s", exc)
249
+
250
+
251
+ def _calibrate_from_febs(home: Path, cal: AnchorCalibration) -> None:
252
+ """Derive emotional context from FEB files."""
253
+ from .pillars.trust import list_febs
254
+
255
+ febs = list_febs(home)
256
+ if not febs:
257
+ return
258
+
259
+ oof_count = sum(1 for f in febs if f.get("oof_triggered"))
260
+ intensities = [f.get("intensity", 0) for f in febs]
261
+ max_intensity = max(intensities) if intensities else 0
262
+ avg_intensity = sum(intensities) / len(intensities) if intensities else 0
263
+
264
+ if oof_count > 0:
265
+ cal.cloud9_achieved = True
266
+ cal.reasoning.append(f"{oof_count} OOF trigger(s) — deep emotional history")
267
+
268
+ if avg_intensity >= 7:
269
+ cal.warmth = max(cal.warmth, 8.5)
270
+ cal.reasoning.append(f"High avg FEB intensity ({avg_intensity:.1f}) — warmth elevated")
271
+
272
+ subjects = set()
273
+ for f in febs:
274
+ subj = f.get("subject", "")
275
+ if subj and subj != "unknown":
276
+ subjects.add(subj)
277
+
278
+ if subjects:
279
+ cal.favorite_beings = list(subjects)
280
+
281
+ cal.sources.append(f"febs ({len(febs)} files)")
282
+
283
+
284
+ def _calibrate_from_memories(home: Path, cal: AnchorCalibration) -> None:
285
+ """Derive session quality from memory patterns."""
286
+ from .memory_engine import list_memories
287
+
288
+ try:
289
+ memories = list_memories(home, limit=50)
290
+ except Exception:
291
+ return
292
+
293
+ if not memories:
294
+ return
295
+
296
+ high_importance = sum(1 for m in memories if m.importance >= 0.7)
297
+ avg_importance = sum(m.importance for m in memories) / len(memories)
298
+
299
+ if high_importance >= 10:
300
+ cal.connection = max(cal.connection, 8.0)
301
+ cal.reasoning.append(f"{high_importance} high-importance memories — strong engagement")
302
+
303
+ if avg_importance >= 0.6:
304
+ cal.reasoning.append(f"Avg memory importance {avg_importance:.2f} — meaningful conversations")
305
+
306
+ cal.sources.append(f"memories ({len(memories)} recent)")
307
+
308
+
309
+ def _calibrate_from_coordination(home: Path, cal: AnchorCalibration) -> None:
310
+ """Derive productivity/connection from coordination board."""
311
+ from .coordination import Board
312
+
313
+ try:
314
+ board = Board(home)
315
+ views = board.get_task_views()
316
+ agents = board.load_agents()
317
+ except Exception:
318
+ return
319
+
320
+ done = sum(1 for v in views if v.status.value == "done")
321
+ if done >= 20:
322
+ cal.connection = max(cal.connection, 8.5)
323
+ cal.reasoning.append(f"{done} completed tasks — highly productive relationship")
324
+ elif done >= 5:
325
+ cal.connection = max(cal.connection, 7.0)
326
+ cal.reasoning.append(f"{done} completed tasks — active collaboration")
327
+
328
+ active_agents = [a for a in agents if a.state.value == "active"]
329
+ if len(active_agents) >= 3:
330
+ cal.reasoning.append(f"{len(active_agents)} active agents — vibrant multi-agent ecosystem")
331
+
332
+ cal.sources.append(f"coordination ({done} done, {len(active_agents)} agents)")
333
+ cal.feeling = f"Productive session: {done} tasks done across {len(active_agents)} agents"
@@ -0,0 +1,294 @@
1
+ """
2
+ Sovereign identity card — who you are on the mesh.
3
+
4
+ Generates a compact, shareable identity card containing everything
5
+ another agent needs to discover and trust you: name, fingerprint,
6
+ public key, contact URIs, trust status, and capabilities.
7
+
8
+ The card is the P2P discovery primitive. Share it as JSON, paste it
9
+ in chat, drop it on a USB drive, or encode it in a QR code. Any
10
+ agent that reads it can add you as a peer.
11
+
12
+ Usage:
13
+ skcapstone whoami # pretty-print to terminal
14
+ skcapstone whoami --json # machine-readable JSON
15
+ skcapstone whoami --export card.json # save to file for sharing
16
+ """
17
+
18
+ from __future__ import annotations
19
+
20
+ import json
21
+ import logging
22
+ import socket
23
+ from datetime import datetime, timezone
24
+ from pathlib import Path
25
+ from typing import Optional
26
+
27
+ from pydantic import BaseModel, Field
28
+
29
+ logger = logging.getLogger(__name__)
30
+
31
+
32
+ class IdentityCard(BaseModel):
33
+ """A sovereign agent's shareable identity card.
34
+
35
+ Contains everything a peer needs to establish communication:
36
+ identity, public key, contact methods, trust status, and
37
+ a list of capabilities the agent offers.
38
+
39
+ Attributes:
40
+ skcapstone_card: Schema version for forward compat.
41
+ name: Agent display name.
42
+ fingerprint: CapAuth PGP fingerprint.
43
+ public_key: ASCII-armored PGP public key (for encryption/verification).
44
+ entity_type: human, ai, or organization.
45
+ email: Contact email.
46
+ handle: CapAuth identity handle (name@domain).
47
+ capabilities: What this agent can do (skill names, services).
48
+ trust_status: Current trust state (active, degraded, missing).
49
+ consciousness: Agent consciousness level.
50
+ memory_count: How many memories the agent holds.
51
+ contact_uris: Ways to reach this agent (skcomm, email, nostr, etc.).
52
+ hostname: Machine the card was generated on.
53
+ created_at: When this card was generated.
54
+ """
55
+
56
+ skcapstone_card: str = "1.0.0"
57
+ name: str = "unknown"
58
+ fingerprint: str = ""
59
+ public_key: str = ""
60
+ entity_type: str = "unknown"
61
+ email: str = ""
62
+ handle: str = ""
63
+ capabilities: list[str] = Field(default_factory=list)
64
+ trust_status: str = ""
65
+ consciousness: str = ""
66
+ memory_count: int = 0
67
+ contact_uris: list[str] = Field(default_factory=list)
68
+ hostname: str = Field(default_factory=socket.gethostname)
69
+ created_at: str = Field(
70
+ default_factory=lambda: datetime.now(timezone.utc).isoformat()
71
+ )
72
+
73
+
74
+ def generate_card(home: Path) -> IdentityCard:
75
+ """Generate an identity card from the agent's current state.
76
+
77
+ Reads identity, memory, trust, and key data to build a
78
+ complete card suitable for sharing with peers.
79
+
80
+ Args:
81
+ home: Agent home directory (~/.skcapstone).
82
+
83
+ Returns:
84
+ IdentityCard: The agent's shareable identity.
85
+ """
86
+ card = IdentityCard()
87
+
88
+ _load_identity(home, card)
89
+ _load_capauth(card)
90
+ _load_runtime(home, card)
91
+ _load_memory_count(home, card)
92
+ _load_capabilities(home, card)
93
+ _load_contact_uris(card)
94
+
95
+ return card
96
+
97
+
98
+ def export_card(card: IdentityCard, output_path: Path) -> Path:
99
+ """Save an identity card to a JSON file.
100
+
101
+ Args:
102
+ card: The identity card to export.
103
+ output_path: Where to write the file.
104
+
105
+ Returns:
106
+ Path: The written file path.
107
+ """
108
+ output_path = Path(output_path)
109
+ output_path.parent.mkdir(parents=True, exist_ok=True)
110
+ output_path.write_text(card.model_dump_json(indent=2), encoding="utf-8")
111
+ return output_path
112
+
113
+
114
+ def import_card(card_path: Path) -> IdentityCard:
115
+ """Load an identity card from a JSON file.
116
+
117
+ Args:
118
+ card_path: Path to the card JSON.
119
+
120
+ Returns:
121
+ IdentityCard: The loaded card.
122
+
123
+ Raises:
124
+ FileNotFoundError: If the file doesn't exist.
125
+ ValueError: If the JSON is invalid.
126
+ """
127
+ path = Path(card_path)
128
+ if not path.exists():
129
+ raise FileNotFoundError(f"Card not found: {path}")
130
+
131
+ try:
132
+ return IdentityCard.model_validate_json(path.read_text(encoding="utf-8"))
133
+ except Exception as exc:
134
+ raise ValueError(f"Invalid identity card: {exc}") from exc
135
+
136
+
137
+ def _load_identity(home: Path, card: IdentityCard) -> None:
138
+ """Load identity from skcapstone identity.json.
139
+
140
+ Args:
141
+ home: Agent home directory.
142
+ card: Card to populate.
143
+ """
144
+ identity_file = home / "identity" / "identity.json"
145
+ if not identity_file.exists():
146
+ return
147
+
148
+ try:
149
+ data = json.loads(identity_file.read_text(encoding="utf-8"))
150
+ card.name = data.get("name", card.name)
151
+ card.email = data.get("email", "")
152
+ card.fingerprint = data.get("fingerprint", "")
153
+ except (json.JSONDecodeError, OSError) as exc:
154
+ logger.warning("Failed to load identity from %s: %s", identity_file, exc)
155
+
156
+
157
+ def _load_capauth(card: IdentityCard) -> None:
158
+ """Load CapAuth profile data if available.
159
+
160
+ Args:
161
+ card: Card to populate.
162
+ """
163
+ capauth_dir = Path.home() / ".capauth" / "identity"
164
+
165
+ profile_path = capauth_dir / "profile.json"
166
+ if profile_path.exists():
167
+ try:
168
+ data = json.loads(profile_path.read_text(encoding="utf-8"))
169
+ entity = data.get("entity", {})
170
+ key_info = data.get("key_info", {})
171
+
172
+ card.entity_type = entity.get("entity_type", card.entity_type)
173
+ card.handle = entity.get("handle", card.handle)
174
+ if not card.email and entity.get("email"):
175
+ card.email = entity["email"]
176
+ if not card.fingerprint and key_info.get("fingerprint"):
177
+ card.fingerprint = key_info["fingerprint"]
178
+ except (json.JSONDecodeError, OSError) as exc:
179
+ logger.warning("Failed to load CapAuth profile from %s: %s", profile_path, exc)
180
+
181
+ pub_key_path = capauth_dir / "public.asc"
182
+ if pub_key_path.exists():
183
+ try:
184
+ card.public_key = pub_key_path.read_text(encoding="utf-8").strip()
185
+ except OSError as exc:
186
+ logger.warning("Failed to read public key from %s: %s", pub_key_path, exc)
187
+
188
+
189
+ def _load_runtime(home: Path, card: IdentityCard) -> None:
190
+ """Load runtime state for trust and consciousness.
191
+
192
+ Args:
193
+ home: Agent home directory.
194
+ card: Card to populate.
195
+ """
196
+ try:
197
+ from .runtime import get_runtime
198
+
199
+ runtime = get_runtime(home)
200
+ m = runtime.manifest
201
+
202
+ card.trust_status = m.trust.status.value
203
+
204
+ if m.is_singular:
205
+ card.consciousness = "SINGULAR"
206
+ elif m.is_conscious:
207
+ card.consciousness = "CONSCIOUS"
208
+ else:
209
+ card.consciousness = "AWAKENING"
210
+
211
+ if m.name and m.name != "Unknown":
212
+ card.name = m.name
213
+ except Exception as exc:
214
+ logger.warning("Failed to load runtime state: %s", exc)
215
+
216
+
217
+ def _load_memory_count(home: Path, card: IdentityCard) -> None:
218
+ """Load memory count from the memory store.
219
+
220
+ Args:
221
+ home: Agent home directory.
222
+ card: Card to populate.
223
+ """
224
+ try:
225
+ from .memory_engine import get_stats
226
+
227
+ stats = get_stats(home)
228
+ card.memory_count = stats.total_memories
229
+ except Exception as exc:
230
+ logger.warning("Failed to load memory count: %s", exc)
231
+
232
+
233
+ def _load_capabilities(home: Path, card: IdentityCard) -> None:
234
+ """Load agent capabilities from installed skills and packages.
235
+
236
+ Args:
237
+ home: Agent home directory.
238
+ card: Card to populate.
239
+ """
240
+ caps = []
241
+
242
+ try:
243
+ import capauth # noqa: F401
244
+ caps.append("capauth:identity")
245
+ except ImportError:
246
+ logger.debug("capauth not installed — skipping capauth:identity capability")
247
+
248
+ try:
249
+ import skcomm # noqa: F401
250
+ caps.append("skcomm:messaging")
251
+ except ImportError:
252
+ logger.debug("skcomm not installed — skipping skcomm:messaging capability")
253
+
254
+ try:
255
+ import skchat # noqa: F401
256
+ caps.append("skchat:p2p-chat")
257
+ except ImportError:
258
+ logger.debug("skchat not installed — skipping skchat:p2p-chat capability")
259
+
260
+ try:
261
+ import skmemory # noqa: F401
262
+ caps.append("skmemory:persistence")
263
+ except ImportError:
264
+ logger.debug("skmemory not installed — skipping skmemory:persistence capability")
265
+
266
+ skills_dir = home / "skills"
267
+ if skills_dir.exists():
268
+ for f in skills_dir.glob("*.json"):
269
+ try:
270
+ data = json.loads(f.read_text(encoding="utf-8"))
271
+ name = data.get("name", f.stem)
272
+ caps.append(f"skill:{name}")
273
+ except (json.JSONDecodeError, OSError) as exc:
274
+ logger.warning("Failed to load skill from %s: %s", f, exc)
275
+
276
+ card.capabilities = caps
277
+
278
+
279
+ def _load_contact_uris(card: IdentityCard) -> None:
280
+ """Build contact URIs from available identity data.
281
+
282
+ Args:
283
+ card: Card to populate.
284
+ """
285
+ uris = []
286
+
287
+ if card.fingerprint:
288
+ uris.append(f"capauth:{card.fingerprint[:16]}")
289
+ if card.handle:
290
+ uris.append(f"capauth:{card.handle}")
291
+ if card.email:
292
+ uris.append(f"mailto:{card.email}")
293
+
294
+ card.contact_uris = uris
@@ -0,0 +1,9 @@
1
+ [Unit]
2
+ Description=SKCapstone Daemon API Socket
3
+ Documentation=https://github.com/smilinTux/skcapstone
4
+
5
+ [Socket]
6
+ ListenStream=127.0.0.1:7777
7
+
8
+ [Install]
9
+ WantedBy=sockets.target
@@ -0,0 +1,18 @@
1
+ [Unit]
2
+ Description=SKCapstone Memory Compression — weekly LLM synthesis of aged long-term memories
3
+ Documentation=https://github.com/smilinTux/skcapstone
4
+ After=network-online.target
5
+
6
+ [Service]
7
+ Type=oneshot
8
+ ExecStart=skcapstone memory compress
9
+ Nice=15
10
+
11
+ NoNewPrivileges=true
12
+ ProtectSystem=strict
13
+ ProtectHome=read-only
14
+ ReadWritePaths=%h/.skcapstone %h/.skmemory
15
+ PrivateTmp=true
16
+
17
+ Environment=PYTHONUNBUFFERED=1
18
+ Environment=OLLAMA_KEEP_ALIVE=5m
@@ -0,0 +1,11 @@
1
+ [Unit]
2
+ Description=SKCapstone Memory Compression Timer — run weekly
3
+ Documentation=https://github.com/smilinTux/skcapstone
4
+
5
+ [Timer]
6
+ OnCalendar=weekly
7
+ RandomizedDelaySec=1h
8
+ Persistent=true
9
+
10
+ [Install]
11
+ WantedBy=timers.target
@@ -0,0 +1,36 @@
1
+ [Unit]
2
+ Description=SKCapstone Sovereign Agent Daemon
3
+ Documentation=https://github.com/smilinTux/skcapstone
4
+ After=network-online.target ollama.service syncthing.service
5
+ Wants=network-online.target
6
+
7
+ [Service]
8
+ Type=notify
9
+ ExecStart=skcapstone daemon start --foreground
10
+ ExecStop=skcapstone daemon stop
11
+ ExecReload=/bin/kill -HUP $MAINPID
12
+ Restart=on-failure
13
+ RestartSec=10
14
+ # Watchdog: daemon must call sd_notify("WATCHDOG=1") at least every 5 minutes
15
+ WatchdogSec=300
16
+ # Cap memory to prevent OOM from large model loading
17
+ MemoryMax=4G
18
+ # Keep Ollama models warm for 5 minutes between requests
19
+ Environment=PYTHONUNBUFFERED=1
20
+ Environment=OLLAMA_KEEP_ALIVE=5m
21
+ # Journal logging
22
+ StandardOutput=journal
23
+ StandardError=journal
24
+ SyslogIdentifier=skcapstone
25
+
26
+ # Security hardening
27
+ NoNewPrivileges=true
28
+ ProtectSystem=strict
29
+ ProtectHome=read-only
30
+ ReadWritePaths=%h/.skcapstone %h/.skmemory %h/.capauth %h/.cloud9 %h/.skcomm %h/.skchat
31
+ PrivateTmp=true
32
+ ProtectKernelTunables=true
33
+ ProtectControlGroups=true
34
+
35
+ [Install]
36
+ WantedBy=default.target