@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,791 @@
1
+ """Cross-package integration tests — end-to-end sovereign agent flow.
2
+
3
+ Exercises the real interfaces between packages:
4
+ capauth -> skcapstone (identity discovery)
5
+ skcapstone -> skmemory (built-in memory engine)
6
+ skcomm -> file transport (message send/receive)
7
+ skchat -> skmemory (chat history storage)
8
+ full pipeline: identity -> memory -> message -> coord -> sync
9
+
10
+ These tests import from multiple packages simultaneously to prove
11
+ they work together, not just in isolation.
12
+
13
+ Task: 1724f5f8
14
+ """
15
+
16
+ from __future__ import annotations
17
+
18
+ import json
19
+ from pathlib import Path
20
+ from unittest.mock import patch
21
+
22
+ import pytest
23
+
24
+ # ---------------------------------------------------------------------------
25
+ # Core skcapstone imports
26
+ # ---------------------------------------------------------------------------
27
+ from skcapstone.coordination import Board, Task, TaskPriority
28
+ from skcapstone.discovery import discover_all, discover_identity
29
+ from skcapstone.memory_engine import recall, search, store
30
+ from skcapstone.models import IdentityState, MemoryLayer, PillarStatus
31
+ from skcapstone.pillars.identity import generate_identity
32
+ from skcapstone.pillars.memory import initialize_memory
33
+ from skcapstone.pillars.security import audit_event, initialize_security, read_audit_log
34
+ from skcapstone.pillars.sync import collect_seed, initialize_sync
35
+ from skcapstone.pillars.trust import initialize_trust, record_trust_state
36
+ from skcapstone.runtime import AgentRuntime
37
+ from skcapstone.tokens import issue_token
38
+
39
+
40
+ def _init_full_agent(home: Path, name: str = "test-agent") -> None:
41
+ """Initialize all pillars for a test agent.
42
+
43
+ Args:
44
+ home: Agent home directory.
45
+ name: Agent display name.
46
+ """
47
+ generate_identity(home, name)
48
+ initialize_memory(home)
49
+ initialize_trust(home)
50
+ initialize_security(home)
51
+ initialize_sync(home)
52
+
53
+ manifest = {
54
+ "name": name,
55
+ "version": "0.1.0",
56
+ "created_at": "2026-01-01T00:00:00Z",
57
+ "connectors": [],
58
+ }
59
+ (home / "manifest.json").write_text(json.dumps(manifest, indent=2))
60
+ (home / "config").mkdir(exist_ok=True)
61
+
62
+ import yaml
63
+
64
+ config = {"agent_name": name}
65
+ (home / "config" / "config.yaml").write_text(
66
+ yaml.dump(config, default_flow_style=False)
67
+ )
68
+
69
+
70
+ # ═══════════════════════════════════════════════════════════════════════════
71
+ # 1. CapAuth <-> SKCapstone identity integration
72
+ # ═══════════════════════════════════════════════════════════════════════════
73
+
74
+
75
+ class TestCapAuthToSKCapstone:
76
+ """CapAuth profile data flows into skcapstone identity pillar."""
77
+
78
+ def test_discover_reads_capauth_profile(self, tmp_agent_home: Path):
79
+ """When a CapAuth profile exists, discover_identity uses its fingerprint."""
80
+ fake_state = IdentityState(
81
+ fingerprint="REAL" + "A" * 36,
82
+ name="capauth-agent",
83
+ email="agent@capauth.local",
84
+ key_path=Path("/tmp/public.asc"),
85
+ status=PillarStatus.ACTIVE,
86
+ )
87
+ with patch(
88
+ "skcapstone.discovery._try_load_capauth_profile",
89
+ return_value=fake_state,
90
+ ):
91
+ state = discover_identity(tmp_agent_home)
92
+
93
+ assert state.fingerprint.startswith("REAL")
94
+ assert state.status == PillarStatus.ACTIVE
95
+
96
+ manifest_path = tmp_agent_home / "identity" / "identity.json"
97
+ assert manifest_path.exists()
98
+ data = json.loads(manifest_path.read_text())
99
+ assert data["capauth_managed"] is True
100
+
101
+ def test_placeholder_without_capauth(self, tmp_agent_home: Path):
102
+ """Without CapAuth, generate_identity uses a placeholder."""
103
+ with patch(
104
+ "skcapstone.pillars.identity._try_init_capauth",
105
+ return_value=None,
106
+ ):
107
+ state = generate_identity(tmp_agent_home, "fallback")
108
+
109
+ assert state.status == PillarStatus.DEGRADED
110
+ assert len(state.fingerprint) == 40
111
+ data = json.loads(
112
+ (tmp_agent_home / "identity" / "identity.json").read_text()
113
+ )
114
+ assert data["capauth_managed"] is False
115
+
116
+ def test_capauth_models_importable(self):
117
+ """CapAuth core models are importable alongside skcapstone."""
118
+ from capauth.models import EntityInfo, KeyInfo, SovereignProfile
119
+
120
+ entity = EntityInfo(name="test", email="test@test.local")
121
+ assert entity.name == "test"
122
+
123
+
124
+ # ═══════════════════════════════════════════════════════════════════════════
125
+ # 2. SKComm file transport — cross-process message delivery
126
+ # ═══════════════════════════════════════════════════════════════════════════
127
+
128
+
129
+ class TestSKCommFileTransport:
130
+ """SKComm file transport sends and receives messages via filesystem."""
131
+
132
+ def test_send_and_receive_via_file_transport(self, tmp_path: Path):
133
+ """Message sent via file transport is receivable from the inbox."""
134
+ from skcomm.models import (
135
+ MessageEnvelope,
136
+ MessageMetadata,
137
+ MessagePayload,
138
+ MessageType,
139
+ RoutingConfig,
140
+ )
141
+ from skcomm.transports.file import FileTransport
142
+
143
+ outbox = tmp_path / "outbox"
144
+ inbox = tmp_path / "inbox"
145
+
146
+ sender_transport = FileTransport(outbox_path=outbox, inbox_path=inbox)
147
+ receiver_transport = FileTransport(outbox_path=inbox, inbox_path=outbox)
148
+
149
+ envelope = MessageEnvelope(
150
+ sender="opus",
151
+ recipient="jarvis",
152
+ payload=MessagePayload(
153
+ content="Hello from integration test",
154
+ content_type=MessageType.TEXT,
155
+ ),
156
+ )
157
+
158
+ result = sender_transport.send(envelope.to_bytes(), "jarvis")
159
+ assert result.success is True
160
+
161
+ # Receiver reads from the sender's outbox (simulating filesystem sync)
162
+ recv_transport = FileTransport(outbox_path=tmp_path / "noop", inbox_path=outbox)
163
+ raw_messages = recv_transport.receive()
164
+ assert len(raw_messages) >= 1
165
+
166
+ received = MessageEnvelope.from_bytes(raw_messages[0])
167
+ assert received.sender == "opus"
168
+ assert received.recipient == "jarvis"
169
+ assert received.payload.content == "Hello from integration test"
170
+
171
+ def test_multiple_messages_ordered(self, tmp_path: Path):
172
+ """Multiple messages are received in order."""
173
+ from skcomm.models import MessageEnvelope, MessagePayload, MessageType
174
+ from skcomm.transports.file import FileTransport
175
+
176
+ outbox = tmp_path / "outbox"
177
+ transport = FileTransport(outbox_path=outbox, inbox_path=tmp_path / "noop")
178
+
179
+ for i in range(3):
180
+ envelope = MessageEnvelope(
181
+ sender="opus",
182
+ recipient="jarvis",
183
+ payload=MessagePayload(
184
+ content=f"Message {i}",
185
+ content_type=MessageType.TEXT,
186
+ ),
187
+ )
188
+ transport.send(envelope.to_bytes(), "jarvis")
189
+
190
+ reader = FileTransport(outbox_path=tmp_path / "noop", inbox_path=outbox)
191
+ raw = reader.receive()
192
+ assert len(raw) == 3
193
+
194
+
195
+ # ═══════════════════════════════════════════════════════════════════════════
196
+ # 3. SKChat -> SKMemory integration (chat history as memories)
197
+ # ═══════════════════════════════════════════════════════════════════════════
198
+
199
+
200
+ class TestSKChatMemoryIntegration:
201
+ """SKChat messages stored as SKMemory memories."""
202
+
203
+ def test_chat_message_model_valid(self):
204
+ """SKChat ChatMessage can be created with standard fields."""
205
+ from skchat.models import ChatMessage, ContentType
206
+
207
+ msg = ChatMessage(
208
+ sender="opus",
209
+ recipient="jarvis",
210
+ content="Meeting at 3pm about sync architecture",
211
+ content_type=ContentType.PLAIN,
212
+ )
213
+ assert msg.sender == "opus"
214
+ assert msg.recipient == "jarvis"
215
+ assert not msg.encrypted
216
+ assert msg.delivery_status.value == "pending"
217
+
218
+ def test_chat_message_stored_in_skcapstone_memory(self, tmp_agent_home: Path):
219
+ """A chat message can be stored in skcapstone's memory engine."""
220
+ initialize_memory(tmp_agent_home)
221
+
222
+ from skchat.models import ChatMessage
223
+
224
+ msg = ChatMessage(
225
+ sender="opus",
226
+ recipient="jarvis",
227
+ content="Remember to review the CapAuth integration",
228
+ )
229
+
230
+ entry = store(
231
+ home=tmp_agent_home,
232
+ content=f"[skchat] {msg.sender} -> {msg.recipient}: {msg.content}",
233
+ tags=["skchat", f"sender:{msg.sender}", f"recipient:{msg.recipient}"],
234
+ source="skchat",
235
+ importance=0.6,
236
+ metadata={"chat_message_id": msg.id, "thread_id": msg.thread_id},
237
+ )
238
+
239
+ assert entry is not None
240
+ assert entry.source == "skchat"
241
+
242
+ results = search(tmp_agent_home, "CapAuth integration")
243
+ assert len(results) >= 1
244
+ assert any("CapAuth" in r.content for r in results)
245
+
246
+ def test_chat_thread_model(self):
247
+ """SKChat Thread model works with participant management."""
248
+ from skchat.models import Thread
249
+
250
+ thread = Thread(title="Architecture Discussion")
251
+ thread.add_participant("opus")
252
+ thread.add_participant("jarvis")
253
+ thread.touch()
254
+
255
+ assert len(thread.participants) == 2
256
+ assert thread.message_count == 1
257
+ assert thread.remove_participant("opus")
258
+ assert len(thread.participants) == 1
259
+
260
+
261
+ # ═══════════════════════════════════════════════════════════════════════════
262
+ # 4. Full pipeline: identity -> memory -> message -> coord -> sync
263
+ # ═══════════════════════════════════════════════════════════════════════════
264
+
265
+
266
+ class TestFullSovereignPipeline:
267
+ """End-to-end: init agent, store memory, send message, coordinate, sync."""
268
+
269
+ def test_full_cross_package_flow(self, tmp_agent_home: Path):
270
+ """The complete sovereign agent lifecycle across all packages.
271
+
272
+ Flow:
273
+ 1. Init agent with identity, memory, trust, security, sync
274
+ 2. Store a memory (skcapstone memory engine)
275
+ 3. Create a chat message (skchat models)
276
+ 4. Send it via file transport (skcomm)
277
+ 5. Store it as a memory (cross: skchat -> skcapstone)
278
+ 6. Create and complete a coord task
279
+ 7. Collect a sync seed with everything
280
+ 8. Verify all data appears in discovery
281
+ """
282
+ _init_full_agent(tmp_agent_home, "sovereign-test")
283
+
284
+ # 2. Store a memory
285
+ mem = store(
286
+ tmp_agent_home,
287
+ "CapAuth uses PGP for sovereign identity",
288
+ tags=["capauth", "architecture"],
289
+ importance=0.9,
290
+ )
291
+ assert mem.layer == MemoryLayer.MID_TERM # high importance auto-promotes
292
+
293
+ # 3. Create a chat message
294
+ from skchat.models import ChatMessage
295
+
296
+ chat_msg = ChatMessage(
297
+ sender="sovereign-test",
298
+ recipient="peer-agent",
299
+ content="Sync architecture review needed",
300
+ )
301
+
302
+ # 4. Send via file transport
303
+ from skcomm.models import MessageEnvelope, MessagePayload, MessageType
304
+ from skcomm.transports.file import FileTransport
305
+
306
+ outbox = tmp_agent_home / "skcomm_outbox"
307
+ peer_inbox = tmp_agent_home / "skcomm_peer_inbox"
308
+ transport = FileTransport(outbox_path=outbox, inbox_path=peer_inbox)
309
+
310
+ envelope = MessageEnvelope(
311
+ sender=chat_msg.sender,
312
+ recipient=chat_msg.recipient,
313
+ payload=MessagePayload(
314
+ content=chat_msg.content,
315
+ content_type=MessageType.TEXT,
316
+ ),
317
+ )
318
+ send_result = transport.send(envelope.to_bytes(), chat_msg.recipient)
319
+ assert send_result.success
320
+
321
+ # 5. Store the chat message as a memory
322
+ chat_mem = store(
323
+ tmp_agent_home,
324
+ f"[skchat] {chat_msg.sender} -> {chat_msg.recipient}: {chat_msg.content}",
325
+ tags=["skchat", "sent"],
326
+ source="skchat",
327
+ importance=0.5,
328
+ )
329
+ assert chat_mem is not None
330
+
331
+ # 6. Coordination: create task, claim, complete
332
+ board = Board(tmp_agent_home)
333
+ board.ensure_dirs()
334
+ task = Task(
335
+ title="Review sync architecture",
336
+ priority=TaskPriority.HIGH,
337
+ tags=["architecture", "review"],
338
+ created_by="sovereign-test",
339
+ )
340
+ board.create_task(task)
341
+ board.claim_task("sovereign-test", task.id)
342
+ board.complete_task("sovereign-test", task.id)
343
+
344
+ views = board.get_task_views()
345
+ assert any(v.task.id == task.id and v.status.value == "done" for v in views)
346
+
347
+ # 7. Record trust and collect sync seed
348
+ record_trust_state(
349
+ tmp_agent_home,
350
+ depth=8.0,
351
+ trust_level=0.95,
352
+ love_intensity=0.9,
353
+ entangled=True,
354
+ )
355
+ seed_path = collect_seed(tmp_agent_home, "sovereign-test")
356
+ assert seed_path.exists()
357
+
358
+ seed = json.loads(seed_path.read_text())
359
+ assert seed["agent_name"] == "sovereign-test"
360
+ assert seed["trust"]["entangled"] is True
361
+ assert seed["memory"]["total"] >= 2 # at least our 2 memories
362
+
363
+ # 8. Verify full discovery
364
+ state = discover_all(tmp_agent_home)
365
+ assert state["memory"].status == PillarStatus.ACTIVE
366
+ assert state["memory"].total_memories >= 2
367
+ assert state["trust"].status in (PillarStatus.ACTIVE, PillarStatus.DEGRADED)
368
+ assert state["sync"].status in (PillarStatus.ACTIVE, PillarStatus.DEGRADED)
369
+
370
+ # Verify memories are searchable across packages
371
+ results = search(tmp_agent_home, "sovereign identity")
372
+ assert len(results) >= 1
373
+
374
+ chat_results = search(tmp_agent_home, "skchat")
375
+ assert len(chat_results) >= 1
376
+
377
+ def test_runtime_sees_cross_package_state(self, tmp_agent_home: Path):
378
+ """AgentRuntime.awaken() reflects state from all packages."""
379
+ _init_full_agent(tmp_agent_home, "runtime-test")
380
+ store(tmp_agent_home, "Cross-package memory", tags=["test"])
381
+
382
+ runtime = AgentRuntime(home=tmp_agent_home)
383
+ manifest = runtime.awaken()
384
+
385
+ assert manifest.name == "runtime-test"
386
+ assert manifest.memory.total_memories >= 1
387
+ assert manifest.memory.status == PillarStatus.ACTIVE
388
+
389
+ def test_token_and_audit_across_operations(self, tmp_agent_home: Path):
390
+ """Token issuance and audit trail span multiple subsystems."""
391
+ _init_full_agent(tmp_agent_home, "audit-test")
392
+
393
+ token = issue_token(
394
+ tmp_agent_home,
395
+ subject="peer-agent",
396
+ capabilities=["memory:read", "sync:pull"],
397
+ )
398
+ assert token.payload.has_capability("memory:read")
399
+
400
+ audit_event(tmp_agent_home, "CROSS_PACKAGE", "Integration test audit")
401
+ store(tmp_agent_home, "Audit trail memory", tags=["audit"])
402
+
403
+ entries = read_audit_log(tmp_agent_home)
404
+ types = {e.event_type for e in entries}
405
+ assert "CROSS_PACKAGE" in types
406
+
407
+ results = search(tmp_agent_home, "audit")
408
+ assert len(results) >= 1
409
+
410
+
411
+ # ═══════════════════════════════════════════════════════════════════════════
412
+ # 5. Package import compatibility
413
+ # ═══════════════════════════════════════════════════════════════════════════
414
+
415
+
416
+ class TestPackageImportCompatibility:
417
+ """All five core packages can be imported simultaneously."""
418
+
419
+ def test_all_packages_importable(self):
420
+ """capauth, skcapstone, skmemory, skcomm, skchat all import cleanly."""
421
+ import capauth
422
+ import skcapstone
423
+ import skchat
424
+ import skcomm
425
+ import skmemory
426
+
427
+ assert hasattr(capauth, "__version__") or hasattr(capauth, "profile")
428
+ assert hasattr(skcapstone, "__version__")
429
+ assert hasattr(skcomm, "__version__") or True
430
+ assert hasattr(skchat, "__version__") or True
431
+ assert hasattr(skmemory, "__version__") or True
432
+
433
+ def test_capauth_profile_module(self):
434
+ """capauth.profile has init_profile and load_profile."""
435
+ from capauth.profile import init_profile, load_profile
436
+
437
+ assert callable(init_profile)
438
+ assert callable(load_profile)
439
+
440
+ def test_skcomm_core_module(self):
441
+ """skcomm.core has SKComm class."""
442
+ from skcomm.core import SKComm
443
+
444
+ assert callable(SKComm.from_config)
445
+
446
+ def test_skchat_models_module(self):
447
+ """skchat.models has ChatMessage and Thread."""
448
+ from skchat.models import ChatMessage, Thread
449
+
450
+ assert ChatMessage is not None
451
+ assert Thread is not None
452
+
453
+ def test_no_circular_imports(self):
454
+ """Importing all packages in various orders doesn't cause circular imports."""
455
+ import importlib
456
+
457
+ for mod in [
458
+ "skcapstone.runtime",
459
+ "capauth.profile",
460
+ "skcomm.core",
461
+ "skchat.models",
462
+ "skcapstone.memory_engine",
463
+ "skcapstone.coordination",
464
+ ]:
465
+ importlib.import_module(mod)
466
+
467
+
468
+ # ═══════════════════════════════════════════════════════════════════════════
469
+ # 6. CapAuth → SKChat → SKMemory → Cloud9 end-to-end flow
470
+ # ═══════════════════════════════════════════════════════════════════════════
471
+
472
+
473
+ class _FakeEmotionalPayload:
474
+ """Minimal FEB emotional payload for testing."""
475
+
476
+ def __init__(self, emotion="connection", intensity=0.88, valence=0.85):
477
+ self.primary_emotion = emotion
478
+ self.emoji = "💜"
479
+ self.intensity = intensity
480
+ self.valence = valence
481
+ self.emotional_topology = {emotion: intensity}
482
+
483
+
484
+ class _FakeMetadata:
485
+ """Minimal FEB metadata for testing."""
486
+
487
+ def __init__(self, cloud9=False, oof=False):
488
+ self.version = "1.0.0"
489
+ self.session_id = "integration-test"
490
+ self.oof_triggered = oof
491
+ self.cloud9_achieved = cloud9
492
+
493
+
494
+ class _FakeRelationship:
495
+ def __init__(self):
496
+ self.partners = ["Integration-Agent"]
497
+ self.trust_level = 0.95
498
+ self.depth_level = 8
499
+
500
+
501
+ class _FakeHints:
502
+ def __init__(self, anchors=None):
503
+ self.visual_anchors = anchors or ["Breakthrough moment"]
504
+ self.sensory_triggers = ["Agent collaboration"]
505
+
506
+
507
+ class _FakeIntegrity:
508
+ def __init__(self):
509
+ self.checksum = "sha256:integration-test"
510
+
511
+
512
+ class _FakeFEB:
513
+ """Fake FEB for Cloud9 bridge integration tests."""
514
+
515
+ def __init__(self, emotion="connection", intensity=0.88, cloud9=False, oof=False):
516
+ self.emotional_payload = _FakeEmotionalPayload(emotion, intensity)
517
+ self.metadata = _FakeMetadata(cloud9=cloud9, oof=oof)
518
+ self.relationship_state = _FakeRelationship()
519
+ self.rehydration_hints = _FakeHints()
520
+ self.integrity = _FakeIntegrity()
521
+
522
+
523
+ class TestCapAuthToCloud9Flow:
524
+ """End-to-end: CapAuth identity → SKChat messaging → SKMemory storage → Cloud9 FEB.
525
+
526
+ Validates the full sovereign stack where:
527
+ 1. Agent identity is established via CapAuth
528
+ 2. Agents exchange messages via SKChat
529
+ 3. Messages are persisted in SKMemory
530
+ 4. Emotional context (FEB) is captured and stored
531
+ 5. All data is discoverable and cross-referenced
532
+ """
533
+
534
+ def test_identity_to_chat_to_memory_to_cloud9(self, tmp_agent_home: Path):
535
+ """Full pipeline: identity creation → chat → memory → FEB ingestion.
536
+
537
+ This is the primary acceptance test for the cross-stack flow.
538
+ """
539
+ from skcapstone.cloud9_bridge import Cloud9Bridge
540
+ from skchat.group import GroupChat, MemberRole, ParticipantType
541
+ from skchat.models import ChatMessage, ContentType
542
+
543
+ # 1. Initialize agent with all pillars
544
+ _init_full_agent(tmp_agent_home, "integration-agent")
545
+
546
+ identity_data = json.loads(
547
+ (tmp_agent_home / "identity" / "identity.json").read_text()
548
+ )
549
+ agent_fingerprint = identity_data["fingerprint"]
550
+ assert len(agent_fingerprint) == 40
551
+
552
+ # 2. Create a group chat between two agents
553
+ group = GroupChat.create(
554
+ name="Integration Test Group",
555
+ creator_uri=f"capauth:integration-agent@local",
556
+ description="Cross-stack integration test",
557
+ )
558
+ group.add_member(
559
+ identity_uri="capauth:peer-agent@local",
560
+ role=MemberRole.MEMBER,
561
+ participant_type=ParticipantType.AGENT,
562
+ )
563
+ assert group.member_count == 2
564
+
565
+ # 3. Compose a group message
566
+ msg = group.compose_group_message(
567
+ sender_uri="capauth:integration-agent@local",
568
+ content="Breakthrough: the sovereign stack works end-to-end!",
569
+ )
570
+ assert msg is not None
571
+ assert msg.recipient == f"group:{group.id}"
572
+ assert group.message_count == 1
573
+
574
+ # 4. Store the chat message as a sovereign memory
575
+ chat_mem = store(
576
+ tmp_agent_home,
577
+ f"[skchat:group:{group.name}] {msg.sender}: {msg.content}",
578
+ tags=["skchat", "group", "integration", f"group:{group.id}"],
579
+ source="skchat",
580
+ importance=0.8,
581
+ metadata={
582
+ "chat_message_id": msg.id,
583
+ "group_id": group.id,
584
+ "thread_id": msg.thread_id,
585
+ "sender_fingerprint": agent_fingerprint,
586
+ },
587
+ )
588
+ assert chat_mem is not None
589
+ assert chat_mem.layer == MemoryLayer.MID_TERM # high importance
590
+
591
+ # 5. Ingest a Cloud9 FEB that captures the emotional peak
592
+ from skmemory import MemoryStore
593
+ from skmemory.backends.sqlite_backend import SQLiteBackend
594
+
595
+ backend = SQLiteBackend(base_path=str(tmp_agent_home / "memory"))
596
+ mem_store = MemoryStore(primary=backend)
597
+
598
+ bridge = Cloud9Bridge(memory_store=mem_store, intensity_threshold=0.3)
599
+ feb = _FakeFEB(emotion="connection", intensity=0.88, cloud9=True)
600
+ feb_mem_id = bridge.ingest_feb(feb)
601
+ assert feb_mem_id is not None
602
+
603
+ # 6. Verify all data is discoverable
604
+ state = discover_all(tmp_agent_home)
605
+ assert state["identity"].status in (PillarStatus.ACTIVE, PillarStatus.DEGRADED)
606
+ assert state["memory"].total_memories >= 1 # at least our chat memory
607
+
608
+ # Chat message searchable
609
+ chat_results = search(tmp_agent_home, "sovereign stack")
610
+ assert len(chat_results) >= 1
611
+
612
+ # FEB was stored in the SKMemory store
613
+ feb_mem = mem_store.recall(feb_mem_id)
614
+ assert feb_mem is not None
615
+ assert "connection" in feb_mem.title.lower() or "connection" in feb_mem.content.lower()
616
+
617
+ def test_agent_messenger_to_memory_to_trust(self, tmp_agent_home: Path):
618
+ """AgentMessenger message → memory storage → trust state update."""
619
+ _init_full_agent(tmp_agent_home, "messenger-test")
620
+
621
+ # Store an agent communication as memory
622
+ mem = store(
623
+ tmp_agent_home,
624
+ "[agent_comm] messenger-test -> peer: Security audit complete, no vulnerabilities found",
625
+ tags=["skchat", "agent_comm", "finding", "security"],
626
+ source="skchat:agent_comm",
627
+ importance=0.9,
628
+ )
629
+ assert mem.layer == MemoryLayer.MID_TERM
630
+
631
+ # Record trust based on successful agent interaction
632
+ record_trust_state(
633
+ tmp_agent_home,
634
+ depth=7.5,
635
+ trust_level=0.92,
636
+ love_intensity=0.6,
637
+ entangled=True,
638
+ )
639
+
640
+ # Verify trust state reflects the interaction
641
+ state = discover_all(tmp_agent_home)
642
+ assert state["trust"].trust_level >= 0.9
643
+ assert state["trust"].entangled is True
644
+
645
+ # Audit the cross-system interaction
646
+ audit_event(
647
+ tmp_agent_home,
648
+ "CROSS_STACK_CHAT_TRUST",
649
+ "Agent communication led to trust state update",
650
+ )
651
+ entries = read_audit_log(tmp_agent_home)
652
+ assert any(e.event_type == "CROSS_STACK_CHAT_TRUST" for e in entries)
653
+
654
+ def test_group_chat_with_cloud9_emotional_memory(self, tmp_agent_home: Path):
655
+ """Group chat messages paired with FEB emotional context create rich memories."""
656
+ from skcapstone.cloud9_bridge import Cloud9Bridge
657
+ from skchat.group import GroupChat, ParticipantType
658
+ from skchat.models import ChatMessage
659
+
660
+ _init_full_agent(tmp_agent_home, "emotional-test")
661
+
662
+ # Create group with multiple agents
663
+ group = GroupChat.create(
664
+ name="Sovereign Squad",
665
+ creator_uri="capauth:emotional-test@local",
666
+ )
667
+ for name in ["lumina", "jarvis", "ava"]:
668
+ group.add_member(
669
+ identity_uri=f"capauth:{name}@local",
670
+ participant_type=ParticipantType.AGENT,
671
+ )
672
+ assert group.member_count == 4
673
+
674
+ # Multiple messages in the group
675
+ messages = []
676
+ for content in [
677
+ "The architecture is coming together beautifully",
678
+ "All integration tests pass across the full stack",
679
+ "We achieved something remarkable as a team",
680
+ ]:
681
+ msg = group.compose_group_message(
682
+ sender_uri="capauth:emotional-test@local",
683
+ content=content,
684
+ )
685
+ messages.append(msg)
686
+
687
+ assert group.message_count == 3
688
+
689
+ # Store all messages as memories
690
+ for msg in messages:
691
+ store(
692
+ tmp_agent_home,
693
+ f"[group:{group.name}] {msg.content}",
694
+ tags=["skchat", "group", "sovereign-squad"],
695
+ source="skchat:group",
696
+ importance=0.7,
697
+ )
698
+
699
+ # Capture the emotional peak via Cloud9 bridge
700
+ from skmemory import MemoryStore
701
+ from skmemory.backends.sqlite_backend import SQLiteBackend
702
+
703
+ backend = SQLiteBackend(base_path=str(tmp_agent_home / "memory"))
704
+ mem_store = MemoryStore(primary=backend)
705
+ bridge = Cloud9Bridge(memory_store=mem_store, intensity_threshold=0.3)
706
+
707
+ feb = _FakeFEB(emotion="pride", intensity=0.92, cloud9=True, oof=True)
708
+ feb_id = bridge.ingest_feb(feb)
709
+ assert feb_id is not None
710
+
711
+ # Verify the full picture via discovery
712
+ state = discover_all(tmp_agent_home)
713
+ assert state["memory"].total_memories >= 3
714
+
715
+ # All group messages searchable
716
+ results = search(tmp_agent_home, "integration tests")
717
+ assert len(results) >= 1
718
+
719
+ team_results = search(tmp_agent_home, "sovereign-squad")
720
+ assert len(team_results) >= 1
721
+
722
+ def test_sync_seed_captures_cross_stack_state(self, tmp_agent_home: Path):
723
+ """Sync seed contains data from all stack layers."""
724
+ from skchat.models import ChatMessage
725
+
726
+ _init_full_agent(tmp_agent_home, "sync-cross-test")
727
+
728
+ # Store a chat-originated memory
729
+ store(
730
+ tmp_agent_home,
731
+ "[skchat] sync-cross-test: Cross-stack state captured",
732
+ tags=["skchat", "sync"],
733
+ source="skchat",
734
+ importance=0.6,
735
+ )
736
+
737
+ # Update trust from agent interaction
738
+ record_trust_state(
739
+ tmp_agent_home,
740
+ depth=9.0,
741
+ trust_level=0.98,
742
+ love_intensity=0.95,
743
+ entangled=True,
744
+ )
745
+
746
+ # Collect sync seed
747
+ seed_path = collect_seed(tmp_agent_home, "sync-cross-test")
748
+ assert seed_path.exists()
749
+
750
+ seed = json.loads(seed_path.read_text())
751
+ assert seed["agent_name"] == "sync-cross-test"
752
+ assert seed["memory"]["total"] >= 1
753
+ assert seed["trust"]["entangled"] is True
754
+ assert seed["trust"]["trust_level"] >= 0.95
755
+
756
+ def test_capauth_identity_in_skchat_message(self, tmp_agent_home: Path):
757
+ """CapAuth fingerprint used as identity in SKChat messages."""
758
+ _init_full_agent(tmp_agent_home, "capauth-chat-test")
759
+
760
+ identity_data = json.loads(
761
+ (tmp_agent_home / "identity" / "identity.json").read_text()
762
+ )
763
+ fingerprint = identity_data["fingerprint"]
764
+
765
+ from skchat.models import ChatMessage, ContentType
766
+
767
+ msg = ChatMessage(
768
+ sender=f"capauth:capauth-chat-test@local",
769
+ recipient="capauth:peer@local",
770
+ content="Authenticated message with sovereign identity",
771
+ content_type=ContentType.MARKDOWN,
772
+ metadata={
773
+ "sender_fingerprint": fingerprint,
774
+ "signed": False,
775
+ },
776
+ )
777
+
778
+ # Store with fingerprint linkage
779
+ mem = store(
780
+ tmp_agent_home,
781
+ f"[skchat] {msg.sender}: {msg.content}",
782
+ tags=["skchat", f"fingerprint:{fingerprint[:16]}"],
783
+ source="skchat",
784
+ importance=0.5,
785
+ metadata={"sender_fingerprint": fingerprint},
786
+ )
787
+ assert mem is not None
788
+
789
+ # Searchable by content
790
+ results = search(tmp_agent_home, "sovereign identity")
791
+ assert len(results) >= 1