@vauban-org/agent-sdk 0.17.4 → 1.2.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 (506) hide show
  1. package/CONTRACT.md +6401 -813
  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 +327 -30
  39. package/dist/events/catalogue.d.ts.map +1 -1
  40. package/dist/events/catalogue.js +18 -0
  41. package/dist/events/catalogue.js.map +1 -1
  42. package/dist/events/index.d.ts +9 -0
  43. package/dist/events/index.d.ts.map +1 -1
  44. package/dist/events/index.js +9 -0
  45. package/dist/events/index.js.map +1 -1
  46. package/dist/events/schemas/agent.completed.v1.d.ts +4 -4
  47. package/dist/events/schemas/agent.failed.v1.d.ts +2 -2
  48. package/dist/events/schemas/agent.hitl_resolved.v1.d.ts +2 -2
  49. package/dist/events/schemas/agent.started.v1.d.ts +2 -2
  50. package/dist/events/schemas/brain.skill.extracted.v1.d.ts +4 -4
  51. package/dist/events/schemas/cc.cost.anomaly_detected.v1.d.ts +2 -2
  52. package/dist/events/schemas/cc.cost.recorded.v1.d.ts +4 -4
  53. package/dist/events/schemas/citadel.sprint.analyzed.v1.d.ts +55 -0
  54. package/dist/events/schemas/citadel.sprint.analyzed.v1.d.ts.map +1 -0
  55. package/dist/events/schemas/citadel.sprint.analyzed.v1.js +22 -0
  56. package/dist/events/schemas/citadel.sprint.analyzed.v1.js.map +1 -0
  57. package/dist/events/schemas/citadel.sprint.closed.v1.d.ts +2 -2
  58. package/dist/events/schemas/forge.inbox.reply_classified.v1.d.ts +33 -0
  59. package/dist/events/schemas/forge.inbox.reply_classified.v1.d.ts.map +1 -0
  60. package/dist/events/schemas/forge.inbox.reply_classified.v1.js +15 -0
  61. package/dist/events/schemas/forge.inbox.reply_classified.v1.js.map +1 -0
  62. package/dist/events/schemas/forge.lead.qualified.v1.d.ts +2 -2
  63. package/dist/events/schemas/forge.outreach.sent.v1.d.ts +4 -4
  64. package/dist/events/schemas/incident.detected.v1.d.ts +2 -2
  65. package/dist/events/schemas/vauban-finance.forecast.generated.v1.d.ts +21 -0
  66. package/dist/events/schemas/vauban-finance.forecast.generated.v1.d.ts.map +1 -0
  67. package/dist/events/schemas/vauban-finance.forecast.generated.v1.js +11 -0
  68. package/dist/events/schemas/vauban-finance.forecast.generated.v1.js.map +1 -0
  69. package/dist/events/schemas/vauban-finance.trade.executed.v1.d.ts +24 -0
  70. package/dist/events/schemas/vauban-finance.trade.executed.v1.d.ts.map +1 -0
  71. package/dist/events/schemas/vauban-finance.trade.executed.v1.js +12 -0
  72. package/dist/events/schemas/vauban-finance.trade.executed.v1.js.map +1 -0
  73. package/dist/events/schemas/vauban.goal.checked.v1.d.ts +21 -0
  74. package/dist/events/schemas/vauban.goal.checked.v1.d.ts.map +1 -0
  75. package/dist/events/schemas/vauban.goal.checked.v1.js +11 -0
  76. package/dist/events/schemas/vauban.goal.checked.v1.js.map +1 -0
  77. package/dist/events/schemas/vauban.rebalancing.checked.v1.d.ts +21 -0
  78. package/dist/events/schemas/vauban.rebalancing.checked.v1.d.ts.map +1 -0
  79. package/dist/events/schemas/vauban.rebalancing.checked.v1.js +11 -0
  80. package/dist/events/schemas/vauban.rebalancing.checked.v1.js.map +1 -0
  81. package/dist/events/schemas/vauban.tax.checked.v1.d.ts +21 -0
  82. package/dist/events/schemas/vauban.tax.checked.v1.d.ts.map +1 -0
  83. package/dist/events/schemas/vauban.tax.checked.v1.js +11 -0
  84. package/dist/events/schemas/vauban.tax.checked.v1.js.map +1 -0
  85. package/dist/events/schemas/vauban.vault.analyzed.v1.d.ts +59 -0
  86. package/dist/events/schemas/vauban.vault.analyzed.v1.d.ts.map +1 -0
  87. package/dist/events/schemas/vauban.vault.analyzed.v1.js +19 -0
  88. package/dist/events/schemas/vauban.vault.analyzed.v1.js.map +1 -0
  89. package/dist/events/schemas/vauban.vault.compounded.v1.d.ts +24 -0
  90. package/dist/events/schemas/vauban.vault.compounded.v1.d.ts.map +1 -0
  91. package/dist/events/schemas/vauban.vault.compounded.v1.js +12 -0
  92. package/dist/events/schemas/vauban.vault.compounded.v1.js.map +1 -0
  93. package/dist/identity/agent-persona.d.ts +73 -0
  94. package/dist/identity/agent-persona.d.ts.map +1 -0
  95. package/dist/identity/agent-persona.js +165 -0
  96. package/dist/identity/agent-persona.js.map +1 -0
  97. package/dist/identity/persona-prompt.d.ts +25 -0
  98. package/dist/identity/persona-prompt.d.ts.map +1 -0
  99. package/dist/identity/persona-prompt.js +71 -0
  100. package/dist/identity/persona-prompt.js.map +1 -0
  101. package/dist/identity/persona-schema.d.ts +120 -0
  102. package/dist/identity/persona-schema.d.ts.map +1 -0
  103. package/dist/identity/persona-schema.js +103 -0
  104. package/dist/identity/persona-schema.js.map +1 -0
  105. package/dist/index.d.ts +37 -2
  106. package/dist/index.d.ts.map +1 -1
  107. package/dist/index.js +29 -1
  108. package/dist/index.js.map +1 -1
  109. package/dist/loop/index.d.ts +1 -1
  110. package/dist/loop/index.d.ts.map +1 -1
  111. package/dist/loop/index.js.map +1 -1
  112. package/dist/loop/minimal-loop.js +293 -287
  113. package/dist/loop/sdk-loop.d.ts +1 -3
  114. package/dist/loop/sdk-loop.d.ts.map +1 -1
  115. package/dist/loop/sdk-loop.js +1 -1
  116. package/dist/loop/sdk-loop.js.map +1 -1
  117. package/dist/memory/episodic-rrf.d.ts +114 -0
  118. package/dist/memory/episodic-rrf.d.ts.map +1 -0
  119. package/dist/memory/episodic-rrf.js +148 -0
  120. package/dist/memory/episodic-rrf.js.map +1 -0
  121. package/dist/mesh/attenuation.d.ts +78 -0
  122. package/dist/mesh/attenuation.d.ts.map +1 -0
  123. package/dist/mesh/attenuation.js +141 -0
  124. package/dist/mesh/attenuation.js.map +1 -0
  125. package/dist/mesh/delegate.d.ts +96 -0
  126. package/dist/mesh/delegate.d.ts.map +1 -0
  127. package/dist/mesh/delegate.js +172 -0
  128. package/dist/mesh/delegate.js.map +1 -0
  129. package/dist/mesh/dispatcher.d.ts +119 -0
  130. package/dist/mesh/dispatcher.d.ts.map +1 -0
  131. package/dist/mesh/dispatcher.js +207 -0
  132. package/dist/mesh/dispatcher.js.map +1 -0
  133. package/dist/mesh/index.d.ts +12 -0
  134. package/dist/mesh/index.d.ts.map +1 -0
  135. package/dist/mesh/index.js +11 -0
  136. package/dist/mesh/index.js.map +1 -0
  137. package/dist/mesh/types.d.ts +30 -0
  138. package/dist/mesh/types.d.ts.map +1 -0
  139. package/dist/mesh/types.js +11 -0
  140. package/dist/mesh/types.js.map +1 -0
  141. package/dist/orchestration/ooda/skills.d.ts +104 -0
  142. package/dist/orchestration/ooda/skills.d.ts.map +1 -1
  143. package/dist/orchestration/ooda/skills.js +106 -0
  144. package/dist/orchestration/ooda/skills.js.map +1 -1
  145. package/dist/orchestration/ooda/types.d.ts +3 -8
  146. package/dist/orchestration/ooda/types.d.ts.map +1 -1
  147. package/dist/ports/bastion-action.contract.test.d.ts +11 -0
  148. package/dist/ports/bastion-action.contract.test.d.ts.map +1 -0
  149. package/dist/ports/bastion-action.contract.test.js +238 -0
  150. package/dist/ports/bastion-action.contract.test.js.map +1 -0
  151. package/dist/ports/bastion-action.d.ts +133 -0
  152. package/dist/ports/bastion-action.d.ts.map +1 -0
  153. package/dist/ports/bastion-action.js +73 -0
  154. package/dist/ports/bastion-action.js.map +1 -0
  155. package/dist/ports/brain.d.ts +31 -0
  156. package/dist/ports/brain.d.ts.map +1 -1
  157. package/dist/ports/brain.js +115 -1
  158. package/dist/ports/brain.js.map +1 -1
  159. package/dist/ports/citadel-action.contract.test.d.ts +11 -0
  160. package/dist/ports/citadel-action.contract.test.d.ts.map +1 -0
  161. package/dist/ports/citadel-action.contract.test.js +317 -0
  162. package/dist/ports/citadel-action.contract.test.js.map +1 -0
  163. package/dist/ports/citadel-action.d.ts +111 -0
  164. package/dist/ports/citadel-action.d.ts.map +1 -0
  165. package/dist/ports/citadel-action.js +62 -0
  166. package/dist/ports/citadel-action.js.map +1 -0
  167. package/dist/ports/compliance-contract.d.ts +123 -0
  168. package/dist/ports/compliance-contract.d.ts.map +1 -0
  169. package/dist/ports/compliance-contract.js +35 -0
  170. package/dist/ports/compliance-contract.js.map +1 -0
  171. package/dist/ports/db.d.ts +38 -0
  172. package/dist/ports/db.d.ts.map +1 -1
  173. package/dist/ports/db.js +88 -1
  174. package/dist/ports/db.js.map +1 -1
  175. package/dist/ports/delegation.contract.test.d.ts +9 -0
  176. package/dist/ports/delegation.contract.test.d.ts.map +1 -0
  177. package/dist/ports/delegation.contract.test.js +337 -0
  178. package/dist/ports/delegation.contract.test.js.map +1 -0
  179. package/dist/ports/delegation.d.ts +134 -0
  180. package/dist/ports/delegation.d.ts.map +1 -0
  181. package/dist/ports/delegation.js +105 -0
  182. package/dist/ports/delegation.js.map +1 -0
  183. package/dist/ports/event-bus.d.ts +29 -13
  184. package/dist/ports/event-bus.d.ts.map +1 -1
  185. package/dist/ports/event-bus.js +106 -1
  186. package/dist/ports/event-bus.js.map +1 -1
  187. package/dist/ports/federation.contract.test.d.ts +9 -0
  188. package/dist/ports/federation.contract.test.d.ts.map +1 -0
  189. package/dist/ports/federation.contract.test.js +279 -0
  190. package/dist/ports/federation.contract.test.js.map +1 -0
  191. package/dist/ports/federation.d.ts +140 -0
  192. package/dist/ports/federation.d.ts.map +1 -0
  193. package/dist/ports/federation.js +57 -0
  194. package/dist/ports/federation.js.map +1 -0
  195. package/dist/ports/index.d.ts +28 -2
  196. package/dist/ports/index.d.ts.map +1 -1
  197. package/dist/ports/index.js +17 -2
  198. package/dist/ports/index.js.map +1 -1
  199. package/dist/ports/llm-provider.d.ts +37 -0
  200. package/dist/ports/llm-provider.d.ts.map +1 -1
  201. package/dist/ports/llm-provider.js +99 -1
  202. package/dist/ports/llm-provider.js.map +1 -1
  203. package/dist/ports/logger.d.ts +27 -0
  204. package/dist/ports/logger.d.ts.map +1 -1
  205. package/dist/ports/logger.js +87 -0
  206. package/dist/ports/logger.js.map +1 -1
  207. package/dist/ports/manifest-registry.contract.test.d.ts +9 -0
  208. package/dist/ports/manifest-registry.contract.test.d.ts.map +1 -0
  209. package/dist/ports/manifest-registry.contract.test.js +246 -0
  210. package/dist/ports/manifest-registry.contract.test.js.map +1 -0
  211. package/dist/ports/manifest-registry.d.ts +116 -0
  212. package/dist/ports/manifest-registry.d.ts.map +1 -0
  213. package/dist/ports/manifest-registry.js +79 -0
  214. package/dist/ports/manifest-registry.js.map +1 -0
  215. package/dist/ports/observability.contract.test.d.ts +12 -0
  216. package/dist/ports/observability.contract.test.d.ts.map +1 -0
  217. package/dist/ports/observability.contract.test.js +260 -0
  218. package/dist/ports/observability.contract.test.js.map +1 -0
  219. package/dist/ports/observability.d.ts +98 -0
  220. package/dist/ports/observability.d.ts.map +1 -0
  221. package/dist/ports/observability.js +59 -0
  222. package/dist/ports/observability.js.map +1 -0
  223. package/dist/ports/outcome.d.ts +26 -0
  224. package/dist/ports/outcome.d.ts.map +1 -1
  225. package/dist/ports/outcome.js +62 -1
  226. package/dist/ports/outcome.js.map +1 -1
  227. package/dist/ports/privacy.contract.test.d.ts +12 -0
  228. package/dist/ports/privacy.contract.test.d.ts.map +1 -0
  229. package/dist/ports/privacy.contract.test.js +325 -0
  230. package/dist/ports/privacy.contract.test.js.map +1 -0
  231. package/dist/ports/privacy.d.ts +132 -0
  232. package/dist/ports/privacy.d.ts.map +1 -0
  233. package/dist/ports/privacy.js +83 -0
  234. package/dist/ports/privacy.js.map +1 -0
  235. package/dist/ports/tenant-context.contract.test.d.ts +14 -0
  236. package/dist/ports/tenant-context.contract.test.d.ts.map +1 -0
  237. package/dist/ports/tenant-context.contract.test.js +352 -0
  238. package/dist/ports/tenant-context.contract.test.js.map +1 -0
  239. package/dist/ports/tenant-context.d.ts +103 -0
  240. package/dist/ports/tenant-context.d.ts.map +1 -0
  241. package/dist/ports/tenant-context.js +48 -0
  242. package/dist/ports/tenant-context.js.map +1 -0
  243. package/dist/ports/vauban-finance-action.contract.test.d.ts +11 -0
  244. package/dist/ports/vauban-finance-action.contract.test.d.ts.map +1 -0
  245. package/dist/ports/vauban-finance-action.contract.test.js +260 -0
  246. package/dist/ports/vauban-finance-action.contract.test.js.map +1 -0
  247. package/dist/ports/vauban-finance-action.d.ts +106 -0
  248. package/dist/ports/vauban-finance-action.d.ts.map +1 -0
  249. package/dist/ports/vauban-finance-action.js +60 -0
  250. package/dist/ports/vauban-finance-action.js.map +1 -0
  251. package/dist/ports/workflow-runtime.d.ts +204 -0
  252. package/dist/ports/workflow-runtime.d.ts.map +1 -0
  253. package/dist/ports/workflow-runtime.js +72 -0
  254. package/dist/ports/workflow-runtime.js.map +1 -0
  255. package/dist/proof/cert-verify.d.ts +80 -0
  256. package/dist/proof/cert-verify.d.ts.map +1 -0
  257. package/dist/proof/cert-verify.js +178 -0
  258. package/dist/proof/cert-verify.js.map +1 -0
  259. package/dist/replay/replay.d.ts.map +1 -1
  260. package/dist/replay/replay.js +5 -1
  261. package/dist/replay/replay.js.map +1 -1
  262. package/dist/retry/index.d.ts +129 -0
  263. package/dist/retry/index.d.ts.map +1 -0
  264. package/dist/retry/index.js +156 -0
  265. package/dist/retry/index.js.map +1 -0
  266. package/dist/retry/presets.d.ts +39 -0
  267. package/dist/retry/presets.d.ts.map +1 -0
  268. package/dist/retry/presets.js +69 -0
  269. package/dist/retry/presets.js.map +1 -0
  270. package/dist/skill-loop/ab-runner.d.ts +67 -0
  271. package/dist/skill-loop/ab-runner.d.ts.map +1 -0
  272. package/dist/skill-loop/ab-runner.js +160 -0
  273. package/dist/skill-loop/ab-runner.js.map +1 -0
  274. package/dist/skill-loop/adoption.d.ts +67 -0
  275. package/dist/skill-loop/adoption.d.ts.map +1 -0
  276. package/dist/skill-loop/adoption.js +126 -0
  277. package/dist/skill-loop/adoption.js.map +1 -0
  278. package/dist/skill-loop/candidate.d.ts +45 -0
  279. package/dist/skill-loop/candidate.d.ts.map +1 -0
  280. package/dist/skill-loop/candidate.js +43 -0
  281. package/dist/skill-loop/candidate.js.map +1 -0
  282. package/dist/skill-loop/evaluator.d.ts +42 -0
  283. package/dist/skill-loop/evaluator.d.ts.map +1 -0
  284. package/dist/skill-loop/evaluator.js +184 -0
  285. package/dist/skill-loop/evaluator.js.map +1 -0
  286. package/dist/skill-loop/index.d.ts +27 -0
  287. package/dist/skill-loop/index.d.ts.map +1 -0
  288. package/dist/skill-loop/index.js +27 -0
  289. package/dist/skill-loop/index.js.map +1 -0
  290. package/dist/skill-loop/reflexion-replay.d.ts +87 -0
  291. package/dist/skill-loop/reflexion-replay.d.ts.map +1 -0
  292. package/dist/skill-loop/reflexion-replay.js +110 -0
  293. package/dist/skill-loop/reflexion-replay.js.map +1 -0
  294. package/dist/skill-loop/sign-off.d.ts +88 -0
  295. package/dist/skill-loop/sign-off.d.ts.map +1 -0
  296. package/dist/skill-loop/sign-off.js +146 -0
  297. package/dist/skill-loop/sign-off.js.map +1 -0
  298. package/dist/skill-loop/value-metric.d.ts +55 -0
  299. package/dist/skill-loop/value-metric.d.ts.map +1 -0
  300. package/dist/skill-loop/value-metric.js +69 -0
  301. package/dist/skill-loop/value-metric.js.map +1 -0
  302. package/dist/skill-loop/versioning.d.ts +36 -0
  303. package/dist/skill-loop/versioning.d.ts.map +1 -0
  304. package/dist/skill-loop/versioning.js +47 -0
  305. package/dist/skill-loop/versioning.js.map +1 -0
  306. package/dist/skill-manifest/anchor.d.ts +91 -0
  307. package/dist/skill-manifest/anchor.d.ts.map +1 -0
  308. package/dist/skill-manifest/anchor.js +331 -0
  309. package/dist/skill-manifest/anchor.js.map +1 -0
  310. package/dist/skill-manifest/builder.d.ts +47 -0
  311. package/dist/skill-manifest/builder.d.ts.map +1 -0
  312. package/dist/skill-manifest/builder.js +93 -0
  313. package/dist/skill-manifest/builder.js.map +1 -0
  314. package/dist/skill-manifest/index.d.ts +13 -0
  315. package/dist/skill-manifest/index.d.ts.map +1 -0
  316. package/dist/skill-manifest/index.js +9 -0
  317. package/dist/skill-manifest/index.js.map +1 -0
  318. package/dist/skill-manifest/types.d.ts +67 -0
  319. package/dist/skill-manifest/types.d.ts.map +1 -0
  320. package/dist/skill-manifest/types.js +16 -0
  321. package/dist/skill-manifest/types.js.map +1 -0
  322. package/dist/skill-manifest/verifier.d.ts +42 -0
  323. package/dist/skill-manifest/verifier.d.ts.map +1 -0
  324. package/dist/skill-manifest/verifier.js +136 -0
  325. package/dist/skill-manifest/verifier.js.map +1 -0
  326. package/dist/skills/brain-query.d.ts +4 -4
  327. package/dist/skills/brain-store.d.ts +6 -6
  328. package/dist/skills/errors.d.ts +15 -0
  329. package/dist/skills/errors.d.ts.map +1 -1
  330. package/dist/skills/errors.js +21 -0
  331. package/dist/skills/errors.js.map +1 -1
  332. package/dist/skills/hitl-request.d.ts +2 -2
  333. package/dist/skills/index.d.ts +3 -1
  334. package/dist/skills/index.d.ts.map +1 -1
  335. package/dist/skills/index.js +4 -1
  336. package/dist/skills/index.js.map +1 -1
  337. package/dist/skills/markdown/loader.d.ts +52 -0
  338. package/dist/skills/markdown/loader.d.ts.map +1 -0
  339. package/dist/skills/markdown/loader.js +93 -0
  340. package/dist/skills/markdown/loader.js.map +1 -0
  341. package/dist/skills/markdown/schema.d.ts +432 -0
  342. package/dist/skills/markdown/schema.d.ts.map +1 -0
  343. package/dist/skills/markdown/schema.js +121 -0
  344. package/dist/skills/markdown/schema.js.map +1 -0
  345. package/dist/skills/poc-md-loader/markdown-loader.d.ts +77 -0
  346. package/dist/skills/poc-md-loader/markdown-loader.d.ts.map +1 -0
  347. package/dist/skills/poc-md-loader/markdown-loader.js +125 -0
  348. package/dist/skills/poc-md-loader/markdown-loader.js.map +1 -0
  349. package/dist/skills/poc-md-loader/runner.d.ts +24 -0
  350. package/dist/skills/poc-md-loader/runner.d.ts.map +1 -0
  351. package/dist/skills/poc-md-loader/runner.js +57 -0
  352. package/dist/skills/poc-md-loader/runner.js.map +1 -0
  353. package/dist/skills/poc-md-loader/vitest.poc.config.d.ts +3 -0
  354. package/dist/skills/poc-md-loader/vitest.poc.config.d.ts.map +1 -0
  355. package/dist/skills/poc-md-loader/vitest.poc.config.js +13 -0
  356. package/dist/skills/poc-md-loader/vitest.poc.config.js.map +1 -0
  357. package/dist/skills/poc-md-loader/web-search/script.d.ts +33 -0
  358. package/dist/skills/poc-md-loader/web-search/script.d.ts.map +1 -0
  359. package/dist/skills/poc-md-loader/web-search/script.js +75 -0
  360. package/dist/skills/poc-md-loader/web-search/script.js.map +1 -0
  361. package/dist/skills/record-outcome.d.ts +4 -4
  362. package/dist/skills/send-email.d.ts.map +1 -1
  363. package/dist/skills/send-email.js +15 -3
  364. package/dist/skills/send-email.js.map +1 -1
  365. package/dist/skills/slack-notify.d.ts +4 -4
  366. package/dist/skills/starknet-balance.d.ts +1 -1
  367. package/dist/skills/telegram-notify.d.ts +4 -4
  368. package/dist/skills/web-search.d.ts +1 -1
  369. package/dist/testing/contracts/event-bus.contract.d.ts.map +1 -1
  370. package/dist/testing/contracts/event-bus.contract.js +14 -12
  371. package/dist/testing/contracts/event-bus.contract.js.map +1 -1
  372. package/dist/testing/index.d.ts +3 -0
  373. package/dist/testing/test-brain-port.d.ts +4 -0
  374. package/dist/testing/test-brain-port.d.ts.map +1 -1
  375. package/dist/testing/test-brain-port.js +75 -20
  376. package/dist/testing/test-brain-port.js.map +1 -1
  377. package/dist/testing/test-event-bus.d.ts.map +1 -1
  378. package/dist/testing/test-event-bus.js +89 -36
  379. package/dist/testing/test-event-bus.js.map +1 -1
  380. package/dist/trace/schema.d.ts +1 -1
  381. package/dist/trace/schema.d.ts.map +1 -1
  382. package/dist/trace/schema.js +1 -1
  383. package/dist/trace/schema.js.map +1 -1
  384. package/dist/verify/formal/index.d.ts +44 -0
  385. package/dist/verify/formal/index.d.ts.map +1 -0
  386. package/dist/verify/formal/index.js +98 -0
  387. package/dist/verify/formal/index.js.map +1 -0
  388. package/dist/verify/formal/policy.d.ts +105 -0
  389. package/dist/verify/formal/policy.d.ts.map +1 -0
  390. package/dist/verify/formal/policy.js +159 -0
  391. package/dist/verify/formal/policy.js.map +1 -0
  392. package/dist/verify/formal/result.d.ts +50 -0
  393. package/dist/verify/formal/result.d.ts.map +1 -0
  394. package/dist/verify/formal/result.js +21 -0
  395. package/dist/verify/formal/result.js.map +1 -0
  396. package/dist/verify/formal/solver.d.ts +67 -0
  397. package/dist/verify/formal/solver.d.ts.map +1 -0
  398. package/dist/verify/formal/solver.js +184 -0
  399. package/dist/verify/formal/solver.js.map +1 -0
  400. package/dist/verify/formal/spec-language.d.ts +80 -0
  401. package/dist/verify/formal/spec-language.d.ts.map +1 -0
  402. package/dist/verify/formal/spec-language.js +219 -0
  403. package/dist/verify/formal/spec-language.js.map +1 -0
  404. package/docs/attestation.md +199 -0
  405. package/docs/identity.md +193 -0
  406. package/package.json +22 -1
  407. package/src/adapters/llm/anthropic-direct.ts +51 -0
  408. package/src/adapters/llm/cascade.ts +64 -19
  409. package/src/adapters/llm/litellm.ts +49 -0
  410. package/src/compute/difficulty-estimator.ts +111 -0
  411. package/src/compute/strategies/mixture-of-agents.ts +150 -0
  412. package/src/compute/strategies/tree-of-thoughts.ts +293 -0
  413. package/src/compute/strategies/two-phase-orient.ts +147 -0
  414. package/src/container/protocol.ts +243 -0
  415. package/src/container/runtime.ts +424 -0
  416. package/src/db/migrations/026_formal_verify_results.sql +30 -0
  417. package/src/events/catalogue.ts +54 -0
  418. package/src/events/index.ts +9 -0
  419. package/src/events/schemas/citadel.sprint.analyzed.v1.ts +23 -0
  420. package/src/events/schemas/forge.inbox.reply_classified.v1.ts +15 -0
  421. package/src/events/schemas/vauban-finance.forecast.generated.v1.ts +11 -0
  422. package/src/events/schemas/vauban-finance.trade.executed.v1.ts +12 -0
  423. package/src/events/schemas/vauban.goal.checked.v1.ts +11 -0
  424. package/src/events/schemas/vauban.rebalancing.checked.v1.ts +11 -0
  425. package/src/events/schemas/vauban.tax.checked.v1.ts +11 -0
  426. package/src/events/schemas/vauban.vault.analyzed.v1.ts +21 -0
  427. package/src/events/schemas/vauban.vault.compounded.v1.ts +12 -0
  428. package/src/identity/agent-persona.ts +203 -0
  429. package/src/identity/persona-prompt.ts +84 -0
  430. package/src/identity/persona-schema.ts +127 -0
  431. package/src/index.ts +338 -1
  432. package/src/loop/index.ts +0 -1
  433. package/src/loop/sdk-loop.ts +5 -8
  434. package/src/memory/episodic-rrf.ts +224 -0
  435. package/src/mesh/attenuation.ts +190 -0
  436. package/src/mesh/delegate.ts +254 -0
  437. package/src/mesh/dispatcher.ts +301 -0
  438. package/src/mesh/index.ts +39 -0
  439. package/src/mesh/types.ts +31 -0
  440. package/src/orchestration/ooda/skills.ts +177 -0
  441. package/src/orchestration/ooda/types.ts +3 -9
  442. package/src/ports/bastion-action.contract.test.ts +355 -0
  443. package/src/ports/bastion-action.ts +198 -0
  444. package/src/ports/brain.ts +177 -15
  445. package/src/ports/citadel-action.contract.test.ts +430 -0
  446. package/src/ports/citadel-action.ts +174 -0
  447. package/src/ports/compliance-contract.ts +191 -0
  448. package/src/ports/db.ts +98 -0
  449. package/src/ports/delegation.contract.test.ts +428 -0
  450. package/src/ports/delegation.ts +211 -0
  451. package/src/ports/event-bus.ts +133 -18
  452. package/src/ports/federation.contract.test.ts +355 -0
  453. package/src/ports/federation.ts +190 -0
  454. package/src/ports/index.ts +186 -1
  455. package/src/ports/llm-provider.ts +123 -0
  456. package/src/ports/logger.ts +104 -0
  457. package/src/ports/manifest-registry.contract.test.ts +324 -0
  458. package/src/ports/manifest-registry.ts +188 -0
  459. package/src/ports/observability.contract.test.ts +315 -0
  460. package/src/ports/observability.ts +150 -0
  461. package/src/ports/outcome.ts +69 -0
  462. package/src/ports/privacy.contract.test.ts +413 -0
  463. package/src/ports/privacy.ts +207 -0
  464. package/src/ports/tenant-context.contract.test.ts +454 -0
  465. package/src/ports/tenant-context.ts +150 -0
  466. package/src/ports/vauban-finance-action.contract.test.ts +335 -0
  467. package/src/ports/vauban-finance-action.ts +166 -0
  468. package/src/ports/workflow-runtime.ts +327 -0
  469. package/src/proof/cert-verify.ts +249 -0
  470. package/src/replay/replay.ts +11 -8
  471. package/src/retry/index.ts +227 -0
  472. package/src/retry/presets.ts +75 -0
  473. package/src/skill-loop/ab-runner.ts +196 -0
  474. package/src/skill-loop/adoption.ts +188 -0
  475. package/src/skill-loop/candidate.ts +75 -0
  476. package/src/skill-loop/evaluator.ts +238 -0
  477. package/src/skill-loop/index.ts +51 -0
  478. package/src/skill-loop/reflexion-replay.ts +173 -0
  479. package/src/skill-loop/sign-off.ts +247 -0
  480. package/src/skill-loop/value-metric.ts +120 -0
  481. package/src/skill-loop/versioning.ts +75 -0
  482. package/src/skill-manifest/anchor.ts +401 -0
  483. package/src/skill-manifest/builder.ts +129 -0
  484. package/src/skill-manifest/index.ts +18 -0
  485. package/src/skill-manifest/types.ts +72 -0
  486. package/src/skill-manifest/verifier.ts +198 -0
  487. package/src/skills/errors.ts +30 -2
  488. package/src/skills/index.ts +19 -0
  489. package/src/skills/markdown/loader.ts +129 -0
  490. package/src/skills/markdown/schema.ts +144 -0
  491. package/src/skills/poc-md-loader/e2e-parity.test.ts +237 -0
  492. package/src/skills/poc-md-loader/markdown-loader.ts +161 -0
  493. package/src/skills/poc-md-loader/runner.ts +82 -0
  494. package/src/skills/poc-md-loader/vitest.poc.config.ts +13 -0
  495. package/src/skills/poc-md-loader/web-search/SKILL.md +42 -0
  496. package/src/skills/poc-md-loader/web-search/script.ts +109 -0
  497. package/src/skills/send-email.ts +15 -3
  498. package/src/testing/contracts/event-bus.contract.ts +16 -14
  499. package/src/testing/test-brain-port.ts +98 -24
  500. package/src/testing/test-event-bus.ts +104 -43
  501. package/src/trace/schema.ts +1 -1
  502. package/src/verify/formal/index.ts +154 -0
  503. package/src/verify/formal/policy.ts +253 -0
  504. package/src/verify/formal/result.ts +52 -0
  505. package/src/verify/formal/solver.ts +235 -0
  506. package/src/verify/formal/spec-language.ts +274 -0
@@ -0,0 +1,75 @@
1
+ /**
2
+ * src/skill-loop/candidate.ts
3
+ *
4
+ * Reflexion-style deterministic skill candidate extraction.
5
+ *
6
+ * Key invariant: extraction is deterministic — SHA-256(cycleId + domain) is the
7
+ * sole source of entropy. No LLM calls. Replay produces bit-identical output.
8
+ *
9
+ * @module skill-loop/candidate
10
+ */
11
+
12
+ import { sha256 } from "../proof/sha256.js";
13
+
14
+ // ---------------------------------------------------------------------------
15
+ // Types
16
+ // ---------------------------------------------------------------------------
17
+
18
+ export interface SkillCandidate {
19
+ /** Unique candidate ID: SHA-256(cycleId + domain) hex. */
20
+ id: string;
21
+ /** The cycle ID from which this candidate was extracted. */
22
+ extractedFrom: string;
23
+ /** Domain key e.g. "vault_rebalance", "cairo_audit". */
24
+ domain: string;
25
+ /** Extracted skill text — deterministic, NOT LLM-paraphrase. */
26
+ instructions: string;
27
+ /** Constitutional axiom score from the source cycle [0, 1]. */
28
+ constitutionalScore: number;
29
+ /** Outcome quality score from the source cycle [0, 1]. */
30
+ outcomeScore: number;
31
+ /** Semantic version, e.g. "1.0.0". */
32
+ version: string;
33
+ /** SHA-256 of the source cycle trace (replay root). */
34
+ replayRoot: string;
35
+ }
36
+
37
+ // ---------------------------------------------------------------------------
38
+ // Extraction
39
+ // ---------------------------------------------------------------------------
40
+
41
+ /**
42
+ * Extract a SkillCandidate from a high-scoring cycle's outcome text.
43
+ *
44
+ * Deterministic: SHA-256(cycleId + domain) seeded extraction, no LLM calls.
45
+ * Replay with the same arguments produces bit-identical output.
46
+ *
47
+ * @param cycleId - Source cycle identifier.
48
+ * @param instructions - Raw skill instructions text extracted from the cycle.
49
+ * @param domain - Domain key for the skill.
50
+ * @param scores - Constitutional and outcome scores from the cycle.
51
+ * @returns - Fully populated SkillCandidate (async due to SHA-256).
52
+ */
53
+ export async function extractCandidate(
54
+ cycleId: string,
55
+ instructions: string,
56
+ domain: string,
57
+ scores: { constitutional: number; outcome: number }
58
+ ): Promise<SkillCandidate> {
59
+ // Deterministic id: SHA-256(cycleId + ":" + domain)
60
+ const id = await sha256(`${cycleId}:${domain}`);
61
+
62
+ // replayRoot: SHA-256 of the full source context (cycle trace)
63
+ const replayRoot = await sha256(`${cycleId}:${domain}:${instructions}`);
64
+
65
+ return {
66
+ id,
67
+ extractedFrom: cycleId,
68
+ domain,
69
+ instructions,
70
+ constitutionalScore: scores.constitutional,
71
+ outcomeScore: scores.outcome,
72
+ version: "1.0.0",
73
+ replayRoot,
74
+ };
75
+ }
@@ -0,0 +1,238 @@
1
+ /**
2
+ * src/skill-loop/evaluator.ts
3
+ *
4
+ * Eval harness for SkillCandidates against a verifier set.
5
+ *
6
+ * Scoring is deterministic string-similarity (Jaccard token overlap).
7
+ * No LLM calls — consumer provides the executor function.
8
+ *
9
+ * Statistical significance: Welch's t-test (p < 0.05 AND delta >= 0.10).
10
+ *
11
+ * @module skill-loop/evaluator
12
+ */
13
+
14
+ import type { SkillCandidate } from "./candidate.js";
15
+
16
+ // ---------------------------------------------------------------------------
17
+ // Types
18
+ // ---------------------------------------------------------------------------
19
+
20
+ export interface VerifierExample {
21
+ input: string;
22
+ expectedOutput: string;
23
+ domain: string;
24
+ }
25
+
26
+ export interface EvalResult {
27
+ candidateId: string;
28
+ verifierSetSize: number;
29
+ meanScore: number;
30
+ stddev: number;
31
+ /** Fraction of examples where score >= 0.7 */
32
+ passRate: number;
33
+ incumbentMeanScore: number;
34
+ deltaVsIncumbent: number;
35
+ /** Welch's t-test p-value vs incumbent */
36
+ pValue: number;
37
+ /** true if p < 0.05 AND delta >= 0.10 */
38
+ significant: boolean;
39
+ }
40
+
41
+ // ---------------------------------------------------------------------------
42
+ // Similarity scoring — Jaccard token overlap (deterministic, no LLM)
43
+ // ---------------------------------------------------------------------------
44
+
45
+ function tokenize(text: string): Set<string> {
46
+ return new Set(
47
+ text
48
+ .toLowerCase()
49
+ .split(/\s+/)
50
+ .filter((t) => t.length > 0)
51
+ );
52
+ }
53
+
54
+ function jaccardScore(a: string, b: string): number {
55
+ const setA = tokenize(a);
56
+ const setB = tokenize(b);
57
+ if (setA.size === 0 && setB.size === 0) return 1.0;
58
+ if (setA.size === 0 || setB.size === 0) return 0.0;
59
+
60
+ let intersection = 0;
61
+ for (const token of setA) {
62
+ if (setB.has(token)) intersection++;
63
+ }
64
+ const union = setA.size + setB.size - intersection;
65
+ return intersection / union;
66
+ }
67
+
68
+ // ---------------------------------------------------------------------------
69
+ // Statistical helpers — Welch's t-test (two-sample, unequal variance)
70
+ // ---------------------------------------------------------------------------
71
+
72
+ function mean(xs: number[]): number {
73
+ if (xs.length === 0) return 0;
74
+ return xs.reduce((a, b) => a + b, 0) / xs.length;
75
+ }
76
+
77
+ function variance(xs: number[], m: number): number {
78
+ if (xs.length < 2) return 0;
79
+ return xs.reduce((acc, x) => acc + (x - m) ** 2, 0) / (xs.length - 1);
80
+ }
81
+
82
+ /**
83
+ * Welch's t-test — returns p-value (two-tailed approximation via t-distribution).
84
+ *
85
+ * Uses the Cornish-Fisher normal approximation for the CDF when df is large (>30).
86
+ * For small df we use a simple lookup table truncated at key quantiles.
87
+ * This is sufficient for the pass criterion (p < 0.05 threshold).
88
+ */
89
+ function welchPValue(
90
+ candidateScores: number[],
91
+ incumbentScores: number[]
92
+ ): number {
93
+ const n1 = candidateScores.length;
94
+ const n2 = incumbentScores.length;
95
+ if (n1 < 2 || n2 < 2) return 1.0;
96
+
97
+ const m1 = mean(candidateScores);
98
+ const m2 = mean(incumbentScores);
99
+ const v1 = variance(candidateScores, m1);
100
+ const v2 = variance(incumbentScores, m2);
101
+
102
+ const se = Math.sqrt(v1 / n1 + v2 / n2);
103
+ if (se === 0) return m1 === m2 ? 1.0 : 0.0;
104
+
105
+ const t = Math.abs((m1 - m2) / se);
106
+
107
+ // Welch–Satterthwaite degrees of freedom
108
+ const df =
109
+ (v1 / n1 + v2 / n2) ** 2 /
110
+ ((v1 / n1) ** 2 / (n1 - 1) + (v2 / n2) ** 2 / (n2 - 1));
111
+
112
+ // Approximation: for df >= 30 use standard normal; else conservative t lookup
113
+ if (df >= 30) {
114
+ // Two-tailed p using standard normal approximation
115
+ // p ≈ 2 * (1 - Φ(t)) where Φ is the standard normal CDF
116
+ const p = 2 * (1 - normalCdf(t));
117
+ return Math.max(0, Math.min(1, p));
118
+ }
119
+
120
+ // Conservative lookup table for small df — sufficient for p < 0.05 gate
121
+ // t-critical values at alpha=0.05 (two-tailed) by df (1..29)
122
+ const tCrit05: Record<number, number> = {
123
+ 1: 12.706,
124
+ 2: 4.303,
125
+ 3: 3.182,
126
+ 4: 2.776,
127
+ 5: 2.571,
128
+ 6: 2.447,
129
+ 7: 2.365,
130
+ 8: 2.306,
131
+ 9: 2.262,
132
+ 10: 2.228,
133
+ 11: 2.201,
134
+ 12: 2.179,
135
+ 13: 2.16,
136
+ 14: 2.145,
137
+ 15: 2.131,
138
+ 16: 2.12,
139
+ 17: 2.11,
140
+ 18: 2.101,
141
+ 19: 2.093,
142
+ 20: 2.086,
143
+ 25: 2.06,
144
+ 29: 2.045,
145
+ };
146
+ const dfInt = Math.max(1, Math.min(29, Math.round(df)));
147
+ // Find the nearest key
148
+ const keys = Object.keys(tCrit05)
149
+ .map(Number)
150
+ .sort((a, b) => a - b);
151
+ let nearest = keys[0];
152
+ for (const k of keys) {
153
+ if (k <= dfInt) nearest = k;
154
+ }
155
+ const crit = tCrit05[nearest] ?? 2.045;
156
+ // Return p < 0.05 signal: if t > crit → p < 0.05
157
+ return t > crit ? 0.04 : 0.1;
158
+ }
159
+
160
+ /**
161
+ * Standard normal CDF approximation (Hart algorithm, sufficient for p-value use).
162
+ */
163
+ function normalCdf(z: number): number {
164
+ const t = 1 / (1 + 0.2316419 * z);
165
+ const d = 0.3989423 * Math.exp((-z * z) / 2);
166
+ const p =
167
+ d *
168
+ t *
169
+ (0.3193815 +
170
+ t * (-0.3565638 + t * (1.7814779 + t * (-1.8212559 + t * 1.3302744))));
171
+ return 1 - p;
172
+ }
173
+
174
+ // ---------------------------------------------------------------------------
175
+ // Main evaluator
176
+ // ---------------------------------------------------------------------------
177
+
178
+ /**
179
+ * Evaluate a SkillCandidate against a verifier set.
180
+ *
181
+ * @param candidate - The skill candidate under evaluation.
182
+ * @param verifierSet - Ground-truth input/output pairs.
183
+ * @param incumbentScore - Mean score of the current production skill.
184
+ * @param executor - Runs the skill on an input, returns output.
185
+ */
186
+ export async function evaluateCandidate(
187
+ candidate: SkillCandidate,
188
+ verifierSet: VerifierExample[],
189
+ incumbentScore: number,
190
+ executor: (skill: string, input: string) => Promise<string>
191
+ ): Promise<EvalResult> {
192
+ if (verifierSet.length === 0) {
193
+ return {
194
+ candidateId: candidate.id,
195
+ verifierSetSize: 0,
196
+ meanScore: 0,
197
+ stddev: 0,
198
+ passRate: 0,
199
+ incumbentMeanScore: incumbentScore,
200
+ deltaVsIncumbent: -incumbentScore,
201
+ pValue: 1.0,
202
+ significant: false,
203
+ };
204
+ }
205
+
206
+ // Evaluate candidate on each example
207
+ const scores: number[] = await Promise.all(
208
+ verifierSet.map(async (example) => {
209
+ const actual = await executor(candidate.instructions, example.input);
210
+ return jaccardScore(actual, example.expectedOutput);
211
+ })
212
+ );
213
+
214
+ const m = mean(scores);
215
+ const v = variance(scores, m);
216
+ const stddev = Math.sqrt(v);
217
+ const passRate = scores.filter((s) => s >= 0.7).length / scores.length;
218
+ const delta = m - incumbentScore;
219
+
220
+ // Build synthetic incumbent scores for statistical test
221
+ // (treat incumbentScore as a constant distribution — one sample per example)
222
+ const incumbentScores = verifierSet.map(() => incumbentScore);
223
+
224
+ const pValue = welchPValue(scores, incumbentScores);
225
+ const significant = pValue < 0.05 && delta >= 0.1;
226
+
227
+ return {
228
+ candidateId: candidate.id,
229
+ verifierSetSize: verifierSet.length,
230
+ meanScore: m,
231
+ stddev,
232
+ passRate,
233
+ incumbentMeanScore: incumbentScore,
234
+ deltaVsIncumbent: delta,
235
+ pValue,
236
+ significant,
237
+ };
238
+ }
@@ -0,0 +1,51 @@
1
+ /**
2
+ * src/skill-loop/index.ts
3
+ *
4
+ * Barrel export for the skill-loop module.
5
+ *
6
+ * Pipeline: candidate → evaluator → ab-runner → sign-off → adoption
7
+ * Supporting: versioning, value-metric, reflexion-replay
8
+ *
9
+ * @module skill-loop
10
+ */
11
+
12
+ // ── Candidate extraction ──────────────────────────────────────────────────────
13
+ export { extractCandidate } from "./candidate.js";
14
+ export type { SkillCandidate } from "./candidate.js";
15
+
16
+ // ── Evaluator ─────────────────────────────────────────────────────────────────
17
+ export { evaluateCandidate } from "./evaluator.js";
18
+ export type { VerifierExample, EvalResult } from "./evaluator.js";
19
+
20
+ // ── A/B runner ────────────────────────────────────────────────────────────────
21
+ export { ABRunner } from "./ab-runner.js";
22
+ export type { ABConfig, ABSlot } from "./ab-runner.js";
23
+
24
+ // ── Sign-off (Art. 14 human oversight) ────────────────────────────────────────
25
+ export { SignOffManager } from "./sign-off.js";
26
+ export type {
27
+ SignOffDecision,
28
+ SignOffRecord,
29
+ PendingRequest,
30
+ } from "./sign-off.js";
31
+
32
+ // ── Adoption ──────────────────────────────────────────────────────────────────
33
+ export {
34
+ promoteCandidate,
35
+ rejectCandidate,
36
+ deprecateUnderperformers,
37
+ PromotionWithoutSignOffError,
38
+ } from "./adoption.js";
39
+ export type { AdoptionStatus, AdoptionRecord } from "./adoption.js";
40
+
41
+ // ── Versioning ────────────────────────────────────────────────────────────────
42
+ export { bumpVersion } from "./versioning.js";
43
+ export type { SkillVersion } from "./versioning.js";
44
+
45
+ // ── Value metric ──────────────────────────────────────────────────────────────
46
+ export { computeSkillValue, rankSkillsByValue } from "./value-metric.js";
47
+ export type { UsageEvent, SkillValueResult } from "./value-metric.js";
48
+
49
+ // ── Reflexion replay ──────────────────────────────────────────────────────────
50
+ export { ReflexionStore } from "./reflexion-replay.js";
51
+ export type { ReflexionEntry, ReplayResult } from "./reflexion-replay.js";
@@ -0,0 +1,173 @@
1
+ /**
2
+ * src/skill-loop/reflexion-replay.ts
3
+ *
4
+ * Deterministic reflexion storage and replay.
5
+ *
6
+ * Invariants:
7
+ * - Reflexion is stored as a deterministic hash, NOT an LLM paraphrase.
8
+ * - replay() with the same args produces bit-identical output every time.
9
+ * - The replay hash is SHA-256(skillId + ":" + domain + ":" + instructionsHash).
10
+ * - No LLM calls. Pure deterministic computation.
11
+ *
12
+ * @module skill-loop/reflexion-replay
13
+ */
14
+
15
+ import { createHash } from "node:crypto";
16
+
17
+ // ---------------------------------------------------------------------------
18
+ // Types
19
+ // ---------------------------------------------------------------------------
20
+
21
+ export interface ReflexionEntry {
22
+ /** Unique key for this reflexion: SHA-256(skillId + domain + instructionsHash). */
23
+ replayHash: string;
24
+ skillId: string;
25
+ domain: string;
26
+ /** SHA-256 of the raw instructions text. */
27
+ instructionsHash: string;
28
+ /** Deterministic lesson extracted from the reflexion cycle (NOT LLM paraphrase). */
29
+ lesson: string;
30
+ /** Constitutional axiom scores that triggered this reflexion. */
31
+ scores: { constitutional: number; outcome: number };
32
+ /** ISO-8601 timestamp of storage. */
33
+ storedAt: string;
34
+ }
35
+
36
+ export interface ReplayResult {
37
+ replayHash: string;
38
+ lesson: string;
39
+ scores: { constitutional: number; outcome: number };
40
+ /** True when the replay output is bit-identical to the stored entry. */
41
+ identical: boolean;
42
+ }
43
+
44
+ // ---------------------------------------------------------------------------
45
+ // Helpers
46
+ // ---------------------------------------------------------------------------
47
+
48
+ function sha256Hex(input: string): string {
49
+ return createHash("sha256").update(input, "utf8").digest("hex");
50
+ }
51
+
52
+ function computeReplayHash(
53
+ skillId: string,
54
+ domain: string,
55
+ instructionsHash: string
56
+ ): string {
57
+ return sha256Hex(`${skillId}:${domain}:${instructionsHash}`);
58
+ }
59
+
60
+ // ---------------------------------------------------------------------------
61
+ // ReflexionStore
62
+ // ---------------------------------------------------------------------------
63
+
64
+ /**
65
+ * In-memory deterministic reflexion store.
66
+ *
67
+ * In production, persist entries to the DB (table: skill_reflexions).
68
+ * This implementation is process-local and suitable for tests.
69
+ */
70
+ export class ReflexionStore {
71
+ private readonly entries = new Map<string, ReflexionEntry>();
72
+
73
+ // ── Store ──────────────────────────────────────────────────────────────────
74
+
75
+ /**
76
+ * Store a reflexion entry deterministically.
77
+ *
78
+ * The replayHash is computed solely from (skillId, domain, instructions) —
79
+ * no randomness, no timestamps in the hash computation.
80
+ * Idempotent: storing with the same inputs overwrites with bit-identical data.
81
+ *
82
+ * @param skillId - Skill identifier.
83
+ * @param domain - Domain key.
84
+ * @param instructions - Raw skill instructions (deterministic source).
85
+ * @param lesson - Extracted lesson (must be deterministic — NOT LLM output).
86
+ * @param scores - Constitutional and outcome scores.
87
+ * @param nowDate - Optional timestamp override for testing.
88
+ */
89
+ store(
90
+ skillId: string,
91
+ domain: string,
92
+ instructions: string,
93
+ lesson: string,
94
+ scores: { constitutional: number; outcome: number },
95
+ nowDate?: Date
96
+ ): ReflexionEntry {
97
+ const instructionsHash = sha256Hex(instructions);
98
+ const replayHash = computeReplayHash(skillId, domain, instructionsHash);
99
+
100
+ const entry: ReflexionEntry = {
101
+ replayHash,
102
+ skillId,
103
+ domain,
104
+ instructionsHash,
105
+ lesson,
106
+ scores,
107
+ storedAt: (nowDate ?? new Date()).toISOString(),
108
+ };
109
+
110
+ this.entries.set(replayHash, entry);
111
+ return entry;
112
+ }
113
+
114
+ // ── Replay ─────────────────────────────────────────────────────────────────
115
+
116
+ /**
117
+ * Replay a stored reflexion with the same arguments.
118
+ *
119
+ * Determinism guarantee: replay(skillId, domain, instructions) with the
120
+ * same inputs as the original store() call ALWAYS produces the same
121
+ * replayHash and lesson — bit-identical output.
122
+ *
123
+ * @returns ReplayResult with `identical: true` if the entry is found and
124
+ * the recomputed hash matches the stored replayHash.
125
+ */
126
+ replay(
127
+ skillId: string,
128
+ domain: string,
129
+ instructions: string
130
+ ): ReplayResult | null {
131
+ const instructionsHash = sha256Hex(instructions);
132
+ const replayHash = computeReplayHash(skillId, domain, instructionsHash);
133
+
134
+ const entry = this.entries.get(replayHash);
135
+ if (!entry) return null;
136
+
137
+ // Verify bit-identical determinism
138
+ const identical =
139
+ replayHash === entry.replayHash &&
140
+ instructionsHash === entry.instructionsHash;
141
+
142
+ return {
143
+ replayHash,
144
+ lesson: entry.lesson,
145
+ scores: entry.scores,
146
+ identical,
147
+ };
148
+ }
149
+
150
+ // ── Queries ────────────────────────────────────────────────────────────────
151
+
152
+ /** Retrieve an entry by its replay hash. */
153
+ get(replayHash: string): ReflexionEntry | null {
154
+ return this.entries.get(replayHash) ?? null;
155
+ }
156
+
157
+ /** List all stored entries for a given skill. */
158
+ listBySkill(skillId: string): ReflexionEntry[] {
159
+ return Array.from(this.entries.values()).filter(
160
+ (e) => e.skillId === skillId
161
+ );
162
+ }
163
+
164
+ /** Total number of stored entries. */
165
+ get size(): number {
166
+ return this.entries.size;
167
+ }
168
+
169
+ /** Clear all entries (useful for test isolation). */
170
+ clear(): void {
171
+ this.entries.clear();
172
+ }
173
+ }