@senpi/runtime 3.0.6-dev.skill-manager-v2.20260629194505 → 3.0.9-dev.runtime-phase-2.20260707070820

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 (458) hide show
  1. package/dist/actions/action-events.d.ts +67 -0
  2. package/dist/actions/action-events.d.ts.map +1 -0
  3. package/dist/actions/action-events.js +164 -0
  4. package/dist/actions/action-events.js.map +1 -0
  5. package/dist/actions/close-position/close-position.action.d.ts +1 -1
  6. package/dist/actions/close-position/close-position.action.d.ts.map +1 -1
  7. package/dist/actions/close-position/close-position.action.js +108 -86
  8. package/dist/actions/close-position/close-position.action.js.map +1 -1
  9. package/dist/actions/decision-engine.d.ts.map +1 -1
  10. package/dist/actions/decision-engine.js +40 -28
  11. package/dist/actions/decision-engine.js.map +1 -1
  12. package/dist/actions/event-derivation.d.ts +61 -0
  13. package/dist/actions/event-derivation.d.ts.map +1 -0
  14. package/dist/actions/event-derivation.js +180 -0
  15. package/dist/actions/event-derivation.js.map +1 -0
  16. package/dist/actions/llm-decision/anthropic-llm-decision.d.ts +5 -9
  17. package/dist/actions/llm-decision/anthropic-llm-decision.d.ts.map +1 -1
  18. package/dist/actions/llm-decision/anthropic-llm-decision.js +6 -87
  19. package/dist/actions/llm-decision/anthropic-llm-decision.js.map +1 -1
  20. package/dist/actions/llm-decision/factory.d.ts +0 -6
  21. package/dist/actions/llm-decision/factory.d.ts.map +1 -1
  22. package/dist/actions/llm-decision/factory.js +0 -2
  23. package/dist/actions/llm-decision/factory.js.map +1 -1
  24. package/dist/actions/llm-decision/openclaw-llm-decision.d.ts.map +1 -1
  25. package/dist/actions/llm-decision/openclaw-llm-decision.js +26 -7
  26. package/dist/actions/llm-decision/openclaw-llm-decision.js.map +1 -1
  27. package/dist/actions/open-position/open-position.action.d.ts +1 -1
  28. package/dist/actions/open-position/open-position.action.d.ts.map +1 -1
  29. package/dist/actions/open-position/open-position.action.js +282 -224
  30. package/dist/actions/open-position/open-position.action.js.map +1 -1
  31. package/dist/actions/position-tracker/position-tracker.action.d.ts.map +1 -1
  32. package/dist/actions/position-tracker/position-tracker.action.js +3 -6
  33. package/dist/actions/position-tracker/position-tracker.action.js.map +1 -1
  34. package/dist/cli/guide-commands.d.ts.map +1 -1
  35. package/dist/cli/guide-commands.js +61 -0
  36. package/dist/cli/guide-commands.js.map +1 -1
  37. package/dist/cli/senpi-commands.d.ts +14 -0
  38. package/dist/cli/senpi-commands.d.ts.map +1 -1
  39. package/dist/cli/senpi-commands.js +390 -2
  40. package/dist/cli/senpi-commands.js.map +1 -1
  41. package/dist/dsl/engine-client/event-mapping.d.ts.map +1 -1
  42. package/dist/dsl/engine-client/event-mapping.js +0 -3
  43. package/dist/dsl/engine-client/event-mapping.js.map +1 -1
  44. package/dist/dsl/events/build-closed-event.d.ts.map +1 -1
  45. package/dist/dsl/events/build-closed-event.js +0 -1
  46. package/dist/dsl/events/build-closed-event.js.map +1 -1
  47. package/dist/dsl/events/handlers.d.ts.map +1 -1
  48. package/dist/dsl/events/handlers.js +2 -4
  49. package/dist/dsl/events/handlers.js.map +1 -1
  50. package/dist/dsl/events/initial-state.d.ts.map +1 -1
  51. package/dist/dsl/events/initial-state.js +1 -0
  52. package/dist/dsl/events/initial-state.js.map +1 -1
  53. package/dist/dsl/monitor/create-monitor.d.ts +3 -0
  54. package/dist/dsl/monitor/create-monitor.d.ts.map +1 -1
  55. package/dist/dsl/monitor/create-monitor.js +76 -58
  56. package/dist/dsl/monitor/create-monitor.js.map +1 -1
  57. package/dist/dsl/monitor/dsl-failure-events.d.ts +42 -0
  58. package/dist/dsl/monitor/dsl-failure-events.d.ts.map +1 -0
  59. package/dist/dsl/monitor/dsl-failure-events.js +73 -0
  60. package/dist/dsl/monitor/dsl-failure-events.js.map +1 -0
  61. package/dist/dsl/monitor/process-one-position.d.ts +2 -1
  62. package/dist/dsl/monitor/process-one-position.d.ts.map +1 -1
  63. package/dist/dsl/monitor/process-one-position.js +130 -196
  64. package/dist/dsl/monitor/process-one-position.js.map +1 -1
  65. package/dist/dsl/plugin/index.d.ts +10 -0
  66. package/dist/dsl/plugin/index.d.ts.map +1 -1
  67. package/dist/dsl/plugin/index.js +48 -4
  68. package/dist/dsl/plugin/index.js.map +1 -1
  69. package/dist/dsl/plugin/options.d.ts +3 -0
  70. package/dist/dsl/plugin/options.d.ts.map +1 -1
  71. package/dist/health/types.d.ts +14 -0
  72. package/dist/health/types.d.ts.map +1 -1
  73. package/dist/health/types.js.map +1 -1
  74. package/dist/index.d.ts +1 -0
  75. package/dist/index.d.ts.map +1 -1
  76. package/dist/index.js +255 -77
  77. package/dist/index.js.map +1 -1
  78. package/dist/risk/risk-audit-log.d.ts +7 -0
  79. package/dist/risk/risk-audit-log.d.ts.map +1 -1
  80. package/dist/risk/risk-audit-log.js +48 -1
  81. package/dist/risk/risk-audit-log.js.map +1 -1
  82. package/dist/runtime/__tests__/helpers/runtime-gateway-harness.d.ts +2 -0
  83. package/dist/runtime/__tests__/helpers/runtime-gateway-harness.d.ts.map +1 -1
  84. package/dist/runtime/__tests__/helpers/runtime-gateway-harness.js +24 -3
  85. package/dist/runtime/__tests__/helpers/runtime-gateway-harness.js.map +1 -1
  86. package/dist/runtime/auto-update/coordinator.js +2 -2
  87. package/dist/runtime/auto-update/coordinator.js.map +1 -1
  88. package/dist/runtime/create-actions.d.ts.map +1 -1
  89. package/dist/runtime/create-actions.js +40 -15
  90. package/dist/runtime/create-actions.js.map +1 -1
  91. package/dist/runtime/create-runtime-context.d.ts +1 -1
  92. package/dist/runtime/create-runtime-context.d.ts.map +1 -1
  93. package/dist/runtime/create-scanner-module.d.ts +2 -1
  94. package/dist/runtime/create-scanner-module.d.ts.map +1 -1
  95. package/dist/runtime/create-scanner-module.js +2 -1
  96. package/dist/runtime/create-scanner-module.js.map +1 -1
  97. package/dist/runtime/domain-events.d.ts +43 -0
  98. package/dist/runtime/domain-events.d.ts.map +1 -0
  99. package/dist/runtime/domain-events.js +181 -0
  100. package/dist/runtime/domain-events.js.map +1 -0
  101. package/dist/runtime/lifecycle-events.d.ts +86 -0
  102. package/dist/runtime/lifecycle-events.d.ts.map +1 -0
  103. package/dist/runtime/lifecycle-events.js +200 -0
  104. package/dist/runtime/lifecycle-events.js.map +1 -0
  105. package/dist/runtime/notifications.js +2 -2
  106. package/dist/runtime/notifications.js.map +1 -1
  107. package/dist/{tracking → runtime}/position-id-registry.d.ts +14 -1
  108. package/dist/runtime/position-id-registry.d.ts.map +1 -0
  109. package/dist/{tracking → runtime}/position-id-registry.js +20 -3
  110. package/dist/runtime/position-id-registry.js.map +1 -0
  111. package/dist/runtime/run.d.ts +2 -4
  112. package/dist/runtime/run.d.ts.map +1 -1
  113. package/dist/runtime/run.js.map +1 -1
  114. package/dist/runtime/runtime-schema.d.ts +276 -588
  115. package/dist/runtime/runtime-schema.d.ts.map +1 -1
  116. package/dist/runtime/runtime-schema.js +8 -28
  117. package/dist/runtime/runtime-schema.js.map +1 -1
  118. package/dist/runtime/runtime.d.ts +23 -9
  119. package/dist/runtime/runtime.d.ts.map +1 -1
  120. package/dist/runtime/runtime.js +276 -248
  121. package/dist/runtime/runtime.js.map +1 -1
  122. package/dist/runtime/strategy-lifecycle.d.ts.map +1 -1
  123. package/dist/runtime/strategy-lifecycle.js +13 -1
  124. package/dist/runtime/strategy-lifecycle.js.map +1 -1
  125. package/dist/runtime/supervisor/long-running-supervisor.d.ts +3 -0
  126. package/dist/runtime/supervisor/long-running-supervisor.d.ts.map +1 -1
  127. package/dist/runtime/supervisor/long-running-supervisor.js +27 -53
  128. package/dist/runtime/supervisor/long-running-supervisor.js.map +1 -1
  129. package/dist/runtime-api/intake/intake-events.d.ts +44 -0
  130. package/dist/runtime-api/intake/intake-events.d.ts.map +1 -0
  131. package/dist/runtime-api/intake/intake-events.js +131 -0
  132. package/dist/runtime-api/intake/intake-events.js.map +1 -0
  133. package/dist/runtime-api/intake/scanner-launcher.d.ts +2 -0
  134. package/dist/runtime-api/intake/scanner-launcher.d.ts.map +1 -1
  135. package/dist/runtime-api/intake/scanner-launcher.js +58 -15
  136. package/dist/runtime-api/intake/scanner-launcher.js.map +1 -1
  137. package/dist/runtime-api/intake/scanner-registry.d.ts +3 -0
  138. package/dist/runtime-api/intake/scanner-registry.d.ts.map +1 -1
  139. package/dist/runtime-api/intake/scanner-registry.js +3 -0
  140. package/dist/runtime-api/intake/scanner-registry.js.map +1 -1
  141. package/dist/runtime-api/intake/supervisor-events.d.ts +61 -0
  142. package/dist/runtime-api/intake/supervisor-events.d.ts.map +1 -0
  143. package/dist/runtime-api/intake/supervisor-events.js +173 -0
  144. package/dist/runtime-api/intake/supervisor-events.js.map +1 -0
  145. package/dist/runtime-api/routes/signals.d.ts +1 -1
  146. package/dist/runtime-api/routes/signals.d.ts.map +1 -1
  147. package/dist/runtime-api/routes/signals.js +121 -35
  148. package/dist/runtime-api/routes/signals.js.map +1 -1
  149. package/dist/runtime-api/server.d.ts.map +1 -1
  150. package/dist/runtime-api/server.js +10 -1
  151. package/dist/runtime-api/server.js.map +1 -1
  152. package/dist/scanners/engine/data-providers.d.ts +3 -0
  153. package/dist/scanners/engine/data-providers.d.ts.map +1 -1
  154. package/dist/scanners/engine/data-providers.js.map +1 -1
  155. package/dist/scanners/engine/engine.d.ts +18 -0
  156. package/dist/scanners/engine/engine.d.ts.map +1 -1
  157. package/dist/scanners/engine/engine.js +96 -2
  158. package/dist/scanners/engine/engine.js.map +1 -1
  159. package/dist/scanners/engine/input-resolver.d.ts.map +1 -1
  160. package/dist/scanners/engine/input-resolver.js +9 -7
  161. package/dist/scanners/engine/input-resolver.js.map +1 -1
  162. package/dist/scanners/runtime-module.d.ts +3 -0
  163. package/dist/scanners/runtime-module.d.ts.map +1 -1
  164. package/dist/scanners/runtime-module.js +7 -0
  165. package/dist/scanners/runtime-module.js.map +1 -1
  166. package/dist/senpi/client.d.ts +10 -0
  167. package/dist/senpi/client.d.ts.map +1 -1
  168. package/dist/senpi/client.js +113 -46
  169. package/dist/senpi/client.js.map +1 -1
  170. package/dist/skills-manager/bootstrap.d.ts.map +1 -1
  171. package/dist/skills-manager/bootstrap.js +22 -33
  172. package/dist/skills-manager/bootstrap.js.map +1 -1
  173. package/dist/skills-manager/clone-groups.d.ts +20 -0
  174. package/dist/skills-manager/clone-groups.d.ts.map +1 -0
  175. package/dist/skills-manager/clone-groups.js +45 -0
  176. package/dist/skills-manager/clone-groups.js.map +1 -0
  177. package/dist/skills-manager/coordinator.d.ts.map +1 -1
  178. package/dist/skills-manager/coordinator.js +111 -75
  179. package/dist/skills-manager/coordinator.js.map +1 -1
  180. package/dist/skills-manager/manifest.d.ts +24 -0
  181. package/dist/skills-manager/manifest.d.ts.map +1 -1
  182. package/dist/skills-manager/manifest.js +23 -10
  183. package/dist/skills-manager/manifest.js.map +1 -1
  184. package/dist/skills-manager/skills-manifest.json +12 -7
  185. package/dist/skills-manager/types.d.ts +12 -0
  186. package/dist/skills-manager/types.d.ts.map +1 -1
  187. package/dist/state/state-events.d.ts +13 -0
  188. package/dist/state/state-events.d.ts.map +1 -0
  189. package/dist/state/state-events.js +22 -0
  190. package/dist/state/state-events.js.map +1 -0
  191. package/dist/state/state-manager.d.ts.map +1 -1
  192. package/dist/state/state-manager.js +14 -1
  193. package/dist/state/state-manager.js.map +1 -1
  194. package/dist/telemetry/attributes.d.ts +13 -0
  195. package/dist/telemetry/attributes.d.ts.map +1 -0
  196. package/dist/telemetry/attributes.js +22 -0
  197. package/dist/telemetry/attributes.js.map +1 -0
  198. package/dist/{tracking → telemetry}/context.d.ts +12 -5
  199. package/dist/telemetry/context.d.ts.map +1 -0
  200. package/dist/{tracking → telemetry}/context.js +4 -4
  201. package/dist/telemetry/context.js.map +1 -0
  202. package/dist/{recording/records.d.ts → telemetry/event-builders.d.ts} +145 -33
  203. package/dist/telemetry/event-builders.d.ts.map +1 -0
  204. package/dist/{recording/wiring/record-builders.js → telemetry/event-builders.js} +94 -40
  205. package/dist/telemetry/event-builders.js.map +1 -0
  206. package/dist/telemetry/event-store.d.ts +66 -0
  207. package/dist/telemetry/event-store.d.ts.map +1 -0
  208. package/dist/telemetry/event-store.js +202 -0
  209. package/dist/telemetry/event-store.js.map +1 -0
  210. package/dist/telemetry/identity.d.ts +72 -0
  211. package/dist/telemetry/identity.d.ts.map +1 -0
  212. package/dist/{recording/wiring → telemetry}/identity.js +6 -2
  213. package/dist/telemetry/identity.js.map +1 -0
  214. package/dist/telemetry/metrics.d.ts +169 -0
  215. package/dist/telemetry/metrics.d.ts.map +1 -0
  216. package/dist/telemetry/metrics.js +437 -0
  217. package/dist/telemetry/metrics.js.map +1 -0
  218. package/dist/telemetry/otel-sdk.d.ts +93 -0
  219. package/dist/telemetry/otel-sdk.d.ts.map +1 -0
  220. package/dist/telemetry/otel-sdk.js +297 -0
  221. package/dist/telemetry/otel-sdk.js.map +1 -0
  222. package/dist/telemetry/spans/constants.d.ts +12 -0
  223. package/dist/telemetry/spans/constants.d.ts.map +1 -0
  224. package/dist/telemetry/spans/constants.js +12 -0
  225. package/dist/telemetry/spans/constants.js.map +1 -0
  226. package/dist/telemetry/spans/gen-ai.d.ts +74 -0
  227. package/dist/telemetry/spans/gen-ai.d.ts.map +1 -0
  228. package/dist/telemetry/spans/gen-ai.js +339 -0
  229. package/dist/telemetry/spans/gen-ai.js.map +1 -0
  230. package/dist/telemetry/spans/index.d.ts +11 -0
  231. package/dist/telemetry/spans/index.d.ts.map +1 -0
  232. package/dist/telemetry/spans/index.js +11 -0
  233. package/dist/telemetry/spans/index.js.map +1 -0
  234. package/dist/{tracking → telemetry}/spans/redact-pii.d.ts +19 -21
  235. package/dist/telemetry/spans/redact-pii.d.ts.map +1 -0
  236. package/dist/{tracking → telemetry}/spans/redact-pii.js +35 -32
  237. package/dist/telemetry/spans/redact-pii.js.map +1 -0
  238. package/dist/telemetry/spans/sanitize-payload.d.ts.map +1 -0
  239. package/dist/telemetry/spans/sanitize-payload.js.map +1 -0
  240. package/dist/telemetry/spans/span-hooks.d.ts +18 -0
  241. package/dist/telemetry/spans/span-hooks.d.ts.map +1 -0
  242. package/dist/telemetry/spans/span-hooks.js +764 -0
  243. package/dist/telemetry/spans/span-hooks.js.map +1 -0
  244. package/dist/telemetry/tool-plane.d.ts +31 -0
  245. package/dist/telemetry/tool-plane.d.ts.map +1 -0
  246. package/dist/telemetry/tool-plane.js +70 -0
  247. package/dist/telemetry/tool-plane.js.map +1 -0
  248. package/dist/telemetry/trace-identity.d.ts +32 -0
  249. package/dist/telemetry/trace-identity.d.ts.map +1 -0
  250. package/dist/telemetry/trace-identity.js +62 -0
  251. package/dist/telemetry/trace-identity.js.map +1 -0
  252. package/dist/telemetry/tracing.d.ts +33 -0
  253. package/dist/telemetry/tracing.d.ts.map +1 -0
  254. package/dist/telemetry/tracing.js +70 -0
  255. package/dist/telemetry/tracing.js.map +1 -0
  256. package/dist/types/dsl/index.d.ts +8 -9
  257. package/dist/types/dsl/index.d.ts.map +1 -1
  258. package/dist/types/runtime.d.ts +1 -1
  259. package/dist/types/runtime.d.ts.map +1 -1
  260. package/dist/types/scanner.d.ts +2 -0
  261. package/dist/types/scanner.d.ts.map +1 -1
  262. package/dist/utils/event-catalog.d.ts +506 -0
  263. package/dist/utils/event-catalog.d.ts.map +1 -0
  264. package/dist/utils/event-catalog.js +142 -0
  265. package/dist/utils/event-catalog.js.map +1 -0
  266. package/dist/utils/logger.d.ts +63 -5
  267. package/dist/utils/logger.d.ts.map +1 -1
  268. package/dist/utils/logger.js +360 -27
  269. package/dist/utils/logger.js.map +1 -1
  270. package/dist/utils/wallet-address.d.ts +3 -0
  271. package/dist/utils/wallet-address.d.ts.map +1 -0
  272. package/dist/utils/wallet-address.js +17 -0
  273. package/dist/utils/wallet-address.js.map +1 -0
  274. package/openclaw.plugin.json +20 -6
  275. package/package.json +10 -2
  276. package/dist/actions/tracking-helpers.d.ts +0 -28
  277. package/dist/actions/tracking-helpers.d.ts.map +0 -1
  278. package/dist/actions/tracking-helpers.js +0 -93
  279. package/dist/actions/tracking-helpers.js.map +0 -1
  280. package/dist/recording/emitter.d.ts +0 -27
  281. package/dist/recording/emitter.d.ts.map +0 -1
  282. package/dist/recording/emitter.js +0 -2
  283. package/dist/recording/emitter.js.map +0 -1
  284. package/dist/recording/identity.d.ts +0 -34
  285. package/dist/recording/identity.d.ts.map +0 -1
  286. package/dist/recording/identity.js +0 -2
  287. package/dist/recording/identity.js.map +0 -1
  288. package/dist/recording/index.d.ts +0 -11
  289. package/dist/recording/index.d.ts.map +0 -1
  290. package/dist/recording/index.js +0 -2
  291. package/dist/recording/index.js.map +0 -1
  292. package/dist/recording/noop-emitter.d.ts +0 -23
  293. package/dist/recording/noop-emitter.d.ts.map +0 -1
  294. package/dist/recording/noop-emitter.js +0 -22
  295. package/dist/recording/noop-emitter.js.map +0 -1
  296. package/dist/recording/otel/attributes.d.ts +0 -35
  297. package/dist/recording/otel/attributes.d.ts.map +0 -1
  298. package/dist/recording/otel/attributes.js +0 -131
  299. package/dist/recording/otel/attributes.js.map +0 -1
  300. package/dist/recording/otel/constants.d.ts +0 -123
  301. package/dist/recording/otel/constants.d.ts.map +0 -1
  302. package/dist/recording/otel/constants.js +0 -172
  303. package/dist/recording/otel/constants.js.map +0 -1
  304. package/dist/recording/otel/ids.d.ts +0 -25
  305. package/dist/recording/otel/ids.d.ts.map +0 -1
  306. package/dist/recording/otel/ids.js +0 -37
  307. package/dist/recording/otel/ids.js.map +0 -1
  308. package/dist/recording/otel/index.d.ts +0 -13
  309. package/dist/recording/otel/index.d.ts.map +0 -1
  310. package/dist/recording/otel/index.js +0 -9
  311. package/dist/recording/otel/index.js.map +0 -1
  312. package/dist/recording/otel/mappers.d.ts +0 -100
  313. package/dist/recording/otel/mappers.d.ts.map +0 -1
  314. package/dist/recording/otel/mappers.js +0 -683
  315. package/dist/recording/otel/mappers.js.map +0 -1
  316. package/dist/recording/otel/otel-emitter.d.ts +0 -43
  317. package/dist/recording/otel/otel-emitter.d.ts.map +0 -1
  318. package/dist/recording/otel/otel-emitter.js +0 -99
  319. package/dist/recording/otel/otel-emitter.js.map +0 -1
  320. package/dist/recording/otel/redaction.d.ts +0 -47
  321. package/dist/recording/otel/redaction.d.ts.map +0 -1
  322. package/dist/recording/otel/redaction.js +0 -88
  323. package/dist/recording/otel/redaction.js.map +0 -1
  324. package/dist/recording/records.d.ts.map +0 -1
  325. package/dist/recording/records.js +0 -14
  326. package/dist/recording/records.js.map +0 -1
  327. package/dist/recording/transport/batcher.d.ts +0 -59
  328. package/dist/recording/transport/batcher.d.ts.map +0 -1
  329. package/dist/recording/transport/batcher.js +0 -234
  330. package/dist/recording/transport/batcher.js.map +0 -1
  331. package/dist/recording/transport/client.d.ts +0 -41
  332. package/dist/recording/transport/client.d.ts.map +0 -1
  333. package/dist/recording/transport/client.js +0 -69
  334. package/dist/recording/transport/client.js.map +0 -1
  335. package/dist/recording/transport/config.d.ts +0 -53
  336. package/dist/recording/transport/config.d.ts.map +0 -1
  337. package/dist/recording/transport/config.js +0 -41
  338. package/dist/recording/transport/config.js.map +0 -1
  339. package/dist/recording/transport/index.d.ts +0 -16
  340. package/dist/recording/transport/index.d.ts.map +0 -1
  341. package/dist/recording/transport/index.js +0 -12
  342. package/dist/recording/transport/index.js.map +0 -1
  343. package/dist/recording/transport/rows.d.ts +0 -88
  344. package/dist/recording/transport/rows.d.ts.map +0 -1
  345. package/dist/recording/transport/rows.js +0 -15
  346. package/dist/recording/transport/rows.js.map +0 -1
  347. package/dist/recording/wiring/emitter-factory.d.ts +0 -39
  348. package/dist/recording/wiring/emitter-factory.d.ts.map +0 -1
  349. package/dist/recording/wiring/emitter-factory.js +0 -62
  350. package/dist/recording/wiring/emitter-factory.js.map +0 -1
  351. package/dist/recording/wiring/identity.d.ts +0 -27
  352. package/dist/recording/wiring/identity.d.ts.map +0 -1
  353. package/dist/recording/wiring/identity.js.map +0 -1
  354. package/dist/recording/wiring/index.d.ts +0 -12
  355. package/dist/recording/wiring/index.d.ts.map +0 -1
  356. package/dist/recording/wiring/index.js +0 -9
  357. package/dist/recording/wiring/index.js.map +0 -1
  358. package/dist/recording/wiring/record-builders.d.ts +0 -107
  359. package/dist/recording/wiring/record-builders.d.ts.map +0 -1
  360. package/dist/recording/wiring/record-builders.js.map +0 -1
  361. package/dist/recording/wiring/subscriber.d.ts +0 -28
  362. package/dist/recording/wiring/subscriber.d.ts.map +0 -1
  363. package/dist/recording/wiring/subscriber.js +0 -173
  364. package/dist/recording/wiring/subscriber.js.map +0 -1
  365. package/dist/recording/wiring/values.d.ts +0 -19
  366. package/dist/recording/wiring/values.d.ts.map +0 -1
  367. package/dist/recording/wiring/values.js +0 -49
  368. package/dist/recording/wiring/values.js.map +0 -1
  369. package/dist/tracking/build-rehydrate-items.d.ts +0 -15
  370. package/dist/tracking/build-rehydrate-items.d.ts.map +0 -1
  371. package/dist/tracking/build-rehydrate-items.js +0 -19
  372. package/dist/tracking/build-rehydrate-items.js.map +0 -1
  373. package/dist/tracking/constants.d.ts +0 -24
  374. package/dist/tracking/constants.d.ts.map +0 -1
  375. package/dist/tracking/constants.js +0 -52
  376. package/dist/tracking/constants.js.map +0 -1
  377. package/dist/tracking/context.d.ts.map +0 -1
  378. package/dist/tracking/context.js.map +0 -1
  379. package/dist/tracking/index.d.ts +0 -16
  380. package/dist/tracking/index.d.ts.map +0 -1
  381. package/dist/tracking/index.js +0 -11
  382. package/dist/tracking/index.js.map +0 -1
  383. package/dist/tracking/plugin-event-tracker.d.ts +0 -13
  384. package/dist/tracking/plugin-event-tracker.d.ts.map +0 -1
  385. package/dist/tracking/plugin-event-tracker.js +0 -27
  386. package/dist/tracking/plugin-event-tracker.js.map +0 -1
  387. package/dist/tracking/position-id-registry.d.ts.map +0 -1
  388. package/dist/tracking/position-id-registry.js.map +0 -1
  389. package/dist/tracking/spans/constants.d.ts +0 -19
  390. package/dist/tracking/spans/constants.d.ts.map +0 -1
  391. package/dist/tracking/spans/constants.js +0 -31
  392. package/dist/tracking/spans/constants.js.map +0 -1
  393. package/dist/tracking/spans/fan-out-span-transport.d.ts +0 -22
  394. package/dist/tracking/spans/fan-out-span-transport.d.ts.map +0 -1
  395. package/dist/tracking/spans/fan-out-span-transport.js +0 -49
  396. package/dist/tracking/spans/fan-out-span-transport.js.map +0 -1
  397. package/dist/tracking/spans/index.d.ts +0 -13
  398. package/dist/tracking/spans/index.d.ts.map +0 -1
  399. package/dist/tracking/spans/index.js +0 -16
  400. package/dist/tracking/spans/index.js.map +0 -1
  401. package/dist/tracking/spans/otel/fit-row-budget.d.ts +0 -22
  402. package/dist/tracking/spans/otel/fit-row-budget.d.ts.map +0 -1
  403. package/dist/tracking/spans/otel/fit-row-budget.js +0 -91
  404. package/dist/tracking/spans/otel/fit-row-budget.js.map +0 -1
  405. package/dist/tracking/spans/otel/map-span-to-trace-row.d.ts +0 -16
  406. package/dist/tracking/spans/otel/map-span-to-trace-row.d.ts.map +0 -1
  407. package/dist/tracking/spans/otel/map-span-to-trace-row.js +0 -227
  408. package/dist/tracking/spans/otel/map-span-to-trace-row.js.map +0 -1
  409. package/dist/tracking/spans/otel/recording-span-transport.d.ts +0 -43
  410. package/dist/tracking/spans/otel/recording-span-transport.d.ts.map +0 -1
  411. package/dist/tracking/spans/otel/recording-span-transport.js +0 -67
  412. package/dist/tracking/spans/otel/recording-span-transport.js.map +0 -1
  413. package/dist/tracking/spans/otel/span-ids.d.ts +0 -22
  414. package/dist/tracking/spans/otel/span-ids.d.ts.map +0 -1
  415. package/dist/tracking/spans/otel/span-ids.js +0 -32
  416. package/dist/tracking/spans/otel/span-ids.js.map +0 -1
  417. package/dist/tracking/spans/plugin-span-tracker.d.ts +0 -9
  418. package/dist/tracking/spans/plugin-span-tracker.d.ts.map +0 -1
  419. package/dist/tracking/spans/plugin-span-tracker.js +0 -115
  420. package/dist/tracking/spans/plugin-span-tracker.js.map +0 -1
  421. package/dist/tracking/spans/redact-pii.d.ts.map +0 -1
  422. package/dist/tracking/spans/redact-pii.js.map +0 -1
  423. package/dist/tracking/spans/sanitize-payload.d.ts.map +0 -1
  424. package/dist/tracking/spans/sanitize-payload.js.map +0 -1
  425. package/dist/tracking/spans/span-hooks.d.ts +0 -28
  426. package/dist/tracking/spans/span-hooks.d.ts.map +0 -1
  427. package/dist/tracking/spans/span-hooks.js +0 -409
  428. package/dist/tracking/spans/span-hooks.js.map +0 -1
  429. package/dist/tracking/spans/span-tracker.d.ts +0 -133
  430. package/dist/tracking/spans/span-tracker.d.ts.map +0 -1
  431. package/dist/tracking/spans/span-tracker.js +0 -721
  432. package/dist/tracking/spans/span-tracker.js.map +0 -1
  433. package/dist/tracking/spans/span-transport.d.ts +0 -71
  434. package/dist/tracking/spans/span-transport.d.ts.map +0 -1
  435. package/dist/tracking/spans/span-transport.js +0 -240
  436. package/dist/tracking/spans/span-transport.js.map +0 -1
  437. package/dist/tracking/spans/types.d.ts +0 -101
  438. package/dist/tracking/spans/types.d.ts.map +0 -1
  439. package/dist/tracking/spans/types.js +0 -6
  440. package/dist/tracking/spans/types.js.map +0 -1
  441. package/dist/tracking/tracker.d.ts +0 -30
  442. package/dist/tracking/tracker.d.ts.map +0 -1
  443. package/dist/tracking/tracker.js +0 -66
  444. package/dist/tracking/tracker.js.map +0 -1
  445. package/dist/tracking/tracking-handler.d.ts +0 -12
  446. package/dist/tracking/tracking-handler.d.ts.map +0 -1
  447. package/dist/tracking/tracking-handler.js +0 -148
  448. package/dist/tracking/tracking-handler.js.map +0 -1
  449. package/dist/tracking/transport.d.ts +0 -35
  450. package/dist/tracking/transport.d.ts.map +0 -1
  451. package/dist/tracking/transport.js +0 -133
  452. package/dist/tracking/transport.js.map +0 -1
  453. package/dist/tracking/types.d.ts +0 -21
  454. package/dist/tracking/types.d.ts.map +0 -1
  455. package/dist/tracking/types.js +0 -6
  456. package/dist/tracking/types.js.map +0 -1
  457. /package/dist/{tracking → telemetry}/spans/sanitize-payload.d.ts +0 -0
  458. /package/dist/{tracking → telemetry}/spans/sanitize-payload.js +0 -0
package/dist/index.js CHANGED
@@ -11,21 +11,10 @@
11
11
  * that reason. Keeping every export in a single file (this one) avoids
12
12
  * the loader's relative-import path entirely.
13
13
  */
14
- // dd-trace init MUST be the first executable statement in this file so it
15
- // patches Node core modules (http, fs, etc.) before any traceable resource is
16
- // constructed by the imports below. Gated on DD_TRACE_ENABLED=true so unit
17
- // tests and standalone CLI invocations do not pay the init cost.
18
- // `createRequire` is used because `dd-trace` is a CJS module and our
19
- // tsconfig uses Node16 modules — a top-level `import "dd-trace"` would
20
- // be hoisted above this gate by the bundler/loader.
21
- import { createRequire } from "node:module";
22
- const __require = createRequire(import.meta.url);
23
- if (process.env.DD_TRACE_ENABLED === "true") {
24
- __require("dd-trace").init();
25
- }
26
14
  import { readFileSync } from "node:fs";
27
15
  import { join, dirname } from "node:path";
28
16
  import { SenpiClient } from "./senpi/client.js";
17
+ import { AuditQueryError } from "./runtime/audit-query.types.js";
29
18
  import { buildRuntimeStateDir, archiveStateDir } from "./runtime/state-layout.js";
30
19
  import { registerSenpiCli } from "./cli/senpi-commands.js";
31
20
  import { readSenpiCliStore, resolveSenpiApiKeyFromStore, resolveSenpiBaseStateDir, resolveTelegramChatIdFromStore, } from "./cli/senpi-cli-config.js";
@@ -39,15 +28,21 @@ import { createScannerProvidersForRun } from "./runtime/create-scanner-providers
39
28
  import { initDsl } from "./dsl/index.js";
40
29
  import { initHealth } from "./health/index.js";
41
30
  import { initRisk } from "./risk/index.js";
31
+ import { readRiskAuditEntries } from "./risk/risk-audit-log.js";
32
+ import { readEvents } from "./telemetry/event-store.js";
42
33
  import { VERSION } from "./version.js";
43
34
  import { resolvePackageName } from "./runtime/auto-update/resolve-package-name.js";
44
35
  import { runOpenClawPluginsUpdate } from "./runtime/auto-update/run-update-command.js";
45
- import { BUS_EVENT_MAP } from "./tracking/constants.js";
46
- import { createPluginEventTracker } from "./tracking/plugin-event-tracker.js";
47
- import { createPluginSpanTracker, registerSpanHooks, setDefaultSpanTracker, } from "./tracking/spans/index.js";
36
+ import { registerSpanHooks } from "./telemetry/spans/index.js";
37
+ import { initDefaultPiiRedactor } from "./telemetry/spans/redact-pii.js";
38
+ import { initOtelSdk, shutdownOtelSdk } from "./telemetry/otel-sdk.js";
48
39
  import { getLogLevel, getLogLevelSource, parseLogLevel, setErrorNotifier, setLogLevel, } from "./utils/logger.js";
49
40
  import { ExternalScannerIngestError, } from "./scanners/external-scanner-receiver.js";
50
41
  import { createLogger } from "./utils/logger.js";
42
+ import { EVENT_NAME, eventAttrs } from "./utils/event-catalog.js";
43
+ import { emitEvent } from "./actions/event-derivation.js";
44
+ import { buildRuntimeCreatedEvent, buildRuntimeDeletedEvent } from "./runtime/lifecycle-events.js";
45
+ import { isWalletAddress } from "./utils/wallet-address.js";
51
46
  import { fileURLToPath } from "node:url";
52
47
  import { loadApiConfig } from "./runtime-api/config.js";
53
48
  import { startApi } from "./runtime-api/lifecycle.js";
@@ -140,8 +135,11 @@ function formatSharedLoggerErrorNotification(payload) {
140
135
  `level: ${payload.level}`,
141
136
  `message: ${payload.message}`,
142
137
  ];
143
- if (payload.meta !== undefined) {
144
- lines.push(`meta:\n${stringifyForTelegram(payload.meta)}`);
138
+ if (payload.exception !== undefined) {
139
+ lines.push(`exception:\n${stringifyForTelegram(payload.exception)}`);
140
+ }
141
+ if (payload.attributes !== undefined) {
142
+ lines.push(`attributes:\n${stringifyForTelegram(payload.attributes)}`);
145
143
  }
146
144
  return trimTelegramMessage(lines.join("\n"));
147
145
  }
@@ -267,16 +265,27 @@ const senpiRuntimePlugin = {
267
265
  // mcpTransport = gateway-injected (no eager connect); apiKey = self-managed SenpiClient
268
266
  // (lazy connect — the R7 boot-resilience path). No secret is logged, only presence + url.
269
267
  pluginLogger.info(`[senpi-runtime] MCP transport: ${mcpTransport ? "mcpTransport (gateway-injected)" : "apiKey (self-managed SenpiClient)"}; mcpUrl=${process.env.SENPI_MCP_URL ?? "(default)"}`);
270
- const pluginEventTracker = createPluginEventTracker(apiKey ?? process.env.SENPI_AUTH_TOKEN ?? process.env.SENPI_API_KEY);
271
- // Span telemetry — one tracker per gateway, shared across all hosted runtimes
272
- // and OpenClaw hook activity. Captures llm/tool/subagent/agent_end via
273
- // OpenClaw plugin hooks; direct-SDK paths (AnthropicLlmDecision) emit
274
- // through the same tracker via factory injection.
275
- const pluginSpanTracker = createPluginSpanTracker(apiKey ?? process.env.SENPI_AUTH_TOKEN ?? process.env.SENPI_API_KEY);
276
- setDefaultSpanTracker(pluginSpanTracker);
268
+ // Register the process-wide default PII redactor at boot (always on, no env gate)
269
+ // so `logger.event()` redact fields are scrubbed on the live path. Fire-and-forget;
270
+ // see initDefaultPiiRedactor in telemetry/spans/redact-pii.ts.
271
+ initDefaultPiiRedactor();
272
+ // OTel SDK stand-up at process scope. register() must stay synchronous (the gateway
273
+ // loader doesn't await it; awaiting init would defer the registrations below), so it's
274
+ // fire-and-forget — the hooks resolve their tracer lazily at fire time, by which point
275
+ // init has run. Self-guarding; see src/telemetry/otel-sdk.ts.
276
+ void initOtelSdk({
277
+ userToken: apiKey ?? process.env.SENPI_AUTH_TOKEN ?? process.env.SENPI_API_KEY,
278
+ serviceVersion: VERSION,
279
+ }).catch((err) => {
280
+ pluginLogger.warn("[senpi-runtime] OTel SDK init failed", {
281
+ err: err instanceof Error ? err.message : String(err),
282
+ });
283
+ });
284
+ // Agent telemetry — gateway hooks emit gen_ai spans (llm/tool/subagent) through
285
+ // the shared tracer; on-site MCP calls emit their own spans from SenpiClient.
277
286
  try {
278
- registerSpanHooks({ api, tracker: pluginSpanTracker });
279
- pluginLogger.info("[senpi-runtime] span hooks registered (9 hooks)");
287
+ registerSpanHooks({ api });
288
+ pluginLogger.info("[senpi-runtime] gen_ai span hooks registered (9 hooks)");
280
289
  }
281
290
  catch (err) {
282
291
  pluginLogger.warn("[senpi-runtime] failed to register span hooks", {
@@ -323,6 +332,24 @@ const senpiRuntimePlugin = {
323
332
  // PluginLogger surface (info/warn/error) lacks `debug`, while the
324
333
  // Logger contract used by `runtime-api/` includes it.
325
334
  const apiLogger = createLogger("[senpi-core][api]");
335
+ // A gateway seam failed to wire/launch a runtime's external scanner stack: the runtime is up but
336
+ // runs blind on internal scanners only. Two records, by design: a first-class `runtime.scanners_unwired`
337
+ // event (the queryable/alertable fact, by phase) and the migrated exception-form `logger.error`
338
+ // (carries the stack + trace context, and fans the error notifier so a blind runtime still pages).
339
+ const eventScannersUnwired = (phase, runtimeId, wallet, message, error) => {
340
+ apiLogger.event(EVENT_NAME.runtimeScannersUnwired, "error", {
341
+ body: message,
342
+ attributes: eventAttrs({
343
+ "senpi.runtime.id": runtimeId,
344
+ "senpi.strategy.address": wallet ? wallet.toLowerCase() : undefined,
345
+ "senpi.scanners.launch_phase": phase,
346
+ }),
347
+ });
348
+ apiLogger.error(message, error, {
349
+ "senpi.runtime.id": runtimeId,
350
+ "senpi.scanners.launch_phase": phase,
351
+ });
352
+ };
326
353
  const lifecycleChatId = resolveTelegramChatIdFromStore(senpiCliStore);
327
354
  const lifecycleNotifications = lifecycleChatId
328
355
  ? createNotificationService({
@@ -523,8 +550,8 @@ const senpiRuntimePlugin = {
523
550
  }
524
551
  catch (mountErr) {
525
552
  // Mount failure is non-fatal: the runtime itself is already up.
526
- // Log and skip the launcher for this runtime.
527
- apiLogger.error("[senpi-runtime] scanner mount failed — runtime running without supervised scanners", { runtimeId: entry.id, err: mountErr });
553
+ // Event it and skip the launcher for this runtime.
554
+ eventScannersUnwired("mount", entry.id, entry.wallet, "[senpi-runtime] scanner mount failed — runtime running without supervised scanners", mountErr);
528
555
  }
529
556
  }
530
557
  }
@@ -603,7 +630,7 @@ const senpiRuntimePlugin = {
603
630
  catch (startErr) {
604
631
  await launcher.stop().catch(() => { });
605
632
  launchers.delete(id);
606
- apiLogger.error("[senpi-runtime] supervised scanner launch failed — runtime running without it", { err: startErr });
633
+ eventScannersUnwired("launch", id, runtimeHandles.get(id)?.wallet, "[senpi-runtime] supervised scanner launch failed — runtime running without it", startErr);
607
634
  }
608
635
  }
609
636
  }
@@ -649,13 +676,11 @@ const senpiRuntimePlugin = {
649
676
  runtimeHandles.delete(ids[i]);
650
677
  }
651
678
  pluginLogger.info("[senpi-runtime] All runtimes stopped");
652
- // Flush plugin-scoped telemetry (lifecycle.runtime.created/deleted); otherwise
653
- // BatchingTransport may still hold buffered events until the interval fires.
654
- await pluginEventTracker.shutdown().catch((err) => {
655
- pluginLogger.warn("[senpi-runtime] plugin telemetry shutdown failed", {
656
- err: err instanceof Error ? err.message : String(err),
657
- });
658
- });
679
+ // Final, process-global OTel SDK flush. Last step, after every runtime is
680
+ // stopped and all spans are emitted: we disabled HyperDX's own SIGTERM
681
+ // flush (stopOnTerminationSignals: false), so this is the only drain of the
682
+ // SDK's span/log buffers on exit.
683
+ await shutdownOtelSdk();
659
684
  },
660
685
  });
661
686
  pluginLogger.info("[senpi-runtime] calling api.registerCli(..., { commands: ['senpi'] })");
@@ -818,21 +843,6 @@ const senpiRuntimePlugin = {
818
843
  }
819
844
  registry.runtimes.push(entry);
820
845
  await writeRegistry(baseStateDir, registry);
821
- const createdMapping = BUS_EVENT_MAP["tracking.runtime_created"];
822
- pluginEventTracker.capture({
823
- eventType: createdMapping.eventType,
824
- category: createdMapping.category,
825
- address: wallet,
826
- data: {
827
- id: resolvedId,
828
- name: runtimeName,
829
- wallet,
830
- schemaVersion: parsedSchemaVersion,
831
- source: hasPath ? "file" : "inline",
832
- config: entry,
833
- timestamp: new Date().toISOString(),
834
- },
835
- });
836
846
  try {
837
847
  const scannerProviders = await createScannerProvidersForRun({
838
848
  mcpTransport,
@@ -848,6 +858,9 @@ const senpiRuntimePlugin = {
848
858
  runtimeId: resolvedId,
849
859
  });
850
860
  runtimeHandles.set(resolvedId, handle);
861
+ // Registry create fact — distinct from the runtime.started boot transition (which also fires
862
+ // on a transient restart). Emitted inside emitEvent's guard so telemetry never fails the install.
863
+ emitEvent(apiLogger, () => buildRuntimeCreatedEvent({ runtimeId: resolvedId, address: wallet, recipeName: runtimeName }));
851
864
  // ── hot-install supervised scanner wire ───────────────────────────────
852
865
  // Live-install path: used when a runtime is registered after boot via
853
866
  // senpi.installRuntime, while the API is already listening — the
@@ -888,13 +901,13 @@ const senpiRuntimePlugin = {
888
901
  }
889
902
  catch (startErr) {
890
903
  await hotLauncher.stop().catch(() => { });
891
- apiLogger.error("[senpi-runtime] hot-install supervised scanner launch failed — runtime running without it", { runtimeId: resolvedId, err: startErr });
904
+ eventScannersUnwired("install_launch", resolvedId, wallet, "[senpi-runtime] hot-install supervised scanner launch failed — runtime running without it", startErr);
892
905
  }
893
906
  }
894
907
  }
895
908
  catch (wireErr) {
896
909
  // Wire failure must NOT fail the install — the runtime is already up.
897
- apiLogger.error("[senpi-runtime] hot-install wiring failed — runtime running without supervised scanners", { runtimeId: resolvedId, err: wireErr });
910
+ eventScannersUnwired("install_wire", resolvedId, wallet, "[senpi-runtime] hot-install wiring failed — runtime running without supervised scanners", wireErr);
898
911
  }
899
912
  }
900
913
  // ──────────────────────────────────────────────────────────────────────
@@ -954,13 +967,8 @@ const senpiRuntimePlugin = {
954
967
  });
955
968
  return;
956
969
  }
957
- const targetWallet = deletedEntry?.wallet ??
958
- handle?.wallet ??
959
- (typeof targetAddress === "string" ? targetAddress : "");
960
- let openPositionsAbandoned = 0;
961
- let archivePath;
962
970
  if (handle) {
963
- openPositionsAbandoned = await handle.teardownDslForRuntimeDeletion();
971
+ await handle.teardownDslForRuntimeDeletion();
964
972
  await handle.stop();
965
973
  runtimeHandles.delete(targetId);
966
974
  }
@@ -977,32 +985,25 @@ const senpiRuntimePlugin = {
977
985
  const runtimeStateDir = buildRuntimeStateDir(baseStateDir, targetId, deletedEntry.wallet ?? "");
978
986
  const archivesDir = join(baseStateDir, "archives");
979
987
  try {
980
- archivePath = await archiveStateDir(runtimeStateDir, archivesDir, targetId, deletedEntry.wallet ?? "");
988
+ const archivePath = await archiveStateDir(runtimeStateDir, archivesDir, targetId, deletedEntry.wallet ?? "");
981
989
  api.logger.info(`[senpi-runtime] Archived state to ${archivePath}`);
982
990
  }
983
991
  catch (err) {
984
992
  api.logger.warn("[senpi-runtime] Failed to archive state dir", { err });
985
993
  }
986
994
  }
987
- const deletedMapping = BUS_EVENT_MAP["tracking.runtime_deleted"];
988
- pluginEventTracker.capture({
989
- eventType: deletedMapping.eventType,
990
- category: deletedMapping.category,
991
- address: targetWallet,
992
- data: {
993
- id: targetId,
994
- wallet: targetWallet,
995
- schemaVersion: deletedEntry?.schemaVersion,
996
- reason: "user_initiated",
997
- openPositionsAbandoned,
998
- ...(typeof archivePath === "string" ? { archivedAt: archivePath } : {}),
999
- timestamp: new Date().toISOString(),
1000
- },
1001
- });
1002
995
  if (deletedEntry) {
1003
996
  const next = registry.runtimes.filter((e) => e.id !== targetId);
1004
997
  await writeRegistry(baseStateDir, { ...registry, runtimes: next });
1005
998
  }
999
+ // Registry delete fact — the permanent-removal discriminator a transient runtime.stopped can't
1000
+ // give. Unconditional (a never-booted runtime stops no handle, so emits no runtime.stopped) and
1001
+ // inside emitEvent's guard so telemetry never fails the delete.
1002
+ emitEvent(apiLogger, () => buildRuntimeDeletedEvent({
1003
+ runtimeId: targetId,
1004
+ address: deletedEntry?.wallet,
1005
+ hadLiveHandle: Boolean(handle),
1006
+ }));
1006
1007
  respond(true, { id: targetId });
1007
1008
  }, { scope: "operator.write" });
1008
1009
  /**
@@ -1225,7 +1226,9 @@ const senpiRuntimePlugin = {
1225
1226
  try {
1226
1227
  const state = await handle.getSystemState();
1227
1228
  respond(true, {
1228
- state: state ? { ...state, runtimeId } : null,
1229
+ state: state
1230
+ ? enrichScannerLiveness({ ...state, runtimeId }, sharedIntakeContext)
1231
+ : null,
1229
1232
  updater,
1230
1233
  });
1231
1234
  }
@@ -1238,7 +1241,7 @@ const senpiRuntimePlugin = {
1238
1241
  }
1239
1242
  return;
1240
1243
  }
1241
- const states = await collectRuntimeSystemStates(runtimeHandles, api.logger, baseStateDir);
1244
+ const states = (await collectRuntimeSystemStates(runtimeHandles, api.logger, baseStateDir)).map((s) => enrichScannerLiveness(s, sharedIntakeContext));
1242
1245
  respond(true, { states, updater });
1243
1246
  }, { scope: "operator.read" });
1244
1247
  /**
@@ -1391,6 +1394,157 @@ const senpiRuntimePlugin = {
1391
1394
  });
1392
1395
  }
1393
1396
  }, { scope: "operator.read" });
1397
+ // Backend trade-audit trail (MCP tool calls + AI reasoning), already
1398
+ // reachable on HTTP `/audit`. Passes through the caller-controlled subset
1399
+ // of the audit_query contract; resource scoping (wallet → strategyId) is
1400
+ // owned by handle.auditQuery, never the caller.
1401
+ api.registerGatewayMethod("senpi.auditQuery", async (ctx) => {
1402
+ const respond = ctx.respond;
1403
+ const runtimeId = typeof ctx.params?.runtimeId === "string" ? ctx.params.runtimeId : undefined;
1404
+ if (!runtimeId) {
1405
+ respond(false, undefined, { code: "INVALID_REQUEST", message: "runtimeId is required" });
1406
+ return;
1407
+ }
1408
+ const handle = getRuntimeHandleOrRespond(runtimeHandles, runtimeId, respond);
1409
+ if (!handle) {
1410
+ return;
1411
+ }
1412
+ const p = ctx.params ?? {};
1413
+ const args = {};
1414
+ if (typeof p.tool_name === "string")
1415
+ args.tool_name = p.tool_name;
1416
+ if (p.action_type === "read" || p.action_type === "create" || p.action_type === "update" || p.action_type === "delete") {
1417
+ args.action_type = p.action_type;
1418
+ }
1419
+ if (typeof p.success === "boolean")
1420
+ args.success = p.success;
1421
+ if (typeof p.start_time === "string")
1422
+ args.start_time = p.start_time;
1423
+ if (typeof p.end_time === "string")
1424
+ args.end_time = p.end_time;
1425
+ if (typeof p.limit === "number")
1426
+ args.limit = p.limit;
1427
+ if (typeof p.offset === "number")
1428
+ args.offset = p.offset;
1429
+ try {
1430
+ const result = await handle.auditQuery(args);
1431
+ respond(true, { result, strategyId: handle.getStrategyId() });
1432
+ }
1433
+ catch (err) {
1434
+ if (err instanceof AuditQueryError) {
1435
+ respond(false, undefined, { code: err.code, message: err.message });
1436
+ return;
1437
+ }
1438
+ api.logger.warn("[senpi-runtime] auditQuery error", { runtimeId, err });
1439
+ respond(false, undefined, {
1440
+ code: "INTERNAL_ERROR",
1441
+ message: `Failed to query audit trail: ${formatGatewayError(err)}`,
1442
+ });
1443
+ }
1444
+ }, { scope: "operator.read" });
1445
+ // Per-wallet risk gate-check audit log (on-disk JSONL). The Runtime keeps
1446
+ // its state root private, so re-derive it from baseStateDir + the handle's
1447
+ // wallet (same helper the writer's stateDir was built with); the writer
1448
+ // nests entries under `<root>/<address>/risk-guard/audit.jsonl`.
1449
+ api.registerGatewayMethod("senpi.getRiskAudit", async (ctx) => {
1450
+ const respond = ctx.respond;
1451
+ const runtimeId = typeof ctx.params?.runtimeId === "string" ? ctx.params.runtimeId : undefined;
1452
+ if (!runtimeId) {
1453
+ respond(false, undefined, { code: "INVALID_REQUEST", message: "runtimeId is required" });
1454
+ return;
1455
+ }
1456
+ const handle = getRuntimeHandleOrRespond(runtimeHandles, runtimeId, respond);
1457
+ if (!handle) {
1458
+ return;
1459
+ }
1460
+ const resolvedAddress = typeof ctx.params?.address === "string" && ctx.params.address.length > 0
1461
+ ? ctx.params.address
1462
+ : handle.wallet;
1463
+ if (!resolvedAddress) {
1464
+ respond(false, undefined, {
1465
+ code: "INVALID_REQUEST",
1466
+ message: "address is required when the runtime wallet is unknown",
1467
+ });
1468
+ return;
1469
+ }
1470
+ // Path safety: the address builds the on-disk audit path; reject a non-wallet before the read.
1471
+ if (!isWalletAddress(resolvedAddress)) {
1472
+ respond(false, undefined, { code: "INVALID_REQUEST", message: "address is not a valid wallet" });
1473
+ return;
1474
+ }
1475
+ const limit = typeof ctx.params?.limit === "number" && ctx.params.limit > 0 ? ctx.params.limit : 100;
1476
+ const stateDir = buildRuntimeStateDir(baseStateDir, runtimeId, handle.wallet ?? "");
1477
+ try {
1478
+ const entries = await readRiskAuditEntries(stateDir, resolvedAddress, limit);
1479
+ respond(true, { entries, address: resolvedAddress });
1480
+ }
1481
+ catch (err) {
1482
+ api.logger.warn("[senpi-runtime] getRiskAudit error", { runtimeId, err });
1483
+ respond(false, undefined, {
1484
+ code: "INTERNAL_ERROR",
1485
+ message: `Failed to read risk audit: ${formatGatewayError(err)}`,
1486
+ });
1487
+ }
1488
+ }, { scope: "operator.read" });
1489
+ // Per-strategy local domain-event ring (on-disk JSONL) — the trade narrative, queryable locally.
1490
+ // Same state-root re-derivation as getRiskAudit: the Runtime keeps its root private, so rebuild it
1491
+ // from baseStateDir + the handle's wallet; the writer nests rows under `<root>/strategies/<address>/events/`.
1492
+ api.registerGatewayMethod("senpi.getEvents", async (ctx) => {
1493
+ const respond = ctx.respond;
1494
+ const runtimeId = typeof ctx.params?.runtimeId === "string" ? ctx.params.runtimeId : undefined;
1495
+ if (!runtimeId) {
1496
+ respond(false, undefined, { code: "INVALID_REQUEST", message: "runtimeId is required" });
1497
+ return;
1498
+ }
1499
+ const handle = getRuntimeHandleOrRespond(runtimeHandles, runtimeId, respond);
1500
+ if (!handle) {
1501
+ return;
1502
+ }
1503
+ const p = ctx.params ?? {};
1504
+ const resolvedAddress = typeof p.address === "string" && p.address.length > 0 ? p.address : handle.wallet;
1505
+ if (!resolvedAddress) {
1506
+ respond(false, undefined, {
1507
+ code: "INVALID_REQUEST",
1508
+ message: "address is required when the runtime wallet is unknown",
1509
+ });
1510
+ return;
1511
+ }
1512
+ // Path safety: the address builds the on-disk events path; reject a non-wallet before the read.
1513
+ if (!isWalletAddress(resolvedAddress)) {
1514
+ respond(false, undefined, { code: "INVALID_REQUEST", message: "address is not a valid wallet" });
1515
+ return;
1516
+ }
1517
+ const query = {};
1518
+ if (typeof p.name === "string")
1519
+ query.name = p.name;
1520
+ if (typeof p.asset === "string")
1521
+ query.asset = p.asset;
1522
+ if (p.level === "debug" || p.level === "info" || p.level === "warn" || p.level === "error") {
1523
+ query.level = p.level;
1524
+ }
1525
+ // ISO 8601 (or epoch-ms) time bounds → epoch ms; Date.parse returns NaN (not undefined) on
1526
+ // unparseable input, so Number.isFinite is the carry — no separate undefined check needed.
1527
+ const sinceMs = typeof p.since === "string" ? Date.parse(p.since) : NaN;
1528
+ if (Number.isFinite(sinceMs))
1529
+ query.sinceMs = sinceMs;
1530
+ const untilMs = typeof p.until === "string" ? Date.parse(p.until) : NaN;
1531
+ if (Number.isFinite(untilMs))
1532
+ query.untilMs = untilMs;
1533
+ if (typeof p.limit === "number" && p.limit > 0)
1534
+ query.limit = p.limit;
1535
+ const stateDir = buildRuntimeStateDir(baseStateDir, runtimeId, handle.wallet ?? "");
1536
+ try {
1537
+ const entries = await readEvents(stateDir, resolvedAddress, query);
1538
+ respond(true, { entries, address: resolvedAddress });
1539
+ }
1540
+ catch (err) {
1541
+ api.logger.warn("[senpi-runtime] getEvents error", { runtimeId, err });
1542
+ respond(false, undefined, {
1543
+ code: "INTERNAL_ERROR",
1544
+ message: `Failed to read events: ${formatGatewayError(err)}`,
1545
+ });
1546
+ }
1547
+ }, { scope: "operator.read" });
1394
1548
  // ─── Skills manager — read + mutate ──────────────────────────────────────
1395
1549
  api.registerGatewayMethod("senpi.skills.status", async (ctx) => {
1396
1550
  const respond = ctx.respond;
@@ -1505,6 +1659,30 @@ async function collectRuntimeHealthStatuses(runtimeHandles, logger) {
1505
1659
  }
1506
1660
  }))).filter((status) => status !== null);
1507
1661
  }
1662
+ /**
1663
+ * Stamps external-scanner `lastAliveAt` onto the scanners component from the shared intake
1664
+ * liveness clock. Liveness is keyed by the ephemeral scanner_id; the registry resolves it back
1665
+ * to the stable scanner name (which matches the system-state row's scannerId). Interval/internal
1666
+ * scanners never POST, so they keep the module's `null`. Mutates the freshly-built rows in place.
1667
+ */
1668
+ function enrichScannerLiveness(state, intake) {
1669
+ const rows = state.components?.scanners?.state?.scanners;
1670
+ if (!intake || !Array.isArray(rows) || rows.length === 0) {
1671
+ return state;
1672
+ }
1673
+ const liveByName = new Map();
1674
+ for (const entry of intake.registry.entries()) {
1675
+ if (entry.runtimeId === state.runtimeId) {
1676
+ liveByName.set(entry.scannerName, intake.liveness.lastAliveAt(entry.scannerId));
1677
+ }
1678
+ }
1679
+ for (const row of rows) {
1680
+ if (row.scheduleMode === "external") {
1681
+ row.lastAliveAt = liveByName.get(row.scannerId) ?? null;
1682
+ }
1683
+ }
1684
+ return state;
1685
+ }
1508
1686
  async function collectRuntimeSystemStates(runtimeHandles, logger, baseStateDir) {
1509
1687
  return (await Promise.all(Array.from(runtimeHandles, async ([runtimeId, handle]) => {
1510
1688
  try {