chainlesschain 0.166.22 → 0.166.25

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 (298) hide show
  1. package/README.md +46 -3
  2. package/package.json +4 -3
  3. package/src/assets/web-panel/assets/{AIOps-oJ7USzMC.js → AIOps-RaxL_QQD.js} +1 -1
  4. package/src/assets/web-panel/assets/{ActionButton-BlgnZe_C.js → ActionButton-DD3ieFO-.js} +1 -1
  5. package/src/assets/web-panel/assets/{Analytics-D2rRbTLu.js → Analytics-CATDJukS.js} +3 -3
  6. package/src/assets/web-panel/assets/{AppLayout-FwS3f0B2.js → AppLayout-BHGsnRDS.js} +5 -5
  7. package/src/assets/web-panel/assets/{Artifacts-iF-_08Hi.js → Artifacts-BL6NunjN.js} +1 -1
  8. package/src/assets/web-panel/assets/{Audit-D24p0zQw.js → Audit-D0nEWfbA.js} +1 -1
  9. package/src/assets/web-panel/assets/{BackgroundAgents-Cg3mRVi9.js → BackgroundAgents-BAP1MUol.js} +1 -1
  10. package/src/assets/web-panel/assets/{Backup-EOqht3H-.js → Backup-R4y2OeSi.js} +1 -1
  11. package/src/assets/web-panel/assets/{BaseInput-9XWYq2hj.js → BaseInput-ByQZ2z6S.js} +1 -1
  12. package/src/assets/web-panel/assets/{Chat-Dq5yardA.js → Chat-32uV--xF.js} +4 -4
  13. package/src/assets/web-panel/assets/ChatBubbleRenderer-t1enanwz.js +1 -0
  14. package/src/assets/web-panel/assets/{Checkbox-CuyCBoBf.js → Checkbox-D1CB-7bq.js} +1 -1
  15. package/src/assets/web-panel/assets/{Codegen-DjWtYHNe.js → Codegen-BPx3dQ2q.js} +1 -1
  16. package/src/assets/web-panel/assets/{Col-CrVr_iuG.js → Col-DkPTQ2Gl.js} +1 -1
  17. package/src/assets/web-panel/assets/{Community-C6QxpfGc.js → Community-ZriaxRlr.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compact-B-v5r6Pa.js → Compact-C_qJ0P7F.js} +1 -1
  19. package/src/assets/web-panel/assets/{Compliance-zNiLiFgD.js → Compliance-Bgoy-saS.js} +1 -1
  20. package/src/assets/web-panel/assets/{Cowork-D9K7lMOu.js → Cowork-B5i9y6XK.js} +2 -2
  21. package/src/assets/web-panel/assets/{Cron-DAjO36z4.js → Cron-D7vBJ5-J.js} +2 -2
  22. package/src/assets/web-panel/assets/{Crosschain-Bxqn0aqB.js → Crosschain-D4kvoGI_.js} +1 -1
  23. package/src/assets/web-panel/assets/{DID-DfRmLUe-.js → DID-BLOeBd-r.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dashboard-Cz8KF3fr.js → Dashboard-mecJaonC.js} +2 -2
  25. package/src/assets/web-panel/assets/{Dropdown-C4oVfkP0.js → Dropdown-GPKwaFer.js} +1 -1
  26. package/src/assets/web-panel/assets/{EmailListRenderer-ivyZKN8k.js → EmailListRenderer-BML9m7Dd.js} +1 -1
  27. package/src/assets/web-panel/assets/{FamilyGuardDashboard-DoxY1CPW.js → FamilyGuardDashboard-DN5bAtJC.js} +1 -1
  28. package/src/assets/web-panel/assets/{Federation-C93gZxnb.js → Federation-DmD6Gecd.js} +1 -1
  29. package/src/assets/web-panel/assets/{FormItemContext-D_lEjYJE.js → FormItemContext-6wwplN_K.js} +1 -1
  30. package/src/assets/web-panel/assets/{GenericCardRenderer-BNFN9YjN.js → GenericCardRenderer-DUhpLkDL.js} +1 -1
  31. package/src/assets/web-panel/assets/{Git-mUu2HcLI.js → Git-eJfyXkwf.js} +2 -2
  32. package/src/assets/web-panel/assets/{Governance-CNuosrge.js → Governance-swAUW59x.js} +1 -1
  33. package/src/assets/web-panel/assets/{Inference-DwY5pbCB.js → Inference-CbdwJPDJ.js} +1 -1
  34. package/src/assets/web-panel/assets/{KnowledgeGraph-aRUxhACD.js → KnowledgeGraph-UuYpg1nm.js} +1 -1
  35. package/src/assets/web-panel/assets/{Logs-DFfsWYy_.js → Logs-CS0G057y.js} +2 -2
  36. package/src/assets/web-panel/assets/MarkdownRenderer-BxIIB4k3.js +1 -0
  37. package/src/assets/web-panel/assets/{Marketplace-COI-ciM-.js → Marketplace-CZRjuvvI.js} +1 -1
  38. package/src/assets/web-panel/assets/{McpTools-BJJwaIpe.js → McpTools-BOJ9A_Rf.js} +3 -3
  39. package/src/assets/web-panel/assets/{Memory-CDO6SGDZ.js → Memory-BnkrR-Ok.js} +2 -2
  40. package/src/assets/web-panel/assets/{MobileBridge-BlZ5tFf4.js → MobileBridge-Do4mPi13.js} +1 -1
  41. package/src/assets/web-panel/assets/{MobileProjects-DuoxbgWz.js → MobileProjects-2JxWa6-p.js} +1 -1
  42. package/src/assets/web-panel/assets/{Mtc-6ec9j70b.js → Mtc-CS_mnpGd.js} +2 -2
  43. package/src/assets/web-panel/assets/{MtcAudit-BuL7HkC7.js → MtcAudit-DZ4J_351.js} +5 -5
  44. package/src/assets/web-panel/assets/{Multisig-CJxR85lk.js → Multisig-Jh74zKXu.js} +3 -3
  45. package/src/assets/web-panel/assets/{NLProgramming-B71O1S4l.js → NLProgramming-_4n2BfnS.js} +1 -1
  46. package/src/assets/web-panel/assets/{Notes-Bsw5zbpV.js → Notes-CtENcKHv.js} +3 -3
  47. package/src/assets/web-panel/assets/{NotificationSettings-BnAhXuK_.js → NotificationSettings-dgDCvpK9.js} +1 -1
  48. package/src/assets/web-panel/assets/{OrderTableRenderer-BJ0R5GGz.js → OrderTableRenderer-D5VxCrmG.js} +1 -1
  49. package/src/assets/web-panel/assets/{Organization-B7wwNxoP.js → Organization-CpIF8Xkd.js} +2 -2
  50. package/src/assets/web-panel/assets/{Overflow-CfAGr0gM.js → Overflow-aHnBZaez.js} +1 -1
  51. package/src/assets/web-panel/assets/{P2P-KhMg22Fz.js → P2P-8ppzog2V.js} +2 -2
  52. package/src/assets/web-panel/assets/{PdhVaultBrowser-NdAXI9ft.js → PdhVaultBrowser-D3p1BXkp.js} +3 -3
  53. package/src/assets/web-panel/assets/{Permissions-CIYjqyT7.js → Permissions-D7vflD5q.js} +4 -4
  54. package/src/assets/web-panel/assets/{PersonalDataHub-D2ht3P_R.js → PersonalDataHub-D2hY-Ek2.js} +4 -4
  55. package/src/assets/web-panel/assets/{Pipeline-i6flZW1m.js → Pipeline-qK2VqhJC.js} +1 -1
  56. package/src/assets/web-panel/assets/{Privacy-DE0lhYVc.js → Privacy-DHJr4uu0.js} +1 -1
  57. package/src/assets/web-panel/assets/{ProjectInit-BL3YbyxS.js → ProjectInit-DMBS6trm.js} +2 -2
  58. package/src/assets/web-panel/assets/{ProjectSettings-CEtdg7ni.js → ProjectSettings-D3Ng74BT.js} +2 -2
  59. package/src/assets/web-panel/assets/{Projects-CvtU5peJ.js → Projects-BfJFZiIW.js} +1 -1
  60. package/src/assets/web-panel/assets/{Providers-DKt_Cg-j.js → Providers-DlNA95G0.js} +1 -1
  61. package/src/assets/web-panel/assets/{QrScannerModal-DA61jNSx.js → QrScannerModal-CMOIYxIm.js} +1 -1
  62. package/src/assets/web-panel/assets/{QuickAsk-fS9ryUmq.js → QuickAsk-D6MyGp5I.js} +1 -1
  63. package/src/assets/web-panel/assets/{Recommend-CR9dZU5Y.js → Recommend-W6WcShtf.js} +1 -1
  64. package/src/assets/web-panel/assets/{RemoteSession-BV0BR2Dz.js → RemoteSession-Dm_MjlV_.js} +2 -2
  65. package/src/assets/web-panel/assets/{Reputation-BIeGUvYD.js → Reputation-Ctvij6eX.js} +1 -1
  66. package/src/assets/web-panel/assets/{Row-DHDT1aro.js → Row-DivbeDE-.js} +1 -1
  67. package/src/assets/web-panel/assets/{RssFeed-Cq6YKb1h.js → RssFeed-D4famoAw.js} +3 -3
  68. package/src/assets/web-panel/assets/{Search-DEF6vsy6.js → Search-6gOAh3zG.js} +1 -1
  69. package/src/assets/web-panel/assets/{Security-CHtYiKY9.js → Security-DApb9kK8.js} +4 -4
  70. package/src/assets/web-panel/assets/{Services-u16lvBJN.js → Services-B8OomyE2.js} +2 -2
  71. package/src/assets/web-panel/assets/{Skeleton-CGbizyDj.js → Skeleton-BTJ2g2E3.js} +1 -1
  72. package/src/assets/web-panel/assets/{Skills-BZMQcAa7.js → Skills-NIRr4DD1.js} +1 -1
  73. package/src/assets/web-panel/assets/{Sla-Bm-CycVi.js → Sla-BQHP_6px.js} +1 -1
  74. package/src/assets/web-panel/assets/{SpeechSettings-BudpA5kr.js → SpeechSettings-BVQTDSVS.js} +1 -1
  75. package/src/assets/web-panel/assets/{SyncSettings-B8q1C1eC.js → SyncSettings-BOD4Mar6.js} +2 -2
  76. package/src/assets/web-panel/assets/{Tasks-SU1pBWc-.js → Tasks-Ciu7H2-y.js} +1 -1
  77. package/src/assets/web-panel/assets/{Templates-CyOfJzmt.js → Templates-CtlwavRU.js} +1 -1
  78. package/src/assets/web-panel/assets/{Tenant-xqWSm2GP.js → Tenant-QLWYJdL6.js} +1 -1
  79. package/src/assets/web-panel/assets/{Terminal-D1Ttgjsi.js → Terminal-B3q10mjm.js} +2 -2
  80. package/src/assets/web-panel/assets/{TimelineRenderer-Da2lYs5D.js → TimelineRenderer-CqltBA_8.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tokens-B34-SduO.js → Tokens-CJOKrj4y.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trigger-C8zyYm4R.js → Trigger-CPMGgfdM.js} +1 -1
  83. package/src/assets/web-panel/assets/{Trust-D1Pvqems.js → Trust-DiJms7Bl.js} +1 -1
  84. package/src/assets/web-panel/assets/{UkeySign-Do3VVnAy.js → UkeySign-rakR8eel.js} +1 -1
  85. package/src/assets/web-panel/assets/{VideoEditing-Dz7egVIA.js → VideoEditing-DAWZUM5o.js} +1 -1
  86. package/src/assets/web-panel/assets/{Wallet-Dcuw-OxR.js → Wallet-DqUPnl7K.js} +3 -3
  87. package/src/assets/web-panel/assets/{WebAuthn-DPlw-QsB.js → WebAuthn-BnVUwvMm.js} +3 -3
  88. package/src/assets/web-panel/assets/{WorkflowEditor-h4OsnU5q.js → WorkflowEditor-B1CAwxgs.js} +1 -1
  89. package/src/assets/web-panel/assets/{chat-eO9wEwrW.js → chat-k2-0Jzfy.js} +1 -1
  90. package/src/assets/web-panel/assets/{colors-34lSmOXw.js → colors-BAu8xBmW.js} +1 -1
  91. package/src/assets/web-panel/assets/{compact-item-CK4kEWJ4.js → compact-item-DMlqcdfI.js} +1 -1
  92. package/src/assets/web-panel/assets/{createContext-E0A57xed.js → createContext-BU9kfiSw.js} +1 -1
  93. package/src/assets/web-panel/assets/devWarning-DuGrUMAS.js +1 -0
  94. package/src/assets/web-panel/assets/{hasIn-BD9ZMGAl.js → hasIn-2vacgdcl.js} +1 -1
  95. package/src/assets/web-panel/assets/{index--N0u6kTG.js → index-B-C-Ruft.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-DzXjP44T.js → index-B7wDjYUd.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-CZBaqe3d.js → index-BMq0frKK.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-DrOalGut.js → index-BUX4W-2v.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-CT1_eRL-.js → index-BZz2eB33.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-DrsDA_md.js → index-BblNQlaA.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-DP-UZAQN.js → index-BdfKoqsK.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-DiT_REby.js → index-Bf8YofPE.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-Cx3Jn1r0.js → index-Bn8tARil.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-B0rkHxKK.js → index-Bpe2CJd-.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-B_G_ElKO.js → index-BxctzdYQ.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-MIg5Z8qe.js → index-C24NoPpy.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-BmNbU2Z6.js → index-C5C4kSi8.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-BsGmo6v1.js → index-C6ICn9Y6.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-CsrKJJcX.js → index-C8ldqZi6.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-BbX_Dted.js → index-C9WsM29I.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-Ch175NUw.js → index-CONPVaxw.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-DONOUtlz.js → index-CPyYXKFB.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-DFLE2qO9.js → index-CSvSf9px.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-o8pYehRq.js → index-CXmpR6N3.js} +3 -3
  115. package/src/assets/web-panel/assets/{index-Cz3unNfL.js → index-Chybe7Ge.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-yAGBu2E0.js → index-CyXmP3PW.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-CuSau5ya.js → index-DCusBOqR.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-DcE1BspQ.js → index-DH01oIaj.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-DrSAAuJj.js → index-DHg3LMNP.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-CZkFMeWL.js → index-DWLTSIka.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-DvKcroix.js → index-DaUGdvtU.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-Bjs90Eh9.js → index-DcA-tEQd.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-DGRxt5wj.js → index-DfWvcu4p.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-DCn-ECvK.js → index-DmZNnZz7.js} +1 -1
  125. package/src/assets/web-panel/assets/index-DvFfMAux.js +1 -0
  126. package/src/assets/web-panel/assets/{index-8qMA1DWQ.js → index-JsyGqKmD.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-D4bB_x_v.js → index-TtrpHmYx.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-Brqc9Emx.js → index-Ygh0wmKz.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-Da5fmOHB.js → index-dIYqw3f0.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-DpfisY1g.js → index-hDHHJYno.js} +1 -1
  131. package/src/assets/web-panel/assets/index-n6p-1A77.js +1 -0
  132. package/src/assets/web-panel/assets/{index-DeXNCyQJ.js → index-oElehY4F.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-DcbgVLOH.js → index-z4_YwZDW.js} +1 -1
  134. package/src/assets/web-panel/assets/{initDefaultProps-DMTkAomF.js → initDefaultProps-B9OXWu2e.js} +1 -1
  135. package/src/assets/web-panel/assets/{motion-Cnti1F5g.js → motion-IQ47MCDQ.js} +1 -1
  136. package/src/assets/web-panel/assets/{move-CGxmHUga.js → move-CLCU4kjV.js} +1 -1
  137. package/src/assets/web-panel/assets/{mtc-parser-CuwwLoq7.js → mtc-parser-CXnVlSPq.js} +1 -1
  138. package/src/assets/web-panel/assets/{omit-BpdlTkPM.js → omit-BJjLXB0f.js} +1 -1
  139. package/src/assets/web-panel/assets/{pickAttrs-D7nWrThp.js → pickAttrs-BHdtvdy6.js} +1 -1
  140. package/src/assets/web-panel/assets/{placementArrow-Bhx0TV8F.js → placementArrow-oq8X_Bwc.js} +1 -1
  141. package/src/assets/web-panel/assets/{responsiveObserve-CZ1KesZh.js → responsiveObserve-DTD02LAO.js} +1 -1
  142. package/src/assets/web-panel/assets/{slide-CnldF8J6.js → slide-DbEeq8to.js} +1 -1
  143. package/src/assets/web-panel/assets/{statusUtils-CZfo_GOA.js → statusUtils-Do2fy1CJ.js} +1 -1
  144. package/src/assets/web-panel/assets/{styleChecker-B2QCcAv5.js → styleChecker-CFWD63T-.js} +1 -1
  145. package/src/assets/web-panel/assets/{useFlexGapSupport-DzzjIS4J.js → useFlexGapSupport-BeozAWOo.js} +1 -1
  146. package/src/assets/web-panel/assets/{useFs-B_atg9M0.js → useFs-0-rIgnBL.js} +1 -1
  147. package/src/assets/web-panel/assets/{usePersonalDataHub-DhZs3QYN.js → usePersonalDataHub-CeiNoI31.js} +1 -1
  148. package/src/assets/web-panel/assets/{vnode-DcePTYAm.js → vnode-Dj0ReRNg.js} +1 -1
  149. package/src/assets/web-panel/assets/{zoom-BYmlnjRk.js → zoom-DD7MC4Dy.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-knowledge.js +40 -1
  155. package/src/commands/evolution.js +2 -0
  156. package/src/commands/governed-skill-marketplace.js +142 -0
  157. package/src/commands/marketplace.js +4 -1
  158. package/src/commands/serve.js +21 -0
  159. package/src/commands/skill.js +3 -0
  160. package/src/data/changelog.json +39 -0
  161. package/src/gateways/ws/ws-agent-handler.js +59 -2
  162. package/src/gateways/ws/ws-server.js +2 -0
  163. package/src/generated/cc-agent-protocol.schema.json +3 -1
  164. package/src/harness/golden-transcript.js +1 -0
  165. package/src/harness/prompt-compressor.js +51 -5
  166. package/src/harness/provider-backed-compaction.js +28 -1
  167. package/src/harness/remote-session-registry.js +15 -3
  168. package/src/index.js +20 -2
  169. package/src/lazy-dispatch.js +6 -0
  170. package/src/lib/advisor-runtime.js +55 -2
  171. package/src/lib/app-server/cli-agent-kernel-adapter.js +4 -0
  172. package/src/lib/app-server/graph-runtime.js +32 -0
  173. package/src/lib/app-server/server.js +94 -1
  174. package/src/lib/app-server/websocket-transport.js +15 -0
  175. package/src/lib/autonomous-agent.js +63 -13
  176. package/src/lib/cowork/ab-comparator-cli.js +4 -3
  177. package/src/lib/cowork/debate-review-cli.js +4 -3
  178. package/src/lib/cowork/decision-kb-cli.js +5 -0
  179. package/src/lib/cowork-adapter.js +38 -16
  180. package/src/lib/evolution/agent-evolution-ingress.js +95 -15
  181. package/src/lib/evolution/agent-evolution-runtime-composition.js +82 -0
  182. package/src/lib/evolution/agent-evolution-session-lifecycle.js +46 -0
  183. package/src/lib/evolution/agent-model-projection.js +437 -0
  184. package/src/lib/evolution/bounded-descriptor-read.js +29 -0
  185. package/src/lib/evolution/controlled-skill-pilot-ledger-adapter.js +551 -0
  186. package/src/lib/evolution/controlled-skill-production-pilot.js +308 -18
  187. package/src/lib/evolution/evidence-backed-wiki-maintainer.js +32 -10
  188. package/src/lib/evolution/evidence-json-text.js +236 -0
  189. package/src/lib/evolution/evolution-artifact-ports.js +196 -21
  190. package/src/lib/evolution/evolution-deployment-loader.js +240 -2
  191. package/src/lib/evolution/evolution-eval-child-evidence-ledger-adapter.js +373 -0
  192. package/src/lib/evolution/evolution-eval-gate.js +14 -1
  193. package/src/lib/evolution/evolution-eval-process-supervisor-worker.mjs +14 -0
  194. package/src/lib/evolution/evolution-eval-process-supervisor.js +607 -0
  195. package/src/lib/evolution/evolution-evidence-artifact-adapter.js +14 -1
  196. package/src/lib/evolution/evolution-evidence-projector.js +271 -37
  197. package/src/lib/evolution/evolution-file-witness.js +153 -30
  198. package/src/lib/evolution/evolution-ledger-ports.js +1219 -66
  199. package/src/lib/evolution/evolution-ledger.js +66 -2
  200. package/src/lib/evolution/evolution-raw-crypto-shred.js +29 -15
  201. package/src/lib/evolution/evolution-raw-deletion-ledger-adapter.js +865 -0
  202. package/src/lib/evolution/evolution-release-train-domain-stages.js +769 -0
  203. package/src/lib/evolution/evolution-release-train-stage-output-ledger-adapter.js +333 -0
  204. package/src/lib/evolution/evolution-release-train.js +54 -6
  205. package/src/lib/evolution/evolution-workbench-batch-executor.js +101 -144
  206. package/src/lib/evolution/evolution-workbench-control-ports.js +203 -0
  207. package/src/lib/evolution/evolution-workbench-file-resources.js +403 -0
  208. package/src/lib/evolution/evolution-workbench-projection.js +134 -26
  209. package/src/lib/evolution/evolution-workbench-registry-source.js +482 -0
  210. package/src/lib/evolution/evolution-workbench-review-ledger-adapter.js +823 -0
  211. package/src/lib/evolution/evolution-workbench-review-protocol.js +157 -0
  212. package/src/lib/evolution/evolution-workbench-rollback-authorization.js +57 -0
  213. package/src/lib/evolution/evolution-workbench-rollback-ledger-adapter.js +1016 -0
  214. package/src/lib/evolution/evolution-workbench-runtime.js +133 -0
  215. package/src/lib/evolution/evolution-workbench-version-control.js +70 -36
  216. package/src/lib/evolution/evolvable-artifact-ledger-adapter.js +48 -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-inventory.js +392 -0
  220. package/src/lib/evolution/governed-knowledge-dependency-ledger-executor.js +217 -82
  221. package/src/lib/evolution/governed-knowledge-quarantine-release.js +1013 -0
  222. package/src/lib/evolution/governed-knowledge-record.js +148 -0
  223. package/src/lib/evolution/governed-knowledge-revocation-host.js +59 -0
  224. package/src/lib/evolution/governed-knowledge-revocation-record.js +135 -0
  225. package/src/lib/evolution/governed-knowledge-skill-rollback.js +510 -0
  226. package/src/lib/evolution/governed-knowledge-sync.js +181 -95
  227. package/src/lib/evolution/governed-knowledge-wiki-tombstone.js +516 -0
  228. package/src/lib/evolution/governed-skill-marketplace-badge.js +208 -0
  229. package/src/lib/evolution/governed-skill-marketplace-candidate.js +330 -0
  230. package/src/lib/evolution/governed-skill-marketplace-cli-host.js +308 -0
  231. package/src/lib/evolution/governed-skill-marketplace-ledger-adapter.js +420 -0
  232. package/src/lib/evolution/governed-skill-marketplace.js +288 -5
  233. package/src/lib/evolution/governed-wiki-pruning-journal.js +302 -0
  234. package/src/lib/evolution/governed-wiki-pruning-ledger-adapter.js +459 -0
  235. package/src/lib/evolution/governed-wiki-pruning-maintenance.js +576 -0
  236. package/src/lib/evolution/governed-wiki-pruning-plan-authority.js +169 -0
  237. package/src/lib/evolution/governed-wiki-pruning-raw-shred.js +207 -0
  238. package/src/lib/evolution/governed-wiki-pruning-retrieval.js +587 -0
  239. package/src/lib/evolution/governed-wiki-pruning-runtime.js +153 -0
  240. package/src/lib/evolution/governed-wiki-pruning-skill-rollback.js +360 -0
  241. package/src/lib/evolution/governed-wiki-pruning.js +322 -143
  242. package/src/lib/evolution/independent-skill-revocation-source.js +231 -0
  243. package/src/lib/evolution/knowledge-wiki-source-admission.js +283 -0
  244. package/src/lib/evolution/knowledge-wiki-source-provenance.js +360 -0
  245. package/src/lib/evolution/progressive-canary-external-watchdog.js +578 -0
  246. package/src/lib/evolution/progressive-canary-traffic-worker.js +628 -0
  247. package/src/lib/evolution/progressive-canary-watchdog-file-store.js +285 -0
  248. package/src/lib/evolution/progressive-canary-watchdog-node-pki.js +265 -0
  249. package/src/lib/evolution/skill-candidate-registry.js +43 -3
  250. package/src/lib/evolution/skill-promotion-controller.js +25 -0
  251. package/src/lib/evolution/skill-promotion-review-ledger-adapter.js +100 -0
  252. package/src/lib/evolution/skill-registry-transition-ledger-adapter.js +131 -2
  253. package/src/lib/evolution/skill-release-registry.js +168 -4
  254. package/src/lib/evolution/skill-retrieval-revocation-authority.js +361 -0
  255. package/src/lib/evolution/skill-retrieval-revocation-ledger-adapter.js +346 -0
  256. package/src/lib/evolution/skill-revocation-propagation.js +467 -0
  257. package/src/lib/evolution/skill-target-matrix-eval.js +162 -11
  258. package/src/lib/evolution/skill-wiki-reconciliation.js +985 -0
  259. package/src/lib/evolution/skill-writer-inventory-manifest.js +8 -6
  260. package/src/lib/evolution/statistical-progressive-canary.js +165 -3
  261. package/src/lib/evolution/structured-memory-agent-control-plane.js +120 -0
  262. package/src/lib/evolution/structured-memory-authority-ledger-adapter.js +5 -1
  263. package/src/lib/evolution/structured-memory-promotion-receipt-writer.js +126 -0
  264. package/src/lib/evolution/wiki-informed-skill-proposer.js +127 -21
  265. package/src/lib/evolution/wiki-maintainer-ledger-adapter.js +822 -101
  266. package/src/lib/evolution/wiki-revision-protocol.js +120 -0
  267. package/src/lib/evolution/wiki-skill-proposal-ledger-adapter.js +307 -0
  268. package/src/lib/evolution/wiki-target-tombstone-revision.js +109 -0
  269. package/src/lib/evolution/wikiskill-benchmark-cli-host.js +178 -0
  270. package/src/lib/evolution/wikiskill-benchmark-execution-host.js +702 -0
  271. package/src/lib/evolution/wikiskill-benchmark-ledger-adapter.js +613 -0
  272. package/src/lib/evolution/wikiskill-benchmark.js +80 -16
  273. package/src/lib/goal-assess.js +17 -10
  274. package/src/lib/interactive-planner.js +9 -1
  275. package/src/lib/iteration-budget.js +16 -2
  276. package/src/lib/micro-compact.js +4 -1
  277. package/src/lib/model-failure-policy.js +21 -0
  278. package/src/lib/process-execution-broker/index.js +1 -0
  279. package/src/lib/process-execution-broker/windows-sandbox-helper.dll +0 -0
  280. package/src/lib/process-execution-broker/windows-sandbox-helper.exe +0 -0
  281. package/src/lib/process-execution-broker/windows-sandbox.cs +33 -15
  282. package/src/lib/read-file-loop-guard.js +113 -0
  283. package/src/lib/read-file-page.js +191 -0
  284. package/src/lib/runnable-provider.js +2 -1
  285. package/src/lib/skill-retrieval-router.js +22 -1
  286. package/src/repl/agent-repl.js +133 -34
  287. package/src/runtime/agent-core.js +196 -74
  288. package/src/runtime/agent-runtime.js +43 -0
  289. package/src/runtime/coding-agent-contract-shared.cjs +7 -1
  290. package/src/runtime/fallback-model.js +143 -62
  291. package/src/runtime/headless-runner.js +54 -10
  292. package/src/runtime/headless-stream.js +50 -6
  293. package/src/runtime/runtime-factory.js +41 -2
  294. package/src/assets/web-panel/assets/ChatBubbleRenderer-Ds3pA-ET.js +0 -1
  295. package/src/assets/web-panel/assets/MarkdownRenderer-DqTx7_u1.js +0 -1
  296. package/src/assets/web-panel/assets/devWarning-CF3xafX2.js +0 -1
  297. package/src/assets/web-panel/assets/index-C907rPwd.js +0 -1
  298. package/src/assets/web-panel/assets/index-wueRSK2d.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");
61
- }
62
- return revision;
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
+ );
105
+ }
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,802 @@ 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
+ readInventory: () => this.#readInventory(),
166
+ readRevision: (input) => this.#readRevision(input),
167
+ readKnowledgeProvenance: (input) =>
168
+ this.#readKnowledgeProvenance(input),
169
+ readStateRevision: (input) => this.#readStateRevision(input),
170
+ findStateRevision: (input) => this.#readStateRevision(input, false),
171
+ resolveHistory: (input) => this.#resolveHistory(input),
172
+ resolveAtCheckpoint: (input) => this.#resolveHistory(input, true),
173
+ }),
174
+ );
175
+ }
176
+
177
+ #history({
178
+ sourceDigest = null,
179
+ allowed = [],
180
+ checkpoint = null,
181
+ inventory = false,
182
+ revisionId = null,
183
+ stateRevisionDigest = null,
184
+ } = {}) {
185
+ // read() already authenticates its snapshot. Resolve against that snapshot's
186
+ // identity, then compare the entire event range with a fresh authority head.
187
+ // This avoids a redundant pre-read scan without caching authorization.
188
+ const events = this.#readLedger({ limit: EVOLUTION_LEDGER_MAX_EVENTS });
189
+ if (!Array.isArray(events) || events.length > EVOLUTION_LEDGER_MAX_EVENTS)
190
+ fail(
191
+ WIKI_LEDGER_CORRUPT_CODE,
192
+ "EvolutionLedger read did not return events",
193
+ );
194
+ const tail = events.at(-1);
195
+ if (checkpoint) {
196
+ const boundary = events[checkpoint.sequence - 1];
197
+ if (
198
+ !boundary ||
199
+ ["epoch", "ledgerId", "identityDigest"].some(
200
+ (key) => checkpoint[key] !== boundary[key],
201
+ ) ||
202
+ checkpoint.headDigest !== boundary.eventDigest
203
+ ) {
204
+ fail(
205
+ WIKI_LEDGER_CONFLICT_CODE,
206
+ "Wiki checkpoint is not in this authenticated ledger",
207
+ );
208
+ }
209
+ }
210
+ if (
211
+ tail &&
212
+ (typeof tail.epoch !== "string" ||
213
+ typeof tail.ledgerId !== "string" ||
214
+ !DIGEST.test(tail.identityDigest ?? "") ||
215
+ !DIGEST.test(tail.eventDigest ?? "") ||
216
+ events.some(
217
+ (event, index) =>
218
+ event.sequence !== index + 1 ||
219
+ event.epoch !== tail.epoch ||
220
+ event.ledgerId !== tail.ledgerId ||
221
+ event.identityDigest !== tail.identityDigest,
222
+ ))
223
+ ) {
224
+ fail(
225
+ WIKI_LEDGER_CORRUPT_CODE,
226
+ "Wiki ledger read has incomplete sequence or identity bindings",
227
+ );
228
+ }
229
+ const matches = events.filter(
230
+ (event) =>
231
+ event.schema === EVOLUTION_LEDGER_DOMAIN_EVENT_SCHEMA &&
232
+ event.type === WIKI_LEDGER_EVENT_TYPE &&
233
+ event.tenantId === this.descriptor.tenantId &&
234
+ event.correlationId === this.descriptor.evolutionRunId,
235
+ );
236
+ const tenantWikiRunIds = [
237
+ ...new Set(
238
+ events
239
+ .filter(
240
+ (event) =>
241
+ event.schema === EVOLUTION_LEDGER_DOMAIN_EVENT_SCHEMA &&
242
+ event.type === WIKI_LEDGER_EVENT_TYPE &&
243
+ event.tenantId === this.descriptor.tenantId,
244
+ )
245
+ .map((event) => requiredString(event.correlationId, "correlationId")),
246
+ ),
247
+ ].sort();
248
+ let state = createEmptyWikiState(this.descriptor.tenantId);
249
+ let viewState = state;
250
+ let latest = null;
251
+ let selectedRevision = null;
252
+ let source = sourceDigest === digestWikiState(state) ? state : null;
253
+ const successors = [];
254
+ const revisions = [];
255
+ let retainedBytes = 0;
256
+ let batch = [];
257
+ for (const [index, event] of matches.entries()) {
258
+ const previous = latest;
259
+ if (
260
+ !Number.isSafeInteger(event.sequence) ||
261
+ event.sequence <= (previous?.event.sequence ?? 0) ||
262
+ event.artifactTenantId !== this.descriptor.artifactTenantId ||
263
+ event.decision !== "committed" ||
264
+ event.skillName !== null ||
265
+ !Array.isArray(event.sourceRefs) ||
266
+ digestWikiState(event.sourceRefs) !==
267
+ digestWikiState(previous ? [previous.event.subjectRef] : [])
268
+ ) {
269
+ fail(WIKI_LEDGER_CORRUPT_CODE, "Wiki ledger event lineage is invalid");
270
+ }
271
+ // Four revisions at most (4 MiB of payload), retained only while this
272
+ // synchronous chunk is checked. Full index readback and fresh authority
273
+ // remain inside each batch; no snapshot survives this history read.
274
+ if (index % 4 === 0)
275
+ batch = this.#resolveArtifactBatch(
276
+ matches.slice(index, index + 4).map((item) => ({
277
+ epoch: tail.epoch,
278
+ ledgerId: tail.ledgerId,
279
+ ref: item.subjectRef,
280
+ tenantId: this.descriptor.artifactTenantId,
281
+ })),
282
+ );
283
+ const revision = this.#resolveEvent(event, tail, batch[index % 4]);
284
+ const inView =
285
+ checkpoint === null || event.sequence <= checkpoint.sequence;
286
+ // Before durable maintenance requests, v1 genesis did not contain that
287
+ // map. Accept only the exact known legacy genesis, never an arbitrary
288
+ // caller-supplied predecessor or a modern revision with missing fields.
289
+ if (
290
+ !previous &&
291
+ !Object.hasOwn(revision, "maintenanceRequestId") &&
292
+ !Object.hasOwn(revision.state, "maintenanceRequests") &&
293
+ revision.priorStateDigest !== digestWikiState(state)
294
+ ) {
295
+ const legacyGenesis = {
296
+ ...createEmptyWikiState(this.descriptor.tenantId),
297
+ };
298
+ delete legacyGenesis.maintenanceRequests;
299
+ if (revision.priorStateDigest === digestWikiState(legacyGenesis)) {
300
+ state = freeze(legacyGenesis);
301
+ if (inView) {
302
+ viewState = state;
303
+ source = sourceDigest === revision.priorStateDigest ? state : null;
304
+ }
305
+ }
306
+ }
307
+ if (
308
+ revision.revision !== state.revision + 1 ||
309
+ revision.priorStateDigest !== digestWikiState(state) ||
310
+ event.eventId !== `wiki.revision.${revision.revisionId.slice(5)}` ||
311
+ event.timestamp !== revision.effectiveAt
312
+ ) {
313
+ fail(
314
+ WIKI_LEDGER_CORRUPT_CODE,
315
+ "Wiki revision does not extend its authenticated predecessor",
316
+ );
317
+ }
318
+ verifyRequestTransition(state, revision);
319
+ if (inventory) {
320
+ const wikiSourceRevisionIds = [
321
+ ...new Set(
322
+ Object.values(revision.state.evidence)
323
+ .flatMap((entry) => [entry.ref, entry.artifactRef])
324
+ .filter(
325
+ (ref) =>
326
+ typeof ref === "string" &&
327
+ ref.startsWith(`wiki-source://${this.descriptor.tenantId}/wiki:`),
328
+ )
329
+ .map((ref) => ref.slice(ref.lastIndexOf("/") + 1)),
330
+ ),
331
+ ].sort();
332
+ revisions.push(
333
+ freeze({
334
+ revision: revision.revision,
335
+ revisionId: revision.revisionId,
336
+ priorStateDigest: revision.priorStateDigest,
337
+ stateDigest: revision.stateDigest,
338
+ artifactRef: event.subjectRef,
339
+ wikiSourceRevisionIds,
340
+ checkpoint: {
341
+ epoch: event.epoch,
342
+ ledgerId: event.ledgerId,
343
+ identityDigest: event.identityDigest,
344
+ sequence: event.sequence,
345
+ headDigest: event.eventDigest,
346
+ },
347
+ }),
348
+ );
349
+ }
350
+ if (
351
+ revision.revisionId === revisionId ||
352
+ revision.stateDigest === stateRevisionDigest
353
+ ) {
354
+ if (selectedRevision)
355
+ fail(WIKI_LEDGER_CORRUPT_CODE, "Wiki revision identity is ambiguous");
356
+ selectedRevision = {
357
+ trusted: true,
358
+ state: revision.state,
359
+ stateDigest: revision.stateDigest,
360
+ revisionId: revision.revisionId,
361
+ checkpoint: {
362
+ epoch: event.epoch,
363
+ ledgerId: event.ledgerId,
364
+ identityDigest: event.identityDigest,
365
+ sequence: event.sequence,
366
+ headDigest: event.eventDigest,
367
+ },
368
+ artifactRef: event.subjectRef,
369
+ };
370
+ }
371
+ if (source && inView) {
372
+ if (
373
+ !revision.maintenanceRequestDigest ||
374
+ revision.maintenanceRequestDigest !== allowed[successors.length]
375
+ ) {
376
+ fail(
377
+ WIKI_LEDGER_CONFLICT_CODE,
378
+ "Wiki has successors outside the authorized maintenance sequence",
379
+ );
380
+ }
381
+ retainedBytes += Buffer.byteLength(JSON.stringify(revision), "utf8");
382
+ if (retainedBytes > 8 * EVOLUTION_ARTIFACT_MAX_CANONICAL_BYTES) {
383
+ fail(
384
+ WIKI_LEDGER_CORRUPT_CODE,
385
+ "Wiki successor history exceeds its retained byte budget",
386
+ );
387
+ }
388
+ successors.push({
389
+ revision,
390
+ eventDigest: event.eventDigest,
391
+ artifactRef: event.subjectRef,
392
+ predecessorHead: {
393
+ epoch: event.epoch,
394
+ ledgerId: event.ledgerId,
395
+ identityDigest: event.identityDigest,
396
+ sequence: event.sequence - 1,
397
+ headDigest: event.prevDigest,
398
+ },
399
+ });
400
+ } else if (inView && sourceDigest === revision.stateDigest) {
401
+ source = revision.state;
402
+ }
403
+ if (inView) viewState = revision.state;
404
+ latest = { event, revision };
405
+ state = revision.state;
406
+ }
407
+ const head = this.#verifyLedger();
408
+ if (
409
+ head.sequence !== events.length ||
410
+ head.headDigest !== (tail?.eventDigest ?? null) ||
411
+ (tail &&
412
+ ["identityDigest", "epoch", "ledgerId"].some(
413
+ (key) => tail[key] !== head[key],
414
+ ))
415
+ ) {
416
+ fail(
417
+ WIKI_LEDGER_CONFLICT_CODE,
418
+ "Wiki ledger changed while authenticating history",
419
+ );
420
+ }
421
+ return {
422
+ head,
423
+ latest,
424
+ state,
425
+ viewState,
426
+ source,
427
+ successors,
428
+ selectedRevision,
429
+ revisions,
430
+ tenantWikiRunIds,
431
+ };
432
+ }
433
+
434
+ #readInventory() {
435
+ const { head, revisions, tenantWikiRunIds } = this.#history({
436
+ inventory: true,
437
+ });
438
+ return freeze({
439
+ authenticated: true,
440
+ descriptor: this.descriptor,
441
+ ledgerHead: head,
442
+ revisions,
443
+ tenantWikiRunIds,
444
+ });
445
+ }
446
+
447
+ #readKnowledgeProvenance({
448
+ tenantId,
449
+ revisionId,
450
+ knowledgeId,
451
+ contentDigest,
452
+ } = {}) {
453
+ if (
454
+ tenantId !== this.descriptor.tenantId ||
455
+ !REVISION_ID.test(revisionId ?? "") ||
456
+ typeof knowledgeId !== "string" ||
457
+ !/^[A-Za-z0-9][A-Za-z0-9._:@/-]{0,255}$/u.test(knowledgeId) ||
458
+ !DIGEST.test(contentDigest ?? "")
459
+ )
460
+ throw new TypeError(
461
+ "Wiki Knowledge provenance requires exact source identities",
462
+ );
463
+ const events = this.#readLedger({ limit: EVOLUTION_LEDGER_MAX_EVENTS });
464
+ const tail = Array.isArray(events) ? events.at(-1) : null;
465
+ if (
466
+ !tail ||
467
+ events.length > EVOLUTION_LEDGER_MAX_EVENTS ||
468
+ events.some(
469
+ (event, index) =>
470
+ event.sequence !== index + 1 ||
471
+ ["epoch", "ledgerId", "identityDigest"].some(
472
+ (key) => event[key] !== tail[key],
473
+ ),
474
+ )
475
+ )
476
+ fail(
477
+ WIKI_LEDGER_CORRUPT_CODE,
478
+ "Wiki provenance event range is incomplete",
479
+ );
480
+ const selected = events.find(
481
+ (event) =>
482
+ event.eventId === `wiki.revision.${revisionId.slice(5)}` &&
483
+ event.tenantId === tenantId,
484
+ );
485
+ const sources = events.filter(
486
+ (event) =>
487
+ event.type === WIKI_LEDGER_EVENT_TYPE &&
488
+ event.tenantId === tenantId &&
489
+ event.sequence <= (selected?.sequence ?? 0),
490
+ );
491
+ const positions = new Map(
492
+ sources.map((event, index) => [event.sequence, index]),
493
+ );
494
+ // Same bounded four-subject read as normal Wiki history. Retain no proof
495
+ // across calls and never resolve a future revision as an earlier source.
496
+ let batchStart = -1;
497
+ let batch = [];
498
+ const proof = resolveKnowledgeWikiSourceProvenance({
499
+ events,
500
+ descriptor: this.descriptor,
501
+ revisionId,
502
+ knowledge: { knowledgeId, contentDigest },
503
+ resolveSubject: (event) => {
504
+ const position = positions.get(event.sequence);
505
+ const start = position - (position % 4);
506
+ if (start !== batchStart) {
507
+ batch = this.#resolveArtifactBatch(
508
+ sources.slice(start, start + 4).map((item) => ({
509
+ epoch: tail.epoch,
510
+ ledgerId: tail.ledgerId,
511
+ tenantId: this.descriptor.artifactTenantId,
512
+ ref: item.subjectRef,
513
+ })),
514
+ );
515
+ batchStart = start;
516
+ }
517
+ const resolution = batch[position - start];
518
+ if (
519
+ resolution?.schema !== EVOLUTION_ARTIFACT_RESOLUTION_SCHEMA ||
520
+ resolution.authenticated !== true ||
521
+ resolution.found !== true ||
522
+ resolution.ref !== event.subjectRef.ref ||
523
+ resolution.digest !== event.subjectRef.digest ||
524
+ !DIGEST.test(resolution.receiptDigest ?? "") ||
525
+ !Buffer.isBuffer(resolution.bytes) ||
526
+ resolution.bytes.length > EVOLUTION_ARTIFACT_MAX_CANONICAL_BYTES ||
527
+ `sha256:${createHash("sha256").update(resolution.bytes).digest("hex")}` !==
528
+ event.subjectRef.digest
529
+ )
530
+ fail(
531
+ WIKI_LEDGER_CORRUPT_CODE,
532
+ "Wiki provenance subject is not authenticated and exactly bound",
533
+ );
534
+ return resolution.bytes;
535
+ },
536
+ });
537
+ const head = this.#verifyLedger();
538
+ if (
539
+ head.sequence !== events.length ||
540
+ head.headDigest !== tail.eventDigest ||
541
+ ["epoch", "ledgerId", "identityDigest"].some(
542
+ (key) => head[key] !== tail[key],
543
+ )
544
+ )
545
+ fail(
546
+ WIKI_LEDGER_CONFLICT_CODE,
547
+ "Wiki ledger changed while authenticating source provenance",
548
+ );
549
+ return freeze({
550
+ authenticated: true,
551
+ tenantId,
552
+ ...proof,
553
+ ledgerHead: head,
554
+ });
87
555
  }
88
556
 
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);
557
+ // Immutable provenance, not an authorization to use an obsolete Wiki as current.
558
+ // Authenticate the full present history, retaining only the selected revision.
559
+ #readRevision({ tenantId, revisionId } = {}) {
560
+ if (
561
+ tenantId !== this.descriptor.tenantId ||
562
+ !REVISION_ID.test(revisionId ?? "")
563
+ )
564
+ throw new TypeError(
565
+ "Wiki provenance requires an exact tenant and revisionId",
566
+ );
567
+ const { head, selectedRevision } = this.#history({ revisionId });
568
+ if (!selectedRevision)
569
+ fail(
570
+ WIKI_LEDGER_CONFLICT_CODE,
571
+ "Wiki revision is not in authenticated history",
572
+ );
573
+ return freeze({
574
+ authenticated: true,
575
+ tenantId,
576
+ evolutionRunId: this.descriptor.evolutionRunId,
577
+ ...selectedRevision,
578
+ ledgerHead: head,
579
+ });
95
580
  }
96
581
 
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,
582
+ // Content-addressed original state lookup, without authorizing intervening
583
+ // changes. Effect consumers still replay their exact permitted successors.
584
+ #readStateRevision({ tenantId, stateDigest } = {}, required = true) {
585
+ if (
586
+ tenantId !== this.descriptor.tenantId ||
587
+ !DIGEST.test(stateDigest ?? "")
588
+ )
589
+ throw new TypeError(
590
+ "Wiki source requires an exact tenant and state digest",
591
+ );
592
+ const { head, selectedRevision } = this.#history({
593
+ stateRevisionDigest: stateDigest,
594
+ });
595
+ // A scoped lookup may prove absence only after authenticating the complete
596
+ // run. Corrupt/missing bytes and concurrent ledger changes still throw.
597
+ if (!selectedRevision && !required) return null;
598
+ if (!selectedRevision)
599
+ fail(
600
+ WIKI_LEDGER_CONFLICT_CODE,
601
+ "Wiki state revision is not in authenticated history",
602
+ );
603
+ return freeze({
604
+ authenticated: true,
605
+ tenantId,
606
+ evolutionRunId: this.descriptor.evolutionRunId,
607
+ ...selectedRevision,
608
+ ledgerHead: head,
104
609
  });
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");
610
+ }
611
+
612
+ #resolveEvent(event, authority, capturedResolution = null) {
613
+ const resolution =
614
+ capturedResolution ??
615
+ this.#resolveArtifact({
616
+ epoch: authority.epoch,
617
+ ledgerId: authority.ledgerId,
618
+ ref: event.subjectRef,
619
+ tenantId: this.descriptor.artifactTenantId,
620
+ });
621
+ if (
622
+ resolution?.ref !== event.subjectRef.ref ||
623
+ resolution.digest !== event.subjectRef.digest
624
+ ) {
625
+ fail(
626
+ WIKI_LEDGER_CORRUPT_CODE,
627
+ "Wiki ledger event resolved a substituted artifact",
628
+ );
107
629
  }
108
630
  return parseRecord(resolution, this.descriptor);
109
631
  }
110
632
 
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");
633
+ loadWiki = () => this.#loadWiki();
634
+
635
+ #loadWiki() {
636
+ const { state } = this.#history();
637
+ return freeze({
638
+ trusted: true,
639
+ state,
640
+ stateDigest: digestWikiState(state),
641
+ });
642
+ }
643
+
644
+ resolveHistory(input) {
645
+ return this.#resolveHistory(input);
646
+ }
647
+
648
+ resolveAtCheckpoint(input) {
649
+ return this.#resolveHistory(input, true);
650
+ }
651
+
652
+ // Provenance only: callers must authorize the plan and independently check
653
+ // the successor's actual operation/state, not treat a request digest as an
654
+ // effect receipt. Allowed digests describe an ordered prefix, not a set.
655
+ #resolveHistory(
656
+ {
657
+ tenantId,
658
+ stateDigest,
659
+ allowedMaintenanceRequestDigests = [],
660
+ checkpoint = null,
661
+ } = {},
662
+ historical = false,
663
+ ) {
664
+ if (historical) {
665
+ const fields = [
666
+ "epoch",
667
+ "ledgerId",
668
+ "identityDigest",
669
+ "sequence",
670
+ "headDigest",
671
+ ];
672
+ if (
673
+ !checkpoint ||
674
+ typeof checkpoint !== "object" ||
675
+ Array.isArray(checkpoint) ||
676
+ Object.keys(checkpoint).length !== fields.length ||
677
+ fields.some((key) => !Object.hasOwn(checkpoint, key)) ||
678
+ typeof checkpoint.epoch !== "string" ||
679
+ typeof checkpoint.ledgerId !== "string" ||
680
+ !DIGEST.test(checkpoint.identityDigest ?? "") ||
681
+ !DIGEST.test(checkpoint.headDigest ?? "") ||
682
+ !Number.isSafeInteger(checkpoint.sequence) ||
683
+ checkpoint.sequence < 1 ||
684
+ checkpoint.sequence > EVOLUTION_LEDGER_MAX_EVENTS
685
+ ) {
686
+ throw new TypeError(
687
+ "Wiki historical read requires an exact authenticated checkpoint",
688
+ );
689
+ }
690
+ checkpoint = Object.freeze({ ...checkpoint });
691
+ } else if (checkpoint !== null) {
692
+ throw new TypeError(
693
+ "current Wiki history cannot be downgraded to a checkpoint view",
694
+ );
695
+ }
696
+ if (
697
+ tenantId !== this.descriptor.tenantId ||
698
+ !DIGEST.test(stateDigest ?? "") ||
699
+ !Array.isArray(allowedMaintenanceRequestDigests) ||
700
+ allowedMaintenanceRequestDigests.length > 128
701
+ ) {
702
+ throw new TypeError(
703
+ "Wiki history requires an exact tenant, baseline, and bounded request sequence",
704
+ );
705
+ }
706
+ const allowed = [];
707
+ const length = allowedMaintenanceRequestDigests.length;
708
+ for (let index = 0; index < length; index += 1) {
709
+ const value = allowedMaintenanceRequestDigests[index];
710
+ if (!DIGEST.test(value ?? "") || allowed.includes(value)) {
711
+ throw new TypeError(
712
+ "Wiki history request digests must be unique and dense",
713
+ );
117
714
  }
715
+ allowed.push(value);
118
716
  }
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");
717
+ const { head, viewState, source, successors } = this.#history({
718
+ sourceDigest: stateDigest,
719
+ allowed,
720
+ checkpoint,
721
+ });
722
+ if (!source) {
723
+ fail(
724
+ WIKI_LEDGER_CONFLICT_CODE,
725
+ "Wiki baseline is not in authenticated history",
726
+ );
123
727
  }
124
- return { event, revision };
728
+ return freeze({
729
+ authenticated: true,
730
+ tenantId,
731
+ evolutionRunId: this.descriptor.evolutionRunId,
732
+ source: { trusted: true, state: source, stateDigest },
733
+ current: {
734
+ trusted: true,
735
+ state: viewState,
736
+ stateDigest: digestWikiState(viewState),
737
+ },
738
+ successors,
739
+ ledgerHead: head,
740
+ scope: historical ? "checkpoint" : "current",
741
+ checkpoint,
742
+ });
125
743
  }
126
744
 
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 ?? "")) {
745
+ commitRevision = ({
746
+ expectedStateDigest,
747
+ revision,
748
+ expectedLedgerHead,
749
+ } = {}) => {
750
+ const headKeys = [
751
+ "epoch",
752
+ "ledgerId",
753
+ "identityDigest",
754
+ "sequence",
755
+ "headDigest",
756
+ ];
757
+ if (expectedLedgerHead !== undefined) {
758
+ if (
759
+ !expectedLedgerHead ||
760
+ typeof expectedLedgerHead !== "object" ||
761
+ Array.isArray(expectedLedgerHead) ||
762
+ Object.keys(expectedLedgerHead).length !== headKeys.length ||
763
+ headKeys.some((key) => !Object.hasOwn(expectedLedgerHead, key)) ||
764
+ typeof expectedLedgerHead.epoch !== "string" ||
765
+ typeof expectedLedgerHead.ledgerId !== "string" ||
766
+ !DIGEST.test(expectedLedgerHead.identityDigest ?? "") ||
767
+ !Number.isSafeInteger(expectedLedgerHead.sequence) ||
768
+ expectedLedgerHead.sequence < 0 ||
769
+ (expectedLedgerHead.sequence === 0
770
+ ? expectedLedgerHead.headDigest !== null
771
+ : !DIGEST.test(expectedLedgerHead.headDigest ?? ""))
772
+ ) {
773
+ throw new TypeError("Wiki expected ledger head is invalid");
774
+ }
775
+ expectedLedgerHead = Object.freeze({ ...expectedLedgerHead });
776
+ }
777
+ if (
778
+ !DIGEST.test(expectedStateDigest ?? "") ||
779
+ revision?.schema !== WIKI_REVISION_SCHEMA ||
780
+ revision.tenantId !== this.descriptor.tenantId ||
781
+ revision.evolutionRunId !== this.descriptor.evolutionRunId ||
782
+ revision.stateDigest !== digestWikiState(revision.state) ||
783
+ revision.state.revisionId !== revision.revisionId ||
784
+ !REVISION_ID.test(revision.revisionId ?? "")
785
+ ) {
138
786
  throw new TypeError("Wiki revision commit request is invalid");
139
787
  }
140
- const latest = this._latest();
141
- const currentState = latest?.revision.state ?? createEmptyWikiState(this.descriptor.tenantId);
788
+ // Own the revision before handing it to any persistence callback.
789
+ revision = freeze(
790
+ structuredClone(verifyRevision(revision, this.descriptor)),
791
+ );
792
+ const { head, latest, state: currentState } = this.#history();
793
+ if (
794
+ expectedLedgerHead &&
795
+ headKeys.some((key) => expectedLedgerHead[key] !== head[key])
796
+ ) {
797
+ fail(
798
+ WIKI_LEDGER_CONFLICT_CODE,
799
+ "Wiki authorization ledger head changed before revision commit",
800
+ );
801
+ }
142
802
  const currentDigest = digestWikiState(currentState);
143
803
  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 });
804
+ if (
805
+ latest?.revision.revisionId === revision.revisionId &&
806
+ currentDigest === revision.stateDigest
807
+ ) {
808
+ return Object.freeze({
809
+ committed: true,
810
+ recovered: true,
811
+ revisionId: revision.revisionId,
812
+ stateDigest: revision.stateDigest,
813
+ evolutionRunId: this.descriptor.evolutionRunId,
814
+ });
147
815
  }
148
- fail(WIKI_LEDGER_CONFLICT_CODE, "Wiki state changed before revision commit");
816
+ fail(
817
+ WIKI_LEDGER_CONFLICT_CODE,
818
+ "Wiki state changed before revision commit",
819
+ );
149
820
  }
150
- if (revision.revision !== currentState.revision + 1 || revision.priorStateDigest !== currentDigest) {
151
- fail(WIKI_LEDGER_CONFLICT_CODE, "Wiki revision does not extend the current state");
821
+ if (
822
+ revision.revision !== currentState.revision + 1 ||
823
+ revision.priorStateDigest !== currentDigest
824
+ ) {
825
+ fail(
826
+ WIKI_LEDGER_CONFLICT_CODE,
827
+ "Wiki revision does not extend the current state",
828
+ );
152
829
  }
153
- const head = this._verifyLedger();
154
- const published = this._putCanonical("wiki-revision", revision, {
830
+ verifyRequestTransition(currentState, revision);
831
+ const published = this.#putCanonical("wiki-revision", revision, {
155
832
  audience: this.descriptor.audience,
156
833
  purpose: this.descriptor.purpose,
157
834
  retention: "ledger",
158
835
  });
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");
836
+ if (
837
+ !published?.ref ||
838
+ published.receipt?.persisted !== true ||
839
+ published.receipt?.readbackVerified !== true ||
840
+ published.receipt?.integrityVerified !== true ||
841
+ published.receipt?.retention !== "ledger"
842
+ ) {
843
+ fail(
844
+ WIKI_LEDGER_CORRUPT_CODE,
845
+ "Wiki revision artifact was not durably read back",
846
+ );
162
847
  }
163
848
  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 });
849
+ const receipt = this.#appendDomainEvent(
850
+ {
851
+ artifactTenantId: this.descriptor.artifactTenantId,
852
+ correlationId: this.descriptor.evolutionRunId,
853
+ decision: "committed",
854
+ eventId,
855
+ reason: `wiki revision ${revision.revision} committed`,
856
+ skillName: null,
857
+ sourceRefs: latest ? [latest.event.subjectRef] : [],
858
+ subjectRef: published.ref,
859
+ tenantId: this.descriptor.tenantId,
860
+ timestamp: revision.effectiveAt,
861
+ type: WIKI_LEDGER_EVENT_TYPE,
862
+ },
863
+ { expectedHeadDigest: head.headDigest, expectedSequence: head.sequence },
864
+ );
865
+ if (
866
+ receipt?.authenticated !== true ||
867
+ receipt?.committed !== true ||
868
+ receipt?.durable !== true ||
869
+ receipt.eventId !== eventId ||
870
+ !DIGEST.test(receipt.receiptDigest ?? "")
871
+ ) {
872
+ fail(
873
+ WIKI_LEDGER_CORRUPT_CODE,
874
+ "Wiki ledger did not confirm a durable authenticated append",
875
+ );
876
+ }
877
+ const stored = this.#history().latest;
878
+ if (
879
+ stored?.revision.revisionId !== revision.revisionId ||
880
+ stored.revision.stateDigest !== revision.stateDigest
881
+ ) {
882
+ fail(
883
+ WIKI_LEDGER_CORRUPT_CODE,
884
+ "Wiki revision readback differs after ledger commit",
885
+ );
886
+ }
887
+ return Object.freeze({
888
+ committed: true,
889
+ recovered: false,
890
+ revisionId: revision.revisionId,
891
+ stateDigest: revision.stateDigest,
892
+ evolutionRunId: this.descriptor.evolutionRunId,
893
+ ledgerReceiptDigest: receipt.receiptDigest,
894
+ });
188
895
  };
189
896
 
190
897
  maintainerPorts({ resolveEvidence, derive } = {}) {
191
898
  if (typeof resolveEvidence !== "function" || typeof derive !== "function") {
192
899
  throw new TypeError("resolveEvidence and derive ports are required");
193
900
  }
194
- return Object.freeze({ loadWiki: this.loadWiki, commitRevision: this.commitRevision, resolveEvidence, derive });
901
+ return Object.freeze({
902
+ loadWiki: () => this.#loadWiki(),
903
+ commitRevision: this.commitRevision,
904
+ resolveEvidence,
905
+ derive,
906
+ });
195
907
  }
196
908
  }
197
909
 
910
+ export function captureWikiRevisionReader(adapter) {
911
+ const reader = READERS.get(adapter);
912
+ if (!reader)
913
+ throw new TypeError(
914
+ "a branded WikiMaintainerLedgerAdapter reader is required",
915
+ );
916
+ return reader;
917
+ }
918
+
198
919
  export function createWikiMaintainerLedgerAdapter(options) {
199
920
  return new WikiMaintainerLedgerAdapter(options);
200
921
  }