@noy-db/hub 0.6.0-pre.20 → 0.6.0-pre.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (363) hide show
  1. package/CHANGELOG.md +5234 -0
  2. package/dist/api-EYNT6KGS.js +20 -0
  3. package/dist/attestation/index.js +18 -18
  4. package/dist/{backup-K62BFMYK.js → backup-FSC36VWC.js} +12 -12
  5. package/dist/blobs/index.js +13 -13
  6. package/dist/broker/index.js +12 -12
  7. package/dist/cargo/index.js +29 -29
  8. package/dist/{chunk-GT72D4FO.js → chunk-2LFOMUEA.js} +3 -3
  9. package/dist/{chunk-W6NFONOV.js → chunk-32B7VCKU.js} +2 -2
  10. package/dist/{chunk-PG6PFMDC.js → chunk-3B6S6RSI.js} +2 -2
  11. package/dist/{chunk-DKYEVHZH.js → chunk-3ENNPCIW.js} +2 -2
  12. package/dist/{chunk-5J5TTSGW.js → chunk-3O72ZD2E.js} +3 -3
  13. package/dist/{chunk-WKD5ESK4.js → chunk-3PMFMUFX.js} +2 -2
  14. package/dist/{chunk-VEX2BQVX.js → chunk-45YHJ3GV.js} +11 -3
  15. package/dist/{chunk-VEX2BQVX.js.map → chunk-45YHJ3GV.js.map} +1 -1
  16. package/dist/{chunk-MNUTPZRQ.js → chunk-4A34KWOU.js} +6 -6
  17. package/dist/{chunk-32O2N2CH.js → chunk-4N5Q23KV.js} +7 -7
  18. package/dist/{chunk-MQXYR65M.js → chunk-4OQZNXQG.js} +6 -6
  19. package/dist/{chunk-S55DBWRC.js → chunk-4RAS6HN6.js} +2 -2
  20. package/dist/{chunk-6S466CMQ.js → chunk-4YL2LMXK.js} +8 -8
  21. package/dist/{chunk-TC6MBEGH.js → chunk-5Q7AJ7DN.js} +5 -5
  22. package/dist/{chunk-GDGTIWB4.js → chunk-6JPGVL7X.js} +2 -2
  23. package/dist/{chunk-GYUCRDAU.js → chunk-6KTVJ5ZZ.js} +4 -4
  24. package/dist/{chunk-YVTADFTC.js → chunk-6WO62AJW.js} +4 -4
  25. package/dist/{chunk-RORE2GX2.js → chunk-6YD5SYQS.js} +2 -2
  26. package/dist/{chunk-JIF3IBRK.js → chunk-7KAE7CQ2.js} +2 -2
  27. package/dist/{chunk-4HVTRHSA.js → chunk-7LNE2N2V.js} +6 -6
  28. package/dist/{chunk-M4IKEOJS.js → chunk-7PJ3BKHS.js} +6 -6
  29. package/dist/{chunk-HTHRCGWP.js → chunk-A4TOGAUW.js} +2 -2
  30. package/dist/{chunk-VJ4B3ZXY.js → chunk-AU3AUJIZ.js} +2 -2
  31. package/dist/{chunk-XGQGWZ6D.js → chunk-AUPSEJ7O.js} +4 -4
  32. package/dist/{chunk-A4K5GLE6.js → chunk-B6IYATME.js} +4 -4
  33. package/dist/{chunk-CV7WXCZD.js → chunk-BAHOV5I5.js} +10 -10
  34. package/dist/{chunk-E6VDPBE3.js → chunk-BEZDLIDG.js} +6 -6
  35. package/dist/{chunk-RKDH6L53.js → chunk-CAGI4LLJ.js} +303 -49
  36. package/dist/chunk-CAGI4LLJ.js.map +1 -0
  37. package/dist/{chunk-BTNKPDZM.js → chunk-CLAHBPOI.js} +3 -3
  38. package/dist/{chunk-P7L3OQLL.js → chunk-CWM4GQD2.js} +15 -1
  39. package/dist/chunk-CWM4GQD2.js.map +1 -0
  40. package/dist/{chunk-C7WJNVJG.js → chunk-D3R7Q4QK.js} +2 -2
  41. package/dist/{chunk-ODVIFBAQ.js → chunk-DIZ6HM7Q.js} +6 -6
  42. package/dist/{chunk-ICCRAPWD.js → chunk-DVRZYAGT.js} +4 -4
  43. package/dist/{chunk-SG3OQCRG.js → chunk-DXKLLKME.js} +3 -3
  44. package/dist/{chunk-RQY5UWEL.js → chunk-E5SC6ENM.js} +12 -12
  45. package/dist/{chunk-OIIAXFKM.js → chunk-EES37S2V.js} +3 -3
  46. package/dist/{chunk-REL4OLWW.js → chunk-EKEIEJL6.js} +2 -2
  47. package/dist/{chunk-ZBDWKPBW.js → chunk-ESKIAXO2.js} +5 -5
  48. package/dist/{chunk-HJRTFXAA.js → chunk-FFSQFH6D.js} +2 -2
  49. package/dist/{chunk-A3NTKHDB.js → chunk-FS7NTGCJ.js} +2 -2
  50. package/dist/{chunk-5BS6IQZZ.js → chunk-FW7NGYLT.js} +5 -5
  51. package/dist/{chunk-ZPMXYPBR.js → chunk-GBBDFE6C.js} +2 -2
  52. package/dist/{chunk-OQLYMBJI.js → chunk-GQXFOAYZ.js} +3 -3
  53. package/dist/{chunk-5JT4Y5UE.js → chunk-GTHVPVAR.js} +10 -10
  54. package/dist/{chunk-NH2MST6J.js → chunk-GWO2IDAB.js} +2 -2
  55. package/dist/{chunk-MNMYHZVU.js → chunk-H3G4I3PN.js} +2 -2
  56. package/dist/{chunk-PNAIDIP7.js → chunk-HQSPF5IY.js} +16 -9
  57. package/dist/{chunk-PNAIDIP7.js.map → chunk-HQSPF5IY.js.map} +1 -1
  58. package/dist/{chunk-ZWKF3CD3.js → chunk-HR5R5JOM.js} +2 -2
  59. package/dist/{chunk-2E2MKBMI.js → chunk-HYYVT2KZ.js} +2 -2
  60. package/dist/{chunk-HGJC7I5F.js → chunk-I6QKB7MT.js} +2 -2
  61. package/dist/{chunk-IPDS2TYW.js → chunk-ICDHUUMQ.js} +3 -3
  62. package/dist/{chunk-3Y4OFWQJ.js → chunk-IGNJOJEP.js} +1 -1
  63. package/dist/chunk-IGNJOJEP.js.map +1 -0
  64. package/dist/{chunk-BP4I7IBK.js → chunk-IJ46VCWD.js} +2 -2
  65. package/dist/{chunk-AQF7JSQR.js → chunk-INMHEMXX.js} +2 -2
  66. package/dist/{chunk-IOURTXTM.js → chunk-JLYQQNY4.js} +7 -7
  67. package/dist/{chunk-IOURTXTM.js.map → chunk-JLYQQNY4.js.map} +1 -1
  68. package/dist/{chunk-KDX6VEYV.js → chunk-JNMTN5D5.js} +2 -2
  69. package/dist/{chunk-ZXW3X3DQ.js → chunk-JWMBG5S3.js} +7 -7
  70. package/dist/{chunk-L2XQ776M.js → chunk-KRVS7YWY.js} +2 -2
  71. package/dist/{chunk-DJ23QZIN.js → chunk-KV6JM2IA.js} +2 -2
  72. package/dist/{chunk-EJIVFOOQ.js → chunk-KX57HODD.js} +6 -6
  73. package/dist/{chunk-6TXUVKPG.js → chunk-LGFTOU27.js} +115 -90
  74. package/dist/chunk-LGFTOU27.js.map +1 -0
  75. package/dist/{chunk-YOT7D63X.js → chunk-LN7P6MZB.js} +3 -3
  76. package/dist/{chunk-JHO6FGZX.js → chunk-LX46B56Q.js} +5 -5
  77. package/dist/{chunk-APV42WPR.js → chunk-LXECF2ZR.js} +2 -2
  78. package/dist/{chunk-VH2W6BOG.js → chunk-MSLPDFK2.js} +7 -7
  79. package/dist/{chunk-NYSD43OE.js → chunk-MZTUTEHP.js} +4 -4
  80. package/dist/{chunk-F5AJZC3U.js → chunk-NCCEDL2K.js} +30 -11
  81. package/dist/chunk-NCCEDL2K.js.map +1 -0
  82. package/dist/{chunk-KBOPY6W2.js → chunk-NR2SUJ3H.js} +2 -2
  83. package/dist/{chunk-HTMQBBF3.js → chunk-NW4TY6VC.js} +3 -3
  84. package/dist/{chunk-OWGEHDT2.js → chunk-O742QBZZ.js} +5 -5
  85. package/dist/{chunk-D5UDZANO.js → chunk-OHOKBMTM.js} +96 -8
  86. package/dist/chunk-OHOKBMTM.js.map +1 -0
  87. package/dist/{chunk-KM6YR5XF.js → chunk-OIBEJN5H.js} +2 -2
  88. package/dist/{chunk-N2HKBESK.js → chunk-OMYCSTXL.js} +4 -4
  89. package/dist/{chunk-N7YAQKAO.js → chunk-ONVD6GBY.js} +2 -2
  90. package/dist/{chunk-NRNTXBHT.js → chunk-OTHHO3KI.js} +2 -2
  91. package/dist/{chunk-KUXTWVAR.js → chunk-P2MR5UNE.js} +3 -3
  92. package/dist/{chunk-ZVAFJQZB.js → chunk-PENPHA45.js} +2 -2
  93. package/dist/{chunk-47ZFULEZ.js → chunk-PPCOKVFA.js} +2 -2
  94. package/dist/{chunk-2IK6AC6A.js → chunk-QSIEL6TL.js} +5 -5
  95. package/dist/{chunk-VHVMJWM6.js → chunk-RFO4UXKQ.js} +6 -6
  96. package/dist/{chunk-CVYXIN5B.js → chunk-RKCRPPNB.js} +3 -3
  97. package/dist/{chunk-RSFG7XHM.js → chunk-RSXQNFGO.js} +2 -2
  98. package/dist/{chunk-DYASJSKI.js → chunk-S56VYR4Q.js} +3 -3
  99. package/dist/{chunk-7RCZ436O.js → chunk-SYS46BL7.js} +2 -2
  100. package/dist/{chunk-EG6AQBYW.js → chunk-T7JGWTES.js} +8 -8
  101. package/dist/{chunk-SA77BQ7F.js → chunk-TDSN2O2V.js} +5 -5
  102. package/dist/{chunk-SFD2LL7G.js → chunk-TMBSPLUG.js} +2 -2
  103. package/dist/{chunk-5EJQNA26.js → chunk-TQPASLY4.js} +2 -2
  104. package/dist/{chunk-QPIUFRUC.js → chunk-TX5MKAHA.js} +3 -3
  105. package/dist/{chunk-TENLCGYD.js → chunk-U27Y4DJZ.js} +4 -4
  106. package/dist/{chunk-L6FSZFG7.js → chunk-VVSOPRUE.js} +2 -2
  107. package/dist/{chunk-437FDIHO.js → chunk-WVE6YKMX.js} +3 -3
  108. package/dist/{chunk-PZSS7MUM.js → chunk-YALD3SST.js} +5 -5
  109. package/dist/{chunk-WBNXZU42.js → chunk-YKXZHUOW.js} +4 -4
  110. package/dist/{chunk-RNSC2ARR.js → chunk-ZLHHE5XZ.js} +3 -3
  111. package/dist/{chunk-GILI76SU.js → chunk-ZZXLB6AS.js} +2 -2
  112. package/dist/classified/index.js +5 -5
  113. package/dist/{classified-marker-PMDG3O36.js → classified-marker-NA6HUV33.js} +3 -3
  114. package/dist/collection-facade-VBM35WAH.js +45 -0
  115. package/dist/{computed-UHCBRILW.js → computed-GSTLWSY5.js} +3 -3
  116. package/dist/consent/index.js +9 -9
  117. package/dist/cover/index.js +9 -9
  118. package/dist/custody/index.js +11 -11
  119. package/dist/{dead-filter-777VWDER.js → dead-filter-UALP5DJX.js} +2 -2
  120. package/dist/debug/index.js +1 -1
  121. package/dist/{delegation-4R5DU23X.js → delegation-JLNXM7KH.js} +11 -11
  122. package/dist/derivations/index.js +12 -12
  123. package/dist/derive-YUO3TQYN.js +22 -0
  124. package/dist/directory/index.js +10 -10
  125. package/dist/{dispatch-ASL257KG.js → dispatch-4ZHLSFZQ.js} +5 -5
  126. package/dist/{dispatch-3EN6YCCS.js → dispatch-77CB75KB.js} +18 -18
  127. package/dist/{enclave-ZJS5R5RH.js → enclave-O4NOROCJ.js} +11 -9
  128. package/dist/executor-CZDXBXKE.js +29 -0
  129. package/dist/executor-DVJAWN3B.js +9 -0
  130. package/dist/executor-VRLG4TQJ.js +9 -0
  131. package/dist/export-accessible-UXSMG7AB.js +23 -0
  132. package/dist/extract-partition-TVY7AMKH.js +38 -0
  133. package/dist/{fanout-sidecar-TFPWDOME.js → fanout-sidecar-NLQ7QAYW.js} +9 -9
  134. package/dist/find-WSARMJBW.js +11 -0
  135. package/dist/forget/index.js +9 -9
  136. package/dist/guards/index.js +7 -7
  137. package/dist/history/index.js +13 -13
  138. package/dist/i18n/index.js +14 -14
  139. package/dist/index.d.ts +2 -1
  140. package/dist/index.js +95 -91
  141. package/dist/index.js.map +1 -1
  142. package/dist/indexing/index.js +2 -2
  143. package/dist/introspection/index.js +11 -11
  144. package/dist/issue-3JNJNPT3.js +19 -0
  145. package/dist/kernel/constants.d.ts +18 -0
  146. package/dist/kernel/enclave/index.d.ts +1 -0
  147. package/dist/kernel/enclave/record-keys/rekey-blob.d.ts +88 -0
  148. package/dist/kernel/errors.d.ts +48 -1
  149. package/dist/kernel/noydb.d.ts +18 -1
  150. package/dist/kernel/types.d.ts +20 -6
  151. package/dist/kernel/vault.d.ts +1 -1
  152. package/dist/{ledger-62CEPRPX.js → ledger-MVPNG5OS.js} +11 -11
  153. package/dist/liberate-4LOJOLDT.js +24 -0
  154. package/dist/{link-set-ZRYNUHN3.js → link-set-3POMQR3I.js} +11 -11
  155. package/dist/{managed-secret-T2WB4O47.js → managed-secret-IARIJJ7Q.js} +10 -10
  156. package/dist/materialized-views/index.js +20 -20
  157. package/dist/migrate-cek-XM2ETTZW.js +19 -0
  158. package/dist/migrate-cek-XM2ETTZW.js.map +1 -0
  159. package/dist/money/index.js +4 -4
  160. package/dist/noydb-IRILUDED.js +84 -0
  161. package/dist/overlay-views/index.js +4 -4
  162. package/dist/periods/index.js +12 -12
  163. package/dist/pod/index.js +55 -55
  164. package/dist/{pod-handle-UPLXOGIK.js → pod-handle-MELERCKU.js} +9 -9
  165. package/dist/policy/index.js +10 -10
  166. package/dist/port/with/team-strategy.d.ts +5 -1
  167. package/dist/portability/index.js +8 -8
  168. package/dist/{post-register-J4DEVNXK.js → post-register-Z5T7FY45.js} +6 -6
  169. package/dist/query/index.js +3 -3
  170. package/dist/reduce/index.js +4 -4
  171. package/dist/register-UZ37QPDB.js +32 -0
  172. package/dist/registry-ETJNA7PO.js +9 -0
  173. package/dist/registry-F7U6KSLX.js +9 -0
  174. package/dist/registry-L4ELKX6C.js +18 -0
  175. package/dist/registry-SDT5LIGO.js +19 -0
  176. package/dist/request-withdrawal-PVFEYX57.js +31 -0
  177. package/dist/{reveal-525XWQU2.js → reveal-DQ2E3QAZ.js} +6 -6
  178. package/dist/revoke-YXY6SHUH.js +24 -0
  179. package/dist/satellites/index.js +1 -1
  180. package/dist/schema-update/index.js +2 -2
  181. package/dist/sealed-record/index.js +12 -12
  182. package/dist/search/index.js +4 -4
  183. package/dist/{seed-SGIF3EN4.js → seed-DZ4ORU5N.js} +11 -11
  184. package/dist/sequence/index.js +9 -9
  185. package/dist/session/index.js +9 -9
  186. package/dist/shadow/index.js +2 -2
  187. package/dist/signer-Q7XQBMPA.js +25 -0
  188. package/dist/snapshots/index.js +10 -10
  189. package/dist/{stale-PQYPVCER.js → stale-NI7SAXAZ.js} +10 -10
  190. package/dist/storage-3VNGSHXS.js +23 -0
  191. package/dist/{store-coordination-provider-TFHZLKHG.js → store-coordination-provider-TYKNR3OU.js} +10 -10
  192. package/dist/sync/index.js +10 -10
  193. package/dist/team/index.js +15 -15
  194. package/dist/tiers/index.js +11 -11
  195. package/dist/to/index.js +1 -1
  196. package/dist/transactions/index.js +3 -3
  197. package/dist/util/index.js +1 -1
  198. package/dist/vault-head/index.js +8 -8
  199. package/dist/{verify-J6DEOXP3.js → verify-6J2YLKSO.js} +5 -5
  200. package/dist/walk-WRA7RAPY.js +21 -0
  201. package/dist/with-party/team/keyring.d.ts +132 -0
  202. package/dist/with-party/team/noydb-facade.d.ts +5 -1
  203. package/dist/with-party/team/roster-tag.d.ts +101 -0
  204. package/dist/with-shape/blobs/blob-set.d.ts +2 -2
  205. package/dist/withdraw-accessible-4JTDFRFZ.js +28 -0
  206. package/package.json +4 -3
  207. package/dist/api-Z5VHH24A.js +0 -20
  208. package/dist/chunk-3Y4OFWQJ.js.map +0 -1
  209. package/dist/chunk-6TXUVKPG.js.map +0 -1
  210. package/dist/chunk-D5UDZANO.js.map +0 -1
  211. package/dist/chunk-F5AJZC3U.js.map +0 -1
  212. package/dist/chunk-P7L3OQLL.js.map +0 -1
  213. package/dist/chunk-RKDH6L53.js.map +0 -1
  214. package/dist/collection-facade-ZJK5EB33.js +0 -45
  215. package/dist/derive-3WAS2G5T.js +0 -22
  216. package/dist/executor-GPM6DNWV.js +0 -9
  217. package/dist/executor-LJSMZ4IB.js +0 -9
  218. package/dist/executor-SHUVRZUJ.js +0 -29
  219. package/dist/export-accessible-GNY6DC6U.js +0 -23
  220. package/dist/extract-partition-BG3AF4NZ.js +0 -38
  221. package/dist/find-KX6OKHDP.js +0 -11
  222. package/dist/issue-PAUM7NCX.js +0 -19
  223. package/dist/liberate-I6AOLWXW.js +0 -24
  224. package/dist/noydb-SS6EN7TK.js +0 -84
  225. package/dist/register-UPD4GKBC.js +0 -32
  226. package/dist/registry-7KX2HWFS.js +0 -18
  227. package/dist/registry-PKYYEHEW.js +0 -9
  228. package/dist/registry-XHCYMD34.js +0 -19
  229. package/dist/registry-XIRTZHPC.js +0 -9
  230. package/dist/request-withdrawal-XZSESWZV.js +0 -31
  231. package/dist/revoke-QI7YHQ2B.js +0 -24
  232. package/dist/signer-BZWDPGGN.js +0 -25
  233. package/dist/storage-MJHKNQRO.js +0 -23
  234. package/dist/walk-BX4NSB5L.js +0 -21
  235. package/dist/withdraw-accessible-K4CPMH4C.js +0 -28
  236. /package/dist/{api-Z5VHH24A.js.map → api-EYNT6KGS.js.map} +0 -0
  237. /package/dist/{backup-K62BFMYK.js.map → backup-FSC36VWC.js.map} +0 -0
  238. /package/dist/{chunk-GT72D4FO.js.map → chunk-2LFOMUEA.js.map} +0 -0
  239. /package/dist/{chunk-W6NFONOV.js.map → chunk-32B7VCKU.js.map} +0 -0
  240. /package/dist/{chunk-PG6PFMDC.js.map → chunk-3B6S6RSI.js.map} +0 -0
  241. /package/dist/{chunk-DKYEVHZH.js.map → chunk-3ENNPCIW.js.map} +0 -0
  242. /package/dist/{chunk-5J5TTSGW.js.map → chunk-3O72ZD2E.js.map} +0 -0
  243. /package/dist/{chunk-WKD5ESK4.js.map → chunk-3PMFMUFX.js.map} +0 -0
  244. /package/dist/{chunk-MNUTPZRQ.js.map → chunk-4A34KWOU.js.map} +0 -0
  245. /package/dist/{chunk-32O2N2CH.js.map → chunk-4N5Q23KV.js.map} +0 -0
  246. /package/dist/{chunk-MQXYR65M.js.map → chunk-4OQZNXQG.js.map} +0 -0
  247. /package/dist/{chunk-S55DBWRC.js.map → chunk-4RAS6HN6.js.map} +0 -0
  248. /package/dist/{chunk-6S466CMQ.js.map → chunk-4YL2LMXK.js.map} +0 -0
  249. /package/dist/{chunk-TC6MBEGH.js.map → chunk-5Q7AJ7DN.js.map} +0 -0
  250. /package/dist/{chunk-GDGTIWB4.js.map → chunk-6JPGVL7X.js.map} +0 -0
  251. /package/dist/{chunk-GYUCRDAU.js.map → chunk-6KTVJ5ZZ.js.map} +0 -0
  252. /package/dist/{chunk-YVTADFTC.js.map → chunk-6WO62AJW.js.map} +0 -0
  253. /package/dist/{chunk-RORE2GX2.js.map → chunk-6YD5SYQS.js.map} +0 -0
  254. /package/dist/{chunk-JIF3IBRK.js.map → chunk-7KAE7CQ2.js.map} +0 -0
  255. /package/dist/{chunk-4HVTRHSA.js.map → chunk-7LNE2N2V.js.map} +0 -0
  256. /package/dist/{chunk-M4IKEOJS.js.map → chunk-7PJ3BKHS.js.map} +0 -0
  257. /package/dist/{chunk-HTHRCGWP.js.map → chunk-A4TOGAUW.js.map} +0 -0
  258. /package/dist/{chunk-VJ4B3ZXY.js.map → chunk-AU3AUJIZ.js.map} +0 -0
  259. /package/dist/{chunk-XGQGWZ6D.js.map → chunk-AUPSEJ7O.js.map} +0 -0
  260. /package/dist/{chunk-A4K5GLE6.js.map → chunk-B6IYATME.js.map} +0 -0
  261. /package/dist/{chunk-CV7WXCZD.js.map → chunk-BAHOV5I5.js.map} +0 -0
  262. /package/dist/{chunk-E6VDPBE3.js.map → chunk-BEZDLIDG.js.map} +0 -0
  263. /package/dist/{chunk-BTNKPDZM.js.map → chunk-CLAHBPOI.js.map} +0 -0
  264. /package/dist/{chunk-C7WJNVJG.js.map → chunk-D3R7Q4QK.js.map} +0 -0
  265. /package/dist/{chunk-ODVIFBAQ.js.map → chunk-DIZ6HM7Q.js.map} +0 -0
  266. /package/dist/{chunk-ICCRAPWD.js.map → chunk-DVRZYAGT.js.map} +0 -0
  267. /package/dist/{chunk-SG3OQCRG.js.map → chunk-DXKLLKME.js.map} +0 -0
  268. /package/dist/{chunk-RQY5UWEL.js.map → chunk-E5SC6ENM.js.map} +0 -0
  269. /package/dist/{chunk-OIIAXFKM.js.map → chunk-EES37S2V.js.map} +0 -0
  270. /package/dist/{chunk-REL4OLWW.js.map → chunk-EKEIEJL6.js.map} +0 -0
  271. /package/dist/{chunk-ZBDWKPBW.js.map → chunk-ESKIAXO2.js.map} +0 -0
  272. /package/dist/{chunk-HJRTFXAA.js.map → chunk-FFSQFH6D.js.map} +0 -0
  273. /package/dist/{chunk-A3NTKHDB.js.map → chunk-FS7NTGCJ.js.map} +0 -0
  274. /package/dist/{chunk-5BS6IQZZ.js.map → chunk-FW7NGYLT.js.map} +0 -0
  275. /package/dist/{chunk-ZPMXYPBR.js.map → chunk-GBBDFE6C.js.map} +0 -0
  276. /package/dist/{chunk-OQLYMBJI.js.map → chunk-GQXFOAYZ.js.map} +0 -0
  277. /package/dist/{chunk-5JT4Y5UE.js.map → chunk-GTHVPVAR.js.map} +0 -0
  278. /package/dist/{chunk-NH2MST6J.js.map → chunk-GWO2IDAB.js.map} +0 -0
  279. /package/dist/{chunk-MNMYHZVU.js.map → chunk-H3G4I3PN.js.map} +0 -0
  280. /package/dist/{chunk-ZWKF3CD3.js.map → chunk-HR5R5JOM.js.map} +0 -0
  281. /package/dist/{chunk-2E2MKBMI.js.map → chunk-HYYVT2KZ.js.map} +0 -0
  282. /package/dist/{chunk-HGJC7I5F.js.map → chunk-I6QKB7MT.js.map} +0 -0
  283. /package/dist/{chunk-IPDS2TYW.js.map → chunk-ICDHUUMQ.js.map} +0 -0
  284. /package/dist/{chunk-BP4I7IBK.js.map → chunk-IJ46VCWD.js.map} +0 -0
  285. /package/dist/{chunk-AQF7JSQR.js.map → chunk-INMHEMXX.js.map} +0 -0
  286. /package/dist/{chunk-KDX6VEYV.js.map → chunk-JNMTN5D5.js.map} +0 -0
  287. /package/dist/{chunk-ZXW3X3DQ.js.map → chunk-JWMBG5S3.js.map} +0 -0
  288. /package/dist/{chunk-L2XQ776M.js.map → chunk-KRVS7YWY.js.map} +0 -0
  289. /package/dist/{chunk-DJ23QZIN.js.map → chunk-KV6JM2IA.js.map} +0 -0
  290. /package/dist/{chunk-EJIVFOOQ.js.map → chunk-KX57HODD.js.map} +0 -0
  291. /package/dist/{chunk-YOT7D63X.js.map → chunk-LN7P6MZB.js.map} +0 -0
  292. /package/dist/{chunk-JHO6FGZX.js.map → chunk-LX46B56Q.js.map} +0 -0
  293. /package/dist/{chunk-APV42WPR.js.map → chunk-LXECF2ZR.js.map} +0 -0
  294. /package/dist/{chunk-VH2W6BOG.js.map → chunk-MSLPDFK2.js.map} +0 -0
  295. /package/dist/{chunk-NYSD43OE.js.map → chunk-MZTUTEHP.js.map} +0 -0
  296. /package/dist/{chunk-KBOPY6W2.js.map → chunk-NR2SUJ3H.js.map} +0 -0
  297. /package/dist/{chunk-HTMQBBF3.js.map → chunk-NW4TY6VC.js.map} +0 -0
  298. /package/dist/{chunk-OWGEHDT2.js.map → chunk-O742QBZZ.js.map} +0 -0
  299. /package/dist/{chunk-KM6YR5XF.js.map → chunk-OIBEJN5H.js.map} +0 -0
  300. /package/dist/{chunk-N2HKBESK.js.map → chunk-OMYCSTXL.js.map} +0 -0
  301. /package/dist/{chunk-N7YAQKAO.js.map → chunk-ONVD6GBY.js.map} +0 -0
  302. /package/dist/{chunk-NRNTXBHT.js.map → chunk-OTHHO3KI.js.map} +0 -0
  303. /package/dist/{chunk-KUXTWVAR.js.map → chunk-P2MR5UNE.js.map} +0 -0
  304. /package/dist/{chunk-ZVAFJQZB.js.map → chunk-PENPHA45.js.map} +0 -0
  305. /package/dist/{chunk-47ZFULEZ.js.map → chunk-PPCOKVFA.js.map} +0 -0
  306. /package/dist/{chunk-2IK6AC6A.js.map → chunk-QSIEL6TL.js.map} +0 -0
  307. /package/dist/{chunk-VHVMJWM6.js.map → chunk-RFO4UXKQ.js.map} +0 -0
  308. /package/dist/{chunk-CVYXIN5B.js.map → chunk-RKCRPPNB.js.map} +0 -0
  309. /package/dist/{chunk-RSFG7XHM.js.map → chunk-RSXQNFGO.js.map} +0 -0
  310. /package/dist/{chunk-DYASJSKI.js.map → chunk-S56VYR4Q.js.map} +0 -0
  311. /package/dist/{chunk-7RCZ436O.js.map → chunk-SYS46BL7.js.map} +0 -0
  312. /package/dist/{chunk-EG6AQBYW.js.map → chunk-T7JGWTES.js.map} +0 -0
  313. /package/dist/{chunk-SA77BQ7F.js.map → chunk-TDSN2O2V.js.map} +0 -0
  314. /package/dist/{chunk-SFD2LL7G.js.map → chunk-TMBSPLUG.js.map} +0 -0
  315. /package/dist/{chunk-5EJQNA26.js.map → chunk-TQPASLY4.js.map} +0 -0
  316. /package/dist/{chunk-QPIUFRUC.js.map → chunk-TX5MKAHA.js.map} +0 -0
  317. /package/dist/{chunk-TENLCGYD.js.map → chunk-U27Y4DJZ.js.map} +0 -0
  318. /package/dist/{chunk-L6FSZFG7.js.map → chunk-VVSOPRUE.js.map} +0 -0
  319. /package/dist/{chunk-437FDIHO.js.map → chunk-WVE6YKMX.js.map} +0 -0
  320. /package/dist/{chunk-PZSS7MUM.js.map → chunk-YALD3SST.js.map} +0 -0
  321. /package/dist/{chunk-WBNXZU42.js.map → chunk-YKXZHUOW.js.map} +0 -0
  322. /package/dist/{chunk-RNSC2ARR.js.map → chunk-ZLHHE5XZ.js.map} +0 -0
  323. /package/dist/{chunk-GILI76SU.js.map → chunk-ZZXLB6AS.js.map} +0 -0
  324. /package/dist/{classified-marker-PMDG3O36.js.map → classified-marker-NA6HUV33.js.map} +0 -0
  325. /package/dist/{collection-facade-ZJK5EB33.js.map → collection-facade-VBM35WAH.js.map} +0 -0
  326. /package/dist/{computed-UHCBRILW.js.map → computed-GSTLWSY5.js.map} +0 -0
  327. /package/dist/{dead-filter-777VWDER.js.map → dead-filter-UALP5DJX.js.map} +0 -0
  328. /package/dist/{delegation-4R5DU23X.js.map → delegation-JLNXM7KH.js.map} +0 -0
  329. /package/dist/{derive-3WAS2G5T.js.map → derive-YUO3TQYN.js.map} +0 -0
  330. /package/dist/{dispatch-ASL257KG.js.map → dispatch-4ZHLSFZQ.js.map} +0 -0
  331. /package/dist/{dispatch-3EN6YCCS.js.map → dispatch-77CB75KB.js.map} +0 -0
  332. /package/dist/{enclave-ZJS5R5RH.js.map → enclave-O4NOROCJ.js.map} +0 -0
  333. /package/dist/{executor-GPM6DNWV.js.map → executor-CZDXBXKE.js.map} +0 -0
  334. /package/dist/{executor-LJSMZ4IB.js.map → executor-DVJAWN3B.js.map} +0 -0
  335. /package/dist/{executor-SHUVRZUJ.js.map → executor-VRLG4TQJ.js.map} +0 -0
  336. /package/dist/{export-accessible-GNY6DC6U.js.map → export-accessible-UXSMG7AB.js.map} +0 -0
  337. /package/dist/{extract-partition-BG3AF4NZ.js.map → extract-partition-TVY7AMKH.js.map} +0 -0
  338. /package/dist/{fanout-sidecar-TFPWDOME.js.map → fanout-sidecar-NLQ7QAYW.js.map} +0 -0
  339. /package/dist/{find-KX6OKHDP.js.map → find-WSARMJBW.js.map} +0 -0
  340. /package/dist/{issue-PAUM7NCX.js.map → issue-3JNJNPT3.js.map} +0 -0
  341. /package/dist/{ledger-62CEPRPX.js.map → ledger-MVPNG5OS.js.map} +0 -0
  342. /package/dist/{liberate-I6AOLWXW.js.map → liberate-4LOJOLDT.js.map} +0 -0
  343. /package/dist/{link-set-ZRYNUHN3.js.map → link-set-3POMQR3I.js.map} +0 -0
  344. /package/dist/{managed-secret-T2WB4O47.js.map → managed-secret-IARIJJ7Q.js.map} +0 -0
  345. /package/dist/{noydb-SS6EN7TK.js.map → noydb-IRILUDED.js.map} +0 -0
  346. /package/dist/{pod-handle-UPLXOGIK.js.map → pod-handle-MELERCKU.js.map} +0 -0
  347. /package/dist/{post-register-J4DEVNXK.js.map → post-register-Z5T7FY45.js.map} +0 -0
  348. /package/dist/{register-UPD4GKBC.js.map → register-UZ37QPDB.js.map} +0 -0
  349. /package/dist/{registry-7KX2HWFS.js.map → registry-ETJNA7PO.js.map} +0 -0
  350. /package/dist/{registry-PKYYEHEW.js.map → registry-F7U6KSLX.js.map} +0 -0
  351. /package/dist/{registry-XHCYMD34.js.map → registry-L4ELKX6C.js.map} +0 -0
  352. /package/dist/{registry-XIRTZHPC.js.map → registry-SDT5LIGO.js.map} +0 -0
  353. /package/dist/{request-withdrawal-XZSESWZV.js.map → request-withdrawal-PVFEYX57.js.map} +0 -0
  354. /package/dist/{reveal-525XWQU2.js.map → reveal-DQ2E3QAZ.js.map} +0 -0
  355. /package/dist/{revoke-QI7YHQ2B.js.map → revoke-YXY6SHUH.js.map} +0 -0
  356. /package/dist/{seed-SGIF3EN4.js.map → seed-DZ4ORU5N.js.map} +0 -0
  357. /package/dist/{signer-BZWDPGGN.js.map → signer-Q7XQBMPA.js.map} +0 -0
  358. /package/dist/{stale-PQYPVCER.js.map → stale-NI7SAXAZ.js.map} +0 -0
  359. /package/dist/{storage-MJHKNQRO.js.map → storage-3VNGSHXS.js.map} +0 -0
  360. /package/dist/{store-coordination-provider-TFHZLKHG.js.map → store-coordination-provider-TYKNR3OU.js.map} +0 -0
  361. /package/dist/{verify-J6DEOXP3.js.map → verify-6J2YLKSO.js.map} +0 -0
  362. /package/dist/{walk-BX4NSB5L.js.map → walk-WRA7RAPY.js.map} +0 -0
  363. /package/dist/{withdraw-accessible-K4CPMH4C.js.map → withdraw-accessible-4JTDFRFZ.js.map} +0 -0
@@ -5,43 +5,95 @@ import {
5
5
  readDirectoryConfig,
6
6
  readUserVisibility,
7
7
  saveUserEnvelope
8
- } from "./chunk-JHO6FGZX.js";
8
+ } from "./chunk-LX46B56Q.js";
9
9
  import {
10
+ rekeyBlobSet,
10
11
  rekeyEnvelopeIfNeeded
11
- } from "./chunk-D5UDZANO.js";
12
+ } from "./chunk-OHOKBMTM.js";
12
13
  import {
13
14
  buildRecordEnvelope
14
- } from "./chunk-ZVAFJQZB.js";
15
+ } from "./chunk-PENPHA45.js";
15
16
  import {
16
17
  base64ToBuffer,
17
18
  bufferToBase64,
19
+ decrypt,
18
20
  deriveEchoKey,
19
21
  deriveKey,
20
22
  deriveSecretKey,
21
23
  encodeEchoParts,
24
+ encrypt,
22
25
  generateDEK,
23
26
  generateIV,
24
27
  generateSalt,
25
28
  unwrapKey,
26
29
  wrapKey
27
- } from "./chunk-VJ4B3ZXY.js";
30
+ } from "./chunk-AU3AUJIZ.js";
28
31
  import {
29
32
  NOYDB_KEYRING_VERSION
30
- } from "./chunk-3Y4OFWQJ.js";
33
+ } from "./chunk-IGNJOJEP.js";
31
34
  import {
32
35
  DirectoryDisabledError,
33
36
  EchoCeremonyRequiredError,
34
37
  InvalidKeyError,
35
38
  KeyringCorruptError,
36
39
  KeyringExpiredError,
40
+ KeyringTamperedError,
37
41
  NoAccessError,
38
42
  NoydbError,
39
43
  PermissionDeniedError,
40
44
  PrivilegeEscalationError,
45
+ ROSTER_KEY_ID,
41
46
  USER_ENVELOPE_COLLECTION,
42
47
  ValidationError,
43
48
  WrongPromptError
44
- } from "./chunk-P7L3OQLL.js";
49
+ } from "./chunk-CWM4GQD2.js";
50
+
51
+ // src/with-party/team/roster-tag.ts
52
+ function stable(value) {
53
+ if (Array.isArray(value)) return `[${value.map(stable).join(",")}]`;
54
+ if (value !== null && typeof value === "object") {
55
+ const entries = Object.entries(value).filter(([, v]) => v !== void 0).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([k, v]) => `${JSON.stringify(k)}:${stable(v)}`);
56
+ return `{${entries.join(",")}}`;
57
+ }
58
+ return JSON.stringify(value) ?? "null";
59
+ }
60
+ function rosterCanonical(file) {
61
+ return stable({
62
+ user_id: file.user_id,
63
+ role: file.role,
64
+ permissions: file.permissions,
65
+ granted_by: file.granted_by,
66
+ expires_at: file.expires_at ?? null,
67
+ export_capability: file.export_capability ?? null,
68
+ import_capability: file.import_capability ?? null
69
+ });
70
+ }
71
+ async function mintRosterTag(file, rosterKey) {
72
+ return encrypt(rosterCanonical(file), rosterKey);
73
+ }
74
+ async function verifyRosterTag(file, tag, rosterKey) {
75
+ if (tag == null) return false;
76
+ try {
77
+ return await decrypt(tag.iv, tag.data, rosterKey) === rosterCanonical(file);
78
+ } catch {
79
+ return false;
80
+ }
81
+ }
82
+ async function assertRosterAuthenticated(file, deks, userId) {
83
+ const rosterKey = deks.get(ROSTER_KEY_ID);
84
+ if (rosterKey === void 0) {
85
+ throw new KeyringTamperedError({ userId, reason: "roster-key-missing" });
86
+ }
87
+ await assertRosterTagValid(file, rosterKey, userId);
88
+ }
89
+ async function assertRosterTagValid(file, rosterKey, userId) {
90
+ if (!await verifyRosterTag(file, file.roster_tag, rosterKey)) {
91
+ throw new KeyringTamperedError({
92
+ userId,
93
+ reason: file.roster_tag == null ? "roster-tag-missing" : "roster-tag-mismatch"
94
+ });
95
+ }
96
+ }
45
97
 
46
98
  // src/kernel/validation.ts
47
99
  var WeakSecretError = class extends NoydbError {
@@ -297,6 +349,18 @@ async function verifyKeyringCanary(wrappedCanary, kek) {
297
349
  return false;
298
350
  }
299
351
  }
352
+ function rosterKeyOf(keyring) {
353
+ return keyring.deks.get(ROSTER_KEY_ID) ?? null;
354
+ }
355
+ function requireRosterKey(keyring, fn) {
356
+ const rosterKey = rosterKeyOf(keyring);
357
+ if (!rosterKey) {
358
+ throw new ValidationError(
359
+ `${fn}: caller keyring has no vault roster key \u2014 cannot stamp a roster tag. This typically means the keyring was opened via tier-3 PIN resume, session restore, or a wrap-DEKs tier-2 unlock. Re-authenticate at tier 1 (secret) before writing a keyring.`
360
+ );
361
+ }
362
+ return rosterKey;
363
+ }
300
364
  async function deriveKekForKeyring(file, secret, salt) {
301
365
  if (file.echo !== void 0) {
302
366
  if (typeof secret === "string") throw new EchoCeremonyRequiredError();
@@ -330,10 +394,12 @@ async function loadKeyring(store, vault, opts) {
330
394
  throw new NoAccessError(`No keyring found for user "${userId}" in vault "${vault}"`);
331
395
  }
332
396
  const { file: keyringFile } = found;
333
- assertKeyringNotExpired(keyringFile);
334
397
  const salt = base64ToBuffer(keyringFile.salt);
335
398
  const kek = await deriveKekForKeyring(keyringFile, secret, salt);
336
- const canaryOk = keyringFile.canary !== void 0 ? await verifyKeyringCanary(keyringFile.canary, kek) : null;
399
+ if (keyringFile.canary === void 0) {
400
+ throw new KeyringTamperedError({ userId, reason: "canary-missing" });
401
+ }
402
+ const canaryOk = await verifyKeyringCanary(keyringFile.canary, kek);
337
403
  const deks = /* @__PURE__ */ new Map();
338
404
  const failedCollections = [];
339
405
  let firstUnwrapError = null;
@@ -353,11 +419,11 @@ async function loadKeyring(store, vault, opts) {
353
419
  } catch {
354
420
  }
355
421
  }
356
- if (canaryOk === true) {
422
+ if (canaryOk) {
357
423
  if (failedCollections.length > 0) {
358
424
  throw new KeyringCorruptError({ failedCollections, intactCount: deks.size });
359
425
  }
360
- } else if (canaryOk === false) {
426
+ } else {
361
427
  if (deks.size > 0) {
362
428
  throw new KeyringCorruptError({
363
429
  failedCollections: [...failedCollections, "_canary"],
@@ -365,14 +431,9 @@ async function loadKeyring(store, vault, opts) {
365
431
  });
366
432
  }
367
433
  throw firstUnwrapError instanceof Error ? firstUnwrapError : new InvalidKeyError();
368
- } else {
369
- if (failedCollections.length > 0) {
370
- if (deks.size > 0) {
371
- throw new KeyringCorruptError({ failedCollections, intactCount: deks.size });
372
- }
373
- throw firstUnwrapError instanceof Error ? firstUnwrapError : new InvalidKeyError();
374
- }
375
434
  }
435
+ await assertRosterAuthenticated(keyringFile, deks, userId);
436
+ assertKeyringNotExpired(keyringFile);
376
437
  return {
377
438
  userId: keyringFile.user_id,
378
439
  displayName: keyringFile.display_name,
@@ -415,18 +476,27 @@ async function createOwnerKeyring(store, vault, opts) {
415
476
  const kek = typeof secret === "string" ? await deriveKey(secret, salt) : await deriveEchoKey(secret, salt);
416
477
  const userEnvelopeDek = await generateDEK();
417
478
  const wrappedUserEnvelopeDek = await wrapKey(userEnvelopeDek, kek);
479
+ const rosterKey = await generateDEK();
480
+ const wrappedRosterKey = await wrapKey(rosterKey, kek);
418
481
  const canary = await mintKeyringCanary(kek);
419
- const keyringFile = {
420
- _noydb_keyring: NOYDB_KEYRING_VERSION,
482
+ const authority = {
421
483
  user_id: userId,
422
484
  display_name: userId,
423
485
  role: "owner",
424
486
  permissions: {},
425
- deks: { [USER_ENVELOPE_COLLECTION]: wrappedUserEnvelopeDek },
487
+ granted_by: userId
488
+ };
489
+ const keyringFile = {
490
+ _noydb_keyring: NOYDB_KEYRING_VERSION,
491
+ ...authority,
492
+ deks: {
493
+ [USER_ENVELOPE_COLLECTION]: wrappedUserEnvelopeDek,
494
+ [ROSTER_KEY_ID]: wrappedRosterKey
495
+ },
426
496
  salt: bufferToBase64(salt),
427
497
  created_at: (/* @__PURE__ */ new Date()).toISOString(),
428
- granted_by: userId,
429
498
  canary,
499
+ roster_tag: await mintRosterTag(authority, rosterKey),
430
500
  // The presence of this block is what makes the keyring an echo keyring —
431
501
  // `deriveKekForKeyring` reads it to refuse a single-string unlock (AG-1).
432
502
  ...typeof secret !== "string" ? {
@@ -443,7 +513,10 @@ async function createOwnerKeyring(store, vault, opts) {
443
513
  displayName: userId,
444
514
  role: "owner",
445
515
  permissions: {},
446
- deks: /* @__PURE__ */ new Map([[USER_ENVELOPE_COLLECTION, userEnvelopeDek]]),
516
+ deks: /* @__PURE__ */ new Map([
517
+ [USER_ENVELOPE_COLLECTION, userEnvelopeDek],
518
+ [ROSTER_KEY_ID, rosterKey]
519
+ ]),
447
520
  kek,
448
521
  salt,
449
522
  authenticators: []
@@ -455,6 +528,7 @@ async function grant(store, vault, callerKeyring, options) {
455
528
  "grant: caller keyring has no KEK \u2014 tier-2 wrap-DEKs and tier-3 PIN-resume sessions cannot grant access to other users. Re-authenticate at tier 1 (secret) before granting."
456
529
  );
457
530
  }
531
+ const callerRosterKey = requireRosterKey(callerKeyring, "grant");
458
532
  if (!canGrant(callerKeyring.role, options.role)) {
459
533
  throw new PermissionDeniedError(
460
534
  `Role "${callerKeyring.role}" cannot grant role "${options.role}"`
@@ -510,19 +584,25 @@ async function grant(store, vault, callerKeyring, options) {
510
584
  }
511
585
  }
512
586
  const canary = await mintKeyringCanary(newKek);
513
- const keyringFile = {
514
- _noydb_keyring: NOYDB_KEYRING_VERSION,
587
+ const authority = {
515
588
  user_id: options.userId,
516
589
  display_name: options.displayName,
517
590
  role: options.role,
518
591
  permissions,
592
+ granted_by: callerKeyring.userId,
593
+ ...options.exportCapability !== void 0 && { export_capability: options.exportCapability },
594
+ ...options.importCapability !== void 0 && { import_capability: options.importCapability }
595
+ };
596
+ const keyringFile = {
597
+ _noydb_keyring: NOYDB_KEYRING_VERSION,
598
+ ...authority,
519
599
  deks: wrappedDeks,
520
600
  salt: bufferToBase64(newSalt),
521
601
  created_at: (/* @__PURE__ */ new Date()).toISOString(),
522
- granted_by: callerKeyring.userId,
523
602
  canary,
524
- ...options.exportCapability !== void 0 && { export_capability: options.exportCapability },
525
- ...options.importCapability !== void 0 && { import_capability: options.importCapability }
603
+ // The grantee's own copy of the roster key rode in via the `_`-prefix
604
+ // propagation loop above, so they can verify this tag on first unlock.
605
+ roster_tag: await mintRosterTag(authority, callerRosterKey)
526
606
  };
527
607
  await writeKeyringFile(store, vault, options.userId, keyringFile);
528
608
  const userEnvelopeDek = callerKeyring.deks.get(USER_ENVELOPE_COLLECTION);
@@ -537,13 +617,14 @@ async function grant(store, vault, callerKeyring, options) {
537
617
  );
538
618
  }
539
619
  }
540
- async function findAdminDescendants(store, vault, rootUserId) {
620
+ async function findAdminDescendants(store, vault, rootUserId, rosterKey) {
541
621
  const allUserIds = await store.list(vault, "_keyring");
542
622
  const childrenByParent = /* @__PURE__ */ new Map();
543
623
  for (const userId of allUserIds) {
544
624
  const found = await readKeyringFile(store, vault, userId);
545
625
  if (!found) continue;
546
626
  const kf = found.file;
627
+ await assertRosterTagValid(kf, rosterKey, userId);
547
628
  if (kf.role !== "admin") continue;
548
629
  if (kf.user_id === rootUserId) continue;
549
630
  const list = childrenByParent.get(kf.granted_by) ?? [];
@@ -575,6 +656,8 @@ async function revoke(store, vault, callerKeyring, options) {
575
656
  throw new NoAccessError(`User "${options.userId}" has no keyring in vault "${vault}"`);
576
657
  }
577
658
  const targetKeyring = targetFound.file;
659
+ const callerRosterKey = requireRosterKey(callerKeyring, "revoke");
660
+ await assertRosterTagValid(targetKeyring, callerRosterKey, options.userId);
578
661
  if (!canRevoke(callerKeyring.role, targetKeyring.role)) {
579
662
  throw new PermissionDeniedError(
580
663
  `Role "${callerKeyring.role}" cannot revoke role "${targetKeyring.role}"`
@@ -584,7 +667,7 @@ async function revoke(store, vault, callerKeyring, options) {
584
667
  const usersToRevoke = [options.userId];
585
668
  const affectedCollections = new Set(Object.keys(targetKeyring.deks));
586
669
  if (targetKeyring.role === "admin") {
587
- const descendants = await findAdminDescendants(store, vault, options.userId);
670
+ const descendants = await findAdminDescendants(store, vault, options.userId, callerRosterKey);
588
671
  if (descendants.length > 0) {
589
672
  if (cascadeMode === "warn") {
590
673
  console.warn(
@@ -594,6 +677,7 @@ async function revoke(store, vault, callerKeyring, options) {
594
677
  for (const userId of descendants) {
595
678
  const descFound = await readKeyringFile(store, vault, userId);
596
679
  if (!descFound) continue;
680
+ await assertRosterTagValid(descFound.file, callerRosterKey, userId);
597
681
  usersToRevoke.push(userId);
598
682
  for (const c of Object.keys(descFound.file.deks)) affectedCollections.add(c);
599
683
  }
@@ -605,9 +689,103 @@ async function revoke(store, vault, callerKeyring, options) {
605
689
  await deleteUserEnvelope(store, vault, userId);
606
690
  await deleteUserVisibility(store, vault, userId);
607
691
  }
692
+ affectedCollections.delete(ROSTER_KEY_ID);
608
693
  if (affectedCollections.size > 0) {
609
- await rotateKeys(store, vault, callerKeyring, { collections: [...affectedCollections] });
694
+ const { unverified } = await rotateKeys(store, vault, callerKeyring, {
695
+ collections: [...affectedCollections]
696
+ });
697
+ if (unverified.length > 0) {
698
+ console.warn(
699
+ `[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 (noy-db#1114).`
700
+ );
701
+ }
702
+ }
703
+ }
704
+ async function readKeyringForAudit(store, vault, userId) {
705
+ const envelope = await store.get(vault, "_keyring", userId);
706
+ if (!envelope) return void 0;
707
+ try {
708
+ return { file: parseKeyringEnvelope(envelope) };
709
+ } catch {
710
+ return { unparseable: true };
711
+ }
712
+ }
713
+ async function verifyRoster(store, vault, callerKeyring) {
714
+ const rosterKey = requireRosterKey(callerKeyring, "verifyRoster");
715
+ const unverified = [];
716
+ let checked = 0;
717
+ for (const userId of await store.list(vault, "_keyring")) {
718
+ const found = await readKeyringForAudit(store, vault, userId);
719
+ if (!found) continue;
720
+ checked += 1;
721
+ if ("unparseable" in found) {
722
+ unverified.push({ userId, reason: "unparseable" });
723
+ continue;
724
+ }
725
+ try {
726
+ await assertRosterTagValid(found.file, rosterKey, userId);
727
+ } catch (err) {
728
+ if (!(err instanceof KeyringTamperedError)) throw err;
729
+ unverified.push({ userId, reason: err.details.reason });
730
+ }
731
+ }
732
+ return { checked, unverified };
733
+ }
734
+ async function quarantineKeyring(store, vault, callerKeyring, userId) {
735
+ if (callerKeyring.role !== "owner") {
736
+ throw new PermissionDeniedError(
737
+ `Role "${callerKeyring.role}" cannot quarantine a keyring \u2014 quarantine is owner-only, because it removes a file whose own authority claims cannot be trusted.`
738
+ );
739
+ }
740
+ if (userId === callerKeyring.userId) {
741
+ throw new ValidationError(
742
+ "quarantineKeyring: refusing to quarantine the calling keyring. Removing your own keyring and rotating behind it would leave the vault with no reachable owner."
743
+ );
744
+ }
745
+ const rosterKey = requireRosterKey(callerKeyring, "quarantineKeyring");
746
+ const found = await readKeyringForAudit(store, vault, userId);
747
+ if (!found) {
748
+ const pending = [...callerKeyring.pendingDeks?.keys() ?? []];
749
+ if (pending.length > 0) {
750
+ const resumed = await rotateKeys(store, vault, callerKeyring, { collections: pending });
751
+ return {
752
+ userId,
753
+ reason: "roster-tag-mismatch",
754
+ rotated: pending,
755
+ needsRegrant: resumed.needsRegrant,
756
+ alsoUnverified: resumed.unverified
757
+ };
758
+ }
759
+ throw new NoAccessError(`No keyring found for user "${userId}" in vault "${vault}"`);
760
+ }
761
+ let reason = null;
762
+ if ("unparseable" in found) {
763
+ reason = "unparseable";
764
+ } else {
765
+ try {
766
+ await assertRosterTagValid(found.file, rosterKey, userId);
767
+ } catch (err) {
768
+ if (!(err instanceof KeyringTamperedError)) throw err;
769
+ reason = err.details.reason;
770
+ }
771
+ }
772
+ if (reason === null) {
773
+ throw new ValidationError(
774
+ `quarantineKeyring: the keyring for "${userId}" authenticates correctly, so it is not a quarantine case \u2014 use revoke() instead. Quarantine bypasses the role checks revoke performs, so it is restricted to files that genuinely fail authentication.`
775
+ );
610
776
  }
777
+ await store.delete(vault, "_keyring", userId);
778
+ await deleteUserEnvelope(store, vault, userId);
779
+ await deleteUserVisibility(store, vault, userId);
780
+ const rotated = [...callerKeyring.deks.keys()].filter((c) => c !== ROSTER_KEY_ID);
781
+ const result = rotated.length > 0 ? await rotateKeys(store, vault, callerKeyring, { collections: rotated }) : { needsRegrant: [], unverified: [] };
782
+ return {
783
+ userId,
784
+ reason,
785
+ rotated,
786
+ needsRegrant: result.needsRegrant,
787
+ alsoUnverified: result.unverified
788
+ };
611
789
  }
612
790
  async function updateKeyringIdentity(store, vault, callerKeyring, options) {
613
791
  if (options.role === void 0 && options.displayName === void 0 && options.permissions === void 0) {
@@ -622,6 +800,8 @@ async function updateKeyringIdentity(store, vault, callerKeyring, options) {
622
800
  );
623
801
  }
624
802
  const target = found.file;
803
+ const rosterKey = requireRosterKey(callerKeyring, "updateKeyringIdentity");
804
+ await assertRosterTagValid(target, rosterKey, options.userId);
625
805
  if (!canUpdateRole(callerKeyring.role, target.role)) {
626
806
  throw new PermissionDeniedError(
627
807
  `Role "${callerKeyring.role}" cannot update a keyring with role "${target.role}"`
@@ -632,7 +812,7 @@ async function updateKeyringIdentity(store, vault, callerKeyring, options) {
632
812
  `Role "${callerKeyring.role}" cannot promote target to role "${options.role}"`
633
813
  );
634
814
  }
635
- const next = {
815
+ const edited = {
636
816
  ...target,
637
817
  ...options.role !== void 0 && { role: options.role },
638
818
  ...options.displayName !== void 0 && {
@@ -641,11 +821,16 @@ async function updateKeyringIdentity(store, vault, callerKeyring, options) {
641
821
  },
642
822
  ...options.permissions !== void 0 && { permissions: options.permissions }
643
823
  };
824
+ const next = { ...edited, roster_tag: await mintRosterTag(edited, rosterKey) };
644
825
  await writeKeyringFile(store, vault, options.userId, next);
645
826
  }
646
827
  var HISTORY_COLLECTION = "_history";
647
828
  var LEDGER_COLLECTION = "_ledger";
648
829
  var LEDGER_DELTAS_COLLECTION = "_ledger_deltas";
830
+ var BLOB_COLLECTION = "_blob";
831
+ var BLOB_SLOTS_PREFIX = "_blob_slots_";
832
+ var BLOB_VERSIONS_PREFIX = "_blob_versions_";
833
+ var BLOB_INTENT_COLLECTION = "_blob_intent";
649
834
  async function listOrEmpty(store, vault, collection) {
650
835
  try {
651
836
  return await store.list(vault, collection);
@@ -665,15 +850,32 @@ async function derivedRefsFor(store, vault, rotated) {
665
850
  out.push({ collection: LEDGER_DELTAS_COLLECTION, id });
666
851
  }
667
852
  }
853
+ if (!rotated.startsWith("_")) {
854
+ for (const id of await listOrEmpty(store, vault, `${BLOB_SLOTS_PREFIX}${rotated}`)) {
855
+ out.push({ collection: `${BLOB_SLOTS_PREFIX}${rotated}`, id });
856
+ }
857
+ for (const id of await listOrEmpty(store, vault, `${BLOB_VERSIONS_PREFIX}${rotated}`)) {
858
+ out.push({ collection: `${BLOB_VERSIONS_PREFIX}${rotated}`, id });
859
+ }
860
+ for (const id of await listOrEmpty(store, vault, BLOB_INTENT_COLLECTION)) {
861
+ if (id.startsWith(`${rotated}::`)) out.push({ collection: BLOB_INTENT_COLLECTION, id });
862
+ }
863
+ }
668
864
  return out;
669
865
  }
670
866
  async function rotateKeys(store, vault, callerKeyring, opts) {
671
867
  const { collections } = opts;
868
+ if (collections.includes(ROSTER_KEY_ID)) {
869
+ throw new ValidationError(
870
+ `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\`.`
871
+ );
872
+ }
672
873
  if (callerKeyring.role === "custodian") {
673
874
  throw new PermissionDeniedError(
674
875
  "custodian cannot rotate keys (FR-6: re-key is an owner-only meta-capability; use the Deed owner)"
675
876
  );
676
877
  }
878
+ const callerRosterKey = requireRosterKey(callerKeyring, "rotateKeys");
677
879
  const newDeks = /* @__PURE__ */ new Map();
678
880
  for (const collName of collections) {
679
881
  newDeks.set(collName, callerKeyring.pendingDeks?.get(collName) ?? await generateDEK());
@@ -688,6 +890,12 @@ async function rotateKeys(store, vault, callerKeyring, opts) {
688
890
  const oldDek = callerKeyring.deks.get(collName);
689
891
  const newDek = newDeks.get(collName);
690
892
  if (!oldDek) continue;
893
+ if (collName === BLOB_COLLECTION || collName.startsWith(`${BLOB_COLLECTION}#`)) {
894
+ const others = [];
895
+ for (const [name, dek] of callerKeyring.deks) if (name !== collName) others.push(dek);
896
+ for (const [name, dek] of newDeks) if (name !== collName) others.push(dek);
897
+ await rekeyBlobSet(store, vault, oldDek, newDek, others);
898
+ }
691
899
  const refs = [
692
900
  ...(await store.list(vault, collName)).map((id) => ({ collection: collName, id })),
693
901
  ...await derivedRefsFor(store, vault, collName)
@@ -706,12 +914,20 @@ async function rotateKeys(store, vault, callerKeyring, opts) {
706
914
  }
707
915
  await persistKeyring(store, vault, callerKeyring);
708
916
  const needsRegrant = [];
917
+ const unverified = [];
709
918
  const userIds = await store.list(vault, "_keyring");
710
919
  for (const userId of userIds) {
711
920
  if (userId === callerKeyring.userId) continue;
712
921
  const userFound = await readKeyringFile(store, vault, userId);
713
922
  if (!userFound) continue;
714
923
  const userKeyringFile = userFound.file;
924
+ try {
925
+ await assertRosterTagValid(userKeyringFile, callerRosterKey, userId);
926
+ } catch (err) {
927
+ if (!(err instanceof KeyringTamperedError)) throw err;
928
+ unverified.push({ userId, reason: err.details.reason });
929
+ continue;
930
+ }
715
931
  const updatedDeks = { ...userKeyringFile.deks };
716
932
  const updatedPermissions = { ...userKeyringFile.permissions };
717
933
  for (const collName of collections) {
@@ -721,17 +937,24 @@ async function rotateKeys(store, vault, callerKeyring, opts) {
721
937
  delete updatedDeks[collName];
722
938
  delete updatedPermissions[collName];
723
939
  }
724
- const updatedKeyring = {
940
+ const edited = {
725
941
  ...userKeyringFile,
726
942
  deks: updatedDeks,
727
943
  permissions: updatedPermissions
728
944
  };
945
+ const updatedKeyring = {
946
+ ...edited,
947
+ roster_tag: await mintRosterTag(edited, callerRosterKey)
948
+ };
729
949
  await writeKeyringFile(store, vault, userId, updatedKeyring);
730
950
  }
731
- return { needsRegrant };
951
+ return { needsRegrant, unverified };
732
952
  }
733
953
  async function changeSecret(store, vault, keyring, opts) {
734
954
  const existingFound = await readKeyringFile(store, vault, keyring.userId);
955
+ if (existingFound) {
956
+ await assertRosterTagValid(existingFound.file, requireRosterKey(keyring, "changeSecret"), keyring.userId);
957
+ }
735
958
  if (existingFound && existingFound.file.echo !== void 0) throw new EchoCeremonyRequiredError();
736
959
  const { newSecret } = opts;
737
960
  if (!opts.allowWeakSecret) {
@@ -743,18 +966,28 @@ async function changeSecret(store, vault, keyring, opts) {
743
966
  for (const [collName, dek] of keyring.deks) {
744
967
  wrappedDeks[collName] = await wrapKey(dek, newKek);
745
968
  }
969
+ const rosterKey = requireRosterKey(keyring, "changeSecret");
746
970
  const canary = await mintKeyringCanary(newKek);
747
- const keyringFile = {
748
- _noydb_keyring: NOYDB_KEYRING_VERSION,
971
+ const existingAuthority = existingFound?.file;
972
+ const keptGrantedBy = existingAuthority?.granted_by ?? keyring.userId;
973
+ const authority = {
749
974
  user_id: keyring.userId,
750
975
  display_name: keyring.displayName,
751
976
  role: keyring.role,
752
977
  permissions: keyring.permissions,
978
+ granted_by: keptGrantedBy,
979
+ ...existingAuthority?.expires_at !== void 0 && { expires_at: existingAuthority.expires_at },
980
+ ...existingAuthority?.export_capability !== void 0 && { export_capability: existingAuthority.export_capability },
981
+ ...existingAuthority?.import_capability !== void 0 && { import_capability: existingAuthority.import_capability }
982
+ };
983
+ const keyringFile = {
984
+ _noydb_keyring: NOYDB_KEYRING_VERSION,
985
+ ...authority,
753
986
  deks: wrappedDeks,
754
987
  salt: bufferToBase64(newSalt),
755
988
  created_at: (/* @__PURE__ */ new Date()).toISOString(),
756
- granted_by: keyring.userId,
757
- canary
989
+ canary,
990
+ roster_tag: await mintRosterTag(authority, rosterKey)
758
991
  };
759
992
  await writeKeyringFile(store, vault, keyring.userId, keyringFile);
760
993
  return {
@@ -781,6 +1014,7 @@ async function buildRecipientKeyringFile(callerKeyring, recipient) {
781
1014
  "buildRecipientKeyringFile: caller keyring has no KEK \u2014 tier-2 wrap-DEKs and tier-3 PIN-resume sessions cannot create bundle recipients. Re-authenticate at tier 1 (secret) before building a bundle."
782
1015
  );
783
1016
  }
1017
+ const rosterKey = requireRosterKey(callerKeyring, "buildRecipientKeyringFile");
784
1018
  const role = recipient.role ?? "viewer";
785
1019
  const permissions = resolvePermissions(role, recipient.permissions);
786
1020
  const newSalt = generateSalt();
@@ -810,20 +1044,26 @@ async function buildRecipientKeyringFile(callerKeyring, recipient) {
810
1044
  }
811
1045
  }
812
1046
  const canary = await mintKeyringCanary(newKek);
813
- return {
814
- _noydb_keyring: NOYDB_KEYRING_VERSION,
1047
+ const authority = {
815
1048
  user_id: recipient.id,
816
1049
  display_name: recipient.displayName ?? recipient.id,
817
1050
  role,
818
1051
  permissions,
1052
+ granted_by: callerKeyring.userId,
1053
+ ...recipient.exportCapability !== void 0 ? { export_capability: recipient.exportCapability } : {},
1054
+ ...recipient.importCapability !== void 0 ? { import_capability: recipient.importCapability } : {},
1055
+ ...recipient.expiresAt !== void 0 ? { expires_at: recipient.expiresAt } : {}
1056
+ };
1057
+ return {
1058
+ _noydb_keyring: NOYDB_KEYRING_VERSION,
1059
+ ...authority,
819
1060
  deks: wrappedDeks,
820
1061
  salt: bufferToBase64(newSalt),
821
1062
  created_at: (/* @__PURE__ */ new Date()).toISOString(),
822
- granted_by: callerKeyring.userId,
823
1063
  canary,
824
- ...recipient.exportCapability !== void 0 ? { export_capability: recipient.exportCapability } : {},
825
- ...recipient.importCapability !== void 0 ? { import_capability: recipient.importCapability } : {},
826
- ...recipient.expiresAt !== void 0 ? { expires_at: recipient.expiresAt } : {},
1064
+ // The recipient's copy of the roster key rode in via the `_`-prefix
1065
+ // propagation loop above, so the slot verifies on first unlock.
1066
+ roster_tag: await mintRosterTag(authority, rosterKey),
827
1067
  // The presence of this block is what makes the recipient's slot an
828
1068
  // echo keyring — mirrors `createOwnerKeyring`'s same dance so the
829
1069
  // ceremony (prompt → echo → key) travels with the pod, not just a
@@ -951,10 +1191,13 @@ async function persistKeyring(store, vault, keyring) {
951
1191
  "persistKeyring: keyring.kek is null \u2014 cannot wrap DEKs without the KEK. This typically means the keyring was opened via tier-3 PIN resume, session restore, or a wrap-DEKs tier-2 unlock. Re-authenticate at tier 1 (secret) before persisting."
952
1192
  );
953
1193
  }
1194
+ const rosterKey = requireRosterKey(keyring, "persistKeyring");
954
1195
  const existingFound = await readKeyringFile(store, vault, keyring.userId);
1196
+ if (existingFound) await assertRosterTagValid(existingFound.file, rosterKey, keyring.userId);
955
1197
  const existingEcho = existingFound?.file.echo;
956
1198
  const existingGrantedBy = existingFound?.file.granted_by;
957
1199
  const existingCreatedAt = existingFound?.file.created_at;
1200
+ const existingExpiresAt = existingFound?.file.expires_at;
958
1201
  const wrappedDeks = {};
959
1202
  for (const [collName, dek] of keyring.deks) {
960
1203
  wrappedDeks[collName] = await wrapKey(dek, keyring.kek);
@@ -964,20 +1207,25 @@ async function persistKeyring(store, vault, keyring) {
964
1207
  wrappedPending[collName] = await wrapKey(dek, keyring.kek);
965
1208
  }
966
1209
  const canary = await mintKeyringCanary(keyring.kek);
967
- const keyringFile = {
968
- _noydb_keyring: NOYDB_KEYRING_VERSION,
1210
+ const authority = {
969
1211
  user_id: keyring.userId,
970
1212
  display_name: keyring.displayName,
971
1213
  role: keyring.role,
972
1214
  permissions: keyring.permissions,
1215
+ granted_by: existingGrantedBy ?? keyring.userId,
1216
+ ...existingExpiresAt !== void 0 && { expires_at: existingExpiresAt },
1217
+ ...keyring.exportCapability !== void 0 && { export_capability: keyring.exportCapability },
1218
+ ...keyring.importCapability !== void 0 && { import_capability: keyring.importCapability }
1219
+ };
1220
+ const keyringFile = {
1221
+ _noydb_keyring: NOYDB_KEYRING_VERSION,
1222
+ ...authority,
973
1223
  deks: wrappedDeks,
974
1224
  ...Object.keys(wrappedPending).length > 0 ? { pending_deks: wrappedPending } : {},
975
1225
  salt: bufferToBase64(keyring.salt),
976
1226
  created_at: existingCreatedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
977
- granted_by: existingGrantedBy ?? keyring.userId,
978
1227
  canary,
979
- ...keyring.exportCapability !== void 0 && { export_capability: keyring.exportCapability },
980
- ...keyring.importCapability !== void 0 && { import_capability: keyring.importCapability },
1228
+ roster_tag: await mintRosterTag(authority, rosterKey),
981
1229
  ...keyring.authenticators.length > 0 && { authenticators: keyring.authenticators },
982
1230
  ...keyring.policy !== void 0 && { policy: keyring.policy },
983
1231
  ...existingEcho !== void 0 && { echo: existingEcho }
@@ -1030,6 +1278,9 @@ async function writeKeyringFile(store, vault, userId, keyringFile) {
1030
1278
  }
1031
1279
 
1032
1280
  export {
1281
+ mintRosterTag,
1282
+ assertRosterAuthenticated,
1283
+ assertRosterTagValid,
1033
1284
  WeakSecretError,
1034
1285
  validateSecret,
1035
1286
  assertStrongSecret,
@@ -1046,6 +1297,7 @@ export {
1046
1297
  BROKER_COLLECTION,
1047
1298
  isSecretBearingReservedCollection,
1048
1299
  mintKeyringCanary,
1300
+ requireRosterKey,
1049
1301
  deriveKekForKeyring,
1050
1302
  readKeyringFile,
1051
1303
  assertKeyringNotExpired,
@@ -1054,6 +1306,8 @@ export {
1054
1306
  createOwnerKeyring,
1055
1307
  grant,
1056
1308
  revoke,
1309
+ verifyRoster,
1310
+ quarantineKeyring,
1057
1311
  updateKeyringIdentity,
1058
1312
  rotateKeys,
1059
1313
  changeSecret,
@@ -1069,4 +1323,4 @@ export {
1069
1323
  hasImportCapability,
1070
1324
  evaluateImportCapability
1071
1325
  };
1072
- //# sourceMappingURL=chunk-RKDH6L53.js.map
1326
+ //# sourceMappingURL=chunk-CAGI4LLJ.js.map