@origintrail-official/dkg-agent 10.0.20 → 10.0.21

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 (535) hide show
  1. package/dist/approved-private-replica.d.ts +54 -0
  2. package/dist/approved-private-replica.d.ts.map +1 -0
  3. package/dist/approved-private-replica.js +148 -0
  4. package/dist/approved-private-replica.js.map +1 -0
  5. package/dist/bounded-operation.d.ts +2 -0
  6. package/dist/bounded-operation.d.ts.map +1 -1
  7. package/dist/bounded-operation.js +5 -0
  8. package/dist/bounded-operation.js.map +1 -1
  9. package/dist/chain-finality-confirmations-v1.d.ts +7 -0
  10. package/dist/chain-finality-confirmations-v1.d.ts.map +1 -0
  11. package/dist/chain-finality-confirmations-v1.js +9 -0
  12. package/dist/chain-finality-confirmations-v1.js.map +1 -0
  13. package/dist/chain-reconciler.d.ts +23 -0
  14. package/dist/chain-reconciler.d.ts.map +1 -1
  15. package/dist/chain-reconciler.js +35 -0
  16. package/dist/chain-reconciler.js.map +1 -1
  17. package/dist/context-graph-member-proof.d.ts +13 -0
  18. package/dist/context-graph-member-proof.d.ts.map +1 -1
  19. package/dist/context-graph-member-proof.js +36 -0
  20. package/dist/context-graph-member-proof.js.map +1 -1
  21. package/dist/context-graph-membership-persist-scheduler.d.ts +7 -23
  22. package/dist/context-graph-membership-persist-scheduler.d.ts.map +1 -1
  23. package/dist/context-graph-membership-persist-scheduler.js +12 -88
  24. package/dist/context-graph-membership-persist-scheduler.js.map +1 -1
  25. package/dist/context-graph-meta-projection.d.ts +13 -2
  26. package/dist/context-graph-meta-projection.d.ts.map +1 -1
  27. package/dist/context-graph-meta-projection.js +61 -24
  28. package/dist/context-graph-meta-projection.js.map +1 -1
  29. package/dist/context-graph-private-meta-proof.d.ts +5 -0
  30. package/dist/context-graph-private-meta-proof.d.ts.map +1 -1
  31. package/dist/context-graph-private-meta-proof.js +23 -0
  32. package/dist/context-graph-private-meta-proof.js.map +1 -1
  33. package/dist/context-graph-read-authority.d.ts +13 -0
  34. package/dist/context-graph-read-authority.d.ts.map +1 -1
  35. package/dist/context-graph-read-authority.js +23 -3
  36. package/dist/context-graph-read-authority.js.map +1 -1
  37. package/dist/context-graph-storage-discovery.d.ts +11 -2
  38. package/dist/context-graph-storage-discovery.d.ts.map +1 -1
  39. package/dist/context-graph-storage-discovery.js +11 -2
  40. package/dist/context-graph-storage-discovery.js.map +1 -1
  41. package/dist/context-graph-subscription-persist-scheduler.d.ts +52 -0
  42. package/dist/context-graph-subscription-persist-scheduler.d.ts.map +1 -0
  43. package/dist/context-graph-subscription-persist-scheduler.js +78 -0
  44. package/dist/context-graph-subscription-persist-scheduler.js.map +1 -0
  45. package/dist/curator-dial-address.d.ts +16 -0
  46. package/dist/curator-dial-address.d.ts.map +1 -0
  47. package/dist/curator-dial-address.js +58 -0
  48. package/dist/curator-dial-address.js.map +1 -0
  49. package/dist/curator-meta-refresh.d.ts +2 -0
  50. package/dist/curator-meta-refresh.d.ts.map +1 -1
  51. package/dist/curator-meta-refresh.js +2 -44
  52. package/dist/curator-meta-refresh.js.map +1 -1
  53. package/dist/curator-peer-connection.d.ts +21 -0
  54. package/dist/curator-peer-connection.d.ts.map +1 -0
  55. package/dist/curator-peer-connection.js +41 -0
  56. package/dist/curator-peer-connection.js.map +1 -0
  57. package/dist/dkg-agent-base.d.ts +94 -22
  58. package/dist/dkg-agent-base.d.ts.map +1 -1
  59. package/dist/dkg-agent-base.js +97 -144
  60. package/dist/dkg-agent-base.js.map +1 -1
  61. package/dist/dkg-agent-cg-registry.d.ts +10 -0
  62. package/dist/dkg-agent-cg-registry.d.ts.map +1 -1
  63. package/dist/dkg-agent-cg-registry.js +176 -115
  64. package/dist/dkg-agent-cg-registry.js.map +1 -1
  65. package/dist/dkg-agent-cg-resolve.d.ts +6 -4
  66. package/dist/dkg-agent-cg-resolve.d.ts.map +1 -1
  67. package/dist/dkg-agent-cg-resolve.js +22 -16
  68. package/dist/dkg-agent-cg-resolve.js.map +1 -1
  69. package/dist/dkg-agent-constants.d.ts +4 -2
  70. package/dist/dkg-agent-constants.d.ts.map +1 -1
  71. package/dist/dkg-agent-constants.js +4 -2
  72. package/dist/dkg-agent-constants.js.map +1 -1
  73. package/dist/dkg-agent-crypto.d.ts +101 -21
  74. package/dist/dkg-agent-crypto.d.ts.map +1 -1
  75. package/dist/dkg-agent-crypto.js +670 -152
  76. package/dist/dkg-agent-crypto.js.map +1 -1
  77. package/dist/dkg-agent-helpers.d.ts +2 -2
  78. package/dist/dkg-agent-helpers.d.ts.map +1 -1
  79. package/dist/dkg-agent-helpers.js +3 -3
  80. package/dist/dkg-agent-helpers.js.map +1 -1
  81. package/dist/dkg-agent-join.d.ts +12 -1
  82. package/dist/dkg-agent-join.d.ts.map +1 -1
  83. package/dist/dkg-agent-join.js +80 -92
  84. package/dist/dkg-agent-join.js.map +1 -1
  85. package/dist/dkg-agent-lifecycle.d.ts +58 -15
  86. package/dist/dkg-agent-lifecycle.d.ts.map +1 -1
  87. package/dist/dkg-agent-lifecycle.js +295 -114
  88. package/dist/dkg-agent-lifecycle.js.map +1 -1
  89. package/dist/dkg-agent-publish.d.ts +33 -40
  90. package/dist/dkg-agent-publish.d.ts.map +1 -1
  91. package/dist/dkg-agent-publish.js +190 -256
  92. package/dist/dkg-agent-publish.js.map +1 -1
  93. package/dist/dkg-agent-query.d.ts +7 -0
  94. package/dist/dkg-agent-query.d.ts.map +1 -1
  95. package/dist/dkg-agent-query.js +75 -63
  96. package/dist/dkg-agent-query.js.map +1 -1
  97. package/dist/dkg-agent-registered-private-empty-vm.d.ts +70 -0
  98. package/dist/dkg-agent-registered-private-empty-vm.d.ts.map +1 -0
  99. package/dist/dkg-agent-registered-private-empty-vm.js +133 -0
  100. package/dist/dkg-agent-registered-private-empty-vm.js.map +1 -0
  101. package/dist/dkg-agent-rfc64-catalog-auto-publish.d.ts +8 -3
  102. package/dist/dkg-agent-rfc64-catalog-auto-publish.d.ts.map +1 -1
  103. package/dist/dkg-agent-rfc64-catalog-auto-publish.js +45 -51
  104. package/dist/dkg-agent-rfc64-catalog-auto-publish.js.map +1 -1
  105. package/dist/dkg-agent-rfc64-catalog.d.ts +63 -87
  106. package/dist/dkg-agent-rfc64-catalog.d.ts.map +1 -1
  107. package/dist/dkg-agent-rfc64-catalog.js +595 -551
  108. package/dist/dkg-agent-rfc64-catalog.js.map +1 -1
  109. package/dist/dkg-agent-swm-host.d.ts +43 -52
  110. package/dist/dkg-agent-swm-host.d.ts.map +1 -1
  111. package/dist/dkg-agent-swm-host.js +629 -812
  112. package/dist/dkg-agent-swm-host.js.map +1 -1
  113. package/dist/dkg-agent-swm-state.d.ts +15 -0
  114. package/dist/dkg-agent-swm-state.d.ts.map +1 -1
  115. package/dist/dkg-agent-swm-state.js +43 -0
  116. package/dist/dkg-agent-swm-state.js.map +1 -1
  117. package/dist/dkg-agent-swm-substrate.d.ts +2 -0
  118. package/dist/dkg-agent-swm-substrate.d.ts.map +1 -1
  119. package/dist/dkg-agent-swm-substrate.js +110 -53
  120. package/dist/dkg-agent-swm-substrate.js.map +1 -1
  121. package/dist/dkg-agent-types.d.ts +62 -26
  122. package/dist/dkg-agent-types.d.ts.map +1 -1
  123. package/dist/dkg-agent-types.js.map +1 -1
  124. package/dist/dkg-agent-vm-promotion.d.ts +2 -0
  125. package/dist/dkg-agent-vm-promotion.d.ts.map +1 -1
  126. package/dist/dkg-agent-vm-promotion.js +39 -5
  127. package/dist/dkg-agent-vm-promotion.js.map +1 -1
  128. package/dist/dkg-agent.d.ts +8 -1
  129. package/dist/dkg-agent.d.ts.map +1 -1
  130. package/dist/dkg-agent.js +75 -45
  131. package/dist/dkg-agent.js.map +1 -1
  132. package/dist/exact-graph-content-verifier.d.ts.map +1 -1
  133. package/dist/exact-graph-content-verifier.js +3 -2
  134. package/dist/exact-graph-content-verifier.js.map +1 -1
  135. package/dist/finalization-handler.d.ts +19 -207
  136. package/dist/finalization-handler.d.ts.map +1 -1
  137. package/dist/finalization-handler.js +79 -1646
  138. package/dist/finalization-handler.js.map +1 -1
  139. package/dist/finalization-recovery-worker.js +1 -1
  140. package/dist/finalization-recovery-worker.js.map +1 -1
  141. package/dist/finalized-authority-cold-resolution.d.ts +6 -1
  142. package/dist/finalized-authority-cold-resolution.d.ts.map +1 -1
  143. package/dist/finalized-authority-cold-resolution.js +22 -3
  144. package/dist/finalized-authority-cold-resolution.js.map +1 -1
  145. package/dist/gossip-session.d.ts +29 -0
  146. package/dist/gossip-session.d.ts.map +1 -0
  147. package/dist/gossip-session.js +48 -0
  148. package/dist/gossip-session.js.map +1 -0
  149. package/dist/index.d.ts +3 -0
  150. package/dist/index.d.ts.map +1 -1
  151. package/dist/index.js +4 -0
  152. package/dist/index.js.map +1 -1
  153. package/dist/internal/context-graph-authority/context-graph-agent-gate-authority.d.ts +5 -5
  154. package/dist/internal/context-graph-authority/context-graph-agent-gate-authority.d.ts.map +1 -1
  155. package/dist/internal/context-graph-authority/context-graph-agent-gate-authority.js +59 -49
  156. package/dist/internal/context-graph-authority/context-graph-agent-gate-authority.js.map +1 -1
  157. package/dist/internal/context-graph-authority/finalized-target-projection.d.ts +17 -0
  158. package/dist/internal/context-graph-authority/finalized-target-projection.d.ts.map +1 -0
  159. package/dist/internal/context-graph-authority/finalized-target-projection.js +36 -0
  160. package/dist/internal/context-graph-authority/finalized-target-projection.js.map +1 -0
  161. package/dist/internal/context-graph-authority/swm-transport-authority.d.ts +43 -7
  162. package/dist/internal/context-graph-authority/swm-transport-authority.d.ts.map +1 -1
  163. package/dist/internal/context-graph-authority/swm-transport-authority.js +135 -18
  164. package/dist/internal/context-graph-authority/swm-transport-authority.js.map +1 -1
  165. package/dist/internal/context-graph-binding-abort.d.ts +3 -0
  166. package/dist/internal/context-graph-binding-abort.d.ts.map +1 -0
  167. package/dist/internal/context-graph-binding-abort.js +32 -0
  168. package/dist/internal/context-graph-binding-abort.js.map +1 -0
  169. package/dist/internal/context-graph-cache-invalidating-store.d.ts +3 -0
  170. package/dist/internal/context-graph-cache-invalidating-store.d.ts.map +1 -0
  171. package/dist/internal/context-graph-cache-invalidating-store.js +167 -0
  172. package/dist/internal/context-graph-cache-invalidating-store.js.map +1 -0
  173. package/dist/internal/context-graph-meta-record-copy.d.ts +3 -0
  174. package/dist/internal/context-graph-meta-record-copy.d.ts.map +1 -0
  175. package/dist/internal/context-graph-meta-record-copy.js +21 -0
  176. package/dist/internal/context-graph-meta-record-copy.js.map +1 -0
  177. package/dist/internal/gossip/host-mode-handler.d.ts +11 -0
  178. package/dist/internal/gossip/host-mode-handler.d.ts.map +1 -0
  179. package/dist/internal/gossip/host-mode-handler.js +41 -0
  180. package/dist/internal/gossip/host-mode-handler.js.map +1 -0
  181. package/dist/internal/join-encryption-key-bundle.d.ts +10 -0
  182. package/dist/internal/join-encryption-key-bundle.d.ts.map +1 -0
  183. package/dist/internal/join-encryption-key-bundle.js +72 -0
  184. package/dist/internal/join-encryption-key-bundle.js.map +1 -0
  185. package/dist/internal/knowledge-asset-vm-publish-request.d.ts +31 -0
  186. package/dist/internal/knowledge-asset-vm-publish-request.d.ts.map +1 -0
  187. package/dist/internal/knowledge-asset-vm-publish-request.js +91 -0
  188. package/dist/internal/knowledge-asset-vm-publish-request.js.map +1 -0
  189. package/dist/internal/lifecycle-sync-policy.d.ts +5 -0
  190. package/dist/internal/lifecycle-sync-policy.d.ts.map +1 -0
  191. package/dist/internal/lifecycle-sync-policy.js +12 -0
  192. package/dist/internal/lifecycle-sync-policy.js.map +1 -0
  193. package/dist/internal/local-private-member.d.ts +14 -0
  194. package/dist/internal/local-private-member.d.ts.map +1 -0
  195. package/dist/internal/local-private-member.js +21 -0
  196. package/dist/internal/local-private-member.js.map +1 -0
  197. package/dist/internal/promote/assertion-promote-precommit.d.ts +41 -1
  198. package/dist/internal/promote/assertion-promote-precommit.d.ts.map +1 -1
  199. package/dist/internal/promote/assertion-promote-precommit.js +74 -5
  200. package/dist/internal/promote/assertion-promote-precommit.js.map +1 -1
  201. package/dist/internal/storage-ack-owned-request.d.ts +16 -0
  202. package/dist/internal/storage-ack-owned-request.d.ts.map +1 -0
  203. package/dist/internal/storage-ack-owned-request.js +16 -0
  204. package/dist/internal/storage-ack-owned-request.js.map +1 -0
  205. package/dist/internal/vm-reconcile-local-admission-wait.d.ts +96 -0
  206. package/dist/internal/vm-reconcile-local-admission-wait.d.ts.map +1 -0
  207. package/dist/internal/vm-reconcile-local-admission-wait.js +226 -0
  208. package/dist/internal/vm-reconcile-local-admission-wait.js.map +1 -0
  209. package/dist/internal/vm-reconcile-read-authority.d.ts +27 -0
  210. package/dist/internal/vm-reconcile-read-authority.d.ts.map +1 -0
  211. package/dist/internal/vm-reconcile-read-authority.js +33 -0
  212. package/dist/internal/vm-reconcile-read-authority.js.map +1 -0
  213. package/dist/internal/vm-reconcile-sweep-admission.d.ts +2 -0
  214. package/dist/internal/vm-reconcile-sweep-admission.d.ts.map +1 -1
  215. package/dist/internal/vm-reconcile-sweep.d.ts +16 -4
  216. package/dist/internal/vm-reconcile-sweep.d.ts.map +1 -1
  217. package/dist/internal/vm-reconcile-sweep.js +91 -50
  218. package/dist/internal/vm-reconcile-sweep.js.map +1 -1
  219. package/dist/internal/workspace-projected-delegatees.d.ts +3 -0
  220. package/dist/internal/workspace-projected-delegatees.d.ts.map +1 -0
  221. package/dist/internal/workspace-projected-delegatees.js +34 -0
  222. package/dist/internal/workspace-projected-delegatees.js.map +1 -0
  223. package/dist/join-approval-restart-projection.d.ts +14 -0
  224. package/dist/join-approval-restart-projection.d.ts.map +1 -0
  225. package/dist/join-approval-restart-projection.js +32 -0
  226. package/dist/join-approval-restart-projection.js.map +1 -0
  227. package/dist/keyed-persist-scheduler.d.ts +72 -0
  228. package/dist/keyed-persist-scheduler.d.ts.map +1 -0
  229. package/dist/keyed-persist-scheduler.js +140 -0
  230. package/dist/keyed-persist-scheduler.js.map +1 -0
  231. package/dist/map-with-concurrency.d.ts +7 -0
  232. package/dist/map-with-concurrency.d.ts.map +1 -1
  233. package/dist/map-with-concurrency.js +36 -0
  234. package/dist/map-with-concurrency.js.map +1 -1
  235. package/dist/p2p/network-admission-coordinator.d.ts +15 -0
  236. package/dist/p2p/network-admission-coordinator.d.ts.map +1 -1
  237. package/dist/p2p/network-admission-coordinator.js +20 -2
  238. package/dist/p2p/network-admission-coordinator.js.map +1 -1
  239. package/dist/prepare-unscoped-context-graph-read-checks.d.ts.map +1 -1
  240. package/dist/prepare-unscoped-context-graph-read-checks.js +12 -0
  241. package/dist/prepare-unscoped-context-graph-read-checks.js.map +1 -1
  242. package/dist/registered-context-graph-authority.d.ts +7 -0
  243. package/dist/registered-context-graph-authority.d.ts.map +1 -1
  244. package/dist/registered-private-empty-vm-attempt-v1.d.ts +34 -0
  245. package/dist/registered-private-empty-vm-attempt-v1.d.ts.map +1 -0
  246. package/dist/registered-private-empty-vm-attempt-v1.js +120 -0
  247. package/dist/registered-private-empty-vm-attempt-v1.js.map +1 -0
  248. package/dist/reserved-ka-id-allocation.d.ts +12 -0
  249. package/dist/reserved-ka-id-allocation.d.ts.map +1 -0
  250. package/dist/reserved-ka-id-allocation.js +25 -0
  251. package/dist/reserved-ka-id-allocation.js.map +1 -0
  252. package/dist/rfc64/authority-rpc-circuit-breaker-v1.d.ts +5 -3
  253. package/dist/rfc64/authority-rpc-circuit-breaker-v1.d.ts.map +1 -1
  254. package/dist/rfc64/authority-rpc-circuit-breaker-v1.js +9 -0
  255. package/dist/rfc64/authority-rpc-circuit-breaker-v1.js.map +1 -1
  256. package/dist/rfc64/catalog-completion-evidence-v1.d.ts +38 -0
  257. package/dist/rfc64/catalog-completion-evidence-v1.d.ts.map +1 -0
  258. package/dist/rfc64/catalog-completion-evidence-v1.js +49 -0
  259. package/dist/rfc64/catalog-completion-evidence-v1.js.map +1 -0
  260. package/dist/rfc64/catalog-operational-applied-heads-v1.d.ts +6 -3
  261. package/dist/rfc64/catalog-operational-applied-heads-v1.d.ts.map +1 -1
  262. package/dist/rfc64/catalog-operational-applied-heads-v1.js +6 -3
  263. package/dist/rfc64/catalog-operational-applied-heads-v1.js.map +1 -1
  264. package/dist/rfc64/catalog-operational-reads-v1.d.ts +13 -0
  265. package/dist/rfc64/catalog-operational-reads-v1.d.ts.map +1 -0
  266. package/dist/rfc64/catalog-operational-reads-v1.js +56 -0
  267. package/dist/rfc64/catalog-operational-reads-v1.js.map +1 -0
  268. package/dist/rfc64/catalog-operational-targets-v1.d.ts +55 -0
  269. package/dist/rfc64/catalog-operational-targets-v1.d.ts.map +1 -0
  270. package/dist/rfc64/catalog-operational-targets-v1.js +379 -0
  271. package/dist/rfc64/catalog-operational-targets-v1.js.map +1 -0
  272. package/dist/rfc64/catalog-replay-recovery-runtime-v1.d.ts +2 -0
  273. package/dist/rfc64/catalog-replay-recovery-runtime-v1.d.ts.map +1 -1
  274. package/dist/rfc64/catalog-replay-recovery-runtime-v1.js +18 -25
  275. package/dist/rfc64/catalog-replay-recovery-runtime-v1.js.map +1 -1
  276. package/dist/rfc64/legacy-swm-boundary-codec-v1.d.ts +25 -0
  277. package/dist/rfc64/legacy-swm-boundary-codec-v1.d.ts.map +1 -0
  278. package/dist/rfc64/legacy-swm-boundary-codec-v1.js +127 -0
  279. package/dist/rfc64/legacy-swm-boundary-codec-v1.js.map +1 -0
  280. package/dist/rfc64/legacy-swm-boundary-v1.d.ts +12 -0
  281. package/dist/rfc64/legacy-swm-boundary-v1.d.ts.map +1 -1
  282. package/dist/rfc64/legacy-swm-boundary-v1.js +83 -144
  283. package/dist/rfc64/legacy-swm-boundary-v1.js.map +1 -1
  284. package/dist/rfc64/private-catalog-subscription-readiness-v1.d.ts +33 -0
  285. package/dist/rfc64/private-catalog-subscription-readiness-v1.d.ts.map +1 -0
  286. package/dist/rfc64/private-catalog-subscription-readiness-v1.js +97 -0
  287. package/dist/rfc64/private-catalog-subscription-readiness-v1.js.map +1 -0
  288. package/dist/rfc64/private-read-roster-v1.d.ts +14 -0
  289. package/dist/rfc64/private-read-roster-v1.d.ts.map +1 -0
  290. package/dist/rfc64/private-read-roster-v1.js +57 -0
  291. package/dist/rfc64/private-read-roster-v1.js.map +1 -0
  292. package/dist/rfc64/registered-private-empty-vm-proof-v1.d.ts +20 -0
  293. package/dist/rfc64/registered-private-empty-vm-proof-v1.d.ts.map +1 -0
  294. package/dist/rfc64/registered-private-empty-vm-proof-v1.js +26 -0
  295. package/dist/rfc64/registered-private-empty-vm-proof-v1.js.map +1 -0
  296. package/dist/rfc64/swm-inventory-shadow-runtime-v1.d.ts +3 -1
  297. package/dist/rfc64/swm-inventory-shadow-runtime-v1.d.ts.map +1 -1
  298. package/dist/rfc64/swm-inventory-shadow-runtime-v1.js +34 -0
  299. package/dist/rfc64/swm-inventory-shadow-runtime-v1.js.map +1 -1
  300. package/dist/sync/auth/pipe-request-tail.d.ts +5 -1
  301. package/dist/sync/auth/pipe-request-tail.d.ts.map +1 -1
  302. package/dist/sync/auth/pipe-request-tail.js +13 -3
  303. package/dist/sync/auth/pipe-request-tail.js.map +1 -1
  304. package/dist/sync/auth/request-build.d.ts +3 -0
  305. package/dist/sync/auth/request-build.d.ts.map +1 -1
  306. package/dist/sync/auth/request-build.js +11 -2
  307. package/dist/sync/auth/request-build.js.map +1 -1
  308. package/dist/sync/backpressure.d.ts +27 -16
  309. package/dist/sync/backpressure.d.ts.map +1 -1
  310. package/dist/sync/backpressure.js +66 -40
  311. package/dist/sync/backpressure.js.map +1 -1
  312. package/dist/sync/catchup-policy.d.ts +2 -0
  313. package/dist/sync/catchup-policy.d.ts.map +1 -1
  314. package/dist/sync/catchup-policy.js +2 -0
  315. package/dist/sync/catchup-policy.js.map +1 -1
  316. package/dist/sync/exact-assets.d.ts +7 -5
  317. package/dist/sync/exact-assets.d.ts.map +1 -1
  318. package/dist/sync/exact-assets.js +13 -8
  319. package/dist/sync/exact-assets.js.map +1 -1
  320. package/dist/sync/exact-batch-observation.d.ts +3 -0
  321. package/dist/sync/exact-batch-observation.d.ts.map +1 -0
  322. package/dist/sync/exact-batch-observation.js +13 -0
  323. package/dist/sync/exact-batch-observation.js.map +1 -0
  324. package/dist/sync/exact-batch-stream-capability.d.ts +24 -0
  325. package/dist/sync/exact-batch-stream-capability.d.ts.map +1 -0
  326. package/dist/sync/exact-batch-stream-capability.js +88 -0
  327. package/dist/sync/exact-batch-stream-capability.js.map +1 -0
  328. package/dist/sync/exact-batch-stream-contract.d.ts +78 -0
  329. package/dist/sync/exact-batch-stream-contract.d.ts.map +1 -0
  330. package/dist/sync/exact-batch-stream-contract.js +206 -0
  331. package/dist/sync/exact-batch-stream-contract.js.map +1 -0
  332. package/dist/sync/peer-connection.d.ts.map +1 -1
  333. package/dist/sync/peer-connection.js +11 -2
  334. package/dist/sync/peer-connection.js.map +1 -1
  335. package/dist/sync/priority-admission-queue.d.ts +17 -0
  336. package/dist/sync/priority-admission-queue.d.ts.map +1 -1
  337. package/dist/sync/priority-admission-queue.js +58 -37
  338. package/dist/sync/priority-admission-queue.js.map +1 -1
  339. package/dist/sync/requester/admission-boundary.d.ts +12 -0
  340. package/dist/sync/requester/admission-boundary.d.ts.map +1 -0
  341. package/dist/sync/requester/admission-boundary.js +22 -0
  342. package/dist/sync/requester/admission-boundary.js.map +1 -0
  343. package/dist/sync/requester/durable-sync.d.ts +2 -1
  344. package/dist/sync/requester/durable-sync.d.ts.map +1 -1
  345. package/dist/sync/requester/durable-sync.js +3 -188
  346. package/dist/sync/requester/durable-sync.js.map +1 -1
  347. package/dist/sync/requester/exact-batch-stream-driver.d.ts +83 -0
  348. package/dist/sync/requester/exact-batch-stream-driver.d.ts.map +1 -0
  349. package/dist/sync/requester/exact-batch-stream-driver.js +299 -0
  350. package/dist/sync/requester/exact-batch-stream-driver.js.map +1 -0
  351. package/dist/sync/requester/exact-batch-stream.d.ts +72 -0
  352. package/dist/sync/requester/exact-batch-stream.d.ts.map +1 -0
  353. package/dist/sync/requester/exact-batch-stream.js +267 -0
  354. package/dist/sync/requester/exact-batch-stream.js.map +1 -0
  355. package/dist/sync/requester/exact-recovery-transport.d.ts +19 -0
  356. package/dist/sync/requester/exact-recovery-transport.d.ts.map +1 -0
  357. package/dist/sync/requester/exact-recovery-transport.js +3 -0
  358. package/dist/sync/requester/exact-recovery-transport.js.map +1 -0
  359. package/dist/sync/requester/finalized-swm-twin-reconciliation.js +12 -3
  360. package/dist/sync/requester/finalized-swm-twin-reconciliation.js.map +1 -1
  361. package/dist/sync/requester/graph-scoped-materialization.d.ts.map +1 -1
  362. package/dist/sync/requester/graph-scoped-materialization.js +58 -24
  363. package/dist/sync/requester/graph-scoped-materialization.js.map +1 -1
  364. package/dist/sync/requester/page-fetch.d.ts +7 -0
  365. package/dist/sync/requester/page-fetch.d.ts.map +1 -1
  366. package/dist/sync/requester/page-fetch.js +103 -49
  367. package/dist/sync/requester/page-fetch.js.map +1 -1
  368. package/dist/sync/requester/shared-memory-sync.d.ts +10 -5
  369. package/dist/sync/requester/shared-memory-sync.d.ts.map +1 -1
  370. package/dist/sync/requester/shared-memory-sync.js +149 -150
  371. package/dist/sync/requester/shared-memory-sync.js.map +1 -1
  372. package/dist/sync/requester/swm-materialization-memo.d.ts +12 -0
  373. package/dist/sync/requester/swm-materialization-memo.d.ts.map +1 -0
  374. package/dist/sync/requester/swm-materialization-memo.js +54 -0
  375. package/dist/sync/requester/swm-materialization-memo.js.map +1 -0
  376. package/dist/sync/requester/swm-recovery.d.ts +3 -29
  377. package/dist/sync/requester/swm-recovery.d.ts.map +1 -1
  378. package/dist/sync/requester/swm-recovery.js +11 -10
  379. package/dist/sync/requester/swm-recovery.js.map +1 -1
  380. package/dist/sync/requester/swm-snapshot-materializer.d.ts.map +1 -1
  381. package/dist/sync/requester/swm-snapshot-materializer.js +18 -0
  382. package/dist/sync/requester/swm-snapshot-materializer.js.map +1 -1
  383. package/dist/sync/requester/swm-target-executor.d.ts +6 -0
  384. package/dist/sync/requester/swm-target-executor.d.ts.map +1 -1
  385. package/dist/sync/requester/swm-target-executor.js +24 -3
  386. package/dist/sync/requester/swm-target-executor.js.map +1 -1
  387. package/dist/sync/requester/verified-asset-preparation.d.ts +9 -0
  388. package/dist/sync/requester/verified-asset-preparation.d.ts.map +1 -0
  389. package/dist/sync/requester/verified-asset-preparation.js +190 -0
  390. package/dist/sync/requester/verified-asset-preparation.js.map +1 -0
  391. package/dist/sync/responder/asset-metadata.d.ts +18 -0
  392. package/dist/sync/responder/asset-metadata.d.ts.map +1 -0
  393. package/dist/sync/responder/asset-metadata.js +27 -0
  394. package/dist/sync/responder/asset-metadata.js.map +1 -0
  395. package/dist/sync/responder/durable-data-request-policy.d.ts +2 -16
  396. package/dist/sync/responder/durable-data-request-policy.d.ts.map +1 -1
  397. package/dist/sync/responder/durable-data-request-policy.js +1 -31
  398. package/dist/sync/responder/durable-data-request-policy.js.map +1 -1
  399. package/dist/sync/responder/exact-asset-export-cache.d.ts +89 -0
  400. package/dist/sync/responder/exact-asset-export-cache.d.ts.map +1 -0
  401. package/dist/sync/responder/exact-asset-export-cache.js +550 -0
  402. package/dist/sync/responder/exact-asset-export-cache.js.map +1 -0
  403. package/dist/sync/responder/exact-batch-stream.d.ts +47 -0
  404. package/dist/sync/responder/exact-batch-stream.d.ts.map +1 -0
  405. package/dist/sync/responder/exact-batch-stream.js +151 -0
  406. package/dist/sync/responder/exact-batch-stream.js.map +1 -0
  407. package/dist/sync/responder/exact-data-session.d.ts +67 -0
  408. package/dist/sync/responder/exact-data-session.d.ts.map +1 -0
  409. package/dist/sync/responder/exact-data-session.js +130 -0
  410. package/dist/sync/responder/exact-data-session.js.map +1 -0
  411. package/dist/sync/responder/exact-graph-cursor-filter.d.ts +9 -0
  412. package/dist/sync/responder/exact-graph-cursor-filter.d.ts.map +1 -0
  413. package/dist/sync/responder/exact-graph-cursor-filter.js +101 -0
  414. package/dist/sync/responder/exact-graph-cursor-filter.js.map +1 -0
  415. package/dist/sync/responder/exact-graph-reader.d.ts +95 -0
  416. package/dist/sync/responder/exact-graph-reader.d.ts.map +1 -0
  417. package/dist/sync/responder/exact-graph-reader.js +623 -0
  418. package/dist/sync/responder/exact-graph-reader.js.map +1 -0
  419. package/dist/sync/responder/exact-page-reader.d.ts +37 -0
  420. package/dist/sync/responder/exact-page-reader.d.ts.map +1 -0
  421. package/dist/sync/responder/exact-page-reader.js +130 -0
  422. package/dist/sync/responder/exact-page-reader.js.map +1 -0
  423. package/dist/sync/responder/graph-plan.d.ts +19 -85
  424. package/dist/sync/responder/graph-plan.d.ts.map +1 -1
  425. package/dist/sync/responder/graph-plan.js +51 -988
  426. package/dist/sync/responder/graph-plan.js.map +1 -1
  427. package/dist/sync/responder/page-framing-policy.d.ts +31 -0
  428. package/dist/sync/responder/page-framing-policy.d.ts.map +1 -0
  429. package/dist/sync/responder/page-framing-policy.js +41 -0
  430. package/dist/sync/responder/page-framing-policy.js.map +1 -0
  431. package/dist/sync/responder/responder-row-page.d.ts +85 -0
  432. package/dist/sync/responder/responder-row-page.d.ts.map +1 -0
  433. package/dist/sync/responder/responder-row-page.js +181 -0
  434. package/dist/sync/responder/responder-row-page.js.map +1 -0
  435. package/dist/sync/responder/row-serialization.d.ts +34 -0
  436. package/dist/sync/responder/row-serialization.d.ts.map +1 -0
  437. package/dist/sync/responder/row-serialization.js +69 -0
  438. package/dist/sync/responder/row-serialization.js.map +1 -0
  439. package/dist/sync/responder/session-plan-memo.d.ts +20 -0
  440. package/dist/sync/responder/session-plan-memo.d.ts.map +1 -0
  441. package/dist/sync/responder/session-plan-memo.js +135 -0
  442. package/dist/sync/responder/session-plan-memo.js.map +1 -0
  443. package/dist/sync/responder/sync-handler.d.ts +18 -1
  444. package/dist/sync/responder/sync-handler.d.ts.map +1 -1
  445. package/dist/sync/responder/sync-handler.js +101 -57
  446. package/dist/sync/responder/sync-handler.js.map +1 -1
  447. package/dist/sync/shared-memory-completion.d.ts +30 -0
  448. package/dist/sync/shared-memory-completion.d.ts.map +1 -1
  449. package/dist/sync/shared-memory-completion.js +13 -0
  450. package/dist/sync/shared-memory-completion.js.map +1 -1
  451. package/dist/sync/wire-compression.d.ts +47 -0
  452. package/dist/sync/wire-compression.d.ts.map +1 -0
  453. package/dist/sync/wire-compression.js +111 -0
  454. package/dist/sync/wire-compression.js.map +1 -0
  455. package/dist/unscoped-query-consistency.d.ts +12 -0
  456. package/dist/unscoped-query-consistency.d.ts.map +1 -1
  457. package/dist/unscoped-query-consistency.js +17 -1
  458. package/dist/unscoped-query-consistency.js.map +1 -1
  459. package/dist/vm-promotion-audit.d.ts +2 -2
  460. package/dist/vm-promotion-audit.d.ts.map +1 -1
  461. package/dist/vm-promotion-audit.js +26 -9
  462. package/dist/vm-promotion-audit.js.map +1 -1
  463. package/dist/vm-reconcile-dispatcher.d.ts +42 -1
  464. package/dist/vm-reconcile-dispatcher.d.ts.map +1 -1
  465. package/dist/vm-reconcile-dispatcher.js +103 -4
  466. package/dist/vm-reconcile-dispatcher.js.map +1 -1
  467. package/dist/vm-reconcile-peer-topology.d.ts +7 -9
  468. package/dist/vm-reconcile-peer-topology.d.ts.map +1 -1
  469. package/dist/vm-reconcile-peer-topology.js +1 -37
  470. package/dist/vm-reconcile-peer-topology.js.map +1 -1
  471. package/dist/vm-recovery-candidate-order.d.ts +16 -0
  472. package/dist/vm-recovery-candidate-order.d.ts.map +1 -0
  473. package/dist/vm-recovery-candidate-order.js +24 -0
  474. package/dist/vm-recovery-candidate-order.js.map +1 -0
  475. package/dist/vm-recovery-core-transport-preference.d.ts +69 -0
  476. package/dist/vm-recovery-core-transport-preference.d.ts.map +1 -0
  477. package/dist/vm-recovery-core-transport-preference.js +131 -0
  478. package/dist/vm-recovery-core-transport-preference.js.map +1 -0
  479. package/dist/vm-recovery-experiment-policy.d.ts +24 -0
  480. package/dist/vm-recovery-experiment-policy.d.ts.map +1 -0
  481. package/dist/vm-recovery-experiment-policy.js +18 -0
  482. package/dist/vm-recovery-experiment-policy.js.map +1 -0
  483. package/dist/vm-recovery-footprint.d.ts +54 -0
  484. package/dist/vm-recovery-footprint.d.ts.map +1 -1
  485. package/dist/vm-recovery-footprint.js +88 -24
  486. package/dist/vm-recovery-footprint.js.map +1 -1
  487. package/dist/vm-recovery-microbatch.d.ts +2 -0
  488. package/dist/vm-recovery-microbatch.d.ts.map +1 -1
  489. package/dist/vm-recovery-microbatch.js +7 -3
  490. package/dist/vm-recovery-microbatch.js.map +1 -1
  491. package/dist/vm-recovery-pass-authority.d.ts +84 -0
  492. package/dist/vm-recovery-pass-authority.d.ts.map +1 -0
  493. package/dist/vm-recovery-pass-authority.js +126 -0
  494. package/dist/vm-recovery-pass-authority.js.map +1 -0
  495. package/dist/vm-recovery-phase-timing.d.ts +75 -0
  496. package/dist/vm-recovery-phase-timing.d.ts.map +1 -0
  497. package/dist/vm-recovery-phase-timing.js +236 -0
  498. package/dist/vm-recovery-phase-timing.js.map +1 -0
  499. package/dist/vm-recovery-preparation.d.ts +143 -0
  500. package/dist/vm-recovery-preparation.d.ts.map +1 -0
  501. package/dist/vm-recovery-preparation.js +433 -0
  502. package/dist/vm-recovery-preparation.js.map +1 -0
  503. package/dist/vm-recovery-provider-policy.d.ts +13 -1
  504. package/dist/vm-recovery-provider-policy.d.ts.map +1 -1
  505. package/dist/vm-recovery-provider-policy.js +37 -5
  506. package/dist/vm-recovery-provider-policy.js.map +1 -1
  507. package/dist/vm-recovery-stream-profile.d.ts +15 -0
  508. package/dist/vm-recovery-stream-profile.d.ts.map +1 -0
  509. package/dist/vm-recovery-stream-profile.js +53 -0
  510. package/dist/vm-recovery-stream-profile.js.map +1 -0
  511. package/dist/vm-recovery-stream-setback-policy.d.ts +54 -0
  512. package/dist/vm-recovery-stream-setback-policy.d.ts.map +1 -0
  513. package/dist/vm-recovery-stream-setback-policy.js +85 -0
  514. package/dist/vm-recovery-stream-setback-policy.js.map +1 -0
  515. package/dist/vm-recovery-timing-observer.d.ts +27 -0
  516. package/dist/vm-recovery-timing-observer.d.ts.map +1 -0
  517. package/dist/vm-recovery-timing-observer.js +49 -0
  518. package/dist/vm-recovery-timing-observer.js.map +1 -0
  519. package/dist/vm-recovery-transport-budget-policy.d.ts +32 -0
  520. package/dist/vm-recovery-transport-budget-policy.d.ts.map +1 -0
  521. package/dist/vm-recovery-transport-budget-policy.js +55 -0
  522. package/dist/vm-recovery-transport-budget-policy.js.map +1 -0
  523. package/dist/vm-recovery-transport-plan.d.ts +83 -0
  524. package/dist/vm-recovery-transport-plan.d.ts.map +1 -0
  525. package/dist/vm-recovery-transport-plan.js +117 -0
  526. package/dist/vm-recovery-transport-plan.js.map +1 -0
  527. package/package.json +17 -9
  528. package/dist/finalization-annotations.d.ts +0 -5
  529. package/dist/finalization-annotations.d.ts.map +0 -1
  530. package/dist/finalization-annotations.js +0 -6
  531. package/dist/finalization-annotations.js.map +0 -1
  532. package/dist/swm-ka-bound.d.ts +0 -21
  533. package/dist/swm-ka-bound.d.ts.map +0 -1
  534. package/dist/swm-ka-bound.js +0 -36
  535. package/dist/swm-ka-bound.js.map +0 -1
@@ -16,10 +16,15 @@
16
16
  * Gate-1 boundary: staging a fetched head is the terminal step. Nothing here
17
17
  * admits candidate rows or activates KA / SWM / VM state.
18
18
  */
19
- import { SYSTEM_CONTEXT_GRAPHS, ZERO_DIGEST32_V1, MAX_AUTHOR_CATALOG_BUCKET_ROWS_V1, contextGraphDataGraphUri, contextGraphMetaGraphUri, assertContextGraphIdV1, assertNetworkIdV1, assertSignedAuthorCatalogBucketEnvelopeV1, assertSignedAuthorCatalogDirectoryNodeEnvelopeV1, assertSignedAuthorCatalogHeadEnvelopeV1, assertSignedAuthorCatalogIssuerDelegationEnvelopeV1, computeAuthorCatalogScopeDigestV1, computeControlSignatureVariantDigestHex, createOperationContext, deriveAuthorCatalogScopeFromHeadV1, } from '@origintrail-official/dkg-core';
19
+ import { Rfc64CatalogTargetTrackerV1, rfc64CatalogTargetExactIdentityKeyV1 } from './rfc64/catalog-operational-targets-v1.js';
20
+ import { evaluateRfc64CatalogCompletionV1 } from './rfc64/catalog-completion-evidence-v1.js';
21
+ export { RFC64_CATALOG_TARGET_MAX_ENTRIES_V1, RFC64_CATALOG_TARGET_MAX_CONTEXT_OVERFLOWS_V1, Rfc64CatalogTargetTrackerV1, rfc64CatalogTargetExactIdentityKeyV1, projectRfc64OperationalRowCountsV1 } from './rfc64/catalog-operational-targets-v1.js';
22
+ import { SYSTEM_CONTEXT_GRAPHS, DKGEvent, ZERO_DIGEST32_V1, MAX_AUTHOR_CATALOG_BUCKET_ROWS_V1, contextGraphDataGraphUri, contextGraphMetaGraphUri, assertContextGraphIdV1, assertNetworkIdV1, assertSignedAuthorCatalogBucketEnvelopeV1, assertSignedAuthorCatalogDirectoryNodeEnvelopeV1, assertSignedAuthorCatalogHeadEnvelopeV1, assertSignedAuthorCatalogIssuerDelegationEnvelopeV1, computeAuthorCatalogScopeDigestV1, computeControlSignatureVariantDigestHex, createOperationContext, deriveAuthorCatalogScopeFromHeadV1, } from '@origintrail-official/dkg-core';
20
23
  import { assertContextGraphAuthorityIndexId, resolveRpcUrls, verifyControlEnvelopeIssuerSignatureV1, withRpcRequestContext, } from '@origintrail-official/dkg-chain';
21
24
  import { ethers } from 'ethers';
22
25
  import { DKGAgentBase } from './dkg-agent-base.js';
26
+ import { resolveChainFinalityConfirmationsV1 } from './chain-finality-confirmations-v1.js';
27
+ import { isApprovedPrivateReplicaDelegationActive, resolveApprovedPrivateReplicaAuthority, } from './approved-private-replica.js';
23
28
  import { Rfc64CatalogReplayConnectionRuntimeV1, } from './rfc64/catalog-replay-connection-runtime-v1.js';
24
29
  import { Rfc64CatalogReplayRecoveryRuntimeV1, } from './rfc64/catalog-replay-recovery-runtime-v1.js';
25
30
  export { RFC64_CATALOG_TARGET_MAX_ENTRIES_PER_CONTEXT_GRAPH_V1 } from './rfc64/catalog-limits-v1.js';
@@ -33,14 +38,16 @@ import { createRfc64FinalizedVmAgentPrecommitV1 } from './rfc64/finalized-vm-age
33
38
  import { createRfc64CatalogAppliedHeadCoordinatorV1, } from './rfc64/catalog-applied-head-coordinator-v1.js';
34
39
  import { reduceRfc64CatalogSynchronizationEvidenceReplayV1, snapshotRfc64CatalogSynchronizationEvidenceV1, } from './rfc64/catalog-synchronization-evidence-v1.js';
35
40
  import { createRfc64BoundedPublicRootCatalogNativeReconcilerV1, createRfc64VerifiedStagedCatalogHeadMemoV1, } from './rfc64/public-catalog-native-reconciler-v1.js';
36
- import { RFC64_OPERATIONAL_STATUS_HEAD_READ_CONCURRENCY_V1, loadRfc64OperationalAppliedHeadsV1, rfc64CatalogTargetScopeKeyV1, } from './rfc64/catalog-operational-applied-heads-v1.js';
37
- import { mapWithConcurrency } from './map-with-concurrency.js';
41
+ import { loadRfc64OperationalAppliedHeadsV1, rfc64CatalogTargetScopeKeyV1, } from './rfc64/catalog-operational-applied-heads-v1.js';
42
+ import { groupRfc64OperationalAppliedHeadsV1, loadRfc64OperationalPromisedRowCountsV1 } from './rfc64/catalog-operational-reads-v1.js';
43
+ import { verifyPrivateCatalogSubscriptionReadinessV1 } from './rfc64/private-catalog-subscription-readiness-v1.js';
38
44
  import { Rfc64PublicCatalogSuccessorProducerV1, } from './rfc64/public-catalog-successor-producer-v1.js';
39
- import { RFC64_PUBLIC_CATALOG_HEAD_ANNOUNCEMENT_KIND_V1, Rfc64PublicCatalogTransportErrorV1, } from './rfc64/public-catalog-transport-v1.js';
45
+ import { RFC64_PUBLIC_CATALOG_HEAD_ANNOUNCEMENT_KIND_V1, RFC64_PUBLIC_CATALOG_HEAD_REPLAY_KIND_V1, Rfc64PublicCatalogTransportErrorV1, } from './rfc64/public-catalog-transport-v1.js';
40
46
  import { createRfc64CatalogNativeScopedReadProviderV1 } from './rfc64/catalog-native-scoped-read-provider-v1.js';
41
47
  import { projectRfc64CatalogReceiverAuthorityV1, resolveRfc64CatalogResponsibilityAuthorityV1, } from './rfc64/public-catalog-activation-config-v1.js';
42
48
  import { Rfc64CatalogResponsibilityRegistryV1, resolveRfc64CatalogResponsibilityReasonV1, } from './rfc64/catalog-responsibility-registry-v1.js';
43
49
  import { projectRfc64CatalogTransportStateV1, rfc64CatalogResponsibilityOwnsAuthorityWorkloadV1, } from './rfc64/catalog-rollout-authority-v1.js';
50
+ import { isRfc64AuthorityRpcCircuitOpenErrorV1, } from './rfc64/authority-rpc-circuit-breaker-v1.js';
44
51
  import { composeRfc64FinalizedCatalogAuthorityV1, composeRfc64RegisteredRosterVersionV1, composeRfc64UnregisteredCatalogAuthorityV1, parseRfc64AuthoritySnapshotV1, } from './rfc64/release-native-catalog-authority-v1.js';
45
52
  import { acquireRfc64LegacySwmBoundaryReceiverLeaseV1, readRfc64LegacySwmBoundaryCountV1, } from './rfc64/legacy-swm-boundary-v1.js';
46
53
  import { Rfc64CatalogReplaySnapshotRuntimeV1, } from './rfc64/catalog-replay-snapshot-runtime-v1.js';
@@ -50,47 +57,6 @@ import { isRfc64SharedStorePressureFailureV1, } from './rfc64/catalog-authority-
50
57
  import { loadRfc64UnregisteredReplicaAuthorityV1 } from './rfc64/unregistered-replica-authority-v1.js';
51
58
  const RFC64_PRIVATE_ROSTER_VERSION_PREDICATE_V1 = 'https://dkg.network/ontology#rfc64RosterVersion';
52
59
  const RFC64_PRIVATE_ROSTER_VERSION_RADIX_V1 = 10000000000000n;
53
- function groupRfc64OperationalAppliedHeadsV1(heads) {
54
- const byContextGraph = new Map();
55
- for (const head of heads) {
56
- const grouped = byContextGraph.get(head.contextGraphId) ?? [];
57
- grouped.push(head);
58
- byContextGraph.set(head.contextGraphId, grouped);
59
- }
60
- return byContextGraph;
61
- }
62
- async function loadRfc64OperationalPromisedRowCountsV1(persistence, targets) {
63
- const uniqueTargets = new Map(targets.map((target) => [
64
- rfc64CatalogTargetExactIdentityKeyV1(target),
65
- target,
66
- ]));
67
- const loaded = await mapWithConcurrency([...uniqueTargets], RFC64_OPERATIONAL_STATUS_HEAD_READ_CONCURRENCY_V1, async ([identity, target]) => {
68
- const stored = await persistence.controlObjects.getVerifiedObject({
69
- objectDigest: target.catalogHeadObjectDigest,
70
- signatureVariantDigest: target.signatureVariantDigest,
71
- verifyIssuerSignature: verifyControlEnvelopeIssuerSignatureV1,
72
- }).catch(() => null);
73
- if (stored === null)
74
- return [identity, null];
75
- try {
76
- assertSignedAuthorCatalogHeadEnvelopeV1(stored.envelope);
77
- const payload = stored.envelope.payload;
78
- if (stored.envelope.objectDigest !== target.catalogHeadObjectDigest
79
- || payload.networkId !== target.networkId
80
- || payload.contextGraphId !== target.contextGraphId
81
- || payload.subGraphName !== target.subGraphName
82
- || payload.authorAddress !== target.authorAddress
83
- || payload.era !== target.catalogEra
84
- || payload.version !== target.catalogVersion)
85
- return [identity, null];
86
- return [identity, payload.totalRows];
87
- }
88
- catch {
89
- return [identity, null];
90
- }
91
- });
92
- return new Map(loaded);
93
- }
94
60
  export { RFC64_PUBLIC_CATALOG_RECONCILIATION_FAILURE_MAX_ENTRIES_V1, Rfc64CatalogReconciliationTerminalErrorV1, } from './rfc64/public-catalog-reconciliation-failure-v1.js';
95
61
  export { snapshotRfc64CatalogAccessPolicyAuthorityV1, snapshotRfc64CatalogDeploymentProfileV1, snapshotRfc64PublicCatalogAutoPublishConfigV1, snapshotRfc64PublicCatalogBootstrapConfigV1, } from './rfc64/catalog-authority-config-v1.js';
96
62
  import { CONTEXT_GRAPH_AUTHORITY_RPC_SITES as CG_AUTH_RPC_SITES, withRpcUsageSite, } from '@origintrail-official/dkg-chain';
@@ -100,6 +66,14 @@ const rfc64CatalogAuthorityProgressV1 = new WeakMap();
100
66
  const rfc64CatalogAuthorityRevisionsV1 = new WeakMap();
101
67
  const rfc64AuthorityAcceptedCatchupTimersV1 = new WeakMap();
102
68
  const rfc64DirectAcceptedCompatibilityV1 = new WeakMap();
69
+ /**
70
+ * Context graphs whose accepted policy was composed from a private join
71
+ * approval rather than from owner-signed or finalized evidence. The approval
72
+ * proof is time-limited and bound to one request generation, so this
73
+ * authority may run catalog responsibility but never stands in for the live
74
+ * proof on reads or shared-memory access.
75
+ */
76
+ const rfc64JoinDerivedAcceptedAuthorityV1 = new WeakMap();
103
77
  const rfc64ResponsibilityAuthorityBatchRuntimesV1 = new WeakMap();
104
78
  const rfc64ScheduledResponsibilityStatesV1 = new WeakMap();
105
79
  const rfc64SystemContextGraphIdsV1 = new Set(Object.values(SYSTEM_CONTEXT_GRAPHS));
@@ -119,15 +93,50 @@ const RFC64_AUTHORITY_CATALOG_RECOVERY_RETRY_DELAYS_MS_V1 = Object.freeze([
119
93
  1_000,
120
94
  4_000,
121
95
  ]);
96
+ /**
97
+ * A join-approved replica can accept its policy before its providers have the
98
+ * roster that names it. Only that replica keeps asking for this long.
99
+ */
100
+ const RFC64_JOIN_DERIVED_CATALOG_RECOVERY_RETRY_DELAYS_MS_V1 = Object.freeze([
101
+ ...RFC64_AUTHORITY_CATALOG_RECOVERY_RETRY_DELAYS_MS_V1,
102
+ 15_000,
103
+ 30_000,
104
+ 60_000,
105
+ 120_000,
106
+ 240_000,
107
+ ]);
108
+ const RFC64_JOIN_APPROVAL_CATALOG_REPLAY_RETRY_DELAYS_MS_V1 = Object.freeze([
109
+ 5_000,
110
+ 15_000,
111
+ 30_000,
112
+ 60_000,
113
+ ]);
114
+ /**
115
+ * Waits before an authority snapshot is composed again after local authority
116
+ * facts moved under the previous composition. The first retry is immediate;
117
+ * the later ones outlast the burst of local writes a join or a publish makes.
118
+ */
119
+ export const RFC64_AUTHORITY_FACTS_MOVED_RETRY_DELAYS_MS_V1 = Object.freeze([
120
+ 0,
121
+ 50,
122
+ 200,
123
+ 500,
124
+ 1_000,
125
+ 2_000,
126
+ ]);
122
127
  const RFC64_CATALOG_REPLAY_MAX_QUEUED_V1 = 64;
123
128
  const RFC64_CATALOG_REPLAY_MAX_QUEUED_PER_PEER_V1 = 4;
124
- export const RFC64_CATALOG_TARGET_MAX_ENTRIES_V1 = 1_024;
125
- export const RFC64_CATALOG_TARGET_MAX_CONTEXT_OVERFLOWS_V1 = 64;
126
129
  function isRfc64ActiveRegisteredSubscriptionV1(subscription) {
127
130
  return subscription?.subscribed === true
128
131
  && subscription.onChainId !== undefined
129
132
  && subscription.onChainHash !== undefined;
130
133
  }
134
+ /** A private join has no numeric binding while its signed _meta catches up. */
135
+ function isRfc64LocalJoinIntentUnregisteredSubscriptionV1(hasLocalJoinIntent, subscription) {
136
+ return subscription?.subscribed === true
137
+ && subscription.onChainId === undefined
138
+ && hasLocalJoinIntent;
139
+ }
131
140
  /**
132
141
  * Construct the complete retry identity once so dispatcher-key uniqueness,
133
142
  * the revision fence, attempt, and delay cannot drift at separate call sites.
@@ -158,294 +167,6 @@ const rfc64CatalogReplayRuntimesV1 = new WeakMap();
158
167
  const rfc64CatalogReplaySnapshotRuntimesV1 = new WeakMap();
159
168
  const rfc64CatalogReplayConnectionRuntimesV1 = new WeakMap();
160
169
  const rfc64CatalogReplayRecoveryRuntimesV1 = new WeakMap();
161
- /** Process-local, bounded operational targets; semantic truth remains the durable inventory. */
162
- export class Rfc64CatalogTargetTrackerV1 {
163
- #byContextGraph = new Map();
164
- #contextGraphOverflows = new Map();
165
- #contextEpochs = new Map();
166
- #globalOverflow = null;
167
- #size = 0;
168
- get size() {
169
- return this.#size;
170
- }
171
- targetsForContextGraph(contextGraphId) {
172
- return Object.freeze([...this.#byContextGraph.get(contextGraphId)?.values() ?? []]
173
- .map(({ announcement }) => announcement));
174
- }
175
- hasTerminalFailure(announcement) {
176
- const entry = this.#byContextGraph
177
- .get(announcement.contextGraphId)
178
- ?.get(rfc64CatalogTargetScopeKeyV1(announcement));
179
- return entry !== undefined
180
- && rfc64CatalogTargetExactIdentityV1(entry.announcement, announcement)
181
- && entry.terminalFailure;
182
- }
183
- capacityExceededForContextGraph(contextGraphId) {
184
- return this.#globalOverflow !== null
185
- || this.#contextGraphOverflows.has(contextGraphId);
186
- }
187
- /** Invalidate every outstanding lease and release all process-local target evidence. */
188
- resetAll() {
189
- for (const contextEpoch of this.#contextEpochs.values())
190
- contextEpoch.valid = false;
191
- this.#contextEpochs.clear();
192
- this.#byContextGraph.clear();
193
- this.#contextGraphOverflows.clear();
194
- this.#globalOverflow = null;
195
- this.#size = 0;
196
- }
197
- clearContextGraph(contextGraphId) {
198
- const byScope = this.#byContextGraph.get(contextGraphId);
199
- const contextEpoch = this.#contextEpochs.get(contextGraphId);
200
- if (contextEpoch !== undefined) {
201
- contextEpoch.valid = false;
202
- this.#contextEpochs.delete(contextGraphId);
203
- }
204
- this.#contextGraphOverflows.delete(contextGraphId);
205
- if (this.#globalOverflow !== null) {
206
- for (const [identity, witness] of this.#globalOverflow.failureWitnesses) {
207
- if (witness.contextGraphId === contextGraphId) {
208
- this.#globalOverflow.failureWitnesses.delete(identity);
209
- }
210
- }
211
- this.#globalOverflow.saturatedContextGraphs.delete(contextGraphId);
212
- this.#finishOverflowIfResolved(this.#globalOverflow, null);
213
- }
214
- if (byScope !== undefined) {
215
- this.#byContextGraph.delete(contextGraphId);
216
- this.#size -= byScope.size;
217
- }
218
- this.#promoteOverflowWitnesses();
219
- return byScope?.size ?? 0;
220
- }
221
- begin(announcement) {
222
- const existingByScope = this.#byContextGraph.get(announcement.contextGraphId);
223
- const key = rfc64CatalogTargetScopeKeyV1(announcement);
224
- const previous = existingByScope?.get(key);
225
- let contextEpoch = this.#contextEpochs.get(announcement.contextGraphId);
226
- if (contextEpoch === undefined) {
227
- contextEpoch = { valid: true, activeLeases: 0 };
228
- this.#contextEpochs.set(announcement.contextGraphId, contextEpoch);
229
- }
230
- contextEpoch.activeLeases += 1;
231
- const lease = (disposition, overflow = null) => Object.freeze({
232
- announcement,
233
- disposition,
234
- state: { active: true, contextEpoch, overflow },
235
- });
236
- if (previous !== undefined
237
- && BigInt(announcement.catalogVersion)
238
- < BigInt(previous.announcement.catalogVersion))
239
- return lease('covered');
240
- if (previous === undefined
241
- && (existingByScope?.size ?? 0)
242
- >= RFC64_CATALOG_TARGET_MAX_ENTRIES_PER_CONTEXT_GRAPH_V1) {
243
- const overflow = this.#beginContextGraphOverflow(announcement.contextGraphId);
244
- return lease(overflow.disposition, overflow.overflow);
245
- }
246
- if (previous === undefined && this.#size >= RFC64_CATALOG_TARGET_MAX_ENTRIES_V1) {
247
- this.#globalOverflow ??= this.#createOverflow();
248
- this.#globalOverflow.active += 1;
249
- return lease('global-capacity', this.#globalOverflow);
250
- }
251
- let byScope = existingByScope;
252
- if (byScope === undefined) {
253
- byScope = new Map();
254
- this.#byContextGraph.set(announcement.contextGraphId, byScope);
255
- }
256
- byScope.set(key, { announcement, terminalFailure: false });
257
- if (previous === undefined)
258
- this.#size += 1;
259
- return lease('tracked');
260
- }
261
- reject(announcement) {
262
- const lease = this.begin(announcement);
263
- this.settle(lease, 'dropped');
264
- return lease;
265
- }
266
- settle(lease, outcome) {
267
- if (!lease.state.active)
268
- return;
269
- lease.state.active = false;
270
- const { contextEpoch } = lease.state;
271
- contextEpoch.activeLeases = Math.max(0, contextEpoch.activeLeases - 1);
272
- if (contextEpoch.activeLeases === 0
273
- && this.#contextEpochs.get(lease.announcement.contextGraphId) === contextEpoch)
274
- this.#contextEpochs.delete(lease.announcement.contextGraphId);
275
- const overflow = lease.state.overflow;
276
- if (!contextEpoch.valid) {
277
- if (overflow !== null) {
278
- overflow.active = Math.max(0, overflow.active - 1);
279
- if (this.#globalOverflow === overflow) {
280
- this.#finishOverflowIfResolved(overflow, null);
281
- }
282
- }
283
- return;
284
- }
285
- const resolved = outcome === 'already-applied'
286
- || outcome === 'applied'
287
- || outcome === 'closed'
288
- || outcome === 'staged-only';
289
- if (lease.disposition === 'tracked') {
290
- if (resolved)
291
- this.retire(lease.announcement);
292
- else
293
- this.#markTerminalFailure(lease.announcement);
294
- return;
295
- }
296
- if (lease.disposition === 'covered')
297
- return;
298
- if (overflow === null
299
- || (lease.disposition === 'context-capacity'
300
- ? this.#contextGraphOverflows.get(lease.announcement.contextGraphId) !== overflow
301
- : this.#globalOverflow !== overflow))
302
- return;
303
- overflow.active = Math.max(0, overflow.active - 1);
304
- const exactIdentity = rfc64CatalogTargetExactIdentityKeyV1(lease.announcement);
305
- if (resolved) {
306
- overflow.failureWitnesses.delete(exactIdentity);
307
- }
308
- else if (!overflow.failureWitnesses.has(exactIdentity)) {
309
- if (overflow.failureWitnesses.size
310
- >= RFC64_CATALOG_TARGET_MAX_ENTRIES_PER_CONTEXT_GRAPH_V1)
311
- this.#markOverflowSaturated(overflow, lease.announcement.contextGraphId);
312
- else
313
- overflow.failureWitnesses.set(exactIdentity, lease.announcement);
314
- }
315
- this.#finishOverflowIfResolved(overflow, lease.disposition === 'context-capacity'
316
- ? lease.announcement.contextGraphId
317
- : null);
318
- }
319
- retire(announcement) {
320
- const byScope = this.#byContextGraph.get(announcement.contextGraphId);
321
- const key = rfc64CatalogTargetScopeKeyV1(announcement);
322
- const current = byScope?.get(key);
323
- let retired = false;
324
- if (current !== undefined
325
- && rfc64CatalogTargetExactIdentityV1(current.announcement, announcement)) {
326
- byScope.delete(key);
327
- this.#size -= 1;
328
- if (byScope.size === 0)
329
- this.#byContextGraph.delete(announcement.contextGraphId);
330
- retired = true;
331
- }
332
- const exactIdentity = rfc64CatalogTargetExactIdentityKeyV1(announcement);
333
- const contextOverflow = this.#contextGraphOverflows.get(announcement.contextGraphId);
334
- if (contextOverflow?.failureWitnesses.delete(exactIdentity) === true) {
335
- this.#finishOverflowIfResolved(contextOverflow, announcement.contextGraphId);
336
- retired = true;
337
- }
338
- if (this.#globalOverflow?.failureWitnesses.delete(exactIdentity) === true) {
339
- this.#finishOverflowIfResolved(this.#globalOverflow, null);
340
- retired = true;
341
- }
342
- this.#promoteOverflowWitnesses();
343
- return retired;
344
- }
345
- #markTerminalFailure(announcement) {
346
- const entry = this.#byContextGraph
347
- .get(announcement.contextGraphId)
348
- ?.get(rfc64CatalogTargetScopeKeyV1(announcement));
349
- if (entry !== undefined
350
- && rfc64CatalogTargetExactIdentityV1(entry.announcement, announcement))
351
- entry.terminalFailure = true;
352
- }
353
- #beginContextGraphOverflow(contextGraphId) {
354
- let overflow = this.#contextGraphOverflows.get(contextGraphId);
355
- if (overflow === undefined) {
356
- if (this.#contextGraphOverflows.size
357
- >= RFC64_CATALOG_TARGET_MAX_CONTEXT_OVERFLOWS_V1) {
358
- this.#globalOverflow ??= this.#createOverflow();
359
- this.#globalOverflow.active += 1;
360
- return Object.freeze({
361
- disposition: 'global-capacity',
362
- overflow: this.#globalOverflow,
363
- });
364
- }
365
- overflow = this.#createOverflow();
366
- this.#contextGraphOverflows.set(contextGraphId, overflow);
367
- }
368
- overflow.active += 1;
369
- return Object.freeze({ disposition: 'context-capacity', overflow });
370
- }
371
- #createOverflow() {
372
- return {
373
- active: 0,
374
- failureWitnesses: new Map(),
375
- saturatedContextGraphs: new Set(),
376
- unattributedSaturation: false,
377
- };
378
- }
379
- #markOverflowSaturated(overflow, contextGraphId) {
380
- if (overflow.saturatedContextGraphs.has(contextGraphId))
381
- return;
382
- if (overflow.saturatedContextGraphs.size
383
- >= RFC64_CATALOG_TARGET_MAX_CONTEXT_OVERFLOWS_V1) {
384
- overflow.unattributedSaturation = true;
385
- return;
386
- }
387
- overflow.saturatedContextGraphs.add(contextGraphId);
388
- }
389
- #finishOverflowIfResolved(overflow, contextGraphId) {
390
- if (overflow.active > 0)
391
- return;
392
- if (overflow.failureWitnesses.size === 0
393
- && overflow.saturatedContextGraphs.size === 0
394
- && !overflow.unattributedSaturation) {
395
- if (contextGraphId === null)
396
- this.#globalOverflow = null;
397
- else
398
- this.#contextGraphOverflows.delete(contextGraphId);
399
- return;
400
- }
401
- this.#promoteOverflowWitness(contextGraphId, overflow);
402
- }
403
- #promoteOverflowWitnesses() {
404
- for (const [contextGraphId, overflow] of this.#contextGraphOverflows) {
405
- this.#promoteOverflowWitness(contextGraphId, overflow);
406
- }
407
- if (this.#globalOverflow !== null)
408
- this.#promoteOverflowWitness(null, this.#globalOverflow);
409
- }
410
- #promoteOverflowWitness(contextGraphId, overflow) {
411
- if (overflow.active > 0)
412
- return;
413
- for (const [identity, witness] of overflow.failureWitnesses) {
414
- const byScope = this.#byContextGraph.get(witness.contextGraphId);
415
- const key = rfc64CatalogTargetScopeKeyV1(witness);
416
- const current = byScope?.get(key);
417
- if (current !== undefined) {
418
- if (BigInt(current.announcement.catalogVersion) > BigInt(witness.catalogVersion)) {
419
- overflow.failureWitnesses.delete(identity);
420
- continue;
421
- }
422
- current.announcement = witness;
423
- current.terminalFailure = true;
424
- overflow.failureWitnesses.delete(identity);
425
- continue;
426
- }
427
- if ((byScope?.size ?? 0) >= RFC64_CATALOG_TARGET_MAX_ENTRIES_PER_CONTEXT_GRAPH_V1
428
- || this.#size >= RFC64_CATALOG_TARGET_MAX_ENTRIES_V1)
429
- continue;
430
- const targetByScope = byScope ?? new Map();
431
- if (byScope === undefined)
432
- this.#byContextGraph.set(witness.contextGraphId, targetByScope);
433
- targetByScope.set(key, { announcement: witness, terminalFailure: true });
434
- this.#size += 1;
435
- overflow.failureWitnesses.delete(identity);
436
- }
437
- if (overflow.failureWitnesses.size === 0
438
- && overflow.saturatedContextGraphs.size === 0
439
- && !overflow.unattributedSaturation) {
440
- if (contextGraphId === null && this.#globalOverflow === overflow) {
441
- this.#globalOverflow = null;
442
- }
443
- else if (contextGraphId !== null
444
- && this.#contextGraphOverflows.get(contextGraphId) === overflow)
445
- this.#contextGraphOverflows.delete(contextGraphId);
446
- }
447
- }
448
- }
449
170
  const rfc64CatalogTargetAnnouncementsV1 = new WeakMap();
450
171
  function rfc64CatalogReplayRuntimeForV1(agent) {
451
172
  let runtime = rfc64CatalogReplayRuntimesV1.get(agent);
@@ -490,19 +211,6 @@ function pruneRfc64SupersededCatalogTargetsV1(targets) {
490
211
  }
491
212
  return targets.filter((target) => (BigInt(target.catalogVersion) === newestByScope.get(rfc64CatalogTargetScopeKeyV1(target))));
492
213
  }
493
- function rfc64CatalogTargetExactIdentityV1(left, right) {
494
- return rfc64CatalogTargetExactIdentityKeyV1(left)
495
- === rfc64CatalogTargetExactIdentityKeyV1(right);
496
- }
497
- export function rfc64CatalogTargetExactIdentityKeyV1(target) {
498
- return [
499
- rfc64CatalogTargetScopeKeyV1(target),
500
- target.catalogVersion,
501
- target.policyDigest,
502
- target.catalogHeadObjectDigest,
503
- target.signatureVariantDigest,
504
- ].join('\0');
505
- }
506
214
  function recordRfc64CatalogTargetAnnouncementV1(agent, announcement) {
507
215
  let tracker = rfc64CatalogTargetAnnouncementsV1.get(agent);
508
216
  if (tracker === undefined) {
@@ -530,6 +238,25 @@ function markRfc64DirectAcceptedCompatibilityV1(agent, contextGraphId) {
530
238
  }
531
239
  accepted.add(contextGraphId);
532
240
  }
241
+ /**
242
+ * Record whether the private policy just accepted for a graph is join-derived.
243
+ * Both ways a private policy is accepted call this (authority composition and
244
+ * the direct snapshot acceptance), so the mark always describes the acceptance
245
+ * that produced the current snapshot. An open policy cannot replace a
246
+ * join-derived one: the registry only takes a linked successor.
247
+ */
248
+ function noteRfc64AcceptedAuthorityOriginV1(agent, contextGraphId, origin) {
249
+ let joinDerived = rfc64JoinDerivedAcceptedAuthorityV1.get(agent);
250
+ if (origin === 'authenticated') {
251
+ joinDerived?.delete(contextGraphId);
252
+ return;
253
+ }
254
+ if (joinDerived === undefined) {
255
+ joinDerived = new Set();
256
+ rfc64JoinDerivedAcceptedAuthorityV1.set(agent, joinDerived);
257
+ }
258
+ joinDerived.add(contextGraphId);
259
+ }
533
260
  function rfc64CatalogAuthorityGenerationChangedV1(previous, accepted) {
534
261
  return previous !== null
535
262
  && (previous.policyDigest !== accepted.policyDigest
@@ -613,6 +340,22 @@ function nextRfc64CatalogAuthorityRevisionV1(agent, contextGraphId) {
613
340
  function isCurrentRfc64CatalogAuthorityRevisionV1(agent, contextGraphId, revision) {
614
341
  return rfc64CatalogAuthorityRevisionsV1.get(agent)?.get(contextGraphId) === revision;
615
342
  }
343
+ /**
344
+ * One authority composition that was discarded because a local authority fact
345
+ * moved while it was being read. Unlike a superseded composition, no newer one
346
+ * is running for this graph.
347
+ */
348
+ class Rfc64AuthorityFactsMovedV1 {
349
+ authorityRevision;
350
+ constructor(authorityRevision) {
351
+ this.authorityRevision = authorityRevision;
352
+ }
353
+ }
354
+ function waitForRfc64AuthorityFactsMovedRetryV1(delayMs, signal) {
355
+ if (signal !== undefined)
356
+ return waitForRfc64ScheduledResponsibilityDelayV1(signal, delayMs);
357
+ return new Promise((resolve) => { setTimeout(resolve, delayMs); });
358
+ }
616
359
  /** Intermediate acceleration-pull WARNs are rate-limited per scope to this window. */
617
360
  const RFC64_ACCELERATION_WARN_INTERVAL_MS_V1 = 30_000;
618
361
  /** Bound on rate-limit bookkeeping so hostile scope churn cannot grow it unboundedly. */
@@ -647,6 +390,8 @@ function requireRfc64ContextGraphAuthorityReaderV1(capability) {
647
390
  const RFC64_TRANSIENT_AUTHORITY_REFRESH_FAILURES_V1 = new Set([
648
391
  'registered-authority-unfinalized',
649
392
  'registered-private-roster-unresolved',
393
+ 'unregistered-private-roster-unresolved',
394
+ 'authority-rpc-circuit-open',
650
395
  ]);
651
396
  /**
652
397
  * Is this refresh failure a not-yet rather than a denial? Exported so the
@@ -660,6 +405,8 @@ export function isRfc64TransientAuthorityRefreshFailureV1(code) {
660
405
  function rfc64CatalogAuthorityFailureCodeV1(error) {
661
406
  if (error instanceof Rfc64CatalogAuthorityResolutionErrorV1)
662
407
  return error.code;
408
+ if (isRfc64AuthorityRpcCircuitOpenErrorV1(error))
409
+ return 'authority-rpc-circuit-open';
663
410
  return 'authority-resolution-failed';
664
411
  }
665
412
  /**
@@ -670,95 +417,8 @@ function rfc64CatalogAuthorityFailureCodeV1(error) {
670
417
  export function isRfc64UnregisteredOwnerUnresolvedErrorV1(error) {
671
418
  return rfc64CatalogAuthorityFailureCodeV1(error) === 'unregistered-owner-unresolved';
672
419
  }
673
- function aggregateRfc64DigestV1(values) {
674
- if (values.length === 0)
675
- return null;
676
- const sorted = [...values].sort();
677
- if (sorted.length === 1)
678
- return sorted[0];
679
- return ethers.keccak256(ethers.toUtf8Bytes(sorted.join('\n')));
680
- }
681
- function sumDecimalCountsV1(values) {
682
- return values.reduce((sum, value) => sum + BigInt(value), 0n).toString(10);
683
- }
684
- export function projectRfc64OperationalRowCountsV1(heads, targets, promisedRowCounts) {
685
- if (heads.length === 0 && targets.length === 0) {
686
- return Object.freeze({ expectedRowCount: null, missingRowCount: null });
687
- }
688
- const appliedByScope = new Map(heads.map((head) => [head.scopeKey, head]));
689
- const expectedByScope = new Map(heads.map(({ scopeKey, snapshot }) => [scopeKey, {
690
- catalogVersion: snapshot.catalogVersion,
691
- catalogHeadObjectDigest: snapshot.currentCatalogHeadDigest,
692
- rowCount: snapshot.inventoryRowCount,
693
- target: null,
694
- }]));
695
- // A fork is a property of the newest version in a scope, not of the order
696
- // the targets arrive in: `authoritativeTargets` preserves insertion order and
697
- // the promised half arrives in peer-completion order, so deciding as the loop
698
- // walks would let the same state report an ambiguous pair or a definite one
699
- // depending on which peer answered first. The scope's maximum version is
700
- // resolved first, and only a digest disagreement AT that maximum is ambiguous
701
- // -- a strictly newer head settles the branch the older fork was on.
702
- const ambiguousScopes = new Set();
703
- for (const target of targets) {
704
- const scopeKey = rfc64CatalogTargetScopeKeyV1(target);
705
- const current = expectedByScope.get(scopeKey);
706
- const targetVersion = BigInt(target.catalogVersion);
707
- if (current === undefined || targetVersion > BigInt(current.catalogVersion)) {
708
- expectedByScope.set(scopeKey, {
709
- catalogVersion: target.catalogVersion,
710
- catalogHeadObjectDigest: target.catalogHeadObjectDigest,
711
- rowCount: null,
712
- target,
713
- });
714
- ambiguousScopes.delete(scopeKey);
715
- }
716
- else if (targetVersion === BigInt(current.catalogVersion)
717
- && target.catalogHeadObjectDigest !== current.catalogHeadObjectDigest) {
718
- ambiguousScopes.add(scopeKey);
719
- }
720
- }
721
- if (ambiguousScopes.size > 0) {
722
- return Object.freeze({ expectedRowCount: null, missingRowCount: null });
723
- }
724
- let expected = 0n;
725
- let missing = 0n;
726
- for (const [scopeKey, projected] of expectedByScope) {
727
- const targetRowCount = projected.target === null
728
- ? projected.rowCount
729
- : promisedRowCounts.get(rfc64CatalogTargetExactIdentityKeyV1(projected.target)) ?? null;
730
- if (targetRowCount === null) {
731
- return Object.freeze({ expectedRowCount: null, missingRowCount: null });
732
- }
733
- const expectedForScope = BigInt(targetRowCount);
734
- const appliedForScope = BigInt(appliedByScope.get(scopeKey)?.snapshot.inventoryRowCount ?? '0');
735
- expected += expectedForScope;
736
- if (expectedForScope > appliedForScope)
737
- missing += expectedForScope - appliedForScope;
738
- }
739
- return Object.freeze({
740
- expectedRowCount: expected.toString(10),
741
- missingRowCount: missing.toString(10),
742
- });
743
- }
744
420
  export class Rfc64CatalogMethods extends DKGAgentBase {
745
421
  /** Stable recovery capabilities are captured once per agent-owned runtime. */
746
- /**
747
- * The node's SINGLE finality depth, taken from the adapter that actually
748
- * resolves the anchors whenever it can report one.
749
- *
750
- * `dkg-agent-types.ts` documents `chainAdapter` as "If provided, chainConfig
751
- * is ignored", so in the SDK-embedding shape `chainConfig.finalityConfirmations`
752
- * is absent or stale while the adapter holds the operator's real value. An
753
- * adapter that does not implement the accessor (mocks, out-of-tree adapters)
754
- * has no opinion, and the configured value stands.
755
- */
756
- resolveChainFinalityConfirmationsV1() {
757
- const fromAdapter = typeof this.chain.getFinalityConfirmations === 'function'
758
- ? this.chain.getFinalityConfirmations()
759
- : undefined;
760
- return fromAdapter ?? this.config.chainConfig?.finalityConfirmations;
761
- }
762
422
  rfc64CatalogReplayRecoveryRuntimeV1() {
763
423
  let runtime = rfc64CatalogReplayRecoveryRuntimesV1.get(this);
764
424
  if (runtime !== undefined)
@@ -981,55 +641,37 @@ export class Rfc64CatalogMethods extends DKGAgentBase {
981
641
  const currentReplayProgress = accepted === null
982
642
  ? null
983
643
  : replayRecovery.status(selection.contextGraphId, accepted.policyDigest);
984
- const replayActive = replaySnapshotUnstable || currentReplayProgress?.active === true;
985
- // Only parity/overflow evidence fails a Context Graph. Providers that
986
- // could not be replayed from surface through providerHealth instead.
987
- const replayFailed = currentReplayProgress?.failed === true;
988
644
  const heads = appliedByContextGraph.get(selection.contextGraphId) ?? [];
989
- // A full pass that reached no provider at all corroborated nothing: with
990
- // an empty promised set parity is vacuously satisfied, so applied rows
991
- // would otherwise be reported as agreed by every provider. It is not
992
- // evidence of missing rows, so it stays distinct from `replayFailed`, and
993
- // it can only mislead once something has been applied.
994
- const replayUnverified = currentReplayProgress?.unverified === true
995
- && heads.length > 0;
996
- const replayUnsettled = replayActive || replayFailed || replayUnverified;
645
+ // The owner is the only possible catalog author only in a private graph
646
+ // whose accepted roster is the owner alone: catalog authorship follows
647
+ // the access policy (any member, or any author of a public graph, which
648
+ // has no roster), not the publish policy. When this node is that owner
649
+ // and its verified applied heads all belong to it, an unanswered
650
+ // connected peer cannot reveal another author's catalog. Keep the
651
+ // provider failure visible in providerHealth, but do not turn locally
652
+ // complete owner inventory into unknown graph parity.
653
+ const curatedOwnerAddress = accepted?.policy.source.kind === 'owner-signed-unregistered'
654
+ ? accepted.policy.source.ownerAddress
655
+ : null;
656
+ const ownerIsSoleCatalogAuthor = accepted !== null
657
+ && curatedOwnerAddress !== null
658
+ && accepted.roster?.members.length === 1
659
+ && accepted.roster.members[0]?.agentAddress === curatedOwnerAddress;
660
+ const localCuratedOwnerHeads = accepted !== null
661
+ && accepted.policy.publishPolicy === 0
662
+ && curatedOwnerAddress !== null
663
+ && ownerIsSoleCatalogAuthor
664
+ && heads.length > 0
665
+ && this.listLocalAgents().some(({ agentAddress }) => (agentAddress.toLowerCase() === curatedOwnerAddress))
666
+ && heads.every(({ snapshot }) => (snapshot.authorAddress === curatedOwnerAddress));
997
667
  const targets = targetsByContextGraph.get(selection.contextGraphId) ?? [];
998
668
  const promisedTargets = promisedTargetsByContextGraph.get(selection.contextGraphId) ?? null;
999
- const authoritativeTargets = [...new Map([
1000
- ...targets,
1001
- ...promisedTargets ?? [],
1002
- ].map((target) => [rfc64CatalogTargetExactIdentityKeyV1(target), target])).values()];
1003
669
  const targetCapacityExceeded = targetTracker
1004
670
  ?.capacityExceededForContextGraph(selection.contextGraphId) ?? false;
1005
- const appliedByScope = new Map(heads.map((head) => [head.scopeKey, head]));
1006
- const pendingTargets = targets.filter((target) => {
1007
- const applied = appliedByScope.get(rfc64CatalogTargetScopeKeyV1(target));
1008
- return applied === undefined
1009
- || BigInt(target.catalogVersion) > BigInt(applied.snapshot.catalogVersion)
1010
- || (target.catalogVersion === applied.snapshot.catalogVersion
1011
- && target.catalogHeadObjectDigest !== applied.snapshot.currentCatalogHeadDigest);
671
+ const { replayActive, replayFailed, replayUnverified, replayUnsettled, pendingTargets, catalogHeadDigest, expectedCatalogHeadDigest, inventoryDigest, rowCount, rowProjection, } = evaluateRfc64CatalogCompletionV1({
672
+ heads, targets, promisedTargets, promisedRowCounts, replay: currentReplayProgress,
673
+ replaySnapshotUnstable, targetCapacityExceeded, localCuratedOwnerHeads,
1012
674
  });
1013
- const catalogHeadDigest = aggregateRfc64DigestV1(heads.map(({ snapshot }) => snapshot.currentCatalogHeadDigest));
1014
- const expectedCatalogHeadDigests = new Map(heads.map(({ scopeKey, snapshot }) => [
1015
- scopeKey,
1016
- snapshot.currentCatalogHeadDigest,
1017
- ]));
1018
- for (const target of pendingTargets) {
1019
- expectedCatalogHeadDigests.set(rfc64CatalogTargetScopeKeyV1(target), target.catalogHeadObjectDigest);
1020
- }
1021
- const expectedCatalogHeadDigest = aggregateRfc64DigestV1([...expectedCatalogHeadDigests.values()]);
1022
- const inventoryDigest = aggregateRfc64DigestV1(heads.map(({ snapshot }) => snapshot.appliedInventoryDigest));
1023
- const rowCount = heads.length === 0
1024
- ? null
1025
- : sumDecimalCountsV1(heads.map(({ snapshot }) => snapshot.inventoryRowCount));
1026
- const rowProjectionUnavailable = targetCapacityExceeded
1027
- || replayActive
1028
- || replayUnverified
1029
- || (replayFailed && promisedTargets === null);
1030
- const rowProjection = rowProjectionUnavailable
1031
- ? Object.freeze({ expectedRowCount: null, missingRowCount: null })
1032
- : projectRfc64OperationalRowCountsV1(heads, authoritativeTargets, promisedRowCounts);
1033
675
  const appliedCatalogVersion = heads.length === 0
1034
676
  ? null
1035
677
  : heads.reduce((highest, { snapshot }) => (BigInt(snapshot.catalogVersion) > BigInt(highest)
@@ -1160,18 +802,122 @@ export class Rfc64CatalogMethods extends DKGAgentBase {
1160
802
  });
1161
803
  }));
1162
804
  }
805
+ /** Re-prove catalog completion before the daemon's synchronous readiness commit. */
806
+ async withVerifiedPrivateCatalogSubscriptionReadinessV1(contextGraphId, commit) {
807
+ return verifyPrivateCatalogSubscriptionReadinessV1(this, contextGraphId, commit, () => {
808
+ const progress = rfc64CatalogAuthorityProgressV1.get(this)?.get(contextGraphId);
809
+ const tracker = rfc64CatalogTargetAnnouncementsV1.get(this);
810
+ const targets = tracker?.targetsForContextGraph(contextGraphId) ?? [];
811
+ return {
812
+ service: this.rfc64PublicCatalogServiceV1,
813
+ persistence: this.rfc64PersistenceV1,
814
+ networkId: this.config.rfc64CatalogDeploymentProfile?.networkId ?? this.config.networkIdentity?.chainId,
815
+ approvedAgent: this.localApprovedAgentByCG.get(contextGraphId),
816
+ subscription: this.subscribedContextGraphs.get(contextGraphId),
817
+ plan: this.config.rfc64CatalogExecutionPlan,
818
+ metadataRevision: this.contextGraphMetaProjection.readContextGraphAuthorityFactsRevision(contextGraphId),
819
+ replay: this.rfc64CatalogReplayRecoveryRuntimeV1(),
820
+ authorityRevision: rfc64CatalogAuthorityRevisionsV1.get(this)?.get(contextGraphId),
821
+ authorityCurrent: progress?.state === 'accepted' && Date.now() - progress.updatedAtMs
822
+ <= RFC64_CATALOG_AUTHORITY_REFRESH_POLICY_V1.intervalMs * RFC64_CATALOG_AUTHORITY_REFRESH_POLICY_V1.freshnessIntervalCount,
823
+ legacyReadOnlyCount: readRfc64LegacySwmBoundaryCountV1(this, contextGraphId),
824
+ targets,
825
+ targetCapacityExceeded: tracker?.capacityExceededForContextGraph(contextGraphId) ?? false,
826
+ targetFailed: targets.some((target) => tracker.hasTerminalFailure(target)),
827
+ targetFence: JSON.stringify(targets.map((target) => [
828
+ rfc64CatalogTargetExactIdentityKeyV1(target), tracker.hasTerminalFailure(target),
829
+ ])),
830
+ };
831
+ });
832
+ }
1163
833
  /**
1164
- * Resolve the private member set from the hardened, store-backed `_meta`
1165
- * gate after the complete graph definition has been authenticated. This is
1166
- * deliberately independent of the accepted RFC-64 roster: responsibility
1167
- * and roster rotation cannot ask the roster they are about to establish for
1168
- * permission to establish it.
834
+ * Resolve the private member set from the authoritative roster source after
835
+ * the complete graph definition has been authenticated. Registered private
836
+ * graphs retain the finalized chain roster; unregistered graphs use the
837
+ * effective store-backed metadata projection. This is deliberately
838
+ * independent of the accepted RFC-64 overlay: responsibility and roster
839
+ * rotation cannot ask the roster they are about to establish for permission
840
+ * to establish it.
1169
841
  */
1170
842
  async resolveRfc64VerifiedPrivateRosterV1(contextGraphId) {
1171
- if (!await this.hasConfirmedMetaState(contextGraphId).catch(() => false)) {
843
+ // The creator's explicit local-first registration marker already proves
844
+ // this graph has no chain roster. Reading the general member-recovery
845
+ // authority here would ask the accepted catalog policy we are currently
846
+ // rotating to authorize its own successor. A concurrent admission can
847
+ // then make that read return unavailable and strand the new member behind
848
+ // the old policy. Read the creator's own confirmed _meta instead, while
849
+ // keeping merged revocations effective and fencing registration changes.
850
+ const localFirst = await this.isLocalFirstUnregisteredContextGraph(contextGraphId);
851
+ const accepted = this.readAcceptedRfc64CatalogAccessSnapshotV1(contextGraphId);
852
+ const approvedAgent = this.localApprovedAgentByCG.get(contextGraphId);
853
+ let approvedReplicaGate;
854
+ if (!localFirst
855
+ && approvedAgent !== undefined
856
+ && accepted?.policy.accessPolicy === 1
857
+ && accepted.policy.source.kind === 'owner-signed-unregistered') {
858
+ const revision = this.contextGraphMetaProjection
859
+ .readContextGraphAuthorityFactsRevision(contextGraphId);
860
+ const approved = await resolveApprovedPrivateReplicaAuthority(this, contextGraphId, approvedAgent, () => this.localApprovedAgentByCG.get(contextGraphId)?.toLowerCase()
861
+ === approvedAgent.toLowerCase(), () => this.contextGraphMetaProjection
862
+ .readContextGraphAuthorityFactsRevision(contextGraphId) === revision).catch(() => null);
863
+ if (approved?.kind === 'unregistered-private-replica'
864
+ && approved.authority.ownerAddress === accepted.policy.source.ownerAddress) {
865
+ // The approved-member proof authenticates this replica's own private
866
+ // definition. Check finalized name absence independently, then read
867
+ // the effective local roster and fence both sources again after the
868
+ // store awaits. The general recovery helper would ask the accepted
869
+ // catalog policy to authorize the roster needed to authorize that
870
+ // same catalog transport, leaving cold approved replicas stuck.
871
+ const before = await this.readRfc64RegisteredAuthoritySnapshotV1(contextGraphId)
872
+ .catch(() => undefined);
873
+ if (before === undefined)
874
+ return null;
875
+ if (before === null) {
876
+ const merged = await this.getLocalMetadataMemberRecoveryGate(contextGraphId)
877
+ .catch(() => null);
878
+ const own = await this.getOwnCgMetaFacts(contextGraphId)
879
+ .catch(() => null);
880
+ const after = await this.readRfc64RegisteredAuthoritySnapshotV1(contextGraphId)
881
+ .catch(() => undefined);
882
+ if (merged === null
883
+ || own === null
884
+ || after !== null
885
+ || this.contextGraphMetaProjection
886
+ .readContextGraphAuthorityFactsRevision(contextGraphId) !== revision
887
+ || this.localApprovedAgentByCG.get(contextGraphId)?.toLowerCase()
888
+ !== approvedAgent.toLowerCase()
889
+ || this.readAcceptedRfc64CatalogAccessSnapshotV1(contextGraphId)
890
+ ?.policyDigest !== accepted.policyDigest
891
+ // The clock is the one thing the fences above cannot see.
892
+ || !isApprovedPrivateReplicaDelegationActive(approved.authority))
893
+ return null;
894
+ const named = new Set([...own.allowedAgents, ...own.participantAgents]
895
+ .map((address) => address.toLowerCase()));
896
+ approvedReplicaGate = merged.filter((address) => named.has(address.toLowerCase()));
897
+ }
898
+ }
899
+ }
900
+ if (approvedReplicaGate === undefined
901
+ && !await this.hasConfirmedMetaState(contextGraphId).catch(() => false)) {
1172
902
  return null;
1173
903
  }
1174
- const gate = await withRpcUsageSite(CG_AUTH_RPC_SITES.rfc64Roster, () => this.getMemberRecoveryGate(contextGraphId)).catch(() => null);
904
+ const gate = approvedReplicaGate !== undefined
905
+ ? approvedReplicaGate
906
+ : localFirst
907
+ ? await (async () => {
908
+ const revision = this.contextGraphMetaProjection
909
+ .readContextGraphAuthorityFactsRevision(contextGraphId);
910
+ const merged = await this.getLocalMetadataMemberRecoveryGate(contextGraphId);
911
+ const own = await this.getOwnCgMetaFacts(contextGraphId);
912
+ if (!await this.isLocalFirstUnregisteredContextGraph(contextGraphId)
913
+ || this.contextGraphMetaProjection
914
+ .readContextGraphAuthorityFactsRevision(contextGraphId) !== revision)
915
+ return null;
916
+ const named = new Set([...own.allowedAgents, ...own.participantAgents]
917
+ .map((address) => address.toLowerCase()));
918
+ return merged?.filter((address) => named.has(address.toLowerCase())) ?? null;
919
+ })().catch(() => null)
920
+ : await withRpcUsageSite(CG_AUTH_RPC_SITES.rfc64Roster, () => this.getMemberRecoveryRosterSource(contextGraphId)).catch(() => null);
1175
921
  if (gate === null || gate.length === 0)
1176
922
  return null;
1177
923
  const members = new Set();
@@ -1296,50 +1042,47 @@ export class Rfc64CatalogMethods extends DKGAgentBase {
1296
1042
  }
1297
1043
  /**
1298
1044
  * Resolve a catalog peer from authenticated, Context-Graph-scoped state.
1299
- * Public agent profiles remain the first choice, but private admission must
1300
- * not depend on best-effort profile gossip. Curators already hold the
1301
- * member's signed delegatee binding, while approved receivers persist the
1302
- * authenticated curator peer together with its exact owner generation.
1045
+ * A peer may advertise a generic agent profile after a private transfer has
1046
+ * already begun. That profile need not be the agent approved for this graph.
1047
+ * Prefer the verified delegatee or curator binding, so late profile gossip
1048
+ * cannot change the identity used for catalog authorization mid-transfer.
1303
1049
  */
1304
1050
  async resolveRfc64CatalogRemoteAgentAddressV1(remotePeerId, contextGraphId) {
1051
+ if (await this.hasConfirmedMetaState(contextGraphId).catch(() => false)) {
1052
+ const delegatedAgents = new Set();
1053
+ const delegateePeers = await this.getContextGraphAllowedDelegateePeers(contextGraphId)
1054
+ .catch(() => new Map());
1055
+ for (const [agentAddress, peerIds] of delegateePeers) {
1056
+ const normalized = agentAddress.toLowerCase();
1057
+ if (peerIds.includes(remotePeerId)
1058
+ && /^0x[0-9a-f]{40}$/u.test(normalized)) {
1059
+ delegatedAgents.add(normalized);
1060
+ }
1061
+ }
1062
+ if (delegatedAgents.size === 1)
1063
+ return [...delegatedAgents][0];
1064
+ if (delegatedAgents.size > 1)
1065
+ return null;
1066
+ const approvedAgent = this.localApprovedAgentByCG.get(contextGraphId);
1067
+ if (approvedAgent !== undefined) {
1068
+ const requesterState = await this.readRequesterJoinRequestState(contextGraphId, approvedAgent).catch(() => null);
1069
+ if (requesterState?.status === 'approved'
1070
+ && requesterState.curatorPeerId === remotePeerId
1071
+ && requesterState.curatorAgentAddress !== undefined
1072
+ && requesterState.curatorAuthorityEra !== undefined) {
1073
+ const current = await this.readRfc64CurrentCuratorAuthorityBindingV1(contextGraphId).catch(() => null);
1074
+ if (current?.agentAddress === requesterState.curatorAgentAddress
1075
+ && current.authorityEra === requesterState.curatorAuthorityEra)
1076
+ return current.agentAddress;
1077
+ }
1078
+ }
1079
+ }
1305
1080
  const discovered = (await this.findAgentByPeerId(remotePeerId))
1306
1081
  ?.agentAddress
1307
1082
  ?.toLowerCase();
1308
- if (discovered !== undefined && /^0x[0-9a-f]{40}$/u.test(discovered)) {
1309
- return discovered;
1310
- }
1311
- if (!await this.hasConfirmedMetaState(contextGraphId).catch(() => false)) {
1312
- return null;
1313
- }
1314
- const delegatedAgents = new Set();
1315
- const delegateePeers = await this.getContextGraphAllowedDelegateePeers(contextGraphId)
1316
- .catch(() => new Map());
1317
- for (const [agentAddress, peerIds] of delegateePeers) {
1318
- const normalized = agentAddress.toLowerCase();
1319
- if (peerIds.includes(remotePeerId)
1320
- && /^0x[0-9a-f]{40}$/u.test(normalized)) {
1321
- delegatedAgents.add(normalized);
1322
- }
1323
- }
1324
- if (delegatedAgents.size === 1)
1325
- return [...delegatedAgents][0];
1326
- if (delegatedAgents.size > 1)
1327
- return null;
1328
- const approvedAgent = this.localApprovedAgentByCG.get(contextGraphId);
1329
- if (approvedAgent === undefined)
1330
- return null;
1331
- const requesterState = await this.readRequesterJoinRequestState(contextGraphId, approvedAgent).catch(() => null);
1332
- if (requesterState?.status !== 'approved'
1333
- || requesterState.curatorPeerId !== remotePeerId
1334
- || requesterState.curatorAgentAddress === undefined
1335
- || requesterState.curatorAuthorityEra === undefined)
1336
- return null;
1337
- const current = await this.readRfc64CurrentCuratorAuthorityBindingV1(contextGraphId).catch(() => null);
1338
- if (current === null
1339
- || current.agentAddress !== requesterState.curatorAgentAddress
1340
- || current.authorityEra !== requesterState.curatorAuthorityEra)
1341
- return null;
1342
- return current.agentAddress;
1083
+ return discovered !== undefined && /^0x[0-9a-f]{40}$/u.test(discovered)
1084
+ ? discovered
1085
+ : null;
1343
1086
  }
1344
1087
  /** Read the curator-authored local roster generation from authenticated metadata. */
1345
1088
  async readRfc64PrivateRosterVersionV1(contextGraphId) {
@@ -1751,6 +1494,18 @@ export class Rfc64CatalogMethods extends DKGAgentBase {
1751
1494
  // silently instead of reporting a false authority failure.
1752
1495
  if (ownerSignal.aborted)
1753
1496
  throw ownerSignal.reason;
1497
+ if (isRfc64AuthorityRpcCircuitOpenErrorV1(error)) {
1498
+ // Awaited subscribe/bootstrap callers do not belong to the
1499
+ // scheduled responsibility batch. A circuit-open read must still
1500
+ // get an owned follow-up after cooldown; otherwise the private
1501
+ // receiver can remain unselected until an unrelated event.
1502
+ this.rfc64BackgroundWorkDispatcherV1.scheduleKeyed(`responsibility-circuit-retry\0${contextGraphId}\0${revision}`, async (signal) => {
1503
+ await waitForRfc64ScheduledResponsibilityDelayV1(signal, RFC64_SCHEDULED_RESPONSIBILITY_RETRY_MS_V1);
1504
+ signal.throwIfAborted();
1505
+ if (isCurrentRfc64CatalogResponsibilityRevisionV1(this, contextGraphId, revision))
1506
+ this.scheduleRfc64CatalogResponsibilityReconciliationV1(contextGraphId);
1507
+ });
1508
+ }
1754
1509
  this.log.warn(createOperationContext('system'), `RFC-64 authority bootstrap incomplete for "${contextGraphId}": ${error instanceof Error ? error.message : String(error)}`);
1755
1510
  return null;
1756
1511
  });
@@ -1857,7 +1612,8 @@ export class Rfc64CatalogMethods extends DKGAgentBase {
1857
1612
  const eligible = authorityRequest.kind === 'finalized-absence'
1858
1613
  && !responsibility.active
1859
1614
  && !this.config.rfc64CatalogExecutionPlan.killSwitchActive
1860
- && isRfc64ActiveRegisteredSubscriptionV1(subscription)
1615
+ && (isRfc64ActiveRegisteredSubscriptionV1(subscription)
1616
+ || isRfc64LocalJoinIntentUnregisteredSubscriptionV1(this.localApprovedAgentByCG.has(contextGraphId), subscription))
1861
1617
  && isCurrentRfc64CatalogResponsibilityRevisionV1(this, contextGraphId, revision);
1862
1618
  if (!eligible) {
1863
1619
  this.clearRfc64ScheduledFinalizedAbsenceRetryV1(contextGraphId, revision);
@@ -1879,7 +1635,8 @@ export class Rfc64CatalogMethods extends DKGAgentBase {
1879
1635
  return;
1880
1636
  }
1881
1637
  const currentSubscription = this.subscribedContextGraphs.get(contextGraphId);
1882
- if (!isRfc64ActiveRegisteredSubscriptionV1(currentSubscription)) {
1638
+ if (!isRfc64ActiveRegisteredSubscriptionV1(currentSubscription)
1639
+ && !isRfc64LocalJoinIntentUnregisteredSubscriptionV1(this.localApprovedAgentByCG.has(contextGraphId), currentSubscription)) {
1883
1640
  this.clearRfc64ScheduledFinalizedAbsenceRetryV1(contextGraphId, retry.revision);
1884
1641
  return;
1885
1642
  }
@@ -2025,13 +1782,13 @@ export class Rfc64CatalogMethods extends DKGAgentBase {
2025
1782
  pending.clear();
2026
1783
  throw ownerSignal.reason ?? error;
2027
1784
  }
2028
- if (isRfc64SharedStorePressureFailureV1(error)) {
2029
- // One managed-store timeout/admission failure represents shared
2030
- // backend pressure. Do not ask every remaining graph to rediscover
2031
- // the same unavailable store in this pass. Requeue the untouched
2032
- // suffix behind one abortable retry delay; accepted authority stays
2033
- // in place until a later complete projection supersedes it.
2034
- this.log.warn(createOperationContext('system'), `RFC-64 background responsibility batch paused after shared store pressure; `
1785
+ if (isRfc64SharedStorePressureFailureV1(error)
1786
+ || isRfc64AuthorityRpcCircuitOpenErrorV1(error)) {
1787
+ // Shared store pressure and an open authority RPC circuit are
1788
+ // temporary node-wide conditions. Requeue this graph and the
1789
+ // untouched suffix after one bounded delay instead of leaving a
1790
+ // private receiver parked until an unrelated lifecycle nudge.
1791
+ this.log.warn(createOperationContext('system'), `RFC-64 background responsibility batch paused after shared authority pressure; `
2035
1792
  + `${authorityTargets.length - targetIndex} target(s) deferred: ${error instanceof Error ? error.message : String(error)}`);
2036
1793
  try {
2037
1794
  await waitForRfc64ScheduledResponsibilityDelayV1(ownerSignal, RFC64_SCHEDULED_RESPONSIBILITY_RETRY_MS_V1);
@@ -2064,8 +1821,32 @@ export class Rfc64CatalogMethods extends DKGAgentBase {
2064
1821
  * Rebuild and accept current RFC-64 authority from ordinary DKG state. A
2065
1822
  * supplied compatibility manifest remains an authority seed for its exact
2066
1823
  * graph; every other responsible graph takes this release-native path.
1824
+ *
1825
+ * `null` means a newer composition owns the outcome. A snapshot discarded
1826
+ * because a local authority fact moved while it was being composed has no
1827
+ * such successor, so it is composed again here. Returning `null` for it left
1828
+ * the graph `resolving` until the next periodic refresh pass, and a curator
1829
+ * that lost the refresh after a membership change kept refusing the new
1830
+ * member's catalog replay for that long.
2067
1831
  */
2068
1832
  async reconcileRfc64CatalogAccessAuthorityV1(contextGraphId, signal, authorityRequest = Object.freeze({ kind: 'auto' })) {
1833
+ for (let retry = 0;; retry += 1) {
1834
+ const outcome = await this.composeRfc64CatalogAccessAuthorityV1(contextGraphId, signal, authorityRequest);
1835
+ if (!(outcome instanceof Rfc64AuthorityFactsMovedV1))
1836
+ return outcome;
1837
+ const retryDelayMs = RFC64_AUTHORITY_FACTS_MOVED_RETRY_DELAYS_MS_V1[retry];
1838
+ if (retryDelayMs === undefined) {
1839
+ this.log.warn(createOperationContext('system'), `RFC-64 authority refresh for "${contextGraphId}" was discarded ${retry + 1} times because local authority facts kept changing; the next refresh pass retries it`);
1840
+ return null;
1841
+ }
1842
+ await waitForRfc64AuthorityFactsMovedRetryV1(retryDelayMs, signal);
1843
+ // A composition that started during the wait owns the outcome now.
1844
+ if (!isCurrentRfc64CatalogAuthorityRevisionV1(this, contextGraphId, outcome.authorityRevision))
1845
+ return null;
1846
+ }
1847
+ }
1848
+ /** One composition; see {@link reconcileRfc64CatalogAccessAuthorityV1}. */
1849
+ async composeRfc64CatalogAccessAuthorityV1(contextGraphId, signal, authorityRequest) {
2069
1850
  const service = this.rfc64PublicCatalogServiceV1;
2070
1851
  if (this.config.rfc64CatalogExecutionPlan.selectedAuthority[contextGraphId] !== undefined) {
2071
1852
  return null;
@@ -2123,6 +1904,38 @@ export class Rfc64CatalogMethods extends DKGAgentBase {
2123
1904
  && directAcceptedPrivateSnapshot.policy.accessPolicy === 1
2124
1905
  && directAcceptedPrivateSnapshot.roster !== null
2125
1906
  && directAcceptedPrivateSnapshot.policy.source.kind === 'owner-signed-unregistered';
1907
+ // A join-approved private replica has a curator-bound decision and an
1908
+ // exact, source-qualified member/delegation proof in its own _meta. That
1909
+ // is sufficient local authority after finalized name absence; a remote
1910
+ // private definition must not be promoted from RDF alone.
1911
+ const approvedAgent = this.localApprovedAgentByCG.get(contextGraphId);
1912
+ const approvedPrivateMetaRevision = this.contextGraphMetaProjection
1913
+ .readContextGraphAuthorityFactsRevision(contextGraphId);
1914
+ const approvedPrivateReplica = (boundOnChainId === undefined
1915
+ && !localFirstUnregistered
1916
+ && !directAcceptedPrivateAuthority
1917
+ && authorityRequest.kind === 'finalized-absence'
1918
+ && approvedAgent !== undefined) ? await resolveApprovedPrivateReplicaAuthority(this, contextGraphId, approvedAgent, () => this.localApprovedAgentByCG.get(contextGraphId)?.toLowerCase()
1919
+ === approvedAgent.toLowerCase(), () => this.contextGraphMetaProjection
1920
+ .readContextGraphAuthorityFactsRevision(contextGraphId)
1921
+ === approvedPrivateMetaRevision, signal) : null;
1922
+ // A join or catalog write can invalidate this graph's metadata while
1923
+ // the source-qualified proof is reading it. The proof correctly returns
1924
+ // null for that mixed generation, but null alone is not evidence that
1925
+ // the approved owner vanished. Recompose against the new revision before
1926
+ // falling through to owner-unresolved and deactivating a valid receiver.
1927
+ if (approvedPrivateReplica === null
1928
+ && approvedAgent !== undefined
1929
+ && boundOnChainId === undefined
1930
+ && !localFirstUnregistered
1931
+ && !directAcceptedPrivateAuthority
1932
+ && authorityRequest.kind === 'finalized-absence'
1933
+ && this.contextGraphMetaProjection
1934
+ .readContextGraphAuthorityFactsRevision(contextGraphId)
1935
+ !== approvedPrivateMetaRevision)
1936
+ return new Rfc64AuthorityFactsMovedV1(authorityRevision);
1937
+ const approvedPrivateReplicaAuthority = approvedPrivateReplica?.kind
1938
+ === 'unregistered-private-replica' ? approvedPrivateReplica.authority : null;
2126
1939
  // Replica authority is admissible only after the shared finalized name
2127
1940
  // index proves that no on-chain graph owns this name. The embedded
2128
1941
  // policy is independently owner-signed and graph/network-bound; plain
@@ -2132,6 +1945,7 @@ export class Rfc64CatalogMethods extends DKGAgentBase {
2132
1945
  const replicaUnregisteredAuthority = (boundOnChainId === undefined
2133
1946
  && !localFirstUnregistered
2134
1947
  && !directAcceptedPrivateAuthority
1948
+ && approvedPrivateReplicaAuthority === null
2135
1949
  && authorityRequest.kind === 'finalized-absence')
2136
1950
  ? await loadRfc64UnregisteredReplicaAuthorityV1({
2137
1951
  store: this.store,
@@ -2178,6 +1992,7 @@ export class Rfc64CatalogMethods extends DKGAgentBase {
2178
1992
  }
2179
1993
  const registeredAuthorityRead = (localFirstUnregistered
2180
1994
  || directAcceptedPrivateAuthority
1995
+ || approvedPrivateReplicaAuthority !== null
2181
1996
  || replicaUnregisteredAuthority !== null
2182
1997
  || (boundOnChainId === undefined
2183
1998
  && authorityRequest.kind === 'finalized-absence'))
@@ -2206,6 +2021,11 @@ export class Rfc64CatalogMethods extends DKGAgentBase {
2206
2021
  })()
2207
2022
  : await this.readRfc64RegisteredAuthoritySnapshotV1(contextGraphId, signal);
2208
2023
  let authority;
2024
+ // Mutable local authority facts must be one projection generation. Keep
2025
+ // the exact revision paired with every later metadata/version await and
2026
+ // refuse to accept a composed snapshot if owner, policy, revocation, or
2027
+ // membership facts changed in the meantime.
2028
+ let metadataAuthorityRevision = null;
2209
2029
  if (registeredAuthorityRead !== null) {
2210
2030
  const { expectedNameHash, snapshot } = registeredAuthorityRead;
2211
2031
  if (signal?.aborted)
@@ -2215,6 +2035,8 @@ export class Rfc64CatalogMethods extends DKGAgentBase {
2215
2035
  }
2216
2036
  let authoritativeSnapshot = snapshot;
2217
2037
  if (snapshot.accessPolicy === 1) {
2038
+ metadataAuthorityRevision = this.contextGraphMetaProjection
2039
+ .readContextGraphAuthorityFactsRevision(contextGraphId);
2218
2040
  const localRoster = await this.resolveRfc64VerifiedPrivateRosterV1(contextGraphId);
2219
2041
  if (localRoster === null) {
2220
2042
  // TRANSIENT, and typed so it is classified as such. `null` here
@@ -2255,6 +2077,7 @@ export class Rfc64CatalogMethods extends DKGAgentBase {
2255
2077
  else {
2256
2078
  if (!localFirstUnregistered
2257
2079
  && !directAcceptedPrivateAuthority
2080
+ && approvedPrivateReplicaAuthority === null
2258
2081
  && replicaUnregisteredAuthority === null) {
2259
2082
  throw new Rfc64CatalogAuthorityResolutionErrorV1('unregistered-owner-unresolved', 'unregistered RFC-64 Context Graph has no authenticated owner authority');
2260
2083
  }
@@ -2262,6 +2085,19 @@ export class Rfc64CatalogMethods extends DKGAgentBase {
2262
2085
  authority = replicaUnregisteredAuthority;
2263
2086
  }
2264
2087
  else {
2088
+ // Capture before the first owner/policy authority-fact read. Taking
2089
+ // this revision only before the later roster read could combine an
2090
+ // old owner with a new policy/roster generation and still pass the
2091
+ // acceptance-time fence.
2092
+ //
2093
+ // A join-approved composition keeps the revision its proof was
2094
+ // taken against. Capturing a fresh one here would make a change
2095
+ // that landed between the proof's last check and this line the new
2096
+ // baseline, and the acceptance-time fence could no longer see it.
2097
+ metadataAuthorityRevision = approvedPrivateReplicaAuthority !== null
2098
+ ? approvedPrivateMetaRevision
2099
+ : this.contextGraphMetaProjection
2100
+ .readContextGraphAuthorityFactsRevision(contextGraphId);
2265
2101
  const ownerDid = await this.getContextGraphOwner(contextGraphId);
2266
2102
  if (signal?.aborted)
2267
2103
  throw signal.reason;
@@ -2294,15 +2130,58 @@ export class Rfc64CatalogMethods extends DKGAgentBase {
2294
2130
  && ownerAddress !== directAcceptedPrivateSnapshot.policy.source.ownerAddress) {
2295
2131
  throw new Rfc64CatalogAuthorityResolutionErrorV1('unregistered-owner-unresolved', 'authenticated private RFC-64 authority owner does not match lifecycle metadata');
2296
2132
  }
2133
+ if (approvedPrivateReplicaAuthority !== null
2134
+ && (accessPolicy !== 'private'
2135
+ || ownerAddress !== approvedPrivateReplicaAuthority.ownerAddress)) {
2136
+ throw new Rfc64CatalogAuthorityResolutionErrorV1('unregistered-owner-unresolved', 'approved private replica authority does not match lifecycle metadata');
2137
+ }
2297
2138
  const stored = await this.getStoredContextGraphRegistrationOptions(contextGraphId);
2298
2139
  const publishPolicy = stored.publishPolicy === 0 || stored.publishPolicy === 1
2299
2140
  ? stored.publishPolicy
2300
2141
  : accessPolicy === 'private' ? 0 : 1;
2301
- const members = accessPolicy === 'private'
2302
- ? await this.resolveRfc64VerifiedPrivateRosterV1(contextGraphId)
2303
- : [];
2142
+ // The approved-replica proof above has already authenticated this
2143
+ // receiver's private definition and is fenced to its metadata
2144
+ // revision. Read that definition's effective roster directly here.
2145
+ // The general recovery helper performs another registration read;
2146
+ // during a catalog refresh that read can lose the accepted-absence
2147
+ // allowance while authority is resolving, making the roster depend
2148
+ // on the very catalog authority this refresh is meant to restore.
2149
+ let members = [];
2150
+ if (accessPolicy === 'private') {
2151
+ if (approvedPrivateReplicaAuthority !== null) {
2152
+ const confirmed = await this.hasConfirmedMetaState(contextGraphId)
2153
+ .catch(() => false);
2154
+ members = confirmed
2155
+ ? await this.getLocalMetadataMemberRecoveryGate(contextGraphId, { signal })
2156
+ : null;
2157
+ if (members !== null) {
2158
+ // The join proof authenticates one member against the graph's
2159
+ // own `_meta`. The roster above comes from the merged
2160
+ // projection, where the shared agents and ontology graphs can
2161
+ // name allowed agents no curator approved. Keep only addresses
2162
+ // the graph's own `_meta` names; a revocation from any source
2163
+ // has already been applied.
2164
+ const ownMeta = await this.getOwnCgMetaFacts(contextGraphId, { signal });
2165
+ if (signal?.aborted)
2166
+ throw signal.reason;
2167
+ const namedByOwnMeta = new Set([...ownMeta.allowedAgents, ...ownMeta.participantAgents]
2168
+ .map((address) => address.toLowerCase()));
2169
+ members = members.filter((member) => namedByOwnMeta.has(member.toLowerCase()));
2170
+ }
2171
+ }
2172
+ else {
2173
+ members = await this.resolveRfc64VerifiedPrivateRosterV1(contextGraphId);
2174
+ }
2175
+ }
2304
2176
  if (accessPolicy === 'private' && members === null) {
2305
- throw new Error('unregistered private RFC-64 Context Graph has no authenticated lifecycle roster');
2177
+ throw new Rfc64CatalogAuthorityResolutionErrorV1(localFirstUnregistered
2178
+ ? 'unregistered-private-roster-unresolved'
2179
+ : 'unregistered-owner-unresolved', 'unregistered private RFC-64 Context Graph has no authenticated lifecycle roster');
2180
+ }
2181
+ if (approvedPrivateReplicaAuthority !== null
2182
+ && !members?.some((member) => member.toLowerCase()
2183
+ === approvedPrivateReplicaAuthority.approvedAgentAddress)) {
2184
+ throw new Rfc64CatalogAuthorityResolutionErrorV1('unregistered-owner-unresolved', 'approved private replica member is absent from the authenticated roster');
2306
2185
  }
2307
2186
  const rosterVersion = await this.readRfc64PrivateRosterVersionV1(contextGraphId);
2308
2187
  if (signal?.aborted)
@@ -2323,6 +2202,11 @@ export class Rfc64CatalogMethods extends DKGAgentBase {
2323
2202
  }
2324
2203
  if (!isCurrentRfc64CatalogAuthorityRevisionV1(this, contextGraphId, authorityRevision))
2325
2204
  return null;
2205
+ if (metadataAuthorityRevision !== null
2206
+ && this.contextGraphMetaProjection
2207
+ .readContextGraphAuthorityFactsRevision(contextGraphId)
2208
+ !== metadataAuthorityRevision)
2209
+ return new Rfc64AuthorityFactsMovedV1(authorityRevision);
2326
2210
  // Finalized absence was exact when the refresh request was created, but
2327
2211
  // RDF evidence loading is asynchronous. Discovery may bind the graph to
2328
2212
  // a chain id during that await without starting a successor reconcile
@@ -2334,12 +2218,20 @@ export class Rfc64CatalogMethods extends DKGAgentBase {
2334
2218
  && this.subscribedContextGraphs.get(contextGraphId)?.onChainId !== undefined) {
2335
2219
  throw new Rfc64CatalogAuthorityResolutionErrorV1('registered-authority-binding-mismatch', 'registered RFC-64 Context Graph cannot accept unregistered replica authority');
2336
2220
  }
2221
+ // The join proof was taken before the reads above. Its delegation can
2222
+ // pass its deadline in the meantime without any store write, so the
2223
+ // revision fences do not see it: check the deadline in this same pass.
2224
+ if (approvedPrivateReplicaAuthority !== null
2225
+ && !isApprovedPrivateReplicaDelegationActive(approvedPrivateReplicaAuthority)) {
2226
+ throw new Rfc64CatalogAuthorityResolutionErrorV1('unregistered-owner-unresolved', 'approved private replica delegation expired while its authority was composed');
2227
+ }
2337
2228
  const previousAuthority = service.acceptedPolicySnapshot(authority.policy.networkId, authority.policy.contextGraphId);
2338
2229
  const acceptedAuthority = service.acceptAuthoritativePolicySnapshot({
2339
2230
  policy: authority.policy,
2340
2231
  policyDigest: authority.policyDigest,
2341
2232
  roster: authority.roster,
2342
2233
  });
2234
+ noteRfc64AcceptedAuthorityOriginV1(this, contextGraphId, approvedPrivateReplicaAuthority === null ? 'authenticated' : 'join-approval');
2343
2235
  const authorityGenerationChanged = rfc64CatalogAuthorityGenerationChangedV1(previousAuthority, acceptedAuthority);
2344
2236
  if (authorityGenerationChanged) {
2345
2237
  service.deactivateReceiverContextGraph(contextGraphId);
@@ -2354,6 +2246,11 @@ export class Rfc64CatalogMethods extends DKGAgentBase {
2354
2246
  reason: null,
2355
2247
  updatedAtMs: Date.now(),
2356
2248
  });
2249
+ // Restart can restore all applied heads without a receiver completion.
2250
+ // Fresh accepted authority must also wake the live readiness verifier.
2251
+ if (approvedPrivateReplicaAuthority !== null) {
2252
+ this.eventBus.emit(DKGEvent.CATALOG_READINESS_CHECK_REQUESTED, { contextGraphId });
2253
+ }
2357
2254
  // A first subscription attempt can race this authority bootstrap and
2358
2255
  // correctly fail closed. Re-enter the idempotent transport reconciler
2359
2256
  // exactly when authority becomes usable (or its generation changes),
@@ -2362,7 +2259,10 @@ export class Rfc64CatalogMethods extends DKGAgentBase {
2362
2259
  this.queueSharedMemoryGossipSubscription(contextGraphId);
2363
2260
  this.scheduleRfc64AuthorityAcceptedPeerCatchupV1();
2364
2261
  }
2365
- this.scheduleRfc64AuthorityAcceptedCatalogRecoveryV1(contextGraphId, acceptedAuthority.policyDigest);
2262
+ this.scheduleRfc64AuthorityAcceptedCatalogRecoveryV1(contextGraphId, acceptedAuthority.policyDigest, {
2263
+ awaitsProviderAuthorization: approvedPrivateReplicaAuthority !== null,
2264
+ retryIncompletePrivate: acceptedAuthority.policy.accessPolicy === 1,
2265
+ });
2366
2266
  return authority;
2367
2267
  }
2368
2268
  catch (error) {
@@ -2416,24 +2316,56 @@ export class Rfc64CatalogMethods extends DKGAgentBase {
2416
2316
  * wait on receiver admission. The keyed dispatcher owns cancellation,
2417
2317
  * coalescing, error reporting, and shutdown drain for the detached work.
2418
2318
  */
2419
- scheduleRfc64AuthorityAcceptedCatalogRecoveryV1(contextGraphId, policyDigest) {
2319
+ scheduleRfc64AuthorityAcceptedCatalogRecoveryV1(contextGraphId, policyDigest, options = {}) {
2320
+ const awaitsProviderAuthorization = options.awaitsProviderAuthorization === true;
2321
+ const retryDelays = awaitsProviderAuthorization
2322
+ ? RFC64_JOIN_DERIVED_CATALOG_RECOVERY_RETRY_DELAYS_MS_V1
2323
+ : RFC64_AUTHORITY_CATALOG_RECOVERY_RETRY_DELAYS_MS_V1;
2420
2324
  const workKey = `authority-catalog-recovery\0${contextGraphId}\0${policyDigest}`;
2421
2325
  this.rfc64BackgroundWorkDispatcherV1.scheduleKeyed(workKey, async (signal) => {
2422
- for (let attempt = 0; attempt <= RFC64_AUTHORITY_CATALOG_RECOVERY_RETRY_DELAYS_MS_V1.length; attempt += 1) {
2326
+ for (let attempt = 0; attempt <= retryDelays.length; attempt += 1) {
2423
2327
  try {
2424
2328
  await this.promoteRfc64OwnerSignedSwmInventoriesV1(contextGraphId, signal);
2425
2329
  signal.throwIfAborted();
2426
- await this.requestRfc64CatalogHeadReplaysFromConnectedPeersV1(contextGraphId, signal);
2427
- return;
2330
+ const replay = await this.requestRfc64CatalogHeadReplaysFromConnectedPeersV1(contextGraphId, signal);
2331
+ // A private join may accept its owner-signed policy before both
2332
+ // peers have the current member roster. A peer may answer replay
2333
+ // while the subsequent native fetch is still denied. The replay
2334
+ // runtime's settled parity, not an answered request alone, is the
2335
+ // evidence that the promised catalog rows were applied, so that
2336
+ // replica keeps this bounded demand alive until the parity is clean.
2337
+ if (!awaitsProviderAuthorization && !options.retryIncompletePrivate)
2338
+ return;
2339
+ const progress = this.rfc64CatalogReplayRecoveryRuntimeV1().status(contextGraphId, policyDigest);
2340
+ const incomplete = progress?.failed === true || progress?.unverified === true;
2341
+ // A private graph can finish receiving every row while its replay
2342
+ // drain times out or an authorized peer is temporarily unavailable.
2343
+ // Its first accepted-authority pass must not leave that unverified
2344
+ // witness standing until another authority revision happens. Retry
2345
+ // only this observed incomplete state, under the existing short
2346
+ // budget. Ordinary public and already-clean graphs still do one
2347
+ // pass; the longer join-derived budget remains join-only.
2348
+ if (!awaitsProviderAuthorization) {
2349
+ if (!options.retryIncompletePrivate || !incomplete)
2350
+ return;
2351
+ }
2352
+ else if (replay.requested > 0 && !incomplete) {
2353
+ return;
2354
+ }
2428
2355
  }
2429
2356
  catch (error) {
2430
2357
  if (signal.aborted)
2431
2358
  throw signal.reason ?? error;
2432
- const retryDelayMs = RFC64_AUTHORITY_CATALOG_RECOVERY_RETRY_DELAYS_MS_V1[attempt];
2359
+ const retryDelayMs = retryDelays[attempt];
2433
2360
  if (retryDelayMs === undefined)
2434
2361
  throw error;
2435
2362
  await waitForRfc64ScheduledResponsibilityDelayV1(signal, retryDelayMs);
2363
+ continue;
2436
2364
  }
2365
+ const retryDelayMs = retryDelays[attempt];
2366
+ if (retryDelayMs === undefined)
2367
+ return;
2368
+ await waitForRfc64ScheduledResponsibilityDelayV1(signal, retryDelayMs);
2437
2369
  }
2438
2370
  });
2439
2371
  }
@@ -2494,6 +2426,10 @@ export class Rfc64CatalogMethods extends DKGAgentBase {
2494
2426
  return false;
2495
2427
  if (accepted.policy.accessPolicy === 0)
2496
2428
  return true;
2429
+ // Join-derived authority does not replace the live join proof: leave the
2430
+ // decision to the caller's read-authority check, which runs that proof.
2431
+ if (this.isRfc64JoinDerivedAcceptedAuthorityV1?.(contextGraphId) === true)
2432
+ return undefined;
2497
2433
  if (accepted.roster === null)
2498
2434
  return false;
2499
2435
  const effectiveCaller = opts.callerAgentAddress
@@ -2501,6 +2437,16 @@ export class Rfc64CatalogMethods extends DKGAgentBase {
2501
2437
  ?? this.defaultAgentAddress;
2502
2438
  return this.isAgentAddressAllowed(effectiveCaller, accepted.roster.members.map(({ agentAddress }) => agentAddress));
2503
2439
  }
2440
+ /**
2441
+ * Whether this graph's accepted policy was composed from a private join
2442
+ * approval. Such a snapshot is labelled owner-signed-unregistered like an
2443
+ * authenticated owner policy, but it rests on a proof that expires with the
2444
+ * member's delegation and belongs to one request generation. Reads and
2445
+ * shared-memory access therefore ignore it and keep running the proof.
2446
+ */
2447
+ isRfc64JoinDerivedAcceptedAuthorityV1(contextGraphId) {
2448
+ return rfc64JoinDerivedAcceptedAuthorityV1.get(this)?.has(contextGraphId) === true;
2449
+ }
2504
2450
  /** Whether an accepted compatibility policy, not responsibility, owns this CG's RFC-64 authority. */
2505
2451
  hasRfc64AcceptedCompatibilityAuthorityV1(contextGraphId) {
2506
2452
  return this.resolveRfc64AcceptedCompatibilityAuthorityV1(contextGraphId) !== null;
@@ -2553,6 +2499,39 @@ export class Rfc64CatalogMethods extends DKGAgentBase {
2553
2499
  return this.isRfc64CatalogTransportAuthorityActiveV1(contextGraphId)
2554
2500
  && this.hasAcceptedRfc64PublicUnregisteredAuthorityV1(contextGraphId);
2555
2501
  }
2502
+ /**
2503
+ * Current private roster of the accepted owner-signed unregistered policy,
2504
+ * but only while RFC-64 catalog authority governs transport for this graph.
2505
+ *
2506
+ * `undefined` means that no active accepted private-unregistered authority
2507
+ * applies. `null` keeps an applicable but incomplete private authority
2508
+ * fail-closed. Callers must not use the retained accepted snapshot directly:
2509
+ * it deliberately survives a kill switch or inactive catalog lane.
2510
+ */
2511
+ resolveActiveAcceptedRfc64PrivateUnregisteredRosterV1(contextGraphId) {
2512
+ if (!this.isRfc64CatalogTransportAuthorityActiveV1(contextGraphId)) {
2513
+ return undefined;
2514
+ }
2515
+ const configuredPrivate = this.config.rfc64CatalogBootstrap?.acceptedPolicies.some(({ policyEnvelope }) => (policyEnvelope.payload.contextGraphId === contextGraphId
2516
+ && policyEnvelope.payload.accessPolicy === 1)) === true;
2517
+ const accepted = this.readAcceptedRfc64CatalogAccessSnapshotV1(contextGraphId);
2518
+ // A selected private graph stays fail-closed while its policy/roster has
2519
+ // not yet been accepted. Once the catalog transport fence is inactive,
2520
+ // the early return above deliberately restores the legacy fallback.
2521
+ if (accepted === null)
2522
+ return configuredPrivate ? null : undefined;
2523
+ if (accepted.policy.source.kind !== 'owner-signed-unregistered'
2524
+ || accepted.policy.accessPolicy !== 1) {
2525
+ return undefined;
2526
+ }
2527
+ // A join-derived roster is not owner-authenticated transport authority;
2528
+ // the approved-replica proof path keeps governing this graph.
2529
+ if (this.isRfc64JoinDerivedAcceptedAuthorityV1?.(contextGraphId) === true)
2530
+ return undefined;
2531
+ if (accepted.roster === null)
2532
+ return null;
2533
+ return Object.freeze(accepted.roster.members.map(({ agentAddress }) => agentAddress));
2534
+ }
2556
2535
  /**
2557
2536
  * Access policy of the authority this catalog owner has already accepted for
2558
2537
  * the exact active network and graph, or `null` while none is accepted. The
@@ -2843,6 +2822,9 @@ export class Rfc64CatalogMethods extends DKGAgentBase {
2843
2822
  // through the ambient lane. Exact retirement must not depend on the
2844
2823
  // optional attempt-observer bookkeeping still being present.
2845
2824
  retireRfc64CatalogTargetAnnouncementV1(this, announcement);
2825
+ this.eventBus.emit(DKGEvent.CATALOG_READINESS_CHECK_REQUESTED, {
2826
+ contextGraphId: announcement.contextGraphId,
2827
+ });
2846
2828
  const attempt = reconciliationAttempts.get(token);
2847
2829
  if (attempt === undefined)
2848
2830
  return;
@@ -2967,6 +2949,7 @@ export class Rfc64CatalogMethods extends DKGAgentBase {
2967
2949
  this.rfc64PublicCatalogSynchronizationEvidenceV1.clear();
2968
2950
  this.rfc64PublicCatalogReconciliationFailuresV1.clear();
2969
2951
  rfc64DirectAcceptedCompatibilityV1.delete(this);
2952
+ rfc64JoinDerivedAcceptedAuthorityV1.delete(this);
2970
2953
  rfc64CatalogReplayRuntimesV1.delete(this);
2971
2954
  rfc64CatalogReplaySnapshotRuntimesV1.delete(this);
2972
2955
  rfc64CatalogReplayRecoveryRuntimesV1.get(this)?.reset();
@@ -3007,6 +2990,7 @@ export class Rfc64CatalogMethods extends DKGAgentBase {
3007
2990
  this.clearRfc64CatalogOperationalTargetsV1(input.policy.contextGraphId);
3008
2991
  }
3009
2992
  markRfc64DirectAcceptedCompatibilityV1(this, input.policy.contextGraphId);
2993
+ noteRfc64AcceptedAuthorityOriginV1(this, input.policy.contextGraphId, 'authenticated');
3010
2994
  return accepted;
3011
2995
  }
3012
2996
  /** Author path for a previously accepted policy snapshot in any V1 cell. */
@@ -3249,6 +3233,53 @@ export class Rfc64CatalogMethods extends DKGAgentBase {
3249
3233
  },
3250
3234
  });
3251
3235
  }
3236
+ /** Replay only this graph's current head to the exact approved peer. */
3237
+ async reannounceRfc64CatalogAfterJoinApprovalV1(contextGraphId, approvedAgentAddress, peerId) {
3238
+ const accepted = this.readAcceptedRfc64CatalogAccessSnapshotV1(contextGraphId);
3239
+ if (accepted === null)
3240
+ return false;
3241
+ if (accepted.policy.accessPolicy === 1
3242
+ && !accepted.roster?.members.some((member) => member.agentAddress.toLowerCase() === approvedAgentAddress.toLowerCase()))
3243
+ return false;
3244
+ const replay = await this.reannounceRfc64CatalogHeadsToPeerV1(peerId, {
3245
+ kind: RFC64_PUBLIC_CATALOG_HEAD_REPLAY_KIND_V1,
3246
+ networkId: accepted.policy.networkId,
3247
+ contextGraphId: accepted.policy.contextGraphId,
3248
+ policyDigest: accepted.policyDigest,
3249
+ });
3250
+ // An approval can precede the first authored head. An empty replay is not
3251
+ // delivery evidence: keep the bounded retry armed so a head published a
3252
+ // moment later is announced under the settled private roster.
3253
+ return replay.failed === 0 && replay.announced > 0;
3254
+ }
3255
+ /**
3256
+ * An approval can arrive while its successor private roster is still being
3257
+ * composed. Keep the exact approved peer's replay demand alive past the
3258
+ * short notification attempt without delaying the join or widening the
3259
+ * accepted policy. The dispatcher cancels and drains this bounded work on
3260
+ * shutdown; each attempt rechecks current authority and membership.
3261
+ */
3262
+ scheduleRfc64CatalogAfterJoinApprovalRetryV1(contextGraphId, approvedAgentAddress, peerId) {
3263
+ const workKey = `join-approved-catalog-replay\0${contextGraphId}\0${approvedAgentAddress.toLowerCase()}\0${peerId}`;
3264
+ return this.rfc64BackgroundWorkDispatcherV1.scheduleKeyed(workKey, async (signal) => {
3265
+ for (const delayMs of RFC64_JOIN_APPROVAL_CATALOG_REPLAY_RETRY_DELAYS_MS_V1) {
3266
+ await waitForRfc64ScheduledResponsibilityDelayV1(signal, delayMs);
3267
+ try {
3268
+ await this.reconcileRfc64CatalogAccessAuthorityV1(contextGraphId, signal);
3269
+ signal.throwIfAborted();
3270
+ if (await this.reannounceRfc64CatalogAfterJoinApprovalV1(contextGraphId, approvedAgentAddress, peerId))
3271
+ return;
3272
+ }
3273
+ catch (error) {
3274
+ if (signal.aborted)
3275
+ throw signal.reason ?? error;
3276
+ // An overlapping metadata write or transport refusal is retryable;
3277
+ // the next pass still has to authenticate the current roster.
3278
+ }
3279
+ }
3280
+ this.log.warn(createOperationContext('system'), `RFC-64 catalog replay remained pending after bounded join approval retries for "${contextGraphId}"`);
3281
+ });
3282
+ }
3252
3283
  /** Request scoped head replay from already-connected peers after late activation. */
3253
3284
  async requestRfc64CatalogHeadReplaysFromConnectedPeersV1(contextGraphId, signal) {
3254
3285
  return this.requestRfc64CatalogHeadReplayV1(contextGraphId, {
@@ -3279,27 +3310,34 @@ export class Rfc64CatalogMethods extends DKGAgentBase {
3279
3310
  contextGraphId,
3280
3311
  policyDigest: accepted.policyDigest,
3281
3312
  };
3313
+ const settle = async (task) => {
3314
+ const result = await task;
3315
+ // Receiver completion precedes the replay owner's parity settlement.
3316
+ // Wake readiness again after that owner releases its active fence.
3317
+ this.eventBus.emit(DKGEvent.CATALOG_READINESS_CHECK_REQUESTED, { contextGraphId });
3318
+ return result;
3319
+ };
3282
3320
  switch (request.kind) {
3283
3321
  case 'connected-peers':
3284
- return this.rfc64CatalogReplayRecoveryRuntimeV1().request({
3322
+ return settle(this.rfc64CatalogReplayRecoveryRuntimeV1().request({
3285
3323
  ...scope,
3286
3324
  ...(signal === undefined ? {} : { signal }),
3287
3325
  kind: 'full-connected-peers',
3288
3326
  connectedPeerIds: this.node.libp2p.getPeers().map((peer) => peer.toString()),
3289
- });
3327
+ }));
3290
3328
  case 'pending-recovery':
3291
- return this.rfc64CatalogReplayRecoveryRuntimeV1().request({
3329
+ return settle(this.rfc64CatalogReplayRecoveryRuntimeV1().request({
3292
3330
  ...scope,
3293
3331
  ...(signal === undefined ? {} : { signal }),
3294
3332
  kind: 'pending-recovery',
3295
- });
3333
+ }));
3296
3334
  case 'connection-demand':
3297
- return this.rfc64CatalogReplayRecoveryRuntimeV1().request({
3335
+ return settle(this.rfc64CatalogReplayRecoveryRuntimeV1().request({
3298
3336
  ...scope,
3299
3337
  ...(signal === undefined ? {} : { signal }),
3300
3338
  kind: 'connection-demand',
3301
3339
  demand: request.replayDemand,
3302
- });
3340
+ }));
3303
3341
  }
3304
3342
  }
3305
3343
  /**
@@ -3602,7 +3640,7 @@ export class Rfc64CatalogMethods extends DKGAgentBase {
3602
3640
  // `chainConfig` is ignored, so reading it here would pin the
3603
3641
  // precommits to the default while the adapter's own authority
3604
3642
  // reads honoured the operator. One anchor, one source.
3605
- finalityConfirmations: this.resolveChainFinalityConfirmationsV1(),
3643
+ finalityConfirmations: resolveChainFinalityConfirmationsV1(this.chain, this.config.chainConfig),
3606
3644
  getOnChainContextGraphId: (contextGraphId, signal) => this.getContextGraphOnChainId(contextGraphId, { signal }),
3607
3645
  getEvmChainId: () => this.chain.getEvmChainId(),
3608
3646
  });
@@ -3616,7 +3654,7 @@ export class Rfc64CatalogMethods extends DKGAgentBase {
3616
3654
  // `chainConfig` is ignored, so reading it here would pin the
3617
3655
  // precommits to the default while the adapter's own authority
3618
3656
  // reads honoured the operator. One anchor, one source.
3619
- finalityConfirmations: this.resolveChainFinalityConfirmationsV1(),
3657
+ finalityConfirmations: resolveChainFinalityConfirmationsV1(this.chain, this.config.chainConfig),
3620
3658
  getOnChainContextGraphId: (contextGraphId, signal) => this.getContextGraphOnChainId(contextGraphId, { signal }),
3621
3659
  getEvmChainId: () => this.chain.getEvmChainId(),
3622
3660
  getKnowledgeAssetStorageAddress: async () => {
@@ -3694,6 +3732,12 @@ export class Rfc64CatalogMethods extends DKGAgentBase {
3694
3732
  resolveTrustedCatalogScope: clients.resolveTrustedCatalogScope,
3695
3733
  resolveDeployment,
3696
3734
  requiresAppliedHeadPrecommit: (announcement) => {
3735
+ // An exact applied head can precede a late legacy SWM root marker.
3736
+ // Replaying that authenticated head retires the marker under the
3737
+ // native receiver lease; treating the head as satisfied would
3738
+ // leave the graph permanently known-incomplete despite row parity.
3739
+ if (readRfc64LegacySwmBoundaryCountV1(this, announcement.contextGraphId) > 0)
3740
+ return true;
3697
3741
  const accepted = this.requireRfc64PublicCatalogServiceV1()
3698
3742
  .acceptedPolicySnapshotForCatalogScope(clients.resolveTrustedCatalogScope(announcement));
3699
3743
  return accepted.policy.accessPolicy === 1