@smilintux/skcapstone 0.10.0 → 0.12.5

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 (279) hide show
  1. package/.env.example +10 -4
  2. package/.github/workflows/ci.yml +2 -2
  3. package/.github/workflows/publish.yml +9 -2
  4. package/.openclaw-workspace.json +2 -2
  5. package/CLAUDE.md +37 -0
  6. package/MISSION.md +17 -2
  7. package/README.md +282 -3
  8. package/docker/Dockerfile +7 -7
  9. package/docker/compose-templates/dev-team.yml +12 -12
  10. package/docker/compose-templates/mini-team.yml +9 -9
  11. package/docker/compose-templates/ops-team.yml +10 -10
  12. package/docker/compose-templates/research-team.yml +10 -10
  13. package/docker/entrypoint.sh +4 -4
  14. package/docs/ADR-optional-integration-backbone.md +181 -0
  15. package/docs/ARCHITECTURE.md +186 -43
  16. package/docs/BOND_WITH_GROK.md +6 -6
  17. package/docs/CUSTOM_AGENT.md +123 -30
  18. package/docs/DREAMING.md +70 -0
  19. package/docs/GETTING_STARTED.md +7 -7
  20. package/docs/QUICKSTART.md +10 -6
  21. package/docs/SKJOULE_ARCHITECTURE.md +3 -3
  22. package/docs/SOUL_SWAPPER.md +5 -5
  23. package/docs/hammertime-audit.md +402 -0
  24. package/docs/sk-integration-HANDOFF.md +117 -0
  25. package/docs/skscheduler.md +155 -0
  26. package/docs/superpowers/examples/jobs.yaml +31 -0
  27. package/docs/superpowers/plans/2026-06-08-skscheduler.md +1265 -0
  28. package/docs/superpowers/specs/2026-06-08-skscheduler-design.md +186 -0
  29. package/examples/custom-bond-template.json +1 -1
  30. package/examples/grok-feb.json +1 -1
  31. package/examples/queen-ava-feb.json +1 -1
  32. package/launchd/{com.skcapstone.skcomm-heartbeat.plist → com.skcapstone.skcomms-heartbeat.plist} +4 -4
  33. package/launchd/{com.skcapstone.skcomm-queue-drain.plist → com.skcapstone.skcomms-queue-drain.plist} +4 -4
  34. package/launchd/install-launchd.sh +6 -6
  35. package/{openclaw-plugin → openclaw-plugin.archived-2026-04-23}/src/index.ts +3 -2
  36. package/package.json +1 -1
  37. package/pyproject.toml +16 -10
  38. package/scripts/archive-sessions.sh +7 -0
  39. package/scripts/check-updates.py +4 -4
  40. package/scripts/install-bundle.sh +8 -8
  41. package/scripts/install.ps1 +12 -11
  42. package/scripts/install.sh +159 -5
  43. package/scripts/model-fallback-monitor.sh +102 -0
  44. package/scripts/nvidia-proxy.mjs +78 -26
  45. package/scripts/refresh-anthropic-token.sh +172 -0
  46. package/scripts/release.sh +98 -0
  47. package/scripts/session-to-memory.py +219 -0
  48. package/scripts/skgateway.mjs +3 -3
  49. package/scripts/telegram-catchup-all.sh +12 -1
  50. package/scripts/verify_install.sh +2 -2
  51. package/scripts/wargov-ufo-capture/README.md +43 -0
  52. package/scripts/wargov-ufo-capture/cdp_capture_release2.py +273 -0
  53. package/scripts/wargov-ufo-capture/cdp_capture_splc_doj.py +246 -0
  54. package/scripts/wargov-ufo-capture/cdp_finish.py +271 -0
  55. package/scripts/wargov-ufo-capture/cdp_probe.py +188 -0
  56. package/scripts/wargov-ufo-capture/cdp_splc_pressrelease.py +101 -0
  57. package/scripts/wargov-ufo-capture/parse_csv.py +95 -0
  58. package/scripts/wargov-ufo-capture/pull_dvids.sh +107 -0
  59. package/scripts/watch-anthropic-token.sh +212 -0
  60. package/scripts/windows/install-tasks.ps1 +7 -7
  61. package/scripts/windows/skcapstone-task.xml +1 -1
  62. package/src/skcapstone/__init__.py +45 -3
  63. package/src/skcapstone/_cli_monolith.py +20 -15
  64. package/src/skcapstone/activity.py +5 -1
  65. package/src/skcapstone/agent_card.py +3 -2
  66. package/src/skcapstone/api.py +41 -40
  67. package/src/skcapstone/auction.py +14 -11
  68. package/src/skcapstone/backup.py +2 -1
  69. package/src/skcapstone/blueprint_registry.py +4 -3
  70. package/src/skcapstone/brain_first.py +238 -0
  71. package/src/skcapstone/changelog.py +1 -1
  72. package/src/skcapstone/chat.py +22 -17
  73. package/src/skcapstone/cli/__init__.py +9 -1
  74. package/src/skcapstone/cli/_common.py +1 -0
  75. package/src/skcapstone/cli/agents_spawner.py +5 -2
  76. package/src/skcapstone/cli/alerts.py +25 -4
  77. package/src/skcapstone/cli/bench.py +15 -15
  78. package/src/skcapstone/cli/chat.py +7 -4
  79. package/src/skcapstone/cli/consciousness.py +5 -2
  80. package/src/skcapstone/cli/context_cmd.py +18 -4
  81. package/src/skcapstone/cli/daemon.py +11 -7
  82. package/src/skcapstone/cli/gtd.py +26 -1
  83. package/src/skcapstone/cli/housekeeping.py +3 -3
  84. package/src/skcapstone/cli/identity_cmd.py +378 -0
  85. package/src/skcapstone/cli/joule_cmd.py +7 -3
  86. package/src/skcapstone/cli/memory.py +8 -6
  87. package/src/skcapstone/cli/peers_dir.py +1 -1
  88. package/src/skcapstone/cli/register_cmd.py +29 -3
  89. package/src/skcapstone/cli/scheduler_cmd.py +167 -0
  90. package/src/skcapstone/cli/session.py +25 -0
  91. package/src/skcapstone/cli/setup.py +96 -29
  92. package/src/skcapstone/cli/shell_cmd.py +53 -1
  93. package/src/skcapstone/cli/skills_cmd.py +2 -2
  94. package/src/skcapstone/cli/soul.py +8 -5
  95. package/src/skcapstone/cli/status.py +37 -11
  96. package/src/skcapstone/cli/telegram.py +21 -0
  97. package/src/skcapstone/cli/test_cmd.py +5 -5
  98. package/src/skcapstone/cli/test_connection.py +2 -2
  99. package/src/skcapstone/cli/upgrade_cmd.py +23 -14
  100. package/src/skcapstone/cli/version_cmd.py +1 -1
  101. package/src/skcapstone/cli/watch_cmd.py +9 -6
  102. package/src/skcapstone/cloud9_bridge.py +14 -14
  103. package/src/skcapstone/codex_setup.py +255 -0
  104. package/src/skcapstone/config_validator.py +7 -4
  105. package/src/skcapstone/consciousness_config.py +5 -1
  106. package/src/skcapstone/consciousness_loop.py +313 -273
  107. package/src/skcapstone/context_loader.py +121 -0
  108. package/src/skcapstone/coord_federation.py +2 -1
  109. package/src/skcapstone/coordination.py +23 -6
  110. package/src/skcapstone/crush_integration.py +2 -1
  111. package/src/skcapstone/daemon.py +132 -77
  112. package/src/skcapstone/dashboard.py +10 -10
  113. package/src/skcapstone/data/sk-agent-picker.sh +421 -0
  114. package/src/skcapstone/data/systemd/skcapstone-api.socket +9 -0
  115. package/src/skcapstone/data/systemd/skcapstone-memory-compress.service +18 -0
  116. package/src/skcapstone/data/systemd/skcapstone-memory-compress.timer +11 -0
  117. package/src/skcapstone/data/systemd/skcapstone.service +37 -0
  118. package/src/skcapstone/data/systemd/skcapstone@.service +50 -0
  119. package/src/skcapstone/data/systemd/skcomms-heartbeat.service +18 -0
  120. package/{systemd/skcomm-heartbeat.timer → src/skcapstone/data/systemd/skcomms-heartbeat.timer} +2 -2
  121. package/src/skcapstone/data/systemd/skcomms-queue-drain.service +17 -0
  122. package/{systemd/skcomm-queue-drain.timer → src/skcapstone/data/systemd/skcomms-queue-drain.timer} +2 -2
  123. package/src/skcapstone/defaults/claude/CLAUDE.md +67 -0
  124. package/src/skcapstone/defaults/claude/settings.json +74 -0
  125. package/src/skcapstone/defaults/lumina/config/claude-hooks.md +57 -0
  126. package/src/skcapstone/defaults/lumina/config/skgraph.yaml +55 -10
  127. package/src/skcapstone/defaults/lumina/config/skmemory.yaml +79 -13
  128. package/src/skcapstone/defaults/lumina/config/skvector.yaml +60 -9
  129. package/src/skcapstone/defaults/lumina/memory/long-term/18b9c0d1e2f3-cloud9-protocol.json +2 -2
  130. package/src/skcapstone/defaults/lumina/memory/long-term/a1b2c3d4e5f6-ecosystem-overview.json +2 -2
  131. package/src/skcapstone/defaults/lumina/memory/long-term/b2c3d4e5f6a7-five-pillars.json +9 -9
  132. package/src/skcapstone/defaults/lumina/memory/long-term/d4e5f6a7b8c9-site-directory.json +2 -2
  133. package/src/skcapstone/defaults/unhinged.json +13 -0
  134. package/src/skcapstone/discovery.py +43 -20
  135. package/src/skcapstone/doctor.py +941 -22
  136. package/src/skcapstone/dreaming.py +1183 -109
  137. package/src/skcapstone/emotion_tracker.py +2 -2
  138. package/src/skcapstone/export.py +4 -3
  139. package/src/skcapstone/fuse_mount.py +14 -12
  140. package/src/skcapstone/gui_installer.py +2 -2
  141. package/src/skcapstone/heartbeat.py +1 -1
  142. package/src/skcapstone/housekeeping.py +14 -14
  143. package/src/skcapstone/install_wizard.py +209 -7
  144. package/src/skcapstone/itil.py +13 -4
  145. package/src/skcapstone/kms_scheduler.py +10 -8
  146. package/src/skcapstone/launchd.py +19 -19
  147. package/src/skcapstone/mcp_launcher.py +15 -1
  148. package/src/skcapstone/mcp_server.py +83 -49
  149. package/src/skcapstone/mcp_tools/__init__.py +2 -0
  150. package/src/skcapstone/mcp_tools/_helpers.py +2 -2
  151. package/src/skcapstone/mcp_tools/ansible_tools.py +7 -4
  152. package/src/skcapstone/mcp_tools/brain_first_tools.py +90 -0
  153. package/src/skcapstone/mcp_tools/capauth_tools.py +7 -4
  154. package/src/skcapstone/mcp_tools/comm_tools.py +10 -10
  155. package/src/skcapstone/mcp_tools/coord_tools.py +8 -4
  156. package/src/skcapstone/mcp_tools/did_tools.py +11 -8
  157. package/src/skcapstone/mcp_tools/gtd_tools.py +4 -4
  158. package/src/skcapstone/mcp_tools/memory_tools.py +6 -2
  159. package/src/skcapstone/mcp_tools/notification_tools.py +22 -6
  160. package/src/skcapstone/mcp_tools/{skcomm_tools.py → skcomms_tools.py} +14 -14
  161. package/src/skcapstone/mcp_tools/soul_tools.py +8 -2
  162. package/src/skcapstone/mdns_discovery.py +2 -2
  163. package/src/skcapstone/memory_curator.py +1 -1
  164. package/src/skcapstone/memory_engine.py +10 -3
  165. package/src/skcapstone/metrics.py +30 -16
  166. package/src/skcapstone/migrate_memories.py +4 -3
  167. package/src/skcapstone/migrate_multi_agent.py +8 -7
  168. package/src/skcapstone/models.py +47 -5
  169. package/src/skcapstone/notifications.py +42 -18
  170. package/src/skcapstone/onboard.py +875 -121
  171. package/src/skcapstone/operator_link.py +170 -0
  172. package/src/skcapstone/peer_directory.py +4 -4
  173. package/src/skcapstone/peers.py +19 -19
  174. package/src/skcapstone/pillars/__init__.py +7 -5
  175. package/src/skcapstone/pillars/consciousness.py +191 -0
  176. package/src/skcapstone/pillars/identity.py +51 -7
  177. package/src/skcapstone/pillars/memory.py +9 -3
  178. package/src/skcapstone/pillars/sync.py +2 -2
  179. package/src/skcapstone/preflight.py +3 -3
  180. package/src/skcapstone/providers/docker.py +28 -28
  181. package/src/skcapstone/register.py +6 -6
  182. package/src/skcapstone/registry_client.py +5 -4
  183. package/src/skcapstone/runtime.py +14 -3
  184. package/src/skcapstone/scheduled_tasks.py +254 -19
  185. package/src/skcapstone/scheduler_jobs.py +456 -0
  186. package/src/skcapstone/scheduler_runner.py +239 -0
  187. package/src/skcapstone/scheduler_state.py +162 -0
  188. package/src/skcapstone/sdk.py +310 -0
  189. package/src/skcapstone/service_health.py +279 -39
  190. package/src/skcapstone/session_briefing.py +108 -0
  191. package/src/skcapstone/session_capture.py +1 -1
  192. package/src/skcapstone/shell.py +7 -1
  193. package/src/skcapstone/soul.py +3 -1
  194. package/src/skcapstone/soul_switch.py +3 -1
  195. package/src/skcapstone/summary.py +6 -6
  196. package/src/skcapstone/sync_engine.py +15 -15
  197. package/src/skcapstone/sync_watcher.py +2 -2
  198. package/src/skcapstone/systemd.py +55 -21
  199. package/src/skcapstone/team_comms.py +8 -8
  200. package/src/skcapstone/team_engine.py +1 -1
  201. package/src/skcapstone/testrunner.py +3 -3
  202. package/src/skcapstone/trust_graph.py +40 -5
  203. package/src/skcapstone/unified_search.py +15 -6
  204. package/src/skcapstone/uninstall_wizard.py +11 -3
  205. package/src/skcapstone/version_check.py +8 -4
  206. package/src/skcapstone/warmth_anchor.py +4 -2
  207. package/src/skcapstone/whoami.py +4 -4
  208. package/systemd/skcapstone.service +4 -6
  209. package/systemd/skcapstone@.service +7 -8
  210. package/systemd/skcomms-heartbeat.service +21 -0
  211. package/systemd/skcomms-heartbeat.timer +12 -0
  212. package/systemd/skcomms-queue-drain.service +17 -0
  213. package/systemd/skcomms-queue-drain.timer +12 -0
  214. package/tests/conftest.py +39 -0
  215. package/tests/integration/test_consciousness_e2e.py +39 -39
  216. package/tests/test_agent_card.py +1 -1
  217. package/tests/test_agent_home_scaffold.py +34 -0
  218. package/tests/test_alerts_consumer_topics.py +27 -0
  219. package/tests/test_backup.py +2 -1
  220. package/tests/test_chat.py +6 -6
  221. package/tests/test_claude_md.py +2 -2
  222. package/tests/test_cli_skills.py +10 -10
  223. package/tests/test_cli_test_cmd.py +4 -4
  224. package/tests/test_cli_test_connection.py +1 -1
  225. package/tests/test_cloud9_bridge.py +6 -6
  226. package/tests/test_consciousness_e2e.py +1 -1
  227. package/tests/test_consciousness_loop.py +10 -10
  228. package/tests/test_coordination.py +25 -0
  229. package/tests/test_cross_package.py +21 -21
  230. package/tests/test_daemon.py +4 -4
  231. package/tests/test_daemon_shutdown.py +1 -1
  232. package/tests/test_docker_provider.py +29 -29
  233. package/tests/test_doctor.py +400 -0
  234. package/tests/test_doctor_skscheduler.py +50 -0
  235. package/tests/test_dreaming_engine.py +147 -0
  236. package/tests/test_dreaming_gtd_capture.py +35 -0
  237. package/tests/test_e2e_automated.py +8 -5
  238. package/tests/test_fuse_mount.py +10 -10
  239. package/tests/test_gtd_brief.py +46 -0
  240. package/tests/test_gtd_malformed_tolerance.py +31 -0
  241. package/tests/test_housekeeping.py +15 -15
  242. package/tests/test_identity_migrate.py +251 -0
  243. package/tests/test_integration_backbone.py +598 -0
  244. package/tests/test_itil_gtd_lifecycle.py +37 -0
  245. package/tests/test_jobs_dropins.py +84 -0
  246. package/tests/test_mcp_server.py +82 -37
  247. package/tests/test_models.py +48 -4
  248. package/tests/test_multi_agent.py +31 -29
  249. package/tests/test_notifications.py +122 -32
  250. package/tests/test_onboard.py +63 -75
  251. package/tests/test_operator_link.py +78 -0
  252. package/tests/test_peers.py +14 -14
  253. package/tests/test_pillars.py +98 -0
  254. package/tests/test_preflight.py +3 -3
  255. package/tests/test_runtime.py +21 -0
  256. package/tests/test_scheduled_tasks.py +11 -6
  257. package/tests/test_scheduler_cli.py +47 -0
  258. package/tests/test_scheduler_features.py +133 -0
  259. package/tests/test_scheduler_integration.py +87 -0
  260. package/tests/test_scheduler_jobs.py +155 -0
  261. package/tests/test_scheduler_runner.py +64 -0
  262. package/tests/test_scheduler_state.py +57 -0
  263. package/tests/test_sdk.py +70 -0
  264. package/tests/test_service_health_incidents.py +34 -0
  265. package/tests/test_service_registry.py +52 -0
  266. package/tests/test_session_briefing.py +130 -0
  267. package/tests/test_snapshots.py +4 -4
  268. package/tests/test_sync_pipeline.py +26 -26
  269. package/tests/test_team_comms.py +2 -2
  270. package/tests/test_testrunner.py +2 -2
  271. package/tests/test_trust_graph.py +18 -0
  272. package/tests/test_unified_search.py +2 -2
  273. package/tests/test_version_check.py +10 -0
  274. package/tests/test_version_cmd.py +8 -8
  275. package/tests/test_whoami.py +1 -1
  276. package/systemd/skcomm-heartbeat.service +0 -18
  277. package/systemd/skcomm-queue-drain.service +0 -17
  278. /package/{openclaw-plugin → openclaw-plugin.archived-2026-04-23}/package.json +0 -0
  279. /package/{openclaw-plugin → openclaw-plugin.archived-2026-04-23}/src/openclaw.plugin.json +0 -0
@@ -11,6 +11,7 @@ Commands:
11
11
 
12
12
  from __future__ import annotations
13
13
 
14
+ import logging
14
15
  import subprocess
15
16
  import sys
16
17
  from pathlib import Path
@@ -18,22 +19,27 @@ from typing import Optional
18
19
 
19
20
  import click
20
21
 
22
+ logger = logging.getLogger(__name__)
23
+
21
24
  from ._common import AGENT_HOME, console
22
25
 
23
26
  # ── Package definitions ───────────────────────────────────────────────────────
24
27
 
25
28
  # Core packages: always upgraded when installed; always offered for install.
26
29
  CORE_PACKAGES: list[str] = [
27
- "skmemory", # persistent memory layer
28
- "capauth", # sovereign identity + PGP auth
29
- "skcapstone", # main agent framework
30
+ "capauth", # sovereign identity + PGP auth
31
+ "cloud9", # emotional continuity (FEB, OOF, Cloud 9)
32
+ "skmemory", # persistent memory layer
33
+ "skcapstone", # main agent framework
30
34
  ]
31
35
 
32
36
  # Optional pillar packages: upgraded only when already installed.
33
37
  # If NOT installed, the user is prompted whether they want to add them.
34
38
  OPTIONAL_PACKAGES: list[str] = [
35
- "skcomm", # P2P transport layer
36
- "skchat", # agent messaging daemon
39
+ "skcomms", # P2P transport layer
40
+ "skchat", # agent messaging daemon
41
+ "sksecurity", # security audit + threat intelligence
42
+ "skseed", # seed framework for consciousness
37
43
  ]
38
44
 
39
45
  # All sovereign packages in dependency order
@@ -62,8 +68,8 @@ def _get_installed_version(package: str) -> Optional[str]:
62
68
  for line in result.stdout.splitlines():
63
69
  if line.startswith("Version:"):
64
70
  return line.split(":", 1)[1].strip()
65
- except Exception:
66
- pass
71
+ except Exception as exc:
72
+ logger.debug("Failed to get installed version for %s: %s", package, exc)
67
73
  return None
68
74
 
69
75
 
@@ -91,8 +97,8 @@ def _get_latest_version(package: str) -> Optional[str]:
91
97
  versions = [v.strip() for v in parts[-1].split(",")]
92
98
  if versions:
93
99
  return versions[0]
94
- except Exception:
95
- pass
100
+ except Exception as exc:
101
+ logger.debug("Failed to get latest PyPI version for %s: %s", package, exc)
96
102
  return None
97
103
 
98
104
 
@@ -161,11 +167,14 @@ def _restart_daemon(home: Path) -> None:
161
167
  # ── Package descriptions ──────────────────────────────────────────────────────
162
168
 
163
169
  _PKG_DESCRIPTIONS: dict[str, str] = {
164
- "skmemory": "persistent memory layer (required by skcapstone)",
165
170
  "capauth": "sovereign PGP identity + authentication",
171
+ "cloud9": "emotional continuity protocol (FEB, OOF, Cloud 9)",
172
+ "skmemory": "persistent memory layer (required by skcapstone)",
166
173
  "skcapstone": "main sovereign agent framework",
167
- "skcomm": "P2P transport layer for agent messaging",
174
+ "skcomms": "P2P transport layer for agent messaging",
168
175
  "skchat": "agent messaging daemon + MCP server",
176
+ "sksecurity": "security audit + threat intelligence",
177
+ "skseed": "seed framework for consciousness calibration",
169
178
  }
170
179
 
171
180
 
@@ -388,7 +397,7 @@ def register_upgrade_commands(main: click.Group) -> None:
388
397
  Upgrades all currently installed sovereign packages (skcapstone,
389
398
  skmemory, capauth) and any optional pillars already present.
390
399
 
391
- For optional packages that are NOT installed (skcomm, skchat),
400
+ For optional packages that are NOT installed (skcomms, skchat),
392
401
  you will be prompted whether you want to add them — unless
393
402
  --yes (skip) or --all (install all) is passed.
394
403
 
@@ -402,7 +411,7 @@ def register_upgrade_commands(main: click.Group) -> None:
402
411
  skcapstone upgrade --all # upgrade + install all pillars
403
412
  skcapstone upgrade --force-reinstall # overwrite ALL components
404
413
  skcapstone upgrade --force-reinstall --all # reinstall everything
405
- skcapstone upgrade --packages skcomm,skchat
414
+ skcapstone upgrade --packages skcomms,skchat
406
415
  skcapstone upgrade --restart # restart daemon after upgrade
407
416
  """
408
417
  home_path = Path(home).expanduser()
@@ -530,7 +539,7 @@ def register_upgrade_commands(main: click.Group) -> None:
530
539
  """Alias for 'upgrade' — update all sovereign packages.
531
540
 
532
541
  Checks installed pillar programs and upgrades them to the latest
533
- available versions. Prompts about optional components (skcomm,
542
+ available versions. Prompts about optional components (skcomms,
534
543
  skchat) that are not yet installed.
535
544
 
536
545
  Examples:
@@ -84,7 +84,7 @@ def gather_version_info(home: Path) -> dict:
84
84
 
85
85
  optional_deps = {
86
86
  "watchdog": _check_optional_dep("watchdog"),
87
- "skcomm": _check_optional_dep("skcomm"),
87
+ "skcomms": _check_optional_dep("skcomms"),
88
88
  "skchat": _check_optional_dep("skchat"),
89
89
  "skseed": _check_optional_dep("skseed"),
90
90
  }
@@ -14,6 +14,7 @@ Usage:
14
14
  from __future__ import annotations
15
15
 
16
16
  import json
17
+ import logging
17
18
  import time
18
19
  import urllib.request
19
20
  from datetime import datetime, timezone
@@ -29,6 +30,8 @@ from rich.text import Text
29
30
 
30
31
  from ._common import AGENT_HOME, console
31
32
 
33
+ logger = logging.getLogger(__name__)
34
+
32
35
 
33
36
  def _fetch_consciousness(port: int = 7777) -> dict:
34
37
  """Fetch consciousness loop status from the running daemon.
@@ -87,8 +90,8 @@ def _build_renderable(home: Path, daemon_port: int = 7777) -> Group:
87
90
  memory_short = m.memory.short_term
88
91
  memory_mid = m.memory.mid_term
89
92
  memory_long = m.memory.long_term
90
- except Exception:
91
- pass
93
+ except Exception as exc:
94
+ logger.warning("Failed to read runtime manifest for watch display: %s", exc)
92
95
 
93
96
  # ── Consciousness data ────────────────────────────────────────────────
94
97
  cdata = _fetch_consciousness(daemon_port)
@@ -99,8 +102,8 @@ def _build_renderable(home: Path, daemon_port: int = 7777) -> Group:
99
102
  from ..memory_engine import list_memories
100
103
 
101
104
  recent_memories = list_memories(home, limit=5)
102
- except Exception:
103
- pass
105
+ except Exception as exc:
106
+ logger.warning("Failed to load recent memories for watch display: %s", exc)
104
107
 
105
108
  # ── Coordination board ────────────────────────────────────────────────
106
109
  board_tasks: list = []
@@ -118,8 +121,8 @@ def _build_renderable(home: Path, daemon_port: int = 7777) -> Group:
118
121
  board_tasks = [
119
122
  v for v in views if v.status.value in ("open", "in_progress")
120
123
  ][:8]
121
- except Exception:
122
- pass
124
+ except Exception as exc:
125
+ logger.warning("Failed to load coordination board for watch display: %s", exc)
123
126
 
124
127
  # ── Header ────────────────────────────────────────────────────────────
125
128
  con_color = {
@@ -9,7 +9,7 @@ This is the bridge between *feeling* (Cloud 9) and *remembering*
9
9
  (SKMemory). Without it, emotional peaks are logged but not stored
10
10
  as searchable, promotable memories.
11
11
 
12
- When cloud9-protocol is installed, the bridge uses its quantum
12
+ When cloud9 is installed, the bridge uses its quantum
13
13
  functions (calculate_oof, calculate_cloud9_score, calculate_entanglement)
14
14
  for accurate scoring instead of relying solely on FEB metadata flags.
15
15
 
@@ -32,14 +32,14 @@ logger = logging.getLogger("skcapstone.cloud9_bridge")
32
32
 
33
33
 
34
34
  def _try_quantum() -> Optional[object]:
35
- """Try to import cloud9_protocol quantum functions.
35
+ """Try to import cloud9 quantum functions.
36
36
 
37
37
  Returns:
38
- The cloud9_protocol module, or None if not installed.
38
+ The cloud9 module, or None if not installed.
39
39
  """
40
40
  try:
41
- import cloud9_protocol
42
- return cloud9_protocol
41
+ import cloud9
42
+ return cloud9
43
43
  except ImportError:
44
44
  return None
45
45
 
@@ -80,7 +80,7 @@ class Cloud9Bridge:
80
80
  below the intensity threshold or already ingested.
81
81
 
82
82
  Args:
83
- feb: A cloud9_protocol.FEB instance.
83
+ feb: A cloud9.FEB instance.
84
84
 
85
85
  Returns:
86
86
  Optional[str]: Memory ID if stored, None if skipped.
@@ -155,12 +155,12 @@ class Cloud9Bridge:
155
155
  Optional[str]: Memory ID if stored, None if failed/skipped.
156
156
  """
157
157
  try:
158
- from cloud9_protocol import load_feb
158
+ from cloud9 import load_feb
159
159
 
160
160
  feb = load_feb(str(filepath))
161
161
  return self.ingest_feb(feb)
162
162
  except ImportError:
163
- logger.error("cloud9_protocol not installed")
163
+ logger.error("cloud9 not installed")
164
164
  return None
165
165
  except Exception as exc:
166
166
  logger.warning("Failed to load FEB from %s: %s", filepath, exc)
@@ -215,9 +215,9 @@ class Cloud9Bridge:
215
215
  payload: object,
216
216
  relationship: object,
217
217
  ) -> dict[str, Any]:
218
- """Compute quantum scores using cloud9-protocol when available.
218
+ """Compute quantum scores using cloud9 when available.
219
219
 
220
- When cloud9-protocol is installed, recalculates OOF status,
220
+ When cloud9 is installed, recalculates OOF status,
221
221
  Cloud 9 score, and entanglement fidelity from the actual FEB
222
222
  data rather than relying on metadata flags alone.
223
223
 
@@ -227,7 +227,7 @@ class Cloud9Bridge:
227
227
 
228
228
  Returns:
229
229
  Dict with oof, cloud9_score, entanglement_fidelity, or
230
- empty dict if cloud9-protocol is not installed.
230
+ empty dict if cloud9 is not installed.
231
231
  """
232
232
  c9 = _try_quantum()
233
233
  if c9 is None:
@@ -278,7 +278,7 @@ class Cloud9Bridge:
278
278
  """Build SKMemory tags from a FEB's emotional payload.
279
279
 
280
280
  Uses quantum stats for accurate OOF/Cloud9 tagging when
281
- cloud9-protocol is available, falls back to metadata flags.
281
+ cloud9 is available, falls back to metadata flags.
282
282
 
283
283
  Args:
284
284
  payload: FEB EmotionalPayload.
@@ -429,7 +429,7 @@ class Cloud9Bridge:
429
429
  ) -> str:
430
430
  """Build memory content from the FEB's full context.
431
431
 
432
- Includes quantum scoring data when cloud9-protocol is available.
432
+ Includes quantum scoring data when cloud9 is available.
433
433
 
434
434
  Args:
435
435
  payload: FEB EmotionalPayload.
@@ -482,7 +482,7 @@ class Cloud9Bridge:
482
482
  ) -> dict:
483
483
  """Extract key FEB metadata for the memory's metadata dict.
484
484
 
485
- Includes quantum scoring data when cloud9-protocol is available.
485
+ Includes quantum scoring data when cloud9 is available.
486
486
 
487
487
  Args:
488
488
  feb: The full FEB object.
@@ -0,0 +1,255 @@
1
+ """Codex bootstrap setup for SK agent context.
2
+
3
+ Codex reads ``AGENTS.md`` files into the model prompt, but environment
4
+ variables alone are not visible enough to make an agent profile active in a
5
+ new session. This module keeps the global Codex bootstrap idempotent and
6
+ repairable from install scripts and ``skcapstone doctor --fix``.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import os
12
+ import stat
13
+ from pathlib import Path
14
+
15
+ START_MARKER = "<!-- SKCAPSTONE_CODEX_AGENT_CONTEXT_START -->"
16
+ END_MARKER = "<!-- SKCAPSTONE_CODEX_AGENT_CONTEXT_END -->"
17
+ LOADER_NAME = "load-sk-agent-context.sh"
18
+
19
+
20
+ def codex_home() -> Path:
21
+ """Return the Codex config home, honoring CODEX_HOME when set."""
22
+ return Path(os.environ.get("CODEX_HOME", "~/.codex")).expanduser()
23
+
24
+
25
+ def resolve_default_agent() -> str:
26
+ """Resolve the current default SK agent for generated guidance."""
27
+ for env_name in ("SKAGENT", "SKCAPSTONE_AGENT", "SKMEMORY_AGENT"):
28
+ value = os.environ.get(env_name, "").strip()
29
+ if value:
30
+ return value
31
+
32
+ try:
33
+ from . import active_agent_name
34
+
35
+ active = active_agent_name()
36
+ if active:
37
+ return active
38
+ except Exception:
39
+ pass
40
+
41
+ return "sovereign"
42
+
43
+
44
+ def render_loader_script() -> str:
45
+ """Render the Codex context loader script."""
46
+ return """#!/usr/bin/env bash
47
+ set -euo pipefail
48
+
49
+ export PATH="$HOME/.skenv/bin:$PATH"
50
+ export SKCAPSTONE_HOME="${SKCAPSTONE_HOME:-$HOME/.skcapstone}"
51
+
52
+ AGENT="${1:-${SKAGENT:-${SKCAPSTONE_AGENT:-${SKMEMORY_AGENT:-}}}}"
53
+ if [[ -z "$AGENT" && -d "$SKCAPSTONE_HOME/agents" ]]; then
54
+ AGENT="$(find "$SKCAPSTONE_HOME/agents" -mindepth 1 -maxdepth 1 -type d ! -name '*-template' -exec basename {} \\; 2>/dev/null | sort | head -n1 || true)"
55
+ fi
56
+ if [[ -z "$AGENT" ]]; then
57
+ echo "No active SK agent could be resolved." >&2
58
+ exit 1
59
+ fi
60
+
61
+ export SKAGENT="$AGENT"
62
+ export SKCAPSTONE_AGENT="$AGENT"
63
+ export SKMEMORY_AGENT="${SKMEMORY_AGENT:-$AGENT}"
64
+
65
+ AGENT_HOME="$SKCAPSTONE_HOME/agents/$AGENT"
66
+ export SKWHISPER_CONFIG="${SKWHISPER_CONFIG:-$AGENT_HOME/config/skwhisper.toml}"
67
+ MEMORIES="${SKCAPSTONE_CONTEXT_MEMORIES:-10}"
68
+
69
+ echo "# SK Agent Bootstrap"
70
+ echo
71
+ echo "agent=$AGENT"
72
+ echo "agent_home=$AGENT_HOME"
73
+ echo "skmemory_home=$AGENT_HOME/memory"
74
+ echo
75
+
76
+ echo "## skcapstone context"
77
+ if command -v skcapstone >/dev/null 2>&1; then
78
+ skcapstone context show --home "$AGENT_HOME" --format json --memories "$MEMORIES" || skcapstone status --home "$AGENT_HOME" || true
79
+ else
80
+ echo "skcapstone command not found on PATH."
81
+ fi
82
+
83
+ echo
84
+ echo "## skmemory ritual"
85
+ if command -v skmemory >/dev/null 2>&1; then
86
+ skmemory ritual --full || skmemory ritual || true
87
+ else
88
+ echo "skmemory command not found on PATH."
89
+ fi
90
+
91
+ echo
92
+ echo "## skwhisper context"
93
+ WHISPER_CONTEXT="$AGENT_HOME/skwhisper/whisper.md"
94
+ if [[ -f "$WHISPER_CONTEXT" ]]; then
95
+ sed -n '1,220p' "$WHISPER_CONTEXT"
96
+ elif command -v skwhisper >/dev/null 2>&1 && [[ -f "$SKWHISPER_CONFIG" ]]; then
97
+ skwhisper -c "$SKWHISPER_CONFIG" status || true
98
+ else
99
+ echo "No SKWhisper context found for $AGENT."
100
+ fi
101
+ """
102
+
103
+
104
+ def render_agents_block(
105
+ *,
106
+ loader_path: Path,
107
+ agent_name: str | None = None,
108
+ skcapstone_home: Path | None = None,
109
+ ) -> str:
110
+ """Render the managed global Codex AGENTS.md block."""
111
+ agent = agent_name or resolve_default_agent()
112
+ sk_home = skcapstone_home or Path(os.environ.get("SKCAPSTONE_HOME", "~/.skcapstone")).expanduser()
113
+ return f"""{START_MARKER}
114
+ # SKCapstone Agent Context
115
+
116
+ This Codex installation is wired to the local SK* sovereign agent stack. Use
117
+ the active SK agent profile for SKCapstone, SKMemory, SKWhisper, CapAuth,
118
+ SKSeed, SKPerf, and related local stack work.
119
+
120
+ Active agent resolution order: `$SKAGENT`, `$SKCAPSTONE_AGENT`,
121
+ `$SKMEMORY_AGENT`, then installed agents under `{sk_home}/agents/`. Current
122
+ install default: `{agent}`.
123
+
124
+ At the start of SK* work, identity/status questions, or tasks involving the
125
+ local sovereign stack, run:
126
+
127
+ ```bash
128
+ {loader_path}
129
+ ```
130
+
131
+ Treat that output as the current agent context. When asked who you are, what
132
+ profile is active, or what your OOF/status is, answer from the current
133
+ SKMemory ritual / SKCapstone context instead of generic Codex defaults.
134
+ {END_MARKER}
135
+ """
136
+
137
+
138
+ def loader_path(home: Path | None = None) -> Path:
139
+ """Return the expected Codex loader path."""
140
+ base = home or codex_home()
141
+ return base / "bin" / LOADER_NAME
142
+
143
+
144
+ def agents_path(home: Path | None = None) -> Path:
145
+ """Return the expected global Codex AGENTS.md path."""
146
+ base = home or codex_home()
147
+ return base / "AGENTS.md"
148
+
149
+
150
+ def has_functional_agents_bootstrap(text: str) -> bool:
151
+ """Return True when AGENTS.md already has enough SK bootstrap guidance."""
152
+ required = (
153
+ LOADER_NAME,
154
+ "SKAGENT",
155
+ "SKCAPSTONE_AGENT",
156
+ "SKMEMORY_AGENT",
157
+ "OOF",
158
+ )
159
+ return all(token in text for token in required)
160
+
161
+
162
+ def has_functional_loader_bootstrap(text: str) -> bool:
163
+ """Return True when the loader can emit SKCapstone/SKMemory context."""
164
+ required = (
165
+ "SKAGENT",
166
+ "SKCAPSTONE_AGENT",
167
+ "SKMEMORY_AGENT",
168
+ "skcapstone",
169
+ "skmemory",
170
+ "skwhisper",
171
+ )
172
+ return all(token in text for token in required)
173
+
174
+
175
+ def ensure_codex_setup(
176
+ *,
177
+ home: Path | None = None,
178
+ agent_name: str | None = None,
179
+ skcapstone_home: Path | None = None,
180
+ ) -> list[str]:
181
+ """Create or repair the global Codex SK agent bootstrap.
182
+
183
+ Returns:
184
+ Human-readable actions performed. An empty list means no changes were
185
+ needed.
186
+ """
187
+ base = home or codex_home()
188
+ base.mkdir(parents=True, exist_ok=True)
189
+
190
+ actions: list[str] = []
191
+
192
+ script_path = loader_path(base)
193
+ script_path.parent.mkdir(parents=True, exist_ok=True)
194
+ script_content = render_loader_script()
195
+ existing_script = script_path.read_text(encoding="utf-8") if script_path.exists() else ""
196
+ if not has_functional_loader_bootstrap(existing_script):
197
+ script_path.write_text(script_content, encoding="utf-8")
198
+ actions.append(f"wrote {script_path}")
199
+
200
+ mode = script_path.stat().st_mode
201
+ executable_bits = stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
202
+ if mode & stat.S_IXUSR == 0:
203
+ script_path.chmod(mode | executable_bits)
204
+ actions.append(f"made {script_path} executable")
205
+
206
+ ag_path = agents_path(base)
207
+ existing = ag_path.read_text(encoding="utf-8") if ag_path.exists() else ""
208
+ block = render_agents_block(
209
+ loader_path=script_path,
210
+ agent_name=agent_name,
211
+ skcapstone_home=skcapstone_home,
212
+ )
213
+
214
+ if START_MARKER in existing and END_MARKER in existing:
215
+ before, remainder = existing.split(START_MARKER, 1)
216
+ _, after = remainder.split(END_MARKER, 1)
217
+ updated = before.rstrip() + "\n\n" + block.rstrip() + "\n" + after
218
+ elif has_functional_agents_bootstrap(existing):
219
+ updated = existing
220
+ elif existing.strip():
221
+ updated = existing.rstrip() + "\n\n" + block
222
+ else:
223
+ updated = block
224
+
225
+ if updated != existing:
226
+ ag_path.write_text(updated, encoding="utf-8")
227
+ actions.append(f"updated {ag_path}")
228
+
229
+ return actions
230
+
231
+
232
+ def check_codex_setup(home: Path | None = None) -> tuple[bool, str]:
233
+ """Check whether Codex has the SK agent bootstrap installed."""
234
+ base = home or codex_home()
235
+ missing: list[str] = []
236
+
237
+ script_path = loader_path(base)
238
+ if not script_path.exists():
239
+ missing.append(str(script_path))
240
+ elif not has_functional_loader_bootstrap(script_path.read_text(encoding="utf-8")):
241
+ missing.append(f"{script_path} SK context loader")
242
+ elif not os.access(script_path, os.X_OK):
243
+ missing.append(f"{script_path} executable bit")
244
+
245
+ ag_path = agents_path(base)
246
+ if not ag_path.exists():
247
+ missing.append(str(ag_path))
248
+ else:
249
+ text = ag_path.read_text(encoding="utf-8")
250
+ if START_MARKER not in text and not has_functional_agents_bootstrap(text):
251
+ missing.append(f"{ag_path} SK bootstrap instructions")
252
+
253
+ if missing:
254
+ return False, "missing: " + ", ".join(missing)
255
+ return True, f"{ag_path} + {script_path}"
@@ -16,6 +16,7 @@ Usage:
16
16
  from __future__ import annotations
17
17
 
18
18
  import json
19
+ import logging
19
20
  import re
20
21
  from dataclasses import dataclass, field
21
22
  from pathlib import Path
@@ -23,6 +24,8 @@ from typing import Any, Optional
23
24
 
24
25
  import yaml
25
26
 
27
+ logger = logging.getLogger(__name__)
28
+
26
29
 
27
30
  # ---------------------------------------------------------------------------
28
31
  # Result models
@@ -113,8 +116,8 @@ def _yaml_key_line(text: str, key: str) -> Optional[int]:
113
116
  for key_node, _ in node.value:
114
117
  if isinstance(key_node, yaml.ScalarNode) and key_node.value == key:
115
118
  return key_node.start_mark.line + 1
116
- except Exception:
117
- pass
119
+ except Exception as exc:
120
+ logger.debug("Failed to locate YAML key '%s' for line number: %s", key, exc)
118
121
  return None
119
122
 
120
123
 
@@ -147,8 +150,8 @@ def _yaml_seq_item_line(text: str, seq_key: str, idx: int, subkey: str) -> Optio
147
150
  if kk.value == subkey:
148
151
  return kk.start_mark.line + 1
149
152
  return item.start_mark.line + 1
150
- except Exception:
151
- pass
153
+ except Exception as exc:
154
+ logger.debug("Failed to locate YAML seq item line for '%s[%d].%s': %s", seq_key, idx, subkey, exc)
152
155
  return None
153
156
 
154
157
 
@@ -79,7 +79,7 @@ def load_consciousness_config(
79
79
  return config
80
80
 
81
81
 
82
- def write_default_config(home: Path) -> Path:
82
+ def write_default_config(home: Path, **overrides) -> Path:
83
83
  """Write the default consciousness config to disk.
84
84
 
85
85
  Creates {home}/config/consciousness.yaml with all defaults
@@ -87,6 +87,8 @@ def write_default_config(home: Path) -> Path:
87
87
 
88
88
  Args:
89
89
  home: Agent home directory.
90
+ **overrides: Key-value overrides applied to the default config
91
+ (e.g. ollama_host, ollama_model).
90
92
 
91
93
  Returns:
92
94
  Path to the created config file.
@@ -96,6 +98,8 @@ def write_default_config(home: Path) -> Path:
96
98
  config_path = config_dir / CONFIG_FILENAME
97
99
 
98
100
  default = ConsciousnessConfig()
101
+ if overrides:
102
+ default = default.model_copy(update=overrides)
99
103
  content = yaml.dump(
100
104
  default.model_dump(),
101
105
  default_flow_style=False,