@noy-db/hub 0.8.0 → 0.9.0-pre.1

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 (567) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/README.md +8 -8
  3. package/codemods/0.4.0-pre.json +1 -1
  4. package/codemods/0.8.0-pre.json +1 -1
  5. package/dist/api-6EFD43KN.js +18 -0
  6. package/dist/as/index.js +33 -23
  7. package/dist/as/index.js.map +1 -1
  8. package/dist/at/index.js +8 -8
  9. package/dist/attestation/index.js +18 -18
  10. package/dist/{backup-YE2VQ26S.js → backup-RJBFQSHE.js} +92 -31
  11. package/dist/backup-RJBFQSHE.js.map +1 -0
  12. package/dist/blobs/index.js +12 -12
  13. package/dist/broker/index.js +19 -11
  14. package/dist/broker/index.js.map +1 -1
  15. package/dist/by/index.js +2 -2
  16. package/dist/capsule/contract.d.ts +1 -1
  17. package/dist/capsule/contract.js +6 -6
  18. package/dist/capsule/enclave-aes/broker/proof.d.ts +12 -3
  19. package/dist/capsule/enclave-aes/crypto.d.ts +18 -0
  20. package/dist/capsule/enclave-aes/index.d.ts +3 -3
  21. package/dist/capsule/enclave-aes/index.js +46 -14
  22. package/dist/capsule/enclave-aes/index.js.map +1 -1
  23. package/dist/capsule/index.d.ts +2 -2
  24. package/dist/capsule/plumbing/record-codec.d.ts +7 -0
  25. package/dist/{capsule-VOLX3QRQ.js → capsule-6LJAVQNM.js} +14 -8
  26. package/dist/cargo/index.js +35 -35
  27. package/dist/{chunk-GZT3NQRA.js → chunk-25FXU6WS.js} +8 -2
  28. package/dist/chunk-25FXU6WS.js.map +1 -0
  29. package/dist/{chunk-OYW3I5M4.js → chunk-2DOCDOPL.js} +6 -6
  30. package/dist/chunk-2DX4JCRI.js +1 -0
  31. package/dist/{chunk-FLPCETP6.js → chunk-2LBS62AC.js} +2 -2
  32. package/dist/{chunk-WXE4W2U6.js → chunk-2ST3WA3C.js} +4 -4
  33. package/dist/{chunk-DQESF6RP.js → chunk-3G3GOGZZ.js} +50 -40
  34. package/dist/chunk-3G3GOGZZ.js.map +1 -0
  35. package/dist/{chunk-O2IMQSNA.js → chunk-3YBIVLTC.js} +2 -2
  36. package/dist/{chunk-LGNDFRYC.js → chunk-4CFHL5RY.js} +1 -1
  37. package/dist/chunk-4CFHL5RY.js.map +1 -0
  38. package/dist/{chunk-DIZLQVAA.js → chunk-4CHM2TRS.js} +2 -2
  39. package/dist/{chunk-V7ADQF5O.js → chunk-4CUJLEOA.js} +4 -4
  40. package/dist/{chunk-3EWS67C7.js → chunk-4TG2ITRW.js} +2 -2
  41. package/dist/{chunk-HS554XAF.js → chunk-5HQFROZS.js} +2 -2
  42. package/dist/{chunk-IUBMZPHM.js → chunk-5ZVE3N5C.js} +5 -6
  43. package/dist/chunk-5ZVE3N5C.js.map +1 -0
  44. package/dist/{chunk-PP3K67AJ.js → chunk-654RE5YC.js} +3 -3
  45. package/dist/{chunk-FOEDQATO.js → chunk-66GD7XXU.js} +2 -2
  46. package/dist/{chunk-BNWA3WG5.js → chunk-72FQ46VW.js} +3 -3
  47. package/dist/{chunk-EYG2CY2X.js → chunk-7JPA3LIH.js} +11 -11
  48. package/dist/chunk-7JPA3LIH.js.map +1 -0
  49. package/dist/{chunk-JQYKPKG6.js → chunk-7K42TSCY.js} +4 -4
  50. package/dist/{chunk-BPWYQ25R.js → chunk-7Q6IU3R7.js} +4 -4
  51. package/dist/{chunk-BPWYQ25R.js.map → chunk-7Q6IU3R7.js.map} +1 -1
  52. package/dist/{chunk-T7IR4N2S.js → chunk-7UHLO4ZN.js} +37 -2
  53. package/dist/chunk-7UHLO4ZN.js.map +1 -0
  54. package/dist/{chunk-UEFOQH74.js → chunk-ADCXTW7L.js} +2 -2
  55. package/dist/{chunk-MBMTND6D.js → chunk-AGGPT4UE.js} +2 -2
  56. package/dist/{chunk-RB4DOPGZ.js → chunk-AKIEBFIJ.js} +10 -10
  57. package/dist/{chunk-VHBKYN2J.js → chunk-B3B6HV5S.js} +2 -2
  58. package/dist/{chunk-JWWYRR4Q.js → chunk-B6EWMGFX.js} +2 -2
  59. package/dist/{chunk-H7JBY4P7.js → chunk-B7Y2BRQA.js} +14 -14
  60. package/dist/chunk-B7Y2BRQA.js.map +1 -0
  61. package/dist/{chunk-4CIQDWRB.js → chunk-BFJE2GPP.js} +14 -8
  62. package/dist/{chunk-4CIQDWRB.js.map → chunk-BFJE2GPP.js.map} +1 -1
  63. package/dist/{chunk-WPOYWFSE.js → chunk-BJRKXNFP.js} +7 -7
  64. package/dist/{chunk-H427H63K.js → chunk-BPQ5CRJF.js} +2 -2
  65. package/dist/{chunk-VFHCKG5M.js → chunk-BVRJYMFZ.js} +3 -3
  66. package/dist/{chunk-244QBK7Z.js → chunk-C4XV3PSJ.js} +4 -4
  67. package/dist/{chunk-244QBK7Z.js.map → chunk-C4XV3PSJ.js.map} +1 -1
  68. package/dist/{chunk-SMV2HRDU.js → chunk-DFC4WTJW.js} +2 -2
  69. package/dist/{chunk-5A4345TG.js → chunk-DMIEKD24.js} +3 -3
  70. package/dist/{chunk-TKVUE4JF.js → chunk-DQAXA2GK.js} +9 -9
  71. package/dist/{chunk-AL6ML4LA.js → chunk-DWCFGF2K.js} +5 -5
  72. package/dist/{chunk-Y3LPTBG7.js → chunk-E2C6FFSI.js} +6 -9
  73. package/dist/chunk-E2C6FFSI.js.map +1 -0
  74. package/dist/{chunk-LNSVGRHO.js → chunk-EQ6C2ZPT.js} +17 -51
  75. package/dist/chunk-EQ6C2ZPT.js.map +1 -0
  76. package/dist/chunk-EZOFTI4K.js +60 -0
  77. package/dist/chunk-EZOFTI4K.js.map +1 -0
  78. package/dist/{chunk-PD64727P.js → chunk-FMINS2B6.js} +2 -2
  79. package/dist/chunk-FMINS2B6.js.map +1 -0
  80. package/dist/{chunk-QBLT6POL.js → chunk-FPF5HRBE.js} +2 -2
  81. package/dist/{chunk-UA372JHH.js → chunk-FZVCZEVI.js} +3 -3
  82. package/dist/chunk-FZVCZEVI.js.map +1 -0
  83. package/dist/{chunk-FFWI7UH7.js → chunk-GAGT3YZN.js} +1 -1
  84. package/dist/chunk-GAGT3YZN.js.map +1 -0
  85. package/dist/{chunk-5WWDGFOS.js → chunk-GIQJGXV7.js} +2 -2
  86. package/dist/{chunk-V3RWOOSO.js → chunk-GYZICGRU.js} +4 -4
  87. package/dist/chunk-GYZICGRU.js.map +1 -0
  88. package/dist/{chunk-BVCUTXE3.js → chunk-H334G6KU.js} +2 -2
  89. package/dist/{chunk-AEQGFRU4.js → chunk-HE7EAHGS.js} +3 -3
  90. package/dist/chunk-HKB4HZDU.js +74 -0
  91. package/dist/chunk-HKB4HZDU.js.map +1 -0
  92. package/dist/{chunk-4V3Q35WG.js → chunk-ICF3TIGY.js} +3 -3
  93. package/dist/{chunk-3L2NBKDR.js → chunk-IF2M43G4.js} +2 -2
  94. package/dist/{chunk-37EPTBBR.js → chunk-IKPQ2GGB.js} +46 -4
  95. package/dist/chunk-IKPQ2GGB.js.map +1 -0
  96. package/dist/{chunk-DHHGL42E.js → chunk-IKS2CPAG.js} +27 -11
  97. package/dist/chunk-IKS2CPAG.js.map +1 -0
  98. package/dist/{chunk-3A5DUZ56.js → chunk-IMIQAGR7.js} +6 -6
  99. package/dist/{chunk-3A5DUZ56.js.map → chunk-IMIQAGR7.js.map} +1 -1
  100. package/dist/{chunk-A4XMIZT3.js → chunk-IQAJ4OR6.js} +41 -6
  101. package/dist/chunk-IQAJ4OR6.js.map +1 -0
  102. package/dist/{chunk-IUT3GWP3.js → chunk-IUD7WU67.js} +17 -93
  103. package/dist/chunk-IUD7WU67.js.map +1 -0
  104. package/dist/{chunk-AUKKUPVB.js → chunk-IVLRPRXM.js} +2 -2
  105. package/dist/{chunk-GUZET4SG.js → chunk-JAQHWHUN.js} +4 -4
  106. package/dist/chunk-JAQHWHUN.js.map +1 -0
  107. package/dist/{chunk-Y2RKVFKR.js → chunk-K4JSTGXT.js} +2 -2
  108. package/dist/{chunk-EJLV62NI.js → chunk-KN4LUMH6.js} +2 -2
  109. package/dist/{chunk-23D6M6VM.js → chunk-KZA3DITX.js} +4 -4
  110. package/dist/{chunk-E2N2T5ZO.js → chunk-L2VM64HK.js} +2 -2
  111. package/dist/chunk-L4UL4IAR.js +55 -0
  112. package/dist/chunk-L4UL4IAR.js.map +1 -0
  113. package/dist/{chunk-UIYESRD6.js → chunk-LUCQY3OM.js} +10 -10
  114. package/dist/{chunk-UIYESRD6.js.map → chunk-LUCQY3OM.js.map} +1 -1
  115. package/dist/{chunk-O46CHQT7.js → chunk-MAQBYBUX.js} +4 -4
  116. package/dist/{chunk-EZOAKKTB.js → chunk-MBPZMZVB.js} +2 -2
  117. package/dist/{chunk-XQRFSKYM.js → chunk-MCNNZBG7.js} +2 -2
  118. package/dist/{chunk-YRXFFWG4.js → chunk-MLVPMDOZ.js} +2 -2
  119. package/dist/{chunk-5FE75J4S.js → chunk-MMCN7TLK.js} +5 -5
  120. package/dist/{chunk-MXOQ5JCG.js → chunk-MRCR7ZMC.js} +686 -202
  121. package/dist/chunk-MRCR7ZMC.js.map +1 -0
  122. package/dist/{chunk-SYNY3VB5.js → chunk-NCTN2FW4.js} +2 -2
  123. package/dist/{chunk-4T3SE27M.js → chunk-ND6S2DKC.js} +2 -2
  124. package/dist/{chunk-3XJQBBZD.js → chunk-NTVKHQ3L.js} +2 -2
  125. package/dist/{chunk-RHVMZSUU.js → chunk-NV4OESHC.js} +1 -1
  126. package/dist/chunk-NV4OESHC.js.map +1 -0
  127. package/dist/chunk-NXQEOC3X.js +40 -0
  128. package/dist/chunk-NXQEOC3X.js.map +1 -0
  129. package/dist/{chunk-Q4UHJ5SN.js → chunk-O2VQ3K36.js} +2 -2
  130. package/dist/{chunk-HW7CMKUG.js → chunk-OFD2HD6F.js} +1 -1
  131. package/dist/{chunk-HW7CMKUG.js.map → chunk-OFD2HD6F.js.map} +1 -1
  132. package/dist/{chunk-2GHDLTPE.js → chunk-OGKMRIIJ.js} +2 -2
  133. package/dist/{chunk-N7EVQD5S.js → chunk-ONZ3B5EW.js} +4 -4
  134. package/dist/{chunk-VKI2EB3N.js → chunk-OOPSMQX5.js} +3 -3
  135. package/dist/{chunk-VMV5SBE4.js → chunk-OYEBSWLE.js} +5 -5
  136. package/dist/{chunk-JDEYF3PJ.js → chunk-P6FATPXQ.js} +2 -2
  137. package/dist/chunk-P6FATPXQ.js.map +1 -0
  138. package/dist/{chunk-VVOLDVIR.js → chunk-PLTIJDQN.js} +2 -2
  139. package/dist/{chunk-OKSTSITU.js → chunk-PR7ILCIH.js} +3 -3
  140. package/dist/{chunk-7R2Q7CPL.js → chunk-QE3TLZ6Z.js} +7 -7
  141. package/dist/{chunk-G2MVBDFP.js → chunk-QFW4MYGN.js} +39 -9
  142. package/dist/chunk-QFW4MYGN.js.map +1 -0
  143. package/dist/{chunk-6QVKPHBF.js → chunk-QHG7GQKM.js} +2 -2
  144. package/dist/chunk-QJNAHPVT.js +91 -0
  145. package/dist/chunk-QJNAHPVT.js.map +1 -0
  146. package/dist/{chunk-LIOVX5TJ.js → chunk-QT5ITL25.js} +3 -3
  147. package/dist/{chunk-IMQKWR46.js → chunk-R2ZULFXU.js} +4 -5
  148. package/dist/chunk-R2ZULFXU.js.map +1 -0
  149. package/dist/{chunk-Q2XRFWOI.js → chunk-RRTQAQ3N.js} +2 -2
  150. package/dist/{chunk-H23XHRTT.js → chunk-RUE6TCES.js} +809 -101
  151. package/dist/chunk-RUE6TCES.js.map +1 -0
  152. package/dist/chunk-RWFQVNXR.js +24 -0
  153. package/dist/chunk-RWFQVNXR.js.map +1 -0
  154. package/dist/{chunk-2PVXF5CS.js → chunk-SALY3LIJ.js} +3 -3
  155. package/dist/{chunk-JOSPH3E5.js → chunk-SBAR5JQ6.js} +2 -2
  156. package/dist/{chunk-N7UDP5VU.js → chunk-SCH2F7R2.js} +7 -7
  157. package/dist/{chunk-MXKI4ABF.js → chunk-SOOAW6HK.js} +3 -3
  158. package/dist/{chunk-VQDZYB2B.js → chunk-T4VTRKCY.js} +3 -3
  159. package/dist/{chunk-VQDZYB2B.js.map → chunk-T4VTRKCY.js.map} +1 -1
  160. package/dist/{chunk-TEHHROZL.js → chunk-T5EXREMW.js} +5 -5
  161. package/dist/{chunk-M5B2W6YY.js → chunk-TDJVQTXD.js} +3 -3
  162. package/dist/{chunk-QMWY2FDS.js → chunk-THQ3BHLM.js} +2 -2
  163. package/dist/{chunk-VAORSCSU.js → chunk-TLIFNRU5.js} +2 -2
  164. package/dist/chunk-TLIFNRU5.js.map +1 -0
  165. package/dist/{chunk-FVH5QYY2.js → chunk-TRHUNPXP.js} +2 -2
  166. package/dist/{chunk-EGVJ7TM4.js → chunk-UL6MTRMJ.js} +8 -9
  167. package/dist/chunk-UL6MTRMJ.js.map +1 -0
  168. package/dist/chunk-UNL6YGL5.js +169 -0
  169. package/dist/chunk-UNL6YGL5.js.map +1 -0
  170. package/dist/{chunk-747G6CT3.js → chunk-UORWAG7K.js} +2 -2
  171. package/dist/{chunk-XSPFDUDG.js → chunk-V7AKGAXY.js} +314 -77
  172. package/dist/chunk-V7AKGAXY.js.map +1 -0
  173. package/dist/{chunk-TZZBXPZK.js → chunk-VLQ6KT7F.js} +2 -2
  174. package/dist/{chunk-NCO25JZO.js → chunk-VP37VUKQ.js} +4 -4
  175. package/dist/{chunk-52MGURXO.js → chunk-WBUHHMLN.js} +2 -2
  176. package/dist/{chunk-EZGV6F47.js → chunk-WRLWEYHY.js} +7 -1
  177. package/dist/chunk-WRLWEYHY.js.map +1 -0
  178. package/dist/{chunk-2MG3SW7Q.js → chunk-X6Z2SIRF.js} +2 -2
  179. package/dist/{chunk-U2FZNEWJ.js → chunk-XLKWF3L4.js} +8 -6
  180. package/dist/{chunk-U2FZNEWJ.js.map → chunk-XLKWF3L4.js.map} +1 -1
  181. package/dist/{chunk-5UMK7GRI.js → chunk-XPNJH7GN.js} +5 -5
  182. package/dist/{chunk-KZXDLBY6.js → chunk-XPW7T2GN.js} +5 -5
  183. package/dist/{chunk-SV2PM2OY.js → chunk-XX4R7TUB.js} +1 -1
  184. package/dist/chunk-XX4R7TUB.js.map +1 -0
  185. package/dist/{chunk-NBQ3KK6X.js → chunk-Y55XHMQB.js} +4 -4
  186. package/dist/chunk-Y55XHMQB.js.map +1 -0
  187. package/dist/{chunk-5KC7QYEC.js → chunk-YH4OUOSI.js} +33 -7
  188. package/dist/chunk-YH4OUOSI.js.map +1 -0
  189. package/dist/{chunk-FFJFE4T7.js → chunk-YJGKOSQD.js} +2 -2
  190. package/dist/{chunk-2AFX33YA.js → chunk-Z3STG43F.js} +3 -3
  191. package/dist/chunk-Z3STG43F.js.map +1 -0
  192. package/dist/{chunk-OIEO4WDL.js → chunk-ZD7WFMV2.js} +2 -2
  193. package/dist/chunk-ZD7WFMV2.js.map +1 -0
  194. package/dist/{chunk-42ALPZ2B.js → chunk-ZF6JECDT.js} +4 -4
  195. package/dist/{chunk-42ALPZ2B.js.map → chunk-ZF6JECDT.js.map} +1 -1
  196. package/dist/{chunk-4JPMZTJY.js → chunk-ZF7KNSLU.js} +2 -2
  197. package/dist/{chunk-2ODVB6LZ.js → chunk-ZGKODRGB.js} +2 -2
  198. package/dist/{chunk-JIBUPZHA.js → chunk-ZNEKQFGF.js} +4 -4
  199. package/dist/{chunk-DLD5LGDS.js → chunk-ZUTUNVFD.js} +3 -3
  200. package/dist/{chunk-JSMTXZR3.js → chunk-ZWMOHANW.js} +8 -6
  201. package/dist/chunk-ZWMOHANW.js.map +1 -0
  202. package/dist/{chunk-MILI22XQ.js → chunk-ZZZ4VCY2.js} +10 -10
  203. package/dist/chunk-ZZZ4VCY2.js.map +1 -0
  204. package/dist/classified/index.js +5 -5
  205. package/dist/{classified-marker-SIYKUU5L.js → classified-marker-WKP33U2R.js} +3 -3
  206. package/dist/collection-facade-COSGZKLC.js +41 -0
  207. package/dist/{computed-FAD7SED4.js → computed-WN6V53ZV.js} +3 -3
  208. package/dist/consent/index.js +8 -8
  209. package/dist/cover/index.js +8 -8
  210. package/dist/coverage/index.js +1 -1
  211. package/dist/custody/index.js +12 -11
  212. package/dist/{dead-filter-4F3LWYKH.js → dead-filter-43WL3Y5H.js} +10 -10
  213. package/dist/debug/index.js +7 -7
  214. package/dist/delegation-5UWT4JGT.js +26 -0
  215. package/dist/derivations/index.js +24 -23
  216. package/dist/derive-IL5JNLEE.js +20 -0
  217. package/dist/directory/index.js +9 -9
  218. package/dist/{dispatch-JDZNGEB3.js → dispatch-LOQQD5JK.js} +20 -20
  219. package/dist/{dispatch-H4HV32AM.js → dispatch-SHKTG57L.js} +5 -5
  220. package/dist/executor-6PQ7WAGV.js +35 -0
  221. package/dist/executor-6ZPQA6HS.js +8 -0
  222. package/dist/executor-OXRA64TY.js +8 -0
  223. package/dist/export-accessible-XG3FKJWW.js +22 -0
  224. package/dist/extract-partition-33747NY5.js +35 -0
  225. package/dist/{fanout-sidecar-L7NHPIOC.js → fanout-sidecar-NEB6IYV7.js} +8 -8
  226. package/dist/find-VW543G3J.js +10 -0
  227. package/dist/forget/index.js +25 -8
  228. package/dist/forget/index.js.map +1 -1
  229. package/dist/guards/index.js +4 -4
  230. package/dist/history/index.js +15 -13
  231. package/dist/history/index.js.map +1 -1
  232. package/dist/i18n/index.js +13 -13
  233. package/dist/index.d.ts +9 -6
  234. package/dist/index.js +126 -110
  235. package/dist/index.js.map +1 -1
  236. package/dist/indexing/index.js +6 -6
  237. package/dist/introspection/index.js +15 -11
  238. package/dist/issue-4ZPSY44M.js +19 -0
  239. package/dist/kernel/cache/index.d.ts +1 -1
  240. package/dist/kernel/collection.d.ts +86 -6
  241. package/dist/kernel/constants.d.ts +7 -0
  242. package/dist/kernel/errors.d.ts +42 -4
  243. package/dist/kernel/export-scope.d.ts +40 -0
  244. package/dist/kernel/merge-authority.d.ts +5 -1
  245. package/dist/kernel/noydb.d.ts +118 -21
  246. package/dist/kernel/put-many-atomic.d.ts +1 -1
  247. package/dist/kernel/query/live/live.d.ts +2 -1
  248. package/dist/kernel/query/sort-key.d.ts +0 -2
  249. package/dist/kernel/rejection-seal.d.ts +13 -0
  250. package/dist/kernel/sync-wiring.d.ts +55 -0
  251. package/dist/kernel/tx-write-gate.d.ts +2 -4
  252. package/dist/kernel/types.d.ts +463 -14
  253. package/dist/kernel/validation.d.ts +0 -10
  254. package/dist/kernel/vault.d.ts +42 -4
  255. package/dist/kernel/via/reconcile.d.ts +1 -42
  256. package/dist/{ledger-5ZMGE44K.js → ledger-MZ25UFT2.js} +10 -10
  257. package/dist/liberate-OJIP2ZFX.js +25 -0
  258. package/dist/{link-set-MFXC24VK.js → link-set-4FRRAVTH.js} +10 -10
  259. package/dist/{managed-secret-MFTFT22X.js → managed-secret-SQWO2EUR.js} +9 -9
  260. package/dist/materialized-views/index.js +26 -26
  261. package/dist/{migrate-cek-DZRFFOHW.js → migrate-cek-JWEM4RP6.js} +2 -2
  262. package/dist/money/index.js +5 -5
  263. package/dist/noydb-U62OVKXB.js +100 -0
  264. package/dist/on/index.js +25 -0
  265. package/dist/overlay-views/index.js +4 -4
  266. package/dist/periods/index.js +11 -11
  267. package/dist/pod/index.js +71 -67
  268. package/dist/{pod-handle-A3LET7NO.js → pod-handle-R6Y4MILX.js} +8 -8
  269. package/dist/policy/index.js +9 -9
  270. package/dist/port/as/active.d.ts +4 -0
  271. package/dist/port/as/index.d.ts +1 -0
  272. package/dist/port/by/index.d.ts +14 -5
  273. package/dist/port/on/index.d.ts +26 -0
  274. package/dist/port/to/index.d.ts +1 -1
  275. package/dist/port/with/admission-authority.d.ts +34 -0
  276. package/dist/port/with/broker-strategy.d.ts +24 -0
  277. package/dist/port/with/coverage-strategy.d.ts +17 -1
  278. package/dist/port/with/formats-strategy.d.ts +34 -1
  279. package/dist/port/with/lookup-strategy.d.ts +85 -4
  280. package/dist/port/with/rejection-courier.d.ts +37 -0
  281. package/dist/port/with/restore-host.d.ts +33 -0
  282. package/dist/port/with/service-bus.d.ts +20 -1
  283. package/dist/port/with/team-strategy.d.ts +2 -2
  284. package/dist/port/with/write-hooks.d.ts +2 -0
  285. package/dist/portability/index.js +8 -8
  286. package/dist/{post-register-7ND27CF2.js → post-register-GRVQHBOH.js} +6 -6
  287. package/dist/query/all/index.js +16 -16
  288. package/dist/query/index.js +8 -8
  289. package/dist/query/live/index.js +7 -7
  290. package/dist/query/reduce/index.js +10 -10
  291. package/dist/query/relate/index.js +10 -10
  292. package/dist/reduce/index.js +8 -8
  293. package/dist/register-YJ5YLQ36.js +30 -0
  294. package/dist/registry-ICOHBQFD.js +8 -0
  295. package/dist/registry-MJ7MWCSW.js +35 -0
  296. package/dist/registry-MVEKKGWL.js +23 -0
  297. package/dist/registry-XP744FAP.js +8 -0
  298. package/dist/request-withdrawal-LSU4G6W3.js +28 -0
  299. package/dist/restore-to-DVBHAQAA.js +66 -0
  300. package/dist/restore-to-DVBHAQAA.js.map +1 -0
  301. package/dist/{reveal-B2TLP4JQ.js → reveal-AIHOIK2N.js} +7 -7
  302. package/dist/revoke-QUT7WWG3.js +24 -0
  303. package/dist/satellites/index.js +1 -1
  304. package/dist/schema-update/index.js +2 -2
  305. package/dist/sealed-record/index.js +11 -11
  306. package/dist/search/index.js +4 -4
  307. package/dist/{seed-XNSE4U3S.js → seed-GFLA4FCK.js} +136 -27
  308. package/dist/seed-GFLA4FCK.js.map +1 -0
  309. package/dist/sequence/index.js +8 -8
  310. package/dist/session/index.js +8 -8
  311. package/dist/shadow/index.js +2 -2
  312. package/dist/signer-NYR4I3FO.js +23 -0
  313. package/dist/snapshots/index.js +9 -9
  314. package/dist/{stale-6GCFMOOR.js → stale-PIJPAL5T.js} +9 -9
  315. package/dist/storage-VH6SPXHC.js +21 -0
  316. package/dist/{store-coordination-provider-C4BPT5XF.js → store-coordination-provider-2KSHCOPU.js} +9 -9
  317. package/dist/sync/index.js +19 -13
  318. package/dist/sync/index.js.map +1 -1
  319. package/dist/team/index.js +17 -15
  320. package/dist/tiers/index.js +10 -10
  321. package/dist/to/index.js +2 -2
  322. package/dist/transactions/index.js +3 -3
  323. package/dist/util/index.js +1 -1
  324. package/dist/vault-head/index.js +8 -8
  325. package/dist/{verify-UKALW7C2.js → verify-PCFS4PNS.js} +7 -7
  326. package/dist/via/classified/presets.d.ts +29 -0
  327. package/dist/via/classified/resolve.d.ts +7 -0
  328. package/dist/via/geo/binding.d.ts +0 -4
  329. package/dist/via/lookup/index.d.ts +32 -0
  330. package/dist/via/money/binding.d.ts +0 -9
  331. package/dist/walk-OZCN6LJS.js +20 -0
  332. package/dist/with-audit/attestation/strategy.d.ts +2 -1
  333. package/dist/with-audit/attestation/vault-facade.d.ts +7 -0
  334. package/dist/with-audit/forget/completeness.d.ts +66 -0
  335. package/dist/with-audit/forget/index.d.ts +2 -0
  336. package/dist/with-audit/forget/strategy.d.ts +65 -0
  337. package/dist/with-audit/guards/types.d.ts +2 -0
  338. package/dist/with-audit/periods/periods.d.ts +0 -9
  339. package/dist/with-audit/periods/reserved-collections.d.ts +7 -0
  340. package/dist/with-audit/portability/request-withdrawal.d.ts +0 -1
  341. package/dist/with-audit/portability/withdraw-accessible.d.ts +0 -1
  342. package/dist/with-audit/tiers/index.d.ts +6 -6
  343. package/dist/with-audit/tiers/strategy.d.ts +19 -0
  344. package/dist/with-cargo/extract-partition.d.ts +0 -46
  345. package/dist/with-commit/history/history.d.ts +16 -0
  346. package/dist/with-commit/history/restore-to.d.ts +40 -0
  347. package/dist/with-commit/numbering/index.d.ts +0 -2
  348. package/dist/with-commit/tx/transaction.d.ts +2 -24
  349. package/dist/with-commit/vault-head/strategy.d.ts +7 -0
  350. package/dist/with-fork/snapshots/noydb-facade.d.ts +7 -0
  351. package/dist/with-formula/derivations/trigger-match.d.ts +8 -5
  352. package/dist/with-formula/materialized-views/emit-memo.d.ts +0 -2
  353. package/dist/with-lookup/embeddings/index.d.ts +1 -2
  354. package/dist/with-lookup/indexing/collection-facade.d.ts +1 -15
  355. package/dist/with-lookup/indexing/eager-indexes.d.ts +2 -1
  356. package/dist/with-lookup/search/collection-facade.d.ts +0 -12
  357. package/dist/with-party/broker/index.d.ts +2 -2
  358. package/dist/with-party/broker/seed.d.ts +29 -10
  359. package/dist/with-party/custody/strategy.d.ts +2 -2
  360. package/dist/with-party/policy/noydb-facade.d.ts +1 -31
  361. package/dist/with-party/team/delegation.d.ts +93 -7
  362. package/dist/with-party/team/echo-secret.d.ts +0 -2
  363. package/dist/with-party/team/index.d.ts +2 -0
  364. package/dist/with-party/team/keyring.d.ts +133 -24
  365. package/dist/with-party/team/magic-link-grant.d.ts +11 -1
  366. package/dist/with-party/team/noydb-facade.d.ts +19 -2
  367. package/dist/with-party/team/reserved-secret-collections.d.ts +10 -8
  368. package/dist/with-party/team/roster-tag.d.ts +42 -1
  369. package/dist/with-party/team/tiers.d.ts +36 -5
  370. package/dist/with-pod/backup.d.ts +9 -17
  371. package/dist/with-shape/blobs/blob-set.d.ts +23 -0
  372. package/dist/with-shape/blobs/legacy-sweep.d.ts +16 -0
  373. package/dist/with-shape/introspection/describe.d.ts +1 -2
  374. package/dist/with-shape/introspection/index.d.ts +1 -0
  375. package/dist/with-shape/introspection/types.d.ts +2 -1
  376. package/dist/with-shape/schema-update/fence.d.ts +7 -0
  377. package/dist/with-sync/active.d.ts +28 -1
  378. package/dist/with-sync/engine.d.ts +88 -2
  379. package/dist/with-sync/index.d.ts +1 -0
  380. package/dist/with-sync/reserved-mirror.d.ts +112 -0
  381. package/dist/with-sync/strategy.d.ts +9 -0
  382. package/dist/with-sync/tab-write-relay.d.ts +0 -10
  383. package/dist/withdraw-accessible-MTFP7OIB.js +25 -0
  384. package/dist/withdraw-accessible-MTFP7OIB.js.map +1 -0
  385. package/package.json +3 -3
  386. package/dist/api-OS747DS4.js +0 -18
  387. package/dist/backup-YE2VQ26S.js.map +0 -1
  388. package/dist/chunk-2AFX33YA.js.map +0 -1
  389. package/dist/chunk-2RH777HH.js +0 -126
  390. package/dist/chunk-2RH777HH.js.map +0 -1
  391. package/dist/chunk-37EPTBBR.js.map +0 -1
  392. package/dist/chunk-5KC7QYEC.js.map +0 -1
  393. package/dist/chunk-7XMHMVTS.js +0 -20
  394. package/dist/chunk-7XMHMVTS.js.map +0 -1
  395. package/dist/chunk-A4XMIZT3.js.map +0 -1
  396. package/dist/chunk-DHHGL42E.js.map +0 -1
  397. package/dist/chunk-DQESF6RP.js.map +0 -1
  398. package/dist/chunk-EGVJ7TM4.js.map +0 -1
  399. package/dist/chunk-EYG2CY2X.js.map +0 -1
  400. package/dist/chunk-EZGV6F47.js.map +0 -1
  401. package/dist/chunk-FFWI7UH7.js.map +0 -1
  402. package/dist/chunk-G2MVBDFP.js.map +0 -1
  403. package/dist/chunk-GUZET4SG.js.map +0 -1
  404. package/dist/chunk-GZT3NQRA.js.map +0 -1
  405. package/dist/chunk-H23XHRTT.js.map +0 -1
  406. package/dist/chunk-H7JBY4P7.js.map +0 -1
  407. package/dist/chunk-IMQKWR46.js.map +0 -1
  408. package/dist/chunk-IUBMZPHM.js.map +0 -1
  409. package/dist/chunk-IUT3GWP3.js.map +0 -1
  410. package/dist/chunk-JDEYF3PJ.js.map +0 -1
  411. package/dist/chunk-JSMTXZR3.js.map +0 -1
  412. package/dist/chunk-LGNDFRYC.js.map +0 -1
  413. package/dist/chunk-LNSVGRHO.js.map +0 -1
  414. package/dist/chunk-MILI22XQ.js.map +0 -1
  415. package/dist/chunk-MXOQ5JCG.js.map +0 -1
  416. package/dist/chunk-NBQ3KK6X.js.map +0 -1
  417. package/dist/chunk-OIEO4WDL.js.map +0 -1
  418. package/dist/chunk-PD64727P.js.map +0 -1
  419. package/dist/chunk-RHVMZSUU.js.map +0 -1
  420. package/dist/chunk-SV2PM2OY.js.map +0 -1
  421. package/dist/chunk-T7IR4N2S.js.map +0 -1
  422. package/dist/chunk-UA372JHH.js.map +0 -1
  423. package/dist/chunk-UBSFPGVJ.js +0 -1
  424. package/dist/chunk-V3RWOOSO.js.map +0 -1
  425. package/dist/chunk-VAORSCSU.js.map +0 -1
  426. package/dist/chunk-XSPFDUDG.js.map +0 -1
  427. package/dist/chunk-Y3LPTBG7.js.map +0 -1
  428. package/dist/collection-facade-CS7CA2XO.js +0 -47
  429. package/dist/delegation-NANZDG4N.js +0 -102
  430. package/dist/delegation-NANZDG4N.js.map +0 -1
  431. package/dist/derive-XLOJVXPU.js +0 -20
  432. package/dist/executor-FMPVN6DT.js +0 -35
  433. package/dist/executor-LBBBRTN5.js +0 -8
  434. package/dist/executor-OSRZST2U.js +0 -8
  435. package/dist/export-accessible-RAOJAAU5.js +0 -22
  436. package/dist/extract-partition-JD5CUSTG.js +0 -37
  437. package/dist/find-JRN4RNQ5.js +0 -10
  438. package/dist/issue-YIVBZUTH.js +0 -19
  439. package/dist/liberate-WZSZM2W6.js +0 -24
  440. package/dist/noydb-ITIGNKUF.js +0 -96
  441. package/dist/register-DT5HZ2LZ.js +0 -30
  442. package/dist/registry-BHRZGZHF.js +0 -8
  443. package/dist/registry-ET6ZFFWA.js +0 -34
  444. package/dist/registry-HXFGLGTG.js +0 -8
  445. package/dist/registry-THCPDEOD.js +0 -23
  446. package/dist/request-withdrawal-AV2MJJKY.js +0 -30
  447. package/dist/revoke-6DWIEOCV.js +0 -24
  448. package/dist/seed-XNSE4U3S.js.map +0 -1
  449. package/dist/signer-MHGW3OIL.js +0 -23
  450. package/dist/storage-BYN5LO6Z.js +0 -21
  451. package/dist/walk-4VPK7AS4.js +0 -20
  452. package/dist/withdraw-accessible-HL7GACUE.js +0 -27
  453. /package/dist/{api-OS747DS4.js.map → api-6EFD43KN.js.map} +0 -0
  454. /package/dist/{capsule-VOLX3QRQ.js.map → capsule-6LJAVQNM.js.map} +0 -0
  455. /package/dist/{chunk-OYW3I5M4.js.map → chunk-2DOCDOPL.js.map} +0 -0
  456. /package/dist/{chunk-UBSFPGVJ.js.map → chunk-2DX4JCRI.js.map} +0 -0
  457. /package/dist/{chunk-FLPCETP6.js.map → chunk-2LBS62AC.js.map} +0 -0
  458. /package/dist/{chunk-WXE4W2U6.js.map → chunk-2ST3WA3C.js.map} +0 -0
  459. /package/dist/{chunk-O2IMQSNA.js.map → chunk-3YBIVLTC.js.map} +0 -0
  460. /package/dist/{chunk-DIZLQVAA.js.map → chunk-4CHM2TRS.js.map} +0 -0
  461. /package/dist/{chunk-V7ADQF5O.js.map → chunk-4CUJLEOA.js.map} +0 -0
  462. /package/dist/{chunk-3EWS67C7.js.map → chunk-4TG2ITRW.js.map} +0 -0
  463. /package/dist/{chunk-HS554XAF.js.map → chunk-5HQFROZS.js.map} +0 -0
  464. /package/dist/{chunk-PP3K67AJ.js.map → chunk-654RE5YC.js.map} +0 -0
  465. /package/dist/{chunk-FOEDQATO.js.map → chunk-66GD7XXU.js.map} +0 -0
  466. /package/dist/{chunk-BNWA3WG5.js.map → chunk-72FQ46VW.js.map} +0 -0
  467. /package/dist/{chunk-JQYKPKG6.js.map → chunk-7K42TSCY.js.map} +0 -0
  468. /package/dist/{chunk-UEFOQH74.js.map → chunk-ADCXTW7L.js.map} +0 -0
  469. /package/dist/{chunk-MBMTND6D.js.map → chunk-AGGPT4UE.js.map} +0 -0
  470. /package/dist/{chunk-RB4DOPGZ.js.map → chunk-AKIEBFIJ.js.map} +0 -0
  471. /package/dist/{chunk-VHBKYN2J.js.map → chunk-B3B6HV5S.js.map} +0 -0
  472. /package/dist/{chunk-JWWYRR4Q.js.map → chunk-B6EWMGFX.js.map} +0 -0
  473. /package/dist/{chunk-WPOYWFSE.js.map → chunk-BJRKXNFP.js.map} +0 -0
  474. /package/dist/{chunk-H427H63K.js.map → chunk-BPQ5CRJF.js.map} +0 -0
  475. /package/dist/{chunk-VFHCKG5M.js.map → chunk-BVRJYMFZ.js.map} +0 -0
  476. /package/dist/{chunk-SMV2HRDU.js.map → chunk-DFC4WTJW.js.map} +0 -0
  477. /package/dist/{chunk-5A4345TG.js.map → chunk-DMIEKD24.js.map} +0 -0
  478. /package/dist/{chunk-TKVUE4JF.js.map → chunk-DQAXA2GK.js.map} +0 -0
  479. /package/dist/{chunk-AL6ML4LA.js.map → chunk-DWCFGF2K.js.map} +0 -0
  480. /package/dist/{chunk-QBLT6POL.js.map → chunk-FPF5HRBE.js.map} +0 -0
  481. /package/dist/{chunk-5WWDGFOS.js.map → chunk-GIQJGXV7.js.map} +0 -0
  482. /package/dist/{chunk-BVCUTXE3.js.map → chunk-H334G6KU.js.map} +0 -0
  483. /package/dist/{chunk-AEQGFRU4.js.map → chunk-HE7EAHGS.js.map} +0 -0
  484. /package/dist/{chunk-4V3Q35WG.js.map → chunk-ICF3TIGY.js.map} +0 -0
  485. /package/dist/{chunk-3L2NBKDR.js.map → chunk-IF2M43G4.js.map} +0 -0
  486. /package/dist/{chunk-AUKKUPVB.js.map → chunk-IVLRPRXM.js.map} +0 -0
  487. /package/dist/{chunk-Y2RKVFKR.js.map → chunk-K4JSTGXT.js.map} +0 -0
  488. /package/dist/{chunk-EJLV62NI.js.map → chunk-KN4LUMH6.js.map} +0 -0
  489. /package/dist/{chunk-23D6M6VM.js.map → chunk-KZA3DITX.js.map} +0 -0
  490. /package/dist/{chunk-E2N2T5ZO.js.map → chunk-L2VM64HK.js.map} +0 -0
  491. /package/dist/{chunk-O46CHQT7.js.map → chunk-MAQBYBUX.js.map} +0 -0
  492. /package/dist/{chunk-EZOAKKTB.js.map → chunk-MBPZMZVB.js.map} +0 -0
  493. /package/dist/{chunk-XQRFSKYM.js.map → chunk-MCNNZBG7.js.map} +0 -0
  494. /package/dist/{chunk-YRXFFWG4.js.map → chunk-MLVPMDOZ.js.map} +0 -0
  495. /package/dist/{chunk-5FE75J4S.js.map → chunk-MMCN7TLK.js.map} +0 -0
  496. /package/dist/{chunk-SYNY3VB5.js.map → chunk-NCTN2FW4.js.map} +0 -0
  497. /package/dist/{chunk-4T3SE27M.js.map → chunk-ND6S2DKC.js.map} +0 -0
  498. /package/dist/{chunk-3XJQBBZD.js.map → chunk-NTVKHQ3L.js.map} +0 -0
  499. /package/dist/{chunk-Q4UHJ5SN.js.map → chunk-O2VQ3K36.js.map} +0 -0
  500. /package/dist/{chunk-2GHDLTPE.js.map → chunk-OGKMRIIJ.js.map} +0 -0
  501. /package/dist/{chunk-N7EVQD5S.js.map → chunk-ONZ3B5EW.js.map} +0 -0
  502. /package/dist/{chunk-VKI2EB3N.js.map → chunk-OOPSMQX5.js.map} +0 -0
  503. /package/dist/{chunk-VMV5SBE4.js.map → chunk-OYEBSWLE.js.map} +0 -0
  504. /package/dist/{chunk-VVOLDVIR.js.map → chunk-PLTIJDQN.js.map} +0 -0
  505. /package/dist/{chunk-OKSTSITU.js.map → chunk-PR7ILCIH.js.map} +0 -0
  506. /package/dist/{chunk-7R2Q7CPL.js.map → chunk-QE3TLZ6Z.js.map} +0 -0
  507. /package/dist/{chunk-6QVKPHBF.js.map → chunk-QHG7GQKM.js.map} +0 -0
  508. /package/dist/{chunk-LIOVX5TJ.js.map → chunk-QT5ITL25.js.map} +0 -0
  509. /package/dist/{chunk-Q2XRFWOI.js.map → chunk-RRTQAQ3N.js.map} +0 -0
  510. /package/dist/{chunk-2PVXF5CS.js.map → chunk-SALY3LIJ.js.map} +0 -0
  511. /package/dist/{chunk-JOSPH3E5.js.map → chunk-SBAR5JQ6.js.map} +0 -0
  512. /package/dist/{chunk-N7UDP5VU.js.map → chunk-SCH2F7R2.js.map} +0 -0
  513. /package/dist/{chunk-MXKI4ABF.js.map → chunk-SOOAW6HK.js.map} +0 -0
  514. /package/dist/{chunk-TEHHROZL.js.map → chunk-T5EXREMW.js.map} +0 -0
  515. /package/dist/{chunk-M5B2W6YY.js.map → chunk-TDJVQTXD.js.map} +0 -0
  516. /package/dist/{chunk-QMWY2FDS.js.map → chunk-THQ3BHLM.js.map} +0 -0
  517. /package/dist/{chunk-FVH5QYY2.js.map → chunk-TRHUNPXP.js.map} +0 -0
  518. /package/dist/{chunk-747G6CT3.js.map → chunk-UORWAG7K.js.map} +0 -0
  519. /package/dist/{chunk-TZZBXPZK.js.map → chunk-VLQ6KT7F.js.map} +0 -0
  520. /package/dist/{chunk-NCO25JZO.js.map → chunk-VP37VUKQ.js.map} +0 -0
  521. /package/dist/{chunk-52MGURXO.js.map → chunk-WBUHHMLN.js.map} +0 -0
  522. /package/dist/{chunk-2MG3SW7Q.js.map → chunk-X6Z2SIRF.js.map} +0 -0
  523. /package/dist/{chunk-5UMK7GRI.js.map → chunk-XPNJH7GN.js.map} +0 -0
  524. /package/dist/{chunk-KZXDLBY6.js.map → chunk-XPW7T2GN.js.map} +0 -0
  525. /package/dist/{chunk-FFJFE4T7.js.map → chunk-YJGKOSQD.js.map} +0 -0
  526. /package/dist/{chunk-4JPMZTJY.js.map → chunk-ZF7KNSLU.js.map} +0 -0
  527. /package/dist/{chunk-2ODVB6LZ.js.map → chunk-ZGKODRGB.js.map} +0 -0
  528. /package/dist/{chunk-JIBUPZHA.js.map → chunk-ZNEKQFGF.js.map} +0 -0
  529. /package/dist/{chunk-DLD5LGDS.js.map → chunk-ZUTUNVFD.js.map} +0 -0
  530. /package/dist/{classified-marker-SIYKUU5L.js.map → classified-marker-WKP33U2R.js.map} +0 -0
  531. /package/dist/{collection-facade-CS7CA2XO.js.map → collection-facade-COSGZKLC.js.map} +0 -0
  532. /package/dist/{computed-FAD7SED4.js.map → computed-WN6V53ZV.js.map} +0 -0
  533. /package/dist/{dead-filter-4F3LWYKH.js.map → dead-filter-43WL3Y5H.js.map} +0 -0
  534. /package/dist/{derive-XLOJVXPU.js.map → delegation-5UWT4JGT.js.map} +0 -0
  535. /package/dist/{executor-FMPVN6DT.js.map → derive-IL5JNLEE.js.map} +0 -0
  536. /package/dist/{dispatch-JDZNGEB3.js.map → dispatch-LOQQD5JK.js.map} +0 -0
  537. /package/dist/{dispatch-H4HV32AM.js.map → dispatch-SHKTG57L.js.map} +0 -0
  538. /package/dist/{executor-LBBBRTN5.js.map → executor-6PQ7WAGV.js.map} +0 -0
  539. /package/dist/{executor-OSRZST2U.js.map → executor-6ZPQA6HS.js.map} +0 -0
  540. /package/dist/{export-accessible-RAOJAAU5.js.map → executor-OXRA64TY.js.map} +0 -0
  541. /package/dist/{extract-partition-JD5CUSTG.js.map → export-accessible-XG3FKJWW.js.map} +0 -0
  542. /package/dist/{find-JRN4RNQ5.js.map → extract-partition-33747NY5.js.map} +0 -0
  543. /package/dist/{fanout-sidecar-L7NHPIOC.js.map → fanout-sidecar-NEB6IYV7.js.map} +0 -0
  544. /package/dist/{issue-YIVBZUTH.js.map → find-VW543G3J.js.map} +0 -0
  545. /package/dist/{ledger-5ZMGE44K.js.map → issue-4ZPSY44M.js.map} +0 -0
  546. /package/dist/{liberate-WZSZM2W6.js.map → ledger-MZ25UFT2.js.map} +0 -0
  547. /package/dist/{link-set-MFXC24VK.js.map → liberate-OJIP2ZFX.js.map} +0 -0
  548. /package/dist/{managed-secret-MFTFT22X.js.map → link-set-4FRRAVTH.js.map} +0 -0
  549. /package/dist/{noydb-ITIGNKUF.js.map → managed-secret-SQWO2EUR.js.map} +0 -0
  550. /package/dist/{migrate-cek-DZRFFOHW.js.map → migrate-cek-JWEM4RP6.js.map} +0 -0
  551. /package/dist/{register-DT5HZ2LZ.js.map → noydb-U62OVKXB.js.map} +0 -0
  552. /package/dist/{pod-handle-A3LET7NO.js.map → pod-handle-R6Y4MILX.js.map} +0 -0
  553. /package/dist/{post-register-7ND27CF2.js.map → post-register-GRVQHBOH.js.map} +0 -0
  554. /package/dist/{registry-BHRZGZHF.js.map → register-YJ5YLQ36.js.map} +0 -0
  555. /package/dist/{registry-ET6ZFFWA.js.map → registry-ICOHBQFD.js.map} +0 -0
  556. /package/dist/{registry-HXFGLGTG.js.map → registry-MJ7MWCSW.js.map} +0 -0
  557. /package/dist/{registry-THCPDEOD.js.map → registry-MVEKKGWL.js.map} +0 -0
  558. /package/dist/{request-withdrawal-AV2MJJKY.js.map → registry-XP744FAP.js.map} +0 -0
  559. /package/dist/{revoke-6DWIEOCV.js.map → request-withdrawal-LSU4G6W3.js.map} +0 -0
  560. /package/dist/{reveal-B2TLP4JQ.js.map → reveal-AIHOIK2N.js.map} +0 -0
  561. /package/dist/{signer-MHGW3OIL.js.map → revoke-QUT7WWG3.js.map} +0 -0
  562. /package/dist/{stale-6GCFMOOR.js.map → signer-NYR4I3FO.js.map} +0 -0
  563. /package/dist/{storage-BYN5LO6Z.js.map → stale-PIJPAL5T.js.map} +0 -0
  564. /package/dist/{walk-4VPK7AS4.js.map → storage-VH6SPXHC.js.map} +0 -0
  565. /package/dist/{store-coordination-provider-C4BPT5XF.js.map → store-coordination-provider-2KSHCOPU.js.map} +0 -0
  566. /package/dist/{verify-UKALW7C2.js.map → verify-PCFS4PNS.js.map} +0 -0
  567. /package/dist/{withdraw-accessible-HL7GACUE.js.map → walk-OZCN6LJS.js.map} +0 -0
@@ -7,25 +7,28 @@ import {
7
7
  isLinkCollectionName,
8
8
  linkCollectionName,
9
9
  linkRowKey
10
- } from "./chunk-Q4UHJ5SN.js";
10
+ } from "./chunk-O2VQ3K36.js";
11
11
  import {
12
12
  hashFields,
13
13
  validateSatelliteDeclaration
14
- } from "./chunk-XQRFSKYM.js";
14
+ } from "./chunk-MCNNZBG7.js";
15
15
  import {
16
16
  resolveStaleOnRead
17
- } from "./chunk-JOSPH3E5.js";
17
+ } from "./chunk-SBAR5JQ6.js";
18
18
  import {
19
19
  loadFence
20
- } from "./chunk-VAORSCSU.js";
20
+ } from "./chunk-TLIFNRU5.js";
21
+ import {
22
+ DELEGATIONS_COLLECTION
23
+ } from "./chunk-UNL6YGL5.js";
21
24
  import {
22
25
  buildPersistedIndexCallbacks,
23
26
  syncTierSearch
24
- } from "./chunk-Y3LPTBG7.js";
27
+ } from "./chunk-E2C6FFSI.js";
25
28
  import {
26
29
  isBaseLive,
27
30
  liveBaseIdSet
28
- } from "./chunk-2MG3SW7Q.js";
31
+ } from "./chunk-X6Z2SIRF.js";
29
32
  import {
30
33
  SchemaUpdateGate
31
34
  } from "./chunk-6LJY7X5A.js";
@@ -33,26 +36,29 @@ import {
33
36
  NO_TIERS,
34
37
  classifySealedShred,
35
38
  syncDerivedOutputs
36
- } from "./chunk-DHHGL42E.js";
39
+ } from "./chunk-IKS2CPAG.js";
37
40
  import {
38
41
  NO_PORTABILITY
39
- } from "./chunk-AUKKUPVB.js";
42
+ } from "./chunk-IVLRPRXM.js";
40
43
  import {
41
44
  NO_CARGO
42
- } from "./chunk-52MGURXO.js";
45
+ } from "./chunk-WBUHHMLN.js";
43
46
  import {
44
47
  saveSealedSecret
45
- } from "./chunk-3XJQBBZD.js";
48
+ } from "./chunk-NTVKHQ3L.js";
46
49
  import {
47
50
  runDrainBarrier
48
- } from "./chunk-DIZLQVAA.js";
51
+ } from "./chunk-4CHM2TRS.js";
52
+ import {
53
+ NO_FORMATS
54
+ } from "./chunk-RWFQVNXR.js";
49
55
  import {
50
56
  fallbackDerivationName
51
57
  } from "./chunk-RXLYKVTF.js";
52
58
  import {
53
59
  CustodyApi,
54
60
  NO_CUSTODY
55
- } from "./chunk-V3RWOOSO.js";
61
+ } from "./chunk-GYZICGRU.js";
56
62
  import {
57
63
  DEFAULT_POSTURE,
58
64
  ViaGraph,
@@ -66,21 +72,21 @@ import {
66
72
  resolveComputedEdges,
67
73
  resolveDescribeFieldIds,
68
74
  resolveVirtualMoneyFields
69
- } from "./chunk-IUT3GWP3.js";
75
+ } from "./chunk-IUD7WU67.js";
70
76
  import {
71
77
  findMatchingIdsByPairs
72
78
  } from "./chunk-TFMM5DBB.js";
73
79
  import {
74
80
  encodeVecId
75
- } from "./chunk-M5B2W6YY.js";
81
+ } from "./chunk-TDJVQTXD.js";
76
82
  import {
77
83
  NO_CLASSIFIED,
78
84
  guardClassifiedCompat,
79
85
  resolveClassifiedFields
80
- } from "./chunk-GUZET4SG.js";
86
+ } from "./chunk-JAQHWHUN.js";
81
87
  import {
82
88
  derivePersistedSchema
83
- } from "./chunk-747G6CT3.js";
89
+ } from "./chunk-UORWAG7K.js";
84
90
  import {
85
91
  findRollupSpecForIntent,
86
92
  forgetDerivedFanout,
@@ -90,7 +96,7 @@ import {
90
96
  runGraphDispatchWave,
91
97
  selfWriteFieldEqual,
92
98
  touchFor
93
- } from "./chunk-MILI22XQ.js";
99
+ } from "./chunk-ZZZ4VCY2.js";
94
100
  import {
95
101
  buildLookupAltIndex,
96
102
  buildLookupSnapshotRows,
@@ -105,20 +111,22 @@ import {
105
111
  resolveDictSource,
106
112
  resolveLabelFromMap,
107
113
  updateReferencingRecords
108
- } from "./chunk-244QBK7Z.js";
114
+ } from "./chunk-C4XV3PSJ.js";
109
115
  import {
110
116
  OverlayedCollection
111
- } from "./chunk-HS554XAF.js";
117
+ } from "./chunk-5HQFROZS.js";
112
118
  import {
113
119
  INDEXED_STORE_POLICY,
114
- NO_SYNC
115
- } from "./chunk-T7IR4N2S.js";
120
+ NO_SYNC,
121
+ openRejection,
122
+ sealRejection
123
+ } from "./chunk-7UHLO4ZN.js";
116
124
  import {
117
125
  NO_ATTESTATION
118
- } from "./chunk-PD64727P.js";
126
+ } from "./chunk-FMINS2B6.js";
119
127
  import {
120
128
  NO_COVERAGE
121
- } from "./chunk-RHVMZSUU.js";
129
+ } from "./chunk-NV4OESHC.js";
122
130
  import {
123
131
  NO_PERIODS,
124
132
  isEffectivelyReopened,
@@ -128,7 +136,7 @@ import {
128
136
  resolvePeriodKey,
129
137
  resolveReopenState,
130
138
  samePartition
131
- } from "./chunk-3A5DUZ56.js";
139
+ } from "./chunk-IMIQAGR7.js";
132
140
  import {
133
141
  PERIODS_COLLECTION,
134
142
  PERIOD_ARCHIVES_COLLECTION,
@@ -136,7 +144,7 @@ import {
136
144
  PERIOD_REOPENS_COLLECTION,
137
145
  PERIOD_TARGET_PURGES_COLLECTION,
138
146
  periodExclusiveUpperBound
139
- } from "./chunk-QBLT6POL.js";
147
+ } from "./chunk-FPF5HRBE.js";
140
148
  import {
141
149
  NO_SHADOW
142
150
  } from "./chunk-SMY5X46Z.js";
@@ -147,7 +155,7 @@ import {
147
155
  TxContext,
148
156
  bestEffortRevert,
149
157
  trackKeyedWrite
150
- } from "./chunk-UA372JHH.js";
158
+ } from "./chunk-FZVCZEVI.js";
151
159
  import {
152
160
  lazy
153
161
  } from "./chunk-5D2ALSM5.js";
@@ -156,26 +164,26 @@ import {
156
164
  InvertedIndex,
157
165
  MemoryIndexStore,
158
166
  NO_SEARCH
159
- } from "./chunk-RB4DOPGZ.js";
167
+ } from "./chunk-AKIEBFIJ.js";
160
168
  import {
161
169
  NO_SEQUENCE,
162
170
  SEQUENCE_COLLECTION,
163
171
  compileSequenceFormat,
164
172
  resolveSequenceKey
165
- } from "./chunk-VFHCKG5M.js";
173
+ } from "./chunk-BVRJYMFZ.js";
166
174
  import {
167
175
  EXPORT_AUDIT_COLLECTION,
168
176
  NO_BLOBS,
169
177
  createExportBlobsHandle,
170
178
  runCompaction
171
- } from "./chunk-JSMTXZR3.js";
179
+ } from "./chunk-ZWMOHANW.js";
172
180
  import {
173
181
  LazyQuery,
174
182
  NO_INDEXING,
175
183
  compositeKey,
176
184
  decodeIdxId,
177
185
  encodeIdxId
178
- } from "./chunk-V7ADQF5O.js";
186
+ } from "./chunk-4CUJLEOA.js";
179
187
  import {
180
188
  IMPLICIT_LAZY
181
189
  } from "./chunk-66TQOPFM.js";
@@ -193,41 +201,41 @@ import {
193
201
  } from "./chunk-GSAK56VF.js";
194
202
  import {
195
203
  NO_SEALED_RECORD
196
- } from "./chunk-UEFOQH74.js";
204
+ } from "./chunk-ADCXTW7L.js";
197
205
  import {
198
206
  normalizeIndexDefs,
199
207
  parseFieldIndexSnapshot
200
- } from "./chunk-2AFX33YA.js";
208
+ } from "./chunk-Z3STG43F.js";
201
209
  import {
202
210
  EXPORT_REDACTION_MARKER,
203
211
  ViaPipeline,
204
212
  exportRedact
205
- } from "./chunk-3EWS67C7.js";
213
+ } from "./chunk-4TG2ITRW.js";
206
214
  import {
207
215
  ScanBuilder
208
- } from "./chunk-JQYKPKG6.js";
216
+ } from "./chunk-7K42TSCY.js";
209
217
  import {
210
218
  Query
211
- } from "./chunk-AL6ML4LA.js";
219
+ } from "./chunk-DWCFGF2K.js";
212
220
  import {
213
221
  NO_REDUCE
214
222
  } from "./chunk-3TDUWVWB.js";
215
223
  import {
216
224
  readPath
217
- } from "./chunk-5WWDGFOS.js";
225
+ } from "./chunk-GIQJGXV7.js";
218
226
  import {
219
227
  dictCollectionName
220
- } from "./chunk-23D6M6VM.js";
228
+ } from "./chunk-KZA3DITX.js";
221
229
  import {
222
230
  NO_I18N,
223
231
  getAtPath,
224
232
  isDictCollectionName,
225
233
  isStaticDictDescriptor
226
- } from "./chunk-OKSTSITU.js";
234
+ } from "./chunk-PR7ILCIH.js";
227
235
  import {
228
236
  isViaInstalled,
229
237
  viaBinder
230
- } from "./chunk-SYNY3VB5.js";
238
+ } from "./chunk-NCTN2FW4.js";
231
239
  import {
232
240
  NO_TEAM,
233
241
  describeAllUsersAuth,
@@ -250,7 +258,7 @@ import {
250
258
  saveShamirRecoveryEntries,
251
259
  updateAuthenticator,
252
260
  writeMagicLinkGrant
253
- } from "./chunk-DQESF6RP.js";
261
+ } from "./chunk-3G3GOGZZ.js";
254
262
  import {
255
263
  assertKeyringOpenAllowed,
256
264
  buildRecipientKeyringFile,
@@ -265,15 +273,15 @@ import {
265
273
  listUsers,
266
274
  loadKeyring,
267
275
  updateKeyringIdentity
268
- } from "./chunk-XSPFDUDG.js";
276
+ } from "./chunk-V7AKGAXY.js";
269
277
  import {
270
278
  persistDirectoryConfig,
271
279
  readDirectoryConfig
272
- } from "./chunk-LIOVX5TJ.js";
280
+ } from "./chunk-QT5ITL25.js";
273
281
  import {
274
282
  NO_BROKER,
275
283
  buildCredentialBrokerHandle
276
- } from "./chunk-GZT3NQRA.js";
284
+ } from "./chunk-25FXU6WS.js";
277
285
  import {
278
286
  NO_SESSION
279
287
  } from "./chunk-VKQCVU2Z.js";
@@ -282,19 +290,19 @@ import {
282
290
  } from "./chunk-4AOERLTV.js";
283
291
  import {
284
292
  NO_HISTORY
285
- } from "./chunk-LNSVGRHO.js";
293
+ } from "./chunk-L4UL4IAR.js";
286
294
  import {
287
295
  sha256Hex
288
- } from "./chunk-6QVKPHBF.js";
296
+ } from "./chunk-QHG7GQKM.js";
289
297
  import {
290
298
  assertCutoverTierSafe,
291
299
  assertTierWritable,
292
300
  dekKey,
293
301
  liveRecordIsElevated
294
- } from "./chunk-FLPCETP6.js";
302
+ } from "./chunk-2LBS62AC.js";
295
303
  import {
296
304
  NO_VAULT_HEAD
297
- } from "./chunk-HW7CMKUG.js";
305
+ } from "./chunk-OFD2HD6F.js";
298
306
  import {
299
307
  NO_FORGET,
300
308
  addSubjectRef,
@@ -303,7 +311,7 @@ import {
303
311
  readDottedPath,
304
312
  rebuildSubjectIndex,
305
313
  removeSubjectRef
306
- } from "./chunk-JDEYF3PJ.js";
314
+ } from "./chunk-P6FATPXQ.js";
307
315
  import {
308
316
  RecordCodec,
309
317
  SEALED_CEK_NS,
@@ -324,13 +332,13 @@ import {
324
332
  resolveStableCek,
325
333
  rewrapBodyToDek,
326
334
  verifyRecordIdentity
327
- } from "./chunk-EZGV6F47.js";
335
+ } from "./chunk-WRLWEYHY.js";
328
336
  import {
329
337
  validateSchemaInput
330
- } from "./chunk-42ALPZ2B.js";
338
+ } from "./chunk-ZF6JECDT.js";
331
339
  import {
332
340
  SealedHandle
333
- } from "./chunk-SV2PM2OY.js";
341
+ } from "./chunk-XX4R7TUB.js";
334
342
  import {
335
343
  AlreadyElevatedError,
336
344
  AttestationError,
@@ -370,19 +378,19 @@ import {
370
378
  UniqueConstraintError,
371
379
  ValidationError,
372
380
  isConflictError
373
- } from "./chunk-37EPTBBR.js";
381
+ } from "./chunk-IKPQ2GGB.js";
374
382
 
375
383
  // src/kernel/merge-authority.ts
376
384
  function buildMergeAuthority(keyring) {
377
385
  return {
378
386
  verify: async (collection, id, envelope) => {
379
- const dek = keyring.deks.get(dekKey(collection, envelope._tier ?? 0));
387
+ const dek = keyring().deks.get(dekKey(collection, envelope._tier ?? 0));
380
388
  if (dek === void 0) return true;
381
389
  return verifyRecordIdentity({ collection, id }, envelope, dek);
382
390
  },
383
391
  advance: async (collection, id, envelope, toVersion) => {
384
392
  if (!hasSealedBody(envelope)) return { ...envelope, _v: toVersion };
385
- const dek = keyring.deks.get(dekKey(collection, envelope._tier ?? 0));
393
+ const dek = keyring().deks.get(dekKey(collection, envelope._tier ?? 0));
386
394
  if (dek === void 0) {
387
395
  throw new ValidationError(
388
396
  `sync: cannot advance "${collection}/${id}" past the remote \u2014 no key for it, so its body cannot be re-sealed at the new version. The local copy is unchanged.`
@@ -401,24 +409,23 @@ function buildMergeAuthority(keyring) {
401
409
  };
402
410
  }
403
411
 
404
- // src/port/with/formats-strategy.ts
405
- var FormatsNotEnabledError = class extends Error {
406
- constructor(op) {
407
- super(
408
- `vault.${op}() requires the formats service. Import { withFormats } from "@noy-db/hub/as" and pass formatsStrategy: withFormats() to createNoydb().`
409
- );
410
- this.name = "FormatsNotEnabledError";
411
- }
412
- };
413
- var NO_FORMATS = {
414
- enabled: false,
415
- exportWith() {
416
- throw new FormatsNotEnabledError("export");
417
- },
418
- importWith() {
419
- throw new FormatsNotEnabledError("import");
420
- }
421
- };
412
+ // src/kernel/sync-wiring.ts
413
+ function wireEngine(host, name, comp, engine) {
414
+ engine.setCacheInvalidator((collection, id, action) => comp._invalidateSyncApplied(collection, id, action));
415
+ engine.setGraphBatchController({ begin: () => comp._beginGraphBatch(), flush: () => comp._flushGraphBatch() });
416
+ engine.setReservedLookupSource({ collections: () => comp._reservedLookupCollectionNames() });
417
+ engine.setReservedDictExpander((names) => comp._reservedDictDepsOf(names));
418
+ engine.setPeriodPullSource({ periods: () => comp.listPeriods() });
419
+ engine.setRosterReload({ userId: host.user, reload: () => comp._reloadKeyringAfterSync() });
420
+ engine.setAdmission({ admit: (collection, id, envelope, origin) => comp._admitRemote(collection, id, envelope, origin) });
421
+ engine.setRejectionCourier({
422
+ // core#107
423
+ seal: (collection, id, rejection, version) => comp._sealRejection(collection, id, rejection, version),
424
+ open: (collection, id, envelope) => comp._openRejection(collection, id, envelope)
425
+ });
426
+ engine.setCollectionNames(() => [...host.keyringCache.get(name)?.deks.keys() ?? []].filter((n) => !n.startsWith("_")));
427
+ for (const [resolverName, resolver] of host.conflictResolvers.get(name) ?? []) engine.registerConflictResolver(resolverName, resolver);
428
+ }
422
429
 
423
430
  // src/with-commit/tx/strategy.ts
424
431
  var NOT_ENABLED = new Error(
@@ -551,7 +558,7 @@ function validateSecretModeOptions(options) {
551
558
  }
552
559
  async function resolveEffectiveSecret(options, store, vault) {
553
560
  if (options.secretMode === "managed") {
554
- const { resolveManagedSecret } = await import("./managed-secret-MFTFT22X.js");
561
+ const { resolveManagedSecret } = await import("./managed-secret-SQWO2EUR.js");
555
562
  return resolveManagedSecret(store, vault, options.sealingKey);
556
563
  }
557
564
  return options.secret;
@@ -569,7 +576,7 @@ function ownerKeyringOptions(options, secret) {
569
576
 
570
577
  // src/port/by/default-provider.ts
571
578
  async function createDefaultMesh(store) {
572
- const { StoreMesh } = await import("./store-coordination-provider-C4BPT5XF.js");
579
+ const { StoreMesh } = await import("./store-coordination-provider-2KSHCOPU.js");
573
580
  return new StoreMesh(store);
574
581
  }
575
582
 
@@ -624,6 +631,28 @@ function populateCollectionRegistries(r, collectionName, options, effectiveViaFi
624
631
  }
625
632
  }
626
633
 
634
+ // src/kernel/export-scope.ts
635
+ async function resolveExportSource(adapter, vault, opts) {
636
+ const scope = opts.collections ? [...new Set(opts.collections)].filter((n) => !n.startsWith("_")).sort() : null;
637
+ if (scope) {
638
+ return {
639
+ collections: scope,
640
+ scoped: true,
641
+ // One `list` per requested collection. Calling `loadAll` here would pull
642
+ // every collection's envelopes out of the store before declining to
643
+ // decrypt most of them — the fetch would already have happened, which is
644
+ // precisely the half that makes "scoping" a word rather than a property.
645
+ ids: async (collection) => await adapter.list(vault, collection)
646
+ };
647
+ }
648
+ const snapshot = await adapter.loadAll(vault);
649
+ return {
650
+ collections: Object.keys(snapshot).sort(),
651
+ scoped: false,
652
+ ids: async (collection) => Object.keys(snapshot[collection] ?? {})
653
+ };
654
+ }
655
+
627
656
  // src/kernel/generation-map.ts
628
657
  var tick = 0;
629
658
  var GenerationMap = class extends Map {
@@ -1723,7 +1752,7 @@ async function commitSequentially(ctx, entries, priors) {
1723
1752
  }
1724
1753
 
1725
1754
  // src/with-formula/computed/lazy.ts
1726
- var loadComputed = lazy(() => import("./computed-FAD7SED4.js"));
1755
+ var loadComputed = lazy(() => import("./computed-WN6V53ZV.js"));
1727
1756
  async function loadEvalComputedFields() {
1728
1757
  return (await loadComputed()).evalComputedFields;
1729
1758
  }
@@ -2532,7 +2561,7 @@ var Collection = class {
2532
2561
  }
2533
2562
  await this.onAccess?.("find", "*");
2534
2563
  if (hits.length === 0) return [];
2535
- const { verifyDigestField } = await import("./verify-UKALW7C2.js");
2564
+ const { verifyDigestField } = await import("./verify-PCFS4PNS.js");
2536
2565
  const policy = {
2537
2566
  normalize: spec.verifyNormalize ?? "password",
2538
2567
  notLastN: spec.notLastN ?? 0,
@@ -2744,7 +2773,7 @@ var Collection = class {
2744
2773
  }
2745
2774
  }
2746
2775
  if (this.materializedViewSource !== void 0) {
2747
- const { resolveStaleMVOnRead } = await import("./stale-6GCFMOOR.js");
2776
+ const { resolveStaleMVOnRead } = await import("./stale-PIJPAL5T.js");
2748
2777
  await resolveStaleMVOnRead(this.materializedViewSource, this.name, this.#dispatchCtx({ collection: this.name, id: "resolve-on-read" }));
2749
2778
  }
2750
2779
  let record;
@@ -2943,6 +2972,85 @@ var Collection = class {
2943
2972
  #hooksActive() {
2944
2973
  return this.writeHooks !== void 0 && this.writeHooks.hasHandlers && !this.writeHooks.suppressed;
2945
2974
  }
2975
+ /**
2976
+ * core#74 — ADMISSION of a record arriving by sync. Runs the same
2977
+ * `beforePut` gate bus (guards, periods) and `db.onBeforeWrite` hooks a
2978
+ * local `put` runs, on the DECRYPTED incoming record against this device's
2979
+ * current state, with `origin: 'sync-apply'`. A throw is a refusal; the
2980
+ * engine parks the envelope and leaves the local copy untouched.
2981
+ *
2982
+ * Not gated, deliberately: tombstones and delete markers (erasure wins, as
2983
+ * on every other path), elevated envelopes (#707 — invisible to gate
2984
+ * handlers), and a record this session holds no key for (it cannot judge;
2985
+ * the merge authority's stated residue, #1042). Schema validation does not
2986
+ * run — the writer validated. Zero cost when nothing is registered.
2987
+ * @internal
2988
+ */
2989
+ /**
2990
+ * @internal core#74 — judge a record against THIS device's gates and hooks.
2991
+ *
2992
+ * ⚠️ core#108: under `'push-recheck'` the record is already in the local
2993
+ * store, so `resolveGatePrior` returns the record itself and `existing`
2994
+ * equals `incoming` — the state it was written over is gone and cannot be
2995
+ * reconstructed. That makes the re-check sound for rules that read AMBIENT
2996
+ * state (a closed period, a revoked clearance) and degenerate for rules
2997
+ * that compare against a prior, which see a no-op diff and pass. Widening
2998
+ * it would need the pre-write snapshot kept in the dirty log, which is a
2999
+ * different feature; do not "fix" it by synthesising a prior here.
3000
+ */
3001
+ async _admitRemote(id, envelope, origin = "sync-apply") {
3002
+ const gates = this.subsystemBus?.hasGateHandlers("beforePut") ?? false;
3003
+ const hooks = this.#hooksActive();
3004
+ if (!gates && !hooks) return { admitted: true };
3005
+ if ((envelope._tier ?? 0) > 0) return { admitted: true };
3006
+ let incoming;
3007
+ try {
3008
+ incoming = await this.codec.decryptRecord({ collection: this.name, id }, envelope, { skipValidation: true });
3009
+ } catch {
3010
+ return { admitted: true };
3011
+ }
3012
+ try {
3013
+ const selfIsPrior = origin === "push-recheck" && envelope._v === 1;
3014
+ if (gates) {
3015
+ const { env: existingEnv, record: existingRecord } = await this.resolveGatePrior("beforePut", id);
3016
+ const gateEvent = {
3017
+ op: existingEnv && !selfIsPrior ? "update" : "create",
3018
+ vault: this.vault,
3019
+ collection: this.name,
3020
+ docId: id,
3021
+ incoming,
3022
+ existing: selfIsPrior ? null : this.via ? this.via.canonicalizeStored(existingRecord) : existingRecord,
3023
+ existingVersion: selfIsPrior ? 0 : existingEnv?._v ?? 0,
3024
+ existingTs: selfIsPrior ? void 0 : existingEnv?._ts,
3025
+ origin,
3026
+ userId: envelope._by ?? this.keyring.userId,
3027
+ role: this.keyring.role,
3028
+ ...this.computed !== void 0 ? { computedFieldNames: new Set(Object.keys(this.computed)) } : {}
3029
+ };
3030
+ await this.subsystemBus.dispatchGate("beforePut", gateEvent);
3031
+ }
3032
+ if (hooks) {
3033
+ const prior = await this.#priorForHook(id);
3034
+ await this.writeHooks.runBefore({
3035
+ op: prior.record === null || selfIsPrior ? "create" : "update",
3036
+ vault: this.vault,
3037
+ collection: this.name,
3038
+ docId: id,
3039
+ before: selfIsPrior ? null : prior.record,
3040
+ after: incoming,
3041
+ userId: envelope._by ?? this.keyring.userId,
3042
+ timestamp: Date.now(),
3043
+ txId: generateULID(),
3044
+ baseVersion: prior.version,
3045
+ version: envelope._v,
3046
+ origin
3047
+ });
3048
+ }
3049
+ } catch (err) {
3050
+ return { admitted: false, reason: err instanceof Error ? err.message : String(err) };
3051
+ }
3052
+ return { admitted: true };
3053
+ }
2946
3054
  /**
2947
3055
  * @internal — resolve the prior record for a hook's `before` and
2948
3056
  * its version. Critically, this uses the SAME basis `_putInternal` writes from
@@ -3284,9 +3392,9 @@ var Collection = class {
3284
3392
  * @internal `wave` (#638 Task 4): when present (the sync/cutover/restore dispatch wave),
3285
3393
  * an eager MV already refreshed this wave is skipped (per-target dedup, keyed on spec name).
3286
3394
  */
3287
- async dispatchMaterializedViews(id, record, wave) {
3395
+ async _dispatchMaterializedViews(id, record, wave) {
3288
3396
  if (this.materializedViewSource === void 0) return;
3289
- const { dispatchMaterializedViews } = await import("./dispatch-H4HV32AM.js");
3397
+ const { dispatchMaterializedViews } = await import("./dispatch-SHKTG57L.js");
3290
3398
  return dispatchMaterializedViews(this.#mvDispatchCtx(this.materializedViewSource), id, record, wave);
3291
3399
  }
3292
3400
  /**
@@ -3429,7 +3537,7 @@ var Collection = class {
3429
3537
  * and from `forgetDerivedFanout` (#638 Task 6), which needs the per-target outcome to fill
3430
3538
  * `ForgetResult.derivedAggregatesRecomputed`/`derivedResidueFrozen`). `wave` (#640): per-target dedup for the sync-apply path; `undefined` on local-delete (byte-identical).
3431
3539
  */
3432
- async dispatchRollupsOnDelete(id, deleted, wave) {
3540
+ async _dispatchRollupsOnDelete(id, deleted, wave) {
3433
3541
  const results = [];
3434
3542
  for (const intent of this._rollupDeleteIntents(deleted)) {
3435
3543
  const spec = findRollupSpecForIntent(this.derivationSource?.registry(), this.name, intent);
@@ -3450,20 +3558,21 @@ var Collection = class {
3450
3558
  }
3451
3559
  /** @internal `wave` (#638 Task 4) — threaded to `recomputeRollup` for the sync/cutover/restore
3452
3560
  * dispatch wave's per-target dedup; `undefined` on the local-write path (byte-identical). */
3453
- async dispatchDerivations(id, record, version, wave, prior) {
3561
+ async _dispatchDerivations(id, record, version, wave, prior) {
3454
3562
  if (this.derivationSource === void 0) return;
3455
- const { dispatchDerivations } = await import("./dispatch-JDZNGEB3.js");
3563
+ const { dispatchDerivations } = await import("./dispatch-LOQQD5JK.js");
3456
3564
  return dispatchDerivations(this.#derivationDispatchCtx(), id, record, version, wave, prior);
3457
3565
  }
3458
3566
  /** @internal — trigger fan-out for a deleted parent (#1249); see dispatch.ts. */
3459
- async dispatchTriggerDerivationsOnDelete(id, deleted) {
3567
+ async _dispatchTriggerDerivationsOnDelete(id, deleted) {
3460
3568
  if (this.derivationSource === void 0) return;
3461
- const { dispatchTriggerDerivationsOnDelete } = await import("./dispatch-JDZNGEB3.js");
3569
+ const { dispatchTriggerDerivationsOnDelete } = await import("./dispatch-LOQQD5JK.js");
3462
3570
  return dispatchTriggerDerivationsOnDelete(this.#derivationDispatchCtx(), id, deleted);
3463
3571
  }
3464
3572
  /**
3465
3573
  * Delete a record by ID. Runs inside the hub's write-queue tracker
3466
3574
  * so `hub.writeQueue.pending` reflects this write.
3575
+ * ⚠️ Blobs are released (#1451) but a legacy collection defers the erase — a `null` blob read is NOT proof the bytes are gone; see {@link BlobSet.releaseAll} (noy-db/core#28).
3467
3576
  */
3468
3577
  async delete(id) {
3469
3578
  return trackKeyedWrite(this.adapter, this.vault, this.name, id, () => this.#deleteGated(id));
@@ -3705,11 +3814,11 @@ var Collection = class {
3705
3814
  }
3706
3815
  await this._onRecordMutated(id, "delete", "local-delete", { version: marker?._v ?? (existing?.version ?? 0) + 1 });
3707
3816
  if (!internal) {
3708
- await this.dispatchMaterializedViewsOnDelete(id);
3709
- await this.dispatchArrayDerivationsOnDelete(id);
3817
+ await this._dispatchMaterializedViewsOnDelete(id);
3818
+ await this._dispatchArrayDerivationsOnDelete(id);
3710
3819
  if (existing) {
3711
- await this.dispatchRollupsOnDelete(id, existing.record);
3712
- await this.dispatchTriggerDerivationsOnDelete(id, existing.record);
3820
+ await this._dispatchRollupsOnDelete(id, existing.record);
3821
+ await this._dispatchTriggerDerivationsOnDelete(id, existing.record);
3713
3822
  }
3714
3823
  }
3715
3824
  return true;
@@ -3778,9 +3887,9 @@ var Collection = class {
3778
3887
  * erasure too — forget()'s fanout, GDPR residue. A delete-of-absent contributes 0 either way.
3779
3888
  * @internal
3780
3889
  */
3781
- async dispatchArrayDerivationsOnDelete(id, eraseRecordShapeToo = false) {
3890
+ async _dispatchArrayDerivationsOnDelete(id, eraseRecordShapeToo = false) {
3782
3891
  if (this.derivationSource === void 0) return 0;
3783
- const { dispatchArrayDerivationsOnDelete } = await import("./dispatch-JDZNGEB3.js");
3892
+ const { dispatchArrayDerivationsOnDelete } = await import("./dispatch-LOQQD5JK.js");
3784
3893
  return dispatchArrayDerivationsOnDelete(this.#derivationDeleteCtx(this.derivationSource), id, eraseRecordShapeToo);
3785
3894
  }
3786
3895
  /**
@@ -3792,9 +3901,9 @@ var Collection = class {
3792
3901
  * manual serves empty until `refreshView()`. `residueUndecodable`/`residueDeclined` (#776/#785) carry `outputCollection:id` entries whose ownership stamp `invalidateMVAtRest` could not decode, resp. decoded+stamp-matched but declined erasure — surfaced, not erased.
3793
3902
  * @internal
3794
3903
  */
3795
- async dispatchMaterializedViewsOnDelete(id) {
3904
+ async _dispatchMaterializedViewsOnDelete(id) {
3796
3905
  if (this.materializedViewSource === void 0) return { deleted: 0, residueUndecodable: [], residueDeclined: [] };
3797
- const { dispatchMaterializedViewsOnDelete } = await import("./dispatch-H4HV32AM.js");
3906
+ const { dispatchMaterializedViewsOnDelete } = await import("./dispatch-SHKTG57L.js");
3798
3907
  return dispatchMaterializedViewsOnDelete(this.#mvDispatchCtx(this.materializedViewSource), id);
3799
3908
  }
3800
3909
  /**
@@ -3814,7 +3923,7 @@ var Collection = class {
3814
3923
  );
3815
3924
  }
3816
3925
  if (this.materializedViewSource !== void 0) {
3817
- const { resolveStaleMVOnRead } = await import("./stale-6GCFMOOR.js");
3926
+ const { resolveStaleMVOnRead } = await import("./stale-PIJPAL5T.js");
3818
3927
  await resolveStaleMVOnRead(this.materializedViewSource, this.name, this.#dispatchCtx({ collection: this.name, id: "resolve-on-read" }));
3819
3928
  }
3820
3929
  await this.ensureHydrated();
@@ -3822,6 +3931,53 @@ var Collection = class {
3822
3931
  if (!this.via) return records;
3823
3932
  return Promise.all(records.map((r) => this.applyLocaleToRecord(r, locale)));
3824
3933
  }
3934
+ /**
3935
+ * @internal core#122 — forget everything read from the store, so the next
3936
+ * read re-hydrates.
3937
+ *
3938
+ * ⭐ Why this is needed even though the vault drops its collection cache on
3939
+ * restore: `vault.collection(name)` hands back the instance FROM that cache,
3940
+ * so a handle the caller is already holding IS one of the objects in it.
3941
+ * Dropping the map makes the NEXT `vault.collection()` build a fresh
3942
+ * instance and leaves the caller's handle answering from its own pre-restore
3943
+ * cache — correct for the next caller, invisible to the current one, and the
3944
+ * natural shape of restore code holds the handle across the load.
3945
+ *
3946
+ * ⛔ Not a general "refresh": it deliberately does NOT re-read here. The
3947
+ * next read pays for it, so a restore that touches fifty collections does
3948
+ * not hydrate fifty times for a caller who will look at one.
3949
+ */
3950
+ _invalidateAfterRestore() {
3951
+ this.cache.clear();
3952
+ this.markerIds.clear();
3953
+ this.hydrated = false;
3954
+ }
3955
+ /**
3956
+ * core#103 — `list()` with the hub-assigned id alongside each record.
3957
+ *
3958
+ * ⭐ The id is not derivable from a record, so a caller keyed on it
3959
+ * previously had to `get()` per row after `list()`. Tuple order mirrors
3960
+ * `putMany`: `[id, record]` reads the same going in and coming out.
3961
+ *
3962
+ * Same eager-mode requirement and the same locale/Via pipeline as `list()`
3963
+ * — deliberately, so the two cannot drift into answering differently about
3964
+ * the same collection. `list()` is unchanged.
3965
+ */
3966
+ async listEntries(locale) {
3967
+ if (this.lazy) {
3968
+ throw new Error(
3969
+ `Collection "${this.name}": listEntries() is not available in lazy mode (prefetch: false). Use collection.listPageEntries({ limit }) to page through the collection.`
3970
+ );
3971
+ }
3972
+ if (this.materializedViewSource !== void 0) {
3973
+ const { resolveStaleMVOnRead } = await import("./stale-PIJPAL5T.js");
3974
+ await resolveStaleMVOnRead(this.materializedViewSource, this.name, this.#dispatchCtx({ collection: this.name, id: "resolve-on-read" }));
3975
+ }
3976
+ await this.ensureHydrated();
3977
+ const entries = [...this.cache.entries()].map(([id, e]) => [id, e.record]);
3978
+ if (!this.via) return entries;
3979
+ return Promise.all(entries.map(async ([id, r]) => [id, await this.applyLocaleToRecord(r, locale)]));
3980
+ }
3825
3981
  /**
3826
3982
  * Scan-mode full-text search over a plain-text `field`. Decrypts the
3827
3983
  * collection in memory and ranks records by BM25 against the tokenized query.
@@ -4273,6 +4429,21 @@ var Collection = class {
4273
4429
  * developers can spot adapters that should opt into the fast path.
4274
4430
  */
4275
4431
  async listPage(opts = {}) {
4432
+ const page = await this.listPageEntries(opts);
4433
+ return { items: page.items.map(([, record]) => record), nextCursor: page.nextCursor };
4434
+ }
4435
+ /**
4436
+ * core#103 — `listPage()` with the hub-assigned id alongside each record.
4437
+ *
4438
+ * ⭐ The id is not derivable from the record. An app that stores its own key
4439
+ * in a field is fine; one that relies on the id hub assigned had no bulk
4440
+ * read that returned it and had to `get()` per row to find out — which is
4441
+ * the shape pilot-1 hit writing a rule keyed on the record id.
4442
+ *
4443
+ * Tuple order mirrors `putMany`, so `[id, record]` reads the same way going
4444
+ * in and coming out. `listPage()` is unchanged and delegates here.
4445
+ */
4446
+ async listPageEntries(opts = {}) {
4276
4447
  const limit = opts.limit ?? 100;
4277
4448
  if (this.adapter.listPage) {
4278
4449
  const result = await this.adapter.listPage(this.vault, this.name, opts.cursor, limit);
@@ -4281,7 +4452,7 @@ var Collection = class {
4281
4452
  if (!this.lazy && !this.cache.has(id)) {
4282
4453
  this.cache.set(id, { record, version });
4283
4454
  }
4284
- decrypted.push(record);
4455
+ decrypted.push([id, record]);
4285
4456
  }
4286
4457
  return { items: decrypted, nextCursor: result.nextCursor };
4287
4458
  }
@@ -4296,7 +4467,7 @@ var Collection = class {
4296
4467
  if (envelope && (envelope._tier ?? 0) === 0) {
4297
4468
  const record = await this.codec.decryptRecord({ collection: this.name, id }, envelope, { sealedAsHandles: true });
4298
4469
  if (record === null) continue;
4299
- items.push(record);
4470
+ items.push([id, record]);
4300
4471
  if (!this.lazy && !this.cache.has(id)) {
4301
4472
  this.cache.set(id, { record, version: envelope._v });
4302
4473
  }
@@ -4499,8 +4670,8 @@ var Collection = class {
4499
4670
  this.searchIndexStore?.markDirty();
4500
4671
  this.fieldIndexStore?.markDirty();
4501
4672
  await this.onAccess?.("put", id);
4502
- await this.dispatchDerivations(id, record, version, void 0, ctx.prior);
4503
- await this.dispatchMaterializedViews(id, record);
4673
+ await this._dispatchDerivations(id, record, version, void 0, ctx.prior);
4674
+ await this._dispatchMaterializedViews(id, record);
4504
4675
  return;
4505
4676
  }
4506
4677
  case "local-delete": {
@@ -4979,14 +5150,14 @@ var Collection = class {
4979
5150
  /** C-A/R10: persist the classified marker once per classified handle (store I/O in config-drift.ts). */
4980
5151
  async _ensureClassifiedMarker() {
4981
5152
  if (this._markerPersisted || this.vdigFields === null) return;
4982
- const { persistClassifiedMarkerForFields } = await import("./classified-marker-SIYKUU5L.js");
5153
+ const { persistClassifiedMarkerForFields } = await import("./classified-marker-WKP33U2R.js");
4983
5154
  await persistClassifiedMarkerForFields(this.adapter, this.vault, this.name, this.vdigFields, await this.getDEK(this.name));
4984
5155
  this._markerPersisted = true;
4985
5156
  }
4986
5157
  /** C-A/R10 drift signal — the marker's declared digest-only set, memoized to one store read per handle (see config-drift.ts). */
4987
5158
  async _classifiedMarkerDigestOnly() {
4988
5159
  if (this._markerDigestOnlyCache !== void 0) return this._markerDigestOnlyCache;
4989
- const { readClassifiedMarkerDigestOnly } = await import("./classified-marker-SIYKUU5L.js");
5160
+ const { readClassifiedMarkerDigestOnly } = await import("./classified-marker-WKP33U2R.js");
4990
5161
  this._markerDigestOnlyCache = await readClassifiedMarkerDigestOnly(this.adapter, this.vault, this.name, await this.getDEK(this.name));
4991
5162
  return this._markerDigestOnlyCache;
4992
5163
  }
@@ -6654,7 +6825,7 @@ var VaultLinks = class {
6654
6825
  // src/with-shape/links/lazy-handle.ts
6655
6826
  function makeLazyLinkSetHandle(d) {
6656
6827
  let engine = null;
6657
- const load = () => engine ??= import("./link-set-MFXC24VK.js").then(
6828
+ const load = () => engine ??= import("./link-set-4FRRAVTH.js").then(
6658
6829
  ({ LinkSet }) => new LinkSet(d.adapter, d.vault, d.name, d.spec, d.encrypted, d.getDEK, d.actor, d.emitter, d.endpointExists)
6659
6830
  );
6660
6831
  return {
@@ -7037,6 +7208,8 @@ function reconcileCollectionReadState(coll, vaultCtx, plan, hadI18n, hadLookup)
7037
7208
  });
7038
7209
  }
7039
7210
  function reconcileViaAttach(coll, graph, name, vaultCtx, plan) {
7211
+ const allComputed = { ...plan.computed ?? {}, ...plan.effectiveViaFields.computedFields ?? {} };
7212
+ const hasComputed = Object.keys(allComputed).length > 0;
7040
7213
  guardReconcileCollisions(coll._via, {
7041
7214
  moneyFields: plan.effectiveViaFields.moneyFields,
7042
7215
  i18nFields: plan.effectiveViaFields.i18nFields,
@@ -7044,12 +7217,12 @@ function reconcileViaAttach(coll, graph, name, vaultCtx, plan) {
7044
7217
  lookupFields: plan.effectiveViaFields.lookupFields,
7045
7218
  classifiedFields: plan.classifiedFields !== void 0 ? resolveClassifiedFields(name, plan.classifiedFields).byField : void 0,
7046
7219
  blobFields: plan.blobFields,
7047
- computed: { ...plan.computed ?? {}, ...plan.effectiveViaFields.computedFields ?? {} }
7220
+ computed: allComputed
7048
7221
  });
7049
7222
  if (plan.effectiveViaFields.lookupFields !== void 0 && !hasLookupBinding(coll)) {
7050
7223
  refuseUnattachableMatrixLookupFields(vaultCtx, plan.effectiveViaFields.lookupFields);
7051
7224
  }
7052
- const reconcilePlan = plan.computed || plan.classifiedFields ? validateReconcileGraphEdges(graph, name, {
7225
+ const reconcilePlan = hasComputed || plan.classifiedFields ? validateReconcileGraphEdges(graph, name, {
7053
7226
  // `moneyFields` here is the MERGED view (`plan.effectiveViaFields.moneyFields`), not the
7054
7227
  // raw incoming `moneyFields` option — intentional (controller ruling, #664a review): a
7055
7228
  // via()-spelled money field must count in this call's `knownFields` for computed `deps`
@@ -7058,14 +7231,14 @@ function reconcileViaAttach(coll, graph, name, vaultCtx, plan) {
7058
7231
  // silently read the RAW option instead — never intentional, just uncovered before now.
7059
7232
  moneyFields: plan.effectiveViaFields.moneyFields,
7060
7233
  classifiedFields: plan.classifiedFields,
7061
- computed: plan.computed
7234
+ computed: allComputed
7062
7235
  }) : void 0;
7063
7236
  if (plan.refs !== void 0) {
7064
7237
  vaultCtx.refRegistry.register(name, plan.refs);
7065
7238
  coll._attachDeclaredRefs(vaultCtx.refRegistry.getOutbound(name));
7066
7239
  }
7067
7240
  if (plan.effectiveViaFields.moneyFields) coll._applyMoneyFields(plan.effectiveViaFields.moneyFields);
7068
- if (plan.computed) coll._applyComputed(plan.computed);
7241
+ if (hasComputed) coll._applyComputed(allComputed);
7069
7242
  if (plan.fieldMeta) coll._applyFieldMeta(plan.fieldMeta);
7070
7243
  if (plan.meta) coll._applyMeta(plan.meta);
7071
7244
  if (plan.classifiedFields) coll._applyClassifiedFields(plan.classifiedFields);
@@ -7305,7 +7478,7 @@ function declareSatellite(ctx, collectionName, options, existingRegistry) {
7305
7478
  ctx.forEachSyncEngine((e) => e.remirrorPairResolvers([spec.base, spec.satellite]));
7306
7479
  const registry = reg;
7307
7480
  const baseSchema = ctx.getBaseSchema(spec.base);
7308
- void import("./post-register-7ND27CF2.js").then((m) => m.postRegister(ctx.adapter, ctx.vaultName, spec, ctx.getDEK, baseSchema, registry)).catch(() => {
7481
+ void import("./post-register-GRVQHBOH.js").then((m) => m.postRegister(ctx.adapter, ctx.vaultName, spec, ctx.getDEK, baseSchema, registry)).catch(() => {
7309
7482
  });
7310
7483
  return reg;
7311
7484
  }
@@ -7946,6 +8119,7 @@ var Vault = class {
7946
8119
  * `load()` after the on-disk keyring file has been replaced. Provided by Noydb at openVault()
7947
8120
  * time; `undefined` in tests that construct Vault directly (load() then skips the refresh). */
7948
8121
  reloadKeyring;
8122
+ onRestore;
7949
8123
  collectionCache = /* @__PURE__ */ new Map();
7950
8124
  satelliteRegistry = null;
7951
8125
  // spec #591, archetype-③
@@ -8051,7 +8225,7 @@ var Vault = class {
8051
8225
  /** — currently-active elevation, or null. One per vault. */
8052
8226
  activeElevation = null;
8053
8227
  /**
8054
- * Optional translator callback threaded from `Noydb.invokeTranslator`.
8228
+ * Optional translator callback threaded from `Noydb._invokeTranslator`.
8055
8229
  * Present only when `plaintextTranslator` was configured on `createNoydb()`.
8056
8230
  */
8057
8231
  translateText;
@@ -8108,6 +8282,7 @@ var Vault = class {
8108
8282
  void opts.guardStrategies;
8109
8283
  this.historyConfig = opts.historyConfig ?? { enabled: true };
8110
8284
  this.reloadKeyring = opts.reloadKeyring;
8285
+ this.onRestore = opts.onRestore;
8111
8286
  this.locale = opts.locale;
8112
8287
  this.vaultMeta = opts.meta;
8113
8288
  this.translateText = opts.plaintextTranslator;
@@ -8135,7 +8310,7 @@ var Vault = class {
8135
8310
  this.custody = new CustodyApi(
8136
8311
  (options, factors) => this.noydb.grantCustodian(this.name, options, factors),
8137
8312
  (options, factors) => this.noydb.revokeCustodian(this.name, options, factors),
8138
- (opts2) => this.noydb.custodyStrategy.liberate(this, opts2)
8313
+ (opts2) => this.noydb._custodyStrategy.liberate(this, opts2)
8139
8314
  );
8140
8315
  }
8141
8316
  /**
@@ -8282,7 +8457,7 @@ var Vault = class {
8282
8457
  const strategies = options.schemaUpdate ?? [];
8283
8458
  const work = (async () => {
8284
8459
  const dek = await this.getDEK(collectionName);
8285
- const { persistSchemaIfNeeded } = await import("./register-DT5HZ2LZ.js");
8460
+ const { persistSchemaIfNeeded } = await import("./register-YJ5YLQ36.js");
8286
8461
  const result = await persistSchemaIfNeeded({
8287
8462
  store: this.adapter,
8288
8463
  vault: this.name,
@@ -8432,7 +8607,7 @@ var Vault = class {
8432
8607
  const work = (async () => {
8433
8608
  try {
8434
8609
  const dek = await this.getDEK(collectionName);
8435
- await (await import("./register-DT5HZ2LZ.js")).persistSchemaIfNeeded({
8610
+ await (await import("./register-YJ5YLQ36.js")).persistSchemaIfNeeded({
8436
8611
  store: this.adapter,
8437
8612
  vault: this.name,
8438
8613
  collectionName,
@@ -8478,7 +8653,7 @@ var Vault = class {
8478
8653
  * writes (unfenced walk — see `with-shape/satellites/migrate-cek.ts`); resumable.
8479
8654
  */
8480
8655
  async migrateSatellitePerRecordKeys(satelliteName) {
8481
- const { migrateSatelliteCek } = await import("./migrate-cek-DZRFFOHW.js");
8656
+ const { migrateSatelliteCek } = await import("./migrate-cek-JWEM4RP6.js");
8482
8657
  return migrateSatelliteCek(satelliteName, this.collection(satelliteName, { perRecordKeys: true }));
8483
8658
  }
8484
8659
  /**
@@ -8530,6 +8705,21 @@ var Vault = class {
8530
8705
  * its already-warmed `LookupHandle._syncCache` (membership/altIndex/snapshot reads never see a
8531
8706
  * stale verdict for a pulled vocabulary edit) and collect the touch into any open graph batch
8532
8707
  * (the sync-apply wave-reachability seam Task 5's ref edges will use). No-op if never warmed. */
8708
+ /** core#74 — admission of a sync-applied record: the collection's own gates and hooks judge it. Reserved names are never gated. @internal */
8709
+ async _admitRemote(collection, id, envelope, origin = "sync-apply") {
8710
+ if (collection.startsWith("_")) return { admitted: true };
8711
+ return this.collection(collection)._admitRemote(id, envelope, origin);
8712
+ }
8713
+ /** @internal core#107 — seal a refusal under the refused record's own collection DEK. `null`: no DEK here. */
8714
+ async _sealRejection(collection, id, rejection, version) {
8715
+ const dek = this.keyring.deks.get(collection);
8716
+ return dek ? sealRejection(collection, id, rejection, dek, version) : null;
8717
+ }
8718
+ /** @internal core#107 — open a replicated refusal. `null` when this device holds no DEK for it. */
8719
+ async _openRejection(collection, id, envelope) {
8720
+ const dek = this.keyring.deks.get(collection);
8721
+ return dek ? openRejection(collection, id, envelope, dek) : null;
8722
+ }
8533
8723
  async _invalidateSyncApplied(collection, id, action) {
8534
8724
  const coll = this.collectionCache.get(collection);
8535
8725
  if (coll) {
@@ -9113,7 +9303,7 @@ var Vault = class {
9113
9303
  */
9114
9304
  // eslint-disable-next-line @typescript-eslint/consistent-type-imports
9115
9305
  async _loadPodSigner() {
9116
- const { loadSigner } = await import("./signer-MHGW3OIL.js");
9306
+ const { loadSigner } = await import("./signer-NYR4I3FO.js");
9117
9307
  return loadSigner(this.adapter, this.name, this.getDEK);
9118
9308
  }
9119
9309
  async writeExportAudit(entry) {
@@ -9329,6 +9519,8 @@ var Vault = class {
9329
9519
  const collections = /* @__PURE__ */ new Set();
9330
9520
  const unmigratedRecords = [];
9331
9521
  const blobResidueCollections = /* @__PURE__ */ new Set();
9522
+ const blobResidueRecords = /* @__PURE__ */ new Set();
9523
+ const blobResidueETags = /* @__PURE__ */ new Set();
9332
9524
  let blobsShredded = 0;
9333
9525
  let blobsRetainedShared = 0;
9334
9526
  let indexPostingsPurged = 0;
@@ -9391,6 +9583,7 @@ var Vault = class {
9391
9583
  await coll.blob(ref2.id).mintShredIntent(live?._tier ?? 0);
9392
9584
  } catch {
9393
9585
  blobResidueCollections.add(ref2.collection);
9586
+ blobResidueRecords.add(`${ref2.collection}:${ref2.id}`);
9394
9587
  }
9395
9588
  }
9396
9589
  let shred;
@@ -9436,11 +9629,18 @@ var Vault = class {
9436
9629
  const r = await this.collection(ref2.collection).blob(ref2.id).shredAllForRecord(live?._tier ?? 0);
9437
9630
  blobsShredded += r.shredded.length;
9438
9631
  blobsRetainedShared += r.retainedShared.length;
9439
- if (r.residue.length > 0) blobResidueCollections.add(ref2.collection);
9632
+ if (r.residue.length > 0) {
9633
+ blobResidueCollections.add(ref2.collection);
9634
+ blobResidueRecords.add(`${ref2.collection}:${ref2.id}`);
9635
+ for (const e of r.residueETags) blobResidueETags.add(e);
9636
+ }
9440
9637
  } else {
9441
9638
  try {
9442
9639
  const [slotIds, verKeys] = await Promise.all([this.adapter.list(this.name, `_blob_slots_${ref2.collection}`), this.adapter.list(this.name, `_blob_versions_${ref2.collection}`)]);
9443
- if (slotIds.includes(ref2.id) || verKeys.some((k) => k.startsWith(`${ref2.id}::`))) blobResidueCollections.add(ref2.collection);
9640
+ if (slotIds.includes(ref2.id) || verKeys.some((k) => k.startsWith(`${ref2.id}::`))) {
9641
+ blobResidueCollections.add(ref2.collection);
9642
+ blobResidueRecords.add(`${ref2.collection}:${ref2.id}`);
9643
+ }
9444
9644
  } catch {
9445
9645
  }
9446
9646
  }
@@ -9489,6 +9689,8 @@ var Vault = class {
9489
9689
  blobsShredded,
9490
9690
  blobsRetainedShared,
9491
9691
  blobResidueCollections: [...blobResidueCollections],
9692
+ blobResidueRecords: [...blobResidueRecords],
9693
+ blobResidueETags: [...blobResidueETags],
9492
9694
  indexPostingsPurged,
9493
9695
  indexResidue,
9494
9696
  sealedFieldsShredded,
@@ -9603,7 +9805,7 @@ var Vault = class {
9603
9805
  async _initGuards(handles) {
9604
9806
  if (handles.length === 0) return;
9605
9807
  const [{ GuardRegistry }, { ReadOnlyVaultFacade }] = await Promise.all([
9606
- import("./registry-BHRZGZHF.js"),
9808
+ import("./registry-XP744FAP.js"),
9607
9809
  import("./read-only-facade-BIGO37U3.js")
9608
9810
  ]);
9609
9811
  const registry = new GuardRegistry();
@@ -9631,7 +9833,7 @@ var Vault = class {
9631
9833
  async _initDerivations(handles) {
9632
9834
  if (handles.length === 0) return;
9633
9835
  const [{ DerivationRegistry }, { ReadOnlyVaultFacade }] = await Promise.all([
9634
- import("./registry-ET6ZFFWA.js"),
9836
+ import("./registry-MJ7MWCSW.js"),
9635
9837
  import("./read-only-facade-BIGO37U3.js")
9636
9838
  ]);
9637
9839
  const registry = new DerivationRegistry();
@@ -9663,7 +9865,7 @@ var Vault = class {
9663
9865
  */
9664
9866
  async _initMaterializedViews(handles) {
9665
9867
  if (handles.length === 0) return;
9666
- const { MaterializedViewRegistry } = await import("./registry-THCPDEOD.js");
9868
+ const { MaterializedViewRegistry } = await import("./registry-MVEKKGWL.js");
9667
9869
  const registry = new MaterializedViewRegistry();
9668
9870
  this.materializedViewRegistry = registry;
9669
9871
  const db = this;
@@ -9688,7 +9890,7 @@ var Vault = class {
9688
9890
  */
9689
9891
  async _initOverlayedViews(handles) {
9690
9892
  if (handles.length === 0) return;
9691
- const { OverlayedViewRegistry } = await import("./registry-HXFGLGTG.js");
9893
+ const { OverlayedViewRegistry } = await import("./registry-ICOHBQFD.js");
9692
9894
  const registry = new OverlayedViewRegistry();
9693
9895
  const mvRegistry = this.materializedViewRegistry;
9694
9896
  const overlayNames = /* @__PURE__ */ new Set();
@@ -9751,14 +9953,14 @@ var Vault = class {
9751
9953
  if (!reg) {
9752
9954
  throw new Error(`refreshView: no MV registered with name "${name}"`);
9753
9955
  }
9754
- const { MaterializedViewExecutor } = await import("./executor-FMPVN6DT.js");
9956
+ const { MaterializedViewExecutor } = await import("./executor-6PQ7WAGV.js");
9755
9957
  const result = await MaterializedViewExecutor.refresh(reg, {
9756
9958
  getCollection: (n) => this.collection(n),
9757
9959
  getActiveTxContext: () => this.noydb._activeTxContextOrNull,
9758
9960
  getQueryContext: () => this,
9759
9961
  dispatchCtx: this._dispatchCtx({ collection: name, id: "refreshView" })
9760
9962
  });
9761
- const { clearMVStaleFully } = await import("./stale-6GCFMOOR.js");
9963
+ const { clearMVStaleFully } = await import("./stale-PIJPAL5T.js");
9762
9964
  await clearMVStaleFully(this.adapter, this.name, registry, name);
9763
9965
  return result;
9764
9966
  }
@@ -9771,7 +9973,7 @@ var Vault = class {
9771
9973
  if (registry === null) return { derived: 0, failed: 0, skippedFrozen: 0 };
9772
9974
  const strategies = registry.strategiesForSource(sourceCollection);
9773
9975
  if (strategies.length === 0) return { derived: 0, failed: 0, skippedFrozen: 0 };
9774
- const { DerivationExecutor } = await import("./executor-OSRZST2U.js");
9976
+ const { DerivationExecutor } = await import("./executor-6ZPQA6HS.js");
9775
9977
  const sourceColl = this.collection(sourceCollection);
9776
9978
  const records = await sourceColl.list();
9777
9979
  const ctx = { vault: this.derivationFacade ?? new (await import("./read-only-facade-BIGO37U3.js")).ReadOnlyVaultFacade(this, "derivation") };
@@ -9798,7 +10000,7 @@ var Vault = class {
9798
10000
  if (!outSpec) continue;
9799
10001
  const outputColl = this.collection(outSpec.collection);
9800
10002
  if (out.kind === "array") {
9801
- const { loadFanoutSidecar, saveFanoutSidecar } = await import("./fanout-sidecar-L7NHPIOC.js");
10003
+ const { loadFanoutSidecar, saveFanoutSidecar } = await import("./fanout-sidecar-NEB6IYV7.js");
9802
10004
  const prior = await loadFanoutSidecar(this.adapter, this.name, spec.source, id, key, this.getDEK, this.encrypted);
9803
10005
  const prevKeys = new Set(prior?.keys ?? []);
9804
10006
  const newKeysList = out.entries.map((e) => e.key);
@@ -10025,31 +10227,27 @@ var Vault = class {
10025
10227
  * collection.
10026
10228
  */
10027
10229
  async delegate(opts) {
10028
- const { issueDelegation, DELEGATIONS_COLLECTION } = await import("./delegation-NANZDG4N.js");
10230
+ const { issueDelegation, DELEGATIONS_COLLECTION: DELEGATIONS_COLLECTION2 } = await import("./delegation-5UWT4JGT.js");
10029
10231
  if (!this.keyring.kek) {
10030
10232
  throw new ValidationError(
10031
10233
  "issueDelegation: keyring.kek is null \u2014 issuing a delegation requires a tier-1 unlock. Re-authenticate at tier 1 (secret) first."
10032
10234
  );
10033
10235
  }
10034
- const targetKek = this.keyring.kek;
10035
- const delegationsDek = await this.getDEK(DELEGATIONS_COLLECTION);
10036
- return issueDelegation(
10037
- this.adapter,
10038
- this.name,
10039
- this.keyring,
10040
- targetKek,
10041
- delegationsDek,
10042
- opts
10043
- );
10236
+ const delegationsDek = await this.getDEK(DELEGATIONS_COLLECTION2);
10237
+ return issueDelegation(this.adapter, this.name, this.keyring, delegationsDek, opts);
10238
+ }
10239
+ /** Merge live delegations addressed to this user into the keyring — core#56's read half, cross-user since core#65. Explicit, never automatic: `with-party/team/delegation.ts` says why. */
10240
+ async refreshDelegations(now) {
10241
+ return this.strategies.tiers.refreshDelegations({ vault: this.name, adapter: this.adapter, keyring: this.keyring }, now);
10044
10242
  }
10045
10243
  /**
10046
10244
  * revoke an issued delegation by id. Safe to call even
10047
10245
  * if the id does not exist.
10048
10246
  */
10049
10247
  async revokeDelegation(id) {
10050
- const { revokeDelegation, DELEGATIONS_COLLECTION } = await import("./delegation-NANZDG4N.js");
10248
+ const { revokeDelegation, DELEGATIONS_COLLECTION: DELEGATIONS_COLLECTION2 } = await import("./delegation-5UWT4JGT.js");
10051
10249
  await revokeDelegation(this.adapter, this.name, id);
10052
- void DELEGATIONS_COLLECTION;
10250
+ await this.onDirty?.(DELEGATIONS_COLLECTION2, id, "delete", 1);
10053
10251
  }
10054
10252
  // ─── Scoped tier elevation ───────────────────────────
10055
10253
  /**
@@ -10304,7 +10502,7 @@ var Vault = class {
10304
10502
  * @see design-history/2026-05-22-schema-dump-design.md
10305
10503
  */
10306
10504
  async dumpSchema(opts = {}) {
10307
- const { dumpVaultSchema } = await import("./walk-4VPK7AS4.js");
10505
+ const { dumpVaultSchema } = await import("./walk-OZCN6LJS.js");
10308
10506
  return dumpVaultSchema(this, opts);
10309
10507
  }
10310
10508
  /**
@@ -10400,7 +10598,7 @@ var Vault = class {
10400
10598
  * separate vault instances now.
10401
10599
  */
10402
10600
  async getPodHandle() {
10403
- const { buildPodHandle } = await import("./pod-handle-A3LET7NO.js");
10601
+ const { buildPodHandle } = await import("./pod-handle-R6Y4MILX.js");
10404
10602
  return buildPodHandle(this.adapter, this.name);
10405
10603
  }
10406
10604
  /**
@@ -10432,7 +10630,7 @@ var Vault = class {
10432
10630
  * both modes round-trip cleanly.
10433
10631
  */
10434
10632
  async dump() {
10435
- const { dumpVault } = await import("./backup-YE2VQ26S.js");
10633
+ const { dumpVault } = await import("./backup-RJBFQSHE.js");
10436
10634
  return dumpVault(this.backupContext());
10437
10635
  }
10438
10636
  /**
@@ -10441,6 +10639,16 @@ var Vault = class {
10441
10639
  * collection-cache clear, ledger-store reset) that `load()` performs on this
10442
10640
  * Vault's private state.
10443
10641
  */
10642
+ /** core#90 — the first `attachSyncTarget()` on a vault opened without one: from here every write is dirty-tracked. Cached collection handles are rebuilt (as after `load()`); re-acquire handles obtained before the attach. */
10643
+ _enableSync(onDirty) {
10644
+ this.onDirty = onDirty;
10645
+ this.collectionCache.clear();
10646
+ }
10647
+ /** core#82 — sync pulled a newer copy of THIS user's keyring file: reload it in place, rebuild the DEK resolver, drop cached collections. */
10648
+ async _reloadKeyringAfterSync() {
10649
+ await this.backupContext().reloadKeyringAndRebuildDEK();
10650
+ this.collectionCache.clear();
10651
+ }
10444
10652
  backupContext() {
10445
10653
  return {
10446
10654
  adapter: this.adapter,
@@ -10454,10 +10662,18 @@ var Vault = class {
10454
10662
  this.getDEK = this.makeGetDEK();
10455
10663
  }
10456
10664
  },
10457
- clearCollectionCache: () => this.collectionCache.clear(),
10665
+ // core#122 — invalidate the instances BEFORE dropping the map. A handle
10666
+ // the caller already holds is one of these objects, so clearing the map
10667
+ // alone fixes the next `vault.collection()` and leaves the caller reading
10668
+ // pre-restore data from the handle they were told to use.
10669
+ clearCollectionCache: () => {
10670
+ for (const c of this.collectionCache.values()) c._invalidateAfterRestore();
10671
+ this.collectionCache.clear();
10672
+ },
10458
10673
  resetLedgerStore: () => {
10459
10674
  this.ledgerStore = null;
10460
10675
  },
10676
+ ...this.onRestore !== void 0 ? { resetSync: this.onRestore } : {},
10461
10677
  exportStream: (opts) => this.exportStream(opts)
10462
10678
  };
10463
10679
  }
@@ -10483,9 +10699,38 @@ var Vault = class {
10483
10699
  * with a console warning and skip the integrity check entirely
10484
10700
  * — there's no chain to verify against.
10485
10701
  */
10486
- async load(backupJson) {
10487
- const { loadVault } = await import("./backup-YE2VQ26S.js");
10488
- return loadVault(this.backupContext(), backupJson);
10702
+ /**
10703
+ * core#76 — restore this vault to its state at `timestamp`, as FORWARD
10704
+ * WRITES. Every record whose state at T differs from its state now is put
10705
+ * back at T's value; every record that exists now and did not exist at T is
10706
+ * deleted.
10707
+ *
10708
+ * ⭐ The writes go through `Collection.put`/`.delete`, so guards, periods,
10709
+ * history and the ledger all see them. The restore is therefore an audited,
10710
+ * reversible event that replicates through ordinary sync — no pod, and none
10711
+ * of the state-replacement machinery core#71/#72 exists to make safe.
10712
+ *
10713
+ * `{ dryRun: true }` returns the same report having written nothing.
10714
+ *
10715
+ * ⚠️ Bounded by history retention, and ⛔ blobs are not restored — see the
10716
+ * module header on `with-commit/history/restore-to.ts`, which states both
10717
+ * limits and why the blob one is not reported rather than reported empty.
10718
+ */
10719
+ async restoreTo(timestamp, options) {
10720
+ const iso = timestamp instanceof Date ? timestamp.toISOString() : timestamp;
10721
+ const { restoreTo } = await import("./restore-to-DVBHAQAA.js");
10722
+ const instant = this.at(iso);
10723
+ return restoreTo({
10724
+ adapter: this.adapter,
10725
+ vault: this.name,
10726
+ instantCollection: (name) => instant.collection(name),
10727
+ liveCollection: (name) => this.collection(name),
10728
+ liveCollectionNames: async () => Object.keys(await this.adapter.loadAll(this.name))
10729
+ }, iso, options);
10730
+ }
10731
+ async load(backupJson, options) {
10732
+ const { loadVault } = await import("./backup-RJBFQSHE.js");
10733
+ return loadVault(this.backupContext(), backupJson, options);
10489
10734
  }
10490
10735
  /**
10491
10736
  * End-to-end backup integrity check. Runs both:
@@ -10516,7 +10761,7 @@ var Vault = class {
10516
10761
  * way to detect tampering of an in-place vault.
10517
10762
  */
10518
10763
  async verifyBackupIntegrity() {
10519
- const { verifyBackupIntegrity } = await import("./backup-YE2VQ26S.js");
10764
+ const { verifyBackupIntegrity } = await import("./backup-RJBFQSHE.js");
10520
10765
  return verifyBackupIntegrity(this.backupContext());
10521
10766
  }
10522
10767
  /**
@@ -10597,8 +10842,7 @@ var Vault = class {
10597
10842
  const granularity = opts.granularity ?? "collection";
10598
10843
  const exportLocale = opts.resolveLabels;
10599
10844
  const localeOpts = exportLocale !== void 0 ? { locale: exportLocale, _layer: "export" } : void 0;
10600
- const snapshot = await this.adapter.loadAll(this.name);
10601
- const collectionNames = Object.keys(snapshot).sort();
10845
+ const source = await resolveExportSource(this.adapter, this.name, opts);
10602
10846
  const ledgerHead = opts.withLedgerHead ? await (async () => {
10603
10847
  const ledger = this.getLedgerOrNull();
10604
10848
  if (!ledger) return void 0;
@@ -10607,7 +10851,7 @@ var Vault = class {
10607
10851
  })() : void 0;
10608
10852
  const dictSnapshotCache = /* @__PURE__ */ new Map();
10609
10853
  if (exportLocale === void 0) {
10610
- for (const collectionName of collectionNames) {
10854
+ for (const collectionName of source.collections) {
10611
10855
  const dictFields = this.dictKeyFieldRegistry.get(collectionName);
10612
10856
  if (dictFields && Object.keys(dictFields).length > 0) {
10613
10857
  const snap = {};
@@ -10623,12 +10867,13 @@ var Vault = class {
10623
10867
  }
10624
10868
  }
10625
10869
  }
10626
- for (const collectionName of collectionNames) {
10870
+ for (const collectionName of source.collections) {
10627
10871
  if (!hasAccess(this.keyring, collectionName)) continue;
10628
10872
  const coll = this.collection(collectionName);
10629
10873
  const schema = coll.getSchema() ?? null;
10630
10874
  const refs = this.refRegistry.getOutbound(collectionName);
10631
- const ids = Object.keys(snapshot[collectionName] ?? {});
10875
+ const ids = await source.ids(collectionName);
10876
+ if (source.scoped && ids.length === 0) continue;
10632
10877
  const dictionaries = dictSnapshotCache.get(collectionName);
10633
10878
  if (granularity === "collection") {
10634
10879
  const records = [];
@@ -10746,7 +10991,7 @@ var Vault = class {
10746
10991
  * is the live validator object, not a serialization of it).
10747
10992
  */
10748
10993
  async exportJSON(opts = {}) {
10749
- const { exportVaultJSON } = await import("./backup-YE2VQ26S.js");
10994
+ const { exportVaultJSON } = await import("./backup-RJBFQSHE.js");
10750
10995
  return exportVaultJSON(this.backupContext(), opts);
10751
10996
  }
10752
10997
  };
@@ -11760,6 +12005,9 @@ var TeamFacade = class {
11760
12005
  if (this.deps.options.periodsStrategy !== void 0) {
11761
12006
  await (await ensureCollectionDEK(this.deps.options.store, vault, keyring))(PERIODS_COLLECTION);
11762
12007
  }
12008
+ if (this.deps.options.tiersStrategy !== void 0) {
12009
+ await (await ensureCollectionDEK(this.deps.options.store, vault, keyring))(DELEGATIONS_COLLECTION);
12010
+ }
11763
12011
  await engine(this.deps.options.store, vault, keyring, options);
11764
12012
  }
11765
12013
  /** Gate + run a `revoke` engine. See `Noydb.revoke` for the public contract. */
@@ -11767,7 +12015,7 @@ var TeamFacade = class {
11767
12015
  this.deps.checkPolicyOperation(vault, "revoke");
11768
12016
  await this.deps.checkGate(vault, "revoke-user", factors);
11769
12017
  const keyring = await this.deps.getKeyringInternal(vault);
11770
- await engine(this.deps.options.store, vault, keyring, options);
12018
+ return engine(this.deps.options.store, vault, keyring, options);
11771
12019
  }
11772
12020
  /** Gate + run a `rotateKeys` engine. See `Noydb.rotate` for the public contract. */
11773
12021
  async runRotate(engine, vault, collections) {
@@ -11898,6 +12146,7 @@ var TeamFacade = class {
11898
12146
  * meta: {
11899
12147
  * credentialId: e.credentialId,
11900
12148
  * wrapIv: e.wrapIv,
12149
+ * rpId: e.rpId,
11901
12150
  * prfUsed: e.prfUsed,
11902
12151
  * beFlag: e.beFlag,
11903
12152
  * requireSingleDevice: e.requireSingleDevice,
@@ -11906,6 +12155,15 @@ var TeamFacade = class {
11906
12155
  * })
11907
12156
  * ```
11908
12157
  *
12158
+ * `meta` is a free-form blob — hub validates `credentialId` and nothing
12159
+ * else, so this example IS the contract for what a slot carries. Record
12160
+ * `rpId` (core#140): the slot rewrap / rotation ceremony falls back to
12161
+ * `meta.rpId` when the caller passes no `options.rpId` and the enrollment
12162
+ * record predates `WebAuthnEnrollment.rpId`. Omitting it does not break
12163
+ * single-hostname deployments — absence correctly reads as "send no RP ID"
12164
+ * — but on a shared registrable domain rotation then works only if every
12165
+ * caller remembers to pass the RP ID by hand.
12166
+ *
11909
12167
  * Returns the WebAuthn `credentialId` (extracted from `meta.credentialId`)
11910
12168
  * for the caller's lookup index (a bootstrap vault, a Cover,
11911
12169
  * a server-side allowlist).
@@ -12347,8 +12605,10 @@ var TeamFacade = class {
12347
12605
  */
12348
12606
  async recoverUser(vault, options, factors) {
12349
12607
  await this.deps.checkGate(vault, "peer-recover-user", factors);
12608
+ await this.deps.refreshRoster(vault, options.userId);
12350
12609
  const callerKeyring = await this.deps.getKeyringInternal(vault);
12351
12610
  await recoverUser(this.deps.options.store, vault, callerKeyring, options);
12611
+ await this.deps.enrolBrokerMember(vault, { userId: options.userId, secret: options.secret });
12352
12612
  if (options.userId === this.deps.options.user) {
12353
12613
  this.deps.keyringCache.delete(vault);
12354
12614
  }
@@ -12557,6 +12817,8 @@ var Noydb = class {
12557
12817
  vaultOpening = /* @__PURE__ */ new Map();
12558
12818
  keyringCache = /* @__PURE__ */ new Map();
12559
12819
  syncEngines = /* @__PURE__ */ new Map();
12820
+ /** core#90 — conflict resolvers registered per vault, replayed onto a target attached after open. */
12821
+ conflictResolvers = /* @__PURE__ */ new Map();
12560
12822
  /**
12561
12823
  * Per-vault active session tier — defaults to `1` after a secret
12562
12824
  * unlock; tier-2 / tier-3 unlocks downgrade it. Used by
@@ -12596,10 +12858,10 @@ var Noydb = class {
12596
12858
  /**
12597
12859
  * Opt-in sovereign-custody (FR-6) strategy — `NO_CUSTODY` (throwing) unless
12598
12860
  * `withCustody()` was passed. Kept as a public accessor because `Vault`
12599
- * routes `vault.custody.liberate` through `this.noydb.custodyStrategy`.
12861
+ * routes `vault.custody.liberate` through `this.noydb._custodyStrategy`.
12600
12862
  * @internal
12601
12863
  */
12602
- get custodyStrategy() {
12864
+ get _custodyStrategy() {
12603
12865
  return this.strategies.custody;
12604
12866
  }
12605
12867
  snapshots;
@@ -12693,6 +12955,8 @@ var Noydb = class {
12693
12955
  checkGate: (vault, gate, factors) => this.checkGate(vault, gate, factors),
12694
12956
  checkPolicyOperation: (vault, op) => this.checkPolicyOperation(vault, op),
12695
12957
  getKeyringInternal: (vault, opts) => this._getKeyringInternal(vault, opts),
12958
+ enrolBrokerMember: (vault, member) => this.#enrolBrokerMember(vault, member),
12959
+ refreshRoster: (vault, userId) => this.#refreshRoster(vault, userId),
12696
12960
  assertRecoveryEnrolled: (vault, policy, opts) => this.assertRecoveryEnrolled(vault, policy, opts),
12697
12961
  openVault: (vault, opts) => this.openVault(vault, opts),
12698
12962
  setSkipNextManagedRecoveryCheck: (value) => {
@@ -12801,9 +13065,9 @@ var Noydb = class {
12801
13065
  }
12802
13066
  const facade = v._getReadOnlyFacade();
12803
13067
  if (!facade) return;
12804
- const ctx = { existing, vault: facade, userId: e.userId, role: e.role };
13068
+ const ctx = { existing, vault: facade, userId: e.userId, role: e.role, ...e.origin !== void 0 ? { origin: e.origin } : {} };
12805
13069
  await registry.runChecks(e.collection, incoming, ctx);
12806
- const { GuardExecutor } = await import("./executor-LBBBRTN5.js");
13070
+ const { GuardExecutor } = await import("./executor-OXRA64TY.js");
12807
13071
  for (const g of guards) {
12808
13072
  await GuardExecutor.checkFrozenFields(g, e.docId, existing, incoming, e.computedFieldNames);
12809
13073
  }
@@ -12827,7 +13091,7 @@ var Noydb = class {
12827
13091
  if (e.internal) return;
12828
13092
  const facade = v._getReadOnlyFacade();
12829
13093
  if (!facade) return;
12830
- const ctx = { existing, vault: facade, userId: e.userId, role: e.role };
13094
+ const ctx = { existing, vault: facade, userId: e.userId, role: e.role, ...e.origin !== void 0 ? { origin: e.origin } : {} };
12831
13095
  await registry.runOnDelete(e.collection, existing ?? {}, ctx);
12832
13096
  });
12833
13097
  }
@@ -12931,11 +13195,13 @@ var Noydb = class {
12931
13195
  if (this.options.encrypt !== false && !this.policyCache.has(name)) {
12932
13196
  await this.bootstrapPolicy(name);
12933
13197
  }
12934
- const mergeAuthority = buildMergeAuthority(keyring);
13198
+ const mergeAuthority = buildMergeAuthority(() => this.keyringCache.get(name) ?? keyring);
12935
13199
  let syncEngine;
12936
13200
  const targets = normalizeSyncTargets(this.options.sync);
13201
+ const primaryTarget = targets.find((t) => t.role === "sync-peer") ?? targets[0];
13202
+ const primaryStore = primaryTarget?.store;
12937
13203
  if (targets.length > 0) {
12938
- const primary = targets.find((t) => t.role === "sync-peer") ?? targets[0];
13204
+ const primary = primaryTarget;
12939
13205
  const declaredPolicy = this.options.syncPolicy ?? primary.policy;
12940
13206
  const effectivePolicy = declaredPolicy ?? INDEXED_STORE_POLICY;
12941
13207
  syncEngine = this.strategies.sync.buildSyncEngine({
@@ -12976,16 +13242,26 @@ var Noydb = class {
12976
13242
  keyring,
12977
13243
  encrypted: this.options.encrypt !== false,
12978
13244
  emitter: this.emitter,
12979
- onDirty: targets.length > 0 ? async (coll, id, action, version) => {
12980
- for (const [key, engine] of this.syncEngines) {
12981
- if (key === name || key.startsWith(`${name}::`)) {
12982
- if (action === "revert") void engine.removeDirty(coll, id);
12983
- else void engine.trackChange(coll, id, action, version);
12984
- }
13245
+ // `onDirty` PRESENCE is Collection's sync-mode flag (delete markers instead of
13246
+ // physical deletes, #1439's memo gate), so it stays gated on a target existing;
13247
+ // the first `attachSyncTarget()` on a target-less vault switches it on (core#90).
13248
+ onDirty: targets.length > 0 ? this.#dirtyFanout(name) : void 0,
13249
+ // Recorded per vault so a target attached later (core#90) is registered too.
13250
+ onRegisterConflictResolver: (resolverName, resolver) => {
13251
+ let m = this.conflictResolvers.get(name);
13252
+ if (!m) {
13253
+ m = /* @__PURE__ */ new Map();
13254
+ this.conflictResolvers.set(name, m);
12985
13255
  }
12986
- } : void 0,
12987
- onRegisterConflictResolver: syncEngine ? (resolverName, resolver) => syncEngine.registerConflictResolver(resolverName, resolver) : void 0,
12988
- syncAdapter: targets.length > 0 ? targets[0].store : void 0,
13256
+ m.set(resolverName, resolver);
13257
+ this._forEachSyncEngine(name, (e) => e.registerConflictResolver(resolverName, resolver));
13258
+ },
13259
+ // core#139 — the SAME selector the record-sync engine uses, not `targets[0]`.
13260
+ // Presence is published to this store and polled back from it, so on
13261
+ // `[{backup}, {sync-peer}]` the positional read sent presence to a
13262
+ // push-only archive target — quietly, since a presence write that nobody
13263
+ // reads back degrades instead of throwing.
13264
+ syncAdapter: primaryStore,
12989
13265
  getPurgeableTargets: () => targets.filter((t) => t.role === "backup" || t.role === "archive").map((t) => ({ store: t.store, role: t.role, ...t.label !== void 0 ? { label: t.label } : {} })),
12990
13266
  historyConfig: this.options.history,
12991
13267
  // #838 — the 21 conditional strategy spreads that used to live here are
@@ -12999,28 +13275,45 @@ var Noydb = class {
12999
13275
  locale: opts?.locale,
13000
13276
  ...opts?.meta !== void 0 ? { meta: opts.meta } : {},
13001
13277
  // Thread the translator hook so Collection.put() can invoke it
13002
- plaintextTranslator: this.options.plaintextTranslator ? (text, from, to, field, collection) => this.invokeTranslator(text, from, to, field, collection) : void 0,
13278
+ plaintextTranslator: this.options.plaintextTranslator ? (text, from, to, field, collection) => this._invokeTranslator(text, from, to, field, collection) : void 0,
13003
13279
  // Refresh callback used by Vault.load() to re-derive
13004
13280
  // the in-memory keyring from a freshly-loaded keyring file.
13005
13281
  // Encrypted compartments need this so post-load decrypts work
13006
13282
  // against the loaded session's wrapped DEKs; plaintext
13007
13283
  // compartments leave it null and load() skips the refresh.
13008
- reloadKeyring: this.options.encrypt !== false && this.options.secret ? async () => {
13009
- this.keyringCache.delete(name);
13010
- const refreshed = await loadKeyring(this.options.store, name, {
13011
- userId: this.options.user,
13012
- secret: this.options.secret
13284
+ // core#71 — a restore resets every engine attached to this vault.
13285
+ onRestore: async () => {
13286
+ const engines = [];
13287
+ this._forEachSyncEngine(name, (e) => {
13288
+ engines.push(e);
13013
13289
  });
13290
+ for (const e of engines) await e.resetAfterRestore();
13291
+ },
13292
+ reloadKeyring: this.options.encrypt !== false ? async () => {
13293
+ const held = this.keyringCache.get(name)?.kek ?? null;
13294
+ const secret = this.options.secret;
13295
+ if (!held && !secret) {
13296
+ throw new ValidationError(
13297
+ `reloadKeyring: vault "${name}" holds no KEK (tier-2 or session open) \u2014 reopen the vault to adopt the roster change.`
13298
+ );
13299
+ }
13300
+ this.keyringCache.delete(name);
13301
+ let refreshed;
13302
+ try {
13303
+ refreshed = await loadKeyring(this.options.store, name, {
13304
+ userId: this.options.user,
13305
+ ...held ? { kek: held } : { secret }
13306
+ });
13307
+ } catch (err) {
13308
+ if (!(err instanceof InvalidKeyError) || !held || !secret) throw err;
13309
+ refreshed = await loadKeyring(this.options.store, name, { userId: this.options.user, secret });
13310
+ }
13014
13311
  this.keyringCache.set(name, refreshed);
13015
13312
  return refreshed;
13016
13313
  } : void 0
13017
13314
  });
13018
13315
  this._forEachSyncEngine(name, (engine) => {
13019
- engine.setCacheInvalidator((collection, id, action) => comp._invalidateSyncApplied(collection, id, action));
13020
- engine.setGraphBatchController({ begin: () => comp._beginGraphBatch(), flush: () => comp._flushGraphBatch() });
13021
- engine.setReservedLookupSource({ collections: () => comp._reservedLookupCollectionNames() });
13022
- engine.setReservedDictExpander((names) => comp._reservedDictDepsOf(names));
13023
- engine.setPeriodPullSource({ periods: () => comp.listPeriods() });
13316
+ wireEngine(this.#wiring, name, comp, engine);
13024
13317
  });
13025
13318
  await comp._initGuards(this.options.guardStrategies ?? []);
13026
13319
  await comp._initDerivations(this.options.derivationStrategies ?? []);
@@ -13053,6 +13346,13 @@ var Noydb = class {
13053
13346
  /**
13054
13347
  * Grant access to a user for a vault.
13055
13348
  *
13349
+ * ⚠️ On an EXISTING user this RE-KEYS them: a new KEK from `secret`,
13350
+ * authenticator slots dropped, the file overwritten. So it needs the
13351
+ * member's CURRENT secret — after `acceptInvite` or `rotateSecret` an
13352
+ * owner never holds it, and a re-grant with a stale one locks the member
13353
+ * out. To change what an existing member may do, use `updateUser`
13354
+ * (core#96); re-grant only to re-key, with a fresh temporary secret.
13355
+ *
13056
13356
  * Gated by `enroll-user`. `STRICT_POLICY` requires a TOTP / email-OTP
13057
13357
  * factor proof so the operator affirmatively re-asserts identity at
13058
13358
  * the moment of grant; `PERSONAL_POLICY` accepts a tier-1 unlock alone.
@@ -13062,7 +13362,29 @@ var Noydb = class {
13062
13362
  * Opt-in (#267): throws {@link TeamNotEnabledError} without `withTeam()`.
13063
13363
  */
13064
13364
  async grant(vault, options, factors) {
13065
- return this.strategies.team.grant(this.team, vault, options, factors);
13365
+ await this.#refreshRoster(vault, options.userId);
13366
+ await this.strategies.team.grant(this.team, vault, options, factors);
13367
+ await this.#enrolBrokerMember(vault, { userId: options.userId, secret: options.secret });
13368
+ }
13369
+ /**
13370
+ * core#96 (pilot-1, finding B) — before an AUTHORITY edit of a member's
13371
+ * keyring, bring that file down from every sync target that supersedes
13372
+ * ours. The roster replicates by epoch ("higher wins"), so an edit made on a
13373
+ * stale local copy would push as the loser and be discarded; refreshing
13374
+ * first makes the edit land on the current file. One GET per target; a
13375
+ * target that cannot be reached fails the edit (fail-closed — the edit
13376
+ * would otherwise be a silent no-op on that target).
13377
+ */
13378
+ async #refreshRoster(vault, userId) {
13379
+ const engines = [];
13380
+ this._forEachSyncEngine(vault, (e) => {
13381
+ engines.push(e);
13382
+ });
13383
+ for (const e of engines) await e.refreshKeyring(userId);
13384
+ }
13385
+ /** core#73 — register a (re-)granted or recovered sub-admin member with the broker host; a no-op without a broker. */
13386
+ async #enrolBrokerMember(vault, member) {
13387
+ await this.strategies.broker.enrolMember({ store: this.options.store, vault, keyring: await this._getKeyringInternal(vault) }, member);
13066
13388
  }
13067
13389
  /**
13068
13390
  * Revoke a user's access to a vault.
@@ -13075,7 +13397,14 @@ var Noydb = class {
13075
13397
  * Opt-in (#267): throws {@link TeamNotEnabledError} without `withTeam()`.
13076
13398
  */
13077
13399
  async revoke(vault, options, factors) {
13078
- return this.strategies.team.revoke(this.team, vault, options, factors);
13400
+ await this.#refreshRoster(vault, options.userId);
13401
+ const { rewritten } = await this.strategies.team.revoke(this.team, vault, options, factors);
13402
+ await this.#trackRewrites(vault, rewritten);
13403
+ await this.options.store.delete(vault, "_users", options.userId);
13404
+ await this.strategies.broker.revokeMember({ store: this.options.store, vault, keyring: await this._getKeyringInternal(vault) }, options.userId);
13405
+ for (const coll of ["_keyring", "_users", "_broker_member"]) {
13406
+ await Promise.all([...this.syncEngines].filter(([k]) => k === vault || k.startsWith(`${vault}::`)).map(([, e]) => e.trackChange(coll, options.userId, "delete", 1)));
13407
+ }
13079
13408
  }
13080
13409
  /**
13081
13410
  * Grant the FR-6 `custodian` role to a user (owner-only custody API).
@@ -13116,24 +13445,39 @@ var Noydb = class {
13116
13445
  await this.checkGate(vault, "revoke-user", factors);
13117
13446
  const keyring = await this._getKeyringInternal(vault);
13118
13447
  if (keyring.role !== "owner") throw new PermissionDeniedError("only the Deed owner can revoke a custodian");
13119
- await engine(this.options.store, vault, keyring, options);
13120
- }
13121
- /**
13122
- * Mutate post-grant identity fields on an existing keyring — `role`,
13123
- * `displayName`, and/or `permissions`. Pure plaintext-header rewrite:
13124
- * no DEK rewrap, no KEK required, no authenticator slots touched.
13125
- * Tier-2 enrollments and recovery codes survive.
13448
+ const { rewritten } = await engine(this.options.store, vault, keyring, options);
13449
+ await this.#trackRewrites(vault, rewritten);
13450
+ }
13451
+ /**
13452
+ * Change what an EXISTING member may do — `role`, `displayName`, and/or
13453
+ * `permissions` — without holding their secret. The member's KEK, salt
13454
+ * and authenticator slots are untouched; tier-2 enrollments and recovery
13455
+ * codes survive.
13456
+ *
13457
+ * core#96 — the keys follow the header. A change that widens access
13458
+ * delivers the DEKs the member lacks through their keyring INBOX
13459
+ * (sealed to a per-member key pair only their KEK opens; drained at
13460
+ * their next tier-1 unlock, or at the next pull of an open session). A
13461
+ * change that narrows access drops the DEKs and rotates those
13462
+ * collections, as a narrowing `grant` does (#1097). A role change
13463
+ * re-registers the member with a configured broker host under a fresh
13464
+ * `_broker_member` key. This is the widening path: `db.grant` on an
13465
+ * existing user RE-KEYS them from `secret`, so it needs their CURRENT
13466
+ * secret — after `acceptInvite` or `rotateSecret` an owner never holds it.
13126
13467
  *
13127
13468
  * Different from `db.revoke + db.grant`:
13128
13469
  *
13129
- * - Same `userId`, same DEK wrappings, same `granted_by`, same
13130
- * `_users/<keyringId>` envelope. Only the specified header
13131
- * fields move. Last-write-wins via the standard keyring put.
13470
+ * - Same `userId`, same KEK, same `granted_by`, same
13471
+ * `_users/<keyringId>` envelope. Last-write-wins via the standard
13472
+ * keyring put.
13132
13473
  * - No cascade on role demotion (admins demoted to operator keep
13133
13474
  * the keyrings they previously granted; the cascade rules are
13134
13475
  * a `db.revoke` concern, not `db.updateUser`).
13135
13476
  * - Tier-2 slots NOT dropped — the wrapping is unaffected.
13136
13477
  *
13478
+ * @throws `MemberInboxMissingError` when a DEK must be delivered to a
13479
+ * member whose keyring predates inboxes — re-grant them once.
13480
+ *
13137
13481
  * Role-elevation guard: BOTH the old and new role must satisfy
13138
13482
  * `db.grant`'s hierarchy. Owner can do anything; admin manages
13139
13483
  * admin/operator/viewer/client laterally; admin cannot promote to
@@ -13154,14 +13498,60 @@ var Noydb = class {
13154
13498
  * }, { factors: [{ kind: 'totp' }] })
13155
13499
  * ```
13156
13500
  *
13501
+ * ## ⚠️ A NARROWING DOES NOT REACH A SESSION THAT IS ALREADY OPEN
13502
+ *
13503
+ * This writes the target's keyring. It cannot reach into a `Noydb` the
13504
+ * target already has open: an eager collection holds the records it
13505
+ * hydrated, and nothing polls the keyring, so that session keeps serving
13506
+ * rows it read while it still had the key. A FRESH open throws
13507
+ * `NoAccessError` correctly (core#101), and so does that session for any
13508
+ * collection it had not already hydrated.
13509
+ *
13510
+ * ⭐ A long-lived admin console — one holding a vault open while changing
13511
+ * somebody's permissions — must RE-OPEN the affected session rather than
13512
+ * expect its next read to start failing.
13513
+ *
13514
+ * ## What the window is, MEASURED — it is narrower than it sounds
13515
+ *
13516
+ * The consumer building that console asked the two questions a security
13517
+ * reviewer asks, and reasoning would have got both wrong in the cautious
13518
+ * direction. Measured on a synced vault, after `updateUser` narrowed the
13519
+ * member away and `rotate()` re-keyed:
13520
+ *
13521
+ * 1. **Records arriving AFTER the narrowing are not readable.** A `pull()`
13522
+ * into the open session brings the new roster, the session reloads its
13523
+ * keyring, and reads then throw `NoAccessError` — including for rows it
13524
+ * had already cached. ⭐ So with sync on, the window CLOSES at the next
13525
+ * pull; it is not open until re-open.
13526
+ * 2. **Writes are refused locally.** `put()` throws `ReadOnlyError` on the
13527
+ * narrowed collection — the record is never encrypted, never queued, and
13528
+ * `push()` carries nothing. Nothing reaches the remote to be judged, so
13529
+ * this does not even rest on the admission gate (core#74).
13530
+ *
13531
+ * ⛔ So it is not a confidentiality hole and not a write hole: no access is
13532
+ * gained, nothing new becomes readable, and nothing can be written. What
13533
+ * survives is a read of rows the session ALREADY HELD, on a device with no
13534
+ * sync or one that has not pulled since.
13535
+ *
13536
+ * ⚠️ Which is still the window that matters when a narrowing is
13537
+ * security-motivated rather than administrative — a departing member, a
13538
+ * suspected device. `rotate()` is the answer there and a console should
13539
+ * REQUIRE it for that case rather than offer it.
13540
+ *
13157
13541
  * @throws `NoAccessError` when no keyring exists for the target.
13158
13542
  * @throws `PermissionDeniedError` when the role hierarchy rejects.
13159
13543
  * @throws `ValidationError` when no field is provided.
13160
13544
  */
13161
13545
  async updateUser(vault, options, factors) {
13162
13546
  await this.checkGate(vault, "update-user", factors);
13547
+ await this.#refreshRoster(vault, options.userId);
13163
13548
  const keyring = await this._getKeyringInternal(vault);
13164
- await updateKeyringIdentity(this.options.store, vault, keyring, options);
13549
+ const { roleChanged, brokerMemberDek } = await updateKeyringIdentity(this.options.store, vault, keyring, options);
13550
+ if (roleChanged) {
13551
+ const ctx = { store: this.options.store, vault, keyring };
13552
+ if (brokerMemberDek) await this.strategies.broker.enrolMember(ctx, { userId: options.userId, dek: brokerMemberDek });
13553
+ else if (await this.options.store.get(vault, "_broker_member", options.userId)) await this.strategies.broker.revokeMember(ctx, options.userId);
13554
+ }
13165
13555
  if (options.userId === this.options.user) {
13166
13556
  this.keyringCache.delete(vault);
13167
13557
  }
@@ -13195,8 +13585,36 @@ var Noydb = class {
13195
13585
  * reaching into internals. See `noy-db rotate` for the CLI wrapper.
13196
13586
  * Opt-in (#267): throws {@link TeamNotEnabledError} without `withTeam()`.
13197
13587
  */
13588
+ /**
13589
+ * core#74 — the records this device's admission gate refused on pull
13590
+ * (`PullResult.rejected`, `sync:rejected`), parked under `_sync_rejected`
13591
+ * with the envelope intact. `list()` them; `readmit()` applies one after all
13592
+ * (bypassing the gate); `discard()` drops the parking record. Per device:
13593
+ * a refusal is local to the device that judged it.
13594
+ */
13595
+ rejected(vault) {
13596
+ const engine = this.syncEngines.get(vault);
13597
+ if (!engine) throw new ValidationError(`rejected: vault "${vault}" has no sync target.`);
13598
+ return engine.rejected();
13599
+ }
13198
13600
  async rotate(vault, collections) {
13199
- return this.strategies.team.rotate(this.team, vault, collections);
13601
+ const result = await this.strategies.team.rotate(this.team, vault, collections);
13602
+ await this.#trackRewrites(vault, result.rewritten);
13603
+ return result;
13604
+ }
13605
+ /**
13606
+ * core#100 — a rotation re-encrypts records through the raw store, which the
13607
+ * sync dirty log cannot see; without this a replica kept the OLD ciphertext
13608
+ * until each record was edited again — a revoked member with store access
13609
+ * read on, and a survivor handed the new DEK read `TamperedError`.
13610
+ */
13611
+ async #trackRewrites(vault, rewritten) {
13612
+ if (rewritten.length === 0) return;
13613
+ const engines = [];
13614
+ this._forEachSyncEngine(vault, (e) => {
13615
+ engines.push(e);
13616
+ });
13617
+ for (const e of engines) for (const r of rewritten) await e.trackChange(r.collection, r.id, "rekey", r.version);
13200
13618
  }
13201
13619
  /**
13202
13620
  * Verify every `_keyring` file in the vault. Read-only (#1121).
@@ -13421,9 +13839,13 @@ var Noydb = class {
13421
13839
  return results;
13422
13840
  }
13423
13841
  /**
13424
- * @internal True once `close()` has been called. Read by outward
13425
- * orchestration frameworks whose entry points can't see the private
13426
- * `closed` field.
13842
+ * True once `close()` has been called.
13843
+ *
13844
+ * ⭐ NOT `@internal`, and core#128 removed that tag rather than `_`-prefixing
13845
+ * this: the doc's own reason — "read by outward orchestration frameworks
13846
+ * whose entry points can't see the private `closed` field" — IS a public
13847
+ * contract. Prefixing it would have broken the readers it exists for. The
13848
+ * tag was the defect, not the name.
13427
13849
  */
13428
13850
  get isClosed() {
13429
13851
  return this.closed;
@@ -13477,6 +13899,24 @@ var Noydb = class {
13477
13899
  if (engine.role !== "sync-peer") return emptyPullResult();
13478
13900
  return engine.pull(options);
13479
13901
  }
13902
+ /** core#82 — replace every local envelope that fails to authenticate with the primary target's healthy copy; see `SyncEngine.realign`. */
13903
+ async realign(vault) {
13904
+ return this.getSyncEngine(vault).realign();
13905
+ }
13906
+ /**
13907
+ * core#72 — make THIS device's vault authoritative on its primary target:
13908
+ * every local record is written unconditionally (re-versioned above the
13909
+ * target's copy where the target moved on), every id the target holds that
13910
+ * the local vault does not gets a delete marker, the reserved collections
13911
+ * are mirrored, and a new restore EPOCH is written on the target. Every
13912
+ * other device's next pull crosses that epoch: its unpushed edits are parked
13913
+ * (`db.rejected(vault)`, reason `restore-epoch`), its dirty log dropped, the
13914
+ * target adopted wholesale. The act of a restore (`vault.load` then this), or
13915
+ * of declaring one replica the truth. Owner/admin, ledgered by the pushes.
13916
+ */
13917
+ async replaceRemote(vault) {
13918
+ return this.getSyncEngine(vault).replaceRemote();
13919
+ }
13480
13920
  /**
13481
13921
  * Bidirectional sync: pull then push for all targets.
13482
13922
  * `sync-peer` targets do pull+push; `backup`/`archive` targets do push-only.
@@ -13553,7 +13993,7 @@ var Noydb = class {
13553
13993
  }
13554
13994
  /**
13555
13995
  * Currently-running multi-record transaction, or `null` outside
13556
- * Phase 2. `Collection.dispatchDerivations` consults this so a
13996
+ * Phase 2. `Collection._dispatchDerivations` consults this so a
13557
13997
  * recursive derived-output write inside `Collection.put` can register
13558
13998
  * its envelope onto `ctx._executed` and roll back with the main
13559
13999
  * staged ops on mid-batch failure.
@@ -13621,9 +14061,9 @@ var Noydb = class {
13621
14061
  const targets = [];
13622
14062
  for (const [key, engine] of this.syncEngines) {
13623
14063
  if (key !== vault && !key.startsWith(`${vault}::`)) continue;
13624
- const { dirty, lastPush, lastPull } = engine.status();
14064
+ const { dirty, lastPush, lastPull, inFlight, epoch } = engine.status();
13625
14065
  const { label, role } = engine;
13626
- targets.push({ label, role, dirty, lastPush, lastPull, caughtUp: dirty === 0 });
14066
+ targets.push({ label, role, dirty, lastPush, lastPull, caughtUp: dirty === 0, ...inFlight ? { inFlight } : {}, ...epoch !== void 0 ? { epoch } : {} });
13627
14067
  }
13628
14068
  return targets;
13629
14069
  }
@@ -13660,6 +14100,43 @@ var Noydb = class {
13660
14100
  }
13661
14101
  return engine;
13662
14102
  }
14103
+ /** Dirty tracking fans out to every engine of the vault; 'revert' (satellite fan-out compensation, spec #591) un-dirties instead. */
14104
+ #dirtyFanout(name) {
14105
+ return async (coll, id, action, version) => {
14106
+ for (const [key, engine] of this.syncEngines) {
14107
+ if (key === name || key.startsWith(`${name}::`)) {
14108
+ if (action === "revert") void engine.removeDirty(coll, id);
14109
+ else void engine.trackChange(coll, id, action, version);
14110
+ }
14111
+ }
14112
+ };
14113
+ }
14114
+ /** core#90 — attach a sync target to an OPEN vault (primary when it had none, else keyed by position); records written before it are sent by `push({ full: true })`. Rationale in `kernel/sync-wiring.ts`. */
14115
+ async attachSyncTarget(vault, target) {
14116
+ const comp = this.vault(vault);
14117
+ const t = normalizeSyncTargets(target)[0];
14118
+ const declared = t.policy ?? this.options.syncPolicy;
14119
+ const keyring = await this._getKeyringInternal(vault);
14120
+ const engine = this.strategies.sync.buildSyncEngine({
14121
+ local: this.options.store,
14122
+ remote: t.store,
14123
+ vault,
14124
+ strategy: this.options.conflict ?? "version",
14125
+ emitter: this.emitter,
14126
+ syncPolicy: declared ?? INDEXED_STORE_POLICY,
14127
+ role: t.role,
14128
+ mergeAuthority: buildMergeAuthority(() => this.keyringCache.get(vault) ?? keyring),
14129
+ ...t.label !== void 0 ? { label: t.label } : {}
14130
+ });
14131
+ const existing = [...this.syncEngines.keys()].filter((k) => k === vault || k.startsWith(`${vault}::`)).length;
14132
+ this.syncEngines.set(existing === 0 ? vault : `${vault}::${existing}`, engine);
14133
+ if (existing === 0) comp._enableSync(this.#dirtyFanout(vault));
14134
+ wireEngine(this.#wiring, vault, comp, engine);
14135
+ if (declared) engine.startScheduler();
14136
+ }
14137
+ get #wiring() {
14138
+ return { user: this.options.user, keyringCache: this.keyringCache, conflictResolvers: this.conflictResolvers };
14139
+ }
13663
14140
  _forEachSyncEngine(vault, fn) {
13664
14141
  for (const [key, engine] of this.syncEngines) if (key === vault || key.startsWith(`${vault}::`)) fn(engine);
13665
14142
  }
@@ -13815,9 +14292,15 @@ var Noydb = class {
13815
14292
  return this.sessionId;
13816
14293
  }
13817
14294
  /**
13818
- * @internal Drain-barrier coordination transport for the schema fence.
13819
- * The default store-backed provider reproduces today's fence behavior; a
13820
- * `by-*` real-time transport is injected via `mesh`.
14295
+ * Drain-barrier coordination transport for the schema fence. The default
14296
+ * store-backed provider reproduces today's fence behavior; a `by-*`
14297
+ * real-time transport is injected via the `mesh` option.
14298
+ *
14299
+ * ⭐ NOT `@internal`, and core#128 removed that tag rather than
14300
+ * `_`-prefixing this. `db.mesh` is documented as a public handle in
14301
+ * `port/by/index.ts` — "a `Noydb` handle (`db.mesh`) without ever naming a
14302
+ * `by-*` pack" — and `createNoydb({ mesh })` is a public option. The tag
14303
+ * contradicted both; prefixing would have broken the documented handle.
13821
14304
  */
13822
14305
  get mesh() {
13823
14306
  return this.meshPort;
@@ -13909,7 +14392,7 @@ var Noydb = class {
13909
14392
  *
13910
14393
  * @internal — not part of the public API surface
13911
14394
  */
13912
- async invokeTranslator(text, from, to, field, collection) {
14395
+ async _invokeTranslator(text, from, to, field, collection) {
13913
14396
  const cacheKey = `${field}\0${collection}\0${from}\0${to}\0${text}`;
13914
14397
  const translatorName = this.options.plaintextTranslatorName ?? "anonymous";
13915
14398
  const cached = this.translatorCache.get(cacheKey);
@@ -14141,6 +14624,7 @@ var Noydb = class {
14141
14624
  this.keyringCache.set(vault, keyring2);
14142
14625
  return keyring2;
14143
14626
  }
14627
+ await this.strategies.sync.bootstrapKeyrings(this.options.store, normalizeSyncTargets(this.options.sync).find((t) => t.role === "sync-peer")?.store, vault);
14144
14628
  await assertKeyringOpenAllowed(this.options.store, vault, this.options.user, opts.create);
14145
14629
  const effectiveSecret = await resolveEffectiveSecret(this.options, this.options.store, vault);
14146
14630
  if (!effectiveSecret) {
@@ -14191,7 +14675,7 @@ async function createNoydb(options) {
14191
14675
  if (!options.store) options = { ...options, store: memoryStore() };
14192
14676
  validateSecretModeOptions(options);
14193
14677
  if (!options.mesh) options = { ...options, mesh: await createDefaultMesh(options.store) };
14194
- if (!options.userApiFactory) options = { ...options, userApiFactory: (await import("./api-OS747DS4.js")).createUserApi };
14678
+ if (!options.userApiFactory) options = { ...options, userApiFactory: (await import("./api-6EFD43KN.js")).createUserApi };
14195
14679
  if (!options.policyFactory) {
14196
14680
  const policyModule = await import("./policy/index.js");
14197
14681
  options = { ...options, policyFactory: policyModule.createNoydbPolicy, policyCheckGateFn: policyModule.checkGate };
@@ -14224,4 +14708,4 @@ export {
14224
14708
  Noydb,
14225
14709
  createNoydb
14226
14710
  };
14227
- //# sourceMappingURL=chunk-MXOQ5JCG.js.map
14711
+ //# sourceMappingURL=chunk-MRCR7ZMC.js.map