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,687 @@
1
+ import { createHash } from "node:crypto";
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
+ import {
12
+ WIKI_MAINTENANCE_REQUEST_SCHEMA,
13
+ WIKI_REVISION_SCHEMA,
14
+ digestWikiState,
15
+ } from "./evidence-backed-wiki-maintainer.js";
16
+ import { WIKI_LEDGER_EVENT_TYPE } from "./wiki-maintainer-ledger-adapter.js";
17
+
18
+ export const WIKI_MAINTENANCE_TRIGGER_SCHEMA =
19
+ "chainlesschain.evolution-wiki-maintenance-trigger/v1";
20
+ export const WIKI_MAINTENANCE_SETTLEMENT_SCHEMA =
21
+ "chainlesschain.evolution-wiki-maintenance-settlement/v1";
22
+ export const WIKI_MAINTENANCE_REQUEST_EVENT_TYPE = "wiki.maintenance.requested";
23
+ export const WIKI_MAINTENANCE_SETTLED_EVENT_TYPE = "wiki.maintenance.settled";
24
+ export const WIKI_MAINTENANCE_TRIGGER_CORRUPT_CODE =
25
+ "CC_EVOLUTION_WIKI_MAINTENANCE_TRIGGER_CORRUPT";
26
+ export const WIKI_MAINTENANCE_TRIGGER_CONFLICT_CODE =
27
+ "CC_EVOLUTION_WIKI_MAINTENANCE_TRIGGER_CONFLICT";
28
+
29
+ export const WIKI_MAINTENANCE_TRIGGER_KIND = Object.freeze({
30
+ SESSION_END: "session-end",
31
+ GOAL_END: "goal-end",
32
+ SCHEDULED_BATCH: "scheduled-batch",
33
+ });
34
+
35
+ const REQUEST_TYPE = "wiki-maintenance-request";
36
+ const SETTLEMENT_TYPE = "wiki-maintenance-settlement";
37
+ const DIGEST = /^sha256:[a-f0-9]{64}$/u;
38
+ const REVISION_ID = /^wiki:[a-f0-9]{64}$/u;
39
+ const REQUEST_ID = /^wiki-maintenance:[a-f0-9]{64}$/u;
40
+ const KINDS = new Set(Object.values(WIKI_MAINTENANCE_TRIGGER_KIND));
41
+
42
+ function canonical(value) {
43
+ if (value === null || typeof value !== "object") return JSON.stringify(value);
44
+ if (Array.isArray(value)) return `[${value.map(canonical).join(",")}]`;
45
+ return `{${Object.keys(value)
46
+ .sort()
47
+ .map((key) => `${JSON.stringify(key)}:${canonical(value[key])}`)
48
+ .join(",")}}`;
49
+ }
50
+
51
+ function hash(value) {
52
+ return `sha256:${createHash("sha256").update(canonical(value)).digest("hex")}`;
53
+ }
54
+
55
+ function deepFreeze(value) {
56
+ if (value && typeof value === "object" && !Object.isFrozen(value)) {
57
+ Object.freeze(value);
58
+ for (const child of Object.values(value)) deepFreeze(child);
59
+ }
60
+ return value;
61
+ }
62
+
63
+ function requiredString(value, label) {
64
+ if (typeof value !== "string" || value.trim() === "") {
65
+ throw new TypeError(`${label} is required`);
66
+ }
67
+ if (Buffer.byteLength(value, "utf8") > 256) {
68
+ throw new TypeError(`${label} is too long`);
69
+ }
70
+ return value;
71
+ }
72
+
73
+ function timestamp(value, label) {
74
+ requiredString(value, label);
75
+ const parsed = new Date(value);
76
+ if (!Number.isFinite(parsed.getTime()) || parsed.toISOString() !== value) {
77
+ throw new TypeError(`${label} must be a canonical timestamp`);
78
+ }
79
+ return value;
80
+ }
81
+
82
+ function evidenceRefs(value) {
83
+ if (
84
+ !Array.isArray(value) ||
85
+ value.length < 1 ||
86
+ value.length > 256 ||
87
+ value.some((item) => typeof item !== "string" || item.trim() === "")
88
+ ) {
89
+ throw new TypeError("evidenceRefs must be a non-empty bounded string list");
90
+ }
91
+ return [...new Set(value)].sort();
92
+ }
93
+
94
+ function fail(code, message, options) {
95
+ const error = new Error(message, options);
96
+ error.code = code;
97
+ throw error;
98
+ }
99
+
100
+ function capture(owner, method, label = method) {
101
+ if (typeof owner?.[method] !== "function") {
102
+ throw new TypeError(`${label} port is required`);
103
+ }
104
+ return (...args) => Reflect.apply(owner[method], owner, args);
105
+ }
106
+
107
+ function same(left, right) {
108
+ return canonical(left) === canonical(right);
109
+ }
110
+
111
+ function normalizeDescriptor(input) {
112
+ return Object.freeze({
113
+ tenantId: requiredString(input?.tenantId, "tenantId"),
114
+ artifactTenantId: requiredString(
115
+ input?.artifactTenantId,
116
+ "artifactTenantId",
117
+ ),
118
+ streamId: requiredString(input?.streamId, "streamId"),
119
+ audience: requiredString(input?.audience, "audience"),
120
+ purpose: requiredString(input?.purpose, "purpose"),
121
+ });
122
+ }
123
+
124
+ function normalizeTrigger(input, descriptor) {
125
+ const kind = requiredString(input?.kind, "trigger.kind");
126
+ if (!KINDS.has(kind)) throw new TypeError("trigger.kind is invalid");
127
+ const core = {
128
+ schema: WIKI_MAINTENANCE_TRIGGER_SCHEMA,
129
+ tenantId: descriptor.tenantId,
130
+ streamId: descriptor.streamId,
131
+ kind,
132
+ sourceId: requiredString(input?.sourceId, "trigger.sourceId"),
133
+ sourceReceiptDigest: DIGEST.test(input?.sourceReceiptDigest ?? "")
134
+ ? input.sourceReceiptDigest
135
+ : (() => {
136
+ throw new TypeError(
137
+ "trigger.sourceReceiptDigest must be sha256-bound",
138
+ );
139
+ })(),
140
+ evidenceRefs: evidenceRefs(input?.evidenceRefs),
141
+ effectiveAt: timestamp(input?.effectiveAt, "trigger.effectiveAt"),
142
+ };
143
+ const requestDigest = hash(core);
144
+ return deepFreeze({
145
+ ...core,
146
+ requestId: `wiki-maintenance:${requestDigest.slice("sha256:".length)}`,
147
+ requestDigest,
148
+ });
149
+ }
150
+
151
+ function verifyTrigger(value, descriptor) {
152
+ const expected = normalizeTrigger(value, descriptor);
153
+ if (!same(value, expected)) {
154
+ fail(
155
+ WIKI_MAINTENANCE_TRIGGER_CORRUPT_CODE,
156
+ "stored Wiki maintenance request contains unsupported or substituted fields",
157
+ );
158
+ }
159
+ return expected;
160
+ }
161
+
162
+ function normalizeSettlement(input, descriptor) {
163
+ if (
164
+ !REQUEST_ID.test(input?.requestId ?? "") ||
165
+ !DIGEST.test(input?.requestDigest ?? "") ||
166
+ input.requestId !==
167
+ `wiki-maintenance:${input.requestDigest.slice("sha256:".length)}` ||
168
+ !REVISION_ID.test(input?.revisionId ?? "") ||
169
+ !Number.isSafeInteger(input?.revision) ||
170
+ input.revision < 1 ||
171
+ !DIGEST.test(input?.stateDigest ?? "")
172
+ ) {
173
+ throw new TypeError("Wiki maintenance settlement identity is invalid");
174
+ }
175
+ const core = {
176
+ schema: WIKI_MAINTENANCE_SETTLEMENT_SCHEMA,
177
+ tenantId: descriptor.tenantId,
178
+ streamId: descriptor.streamId,
179
+ requestId: input.requestId,
180
+ requestDigest: input.requestDigest,
181
+ status: "committed",
182
+ revisionId: input.revisionId,
183
+ revision: input.revision,
184
+ stateDigest: input.stateDigest,
185
+ settledAt: timestamp(input.settledAt, "settlement.settledAt"),
186
+ };
187
+ return deepFreeze({ ...core, settlementDigest: hash(core) });
188
+ }
189
+
190
+ function verifySettlement(value, descriptor) {
191
+ const expected = normalizeSettlement(value, descriptor);
192
+ if (!same(value, expected)) {
193
+ fail(
194
+ WIKI_MAINTENANCE_TRIGGER_CORRUPT_CODE,
195
+ "stored Wiki maintenance settlement contains substituted fields",
196
+ );
197
+ }
198
+ return expected;
199
+ }
200
+
201
+ function parseRecord(resolution, descriptor, expectedType) {
202
+ if (
203
+ resolution?.schema !== EVOLUTION_ARTIFACT_RESOLUTION_SCHEMA ||
204
+ resolution.authenticated !== true ||
205
+ resolution.found !== true ||
206
+ !Buffer.isBuffer(resolution.bytes)
207
+ ) {
208
+ fail(
209
+ WIKI_MAINTENANCE_TRIGGER_CORRUPT_CODE,
210
+ "Wiki maintenance artifact resolution is unauthenticated or incomplete",
211
+ );
212
+ }
213
+ let record;
214
+ try {
215
+ record = JSON.parse(resolution.bytes.toString("utf8"));
216
+ } catch {
217
+ fail(
218
+ WIKI_MAINTENANCE_TRIGGER_CORRUPT_CODE,
219
+ "Wiki maintenance artifact is not canonical JSON",
220
+ );
221
+ }
222
+ if (
223
+ record?.schema !== EVOLUTION_DURABLE_ARTIFACT_RECORD_SCHEMA ||
224
+ record.tenantId !== descriptor.artifactTenantId ||
225
+ record.audience !== descriptor.audience ||
226
+ record.purpose !== descriptor.purpose ||
227
+ record.retention !== "ledger" ||
228
+ record.type !== expectedType
229
+ ) {
230
+ fail(
231
+ WIKI_MAINTENANCE_TRIGGER_CORRUPT_CODE,
232
+ "Wiki maintenance durable artifact binding is invalid",
233
+ );
234
+ }
235
+ return record.value;
236
+ }
237
+
238
+ export class WikiMaintenanceTriggerLedgerAdapter {
239
+ constructor({
240
+ descriptor: input,
241
+ artifactPorts,
242
+ ledger,
243
+ ledgerArtifactResolver,
244
+ sourceVerifier,
245
+ maintainer,
246
+ now = Date.now,
247
+ } = {}) {
248
+ this.descriptor = normalizeDescriptor(input);
249
+ this._put = capture(artifactPorts, "putCanonical", "artifactPorts");
250
+ this._read = capture(ledger, "read", "ledger");
251
+ this._verifyLedger = capture(ledger, "verify", "ledger");
252
+ this._append = capture(ledger, "appendDomainEvent", "ledger");
253
+ this._verifySource = capture(sourceVerifier, "verify", "sourceVerifier");
254
+ this._maintain = capture(maintainer, "maintain", "maintainer");
255
+ if (!isEvolutionLedgerArtifactResolver(ledgerArtifactResolver)) {
256
+ throw new TypeError(
257
+ "a branded EvolutionArtifactPorts ledger resolver is required",
258
+ );
259
+ }
260
+ if (typeof now !== "function")
261
+ throw new TypeError("now must be a function");
262
+ this._resolve = ledgerArtifactResolver;
263
+ this._now = now;
264
+ Object.freeze(this);
265
+ }
266
+
267
+ _events(type) {
268
+ const events = this._read();
269
+ if (!Array.isArray(events)) {
270
+ fail(
271
+ WIKI_MAINTENANCE_TRIGGER_CORRUPT_CODE,
272
+ "EvolutionLedger did not return events",
273
+ );
274
+ }
275
+ return events.filter(
276
+ (event) =>
277
+ event.schema === EVOLUTION_LEDGER_DOMAIN_EVENT_SCHEMA &&
278
+ event.type === type &&
279
+ event.tenantId === this.descriptor.tenantId &&
280
+ event.correlationId === this.descriptor.streamId,
281
+ );
282
+ }
283
+
284
+ _resolveEvent(event, expectedType) {
285
+ const identity = this._verifyLedger();
286
+ const resolution = this._resolve({
287
+ epoch: identity.epoch,
288
+ ledgerId: identity.ledgerId,
289
+ ref: event.subjectRef,
290
+ tenantId: this.descriptor.artifactTenantId,
291
+ });
292
+ if (
293
+ resolution?.ref !== event.subjectRef.ref ||
294
+ resolution.digest !== event.subjectRef.digest
295
+ ) {
296
+ fail(
297
+ WIKI_MAINTENANCE_TRIGGER_CORRUPT_CODE,
298
+ "Wiki maintenance ledger subject was substituted",
299
+ );
300
+ }
301
+ return parseRecord(resolution, this.descriptor, expectedType);
302
+ }
303
+
304
+ _requests() {
305
+ return this._events(WIKI_MAINTENANCE_REQUEST_EVENT_TYPE).map((event) => {
306
+ const request = verifyTrigger(
307
+ this._resolveEvent(event, REQUEST_TYPE),
308
+ this.descriptor,
309
+ );
310
+ if (
311
+ event.eventId !==
312
+ `${WIKI_MAINTENANCE_REQUEST_EVENT_TYPE}.${request.requestDigest.slice(7)}` ||
313
+ event.decision !== "proposed" ||
314
+ event.skillName !== null ||
315
+ !Array.isArray(event.sourceRefs) ||
316
+ event.sourceRefs.length !== 0
317
+ ) {
318
+ fail(
319
+ WIKI_MAINTENANCE_TRIGGER_CORRUPT_CODE,
320
+ "Wiki maintenance request event binding is invalid",
321
+ );
322
+ }
323
+ return { event, request };
324
+ });
325
+ }
326
+
327
+ _verifyCommittedRevision(settlement) {
328
+ const revisionEvents = this._read().filter(
329
+ (candidate) =>
330
+ candidate.schema === EVOLUTION_LEDGER_DOMAIN_EVENT_SCHEMA &&
331
+ candidate.type === WIKI_LEDGER_EVENT_TYPE &&
332
+ candidate.tenantId === this.descriptor.tenantId &&
333
+ candidate.eventId ===
334
+ `wiki.revision.${settlement.revisionId.slice("wiki:".length)}`,
335
+ );
336
+ if (revisionEvents.length !== 1) {
337
+ fail(
338
+ WIKI_MAINTENANCE_TRIGGER_CORRUPT_CODE,
339
+ "Wiki maintenance settlement has no unique committed revision",
340
+ );
341
+ }
342
+ const revision = this._resolveEvent(revisionEvents[0], "wiki-revision");
343
+ if (
344
+ revision?.schema !== WIKI_REVISION_SCHEMA ||
345
+ revision.tenantId !== this.descriptor.tenantId ||
346
+ revision.revisionId !== settlement.revisionId ||
347
+ revision.revision !== settlement.revision ||
348
+ revision.stateDigest !== settlement.stateDigest ||
349
+ revision.stateDigest !== digestWikiState(revision.state)
350
+ ) {
351
+ fail(
352
+ WIKI_MAINTENANCE_TRIGGER_CORRUPT_CODE,
353
+ "Wiki maintenance settlement does not match its committed revision",
354
+ );
355
+ }
356
+ return revision;
357
+ }
358
+
359
+ _settlements() {
360
+ const requests = this._requests();
361
+ return this._events(WIKI_MAINTENANCE_SETTLED_EVENT_TYPE).map((event) => {
362
+ const settlement = verifySettlement(
363
+ this._resolveEvent(event, SETTLEMENT_TYPE),
364
+ this.descriptor,
365
+ );
366
+ this._verifyCommittedRevision(settlement);
367
+ const request = requests.find(
368
+ (entry) => entry.request.requestId === settlement.requestId,
369
+ );
370
+ if (
371
+ !request ||
372
+ settlement.requestDigest !== request.request.requestDigest ||
373
+ event.eventId !==
374
+ `${WIKI_MAINTENANCE_SETTLED_EVENT_TYPE}.${settlement.settlementDigest.slice(7)}` ||
375
+ event.decision !== "committed" ||
376
+ event.skillName !== null ||
377
+ !Array.isArray(event.sourceRefs) ||
378
+ event.sourceRefs.length !== 1 ||
379
+ !same(event.sourceRefs[0], request.event.subjectRef)
380
+ ) {
381
+ fail(
382
+ WIKI_MAINTENANCE_TRIGGER_CORRUPT_CODE,
383
+ "Wiki maintenance settlement lineage is invalid",
384
+ );
385
+ }
386
+ return { event, settlement };
387
+ });
388
+ }
389
+
390
+ async _assertSource(request) {
391
+ const verified = await this._verifySource(
392
+ deepFreeze({
393
+ tenantId: request.tenantId,
394
+ kind: request.kind,
395
+ sourceId: request.sourceId,
396
+ sourceReceiptDigest: request.sourceReceiptDigest,
397
+ evidenceRefs: request.evidenceRefs,
398
+ effectiveAt: request.effectiveAt,
399
+ }),
400
+ );
401
+ if (
402
+ verified?.authenticated !== true ||
403
+ verified.durable !== true ||
404
+ verified.tenantId !== request.tenantId ||
405
+ verified.kind !== request.kind ||
406
+ verified.sourceId !== request.sourceId ||
407
+ verified.receiptDigest !== request.sourceReceiptDigest ||
408
+ !same(verified.evidenceRefs, request.evidenceRefs) ||
409
+ verified.effectiveAt !== request.effectiveAt
410
+ ) {
411
+ throw new Error(
412
+ "Wiki maintenance trigger source was not durably authenticated",
413
+ );
414
+ }
415
+ }
416
+
417
+ async enqueue(input) {
418
+ const request = normalizeTrigger(input, this.descriptor);
419
+ await this._assertSource(request);
420
+ const eventId = `${WIKI_MAINTENANCE_REQUEST_EVENT_TYPE}.${request.requestDigest.slice(7)}`;
421
+ const existing = this._requests().filter(
422
+ (entry) => entry.event.eventId === eventId,
423
+ );
424
+ if (existing.length > 1) {
425
+ fail(
426
+ WIKI_MAINTENANCE_TRIGGER_CORRUPT_CODE,
427
+ "Wiki maintenance request is duplicated in the ledger",
428
+ );
429
+ }
430
+ if (existing.length === 1) {
431
+ if (!same(existing[0].request, request)) {
432
+ fail(
433
+ WIKI_MAINTENANCE_TRIGGER_CONFLICT_CODE,
434
+ "Wiki maintenance request id binds different content",
435
+ );
436
+ }
437
+ return deepFreeze({
438
+ queued: true,
439
+ recovered: true,
440
+ requestId: request.requestId,
441
+ requestDigest: request.requestDigest,
442
+ });
443
+ }
444
+ const head = this._verifyLedger();
445
+ const published = this._put(REQUEST_TYPE, request, {
446
+ audience: this.descriptor.audience,
447
+ purpose: this.descriptor.purpose,
448
+ retention: "ledger",
449
+ });
450
+ if (
451
+ published?.receipt?.persisted !== true ||
452
+ published.receipt.readbackVerified !== true ||
453
+ published.receipt.integrityVerified !== true ||
454
+ published.receipt.retention !== "ledger"
455
+ ) {
456
+ fail(
457
+ WIKI_MAINTENANCE_TRIGGER_CORRUPT_CODE,
458
+ "Wiki maintenance request was not durably read back",
459
+ );
460
+ }
461
+ try {
462
+ const receipt = this._append(
463
+ {
464
+ artifactTenantId: this.descriptor.artifactTenantId,
465
+ correlationId: this.descriptor.streamId,
466
+ decision: "proposed",
467
+ eventId,
468
+ reason: `${request.kind} requested Wiki maintenance`,
469
+ skillName: null,
470
+ sourceRefs: [],
471
+ subjectRef: published.ref,
472
+ tenantId: this.descriptor.tenantId,
473
+ timestamp: request.effectiveAt,
474
+ type: WIKI_MAINTENANCE_REQUEST_EVENT_TYPE,
475
+ },
476
+ {
477
+ expectedHeadDigest: head.headDigest,
478
+ expectedSequence: head.sequence,
479
+ },
480
+ );
481
+ if (
482
+ receipt?.authenticated !== true ||
483
+ receipt.committed !== true ||
484
+ receipt.durable !== true ||
485
+ receipt.eventId !== eventId ||
486
+ !DIGEST.test(receipt.receiptDigest ?? "")
487
+ ) {
488
+ fail(
489
+ WIKI_MAINTENANCE_TRIGGER_CORRUPT_CODE,
490
+ "Wiki maintenance request ledger append was not authenticated",
491
+ );
492
+ }
493
+ } catch (cause) {
494
+ const recovered = this._requests().find(
495
+ (entry) => entry.event.eventId === eventId,
496
+ );
497
+ if (!recovered || !same(recovered.request, request)) throw cause;
498
+ return deepFreeze({
499
+ queued: true,
500
+ recovered: true,
501
+ requestId: request.requestId,
502
+ requestDigest: request.requestDigest,
503
+ });
504
+ }
505
+ return deepFreeze({
506
+ queued: true,
507
+ recovered: false,
508
+ requestId: request.requestId,
509
+ requestDigest: request.requestDigest,
510
+ });
511
+ }
512
+
513
+ list() {
514
+ const settlements = this._settlements();
515
+ return deepFreeze(
516
+ this._requests()
517
+ .map(({ event, request }) => {
518
+ const matches = settlements.filter(
519
+ ({ settlement }) => settlement.requestId === request.requestId,
520
+ );
521
+ if (matches.length > 1) {
522
+ fail(
523
+ WIKI_MAINTENANCE_TRIGGER_CORRUPT_CODE,
524
+ "Wiki maintenance request has conflicting settlements",
525
+ );
526
+ }
527
+ return {
528
+ request,
529
+ requestEventDigest: event.eventDigest,
530
+ requestEventSequence: event.sequence,
531
+ status: matches.length === 1 ? "committed" : "pending",
532
+ settlement: matches[0]?.settlement ?? null,
533
+ };
534
+ })
535
+ .sort(
536
+ (left, right) =>
537
+ left.requestEventSequence - right.requestEventSequence,
538
+ ),
539
+ );
540
+ }
541
+
542
+ async _settle(request, result) {
543
+ if (
544
+ result?.maintenanceRequestId !== request.requestId ||
545
+ !REVISION_ID.test(result?.revisionId ?? "") ||
546
+ !Number.isSafeInteger(result?.revision) ||
547
+ result.revision < 1 ||
548
+ !DIGEST.test(result?.stateDigest ?? "")
549
+ ) {
550
+ throw new Error(
551
+ "Maintainer did not confirm the exact durable request and revision",
552
+ );
553
+ }
554
+ const existing = this.list().find(
555
+ (entry) => entry.request.requestId === request.requestId,
556
+ );
557
+ if (existing?.settlement) {
558
+ if (
559
+ existing.settlement.revisionId !== result.revisionId ||
560
+ existing.settlement.revision !== result.revision
561
+ ) {
562
+ fail(
563
+ WIKI_MAINTENANCE_TRIGGER_CONFLICT_CODE,
564
+ "Wiki maintenance request already settled to another revision",
565
+ );
566
+ }
567
+ return deepFreeze({
568
+ committed: true,
569
+ recovered: true,
570
+ settlement: existing.settlement,
571
+ });
572
+ }
573
+ const nowMs = Number(this._now());
574
+ if (!Number.isFinite(nowMs))
575
+ throw new TypeError("trigger clock is invalid");
576
+ const settlement = normalizeSettlement(
577
+ {
578
+ requestId: request.requestId,
579
+ requestDigest: request.requestDigest,
580
+ revisionId: result.revisionId,
581
+ revision: result.revision,
582
+ stateDigest: result.stateDigest,
583
+ settledAt: new Date(nowMs).toISOString(),
584
+ },
585
+ this.descriptor,
586
+ );
587
+ this._verifyCommittedRevision(settlement);
588
+ const requestEntry = this._requests().find(
589
+ (entry) => entry.request.requestId === request.requestId,
590
+ );
591
+ if (!requestEntry) {
592
+ fail(
593
+ WIKI_MAINTENANCE_TRIGGER_CORRUPT_CODE,
594
+ "Wiki maintenance request disappeared before settlement",
595
+ );
596
+ }
597
+ const head = this._verifyLedger();
598
+ const published = this._put(SETTLEMENT_TYPE, settlement, {
599
+ audience: this.descriptor.audience,
600
+ purpose: this.descriptor.purpose,
601
+ retention: "ledger",
602
+ });
603
+ if (
604
+ published?.receipt?.persisted !== true ||
605
+ published.receipt.readbackVerified !== true ||
606
+ published.receipt.integrityVerified !== true ||
607
+ published.receipt.retention !== "ledger"
608
+ ) {
609
+ fail(
610
+ WIKI_MAINTENANCE_TRIGGER_CORRUPT_CODE,
611
+ "Wiki maintenance settlement was not durably read back",
612
+ );
613
+ }
614
+ const eventId = `${WIKI_MAINTENANCE_SETTLED_EVENT_TYPE}.${settlement.settlementDigest.slice(7)}`;
615
+ try {
616
+ const receipt = this._append(
617
+ {
618
+ artifactTenantId: this.descriptor.artifactTenantId,
619
+ correlationId: this.descriptor.streamId,
620
+ decision: "committed",
621
+ eventId,
622
+ reason: `Wiki revision ${settlement.revision} committed for maintenance request`,
623
+ skillName: null,
624
+ sourceRefs: [requestEntry.event.subjectRef],
625
+ subjectRef: published.ref,
626
+ tenantId: this.descriptor.tenantId,
627
+ timestamp: settlement.settledAt,
628
+ type: WIKI_MAINTENANCE_SETTLED_EVENT_TYPE,
629
+ },
630
+ {
631
+ expectedHeadDigest: head.headDigest,
632
+ expectedSequence: head.sequence,
633
+ },
634
+ );
635
+ if (
636
+ receipt?.authenticated !== true ||
637
+ receipt.committed !== true ||
638
+ receipt.durable !== true ||
639
+ receipt.eventId !== eventId
640
+ ) {
641
+ fail(
642
+ WIKI_MAINTENANCE_TRIGGER_CORRUPT_CODE,
643
+ "Wiki maintenance settlement append was not authenticated",
644
+ );
645
+ }
646
+ } catch (cause) {
647
+ const recovered = this._settlements().find(
648
+ (entry) => entry.settlement.requestId === request.requestId,
649
+ );
650
+ if (!recovered || !same(recovered.settlement, settlement)) throw cause;
651
+ return deepFreeze({
652
+ committed: true,
653
+ recovered: true,
654
+ settlement,
655
+ });
656
+ }
657
+ return deepFreeze({ committed: true, recovered: false, settlement });
658
+ }
659
+
660
+ async processNext() {
661
+ const pending = this.list().find((entry) => entry.status === "pending");
662
+ if (!pending) return deepFreeze({ processed: false });
663
+ const request = pending.request;
664
+ await this._assertSource(request);
665
+ const result = await this._maintain({
666
+ evidenceRefs: request.evidenceRefs,
667
+ effectiveAt: request.effectiveAt,
668
+ maintenanceRequest: deepFreeze({
669
+ schema: WIKI_MAINTENANCE_REQUEST_SCHEMA,
670
+ tenantId: request.tenantId,
671
+ requestId: request.requestId,
672
+ requestDigest: request.requestDigest,
673
+ }),
674
+ });
675
+ const settled = await this._settle(request, result);
676
+ return deepFreeze({
677
+ processed: true,
678
+ requestId: request.requestId,
679
+ revisionId: settled.settlement.revisionId,
680
+ recovered: result.recovered === true || settled.recovered === true,
681
+ });
682
+ }
683
+ }
684
+
685
+ export function createWikiMaintenanceTriggerLedgerAdapter(options) {
686
+ return new WikiMaintenanceTriggerLedgerAdapter(options);
687
+ }