@noy-db/hub 0.8.0-pre.0 → 0.8.0

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 (624) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/dist/api-OS747DS4.js +18 -0
  3. package/dist/as/index.js +11 -12
  4. package/dist/as/index.js.map +1 -1
  5. package/dist/at/index.js +9 -10
  6. package/dist/attestation/index.js +39 -28
  7. package/dist/attestation/index.js.map +1 -1
  8. package/dist/{backup-7TFRVFLH.js → backup-YE2VQ26S.js} +15 -16
  9. package/dist/backup-YE2VQ26S.js.map +1 -0
  10. package/dist/blobs/index.js +13 -14
  11. package/dist/blobs/index.js.map +1 -1
  12. package/dist/broker/index.js +12 -13
  13. package/dist/broker/index.js.map +1 -1
  14. package/dist/by/index.js +2 -2
  15. package/dist/capsule/contract.d.ts +159 -0
  16. package/dist/capsule/contract.js +95 -0
  17. package/dist/capsule/enclave-aes/bound.d.ts +52 -0
  18. package/dist/capsule/enclave-aes/capabilities.d.ts +2 -0
  19. package/dist/capsule/enclave-aes/classify/compare.d.ts +20 -0
  20. package/dist/{kernel/enclave → capsule/enclave-aes}/classify/find.d.ts +1 -1
  21. package/dist/{kernel/enclave → capsule/enclave-aes}/classify/reveal.d.ts +1 -1
  22. package/dist/{kernel/enclave → capsule/enclave-aes}/classify/verify.d.ts +2 -2
  23. package/dist/{kernel/enclave → capsule/enclave-aes}/classify/write.d.ts +1 -1
  24. package/dist/{kernel/enclave → capsule/enclave-aes}/crypto.d.ts +33 -129
  25. package/dist/capsule/enclave-aes/index.d.ts +113 -0
  26. package/dist/capsule/enclave-aes/index.js +335 -0
  27. package/dist/capsule/enclave-aes/index.js.map +1 -0
  28. package/dist/capsule/enclave-aes/primitives.d.ts +29 -0
  29. package/dist/capsule/index.d.ts +27 -0
  30. package/dist/capsule/plumbing/ct-equal.d.ts +11 -0
  31. package/dist/{kernel/enclave/record-keys → capsule/plumbing}/deterministic.d.ts +8 -21
  32. package/dist/capsule/plumbing/digest.d.ts +122 -0
  33. package/dist/{kernel/enclave/record-keys → capsule/plumbing}/envelope-body.d.ts +44 -48
  34. package/dist/capsule/plumbing/index.d.ts +100 -0
  35. package/dist/capsule/plumbing/lifecycle.d.ts +50 -0
  36. package/dist/{kernel/enclave/record-keys → capsule/plumbing}/record-codec.d.ts +55 -20
  37. package/dist/{kernel/enclave → capsule/plumbing}/record-envelope.d.ts +1 -1
  38. package/dist/capsule/plumbing/rekey-blob.d.ts +33 -0
  39. package/dist/capsule/plumbing/rekey.d.ts +44 -0
  40. package/dist/capsule/plumbing/sealed-slot.d.ts +22 -0
  41. package/dist/capsule/plumbing/sealed-slots.d.ts +37 -0
  42. package/dist/capsule/plumbing/sealing.d.ts +29 -0
  43. package/dist/capsule/plumbing/sign.d.ts +9 -0
  44. package/dist/{kernel/enclave/record-keys → capsule/plumbing}/tombstone.d.ts +2 -2
  45. package/dist/capsule-VOLX3QRQ.js +209 -0
  46. package/dist/cargo/index.js +36 -36
  47. package/dist/{chunk-DF73H4UN.js → chunk-23D6M6VM.js} +5 -5
  48. package/dist/chunk-23D6M6VM.js.map +1 -0
  49. package/dist/{chunk-FH2L2E34.js → chunk-244QBK7Z.js} +4 -4
  50. package/dist/{chunk-FH2L2E34.js.map → chunk-244QBK7Z.js.map} +1 -1
  51. package/dist/{chunk-YSK2CU2Q.js → chunk-2AFX33YA.js} +2 -2
  52. package/dist/{chunk-TKUOEU2F.js → chunk-2GHDLTPE.js} +2 -2
  53. package/dist/{chunk-GYGLAVCX.js → chunk-2MG3SW7Q.js} +6 -2
  54. package/dist/chunk-2MG3SW7Q.js.map +1 -0
  55. package/dist/{chunk-6OWXYZK2.js → chunk-2ODVB6LZ.js} +2 -2
  56. package/dist/{chunk-X25NWUZB.js → chunk-2PVXF5CS.js} +3 -3
  57. package/dist/{chunk-IEX7NK2K.js → chunk-2RH777HH.js} +21 -20
  58. package/dist/{chunk-IEX7NK2K.js.map → chunk-2RH777HH.js.map} +1 -1
  59. package/dist/{chunk-244VXYPG.js → chunk-37EPTBBR.js} +14 -1
  60. package/dist/chunk-37EPTBBR.js.map +1 -0
  61. package/dist/{chunk-NRT6QZQB.js → chunk-3A5DUZ56.js} +6 -6
  62. package/dist/chunk-3A5DUZ56.js.map +1 -0
  63. package/dist/{chunk-ORDURZBU.js → chunk-3EWS67C7.js} +2 -2
  64. package/dist/{chunk-3H5KLDZN.js → chunk-3L2NBKDR.js} +4 -8
  65. package/dist/chunk-3L2NBKDR.js.map +1 -0
  66. package/dist/{chunk-ENAG3IY7.js → chunk-3XJQBBZD.js} +26 -28
  67. package/dist/chunk-3XJQBBZD.js.map +1 -0
  68. package/dist/{chunk-KJFW62P4.js → chunk-42ALPZ2B.js} +652 -662
  69. package/dist/chunk-42ALPZ2B.js.map +1 -0
  70. package/dist/{chunk-FXQBGFOX.js → chunk-4CIQDWRB.js} +8 -8
  71. package/dist/{chunk-HT2AHGQI.js → chunk-4JPMZTJY.js} +2 -2
  72. package/dist/{chunk-FQ5VRHIB.js → chunk-4T3SE27M.js} +5 -9
  73. package/dist/chunk-4T3SE27M.js.map +1 -0
  74. package/dist/{chunk-MKXXMNJH.js → chunk-4V3Q35WG.js} +2 -2
  75. package/dist/{chunk-A6IJU4TK.js → chunk-52MGURXO.js} +2 -2
  76. package/dist/{chunk-IUWCVHQ7.js → chunk-5A4345TG.js} +4 -4
  77. package/dist/{chunk-IUWCVHQ7.js.map → chunk-5A4345TG.js.map} +1 -1
  78. package/dist/{chunk-ISZQJBML.js → chunk-5FE75J4S.js} +6 -6
  79. package/dist/chunk-5FE75J4S.js.map +1 -0
  80. package/dist/chunk-5KC7QYEC.js +565 -0
  81. package/dist/chunk-5KC7QYEC.js.map +1 -0
  82. package/dist/{chunk-NNARWO72.js → chunk-5UMK7GRI.js} +13 -12
  83. package/dist/chunk-5UMK7GRI.js.map +1 -0
  84. package/dist/{chunk-HLEK5VAN.js → chunk-5WWDGFOS.js} +2 -2
  85. package/dist/{chunk-CKNGS5MH.js → chunk-6QVKPHBF.js} +3 -5
  86. package/dist/chunk-6QVKPHBF.js.map +1 -0
  87. package/dist/{chunk-PSIV7CJV.js → chunk-747G6CT3.js} +2 -2
  88. package/dist/chunk-747G6CT3.js.map +1 -0
  89. package/dist/{chunk-LGRLME4M.js → chunk-7R2Q7CPL.js} +16 -16
  90. package/dist/chunk-7R2Q7CPL.js.map +1 -0
  91. package/dist/{chunk-SOIQ4MM4.js → chunk-7XMHMVTS.js} +3 -3
  92. package/dist/{chunk-BUDAGWL5.js → chunk-A4XMIZT3.js} +6 -6
  93. package/dist/{chunk-BUDAGWL5.js.map → chunk-A4XMIZT3.js.map} +1 -1
  94. package/dist/{chunk-4MXI3ODD.js → chunk-AEQGFRU4.js} +3 -3
  95. package/dist/{chunk-7JE7BDYJ.js → chunk-AL6ML4LA.js} +5 -5
  96. package/dist/{chunk-ZUVBC32X.js → chunk-AUKKUPVB.js} +2 -2
  97. package/dist/chunk-BNWA3WG5.js +22 -0
  98. package/dist/chunk-BNWA3WG5.js.map +1 -0
  99. package/dist/{chunk-WY2XXTET.js → chunk-BPWYQ25R.js} +4 -4
  100. package/dist/{chunk-EOVMT6TB.js → chunk-BVCUTXE3.js} +2 -2
  101. package/dist/{chunk-UPD5NWI5.js → chunk-DHHGL42E.js} +13 -16
  102. package/dist/chunk-DHHGL42E.js.map +1 -0
  103. package/dist/{chunk-3JWHAR6E.js → chunk-DIZLQVAA.js} +2 -2
  104. package/dist/{chunk-QWFHIOD2.js → chunk-DLD5LGDS.js} +11 -12
  105. package/dist/chunk-DLD5LGDS.js.map +1 -0
  106. package/dist/{chunk-ZE4CHIED.js → chunk-DQESF6RP.js} +17 -28
  107. package/dist/chunk-DQESF6RP.js.map +1 -0
  108. package/dist/{chunk-IT22PWKV.js → chunk-E2N2T5ZO.js} +2 -2
  109. package/dist/{chunk-3ELRMVJK.js → chunk-EGVJ7TM4.js} +31 -34
  110. package/dist/chunk-EGVJ7TM4.js.map +1 -0
  111. package/dist/{chunk-WNJ4AVGE.js → chunk-EJLV62NI.js} +2 -2
  112. package/dist/{chunk-QBBUZ3I3.js → chunk-EYG2CY2X.js} +11 -11
  113. package/dist/{enclave-27SMF6GF.js → chunk-EZGV6F47.js} +83 -56
  114. package/dist/chunk-EZGV6F47.js.map +1 -0
  115. package/dist/{chunk-LQ4ZHOKP.js → chunk-EZOAKKTB.js} +36 -27
  116. package/dist/chunk-EZOAKKTB.js.map +1 -0
  117. package/dist/{chunk-BJ2IXQ5Q.js → chunk-FFJFE4T7.js} +2 -2
  118. package/dist/{chunk-JCN44NCY.js → chunk-FLPCETP6.js} +2 -2
  119. package/dist/{chunk-5O7D6ZTW.js → chunk-FOEDQATO.js} +2 -2
  120. package/dist/{chunk-VNNRUGMM.js → chunk-FVH5QYY2.js} +2 -2
  121. package/dist/{chunk-ANWPSTZU.js → chunk-G2MVBDFP.js} +23 -26
  122. package/dist/chunk-G2MVBDFP.js.map +1 -0
  123. package/dist/chunk-GMKGGY7V.js +234 -0
  124. package/dist/chunk-GMKGGY7V.js.map +1 -0
  125. package/dist/{chunk-EIPVYUEP.js → chunk-GQ4MF3CM.js} +3 -3
  126. package/dist/chunk-GQ4MF3CM.js.map +1 -0
  127. package/dist/{chunk-PEOZ34EM.js → chunk-GSAK56VF.js} +1 -1
  128. package/dist/chunk-GSAK56VF.js.map +1 -0
  129. package/dist/{chunk-QOOUUR4A.js → chunk-GUZET4SG.js} +10 -4
  130. package/dist/chunk-GUZET4SG.js.map +1 -0
  131. package/dist/{chunk-4AF3TUMP.js → chunk-GZT3NQRA.js} +2 -2
  132. package/dist/{chunk-N5DNADLQ.js → chunk-H23XHRTT.js} +19 -34
  133. package/dist/chunk-H23XHRTT.js.map +1 -0
  134. package/dist/{chunk-MVZ2TPVP.js → chunk-H427H63K.js} +2 -2
  135. package/dist/{chunk-6B3VNR4P.js → chunk-H7JBY4P7.js} +23 -32
  136. package/dist/chunk-H7JBY4P7.js.map +1 -0
  137. package/dist/{chunk-MLPHLJIQ.js → chunk-HS554XAF.js} +2 -2
  138. package/dist/{chunk-HK67PX4J.js → chunk-HW7CMKUG.js} +1 -1
  139. package/dist/chunk-HW7CMKUG.js.map +1 -0
  140. package/dist/{chunk-S57HTZ6X.js → chunk-IMQKWR46.js} +5 -7
  141. package/dist/chunk-IMQKWR46.js.map +1 -0
  142. package/dist/{chunk-FCKWQE2H.js → chunk-IUBMZPHM.js} +7 -7
  143. package/dist/chunk-IUBMZPHM.js.map +1 -0
  144. package/dist/{chunk-UD5EVGZ7.js → chunk-IUT3GWP3.js} +49 -13
  145. package/dist/chunk-IUT3GWP3.js.map +1 -0
  146. package/dist/{chunk-J6UOHJY5.js → chunk-JDEYF3PJ.js} +4 -8
  147. package/dist/{chunk-J6UOHJY5.js.map → chunk-JDEYF3PJ.js.map} +1 -1
  148. package/dist/{chunk-NWHBJQAL.js → chunk-JIBUPZHA.js} +4 -4
  149. package/dist/chunk-JIBUPZHA.js.map +1 -0
  150. package/dist/{chunk-TROR3ALR.js → chunk-JOSPH3E5.js} +2 -2
  151. package/dist/{chunk-F24ZZTHQ.js → chunk-JQYKPKG6.js} +4 -4
  152. package/dist/{chunk-GF5BZ7D4.js → chunk-JSMTXZR3.js} +8 -12
  153. package/dist/chunk-JSMTXZR3.js.map +1 -0
  154. package/dist/chunk-JWWYRR4Q.js +12 -0
  155. package/dist/chunk-JWWYRR4Q.js.map +1 -0
  156. package/dist/{chunk-HBPPGWUM.js → chunk-KZXDLBY6.js} +14 -9
  157. package/dist/chunk-KZXDLBY6.js.map +1 -0
  158. package/dist/{chunk-7VCXZDA4.js → chunk-LIOVX5TJ.js} +7 -11
  159. package/dist/chunk-LIOVX5TJ.js.map +1 -0
  160. package/dist/{chunk-QWGU66MP.js → chunk-LNSVGRHO.js} +5 -7
  161. package/dist/chunk-LNSVGRHO.js.map +1 -0
  162. package/dist/{chunk-MDWKM2XC.js → chunk-M5B2W6YY.js} +3 -3
  163. package/dist/{chunk-F2TDU7MQ.js → chunk-MBMTND6D.js} +2 -2
  164. package/dist/{chunk-K6W7BVZ6.js → chunk-MILI22XQ.js} +3 -3
  165. package/dist/{chunk-YNIUIERI.js → chunk-MXKI4ABF.js} +18 -59
  166. package/dist/chunk-MXKI4ABF.js.map +1 -0
  167. package/dist/{chunk-T2LBQ5DV.js → chunk-MXOQ5JCG.js} +252 -214
  168. package/dist/chunk-MXOQ5JCG.js.map +1 -0
  169. package/dist/{chunk-ZXABPVM6.js → chunk-N7EVQD5S.js} +9 -13
  170. package/dist/chunk-N7EVQD5S.js.map +1 -0
  171. package/dist/{chunk-CF5UU4S7.js → chunk-N7UDP5VU.js} +7 -7
  172. package/dist/{chunk-FQ54DWUQ.js → chunk-NBQ3KK6X.js} +4 -4
  173. package/dist/{chunk-4I522ERM.js → chunk-NCO25JZO.js} +4 -4
  174. package/dist/chunk-NH2UOV3B.js +18 -0
  175. package/dist/chunk-NH2UOV3B.js.map +1 -0
  176. package/dist/{chunk-SI3V7D4G.js → chunk-O2IMQSNA.js} +2 -2
  177. package/dist/{chunk-T52GX4SA.js → chunk-O46CHQT7.js} +4 -4
  178. package/dist/chunk-OIEO4WDL.js +27 -0
  179. package/dist/chunk-OIEO4WDL.js.map +1 -0
  180. package/dist/{chunk-GHLTDZRS.js → chunk-OKSTSITU.js} +25 -4
  181. package/dist/chunk-OKSTSITU.js.map +1 -0
  182. package/dist/{chunk-TOPYQ6GA.js → chunk-OYW3I5M4.js} +6 -6
  183. package/dist/{chunk-X4773RBR.js → chunk-PD64727P.js} +2 -2
  184. package/dist/chunk-PD64727P.js.map +1 -0
  185. package/dist/{chunk-BP6DARYA.js → chunk-PP3K67AJ.js} +4 -4
  186. package/dist/chunk-PP3K67AJ.js.map +1 -0
  187. package/dist/chunk-Q2XRFWOI.js +40 -0
  188. package/dist/chunk-Q2XRFWOI.js.map +1 -0
  189. package/dist/{chunk-AOWGXU6D.js → chunk-Q4UHJ5SN.js} +2 -2
  190. package/dist/{chunk-FW22ZCXT.js → chunk-QBLT6POL.js} +2 -2
  191. package/dist/chunk-QMWY2FDS.js +157 -0
  192. package/dist/chunk-QMWY2FDS.js.map +1 -0
  193. package/dist/{chunk-I3JDRCMW.js → chunk-RB4DOPGZ.js} +10 -10
  194. package/dist/{chunk-32YV3TJT.js → chunk-SMV2HRDU.js} +2 -2
  195. package/dist/{chunk-ODVPTDPK.js → chunk-SV2PM2OY.js} +1 -1
  196. package/dist/chunk-SV2PM2OY.js.map +1 -0
  197. package/dist/{chunk-Z5HTYMMQ.js → chunk-SYNY3VB5.js} +2 -2
  198. package/dist/{chunk-SYVZW77S.js → chunk-TEHHROZL.js} +6 -8
  199. package/dist/chunk-TEHHROZL.js.map +1 -0
  200. package/dist/{chunk-ZSX4S5XB.js → chunk-TKVUE4JF.js} +9 -9
  201. package/dist/{chunk-B57AFBY2.js → chunk-TZZBXPZK.js} +2 -2
  202. package/dist/{chunk-VNPEWFPD.js → chunk-U2FZNEWJ.js} +4 -4
  203. package/dist/chunk-U2FZNEWJ.js.map +1 -0
  204. package/dist/{chunk-5FDLC6G7.js → chunk-UA372JHH.js} +3 -3
  205. package/dist/{chunk-PDCG6PR5.js → chunk-UEFOQH74.js} +2 -2
  206. package/dist/chunk-UEFOQH74.js.map +1 -0
  207. package/dist/{chunk-HVSCEIYL.js → chunk-UIYESRD6.js} +9 -11
  208. package/dist/chunk-UIYESRD6.js.map +1 -0
  209. package/dist/{chunk-B6SJIBQK.js → chunk-V3RWOOSO.js} +4 -4
  210. package/dist/{chunk-HBRLNOHL.js → chunk-V7ADQF5O.js} +4 -4
  211. package/dist/{chunk-L7DOS3TE.js → chunk-VAORSCSU.js} +3 -3
  212. package/dist/chunk-VAORSCSU.js.map +1 -0
  213. package/dist/{chunk-M522UYZ2.js → chunk-VFHCKG5M.js} +6 -10
  214. package/dist/chunk-VFHCKG5M.js.map +1 -0
  215. package/dist/{chunk-DC5QVPV7.js → chunk-VHBKYN2J.js} +3 -3
  216. package/dist/chunk-VHBKYN2J.js.map +1 -0
  217. package/dist/{chunk-WX5ADGTZ.js → chunk-VKI2EB3N.js} +3 -3
  218. package/dist/chunk-VKI2EB3N.js.map +1 -0
  219. package/dist/{chunk-MTL7MXGR.js → chunk-VMV5SBE4.js} +16 -17
  220. package/dist/chunk-VMV5SBE4.js.map +1 -0
  221. package/dist/{chunk-F7XGHL5O.js → chunk-VQDZYB2B.js} +3 -3
  222. package/dist/{chunk-BK2HHQGN.js → chunk-VVOLDVIR.js} +2 -2
  223. package/dist/{chunk-6LMQ5R26.js → chunk-WPOYWFSE.js} +7 -7
  224. package/dist/{chunk-6LMQ5R26.js.map → chunk-WPOYWFSE.js.map} +1 -1
  225. package/dist/{chunk-3F7GLNAE.js → chunk-WXE4W2U6.js} +7 -11
  226. package/dist/chunk-WXE4W2U6.js.map +1 -0
  227. package/dist/{chunk-6K7DPM7D.js → chunk-XQRFSKYM.js} +2 -2
  228. package/dist/{chunk-M7NI3IWE.js → chunk-XSPFDUDG.js} +22 -50
  229. package/dist/chunk-XSPFDUDG.js.map +1 -0
  230. package/dist/{chunk-ID6Z6E66.js → chunk-Y2RKVFKR.js} +2 -2
  231. package/dist/{chunk-6LNL42F5.js → chunk-Y3LPTBG7.js} +12 -12
  232. package/dist/chunk-Y3LPTBG7.js.map +1 -0
  233. package/dist/{chunk-FN5EBVTQ.js → chunk-YRXFFWG4.js} +2 -2
  234. package/dist/classified/index.js +5 -5
  235. package/dist/{classified-marker-W3USLL5M.js → classified-marker-SIYKUU5L.js} +3 -3
  236. package/dist/classified-marker-SIYKUU5L.js.map +1 -0
  237. package/dist/collection-facade-CS7CA2XO.js +47 -0
  238. package/dist/{computed-TPFBX7U4.js → computed-FAD7SED4.js} +3 -3
  239. package/dist/consent/index.js +10 -11
  240. package/dist/consent/index.js.map +1 -1
  241. package/dist/cover/index.js +9 -10
  242. package/dist/custody/index.js +12 -13
  243. package/dist/{dead-filter-U2UYKSZL.js → dead-filter-4F3LWYKH.js} +11 -3
  244. package/dist/dead-filter-4F3LWYKH.js.map +1 -0
  245. package/dist/debug/index.js +11 -2
  246. package/dist/debug/index.js.map +1 -1
  247. package/dist/{delegation-S3AEPW2T.js → delegation-NANZDG4N.js} +13 -16
  248. package/dist/delegation-NANZDG4N.js.map +1 -0
  249. package/dist/derivations/index.js +23 -24
  250. package/dist/derive-XLOJVXPU.js +20 -0
  251. package/dist/directory/index.js +10 -11
  252. package/dist/{dispatch-3CQDJV5Q.js → dispatch-H4HV32AM.js} +5 -5
  253. package/dist/{dispatch-RH4LHKBH.js → dispatch-JDZNGEB3.js} +21 -22
  254. package/dist/dispatch-JDZNGEB3.js.map +1 -0
  255. package/dist/executor-FMPVN6DT.js +35 -0
  256. package/dist/executor-LBBBRTN5.js +8 -0
  257. package/dist/executor-OSRZST2U.js +8 -0
  258. package/dist/export-accessible-RAOJAAU5.js +22 -0
  259. package/dist/extract-partition-JD5CUSTG.js +37 -0
  260. package/dist/{fanout-sidecar-OT6RYLOL.js → fanout-sidecar-L7NHPIOC.js} +13 -15
  261. package/dist/fanout-sidecar-L7NHPIOC.js.map +1 -0
  262. package/dist/find-JRN4RNQ5.js +10 -0
  263. package/dist/forget/index.js +9 -10
  264. package/dist/forget/index.js.map +1 -1
  265. package/dist/guards/index.js +4 -4
  266. package/dist/history/index.js +13 -14
  267. package/dist/history/index.js.map +1 -1
  268. package/dist/i18n/index.js +14 -15
  269. package/dist/i18n/index.js.map +1 -1
  270. package/dist/index.d.ts +8 -8
  271. package/dist/index.js +183 -184
  272. package/dist/index.js.map +1 -1
  273. package/dist/indexing/index.js +5 -5
  274. package/dist/introspection/index.js +11 -12
  275. package/dist/issue-YIVBZUTH.js +19 -0
  276. package/dist/kernel/attestation-types.d.ts +62 -0
  277. package/dist/kernel/collection-config.d.ts +1 -48
  278. package/dist/kernel/collection.d.ts +1 -1
  279. package/dist/kernel/cutover-transform.d.ts +1 -1
  280. package/dist/kernel/errors.d.ts +30 -2
  281. package/dist/kernel/merge-authority.d.ts +1 -1
  282. package/dist/kernel/paths.d.ts +29 -5
  283. package/dist/kernel/prepared-write.d.ts +1 -1
  284. package/dist/kernel/secret-mode.d.ts +1 -1
  285. package/dist/kernel/types.d.ts +42 -5
  286. package/dist/kernel/vault.d.ts +2 -2
  287. package/dist/kernel/write-queue.d.ts +17 -0
  288. package/dist/{ledger-KZPCMVZY.js → ledger-5ZMGE44K.js} +11 -12
  289. package/dist/liberate-WZSZM2W6.js +24 -0
  290. package/dist/link-set-MFXC24VK.js +29 -0
  291. package/dist/{managed-secret-S3MQ6SH6.js → managed-secret-MFTFT22X.js} +10 -11
  292. package/dist/materialized-views/index.js +26 -27
  293. package/dist/{migrate-cek-V7GKJZ7O.js → migrate-cek-DZRFFOHW.js} +2 -2
  294. package/dist/money/index.js +5 -5
  295. package/dist/noydb-ITIGNKUF.js +96 -0
  296. package/dist/overlay-views/index.js +4 -4
  297. package/dist/periods/index.js +12 -13
  298. package/dist/pod/index.js +72 -72
  299. package/dist/{pod-handle-WGDFB4C2.js → pod-handle-A3LET7NO.js} +10 -11
  300. package/dist/pod-handle-A3LET7NO.js.map +1 -0
  301. package/dist/policy/index.js +10 -11
  302. package/dist/port/on/index.d.ts +1 -1
  303. package/dist/port/to/index.d.ts +1 -1
  304. package/dist/port/with/blob-strategy.d.ts +1 -1
  305. package/dist/port/with/classified-strategy.d.ts +1 -1
  306. package/dist/port/with/collection-options.d.ts +1 -1
  307. package/dist/port/with/collection-registries.d.ts +1 -1
  308. package/dist/port/with/lookup-strategy.d.ts +2 -2
  309. package/dist/portability/index.js +8 -8
  310. package/dist/{post-register-SLSXIPBV.js → post-register-7ND27CF2.js} +6 -6
  311. package/dist/post-register-7ND27CF2.js.map +1 -0
  312. package/dist/query/all/index.js +15 -15
  313. package/dist/query/index.js +7 -7
  314. package/dist/query/live/index.js +7 -7
  315. package/dist/query/reduce/index.js +10 -10
  316. package/dist/query/relate/index.js +9 -9
  317. package/dist/reduce/index.js +8 -8
  318. package/dist/register-DT5HZ2LZ.js +30 -0
  319. package/dist/registry-BHRZGZHF.js +8 -0
  320. package/dist/registry-ET6ZFFWA.js +34 -0
  321. package/dist/registry-HXFGLGTG.js +8 -0
  322. package/dist/registry-THCPDEOD.js +23 -0
  323. package/dist/request-withdrawal-AV2MJJKY.js +30 -0
  324. package/dist/{reveal-4BCKPEC2.js → reveal-B2TLP4JQ.js} +10 -9
  325. package/dist/reveal-B2TLP4JQ.js.map +1 -0
  326. package/dist/revoke-6DWIEOCV.js +24 -0
  327. package/dist/satellites/index.js +1 -1
  328. package/dist/schema-update/index.js +2 -2
  329. package/dist/sealed-record/index.js +16 -18
  330. package/dist/sealed-record/index.js.map +1 -1
  331. package/dist/search/index.js +4 -4
  332. package/dist/{seed-4JS2RJ4A.js → seed-XNSE4U3S.js} +15 -18
  333. package/dist/seed-XNSE4U3S.js.map +1 -0
  334. package/dist/sequence/index.js +9 -10
  335. package/dist/session/index.js +9 -10
  336. package/dist/session/index.js.map +1 -1
  337. package/dist/shadow/index.js +2 -2
  338. package/dist/signer-MHGW3OIL.js +23 -0
  339. package/dist/snapshots/index.js +11 -11
  340. package/dist/stale-6GCFMOOR.js +28 -0
  341. package/dist/storage-BYN5LO6Z.js +21 -0
  342. package/dist/store/index.js +1 -1
  343. package/dist/{store-coordination-provider-2O2VUHKW.js → store-coordination-provider-C4BPT5XF.js} +11 -12
  344. package/dist/store-coordination-provider-C4BPT5XF.js.map +1 -0
  345. package/dist/sync/index.js +10 -11
  346. package/dist/sync/index.js.map +1 -1
  347. package/dist/team/index.js +15 -16
  348. package/dist/tiers/index.js +11 -12
  349. package/dist/to/index.js +2 -2
  350. package/dist/transactions/index.js +3 -3
  351. package/dist/util/index.js +1 -1
  352. package/dist/vault-head/index.js +11 -14
  353. package/dist/vault-head/index.js.map +1 -1
  354. package/dist/{verify-RVT67IMH.js → verify-UKALW7C2.js} +14 -12
  355. package/dist/verify-UKALW7C2.js.map +1 -0
  356. package/dist/via/classified/binding.d.ts +2 -2
  357. package/dist/via/classified/config-drift.d.ts +2 -2
  358. package/dist/via/classified/errors.d.ts +1 -1
  359. package/dist/via/lookup/handle.d.ts +4 -4
  360. package/dist/walk-4VPK7AS4.js +20 -0
  361. package/dist/with-audit/attestation/index.d.ts +2 -1
  362. package/dist/with-audit/attestation/issue.d.ts +2 -2
  363. package/dist/with-audit/attestation/revoke.d.ts +2 -2
  364. package/dist/with-audit/attestation/scheme.d.ts +7 -0
  365. package/dist/with-audit/attestation/signer.d.ts +1 -1
  366. package/dist/with-audit/attestation/strategy.d.ts +2 -2
  367. package/dist/with-audit/attestation/types.d.ts +10 -0
  368. package/dist/with-audit/attestation/vault-facade.d.ts +2 -2
  369. package/dist/with-audit/attestation/verifier.d.ts +6 -0
  370. package/dist/with-audit/consent/consent.d.ts +1 -1
  371. package/dist/with-audit/consent/strategy.d.ts +1 -1
  372. package/dist/with-audit/forget/subject-index.d.ts +1 -1
  373. package/dist/with-audit/periods/vault-facade.d.ts +1 -1
  374. package/dist/with-audit/sealed-record/index.d.ts +2 -2
  375. package/dist/with-audit/sealed-record/strategy.d.ts +1 -1
  376. package/dist/with-audit/tiers/index.d.ts +2 -2
  377. package/dist/with-cargo/adopt-partition.d.ts +1 -1
  378. package/dist/with-cargo/extract-partition.d.ts +1 -1
  379. package/dist/with-cargo/floor.d.ts +1 -1
  380. package/dist/with-commit/history/history.d.ts +2 -2
  381. package/dist/with-commit/history/index.d.ts +1 -1
  382. package/dist/with-commit/history/ledger/store.d.ts +1 -1
  383. package/dist/with-commit/history/strategy.d.ts +1 -1
  384. package/dist/with-commit/history/time-machine.d.ts +1 -1
  385. package/dist/with-commit/numbering/index.d.ts +1 -1
  386. package/dist/with-commit/sequence/index.d.ts +1 -1
  387. package/dist/with-commit/vault-head/head.d.ts +1 -1
  388. package/dist/with-commit/vault-head/index.d.ts +1 -1
  389. package/dist/with-commit/vault-head/strategy.d.ts +1 -1
  390. package/dist/with-commit/vault-head/verify.d.ts +1 -1
  391. package/dist/with-formula/derivations/dispatch.d.ts +1 -1
  392. package/dist/with-formula/derivations/fanout-sidecar.d.ts +1 -1
  393. package/dist/with-lookup/indexing/collection-facade.d.ts +1 -1
  394. package/dist/with-lookup/search/collection-facade.d.ts +1 -1
  395. package/dist/with-party/broker/index.d.ts +3 -3
  396. package/dist/with-party/directory/user-envelope/storage.d.ts +1 -1
  397. package/dist/with-party/team/delegation.d.ts +1 -1
  398. package/dist/with-party/team/echo-secret.d.ts +2 -2
  399. package/dist/with-party/team/index.d.ts +1 -1
  400. package/dist/with-party/team/keyring.d.ts +1 -1
  401. package/dist/with-party/team/magic-link-grant.d.ts +1 -1
  402. package/dist/with-party/team/recovery.d.ts +1 -1
  403. package/dist/with-party/team/roster-tag.d.ts +1 -1
  404. package/dist/with-party/team/rotate-recover.d.ts +1 -1
  405. package/dist/with-party/team/wrapped-deks.d.ts +1 -1
  406. package/dist/with-pod/index.d.ts +1 -1
  407. package/dist/with-shape/blobs/blob-compaction.d.ts +1 -1
  408. package/dist/with-shape/blobs/blob-intent.d.ts +1 -1
  409. package/dist/with-shape/blobs/blob-set.d.ts +2 -2
  410. package/dist/with-shape/blobs/legacy-sweep.d.ts +1 -1
  411. package/dist/with-shape/introspection/describe.d.ts +1 -1
  412. package/dist/with-shape/introspection/walk.d.ts +1 -1
  413. package/dist/with-shape/links/lazy-handle.d.ts +1 -1
  414. package/dist/with-shape/links/link-set.d.ts +1 -1
  415. package/dist/with-shape/manifest/derive.d.ts +1 -1
  416. package/dist/with-shape/manifest/storage.d.ts +1 -1
  417. package/dist/with-shape/persisted-schemas/register.d.ts +1 -1
  418. package/dist/with-shape/persisted-schemas/storage.d.ts +1 -1
  419. package/dist/with-shape/satellites/dead-filter.d.ts +1 -1
  420. package/dist/with-shape/satellites/declare.d.ts +1 -1
  421. package/dist/with-shape/satellites/marker.d.ts +1 -1
  422. package/dist/with-shape/satellites/post-register.d.ts +1 -1
  423. package/dist/with-sync/presence.d.ts +5 -10
  424. package/dist/withdraw-accessible-HL7GACUE.js +27 -0
  425. package/dist/withdraw-accessible-HL7GACUE.js.map +1 -0
  426. package/package.json +14 -5
  427. package/dist/api-GVYEKSJE.js +0 -19
  428. package/dist/backup-7TFRVFLH.js.map +0 -1
  429. package/dist/chunk-244VXYPG.js.map +0 -1
  430. package/dist/chunk-3ELRMVJK.js.map +0 -1
  431. package/dist/chunk-3F7GLNAE.js.map +0 -1
  432. package/dist/chunk-3H5KLDZN.js.map +0 -1
  433. package/dist/chunk-6B3VNR4P.js.map +0 -1
  434. package/dist/chunk-6LNL42F5.js.map +0 -1
  435. package/dist/chunk-6QSQQLSE.js +0 -95
  436. package/dist/chunk-6QSQQLSE.js.map +0 -1
  437. package/dist/chunk-7VCXZDA4.js.map +0 -1
  438. package/dist/chunk-ANWPSTZU.js.map +0 -1
  439. package/dist/chunk-BP6DARYA.js.map +0 -1
  440. package/dist/chunk-CKNGS5MH.js.map +0 -1
  441. package/dist/chunk-DC5QVPV7.js.map +0 -1
  442. package/dist/chunk-DE4DH2RZ.js +0 -29
  443. package/dist/chunk-DE4DH2RZ.js.map +0 -1
  444. package/dist/chunk-DF73H4UN.js.map +0 -1
  445. package/dist/chunk-EIPVYUEP.js.map +0 -1
  446. package/dist/chunk-ENAG3IY7.js.map +0 -1
  447. package/dist/chunk-FCKWQE2H.js.map +0 -1
  448. package/dist/chunk-FQ5VRHIB.js.map +0 -1
  449. package/dist/chunk-GF5BZ7D4.js.map +0 -1
  450. package/dist/chunk-GHLTDZRS.js.map +0 -1
  451. package/dist/chunk-GYGLAVCX.js.map +0 -1
  452. package/dist/chunk-HBPPGWUM.js.map +0 -1
  453. package/dist/chunk-HK67PX4J.js.map +0 -1
  454. package/dist/chunk-HVSCEIYL.js.map +0 -1
  455. package/dist/chunk-ISZQJBML.js.map +0 -1
  456. package/dist/chunk-KJFW62P4.js.map +0 -1
  457. package/dist/chunk-L7DOS3TE.js.map +0 -1
  458. package/dist/chunk-LGRLME4M.js.map +0 -1
  459. package/dist/chunk-LP7BEXCT.js +0 -32
  460. package/dist/chunk-LP7BEXCT.js.map +0 -1
  461. package/dist/chunk-LQ4ZHOKP.js.map +0 -1
  462. package/dist/chunk-M522UYZ2.js.map +0 -1
  463. package/dist/chunk-M7NI3IWE.js.map +0 -1
  464. package/dist/chunk-MTL7MXGR.js.map +0 -1
  465. package/dist/chunk-N5DNADLQ.js.map +0 -1
  466. package/dist/chunk-NNARWO72.js.map +0 -1
  467. package/dist/chunk-NRT6QZQB.js.map +0 -1
  468. package/dist/chunk-NWHBJQAL.js.map +0 -1
  469. package/dist/chunk-ODVPTDPK.js.map +0 -1
  470. package/dist/chunk-PDCG6PR5.js.map +0 -1
  471. package/dist/chunk-PEOZ34EM.js.map +0 -1
  472. package/dist/chunk-PSIV7CJV.js.map +0 -1
  473. package/dist/chunk-QOOUUR4A.js.map +0 -1
  474. package/dist/chunk-QWFHIOD2.js.map +0 -1
  475. package/dist/chunk-QWGU66MP.js.map +0 -1
  476. package/dist/chunk-S57HTZ6X.js.map +0 -1
  477. package/dist/chunk-SEE332EV.js +0 -66
  478. package/dist/chunk-SEE332EV.js.map +0 -1
  479. package/dist/chunk-SYVZW77S.js.map +0 -1
  480. package/dist/chunk-T2LBQ5DV.js.map +0 -1
  481. package/dist/chunk-UD5EVGZ7.js.map +0 -1
  482. package/dist/chunk-UPD5NWI5.js.map +0 -1
  483. package/dist/chunk-UYB234ZR.js +0 -479
  484. package/dist/chunk-UYB234ZR.js.map +0 -1
  485. package/dist/chunk-VNPEWFPD.js.map +0 -1
  486. package/dist/chunk-WX5ADGTZ.js.map +0 -1
  487. package/dist/chunk-X4773RBR.js.map +0 -1
  488. package/dist/chunk-YNIUIERI.js.map +0 -1
  489. package/dist/chunk-ZE4CHIED.js.map +0 -1
  490. package/dist/chunk-ZXABPVM6.js.map +0 -1
  491. package/dist/classified-marker-W3USLL5M.js.map +0 -1
  492. package/dist/collection-facade-QU6IJBN3.js +0 -48
  493. package/dist/dead-filter-U2UYKSZL.js.map +0 -1
  494. package/dist/delegation-S3AEPW2T.js.map +0 -1
  495. package/dist/derive-OX7F6TGG.js +0 -21
  496. package/dist/dispatch-RH4LHKBH.js.map +0 -1
  497. package/dist/executor-B6SRO2QS.js +0 -36
  498. package/dist/executor-BI5CHWRY.js +0 -8
  499. package/dist/executor-RBKM5W5K.js +0 -8
  500. package/dist/export-accessible-VMA3YM5V.js +0 -22
  501. package/dist/extract-partition-NF7PXGPP.js +0 -37
  502. package/dist/fanout-sidecar-OT6RYLOL.js.map +0 -1
  503. package/dist/find-LZMP26KF.js +0 -10
  504. package/dist/issue-IHARXWW5.js +0 -18
  505. package/dist/kernel/enclave/classify/compare.d.ts +0 -10
  506. package/dist/kernel/enclave/index.d.ts +0 -87
  507. package/dist/kernel/enclave/record-keys/lifecycle.d.ts +0 -124
  508. package/dist/kernel/enclave/record-keys/rekey-blob.d.ts +0 -88
  509. package/dist/kernel/enclave/record-keys/rekey.d.ts +0 -91
  510. package/dist/kernel/enclave/record-keys/sealed-slot.d.ts +0 -14
  511. package/dist/kernel/enclave/record-keys/sealed-slots.d.ts +0 -123
  512. package/dist/kernel/enclave/record-keys/sealing.d.ts +0 -70
  513. package/dist/liberate-GRLCZMW4.js +0 -24
  514. package/dist/link-set-JCMJ7ULP.js +0 -30
  515. package/dist/noydb-SWQJ3MZS.js +0 -97
  516. package/dist/pod-handle-WGDFB4C2.js.map +0 -1
  517. package/dist/post-register-SLSXIPBV.js.map +0 -1
  518. package/dist/register-F3OYE7MJ.js +0 -31
  519. package/dist/registry-CILQFXFK.js +0 -8
  520. package/dist/registry-XNNYQVKV.js +0 -8
  521. package/dist/registry-YCDZV3VW.js +0 -35
  522. package/dist/registry-ZGYS33TE.js +0 -24
  523. package/dist/request-withdrawal-Z5NC6TXT.js +0 -30
  524. package/dist/reveal-4BCKPEC2.js.map +0 -1
  525. package/dist/revoke-ZL62WC2D.js +0 -23
  526. package/dist/seed-4JS2RJ4A.js.map +0 -1
  527. package/dist/signer-MBZZMXTC.js +0 -24
  528. package/dist/stale-TJ3DYZMQ.js +0 -29
  529. package/dist/storage-SVMKRGCW.js +0 -22
  530. package/dist/store-coordination-provider-2O2VUHKW.js.map +0 -1
  531. package/dist/verify-RVT67IMH.js.map +0 -1
  532. package/dist/walk-HJ42EISE.js +0 -21
  533. package/dist/withdraw-accessible-5NZUPAVA.js +0 -27
  534. /package/dist/{api-GVYEKSJE.js.map → api-OS747DS4.js.map} +0 -0
  535. /package/dist/{computed-TPFBX7U4.js.map → capsule/contract.js.map} +0 -0
  536. /package/dist/{kernel/enclave → capsule/enclave-aes}/broker/proof.d.ts +0 -0
  537. /package/dist/{kernel/enclave → capsule/enclave-aes}/classify/bidx.d.ts +0 -0
  538. /package/dist/{kernel/enclave → capsule/enclave-aes}/classify/digest.d.ts +0 -0
  539. /package/dist/{kernel/enclave → capsule/enclave-aes}/classify/vdig.d.ts +0 -0
  540. /package/dist/{kernel/enclave/classify → capsule/plumbing}/kofn.d.ts +0 -0
  541. /package/dist/{kernel/enclave/classify → capsule/plumbing}/normalize.d.ts +0 -0
  542. /package/dist/{kernel/enclave → capsule/plumbing}/record-aad.d.ts +0 -0
  543. /package/dist/{collection-facade-QU6IJBN3.js.map → capsule-VOLX3QRQ.js.map} +0 -0
  544. /package/dist/{chunk-YSK2CU2Q.js.map → chunk-2AFX33YA.js.map} +0 -0
  545. /package/dist/{chunk-TKUOEU2F.js.map → chunk-2GHDLTPE.js.map} +0 -0
  546. /package/dist/{chunk-6OWXYZK2.js.map → chunk-2ODVB6LZ.js.map} +0 -0
  547. /package/dist/{chunk-X25NWUZB.js.map → chunk-2PVXF5CS.js.map} +0 -0
  548. /package/dist/{chunk-ORDURZBU.js.map → chunk-3EWS67C7.js.map} +0 -0
  549. /package/dist/{chunk-FXQBGFOX.js.map → chunk-4CIQDWRB.js.map} +0 -0
  550. /package/dist/{chunk-HT2AHGQI.js.map → chunk-4JPMZTJY.js.map} +0 -0
  551. /package/dist/{chunk-MKXXMNJH.js.map → chunk-4V3Q35WG.js.map} +0 -0
  552. /package/dist/{chunk-A6IJU4TK.js.map → chunk-52MGURXO.js.map} +0 -0
  553. /package/dist/{chunk-HLEK5VAN.js.map → chunk-5WWDGFOS.js.map} +0 -0
  554. /package/dist/{chunk-SOIQ4MM4.js.map → chunk-7XMHMVTS.js.map} +0 -0
  555. /package/dist/{chunk-4MXI3ODD.js.map → chunk-AEQGFRU4.js.map} +0 -0
  556. /package/dist/{chunk-7JE7BDYJ.js.map → chunk-AL6ML4LA.js.map} +0 -0
  557. /package/dist/{chunk-ZUVBC32X.js.map → chunk-AUKKUPVB.js.map} +0 -0
  558. /package/dist/{chunk-WY2XXTET.js.map → chunk-BPWYQ25R.js.map} +0 -0
  559. /package/dist/{chunk-EOVMT6TB.js.map → chunk-BVCUTXE3.js.map} +0 -0
  560. /package/dist/{chunk-3JWHAR6E.js.map → chunk-DIZLQVAA.js.map} +0 -0
  561. /package/dist/{chunk-IT22PWKV.js.map → chunk-E2N2T5ZO.js.map} +0 -0
  562. /package/dist/{chunk-WNJ4AVGE.js.map → chunk-EJLV62NI.js.map} +0 -0
  563. /package/dist/{chunk-QBBUZ3I3.js.map → chunk-EYG2CY2X.js.map} +0 -0
  564. /package/dist/{chunk-BJ2IXQ5Q.js.map → chunk-FFJFE4T7.js.map} +0 -0
  565. /package/dist/{chunk-JCN44NCY.js.map → chunk-FLPCETP6.js.map} +0 -0
  566. /package/dist/{chunk-5O7D6ZTW.js.map → chunk-FOEDQATO.js.map} +0 -0
  567. /package/dist/{chunk-VNNRUGMM.js.map → chunk-FVH5QYY2.js.map} +0 -0
  568. /package/dist/{chunk-4AF3TUMP.js.map → chunk-GZT3NQRA.js.map} +0 -0
  569. /package/dist/{chunk-MVZ2TPVP.js.map → chunk-H427H63K.js.map} +0 -0
  570. /package/dist/{chunk-MLPHLJIQ.js.map → chunk-HS554XAF.js.map} +0 -0
  571. /package/dist/{chunk-TROR3ALR.js.map → chunk-JOSPH3E5.js.map} +0 -0
  572. /package/dist/{chunk-F24ZZTHQ.js.map → chunk-JQYKPKG6.js.map} +0 -0
  573. /package/dist/{chunk-MDWKM2XC.js.map → chunk-M5B2W6YY.js.map} +0 -0
  574. /package/dist/{chunk-F2TDU7MQ.js.map → chunk-MBMTND6D.js.map} +0 -0
  575. /package/dist/{chunk-K6W7BVZ6.js.map → chunk-MILI22XQ.js.map} +0 -0
  576. /package/dist/{chunk-CF5UU4S7.js.map → chunk-N7UDP5VU.js.map} +0 -0
  577. /package/dist/{chunk-FQ54DWUQ.js.map → chunk-NBQ3KK6X.js.map} +0 -0
  578. /package/dist/{chunk-4I522ERM.js.map → chunk-NCO25JZO.js.map} +0 -0
  579. /package/dist/{chunk-SI3V7D4G.js.map → chunk-O2IMQSNA.js.map} +0 -0
  580. /package/dist/{chunk-T52GX4SA.js.map → chunk-O46CHQT7.js.map} +0 -0
  581. /package/dist/{chunk-TOPYQ6GA.js.map → chunk-OYW3I5M4.js.map} +0 -0
  582. /package/dist/{chunk-AOWGXU6D.js.map → chunk-Q4UHJ5SN.js.map} +0 -0
  583. /package/dist/{chunk-FW22ZCXT.js.map → chunk-QBLT6POL.js.map} +0 -0
  584. /package/dist/{chunk-I3JDRCMW.js.map → chunk-RB4DOPGZ.js.map} +0 -0
  585. /package/dist/{chunk-32YV3TJT.js.map → chunk-SMV2HRDU.js.map} +0 -0
  586. /package/dist/{chunk-Z5HTYMMQ.js.map → chunk-SYNY3VB5.js.map} +0 -0
  587. /package/dist/{chunk-ZSX4S5XB.js.map → chunk-TKVUE4JF.js.map} +0 -0
  588. /package/dist/{chunk-B57AFBY2.js.map → chunk-TZZBXPZK.js.map} +0 -0
  589. /package/dist/{chunk-5FDLC6G7.js.map → chunk-UA372JHH.js.map} +0 -0
  590. /package/dist/{chunk-B6SJIBQK.js.map → chunk-V3RWOOSO.js.map} +0 -0
  591. /package/dist/{chunk-HBRLNOHL.js.map → chunk-V7ADQF5O.js.map} +0 -0
  592. /package/dist/{chunk-F7XGHL5O.js.map → chunk-VQDZYB2B.js.map} +0 -0
  593. /package/dist/{chunk-BK2HHQGN.js.map → chunk-VVOLDVIR.js.map} +0 -0
  594. /package/dist/{chunk-6K7DPM7D.js.map → chunk-XQRFSKYM.js.map} +0 -0
  595. /package/dist/{chunk-ID6Z6E66.js.map → chunk-Y2RKVFKR.js.map} +0 -0
  596. /package/dist/{chunk-FN5EBVTQ.js.map → chunk-YRXFFWG4.js.map} +0 -0
  597. /package/dist/{derive-OX7F6TGG.js.map → collection-facade-CS7CA2XO.js.map} +0 -0
  598. /package/dist/{enclave-27SMF6GF.js.map → computed-FAD7SED4.js.map} +0 -0
  599. /package/dist/{executor-B6SRO2QS.js.map → derive-XLOJVXPU.js.map} +0 -0
  600. /package/dist/{dispatch-3CQDJV5Q.js.map → dispatch-H4HV32AM.js.map} +0 -0
  601. /package/dist/{executor-BI5CHWRY.js.map → executor-FMPVN6DT.js.map} +0 -0
  602. /package/dist/{executor-RBKM5W5K.js.map → executor-LBBBRTN5.js.map} +0 -0
  603. /package/dist/{export-accessible-VMA3YM5V.js.map → executor-OSRZST2U.js.map} +0 -0
  604. /package/dist/{extract-partition-NF7PXGPP.js.map → export-accessible-RAOJAAU5.js.map} +0 -0
  605. /package/dist/{find-LZMP26KF.js.map → extract-partition-JD5CUSTG.js.map} +0 -0
  606. /package/dist/{issue-IHARXWW5.js.map → find-JRN4RNQ5.js.map} +0 -0
  607. /package/dist/{ledger-KZPCMVZY.js.map → issue-YIVBZUTH.js.map} +0 -0
  608. /package/dist/{liberate-GRLCZMW4.js.map → ledger-5ZMGE44K.js.map} +0 -0
  609. /package/dist/{link-set-JCMJ7ULP.js.map → liberate-WZSZM2W6.js.map} +0 -0
  610. /package/dist/{managed-secret-S3MQ6SH6.js.map → link-set-MFXC24VK.js.map} +0 -0
  611. /package/dist/{noydb-SWQJ3MZS.js.map → managed-secret-MFTFT22X.js.map} +0 -0
  612. /package/dist/{migrate-cek-V7GKJZ7O.js.map → migrate-cek-DZRFFOHW.js.map} +0 -0
  613. /package/dist/{register-F3OYE7MJ.js.map → noydb-ITIGNKUF.js.map} +0 -0
  614. /package/dist/{registry-CILQFXFK.js.map → register-DT5HZ2LZ.js.map} +0 -0
  615. /package/dist/{registry-XNNYQVKV.js.map → registry-BHRZGZHF.js.map} +0 -0
  616. /package/dist/{registry-YCDZV3VW.js.map → registry-ET6ZFFWA.js.map} +0 -0
  617. /package/dist/{registry-ZGYS33TE.js.map → registry-HXFGLGTG.js.map} +0 -0
  618. /package/dist/{request-withdrawal-Z5NC6TXT.js.map → registry-THCPDEOD.js.map} +0 -0
  619. /package/dist/{revoke-ZL62WC2D.js.map → request-withdrawal-AV2MJJKY.js.map} +0 -0
  620. /package/dist/{signer-MBZZMXTC.js.map → revoke-6DWIEOCV.js.map} +0 -0
  621. /package/dist/{stale-TJ3DYZMQ.js.map → signer-MHGW3OIL.js.map} +0 -0
  622. /package/dist/{storage-SVMKRGCW.js.map → stale-6GCFMOOR.js.map} +0 -0
  623. /package/dist/{walk-HJ42EISE.js.map → storage-BYN5LO6Z.js.map} +0 -0
  624. /package/dist/{withdraw-accessible-5NZUPAVA.js.map → walk-4VPK7AS4.js.map} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/with-audit/tiers/active.ts","../src/with-audit/tiers/strategy.ts","../src/with-audit/tiers/index.ts"],"sourcesContent":["/**\n * Enable the hierarchical-tiers capability.\n * Pass to `createNoydb({ tiersStrategy: withTiers() })` to make a collection's\n * `putAtTier` / `getAtTier` / `listAtTier` / `elevate` / `demote` methods live.\n * The tier read/write/re-key engine is dynamically imported here, so it stays\n * out of the floor bundle until opted in.\n */\nimport type { TiersStrategy } from './strategy.js'\n\nexport function withTiers(): TiersStrategy {\n return {\n async putAtTier(ctx, id, record, tier, opts) {\n const { putAtTier } = await import('./index.js')\n return putAtTier(ctx, id, record, tier, opts)\n },\n async getAtTier(ctx, id) {\n const { getAtTier } = await import('./index.js')\n return getAtTier(ctx, id)\n },\n async listAtTier(ctx) {\n const { listAtTier } = await import('./index.js')\n return listAtTier(ctx)\n },\n async elevate(ctx, id, toTier) {\n const { elevate } = await import('./index.js')\n return elevate(ctx, id, toTier)\n },\n async demote(ctx, id, toTier) {\n const { demote } = await import('./index.js')\n return demote(ctx, id, toTier)\n },\n async checkUnique(ctx, id, record) {\n // Skip the dynamic import entirely on the overwhelmingly common case:\n // a tiered collection with no `unique` index declared.\n if (!ctx.uniqueKeys) return\n const { checkUniqueAcrossTiers } = await import('./index.js')\n return checkUniqueAcrossTiers(ctx, id, record)\n },\n }\n}\n","/**\n * Tiers capability strategy — the five on-demand collection-level tier\n * operations the `Collection` routes through. The active engine\n * ({@link withTiers}) dynamically imports the tier cores (keeping them out of\n * the floor bundle); {@link NO_TIERS} throws. Collection always builds its\n * per-call {@link TiersContext} and delegates here, so an un-opted-in caller\n * hits `NO_TIERS`'s throw.\n * @internal\n */\nimport type { GhostRecord } from '../../kernel/types.js'\nimport type { TiersContext, TierMoveResult } from './index.js'\nimport { TiersNotEnabledError } from '../../kernel/errors.js'\n\n// #779 — re-exported so kernel-spine callers (e.g. `Vault._elevatedPut`) can reference the\n// result shape via this grandfathered strategy.js seam instead of statically importing\n// tiers/index.js directly (the port-layering check only grandfathers this file).\nexport type { TierMoveResult }\n\nexport interface TiersStrategy {\n putAtTier<T>(\n ctx: TiersContext<T>,\n id: string,\n record: T,\n tier: number,\n opts?: { elevation?: { reason: string; fromTier: number }; source?: string; sourceTs?: string },\n ): Promise<TierMoveResult>\n getAtTier<T>(ctx: TiersContext<T>, id: string): Promise<T | GhostRecord | null>\n listAtTier<T>(ctx: TiersContext<T>): Promise<Array<{ id: string; tier: number; readable: boolean }>>\n elevate<T>(ctx: TiersContext<T>, id: string, toTier: number): Promise<TierMoveResult>\n demote<T>(ctx: TiersContext<T>, id: string, toTier: number): Promise<TierMoveResult>\n /**\n * #1358 — unique-constraint scan across every tier whose DEK the writer\n * holds. Called by the ORDINARY `Collection.put()` on a tiered collection\n * (`putAtTier` calls the core directly): the tier-0 mirror cannot see an\n * elevated record, because #709 purges its index entries on elevation.\n * A tier the writer cannot read is outside the guarantee.\n */\n checkUnique<T>(ctx: TiersContext<T>, id: string, record: T): Promise<void>\n}\n\n/**\n * No-op stub — the floor default. Every capability method throws\n * {@link TiersNotEnabledError}; opt in with `tiersStrategy: withTiers()` in\n * createNoydb. @internal\n */\nexport const NO_TIERS: TiersStrategy = {\n async putAtTier() { throw new TiersNotEnabledError() },\n async getAtTier() { throw new TiersNotEnabledError() },\n async listAtTier() { throw new TiersNotEnabledError() },\n async elevate() { throw new TiersNotEnabledError() },\n async demote() { throw new TiersNotEnabledError() },\n // NOT a throw, unlike its five siblings: this one is called from the\n // ORDINARY put path of any collection that declared `tiers` — and a\n // collection can declare `tiers` without wiring `withTiers()`. Without the\n // engine no record can ever leave tier 0, so there is nothing above tier 0\n // to scan and the tier-0 mirror is already the whole truth. Throwing here\n // would break plain `put()` on such a collection for no gain.\n async checkUnique() { /* no tier engine ⇒ every record is at tier 0 */ },\n}\n","/**\n * Hierarchical access — the collection-level tier operations\n * (`putAtTier` / `getAtTier` / `listAtTier` / `elevate` / `demote`).\n *\n * A collection opted into `{ tiers: [...] }` stamps `_tier: N` on each envelope\n * and encrypts its body under the tier-N DEK. These helpers are the read/write\n * surface for that scheme: write at a tier, read with tier-aware visibility\n * (invisibility vs. ghost), and move a record up (`elevate`) or down (`demote`)\n * the tier ladder by re-wrapping its body key.\n *\n * Each function takes a small {@link TiersContext} (the exact `this.*` the\n * moving methods touched) instead of `this`, mirroring the `record-keys/`\n * siblings. Behaviour is byte-identical to the inline code it replaced.\n *\n * The crux is `cekCache`: `elevate`/`demote`/`getAtTier` write the SAME `Lru`\n * reference `Collection` owns (never a copy) so a per-record CEK re-wrap stays\n * synchronous with the cache the kernel's write/read path also mutates. The\n * cross-tier event sink stays collection-resident and is reached via the\n * `emitCrossTierEvent` callback.\n *\n * Internal service — not exported as a `@noy-db/hub/*` subpath.\n */\nexport { withTiers } from './active.js'\nexport { NO_TIERS, type TiersStrategy } from './strategy.js'\nexport { TiersNotEnabledError } from '../../kernel/errors.js'\nimport { recordAadFor, type RecordIdentity, buildRecordAad, buildRecordEnvelope, encrypt, decrypt, unwrapCek, rewrapBodyToDek, applyRewrappedBody, isDeleteMarker, isTombstoneShape, type RecordCodec, type EnclaveKey, type SealedShredSlot } from '../../kernel/enclave/index.js'\nimport { TierDemoteDeniedError, UnsupportedTierCompositionError, PersistedIndexCompensationError, UniqueConstraintError } from '../../kernel/errors.js'\nimport { dekKey, assertTierAccess } from '../../with-party/team/tiers.js'\nimport type { UnlockedKeyring } from '../../with-party/team/keyring.js'\nimport type { Lru } from '../../kernel/cache/index.js'\nimport type { BlobFieldsConfig } from '../../with-shape/blobs/blob-compaction.js'\nimport {\n NOYDB_FORMAT_VERSION,\n type NoydbStore,\n type EncryptedEnvelope,\n type GhostRecord,\n type TierMode,\n type CrossTierAccessEvent,\n} from '../../kernel/types.js'\n\n/** Everything the moving tier methods touched on `this.*`, as a flat context. */\nexport interface TiersContext<T> {\n /** Collection name — the crypto AAD scope and tier-DEK key prefix. */\n readonly name: string\n /** Vault namespace the records live under. */\n readonly vault: string\n /** The ciphertext store. */\n readonly adapter: NoydbStore\n /**\n * #1358 — the unique-constraint keys a record occupies, or `[]` when the\n * record is exempt (null-distinct) . `undefined` when the collection\n * declares no `unique` index, which is what makes the tier scan free for\n * every other collection. Deliberately a plain callback rather than the\n * `UniqueConstraintSet` itself: the tier domain must not import the\n * indexing domain, and this is the whole of what it needs.\n */\n readonly uniqueKeys?: ((record: unknown) => ReadonlyArray<{ readonly fields: readonly string[]; readonly key: string }>) | undefined\n /**\n * #1358 — the collection's own tier-0 unique pre-flight (the eager map or\n * the lazy `_idx/` probe). `putAtTier` runs it before its write because it\n * bypasses `Collection.put()` entirely; the tier-0 `put()` path calls it\n * directly and does not need this. `undefined` ⇒ no unique index declared.\n */\n readonly checkUniqueLocal?: ((id: string, record: unknown) => Promise<void>) | undefined\n /** The caller's unlocked keyring (tier-DEK holdings + role + userId). */\n readonly keyring: UnlockedKeyring\n /** The record codec — decrypts a tier-0 envelope to T. */\n readonly codec: RecordCodec<T>\n /**\n * The collection's per-record CEK cache (SHARED reference, not a copy).\n * `elevate`/`demote`/`getAtTier` re-wrap a record's CEK and `set` it here so\n * the move stays synchronous with the cache the kernel's read/write path\n * owns. `null` → no caching.\n */\n readonly cekCache: Lru<string, EnclaveKey> | null\n /**\n * Sync the collection's decoded-record cache after a tier move rewraps the\n * envelope (#691). The lazy LRU is evicted on EVERY call — it is never\n * re-seeded, since a lazy `#getRaw` miss refetches and decodes the fresh\n * envelope via its adapter fallback (a stale LRU entry after a tier-0\n * `putAtTier` overwrite was the #702 lazy-mode gap). `null` → also evict\n * the eager cache entry; an `entry` → set the eager cache to the given\n * decoded record/version (used by `demote()` landing back at tier 0 and\n * `putAtTier`'s tier-0 write, #702 — the record is tier-0, so it must stay\n * plain-`get()`-readable in-session).\n */\n syncCache(id: string, entry: { record: T; version: number } | null): void\n /**\n * Sync the collection's indexes after a tier move rewraps the envelope\n * (#709). Persisted `_idx/<field>/<recordId>` side-cars hold the indexed\n * field's PLAINTEXT value and are always encrypted under the tier-0 DEK,\n * whatever the record's own tier — the same leak class `forget()` fixed\n * via `purgePersistedIndexes` (\"forget() crypto-shreds the body but keeps\n * the collection DEK, under which these side-cars are encrypted — so\n * without this they leave the indexed field VALUES readable\"). `null` →\n * the record just left tier 0: purge its persisted side-cars and drop its\n * in-memory index entries. A record → it is tier-0 again: (re)build its\n * entries from that record. Call this BEFORE {@link syncCache} — the\n * implementation reads the pre-write cached value as \"previous\" to clean\n * up stale index buckets, so it must run while that entry is still live.\n * `version` stamps a rebuilt side-car's own envelope version — every\n * caller has one in scope (the envelope it just wrote), including the\n * purge (`null`) branches, which pass it along even though it's ignored\n * there (#720: keeps the parameter honestly required, no dead default).\n * `priorEnvelope` (#720) — the RAW envelope read BEFORE this call's own\n * overwrite (already in scope as `existing`/`envelope` at every record-\n * branch call site), so a lazy same-tier value change (a `putAtTier(0)`\n * dropping an indexed field, a `demote(0)` off an elevated record) can\n * still be tier-gate-decoded as \"previous\" once the live envelope itself\n * has already moved past it. The `null`-record branches never pass one —\n * see the implementation's doc comment for why they don't need to.\n */\n syncIndexes(id: string, record: T | null, version: number, priorEnvelope?: EncryptedEnvelope): Promise<void>\n /** Sync the collection's SEARCH artifacts after a tier move (#721). Both the\n * lexical `_ftindex` blob and the `_vec/<id>` embedding are encrypted under\n * the tier-0 DEK and hold the record's derived plaintext (full field text /\n * a text-invertible vector), so leaving them means elevation never hid what\n * the record was searchable by — the `forget()` precedent, unapplied to\n * elevate. `null` → the record left tier 0: purge its `_vec`, and\n * invalidate the `_ftindex` blob (the cache-driven rebuild then excludes\n * it). A record → it is tier-0 again: re-embed it, and invalidate\n * `_ftindex` (rebuild includes it). No-op fast when the collection has no\n * search. */\n syncSearch(id: string, record: T | null, version?: number): Promise<void>\n /**\n * Sync a record's `_history` snapshots after a tier move rewraps the live\n * envelope (#712, at-rest hardening). Each snapshot carries its own key\n * material (a direct DEK wrap, or a per-record `_cek` itself wrapped under\n * the tier DEK) — `elevate()`'s live-body rewrap moves only the live\n * envelope, leaving prior versions decryptable at rest under the tier the\n * record has moved away from (the same leak class `forget()`'s\n * `tombstoneHistory` closed for erasure). `fromDek`/`toDek` are the SAME\n * DEKs the caller already resolved for the live rewrap — reuse them, don't\n * recompute. No-op when the strategy is `NO_HISTORY`.\n */\n syncHistory(id: string, fromDek: EnclaveKey, toDek: EnclaveKey): Promise<void>\n /**\n * Save a raw pre-move envelope as a `_history` snapshot (#728). Tier moves\n * (`putAtTier`/`elevate`/`demote`) bump `_v` and overwrite the live\n * envelope without ever snapshotting the version that existed just before\n * the move — so `history()` silently lost it. The caller (`tiers/index.ts`)\n * builds `envelope` by reusing the SAME `rewrapBodyToDek(envelope, fromDek,\n * toDek)` result it already computed for the live write, so the snapshot\n * lands wrapped under the DESTINATION tier's DEK — never `ctx.codec.\n * encryptRecord`, which always resolves the tier-0 DEK and would leak the\n * pre-move body whenever `fromTier > 0`. No-op when history is disabled\n * (folds the `historyConfig.enabled` gate so `tiers/index.ts` stays simple).\n */\n /**\n * Persist a `_history` snapshot of `version`, sealed against the address it\n * will be STORED at (#1041).\n *\n * Takes a **sealer**, not a finished envelope, because the destination\n * identity is not knowable here: only the history strategy owns the\n * `_history` layout. It hands the address in; the caller seals to it.\n *\n * ⚠️ The identity passed to `rewrapBodyToDek` must be what a READER will\n * recompute — `recordAadFor(address, finalEnvelope)`. A tier-move snapshot\n * strips `_tier`/`_elevatedBy` but KEEPS `_by`, so the destination is\n * `{...address, by: envelope._by}` with no tier. Sealing against the bare\n * address would produce history nothing can open, and the failure would\n * surface only when someone reads it.\n */\n saveHistorySnapshot(\n id: string,\n version: number,\n seal: (address: RecordIdentity) => Promise<EncryptedEnvelope>,\n ): Promise<void>\n /**\n * `true` iff a real history strategy is wired (not `NO_HISTORY`) AND not\n * explicitly disabled via `historyConfig.enabled`. `putAtTier` checks this\n * BEFORE decrypting `existing` to build a snapshot (#728, #737 regression\n * fix) — unlike elevate/demote, which reuse a `body` rewrap their live\n * write needs unconditionally, putAtTier's live write never decrypts the\n * prior envelope, so building a snapshot is the ONLY reason it would\n * touch (and potentially throw decrypting) `existing`'s ciphertext. A\n * derivation-free, history-disabled collection must not pay that decode —\n * or risk it, on a corrupted/inaccessible prior body — same law\n * `hasDerivedOutputs` already enforces for the derived-outputs decode.\n */\n readonly historyEnabled: boolean\n /**\n * Rehome a record's blob attachments after a tier move (#724 Arc 10 Task\n * 2, at-rest hardening). A blob's home tier is its owning record's tier —\n * the `_blob` DEK is tier-scoped (`dekKey('_blob', tier)`), so a solo-\n * owned blob's content CEK must move with the record or it stays\n * tier-0-unwrappable at rest even once the live body has moved (the same\n * leak class `syncHistory` closes for `_history` snapshots). Delegates to\n * `BlobSet.rehomeForTier`; no-op fast when the collection has no blob\n * fields. Order-independent with the other sync hooks — touches only\n * blob side structures, not this collection's own cache/indexes.\n */\n syncBlobs(id: string, fromTier: number, toTier: number): Promise<void>\n /**\n * Purge a record's tier-0-era plaintext ledger deltas after a tier move\n * lands it above tier 0 (#729). The audit ledger is a flat, vault-wide,\n * hash-chained log — a record's reverse-JSON-Patch deltas in\n * `_ledger_deltas` are encrypted under one collection-wide `_ledger` DEK\n * (not the record's own tier DEK), so `elevate()`/`putAtTier()`'s live-body\n * rewrap never moves them: they stay readable at rest to any tier-0\n * caller, the same leak class `syncHistory` closed for `_history`\n * snapshots. Chain-safe: `verify()` reads only `_ledger` entry fields\n * (including `deltaHash`, which lives on the entry, not the deleted delta\n * row), never `_ledger_deltas`, so a purge cannot break it.\n * **Irreversible** — the deleted plaintext cannot be restored by\n * `demote()`. **Metadata-retained** — the `_ledger` entries (that the\n * record was mutated, at which version/timestamp/actor) are untouched;\n * only the delta *content* is purged. No-op when the collection has no\n * ledger (`withHistory()` not enabled).\n */\n syncLedger(id: string): Promise<void>\n /**\n * Sync a record's derived outputs (materialized-view rows, rollup\n * contributions, `withDerivation` outputs) after a tier move (#722).\n * Those outputs are computed from this record and written to OTHER\n * (output) collections via a plain `put` at tier 0 — `elevate()`'s live-\n * body rewrap moves only the source envelope, so the output rows keep\n * holding the source's tier-0-era plaintext, the same leak class\n * `syncSearch`/`syncIndexes` closed for THIS collection's own artifacts.\n * `elevated` (landing tier > 0) reuses the SAME onDelete fanout\n * `forgetDerivedFanout` drives for `forget()` (`kernel/via/dispatch.ts`)\n * — minus its `'ref'` cascade edge (elevate/demote never erase a\n * *different* record) — to recompute this record's derived outputs as\n * REMOVED. Recompute is tier-safe: the fanout's own source scan reads\n * the elevated-excluding cache (#701/#709/#712), so it naturally omits\n * the now-elevated record instead of re-embedding its plaintext. Landing\n * back at tier 0 (`elevated === false`) is the reverse (Task 2, #722):\n * `syncDerivedOutputs` instead runs the ordinary local-write add-\n * dispatchers (`dispatchDerivations`/`dispatchMaterializedViews`, the\n * same ones a plain `put()` fires) to restore the contribution —\n * reversible, since the source's plaintext survives the elevate/demote\n * rewrap round-trip. `record` is the decoded source record (PRE-move on\n * the remove side, POST-move on the add side); only the rollup edge\n * consumes it on remove, both add-dispatchers require it on add; `null`\n * (tombstone/delete-marker) skips both. `version` stamps the add-\n * dispatchers' `_derivedFrom.sourceVersion` metadata — reuses the version\n * the tier op already has, no re-read; unused on the remove side. No-op\n * fast when the collection has no MV/derivation source — each dispatcher\n * below checks its own source before doing any work.\n */\n syncDerived(id: string, record: T | null, elevated: boolean, version?: number): Promise<void>\n /**\n * `true` iff the collection has a materialized-view or derivation source\n * attached. Gates the {@link syncDerived} pre-move decode on the remove\n * direction (`elevate()`, `putAtTier(tier>0)`, `demote()`'s intermediate-\n * tier branch): those sites decode the record SOLELY to feed\n * `syncDerived(..., true)`, whose dispatchers no-op immediately when the\n * collection has no MV/derivation source — so a no-derivation collection\n * would otherwise pay a full record-body decrypt on every tier move for\n * nothing (#722 perf regression). `false` short-circuits the decode to\n * `null`, which `syncDerivedOutputs` already treats safely.\n */\n readonly hasDerivedOutputs: boolean\n /** Emit `_source`/`_sourceTs` provenance fields when a source is supplied. */\n readonly provenance: boolean\n /** Declared tiers, or null when the feature is off. */\n readonly tiers: ReadonlySet<number> | null\n /** Above-tier read visibility mode (`'invisibility'` | `'ghost'`). */\n readonly tierMode: TierMode\n /** Resolve a tier DEK by its `dekKey(name, tier)`. */\n getDEK(key: string): Promise<EnclaveKey>\n /** Fire a cross-tier access event (sink stays collection-resident). */\n emitCrossTierEvent(event: CrossTierAccessEvent): void\n /**\n * Register this record's ref in the encrypted `_subject_index` (#766).\n * `putAtTier`'s raw `ctx.adapter.put` bypasses `Collection.put()`'s write-\n * hook pipeline — the `onAfterWrite` hook that normally does this — so a\n * record whose FIRST persistence is `putAtTier` (sensitive from birth, a\n * documented legitimate use) would otherwise never enter the index and\n * stay unreachable by `vault.forget()`. Idempotent (safe on every call,\n * including a repeat write of an already-registered record) and a no-op\n * when the collection declares no forget-subject field.\n */\n addSubjectRef(id: string, record: T): Promise<void>\n}\n\nexport function assertTiersEnabled<T>(ctx: TiersContext<T>): void {\n if (!ctx.tiers) {\n throw new Error(\n `Collection \"${ctx.name}\": hierarchical tiers are not enabled. ` +\n `Pass { tiers: [0, 1, 2, …] } to vault.collection() to opt in.`,\n )\n }\n}\n\nexport function assertDeclaredTier<T>(ctx: TiersContext<T>, tier: number): void {\n if (tier < 0 || !Number.isInteger(tier)) {\n throw new Error(`Collection \"${ctx.name}\": tier must be a non-negative integer, got ${tier}`)\n }\n if (tier === 0) return\n if (!ctx.tiers || !ctx.tiers.has(tier)) {\n throw new Error(\n `Collection \"${ctx.name}\": tier ${tier} is not declared in { tiers: [...] }`,\n )\n }\n}\n\n/**\n * Tier-composition guard (#724 / Arc 7 of the tier-invisibility campaign).\n *\n * Refuses `tiers` declared together with a derived-artifact feature whose\n * crypto has not yet been made tier-aware — i.e. a feature `elevate()` /\n * `demote()` does not re-key when a record moves tiers, so an elevated\n * record's data for that feature would stay readable at tier 0.\n *\n * **Status:** the original call site (`Collection` constructor, beside\n * `buildUniqueConstraintSet`) was removed by Arc 10 Task 1 (#724) — the\n * `tiers + blobFields` refusal below was superseded by a runtime read gate\n * on `collection.blob(id)` (`with-shape/blobs/blob-set.ts`), so this\n * function currently has no caller. Relocated here from\n * `with-lookup/indexing/unique-constraints.ts` (#733) so the tier-domain\n * guard lives in the tier domain, rather than an indexing file it only\n * borrowed for a grandfathered import specifier.\n *\n * ## #724 verified: `tiers + blobFields` leaks\n *\n * `collection.blob(id)` (`Collection.blob()`) never checks the live\n * record's tier before returning a `BlobSet` handle, and `BlobSet`'s crypto\n * is entirely orthogonal to the tier ladder:\n * - the slot map (`_blob_slots_{collection}/{id}`) is encrypted under the\n * collection's TIER-0 DEK (`getDEK(name)` ≡ `dekKey(name, 0)` — see\n * `dekKey` in `with-party/team/tiers.ts`), never a tier-N DEK;\n * - chunk content (`_blob_index` / `_blob_chunks`) is encrypted under the\n * vault-shared `_blob` DEK (`BLOB_COLLECTION`), which has no tier\n * dimension at all.\n * `elevate()`/`demote()` (this file) rewrap only the live record body,\n * `_history` snapshots (#712), and index side-cars — blob slots and chunks\n * are untouched. A caller whose keyring never held the record's elevated\n * tier DEK can still open `collection.blob(id).get(slot)` and read full\n * plaintext, even though `collection.get(id)` correctly reports the same\n * record as invisible. See `__tests__/tier-composition-guard.test.ts` for\n * the reproduction.\n *\n * ## Safe today — no check needed here\n *\n * Field indexes, search (`textIndexes`/`embeddings`), `withHistory`\n * (snapshot keys are rewrapped by `elevate()`/`demote()`, #712), and the\n * decoded-record cache (evicted on tier moves) are already tier-safe. They\n * are not enumerated below; only known-unsafe features are refused, so any\n * combination not named here passes silently by default.\n *\n * ## Deliberately NOT handled here\n *\n * - `ledger` — `withHistory` threads a ledger writer onto every tiered\n * collection by default in shipped usage; refusing `tiers + ledger` would\n * break that default. A ledger-specific tier-rekey handler (rewrap ledger\n * entries, or scope ledger visibility to tier) is a separate arc.\n * - materialized-view (MV) output — an MV's fanout spec lives on the\n * SOURCE collection, not on the MV collection's own config, so it is not\n * visible at `vault.collection()` registration time and this guard cannot\n * detect it structurally.\n */\nexport function assertTierComposition(\n collectionName: string,\n cfg: { readonly tiers: boolean; readonly blobFields: BlobFieldsConfig | undefined },\n): void {\n if (!cfg.tiers) return\n if (cfg.blobFields !== undefined && Object.keys(cfg.blobFields).length > 0) {\n throw new UnsupportedTierCompositionError(\n 'blobs',\n `Collection \"${collectionName}\": blobFields are not supported together with tiers (#724) — ` +\n `blob chunk content is encrypted under a vault-shared DEK that elevate()/demote() do not ` +\n `re-key, so an elevated record's blob attachments would remain readable at tier 0. Use a ` +\n `non-tiered collection for blob-bearing records until a blob tier-rekey handler ships.`,\n )\n }\n}\n\nfunction isElevatorOrOwner<T>(ctx: TiersContext<T>): boolean {\n return ctx.keyring.role === 'owner' || ctx.keyring.role === 'admin'\n}\n\n/**\n * Structural surface {@link syncDerivedOutputs} needs from the owning\n * collection — the SAME onDelete dispatchers `forgetDerivedFanout` already\n * drives (`kernel/via/dispatch.ts`), reused as-is (#722). Narrower than\n * `Collection<T>` (avoids an import cycle: collection.ts constructs\n * `TiersContext` FROM `this`, which already satisfies this shape\n * structurally — no cast needed at the `tiersContext()` call site).\n */\nexport interface DerivedOutputsHost<T> {\n dispatchMaterializedViewsOnDelete(id: string): Promise<{ deleted: number; residueUndecodable: string[]; residueDeclined: string[] }>\n dispatchArrayDerivationsOnDelete(id: string, eraseRecordShapeToo?: boolean): Promise<number>\n dispatchRollupsOnDelete(id: string, deleted: T): Promise<unknown>\n /** Task 2 (#722) add-direction: the same local-write dispatchers an ordinary `put()` fires. */\n dispatchMaterializedViews(id: string, record: T): Promise<void>\n dispatchDerivations(id: string, record: T, version: number): Promise<void>\n}\n\n/**\n * The {@link TiersContext.syncDerived} implementation collection.ts's\n * `tiersContext()` binds `this` into (#722). See that field's doc comment\n * for the design; `host` is `this` — every dispatcher below is a public\n * Collection method, already self-guarding (no-op) when the collection has\n * no materialized-view/derivation source, so no separate fast-path check is\n * needed here.\n */\nexport async function syncDerivedOutputs<T>(\n host: DerivedOutputsHost<T>,\n id: string,\n record: T | null,\n elevated: boolean,\n version?: number,\n): Promise<void> {\n if (elevated) {\n await host.dispatchMaterializedViewsOnDelete(id)\n await host.dispatchArrayDerivationsOnDelete(id, true)\n if (record !== null) await host.dispatchRollupsOnDelete(id, record)\n return\n }\n // Task 2 (#722) recompute-as-add: the record rejoined tier 0 (demote(→0) /\n // putAtTier(0)) — restore its contribution via the SAME local-write\n // dispatchers an ordinary `put()` fires (`collection.ts`'s\n // `_onRecordMutated('local-write')`), same order. `record === null` only\n // when a caller demotes a tombstone/delete-marker to 0 — nothing to add.\n if (record === null) return\n await host.dispatchDerivations(id, record, version ?? 0)\n await host.dispatchMaterializedViews(id, record)\n}\n\n/**\n * tier-aware put. Encrypts the record with the collection's tier-N DEK and\n * stamps `_tier: N` on the envelope. The caller's keyring must hold the tier-N\n * DEK (directly, by delegation, or by virtue of being the grantor); otherwise\n * throws `TierNotGrantedError`.\n *\n * accepts an optional `elevation` context. When present, the emitted cross-tier\n * event is stamped with `authorization: 'elevation'`, the elevation's reason,\n * and the caller's pre-elevation tier. `vault.elevate(...).collection().put`\n * threads this through; direct `putAtTier` calls leave it undefined and fall\n * back to the inherent-write event shape.\n */\nexport async function putAtTier<T>(\n ctx: TiersContext<T>,\n id: string,\n record: T,\n tier: number,\n opts?: { elevation?: { reason: string; fromTier: number }; source?: string; sourceTs?: string },\n): Promise<TierMoveResult> {\n assertTiersEnabled(ctx)\n assertDeclaredTier(ctx, tier)\n assertTierAccess(ctx.keyring, ctx.name, tier)\n\n // #1358: `putAtTier` is the \"separate path that bypasses unique\n // enforcement\" the old registration-time refusal named. Both halves run\n // here, BEFORE any key resolution or write, so a violation leaves nothing\n // behind: the tier-0 mirror check the collection owns, then the scan of\n // every above-tier record this writer can decrypt.\n await ctx.checkUniqueLocal?.(id, record)\n await checkUniqueAcrossTiers(ctx, id, record)\n\n const key = dekKey(ctx.name, tier)\n const dek = await ctx.getDEK(key)\n\n const existing = await ctx.adapter.get(ctx.vault, ctx.name, id)\n // #712/whole-branch-fix-1: putAtTier moves the record OFF its existing\n // tier, same as elevate/demote — so the caller must also be cleared for\n // that existing tier, not just the target. Without this, a member holding\n // only the target tier's DEK could putAtTier over a record parked at a\n // tier they've never been granted; the from-tier `getDEK` below would then\n // silently MINT a fresh DEK for that tier into their keyring (a\n // non-cleared caller creating tier key material inside the trust\n // boundary — see `assertTierAccess`'s doc comment). Gate here, BEFORE any\n // from-tier getDEK/syncHistory call, so the mint never happens; owner/\n // admin/custodian still bypass (they may mint, same as elevate/demote).\n assertTierAccess(ctx.keyring, ctx.name, existing?._tier ?? 0)\n const version = existing ? existing._v + 1 : 1\n\n // #728 review-fix-2: resolve the from-tier DEK and snapshot the PRE-move\n // version BEFORE the live write below, mirroring elevate()/demote() —\n // originally this ran much later (after syncIndexes/syncLedger/syncDerived/\n // syncSearchResilient), so a throw in any of those left the live record\n // already moved with `existing` — its sole pre-move copy — gone, silently\n // losing the version #728 exists to preserve. `fromKey`/`fromDek` are\n // resolved ONCE here and reused below for the trailing syncHistory rewrap.\n const fromKey = dekKey(ctx.name, existing?._tier ?? 0)\n const fromDek = await ctx.getDEK(fromKey)\n if (existing && ctx.historyEnabled) {\n // Snapshot the version this write is about to overwrite — same law as\n // Collection.put()'s history save, extended to putAtTier (#728). Rewrap\n // under the DESTINATION `dek` via `applyRewrappedBody` (never\n // `ctx.codec.encryptRecord`, which always resolves the tier-0 DEK and\n // would leak this body at rest whenever the prior tier was > 0).\n // Untagged (`_tier`/`_elevatedBy` stripped), same as elevate()/\n // demote()'s snapshots. `_v` stays the PRE-move version (unbumped), as\n // `preCarried` already carries it.\n const preFrom: RecordIdentity = {\n // The PRE-move version — this identity opens what is already stored.\n collection: ctx.name, id, version: existing._v,\n ...(existing._tier !== undefined ? { tier: existing._tier } : {}),\n ...(existing._by !== undefined ? { by: existing._by } : {}),\n }\n await ctx.saveHistorySnapshot(id, existing._v, async (address) => {\n // The snapshot is UNTAGGED (`_tier` stripped) and keeps `_by`, so that is\n // the identity a reader will recompute from it (#1041).\n const to: RecordIdentity = { ...address, ...(existing._by !== undefined ? { by: existing._by } : {}) }\n const body = await rewrapBodyToDek(preFrom, to, existing, fromDek, dek)\n // eslint-disable-next-line @typescript-eslint/no-unused-vars -- excluded from ...preCarried\n const { _tier: _preTier, _elevatedBy: _preElevatedBy, ...preCarried } = existing\n return applyRewrappedBody(preCarried, body)\n })\n }\n\n const json = JSON.stringify(record)\n const identity = { collection: ctx.name, id, version, by: ctx.keyring.userId, ...(tier > 0 ? { tier } : {}) }\n const { iv, data } = await encrypt(json, dek, buildRecordAad(identity))\n const envelope = buildRecordEnvelope(\n identity,\n {\n iv,\n data,\n // `_tier` is stamped from `identity.tier` above — the single source.\n ...(ctx.provenance && opts?.source !== undefined\n ? { provenance: { source: opts.source, sourceTs: opts.sourceTs ?? new Date().toISOString() } }\n : {}),\n },\n )\n\n await ctx.adapter.put(ctx.vault, ctx.name, id, envelope)\n\n // #766: putAtTier bypasses Collection.put()'s onAfterWrite hook — register\n // the subject ref directly so a sensitive-from-birth first write stays\n // reachable by vault.forget(). No-op when no forget-subject field is declared.\n await ctx.addSubjectRef(id, record)\n\n // #702/#709: keep the record cache AND indexes coherent with the raw\n // write — same law as elevate/demote (#691): tier > 0 → invisible on\n // tier-0 surfaces (evict + purge); tier 0 → an ordinary write (re-seed +\n // reindex). syncIndexes runs first — it needs the pre-write cache entry\n // as \"previous\", which syncCache is about to overwrite/evict.\n if (tier > 0) {\n await ctx.syncIndexes(id, null, version)\n ctx.syncCache(id, null)\n // #729: the record lands above tier 0 — purge its tier-0-era plaintext\n // ledger deltas (irreversible; a tier-0 putAtTier(0) has nothing to purge).\n await ctx.syncLedger(id)\n // #722: recompute this record's derived outputs now that it left tier 0\n // — same law as elevate() below. `existing` is the PRE-write envelope;\n // decode it only here (the rollup edge is the only consumer). Gated by\n // `hasDerivedOutputs` — no-derivation collections skip this decrypt\n // entirely (perf regression review finding, Arc 9 #722). Whole-branch\n // review: `existing` may sit at ANY prior tier (including a\n // `putAtTier`-origin tier>0 record with no `_cek` ever minted) — decode\n // it under ITS OWN tier's DEK via `codec.decryptRecordAtDek`, not\n // `ctx.codec.decryptRecord`'s tier-unaware default, which threw\n // `TamperedError` here.\n await ctx.syncDerived(\n id,\n ctx.hasDerivedOutputs && existing\n ? await ctx.codec.decryptRecordAtDek({ collection: ctx.name, id }, existing, await ctx.getDEK(dekKey(ctx.name, existing._tier ?? 0)))\n : null,\n true,\n )\n } else {\n const rec = await ctx.codec.decryptRecord({ collection: ctx.name, id }, envelope, { sealedAsHandles: true })\n await ctx.syncIndexes(id, rec, envelope._v, existing ?? undefined)\n ctx.syncCache(id, rec !== null ? { record: rec, version: envelope._v } : null)\n // #722 Task 2: the record is written at tier 0 — restore its\n // contribution to every derived output (reuse the decode above, no\n // double-decrypt).\n await ctx.syncDerived(id, rec, false, envelope._v)\n }\n // #721: search artifacts follow the same tier > 0 → purge / tier 0 →\n // re-embed law as syncIndexes above. No ordering dependency on syncCache —\n // the _ftindex rebuild is deferred to the next retrieve() and _vec re-embed\n // reads `record` directly, not the cache. #774: a permanently stuck\n // compensation must not abort the write — the record put above already\n // landed — so it is caught and surfaced as residue instead, same as\n // elevate()/demote() (#764).\n const searchResidue = await syncSearchResilient(ctx, id, tier > 0 ? null : record, envelope._v)\n\n if (tier > 0) {\n ctx.emitCrossTierEvent({\n actor: ctx.keyring.userId,\n collection: ctx.name,\n id,\n tier,\n authorization: opts?.elevation ? 'elevation' : 'inherent',\n op: 'put',\n ts: envelope._ts,\n ...(opts?.elevation && {\n reason: opts.elevation.reason,\n elevatedFrom: opts.elevation.fromTier,\n }),\n })\n }\n\n // #712/whole-branch-fix-2: syncHistory runs LAST — after syncIndexes/\n // syncCache/syncSearch (and the cross-tier emit) have already landed. Its\n // own throw (adapter I/O, the Fix-1 assertion, the rewrap) then strands\n // only the `_history` artifact instead of leaving indexes/cache/search\n // unsynced behind an already-moved live record (would conditionally\n // reopen #709/#721/#723 on the error path). A direct putAtTier also moves\n // the record's tier — its history snapshots (if any exist from an earlier\n // tier-0 put()) must follow, same as elevate/demote. Skip when the record\n // was already at this tier (no move, nothing to rewrap). `fromKey`/\n // `fromDek` were already resolved above (review-fix-2), before the live\n // write, for the pre-move snapshot — reused here rather than recomputed.\n if (fromKey !== key) {\n await ctx.syncHistory(id, fromDek, dek)\n // #724: this putAtTier moved the record's tier — rehome its blobs too.\n await ctx.syncBlobs(id, existing?._tier ?? 0, tier)\n }\n return { searchResidue }\n}\n\n/**\n * tier-aware get. When the stored record is at a tier the caller cannot\n * decrypt:\n * - `'invisibility'` mode (default) → returns `null`.\n * - `'ghost'` mode → returns a `GhostRecord` placeholder with the tier and\n * the record id (the record exists but contents are withheld).\n *\n * Fully-cleared reads return the plaintext record and fire a cross-tier event\n * when `_tier > 0`.\n */\nexport async function getAtTier<T>(ctx: TiersContext<T>, id: string): Promise<T | GhostRecord | null> {\n assertTiersEnabled(ctx)\n const envelope = await ctx.adapter.get(ctx.vault, ctx.name, id)\n if (!envelope) return null\n const tier = envelope._tier ?? 0\n if (tier === 0) {\n return ctx.codec.decryptRecord({ collection: ctx.name, id }, envelope)\n }\n\n const key = dekKey(ctx.name, tier)\n if (!ctx.keyring.deks.has(key)) {\n if (ctx.tierMode === 'ghost') {\n return { _ghost: true, _tier: tier } as GhostRecord\n }\n return null\n }\n\n const record = await decryptElevated<T>(ctx, id, envelope, key)\n\n ctx.emitCrossTierEvent({\n actor: ctx.keyring.userId,\n collection: ctx.name,\n id,\n tier,\n authorization: isElevatorOrOwner(ctx) ? 'inherent' : 'delegation',\n op: 'get',\n ts: new Date().toISOString(),\n })\n\n return record\n}\n\n/**\n * Decrypt an ABOVE-TIER envelope under `dekKey` — the manual leg\n * {@link getAtTier} used to inline (#635/#1041). Extracted so the\n * unique-constraint tier scan (#1358) reuses exactly this key handling\n * instead of growing a second copy that could drift from it.\n *\n * A tiered record may carry a per-record CEK (e.g. a CEK record elevated via\n * `elevate()`): the CEK is wrapped under the TIER DEK, so unwrap under the\n * tier DEK then decrypt the body under the CEK. Legacy tiered records decrypt\n * directly under the tier DEK.\n *\n * This leg decrypts manually rather than through `decryptRecord`, so it must\n * build the AAD itself — from the address it fetched from plus the envelope's\n * own `_tier`/`_by`, exactly as `recordAadFor` does everywhere else (#1041).\n *\n * #635: it never went through `decryptRecord`, so it never processed\n * `_sealed` slots — an elevated classified record read back through here\n * would otherwise return the body WITHOUT its sealed fields (silent\n * omission). `applySealedSlots` takes OUR already-unwrapped `cek` (unwrapped\n * under the TIER dek) instead of resolving one under the collection DEK the\n * way `decryptRecord`/`resolveEnvelopeCek` would — which would be the wrong\n * key for a `_cek` wrapped under a tier DEK. `sealedAsHandles` is omitted\n * (default false) to match `getAtTier`'s tier-0 branch: both tiers return\n * sealed fields inline-decrypted, not as handles.\n *\n * The caller MUST have established readability first (`keyring.deks.has(key)`\n * or owner/elevator standing) — this function does not gate.\n */\nasync function decryptElevated<T>(ctx: TiersContext<T>, id: string, envelope: EncryptedEnvelope, key: string): Promise<T> {\n const dek = await ctx.getDEK(key)\n const aad = recordAadFor({ collection: ctx.name, id }, envelope)\n let plaintext: string\n let cek: EnclaveKey | undefined\n if (envelope._cek !== undefined) {\n cek = await unwrapCek(envelope._cek, dek)\n ctx.cekCache?.set(id, cek, 1)\n plaintext = await decrypt(envelope._iv, envelope._data, cek, aad)\n } else {\n plaintext = await decrypt(envelope._iv, envelope._data, dek, aad)\n }\n let record = JSON.parse(plaintext) as T\n if (envelope._sealed !== undefined) {\n record = await ctx.codec.applySealedSlots(record, envelope._sealed, cek, { id })\n }\n return record\n}\n\n/**\n * Unique-constraint enforcement across TIERS (#1358).\n *\n * The in-memory / persisted mirrors that back ordinary unique enforcement\n * hold TIER-0 records only — #709 purges an elevated record's index entries\n * precisely so elevation actually hides its field values. That is correct,\n * and it is also exactly why a tier-0 `put()` would otherwise be free to\n * re-take a value an elevated record still holds. This closes that by\n * scanning the above-tier records the writer can decrypt.\n *\n * ## The guarantee, stated exactly\n *\n * Uniqueness is enforced across **every tier whose DEK this writer holds**.\n * A tier the writer cannot read is **outside the guarantee**: those records\n * are not merely skipped-with-a-warning, they are unreadable, so no local\n * check of any design can see them. A duplicate against such a record is\n * accepted, and stays accepted. Do not describe this as \"enforced across all\n * tiers\" anywhere.\n *\n * ## Cost\n *\n * Zero for a collection with no unique index (`ctx.uniqueKeys` is undefined\n * and this returns immediately) and for one with no elevated records (the\n * scan reads envelope headers only until it meets a `_tier > 0` row it can\n * read). On a tiered collection that DOES hold both, it is a list + get per\n * write — the price of the guarantee, paid only where it was asked for.\n *\n * No cross-tier ACCESS event is emitted per scanned record: this is a\n * constraint pre-flight over material the writer is already cleared for, not\n * a read the caller asked for. The write it gates emits its own event.\n */\nexport async function checkUniqueAcrossTiers<T>(ctx: TiersContext<T>, id: string, record: T): Promise<void> {\n const keysOf = ctx.uniqueKeys\n if (!keysOf || !ctx.tiers) return\n const mine = keysOf(record)\n if (mine.length === 0) return // null-distinct exempt, or nothing declared\n\n for (const otherId of await ctx.adapter.list(ctx.vault, ctx.name)) {\n if (otherId === id || otherId.startsWith('_')) continue\n const env = await ctx.adapter.get(ctx.vault, ctx.name, otherId)\n if (!env) continue\n const tier = env._tier ?? 0\n if (tier === 0) continue // already covered by the tier-0 mirror\n const key = dekKey(ctx.name, tier)\n if (!ctx.keyring.deks.has(key)) continue // unreadable ⇒ outside the guarantee\n let other: T\n try {\n other = await decryptElevated<T>(ctx, otherId, env, key)\n } catch {\n continue // a row this writer cannot open is, for this purpose, unreadable\n }\n const theirs = new Map(keysOf(other).map(k => [`${k.fields.join('\\u0000')}\\u0000${k.key}`, k]))\n for (const k of mine) {\n if (theirs.has(`${k.fields.join('\\u0000')}\\u0000${k.key}`)) {\n throw new UniqueConstraintError(ctx.name, id, k.fields, otherId)\n }\n }\n }\n}\n\n/**\n * list ids grouped by the caller's readability. Returns only ids whose tier the\n * caller can read. Above-tier ids are omitted in `'invisibility'` mode and\n * included (with tier metadata) in `'ghost'` mode.\n */\nexport async function listAtTier<T>(ctx: TiersContext<T>): Promise<Array<{ id: string; tier: number; readable: boolean }>> {\n assertTiersEnabled(ctx)\n const ids = await ctx.adapter.list(ctx.vault, ctx.name)\n const out: Array<{ id: string; tier: number; readable: boolean }> = []\n for (const id of ids) {\n const env = await ctx.adapter.get(ctx.vault, ctx.name, id)\n if (!env) continue\n const tier = env._tier ?? 0\n const readable = tier === 0 || ctx.keyring.deks.has(dekKey(ctx.name, tier))\n if (!readable && ctx.tierMode === 'invisibility') continue\n out.push({ id, tier, readable })\n }\n return out\n}\n\n/**\n * Result of a completed `elevate()`/`demote()` (#764). The record move\n * (put + indexes/cache/ledger/derived/history/blobs sync) always completes —\n * `searchResidue: true` means only the search-index side (`_vec`/`_ftindex`)\n * was left in a needs-retry state (a stuck `PersistedIndexCompensationError`),\n * mirroring `forget()`'s `indexResidue` posture rather than aborting the move.\n */\nexport interface TierMoveResult {\n readonly searchResidue: boolean\n}\n\n/**\n * Run {@link TiersContext.syncSearch} with #764 resilience: a permanently\n * stuck compensation (`PersistedIndexCompensationError`, thrown by\n * `PersistedIndexStore` when its compensating `remove()` of a stale\n * `_ftindex` blob keeps failing) must not abort `elevate()`/`demote()` — the\n * record's tier-move `put` has already landed, and aborting here would leave\n * `syncLedger`/`syncDerived`/`syncHistory`/`syncBlobs` unsynced behind it (the\n * partial-completion hazard #764 names). Same posture `forget()` takes for\n * `_purgeSearchIndex` (`vault.ts`'s `indexResidue`) — everything else (a\n * genuinely unexpected search-hook error) still aborts, undisturbed.\n */\nasync function syncSearchResilient<T>(ctx: TiersContext<T>, id: string, record: T | null, version?: number): Promise<boolean> {\n try {\n await ctx.syncSearch(id, record, version)\n return false\n } catch (e) {\n if (e instanceof PersistedIndexCompensationError) return true\n throw e\n }\n}\n\n/**\n * elevate a record to a higher tier. Re-encrypts with the target tier's DEK.\n * The caller must hold DEKs for both the current tier (to decrypt) and the\n * target tier (to re-encrypt). Stamps `_elevatedBy` with the caller id so\n * `demote()` can check the reverse operation.\n */\nexport async function elevate<T>(ctx: TiersContext<T>, id: string, toTier: number): Promise<TierMoveResult> {\n assertTiersEnabled(ctx)\n assertDeclaredTier(ctx, toTier)\n assertTierAccess(ctx.keyring, ctx.name, toTier)\n\n const envelope = await ctx.adapter.get(ctx.vault, ctx.name, id)\n if (!envelope || isDeleteMarker(envelope) || isTombstoneShape(envelope)) {\n throw new Error(`Record \"${id}\" not found in collection \"${ctx.name}\"`)\n }\n const fromTier = envelope._tier ?? 0\n if (toTier === fromTier) return { searchResidue: false }\n if (toTier < fromTier) {\n throw new Error(`Use demote() to lower the tier of \"${id}\" from ${fromTier} to ${toTier}`)\n }\n // Caller must have access at the existing tier to decrypt.\n if (fromTier > 0) assertTierAccess(ctx.keyring, ctx.name, fromTier)\n\n const fromKey = dekKey(ctx.name, fromTier)\n const toKey = dekKey(ctx.name, toTier)\n const fromDek = await ctx.getDEK(fromKey)\n const toDek = await ctx.getDEK(toKey)\n\n // Per-record CEK composes with tiers: the body key is unchanged (history\n // chain identity preserved); only the wrapping key moves with the tier.\n // Legacy (no `_cek`) records take the direct-DEK path unchanged.\n const now = new Date().toISOString()\n const moveFrom: RecordIdentity = {\n // Opens at the version currently stored; the live write below re-seals at\n // `_v + 1`, so the two ends of a move are NOT the same identity (#1093).\n collection: ctx.name, id, version: envelope._v,\n ...(fromTier > 0 ? { tier: fromTier } : {}),\n ...(envelope._by !== undefined ? { by: envelope._by } : {}),\n }\n const moveTo: RecordIdentity = {\n collection: ctx.name, id, version: envelope._v + 1,\n ...(toTier > 0 ? { tier: toTier } : {}),\n by: ctx.keyring.userId,\n }\n const body = await rewrapBodyToDek(moveFrom, moveTo, envelope, fromDek, toDek)\n if (body.cek) ctx.cekCache?.set(id, body.cek, 1)\n // #728: snapshot the PRE-move version into `_history` before it's\n // overwritten below — reuses `body` (already fromDek→toDek) via\n // `applyRewrappedBody` (never `ctx.codec.encryptRecord`, which always\n // resolves the tier-0 DEK and would leak this body at rest whenever\n // `fromTier > 0`). Untagged (`_tier`/`_elevatedBy` stripped) so the\n // history read-gate doesn't hide it PERMANENTLY once the record demotes\n // back — at-rest protection comes from the ciphertext being under\n // `toDek`, not from the tag. `_v` stays the PRE-move version (unbumped),\n // exactly as `envelope` already carries it.\n //\n // A SECOND rewrap, not a reuse of `body` above. The live write and the\n // snapshot now land at different identities, so they need different AAD and\n // therefore different ciphertext — sharing one rewrap would produce bytes\n // that open at one address and not the other (#1041).\n await ctx.saveHistorySnapshot(id, envelope._v, async (address) => {\n const to: RecordIdentity = { ...address, ...(envelope._by !== undefined ? { by: envelope._by } : {}) }\n const histBody = await rewrapBodyToDek(moveFrom, to, envelope, fromDek, toDek)\n // eslint-disable-next-line @typescript-eslint/no-unused-vars -- excluded from ...snapshot\n const { _tier: _preTier, _elevatedBy: _preElevatedBy, ...snapshot } = applyRewrappedBody(envelope, histBody)\n return snapshot\n })\n // #662: spread every slot the source carries (_sealed/_det/_vdig/_bidx/\n // _source/_sourceTs/_debug) through UNCHANGED, then override only\n // the fields a tier move manages. rewrapBodyToDek preserves the CEK, so no\n // passenger slot is re-keyed by the move. The old field-literal dropped every\n // unlisted slot.\n // NOT a `buildRecordEnvelope` site, deliberately (#1051). This is an envelope\n // TRANSFORM, not a construction: the spread is load-bearing (#662) — it carries\n // every passenger slot (`_sealed`/`_det`/`_vdig`/`_bidx`/`_source`/`_debug`)\n // through unchanged, which a fresh literal would drop. That drop is exactly the\n // defect #1074 found in `rotateKeys`. Its body already goes through the enclave\n // (`rewrapBodyToDek`), which is where a tier move will supply AAD.\n const next: EncryptedEnvelope = {\n ...envelope,\n _noydb: NOYDB_FORMAT_VERSION,\n _v: envelope._v + 1,\n _ts: now,\n _iv: body._iv,\n _data: body._data,\n _by: ctx.keyring.userId,\n _tier: toTier,\n _elevatedBy: ctx.keyring.userId,\n ...(body._cek !== undefined ? { _cek: body._cek } : {}),\n }\n await ctx.adapter.put(ctx.vault, ctx.name, id, next)\n // Evict/purge only once the write landed — a throwing put must not blind\n // the eager cache or leave a readable index behind for a still-valid\n // tier-0 record (same ordering as demote). #709: syncIndexes runs first —\n // it needs the pre-elevation cache entry as \"previous\" to clean the\n // eager index bucket; the persisted side-car purge is content-free.\n await ctx.syncIndexes(id, null, next._v)\n ctx.syncCache(id, null)\n // #721: same purge law as syncIndexes above — the record left tier 0, so\n // its _vec sidecar is purged and _ftindex is invalidated. #764: a\n // permanently stuck compensation must not abort the move — the record put\n // above already landed — so it is caught and surfaced as residue instead.\n const searchResidue = await syncSearchResilient(ctx, id, null)\n // #729: elevate always lands the record at tier > 0 — purge its\n // tier-0-era plaintext ledger deltas (irreversible; entry metadata stays).\n await ctx.syncLedger(id)\n // #722: recompute this record's derived outputs now that it left tier 0 —\n // same law as putAtTier(tier>0) above. `envelope` is the PRE-move envelope\n // (captured before the rewrap), decoded only here (the rollup edge is the\n // only consumer of the record content). Gated by `hasDerivedOutputs` — no-\n // derivation collections skip this decrypt entirely (perf regression\n // review finding, Arc 9 #722). Whole-branch review: decode under `fromDek`\n // via `codec.decryptRecordAtDek` — `fromTier` may be > 0 here (a prior\n // elevate), and `ctx.codec.decryptRecord`'s tier-unaware CEK resolution\n // threw `TamperedError` whenever this op's own rewrap hadn't just primed\n // the cekCache (non-`perRecordKeys` collections; `_cek`-absent bodies).\n await ctx.syncDerived(id, ctx.hasDerivedOutputs ? await ctx.codec.decryptRecordAtDek({ collection: ctx.name, id }, envelope, fromDek) : null, true)\n\n ctx.emitCrossTierEvent({\n actor: ctx.keyring.userId,\n collection: ctx.name,\n id,\n tier: toTier,\n authorization: 'elevation',\n op: 'elevate',\n ts: now,\n })\n\n // #712/whole-branch-fix-2: syncHistory runs LAST — after syncIndexes/\n // syncCache/syncSearch/the cross-tier emit have already landed, so its own\n // throw (adapter I/O, the rewrap) strands only the `_history` artifact\n // instead of leaving indexes/cache/search unsynced behind an already-moved\n // live record (would conditionally reopen #709/#721/#723 on the error\n // path). Rewraps prior-version history snapshots to the SAME toTier DEK —\n // otherwise they stay decryptable at rest under fromDek forever.\n await ctx.syncHistory(id, fromDek, toDek)\n // #724: rehome any solo-owned blob attachments to the target tier's\n // `_blob` DEK — same at-rest law as syncHistory above.\n await ctx.syncBlobs(id, fromTier, toTier)\n return { searchResidue }\n}\n\n/**\n * demote a record to a lower tier. Allowed only for the user who performed the\n * last elevation or an owner.\n */\nexport async function demote<T>(ctx: TiersContext<T>, id: string, toTier: number): Promise<TierMoveResult> {\n assertTiersEnabled(ctx)\n if (toTier < 0) throw new Error(`Cannot demote to negative tier ${toTier}`)\n\n const envelope = await ctx.adapter.get(ctx.vault, ctx.name, id)\n if (!envelope || isDeleteMarker(envelope) || isTombstoneShape(envelope)) {\n throw new Error(`Record \"${id}\" not found in collection \"${ctx.name}\"`)\n }\n const fromTier = envelope._tier ?? 0\n if (toTier === fromTier) return { searchResidue: false }\n if (toTier > fromTier) {\n throw new Error(`Use elevate() to raise the tier of \"${id}\" from ${fromTier} to ${toTier}`)\n }\n const isOwner = ctx.keyring.role === 'owner'\n const isOriginalElevator = envelope._elevatedBy === ctx.keyring.userId\n if (!isOwner && !isOriginalElevator) {\n throw new TierDemoteDeniedError(id, fromTier)\n }\n // Caller must still hold the DEK of the current tier to decrypt.\n assertTierAccess(ctx.keyring, ctx.name, fromTier)\n if (toTier > 0) assertDeclaredTier(ctx, toTier)\n\n const fromDek = await ctx.getDEK(dekKey(ctx.name, fromTier))\n const toDek = await ctx.getDEK(dekKey(ctx.name, toTier))\n\n // CEK re-wrap on demote — same body key, moved from the source tier\n // DEK to the target tier DEK. Legacy records take the direct-DEK path.\n const now = new Date().toISOString()\n const moveFrom: RecordIdentity = {\n // Opens at the version currently stored; the live write below re-seals at\n // `_v + 1`, so the two ends of a move are NOT the same identity (#1093).\n collection: ctx.name, id, version: envelope._v,\n ...(fromTier > 0 ? { tier: fromTier } : {}),\n ...(envelope._by !== undefined ? { by: envelope._by } : {}),\n }\n const moveTo: RecordIdentity = {\n collection: ctx.name, id, version: envelope._v + 1,\n ...(toTier > 0 ? { tier: toTier } : {}),\n by: ctx.keyring.userId,\n }\n const body = await rewrapBodyToDek(moveFrom, moveTo, envelope, fromDek, toDek)\n if (body.cek) ctx.cekCache?.set(id, body.cek, 1)\n // #662: same passenger carry-through as elevate(). demote additionally CLEARS\n // `_elevatedBy` (the demote right is consumed) and OMITS `_tier` at tier 0, so\n // both are destructured out of the spread rather than carried.\n // eslint-disable-next-line @typescript-eslint/no-unused-vars -- excluded from ...carried\n const { _elevatedBy, _tier: _priorTier, ...carried } = envelope\n // #728: snapshot the PRE-move version into `_history` — reuses `body`\n // (already fromDek→toDek) and `carried` (envelope minus `_tier`/\n // `_elevatedBy`, computed above for the live write) via\n // `applyRewrappedBody`, so a tier-0-landing demote's snapshot is untagged\n // just like an ordinary put() entry, same law as elevate()'s snapshot\n // above. `_v` stays the PRE-move version (unbumped), as `carried` already\n // carries it.\n // A SECOND rewrap — see elevate()'s note. The snapshot's destination\n // identity differs from the live write's, so the bytes must differ too.\n await ctx.saveHistorySnapshot(id, envelope._v, async (address) => {\n const to: RecordIdentity = { ...address, ...(envelope._by !== undefined ? { by: envelope._by } : {}) }\n const histBody = await rewrapBodyToDek(moveFrom, to, envelope, fromDek, toDek)\n return applyRewrappedBody(carried, histBody)\n })\n // Transform, not construction — see the note on elevate()'s `next` above.\n const next: EncryptedEnvelope = {\n ...carried,\n _noydb: NOYDB_FORMAT_VERSION,\n _v: envelope._v + 1,\n _ts: now,\n _iv: body._iv,\n _data: body._data,\n _by: ctx.keyring.userId,\n ...(toTier > 0 ? { _tier: toTier } : {}),\n ...(body._cek !== undefined ? { _cek: body._cek } : {}),\n }\n await ctx.adapter.put(ctx.vault, ctx.name, id, next)\n\n // #691/#709: landing back at tier 0 makes this a plain tier-0 record\n // again — it must stay plain-get()-readable AND indexed in the same\n // session, so re-seed the eager cache and rebuild its index entries from\n // the just-written (now tier-0-keyed) envelope through the canonical\n // codec path, the same decode collection.ts's own eager hydration / lazy\n // cache-miss paths use — reused for both, no double-decrypt. A demote\n // that lands on an intermediate elevated tier (toTier > 0) still evicts\n // + purges: the record stays above tier 0 and must remain invisible on\n // tier-0 surfaces, unindexed. syncIndexes runs first in both branches —\n // it needs the pre-demote cache entry as \"previous\".\n // #764: a permanently stuck search-index compensation must not abort the\n // move — the record put above already landed — so it is caught in both\n // branches and surfaced as residue on the return value instead.\n let searchResidue: boolean\n if (toTier === 0) {\n const rec = await ctx.codec.decryptRecord({ collection: ctx.name, id }, next, { sealedAsHandles: true })\n await ctx.syncIndexes(id, rec, next._v, envelope)\n ctx.syncCache(id, rec !== null ? { record: rec, version: next._v } : null)\n // #721: reuse the decode above — no double-decrypt. The record is tier-0\n // again, so re-embed its _vec and invalidate _ftindex to include it.\n searchResidue = await syncSearchResilient(ctx, id, rec, next._v)\n // #722 Task 2: the record rejoined tier 0 — restore its contribution to\n // every derived output (reuse the decode above, no double-decrypt).\n await ctx.syncDerived(id, rec, false, next._v)\n } else {\n await ctx.syncIndexes(id, null, next._v)\n ctx.syncCache(id, null)\n // #721: still above tier 0 — purge _vec, invalidate _ftindex.\n searchResidue = await syncSearchResilient(ctx, id, null)\n // #722 Task 2: still elevated (an intermediate tier) — the source's\n // derived outputs stay recompute-as-removed, same law as elevate()\n // above. `envelope` is the PRE-move envelope captured at function\n // entry; decoded only here (the rollup edge is the only consumer).\n // Gated by `hasDerivedOutputs` — no-derivation collections skip this\n // decrypt entirely (perf regression review finding, Arc 9 #722).\n // Whole-branch review: decode under `fromDek` via\n // `codec.decryptRecordAtDek` — this branch's `fromTier` is always > 0 (a\n // demote FROM tier `fromTier` TO an intermediate `toTier` > 0), so\n // `ctx.codec.decryptRecord`'s tier-unaware CEK resolution threw\n // `TamperedError` here exactly as it did in elevate() above\n // (code-identical bug, same fix).\n await ctx.syncDerived(id, ctx.hasDerivedOutputs ? await ctx.codec.decryptRecordAtDek({ collection: ctx.name, id }, envelope, fromDek) : null, true)\n }\n\n ctx.emitCrossTierEvent({\n actor: ctx.keyring.userId,\n collection: ctx.name,\n id,\n tier: fromTier,\n authorization: 'elevation',\n op: 'demote',\n ts: now,\n })\n\n // #712/whole-branch-fix-2: syncHistory runs LAST — after syncIndexes/\n // syncCache/syncSearch/the cross-tier emit have already landed, so its own\n // throw (adapter I/O, the rewrap) strands only the `_history` artifact\n // instead of leaving indexes/cache/search unsynced behind an already-moved\n // live record (would conditionally reopen #709/#721/#723 on the error\n // path). Rewraps history snapshots the same direction as the live body —\n // demote restores tier-0 (or intermediate-tier) readability at rest.\n await ctx.syncHistory(id, fromDek, toDek)\n // #724: rehome any solo-owned blob attachments the same direction as the\n // live body — restores tier-0 (or intermediate-tier) readability at rest.\n await ctx.syncBlobs(id, fromTier, toTier)\n return { searchResidue }\n}\n\n/**\n * Classify a live envelope's `_sealed` slots for crypto-shred completeness\n * (#M-1). Thin delegate to {@link RecordCodec.classifySealedShred}; surfaced\n * here because `vault.ts` forget() reaches in via `collection._classifySealedShred`.\n */\nexport function classifySealedShred<T>(\n ctx: TiersContext<T>,\n live: EncryptedEnvelope,\n): Promise<{ readonly slots: readonly SealedShredSlot[] }> {\n return ctx.codec.classifySealedShred(live)\n}\n\n// #837 — classifySealedShred's slot type must be nameable from this entry.\nexport type { SealedShredSlot } from '../../kernel/enclave/index.js'\n"],"mappings":"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","names":["putAtTier","getAtTier","listAtTier","elevate","demote","checkUniqueAcrossTiers"]}
@@ -1,479 +0,0 @@
1
- import {
2
- DecryptionError,
3
- InvalidKeyError,
4
- TamperedError,
5
- ValidationError
6
- } from "./chunk-244VXYPG.js";
7
-
8
- // src/kernel/enclave/crypto.ts
9
- var PBKDF2_ITERATIONS = 6e5;
10
- var SALT_BYTES = 32;
11
- var IV_BYTES = 12;
12
- var RECOVERY_SECRET_BYTES = 32;
13
- var KEY_BITS = 256;
14
- var subtle = globalThis.crypto.subtle;
15
- async function deriveKey(secret, salt) {
16
- return deriveKekFromMaterial(new TextEncoder().encode(secret), salt);
17
- }
18
- async function deriveKekFromMaterial(material, salt) {
19
- const keyMaterial = await subtle.importKey("raw", material, "PBKDF2", false, ["deriveKey"]);
20
- return subtle.deriveKey(
21
- { name: "PBKDF2", salt, iterations: PBKDF2_ITERATIONS, hash: "SHA-256" },
22
- keyMaterial,
23
- { name: "AES-KW", length: KEY_BITS },
24
- false,
25
- ["wrapKey", "unwrapKey"]
26
- );
27
- }
28
- var ECHO_KDF_CONTEXT = new Uint8Array([255, ...new TextEncoder().encode("noydb-echo-secret-v1")]);
29
- function encodeEchoParts(parts) {
30
- for (const name of ["prompt", "echo", "key"]) {
31
- if (typeof parts?.[name] !== "string") {
32
- throw new ValidationError("echo secret parts must be three strings: prompt, echo, key");
33
- }
34
- }
35
- const enc = new TextEncoder();
36
- const segments = [parts.prompt, parts.echo, parts.key].map((p) => enc.encode(p));
37
- const total = ECHO_KDF_CONTEXT.length + segments.reduce((n, s) => n + 4 + s.length, 0);
38
- const out = new Uint8Array(total);
39
- out.set(ECHO_KDF_CONTEXT, 0);
40
- let offset = ECHO_KDF_CONTEXT.length;
41
- for (const s of segments) {
42
- new DataView(out.buffer).setUint32(offset, s.length, false);
43
- out.set(s, offset + 4);
44
- offset += 4 + s.length;
45
- }
46
- return out;
47
- }
48
- async function deriveEchoKey(parts, salt) {
49
- return deriveKekFromMaterial(encodeEchoParts(parts), salt);
50
- }
51
- async function deriveSecretKey(secret, salt, params) {
52
- const keyMaterial = await subtle.importKey(
53
- "raw",
54
- new TextEncoder().encode(secret),
55
- "PBKDF2",
56
- false,
57
- ["deriveKey"]
58
- );
59
- return params.keyUsage === "aes-gcm" ? subtle.deriveKey(
60
- {
61
- name: "PBKDF2",
62
- salt,
63
- iterations: params.iterations,
64
- hash: "SHA-256"
65
- },
66
- keyMaterial,
67
- { name: "AES-GCM", length: KEY_BITS },
68
- false,
69
- ["encrypt", "decrypt"]
70
- ) : subtle.deriveKey(
71
- {
72
- name: "PBKDF2",
73
- salt,
74
- iterations: params.iterations,
75
- hash: "SHA-256"
76
- },
77
- keyMaterial,
78
- { name: "AES-KW", length: KEY_BITS },
79
- false,
80
- ["wrapKey", "unwrapKey"]
81
- );
82
- }
83
- async function generateDEK() {
84
- return subtle.generateKey(
85
- { name: "AES-GCM", length: KEY_BITS },
86
- true,
87
- // extractable — needed for AES-KW wrapping
88
- ["encrypt", "decrypt"]
89
- );
90
- }
91
- async function exportDekSet(deks) {
92
- const out = {};
93
- for (const [coll, dek] of deks) {
94
- out[coll] = bufferToBase64(await subtle.exportKey("raw", dek));
95
- }
96
- return out;
97
- }
98
- async function importDekSet(exported) {
99
- const deks = /* @__PURE__ */ new Map();
100
- for (const [coll, b64] of Object.entries(exported)) {
101
- const key = await subtle.importKey(
102
- "raw",
103
- base64ToBuffer(b64),
104
- { name: "AES-GCM", length: KEY_BITS },
105
- true,
106
- ["encrypt", "decrypt"]
107
- );
108
- deks.set(coll, key);
109
- }
110
- return deks;
111
- }
112
- async function wrapKey(dek, kek) {
113
- const wrapped = await subtle.wrapKey("raw", dek, kek, "AES-KW");
114
- return bufferToBase64(wrapped);
115
- }
116
- async function unwrapKey(wrappedBase64, kek) {
117
- try {
118
- return await subtle.unwrapKey(
119
- "raw",
120
- base64ToBuffer(wrappedBase64),
121
- kek,
122
- "AES-KW",
123
- { name: "AES-GCM", length: KEY_BITS },
124
- true,
125
- ["encrypt", "decrypt"]
126
- );
127
- } catch {
128
- throw new InvalidKeyError();
129
- }
130
- }
131
- async function asKwKey(dek) {
132
- const rawDek = await subtle.exportKey("raw", dek);
133
- const hkdfKey = await subtle.importKey("raw", rawDek, "HKDF", false, ["deriveBits"]);
134
- const salt = new TextEncoder().encode("noydb-cek-wrap");
135
- const info = new TextEncoder().encode("v1");
136
- const bits = await subtle.deriveBits(
137
- { name: "HKDF", hash: "SHA-256", salt, info },
138
- hkdfKey,
139
- KEY_BITS
140
- );
141
- return subtle.importKey("raw", bits, "AES-KW", false, ["wrapKey", "unwrapKey"]);
142
- }
143
- async function wrapCek(cek, dek) {
144
- const kw = await asKwKey(dek);
145
- const wrapped = await subtle.wrapKey("raw", cek, kw, "AES-KW");
146
- return bufferToBase64(wrapped);
147
- }
148
- async function unwrapCek(wrappedBase64, dek) {
149
- const kw = await asKwKey(dek);
150
- try {
151
- return await subtle.unwrapKey(
152
- "raw",
153
- base64ToBuffer(wrappedBase64),
154
- kw,
155
- "AES-KW",
156
- { name: "AES-GCM", length: KEY_BITS },
157
- true,
158
- ["encrypt", "decrypt"]
159
- );
160
- } catch {
161
- throw new InvalidKeyError();
162
- }
163
- }
164
- async function importCek(rawKey) {
165
- return subtle.importKey("raw", rawKey, { name: "AES-GCM", length: KEY_BITS }, false, ["decrypt"]);
166
- }
167
- async function encrypt(plaintext, dek, aad) {
168
- const iv = generateIV();
169
- const encoded = new TextEncoder().encode(plaintext);
170
- const ciphertext = await subtle.encrypt(
171
- {
172
- name: "AES-GCM",
173
- iv,
174
- ...aad !== void 0 && { additionalData: aad }
175
- },
176
- dek,
177
- encoded
178
- );
179
- return {
180
- iv: bufferToBase64(iv),
181
- data: bufferToBase64(ciphertext)
182
- };
183
- }
184
- async function decrypt(ivBase64, dataBase64, dek, aad) {
185
- const iv = base64ToBuffer(ivBase64);
186
- const ciphertext = base64ToBuffer(dataBase64);
187
- try {
188
- const plaintext = await subtle.decrypt(
189
- {
190
- name: "AES-GCM",
191
- iv,
192
- ...aad !== void 0 && { additionalData: aad }
193
- },
194
- dek,
195
- ciphertext
196
- );
197
- return new TextDecoder().decode(plaintext);
198
- } catch (err) {
199
- if (err instanceof Error && err.name === "OperationError") {
200
- throw new TamperedError(...await classifyTagFailure(iv, ciphertext, dek, aad));
201
- }
202
- throw new DecryptionError(
203
- err instanceof Error ? err.message : "Decryption failed"
204
- );
205
- }
206
- }
207
- async function classifyTagFailure(iv, ciphertext, dek, aad) {
208
- if (aad === void 0) return [];
209
- try {
210
- await subtle.decrypt({ name: "AES-GCM", iv }, dek, ciphertext);
211
- } catch {
212
- return [];
213
- }
214
- return [
215
- "This record was sealed BEFORE record-identity binding (#1041) and cannot be read by this version. Its body decrypts correctly under the record key, so this is a data-format transition, not tampering \u2014 but it also means the record predates authenticated metadata. There is no migration path; see noy-db #1100.",
216
- "unbound-legacy-format"
217
- ];
218
- }
219
- async function encryptBytes(data, dek) {
220
- const iv = generateIV();
221
- const ciphertext = await subtle.encrypt(
222
- { name: "AES-GCM", iv },
223
- dek,
224
- data
225
- );
226
- return {
227
- iv: bufferToBase64(iv),
228
- data: bufferToBase64(ciphertext)
229
- };
230
- }
231
- async function decryptBytes(ivBase64, dataBase64, dek) {
232
- const iv = base64ToBuffer(ivBase64);
233
- const ciphertext = base64ToBuffer(dataBase64);
234
- try {
235
- const plaintext = await subtle.decrypt(
236
- { name: "AES-GCM", iv },
237
- dek,
238
- ciphertext
239
- );
240
- return new Uint8Array(plaintext);
241
- } catch (err) {
242
- if (err instanceof Error && err.name === "OperationError") {
243
- throw new TamperedError();
244
- }
245
- throw new DecryptionError(
246
- err instanceof Error ? err.message : "Decryption failed"
247
- );
248
- }
249
- }
250
- async function sha256Hex(data) {
251
- const hash = await subtle.digest("SHA-256", data);
252
- return Array.from(new Uint8Array(hash)).map((b) => b.toString(16).padStart(2, "0")).join("");
253
- }
254
- async function deriveBlobAddressKey(root, tier) {
255
- const rawRoot = await subtle.exportKey("raw", root);
256
- const hkdfKey = await subtle.importKey("raw", rawRoot, "HKDF", false, ["deriveBits"]);
257
- const salt = new TextEncoder().encode("noydb-blob-address");
258
- const info = new TextEncoder().encode(`tier:${tier}`);
259
- const bits = await subtle.deriveBits({ name: "HKDF", hash: "SHA-256", salt, info }, hkdfKey, KEY_BITS);
260
- return subtle.importKey("raw", bits, { name: "AES-GCM" }, true, ["encrypt", "decrypt"]);
261
- }
262
- async function hmacSha256Hex(key, data) {
263
- const rawKey = await subtle.exportKey("raw", key);
264
- const hmacKey = await subtle.importKey(
265
- "raw",
266
- rawKey,
267
- { name: "HMAC", hash: "SHA-256" },
268
- false,
269
- ["sign"]
270
- );
271
- const sig = await subtle.sign("HMAC", hmacKey, data);
272
- return Array.from(new Uint8Array(sig)).map((b) => b.toString(16).padStart(2, "0")).join("");
273
- }
274
- async function encryptBytesWithAAD(data, dek, aad) {
275
- const iv = generateIV();
276
- const ciphertext = await subtle.encrypt(
277
- {
278
- name: "AES-GCM",
279
- iv,
280
- additionalData: aad
281
- },
282
- dek,
283
- data
284
- );
285
- return {
286
- iv: bufferToBase64(iv),
287
- data: bufferToBase64(ciphertext)
288
- };
289
- }
290
- async function decryptBytesWithAAD(ivBase64, dataBase64, dek, aad) {
291
- const iv = base64ToBuffer(ivBase64);
292
- const ciphertext = base64ToBuffer(dataBase64);
293
- try {
294
- const plaintext = await subtle.decrypt(
295
- {
296
- name: "AES-GCM",
297
- iv,
298
- additionalData: aad
299
- },
300
- dek,
301
- ciphertext
302
- );
303
- return new Uint8Array(plaintext);
304
- } catch (err) {
305
- if (err instanceof Error && err.name === "OperationError") {
306
- throw new TamperedError();
307
- }
308
- throw new DecryptionError(
309
- err instanceof Error ? err.message : "Decryption failed"
310
- );
311
- }
312
- }
313
- async function derivePresenceKey(dek, collectionName) {
314
- const rawDek = await subtle.exportKey("raw", dek);
315
- const hkdfKey = await subtle.importKey(
316
- "raw",
317
- rawDek,
318
- "HKDF",
319
- false,
320
- ["deriveBits"]
321
- );
322
- const salt = new TextEncoder().encode("noydb-presence");
323
- const info = new TextEncoder().encode(collectionName);
324
- const bits = await subtle.deriveBits(
325
- { name: "HKDF", hash: "SHA-256", salt, info },
326
- hkdfKey,
327
- KEY_BITS
328
- );
329
- return subtle.importKey(
330
- "raw",
331
- bits,
332
- { name: "AES-GCM", length: KEY_BITS },
333
- false,
334
- ["encrypt", "decrypt"]
335
- );
336
- }
337
- async function deriveSealedFieldKey(dek, collectionName, field) {
338
- const rawDek = await subtle.exportKey("raw", dek);
339
- const hkdfKey = await subtle.importKey("raw", rawDek, "HKDF", false, ["deriveBits"]);
340
- const salt = new TextEncoder().encode("noydb-sealed");
341
- const info = new TextEncoder().encode(JSON.stringify(["noydb-sealed", collectionName, field]));
342
- const bits = await subtle.deriveBits(
343
- { name: "HKDF", hash: "SHA-256", salt, info },
344
- hkdfKey,
345
- KEY_BITS
346
- );
347
- return subtle.importKey(
348
- "raw",
349
- bits,
350
- { name: "AES-GCM", length: KEY_BITS },
351
- false,
352
- ["encrypt", "decrypt"]
353
- );
354
- }
355
- async function deriveSealedFieldKeyFromCek(cek, collectionName, field) {
356
- const rawCek = await subtle.exportKey("raw", cek);
357
- const hkdfKey = await subtle.importKey("raw", rawCek, "HKDF", false, ["deriveBits"]);
358
- const salt = new TextEncoder().encode("noydb-sealed-cek");
359
- const info = new TextEncoder().encode(JSON.stringify(["noydb-sealed-cek", collectionName, field]));
360
- const bits = await subtle.deriveBits(
361
- { name: "HKDF", hash: "SHA-256", salt, info },
362
- hkdfKey,
363
- KEY_BITS
364
- );
365
- return subtle.importKey(
366
- "raw",
367
- bits,
368
- { name: "AES-GCM", length: KEY_BITS },
369
- false,
370
- ["encrypt", "decrypt"]
371
- );
372
- }
373
- async function deriveDeterministicKey(dek) {
374
- const rawDek = await subtle.exportKey("raw", dek);
375
- const hkdfKey = await subtle.importKey("raw", rawDek, "HKDF", false, ["deriveBits"]);
376
- const salt = new TextEncoder().encode("noydb-det");
377
- const info = new TextEncoder().encode(JSON.stringify(["noydb-det"]));
378
- const bits = await subtle.deriveBits(
379
- { name: "HKDF", hash: "SHA-256", salt, info },
380
- hkdfKey,
381
- KEY_BITS
382
- );
383
- return subtle.importKey(
384
- "raw",
385
- bits,
386
- { name: "AES-GCM", length: KEY_BITS },
387
- true,
388
- ["encrypt", "decrypt"]
389
- );
390
- }
391
- async function deriveDeterministicIV(dek, context, plaintext) {
392
- const rawDek = await subtle.exportKey("raw", dek);
393
- const hkdfKey = await subtle.importKey("raw", rawDek, "HKDF", false, ["deriveBits"]);
394
- const salt = new TextEncoder().encode("noydb-deterministic-v1");
395
- const info = new TextEncoder().encode(`${context}\0${plaintext}`);
396
- const bits = await subtle.deriveBits(
397
- { name: "HKDF", hash: "SHA-256", salt, info },
398
- hkdfKey,
399
- IV_BYTES * 8
400
- );
401
- return new Uint8Array(bits);
402
- }
403
- async function encryptDeterministic(plaintext, dek, context) {
404
- const iv = await deriveDeterministicIV(dek, context, plaintext);
405
- const encoded = new TextEncoder().encode(plaintext);
406
- const ciphertext = await subtle.encrypt(
407
- { name: "AES-GCM", iv },
408
- dek,
409
- encoded
410
- );
411
- return {
412
- iv: bufferToBase64(iv),
413
- data: bufferToBase64(ciphertext)
414
- };
415
- }
416
- async function decryptDeterministic(ivBase64, dataBase64, dek) {
417
- return decrypt(ivBase64, dataBase64, dek);
418
- }
419
- function generateIV() {
420
- return globalThis.crypto.getRandomValues(new Uint8Array(IV_BYTES));
421
- }
422
- function generateSalt() {
423
- return globalThis.crypto.getRandomValues(new Uint8Array(SALT_BYTES));
424
- }
425
- function generateRecoverySecret() {
426
- return globalThis.crypto.getRandomValues(new Uint8Array(RECOVERY_SECRET_BYTES));
427
- }
428
- function bufferToBase64(buffer) {
429
- const bytes = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer);
430
- let binary = "";
431
- for (let i = 0; i < bytes.length; i++) {
432
- binary += String.fromCharCode(bytes[i]);
433
- }
434
- return btoa(binary);
435
- }
436
- function base64ToBuffer(base64) {
437
- const binary = atob(base64);
438
- const bytes = new Uint8Array(binary.length);
439
- for (let i = 0; i < binary.length; i++) {
440
- bytes[i] = binary.charCodeAt(i);
441
- }
442
- return bytes;
443
- }
444
-
445
- export {
446
- deriveKey,
447
- encodeEchoParts,
448
- deriveEchoKey,
449
- deriveSecretKey,
450
- generateDEK,
451
- exportDekSet,
452
- importDekSet,
453
- wrapKey,
454
- unwrapKey,
455
- wrapCek,
456
- unwrapCek,
457
- importCek,
458
- encrypt,
459
- decrypt,
460
- encryptBytes,
461
- decryptBytes,
462
- sha256Hex,
463
- deriveBlobAddressKey,
464
- hmacSha256Hex,
465
- encryptBytesWithAAD,
466
- decryptBytesWithAAD,
467
- derivePresenceKey,
468
- deriveSealedFieldKey,
469
- deriveSealedFieldKeyFromCek,
470
- deriveDeterministicKey,
471
- encryptDeterministic,
472
- decryptDeterministic,
473
- generateIV,
474
- generateSalt,
475
- generateRecoverySecret,
476
- bufferToBase64,
477
- base64ToBuffer
478
- };
479
- //# sourceMappingURL=chunk-UYB234ZR.js.map