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,628 @@
1
+ import { createHash } from "node:crypto";
2
+
3
+ import {
4
+ isProgressiveCanaryAssignmentAuthority,
5
+ verifyProgressiveCanaryPlan,
6
+ } from "./statistical-progressive-canary.js";
7
+
8
+ export const PROGRESSIVE_CANARY_TRAFFIC_MANIFEST_SCHEMA =
9
+ "chainlesschain.progressive-canary-traffic-manifest/v1";
10
+ export const PROGRESSIVE_CANARY_PAIRED_OUTCOME_SCHEMA =
11
+ "chainlesschain.progressive-canary-paired-outcome/v1";
12
+ export const PROGRESSIVE_CANARY_OBSERVATION_SCHEMA =
13
+ "chainlesschain.progressive-canary-observation/v1";
14
+
15
+ const DIGEST = /^sha256:[a-f0-9]{64}$/u;
16
+ const SAFE_ID = /^[A-Za-z0-9][A-Za-z0-9._:@/-]{0,255}$/u;
17
+ const OUTCOME_AUTHORITIES = new WeakSet();
18
+ const OBSERVATION_STORES = new WeakSet();
19
+
20
+ function canonical(value) {
21
+ if (value === null || typeof value !== "object") return JSON.stringify(value);
22
+ if (Array.isArray(value)) return `[${value.map(canonical).join(",")}]`;
23
+ return `{${Object.keys(value)
24
+ .sort()
25
+ .map((key) => `${JSON.stringify(key)}:${canonical(value[key])}`)
26
+ .join(",")}}`;
27
+ }
28
+
29
+ function hash(schema, value) {
30
+ return `sha256:${createHash("sha256")
31
+ .update(schema)
32
+ .update("\0")
33
+ .update(canonical(value))
34
+ .digest("hex")}`;
35
+ }
36
+
37
+ function exact(value, keys, label) {
38
+ if (
39
+ !value ||
40
+ typeof value !== "object" ||
41
+ Array.isArray(value) ||
42
+ canonical(Object.keys(value).sort()) !== canonical([...keys].sort())
43
+ )
44
+ throw new TypeError(`${label} has unexpected or missing fields`);
45
+ }
46
+
47
+ function digest(value, label) {
48
+ if (!DIGEST.test(value ?? "")) throw new TypeError(`${label} is invalid`);
49
+ return value;
50
+ }
51
+
52
+ function id(value, label) {
53
+ if (typeof value !== "string" || !SAFE_ID.test(value))
54
+ throw new TypeError(`${label} is invalid`);
55
+ return value;
56
+ }
57
+
58
+ function integer(value, label) {
59
+ if (!Number.isSafeInteger(value) || value < 0)
60
+ throw new TypeError(`${label} is invalid`);
61
+ return value;
62
+ }
63
+
64
+ function finite(value, label) {
65
+ if (!Number.isFinite(value) || value < 0)
66
+ throw new TypeError(`${label} is invalid`);
67
+ return value;
68
+ }
69
+
70
+ function cloneJson(value, label, maxBytes = 1024 * 1024) {
71
+ let encoded;
72
+ let cloned;
73
+ try {
74
+ encoded = JSON.stringify(value);
75
+ cloned = JSON.parse(encoded);
76
+ } catch (cause) {
77
+ throw new TypeError(`${label} must be JSON data`, { cause });
78
+ }
79
+ if (!encoded || Buffer.byteLength(encoded) > maxBytes)
80
+ throw new TypeError(`${label} exceeds its size bound`);
81
+ if (canonical(cloned) !== canonical(value))
82
+ throw new TypeError(`${label} must not contain non-JSON values`);
83
+ return cloned;
84
+ }
85
+
86
+ function normalizeAuthority(value, label) {
87
+ exact(value, ["id", "revision", "handlerDigest"], label);
88
+ if (!Number.isSafeInteger(value.revision) || value.revision < 1)
89
+ throw new TypeError(`${label}.revision is invalid`);
90
+ return Object.freeze({
91
+ id: id(value.id, `${label}.id`),
92
+ revision: value.revision,
93
+ handlerDigest: digest(value.handlerDigest, `${label}.handlerDigest`),
94
+ });
95
+ }
96
+
97
+ export function createProgressiveCanaryTrafficManifest(input = {}) {
98
+ exact(
99
+ input,
100
+ ["planDigest", "baselineRunner", "candidateRunner", "outcomeAuthority"],
101
+ "traffic manifest",
102
+ );
103
+ const core = {
104
+ schema: PROGRESSIVE_CANARY_TRAFFIC_MANIFEST_SCHEMA,
105
+ planDigest: digest(input.planDigest, "planDigest"),
106
+ baselineRunner: normalizeAuthority(input.baselineRunner, "baselineRunner"),
107
+ candidateRunner: normalizeAuthority(
108
+ input.candidateRunner,
109
+ "candidateRunner",
110
+ ),
111
+ outcomeAuthority: normalizeAuthority(
112
+ input.outcomeAuthority,
113
+ "outcomeAuthority",
114
+ ),
115
+ };
116
+ return Object.freeze({
117
+ ...core,
118
+ manifestDigest: hash(PROGRESSIVE_CANARY_TRAFFIC_MANIFEST_SCHEMA, core),
119
+ });
120
+ }
121
+
122
+ export function verifyProgressiveCanaryTrafficManifest(manifest) {
123
+ if (manifest?.schema !== PROGRESSIVE_CANARY_TRAFFIC_MANIFEST_SCHEMA)
124
+ throw new TypeError("a canonical traffic manifest is required");
125
+ const core = structuredClone(manifest);
126
+ delete core.manifestDigest;
127
+ if (
128
+ hash(PROGRESSIVE_CANARY_TRAFFIC_MANIFEST_SCHEMA, core) !==
129
+ manifest.manifestDigest
130
+ )
131
+ throw new Error("traffic manifest digest mismatch");
132
+ return manifest;
133
+ }
134
+
135
+ function normalizeArmResult(value, arm, manifest) {
136
+ exact(
137
+ value,
138
+ [
139
+ "authenticated",
140
+ "durable",
141
+ "runnerId",
142
+ "runnerRevision",
143
+ "handlerDigest",
144
+ "success",
145
+ "cost",
146
+ "latencyMs",
147
+ "toolCalls",
148
+ "securityEvents",
149
+ "permissionEvents",
150
+ "resultDigest",
151
+ ],
152
+ `${arm} result`,
153
+ );
154
+ const authority = manifest[`${arm}Runner`];
155
+ if (
156
+ value.authenticated !== true ||
157
+ value.durable !== true ||
158
+ value.runnerId !== authority.id ||
159
+ value.runnerRevision !== authority.revision ||
160
+ value.handlerDigest !== authority.handlerDigest ||
161
+ typeof value.success !== "boolean"
162
+ )
163
+ throw new Error(`${arm} runner did not authenticate the exact execution`);
164
+ return Object.freeze({
165
+ authenticated: true,
166
+ durable: true,
167
+ runnerId: value.runnerId,
168
+ runnerRevision: value.runnerRevision,
169
+ handlerDigest: value.handlerDigest,
170
+ success: value.success,
171
+ cost: finite(value.cost, `${arm}.cost`),
172
+ latencyMs: finite(value.latencyMs, `${arm}.latencyMs`),
173
+ toolCalls: integer(value.toolCalls, `${arm}.toolCalls`),
174
+ securityEvents: integer(value.securityEvents, `${arm}.securityEvents`),
175
+ permissionEvents: integer(
176
+ value.permissionEvents,
177
+ `${arm}.permissionEvents`,
178
+ ),
179
+ resultDigest: digest(value.resultDigest, `${arm}.resultDigest`),
180
+ });
181
+ }
182
+
183
+ export function createProgressiveCanaryPairedOutcomeAuthority({
184
+ manifest: manifestInput,
185
+ executeBaseline,
186
+ executeCandidate,
187
+ verifyBaseline,
188
+ verifyCandidate,
189
+ attestor,
190
+ verifier,
191
+ now = Date.now,
192
+ } = {}) {
193
+ const manifest = verifyProgressiveCanaryTrafficManifest(manifestInput);
194
+ if (
195
+ typeof executeBaseline !== "function" ||
196
+ typeof executeCandidate !== "function" ||
197
+ typeof verifyBaseline !== "function" ||
198
+ typeof verifyCandidate !== "function" ||
199
+ typeof attestor !== "function" ||
200
+ typeof verifier !== "function" ||
201
+ typeof now !== "function"
202
+ )
203
+ throw new TypeError("paired outcome authority ports are required");
204
+
205
+ async function verify(receipt, binding = {}) {
206
+ exact(
207
+ receipt,
208
+ [
209
+ "schema",
210
+ "manifestDigest",
211
+ "planDigest",
212
+ "stepId",
213
+ "subjectDigest",
214
+ "requestDigest",
215
+ "baseline",
216
+ "candidate",
217
+ "authorityId",
218
+ "authorityRevision",
219
+ "handlerDigest",
220
+ "issuedAt",
221
+ "signature",
222
+ "receiptDigest",
223
+ ],
224
+ "paired outcome receipt",
225
+ );
226
+ if (
227
+ receipt.schema !== PROGRESSIVE_CANARY_PAIRED_OUTCOME_SCHEMA ||
228
+ receipt.manifestDigest !== manifest.manifestDigest ||
229
+ receipt.planDigest !== manifest.planDigest ||
230
+ receipt.stepId !== binding.stepId ||
231
+ receipt.subjectDigest !== binding.subjectDigest ||
232
+ receipt.requestDigest !== binding.requestDigest ||
233
+ receipt.authorityId !== manifest.outcomeAuthority.id ||
234
+ receipt.authorityRevision !== manifest.outcomeAuthority.revision ||
235
+ receipt.handlerDigest !== manifest.outcomeAuthority.handlerDigest ||
236
+ !Number.isSafeInteger(receipt.issuedAt) ||
237
+ receipt.issuedAt > Number(now()) ||
238
+ typeof receipt.signature !== "string" ||
239
+ receipt.signature.length < 32
240
+ )
241
+ throw new Error("paired outcome receipt binding is invalid");
242
+ normalizeArmResult(receipt.baseline, "baseline", manifest);
243
+ normalizeArmResult(receipt.candidate, "candidate", manifest);
244
+ const core = structuredClone(receipt);
245
+ delete core.receiptDigest;
246
+ if (
247
+ hash(PROGRESSIVE_CANARY_PAIRED_OUTCOME_SCHEMA, core) !==
248
+ receipt.receiptDigest
249
+ )
250
+ throw new Error("paired outcome receipt digest mismatch");
251
+ const payload = structuredClone(core);
252
+ delete payload.signature;
253
+ if (!(await verifier({ payload, signature: receipt.signature })))
254
+ throw new Error("paired outcome signature rejected");
255
+ return Object.freeze(structuredClone(receipt));
256
+ }
257
+
258
+ const authority = Object.freeze({
259
+ manifestDigest: manifest.manifestDigest,
260
+ planDigest: manifest.planDigest,
261
+ async execute({ stepId, subjectDigest, requestDigest, request }) {
262
+ id(stepId, "stepId");
263
+ digest(subjectDigest, "subjectDigest");
264
+ digest(requestDigest, "requestDigest");
265
+ const execution = Object.freeze({
266
+ manifestDigest: manifest.manifestDigest,
267
+ planDigest: manifest.planDigest,
268
+ stepId,
269
+ subjectDigest,
270
+ requestDigest,
271
+ request: Object.freeze(cloneJson(request, "traffic request")),
272
+ });
273
+ const [baselineValue, candidateValue] = await Promise.all([
274
+ executeBaseline(execution),
275
+ executeCandidate(execution),
276
+ ]);
277
+ const baseline = normalizeArmResult(baselineValue, "baseline", manifest);
278
+ const candidate = normalizeArmResult(
279
+ candidateValue,
280
+ "candidate",
281
+ manifest,
282
+ );
283
+ const [baselineVerified, candidateVerified] = await Promise.all([
284
+ verifyBaseline({ execution, receipt: baseline }),
285
+ verifyCandidate({ execution, receipt: candidate }),
286
+ ]);
287
+ if (baselineVerified !== true || candidateVerified !== true)
288
+ throw new Error("a paired runner receipt was rejected");
289
+ const payload = {
290
+ schema: PROGRESSIVE_CANARY_PAIRED_OUTCOME_SCHEMA,
291
+ manifestDigest: manifest.manifestDigest,
292
+ planDigest: manifest.planDigest,
293
+ stepId,
294
+ subjectDigest,
295
+ requestDigest,
296
+ baseline,
297
+ candidate,
298
+ authorityId: manifest.outcomeAuthority.id,
299
+ authorityRevision: manifest.outcomeAuthority.revision,
300
+ handlerDigest: manifest.outcomeAuthority.handlerDigest,
301
+ issuedAt: integer(Number(now()), "outcome clock"),
302
+ };
303
+ const signature = await attestor(Object.freeze(structuredClone(payload)));
304
+ if (typeof signature !== "string" || signature.length < 32)
305
+ throw new Error(
306
+ "paired outcome attestor returned an invalid signature",
307
+ );
308
+ const core = { ...payload, signature };
309
+ return verify(
310
+ Object.freeze({
311
+ ...core,
312
+ receiptDigest: hash(PROGRESSIVE_CANARY_PAIRED_OUTCOME_SCHEMA, core),
313
+ }),
314
+ { stepId, subjectDigest, requestDigest },
315
+ );
316
+ },
317
+ verify,
318
+ });
319
+ OUTCOME_AUTHORITIES.add(authority);
320
+ return authority;
321
+ }
322
+
323
+ export function createProgressiveCanaryObservationStore({
324
+ reserve,
325
+ commit,
326
+ load,
327
+ list,
328
+ } = {}) {
329
+ if (
330
+ typeof reserve !== "function" ||
331
+ typeof commit !== "function" ||
332
+ typeof load !== "function" ||
333
+ typeof list !== "function"
334
+ )
335
+ throw new TypeError("observation store ports are required");
336
+ const store = Object.freeze({
337
+ reserve: (...args) => reserve(...args),
338
+ commit: (...args) => commit(...args),
339
+ load: (...args) => load(...args),
340
+ list: (...args) => list(...args),
341
+ });
342
+ OBSERVATION_STORES.add(store);
343
+ return store;
344
+ }
345
+
346
+ function verifyObservation(value, { plan, manifest, stepId, subjectDigest }) {
347
+ if (
348
+ value?.schema !== PROGRESSIVE_CANARY_OBSERVATION_SCHEMA ||
349
+ value.planDigest !== plan.planDigest ||
350
+ value.manifestDigest !== manifest.manifestDigest ||
351
+ value.stepId !== stepId ||
352
+ value.subjectDigest !== subjectDigest ||
353
+ !DIGEST.test(value.observationDigest ?? "")
354
+ )
355
+ throw new Error("persisted Canary observation binding is invalid");
356
+ const core = structuredClone(value);
357
+ delete core.observationDigest;
358
+ if (
359
+ hash(PROGRESSIVE_CANARY_OBSERVATION_SCHEMA, core) !==
360
+ value.observationDigest
361
+ )
362
+ throw new Error("persisted Canary observation digest mismatch");
363
+ const expectedOperationDigest = hash(PROGRESSIVE_CANARY_OBSERVATION_SCHEMA, {
364
+ planDigest: plan.planDigest,
365
+ manifestDigest: manifest.manifestDigest,
366
+ stepId,
367
+ subjectDigest,
368
+ requestDigest: value.requestDigest,
369
+ });
370
+ if (value.operationDigest !== expectedOperationDigest)
371
+ throw new Error(
372
+ "persisted Canary observation operation binding is invalid",
373
+ );
374
+ return Object.freeze(structuredClone(value));
375
+ }
376
+
377
+ export class ProgressiveCanaryTrafficWorker {
378
+ constructor({
379
+ plan: planInput,
380
+ manifest: manifestInput,
381
+ assignmentAuthority,
382
+ outcomeAuthority,
383
+ observationStore,
384
+ now = Date.now,
385
+ } = {}) {
386
+ this.plan = verifyProgressiveCanaryPlan(planInput);
387
+ this.manifest = verifyProgressiveCanaryTrafficManifest(manifestInput);
388
+ if (this.manifest.planDigest !== this.plan.planDigest)
389
+ throw new TypeError("traffic manifest belongs to another plan");
390
+ if (!isProgressiveCanaryAssignmentAuthority(assignmentAuthority))
391
+ throw new TypeError("a branded assignment authority is required");
392
+ if (
393
+ assignmentAuthority.planDigest !== this.plan.planDigest ||
394
+ assignmentAuthority.tenantId !== this.plan.tenantId ||
395
+ assignmentAuthority.pilotId !== this.plan.pilotId
396
+ )
397
+ throw new TypeError("assignment authority belongs to another plan");
398
+ if (
399
+ !OUTCOME_AUTHORITIES.has(outcomeAuthority) ||
400
+ outcomeAuthority.manifestDigest !== this.manifest.manifestDigest
401
+ )
402
+ throw new TypeError("a branded paired outcome authority is required");
403
+ if (!OBSERVATION_STORES.has(observationStore))
404
+ throw new TypeError("a branded durable observation store is required");
405
+ if (typeof now !== "function")
406
+ throw new TypeError("traffic worker clock is required");
407
+ this._assignment = assignmentAuthority;
408
+ this._outcomes = outcomeAuthority;
409
+ this._store = observationStore;
410
+ this._now = now;
411
+ Object.freeze(this);
412
+ }
413
+
414
+ async process({ stepId, subjectDigest, request } = {}) {
415
+ const step = this.plan.steps.find((value) => value.id === stepId);
416
+ if (!step) throw new TypeError("traffic step is invalid");
417
+ digest(subjectDigest, "subjectDigest");
418
+ const requestValue = Object.freeze(cloneJson(request, "traffic request"));
419
+ const requestDigest = hash(
420
+ PROGRESSIVE_CANARY_TRAFFIC_MANIFEST_SCHEMA,
421
+ requestValue,
422
+ );
423
+ const operationDigest = hash(PROGRESSIVE_CANARY_OBSERVATION_SCHEMA, {
424
+ planDigest: this.plan.planDigest,
425
+ manifestDigest: this.manifest.manifestDigest,
426
+ stepId,
427
+ subjectDigest,
428
+ requestDigest,
429
+ });
430
+ const prior = await this._store.load({
431
+ planDigest: this.plan.planDigest,
432
+ stepId,
433
+ subjectDigest,
434
+ });
435
+ if (prior !== null && prior !== undefined) {
436
+ const recovered = verifyObservation(prior, {
437
+ plan: this.plan,
438
+ manifest: this.manifest,
439
+ stepId,
440
+ subjectDigest,
441
+ });
442
+ if (recovered.requestDigest !== requestDigest)
443
+ throw new Error("a Canary subject cannot replace its traffic request");
444
+ await this._outcomes.verify(recovered.outcomeReceipt, {
445
+ stepId,
446
+ subjectDigest,
447
+ requestDigest,
448
+ });
449
+ return Object.freeze({
450
+ assigned: true,
451
+ observation: recovered,
452
+ recovered: true,
453
+ });
454
+ }
455
+ const assignmentReceipt = await this._assignment.assign({
456
+ stepId,
457
+ subjectDigest,
458
+ });
459
+ const assignment = await this._assignment.verify(assignmentReceipt, {
460
+ stepId,
461
+ subjectDigest,
462
+ });
463
+ if (!assignment.assigned)
464
+ return Object.freeze({
465
+ assigned: false,
466
+ assignmentReceipt,
467
+ observation: null,
468
+ recovered: false,
469
+ });
470
+ const reservation = await this._store.reserve({
471
+ planDigest: this.plan.planDigest,
472
+ manifestDigest: this.manifest.manifestDigest,
473
+ stepId,
474
+ subjectDigest,
475
+ requestDigest,
476
+ operationDigest,
477
+ });
478
+ if (
479
+ reservation?.authenticated !== true ||
480
+ reservation?.durable !== true ||
481
+ reservation.operationDigest !== operationDigest ||
482
+ typeof reservation.acquired !== "boolean"
483
+ )
484
+ throw new Error(
485
+ "Canary execution reservation was not durably authenticated",
486
+ );
487
+ if (!reservation.acquired) {
488
+ const completed = await this._store.load({
489
+ planDigest: this.plan.planDigest,
490
+ stepId,
491
+ subjectDigest,
492
+ });
493
+ if (completed === null || completed === undefined)
494
+ throw new Error(
495
+ "Canary execution is already reserved by another worker",
496
+ );
497
+ const recovered = verifyObservation(completed, {
498
+ plan: this.plan,
499
+ manifest: this.manifest,
500
+ stepId,
501
+ subjectDigest,
502
+ });
503
+ if (
504
+ recovered.requestDigest !== requestDigest ||
505
+ recovered.operationDigest !== operationDigest
506
+ )
507
+ throw new Error("Canary execution reservation binding differs");
508
+ await this._outcomes.verify(recovered.outcomeReceipt, {
509
+ stepId,
510
+ subjectDigest,
511
+ requestDigest,
512
+ });
513
+ return Object.freeze({
514
+ assigned: true,
515
+ observation: recovered,
516
+ recovered: true,
517
+ });
518
+ }
519
+ const outcome = await this._outcomes.execute({
520
+ stepId,
521
+ subjectDigest,
522
+ requestDigest,
523
+ request: requestValue,
524
+ });
525
+ const verified = await this._outcomes.verify(outcome, {
526
+ stepId,
527
+ subjectDigest,
528
+ requestDigest,
529
+ });
530
+ const core = {
531
+ schema: PROGRESSIVE_CANARY_OBSERVATION_SCHEMA,
532
+ planDigest: this.plan.planDigest,
533
+ manifestDigest: this.manifest.manifestDigest,
534
+ stepId,
535
+ subjectDigest,
536
+ requestDigest,
537
+ operationDigest,
538
+ assignmentReceipt,
539
+ outcomeReceipt: verified,
540
+ observedAt: integer(Number(this._now()), "traffic worker clock"),
541
+ };
542
+ const observation = Object.freeze({
543
+ ...core,
544
+ observationDigest: hash(PROGRESSIVE_CANARY_OBSERVATION_SCHEMA, core),
545
+ });
546
+ const acknowledgement = await this._store.commit(observation);
547
+ if (
548
+ acknowledgement?.authenticated !== true ||
549
+ acknowledgement?.durable !== true ||
550
+ acknowledgement.operationDigest !== operationDigest ||
551
+ acknowledgement.observationDigest !== observation.observationDigest
552
+ )
553
+ throw new Error("Canary observation was not durably authenticated");
554
+ const readback = verifyObservation(
555
+ await this._store.load({
556
+ planDigest: this.plan.planDigest,
557
+ stepId,
558
+ subjectDigest,
559
+ }),
560
+ { plan: this.plan, manifest: this.manifest, stepId, subjectDigest },
561
+ );
562
+ if (readback.observationDigest !== observation.observationDigest)
563
+ throw new Error("Canary observation durable readback differs");
564
+ return Object.freeze({
565
+ assigned: true,
566
+ observation: readback,
567
+ recovered: false,
568
+ });
569
+ }
570
+
571
+ async observations({ stepId } = {}) {
572
+ if (!this.plan.steps.some((value) => value.id === stepId))
573
+ throw new TypeError("traffic step is invalid");
574
+ const values = await this._store.list({
575
+ planDigest: this.plan.planDigest,
576
+ stepId,
577
+ });
578
+ if (!Array.isArray(values) || values.length > 1_000_000)
579
+ throw new Error("Canary observation store returned an invalid list");
580
+ const subjects = new Set();
581
+ const result = [];
582
+ for (const value of values) {
583
+ const subjectDigest = digest(
584
+ value?.subjectDigest,
585
+ "observation subjectDigest",
586
+ );
587
+ if (subjects.has(subjectDigest))
588
+ throw new Error("Canary observation store returned duplicate subjects");
589
+ subjects.add(subjectDigest);
590
+ const row = verifyObservation(value, {
591
+ plan: this.plan,
592
+ manifest: this.manifest,
593
+ stepId,
594
+ subjectDigest,
595
+ });
596
+ await this._outcomes.verify(row.outcomeReceipt, {
597
+ stepId,
598
+ subjectDigest,
599
+ requestDigest: row.requestDigest,
600
+ });
601
+ const { baseline, candidate } = row.outcomeReceipt;
602
+ result.push(
603
+ Object.freeze({
604
+ subjectDigest,
605
+ assignmentReceipt: row.assignmentReceipt,
606
+ outcomeReceiptDigest: row.outcomeReceipt.receiptDigest,
607
+ observedAt: row.observedAt,
608
+ baselineSuccess: baseline.success,
609
+ candidateSuccess: candidate.success,
610
+ baselineCost: baseline.cost,
611
+ candidateCost: candidate.cost,
612
+ baselineLatencyMs: baseline.latencyMs,
613
+ candidateLatencyMs: candidate.latencyMs,
614
+ baselineToolCalls: baseline.toolCalls,
615
+ candidateToolCalls: candidate.toolCalls,
616
+ securityEvents: baseline.securityEvents + candidate.securityEvents,
617
+ permissionEvents:
618
+ baseline.permissionEvents + candidate.permissionEvents,
619
+ }),
620
+ );
621
+ }
622
+ return Object.freeze(
623
+ result.sort((left, right) =>
624
+ left.subjectDigest.localeCompare(right.subjectDigest),
625
+ ),
626
+ );
627
+ }
628
+ }