@vauban-org/agent-sdk 1.0.0 → 1.3.0

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 (513) hide show
  1. package/CONTRACT.md +6918 -742
  2. package/dist/adapters/llm/anthropic-direct.d.ts +1 -0
  3. package/dist/adapters/llm/anthropic-direct.d.ts.map +1 -1
  4. package/dist/adapters/llm/anthropic-direct.js +43 -0
  5. package/dist/adapters/llm/anthropic-direct.js.map +1 -1
  6. package/dist/adapters/llm/cascade.d.ts.map +1 -1
  7. package/dist/adapters/llm/cascade.js +57 -14
  8. package/dist/adapters/llm/cascade.js.map +1 -1
  9. package/dist/adapters/llm/litellm.d.ts +2 -0
  10. package/dist/adapters/llm/litellm.d.ts.map +1 -1
  11. package/dist/adapters/llm/litellm.js +44 -0
  12. package/dist/adapters/llm/litellm.js.map +1 -1
  13. package/dist/compute/difficulty-estimator.d.ts +53 -0
  14. package/dist/compute/difficulty-estimator.d.ts.map +1 -0
  15. package/dist/compute/difficulty-estimator.js +82 -0
  16. package/dist/compute/difficulty-estimator.js.map +1 -0
  17. package/dist/compute/strategies/mixture-of-agents.d.ts +40 -0
  18. package/dist/compute/strategies/mixture-of-agents.d.ts.map +1 -0
  19. package/dist/compute/strategies/mixture-of-agents.js +110 -0
  20. package/dist/compute/strategies/mixture-of-agents.js.map +1 -0
  21. package/dist/compute/strategies/tree-of-thoughts.d.ts +48 -0
  22. package/dist/compute/strategies/tree-of-thoughts.d.ts.map +1 -0
  23. package/dist/compute/strategies/tree-of-thoughts.js +242 -0
  24. package/dist/compute/strategies/tree-of-thoughts.js.map +1 -0
  25. package/dist/compute/strategies/two-phase-orient.d.ts +72 -0
  26. package/dist/compute/strategies/two-phase-orient.d.ts.map +1 -0
  27. package/dist/compute/strategies/two-phase-orient.js +85 -0
  28. package/dist/compute/strategies/two-phase-orient.js.map +1 -0
  29. package/dist/constitution/types.d.ts +10 -10
  30. package/dist/container/protocol.d.ts +134 -0
  31. package/dist/container/protocol.d.ts.map +1 -0
  32. package/dist/container/protocol.js +157 -0
  33. package/dist/container/protocol.js.map +1 -0
  34. package/dist/container/runtime.d.ts +140 -0
  35. package/dist/container/runtime.d.ts.map +1 -0
  36. package/dist/container/runtime.js +256 -0
  37. package/dist/container/runtime.js.map +1 -0
  38. package/dist/events/catalogue.d.ts +46 -46
  39. package/dist/events/schemas/agent.completed.v1.d.ts +4 -4
  40. package/dist/events/schemas/agent.failed.v1.d.ts +2 -2
  41. package/dist/events/schemas/agent.hitl_resolved.v1.d.ts +2 -2
  42. package/dist/events/schemas/agent.started.v1.d.ts +2 -2
  43. package/dist/events/schemas/brain.skill.extracted.v1.d.ts +4 -4
  44. package/dist/events/schemas/cc.cost.anomaly_detected.v1.d.ts +2 -2
  45. package/dist/events/schemas/cc.cost.recorded.v1.d.ts +4 -4
  46. package/dist/events/schemas/citadel.sprint.analyzed.v1.d.ts +6 -6
  47. package/dist/events/schemas/citadel.sprint.closed.v1.d.ts +2 -2
  48. package/dist/events/schemas/forge.inbox.reply_classified.v1.d.ts +6 -6
  49. package/dist/events/schemas/forge.lead.qualified.v1.d.ts +2 -2
  50. package/dist/events/schemas/forge.outreach.sent.v1.d.ts +4 -4
  51. package/dist/events/schemas/incident.detected.v1.d.ts +2 -2
  52. package/dist/events/schemas/vauban.goal.checked.v1.d.ts +2 -2
  53. package/dist/events/schemas/vauban.rebalancing.checked.v1.d.ts +2 -2
  54. package/dist/events/schemas/vauban.tax.checked.v1.d.ts +2 -2
  55. package/dist/events/schemas/vauban.vault.analyzed.v1.d.ts +6 -6
  56. package/dist/identity/agent-persona.d.ts +73 -0
  57. package/dist/identity/agent-persona.d.ts.map +1 -0
  58. package/dist/identity/agent-persona.js +165 -0
  59. package/dist/identity/agent-persona.js.map +1 -0
  60. package/dist/identity/persona-prompt.d.ts +25 -0
  61. package/dist/identity/persona-prompt.d.ts.map +1 -0
  62. package/dist/identity/persona-prompt.js +71 -0
  63. package/dist/identity/persona-prompt.js.map +1 -0
  64. package/dist/identity/persona-schema.d.ts +120 -0
  65. package/dist/identity/persona-schema.d.ts.map +1 -0
  66. package/dist/identity/persona-schema.js +103 -0
  67. package/dist/identity/persona-schema.js.map +1 -0
  68. package/dist/index.d.ts +41 -3
  69. package/dist/index.d.ts.map +1 -1
  70. package/dist/index.js +31 -1
  71. package/dist/index.js.map +1 -1
  72. package/dist/loop/minimal-loop.js +293 -287
  73. package/dist/memory/episodic-rrf.d.ts +114 -0
  74. package/dist/memory/episodic-rrf.d.ts.map +1 -0
  75. package/dist/memory/episodic-rrf.js +148 -0
  76. package/dist/memory/episodic-rrf.js.map +1 -0
  77. package/dist/mesh/attenuation.d.ts +78 -0
  78. package/dist/mesh/attenuation.d.ts.map +1 -0
  79. package/dist/mesh/attenuation.js +141 -0
  80. package/dist/mesh/attenuation.js.map +1 -0
  81. package/dist/mesh/delegate.d.ts +96 -0
  82. package/dist/mesh/delegate.d.ts.map +1 -0
  83. package/dist/mesh/delegate.js +172 -0
  84. package/dist/mesh/delegate.js.map +1 -0
  85. package/dist/mesh/dispatcher.d.ts +119 -0
  86. package/dist/mesh/dispatcher.d.ts.map +1 -0
  87. package/dist/mesh/dispatcher.js +207 -0
  88. package/dist/mesh/dispatcher.js.map +1 -0
  89. package/dist/mesh/index.d.ts +12 -0
  90. package/dist/mesh/index.d.ts.map +1 -0
  91. package/dist/mesh/index.js +11 -0
  92. package/dist/mesh/index.js.map +1 -0
  93. package/dist/mesh/types.d.ts +30 -0
  94. package/dist/mesh/types.d.ts.map +1 -0
  95. package/dist/mesh/types.js +11 -0
  96. package/dist/mesh/types.js.map +1 -0
  97. package/dist/orchestration/ooda/agent.d.ts.map +1 -1
  98. package/dist/orchestration/ooda/agent.js +36 -0
  99. package/dist/orchestration/ooda/agent.js.map +1 -1
  100. package/dist/orchestration/ooda/skills.d.ts +104 -0
  101. package/dist/orchestration/ooda/skills.d.ts.map +1 -1
  102. package/dist/orchestration/ooda/skills.js +106 -0
  103. package/dist/orchestration/ooda/skills.js.map +1 -1
  104. package/dist/orchestration/ooda/types.d.ts +11 -0
  105. package/dist/orchestration/ooda/types.d.ts.map +1 -1
  106. package/dist/ports/bastion-action.contract.test.d.ts +11 -0
  107. package/dist/ports/bastion-action.contract.test.d.ts.map +1 -0
  108. package/dist/ports/bastion-action.contract.test.js +238 -0
  109. package/dist/ports/bastion-action.contract.test.js.map +1 -0
  110. package/dist/ports/bastion-action.d.ts +133 -0
  111. package/dist/ports/bastion-action.d.ts.map +1 -0
  112. package/dist/ports/bastion-action.js +73 -0
  113. package/dist/ports/bastion-action.js.map +1 -0
  114. package/dist/ports/brain.d.ts +31 -0
  115. package/dist/ports/brain.d.ts.map +1 -1
  116. package/dist/ports/brain.js +115 -1
  117. package/dist/ports/brain.js.map +1 -1
  118. package/dist/ports/citadel-action.contract.test.d.ts +11 -0
  119. package/dist/ports/citadel-action.contract.test.d.ts.map +1 -0
  120. package/dist/ports/citadel-action.contract.test.js +317 -0
  121. package/dist/ports/citadel-action.contract.test.js.map +1 -0
  122. package/dist/ports/citadel-action.d.ts +111 -0
  123. package/dist/ports/citadel-action.d.ts.map +1 -0
  124. package/dist/ports/citadel-action.js +62 -0
  125. package/dist/ports/citadel-action.js.map +1 -0
  126. package/dist/ports/compliance-contract.d.ts +123 -0
  127. package/dist/ports/compliance-contract.d.ts.map +1 -0
  128. package/dist/ports/compliance-contract.js +35 -0
  129. package/dist/ports/compliance-contract.js.map +1 -0
  130. package/dist/ports/db.d.ts +38 -0
  131. package/dist/ports/db.d.ts.map +1 -1
  132. package/dist/ports/db.js +88 -1
  133. package/dist/ports/db.js.map +1 -1
  134. package/dist/ports/delegation.contract.test.d.ts +9 -0
  135. package/dist/ports/delegation.contract.test.d.ts.map +1 -0
  136. package/dist/ports/delegation.contract.test.js +337 -0
  137. package/dist/ports/delegation.contract.test.js.map +1 -0
  138. package/dist/ports/delegation.d.ts +134 -0
  139. package/dist/ports/delegation.d.ts.map +1 -0
  140. package/dist/ports/delegation.js +105 -0
  141. package/dist/ports/delegation.js.map +1 -0
  142. package/dist/ports/event-bus.d.ts +29 -0
  143. package/dist/ports/event-bus.d.ts.map +1 -1
  144. package/dist/ports/event-bus.js +106 -1
  145. package/dist/ports/event-bus.js.map +1 -1
  146. package/dist/ports/federation.contract.test.d.ts +9 -0
  147. package/dist/ports/federation.contract.test.d.ts.map +1 -0
  148. package/dist/ports/federation.contract.test.js +279 -0
  149. package/dist/ports/federation.contract.test.js.map +1 -0
  150. package/dist/ports/federation.d.ts +140 -0
  151. package/dist/ports/federation.d.ts.map +1 -0
  152. package/dist/ports/federation.js +57 -0
  153. package/dist/ports/federation.js.map +1 -0
  154. package/dist/ports/index.d.ts +28 -2
  155. package/dist/ports/index.d.ts.map +1 -1
  156. package/dist/ports/index.js +17 -2
  157. package/dist/ports/index.js.map +1 -1
  158. package/dist/ports/llm-provider.d.ts +37 -0
  159. package/dist/ports/llm-provider.d.ts.map +1 -1
  160. package/dist/ports/llm-provider.js +99 -1
  161. package/dist/ports/llm-provider.js.map +1 -1
  162. package/dist/ports/logger.d.ts +27 -0
  163. package/dist/ports/logger.d.ts.map +1 -1
  164. package/dist/ports/logger.js +87 -0
  165. package/dist/ports/logger.js.map +1 -1
  166. package/dist/ports/manifest-registry.contract.test.d.ts +9 -0
  167. package/dist/ports/manifest-registry.contract.test.d.ts.map +1 -0
  168. package/dist/ports/manifest-registry.contract.test.js +246 -0
  169. package/dist/ports/manifest-registry.contract.test.js.map +1 -0
  170. package/dist/ports/manifest-registry.d.ts +116 -0
  171. package/dist/ports/manifest-registry.d.ts.map +1 -0
  172. package/dist/ports/manifest-registry.js +79 -0
  173. package/dist/ports/manifest-registry.js.map +1 -0
  174. package/dist/ports/observability.contract.test.d.ts +12 -0
  175. package/dist/ports/observability.contract.test.d.ts.map +1 -0
  176. package/dist/ports/observability.contract.test.js +260 -0
  177. package/dist/ports/observability.contract.test.js.map +1 -0
  178. package/dist/ports/observability.d.ts +98 -0
  179. package/dist/ports/observability.d.ts.map +1 -0
  180. package/dist/ports/observability.js +59 -0
  181. package/dist/ports/observability.js.map +1 -0
  182. package/dist/ports/outcome.d.ts +26 -0
  183. package/dist/ports/outcome.d.ts.map +1 -1
  184. package/dist/ports/outcome.js +62 -1
  185. package/dist/ports/outcome.js.map +1 -1
  186. package/dist/ports/privacy.contract.test.d.ts +12 -0
  187. package/dist/ports/privacy.contract.test.d.ts.map +1 -0
  188. package/dist/ports/privacy.contract.test.js +325 -0
  189. package/dist/ports/privacy.contract.test.js.map +1 -0
  190. package/dist/ports/privacy.d.ts +132 -0
  191. package/dist/ports/privacy.d.ts.map +1 -0
  192. package/dist/ports/privacy.js +83 -0
  193. package/dist/ports/privacy.js.map +1 -0
  194. package/dist/ports/tenant-context.contract.test.d.ts +14 -0
  195. package/dist/ports/tenant-context.contract.test.d.ts.map +1 -0
  196. package/dist/ports/tenant-context.contract.test.js +352 -0
  197. package/dist/ports/tenant-context.contract.test.js.map +1 -0
  198. package/dist/ports/tenant-context.d.ts +103 -0
  199. package/dist/ports/tenant-context.d.ts.map +1 -0
  200. package/dist/ports/tenant-context.js +48 -0
  201. package/dist/ports/tenant-context.js.map +1 -0
  202. package/dist/ports/vauban-finance-action.contract.test.d.ts +11 -0
  203. package/dist/ports/vauban-finance-action.contract.test.d.ts.map +1 -0
  204. package/dist/ports/vauban-finance-action.contract.test.js +260 -0
  205. package/dist/ports/vauban-finance-action.contract.test.js.map +1 -0
  206. package/dist/ports/vauban-finance-action.d.ts +106 -0
  207. package/dist/ports/vauban-finance-action.d.ts.map +1 -0
  208. package/dist/ports/vauban-finance-action.js +60 -0
  209. package/dist/ports/vauban-finance-action.js.map +1 -0
  210. package/dist/ports/workflow-runtime.d.ts +204 -0
  211. package/dist/ports/workflow-runtime.d.ts.map +1 -0
  212. package/dist/ports/workflow-runtime.js +72 -0
  213. package/dist/ports/workflow-runtime.js.map +1 -0
  214. package/dist/proof/cert-verify.d.ts +80 -0
  215. package/dist/proof/cert-verify.d.ts.map +1 -0
  216. package/dist/proof/cert-verify.js +178 -0
  217. package/dist/proof/cert-verify.js.map +1 -0
  218. package/dist/replay/replay.d.ts.map +1 -1
  219. package/dist/replay/replay.js +5 -1
  220. package/dist/replay/replay.js.map +1 -1
  221. package/dist/retry/index.d.ts +129 -0
  222. package/dist/retry/index.d.ts.map +1 -0
  223. package/dist/retry/index.js +156 -0
  224. package/dist/retry/index.js.map +1 -0
  225. package/dist/retry/presets.d.ts +39 -0
  226. package/dist/retry/presets.d.ts.map +1 -0
  227. package/dist/retry/presets.js +69 -0
  228. package/dist/retry/presets.js.map +1 -0
  229. package/dist/skill-loop/ab-runner.d.ts +67 -0
  230. package/dist/skill-loop/ab-runner.d.ts.map +1 -0
  231. package/dist/skill-loop/ab-runner.js +160 -0
  232. package/dist/skill-loop/ab-runner.js.map +1 -0
  233. package/dist/skill-loop/adoption.d.ts +67 -0
  234. package/dist/skill-loop/adoption.d.ts.map +1 -0
  235. package/dist/skill-loop/adoption.js +126 -0
  236. package/dist/skill-loop/adoption.js.map +1 -0
  237. package/dist/skill-loop/candidate.d.ts +45 -0
  238. package/dist/skill-loop/candidate.d.ts.map +1 -0
  239. package/dist/skill-loop/candidate.js +43 -0
  240. package/dist/skill-loop/candidate.js.map +1 -0
  241. package/dist/skill-loop/evaluator.d.ts +42 -0
  242. package/dist/skill-loop/evaluator.d.ts.map +1 -0
  243. package/dist/skill-loop/evaluator.js +184 -0
  244. package/dist/skill-loop/evaluator.js.map +1 -0
  245. package/dist/skill-loop/index.d.ts +27 -0
  246. package/dist/skill-loop/index.d.ts.map +1 -0
  247. package/dist/skill-loop/index.js +27 -0
  248. package/dist/skill-loop/index.js.map +1 -0
  249. package/dist/skill-loop/reflexion-replay.d.ts +87 -0
  250. package/dist/skill-loop/reflexion-replay.d.ts.map +1 -0
  251. package/dist/skill-loop/reflexion-replay.js +110 -0
  252. package/dist/skill-loop/reflexion-replay.js.map +1 -0
  253. package/dist/skill-loop/sign-off.d.ts +88 -0
  254. package/dist/skill-loop/sign-off.d.ts.map +1 -0
  255. package/dist/skill-loop/sign-off.js +146 -0
  256. package/dist/skill-loop/sign-off.js.map +1 -0
  257. package/dist/skill-loop/value-metric.d.ts +55 -0
  258. package/dist/skill-loop/value-metric.d.ts.map +1 -0
  259. package/dist/skill-loop/value-metric.js +69 -0
  260. package/dist/skill-loop/value-metric.js.map +1 -0
  261. package/dist/skill-loop/versioning.d.ts +36 -0
  262. package/dist/skill-loop/versioning.d.ts.map +1 -0
  263. package/dist/skill-loop/versioning.js +47 -0
  264. package/dist/skill-loop/versioning.js.map +1 -0
  265. package/dist/skill-manifest/anchor.d.ts +91 -0
  266. package/dist/skill-manifest/anchor.d.ts.map +1 -0
  267. package/dist/skill-manifest/anchor.js +331 -0
  268. package/dist/skill-manifest/anchor.js.map +1 -0
  269. package/dist/skill-manifest/builder.d.ts +47 -0
  270. package/dist/skill-manifest/builder.d.ts.map +1 -0
  271. package/dist/skill-manifest/builder.js +93 -0
  272. package/dist/skill-manifest/builder.js.map +1 -0
  273. package/dist/skill-manifest/index.d.ts +13 -0
  274. package/dist/skill-manifest/index.d.ts.map +1 -0
  275. package/dist/skill-manifest/index.js +9 -0
  276. package/dist/skill-manifest/index.js.map +1 -0
  277. package/dist/skill-manifest/types.d.ts +67 -0
  278. package/dist/skill-manifest/types.d.ts.map +1 -0
  279. package/dist/skill-manifest/types.js +16 -0
  280. package/dist/skill-manifest/types.js.map +1 -0
  281. package/dist/skill-manifest/verifier.d.ts +42 -0
  282. package/dist/skill-manifest/verifier.d.ts.map +1 -0
  283. package/dist/skill-manifest/verifier.js +136 -0
  284. package/dist/skill-manifest/verifier.js.map +1 -0
  285. package/dist/skills/_secrets.d.ts +16 -0
  286. package/dist/skills/_secrets.d.ts.map +1 -0
  287. package/dist/skills/_secrets.js +20 -0
  288. package/dist/skills/_secrets.js.map +1 -0
  289. package/dist/skills/alpaca-quote.d.ts +2 -2
  290. package/dist/skills/alpaca-quote.d.ts.map +1 -1
  291. package/dist/skills/alpaca-quote.js +51 -20
  292. package/dist/skills/alpaca-quote.js.map +1 -1
  293. package/dist/skills/brain-query.d.ts +4 -4
  294. package/dist/skills/brain-store.d.ts +6 -6
  295. package/dist/skills/errors.d.ts +15 -0
  296. package/dist/skills/errors.d.ts.map +1 -1
  297. package/dist/skills/errors.js +21 -0
  298. package/dist/skills/errors.js.map +1 -1
  299. package/dist/skills/hitl-request.d.ts +2 -2
  300. package/dist/skills/index.d.ts +3 -1
  301. package/dist/skills/index.d.ts.map +1 -1
  302. package/dist/skills/index.js +4 -1
  303. package/dist/skills/index.js.map +1 -1
  304. package/dist/skills/markdown/loader.d.ts +52 -0
  305. package/dist/skills/markdown/loader.d.ts.map +1 -0
  306. package/dist/skills/markdown/loader.js +93 -0
  307. package/dist/skills/markdown/loader.js.map +1 -0
  308. package/dist/skills/markdown/schema.d.ts +432 -0
  309. package/dist/skills/markdown/schema.d.ts.map +1 -0
  310. package/dist/skills/markdown/schema.js +121 -0
  311. package/dist/skills/markdown/schema.js.map +1 -0
  312. package/dist/skills/poc-md-loader/markdown-loader.d.ts +77 -0
  313. package/dist/skills/poc-md-loader/markdown-loader.d.ts.map +1 -0
  314. package/dist/skills/poc-md-loader/markdown-loader.js +125 -0
  315. package/dist/skills/poc-md-loader/markdown-loader.js.map +1 -0
  316. package/dist/skills/poc-md-loader/runner.d.ts +24 -0
  317. package/dist/skills/poc-md-loader/runner.d.ts.map +1 -0
  318. package/dist/skills/poc-md-loader/runner.js +57 -0
  319. package/dist/skills/poc-md-loader/runner.js.map +1 -0
  320. package/dist/skills/poc-md-loader/vitest.poc.config.d.ts +3 -0
  321. package/dist/skills/poc-md-loader/vitest.poc.config.d.ts.map +1 -0
  322. package/dist/skills/poc-md-loader/vitest.poc.config.js +13 -0
  323. package/dist/skills/poc-md-loader/vitest.poc.config.js.map +1 -0
  324. package/dist/skills/poc-md-loader/web-search/script.d.ts +33 -0
  325. package/dist/skills/poc-md-loader/web-search/script.d.ts.map +1 -0
  326. package/dist/skills/poc-md-loader/web-search/script.js +75 -0
  327. package/dist/skills/poc-md-loader/web-search/script.js.map +1 -0
  328. package/dist/skills/record-outcome.d.ts +4 -4
  329. package/dist/skills/send-email.d.ts +2 -2
  330. package/dist/skills/send-email.d.ts.map +1 -1
  331. package/dist/skills/send-email.js +4 -3
  332. package/dist/skills/send-email.js.map +1 -1
  333. package/dist/skills/slack-notify.d.ts +4 -4
  334. package/dist/skills/slack-notify.d.ts.map +1 -1
  335. package/dist/skills/slack-notify.js +52 -21
  336. package/dist/skills/slack-notify.js.map +1 -1
  337. package/dist/skills/starknet-balance.d.ts +1 -1
  338. package/dist/skills/telegram-notify.d.ts +4 -4
  339. package/dist/skills/telegram-notify.d.ts.map +1 -1
  340. package/dist/skills/telegram-notify.js +48 -19
  341. package/dist/skills/telegram-notify.js.map +1 -1
  342. package/dist/skills/web-search.d.ts +1 -1
  343. package/dist/skills/web-search.d.ts.map +1 -1
  344. package/dist/skills/web-search.js +85 -40
  345. package/dist/skills/web-search.js.map +1 -1
  346. package/dist/telemetry/bus.d.ts +54 -0
  347. package/dist/telemetry/bus.d.ts.map +1 -0
  348. package/dist/telemetry/bus.js +159 -0
  349. package/dist/telemetry/bus.js.map +1 -0
  350. package/dist/telemetry/index.d.ts +35 -0
  351. package/dist/telemetry/index.d.ts.map +1 -0
  352. package/dist/telemetry/index.js +30 -0
  353. package/dist/telemetry/index.js.map +1 -0
  354. package/dist/telemetry/port.d.ts +121 -0
  355. package/dist/telemetry/port.d.ts.map +1 -0
  356. package/dist/telemetry/port.js +48 -0
  357. package/dist/telemetry/port.js.map +1 -0
  358. package/dist/telemetry/sinks/otlp.d.ts +45 -0
  359. package/dist/telemetry/sinks/otlp.d.ts.map +1 -0
  360. package/dist/telemetry/sinks/otlp.js +195 -0
  361. package/dist/telemetry/sinks/otlp.js.map +1 -0
  362. package/dist/telemetry/sinks/sqlite.d.ts +32 -0
  363. package/dist/telemetry/sinks/sqlite.d.ts.map +1 -0
  364. package/dist/telemetry/sinks/sqlite.js +170 -0
  365. package/dist/telemetry/sinks/sqlite.js.map +1 -0
  366. package/dist/telemetry/sinks/stdout.d.ts +22 -0
  367. package/dist/telemetry/sinks/stdout.d.ts.map +1 -0
  368. package/dist/telemetry/sinks/stdout.js +38 -0
  369. package/dist/telemetry/sinks/stdout.js.map +1 -0
  370. package/dist/testing/index.d.ts +3 -0
  371. package/dist/testing/test-brain-port.d.ts +4 -0
  372. package/dist/testing/test-brain-port.d.ts.map +1 -1
  373. package/dist/testing/test-brain-port.js +75 -20
  374. package/dist/testing/test-brain-port.js.map +1 -1
  375. package/dist/testing/test-event-bus.d.ts.map +1 -1
  376. package/dist/testing/test-event-bus.js +89 -36
  377. package/dist/testing/test-event-bus.js.map +1 -1
  378. package/dist/trace/schema.d.ts +1 -1
  379. package/dist/trace/schema.d.ts.map +1 -1
  380. package/dist/trace/schema.js +1 -1
  381. package/dist/trace/schema.js.map +1 -1
  382. package/dist/verify/formal/index.d.ts +44 -0
  383. package/dist/verify/formal/index.d.ts.map +1 -0
  384. package/dist/verify/formal/index.js +98 -0
  385. package/dist/verify/formal/index.js.map +1 -0
  386. package/dist/verify/formal/policy.d.ts +105 -0
  387. package/dist/verify/formal/policy.d.ts.map +1 -0
  388. package/dist/verify/formal/policy.js +159 -0
  389. package/dist/verify/formal/policy.js.map +1 -0
  390. package/dist/verify/formal/result.d.ts +50 -0
  391. package/dist/verify/formal/result.d.ts.map +1 -0
  392. package/dist/verify/formal/result.js +21 -0
  393. package/dist/verify/formal/result.js.map +1 -0
  394. package/dist/verify/formal/solver.d.ts +67 -0
  395. package/dist/verify/formal/solver.d.ts.map +1 -0
  396. package/dist/verify/formal/solver.js +184 -0
  397. package/dist/verify/formal/solver.js.map +1 -0
  398. package/dist/verify/formal/spec-language.d.ts +80 -0
  399. package/dist/verify/formal/spec-language.d.ts.map +1 -0
  400. package/dist/verify/formal/spec-language.js +219 -0
  401. package/dist/verify/formal/spec-language.js.map +1 -0
  402. package/docs/attestation.md +199 -0
  403. package/docs/identity.md +193 -0
  404. package/docs/telemetry/migration.md +155 -0
  405. package/docs/telemetry/overview.md +154 -0
  406. package/docs/telemetry/privacy.md +127 -0
  407. package/docs/telemetry/sinks/cc.md +155 -0
  408. package/docs/telemetry/sinks/otlp.md +146 -0
  409. package/docs/telemetry/sinks/sqlite.md +126 -0
  410. package/docs/telemetry/sinks/stdout.md +82 -0
  411. package/package.json +18 -2
  412. package/src/adapters/llm/anthropic-direct.ts +51 -0
  413. package/src/adapters/llm/cascade.ts +64 -19
  414. package/src/adapters/llm/litellm.ts +49 -0
  415. package/src/compute/difficulty-estimator.ts +111 -0
  416. package/src/compute/strategies/mixture-of-agents.ts +150 -0
  417. package/src/compute/strategies/tree-of-thoughts.ts +293 -0
  418. package/src/compute/strategies/two-phase-orient.ts +147 -0
  419. package/src/container/protocol.ts +243 -0
  420. package/src/container/runtime.ts +424 -0
  421. package/src/db/migrations/026_formal_verify_results.sql +30 -0
  422. package/src/identity/agent-persona.ts +203 -0
  423. package/src/identity/persona-prompt.ts +84 -0
  424. package/src/identity/persona-schema.ts +127 -0
  425. package/src/index.ts +368 -2
  426. package/src/memory/episodic-rrf.ts +224 -0
  427. package/src/mesh/attenuation.ts +190 -0
  428. package/src/mesh/delegate.ts +254 -0
  429. package/src/mesh/dispatcher.ts +301 -0
  430. package/src/mesh/index.ts +39 -0
  431. package/src/mesh/types.ts +31 -0
  432. package/src/orchestration/ooda/agent.ts +50 -0
  433. package/src/orchestration/ooda/skills.ts +177 -0
  434. package/src/orchestration/ooda/types.ts +12 -0
  435. package/src/ports/bastion-action.contract.test.ts +355 -0
  436. package/src/ports/bastion-action.ts +198 -0
  437. package/src/ports/brain.ts +177 -15
  438. package/src/ports/citadel-action.contract.test.ts +430 -0
  439. package/src/ports/citadel-action.ts +174 -0
  440. package/src/ports/compliance-contract.ts +191 -0
  441. package/src/ports/db.ts +98 -0
  442. package/src/ports/delegation.contract.test.ts +428 -0
  443. package/src/ports/delegation.ts +211 -0
  444. package/src/ports/event-bus.ts +133 -0
  445. package/src/ports/federation.contract.test.ts +355 -0
  446. package/src/ports/federation.ts +190 -0
  447. package/src/ports/index.ts +186 -1
  448. package/src/ports/llm-provider.ts +123 -0
  449. package/src/ports/logger.ts +104 -0
  450. package/src/ports/manifest-registry.contract.test.ts +324 -0
  451. package/src/ports/manifest-registry.ts +188 -0
  452. package/src/ports/observability.contract.test.ts +315 -0
  453. package/src/ports/observability.ts +150 -0
  454. package/src/ports/outcome.ts +69 -0
  455. package/src/ports/privacy.contract.test.ts +413 -0
  456. package/src/ports/privacy.ts +207 -0
  457. package/src/ports/tenant-context.contract.test.ts +454 -0
  458. package/src/ports/tenant-context.ts +150 -0
  459. package/src/ports/vauban-finance-action.contract.test.ts +335 -0
  460. package/src/ports/vauban-finance-action.ts +166 -0
  461. package/src/ports/workflow-runtime.ts +327 -0
  462. package/src/proof/cert-verify.ts +249 -0
  463. package/src/replay/replay.ts +11 -8
  464. package/src/retry/index.ts +227 -0
  465. package/src/retry/presets.ts +75 -0
  466. package/src/skill-loop/ab-runner.ts +196 -0
  467. package/src/skill-loop/adoption.ts +188 -0
  468. package/src/skill-loop/candidate.ts +75 -0
  469. package/src/skill-loop/evaluator.ts +238 -0
  470. package/src/skill-loop/index.ts +51 -0
  471. package/src/skill-loop/reflexion-replay.ts +173 -0
  472. package/src/skill-loop/sign-off.ts +247 -0
  473. package/src/skill-loop/value-metric.ts +120 -0
  474. package/src/skill-loop/versioning.ts +75 -0
  475. package/src/skill-manifest/anchor.ts +401 -0
  476. package/src/skill-manifest/builder.ts +129 -0
  477. package/src/skill-manifest/index.ts +18 -0
  478. package/src/skill-manifest/types.ts +72 -0
  479. package/src/skill-manifest/verifier.ts +198 -0
  480. package/src/skills/_secrets.ts +25 -0
  481. package/src/skills/alpaca-quote.ts +68 -23
  482. package/src/skills/errors.ts +30 -2
  483. package/src/skills/index.ts +19 -0
  484. package/src/skills/markdown/loader.ts +129 -0
  485. package/src/skills/markdown/schema.ts +144 -0
  486. package/src/skills/poc-md-loader/e2e-parity.test.ts +237 -0
  487. package/src/skills/poc-md-loader/markdown-loader.ts +161 -0
  488. package/src/skills/poc-md-loader/runner.ts +82 -0
  489. package/src/skills/poc-md-loader/vitest.poc.config.ts +13 -0
  490. package/src/skills/poc-md-loader/web-search/SKILL.md +42 -0
  491. package/src/skills/poc-md-loader/web-search/script.ts +109 -0
  492. package/src/skills/send-email.ts +4 -3
  493. package/src/skills/slack-notify.ts +73 -30
  494. package/src/skills/telegram-notify.ts +70 -24
  495. package/src/skills/web-search.ts +132 -50
  496. package/src/telemetry/bus.test.ts +231 -0
  497. package/src/telemetry/bus.ts +241 -0
  498. package/src/telemetry/index.ts +49 -0
  499. package/src/telemetry/port.ts +160 -0
  500. package/src/telemetry/sinks/otlp.test.ts +146 -0
  501. package/src/telemetry/sinks/otlp.ts +250 -0
  502. package/src/telemetry/sinks/sqlite.test.ts +121 -0
  503. package/src/telemetry/sinks/sqlite.ts +260 -0
  504. package/src/telemetry/sinks/stdout.test.ts +109 -0
  505. package/src/telemetry/sinks/stdout.ts +59 -0
  506. package/src/testing/test-brain-port.ts +98 -24
  507. package/src/testing/test-event-bus.ts +104 -43
  508. package/src/trace/schema.ts +1 -1
  509. package/src/verify/formal/index.ts +154 -0
  510. package/src/verify/formal/policy.ts +253 -0
  511. package/src/verify/formal/result.ts +52 -0
  512. package/src/verify/formal/solver.ts +235 -0
  513. package/src/verify/formal/spec-language.ts +274 -0
@@ -0,0 +1,231 @@
1
+ /**
2
+ * TelemetryBus — fanout, isolation, backpressure tests.
3
+ *
4
+ * Ref: command-center:sprint-693:telemetry-bus
5
+ */
6
+
7
+ import { describe, expect, it, vi } from "vitest";
8
+
9
+ import { createTelemetryBus } from "./bus.js";
10
+ import type { TelemetrySink } from "./port.js";
11
+
12
+ function makeSink(
13
+ name: string,
14
+ behavior: "ok" | "throw" = "ok"
15
+ ): TelemetrySink {
16
+ const calls = { start: 0, step: 0, finish: 0 };
17
+ return {
18
+ name,
19
+ async start() {
20
+ calls.start += 1;
21
+ if (behavior === "throw") throw new Error(`${name}.start failed`);
22
+ },
23
+ async step() {
24
+ calls.step += 1;
25
+ if (behavior === "throw") throw new Error(`${name}.step failed`);
26
+ },
27
+ async finish() {
28
+ calls.finish += 1;
29
+ if (behavior === "throw") throw new Error(`${name}.finish failed`);
30
+ },
31
+ // expose counters via name munging — vitest reads `(sink as any).calls`
32
+ // @ts-expect-error — test affordance
33
+ calls,
34
+ };
35
+ }
36
+
37
+ const RUN_START = {
38
+ runId: "11111111-1111-1111-1111-111111111111",
39
+ agentId: "agent-x",
40
+ agentVersion: "1.0.0",
41
+ model: "test",
42
+ provider: "test",
43
+ startedAt: "2026-05-16T17:00:00.000Z",
44
+ };
45
+
46
+ const STEP_DELTA = {
47
+ stepIndex: 0,
48
+ kind: "observe",
49
+ status: "completed" as const,
50
+ inputTokens: 10,
51
+ outputTokens: 20,
52
+ costUsd: 0.001,
53
+ };
54
+
55
+ const FINISH = {
56
+ status: "success" as const,
57
+ finishedAt: "2026-05-16T17:00:05.000Z",
58
+ };
59
+
60
+ describe("createTelemetryBus", () => {
61
+ it("returns a NOOP sink when sinks=[]", async () => {
62
+ const bus = createTelemetryBus({ sinks: [] });
63
+ expect(bus.name).toBe("noop");
64
+ await expect(bus.start(RUN_START)).resolves.toBeUndefined();
65
+ expect(bus.counters.dispatched).toBe(0);
66
+ });
67
+
68
+ it("fans out start/step/finish to every sink (blocking mode)", async () => {
69
+ const a = makeSink("a");
70
+ const b = makeSink("b");
71
+ const bus = createTelemetryBus({
72
+ sinks: [a, b],
73
+ nonBlocking: false,
74
+ });
75
+
76
+ await bus.start(RUN_START);
77
+ await bus.step(RUN_START.runId, STEP_DELTA);
78
+ await bus.finish(RUN_START.runId, FINISH);
79
+
80
+ // @ts-expect-error — test affordance
81
+ expect(a.calls).toEqual({ start: 1, step: 1, finish: 1 });
82
+ // @ts-expect-error — test affordance
83
+ expect(b.calls).toEqual({ start: 1, step: 1, finish: 1 });
84
+ expect(bus.counters.dispatched).toBe(6); // 3 events × 2 sinks
85
+ expect(bus.counters.sinkErrors).toBe(0);
86
+ });
87
+
88
+ it("isolates failures — one sink throwing does not affect others", async () => {
89
+ const good = makeSink("good");
90
+ const bad = makeSink("bad", "throw");
91
+ const warn = vi.fn();
92
+ const bus = createTelemetryBus({
93
+ sinks: [good, bad],
94
+ logger: { warn, error: () => {} },
95
+ nonBlocking: false,
96
+ });
97
+
98
+ await bus.start(RUN_START);
99
+ await bus.step(RUN_START.runId, STEP_DELTA);
100
+ await bus.finish(RUN_START.runId, FINISH);
101
+
102
+ // @ts-expect-error
103
+ expect(good.calls).toEqual({ start: 1, step: 1, finish: 1 });
104
+ // @ts-expect-error
105
+ expect(bad.calls).toEqual({ start: 1, step: 1, finish: 1 });
106
+ expect(bus.counters.sinkErrors).toBe(3);
107
+ expect(warn).toHaveBeenCalledTimes(3);
108
+ expect(warn.mock.calls[0]![1]).toMatch(/isolated/);
109
+ });
110
+
111
+ it("backpressure: drops oldest events when queue exceeds maxQueueDepth", async () => {
112
+ // Pending-resolver sink — caller controls when each call resolves.
113
+ const pending: Array<() => void> = [];
114
+ const blockingSink: TelemetrySink = {
115
+ name: "slow",
116
+ async start() {
117
+ await new Promise<void>((res) => {
118
+ pending.push(res);
119
+ });
120
+ },
121
+ async step() {},
122
+ async finish() {},
123
+ };
124
+ const warn = vi.fn();
125
+ const bus = createTelemetryBus({
126
+ sinks: [blockingSink],
127
+ logger: { warn, error: () => {} },
128
+ nonBlocking: true,
129
+ maxQueueDepth: 3,
130
+ });
131
+
132
+ // Enqueue 6 starts — 1 enters dispatch and blocks; the next 3 fill the
133
+ // queue; the 5th and 6th cause overflow (drop oldest).
134
+ for (let i = 0; i < 6; i++) {
135
+ await bus.start({ ...RUN_START, runId: `run-${i}` });
136
+ }
137
+ expect(bus.counters.dropped).toBeGreaterThanOrEqual(1);
138
+
139
+ // Release all pending dispatches so flush() resolves.
140
+ while (pending.length > 0 || bus.counters.dispatched < 4) {
141
+ const r = pending.shift();
142
+ r?.();
143
+ await new Promise((res) => setTimeout(res, 0));
144
+ }
145
+ await bus.flush();
146
+ }, 10_000);
147
+
148
+ it("non-blocking mode returns immediately", async () => {
149
+ let resolveSink: (() => void) | undefined;
150
+ const sink: TelemetrySink = {
151
+ name: "slow",
152
+ async start() {
153
+ await new Promise<void>((res) => {
154
+ resolveSink = res;
155
+ });
156
+ },
157
+ async step() {},
158
+ async finish() {},
159
+ };
160
+ const bus = createTelemetryBus({ sinks: [sink], nonBlocking: true });
161
+
162
+ const t0 = Date.now();
163
+ await bus.start(RUN_START); // should return immediately
164
+ const elapsed = Date.now() - t0;
165
+ expect(elapsed).toBeLessThan(50);
166
+ expect(bus.counters.dispatched).toBe(0); // not dispatched yet
167
+
168
+ resolveSink?.();
169
+ await bus.flush();
170
+ });
171
+
172
+ it("flush awaits in-flight dispatches", async () => {
173
+ const sink = makeSink("a");
174
+ const bus = createTelemetryBus({ sinks: [sink], nonBlocking: true });
175
+
176
+ await bus.start(RUN_START);
177
+ await bus.step(RUN_START.runId, STEP_DELTA);
178
+ await bus.finish(RUN_START.runId, FINISH);
179
+ await bus.flush();
180
+
181
+ // @ts-expect-error
182
+ expect(sink.calls).toEqual({ start: 1, step: 1, finish: 1 });
183
+ expect(bus.counters.dispatched).toBe(3);
184
+ });
185
+
186
+ it("preserves FIFO order per sink", async () => {
187
+ const events: string[] = [];
188
+ const sink: TelemetrySink = {
189
+ name: "ordered",
190
+ async start(e) {
191
+ events.push(`start:${e.runId}`);
192
+ },
193
+ async step(runId, d) {
194
+ events.push(`step:${runId}:${d.stepIndex}`);
195
+ },
196
+ async finish(runId) {
197
+ events.push(`finish:${runId}`);
198
+ },
199
+ };
200
+ const bus = createTelemetryBus({ sinks: [sink], nonBlocking: true });
201
+
202
+ await bus.start(RUN_START);
203
+ await bus.step(RUN_START.runId, { ...STEP_DELTA, stepIndex: 0 });
204
+ await bus.step(RUN_START.runId, { ...STEP_DELTA, stepIndex: 1 });
205
+ await bus.finish(RUN_START.runId, FINISH);
206
+ await bus.flush();
207
+
208
+ expect(events).toEqual([
209
+ `start:${RUN_START.runId}`,
210
+ `step:${RUN_START.runId}:0`,
211
+ `step:${RUN_START.runId}:1`,
212
+ `finish:${RUN_START.runId}`,
213
+ ]);
214
+ });
215
+
216
+ it("counts dispatched accurately under mixed success/failure", async () => {
217
+ const good = makeSink("good");
218
+ const bad = makeSink("bad", "throw");
219
+ const bus = createTelemetryBus({
220
+ sinks: [good, bad],
221
+ nonBlocking: false,
222
+ logger: { warn: () => {}, error: () => {} },
223
+ });
224
+
225
+ await bus.start(RUN_START);
226
+ await bus.finish(RUN_START.runId, FINISH);
227
+
228
+ expect(bus.counters.dispatched).toBe(2); // good's 2 events
229
+ expect(bus.counters.sinkErrors).toBe(2); // bad's 2 events
230
+ });
231
+ });
@@ -0,0 +1,241 @@
1
+ /**
2
+ * TelemetryBus — fanout to multiple {@link TelemetrySink}s, non-blocking.
3
+ *
4
+ * Invariants :
5
+ * 1. Sink failures are ISOLATED — one sink throwing never affects the others
6
+ * nor the host agent loop. Failures are logged via the bus logger.
7
+ * 2. The bus itself implements {@link TelemetrySink}, so it can be passed
8
+ * transparently to consumers expecting a single sink (composition).
9
+ * 3. When `nonBlocking: true` (default), `start`/`step`/`finish` return
10
+ * immediately and dispatch in background. Errors surface via the logger.
11
+ * 4. Backpressure : if internal queue > `maxQueueDepth`, oldest events are
12
+ * dropped and counted.
13
+ *
14
+ * Ref: command-center:sprint-693:telemetry-bus
15
+ */
16
+
17
+ import {
18
+ NOOP_TELEMETRY_SINK,
19
+ type TelemetryRunFinish,
20
+ type TelemetryRunStart,
21
+ type TelemetryRunStep,
22
+ type TelemetrySink,
23
+ } from "./port.js";
24
+
25
+ // ─── Minimal logger interface (avoid SDK dep) ────────────────────────────────
26
+
27
+ export interface TelemetryLogger {
28
+ warn(obj: Record<string, unknown>, msg?: string): void;
29
+ error(obj: Record<string, unknown>, msg?: string): void;
30
+ }
31
+
32
+ const NOOP_LOGGER: TelemetryLogger = {
33
+ warn: () => {
34
+ /* no-op */
35
+ },
36
+ error: () => {
37
+ /* no-op */
38
+ },
39
+ };
40
+
41
+ // ─── Bus options ─────────────────────────────────────────────────────────────
42
+
43
+ export interface TelemetryBusOptions {
44
+ sinks: readonly TelemetrySink[];
45
+ /** Pino-compatible logger. Defaults to no-op. */
46
+ logger?: TelemetryLogger;
47
+ /**
48
+ * When true (default), `start/step/finish` resolve immediately and dispatch
49
+ * in background. Set false in tests for deterministic assertions.
50
+ */
51
+ nonBlocking?: boolean;
52
+ /**
53
+ * Max number of in-flight events per sink before dropping oldest.
54
+ * Defaults to 1000.
55
+ */
56
+ maxQueueDepth?: number;
57
+ }
58
+
59
+ // ─── Telemetry counters (exposed for Prometheus or tests) ────────────────────
60
+
61
+ export interface TelemetryCounters {
62
+ /** Events dropped due to queue overflow. */
63
+ readonly dropped: number;
64
+ /** Sink errors caught and isolated. */
65
+ readonly sinkErrors: number;
66
+ /** Events successfully dispatched. */
67
+ readonly dispatched: number;
68
+ }
69
+
70
+ // ─── Implementation ──────────────────────────────────────────────────────────
71
+
72
+ interface PendingEvent {
73
+ kind: "start" | "step" | "finish";
74
+ exec: (sink: TelemetrySink) => Promise<unknown>;
75
+ }
76
+
77
+ class TelemetryBusImpl implements TelemetrySink {
78
+ readonly name = "telemetry-bus";
79
+
80
+ private readonly _sinks: readonly TelemetrySink[];
81
+ private readonly _logger: TelemetryLogger;
82
+ private readonly _nonBlocking: boolean;
83
+ private readonly _maxQueueDepth: number;
84
+ /** Per-sink queue of pending events (FIFO). */
85
+ private readonly _queues: PendingEvent[][];
86
+ /** Per-sink drain promise (single-flight). */
87
+ private readonly _draining: Array<Promise<void> | null>;
88
+
89
+ private _dropped = 0;
90
+ private _sinkErrors = 0;
91
+ private _dispatched = 0;
92
+
93
+ constructor(opts: TelemetryBusOptions) {
94
+ this._sinks = opts.sinks;
95
+ this._logger = opts.logger ?? NOOP_LOGGER;
96
+ this._nonBlocking = opts.nonBlocking ?? true;
97
+ this._maxQueueDepth = opts.maxQueueDepth ?? 1000;
98
+ this._queues = this._sinks.map(() => []);
99
+ this._draining = this._sinks.map(() => null);
100
+ }
101
+
102
+ get counters(): TelemetryCounters {
103
+ return {
104
+ dropped: this._dropped,
105
+ sinkErrors: this._sinkErrors,
106
+ dispatched: this._dispatched,
107
+ };
108
+ }
109
+
110
+ async start(event: TelemetryRunStart): Promise<void> {
111
+ return this._fanout({
112
+ kind: "start",
113
+ exec: (s) => s.start(event),
114
+ });
115
+ }
116
+
117
+ async step(runId: string, delta: TelemetryRunStep): Promise<void> {
118
+ return this._fanout({
119
+ kind: "step",
120
+ exec: (s) => s.step(runId, delta),
121
+ });
122
+ }
123
+
124
+ async finish(runId: string, event: TelemetryRunFinish): Promise<void> {
125
+ return this._fanout({
126
+ kind: "finish",
127
+ exec: (s) => s.finish(runId, event),
128
+ });
129
+ }
130
+
131
+ async flush(): Promise<void> {
132
+ await Promise.all([
133
+ ...this._draining.map((p) => p ?? Promise.resolve()),
134
+ ...this._sinks.map((s) =>
135
+ s.flush?.().catch((err) => {
136
+ this._sinkErrors += 1;
137
+ this._logger.warn(
138
+ { sink: s.name, err: errorMessage(err) },
139
+ "telemetry-bus: flush failed"
140
+ );
141
+ })
142
+ ),
143
+ ]);
144
+ }
145
+
146
+ // ── internal ───────────────────────────────────────────────────────────────
147
+
148
+ private async _fanout(evt: PendingEvent): Promise<void> {
149
+ if (this._nonBlocking) {
150
+ // Enqueue on each sink, kick drain in background.
151
+ this._sinks.forEach((_, i) => this._enqueue(i, evt));
152
+ return;
153
+ }
154
+ // Blocking mode (tests) — dispatch sequentially and surface errors via log.
155
+ await Promise.all(this._sinks.map((sink) => this._dispatchOne(sink, evt)));
156
+ }
157
+
158
+ private _enqueue(sinkIdx: number, evt: PendingEvent): void {
159
+ const queue = this._queues[sinkIdx]!;
160
+ if (queue.length >= this._maxQueueDepth) {
161
+ queue.shift(); // drop oldest
162
+ this._dropped += 1;
163
+ const sink = this._sinks[sinkIdx]!;
164
+ this._logger.warn(
165
+ { sink: sink.name, depth: queue.length, dropped: this._dropped },
166
+ "telemetry-bus: queue overflow, oldest dropped"
167
+ );
168
+ }
169
+ queue.push(evt);
170
+ void this._drain(sinkIdx);
171
+ }
172
+
173
+ private async _drain(sinkIdx: number): Promise<void> {
174
+ if (this._draining[sinkIdx]) return;
175
+ const sink = this._sinks[sinkIdx]!;
176
+ const queue = this._queues[sinkIdx]!;
177
+
178
+ const promise = (async () => {
179
+ while (queue.length > 0) {
180
+ const evt = queue.shift()!;
181
+ await this._dispatchOne(sink, evt);
182
+ }
183
+ })();
184
+ this._draining[sinkIdx] = promise;
185
+ try {
186
+ await promise;
187
+ } finally {
188
+ this._draining[sinkIdx] = null;
189
+ }
190
+ }
191
+
192
+ private async _dispatchOne(
193
+ sink: TelemetrySink,
194
+ evt: PendingEvent
195
+ ): Promise<void> {
196
+ try {
197
+ await evt.exec(sink);
198
+ this._dispatched += 1;
199
+ } catch (err) {
200
+ this._sinkErrors += 1;
201
+ this._logger.warn(
202
+ {
203
+ sink: sink.name,
204
+ kind: evt.kind,
205
+ err: errorMessage(err),
206
+ },
207
+ "telemetry-bus: sink dispatch failed (isolated)"
208
+ );
209
+ }
210
+ }
211
+ }
212
+
213
+ // ─── Factory ─────────────────────────────────────────────────────────────────
214
+
215
+ /**
216
+ * Build a TelemetryBus that fans events to all sinks non-blockingly.
217
+ *
218
+ * If `sinks` is empty, returns {@link NOOP_TELEMETRY_SINK} so callers never
219
+ * need to null-check.
220
+ */
221
+ export function createTelemetryBus(
222
+ opts: TelemetryBusOptions
223
+ ): TelemetrySink & { counters: TelemetryCounters; flush(): Promise<void> } {
224
+ if (opts.sinks.length === 0) {
225
+ // Wrap NOOP with stub counters + flush for type consistency.
226
+ return {
227
+ ...NOOP_TELEMETRY_SINK,
228
+ counters: { dropped: 0, sinkErrors: 0, dispatched: 0 },
229
+ async flush() {
230
+ /* no-op */
231
+ },
232
+ };
233
+ }
234
+ return new TelemetryBusImpl(opts);
235
+ }
236
+
237
+ // ─── Helpers ─────────────────────────────────────────────────────────────────
238
+
239
+ function errorMessage(err: unknown): string {
240
+ return err instanceof Error ? err.message : String(err);
241
+ }
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Public telemetry API for agent-sdk consumers.
3
+ *
4
+ * Per ADR-ECO-039. Sovereign multi-sink observability for OODA agents.
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * import {
9
+ * createOODAAgent,
10
+ * stdoutTelemetrySink,
11
+ * localSqliteTelemetrySink,
12
+ * } from "@vauban-org/agent-sdk";
13
+ *
14
+ * createOODAAgent({
15
+ * agentId: "my-agent",
16
+ * telemetry: {
17
+ * sinks: [
18
+ * stdoutTelemetrySink(),
19
+ * localSqliteTelemetrySink(),
20
+ * ],
21
+ * },
22
+ * });
23
+ * ```
24
+ */
25
+
26
+ export { NOOP_TELEMETRY_SINK, TelemetrySinkError } from "./port.js";
27
+ export type {
28
+ TelemetryRunStatus,
29
+ TelemetryRunFinish,
30
+ TelemetryRunStart,
31
+ TelemetryRunStep,
32
+ TelemetrySink,
33
+ } from "./port.js";
34
+
35
+ export { createTelemetryBus } from "./bus.js";
36
+ export type {
37
+ TelemetryBusOptions,
38
+ TelemetryCounters,
39
+ TelemetryLogger,
40
+ } from "./bus.js";
41
+
42
+ export { stdoutTelemetrySink } from "./sinks/stdout.js";
43
+ export type { StdoutTelemetrySinkOptions } from "./sinks/stdout.js";
44
+
45
+ export { localSqliteTelemetrySink } from "./sinks/sqlite.js";
46
+ export type { LocalSqliteTelemetrySinkOptions } from "./sinks/sqlite.js";
47
+
48
+ export { otlpTelemetrySink } from "./sinks/otlp.js";
49
+ export type { OtlpTelemetrySinkOptions } from "./sinks/otlp.js";
@@ -0,0 +1,160 @@
1
+ /**
2
+ * TelemetryPort — sovereign multi-sink observability for agent runs.
3
+ *
4
+ * Per ADR-ECO-039 (accepted 2026-05-16). Sink-based interface replaces the
5
+ * implicit coupling between agent-sdk and the CC `agent_run` table (legacy
6
+ * `AgentRunTracker`). Callers configure 0..N sinks; the {@link TelemetryBus}
7
+ * fans events out non-blockingly.
8
+ *
9
+ * Three modes :
10
+ * 1. Standalone : `[stdoutTelemetrySink(), localSqliteTelemetrySink()]`
11
+ * 2. + CC SaaS : add `commandCenterTelemetrySink({apiKey})`
12
+ * 3. Tiered : same code, API key changes entitlement server-side
13
+ *
14
+ * Ref: command-center:sprint-693:port-interface
15
+ */
16
+
17
+ // ─── Run lifecycle types (compatible with legacy AgentRunTracker) ────────────
18
+
19
+ export interface TelemetryRunStart {
20
+ /** Caller-generated run id (matches the OODA loop's runId / trace). */
21
+ runId: string;
22
+ agentId: string;
23
+ agentVersion: string;
24
+ model: string;
25
+ provider: string;
26
+ /** Optional tenant scoping — required by the CC sink. */
27
+ tenantId?: string;
28
+ /** OTel trace id for replay linkage. */
29
+ traceId?: string;
30
+ /** ISO8601 timestamp of cycle start. */
31
+ startedAt: string;
32
+ }
33
+
34
+ export interface TelemetryRunStep {
35
+ /** Monotonic step index within the run, starting at 0. */
36
+ stepIndex: number;
37
+ /** OODA phase or step kind ("observe" | "orient" | "decide" | "act" | ...). */
38
+ kind: string;
39
+ /** Status of THIS step (not the whole run). */
40
+ status: "completed" | "failed" | "skipped";
41
+ inputTokens: number;
42
+ outputTokens: number;
43
+ toolCalls?: number;
44
+ /**
45
+ * USD cost delta. MUST be >= 0. Use 0 for non-LLM steps.
46
+ * Fixed(6) precision recommended.
47
+ */
48
+ costUsd: number;
49
+ /** Optional duration in ms — useful for OTLP span span_start/span_end. */
50
+ durationMs?: number;
51
+ /** Optional metadata. Hashed at sink boundary unless `includePayloads`. */
52
+ metadata?: Record<string, unknown>;
53
+ }
54
+
55
+ /**
56
+ * Run final status.
57
+ *
58
+ * NEW (sprint-693) : "skipped" — added so that session_guard /
59
+ * risk_guard / heap_exceeded short-circuits are observably distinct
60
+ * from "success" or "failed".
61
+ */
62
+ export type TelemetryRunStatus =
63
+ | "success"
64
+ | "failed"
65
+ | "skipped"
66
+ | "timeout"
67
+ | "incoherent";
68
+
69
+ export interface TelemetryRunFinish {
70
+ status: TelemetryRunStatus;
71
+ /** Free-text reason — e.g. "session_guard:business-hours". */
72
+ stopReason?: string;
73
+ /** Only set when status === "failed" | "incoherent". */
74
+ errorMessage?: string;
75
+ /** ISO8601 timestamp of cycle finish. */
76
+ finishedAt: string;
77
+ /** Optional cumulative totals — sinks may compute or trust caller. */
78
+ totalInputTokens?: number;
79
+ totalOutputTokens?: number;
80
+ totalCostUsd?: number;
81
+ totalToolCalls?: number;
82
+ }
83
+
84
+ // ─── Sink interface ──────────────────────────────────────────────────────────
85
+
86
+ /**
87
+ * TelemetrySink — pluggable destination for run lifecycle events.
88
+ *
89
+ * Contract :
90
+ * - `start` is called ONCE per run before any `step`.
91
+ * - `step` MAY be called 0..N times after start; the bus serialises per-run.
92
+ * - `finish` is called ONCE after the last `step` (or directly after `start`
93
+ * for skipped runs).
94
+ * - All methods MUST be idempotent w.r.t. their (runId, stepIndex) pair —
95
+ * the bus may retry on transient sink failures.
96
+ * - Implementations MUST NOT throw on transient errors ; return a rejected
97
+ * Promise instead so the bus can isolate the failure.
98
+ *
99
+ * Implementations should NOT block the agent loop. Long-running I/O should
100
+ * be batched/queued internally.
101
+ */
102
+ export interface TelemetrySink {
103
+ /** Unique sink identifier — used for audit log + Prometheus labels. */
104
+ readonly name: string;
105
+
106
+ /**
107
+ * Record run start. Returns a sink-local reference (e.g. DB UUID, file
108
+ * offset, span id) the bus may pass back to `step` / `finish` for
109
+ * correlation. Return value is opaque to the bus.
110
+ */
111
+ start(event: TelemetryRunStart): Promise<string | void>;
112
+
113
+ /** Record a single OODA step delta. */
114
+ step(runId: string, delta: TelemetryRunStep): Promise<void>;
115
+
116
+ /** Record run finish. */
117
+ finish(runId: string, event: TelemetryRunFinish): Promise<void>;
118
+
119
+ /**
120
+ * Flush pending I/O (best-effort). Called on agent shutdown.
121
+ * Implementations without a buffer can no-op.
122
+ */
123
+ flush?(): Promise<void>;
124
+ }
125
+
126
+ // ─── NOOP — default when no sinks configured ─────────────────────────────────
127
+
128
+ /**
129
+ * No-op sink. The bus uses this when no sinks are configured, so callers
130
+ * never need to null-check.
131
+ */
132
+ export const NOOP_TELEMETRY_SINK: TelemetrySink = {
133
+ name: "noop",
134
+ async start() {
135
+ /* no-op */
136
+ },
137
+ async step() {
138
+ /* no-op */
139
+ },
140
+ async finish() {
141
+ /* no-op */
142
+ },
143
+ };
144
+
145
+ // ─── Error type ──────────────────────────────────────────────────────────────
146
+
147
+ /**
148
+ * Thrown only at the BUS boundary when ALL sinks fail. Individual sink
149
+ * failures are warned and isolated (see {@link TelemetryBus}).
150
+ */
151
+ export class TelemetrySinkError extends Error {
152
+ constructor(
153
+ message: string,
154
+ public readonly sinkName: string,
155
+ public readonly cause?: unknown
156
+ ) {
157
+ super(`[telemetry:${sinkName}] ${message}`);
158
+ this.name = "TelemetrySinkError";
159
+ }
160
+ }