@noy-db/hub 0.10.0-pre.1 → 0.10.0-pre.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (482) hide show
  1. package/CHANGELOG.md +81 -0
  2. package/dist/api-QSEKT4KS.js +15 -0
  3. package/dist/as/index.js +19 -12
  4. package/dist/as/index.js.map +1 -1
  5. package/dist/at/index.js +6 -9
  6. package/dist/attestation/index.js +16 -19
  7. package/dist/attestation/index.js.map +1 -1
  8. package/dist/{backup-6EKBNC67.js → backup-BHKVK5SD.js} +9 -12
  9. package/dist/{backup-6EKBNC67.js.map → backup-BHKVK5SD.js.map} +1 -1
  10. package/dist/blobs/index.js +10 -13
  11. package/dist/blobs/index.js.map +1 -1
  12. package/dist/broker/index.js +11 -14
  13. package/dist/broker/index.js.map +1 -1
  14. package/dist/by/index.js +2 -2
  15. package/dist/capsule/contract.d.ts +176 -16
  16. package/dist/capsule/contract.js +35 -30
  17. package/dist/capsule/enclave-aes/bound.d.ts +11 -1
  18. package/dist/capsule/enclave-aes/classify/digest.d.ts +4 -2
  19. package/dist/capsule/enclave-aes/index.d.ts +9 -0
  20. package/dist/capsule/enclave-aes/index.js +643 -78
  21. package/dist/capsule/enclave-aes/index.js.map +1 -1
  22. package/dist/capsule/enclave-aes/primitives.d.ts +2 -2
  23. package/dist/capsule/index.d.ts +1 -1
  24. package/dist/capsule/plumbing/classify-reveal.d.ts +29 -0
  25. package/dist/capsule/plumbing/classify-verify.d.ts +53 -0
  26. package/dist/capsule/plumbing/index.d.ts +17 -0
  27. package/dist/{capsule-QJJFUUSH.js → capsule-YAITMH77.js} +16 -9
  28. package/dist/cargo/index.js +34 -36
  29. package/dist/{chunk-J57OMNJ4.js → chunk-23A4SBRR.js} +3 -4
  30. package/dist/{chunk-J57OMNJ4.js.map → chunk-23A4SBRR.js.map} +1 -1
  31. package/dist/{chunk-E3CUGBGW.js → chunk-24AGG4PP.js} +3 -3
  32. package/dist/{chunk-M2VLXPRU.js → chunk-24IJZA4M.js} +14 -8
  33. package/dist/chunk-24IJZA4M.js.map +1 -0
  34. package/dist/{chunk-BCJAUHSG.js → chunk-2NVQ5SEA.js} +15 -5
  35. package/dist/chunk-2NVQ5SEA.js.map +1 -0
  36. package/dist/{chunk-MRVQKRXI.js → chunk-2SIREKBR.js} +2 -2
  37. package/dist/{chunk-CE443VXM.js → chunk-37FOG6AE.js} +14 -7
  38. package/dist/chunk-37FOG6AE.js.map +1 -0
  39. package/dist/{chunk-ZZZVNHN2.js → chunk-3M2KK7O7.js} +3 -3
  40. package/dist/{chunk-P6FATPXQ.js → chunk-3ZCVY3T6.js} +2 -2
  41. package/dist/{chunk-I7NDTNHK.js → chunk-4CGWLHPQ.js} +6 -6
  42. package/dist/{chunk-PVQIME6P.js → chunk-56Z4NOC6.js} +3 -3
  43. package/dist/{chunk-XBG6YJPK.js → chunk-5AVIUJP4.js} +11 -9
  44. package/dist/{chunk-XBG6YJPK.js.map → chunk-5AVIUJP4.js.map} +1 -1
  45. package/dist/{chunk-HQFTE3DX.js → chunk-5BGHAVBN.js} +2 -2
  46. package/dist/{chunk-QHG7GQKM.js → chunk-5JNEDW7I.js} +2 -2
  47. package/dist/{chunk-NC6CF37L.js → chunk-5OWJSDTO.js} +4 -4
  48. package/dist/{chunk-NC6CF37L.js.map → chunk-5OWJSDTO.js.map} +1 -1
  49. package/dist/{chunk-YAYDDYRU.js → chunk-5Y4MO7UQ.js} +4 -4
  50. package/dist/{chunk-TLIFNRU5.js → chunk-63LZLRWG.js} +2 -2
  51. package/dist/{chunk-BUFFPAR2.js → chunk-74W56QPY.js} +4 -4
  52. package/dist/{chunk-VPG2UJYR.js → chunk-7KNYLHVX.js} +3 -3
  53. package/dist/chunk-7KNYLHVX.js.map +1 -0
  54. package/dist/{chunk-LFUID7OW.js → chunk-7VJ2SIEI.js} +42 -22
  55. package/dist/chunk-7VJ2SIEI.js.map +1 -0
  56. package/dist/{chunk-U2N7DH4S.js → chunk-AHA7UALU.js} +4 -4
  57. package/dist/{chunk-NB2DYYZL.js → chunk-AIHBYQHF.js} +254 -118
  58. package/dist/chunk-AIHBYQHF.js.map +1 -0
  59. package/dist/{chunk-RNQ7V4LH.js → chunk-ANYX2M6P.js} +3 -3
  60. package/dist/{chunk-VFGLMRO2.js → chunk-ATKYMRBC.js} +4 -4
  61. package/dist/{chunk-7UHLO4ZN.js → chunk-B2HU55QD.js} +2 -2
  62. package/dist/{chunk-RKOXA5GZ.js → chunk-BEKMLYQ4.js} +4 -4
  63. package/dist/{chunk-AYUMAPOS.js → chunk-BPFXD4EX.js} +23 -3
  64. package/dist/chunk-BPFXD4EX.js.map +1 -0
  65. package/dist/{chunk-R4PDYYK5.js → chunk-C2NXAR3D.js} +5 -5
  66. package/dist/{chunk-XBOGGTUJ.js → chunk-CJBWJO5P.js} +6 -6
  67. package/dist/{chunk-XBOGGTUJ.js.map → chunk-CJBWJO5P.js.map} +1 -1
  68. package/dist/{chunk-44CU4N7N.js → chunk-CQLMRCKX.js} +2 -2
  69. package/dist/{chunk-VUBRHJ4H.js → chunk-CR5UPYIJ.js} +1 -1
  70. package/dist/chunk-CR5UPYIJ.js.map +1 -0
  71. package/dist/{chunk-4XXRPSPS.js → chunk-DS2JXSUA.js} +6 -6
  72. package/dist/{chunk-X6Z2SIRF.js → chunk-E2JIE4S3.js} +2 -2
  73. package/dist/{chunk-EQ6C2ZPT.js → chunk-E7Y4J4GL.js} +2 -2
  74. package/dist/{chunk-ZMDSBTFT.js → chunk-ECDM6YRX.js} +2 -2
  75. package/dist/{chunk-WRLWEYHY.js → chunk-EFINFZIF.js} +11 -1
  76. package/dist/chunk-EFINFZIF.js.map +1 -0
  77. package/dist/{chunk-JM72WDAY.js → chunk-EM56MHN5.js} +6 -6
  78. package/dist/{chunk-YWJMM2WY.js → chunk-EQXOJH6O.js} +4 -4
  79. package/dist/{chunk-ME6LY5UG.js → chunk-ET3U2C3A.js} +2 -2
  80. package/dist/{chunk-G2KLVCKO.js → chunk-EU4G7PQH.js} +2 -2
  81. package/dist/{chunk-WJXLTO43.js → chunk-EUCUYK5E.js} +10 -10
  82. package/dist/{chunk-EPMX3SCC.js → chunk-EWSIJDWO.js} +4 -4
  83. package/dist/{chunk-KFYUQMF5.js → chunk-F2FD4LSB.js} +2 -2
  84. package/dist/{chunk-L4UL4IAR.js → chunk-F7ENMZYJ.js} +2 -2
  85. package/dist/{chunk-5OG7YQX5.js → chunk-FIIVYQOW.js} +5 -5
  86. package/dist/{chunk-4RF7DVH2.js → chunk-FPK2LPLR.js} +8 -8
  87. package/dist/chunk-FPK2LPLR.js.map +1 -0
  88. package/dist/{chunk-2EF2Z4UN.js → chunk-FQEUJGBV.js} +2 -2
  89. package/dist/{chunk-UORWAG7K.js → chunk-FY4FFNKK.js} +2 -2
  90. package/dist/{chunk-WA4ZPMKP.js → chunk-GDCYZGPB.js} +2 -2
  91. package/dist/{chunk-3HDBDUX2.js → chunk-H6Q7GKLI.js} +2 -2
  92. package/dist/{chunk-654RE5YC.js → chunk-HDAPQF6Q.js} +3 -3
  93. package/dist/{chunk-B5PWQMZN.js → chunk-HRLMUZLI.js} +5 -5
  94. package/dist/{chunk-QWC2PRUR.js → chunk-HRNQYGLQ.js} +2 -2
  95. package/dist/{chunk-YIVAKBCW.js → chunk-I4S7IZSS.js} +321 -235
  96. package/dist/chunk-I4S7IZSS.js.map +1 -0
  97. package/dist/{chunk-7DWAYY45.js → chunk-IN4XZJYD.js} +4 -3
  98. package/dist/{chunk-7DWAYY45.js.map → chunk-IN4XZJYD.js.map} +1 -1
  99. package/dist/{chunk-JGYCKX56.js → chunk-ISIXU45J.js} +1 -1
  100. package/dist/{chunk-JGYCKX56.js.map → chunk-ISIXU45J.js.map} +1 -1
  101. package/dist/{chunk-7PFOKQOJ.js → chunk-J4L4AS2W.js} +2 -2
  102. package/dist/{chunk-PZZWAHEJ.js → chunk-JPSOFWJR.js} +2 -2
  103. package/dist/{chunk-B24ODIKE.js → chunk-JRCO67NG.js} +2 -2
  104. package/dist/{chunk-PNEBCVXP.js → chunk-JW3I3NNZ.js} +2 -2
  105. package/dist/{chunk-MXNYMFHE.js → chunk-JZMPSQBH.js} +4 -4
  106. package/dist/{chunk-IIQMNZXT.js → chunk-K5TVSOPQ.js} +5 -5
  107. package/dist/{chunk-ZPXCQNXJ.js → chunk-K75SL74I.js} +2 -2
  108. package/dist/{chunk-TA5VTIC4.js → chunk-KA4AAUST.js} +2 -2
  109. package/dist/chunk-KHSBMLQE.js +161 -0
  110. package/dist/chunk-KHSBMLQE.js.map +1 -0
  111. package/dist/{chunk-JWLVBYP4.js → chunk-KUGUML7H.js} +3 -3
  112. package/dist/{chunk-GWYZEPBY.js → chunk-L4J5NC2Q.js} +2 -2
  113. package/dist/{chunk-PIF3TNU2.js → chunk-LIX4QPMM.js} +2 -2
  114. package/dist/{chunk-LCY6ANV2.js → chunk-LWQFGR34.js} +3 -3
  115. package/dist/{chunk-HQPS27BT.js → chunk-MMSSHMHW.js} +2 -2
  116. package/dist/{chunk-T5EXREMW.js → chunk-N25Z6PR4.js} +6 -5
  117. package/dist/chunk-N25Z6PR4.js.map +1 -0
  118. package/dist/{chunk-ND6S2DKC.js → chunk-N5S2BCW3.js} +2 -2
  119. package/dist/{chunk-63INIVE4.js → chunk-NIZH2TYZ.js} +2 -2
  120. package/dist/{chunk-WQHEEYQA.js → chunk-NLDBQHDV.js} +2 -2
  121. package/dist/{chunk-SKSHWV3E.js → chunk-NQQ4MOPC.js} +4 -4
  122. package/dist/{chunk-B6EWMGFX.js → chunk-NUBI6PYH.js} +2 -2
  123. package/dist/{chunk-VWUSOPBF.js → chunk-NYEXUZDW.js} +4 -4
  124. package/dist/{chunk-GU6QXHPZ.js → chunk-OIBFIWVJ.js} +4 -4
  125. package/dist/chunk-OIBFIWVJ.js.map +1 -0
  126. package/dist/{chunk-PIEX7WSG.js → chunk-OOLF5FU2.js} +2 -2
  127. package/dist/{chunk-HOK5KGBO.js → chunk-OQA7UF2Q.js} +3 -3
  128. package/dist/{chunk-JMMG7UWR.js → chunk-ORJPICJI.js} +2 -2
  129. package/dist/{chunk-IF2M43G4.js → chunk-PBRD75JF.js} +2 -2
  130. package/dist/{chunk-X7Q2XL5U.js → chunk-PDCBL23X.js} +39 -17
  131. package/dist/chunk-PDCBL23X.js.map +1 -0
  132. package/dist/{chunk-PR2R57YF.js → chunk-PR36DD2X.js} +7 -7
  133. package/dist/{chunk-LFCX2JAV.js → chunk-PV4HIC4E.js} +2 -2
  134. package/dist/{chunk-SKF3DF7M.js → chunk-PZNK4HTV.js} +3 -3
  135. package/dist/{chunk-5F3KYRG6.js → chunk-QBLPLNPE.js} +3 -3
  136. package/dist/{chunk-4ZRNXWF6.js → chunk-QZXUISRF.js} +5 -5
  137. package/dist/{chunk-7Q72NTBE.js → chunk-RBXYO7MD.js} +5 -5
  138. package/dist/{chunk-S2BQV6HM.js → chunk-RIACRFWA.js} +4 -4
  139. package/dist/{chunk-DO33YCSZ.js → chunk-RL6RNDJQ.js} +8 -8
  140. package/dist/{chunk-2SPWVX6W.js → chunk-SJ2P7UXD.js} +7 -7
  141. package/dist/{chunk-26FMWFAW.js → chunk-SWXS4LV3.js} +11 -11
  142. package/dist/{chunk-J3ECXFU7.js → chunk-TOTCZFRF.js} +2 -2
  143. package/dist/{chunk-AN4GUUQM.js → chunk-TT4D52EK.js} +6 -6
  144. package/dist/{chunk-KOJHCSGS.js → chunk-U7CMJY5P.js} +10 -10
  145. package/dist/{chunk-DDR6SCG7.js → chunk-UNKTZDA2.js} +11 -11
  146. package/dist/{chunk-DDR6SCG7.js.map → chunk-UNKTZDA2.js.map} +1 -1
  147. package/dist/{chunk-WVML7HUZ.js → chunk-UXH4AKH3.js} +95 -151
  148. package/dist/chunk-UXH4AKH3.js.map +1 -0
  149. package/dist/{chunk-MKQHIYUY.js → chunk-UZVHSYIF.js} +2 -2
  150. package/dist/{chunk-FDGE56FS.js → chunk-VHKAW5OI.js} +29 -5
  151. package/dist/chunk-VHKAW5OI.js.map +1 -0
  152. package/dist/{chunk-OCSKQUNE.js → chunk-VKZ3TDET.js} +3 -3
  153. package/dist/{chunk-ESDYDGPH.js → chunk-VLZPUG5A.js} +4 -4
  154. package/dist/{chunk-PCYIDPFM.js → chunk-VSN5FLMI.js} +2 -2
  155. package/dist/{chunk-S4QDN4IQ.js → chunk-VYBBE7RN.js} +5 -5
  156. package/dist/{chunk-XBFJRCRW.js → chunk-WHK4JVKF.js} +8 -8
  157. package/dist/{chunk-CZEWEOOV.js → chunk-X4LDBALX.js} +2 -2
  158. package/dist/{chunk-YWEPWJRG.js → chunk-X67E7NIJ.js} +3 -3
  159. package/dist/{chunk-RRI3JBD6.js → chunk-XMARKBUC.js} +3 -3
  160. package/dist/{chunk-B3B6HV5S.js → chunk-XMBBTETD.js} +2 -2
  161. package/dist/{chunk-GQ4MF3CM.js → chunk-XMBTAN5E.js} +28 -14
  162. package/dist/chunk-XMBTAN5E.js.map +1 -0
  163. package/dist/{chunk-GEICXZCQ.js → chunk-XROQP6IQ.js} +4 -4
  164. package/dist/chunk-XWWDZKLS.js +196 -0
  165. package/dist/chunk-XWWDZKLS.js.map +1 -0
  166. package/dist/{chunk-VX72USUQ.js → chunk-Y2RYUWSQ.js} +10 -10
  167. package/dist/{chunk-6I5RRBPP.js → chunk-YCTSQV7K.js} +5 -5
  168. package/dist/{chunk-7WV6R7RG.js → chunk-YF7P2DG7.js} +2 -2
  169. package/dist/{chunk-ZZLIFVZG.js → chunk-ZG7DBIVX.js} +2 -2
  170. package/dist/{chunk-Y6WJJRVV.js → chunk-ZGJ775X7.js} +2 -2
  171. package/dist/{chunk-PQGCWTTI.js → chunk-ZQQLOEWN.js} +3 -3
  172. package/dist/classified/index.js +5 -5
  173. package/dist/{classified-marker-LY7KQFPH.js → classified-marker-HKMRC7SC.js} +3 -3
  174. package/dist/{reveal-LK3GX4L6.js → classify-reveal-YSJKJEIR.js} +7 -12
  175. package/dist/classify-reveal-YSJKJEIR.js.map +1 -0
  176. package/dist/{verify-FT5COLP2.js → classify-verify-ZCTKYQ43.js} +31 -41
  177. package/dist/classify-verify-ZCTKYQ43.js.map +1 -0
  178. package/dist/collection-facade-PPKNUR2J.js +38 -0
  179. package/dist/{computed-XG7LFB7A.js → computed-UCYVPMZA.js} +3 -3
  180. package/dist/consent/index.js +6 -9
  181. package/dist/consent/index.js.map +1 -1
  182. package/dist/cover/index.js +6 -9
  183. package/dist/custody/index.js +11 -13
  184. package/dist/{dead-filter-F4EKHDQY.js → dead-filter-YOBWRG4O.js} +8 -11
  185. package/dist/{dead-filter-F4EKHDQY.js.map → dead-filter-YOBWRG4O.js.map} +1 -1
  186. package/dist/debug/index.js +5 -8
  187. package/dist/debug/index.js.map +1 -1
  188. package/dist/delegation-SNALWRMO.js +24 -0
  189. package/dist/derivations/index.js +20 -23
  190. package/dist/derive-4GNU4E4I.js +17 -0
  191. package/dist/directory/index.js +7 -10
  192. package/dist/{dispatch-YNHZLB72.js → dispatch-QW32QBLW.js} +17 -20
  193. package/dist/{dispatch-YNHZLB72.js.map → dispatch-QW32QBLW.js.map} +1 -1
  194. package/dist/{dispatch-URNW4Q2T.js → dispatch-V5WLDTVX.js} +5 -5
  195. package/dist/executor-7QN22OKI.js +8 -0
  196. package/dist/executor-BJZJNVBB.js +8 -0
  197. package/dist/executor-JEAAEJUM.js +32 -0
  198. package/dist/export-accessible-TVO2KQPG.js +20 -0
  199. package/dist/extract-partition-43CLDRN4.js +33 -0
  200. package/dist/{fanout-sidecar-6CSMTIVB.js → fanout-sidecar-DDONAFJT.js} +6 -9
  201. package/dist/{fanout-sidecar-6CSMTIVB.js.map → fanout-sidecar-DDONAFJT.js.map} +1 -1
  202. package/dist/forget/index.js +6 -9
  203. package/dist/forget/index.js.map +1 -1
  204. package/dist/guards/index.js +4 -4
  205. package/dist/history/index.js +11 -14
  206. package/dist/history/index.js.map +1 -1
  207. package/dist/i18n/index.js +11 -14
  208. package/dist/i18n/index.js.map +1 -1
  209. package/dist/index.d.ts +2 -2
  210. package/dist/index.js +122 -123
  211. package/dist/index.js.map +1 -1
  212. package/dist/indexing/index.js +5 -5
  213. package/dist/introspection/index.js +8 -11
  214. package/dist/issue-EIHEDAXM.js +16 -0
  215. package/dist/kernel/capsule-requirements.d.ts +84 -0
  216. package/dist/kernel/errors.d.ts +15 -0
  217. package/dist/kernel/export-scope.d.ts +28 -1
  218. package/dist/kernel/store-segment-guard.d.ts +29 -0
  219. package/dist/kernel/types.d.ts +164 -8
  220. package/dist/kernel/validation.d.ts +32 -0
  221. package/dist/kernel/vault.d.ts +3 -3
  222. package/dist/{ledger-FV6NFTOR.js → ledger-BMVUFQ3R.js} +8 -11
  223. package/dist/liberate-7KHXCLNJ.js +23 -0
  224. package/dist/link-set-PC2EJRKL.js +26 -0
  225. package/dist/{managed-secret-PBJZHPQO.js → managed-secret-RPRVEYZA.js} +7 -10
  226. package/dist/materialized-views/index.js +23 -26
  227. package/dist/{migrate-cek-J634S4NU.js → migrate-cek-DTSCWGEF.js} +2 -2
  228. package/dist/money/index.js +5 -5
  229. package/dist/noydb-AYDNOXAX.js +98 -0
  230. package/dist/on/index.js +11 -13
  231. package/dist/overlay-views/index.js +4 -4
  232. package/dist/periods/index.js +9 -12
  233. package/dist/pod/index.js +65 -67
  234. package/dist/{pod-handle-IOEYUDCA.js → pod-handle-KBPQRN6Q.js} +6 -9
  235. package/dist/{pod-handle-IOEYUDCA.js.map → pod-handle-KBPQRN6Q.js.map} +1 -1
  236. package/dist/policy/index.js +7 -10
  237. package/dist/port/at/index.d.ts +1 -0
  238. package/dist/port/with/collection-registries.d.ts +37 -0
  239. package/dist/portability/index.js +8 -8
  240. package/dist/{post-register-L42VXYFB.js → post-register-RITSNASO.js} +6 -6
  241. package/dist/query/all/index.js +15 -15
  242. package/dist/query/index.js +7 -7
  243. package/dist/query/live/index.js +7 -7
  244. package/dist/query/reduce/index.js +10 -10
  245. package/dist/query/relate/index.js +9 -9
  246. package/dist/reduce/index.js +8 -8
  247. package/dist/register-BB34SK7E.js +27 -0
  248. package/dist/registry-65L6V5TO.js +20 -0
  249. package/dist/registry-HU62GPWA.js +32 -0
  250. package/dist/registry-SMNK6UM4.js +8 -0
  251. package/dist/registry-X5VPBKCO.js +8 -0
  252. package/dist/request-withdrawal-4SKAH46W.js +26 -0
  253. package/dist/{restore-to-ZQ2MXOFO.js → restore-to-VQHT67OH.js} +7 -10
  254. package/dist/{restore-to-ZQ2MXOFO.js.map → restore-to-VQHT67OH.js.map} +1 -1
  255. package/dist/revoke-IF5PX2JY.js +21 -0
  256. package/dist/satellites/index.js +1 -1
  257. package/dist/schema-update/index.js +2 -2
  258. package/dist/sealed-record/index.js +9 -12
  259. package/dist/sealed-record/index.js.map +1 -1
  260. package/dist/search/index.js +4 -4
  261. package/dist/{seed-XHQQF6LJ.js → seed-F2OSDZJR.js} +11 -13
  262. package/dist/{seed-XHQQF6LJ.js.map → seed-F2OSDZJR.js.map} +1 -1
  263. package/dist/sequence/index.js +6 -9
  264. package/dist/session/index.js +6 -9
  265. package/dist/session/index.js.map +1 -1
  266. package/dist/shadow/index.js +2 -2
  267. package/dist/signer-5P7IZC2K.js +20 -0
  268. package/dist/snapshots/index.js +8 -10
  269. package/dist/snapshots/index.js.map +1 -1
  270. package/dist/{stale-XY2QUSGU.js → stale-PUCZH5GJ.js} +7 -10
  271. package/dist/storage-5EGY5OYE.js +18 -0
  272. package/dist/store/index.js +1 -1
  273. package/dist/{store-coordination-provider-F7YG22D3.js → store-coordination-provider-SEQM7SHJ.js} +7 -10
  274. package/dist/{store-coordination-provider-F7YG22D3.js.map → store-coordination-provider-SEQM7SHJ.js.map} +1 -1
  275. package/dist/sync/index.js +13 -15
  276. package/dist/sync/index.js.map +1 -1
  277. package/dist/team/index.js +14 -16
  278. package/dist/tiers/index.js +8 -11
  279. package/dist/to/index.js +2 -2
  280. package/dist/transactions/index.js +3 -3
  281. package/dist/util/index.js +1 -1
  282. package/dist/vault-diff-H7LT5ZBJ.js +8 -0
  283. package/dist/vault-head/index.js +5 -8
  284. package/dist/vault-head/index.js.map +1 -1
  285. package/dist/walk-Z4N7PCZ2.js +17 -0
  286. package/dist/with-audit/portability/export-accessible.d.ts +3 -1
  287. package/dist/with-cargo/vault-diff.d.ts +28 -0
  288. package/dist/with-commit/sequence/index.d.ts +22 -0
  289. package/dist/with-party/team/keyring.d.ts +77 -0
  290. package/dist/with-party/team/managed-secret.d.ts +40 -3
  291. package/dist/with-shape/manifest/storage.d.ts +2 -2
  292. package/dist/with-shape/manifest/writer.d.ts +2 -2
  293. package/dist/with-store/store-middleware.d.ts +18 -5
  294. package/dist/withdraw-accessible-CRCIQSTL.js +23 -0
  295. package/package.json +3 -3
  296. package/dist/api-ARU35MCC.js +0 -18
  297. package/dist/capsule/enclave-aes/classify/reveal.d.ts +0 -10
  298. package/dist/capsule/enclave-aes/classify/verify.d.ts +0 -36
  299. package/dist/chunk-4RF7DVH2.js.map +0 -1
  300. package/dist/chunk-6B4X447I.js +0 -40
  301. package/dist/chunk-6B4X447I.js.map +0 -1
  302. package/dist/chunk-6Y3UJT5H.js +0 -157
  303. package/dist/chunk-6Y3UJT5H.js.map +0 -1
  304. package/dist/chunk-AYUMAPOS.js.map +0 -1
  305. package/dist/chunk-BCJAUHSG.js.map +0 -1
  306. package/dist/chunk-CE443VXM.js.map +0 -1
  307. package/dist/chunk-FDGE56FS.js.map +0 -1
  308. package/dist/chunk-GLSRKIU3.js +0 -591
  309. package/dist/chunk-GLSRKIU3.js.map +0 -1
  310. package/dist/chunk-GQ4MF3CM.js.map +0 -1
  311. package/dist/chunk-GU6QXHPZ.js.map +0 -1
  312. package/dist/chunk-LFUID7OW.js.map +0 -1
  313. package/dist/chunk-M2VLXPRU.js.map +0 -1
  314. package/dist/chunk-NB2DYYZL.js.map +0 -1
  315. package/dist/chunk-NH2UOV3B.js +0 -18
  316. package/dist/chunk-NH2UOV3B.js.map +0 -1
  317. package/dist/chunk-OJAFKGI7.js +0 -27
  318. package/dist/chunk-OJAFKGI7.js.map +0 -1
  319. package/dist/chunk-PVBKEBJU.js +0 -22
  320. package/dist/chunk-PVBKEBJU.js.map +0 -1
  321. package/dist/chunk-RQLCOSEJ.js +0 -78
  322. package/dist/chunk-RQLCOSEJ.js.map +0 -1
  323. package/dist/chunk-T5EXREMW.js.map +0 -1
  324. package/dist/chunk-VPG2UJYR.js.map +0 -1
  325. package/dist/chunk-VUBRHJ4H.js.map +0 -1
  326. package/dist/chunk-WRLWEYHY.js.map +0 -1
  327. package/dist/chunk-WVML7HUZ.js.map +0 -1
  328. package/dist/chunk-X7Q2XL5U.js.map +0 -1
  329. package/dist/chunk-YIVAKBCW.js.map +0 -1
  330. package/dist/collection-facade-SETOHJ3R.js +0 -41
  331. package/dist/delegation-JIQCMKW6.js +0 -26
  332. package/dist/derive-45KCFFOS.js +0 -20
  333. package/dist/executor-BVVZ5UHG.js +0 -8
  334. package/dist/executor-R25UN3FA.js +0 -8
  335. package/dist/executor-SIYBLT3P.js +0 -35
  336. package/dist/export-accessible-P672FZEJ.js +0 -22
  337. package/dist/extract-partition-DQ3FVL6H.js +0 -35
  338. package/dist/find-HHF2HBAC.js +0 -10
  339. package/dist/issue-NPLQHB3S.js +0 -19
  340. package/dist/liberate-A7WASOCG.js +0 -25
  341. package/dist/link-set-UMRSGMQ5.js +0 -29
  342. package/dist/noydb-V23UJKHT.js +0 -100
  343. package/dist/register-2VINJWYJ.js +0 -30
  344. package/dist/registry-3VLHDUID.js +0 -8
  345. package/dist/registry-6HVHDR3P.js +0 -35
  346. package/dist/registry-V4FQUMYP.js +0 -23
  347. package/dist/registry-Z2E6ZCPM.js +0 -8
  348. package/dist/request-withdrawal-PSIHKQP4.js +0 -28
  349. package/dist/reveal-LK3GX4L6.js.map +0 -1
  350. package/dist/revoke-2NYMID63.js +0 -24
  351. package/dist/signer-CP6XZLE3.js +0 -23
  352. package/dist/storage-QTM6JYQF.js +0 -21
  353. package/dist/vault-diff-C6WUJFNP.js +0 -8
  354. package/dist/verify-FT5COLP2.js.map +0 -1
  355. package/dist/walk-52FW6EKP.js +0 -20
  356. package/dist/withdraw-accessible-IVMKJGEN.js +0 -25
  357. package/dist/withdraw-accessible-IVMKJGEN.js.map +0 -1
  358. /package/dist/{api-ARU35MCC.js.map → api-QSEKT4KS.js.map} +0 -0
  359. /package/dist/{capsule-QJJFUUSH.js.map → capsule-YAITMH77.js.map} +0 -0
  360. /package/dist/{chunk-E3CUGBGW.js.map → chunk-24AGG4PP.js.map} +0 -0
  361. /package/dist/{chunk-MRVQKRXI.js.map → chunk-2SIREKBR.js.map} +0 -0
  362. /package/dist/{chunk-ZZZVNHN2.js.map → chunk-3M2KK7O7.js.map} +0 -0
  363. /package/dist/{chunk-P6FATPXQ.js.map → chunk-3ZCVY3T6.js.map} +0 -0
  364. /package/dist/{chunk-I7NDTNHK.js.map → chunk-4CGWLHPQ.js.map} +0 -0
  365. /package/dist/{chunk-PVQIME6P.js.map → chunk-56Z4NOC6.js.map} +0 -0
  366. /package/dist/{chunk-HQFTE3DX.js.map → chunk-5BGHAVBN.js.map} +0 -0
  367. /package/dist/{chunk-QHG7GQKM.js.map → chunk-5JNEDW7I.js.map} +0 -0
  368. /package/dist/{chunk-YAYDDYRU.js.map → chunk-5Y4MO7UQ.js.map} +0 -0
  369. /package/dist/{chunk-TLIFNRU5.js.map → chunk-63LZLRWG.js.map} +0 -0
  370. /package/dist/{chunk-BUFFPAR2.js.map → chunk-74W56QPY.js.map} +0 -0
  371. /package/dist/{chunk-U2N7DH4S.js.map → chunk-AHA7UALU.js.map} +0 -0
  372. /package/dist/{chunk-RNQ7V4LH.js.map → chunk-ANYX2M6P.js.map} +0 -0
  373. /package/dist/{chunk-VFGLMRO2.js.map → chunk-ATKYMRBC.js.map} +0 -0
  374. /package/dist/{chunk-7UHLO4ZN.js.map → chunk-B2HU55QD.js.map} +0 -0
  375. /package/dist/{chunk-RKOXA5GZ.js.map → chunk-BEKMLYQ4.js.map} +0 -0
  376. /package/dist/{chunk-R4PDYYK5.js.map → chunk-C2NXAR3D.js.map} +0 -0
  377. /package/dist/{chunk-44CU4N7N.js.map → chunk-CQLMRCKX.js.map} +0 -0
  378. /package/dist/{chunk-4XXRPSPS.js.map → chunk-DS2JXSUA.js.map} +0 -0
  379. /package/dist/{chunk-X6Z2SIRF.js.map → chunk-E2JIE4S3.js.map} +0 -0
  380. /package/dist/{chunk-EQ6C2ZPT.js.map → chunk-E7Y4J4GL.js.map} +0 -0
  381. /package/dist/{chunk-ZMDSBTFT.js.map → chunk-ECDM6YRX.js.map} +0 -0
  382. /package/dist/{chunk-JM72WDAY.js.map → chunk-EM56MHN5.js.map} +0 -0
  383. /package/dist/{chunk-YWJMM2WY.js.map → chunk-EQXOJH6O.js.map} +0 -0
  384. /package/dist/{chunk-ME6LY5UG.js.map → chunk-ET3U2C3A.js.map} +0 -0
  385. /package/dist/{chunk-G2KLVCKO.js.map → chunk-EU4G7PQH.js.map} +0 -0
  386. /package/dist/{chunk-WJXLTO43.js.map → chunk-EUCUYK5E.js.map} +0 -0
  387. /package/dist/{chunk-EPMX3SCC.js.map → chunk-EWSIJDWO.js.map} +0 -0
  388. /package/dist/{chunk-KFYUQMF5.js.map → chunk-F2FD4LSB.js.map} +0 -0
  389. /package/dist/{chunk-L4UL4IAR.js.map → chunk-F7ENMZYJ.js.map} +0 -0
  390. /package/dist/{chunk-5OG7YQX5.js.map → chunk-FIIVYQOW.js.map} +0 -0
  391. /package/dist/{chunk-2EF2Z4UN.js.map → chunk-FQEUJGBV.js.map} +0 -0
  392. /package/dist/{chunk-UORWAG7K.js.map → chunk-FY4FFNKK.js.map} +0 -0
  393. /package/dist/{chunk-WA4ZPMKP.js.map → chunk-GDCYZGPB.js.map} +0 -0
  394. /package/dist/{chunk-3HDBDUX2.js.map → chunk-H6Q7GKLI.js.map} +0 -0
  395. /package/dist/{chunk-654RE5YC.js.map → chunk-HDAPQF6Q.js.map} +0 -0
  396. /package/dist/{chunk-B5PWQMZN.js.map → chunk-HRLMUZLI.js.map} +0 -0
  397. /package/dist/{chunk-QWC2PRUR.js.map → chunk-HRNQYGLQ.js.map} +0 -0
  398. /package/dist/{chunk-7PFOKQOJ.js.map → chunk-J4L4AS2W.js.map} +0 -0
  399. /package/dist/{chunk-PZZWAHEJ.js.map → chunk-JPSOFWJR.js.map} +0 -0
  400. /package/dist/{chunk-B24ODIKE.js.map → chunk-JRCO67NG.js.map} +0 -0
  401. /package/dist/{chunk-PNEBCVXP.js.map → chunk-JW3I3NNZ.js.map} +0 -0
  402. /package/dist/{chunk-MXNYMFHE.js.map → chunk-JZMPSQBH.js.map} +0 -0
  403. /package/dist/{chunk-IIQMNZXT.js.map → chunk-K5TVSOPQ.js.map} +0 -0
  404. /package/dist/{chunk-ZPXCQNXJ.js.map → chunk-K75SL74I.js.map} +0 -0
  405. /package/dist/{chunk-TA5VTIC4.js.map → chunk-KA4AAUST.js.map} +0 -0
  406. /package/dist/{chunk-JWLVBYP4.js.map → chunk-KUGUML7H.js.map} +0 -0
  407. /package/dist/{chunk-GWYZEPBY.js.map → chunk-L4J5NC2Q.js.map} +0 -0
  408. /package/dist/{chunk-PIF3TNU2.js.map → chunk-LIX4QPMM.js.map} +0 -0
  409. /package/dist/{chunk-LCY6ANV2.js.map → chunk-LWQFGR34.js.map} +0 -0
  410. /package/dist/{chunk-HQPS27BT.js.map → chunk-MMSSHMHW.js.map} +0 -0
  411. /package/dist/{chunk-ND6S2DKC.js.map → chunk-N5S2BCW3.js.map} +0 -0
  412. /package/dist/{chunk-63INIVE4.js.map → chunk-NIZH2TYZ.js.map} +0 -0
  413. /package/dist/{chunk-WQHEEYQA.js.map → chunk-NLDBQHDV.js.map} +0 -0
  414. /package/dist/{chunk-SKSHWV3E.js.map → chunk-NQQ4MOPC.js.map} +0 -0
  415. /package/dist/{chunk-B6EWMGFX.js.map → chunk-NUBI6PYH.js.map} +0 -0
  416. /package/dist/{chunk-VWUSOPBF.js.map → chunk-NYEXUZDW.js.map} +0 -0
  417. /package/dist/{chunk-PIEX7WSG.js.map → chunk-OOLF5FU2.js.map} +0 -0
  418. /package/dist/{chunk-HOK5KGBO.js.map → chunk-OQA7UF2Q.js.map} +0 -0
  419. /package/dist/{chunk-JMMG7UWR.js.map → chunk-ORJPICJI.js.map} +0 -0
  420. /package/dist/{chunk-IF2M43G4.js.map → chunk-PBRD75JF.js.map} +0 -0
  421. /package/dist/{chunk-PR2R57YF.js.map → chunk-PR36DD2X.js.map} +0 -0
  422. /package/dist/{chunk-LFCX2JAV.js.map → chunk-PV4HIC4E.js.map} +0 -0
  423. /package/dist/{chunk-SKF3DF7M.js.map → chunk-PZNK4HTV.js.map} +0 -0
  424. /package/dist/{chunk-5F3KYRG6.js.map → chunk-QBLPLNPE.js.map} +0 -0
  425. /package/dist/{chunk-4ZRNXWF6.js.map → chunk-QZXUISRF.js.map} +0 -0
  426. /package/dist/{chunk-7Q72NTBE.js.map → chunk-RBXYO7MD.js.map} +0 -0
  427. /package/dist/{chunk-S2BQV6HM.js.map → chunk-RIACRFWA.js.map} +0 -0
  428. /package/dist/{chunk-DO33YCSZ.js.map → chunk-RL6RNDJQ.js.map} +0 -0
  429. /package/dist/{chunk-2SPWVX6W.js.map → chunk-SJ2P7UXD.js.map} +0 -0
  430. /package/dist/{chunk-26FMWFAW.js.map → chunk-SWXS4LV3.js.map} +0 -0
  431. /package/dist/{chunk-J3ECXFU7.js.map → chunk-TOTCZFRF.js.map} +0 -0
  432. /package/dist/{chunk-AN4GUUQM.js.map → chunk-TT4D52EK.js.map} +0 -0
  433. /package/dist/{chunk-KOJHCSGS.js.map → chunk-U7CMJY5P.js.map} +0 -0
  434. /package/dist/{chunk-MKQHIYUY.js.map → chunk-UZVHSYIF.js.map} +0 -0
  435. /package/dist/{chunk-OCSKQUNE.js.map → chunk-VKZ3TDET.js.map} +0 -0
  436. /package/dist/{chunk-ESDYDGPH.js.map → chunk-VLZPUG5A.js.map} +0 -0
  437. /package/dist/{chunk-PCYIDPFM.js.map → chunk-VSN5FLMI.js.map} +0 -0
  438. /package/dist/{chunk-S4QDN4IQ.js.map → chunk-VYBBE7RN.js.map} +0 -0
  439. /package/dist/{chunk-XBFJRCRW.js.map → chunk-WHK4JVKF.js.map} +0 -0
  440. /package/dist/{chunk-CZEWEOOV.js.map → chunk-X4LDBALX.js.map} +0 -0
  441. /package/dist/{chunk-YWEPWJRG.js.map → chunk-X67E7NIJ.js.map} +0 -0
  442. /package/dist/{chunk-RRI3JBD6.js.map → chunk-XMARKBUC.js.map} +0 -0
  443. /package/dist/{chunk-B3B6HV5S.js.map → chunk-XMBBTETD.js.map} +0 -0
  444. /package/dist/{chunk-GEICXZCQ.js.map → chunk-XROQP6IQ.js.map} +0 -0
  445. /package/dist/{chunk-VX72USUQ.js.map → chunk-Y2RYUWSQ.js.map} +0 -0
  446. /package/dist/{chunk-6I5RRBPP.js.map → chunk-YCTSQV7K.js.map} +0 -0
  447. /package/dist/{chunk-7WV6R7RG.js.map → chunk-YF7P2DG7.js.map} +0 -0
  448. /package/dist/{chunk-ZZLIFVZG.js.map → chunk-ZG7DBIVX.js.map} +0 -0
  449. /package/dist/{chunk-Y6WJJRVV.js.map → chunk-ZGJ775X7.js.map} +0 -0
  450. /package/dist/{chunk-PQGCWTTI.js.map → chunk-ZQQLOEWN.js.map} +0 -0
  451. /package/dist/{classified-marker-LY7KQFPH.js.map → classified-marker-HKMRC7SC.js.map} +0 -0
  452. /package/dist/{collection-facade-SETOHJ3R.js.map → collection-facade-PPKNUR2J.js.map} +0 -0
  453. /package/dist/{computed-XG7LFB7A.js.map → computed-UCYVPMZA.js.map} +0 -0
  454. /package/dist/{delegation-JIQCMKW6.js.map → delegation-SNALWRMO.js.map} +0 -0
  455. /package/dist/{derive-45KCFFOS.js.map → derive-4GNU4E4I.js.map} +0 -0
  456. /package/dist/{dispatch-URNW4Q2T.js.map → dispatch-V5WLDTVX.js.map} +0 -0
  457. /package/dist/{executor-BVVZ5UHG.js.map → executor-7QN22OKI.js.map} +0 -0
  458. /package/dist/{executor-R25UN3FA.js.map → executor-BJZJNVBB.js.map} +0 -0
  459. /package/dist/{executor-SIYBLT3P.js.map → executor-JEAAEJUM.js.map} +0 -0
  460. /package/dist/{export-accessible-P672FZEJ.js.map → export-accessible-TVO2KQPG.js.map} +0 -0
  461. /package/dist/{extract-partition-DQ3FVL6H.js.map → extract-partition-43CLDRN4.js.map} +0 -0
  462. /package/dist/{find-HHF2HBAC.js.map → issue-EIHEDAXM.js.map} +0 -0
  463. /package/dist/{issue-NPLQHB3S.js.map → ledger-BMVUFQ3R.js.map} +0 -0
  464. /package/dist/{ledger-FV6NFTOR.js.map → liberate-7KHXCLNJ.js.map} +0 -0
  465. /package/dist/{liberate-A7WASOCG.js.map → link-set-PC2EJRKL.js.map} +0 -0
  466. /package/dist/{link-set-UMRSGMQ5.js.map → managed-secret-RPRVEYZA.js.map} +0 -0
  467. /package/dist/{migrate-cek-J634S4NU.js.map → migrate-cek-DTSCWGEF.js.map} +0 -0
  468. /package/dist/{managed-secret-PBJZHPQO.js.map → noydb-AYDNOXAX.js.map} +0 -0
  469. /package/dist/{post-register-L42VXYFB.js.map → post-register-RITSNASO.js.map} +0 -0
  470. /package/dist/{noydb-V23UJKHT.js.map → register-BB34SK7E.js.map} +0 -0
  471. /package/dist/{register-2VINJWYJ.js.map → registry-65L6V5TO.js.map} +0 -0
  472. /package/dist/{registry-3VLHDUID.js.map → registry-HU62GPWA.js.map} +0 -0
  473. /package/dist/{registry-6HVHDR3P.js.map → registry-SMNK6UM4.js.map} +0 -0
  474. /package/dist/{registry-V4FQUMYP.js.map → registry-X5VPBKCO.js.map} +0 -0
  475. /package/dist/{registry-Z2E6ZCPM.js.map → request-withdrawal-4SKAH46W.js.map} +0 -0
  476. /package/dist/{request-withdrawal-PSIHKQP4.js.map → revoke-IF5PX2JY.js.map} +0 -0
  477. /package/dist/{revoke-2NYMID63.js.map → signer-5P7IZC2K.js.map} +0 -0
  478. /package/dist/{signer-CP6XZLE3.js.map → stale-PUCZH5GJ.js.map} +0 -0
  479. /package/dist/{stale-XY2QUSGU.js.map → storage-5EGY5OYE.js.map} +0 -0
  480. /package/dist/{storage-QTM6JYQF.js.map → vault-diff-H7LT5ZBJ.js.map} +0 -0
  481. /package/dist/{vault-diff-C6WUJFNP.js.map → walk-Z4N7PCZ2.js.map} +0 -0
  482. /package/dist/{walk-52FW6EKP.js.map → withdraw-accessible-CRCIQSTL.js.map} +0 -0
@@ -1,18 +0,0 @@
1
- // src/capsule/plumbing/kofn.ts
2
- function evaluateKofN(results, min) {
3
- if (!Number.isInteger(min) || min < 1 || min > results.length) {
4
- throw new Error(
5
- `evaluateKofN: min ${min} out of range 1..${results.length} \u2014 caller bug (matchGroup validates bounds up front, before any PBKDF2)`
6
- );
7
- }
8
- let count = 0;
9
- for (const r of results) {
10
- if (r) count += 1;
11
- }
12
- return count >= min;
13
- }
14
-
15
- export {
16
- evaluateKofN
17
- };
18
- //# sourceMappingURL=chunk-NH2UOV3B.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/capsule/plumbing/kofn.ts"],"sourcesContent":["/**\n * k-of-n aggregate for matchGroup (§3). Deliberately a full scan that\n * never breaks: per-member results must never influence control flow in\n * a way an observer could time or decompose. Returns ONLY the aggregate.\n * @module\n */\nexport function evaluateKofN(results: readonly boolean[], min: number): boolean {\n if (!Number.isInteger(min) || min < 1 || min > results.length) {\n throw new Error(\n `evaluateKofN: min ${min} out of range 1..${results.length} — caller bug ` +\n `(matchGroup validates bounds up front, before any PBKDF2)`,\n )\n }\n let count = 0\n for (const r of results) {\n if (r) count += 1 // no short-circuit — collect, never break\n }\n return count >= min\n}\n"],"mappings":";AAMO,SAAS,aAAa,SAA6B,KAAsB;AAC9E,MAAI,CAAC,OAAO,UAAU,GAAG,KAAK,MAAM,KAAK,MAAM,QAAQ,QAAQ;AAC7D,UAAM,IAAI;AAAA,MACR,qBAAqB,GAAG,oBAAoB,QAAQ,MAAM;AAAA,IAE5D;AAAA,EACF;AACA,MAAI,QAAQ;AACZ,aAAW,KAAK,SAAS;AACvB,QAAI,EAAG,UAAS;AAAA,EAClB;AACA,SAAO,SAAS;AAClB;","names":[]}
@@ -1,27 +0,0 @@
1
- import {
2
- NoydbError
3
- } from "./chunk-JGYCKX56.js";
4
-
5
- // src/capsule/contract.ts
6
- function assertCapsuleSupports(caps, group, requirer) {
7
- if (!caps.has(group)) throw new CapsuleNotSupportedError(group, requirer);
8
- }
9
- var CapsuleNotSupportedError = class extends NoydbError {
10
- constructor(group, requirer) {
11
- super(
12
- "CAPSULE_NOT_SUPPORTED",
13
- `Capsule does not support the "${group}" group, which "${requirer}" requires. An exclave capsule refuses "authenticate" and "seal" by design \u2014 services that need them cannot be used with it. Check capabilities().`
14
- );
15
- this.group = group;
16
- this.requirer = requirer;
17
- this.name = "CapsuleNotSupportedError";
18
- }
19
- group;
20
- requirer;
21
- };
22
-
23
- export {
24
- assertCapsuleSupports,
25
- CapsuleNotSupportedError
26
- };
27
- //# sourceMappingURL=chunk-OJAFKGI7.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/capsule/contract.ts"],"sourcesContent":["/**\n * The capsule seam (capsule seam spec, Section 2).\n *\n * A capsule is hub's crypto interior behind one contract. `enclave-aes` is the\n * default and ships INSIDE hub, so `npm install @noy-db/hub` alone is a working\n * noy-db. An alternative binds at BUILD TIME through hub's `imports` map —\n * deliberately not at runtime: a `createNoydb({ capsule })` option would be a\n * hot-swap surface, and a build condition lives in build config where the\n * shipped bundle stays auditable (`npm ls` tells an auditor whether a build is\n * plaintext-at-rest).\n *\n * ⛔ `CapsuleKey` is OPAQUE outside `capsule/`. Never construct, inspect or\n * serialise one; only pass it between contract functions. A fork may define it\n * as something that is not a `CryptoKey` at all — hardware-backed,\n * post-quantum, or null for a capsule that does no encryption.\n */\nimport { NoydbError } from '../kernel/errors.js'\nimport type { VdigFieldPolicy } from '../kernel/types.js'\n\n/** Opaque key at the capsule seam. `CryptoKey` in the reference capsule. */\nexport type CapsuleKey = CryptoKey\n\n/** Opaque asymmetric pair at the capsule seam. */\nexport type CapsuleKeyPair = CryptoKeyPair\n\n/**\n * The groups a capsule may support. A capsule declares its set via\n * `capabilities()`; a service needing a group asserts at `createNoydb()`.\n *\n * `authenticate` and `seal` are what an `enclave-*` MUST support and an\n * `exclave-*` MUST refuse. That prefix rule is asserted by the conformance\n * suite from the package name, which is what makes the prefix a trust posture\n * rather than a naming convention.\n */\nexport type CapsuleGroup =\n | 'authenticate'\n | 'seal'\n | 'cipher'\n | 'digest'\n | 'sign'\n | 'codec'\n | 'sealing'\n | 'deterministic'\n | 'classify'\n // ⭐ ADDED 2026-09-16 (core#42). `wrapCek` / `unwrapCek` are real primitives\n // a capsule may refuse independently, and the conformance kit has carried a\n // live refusal test for them under this name since it shipped — but no\n // member of this union covered them, so the refusal could not be NAMED.\n // Found when `EnclaveNotSupportedError` turned out to accept it while this\n // union did not: three vocabularies disagreed, and this one was the one\n // missing a group rather than the error inventing one.\n | 'per-record-keys'\n\n/**\n * Thrown at `createNoydb()` when a service needs a group the bound capsule\n * does not support.\n *\n * ⚠️ Never thrown on first write, and never discovered by try/catch probing: a\n * consumer learns at startup or not at all. A capability discovered mid-write\n * is a half-built vault.\n */\n/**\n * Refuse at CONSTRUCTION when a service needs a capsule group the bound\n * capsule lacks.\n *\n * ⛔ At startup or not at all. A capability discovered on first write is a\n * half-built vault: some records sealed, a service silently inert, and a\n * consumer who cannot tell a missing capability from a bug. `capabilities()`\n * is a set, so this is a membership test — never a try/catch probe against the\n * primitive itself, which would make \"unsupported\" and \"broken\" the same\n * observation.\n *\n * Lives on the CONTRACT, not in the kernel: it depends on nothing but the\n * declared set, and every capsule's consumers need the same assertion.\n *\n * ⚠️ Per-service wiring is deliberately NOT done yet. `enclave-aes` supports\n * every group, so every call site would be unreachable code behind an\n * untestable branch. It lands in Stage C with `exclave-plain`, which is the\n * first capsule that refuses anything. Until then this is exercised against a\n * stub set — see `__tests__/capsule-capabilities.test.ts`.\n */\nexport function assertCapsuleSupports(\n caps: ReadonlySet<CapsuleGroup>,\n group: CapsuleGroup,\n requirer: string,\n): void {\n if (!caps.has(group)) throw new CapsuleNotSupportedError(group, requirer)\n}\n\nexport class CapsuleNotSupportedError extends NoydbError {\n constructor(readonly group: CapsuleGroup, readonly requirer: string) {\n super(\n 'CAPSULE_NOT_SUPPORTED',\n `Capsule does not support the \"${group}\" group, which \"${requirer}\" requires. ` +\n `An exclave capsule refuses \"authenticate\" and \"seal\" by design — services ` +\n `that need them cannot be used with it. Check capabilities().`,\n )\n this.name = 'CapsuleNotSupportedError'\n }\n}\n\n/**\n * The 13 cipher primitives the shared plumbing needs — the ENTIRE surface a\n * capsule must actually implement.\n *\n * ⭐ This is the measurement that shaped Stage C. `enclave-aes` is ~4,200\n * lines, but only ~1,200 of them touch `crypto.subtle`; the other ~3,000 are\n * envelope assembly, record-identity AAD, tombstones and the record codec —\n * plumbing that is IDENTICAL for every capsule because it encodes hub's\n * envelope format, not anyone's cipher. `makeCapsule()` binds that plumbing to\n * these primitives, so a second capsule writes ~400 lines instead of ~3,400\n * and the format lives in exactly one place.\n *\n * The alternative — copying the plumbing into each capsule — was rejected for\n * a specific reason: nothing would fail when the two copies drifted. A change\n * to the tombstone shape or the AAD would have to be made twice, and the\n * second miss surfaces as an envelope that one capsule writes and the other\n * cannot read.\n *\n * ⚠️ Declared with PROPERTY syntax (`encrypt: (…) => …`), never method\n * shorthand. Two reasons, both measured. TypeScript checks method shorthand\n * BIVARIANTLY, so a capsule whose `encrypt` took the wrong number of arguments\n * would satisfy a shorthand declaration and fail only at a call site — the\n * exact hole #16 fell through. And `@typescript-eslint/unbound-method` refuses\n * to let a shorthand method be destructured off the object, which is precisely\n * how the plumbing consumes these.\n *\n * ⚠️ Every primitive here is `async` except `bufferToBase64`, including ones a\n * plaintext capsule answers instantly. That is deliberate: a capsule that\n * needs real asynchrony (hardware-backed keys, a remote KMS) must be\n * expressible without changing this type, and a synchronous implementation\n * loses nothing by returning a resolved promise.\n */\nexport interface CapsulePrimitives<K = CapsuleKey> {\n encrypt: (plaintext: string, key: K, aad?: Uint8Array) => Promise<{ iv: string; data: string }>\n decrypt: (iv: string, data: string, key: K, aad?: Uint8Array) => Promise<string>\n encryptBytesWithAAD: (bytes: Uint8Array, key: K, aad: Uint8Array) => Promise<{ iv: string; data: string }>\n decryptBytesWithAAD: (iv: string, data: string, key: K, aad: Uint8Array) => Promise<Uint8Array>\n /** Same plaintext + key + context ⇒ same ciphertext. Refused by a capsule without the group. */\n encryptDeterministic: (plaintext: string, key: K, context: string) => Promise<{ iv: string; data: string }>\n /** ⚠️ ONE argument. The AES capsule derives the CONTEXT into the IV, not the key\n * (`encryptDeterministic` calls `deriveDeterministicIV(dek, context, plaintext)`),\n * so a `(dek, context)` signature here would have been a plausible-looking lie\n * that only the call sites caught. */\n deriveDeterministicKey: (dek: K) => Promise<K>\n deriveSealedFieldKey: (dek: K, collectionName: string, field: string) => Promise<K>\n deriveSealedFieldKeyFromCek: (cek: K, collectionName: string, field: string) => Promise<K>\n generateDEK: () => Promise<K>\n wrapCek: (cek: K, dek: K) => Promise<string>\n unwrapCek: (wrapped: string, dek: K) => Promise<K>\n /** Accepts `ArrayBuffer` too — the AES capsule's callers pass raw `subtle` output. */\n bufferToBase64: (buffer: ArrayBuffer | Uint8Array) => string\n\n // ─── optional group: classify ──────────────────────────────────────\n //\n // The record codec reaches into exactly two cipher-bound classify functions\n // (plus `normalizeForVerify`, which is pure and lives in the plumbing). They\n // sit here rather than in a separate object because the codec calls them the\n // same way it calls `encrypt` — and a capsule that refuses the `classify`\n // group implements them as a throw, which is the refusal the group means.\n mintVdigSlot: (\n value: string,\n policy: VdigFieldPolicy,\n prevBlob: string | undefined,\n cek: K,\n collection: string,\n id: string,\n field: string,\n ) => Promise<string>\n mintBidxTag: (normalized: string, dek: K, collection: string, field: string) => Promise<string>\n /** The vdig payload is sealed under a capsule-derived slot key, so open/seal\n * are the capsule's, not the plumbing's. `rotateRecordCek` needs both to\n * carry a classified slot across a key rotation. */\n openVdigPayload: (blob: string, cek: K, collection: string, id: string, field: string) => Promise<VdigPayload>\n sealVdigPayload: (payload: VdigPayload, cek: K, collection: string, id: string, field: string) => Promise<string>\n}\n\n/** The classified verify-digest payload, at the seam because both the capsule\n * and the plumbing name it. Structural, not the capsule's own type. */\nexport interface VdigDigestEntry {\n readonly salt: string\n readonly hash: string\n}\n\nexport interface VdigPayload {\n readonly v: 1\n readonly alg: 'PBKDF2-SHA256'\n readonly iter: number\n readonly cur: VdigDigestEntry & { readonly at: string }\n readonly ring?: readonly VdigDigestEntry[]\n}\n\n\n// ─── what an alternative capsule builds on ─────────────────────────\n//\n// `@noy-db/hub/capsule` is the subpath an out-of-tree capsule installs, so the\n// shared halves have to be reachable from it: `makeCapsule()` binds hub's\n// envelope plumbing to a cipher, and the `digest` group is identical for every\n// capsule by design. Without these, an alternative capsule would have to\n// re-implement ~3,400 lines it does not own — and drift from them silently.\nexport { makeCapsule } from './plumbing/index.js'\nexport type { Capsule, RecordCodec } from './plumbing/index.js'\nexport {\n sha256Hex,\n sha256Bytes,\n hmacSha256Hex,\n hmacSignHex,\n hkdfAesGcmKey,\n deriveBlobAddressKey,\n derivePresenceKey,\n derivePresenceTagKey,\n generateIV,\n generateSalt,\n generateRecoverySecret,\n bufferToBase64,\n base64ToBuffer,\n encodeEchoParts,\n KEY_BITS,\n} from './plumbing/digest.js'\nexport type { EchoSecretParts } from './plumbing/digest.js'\nexport {\n buildRecordAad,\n recordAadFor,\n buildRecordEnvelope,\n buildTombstone,\n isTombstone,\n isTombstoneShape,\n buildDeleteMarker,\n isDeleteMarker,\n requireSealedBody,\n sealedBodyArgs,\n envelopeBodySize,\n hasPerRecordKey,\n envelopeBodyForHash,\n hasSealedBody,\n normalizeForVerify,\n parseSealedSlot,\n} from './plumbing/index.js'\nexport type { RecordIdentity, RecordRef } from './plumbing/index.js'\nexport { buildSealedRecordEnvelope } from './plumbing/record-envelope.js'\nexport { generateSigningKeyPair, signBytes, verifyBytes } from './plumbing/sign.js'\nexport { ctEqualTags } from './plumbing/ct-equal.js'\nexport { evaluateKofN } from './plumbing/kofn.js'\n"],"mappings":";;;;;AAiFO,SAAS,sBACd,MACA,OACA,UACM;AACN,MAAI,CAAC,KAAK,IAAI,KAAK,EAAG,OAAM,IAAI,yBAAyB,OAAO,QAAQ;AAC1E;AAEO,IAAM,2BAAN,cAAuC,WAAW;AAAA,EACvD,YAAqB,OAA8B,UAAkB;AACnE;AAAA,MACE;AAAA,MACA,iCAAiC,KAAK,mBAAmB,QAAQ;AAAA,IAGnE;AANmB;AAA8B;AAOjD,SAAK,OAAO;AAAA,EACd;AAAA,EARqB;AAAA,EAA8B;AASrD;","names":[]}
@@ -1,22 +0,0 @@
1
- import {
2
- CURRENT_COST_BYTE,
3
- iterationsForCostByte,
4
- mintAt
5
- } from "./chunk-RQLCOSEJ.js";
6
- import {
7
- normalizeForVerify
8
- } from "./chunk-6Y3UJT5H.js";
9
-
10
- // src/capsule/enclave-aes/classify/find.ts
11
- async function computeBidxTarget(candidate, normalize, dek, collection, field, costByte) {
12
- const resolvedCostByte = costByte ?? CURRENT_COST_BYTE;
13
- const iters = iterationsForCostByte(resolvedCostByte);
14
- if (iters === null) return null;
15
- const normalized = normalizeForVerify(normalize, candidate);
16
- return mintAt(normalized, dek, collection, field, resolvedCostByte);
17
- }
18
-
19
- export {
20
- computeBidxTarget
21
- };
22
- //# sourceMappingURL=chunk-PVBKEBJU.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/capsule/enclave-aes/classify/find.ts"],"sourcesContent":["/**\n * Query-side blind-index target derivation for classified `equatable`\n * fields (stage 2). `computeBidxTarget` normalizes a caller-supplied\n * candidate and mints it into the same 33-byte `_bidx` tag shape produced by\n * `mintBidxTag` (`bidx.ts`), so a caller can string-compare the result\n * against a stored tag to answer \"does this candidate match?\" without ever\n * decrypting or dictionary-attacking the field.\n *\n * Discriminator-scan contract (Oracle #4): a scanning caller reads each\n * stored tag's leading cost-byte discriminator and derives the target tag\n * **once per distinct discriminator present** — never per-record. `find.ts`\n * itself only computes a single target for a single requested `costByte`;\n * the batching-by-discriminator behavior belongs to the scanner\n * (`findByDigest`, a later task), which calls this function once per\n * distinct discriminator it encounters at step 2 of its scan.\n *\n * An unrecognized `costByte` (unknown or legacy tier not yet supported) is a\n * cheap `null` non-match — `computeBidxTarget` never runs PBKDF2 at a wrong\n * iteration tier just to produce a target that could not possibly match.\n * A legacy tag of a KNOWN older tier remains matchable today by passing that\n * tier's `costByte` explicitly (v1-only today: `CURRENT_COST_BYTE` is the\n * only recognized tier, so this is a future-proofing hook, not live behavior\n * yet).\n *\n * @module\n */\nimport type { EnclaveKey } from '../crypto.js'\nimport { mintAt, iterationsForCostByte, CURRENT_COST_BYTE } from './bidx.js'\nimport { normalizeForVerify, type VerifyNormalizeMode } from '../../plumbing/normalize.js'\n\n/**\n * Normalize `candidate` and mint it into a blind-index target tag at\n * `costByte` (default {@link CURRENT_COST_BYTE}), for string-comparison\n * against a stored `_bidx` tag. Returns `null` when `costByte` is not a\n * recognized discriminator — no PBKDF2 is attempted at an unknown/wrong\n * tier (Oracle #4).\n */\nexport async function computeBidxTarget(\n candidate: string,\n normalize: VerifyNormalizeMode,\n dek: EnclaveKey,\n collection: string,\n field: string,\n costByte?: number,\n): Promise<string | null> {\n const resolvedCostByte = costByte ?? CURRENT_COST_BYTE\n const iters = iterationsForCostByte(resolvedCostByte)\n if (iters === null) return null\n const normalized = normalizeForVerify(normalize, candidate)\n return mintAt(normalized, dek, collection, field, resolvedCostByte)\n}\n"],"mappings":";;;;;;;;;;AAqCA,eAAsB,kBACpB,WACA,WACA,KACA,YACA,OACA,UACwB;AACxB,QAAM,mBAAmB,YAAY;AACrC,QAAM,QAAQ,sBAAsB,gBAAgB;AACpD,MAAI,UAAU,KAAM,QAAO;AAC3B,QAAM,aAAa,mBAAmB,WAAW,SAAS;AAC1D,SAAO,OAAO,YAAY,KAAK,YAAY,OAAO,gBAAgB;AACpE;","names":[]}
@@ -1,78 +0,0 @@
1
- import {
2
- bufferToBase64
3
- } from "./chunk-6Y3UJT5H.js";
4
-
5
- // src/capsule/enclave-aes/classify/digest.ts
6
- var subtle = globalThis.crypto.subtle;
7
- var VDIG_ITERATIONS = 6e5;
8
- async function pbkdf2VerifyDigest(value, salt, iterations) {
9
- const keyMaterial = await subtle.importKey(
10
- "raw",
11
- new TextEncoder().encode(value),
12
- "PBKDF2",
13
- false,
14
- ["deriveBits"]
15
- );
16
- const bits = await subtle.deriveBits(
17
- { name: "PBKDF2", salt, iterations, hash: "SHA-256" },
18
- keyMaterial,
19
- 256
20
- );
21
- return new Uint8Array(bits);
22
- }
23
-
24
- // src/capsule/enclave-aes/classify/bidx.ts
25
- var subtle2 = globalThis.crypto.subtle;
26
- var CLASSIFY_INDEX_KEY_DOMAIN = "noydb-classify-index-v1";
27
- var CLASSIFY_INDEX_SALT_DOMAIN = "noydb-classify-index-salt-v1";
28
- var COST_BYTE_V1 = 1;
29
- var CURRENT_COST_BYTE = COST_BYTE_V1;
30
- function iterationsForCostByte(b) {
31
- if (b === COST_BYTE_V1) return VDIG_ITERATIONS;
32
- return null;
33
- }
34
- async function deriveClassifyIndexKey(dek, collection, field) {
35
- const rawDek = await subtle2.exportKey("raw", dek);
36
- const hkdfKey = await subtle2.importKey("raw", rawDek, "HKDF", false, ["deriveBits"]);
37
- const salt = new TextEncoder().encode(CLASSIFY_INDEX_KEY_DOMAIN);
38
- const info = new TextEncoder().encode(JSON.stringify([CLASSIFY_INDEX_KEY_DOMAIN, collection, field]));
39
- const bits = await subtle2.deriveBits({ name: "HKDF", hash: "SHA-256", salt, info }, hkdfKey, 256);
40
- return subtle2.importKey("raw", bits, { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
41
- }
42
- async function deriveClassifyIndexSalt(dek, collection, field) {
43
- const rawDek = await subtle2.exportKey("raw", dek);
44
- const hkdfKey = await subtle2.importKey("raw", rawDek, "HKDF", false, ["deriveBits"]);
45
- const salt = new TextEncoder().encode(CLASSIFY_INDEX_SALT_DOMAIN);
46
- const info = new TextEncoder().encode(JSON.stringify([CLASSIFY_INDEX_SALT_DOMAIN, collection, field]));
47
- const bits = await subtle2.deriveBits({ name: "HKDF", hash: "SHA-256", salt, info }, hkdfKey, 256);
48
- return new Uint8Array(bits);
49
- }
50
- async function mintAt(normalized, dek, collection, field, costByte) {
51
- const iterations = iterationsForCostByte(costByte);
52
- if (iterations == null) {
53
- throw new Error(`bidx: unknown cost byte 0x${costByte.toString(16)}`);
54
- }
55
- const saltCf = await deriveClassifyIndexSalt(dek, collection, field);
56
- const inner = await pbkdf2VerifyDigest(normalized, saltCf, iterations);
57
- const kIdx = await deriveClassifyIndexKey(dek, collection, field);
58
- const mac = await subtle2.sign("HMAC", kIdx, inner);
59
- const tag = new Uint8Array(1 + 32);
60
- tag[0] = costByte;
61
- tag.set(new Uint8Array(mac), 1);
62
- return bufferToBase64(tag);
63
- }
64
- async function mintBidxTag(normalized, dek, collection, field) {
65
- return mintAt(normalized, dek, collection, field, CURRENT_COST_BYTE);
66
- }
67
-
68
- export {
69
- VDIG_ITERATIONS,
70
- pbkdf2VerifyDigest,
71
- CURRENT_COST_BYTE,
72
- iterationsForCostByte,
73
- deriveClassifyIndexKey,
74
- deriveClassifyIndexSalt,
75
- mintAt,
76
- mintBidxTag
77
- };
78
- //# sourceMappingURL=chunk-RQLCOSEJ.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/capsule/enclave-aes/classify/digest.ts","../src/capsule/enclave-aes/classify/bidx.ts"],"sourcesContent":["/**\n * Verify-digest primitive for classified `digest-only` fields (stage 2).\n * PBKDF2-SHA256 → fixed 32-byte digest. The digest NEVER leaves the enclave\n * in recoverable form — it is sealed into the `_vdig` envelope slot (vdig.ts)\n * or compared in-enclave (verify.ts). @module\n */\nconst subtle = globalThis.crypto.subtle\n\n/** Family KDF constant — matches crypto.ts PBKDF2_ITERATIONS (600K). */\nexport const VDIG_ITERATIONS = 600_000\n\n/**\n * Digest a (pre-normalized) candidate/value to exactly 32 bytes.\n * PBKDF2-SHA256 with a per-record per-write random salt (§2): verify\n * digests are non-equatable by construction.\n */\nexport async function pbkdf2VerifyDigest(\n value: string,\n salt: Uint8Array,\n iterations: number,\n): Promise<Uint8Array> {\n const keyMaterial = await subtle.importKey(\n 'raw',\n new TextEncoder().encode(value),\n 'PBKDF2',\n false,\n ['deriveBits'],\n )\n const bits = await subtle.deriveBits(\n { name: 'PBKDF2', salt: salt as BufferSource, iterations, hash: 'SHA-256' },\n keyMaterial,\n 256,\n )\n return new Uint8Array(bits)\n}\n","/**\n * Blind-index slow-tag primitive for classified `equatable` fields (stage 2).\n *\n * `mintBidxTag` mints a deterministic, key-and-cost-gated tag —\n * `COST_BYTE ‖ HMAC-SHA256(K_idx, PBKDF2-SHA256(normalized, salt_cf))` — that\n * lets `find.ts` do blind equality lookup over an otherwise-opaque field\n * without ever storing the plaintext or a fast dictionary-crackable digest.\n *\n * Rationale (M-2/I3, spec §4/Crypto #1):\n * - The outer HMAC is **keyed** by `K_idx`, a DEK-derived key never seen by\n * the store. A key-less adversary (store access only) cannot mint a\n * candidate tag to test against the index at all — the HMAC blocks the\n * classic \"key-less dictionary attack\" a plain digest would invite.\n * - The inner `pbkdf2VerifyDigest` (stage-2, `digest.ts`) reuses the\n * existing 600K-iteration cost floor, so even a **DEK holder** who can\n * compute `K_idx` still pays the PBKDF2 cost per guess — minting is not\n * free just because you crossed the door.\n * - Neither control is the real security boundary: the DOOR (who is ever\n * handed the DEK to begin with) is. These two costs only shape the\n * economics for whoever is already inside; they do not substitute for\n * access control.\n *\n * `K_idx` and `salt_cf` are separate HKDF derivations off the same DEK\n * (L-1, #554 precedent: dedicated keys from day one, no shared/legacy form) —\n * sign-key hygiene, not `HMAC(K_idx, const)`. Both derivations are\n * domain-separated per `(collection, field)` so a tag cannot be replayed\n * across fields or collections (join-attack separation).\n *\n * `CURRENT_COST_BYTE` is a 1-byte discriminator prefixed onto every tag so a\n * future iteration-tier bump can mint new tags while old ones still parse:\n * an unknown discriminator is a cheap, immediate non-match instead of a\n * PBKDF2 run at the wrong iteration count.\n *\n * @module\n */\nimport type { EnclaveKey } from '../crypto.js'\nimport { bufferToBase64 } from '../../plumbing/digest.js'\nimport { pbkdf2VerifyDigest, VDIG_ITERATIONS } from './digest.js'\n\nconst subtle = globalThis.crypto.subtle\n\n/** HKDF salt domain for the `K_idx` (blind-index HMAC key) derivation. */\nexport const CLASSIFY_INDEX_KEY_DOMAIN = 'noydb-classify-index-v1'\n\n/** HKDF salt domain for the `salt_cf` (per collection/field PBKDF2 salt) derivation. */\nexport const CLASSIFY_INDEX_SALT_DOMAIN = 'noydb-classify-index-salt-v1'\n\n/** Cost-byte discriminator: version 1, iteration-tier 600K. */\nexport const COST_BYTE_V1 = 0x01\n/** The cost byte new tags are minted at. */\nexport const CURRENT_COST_BYTE = COST_BYTE_V1\n\n/**\n * Map a tag's cost-byte discriminator to its PBKDF2 iteration count.\n * An unrecognized discriminator returns `null` — a mismatched/legacy byte\n * is a cheap non-match, never a PBKDF2 run at the wrong tier.\n */\nexport function iterationsForCostByte(b: number): number | null {\n if (b === COST_BYTE_V1) return VDIG_ITERATIONS\n return null\n}\n\n/**\n * Derive the collection+field's dedicated blind-index HMAC key `K_idx` from\n * the DEK via HKDF-SHA256. Non-extractable, `sign`-only — it never leaves\n * this module in usable form.\n */\nexport async function deriveClassifyIndexKey(\n dek: EnclaveKey,\n collection: string,\n field: string,\n): Promise<EnclaveKey> {\n const rawDek = await subtle.exportKey('raw', dek)\n const hkdfKey = await subtle.importKey('raw', rawDek, 'HKDF', false, ['deriveBits'])\n const salt = new TextEncoder().encode(CLASSIFY_INDEX_KEY_DOMAIN)\n const info = new TextEncoder().encode(JSON.stringify([CLASSIFY_INDEX_KEY_DOMAIN, collection, field]))\n const bits = await subtle.deriveBits({ name: 'HKDF', hash: 'SHA-256', salt, info }, hkdfKey, 256)\n return subtle.importKey('raw', bits, { name: 'HMAC', hash: 'SHA-256' }, false, ['sign'])\n}\n\n/**\n * Derive the collection+field's dedicated PBKDF2 salt `salt_cf` from the DEK\n * via a SEPARATE HKDF-deriveBits (distinct from {@link deriveClassifyIndexKey}\n * — sign-key hygiene, not `HMAC(K_idx, const)`). 32 raw bytes.\n */\nexport async function deriveClassifyIndexSalt(\n dek: EnclaveKey,\n collection: string,\n field: string,\n): Promise<Uint8Array> {\n const rawDek = await subtle.exportKey('raw', dek)\n const hkdfKey = await subtle.importKey('raw', rawDek, 'HKDF', false, ['deriveBits'])\n const salt = new TextEncoder().encode(CLASSIFY_INDEX_SALT_DOMAIN)\n const info = new TextEncoder().encode(JSON.stringify([CLASSIFY_INDEX_SALT_DOMAIN, collection, field]))\n const bits = await subtle.deriveBits({ name: 'HKDF', hash: 'SHA-256', salt, info }, hkdfKey, 256)\n return new Uint8Array(bits)\n}\n\n/**\n * Mint a blind-index tag at a given cost byte:\n * `tag = base64(COST_BYTE ‖ HMAC(K_idx, PBKDF2(normalized, salt_cf, iterations-for(COST_BYTE))))`.\n * Factored out of {@link mintBidxTag} so `find.ts`'s `computeBidxTarget` can\n * reuse the same crypto at a caller-chosen cost byte (e.g. to evaluate a\n * legacy tier) without duplicating the derivation/digest/MAC pipeline.\n */\nexport async function mintAt(\n normalized: string,\n dek: EnclaveKey,\n collection: string,\n field: string,\n costByte: number,\n): Promise<string> {\n const iterations = iterationsForCostByte(costByte)\n if (iterations == null) {\n throw new Error(`bidx: unknown cost byte 0x${costByte.toString(16)}`)\n }\n const saltCf = await deriveClassifyIndexSalt(dek, collection, field)\n const inner = await pbkdf2VerifyDigest(normalized, saltCf, iterations)\n const kIdx = await deriveClassifyIndexKey(dek, collection, field)\n const mac = await subtle.sign('HMAC', kIdx, inner as BufferSource)\n const tag = new Uint8Array(1 + 32)\n tag[0] = costByte\n tag.set(new Uint8Array(mac), 1)\n return bufferToBase64(tag)\n}\n\n/**\n * Mint a blind-index tag for an already-normalized value at\n * {@link CURRENT_COST_BYTE}. The caller normalizes once via\n * `normalizeForVerify` (the shared pipeline with `mintVdigSlot`) —\n * `mintBidxTag` never re-normalizes.\n */\nexport async function mintBidxTag(\n normalized: string,\n dek: EnclaveKey,\n collection: string,\n field: string,\n): Promise<string> {\n return mintAt(normalized, dek, collection, field, CURRENT_COST_BYTE)\n}\n"],"mappings":";;;;;AAMA,IAAM,SAAS,WAAW,OAAO;AAG1B,IAAM,kBAAkB;AAO/B,eAAsB,mBACpB,OACA,MACA,YACqB;AACrB,QAAM,cAAc,MAAM,OAAO;AAAA,IAC/B;AAAA,IACA,IAAI,YAAY,EAAE,OAAO,KAAK;AAAA,IAC9B;AAAA,IACA;AAAA,IACA,CAAC,YAAY;AAAA,EACf;AACA,QAAM,OAAO,MAAM,OAAO;AAAA,IACxB,EAAE,MAAM,UAAU,MAA4B,YAAY,MAAM,UAAU;AAAA,IAC1E;AAAA,IACA;AAAA,EACF;AACA,SAAO,IAAI,WAAW,IAAI;AAC5B;;;ACKA,IAAMA,UAAS,WAAW,OAAO;AAG1B,IAAM,4BAA4B;AAGlC,IAAM,6BAA6B;AAGnC,IAAM,eAAe;AAErB,IAAM,oBAAoB;AAO1B,SAAS,sBAAsB,GAA0B;AAC9D,MAAI,MAAM,aAAc,QAAO;AAC/B,SAAO;AACT;AAOA,eAAsB,uBACpB,KACA,YACA,OACqB;AACrB,QAAM,SAAS,MAAMA,QAAO,UAAU,OAAO,GAAG;AAChD,QAAM,UAAU,MAAMA,QAAO,UAAU,OAAO,QAAQ,QAAQ,OAAO,CAAC,YAAY,CAAC;AACnF,QAAM,OAAO,IAAI,YAAY,EAAE,OAAO,yBAAyB;AAC/D,QAAM,OAAO,IAAI,YAAY,EAAE,OAAO,KAAK,UAAU,CAAC,2BAA2B,YAAY,KAAK,CAAC,CAAC;AACpG,QAAM,OAAO,MAAMA,QAAO,WAAW,EAAE,MAAM,QAAQ,MAAM,WAAW,MAAM,KAAK,GAAG,SAAS,GAAG;AAChG,SAAOA,QAAO,UAAU,OAAO,MAAM,EAAE,MAAM,QAAQ,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;AACzF;AAOA,eAAsB,wBACpB,KACA,YACA,OACqB;AACrB,QAAM,SAAS,MAAMA,QAAO,UAAU,OAAO,GAAG;AAChD,QAAM,UAAU,MAAMA,QAAO,UAAU,OAAO,QAAQ,QAAQ,OAAO,CAAC,YAAY,CAAC;AACnF,QAAM,OAAO,IAAI,YAAY,EAAE,OAAO,0BAA0B;AAChE,QAAM,OAAO,IAAI,YAAY,EAAE,OAAO,KAAK,UAAU,CAAC,4BAA4B,YAAY,KAAK,CAAC,CAAC;AACrG,QAAM,OAAO,MAAMA,QAAO,WAAW,EAAE,MAAM,QAAQ,MAAM,WAAW,MAAM,KAAK,GAAG,SAAS,GAAG;AAChG,SAAO,IAAI,WAAW,IAAI;AAC5B;AASA,eAAsB,OACpB,YACA,KACA,YACA,OACA,UACiB;AACjB,QAAM,aAAa,sBAAsB,QAAQ;AACjD,MAAI,cAAc,MAAM;AACtB,UAAM,IAAI,MAAM,6BAA6B,SAAS,SAAS,EAAE,CAAC,EAAE;AAAA,EACtE;AACA,QAAM,SAAS,MAAM,wBAAwB,KAAK,YAAY,KAAK;AACnE,QAAM,QAAQ,MAAM,mBAAmB,YAAY,QAAQ,UAAU;AACrE,QAAM,OAAO,MAAM,uBAAuB,KAAK,YAAY,KAAK;AAChE,QAAM,MAAM,MAAMA,QAAO,KAAK,QAAQ,MAAM,KAAqB;AACjE,QAAM,MAAM,IAAI,WAAW,IAAI,EAAE;AACjC,MAAI,CAAC,IAAI;AACT,MAAI,IAAI,IAAI,WAAW,GAAG,GAAG,CAAC;AAC9B,SAAO,eAAe,GAAG;AAC3B;AAQA,eAAsB,YACpB,YACA,KACA,YACA,OACiB;AACjB,SAAO,OAAO,YAAY,KAAK,YAAY,OAAO,iBAAiB;AACrE;","names":["subtle"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/with-shape/manifest/types.ts","../src/with-shape/manifest/storage.ts","../src/with-shape/manifest/derive.ts"],"sourcesContent":["/**\n * The pod-wide **schema manifest** record type (#941).\n *\n * This is an INDEX, not a full-inline manifest: `SchemaManifest.collections`\n * carries per-collection *metadata* (generation / content hash / field ids),\n * never the JSON Schema body itself. The JSON Schema stays the source of\n * truth at `_schemas/<collection>`, encrypted under that collection's own\n * DEK (see `with-shape/persisted-schemas`). Inlining full schemas into one\n * pod-wide manifest record would either leak every collection's schema to a\n * principal scoped to a single collection, or force the manifest itself\n * onto a collection-DEK it has no business holding — the index preserves\n * per-collection DEK isolation while still giving a single place to answer\n * \"what schema generation is this pod at, and does collection X's stored\n * schema match its declared content hash.\"\n *\n * `aggregateHash` binds the whole per-collection index's content: it is\n * `sha256Hex(canonicalJson(collections))`, so any change to any collection's\n * entry (a new generation, a changed hash, added/renamed field ids) changes\n * `aggregateHash` too. Canonical JSON (sorted object keys, no whitespace)\n * makes the hash independent of the map's key insertion order.\n *\n * @module\n */\n\n/** Per-collection entry inside a {@link SchemaManifest}'s `collections` index. */\nexport interface SchemaManifestEntry {\n /** The vault-wide schema-fence generation this collection's schema was last written at. */\n readonly generation: number\n /** SHA-256 (hex) of the collection's canonicalised JSON Schema (see `persisted-schemas/derive.ts`). */\n readonly contentHash: string\n /** Stable per-field ids (#946), keyed by the field's current name. Absent when the collection has none. */\n readonly fieldIds?: Record<string, string>\n}\n\n/**\n * The pod-wide schema manifest — one record per pod, stored at\n * `_manifest/schema` (see `storage.ts`). An INDEX over the per-collection\n * `_schemas/<collection>` entries, not the schemas themselves.\n */\nexport interface SchemaManifest {\n readonly v: 1\n readonly kind: 'schema'\n /** Pod-wide schema-fence generation (`FenceDoc.currentSchemaVersion`) as of this manifest's derivation. */\n readonly generation: number\n /** Per-collection index: collection name → its manifest entry. */\n readonly collections: Record<string, SchemaManifestEntry>\n /** `sha256Hex(canonicalJson(collections))` — the pod-wide content binding over the index. */\n readonly aggregateHash: string\n}\n\n/** The record id the schema manifest is stored under inside `_manifest`. */\nexport const MANIFEST_SCHEMA_RECORD_ID = 'schema' as const\n","/**\n * Read / write the pod-wide `_manifest/schema` envelope.\n *\n * Mirrors `with-shape/persisted-schemas/storage.ts`'s shape: the same\n * standard noy-db record envelope, AES-GCM encrypted with a collection DEK\n * (here, the `_manifest` collection's own DEK — the manifest INDEX\n * discloses collection names + hashes + generations + field ids, metadata\n * rather than schema bodies, so it gets the same encryption grain as\n * `_schemas` itself).\n *\n * Storage layout:\n *\n * <vault>/_manifest/schema → EncryptedEnvelope\n *\n * Unlike `persisted-schemas/storage.ts` (which takes an already-resolved\n * `EnclaveKey`), these functions take a `getDEK` resolver and call\n * `getDEK(MANIFEST_COLLECTION)` themselves — there is exactly one manifest\n * record per pod, so there is no per-collection DEK the caller needs to\n * pick; resolving it here keeps every manifest call-site symmetric.\n *\n * @module\n */\n\nimport { buildSealedRecordEnvelope, openEnvelopeJson, writeEnvelopeBody, type EnclaveKey } from '../../capsule/index.js'\nimport { canonicalJson, sha256Hex } from '../../with-commit/history/ledger/index.js'\nimport type { NoydbStore } from '../../kernel/types.js'\nimport { MANIFEST_COLLECTION } from './reserved-collections.js'\nimport { MANIFEST_SCHEMA_RECORD_ID, type SchemaManifest, type SchemaManifestEntry } from './types.js'\n\n/** A resolver for a collection's DEK — the same shape as `Vault`'s internal `getDEK`. */\nexport type GetManifestDEK = (collectionName: string) => Promise<EnclaveKey>\n\n/**\n * A decrypted schema-manifest read paired with the wrapping envelope's `_v`\n * — the optimistic-concurrency token. Pass `version` back to\n * {@link saveSchemaManifest} (via `writeSchemaManifest`'s `expectedVersion`)\n * to make the write a strict CAS.\n */\nexport interface LoadedSchemaManifest {\n /** Wrapping envelope `_v`. */\n readonly version: number\n /** Decrypted schema manifest. */\n readonly manifest: SchemaManifest\n}\n\n/**\n * Read the `_manifest/schema` envelope together with its wrapping `_v`.\n * Returns `undefined` when no manifest has ever been written, when the\n * envelope fails to decrypt (wrong DEK), or when it doesn't parse as a\n * `v: 1, kind: 'schema'` manifest.\n */\nexport async function loadSchemaManifestEntry(\n store: NoydbStore,\n vault: string,\n getDEK: GetManifestDEK,\n): Promise<LoadedSchemaManifest | undefined> {\n const envelope = await store.get(vault, MANIFEST_COLLECTION, MANIFEST_SCHEMA_RECORD_ID)\n if (!envelope) return undefined\n const dek = await getDEK(MANIFEST_COLLECTION)\n try {\n const plaintext = await openEnvelopeJson({ collection: MANIFEST_COLLECTION, id: MANIFEST_SCHEMA_RECORD_ID }, envelope, dek)\n const parsed = JSON.parse(plaintext) as SchemaManifest\n if (parsed.v !== 1 || parsed.kind !== 'schema') return undefined\n return { version: envelope._v, manifest: parsed }\n } catch {\n return undefined\n }\n}\n\n/**\n * Encrypt and persist the schema manifest as a strict CAS write:\n * `expectedVersion` must match the stored envelope's `_v` (0 when no\n * envelope exists yet) or `store.put` throws `ConflictError` — surfaced by\n * `writer.ts`'s `writeSchemaManifest` as `ManifestConflictError` rather than\n * retried.\n */\nexport async function saveSchemaManifest(\n store: NoydbStore,\n vault: string,\n manifest: SchemaManifest,\n expectedVersion: number,\n getDEK: GetManifestDEK,\n): Promise<void> {\n const dek = await getDEK(MANIFEST_COLLECTION)\n const json = JSON.stringify(manifest)\n const env = await buildSealedRecordEnvelope(\n { collection: MANIFEST_COLLECTION, id: MANIFEST_SCHEMA_RECORD_ID, version: expectedVersion + 1 },\n (identity) => writeEnvelopeBody(identity, json, dek),\n {},\n )\n await store.put(vault, MANIFEST_COLLECTION, MANIFEST_SCHEMA_RECORD_ID, env, expectedVersion)\n}\n\n/**\n * `sha256Hex(canonicalJson(collections))` — the pod-wide content binding\n * over a schema manifest's per-collection index. Canonical JSON sorts\n * object keys at every depth, so the result is independent of the map's\n * key insertion order. Shared by the writer's tests and (#941 Task 3) the\n * derivation path, so the hash is computed identically everywhere.\n */\nexport async function computeAggregateHash(\n collections: Record<string, SchemaManifestEntry>,\n): Promise<string> {\n return sha256Hex(canonicalJson(collections))\n}\n","/**\n * Derive the pod-wide {@link SchemaManifest} from the per-collection\n * `_schemas/<collection>` records — the source of truth (#941 Task 3).\n *\n * The manifest is an INDEX, never a cache with independent state: every\n * field in a {@link SchemaManifestEntry} is a direct projection of the\n * matching `PersistedSchemaEnvelope` (`hash` → `contentHash`, `fieldIds` →\n * `fieldIds`, `generation` → `generation`, falling back to the live fence's\n * `currentSchemaVersion` for a legacy pre-#946 envelope that never got a\n * generation stamp). Re-running this function against the same stored state\n * always produces the same manifest — that's what makes round-trip identity\n * (AC #2: dump → restore → re-derive matches the original) hold for free,\n * with no special-cased restore logic.\n *\n * A collection whose `_schemas/<collection>` envelope decrypts successfully\n * but has no derivable content (`hash === null` — a stub envelope for a\n * non-Zod validator) is legitimately omitted from the index: there is no\n * content hash to bind.\n *\n * ## Scoped principals: \"cannot decrypt\" is NOT \"doesn't exist\"\n *\n * A `_schemas/<collection>` envelope is encrypted under **that data\n * collection's own DEK** — the same key its records use — NOT a shared\n * `_schemas`-wide key. In a team vault, a collection-scoped grantee (e.g.\n * `grant(..., { role: 'operator', permissions: { invoices: 'rw' } })`) holds\n * only the DEKs their `permissions` name, plus every system-prefixed (`_*`)\n * collection's DEK — `_manifest` included, by `grant()`'s \"propagate system\n * collections to every role\" rule (`keyring.ts`). So a member scoped to\n * `invoices` CAN decrypt `_manifest/schema` (the pod-wide index) but CANNOT\n * decrypt a sibling's `_schemas/customers` envelope — even though that\n * envelope is right there in `store.list(vault, SCHEMAS_COLLECTION)`.\n *\n * `lookupDEK` (the {@link LookupDEK} passed in) reflects this: it returns\n * `undefined` for a collection name whose DEK the caller does not hold —\n * deliberately NEVER minting a fresh one (see the module doc on\n * `LookupDEK` for why). This function distinguishes that case\n * (`undecodableCollections`) from \"the schema envelope legitimately has no\n * derivable content\" (`hash === null`) — the caller (`sync.ts`) MUST treat\n * an incomplete view differently: writing a manifest derived from a\n * partial view would silently drop every collection this principal can't\n * see. See `sync.ts`'s module doc for how the sync path handles this.\n *\n * @module\n */\n\nimport type { EnclaveKey } from '../../capsule/index.js'\nimport { loadFence } from '../schema-update/fence.js'\nimport { loadPersistedSchema, SCHEMAS_COLLECTION } from '../persisted-schemas/storage.js'\nimport { computeAggregateHash } from './storage.js'\nimport type { NoydbStore } from '../../kernel/types.js'\nimport type { SchemaManifest, SchemaManifestEntry } from './types.js'\n\n/**\n * A NON-MINTING DEK lookup: returns the collection's DEK if the caller\n * already holds it, `undefined` otherwise. Deliberately distinct from\n * `storage.ts`'s `GetManifestDEK` (which mints+persists a fresh DEK for an\n * absent collection — correct for a caller about to WRITE that collection,\n * e.g. `_manifest` itself). `deriveSchemaManifest` only ever READS sibling\n * collections it never created and has no business minting keys for — an\n * absent DEK here means \"not my collection to see,\" never \"new collection\n * that needs a key.\" Minting here would be worse than a no-op: it would\n * silently persist a garbage DEK into the caller's OWN `_keyring/<user>`\n * file (via `ensureCollectionDEK`'s `persistKeyring` side effect) that\n * still can't decrypt anything — see `sync.ts` / `with-pod/open.ts`'s\n * fix notes (#941 review).\n */\nexport type LookupDEK = (collectionName: string) => Promise<EnclaveKey | undefined>\n\nexport interface DeriveSchemaManifestResult {\n /** The derived manifest — an index over every collection this principal could decrypt. */\n readonly manifest: SchemaManifest\n /**\n * Names present in `_schemas` (per `store.list`) whose envelope this\n * principal could NOT decrypt — either no DEK held for that collection,\n * or the DEK held failed to decrypt/parse it (treated the same: the\n * caller cannot verify what's there, so it cannot safely be omitted or\n * asserted). Empty for a principal with full visibility (typically the\n * owner/admin/custodian). Non-empty means `manifest.collections` is\n * DEFINITELY INCOMPLETE relative to the pod's true collection set —\n * see `sync.ts` for why that must gate whether the manifest gets written.\n */\n readonly undecodableCollections: readonly string[]\n}\n\n/**\n * Read the fence generation + every `_schemas/<collection>` envelope this\n * principal can decrypt, and project them into a fresh {@link SchemaManifest}.\n * `lookupDEK` is called once per collection found under `_schemas` (never\n * mints — see {@link LookupDEK}). Names whose DEK isn't held, or whose\n * envelope fails to decrypt/parse despite holding a DEK, are reported via\n * `undecodableCollections` rather than silently dropped from the result.\n */\nexport async function deriveSchemaManifest(\n store: NoydbStore,\n vault: string,\n lookupDEK: LookupDEK,\n): Promise<DeriveSchemaManifestResult> {\n const fence = await loadFence(store, vault)\n const collectionNames = await store.list(vault, SCHEMAS_COLLECTION)\n\n const collections: Record<string, SchemaManifestEntry> = {}\n const undecodableCollections: string[] = []\n for (const name of collectionNames) {\n const dek = await lookupDEK(name)\n if (dek === undefined) {\n undecodableCollections.push(name) // present in _schemas, but not decodable by this principal\n continue\n }\n\n const payload = await loadPersistedSchema(store, vault, name, dek)\n if (!payload) {\n // Held a DEK but still couldn't decrypt/parse — cannot distinguish\n // \"wrong key after all\" from real corruption from here; treat as\n // undecodable (never silently drop) rather than \"no content.\"\n undecodableCollections.push(name)\n continue\n }\n if (payload.hash === null) continue // legitimately no derivable content (stub envelope)\n\n const entry: SchemaManifestEntry = {\n generation: payload.generation ?? fence.currentSchemaVersion,\n contentHash: payload.hash,\n }\n collections[name] = payload.fieldIds !== undefined ? { ...entry, fieldIds: payload.fieldIds } : entry\n }\n\n const aggregateHash = await computeAggregateHash(collections)\n const manifest: SchemaManifest = { v: 1, kind: 'schema', generation: fence.currentSchemaVersion, collections, aggregateHash }\n return { manifest, undecodableCollections }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAmDO,IAAM,4BAA4B;;;ACAzC,eAAsB,wBACpB,OACA,OACA,QAC2C;AAC3C,QAAM,WAAW,MAAM,MAAM,IAAI,OAAO,qBAAqB,yBAAyB;AACtF,MAAI,CAAC,SAAU,QAAO;AACtB,QAAM,MAAM,MAAM,OAAO,mBAAmB;AAC5C,MAAI;AACF,UAAM,YAAY,MAAM,iBAAiB,EAAE,YAAY,qBAAqB,IAAI,0BAA0B,GAAG,UAAU,GAAG;AAC1H,UAAM,SAAS,KAAK,MAAM,SAAS;AACnC,QAAI,OAAO,MAAM,KAAK,OAAO,SAAS,SAAU,QAAO;AACvD,WAAO,EAAE,SAAS,SAAS,IAAI,UAAU,OAAO;AAAA,EAClD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AASA,eAAsB,mBACpB,OACA,OACA,UACA,iBACA,QACe;AACf,QAAM,MAAM,MAAM,OAAO,mBAAmB;AAC5C,QAAM,OAAO,KAAK,UAAU,QAAQ;AACpC,QAAM,MAAM,MAAM;AAAA,IAChB,EAAE,YAAY,qBAAqB,IAAI,2BAA2B,SAAS,kBAAkB,EAAE;AAAA,IAC/F,CAAC,aAAa,kBAAkB,UAAU,MAAM,GAAG;AAAA,IACnD,CAAC;AAAA,EACH;AACA,QAAM,MAAM,IAAI,OAAO,qBAAqB,2BAA2B,KAAK,eAAe;AAC7F;AASA,eAAsB,qBACpB,aACiB;AACjB,SAAO,UAAU,cAAc,WAAW,CAAC;AAC7C;;;ACZA,eAAsB,qBACpB,OACA,OACA,WACqC;AACrC,QAAM,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC1C,QAAM,kBAAkB,MAAM,MAAM,KAAK,OAAO,kBAAkB;AAElE,QAAM,cAAmD,CAAC;AAC1D,QAAM,yBAAmC,CAAC;AAC1C,aAAW,QAAQ,iBAAiB;AAClC,UAAM,MAAM,MAAM,UAAU,IAAI;AAChC,QAAI,QAAQ,QAAW;AACrB,6BAAuB,KAAK,IAAI;AAChC;AAAA,IACF;AAEA,UAAM,UAAU,MAAM,oBAAoB,OAAO,OAAO,MAAM,GAAG;AACjE,QAAI,CAAC,SAAS;AAIZ,6BAAuB,KAAK,IAAI;AAChC;AAAA,IACF;AACA,QAAI,QAAQ,SAAS,KAAM;AAE3B,UAAM,QAA6B;AAAA,MACjC,YAAY,QAAQ,cAAc,MAAM;AAAA,MACxC,aAAa,QAAQ;AAAA,IACvB;AACA,gBAAY,IAAI,IAAI,QAAQ,aAAa,SAAY,EAAE,GAAG,OAAO,UAAU,QAAQ,SAAS,IAAI;AAAA,EAClG;AAEA,QAAM,gBAAgB,MAAM,qBAAqB,WAAW;AAC5D,QAAM,WAA2B,EAAE,GAAG,GAAG,MAAM,UAAU,YAAY,MAAM,sBAAsB,aAAa,cAAc;AAC5H,SAAO,EAAE,UAAU,uBAAuB;AAC5C;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/with-commit/sequence/active.ts","../src/with-commit/sequence/strategy.ts","../src/with-commit/sequence/index.ts"],"sourcesContent":["/**\n * Enable the atomic-sequence capability.\n * Pass to `createNoydb({ sequenceStrategy: withSequence() })` to make\n * `vault.sequence('name').next()` / `.peek()` / `.seedTo()` live. The\n * {@link SequenceStore} CAS engine is statically imported here, so it is pulled\n * into the bundle only when `withSequence()` is referenced (the floor never\n * imports it).\n */\nimport type { SequenceStrategy } from './strategy.js'\nimport { SequenceStore } from './index.js'\n\nexport function withSequence(): SequenceStrategy {\n return {\n createStore(opts) {\n return new SequenceStore(opts)\n },\n }\n}\n","/**\n * Sequence capability strategy — the single on-demand factory the vault routes\n * `vault.sequence()` through to build its atomic-CAS {@link SequenceStore}. The\n * active engine ({@link withSequence}) constructs the real store (kept out of\n * the floor bundle — the store class is reached only via the opt-in\n * `active.ts` chunk); {@link NO_SEQUENCE} throws. The vault always assembles the\n * per-call {@link SequenceStoreOptions} and delegates here, so an un-opted-in\n * caller hits `NO_SEQUENCE`'s throw at `vault.sequence()`.\n *\n * Note: `vault.sequence()` is synchronous, so the factory is a plain (sync)\n * constructor — the engine is tree-shaken by reachability (only `withSequence()`\n * pulls `active.ts`, which statically imports the store), not by a dynamic\n * import. Deferred-numbering series (`withDeferredNumbering`) are a distinct\n * capability and are NOT routed through this strategy.\n * @internal\n */\nimport type { SequenceStore, SequenceStoreOptions } from './index.js'\nimport { SequenceNotEnabledError } from '../../kernel/errors.js'\n\nexport interface SequenceStrategy {\n createStore(opts: SequenceStoreOptions): SequenceStore\n}\n\n/**\n * No-op stub — the floor default. The capability factory throws\n * {@link SequenceNotEnabledError}; opt in with `sequenceStrategy: withSequence()`\n * in createNoydb. @internal\n */\nexport const NO_SEQUENCE: SequenceStrategy = {\n createStore(): SequenceStore {\n throw new SequenceNotEnabledError()\n },\n}\n","/**\n * Atomic sequence primitive — online-coordinated gap-free numbering.\n *\n * `vault.sequence('invoice-2026').next()` returns 1, 2, 3, … with no\n * gaps and no duplicates, even under concurrent callers. Each named\n * sequence is an independent counter record at `_sequences/<name>`,\n * incremented with an optimistic compare-and-swap retry loop — the same\n * proven pattern as the ledger head (`history/ledger/store.ts`).\n *\n * **Explicitly online-only.** Gap-free numbering requires single-authority\n * serialization, which an offline / non-CAS store cannot provide. `next()`\n * throws {@link SequenceOfflineError} unless the backing store advertises\n * `capabilities.casAtomic`. This is a deliberate, honest wall — an offline\n * writer cannot safely allocate a global sequence number.\n *\n * Note on \"gap-free\": the *sequence* is gap-free (each `next()` yields a\n * unique, +1 value). If a caller discards a value without using it, that\n * is a gap in *usage*, not in the sequence — assign each `next()` result\n * to its record in the same operation.\n */\n\nimport { buildRecordAad, buildRecordEnvelope } from '../../capsule/index.js'\nimport type { NoydbStore, EncryptedEnvelope } from '../../kernel/types.js'\nimport { encrypt, openEnvelopeJson, type EnclaveKey } from '../../capsule/index.js'\nimport type { ConflictError} from '../../kernel/errors.js';\nimport { isConflictError, SequenceContentionError, SequenceOfflineError, ValidationError } from '../../kernel/errors.js'\n\n// Capability opt-in seam (S4): `vault.sequence()` builds its CAS store through\n// the sequenceStrategy, so it throws SequenceNotEnabledError unless opted in.\nexport { withSequence } from './active.js'\nexport { NO_SEQUENCE, type SequenceStrategy } from './strategy.js'\nexport { SequenceNotEnabledError } from '../../kernel/errors.js'\n\nexport const SEQUENCE_COLLECTION = '_sequences'\n// A sequence is a single hot CAS row — higher contention than a ledger\n// append. A larger budget + jittered backoff absorbs moderate concurrency;\n// a genuine burst beyond this surfaces SequenceContentionError so the\n// caller can retry / queue (the honest online-only contract).\nconst MAX_NEXT_ATTEMPTS = 16\n\ninterface SequenceState {\n value: number\n}\n\n/** Options for `SequenceHandle.next`. Deferred-numbering series use `for`; the CAS counter ignores all of these. */\nexport interface NextOptions {\n /** Deferred mode: the record id to number. Ignored by the CAS counter. */\n readonly for?: string\n /** Deferred mode: reject after this many ms if still unsealed (reserved; not yet enforced in this slice). */\n readonly timeoutMs?: number\n}\n\n/**\n * Partitioning for a CAS sequence. A partitioned sequence is an\n * independent counter scoped to one tuple of values — e.g.\n * `sequence('invoice', { partition: [2026, 'EU'] })` numbers EU-2026 invoices\n * separately from `[2026, 'US']` and from the bare `invoice` series.\n *\n * Partition components are URI-encoded (so `/`, null bytes and other\n * separators in a value can never collide with the structural separators) and\n * `'/'`-joined, then appended to the series with a null-byte (`\\x00`)\n * separator. The null byte is illegal in a plain series name, which guarantees\n * a partitioned key is always disjoint from any unpartitioned series.\n */\nexport interface SequenceOptions {\n /** Partition tuple. Each component is URI-encoded and `'/'`-joined. */\n readonly partition?: readonly (string | number)[]\n /**\n * Render template for the serial string. When set, `vault.sequence`\n * returns a {@link FormattedSequenceHandle} whose `next()` resolves to\n * `{ serial, formatted }`. Tokens:\n * - `{seq}` — the allocated integer\n * - `{seq:0N}` — zero-padded to width N (e.g. `{seq:04}` → `0001`)\n * - `{partition.i}` — the i-th `partition` component (original value)\n *\n * Any other token, or a `{partition.i}` index beyond the supplied\n * `partition`, throws `ValidationError` at `vault.sequence()` construction.\n * Per-partition reset is inherent: a new partition tuple starts at 1.\n */\n readonly format?: string\n}\n\n/**\n * A formatted sequence handle. Identical to {@link SequenceHandle}\n * except `next()` also returns the rendered `formatted` string. `peek()` /\n * `seedTo()` operate on the underlying integer counter, unchanged.\n */\nexport interface FormattedSequenceHandle {\n /** Allocate the next value and return it with its rendered serial string. */\n next(opts?: NextOptions): Promise<{ serial: number; formatted: string }>\n /** Read the current integer value without allocating. Returns 0 if never used. */\n peek(): Promise<number>\n /** Set-if-greater on the underlying integer counter. See {@link SequenceHandle.seedTo}. */\n seedTo(n: number): Promise<void>\n}\n\n// Matches a single `{...}` token with no nested braces.\nconst SEQ_FORMAT_TOKEN = /\\{([^{}]*)\\}/g\nconst SEQ_PAD_TOKEN = /^seq:0(\\d+)$/\nconst SEQ_PARTITION_TOKEN = /^partition\\.(\\d+)$/\n\n/**\n * Validate a sequence `format` against the supplied partition and return a\n * pure `(serial) => string` renderer. Eager validation: every token is\n * checked now, so a bad pattern throws `ValidationError` at construction —\n * never at `next()` time.\n */\nexport function compileSequenceFormat(\n format: string,\n series: string,\n partition: readonly (string | number)[] | undefined,\n): (serial: number) => string {\n const parts = partition ?? []\n for (const m of format.matchAll(SEQ_FORMAT_TOKEN)) {\n const token = m[1] ?? ''\n if (token === 'seq') continue\n if (SEQ_PAD_TOKEN.test(token)) continue\n const partMatch = SEQ_PARTITION_TOKEN.exec(token)\n if (partMatch) {\n const idx = Number(partMatch[1])\n if (idx >= parts.length) {\n throw new ValidationError(\n `sequence(\"${series}\"): format token \"{${token}}\" references partition index ${idx}, ` +\n `but only ${parts.length} partition component(s) were supplied.`,\n )\n }\n continue\n }\n throw new ValidationError(\n `sequence(\"${series}\"): format contains unknown token \"{${token}}\". ` +\n `Accepted tokens: {seq}, {seq:0N}, {partition.i}.`,\n )\n }\n return (serial: number): string =>\n format.replace(SEQ_FORMAT_TOKEN, (full, token: string) => {\n if (token === 'seq') return String(serial)\n const padMatch = SEQ_PAD_TOKEN.exec(token)\n if (padMatch) return String(serial).padStart(Number(padMatch[1]), '0')\n const partMatch = SEQ_PARTITION_TOKEN.exec(token)\n if (partMatch) return String(parts[Number(partMatch[1])])\n return full // unreachable — validated above\n })\n}\n\n/**\n * Resolve the CAS storage key for a (series, partition) pair.\n *\n * With no partition the key is `series` verbatim. With a partition the key is\n * `${series}\\x00${parts}` where `parts` is each component passed through\n * `encodeURIComponent(String(part))` and `'/'`-joined. The null-byte separator\n * is illegal in a plain series name, so partitioned keys never collide with\n * unpartitioned ones; URI-encoding keeps any component containing `/` distinct\n * from a multi-component partition.\n *\n * @throws {ValidationError} if any partition component is empty after `String()`\n * or is a non-finite number (`NaN`, `±Infinity`).\n */\nexport function resolveSequenceKey(series: string, opts?: SequenceOptions): string {\n const partition = opts?.partition\n if (!partition || partition.length === 0) return series\n const parts = partition.map((p) => {\n if (typeof p === 'number' && !Number.isFinite(p)) {\n throw new ValidationError(`sequence partition component must be a finite number, got ${p}`)\n }\n const s = String(p)\n if (s === '') {\n throw new ValidationError('sequence partition component must not be empty')\n }\n return encodeURIComponent(s)\n })\n return `${series}\\x00${parts.join('/')}`\n}\n\nexport interface SequenceHandle {\n /** Atomically allocate and return the next value (1, 2, 3, …). Deferred series resolve at the next pass. */\n next(opts?: NextOptions): Promise<number>\n /** Read the current value without allocating. Returns 0 if never used. */\n peek(): Promise<number>\n /**\n * Set-if-greater: advance the counter to at least `n`. A no-op if the\n * current value is already `>= n` (so it never rewinds), and `seedTo(0)` is\n * a no-op. Idempotent and CAS-safe under concurrent `next()` / `seedTo()`.\n *\n * Use after a bundle / CSV import to fast-forward the counter past the\n * highest imported serial, so subsequent `next()` calls cannot re-use a\n * number that is already on a record.\n *\n * Online-only: throws {@link SequenceOfflineError} on a non-CAS store.\n */\n seedTo(n: number): Promise<void>\n}\n\nasync function sleepBackoff(attempt: number): Promise<void> {\n // Exponential backoff with full jitter to break the thundering herd\n // when many writers contend on the same counter row.\n const ceil = Math.min(2 ** attempt, 32)\n const ms = Math.floor(Math.random() * ceil)\n await new Promise((r) => setTimeout(r, ms))\n}\n\n/** Per-call context the vault assembles to build a {@link SequenceStore}. */\nexport interface SequenceStoreOptions {\n adapter: NoydbStore\n vault: string\n encrypted: boolean\n getDEK: (collectionName: string) => Promise<EnclaveKey>\n actor: string\n}\n\nexport class SequenceStore {\n private readonly adapter: NoydbStore\n private readonly vault: string\n private readonly encrypted: boolean\n private readonly getDEK: (collectionName: string) => Promise<EnclaveKey>\n private readonly actor: string\n /**\n * Memoized DEK promise. The `_sequences` collection DEK is created on\n * first access; without sharing one promise, a burst of concurrent\n * `next()` calls would each trigger DEK creation and diverge (one\n * writer's ciphertext unreadable by another). One shared promise → one\n * DEK.\n */\n private dekPromise: Promise<EnclaveKey> | null = null\n\n constructor(opts: SequenceStoreOptions) {\n this.adapter = opts.adapter\n this.vault = opts.vault\n this.encrypted = opts.encrypted\n this.getDEK = opts.getDEK\n this.actor = opts.actor\n }\n\n /** A handle bound to one sequence name. */\n handle(name: string): SequenceHandle {\n return {\n next: () => this.next(name),\n peek: () => this.peek(name),\n seedTo: (n) => this.seedTo(name, n),\n }\n }\n\n private assertOnline(): void {\n if (this.adapter.capabilities?.casAtomic !== true) {\n throw new SequenceOfflineError()\n }\n }\n\n private dek(): Promise<EnclaveKey> {\n if (!this.dekPromise) this.dekPromise = this.getDEK(SEQUENCE_COLLECTION)\n return this.dekPromise\n }\n\n private async read(name: string): Promise<{ env: EncryptedEnvelope | null; value: number }> {\n const env = await this.adapter.get(this.vault, SEQUENCE_COLLECTION, name)\n if (!env) return { env: null, value: 0 }\n const json = this.encrypted ? await openEnvelopeJson({ collection: SEQUENCE_COLLECTION, id: name }, env, await this.dek()) : (env._data ?? '')\n const state = JSON.parse(json) as SequenceState\n return { env, value: state.value }\n }\n\n private async encryptState(name: string, state: SequenceState, version: number): Promise<EncryptedEnvelope> {\n const json = JSON.stringify(state)\n if (!this.encrypted) {\n return buildRecordEnvelope({ collection: SEQUENCE_COLLECTION, id: name, version }, { iv: '', data: json})\n }\n const identity = { collection: SEQUENCE_COLLECTION, id: name, version }\n const { iv, data } = await encrypt(json, await this.dek(), buildRecordAad(identity))\n return buildRecordEnvelope(identity, { iv, data})\n }\n\n async peek(name: string): Promise<number> {\n return (await this.read(name)).value\n }\n\n async next(name: string): Promise<number> {\n this.assertOnline()\n let lastConflict: ConflictError | undefined\n for (let attempt = 0; attempt < MAX_NEXT_ATTEMPTS; attempt++) {\n const { env, value } = await this.read(name)\n const nextValue = value + 1\n const expectedVersion = env?._v ?? 0 // 0 ≡ \"must not yet exist\" (create)\n const envelope = await this.encryptState(name, { value: nextValue }, expectedVersion + 1)\n try {\n await this.adapter.put(this.vault, SEQUENCE_COLLECTION, name, envelope, expectedVersion)\n return nextValue\n } catch (err) {\n if (isConflictError(err)) {\n lastConflict = err\n if (attempt < MAX_NEXT_ATTEMPTS - 1) await sleepBackoff(attempt)\n continue\n }\n throw err\n }\n }\n void lastConflict\n throw new SequenceContentionError(name, MAX_NEXT_ATTEMPTS)\n }\n\n async seedTo(name: string, n: number): Promise<void> {\n this.assertOnline()\n if (n <= 0) return // set-if-greater: 0 (and any non-positive seed) is a no-op\n let lastConflict: ConflictError | undefined\n for (let attempt = 0; attempt < MAX_NEXT_ATTEMPTS; attempt++) {\n const { env, value } = await this.read(name)\n if (value >= n) return // already at or past the floor — no write, idempotent\n const expectedVersion = env?._v ?? 0 // 0 ≡ \"must not yet exist\" (create)\n const envelope = await this.encryptState(name, { value: n }, expectedVersion + 1)\n try {\n await this.adapter.put(this.vault, SEQUENCE_COLLECTION, name, envelope, expectedVersion)\n return\n } catch (err) {\n if (isConflictError(err)) {\n lastConflict = err\n if (attempt < MAX_NEXT_ATTEMPTS - 1) await sleepBackoff(attempt)\n continue\n }\n throw err\n }\n }\n void lastConflict\n throw new SequenceContentionError(name, MAX_NEXT_ATTEMPTS)\n }\n}\n"],"mappings":"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","names":[]}