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
@@ -1,10 +1,15 @@
1
+ import { createHash } from "node:crypto";
2
+ import { resolveKnowledgeWikiSourceProvenance } from "./knowledge-wiki-source-provenance.js";
1
3
  import {
4
+ EVOLUTION_ARTIFACT_MAX_CANONICAL_BYTES,
2
5
  EVOLUTION_DURABLE_ARTIFACT_RECORD_SCHEMA,
3
6
  isEvolutionLedgerArtifactResolver,
7
+ captureEvolutionLedgerBatchResolver,
4
8
  } from "./evolution-artifact-ports.js";
5
9
  import {
6
10
  EVOLUTION_ARTIFACT_RESOLUTION_SCHEMA,
7
11
  EVOLUTION_LEDGER_DOMAIN_EVENT_SCHEMA,
12
+ EVOLUTION_LEDGER_MAX_EVENTS,
8
13
  } from "./evolution-ledger.js";
9
14
  import {
10
15
  WIKI_REVISION_SCHEMA,
@@ -15,13 +20,28 @@ import {
15
20
 
16
21
  export const WIKI_LEDGER_EVENT_TYPE = "wiki.revision.committed";
17
22
  export const WIKI_LEDGER_CONFLICT_CODE = "CC_EVOLUTION_WIKI_REVISION_CONFLICT";
18
- export const WIKI_LEDGER_CORRUPT_CODE = "CC_EVOLUTION_WIKI_LEDGER_CORRUPT";
23
+ import {
24
+ WIKI_LEDGER_CORRUPT_CODE,
25
+ verifyWikiRevision as verifyRevision,
26
+ verifyWikiRequestTransition as verifyRequestTransition,
27
+ } from "./wiki-revision-protocol.js";
28
+ export { WIKI_LEDGER_CORRUPT_CODE } from "./wiki-revision-protocol.js";
19
29
 
20
30
  const DIGEST = /^sha256:[a-f0-9]{64}$/u;
21
31
  const REVISION_ID = /^wiki:[a-f0-9]{64}$/u;
32
+ const READERS = new WeakMap();
33
+
34
+ function freeze(value) {
35
+ if (value && typeof value === "object" && !Object.isFrozen(value)) {
36
+ Object.freeze(value);
37
+ for (const child of Object.values(value)) freeze(child);
38
+ }
39
+ return value;
40
+ }
22
41
 
23
42
  function requiredString(value, name) {
24
- if (typeof value !== "string" || value.trim() === "") throw new TypeError(`${name} is required`);
43
+ if (typeof value !== "string" || value.trim() === "")
44
+ throw new TypeError(`${name} is required`);
25
45
  return value;
26
46
  }
27
47
 
@@ -33,39 +53,66 @@ function fail(code, message) {
33
53
 
34
54
  function captureMethod(owner, name, label) {
35
55
  const method = owner?.[name];
36
- if (typeof method !== "function") throw new TypeError(`${label}.${name} is required`);
56
+ if (typeof method !== "function")
57
+ throw new TypeError(`${label}.${name} is required`);
37
58
  return (...args) => Reflect.apply(method, owner, args);
38
59
  }
39
60
 
40
61
  function parseRecord(resolution, descriptor) {
41
- if (resolution?.schema !== EVOLUTION_ARTIFACT_RESOLUTION_SCHEMA || resolution.authenticated !== true ||
42
- resolution.found !== true || !DIGEST.test(resolution.digest ?? "") ||
43
- !DIGEST.test(resolution.receiptDigest ?? "") || !Buffer.isBuffer(resolution.bytes)) {
44
- fail(WIKI_LEDGER_CORRUPT_CODE, "Wiki artifact resolution is not authenticated and complete");
62
+ if (
63
+ resolution?.schema !== EVOLUTION_ARTIFACT_RESOLUTION_SCHEMA ||
64
+ resolution.authenticated !== true ||
65
+ resolution.found !== true ||
66
+ !DIGEST.test(resolution.digest ?? "") ||
67
+ !DIGEST.test(resolution.receiptDigest ?? "") ||
68
+ !Buffer.isBuffer(resolution.bytes) ||
69
+ resolution.bytes.length > EVOLUTION_ARTIFACT_MAX_CANONICAL_BYTES
70
+ ) {
71
+ fail(
72
+ WIKI_LEDGER_CORRUPT_CODE,
73
+ "Wiki artifact resolution is not authenticated and complete",
74
+ );
45
75
  }
46
76
  let record;
47
77
  try {
48
- record = JSON.parse(resolution.bytes.toString("utf8"));
78
+ record = JSON.parse(
79
+ new TextDecoder("utf-8", { fatal: true }).decode(resolution.bytes),
80
+ );
49
81
  } catch {
50
82
  fail(WIKI_LEDGER_CORRUPT_CODE, "Wiki artifact is not canonical JSON");
51
83
  }
52
84
  const revision = record?.value;
53
- if (record?.schema !== EVOLUTION_DURABLE_ARTIFACT_RECORD_SCHEMA || record.tenantId !== descriptor.artifactTenantId ||
54
- record.audience !== descriptor.audience || record.purpose !== descriptor.purpose || record.retention !== "ledger" ||
55
- record.type !== "wiki-revision" || revision?.schema !== WIKI_REVISION_SCHEMA ||
56
- revision.tenantId !== descriptor.tenantId || revision.evolutionRunId !== descriptor.evolutionRunId ||
57
- revision.state?.schema !== WIKI_STATE_SCHEMA || revision.state.tenantId !== descriptor.tenantId ||
58
- revision.stateDigest !== digestWikiState(revision.state) || revision.state.revisionId !== revision.revisionId ||
59
- !REVISION_ID.test(revision.revisionId ?? "")) {
60
- fail(WIKI_LEDGER_CORRUPT_CODE, "Wiki artifact record or revision binding is invalid");
85
+ if (
86
+ record?.schema !== EVOLUTION_DURABLE_ARTIFACT_RECORD_SCHEMA ||
87
+ record.tenantId !== descriptor.artifactTenantId ||
88
+ record.audience !== descriptor.audience ||
89
+ record.purpose !== descriptor.purpose ||
90
+ record.retention !== "ledger" ||
91
+ record.type !== "wiki-revision" ||
92
+ revision?.schema !== WIKI_REVISION_SCHEMA ||
93
+ revision.tenantId !== descriptor.tenantId ||
94
+ revision.evolutionRunId !== descriptor.evolutionRunId ||
95
+ revision.state?.schema !== WIKI_STATE_SCHEMA ||
96
+ revision.state.tenantId !== descriptor.tenantId ||
97
+ revision.stateDigest !== digestWikiState(revision.state) ||
98
+ revision.state.revisionId !== revision.revisionId ||
99
+ !REVISION_ID.test(revision.revisionId ?? "")
100
+ ) {
101
+ fail(
102
+ WIKI_LEDGER_CORRUPT_CODE,
103
+ "Wiki artifact record or revision binding is invalid",
104
+ );
61
105
  }
62
- return revision;
106
+ return verifyRevision(revision, descriptor);
63
107
  }
64
108
 
65
109
  function normalizeDescriptor(input) {
66
110
  return Object.freeze({
67
111
  tenantId: requiredString(input?.tenantId, "tenantId"),
68
- artifactTenantId: requiredString(input?.artifactTenantId, "artifactTenantId"),
112
+ artifactTenantId: requiredString(
113
+ input?.artifactTenantId,
114
+ "artifactTenantId",
115
+ ),
69
116
  evolutionRunId: requiredString(input?.evolutionRunId, "evolutionRunId"),
70
117
  audience: requiredString(input?.audience, "audience"),
71
118
  purpose: requiredString(input?.purpose, "purpose"),
@@ -73,128 +120,741 @@ function normalizeDescriptor(input) {
73
120
  }
74
121
 
75
122
  export class WikiMaintainerLedgerAdapter {
76
- constructor({ descriptor, artifactPorts, ledger, ledgerArtifactResolver } = {}) {
123
+ #putCanonical;
124
+ #readLedger;
125
+ #verifyLedger;
126
+ #appendDomainEvent;
127
+ #resolveArtifact;
128
+ #resolveArtifactBatch;
129
+
130
+ constructor({
131
+ descriptor,
132
+ artifactPorts,
133
+ ledger,
134
+ ledgerArtifactResolver,
135
+ } = {}) {
77
136
  this.descriptor = normalizeDescriptor(descriptor);
78
- this._putCanonical = captureMethod(artifactPorts, "putCanonical", "artifactPorts");
79
- this._readLedger = captureMethod(ledger, "read", "ledger");
80
- this._verifyLedger = captureMethod(ledger, "verify", "ledger");
81
- this._appendDomainEvent = captureMethod(ledger, "appendDomainEvent", "ledger");
137
+ this.#putCanonical = captureMethod(
138
+ artifactPorts,
139
+ "putCanonical",
140
+ "artifactPorts",
141
+ );
142
+ this.#readLedger = captureMethod(ledger, "read", "ledger");
143
+ this.#verifyLedger = captureMethod(ledger, "verify", "ledger");
144
+ this.#appendDomainEvent = captureMethod(
145
+ ledger,
146
+ "appendDomainEvent",
147
+ "ledger",
148
+ );
82
149
  if (!isEvolutionLedgerArtifactResolver(ledgerArtifactResolver)) {
83
- throw new TypeError("a branded EvolutionArtifactPorts ledger resolver is required");
150
+ throw new TypeError(
151
+ "a branded EvolutionArtifactPorts ledger resolver is required",
152
+ );
84
153
  }
85
- this._resolveArtifact = ledgerArtifactResolver;
154
+ this.#resolveArtifact = ledgerArtifactResolver;
155
+ this.#resolveArtifactBatch = captureEvolutionLedgerBatchResolver(
156
+ ledgerArtifactResolver,
157
+ );
86
158
  Object.freeze(this);
159
+ READERS.set(
160
+ this,
161
+ Object.freeze({
162
+ descriptor: this.descriptor,
163
+ matchesLedger: (candidate) => candidate === ledger,
164
+ loadWiki: () => this.#loadWiki(),
165
+ readRevision: (input) => this.#readRevision(input),
166
+ readKnowledgeProvenance: (input) =>
167
+ this.#readKnowledgeProvenance(input),
168
+ readStateRevision: (input) => this.#readStateRevision(input),
169
+ findStateRevision: (input) => this.#readStateRevision(input, false),
170
+ resolveHistory: (input) => this.#resolveHistory(input),
171
+ resolveAtCheckpoint: (input) => this.#resolveHistory(input, true),
172
+ }),
173
+ );
87
174
  }
88
175
 
89
- _matchingEvents() {
90
- const events = this._readLedger();
91
- if (!Array.isArray(events)) fail(WIKI_LEDGER_CORRUPT_CODE, "EvolutionLedger read did not return events");
92
- return events.filter((event) => event.schema === EVOLUTION_LEDGER_DOMAIN_EVENT_SCHEMA &&
93
- event.type === WIKI_LEDGER_EVENT_TYPE && event.tenantId === this.descriptor.tenantId &&
94
- event.correlationId === this.descriptor.evolutionRunId);
176
+ #history({
177
+ sourceDigest = null,
178
+ allowed = [],
179
+ checkpoint = null,
180
+ revisionId = null,
181
+ stateRevisionDigest = null,
182
+ } = {}) {
183
+ // read() already authenticates its snapshot. Resolve against that snapshot's
184
+ // identity, then compare the entire event range with a fresh authority head.
185
+ // This avoids a redundant pre-read scan without caching authorization.
186
+ const events = this.#readLedger({ limit: EVOLUTION_LEDGER_MAX_EVENTS });
187
+ if (!Array.isArray(events) || events.length > EVOLUTION_LEDGER_MAX_EVENTS)
188
+ fail(
189
+ WIKI_LEDGER_CORRUPT_CODE,
190
+ "EvolutionLedger read did not return events",
191
+ );
192
+ const tail = events.at(-1);
193
+ if (checkpoint) {
194
+ const boundary = events[checkpoint.sequence - 1];
195
+ if (
196
+ !boundary ||
197
+ ["epoch", "ledgerId", "identityDigest"].some(
198
+ (key) => checkpoint[key] !== boundary[key],
199
+ ) ||
200
+ checkpoint.headDigest !== boundary.eventDigest
201
+ ) {
202
+ fail(
203
+ WIKI_LEDGER_CONFLICT_CODE,
204
+ "Wiki checkpoint is not in this authenticated ledger",
205
+ );
206
+ }
207
+ }
208
+ if (
209
+ tail &&
210
+ (typeof tail.epoch !== "string" ||
211
+ typeof tail.ledgerId !== "string" ||
212
+ !DIGEST.test(tail.identityDigest ?? "") ||
213
+ !DIGEST.test(tail.eventDigest ?? "") ||
214
+ events.some(
215
+ (event, index) =>
216
+ event.sequence !== index + 1 ||
217
+ event.epoch !== tail.epoch ||
218
+ event.ledgerId !== tail.ledgerId ||
219
+ event.identityDigest !== tail.identityDigest,
220
+ ))
221
+ ) {
222
+ fail(
223
+ WIKI_LEDGER_CORRUPT_CODE,
224
+ "Wiki ledger read has incomplete sequence or identity bindings",
225
+ );
226
+ }
227
+ const matches = events.filter(
228
+ (event) =>
229
+ event.schema === EVOLUTION_LEDGER_DOMAIN_EVENT_SCHEMA &&
230
+ event.type === WIKI_LEDGER_EVENT_TYPE &&
231
+ event.tenantId === this.descriptor.tenantId &&
232
+ event.correlationId === this.descriptor.evolutionRunId,
233
+ );
234
+ let state = createEmptyWikiState(this.descriptor.tenantId);
235
+ let viewState = state;
236
+ let latest = null;
237
+ let selectedRevision = null;
238
+ let source = sourceDigest === digestWikiState(state) ? state : null;
239
+ const successors = [];
240
+ let retainedBytes = 0;
241
+ let batch = [];
242
+ for (const [index, event] of matches.entries()) {
243
+ const previous = latest;
244
+ if (
245
+ !Number.isSafeInteger(event.sequence) ||
246
+ event.sequence <= (previous?.event.sequence ?? 0) ||
247
+ event.artifactTenantId !== this.descriptor.artifactTenantId ||
248
+ event.decision !== "committed" ||
249
+ event.skillName !== null ||
250
+ !Array.isArray(event.sourceRefs) ||
251
+ digestWikiState(event.sourceRefs) !==
252
+ digestWikiState(previous ? [previous.event.subjectRef] : [])
253
+ ) {
254
+ fail(WIKI_LEDGER_CORRUPT_CODE, "Wiki ledger event lineage is invalid");
255
+ }
256
+ // Four revisions at most (4 MiB of payload), retained only while this
257
+ // synchronous chunk is checked. Full index readback and fresh authority
258
+ // remain inside each batch; no snapshot survives this history read.
259
+ if (index % 4 === 0)
260
+ batch = this.#resolveArtifactBatch(
261
+ matches.slice(index, index + 4).map((item) => ({
262
+ epoch: tail.epoch,
263
+ ledgerId: tail.ledgerId,
264
+ ref: item.subjectRef,
265
+ tenantId: this.descriptor.artifactTenantId,
266
+ })),
267
+ );
268
+ const revision = this.#resolveEvent(event, tail, batch[index % 4]);
269
+ const inView =
270
+ checkpoint === null || event.sequence <= checkpoint.sequence;
271
+ // Before durable maintenance requests, v1 genesis did not contain that
272
+ // map. Accept only the exact known legacy genesis, never an arbitrary
273
+ // caller-supplied predecessor or a modern revision with missing fields.
274
+ if (
275
+ !previous &&
276
+ !Object.hasOwn(revision, "maintenanceRequestId") &&
277
+ !Object.hasOwn(revision.state, "maintenanceRequests") &&
278
+ revision.priorStateDigest !== digestWikiState(state)
279
+ ) {
280
+ const legacyGenesis = {
281
+ ...createEmptyWikiState(this.descriptor.tenantId),
282
+ };
283
+ delete legacyGenesis.maintenanceRequests;
284
+ if (revision.priorStateDigest === digestWikiState(legacyGenesis)) {
285
+ state = freeze(legacyGenesis);
286
+ if (inView) {
287
+ viewState = state;
288
+ source = sourceDigest === revision.priorStateDigest ? state : null;
289
+ }
290
+ }
291
+ }
292
+ if (
293
+ revision.revision !== state.revision + 1 ||
294
+ revision.priorStateDigest !== digestWikiState(state) ||
295
+ event.eventId !== `wiki.revision.${revision.revisionId.slice(5)}` ||
296
+ event.timestamp !== revision.effectiveAt
297
+ ) {
298
+ fail(
299
+ WIKI_LEDGER_CORRUPT_CODE,
300
+ "Wiki revision does not extend its authenticated predecessor",
301
+ );
302
+ }
303
+ verifyRequestTransition(state, revision);
304
+ if (
305
+ revision.revisionId === revisionId ||
306
+ revision.stateDigest === stateRevisionDigest
307
+ ) {
308
+ if (selectedRevision)
309
+ fail(WIKI_LEDGER_CORRUPT_CODE, "Wiki revision identity is ambiguous");
310
+ selectedRevision = {
311
+ trusted: true,
312
+ state: revision.state,
313
+ stateDigest: revision.stateDigest,
314
+ revisionId: revision.revisionId,
315
+ checkpoint: {
316
+ epoch: event.epoch,
317
+ ledgerId: event.ledgerId,
318
+ identityDigest: event.identityDigest,
319
+ sequence: event.sequence,
320
+ headDigest: event.eventDigest,
321
+ },
322
+ artifactRef: event.subjectRef,
323
+ };
324
+ }
325
+ if (source && inView) {
326
+ if (
327
+ !revision.maintenanceRequestDigest ||
328
+ revision.maintenanceRequestDigest !== allowed[successors.length]
329
+ ) {
330
+ fail(
331
+ WIKI_LEDGER_CONFLICT_CODE,
332
+ "Wiki has successors outside the authorized maintenance sequence",
333
+ );
334
+ }
335
+ retainedBytes += Buffer.byteLength(JSON.stringify(revision), "utf8");
336
+ if (retainedBytes > 8 * EVOLUTION_ARTIFACT_MAX_CANONICAL_BYTES) {
337
+ fail(
338
+ WIKI_LEDGER_CORRUPT_CODE,
339
+ "Wiki successor history exceeds its retained byte budget",
340
+ );
341
+ }
342
+ successors.push({
343
+ revision,
344
+ eventDigest: event.eventDigest,
345
+ artifactRef: event.subjectRef,
346
+ predecessorHead: {
347
+ epoch: event.epoch,
348
+ ledgerId: event.ledgerId,
349
+ identityDigest: event.identityDigest,
350
+ sequence: event.sequence - 1,
351
+ headDigest: event.prevDigest,
352
+ },
353
+ });
354
+ } else if (inView && sourceDigest === revision.stateDigest) {
355
+ source = revision.state;
356
+ }
357
+ if (inView) viewState = revision.state;
358
+ latest = { event, revision };
359
+ state = revision.state;
360
+ }
361
+ const head = this.#verifyLedger();
362
+ if (
363
+ head.sequence !== events.length ||
364
+ head.headDigest !== (tail?.eventDigest ?? null) ||
365
+ (tail &&
366
+ ["identityDigest", "epoch", "ledgerId"].some(
367
+ (key) => tail[key] !== head[key],
368
+ ))
369
+ ) {
370
+ fail(
371
+ WIKI_LEDGER_CONFLICT_CODE,
372
+ "Wiki ledger changed while authenticating history",
373
+ );
374
+ }
375
+ return {
376
+ head,
377
+ latest,
378
+ state,
379
+ viewState,
380
+ source,
381
+ successors,
382
+ selectedRevision,
383
+ };
384
+ }
385
+
386
+ #readKnowledgeProvenance({
387
+ tenantId,
388
+ revisionId,
389
+ knowledgeId,
390
+ contentDigest,
391
+ } = {}) {
392
+ if (
393
+ tenantId !== this.descriptor.tenantId ||
394
+ !REVISION_ID.test(revisionId ?? "") ||
395
+ typeof knowledgeId !== "string" ||
396
+ !/^[A-Za-z0-9][A-Za-z0-9._:@/-]{0,255}$/u.test(knowledgeId) ||
397
+ !DIGEST.test(contentDigest ?? "")
398
+ )
399
+ throw new TypeError(
400
+ "Wiki Knowledge provenance requires exact source identities",
401
+ );
402
+ const events = this.#readLedger({ limit: EVOLUTION_LEDGER_MAX_EVENTS });
403
+ const tail = Array.isArray(events) ? events.at(-1) : null;
404
+ if (
405
+ !tail ||
406
+ events.length > EVOLUTION_LEDGER_MAX_EVENTS ||
407
+ events.some(
408
+ (event, index) =>
409
+ event.sequence !== index + 1 ||
410
+ ["epoch", "ledgerId", "identityDigest"].some(
411
+ (key) => event[key] !== tail[key],
412
+ ),
413
+ )
414
+ )
415
+ fail(
416
+ WIKI_LEDGER_CORRUPT_CODE,
417
+ "Wiki provenance event range is incomplete",
418
+ );
419
+ const selected = events.find(
420
+ (event) =>
421
+ event.eventId === `wiki.revision.${revisionId.slice(5)}` &&
422
+ event.tenantId === tenantId,
423
+ );
424
+ const sources = events.filter(
425
+ (event) =>
426
+ event.type === WIKI_LEDGER_EVENT_TYPE &&
427
+ event.tenantId === tenantId &&
428
+ event.sequence <= (selected?.sequence ?? 0),
429
+ );
430
+ const positions = new Map(
431
+ sources.map((event, index) => [event.sequence, index]),
432
+ );
433
+ // Same bounded four-subject read as normal Wiki history. Retain no proof
434
+ // across calls and never resolve a future revision as an earlier source.
435
+ let batchStart = -1;
436
+ let batch = [];
437
+ const proof = resolveKnowledgeWikiSourceProvenance({
438
+ events,
439
+ descriptor: this.descriptor,
440
+ revisionId,
441
+ knowledge: { knowledgeId, contentDigest },
442
+ resolveSubject: (event) => {
443
+ const position = positions.get(event.sequence);
444
+ const start = position - (position % 4);
445
+ if (start !== batchStart) {
446
+ batch = this.#resolveArtifactBatch(
447
+ sources.slice(start, start + 4).map((item) => ({
448
+ epoch: tail.epoch,
449
+ ledgerId: tail.ledgerId,
450
+ tenantId: this.descriptor.artifactTenantId,
451
+ ref: item.subjectRef,
452
+ })),
453
+ );
454
+ batchStart = start;
455
+ }
456
+ const resolution = batch[position - start];
457
+ if (
458
+ resolution?.schema !== EVOLUTION_ARTIFACT_RESOLUTION_SCHEMA ||
459
+ resolution.authenticated !== true ||
460
+ resolution.found !== true ||
461
+ resolution.ref !== event.subjectRef.ref ||
462
+ resolution.digest !== event.subjectRef.digest ||
463
+ !DIGEST.test(resolution.receiptDigest ?? "") ||
464
+ !Buffer.isBuffer(resolution.bytes) ||
465
+ resolution.bytes.length > EVOLUTION_ARTIFACT_MAX_CANONICAL_BYTES ||
466
+ `sha256:${createHash("sha256").update(resolution.bytes).digest("hex")}` !==
467
+ event.subjectRef.digest
468
+ )
469
+ fail(
470
+ WIKI_LEDGER_CORRUPT_CODE,
471
+ "Wiki provenance subject is not authenticated and exactly bound",
472
+ );
473
+ return resolution.bytes;
474
+ },
475
+ });
476
+ const head = this.#verifyLedger();
477
+ if (
478
+ head.sequence !== events.length ||
479
+ head.headDigest !== tail.eventDigest ||
480
+ ["epoch", "ledgerId", "identityDigest"].some(
481
+ (key) => head[key] !== tail[key],
482
+ )
483
+ )
484
+ fail(
485
+ WIKI_LEDGER_CONFLICT_CODE,
486
+ "Wiki ledger changed while authenticating source provenance",
487
+ );
488
+ return freeze({
489
+ authenticated: true,
490
+ tenantId,
491
+ ...proof,
492
+ ledgerHead: head,
493
+ });
494
+ }
495
+
496
+ // Immutable provenance, not an authorization to use an obsolete Wiki as current.
497
+ // Authenticate the full present history, retaining only the selected revision.
498
+ #readRevision({ tenantId, revisionId } = {}) {
499
+ if (
500
+ tenantId !== this.descriptor.tenantId ||
501
+ !REVISION_ID.test(revisionId ?? "")
502
+ )
503
+ throw new TypeError(
504
+ "Wiki provenance requires an exact tenant and revisionId",
505
+ );
506
+ const { head, selectedRevision } = this.#history({ revisionId });
507
+ if (!selectedRevision)
508
+ fail(
509
+ WIKI_LEDGER_CONFLICT_CODE,
510
+ "Wiki revision is not in authenticated history",
511
+ );
512
+ return freeze({
513
+ authenticated: true,
514
+ tenantId,
515
+ evolutionRunId: this.descriptor.evolutionRunId,
516
+ ...selectedRevision,
517
+ ledgerHead: head,
518
+ });
95
519
  }
96
520
 
97
- _resolveEvent(event) {
98
- const authority = this._verifyLedger();
99
- const resolution = this._resolveArtifact({
100
- epoch: authority.epoch,
101
- ledgerId: authority.ledgerId,
102
- ref: event.subjectRef,
103
- tenantId: this.descriptor.artifactTenantId,
521
+ // Content-addressed original state lookup, without authorizing intervening
522
+ // changes. Effect consumers still replay their exact permitted successors.
523
+ #readStateRevision({ tenantId, stateDigest } = {}, required = true) {
524
+ if (
525
+ tenantId !== this.descriptor.tenantId ||
526
+ !DIGEST.test(stateDigest ?? "")
527
+ )
528
+ throw new TypeError(
529
+ "Wiki source requires an exact tenant and state digest",
530
+ );
531
+ const { head, selectedRevision } = this.#history({
532
+ stateRevisionDigest: stateDigest,
533
+ });
534
+ // A scoped lookup may prove absence only after authenticating the complete
535
+ // run. Corrupt/missing bytes and concurrent ledger changes still throw.
536
+ if (!selectedRevision && !required) return null;
537
+ if (!selectedRevision)
538
+ fail(
539
+ WIKI_LEDGER_CONFLICT_CODE,
540
+ "Wiki state revision is not in authenticated history",
541
+ );
542
+ return freeze({
543
+ authenticated: true,
544
+ tenantId,
545
+ evolutionRunId: this.descriptor.evolutionRunId,
546
+ ...selectedRevision,
547
+ ledgerHead: head,
104
548
  });
105
- if (resolution?.ref !== event.subjectRef.ref || resolution.digest !== event.subjectRef.digest) {
106
- fail(WIKI_LEDGER_CORRUPT_CODE, "Wiki ledger event resolved a substituted artifact");
549
+ }
550
+
551
+ #resolveEvent(event, authority, capturedResolution = null) {
552
+ const resolution =
553
+ capturedResolution ??
554
+ this.#resolveArtifact({
555
+ epoch: authority.epoch,
556
+ ledgerId: authority.ledgerId,
557
+ ref: event.subjectRef,
558
+ tenantId: this.descriptor.artifactTenantId,
559
+ });
560
+ if (
561
+ resolution?.ref !== event.subjectRef.ref ||
562
+ resolution.digest !== event.subjectRef.digest
563
+ ) {
564
+ fail(
565
+ WIKI_LEDGER_CORRUPT_CODE,
566
+ "Wiki ledger event resolved a substituted artifact",
567
+ );
107
568
  }
108
569
  return parseRecord(resolution, this.descriptor);
109
570
  }
110
571
 
111
- _latest() {
112
- const matches = this._matchingEvents();
113
- if (matches.length === 0) return null;
114
- for (let index = 1; index < matches.length; index += 1) {
115
- if (matches[index].sequence <= matches[index - 1].sequence) {
116
- fail(WIKI_LEDGER_CORRUPT_CODE, "Wiki ledger revisions are not strictly ordered");
572
+ loadWiki = () => this.#loadWiki();
573
+
574
+ #loadWiki() {
575
+ const { state } = this.#history();
576
+ return freeze({
577
+ trusted: true,
578
+ state,
579
+ stateDigest: digestWikiState(state),
580
+ });
581
+ }
582
+
583
+ resolveHistory(input) {
584
+ return this.#resolveHistory(input);
585
+ }
586
+
587
+ resolveAtCheckpoint(input) {
588
+ return this.#resolveHistory(input, true);
589
+ }
590
+
591
+ // Provenance only: callers must authorize the plan and independently check
592
+ // the successor's actual operation/state, not treat a request digest as an
593
+ // effect receipt. Allowed digests describe an ordered prefix, not a set.
594
+ #resolveHistory(
595
+ {
596
+ tenantId,
597
+ stateDigest,
598
+ allowedMaintenanceRequestDigests = [],
599
+ checkpoint = null,
600
+ } = {},
601
+ historical = false,
602
+ ) {
603
+ if (historical) {
604
+ const fields = [
605
+ "epoch",
606
+ "ledgerId",
607
+ "identityDigest",
608
+ "sequence",
609
+ "headDigest",
610
+ ];
611
+ if (
612
+ !checkpoint ||
613
+ typeof checkpoint !== "object" ||
614
+ Array.isArray(checkpoint) ||
615
+ Object.keys(checkpoint).length !== fields.length ||
616
+ fields.some((key) => !Object.hasOwn(checkpoint, key)) ||
617
+ typeof checkpoint.epoch !== "string" ||
618
+ typeof checkpoint.ledgerId !== "string" ||
619
+ !DIGEST.test(checkpoint.identityDigest ?? "") ||
620
+ !DIGEST.test(checkpoint.headDigest ?? "") ||
621
+ !Number.isSafeInteger(checkpoint.sequence) ||
622
+ checkpoint.sequence < 1 ||
623
+ checkpoint.sequence > EVOLUTION_LEDGER_MAX_EVENTS
624
+ ) {
625
+ throw new TypeError(
626
+ "Wiki historical read requires an exact authenticated checkpoint",
627
+ );
628
+ }
629
+ checkpoint = Object.freeze({ ...checkpoint });
630
+ } else if (checkpoint !== null) {
631
+ throw new TypeError(
632
+ "current Wiki history cannot be downgraded to a checkpoint view",
633
+ );
634
+ }
635
+ if (
636
+ tenantId !== this.descriptor.tenantId ||
637
+ !DIGEST.test(stateDigest ?? "") ||
638
+ !Array.isArray(allowedMaintenanceRequestDigests) ||
639
+ allowedMaintenanceRequestDigests.length > 128
640
+ ) {
641
+ throw new TypeError(
642
+ "Wiki history requires an exact tenant, baseline, and bounded request sequence",
643
+ );
644
+ }
645
+ const allowed = [];
646
+ const length = allowedMaintenanceRequestDigests.length;
647
+ for (let index = 0; index < length; index += 1) {
648
+ const value = allowedMaintenanceRequestDigests[index];
649
+ if (!DIGEST.test(value ?? "") || allowed.includes(value)) {
650
+ throw new TypeError(
651
+ "Wiki history request digests must be unique and dense",
652
+ );
117
653
  }
654
+ allowed.push(value);
118
655
  }
119
- const event = matches.at(-1);
120
- const revision = this._resolveEvent(event);
121
- if (revision.revision !== matches.length) {
122
- fail(WIKI_LEDGER_CORRUPT_CODE, "Wiki revision sequence has a gap or duplicate");
656
+ const { head, viewState, source, successors } = this.#history({
657
+ sourceDigest: stateDigest,
658
+ allowed,
659
+ checkpoint,
660
+ });
661
+ if (!source) {
662
+ fail(
663
+ WIKI_LEDGER_CONFLICT_CODE,
664
+ "Wiki baseline is not in authenticated history",
665
+ );
123
666
  }
124
- return { event, revision };
667
+ return freeze({
668
+ authenticated: true,
669
+ tenantId,
670
+ evolutionRunId: this.descriptor.evolutionRunId,
671
+ source: { trusted: true, state: source, stateDigest },
672
+ current: {
673
+ trusted: true,
674
+ state: viewState,
675
+ stateDigest: digestWikiState(viewState),
676
+ },
677
+ successors,
678
+ ledgerHead: head,
679
+ scope: historical ? "checkpoint" : "current",
680
+ checkpoint,
681
+ });
125
682
  }
126
683
 
127
- loadWiki = () => {
128
- const latest = this._latest();
129
- const state = latest?.revision.state ?? createEmptyWikiState(this.descriptor.tenantId);
130
- return Object.freeze({ trusted: true, state, stateDigest: digestWikiState(state) });
131
- };
132
-
133
- commitRevision = ({ expectedStateDigest, revision } = {}) => {
134
- if (!DIGEST.test(expectedStateDigest ?? "") || revision?.schema !== WIKI_REVISION_SCHEMA ||
135
- revision.tenantId !== this.descriptor.tenantId || revision.evolutionRunId !== this.descriptor.evolutionRunId ||
136
- revision.stateDigest !== digestWikiState(revision.state) || revision.state.revisionId !== revision.revisionId ||
137
- !REVISION_ID.test(revision.revisionId ?? "")) {
684
+ commitRevision = ({
685
+ expectedStateDigest,
686
+ revision,
687
+ expectedLedgerHead,
688
+ } = {}) => {
689
+ const headKeys = [
690
+ "epoch",
691
+ "ledgerId",
692
+ "identityDigest",
693
+ "sequence",
694
+ "headDigest",
695
+ ];
696
+ if (expectedLedgerHead !== undefined) {
697
+ if (
698
+ !expectedLedgerHead ||
699
+ typeof expectedLedgerHead !== "object" ||
700
+ Array.isArray(expectedLedgerHead) ||
701
+ Object.keys(expectedLedgerHead).length !== headKeys.length ||
702
+ headKeys.some((key) => !Object.hasOwn(expectedLedgerHead, key)) ||
703
+ typeof expectedLedgerHead.epoch !== "string" ||
704
+ typeof expectedLedgerHead.ledgerId !== "string" ||
705
+ !DIGEST.test(expectedLedgerHead.identityDigest ?? "") ||
706
+ !Number.isSafeInteger(expectedLedgerHead.sequence) ||
707
+ expectedLedgerHead.sequence < 0 ||
708
+ (expectedLedgerHead.sequence === 0
709
+ ? expectedLedgerHead.headDigest !== null
710
+ : !DIGEST.test(expectedLedgerHead.headDigest ?? ""))
711
+ ) {
712
+ throw new TypeError("Wiki expected ledger head is invalid");
713
+ }
714
+ expectedLedgerHead = Object.freeze({ ...expectedLedgerHead });
715
+ }
716
+ if (
717
+ !DIGEST.test(expectedStateDigest ?? "") ||
718
+ revision?.schema !== WIKI_REVISION_SCHEMA ||
719
+ revision.tenantId !== this.descriptor.tenantId ||
720
+ revision.evolutionRunId !== this.descriptor.evolutionRunId ||
721
+ revision.stateDigest !== digestWikiState(revision.state) ||
722
+ revision.state.revisionId !== revision.revisionId ||
723
+ !REVISION_ID.test(revision.revisionId ?? "")
724
+ ) {
138
725
  throw new TypeError("Wiki revision commit request is invalid");
139
726
  }
140
- const latest = this._latest();
141
- const currentState = latest?.revision.state ?? createEmptyWikiState(this.descriptor.tenantId);
727
+ // Own the revision before handing it to any persistence callback.
728
+ revision = freeze(
729
+ structuredClone(verifyRevision(revision, this.descriptor)),
730
+ );
731
+ const { head, latest, state: currentState } = this.#history();
732
+ if (
733
+ expectedLedgerHead &&
734
+ headKeys.some((key) => expectedLedgerHead[key] !== head[key])
735
+ ) {
736
+ fail(
737
+ WIKI_LEDGER_CONFLICT_CODE,
738
+ "Wiki authorization ledger head changed before revision commit",
739
+ );
740
+ }
142
741
  const currentDigest = digestWikiState(currentState);
143
742
  if (currentDigest !== expectedStateDigest) {
144
- if (latest?.revision.revisionId === revision.revisionId && currentDigest === revision.stateDigest) {
145
- return Object.freeze({ committed: true, recovered: true, revisionId: revision.revisionId,
146
- stateDigest: revision.stateDigest, evolutionRunId: this.descriptor.evolutionRunId });
743
+ if (
744
+ latest?.revision.revisionId === revision.revisionId &&
745
+ currentDigest === revision.stateDigest
746
+ ) {
747
+ return Object.freeze({
748
+ committed: true,
749
+ recovered: true,
750
+ revisionId: revision.revisionId,
751
+ stateDigest: revision.stateDigest,
752
+ evolutionRunId: this.descriptor.evolutionRunId,
753
+ });
147
754
  }
148
- fail(WIKI_LEDGER_CONFLICT_CODE, "Wiki state changed before revision commit");
755
+ fail(
756
+ WIKI_LEDGER_CONFLICT_CODE,
757
+ "Wiki state changed before revision commit",
758
+ );
149
759
  }
150
- if (revision.revision !== currentState.revision + 1 || revision.priorStateDigest !== currentDigest) {
151
- fail(WIKI_LEDGER_CONFLICT_CODE, "Wiki revision does not extend the current state");
760
+ if (
761
+ revision.revision !== currentState.revision + 1 ||
762
+ revision.priorStateDigest !== currentDigest
763
+ ) {
764
+ fail(
765
+ WIKI_LEDGER_CONFLICT_CODE,
766
+ "Wiki revision does not extend the current state",
767
+ );
152
768
  }
153
- const head = this._verifyLedger();
154
- const published = this._putCanonical("wiki-revision", revision, {
769
+ verifyRequestTransition(currentState, revision);
770
+ const published = this.#putCanonical("wiki-revision", revision, {
155
771
  audience: this.descriptor.audience,
156
772
  purpose: this.descriptor.purpose,
157
773
  retention: "ledger",
158
774
  });
159
- if (!published?.ref || published.receipt?.persisted !== true || published.receipt?.readbackVerified !== true ||
160
- published.receipt?.integrityVerified !== true || published.receipt?.retention !== "ledger") {
161
- fail(WIKI_LEDGER_CORRUPT_CODE, "Wiki revision artifact was not durably read back");
775
+ if (
776
+ !published?.ref ||
777
+ published.receipt?.persisted !== true ||
778
+ published.receipt?.readbackVerified !== true ||
779
+ published.receipt?.integrityVerified !== true ||
780
+ published.receipt?.retention !== "ledger"
781
+ ) {
782
+ fail(
783
+ WIKI_LEDGER_CORRUPT_CODE,
784
+ "Wiki revision artifact was not durably read back",
785
+ );
162
786
  }
163
787
  const eventId = `wiki.revision.${revision.revisionId.slice("wiki:".length)}`;
164
- const receipt = this._appendDomainEvent({
165
- artifactTenantId: this.descriptor.artifactTenantId,
166
- correlationId: this.descriptor.evolutionRunId,
167
- decision: "committed",
168
- eventId,
169
- reason: `wiki revision ${revision.revision} committed`,
170
- skillName: null,
171
- sourceRefs: latest ? [latest.event.subjectRef] : [],
172
- subjectRef: published.ref,
173
- tenantId: this.descriptor.tenantId,
174
- timestamp: revision.effectiveAt,
175
- type: WIKI_LEDGER_EVENT_TYPE,
176
- }, { expectedHeadDigest: head.headDigest, expectedSequence: head.sequence });
177
- if (receipt?.authenticated !== true || receipt?.committed !== true || receipt?.durable !== true ||
178
- receipt.eventId !== eventId || !DIGEST.test(receipt.receiptDigest ?? "")) {
179
- fail(WIKI_LEDGER_CORRUPT_CODE, "Wiki ledger did not confirm a durable authenticated append");
180
- }
181
- const stored = this._latest();
182
- if (stored?.revision.revisionId !== revision.revisionId || stored.revision.stateDigest !== revision.stateDigest) {
183
- fail(WIKI_LEDGER_CORRUPT_CODE, "Wiki revision readback differs after ledger commit");
184
- }
185
- return Object.freeze({ committed: true, recovered: false, revisionId: revision.revisionId,
186
- stateDigest: revision.stateDigest, evolutionRunId: this.descriptor.evolutionRunId,
187
- ledgerReceiptDigest: receipt.receiptDigest });
788
+ const receipt = this.#appendDomainEvent(
789
+ {
790
+ artifactTenantId: this.descriptor.artifactTenantId,
791
+ correlationId: this.descriptor.evolutionRunId,
792
+ decision: "committed",
793
+ eventId,
794
+ reason: `wiki revision ${revision.revision} committed`,
795
+ skillName: null,
796
+ sourceRefs: latest ? [latest.event.subjectRef] : [],
797
+ subjectRef: published.ref,
798
+ tenantId: this.descriptor.tenantId,
799
+ timestamp: revision.effectiveAt,
800
+ type: WIKI_LEDGER_EVENT_TYPE,
801
+ },
802
+ { expectedHeadDigest: head.headDigest, expectedSequence: head.sequence },
803
+ );
804
+ if (
805
+ receipt?.authenticated !== true ||
806
+ receipt?.committed !== true ||
807
+ receipt?.durable !== true ||
808
+ receipt.eventId !== eventId ||
809
+ !DIGEST.test(receipt.receiptDigest ?? "")
810
+ ) {
811
+ fail(
812
+ WIKI_LEDGER_CORRUPT_CODE,
813
+ "Wiki ledger did not confirm a durable authenticated append",
814
+ );
815
+ }
816
+ const stored = this.#history().latest;
817
+ if (
818
+ stored?.revision.revisionId !== revision.revisionId ||
819
+ stored.revision.stateDigest !== revision.stateDigest
820
+ ) {
821
+ fail(
822
+ WIKI_LEDGER_CORRUPT_CODE,
823
+ "Wiki revision readback differs after ledger commit",
824
+ );
825
+ }
826
+ return Object.freeze({
827
+ committed: true,
828
+ recovered: false,
829
+ revisionId: revision.revisionId,
830
+ stateDigest: revision.stateDigest,
831
+ evolutionRunId: this.descriptor.evolutionRunId,
832
+ ledgerReceiptDigest: receipt.receiptDigest,
833
+ });
188
834
  };
189
835
 
190
836
  maintainerPorts({ resolveEvidence, derive } = {}) {
191
837
  if (typeof resolveEvidence !== "function" || typeof derive !== "function") {
192
838
  throw new TypeError("resolveEvidence and derive ports are required");
193
839
  }
194
- return Object.freeze({ loadWiki: this.loadWiki, commitRevision: this.commitRevision, resolveEvidence, derive });
840
+ return Object.freeze({
841
+ loadWiki: () => this.#loadWiki(),
842
+ commitRevision: this.commitRevision,
843
+ resolveEvidence,
844
+ derive,
845
+ });
195
846
  }
196
847
  }
197
848
 
849
+ export function captureWikiRevisionReader(adapter) {
850
+ const reader = READERS.get(adapter);
851
+ if (!reader)
852
+ throw new TypeError(
853
+ "a branded WikiMaintainerLedgerAdapter reader is required",
854
+ );
855
+ return reader;
856
+ }
857
+
198
858
  export function createWikiMaintainerLedgerAdapter(options) {
199
859
  return new WikiMaintainerLedgerAdapter(options);
200
860
  }