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,899 @@
1
+ import { createHash } from "node:crypto";
2
+ import { types as utilTypes } from "node:util";
3
+
4
+ import {
5
+ SKILL_EVALUATED_PROMOTION_RECEIPT_RESOLUTION_REQUEST_SCHEMA,
6
+ SKILL_EVALUATED_PROMOTION_RECEIPT_RESOLUTION_SCHEMA,
7
+ SKILL_EVALUATED_PROMOTION_RECEIPT_RESOLVER_SCHEMA,
8
+ buildSkillEvaluatedPromotionReceiptEnvelope,
9
+ } from "./skill-evaluated-promotion.js";
10
+
11
+ export const SKILL_EVALUATED_PROMOTION_DURABILITY_AUTHORITY_SCHEMA =
12
+ "chainlesschain.skill-evaluated-promotion-durability-authority/v1";
13
+ export const SKILL_EVALUATED_PROMOTION_DURABILITY_RETAIN_REQUEST_SCHEMA =
14
+ "chainlesschain.skill-evaluated-promotion-durability-retain-request/v1";
15
+ export const SKILL_EVALUATED_PROMOTION_DURABILITY_RESOLVE_REQUEST_SCHEMA =
16
+ "chainlesschain.skill-evaluated-promotion-durability-resolve-request/v1";
17
+ export const SKILL_EVALUATED_PROMOTION_DURABILITY_RECEIPT_SCHEMA =
18
+ "chainlesschain.skill-evaluated-promotion-durability-receipt/v1";
19
+ export const SKILL_EVALUATED_PROMOTION_DURABILITY_RESOLUTION_SCHEMA =
20
+ "chainlesschain.skill-evaluated-promotion-durability-resolution/v1";
21
+ export const SKILL_EVALUATED_PROMOTION_DURABILITY_ATTESTATION_PURPOSES =
22
+ Object.freeze({
23
+ retain: "skill-evaluated-promotion-durability-retain",
24
+ resolve: "skill-evaluated-promotion-durability-resolve",
25
+ });
26
+
27
+ const DIGEST_PATTERN = /^sha256:[a-f0-9]{64}$/u;
28
+ const ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._:/-]{0,255}$/u;
29
+ const ADAPTER_OPTION_KEYS = new Set([
30
+ "authority",
31
+ "maximumEvidenceAgeMs",
32
+ "maximumGracePeriodMs",
33
+ "maximumOperationMs",
34
+ "now",
35
+ ]);
36
+ const MAXIMUM_OPERATION_MS = 60_000;
37
+ const MAXIMUM_EVIDENCE_AGE_MS = 24 * 60 * 60 * 1000;
38
+ const MAXIMUM_GRACE_PERIOD_MS = 7 * 24 * 60 * 60 * 1000;
39
+ const CLOCK_SKEW_MS = 5_000;
40
+ const NATIVE_SET_TIMEOUT = globalThis.setTimeout.bind(globalThis);
41
+ const NATIVE_CLEAR_TIMEOUT = globalThis.clearTimeout.bind(globalThis);
42
+ const NATIVE_PROMISE = globalThis.Promise;
43
+ const NATIVE_PROMISE_RACE = NATIVE_PROMISE.race.bind(NATIVE_PROMISE);
44
+ const NATIVE_PROMISE_RESOLVE = NATIVE_PROMISE.resolve.bind(NATIVE_PROMISE);
45
+ const AUTHORITY_KEYS = new Set([
46
+ "schema",
47
+ "authorityId",
48
+ "trust",
49
+ "revision",
50
+ "handlerArtifactDigest",
51
+ "attestationTrust",
52
+ "attestationGraceTrusts",
53
+ "attestationRevocations",
54
+ "retain",
55
+ "resolve",
56
+ "verifyAttestation",
57
+ ]);
58
+ const RESOLVE_REQUEST_KEYS = new Set(["schema", "tenantId", "receiptDigest"]);
59
+ const DURABILITY_RECEIPT_KEYS = new Set([
60
+ "schema",
61
+ "authenticated",
62
+ "durable",
63
+ "authorityId",
64
+ "revision",
65
+ "handlerArtifactDigest",
66
+ "tenantId",
67
+ "receiptDigest",
68
+ "persistedAt",
69
+ "persistenceReceiptDigest",
70
+ "attestation",
71
+ ]);
72
+ const DURABILITY_RESOLUTION_KEYS = new Set([
73
+ "schema",
74
+ "authenticated",
75
+ "durable",
76
+ "authorityId",
77
+ "revision",
78
+ "handlerArtifactDigest",
79
+ "tenantId",
80
+ "receiptDigest",
81
+ "matrixReceipt",
82
+ "resolvedAt",
83
+ "resolutionReceiptDigest",
84
+ "attestation",
85
+ ]);
86
+ const TRUST_KEYS = new Set([
87
+ "algorithm",
88
+ "issuer",
89
+ "keyId",
90
+ "trustPolicyDigest",
91
+ ]);
92
+ const ATTESTATION_KEYS = new Set([...TRUST_KEYS, "value"]);
93
+ const GRACE_TRUST_KEYS = new Set(["trust", "notAfter"]);
94
+ const REVOCATION_KEYS = new Set(["revision", "keyIds"]);
95
+ const MAX_GRACE_TRUSTS = 8;
96
+ const MAX_REVOKED_KEYS = 64;
97
+ const RETAIN_ATTESTATION_CORE_KEYS = new Set([
98
+ "schema",
99
+ "authenticated",
100
+ "durable",
101
+ "authorityId",
102
+ "revision",
103
+ "handlerArtifactDigest",
104
+ "tenantId",
105
+ "receiptDigest",
106
+ "persistedAt",
107
+ "persistenceReceiptDigest",
108
+ ]);
109
+ const RESOLVE_ATTESTATION_CORE_KEYS = new Set([
110
+ "schema",
111
+ "authenticated",
112
+ "durable",
113
+ "authorityId",
114
+ "revision",
115
+ "handlerArtifactDigest",
116
+ "tenantId",
117
+ "receiptDigest",
118
+ "resolvedAt",
119
+ "resolutionReceiptDigest",
120
+ ]);
121
+
122
+ export class SkillEvaluatedPromotionDurabilityError extends Error {
123
+ constructor(code, message, details = {}) {
124
+ super(message, details.cause ? { cause: details.cause } : undefined);
125
+ this.name = "SkillEvaluatedPromotionDurabilityError";
126
+ this.code = code;
127
+ for (const [key, value] of Object.entries(details)) {
128
+ if (key !== "cause") this[key] = value;
129
+ }
130
+ }
131
+ }
132
+
133
+ function failure(code, message, details = {}) {
134
+ return new SkillEvaluatedPromotionDurabilityError(code, message, details);
135
+ }
136
+
137
+ function assertRecord(value, keys, label) {
138
+ if (
139
+ !value ||
140
+ typeof value !== "object" ||
141
+ Array.isArray(value) ||
142
+ utilTypes.isProxy(value) ||
143
+ ![Object.prototype, null].includes(Object.getPrototypeOf(value))
144
+ ) {
145
+ throw failure(
146
+ "SKILL_EVALUATED_PROMOTION_DURABILITY_INVALID",
147
+ `${label} must be a plain object`,
148
+ );
149
+ }
150
+ const ownKeys = Reflect.ownKeys(value);
151
+ if (
152
+ ownKeys.length !== keys.size ||
153
+ ownKeys.some((key) => typeof key !== "string" || !keys.has(key))
154
+ ) {
155
+ throw failure(
156
+ "SKILL_EVALUATED_PROMOTION_DURABILITY_INVALID",
157
+ `${label} must contain exactly the supported fields`,
158
+ );
159
+ }
160
+ for (const key of ownKeys) {
161
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
162
+ if (!descriptor || !("value" in descriptor) || !descriptor.enumerable) {
163
+ throw failure(
164
+ "SKILL_EVALUATED_PROMOTION_DURABILITY_INVALID",
165
+ `${label}.${String(key)} must be an enumerable own data property`,
166
+ );
167
+ }
168
+ }
169
+ }
170
+
171
+ function normalizeId(value, label) {
172
+ if (typeof value !== "string" || !ID_PATTERN.test(value)) {
173
+ throw failure(
174
+ "SKILL_EVALUATED_PROMOTION_DURABILITY_INVALID",
175
+ `${label} is invalid`,
176
+ );
177
+ }
178
+ return value;
179
+ }
180
+
181
+ function normalizeDigest(value, label) {
182
+ if (typeof value !== "string" || !DIGEST_PATTERN.test(value)) {
183
+ throw failure(
184
+ "SKILL_EVALUATED_PROMOTION_DURABILITY_INVALID",
185
+ `${label} must be a lowercase SHA-256 digest`,
186
+ );
187
+ }
188
+ return value;
189
+ }
190
+
191
+ function normalizeSignature(value, label) {
192
+ if (typeof value !== "string" || value.length < 1 || value.length > 16_384) {
193
+ throw failure(
194
+ "SKILL_EVALUATED_PROMOTION_DURABILITY_INVALID",
195
+ `${label} must be a bounded signature`,
196
+ );
197
+ }
198
+ return value;
199
+ }
200
+
201
+ function normalizeTrust(value, label) {
202
+ assertRecord(value, TRUST_KEYS, label);
203
+ return deepFreeze({
204
+ algorithm: normalizeId(value.algorithm, `${label}.algorithm`),
205
+ issuer: normalizeId(value.issuer, `${label}.issuer`),
206
+ keyId: normalizeId(value.keyId, `${label}.keyId`),
207
+ trustPolicyDigest: normalizeDigest(
208
+ value.trustPolicyDigest,
209
+ `${label}.trustPolicyDigest`,
210
+ ),
211
+ });
212
+ }
213
+
214
+ function normalizeAttestation(value, label) {
215
+ assertRecord(value, ATTESTATION_KEYS, label);
216
+ return deepFreeze({
217
+ algorithm: normalizeId(value.algorithm, `${label}.algorithm`),
218
+ issuer: normalizeId(value.issuer, `${label}.issuer`),
219
+ keyId: normalizeId(value.keyId, `${label}.keyId`),
220
+ trustPolicyDigest: normalizeDigest(
221
+ value.trustPolicyDigest,
222
+ `${label}.trustPolicyDigest`,
223
+ ),
224
+ value: normalizeSignature(value.value, `${label}.value`),
225
+ });
226
+ }
227
+
228
+ function sameTrust(left, right) {
229
+ for (const key of TRUST_KEYS) {
230
+ if (left[key] !== right[key]) return false;
231
+ }
232
+ return true;
233
+ }
234
+
235
+ function normalizeGraceTrusts(value, activeTrust) {
236
+ if (
237
+ !Array.isArray(value) ||
238
+ utilTypes.isProxy(value) ||
239
+ Object.getPrototypeOf(value) !== Array.prototype ||
240
+ value.length > MAX_GRACE_TRUSTS
241
+ ) {
242
+ throw failure(
243
+ "SKILL_EVALUATED_PROMOTION_DURABILITY_INVALID",
244
+ `attestationGraceTrusts must be a standard array with at most ${MAX_GRACE_TRUSTS} entries`,
245
+ );
246
+ }
247
+ const ownKeys = Reflect.ownKeys(value);
248
+ const expectedKeys = new Set([
249
+ "length",
250
+ ...Array.from({ length: value.length }, (_, index) => String(index)),
251
+ ]);
252
+ if (
253
+ ownKeys.length !== expectedKeys.size ||
254
+ ownKeys.some((key) => typeof key !== "string" || !expectedKeys.has(key))
255
+ ) {
256
+ throw failure(
257
+ "SKILL_EVALUATED_PROMOTION_DURABILITY_INVALID",
258
+ "attestationGraceTrusts must be dense and contain only indexes",
259
+ );
260
+ }
261
+ const seenKeyIds = new Set([activeTrust.keyId]);
262
+ const normalized = [];
263
+ for (let index = 0; index < value.length; index += 1) {
264
+ const entryDescriptor = Object.getOwnPropertyDescriptor(
265
+ value,
266
+ String(index),
267
+ );
268
+ if (
269
+ !entryDescriptor ||
270
+ !("value" in entryDescriptor) ||
271
+ !entryDescriptor.enumerable
272
+ ) {
273
+ throw failure(
274
+ "SKILL_EVALUATED_PROMOTION_DURABILITY_INVALID",
275
+ `attestationGraceTrusts[${index}] must be an enumerable own data property`,
276
+ );
277
+ }
278
+ const entry = entryDescriptor.value;
279
+ assertRecord(entry, GRACE_TRUST_KEYS, `attestationGraceTrusts[${index}]`);
280
+ const trust = normalizeTrust(
281
+ entry.trust,
282
+ `attestationGraceTrusts[${index}].trust`,
283
+ );
284
+ if (seenKeyIds.has(trust.keyId)) {
285
+ throw failure(
286
+ "SKILL_EVALUATED_PROMOTION_DURABILITY_INVALID",
287
+ "attestation active and grace keyId values must be globally unique",
288
+ );
289
+ }
290
+ seenKeyIds.add(trust.keyId);
291
+ normalized.push(
292
+ deepFreeze({
293
+ trust,
294
+ notAfter: normalizeTime(
295
+ entry.notAfter,
296
+ `attestationGraceTrusts[${index}].notAfter`,
297
+ ),
298
+ }),
299
+ );
300
+ }
301
+ return deepFreeze(normalized);
302
+ }
303
+
304
+ function normalizeRevocations(value, activeTrust) {
305
+ assertRecord(value, REVOCATION_KEYS, "attestationRevocations");
306
+ if (!Number.isSafeInteger(value.revision) || value.revision < 1) {
307
+ throw failure(
308
+ "SKILL_EVALUATED_PROMOTION_DURABILITY_INVALID",
309
+ "attestationRevocations.revision must be a positive safe integer",
310
+ );
311
+ }
312
+ const keyIds = value.keyIds;
313
+ if (
314
+ !Array.isArray(keyIds) ||
315
+ utilTypes.isProxy(keyIds) ||
316
+ Object.getPrototypeOf(keyIds) !== Array.prototype ||
317
+ keyIds.length > MAX_REVOKED_KEYS
318
+ ) {
319
+ throw failure(
320
+ "SKILL_EVALUATED_PROMOTION_DURABILITY_INVALID",
321
+ `attestationRevocations.keyIds must be a standard array with at most ${MAX_REVOKED_KEYS} entries`,
322
+ );
323
+ }
324
+ const ownKeys = Reflect.ownKeys(keyIds);
325
+ const expectedKeys = new Set([
326
+ "length",
327
+ ...Array.from({ length: keyIds.length }, (_, index) => String(index)),
328
+ ]);
329
+ if (
330
+ ownKeys.length !== expectedKeys.size ||
331
+ ownKeys.some((key) => typeof key !== "string" || !expectedKeys.has(key))
332
+ ) {
333
+ throw failure(
334
+ "SKILL_EVALUATED_PROMOTION_DURABILITY_INVALID",
335
+ "attestationRevocations.keyIds must be dense and contain only indexes",
336
+ );
337
+ }
338
+ const normalizedKeyIds = [];
339
+ const seenKeyIds = new Set();
340
+ for (let index = 0; index < keyIds.length; index += 1) {
341
+ const entryDescriptor = Object.getOwnPropertyDescriptor(
342
+ keyIds,
343
+ String(index),
344
+ );
345
+ if (
346
+ !entryDescriptor ||
347
+ !("value" in entryDescriptor) ||
348
+ !entryDescriptor.enumerable
349
+ ) {
350
+ throw failure(
351
+ "SKILL_EVALUATED_PROMOTION_DURABILITY_INVALID",
352
+ `attestationRevocations.keyIds[${index}] must be an enumerable own data property`,
353
+ );
354
+ }
355
+ const keyId = normalizeId(
356
+ entryDescriptor.value,
357
+ `attestationRevocations.keyIds[${index}]`,
358
+ );
359
+ if (seenKeyIds.has(keyId)) {
360
+ throw failure(
361
+ "SKILL_EVALUATED_PROMOTION_DURABILITY_INVALID",
362
+ "attestationRevocations.keyIds must be unique",
363
+ );
364
+ }
365
+ seenKeyIds.add(keyId);
366
+ normalizedKeyIds.push(keyId);
367
+ }
368
+ if (seenKeyIds.has(activeTrust.keyId)) {
369
+ throw failure(
370
+ "SKILL_EVALUATED_PROMOTION_DURABILITY_REVOKED",
371
+ "active attestation keyId is revoked",
372
+ );
373
+ }
374
+ return deepFreeze({
375
+ revision: value.revision,
376
+ keyIds: normalizedKeyIds,
377
+ });
378
+ }
379
+
380
+ function normalizeTime(value, label) {
381
+ if (
382
+ typeof value !== "string" ||
383
+ !Number.isFinite(Date.parse(value)) ||
384
+ new Date(value).toISOString() !== value
385
+ ) {
386
+ throw failure(
387
+ "SKILL_EVALUATED_PROMOTION_DURABILITY_INVALID",
388
+ `${label} must be a canonical ISO timestamp`,
389
+ );
390
+ }
391
+ return value;
392
+ }
393
+
394
+ function normalizeMaximumOperationMs(value) {
395
+ if (
396
+ !Number.isSafeInteger(value) ||
397
+ value < 1 ||
398
+ value > MAXIMUM_OPERATION_MS
399
+ ) {
400
+ throw failure(
401
+ "SKILL_EVALUATED_PROMOTION_DURABILITY_INVALID",
402
+ `maximumOperationMs must be an integer from 1 through ${MAXIMUM_OPERATION_MS}`,
403
+ );
404
+ }
405
+ return value;
406
+ }
407
+
408
+ function normalizeMaximumEvidenceAgeMs(value) {
409
+ if (
410
+ !Number.isSafeInteger(value) ||
411
+ value < 1 ||
412
+ value > MAXIMUM_EVIDENCE_AGE_MS
413
+ ) {
414
+ throw failure(
415
+ "SKILL_EVALUATED_PROMOTION_DURABILITY_INVALID",
416
+ `maximumEvidenceAgeMs must be an integer from 1 through ${MAXIMUM_EVIDENCE_AGE_MS}`,
417
+ );
418
+ }
419
+ return value;
420
+ }
421
+
422
+ function normalizeMaximumGracePeriodMs(value) {
423
+ if (
424
+ !Number.isSafeInteger(value) ||
425
+ value < 1 ||
426
+ value > MAXIMUM_GRACE_PERIOD_MS
427
+ ) {
428
+ throw failure(
429
+ "SKILL_EVALUATED_PROMOTION_DURABILITY_INVALID",
430
+ `maximumGracePeriodMs must be an integer from 1 through ${MAXIMUM_GRACE_PERIOD_MS}`,
431
+ );
432
+ }
433
+ return value;
434
+ }
435
+
436
+ function captureClock(value) {
437
+ if (typeof value !== "function" || utilTypes.isProxy(value)) {
438
+ throw failure(
439
+ "SKILL_EVALUATED_PROMOTION_DURABILITY_INVALID",
440
+ "now must be a trusted clock function",
441
+ );
442
+ }
443
+ return Object.freeze(() => normalizeTime(value(), "trusted clock result"));
444
+ }
445
+
446
+ function assertFreshEvidence(value, trustedNow, maximumEvidenceAgeMs, label) {
447
+ const evidenceMs = Date.parse(value);
448
+ const nowMs = Date.parse(trustedNow);
449
+ if (
450
+ evidenceMs > nowMs + CLOCK_SKEW_MS ||
451
+ nowMs - evidenceMs > maximumEvidenceAgeMs
452
+ ) {
453
+ throw failure(
454
+ "SKILL_EVALUATED_PROMOTION_DURABILITY_STALE",
455
+ `${label} is outside the accepted evidence window`,
456
+ );
457
+ }
458
+ }
459
+
460
+ function assertBoundedGraceWindows(
461
+ descriptor,
462
+ trustedNow,
463
+ maximumGracePeriodMs,
464
+ ) {
465
+ const nowMs = Date.parse(trustedNow);
466
+ for (const grace of descriptor.attestationGraceTrusts) {
467
+ if (Date.parse(grace.notAfter) - nowMs > maximumGracePeriodMs) {
468
+ throw failure(
469
+ "SKILL_EVALUATED_PROMOTION_DURABILITY_INVALID",
470
+ "attestation grace trust exceeds maximumGracePeriodMs",
471
+ );
472
+ }
473
+ }
474
+ }
475
+
476
+ function deepFreeze(value, seen = new WeakSet()) {
477
+ if (!value || typeof value !== "object" || seen.has(value)) return value;
478
+ if (utilTypes.isProxy(value)) {
479
+ throw failure(
480
+ "SKILL_EVALUATED_PROMOTION_DURABILITY_INVALID",
481
+ "durability evidence must not contain proxies",
482
+ );
483
+ }
484
+ seen.add(value);
485
+ for (const key of Reflect.ownKeys(value)) {
486
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
487
+ if (!descriptor || !("value" in descriptor)) {
488
+ throw failure(
489
+ "SKILL_EVALUATED_PROMOTION_DURABILITY_INVALID",
490
+ "durability evidence must contain only data properties",
491
+ );
492
+ }
493
+ deepFreeze(descriptor.value, seen);
494
+ }
495
+ return Object.freeze(value);
496
+ }
497
+
498
+ function receiptIdentity(matrixReceipt) {
499
+ const envelope = JSON.parse(
500
+ buildSkillEvaluatedPromotionReceiptEnvelope(matrixReceipt),
501
+ );
502
+ const tenantId = normalizeId(
503
+ Object.getOwnPropertyDescriptor(matrixReceipt, "tenantId")?.value,
504
+ "matrix receipt tenantId",
505
+ );
506
+ return { tenantId, receiptDigest: envelope.receiptDigest };
507
+ }
508
+
509
+ function captureAuthority(value) {
510
+ assertRecord(value, AUTHORITY_KEYS, "durability authority");
511
+ if (
512
+ value.schema !== SKILL_EVALUATED_PROMOTION_DURABILITY_AUTHORITY_SCHEMA ||
513
+ value.trust !== "trusted" ||
514
+ !Number.isSafeInteger(value.revision) ||
515
+ value.revision < 1 ||
516
+ typeof value.retain !== "function" ||
517
+ typeof value.resolve !== "function" ||
518
+ typeof value.verifyAttestation !== "function" ||
519
+ utilTypes.isProxy(value.retain) ||
520
+ utilTypes.isProxy(value.resolve) ||
521
+ utilTypes.isProxy(value.verifyAttestation)
522
+ ) {
523
+ throw failure(
524
+ "SKILL_EVALUATED_PROMOTION_DURABILITY_INVALID",
525
+ "durability authority descriptor is invalid",
526
+ );
527
+ }
528
+ const attestationTrust = normalizeTrust(
529
+ value.attestationTrust,
530
+ "authority attestationTrust",
531
+ );
532
+ const descriptor = deepFreeze({
533
+ authorityId: normalizeId(value.authorityId, "authorityId"),
534
+ trust: value.trust,
535
+ revision: value.revision,
536
+ handlerArtifactDigest: normalizeDigest(
537
+ value.handlerArtifactDigest,
538
+ "handlerArtifactDigest",
539
+ ),
540
+ attestationTrust,
541
+ attestationGraceTrusts: normalizeGraceTrusts(
542
+ value.attestationGraceTrusts,
543
+ attestationTrust,
544
+ ),
545
+ attestationRevocations: normalizeRevocations(
546
+ value.attestationRevocations,
547
+ attestationTrust,
548
+ ),
549
+ });
550
+ const retain = value.retain.bind(value);
551
+ const resolve = value.resolve.bind(value);
552
+ const verifyAttestation = value.verifyAttestation.bind(value);
553
+ Object.freeze(value);
554
+ return { descriptor, retain, resolve, verifyAttestation };
555
+ }
556
+
557
+ function attestationCore(value, keys, label) {
558
+ const core = {};
559
+ for (const key of keys) {
560
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
561
+ if (!descriptor || !("value" in descriptor)) {
562
+ throw failure(
563
+ "SKILL_EVALUATED_PROMOTION_DURABILITY_INVALID",
564
+ `${label}.${key} must be an own data property`,
565
+ );
566
+ }
567
+ core[key] = descriptor.value;
568
+ }
569
+ return core;
570
+ }
571
+
572
+ export function computeSkillEvaluatedPromotionDurabilityAttestationDigest(
573
+ value,
574
+ ) {
575
+ if (!value || typeof value !== "object" || utilTypes.isProxy(value)) {
576
+ throw failure(
577
+ "SKILL_EVALUATED_PROMOTION_DURABILITY_INVALID",
578
+ "durability attestation payload must be a plain object",
579
+ );
580
+ }
581
+ const schema = Object.getOwnPropertyDescriptor(value, "schema")?.value;
582
+ const keys =
583
+ schema === SKILL_EVALUATED_PROMOTION_DURABILITY_RECEIPT_SCHEMA
584
+ ? RETAIN_ATTESTATION_CORE_KEYS
585
+ : schema === SKILL_EVALUATED_PROMOTION_DURABILITY_RESOLUTION_SCHEMA
586
+ ? RESOLVE_ATTESTATION_CORE_KEYS
587
+ : null;
588
+ if (keys === null) {
589
+ throw failure(
590
+ "SKILL_EVALUATED_PROMOTION_DURABILITY_INVALID",
591
+ "durability attestation payload schema is invalid",
592
+ );
593
+ }
594
+ const purpose =
595
+ schema === SKILL_EVALUATED_PROMOTION_DURABILITY_RECEIPT_SCHEMA
596
+ ? SKILL_EVALUATED_PROMOTION_DURABILITY_ATTESTATION_PURPOSES.retain
597
+ : SKILL_EVALUATED_PROMOTION_DURABILITY_ATTESTATION_PURPOSES.resolve;
598
+ return `sha256:${createHash("sha256")
599
+ .update(
600
+ `chainlesschain.skill-evaluated-promotion-durability-attestation/v1\0${purpose}\0${JSON.stringify(attestationCore(value, keys, "attestation payload"))}`,
601
+ "utf8",
602
+ )
603
+ .digest("hex")}`;
604
+ }
605
+
606
+ function selectAttestationTrust(descriptor, attestation, trustedNow, label) {
607
+ if (descriptor.attestationRevocations.keyIds.includes(attestation.keyId)) {
608
+ throw failure(
609
+ "SKILL_EVALUATED_PROMOTION_DURABILITY_REVOKED",
610
+ `${label} uses a revoked attestation key`,
611
+ );
612
+ }
613
+ if (sameTrust(attestation, descriptor.attestationTrust)) {
614
+ return descriptor.attestationTrust;
615
+ }
616
+ const trustedNowMs = Date.parse(trustedNow);
617
+ for (const grace of descriptor.attestationGraceTrusts) {
618
+ if (sameTrust(attestation, grace.trust)) {
619
+ if (trustedNowMs <= Date.parse(grace.notAfter) + CLOCK_SKEW_MS) {
620
+ return grace.trust;
621
+ }
622
+ throw failure(
623
+ "SKILL_EVALUATED_PROMOTION_DURABILITY_STALE",
624
+ `${label} uses an expired grace key`,
625
+ );
626
+ }
627
+ }
628
+ throw failure(
629
+ "SKILL_EVALUATED_PROMOTION_DURABILITY_REJECTED",
630
+ `${label} does not match an active or grace trust identity`,
631
+ );
632
+ }
633
+
634
+ async function verifyAuthorityAttestation(
635
+ captured,
636
+ result,
637
+ purpose,
638
+ trustedNow,
639
+ label,
640
+ ) {
641
+ const attestation = normalizeAttestation(
642
+ result.attestation,
643
+ `${label} attestation`,
644
+ );
645
+ const selectedTrust = selectAttestationTrust(
646
+ captured.descriptor,
647
+ attestation,
648
+ trustedNow,
649
+ label,
650
+ );
651
+ const payloadDigest =
652
+ computeSkillEvaluatedPromotionDurabilityAttestationDigest(result);
653
+ let verified;
654
+ try {
655
+ verified = await captured.verifyAttestation(
656
+ deepFreeze({
657
+ purpose,
658
+ payloadDigest,
659
+ attestation,
660
+ selectedTrust,
661
+ revocationRevision: captured.descriptor.attestationRevocations.revision,
662
+ }),
663
+ );
664
+ } catch (cause) {
665
+ throw failure(
666
+ "SKILL_EVALUATED_PROMOTION_DURABILITY_UNAVAILABLE",
667
+ `${label} attestation verifier failed`,
668
+ { cause },
669
+ );
670
+ }
671
+ if (verified !== true) {
672
+ throw failure(
673
+ "SKILL_EVALUATED_PROMOTION_DURABILITY_REJECTED",
674
+ `${label} attestation is invalid`,
675
+ );
676
+ }
677
+ }
678
+
679
+ async function runAuthorityOperation(
680
+ operation,
681
+ request,
682
+ maximumOperationMs,
683
+ label,
684
+ ) {
685
+ const controller = new AbortController();
686
+ let timer;
687
+ const timeout = new NATIVE_PROMISE((_, reject) => {
688
+ timer = NATIVE_SET_TIMEOUT(() => {
689
+ controller.abort(
690
+ failure(
691
+ "SKILL_EVALUATED_PROMOTION_DURABILITY_TIMEOUT",
692
+ `${label} exceeded its bounded deadline`,
693
+ ),
694
+ );
695
+ reject(controller.signal.reason);
696
+ }, maximumOperationMs);
697
+ });
698
+ try {
699
+ return await NATIVE_PROMISE_RACE([
700
+ NATIVE_PROMISE_RESOLVE(
701
+ operation(request, Object.freeze({ signal: controller.signal })),
702
+ ),
703
+ timeout,
704
+ ]);
705
+ } finally {
706
+ NATIVE_CLEAR_TIMEOUT(timer);
707
+ }
708
+ }
709
+
710
+ function assertAuthorityBinding(result, authority, identity, label) {
711
+ if (
712
+ result.authenticated !== true ||
713
+ result.durable !== true ||
714
+ result.authorityId !== authority.authorityId ||
715
+ result.revision !== authority.revision ||
716
+ result.handlerArtifactDigest !== authority.handlerArtifactDigest ||
717
+ result.tenantId !== identity.tenantId ||
718
+ result.receiptDigest !== identity.receiptDigest
719
+ ) {
720
+ throw failure(
721
+ "SKILL_EVALUATED_PROMOTION_DURABILITY_REJECTED",
722
+ `${label} is not authenticated, durable, and exactly bound`,
723
+ );
724
+ }
725
+ }
726
+
727
+ export function createSkillEvaluatedPromotionDurabilityAdapter(options = {}) {
728
+ assertRecord(options, ADAPTER_OPTION_KEYS, "durability adapter options");
729
+ const captured = captureAuthority(options.authority);
730
+ const maximumEvidenceAgeMs = normalizeMaximumEvidenceAgeMs(
731
+ options.maximumEvidenceAgeMs,
732
+ );
733
+ const maximumGracePeriodMs = normalizeMaximumGracePeriodMs(
734
+ options.maximumGracePeriodMs,
735
+ );
736
+ const maximumOperationMs = normalizeMaximumOperationMs(
737
+ options.maximumOperationMs,
738
+ );
739
+ const now = captureClock(options.now);
740
+ assertBoundedGraceWindows(captured.descriptor, now(), maximumGracePeriodMs);
741
+ const retain = async (matrixReceipt) => {
742
+ const identity = receiptIdentity(matrixReceipt);
743
+ const request = deepFreeze({
744
+ schema: SKILL_EVALUATED_PROMOTION_DURABILITY_RETAIN_REQUEST_SCHEMA,
745
+ ...identity,
746
+ matrixReceipt,
747
+ });
748
+ let result;
749
+ try {
750
+ result = await runAuthorityOperation(
751
+ captured.retain,
752
+ request,
753
+ maximumOperationMs,
754
+ "durability retain",
755
+ );
756
+ } catch (cause) {
757
+ if (cause instanceof SkillEvaluatedPromotionDurabilityError) throw cause;
758
+ throw failure(
759
+ "SKILL_EVALUATED_PROMOTION_DURABILITY_UNAVAILABLE",
760
+ "durability authority failed to retain the matrix receipt",
761
+ { cause },
762
+ );
763
+ }
764
+ assertRecord(result, DURABILITY_RECEIPT_KEYS, "durability receipt");
765
+ if (result.schema !== SKILL_EVALUATED_PROMOTION_DURABILITY_RECEIPT_SCHEMA) {
766
+ throw failure(
767
+ "SKILL_EVALUATED_PROMOTION_DURABILITY_REJECTED",
768
+ "durability receipt schema is invalid",
769
+ );
770
+ }
771
+ assertAuthorityBinding(result, captured.descriptor, identity, "receipt");
772
+ const persistedAt = normalizeTime(result.persistedAt, "persistedAt");
773
+ const trustedNow = now();
774
+ assertFreshEvidence(
775
+ persistedAt,
776
+ trustedNow,
777
+ maximumEvidenceAgeMs,
778
+ "durability receipt",
779
+ );
780
+ normalizeDigest(
781
+ result.persistenceReceiptDigest,
782
+ "persistenceReceiptDigest",
783
+ );
784
+ await verifyAuthorityAttestation(
785
+ captured,
786
+ result,
787
+ SKILL_EVALUATED_PROMOTION_DURABILITY_ATTESTATION_PURPOSES.retain,
788
+ trustedNow,
789
+ "durability receipt",
790
+ );
791
+ return deepFreeze({ ...result });
792
+ };
793
+ const resolverDescriptor = {
794
+ authorityId: captured.descriptor.authorityId,
795
+ trust: captured.descriptor.trust,
796
+ revision: captured.descriptor.revision,
797
+ handlerArtifactDigest: captured.descriptor.handlerArtifactDigest,
798
+ };
799
+ const resolver = {
800
+ schema: SKILL_EVALUATED_PROMOTION_RECEIPT_RESOLVER_SCHEMA,
801
+ ...resolverDescriptor,
802
+ async resolve(input) {
803
+ assertRecord(input, RESOLVE_REQUEST_KEYS, "receipt resolver request");
804
+ if (
805
+ input.schema !==
806
+ SKILL_EVALUATED_PROMOTION_RECEIPT_RESOLUTION_REQUEST_SCHEMA
807
+ ) {
808
+ throw failure(
809
+ "SKILL_EVALUATED_PROMOTION_DURABILITY_INVALID",
810
+ "receipt resolver request schema is invalid",
811
+ );
812
+ }
813
+ const identity = {
814
+ tenantId: normalizeId(input.tenantId, "resolver tenantId"),
815
+ receiptDigest: normalizeDigest(
816
+ input.receiptDigest,
817
+ "resolver receiptDigest",
818
+ ),
819
+ };
820
+ const request = deepFreeze({
821
+ schema: SKILL_EVALUATED_PROMOTION_DURABILITY_RESOLVE_REQUEST_SCHEMA,
822
+ ...identity,
823
+ });
824
+ let result;
825
+ try {
826
+ result = await runAuthorityOperation(
827
+ captured.resolve,
828
+ request,
829
+ maximumOperationMs,
830
+ "durability resolve",
831
+ );
832
+ } catch (cause) {
833
+ if (cause instanceof SkillEvaluatedPromotionDurabilityError)
834
+ throw cause;
835
+ throw failure(
836
+ "SKILL_EVALUATED_PROMOTION_DURABILITY_UNAVAILABLE",
837
+ "durability authority failed to resolve the matrix receipt",
838
+ { cause },
839
+ );
840
+ }
841
+ assertRecord(result, DURABILITY_RESOLUTION_KEYS, "durability resolution");
842
+ if (
843
+ result.schema !== SKILL_EVALUATED_PROMOTION_DURABILITY_RESOLUTION_SCHEMA
844
+ ) {
845
+ throw failure(
846
+ "SKILL_EVALUATED_PROMOTION_DURABILITY_REJECTED",
847
+ "durability resolution schema is invalid",
848
+ );
849
+ }
850
+ assertAuthorityBinding(
851
+ result,
852
+ captured.descriptor,
853
+ identity,
854
+ "resolution",
855
+ );
856
+ const resolvedIdentity = receiptIdentity(result.matrixReceipt);
857
+ if (
858
+ resolvedIdentity.tenantId !== identity.tenantId ||
859
+ resolvedIdentity.receiptDigest !== identity.receiptDigest
860
+ ) {
861
+ throw failure(
862
+ "SKILL_EVALUATED_PROMOTION_DURABILITY_REJECTED",
863
+ "resolved matrix receipt differs from the durable lookup subject",
864
+ );
865
+ }
866
+ const resolvedAt = normalizeTime(result.resolvedAt, "resolvedAt");
867
+ const trustedNow = now();
868
+ assertFreshEvidence(
869
+ resolvedAt,
870
+ trustedNow,
871
+ maximumEvidenceAgeMs,
872
+ "durability resolution",
873
+ );
874
+ normalizeDigest(
875
+ result.resolutionReceiptDigest,
876
+ "resolutionReceiptDigest",
877
+ );
878
+ await verifyAuthorityAttestation(
879
+ captured,
880
+ result,
881
+ SKILL_EVALUATED_PROMOTION_DURABILITY_ATTESTATION_PURPOSES.resolve,
882
+ trustedNow,
883
+ "durability resolution",
884
+ );
885
+ return deepFreeze({
886
+ schema: SKILL_EVALUATED_PROMOTION_RECEIPT_RESOLUTION_SCHEMA,
887
+ ...resolverDescriptor,
888
+ tenantId: identity.tenantId,
889
+ receiptDigest: identity.receiptDigest,
890
+ matrixReceipt: result.matrixReceipt,
891
+ resolvedAt: result.resolvedAt,
892
+ });
893
+ },
894
+ };
895
+ return Object.freeze({
896
+ retain: Object.freeze(retain),
897
+ resolver: Object.freeze(resolver),
898
+ });
899
+ }