chainlesschain 0.166.24 → 0.166.26

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 (184) hide show
  1. package/README.md +52 -3
  2. package/package.json +1 -1
  3. package/src/assets/web-panel/assets/{AIOps-DR-MWcZc.js → AIOps-Z8_dnLd8.js} +1 -1
  4. package/src/assets/web-panel/assets/{ActionButton-DT8B7sEb.js → ActionButton-C4bKCISV.js} +1 -1
  5. package/src/assets/web-panel/assets/{Analytics-asjh3dQJ.js → Analytics-GztAv2jy.js} +3 -3
  6. package/src/assets/web-panel/assets/{AppLayout-DivQ491i.js → AppLayout-DEqNcuVx.js} +4 -4
  7. package/src/assets/web-panel/assets/{Artifacts-DPH2uUmy.js → Artifacts-D-R4Ehap.js} +1 -1
  8. package/src/assets/web-panel/assets/{Audit-Bp2nLyc-.js → Audit-mzzdTIlM.js} +1 -1
  9. package/src/assets/web-panel/assets/{BackgroundAgents-CHS28khl.js → BackgroundAgents-DS2QupIC.js} +1 -1
  10. package/src/assets/web-panel/assets/{Backup-CKeaFSfz.js → Backup-CQSirC39.js} +1 -1
  11. package/src/assets/web-panel/assets/{BaseInput-CxwM9BAH.js → BaseInput-Bhuc-eOV.js} +1 -1
  12. package/src/assets/web-panel/assets/{Chat-DYLDwaCv.js → Chat-B-RLVGnt.js} +6 -6
  13. package/src/assets/web-panel/assets/{ChatBubbleRenderer-DdBJDBP0.js → ChatBubbleRenderer-CBbMoVuE.js} +1 -1
  14. package/src/assets/web-panel/assets/{Checkbox-uYTWOB8j.js → Checkbox-DxwgBryW.js} +1 -1
  15. package/src/assets/web-panel/assets/{Codegen-CvYa_dwT.js → Codegen-Cwrm-7nh.js} +1 -1
  16. package/src/assets/web-panel/assets/{Col-CanMAX4m.js → Col-DrSCT-nF.js} +1 -1
  17. package/src/assets/web-panel/assets/{Community-B4WaDtHw.js → Community-DY2D9WNs.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compact-K93Uof_3.js → Compact-o-tV0URw.js} +1 -1
  19. package/src/assets/web-panel/assets/{Compliance-CKeDLgUW.js → Compliance-Bndh6S8f.js} +1 -1
  20. package/src/assets/web-panel/assets/{Cowork-P93grAeB.js → Cowork-CSNQODak.js} +3 -3
  21. package/src/assets/web-panel/assets/{Cron-BSHnMtDn.js → Cron-CTgxRHdy.js} +2 -2
  22. package/src/assets/web-panel/assets/{Crosschain-epAOpUVJ.js → Crosschain-BJoGQzDI.js} +1 -1
  23. package/src/assets/web-panel/assets/{DID-ByjXfP7t.js → DID-V0Ztm8ne.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dashboard-QztTU8tb.js → Dashboard-B-38THOj.js} +2 -2
  25. package/src/assets/web-panel/assets/{Dropdown-DhUc9yhN.js → Dropdown-B3FdOwMO.js} +1 -1
  26. package/src/assets/web-panel/assets/{EmailListRenderer-C2sLhJJN.js → EmailListRenderer-YQDz4mUF.js} +1 -1
  27. package/src/assets/web-panel/assets/{FamilyGuardDashboard-CdfbWNDn.js → FamilyGuardDashboard-DYE45IF9.js} +1 -1
  28. package/src/assets/web-panel/assets/{Federation-CcF_R7NW.js → Federation-DjBFjdRZ.js} +1 -1
  29. package/src/assets/web-panel/assets/{FormItemContext-Cm_X2IBk.js → FormItemContext-CVTXEa0R.js} +1 -1
  30. package/src/assets/web-panel/assets/{GenericCardRenderer-DUi4NWlb.js → GenericCardRenderer-B6Tkke8X.js} +1 -1
  31. package/src/assets/web-panel/assets/{Git-4Sq5FjBt.js → Git-CD0hyAzT.js} +2 -2
  32. package/src/assets/web-panel/assets/{Governance-Dx2_v4V6.js → Governance-CWOQQJr8.js} +1 -1
  33. package/src/assets/web-panel/assets/{Inference-7Vr1xekR.js → Inference-lHYwUk-C.js} +1 -1
  34. package/src/assets/web-panel/assets/{KnowledgeGraph-Cnd2XOzf.js → KnowledgeGraph-Cledxv7t.js} +1 -1
  35. package/src/assets/web-panel/assets/{Logs-B66QPVf-.js → Logs-D45mt-rM.js} +2 -2
  36. package/src/assets/web-panel/assets/{MarkdownRenderer-PLsEvhly.js → MarkdownRenderer-DJjPaOnM.js} +1 -1
  37. package/src/assets/web-panel/assets/{Marketplace-BMIK9BmC.js → Marketplace-Yy30UZPw.js} +1 -1
  38. package/src/assets/web-panel/assets/{McpTools-BDbyp3J_.js → McpTools-Cil5l-bh.js} +3 -3
  39. package/src/assets/web-panel/assets/{Memory-CJdzfZGi.js → Memory-DdJcnyqy.js} +2 -2
  40. package/src/assets/web-panel/assets/{MobileBridge-C2TH5Y3-.js → MobileBridge-IrzFYHEv.js} +1 -1
  41. package/src/assets/web-panel/assets/{MobileProjects-D1dYXkvV.js → MobileProjects-D8q64LMd.js} +1 -1
  42. package/src/assets/web-panel/assets/{Mtc-B-4A1I1j.js → Mtc-CpdTJzW7.js} +5 -5
  43. package/src/assets/web-panel/assets/{MtcAudit-Bgcc9UOl.js → MtcAudit-C7Tvw2m6.js} +2 -2
  44. package/src/assets/web-panel/assets/{Multisig-DqOe-etP.js → Multisig-Dmj9F5Kr.js} +3 -3
  45. package/src/assets/web-panel/assets/{NLProgramming-7VnhzE_6.js → NLProgramming-C9Xchob5.js} +1 -1
  46. package/src/assets/web-panel/assets/{Notes-BxawpeUQ.js → Notes-Bzq6Yry5.js} +4 -4
  47. package/src/assets/web-panel/assets/{NotificationSettings-Cr08G2aE.js → NotificationSettings-DxG9eKb4.js} +1 -1
  48. package/src/assets/web-panel/assets/{OrderTableRenderer-Ce8bEGlK.js → OrderTableRenderer-BS_IYoCe.js} +1 -1
  49. package/src/assets/web-panel/assets/{Organization-BC7lveGv.js → Organization-kazsRvcq.js} +4 -4
  50. package/src/assets/web-panel/assets/{Overflow-CakOW-G0.js → Overflow-i4wP-hwn.js} +1 -1
  51. package/src/assets/web-panel/assets/{P2P-Cf8CaOBZ.js → P2P-CfGeU3h-.js} +2 -2
  52. package/src/assets/web-panel/assets/{PdhVaultBrowser-Dc7b98W9.js → PdhVaultBrowser-CS-VhVUx.js} +5 -5
  53. package/src/assets/web-panel/assets/{Permissions-DGJyMEfS.js → Permissions-DnEHXs0I.js} +4 -4
  54. package/src/assets/web-panel/assets/{PersonalDataHub-DNIwSdwu.js → PersonalDataHub-DeD82qke.js} +6 -6
  55. package/src/assets/web-panel/assets/{Pipeline-5B1S12wa.js → Pipeline-CMGGLgBY.js} +1 -1
  56. package/src/assets/web-panel/assets/{Privacy-CMB6Ke5t.js → Privacy-CvHoFv32.js} +1 -1
  57. package/src/assets/web-panel/assets/{ProjectInit-D5PqTFiT.js → ProjectInit-DnJapCc1.js} +2 -2
  58. package/src/assets/web-panel/assets/{ProjectSettings-CbKNdSjV.js → ProjectSettings-CqVdv3-g.js} +2 -2
  59. package/src/assets/web-panel/assets/Projects-B_o8vcs_.js +1 -0
  60. package/src/assets/web-panel/assets/{Providers-CJF5_-Gs.js → Providers-CPKseoDW.js} +1 -1
  61. package/src/assets/web-panel/assets/{QrScannerModal-CT6iEAdi.js → QrScannerModal-_iBfKbPQ.js} +1 -1
  62. package/src/assets/web-panel/assets/{QuickAsk-Ci0h9mJ_.js → QuickAsk-CMrlZ69a.js} +1 -1
  63. package/src/assets/web-panel/assets/{Recommend-Da5mobZu.js → Recommend-BwDtSZ0l.js} +1 -1
  64. package/src/assets/web-panel/assets/{RemoteSession-BaCY8eey.js → RemoteSession-DomUAtn4.js} +2 -2
  65. package/src/assets/web-panel/assets/{Reputation-CaITfTsI.js → Reputation-Cuu2GCHr.js} +1 -1
  66. package/src/assets/web-panel/assets/{Row-DtUDamyP.js → Row-C7GVts31.js} +1 -1
  67. package/src/assets/web-panel/assets/{RssFeed-DX27gFpg.js → RssFeed-DRKvgEog.js} +3 -3
  68. package/src/assets/web-panel/assets/{Search-DFL69osN.js → Search-BGI9wOeA.js} +1 -1
  69. package/src/assets/web-panel/assets/{Security-BqGeoWv-.js → Security-BlLaHy_L.js} +3 -3
  70. package/src/assets/web-panel/assets/{Services-3z1WnEAc.js → Services-DFqZbjmX.js} +2 -2
  71. package/src/assets/web-panel/assets/{Skeleton-C_OJQQ9Z.js → Skeleton-BCGxdooP.js} +1 -1
  72. package/src/assets/web-panel/assets/{Skills-BY7aT6Mo.js → Skills-CwFKgcmm.js} +1 -1
  73. package/src/assets/web-panel/assets/{Sla-BZv7DSaD.js → Sla-CiXXh9eS.js} +1 -1
  74. package/src/assets/web-panel/assets/SpeechSettings-WSx2CLqO.js +1 -0
  75. package/src/assets/web-panel/assets/{SyncSettings-B6D7STlI.js → SyncSettings-BBIqQOtW.js} +2 -2
  76. package/src/assets/web-panel/assets/{Tasks-Co_FCZAO.js → Tasks-D1BGLjO1.js} +1 -1
  77. package/src/assets/web-panel/assets/{Templates-CnY-9fgz.js → Templates-CUIl9axA.js} +1 -1
  78. package/src/assets/web-panel/assets/{Tenant-B71yXfZ8.js → Tenant-BFZJ0hNz.js} +1 -1
  79. package/src/assets/web-panel/assets/{Terminal-Dd_P7awo.js → Terminal-Cw-3eYVn.js} +2 -2
  80. package/src/assets/web-panel/assets/{TimelineRenderer-CvIEMyli.js → TimelineRenderer-bOVPB56L.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tokens-DknFBGOi.js → Tokens-Czfyq2VY.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trigger-D_4nJONB.js → Trigger-C-o4uJY0.js} +1 -1
  83. package/src/assets/web-panel/assets/{Trust-BNl21fa7.js → Trust-BKq_S6iF.js} +1 -1
  84. package/src/assets/web-panel/assets/{UkeySign-CFrCI7uK.js → UkeySign-fKlWUvMx.js} +1 -1
  85. package/src/assets/web-panel/assets/{VideoEditing-BVfY6JLg.js → VideoEditing-DB5MLuS7.js} +1 -1
  86. package/src/assets/web-panel/assets/{Wallet-Cj9CAK0J.js → Wallet-WGXBn7IS.js} +4 -4
  87. package/src/assets/web-panel/assets/{WebAuthn-DcqZlzA3.js → WebAuthn-B8TC4EMF.js} +4 -4
  88. package/src/assets/web-panel/assets/{WorkflowEditor-Dfr_dMld.js → WorkflowEditor-DLY--KmM.js} +1 -1
  89. package/src/assets/web-panel/assets/{chat-Yv6UF0AD.js → chat-Crw3XQaA.js} +1 -1
  90. package/src/assets/web-panel/assets/{colors-CDW_-1fs.js → colors-CxhWauPV.js} +1 -1
  91. package/src/assets/web-panel/assets/{compact-item-BYOQvd-6.js → compact-item-Cp3ojtk5.js} +1 -1
  92. package/src/assets/web-panel/assets/{createContext-BCGO0BiP.js → createContext-CRuRXjSo.js} +1 -1
  93. package/src/assets/web-panel/assets/devWarning-CKAQY2zn.js +1 -0
  94. package/src/assets/web-panel/assets/{hasIn-DY-70cfQ.js → hasIn-XGW474dj.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-B9ZogJJM.js → index-38TRdZb6.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-BBs2mv5M.js → index-B45Vkh3T.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-CCwWp3mT.js → index-B5fJS-kn.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-CUo27q9J.js → index-BElgeKJ0.js} +3 -3
  99. package/src/assets/web-panel/assets/{index-CFa2fPCk.js → index-BUWZ57T4.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-DCtsjhhT.js → index-BVmSfIkJ.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-NaCESahy.js → index-BW028Pwn.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-CaT8trvf.js → index-BXnNbbwa.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-DRFC2Qt0.js → index-BYkjs7eP.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-Br3wQLVY.js → index-BetOkRLs.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-DuIPq5MX.js → index-BuVA26SD.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-C4UJA2ju.js → index-C73pqyDb.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-BvK4fjkk.js → index-C8UOVaUH.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-hZ0Eyrrw.js → index-CDIpH_8Q.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-D--TEyDj.js → index-CPFam-me.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-CUP-A2_h.js → index-CTE32qol.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-CnZNbcux.js → index-CdlfrcC-.js} +1 -1
  112. package/src/assets/web-panel/assets/index-Cetfwq8j.js +1 -0
  113. package/src/assets/web-panel/assets/{index-C40UdtlS.js → index-Ctu98x57.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-B9m5QAMg.js → index-DBcBsJYg.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-BXlEx4UH.js → index-DHNixOg_.js} +1 -1
  116. package/src/assets/web-panel/assets/index-DOpcRO2-.js +1 -0
  117. package/src/assets/web-panel/assets/{index-Dg-AQYDf.js → index-DUSVsOGS.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-CzeEEazr.js → index-De2FN0xN.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-DUDoRk9r.js → index-DfPLIA-f.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-Y9akzgFO.js → index-DhomnuaB.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-366wfQBU.js → index-DoUC5_ry.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-Bb9nyts1.js → index-Dp2nC5On.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-CIyHxV4u.js → index-DxOtBFVy.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-BFv1hzF6.js → index-E-RSfImO.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-DLOf7BSz.js → index-J_08R33H.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-RjIMPG0u.js → index-QqAuH7-S.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-CB_Iw73G.js → index-W8_0yAi_.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-DM5c4pc-.js → index-WvNZXbIO.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-DT_qVaaV.js → index-Yq3bFbYX.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-NYVBUAVN.js → index-jrIcbPUa.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-Cy2NE6AO.js → index-nJR64pA_.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-Bf_Va0S-.js → index-qzmihx1d.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-BayRTE5w.js → index-rsACoVT9.js} +1 -1
  134. package/src/assets/web-panel/assets/{initDefaultProps-CG99CcR4.js → initDefaultProps-DAu-hgme.js} +1 -1
  135. package/src/assets/web-panel/assets/{motion-Z7MH0_0G.js → motion-Db8yk0Hu.js} +1 -1
  136. package/src/assets/web-panel/assets/{move-BX67lOdq.js → move-Cii2jOin.js} +1 -1
  137. package/src/assets/web-panel/assets/{mtc-parser-CmAbG1fE.js → mtc-parser-CnZBDkyZ.js} +1 -1
  138. package/src/assets/web-panel/assets/{omit-DiU5tI1_.js → omit-Buzt1FTL.js} +1 -1
  139. package/src/assets/web-panel/assets/{pickAttrs-BGfvLrYL.js → pickAttrs-CpZ_NmE6.js} +1 -1
  140. package/src/assets/web-panel/assets/{placementArrow-CggLEgaJ.js → placementArrow-mBrx3dYm.js} +1 -1
  141. package/src/assets/web-panel/assets/{responsiveObserve-t3nlghPZ.js → responsiveObserve-DC_QzljB.js} +1 -1
  142. package/src/assets/web-panel/assets/{slide-BkV4dL9s.js → slide-DT_UVED-.js} +1 -1
  143. package/src/assets/web-panel/assets/{statusUtils-qec1PUoC.js → statusUtils-78t6eNLV.js} +1 -1
  144. package/src/assets/web-panel/assets/{styleChecker-ChjX6T8D.js → styleChecker-CV_T1ULL.js} +1 -1
  145. package/src/assets/web-panel/assets/{useFlexGapSupport-B1jLoZcM.js → useFlexGapSupport-s8edGuXD.js} +1 -1
  146. package/src/assets/web-panel/assets/{useFs-C3X53s4E.js → useFs-Pk9dH2HC.js} +1 -1
  147. package/src/assets/web-panel/assets/{usePersonalDataHub-DOvbbnkZ.js → usePersonalDataHub-B_GqAm8c.js} +1 -1
  148. package/src/assets/web-panel/assets/{vnode-Ie0TEVFT.js → vnode-Cxyss24q.js} +1 -1
  149. package/src/assets/web-panel/assets/{zoom-CRUMVS8l.js → zoom-0UY3cOuc.js} +1 -1
  150. package/src/assets/web-panel/index.html +1 -1
  151. package/src/commands/evolution-knowledge.js +40 -1
  152. package/src/commands/serve.js +11 -0
  153. package/src/data/changelog.json +29 -3
  154. package/src/generated/cc-agent-protocol.schema.json +3 -1
  155. package/src/lib/app-server/server.js +49 -0
  156. package/src/lib/app-server/websocket-transport.js +13 -0
  157. package/src/lib/evolution/agent-model-projection.js +252 -32
  158. package/src/lib/evolution/evidence-backed-wiki-maintainer.js +22 -9
  159. package/src/lib/evolution/evolution-artifact-ports.js +3 -0
  160. package/src/lib/evolution/evolution-deployment-loader.js +77 -0
  161. package/src/lib/evolution/evolution-evidence-projector.js +36 -5
  162. package/src/lib/evolution/evolution-ledger-ports.js +210 -18
  163. package/src/lib/evolution/governed-knowledge-dependency-inventory.js +392 -0
  164. package/src/lib/evolution/governed-knowledge-dependency-ledger-executor.js +123 -0
  165. package/src/lib/evolution/governed-knowledge-quarantine-release.js +1013 -0
  166. package/src/lib/evolution/governed-knowledge-revocation-host.js +59 -0
  167. package/src/lib/evolution/governed-knowledge-skill-rollback.js +62 -27
  168. package/src/lib/evolution/governed-knowledge-sync.js +164 -1
  169. package/src/lib/evolution/governed-knowledge-wiki-tombstone.js +88 -34
  170. package/src/lib/evolution/knowledge-wiki-source-admission.js +160 -1
  171. package/src/lib/evolution/knowledge-wiki-source-provenance.js +1 -0
  172. package/src/lib/evolution/skill-candidate-registry.js +21 -3
  173. package/src/lib/evolution/skill-release-registry.js +143 -0
  174. package/src/lib/evolution/wiki-maintainer-ledger-adapter.js +61 -0
  175. package/src/lib/evolution/wiki-target-tombstone-revision.js +15 -7
  176. package/src/lib/read-file-loop-guard.js +222 -0
  177. package/src/lib/read-file-page.js +55 -2
  178. package/src/repl/agent-repl.js +6 -1
  179. package/src/runtime/agent-core.js +177 -57
  180. package/src/assets/web-panel/assets/Projects-ccXaHzYL.js +0 -1
  181. package/src/assets/web-panel/assets/SpeechSettings-6lJKLhCn.js +0 -1
  182. package/src/assets/web-panel/assets/devWarning-H-kXSuf-.js +0 -1
  183. package/src/assets/web-panel/assets/index-B0o4MeNK.js +0 -1
  184. package/src/assets/web-panel/assets/index-BVafOL_I.js +0 -1
@@ -0,0 +1,59 @@
1
+ import { isGovernedKnowledgeSync } from "./governed-knowledge-sync.js";
2
+
3
+ const HOSTS = new WeakSet();
4
+ const DIGEST = /^sha256:[a-f0-9]{64}$/u;
5
+
6
+ function freeze(value) {
7
+ if (value && typeof value === "object" && !Object.isFrozen(value)) {
8
+ Object.freeze(value);
9
+ for (const child of Object.values(value)) freeze(child);
10
+ }
11
+ return value;
12
+ }
13
+
14
+ function clone(value) {
15
+ return structuredClone(value);
16
+ }
17
+
18
+ export function createGovernedKnowledgeRevocationHost({ sync } = {}) {
19
+ if (!isGovernedKnowledgeSync(sync)) {
20
+ throw new TypeError("a branded governed Knowledge sync is required");
21
+ }
22
+ const host = Object.freeze({
23
+ async prepare(record) {
24
+ const planned = await sync.planRevocation(record);
25
+ return freeze({
26
+ authenticated: true,
27
+ durable: true,
28
+ operationDigest: planned.operationDigest,
29
+ inventoryDigest: planned.inventory.inventoryDigest,
30
+ knowledge: clone(planned.knowledge),
31
+ });
32
+ },
33
+ async publish({ operationDigest } = {}) {
34
+ if (!DIGEST.test(operationDigest ?? "")) {
35
+ throw new TypeError("revocation operationDigest is invalid");
36
+ }
37
+ const planned = await sync.recoverPlannedRevocation({ operationDigest });
38
+ const result = await sync.publishPlanned(planned, {
39
+ operationId: `knowledge-revocation:${operationDigest.slice(7)}`,
40
+ });
41
+ return freeze({
42
+ authenticated: true,
43
+ durable: true,
44
+ recoveredPlan: true,
45
+ operationDigest,
46
+ envelopeDigest: result.envelope.envelopeDigest,
47
+ knowledgeId: planned.knowledge.knowledgeId,
48
+ contentDigest: planned.knowledge.contentDigest,
49
+ dependencyCount: planned.knowledge.dependencies.length,
50
+ });
51
+ },
52
+ });
53
+ HOSTS.add(host);
54
+ return host;
55
+ }
56
+
57
+ export function isGovernedKnowledgeRevocationHost(value) {
58
+ return HOSTS.has(value);
59
+ }
@@ -22,6 +22,16 @@ import {
22
22
  const ID = /^[A-Za-z0-9][A-Za-z0-9._:@/-]{0,255}$/u;
23
23
  const VERIFICATION_SCHEMA =
24
24
  "chainlesschain.knowledge-skill-rollback-verification/v1";
25
+ const QUARANTINE_VERIFICATION_SCHEMA =
26
+ "chainlesschain.knowledge-skill-quarantine-verification/v1";
27
+ const ROLLBACK = Object.freeze({
28
+ disposition: "rollback-active",
29
+ verificationSchema: VERIFICATION_SCHEMA,
30
+ });
31
+ const QUARANTINE = Object.freeze({
32
+ disposition: "quarantine",
33
+ verificationSchema: QUARANTINE_VERIFICATION_SCHEMA,
34
+ });
25
35
 
26
36
  function fail(message) {
27
37
  throw new Error(`knowledge Skill rollback: ${message}`);
@@ -117,12 +127,14 @@ function sameLedger(provider, verifier) {
117
127
  fail("independent readers do not authenticate the same ledger");
118
128
  }
119
129
 
120
- function releasesFor(reader, request) {
130
+ function releasesFor(reader, request, configuration) {
121
131
  if (
122
132
  request.dependency.kind !== "active-skill" ||
123
- request.dependency.disposition !== "rollback-active"
133
+ request.dependency.disposition !== configuration.disposition
124
134
  )
125
- fail("this provider requires an active-skill / rollback-active dependency");
135
+ fail(
136
+ `this provider requires an active-skill / ${configuration.disposition} dependency`,
137
+ );
126
138
  // This effect accepts an immutable release identity, never an ambiguous content
127
139
  // digest or a caller-supplied Skill name. Other dependency kinds need their own effect.
128
140
  const from = reader.registry.readRelease(request.dependency.digest);
@@ -175,8 +187,8 @@ function resolve(reader, request, from) {
175
187
  }).result;
176
188
  }
177
189
 
178
- function committedProof(reader, request) {
179
- const { from, sourceRef, wiki } = releasesFor(reader, request);
190
+ function committedProof(reader, request, configuration) {
191
+ const { from, sourceRef, wiki } = releasesFor(reader, request, configuration);
180
192
  const result = resolve(reader, request, from);
181
193
  if (!result) return null;
182
194
  const { intent, previous, projection, finalizationEvidence } = result;
@@ -247,20 +259,21 @@ function authorizationData(value) {
247
259
 
248
260
  // Real active-release effect with direct or historically authenticated Wiki
249
261
  // provenance. Candidate rejection and quarantine require separate effects.
250
- export function createGovernedKnowledgeSkillRollbackAuthority({
251
- tenantId,
252
- deviceId,
253
- releaseRegistry,
254
- transactionLedger,
255
- rollbackProvider,
256
- authorizationProvider,
257
- verifierReleaseRegistry,
258
- verifierTransactionLedger,
259
- wikiLedgerAdapter = null,
260
- verifierWikiLedgerAdapter = null,
261
- providerDescriptor,
262
- verifierDescriptor,
263
- } = {}) {
262
+ function createSkillDispositionAuthority(options = {}, configuration) {
263
+ const {
264
+ tenantId,
265
+ deviceId,
266
+ releaseRegistry,
267
+ transactionLedger,
268
+ rollbackProvider,
269
+ authorizationProvider,
270
+ verifierReleaseRegistry,
271
+ verifierTransactionLedger,
272
+ wikiLedgerAdapter = null,
273
+ verifierWikiLedgerAdapter = null,
274
+ providerDescriptor,
275
+ verifierDescriptor,
276
+ } = options;
264
277
  if (
265
278
  releaseRegistry === verifierReleaseRegistry ||
266
279
  transactionLedger === verifierTransactionLedger
@@ -316,9 +329,13 @@ export function createGovernedKnowledgeSkillRollbackAuthority({
316
329
 
317
330
  async function apply(request) {
318
331
  sameLedger(providerReader, verifierReader);
319
- let proof = committedProof(providerReader, request);
332
+ let proof = committedProof(providerReader, request, configuration);
320
333
  if (!proof) {
321
- const { from, sourceRef, wiki } = releasesFor(providerReader, request);
334
+ const { from, sourceRef, wiki } = releasesFor(
335
+ providerReader,
336
+ request,
337
+ configuration,
338
+ );
322
339
  const active = providerReader.registry.readActive(from.skillName);
323
340
  if (!active || active.release.releaseDigest !== from.releaseDigest)
324
341
  fail("dependent release is not currently active");
@@ -336,7 +353,11 @@ export function createGovernedKnowledgeSkillRollbackAuthority({
336
353
  const independent = verifierReader.registry.readActive(from.skillName);
337
354
  if (canonical(independent) !== canonical(active))
338
355
  fail("independent active state differs");
339
- const independentSource = releasesFor(verifierReader, request);
356
+ const independentSource = releasesFor(
357
+ verifierReader,
358
+ request,
359
+ configuration,
360
+ );
340
361
  const independentTargetWiki = validateTarget(
341
362
  verifierReader,
342
363
  request,
@@ -388,7 +409,7 @@ export function createGovernedKnowledgeSkillRollbackAuthority({
388
409
  fail("authority authorized a different transition");
389
410
  sameLedger(providerReader, verifierReader);
390
411
  if (
391
- committedProof(providerReader, request) !== null ||
412
+ committedProof(providerReader, request, configuration) !== null ||
392
413
  canonical(providerReader.registry.readActive(from.skillName)) !==
393
414
  canonical(active)
394
415
  )
@@ -397,7 +418,7 @@ export function createGovernedKnowledgeSkillRollbackAuthority({
397
418
  authorization,
398
419
  targetReleaseDigest: target.releaseDigest,
399
420
  });
400
- proof = committedProof(providerReader, request);
421
+ proof = committedProof(providerReader, request, configuration);
401
422
  if (!proof) fail("rollback was not durably read back");
402
423
  }
403
424
  const core = {
@@ -436,8 +457,12 @@ export function createGovernedKnowledgeSkillRollbackAuthority({
436
457
  verifier: Object.freeze({
437
458
  async verify({ request, result }) {
438
459
  sameLedger(providerReader, verifierReader);
439
- const proof = committedProof(verifierReader, request);
440
- const providerProof = committedProof(providerReader, request);
460
+ const proof = committedProof(verifierReader, request, configuration);
461
+ const providerProof = committedProof(
462
+ providerReader,
463
+ request,
464
+ configuration,
465
+ );
441
466
  if (!proof || canonical(proof) !== canonical(providerProof))
442
467
  fail("independent durable rollback proof differs");
443
468
  const { algorithm, keyId, value } =
@@ -460,7 +485,7 @@ export function createGovernedKnowledgeSkillRollbackAuthority({
460
485
  providerRevision: providerIdentity.revision,
461
486
  verifierAuthorityId: verifierIdentity.authorityId,
462
487
  verifierRevision: verifierIdentity.revision,
463
- verificationReceiptDigest: digest(VERIFICATION_SCHEMA, {
488
+ verificationReceiptDigest: digest(configuration.verificationSchema, {
464
489
  tenantId,
465
490
  deviceId,
466
491
  requestDigest: request.requestDigest,
@@ -473,3 +498,13 @@ export function createGovernedKnowledgeSkillRollbackAuthority({
473
498
  }),
474
499
  });
475
500
  }
501
+
502
+ export function createGovernedKnowledgeSkillRollbackAuthority(options = {}) {
503
+ return createSkillDispositionAuthority(options, ROLLBACK);
504
+ }
505
+
506
+ // Active quarantine performs the same safety rollback, while the separately
507
+ // typed durable dependency fence prevents this exact release from reactivation.
508
+ export function createGovernedKnowledgeSkillQuarantineAuthority(options = {}) {
509
+ return createSkillDispositionAuthority(options, QUARANTINE);
510
+ }
@@ -3,6 +3,10 @@ import { types as utilTypes } from "node:util";
3
3
 
4
4
  import { isGovernedKnowledgeDependencyExecutor } from "./governed-knowledge-dependency-ledger-executor.js";
5
5
  import { isGovernedKnowledgeArtifactLifecycle } from "./governed-knowledge-artifact-lifecycle.js";
6
+ import {
7
+ captureGovernedKnowledgeDependencyInventoryPlan,
8
+ isGovernedKnowledgeDependencyInventoryPlanner,
9
+ } from "./governed-knowledge-dependency-inventory.js";
6
10
 
7
11
  import {
8
12
  GOVERNED_KNOWLEDGE_SCOPE,
@@ -28,6 +32,7 @@ const ACTIONS = new Set(["upsert", "tombstone", "revoke"]);
28
32
  const MAX_CIPHERTEXT_BYTES = 12 * 1024 * 1024;
29
33
  const EXECUTION_RECORDS = new WeakSet();
30
34
  const SYNCHRONIZERS = new WeakSet();
35
+ const PLANNED_REVOCATIONS = new WeakMap();
31
36
  const ENVELOPE_KEYS = new Set([
32
37
  "action",
33
38
  "ciphertext",
@@ -244,6 +249,7 @@ export class GovernedKnowledgeSync {
244
249
  deviceId,
245
250
  ports,
246
251
  dependencyExecutor = null,
252
+ dependencyPlanner = null,
247
253
  artifactLifecycle,
248
254
  clock = () => Date.now(),
249
255
  } = {}) {
@@ -282,9 +288,106 @@ export class GovernedKnowledgeSync {
282
288
  this._executeDependencies = dependencyExecutor
283
289
  ? capture(dependencyExecutor, "execute")
284
290
  : null;
291
+ if (
292
+ dependencyPlanner !== null &&
293
+ (!isGovernedKnowledgeDependencyInventoryPlanner(dependencyPlanner) ||
294
+ dependencyExecutor === null)
295
+ ) {
296
+ throw new TypeError(
297
+ "dependencyPlanner requires a branded inventory planner and executor",
298
+ );
299
+ }
300
+ this._dependencyPlanner = dependencyPlanner;
301
+ this._planDependencies = dependencyPlanner
302
+ ? capture(dependencyPlanner, "plan")
303
+ : null;
304
+ this._prepareDependencies = dependencyPlanner
305
+ ? capture(dependencyExecutor, "prepare")
306
+ : null;
307
+ this._readPreparedDependencies = dependencyPlanner
308
+ ? capture(dependencyExecutor, "readPrepared")
309
+ : null;
310
+ this._readPreparedDependenciesForKnowledge = dependencyPlanner
311
+ ? capture(dependencyExecutor, "readPreparedForKnowledge")
312
+ : null;
285
313
  SYNCHRONIZERS.add(this);
286
314
  }
287
315
 
316
+ async planRevocation(input) {
317
+ if (!this._planDependencies) {
318
+ throw new Error("knowledge dependency inventory planner is unavailable");
319
+ }
320
+ const planned = this._planDependencies(input);
321
+ captureGovernedKnowledgeDependencyInventoryPlan(
322
+ this._dependencyPlanner,
323
+ planned,
324
+ );
325
+ const knowledge = normalizeRecord(planned.knowledge, this, {
326
+ executionRecord: true,
327
+ });
328
+ if (knowledge.scope === "personal") {
329
+ throw new Error("personal knowledge cannot enter a shared sync channel");
330
+ }
331
+ await this._admit("publish", knowledge);
332
+ const prepared = await this._prepareDependencies(knowledge);
333
+ if (
334
+ prepared?.authenticated !== true ||
335
+ prepared.durable !== true ||
336
+ !DIGEST.test(prepared.operationDigest ?? "") ||
337
+ canonical(prepared.knowledge) !== canonical(knowledge)
338
+ ) {
339
+ throw new Error("knowledge dependency plan was not durably prepared");
340
+ }
341
+ const result = freeze({
342
+ inventory: planned.inventory,
343
+ knowledge,
344
+ operationDigest: prepared.operationDigest,
345
+ recovered: false,
346
+ });
347
+ PLANNED_REVOCATIONS.set(result, this);
348
+ return result;
349
+ }
350
+
351
+ async recoverPlannedRevocation({ operationDigest } = {}) {
352
+ if (
353
+ !this._readPreparedDependencies ||
354
+ !DIGEST.test(operationDigest ?? "")
355
+ ) {
356
+ throw new TypeError(
357
+ "planned revocation recovery is unavailable or invalid",
358
+ );
359
+ }
360
+ const prepared = this._readPreparedDependencies({ operationDigest });
361
+ if (
362
+ prepared?.authenticated !== true ||
363
+ prepared.durable !== true ||
364
+ prepared.operationDigest !== operationDigest
365
+ ) {
366
+ throw new Error("prepared knowledge revocation was not found");
367
+ }
368
+ const knowledge = normalizeRecord(prepared.knowledge, this, {
369
+ executionRecord: true,
370
+ });
371
+ await this._admit("publish", knowledge);
372
+ const result = freeze({
373
+ inventory: null,
374
+ knowledge,
375
+ operationDigest,
376
+ recovered: true,
377
+ });
378
+ PLANNED_REVOCATIONS.set(result, this);
379
+ return result;
380
+ }
381
+
382
+ async publishPlanned(plan, options = {}) {
383
+ if (PLANNED_REVOCATIONS.get(plan) !== this) {
384
+ throw new TypeError(
385
+ "a revocation plan prepared by this sync is required",
386
+ );
387
+ }
388
+ return this.publishWithArtifactEvidence(plan.knowledge, options);
389
+ }
390
+
288
391
  async publish(input, options = {}) {
289
392
  const result = await this.publishWithArtifactEvidence(input, options);
290
393
  return result.envelope;
@@ -602,7 +705,8 @@ export class GovernedKnowledgeSync {
602
705
  activate: binding.activate,
603
706
  humanReviewed: binding.humanReviewed,
604
707
  });
605
- await this._applyRevocationDependencies(knowledge);
708
+ const dependencyKnowledge = await this._receivedDependencyPlan(knowledge);
709
+ await this._applyRevocationDependencies(dependencyKnowledge);
606
710
  await this._persist(
607
711
  knowledge,
608
712
  envelope,
@@ -711,6 +815,65 @@ export class GovernedKnowledgeSync {
711
815
  throw new Error("revocation dependencies were not durably applied");
712
816
  }
713
817
  }
818
+
819
+ async _receivedDependencyPlan(remoteKnowledge) {
820
+ if (
821
+ !["tombstone", "revoke"].includes(remoteKnowledge.action) ||
822
+ !this._planDependencies
823
+ ) {
824
+ return remoteKnowledge;
825
+ }
826
+ const portable = (value) => {
827
+ const copy = clone(value);
828
+ delete copy.dependencies;
829
+ return copy;
830
+ };
831
+ const recovered =
832
+ this._readPreparedDependenciesForKnowledge(remoteKnowledge);
833
+ let localKnowledge;
834
+ if (recovered) {
835
+ if (
836
+ recovered.authenticated !== true ||
837
+ recovered.durable !== true ||
838
+ !DIGEST.test(recovered.operationDigest ?? "")
839
+ ) {
840
+ throw new Error("received revocation local plan is unauthenticated");
841
+ }
842
+ localKnowledge = normalizeRecord(recovered.knowledge, this, {
843
+ executionRecord: true,
844
+ });
845
+ } else {
846
+ const draft = portable(remoteKnowledge);
847
+ delete draft.schema;
848
+ const planned = this._planDependencies(draft);
849
+ captureGovernedKnowledgeDependencyInventoryPlan(
850
+ this._dependencyPlanner,
851
+ planned,
852
+ );
853
+ localKnowledge = normalizeRecord(planned.knowledge, this, {
854
+ executionRecord: true,
855
+ });
856
+ }
857
+ if (
858
+ canonical(portable(localKnowledge)) !==
859
+ canonical(portable(remoteKnowledge))
860
+ ) {
861
+ throw new Error(
862
+ "received revocation local plan changed signed knowledge",
863
+ );
864
+ }
865
+ const prepared = await this._prepareDependencies(localKnowledge);
866
+ if (
867
+ prepared?.authenticated !== true ||
868
+ prepared.durable !== true ||
869
+ canonical(prepared.knowledge) !== canonical(localKnowledge)
870
+ ) {
871
+ throw new Error(
872
+ "received revocation local plan was not durably prepared",
873
+ );
874
+ }
875
+ return localKnowledge;
876
+ }
714
877
  }
715
878
 
716
879
  export function isGovernedKnowledgeSync(value) {
@@ -2,7 +2,7 @@ import { types } from "node:util";
2
2
  import { captureWikiRevisionReader } from "./wiki-maintainer-ledger-adapter.js";
3
3
  import { captureSkillReleaseOperationReader } from "./evolution-ledger-ports.js";
4
4
  import { governedKnowledgeSourceRef } from "./governed-knowledge-skill-rollback.js";
5
- import { deriveWikiTargetTombstoneRevision } from "./wiki-target-tombstone-revision.js";
5
+ import { deriveWikiTargetDispositionRevision } from "./wiki-target-tombstone-revision.js";
6
6
  import {
7
7
  createGovernedKnowledgeDependencyAuthority,
8
8
  GOVERNED_KNOWLEDGE_DEPENDENCY_RESULT_SCHEMA,
@@ -39,6 +39,36 @@ const MULTIHOP_RULES_DIGEST = digest(MULTIHOP_SCHEMA, {
39
39
  schema: MULTIHOP_SCHEMA,
40
40
  source: "authenticated-pinned-Wiki-exact-Knowledge-ancestry",
41
41
  });
42
+ const QUARANTINE_SCHEMA = "chainlesschain.knowledge-wiki-quarantine/v1";
43
+ const QUARANTINE_RULES = Object.freeze({
44
+ ...RULES,
45
+ schema: QUARANTINE_SCHEMA,
46
+ effect: "target-only-quarantine",
47
+ });
48
+ const QUARANTINE_RULES_DIGEST = digest(QUARANTINE_SCHEMA, QUARANTINE_RULES);
49
+ const QUARANTINE_MULTIHOP_SCHEMA =
50
+ "chainlesschain.knowledge-wiki-quarantine/v2";
51
+ const QUARANTINE_MULTIHOP_RULES_DIGEST = digest(QUARANTINE_MULTIHOP_SCHEMA, {
52
+ ...QUARANTINE_RULES,
53
+ schema: QUARANTINE_MULTIHOP_SCHEMA,
54
+ source: "authenticated-pinned-Wiki-exact-Knowledge-ancestry",
55
+ });
56
+ const TOMBSTONE = Object.freeze({
57
+ disposition: "tombstone",
58
+ schema: SCHEMA,
59
+ rulesDigest: RULES_DIGEST,
60
+ multihopSchema: MULTIHOP_SCHEMA,
61
+ multihopRulesDigest: MULTIHOP_RULES_DIGEST,
62
+ model: "deterministic:knowledge-wiki-tombstone",
63
+ });
64
+ const QUARANTINE = Object.freeze({
65
+ disposition: "quarantine",
66
+ schema: QUARANTINE_SCHEMA,
67
+ rulesDigest: QUARANTINE_RULES_DIGEST,
68
+ multihopSchema: QUARANTINE_MULTIHOP_SCHEMA,
69
+ multihopRulesDigest: QUARANTINE_MULTIHOP_RULES_DIGEST,
70
+ model: "deterministic:knowledge-wiki-quarantine",
71
+ });
42
72
  function fail(message) {
43
73
  throw new Error(`Knowledge Wiki tombstone: ${message}`);
44
74
  }
@@ -57,7 +87,7 @@ function bind(wikiAdapter, transactionLedger, tenantId) {
57
87
  );
58
88
  return Object.freeze({ wiki, operations });
59
89
  }
60
- function partsFor(source, request, provenance) {
90
+ function partsFor(source, request, provenance, configuration) {
61
91
  const sourceRef = governedKnowledgeSourceRef(request);
62
92
  const refs = new Set(
63
93
  Object.values(source.state.evidence)
@@ -82,7 +112,7 @@ function partsFor(source, request, provenance) {
82
112
  .sort();
83
113
  const targetIds = provenance.affectedPatternIds;
84
114
  const operations = targetIds.map((patternId) => ({
85
- type: "tombstone",
115
+ type: configuration.disposition,
86
116
  patternId,
87
117
  reason: "governed-knowledge-revocation",
88
118
  }));
@@ -93,7 +123,7 @@ function partsFor(source, request, provenance) {
93
123
  // v2 contract, pinned to the original revision rather than today's head.
94
124
  const sourceProofDigest = same(directIds, targetIds)
95
125
  ? null
96
- : digest(`${MULTIHOP_SCHEMA}/source`, {
126
+ : digest(`${configuration.multihopSchema}/source`, {
97
127
  revisionId: provenance.revisionId,
98
128
  stateDigest: provenance.stateDigest,
99
129
  checkpoint: provenance.checkpoint,
@@ -111,7 +141,7 @@ function partsFor(source, request, provenance) {
111
141
  operations: batch,
112
142
  ...(sourceProofDigest ? { sourceProofDigest } : {}),
113
143
  requestDigest: digest(
114
- `${sourceProofDigest ? MULTIHOP_SCHEMA : SCHEMA}/batch`,
144
+ `${sourceProofDigest ? configuration.multihopSchema : configuration.schema}/batch`,
115
145
  {
116
146
  requestDigest: request.requestDigest,
117
147
  index,
@@ -123,8 +153,8 @@ function partsFor(source, request, provenance) {
123
153
  };
124
154
  });
125
155
  }
126
- function derive(reader, source, part, fence) {
127
- return deriveWikiTargetTombstoneRevision({
156
+ function derive(reader, source, part, fence, configuration) {
157
+ return deriveWikiTargetDispositionRevision({
128
158
  source,
129
159
  operations: part.operations,
130
160
  requestDigest: part.requestDigest,
@@ -132,24 +162,24 @@ function derive(reader, source, part, fence) {
132
162
  descriptor: {
133
163
  tenantId: reader.wiki.descriptor.tenantId,
134
164
  evolutionRunId: reader.wiki.descriptor.evolutionRunId,
135
- maintainerModel: part.sourceProofDigest
136
- ? "deterministic:knowledge-wiki-tombstone/v2"
137
- : "deterministic:knowledge-wiki-tombstone/v1",
165
+ maintainerModel: `${configuration.model}/${part.sourceProofDigest ? "v2" : "v1"}`,
138
166
  rulesDigest: part.sourceProofDigest
139
- ? MULTIHOP_RULES_DIGEST
140
- : RULES_DIGEST,
167
+ ? configuration.multihopRulesDigest
168
+ : configuration.rulesDigest,
141
169
  minCorroboratingSources: RULES.minCorroboratingSources,
142
170
  decayHalfLifeDays: RULES.decayHalfLifeDays,
143
171
  staleConfidenceFloor: RULES.staleConfidenceFloor,
144
172
  },
145
173
  });
146
174
  }
147
- async function prove(reader, request, context, original) {
175
+ async function prove(reader, request, context, original, configuration) {
148
176
  if (
149
177
  request.dependency.kind !== "wiki" ||
150
- request.dependency.disposition !== "tombstone"
178
+ request.dependency.disposition !== configuration.disposition
151
179
  )
152
- fail("only an exact wiki / tombstone dependency is supported");
180
+ fail(
181
+ `only an exact wiki / ${configuration.disposition} dependency is supported`,
182
+ );
153
183
  const admission = reader.operations.resolveKnowledgeRevocation({
154
184
  tenantId: request.tenantId,
155
185
  operationDigest: request.operationDigest,
@@ -189,7 +219,7 @@ async function prove(reader, request, context, original) {
189
219
  !matchHead(context.checkpoint, provenance.ledgerHead)
190
220
  )
191
221
  fail("Wiki ancestry does not bind the original state and current ledger");
192
- const parts = partsFor(original, request, provenance);
222
+ const parts = partsFor(original, request, provenance, configuration);
193
223
  const history = reader.wiki.resolveHistory({
194
224
  tenantId: request.tenantId,
195
225
  stateDigest: request.dependency.digest,
@@ -204,7 +234,13 @@ async function prove(reader, request, context, original) {
204
234
  for (const [index, entry] of history.successors.entries()) {
205
235
  if (entry.predecessorHead.sequence < fence.sequence)
206
236
  fail("Wiki effect predates its prepared Knowledge authorization");
207
- const expected = await derive(reader, source, parts[index], fence);
237
+ const expected = await derive(
238
+ reader,
239
+ source,
240
+ parts[index],
241
+ fence,
242
+ configuration,
243
+ );
208
244
  if (!same(expected, entry.revision))
209
245
  fail("Wiki successor does not match the exact target-only tombstones");
210
246
  source = {
@@ -228,17 +264,18 @@ async function prove(reader, request, context, original) {
228
264
  });
229
265
  }
230
266
 
231
- export function createGovernedKnowledgeWikiTombstoneAuthority({
232
- tenantId,
233
- deviceId,
234
- wikiLedgerAdapter,
235
- transactionLedger,
236
- verifierWikiLedgerAdapter,
237
- verifierTransactionLedger,
238
- providerDescriptor,
239
- verifierDescriptor,
240
- additionalWikiTargets = [],
241
- } = {}) {
267
+ function createWikiDispositionAuthority(options = {}, configuration) {
268
+ const {
269
+ tenantId,
270
+ deviceId,
271
+ wikiLedgerAdapter,
272
+ transactionLedger,
273
+ verifierWikiLedgerAdapter,
274
+ verifierTransactionLedger,
275
+ providerDescriptor,
276
+ verifierDescriptor,
277
+ additionalWikiTargets = [],
278
+ } = options;
242
279
  if (
243
280
  wikiLedgerAdapter === verifierWikiLedgerAdapter ||
244
281
  transactionLedger === verifierTransactionLedger
@@ -354,12 +391,14 @@ export function createGovernedKnowledgeWikiTombstoneAuthority({
354
391
  request,
355
392
  context,
356
393
  selected.original,
394
+ configuration,
357
395
  );
358
396
  const independent = await prove(
359
397
  selected.binding.verifier,
360
398
  request,
361
399
  context,
362
400
  selected.independentOriginal,
401
+ configuration,
363
402
  );
364
403
  if (!same(primary, independent))
365
404
  fail("independent Wiki effect proof differs");
@@ -407,6 +446,7 @@ export function createGovernedKnowledgeWikiTombstoneAuthority({
407
446
  proof.current,
408
447
  proof.parts[done],
409
448
  proof.fence,
449
+ configuration,
410
450
  );
411
451
  let commitError = null;
412
452
  try {
@@ -449,14 +489,28 @@ export function createGovernedKnowledgeWikiTombstoneAuthority({
449
489
  providerRevision: providerIdentity.revision,
450
490
  verifierAuthorityId: verifierIdentity.authorityId,
451
491
  verifierRevision: verifierIdentity.revision,
452
- verificationReceiptDigest: digest(`${SCHEMA}/verification`, {
453
- requestDigest: request.requestDigest,
454
- resultDigest: result.resultDigest,
455
- proof,
456
- verifierIdentity,
457
- }),
492
+ verificationReceiptDigest: digest(
493
+ `${configuration.schema}/verification`,
494
+ {
495
+ requestDigest: request.requestDigest,
496
+ resultDigest: result.resultDigest,
497
+ proof,
498
+ verifierIdentity,
499
+ },
500
+ ),
458
501
  });
459
502
  },
460
503
  }),
461
504
  });
462
505
  }
506
+
507
+ export function createGovernedKnowledgeWikiTombstoneAuthority(options = {}) {
508
+ return createWikiDispositionAuthority(options, TOMBSTONE);
509
+ }
510
+
511
+ // Quarantine is a distinct non-deletion state. The generic Wiki maintainer
512
+ // refuses to rewrite quarantined patterns, so only a future separately governed
513
+ // release authority can make them actionable again.
514
+ export function createGovernedKnowledgeWikiQuarantineAuthority(options = {}) {
515
+ return createWikiDispositionAuthority(options, QUARANTINE);
516
+ }