@noy-db/hub 0.9.0-pre.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 (460) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/api-6EFD43KN.js +18 -0
  3. package/dist/as/index.js +10 -10
  4. package/dist/at/index.js +8 -8
  5. package/dist/attestation/index.js +18 -18
  6. package/dist/{backup-7RKNZMQO.js → backup-RJBFQSHE.js} +92 -31
  7. package/dist/backup-RJBFQSHE.js.map +1 -0
  8. package/dist/blobs/index.js +12 -12
  9. package/dist/broker/index.js +13 -13
  10. package/dist/by/index.js +2 -2
  11. package/dist/capsule/contract.js +6 -6
  12. package/dist/capsule/enclave-aes/crypto.d.ts +18 -0
  13. package/dist/capsule/enclave-aes/index.d.ts +2 -2
  14. package/dist/capsule/enclave-aes/index.js +14 -8
  15. package/dist/capsule/enclave-aes/index.js.map +1 -1
  16. package/dist/capsule/index.d.ts +1 -1
  17. package/dist/{capsule-57BDK7LG.js → capsule-6LJAVQNM.js} +14 -8
  18. package/dist/cargo/index.js +35 -35
  19. package/dist/{chunk-72XBVN4J.js → chunk-25FXU6WS.js} +2 -2
  20. package/dist/chunk-25FXU6WS.js.map +1 -0
  21. package/dist/{chunk-PCYPXLEX.js → chunk-2DOCDOPL.js} +6 -6
  22. package/dist/{chunk-RIZTZJX6.js → chunk-2LBS62AC.js} +2 -2
  23. package/dist/{chunk-EUD3HQM4.js → chunk-2ST3WA3C.js} +4 -4
  24. package/dist/{chunk-APFFJN5T.js → chunk-3G3GOGZZ.js} +31 -34
  25. package/dist/chunk-3G3GOGZZ.js.map +1 -0
  26. package/dist/{chunk-4UIP3QNW.js → chunk-3YBIVLTC.js} +2 -2
  27. package/dist/{chunk-UNSQZSZP.js → chunk-4CHM2TRS.js} +2 -2
  28. package/dist/{chunk-NYJBYVBG.js → chunk-4CUJLEOA.js} +4 -4
  29. package/dist/{chunk-YFFMPZPY.js → chunk-4TG2ITRW.js} +2 -2
  30. package/dist/{chunk-ZHQJAV6D.js → chunk-5HQFROZS.js} +2 -2
  31. package/dist/{chunk-6Y5E4SJU.js → chunk-5ZVE3N5C.js} +5 -5
  32. package/dist/{chunk-EMAWOGVH.js → chunk-654RE5YC.js} +3 -3
  33. package/dist/{chunk-DHU2AQ6T.js → chunk-66GD7XXU.js} +2 -2
  34. package/dist/{chunk-JZ4EDEIP.js → chunk-72FQ46VW.js} +3 -3
  35. package/dist/{chunk-7BMOS4JQ.js → chunk-7JPA3LIH.js} +11 -11
  36. package/dist/{chunk-QGFEBNHO.js → chunk-7K42TSCY.js} +4 -4
  37. package/dist/{chunk-OJU67C23.js → chunk-7Q6IU3R7.js} +4 -4
  38. package/dist/{chunk-JBMMWYOH.js → chunk-7UHLO4ZN.js} +35 -2
  39. package/dist/chunk-7UHLO4ZN.js.map +1 -0
  40. package/dist/{chunk-GRS2HIV6.js → chunk-ADCXTW7L.js} +2 -2
  41. package/dist/{chunk-BJH77UY2.js → chunk-AGGPT4UE.js} +2 -2
  42. package/dist/{chunk-TZYTMZZY.js → chunk-AKIEBFIJ.js} +10 -10
  43. package/dist/{chunk-DL6BZKP3.js → chunk-B3B6HV5S.js} +2 -2
  44. package/dist/{chunk-5XONHAFD.js → chunk-B6EWMGFX.js} +2 -2
  45. package/dist/{chunk-TFWFPZRU.js → chunk-B7Y2BRQA.js} +11 -11
  46. package/dist/{chunk-TFWFPZRU.js.map → chunk-B7Y2BRQA.js.map} +1 -1
  47. package/dist/{chunk-MRJDLXI3.js → chunk-BFJE2GPP.js} +8 -8
  48. package/dist/{chunk-G46JSSVX.js → chunk-BJRKXNFP.js} +7 -7
  49. package/dist/{chunk-RNACRT5H.js → chunk-BPQ5CRJF.js} +2 -2
  50. package/dist/{chunk-BYHCKX73.js → chunk-BVRJYMFZ.js} +3 -3
  51. package/dist/{chunk-GETUTTZU.js → chunk-C4XV3PSJ.js} +4 -4
  52. package/dist/{chunk-XXNWU5QZ.js → chunk-DFC4WTJW.js} +2 -2
  53. package/dist/{chunk-YQFBH5ZJ.js → chunk-DMIEKD24.js} +3 -3
  54. package/dist/{chunk-2ZFD2UJC.js → chunk-DQAXA2GK.js} +9 -9
  55. package/dist/{chunk-ZVSKSUGI.js → chunk-DWCFGF2K.js} +5 -5
  56. package/dist/{chunk-5HNW4ZTA.js → chunk-E2C6FFSI.js} +6 -6
  57. package/dist/{chunk-2A56DSRI.js → chunk-EQ6C2ZPT.js} +17 -51
  58. package/dist/chunk-EQ6C2ZPT.js.map +1 -0
  59. package/dist/{chunk-G66YXUTY.js → chunk-EZOFTI4K.js} +3 -3
  60. package/dist/{chunk-6QLCS7ET.js → chunk-FMINS2B6.js} +2 -2
  61. package/dist/{chunk-6WS35E6X.js → chunk-FPF5HRBE.js} +2 -2
  62. package/dist/{chunk-7CT6SX4M.js → chunk-FZVCZEVI.js} +3 -3
  63. package/dist/{chunk-BUE7R3B5.js → chunk-GIQJGXV7.js} +2 -2
  64. package/dist/{chunk-GOJQ5DZA.js → chunk-GYZICGRU.js} +4 -4
  65. package/dist/chunk-GYZICGRU.js.map +1 -0
  66. package/dist/{chunk-C53ER7AG.js → chunk-H334G6KU.js} +2 -2
  67. package/dist/{chunk-GCUMOKTN.js → chunk-HE7EAHGS.js} +3 -3
  68. package/dist/{chunk-BU2ABHFW.js → chunk-HKB4HZDU.js} +4 -4
  69. package/dist/{chunk-5UUJE4FP.js → chunk-ICF3TIGY.js} +2 -2
  70. package/dist/{chunk-H3YM66EI.js → chunk-IF2M43G4.js} +2 -2
  71. package/dist/{chunk-VSUQI5Q6.js → chunk-IKPQ2GGB.js} +15 -1
  72. package/dist/chunk-IKPQ2GGB.js.map +1 -0
  73. package/dist/{chunk-Z3ZXVB2Y.js → chunk-IKS2CPAG.js} +12 -12
  74. package/dist/chunk-IKS2CPAG.js.map +1 -0
  75. package/dist/{chunk-IVMFIKNA.js → chunk-IMIQAGR7.js} +6 -6
  76. package/dist/{chunk-226V6XXJ.js → chunk-IQAJ4OR6.js} +6 -6
  77. package/dist/{chunk-ZMVSKYTJ.js → chunk-IUD7WU67.js} +10 -10
  78. package/dist/{chunk-OK57EATL.js → chunk-IVLRPRXM.js} +2 -2
  79. package/dist/{chunk-K673OO6B.js → chunk-JAQHWHUN.js} +4 -4
  80. package/dist/{chunk-MQ7YWBQ5.js → chunk-K4JSTGXT.js} +2 -2
  81. package/dist/{chunk-55P6OBB7.js → chunk-KN4LUMH6.js} +2 -2
  82. package/dist/{chunk-NZULV7LK.js → chunk-KZA3DITX.js} +4 -4
  83. package/dist/{chunk-ECGXA4LT.js → chunk-L2VM64HK.js} +2 -2
  84. package/dist/chunk-L4UL4IAR.js +55 -0
  85. package/dist/chunk-L4UL4IAR.js.map +1 -0
  86. package/dist/{chunk-XITHENBI.js → chunk-LUCQY3OM.js} +7 -7
  87. package/dist/{chunk-XITHENBI.js.map → chunk-LUCQY3OM.js.map} +1 -1
  88. package/dist/{chunk-LGGIFKJP.js → chunk-MAQBYBUX.js} +4 -4
  89. package/dist/{chunk-ABU6A4Z5.js → chunk-MBPZMZVB.js} +2 -2
  90. package/dist/{chunk-WFWFXDNS.js → chunk-MCNNZBG7.js} +2 -2
  91. package/dist/{chunk-NIXRB5BP.js → chunk-MLVPMDOZ.js} +2 -2
  92. package/dist/{chunk-BVF3SXD7.js → chunk-MMCN7TLK.js} +5 -5
  93. package/dist/{chunk-FSQNGPHH.js → chunk-MRCR7ZMC.js} +612 -175
  94. package/dist/chunk-MRCR7ZMC.js.map +1 -0
  95. package/dist/{chunk-PTJY5R3O.js → chunk-NCTN2FW4.js} +2 -2
  96. package/dist/{chunk-UOZOWN73.js → chunk-ND6S2DKC.js} +2 -2
  97. package/dist/{chunk-XKBTJGFP.js → chunk-NTVKHQ3L.js} +2 -2
  98. package/dist/{chunk-UHFGK6YA.js → chunk-NXQEOC3X.js} +3 -3
  99. package/dist/{chunk-UAKY6E4N.js → chunk-O2VQ3K36.js} +2 -2
  100. package/dist/{chunk-JSWKVZCR.js → chunk-OGKMRIIJ.js} +2 -2
  101. package/dist/{chunk-L2F3CFCH.js → chunk-ONZ3B5EW.js} +4 -4
  102. package/dist/{chunk-AJFPAHMW.js → chunk-OOPSMQX5.js} +3 -3
  103. package/dist/{chunk-QDHHHI5Q.js → chunk-OYEBSWLE.js} +5 -5
  104. package/dist/{chunk-ZWF3EWZA.js → chunk-P6FATPXQ.js} +2 -2
  105. package/dist/{chunk-QSHATAXJ.js → chunk-PLTIJDQN.js} +2 -2
  106. package/dist/{chunk-V55JASXO.js → chunk-PR7ILCIH.js} +3 -3
  107. package/dist/{chunk-X2RP4TO5.js → chunk-QE3TLZ6Z.js} +7 -7
  108. package/dist/{chunk-QXJXG7DN.js → chunk-QFW4MYGN.js} +5 -5
  109. package/dist/{chunk-2WJKJZSO.js → chunk-QHG7GQKM.js} +2 -2
  110. package/dist/{chunk-FZXRLNJO.js → chunk-QT5ITL25.js} +3 -3
  111. package/dist/{chunk-SNM7LSYG.js → chunk-R2ZULFXU.js} +4 -4
  112. package/dist/{chunk-SPPOUJLN.js → chunk-RRTQAQ3N.js} +2 -2
  113. package/dist/{chunk-JA25QG5M.js → chunk-RUE6TCES.js} +622 -119
  114. package/dist/chunk-RUE6TCES.js.map +1 -0
  115. package/dist/{chunk-L5A3KR7R.js → chunk-SALY3LIJ.js} +3 -3
  116. package/dist/{chunk-SFCD6OU7.js → chunk-SBAR5JQ6.js} +2 -2
  117. package/dist/{chunk-WHOKGHJ3.js → chunk-SCH2F7R2.js} +7 -7
  118. package/dist/{chunk-JPSL5GIZ.js → chunk-SOOAW6HK.js} +3 -3
  119. package/dist/{chunk-TMIJAR2X.js → chunk-T4VTRKCY.js} +3 -3
  120. package/dist/{chunk-5LMCVBMY.js → chunk-T5EXREMW.js} +5 -5
  121. package/dist/{chunk-YKGJ44Z7.js → chunk-TDJVQTXD.js} +3 -3
  122. package/dist/{chunk-PUBI455O.js → chunk-THQ3BHLM.js} +2 -2
  123. package/dist/{chunk-BMHQHH7Q.js → chunk-TLIFNRU5.js} +2 -2
  124. package/dist/{chunk-PGC35KXE.js → chunk-TRHUNPXP.js} +2 -2
  125. package/dist/{chunk-SWXLZ4HX.js → chunk-UL6MTRMJ.js} +8 -8
  126. package/dist/{delegation-ONLM4JFI.js → chunk-UNL6YGL5.js} +59 -16
  127. package/dist/chunk-UNL6YGL5.js.map +1 -0
  128. package/dist/{chunk-J4KAPKBJ.js → chunk-UORWAG7K.js} +2 -2
  129. package/dist/{chunk-45VHWE4C.js → chunk-V7AKGAXY.js} +271 -69
  130. package/dist/chunk-V7AKGAXY.js.map +1 -0
  131. package/dist/{chunk-XXQ5XIYY.js → chunk-VLQ6KT7F.js} +2 -2
  132. package/dist/{chunk-PT2YCQVK.js → chunk-VP37VUKQ.js} +4 -4
  133. package/dist/{chunk-QGSNJD3B.js → chunk-WBUHHMLN.js} +2 -2
  134. package/dist/{chunk-4J3MNVVX.js → chunk-WRLWEYHY.js} +7 -1
  135. package/dist/{chunk-4J3MNVVX.js.map → chunk-WRLWEYHY.js.map} +1 -1
  136. package/dist/{chunk-PFCTSXHU.js → chunk-X6Z2SIRF.js} +2 -2
  137. package/dist/{chunk-XA34THLF.js → chunk-XLKWF3L4.js} +4 -4
  138. package/dist/{chunk-K7RW7FI4.js → chunk-XPNJH7GN.js} +5 -5
  139. package/dist/{chunk-RDOEOPOI.js → chunk-XPW7T2GN.js} +5 -5
  140. package/dist/{chunk-2ELOCEXE.js → chunk-XX4R7TUB.js} +1 -1
  141. package/dist/chunk-XX4R7TUB.js.map +1 -0
  142. package/dist/{chunk-EA4VDI5D.js → chunk-Y55XHMQB.js} +4 -4
  143. package/dist/{chunk-CB4467G3.js → chunk-YH4OUOSI.js} +33 -7
  144. package/dist/chunk-YH4OUOSI.js.map +1 -0
  145. package/dist/{chunk-BNFNQNEP.js → chunk-YJGKOSQD.js} +2 -2
  146. package/dist/{chunk-3V6LZHUO.js → chunk-Z3STG43F.js} +2 -2
  147. package/dist/{chunk-ZBUAX4EF.js → chunk-ZD7WFMV2.js} +2 -2
  148. package/dist/{chunk-OM3SEDI4.js → chunk-ZF6JECDT.js} +4 -4
  149. package/dist/{chunk-3Y5JLSXS.js → chunk-ZF7KNSLU.js} +2 -2
  150. package/dist/{chunk-B65CC6Z6.js → chunk-ZGKODRGB.js} +2 -2
  151. package/dist/{chunk-D4V5JJAK.js → chunk-ZNEKQFGF.js} +4 -4
  152. package/dist/{chunk-D5A3GCZ4.js → chunk-ZUTUNVFD.js} +3 -3
  153. package/dist/{chunk-G5EDYVSE.js → chunk-ZWMOHANW.js} +5 -5
  154. package/dist/{chunk-CAD7N6HQ.js → chunk-ZZZ4VCY2.js} +10 -10
  155. package/dist/chunk-ZZZ4VCY2.js.map +1 -0
  156. package/dist/classified/index.js +5 -5
  157. package/dist/{classified-marker-KHDOYIJB.js → classified-marker-WKP33U2R.js} +3 -3
  158. package/dist/collection-facade-COSGZKLC.js +41 -0
  159. package/dist/{computed-XMFTHAXV.js → computed-WN6V53ZV.js} +3 -3
  160. package/dist/consent/index.js +8 -8
  161. package/dist/cover/index.js +8 -8
  162. package/dist/custody/index.js +12 -12
  163. package/dist/{dead-filter-CXV5NS67.js → dead-filter-43WL3Y5H.js} +10 -10
  164. package/dist/debug/index.js +7 -7
  165. package/dist/delegation-5UWT4JGT.js +26 -0
  166. package/dist/derivations/index.js +22 -22
  167. package/dist/derive-IL5JNLEE.js +20 -0
  168. package/dist/directory/index.js +9 -9
  169. package/dist/{dispatch-2MQFMEGY.js → dispatch-LOQQD5JK.js} +19 -19
  170. package/dist/{dispatch-OFDA4WQV.js → dispatch-SHKTG57L.js} +5 -5
  171. package/dist/executor-6PQ7WAGV.js +35 -0
  172. package/dist/executor-6ZPQA6HS.js +8 -0
  173. package/dist/executor-OXRA64TY.js +8 -0
  174. package/dist/export-accessible-XG3FKJWW.js +22 -0
  175. package/dist/extract-partition-33747NY5.js +35 -0
  176. package/dist/{fanout-sidecar-BO67PCPO.js → fanout-sidecar-NEB6IYV7.js} +8 -8
  177. package/dist/find-VW543G3J.js +10 -0
  178. package/dist/forget/index.js +8 -8
  179. package/dist/guards/index.js +4 -4
  180. package/dist/history/index.js +15 -13
  181. package/dist/history/index.js.map +1 -1
  182. package/dist/i18n/index.js +13 -13
  183. package/dist/index.d.ts +3 -2
  184. package/dist/index.js +111 -107
  185. package/dist/index.js.map +1 -1
  186. package/dist/indexing/index.js +5 -5
  187. package/dist/introspection/index.js +10 -10
  188. package/dist/issue-4ZPSY44M.js +19 -0
  189. package/dist/kernel/collection.d.ts +85 -6
  190. package/dist/kernel/constants.d.ts +7 -0
  191. package/dist/kernel/errors.d.ts +9 -0
  192. package/dist/kernel/merge-authority.d.ts +5 -1
  193. package/dist/kernel/noydb.d.ts +116 -21
  194. package/dist/kernel/rejection-seal.d.ts +13 -0
  195. package/dist/kernel/sync-wiring.d.ts +55 -0
  196. package/dist/kernel/types.d.ts +370 -8
  197. package/dist/kernel/vault.d.ts +39 -5
  198. package/dist/{ledger-MSJGWKGW.js → ledger-MZ25UFT2.js} +10 -10
  199. package/dist/liberate-OJIP2ZFX.js +25 -0
  200. package/dist/{link-set-QXXSPPHL.js → link-set-4FRRAVTH.js} +10 -10
  201. package/dist/{managed-secret-VSK7ANQI.js → managed-secret-SQWO2EUR.js} +9 -9
  202. package/dist/materialized-views/index.js +25 -25
  203. package/dist/{migrate-cek-GEBFYBDC.js → migrate-cek-JWEM4RP6.js} +2 -2
  204. package/dist/money/index.js +5 -5
  205. package/dist/noydb-U62OVKXB.js +100 -0
  206. package/dist/on/index.js +12 -12
  207. package/dist/overlay-views/index.js +4 -4
  208. package/dist/periods/index.js +11 -11
  209. package/dist/pod/index.js +66 -64
  210. package/dist/{pod-handle-YE7CT66T.js → pod-handle-R6Y4MILX.js} +8 -8
  211. package/dist/policy/index.js +9 -9
  212. package/dist/port/with/admission-authority.d.ts +34 -0
  213. package/dist/port/with/broker-strategy.d.ts +10 -0
  214. package/dist/port/with/rejection-courier.d.ts +37 -0
  215. package/dist/port/with/restore-host.d.ts +33 -0
  216. package/dist/port/with/service-bus.d.ts +18 -0
  217. package/dist/port/with/team-strategy.d.ts +2 -2
  218. package/dist/port/with/write-hooks.d.ts +2 -0
  219. package/dist/portability/index.js +8 -8
  220. package/dist/{post-register-QC5TEAW3.js → post-register-GRVQHBOH.js} +6 -6
  221. package/dist/query/all/index.js +15 -15
  222. package/dist/query/index.js +7 -7
  223. package/dist/query/live/index.js +7 -7
  224. package/dist/query/reduce/index.js +10 -10
  225. package/dist/query/relate/index.js +9 -9
  226. package/dist/reduce/index.js +8 -8
  227. package/dist/register-YJ5YLQ36.js +30 -0
  228. package/dist/registry-ICOHBQFD.js +8 -0
  229. package/dist/registry-MJ7MWCSW.js +35 -0
  230. package/dist/registry-MVEKKGWL.js +23 -0
  231. package/dist/registry-XP744FAP.js +8 -0
  232. package/dist/request-withdrawal-LSU4G6W3.js +28 -0
  233. package/dist/restore-to-DVBHAQAA.js +66 -0
  234. package/dist/restore-to-DVBHAQAA.js.map +1 -0
  235. package/dist/{reveal-YQTRNQFH.js → reveal-AIHOIK2N.js} +7 -7
  236. package/dist/revoke-QUT7WWG3.js +24 -0
  237. package/dist/satellites/index.js +1 -1
  238. package/dist/schema-update/index.js +2 -2
  239. package/dist/sealed-record/index.js +11 -11
  240. package/dist/search/index.js +4 -4
  241. package/dist/{seed-JMQTRKRE.js → seed-GFLA4FCK.js} +33 -18
  242. package/dist/seed-GFLA4FCK.js.map +1 -0
  243. package/dist/sequence/index.js +8 -8
  244. package/dist/session/index.js +8 -8
  245. package/dist/shadow/index.js +2 -2
  246. package/dist/signer-NYR4I3FO.js +23 -0
  247. package/dist/snapshots/index.js +9 -9
  248. package/dist/{stale-SKV33PBU.js → stale-PIJPAL5T.js} +9 -9
  249. package/dist/storage-VH6SPXHC.js +21 -0
  250. package/dist/{store-coordination-provider-Z6HKPOGM.js → store-coordination-provider-2KSHCOPU.js} +9 -9
  251. package/dist/sync/index.js +16 -16
  252. package/dist/sync/index.js.map +1 -1
  253. package/dist/team/index.js +15 -15
  254. package/dist/tiers/index.js +10 -10
  255. package/dist/to/index.js +2 -2
  256. package/dist/transactions/index.js +3 -3
  257. package/dist/util/index.js +1 -1
  258. package/dist/vault-head/index.js +7 -7
  259. package/dist/{verify-KWQIWLGH.js → verify-PCFS4PNS.js} +7 -7
  260. package/dist/walk-OZCN6LJS.js +20 -0
  261. package/dist/with-audit/guards/types.d.ts +2 -0
  262. package/dist/with-audit/tiers/index.d.ts +5 -5
  263. package/dist/with-commit/history/history.d.ts +16 -0
  264. package/dist/with-commit/history/restore-to.d.ts +40 -0
  265. package/dist/with-party/broker/seed.d.ts +4 -0
  266. package/dist/with-party/custody/strategy.d.ts +2 -2
  267. package/dist/with-party/team/delegation.d.ts +41 -11
  268. package/dist/with-party/team/index.d.ts +2 -0
  269. package/dist/with-party/team/keyring.d.ts +132 -3
  270. package/dist/with-party/team/noydb-facade.d.ts +14 -2
  271. package/dist/with-party/team/roster-tag.d.ts +1 -1
  272. package/dist/with-pod/backup.d.ts +9 -17
  273. package/dist/with-sync/active.d.ts +28 -1
  274. package/dist/with-sync/engine.d.ts +59 -2
  275. package/dist/with-sync/index.d.ts +1 -0
  276. package/dist/with-sync/reserved-mirror.d.ts +27 -4
  277. package/dist/with-sync/strategy.d.ts +2 -0
  278. package/dist/withdraw-accessible-MTFP7OIB.js +25 -0
  279. package/dist/withdraw-accessible-MTFP7OIB.js.map +1 -0
  280. package/package.json +3 -3
  281. package/dist/api-MSJXVYQG.js +0 -18
  282. package/dist/backup-7RKNZMQO.js.map +0 -1
  283. package/dist/chunk-2A56DSRI.js.map +0 -1
  284. package/dist/chunk-2ELOCEXE.js.map +0 -1
  285. package/dist/chunk-45VHWE4C.js.map +0 -1
  286. package/dist/chunk-72XBVN4J.js.map +0 -1
  287. package/dist/chunk-APFFJN5T.js.map +0 -1
  288. package/dist/chunk-CAD7N6HQ.js.map +0 -1
  289. package/dist/chunk-CB4467G3.js.map +0 -1
  290. package/dist/chunk-FSQNGPHH.js.map +0 -1
  291. package/dist/chunk-GOJQ5DZA.js.map +0 -1
  292. package/dist/chunk-JA25QG5M.js.map +0 -1
  293. package/dist/chunk-JBMMWYOH.js.map +0 -1
  294. package/dist/chunk-VSUQI5Q6.js.map +0 -1
  295. package/dist/chunk-Z3ZXVB2Y.js.map +0 -1
  296. package/dist/collection-facade-LZIF7GWD.js +0 -41
  297. package/dist/delegation-ONLM4JFI.js.map +0 -1
  298. package/dist/derive-3YSIS36W.js +0 -20
  299. package/dist/executor-E6YDJ7YA.js +0 -8
  300. package/dist/executor-NJX3YQQ4.js +0 -35
  301. package/dist/executor-WWM3DD4P.js +0 -8
  302. package/dist/export-accessible-RLHU5G4W.js +0 -22
  303. package/dist/extract-partition-QII2EDCS.js +0 -35
  304. package/dist/find-6M7GYDUZ.js +0 -10
  305. package/dist/issue-LPEEEMPP.js +0 -19
  306. package/dist/liberate-LEKDYKTC.js +0 -25
  307. package/dist/noydb-F2AUF6KL.js +0 -98
  308. package/dist/register-SN72QALV.js +0 -30
  309. package/dist/registry-253FF7C6.js +0 -35
  310. package/dist/registry-3AZWQTDT.js +0 -23
  311. package/dist/registry-7UEBTHWG.js +0 -8
  312. package/dist/registry-IVJ67NFQ.js +0 -8
  313. package/dist/request-withdrawal-UKVJZKX2.js +0 -28
  314. package/dist/revoke-G2KXJQA5.js +0 -24
  315. package/dist/seed-JMQTRKRE.js.map +0 -1
  316. package/dist/signer-IUIYR3CX.js +0 -23
  317. package/dist/storage-NPBYP2SM.js +0 -21
  318. package/dist/walk-F4OLXI5H.js +0 -20
  319. package/dist/withdraw-accessible-ZKPLZ66E.js +0 -25
  320. /package/dist/{api-MSJXVYQG.js.map → api-6EFD43KN.js.map} +0 -0
  321. /package/dist/{capsule-57BDK7LG.js.map → capsule-6LJAVQNM.js.map} +0 -0
  322. /package/dist/{chunk-PCYPXLEX.js.map → chunk-2DOCDOPL.js.map} +0 -0
  323. /package/dist/{chunk-RIZTZJX6.js.map → chunk-2LBS62AC.js.map} +0 -0
  324. /package/dist/{chunk-EUD3HQM4.js.map → chunk-2ST3WA3C.js.map} +0 -0
  325. /package/dist/{chunk-4UIP3QNW.js.map → chunk-3YBIVLTC.js.map} +0 -0
  326. /package/dist/{chunk-UNSQZSZP.js.map → chunk-4CHM2TRS.js.map} +0 -0
  327. /package/dist/{chunk-NYJBYVBG.js.map → chunk-4CUJLEOA.js.map} +0 -0
  328. /package/dist/{chunk-YFFMPZPY.js.map → chunk-4TG2ITRW.js.map} +0 -0
  329. /package/dist/{chunk-ZHQJAV6D.js.map → chunk-5HQFROZS.js.map} +0 -0
  330. /package/dist/{chunk-6Y5E4SJU.js.map → chunk-5ZVE3N5C.js.map} +0 -0
  331. /package/dist/{chunk-EMAWOGVH.js.map → chunk-654RE5YC.js.map} +0 -0
  332. /package/dist/{chunk-DHU2AQ6T.js.map → chunk-66GD7XXU.js.map} +0 -0
  333. /package/dist/{chunk-JZ4EDEIP.js.map → chunk-72FQ46VW.js.map} +0 -0
  334. /package/dist/{chunk-7BMOS4JQ.js.map → chunk-7JPA3LIH.js.map} +0 -0
  335. /package/dist/{chunk-QGFEBNHO.js.map → chunk-7K42TSCY.js.map} +0 -0
  336. /package/dist/{chunk-OJU67C23.js.map → chunk-7Q6IU3R7.js.map} +0 -0
  337. /package/dist/{chunk-GRS2HIV6.js.map → chunk-ADCXTW7L.js.map} +0 -0
  338. /package/dist/{chunk-BJH77UY2.js.map → chunk-AGGPT4UE.js.map} +0 -0
  339. /package/dist/{chunk-TZYTMZZY.js.map → chunk-AKIEBFIJ.js.map} +0 -0
  340. /package/dist/{chunk-DL6BZKP3.js.map → chunk-B3B6HV5S.js.map} +0 -0
  341. /package/dist/{chunk-5XONHAFD.js.map → chunk-B6EWMGFX.js.map} +0 -0
  342. /package/dist/{chunk-MRJDLXI3.js.map → chunk-BFJE2GPP.js.map} +0 -0
  343. /package/dist/{chunk-G46JSSVX.js.map → chunk-BJRKXNFP.js.map} +0 -0
  344. /package/dist/{chunk-RNACRT5H.js.map → chunk-BPQ5CRJF.js.map} +0 -0
  345. /package/dist/{chunk-BYHCKX73.js.map → chunk-BVRJYMFZ.js.map} +0 -0
  346. /package/dist/{chunk-GETUTTZU.js.map → chunk-C4XV3PSJ.js.map} +0 -0
  347. /package/dist/{chunk-XXNWU5QZ.js.map → chunk-DFC4WTJW.js.map} +0 -0
  348. /package/dist/{chunk-YQFBH5ZJ.js.map → chunk-DMIEKD24.js.map} +0 -0
  349. /package/dist/{chunk-2ZFD2UJC.js.map → chunk-DQAXA2GK.js.map} +0 -0
  350. /package/dist/{chunk-ZVSKSUGI.js.map → chunk-DWCFGF2K.js.map} +0 -0
  351. /package/dist/{chunk-5HNW4ZTA.js.map → chunk-E2C6FFSI.js.map} +0 -0
  352. /package/dist/{chunk-G66YXUTY.js.map → chunk-EZOFTI4K.js.map} +0 -0
  353. /package/dist/{chunk-6QLCS7ET.js.map → chunk-FMINS2B6.js.map} +0 -0
  354. /package/dist/{chunk-6WS35E6X.js.map → chunk-FPF5HRBE.js.map} +0 -0
  355. /package/dist/{chunk-7CT6SX4M.js.map → chunk-FZVCZEVI.js.map} +0 -0
  356. /package/dist/{chunk-BUE7R3B5.js.map → chunk-GIQJGXV7.js.map} +0 -0
  357. /package/dist/{chunk-C53ER7AG.js.map → chunk-H334G6KU.js.map} +0 -0
  358. /package/dist/{chunk-GCUMOKTN.js.map → chunk-HE7EAHGS.js.map} +0 -0
  359. /package/dist/{chunk-BU2ABHFW.js.map → chunk-HKB4HZDU.js.map} +0 -0
  360. /package/dist/{chunk-5UUJE4FP.js.map → chunk-ICF3TIGY.js.map} +0 -0
  361. /package/dist/{chunk-H3YM66EI.js.map → chunk-IF2M43G4.js.map} +0 -0
  362. /package/dist/{chunk-IVMFIKNA.js.map → chunk-IMIQAGR7.js.map} +0 -0
  363. /package/dist/{chunk-226V6XXJ.js.map → chunk-IQAJ4OR6.js.map} +0 -0
  364. /package/dist/{chunk-ZMVSKYTJ.js.map → chunk-IUD7WU67.js.map} +0 -0
  365. /package/dist/{chunk-OK57EATL.js.map → chunk-IVLRPRXM.js.map} +0 -0
  366. /package/dist/{chunk-K673OO6B.js.map → chunk-JAQHWHUN.js.map} +0 -0
  367. /package/dist/{chunk-MQ7YWBQ5.js.map → chunk-K4JSTGXT.js.map} +0 -0
  368. /package/dist/{chunk-55P6OBB7.js.map → chunk-KN4LUMH6.js.map} +0 -0
  369. /package/dist/{chunk-NZULV7LK.js.map → chunk-KZA3DITX.js.map} +0 -0
  370. /package/dist/{chunk-ECGXA4LT.js.map → chunk-L2VM64HK.js.map} +0 -0
  371. /package/dist/{chunk-LGGIFKJP.js.map → chunk-MAQBYBUX.js.map} +0 -0
  372. /package/dist/{chunk-ABU6A4Z5.js.map → chunk-MBPZMZVB.js.map} +0 -0
  373. /package/dist/{chunk-WFWFXDNS.js.map → chunk-MCNNZBG7.js.map} +0 -0
  374. /package/dist/{chunk-NIXRB5BP.js.map → chunk-MLVPMDOZ.js.map} +0 -0
  375. /package/dist/{chunk-BVF3SXD7.js.map → chunk-MMCN7TLK.js.map} +0 -0
  376. /package/dist/{chunk-PTJY5R3O.js.map → chunk-NCTN2FW4.js.map} +0 -0
  377. /package/dist/{chunk-UOZOWN73.js.map → chunk-ND6S2DKC.js.map} +0 -0
  378. /package/dist/{chunk-XKBTJGFP.js.map → chunk-NTVKHQ3L.js.map} +0 -0
  379. /package/dist/{chunk-UHFGK6YA.js.map → chunk-NXQEOC3X.js.map} +0 -0
  380. /package/dist/{chunk-UAKY6E4N.js.map → chunk-O2VQ3K36.js.map} +0 -0
  381. /package/dist/{chunk-JSWKVZCR.js.map → chunk-OGKMRIIJ.js.map} +0 -0
  382. /package/dist/{chunk-L2F3CFCH.js.map → chunk-ONZ3B5EW.js.map} +0 -0
  383. /package/dist/{chunk-AJFPAHMW.js.map → chunk-OOPSMQX5.js.map} +0 -0
  384. /package/dist/{chunk-QDHHHI5Q.js.map → chunk-OYEBSWLE.js.map} +0 -0
  385. /package/dist/{chunk-ZWF3EWZA.js.map → chunk-P6FATPXQ.js.map} +0 -0
  386. /package/dist/{chunk-QSHATAXJ.js.map → chunk-PLTIJDQN.js.map} +0 -0
  387. /package/dist/{chunk-V55JASXO.js.map → chunk-PR7ILCIH.js.map} +0 -0
  388. /package/dist/{chunk-X2RP4TO5.js.map → chunk-QE3TLZ6Z.js.map} +0 -0
  389. /package/dist/{chunk-QXJXG7DN.js.map → chunk-QFW4MYGN.js.map} +0 -0
  390. /package/dist/{chunk-2WJKJZSO.js.map → chunk-QHG7GQKM.js.map} +0 -0
  391. /package/dist/{chunk-FZXRLNJO.js.map → chunk-QT5ITL25.js.map} +0 -0
  392. /package/dist/{chunk-SNM7LSYG.js.map → chunk-R2ZULFXU.js.map} +0 -0
  393. /package/dist/{chunk-SPPOUJLN.js.map → chunk-RRTQAQ3N.js.map} +0 -0
  394. /package/dist/{chunk-L5A3KR7R.js.map → chunk-SALY3LIJ.js.map} +0 -0
  395. /package/dist/{chunk-SFCD6OU7.js.map → chunk-SBAR5JQ6.js.map} +0 -0
  396. /package/dist/{chunk-WHOKGHJ3.js.map → chunk-SCH2F7R2.js.map} +0 -0
  397. /package/dist/{chunk-JPSL5GIZ.js.map → chunk-SOOAW6HK.js.map} +0 -0
  398. /package/dist/{chunk-TMIJAR2X.js.map → chunk-T4VTRKCY.js.map} +0 -0
  399. /package/dist/{chunk-5LMCVBMY.js.map → chunk-T5EXREMW.js.map} +0 -0
  400. /package/dist/{chunk-YKGJ44Z7.js.map → chunk-TDJVQTXD.js.map} +0 -0
  401. /package/dist/{chunk-PUBI455O.js.map → chunk-THQ3BHLM.js.map} +0 -0
  402. /package/dist/{chunk-BMHQHH7Q.js.map → chunk-TLIFNRU5.js.map} +0 -0
  403. /package/dist/{chunk-PGC35KXE.js.map → chunk-TRHUNPXP.js.map} +0 -0
  404. /package/dist/{chunk-SWXLZ4HX.js.map → chunk-UL6MTRMJ.js.map} +0 -0
  405. /package/dist/{chunk-J4KAPKBJ.js.map → chunk-UORWAG7K.js.map} +0 -0
  406. /package/dist/{chunk-XXQ5XIYY.js.map → chunk-VLQ6KT7F.js.map} +0 -0
  407. /package/dist/{chunk-PT2YCQVK.js.map → chunk-VP37VUKQ.js.map} +0 -0
  408. /package/dist/{chunk-QGSNJD3B.js.map → chunk-WBUHHMLN.js.map} +0 -0
  409. /package/dist/{chunk-PFCTSXHU.js.map → chunk-X6Z2SIRF.js.map} +0 -0
  410. /package/dist/{chunk-XA34THLF.js.map → chunk-XLKWF3L4.js.map} +0 -0
  411. /package/dist/{chunk-K7RW7FI4.js.map → chunk-XPNJH7GN.js.map} +0 -0
  412. /package/dist/{chunk-RDOEOPOI.js.map → chunk-XPW7T2GN.js.map} +0 -0
  413. /package/dist/{chunk-EA4VDI5D.js.map → chunk-Y55XHMQB.js.map} +0 -0
  414. /package/dist/{chunk-BNFNQNEP.js.map → chunk-YJGKOSQD.js.map} +0 -0
  415. /package/dist/{chunk-3V6LZHUO.js.map → chunk-Z3STG43F.js.map} +0 -0
  416. /package/dist/{chunk-ZBUAX4EF.js.map → chunk-ZD7WFMV2.js.map} +0 -0
  417. /package/dist/{chunk-OM3SEDI4.js.map → chunk-ZF6JECDT.js.map} +0 -0
  418. /package/dist/{chunk-3Y5JLSXS.js.map → chunk-ZF7KNSLU.js.map} +0 -0
  419. /package/dist/{chunk-B65CC6Z6.js.map → chunk-ZGKODRGB.js.map} +0 -0
  420. /package/dist/{chunk-D4V5JJAK.js.map → chunk-ZNEKQFGF.js.map} +0 -0
  421. /package/dist/{chunk-D5A3GCZ4.js.map → chunk-ZUTUNVFD.js.map} +0 -0
  422. /package/dist/{chunk-G5EDYVSE.js.map → chunk-ZWMOHANW.js.map} +0 -0
  423. /package/dist/{classified-marker-KHDOYIJB.js.map → classified-marker-WKP33U2R.js.map} +0 -0
  424. /package/dist/{collection-facade-LZIF7GWD.js.map → collection-facade-COSGZKLC.js.map} +0 -0
  425. /package/dist/{computed-XMFTHAXV.js.map → computed-WN6V53ZV.js.map} +0 -0
  426. /package/dist/{dead-filter-CXV5NS67.js.map → dead-filter-43WL3Y5H.js.map} +0 -0
  427. /package/dist/{derive-3YSIS36W.js.map → delegation-5UWT4JGT.js.map} +0 -0
  428. /package/dist/{executor-E6YDJ7YA.js.map → derive-IL5JNLEE.js.map} +0 -0
  429. /package/dist/{dispatch-2MQFMEGY.js.map → dispatch-LOQQD5JK.js.map} +0 -0
  430. /package/dist/{dispatch-OFDA4WQV.js.map → dispatch-SHKTG57L.js.map} +0 -0
  431. /package/dist/{executor-NJX3YQQ4.js.map → executor-6PQ7WAGV.js.map} +0 -0
  432. /package/dist/{executor-WWM3DD4P.js.map → executor-6ZPQA6HS.js.map} +0 -0
  433. /package/dist/{export-accessible-RLHU5G4W.js.map → executor-OXRA64TY.js.map} +0 -0
  434. /package/dist/{extract-partition-QII2EDCS.js.map → export-accessible-XG3FKJWW.js.map} +0 -0
  435. /package/dist/{find-6M7GYDUZ.js.map → extract-partition-33747NY5.js.map} +0 -0
  436. /package/dist/{fanout-sidecar-BO67PCPO.js.map → fanout-sidecar-NEB6IYV7.js.map} +0 -0
  437. /package/dist/{issue-LPEEEMPP.js.map → find-VW543G3J.js.map} +0 -0
  438. /package/dist/{ledger-MSJGWKGW.js.map → issue-4ZPSY44M.js.map} +0 -0
  439. /package/dist/{liberate-LEKDYKTC.js.map → ledger-MZ25UFT2.js.map} +0 -0
  440. /package/dist/{link-set-QXXSPPHL.js.map → liberate-OJIP2ZFX.js.map} +0 -0
  441. /package/dist/{managed-secret-VSK7ANQI.js.map → link-set-4FRRAVTH.js.map} +0 -0
  442. /package/dist/{noydb-F2AUF6KL.js.map → managed-secret-SQWO2EUR.js.map} +0 -0
  443. /package/dist/{migrate-cek-GEBFYBDC.js.map → migrate-cek-JWEM4RP6.js.map} +0 -0
  444. /package/dist/{register-SN72QALV.js.map → noydb-U62OVKXB.js.map} +0 -0
  445. /package/dist/{pod-handle-YE7CT66T.js.map → pod-handle-R6Y4MILX.js.map} +0 -0
  446. /package/dist/{post-register-QC5TEAW3.js.map → post-register-GRVQHBOH.js.map} +0 -0
  447. /package/dist/{registry-253FF7C6.js.map → register-YJ5YLQ36.js.map} +0 -0
  448. /package/dist/{registry-3AZWQTDT.js.map → registry-ICOHBQFD.js.map} +0 -0
  449. /package/dist/{registry-7UEBTHWG.js.map → registry-MJ7MWCSW.js.map} +0 -0
  450. /package/dist/{registry-IVJ67NFQ.js.map → registry-MVEKKGWL.js.map} +0 -0
  451. /package/dist/{request-withdrawal-UKVJZKX2.js.map → registry-XP744FAP.js.map} +0 -0
  452. /package/dist/{revoke-G2KXJQA5.js.map → request-withdrawal-LSU4G6W3.js.map} +0 -0
  453. /package/dist/{reveal-YQTRNQFH.js.map → reveal-AIHOIK2N.js.map} +0 -0
  454. /package/dist/{signer-IUIYR3CX.js.map → revoke-QUT7WWG3.js.map} +0 -0
  455. /package/dist/{stale-SKV33PBU.js.map → signer-NYR4I3FO.js.map} +0 -0
  456. /package/dist/{storage-NPBYP2SM.js.map → stale-PIJPAL5T.js.map} +0 -0
  457. /package/dist/{walk-F4OLXI5H.js.map → storage-VH6SPXHC.js.map} +0 -0
  458. /package/dist/{store-coordination-provider-Z6HKPOGM.js.map → store-coordination-provider-2KSHCOPU.js.map} +0 -0
  459. /package/dist/{verify-KWQIWLGH.js.map → verify-PCFS4PNS.js.map} +0 -0
  460. /package/dist/{withdraw-accessible-ZKPLZ66E.js.map → walk-OZCN6LJS.js.map} +0 -0
@@ -99,8 +99,18 @@ export interface LoadKeyringOptions {
99
99
  * That user's secret — a single string for a standard keyring, or the
100
100
  * structured 3-part {@link EchoSecretParts} for an echo keyring (spec
101
101
  * #940, AG-1: a single string can never unlock an echo keyring).
102
+ * One of `secret` / `kek` is required.
102
103
  */
103
- readonly secret: string | EchoSecretParts;
104
+ readonly secret?: string | EchoSecretParts;
105
+ /**
106
+ * core#96 — a KEK this session already HOLDS, instead of re-deriving one
107
+ * from a secret. The in-session roster reload (core#82) uses it: the secret
108
+ * the vault was opened with is stale after an in-session `rotateSecret`,
109
+ * and 600K PBKDF2 iterations are not needed to adopt a file this KEK
110
+ * already opens. A file re-keyed under this member by somebody else fails
111
+ * the canary and reports `InvalidKeyError` — a defined event, not a hang.
112
+ */
113
+ readonly kek?: EnclaveKey;
104
114
  }
105
115
  /**
106
116
  * KDF dispatch for tier-1 unlock (spec #940). An echo keyring accepts
@@ -186,8 +196,18 @@ export interface CreateOwnerKeyringOptions extends SecretPolicy {
186
196
  export declare function createOwnerKeyring(store: NoydbStore, vault: string, opts: CreateOwnerKeyringOptions): Promise<UnlockedKeyring>;
187
197
  /** Grant access to a new user. Caller must have grant privilege. */
188
198
  export declare function grant(store: NoydbStore, vault: string, callerKeyring: UnlockedKeyring, options: GrantOptions): Promise<void>;
199
+ /**
200
+ * Reserved DEK-map slots that are KEYS, not collections, and can never be
201
+ * rotated — `rotateKeys` refuses each by name. Every caller that derives a
202
+ * rotation scope from a DEK map (`revoke`, `quarantineKeyring`) strips these
203
+ * first. ⛔ Kept as ONE set rather than a filter per caller: `quarantineKeyring`
204
+ * stripped only `_roster` and broke the moment the owner keyring gained an
205
+ * inbox key (core#65), which is the second time this list grew and a caller
206
+ * was missed.
207
+ */
208
+ export declare const NON_ROTATABLE_SLOTS: ReadonlySet<string>;
189
209
  /** Revoke a user's access. Optionally rotate keys for affected collections. */
190
- export declare function revoke(store: NoydbStore, vault: string, callerKeyring: UnlockedKeyring, options: RevokeOptions): Promise<void>;
210
+ export declare function revoke(store: NoydbStore, vault: string, callerKeyring: UnlockedKeyring, options: RevokeOptions): Promise<RevokeResult>;
191
211
  /** What {@link verifyRoster} found. */
192
212
  export interface RosterVerifyResult {
193
213
  /**
@@ -306,7 +326,19 @@ export declare function quarantineKeyring(store: NoydbStore, vault: string, call
306
326
  * @throws `ValidationError` when the diff is empty (nothing to update).
307
327
  *
308
328
  */
309
- export declare function updateKeyringIdentity(store: NoydbStore, vault: string, callerKeyring: UnlockedKeyring, options: UpdateUserOptions): Promise<void>;
329
+ /** What `updateKeyringIdentity` hands back to the kernel (core#96). */
330
+ export interface UpdateKeyringResult {
331
+ /** The role moved. The kernel re-registers the member with a broker host, if one is configured. */
332
+ readonly roleChanged: boolean;
333
+ /**
334
+ * A fresh `_broker_member` DEK, delivered through the inbox, when the member
335
+ * is (still) a sub-admin after a role change — the kernel seals the new seed
336
+ * under it and re-enrols. Absent otherwise (a promotion to owner/admin drops
337
+ * the slot: those roles use the shared `_broker` seed).
338
+ */
339
+ readonly brokerMemberDek?: EnclaveKey;
340
+ }
341
+ export declare function updateKeyringIdentity(store: NoydbStore, vault: string, callerKeyring: UnlockedKeyring, options: UpdateUserOptions): Promise<UpdateKeyringResult>;
310
342
  /**
311
343
  * Rotate DEKs for specified collections:
312
344
  * 1. Generate new DEKs
@@ -351,11 +383,38 @@ export interface RotateResult {
351
383
  readonly userId: string;
352
384
  readonly reason: KeyringTamperedReason;
353
385
  }>;
386
+ /**
387
+ * core#100 — every record this rotation re-encrypted, with its version.
388
+ * Rotation writes through the raw store, invisible to the sync dirty log,
389
+ * so a replica kept the OLD ciphertext until each record was edited again —
390
+ * a revoked member with store access went on reading it, and a survivor
391
+ * handed the new DEK read `TamperedError` (measured by pilot-1). The kernel
392
+ * dirty-tracks these on every sync engine so the next push carries them.
393
+ */
394
+ readonly rewritten: ReadonlyArray<{
395
+ readonly collection: string;
396
+ readonly id: string;
397
+ readonly version: number;
398
+ }>;
399
+ }
400
+ /** core#100 — what `revoke` hands the kernel: the rotation's rewrites, for the dirty log. */
401
+ export interface RevokeResult {
402
+ readonly rewritten: RotateResult['rewritten'];
354
403
  }
355
404
  /** Options for {@link rotateKeys} (#846b — was a bare `string[]`). */
356
405
  export interface RotateKeysOptions {
357
406
  /** Collections whose DEKs are re-minted. */
358
407
  readonly collections: readonly string[];
408
+ /**
409
+ * core#100 — members who must NOT be delivered the new keys: the member
410
+ * being revoked or quarantined (a store that suppresses the `_keyring`
411
+ * delete leaves their file in place — #1043 — and delivering to it would
412
+ * hand the revoked member the very key the rotation exists to take away),
413
+ * and a member being narrowed (the collection just left their file, but a
414
+ * pending inbox slot for it cannot be pulled out of its box). They get the
415
+ * drop, and appear in `needsRegrant` as before.
416
+ */
417
+ readonly exclude?: readonly string[];
359
418
  }
360
419
  export declare function rotateKeys(store: NoydbStore, vault: string, callerKeyring: UnlockedKeyring, opts: RotateKeysOptions): Promise<RotateResult>;
361
420
  /** Options for {@link changeSecret} (#846b). */
@@ -507,7 +566,38 @@ export declare function ensureCollectionDEK(store: NoydbStore, vault: string, ke
507
566
  export declare function hasWritePermission(keyring: UnlockedKeyring, collectionName: string): boolean;
508
567
  /** Check if a user has any access to a collection. */
509
568
  export declare function hasAccess(keyring: UnlockedKeyring, collectionName: string): boolean;
569
+ export declare function mintInboxKey(kek: EnclaveKey): Promise<{
570
+ wrappedInboxKey: string;
571
+ inboxKeyAes: EnclaveKey;
572
+ inboxKey: NonNullable<KeyringFile['inbox_key']>;
573
+ }>;
574
+ /** core#96 — the collections a member has pending in their inbox, over every box. */
575
+ export declare function inboxSlots(file: Pick<KeyringFile, 'inbox'>): string[];
576
+ /**
577
+ * core#65 — this member's INBOX KEY PAIR, rebuilt from their keyring file: the
578
+ * private half is sealed under `deks[INBOX_KEY_ID]`, which only their own KEK
579
+ * unwraps. The inbox drain below opens boxes with it; `with-party/team/
580
+ * delegation.ts` opens a delegation's content key with the same pair, so a
581
+ * grantor can hand a member a key without knowing their secret.
582
+ */
583
+ export declare function openInboxKeyPair(inboxKey: NonNullable<KeyringFile['inbox_key']>, inboxKeyAes: EnclaveKey): Promise<CryptoKeyPair>;
510
584
  /** Persist a keyring file to the store. */
585
+ /**
586
+ * ⛔⛔ core#132 — DO NOT ADD A RETRY HERE. An earlier cut of this change did,
587
+ * and it was wrong in a way that looked like a fix.
588
+ *
589
+ * This function writes the caller's in-memory `keyring.deks` WHOLESALE. If a
590
+ * CAS fails, the write that lost was based on a stale version — retrying it
591
+ * re-persists that same map over the winner's, which is exactly the clobber
592
+ * the CAS just caught, laundered into a success. The suite went green and the
593
+ * data loss stayed.
594
+ *
595
+ * ⭐ The resolution belongs where the intent is, not where the write is. The
596
+ * only caller that races in practice is the lazy DEK mint in
597
+ * `ensureCollectionDEK`, and it can resolve correctly because it has not
598
+ * encrypted anything yet: on conflict it adopts the winner's key and returns
599
+ * that. See the comment there.
600
+ */
511
601
  export declare function persistKeyring(store: NoydbStore, vault: string, keyring: UnlockedKeyring): Promise<void>;
512
602
  /**
513
603
  * Check whether a keyring is authorised for a given `@noy-db/as-*`
@@ -559,3 +649,42 @@ export declare function hasImportCapability(keyring: UnlockedKeyring, tier: 'bun
559
649
  */
560
650
  export declare function evaluateImportCapability(capability: ImportCapability | undefined, role: Role, tier: 'plaintext', format: ExportFormat): boolean;
561
651
  export declare function evaluateImportCapability(capability: ImportCapability | undefined, role: Role, tier: 'bundle'): boolean;
652
+ /**
653
+ * core#132 — what this write is based on.
654
+ *
655
+ * `{ on }` is the envelope the edit was computed from; the write then CASes
656
+ * against its `_v` and lands at `_v + 1`. `'create'` is a keyring that did not
657
+ * exist.
658
+ *
659
+ * ⭐ REQUIRED, not optional, and that is the point: keyring writes were a bare
660
+ * `store.put` with no `expectedVersion`, so two concurrent edits to one member
661
+ * were last-writer-wins, silently. Making the basis a required parameter means
662
+ * the COMPILER enumerates every call site — `NON_ROTATABLE_SLOTS`' own comment
663
+ * records two defects caused by enumerating callers with grep instead.
664
+ *
665
+ * ⛔ `'create'` is NOT protected, and the limit is in the store contract, not
666
+ * in this function: two concurrent creates of the same userId still clobber,
667
+ * because this path passes no `expectedVersion` at all. Do not read a
668
+ * `'create'` basis as protected.
669
+ *
670
+ * ⚠️ It is not that absence is inexpressible — core#134 measured that claim and
671
+ * it was wrong. Every version hub writes starts at 1, so on a store that
672
+ * compares only when the record is present, `expectedVersion: 0` lets the
673
+ * first create through and conflicts every later one: an exact "write only if
674
+ * absent", for free. Censused 2026-09-24, every record store in the family
675
+ * already behaves that way, `to-aws-s3` deliberately and by name.
676
+ *
677
+ * ⛔ What stops this call site adopting it is that NOTHING HOLDS that
678
+ * convergence: `@noy-db/ports/to` asserts none of it, so a third-party adapter
679
+ * owes it nothing and this would become a silent correctness dependency on
680
+ * behaviour no gate checks. Adopt it after the conformance case lands, not
681
+ * before. core#134 carries the decision.
682
+ */
683
+ export type KeyringWriteBasis = {
684
+ readonly on: EncryptedEnvelope;
685
+ } | 'create';
686
+ /** The basis for a write computed from a `readKeyringFile` result. */
687
+ export declare const basisOf: (found: {
688
+ readonly envelope: EncryptedEnvelope;
689
+ } | undefined) => KeyringWriteBasis;
690
+ export declare function writeKeyringFile(store: NoydbStore, vault: string, userId: string, keyringFile: KeyringFile, basis: KeyringWriteBasis): Promise<void>;
@@ -24,7 +24,7 @@ import { type RotateSecretInput, type RecoverSecretInput, type RecoverSecretResu
24
24
  import { type RecoverUserOptions } from './peer-recover.js';
25
25
  import { type PaperRecoveryEntry, type ShamirRecoveryEntry } from './recovery.js';
26
26
  import type { Vault } from '../../kernel/vault.js';
27
- import type { UnlockedKeyring } from './keyring.js';
27
+ import type { UnlockedKeyring, RevokeResult } from './keyring.js';
28
28
  import { type EnrollAuthenticatorOptions, type UpdateAuthenticatorOptions } from './authenticators.js';
29
29
  import type { QuickUnlockStore, QuickUnlockState } from '../session/unlock-state.js';
30
30
  import type { SecretPolicy } from '../../kernel/validation.js';
@@ -58,6 +58,8 @@ export interface TeamFacadeDeps {
58
58
  readonly userId: string;
59
59
  readonly secret: string;
60
60
  }): Promise<void>;
61
+ /** core#96 — pull a member's keyring file from every sync target before an authority edit. */
62
+ refreshRoster(vault: string, userId: string): Promise<void>;
61
63
  /** Managed-recovery enrolment check (kernel-resident). */
62
64
  assertRecoveryEnrolled(vault: string, policy: VaultPolicy, opts?: {
63
65
  skipManagedCheck?: boolean;
@@ -76,7 +78,7 @@ export declare class TeamFacade {
76
78
  /** Gate + run a `grant` engine. See `Noydb.grant` for the public contract. */
77
79
  runGrant(engine: (adapter: NoydbStore, vault: string, callerKeyring: UnlockedKeyring, options: GrantOptions) => Promise<void>, vault: string, options: GrantOptions, factors?: FactorProofBundle): Promise<void>;
78
80
  /** Gate + run a `revoke` engine. See `Noydb.revoke` for the public contract. */
79
- runRevoke(engine: (adapter: NoydbStore, vault: string, callerKeyring: UnlockedKeyring, options: RevokeOptions) => Promise<void>, vault: string, options: RevokeOptions, factors?: FactorProofBundle): Promise<void>;
81
+ runRevoke(engine: (adapter: NoydbStore, vault: string, callerKeyring: UnlockedKeyring, options: RevokeOptions) => Promise<RevokeResult>, vault: string, options: RevokeOptions, factors?: FactorProofBundle): Promise<RevokeResult>;
80
82
  /** Gate + run a `rotateKeys` engine. See `Noydb.rotate` for the public contract. */
81
83
  runRotate(engine: (store: NoydbStore, vault: string, callerKeyring: UnlockedKeyring, opts: RotateKeysOptions) => Promise<RotateResult>, vault: string, collections: string[]): Promise<RotateResult>;
82
84
  /** Gate + run the `verifyRoster` engine (#1121). See `Noydb.verifyRoster`. */
@@ -171,6 +173,7 @@ export declare class TeamFacade {
171
173
  * meta: {
172
174
  * credentialId: e.credentialId,
173
175
  * wrapIv: e.wrapIv,
176
+ * rpId: e.rpId,
174
177
  * prfUsed: e.prfUsed,
175
178
  * beFlag: e.beFlag,
176
179
  * requireSingleDevice: e.requireSingleDevice,
@@ -179,6 +182,15 @@ export declare class TeamFacade {
179
182
  * })
180
183
  * ```
181
184
  *
185
+ * `meta` is a free-form blob — hub validates `credentialId` and nothing
186
+ * else, so this example IS the contract for what a slot carries. Record
187
+ * `rpId` (core#140): the slot rewrap / rotation ceremony falls back to
188
+ * `meta.rpId` when the caller passes no `options.rpId` and the enrollment
189
+ * record predates `WebAuthnEnrollment.rpId`. Omitting it does not break
190
+ * single-hostname deployments — absence correctly reads as "send no RP ID"
191
+ * — but on a shared registrable domain rotation then works only if every
192
+ * caller remembers to pass the RP ID by hand.
193
+ *
182
194
  * Returns the WebAuthn `credentialId` (extracted from `meta.credentialId`)
183
195
  * for the caller's lookup index (a bootstrap vault, a Cover,
184
196
  * a server-side allowlist).
@@ -44,7 +44,7 @@ export interface RosterTag {
44
44
  readonly iv: string;
45
45
  readonly data: string;
46
46
  }
47
- export type RosterAuthorityFields = Pick<KeyringFile, 'user_id' | 'role' | 'permissions' | 'granted_by' | 'expires_at' | 'export_capability' | 'import_capability' | 'deks' | 'pending_deks' | 'roster_epoch' | 'clearance'>;
47
+ export type RosterAuthorityFields = Pick<KeyringFile, 'user_id' | 'role' | 'permissions' | 'granted_by' | 'expires_at' | 'export_capability' | 'import_capability' | 'deks' | 'pending_deks' | 'roster_epoch' | 'clearance' | 'inbox_key' | 'inbox'>;
48
48
  export declare function rosterCanonical(file: RosterAuthorityFields): string;
49
49
  export declare function mintRosterTag(file: RosterAuthorityFields, rosterKey: EnclaveKey): Promise<RosterTag>;
50
50
  /**
@@ -1,4 +1,4 @@
1
- import type { NoydbStore, EncryptedEnvelope, ExportStreamOptions, ExportChunk } from '../kernel/types.js';
1
+ import type { NoydbStore, EncryptedEnvelope, LoadPodOptions, LoadPodResult, ExportStreamOptions, ExportChunk } from '../kernel/types.js';
2
2
  import type { LedgerStore } from '../with-commit/history/ledger/store.js';
3
3
  /** Everything the moving backup methods touched on the vault's `this.*`. */
4
4
  export interface BackupContext {
@@ -18,6 +18,13 @@ export interface BackupContext {
18
18
  * callback (plaintext vaults / test constructions).
19
19
  */
20
20
  reloadKeyringAndRebuildDEK(): Promise<void>;
21
+ /**
22
+ * core#71 — reset every sync engine attached to the vault after a restore:
23
+ * the dirty log, the watermarks, the adopted epoch. A restore is a new base;
24
+ * the pre-restore dirty entries refer to records the load just replaced.
25
+ * Absent on test constructions without sync.
26
+ */
27
+ resetSync?(): Promise<void>;
21
28
  /** Clear the vault's collection cache (post-load). */
22
29
  clearCollectionCache(): void;
23
30
  /** Reset the ledger store so the next `ledger()` rebuilds its head cache. */
@@ -42,23 +49,8 @@ export type VerifyBackupResult = {
42
49
  readonly id: string;
43
50
  readonly message: string;
44
51
  };
45
- /**
46
- * Dump vault as a verifiable encrypted JSON backup string.
47
- *
48
- * backups embed the current ledger head and the full `_ledger` +
49
- * `_ledger_deltas` internal collections so the receiver can run
50
- * `verifyBackupIntegrity()` after `load()` and detect any tampering between
51
- * dump and restore. Backups produced without a ledger skip the integrity check
52
- * with a warning — both modes round-trip cleanly.
53
- */
54
52
  export declare function dumpVault(ctx: BackupContext): Promise<string>;
55
- /**
56
- * Restore a vault from a verifiable backup. After loading, runs
57
- * `verifyBackupIntegrity()` to confirm the hash chain, the embedded head, and
58
- * every data envelope's payload hash. Legacy backups (no `ledgerHead`) load
59
- * with a console warning and skip the integrity check.
60
- */
61
- export declare function loadVault(ctx: BackupContext, backupJson: string): Promise<void>;
53
+ export declare function loadVault(ctx: BackupContext, backupJson: string, options?: LoadPodOptions): Promise<LoadPodResult>;
62
54
  /**
63
55
  * End-to-end backup integrity check: `ledger.verify()` (hash chain) plus a data
64
56
  * envelope cross-check (every current record's `_data` hash must match the
@@ -30,4 +30,31 @@
30
30
  * @public
31
31
  */
32
32
  import type { SyncStrategy } from './strategy.js';
33
- export declare function withSync(): SyncStrategy;
33
+ /**
34
+ * core#107 — `arbiter: true` makes this device the vault's ARBITER: its
35
+ * admission refusals are replicated so the writer finds out, instead of
36
+ * staying local to the device that judged them.
37
+ *
38
+ * ⚠️ One arbiter, named by configuration on the device that is to be it
39
+ * (the admin host, or the daemon) — ruled over a quorum because the failure
40
+ * mode is legible: no arbiter configured means no replication, which is
41
+ * exactly the pre-core#107 behaviour. It is NOT an authority proof: nothing
42
+ * stops a member hand-writing `_sync_rejections`, and the reason that is
43
+ * tolerable is the report-only ruling — a replicated refusal never deletes,
44
+ * tombstones or retracts anything, so the worst a forged one does is show
45
+ * somebody a notice about their own record.
46
+ *
47
+ * ⚠️ THE CONDITION THAT WOULD MAKE THAT NON-BOUNDARY A REAL ONE, named by
48
+ * pilot-1 when they accepted it: every member is currently staff of the same
49
+ * firm, and a forged refusal is sealed under the refused record's own
50
+ * collection DEK — so a forger can only show a notice about a record they
51
+ * could already read. ⛔ If EXTERNAL `client`-role users ever hold
52
+ * collections of their own, "who may write `_sync_rejections`" stops being
53
+ * cosmetic and this needs an authority design, not a flag. Do not read the
54
+ * paragraph above as a general safety argument; it is an argument about one
55
+ * topology, and this is the trigger to re-open it.
56
+ */
57
+ export interface WithSyncOptions {
58
+ readonly arbiter?: boolean;
59
+ }
60
+ export declare function withSync(options?: WithSyncOptions): SyncStrategy;
@@ -1,5 +1,9 @@
1
- import type { NoydbStore, DirtyEntry, ConflictStrategy, CollectionConflictResolver, PushOptions, PullOptions, PushResult, PullResult, SyncStatus, SyncTargetRole, RealignResult } from '../kernel/types.js';
1
+ import type { NoydbStore, DirtyEntry, ConflictStrategy, CollectionConflictResolver, PushOptions, PullOptions, PushResult, PullResult, SyncStatus, SyncTargetRole, RealignResult, SyncRejectedApi, ReplaceRemoteResult } from '../kernel/types.js';
2
+ /** core#74 — where a device parks the records its admission gate refused. Local-only: never mirrored, never full-pushed. */
3
+ export declare const REJECTED_COLLECTION = "_sync_rejected";
2
4
  import type { MergeAuthority } from '../port/with/merge-authority.js';
5
+ import type { AdmissionAuthority } from '../port/with/admission-authority.js';
6
+ import type { RejectionCourier } from '../port/with/rejection-courier.js';
3
7
  import { type PeriodPullSource } from './period-scope.js';
4
8
  import type { NoydbEventEmitter } from '../kernel/events.js';
5
9
  import type { SyncPolicy } from '../kernel/sync-policy.js';
@@ -13,7 +17,14 @@ export interface ReservedLookupSource {
13
17
  }
14
18
  /** Sync engine: dirty tracking, push, pull, conflict resolution, scheduling. */
15
19
  export declare class SyncEngine {
20
+ #private;
16
21
  private readonly mergeAuthority;
22
+ /** core#74 — the vault's admission gate for incoming records; wired at open like the other vault seams. */
23
+ private admission;
24
+ /** core#107 — the vault's sealing capability for replicated refusals; wired at open like `admission`. */
25
+ private courier;
26
+ /** core#107 — this device's refusals replicate. Configuration, not an authority proof — see `withSync`. */
27
+ private readonly arbiter;
17
28
  private readonly local;
18
29
  private readonly remote;
19
30
  private readonly strategy;
@@ -29,6 +40,8 @@ export declare class SyncEngine {
29
40
  /** #1036 — last SUCCESSFUL push/pull. Never advanced by a failed attempt. */
30
41
  private lastPush;
31
42
  private lastPull;
43
+ /** core#72 — the target's restore epoch this device adopted; null before any. */
44
+ private epoch;
32
45
  /**
33
46
  * #1036 — the failure that ended the most recent attempt, cleared by the next
34
47
  * success. Live state only: deliberately NOT persisted in `_sync/meta`, since a
@@ -89,9 +102,37 @@ export declare class SyncEngine {
89
102
  private periodPullSource?;
90
103
  /** Wire the period-window source (#807). Same injection pattern as `setReservedLookupSource`. */
91
104
  setPeriodPullSource(source: PeriodPullSource): void;
105
+ /** core#81 — the collections this keyring names; the walk set for a paged pull. Wired by the vault at open. */
106
+ private collectionNames?;
107
+ /** Wire the paged-pull walk set (core#81). Same injection pattern as `setCacheInvalidator`. */
108
+ setCollectionNames(fn: () => readonly string[]): void;
109
+ /**
110
+ * core#81 — one chunk per page of one collection, for `pull({ paged: true })`.
111
+ * `listPage` when the store offers it (200 per page), else `list` + `get` in
112
+ * batches of the same size. Never more than one page in memory.
113
+ */
114
+ private pagedChunks;
92
115
  /** core#82 — when a pull replaces the caller's OWN keyring file, the vault reloads it in place. */
93
116
  private rosterReload?;
94
117
  /** Wire the roster-reload seam (core#82). Same injection pattern as `setCacheInvalidator`. */
118
+ /** core#107 — wire the vault's rejection sealing capability. */
119
+ setRejectionCourier(c: RejectionCourier): void;
120
+ /** core#74 — wire the vault's admission gate. */
121
+ setAdmission(a: AdmissionAuthority): void;
122
+ /** core#71 — after `vault.load()`: a new base. Drops the dirty log, the watermarks and the adopted epoch. */
123
+ resetAfterRestore(): Promise<void>;
124
+ /**
125
+ * core#72 — make the LOCAL vault authoritative on this target. Every local
126
+ * record goes up unconditionally, re-sealed above the target's version where
127
+ * the target moved on (so every peer's copy is superseded); every id the
128
+ * target holds that the local vault lacks gets a delete marker at
129
+ * `remote._v + 1` (so every peer removes it); the reserved collections are
130
+ * mirrored; then a new epoch is written at `_sync/epoch`. The dirty log is
131
+ * cleared: the target IS the local state now.
132
+ */
133
+ replaceRemote(): Promise<ReplaceRemoteResult>;
134
+ /** core#74 — the parked refusals on this device, and their two fates. */
135
+ rejected(): SyncRejectedApi;
95
136
  setRosterReload(seam: {
96
137
  userId: string;
97
138
  reload: () => Promise<void>;
@@ -128,6 +169,8 @@ export declare class SyncEngine {
128
169
  * bound to the keys rather than the engine reaching for them.
129
170
  */
130
171
  mergeAuthority?: MergeAuthority;
172
+ /** core#107 — this device is the vault's arbiter: its refusals replicate. */
173
+ arbiter?: boolean;
131
174
  });
132
175
  /** Start the sync scheduler. Called after vault is fully opened. */
133
176
  startScheduler(): void;
@@ -163,9 +206,16 @@ export declare class SyncEngine {
163
206
  */
164
207
  remirrorPairResolvers(names: readonly string[]): void;
165
208
  /** Record a local change for later push. */
166
- trackChange(collection: string, id: string, action: 'put' | 'delete', version: number): Promise<void>;
209
+ trackChange(collection: string, id: string, action: DirtyEntry['action'], version: number): Promise<void>;
167
210
  /** Remove a dirty entry (satellite fan-out revert cleanup — spec #591). */
168
211
  removeDirty(collection: string, id: string): Promise<void>;
212
+ /**
213
+ * core#92 — mark every user-collection record in the local store dirty at its
214
+ * current version, so the next push sends it (CAS against `_v - 1`, so a
215
+ * remote that already holds a newer copy resolves through the conflict path
216
+ * instead of being overwritten). Records already dirty keep their entry.
217
+ */
218
+ markAllDirty(): Promise<void>;
169
219
  /** Push dirty records to remote adapter. Accepts optional `PushOptions` for partial sync. */
170
220
  push(options?: PushOptions): Promise<PushResult>;
171
221
  /** Pull remote records to local adapter. Accepts optional `PullOptions` for partial sync. */
@@ -209,6 +259,13 @@ export declare class SyncEngine {
209
259
  * what the caller can read. Requires a `MergeAuthority` (a vault-attached
210
260
  * engine on an encrypted vault).
211
261
  */
262
+ /**
263
+ * core#96 (pilot-1, finding B) — bring one member's keyring file down from
264
+ * this target if the target's copy supersedes ours. Called by the kernel
265
+ * before an authority edit; reloads the caller's own keyring in place when
266
+ * it is the one refreshed (core#82).
267
+ */
268
+ refreshKeyring(userId: string): Promise<boolean>;
212
269
  realign(): Promise<RealignResult>;
213
270
  status(): SyncStatus;
214
271
  /** Start auto-sync: listen for online/offline events, optional periodic sync. */
@@ -28,6 +28,7 @@
28
28
  * directly. This subpath is the clean LTS factory entry point.
29
29
  */
30
30
  export { withSync } from './active.js';
31
+ export type { WithSyncOptions } from './active.js';
31
32
  export type { SyncStrategy } from './strategy.js';
32
33
  /** The un-opted-in stub for this service — exported so callers can compare against it (#844). */
33
34
  export { NO_SYNC } from './strategy.js';
@@ -26,7 +26,9 @@
26
26
  * | `_meta/invite-audit-*` | higher `_v` wins | single-use evidence for magic links (core#83) |
27
27
  * | `_users` | higher `_v` wins | the directory's user envelopes; a member app renders these |
28
28
  * | `_delegations` | higher `_v` wins | delegation tokens; revocation is a delete |
29
+ * | `_broker`, `_broker_member` | higher `_v` wins | broker seeds (core#91) — sealed under DEKs only their holder has; a fresh device mints from them |
29
30
  * | `_history`, `_ledger` | NOT replicated | per-device evidence: the ledger is a hash chain per writer, two devices appending would fork it; `vault.at(T)` runs where history lives |
31
+ * | `_sync_rejections` | higher `_v` wins | core#107 — the arbiter's refusals, sealed under the refused record's own collection DEK |
30
32
  * | `_sync` | NOT replicated | this device's dirty log and watermarks |
31
33
  * | `_meta/schema-fence`, `_meta/handle`, other `_meta` | NOT replicated | session and instance state; the rest of `_meta` is decided one id at a time |
32
34
  *
@@ -49,12 +51,13 @@
49
51
  * the acting device and is pushed through the dirty log as
50
52
  * `(collection, id, 'delete')`. On PULL, a record the remote lacks and the
51
53
  * local holds is deleted locally only when (a) the remote carries at least
52
- * one record of that collection — a target never pushed to is not evidence
53
- * of revocation — and (b) no dirty entry protects it (a grant made offline,
54
- * not yet pushed). Invite audit docs are never deleted; revocation is a
54
+ * one KEYRING file — a target never pushed to is not evidence of revocation,
55
+ * but a collection that emptied by revocation is exactly what must propagate
56
+ * (core#91) — and (b) no dirty entry protects it (a grant made offline, not
57
+ * yet pushed). Invite audit docs are never deleted; revocation is a
55
58
  * field update, which the `_v` rule carries.
56
59
  */
57
- import type { NoydbStore } from '../kernel/types.js';
60
+ import type { NoydbStore, EncryptedEnvelope } from '../kernel/types.js';
58
61
  export interface ReservedMirrorResult {
59
62
  /** Records written to `to`. */
60
63
  readonly copied: number;
@@ -62,9 +65,29 @@ export interface ReservedMirrorResult {
62
65
  readonly deleted: number;
63
66
  /** Ids of `_keyring` files copied — the roster reload seam reads this for the caller's own file. */
64
67
  readonly keyringsCopied: readonly string[];
68
+ /**
69
+ * core#96 (pilot-1, finding B) — push only: local `_keyring` files the epoch
70
+ * rule did not write and whose content differs from the remote's (the remote
71
+ * is ahead, or the two diverged at one epoch). The local edit LOST; the
72
+ * engine reports each as a `Conflict` so an authority edit made on a stale
73
+ * copy is never silently dropped.
74
+ */
75
+ readonly staleKeyrings?: readonly {
76
+ readonly id: string;
77
+ readonly local: EncryptedEnvelope;
78
+ readonly remote: EncryptedEnvelope;
79
+ }[];
65
80
  }
66
81
  /** The push half: mirror every declared rule from `local` to `remote`. Never deletes. */
67
82
  export declare function pushReserved(local: NoydbStore, remote: NoydbStore, vault: string): Promise<ReservedMirrorResult>;
83
+ /**
84
+ * core#96 (pilot-1, finding B) — bring ONE member's keyring file down from the
85
+ * target if the target's copy supersedes the local one. The kernel calls it
86
+ * before every authority edit (`grant` on an existing user, `updateUser`,
87
+ * `revoke`, `recoverUser`), so the edit is made on the current file and its
88
+ * push wins instead of being discarded by the epoch rule. One GET.
89
+ */
90
+ export declare function pullKeyringFile(remote: NoydbStore, local: NoydbStore, vault: string, userId: string): Promise<boolean>;
68
91
  /**
69
92
  * The pull half: mirror every declared rule from `remote` into `local`, then
70
93
  * propagate revocations under the two guards in the module doc.
@@ -50,6 +50,8 @@ export interface BuildSyncEngineOptions {
50
50
  label?: string;
51
51
  /** #1042 — the merge's verify/re-stamp capability, bound to the keys by the caller. */
52
52
  mergeAuthority?: MergeAuthority;
53
+ /** core#107 — this device is the vault's arbiter: its admission refusals replicate. */
54
+ arbiter?: boolean;
53
55
  }
54
56
  /**
55
57
  * @internal
@@ -0,0 +1,25 @@
1
+ import {
2
+ freezeAndDeleteClosure,
3
+ freezeSnapshotOnly,
4
+ randomId,
5
+ withdrawAccessibleData
6
+ } from "./chunk-R2ZULFXU.js";
7
+ import "./chunk-KN4LUMH6.js";
8
+ import "./chunk-XPW7T2GN.js";
9
+ import "./chunk-DMIEKD24.js";
10
+ import "./chunk-GMKGGY7V.js";
11
+ import "./chunk-WRLWEYHY.js";
12
+ import "./chunk-ZD7WFMV2.js";
13
+ import "./chunk-RRTQAQ3N.js";
14
+ import "./chunk-NH2UOV3B.js";
15
+ import "./chunk-ZF6JECDT.js";
16
+ import "./chunk-THQ3BHLM.js";
17
+ import "./chunk-XX4R7TUB.js";
18
+ import "./chunk-IKPQ2GGB.js";
19
+ export {
20
+ freezeAndDeleteClosure,
21
+ freezeSnapshotOnly,
22
+ randomId,
23
+ withdrawAccessibleData
24
+ };
25
+ //# sourceMappingURL=withdraw-accessible-MTFP7OIB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@noy-db/hub",
3
- "version": "0.9.0-pre.0",
3
+ "version": "0.9.0-pre.1",
4
4
  "description": "Zero-knowledge, offline-first, encrypted document store — core library with AES-256-GCM, PBKDF2, multi-user keyring, and sync engine",
5
5
  "license": "Apache-2.0",
6
6
  "author": "vLannaAi <vicio@lanna.ai>",
@@ -276,8 +276,8 @@
276
276
  "happy-dom": "^18.0.0",
277
277
  "zod": "^4.0.0",
278
278
  "zod-to-json-schema": "^3.25.2",
279
- "@noy-db/attestation": "0.9.0-pre.0",
280
- "@noy-db/shamir": "0.9.0-pre.0"
279
+ "@noy-db/attestation": "0.9.0-pre.1",
280
+ "@noy-db/shamir": "0.9.0-pre.1"
281
281
  },
282
282
  "peerDependencies": {
283
283
  "zod": "^3.0.0 || ^4.0.0",
@@ -1,18 +0,0 @@
1
- import {
2
- UserApi,
3
- createUserApi
4
- } from "./chunk-GCUMOKTN.js";
5
- import "./chunk-FZXRLNJO.js";
6
- import "./chunk-4J3MNVVX.js";
7
- import "./chunk-ZBUAX4EF.js";
8
- import "./chunk-SPPOUJLN.js";
9
- import "./chunk-NH2UOV3B.js";
10
- import "./chunk-OM3SEDI4.js";
11
- import "./chunk-PUBI455O.js";
12
- import "./chunk-2ELOCEXE.js";
13
- import "./chunk-VSUQI5Q6.js";
14
- export {
15
- UserApi,
16
- createUserApi
17
- };
18
- //# sourceMappingURL=api-MSJXVYQG.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/with-pod/backup.ts"],"sourcesContent":["/**\n * Vault backup / restore / integrity.\n *\n * Holds `dump()` (verifiable encrypted JSON backup, including the blob\n * collections so blob \"covers\" travel in the bundle), `load()` (restore +\n * post-load integrity gate), `verifyBackupIntegrity()` (chain + data-envelope\n * cross-check), and `exportJSON()` (plaintext per-collection export, built on\n * the vault's `exportStream`). Behaviour is byte-identical to the inline\n * `Vault` methods these functions replaced — every dependency the moving code\n * touched on `this.*` arrives via {@link BackupContext}. `Vault` keeps the\n * public methods as thin delegators.\n *\n * Internal — reached through `vault.dump()` / `vault.load()` / etc.\n */\nimport { NOYDB_BACKUP_VERSION } from '../kernel/types.js'\nimport { BackupLedgerError, BackupCorruptedError } from '../kernel/errors.js'\nimport { LEDGER_COLLECTION, LEDGER_DELTAS_COLLECTION } from '../with-commit/history/ledger/constants.js'\nimport { SCHEMAS_COLLECTION } from '../with-shape/persisted-schemas/storage.js'\nimport { SEQUENCE_COLLECTION } from '../with-commit/sequence/index.js'\nimport { MANIFEST_COLLECTION } from '../with-shape/manifest/reserved-collections.js'\n// #1025 — imported from the dependency-light `window.ts`, not `periods.ts`: that\n// module exists precisely so a consumer can name the period collections without\n// dragging the ledger hash-chain machinery (`sha256Hex`/`canonicalJson`) into a\n// bundle that opted out of the periods service. Same reason the sync engine's\n// period-scoped pull imports it.\nimport {\n PERIODS_COLLECTION,\n PERIOD_FREEZES_COLLECTION,\n PERIOD_ARCHIVES_COLLECTION,\n PERIOD_TARGET_PURGES_COLLECTION,\n PERIOD_REOPENS_COLLECTION,\n} from '../with-audit/periods/window.js'\nimport type {\n NoydbStore,\n EncryptedEnvelope,\n VaultBackup,\n VaultSnapshot,\n ExportStreamOptions,\n ExportChunk,\n} from '../kernel/types.js'\nimport type { LedgerStore } from '../with-commit/history/ledger/store.js'\nimport { buildRecordEnvelope } from '../capsule/index.js'\n\n/** Everything the moving backup methods touched on the vault's `this.*`. */\nexport interface BackupContext {\n /** The ciphertext store. */\n readonly adapter: NoydbStore\n /** Vault namespace name. */\n readonly vault: string\n /** The invoking keyring's user id (read fresh per call). */\n userId(): string\n /** The vault's ledger store, or null when history is off. */\n getLedgerOrNull(): LedgerStore | null\n /** Recompute an envelope's `payloadHash` (bound `historyStrategy.envelopePayloadHash`). */\n envelopePayloadHash(envelope: EncryptedEnvelope): Promise<string>\n /**\n * Refresh the in-memory keyring from the freshly-loaded keyring file and\n * rebuild the DEK resolver. No-op when the vault has no `reloadKeyring`\n * callback (plaintext vaults / test constructions).\n */\n reloadKeyringAndRebuildDEK(): Promise<void>\n /** Clear the vault's collection cache (post-load). */\n clearCollectionCache(): void\n /** Reset the ledger store so the next `ledger()` rebuilds its head cache. */\n resetLedgerStore(): void\n /** The vault's decrypt+ACL export stream (used by `exportJSON`). */\n exportStream(opts: ExportStreamOptions): AsyncIterableIterator<ExportChunk>\n}\n\n/** Result of {@link verifyBackupIntegrity}. */\nexport type VerifyBackupResult =\n | { readonly ok: true; readonly head: string; readonly length: number }\n | {\n readonly ok: false\n readonly kind: 'chain'\n readonly divergedAt: number\n readonly message: string\n }\n | {\n readonly ok: false\n readonly kind: 'data'\n readonly collection: string\n readonly id: string\n readonly message: string\n }\n\n/**\n * Dump vault as a verifiable encrypted JSON backup string.\n *\n * backups embed the current ledger head and the full `_ledger` +\n * `_ledger_deltas` internal collections so the receiver can run\n * `verifyBackupIntegrity()` after `load()` and detect any tampering between\n * dump and restore. Backups produced without a ledger skip the integrity check\n * with a warning — both modes round-trip cleanly.\n */\nexport async function dumpVault(ctx: BackupContext): Promise<string> {\n const snapshot = await ctx.adapter.loadAll(ctx.vault)\n\n // Load keyrings (separate path because loadAll filters them out\n // along with all other underscore-prefixed internal collections).\n const keyringIds = await ctx.adapter.list(ctx.vault, '_keyring')\n const keyrings: Record<string, unknown> = {}\n for (const keyringId of keyringIds) {\n const envelope = await ctx.adapter.get(ctx.vault, '_keyring', keyringId)\n if (envelope) {\n keyrings[keyringId] = JSON.parse(envelope._data ?? '')\n }\n }\n\n // Load the ledger entries + deltas so the receiver can replay\n // the chain after restore. Without this, `load()` would have an\n // empty ledger and `verifyBackupIntegrity()` would have nothing\n // to compare against.\n //\n // Also enumerate the blob collections so blob content (\"covers\")\n // travels in the bundle (the blob DEK already travels in `_keyring`).\n // Literals are inlined (not imported from blobs/blob-set.ts) to keep\n // the blob runtime out of this kernel hot path — they mirror\n // BLOB_INDEX/CHUNKS/EVICTION_AUDIT_COLLECTION and SLOTS/VERSIONS_PREFIX.\n // The collect-loop skips empty ids, so this no-ops without blobs.\n const internalSnapshot: VaultSnapshot = {}\n const internalNames = [\n LEDGER_COLLECTION, LEDGER_DELTAS_COLLECTION, SCHEMAS_COLLECTION, SEQUENCE_COLLECTION,\n MANIFEST_COLLECTION, // #941: the pod's manifest-set record(s) travel in the bundle too\n // #1025: the accounting-period close state + its companions. The bundle is\n // the backup/restore path, so without these a restore discarded the\n // hash-chained evidence that a month was ever closed — the artifact\n // `closePeriod` exists to produce — and dropped the write gate with it, so\n // the restored vault silently accepted back-dated writes into a sealed\n // month. The companions matter as much as the close: a bounded reopen\n // window (`reopenPeriod({ until })`) is state a restore must not lose.\n PERIODS_COLLECTION,\n PERIOD_REOPENS_COLLECTION,\n PERIOD_FREEZES_COLLECTION,\n PERIOD_ARCHIVES_COLLECTION,\n PERIOD_TARGET_PURGES_COLLECTION,\n '_history', // full-snapshot version history — so history()/getVersion()/diff() survive the bundle\n '_blob_index', '_blob_chunks', '_blob_eviction_audit',\n // #753 spec §7 Q3: `_blob_intent` markers travel too — restoring mid-op\n // state (a blob row without its marker) would reproduce the ambiguity\n // the journal exists to prevent. Note: `_mv_stale` does NOT travel\n // today (a pre-existing, separate gap) — observed here, tracked on\n // #761, not fixed in this pass.\n '_blob_intent',\n // #769: `_blob_slots_<c>` envelopes travel verbatim (raw ciphertext,\n // same DEK, same vault) — including any `SlotRecord.pendingRelease`\n // resume breadcrumb they carry. This is INTENTIONALLY the opposite of\n // `extract-partition`'s `reKeyBlobs`, which STRIPS `pendingRelease`:\n // a full-vault backup restores into the SAME vault it was taken from,\n // so a breadcrumb taken mid-rehome (together with its `_blob_intent`\n // marker, carried above) is resumable on restore — carry-and-resume is\n // correct here. A partition extraction crosses vaults: the breadcrumb's\n // old eTag may not exist in the destination, so it must be stripped\n // there instead. Asymmetry: backup = same-vault-resumable = carry;\n // partition = cross-vault = strip-breadcrumb-carry-marker.\n ...Object.keys(snapshot).flatMap((c) => [`_blob_slots_${c}`, `_blob_versions_${c}`]),\n ]\n for (const internalName of internalNames) {\n const ids = await ctx.adapter.list(ctx.vault, internalName)\n if (ids.length === 0) continue\n const records: Record<string, EncryptedEnvelope> = {}\n for (const id of ids) {\n const envelope = await ctx.adapter.get(ctx.vault, internalName, id)\n if (envelope) records[id] = envelope\n }\n internalSnapshot[internalName] = records\n }\n\n // Embed the ledger head if there's a chain. An empty ledger\n // (fresh vault) leaves `ledgerHead` undefined, which\n // load() treats the same as a legacy backup (no integrity\n // check, console warning). If history is not opted in,\n // `getLedgerOrNull` returns null and we skip embedding entirely\n // — the backup is still valid, just without the integrity head.\n const ledgerForHead = ctx.getLedgerOrNull()\n const head = ledgerForHead ? await ledgerForHead.head() : null\n const backup: VaultBackup = {\n _noydb_backup: NOYDB_BACKUP_VERSION,\n _compartment: ctx.vault,\n _exported_at: new Date().toISOString(),\n _exported_by: ctx.userId(),\n keyrings: keyrings as VaultBackup['keyrings'],\n collections: snapshot,\n ...(Object.keys(internalSnapshot).length > 0\n ? { _internal: internalSnapshot }\n : {}),\n ...(head\n ? {\n ledgerHead: {\n hash: head.hash,\n index: head.entry.index,\n ts: head.entry.ts,\n },\n }\n : {}),\n }\n\n return JSON.stringify(backup)\n}\n\n/**\n * Restore a vault from a verifiable backup. After loading, runs\n * `verifyBackupIntegrity()` to confirm the hash chain, the embedded head, and\n * every data envelope's payload hash. Legacy backups (no `ledgerHead`) load\n * with a console warning and skip the integrity check.\n */\nexport async function loadVault(ctx: BackupContext, backupJson: string): Promise<void> {\n const backup = JSON.parse(backupJson) as VaultBackup\n\n // 1. Restore data collections.\n await ctx.adapter.saveAll(ctx.vault, backup.collections)\n\n // 2. Restore keyrings.\n for (const [userId, keyringFile] of Object.entries(backup.keyrings)) {\n const envelope = buildRecordEnvelope({ collection: '_keyring', id: userId, version: 1 },\n { iv: '', data: JSON.stringify(keyringFile) })\n await ctx.adapter.put(ctx.vault, '_keyring', userId, envelope)\n }\n\n // 3. Restore internal collections (`_ledger`, `_ledger_deltas`).\n // Required so verifyBackupIntegrity has the chain to walk.\n if (backup._internal) {\n for (const [internalName, records] of Object.entries(backup._internal)) {\n for (const [id, envelope] of Object.entries(records)) {\n await ctx.adapter.put(ctx.vault, internalName, id, envelope)\n }\n }\n }\n\n // 4. Refresh the in-memory keyring from the freshly-loaded\n // keyring file. Without this, the Vault's getDEK\n // closure still holds the OLD session's DEKs, and every\n // decrypt of a loaded ledger entry / data envelope fails\n // with TamperedError because the DEK doesn't match the\n // ciphertext that was encrypted with the SOURCE user's DEK.\n // Skipped for plaintext vaults and for tests that\n // construct Vault without a reloadKeyring callback.\n await ctx.reloadKeyringAndRebuildDEK()\n\n // 5. Clear collection cache + reset the ledger store so the\n // next ledger() call rebuilds its head cache from the\n // freshly-loaded entries.\n ctx.clearCollectionCache()\n ctx.resetLedgerStore()\n\n // 5. Run the verification gate. A backup with no ledgerHead cannot be\n // integrity-checked, and skipping silently would collapse\n // *unverifiable* into *clean* — so it always warns. But the REMEDY\n // depends on the reader, not the pod (#1303): the pod cannot say\n // whether its exporter predates the ledger or never enabled it, and\n // the reader knows its own configuration.\n //\n // - Reader HAS the ledger: the pod is behind it. \"Re-export\" is\n // actionable; keep the migration wording.\n // - Reader has NO ledger: nothing is stale and nothing is migrating —\n // the consumer priced the ledger (#1248 measured ~2.4x) and declined.\n // Prescribing a re-export is advice they should not take, and\n // repeating it on every read trains people to filter the one line\n // that also fires on a genuinely stale pod. State the consequence,\n // name the discriminator, prescribe nothing.\n if (!backup.ledgerHead) {\n if (ctx.getLedgerOrNull()) {\n console.warn(\n `[noy-db] Loaded a legacy backup with no ledgerHead — ` +\n `verifiable-backup integrity check skipped. ` +\n `Re-export with a ledger-aware build to get tamper detection.`,\n )\n } else {\n console.warn(\n `[noy-db] Loaded a backup with no ledgerHead — this pod is not integrity-checked. ` +\n `This reader has no ledger enabled (withHistory() is not configured), so nothing is stale: ` +\n `enable the ledger on both the exporter and this reader if tamper detection is wanted.`,\n )\n }\n return\n }\n\n const result = await verifyBackupIntegrity(ctx)\n if (!result.ok) {\n // Surface the most specific error class we can. The result\n // shape carries enough info for callers to inspect.\n if (result.kind === 'data') {\n throw new BackupCorruptedError(\n result.collection,\n result.id,\n result.message,\n )\n }\n throw new BackupLedgerError(result.message, result.divergedAt)\n }\n\n // 6. Cross-check: the freshly-verified head must match the\n // value embedded at dump time. A mismatch means someone\n // truncated or extended the chain after dump.\n if (result.head !== backup.ledgerHead.hash) {\n throw new BackupLedgerError(\n `Backup ledger head mismatch: embedded \"${backup.ledgerHead.hash}\" ` +\n `but reconstructed \"${result.head}\".`,\n )\n }\n}\n\n/**\n * End-to-end backup integrity check: `ledger.verify()` (hash chain) plus a data\n * envelope cross-check (every current record's `_data` hash must match the\n * latest `put` entry's `payloadHash`). Returns a discriminated union so callers\n * can distinguish chain vs data failures.\n */\nexport async function verifyBackupIntegrity(ctx: BackupContext): Promise<VerifyBackupResult> {\n // Step 1: chain verification. Without the history strategy there\n // is no ledger; an unaudited backup verifies trivially as `ok`\n // because there's nothing to diverge from.\n const ledgerForVerify = ctx.getLedgerOrNull()\n if (!ledgerForVerify) {\n return { ok: true, head: '', length: 0 }\n }\n const chainResult = await ledgerForVerify.verify()\n if (!chainResult.ok) {\n return {\n ok: false,\n kind: 'chain',\n divergedAt: chainResult.divergedAt,\n message:\n `Ledger chain diverged at index ${chainResult.divergedAt}: ` +\n `expected prevHash \"${chainResult.expected}\" but found \"${chainResult.actual}\".`,\n }\n }\n\n // Step 2: data envelope cross-check. Walk every entry in the\n // ledger and, for the LATEST `put` per (collection, id), recompute\n // the data envelope's payloadHash and compare. Earlier puts of the\n // same id are skipped because the data collection only holds the\n // current version — historical envelopes live in the deltas\n // collection (which is itself protected by the chain).\n // Reuse the ledger we already resolved in step 1.\n const allEntries = await ledgerForVerify.loadAllEntries()\n\n // Find the latest non-delete entry per (collection, id). Walk\n // the entries in reverse so we hit the latest first; mark each\n // (collection, id) as seen and skip subsequent entries.\n const seen = new Set<string>()\n const latest = new Map<\n string,\n { collection: string; id: string; expectedHash: string }\n >()\n for (let i = allEntries.length - 1; i >= 0; i--) {\n const entry = allEntries[i]\n if (!entry) continue\n // Amendment entries are multi-record audit entries whose\n // `collection` and `id` are empty strings — building a `\"/\"`\n // key here would mark that synthetic slot as seen and falsely\n // trip the data check on a record that never existed. Skip\n // them BEFORE the key/seen bookkeeping so they neither\n // tombstone real entries nor enter the latest map.\n if (entry.op === 'amendment' || entry.op === 'lifecycle') continue\n const key = `${entry.collection}/${entry.id}`\n if (seen.has(key)) continue\n seen.add(key)\n // For deletes the data collection should NOT have the record,\n // so we skip — there's nothing to cross-check. Marking the key\n // as seen above ensures any earlier `put` of the same id is\n // also skipped (the record was subsequently deleted).\n if (entry.op === 'delete') continue\n latest.set(key, {\n collection: entry.collection,\n id: entry.id,\n expectedHash: entry.payloadHash,\n })\n }\n\n for (const { collection, id, expectedHash } of latest.values()) {\n const envelope = await ctx.adapter.get(ctx.vault, collection, id)\n if (!envelope) {\n return {\n ok: false,\n kind: 'data',\n collection,\n id,\n message:\n `Ledger expects data record \"${collection}/${id}\" to exist, ` +\n `but the adapter has no envelope for it.`,\n }\n }\n const actualHash = await ctx.envelopePayloadHash(envelope)\n if (actualHash !== expectedHash) {\n return {\n ok: false,\n kind: 'data',\n collection,\n id,\n message:\n `Data envelope \"${collection}/${id}\" has been tampered with: ` +\n `expected payloadHash \"${expectedHash}\", got \"${actualHash}\".`,\n }\n }\n }\n\n return {\n ok: true,\n head: chainResult.head,\n length: chainResult.length,\n }\n}\n\n/**\n * Plaintext per-collection export, built on the vault's `exportStream`. Forces\n * collection granularity (record-by-record output makes no sense in a single\n * string) and merges dictionary snapshots across collections.\n */\nexport async function exportVaultJSON(ctx: BackupContext, opts: ExportStreamOptions = {}): Promise<string> {\n // Force per-collection granularity regardless of caller setting:\n // record-by-record output doesn't make sense in a single string.\n const collections: Record<\n string,\n {\n schema: null\n refs: Record<string, { target: string; mode: 'strict' | 'warn' | 'cascade' }>\n records: unknown[]\n }\n > = {}\n let ledgerHead: ExportChunk['ledgerHead'] | undefined\n // Merged dictionary snapshot across all collections.\n // Only populated when `resolveLabels` is not set.\n const allDictionaries: Record<\n string, // collection name\n Record<string, Record<string, Record<string, string>>>\n > = {}\n\n for await (const chunk of ctx.exportStream({\n granularity: 'collection',\n withLedgerHead: opts.withLedgerHead === true,\n // Thread the export locale so records are read at the\n // `export` layer (i18nText collapsed + dictKey/staticDict labels resolved).\n ...(opts.resolveLabels !== undefined ? { resolveLabels: opts.resolveLabels } : {}),\n })) {\n collections[chunk.collection] = {\n schema: null, // Standard Schema validators are not JSON-serializable\n refs: chunk.refs,\n records: chunk.records,\n }\n if (chunk.ledgerHead) ledgerHead = chunk.ledgerHead\n // Collect dictionary snapshots unless resolveLabels is set\n if (!opts.resolveLabels && chunk.dictionaries) {\n allDictionaries[chunk.collection] = chunk.dictionaries\n }\n }\n\n const hasDictionaries = Object.keys(allDictionaries).length > 0\n return JSON.stringify({\n _noydb_export: 1,\n _compartment: ctx.vault,\n _exported_at: new Date().toISOString(),\n _exported_by: ctx.userId(),\n collections,\n ...(hasDictionaries ? { _dictionaries: allDictionaries } : {}),\n ...(ledgerHead ? { ledgerHead } : {}),\n })\n}\n"],"mappings":"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","names":[]}