chainlesschain 0.166.18 → 0.166.21

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 (214) hide show
  1. package/package.json +2 -2
  2. package/src/assets/web-panel/assets/{AIOps-CQSBl3hY.js → AIOps-BjMnsUci.js} +1 -1
  3. package/src/assets/web-panel/assets/{ActionButton-IQt-vRLt.js → ActionButton-DdYFP03A.js} +1 -1
  4. package/src/assets/web-panel/assets/{Analytics-DkHC8O7k.js → Analytics-Bb8TuuK_.js} +3 -3
  5. package/src/assets/web-panel/assets/{AppLayout-CSti2P2T.js → AppLayout-Kn3TIOtk.js} +5 -5
  6. package/src/assets/web-panel/assets/{Artifacts-C57hxn3v.js → Artifacts-4IxpqI_b.js} +1 -1
  7. package/src/assets/web-panel/assets/{Audit-DByLntcf.js → Audit-BOV2caqU.js} +1 -1
  8. package/src/assets/web-panel/assets/{BackgroundAgents-D1Bd2EOa.js → BackgroundAgents-B86k-ay4.js} +1 -1
  9. package/src/assets/web-panel/assets/{Backup-VstHzHng.js → Backup-C5_ie1e3.js} +1 -1
  10. package/src/assets/web-panel/assets/{BaseInput-CLhdexIf.js → BaseInput-xpwg6QCW.js} +1 -1
  11. package/src/assets/web-panel/assets/{Chat-BefC_JZS.js → Chat-CVZOcZau.js} +6 -6
  12. package/src/assets/web-panel/assets/{ChatBubbleRenderer-DbXMvgmn.js → ChatBubbleRenderer-D8fPYhUu.js} +1 -1
  13. package/src/assets/web-panel/assets/{Checkbox-CEY982vx.js → Checkbox-MKTq3zdP.js} +1 -1
  14. package/src/assets/web-panel/assets/{Codegen-Dcm_DTvJ.js → Codegen-JUk3wzep.js} +1 -1
  15. package/src/assets/web-panel/assets/{Col-C8SSu4KA.js → Col-JPvTA0kC.js} +1 -1
  16. package/src/assets/web-panel/assets/{Community-BVV9vwRR.js → Community-Tqgl87NQ.js} +1 -1
  17. package/src/assets/web-panel/assets/{Compact-B7c5Vo18.js → Compact-BuAFYBmN.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compliance-Tq9jSZ5a.js → Compliance-CXS9WIPZ.js} +1 -1
  19. package/src/assets/web-panel/assets/{Cowork-BJUjT09Q.js → Cowork-Ds2bFHrr.js} +2 -2
  20. package/src/assets/web-panel/assets/{Cron-CjV9PEaS.js → Cron-C_dV_OeW.js} +2 -2
  21. package/src/assets/web-panel/assets/{Crosschain-Dl7ReL8F.js → Crosschain-BsO6tIRo.js} +1 -1
  22. package/src/assets/web-panel/assets/{DID-CG8PjWmM.js → DID-rNOFqBac.js} +2 -2
  23. package/src/assets/web-panel/assets/{Dashboard-CDBM6wmF.js → Dashboard-C2fcKKVY.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dropdown-8_55bXTD.js → Dropdown-Y7Ndr0X_.js} +1 -1
  25. package/src/assets/web-panel/assets/{EmailListRenderer-D3qOU1Cm.js → EmailListRenderer-DcP_uPmL.js} +1 -1
  26. package/src/assets/web-panel/assets/{FamilyGuardDashboard-Bv5oWMZF.js → FamilyGuardDashboard-Cwn3gDzk.js} +1 -1
  27. package/src/assets/web-panel/assets/{Federation-hpZ1xkKd.js → Federation-ClQuOsqb.js} +1 -1
  28. package/src/assets/web-panel/assets/{FormItemContext-BN7GT191.js → FormItemContext-DfwtmlcK.js} +1 -1
  29. package/src/assets/web-panel/assets/{GenericCardRenderer-PCRhfA7M.js → GenericCardRenderer-zNZhtbC5.js} +1 -1
  30. package/src/assets/web-panel/assets/{Git-CIlP2vy7.js → Git-BZmdW-G5.js} +2 -2
  31. package/src/assets/web-panel/assets/{Governance-81lgm7YL.js → Governance-CqBk4lEn.js} +1 -1
  32. package/src/assets/web-panel/assets/{Inference-Cs24xMOV.js → Inference-Dbmt3ZXk.js} +1 -1
  33. package/src/assets/web-panel/assets/{KnowledgeGraph-CrJLVCZo.js → KnowledgeGraph-hMTH6qf3.js} +1 -1
  34. package/src/assets/web-panel/assets/{Logs-DLyO8RKT.js → Logs-CkiYgiW2.js} +2 -2
  35. package/src/assets/web-panel/assets/{MarkdownRenderer-DBOqijrP.js → MarkdownRenderer-BL1FElXg.js} +1 -1
  36. package/src/assets/web-panel/assets/{Marketplace-Dz7AbQZc.js → Marketplace-CbB6wfin.js} +1 -1
  37. package/src/assets/web-panel/assets/{McpTools-BM0aFiWv.js → McpTools-BSwiFtte.js} +3 -3
  38. package/src/assets/web-panel/assets/{Memory-C9SJzENX.js → Memory-B03PeHrz.js} +2 -2
  39. package/src/assets/web-panel/assets/{MobileBridge-BO2HnNRk.js → MobileBridge-CRGrnd-X.js} +1 -1
  40. package/src/assets/web-panel/assets/{MobileProjects-CK_jMz0l.js → MobileProjects-CE_5v2kO.js} +1 -1
  41. package/src/assets/web-panel/assets/{Mtc-CfhrJsdO.js → Mtc-Dp11QVx1.js} +2 -2
  42. package/src/assets/web-panel/assets/{MtcAudit-BE2ELxgI.js → MtcAudit-CYu-3JBu.js} +5 -5
  43. package/src/assets/web-panel/assets/{Multisig-CgR_E3Jd.js → Multisig-CGyJ0Xl3.js} +3 -3
  44. package/src/assets/web-panel/assets/{NLProgramming-Cw9445_K.js → NLProgramming-CoWi_ov1.js} +1 -1
  45. package/src/assets/web-panel/assets/Notes-CgU9DDo9.js +7 -0
  46. package/src/assets/web-panel/assets/{NotificationSettings-DxHVh4uT.js → NotificationSettings-DX4I2b4W.js} +1 -1
  47. package/src/assets/web-panel/assets/OrderTableRenderer-CwHc15Zs.js +1 -0
  48. package/src/assets/web-panel/assets/{Organization-pPXJtWo4.js → Organization-oopLO_tk.js} +4 -4
  49. package/src/assets/web-panel/assets/{Overflow-YamdTJwA.js → Overflow-BFVvjMyf.js} +1 -1
  50. package/src/assets/web-panel/assets/{P2P-BvqP53x7.js → P2P-CBy5t-Tk.js} +2 -2
  51. package/src/assets/web-panel/assets/{PdhVaultBrowser-Blz1Xn2n.js → PdhVaultBrowser--YWJNsu6.js} +3 -3
  52. package/src/assets/web-panel/assets/{Permissions-CgFRQqFJ.js → Permissions-C2dZ8scb.js} +4 -4
  53. package/src/assets/web-panel/assets/{PersonalDataHub-CFeo3-6O.js → PersonalDataHub-Bs3l7Hlx.js} +4 -4
  54. package/src/assets/web-panel/assets/{Pipeline-BkaRojEK.js → Pipeline-DEBWbZuD.js} +1 -1
  55. package/src/assets/web-panel/assets/{Privacy-BNZEx2Qp.js → Privacy-CjHBb6NU.js} +1 -1
  56. package/src/assets/web-panel/assets/{ProjectInit-HUBOgEEK.js → ProjectInit-D2WipUz5.js} +2 -2
  57. package/src/assets/web-panel/assets/ProjectSettings-B6WfnrGB.js +2 -0
  58. package/src/assets/web-panel/assets/{Projects-Dc517BXp.js → Projects-FF_thRi6.js} +1 -1
  59. package/src/assets/web-panel/assets/{Providers-DTLf8bgj.js → Providers-CCv5M_Dv.js} +1 -1
  60. package/src/assets/web-panel/assets/{QrScannerModal-BBNjPszk.js → QrScannerModal-CGthxU54.js} +1 -1
  61. package/src/assets/web-panel/assets/{QuickAsk-DCsHvk3G.js → QuickAsk-CnPmXPFb.js} +1 -1
  62. package/src/assets/web-panel/assets/{Recommend-Dpr5YSop.js → Recommend-Df_tGEa9.js} +1 -1
  63. package/src/assets/web-panel/assets/{RemoteSession-DmKnvqGg.js → RemoteSession-Z58N0Loe.js} +2 -2
  64. package/src/assets/web-panel/assets/{Reputation-CSRfuurX.js → Reputation-CZTBQ2Vt.js} +1 -1
  65. package/src/assets/web-panel/assets/{Row-CDj3pQ_w.js → Row-CdK3YpCQ.js} +1 -1
  66. package/src/assets/web-panel/assets/{RssFeed-DI0a_kNq.js → RssFeed-CFMVT5sb.js} +3 -3
  67. package/src/assets/web-panel/assets/{Search-jAy7B2nU.js → Search-DrF8RIvD.js} +1 -1
  68. package/src/assets/web-panel/assets/{Security-CkHTqYhc.js → Security-Ddk2f2DM.js} +4 -4
  69. package/src/assets/web-panel/assets/{Services-CP-0Nzga.js → Services-CCuK-VOo.js} +2 -2
  70. package/src/assets/web-panel/assets/{Skeleton-BkF5-p3n.js → Skeleton-DxCpHzeM.js} +1 -1
  71. package/src/assets/web-panel/assets/{Skills-BDu-utDE.js → Skills-t2oTDgcv.js} +1 -1
  72. package/src/assets/web-panel/assets/{Sla-CQvq_2Qb.js → Sla-Df63M9_R.js} +1 -1
  73. package/src/assets/web-panel/assets/{SpeechSettings-T7Ap512g.js → SpeechSettings-l7ox6KuX.js} +1 -1
  74. package/src/assets/web-panel/assets/{SyncSettings-Bt-PLvot.js → SyncSettings-COd_tgPp.js} +2 -2
  75. package/src/assets/web-panel/assets/{Tasks-yLEcCogg.js → Tasks-CzDCcrik.js} +1 -1
  76. package/src/assets/web-panel/assets/{Templates-ByN3fmbr.js → Templates-D-vfxTGA.js} +1 -1
  77. package/src/assets/web-panel/assets/{Tenant-DBI7hITH.js → Tenant-BlpT_Gxc.js} +1 -1
  78. package/src/assets/web-panel/assets/{Terminal-B77_DlGX.js → Terminal-D5rq52Hg.js} +2 -2
  79. package/src/assets/web-panel/assets/TimelineRenderer-DdoMndkK.js +1 -0
  80. package/src/assets/web-panel/assets/{Tokens-BV2N6cR8.js → Tokens-BhgBsI6g.js} +1 -1
  81. package/src/assets/web-panel/assets/{Trigger-CjXWGH3p.js → Trigger-DwwzoikZ.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trust-uqXIq3WC.js → Trust-HkTpzXFb.js} +1 -1
  83. package/src/assets/web-panel/assets/{UkeySign-D-6qu4vY.js → UkeySign-D9nk6Ehe.js} +1 -1
  84. package/src/assets/web-panel/assets/{VideoEditing-CxGmx_2e.js → VideoEditing-BKk0rfoy.js} +1 -1
  85. package/src/assets/web-panel/assets/{Wallet-DSq7WlAg.js → Wallet-IVWIU_Lq.js} +4 -4
  86. package/src/assets/web-panel/assets/{WebAuthn-CDBiD57O.js → WebAuthn-CFTCpfsG.js} +4 -4
  87. package/src/assets/web-panel/assets/{WorkflowEditor-Z8f63TSb.js → WorkflowEditor-Dnf4Obif.js} +1 -1
  88. package/src/assets/web-panel/assets/{chat-B-UZFBjy.js → chat-D2snERdj.js} +1 -1
  89. package/src/assets/web-panel/assets/{colors-CFk7K-7Q.js → colors-DKEjK1N1.js} +1 -1
  90. package/src/assets/web-panel/assets/{compact-item-X0IVMvgi.js → compact-item-BEDLwQdt.js} +1 -1
  91. package/src/assets/web-panel/assets/{createContext-DWg4j2n6.js → createContext-DA9iW1a0.js} +1 -1
  92. package/src/assets/web-panel/assets/devWarning-DyhgpXPf.js +1 -0
  93. package/src/assets/web-panel/assets/{hasIn-CkVCwNNF.js → hasIn-5l2xEcY9.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-BipwEbTA.js → index-5pW4t1iD.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-5OcZHdzc.js → index-7P1b8HZo.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-Cvwu_rA_.js → index-B00GeekA.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-CbIAWbma.js → index-B4QYBliR.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-CNKFsBlz.js → index-B7_W_rYd.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-BoskgPt9.js → index-BO9dQjpt.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-CvOa-IFV.js → index-BZ5lY2zx.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-_-9k3Tna.js → index-B_eCoZgW.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-CbihMThv.js → index-BgfImyZI.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-DLSBks8h.js → index-Bq5P3piS.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-LU54bChK.js → index-Bqc8tdIF.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-Btqk6zWb.js → index-C7sKbM5s.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-D8uEL8Uw.js → index-CGlotREA.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-CLlP1E4X.js → index-CRPrHE7h.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-DeWKPQGs.js → index-CX1x4AFn.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-Db_5xhrU.js → index-CbTPvp2_.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-CDfSD07S.js → index-CjWltbi_.js} +1 -1
  111. package/src/assets/web-panel/assets/index-Ck1jhFE0.js +1 -0
  112. package/src/assets/web-panel/assets/{index-BPBia4b-.js → index-CkMKuqUs.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-C1ZAOJRW.js → index-CmruhzFi.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-P83LDnCz.js → index-Csfb-7hw.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-DcDggpWR.js → index-CxEtQYdi.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-OjnAwUJo.js → index-D7z4zB_a.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-D-EJNxgR.js → index-DLoalqRX.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-B3-B3FWD.js → index-DU2TXJu-.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-D92g4l3n.js → index-DXet1xol.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-Ca0mij1n.js → index-Dbd7eEex.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-DCqpl_E_.js → index-Dbkghqn_.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-DyWlOuak.js → index-Dg2a9owQ.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-CUBkvFPH.js → index-DpqtbXdE.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-DhVHoqGL.js → index-DqwPFbOb.js} +3 -3
  125. package/src/assets/web-panel/assets/{index-BG-GaZri.js → index-DvV03Ayk.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-CMCEXBRh.js → index-NJieh3T1.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-B273IY-E.js → index-Td8ZwyoC.js} +1 -1
  128. package/src/assets/web-panel/assets/index-c8jJEHVs.js +1 -0
  129. package/src/assets/web-panel/assets/{index-BzXjYUmd.js → index-e-e40id6.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-CCLwoATF.js → index-fccZmC_h.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-CN8HZlLH.js → index-fgYk0QXO.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-BB4KHHcv.js → index-yYEQXYaU.js} +1 -1
  133. package/src/assets/web-panel/assets/{initDefaultProps-CFNgY8lJ.js → initDefaultProps-CPrcB1TC.js} +1 -1
  134. package/src/assets/web-panel/assets/{motion-D-5RrDzn.js → motion-BQ7mWRh_.js} +1 -1
  135. package/src/assets/web-panel/assets/{move-DN-L0Bd-.js → move-CzOEq99p.js} +1 -1
  136. package/src/assets/web-panel/assets/{mtc-parser-6mgLSeCK.js → mtc-parser-BlQI5jrw.js} +1 -1
  137. package/src/assets/web-panel/assets/{omit-ClWW8eTP.js → omit-DlW4gxmv.js} +1 -1
  138. package/src/assets/web-panel/assets/{pickAttrs-Vystq3R8.js → pickAttrs-BBYms5nP.js} +1 -1
  139. package/src/assets/web-panel/assets/{placementArrow-D0H9hK4W.js → placementArrow-az2MPJ_7.js} +1 -1
  140. package/src/assets/web-panel/assets/{responsiveObserve-B3iNRU-a.js → responsiveObserve-D1-ibEol.js} +1 -1
  141. package/src/assets/web-panel/assets/{slide-CiMXe6am.js → slide-DHGqa4GA.js} +1 -1
  142. package/src/assets/web-panel/assets/{statusUtils-CGDZJ1uT.js → statusUtils-CYGDo6lD.js} +1 -1
  143. package/src/assets/web-panel/assets/{styleChecker-D2zA6NkY.js → styleChecker-Cl2EM9K6.js} +1 -1
  144. package/src/assets/web-panel/assets/{useFlexGapSupport-C1sYU6QE.js → useFlexGapSupport-DdYhzuv1.js} +1 -1
  145. package/src/assets/web-panel/assets/{useFs-BzUHSjg2.js → useFs-DWumPuBW.js} +1 -1
  146. package/src/assets/web-panel/assets/{usePersonalDataHub-CxB5yZCq.js → usePersonalDataHub-DxAO-Aqi.js} +1 -1
  147. package/src/assets/web-panel/assets/{vnode-BfUfMwtc.js → vnode-CplsQf_N.js} +1 -1
  148. package/src/assets/web-panel/assets/{zoom-CFYmj1TO.js → zoom-Cw5HXNSG.js} +1 -1
  149. package/src/assets/web-panel/index.html +1 -1
  150. package/src/command-help-index.json +2 -2
  151. package/src/commands/agent.js +19 -1
  152. package/src/commands/evolution-knowledge.js +54 -0
  153. package/src/commands/evolution-workbench.js +83 -0
  154. package/src/commands/evolution.js +6 -1
  155. package/src/commands/serve.js +16 -0
  156. package/src/commands/skill.js +158 -16
  157. package/src/data/changelog.json +26 -0
  158. package/src/gateways/ws/session-protocol.js +2 -0
  159. package/src/gateways/ws/ws-agent-handler.js +124 -69
  160. package/src/gateways/ws/ws-server.js +19 -0
  161. package/src/generated/cc-agent-protocol.schema.json +7 -1
  162. package/src/harness/jsonl-session-store.js +25 -1
  163. package/src/index.js +1 -1
  164. package/src/lib/app-server/cli-agent-kernel-adapter.js +8 -0
  165. package/src/lib/app-server/graph-runtime.js +40 -1
  166. package/src/lib/app-server/server.js +181 -3
  167. package/src/lib/app-server/websocket-transport.js +2 -0
  168. package/src/lib/evolution/agent-evolution-runtime-composition-brand.js +17 -0
  169. package/src/lib/evolution/agent-evolution-runtime-composition.js +165 -1
  170. package/src/lib/evolution/controlled-skill-production-pilot.js +912 -0
  171. package/src/lib/evolution/evolution-artifact-ports.js +21 -0
  172. package/src/lib/evolution/evolution-raw-crypto-shred.js +185 -0
  173. package/src/lib/evolution/evolution-workbench-batch-executor.js +195 -0
  174. package/src/lib/evolution/evolution-workbench-cli-host.js +169 -0
  175. package/src/lib/evolution/evolution-workbench-metrics-ledger-adapter.js +648 -0
  176. package/src/lib/evolution/evolution-workbench-metrics.js +943 -0
  177. package/src/lib/evolution/evolution-workbench-projection.js +734 -0
  178. package/src/lib/evolution/evolution-workbench-version-control.js +272 -0
  179. package/src/lib/evolution/governed-knowledge-conflict-merge.js +352 -0
  180. package/src/lib/evolution/governed-knowledge-dependency-authority.js +273 -0
  181. package/src/lib/evolution/governed-knowledge-dependency-ledger-executor.js +646 -0
  182. package/src/lib/evolution/governed-knowledge-merge-ledger-executor.js +644 -0
  183. package/src/lib/evolution/governed-knowledge-merge-publisher-authority.js +282 -0
  184. package/src/lib/evolution/governed-knowledge-node-crypto-authority.js +348 -0
  185. package/src/lib/evolution/governed-knowledge-rbac-approval-authority.js +621 -0
  186. package/src/lib/evolution/governed-knowledge-review-host.js +249 -0
  187. package/src/lib/evolution/governed-knowledge-sync-ledger-adapter.js +643 -0
  188. package/src/lib/evolution/governed-knowledge-sync-merge-publisher.js +259 -0
  189. package/src/lib/evolution/governed-knowledge-sync.js +485 -0
  190. package/src/lib/evolution/governed-knowledge-trust-ledger.js +707 -0
  191. package/src/lib/evolution/governed-skill-marketplace.js +430 -0
  192. package/src/lib/evolution/governed-wiki-pruning.js +435 -0
  193. package/src/lib/evolution/skill-outcome-index-authority.js +268 -0
  194. package/src/lib/evolution/skill-outcome-source-catalog-authority.js +237 -0
  195. package/src/lib/public-ide-capability-manifest.js +4 -0
  196. package/src/lib/skill-outcome-authority.js +43 -0
  197. package/src/lib/skill-outcome-transcript-authority.js +252 -0
  198. package/src/lib/skill-retrieval-router-benchmark.js +135 -0
  199. package/src/lib/skill-retrieval-router.js +235 -0
  200. package/src/lib/skill-vector-authority.js +325 -0
  201. package/src/lib/skill-vector-process-authority.js +386 -0
  202. package/src/repl/agent-repl.js +7 -1
  203. package/src/runtime/agent-core.js +72 -6
  204. package/src/runtime/agent-runtime.js +42 -0
  205. package/src/runtime/headless-runner.js +32 -0
  206. package/src/runtime/headless-stream.js +36 -1
  207. package/src/runtime/runtime-factory.js +62 -4
  208. package/src/assets/web-panel/assets/Notes-DZimkTrb.js +0 -7
  209. package/src/assets/web-panel/assets/OrderTableRenderer-Iy-pnX56.js +0 -1
  210. package/src/assets/web-panel/assets/ProjectSettings-CFMmhROS.js +0 -2
  211. package/src/assets/web-panel/assets/TimelineRenderer-CsLTB_QO.js +0 -1
  212. package/src/assets/web-panel/assets/devWarning-B2IW1J_J.js +0 -1
  213. package/src/assets/web-panel/assets/index-BCp2ir-1.js +0 -1
  214. package/src/assets/web-panel/assets/index-Bw4iuzRD.js +0 -1
@@ -0,0 +1,272 @@
1
+ import { createHash } from "node:crypto";
2
+
3
+ import { filterEvolutionWorkbenchProjection } from "./evolution-workbench-projection.js";
4
+
5
+ export const EVOLUTION_WORKBENCH_VERSION_COMPARISON_SCHEMA =
6
+ "chainlesschain.evolution-workbench-version-comparison/v1";
7
+ export const EVOLUTION_WORKBENCH_ROLLBACK_PLAN_SCHEMA =
8
+ "chainlesschain.evolution-workbench-rollback-plan/v1";
9
+ export const EVOLUTION_WORKBENCH_ROLLBACK_RECEIPT_SCHEMA =
10
+ "chainlesschain.evolution-workbench-rollback-receipt/v1";
11
+
12
+ const DIGEST = /^sha256:[a-f0-9]{64}$/u;
13
+
14
+ function canonical(value) {
15
+ if (value === null || typeof value !== "object") return JSON.stringify(value);
16
+ if (Array.isArray(value)) return `[${value.map(canonical).join(",")}]`;
17
+ return `{${Object.keys(value)
18
+ .sort()
19
+ .map((key) => `${JSON.stringify(key)}:${canonical(value[key])}`)
20
+ .join(",")}}`;
21
+ }
22
+
23
+ function hash(domain, value) {
24
+ return `sha256:${createHash("sha256")
25
+ .update(domain)
26
+ .update("\0")
27
+ .update(canonical(value))
28
+ .digest("hex")}`;
29
+ }
30
+
31
+ function clone(value) {
32
+ return value == null ? value : structuredClone(value);
33
+ }
34
+
35
+ function freeze(value) {
36
+ if (value && typeof value === "object" && !Object.isFrozen(value)) {
37
+ Object.freeze(value);
38
+ for (const child of Object.values(value)) freeze(child);
39
+ }
40
+ return value;
41
+ }
42
+
43
+ function digest(value, name) {
44
+ if (!DIGEST.test(value ?? "")) throw new TypeError(`${name} is invalid`);
45
+ return value;
46
+ }
47
+
48
+ function string(value, name) {
49
+ if (typeof value !== "string" || value.trim() === "")
50
+ throw new TypeError(`${name} is required`);
51
+ return value;
52
+ }
53
+
54
+ function verifiedProjection(projection) {
55
+ filterEvolutionWorkbenchProjection(projection, { limit: 1 });
56
+ return projection;
57
+ }
58
+
59
+ function candidate(projection, packetDigest, label) {
60
+ digest(packetDigest, `${label} packetDigest`);
61
+ const matches = projection.candidates.filter(
62
+ (item) => item.packetDigest === packetDigest,
63
+ );
64
+ if (matches.length !== 1)
65
+ throw new Error(`${label} Workbench version is missing or ambiguous`);
66
+ return matches[0];
67
+ }
68
+
69
+ function summary(item) {
70
+ return {
71
+ packetDigest: item.packetDigest,
72
+ candidateId: item.candidateId,
73
+ contentDigest: item.candidateContentDigest,
74
+ parentContentDigest: item.why.parentContentDigest,
75
+ candidateDiffDigest: item.changes.candidateDiffDigest,
76
+ capabilities: clone(item.changes.capabilities),
77
+ contentRisk: clone(item.changes.contentRisk),
78
+ matrixReceiptDigest: item.validation.matrixReceiptDigest,
79
+ targetRuntimes: [...item.validation.targetRuntimes],
80
+ actualUsage: {
81
+ active: item.actualUsage.active,
82
+ receiptCount: item.actualUsage.receiptCount,
83
+ completed: item.actualUsage.completed,
84
+ failedOrBlocked: item.actualUsage.failedOrBlocked,
85
+ totalCostUsd: item.actualUsage.totalCostUsd,
86
+ },
87
+ };
88
+ }
89
+
90
+ export function compareEvolutionWorkbenchVersions(
91
+ projection,
92
+ { leftPacketDigest, rightPacketDigest } = {},
93
+ ) {
94
+ verifiedProjection(projection);
95
+ if (leftPacketDigest === rightPacketDigest)
96
+ throw new Error("Workbench version comparison requires two versions");
97
+ const left = candidate(projection, leftPacketDigest, "left");
98
+ const right = candidate(projection, rightPacketDigest, "right");
99
+ const core = {
100
+ schema: EVOLUTION_WORKBENCH_VERSION_COMPARISON_SCHEMA,
101
+ tenantId: projection.tenantId,
102
+ skillName: projection.skillName,
103
+ sourceProjectionDigest: projection.projectionDigest,
104
+ left: summary(left),
105
+ right: summary(right),
106
+ };
107
+ return freeze({
108
+ ...core,
109
+ comparisonDigest: hash(EVOLUTION_WORKBENCH_VERSION_COMPARISON_SCHEMA, core),
110
+ });
111
+ }
112
+
113
+ export function buildEvolutionWorkbenchRollbackPlan(
114
+ projection,
115
+ {
116
+ fromPacketDigest,
117
+ toPacketDigest,
118
+ expectedActiveStateDigest,
119
+ requestedBy,
120
+ reason,
121
+ } = {},
122
+ ) {
123
+ const comparison = compareEvolutionWorkbenchVersions(projection, {
124
+ leftPacketDigest: fromPacketDigest,
125
+ rightPacketDigest: toPacketDigest,
126
+ });
127
+ const from = candidate(projection, fromPacketDigest, "active");
128
+ const to = candidate(projection, toPacketDigest, "rollback target");
129
+ if (from.actualUsage.active !== true)
130
+ throw new Error("Workbench rollback source is not active");
131
+ if (to.status !== "approved" || to.decision?.decision !== "approved")
132
+ throw new Error("Workbench rollback target lacks human approval");
133
+ digest(expectedActiveStateDigest, "expectedActiveStateDigest");
134
+ string(requestedBy, "requestedBy");
135
+ string(reason, "reason");
136
+ if (reason.length > 2048) throw new TypeError("rollback reason is too long");
137
+ const core = {
138
+ schema: EVOLUTION_WORKBENCH_ROLLBACK_PLAN_SCHEMA,
139
+ tenantId: projection.tenantId,
140
+ skillName: projection.skillName,
141
+ sourceProjectionDigest: projection.projectionDigest,
142
+ comparisonDigest: comparison.comparisonDigest,
143
+ fromPacketDigest,
144
+ fromCandidateId: from.candidateId,
145
+ fromContentDigest: from.candidateContentDigest,
146
+ toPacketDigest,
147
+ toCandidateId: to.candidateId,
148
+ toContentDigest: to.candidateContentDigest,
149
+ expectedActiveStateDigest,
150
+ requestedBy,
151
+ reason,
152
+ };
153
+ return freeze({
154
+ ...core,
155
+ planDigest: hash(EVOLUTION_WORKBENCH_ROLLBACK_PLAN_SCHEMA, core),
156
+ });
157
+ }
158
+
159
+ function verifyPlan(plan, tenantId) {
160
+ if (
161
+ plan?.schema !== EVOLUTION_WORKBENCH_ROLLBACK_PLAN_SCHEMA ||
162
+ plan.tenantId !== tenantId ||
163
+ !DIGEST.test(plan?.planDigest ?? "")
164
+ )
165
+ throw new TypeError("Workbench rollback plan is invalid");
166
+ const core = clone(plan);
167
+ delete core.planDigest;
168
+ if (hash(EVOLUTION_WORKBENCH_ROLLBACK_PLAN_SCHEMA, core) !== plan.planDigest)
169
+ throw new Error("Workbench rollback plan digest is invalid");
170
+ return freeze(clone(plan));
171
+ }
172
+
173
+ export class EvolutionWorkbenchRollbackExecutor {
174
+ constructor({ tenantId, ports } = {}) {
175
+ this.tenantId = string(tenantId, "tenantId");
176
+ for (const name of [
177
+ "loadProjection",
178
+ "authorizeHumanRollback",
179
+ "applyRollback",
180
+ "readActiveState",
181
+ "commitRollback",
182
+ ]) {
183
+ if (typeof ports?.[name] !== "function")
184
+ throw new TypeError(`Workbench rollback port ${name} is required`);
185
+ this[`_${name}`] = ports[name].bind(ports);
186
+ }
187
+ }
188
+
189
+ async execute(input) {
190
+ const plan = verifyPlan(input, this.tenantId);
191
+ const projection = await this._loadProjection({
192
+ tenantId: this.tenantId,
193
+ projectionDigest: plan.sourceProjectionDigest,
194
+ });
195
+ const rebuilt = buildEvolutionWorkbenchRollbackPlan(projection, {
196
+ fromPacketDigest: plan.fromPacketDigest,
197
+ toPacketDigest: plan.toPacketDigest,
198
+ expectedActiveStateDigest: plan.expectedActiveStateDigest,
199
+ requestedBy: plan.requestedBy,
200
+ reason: plan.reason,
201
+ });
202
+ if (rebuilt.planDigest !== plan.planDigest)
203
+ throw new Error("Workbench rollback source projection changed");
204
+ const authorization = await this._authorizeHumanRollback({ plan });
205
+ if (
206
+ authorization?.authenticated !== true ||
207
+ authorization.durable !== true ||
208
+ authorization.automated !== false ||
209
+ authorization.planDigest !== plan.planDigest ||
210
+ !DIGEST.test(authorization.receiptDigest ?? "")
211
+ )
212
+ throw new Error("Workbench rollback lacks exact human authorization");
213
+ const requestCore = {
214
+ planDigest: plan.planDigest,
215
+ expectedActiveStateDigest: plan.expectedActiveStateDigest,
216
+ fromContentDigest: plan.fromContentDigest,
217
+ toContentDigest: plan.toContentDigest,
218
+ authorizationReceiptDigest: authorization.receiptDigest,
219
+ };
220
+ const request = freeze({
221
+ ...requestCore,
222
+ requestDigest: hash(
223
+ "chainlesschain.evolution-workbench-rollback-request/v1",
224
+ requestCore,
225
+ ),
226
+ });
227
+ const applied = await this._applyRollback(request);
228
+ if (
229
+ applied?.authenticated !== true ||
230
+ applied.durable !== true ||
231
+ applied.requestDigest !== request.requestDigest ||
232
+ !DIGEST.test(applied.receiptDigest ?? "")
233
+ )
234
+ throw new Error("Workbench rollback was not durably applied");
235
+ const active = await this._readActiveState({
236
+ tenantId: this.tenantId,
237
+ skillName: plan.skillName,
238
+ });
239
+ if (
240
+ active?.authenticated !== true ||
241
+ active.contentDigest !== plan.toContentDigest ||
242
+ !DIGEST.test(active.stateDigest ?? "")
243
+ )
244
+ throw new Error("Workbench rollback active readback differs from target");
245
+ const receiptCore = {
246
+ schema: EVOLUTION_WORKBENCH_ROLLBACK_RECEIPT_SCHEMA,
247
+ tenantId: this.tenantId,
248
+ skillName: plan.skillName,
249
+ planDigest: plan.planDigest,
250
+ requestDigest: request.requestDigest,
251
+ authorizationReceiptDigest: authorization.receiptDigest,
252
+ transitionReceiptDigest: applied.receiptDigest,
253
+ activeStateDigest: active.stateDigest,
254
+ activeContentDigest: active.contentDigest,
255
+ };
256
+ const receipt = freeze({
257
+ ...receiptCore,
258
+ receiptDigest: hash(
259
+ EVOLUTION_WORKBENCH_ROLLBACK_RECEIPT_SCHEMA,
260
+ receiptCore,
261
+ ),
262
+ });
263
+ const committed = await this._commitRollback({ receipt });
264
+ if (
265
+ committed?.authenticated !== true ||
266
+ committed.durable !== true ||
267
+ committed.receiptDigest !== receipt.receiptDigest
268
+ )
269
+ throw new Error("Workbench rollback receipt was not durably committed");
270
+ return receipt;
271
+ }
272
+ }
@@ -0,0 +1,352 @@
1
+ import { createHash } from "node:crypto";
2
+ import { types as utilTypes } from "node:util";
3
+
4
+ import { isGovernedKnowledgeConflictReader } from "./governed-knowledge-sync-ledger-adapter.js";
5
+ import { verifyGovernedKnowledgeRecord } from "./governed-knowledge-sync.js";
6
+
7
+ export const GOVERNED_KNOWLEDGE_HUMAN_MERGE_RECEIPT_SCHEMA =
8
+ "chainlesschain.governed-knowledge-human-merge-receipt/v1";
9
+ export const GOVERNED_KNOWLEDGE_MERGE_PLAN_SCHEMA =
10
+ "chainlesschain.governed-knowledge-merge-plan/v1";
11
+
12
+ const DIGEST = /^sha256:[a-f0-9]{64}$/u;
13
+ const ID = /^[A-Za-z0-9][A-Za-z0-9._:@/-]{0,255}$/u;
14
+ const MAX_REASON_LENGTH = 2048;
15
+ const MAX_RECEIPT_AGE_MS = 30 * 24 * 60 * 60 * 1000;
16
+ const MAX_FUTURE_SKEW_MS = 5 * 60 * 1000;
17
+ const MERGE_PLANS = new WeakSet();
18
+ const RECEIPT_KEYS = new Set([
19
+ "attestation",
20
+ "automated",
21
+ "conflictEnvelopeDigest",
22
+ "decidedAt",
23
+ "knowledgeId",
24
+ "localContentDigest",
25
+ "mergedContentDigest",
26
+ "mergedVectorClock",
27
+ "reason",
28
+ "receiptDigest",
29
+ "remoteContentDigest",
30
+ "reviewerId",
31
+ "schema",
32
+ "tenantId",
33
+ ]);
34
+ const ATTESTATION_KEYS = new Set(["algorithm", "keyId", "value"]);
35
+ const PLAN_KEYS = new Set([
36
+ "conflictEnvelopeDigest",
37
+ "decidedAt",
38
+ "deviceId",
39
+ "humanReceiptDigest",
40
+ "knowledgeId",
41
+ "localContentDigest",
42
+ "mergedKnowledge",
43
+ "planDigest",
44
+ "remoteContentDigest",
45
+ "requestedBy",
46
+ "schema",
47
+ "scope",
48
+ "scopeId",
49
+ "tenantId",
50
+ ]);
51
+
52
+ function canonical(value) {
53
+ if (value === null || typeof value !== "object") return JSON.stringify(value);
54
+ if (Array.isArray(value)) return `[${value.map(canonical).join(",")}]`;
55
+ return `{${Object.keys(value)
56
+ .sort()
57
+ .map((key) => `${JSON.stringify(key)}:${canonical(value[key])}`)
58
+ .join(",")}}`;
59
+ }
60
+
61
+ function hash(domain, value) {
62
+ return `sha256:${createHash("sha256")
63
+ .update(domain)
64
+ .update("\0")
65
+ .update(canonical(value))
66
+ .digest("hex")}`;
67
+ }
68
+
69
+ function clone(value) {
70
+ return structuredClone(value);
71
+ }
72
+
73
+ function freeze(value) {
74
+ if (value && typeof value === "object" && !Object.isFrozen(value)) {
75
+ Object.freeze(value);
76
+ for (const child of Object.values(value)) freeze(child);
77
+ }
78
+ return value;
79
+ }
80
+
81
+ function exact(value, keys, label) {
82
+ if (
83
+ !value ||
84
+ typeof value !== "object" ||
85
+ Array.isArray(value) ||
86
+ utilTypes.isProxy(value) ||
87
+ ![Object.prototype, null].includes(Object.getPrototypeOf(value))
88
+ ) {
89
+ throw new TypeError(`${label} must be a plain object`);
90
+ }
91
+ const actual = Reflect.ownKeys(value);
92
+ if (
93
+ actual.length !== keys.size ||
94
+ actual.some((key) => typeof key !== "string" || !keys.has(key))
95
+ ) {
96
+ throw new TypeError(`${label} has an invalid shape`);
97
+ }
98
+ return value;
99
+ }
100
+
101
+ function identifier(value, label) {
102
+ if (typeof value !== "string" || !ID.test(value)) {
103
+ throw new TypeError(`${label} is invalid`);
104
+ }
105
+ return value;
106
+ }
107
+
108
+ function capture(owner, method, label) {
109
+ if (
110
+ !owner ||
111
+ typeof owner !== "object" ||
112
+ utilTypes.isProxy(owner) ||
113
+ typeof owner[method] !== "function"
114
+ ) {
115
+ throw new TypeError(`${label}.${method}() is required`);
116
+ }
117
+ return (...args) => Reflect.apply(owner[method], owner, args);
118
+ }
119
+
120
+ function receiptCore(receipt) {
121
+ const core = clone(receipt);
122
+ delete core.receiptDigest;
123
+ delete core.attestation;
124
+ return core;
125
+ }
126
+
127
+ export function digestGovernedKnowledgeHumanMergeReceipt(receipt) {
128
+ return hash(
129
+ GOVERNED_KNOWLEDGE_HUMAN_MERGE_RECEIPT_SCHEMA,
130
+ receiptCore(receipt),
131
+ );
132
+ }
133
+
134
+ export function verifyGovernedKnowledgeMergePlan(input) {
135
+ const plan = exact(input, PLAN_KEYS, "governed knowledge merge plan");
136
+ const merged = verifyGovernedKnowledgeRecord(plan.mergedKnowledge, {
137
+ tenantId: plan.tenantId,
138
+ });
139
+ const core = clone(plan);
140
+ delete core.planDigest;
141
+ if (
142
+ plan.schema !== GOVERNED_KNOWLEDGE_MERGE_PLAN_SCHEMA ||
143
+ !identifier(plan.tenantId, "tenantId") ||
144
+ !identifier(plan.deviceId, "deviceId") ||
145
+ !identifier(plan.knowledgeId, "knowledgeId") ||
146
+ !identifier(plan.scopeId, "scopeId") ||
147
+ !identifier(plan.requestedBy, "requestedBy") ||
148
+ plan.knowledgeId !== merged.knowledgeId ||
149
+ plan.scope !== merged.scope ||
150
+ plan.scopeId !== merged.scopeId ||
151
+ !DIGEST.test(plan.conflictEnvelopeDigest ?? "") ||
152
+ !DIGEST.test(plan.localContentDigest ?? "") ||
153
+ !DIGEST.test(plan.remoteContentDigest ?? "") ||
154
+ !DIGEST.test(plan.humanReceiptDigest ?? "") ||
155
+ !DIGEST.test(plan.planDigest ?? "") ||
156
+ !Number.isFinite(Date.parse(plan.decidedAt)) ||
157
+ plan.planDigest !== hash(GOVERNED_KNOWLEDGE_MERGE_PLAN_SCHEMA, core)
158
+ ) {
159
+ throw new Error("governed knowledge merge plan is invalid");
160
+ }
161
+ return freeze(clone(plan));
162
+ }
163
+
164
+ export function isGovernedKnowledgeMergePlan(value) {
165
+ return MERGE_PLANS.has(value);
166
+ }
167
+
168
+ function normalizeReceipt(input, context, now) {
169
+ const receipt = exact(input, RECEIPT_KEYS, "human merge receipt");
170
+ const attestation = exact(
171
+ receipt.attestation,
172
+ ATTESTATION_KEYS,
173
+ "human merge attestation",
174
+ );
175
+ const decidedAt = Date.parse(receipt.decidedAt);
176
+ if (
177
+ receipt.schema !== GOVERNED_KNOWLEDGE_HUMAN_MERGE_RECEIPT_SCHEMA ||
178
+ receipt.tenantId !== context.tenantId ||
179
+ receipt.automated !== false ||
180
+ receipt.knowledgeId !== context.knowledgeId ||
181
+ receipt.conflictEnvelopeDigest !== context.conflictEnvelopeDigest ||
182
+ receipt.localContentDigest !== context.localContentDigest ||
183
+ receipt.remoteContentDigest !== context.remoteContentDigest ||
184
+ receipt.mergedContentDigest !== context.mergedContentDigest ||
185
+ canonical(receipt.mergedVectorClock) !==
186
+ canonical(context.mergedVectorClock) ||
187
+ !identifier(receipt.reviewerId, "reviewerId") ||
188
+ typeof receipt.reason !== "string" ||
189
+ receipt.reason.trim() !== receipt.reason ||
190
+ receipt.reason.length < 1 ||
191
+ receipt.reason.length > MAX_REASON_LENGTH ||
192
+ !Number.isFinite(decidedAt) ||
193
+ decidedAt < now - MAX_RECEIPT_AGE_MS ||
194
+ decidedAt > now + MAX_FUTURE_SKEW_MS ||
195
+ !DIGEST.test(receipt.receiptDigest ?? "") ||
196
+ receipt.receiptDigest !== digestGovernedKnowledgeHumanMergeReceipt(receipt)
197
+ ) {
198
+ throw new Error("human merge receipt is not exactly bound");
199
+ }
200
+ for (const [key, value] of Object.entries(attestation)) {
201
+ if (
202
+ typeof value !== "string" ||
203
+ value.trim() !== value ||
204
+ value.length < 1 ||
205
+ value.length > (key === "value" ? 4096 : 256)
206
+ ) {
207
+ throw new TypeError("human merge attestation is invalid");
208
+ }
209
+ }
210
+ return freeze(clone(receipt));
211
+ }
212
+
213
+ function exactMergeClock(local, remote, merged, deviceId) {
214
+ const devices = new Set([...Object.keys(local), ...Object.keys(remote)]);
215
+ devices.add(deviceId);
216
+ if (
217
+ Object.keys(merged).length !== devices.size ||
218
+ Object.keys(merged).some((device) => !devices.has(device))
219
+ ) {
220
+ return false;
221
+ }
222
+ for (const device of devices) {
223
+ const joined = Math.max(local[device] ?? 0, remote[device] ?? 0);
224
+ const expected = device === deviceId ? joined + 1 : joined;
225
+ if (merged[device] !== expected) return false;
226
+ }
227
+ return true;
228
+ }
229
+
230
+ export class GovernedKnowledgeConflictMergePlanner {
231
+ constructor({ conflictReader, receiptVerifier, now = Date.now } = {}) {
232
+ if (!isGovernedKnowledgeConflictReader(conflictReader)) {
233
+ throw new TypeError(
234
+ "a branded governed knowledge conflict reader is required",
235
+ );
236
+ }
237
+ if (typeof now !== "function" || utilTypes.isProxy(now)) {
238
+ throw new TypeError("now must be a non-proxy function");
239
+ }
240
+ this.tenantId = conflictReader.tenantId;
241
+ this.deviceId = conflictReader.deviceId;
242
+ this._getConflict = capture(
243
+ conflictReader,
244
+ "getConflict",
245
+ "conflictReader",
246
+ );
247
+ this._load = capture(conflictReader, "load", "conflictReader");
248
+ this._verifyReceipt = capture(receiptVerifier, "verify", "receiptVerifier");
249
+ this._now = now;
250
+ Object.freeze(this);
251
+ }
252
+
253
+ async plan({ conflictEnvelopeDigest, mergedKnowledge, humanReceipt } = {}) {
254
+ if (!DIGEST.test(conflictEnvelopeDigest ?? "")) {
255
+ throw new TypeError("conflictEnvelopeDigest is invalid");
256
+ }
257
+ const conflict = await this._getConflict({
258
+ envelopeDigest: conflictEnvelopeDigest,
259
+ });
260
+ if (
261
+ conflict?.disposition !== "conflict" ||
262
+ conflict.tenantId !== this.tenantId ||
263
+ conflict.deviceId !== this.deviceId ||
264
+ conflict.envelopeDigest !== conflictEnvelopeDigest ||
265
+ !DIGEST.test(conflict.conflictWithDigest ?? "")
266
+ ) {
267
+ throw new Error("governed knowledge conflict is missing or invalid");
268
+ }
269
+ const current = await this._load({
270
+ knowledgeId: conflict.knowledge.knowledgeId,
271
+ });
272
+ if (
273
+ !current ||
274
+ current.contentDigest !== conflict.conflictWithDigest ||
275
+ current.knowledgeId !== conflict.knowledge.knowledgeId
276
+ ) {
277
+ throw new Error("governed knowledge conflict baseline has advanced");
278
+ }
279
+ const merged = verifyGovernedKnowledgeRecord(mergedKnowledge, {
280
+ tenantId: this.tenantId,
281
+ });
282
+ if (
283
+ merged.knowledgeId !== current.knowledgeId ||
284
+ merged.scope !== current.scope ||
285
+ merged.scopeId !== current.scopeId ||
286
+ merged.scope !== conflict.knowledge.scope ||
287
+ merged.scopeId !== conflict.knowledge.scopeId ||
288
+ merged.action !== "upsert" ||
289
+ !exactMergeClock(
290
+ current.vectorClock,
291
+ conflict.knowledge.vectorClock,
292
+ merged.vectorClock,
293
+ this.deviceId,
294
+ )
295
+ ) {
296
+ throw new Error("merged knowledge does not exactly join both histories");
297
+ }
298
+ const now = Number(this._now());
299
+ if (!Number.isFinite(now)) throw new TypeError("merge clock is invalid");
300
+ const context = {
301
+ tenantId: this.tenantId,
302
+ knowledgeId: merged.knowledgeId,
303
+ conflictEnvelopeDigest,
304
+ localContentDigest: current.contentDigest,
305
+ remoteContentDigest: conflict.knowledge.contentDigest,
306
+ mergedContentDigest: merged.contentDigest,
307
+ mergedVectorClock: merged.vectorClock,
308
+ };
309
+ const receipt = normalizeReceipt(humanReceipt, context, now);
310
+ const verified = await this._verifyReceipt({
311
+ receipt,
312
+ conflict,
313
+ currentKnowledge: current,
314
+ mergedKnowledge: merged,
315
+ });
316
+ if (
317
+ verified?.authenticated !== true ||
318
+ verified.durable !== true ||
319
+ verified.automated !== false ||
320
+ verified.tenantId !== this.tenantId ||
321
+ verified.reviewerId !== receipt.reviewerId ||
322
+ verified.knowledgeId !== merged.knowledgeId ||
323
+ verified.conflictEnvelopeDigest !== conflictEnvelopeDigest ||
324
+ verified.receiptDigest !== receipt.receiptDigest
325
+ ) {
326
+ throw new Error(
327
+ "human merge receipt authority did not authenticate the decision",
328
+ );
329
+ }
330
+ const core = {
331
+ schema: GOVERNED_KNOWLEDGE_MERGE_PLAN_SCHEMA,
332
+ tenantId: this.tenantId,
333
+ deviceId: this.deviceId,
334
+ knowledgeId: merged.knowledgeId,
335
+ scope: merged.scope,
336
+ scopeId: merged.scopeId,
337
+ conflictEnvelopeDigest,
338
+ localContentDigest: current.contentDigest,
339
+ remoteContentDigest: conflict.knowledge.contentDigest,
340
+ mergedKnowledge: merged,
341
+ humanReceiptDigest: receipt.receiptDigest,
342
+ requestedBy: receipt.reviewerId,
343
+ decidedAt: receipt.decidedAt,
344
+ };
345
+ const plan = freeze({
346
+ ...core,
347
+ planDigest: hash(GOVERNED_KNOWLEDGE_MERGE_PLAN_SCHEMA, core),
348
+ });
349
+ MERGE_PLANS.add(plan);
350
+ return plan;
351
+ }
352
+ }