chainlesschain 0.166.20 → 0.166.22

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 (222) hide show
  1. package/README.md +67 -9
  2. package/package.json +2 -2
  3. package/src/assets/web-panel/assets/{AIOps-CcJst5Zs.js → AIOps-oJ7USzMC.js} +1 -1
  4. package/src/assets/web-panel/assets/{ActionButton-BpHPFKd3.js → ActionButton-BlgnZe_C.js} +1 -1
  5. package/src/assets/web-panel/assets/{Analytics-DHAsASuS.js → Analytics-D2rRbTLu.js} +3 -3
  6. package/src/assets/web-panel/assets/{AppLayout-BTKwo5RC.js → AppLayout-FwS3f0B2.js} +5 -5
  7. package/src/assets/web-panel/assets/{Artifacts-BcCBTggA.js → Artifacts-iF-_08Hi.js} +1 -1
  8. package/src/assets/web-panel/assets/{Audit-z1JvJYbT.js → Audit-D24p0zQw.js} +1 -1
  9. package/src/assets/web-panel/assets/{BackgroundAgents-CJ7DCMDR.js → BackgroundAgents-Cg3mRVi9.js} +1 -1
  10. package/src/assets/web-panel/assets/{Backup-CKpxw4uw.js → Backup-EOqht3H-.js} +1 -1
  11. package/src/assets/web-panel/assets/{BaseInput-2jI_IlUB.js → BaseInput-9XWYq2hj.js} +1 -1
  12. package/src/assets/web-panel/assets/{Chat-C_4RfBeN.js → Chat-Dq5yardA.js} +5 -5
  13. package/src/assets/web-panel/assets/ChatBubbleRenderer-Ds3pA-ET.js +1 -0
  14. package/src/assets/web-panel/assets/{Checkbox-BnF4z4N1.js → Checkbox-CuyCBoBf.js} +1 -1
  15. package/src/assets/web-panel/assets/{Codegen-m_LMamhM.js → Codegen-DjWtYHNe.js} +1 -1
  16. package/src/assets/web-panel/assets/{Col-DzMbA760.js → Col-CrVr_iuG.js} +1 -1
  17. package/src/assets/web-panel/assets/{Community-SScuZUcW.js → Community-C6QxpfGc.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compact-CiOHRvwQ.js → Compact-B-v5r6Pa.js} +1 -1
  19. package/src/assets/web-panel/assets/{Compliance-97FzYz-6.js → Compliance-zNiLiFgD.js} +1 -1
  20. package/src/assets/web-panel/assets/{Cowork-C0ss-SRl.js → Cowork-D9K7lMOu.js} +2 -2
  21. package/src/assets/web-panel/assets/{Cron-CCbdc9fp.js → Cron-DAjO36z4.js} +2 -2
  22. package/src/assets/web-panel/assets/{Crosschain-BPnabXej.js → Crosschain-Bxqn0aqB.js} +1 -1
  23. package/src/assets/web-panel/assets/{DID-B65hFnHs.js → DID-DfRmLUe-.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dashboard-B6qR_TF2.js → Dashboard-Cz8KF3fr.js} +2 -2
  25. package/src/assets/web-panel/assets/{Dropdown-6c-2Fxm-.js → Dropdown-C4oVfkP0.js} +1 -1
  26. package/src/assets/web-panel/assets/{EmailListRenderer-GD57mfiz.js → EmailListRenderer-ivyZKN8k.js} +1 -1
  27. package/src/assets/web-panel/assets/{FamilyGuardDashboard-B2mxG6LN.js → FamilyGuardDashboard-DoxY1CPW.js} +1 -1
  28. package/src/assets/web-panel/assets/{Federation-cZS-uvAo.js → Federation-C93gZxnb.js} +1 -1
  29. package/src/assets/web-panel/assets/{FormItemContext-UbSfBIe1.js → FormItemContext-D_lEjYJE.js} +1 -1
  30. package/src/assets/web-panel/assets/{GenericCardRenderer-BMAtvGt1.js → GenericCardRenderer-BNFN9YjN.js} +1 -1
  31. package/src/assets/web-panel/assets/{Git-DAlhOiDA.js → Git-mUu2HcLI.js} +2 -2
  32. package/src/assets/web-panel/assets/{Governance-B-RRVaP8.js → Governance-CNuosrge.js} +1 -1
  33. package/src/assets/web-panel/assets/{Inference-DBl-pXYR.js → Inference-DwY5pbCB.js} +1 -1
  34. package/src/assets/web-panel/assets/{KnowledgeGraph-DjqOkvgY.js → KnowledgeGraph-aRUxhACD.js} +1 -1
  35. package/src/assets/web-panel/assets/{Logs-CEV7AEAD.js → Logs-DFfsWYy_.js} +2 -2
  36. package/src/assets/web-panel/assets/{MarkdownRenderer-BDCxa4d1.js → MarkdownRenderer-DqTx7_u1.js} +1 -1
  37. package/src/assets/web-panel/assets/{Marketplace-oRjzfmYJ.js → Marketplace-COI-ciM-.js} +1 -1
  38. package/src/assets/web-panel/assets/{McpTools-BiTnznLw.js → McpTools-BJJwaIpe.js} +3 -3
  39. package/src/assets/web-panel/assets/{Memory-DR0C5K4N.js → Memory-CDO6SGDZ.js} +2 -2
  40. package/src/assets/web-panel/assets/{MobileBridge--oR8wEcp.js → MobileBridge-BlZ5tFf4.js} +1 -1
  41. package/src/assets/web-panel/assets/{MobileProjects-DKqpYMuG.js → MobileProjects-DuoxbgWz.js} +1 -1
  42. package/src/assets/web-panel/assets/{Mtc-Dg0D6fDQ.js → Mtc-6ec9j70b.js} +2 -2
  43. package/src/assets/web-panel/assets/{MtcAudit-D4_-yWTK.js → MtcAudit-BuL7HkC7.js} +5 -5
  44. package/src/assets/web-panel/assets/{Multisig-Coz55FxA.js → Multisig-CJxR85lk.js} +3 -3
  45. package/src/assets/web-panel/assets/{NLProgramming-BWVjgW9Y.js → NLProgramming-B71O1S4l.js} +1 -1
  46. package/src/assets/web-panel/assets/{Notes-BflVuGwr.js → Notes-Bsw5zbpV.js} +3 -3
  47. package/src/assets/web-panel/assets/{NotificationSettings-CT0F_dJ7.js → NotificationSettings-BnAhXuK_.js} +1 -1
  48. package/src/assets/web-panel/assets/{OrderTableRenderer-Dyrnqy_o.js → OrderTableRenderer-BJ0R5GGz.js} +1 -1
  49. package/src/assets/web-panel/assets/{Organization-CMDTM2z5.js → Organization-B7wwNxoP.js} +2 -2
  50. package/src/assets/web-panel/assets/{Overflow-acKvvYpC.js → Overflow-CfAGr0gM.js} +1 -1
  51. package/src/assets/web-panel/assets/{P2P-CRq5j9Ax.js → P2P-KhMg22Fz.js} +2 -2
  52. package/src/assets/web-panel/assets/{PdhVaultBrowser-DmtzN6Kn.js → PdhVaultBrowser-NdAXI9ft.js} +4 -4
  53. package/src/assets/web-panel/assets/{Permissions-SZ-kjJDa.js → Permissions-CIYjqyT7.js} +4 -4
  54. package/src/assets/web-panel/assets/{PersonalDataHub-DXh-ZfgJ.js → PersonalDataHub-D2ht3P_R.js} +6 -6
  55. package/src/assets/web-panel/assets/{Pipeline-DhBU9ftP.js → Pipeline-i6flZW1m.js} +1 -1
  56. package/src/assets/web-panel/assets/{Privacy-BgEXpO_V.js → Privacy-DE0lhYVc.js} +1 -1
  57. package/src/assets/web-panel/assets/{ProjectInit-B2DJ-dmK.js → ProjectInit-BL3YbyxS.js} +2 -2
  58. package/src/assets/web-panel/assets/{ProjectSettings-ve3SocWc.js → ProjectSettings-CEtdg7ni.js} +2 -2
  59. package/src/assets/web-panel/assets/{Projects-5ZvFasSJ.js → Projects-CvtU5peJ.js} +1 -1
  60. package/src/assets/web-panel/assets/{Providers-C8fcF3BK.js → Providers-DKt_Cg-j.js} +1 -1
  61. package/src/assets/web-panel/assets/{QrScannerModal-unjO8lNO.js → QrScannerModal-DA61jNSx.js} +1 -1
  62. package/src/assets/web-panel/assets/{QuickAsk-BT1QtT7D.js → QuickAsk-fS9ryUmq.js} +1 -1
  63. package/src/assets/web-panel/assets/{Recommend-BSjFrY1w.js → Recommend-CR9dZU5Y.js} +1 -1
  64. package/src/assets/web-panel/assets/{RemoteSession-CWV0bICg.js → RemoteSession-BV0BR2Dz.js} +2 -2
  65. package/src/assets/web-panel/assets/{Reputation-BMjiMsk2.js → Reputation-BIeGUvYD.js} +1 -1
  66. package/src/assets/web-panel/assets/{Row-9XCY22PM.js → Row-DHDT1aro.js} +1 -1
  67. package/src/assets/web-panel/assets/{RssFeed-DQ9PDy7Q.js → RssFeed-Cq6YKb1h.js} +3 -3
  68. package/src/assets/web-panel/assets/{Search-Boym2HwG.js → Search-DEF6vsy6.js} +1 -1
  69. package/src/assets/web-panel/assets/{Security-Gbq3lGQb.js → Security-CHtYiKY9.js} +4 -4
  70. package/src/assets/web-panel/assets/{Services-OcUfLdnu.js → Services-u16lvBJN.js} +2 -2
  71. package/src/assets/web-panel/assets/{Skeleton-BjTog6cA.js → Skeleton-CGbizyDj.js} +1 -1
  72. package/src/assets/web-panel/assets/{Skills-Dny4ft_1.js → Skills-BZMQcAa7.js} +1 -1
  73. package/src/assets/web-panel/assets/{Sla-Cy_VnhpZ.js → Sla-Bm-CycVi.js} +1 -1
  74. package/src/assets/web-panel/assets/{SpeechSettings-CrFuL_lp.js → SpeechSettings-BudpA5kr.js} +1 -1
  75. package/src/assets/web-panel/assets/{SyncSettings-k-FnjuOR.js → SyncSettings-B8q1C1eC.js} +2 -2
  76. package/src/assets/web-panel/assets/{Tasks-ZEqDSo0_.js → Tasks-SU1pBWc-.js} +1 -1
  77. package/src/assets/web-panel/assets/{Templates-CYYksYV5.js → Templates-CyOfJzmt.js} +1 -1
  78. package/src/assets/web-panel/assets/{Tenant-BvTTRTHS.js → Tenant-xqWSm2GP.js} +1 -1
  79. package/src/assets/web-panel/assets/{Terminal-DMOQOtkj.js → Terminal-D1Ttgjsi.js} +2 -2
  80. package/src/assets/web-panel/assets/{TimelineRenderer-CnudkJxk.js → TimelineRenderer-Da2lYs5D.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tokens-VW6Wocdp.js → Tokens-B34-SduO.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trigger-BtOxZqP6.js → Trigger-C8zyYm4R.js} +1 -1
  83. package/src/assets/web-panel/assets/{Trust-XcGJoTQx.js → Trust-D1Pvqems.js} +1 -1
  84. package/src/assets/web-panel/assets/{UkeySign-aASNCs5j.js → UkeySign-Do3VVnAy.js} +1 -1
  85. package/src/assets/web-panel/assets/{VideoEditing-Bz89M52u.js → VideoEditing-Dz7egVIA.js} +1 -1
  86. package/src/assets/web-panel/assets/{Wallet-uU4dSS_N.js → Wallet-Dcuw-OxR.js} +3 -3
  87. package/src/assets/web-panel/assets/{WebAuthn-Brrroxgr.js → WebAuthn-DPlw-QsB.js} +3 -3
  88. package/src/assets/web-panel/assets/{WorkflowEditor-Cny-evI9.js → WorkflowEditor-h4OsnU5q.js} +1 -1
  89. package/src/assets/web-panel/assets/{chat-CJ5iSwWq.js → chat-eO9wEwrW.js} +1 -1
  90. package/src/assets/web-panel/assets/{colors-DWa-2flG.js → colors-34lSmOXw.js} +1 -1
  91. package/src/assets/web-panel/assets/{compact-item-DFwUfptU.js → compact-item-CK4kEWJ4.js} +1 -1
  92. package/src/assets/web-panel/assets/{createContext-FHWWcyeB.js → createContext-E0A57xed.js} +1 -1
  93. package/src/assets/web-panel/assets/devWarning-CF3xafX2.js +1 -0
  94. package/src/assets/web-panel/assets/{hasIn-QY_TElrN.js → hasIn-BD9ZMGAl.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-BcVr-LOk.js → index--N0u6kTG.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-CUiTugu3.js → index-8qMA1DWQ.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-0umhind6.js → index-B0rkHxKK.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-wqiOz655.js → index-B_G_ElKO.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-B18zERdP.js → index-BbX_Dted.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-Dy2PnKZx.js → index-Bjs90Eh9.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-th467RN6.js → index-BmNbU2Z6.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-uRUZdL7I.js → index-Brqc9Emx.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-hw1J_Oxs.js → index-BsGmo6v1.js} +1 -1
  104. package/src/assets/web-panel/assets/index-C907rPwd.js +1 -0
  105. package/src/assets/web-panel/assets/{index-CjejB-z9.js → index-CT1_eRL-.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-DaHvj4jA.js → index-CZBaqe3d.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-B33frlaD.js → index-CZkFMeWL.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-BYbwQ7SP.js → index-Ch175NUw.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-va4Rt-yM.js → index-CsrKJJcX.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-DDpXDi4J.js → index-CuSau5ya.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-D-Mhq8K6.js → index-Cx3Jn1r0.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-CKS7n6mE.js → index-Cz3unNfL.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-BRsGZBHc.js → index-D4bB_x_v.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-Bd7McYpJ.js → index-DCn-ECvK.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-DUfILsc-.js → index-DFLE2qO9.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-DUepuy7O.js → index-DGRxt5wj.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-BR4RMPnB.js → index-DONOUtlz.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-Dlq-u9E4.js → index-DP-UZAQN.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-DCHMVYG1.js → index-Da5fmOHB.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-BiHRihC0.js → index-DcE1BspQ.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-CGv5In_T.js → index-DcbgVLOH.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-BQCtBurK.js → index-DeXNCyQJ.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-D2rPJ6Sv.js → index-DiT_REby.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-CUoLd1dt.js → index-DpfisY1g.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-2ufsNuVn.js → index-DrOalGut.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-aTiI7lOQ.js → index-DrSAAuJj.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-BUNwuu5v.js → index-DrsDA_md.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-CkmgbT7h.js → index-DvKcroix.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-BEjwv2x6.js → index-DzXjP44T.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-CeGn0A4W.js → index-MIg5Z8qe.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-C5F1vwec.js → index-o8pYehRq.js} +3 -3
  132. package/src/assets/web-panel/assets/index-wueRSK2d.js +1 -0
  133. package/src/assets/web-panel/assets/{index-w3SdYwaC.js → index-yAGBu2E0.js} +1 -1
  134. package/src/assets/web-panel/assets/{initDefaultProps-BeSPUFDz.js → initDefaultProps-DMTkAomF.js} +1 -1
  135. package/src/assets/web-panel/assets/{motion-Dcajvjm9.js → motion-Cnti1F5g.js} +1 -1
  136. package/src/assets/web-panel/assets/{move-B76orau-.js → move-CGxmHUga.js} +1 -1
  137. package/src/assets/web-panel/assets/{mtc-parser-zB6yFwcX.js → mtc-parser-CuwwLoq7.js} +1 -1
  138. package/src/assets/web-panel/assets/{omit-BsbNjz8w.js → omit-BpdlTkPM.js} +1 -1
  139. package/src/assets/web-panel/assets/{pickAttrs-BiJ9tssQ.js → pickAttrs-D7nWrThp.js} +1 -1
  140. package/src/assets/web-panel/assets/{placementArrow-BdfMjMeN.js → placementArrow-Bhx0TV8F.js} +1 -1
  141. package/src/assets/web-panel/assets/{responsiveObserve-rV4LGpbU.js → responsiveObserve-CZ1KesZh.js} +1 -1
  142. package/src/assets/web-panel/assets/{slide-HsVw1qFQ.js → slide-CnldF8J6.js} +1 -1
  143. package/src/assets/web-panel/assets/{statusUtils-D1ry8XPE.js → statusUtils-CZfo_GOA.js} +1 -1
  144. package/src/assets/web-panel/assets/{styleChecker-B1t6aQQ_.js → styleChecker-B2QCcAv5.js} +1 -1
  145. package/src/assets/web-panel/assets/{useFlexGapSupport-C8qbl-9w.js → useFlexGapSupport-DzzjIS4J.js} +1 -1
  146. package/src/assets/web-panel/assets/{useFs-R7g_mYTC.js → useFs-B_atg9M0.js} +1 -1
  147. package/src/assets/web-panel/assets/{usePersonalDataHub-Cd-kCe7Z.js → usePersonalDataHub-DhZs3QYN.js} +1 -1
  148. package/src/assets/web-panel/assets/{vnode-9WhK5UWA.js → vnode-DcePTYAm.js} +1 -1
  149. package/src/assets/web-panel/assets/{zoom-CUqppPco.js → zoom-BYmlnjRk.js} +1 -1
  150. package/src/assets/web-panel/index.html +1 -1
  151. package/src/command-help-index.json +2 -2
  152. package/src/commands/agent.js +19 -1
  153. package/src/commands/evolution-knowledge.js +54 -0
  154. package/src/commands/evolution-workbench.js +83 -0
  155. package/src/commands/evolution.js +6 -1
  156. package/src/commands/serve.js +47 -0
  157. package/src/commands/skill.js +158 -16
  158. package/src/data/changelog.json +26 -0
  159. package/src/gateways/ws/session-protocol.js +2 -0
  160. package/src/gateways/ws/ws-agent-handler.js +124 -69
  161. package/src/gateways/ws/ws-server.js +19 -0
  162. package/src/generated/cc-agent-protocol.schema.json +7 -1
  163. package/src/harness/jsonl-session-store.js +25 -1
  164. package/src/index.js +11 -3
  165. package/src/lazy-dispatch.js +9 -1
  166. package/src/lib/app-server/cli-agent-kernel-adapter.js +8 -0
  167. package/src/lib/app-server/graph-runtime.js +40 -1
  168. package/src/lib/app-server/server.js +181 -3
  169. package/src/lib/app-server/websocket-transport.js +23 -0
  170. package/src/lib/evolution/agent-evolution-runtime-composition-brand.js +17 -0
  171. package/src/lib/evolution/agent-evolution-runtime-composition.js +165 -1
  172. package/src/lib/evolution/controlled-skill-production-pilot.js +912 -0
  173. package/src/lib/evolution/evolution-artifact-ports.js +30 -0
  174. package/src/lib/evolution/evolution-deployment-loader.js +208 -0
  175. package/src/lib/evolution/evolution-raw-crypto-shred.js +185 -0
  176. package/src/lib/evolution/evolution-release-train-ledger-adapter.js +335 -0
  177. package/src/lib/evolution/evolution-release-train.js +538 -0
  178. package/src/lib/evolution/evolution-workbench-batch-executor.js +195 -0
  179. package/src/lib/evolution/evolution-workbench-cli-host.js +169 -0
  180. package/src/lib/evolution/evolution-workbench-metrics-ledger-adapter.js +648 -0
  181. package/src/lib/evolution/evolution-workbench-metrics.js +943 -0
  182. package/src/lib/evolution/evolution-workbench-projection.js +753 -0
  183. package/src/lib/evolution/evolution-workbench-version-control.js +272 -0
  184. package/src/lib/evolution/evolvable-artifact-ledger-adapter.js +688 -0
  185. package/src/lib/evolution/governed-knowledge-artifact-lifecycle.js +364 -0
  186. package/src/lib/evolution/governed-knowledge-conflict-merge.js +352 -0
  187. package/src/lib/evolution/governed-knowledge-dependency-authority.js +273 -0
  188. package/src/lib/evolution/governed-knowledge-dependency-ledger-executor.js +646 -0
  189. package/src/lib/evolution/governed-knowledge-merge-ledger-executor.js +671 -0
  190. package/src/lib/evolution/governed-knowledge-merge-publisher-authority.js +310 -0
  191. package/src/lib/evolution/governed-knowledge-node-crypto-authority.js +348 -0
  192. package/src/lib/evolution/governed-knowledge-rbac-approval-authority.js +621 -0
  193. package/src/lib/evolution/governed-knowledge-review-host.js +249 -0
  194. package/src/lib/evolution/governed-knowledge-sync-ledger-adapter.js +729 -0
  195. package/src/lib/evolution/governed-knowledge-sync-merge-publisher.js +312 -0
  196. package/src/lib/evolution/governed-knowledge-sync.js +795 -0
  197. package/src/lib/evolution/governed-knowledge-trust-ledger.js +707 -0
  198. package/src/lib/evolution/governed-skill-marketplace.js +430 -0
  199. package/src/lib/evolution/governed-wiki-pruning.js +435 -0
  200. package/src/lib/evolution/skill-outcome-index-authority.js +268 -0
  201. package/src/lib/evolution/skill-outcome-source-catalog-authority.js +237 -0
  202. package/src/lib/evolution/skill-writer-inventory-manifest.js +7 -6
  203. package/src/lib/evolution/statistical-progressive-canary.js +683 -0
  204. package/src/lib/evolution/wikiskill-benchmark.js +510 -0
  205. package/src/lib/public-ide-capability-manifest.js +4 -0
  206. package/src/lib/session-host-lease.js +11 -16
  207. package/src/lib/skill-outcome-authority.js +43 -0
  208. package/src/lib/skill-outcome-transcript-authority.js +252 -0
  209. package/src/lib/skill-retrieval-router-benchmark.js +135 -0
  210. package/src/lib/skill-retrieval-router.js +235 -0
  211. package/src/lib/skill-vector-authority.js +325 -0
  212. package/src/lib/skill-vector-process-authority.js +386 -0
  213. package/src/repl/agent-repl.js +7 -1
  214. package/src/runtime/agent-core.js +133 -13
  215. package/src/runtime/agent-runtime.js +42 -0
  216. package/src/runtime/headless-runner.js +32 -0
  217. package/src/runtime/headless-stream.js +39 -1
  218. package/src/runtime/runtime-factory.js +62 -4
  219. package/src/assets/web-panel/assets/ChatBubbleRenderer-eMmw1eZF.js +0 -1
  220. package/src/assets/web-panel/assets/devWarning-DxufPwXC.js +0 -1
  221. package/src/assets/web-panel/assets/index-ZMTB9p5z.js +0 -1
  222. package/src/assets/web-panel/assets/index-_PvIDelE.js +0 -1
@@ -0,0 +1,364 @@
1
+ import { types as utilTypes } from "node:util";
2
+
3
+ import evolvableArtifactProtocol from "@chainlesschain/session-core/evolvable-artifact";
4
+
5
+ import {
6
+ isEvolvableArtifactReleaseResolver,
7
+ isEvolvableArtifactTransitionReader,
8
+ } from "./evolvable-artifact-ledger-adapter.js";
9
+ import { verifyGovernedKnowledgeRecord } from "./governed-knowledge-sync.js";
10
+
11
+ const {
12
+ ARTIFACT_TYPE,
13
+ createEvolvableArtifactReceipt,
14
+ digestEvolvableArtifactValue,
15
+ isEvolvableArtifactCandidateGate,
16
+ isEvolvableArtifactReleaseGate,
17
+ } = evolvableArtifactProtocol;
18
+
19
+ export const GOVERNED_KNOWLEDGE_ARTIFACT_LIFECYCLE_SCHEMA =
20
+ "chainlesschain.governed-knowledge-artifact-lifecycle/v1";
21
+
22
+ const LIFECYCLES = new WeakSet();
23
+ const DIGEST = /^sha256:[a-f0-9]{64}$/u;
24
+ const ID = /^[A-Za-z0-9][A-Za-z0-9._:@/-]{0,255}$/u;
25
+ const OPERATIONS = new Set(["publish", "receive", "merge"]);
26
+
27
+ function freeze(value) {
28
+ const result = structuredClone(value);
29
+ function visit(entry) {
30
+ if (entry && typeof entry === "object" && !Object.isFrozen(entry)) {
31
+ Object.freeze(entry);
32
+ for (const child of Object.values(entry)) visit(child);
33
+ }
34
+ }
35
+ visit(result);
36
+ return result;
37
+ }
38
+
39
+ function capture(owner, method, label) {
40
+ if (
41
+ !owner ||
42
+ typeof owner !== "object" ||
43
+ utilTypes.isProxy(owner) ||
44
+ typeof owner[method] !== "function"
45
+ )
46
+ throw new TypeError(`${label}.${method}() is required`);
47
+ return (...args) => Reflect.apply(owner[method], owner, args);
48
+ }
49
+
50
+ function manifest(body) {
51
+ return freeze({ ...body, digest: digestEvolvableArtifactValue(body) });
52
+ }
53
+
54
+ function receipt(artifact, kind, issuedAt, operationDigest, claims) {
55
+ return createEvolvableArtifactReceipt({
56
+ kind,
57
+ tenantId: artifact.tenantId,
58
+ artifactId: artifact.artifactId,
59
+ candidateId: artifact.candidate.candidateId,
60
+ contentDigest: artifact.contentDigest,
61
+ dependencyLockDigest: artifact.dependencyLock.digest,
62
+ issuerId: `governed-knowledge-lifecycle:${kind}`,
63
+ issuerRevision: "v1",
64
+ issuedAt,
65
+ decision: "allow",
66
+ claims: { operationDigest, ...claims },
67
+ });
68
+ }
69
+
70
+ export function createGovernedKnowledgeArtifactLifecycle({
71
+ tenantId,
72
+ artifactCandidateGate,
73
+ artifactReleaseGate,
74
+ artifactReleaseResolver,
75
+ verifierArtifactTransitionReader,
76
+ } = {}) {
77
+ if (typeof tenantId !== "string" || tenantId.trim() === "")
78
+ throw new TypeError("tenantId is required");
79
+ if (
80
+ !isEvolvableArtifactCandidateGate(
81
+ artifactCandidateGate,
82
+ ARTIFACT_TYPE.KNOWLEDGE,
83
+ ) ||
84
+ artifactCandidateGate.tenantId !== tenantId
85
+ )
86
+ throw new TypeError("a tenant-bound Knowledge candidate gate is required");
87
+ if (
88
+ !isEvolvableArtifactReleaseGate(
89
+ artifactReleaseGate,
90
+ ARTIFACT_TYPE.KNOWLEDGE,
91
+ ) ||
92
+ artifactReleaseGate.tenantId !== tenantId ||
93
+ artifactReleaseGate.authorityScope !== artifactCandidateGate.authorityScope
94
+ )
95
+ throw new TypeError("a same-authority Knowledge release gate is required");
96
+ if (
97
+ !isEvolvableArtifactReleaseResolver(artifactReleaseResolver) ||
98
+ artifactReleaseResolver.tenantId !== tenantId
99
+ )
100
+ throw new TypeError("a tenant-bound artifact release resolver is required");
101
+ if (
102
+ !isEvolvableArtifactTransitionReader(verifierArtifactTransitionReader) ||
103
+ verifierArtifactTransitionReader.tenantId !== tenantId ||
104
+ verifierArtifactTransitionReader.readerScope ===
105
+ artifactReleaseGate.transitionReaderScope
106
+ )
107
+ throw new TypeError(
108
+ "an independent artifact transition reader is required",
109
+ );
110
+
111
+ const stageCandidate = capture(
112
+ artifactCandidateGate,
113
+ "stageCandidate",
114
+ "artifactCandidateGate",
115
+ );
116
+ const preparePromotion = capture(
117
+ artifactReleaseGate,
118
+ "preparePromotion",
119
+ "artifactReleaseGate",
120
+ );
121
+ const commitPromotion = capture(
122
+ artifactReleaseGate,
123
+ "commitPreparedPromotion",
124
+ "artifactReleaseGate",
125
+ );
126
+ const resolveDependency = capture(
127
+ artifactReleaseResolver,
128
+ "resolveDependency",
129
+ "artifactReleaseResolver",
130
+ );
131
+ const readTransition = capture(
132
+ verifierArtifactTransitionReader,
133
+ "readTransition",
134
+ "verifierArtifactTransitionReader",
135
+ );
136
+ const preparedHandles = new WeakSet();
137
+
138
+ async function resolveOne(dependency) {
139
+ const resolved = await resolveDependency({ tenantId, ...dependency });
140
+ if (
141
+ resolved?.authenticated !== true ||
142
+ resolved.durable !== true ||
143
+ resolved.tenantId !== tenantId ||
144
+ resolved.sourceKind !== dependency.kind ||
145
+ resolved.sourceDigest !== dependency.digest ||
146
+ resolved.sourceDisposition !== dependency.disposition ||
147
+ !DIGEST.test(resolved.artifactDigest ?? "")
148
+ )
149
+ throw new Error("Knowledge artifact dependency resolution is invalid");
150
+ return {
151
+ artifactId: resolved.artifactId,
152
+ type: resolved.type,
153
+ releaseId: resolved.releaseId,
154
+ contentDigest: resolved.contentDigest,
155
+ };
156
+ }
157
+
158
+ async function resolveBaseline(currentKnowledge) {
159
+ if (currentKnowledge === null) return null;
160
+ const resolved = await resolveOne({
161
+ kind: "active-knowledge",
162
+ digest: currentKnowledge.contentDigest,
163
+ disposition: "baseline",
164
+ });
165
+ if (resolved.artifactId !== currentKnowledge.knowledgeId)
166
+ throw new Error("Knowledge typed baseline resolved another artifact");
167
+ return resolved;
168
+ }
169
+
170
+ const lifecycle = Object.freeze({
171
+ schema: GOVERNED_KNOWLEDGE_ARTIFACT_LIFECYCLE_SCHEMA,
172
+ tenantId,
173
+ async prepare({
174
+ knowledge: knowledgeInput,
175
+ currentKnowledge: currentInput = null,
176
+ operation,
177
+ operationId,
178
+ authorizationReceiptDigest,
179
+ evidenceDigest = null,
180
+ issuedAt,
181
+ activate = true,
182
+ humanReviewed = false,
183
+ } = {}) {
184
+ if (!OPERATIONS.has(operation))
185
+ throw new TypeError("Knowledge lifecycle operation is invalid");
186
+ if (!ID.test(operationId ?? ""))
187
+ throw new TypeError("Knowledge lifecycle operationId is required");
188
+ if (!DIGEST.test(authorizationReceiptDigest ?? ""))
189
+ throw new TypeError("authorizationReceiptDigest is invalid");
190
+ if (!Number.isFinite(Date.parse(issuedAt)))
191
+ throw new TypeError("Knowledge lifecycle issuedAt is invalid");
192
+ const boundEvidenceDigest = evidenceDigest ?? authorizationReceiptDigest;
193
+ if (
194
+ !DIGEST.test(boundEvidenceDigest) ||
195
+ typeof humanReviewed !== "boolean"
196
+ )
197
+ throw new TypeError("Knowledge lifecycle evidence is invalid");
198
+ const knowledge = verifyGovernedKnowledgeRecord(knowledgeInput, {
199
+ tenantId,
200
+ });
201
+ const currentKnowledge =
202
+ currentInput === null
203
+ ? null
204
+ : verifyGovernedKnowledgeRecord(currentInput, { tenantId });
205
+ if (
206
+ currentKnowledge !== null &&
207
+ (currentKnowledge.knowledgeId !== knowledge.knowledgeId ||
208
+ currentKnowledge.scope !== knowledge.scope ||
209
+ currentKnowledge.scopeId !== knowledge.scopeId)
210
+ )
211
+ throw new Error("Knowledge lifecycle baseline boundary changed");
212
+ const baseline = await resolveBaseline(currentKnowledge);
213
+ const dependencies = [];
214
+ if (knowledge.action === "upsert") {
215
+ for (const dependency of knowledge.dependencies)
216
+ dependencies.push(await resolveOne(dependency));
217
+ }
218
+ dependencies.sort((left, right) =>
219
+ left.artifactId.localeCompare(right.artifactId),
220
+ );
221
+ const dependencyLock = {
222
+ dependencies,
223
+ digest: digestEvolvableArtifactValue({ dependencies }),
224
+ };
225
+ const operationCore = {
226
+ tenantId,
227
+ operation,
228
+ operationId,
229
+ knowledgeId: knowledge.knowledgeId,
230
+ contentDigest: knowledge.contentDigest,
231
+ currentContentDigest: currentKnowledge?.contentDigest ?? null,
232
+ authorizationReceiptDigest,
233
+ evidenceDigest: boundEvidenceDigest,
234
+ humanReviewed,
235
+ };
236
+ const operationDigest = digestEvolvableArtifactValue(operationCore);
237
+ const staged = await stageCandidate({
238
+ tenantId,
239
+ artifactId: knowledge.knowledgeId,
240
+ type: ARTIFACT_TYPE.KNOWLEDGE,
241
+ contentDigest: knowledge.contentDigest,
242
+ parent:
243
+ baseline === null
244
+ ? null
245
+ : {
246
+ artifactId: baseline.artifactId,
247
+ releaseId: baseline.releaseId,
248
+ contentDigest: baseline.contentDigest,
249
+ },
250
+ lineage: [
251
+ ...(currentKnowledge ? [currentKnowledge.contentDigest] : []),
252
+ knowledge.contentDigest,
253
+ ],
254
+ dependencyLock,
255
+ runtimeManifest: manifest({
256
+ executable: false,
257
+ operation,
258
+ operationId,
259
+ operationDigest,
260
+ action: knowledge.action,
261
+ scope: knowledge.scope,
262
+ scopeId: knowledge.scopeId,
263
+ vectorClock: knowledge.vectorClock,
264
+ dependencyDispositionDigest: digestEvolvableArtifactValue(
265
+ knowledge.dependencies,
266
+ ),
267
+ }),
268
+ permissionManifest: manifest({
269
+ authorizationReceiptDigest,
270
+ approvalReceiptDigest: knowledge.approvalReceiptDigest,
271
+ revocationReceiptDigest: knowledge.revocationReceiptDigest,
272
+ capabilities: [`knowledge:${knowledge.scope}:${operation}`],
273
+ }),
274
+ candidateId: `knowledge-candidate:${operationDigest.slice(7)}`,
275
+ activeReleaseId: baseline?.releaseId ?? null,
276
+ lastKnownGoodReleaseId: null,
277
+ });
278
+ const promotion = activate
279
+ ? preparePromotion({
280
+ artifact: staged.artifact,
281
+ candidatePersistenceReceipt: staged.receipt,
282
+ evaluationReceipt: receipt(
283
+ staged.artifact,
284
+ "eval",
285
+ issuedAt,
286
+ operationDigest,
287
+ { authorizationReceiptDigest },
288
+ ),
289
+ reviewReceipt: receipt(
290
+ staged.artifact,
291
+ "review",
292
+ issuedAt,
293
+ operationDigest,
294
+ {
295
+ approvalReceiptDigest: knowledge.approvalReceiptDigest,
296
+ automated: !humanReviewed,
297
+ evidenceDigest: boundEvidenceDigest,
298
+ },
299
+ ),
300
+ promotionReceipt: receipt(
301
+ staged.artifact,
302
+ "promotion",
303
+ issuedAt,
304
+ operationDigest,
305
+ { operationId },
306
+ ),
307
+ releaseId: `knowledge-release:${operationDigest.slice(7)}`,
308
+ })
309
+ : null;
310
+ const prepared = Object.freeze({
311
+ operationDigest,
312
+ operation,
313
+ operationId,
314
+ candidate: staged,
315
+ promotion,
316
+ activate,
317
+ });
318
+ preparedHandles.add(prepared);
319
+ return prepared;
320
+ },
321
+ async commit(prepared) {
322
+ if (!preparedHandles.has(prepared))
323
+ throw new TypeError(
324
+ "a prepared Knowledge lifecycle handle is required",
325
+ );
326
+ if (!prepared.activate)
327
+ return freeze({
328
+ candidateOnly: true,
329
+ artifactCandidateDigest: prepared.candidate.artifact.artifactDigest,
330
+ operationDigest: prepared.operationDigest,
331
+ });
332
+ const committed = await commitPromotion(prepared.promotion);
333
+ const readback = await readTransition({
334
+ operationId: committed.receipt.operationId,
335
+ });
336
+ if (
337
+ readback?.request?.previousArtifactDigest !==
338
+ prepared.candidate.artifact.artifactDigest ||
339
+ readback.request.nextArtifactDigest !==
340
+ committed.artifact.artifactDigest ||
341
+ readback.artifact.artifactDigest !==
342
+ committed.artifact.artifactDigest ||
343
+ readback.receipt.receiptDigest !== committed.receipt.receiptDigest ||
344
+ readback.receipt.durable !== true
345
+ )
346
+ throw new Error("Knowledge artifact transition readback is invalid");
347
+ return freeze({
348
+ candidateOnly: false,
349
+ operationDigest: prepared.operationDigest,
350
+ artifactCandidateDigest: prepared.candidate.artifact.artifactDigest,
351
+ artifactDigest: committed.artifact.artifactDigest,
352
+ artifactReleaseId: committed.artifact.activeReleaseId,
353
+ artifactTransitionOperationId: committed.receipt.operationId,
354
+ artifactTransitionReceiptDigest: committed.receipt.receiptDigest,
355
+ });
356
+ },
357
+ });
358
+ LIFECYCLES.add(lifecycle);
359
+ return lifecycle;
360
+ }
361
+
362
+ export function isGovernedKnowledgeArtifactLifecycle(value) {
363
+ return LIFECYCLES.has(value);
364
+ }
@@ -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
+ }