chainlesschain 0.166.21 → 0.166.24

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 (301) hide show
  1. package/README.md +67 -9
  2. package/package.json +4 -3
  3. package/src/assets/web-panel/assets/{AIOps-BjMnsUci.js → AIOps-DR-MWcZc.js} +1 -1
  4. package/src/assets/web-panel/assets/{ActionButton-DdYFP03A.js → ActionButton-DT8B7sEb.js} +1 -1
  5. package/src/assets/web-panel/assets/{Analytics-Bb8TuuK_.js → Analytics-asjh3dQJ.js} +3 -3
  6. package/src/assets/web-panel/assets/{AppLayout-Kn3TIOtk.js → AppLayout-DivQ491i.js} +5 -5
  7. package/src/assets/web-panel/assets/{Artifacts-4IxpqI_b.js → Artifacts-DPH2uUmy.js} +1 -1
  8. package/src/assets/web-panel/assets/{Audit-BOV2caqU.js → Audit-Bp2nLyc-.js} +1 -1
  9. package/src/assets/web-panel/assets/{BackgroundAgents-B86k-ay4.js → BackgroundAgents-CHS28khl.js} +1 -1
  10. package/src/assets/web-panel/assets/{Backup-C5_ie1e3.js → Backup-CKeaFSfz.js} +1 -1
  11. package/src/assets/web-panel/assets/{BaseInput-xpwg6QCW.js → BaseInput-CxwM9BAH.js} +1 -1
  12. package/src/assets/web-panel/assets/{Chat-CVZOcZau.js → Chat-DYLDwaCv.js} +4 -4
  13. package/src/assets/web-panel/assets/{ChatBubbleRenderer-D8fPYhUu.js → ChatBubbleRenderer-DdBJDBP0.js} +1 -1
  14. package/src/assets/web-panel/assets/{Checkbox-MKTq3zdP.js → Checkbox-uYTWOB8j.js} +1 -1
  15. package/src/assets/web-panel/assets/{Codegen-JUk3wzep.js → Codegen-CvYa_dwT.js} +1 -1
  16. package/src/assets/web-panel/assets/{Col-JPvTA0kC.js → Col-CanMAX4m.js} +1 -1
  17. package/src/assets/web-panel/assets/{Community-Tqgl87NQ.js → Community-B4WaDtHw.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compact-BuAFYBmN.js → Compact-K93Uof_3.js} +1 -1
  19. package/src/assets/web-panel/assets/{Compliance-CXS9WIPZ.js → Compliance-CKeDLgUW.js} +1 -1
  20. package/src/assets/web-panel/assets/{Cowork-Ds2bFHrr.js → Cowork-P93grAeB.js} +3 -3
  21. package/src/assets/web-panel/assets/{Cron-C_dV_OeW.js → Cron-BSHnMtDn.js} +2 -2
  22. package/src/assets/web-panel/assets/{Crosschain-BsO6tIRo.js → Crosschain-epAOpUVJ.js} +1 -1
  23. package/src/assets/web-panel/assets/{DID-rNOFqBac.js → DID-ByjXfP7t.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dashboard-C2fcKKVY.js → Dashboard-QztTU8tb.js} +2 -2
  25. package/src/assets/web-panel/assets/{Dropdown-Y7Ndr0X_.js → Dropdown-DhUc9yhN.js} +1 -1
  26. package/src/assets/web-panel/assets/{EmailListRenderer-DcP_uPmL.js → EmailListRenderer-C2sLhJJN.js} +1 -1
  27. package/src/assets/web-panel/assets/{FamilyGuardDashboard-Cwn3gDzk.js → FamilyGuardDashboard-CdfbWNDn.js} +1 -1
  28. package/src/assets/web-panel/assets/{Federation-ClQuOsqb.js → Federation-CcF_R7NW.js} +1 -1
  29. package/src/assets/web-panel/assets/{FormItemContext-DfwtmlcK.js → FormItemContext-Cm_X2IBk.js} +1 -1
  30. package/src/assets/web-panel/assets/{GenericCardRenderer-zNZhtbC5.js → GenericCardRenderer-DUi4NWlb.js} +1 -1
  31. package/src/assets/web-panel/assets/{Git-BZmdW-G5.js → Git-4Sq5FjBt.js} +2 -2
  32. package/src/assets/web-panel/assets/{Governance-CqBk4lEn.js → Governance-Dx2_v4V6.js} +1 -1
  33. package/src/assets/web-panel/assets/{Inference-Dbmt3ZXk.js → Inference-7Vr1xekR.js} +1 -1
  34. package/src/assets/web-panel/assets/{KnowledgeGraph-hMTH6qf3.js → KnowledgeGraph-Cnd2XOzf.js} +1 -1
  35. package/src/assets/web-panel/assets/{Logs-CkiYgiW2.js → Logs-B66QPVf-.js} +2 -2
  36. package/src/assets/web-panel/assets/{MarkdownRenderer-BL1FElXg.js → MarkdownRenderer-PLsEvhly.js} +1 -1
  37. package/src/assets/web-panel/assets/{Marketplace-CbB6wfin.js → Marketplace-BMIK9BmC.js} +1 -1
  38. package/src/assets/web-panel/assets/{McpTools-BSwiFtte.js → McpTools-BDbyp3J_.js} +3 -3
  39. package/src/assets/web-panel/assets/{Memory-B03PeHrz.js → Memory-CJdzfZGi.js} +2 -2
  40. package/src/assets/web-panel/assets/{MobileBridge-CRGrnd-X.js → MobileBridge-C2TH5Y3-.js} +1 -1
  41. package/src/assets/web-panel/assets/{MobileProjects-CE_5v2kO.js → MobileProjects-D1dYXkvV.js} +1 -1
  42. package/src/assets/web-panel/assets/{Mtc-Dp11QVx1.js → Mtc-B-4A1I1j.js} +4 -4
  43. package/src/assets/web-panel/assets/{MtcAudit-CYu-3JBu.js → MtcAudit-Bgcc9UOl.js} +5 -5
  44. package/src/assets/web-panel/assets/{Multisig-CGyJ0Xl3.js → Multisig-DqOe-etP.js} +3 -3
  45. package/src/assets/web-panel/assets/{NLProgramming-CoWi_ov1.js → NLProgramming-7VnhzE_6.js} +1 -1
  46. package/src/assets/web-panel/assets/Notes-BxawpeUQ.js +7 -0
  47. package/src/assets/web-panel/assets/{NotificationSettings-DX4I2b4W.js → NotificationSettings-Cr08G2aE.js} +1 -1
  48. package/src/assets/web-panel/assets/OrderTableRenderer-Ce8bEGlK.js +1 -0
  49. package/src/assets/web-panel/assets/{Organization-oopLO_tk.js → Organization-BC7lveGv.js} +4 -4
  50. package/src/assets/web-panel/assets/{Overflow-BFVvjMyf.js → Overflow-CakOW-G0.js} +1 -1
  51. package/src/assets/web-panel/assets/{P2P-CBy5t-Tk.js → P2P-Cf8CaOBZ.js} +2 -2
  52. package/src/assets/web-panel/assets/{PdhVaultBrowser--YWJNsu6.js → PdhVaultBrowser-Dc7b98W9.js} +3 -3
  53. package/src/assets/web-panel/assets/{Permissions-C2dZ8scb.js → Permissions-DGJyMEfS.js} +4 -4
  54. package/src/assets/web-panel/assets/{PersonalDataHub-Bs3l7Hlx.js → PersonalDataHub-DNIwSdwu.js} +6 -6
  55. package/src/assets/web-panel/assets/{Pipeline-DEBWbZuD.js → Pipeline-5B1S12wa.js} +1 -1
  56. package/src/assets/web-panel/assets/{Privacy-CjHBb6NU.js → Privacy-CMB6Ke5t.js} +1 -1
  57. package/src/assets/web-panel/assets/{ProjectInit-D2WipUz5.js → ProjectInit-D5PqTFiT.js} +2 -2
  58. package/src/assets/web-panel/assets/{ProjectSettings-B6WfnrGB.js → ProjectSettings-CbKNdSjV.js} +2 -2
  59. package/src/assets/web-panel/assets/Projects-ccXaHzYL.js +1 -0
  60. package/src/assets/web-panel/assets/{Providers-CCv5M_Dv.js → Providers-CJF5_-Gs.js} +1 -1
  61. package/src/assets/web-panel/assets/{QrScannerModal-CGthxU54.js → QrScannerModal-CT6iEAdi.js} +1 -1
  62. package/src/assets/web-panel/assets/{QuickAsk-CnPmXPFb.js → QuickAsk-Ci0h9mJ_.js} +1 -1
  63. package/src/assets/web-panel/assets/{Recommend-Df_tGEa9.js → Recommend-Da5mobZu.js} +1 -1
  64. package/src/assets/web-panel/assets/{RemoteSession-Z58N0Loe.js → RemoteSession-BaCY8eey.js} +2 -2
  65. package/src/assets/web-panel/assets/{Reputation-CZTBQ2Vt.js → Reputation-CaITfTsI.js} +1 -1
  66. package/src/assets/web-panel/assets/{Row-CdK3YpCQ.js → Row-DtUDamyP.js} +1 -1
  67. package/src/assets/web-panel/assets/{RssFeed-CFMVT5sb.js → RssFeed-DX27gFpg.js} +3 -3
  68. package/src/assets/web-panel/assets/{Search-DrF8RIvD.js → Search-DFL69osN.js} +1 -1
  69. package/src/assets/web-panel/assets/{Security-Ddk2f2DM.js → Security-BqGeoWv-.js} +3 -3
  70. package/src/assets/web-panel/assets/{Services-CCuK-VOo.js → Services-3z1WnEAc.js} +2 -2
  71. package/src/assets/web-panel/assets/{Skeleton-DxCpHzeM.js → Skeleton-C_OJQQ9Z.js} +1 -1
  72. package/src/assets/web-panel/assets/{Skills-t2oTDgcv.js → Skills-BY7aT6Mo.js} +1 -1
  73. package/src/assets/web-panel/assets/{Sla-Df63M9_R.js → Sla-BZv7DSaD.js} +1 -1
  74. package/src/assets/web-panel/assets/SpeechSettings-6lJKLhCn.js +1 -0
  75. package/src/assets/web-panel/assets/{SyncSettings-COd_tgPp.js → SyncSettings-B6D7STlI.js} +2 -2
  76. package/src/assets/web-panel/assets/{Tasks-CzDCcrik.js → Tasks-Co_FCZAO.js} +1 -1
  77. package/src/assets/web-panel/assets/{Templates-D-vfxTGA.js → Templates-CnY-9fgz.js} +1 -1
  78. package/src/assets/web-panel/assets/{Tenant-BlpT_Gxc.js → Tenant-B71yXfZ8.js} +1 -1
  79. package/src/assets/web-panel/assets/{Terminal-D5rq52Hg.js → Terminal-Dd_P7awo.js} +2 -2
  80. package/src/assets/web-panel/assets/{TimelineRenderer-DdoMndkK.js → TimelineRenderer-CvIEMyli.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tokens-BhgBsI6g.js → Tokens-DknFBGOi.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trigger-DwwzoikZ.js → Trigger-D_4nJONB.js} +1 -1
  83. package/src/assets/web-panel/assets/{Trust-HkTpzXFb.js → Trust-BNl21fa7.js} +1 -1
  84. package/src/assets/web-panel/assets/{UkeySign-D9nk6Ehe.js → UkeySign-CFrCI7uK.js} +1 -1
  85. package/src/assets/web-panel/assets/{VideoEditing-BKk0rfoy.js → VideoEditing-BVfY6JLg.js} +1 -1
  86. package/src/assets/web-panel/assets/{Wallet-IVWIU_Lq.js → Wallet-Cj9CAK0J.js} +4 -4
  87. package/src/assets/web-panel/assets/{WebAuthn-CFTCpfsG.js → WebAuthn-DcqZlzA3.js} +4 -4
  88. package/src/assets/web-panel/assets/{WorkflowEditor-Dnf4Obif.js → WorkflowEditor-Dfr_dMld.js} +1 -1
  89. package/src/assets/web-panel/assets/{chat-D2snERdj.js → chat-Yv6UF0AD.js} +1 -1
  90. package/src/assets/web-panel/assets/{colors-DKEjK1N1.js → colors-CDW_-1fs.js} +1 -1
  91. package/src/assets/web-panel/assets/{compact-item-BEDLwQdt.js → compact-item-BYOQvd-6.js} +1 -1
  92. package/src/assets/web-panel/assets/{createContext-DA9iW1a0.js → createContext-BCGO0BiP.js} +1 -1
  93. package/src/assets/web-panel/assets/devWarning-H-kXSuf-.js +1 -0
  94. package/src/assets/web-panel/assets/{hasIn-5l2xEcY9.js → hasIn-DY-70cfQ.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-B7_W_rYd.js → index-366wfQBU.js} +1 -1
  96. package/src/assets/web-panel/assets/index-B0o4MeNK.js +1 -0
  97. package/src/assets/web-panel/assets/{index-CxEtQYdi.js → index-B9ZogJJM.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-B00GeekA.js → index-B9m5QAMg.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-C7sKbM5s.js → index-BBs2mv5M.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-CX1x4AFn.js → index-BFv1hzF6.js} +1 -1
  101. package/src/assets/web-panel/assets/index-BVafOL_I.js +1 -0
  102. package/src/assets/web-panel/assets/{index-DU2TXJu-.js → index-BXlEx4UH.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-e-e40id6.js → index-BayRTE5w.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-DXet1xol.js → index-Bb9nyts1.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-D7z4zB_a.js → index-Bf_Va0S-.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-fccZmC_h.js → index-Br3wQLVY.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-Bqc8tdIF.js → index-BvK4fjkk.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-BO9dQjpt.js → index-C40UdtlS.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-Csfb-7hw.js → index-C4UJA2ju.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-Td8ZwyoC.js → index-CB_Iw73G.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-BZ5lY2zx.js → index-CCwWp3mT.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-DpqtbXdE.js → index-CFa2fPCk.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-NJieh3T1.js → index-CIyHxV4u.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-Dbkghqn_.js → index-CUP-A2_h.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-DqwPFbOb.js → index-CUo27q9J.js} +3 -3
  116. package/src/assets/web-panel/assets/{index-B4QYBliR.js → index-CaT8trvf.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-BgfImyZI.js → index-CnZNbcux.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-Dbd7eEex.js → index-Cy2NE6AO.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-CbTPvp2_.js → index-CzeEEazr.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-5pW4t1iD.js → index-D--TEyDj.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-Dg2a9owQ.js → index-DCtsjhhT.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-B_eCoZgW.js → index-DLOf7BSz.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-7P1b8HZo.js → index-DM5c4pc-.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-CRPrHE7h.js → index-DRFC2Qt0.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-Bq5P3piS.js → index-DT_qVaaV.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-CjWltbi_.js → index-DUDoRk9r.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-CkMKuqUs.js → index-Dg-AQYDf.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-DLoalqRX.js → index-DuIPq5MX.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-CGlotREA.js → index-NYVBUAVN.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-yYEQXYaU.js → index-NaCESahy.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-CmruhzFi.js → index-RjIMPG0u.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-fgYk0QXO.js → index-Y9akzgFO.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-DvV03Ayk.js → index-hZ0Eyrrw.js} +1 -1
  134. package/src/assets/web-panel/assets/{initDefaultProps-CPrcB1TC.js → initDefaultProps-CG99CcR4.js} +1 -1
  135. package/src/assets/web-panel/assets/{motion-BQ7mWRh_.js → motion-Z7MH0_0G.js} +1 -1
  136. package/src/assets/web-panel/assets/{move-CzOEq99p.js → move-BX67lOdq.js} +1 -1
  137. package/src/assets/web-panel/assets/{mtc-parser-BlQI5jrw.js → mtc-parser-CmAbG1fE.js} +1 -1
  138. package/src/assets/web-panel/assets/{omit-DlW4gxmv.js → omit-DiU5tI1_.js} +1 -1
  139. package/src/assets/web-panel/assets/{pickAttrs-BBYms5nP.js → pickAttrs-BGfvLrYL.js} +1 -1
  140. package/src/assets/web-panel/assets/{placementArrow-az2MPJ_7.js → placementArrow-CggLEgaJ.js} +1 -1
  141. package/src/assets/web-panel/assets/{responsiveObserve-D1-ibEol.js → responsiveObserve-t3nlghPZ.js} +1 -1
  142. package/src/assets/web-panel/assets/{slide-DHGqa4GA.js → slide-BkV4dL9s.js} +1 -1
  143. package/src/assets/web-panel/assets/{statusUtils-CYGDo6lD.js → statusUtils-qec1PUoC.js} +1 -1
  144. package/src/assets/web-panel/assets/{styleChecker-Cl2EM9K6.js → styleChecker-ChjX6T8D.js} +1 -1
  145. package/src/assets/web-panel/assets/{useFlexGapSupport-DdYhzuv1.js → useFlexGapSupport-B1jLoZcM.js} +1 -1
  146. package/src/assets/web-panel/assets/{useFs-DWumPuBW.js → useFs-C3X53s4E.js} +1 -1
  147. package/src/assets/web-panel/assets/{usePersonalDataHub-DxAO-Aqi.js → usePersonalDataHub-DOvbbnkZ.js} +1 -1
  148. package/src/assets/web-panel/assets/{vnode-CplsQf_N.js → vnode-Ie0TEVFT.js} +1 -1
  149. package/src/assets/web-panel/assets/{zoom-Cw5HXNSG.js → zoom-CRUMVS8l.js} +1 -1
  150. package/src/assets/web-panel/index.html +1 -1
  151. package/src/command-help-index.json +3 -3
  152. package/src/commands/agent.js +18 -1
  153. package/src/commands/evolution-benchmark.js +72 -0
  154. package/src/commands/evolution.js +2 -0
  155. package/src/commands/governed-skill-marketplace.js +142 -0
  156. package/src/commands/marketplace.js +4 -1
  157. package/src/commands/serve.js +41 -0
  158. package/src/commands/skill.js +3 -0
  159. package/src/data/changelog.json +39 -0
  160. package/src/gateways/ws/ws-agent-handler.js +59 -2
  161. package/src/gateways/ws/ws-server.js +2 -0
  162. package/src/harness/golden-transcript.js +1 -0
  163. package/src/harness/prompt-compressor.js +51 -5
  164. package/src/harness/provider-backed-compaction.js +28 -1
  165. package/src/harness/remote-session-registry.js +15 -3
  166. package/src/index.js +30 -4
  167. package/src/lazy-dispatch.js +15 -1
  168. package/src/lib/advisor-runtime.js +55 -2
  169. package/src/lib/app-server/cli-agent-kernel-adapter.js +4 -0
  170. package/src/lib/app-server/graph-runtime.js +32 -0
  171. package/src/lib/app-server/server.js +45 -1
  172. package/src/lib/app-server/websocket-transport.js +23 -0
  173. package/src/lib/autonomous-agent.js +63 -13
  174. package/src/lib/cowork/ab-comparator-cli.js +4 -3
  175. package/src/lib/cowork/debate-review-cli.js +4 -3
  176. package/src/lib/cowork/decision-kb-cli.js +5 -0
  177. package/src/lib/cowork-adapter.js +38 -16
  178. package/src/lib/evolution/agent-evolution-ingress.js +95 -15
  179. package/src/lib/evolution/agent-evolution-runtime-composition.js +82 -0
  180. package/src/lib/evolution/agent-evolution-session-lifecycle.js +46 -0
  181. package/src/lib/evolution/agent-model-projection.js +217 -0
  182. package/src/lib/evolution/bounded-descriptor-read.js +29 -0
  183. package/src/lib/evolution/controlled-skill-pilot-ledger-adapter.js +551 -0
  184. package/src/lib/evolution/controlled-skill-production-pilot.js +308 -18
  185. package/src/lib/evolution/evidence-backed-wiki-maintainer.js +10 -1
  186. package/src/lib/evolution/evidence-json-text.js +236 -0
  187. package/src/lib/evolution/evolution-artifact-ports.js +202 -21
  188. package/src/lib/evolution/evolution-deployment-loader.js +369 -0
  189. package/src/lib/evolution/evolution-eval-child-evidence-ledger-adapter.js +373 -0
  190. package/src/lib/evolution/evolution-eval-gate.js +14 -1
  191. package/src/lib/evolution/evolution-eval-process-supervisor-worker.mjs +14 -0
  192. package/src/lib/evolution/evolution-eval-process-supervisor.js +607 -0
  193. package/src/lib/evolution/evolution-evidence-artifact-adapter.js +14 -1
  194. package/src/lib/evolution/evolution-evidence-projector.js +240 -37
  195. package/src/lib/evolution/evolution-file-witness.js +153 -30
  196. package/src/lib/evolution/evolution-ledger-ports.js +1027 -66
  197. package/src/lib/evolution/evolution-ledger.js +66 -2
  198. package/src/lib/evolution/evolution-raw-crypto-shred.js +29 -15
  199. package/src/lib/evolution/evolution-raw-deletion-ledger-adapter.js +865 -0
  200. package/src/lib/evolution/evolution-release-train-domain-stages.js +769 -0
  201. package/src/lib/evolution/evolution-release-train-ledger-adapter.js +335 -0
  202. package/src/lib/evolution/evolution-release-train-stage-output-ledger-adapter.js +333 -0
  203. package/src/lib/evolution/evolution-release-train.js +586 -0
  204. package/src/lib/evolution/evolution-workbench-batch-executor.js +101 -144
  205. package/src/lib/evolution/evolution-workbench-control-ports.js +203 -0
  206. package/src/lib/evolution/evolution-workbench-file-resources.js +403 -0
  207. package/src/lib/evolution/evolution-workbench-projection.js +152 -25
  208. package/src/lib/evolution/evolution-workbench-registry-source.js +482 -0
  209. package/src/lib/evolution/evolution-workbench-review-ledger-adapter.js +823 -0
  210. package/src/lib/evolution/evolution-workbench-review-protocol.js +157 -0
  211. package/src/lib/evolution/evolution-workbench-rollback-authorization.js +57 -0
  212. package/src/lib/evolution/evolution-workbench-rollback-ledger-adapter.js +1016 -0
  213. package/src/lib/evolution/evolution-workbench-runtime.js +133 -0
  214. package/src/lib/evolution/evolution-workbench-version-control.js +70 -36
  215. package/src/lib/evolution/evolvable-artifact-ledger-adapter.js +736 -0
  216. package/src/lib/evolution/governed-knowledge-artifact-lifecycle.js +364 -0
  217. package/src/lib/evolution/governed-knowledge-candidate-rejection.js +343 -0
  218. package/src/lib/evolution/governed-knowledge-dependency-authority.js +227 -44
  219. package/src/lib/evolution/governed-knowledge-dependency-ledger-executor.js +95 -83
  220. package/src/lib/evolution/governed-knowledge-merge-ledger-executor.js +29 -2
  221. package/src/lib/evolution/governed-knowledge-merge-publisher-authority.js +31 -3
  222. package/src/lib/evolution/governed-knowledge-record.js +148 -0
  223. package/src/lib/evolution/governed-knowledge-revocation-record.js +135 -0
  224. package/src/lib/evolution/governed-knowledge-skill-rollback.js +475 -0
  225. package/src/lib/evolution/governed-knowledge-sync-ledger-adapter.js +92 -6
  226. package/src/lib/evolution/governed-knowledge-sync-merge-publisher.js +57 -4
  227. package/src/lib/evolution/governed-knowledge-sync.js +332 -99
  228. package/src/lib/evolution/governed-knowledge-wiki-tombstone.js +462 -0
  229. package/src/lib/evolution/governed-skill-marketplace-badge.js +208 -0
  230. package/src/lib/evolution/governed-skill-marketplace-candidate.js +330 -0
  231. package/src/lib/evolution/governed-skill-marketplace-cli-host.js +308 -0
  232. package/src/lib/evolution/governed-skill-marketplace-ledger-adapter.js +420 -0
  233. package/src/lib/evolution/governed-skill-marketplace.js +288 -5
  234. package/src/lib/evolution/governed-wiki-pruning-journal.js +302 -0
  235. package/src/lib/evolution/governed-wiki-pruning-ledger-adapter.js +459 -0
  236. package/src/lib/evolution/governed-wiki-pruning-maintenance.js +576 -0
  237. package/src/lib/evolution/governed-wiki-pruning-plan-authority.js +169 -0
  238. package/src/lib/evolution/governed-wiki-pruning-raw-shred.js +207 -0
  239. package/src/lib/evolution/governed-wiki-pruning-retrieval.js +587 -0
  240. package/src/lib/evolution/governed-wiki-pruning-runtime.js +153 -0
  241. package/src/lib/evolution/governed-wiki-pruning-skill-rollback.js +360 -0
  242. package/src/lib/evolution/governed-wiki-pruning.js +322 -143
  243. package/src/lib/evolution/independent-skill-revocation-source.js +231 -0
  244. package/src/lib/evolution/knowledge-wiki-source-admission.js +124 -0
  245. package/src/lib/evolution/knowledge-wiki-source-provenance.js +359 -0
  246. package/src/lib/evolution/progressive-canary-external-watchdog.js +578 -0
  247. package/src/lib/evolution/progressive-canary-traffic-worker.js +628 -0
  248. package/src/lib/evolution/progressive-canary-watchdog-file-store.js +285 -0
  249. package/src/lib/evolution/progressive-canary-watchdog-node-pki.js +265 -0
  250. package/src/lib/evolution/skill-candidate-registry.js +22 -0
  251. package/src/lib/evolution/skill-promotion-controller.js +25 -0
  252. package/src/lib/evolution/skill-promotion-review-ledger-adapter.js +100 -0
  253. package/src/lib/evolution/skill-registry-transition-ledger-adapter.js +131 -2
  254. package/src/lib/evolution/skill-release-registry.js +25 -4
  255. package/src/lib/evolution/skill-retrieval-revocation-authority.js +361 -0
  256. package/src/lib/evolution/skill-retrieval-revocation-ledger-adapter.js +346 -0
  257. package/src/lib/evolution/skill-revocation-propagation.js +467 -0
  258. package/src/lib/evolution/skill-target-matrix-eval.js +162 -11
  259. package/src/lib/evolution/skill-wiki-reconciliation.js +985 -0
  260. package/src/lib/evolution/skill-writer-inventory-manifest.js +15 -12
  261. package/src/lib/evolution/statistical-progressive-canary.js +845 -0
  262. package/src/lib/evolution/structured-memory-agent-control-plane.js +120 -0
  263. package/src/lib/evolution/structured-memory-authority-ledger-adapter.js +5 -1
  264. package/src/lib/evolution/structured-memory-promotion-receipt-writer.js +126 -0
  265. package/src/lib/evolution/wiki-informed-skill-proposer.js +127 -21
  266. package/src/lib/evolution/wiki-maintainer-ledger-adapter.js +760 -100
  267. package/src/lib/evolution/wiki-revision-protocol.js +120 -0
  268. package/src/lib/evolution/wiki-skill-proposal-ledger-adapter.js +307 -0
  269. package/src/lib/evolution/wiki-target-tombstone-revision.js +101 -0
  270. package/src/lib/evolution/wikiskill-benchmark-cli-host.js +178 -0
  271. package/src/lib/evolution/wikiskill-benchmark-execution-host.js +702 -0
  272. package/src/lib/evolution/wikiskill-benchmark-ledger-adapter.js +613 -0
  273. package/src/lib/evolution/wikiskill-benchmark.js +574 -0
  274. package/src/lib/goal-assess.js +17 -10
  275. package/src/lib/interactive-planner.js +9 -1
  276. package/src/lib/iteration-budget.js +16 -2
  277. package/src/lib/micro-compact.js +4 -1
  278. package/src/lib/model-failure-policy.js +21 -0
  279. package/src/lib/process-execution-broker/index.js +1 -0
  280. package/src/lib/process-execution-broker/windows-sandbox-helper.dll +0 -0
  281. package/src/lib/process-execution-broker/windows-sandbox-helper.exe +0 -0
  282. package/src/lib/process-execution-broker/windows-sandbox.cs +33 -15
  283. package/src/lib/read-file-page.js +191 -0
  284. package/src/lib/runnable-provider.js +2 -1
  285. package/src/lib/session-host-lease.js +11 -16
  286. package/src/lib/skill-retrieval-router.js +22 -1
  287. package/src/repl/agent-repl.js +127 -33
  288. package/src/runtime/agent-core.js +224 -80
  289. package/src/runtime/agent-runtime.js +43 -0
  290. package/src/runtime/coding-agent-contract-shared.cjs +7 -1
  291. package/src/runtime/fallback-model.js +143 -62
  292. package/src/runtime/headless-runner.js +54 -10
  293. package/src/runtime/headless-stream.js +53 -6
  294. package/src/runtime/runtime-factory.js +41 -2
  295. package/src/assets/web-panel/assets/Notes-CgU9DDo9.js +0 -7
  296. package/src/assets/web-panel/assets/OrderTableRenderer-CwHc15Zs.js +0 -1
  297. package/src/assets/web-panel/assets/Projects-FF_thRi6.js +0 -1
  298. package/src/assets/web-panel/assets/SpeechSettings-l7ox6KuX.js +0 -1
  299. package/src/assets/web-panel/assets/devWarning-DyhgpXPf.js +0 -1
  300. package/src/assets/web-panel/assets/index-Ck1jhFE0.js +0 -1
  301. package/src/assets/web-panel/assets/index-c8jJEHVs.js +0 -1
@@ -0,0 +1,403 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { types } from "node:util";
4
+ import { ArtifactStore } from "../artifact-store.js";
5
+ import { ensurePrivateDirectory } from "../secure-fs.js";
6
+ import { EvolutionArtifactPorts } from "./evolution-artifact-ports.js";
7
+ import { createEvolutionLedgerFileBackend } from "./evolution-ledger-file-backend.js";
8
+ import { createEvolutionLedgerPorts } from "./evolution-ledger-ports.js";
9
+ import { SkillReleaseRegistry } from "./skill-release-registry.js";
10
+ import { capturePruningData as capture } from "./governed-wiki-pruning-journal.js";
11
+
12
+ const ID = /^[A-Za-z0-9][A-Za-z0-9._:@/-]{0,255}$/u;
13
+ const DIGEST = /^sha256:[a-f0-9]{64}$/u;
14
+ const STORAGE_ID = /^[A-Za-z0-9][A-Za-z0-9._:/-]{0,255}$/u;
15
+ const FILE_RESOURCES = new WeakSet();
16
+
17
+ export function captureWorkbenchFileResources(value) {
18
+ if (!FILE_RESOURCES.has(value))
19
+ throw new TypeError("genuine Workbench file resources are required");
20
+ return value;
21
+ }
22
+ const DESCRIPTOR_KEYS = [
23
+ "tenantId",
24
+ "artifactTenantId",
25
+ "streamId",
26
+ "runId",
27
+ "skillName",
28
+ "audience",
29
+ "purpose",
30
+ "authorityId",
31
+ "revision",
32
+ "handlerArtifactDigest",
33
+ ];
34
+ const STORAGE_KEYS = [
35
+ "artifactDir",
36
+ "ledgerRootDir",
37
+ "ledgerAuthorityRootDir",
38
+ "witnessFilePath",
39
+ "witnessId",
40
+ "releaseRootDir",
41
+ ];
42
+
43
+ function record(
44
+ value,
45
+ required,
46
+ optional = [],
47
+ label = "Workbench file resources",
48
+ ) {
49
+ if (
50
+ !value ||
51
+ typeof value !== "object" ||
52
+ Array.isArray(value) ||
53
+ types.isProxy(value)
54
+ )
55
+ throw new TypeError(`${label} must be an explicit data record`);
56
+ const properties = Object.getOwnPropertyDescriptors(value);
57
+ const allowed = new Set([...required, ...optional]);
58
+ if (
59
+ required.some((key) => !Object.hasOwn(properties, key)) ||
60
+ Reflect.ownKeys(properties).some((key) => !allowed.has(key))
61
+ )
62
+ throw new TypeError(`${label} has missing or unsupported fields`);
63
+ const result = {};
64
+ for (const [key, property] of Object.entries(properties)) {
65
+ if (!Object.hasOwn(property, "value") || !property.enumerable)
66
+ throw new TypeError(`${label}.${key} must be an own data field`);
67
+ result[key] = property.value;
68
+ }
69
+ return result;
70
+ }
71
+
72
+ function fixed(owner, name, label) {
73
+ if (!owner || typeof owner !== "object" || types.isProxy(owner))
74
+ throw new TypeError(`${label}.${name} port is required`);
75
+ const fn = Object.getOwnPropertyDescriptor(owner, name)?.value;
76
+ if (typeof fn !== "function" || types.isProxy(fn))
77
+ throw new TypeError(`${label}.${name} must be a fixed own method`);
78
+ return Object.freeze(fn.bind(owner));
79
+ }
80
+
81
+ function signingAuthority(input, label) {
82
+ const value = record(input, ["trust", "signer", "verifier"], [], label);
83
+ const trust = capture(
84
+ record(
85
+ value.trust,
86
+ ["algorithm", "keyId", "trustPolicyDigest"],
87
+ [],
88
+ `${label}.trust`,
89
+ ),
90
+ );
91
+ if (
92
+ typeof trust.algorithm !== "string" ||
93
+ !/^[a-z0-9][a-z0-9._+-]{0,63}$/u.test(trust.algorithm) ||
94
+ typeof trust.keyId !== "string" ||
95
+ trust.keyId.length > 256 ||
96
+ !/^[a-z][a-z0-9+.-]{1,31}:[^\s\\]+$/u.test(trust.keyId) ||
97
+ !DIGEST.test(trust.trustPolicyDigest)
98
+ )
99
+ throw new TypeError(`${label} trust is invalid`);
100
+ return Object.freeze({
101
+ trust,
102
+ signer: Object.freeze({ sign: fixed(value.signer, "sign", label) }),
103
+ verifier: Object.freeze({ verify: fixed(value.verifier, "verify", label) }),
104
+ });
105
+ }
106
+
107
+ function normalizedPath(value, label) {
108
+ if (
109
+ typeof value !== "string" ||
110
+ !path.isAbsolute(value) ||
111
+ value.includes("\0")
112
+ )
113
+ throw new TypeError(`${label} must be an absolute path`);
114
+ const result = path.resolve(value);
115
+ if (result === path.parse(result).root)
116
+ throw new TypeError(`${label} must be a dedicated storage path`);
117
+ return result;
118
+ }
119
+
120
+ function contained(parent, child) {
121
+ const relative = path.relative(parent, child);
122
+ return (
123
+ relative === "" ||
124
+ (relative !== ".." &&
125
+ !relative.startsWith(`..${path.sep}`) &&
126
+ !path.isAbsolute(relative))
127
+ );
128
+ }
129
+
130
+ function assertNoAliases(io, target, directory = true) {
131
+ for (let current = target; ; current = path.dirname(current)) {
132
+ let stat;
133
+ try {
134
+ stat = io.lstatSync(current);
135
+ } catch (error) {
136
+ if (error.code !== "ENOENT") throw error;
137
+ }
138
+ if (stat) {
139
+ const actual = io.realpathSync(current);
140
+ if (stat.isSymbolicLink() || path.relative(actual, current) !== "")
141
+ throw new Error("Workbench storage aliases/symlinks are not allowed");
142
+ if (
143
+ current === target &&
144
+ (directory ? !stat.isDirectory() : !stat.isFile() || stat.nlink !== 1)
145
+ )
146
+ throw new Error(
147
+ "Workbench storage path has an invalid file type or link count",
148
+ );
149
+ if (current !== target && !stat.isDirectory())
150
+ throw new Error("Workbench storage ancestor is not a directory");
151
+ }
152
+ if (path.dirname(current) === current) break;
153
+ }
154
+ }
155
+
156
+ /**
157
+ * Opens real persistence, not a fixture or a permission authority. The caller
158
+ * still provides identity, human approval and mutation authority to the host.
159
+ * Returned writers are for the authenticated deployment module only, never RPC.
160
+ */
161
+ export function openEvolutionWorkbenchFileResources(input) {
162
+ const options = record(
163
+ input,
164
+ ["descriptor", "storage", "authorities"],
165
+ ["secure", "fsImpl", "now"],
166
+ );
167
+ const descriptor = capture(
168
+ record(options.descriptor, DESCRIPTOR_KEYS, [], "Workbench descriptor"),
169
+ );
170
+ for (const key of [
171
+ "tenantId",
172
+ "artifactTenantId",
173
+ "streamId",
174
+ "runId",
175
+ "skillName",
176
+ "audience",
177
+ "authorityId",
178
+ ])
179
+ if (typeof descriptor[key] !== "string" || !ID.test(descriptor[key]))
180
+ throw new TypeError(`Workbench ${key} is invalid`);
181
+ for (const key of ["artifactTenantId", "audience"])
182
+ if (!STORAGE_ID.test(descriptor[key]))
183
+ throw new TypeError(`Workbench storage ${key} is invalid`);
184
+ if (
185
+ descriptor.purpose !== "evolution-ledger" ||
186
+ !Number.isSafeInteger(descriptor.revision) ||
187
+ descriptor.revision < 1 ||
188
+ !DIGEST.test(descriptor.handlerArtifactDigest)
189
+ )
190
+ throw new TypeError(
191
+ "Workbench descriptor purpose/revision/handler digest is invalid",
192
+ );
193
+ const storage = record(
194
+ options.storage,
195
+ STORAGE_KEYS,
196
+ [],
197
+ "Workbench storage",
198
+ );
199
+ if (
200
+ typeof storage.witnessId !== "string" ||
201
+ !/^[A-Za-z0-9][A-Za-z0-9._:/-]{0,159}$/u.test(storage.witnessId)
202
+ )
203
+ throw new TypeError("Workbench witnessId is invalid");
204
+ for (const key of STORAGE_KEYS.filter((key) => key !== "witnessId"))
205
+ storage[key] = normalizedPath(storage[key], key);
206
+ const directories = [
207
+ storage.artifactDir,
208
+ storage.ledgerRootDir,
209
+ storage.ledgerAuthorityRootDir,
210
+ storage.releaseRootDir,
211
+ path.dirname(storage.witnessFilePath),
212
+ ];
213
+ for (let i = 0; i < directories.length; i++)
214
+ for (let j = i + 1; j < directories.length; j++)
215
+ if (
216
+ contained(directories[i], directories[j]) ||
217
+ contained(directories[j], directories[i])
218
+ )
219
+ throw new Error(
220
+ "Workbench artifact, Ledger, authority, witness and Registry storage must be non-overlapping",
221
+ );
222
+
223
+ const secure = options.secure === undefined ? true : options.secure;
224
+ if (typeof secure !== "boolean")
225
+ throw new TypeError("Workbench secure must be boolean");
226
+ const io = options.fsImpl ?? fs;
227
+ if (!io || typeof io !== "object" || types.isProxy(io))
228
+ throw new TypeError("Workbench filesystem is invalid");
229
+ const clock = options.now ?? Date.now;
230
+ if (typeof clock !== "function" || types.isProxy(clock))
231
+ throw new TypeError("Workbench clock must be a fixed function");
232
+ const now = Object.freeze(() => {
233
+ const value = Number(clock());
234
+ if (!Number.isFinite(value) || Math.abs(value) > 8_640_000_000_000_000)
235
+ throw new TypeError("Workbench clock is invalid");
236
+ return value;
237
+ });
238
+ now();
239
+ const authorities = record(
240
+ options.authorities,
241
+ ["artifact", "ledger", "witness", "releaseDurability"],
242
+ [],
243
+ "Workbench authorities",
244
+ );
245
+ const artifact = record(
246
+ authorities.artifact,
247
+ ["envelopeSigner", "envelopeVerifier", "currentAuthorityResolver"],
248
+ [],
249
+ "Workbench artifact authority",
250
+ );
251
+ const artifactAuthority = {
252
+ envelopeSigner: Object.freeze({
253
+ sign: fixed(artifact.envelopeSigner, "sign", "artifact"),
254
+ }),
255
+ envelopeVerifier: Object.freeze({
256
+ verify: fixed(artifact.envelopeVerifier, "verify", "artifact"),
257
+ }),
258
+ currentAuthorityResolver: Object.freeze({
259
+ resolve: fixed(artifact.currentAuthorityResolver, "resolve", "artifact"),
260
+ }),
261
+ };
262
+ const ledgerAuthority = signingAuthority(authorities.ledger, "ledger");
263
+ const witnessAuthority = signingAuthority(authorities.witness, "witness");
264
+ // Check original identities before capturing wrappers, which must not disguise
265
+ // use of the same authority for the event log and its independent witness.
266
+ if (
267
+ authorities.ledger === authorities.witness ||
268
+ authorities.ledger.signer === authorities.witness.signer ||
269
+ authorities.ledger.verifier === authorities.witness.verifier ||
270
+ ledgerAuthority.trust.keyId === witnessAuthority.trust.keyId ||
271
+ ledgerAuthority.trust.trustPolicyDigest ===
272
+ witnessAuthority.trust.trustPolicyDigest
273
+ )
274
+ throw new TypeError(
275
+ "Workbench Ledger and witness authorities must be independent",
276
+ );
277
+ const durability = record(
278
+ authorities.releaseDurability,
279
+ ["id", "retain", "resolve"],
280
+ [],
281
+ "release durability authority",
282
+ );
283
+ if (typeof durability.id !== "string" || !STORAGE_ID.test(durability.id))
284
+ throw new TypeError("release durability authority id is invalid");
285
+ const artifactDurabilityAuthority = Object.freeze({
286
+ id: durability.id,
287
+ retain: fixed(
288
+ authorities.releaseDurability,
289
+ "retain",
290
+ "release durability",
291
+ ),
292
+ resolve: fixed(
293
+ authorities.releaseDurability,
294
+ "resolve",
295
+ "release durability",
296
+ ),
297
+ });
298
+ // All configuration and authority ports are captured before any storage opens.
299
+ for (const target of directories) assertNoAliases(io, target);
300
+ assertNoAliases(io, storage.witnessFilePath, false);
301
+ if (secure) {
302
+ for (const target of [
303
+ storage.artifactDir,
304
+ path.dirname(storage.witnessFilePath),
305
+ ])
306
+ ensurePrivateDirectory(target, {
307
+ applyWindowsAcl: true,
308
+ failIfUnavailable: true,
309
+ deps: { fs: io },
310
+ });
311
+ } else {
312
+ io.mkdirSync(path.dirname(storage.witnessFilePath), {
313
+ recursive: true,
314
+ mode: 0o700,
315
+ });
316
+ }
317
+ function open() {
318
+ for (const target of directories) assertNoAliases(io, target);
319
+ const artifactPorts = new EvolutionArtifactPorts({
320
+ artifactStore: new ArtifactStore({ dir: storage.artifactDir, now }),
321
+ tenantId: descriptor.artifactTenantId,
322
+ audience: descriptor.audience,
323
+ ...artifactAuthority,
324
+ now,
325
+ });
326
+ const ledgerArtifactResolver =
327
+ artifactPorts.createEvolutionLedgerArtifactResolver({
328
+ purpose: descriptor.purpose,
329
+ });
330
+ const { ledger } = createEvolutionLedgerFileBackend({
331
+ rootDir: storage.ledgerRootDir,
332
+ authorityRootDir: storage.ledgerAuthorityRootDir,
333
+ witnessFilePath: storage.witnessFilePath,
334
+ witnessId: storage.witnessId,
335
+ ledgerAuthority,
336
+ witnessAuthority,
337
+ artifactResolver: ledgerArtifactResolver,
338
+ secure,
339
+ fsImpl: io,
340
+ clock: now,
341
+ });
342
+ const ports = createEvolutionLedgerPorts({
343
+ artifactPorts,
344
+ ledger,
345
+ artifactTenantId: descriptor.artifactTenantId,
346
+ audience: descriptor.audience,
347
+ purpose: descriptor.purpose,
348
+ artifactDurabilityAuthority,
349
+ });
350
+ // Constructor authenticates and recovers the actual Registry journal.
351
+ const releaseRegistry = new SkillReleaseRegistry({
352
+ tenantId: descriptor.tenantId,
353
+ rootDir: storage.releaseRootDir,
354
+ transactionLedger: ports.transactionLedger,
355
+ secure,
356
+ fsImpl: io,
357
+ });
358
+ return {
359
+ artifactPorts,
360
+ ledger,
361
+ ledgerArtifactResolver,
362
+ releaseRegistry,
363
+ ...ports,
364
+ };
365
+ }
366
+ const primary = open();
367
+ const verifier = open();
368
+ for (const target of directories) assertNoAliases(io, target);
369
+ assertNoAliases(io, storage.witnessFilePath, false);
370
+ // Authenticate both complete stores now, not just their constructor shapes.
371
+ const left = primary.ledger.verify();
372
+ const right = verifier.ledger.verify();
373
+ for (const key of [
374
+ "epoch",
375
+ "ledgerId",
376
+ "identityDigest",
377
+ "sequence",
378
+ "headDigest",
379
+ ])
380
+ if (left[key] !== right[key])
381
+ throw new Error("Workbench file readers disagree at startup");
382
+ const result = Object.freeze({
383
+ runtimeResources: Object.freeze({
384
+ descriptor,
385
+ artifactPorts: primary.artifactPorts,
386
+ ledger: primary.ledger,
387
+ ledgerArtifactResolver: primary.ledgerArtifactResolver,
388
+ releaseRegistry: primary.releaseRegistry,
389
+ transactionLedger: primary.transactionLedger,
390
+ verifierLedger: verifier.ledger,
391
+ verifierLedgerArtifactResolver: verifier.ledgerArtifactResolver,
392
+ verifierReleaseRegistry: verifier.releaseRegistry,
393
+ verifierTransactionLedger: verifier.transactionLedger,
394
+ now,
395
+ }),
396
+ mutationPorts: Object.freeze({
397
+ auditSink: primary.auditSink,
398
+ nonceStore: primary.nonceStore,
399
+ }),
400
+ });
401
+ FILE_RESOURCES.add(result);
402
+ return result;
403
+ }
@@ -8,12 +8,18 @@ import {
8
8
  verifySkillPromotionReviewDecision,
9
9
  verifySkillPromotionReviewPacketArtifact,
10
10
  } from "./skill-promotion-review.js";
11
+ import {
12
+ captureWorkbenchRegistrySource,
13
+ verifyWorkbenchRegistryState,
14
+ } from "./evolution-workbench-registry-source.js";
11
15
 
12
16
  const { projectEvolutionRun } = evolutionRun;
13
17
  const { verifySkillInvocationReceipt } = skillInvocationReceipt;
14
18
 
15
19
  export const EVOLUTION_WORKBENCH_PROJECTION_SCHEMA =
16
20
  "chainlesschain.evolution-workbench-projection/v1";
21
+ export const EVOLUTION_WORKBENCH_REGISTRY_PROJECTION_SCHEMA =
22
+ "chainlesschain.evolution-workbench-projection/v2";
17
23
  export const EVOLUTION_WORKBENCH_BATCH_PLAN_SCHEMA =
18
24
  "chainlesschain.evolution-workbench-batch-plan/v1";
19
25
  export const EVOLUTION_WORKBENCH_MAX_ITEMS = 10_000;
@@ -211,8 +217,11 @@ function normalizePilot(value, descriptor) {
211
217
  ) ||
212
218
  !Number.isSafeInteger(value.revision) ||
213
219
  value.revision < 0 ||
220
+ typeof value.killSwitch !== "boolean" ||
214
221
  typeof value.reconciliationRequired !== "boolean" ||
215
- value.cohort?.id == null
222
+ typeof value.cohort?.id !== "string" ||
223
+ value.cohort.id.length < 1 ||
224
+ value.cohort.id.length > 256
216
225
  ) {
217
226
  throw new Error("pilot source result is invalid");
218
227
  }
@@ -229,7 +238,8 @@ export function createEvolutionWorkbenchDataSource({
229
238
  skillName: skillNameInput,
230
239
  runAdapter,
231
240
  reviewAdapter,
232
- transitionAdapter,
241
+ transitionAdapter = null,
242
+ registrySource = null,
233
243
  invocationReceiptSource = null,
234
244
  pilotSource = null,
235
245
  } = {}) {
@@ -238,11 +248,23 @@ export function createEvolutionWorkbenchDataSource({
238
248
  const skillName = identifier(skillNameInput, "skillName");
239
249
  const loadRun = capture(runAdapter, "load", "runAdapter");
240
250
  const listReviews = capture(reviewAdapter, "listReviews", "reviewAdapter");
241
- const listTransitions = capture(
242
- transitionAdapter,
243
- "list",
244
- "transitionAdapter",
245
- );
251
+ const registryReader =
252
+ registrySource === null
253
+ ? null
254
+ : captureWorkbenchRegistrySource(registrySource);
255
+ if (
256
+ registryReader &&
257
+ (transitionAdapter !== null ||
258
+ registryReader.descriptor.tenantId !== tenantId ||
259
+ registryReader.descriptor.skillName !== skillName ||
260
+ registryReader.descriptor.runId !== runId)
261
+ )
262
+ throw new TypeError(
263
+ "Workbench Registry source scope differs or has a second transition authority",
264
+ );
265
+ const listTransitions = registryReader
266
+ ? null
267
+ : capture(transitionAdapter, "list", "transitionAdapter");
246
268
  const listInvocations =
247
269
  invocationReceiptSource === null
248
270
  ? () => []
@@ -256,6 +278,7 @@ export function createEvolutionWorkbenchDataSource({
256
278
  runId,
257
279
  skillName,
258
280
  async load() {
281
+ const context = registryReader?.currentContext();
259
282
  const run = normalizeRun(await loadRun(), { tenantId, runId });
260
283
  const reviews = normalizeReviews(await listReviews(), {
261
284
  tenantId,
@@ -275,10 +298,14 @@ export function createEvolutionWorkbenchDataSource({
275
298
  const reviewPacketDigests = new Set(
276
299
  reviews.map(({ packet }) => packet.packetDigest),
277
300
  );
278
- const transitions = normalizeTransitions(await listTransitions(), {
279
- tenantId,
280
- skillName,
281
- });
301
+ const registryData = registryReader?.load();
302
+ const transitions = normalizeTransitions(
303
+ registryData ? registryData.transitions : await listTransitions(),
304
+ {
305
+ tenantId,
306
+ skillName,
307
+ },
308
+ );
282
309
  for (const { request } of transitions) {
283
310
  if (!run.projection.registry.candidates[request.candidateId]) {
284
311
  throw new Error(
@@ -286,13 +313,16 @@ export function createEvolutionWorkbenchDataSource({
286
313
  );
287
314
  }
288
315
  }
289
- return deepFreeze({
316
+ const result = deepFreeze({
290
317
  run,
291
318
  reviews,
292
319
  transitions,
320
+ registry: registryData?.registry ?? null,
293
321
  invocations: normalizeInvocations(await listInvocations(), { runId }),
294
322
  pilot: normalizePilot(await readPilot(), { reviewPacketDigests }),
295
323
  });
324
+ if (registryReader) registryReader.assertCurrent(context);
325
+ return result;
296
326
  },
297
327
  });
298
328
  DATA_SOURCES.add(source);
@@ -560,15 +590,17 @@ export async function buildEvolutionWorkbenchProjection(
560
590
  normalizeTime(observedAt, "observedAt");
561
591
  const data = await source.load();
562
592
  const activeReleaseId = data.run.projection.registry.activeReleaseId;
563
- const activeCandidateIds = new Set(
564
- data.transitions
565
- .filter(
566
- ({ status, settlement }) =>
567
- status === "committed" &&
568
- settlement?.activeReleaseDigest === activeReleaseId,
569
- )
570
- .map(({ settlement }) => settlement.candidateId),
571
- );
593
+ const activeCandidateIds = data.registry
594
+ ? new Set(data.registry.active ? [data.registry.active.candidateId] : [])
595
+ : new Set(
596
+ data.transitions
597
+ .filter(
598
+ ({ status, settlement }) =>
599
+ status === "committed" &&
600
+ settlement?.activeReleaseDigest === activeReleaseId,
601
+ )
602
+ .map(({ settlement }) => settlement.candidateId),
603
+ );
572
604
  const candidates = data.reviews.map((review) =>
573
605
  candidateView(review, data.invocations, activeCandidateIds),
574
606
  );
@@ -576,14 +608,61 @@ export async function buildEvolutionWorkbenchProjection(
576
608
  ...runTimeline(data.run.events),
577
609
  ...reviewTimeline(data.reviews),
578
610
  ...transitionTimeline(data.transitions),
611
+ ...(data.registry?.operations ?? []).map((operation) => ({
612
+ id: `release:${operation.transactionId}`,
613
+ sequence: operation.sequence ?? operation.preparationSequence,
614
+ phase:
615
+ operation.status === "prepared"
616
+ ? `release-${operation.operation}-prepared`
617
+ : operation.operation === "rollback"
618
+ ? "release-rolled-back"
619
+ : "release-promoted",
620
+ status: operation.status,
621
+ subjectId: operation.candidateId,
622
+ digest: operation.receiptDigest,
623
+ artifactRef: null,
624
+ occurredAt: operation.occurredAt,
625
+ source: "release-registry",
626
+ detail: {
627
+ operationId: operation.operationId,
628
+ requestDigest: operation.requestDigest,
629
+ releaseDigest: operation.releaseDigest,
630
+ fromReleaseDigest: operation.fromReleaseDigest,
631
+ stateDigest: operation.stateDigest,
632
+ transactionId: operation.transactionId,
633
+ },
634
+ })),
579
635
  ].sort(timelineOrder);
580
636
  const conflicts = conflictsFor(candidates, data.transitions, data.pilot);
637
+ for (const operation of data.registry?.operations ?? [])
638
+ if (operation.status === "prepared")
639
+ conflicts.push({
640
+ type: "pending-registry-effect",
641
+ candidateId: operation.candidateId,
642
+ packetDigest: null,
643
+ reason: "actual Registry transaction has not finalized",
644
+ });
645
+ if (
646
+ data.registry?.active &&
647
+ !candidates.some((candidate) => candidate.actualUsage.active)
648
+ )
649
+ conflicts.push({
650
+ type: "active-outside-run",
651
+ candidateId: data.registry.active.candidateId,
652
+ packetDigest: null,
653
+ reason:
654
+ "current Registry release is outside this run's review candidates",
655
+ });
656
+ const schema = data.registry
657
+ ? EVOLUTION_WORKBENCH_REGISTRY_PROJECTION_SCHEMA
658
+ : EVOLUTION_WORKBENCH_PROJECTION_SCHEMA;
581
659
  const core = {
582
- schema: EVOLUTION_WORKBENCH_PROJECTION_SCHEMA,
660
+ schema,
583
661
  tenantId: source.tenantId,
584
662
  runId: source.runId,
585
663
  skillName: source.skillName,
586
664
  observedAt,
665
+ ...(data.registry ? { registry: data.registry } : {}),
587
666
  run: {
588
667
  status: data.run.projection.status,
589
668
  projectionDigest: data.run.projection.projectionDigest,
@@ -605,6 +684,9 @@ export async function buildEvolutionWorkbenchProjection(
605
684
  rejectedCount: candidates.filter(({ status }) => status === "rejected")
606
685
  .length,
607
686
  transitionCount: data.transitions.length,
687
+ ...(data.registry
688
+ ? { registryOperationCount: data.registry.operations.length }
689
+ : {}),
608
690
  invocationCount: data.invocations.length,
609
691
  conflictCount: conflicts.length,
610
692
  },
@@ -615,7 +697,7 @@ export async function buildEvolutionWorkbenchProjection(
615
697
  };
616
698
  return deepFreeze({
617
699
  ...core,
618
- projectionDigest: hash(EVOLUTION_WORKBENCH_PROJECTION_SCHEMA, core),
700
+ projectionDigest: hash(schema, core),
619
701
  });
620
702
  }
621
703
 
@@ -624,10 +706,13 @@ export function filterEvolutionWorkbenchProjection(
624
706
  { query = "", status = null, offset = 0, limit = 100 } = {},
625
707
  ) {
626
708
  if (
627
- projection?.schema !== EVOLUTION_WORKBENCH_PROJECTION_SCHEMA ||
709
+ ![
710
+ EVOLUTION_WORKBENCH_PROJECTION_SCHEMA,
711
+ EVOLUTION_WORKBENCH_REGISTRY_PROJECTION_SCHEMA,
712
+ ].includes(projection?.schema) ||
628
713
  projection.projectionDigest !==
629
714
  hash(
630
- EVOLUTION_WORKBENCH_PROJECTION_SCHEMA,
715
+ projection.schema,
631
716
  Object.fromEntries(
632
717
  Object.entries(projection).filter(
633
718
  ([key]) => key !== "projectionDigest",
@@ -639,6 +724,28 @@ export function filterEvolutionWorkbenchProjection(
639
724
  "a verified Evolution Workbench projection is required",
640
725
  );
641
726
  }
727
+ const registry =
728
+ projection.schema === EVOLUTION_WORKBENCH_REGISTRY_PROJECTION_SCHEMA
729
+ ? verifyWorkbenchRegistryState(
730
+ projection.registry,
731
+ projection.tenantId,
732
+ projection.skillName,
733
+ )
734
+ : null;
735
+ if (
736
+ registry &&
737
+ (projection.summary.registryOperationCount !== registry.operations.length ||
738
+ projection.candidates.some(
739
+ (candidate) =>
740
+ candidate.actualUsage.active !==
741
+ (candidate.candidateId === registry.active?.candidateId &&
742
+ candidate.candidateContentDigest ===
743
+ registry.active?.contentDigest),
744
+ ))
745
+ )
746
+ throw new Error(
747
+ "Workbench candidate activity differs from current Registry state",
748
+ );
642
749
  if (
643
750
  !Number.isSafeInteger(offset) ||
644
751
  offset < 0 ||
@@ -674,8 +781,28 @@ export function filterEvolutionWorkbenchProjection(
674
781
  .toLowerCase();
675
782
  return searchable.includes(needle);
676
783
  });
784
+ const governance = {
785
+ runStatus: projection.run.status,
786
+ activeReleaseId: registry
787
+ ? (registry.active?.releaseDigest ?? null)
788
+ : projection.run.activeReleaseId,
789
+ lastKnownGoodReleaseId: registry
790
+ ? (registry.active?.lastKnownGoodReleaseDigest ?? null)
791
+ : projection.run.lastKnownGoodReleaseId,
792
+ conflictCount: projection.summary.conflictCount,
793
+ pilot:
794
+ projection.pilot === null
795
+ ? null
796
+ : {
797
+ stage: projection.pilot.stage,
798
+ revision: projection.pilot.revision,
799
+ killSwitch: projection.pilot.killSwitch,
800
+ reconciliationRequired: projection.pilot.reconciliationRequired,
801
+ },
802
+ };
677
803
  return deepFreeze({
678
804
  projectionDigest: projection.projectionDigest,
805
+ governance: clone(governance),
679
806
  total: matches.length,
680
807
  offset,
681
808
  limit,