@noy-db/hub 0.9.0-pre.0 → 0.9.0-pre.2

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 (465) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/dist/api-H4B7ZQXP.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-E3GBMNDA.js} +92 -31
  7. package/dist/backup-E3GBMNDA.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-YQKQZPH7.js} +14 -8
  18. package/dist/cargo/index.js +35 -35
  19. package/dist/{chunk-AJFPAHMW.js → chunk-27NCEPKM.js} +3 -3
  20. package/dist/{chunk-PGC35KXE.js → chunk-2IASHJPS.js} +2 -2
  21. package/dist/{chunk-NYJBYVBG.js → chunk-2ODEFG6K.js} +4 -4
  22. package/dist/{chunk-7BMOS4JQ.js → chunk-2QH3I7QC.js} +11 -11
  23. package/dist/{chunk-VSUQI5Q6.js → chunk-2RH5SEY7.js} +16 -2
  24. package/dist/chunk-2RH5SEY7.js.map +1 -0
  25. package/dist/{chunk-IVMFIKNA.js → chunk-2T2TGRWE.js} +6 -6
  26. package/dist/{chunk-G66YXUTY.js → chunk-35CNOVQE.js} +3 -3
  27. package/dist/{chunk-OJU67C23.js → chunk-3EXQXOQ2.js} +4 -4
  28. package/dist/{chunk-BJH77UY2.js → chunk-4KYKRYRT.js} +2 -2
  29. package/dist/{chunk-RDOEOPOI.js → chunk-4N4OIVK3.js} +5 -5
  30. package/dist/{chunk-WHOKGHJ3.js → chunk-4WLI37WK.js} +7 -7
  31. package/dist/{chunk-RNACRT5H.js → chunk-52ZFNK46.js} +2 -2
  32. package/dist/{chunk-CB4467G3.js → chunk-5A3HOTP5.js} +33 -7
  33. package/dist/chunk-5A3HOTP5.js.map +1 -0
  34. package/dist/{chunk-QDHHHI5Q.js → chunk-5SMCBPJ2.js} +5 -5
  35. package/dist/{chunk-EMAWOGVH.js → chunk-654RE5YC.js} +3 -3
  36. package/dist/{chunk-FZXRLNJO.js → chunk-6BEBWHNL.js} +3 -3
  37. package/dist/{chunk-EUD3HQM4.js → chunk-6WEPFEMJ.js} +4 -4
  38. package/dist/{chunk-YFFMPZPY.js → chunk-6WIFF46H.js} +2 -2
  39. package/dist/{chunk-ZVSKSUGI.js → chunk-7C7OF26T.js} +5 -5
  40. package/dist/{chunk-QXJXG7DN.js → chunk-7IV7GVOS.js} +5 -5
  41. package/dist/{chunk-MQ7YWBQ5.js → chunk-7JRLCP2J.js} +2 -2
  42. package/dist/{chunk-QSHATAXJ.js → chunk-7ONMS7QI.js} +2 -2
  43. package/dist/{chunk-JBMMWYOH.js → chunk-7UHLO4ZN.js} +35 -2
  44. package/dist/chunk-7UHLO4ZN.js.map +1 -0
  45. package/dist/{chunk-6WS35E6X.js → chunk-A52BK5AY.js} +2 -2
  46. package/dist/{chunk-GOJQ5DZA.js → chunk-AI35LNWQ.js} +4 -4
  47. package/dist/chunk-AI35LNWQ.js.map +1 -0
  48. package/dist/{chunk-XXQ5XIYY.js → chunk-AMSSAOOB.js} +2 -2
  49. package/dist/{chunk-3V6LZHUO.js → chunk-AYOQZJDB.js} +2 -2
  50. package/dist/{chunk-DL6BZKP3.js → chunk-B3B6HV5S.js} +2 -2
  51. package/dist/{chunk-5XONHAFD.js → chunk-B6EWMGFX.js} +2 -2
  52. package/dist/{chunk-6Y5E4SJU.js → chunk-BMAXBTYH.js} +5 -5
  53. package/dist/{chunk-LGGIFKJP.js → chunk-BNYDOF2Q.js} +4 -4
  54. package/dist/{chunk-XXNWU5QZ.js → chunk-BQJ5ORU5.js} +2 -2
  55. package/dist/{chunk-Z3ZXVB2Y.js → chunk-BSEPI3HD.js} +12 -12
  56. package/dist/chunk-BSEPI3HD.js.map +1 -0
  57. package/dist/{chunk-BYHCKX73.js → chunk-CLOSXHR4.js} +3 -3
  58. package/dist/{chunk-5HNW4ZTA.js → chunk-CSAN22QG.js} +6 -6
  59. package/dist/{chunk-TZYTMZZY.js → chunk-DL4GCSTS.js} +10 -10
  60. package/dist/{chunk-EA4VDI5D.js → chunk-DYIR6RC3.js} +4 -4
  61. package/dist/{chunk-PUBI455O.js → chunk-EPPAEGH5.js} +2 -2
  62. package/dist/{chunk-2A56DSRI.js → chunk-EQ6C2ZPT.js} +17 -51
  63. package/dist/chunk-EQ6C2ZPT.js.map +1 -0
  64. package/dist/{chunk-BNFNQNEP.js → chunk-F7X7MPK4.js} +2 -2
  65. package/dist/{chunk-SNM7LSYG.js → chunk-FUHUGKDN.js} +4 -4
  66. package/dist/{chunk-72XBVN4J.js → chunk-FVKQ5QUC.js} +2 -2
  67. package/dist/chunk-FVKQ5QUC.js.map +1 -0
  68. package/dist/{chunk-D4V5JJAK.js → chunk-GHMINSER.js} +4 -4
  69. package/dist/{chunk-APFFJN5T.js → chunk-GLSCL74M.js} +31 -34
  70. package/dist/chunk-GLSCL74M.js.map +1 -0
  71. package/dist/{chunk-XKBTJGFP.js → chunk-GU6QXHPZ.js} +3 -3
  72. package/dist/chunk-GU6QXHPZ.js.map +1 -0
  73. package/dist/{chunk-QGFEBNHO.js → chunk-GZISWBCJ.js} +4 -4
  74. package/dist/{chunk-OM3SEDI4.js → chunk-HTRLQ4ZZ.js} +4 -4
  75. package/dist/{chunk-SWXLZ4HX.js → chunk-ICHHNI5E.js} +8 -8
  76. package/dist/{chunk-K673OO6B.js → chunk-ID4ZBC3X.js} +4 -4
  77. package/dist/{chunk-H3YM66EI.js → chunk-IF2M43G4.js} +2 -2
  78. package/dist/{chunk-QGSNJD3B.js → chunk-IFUYLIEY.js} +2 -2
  79. package/dist/{chunk-D5A3GCZ4.js → chunk-IPF5ORDI.js} +3 -3
  80. package/dist/{delegation-ONLM4JFI.js → chunk-JQMEXCUZ.js} +59 -16
  81. package/dist/chunk-JQMEXCUZ.js.map +1 -0
  82. package/dist/{chunk-TFWFPZRU.js → chunk-K5JNK63R.js} +11 -11
  83. package/dist/{chunk-TFWFPZRU.js.map → chunk-K5JNK63R.js.map} +1 -1
  84. package/dist/{chunk-BVF3SXD7.js → chunk-KBIS64X4.js} +5 -5
  85. package/dist/chunk-L4UL4IAR.js +55 -0
  86. package/dist/chunk-L4UL4IAR.js.map +1 -0
  87. package/dist/{chunk-RIZTZJX6.js → chunk-LJ744WXU.js} +2 -2
  88. package/dist/{chunk-XITHENBI.js → chunk-LMC5L3MM.js} +7 -7
  89. package/dist/{chunk-XITHENBI.js.map → chunk-LMC5L3MM.js.map} +1 -1
  90. package/dist/{chunk-L5A3KR7R.js → chunk-LUQBG637.js} +3 -3
  91. package/dist/{chunk-6QLCS7ET.js → chunk-LZN6DTFI.js} +2 -2
  92. package/dist/{chunk-NIXRB5BP.js → chunk-MMWX5OT5.js} +2 -2
  93. package/dist/{chunk-JA25QG5M.js → chunk-N6EWQ5VB.js} +622 -119
  94. package/dist/chunk-N6EWQ5VB.js.map +1 -0
  95. package/dist/{chunk-UOZOWN73.js → chunk-ND6S2DKC.js} +2 -2
  96. package/dist/{chunk-WFWFXDNS.js → chunk-NHEKQWFI.js} +2 -2
  97. package/dist/{chunk-2ZFD2UJC.js → chunk-NIUHKKMM.js} +9 -9
  98. package/dist/{chunk-XA34THLF.js → chunk-NK4LGBGQ.js} +4 -4
  99. package/dist/{chunk-JSWKVZCR.js → chunk-NUZ7ROUZ.js} +2 -2
  100. package/dist/{chunk-DHU2AQ6T.js → chunk-O3NGOHXQ.js} +2 -2
  101. package/dist/{chunk-ZBUAX4EF.js → chunk-O6VOR4NH.js} +2 -2
  102. package/dist/{chunk-JZ4EDEIP.js → chunk-ODBOHPZU.js} +3 -3
  103. package/dist/{chunk-5UUJE4FP.js → chunk-OK44MD3C.js} +2 -2
  104. package/dist/{chunk-ECGXA4LT.js → chunk-OR3OHKU6.js} +2 -2
  105. package/dist/{chunk-ZWF3EWZA.js → chunk-P6FATPXQ.js} +2 -2
  106. package/dist/{chunk-PCYPXLEX.js → chunk-PBEHTFUG.js} +6 -6
  107. package/dist/{chunk-7CT6SX4M.js → chunk-PFHDQY5L.js} +3 -3
  108. package/dist/{chunk-PTJY5R3O.js → chunk-PIO6NW7O.js} +2 -2
  109. package/dist/{chunk-TMIJAR2X.js → chunk-PREYKC76.js} +3 -3
  110. package/dist/{chunk-ZHQJAV6D.js → chunk-PU5ZEV65.js} +2 -2
  111. package/dist/{chunk-UNSQZSZP.js → chunk-PWAMX5KU.js} +2 -2
  112. package/dist/{chunk-GETUTTZU.js → chunk-PZN76MMV.js} +4 -4
  113. package/dist/{chunk-ABU6A4Z5.js → chunk-Q4DBU5RM.js} +2 -2
  114. package/dist/{chunk-2WJKJZSO.js → chunk-QHG7GQKM.js} +2 -2
  115. package/dist/{chunk-UAKY6E4N.js → chunk-QNOWNCZS.js} +2 -2
  116. package/dist/{chunk-JPSL5GIZ.js → chunk-QQLXKDGC.js} +3 -3
  117. package/dist/{chunk-45VHWE4C.js → chunk-QVUMKG3Z.js} +271 -69
  118. package/dist/chunk-QVUMKG3Z.js.map +1 -0
  119. package/dist/{chunk-OK57EATL.js → chunk-R4GLRJ55.js} +2 -2
  120. package/dist/{chunk-B65CC6Z6.js → chunk-RF5WDM25.js} +2 -2
  121. package/dist/{chunk-G46JSSVX.js → chunk-RKBCUP5D.js} +7 -7
  122. package/dist/{chunk-GCUMOKTN.js → chunk-S2ORTQGS.js} +3 -3
  123. package/dist/{chunk-MRJDLXI3.js → chunk-SVXFCCSX.js} +8 -8
  124. package/dist/{chunk-BUE7R3B5.js → chunk-SXPLIRQH.js} +2 -2
  125. package/dist/{chunk-5LMCVBMY.js → chunk-T5EXREMW.js} +5 -5
  126. package/dist/{chunk-PT2YCQVK.js → chunk-TBVDI3LY.js} +4 -4
  127. package/dist/{chunk-BMHQHH7Q.js → chunk-TLIFNRU5.js} +2 -2
  128. package/dist/{chunk-YKGJ44Z7.js → chunk-TU6ZJTYT.js} +3 -3
  129. package/dist/{chunk-FSQNGPHH.js → chunk-U277K5GR.js} +612 -175
  130. package/dist/chunk-U277K5GR.js.map +1 -0
  131. package/dist/{chunk-55P6OBB7.js → chunk-U43RSPPX.js} +2 -2
  132. package/dist/{chunk-K7RW7FI4.js → chunk-UADW5NOU.js} +5 -5
  133. package/dist/{chunk-GRS2HIV6.js → chunk-UMV5GBTJ.js} +2 -2
  134. package/dist/{chunk-4UIP3QNW.js → chunk-UNAMWK2Q.js} +2 -2
  135. package/dist/{chunk-J4KAPKBJ.js → chunk-UORWAG7K.js} +2 -2
  136. package/dist/{chunk-V55JASXO.js → chunk-UQRKAM2R.js} +3 -3
  137. package/dist/{chunk-2ELOCEXE.js → chunk-URGHKZPL.js} +1 -1
  138. package/dist/chunk-URGHKZPL.js.map +1 -0
  139. package/dist/{chunk-ZMVSKYTJ.js → chunk-VLRY2UH4.js} +10 -10
  140. package/dist/{chunk-SPPOUJLN.js → chunk-VZFTON37.js} +2 -2
  141. package/dist/{chunk-CAD7N6HQ.js → chunk-WIUH6EJ7.js} +10 -10
  142. package/dist/chunk-WIUH6EJ7.js.map +1 -0
  143. package/dist/{chunk-YQFBH5ZJ.js → chunk-WQUIJPN4.js} +3 -3
  144. package/dist/{chunk-4J3MNVVX.js → chunk-WRLWEYHY.js} +7 -1
  145. package/dist/{chunk-4J3MNVVX.js.map → chunk-WRLWEYHY.js.map} +1 -1
  146. package/dist/{chunk-NZULV7LK.js → chunk-WVQDY3UM.js} +4 -4
  147. package/dist/{chunk-3Y5JLSXS.js → chunk-X5RGG3ZW.js} +2 -2
  148. package/dist/{chunk-PFCTSXHU.js → chunk-X6Z2SIRF.js} +2 -2
  149. package/dist/{chunk-UHFGK6YA.js → chunk-XQGKS4OW.js} +3 -3
  150. package/dist/{chunk-L2F3CFCH.js → chunk-Y22JWHCP.js} +4 -4
  151. package/dist/{chunk-C53ER7AG.js → chunk-YVA6UPRN.js} +2 -2
  152. package/dist/{chunk-226V6XXJ.js → chunk-Z2KP6PNF.js} +6 -6
  153. package/dist/{chunk-G5EDYVSE.js → chunk-ZK2WT532.js} +5 -5
  154. package/dist/{chunk-SFCD6OU7.js → chunk-ZNVBCKMV.js} +2 -2
  155. package/dist/{chunk-BU2ABHFW.js → chunk-ZOFNZLAA.js} +4 -4
  156. package/dist/{chunk-X2RP4TO5.js → chunk-ZVJKHGE5.js} +7 -7
  157. package/dist/classified/index.js +5 -5
  158. package/dist/{classified-marker-KHDOYIJB.js → classified-marker-7HXDMYHI.js} +3 -3
  159. package/dist/collection-facade-V63BEBGU.js +41 -0
  160. package/dist/{computed-XMFTHAXV.js → computed-LZLSYOPG.js} +3 -3
  161. package/dist/consent/index.js +8 -8
  162. package/dist/cover/index.js +8 -8
  163. package/dist/custody/index.js +12 -12
  164. package/dist/{dead-filter-CXV5NS67.js → dead-filter-PZIJ4F4G.js} +10 -10
  165. package/dist/debug/index.js +7 -7
  166. package/dist/delegation-7SSGIETH.js +26 -0
  167. package/dist/derivations/index.js +22 -22
  168. package/dist/derive-IMI3BMDS.js +20 -0
  169. package/dist/directory/index.js +9 -9
  170. package/dist/{dispatch-2MQFMEGY.js → dispatch-4BUYPWMJ.js} +19 -19
  171. package/dist/{dispatch-OFDA4WQV.js → dispatch-KOPDDPEQ.js} +5 -5
  172. package/dist/executor-7SY3M6TZ.js +8 -0
  173. package/dist/executor-SNHW4ELF.js +35 -0
  174. package/dist/executor-Z3IKK7G3.js +8 -0
  175. package/dist/export-accessible-O7DIVFUO.js +22 -0
  176. package/dist/extract-partition-ELZEJKXM.js +35 -0
  177. package/dist/{fanout-sidecar-BO67PCPO.js → fanout-sidecar-FYDRL7F3.js} +8 -8
  178. package/dist/find-KWB2RYWJ.js +10 -0
  179. package/dist/forget/index.js +8 -8
  180. package/dist/guards/index.js +4 -4
  181. package/dist/history/index.js +15 -13
  182. package/dist/history/index.js.map +1 -1
  183. package/dist/i18n/index.js +13 -13
  184. package/dist/index.d.ts +3 -2
  185. package/dist/index.js +111 -107
  186. package/dist/index.js.map +1 -1
  187. package/dist/indexing/index.js +5 -5
  188. package/dist/introspection/index.js +10 -10
  189. package/dist/issue-5ZHXK4HJ.js +19 -0
  190. package/dist/kernel/collection.d.ts +85 -6
  191. package/dist/kernel/constants.d.ts +7 -0
  192. package/dist/kernel/errors.d.ts +9 -0
  193. package/dist/kernel/merge-authority.d.ts +5 -1
  194. package/dist/kernel/noydb.d.ts +116 -21
  195. package/dist/kernel/rejection-seal.d.ts +13 -0
  196. package/dist/kernel/sync-wiring.d.ts +55 -0
  197. package/dist/kernel/types.d.ts +366 -8
  198. package/dist/kernel/vault.d.ts +39 -5
  199. package/dist/{ledger-MSJGWKGW.js → ledger-UFJCB6T5.js} +10 -10
  200. package/dist/liberate-OEOSNNFH.js +25 -0
  201. package/dist/{link-set-QXXSPPHL.js → link-set-KMUBFN2L.js} +10 -10
  202. package/dist/{managed-secret-VSK7ANQI.js → managed-secret-H5WYSJ46.js} +9 -9
  203. package/dist/materialized-views/index.js +25 -25
  204. package/dist/{migrate-cek-GEBFYBDC.js → migrate-cek-SPESQAAO.js} +2 -2
  205. package/dist/money/index.js +5 -5
  206. package/dist/noydb-QDZ4QIKO.js +100 -0
  207. package/dist/on/index.js +12 -12
  208. package/dist/overlay-views/index.js +4 -4
  209. package/dist/periods/index.js +11 -11
  210. package/dist/pod/index.js +66 -64
  211. package/dist/{pod-handle-YE7CT66T.js → pod-handle-GJLCOUGK.js} +8 -8
  212. package/dist/policy/index.js +9 -9
  213. package/dist/port/at/index.d.ts +1 -1
  214. package/dist/port/by/index.d.ts +1 -1
  215. package/dist/port/on/index.d.ts +1 -1
  216. package/dist/port/with/admission-authority.d.ts +34 -0
  217. package/dist/port/with/broker-strategy.d.ts +10 -0
  218. package/dist/port/with/rejection-courier.d.ts +37 -0
  219. package/dist/port/with/restore-host.d.ts +33 -0
  220. package/dist/port/with/service-bus.d.ts +18 -0
  221. package/dist/port/with/team-strategy.d.ts +2 -2
  222. package/dist/port/with/write-hooks.d.ts +2 -0
  223. package/dist/portability/index.js +8 -8
  224. package/dist/{post-register-QC5TEAW3.js → post-register-2AC2STHC.js} +6 -6
  225. package/dist/query/all/index.js +15 -15
  226. package/dist/query/index.js +7 -7
  227. package/dist/query/live/index.js +7 -7
  228. package/dist/query/reduce/index.js +10 -10
  229. package/dist/query/relate/index.js +9 -9
  230. package/dist/reduce/index.js +8 -8
  231. package/dist/register-PIORIMMR.js +30 -0
  232. package/dist/registry-BIMICFUH.js +23 -0
  233. package/dist/registry-JGWLW53D.js +35 -0
  234. package/dist/registry-SELCBYEQ.js +8 -0
  235. package/dist/registry-W327UNYH.js +8 -0
  236. package/dist/request-withdrawal-K3SXXODI.js +28 -0
  237. package/dist/restore-to-OOPKLAPU.js +66 -0
  238. package/dist/restore-to-OOPKLAPU.js.map +1 -0
  239. package/dist/{reveal-YQTRNQFH.js → reveal-UAPBG743.js} +7 -7
  240. package/dist/revoke-6AFVXTWF.js +24 -0
  241. package/dist/satellites/index.js +1 -1
  242. package/dist/schema-update/index.js +2 -2
  243. package/dist/sealed-record/index.js +11 -11
  244. package/dist/search/index.js +4 -4
  245. package/dist/{seed-JMQTRKRE.js → seed-BVYDPVIW.js} +33 -18
  246. package/dist/seed-BVYDPVIW.js.map +1 -0
  247. package/dist/sequence/index.js +8 -8
  248. package/dist/session/index.js +8 -8
  249. package/dist/shadow/index.js +2 -2
  250. package/dist/signer-TW5MAQJP.js +23 -0
  251. package/dist/snapshots/index.js +9 -9
  252. package/dist/{stale-SKV33PBU.js → stale-CROGJBIJ.js} +9 -9
  253. package/dist/storage-SO2L2Z5J.js +21 -0
  254. package/dist/{store-coordination-provider-Z6HKPOGM.js → store-coordination-provider-2YD2PTTP.js} +9 -9
  255. package/dist/sync/index.js +16 -16
  256. package/dist/sync/index.js.map +1 -1
  257. package/dist/team/index.js +15 -15
  258. package/dist/tiers/index.js +10 -10
  259. package/dist/to/index.js +2 -2
  260. package/dist/transactions/index.js +3 -3
  261. package/dist/util/index.js +1 -1
  262. package/dist/vault-head/index.js +7 -7
  263. package/dist/{verify-KWQIWLGH.js → verify-QWO5UKD6.js} +7 -7
  264. package/dist/walk-3KEOL7BY.js +20 -0
  265. package/dist/with-audit/guards/types.d.ts +2 -0
  266. package/dist/with-audit/tiers/index.d.ts +5 -5
  267. package/dist/with-commit/history/history.d.ts +16 -0
  268. package/dist/with-commit/history/restore-to.d.ts +40 -0
  269. package/dist/with-party/broker/seed.d.ts +4 -0
  270. package/dist/with-party/custody/strategy.d.ts +2 -2
  271. package/dist/with-party/team/delegation.d.ts +41 -11
  272. package/dist/with-party/team/index.d.ts +2 -0
  273. package/dist/with-party/team/keyring.d.ts +133 -3
  274. package/dist/with-party/team/managed-secret.d.ts +1 -1
  275. package/dist/with-party/team/noydb-facade.d.ts +14 -2
  276. package/dist/with-party/team/roster-tag.d.ts +1 -1
  277. package/dist/with-pod/backup.d.ts +9 -17
  278. package/dist/with-sync/active.d.ts +28 -1
  279. package/dist/with-sync/engine.d.ts +59 -2
  280. package/dist/with-sync/index.d.ts +1 -0
  281. package/dist/with-sync/reserved-mirror.d.ts +27 -4
  282. package/dist/with-sync/strategy.d.ts +2 -0
  283. package/dist/withdraw-accessible-OZU525ND.js +25 -0
  284. package/dist/withdraw-accessible-OZU525ND.js.map +1 -0
  285. package/package.json +3 -3
  286. package/dist/api-MSJXVYQG.js +0 -18
  287. package/dist/backup-7RKNZMQO.js.map +0 -1
  288. package/dist/chunk-2A56DSRI.js.map +0 -1
  289. package/dist/chunk-2ELOCEXE.js.map +0 -1
  290. package/dist/chunk-45VHWE4C.js.map +0 -1
  291. package/dist/chunk-72XBVN4J.js.map +0 -1
  292. package/dist/chunk-APFFJN5T.js.map +0 -1
  293. package/dist/chunk-CAD7N6HQ.js.map +0 -1
  294. package/dist/chunk-CB4467G3.js.map +0 -1
  295. package/dist/chunk-FSQNGPHH.js.map +0 -1
  296. package/dist/chunk-GOJQ5DZA.js.map +0 -1
  297. package/dist/chunk-JA25QG5M.js.map +0 -1
  298. package/dist/chunk-JBMMWYOH.js.map +0 -1
  299. package/dist/chunk-VSUQI5Q6.js.map +0 -1
  300. package/dist/chunk-XKBTJGFP.js.map +0 -1
  301. package/dist/chunk-Z3ZXVB2Y.js.map +0 -1
  302. package/dist/collection-facade-LZIF7GWD.js +0 -41
  303. package/dist/delegation-ONLM4JFI.js.map +0 -1
  304. package/dist/derive-3YSIS36W.js +0 -20
  305. package/dist/executor-E6YDJ7YA.js +0 -8
  306. package/dist/executor-NJX3YQQ4.js +0 -35
  307. package/dist/executor-WWM3DD4P.js +0 -8
  308. package/dist/export-accessible-RLHU5G4W.js +0 -22
  309. package/dist/extract-partition-QII2EDCS.js +0 -35
  310. package/dist/find-6M7GYDUZ.js +0 -10
  311. package/dist/issue-LPEEEMPP.js +0 -19
  312. package/dist/liberate-LEKDYKTC.js +0 -25
  313. package/dist/noydb-F2AUF6KL.js +0 -98
  314. package/dist/register-SN72QALV.js +0 -30
  315. package/dist/registry-253FF7C6.js +0 -35
  316. package/dist/registry-3AZWQTDT.js +0 -23
  317. package/dist/registry-7UEBTHWG.js +0 -8
  318. package/dist/registry-IVJ67NFQ.js +0 -8
  319. package/dist/request-withdrawal-UKVJZKX2.js +0 -28
  320. package/dist/revoke-G2KXJQA5.js +0 -24
  321. package/dist/seed-JMQTRKRE.js.map +0 -1
  322. package/dist/signer-IUIYR3CX.js +0 -23
  323. package/dist/storage-NPBYP2SM.js +0 -21
  324. package/dist/walk-F4OLXI5H.js +0 -20
  325. package/dist/withdraw-accessible-ZKPLZ66E.js +0 -25
  326. /package/dist/{api-MSJXVYQG.js.map → api-H4B7ZQXP.js.map} +0 -0
  327. /package/dist/{capsule-57BDK7LG.js.map → capsule-YQKQZPH7.js.map} +0 -0
  328. /package/dist/{chunk-AJFPAHMW.js.map → chunk-27NCEPKM.js.map} +0 -0
  329. /package/dist/{chunk-PGC35KXE.js.map → chunk-2IASHJPS.js.map} +0 -0
  330. /package/dist/{chunk-NYJBYVBG.js.map → chunk-2ODEFG6K.js.map} +0 -0
  331. /package/dist/{chunk-7BMOS4JQ.js.map → chunk-2QH3I7QC.js.map} +0 -0
  332. /package/dist/{chunk-IVMFIKNA.js.map → chunk-2T2TGRWE.js.map} +0 -0
  333. /package/dist/{chunk-G66YXUTY.js.map → chunk-35CNOVQE.js.map} +0 -0
  334. /package/dist/{chunk-OJU67C23.js.map → chunk-3EXQXOQ2.js.map} +0 -0
  335. /package/dist/{chunk-BJH77UY2.js.map → chunk-4KYKRYRT.js.map} +0 -0
  336. /package/dist/{chunk-RDOEOPOI.js.map → chunk-4N4OIVK3.js.map} +0 -0
  337. /package/dist/{chunk-WHOKGHJ3.js.map → chunk-4WLI37WK.js.map} +0 -0
  338. /package/dist/{chunk-RNACRT5H.js.map → chunk-52ZFNK46.js.map} +0 -0
  339. /package/dist/{chunk-QDHHHI5Q.js.map → chunk-5SMCBPJ2.js.map} +0 -0
  340. /package/dist/{chunk-EMAWOGVH.js.map → chunk-654RE5YC.js.map} +0 -0
  341. /package/dist/{chunk-FZXRLNJO.js.map → chunk-6BEBWHNL.js.map} +0 -0
  342. /package/dist/{chunk-EUD3HQM4.js.map → chunk-6WEPFEMJ.js.map} +0 -0
  343. /package/dist/{chunk-YFFMPZPY.js.map → chunk-6WIFF46H.js.map} +0 -0
  344. /package/dist/{chunk-ZVSKSUGI.js.map → chunk-7C7OF26T.js.map} +0 -0
  345. /package/dist/{chunk-QXJXG7DN.js.map → chunk-7IV7GVOS.js.map} +0 -0
  346. /package/dist/{chunk-MQ7YWBQ5.js.map → chunk-7JRLCP2J.js.map} +0 -0
  347. /package/dist/{chunk-QSHATAXJ.js.map → chunk-7ONMS7QI.js.map} +0 -0
  348. /package/dist/{chunk-6WS35E6X.js.map → chunk-A52BK5AY.js.map} +0 -0
  349. /package/dist/{chunk-XXQ5XIYY.js.map → chunk-AMSSAOOB.js.map} +0 -0
  350. /package/dist/{chunk-3V6LZHUO.js.map → chunk-AYOQZJDB.js.map} +0 -0
  351. /package/dist/{chunk-DL6BZKP3.js.map → chunk-B3B6HV5S.js.map} +0 -0
  352. /package/dist/{chunk-5XONHAFD.js.map → chunk-B6EWMGFX.js.map} +0 -0
  353. /package/dist/{chunk-6Y5E4SJU.js.map → chunk-BMAXBTYH.js.map} +0 -0
  354. /package/dist/{chunk-LGGIFKJP.js.map → chunk-BNYDOF2Q.js.map} +0 -0
  355. /package/dist/{chunk-XXNWU5QZ.js.map → chunk-BQJ5ORU5.js.map} +0 -0
  356. /package/dist/{chunk-BYHCKX73.js.map → chunk-CLOSXHR4.js.map} +0 -0
  357. /package/dist/{chunk-5HNW4ZTA.js.map → chunk-CSAN22QG.js.map} +0 -0
  358. /package/dist/{chunk-TZYTMZZY.js.map → chunk-DL4GCSTS.js.map} +0 -0
  359. /package/dist/{chunk-EA4VDI5D.js.map → chunk-DYIR6RC3.js.map} +0 -0
  360. /package/dist/{chunk-PUBI455O.js.map → chunk-EPPAEGH5.js.map} +0 -0
  361. /package/dist/{chunk-BNFNQNEP.js.map → chunk-F7X7MPK4.js.map} +0 -0
  362. /package/dist/{chunk-SNM7LSYG.js.map → chunk-FUHUGKDN.js.map} +0 -0
  363. /package/dist/{chunk-D4V5JJAK.js.map → chunk-GHMINSER.js.map} +0 -0
  364. /package/dist/{chunk-QGFEBNHO.js.map → chunk-GZISWBCJ.js.map} +0 -0
  365. /package/dist/{chunk-OM3SEDI4.js.map → chunk-HTRLQ4ZZ.js.map} +0 -0
  366. /package/dist/{chunk-SWXLZ4HX.js.map → chunk-ICHHNI5E.js.map} +0 -0
  367. /package/dist/{chunk-K673OO6B.js.map → chunk-ID4ZBC3X.js.map} +0 -0
  368. /package/dist/{chunk-H3YM66EI.js.map → chunk-IF2M43G4.js.map} +0 -0
  369. /package/dist/{chunk-QGSNJD3B.js.map → chunk-IFUYLIEY.js.map} +0 -0
  370. /package/dist/{chunk-D5A3GCZ4.js.map → chunk-IPF5ORDI.js.map} +0 -0
  371. /package/dist/{chunk-BVF3SXD7.js.map → chunk-KBIS64X4.js.map} +0 -0
  372. /package/dist/{chunk-RIZTZJX6.js.map → chunk-LJ744WXU.js.map} +0 -0
  373. /package/dist/{chunk-L5A3KR7R.js.map → chunk-LUQBG637.js.map} +0 -0
  374. /package/dist/{chunk-6QLCS7ET.js.map → chunk-LZN6DTFI.js.map} +0 -0
  375. /package/dist/{chunk-NIXRB5BP.js.map → chunk-MMWX5OT5.js.map} +0 -0
  376. /package/dist/{chunk-UOZOWN73.js.map → chunk-ND6S2DKC.js.map} +0 -0
  377. /package/dist/{chunk-WFWFXDNS.js.map → chunk-NHEKQWFI.js.map} +0 -0
  378. /package/dist/{chunk-2ZFD2UJC.js.map → chunk-NIUHKKMM.js.map} +0 -0
  379. /package/dist/{chunk-XA34THLF.js.map → chunk-NK4LGBGQ.js.map} +0 -0
  380. /package/dist/{chunk-JSWKVZCR.js.map → chunk-NUZ7ROUZ.js.map} +0 -0
  381. /package/dist/{chunk-DHU2AQ6T.js.map → chunk-O3NGOHXQ.js.map} +0 -0
  382. /package/dist/{chunk-ZBUAX4EF.js.map → chunk-O6VOR4NH.js.map} +0 -0
  383. /package/dist/{chunk-JZ4EDEIP.js.map → chunk-ODBOHPZU.js.map} +0 -0
  384. /package/dist/{chunk-5UUJE4FP.js.map → chunk-OK44MD3C.js.map} +0 -0
  385. /package/dist/{chunk-ECGXA4LT.js.map → chunk-OR3OHKU6.js.map} +0 -0
  386. /package/dist/{chunk-ZWF3EWZA.js.map → chunk-P6FATPXQ.js.map} +0 -0
  387. /package/dist/{chunk-PCYPXLEX.js.map → chunk-PBEHTFUG.js.map} +0 -0
  388. /package/dist/{chunk-7CT6SX4M.js.map → chunk-PFHDQY5L.js.map} +0 -0
  389. /package/dist/{chunk-PTJY5R3O.js.map → chunk-PIO6NW7O.js.map} +0 -0
  390. /package/dist/{chunk-TMIJAR2X.js.map → chunk-PREYKC76.js.map} +0 -0
  391. /package/dist/{chunk-ZHQJAV6D.js.map → chunk-PU5ZEV65.js.map} +0 -0
  392. /package/dist/{chunk-UNSQZSZP.js.map → chunk-PWAMX5KU.js.map} +0 -0
  393. /package/dist/{chunk-GETUTTZU.js.map → chunk-PZN76MMV.js.map} +0 -0
  394. /package/dist/{chunk-ABU6A4Z5.js.map → chunk-Q4DBU5RM.js.map} +0 -0
  395. /package/dist/{chunk-2WJKJZSO.js.map → chunk-QHG7GQKM.js.map} +0 -0
  396. /package/dist/{chunk-UAKY6E4N.js.map → chunk-QNOWNCZS.js.map} +0 -0
  397. /package/dist/{chunk-JPSL5GIZ.js.map → chunk-QQLXKDGC.js.map} +0 -0
  398. /package/dist/{chunk-OK57EATL.js.map → chunk-R4GLRJ55.js.map} +0 -0
  399. /package/dist/{chunk-B65CC6Z6.js.map → chunk-RF5WDM25.js.map} +0 -0
  400. /package/dist/{chunk-G46JSSVX.js.map → chunk-RKBCUP5D.js.map} +0 -0
  401. /package/dist/{chunk-GCUMOKTN.js.map → chunk-S2ORTQGS.js.map} +0 -0
  402. /package/dist/{chunk-MRJDLXI3.js.map → chunk-SVXFCCSX.js.map} +0 -0
  403. /package/dist/{chunk-BUE7R3B5.js.map → chunk-SXPLIRQH.js.map} +0 -0
  404. /package/dist/{chunk-5LMCVBMY.js.map → chunk-T5EXREMW.js.map} +0 -0
  405. /package/dist/{chunk-PT2YCQVK.js.map → chunk-TBVDI3LY.js.map} +0 -0
  406. /package/dist/{chunk-BMHQHH7Q.js.map → chunk-TLIFNRU5.js.map} +0 -0
  407. /package/dist/{chunk-YKGJ44Z7.js.map → chunk-TU6ZJTYT.js.map} +0 -0
  408. /package/dist/{chunk-55P6OBB7.js.map → chunk-U43RSPPX.js.map} +0 -0
  409. /package/dist/{chunk-K7RW7FI4.js.map → chunk-UADW5NOU.js.map} +0 -0
  410. /package/dist/{chunk-GRS2HIV6.js.map → chunk-UMV5GBTJ.js.map} +0 -0
  411. /package/dist/{chunk-4UIP3QNW.js.map → chunk-UNAMWK2Q.js.map} +0 -0
  412. /package/dist/{chunk-J4KAPKBJ.js.map → chunk-UORWAG7K.js.map} +0 -0
  413. /package/dist/{chunk-V55JASXO.js.map → chunk-UQRKAM2R.js.map} +0 -0
  414. /package/dist/{chunk-ZMVSKYTJ.js.map → chunk-VLRY2UH4.js.map} +0 -0
  415. /package/dist/{chunk-SPPOUJLN.js.map → chunk-VZFTON37.js.map} +0 -0
  416. /package/dist/{chunk-YQFBH5ZJ.js.map → chunk-WQUIJPN4.js.map} +0 -0
  417. /package/dist/{chunk-NZULV7LK.js.map → chunk-WVQDY3UM.js.map} +0 -0
  418. /package/dist/{chunk-3Y5JLSXS.js.map → chunk-X5RGG3ZW.js.map} +0 -0
  419. /package/dist/{chunk-PFCTSXHU.js.map → chunk-X6Z2SIRF.js.map} +0 -0
  420. /package/dist/{chunk-UHFGK6YA.js.map → chunk-XQGKS4OW.js.map} +0 -0
  421. /package/dist/{chunk-L2F3CFCH.js.map → chunk-Y22JWHCP.js.map} +0 -0
  422. /package/dist/{chunk-C53ER7AG.js.map → chunk-YVA6UPRN.js.map} +0 -0
  423. /package/dist/{chunk-226V6XXJ.js.map → chunk-Z2KP6PNF.js.map} +0 -0
  424. /package/dist/{chunk-G5EDYVSE.js.map → chunk-ZK2WT532.js.map} +0 -0
  425. /package/dist/{chunk-SFCD6OU7.js.map → chunk-ZNVBCKMV.js.map} +0 -0
  426. /package/dist/{chunk-BU2ABHFW.js.map → chunk-ZOFNZLAA.js.map} +0 -0
  427. /package/dist/{chunk-X2RP4TO5.js.map → chunk-ZVJKHGE5.js.map} +0 -0
  428. /package/dist/{classified-marker-KHDOYIJB.js.map → classified-marker-7HXDMYHI.js.map} +0 -0
  429. /package/dist/{collection-facade-LZIF7GWD.js.map → collection-facade-V63BEBGU.js.map} +0 -0
  430. /package/dist/{computed-XMFTHAXV.js.map → computed-LZLSYOPG.js.map} +0 -0
  431. /package/dist/{dead-filter-CXV5NS67.js.map → dead-filter-PZIJ4F4G.js.map} +0 -0
  432. /package/dist/{derive-3YSIS36W.js.map → delegation-7SSGIETH.js.map} +0 -0
  433. /package/dist/{executor-E6YDJ7YA.js.map → derive-IMI3BMDS.js.map} +0 -0
  434. /package/dist/{dispatch-2MQFMEGY.js.map → dispatch-4BUYPWMJ.js.map} +0 -0
  435. /package/dist/{dispatch-OFDA4WQV.js.map → dispatch-KOPDDPEQ.js.map} +0 -0
  436. /package/dist/{executor-NJX3YQQ4.js.map → executor-7SY3M6TZ.js.map} +0 -0
  437. /package/dist/{executor-WWM3DD4P.js.map → executor-SNHW4ELF.js.map} +0 -0
  438. /package/dist/{export-accessible-RLHU5G4W.js.map → executor-Z3IKK7G3.js.map} +0 -0
  439. /package/dist/{extract-partition-QII2EDCS.js.map → export-accessible-O7DIVFUO.js.map} +0 -0
  440. /package/dist/{find-6M7GYDUZ.js.map → extract-partition-ELZEJKXM.js.map} +0 -0
  441. /package/dist/{fanout-sidecar-BO67PCPO.js.map → fanout-sidecar-FYDRL7F3.js.map} +0 -0
  442. /package/dist/{issue-LPEEEMPP.js.map → find-KWB2RYWJ.js.map} +0 -0
  443. /package/dist/{ledger-MSJGWKGW.js.map → issue-5ZHXK4HJ.js.map} +0 -0
  444. /package/dist/{liberate-LEKDYKTC.js.map → ledger-UFJCB6T5.js.map} +0 -0
  445. /package/dist/{link-set-QXXSPPHL.js.map → liberate-OEOSNNFH.js.map} +0 -0
  446. /package/dist/{managed-secret-VSK7ANQI.js.map → link-set-KMUBFN2L.js.map} +0 -0
  447. /package/dist/{noydb-F2AUF6KL.js.map → managed-secret-H5WYSJ46.js.map} +0 -0
  448. /package/dist/{migrate-cek-GEBFYBDC.js.map → migrate-cek-SPESQAAO.js.map} +0 -0
  449. /package/dist/{register-SN72QALV.js.map → noydb-QDZ4QIKO.js.map} +0 -0
  450. /package/dist/{pod-handle-YE7CT66T.js.map → pod-handle-GJLCOUGK.js.map} +0 -0
  451. /package/dist/{post-register-QC5TEAW3.js.map → post-register-2AC2STHC.js.map} +0 -0
  452. /package/dist/{registry-253FF7C6.js.map → register-PIORIMMR.js.map} +0 -0
  453. /package/dist/{registry-3AZWQTDT.js.map → registry-BIMICFUH.js.map} +0 -0
  454. /package/dist/{registry-7UEBTHWG.js.map → registry-JGWLW53D.js.map} +0 -0
  455. /package/dist/{registry-IVJ67NFQ.js.map → registry-SELCBYEQ.js.map} +0 -0
  456. /package/dist/{request-withdrawal-UKVJZKX2.js.map → registry-W327UNYH.js.map} +0 -0
  457. /package/dist/{revoke-G2KXJQA5.js.map → request-withdrawal-K3SXXODI.js.map} +0 -0
  458. /package/dist/{reveal-YQTRNQFH.js.map → reveal-UAPBG743.js.map} +0 -0
  459. /package/dist/{signer-IUIYR3CX.js.map → revoke-6AFVXTWF.js.map} +0 -0
  460. /package/dist/{stale-SKV33PBU.js.map → signer-TW5MAQJP.js.map} +0 -0
  461. /package/dist/{storage-NPBYP2SM.js.map → stale-CROGJBIJ.js.map} +0 -0
  462. /package/dist/{walk-F4OLXI5H.js.map → storage-SO2L2Z5J.js.map} +0 -0
  463. /package/dist/{store-coordination-provider-Z6HKPOGM.js.map → store-coordination-provider-2YD2PTTP.js.map} +0 -0
  464. /package/dist/{verify-KWQIWLGH.js.map → verify-QWO5UKD6.js.map} +0 -0
  465. /package/dist/{withdraw-accessible-ZKPLZ66E.js.map → walk-3KEOL7BY.js.map} +0 -0
@@ -5,13 +5,13 @@ import {
5
5
  readDirectoryConfig,
6
6
  readUserVisibility,
7
7
  saveUserEnvelope
8
- } from "./chunk-FZXRLNJO.js";
8
+ } from "./chunk-6BEBWHNL.js";
9
9
  import {
10
10
  keyringClearance
11
- } from "./chunk-UHFGK6YA.js";
11
+ } from "./chunk-XQGKS4OW.js";
12
12
  import {
13
13
  parseDekKey
14
- } from "./chunk-RIZTZJX6.js";
14
+ } from "./chunk-LJ744WXU.js";
15
15
  import {
16
16
  base64ToBuffer,
17
17
  bufferToBase64,
@@ -26,26 +26,38 @@ import {
26
26
  encrypt,
27
27
  encryptBytes,
28
28
  envelopeOpensUnderAny,
29
+ exportDekSet,
30
+ exportRecipientPrivateKeyPkcs8,
31
+ exportRecipientPublicKeySpki,
29
32
  generateDEK,
33
+ generateRecipientKeyPair,
30
34
  generateSalt,
31
35
  hasSealedBody,
36
+ importDekSet,
37
+ importRecipientKeyPair,
38
+ importRecipientPublicKeySpki,
39
+ importTransferKey,
32
40
  mintCanary,
41
+ recipientUnwrap,
42
+ recipientWrap,
33
43
  rekeyBlobSet,
34
44
  rekeyEnvelopeIfNeeded,
35
45
  unwrapKey,
36
46
  wrapKey
37
- } from "./chunk-4J3MNVVX.js";
47
+ } from "./chunk-WRLWEYHY.js";
38
48
  import {
39
49
  NOYDB_KEYRING_VERSION
40
- } from "./chunk-2ELOCEXE.js";
50
+ } from "./chunk-URGHKZPL.js";
41
51
  import {
42
52
  BLOB_ADDRESS_KEY_ID,
43
53
  DirectoryDisabledError,
44
54
  EchoCeremonyRequiredError,
55
+ INBOX_KEY_ID,
45
56
  InvalidKeyError,
46
57
  KeyringCorruptError,
47
58
  KeyringExpiredError,
48
59
  KeyringTamperedError,
60
+ MemberInboxMissingError,
49
61
  NoAccessError,
50
62
  NoydbError,
51
63
  PermissionDeniedError,
@@ -54,8 +66,9 @@ import {
54
66
  TamperedError,
55
67
  USER_ENVELOPE_COLLECTION,
56
68
  ValidationError,
57
- WrongPromptError
58
- } from "./chunk-VSUQI5Q6.js";
69
+ WrongPromptError,
70
+ isConflictError
71
+ } from "./chunk-2RH5SEY7.js";
59
72
 
60
73
  // src/with-party/team/roster-epoch.ts
61
74
  function assertRosterEpochCurrent(found, expected, userId) {
@@ -141,7 +154,19 @@ function rosterCanonical(file) {
141
154
  // which is the difference between a caught tamper and a silent one, for a
142
155
  // reader who trusted the cheap number. It is defence in depth for a field
143
156
  // whose whole risk is being read instead of the DEK map.
144
- ...file.clearance !== void 0 ? { clearance: file.clearance } : {}
157
+ ...file.clearance !== void 0 ? { clearance: file.clearance } : {},
158
+ // core#96 — the inbox PUBLIC KEY and the PENDING SLOT NAMES, bound ONLY
159
+ // WHEN PRESENT (same conditional spread, same reason as the two above).
160
+ //
161
+ // `inbox_pub`: an amend seals DEKs to this key, so a store that could swap
162
+ // it for its own would read every DEK delivered afterwards. Bound, a swap
163
+ // fails the tag before anything is sealed to it.
164
+ // `inbox_slots`: `revoke` rotates what the target's file NAMES; a pending
165
+ // delivery is a DEK the target may hold, so its names must be as
166
+ // unstrippable as `dek_slots`. Contents are self-authenticating (AES-GCM
167
+ // under a CEK only the private half unwraps) and stay out.
168
+ ...file.inbox_key !== void 0 ? { inbox_pub: file.inbox_key.pub } : {},
169
+ ...file.inbox !== void 0 ? { inbox_slots: [...new Set(file.inbox.flatMap((box) => box.slots))].sort() } : {}
145
170
  });
146
171
  }
147
172
  async function mintRosterTag(file, rosterKey) {
@@ -481,7 +506,10 @@ async function loadKeyring(store, vault, opts) {
481
506
  }
482
507
  const { file: keyringFile } = found;
483
508
  const salt = base64ToBuffer(keyringFile.salt);
484
- const kek = await deriveKekForKeyring(keyringFile, secret, salt);
509
+ if (opts.kek === void 0 && secret === void 0) {
510
+ throw new ValidationError(`loadKeyring: one of \`secret\` / \`kek\` is required (user "${userId}").`);
511
+ }
512
+ const kek = opts.kek ?? await deriveKekForKeyring(keyringFile, secret, salt);
485
513
  if (keyringFile.canary === void 0) {
486
514
  throw new KeyringTamperedError({ userId, reason: "canary-missing" });
487
515
  }
@@ -520,7 +548,13 @@ async function loadKeyring(store, vault, opts) {
520
548
  }
521
549
  await assertRosterAuthenticated(keyringFile, deks, userId);
522
550
  assertKeyringNotExpired(keyringFile);
523
- return {
551
+ let drained = false;
552
+ const inboxKeyAes = deks.get(INBOX_KEY_ID);
553
+ if (keyringFile.inbox !== void 0 && keyringFile.inbox.length > 0 && inboxKeyAes !== void 0) {
554
+ for (const [name, dek] of await openInbox(keyringFile, inboxKeyAes)) deks.set(name, dek);
555
+ drained = true;
556
+ }
557
+ const unlocked = {
524
558
  userId: keyringFile.user_id,
525
559
  displayName: keyringFile.display_name,
526
560
  role: keyringFile.role,
@@ -534,6 +568,8 @@ async function loadKeyring(store, vault, opts) {
534
568
  ...keyringFile.import_capability !== void 0 && { importCapability: keyringFile.import_capability },
535
569
  ...keyringFile.policy !== void 0 && { policy: keyringFile.policy }
536
570
  };
571
+ if (drained) await persistKeyring(store, vault, unlocked);
572
+ return unlocked;
537
573
  }
538
574
  async function assertKeyringOpenAllowed(store, vault, userId, create) {
539
575
  const keyringUsers = await store.list(vault, "_keyring");
@@ -566,6 +602,7 @@ async function createOwnerKeyring(store, vault, opts) {
566
602
  const wrappedRosterKey = await wrapKey(rosterKey, kek);
567
603
  const blobAddressKey = await generateDEK();
568
604
  const wrappedBlobAddressKey = await wrapKey(blobAddressKey, kek);
605
+ const inbox = await mintInboxKey(kek);
569
606
  const canary = await mintKeyringCanary(kek);
570
607
  const authority = {
571
608
  user_id: userId,
@@ -579,8 +616,11 @@ async function createOwnerKeyring(store, vault, opts) {
579
616
  deks: {
580
617
  [USER_ENVELOPE_COLLECTION]: wrappedUserEnvelopeDek,
581
618
  [ROSTER_KEY_ID]: wrappedRosterKey,
582
- [BLOB_ADDRESS_KEY_ID]: wrappedBlobAddressKey
583
- }
619
+ [BLOB_ADDRESS_KEY_ID]: wrappedBlobAddressKey,
620
+ [INBOX_KEY_ID]: inbox.wrappedInboxKey
621
+ },
622
+ inbox_key: inbox.inboxKey
623
+ // core#65 — tag-bound, like every other keyring's
584
624
  };
585
625
  const withEpoch = stampAuthority(authorityWithDeks, void 0);
586
626
  const keyringFile = {
@@ -600,7 +640,7 @@ async function createOwnerKeyring(store, vault, opts) {
600
640
  )
601
641
  } : {}
602
642
  };
603
- await writeKeyringFile(store, vault, userId, keyringFile);
643
+ await writeKeyringFile(store, vault, userId, keyringFile, "create");
604
644
  return {
605
645
  userId,
606
646
  displayName: userId,
@@ -608,13 +648,41 @@ async function createOwnerKeyring(store, vault, opts) {
608
648
  permissions: {},
609
649
  deks: /* @__PURE__ */ new Map([
610
650
  [USER_ENVELOPE_COLLECTION, userEnvelopeDek],
611
- [ROSTER_KEY_ID, rosterKey]
651
+ [ROSTER_KEY_ID, rosterKey],
652
+ [INBOX_KEY_ID, inbox.inboxKeyAes]
653
+ // core#65 — in the SESSION too, not only the file: it opens this owner's own inbox
612
654
  ]),
613
655
  kek,
614
656
  salt,
615
657
  authenticators: []
616
658
  };
617
659
  }
660
+ function selectGranteeDekNames(role, requested, permissions, callerDeks) {
661
+ const mayHoldSecrets = role === "owner" || role === "admin";
662
+ const admits = (name) => name !== INBOX_KEY_ID && name !== BROKER_MEMBER_COLLECTION && !(isSecretBearingReservedCollection(name) && !mayHoldSecrets);
663
+ const selected = /* @__PURE__ */ new Set();
664
+ for (const collName of Object.keys(permissions)) {
665
+ if (collName === PERMISSION_WILDCARD) continue;
666
+ if (admits(collName) && callerDeks.has(collName)) selected.add(collName);
667
+ }
668
+ const wrapAll = role === "owner" || role === "admin" || role === "custodian" || role === "viewer" || permissionsAreWildcard(requested);
669
+ for (const name of callerDeks.keys()) {
670
+ if ((wrapAll || name.startsWith("_")) && admits(name)) selected.add(name);
671
+ }
672
+ return [...selected];
673
+ }
674
+ async function mintMissingDeksForGrant(store, vault, callerKeyring, permissions, mayHoldSecrets) {
675
+ let minted = false;
676
+ for (const collName of Object.keys(permissions)) {
677
+ if (collName === PERMISSION_WILDCARD) continue;
678
+ if (isSecretBearingReservedCollection(collName) && !mayHoldSecrets) continue;
679
+ if (callerKeyring.deks.has(collName)) continue;
680
+ if (await collectionHasRecords(store, vault, collName)) continue;
681
+ callerKeyring.deks.set(collName, await generateDEK());
682
+ minted = true;
683
+ }
684
+ return minted;
685
+ }
618
686
  async function grant(store, vault, callerKeyring, options) {
619
687
  if (!callerKeyring.kek) {
620
688
  throw new ValidationError(
@@ -640,38 +708,13 @@ async function grant(store, vault, callerKeyring, options) {
640
708
  const newSalt = generateSalt();
641
709
  const newKek = await deriveKey(options.secret, newSalt);
642
710
  const granteeMayHoldSecrets = options.role === "owner" || options.role === "admin";
643
- let mintedForGrant = false;
644
- for (const collName of Object.keys(permissions)) {
645
- if (collName === PERMISSION_WILDCARD) continue;
646
- if (isSecretBearingReservedCollection(collName) && !granteeMayHoldSecrets) continue;
647
- if (callerKeyring.deks.has(collName)) continue;
648
- if (await collectionHasRecords(store, vault, collName)) continue;
649
- callerKeyring.deks.set(collName, await generateDEK());
650
- mintedForGrant = true;
651
- }
711
+ const mintedForGrant = await mintMissingDeksForGrant(store, vault, callerKeyring, permissions, granteeMayHoldSecrets);
652
712
  if (mintedForGrant) await persistKeyring(store, vault, callerKeyring);
653
713
  const previousGrantFound = await readKeyringFile(store, vault, options.userId);
654
714
  const previousDekNames = previousGrantFound ? new Set(Object.keys(previousGrantFound.file.deks)) : null;
655
715
  const wrappedDeks = {};
656
- for (const collName of Object.keys(permissions)) {
657
- if (collName === PERMISSION_WILDCARD) continue;
658
- if (isSecretBearingReservedCollection(collName) && !granteeMayHoldSecrets) continue;
659
- const dek = callerKeyring.deks.get(collName);
660
- if (dek) {
661
- wrappedDeks[collName] = await wrapKey(dek, newKek);
662
- }
663
- }
664
- if (options.role === "owner" || options.role === "admin" || options.role === "custodian" || options.role === "viewer" || permissionsAreWildcard(options.permissions)) {
665
- for (const [collName, dek] of callerKeyring.deks) {
666
- if (collName in wrappedDeks) continue;
667
- if (isSecretBearingReservedCollection(collName) && !granteeMayHoldSecrets) continue;
668
- wrappedDeks[collName] = await wrapKey(dek, newKek);
669
- }
670
- }
671
- for (const [collName, dek] of callerKeyring.deks) {
672
- if (!collName.startsWith("_") || collName in wrappedDeks) continue;
673
- if (isSecretBearingReservedCollection(collName) && !granteeMayHoldSecrets) continue;
674
- wrappedDeks[collName] = await wrapKey(dek, newKek);
716
+ for (const collName of selectGranteeDekNames(options.role, options.permissions, permissions, callerKeyring.deks)) {
717
+ wrappedDeks[collName] = await wrapKey(callerKeyring.deks.get(collName), newKek);
675
718
  }
676
719
  for (const collName of Object.keys(wrappedDeks)) {
677
720
  if (!callerKeyring.deks.has(collName)) {
@@ -681,6 +724,8 @@ async function grant(store, vault, callerKeyring, options) {
681
724
  if (!granteeMayHoldSecrets) {
682
725
  wrappedDeks[BROKER_MEMBER_COLLECTION] = await wrapKey(await generateDEK(), newKek);
683
726
  }
727
+ const inbox = await mintInboxKey(newKek);
728
+ wrappedDeks[INBOX_KEY_ID] = inbox.wrappedInboxKey;
684
729
  const canary = await mintKeyringCanary(newKek);
685
730
  const authority = {
686
731
  user_id: options.userId,
@@ -691,7 +736,7 @@ async function grant(store, vault, callerKeyring, options) {
691
736
  ...options.exportCapability !== void 0 && { export_capability: options.exportCapability },
692
737
  ...options.importCapability !== void 0 && { import_capability: options.importCapability }
693
738
  };
694
- const authorityWithDeks = { ...authority, deks: wrappedDeks };
739
+ const authorityWithDeks = { ...authority, deks: wrappedDeks, inbox_key: inbox.inboxKey };
695
740
  const withEpoch = stampAuthority(authorityWithDeks, previousGrantFound?.file.roster_epoch);
696
741
  const keyringFile = {
697
742
  _noydb_keyring: NOYDB_KEYRING_VERSION,
@@ -703,13 +748,13 @@ async function grant(store, vault, callerKeyring, options) {
703
748
  // propagation loop above, so they can verify this tag on first unlock.
704
749
  roster_tag: await mintRosterTag(withEpoch, callerRosterKey)
705
750
  };
706
- await writeKeyringFile(store, vault, options.userId, keyringFile);
751
+ await writeKeyringFile(store, vault, options.userId, keyringFile, basisOf(previousGrantFound));
707
752
  if (previousDekNames !== null && options.userId !== callerKeyring.userId) {
708
753
  const dropped = [...previousDekNames].filter(
709
754
  (name) => !name.startsWith("_") && !(name in wrappedDeks)
710
755
  );
711
756
  if (dropped.length > 0) {
712
- await rotateKeys(store, vault, callerKeyring, { collections: dropped });
757
+ await rotateKeys(store, vault, callerKeyring, { collections: dropped, exclude: [options.userId] });
713
758
  }
714
759
  }
715
760
  const userEnvelopeDek = callerKeyring.deks.get(USER_ENVELOPE_COLLECTION);
@@ -724,6 +769,12 @@ async function grant(store, vault, callerKeyring, options) {
724
769
  );
725
770
  }
726
771
  }
772
+ var NON_ROTATABLE_SLOTS = /* @__PURE__ */ new Set([
773
+ ROSTER_KEY_ID,
774
+ BLOB_ADDRESS_KEY_ID,
775
+ INBOX_KEY_ID,
776
+ BROKER_MEMBER_COLLECTION
777
+ ]);
727
778
  async function findAdminDescendants(store, vault, rootUserId, rosterKey) {
728
779
  const allUserIds = await store.list(vault, "_keyring");
729
780
  const childrenByParent = /* @__PURE__ */ new Map();
@@ -757,8 +808,8 @@ async function revoke(store, vault, callerKeyring, options) {
757
808
  if (!targetFound) {
758
809
  const pending = [...callerKeyring.pendingDeks?.keys() ?? []];
759
810
  if (pending.length > 0) {
760
- await rotateKeys(store, vault, callerKeyring, { collections: pending });
761
- return;
811
+ const resumed = await rotateKeys(store, vault, callerKeyring, { collections: pending });
812
+ return { rewritten: resumed.rewritten };
762
813
  }
763
814
  throw new NoAccessError(`User "${options.userId}" has no keyring in vault "${vault}"`);
764
815
  }
@@ -796,18 +847,24 @@ async function revoke(store, vault, callerKeyring, options) {
796
847
  await deleteUserEnvelope(store, vault, userId);
797
848
  await deleteUserVisibility(store, vault, userId);
798
849
  }
799
- affectedCollections.delete(ROSTER_KEY_ID);
800
- affectedCollections.delete(BLOB_ADDRESS_KEY_ID);
850
+ for (const slot of NON_ROTATABLE_SLOTS) affectedCollections.delete(slot);
851
+ for (const slot of inboxSlots(targetKeyring)) affectedCollections.add(slot);
852
+ let rewritten = [];
801
853
  if (affectedCollections.size > 0) {
802
- const { unverified } = await rotateKeys(store, vault, callerKeyring, {
803
- collections: [...affectedCollections]
854
+ const rotation = await rotateKeys(store, vault, callerKeyring, {
855
+ collections: [...affectedCollections],
856
+ exclude: usersToRevoke
857
+ // core#100 / #1043 — never deliver to the member(s) being revoked
804
858
  });
859
+ const { unverified } = rotation;
860
+ rewritten = rotation.rewritten;
805
861
  if (unverified.length > 0) {
806
862
  console.warn(
807
863
  `[noy-db] revoke(${options.userId}): ${unverified.length} member(s) were SKIPPED by the rotation because their keyring failed roster authentication: ${unverified.map((u) => `${u.userId} (${u.reason})`).join(", ")}. The revocation itself completed. Those members cannot open the vault and did not receive the rotated keys; their keyring files need repair or removal (vLannaAi/noy-db#1114).`
808
864
  );
809
865
  }
810
866
  }
867
+ return { rewritten };
811
868
  }
812
869
  async function readKeyringForAudit(store, vault, userId) {
813
870
  const envelope = await store.get(vault, "_keyring", userId);
@@ -885,8 +942,8 @@ async function quarantineKeyring(store, vault, callerKeyring, userId) {
885
942
  await store.delete(vault, "_keyring", userId);
886
943
  await deleteUserEnvelope(store, vault, userId);
887
944
  await deleteUserVisibility(store, vault, userId);
888
- const rotated = [...callerKeyring.deks.keys()].filter((c) => c !== ROSTER_KEY_ID);
889
- const result = rotated.length > 0 ? await rotateKeys(store, vault, callerKeyring, { collections: rotated }) : { needsRegrant: [], unverified: [] };
945
+ const rotated = [...callerKeyring.deks.keys()].filter((c) => !NON_ROTATABLE_SLOTS.has(c));
946
+ const result = rotated.length > 0 ? await rotateKeys(store, vault, callerKeyring, { collections: rotated, exclude: [userId] }) : { needsRegrant: [], unverified: [], rewritten: [] };
890
947
  return {
891
948
  userId,
892
949
  reason,
@@ -920,7 +977,7 @@ async function updateKeyringIdentity(store, vault, callerKeyring, options) {
920
977
  `Role "${callerKeyring.role}" cannot promote target to role "${options.role}"`
921
978
  );
922
979
  }
923
- const edited = {
980
+ const header = {
924
981
  ...target,
925
982
  ...options.role !== void 0 && { role: options.role },
926
983
  ...options.displayName !== void 0 && {
@@ -929,9 +986,52 @@ async function updateKeyringIdentity(store, vault, callerKeyring, options) {
929
986
  },
930
987
  ...options.permissions !== void 0 && { permissions: options.permissions }
931
988
  };
989
+ const roleChanged = header.role !== target.role;
990
+ const mayHoldSecrets = header.role === "owner" || header.role === "admin";
991
+ const permissions = resolvePermissions(header.role, header.permissions);
992
+ const minted = await mintMissingDeksForGrant(store, vault, callerKeyring, permissions, mayHoldSecrets);
993
+ if (minted) await persistKeyring(store, vault, callerKeyring);
994
+ const wanted = new Set(selectGranteeDekNames(header.role, header.permissions, permissions, callerKeyring.deks));
995
+ const held = target.deks;
996
+ const pending = new Set(inboxSlots(target));
997
+ const retains = (name) => {
998
+ if (name === INBOX_KEY_ID) return true;
999
+ if (name === BROKER_MEMBER_COLLECTION) return !mayHoldSecrets && !roleChanged;
1000
+ if (wanted.has(name)) return true;
1001
+ if (!name.startsWith("_")) return false;
1002
+ return !(isSecretBearingReservedCollection(name) && !mayHoldSecrets);
1003
+ };
1004
+ const deks = {};
1005
+ for (const [name, wrapped] of Object.entries(held)) if (retains(name)) deks[name] = wrapped;
1006
+ const dropped = Object.keys(held).filter((name) => !name.startsWith("_") && !(name in deks));
1007
+ const deliver = /* @__PURE__ */ new Map();
1008
+ for (const name of wanted) {
1009
+ if (name in deks || pending.has(name)) continue;
1010
+ const dek = callerKeyring.deks.get(name);
1011
+ if (!dek) throw new PrivilegeEscalationError(name);
1012
+ deliver.set(name, dek);
1013
+ }
1014
+ for (const name of pending) if (!wanted.has(name) && !name.startsWith("_")) dropped.push(name);
1015
+ let brokerMemberDek;
1016
+ if (roleChanged && !mayHoldSecrets) {
1017
+ brokerMemberDek = await generateDEK();
1018
+ deliver.set(BROKER_MEMBER_COLLECTION, brokerMemberDek);
1019
+ }
1020
+ let inbox = target.inbox;
1021
+ if (deliver.size > 0) {
1022
+ if (target.inbox_key === void 0) throw new MemberInboxMissingError(options.userId);
1023
+ inbox = [...target.inbox ?? [], await sealInbox(target.inbox_key, deliver)];
1024
+ }
1025
+ const { inbox: _previousInbox, ...carried } = header;
1026
+ const edited = { ...carried, deks, ...inbox !== void 0 && inbox.length > 0 && { inbox } };
932
1027
  const withEpoch = stampAuthority(edited, target.roster_epoch);
933
1028
  const next = { ...withEpoch, roster_tag: await mintRosterTag(withEpoch, rosterKey) };
934
- await writeKeyringFile(store, vault, options.userId, next);
1029
+ await writeKeyringFile(store, vault, options.userId, next, basisOf(found));
1030
+ const rotate = [...new Set(dropped)].filter((name) => !name.startsWith("_"));
1031
+ if (rotate.length > 0 && options.userId !== callerKeyring.userId) {
1032
+ await rotateKeys(store, vault, callerKeyring, { collections: rotate, exclude: [options.userId] });
1033
+ }
1034
+ return { roleChanged, ...brokerMemberDek !== void 0 && { brokerMemberDek } };
935
1035
  }
936
1036
  var HISTORY_COLLECTION = "_history";
937
1037
  var LEDGER_COLLECTION = "_ledger";
@@ -984,6 +1084,12 @@ async function rotateKeys(store, vault, callerKeyring, opts) {
984
1084
  `rotateKeys: "${ROSTER_KEY_ID}" is the vault roster key, not a collection, and cannot be rotated \u2014 doing so would strip it from every other member and leave the vault unopenable. Remove it from \`collections\`.`
985
1085
  );
986
1086
  }
1087
+ for (const name of [BROKER_MEMBER_COLLECTION, INBOX_KEY_ID]) {
1088
+ if (collections.includes(name)) {
1089
+ throw new ValidationError(`rotateKeys: "${name}" is a per-member key, not a collection, and cannot be rotated. Remove it from \`collections\`.`);
1090
+ }
1091
+ }
1092
+ const rewritten = [];
987
1093
  if (callerKeyring.role === "custodian") {
988
1094
  throw new PermissionDeniedError(
989
1095
  "custodian cannot rotate keys (FR-6: re-key is an owner-only meta-capability; use the Deed owner)"
@@ -1009,6 +1115,12 @@ async function rotateKeys(store, vault, callerKeyring, opts) {
1009
1115
  for (const [name, dek] of callerKeyring.deks) if (name !== collName) others.push(dek);
1010
1116
  for (const [name, dek] of newDeks) if (name !== collName) others.push(dek);
1011
1117
  await rekeyBlobSet(store, vault, oldDek, newDek, others);
1118
+ for (const blobColl of ["_blob_index", "_blob_chunks"]) {
1119
+ for (const id of await store.list(vault, blobColl)) {
1120
+ const env = await store.get(vault, blobColl, id);
1121
+ if (env) rewritten.push({ collection: blobColl, id, version: env._v });
1122
+ }
1123
+ }
1012
1124
  }
1013
1125
  const { collection: baseColl } = parseDekKey(collName);
1014
1126
  const siblingSlotDeks = [];
@@ -1031,7 +1143,10 @@ async function rotateKeys(store, vault, callerKeyring, opts) {
1031
1143
  }
1032
1144
  throw err;
1033
1145
  }
1034
- if (newEnvelope !== null) await store.put(vault, refColl, id, newEnvelope);
1146
+ if (newEnvelope !== null) {
1147
+ await store.put(vault, refColl, id, newEnvelope);
1148
+ rewritten.push({ collection: refColl, id, version: newEnvelope._v });
1149
+ }
1035
1150
  }
1036
1151
  }
1037
1152
  for (const [collName, newDek] of newDeks) {
@@ -1056,26 +1171,37 @@ async function rotateKeys(store, vault, callerKeyring, opts) {
1056
1171
  }
1057
1172
  const updatedDeks = { ...userKeyringFile.deks };
1058
1173
  const updatedPermissions = { ...userKeyringFile.permissions };
1174
+ const deliver = /* @__PURE__ */ new Map();
1175
+ const pendingSlots = new Set(inboxSlots(userKeyringFile));
1059
1176
  for (const collName of collections) {
1177
+ const held = collName in updatedDeks || pendingSlots.has(collName);
1178
+ if (held && userKeyringFile.inbox_key !== void 0 && !opts.exclude?.includes(userId)) {
1179
+ deliver.set(collName, newDeks.get(collName));
1180
+ delete updatedDeks[collName];
1181
+ continue;
1182
+ }
1060
1183
  if (collName in updatedDeks || collName in updatedPermissions) {
1061
1184
  needsRegrant.push({ userId, collection: collName });
1062
1185
  }
1063
1186
  delete updatedDeks[collName];
1064
1187
  delete updatedPermissions[collName];
1065
1188
  }
1189
+ const inbox = deliver.size > 0 && userKeyringFile.inbox_key !== void 0 ? [...userKeyringFile.inbox ?? [], await sealInbox(userKeyringFile.inbox_key, deliver)] : userKeyringFile.inbox;
1066
1190
  const edited = {
1067
1191
  ...userKeyringFile,
1068
1192
  deks: updatedDeks,
1069
- permissions: updatedPermissions
1193
+ permissions: updatedPermissions,
1194
+ ...inbox !== void 0 && inbox.length > 0 ? { inbox } : {}
1070
1195
  };
1196
+ if (inbox === void 0 || inbox.length === 0) delete edited.inbox;
1071
1197
  const withEpoch = stampAuthority(edited, userKeyringFile.roster_epoch);
1072
1198
  const updatedKeyring = {
1073
1199
  ...withEpoch,
1074
1200
  roster_tag: await mintRosterTag(withEpoch, callerRosterKey)
1075
1201
  };
1076
- await writeKeyringFile(store, vault, userId, updatedKeyring);
1202
+ await writeKeyringFile(store, vault, userId, updatedKeyring, basisOf(userFound));
1077
1203
  }
1078
- return { needsRegrant, unverified };
1204
+ return { needsRegrant, unverified, rewritten };
1079
1205
  }
1080
1206
  async function changeSecret(store, vault, keyring, opts) {
1081
1207
  const existingFound = await readKeyringFile(store, vault, keyring.userId);
@@ -1117,7 +1243,7 @@ async function changeSecret(store, vault, keyring, opts) {
1117
1243
  canary,
1118
1244
  roster_tag: await mintRosterTag(withEpoch, rosterKey)
1119
1245
  };
1120
- await writeKeyringFile(store, vault, keyring.userId, keyringFile);
1246
+ await writeKeyringFile(store, vault, keyring.userId, keyringFile, basisOf(existingFound));
1121
1247
  return {
1122
1248
  userId: keyring.userId,
1123
1249
  displayName: keyring.displayName,
@@ -1301,8 +1427,17 @@ async function ensureCollectionDEK(store, vault, keyring) {
1301
1427
  }
1302
1428
  const dek = await generateDEK();
1303
1429
  keyring.deks.set(collectionName, dek);
1304
- await persistKeyring(store, vault, keyring);
1305
- return dek;
1430
+ for (let attempt = 0; ; attempt++) {
1431
+ try {
1432
+ await persistKeyring(store, vault, keyring);
1433
+ return keyring.deks.get(collectionName) ?? dek;
1434
+ } catch (err) {
1435
+ if (!isConflictError(err)) throw err;
1436
+ const winner = await reloadPersistedDEK(store, vault, keyring, collectionName);
1437
+ if (winner) return winner;
1438
+ if (attempt >= 5) throw err;
1439
+ }
1440
+ }
1306
1441
  })();
1307
1442
  inFlight.set(collectionName, promise);
1308
1443
  try {
@@ -1328,6 +1463,58 @@ function hasAccess(keyring, collectionName) {
1328
1463
  if (PERMISSION_WILDCARD in keyring.permissions) return true;
1329
1464
  return collectionName in keyring.permissions;
1330
1465
  }
1466
+ async function mintInboxKey(kek) {
1467
+ const inboxKey = await generateDEK();
1468
+ const pair = await generateRecipientKeyPair();
1469
+ const pub = await exportRecipientPublicKeySpki(pair);
1470
+ const priv = await exportRecipientPrivateKeyPkcs8(pair);
1471
+ try {
1472
+ const sealed = await encryptBytes(priv, inboxKey);
1473
+ return { wrappedInboxKey: await wrapKey(inboxKey, kek), inboxKeyAes: inboxKey, inboxKey: { pub: bufferToBase64(pub), priv: sealed } };
1474
+ } finally {
1475
+ priv.fill(0);
1476
+ }
1477
+ }
1478
+ function inboxSlots(file) {
1479
+ return [...new Set((file.inbox ?? []).flatMap((box) => box.slots))];
1480
+ }
1481
+ async function sealInbox(inboxKey, deks) {
1482
+ const pub = await importRecipientPublicKeySpki(base64ToBuffer(inboxKey.pub));
1483
+ const cekBytes = globalThis.crypto.getRandomValues(new Uint8Array(32));
1484
+ try {
1485
+ const cek = await importTransferKey(cekBytes);
1486
+ const payload = new TextEncoder().encode(JSON.stringify(await exportDekSet(deks)));
1487
+ const { iv, data } = await encryptBytes(payload, cek);
1488
+ const wrapped = await recipientWrap(pub, cekBytes);
1489
+ return { slots: [...deks.keys()].sort(), cek: bufferToBase64(wrapped), iv, data };
1490
+ } finally {
1491
+ cekBytes.fill(0);
1492
+ }
1493
+ }
1494
+ async function openInboxKeyPair(inboxKey, inboxKeyAes) {
1495
+ const priv = await decryptBytes(inboxKey.priv.iv, inboxKey.priv.data, inboxKeyAes);
1496
+ try {
1497
+ return await importRecipientKeyPair(priv, base64ToBuffer(inboxKey.pub));
1498
+ } finally {
1499
+ priv.fill(0);
1500
+ }
1501
+ }
1502
+ async function openInbox(file, inboxKeyAes) {
1503
+ const out = /* @__PURE__ */ new Map();
1504
+ if (!file.inbox || file.inbox.length === 0 || !file.inbox_key) return out;
1505
+ const pair = await openInboxKeyPair(file.inbox_key, inboxKeyAes);
1506
+ for (const box of file.inbox) {
1507
+ const cekBytes = await recipientUnwrap(pair, base64ToBuffer(box.cek));
1508
+ try {
1509
+ const cek = await importTransferKey(cekBytes);
1510
+ const payload = await decryptBytes(box.iv, box.data, cek);
1511
+ for (const [name, dek] of await importDekSet(JSON.parse(new TextDecoder().decode(payload)))) out.set(name, dek);
1512
+ } finally {
1513
+ cekBytes.fill(0);
1514
+ }
1515
+ }
1516
+ return out;
1517
+ }
1331
1518
  async function persistKeyring(store, vault, keyring) {
1332
1519
  if (!keyring.kek) {
1333
1520
  throw new ValidationError(
@@ -1341,6 +1528,9 @@ async function persistKeyring(store, vault, keyring) {
1341
1528
  const existingGrantedBy = existingFound?.file.granted_by;
1342
1529
  const existingCreatedAt = existingFound?.file.created_at;
1343
1530
  const existingExpiresAt = existingFound?.file.expires_at;
1531
+ const existingInboxKey = existingFound?.file.inbox_key;
1532
+ const existingInbox = existingFound?.file.inbox;
1533
+ const undrainedInbox = existingInbox !== void 0 && existingInbox.length > 0 && !inboxSlots({ inbox: existingInbox }).every((slot) => keyring.deks.has(slot));
1344
1534
  const wrappedDeks = {};
1345
1535
  for (const [collName, dek] of keyring.deks) {
1346
1536
  wrappedDeks[collName] = await wrapKey(dek, keyring.kek);
@@ -1363,7 +1553,11 @@ async function persistKeyring(store, vault, keyring) {
1363
1553
  const authorityWithDeks = {
1364
1554
  ...authority,
1365
1555
  deks: wrappedDeks,
1366
- ...Object.keys(wrappedPending).length > 0 ? { pending_deks: wrappedPending } : {}
1556
+ ...Object.keys(wrappedPending).length > 0 ? { pending_deks: wrappedPending } : {},
1557
+ // core#96 — both tag-bound (`inbox_pub`, `inbox_slots`), so they must be
1558
+ // in the object the tag is minted from, not spread in afterwards.
1559
+ ...existingInboxKey !== void 0 && { inbox_key: existingInboxKey },
1560
+ ...undrainedInbox && existingInbox !== void 0 && { inbox: existingInbox }
1367
1561
  };
1368
1562
  const withEpoch = stampAuthority(authorityWithDeks, existingFound?.file.roster_epoch);
1369
1563
  const keyringFile = {
@@ -1377,7 +1571,7 @@ async function persistKeyring(store, vault, keyring) {
1377
1571
  ...keyring.policy !== void 0 && { policy: keyring.policy },
1378
1572
  ...existingEcho !== void 0 && { echo: existingEcho }
1379
1573
  };
1380
- await writeKeyringFile(store, vault, keyring.userId, keyringFile);
1574
+ await writeKeyringFile(store, vault, keyring.userId, keyringFile, basisOf(existingFound));
1381
1575
  }
1382
1576
  function defaultBundleCapability(role) {
1383
1577
  return role === "owner" || role === "admin";
@@ -1416,17 +1610,19 @@ function resolvePermissions(role, explicit) {
1416
1610
  if (role === "owner" || role === "admin" || role === "custodian" || role === "viewer") return {};
1417
1611
  return explicit ?? {};
1418
1612
  }
1419
- async function writeKeyringFile(store, vault, userId, keyringFile) {
1613
+ var basisOf = (found) => found ? { on: found.envelope } : "create";
1614
+ async function writeKeyringFile(store, vault, userId, keyringFile, basis) {
1420
1615
  if (keyringFile.roster_epoch === void 0) {
1421
1616
  throw new Error(
1422
1617
  `writeKeyringFile: refusing to write a keyring for "${userId}" with no roster_epoch (#1097). Stamp it with nextRosterEpoch(previous) onto the authority object BEFORE minting the roster tag, so it is covered by rosterCanonical.`
1423
1618
  );
1424
1619
  }
1620
+ const base = basis === "create" ? 0 : basis.on._v;
1425
1621
  const envelope = buildRecordEnvelope(
1426
- { collection: "_keyring", id: userId, version: 1 },
1622
+ { collection: "_keyring", id: userId, version: base + 1 },
1427
1623
  { iv: "", data: JSON.stringify(keyringFile) }
1428
1624
  );
1429
- await store.put(vault, "_keyring", userId, envelope);
1625
+ await store.put(vault, "_keyring", userId, envelope, base);
1430
1626
  }
1431
1627
 
1432
1628
  export {
@@ -1462,6 +1658,7 @@ export {
1462
1658
  assertKeyringOpenAllowed,
1463
1659
  createOwnerKeyring,
1464
1660
  grant,
1661
+ NON_ROTATABLE_SLOTS,
1465
1662
  revoke,
1466
1663
  verifyRoster,
1467
1664
  quarantineKeyring,
@@ -1474,10 +1671,15 @@ export {
1474
1671
  ensureCollectionDEK,
1475
1672
  hasWritePermission,
1476
1673
  hasAccess,
1674
+ mintInboxKey,
1675
+ inboxSlots,
1676
+ openInboxKeyPair,
1477
1677
  persistKeyring,
1478
1678
  hasExportCapability,
1479
1679
  evaluateExportCapability,
1480
1680
  hasImportCapability,
1481
- evaluateImportCapability
1681
+ evaluateImportCapability,
1682
+ basisOf,
1683
+ writeKeyringFile
1482
1684
  };
1483
- //# sourceMappingURL=chunk-45VHWE4C.js.map
1685
+ //# sourceMappingURL=chunk-QVUMKG3Z.js.map