@noy-db/hub 0.10.0-pre.0 → 0.10.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 (492) hide show
  1. package/CHANGELOG.md +90 -0
  2. package/README.md +2 -2
  3. package/dist/api-QSEKT4KS.js +15 -0
  4. package/dist/as/index.js +19 -12
  5. package/dist/as/index.js.map +1 -1
  6. package/dist/at/index.js +6 -9
  7. package/dist/attestation/index.js +16 -19
  8. package/dist/attestation/index.js.map +1 -1
  9. package/dist/{backup-E3GBMNDA.js → backup-BHKVK5SD.js} +9 -12
  10. package/dist/{backup-E3GBMNDA.js.map → backup-BHKVK5SD.js.map} +1 -1
  11. package/dist/blobs/index.js +10 -13
  12. package/dist/blobs/index.js.map +1 -1
  13. package/dist/broker/index.js +11 -14
  14. package/dist/broker/index.js.map +1 -1
  15. package/dist/by/index.js +2 -2
  16. package/dist/capsule/contract.d.ts +176 -16
  17. package/dist/capsule/contract.js +35 -30
  18. package/dist/capsule/enclave-aes/bound.d.ts +11 -1
  19. package/dist/capsule/enclave-aes/classify/digest.d.ts +4 -2
  20. package/dist/capsule/enclave-aes/index.d.ts +9 -0
  21. package/dist/capsule/enclave-aes/index.js +643 -78
  22. package/dist/capsule/enclave-aes/index.js.map +1 -1
  23. package/dist/capsule/enclave-aes/primitives.d.ts +2 -2
  24. package/dist/capsule/index.d.ts +1 -1
  25. package/dist/capsule/plumbing/classify-reveal.d.ts +29 -0
  26. package/dist/capsule/plumbing/classify-verify.d.ts +53 -0
  27. package/dist/capsule/plumbing/index.d.ts +17 -0
  28. package/dist/{capsule-YQKQZPH7.js → capsule-YAITMH77.js} +16 -9
  29. package/dist/cargo/index.js +34 -36
  30. package/dist/{chunk-U43RSPPX.js → chunk-23A4SBRR.js} +3 -4
  31. package/dist/{chunk-U43RSPPX.js.map → chunk-23A4SBRR.js.map} +1 -1
  32. package/dist/{chunk-PREYKC76.js → chunk-24AGG4PP.js} +3 -3
  33. package/dist/{chunk-ZVJKHGE5.js → chunk-24IJZA4M.js} +14 -8
  34. package/dist/chunk-24IJZA4M.js.map +1 -0
  35. package/dist/{chunk-4N4OIVK3.js → chunk-2NVQ5SEA.js} +15 -5
  36. package/dist/chunk-2NVQ5SEA.js.map +1 -0
  37. package/dist/{chunk-ZNVBCKMV.js → chunk-2SIREKBR.js} +2 -2
  38. package/dist/{chunk-N6EWQ5VB.js → chunk-37FOG6AE.js} +14 -7
  39. package/dist/chunk-37FOG6AE.js.map +1 -0
  40. package/dist/{chunk-UQRKAM2R.js → chunk-3M2KK7O7.js} +3 -3
  41. package/dist/{chunk-P6FATPXQ.js → chunk-3ZCVY3T6.js} +2 -2
  42. package/dist/{chunk-PBEHTFUG.js → chunk-4CGWLHPQ.js} +6 -6
  43. package/dist/{chunk-PFHDQY5L.js → chunk-56Z4NOC6.js} +3 -3
  44. package/dist/{chunk-GLSCL74M.js → chunk-5AVIUJP4.js} +13 -9
  45. package/dist/chunk-5AVIUJP4.js.map +1 -0
  46. package/dist/{chunk-F7X7MPK4.js → chunk-5BGHAVBN.js} +2 -2
  47. package/dist/{chunk-QHG7GQKM.js → chunk-5JNEDW7I.js} +2 -2
  48. package/dist/{chunk-GHMINSER.js → chunk-5OWJSDTO.js} +4 -4
  49. package/dist/{chunk-GHMINSER.js.map → chunk-5OWJSDTO.js.map} +1 -1
  50. package/dist/{chunk-DYIR6RC3.js → chunk-5Y4MO7UQ.js} +4 -4
  51. package/dist/{chunk-TLIFNRU5.js → chunk-63LZLRWG.js} +2 -2
  52. package/dist/{chunk-GZISWBCJ.js → chunk-74W56QPY.js} +4 -4
  53. package/dist/{chunk-CLOSXHR4.js → chunk-7KNYLHVX.js} +3 -3
  54. package/dist/chunk-7KNYLHVX.js.map +1 -0
  55. package/dist/{chunk-LFUID7OW.js → chunk-7VJ2SIEI.js} +42 -22
  56. package/dist/chunk-7VJ2SIEI.js.map +1 -0
  57. package/dist/{chunk-WVQDY3UM.js → chunk-AHA7UALU.js} +4 -4
  58. package/dist/{chunk-U277K5GR.js → chunk-AIHBYQHF.js} +259 -123
  59. package/dist/chunk-AIHBYQHF.js.map +1 -0
  60. package/dist/{chunk-S2ORTQGS.js → chunk-ANYX2M6P.js} +3 -3
  61. package/dist/{chunk-6WEPFEMJ.js → chunk-ATKYMRBC.js} +4 -4
  62. package/dist/{chunk-7UHLO4ZN.js → chunk-B2HU55QD.js} +2 -2
  63. package/dist/{chunk-Y22JWHCP.js → chunk-BEKMLYQ4.js} +4 -4
  64. package/dist/{chunk-27NCEPKM.js → chunk-BPFXD4EX.js} +23 -3
  65. package/dist/chunk-BPFXD4EX.js.map +1 -0
  66. package/dist/{chunk-7C7OF26T.js → chunk-C2NXAR3D.js} +5 -5
  67. package/dist/{chunk-Z2KP6PNF.js → chunk-CJBWJO5P.js} +6 -6
  68. package/dist/{chunk-Z2KP6PNF.js.map → chunk-CJBWJO5P.js.map} +1 -1
  69. package/dist/{chunk-6WIFF46H.js → chunk-CQLMRCKX.js} +2 -2
  70. package/dist/{chunk-URGHKZPL.js → chunk-CR5UPYIJ.js} +1 -1
  71. package/dist/chunk-CR5UPYIJ.js.map +1 -0
  72. package/dist/{chunk-LMC5L3MM.js → chunk-DS2JXSUA.js} +6 -6
  73. package/dist/{chunk-X6Z2SIRF.js → chunk-E2JIE4S3.js} +2 -2
  74. package/dist/{chunk-EQ6C2ZPT.js → chunk-E7Y4J4GL.js} +2 -2
  75. package/dist/{chunk-LZN6DTFI.js → chunk-ECDM6YRX.js} +2 -2
  76. package/dist/{chunk-WRLWEYHY.js → chunk-EFINFZIF.js} +11 -1
  77. package/dist/chunk-EFINFZIF.js.map +1 -0
  78. package/dist/{chunk-2T2TGRWE.js → chunk-EM56MHN5.js} +6 -6
  79. package/dist/{chunk-NK4LGBGQ.js → chunk-EQXOJH6O.js} +4 -4
  80. package/dist/{chunk-OK44MD3C.js → chunk-ET3U2C3A.js} +2 -2
  81. package/dist/{chunk-RF5WDM25.js → chunk-EU4G7PQH.js} +2 -2
  82. package/dist/{chunk-K5JNK63R.js → chunk-EUCUYK5E.js} +10 -10
  83. package/dist/{chunk-2ODEFG6K.js → chunk-EWSIJDWO.js} +4 -4
  84. package/dist/{chunk-LJ744WXU.js → chunk-F2FD4LSB.js} +2 -2
  85. package/dist/{chunk-L4UL4IAR.js → chunk-F7ENMZYJ.js} +2 -2
  86. package/dist/{chunk-KBIS64X4.js → chunk-FIIVYQOW.js} +5 -5
  87. package/dist/{chunk-TBVDI3LY.js → chunk-FPK2LPLR.js} +8 -8
  88. package/dist/chunk-FPK2LPLR.js.map +1 -0
  89. package/dist/{chunk-BQJ5ORU5.js → chunk-FQEUJGBV.js} +2 -2
  90. package/dist/{chunk-UORWAG7K.js → chunk-FY4FFNKK.js} +2 -2
  91. package/dist/{chunk-MMWX5OT5.js → chunk-GDCYZGPB.js} +2 -2
  92. package/dist/{chunk-7ONMS7QI.js → chunk-H6Q7GKLI.js} +2 -2
  93. package/dist/{chunk-654RE5YC.js → chunk-HDAPQF6Q.js} +3 -3
  94. package/dist/{chunk-5SMCBPJ2.js → chunk-HRLMUZLI.js} +5 -5
  95. package/dist/{chunk-R4GLRJ55.js → chunk-HRNQYGLQ.js} +2 -2
  96. package/dist/{chunk-HTRLQ4ZZ.js → chunk-I4S7IZSS.js} +321 -235
  97. package/dist/chunk-I4S7IZSS.js.map +1 -0
  98. package/dist/{chunk-UNAMWK2Q.js → chunk-IN4XZJYD.js} +4 -3
  99. package/dist/{chunk-UNAMWK2Q.js.map → chunk-IN4XZJYD.js.map} +1 -1
  100. package/dist/{chunk-2RH5SEY7.js → chunk-ISIXU45J.js} +2 -2
  101. package/dist/chunk-ISIXU45J.js.map +1 -0
  102. package/dist/{chunk-NHEKQWFI.js → chunk-J4L4AS2W.js} +2 -2
  103. package/dist/{chunk-UMV5GBTJ.js → chunk-JPSOFWJR.js} +2 -2
  104. package/dist/{chunk-A52BK5AY.js → chunk-JRCO67NG.js} +2 -2
  105. package/dist/{chunk-FVKQ5QUC.js → chunk-JW3I3NNZ.js} +2 -2
  106. package/dist/{chunk-BNYDOF2Q.js → chunk-JZMPSQBH.js} +4 -4
  107. package/dist/{chunk-ZK2WT532.js → chunk-K5TVSOPQ.js} +5 -5
  108. package/dist/{chunk-2IASHJPS.js → chunk-K75SL74I.js} +2 -2
  109. package/dist/{chunk-O3NGOHXQ.js → chunk-KA4AAUST.js} +2 -2
  110. package/dist/chunk-KHSBMLQE.js +161 -0
  111. package/dist/chunk-KHSBMLQE.js.map +1 -0
  112. package/dist/{chunk-QQLXKDGC.js → chunk-KUGUML7H.js} +3 -3
  113. package/dist/{chunk-AMSSAOOB.js → chunk-L4J5NC2Q.js} +2 -2
  114. package/dist/{chunk-AYOQZJDB.js → chunk-LIX4QPMM.js} +2 -2
  115. package/dist/{chunk-WIUH6EJ7.js → chunk-LWQFGR34.js} +3 -3
  116. package/dist/{chunk-QNOWNCZS.js → chunk-MMSSHMHW.js} +2 -2
  117. package/dist/{chunk-T5EXREMW.js → chunk-N25Z6PR4.js} +6 -5
  118. package/dist/chunk-N25Z6PR4.js.map +1 -0
  119. package/dist/{chunk-ND6S2DKC.js → chunk-N5S2BCW3.js} +2 -2
  120. package/dist/{chunk-X5RGG3ZW.js → chunk-NIZH2TYZ.js} +2 -2
  121. package/dist/{chunk-SXPLIRQH.js → chunk-NLDBQHDV.js} +2 -2
  122. package/dist/{chunk-AI35LNWQ.js → chunk-NQQ4MOPC.js} +4 -4
  123. package/dist/{chunk-B6EWMGFX.js → chunk-NUBI6PYH.js} +2 -2
  124. package/dist/{chunk-ID4ZBC3X.js → chunk-NYEXUZDW.js} +4 -4
  125. package/dist/{chunk-GU6QXHPZ.js → chunk-OIBFIWVJ.js} +4 -4
  126. package/dist/chunk-OIBFIWVJ.js.map +1 -0
  127. package/dist/{chunk-PWAMX5KU.js → chunk-OOLF5FU2.js} +2 -2
  128. package/dist/{chunk-WQUIJPN4.js → chunk-OQA7UF2Q.js} +3 -3
  129. package/dist/{chunk-7JRLCP2J.js → chunk-ORJPICJI.js} +2 -2
  130. package/dist/{chunk-IF2M43G4.js → chunk-PBRD75JF.js} +2 -2
  131. package/dist/{chunk-RKBCUP5D.js → chunk-PDCBL23X.js} +39 -17
  132. package/dist/chunk-PDCBL23X.js.map +1 -0
  133. package/dist/{chunk-BSEPI3HD.js → chunk-PR36DD2X.js} +7 -7
  134. package/dist/{chunk-52ZFNK46.js → chunk-PV4HIC4E.js} +2 -2
  135. package/dist/{chunk-TU6ZJTYT.js → chunk-PZNK4HTV.js} +3 -3
  136. package/dist/{chunk-LUQBG637.js → chunk-QBLPLNPE.js} +3 -3
  137. package/dist/{chunk-UADW5NOU.js → chunk-QZXUISRF.js} +5 -5
  138. package/dist/{chunk-BMAXBTYH.js → chunk-RBXYO7MD.js} +5 -5
  139. package/dist/{chunk-PZN76MMV.js → chunk-RIACRFWA.js} +4 -4
  140. package/dist/{chunk-ICHHNI5E.js → chunk-RL6RNDJQ.js} +8 -8
  141. package/dist/{chunk-4WLI37WK.js → chunk-SJ2P7UXD.js} +7 -7
  142. package/dist/{chunk-2QH3I7QC.js → chunk-SWXS4LV3.js} +11 -11
  143. package/dist/{chunk-4KYKRYRT.js → chunk-TOTCZFRF.js} +2 -2
  144. package/dist/{chunk-CSAN22QG.js → chunk-TT4D52EK.js} +6 -6
  145. package/dist/{chunk-VLRY2UH4.js → chunk-U7CMJY5P.js} +10 -10
  146. package/dist/{chunk-NIUHKKMM.js → chunk-UNKTZDA2.js} +11 -11
  147. package/dist/{chunk-NIUHKKMM.js.map → chunk-UNKTZDA2.js.map} +1 -1
  148. package/dist/{chunk-QVUMKG3Z.js → chunk-UXH4AKH3.js} +95 -151
  149. package/dist/chunk-UXH4AKH3.js.map +1 -0
  150. package/dist/{chunk-PU5ZEV65.js → chunk-UZVHSYIF.js} +2 -2
  151. package/dist/{chunk-3EXQXOQ2.js → chunk-VHKAW5OI.js} +29 -5
  152. package/dist/chunk-VHKAW5OI.js.map +1 -0
  153. package/dist/{chunk-XQGKS4OW.js → chunk-VKZ3TDET.js} +3 -3
  154. package/dist/{chunk-ZOFNZLAA.js → chunk-VLZPUG5A.js} +4 -4
  155. package/dist/{chunk-OR3OHKU6.js → chunk-VSN5FLMI.js} +2 -2
  156. package/dist/{chunk-JQMEXCUZ.js → chunk-VYBBE7RN.js} +8 -8
  157. package/dist/chunk-VYBBE7RN.js.map +1 -0
  158. package/dist/{chunk-SVXFCCSX.js → chunk-WHK4JVKF.js} +8 -8
  159. package/dist/{chunk-YVA6UPRN.js → chunk-X4LDBALX.js} +2 -2
  160. package/dist/{chunk-35CNOVQE.js → chunk-X67E7NIJ.js} +3 -3
  161. package/dist/{chunk-IPF5ORDI.js → chunk-XMARKBUC.js} +3 -3
  162. package/dist/{chunk-B3B6HV5S.js → chunk-XMBBTETD.js} +2 -2
  163. package/dist/{chunk-GQ4MF3CM.js → chunk-XMBTAN5E.js} +28 -14
  164. package/dist/chunk-XMBTAN5E.js.map +1 -0
  165. package/dist/{chunk-FUHUGKDN.js → chunk-XROQP6IQ.js} +4 -4
  166. package/dist/chunk-XWWDZKLS.js +196 -0
  167. package/dist/chunk-XWWDZKLS.js.map +1 -0
  168. package/dist/{chunk-DL4GCSTS.js → chunk-Y2RYUWSQ.js} +10 -10
  169. package/dist/{chunk-7IV7GVOS.js → chunk-YCTSQV7K.js} +5 -5
  170. package/dist/{chunk-IFUYLIEY.js → chunk-YF7P2DG7.js} +2 -2
  171. package/dist/{chunk-PIO6NW7O.js → chunk-ZG7DBIVX.js} +2 -2
  172. package/dist/{chunk-NUZ7ROUZ.js → chunk-ZGJ775X7.js} +2 -2
  173. package/dist/{chunk-6BEBWHNL.js → chunk-ZQQLOEWN.js} +3 -3
  174. package/dist/classified/index.js +5 -5
  175. package/dist/{classified-marker-7HXDMYHI.js → classified-marker-HKMRC7SC.js} +3 -3
  176. package/dist/{reveal-UAPBG743.js → classify-reveal-YSJKJEIR.js} +7 -12
  177. package/dist/classify-reveal-YSJKJEIR.js.map +1 -0
  178. package/dist/{verify-QWO5UKD6.js → classify-verify-ZCTKYQ43.js} +31 -41
  179. package/dist/classify-verify-ZCTKYQ43.js.map +1 -0
  180. package/dist/collection-facade-PPKNUR2J.js +38 -0
  181. package/dist/{computed-LZLSYOPG.js → computed-UCYVPMZA.js} +3 -3
  182. package/dist/consent/index.js +6 -9
  183. package/dist/consent/index.js.map +1 -1
  184. package/dist/cover/index.js +6 -9
  185. package/dist/custody/index.js +11 -13
  186. package/dist/{dead-filter-PZIJ4F4G.js → dead-filter-YOBWRG4O.js} +8 -11
  187. package/dist/{dead-filter-PZIJ4F4G.js.map → dead-filter-YOBWRG4O.js.map} +1 -1
  188. package/dist/debug/index.js +5 -8
  189. package/dist/debug/index.js.map +1 -1
  190. package/dist/delegation-SNALWRMO.js +24 -0
  191. package/dist/derivations/index.js +20 -23
  192. package/dist/derive-4GNU4E4I.js +17 -0
  193. package/dist/directory/index.js +7 -10
  194. package/dist/{dispatch-4BUYPWMJ.js → dispatch-QW32QBLW.js} +17 -20
  195. package/dist/{dispatch-4BUYPWMJ.js.map → dispatch-QW32QBLW.js.map} +1 -1
  196. package/dist/{dispatch-KOPDDPEQ.js → dispatch-V5WLDTVX.js} +5 -5
  197. package/dist/executor-7QN22OKI.js +8 -0
  198. package/dist/executor-BJZJNVBB.js +8 -0
  199. package/dist/executor-JEAAEJUM.js +32 -0
  200. package/dist/export-accessible-TVO2KQPG.js +20 -0
  201. package/dist/extract-partition-43CLDRN4.js +33 -0
  202. package/dist/{fanout-sidecar-FYDRL7F3.js → fanout-sidecar-DDONAFJT.js} +6 -9
  203. package/dist/{fanout-sidecar-FYDRL7F3.js.map → fanout-sidecar-DDONAFJT.js.map} +1 -1
  204. package/dist/forget/index.js +6 -9
  205. package/dist/forget/index.js.map +1 -1
  206. package/dist/guards/index.js +4 -4
  207. package/dist/history/index.js +11 -14
  208. package/dist/history/index.js.map +1 -1
  209. package/dist/i18n/index.js +11 -14
  210. package/dist/i18n/index.js.map +1 -1
  211. package/dist/index.d.ts +2 -2
  212. package/dist/index.js +122 -123
  213. package/dist/index.js.map +1 -1
  214. package/dist/indexing/index.js +5 -5
  215. package/dist/introspection/index.js +8 -11
  216. package/dist/issue-EIHEDAXM.js +16 -0
  217. package/dist/kernel/capsule-requirements.d.ts +84 -0
  218. package/dist/kernel/errors.d.ts +19 -3
  219. package/dist/kernel/export-scope.d.ts +28 -1
  220. package/dist/kernel/store-segment-guard.d.ts +29 -0
  221. package/dist/kernel/types.d.ts +169 -13
  222. package/dist/kernel/validation.d.ts +32 -0
  223. package/dist/kernel/vault.d.ts +5 -5
  224. package/dist/{ledger-UFJCB6T5.js → ledger-BMVUFQ3R.js} +8 -11
  225. package/dist/liberate-7KHXCLNJ.js +23 -0
  226. package/dist/link-set-PC2EJRKL.js +26 -0
  227. package/dist/{managed-secret-H5WYSJ46.js → managed-secret-RPRVEYZA.js} +7 -10
  228. package/dist/materialized-views/index.js +23 -26
  229. package/dist/{migrate-cek-SPESQAAO.js → migrate-cek-DTSCWGEF.js} +2 -2
  230. package/dist/money/index.js +5 -5
  231. package/dist/noydb-AYDNOXAX.js +98 -0
  232. package/dist/on/index.js +11 -13
  233. package/dist/overlay-views/index.js +4 -4
  234. package/dist/periods/index.js +9 -12
  235. package/dist/pod/index.js +65 -67
  236. package/dist/{pod-handle-GJLCOUGK.js → pod-handle-KBPQRN6Q.js} +6 -9
  237. package/dist/{pod-handle-GJLCOUGK.js.map → pod-handle-KBPQRN6Q.js.map} +1 -1
  238. package/dist/policy/index.js +7 -10
  239. package/dist/port/at/index.d.ts +1 -0
  240. package/dist/port/with/admission-authority.d.ts +2 -1
  241. package/dist/port/with/collection-registries.d.ts +37 -0
  242. package/dist/portability/index.js +8 -8
  243. package/dist/{post-register-2AC2STHC.js → post-register-RITSNASO.js} +6 -6
  244. package/dist/query/all/index.js +15 -15
  245. package/dist/query/index.js +7 -7
  246. package/dist/query/live/index.js +7 -7
  247. package/dist/query/reduce/index.js +10 -10
  248. package/dist/query/relate/index.js +9 -9
  249. package/dist/reduce/index.js +8 -8
  250. package/dist/register-BB34SK7E.js +27 -0
  251. package/dist/registry-65L6V5TO.js +20 -0
  252. package/dist/registry-HU62GPWA.js +32 -0
  253. package/dist/registry-SMNK6UM4.js +8 -0
  254. package/dist/registry-X5VPBKCO.js +8 -0
  255. package/dist/request-withdrawal-4SKAH46W.js +26 -0
  256. package/dist/{restore-to-OOPKLAPU.js → restore-to-VQHT67OH.js} +7 -10
  257. package/dist/{restore-to-OOPKLAPU.js.map → restore-to-VQHT67OH.js.map} +1 -1
  258. package/dist/revoke-IF5PX2JY.js +21 -0
  259. package/dist/satellites/index.js +1 -1
  260. package/dist/schema-update/index.js +2 -2
  261. package/dist/sealed-record/index.js +9 -12
  262. package/dist/sealed-record/index.js.map +1 -1
  263. package/dist/search/index.js +4 -4
  264. package/dist/{seed-BVYDPVIW.js → seed-F2OSDZJR.js} +11 -13
  265. package/dist/{seed-BVYDPVIW.js.map → seed-F2OSDZJR.js.map} +1 -1
  266. package/dist/sequence/index.js +6 -9
  267. package/dist/session/index.js +6 -9
  268. package/dist/session/index.js.map +1 -1
  269. package/dist/shadow/index.js +2 -2
  270. package/dist/signer-5P7IZC2K.js +20 -0
  271. package/dist/snapshots/index.js +8 -10
  272. package/dist/snapshots/index.js.map +1 -1
  273. package/dist/{stale-CROGJBIJ.js → stale-PUCZH5GJ.js} +7 -10
  274. package/dist/storage-5EGY5OYE.js +18 -0
  275. package/dist/store/index.js +1 -1
  276. package/dist/{store-coordination-provider-2YD2PTTP.js → store-coordination-provider-SEQM7SHJ.js} +7 -10
  277. package/dist/{store-coordination-provider-2YD2PTTP.js.map → store-coordination-provider-SEQM7SHJ.js.map} +1 -1
  278. package/dist/sync/index.js +13 -15
  279. package/dist/sync/index.js.map +1 -1
  280. package/dist/team/index.js +14 -16
  281. package/dist/tiers/index.js +8 -11
  282. package/dist/to/index.js +2 -2
  283. package/dist/transactions/index.js +3 -3
  284. package/dist/util/index.js +1 -1
  285. package/dist/vault-diff-H7LT5ZBJ.js +8 -0
  286. package/dist/vault-head/index.js +5 -8
  287. package/dist/vault-head/index.js.map +1 -1
  288. package/dist/walk-Z4N7PCZ2.js +17 -0
  289. package/dist/with-audit/portability/export-accessible.d.ts +3 -1
  290. package/dist/with-cargo/vault-diff.d.ts +28 -0
  291. package/dist/with-commit/sequence/index.d.ts +22 -0
  292. package/dist/with-party/team/delegation.d.ts +16 -12
  293. package/dist/with-party/team/keyring.d.ts +77 -0
  294. package/dist/with-party/team/managed-secret.d.ts +40 -3
  295. package/dist/with-party/team/noydb-facade.d.ts +2 -2
  296. package/dist/with-party/team/peer-recover.d.ts +2 -2
  297. package/dist/with-party/team/rotate-recover.d.ts +3 -3
  298. package/dist/with-shape/manifest/storage.d.ts +2 -2
  299. package/dist/with-shape/manifest/writer.d.ts +2 -2
  300. package/dist/with-store/store-middleware.d.ts +18 -5
  301. package/dist/with-sync/engine.d.ts +0 -2
  302. package/dist/withdraw-accessible-CRCIQSTL.js +23 -0
  303. package/package.json +3 -3
  304. package/dist/api-H4B7ZQXP.js +0 -18
  305. package/dist/capsule/enclave-aes/classify/reveal.d.ts +0 -10
  306. package/dist/capsule/enclave-aes/classify/verify.d.ts +0 -36
  307. package/dist/chunk-27NCEPKM.js.map +0 -1
  308. package/dist/chunk-2RH5SEY7.js.map +0 -1
  309. package/dist/chunk-3EXQXOQ2.js.map +0 -1
  310. package/dist/chunk-4N4OIVK3.js.map +0 -1
  311. package/dist/chunk-5A3HOTP5.js +0 -591
  312. package/dist/chunk-5A3HOTP5.js.map +0 -1
  313. package/dist/chunk-CLOSXHR4.js.map +0 -1
  314. package/dist/chunk-EPPAEGH5.js +0 -157
  315. package/dist/chunk-EPPAEGH5.js.map +0 -1
  316. package/dist/chunk-GLSCL74M.js.map +0 -1
  317. package/dist/chunk-GQ4MF3CM.js.map +0 -1
  318. package/dist/chunk-GU6QXHPZ.js.map +0 -1
  319. package/dist/chunk-HTRLQ4ZZ.js.map +0 -1
  320. package/dist/chunk-JQMEXCUZ.js.map +0 -1
  321. package/dist/chunk-LFUID7OW.js.map +0 -1
  322. package/dist/chunk-N6EWQ5VB.js.map +0 -1
  323. package/dist/chunk-NH2UOV3B.js +0 -18
  324. package/dist/chunk-NH2UOV3B.js.map +0 -1
  325. package/dist/chunk-O6VOR4NH.js +0 -27
  326. package/dist/chunk-O6VOR4NH.js.map +0 -1
  327. package/dist/chunk-ODBOHPZU.js +0 -22
  328. package/dist/chunk-ODBOHPZU.js.map +0 -1
  329. package/dist/chunk-Q4DBU5RM.js +0 -78
  330. package/dist/chunk-Q4DBU5RM.js.map +0 -1
  331. package/dist/chunk-QVUMKG3Z.js.map +0 -1
  332. package/dist/chunk-RKBCUP5D.js.map +0 -1
  333. package/dist/chunk-T5EXREMW.js.map +0 -1
  334. package/dist/chunk-TBVDI3LY.js.map +0 -1
  335. package/dist/chunk-U277K5GR.js.map +0 -1
  336. package/dist/chunk-URGHKZPL.js.map +0 -1
  337. package/dist/chunk-VZFTON37.js +0 -40
  338. package/dist/chunk-VZFTON37.js.map +0 -1
  339. package/dist/chunk-WRLWEYHY.js.map +0 -1
  340. package/dist/chunk-ZVJKHGE5.js.map +0 -1
  341. package/dist/collection-facade-V63BEBGU.js +0 -41
  342. package/dist/delegation-7SSGIETH.js +0 -26
  343. package/dist/derive-IMI3BMDS.js +0 -20
  344. package/dist/executor-7SY3M6TZ.js +0 -8
  345. package/dist/executor-SNHW4ELF.js +0 -35
  346. package/dist/executor-Z3IKK7G3.js +0 -8
  347. package/dist/export-accessible-O7DIVFUO.js +0 -22
  348. package/dist/extract-partition-ELZEJKXM.js +0 -35
  349. package/dist/find-KWB2RYWJ.js +0 -10
  350. package/dist/issue-5ZHXK4HJ.js +0 -19
  351. package/dist/liberate-OEOSNNFH.js +0 -25
  352. package/dist/link-set-KMUBFN2L.js +0 -29
  353. package/dist/noydb-QDZ4QIKO.js +0 -100
  354. package/dist/register-PIORIMMR.js +0 -30
  355. package/dist/registry-BIMICFUH.js +0 -23
  356. package/dist/registry-JGWLW53D.js +0 -35
  357. package/dist/registry-SELCBYEQ.js +0 -8
  358. package/dist/registry-W327UNYH.js +0 -8
  359. package/dist/request-withdrawal-K3SXXODI.js +0 -28
  360. package/dist/reveal-UAPBG743.js.map +0 -1
  361. package/dist/revoke-6AFVXTWF.js +0 -24
  362. package/dist/signer-TW5MAQJP.js +0 -23
  363. package/dist/storage-SO2L2Z5J.js +0 -21
  364. package/dist/vault-diff-C6WUJFNP.js +0 -8
  365. package/dist/verify-QWO5UKD6.js.map +0 -1
  366. package/dist/walk-3KEOL7BY.js +0 -20
  367. package/dist/withdraw-accessible-OZU525ND.js +0 -25
  368. package/dist/withdraw-accessible-OZU525ND.js.map +0 -1
  369. /package/dist/{api-H4B7ZQXP.js.map → api-QSEKT4KS.js.map} +0 -0
  370. /package/dist/{capsule-YQKQZPH7.js.map → capsule-YAITMH77.js.map} +0 -0
  371. /package/dist/{chunk-PREYKC76.js.map → chunk-24AGG4PP.js.map} +0 -0
  372. /package/dist/{chunk-ZNVBCKMV.js.map → chunk-2SIREKBR.js.map} +0 -0
  373. /package/dist/{chunk-UQRKAM2R.js.map → chunk-3M2KK7O7.js.map} +0 -0
  374. /package/dist/{chunk-P6FATPXQ.js.map → chunk-3ZCVY3T6.js.map} +0 -0
  375. /package/dist/{chunk-PBEHTFUG.js.map → chunk-4CGWLHPQ.js.map} +0 -0
  376. /package/dist/{chunk-PFHDQY5L.js.map → chunk-56Z4NOC6.js.map} +0 -0
  377. /package/dist/{chunk-F7X7MPK4.js.map → chunk-5BGHAVBN.js.map} +0 -0
  378. /package/dist/{chunk-QHG7GQKM.js.map → chunk-5JNEDW7I.js.map} +0 -0
  379. /package/dist/{chunk-DYIR6RC3.js.map → chunk-5Y4MO7UQ.js.map} +0 -0
  380. /package/dist/{chunk-TLIFNRU5.js.map → chunk-63LZLRWG.js.map} +0 -0
  381. /package/dist/{chunk-GZISWBCJ.js.map → chunk-74W56QPY.js.map} +0 -0
  382. /package/dist/{chunk-WVQDY3UM.js.map → chunk-AHA7UALU.js.map} +0 -0
  383. /package/dist/{chunk-S2ORTQGS.js.map → chunk-ANYX2M6P.js.map} +0 -0
  384. /package/dist/{chunk-6WEPFEMJ.js.map → chunk-ATKYMRBC.js.map} +0 -0
  385. /package/dist/{chunk-7UHLO4ZN.js.map → chunk-B2HU55QD.js.map} +0 -0
  386. /package/dist/{chunk-Y22JWHCP.js.map → chunk-BEKMLYQ4.js.map} +0 -0
  387. /package/dist/{chunk-7C7OF26T.js.map → chunk-C2NXAR3D.js.map} +0 -0
  388. /package/dist/{chunk-6WIFF46H.js.map → chunk-CQLMRCKX.js.map} +0 -0
  389. /package/dist/{chunk-LMC5L3MM.js.map → chunk-DS2JXSUA.js.map} +0 -0
  390. /package/dist/{chunk-X6Z2SIRF.js.map → chunk-E2JIE4S3.js.map} +0 -0
  391. /package/dist/{chunk-EQ6C2ZPT.js.map → chunk-E7Y4J4GL.js.map} +0 -0
  392. /package/dist/{chunk-LZN6DTFI.js.map → chunk-ECDM6YRX.js.map} +0 -0
  393. /package/dist/{chunk-2T2TGRWE.js.map → chunk-EM56MHN5.js.map} +0 -0
  394. /package/dist/{chunk-NK4LGBGQ.js.map → chunk-EQXOJH6O.js.map} +0 -0
  395. /package/dist/{chunk-OK44MD3C.js.map → chunk-ET3U2C3A.js.map} +0 -0
  396. /package/dist/{chunk-RF5WDM25.js.map → chunk-EU4G7PQH.js.map} +0 -0
  397. /package/dist/{chunk-K5JNK63R.js.map → chunk-EUCUYK5E.js.map} +0 -0
  398. /package/dist/{chunk-2ODEFG6K.js.map → chunk-EWSIJDWO.js.map} +0 -0
  399. /package/dist/{chunk-LJ744WXU.js.map → chunk-F2FD4LSB.js.map} +0 -0
  400. /package/dist/{chunk-L4UL4IAR.js.map → chunk-F7ENMZYJ.js.map} +0 -0
  401. /package/dist/{chunk-KBIS64X4.js.map → chunk-FIIVYQOW.js.map} +0 -0
  402. /package/dist/{chunk-BQJ5ORU5.js.map → chunk-FQEUJGBV.js.map} +0 -0
  403. /package/dist/{chunk-UORWAG7K.js.map → chunk-FY4FFNKK.js.map} +0 -0
  404. /package/dist/{chunk-MMWX5OT5.js.map → chunk-GDCYZGPB.js.map} +0 -0
  405. /package/dist/{chunk-7ONMS7QI.js.map → chunk-H6Q7GKLI.js.map} +0 -0
  406. /package/dist/{chunk-654RE5YC.js.map → chunk-HDAPQF6Q.js.map} +0 -0
  407. /package/dist/{chunk-5SMCBPJ2.js.map → chunk-HRLMUZLI.js.map} +0 -0
  408. /package/dist/{chunk-R4GLRJ55.js.map → chunk-HRNQYGLQ.js.map} +0 -0
  409. /package/dist/{chunk-NHEKQWFI.js.map → chunk-J4L4AS2W.js.map} +0 -0
  410. /package/dist/{chunk-UMV5GBTJ.js.map → chunk-JPSOFWJR.js.map} +0 -0
  411. /package/dist/{chunk-A52BK5AY.js.map → chunk-JRCO67NG.js.map} +0 -0
  412. /package/dist/{chunk-FVKQ5QUC.js.map → chunk-JW3I3NNZ.js.map} +0 -0
  413. /package/dist/{chunk-BNYDOF2Q.js.map → chunk-JZMPSQBH.js.map} +0 -0
  414. /package/dist/{chunk-ZK2WT532.js.map → chunk-K5TVSOPQ.js.map} +0 -0
  415. /package/dist/{chunk-2IASHJPS.js.map → chunk-K75SL74I.js.map} +0 -0
  416. /package/dist/{chunk-O3NGOHXQ.js.map → chunk-KA4AAUST.js.map} +0 -0
  417. /package/dist/{chunk-QQLXKDGC.js.map → chunk-KUGUML7H.js.map} +0 -0
  418. /package/dist/{chunk-AMSSAOOB.js.map → chunk-L4J5NC2Q.js.map} +0 -0
  419. /package/dist/{chunk-AYOQZJDB.js.map → chunk-LIX4QPMM.js.map} +0 -0
  420. /package/dist/{chunk-WIUH6EJ7.js.map → chunk-LWQFGR34.js.map} +0 -0
  421. /package/dist/{chunk-QNOWNCZS.js.map → chunk-MMSSHMHW.js.map} +0 -0
  422. /package/dist/{chunk-ND6S2DKC.js.map → chunk-N5S2BCW3.js.map} +0 -0
  423. /package/dist/{chunk-X5RGG3ZW.js.map → chunk-NIZH2TYZ.js.map} +0 -0
  424. /package/dist/{chunk-SXPLIRQH.js.map → chunk-NLDBQHDV.js.map} +0 -0
  425. /package/dist/{chunk-AI35LNWQ.js.map → chunk-NQQ4MOPC.js.map} +0 -0
  426. /package/dist/{chunk-B6EWMGFX.js.map → chunk-NUBI6PYH.js.map} +0 -0
  427. /package/dist/{chunk-ID4ZBC3X.js.map → chunk-NYEXUZDW.js.map} +0 -0
  428. /package/dist/{chunk-PWAMX5KU.js.map → chunk-OOLF5FU2.js.map} +0 -0
  429. /package/dist/{chunk-WQUIJPN4.js.map → chunk-OQA7UF2Q.js.map} +0 -0
  430. /package/dist/{chunk-7JRLCP2J.js.map → chunk-ORJPICJI.js.map} +0 -0
  431. /package/dist/{chunk-IF2M43G4.js.map → chunk-PBRD75JF.js.map} +0 -0
  432. /package/dist/{chunk-BSEPI3HD.js.map → chunk-PR36DD2X.js.map} +0 -0
  433. /package/dist/{chunk-52ZFNK46.js.map → chunk-PV4HIC4E.js.map} +0 -0
  434. /package/dist/{chunk-TU6ZJTYT.js.map → chunk-PZNK4HTV.js.map} +0 -0
  435. /package/dist/{chunk-LUQBG637.js.map → chunk-QBLPLNPE.js.map} +0 -0
  436. /package/dist/{chunk-UADW5NOU.js.map → chunk-QZXUISRF.js.map} +0 -0
  437. /package/dist/{chunk-BMAXBTYH.js.map → chunk-RBXYO7MD.js.map} +0 -0
  438. /package/dist/{chunk-PZN76MMV.js.map → chunk-RIACRFWA.js.map} +0 -0
  439. /package/dist/{chunk-ICHHNI5E.js.map → chunk-RL6RNDJQ.js.map} +0 -0
  440. /package/dist/{chunk-4WLI37WK.js.map → chunk-SJ2P7UXD.js.map} +0 -0
  441. /package/dist/{chunk-2QH3I7QC.js.map → chunk-SWXS4LV3.js.map} +0 -0
  442. /package/dist/{chunk-4KYKRYRT.js.map → chunk-TOTCZFRF.js.map} +0 -0
  443. /package/dist/{chunk-CSAN22QG.js.map → chunk-TT4D52EK.js.map} +0 -0
  444. /package/dist/{chunk-VLRY2UH4.js.map → chunk-U7CMJY5P.js.map} +0 -0
  445. /package/dist/{chunk-PU5ZEV65.js.map → chunk-UZVHSYIF.js.map} +0 -0
  446. /package/dist/{chunk-XQGKS4OW.js.map → chunk-VKZ3TDET.js.map} +0 -0
  447. /package/dist/{chunk-ZOFNZLAA.js.map → chunk-VLZPUG5A.js.map} +0 -0
  448. /package/dist/{chunk-OR3OHKU6.js.map → chunk-VSN5FLMI.js.map} +0 -0
  449. /package/dist/{chunk-SVXFCCSX.js.map → chunk-WHK4JVKF.js.map} +0 -0
  450. /package/dist/{chunk-YVA6UPRN.js.map → chunk-X4LDBALX.js.map} +0 -0
  451. /package/dist/{chunk-35CNOVQE.js.map → chunk-X67E7NIJ.js.map} +0 -0
  452. /package/dist/{chunk-IPF5ORDI.js.map → chunk-XMARKBUC.js.map} +0 -0
  453. /package/dist/{chunk-B3B6HV5S.js.map → chunk-XMBBTETD.js.map} +0 -0
  454. /package/dist/{chunk-FUHUGKDN.js.map → chunk-XROQP6IQ.js.map} +0 -0
  455. /package/dist/{chunk-DL4GCSTS.js.map → chunk-Y2RYUWSQ.js.map} +0 -0
  456. /package/dist/{chunk-7IV7GVOS.js.map → chunk-YCTSQV7K.js.map} +0 -0
  457. /package/dist/{chunk-IFUYLIEY.js.map → chunk-YF7P2DG7.js.map} +0 -0
  458. /package/dist/{chunk-PIO6NW7O.js.map → chunk-ZG7DBIVX.js.map} +0 -0
  459. /package/dist/{chunk-NUZ7ROUZ.js.map → chunk-ZGJ775X7.js.map} +0 -0
  460. /package/dist/{chunk-6BEBWHNL.js.map → chunk-ZQQLOEWN.js.map} +0 -0
  461. /package/dist/{classified-marker-7HXDMYHI.js.map → classified-marker-HKMRC7SC.js.map} +0 -0
  462. /package/dist/{collection-facade-V63BEBGU.js.map → collection-facade-PPKNUR2J.js.map} +0 -0
  463. /package/dist/{computed-LZLSYOPG.js.map → computed-UCYVPMZA.js.map} +0 -0
  464. /package/dist/{delegation-7SSGIETH.js.map → delegation-SNALWRMO.js.map} +0 -0
  465. /package/dist/{derive-IMI3BMDS.js.map → derive-4GNU4E4I.js.map} +0 -0
  466. /package/dist/{dispatch-KOPDDPEQ.js.map → dispatch-V5WLDTVX.js.map} +0 -0
  467. /package/dist/{executor-7SY3M6TZ.js.map → executor-7QN22OKI.js.map} +0 -0
  468. /package/dist/{executor-SNHW4ELF.js.map → executor-BJZJNVBB.js.map} +0 -0
  469. /package/dist/{executor-Z3IKK7G3.js.map → executor-JEAAEJUM.js.map} +0 -0
  470. /package/dist/{export-accessible-O7DIVFUO.js.map → export-accessible-TVO2KQPG.js.map} +0 -0
  471. /package/dist/{extract-partition-ELZEJKXM.js.map → extract-partition-43CLDRN4.js.map} +0 -0
  472. /package/dist/{find-KWB2RYWJ.js.map → issue-EIHEDAXM.js.map} +0 -0
  473. /package/dist/{issue-5ZHXK4HJ.js.map → ledger-BMVUFQ3R.js.map} +0 -0
  474. /package/dist/{ledger-UFJCB6T5.js.map → liberate-7KHXCLNJ.js.map} +0 -0
  475. /package/dist/{liberate-OEOSNNFH.js.map → link-set-PC2EJRKL.js.map} +0 -0
  476. /package/dist/{link-set-KMUBFN2L.js.map → managed-secret-RPRVEYZA.js.map} +0 -0
  477. /package/dist/{migrate-cek-SPESQAAO.js.map → migrate-cek-DTSCWGEF.js.map} +0 -0
  478. /package/dist/{managed-secret-H5WYSJ46.js.map → noydb-AYDNOXAX.js.map} +0 -0
  479. /package/dist/{post-register-2AC2STHC.js.map → post-register-RITSNASO.js.map} +0 -0
  480. /package/dist/{noydb-QDZ4QIKO.js.map → register-BB34SK7E.js.map} +0 -0
  481. /package/dist/{register-PIORIMMR.js.map → registry-65L6V5TO.js.map} +0 -0
  482. /package/dist/{registry-BIMICFUH.js.map → registry-HU62GPWA.js.map} +0 -0
  483. /package/dist/{registry-JGWLW53D.js.map → registry-SMNK6UM4.js.map} +0 -0
  484. /package/dist/{registry-SELCBYEQ.js.map → registry-X5VPBKCO.js.map} +0 -0
  485. /package/dist/{registry-W327UNYH.js.map → request-withdrawal-4SKAH46W.js.map} +0 -0
  486. /package/dist/{request-withdrawal-K3SXXODI.js.map → revoke-IF5PX2JY.js.map} +0 -0
  487. /package/dist/{revoke-6AFVXTWF.js.map → signer-5P7IZC2K.js.map} +0 -0
  488. /package/dist/{signer-TW5MAQJP.js.map → stale-PUCZH5GJ.js.map} +0 -0
  489. /package/dist/{stale-CROGJBIJ.js.map → storage-5EGY5OYE.js.map} +0 -0
  490. /package/dist/{storage-SO2L2Z5J.js.map → vault-diff-H7LT5ZBJ.js.map} +0 -0
  491. /package/dist/{vault-diff-C6WUJFNP.js.map → walk-Z4N7PCZ2.js.map} +0 -0
  492. /package/dist/{walk-3KEOL7BY.js.map → withdraw-accessible-CRCIQSTL.js.map} +0 -0
@@ -3,23 +3,21 @@ import {
3
3
  SyncEngine,
4
4
  SyncTransaction,
5
5
  bootstrapKeyrings
6
- } from "../chunk-N6EWQ5VB.js";
6
+ } from "../chunk-37FOG6AE.js";
7
7
  import {
8
8
  NO_SYNC
9
- } from "../chunk-7UHLO4ZN.js";
10
- import "../chunk-A52BK5AY.js";
11
- import "../chunk-QVUMKG3Z.js";
12
- import "../chunk-6BEBWHNL.js";
13
- import "../chunk-XQGKS4OW.js";
14
- import "../chunk-LJ744WXU.js";
15
- import "../chunk-WRLWEYHY.js";
16
- import "../chunk-O6VOR4NH.js";
17
- import "../chunk-VZFTON37.js";
18
- import "../chunk-NH2UOV3B.js";
19
- import "../chunk-HTRLQ4ZZ.js";
20
- import "../chunk-EPPAEGH5.js";
21
- import "../chunk-URGHKZPL.js";
22
- import "../chunk-2RH5SEY7.js";
9
+ } from "../chunk-B2HU55QD.js";
10
+ import "../chunk-JRCO67NG.js";
11
+ import "../chunk-UXH4AKH3.js";
12
+ import "../chunk-ZQQLOEWN.js";
13
+ import "../chunk-KHSBMLQE.js";
14
+ import "../chunk-VKZ3TDET.js";
15
+ import "../chunk-F2FD4LSB.js";
16
+ import "../chunk-EFINFZIF.js";
17
+ import "../chunk-I4S7IZSS.js";
18
+ import "../chunk-XWWDZKLS.js";
19
+ import "../chunk-CR5UPYIJ.js";
20
+ import "../chunk-ISIXU45J.js";
23
21
 
24
22
  // src/with-sync/active.ts
25
23
  function withSync(options) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/with-sync/active.ts"],"sourcesContent":["/**\n * Active sync strategy — `withSync()` returns the real implementation\n * that wires the `SyncEngine`, `SyncTransaction`, and `PresenceHandle`\n * constructors into the Noydb / Vault / Collection hot paths.\n *\n * Consumers opt in by:\n *\n * ```ts\n * import { createNoydb } from '@noy-db/hub'\n * import { withSync } from '@noy-db/hub/sync'\n *\n * const db = await createNoydb({\n * store: localStore,\n * sync: remoteStore,\n * user: ...,\n * syncStrategy: withSync(),\n * })\n * ```\n *\n * The factory delegates to the existing `sync.ts`,\n * `sync-transaction.ts`, and `presence.ts` modules. Splitting the\n * import chain through this file is what lets tsup tree-shake the\n * ~856 LOC of replication + presence machinery out of the default\n * bundle when no `withSync()` import is present.\n *\n * Keyring + grant/revoke/magic-link/delegation stay in the always-on\n * core (or tree-shake via direct named imports) — those are required\n * for any multi-user vault, even purely local ones.\n *\n * @public\n */\n\nimport type { SyncStrategy, BuildSyncEngineOptions } from './strategy.js'\nimport type { PresenceHandleOpts } from './presence.js'\nimport type { Vault } from '../kernel/vault.js'\nimport { SyncEngine } from './engine.js'\nimport { SyncTransaction } from './transaction.js'\nimport { PresenceHandle } from './presence.js'\nimport { bootstrapKeyrings } from './reserved-mirror.js'\n\n/**\n * core#107 — `arbiter: true` makes this device the vault's ARBITER: its\n * admission refusals are replicated so the writer finds out, instead of\n * staying local to the device that judged them.\n *\n * ⚠️ One arbiter, named by configuration on the device that is to be it\n * (the admin host, or the daemon) — ruled over a quorum because the failure\n * mode is legible: no arbiter configured means no replication, which is\n * exactly the pre-core#107 behaviour. It is NOT an authority proof: nothing\n * stops a member hand-writing `_sync_rejections`, and the reason that is\n * tolerable is the report-only ruling — a replicated refusal never deletes,\n * tombstones or retracts anything, so the worst a forged one does is show\n * somebody a notice about their own record.\n *\n * ⚠️ THE CONDITION THAT WOULD MAKE THAT NON-BOUNDARY A REAL ONE, named by\n * pilot-1 when they accepted it: every member is currently staff of the same\n * firm, and a forged refusal is sealed under the refused record's own\n * collection DEK — so a forger can only show a notice about a record they\n * could already read. ⛔ If EXTERNAL `client`-role users ever hold\n * collections of their own, \"who may write `_sync_rejections`\" stops being\n * cosmetic and this needs an authority design, not a flag. Do not read the\n * paragraph above as a general safety argument; it is an argument about one\n * topology, and this is the trigger to re-open it.\n */\nexport interface WithSyncOptions {\n readonly arbiter?: boolean\n}\n\nexport function withSync(options?: WithSyncOptions): SyncStrategy {\n return {\n bootstrapKeyrings,\n buildSyncEngine(opts: BuildSyncEngineOptions): SyncEngine {\n return new SyncEngine({ ...opts, ...(options?.arbiter === true && { arbiter: true }) })\n },\n buildSyncTransaction(vault: Vault, engine: SyncEngine): SyncTransaction {\n return new SyncTransaction(vault, engine)\n },\n buildPresence<P>(opts: PresenceHandleOpts): PresenceHandle<P> {\n return new PresenceHandle<P>(opts)\n },\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAoEO,SAAS,SAAS,SAAyC;AAChE,SAAO;AAAA,IACL;AAAA,IACA,gBAAgB,MAA0C;AACxD,aAAO,IAAI,WAAW,EAAE,GAAG,MAAM,GAAI,SAAS,YAAY,QAAQ,EAAE,SAAS,KAAK,EAAG,CAAC;AAAA,IACxF;AAAA,IACA,qBAAqB,OAAc,QAAqC;AACtE,aAAO,IAAI,gBAAgB,OAAO,MAAM;AAAA,IAC1C;AAAA,IACA,cAAiB,MAA6C;AAC5D,aAAO,IAAI,eAAkB,IAAI;AAAA,IACnC;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/with-sync/active.ts"],"sourcesContent":["/**\n * Active sync strategy — `withSync()` returns the real implementation\n * that wires the `SyncEngine`, `SyncTransaction`, and `PresenceHandle`\n * constructors into the Noydb / Vault / Collection hot paths.\n *\n * Consumers opt in by:\n *\n * ```ts\n * import { createNoydb } from '@noy-db/hub'\n * import { withSync } from '@noy-db/hub/sync'\n *\n * const db = await createNoydb({\n * store: localStore,\n * sync: remoteStore,\n * user: ...,\n * syncStrategy: withSync(),\n * })\n * ```\n *\n * The factory delegates to the existing `sync.ts`,\n * `sync-transaction.ts`, and `presence.ts` modules. Splitting the\n * import chain through this file is what lets tsup tree-shake the\n * ~856 LOC of replication + presence machinery out of the default\n * bundle when no `withSync()` import is present.\n *\n * Keyring + grant/revoke/magic-link/delegation stay in the always-on\n * core (or tree-shake via direct named imports) — those are required\n * for any multi-user vault, even purely local ones.\n *\n * @public\n */\n\nimport type { SyncStrategy, BuildSyncEngineOptions } from './strategy.js'\nimport type { PresenceHandleOpts } from './presence.js'\nimport type { Vault } from '../kernel/vault.js'\nimport { SyncEngine } from './engine.js'\nimport { SyncTransaction } from './transaction.js'\nimport { PresenceHandle } from './presence.js'\nimport { bootstrapKeyrings } from './reserved-mirror.js'\n\n/**\n * core#107 — `arbiter: true` makes this device the vault's ARBITER: its\n * admission refusals are replicated so the writer finds out, instead of\n * staying local to the device that judged them.\n *\n * ⚠️ One arbiter, named by configuration on the device that is to be it\n * (the admin host, or the daemon) — ruled over a quorum because the failure\n * mode is legible: no arbiter configured means no replication, which is\n * exactly the pre-core#107 behaviour. It is NOT an authority proof: nothing\n * stops a member hand-writing `_sync_rejections`, and the reason that is\n * tolerable is the report-only ruling — a replicated refusal never deletes,\n * tombstones or retracts anything, so the worst a forged one does is show\n * somebody a notice about their own record.\n *\n * ⚠️ THE CONDITION THAT WOULD MAKE THAT NON-BOUNDARY A REAL ONE, named by\n * pilot-1 when they accepted it: every member is currently staff of the same\n * firm, and a forged refusal is sealed under the refused record's own\n * collection DEK — so a forger can only show a notice about a record they\n * could already read. ⛔ If EXTERNAL `client`-role users ever hold\n * collections of their own, \"who may write `_sync_rejections`\" stops being\n * cosmetic and this needs an authority design, not a flag. Do not read the\n * paragraph above as a general safety argument; it is an argument about one\n * topology, and this is the trigger to re-open it.\n */\nexport interface WithSyncOptions {\n readonly arbiter?: boolean\n}\n\nexport function withSync(options?: WithSyncOptions): SyncStrategy {\n return {\n bootstrapKeyrings,\n buildSyncEngine(opts: BuildSyncEngineOptions): SyncEngine {\n return new SyncEngine({ ...opts, ...(options?.arbiter === true && { arbiter: true }) })\n },\n buildSyncTransaction(vault: Vault, engine: SyncEngine): SyncTransaction {\n return new SyncTransaction(vault, engine)\n },\n buildPresence<P>(opts: PresenceHandleOpts): PresenceHandle<P> {\n return new PresenceHandle<P>(opts)\n },\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAoEO,SAAS,SAAS,SAAyC;AAChE,SAAO;AAAA,IACL;AAAA,IACA,gBAAgB,MAA0C;AACxD,aAAO,IAAI,WAAW,EAAE,GAAG,MAAM,GAAI,SAAS,YAAY,QAAQ,EAAE,SAAS,KAAK,EAAG,CAAC;AAAA,IACxF;AAAA,IACA,qBAAqB,OAAc,QAAqC;AACtE,aAAO,IAAI,gBAAgB,OAAO,MAAM;AAAA,IAC1C;AAAA,IACA,cAAiB,MAA6C;AAC5D,aAAO,IAAI,eAAkB,IAAI;AAAA,IACnC;AAAA,EACF;AACF;","names":[]}
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  MemoryDeviceSeal,
3
3
  withTeam
4
- } from "../chunk-ZOFNZLAA.js";
4
+ } from "../chunk-VLZPUG5A.js";
5
5
  import {
6
6
  beginEchoUnlock
7
- } from "../chunk-35CNOVQE.js";
7
+ } from "../chunk-X67E7NIJ.js";
8
8
  import {
9
9
  NO_TEAM,
10
10
  burnPaperRecoveryEntry,
@@ -34,8 +34,8 @@ import {
34
34
  unwrapMagicLinkGrant,
35
35
  updateAuthenticator,
36
36
  writeMagicLinkGrant
37
- } from "../chunk-GLSCL74M.js";
38
- import "../chunk-B3B6HV5S.js";
37
+ } from "../chunk-5AVIUJP4.js";
38
+ import "../chunk-XMBBTETD.js";
39
39
  import {
40
40
  buildEchoBlock,
41
41
  buildRecipientKeyringFile,
@@ -56,20 +56,18 @@ import {
56
56
  updateKeyringIdentity,
57
57
  verifyPrompt,
58
58
  verifyTypedEcho
59
- } from "../chunk-QVUMKG3Z.js";
60
- import "../chunk-6BEBWHNL.js";
61
- import "../chunk-XQGKS4OW.js";
62
- import "../chunk-LJ744WXU.js";
63
- import "../chunk-WRLWEYHY.js";
64
- import "../chunk-O6VOR4NH.js";
65
- import "../chunk-VZFTON37.js";
66
- import "../chunk-NH2UOV3B.js";
67
- import "../chunk-HTRLQ4ZZ.js";
68
- import "../chunk-EPPAEGH5.js";
69
- import "../chunk-URGHKZPL.js";
59
+ } from "../chunk-UXH4AKH3.js";
60
+ import "../chunk-ZQQLOEWN.js";
61
+ import "../chunk-KHSBMLQE.js";
62
+ import "../chunk-VKZ3TDET.js";
63
+ import "../chunk-F2FD4LSB.js";
64
+ import "../chunk-EFINFZIF.js";
65
+ import "../chunk-I4S7IZSS.js";
66
+ import "../chunk-XWWDZKLS.js";
67
+ import "../chunk-CR5UPYIJ.js";
70
68
  import {
71
69
  TeamNotEnabledError
72
- } from "../chunk-2RH5SEY7.js";
70
+ } from "../chunk-ISIXU45J.js";
73
71
  export {
74
72
  MemoryDeviceSeal,
75
73
  NO_TEAM,
@@ -12,19 +12,16 @@ import {
12
12
  putAtTier,
13
13
  syncDerivedOutputs,
14
14
  withTiers
15
- } from "../chunk-BSEPI3HD.js";
16
- import "../chunk-XQGKS4OW.js";
17
- import "../chunk-LJ744WXU.js";
18
- import "../chunk-WRLWEYHY.js";
19
- import "../chunk-O6VOR4NH.js";
20
- import "../chunk-VZFTON37.js";
21
- import "../chunk-NH2UOV3B.js";
22
- import "../chunk-HTRLQ4ZZ.js";
23
- import "../chunk-EPPAEGH5.js";
24
- import "../chunk-URGHKZPL.js";
15
+ } from "../chunk-PR36DD2X.js";
16
+ import "../chunk-VKZ3TDET.js";
17
+ import "../chunk-F2FD4LSB.js";
18
+ import "../chunk-EFINFZIF.js";
19
+ import "../chunk-I4S7IZSS.js";
20
+ import "../chunk-XWWDZKLS.js";
21
+ import "../chunk-CR5UPYIJ.js";
25
22
  import {
26
23
  TiersNotEnabledError
27
- } from "../chunk-2RH5SEY7.js";
24
+ } from "../chunk-ISIXU45J.js";
28
25
  export {
29
26
  NO_TIERS,
30
27
  TiersNotEnabledError,
package/dist/to/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  NOYDB_ENVELOPE_GENERATION
3
- } from "../chunk-URGHKZPL.js";
3
+ } from "../chunk-CR5UPYIJ.js";
4
4
  import {
5
5
  ConflictError,
6
6
  DuplicateStoreKindError,
@@ -9,7 +9,7 @@ import {
9
9
  StoreCapabilityError,
10
10
  UnknownStoreKindError,
11
11
  isConflictError
12
- } from "../chunk-2RH5SEY7.js";
12
+ } from "../chunk-ISIXU45J.js";
13
13
 
14
14
  // src/port/to/locator.ts
15
15
  function isPodStore(store) {
@@ -3,15 +3,15 @@ import {
3
3
  TxContext,
4
4
  TxVault,
5
5
  runTransaction
6
- } from "../chunk-PFHDQY5L.js";
6
+ } from "../chunk-56Z4NOC6.js";
7
7
  import {
8
8
  lazy
9
9
  } from "../chunk-5D2ALSM5.js";
10
10
  import "../chunk-4AOERLTV.js";
11
- import "../chunk-2RH5SEY7.js";
11
+ import "../chunk-ISIXU45J.js";
12
12
 
13
13
  // src/with-commit/tx/dry-run.ts
14
- var loadGuardExecutor = lazy(() => import("../executor-7SY3M6TZ.js"));
14
+ var loadGuardExecutor = lazy(() => import("../executor-BJZJNVBB.js"));
15
15
  var SEP = " ";
16
16
  var keyOf = (op) => `${op.vaultName}${SEP}${op.collectionName}${SEP}${op.id}`;
17
17
  async function runDryRun(db, fn) {
@@ -3,7 +3,7 @@ import {
3
3
  } from "../chunk-PY4KJPYU.js";
4
4
  import {
5
5
  FilenameSanitizationError
6
- } from "../chunk-2RH5SEY7.js";
6
+ } from "../chunk-ISIXU45J.js";
7
7
 
8
8
  // src/kernel/util/sanitize-filename.ts
9
9
  var REPLACEMENT = "_";
@@ -0,0 +1,8 @@
1
+ import {
2
+ diffVault
3
+ } from "./chunk-7VJ2SIEI.js";
4
+ import "./chunk-SVLR4POP.js";
5
+ export {
6
+ diffVault
7
+ };
8
+ //# sourceMappingURL=vault-diff-H7LT5ZBJ.js.map
@@ -8,14 +8,11 @@ import {
8
8
  buildRecordEnvelope,
9
9
  encrypt,
10
10
  openEnvelopeJson
11
- } from "../chunk-WRLWEYHY.js";
12
- import "../chunk-O6VOR4NH.js";
13
- import "../chunk-VZFTON37.js";
14
- import "../chunk-NH2UOV3B.js";
15
- import "../chunk-HTRLQ4ZZ.js";
16
- import "../chunk-EPPAEGH5.js";
17
- import "../chunk-URGHKZPL.js";
18
- import "../chunk-2RH5SEY7.js";
11
+ } from "../chunk-EFINFZIF.js";
12
+ import "../chunk-I4S7IZSS.js";
13
+ import "../chunk-XWWDZKLS.js";
14
+ import "../chunk-CR5UPYIJ.js";
15
+ import "../chunk-ISIXU45J.js";
19
16
 
20
17
  // src/with-commit/vault-head/head.ts
21
18
  function bucketIndex(collection, id, buckets) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/with-commit/vault-head/head.ts","../../src/with-commit/vault-head/active.ts","../../src/with-commit/vault-head/verify.ts"],"sourcesContent":["/**\n * The vault head's storage layer (#1044).\n *\n * A bucket is an ordinary encrypted record at `_head/<collection>::<n>`, so it\n * inherits #1041's identity binding for free: the store cannot relocate a\n * bucket, re-author it, or serve one bucket's bytes as another's. What it can\n * still do is serve an OLD bucket, which is why {@link readBucket} enforces\n * monotonicity against the caller's own record of what it last wrote.\n *\n * @packageDocumentation\n */\nimport { encrypt, buildRecordAad, openEnvelopeJson, buildRecordEnvelope, type EnclaveKey } from '../../capsule/index.js'\nimport type { NoydbStore } from '../../kernel/types.js'\nimport { VAULT_HEAD_COLLECTION } from './strategy.js'\n\n/** `{ recordId → version }` for one bucket. */\nexport type BucketBody = Record<string, number>\n\n/**\n * FNV-1a over `collection/id`. A hash, not a cipher: the bucket a record lands\n * in is not secret — the store already sees which bucket was written, and it\n * already saw the record's own address. Choosing something stronger would buy\n * nothing and cost every write.\n */\nexport function bucketIndex(collection: string, id: string, buckets: number): number {\n let h = 0x811c9dc5\n const s = `${collection}/${id}`\n for (let i = 0; i < s.length; i++) {\n h ^= s.charCodeAt(i)\n h = Math.imul(h, 0x01000193) >>> 0\n }\n return h % buckets\n}\n\nexport function bucketId(collection: string, id: string, buckets: number): string {\n return `${collection}::${String(bucketIndex(collection, id, buckets))}`\n}\n\nexport async function readBucket(\n store: NoydbStore,\n vault: string,\n dek: EnclaveKey,\n bucket: string,\n): Promise<{ body: BucketBody; version: number }> {\n const env = await store.get(vault, VAULT_HEAD_COLLECTION, bucket)\n if (!env) return { body: {}, version: 0 }\n const json = await openEnvelopeJson({ collection: VAULT_HEAD_COLLECTION, id: bucket }, env, dek)\n return { body: JSON.parse(json) as BucketBody, version: env._v }\n}\n\nexport async function writeBucket(\n store: NoydbStore,\n vault: string,\n dek: EnclaveKey,\n bucket: string,\n body: BucketBody,\n expectedVersion: number,\n): Promise<void> {\n const identity = { collection: VAULT_HEAD_COLLECTION, id: bucket, version: expectedVersion + 1 }\n const json = JSON.stringify(body)\n const { iv, data } = await encrypt(json, dek, buildRecordAad(identity))\n const env = buildRecordEnvelope(identity, { iv, data })\n // CAS: two writers racing on one bucket must not silently lose an entry.\n // A lost head entry is a record the sweep stops expecting — a false clean.\n await store.put(vault, VAULT_HEAD_COLLECTION, bucket, env, expectedVersion || undefined)\n}\n","/**\n * The real {@link VaultHeadStrategy} (#1044).\n *\n * @packageDocumentation\n */\nimport type { NoydbStore } from '../../kernel/types.js'\nimport type { EnclaveKey } from '../../capsule/index.js'\nimport {\n DEFAULT_HEAD_BUCKETS,\n VAULT_HEAD_COLLECTION,\n type HeadEntry,\n type VaultHeadStrategy,\n type WithVaultHeadOptions,\n} from './strategy.js'\nimport { bucketId, readBucket, writeBucket } from './head.js'\n\nexport function withVaultHead(opts: WithVaultHeadOptions = {}): VaultHeadStrategy {\n const buckets = opts.buckets ?? DEFAULT_HEAD_BUCKETS\n\n const dekFor = (getDEK: (c: string) => Promise<EnclaveKey>) => getDEK(VAULT_HEAD_COLLECTION)\n\n return {\n enabled: true,\n bucketFor: (collection, id) => bucketId(collection, id, buckets),\n\n async note(store: NoydbStore, vault, getDEK, entry: HeadEntry) {\n const dek = await dekFor(getDEK)\n const bucket = bucketId(entry.collection, entry.id, buckets)\n const { body, version } = await readBucket(store, vault, dek, bucket)\n const key = `${entry.collection}/${entry.id}`\n // Monotonic: a head entry never moves BACKWARD. A write that would lower\n // it is either a stale retry or a rollback being laundered through the\n // client's own head, and neither should be recorded.\n if ((body[key] ?? -1) >= entry.version) return\n body[key] = entry.version\n await writeBucket(store, vault, dek, bucket, body, version)\n },\n\n async expected(store, vault, getDEK, collection, id) {\n const dek = await dekFor(getDEK)\n const { body } = await readBucket(store, vault, dek, bucketId(collection, id, buckets))\n return body[`${collection}/${id}`] ?? null\n },\n\n async knownIn(store, vault, getDEK, collection) {\n const dek = await dekFor(getDEK)\n const out = new Map<string, number>()\n const prefix = `${collection}/`\n // Sweep every bucket: a record's bucket is a function of its id, so the\n // set for one collection is spread across all of them.\n for (const bucket of await store.list(vault, VAULT_HEAD_COLLECTION)) {\n if (!bucket.startsWith(`${collection}::`)) continue\n const { body } = await readBucket(store, vault, dek, bucket)\n for (const [k, v] of Object.entries(body)) {\n if (k.startsWith(prefix)) out.set(k.slice(prefix.length), v)\n }\n }\n return out\n },\n }\n}\n","/**\n * The sweep — comparing what the head expects against what the store serves (#1044).\n *\n * This is the only place absence becomes visible. #1041 and #1042 can reject a\n * record that lies about itself; neither can notice one that never arrived, or\n * one served at an older version than the client wrote. Both are indistinguishable\n * from the truth without an independent record of what should be there.\n *\n * @packageDocumentation\n */\nimport type { NoydbStore } from '../../kernel/types.js'\nimport type { EnclaveKey } from '../../capsule/index.js'\nimport type { VaultHeadStrategy } from './strategy.js'\n\n/** One record the store is not serving faithfully. */\nexport interface HeadDiscrepancy {\n readonly collection: string\n readonly id: string\n /** What the client last committed. */\n readonly expected: number\n /**\n * What the store serves now — or `null` when it serves nothing.\n *\n * The two are different attacks wearing the same result. `null` is\n * **suppression**: the record is gone. A lower number is **rollback**: an\n * authentic older version served in place of the current one, which is the\n * case no amount of per-envelope authentication can see.\n */\n readonly actual: number | null\n readonly kind: 'withheld' | 'rolled-back'\n}\n\n/**\n * Why a sweep could not reach a conclusion.\n *\n * - `'no-expectations'` — the head holds nothing for this collection. A fresh\n * vault, a head switched on after the fact, or a **restore from a snapshot**:\n * `_head` is `_`-prefixed, so `loadAll` excludes it and a restored vault has\n * no head to compare against.\n * - `'store-cannot-cas'` — the store does not advertise `capabilities.casAtomic`,\n * so two writers racing on one bucket can silently lose an entry. A lost entry\n * is a record the sweep stops expecting, which is a false clean.\n */\nexport type HeadUnverifiableReason = 'no-expectations' | 'store-cannot-cas'\n\n/**\n * ## Three-way, deliberately (#1101)\n *\n * - `'verified'` — the head held expectations, every one was met, and the store\n * can serialize head writes.\n * - `'unverifiable'` — the sweep could not conclude. See `because`.\n * - `'tampered'` — at least one discrepancy. Positive evidence, so it wins over\n * any `unverifiable` reason present at the same time.\n *\n * **The middle value is the point, and collapsing it is wrong in a different\n * direction each way:** folded into \"clean\" it hides withholding, which is the\n * one thing this service exists to catch; folded into \"tampered\" it cries wolf\n * on a vault that is merely unexamined.\n *\n * That is not hypothetical. #1044's own first bug was a head that recorded\n * nothing and swept **perfectly clean** — the degraded state rendered\n * identically to a healthy one, which is why its test asserts `checked` before\n * anything else. A two-way verdict makes that state a supported outcome.\n */\nexport type HeadVerdict = 'verified' | 'unverifiable' | 'tampered'\n\nexport interface HeadVerifyResult {\n readonly verdict: HeadVerdict\n readonly checked: number\n readonly discrepancies: readonly HeadDiscrepancy[]\n /**\n * Non-empty only when `verdict === 'unverifiable'`.\n *\n * There is deliberately no `clean: boolean`. It could not distinguish \"no\n * expectations\" from \"all expectations met\" — both rendered `true` — and that\n * indistinguishability *was* the defect. Replacing it rather than keeping it\n * alongside forces every caller to face the three-way.\n */\n readonly because: readonly HeadUnverifiableReason[]\n}\n\n/**\n * Sweep one collection.\n *\n * **A record the store serves that the head does NOT know is not reported.**\n * That is not an oversight: the head can be enabled on an existing vault, and\n * every pre-existing record would otherwise read as an anomaly. The head's\n * claim is one-directional — *what I wrote must still be there* — and an\n * unknown record simply falls outside it.\n *\n * **A HIGHER version than expected is also not reported**, for the same reason:\n * another device legitimately advanced it. The head detects going backwards, not\n * moving forwards.\n */\nexport async function verifyVaultHead(\n head: VaultHeadStrategy,\n store: NoydbStore,\n vault: string,\n getDEK: (collection: string) => Promise<EnclaveKey>,\n collection: string,\n): Promise<HeadVerifyResult> {\n const known = await head.knownIn(store, vault, getDEK, collection)\n const discrepancies: HeadDiscrepancy[] = []\n\n const because: HeadUnverifiableReason[] = []\n if (known.size === 0) because.push('no-expectations')\n // Read the store's OWN declared capability rather than probing: a store that\n // cannot serialize head writes may have silently dropped an entry, and a\n // dropped entry is invisible by construction — there is nothing left to find.\n if (store.capabilities?.casAtomic !== true) because.push('store-cannot-cas')\n\n for (const [id, expected] of known) {\n const env = await store.get(vault, collection, id)\n if (env === null) {\n discrepancies.push({ collection, id, expected, actual: null, kind: 'withheld' })\n continue\n }\n if (env._v < expected) {\n discrepancies.push({ collection, id, expected, actual: env._v, kind: 'rolled-back' })\n }\n }\n\n // A discrepancy is positive evidence, so it outranks any reason the sweep was\n // also incomplete: a rolled-back record found by a head that may be missing\n // OTHER entries is still a rolled-back record.\n const verdict: HeadVerdict = discrepancies.length > 0\n ? 'tampered'\n : because.length > 0 ? 'unverifiable' : 'verified'\n\n return { verdict, checked: known.size, discrepancies, because }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/with-commit/vault-head/head.ts","../../src/with-commit/vault-head/active.ts","../../src/with-commit/vault-head/verify.ts"],"sourcesContent":["/**\n * The vault head's storage layer (#1044).\n *\n * A bucket is an ordinary encrypted record at `_head/<collection>::<n>`, so it\n * inherits #1041's identity binding for free: the store cannot relocate a\n * bucket, re-author it, or serve one bucket's bytes as another's. What it can\n * still do is serve an OLD bucket, which is why {@link readBucket} enforces\n * monotonicity against the caller's own record of what it last wrote.\n *\n * @packageDocumentation\n */\nimport { encrypt, buildRecordAad, openEnvelopeJson, buildRecordEnvelope, type EnclaveKey } from '../../capsule/index.js'\nimport type { NoydbStore } from '../../kernel/types.js'\nimport { VAULT_HEAD_COLLECTION } from './strategy.js'\n\n/** `{ recordId → version }` for one bucket. */\nexport type BucketBody = Record<string, number>\n\n/**\n * FNV-1a over `collection/id`. A hash, not a cipher: the bucket a record lands\n * in is not secret — the store already sees which bucket was written, and it\n * already saw the record's own address. Choosing something stronger would buy\n * nothing and cost every write.\n */\nexport function bucketIndex(collection: string, id: string, buckets: number): number {\n let h = 0x811c9dc5\n const s = `${collection}/${id}`\n for (let i = 0; i < s.length; i++) {\n h ^= s.charCodeAt(i)\n h = Math.imul(h, 0x01000193) >>> 0\n }\n return h % buckets\n}\n\nexport function bucketId(collection: string, id: string, buckets: number): string {\n return `${collection}::${String(bucketIndex(collection, id, buckets))}`\n}\n\nexport async function readBucket(\n store: NoydbStore,\n vault: string,\n dek: EnclaveKey,\n bucket: string,\n): Promise<{ body: BucketBody; version: number }> {\n const env = await store.get(vault, VAULT_HEAD_COLLECTION, bucket)\n if (!env) return { body: {}, version: 0 }\n const json = await openEnvelopeJson({ collection: VAULT_HEAD_COLLECTION, id: bucket }, env, dek)\n return { body: JSON.parse(json) as BucketBody, version: env._v }\n}\n\nexport async function writeBucket(\n store: NoydbStore,\n vault: string,\n dek: EnclaveKey,\n bucket: string,\n body: BucketBody,\n expectedVersion: number,\n): Promise<void> {\n const identity = { collection: VAULT_HEAD_COLLECTION, id: bucket, version: expectedVersion + 1 }\n const json = JSON.stringify(body)\n const { iv, data } = await encrypt(json, dek, buildRecordAad(identity))\n const env = buildRecordEnvelope(identity, { iv, data })\n // CAS: two writers racing on one bucket must not silently lose an entry.\n // A lost head entry is a record the sweep stops expecting — a false clean.\n await store.put(vault, VAULT_HEAD_COLLECTION, bucket, env, expectedVersion || undefined)\n}\n","/**\n * The real {@link VaultHeadStrategy} (#1044).\n *\n * @packageDocumentation\n */\nimport type { NoydbStore } from '../../kernel/types.js'\nimport type { EnclaveKey } from '../../capsule/index.js'\nimport {\n DEFAULT_HEAD_BUCKETS,\n VAULT_HEAD_COLLECTION,\n type HeadEntry,\n type VaultHeadStrategy,\n type WithVaultHeadOptions,\n} from './strategy.js'\nimport { bucketId, readBucket, writeBucket } from './head.js'\n\nexport function withVaultHead(opts: WithVaultHeadOptions = {}): VaultHeadStrategy {\n const buckets = opts.buckets ?? DEFAULT_HEAD_BUCKETS\n\n const dekFor = (getDEK: (c: string) => Promise<EnclaveKey>) => getDEK(VAULT_HEAD_COLLECTION)\n\n return {\n enabled: true,\n bucketFor: (collection, id) => bucketId(collection, id, buckets),\n\n async note(store: NoydbStore, vault, getDEK, entry: HeadEntry) {\n const dek = await dekFor(getDEK)\n const bucket = bucketId(entry.collection, entry.id, buckets)\n const { body, version } = await readBucket(store, vault, dek, bucket)\n const key = `${entry.collection}/${entry.id}`\n // Monotonic: a head entry never moves BACKWARD. A write that would lower\n // it is either a stale retry or a rollback being laundered through the\n // client's own head, and neither should be recorded.\n if ((body[key] ?? -1) >= entry.version) return\n body[key] = entry.version\n await writeBucket(store, vault, dek, bucket, body, version)\n },\n\n async expected(store, vault, getDEK, collection, id) {\n const dek = await dekFor(getDEK)\n const { body } = await readBucket(store, vault, dek, bucketId(collection, id, buckets))\n return body[`${collection}/${id}`] ?? null\n },\n\n async knownIn(store, vault, getDEK, collection) {\n const dek = await dekFor(getDEK)\n const out = new Map<string, number>()\n const prefix = `${collection}/`\n // Sweep every bucket: a record's bucket is a function of its id, so the\n // set for one collection is spread across all of them.\n for (const bucket of await store.list(vault, VAULT_HEAD_COLLECTION)) {\n if (!bucket.startsWith(`${collection}::`)) continue\n const { body } = await readBucket(store, vault, dek, bucket)\n for (const [k, v] of Object.entries(body)) {\n if (k.startsWith(prefix)) out.set(k.slice(prefix.length), v)\n }\n }\n return out\n },\n }\n}\n","/**\n * The sweep — comparing what the head expects against what the store serves (#1044).\n *\n * This is the only place absence becomes visible. #1041 and #1042 can reject a\n * record that lies about itself; neither can notice one that never arrived, or\n * one served at an older version than the client wrote. Both are indistinguishable\n * from the truth without an independent record of what should be there.\n *\n * @packageDocumentation\n */\nimport type { NoydbStore } from '../../kernel/types.js'\nimport type { EnclaveKey } from '../../capsule/index.js'\nimport type { VaultHeadStrategy } from './strategy.js'\n\n/** One record the store is not serving faithfully. */\nexport interface HeadDiscrepancy {\n readonly collection: string\n readonly id: string\n /** What the client last committed. */\n readonly expected: number\n /**\n * What the store serves now — or `null` when it serves nothing.\n *\n * The two are different attacks wearing the same result. `null` is\n * **suppression**: the record is gone. A lower number is **rollback**: an\n * authentic older version served in place of the current one, which is the\n * case no amount of per-envelope authentication can see.\n */\n readonly actual: number | null\n readonly kind: 'withheld' | 'rolled-back'\n}\n\n/**\n * Why a sweep could not reach a conclusion.\n *\n * - `'no-expectations'` — the head holds nothing for this collection. A fresh\n * vault, a head switched on after the fact, or a **restore from a snapshot**:\n * `_head` is `_`-prefixed, so `loadAll` excludes it and a restored vault has\n * no head to compare against.\n * - `'store-cannot-cas'` — the store does not advertise `capabilities.casAtomic`,\n * so two writers racing on one bucket can silently lose an entry. A lost entry\n * is a record the sweep stops expecting, which is a false clean.\n */\nexport type HeadUnverifiableReason = 'no-expectations' | 'store-cannot-cas'\n\n/**\n * ## Three-way, deliberately (#1101)\n *\n * - `'verified'` — the head held expectations, every one was met, and the store\n * can serialize head writes.\n * - `'unverifiable'` — the sweep could not conclude. See `because`.\n * - `'tampered'` — at least one discrepancy. Positive evidence, so it wins over\n * any `unverifiable` reason present at the same time.\n *\n * **The middle value is the point, and collapsing it is wrong in a different\n * direction each way:** folded into \"clean\" it hides withholding, which is the\n * one thing this service exists to catch; folded into \"tampered\" it cries wolf\n * on a vault that is merely unexamined.\n *\n * That is not hypothetical. #1044's own first bug was a head that recorded\n * nothing and swept **perfectly clean** — the degraded state rendered\n * identically to a healthy one, which is why its test asserts `checked` before\n * anything else. A two-way verdict makes that state a supported outcome.\n */\nexport type HeadVerdict = 'verified' | 'unverifiable' | 'tampered'\n\nexport interface HeadVerifyResult {\n readonly verdict: HeadVerdict\n readonly checked: number\n readonly discrepancies: readonly HeadDiscrepancy[]\n /**\n * Non-empty only when `verdict === 'unverifiable'`.\n *\n * There is deliberately no `clean: boolean`. It could not distinguish \"no\n * expectations\" from \"all expectations met\" — both rendered `true` — and that\n * indistinguishability *was* the defect. Replacing it rather than keeping it\n * alongside forces every caller to face the three-way.\n */\n readonly because: readonly HeadUnverifiableReason[]\n}\n\n/**\n * Sweep one collection.\n *\n * **A record the store serves that the head does NOT know is not reported.**\n * That is not an oversight: the head can be enabled on an existing vault, and\n * every pre-existing record would otherwise read as an anomaly. The head's\n * claim is one-directional — *what I wrote must still be there* — and an\n * unknown record simply falls outside it.\n *\n * **A HIGHER version than expected is also not reported**, for the same reason:\n * another device legitimately advanced it. The head detects going backwards, not\n * moving forwards.\n */\nexport async function verifyVaultHead(\n head: VaultHeadStrategy,\n store: NoydbStore,\n vault: string,\n getDEK: (collection: string) => Promise<EnclaveKey>,\n collection: string,\n): Promise<HeadVerifyResult> {\n const known = await head.knownIn(store, vault, getDEK, collection)\n const discrepancies: HeadDiscrepancy[] = []\n\n const because: HeadUnverifiableReason[] = []\n if (known.size === 0) because.push('no-expectations')\n // Read the store's OWN declared capability rather than probing: a store that\n // cannot serialize head writes may have silently dropped an entry, and a\n // dropped entry is invisible by construction — there is nothing left to find.\n if (store.capabilities?.casAtomic !== true) because.push('store-cannot-cas')\n\n for (const [id, expected] of known) {\n const env = await store.get(vault, collection, id)\n if (env === null) {\n discrepancies.push({ collection, id, expected, actual: null, kind: 'withheld' })\n continue\n }\n if (env._v < expected) {\n discrepancies.push({ collection, id, expected, actual: env._v, kind: 'rolled-back' })\n }\n }\n\n // A discrepancy is positive evidence, so it outranks any reason the sweep was\n // also incomplete: a rolled-back record found by a head that may be missing\n // OTHER entries is still a rolled-back record.\n const verdict: HeadVerdict = discrepancies.length > 0\n ? 'tampered'\n : because.length > 0 ? 'unverifiable' : 'verified'\n\n return { verdict, checked: known.size, discrepancies, because }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,17 @@
1
+ import {
2
+ dumpVaultSchema
3
+ } from "./chunk-HDAPQF6Q.js";
4
+ import "./chunk-RXLYKVTF.js";
5
+ import "./chunk-VYYM3MEN.js";
6
+ import "./chunk-FY4FFNKK.js";
7
+ import "./chunk-Y2NBBT6K.js";
8
+ import "./chunk-PBRD75JF.js";
9
+ import "./chunk-EFINFZIF.js";
10
+ import "./chunk-I4S7IZSS.js";
11
+ import "./chunk-XWWDZKLS.js";
12
+ import "./chunk-CR5UPYIJ.js";
13
+ import "./chunk-ISIXU45J.js";
14
+ export {
15
+ dumpVaultSchema
16
+ };
17
+ //# sourceMappingURL=walk-Z4N7PCZ2.js.map
@@ -41,6 +41,8 @@ export interface ExportAccessibleOptions {
41
41
  }
42
42
  /**
43
43
  * Produce a re-keyed, access-scoped `.noydb` bundle of the caller's accessible
44
- * data. Appends a tamper-evident audit entry (`reason: 'user-export:<userId>'`).
44
+ * data. Appends a tamper-evident audit entry (`reason: 'user-export:<userId>'`)
45
+ * BEFORE building, so a build that fails part-way still records the access it
46
+ * already made (family#175).
45
47
  */
46
48
  export declare function exportAccessibleData(vault: Vault, opts?: ExportAccessibleOptions): Promise<Uint8Array>;
@@ -88,7 +88,16 @@ export interface VaultDiff<T = unknown> {
88
88
  readonly modify: number;
89
89
  readonly delete: number;
90
90
  readonly total: number;
91
+ /** family#151 — `skipped.length`, so a caller reading only the summary sees it. */
92
+ readonly skipped: number;
91
93
  };
94
+ /**
95
+ * Records this diff could not key, and therefore says nothing about
96
+ * (family#151). Empty for a vault-to-vault diff. ⚠️ A non-empty value means
97
+ * the diff is INCOMPLETE — an importer walking only the buckets will not
98
+ * write these rows, which used to happen silently.
99
+ */
100
+ readonly skipped: readonly VaultDiffSkipped[];
92
101
  /**
93
102
  * Format the diff as a human-readable string.
94
103
  *
@@ -127,6 +136,25 @@ export interface DiffOptions {
127
136
  * - A `VaultDump` (output of `vault.dump()`) — a JSON string carrying the
128
137
  * full vault state. Parsed and reduced to the map shape above.
129
138
  */
139
+ /**
140
+ * A record neither side could key, and therefore one this diff does NOT report
141
+ * on (family#151).
142
+ *
143
+ * ⛔ IT EXISTS BECAUSE THE SKIP WAS SILENT. A record with no `idKey` field was
144
+ * dropped from the map on both sides, so it appeared in no bucket — and
145
+ * `@noy-db/hub/as`'s `plan().apply()` walks only `added`/`modified`/`deleted`.
146
+ * An import therefore did not write it, with no error and no count. A diff that
147
+ * omits a record is reporting a difference it did not find.
148
+ *
149
+ * ⚠️ Only reachable on the object/string candidate path. A vault-to-vault diff
150
+ * keys both sides by the hub id, which every record has.
151
+ */
152
+ export interface VaultDiffSkipped {
153
+ readonly collection: string;
154
+ readonly side: 'vault' | 'candidate';
155
+ /** Position within that side's record list for the collection. */
156
+ readonly index: number;
157
+ }
130
158
  export type DiffCandidate<T = unknown> = Vault | Record<string, readonly T[]> | string;
131
159
  /**
132
160
  * Compute the diff between a live vault and a candidate state.
@@ -23,6 +23,28 @@ import { type EnclaveKey } from '../../capsule/index.js';
23
23
  export { withSequence } from './active.js';
24
24
  export { NO_SEQUENCE, type SequenceStrategy } from './strategy.js';
25
25
  export { SequenceNotEnabledError } from '../../kernel/errors.js';
26
+ /**
27
+ * ⛔ **COUNTERS NEVER SYNC — A SEQUENCE IS UNIQUE PER DEVICE, NOT ACROSS A
28
+ * FLEET (family#206).** `_sequences` is absent from `RESERVED_REPLICATION`
29
+ * (`with-sync/reserved-mirror.ts:108`, whose replicated set is `_keyring`,
30
+ * `_broker_member`, `_broker`, `_meta`, `_users`, `_delegations`,
31
+ * `_rejections`), and `next()` CASes the counter record against the LOCAL
32
+ * store. So two devices issuing from the same sequence name produce the SAME
33
+ * numbers, and `next()`'s "no duplicates under concurrency" guarantee holds
34
+ * within one device only.
35
+ *
36
+ * ⚠️ The CAS is doing real work and it is not the gap here — it serializes
37
+ * concurrent writers against ONE store. What is missing is replication of the
38
+ * counter itself, which is why the failure is invisible to any single-device
39
+ * test and to every in-tree simulation that shares a store.
40
+ *
41
+ * ⛔ Do not use this for an invoice number that must be unique across devices
42
+ * until family#206 lands — it is the first item of the next cycle.
43
+ *
44
+ * ⭐ Measured: with sync on both devices, A `next()` → 1, A pushes, B pulls the
45
+ * whole vault, B `next()` → 1. Two records numbered 1 after a COMPLETE sync
46
+ * cycle — the pull cannot help, because there is nothing replicating to pull.
47
+ */
26
48
  export declare const SEQUENCE_COLLECTION = "_sequences";
27
49
  /** Options for `SequenceHandle.next`. Deferred-numbering series use `for`; the CAS counter ignores all of these. */
28
50
  export interface NextOptions {
@@ -4,9 +4,10 @@
4
4
  * A higher-tier user can issue a delegation that grants another user
5
5
  * temporary access to records at a specified tier. The delegation is
6
6
  * persisted as an encrypted envelope in the reserved `_delegations`
7
- * collection. The target user's runtime scans this collection on every
8
- * open and, while `until` is still in the future, merges the
9
- * unwrapped tier DEKs into their in-memory DEK map.
7
+ * collection. While `until` is still in the future, the target merges the
8
+ * unwrapped tier DEKs into their in-memory DEK map by calling
9
+ * `Vault.refreshDelegations()` — EXPLICIT, never automatic; the core#56
10
+ * section below says why a read path must not scan on open.
10
11
  *
11
12
  * ## Token shape
12
13
  *
@@ -39,14 +40,14 @@
39
40
  * The ciphertext is stored as a normal noy-db envelope — the
40
41
  * `_delegations` collection has its own DEK shared across all vault
41
42
  * users, so an operator can enumerate active delegations for audit
42
- * without being able to *use* them (the `wrappedDek` inside is still
43
- * keyed to the target user's KEK).
43
+ * without being able to *use* them (the `wrappedDek` inside is keyed to
44
+ * the token's own content key — see the core#65 section above).
44
45
  *
45
46
  * ## Revocation
46
47
  *
47
- * Delete the `_delegations/<id>` envelope. The target user's runtime
48
- * reloads the delegation list at each open and at periodic intervals
49
- * (tracked by the caller — this module is pure logic).
48
+ * Delete the `_delegations/<id>` envelope. The target picks the change up
49
+ * at its next `Vault.refreshDelegations()` call — this module is pure
50
+ * logic and schedules nothing.
50
51
  *
51
52
  * @module
52
53
  */
@@ -56,8 +57,9 @@ import { type EnclaveKey } from '../../capsule/index.js';
56
57
  export declare const DELEGATIONS_COLLECTION = "_delegations";
57
58
  /**
58
59
  * Durable payload of a delegation token. Encrypted under the vault's
59
- * `_delegations` DEK; the `wrappedDek` inside is additionally wrapped
60
- * under the target user's KEK.
60
+ * `_delegations` DEK; the `wrappedDek` inside is additionally wrapped under
61
+ * the token's per-token CONTENT KEY — see {@link DelegationToken.sealedCek},
62
+ * which carries the pre-core#65 exception.
61
63
  */
62
64
  export interface DelegationToken {
63
65
  readonly id: string;
@@ -75,8 +77,10 @@ export interface DelegationToken {
75
77
  readonly until: string;
76
78
  /**
77
79
  * The delegated tier DEK for {@link DelegationToken.collection}, wrapped
78
- * under the target's KEK. Present on a per-collection token; absent on a
79
- * collection-wide one, which carries {@link DelegationToken.wrappedDeks}.
80
+ * under the token's content key — see {@link DelegationToken.sealedCek},
81
+ * which carries the pre-core#65 exception. Present on a per-collection
82
+ * token; absent on a collection-wide one, which carries
83
+ * {@link DelegationToken.wrappedDeks}.
80
84
  */
81
85
  readonly wrappedDek?: string;
82
86
  /**
@@ -147,6 +147,56 @@ export declare function loadKeyring(store: NoydbStore, vault: string, opts: Load
147
147
  * otherwise. Placed before managed-secret secret resolution (which persists
148
148
  * on first open), so a fail-closed open writes nothing.
149
149
  */
150
+ /**
151
+ * ⚠️ family#162 — THIS GATE'S FAIL-CLOSED PROPERTY RESTS ON THE STORE
152
+ * CONTRACT. It decides "genuinely-new vault" from `list()` returning empty, so
153
+ * a store that answers a read FAILURE with `[]` turns the refusal below into a
154
+ * pass: hub then self-provisions a second owner into a vault that already has
155
+ * one. `NoydbStore`'s docstring states the rule (absence and failure are
156
+ * different answers); `to-file` violated it in `get`, `list` and `loadAll`.
157
+ *
158
+ * ⛔ Hub cannot verify it. A `[]` is a `[]` — there is no second question to
159
+ * ask that a store answering wrongly would answer differently. So the guard is
160
+ * the contract plus each store honouring it, and what hub owes is to NOT
161
+ * swallow a store that does throw. `__tests__/162-...` asserts that.
162
+ */
163
+ /**
164
+ * Refuse to attach a sync peer whose keyring for this user is a DIFFERENT file
165
+ * from the local one (family#178).
166
+ *
167
+ * ⛔ WHAT IT CATCHES, measured on two devices. A second device that attaches its
168
+ * peer with `attachSyncTarget` rather than the construction-time `sync` option
169
+ * finds no `_keyring` at open, self-provisions a brand-new owner keyring, and
170
+ * then diverges permanently: each device reads only its own records, under two
171
+ * different keyrings, with NO error anywhere. Device 1 cannot read device 2's
172
+ * data and device 2 cannot read device 1's.
173
+ *
174
+ * ⭐ THE TRIGGER IS A LOCAL WRITE BEFORE THE ATTACH. With no local write the
175
+ * reserved-keyring mirror adopts the peer's keyring on the first pull and
176
+ * everything works — so a two-device test WITHOUT the write passes and proves
177
+ * nothing. Once the device has written under its self-provisioned keyring the
178
+ * mirror will not supersede it, and the divergence sticks.
179
+ *
180
+ * ⛔ WHY THE CHECK IS HERE AND NOT AT FIRST KEYRING ACCESS. It cannot be there:
181
+ * `Noydb.vault()` throws unless the vault is already open, so `attachSyncTarget`
182
+ * necessarily runs AFTER `openVault` — and `openVault` is where the
183
+ * self-provision happens. At that moment no peer is attached and none can be
184
+ * consulted. "Bootstrap from any attached peer at first keyring access" is empty
185
+ * on a first open, and "refuse while an attached peer has not been checked"
186
+ * would refuse every first open.
187
+ *
188
+ * ⚠️ IT REFUSES RATHER THAN REPAIRS, deliberately. Adopting the peer's keyring
189
+ * would discard the local one, and every record this device already wrote is
190
+ * sealed under the discarded DEKs — so a "repair" trades a visible divergence
191
+ * for silent data loss. Refusing leaves both copies intact and tells the caller
192
+ * the two supported paths.
193
+ *
194
+ * ⚠️ The invariant it rests on was verified, not assumed: a legitimate pair ends
195
+ * with BYTE-IDENTICAL `_keyring/<user>` on both stores (measured for the
196
+ * construction-time form), because the keyring is per-user and mirrored. Two
197
+ * different files for one userId cannot both be right.
198
+ */
199
+ export declare function assertPeerKeyringMatches(local: NoydbStore, peer: NoydbStore, vault: string, userId: string): Promise<void>;
150
200
  export declare function assertKeyringOpenAllowed(store: NoydbStore, vault: string, userId: string, create: boolean): Promise<void>;
151
201
  /**
152
202
  * Options for {@link createOwnerKeyring} (#846b). The `SecretPolicy` knobs are
@@ -193,6 +243,33 @@ export interface CreateOwnerKeyringOptions extends SecretPolicy {
193
243
  * `NoydbOptions.validateSecret`. Direct callers (CLI, scripts,
194
244
  * test fixtures) opt in explicitly.
195
245
  */
246
+ /**
247
+ * Create the owner keyring, yielding to whoever won a concurrent create
248
+ * (family#164).
249
+ *
250
+ * ⛔ TWO CONCURRENT FIRST OPENS LEFT ONE CALLER WITH A RAW `ConflictError`.
251
+ * {@link writeKeyringFile} CASes a create at `expectedVersion: 0` (core#134),
252
+ * so the second create is correctly REFUSED — but nothing caught the refusal,
253
+ * and `Version conflict: expected 0, found 1` reached the caller out of
254
+ * `openVault`. A caller who does not retry reads that as a vault it cannot
255
+ * open; a caller who does retry succeeds, which is what made this a latent race
256
+ * rather than a visible one.
257
+ *
258
+ * ⭐ The loser is a READER, not a failure. A keyring now exists for this
259
+ * principal, written from the same secret, so loading it is both correct and
260
+ * what the caller asked for. Retried ONCE: a second conflict would mean a third
261
+ * writer, and looping against a shared store is how a race becomes a hang.
262
+ *
263
+ * ⚠️ RESIDUAL, measured rather than assumed. On a store whose
264
+ * `capabilities.casAtomic` is false the CAS is advisory, so two creates could in
265
+ * principle both land and the second clobber the first — which WOULD be
266
+ * permanent unopenability, because the first session's collection DEKs are
267
+ * wrapped under a KEK nobody holds. I could not reproduce it: the
268
+ * 600K-iteration KEK derivation dominates any store's read-then-write window by
269
+ * orders of magnitude, so the two writes serialise in practice. Recorded
270
+ * because "could not reproduce" is not "cannot happen".
271
+ */
272
+ export declare function createOwnerKeyringOrLoad(store: NoydbStore, vault: string, options: CreateOwnerKeyringOptions): Promise<UnlockedKeyring>;
196
273
  export declare function createOwnerKeyring(store: NoydbStore, vault: string, opts: CreateOwnerKeyringOptions): Promise<UnlockedKeyring>;
197
274
  /** Grant access to a new user. Caller must have grant privilege. */
198
275
  export declare function grant(store: NoydbStore, vault: string, callerKeyring: UnlockedKeyring, options: GrantOptions): Promise<void>;
@@ -78,14 +78,51 @@ export interface NoydbSealer {
78
78
  * parses this; it's purely audit metadata.
79
79
  */
80
80
  readonly id: string;
81
- /** Seal raw secret bytes. Output bytes are opaque to hub. */
82
- seal(secret: Uint8Array): Promise<Uint8Array>;
81
+ /**
82
+ * Seal raw secret bytes. Output bytes are opaque to hub.
83
+ *
84
+ * `ctx` is ADDITIVE and OPTIONAL (family#157): hub passes it where the bytes
85
+ * belong to one vault, so a provider can scope its key material — a KMS
86
+ * encryption context, a per-vault keychain account, a key-id suffix. An
87
+ * existing provider that ignores the second argument keeps working unchanged.
88
+ *
89
+ * ⛔ A provider MUST stay functional when `ctx` is ABSENT, and must not treat
90
+ * absence as an error. Hub omits it deliberately where sealed bytes have to
91
+ * TRAVEL — see {@link SealContext}.
92
+ */
93
+ seal(secret: Uint8Array, ctx?: SealContext): Promise<Uint8Array>;
83
94
  /**
84
95
  * Reverse {@link seal}. MUST throw on tamper, wrong-provider, or
85
96
  * any other failure — hub treats a thrown error as "this provider
86
97
  * cannot unlock this vault" and surfaces it to the caller.
98
+ *
99
+ * ⚠️ Hub passes the SAME `ctx` it sealed under at every paired call site, so a
100
+ * provider that binds key material to `ctx.vault` can unseal its own output.
101
+ * It is not passed where it was not available at seal time.
87
102
  */
88
- unseal(sealed: Uint8Array): Promise<Uint8Array>;
103
+ unseal(sealed: Uint8Array, ctx?: SealContext): Promise<Uint8Array>;
104
+ }
105
+ /**
106
+ * What hub knows about the bytes it is asking a {@link NoydbSealer} to seal
107
+ * (family#157). Deliberately one field — anything a provider needs beyond the
108
+ * vault name belongs in its own construction, not in a per-call argument.
109
+ *
110
+ * ⛔ **Hub does NOT pass this on every call, and the exception is load-bearing.**
111
+ * A pod's auto-unlock credentials (`with-pod/pod.ts`) are sealed WITHOUT a
112
+ * context, because a pod is a PORTABLE bundle: `ReadPodOptions` carries no
113
+ * vault, and the pod may be read into a differently-named vault or merely
114
+ * inspected with no vault at all. A provider that bound those bytes to a vault
115
+ * name would produce a credential only the originating vault could open, which
116
+ * defeats the entire point of the format.
117
+ *
118
+ * ⭐ So the rule for a provider author is the asymmetry itself: `ctx` present
119
+ * means "these bytes stay in this vault" and `ctx` absent means "these bytes
120
+ * are meant to travel". Scoping to `ctx.vault` when it IS given is safe for
121
+ * exactly that reason.
122
+ */
123
+ export interface SealContext {
124
+ /** The vault whose secret is being sealed or unsealed. */
125
+ readonly vault: string;
89
126
  }
90
127
  /**
91
128
  * In-memory test provider. NOT secure — uses a deterministic
@@ -397,7 +397,7 @@ export declare class TeamFacade {
397
397
  * recovery / TOTP / email-OTP factor proof at the moment of
398
398
  * recovery, so the issuer affirmatively re-asserts identity.
399
399
  *
400
- * The recipient should call `db.rotateSecret` on first session
400
+ * The recipient should call `db.team.rotateSecret` on first session
401
401
  * to choose their own phrase — the temp acts as a single-use
402
402
  * bridge.
403
403
  *
@@ -407,7 +407,7 @@ export declare class TeamFacade {
407
407
  * secret: 'temporary-correct-horse-battery-staple-printer',
408
408
  * }, { factors: [{ kind: 'recovery' }] })
409
409
  * // Bob opens createNoydb({ user: 'bob', secret: tempPhrase })
410
- * // and immediately calls db.rotateSecret to set his own.
410
+ * // and immediately calls db.team.rotateSecret to set his own.
411
411
  * ```
412
412
  *
413
413
  * @throws `NoAccessError` when no keyring exists for the target.
@@ -27,7 +27,7 @@
27
27
  * their own phrase.
28
28
  *
29
29
  * Caller must be at least as privileged as the target. The hub
30
- * `db.recoverUser` method gates this with the `peer-recover-user`
30
+ * `db.team.recoverUser` method gates this with the `peer-recover-user`
31
31
  * policy gate (the `peer-recover-user` factor-proof requirement); the function below
32
32
  * enforces only the role + anti-privilege-escalation invariants.
33
33
  *
@@ -42,7 +42,7 @@ export interface RecoverUserOptions {
42
42
  readonly userId: string;
43
43
  /**
44
44
  * Temporary secret under which the new keyring is wrapped.
45
- * The recipient should call `db.rotateSecret` immediately on
45
+ * The recipient should call `db.team.rotateSecret` immediately on
46
46
  * acceptance to choose their own phrase — this temp acts as a
47
47
  * single-use bridge in invite / peer-recovery flows.
48
48
  */