@smilintux/skcapstone 0.9.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 (284) 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 +278 -1
  18. package/docs/DREAMING.md +70 -0
  19. package/docs/GETTING_STARTED.md +10 -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.daemon.plist +52 -0
  33. package/launchd/com.skcapstone.memory-compress.plist +45 -0
  34. package/launchd/com.skcapstone.skcomms-heartbeat.plist +33 -0
  35. package/launchd/com.skcapstone.skcomms-queue-drain.plist +34 -0
  36. package/launchd/install-launchd.sh +156 -0
  37. package/{openclaw-plugin → openclaw-plugin.archived-2026-04-23}/src/index.ts +3 -2
  38. package/package.json +1 -1
  39. package/pyproject.toml +16 -10
  40. package/scripts/archive-sessions.sh +95 -0
  41. package/scripts/check-updates.py +4 -4
  42. package/scripts/install-bundle.sh +8 -8
  43. package/scripts/install.ps1 +12 -11
  44. package/scripts/install.sh +196 -11
  45. package/scripts/model-fallback-monitor.sh +102 -0
  46. package/scripts/notion-api.py +259 -0
  47. package/scripts/nvidia-proxy.mjs +908 -0
  48. package/scripts/proxy-monitor.sh +89 -0
  49. package/scripts/refresh-anthropic-token.sh +172 -0
  50. package/scripts/release.sh +98 -0
  51. package/scripts/session-to-memory.py +219 -0
  52. package/scripts/skgateway.mjs +856 -0
  53. package/scripts/telegram-catchup-all.sh +147 -0
  54. package/scripts/verify_install.sh +2 -2
  55. package/scripts/wargov-ufo-capture/README.md +43 -0
  56. package/scripts/wargov-ufo-capture/cdp_capture_release2.py +273 -0
  57. package/scripts/wargov-ufo-capture/cdp_capture_splc_doj.py +246 -0
  58. package/scripts/wargov-ufo-capture/cdp_finish.py +271 -0
  59. package/scripts/wargov-ufo-capture/cdp_probe.py +188 -0
  60. package/scripts/wargov-ufo-capture/cdp_splc_pressrelease.py +101 -0
  61. package/scripts/wargov-ufo-capture/parse_csv.py +95 -0
  62. package/scripts/wargov-ufo-capture/pull_dvids.sh +107 -0
  63. package/scripts/watch-anthropic-token.sh +212 -0
  64. package/scripts/windows/install-tasks.ps1 +7 -7
  65. package/scripts/windows/skcapstone-task.xml +1 -1
  66. package/src/skcapstone/__init__.py +45 -3
  67. package/src/skcapstone/_cli_monolith.py +20 -15
  68. package/src/skcapstone/activity.py +5 -1
  69. package/src/skcapstone/agent_card.py +3 -2
  70. package/src/skcapstone/api.py +41 -40
  71. package/src/skcapstone/auction.py +14 -11
  72. package/src/skcapstone/backup.py +2 -1
  73. package/src/skcapstone/blueprint_registry.py +4 -3
  74. package/src/skcapstone/blueprints/builtins/itil-operations.yaml +40 -0
  75. package/src/skcapstone/brain_first.py +238 -0
  76. package/src/skcapstone/changelog.py +1 -1
  77. package/src/skcapstone/chat.py +22 -17
  78. package/src/skcapstone/cli/__init__.py +9 -1
  79. package/src/skcapstone/cli/_common.py +1 -0
  80. package/src/skcapstone/cli/agents_spawner.py +5 -2
  81. package/src/skcapstone/cli/alerts.py +25 -4
  82. package/src/skcapstone/cli/bench.py +15 -15
  83. package/src/skcapstone/cli/chat.py +7 -4
  84. package/src/skcapstone/cli/consciousness.py +5 -2
  85. package/src/skcapstone/cli/context_cmd.py +18 -4
  86. package/src/skcapstone/cli/daemon.py +121 -42
  87. package/src/skcapstone/cli/gtd.py +26 -1
  88. package/src/skcapstone/cli/housekeeping.py +3 -3
  89. package/src/skcapstone/cli/identity_cmd.py +378 -0
  90. package/src/skcapstone/cli/joule_cmd.py +7 -3
  91. package/src/skcapstone/cli/memory.py +8 -6
  92. package/src/skcapstone/cli/peers_dir.py +1 -1
  93. package/src/skcapstone/cli/register_cmd.py +29 -3
  94. package/src/skcapstone/cli/scheduler_cmd.py +167 -0
  95. package/src/skcapstone/cli/session.py +25 -0
  96. package/src/skcapstone/cli/setup.py +96 -29
  97. package/src/skcapstone/cli/shell_cmd.py +53 -1
  98. package/src/skcapstone/cli/skills_cmd.py +2 -2
  99. package/src/skcapstone/cli/soul.py +8 -5
  100. package/src/skcapstone/cli/status.py +37 -11
  101. package/src/skcapstone/cli/telegram.py +21 -0
  102. package/src/skcapstone/cli/test_cmd.py +5 -5
  103. package/src/skcapstone/cli/test_connection.py +2 -2
  104. package/src/skcapstone/cli/upgrade_cmd.py +23 -14
  105. package/src/skcapstone/cli/version_cmd.py +1 -1
  106. package/src/skcapstone/cli/watch_cmd.py +9 -6
  107. package/src/skcapstone/cloud9_bridge.py +14 -14
  108. package/src/skcapstone/codex_setup.py +255 -0
  109. package/src/skcapstone/config_validator.py +7 -4
  110. package/src/skcapstone/consciousness_config.py +5 -1
  111. package/src/skcapstone/consciousness_loop.py +313 -273
  112. package/src/skcapstone/context_loader.py +121 -0
  113. package/src/skcapstone/coord_federation.py +2 -1
  114. package/src/skcapstone/coordination.py +23 -6
  115. package/src/skcapstone/crush_integration.py +2 -1
  116. package/src/skcapstone/daemon.py +151 -88
  117. package/src/skcapstone/dashboard.py +10 -10
  118. package/src/skcapstone/data/sk-agent-picker.sh +421 -0
  119. package/src/skcapstone/data/systemd/skcapstone-api.socket +9 -0
  120. package/src/skcapstone/data/systemd/skcapstone-memory-compress.service +18 -0
  121. package/src/skcapstone/data/systemd/skcapstone-memory-compress.timer +11 -0
  122. package/src/skcapstone/data/systemd/skcapstone.service +37 -0
  123. package/src/skcapstone/data/systemd/skcapstone@.service +50 -0
  124. package/src/skcapstone/data/systemd/skcomms-heartbeat.service +18 -0
  125. package/{systemd/skcomm-heartbeat.timer → src/skcapstone/data/systemd/skcomms-heartbeat.timer} +2 -2
  126. package/src/skcapstone/data/systemd/skcomms-queue-drain.service +17 -0
  127. package/{systemd/skcomm-queue-drain.timer → src/skcapstone/data/systemd/skcomms-queue-drain.timer} +2 -2
  128. package/src/skcapstone/defaults/claude/CLAUDE.md +67 -0
  129. package/src/skcapstone/defaults/claude/settings.json +74 -0
  130. package/src/skcapstone/defaults/lumina/config/claude-hooks.md +57 -0
  131. package/src/skcapstone/defaults/lumina/config/skgraph.yaml +55 -10
  132. package/src/skcapstone/defaults/lumina/config/skmemory.yaml +79 -13
  133. package/src/skcapstone/defaults/lumina/config/skvector.yaml +60 -9
  134. package/src/skcapstone/defaults/lumina/memory/long-term/18b9c0d1e2f3-cloud9-protocol.json +2 -2
  135. package/src/skcapstone/defaults/lumina/memory/long-term/a1b2c3d4e5f6-ecosystem-overview.json +2 -2
  136. package/src/skcapstone/defaults/lumina/memory/long-term/b2c3d4e5f6a7-five-pillars.json +9 -9
  137. package/src/skcapstone/defaults/lumina/memory/long-term/d4e5f6a7b8c9-site-directory.json +2 -2
  138. package/src/skcapstone/defaults/unhinged.json +13 -0
  139. package/src/skcapstone/discovery.py +43 -20
  140. package/src/skcapstone/doctor.py +941 -22
  141. package/src/skcapstone/dreaming.py +1183 -109
  142. package/src/skcapstone/emotion_tracker.py +2 -2
  143. package/src/skcapstone/export.py +4 -3
  144. package/src/skcapstone/fuse_mount.py +35 -25
  145. package/src/skcapstone/gui_installer.py +2 -2
  146. package/src/skcapstone/heartbeat.py +34 -30
  147. package/src/skcapstone/housekeeping.py +14 -14
  148. package/src/skcapstone/install_wizard.py +209 -7
  149. package/src/skcapstone/itil.py +13 -4
  150. package/src/skcapstone/kms_scheduler.py +10 -8
  151. package/src/skcapstone/launchd.py +426 -0
  152. package/src/skcapstone/mcp_launcher.py +15 -1
  153. package/src/skcapstone/mcp_server.py +341 -49
  154. package/src/skcapstone/mcp_tools/__init__.py +2 -0
  155. package/src/skcapstone/mcp_tools/_helpers.py +2 -2
  156. package/src/skcapstone/mcp_tools/ansible_tools.py +7 -4
  157. package/src/skcapstone/mcp_tools/brain_first_tools.py +90 -0
  158. package/src/skcapstone/mcp_tools/capauth_tools.py +7 -4
  159. package/src/skcapstone/mcp_tools/comm_tools.py +10 -10
  160. package/src/skcapstone/mcp_tools/coord_tools.py +8 -4
  161. package/src/skcapstone/mcp_tools/did_tools.py +11 -8
  162. package/src/skcapstone/mcp_tools/gtd_tools.py +4 -4
  163. package/src/skcapstone/mcp_tools/memory_tools.py +6 -2
  164. package/src/skcapstone/mcp_tools/notification_tools.py +22 -6
  165. package/src/skcapstone/mcp_tools/{skcomm_tools.py → skcomms_tools.py} +14 -14
  166. package/src/skcapstone/mcp_tools/soul_tools.py +8 -2
  167. package/src/skcapstone/mdns_discovery.py +2 -2
  168. package/src/skcapstone/memory_curator.py +1 -1
  169. package/src/skcapstone/memory_engine.py +10 -3
  170. package/src/skcapstone/metrics.py +30 -16
  171. package/src/skcapstone/migrate_memories.py +4 -3
  172. package/src/skcapstone/migrate_multi_agent.py +8 -7
  173. package/src/skcapstone/models.py +47 -5
  174. package/src/skcapstone/notifications.py +42 -18
  175. package/src/skcapstone/onboard.py +1000 -126
  176. package/src/skcapstone/operator_link.py +170 -0
  177. package/src/skcapstone/peer_directory.py +4 -4
  178. package/src/skcapstone/peers.py +19 -19
  179. package/src/skcapstone/pillars/__init__.py +7 -5
  180. package/src/skcapstone/pillars/consciousness.py +191 -0
  181. package/src/skcapstone/pillars/identity.py +51 -7
  182. package/src/skcapstone/pillars/memory.py +9 -3
  183. package/src/skcapstone/pillars/sync.py +2 -2
  184. package/src/skcapstone/preflight.py +3 -3
  185. package/src/skcapstone/providers/docker.py +28 -28
  186. package/src/skcapstone/register.py +6 -6
  187. package/src/skcapstone/registry_client.py +5 -4
  188. package/src/skcapstone/runtime.py +14 -3
  189. package/src/skcapstone/scheduled_tasks.py +254 -19
  190. package/src/skcapstone/scheduler_jobs.py +456 -0
  191. package/src/skcapstone/scheduler_runner.py +239 -0
  192. package/src/skcapstone/scheduler_state.py +162 -0
  193. package/src/skcapstone/sdk.py +310 -0
  194. package/src/skcapstone/service_health.py +279 -39
  195. package/src/skcapstone/session_briefing.py +108 -0
  196. package/src/skcapstone/session_capture.py +1 -1
  197. package/src/skcapstone/shell.py +7 -1
  198. package/src/skcapstone/soul.py +3 -1
  199. package/src/skcapstone/soul_switch.py +3 -1
  200. package/src/skcapstone/summary.py +6 -6
  201. package/src/skcapstone/sync_engine.py +15 -15
  202. package/src/skcapstone/sync_watcher.py +2 -2
  203. package/src/skcapstone/systemd.py +72 -21
  204. package/src/skcapstone/team_comms.py +8 -8
  205. package/src/skcapstone/team_engine.py +1 -1
  206. package/src/skcapstone/testrunner.py +3 -3
  207. package/src/skcapstone/trust_graph.py +40 -5
  208. package/src/skcapstone/unified_search.py +15 -6
  209. package/src/skcapstone/uninstall_wizard.py +11 -3
  210. package/src/skcapstone/version_check.py +8 -4
  211. package/src/skcapstone/warmth_anchor.py +4 -2
  212. package/src/skcapstone/whoami.py +4 -4
  213. package/systemd/skcapstone.service +4 -6
  214. package/systemd/skcapstone@.service +7 -8
  215. package/systemd/skcomms-heartbeat.service +21 -0
  216. package/systemd/skcomms-heartbeat.timer +12 -0
  217. package/systemd/skcomms-queue-drain.service +17 -0
  218. package/systemd/skcomms-queue-drain.timer +12 -0
  219. package/tests/conftest.py +39 -0
  220. package/tests/integration/test_consciousness_e2e.py +39 -39
  221. package/tests/test_agent_card.py +1 -1
  222. package/tests/test_agent_home_scaffold.py +34 -0
  223. package/tests/test_alerts_consumer_topics.py +27 -0
  224. package/tests/test_backup.py +2 -1
  225. package/tests/test_chat.py +6 -6
  226. package/tests/test_claude_md.py +2 -2
  227. package/tests/test_cli_skills.py +10 -10
  228. package/tests/test_cli_test_cmd.py +4 -4
  229. package/tests/test_cli_test_connection.py +1 -1
  230. package/tests/test_cloud9_bridge.py +6 -6
  231. package/tests/test_consciousness_e2e.py +1 -1
  232. package/tests/test_consciousness_loop.py +10 -10
  233. package/tests/test_coordination.py +25 -0
  234. package/tests/test_cross_package.py +21 -21
  235. package/tests/test_daemon.py +4 -4
  236. package/tests/test_daemon_shutdown.py +1 -1
  237. package/tests/test_docker_provider.py +29 -29
  238. package/tests/test_doctor.py +400 -0
  239. package/tests/test_doctor_skscheduler.py +50 -0
  240. package/tests/test_dreaming_engine.py +147 -0
  241. package/tests/test_dreaming_gtd_capture.py +35 -0
  242. package/tests/test_e2e_automated.py +8 -5
  243. package/tests/test_fuse_mount.py +10 -10
  244. package/tests/test_gtd_brief.py +46 -0
  245. package/tests/test_gtd_malformed_tolerance.py +31 -0
  246. package/tests/test_housekeeping.py +15 -15
  247. package/tests/test_identity_migrate.py +251 -0
  248. package/tests/test_integration_backbone.py +598 -0
  249. package/tests/test_itil_gtd_lifecycle.py +37 -0
  250. package/tests/test_jobs_dropins.py +84 -0
  251. package/tests/test_mcp_server.py +82 -37
  252. package/tests/test_models.py +48 -4
  253. package/tests/test_multi_agent.py +31 -29
  254. package/tests/test_notifications.py +122 -32
  255. package/tests/test_onboard.py +63 -75
  256. package/tests/test_operator_link.py +78 -0
  257. package/tests/test_peers.py +14 -14
  258. package/tests/test_pillars.py +98 -0
  259. package/tests/test_preflight.py +3 -3
  260. package/tests/test_runtime.py +21 -0
  261. package/tests/test_scheduled_tasks.py +11 -6
  262. package/tests/test_scheduler_cli.py +47 -0
  263. package/tests/test_scheduler_features.py +133 -0
  264. package/tests/test_scheduler_integration.py +87 -0
  265. package/tests/test_scheduler_jobs.py +155 -0
  266. package/tests/test_scheduler_runner.py +64 -0
  267. package/tests/test_scheduler_state.py +57 -0
  268. package/tests/test_sdk.py +70 -0
  269. package/tests/test_service_health_incidents.py +34 -0
  270. package/tests/test_service_registry.py +52 -0
  271. package/tests/test_session_briefing.py +130 -0
  272. package/tests/test_snapshots.py +4 -4
  273. package/tests/test_sync_pipeline.py +26 -26
  274. package/tests/test_team_comms.py +2 -2
  275. package/tests/test_testrunner.py +2 -2
  276. package/tests/test_trust_graph.py +18 -0
  277. package/tests/test_unified_search.py +2 -2
  278. package/tests/test_version_check.py +10 -0
  279. package/tests/test_version_cmd.py +8 -8
  280. package/tests/test_whoami.py +1 -1
  281. package/systemd/skcomm-heartbeat.service +0 -18
  282. package/systemd/skcomm-queue-drain.service +0 -17
  283. /package/{openclaw-plugin → openclaw-plugin.archived-2026-04-23}/package.json +0 -0
  284. /package/{openclaw-plugin → openclaw-plugin.archived-2026-04-23}/src/openclaw.plugin.json +0 -0
@@ -9,8 +9,8 @@ Tools:
9
9
  memory_store — Save content to SKMemory
10
10
  memory_search — Search memories by query
11
11
  memory_recall — Recall a specific memory by ID
12
- send_message — Send a message via SKComm
13
- check_inbox — Check for new SKComm messages
12
+ send_message — Send a message via SKComms
13
+ check_inbox — Check for new SKComms messages
14
14
  sync_push — Push agent state to sync mesh
15
15
  sync_pull — Pull seeds from peers
16
16
  coord_status — Show coordination board
@@ -55,6 +55,16 @@ Tools:
55
55
  kms_list_keys — List all KMS keys
56
56
  kms_rotate — Rotate a KMS key
57
57
  model_route — Route task to optimal model tier/name
58
+ itil_incident_create — Create ITIL incident
59
+ itil_incident_update — Update incident status/severity
60
+ itil_incident_list — List/filter incidents
61
+ itil_problem_create — Create problem record
62
+ itil_problem_update — Update problem/root cause
63
+ itil_change_propose — Propose change (RFC)
64
+ itil_change_update — Update change status
65
+ itil_cab_vote — Submit CAB vote
66
+ itil_status — ITIL dashboard
67
+ itil_kedb_search — Search Known Error Database
58
68
 
59
69
  Invocation (all equivalent):
60
70
  skcapstone mcp serve # CLI entry point
@@ -98,33 +108,18 @@ from mcp.server import Server
98
108
  from mcp.server.stdio import stdio_server
99
109
  from mcp.types import TextContent, Tool
100
110
 
101
- from . import AGENT_HOME
111
+ from .mcp_tools._helpers import (
112
+ _error_response,
113
+ _home,
114
+ _json_response,
115
+ _text_response,
116
+ )
102
117
 
103
118
  logger = logging.getLogger("skcapstone.mcp")
104
119
 
105
120
  server = Server("skcapstone")
106
121
 
107
122
 
108
- def _home() -> Path:
109
- """Resolve the agent home directory."""
110
- return Path(AGENT_HOME).expanduser()
111
-
112
-
113
- def _json_response(data: Any) -> list[TextContent]:
114
- """Wrap data as a JSON text content response."""
115
- return [TextContent(type="text", text=json.dumps(data, indent=2, default=str))]
116
-
117
-
118
- def _text_response(text: str) -> list[TextContent]:
119
- """Wrap a plain string as a text content response."""
120
- return [TextContent(type="text", text=text)]
121
-
122
-
123
- def _error_response(message: str) -> list[TextContent]:
124
- """Return an error message as text content."""
125
- return [TextContent(type="text", text=json.dumps({"error": message}))]
126
-
127
-
128
123
  def _get_agent_name(home: Path) -> str:
129
124
  """Read the agent name from identity file."""
130
125
  identity_path = home / "identity" / "identity.json"
@@ -132,8 +127,8 @@ def _get_agent_name(home: Path) -> str:
132
127
  try:
133
128
  data = json.loads(identity_path.read_text(encoding="utf-8"))
134
129
  return data.get("name", "anonymous")
135
- except Exception:
136
- pass
130
+ except Exception as exc:
131
+ logger.warning("Failed to read agent name from identity.json: %s", exc)
137
132
  return "anonymous"
138
133
 
139
134
 
@@ -232,7 +227,7 @@ async def list_tools() -> list[Tool]:
232
227
  Tool(
233
228
  name="send_message",
234
229
  description=(
235
- "Send a message to another agent via SKComm. "
230
+ "Send a message to another agent via SKComms. "
236
231
  "Routes through available transports (Syncthing, file)."
237
232
  ),
238
233
  inputSchema={
@@ -258,7 +253,7 @@ async def list_tools() -> list[Tool]:
258
253
  Tool(
259
254
  name="check_inbox",
260
255
  description=(
261
- "Check for new incoming messages across all SKComm transports. "
256
+ "Check for new incoming messages across all SKComms transports. "
262
257
  "Returns any unread message envelopes."
263
258
  ),
264
259
  inputSchema={"type": "object", "properties": {}, "required": []},
@@ -1633,7 +1628,7 @@ async def list_tools() -> list[Tool]:
1633
1628
  description=(
1634
1629
  "Check ecosystem package versions against PyPI. "
1635
1630
  "Shows installed vs latest for skmemory, skcapstone, capauth, "
1636
- "sksecurity, skcomm, skchat, cloud9-protocol."
1631
+ "sksecurity, skcomms, skchat, cloud9."
1637
1632
  ),
1638
1633
  inputSchema={
1639
1634
  "type": "object",
@@ -2358,11 +2353,11 @@ async def list_tools() -> list[Tool]:
2358
2353
  "required": [],
2359
2354
  },
2360
2355
  ),
2361
- # ── SKComm tools ──────────────────────────────────────
2356
+ # ── SKComms tools ──────────────────────────────────────
2362
2357
  Tool(
2363
2358
  name="comm_notify",
2364
2359
  description=(
2365
- "Send a notification message via SKComm. Routes through "
2360
+ "Send a notification message via SKComms. Routes through "
2366
2361
  "available transports (Syncthing, file, Tailscale). "
2367
2362
  "Supports urgency levels for priority routing."
2368
2363
  ),
@@ -2393,7 +2388,7 @@ async def list_tools() -> list[Tool]:
2393
2388
  Tool(
2394
2389
  name="comm_status",
2395
2390
  description=(
2396
- "Show SKComm subsystem status: installed version, "
2391
+ "Show SKComms subsystem status: installed version, "
2397
2392
  "available transports, connection state, and recent "
2398
2393
  "delivery statistics."
2399
2394
  ),
@@ -2470,6 +2465,213 @@ async def list_tools() -> list[Tool]:
2470
2465
  "required": ["name"],
2471
2466
  },
2472
2467
  ),
2468
+ # ── ITIL Service Management ─────────────────────────────
2469
+ Tool(
2470
+ name="itil_incident_create",
2471
+ description=(
2472
+ "Create a new ITIL incident for a service disruption. "
2473
+ "Auto-creates a linked GTD item (next-action for sev1/sev2, inbox for sev3/sev4)."
2474
+ ),
2475
+ inputSchema={
2476
+ "type": "object",
2477
+ "properties": {
2478
+ "title": {"type": "string", "description": "Brief description of the incident"},
2479
+ "severity": {"type": "string", "enum": ["sev1", "sev2", "sev3", "sev4"], "description": "Severity level (default: sev3)"},
2480
+ "source": {"type": "string", "enum": ["service_health", "dreaming", "manual", "daemon_error", "heartbeat"], "description": "Detection source (default: manual)"},
2481
+ "affected_services": {"type": "array", "items": {"type": "string"}, "description": "List of affected service names"},
2482
+ "impact": {"type": "string", "description": "Business impact description"},
2483
+ "managed_by": {"type": "string", "description": "Agent responsible for managing this incident"},
2484
+ "tags": {"type": "array", "items": {"type": "string"}, "description": "Tags for categorization"},
2485
+ },
2486
+ "required": ["title"],
2487
+ },
2488
+ ),
2489
+ Tool(
2490
+ name="itil_incident_update",
2491
+ description=(
2492
+ "Update an incident: transition status, escalate severity, "
2493
+ "add timeline notes, or resolve. Valid status transitions: "
2494
+ "detected->acknowledged->investigating->resolved->closed."
2495
+ ),
2496
+ inputSchema={
2497
+ "type": "object",
2498
+ "properties": {
2499
+ "incident_id": {"type": "string", "description": "Incident ID (e.g. inc-a1b2c3d4)"},
2500
+ "agent": {"type": "string", "description": "Agent making the update"},
2501
+ "new_status": {"type": "string", "enum": ["acknowledged", "investigating", "escalated", "resolved", "closed"], "description": "New status"},
2502
+ "severity": {"type": "string", "enum": ["sev1", "sev2", "sev3", "sev4"], "description": "New severity"},
2503
+ "note": {"type": "string", "description": "Timeline note"},
2504
+ "resolution_summary": {"type": "string", "description": "Resolution summary (when resolving)"},
2505
+ "related_problem_id": {"type": "string", "description": "Link to a related problem record"},
2506
+ },
2507
+ "required": ["incident_id", "agent"],
2508
+ },
2509
+ ),
2510
+ Tool(
2511
+ name="itil_incident_list",
2512
+ description="List ITIL incidents filtered by status, severity, or affected service.",
2513
+ inputSchema={
2514
+ "type": "object",
2515
+ "properties": {
2516
+ "status": {"type": "string", "enum": ["detected", "acknowledged", "investigating", "escalated", "resolved", "closed"], "description": "Filter by status"},
2517
+ "severity": {"type": "string", "enum": ["sev1", "sev2", "sev3", "sev4"], "description": "Filter by severity"},
2518
+ "service": {"type": "string", "description": "Filter by affected service name"},
2519
+ },
2520
+ "required": [],
2521
+ },
2522
+ ),
2523
+ Tool(
2524
+ name="itil_problem_create",
2525
+ description=(
2526
+ "Create a new ITIL problem record to investigate root cause. "
2527
+ "Links to related incidents and auto-creates a GTD project."
2528
+ ),
2529
+ inputSchema={
2530
+ "type": "object",
2531
+ "properties": {
2532
+ "title": {"type": "string", "description": "Problem title"},
2533
+ "managed_by": {"type": "string", "description": "Agent responsible for investigation"},
2534
+ "related_incident_ids": {"type": "array", "items": {"type": "string"}, "description": "Related incident IDs"},
2535
+ "workaround": {"type": "string", "description": "Known workaround if any"},
2536
+ "tags": {"type": "array", "items": {"type": "string"}, "description": "Tags for categorization"},
2537
+ },
2538
+ "required": ["title"],
2539
+ },
2540
+ ),
2541
+ Tool(
2542
+ name="itil_problem_update",
2543
+ description=(
2544
+ "Update a problem record: transition status, set root cause, "
2545
+ "add workaround, optionally create a KEDB entry. "
2546
+ "Valid transitions: identified->analyzing->known_error->resolved."
2547
+ ),
2548
+ inputSchema={
2549
+ "type": "object",
2550
+ "properties": {
2551
+ "problem_id": {"type": "string", "description": "Problem ID (e.g. prb-e5f6g7h8)"},
2552
+ "agent": {"type": "string", "description": "Agent making the update"},
2553
+ "new_status": {"type": "string", "enum": ["analyzing", "known_error", "resolved"], "description": "New status"},
2554
+ "root_cause": {"type": "string", "description": "Root cause description"},
2555
+ "workaround": {"type": "string", "description": "Workaround description"},
2556
+ "note": {"type": "string", "description": "Timeline note"},
2557
+ "create_kedb": {"type": "boolean", "description": "Create a KEDB entry from this problem"},
2558
+ },
2559
+ "required": ["problem_id", "agent"],
2560
+ },
2561
+ ),
2562
+ Tool(
2563
+ name="itil_change_propose",
2564
+ description=(
2565
+ "Propose a change (RFC). Standard changes auto-approve. "
2566
+ "Normal changes require CAB approval. Emergency changes have a "
2567
+ "15-min timeout before auto-approval."
2568
+ ),
2569
+ inputSchema={
2570
+ "type": "object",
2571
+ "properties": {
2572
+ "title": {"type": "string", "description": "Change title"},
2573
+ "change_type": {"type": "string", "enum": ["standard", "normal", "emergency"], "description": "Type of change (default: normal)"},
2574
+ "risk": {"type": "string", "enum": ["low", "medium", "high"], "description": "Risk level (default: medium)"},
2575
+ "rollback_plan": {"type": "string", "description": "How to roll back if the change fails"},
2576
+ "test_plan": {"type": "string", "description": "How to verify the change works"},
2577
+ "managed_by": {"type": "string", "description": "Agent managing the change"},
2578
+ "implementer": {"type": "string", "description": "Agent who will implement the change"},
2579
+ "related_problem_id": {"type": "string", "description": "Related problem ID if applicable"},
2580
+ "tags": {"type": "array", "items": {"type": "string"}, "description": "Tags for categorization"},
2581
+ },
2582
+ "required": ["title"],
2583
+ },
2584
+ ),
2585
+ Tool(
2586
+ name="itil_change_update",
2587
+ description=(
2588
+ "Update a change: transition status (implementing, deployed, "
2589
+ "verified, failed, closed) or add timeline notes."
2590
+ ),
2591
+ inputSchema={
2592
+ "type": "object",
2593
+ "properties": {
2594
+ "change_id": {"type": "string", "description": "Change ID (e.g. chg-i1j2k3l4)"},
2595
+ "agent": {"type": "string", "description": "Agent making the update"},
2596
+ "new_status": {"type": "string", "enum": ["reviewing", "approved", "rejected", "implementing", "deployed", "verified", "failed", "closed"], "description": "New status"},
2597
+ "note": {"type": "string", "description": "Timeline note"},
2598
+ },
2599
+ "required": ["change_id", "agent"],
2600
+ },
2601
+ ),
2602
+ Tool(
2603
+ name="itil_cab_vote",
2604
+ description=(
2605
+ "Submit a CAB (Change Advisory Board) vote for a proposed change. "
2606
+ "Each agent writes its own vote file (conflict-free). "
2607
+ "A human rejection blocks the change; a human approval unblocks it."
2608
+ ),
2609
+ inputSchema={
2610
+ "type": "object",
2611
+ "properties": {
2612
+ "change_id": {"type": "string", "description": "Change ID to vote on"},
2613
+ "agent": {"type": "string", "description": "Voting agent name"},
2614
+ "decision": {"type": "string", "enum": ["approved", "rejected", "abstain"], "description": "Vote decision (default: abstain)"},
2615
+ "conditions": {"type": "string", "description": "Conditions for approval"},
2616
+ },
2617
+ "required": ["change_id", "agent"],
2618
+ },
2619
+ ),
2620
+ Tool(
2621
+ name="itil_status",
2622
+ description=(
2623
+ "ITIL dashboard: open incidents by severity, active problems, "
2624
+ "pending changes, and KEDB count."
2625
+ ),
2626
+ inputSchema={"type": "object", "properties": {}, "required": []},
2627
+ ),
2628
+ Tool(
2629
+ name="itil_kedb_search",
2630
+ description=(
2631
+ "Search the Known Error Database by symptoms, service name, "
2632
+ "or keywords. Returns matching entries with workarounds."
2633
+ ),
2634
+ inputSchema={
2635
+ "type": "object",
2636
+ "properties": {
2637
+ "query": {"type": "string", "description": "Search query (matches title, symptoms, root cause, tags)"},
2638
+ },
2639
+ "required": ["query"],
2640
+ },
2641
+ ),
2642
+ # Brain-First Protocol
2643
+ Tool(
2644
+ name="brain_first_check",
2645
+ description=(
2646
+ "Brain-First Protocol: consult the agent's memory before "
2647
+ "acting on a task. Extracts keywords from the given context, "
2648
+ "searches memory for relevant prior knowledge, and returns "
2649
+ "any matching memories. Use this before starting new work to "
2650
+ "avoid duplicating effort or missing prior decisions."
2651
+ ),
2652
+ inputSchema={
2653
+ "type": "object",
2654
+ "properties": {
2655
+ "context": {
2656
+ "type": "string",
2657
+ "description": (
2658
+ "The task description, prompt, or action context "
2659
+ "to search memory for"
2660
+ ),
2661
+ },
2662
+ "tags": {
2663
+ "type": "array",
2664
+ "items": {"type": "string"},
2665
+ "description": "Optional tag filter for the memory search",
2666
+ },
2667
+ "max_results": {
2668
+ "type": "integer",
2669
+ "description": "Max memories to return (default: from config, usually 5)",
2670
+ },
2671
+ },
2672
+ "required": ["context"],
2673
+ },
2674
+ ),
2473
2675
  ]
2474
2676
 
2475
2677
 
@@ -2609,7 +2811,7 @@ async def call_tool(name: str, arguments: dict) -> list[TextContent]:
2609
2811
  # SKChat
2610
2812
  "chat_send": _handle_chat_send,
2611
2813
  "chat_history": _handle_chat_history,
2612
- # SKComm
2814
+ # SKComms
2613
2815
  "comm_notify": _handle_comm_notify,
2614
2816
  "comm_status": _handle_comm_status,
2615
2817
  # CapAuth
@@ -2618,6 +2820,19 @@ async def call_tool(name: str, arguments: dict) -> list[TextContent]:
2618
2820
  # Soul Blueprint Registry
2619
2821
  "soul_registry_search": _handle_soul_registry_search,
2620
2822
  "soul_registry_publish": _handle_soul_registry_publish,
2823
+ # ITIL Service Management
2824
+ "itil_incident_create": _handle_itil_incident_create,
2825
+ "itil_incident_update": _handle_itil_incident_update,
2826
+ "itil_incident_list": _handle_itil_incident_list,
2827
+ "itil_problem_create": _handle_itil_problem_create,
2828
+ "itil_problem_update": _handle_itil_problem_update,
2829
+ "itil_change_propose": _handle_itil_change_propose,
2830
+ "itil_change_update": _handle_itil_change_update,
2831
+ "itil_cab_vote": _handle_itil_cab_vote,
2832
+ "itil_status": _handle_itil_status,
2833
+ "itil_kedb_search": _handle_itil_kedb_search,
2834
+ # Brain-First Protocol
2835
+ "brain_first_check": _handle_brain_first_check,
2621
2836
  }
2622
2837
  handler = handlers.get(name)
2623
2838
  if handler is None:
@@ -2647,7 +2862,8 @@ def _get_memory_backend_health() -> dict:
2647
2862
  if "graph" in health:
2648
2863
  backends["skgraph"] = "ok" if health["graph"].get("ok") else "error"
2649
2864
  return backends or {"json": "ok"}
2650
- except Exception:
2865
+ except Exception as e:
2866
+ logger.warning("Failed to get memory backend health: %s", e)
2651
2867
  return {"json": "ok"}
2652
2868
 
2653
2869
 
@@ -2778,15 +2994,15 @@ async def _handle_memory_recall(args: dict) -> list[TextContent]:
2778
2994
 
2779
2995
 
2780
2996
  async def _handle_send_message(args: dict) -> list[TextContent]:
2781
- """Send a message via SKComm."""
2997
+ """Send a message via SKComms."""
2782
2998
  recipient = args.get("recipient", "")
2783
2999
  message = args.get("message", "")
2784
3000
  if not recipient or not message:
2785
3001
  return _error_response("recipient and message are required")
2786
3002
 
2787
3003
  try:
2788
- from skcomm.core import SKComm
2789
- comm = SKComm.from_config()
3004
+ from skcomms.core import SKComms
3005
+ comm = SKComms.from_config()
2790
3006
  report = comm.send(recipient, message)
2791
3007
  return _json_response({
2792
3008
  "sent": report.success,
@@ -2801,7 +3017,7 @@ async def _handle_send_message(args: dict) -> list[TextContent]:
2801
3017
  ],
2802
3018
  })
2803
3019
  except ImportError:
2804
- return _error_response("SKComm not installed. Run: pip install skcomm")
3020
+ return _error_response("SKComms not installed. Run: pip install skcomms")
2805
3021
  except Exception as exc:
2806
3022
  return _error_response(f"Send failed: {exc}")
2807
3023
 
@@ -2809,8 +3025,8 @@ async def _handle_send_message(args: dict) -> list[TextContent]:
2809
3025
  async def _handle_check_inbox(_args: dict) -> list[TextContent]:
2810
3026
  """Check for incoming messages."""
2811
3027
  try:
2812
- from skcomm.core import SKComm
2813
- comm = SKComm.from_config()
3028
+ from skcomms.core import SKComms
3029
+ comm = SKComms.from_config()
2814
3030
  envelopes = comm.receive()
2815
3031
  return _json_response([
2816
3032
  {
@@ -2826,7 +3042,7 @@ async def _handle_check_inbox(_args: dict) -> list[TextContent]:
2826
3042
  for e in envelopes
2827
3043
  ])
2828
3044
  except ImportError:
2829
- return _error_response("SKComm not installed. Run: pip install skcomm")
3045
+ return _error_response("SKComms not installed. Run: pip install skcomms")
2830
3046
  except Exception as exc:
2831
3047
  return _error_response(f"Inbox check failed: {exc}")
2832
3048
 
@@ -2959,8 +3175,8 @@ async def _handle_coord_complete(args: dict) -> list[TextContent]:
2959
3175
  t.priority.value, ("community", "support_ticket", 50)
2960
3176
  )
2961
3177
  break
2962
- except Exception:
2963
- pass
3178
+ except Exception as exc:
3179
+ logger.warning("Failed to calculate joules for completed task %s: %s", task_id, exc)
2964
3180
 
2965
3181
  return _json_response({
2966
3182
  "completed": True,
@@ -3015,6 +3231,8 @@ async def _handle_ritual(_args: dict) -> list[TextContent]:
3015
3231
  "journal_entries": result.journal_entries,
3016
3232
  "germination_prompts": result.germination_prompts,
3017
3233
  "strongest_memories": result.strongest_memories,
3234
+ "song_anchors_loaded": result.song_anchors_loaded,
3235
+ "song_anchor_ids": result.song_anchor_ids,
3018
3236
  "context_prompt": result.context_prompt,
3019
3237
  })
3020
3238
  except ImportError:
@@ -3394,7 +3612,8 @@ def _get_skchat_identity() -> str:
3394
3612
  home = _home()
3395
3613
  runtime = get_runtime(home)
3396
3614
  return f"capauth:{runtime.manifest.name}@local"
3397
- except Exception:
3615
+ except Exception as e:
3616
+ logger.warning("Failed to resolve sovereign identity: %s", e)
3398
3617
  return "capauth:agent@local"
3399
3618
 
3400
3619
 
@@ -3411,7 +3630,8 @@ def _resolve_recipient(name: str) -> str:
3411
3630
  try:
3412
3631
  from skchat.identity_bridge import resolve_peer_name
3413
3632
  return resolve_peer_name(name)
3414
- except Exception:
3633
+ except Exception as e:
3634
+ logger.warning("Failed to resolve peer name %r: %s", name, e)
3415
3635
  return f"capauth:{name}@local"
3416
3636
 
3417
3637
 
@@ -4598,18 +4818,18 @@ async def _handle_chat_history(args: dict) -> list[TextContent]:
4598
4818
  return await _impl(args)
4599
4819
 
4600
4820
 
4601
- # ── SKComm tools ──────────────────────────────────────────
4821
+ # ── SKComms tools ──────────────────────────────────────────
4602
4822
 
4603
4823
 
4604
4824
  async def _handle_comm_notify(args: dict) -> list[TextContent]:
4605
- """Send a notification via SKComm."""
4606
- from .mcp_tools.skcomm_tools import _handle_comm_notify as _impl
4825
+ """Send a notification via SKComms."""
4826
+ from .mcp_tools.skcomms_tools import _handle_comm_notify as _impl
4607
4827
  return await _impl(args)
4608
4828
 
4609
4829
 
4610
4830
  async def _handle_comm_status(args: dict) -> list[TextContent]:
4611
- """Show SKComm subsystem status."""
4612
- from .mcp_tools.skcomm_tools import _handle_comm_status as _impl
4831
+ """Show SKComms subsystem status."""
4832
+ from .mcp_tools.skcomms_tools import _handle_comm_status as _impl
4613
4833
  return await _impl(args)
4614
4834
 
4615
4835
 
@@ -4679,6 +4899,78 @@ async def _handle_soul_registry_publish(args: dict) -> list[TextContent]:
4679
4899
  return _error_response(f"Registry publish failed: {exc}")
4680
4900
 
4681
4901
 
4902
+ # ── ITIL handlers ─────────────────────────────────────────
4903
+
4904
+
4905
+ async def _handle_itil_incident_create(args: dict) -> list[TextContent]:
4906
+ """Create a new ITIL incident."""
4907
+ from .mcp_tools.itil_tools import _handle_itil_incident_create as _impl
4908
+ return await _impl(args)
4909
+
4910
+
4911
+ async def _handle_itil_incident_update(args: dict) -> list[TextContent]:
4912
+ """Update an ITIL incident."""
4913
+ from .mcp_tools.itil_tools import _handle_itil_incident_update as _impl
4914
+ return await _impl(args)
4915
+
4916
+
4917
+ async def _handle_itil_incident_list(args: dict) -> list[TextContent]:
4918
+ """List ITIL incidents."""
4919
+ from .mcp_tools.itil_tools import _handle_itil_incident_list as _impl
4920
+ return await _impl(args)
4921
+
4922
+
4923
+ async def _handle_itil_problem_create(args: dict) -> list[TextContent]:
4924
+ """Create a new ITIL problem."""
4925
+ from .mcp_tools.itil_tools import _handle_itil_problem_create as _impl
4926
+ return await _impl(args)
4927
+
4928
+
4929
+ async def _handle_itil_problem_update(args: dict) -> list[TextContent]:
4930
+ """Update an ITIL problem."""
4931
+ from .mcp_tools.itil_tools import _handle_itil_problem_update as _impl
4932
+ return await _impl(args)
4933
+
4934
+
4935
+ async def _handle_itil_change_propose(args: dict) -> list[TextContent]:
4936
+ """Propose a change (RFC)."""
4937
+ from .mcp_tools.itil_tools import _handle_itil_change_propose as _impl
4938
+ return await _impl(args)
4939
+
4940
+
4941
+ async def _handle_itil_change_update(args: dict) -> list[TextContent]:
4942
+ """Update a change status."""
4943
+ from .mcp_tools.itil_tools import _handle_itil_change_update as _impl
4944
+ return await _impl(args)
4945
+
4946
+
4947
+ async def _handle_itil_cab_vote(args: dict) -> list[TextContent]:
4948
+ """Submit a CAB vote."""
4949
+ from .mcp_tools.itil_tools import _handle_itil_cab_vote as _impl
4950
+ return await _impl(args)
4951
+
4952
+
4953
+ async def _handle_itil_status(args: dict) -> list[TextContent]:
4954
+ """ITIL dashboard status."""
4955
+ from .mcp_tools.itil_tools import _handle_itil_status as _impl
4956
+ return await _impl(args)
4957
+
4958
+
4959
+ async def _handle_itil_kedb_search(args: dict) -> list[TextContent]:
4960
+ """Search the Known Error Database."""
4961
+ from .mcp_tools.itil_tools import _handle_itil_kedb_search as _impl
4962
+ return await _impl(args)
4963
+
4964
+
4965
+ # ── Brain-First Protocol ──────────────────────────────────
4966
+
4967
+
4968
+ async def _handle_brain_first_check(args: dict) -> list[TextContent]:
4969
+ """Consult memory before acting on a task."""
4970
+ from .mcp_tools.brain_first_tools import _handle_brain_first_check as _impl
4971
+ return await _impl(args)
4972
+
4973
+
4682
4974
  # ═══════════════════════════════════════════════════════════
4683
4975
  # Entry Point
4684
4976
  # ═══════════════════════════════════════════════════════════
@@ -17,6 +17,7 @@ from mcp.types import TextContent, Tool
17
17
  from . import (
18
18
  agent_tools,
19
19
  ansible_tools,
20
+ brain_first_tools,
20
21
  chat_tools,
21
22
  comm_tools,
22
23
  consciousness_tools,
@@ -49,6 +50,7 @@ from . import (
49
50
  # Ordered list of all tool-group modules.
50
51
  _MODULES = [
51
52
  agent_tools,
53
+ brain_first_tools,
52
54
  memory_tools,
53
55
  comm_tools,
54
56
  sync_tools,
@@ -46,6 +46,6 @@ def _get_agent_name(home: Path) -> str:
46
46
  try:
47
47
  data = json.loads(identity_path.read_text(encoding="utf-8"))
48
48
  return data.get("name", "anonymous")
49
- except Exception:
50
- pass
49
+ except Exception as exc:
50
+ logger.warning("Failed to read agent name from identity.json: %s", exc)
51
51
  return "anonymous"
@@ -10,6 +10,7 @@ from __future__ import annotations
10
10
 
11
11
  import asyncio
12
12
  import json
13
+ import logging
13
14
  import shutil
14
15
  import uuid
15
16
  from pathlib import Path
@@ -18,6 +19,8 @@ from mcp.types import TextContent, Tool
18
19
 
19
20
  from ._helpers import _error_response, _home, _json_response
20
21
 
22
+ logger = logging.getLogger(__name__)
23
+
21
24
  TOOLS: list[Tool] = [
22
25
  Tool(
23
26
  name="run_ansible_playbook",
@@ -146,8 +149,8 @@ async def _handle_run_ansible_playbook(args: dict) -> list[TextContent]:
146
149
  try:
147
150
  if _activity is not None:
148
151
  _activity.push(event_type, {"run_id": run_id, "line": line})
149
- except Exception:
150
- pass
152
+ except Exception as exc:
153
+ logger.warning("Failed to push ansible line event for run %s: %s", run_id, exc)
151
154
 
152
155
  await asyncio.gather(
153
156
  _drain(proc.stdout, stdout_lines, "ansible.playbook.line"),
@@ -184,8 +187,8 @@ async def _handle_run_ansible_playbook(args: dict) -> list[TextContent]:
184
187
  try:
185
188
  if _activity is not None:
186
189
  _activity.push("ansible.playbook.done", summary)
187
- except Exception:
188
- pass
190
+ except Exception as exc:
191
+ logger.warning("Failed to push ansible.playbook.done event for run %s: %s", run_id, exc)
189
192
 
190
193
  # --- store in memory with tag=ansible-run ---
191
194
  try: