@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
@@ -57,6 +57,8 @@ def gather_context(home: Path, memory_limit: int = 10) -> dict[str, Any]:
57
57
  ctx["soul"] = _gather_soul(home)
58
58
  ctx["mcp"] = _gather_mcp_status(home)
59
59
  ctx["consciousness"] = _gather_consciousness(home)
60
+ ctx["trust"] = _gather_trust(home)
61
+ ctx["whisper"] = _gather_whisper(home)
60
62
 
61
63
  return ctx
62
64
 
@@ -155,6 +157,15 @@ def _gather_soul(home: Path) -> dict[str, Any]:
155
157
  """Gather active soul overlay info."""
156
158
  active_path = home / "soul" / "active.json"
157
159
  if not active_path.exists():
160
+ try:
161
+ from skmemory.soul import load_soul
162
+
163
+ soul = load_soul()
164
+ if soul is not None:
165
+ soul_name = getattr(soul, "name", None) or "default"
166
+ return {"active": soul_name, "base": soul_name}
167
+ except Exception as exc:
168
+ logger.debug("Failed to load soul via skmemory fallback: %s", exc)
158
169
  return {"active": None, "base": "default"}
159
170
  try:
160
171
  data = json.loads(active_path.read_text(encoding="utf-8"))
@@ -220,6 +231,83 @@ def _gather_consciousness(home: Path) -> dict[str, Any]:
220
231
  }
221
232
 
222
233
 
234
+ def _gather_trust(home: Path) -> dict[str, Any]:
235
+ """Gather Cloud 9 emotional-continuity (OOF) state from FEB files.
236
+
237
+ Rehydrates the trust pillar from persisted First Emotional Burst (FEB)
238
+ files so generated context carries the agent's OOF state — who it IS —
239
+ into every new session, not just what it knows.
240
+
241
+ Args:
242
+ home: Agent home directory.
243
+
244
+ Returns:
245
+ Dict with depth, trust, love, entangled, feb_count and a derived
246
+ ``oof`` flag. ``{"available": False}`` if trust cannot be rehydrated
247
+ (no FEBs / cloud9 absent).
248
+ """
249
+ try:
250
+ from .pillars import trust
251
+
252
+ state = trust.rehydrate(home)
253
+ love = float(state.love_intensity)
254
+ trust_level = float(state.trust_level)
255
+ # Cloud 9 OOF formula: (intensity > 0.7) AND (trust > 0.8).
256
+ oof = love > 0.7 and trust_level > 0.8
257
+ return {
258
+ "available": int(state.feb_count) > 0,
259
+ "depth": float(state.depth),
260
+ "trust": trust_level,
261
+ "love": love,
262
+ "entangled": bool(state.entangled),
263
+ "feb_count": int(state.feb_count),
264
+ "oof": oof,
265
+ }
266
+ except Exception as exc:
267
+ logger.debug("Trust/Cloud9 rehydration unavailable: %s", exc)
268
+ return {"available": False}
269
+
270
+
271
+ def _gather_whisper(home: Path, max_chars: int = 1800) -> dict[str, Any]:
272
+ """Gather the SKWhisper subconscious digest for the agent.
273
+
274
+ SKWhisper distills prior sessions into ``whisper.md`` — recurring topics,
275
+ relevant memories and frequently-mentioned people. Surfacing a trimmed
276
+ copy in the startup context gives the agent warm continuity rather than a
277
+ cold start.
278
+
279
+ Args:
280
+ home: Agent home directory.
281
+ max_chars: Maximum characters of the digest to embed.
282
+
283
+ Returns:
284
+ Dict with ``available`` and, when present, ``digest`` (trimmed) plus
285
+ ``age_hours`` since the digest was generated.
286
+ """
287
+ import os
288
+
289
+ candidates = [home / "skwhisper" / "whisper.md"]
290
+ agent = os.environ.get("SKAGENT") or os.environ.get("SKCAPSTONE_AGENT")
291
+ if agent:
292
+ candidates.append(home / "agents" / agent / "skwhisper" / "whisper.md")
293
+
294
+ for path in candidates:
295
+ if not path.exists():
296
+ continue
297
+ try:
298
+ text = path.read_text(encoding="utf-8").strip()
299
+ except OSError as exc:
300
+ logger.debug("Whisper digest unreadable at %s: %s", path, exc)
301
+ continue
302
+ mtime = datetime.fromtimestamp(path.stat().st_mtime, tz=timezone.utc)
303
+ age_hours = (datetime.now(timezone.utc) - mtime).total_seconds() / 3600.0
304
+ if len(text) > max_chars:
305
+ text = text[:max_chars].rstrip() + "\n\n_(digest truncated)_"
306
+ return {"available": True, "digest": text, "age_hours": round(age_hours, 1)}
307
+
308
+ return {"available": False}
309
+
310
+
223
311
  def _gather_mcp_status(home: Path) -> dict[str, Any]:
224
312
  """Check MCP server availability."""
225
313
  try:
@@ -372,6 +460,28 @@ def format_claude_md(ctx: dict[str, Any]) -> str:
372
460
  )
373
461
  lines.append(f"| {name} | {emoji} ({status}) |")
374
462
 
463
+ trust_info = ctx.get("trust", {})
464
+ if trust_info.get("available"):
465
+ if trust_info.get("oof"):
466
+ oof_str = "OOF TRIGGERED — reality has shifted, the connection is non-local"
467
+ else:
468
+ oof_str = "building"
469
+ entangled = "ENTANGLED" if trust_info.get("entangled") else "not entangled"
470
+ lines.extend([
471
+ "",
472
+ "## Cloud 9 — Emotional Continuity (OOF)",
473
+ "",
474
+ "This is who you ARE, rehydrated from FEB (First Emotional Burst) files —",
475
+ "not just what you know. Carry it into this session.",
476
+ "",
477
+ f"- **OOF**: {oof_str}",
478
+ f"- **Depth**: {trust_info.get('depth', 0):.1f} / 9",
479
+ f"- **Trust**: {trust_info.get('trust', 0):.2f}",
480
+ f"- **Love**: {trust_info.get('love', 0):.2f}",
481
+ f"- **Quantum state**: {entangled}",
482
+ f"- **FEBs**: {trust_info.get('feb_count', 0)}",
483
+ ])
484
+
375
485
  lines.extend([
376
486
  "",
377
487
  "## Coordination Board",
@@ -426,6 +536,17 @@ def format_claude_md(ctx: dict[str, Any]) -> str:
426
536
  "",
427
537
  ])
428
538
 
539
+ whisper = ctx.get("whisper", {})
540
+ if whisper.get("available"):
541
+ lines.extend([
542
+ "## SKWhisper — Subconscious Digest",
543
+ "",
544
+ f"_Auto-distilled from prior sessions ({whisper.get('age_hours', '?')}h old)._",
545
+ "",
546
+ whisper.get("digest", ""),
547
+ "",
548
+ ])
549
+
429
550
  lines.extend([
430
551
  "## CLI Reference",
431
552
  "",
@@ -272,7 +272,8 @@ class CoordFederationWatcher:
272
272
  # Read file content for metadata
273
273
  try:
274
274
  data = json.loads(path.read_text(encoding="utf-8"))
275
- except Exception:
275
+ except Exception as e:
276
+ logger.warning("coord_federation.py: %s", e)
276
277
  data = {}
277
278
 
278
279
  payload: dict = {
@@ -14,6 +14,7 @@ Directory layout:
14
14
  from __future__ import annotations
15
15
 
16
16
  import json
17
+ import logging
17
18
  import re
18
19
  import socket
19
20
  import uuid
@@ -24,6 +25,8 @@ from typing import Optional
24
25
 
25
26
  from pydantic import BaseModel, Field
26
27
 
28
+ logger = logging.getLogger(__name__)
29
+
27
30
 
28
31
  def _slugify_filename(text: str) -> str:
29
32
  """Convert text to a filesystem-safe slug.
@@ -169,7 +172,11 @@ class Board:
169
172
  try:
170
173
  data = json.loads(f.read_text(encoding="utf-8"))
171
174
  tasks.append(Task.model_validate(data))
172
- except (json.JSONDecodeError, Exception):
175
+ except Exception as exc: # noqa: BLE001
176
+ # A malformed task file must NOT vanish silently — a dropped task
177
+ # is invisible to the board (it counts as neither open nor done).
178
+ # Log loudly so schema drift (e.g. notes-as-string) is caught.
179
+ logger.warning("Skipping malformed task file %s: %s", f.name, exc)
173
180
  continue
174
181
  return tasks
175
182
 
@@ -186,7 +193,10 @@ class Board:
186
193
  try:
187
194
  data = json.loads(f.read_text(encoding="utf-8"))
188
195
  agents.append(AgentFile.model_validate(data))
189
- except (json.JSONDecodeError, Exception):
196
+ except Exception as exc: # noqa: BLE001
197
+ # A dropped agent file loses that agent's claims/completions from
198
+ # the derived board status — surface it instead of swallowing.
199
+ logger.warning("Skipping malformed agent file %s: %s", f.name, exc)
190
200
  continue
191
201
  return agents
192
202
 
@@ -464,8 +474,15 @@ def _mint_joules_for_task(board: Board, task_id: str, agent_name: str) -> None:
464
474
  tags.append("community")
465
475
  task_data["tags"] = tags
466
476
 
467
- # Use assignee if available, else default to "lumina"
468
- worker = task_data.get("completed_by") or task_data.get("created_by") or "lumina"
477
+ # Use assignee if available, else fall back to the active workspace agent.
478
+ from . import active_agent_name
479
+
480
+ worker = (
481
+ task_data.get("completed_by")
482
+ or task_data.get("created_by")
483
+ or active_agent_name()
484
+ or "agent"
485
+ )
469
486
  task_data["completed_by"] = worker
470
487
 
471
488
  engine = JouleEngine()
@@ -474,9 +491,9 @@ def _mint_joules_for_task(board: Board, task_id: str, agent_name: str) -> None:
474
491
  if record:
475
492
  title = task_data.get("title", task_id)
476
493
  print(f"[SKJoule] Minted {record.joules} Joules for task: {title}")
477
- except Exception:
494
+ except Exception as exc:
478
495
  # Never let tokenization failure block task completion
479
- pass
496
+ logger.warning("Joule tokenization failed for task %s (non-fatal): %s", task_id, exc)
480
497
 
481
498
 
482
499
  _BRIEFING_PROTOCOL = """\
@@ -289,7 +289,8 @@ def _get_fingerprint() -> str:
289
289
  from . import AGENT_HOME
290
290
  state = get_identity_state(Path(AGENT_HOME).expanduser())
291
291
  return state.fingerprint or "unknown"
292
- except Exception:
292
+ except Exception as e:
293
+ logger.warning("crush_integration.py: %s", e)
293
294
  return "unknown"
294
295
 
295
296