chainlesschain 0.166.21 → 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 (178) hide show
  1. package/README.md +67 -9
  2. package/package.json +1 -1
  3. package/src/assets/web-panel/assets/{AIOps-BjMnsUci.js → AIOps-oJ7USzMC.js} +1 -1
  4. package/src/assets/web-panel/assets/{ActionButton-DdYFP03A.js → ActionButton-BlgnZe_C.js} +1 -1
  5. package/src/assets/web-panel/assets/{Analytics-Bb8TuuK_.js → Analytics-D2rRbTLu.js} +2 -2
  6. package/src/assets/web-panel/assets/{AppLayout-Kn3TIOtk.js → AppLayout-FwS3f0B2.js} +5 -5
  7. package/src/assets/web-panel/assets/{Artifacts-4IxpqI_b.js → Artifacts-iF-_08Hi.js} +1 -1
  8. package/src/assets/web-panel/assets/{Audit-BOV2caqU.js → Audit-D24p0zQw.js} +1 -1
  9. package/src/assets/web-panel/assets/{BackgroundAgents-B86k-ay4.js → BackgroundAgents-Cg3mRVi9.js} +1 -1
  10. package/src/assets/web-panel/assets/{Backup-C5_ie1e3.js → Backup-EOqht3H-.js} +1 -1
  11. package/src/assets/web-panel/assets/{BaseInput-xpwg6QCW.js → BaseInput-9XWYq2hj.js} +1 -1
  12. package/src/assets/web-panel/assets/{Chat-CVZOcZau.js → Chat-Dq5yardA.js} +4 -4
  13. package/src/assets/web-panel/assets/{ChatBubbleRenderer-D8fPYhUu.js → ChatBubbleRenderer-Ds3pA-ET.js} +1 -1
  14. package/src/assets/web-panel/assets/{Checkbox-MKTq3zdP.js → Checkbox-CuyCBoBf.js} +1 -1
  15. package/src/assets/web-panel/assets/{Codegen-JUk3wzep.js → Codegen-DjWtYHNe.js} +1 -1
  16. package/src/assets/web-panel/assets/{Col-JPvTA0kC.js → Col-CrVr_iuG.js} +1 -1
  17. package/src/assets/web-panel/assets/{Community-Tqgl87NQ.js → Community-C6QxpfGc.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compact-BuAFYBmN.js → Compact-B-v5r6Pa.js} +1 -1
  19. package/src/assets/web-panel/assets/{Compliance-CXS9WIPZ.js → Compliance-zNiLiFgD.js} +1 -1
  20. package/src/assets/web-panel/assets/{Cowork-Ds2bFHrr.js → Cowork-D9K7lMOu.js} +2 -2
  21. package/src/assets/web-panel/assets/{Cron-C_dV_OeW.js → Cron-DAjO36z4.js} +2 -2
  22. package/src/assets/web-panel/assets/{Crosschain-BsO6tIRo.js → Crosschain-Bxqn0aqB.js} +1 -1
  23. package/src/assets/web-panel/assets/{DID-rNOFqBac.js → DID-DfRmLUe-.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dashboard-C2fcKKVY.js → Dashboard-Cz8KF3fr.js} +2 -2
  25. package/src/assets/web-panel/assets/{Dropdown-Y7Ndr0X_.js → Dropdown-C4oVfkP0.js} +1 -1
  26. package/src/assets/web-panel/assets/{EmailListRenderer-DcP_uPmL.js → EmailListRenderer-ivyZKN8k.js} +1 -1
  27. package/src/assets/web-panel/assets/{FamilyGuardDashboard-Cwn3gDzk.js → FamilyGuardDashboard-DoxY1CPW.js} +1 -1
  28. package/src/assets/web-panel/assets/{Federation-ClQuOsqb.js → Federation-C93gZxnb.js} +1 -1
  29. package/src/assets/web-panel/assets/{FormItemContext-DfwtmlcK.js → FormItemContext-D_lEjYJE.js} +1 -1
  30. package/src/assets/web-panel/assets/{GenericCardRenderer-zNZhtbC5.js → GenericCardRenderer-BNFN9YjN.js} +1 -1
  31. package/src/assets/web-panel/assets/{Git-BZmdW-G5.js → Git-mUu2HcLI.js} +2 -2
  32. package/src/assets/web-panel/assets/{Governance-CqBk4lEn.js → Governance-CNuosrge.js} +1 -1
  33. package/src/assets/web-panel/assets/{Inference-Dbmt3ZXk.js → Inference-DwY5pbCB.js} +1 -1
  34. package/src/assets/web-panel/assets/{KnowledgeGraph-hMTH6qf3.js → KnowledgeGraph-aRUxhACD.js} +1 -1
  35. package/src/assets/web-panel/assets/{Logs-CkiYgiW2.js → Logs-DFfsWYy_.js} +2 -2
  36. package/src/assets/web-panel/assets/{MarkdownRenderer-BL1FElXg.js → MarkdownRenderer-DqTx7_u1.js} +1 -1
  37. package/src/assets/web-panel/assets/{Marketplace-CbB6wfin.js → Marketplace-COI-ciM-.js} +1 -1
  38. package/src/assets/web-panel/assets/{McpTools-BSwiFtte.js → McpTools-BJJwaIpe.js} +2 -2
  39. package/src/assets/web-panel/assets/{Memory-B03PeHrz.js → Memory-CDO6SGDZ.js} +2 -2
  40. package/src/assets/web-panel/assets/{MobileBridge-CRGrnd-X.js → MobileBridge-BlZ5tFf4.js} +1 -1
  41. package/src/assets/web-panel/assets/{MobileProjects-CE_5v2kO.js → MobileProjects-DuoxbgWz.js} +1 -1
  42. package/src/assets/web-panel/assets/{Mtc-Dp11QVx1.js → Mtc-6ec9j70b.js} +2 -2
  43. package/src/assets/web-panel/assets/{MtcAudit-CYu-3JBu.js → MtcAudit-BuL7HkC7.js} +2 -2
  44. package/src/assets/web-panel/assets/{Multisig-CGyJ0Xl3.js → Multisig-CJxR85lk.js} +3 -3
  45. package/src/assets/web-panel/assets/{NLProgramming-CoWi_ov1.js → NLProgramming-B71O1S4l.js} +1 -1
  46. package/src/assets/web-panel/assets/Notes-Bsw5zbpV.js +7 -0
  47. package/src/assets/web-panel/assets/{NotificationSettings-DX4I2b4W.js → NotificationSettings-BnAhXuK_.js} +1 -1
  48. package/src/assets/web-panel/assets/OrderTableRenderer-BJ0R5GGz.js +1 -0
  49. package/src/assets/web-panel/assets/{Organization-oopLO_tk.js → Organization-B7wwNxoP.js} +4 -4
  50. package/src/assets/web-panel/assets/{Overflow-BFVvjMyf.js → Overflow-CfAGr0gM.js} +1 -1
  51. package/src/assets/web-panel/assets/{P2P-CBy5t-Tk.js → P2P-KhMg22Fz.js} +2 -2
  52. package/src/assets/web-panel/assets/{PdhVaultBrowser--YWJNsu6.js → PdhVaultBrowser-NdAXI9ft.js} +3 -3
  53. package/src/assets/web-panel/assets/{Permissions-C2dZ8scb.js → Permissions-CIYjqyT7.js} +4 -4
  54. package/src/assets/web-panel/assets/{PersonalDataHub-Bs3l7Hlx.js → PersonalDataHub-D2ht3P_R.js} +4 -4
  55. package/src/assets/web-panel/assets/{Pipeline-DEBWbZuD.js → Pipeline-i6flZW1m.js} +1 -1
  56. package/src/assets/web-panel/assets/{Privacy-CjHBb6NU.js → Privacy-DE0lhYVc.js} +1 -1
  57. package/src/assets/web-panel/assets/{ProjectInit-D2WipUz5.js → ProjectInit-BL3YbyxS.js} +2 -2
  58. package/src/assets/web-panel/assets/{ProjectSettings-B6WfnrGB.js → ProjectSettings-CEtdg7ni.js} +2 -2
  59. package/src/assets/web-panel/assets/{Projects-FF_thRi6.js → Projects-CvtU5peJ.js} +1 -1
  60. package/src/assets/web-panel/assets/{Providers-CCv5M_Dv.js → Providers-DKt_Cg-j.js} +1 -1
  61. package/src/assets/web-panel/assets/{QrScannerModal-CGthxU54.js → QrScannerModal-DA61jNSx.js} +1 -1
  62. package/src/assets/web-panel/assets/{QuickAsk-CnPmXPFb.js → QuickAsk-fS9ryUmq.js} +1 -1
  63. package/src/assets/web-panel/assets/{Recommend-Df_tGEa9.js → Recommend-CR9dZU5Y.js} +1 -1
  64. package/src/assets/web-panel/assets/{RemoteSession-Z58N0Loe.js → RemoteSession-BV0BR2Dz.js} +2 -2
  65. package/src/assets/web-panel/assets/{Reputation-CZTBQ2Vt.js → Reputation-BIeGUvYD.js} +1 -1
  66. package/src/assets/web-panel/assets/{Row-CdK3YpCQ.js → Row-DHDT1aro.js} +1 -1
  67. package/src/assets/web-panel/assets/{RssFeed-CFMVT5sb.js → RssFeed-Cq6YKb1h.js} +3 -3
  68. package/src/assets/web-panel/assets/{Search-DrF8RIvD.js → Search-DEF6vsy6.js} +1 -1
  69. package/src/assets/web-panel/assets/{Security-Ddk2f2DM.js → Security-CHtYiKY9.js} +4 -4
  70. package/src/assets/web-panel/assets/{Services-CCuK-VOo.js → Services-u16lvBJN.js} +2 -2
  71. package/src/assets/web-panel/assets/{Skeleton-DxCpHzeM.js → Skeleton-CGbizyDj.js} +1 -1
  72. package/src/assets/web-panel/assets/{Skills-t2oTDgcv.js → Skills-BZMQcAa7.js} +1 -1
  73. package/src/assets/web-panel/assets/{Sla-Df63M9_R.js → Sla-Bm-CycVi.js} +1 -1
  74. package/src/assets/web-panel/assets/{SpeechSettings-l7ox6KuX.js → SpeechSettings-BudpA5kr.js} +1 -1
  75. package/src/assets/web-panel/assets/{SyncSettings-COd_tgPp.js → SyncSettings-B8q1C1eC.js} +2 -2
  76. package/src/assets/web-panel/assets/{Tasks-CzDCcrik.js → Tasks-SU1pBWc-.js} +1 -1
  77. package/src/assets/web-panel/assets/{Templates-D-vfxTGA.js → Templates-CyOfJzmt.js} +1 -1
  78. package/src/assets/web-panel/assets/{Tenant-BlpT_Gxc.js → Tenant-xqWSm2GP.js} +1 -1
  79. package/src/assets/web-panel/assets/{Terminal-D5rq52Hg.js → Terminal-D1Ttgjsi.js} +2 -2
  80. package/src/assets/web-panel/assets/{TimelineRenderer-DdoMndkK.js → TimelineRenderer-Da2lYs5D.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tokens-BhgBsI6g.js → Tokens-B34-SduO.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trigger-DwwzoikZ.js → Trigger-C8zyYm4R.js} +1 -1
  83. package/src/assets/web-panel/assets/{Trust-HkTpzXFb.js → Trust-D1Pvqems.js} +1 -1
  84. package/src/assets/web-panel/assets/{UkeySign-D9nk6Ehe.js → UkeySign-Do3VVnAy.js} +1 -1
  85. package/src/assets/web-panel/assets/{VideoEditing-BKk0rfoy.js → VideoEditing-Dz7egVIA.js} +1 -1
  86. package/src/assets/web-panel/assets/{Wallet-IVWIU_Lq.js → Wallet-Dcuw-OxR.js} +4 -4
  87. package/src/assets/web-panel/assets/{WebAuthn-CFTCpfsG.js → WebAuthn-DPlw-QsB.js} +4 -4
  88. package/src/assets/web-panel/assets/{WorkflowEditor-Dnf4Obif.js → WorkflowEditor-h4OsnU5q.js} +1 -1
  89. package/src/assets/web-panel/assets/{chat-D2snERdj.js → chat-eO9wEwrW.js} +1 -1
  90. package/src/assets/web-panel/assets/{colors-DKEjK1N1.js → colors-34lSmOXw.js} +1 -1
  91. package/src/assets/web-panel/assets/{compact-item-BEDLwQdt.js → compact-item-CK4kEWJ4.js} +1 -1
  92. package/src/assets/web-panel/assets/{createContext-DA9iW1a0.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-5l2xEcY9.js → hasIn-BD9ZMGAl.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-C7sKbM5s.js → index--N0u6kTG.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-DU2TXJu-.js → index-8qMA1DWQ.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-CxEtQYdi.js → index-B0rkHxKK.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-B7_W_rYd.js → index-B_G_ElKO.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-B4QYBliR.js → index-BbX_Dted.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-DLoalqRX.js → index-Bjs90Eh9.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-Dbkghqn_.js → index-BmNbU2Z6.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-BgfImyZI.js → index-Brqc9Emx.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-5pW4t1iD.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-CRPrHE7h.js → index-CT1_eRL-.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-DvV03Ayk.js → index-CZBaqe3d.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-D7z4zB_a.js → index-CZkFMeWL.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-CmruhzFi.js → index-Ch175NUw.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-e-e40id6.js → index-CsrKJJcX.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-CGlotREA.js → index-CuSau5ya.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-CjWltbi_.js → index-Cx3Jn1r0.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-fccZmC_h.js → index-Cz3unNfL.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-NJieh3T1.js → index-D4bB_x_v.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-CkMKuqUs.js → index-DCn-ECvK.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-BZ5lY2zx.js → index-DFLE2qO9.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-B_eCoZgW.js → index-DGRxt5wj.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-7P1b8HZo.js → index-DONOUtlz.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-yYEQXYaU.js → index-DP-UZAQN.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-Dbd7eEex.js → index-Da5fmOHB.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-Bqc8tdIF.js → index-DcE1BspQ.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-DXet1xol.js → index-DcbgVLOH.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-BO9dQjpt.js → index-DeXNCyQJ.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-CX1x4AFn.js → index-DiT_REby.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-Bq5P3piS.js → index-DpfisY1g.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-Csfb-7hw.js → index-DrOalGut.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-DpqtbXdE.js → index-DrSAAuJj.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-B00GeekA.js → index-DrsDA_md.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-Dg2a9owQ.js → index-DvKcroix.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-fgYk0QXO.js → index-DzXjP44T.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-Td8ZwyoC.js → index-MIg5Z8qe.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-DqwPFbOb.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-CbTPvp2_.js → index-yAGBu2E0.js} +1 -1
  134. package/src/assets/web-panel/assets/{initDefaultProps-CPrcB1TC.js → initDefaultProps-DMTkAomF.js} +1 -1
  135. package/src/assets/web-panel/assets/{motion-BQ7mWRh_.js → motion-Cnti1F5g.js} +1 -1
  136. package/src/assets/web-panel/assets/{move-CzOEq99p.js → move-CGxmHUga.js} +1 -1
  137. package/src/assets/web-panel/assets/{mtc-parser-BlQI5jrw.js → mtc-parser-CuwwLoq7.js} +1 -1
  138. package/src/assets/web-panel/assets/{omit-DlW4gxmv.js → omit-BpdlTkPM.js} +1 -1
  139. package/src/assets/web-panel/assets/{pickAttrs-BBYms5nP.js → pickAttrs-D7nWrThp.js} +1 -1
  140. package/src/assets/web-panel/assets/{placementArrow-az2MPJ_7.js → placementArrow-Bhx0TV8F.js} +1 -1
  141. package/src/assets/web-panel/assets/{responsiveObserve-D1-ibEol.js → responsiveObserve-CZ1KesZh.js} +1 -1
  142. package/src/assets/web-panel/assets/{slide-DHGqa4GA.js → slide-CnldF8J6.js} +1 -1
  143. package/src/assets/web-panel/assets/{statusUtils-CYGDo6lD.js → statusUtils-CZfo_GOA.js} +1 -1
  144. package/src/assets/web-panel/assets/{styleChecker-Cl2EM9K6.js → styleChecker-B2QCcAv5.js} +1 -1
  145. package/src/assets/web-panel/assets/{useFlexGapSupport-DdYhzuv1.js → useFlexGapSupport-DzzjIS4J.js} +1 -1
  146. package/src/assets/web-panel/assets/{useFs-DWumPuBW.js → useFs-B_atg9M0.js} +1 -1
  147. package/src/assets/web-panel/assets/{usePersonalDataHub-DxAO-Aqi.js → usePersonalDataHub-DhZs3QYN.js} +1 -1
  148. package/src/assets/web-panel/assets/{vnode-CplsQf_N.js → vnode-DcePTYAm.js} +1 -1
  149. package/src/assets/web-panel/assets/{zoom-Cw5HXNSG.js → zoom-BYmlnjRk.js} +1 -1
  150. package/src/assets/web-panel/index.html +1 -1
  151. package/src/commands/serve.js +31 -0
  152. package/src/data/changelog.json +13 -0
  153. package/src/index.js +11 -3
  154. package/src/lazy-dispatch.js +9 -1
  155. package/src/lib/app-server/websocket-transport.js +21 -0
  156. package/src/lib/evolution/evolution-artifact-ports.js +9 -0
  157. package/src/lib/evolution/evolution-deployment-loader.js +208 -0
  158. package/src/lib/evolution/evolution-release-train-ledger-adapter.js +335 -0
  159. package/src/lib/evolution/evolution-release-train.js +538 -0
  160. package/src/lib/evolution/evolution-workbench-projection.js +20 -1
  161. package/src/lib/evolution/evolvable-artifact-ledger-adapter.js +688 -0
  162. package/src/lib/evolution/governed-knowledge-artifact-lifecycle.js +364 -0
  163. package/src/lib/evolution/governed-knowledge-merge-ledger-executor.js +29 -2
  164. package/src/lib/evolution/governed-knowledge-merge-publisher-authority.js +31 -3
  165. package/src/lib/evolution/governed-knowledge-sync-ledger-adapter.js +92 -6
  166. package/src/lib/evolution/governed-knowledge-sync-merge-publisher.js +57 -4
  167. package/src/lib/evolution/governed-knowledge-sync.js +317 -7
  168. package/src/lib/evolution/skill-writer-inventory-manifest.js +7 -6
  169. package/src/lib/evolution/statistical-progressive-canary.js +683 -0
  170. package/src/lib/evolution/wikiskill-benchmark.js +510 -0
  171. package/src/lib/session-host-lease.js +11 -16
  172. package/src/runtime/agent-core.js +61 -7
  173. package/src/runtime/headless-stream.js +3 -0
  174. package/src/assets/web-panel/assets/Notes-CgU9DDo9.js +0 -7
  175. package/src/assets/web-panel/assets/OrderTableRenderer-CwHc15Zs.js +0 -1
  176. package/src/assets/web-panel/assets/devWarning-DyhgpXPf.js +0 -1
  177. package/src/assets/web-panel/assets/index-Ck1jhFE0.js +0 -1
  178. package/src/assets/web-panel/assets/index-c8jJEHVs.js +0 -1
@@ -0,0 +1,208 @@
1
+ import { createHash, createPublicKey, verify } from "node:crypto";
2
+ import { readFile, realpath } from "node:fs/promises";
3
+ import { isAbsolute } from "node:path";
4
+ import { types as utilTypes } from "node:util";
5
+
6
+ export const EVOLUTION_DEPLOYMENT_DESCRIPTOR_SCHEMA =
7
+ "chainlesschain.evolution-deployment-descriptor/v1";
8
+
9
+ const DIGEST = /^sha256:[a-f0-9]{64}$/u;
10
+ const SUPPORTED_COMMANDS = new Set(["agent", "evolution", "serve"]);
11
+
12
+ function canonical(value) {
13
+ if (value === null || typeof value !== "object") return JSON.stringify(value);
14
+ if (Array.isArray(value)) return `[${value.map(canonical).join(",")}]`;
15
+ return `{${Object.keys(value)
16
+ .sort()
17
+ .map((key) => `${JSON.stringify(key)}:${canonical(value[key])}`)
18
+ .join(",")}}`;
19
+ }
20
+
21
+ function sha256(bytes) {
22
+ return `sha256:${createHash("sha256").update(bytes).digest("hex")}`;
23
+ }
24
+
25
+ function exactKeys(value, keys, name) {
26
+ if (!value || typeof value !== "object" || Array.isArray(value))
27
+ throw new TypeError(`${name} must be an object`);
28
+ if (canonical(Object.keys(value).sort()) !== canonical([...keys].sort()))
29
+ throw new TypeError(`${name} has unexpected or missing fields`);
30
+ }
31
+
32
+ function normalizeDescriptor(value) {
33
+ exactKeys(
34
+ value,
35
+ [
36
+ "schema",
37
+ "revision",
38
+ "modulePath",
39
+ "moduleDigest",
40
+ "trustRootDigest",
41
+ "commands",
42
+ "signature",
43
+ ],
44
+ "evolution deployment descriptor",
45
+ );
46
+ if (value.schema !== EVOLUTION_DEPLOYMENT_DESCRIPTOR_SCHEMA)
47
+ throw new TypeError("evolution deployment descriptor schema is invalid");
48
+ if (!Number.isSafeInteger(value.revision) || value.revision < 1)
49
+ throw new TypeError("evolution deployment descriptor revision is invalid");
50
+ if (typeof value.modulePath !== "string" || !isAbsolute(value.modulePath))
51
+ throw new TypeError("evolution deployment modulePath must be absolute");
52
+ if (!DIGEST.test(value.moduleDigest ?? ""))
53
+ throw new TypeError("evolution deployment moduleDigest is invalid");
54
+ if (!DIGEST.test(value.trustRootDigest ?? ""))
55
+ throw new TypeError("evolution deployment trustRootDigest is invalid");
56
+ if (
57
+ !Array.isArray(value.commands) ||
58
+ value.commands.length === 0 ||
59
+ new Set(value.commands).size !== value.commands.length ||
60
+ value.commands.some((command) => !SUPPORTED_COMMANDS.has(command))
61
+ )
62
+ throw new TypeError("evolution deployment commands are invalid");
63
+ if (
64
+ typeof value.signature !== "string" ||
65
+ value.signature === "" ||
66
+ !/^[A-Za-z0-9+/]+={0,2}$/u.test(value.signature)
67
+ )
68
+ throw new TypeError("evolution deployment signature is invalid");
69
+ return Object.freeze({
70
+ ...value,
71
+ commands: Object.freeze([...value.commands].sort()),
72
+ });
73
+ }
74
+
75
+ export function serializeEvolutionDeploymentDescriptorPayload(descriptor) {
76
+ const value = normalizeDescriptor({ ...descriptor, signature: "AA==" });
77
+ return canonical({
78
+ schema: value.schema,
79
+ revision: value.revision,
80
+ modulePath: value.modulePath,
81
+ moduleDigest: value.moduleDigest,
82
+ trustRootDigest: value.trustRootDigest,
83
+ commands: value.commands,
84
+ });
85
+ }
86
+
87
+ export function computeEvolutionDeploymentDigest(bytes) {
88
+ return sha256(bytes);
89
+ }
90
+
91
+ function parseJson(bytes) {
92
+ try {
93
+ return JSON.parse(Buffer.from(bytes).toString("utf8"));
94
+ } catch {
95
+ throw new Error("evolution deployment descriptor is not valid JSON");
96
+ }
97
+ }
98
+
99
+ function dependencies(value, commandName) {
100
+ if (
101
+ !value ||
102
+ typeof value !== "object" ||
103
+ Array.isArray(value) ||
104
+ utilTypes.isProxy(value)
105
+ )
106
+ throw new TypeError(
107
+ `evolution deployment returned invalid dependencies for ${commandName}`,
108
+ );
109
+ return Object.freeze({ ...value });
110
+ }
111
+
112
+ async function loadBuiltInFactories(commandName) {
113
+ const factories = {};
114
+ if (commandName === "evolution" || commandName === "serve") {
115
+ const [
116
+ { createEvolutionWorkbenchCliHost },
117
+ { createGovernedKnowledgeReviewHost },
118
+ ] = await Promise.all([
119
+ import("./evolution-workbench-cli-host.js"),
120
+ import("./governed-knowledge-review-host.js"),
121
+ ]);
122
+ factories.createEvolutionWorkbenchCliHost = createEvolutionWorkbenchCliHost;
123
+ factories.createGovernedKnowledgeReviewHost =
124
+ createGovernedKnowledgeReviewHost;
125
+ }
126
+ if (commandName === "agent" || commandName === "serve") {
127
+ const { createAgentEvolutionRuntimeComposition } =
128
+ await import("./agent-evolution-runtime-composition.js");
129
+ factories.createAgentEvolutionRuntimeComposition =
130
+ createAgentEvolutionRuntimeComposition;
131
+ }
132
+ return Object.freeze(factories);
133
+ }
134
+
135
+ export async function loadEvolutionDeploymentCommandDependencies(
136
+ commandName,
137
+ {
138
+ env = process.env,
139
+ read = readFile,
140
+ resolveRealPath = realpath,
141
+ importModule = (url) => import(url),
142
+ } = {},
143
+ ) {
144
+ if (!SUPPORTED_COMMANDS.has(commandName)) return null;
145
+ const descriptorPath = env.CHAINLESSCHAIN_EVOLUTION_DEPLOYMENT_DESCRIPTOR;
146
+ const trustRootPath = env.CHAINLESSCHAIN_EVOLUTION_DEPLOYMENT_TRUST_ROOT;
147
+ if (!descriptorPath && !trustRootPath) return null;
148
+ if (!descriptorPath || !trustRootPath)
149
+ throw new Error(
150
+ "evolution deployment requires both descriptor and trust root",
151
+ );
152
+ if (!isAbsolute(descriptorPath) || !isAbsolute(trustRootPath))
153
+ throw new Error("evolution deployment paths must be absolute");
154
+
155
+ const [descriptorBytes, trustRootBytes] = await Promise.all([
156
+ read(await resolveRealPath(descriptorPath)),
157
+ read(await resolveRealPath(trustRootPath)),
158
+ ]);
159
+ const descriptor = normalizeDescriptor(parseJson(descriptorBytes));
160
+ if (sha256(trustRootBytes) !== descriptor.trustRootDigest)
161
+ throw new Error("evolution deployment trust root digest mismatch");
162
+ let publicKey;
163
+ try {
164
+ publicKey = createPublicKey(trustRootBytes);
165
+ } catch {
166
+ throw new Error("evolution deployment trust root is invalid");
167
+ }
168
+ const payload = serializeEvolutionDeploymentDescriptorPayload(descriptor);
169
+ if (
170
+ !verify(
171
+ null,
172
+ Buffer.from(payload, "utf8"),
173
+ publicKey,
174
+ Buffer.from(descriptor.signature, "base64"),
175
+ )
176
+ )
177
+ throw new Error("evolution deployment descriptor signature rejected");
178
+ if (!descriptor.commands.includes(commandName)) return null;
179
+
180
+ const modulePath = await resolveRealPath(descriptor.modulePath);
181
+ const moduleBytes = await read(modulePath);
182
+ if (moduleBytes.byteLength === 0 || moduleBytes.byteLength > 4 * 1024 * 1024)
183
+ throw new Error("evolution deployment module size is invalid");
184
+ if (sha256(moduleBytes) !== descriptor.moduleDigest)
185
+ throw new Error("evolution deployment module digest mismatch");
186
+ // Import the exact bytes that were authenticated. Importing modulePath here
187
+ // would reopen a pathname-replacement window between hashing and execution.
188
+ // Deployment entrypoints are therefore single-file ESM bundles; any external
189
+ // authority adapters they open remain the deployment's own attested boundary.
190
+ const moduleUrl = `data:text/javascript;base64,${Buffer.from(
191
+ moduleBytes,
192
+ ).toString("base64")}#${encodeURIComponent(descriptor.moduleDigest)}`;
193
+ const loaded = await importModule(moduleUrl);
194
+ if (typeof loaded?.createChainlessChainCommandDependencies !== "function")
195
+ throw new Error(
196
+ "evolution deployment module must export createChainlessChainCommandDependencies",
197
+ );
198
+ return dependencies(
199
+ await loaded.createChainlessChainCommandDependencies(
200
+ Object.freeze({
201
+ commandName,
202
+ descriptor: Object.freeze({ ...descriptor }),
203
+ factories: await loadBuiltInFactories(commandName),
204
+ }),
205
+ ),
206
+ commandName,
207
+ );
208
+ }
@@ -0,0 +1,335 @@
1
+ import { createHash } from "node:crypto";
2
+
3
+ import {
4
+ EVOLUTION_DURABLE_ARTIFACT_RECORD_SCHEMA,
5
+ isEvolutionLedgerArtifactResolver,
6
+ } from "./evolution-artifact-ports.js";
7
+ import {
8
+ EVOLUTION_ARTIFACT_RESOLUTION_SCHEMA,
9
+ EVOLUTION_LEDGER_DOMAIN_EVENT_SCHEMA,
10
+ } from "./evolution-ledger.js";
11
+ import {
12
+ createEvolutionReleaseTrainStateStore,
13
+ verifyEvolutionReleaseTrainState,
14
+ verifyEvolutionTrainStageReceipt,
15
+ } from "./evolution-release-train.js";
16
+
17
+ export const EVOLUTION_RELEASE_TRAIN_CHECKPOINT_SCHEMA =
18
+ "chainlesschain.evolution-release-train-checkpoint/v1";
19
+ export const EVOLUTION_RELEASE_TRAIN_LEDGER_EVENT =
20
+ "evolution.release-train.checkpoint.committed";
21
+
22
+ const DIGEST = /^sha256:[a-f0-9]{64}$/u;
23
+
24
+ function canonical(value) {
25
+ if (value === null || typeof value !== "object") return JSON.stringify(value);
26
+ if (Array.isArray(value)) return `[${value.map(canonical).join(",")}]`;
27
+ return `{${Object.keys(value)
28
+ .sort()
29
+ .map((key) => `${JSON.stringify(key)}:${canonical(value[key])}`)
30
+ .join(",")}}`;
31
+ }
32
+
33
+ function hash(value) {
34
+ return `sha256:${createHash("sha256")
35
+ .update(EVOLUTION_RELEASE_TRAIN_CHECKPOINT_SCHEMA)
36
+ .update("\0")
37
+ .update(canonical(value))
38
+ .digest("hex")}`;
39
+ }
40
+
41
+ function text(value, name) {
42
+ if (typeof value !== "string" || value.trim() === "")
43
+ throw new TypeError(`${name} is required`);
44
+ return value;
45
+ }
46
+
47
+ function capture(owner, method, name) {
48
+ if (!owner || typeof owner[method] !== "function")
49
+ throw new TypeError(`${name}.${method}() is required`);
50
+ return (...args) => Reflect.apply(owner[method], owner, args);
51
+ }
52
+
53
+ function verifyCheckpoint(value, descriptor) {
54
+ if (
55
+ value?.schema !== EVOLUTION_RELEASE_TRAIN_CHECKPOINT_SCHEMA ||
56
+ value.tenantId !== descriptor.tenantId ||
57
+ value.skillName !== descriptor.skillName ||
58
+ !DIGEST.test(value.planDigest ?? "") ||
59
+ (value.priorStateDigest !== null &&
60
+ !DIGEST.test(value.priorStateDigest ?? "")) ||
61
+ !DIGEST.test(value.checkpointDigest ?? "")
62
+ )
63
+ throw new Error("release train checkpoint is invalid");
64
+ const state = verifyEvolutionReleaseTrainState(value.state, {
65
+ planDigest: value.planDigest,
66
+ });
67
+ const receipt = verifyEvolutionTrainStageReceipt(value.receipt);
68
+ if (
69
+ receipt.planDigest !== value.planDigest ||
70
+ state.receiptDigests.at(-1) !== receipt.receiptDigest ||
71
+ state.outputDigests.at(-1) !== receipt.outputDigest
72
+ )
73
+ throw new Error("release train checkpoint receipt binding is invalid");
74
+ const core = structuredClone(value);
75
+ delete core.checkpointDigest;
76
+ if (hash(core) !== value.checkpointDigest)
77
+ throw new Error("release train checkpoint digest mismatch");
78
+ return Object.freeze(structuredClone(value));
79
+ }
80
+
81
+ export class EvolutionReleaseTrainLedgerAdapter {
82
+ constructor({
83
+ descriptor: input,
84
+ artifactPorts,
85
+ ledger,
86
+ ledgerArtifactResolver,
87
+ clock = () => new Date().toISOString(),
88
+ } = {}) {
89
+ this.descriptor = Object.freeze({
90
+ tenantId: text(input?.tenantId, "tenantId"),
91
+ artifactTenantId: text(input?.artifactTenantId, "artifactTenantId"),
92
+ skillName: text(input?.skillName, "skillName"),
93
+ audience: text(input?.audience, "audience"),
94
+ purpose: text(input?.purpose, "purpose"),
95
+ });
96
+ if (this.descriptor.purpose !== "evolution-ledger")
97
+ throw new TypeError(
98
+ "release train adapter purpose must be evolution-ledger",
99
+ );
100
+ this._putCanonical = capture(
101
+ artifactPorts,
102
+ "putCanonical",
103
+ "artifactPorts",
104
+ );
105
+ this._readLedger = capture(ledger, "read", "ledger");
106
+ this._verifyLedger = capture(ledger, "verify", "ledger");
107
+ this._appendDomainEvent = capture(ledger, "appendDomainEvent", "ledger");
108
+ if (!isEvolutionLedgerArtifactResolver(ledgerArtifactResolver))
109
+ throw new TypeError(
110
+ "a branded EvolutionArtifactPorts ledger resolver is required",
111
+ );
112
+ this._resolveArtifact = ledgerArtifactResolver;
113
+ if (typeof clock !== "function") throw new TypeError("clock is required");
114
+ this._clock = clock;
115
+ }
116
+
117
+ _events(planDigest) {
118
+ if (!DIGEST.test(planDigest ?? ""))
119
+ throw new TypeError("planDigest is invalid");
120
+ const events = this._readLedger();
121
+ if (!Array.isArray(events))
122
+ throw new Error("release train ledger read is invalid");
123
+ const selected = events.filter(
124
+ (event) =>
125
+ event.schema === EVOLUTION_LEDGER_DOMAIN_EVENT_SCHEMA &&
126
+ event.type === EVOLUTION_RELEASE_TRAIN_LEDGER_EVENT &&
127
+ event.tenantId === this.descriptor.tenantId &&
128
+ event.skillName === this.descriptor.skillName &&
129
+ event.correlationId === planDigest,
130
+ );
131
+ for (let index = 1; index < selected.length; index += 1) {
132
+ if (selected[index].sequence <= selected[index - 1].sequence)
133
+ throw new Error("release train ledger order is invalid");
134
+ }
135
+ return selected;
136
+ }
137
+
138
+ _resolve(event) {
139
+ const authority = this._verifyLedger();
140
+ const resolution = this._resolveArtifact({
141
+ epoch: authority.epoch,
142
+ ledgerId: authority.ledgerId,
143
+ ref: event.subjectRef,
144
+ tenantId: this.descriptor.artifactTenantId,
145
+ });
146
+ if (
147
+ resolution?.schema !== EVOLUTION_ARTIFACT_RESOLUTION_SCHEMA ||
148
+ resolution.authenticated !== true ||
149
+ resolution.found !== true ||
150
+ resolution.ref !== event.subjectRef.ref ||
151
+ resolution.digest !== event.subjectRef.digest ||
152
+ !Buffer.isBuffer(resolution.bytes)
153
+ )
154
+ throw new Error("release train checkpoint resolution is invalid");
155
+ let record;
156
+ try {
157
+ record = JSON.parse(resolution.bytes.toString("utf8"));
158
+ } catch {
159
+ throw new Error("release train checkpoint is not canonical JSON");
160
+ }
161
+ if (
162
+ record?.schema !== EVOLUTION_DURABLE_ARTIFACT_RECORD_SCHEMA ||
163
+ record.tenantId !== this.descriptor.artifactTenantId ||
164
+ record.audience !== this.descriptor.audience ||
165
+ record.purpose !== this.descriptor.purpose ||
166
+ record.retention !== "ledger" ||
167
+ record.type !== "evolution-release-train-checkpoint"
168
+ )
169
+ throw new Error("release train durable artifact binding is invalid");
170
+ return verifyCheckpoint(record.value, this.descriptor);
171
+ }
172
+
173
+ _chain(planDigest) {
174
+ const events = this._events(planDigest);
175
+ const chain = [];
176
+ let priorStateDigest = null;
177
+ let priorSubjectRef = null;
178
+ for (const event of events) {
179
+ const checkpoint = this._resolve(event);
180
+ if (
181
+ checkpoint.priorStateDigest !== priorStateDigest ||
182
+ checkpoint.state.stageIndex !== chain.length + 1 ||
183
+ (priorSubjectRef !== null &&
184
+ !event.sourceRefs.some(
185
+ (ref) =>
186
+ ref.ref === priorSubjectRef.ref &&
187
+ ref.digest === priorSubjectRef.digest,
188
+ ))
189
+ )
190
+ throw new Error("release train checkpoint lineage is discontinuous");
191
+ chain.push({ event, checkpoint });
192
+ priorStateDigest = checkpoint.state.stateDigest;
193
+ priorSubjectRef = event.subjectRef;
194
+ }
195
+ return chain;
196
+ }
197
+
198
+ createStateStore() {
199
+ return createEvolutionReleaseTrainStateStore({
200
+ load: async (planDigest) =>
201
+ this._chain(planDigest).at(-1)?.checkpoint.state ?? null,
202
+ loadReceipt: async (receiptDigest) => {
203
+ if (!DIGEST.test(receiptDigest ?? ""))
204
+ throw new TypeError("receiptDigest is invalid");
205
+ for (const event of this._readLedger()) {
206
+ if (
207
+ event.schema !== EVOLUTION_LEDGER_DOMAIN_EVENT_SCHEMA ||
208
+ event.type !== EVOLUTION_RELEASE_TRAIN_LEDGER_EVENT ||
209
+ event.tenantId !== this.descriptor.tenantId ||
210
+ event.skillName !== this.descriptor.skillName
211
+ )
212
+ continue;
213
+ const checkpoint = this._resolve(event);
214
+ if (checkpoint.receipt.receiptDigest === receiptDigest)
215
+ return checkpoint.receipt;
216
+ }
217
+ return null;
218
+ },
219
+ compareAndSet: async (request) => this._compareAndSet(request),
220
+ });
221
+ }
222
+
223
+ _compareAndSet({
224
+ planDigest,
225
+ expectedStateDigest,
226
+ receipt: receiptInput,
227
+ nextState: stateInput,
228
+ } = {}) {
229
+ if (!DIGEST.test(planDigest ?? ""))
230
+ throw new TypeError("planDigest is invalid");
231
+ const receipt = verifyEvolutionTrainStageReceipt(receiptInput);
232
+ const nextState = verifyEvolutionReleaseTrainState(stateInput, {
233
+ planDigest,
234
+ });
235
+ if (
236
+ receipt.planDigest !== planDigest ||
237
+ nextState.receiptDigests.at(-1) !== receipt.receiptDigest ||
238
+ nextState.outputDigests.at(-1) !== receipt.outputDigest
239
+ )
240
+ throw new Error("release train CAS receipt binding is invalid");
241
+ const chain = this._chain(planDigest);
242
+ const latest = chain.at(-1) ?? null;
243
+ const currentStateDigest = latest?.checkpoint.state.stateDigest ?? null;
244
+ if (currentStateDigest !== expectedStateDigest) {
245
+ if (
246
+ currentStateDigest === nextState.stateDigest &&
247
+ latest?.checkpoint.receipt.receiptDigest === receipt.receiptDigest
248
+ )
249
+ return Object.freeze({
250
+ durable: true,
251
+ recovered: true,
252
+ stateDigest: nextState.stateDigest,
253
+ receiptDigest: receipt.receiptDigest,
254
+ });
255
+ throw new Error("release train checkpoint CAS conflict");
256
+ }
257
+ if (
258
+ nextState.stageIndex !== chain.length + 1 ||
259
+ nextState.receiptDigests.length !== nextState.stageIndex
260
+ )
261
+ throw new Error("release train checkpoint progression is invalid");
262
+ const checkpointCore = {
263
+ schema: EVOLUTION_RELEASE_TRAIN_CHECKPOINT_SCHEMA,
264
+ tenantId: this.descriptor.tenantId,
265
+ skillName: this.descriptor.skillName,
266
+ planDigest,
267
+ priorStateDigest: currentStateDigest,
268
+ state: nextState,
269
+ receipt,
270
+ };
271
+ const checkpoint = Object.freeze({
272
+ ...checkpointCore,
273
+ checkpointDigest: hash(checkpointCore),
274
+ });
275
+ const head = this._verifyLedger();
276
+ const published = this._putCanonical(
277
+ "evolution-release-train-checkpoint",
278
+ checkpoint,
279
+ {
280
+ audience: this.descriptor.audience,
281
+ purpose: this.descriptor.purpose,
282
+ retention: "ledger",
283
+ },
284
+ );
285
+ if (
286
+ !published?.ref ||
287
+ published.receipt?.persisted !== true ||
288
+ published.receipt?.readbackVerified !== true ||
289
+ published.receipt?.integrityVerified !== true ||
290
+ published.receipt?.retention !== "ledger"
291
+ )
292
+ throw new Error("release train checkpoint was not durably read back");
293
+ const timestamp = this._clock();
294
+ if (
295
+ typeof timestamp !== "string" ||
296
+ !Number.isFinite(Date.parse(timestamp))
297
+ )
298
+ throw new Error("release train checkpoint clock is invalid");
299
+ const eventId = `release-train.${checkpoint.checkpointDigest.slice("sha256:".length)}`;
300
+ const ledgerReceipt = this._appendDomainEvent(
301
+ {
302
+ artifactTenantId: this.descriptor.artifactTenantId,
303
+ correlationId: planDigest,
304
+ decision: "committed",
305
+ eventId,
306
+ reason: `${receipt.stage} checkpoint committed`,
307
+ skillName: this.descriptor.skillName,
308
+ sourceRefs: latest ? [latest.event.subjectRef] : [],
309
+ subjectRef: published.ref,
310
+ tenantId: this.descriptor.tenantId,
311
+ timestamp,
312
+ type: EVOLUTION_RELEASE_TRAIN_LEDGER_EVENT,
313
+ },
314
+ { expectedHeadDigest: head.headDigest, expectedSequence: head.sequence },
315
+ );
316
+ if (
317
+ ledgerReceipt?.authenticated !== true ||
318
+ ledgerReceipt.committed !== true ||
319
+ ledgerReceipt.durable !== true ||
320
+ ledgerReceipt.eventId !== eventId ||
321
+ !DIGEST.test(ledgerReceipt.receiptDigest ?? "")
322
+ )
323
+ throw new Error("release train checkpoint ledger append was not durable");
324
+ const stored = this._chain(planDigest).at(-1)?.checkpoint;
325
+ if (stored?.checkpointDigest !== checkpoint.checkpointDigest)
326
+ throw new Error("release train checkpoint readback differs after commit");
327
+ return Object.freeze({
328
+ durable: true,
329
+ recovered: false,
330
+ stateDigest: nextState.stateDigest,
331
+ receiptDigest: receipt.receiptDigest,
332
+ ledgerReceiptDigest: ledgerReceipt.receiptDigest,
333
+ });
334
+ }
335
+ }