chainlesschain 0.166.16 → 0.166.18

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 (223) hide show
  1. package/README.md +17 -10
  2. package/completions/_cc +1 -1
  3. package/completions/cc.bash +1 -1
  4. package/completions/cc.fish +1 -1
  5. package/completions/cc.ps1 +1 -1
  6. package/package.json +2 -2
  7. package/src/assets/web-panel/assets/{AIOps-CTxa2Wbq.js → AIOps-CQSBl3hY.js} +1 -1
  8. package/src/assets/web-panel/assets/{ActionButton-DHrQyYhy.js → ActionButton-IQt-vRLt.js} +1 -1
  9. package/src/assets/web-panel/assets/{Analytics-DQiUqcNl.js → Analytics-DkHC8O7k.js} +3 -3
  10. package/src/assets/web-panel/assets/{AppLayout-_Iz4r6wt.js → AppLayout-CSti2P2T.js} +5 -5
  11. package/src/assets/web-panel/assets/{Artifacts-BNs63YHo.js → Artifacts-C57hxn3v.js} +1 -1
  12. package/src/assets/web-panel/assets/{Audit-BgHIqRLn.js → Audit-DByLntcf.js} +1 -1
  13. package/src/assets/web-panel/assets/{BackgroundAgents-DUQ5axBB.js → BackgroundAgents-D1Bd2EOa.js} +1 -1
  14. package/src/assets/web-panel/assets/{Backup-CJ51E9Vw.js → Backup-VstHzHng.js} +1 -1
  15. package/src/assets/web-panel/assets/{BaseInput-o-5toA_R.js → BaseInput-CLhdexIf.js} +1 -1
  16. package/src/assets/web-panel/assets/{Chat-Cu7a-x1L.js → Chat-BefC_JZS.js} +6 -6
  17. package/src/assets/web-panel/assets/{ChatBubbleRenderer-BUyYkAXr.js → ChatBubbleRenderer-DbXMvgmn.js} +1 -1
  18. package/src/assets/web-panel/assets/{Checkbox-DwdmZ71L.js → Checkbox-CEY982vx.js} +1 -1
  19. package/src/assets/web-panel/assets/{Codegen-BrH2eYiP.js → Codegen-Dcm_DTvJ.js} +1 -1
  20. package/src/assets/web-panel/assets/{Col-BVJQEP2j.js → Col-C8SSu4KA.js} +1 -1
  21. package/src/assets/web-panel/assets/{Community-FGO3vZPq.js → Community-BVV9vwRR.js} +1 -1
  22. package/src/assets/web-panel/assets/{Compact-DYGAFVnT.js → Compact-B7c5Vo18.js} +1 -1
  23. package/src/assets/web-panel/assets/{Compliance-CRvc8Bdt.js → Compliance-Tq9jSZ5a.js} +1 -1
  24. package/src/assets/web-panel/assets/{Cowork-D6Ah2m7A.js → Cowork-BJUjT09Q.js} +3 -3
  25. package/src/assets/web-panel/assets/{Cron-AXbU2ifR.js → Cron-CjV9PEaS.js} +2 -2
  26. package/src/assets/web-panel/assets/{Crosschain-C5DXgEFd.js → Crosschain-Dl7ReL8F.js} +1 -1
  27. package/src/assets/web-panel/assets/{DID-Bxh9QV9v.js → DID-CG8PjWmM.js} +2 -2
  28. package/src/assets/web-panel/assets/{Dashboard-B-ZHEta-.js → Dashboard-CDBM6wmF.js} +2 -2
  29. package/src/assets/web-panel/assets/{Dropdown-66Ik1jqa.js → Dropdown-8_55bXTD.js} +1 -1
  30. package/src/assets/web-panel/assets/{EmailListRenderer-CCWk1BIM.js → EmailListRenderer-D3qOU1Cm.js} +1 -1
  31. package/src/assets/web-panel/assets/{FamilyGuardDashboard--9faIULK.js → FamilyGuardDashboard-Bv5oWMZF.js} +1 -1
  32. package/src/assets/web-panel/assets/{Federation-CejW9CgX.js → Federation-hpZ1xkKd.js} +1 -1
  33. package/src/assets/web-panel/assets/{FormItemContext-acHgcXki.js → FormItemContext-BN7GT191.js} +1 -1
  34. package/src/assets/web-panel/assets/{GenericCardRenderer-D2ghd_K4.js → GenericCardRenderer-PCRhfA7M.js} +1 -1
  35. package/src/assets/web-panel/assets/{Git-BOe1YJrV.js → Git-CIlP2vy7.js} +2 -2
  36. package/src/assets/web-panel/assets/{Governance-BjgzJsof.js → Governance-81lgm7YL.js} +1 -1
  37. package/src/assets/web-panel/assets/{Inference-CXCD5rnP.js → Inference-Cs24xMOV.js} +1 -1
  38. package/src/assets/web-panel/assets/{KnowledgeGraph-CHA8QgJT.js → KnowledgeGraph-CrJLVCZo.js} +1 -1
  39. package/src/assets/web-panel/assets/{Logs-DORPMcL6.js → Logs-DLyO8RKT.js} +2 -2
  40. package/src/assets/web-panel/assets/{MarkdownRenderer-CPPHz01z.js → MarkdownRenderer-DBOqijrP.js} +1 -1
  41. package/src/assets/web-panel/assets/{Marketplace-BCFlo1Yx.js → Marketplace-Dz7AbQZc.js} +1 -1
  42. package/src/assets/web-panel/assets/{McpTools-Dl_uZAKh.js → McpTools-BM0aFiWv.js} +3 -3
  43. package/src/assets/web-panel/assets/{Memory-DupHamwz.js → Memory-C9SJzENX.js} +2 -2
  44. package/src/assets/web-panel/assets/{MobileBridge-BRSMPJxW.js → MobileBridge-BO2HnNRk.js} +1 -1
  45. package/src/assets/web-panel/assets/{MobileProjects-BHpuzsDl.js → MobileProjects-CK_jMz0l.js} +1 -1
  46. package/src/assets/web-panel/assets/{Mtc-Ch0jOQfZ.js → Mtc-CfhrJsdO.js} +2 -2
  47. package/src/assets/web-panel/assets/{MtcAudit-qzwQrDi7.js → MtcAudit-BE2ELxgI.js} +4 -4
  48. package/src/assets/web-panel/assets/{Multisig-B5wHzUcm.js → Multisig-CgR_E3Jd.js} +3 -3
  49. package/src/assets/web-panel/assets/{NLProgramming-Hy9uAiA0.js → NLProgramming-Cw9445_K.js} +1 -1
  50. package/src/assets/web-panel/assets/{Notes-DkuchMC7.js → Notes-DZimkTrb.js} +3 -3
  51. package/src/assets/web-panel/assets/{NotificationSettings-CYZhD7Pi.js → NotificationSettings-DxHVh4uT.js} +1 -1
  52. package/src/assets/web-panel/assets/{OrderTableRenderer-DKOoqajt.js → OrderTableRenderer-Iy-pnX56.js} +1 -1
  53. package/src/assets/web-panel/assets/{Organization-D9AXn6j8.js → Organization-pPXJtWo4.js} +4 -4
  54. package/src/assets/web-panel/assets/{Overflow-Bg15J6hX.js → Overflow-YamdTJwA.js} +1 -1
  55. package/src/assets/web-panel/assets/{P2P--B54HoQn.js → P2P-BvqP53x7.js} +2 -2
  56. package/src/assets/web-panel/assets/{PdhVaultBrowser-Cz9Kk2Nb.js → PdhVaultBrowser-Blz1Xn2n.js} +3 -3
  57. package/src/assets/web-panel/assets/{Permissions-DHx38eS1.js → Permissions-CgFRQqFJ.js} +4 -4
  58. package/src/assets/web-panel/assets/{PersonalDataHub-Dw8i2hAs.js → PersonalDataHub-CFeo3-6O.js} +4 -4
  59. package/src/assets/web-panel/assets/{Pipeline-B2o6Ur2G.js → Pipeline-BkaRojEK.js} +1 -1
  60. package/src/assets/web-panel/assets/{Privacy-8g-h2fnu.js → Privacy-BNZEx2Qp.js} +1 -1
  61. package/src/assets/web-panel/assets/{ProjectInit-DuVTcINx.js → ProjectInit-HUBOgEEK.js} +2 -2
  62. package/src/assets/web-panel/assets/{ProjectSettings-C8njvdZX.js → ProjectSettings-CFMmhROS.js} +2 -2
  63. package/src/assets/web-panel/assets/Projects-Dc517BXp.js +1 -0
  64. package/src/assets/web-panel/assets/{Providers-wFqgod_W.js → Providers-DTLf8bgj.js} +1 -1
  65. package/src/assets/web-panel/assets/{QrScannerModal-9NCXrpmA.js → QrScannerModal-BBNjPszk.js} +1 -1
  66. package/src/assets/web-panel/assets/{QuickAsk-WUTNvFkY.js → QuickAsk-DCsHvk3G.js} +1 -1
  67. package/src/assets/web-panel/assets/{Recommend-xT4nYmju.js → Recommend-Dpr5YSop.js} +1 -1
  68. package/src/assets/web-panel/assets/{RemoteSession-fak1PBGC.js → RemoteSession-DmKnvqGg.js} +2 -2
  69. package/src/assets/web-panel/assets/{Reputation-D1AkQvD-.js → Reputation-CSRfuurX.js} +1 -1
  70. package/src/assets/web-panel/assets/{Row-DVfm6xGt.js → Row-CDj3pQ_w.js} +1 -1
  71. package/src/assets/web-panel/assets/{RssFeed-BDunoLSE.js → RssFeed-DI0a_kNq.js} +2 -2
  72. package/src/assets/web-panel/assets/{Search-OPycRoU3.js → Search-jAy7B2nU.js} +1 -1
  73. package/src/assets/web-panel/assets/{Security-C8-Fm3Dt.js → Security-CkHTqYhc.js} +4 -4
  74. package/src/assets/web-panel/assets/{Services-qM_sMpMl.js → Services-CP-0Nzga.js} +2 -2
  75. package/src/assets/web-panel/assets/{Skeleton-D3HBJjVF.js → Skeleton-BkF5-p3n.js} +1 -1
  76. package/src/assets/web-panel/assets/{Skills-jr67X-tP.js → Skills-BDu-utDE.js} +1 -1
  77. package/src/assets/web-panel/assets/{Sla-CS3ggyCg.js → Sla-CQvq_2Qb.js} +1 -1
  78. package/src/assets/web-panel/assets/{SpeechSettings-CTOCYxOi.js → SpeechSettings-T7Ap512g.js} +1 -1
  79. package/src/assets/web-panel/assets/{SyncSettings-D3s3cLT5.js → SyncSettings-Bt-PLvot.js} +2 -2
  80. package/src/assets/web-panel/assets/{Tasks-CdfoJ25m.js → Tasks-yLEcCogg.js} +1 -1
  81. package/src/assets/web-panel/assets/{Templates-Drb4AI8X.js → Templates-ByN3fmbr.js} +1 -1
  82. package/src/assets/web-panel/assets/{Tenant-DzwR3Qkz.js → Tenant-DBI7hITH.js} +1 -1
  83. package/src/assets/web-panel/assets/{Terminal-D-ESq7xp.js → Terminal-B77_DlGX.js} +2 -2
  84. package/src/assets/web-panel/assets/{TimelineRenderer-BK-AUuws.js → TimelineRenderer-CsLTB_QO.js} +1 -1
  85. package/src/assets/web-panel/assets/{Tokens-xGTouuNp.js → Tokens-BV2N6cR8.js} +1 -1
  86. package/src/assets/web-panel/assets/{Trigger-BvZj-v2H.js → Trigger-CjXWGH3p.js} +1 -1
  87. package/src/assets/web-panel/assets/{Trust-BLC9CGmc.js → Trust-uqXIq3WC.js} +1 -1
  88. package/src/assets/web-panel/assets/{UkeySign-BSuCXpmE.js → UkeySign-D-6qu4vY.js} +1 -1
  89. package/src/assets/web-panel/assets/{VideoEditing-DT3A-_Ql.js → VideoEditing-CxGmx_2e.js} +1 -1
  90. package/src/assets/web-panel/assets/{Wallet-c1OXao85.js → Wallet-DSq7WlAg.js} +4 -4
  91. package/src/assets/web-panel/assets/{WebAuthn-CuA-F7KJ.js → WebAuthn-CDBiD57O.js} +2 -2
  92. package/src/assets/web-panel/assets/{WorkflowEditor-MANZrf82.js → WorkflowEditor-Z8f63TSb.js} +1 -1
  93. package/src/assets/web-panel/assets/{chat-D4Y4Ey0O.js → chat-B-UZFBjy.js} +1 -1
  94. package/src/assets/web-panel/assets/{colors-DDH06hKO.js → colors-CFk7K-7Q.js} +1 -1
  95. package/src/assets/web-panel/assets/{compact-item-Cym756Xj.js → compact-item-X0IVMvgi.js} +1 -1
  96. package/src/assets/web-panel/assets/{createContext-By4Nb1k-.js → createContext-DWg4j2n6.js} +1 -1
  97. package/src/assets/web-panel/assets/devWarning-B2IW1J_J.js +1 -0
  98. package/src/assets/web-panel/assets/{hasIn-Ch7OY258.js → hasIn-CkVCwNNF.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-D9le0-dc.js → index-5OcZHdzc.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-CykROEJA.js → index-B273IY-E.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-DjwgJ5Jd.js → index-B3-B3FWD.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-CjNUTBwe.js → index-BB4KHHcv.js} +1 -1
  103. package/src/assets/web-panel/assets/index-BCp2ir-1.js +1 -0
  104. package/src/assets/web-panel/assets/{index-BFydNU6a.js → index-BG-GaZri.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-mL3nOcH6.js → index-BPBia4b-.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-XGeQMvWK.js → index-BipwEbTA.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-D5sADPGY.js → index-BoskgPt9.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-CV8qXTvb.js → index-Btqk6zWb.js} +1 -1
  109. package/src/assets/web-panel/assets/index-Bw4iuzRD.js +1 -0
  110. package/src/assets/web-panel/assets/{index-CJPks33Y.js → index-BzXjYUmd.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-BBBUn5v7.js → index-C1ZAOJRW.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-DiewptTL.js → index-CCLwoATF.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-OU8DZ9BL.js → index-CDfSD07S.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-DvnywwUj.js → index-CLlP1E4X.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-CT-3FYwd.js → index-CMCEXBRh.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-tZ5BUdad.js → index-CN8HZlLH.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-DNlxihs8.js → index-CNKFsBlz.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-CF3Lhyns.js → index-CUBkvFPH.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-CV1UC4zo.js → index-Ca0mij1n.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-DAkk1M7x.js → index-CbIAWbma.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-DNEJzc0r.js → index-CbihMThv.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-q-s04OKn.js → index-CvOa-IFV.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-BZB9q-Lp.js → index-Cvwu_rA_.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-oBsfUbyH.js → index-D-EJNxgR.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-ZY2Qs_Sn.js → index-D8uEL8Uw.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-DtGValNi.js → index-D92g4l3n.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-CpudmDhf.js → index-DCqpl_E_.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-Bo20BfdS.js → index-DLSBks8h.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-CUSUzaB8.js → index-Db_5xhrU.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-CZn6dmZe.js → index-DcDggpWR.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-CGsvEbbq.js → index-DeWKPQGs.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-jx7kr6mB.js → index-DhVHoqGL.js} +3 -3
  133. package/src/assets/web-panel/assets/{index-BIrRX-ra.js → index-DyWlOuak.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-6CpOV3Pn.js → index-LU54bChK.js} +1 -1
  135. package/src/assets/web-panel/assets/{index-6-2eYBXr.js → index-OjnAwUJo.js} +1 -1
  136. package/src/assets/web-panel/assets/{index-B51otVoZ.js → index-P83LDnCz.js} +1 -1
  137. package/src/assets/web-panel/assets/{index-ArMrnx0v.js → index-_-9k3Tna.js} +1 -1
  138. package/src/assets/web-panel/assets/{initDefaultProps-DGcX9iPP.js → initDefaultProps-CFNgY8lJ.js} +1 -1
  139. package/src/assets/web-panel/assets/{motion-2SeL1D8A.js → motion-D-5RrDzn.js} +1 -1
  140. package/src/assets/web-panel/assets/{move-3cYbQCpS.js → move-DN-L0Bd-.js} +1 -1
  141. package/src/assets/web-panel/assets/{mtc-parser-IDdxfw0z.js → mtc-parser-6mgLSeCK.js} +1 -1
  142. package/src/assets/web-panel/assets/{omit-BNswdKO6.js → omit-ClWW8eTP.js} +1 -1
  143. package/src/assets/web-panel/assets/{pickAttrs-BwCnem2I.js → pickAttrs-Vystq3R8.js} +1 -1
  144. package/src/assets/web-panel/assets/{placementArrow-B9PtZ5rq.js → placementArrow-D0H9hK4W.js} +1 -1
  145. package/src/assets/web-panel/assets/{responsiveObserve-CPB6iSzV.js → responsiveObserve-B3iNRU-a.js} +1 -1
  146. package/src/assets/web-panel/assets/{slide-DZgyblZa.js → slide-CiMXe6am.js} +1 -1
  147. package/src/assets/web-panel/assets/{statusUtils-D82IBdsx.js → statusUtils-CGDZJ1uT.js} +1 -1
  148. package/src/assets/web-panel/assets/{styleChecker-qSHtosM-.js → styleChecker-D2zA6NkY.js} +1 -1
  149. package/src/assets/web-panel/assets/{useFlexGapSupport-CmWO7h0I.js → useFlexGapSupport-C1sYU6QE.js} +1 -1
  150. package/src/assets/web-panel/assets/{useFs-yLrs_ub4.js → useFs-BzUHSjg2.js} +1 -1
  151. package/src/assets/web-panel/assets/{usePersonalDataHub-CJ1VW6rh.js → usePersonalDataHub-CxB5yZCq.js} +1 -1
  152. package/src/assets/web-panel/assets/{vnode-CzY_moQ4.js → vnode-BfUfMwtc.js} +1 -1
  153. package/src/assets/web-panel/assets/{zoom-DAa7rEY5.js → zoom-CFYmj1TO.js} +1 -1
  154. package/src/assets/web-panel/index.html +1 -1
  155. package/src/command-help-index.json +2 -2
  156. package/src/command-manifest.json +2 -2
  157. package/src/commands/agent.js +80 -2
  158. package/src/commands/evolution.js +61 -42
  159. package/src/commands/learning.js +24 -8
  160. package/src/commands/serve.js +11 -2
  161. package/src/data/changelog.json +13 -0
  162. package/src/gateways/ws/session-protocol.js +1 -0
  163. package/src/gateways/ws/ws-agent-handler.js +70 -2
  164. package/src/gateways/ws/ws-server.js +8 -0
  165. package/src/lib/app-server/cli-agent-kernel-adapter.js +4 -0
  166. package/src/lib/app-server/graph-runtime.js +115 -8
  167. package/src/lib/app-server/server.js +21 -2
  168. package/src/lib/app-server/websocket-transport.js +2 -0
  169. package/src/lib/evolution/agent-evolution-ingress.js +300 -0
  170. package/src/lib/evolution/agent-evolution-runtime-composition-brand.js +22 -0
  171. package/src/lib/evolution/agent-evolution-runtime-composition.js +369 -0
  172. package/src/lib/evolution/bounded-skill-improvement-pilot.js +498 -0
  173. package/src/lib/evolution/evidence-backed-wiki-maintainer.js +752 -0
  174. package/src/lib/evolution/evolution-artifact-ports.js +48 -0
  175. package/src/lib/evolution/evolution-eval-gate.js +11 -4
  176. package/src/lib/evolution/evolution-evidence-artifact-adapter.js +499 -0
  177. package/src/lib/evolution/evolution-evidence-projector.js +61 -1
  178. package/src/lib/evolution/evolution-file-witness.js +601 -0
  179. package/src/lib/evolution/evolution-ledger-file-backend.js +176 -0
  180. package/src/lib/evolution/evolution-ledger-ports.js +353 -16
  181. package/src/lib/evolution/evolution-ledger.js +1355 -54
  182. package/src/lib/evolution/evolution-run-ledger-adapter.js +409 -0
  183. package/src/lib/evolution/evolution-run-runtime-adapter.js +5 -0
  184. package/src/lib/evolution/evolution-run-wiki-maintenance-source.js +300 -0
  185. package/src/lib/evolution/scheduled-batch-wiki-maintenance-source.js +368 -0
  186. package/src/lib/evolution/skill-candidate-registry.js +649 -0
  187. package/src/lib/evolution/skill-evaluated-promotion-durability.js +899 -0
  188. package/src/lib/evolution/skill-evaluated-promotion.js +481 -0
  189. package/src/lib/evolution/skill-promotion-controller.js +220 -37
  190. package/src/lib/evolution/skill-promotion-review-ledger-adapter.js +451 -0
  191. package/src/lib/evolution/skill-promotion-review.js +793 -0
  192. package/src/lib/evolution/skill-registry-transition-capability.js +55 -0
  193. package/src/lib/evolution/skill-registry-transition-ledger-adapter.js +1280 -0
  194. package/src/lib/evolution/skill-registry-transition-source.js +372 -0
  195. package/src/lib/evolution/skill-release-registry.js +2191 -11
  196. package/src/lib/evolution/skill-target-matrix-eval.js +133 -10
  197. package/src/lib/evolution/structured-memory-agent-control-plane.js +222 -0
  198. package/src/lib/evolution/structured-memory-authority-ledger-adapter.js +351 -0
  199. package/src/lib/evolution/structured-memory-ledger-adapter.js +220 -0
  200. package/src/lib/evolution/structured-memory-policy-receipt-writer.js +164 -0
  201. package/src/lib/evolution/structured-memory-post-compact-hook.js +87 -0
  202. package/src/lib/evolution/structured-memory-promotion-receipt-writer.js +221 -0
  203. package/src/lib/evolution/structured-memory-semantic-review-pipeline.js +313 -0
  204. package/src/lib/evolution/wiki-informed-skill-proposer.js +343 -0
  205. package/src/lib/evolution/wiki-maintainer-ledger-adapter.js +200 -0
  206. package/src/lib/evolution/wiki-maintenance-trigger-ledger-adapter.js +687 -0
  207. package/src/lib/evolution-system.js +65 -30
  208. package/src/lib/graph-kernel/evolution-run-runtime-adapter.js +5 -0
  209. package/src/lib/hooks-v2-runtime.js +20 -0
  210. package/src/lib/mcp-lifecycle-authority.js +21 -2
  211. package/src/lib/remote-approval-bridge.js +24 -0
  212. package/src/lib/scheduler-kernel/store.js +62 -14
  213. package/src/repl/agent-repl.js +45 -0
  214. package/src/runtime/agent-core.js +68 -0
  215. package/src/runtime/agent-runtime.js +114 -1
  216. package/src/runtime/headless-runner.js +19 -0
  217. package/src/runtime/headless-stream.js +43 -0
  218. package/src/runtime/runtime-factory.js +19 -1
  219. package/src/assets/web-panel/assets/Projects-Ca9BAfu7.js +0 -1
  220. package/src/assets/web-panel/assets/devWarning-KO3pAGeO.js +0 -1
  221. package/src/assets/web-panel/assets/index-Bh4Rgkg2.js +0 -1
  222. package/src/assets/web-panel/assets/index-Dox_coTY.js +0 -1
  223. package/src/lib/learning/learning-hooks.js +0 -123
@@ -0,0 +1,409 @@
1
+ import evolutionRun from "@chainlesschain/session-core/evolution-run";
2
+
3
+ import {
4
+ EVOLUTION_DURABLE_ARTIFACT_RECORD_SCHEMA,
5
+ isEvolutionLedgerArtifactResolver,
6
+ } from "./evolution-artifact-ports.js";
7
+ import {
8
+ EVOLUTION_ARTIFACT_RESOLUTION_SCHEMA,
9
+ EVOLUTION_LEDGER_DOMAIN_EVENT_SCHEMA,
10
+ } from "./evolution-ledger.js";
11
+
12
+ const { EVENT_TYPES, projectEvolutionRun } = evolutionRun;
13
+
14
+ export const EVOLUTION_RUN_LEDGER_EVENT_TYPE = "evolution.run.event.committed";
15
+ export const EVOLUTION_RUN_LEDGER_CONFLICT_CODE =
16
+ "CC_EVOLUTION_RUN_LEDGER_CONFLICT";
17
+ export const EVOLUTION_RUN_LEDGER_CORRUPT_CODE =
18
+ "CC_EVOLUTION_RUN_LEDGER_CORRUPT";
19
+
20
+ const ARTIFACT_TYPE = "evolution-run-event";
21
+ const DIGEST = /^sha256:[a-f0-9]{64}$/u;
22
+ const EVENT_KEYS = new Set([
23
+ "schema",
24
+ "tenantId",
25
+ "runId",
26
+ "eventId",
27
+ "sequence",
28
+ "type",
29
+ "subjectId",
30
+ "payloadDigest",
31
+ "artifactRef",
32
+ "keyRef",
33
+ "data",
34
+ ]);
35
+
36
+ function requiredString(value, label) {
37
+ if (typeof value !== "string" || value.trim() === "") {
38
+ throw new TypeError(`${label} is required`);
39
+ }
40
+ return value;
41
+ }
42
+
43
+ function fail(code, message, options) {
44
+ const error = new Error(message, options);
45
+ error.code = code;
46
+ throw error;
47
+ }
48
+
49
+ function capture(owner, method, label = method) {
50
+ if (typeof owner?.[method] !== "function") {
51
+ throw new TypeError(`${label} port is required`);
52
+ }
53
+ const fn = owner[method];
54
+ return (...args) => Reflect.apply(fn, owner, args);
55
+ }
56
+
57
+ function canonical(value) {
58
+ if (value === null || typeof value !== "object") {
59
+ return JSON.stringify(value);
60
+ }
61
+ if (Array.isArray(value)) {
62
+ return `[${value.map(canonical).join(",")}]`;
63
+ }
64
+ return `{${Object.keys(value)
65
+ .sort()
66
+ .map((key) => `${JSON.stringify(key)}:${canonical(value[key])}`)
67
+ .join(",")}}`;
68
+ }
69
+
70
+ function clone(value) {
71
+ return JSON.parse(canonical(value));
72
+ }
73
+
74
+ function same(left, right) {
75
+ return canonical(left) === canonical(right);
76
+ }
77
+
78
+ function normalizeDescriptor(input) {
79
+ return Object.freeze({
80
+ tenantId: requiredString(input?.tenantId, "tenantId"),
81
+ artifactTenantId: requiredString(
82
+ input?.artifactTenantId,
83
+ "artifactTenantId",
84
+ ),
85
+ runId: requiredString(input?.runId, "runId"),
86
+ audience: requiredString(input?.audience, "audience"),
87
+ purpose: requiredString(input?.purpose, "purpose"),
88
+ });
89
+ }
90
+
91
+ function normalizeEvent(input, descriptor) {
92
+ if (
93
+ !input ||
94
+ typeof input !== "object" ||
95
+ Array.isArray(input) ||
96
+ Reflect.ownKeys(input).length !== EVENT_KEYS.size ||
97
+ Reflect.ownKeys(input).some(
98
+ (key) => typeof key !== "string" || !EVENT_KEYS.has(key),
99
+ )
100
+ ) {
101
+ throw new TypeError("EvolutionRun event contains unsupported fields");
102
+ }
103
+ const event = clone(input);
104
+ projectEvolutionRun([event], {
105
+ tenantId: descriptor.tenantId,
106
+ runId: descriptor.runId,
107
+ });
108
+ return Object.freeze(event);
109
+ }
110
+
111
+ function parseRecord(resolution, descriptor) {
112
+ if (
113
+ resolution?.schema !== EVOLUTION_ARTIFACT_RESOLUTION_SCHEMA ||
114
+ resolution.authenticated !== true ||
115
+ resolution.found !== true ||
116
+ !DIGEST.test(resolution.digest ?? "") ||
117
+ !DIGEST.test(resolution.receiptDigest ?? "") ||
118
+ !Buffer.isBuffer(resolution.bytes)
119
+ ) {
120
+ fail(
121
+ EVOLUTION_RUN_LEDGER_CORRUPT_CODE,
122
+ "EvolutionRun artifact resolution is unauthenticated or incomplete",
123
+ );
124
+ }
125
+ let record;
126
+ try {
127
+ record = JSON.parse(resolution.bytes.toString("utf8"));
128
+ } catch {
129
+ fail(
130
+ EVOLUTION_RUN_LEDGER_CORRUPT_CODE,
131
+ "EvolutionRun artifact is not canonical JSON",
132
+ );
133
+ }
134
+ if (
135
+ record?.schema !== EVOLUTION_DURABLE_ARTIFACT_RECORD_SCHEMA ||
136
+ record.tenantId !== descriptor.artifactTenantId ||
137
+ record.audience !== descriptor.audience ||
138
+ record.purpose !== descriptor.purpose ||
139
+ record.retention !== "ledger" ||
140
+ record.type !== ARTIFACT_TYPE
141
+ ) {
142
+ fail(
143
+ EVOLUTION_RUN_LEDGER_CORRUPT_CODE,
144
+ "EvolutionRun artifact durable binding is invalid",
145
+ );
146
+ }
147
+ return normalizeEvent(record.value, descriptor);
148
+ }
149
+
150
+ export class EvolutionRunLedgerAdapter {
151
+ constructor({
152
+ descriptor: input,
153
+ artifactPorts,
154
+ ledger,
155
+ ledgerArtifactResolver,
156
+ now = Date.now,
157
+ } = {}) {
158
+ this.descriptor = normalizeDescriptor(input);
159
+ this._put = capture(artifactPorts, "putCanonical", "artifactPorts");
160
+ this._read = capture(ledger, "read", "ledger");
161
+ this._verify = capture(ledger, "verify", "ledger");
162
+ this._append = capture(ledger, "appendDomainEvent", "ledger");
163
+ if (!isEvolutionLedgerArtifactResolver(ledgerArtifactResolver)) {
164
+ throw new TypeError(
165
+ "a branded EvolutionArtifactPorts ledger resolver is required",
166
+ );
167
+ }
168
+ if (typeof now !== "function")
169
+ throw new TypeError("now must be a function");
170
+ this._resolve = ledgerArtifactResolver;
171
+ this._now = now;
172
+ Object.freeze(this);
173
+ }
174
+
175
+ _domainEvents() {
176
+ const events = this._read();
177
+ if (!Array.isArray(events)) {
178
+ fail(
179
+ EVOLUTION_RUN_LEDGER_CORRUPT_CODE,
180
+ "EvolutionLedger did not return events",
181
+ );
182
+ }
183
+ return events.filter(
184
+ (event) =>
185
+ event.schema === EVOLUTION_LEDGER_DOMAIN_EVENT_SCHEMA &&
186
+ event.type === EVOLUTION_RUN_LEDGER_EVENT_TYPE &&
187
+ event.tenantId === this.descriptor.tenantId &&
188
+ event.correlationId === this.descriptor.runId,
189
+ );
190
+ }
191
+
192
+ _resolveEvent(domainEvent) {
193
+ if (
194
+ !domainEvent?.subjectRef ||
195
+ typeof domainEvent.subjectRef.ref !== "string" ||
196
+ !DIGEST.test(domainEvent.subjectRef.digest ?? "")
197
+ ) {
198
+ fail(
199
+ EVOLUTION_RUN_LEDGER_CORRUPT_CODE,
200
+ "EvolutionRun ledger subject reference is invalid",
201
+ );
202
+ }
203
+ const identity = this._verify();
204
+ const resolution = this._resolve({
205
+ epoch: identity.epoch,
206
+ ledgerId: identity.ledgerId,
207
+ ref: domainEvent.subjectRef,
208
+ tenantId: this.descriptor.artifactTenantId,
209
+ });
210
+ if (
211
+ resolution?.ref !== domainEvent.subjectRef.ref ||
212
+ resolution.digest !== domainEvent.subjectRef.digest
213
+ ) {
214
+ fail(
215
+ EVOLUTION_RUN_LEDGER_CORRUPT_CODE,
216
+ "EvolutionRun ledger subject was substituted",
217
+ );
218
+ }
219
+ return parseRecord(resolution, this.descriptor);
220
+ }
221
+
222
+ _entries() {
223
+ const entries = this._domainEvents().map((domainEvent) => ({
224
+ domainEvent,
225
+ event: this._resolveEvent(domainEvent),
226
+ }));
227
+ entries.sort((left, right) => left.event.sequence - right.event.sequence);
228
+ for (let index = 0; index < entries.length; index += 1) {
229
+ const entry = entries[index];
230
+ const previous = entries[index - 1] ?? null;
231
+ const expectedDomainEventId = `${EVOLUTION_RUN_LEDGER_EVENT_TYPE}.${entry.domainEvent.subjectRef.digest.slice("sha256:".length)}`;
232
+ if (
233
+ entry.domainEvent.eventId !== expectedDomainEventId ||
234
+ entry.domainEvent.decision !== "committed" ||
235
+ entry.domainEvent.artifactTenantId !==
236
+ this.descriptor.artifactTenantId ||
237
+ entry.domainEvent.skillName !== null
238
+ ) {
239
+ fail(
240
+ EVOLUTION_RUN_LEDGER_CORRUPT_CODE,
241
+ "EvolutionRun domain event binding is invalid",
242
+ );
243
+ }
244
+ if (entry.event.sequence !== index + 1) {
245
+ fail(
246
+ EVOLUTION_RUN_LEDGER_CORRUPT_CODE,
247
+ "EvolutionRun event sequence has a gap or duplicate",
248
+ );
249
+ }
250
+ const expectedSources = previous ? [previous.domainEvent.subjectRef] : [];
251
+ if (!same(entry.domainEvent.sourceRefs, expectedSources)) {
252
+ fail(
253
+ EVOLUTION_RUN_LEDGER_CORRUPT_CODE,
254
+ "EvolutionRun artifact lineage is discontinuous",
255
+ );
256
+ }
257
+ }
258
+ const events = entries.map(({ event }) => event);
259
+ if (events.length > 0) {
260
+ if (events[0].type !== EVENT_TYPES.RUN_STARTED) {
261
+ fail(
262
+ EVOLUTION_RUN_LEDGER_CORRUPT_CODE,
263
+ "EvolutionRun does not begin with run-started",
264
+ );
265
+ }
266
+ projectEvolutionRun(events, {
267
+ tenantId: this.descriptor.tenantId,
268
+ runId: this.descriptor.runId,
269
+ });
270
+ }
271
+ return entries;
272
+ }
273
+
274
+ load() {
275
+ const entries = this._entries();
276
+ const events = entries.map(({ event }) => event);
277
+ return Object.freeze({
278
+ events: Object.freeze(events),
279
+ projection:
280
+ events.length === 0
281
+ ? null
282
+ : projectEvolutionRun(events, {
283
+ tenantId: this.descriptor.tenantId,
284
+ runId: this.descriptor.runId,
285
+ }),
286
+ });
287
+ }
288
+
289
+ appendEvent(input) {
290
+ const event = normalizeEvent(input, this.descriptor);
291
+ const before = this._entries();
292
+ const duplicate = before.find(
293
+ ({ event: stored }) => stored.eventId === event.eventId,
294
+ );
295
+ if (duplicate) {
296
+ if (!same(duplicate.event, event)) {
297
+ fail(
298
+ EVOLUTION_RUN_LEDGER_CONFLICT_CODE,
299
+ "EvolutionRun eventId already binds different content",
300
+ );
301
+ }
302
+ return Object.freeze({
303
+ committed: true,
304
+ recovered: true,
305
+ eventId: event.eventId,
306
+ projection: this.load().projection,
307
+ });
308
+ }
309
+ const expectedSequence = before.length + 1;
310
+ if (
311
+ event.sequence !== expectedSequence ||
312
+ (expectedSequence === 1 && event.type !== EVENT_TYPES.RUN_STARTED) ||
313
+ before.at(-1)?.event.type === EVENT_TYPES.RUN_COMPLETED
314
+ ) {
315
+ fail(
316
+ EVOLUTION_RUN_LEDGER_CONFLICT_CODE,
317
+ "EvolutionRun event does not extend the current stream",
318
+ );
319
+ }
320
+ const published = this._put(ARTIFACT_TYPE, event, {
321
+ audience: this.descriptor.audience,
322
+ purpose: this.descriptor.purpose,
323
+ retention: "ledger",
324
+ });
325
+ if (
326
+ !published?.ref ||
327
+ published.receipt?.persisted !== true ||
328
+ published.receipt.readbackVerified !== true ||
329
+ published.receipt.integrityVerified !== true ||
330
+ published.receipt.retention !== "ledger"
331
+ ) {
332
+ fail(
333
+ EVOLUTION_RUN_LEDGER_CORRUPT_CODE,
334
+ "EvolutionRun event persistence was not durably confirmed",
335
+ );
336
+ }
337
+ const head = this._verify();
338
+ const currentBeforeAppend = this._entries();
339
+ if (
340
+ currentBeforeAppend.length !== before.length ||
341
+ currentBeforeAppend.some(
342
+ ({ domainEvent }, index) =>
343
+ domainEvent.eventDigest !== before[index].domainEvent.eventDigest,
344
+ )
345
+ ) {
346
+ fail(
347
+ EVOLUTION_RUN_LEDGER_CONFLICT_CODE,
348
+ "EvolutionRun changed before ledger append",
349
+ );
350
+ }
351
+ const timestamp = new Date(Number(this._now())).toISOString();
352
+ const domainEventId = `${EVOLUTION_RUN_LEDGER_EVENT_TYPE}.${published.digest.slice("sha256:".length)}`;
353
+ let recoveredAfterAppend = false;
354
+ try {
355
+ const receipt = this._append(
356
+ {
357
+ artifactTenantId: this.descriptor.artifactTenantId,
358
+ correlationId: this.descriptor.runId,
359
+ decision: "committed",
360
+ eventId: domainEventId,
361
+ reason: `EvolutionRun sequence ${event.sequence} committed`,
362
+ skillName: null,
363
+ sourceRefs:
364
+ before.length === 0 ? [] : [before.at(-1).domainEvent.subjectRef],
365
+ subjectRef: published.ref,
366
+ tenantId: this.descriptor.tenantId,
367
+ timestamp,
368
+ type: EVOLUTION_RUN_LEDGER_EVENT_TYPE,
369
+ },
370
+ {
371
+ expectedHeadDigest: head.headDigest,
372
+ expectedSequence: head.sequence,
373
+ },
374
+ );
375
+ if (
376
+ receipt?.authenticated !== true ||
377
+ receipt.committed !== true ||
378
+ receipt.durable !== true ||
379
+ receipt.eventId !== domainEventId ||
380
+ !DIGEST.test(receipt.receiptDigest ?? "")
381
+ ) {
382
+ fail(
383
+ EVOLUTION_RUN_LEDGER_CORRUPT_CODE,
384
+ "EvolutionRun ledger append was not durably authenticated",
385
+ );
386
+ }
387
+ } catch (cause) {
388
+ const recovered = this._entries().find(
389
+ ({ event: stored }) => stored.eventId === event.eventId,
390
+ );
391
+ if (!recovered || !same(recovered.event, event)) throw cause;
392
+ recoveredAfterAppend = true;
393
+ }
394
+ const after = this.load();
395
+ const stored = after.events.at(-1);
396
+ if (!stored || !same(stored, event)) {
397
+ fail(
398
+ EVOLUTION_RUN_LEDGER_CORRUPT_CODE,
399
+ "EvolutionRun readback differs after append",
400
+ );
401
+ }
402
+ return Object.freeze({
403
+ committed: true,
404
+ recovered: recoveredAfterAppend,
405
+ eventId: event.eventId,
406
+ projection: after.projection,
407
+ });
408
+ }
409
+ }
@@ -0,0 +1,5 @@
1
+ import evolutionRun from "@chainlesschain/session-core/evolution-run";
2
+
3
+ export function projectCliEvolutionRun(events, options) {
4
+ return evolutionRun.projectEvolutionRun(events, options);
5
+ }
@@ -0,0 +1,300 @@
1
+ import { types as utilTypes } from "node:util";
2
+
3
+ import evolutionRun from "@chainlesschain/session-core/evolution-run";
4
+
5
+ import { captureAgentEvolutionRuntimeComposition } from "./agent-evolution-runtime-composition-brand.js";
6
+ import {
7
+ WIKI_MAINTENANCE_TRIGGER_KIND,
8
+ WikiMaintenanceTriggerLedgerAdapter,
9
+ } from "./wiki-maintenance-trigger-ledger-adapter.js";
10
+
11
+ const { EVENT_TYPES } = evolutionRun;
12
+
13
+ export const EVOLUTION_RUN_WIKI_MAINTENANCE_SOURCE_SCHEMA =
14
+ "chainlesschain.evolution-run-wiki-maintenance-source/v1";
15
+ export const EVOLUTION_RUN_WIKI_MAINTENANCE_PRODUCER_SCHEMA =
16
+ "chainlesschain.evolution-run-wiki-maintenance-producer/v1";
17
+ export const EVOLUTION_RUN_WIKI_MAINTENANCE_SOURCE_INVALID_CODE =
18
+ "CC_EVOLUTION_RUN_WIKI_MAINTENANCE_SOURCE_INVALID";
19
+
20
+ const SOURCES = new WeakSet();
21
+ const PRODUCERS = new WeakSet();
22
+ const DIGEST = /^sha256:[a-f0-9]{64}$/u;
23
+ const SUPPORTED_KINDS = new Set([
24
+ WIKI_MAINTENANCE_TRIGGER_KIND.SESSION_END,
25
+ WIKI_MAINTENANCE_TRIGGER_KIND.GOAL_END,
26
+ ]);
27
+ const VERIFY_KEYS = new Set([
28
+ "tenantId",
29
+ "kind",
30
+ "sourceId",
31
+ "sourceReceiptDigest",
32
+ "evidenceRefs",
33
+ "effectiveAt",
34
+ ]);
35
+ const BUILD_KEYS = new Set(["kind", "runId"]);
36
+
37
+ function failure(message, options) {
38
+ const error = new Error(message, options);
39
+ error.code = EVOLUTION_RUN_WIKI_MAINTENANCE_SOURCE_INVALID_CODE;
40
+ return error;
41
+ }
42
+
43
+ function requiredString(value, label) {
44
+ if (
45
+ typeof value !== "string" ||
46
+ value.trim() === "" ||
47
+ Buffer.byteLength(value, "utf8") > 256
48
+ ) {
49
+ throw failure(`${label} is invalid`);
50
+ }
51
+ return value;
52
+ }
53
+
54
+ function assertExactRecord(value, keys, label) {
55
+ if (
56
+ !value ||
57
+ typeof value !== "object" ||
58
+ Array.isArray(value) ||
59
+ utilTypes.isProxy(value) ||
60
+ ![Object.prototype, null].includes(Object.getPrototypeOf(value))
61
+ ) {
62
+ throw failure(`${label} must be a plain object`);
63
+ }
64
+ const ownKeys = Reflect.ownKeys(value);
65
+ if (
66
+ ownKeys.length !== keys.size ||
67
+ ownKeys.some((key) => typeof key !== "string" || !keys.has(key))
68
+ ) {
69
+ throw failure(`${label} must contain exactly the supported fields`);
70
+ }
71
+ for (const key of ownKeys) {
72
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
73
+ if (!descriptor || !("value" in descriptor) || !descriptor.enumerable) {
74
+ throw failure(`${label}.${String(key)} must be an enumerable data field`);
75
+ }
76
+ }
77
+ }
78
+
79
+ function canonical(value) {
80
+ if (value === null || typeof value !== "object") return JSON.stringify(value);
81
+ if (Array.isArray(value)) return `[${value.map(canonical).join(",")}]`;
82
+ return `{${Object.keys(value)
83
+ .sort()
84
+ .map((key) => `${JSON.stringify(key)}:${canonical(value[key])}`)
85
+ .join(",")}}`;
86
+ }
87
+
88
+ function same(left, right) {
89
+ return canonical(left) === canonical(right);
90
+ }
91
+
92
+ function deepFreeze(value) {
93
+ if (value && typeof value === "object" && !Object.isFrozen(value)) {
94
+ Object.freeze(value);
95
+ for (const child of Object.values(value)) deepFreeze(child);
96
+ }
97
+ return value;
98
+ }
99
+
100
+ function canonicalTimestamp(value, label) {
101
+ requiredString(value, label);
102
+ const parsed = new Date(value);
103
+ if (!Number.isFinite(parsed.getTime()) || parsed.toISOString() !== value) {
104
+ throw failure(`${label} must be a canonical timestamp`);
105
+ }
106
+ return value;
107
+ }
108
+
109
+ function captureCompositionResolver(value) {
110
+ if (
111
+ !value ||
112
+ typeof value !== "object" ||
113
+ utilTypes.isProxy(value) ||
114
+ typeof value.resolve !== "function"
115
+ ) {
116
+ throw new TypeError("runCompositionResolver.resolve is required");
117
+ }
118
+ const resolve = value.resolve.bind(value);
119
+ Object.freeze(value);
120
+ return resolve;
121
+ }
122
+
123
+ function captureSource(value) {
124
+ if (!SOURCES.has(value)) {
125
+ throw new TypeError(
126
+ "a branded EvolutionRun Wiki maintenance source is required",
127
+ );
128
+ }
129
+ return value;
130
+ }
131
+
132
+ function normalizeBuildInput(value) {
133
+ assertExactRecord(value, BUILD_KEYS, "completed run trigger input");
134
+ if (!SUPPORTED_KINDS.has(value.kind)) {
135
+ throw failure(
136
+ "completed EvolutionRun sources only support session-end and goal-end",
137
+ );
138
+ }
139
+ return deepFreeze({
140
+ kind: value.kind,
141
+ runId: requiredString(value.runId, "runId"),
142
+ });
143
+ }
144
+
145
+ function captureRun(resolveComposition, tenantId, runId) {
146
+ let composition;
147
+ try {
148
+ composition = captureAgentEvolutionRuntimeComposition(
149
+ resolveComposition(deepFreeze({ tenantId, runId })),
150
+ );
151
+ } catch (cause) {
152
+ throw failure(
153
+ "run resolver did not return a branded Agent evolution composition",
154
+ { cause },
155
+ );
156
+ }
157
+ if (
158
+ composition.tenantId !== tenantId ||
159
+ composition.runId !== runId ||
160
+ typeof composition.loadRun !== "function"
161
+ ) {
162
+ throw failure(
163
+ "run resolver did not return the exact tenant-scoped Agent evolution composition",
164
+ );
165
+ }
166
+ return composition;
167
+ }
168
+
169
+ function projectTrigger(resolveComposition, tenantId, input) {
170
+ const normalized = normalizeBuildInput(input);
171
+ const composition = captureRun(
172
+ resolveComposition,
173
+ tenantId,
174
+ normalized.runId,
175
+ );
176
+ const loaded = composition.loadRun();
177
+ const events = loaded?.events;
178
+ const projection = loaded?.projection;
179
+ const completion = Array.isArray(events) ? events.at(-1) : null;
180
+ if (
181
+ !Array.isArray(events) ||
182
+ events.length < 2 ||
183
+ projection?.tenantId !== tenantId ||
184
+ projection.runId !== normalized.runId ||
185
+ projection.status !== "completed" ||
186
+ !DIGEST.test(projection.projectionDigest ?? "") ||
187
+ completion?.type !== EVENT_TYPES.RUN_COMPLETED ||
188
+ completion.subjectId !== normalized.runId
189
+ ) {
190
+ throw failure("EvolutionRun is not durably completed");
191
+ }
192
+ const effectiveAt = canonicalTimestamp(
193
+ completion.data?.occurredAt,
194
+ "run completion occurredAt",
195
+ );
196
+ const evidenceEvents = events.filter(
197
+ (event) => event.type === EVENT_TYPES.RAW_EVENT_REFERENCED,
198
+ );
199
+ const evidenceRefs = [
200
+ ...new Set(
201
+ evidenceEvents.map((event) =>
202
+ requiredString(event.subjectId, "evidence subjectId"),
203
+ ),
204
+ ),
205
+ ].sort();
206
+ if (evidenceRefs.length === 0 || evidenceRefs.length > 256) {
207
+ throw failure("completed EvolutionRun has no bounded evidence set");
208
+ }
209
+ if (
210
+ normalized.kind === WIKI_MAINTENANCE_TRIGGER_KIND.GOAL_END &&
211
+ !evidenceEvents.some((event) => event.data?.evidenceKind === "goal-ended")
212
+ ) {
213
+ throw failure(
214
+ "goal-end trigger requires authenticated goal-ended evidence",
215
+ );
216
+ }
217
+ return deepFreeze({
218
+ kind: normalized.kind,
219
+ sourceId: normalized.runId,
220
+ sourceReceiptDigest: projection.projectionDigest,
221
+ evidenceRefs,
222
+ effectiveAt,
223
+ });
224
+ }
225
+
226
+ export function createEvolutionRunWikiMaintenanceSource({
227
+ tenantId: tenantInput,
228
+ runCompositionResolver,
229
+ } = {}) {
230
+ const tenantId = requiredString(tenantInput, "tenantId");
231
+ const resolveComposition = captureCompositionResolver(runCompositionResolver);
232
+ const source = {
233
+ schema: EVOLUTION_RUN_WIKI_MAINTENANCE_SOURCE_SCHEMA,
234
+ tenantId,
235
+ build(input) {
236
+ return projectTrigger(resolveComposition, tenantId, input);
237
+ },
238
+ async verify(input) {
239
+ assertExactRecord(input, VERIFY_KEYS, "Wiki maintenance source request");
240
+ if (input.tenantId !== tenantId) {
241
+ throw failure("Wiki maintenance source belongs to another tenant");
242
+ }
243
+ const expected = projectTrigger(resolveComposition, tenantId, {
244
+ kind: input.kind,
245
+ runId: input.sourceId,
246
+ });
247
+ if (!same(input, { tenantId, ...expected })) {
248
+ throw failure(
249
+ "Wiki maintenance source no longer matches the durable EvolutionRun",
250
+ );
251
+ }
252
+ return deepFreeze({
253
+ authenticated: true,
254
+ durable: true,
255
+ tenantId,
256
+ kind: expected.kind,
257
+ sourceId: expected.sourceId,
258
+ receiptDigest: expected.sourceReceiptDigest,
259
+ evidenceRefs: expected.evidenceRefs,
260
+ effectiveAt: expected.effectiveAt,
261
+ });
262
+ },
263
+ };
264
+ SOURCES.add(source);
265
+ return Object.freeze(source);
266
+ }
267
+
268
+ export function createEvolutionRunWikiMaintenanceProducer({
269
+ source: sourceInput,
270
+ triggerAdapter,
271
+ } = {}) {
272
+ const source = captureSource(sourceInput);
273
+ if (
274
+ !(triggerAdapter instanceof WikiMaintenanceTriggerLedgerAdapter) ||
275
+ triggerAdapter.descriptor?.tenantId !== source.tenantId
276
+ ) {
277
+ throw new TypeError(
278
+ "a tenant-matched WikiMaintenanceTriggerLedgerAdapter is required",
279
+ );
280
+ }
281
+ const enqueue = triggerAdapter.enqueue.bind(triggerAdapter);
282
+ const producer = {
283
+ schema: EVOLUTION_RUN_WIKI_MAINTENANCE_PRODUCER_SCHEMA,
284
+ tenantId: source.tenantId,
285
+ async enqueueCompletedRun(input) {
286
+ return enqueue(source.build(input));
287
+ },
288
+ };
289
+ PRODUCERS.add(producer);
290
+ return Object.freeze(producer);
291
+ }
292
+
293
+ export function captureEvolutionRunWikiMaintenanceProducer(value) {
294
+ if (!PRODUCERS.has(value)) {
295
+ throw new TypeError(
296
+ "a branded EvolutionRun Wiki maintenance producer is required",
297
+ );
298
+ }
299
+ return value;
300
+ }