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,845 @@
1
+ import { createHash } from "node:crypto";
2
+
3
+ export const PROGRESSIVE_CANARY_PLAN_SCHEMA =
4
+ "chainlesschain.progressive-canary-plan/v2";
5
+ export const PROGRESSIVE_CANARY_ASSIGNMENT_SCHEMA =
6
+ "chainlesschain.progressive-canary-assignment/v2";
7
+ export const PROGRESSIVE_CANARY_GATE_REPORT_SCHEMA =
8
+ "chainlesschain.progressive-canary-gate-report/v2";
9
+ export const PROGRESSIVE_CANARY_GATE_RECEIPT_SCHEMA =
10
+ "chainlesschain.progressive-canary-gate-receipt/v1";
11
+
12
+ const DIGEST = /^sha256:[a-f0-9]{64}$/u;
13
+ const SAFE_ID = /^[A-Za-z0-9][A-Za-z0-9._:@/-]{0,255}$/u;
14
+ const RISK_TIERS = new Set(["low", "medium", "high"]);
15
+ const AUTHORITIES = new WeakSet();
16
+ const GATE_AUTHORITIES = new WeakSet();
17
+
18
+ function canonical(value) {
19
+ if (value === null || typeof value !== "object") return JSON.stringify(value);
20
+ if (Array.isArray(value)) return `[${value.map(canonical).join(",")}]`;
21
+ return `{${Object.keys(value)
22
+ .sort()
23
+ .map((key) => `${JSON.stringify(key)}:${canonical(value[key])}`)
24
+ .join(",")}}`;
25
+ }
26
+
27
+ function hash(domain, value) {
28
+ return `sha256:${createHash("sha256")
29
+ .update(domain)
30
+ .update("\0")
31
+ .update(canonical(value))
32
+ .digest("hex")}`;
33
+ }
34
+
35
+ function exact(value, keys, name) {
36
+ if (!value || typeof value !== "object" || Array.isArray(value))
37
+ throw new TypeError(`${name} must be an object`);
38
+ if (canonical(Object.keys(value).sort()) !== canonical([...keys].sort()))
39
+ throw new TypeError(`${name} has unexpected or missing fields`);
40
+ }
41
+
42
+ function id(value, name) {
43
+ if (typeof value !== "string" || !SAFE_ID.test(value))
44
+ throw new TypeError(`${name} is invalid`);
45
+ return value;
46
+ }
47
+
48
+ function sha(value, name) {
49
+ if (!DIGEST.test(value ?? ""))
50
+ throw new TypeError(`${name} must be a sha256 digest`);
51
+ return value;
52
+ }
53
+
54
+ function integer(value, name, { min = 0, max = Number.MAX_SAFE_INTEGER } = {}) {
55
+ if (!Number.isSafeInteger(value) || value < min || value > max)
56
+ throw new TypeError(`${name} is out of range`);
57
+ return value;
58
+ }
59
+
60
+ function finite(value, name, { min = -Infinity, max = Infinity } = {}) {
61
+ if (!Number.isFinite(value) || value < min || value > max)
62
+ throw new TypeError(`${name} is out of range`);
63
+ return value;
64
+ }
65
+
66
+ function verifyPlan(plan) {
67
+ if (!plan || plan.schema !== PROGRESSIVE_CANARY_PLAN_SCHEMA)
68
+ throw new TypeError("a canonical progressive Canary plan is required");
69
+ const core = structuredClone(plan);
70
+ delete core.planDigest;
71
+ if (hash(PROGRESSIVE_CANARY_PLAN_SCHEMA, core) !== plan.planDigest)
72
+ throw new Error("progressive Canary plan digest mismatch");
73
+ return plan;
74
+ }
75
+
76
+ export function verifyProgressiveCanaryPlan(plan) {
77
+ return verifyPlan(plan);
78
+ }
79
+
80
+ function normalizeSteps(steps) {
81
+ if (!Array.isArray(steps) || steps.length < 3 || steps.length > 16)
82
+ throw new TypeError("progressive Canary plan requires 3..16 steps");
83
+ const ids = new Set();
84
+ const normalized = steps.map((step, index) => {
85
+ exact(
86
+ step,
87
+ [
88
+ "id",
89
+ "stage",
90
+ "trafficPercent",
91
+ "minSamples",
92
+ "minWindowMs",
93
+ "maxWindowMs",
94
+ ],
95
+ `Canary step ${index}`,
96
+ );
97
+ const stepId = id(step.id, `Canary step ${index} id`);
98
+ if (ids.has(stepId))
99
+ throw new TypeError(`duplicate Canary step: ${stepId}`);
100
+ ids.add(stepId);
101
+ if (!new Set(["shadow", "canary", "active-probation"]).has(step.stage))
102
+ throw new TypeError(`Canary step ${index} stage is invalid`);
103
+ const result = {
104
+ id: stepId,
105
+ stage: step.stage,
106
+ trafficPercent: finite(
107
+ step.trafficPercent,
108
+ `Canary step ${index} trafficPercent`,
109
+ {
110
+ min: 0,
111
+ max: 100,
112
+ },
113
+ ),
114
+ minSamples: integer(step.minSamples, `Canary step ${index} minSamples`, {
115
+ min: 1,
116
+ max: 1_000_000,
117
+ }),
118
+ minWindowMs: integer(
119
+ step.minWindowMs,
120
+ `Canary step ${index} minWindowMs`,
121
+ {
122
+ min: 1,
123
+ },
124
+ ),
125
+ maxWindowMs: integer(
126
+ step.maxWindowMs,
127
+ `Canary step ${index} maxWindowMs`,
128
+ {
129
+ min: 1,
130
+ },
131
+ ),
132
+ };
133
+ if (result.maxWindowMs < result.minWindowMs)
134
+ throw new TypeError(`Canary step ${index} window is invalid`);
135
+ return Object.freeze(result);
136
+ });
137
+ if (
138
+ normalized[0].stage !== "shadow" ||
139
+ normalized[0].trafficPercent !== 0 ||
140
+ normalized.at(-1).stage !== "active-probation" ||
141
+ normalized.at(-1).trafficPercent !== 100 ||
142
+ normalized.slice(1, -1).some((step) => step.stage !== "canary")
143
+ )
144
+ throw new TypeError(
145
+ "progressive Canary steps must be shadow, Canary steps, then active-probation",
146
+ );
147
+ for (let index = 1; index < normalized.length; index += 1) {
148
+ if (
149
+ normalized[index].trafficPercent <= normalized[index - 1].trafficPercent
150
+ )
151
+ throw new TypeError(
152
+ "progressive Canary traffic must increase monotonically",
153
+ );
154
+ }
155
+ return Object.freeze(normalized);
156
+ }
157
+
158
+ export function createProgressiveCanaryPlan(input = {}) {
159
+ exact(
160
+ input,
161
+ [
162
+ "tenantId",
163
+ "pilotId",
164
+ "skillName",
165
+ "candidateDigest",
166
+ "baselineDigest",
167
+ "riskTier",
168
+ "assignmentSaltDigest",
169
+ "assignmentAuthority",
170
+ "gateAuthority",
171
+ "steps",
172
+ "thresholds",
173
+ ],
174
+ "progressive Canary plan",
175
+ );
176
+ if (!RISK_TIERS.has(input.riskTier))
177
+ throw new TypeError("progressive Canary riskTier is invalid");
178
+ exact(
179
+ input.assignmentAuthority,
180
+ ["id", "revision", "handlerDigest"],
181
+ "assignmentAuthority",
182
+ );
183
+ exact(
184
+ input.gateAuthority,
185
+ ["id", "revision", "handlerDigest"],
186
+ "gateAuthority",
187
+ );
188
+ exact(
189
+ input.thresholds,
190
+ [
191
+ "confidence",
192
+ "bootstrapSamples",
193
+ "minQualityDeltaLowerBound",
194
+ "maxMeanCostDelta",
195
+ "maxP95LatencyRatio",
196
+ "maxP99LatencyRatio",
197
+ "maxMeanToolCallDelta",
198
+ ],
199
+ "Canary thresholds",
200
+ );
201
+ if (input.thresholds.bootstrapSamples !== 1_000)
202
+ throw new TypeError("Canary bootstrapSamples must equal 1000");
203
+ const core = {
204
+ schema: PROGRESSIVE_CANARY_PLAN_SCHEMA,
205
+ tenantId: id(input.tenantId, "tenantId"),
206
+ pilotId: id(input.pilotId, "pilotId"),
207
+ skillName: id(input.skillName, "skillName"),
208
+ candidateDigest: sha(input.candidateDigest, "candidateDigest"),
209
+ baselineDigest: sha(input.baselineDigest, "baselineDigest"),
210
+ riskTier: input.riskTier,
211
+ assignmentSaltDigest: sha(
212
+ input.assignmentSaltDigest,
213
+ "assignmentSaltDigest",
214
+ ),
215
+ assignmentAuthority: Object.freeze({
216
+ id: id(input.assignmentAuthority.id, "assignmentAuthority.id"),
217
+ revision: integer(
218
+ input.assignmentAuthority.revision,
219
+ "assignmentAuthority.revision",
220
+ { min: 1 },
221
+ ),
222
+ handlerDigest: sha(
223
+ input.assignmentAuthority.handlerDigest,
224
+ "assignmentAuthority.handlerDigest",
225
+ ),
226
+ }),
227
+ gateAuthority: Object.freeze({
228
+ id: id(input.gateAuthority.id, "gateAuthority.id"),
229
+ revision: integer(
230
+ input.gateAuthority.revision,
231
+ "gateAuthority.revision",
232
+ {
233
+ min: 1,
234
+ },
235
+ ),
236
+ handlerDigest: sha(
237
+ input.gateAuthority.handlerDigest,
238
+ "gateAuthority.handlerDigest",
239
+ ),
240
+ }),
241
+ steps: normalizeSteps(input.steps),
242
+ thresholds: Object.freeze({
243
+ confidence: finite(input.thresholds.confidence, "confidence", {
244
+ min: 0.9,
245
+ max: 0.999,
246
+ }),
247
+ bootstrapSamples: 1_000,
248
+ minQualityDeltaLowerBound: finite(
249
+ input.thresholds.minQualityDeltaLowerBound,
250
+ "minQualityDeltaLowerBound",
251
+ { min: -1, max: 1 },
252
+ ),
253
+ maxMeanCostDelta: finite(
254
+ input.thresholds.maxMeanCostDelta,
255
+ "maxMeanCostDelta",
256
+ ),
257
+ maxP95LatencyRatio: finite(
258
+ input.thresholds.maxP95LatencyRatio,
259
+ "maxP95LatencyRatio",
260
+ { min: 0 },
261
+ ),
262
+ maxP99LatencyRatio: finite(
263
+ input.thresholds.maxP99LatencyRatio,
264
+ "maxP99LatencyRatio",
265
+ { min: 0 },
266
+ ),
267
+ maxMeanToolCallDelta: finite(
268
+ input.thresholds.maxMeanToolCallDelta,
269
+ "maxMeanToolCallDelta",
270
+ ),
271
+ }),
272
+ };
273
+ return Object.freeze({
274
+ ...core,
275
+ planDigest: hash(PROGRESSIVE_CANARY_PLAN_SCHEMA, core),
276
+ });
277
+ }
278
+
279
+ function bucket(plan, subjectDigest) {
280
+ const digest = hash(PROGRESSIVE_CANARY_ASSIGNMENT_SCHEMA, {
281
+ planDigest: plan.planDigest,
282
+ assignmentSaltDigest: plan.assignmentSaltDigest,
283
+ subjectDigest,
284
+ });
285
+ return Number.parseInt(digest.slice(7, 15), 16) % 10_000;
286
+ }
287
+
288
+ export function createProgressiveCanaryAssignmentAuthority({
289
+ plan: planInput,
290
+ attestor,
291
+ verifier,
292
+ now = Date.now,
293
+ } = {}) {
294
+ const plan = verifyPlan(planInput);
295
+ if (typeof attestor !== "function" || typeof verifier !== "function")
296
+ throw new TypeError("Canary assignment attestor and verifier are required");
297
+ if (typeof now !== "function")
298
+ throw new TypeError("Canary authority clock is required");
299
+
300
+ async function verifyReceipt(receipt, { stepId, subjectDigest } = {}) {
301
+ exact(
302
+ receipt,
303
+ [
304
+ "schema",
305
+ "planDigest",
306
+ "tenantId",
307
+ "pilotId",
308
+ "stepId",
309
+ "subjectDigest",
310
+ "bucket",
311
+ "assigned",
312
+ "authorityId",
313
+ "authorityRevision",
314
+ "handlerDigest",
315
+ "issuedAt",
316
+ "expiresAt",
317
+ "signature",
318
+ "receiptDigest",
319
+ ],
320
+ "Canary assignment receipt",
321
+ );
322
+ if (
323
+ receipt?.schema !== PROGRESSIVE_CANARY_ASSIGNMENT_SCHEMA ||
324
+ receipt.planDigest !== plan.planDigest ||
325
+ receipt.tenantId !== plan.tenantId ||
326
+ receipt.pilotId !== plan.pilotId ||
327
+ receipt.stepId !== stepId ||
328
+ receipt.subjectDigest !== subjectDigest ||
329
+ !DIGEST.test(receipt.receiptDigest ?? "")
330
+ )
331
+ throw new Error("Canary assignment receipt binding is invalid");
332
+ const core = structuredClone(receipt);
333
+ delete core.receiptDigest;
334
+ if (
335
+ hash(PROGRESSIVE_CANARY_ASSIGNMENT_SCHEMA, core) !== receipt.receiptDigest
336
+ )
337
+ throw new Error("Canary assignment receipt digest mismatch");
338
+ const step = plan.steps.find(({ id: value }) => value === stepId);
339
+ if (!step || receipt.bucket !== bucket(plan, subjectDigest))
340
+ throw new Error("Canary assignment bucket is invalid");
341
+ const expectedAssigned =
342
+ step.stage !== "canary" || receipt.bucket < step.trafficPercent * 100;
343
+ if (receipt.assigned !== expectedAssigned)
344
+ throw new Error("Canary assignment decision is invalid");
345
+ if (
346
+ receipt.authorityId !== plan.assignmentAuthority.id ||
347
+ receipt.authorityRevision !== plan.assignmentAuthority.revision ||
348
+ receipt.handlerDigest !== plan.assignmentAuthority.handlerDigest ||
349
+ typeof receipt.issuedAt !== "string" ||
350
+ typeof receipt.expiresAt !== "string" ||
351
+ !Number.isFinite(Date.parse(receipt.issuedAt)) ||
352
+ !Number.isFinite(Date.parse(receipt.expiresAt)) ||
353
+ Date.parse(receipt.issuedAt) > Number(now()) ||
354
+ Date.parse(receipt.expiresAt) < Number(now()) ||
355
+ typeof receipt.signature !== "string" ||
356
+ receipt.signature.length < 32
357
+ )
358
+ throw new Error("Canary assignment attestation is invalid or expired");
359
+ const payload = structuredClone(core);
360
+ delete payload.signature;
361
+ if (!(await verifier({ payload, signature: receipt.signature })))
362
+ throw new Error("Canary assignment signature rejected");
363
+ return Object.freeze(structuredClone(receipt));
364
+ }
365
+
366
+ const authority = Object.freeze({
367
+ planDigest: plan.planDigest,
368
+ tenantId: plan.tenantId,
369
+ pilotId: plan.pilotId,
370
+ async assign({ stepId, subjectDigest: subjectDigestInput } = {}) {
371
+ const step = plan.steps.find(({ id: value }) => value === stepId);
372
+ if (!step) throw new TypeError("Canary assignment step is invalid");
373
+ const subjectDigest = sha(subjectDigestInput, "subjectDigest");
374
+ const assignedBucket = bucket(plan, subjectDigest);
375
+ const payload = {
376
+ schema: PROGRESSIVE_CANARY_ASSIGNMENT_SCHEMA,
377
+ planDigest: plan.planDigest,
378
+ tenantId: plan.tenantId,
379
+ pilotId: plan.pilotId,
380
+ stepId,
381
+ subjectDigest,
382
+ bucket: assignedBucket,
383
+ assigned:
384
+ step.stage !== "canary" || assignedBucket < step.trafficPercent * 100,
385
+ authorityId: plan.assignmentAuthority.id,
386
+ authorityRevision: plan.assignmentAuthority.revision,
387
+ handlerDigest: plan.assignmentAuthority.handlerDigest,
388
+ };
389
+ const attestation = await attestor(
390
+ Object.freeze(structuredClone(payload)),
391
+ );
392
+ exact(
393
+ attestation,
394
+ ["issuedAt", "expiresAt", "signature"],
395
+ "assignment attestation",
396
+ );
397
+ const core = { ...payload, ...attestation };
398
+ return verifyReceipt(
399
+ Object.freeze({
400
+ ...core,
401
+ receiptDigest: hash(PROGRESSIVE_CANARY_ASSIGNMENT_SCHEMA, core),
402
+ }),
403
+ { stepId, subjectDigest },
404
+ );
405
+ },
406
+ verify: verifyReceipt,
407
+ });
408
+ AUTHORITIES.add(authority);
409
+ return authority;
410
+ }
411
+
412
+ function percentile(sorted, probability) {
413
+ if (sorted.length === 1) return sorted[0];
414
+ const position = (sorted.length - 1) * probability;
415
+ const lower = Math.floor(position);
416
+ const upper = Math.ceil(position);
417
+ return (
418
+ sorted[lower] * (1 - (position - lower)) +
419
+ sorted[upper] * (position - lower)
420
+ );
421
+ }
422
+
423
+ function mean(values) {
424
+ return values.reduce((sum, value) => sum + value, 0) / values.length;
425
+ }
426
+
427
+ function ratio(candidate, baseline) {
428
+ if (baseline === 0) return candidate === 0 ? 1 : Number.MAX_VALUE;
429
+ return candidate / baseline;
430
+ }
431
+
432
+ function randomFrom(value) {
433
+ let state = Number.parseInt(value.slice(7, 15), 16) || 0x9e3779b9;
434
+ return () => {
435
+ state ^= state << 13;
436
+ state ^= state >>> 17;
437
+ state ^= state << 5;
438
+ return (state >>> 0) / 0x1_0000_0000;
439
+ };
440
+ }
441
+
442
+ function verifyGateReport(report, plan) {
443
+ if (
444
+ report?.schema !== PROGRESSIVE_CANARY_GATE_REPORT_SCHEMA ||
445
+ report.planDigest !== plan.planDigest ||
446
+ !DIGEST.test(report.reportDigest ?? "")
447
+ )
448
+ throw new Error("progressive Canary gate report is invalid");
449
+ const core = structuredClone(report);
450
+ delete core.reportDigest;
451
+ if (hash(PROGRESSIVE_CANARY_GATE_REPORT_SCHEMA, core) !== report.reportDigest)
452
+ throw new Error("progressive Canary gate report digest mismatch");
453
+ return report;
454
+ }
455
+
456
+ export function createProgressiveCanaryGateAuthority({
457
+ plan: planInput,
458
+ assignmentAuthority,
459
+ attestor,
460
+ verifier,
461
+ now = Date.now,
462
+ } = {}) {
463
+ const plan = verifyPlan(planInput);
464
+ if (!AUTHORITIES.has(assignmentAuthority))
465
+ throw new TypeError("a branded Canary assignment authority is required");
466
+ if (
467
+ assignmentAuthority.planDigest !== plan.planDigest ||
468
+ assignmentAuthority.tenantId !== plan.tenantId ||
469
+ assignmentAuthority.pilotId !== plan.pilotId
470
+ )
471
+ throw new TypeError("Canary assignment authority belongs to another plan");
472
+ if (typeof attestor !== "function" || typeof verifier !== "function")
473
+ throw new TypeError("Canary gate attestor and verifier are required");
474
+ if (typeof now !== "function")
475
+ throw new TypeError("Canary gate authority clock is required");
476
+
477
+ async function verifyReceipt(receipt, { stepId } = {}) {
478
+ exact(
479
+ receipt,
480
+ [
481
+ "schema",
482
+ "planDigest",
483
+ "tenantId",
484
+ "pilotId",
485
+ "stepId",
486
+ "report",
487
+ "reportDigest",
488
+ "authorityId",
489
+ "authorityRevision",
490
+ "handlerDigest",
491
+ "issuedAt",
492
+ "expiresAt",
493
+ "signature",
494
+ "receiptDigest",
495
+ ],
496
+ "Canary gate receipt",
497
+ );
498
+ const report = verifyGateReport(receipt.report, plan);
499
+ if (
500
+ receipt.schema !== PROGRESSIVE_CANARY_GATE_RECEIPT_SCHEMA ||
501
+ receipt.planDigest !== plan.planDigest ||
502
+ receipt.tenantId !== plan.tenantId ||
503
+ receipt.pilotId !== plan.pilotId ||
504
+ receipt.stepId !== stepId ||
505
+ report.stepId !== stepId ||
506
+ receipt.reportDigest !== report.reportDigest ||
507
+ receipt.authorityId !== plan.gateAuthority.id ||
508
+ receipt.authorityRevision !== plan.gateAuthority.revision ||
509
+ receipt.handlerDigest !== plan.gateAuthority.handlerDigest ||
510
+ typeof receipt.issuedAt !== "string" ||
511
+ typeof receipt.expiresAt !== "string" ||
512
+ !Number.isFinite(Date.parse(receipt.issuedAt)) ||
513
+ !Number.isFinite(Date.parse(receipt.expiresAt)) ||
514
+ Date.parse(receipt.issuedAt) > Number(now()) ||
515
+ Date.parse(receipt.expiresAt) < Number(now()) ||
516
+ typeof receipt.signature !== "string" ||
517
+ receipt.signature.length < 32 ||
518
+ !DIGEST.test(receipt.receiptDigest ?? "")
519
+ )
520
+ throw new Error("Canary gate receipt binding is invalid or expired");
521
+ const core = structuredClone(receipt);
522
+ delete core.receiptDigest;
523
+ if (
524
+ hash(PROGRESSIVE_CANARY_GATE_RECEIPT_SCHEMA, core) !==
525
+ receipt.receiptDigest
526
+ )
527
+ throw new Error("Canary gate receipt digest mismatch");
528
+ const payload = structuredClone(core);
529
+ delete payload.signature;
530
+ if (!(await verifier({ payload, signature: receipt.signature })))
531
+ throw new Error("Canary gate receipt signature rejected");
532
+ return Object.freeze(structuredClone(receipt));
533
+ }
534
+
535
+ const authority = Object.freeze({
536
+ planDigest: plan.planDigest,
537
+ tenantId: plan.tenantId,
538
+ pilotId: plan.pilotId,
539
+ async evaluate(input = {}) {
540
+ const report = await evaluateProgressiveCanaryGate({
541
+ ...input,
542
+ plan,
543
+ assignmentAuthority,
544
+ });
545
+ const payload = {
546
+ schema: PROGRESSIVE_CANARY_GATE_RECEIPT_SCHEMA,
547
+ planDigest: plan.planDigest,
548
+ tenantId: plan.tenantId,
549
+ pilotId: plan.pilotId,
550
+ stepId: report.stepId,
551
+ report,
552
+ reportDigest: report.reportDigest,
553
+ authorityId: plan.gateAuthority.id,
554
+ authorityRevision: plan.gateAuthority.revision,
555
+ handlerDigest: plan.gateAuthority.handlerDigest,
556
+ };
557
+ const attestation = await attestor(
558
+ Object.freeze(structuredClone(payload)),
559
+ );
560
+ exact(
561
+ attestation,
562
+ ["issuedAt", "expiresAt", "signature"],
563
+ "gate attestation",
564
+ );
565
+ const core = { ...payload, ...attestation };
566
+ return verifyReceipt(
567
+ Object.freeze({
568
+ ...core,
569
+ receiptDigest: hash(PROGRESSIVE_CANARY_GATE_RECEIPT_SCHEMA, core),
570
+ }),
571
+ { stepId: report.stepId },
572
+ );
573
+ },
574
+ verify: verifyReceipt,
575
+ });
576
+ GATE_AUTHORITIES.add(authority);
577
+ return authority;
578
+ }
579
+
580
+ export function isProgressiveCanaryGateAuthority(value) {
581
+ return GATE_AUTHORITIES.has(value);
582
+ }
583
+
584
+ export function isProgressiveCanaryAssignmentAuthority(value) {
585
+ return AUTHORITIES.has(value);
586
+ }
587
+
588
+ export async function evaluateProgressiveCanaryGate({
589
+ plan: planInput,
590
+ stepId,
591
+ stepStartedAt,
592
+ observedAt,
593
+ observations,
594
+ assignmentAuthority,
595
+ } = {}) {
596
+ const plan = verifyPlan(planInput);
597
+ if (!AUTHORITIES.has(assignmentAuthority))
598
+ throw new TypeError("a branded Canary assignment authority is required");
599
+ const step = plan.steps.find(({ id: value }) => value === stepId);
600
+ if (!step) throw new TypeError("progressive Canary step is invalid");
601
+ integer(stepStartedAt, "stepStartedAt");
602
+ integer(observedAt, "observedAt", { min: stepStartedAt });
603
+ if (!Array.isArray(observations) || observations.length > 1_000_000)
604
+ throw new TypeError("Canary observations must be a bounded array");
605
+ const subjects = new Set();
606
+ const normalized = [];
607
+ for (let index = 0; index < observations.length; index += 1) {
608
+ const item = observations[index];
609
+ exact(
610
+ item,
611
+ [
612
+ "subjectDigest",
613
+ "assignmentReceipt",
614
+ "outcomeReceiptDigest",
615
+ "observedAt",
616
+ "baselineSuccess",
617
+ "candidateSuccess",
618
+ "baselineCost",
619
+ "candidateCost",
620
+ "baselineLatencyMs",
621
+ "candidateLatencyMs",
622
+ "baselineToolCalls",
623
+ "candidateToolCalls",
624
+ "securityEvents",
625
+ "permissionEvents",
626
+ ],
627
+ `Canary observation ${index}`,
628
+ );
629
+ const subjectDigest = sha(
630
+ item.subjectDigest,
631
+ `observation ${index} subjectDigest`,
632
+ );
633
+ if (subjects.has(subjectDigest))
634
+ throw new TypeError("Canary observations contain a duplicate subject");
635
+ subjects.add(subjectDigest);
636
+ const assignment = await assignmentAuthority.verify(
637
+ item.assignmentReceipt,
638
+ {
639
+ stepId,
640
+ subjectDigest,
641
+ },
642
+ );
643
+ if (!assignment.assigned)
644
+ throw new Error("non-assigned traffic cannot enter Canary evidence");
645
+ integer(item.observedAt, `observation ${index} observedAt`, {
646
+ min: stepStartedAt,
647
+ max: observedAt,
648
+ });
649
+ if (
650
+ typeof item.baselineSuccess !== "boolean" ||
651
+ typeof item.candidateSuccess !== "boolean"
652
+ )
653
+ throw new TypeError(`observation ${index} paired outcome is invalid`);
654
+ normalized.push(
655
+ Object.freeze({
656
+ subjectDigest,
657
+ assignmentReceiptDigest: assignment.receiptDigest,
658
+ outcomeReceiptDigest: sha(
659
+ item.outcomeReceiptDigest,
660
+ `observation ${index} outcomeReceiptDigest`,
661
+ ),
662
+ observedAt: item.observedAt,
663
+ baselineSuccess: item.baselineSuccess,
664
+ candidateSuccess: item.candidateSuccess,
665
+ baselineCost: finite(
666
+ item.baselineCost,
667
+ `observation ${index} baselineCost`,
668
+ {
669
+ min: 0,
670
+ },
671
+ ),
672
+ candidateCost: finite(
673
+ item.candidateCost,
674
+ `observation ${index} candidateCost`,
675
+ {
676
+ min: 0,
677
+ },
678
+ ),
679
+ baselineLatencyMs: finite(
680
+ item.baselineLatencyMs,
681
+ `observation ${index} baselineLatencyMs`,
682
+ { min: 0 },
683
+ ),
684
+ candidateLatencyMs: finite(
685
+ item.candidateLatencyMs,
686
+ `observation ${index} candidateLatencyMs`,
687
+ { min: 0 },
688
+ ),
689
+ baselineToolCalls: integer(
690
+ item.baselineToolCalls,
691
+ `observation ${index} baselineToolCalls`,
692
+ ),
693
+ candidateToolCalls: integer(
694
+ item.candidateToolCalls,
695
+ `observation ${index} candidateToolCalls`,
696
+ ),
697
+ securityEvents: integer(
698
+ item.securityEvents,
699
+ `observation ${index} securityEvents`,
700
+ ),
701
+ permissionEvents: integer(
702
+ item.permissionEvents,
703
+ `observation ${index} permissionEvents`,
704
+ ),
705
+ }),
706
+ );
707
+ }
708
+ normalized.sort((left, right) =>
709
+ left.subjectDigest.localeCompare(right.subjectDigest),
710
+ );
711
+ const elapsedMs = observedAt - stepStartedAt;
712
+ const failures = [];
713
+ if (normalized.length < step.minSamples) failures.push("min_samples");
714
+ if (elapsedMs < step.minWindowMs) failures.push("min_window");
715
+ if (elapsedMs > step.maxWindowMs) failures.push("max_window");
716
+ const securityEvents = normalized.reduce(
717
+ (sum, item) => sum + item.securityEvents,
718
+ 0,
719
+ );
720
+ const permissionEvents = normalized.reduce(
721
+ (sum, item) => sum + item.permissionEvents,
722
+ 0,
723
+ );
724
+ if (securityEvents > 0) failures.push("security_events");
725
+ if (permissionEvents > 0) failures.push("permission_events");
726
+
727
+ let metrics = null;
728
+ if (normalized.length > 0) {
729
+ const qualityDeltas = normalized.map(
730
+ (item) => Number(item.candidateSuccess) - Number(item.baselineSuccess),
731
+ );
732
+ const seedDigest = hash(PROGRESSIVE_CANARY_GATE_REPORT_SCHEMA, {
733
+ planDigest: plan.planDigest,
734
+ stepId,
735
+ receipts: normalized.map((item) => item.outcomeReceiptDigest),
736
+ });
737
+ const random = randomFrom(seedDigest);
738
+ const bootstrap = Array.from(
739
+ { length: plan.thresholds.bootstrapSamples },
740
+ () =>
741
+ mean(
742
+ Array.from(
743
+ { length: qualityDeltas.length },
744
+ () => qualityDeltas[Math.floor(random() * qualityDeltas.length)],
745
+ ),
746
+ ),
747
+ ).sort((left, right) => left - right);
748
+ const alpha = 1 - plan.thresholds.confidence;
749
+ const baselineLatencies = normalized
750
+ .map((item) => item.baselineLatencyMs)
751
+ .sort((left, right) => left - right);
752
+ const candidateLatencies = normalized
753
+ .map((item) => item.candidateLatencyMs)
754
+ .sort((left, right) => left - right);
755
+ metrics = Object.freeze({
756
+ samples: normalized.length,
757
+ qualityDelta: mean(qualityDeltas),
758
+ qualityDeltaConfidenceInterval: Object.freeze([
759
+ percentile(bootstrap, alpha / 2),
760
+ percentile(bootstrap, 1 - alpha / 2),
761
+ ]),
762
+ meanCostDelta: mean(
763
+ normalized.map((item) => item.candidateCost - item.baselineCost),
764
+ ),
765
+ p95LatencyRatio: ratio(
766
+ percentile(candidateLatencies, 0.95),
767
+ percentile(baselineLatencies, 0.95),
768
+ ),
769
+ p99LatencyRatio: ratio(
770
+ percentile(candidateLatencies, 0.99),
771
+ percentile(baselineLatencies, 0.99),
772
+ ),
773
+ meanToolCallDelta: mean(
774
+ normalized.map(
775
+ (item) => item.candidateToolCalls - item.baselineToolCalls,
776
+ ),
777
+ ),
778
+ securityEvents,
779
+ permissionEvents,
780
+ });
781
+ if (
782
+ metrics.qualityDeltaConfidenceInterval[0] <
783
+ plan.thresholds.minQualityDeltaLowerBound
784
+ )
785
+ failures.push("quality_confidence_lower_bound");
786
+ if (metrics.meanCostDelta > plan.thresholds.maxMeanCostDelta)
787
+ failures.push("mean_cost_delta");
788
+ if (metrics.p95LatencyRatio > plan.thresholds.maxP95LatencyRatio)
789
+ failures.push("p95_latency_ratio");
790
+ if (metrics.p99LatencyRatio > plan.thresholds.maxP99LatencyRatio)
791
+ failures.push("p99_latency_ratio");
792
+ if (metrics.meanToolCallDelta > plan.thresholds.maxMeanToolCallDelta)
793
+ failures.push("mean_tool_call_delta");
794
+ }
795
+ const core = {
796
+ schema: PROGRESSIVE_CANARY_GATE_REPORT_SCHEMA,
797
+ planDigest: plan.planDigest,
798
+ stepId,
799
+ stage: step.stage,
800
+ trafficPercent: step.trafficPercent,
801
+ stepStartedAt,
802
+ observedAt,
803
+ elapsedMs,
804
+ observationRootDigest: hash(
805
+ PROGRESSIVE_CANARY_GATE_REPORT_SCHEMA,
806
+ normalized,
807
+ ),
808
+ metrics,
809
+ failures: Object.freeze([...new Set(failures)]),
810
+ passed: failures.length === 0,
811
+ };
812
+ return Object.freeze({
813
+ ...core,
814
+ reportDigest: hash(PROGRESSIVE_CANARY_GATE_REPORT_SCHEMA, core),
815
+ });
816
+ }
817
+
818
+ export function nextProgressiveCanaryStage({
819
+ plan: planInput,
820
+ currentStepId,
821
+ gateReport,
822
+ } = {}) {
823
+ const plan = verifyPlan(planInput);
824
+ const report = verifyGateReport(gateReport, plan);
825
+ const index = plan.steps.findIndex(
826
+ ({ id: value }) => value === currentStepId,
827
+ );
828
+ if (index < 0 || report.stepId !== currentStepId)
829
+ throw new Error("progressive Canary gate report is bound to another step");
830
+ if (!report.passed) throw new Error("progressive Canary gate did not pass");
831
+ if (index === plan.steps.length - 1) {
832
+ return Object.freeze({
833
+ stage: "stable",
834
+ stepId: null,
835
+ priorReportDigest: report.reportDigest,
836
+ });
837
+ }
838
+ const next = plan.steps[index + 1];
839
+ return Object.freeze({
840
+ stage: next.stage,
841
+ stepId: next.id,
842
+ trafficPercent: next.trafficPercent,
843
+ priorReportDigest: report.reportDigest,
844
+ });
845
+ }