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,4 +1,12 @@
1
1
  import { createHash } from "node:crypto";
2
+ import { captureWikiPruningJournalStore } from "./governed-wiki-pruning-ledger-adapter.js";
3
+ import {
4
+ GOVERNED_WIKI_PRUNING_PLAN_SCHEMA,
5
+ GOVERNED_WIKI_PRUNING_POLICY_SCHEMA,
6
+ buildWikiPruningJournal,
7
+ pruningOperationCalls,
8
+ verifyPruningJournalPlan,
9
+ } from "./governed-wiki-pruning-journal.js";
2
10
 
3
11
  import {
4
12
  WIKI_PATTERN_STATUS,
@@ -6,8 +14,7 @@ import {
6
14
  digestWikiState,
7
15
  } from "./evidence-backed-wiki-maintainer.js";
8
16
 
9
- export const GOVERNED_WIKI_PRUNING_PLAN_SCHEMA =
10
- "chainlesschain.governed-wiki-pruning-plan/v1";
17
+ export { GOVERNED_WIKI_PRUNING_PLAN_SCHEMA } from "./governed-wiki-pruning-journal.js";
11
18
  export const GOVERNED_WIKI_PRUNING_CONTROL_SCHEMA =
12
19
  "chainlesschain.governed-wiki-pruning-control/v1";
13
20
  export const GOVERNED_ONLINE_ADAPTATION_AUTHORIZATION_SCHEMA =
@@ -112,17 +119,7 @@ function verifiedAt(pattern) {
112
119
  }
113
120
 
114
121
  function assertPlan(plan, tenantId) {
115
- if (
116
- plan?.schema !== GOVERNED_WIKI_PRUNING_PLAN_SCHEMA ||
117
- plan.tenantId !== tenantId ||
118
- !DIGEST.test(plan?.planDigest ?? "")
119
- )
120
- throw new TypeError("Wiki pruning plan is invalid");
121
- const core = clone(plan);
122
- delete core.planDigest;
123
- if (hash(GOVERNED_WIKI_PRUNING_PLAN_SCHEMA, core) !== plan.planDigest)
124
- throw new Error("Wiki pruning plan digest is invalid");
125
- return freeze(clone(plan));
122
+ return verifyPruningJournalPlan(plan, tenantId);
126
123
  }
127
124
 
128
125
  function operationRequest(plan, operation, payload) {
@@ -153,9 +150,156 @@ function requireDurableAck(result, requestDigest, label) {
153
150
  return result.receiptDigest;
154
151
  }
155
152
 
153
+ export function createWikiPruningPlanner({ descriptor: input, ports } = {}) {
154
+ const descriptor = normalizeDescriptor(input);
155
+ const captured = {};
156
+ for (const name of ["loadWikiState", "resolveDeletionReceipt"]) {
157
+ if (typeof ports?.[name] !== "function")
158
+ throw new TypeError(`Wiki pruning planner port ${name} is required`);
159
+ captured[name] = ports[name].bind(ports);
160
+ }
161
+ Object.freeze(captured);
162
+ return Object.freeze({
163
+ descriptor,
164
+ plan: (input) => buildPruningPlan(descriptor, captured, input),
165
+ });
166
+ }
167
+
168
+ async function buildPruningPlan(
169
+ descriptor,
170
+ ports,
171
+ { expectedStateDigest, effectiveAt, deletionReceiptDigests = [] },
172
+ ) {
173
+ digest(expectedStateDigest, "expectedStateDigest");
174
+ time(effectiveAt, "effectiveAt");
175
+ const receiptDigests = boundedUniqueStrings(
176
+ deletionReceiptDigests,
177
+ "deletionReceiptDigests",
178
+ descriptor.maxActions,
179
+ );
180
+ receiptDigests.forEach((value) => digest(value, "deletionReceiptDigest"));
181
+ const state = verifyStateEnvelope(
182
+ await ports.loadWikiState({ tenantId: descriptor.tenantId }),
183
+ descriptor.tenantId,
184
+ expectedStateDigest,
185
+ );
186
+ const cutoff =
187
+ Date.parse(effectiveAt) - descriptor.staleGraceDays * 86_400_000;
188
+ const patternActions = [];
189
+ const retrievalRemovals = [];
190
+ for (const pattern of Object.values(state.patterns).sort((a, b) =>
191
+ a.patternId.localeCompare(b.patternId),
192
+ )) {
193
+ if (
194
+ pattern.status === WIKI_PATTERN_STATUS.STALE &&
195
+ Number.isFinite(Date.parse(verifiedAt(pattern))) &&
196
+ Date.parse(verifiedAt(pattern)) <= cutoff
197
+ )
198
+ patternActions.push({
199
+ type: "tombstone",
200
+ patternId: pattern.patternId,
201
+ reason: "stale-grace-elapsed",
202
+ });
203
+ if (
204
+ pattern.status === WIKI_PATTERN_STATUS.STALE ||
205
+ TERMINAL_PATTERN_STATUSES.has(pattern.status)
206
+ )
207
+ retrievalRemovals.push(pattern.patternId);
208
+ }
209
+
210
+ const deletions = [];
211
+ const dependencyDispositions = [];
212
+ for (const receiptDigest of receiptDigests) {
213
+ const receipt = await ports.resolveDeletionReceipt({
214
+ tenantId: descriptor.tenantId,
215
+ receiptDigest,
216
+ });
217
+ const evidence = state.evidence?.[receipt?.evidenceRef];
218
+ if (
219
+ receipt?.authenticated !== true ||
220
+ receipt.tenantId !== descriptor.tenantId ||
221
+ receipt.decision !== "delete" ||
222
+ receipt.receiptDigest !== receiptDigest ||
223
+ evidence == null ||
224
+ receipt.sourceDigest !== evidence.sourceDigest ||
225
+ receipt.artifactRef !== evidence.artifactRef ||
226
+ typeof receipt.rawArtifactRef !== "string" ||
227
+ !receipt.rawArtifactRef.startsWith(
228
+ `artifact://${descriptor.tenantId}/raw/`,
229
+ ) ||
230
+ !DIGEST.test(receipt.rawCipherDigest ?? "") ||
231
+ typeof receipt.keyRef !== "string" ||
232
+ !receipt.keyRef.startsWith(`kms://${descriptor.tenantId}/`)
233
+ )
234
+ throw new Error("privacy deletion receipt is not exactly bound");
235
+ const dependentPatternIds = [
236
+ ...new Set(state.evidenceDependents?.[receipt.evidenceRef] ?? []),
237
+ ].sort();
238
+ for (const patternId of dependentPatternIds) {
239
+ const pattern = state.patterns[patternId];
240
+ if (!pattern) throw new Error("Wiki evidence dependency is corrupt");
241
+ dependencyDispositions.push({
242
+ evidenceRef: receipt.evidenceRef,
243
+ patternId,
244
+ action: pattern.skillNames?.length > 0 ? "rollback" : "tombstone",
245
+ skillNames: [...(pattern.skillNames ?? [])].sort(),
246
+ });
247
+ retrievalRemovals.push(patternId);
248
+ }
249
+ deletions.push({
250
+ evidenceRef: receipt.evidenceRef,
251
+ sourceDigest: evidence.sourceDigest,
252
+ artifactRef: evidence.artifactRef,
253
+ rawArtifactRef: receipt.rawArtifactRef,
254
+ rawCipherDigest: receipt.rawCipherDigest,
255
+ keyRef: receipt.keyRef,
256
+ receiptDigest,
257
+ });
258
+ }
259
+ const actionCount =
260
+ patternActions.length + deletions.length + dependencyDispositions.length;
261
+ if (actionCount > descriptor.maxActions)
262
+ throw new Error("Wiki pruning plan exceeds its action budget");
263
+ const core = {
264
+ schema: GOVERNED_WIKI_PRUNING_PLAN_SCHEMA,
265
+ tenantId: descriptor.tenantId,
266
+ wikiStateDigest: expectedStateDigest,
267
+ policyDigest: hash(GOVERNED_WIKI_PRUNING_POLICY_SCHEMA, descriptor),
268
+ effectiveAt,
269
+ patternActions,
270
+ retrievalRemovals: [...new Set(retrievalRemovals)].sort(),
271
+ dependencyDispositions,
272
+ deletions,
273
+ auditPolicy: {
274
+ retainWikiRevisions: true,
275
+ retainEvolutionLog: true,
276
+ retainDeletionReceipts: true,
277
+ removeDeletedEvidenceFromRetrieval: true,
278
+ },
279
+ };
280
+ return freeze({
281
+ ...core,
282
+ planDigest: hash(GOVERNED_WIKI_PRUNING_PLAN_SCHEMA, core),
283
+ });
284
+ }
285
+
156
286
  export class GovernedWikiPruning {
157
- constructor({ descriptor, ports } = {}) {
287
+ #ports;
288
+ #journal;
289
+ #planner;
290
+
291
+ constructor({ descriptor, ports, journalStore = null } = {}) {
158
292
  this.descriptor = normalizeDescriptor(descriptor);
293
+ this.#journal =
294
+ journalStore === null
295
+ ? null
296
+ : captureWikiPruningJournalStore(journalStore);
297
+ if (
298
+ this.#journal &&
299
+ this.#journal.descriptor.tenantId !== this.descriptor.tenantId
300
+ )
301
+ throw new TypeError("Wiki pruning journal belongs to another tenant");
302
+ const captured = {};
159
303
  for (const name of [
160
304
  "loadWikiState",
161
305
  "resolveDeletionReceipt",
@@ -166,138 +310,68 @@ export class GovernedWikiPruning {
166
310
  "publishRetrievalProjection",
167
311
  "verifyOfflineClosure",
168
312
  ]) {
313
+ if (name === "commitControl" && this.#journal) continue;
169
314
  if (typeof ports?.[name] !== "function")
170
315
  throw new TypeError(`Wiki pruning port ${name} is required`);
171
- this[`_${name}`] = ports[name].bind(ports);
316
+ captured[name] = ports[name].bind(ports);
172
317
  }
318
+ this.#ports = Object.freeze(captured);
319
+ this.#planner = createWikiPruningPlanner({
320
+ descriptor: this.descriptor,
321
+ ports: this.#ports,
322
+ });
323
+ Object.freeze(this);
173
324
  }
174
325
 
175
- async plan({
176
- expectedStateDigest,
177
- effectiveAt,
178
- deletionReceiptDigests = [],
179
- }) {
180
- digest(expectedStateDigest, "expectedStateDigest");
181
- time(effectiveAt, "effectiveAt");
182
- const receiptDigests = boundedUniqueStrings(
183
- deletionReceiptDigests,
184
- "deletionReceiptDigests",
185
- this.descriptor.maxActions,
186
- );
187
- receiptDigests.forEach((value) => digest(value, "deletionReceiptDigest"));
188
- const state = verifyStateEnvelope(
189
- await this._loadWikiState({ tenantId: this.descriptor.tenantId }),
190
- this.descriptor.tenantId,
191
- expectedStateDigest,
192
- );
193
- const cutoff =
194
- Date.parse(effectiveAt) - this.descriptor.staleGraceDays * 86_400_000;
195
- const patternActions = [];
196
- const retrievalRemovals = [];
197
- for (const pattern of Object.values(state.patterns).sort((a, b) =>
198
- a.patternId.localeCompare(b.patternId),
199
- )) {
200
- if (
201
- pattern.status === WIKI_PATTERN_STATUS.STALE &&
202
- Number.isFinite(Date.parse(verifiedAt(pattern))) &&
203
- Date.parse(verifiedAt(pattern)) <= cutoff
204
- )
205
- patternActions.push({
206
- type: "tombstone",
207
- patternId: pattern.patternId,
208
- reason: "stale-grace-elapsed",
209
- });
210
- if (
211
- pattern.status === WIKI_PATTERN_STATUS.STALE ||
212
- TERMINAL_PATTERN_STATUSES.has(pattern.status)
213
- )
214
- retrievalRemovals.push(pattern.patternId);
215
- }
216
-
217
- const deletions = [];
218
- const dependencyDispositions = [];
219
- for (const receiptDigest of receiptDigests) {
220
- const receipt = await this._resolveDeletionReceipt({
221
- tenantId: this.descriptor.tenantId,
222
- receiptDigest,
223
- });
224
- const evidence = state.evidence?.[receipt?.evidenceRef];
225
- if (
226
- receipt?.authenticated !== true ||
227
- receipt.tenantId !== this.descriptor.tenantId ||
228
- receipt.decision !== "delete" ||
229
- receipt.receiptDigest !== receiptDigest ||
230
- evidence == null ||
231
- receipt.sourceDigest !== evidence.sourceDigest ||
232
- receipt.artifactRef !== evidence.artifactRef ||
233
- typeof receipt.rawArtifactRef !== "string" ||
234
- !receipt.rawArtifactRef.startsWith(
235
- `artifact://${this.descriptor.tenantId}/raw/`,
236
- ) ||
237
- !DIGEST.test(receipt.rawCipherDigest ?? "") ||
238
- typeof receipt.keyRef !== "string" ||
239
- !receipt.keyRef.startsWith(`kms://${this.descriptor.tenantId}/`)
240
- )
241
- throw new Error("privacy deletion receipt is not exactly bound");
242
- const dependentPatternIds = [
243
- ...new Set(state.evidenceDependents?.[receipt.evidenceRef] ?? []),
244
- ].sort();
245
- for (const patternId of dependentPatternIds) {
246
- const pattern = state.patterns[patternId];
247
- if (!pattern) throw new Error("Wiki evidence dependency is corrupt");
248
- dependencyDispositions.push({
249
- evidenceRef: receipt.evidenceRef,
250
- patternId,
251
- action: pattern.skillNames?.length > 0 ? "rollback" : "tombstone",
252
- skillNames: [...(pattern.skillNames ?? [])].sort(),
253
- });
254
- retrievalRemovals.push(patternId);
255
- }
256
- deletions.push({
257
- evidenceRef: receipt.evidenceRef,
258
- sourceDigest: evidence.sourceDigest,
259
- artifactRef: evidence.artifactRef,
260
- rawArtifactRef: receipt.rawArtifactRef,
261
- rawCipherDigest: receipt.rawCipherDigest,
262
- keyRef: receipt.keyRef,
263
- receiptDigest,
264
- });
265
- }
266
- const actionCount =
267
- patternActions.length + deletions.length + dependencyDispositions.length;
268
- if (actionCount > this.descriptor.maxActions)
269
- throw new Error("Wiki pruning plan exceeds its action budget");
270
- const core = {
271
- schema: GOVERNED_WIKI_PRUNING_PLAN_SCHEMA,
272
- tenantId: this.descriptor.tenantId,
273
- wikiStateDigest: expectedStateDigest,
274
- effectiveAt,
275
- patternActions,
276
- retrievalRemovals: [...new Set(retrievalRemovals)].sort(),
277
- dependencyDispositions,
278
- deletions,
279
- auditPolicy: {
280
- retainWikiRevisions: true,
281
- retainEvolutionLog: true,
282
- retainDeletionReceipts: true,
283
- removeDeletedEvidenceFromRetrieval: true,
284
- },
285
- };
286
- return freeze({
287
- ...core,
288
- planDigest: hash(GOVERNED_WIKI_PRUNING_PLAN_SCHEMA, core),
289
- });
326
+ async plan(input) {
327
+ return this.#buildPlan(input);
290
328
  }
291
329
 
292
- async execute({ plan: input, expectedControlDigest = null }) {
330
+ async #buildPlan(input) {
331
+ return this.#planner.plan(input);
332
+ }
333
+ async execute({
334
+ plan: input,
335
+ expectedControlDigest = null,
336
+ expectedJournalDigest,
337
+ }) {
293
338
  const plan = assertPlan(input, this.descriptor.tenantId);
339
+ if (
340
+ plan.policyDigest !==
341
+ hash(GOVERNED_WIKI_PRUNING_POLICY_SCHEMA, this.descriptor)
342
+ )
343
+ throw new Error(
344
+ "Wiki pruning plan does not match current trusted policy",
345
+ );
346
+ if (this.#journal) {
347
+ if (expectedControlDigest !== null)
348
+ throw new TypeError(
349
+ "durable pruning uses expectedJournalDigest, not legacy control digests",
350
+ );
351
+ return this.#executeJournal(plan, expectedJournalDigest);
352
+ }
353
+ if (expectedJournalDigest !== undefined)
354
+ throw new TypeError(
355
+ "a durable journal is required for expectedJournalDigest",
356
+ );
294
357
  if (expectedControlDigest != null)
295
358
  digest(expectedControlDigest, "expectedControlDigest");
296
- verifyStateEnvelope(
297
- await this._loadWikiState({ tenantId: this.descriptor.tenantId }),
298
- this.descriptor.tenantId,
299
- plan.wikiStateDigest,
300
- );
359
+ if (!Array.isArray(plan.deletions))
360
+ throw new TypeError("Wiki pruning plan deletions are invalid");
361
+ // A self-consistent digest is not authorization. Rebuild all derived
362
+ // actions using the current trusted Wiki, captured policy, and freshly
363
+ // authenticated deletion receipts before preparing any side effects.
364
+ const authorizedPlan = await this.#buildPlan({
365
+ expectedStateDigest: plan.wikiStateDigest,
366
+ effectiveAt: plan.effectiveAt,
367
+ deletionReceiptDigests: plan.deletions.map(
368
+ (entry) => entry.receiptDigest,
369
+ ),
370
+ });
371
+ if (canonical(plan) !== canonical(authorizedPlan))
372
+ throw new Error(
373
+ "Wiki pruning plan does not match current trusted policy",
374
+ );
301
375
  const preparedCore = {
302
376
  schema: GOVERNED_WIKI_PRUNING_CONTROL_SCHEMA,
303
377
  tenantId: this.descriptor.tenantId,
@@ -310,7 +384,7 @@ export class GovernedWikiPruning {
310
384
  ...preparedCore,
311
385
  controlDigest: hash(GOVERNED_WIKI_PRUNING_CONTROL_SCHEMA, preparedCore),
312
386
  });
313
- const preparation = await this._commitControl({
387
+ const preparation = await this.#ports.commitControl({
314
388
  state: prepared,
315
389
  expectedControlDigest,
316
390
  });
@@ -326,9 +400,9 @@ export class GovernedWikiPruning {
326
400
  [
327
401
  "dependency-dispositions",
328
402
  plan.dependencyDispositions,
329
- this._applyDependencyDispositions,
403
+ this.#ports.applyDependencyDispositions,
330
404
  ],
331
- ["wiki-revision", plan.patternActions, this._applyWikiRevision],
405
+ ["wiki-revision", plan.patternActions, this.#ports.applyWikiRevision],
332
406
  ]) {
333
407
  const call = operationRequest(plan, operation, payload);
334
408
  receipts.push(
@@ -343,7 +417,7 @@ export class GovernedWikiPruning {
343
417
  const call = operationRequest(plan, "crypto-shred", deletion);
344
418
  receipts.push(
345
419
  requireDurableAck(
346
- await this._cryptoShred(call),
420
+ await this.#ports.cryptoShred(call),
347
421
  call.requestDigest,
348
422
  "Wiki privacy deletion",
349
423
  ),
@@ -354,7 +428,7 @@ export class GovernedWikiPruning {
354
428
  });
355
429
  receipts.push(
356
430
  requireDurableAck(
357
- await this._publishRetrievalProjection(projection),
431
+ await this.#ports.publishRetrievalProjection(projection),
358
432
  projection.requestDigest,
359
433
  "Wiki retrieval projection",
360
434
  ),
@@ -368,7 +442,7 @@ export class GovernedWikiPruning {
368
442
  ...finalCore,
369
443
  controlDigest: hash(GOVERNED_WIKI_PRUNING_CONTROL_SCHEMA, finalCore),
370
444
  });
371
- const completion = await this._commitControl({
445
+ const completion = await this.#ports.commitControl({
372
446
  state: finalized,
373
447
  expectedControlDigest: prepared.controlDigest,
374
448
  });
@@ -381,6 +455,111 @@ export class GovernedWikiPruning {
381
455
  return finalized;
382
456
  }
383
457
 
458
+ async resume({ expectedJournalDigest } = {}) {
459
+ if (!this.#journal)
460
+ throw new TypeError("a durable journal is required for pruning recovery");
461
+ const latest = await this.#journal.load({
462
+ tenantId: this.descriptor.tenantId,
463
+ });
464
+ if (!latest.state) return null;
465
+ const plan = assertPlan(latest.state.plan, this.descriptor.tenantId);
466
+ if (
467
+ plan.policyDigest !==
468
+ hash(GOVERNED_WIKI_PRUNING_POLICY_SCHEMA, this.descriptor)
469
+ )
470
+ throw new Error(
471
+ "Wiki pruning plan does not match current trusted policy",
472
+ );
473
+ return this.#executeJournal(plan, expectedJournalDigest, latest);
474
+ }
475
+
476
+ async #executeJournal(plan, expectedJournalDigest, restoredLatest = null) {
477
+ if (expectedJournalDigest !== undefined && expectedJournalDigest !== null)
478
+ digest(expectedJournalDigest, "expectedJournalDigest");
479
+ const scope = { tenantId: this.descriptor.tenantId };
480
+ // The usual case is the current plan. One fully authenticated load proves
481
+ // both its identity and that it is latest; no duplicate restore is needed.
482
+ // An explicitly requested older plan still gets its separate historical
483
+ // lookup. Providers and commits independently authorize their own effects.
484
+ const latest = restoredLatest ?? (await this.#journal.load(scope));
485
+ const known =
486
+ !latest.state || latest.state.plan.planDigest === plan.planDigest
487
+ ? latest
488
+ : await this.#journal.load({ ...scope, planDigest: plan.planDigest });
489
+ let state = known.state;
490
+ if (state && canonical(state.plan) !== canonical(plan))
491
+ throw new Error("restored pruning journal plan was substituted");
492
+ if (state?.phase === "finalized") return state;
493
+ if (
494
+ expectedJournalDigest !== undefined &&
495
+ expectedJournalDigest !== (latest.state?.journalDigest ?? null)
496
+ )
497
+ throw new Error("pruning journal changed before execution");
498
+ if (state && latest.state?.journalDigest !== state.journalDigest)
499
+ throw new Error("pruning journal is no longer the current execution");
500
+ if (!state) {
501
+ if (latest.state && latest.state.phase !== "finalized")
502
+ throw new Error("another pruning plan is unfinished");
503
+ const authorized = await this.#buildPlan({
504
+ expectedStateDigest: plan.wikiStateDigest,
505
+ effectiveAt: plan.effectiveAt,
506
+ deletionReceiptDigests: plan.deletions.map(
507
+ (entry) => entry.receiptDigest,
508
+ ),
509
+ });
510
+ if (canonical(plan) !== canonical(authorized))
511
+ throw new Error(
512
+ "Wiki pruning plan does not match current trusted policy",
513
+ );
514
+ state = buildWikiPruningJournal({ plan, previous: latest.state });
515
+ await this.#journal.commit({
516
+ state,
517
+ expectedJournalDigest: latest.state?.journalDigest ?? null,
518
+ });
519
+ }
520
+ // Restore is authenticated by the branded journal's current plan and
521
+ // operation verifiers, including the historical source Wiki binding. Do
522
+ // not require the original Wiki to remain current after our own revision.
523
+ // Effect providers MUST reconcile the same requestDigest after a response
524
+ // loss or a crash between their durable effect and this checkpoint.
525
+ const handlers = {
526
+ "dependency-dispositions": this.#ports.applyDependencyDispositions,
527
+ "wiki-revision": this.#ports.applyWikiRevision,
528
+ "crypto-shred": this.#ports.cryptoShred,
529
+ "retrieval-projection": this.#ports.publishRetrievalProjection,
530
+ };
531
+ const calls = pruningOperationCalls(plan);
532
+ for (
533
+ let index = state.operationReceipts.length;
534
+ index < calls.length;
535
+ index++
536
+ ) {
537
+ const call = calls[index];
538
+ const receipt = await handlers[call.request.operation](call);
539
+ requireDurableAck(
540
+ receipt,
541
+ call.requestDigest,
542
+ `Wiki pruning ${call.request.operation}`,
543
+ );
544
+ const next = buildWikiPruningJournal({ plan, previous: state, receipt });
545
+ await this.#journal.commit({
546
+ state: next,
547
+ expectedJournalDigest: state.journalDigest,
548
+ });
549
+ state = next;
550
+ }
551
+ const finalized = buildWikiPruningJournal({
552
+ plan,
553
+ previous: state,
554
+ finalize: true,
555
+ });
556
+ await this.#journal.commit({
557
+ state: finalized,
558
+ expectedJournalDigest: state.journalDigest,
559
+ });
560
+ return finalized;
561
+ }
562
+
384
563
  async authorizeOnlineAdaptation(input = {}) {
385
564
  const requested = boundedUniqueStrings(
386
565
  input.requestedCapabilities ?? [],
@@ -400,7 +579,7 @@ export class GovernedWikiPruning {
400
579
  requested.some((capability) => !baseline.includes(capability))
401
580
  )
402
581
  throw new Error("online adaptation cannot expand authority");
403
- const closure = await this._verifyOfflineClosure({
582
+ const closure = await this.#ports.verifyOfflineClosure({
404
583
  tenantId: this.descriptor.tenantId,
405
584
  receiptDigest: digest(
406
585
  input.offlineClosureReceiptDigest,