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

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 (376) hide show
  1. package/CHANGELOG.md +5437 -0
  2. package/dist/api-D6DBNTOS.js +20 -0
  3. package/dist/attestation/index.js +18 -18
  4. package/dist/{backup-K62BFMYK.js → backup-4PZAH67W.js} +12 -12
  5. package/dist/blobs/index.js +13 -13
  6. package/dist/broker/index.js +12 -12
  7. package/dist/cargo/index.js +31 -31
  8. package/dist/{chunk-IPDS2TYW.js → chunk-23XKHFNT.js} +4 -4
  9. package/dist/{chunk-GYUCRDAU.js → chunk-2DFE4TUE.js} +4 -4
  10. package/dist/{chunk-2IK6AC6A.js → chunk-2VMCJUK6.js} +5 -5
  11. package/dist/{chunk-DKYEVHZH.js → chunk-3ENNPCIW.js} +2 -2
  12. package/dist/{chunk-REL4OLWW.js → chunk-3TWEXEKX.js} +3 -3
  13. package/dist/{chunk-RNSC2ARR.js → chunk-47F6AI2K.js} +3 -3
  14. package/dist/{chunk-L2XQ776M.js → chunk-4BYZIQ5T.js} +2 -2
  15. package/dist/{chunk-NH2MST6J.js → chunk-4IPP2P74.js} +2 -2
  16. package/dist/{chunk-M4IKEOJS.js → chunk-4O52JH3C.js} +6 -6
  17. package/dist/{chunk-GDGTIWB4.js → chunk-4RZTW5JH.js} +2 -2
  18. package/dist/{chunk-WKD5ESK4.js → chunk-6QMOJTC6.js} +2 -2
  19. package/dist/{chunk-BTNKPDZM.js → chunk-6ZGDIN2D.js} +3 -3
  20. package/dist/{chunk-KDX6VEYV.js → chunk-7JOXCSDU.js} +2 -2
  21. package/dist/{chunk-VEX2BQVX.js → chunk-7LJA7T4W.js} +11 -3
  22. package/dist/{chunk-VEX2BQVX.js.map → chunk-7LJA7T4W.js.map} +1 -1
  23. package/dist/{chunk-S55DBWRC.js → chunk-A5YEUQOY.js} +2 -2
  24. package/dist/{chunk-5J5TTSGW.js → chunk-A66LJYFG.js} +7 -4
  25. package/dist/chunk-A66LJYFG.js.map +1 -0
  26. package/dist/{chunk-DJ23QZIN.js → chunk-AELW6OJZ.js} +2 -2
  27. package/dist/{chunk-YOT7D63X.js → chunk-AGETRKC5.js} +3 -3
  28. package/dist/{chunk-W6NFONOV.js → chunk-ANYVM4SX.js} +2 -2
  29. package/dist/{chunk-CADUYBQD.js → chunk-ATL3ZVXT.js} +2 -2
  30. package/dist/{chunk-GILI76SU.js → chunk-BFNBYT62.js} +2 -2
  31. package/dist/{chunk-N7YAQKAO.js → chunk-BPLSGN4X.js} +2 -2
  32. package/dist/{chunk-ZPMXYPBR.js → chunk-BXHG26KN.js} +2 -2
  33. package/dist/{chunk-437FDIHO.js → chunk-CW3VJARJ.js} +3 -3
  34. package/dist/{chunk-ODVIFBAQ.js → chunk-D5EXZVQC.js} +6 -6
  35. package/dist/{chunk-D5UDZANO.js → chunk-DIVPOJPV.js} +96 -8
  36. package/dist/chunk-DIVPOJPV.js.map +1 -0
  37. package/dist/{chunk-PZSS7MUM.js → chunk-DIYI32MG.js} +5 -5
  38. package/dist/{chunk-SFD2LL7G.js → chunk-DUUARUZI.js} +2 -2
  39. package/dist/{chunk-OWGEHDT2.js → chunk-ESXVNASI.js} +5 -5
  40. package/dist/{chunk-MNMYHZVU.js → chunk-F3BICEMK.js} +2 -2
  41. package/dist/{chunk-F5AJZC3U.js → chunk-F5IFR56V.js} +30 -11
  42. package/dist/chunk-F5IFR56V.js.map +1 -0
  43. package/dist/{chunk-RKDH6L53.js → chunk-FFESJQ5A.js} +303 -49
  44. package/dist/chunk-FFESJQ5A.js.map +1 -0
  45. package/dist/{chunk-HJRTFXAA.js → chunk-FFSQFH6D.js} +2 -2
  46. package/dist/{chunk-GT72D4FO.js → chunk-FGZ7GJXO.js} +3 -3
  47. package/dist/{chunk-WBNXZU42.js → chunk-FHEVZQQY.js} +4 -4
  48. package/dist/{chunk-VHVMJWM6.js → chunk-FKZI4NSG.js} +6 -6
  49. package/dist/{chunk-TENLCGYD.js → chunk-FUIG7QSS.js} +4 -4
  50. package/dist/{chunk-ZBDWKPBW.js → chunk-GWJJ5CK3.js} +5 -5
  51. package/dist/{chunk-MNUTPZRQ.js → chunk-H27DIXOV.js} +6 -6
  52. package/dist/{chunk-ZXW3X3DQ.js → chunk-H3SEW5HB.js} +7 -7
  53. package/dist/{chunk-ICCRAPWD.js → chunk-H6K24KLL.js} +4 -4
  54. package/dist/{chunk-DYASJSKI.js → chunk-HRSEAGLI.js} +3 -3
  55. package/dist/{chunk-6TXUVKPG.js → chunk-HUEG3YP4.js} +117 -92
  56. package/dist/chunk-HUEG3YP4.js.map +1 -0
  57. package/dist/{chunk-XGQGWZ6D.js → chunk-HZIIDYJV.js} +4 -4
  58. package/dist/{chunk-GQ3BX5EA.js → chunk-I3ISCYT7.js} +2 -2
  59. package/dist/{chunk-3Y4OFWQJ.js → chunk-IGNJOJEP.js} +1 -1
  60. package/dist/chunk-IGNJOJEP.js.map +1 -0
  61. package/dist/{chunk-N2HKBESK.js → chunk-IPA6ODWG.js} +4 -4
  62. package/dist/{chunk-OQLYMBJI.js → chunk-IUQPNAGR.js} +3 -3
  63. package/dist/{chunk-YVTADFTC.js → chunk-JPVJTTHU.js} +4 -4
  64. package/dist/{chunk-KUXTWVAR.js → chunk-JSTQGUE5.js} +43 -9
  65. package/dist/chunk-JSTQGUE5.js.map +1 -0
  66. package/dist/{chunk-JHO6FGZX.js → chunk-KMGAFLCK.js} +5 -5
  67. package/dist/{chunk-5EJQNA26.js → chunk-KYUKZIW5.js} +2 -2
  68. package/dist/{chunk-HGJC7I5F.js → chunk-L2YYIQYR.js} +2 -2
  69. package/dist/{chunk-PNAIDIP7.js → chunk-L3AM6EGU.js} +16 -9
  70. package/dist/{chunk-PNAIDIP7.js.map → chunk-L3AM6EGU.js.map} +1 -1
  71. package/dist/{chunk-KM6YR5XF.js → chunk-LLLSK7UQ.js} +2 -2
  72. package/dist/{chunk-QPIUFRUC.js → chunk-M3FKPVOU.js} +3 -3
  73. package/dist/{chunk-CV7WXCZD.js → chunk-M7VSXBUL.js} +10 -10
  74. package/dist/{chunk-APV42WPR.js → chunk-MBZFAJKM.js} +2 -2
  75. package/dist/{chunk-SG3OQCRG.js → chunk-MQFKH3ZJ.js} +3 -3
  76. package/dist/{chunk-ZWKF3CD3.js → chunk-NB2CKJ27.js} +2 -2
  77. package/dist/{chunk-HTHRCGWP.js → chunk-NCAMIRFB.js} +2 -2
  78. package/dist/{chunk-VH2W6BOG.js → chunk-NHXIFF4Y.js} +7 -7
  79. package/dist/{chunk-IGJCYUT5.js → chunk-NSITFOCJ.js} +1 -1
  80. package/dist/chunk-NSITFOCJ.js.map +1 -0
  81. package/dist/{chunk-VJ4B3ZXY.js → chunk-O5QXH7U7.js} +2 -2
  82. package/dist/{chunk-MQXYR65M.js → chunk-OBPL43F3.js} +6 -6
  83. package/dist/{chunk-HTMQBBF3.js → chunk-OCW3IM2F.js} +3 -3
  84. package/dist/{chunk-E6VDPBE3.js → chunk-OIW75CLW.js} +6 -6
  85. package/dist/{chunk-NRNTXBHT.js → chunk-OTHHO3KI.js} +2 -2
  86. package/dist/{chunk-4HVTRHSA.js → chunk-OZ5QBLEL.js} +6 -6
  87. package/dist/{chunk-ZVAFJQZB.js → chunk-PENPHA45.js} +2 -2
  88. package/dist/{chunk-CVYXIN5B.js → chunk-PGHSH4TY.js} +3 -3
  89. package/dist/{chunk-P7L3OQLL.js → chunk-PKUJ3JLQ.js} +25 -1
  90. package/dist/chunk-PKUJ3JLQ.js.map +1 -0
  91. package/dist/{chunk-IOURTXTM.js → chunk-PNXJV4OS.js} +79 -23
  92. package/dist/chunk-PNXJV4OS.js.map +1 -0
  93. package/dist/{chunk-A4K5GLE6.js → chunk-PWK3SSNB.js} +6 -6
  94. package/dist/{chunk-5JT4Y5UE.js → chunk-QK2QAMF7.js} +10 -10
  95. package/dist/{chunk-PG6PFMDC.js → chunk-QMJI5VHV.js} +2 -2
  96. package/dist/{chunk-RQY5UWEL.js → chunk-QTWWZ25B.js} +12 -12
  97. package/dist/{chunk-RSFG7XHM.js → chunk-REKDM67V.js} +2 -2
  98. package/dist/{chunk-2E2MKBMI.js → chunk-REQJLII3.js} +2 -2
  99. package/dist/{chunk-TC6MBEGH.js → chunk-RJYPFCID.js} +5 -5
  100. package/dist/{chunk-EJIVFOOQ.js → chunk-RT7CWTUG.js} +6 -6
  101. package/dist/{chunk-6S466CMQ.js → chunk-SRR22EW2.js} +8 -8
  102. package/dist/{chunk-C7WJNVJG.js → chunk-TKLQWOTY.js} +2 -2
  103. package/dist/{chunk-SA77BQ7F.js → chunk-UQUWSM33.js} +5 -5
  104. package/dist/{chunk-KBOPY6W2.js → chunk-VKYEEJJ2.js} +2 -2
  105. package/dist/{chunk-7RCZ436O.js → chunk-VMYXYFPX.js} +2 -2
  106. package/dist/{chunk-5BS6IQZZ.js → chunk-VWPJX5B3.js} +5 -5
  107. package/dist/{chunk-JIF3IBRK.js → chunk-VYLC5KAT.js} +2 -2
  108. package/dist/{chunk-OIIAXFKM.js → chunk-WFC2GHJG.js} +3 -3
  109. package/dist/{chunk-NYSD43OE.js → chunk-WKT7NNNR.js} +4 -4
  110. package/dist/{chunk-BP4I7IBK.js → chunk-WRGNEAUZ.js} +2 -2
  111. package/dist/{chunk-47ZFULEZ.js → chunk-WUNRUSBJ.js} +2 -2
  112. package/dist/{chunk-L6FSZFG7.js → chunk-XPTYXXMD.js} +3 -3
  113. package/dist/{chunk-EG6AQBYW.js → chunk-XZZIZ544.js} +8 -8
  114. package/dist/{chunk-RORE2GX2.js → chunk-YF3CIA6E.js} +2 -2
  115. package/dist/{chunk-AQF7JSQR.js → chunk-YOMI3ZCA.js} +2 -2
  116. package/dist/{chunk-A3NTKHDB.js → chunk-ZAZW5LLF.js} +2 -2
  117. package/dist/{chunk-32O2N2CH.js → chunk-ZUDIY7YP.js} +7 -7
  118. package/dist/classified/index.js +5 -5
  119. package/dist/{classified-marker-PMDG3O36.js → classified-marker-EPL2NX3H.js} +3 -3
  120. package/dist/collection-facade-3DN4ETEP.js +45 -0
  121. package/dist/{computed-UHCBRILW.js → computed-UXN4AMI5.js} +3 -3
  122. package/dist/consent/index.js +9 -9
  123. package/dist/cover/index.js +9 -9
  124. package/dist/custody/index.js +11 -11
  125. package/dist/{dead-filter-777VWDER.js → dead-filter-56AYTNAO.js} +2 -2
  126. package/dist/debug/index.js +1 -1
  127. package/dist/{delegation-4R5DU23X.js → delegation-MCCWCFZA.js} +11 -11
  128. package/dist/derivations/index.js +12 -12
  129. package/dist/derive-BSAF6N5X.js +22 -0
  130. package/dist/directory/index.js +10 -10
  131. package/dist/{dispatch-ASL257KG.js → dispatch-JM7X5BLP.js} +5 -5
  132. package/dist/{dispatch-3EN6YCCS.js → dispatch-UPZW4MAO.js} +18 -18
  133. package/dist/{enclave-ZJS5R5RH.js → enclave-CCXI3WEU.js} +11 -9
  134. package/dist/executor-6YQYFGHK.js +9 -0
  135. package/dist/executor-GLKPMISJ.js +9 -0
  136. package/dist/executor-ZEIX7Y7I.js +29 -0
  137. package/dist/export-accessible-SDIQEFHQ.js +23 -0
  138. package/dist/extract-partition-K232SO2V.js +38 -0
  139. package/dist/{fanout-sidecar-TFPWDOME.js → fanout-sidecar-2EHAV6UP.js} +9 -9
  140. package/dist/find-GKFC5753.js +11 -0
  141. package/dist/forget/index.js +9 -9
  142. package/dist/guards/index.js +7 -7
  143. package/dist/history/index.js +13 -13
  144. package/dist/i18n/index.js +14 -14
  145. package/dist/index.d.ts +2 -1
  146. package/dist/index.js +98 -94
  147. package/dist/index.js.map +1 -1
  148. package/dist/indexing/index.js +4 -4
  149. package/dist/introspection/index.js +11 -11
  150. package/dist/issue-QTQYQJCB.js +19 -0
  151. package/dist/kernel/constants.d.ts +18 -0
  152. package/dist/kernel/enclave/index.d.ts +1 -0
  153. package/dist/kernel/enclave/record-keys/rekey-blob.d.ts +88 -0
  154. package/dist/kernel/errors.d.ts +48 -1
  155. package/dist/kernel/noydb.d.ts +18 -1
  156. package/dist/kernel/query/builder.d.ts +36 -2
  157. package/dist/kernel/query/live.d.ts +31 -9
  158. package/dist/kernel/query/predicate.d.ts +9 -0
  159. package/dist/kernel/types.d.ts +20 -6
  160. package/dist/kernel/vault.d.ts +1 -1
  161. package/dist/{ledger-62CEPRPX.js → ledger-TZIDVW22.js} +11 -11
  162. package/dist/liberate-FOK7RFYQ.js +24 -0
  163. package/dist/{link-set-ZRYNUHN3.js → link-set-VOMRQB2H.js} +11 -11
  164. package/dist/{managed-secret-T2WB4O47.js → managed-secret-N6FWB5LX.js} +10 -10
  165. package/dist/materialized-views/index.js +22 -22
  166. package/dist/migrate-cek-UEO2EUWI.js +19 -0
  167. package/dist/migrate-cek-UEO2EUWI.js.map +1 -0
  168. package/dist/money/index.js +5 -5
  169. package/dist/noydb-3BBLBSHI.js +84 -0
  170. package/dist/overlay-views/index.js +4 -4
  171. package/dist/periods/index.js +12 -12
  172. package/dist/pod/index.js +58 -58
  173. package/dist/{pod-handle-UPLXOGIK.js → pod-handle-D6ZRTO4N.js} +9 -9
  174. package/dist/policy/index.js +10 -10
  175. package/dist/port/with/team-strategy.d.ts +5 -1
  176. package/dist/portability/index.js +8 -8
  177. package/dist/{post-register-J4DEVNXK.js → post-register-XVGHYYSB.js} +6 -6
  178. package/dist/query/index.js +6 -6
  179. package/dist/reduce/index.js +6 -6
  180. package/dist/register-FVUE46K4.js +32 -0
  181. package/dist/registry-7PBVHSD5.js +19 -0
  182. package/dist/registry-CCXD57GV.js +18 -0
  183. package/dist/registry-K75FRKSU.js +9 -0
  184. package/dist/registry-KZYPKIOF.js +9 -0
  185. package/dist/request-withdrawal-WS7PXD7B.js +31 -0
  186. package/dist/{reveal-525XWQU2.js → reveal-Z62PLVJT.js} +6 -6
  187. package/dist/revoke-JH4VQTJ3.js +24 -0
  188. package/dist/satellites/index.js +1 -1
  189. package/dist/schema-update/index.js +2 -2
  190. package/dist/sealed-record/index.js +12 -12
  191. package/dist/search/index.js +4 -4
  192. package/dist/{seed-SGIF3EN4.js → seed-R2JK2YQK.js} +11 -11
  193. package/dist/sequence/index.js +9 -9
  194. package/dist/session/index.js +9 -9
  195. package/dist/shadow/index.js +2 -2
  196. package/dist/signer-AFV6AXSN.js +25 -0
  197. package/dist/snapshots/index.js +10 -10
  198. package/dist/{stale-PQYPVCER.js → stale-FVK3WRMM.js} +10 -10
  199. package/dist/storage-EIM5HO2O.js +23 -0
  200. package/dist/{store-coordination-provider-TFHZLKHG.js → store-coordination-provider-HIPOZMC2.js} +10 -10
  201. package/dist/sync/index.js +10 -10
  202. package/dist/team/index.js +15 -15
  203. package/dist/tiers/index.js +11 -11
  204. package/dist/to/index.js +1 -1
  205. package/dist/transactions/index.js +3 -3
  206. package/dist/util/index.js +1 -1
  207. package/dist/vault-head/index.js +8 -8
  208. package/dist/{verify-J6DEOXP3.js → verify-KYICK5IW.js} +5 -5
  209. package/dist/walk-FV6JFWXV.js +21 -0
  210. package/dist/with-party/team/keyring.d.ts +132 -0
  211. package/dist/with-party/team/noydb-facade.d.ts +5 -1
  212. package/dist/with-party/team/roster-tag.d.ts +101 -0
  213. package/dist/with-shape/blobs/blob-set.d.ts +61 -9
  214. package/dist/withdraw-accessible-JYX3SPVY.js +28 -0
  215. package/package.json +4 -3
  216. package/dist/api-Z5VHH24A.js +0 -20
  217. package/dist/chunk-3Y4OFWQJ.js.map +0 -1
  218. package/dist/chunk-5J5TTSGW.js.map +0 -1
  219. package/dist/chunk-6TXUVKPG.js.map +0 -1
  220. package/dist/chunk-D5UDZANO.js.map +0 -1
  221. package/dist/chunk-F5AJZC3U.js.map +0 -1
  222. package/dist/chunk-IGJCYUT5.js.map +0 -1
  223. package/dist/chunk-IOURTXTM.js.map +0 -1
  224. package/dist/chunk-KUXTWVAR.js.map +0 -1
  225. package/dist/chunk-P7L3OQLL.js.map +0 -1
  226. package/dist/chunk-RKDH6L53.js.map +0 -1
  227. package/dist/collection-facade-ZJK5EB33.js +0 -45
  228. package/dist/derive-3WAS2G5T.js +0 -22
  229. package/dist/executor-GPM6DNWV.js +0 -9
  230. package/dist/executor-LJSMZ4IB.js +0 -9
  231. package/dist/executor-SHUVRZUJ.js +0 -29
  232. package/dist/export-accessible-GNY6DC6U.js +0 -23
  233. package/dist/extract-partition-BG3AF4NZ.js +0 -38
  234. package/dist/find-KX6OKHDP.js +0 -11
  235. package/dist/issue-PAUM7NCX.js +0 -19
  236. package/dist/liberate-I6AOLWXW.js +0 -24
  237. package/dist/noydb-SS6EN7TK.js +0 -84
  238. package/dist/register-UPD4GKBC.js +0 -32
  239. package/dist/registry-7KX2HWFS.js +0 -18
  240. package/dist/registry-PKYYEHEW.js +0 -9
  241. package/dist/registry-XHCYMD34.js +0 -19
  242. package/dist/registry-XIRTZHPC.js +0 -9
  243. package/dist/request-withdrawal-XZSESWZV.js +0 -31
  244. package/dist/revoke-QI7YHQ2B.js +0 -24
  245. package/dist/signer-BZWDPGGN.js +0 -25
  246. package/dist/storage-MJHKNQRO.js +0 -23
  247. package/dist/walk-BX4NSB5L.js +0 -21
  248. package/dist/withdraw-accessible-K4CPMH4C.js +0 -28
  249. /package/dist/{api-Z5VHH24A.js.map → api-D6DBNTOS.js.map} +0 -0
  250. /package/dist/{backup-K62BFMYK.js.map → backup-4PZAH67W.js.map} +0 -0
  251. /package/dist/{chunk-IPDS2TYW.js.map → chunk-23XKHFNT.js.map} +0 -0
  252. /package/dist/{chunk-GYUCRDAU.js.map → chunk-2DFE4TUE.js.map} +0 -0
  253. /package/dist/{chunk-2IK6AC6A.js.map → chunk-2VMCJUK6.js.map} +0 -0
  254. /package/dist/{chunk-DKYEVHZH.js.map → chunk-3ENNPCIW.js.map} +0 -0
  255. /package/dist/{chunk-REL4OLWW.js.map → chunk-3TWEXEKX.js.map} +0 -0
  256. /package/dist/{chunk-RNSC2ARR.js.map → chunk-47F6AI2K.js.map} +0 -0
  257. /package/dist/{chunk-L2XQ776M.js.map → chunk-4BYZIQ5T.js.map} +0 -0
  258. /package/dist/{chunk-NH2MST6J.js.map → chunk-4IPP2P74.js.map} +0 -0
  259. /package/dist/{chunk-M4IKEOJS.js.map → chunk-4O52JH3C.js.map} +0 -0
  260. /package/dist/{chunk-GDGTIWB4.js.map → chunk-4RZTW5JH.js.map} +0 -0
  261. /package/dist/{chunk-WKD5ESK4.js.map → chunk-6QMOJTC6.js.map} +0 -0
  262. /package/dist/{chunk-BTNKPDZM.js.map → chunk-6ZGDIN2D.js.map} +0 -0
  263. /package/dist/{chunk-KDX6VEYV.js.map → chunk-7JOXCSDU.js.map} +0 -0
  264. /package/dist/{chunk-S55DBWRC.js.map → chunk-A5YEUQOY.js.map} +0 -0
  265. /package/dist/{chunk-DJ23QZIN.js.map → chunk-AELW6OJZ.js.map} +0 -0
  266. /package/dist/{chunk-YOT7D63X.js.map → chunk-AGETRKC5.js.map} +0 -0
  267. /package/dist/{chunk-W6NFONOV.js.map → chunk-ANYVM4SX.js.map} +0 -0
  268. /package/dist/{chunk-CADUYBQD.js.map → chunk-ATL3ZVXT.js.map} +0 -0
  269. /package/dist/{chunk-GILI76SU.js.map → chunk-BFNBYT62.js.map} +0 -0
  270. /package/dist/{chunk-N7YAQKAO.js.map → chunk-BPLSGN4X.js.map} +0 -0
  271. /package/dist/{chunk-ZPMXYPBR.js.map → chunk-BXHG26KN.js.map} +0 -0
  272. /package/dist/{chunk-437FDIHO.js.map → chunk-CW3VJARJ.js.map} +0 -0
  273. /package/dist/{chunk-ODVIFBAQ.js.map → chunk-D5EXZVQC.js.map} +0 -0
  274. /package/dist/{chunk-PZSS7MUM.js.map → chunk-DIYI32MG.js.map} +0 -0
  275. /package/dist/{chunk-SFD2LL7G.js.map → chunk-DUUARUZI.js.map} +0 -0
  276. /package/dist/{chunk-OWGEHDT2.js.map → chunk-ESXVNASI.js.map} +0 -0
  277. /package/dist/{chunk-MNMYHZVU.js.map → chunk-F3BICEMK.js.map} +0 -0
  278. /package/dist/{chunk-HJRTFXAA.js.map → chunk-FFSQFH6D.js.map} +0 -0
  279. /package/dist/{chunk-GT72D4FO.js.map → chunk-FGZ7GJXO.js.map} +0 -0
  280. /package/dist/{chunk-WBNXZU42.js.map → chunk-FHEVZQQY.js.map} +0 -0
  281. /package/dist/{chunk-VHVMJWM6.js.map → chunk-FKZI4NSG.js.map} +0 -0
  282. /package/dist/{chunk-TENLCGYD.js.map → chunk-FUIG7QSS.js.map} +0 -0
  283. /package/dist/{chunk-ZBDWKPBW.js.map → chunk-GWJJ5CK3.js.map} +0 -0
  284. /package/dist/{chunk-MNUTPZRQ.js.map → chunk-H27DIXOV.js.map} +0 -0
  285. /package/dist/{chunk-ZXW3X3DQ.js.map → chunk-H3SEW5HB.js.map} +0 -0
  286. /package/dist/{chunk-ICCRAPWD.js.map → chunk-H6K24KLL.js.map} +0 -0
  287. /package/dist/{chunk-DYASJSKI.js.map → chunk-HRSEAGLI.js.map} +0 -0
  288. /package/dist/{chunk-XGQGWZ6D.js.map → chunk-HZIIDYJV.js.map} +0 -0
  289. /package/dist/{chunk-GQ3BX5EA.js.map → chunk-I3ISCYT7.js.map} +0 -0
  290. /package/dist/{chunk-N2HKBESK.js.map → chunk-IPA6ODWG.js.map} +0 -0
  291. /package/dist/{chunk-OQLYMBJI.js.map → chunk-IUQPNAGR.js.map} +0 -0
  292. /package/dist/{chunk-YVTADFTC.js.map → chunk-JPVJTTHU.js.map} +0 -0
  293. /package/dist/{chunk-JHO6FGZX.js.map → chunk-KMGAFLCK.js.map} +0 -0
  294. /package/dist/{chunk-5EJQNA26.js.map → chunk-KYUKZIW5.js.map} +0 -0
  295. /package/dist/{chunk-HGJC7I5F.js.map → chunk-L2YYIQYR.js.map} +0 -0
  296. /package/dist/{chunk-KM6YR5XF.js.map → chunk-LLLSK7UQ.js.map} +0 -0
  297. /package/dist/{chunk-QPIUFRUC.js.map → chunk-M3FKPVOU.js.map} +0 -0
  298. /package/dist/{chunk-CV7WXCZD.js.map → chunk-M7VSXBUL.js.map} +0 -0
  299. /package/dist/{chunk-APV42WPR.js.map → chunk-MBZFAJKM.js.map} +0 -0
  300. /package/dist/{chunk-SG3OQCRG.js.map → chunk-MQFKH3ZJ.js.map} +0 -0
  301. /package/dist/{chunk-ZWKF3CD3.js.map → chunk-NB2CKJ27.js.map} +0 -0
  302. /package/dist/{chunk-HTHRCGWP.js.map → chunk-NCAMIRFB.js.map} +0 -0
  303. /package/dist/{chunk-VH2W6BOG.js.map → chunk-NHXIFF4Y.js.map} +0 -0
  304. /package/dist/{chunk-VJ4B3ZXY.js.map → chunk-O5QXH7U7.js.map} +0 -0
  305. /package/dist/{chunk-MQXYR65M.js.map → chunk-OBPL43F3.js.map} +0 -0
  306. /package/dist/{chunk-HTMQBBF3.js.map → chunk-OCW3IM2F.js.map} +0 -0
  307. /package/dist/{chunk-E6VDPBE3.js.map → chunk-OIW75CLW.js.map} +0 -0
  308. /package/dist/{chunk-NRNTXBHT.js.map → chunk-OTHHO3KI.js.map} +0 -0
  309. /package/dist/{chunk-4HVTRHSA.js.map → chunk-OZ5QBLEL.js.map} +0 -0
  310. /package/dist/{chunk-ZVAFJQZB.js.map → chunk-PENPHA45.js.map} +0 -0
  311. /package/dist/{chunk-CVYXIN5B.js.map → chunk-PGHSH4TY.js.map} +0 -0
  312. /package/dist/{chunk-A4K5GLE6.js.map → chunk-PWK3SSNB.js.map} +0 -0
  313. /package/dist/{chunk-5JT4Y5UE.js.map → chunk-QK2QAMF7.js.map} +0 -0
  314. /package/dist/{chunk-PG6PFMDC.js.map → chunk-QMJI5VHV.js.map} +0 -0
  315. /package/dist/{chunk-RQY5UWEL.js.map → chunk-QTWWZ25B.js.map} +0 -0
  316. /package/dist/{chunk-RSFG7XHM.js.map → chunk-REKDM67V.js.map} +0 -0
  317. /package/dist/{chunk-2E2MKBMI.js.map → chunk-REQJLII3.js.map} +0 -0
  318. /package/dist/{chunk-TC6MBEGH.js.map → chunk-RJYPFCID.js.map} +0 -0
  319. /package/dist/{chunk-EJIVFOOQ.js.map → chunk-RT7CWTUG.js.map} +0 -0
  320. /package/dist/{chunk-6S466CMQ.js.map → chunk-SRR22EW2.js.map} +0 -0
  321. /package/dist/{chunk-C7WJNVJG.js.map → chunk-TKLQWOTY.js.map} +0 -0
  322. /package/dist/{chunk-SA77BQ7F.js.map → chunk-UQUWSM33.js.map} +0 -0
  323. /package/dist/{chunk-KBOPY6W2.js.map → chunk-VKYEEJJ2.js.map} +0 -0
  324. /package/dist/{chunk-7RCZ436O.js.map → chunk-VMYXYFPX.js.map} +0 -0
  325. /package/dist/{chunk-5BS6IQZZ.js.map → chunk-VWPJX5B3.js.map} +0 -0
  326. /package/dist/{chunk-JIF3IBRK.js.map → chunk-VYLC5KAT.js.map} +0 -0
  327. /package/dist/{chunk-OIIAXFKM.js.map → chunk-WFC2GHJG.js.map} +0 -0
  328. /package/dist/{chunk-NYSD43OE.js.map → chunk-WKT7NNNR.js.map} +0 -0
  329. /package/dist/{chunk-BP4I7IBK.js.map → chunk-WRGNEAUZ.js.map} +0 -0
  330. /package/dist/{chunk-47ZFULEZ.js.map → chunk-WUNRUSBJ.js.map} +0 -0
  331. /package/dist/{chunk-L6FSZFG7.js.map → chunk-XPTYXXMD.js.map} +0 -0
  332. /package/dist/{chunk-EG6AQBYW.js.map → chunk-XZZIZ544.js.map} +0 -0
  333. /package/dist/{chunk-RORE2GX2.js.map → chunk-YF3CIA6E.js.map} +0 -0
  334. /package/dist/{chunk-AQF7JSQR.js.map → chunk-YOMI3ZCA.js.map} +0 -0
  335. /package/dist/{chunk-A3NTKHDB.js.map → chunk-ZAZW5LLF.js.map} +0 -0
  336. /package/dist/{chunk-32O2N2CH.js.map → chunk-ZUDIY7YP.js.map} +0 -0
  337. /package/dist/{classified-marker-PMDG3O36.js.map → classified-marker-EPL2NX3H.js.map} +0 -0
  338. /package/dist/{collection-facade-ZJK5EB33.js.map → collection-facade-3DN4ETEP.js.map} +0 -0
  339. /package/dist/{computed-UHCBRILW.js.map → computed-UXN4AMI5.js.map} +0 -0
  340. /package/dist/{dead-filter-777VWDER.js.map → dead-filter-56AYTNAO.js.map} +0 -0
  341. /package/dist/{delegation-4R5DU23X.js.map → delegation-MCCWCFZA.js.map} +0 -0
  342. /package/dist/{derive-3WAS2G5T.js.map → derive-BSAF6N5X.js.map} +0 -0
  343. /package/dist/{dispatch-ASL257KG.js.map → dispatch-JM7X5BLP.js.map} +0 -0
  344. /package/dist/{dispatch-3EN6YCCS.js.map → dispatch-UPZW4MAO.js.map} +0 -0
  345. /package/dist/{enclave-ZJS5R5RH.js.map → enclave-CCXI3WEU.js.map} +0 -0
  346. /package/dist/{executor-GPM6DNWV.js.map → executor-6YQYFGHK.js.map} +0 -0
  347. /package/dist/{executor-LJSMZ4IB.js.map → executor-GLKPMISJ.js.map} +0 -0
  348. /package/dist/{executor-SHUVRZUJ.js.map → executor-ZEIX7Y7I.js.map} +0 -0
  349. /package/dist/{export-accessible-GNY6DC6U.js.map → export-accessible-SDIQEFHQ.js.map} +0 -0
  350. /package/dist/{extract-partition-BG3AF4NZ.js.map → extract-partition-K232SO2V.js.map} +0 -0
  351. /package/dist/{fanout-sidecar-TFPWDOME.js.map → fanout-sidecar-2EHAV6UP.js.map} +0 -0
  352. /package/dist/{find-KX6OKHDP.js.map → find-GKFC5753.js.map} +0 -0
  353. /package/dist/{issue-PAUM7NCX.js.map → issue-QTQYQJCB.js.map} +0 -0
  354. /package/dist/{ledger-62CEPRPX.js.map → ledger-TZIDVW22.js.map} +0 -0
  355. /package/dist/{liberate-I6AOLWXW.js.map → liberate-FOK7RFYQ.js.map} +0 -0
  356. /package/dist/{link-set-ZRYNUHN3.js.map → link-set-VOMRQB2H.js.map} +0 -0
  357. /package/dist/{managed-secret-T2WB4O47.js.map → managed-secret-N6FWB5LX.js.map} +0 -0
  358. /package/dist/{noydb-SS6EN7TK.js.map → noydb-3BBLBSHI.js.map} +0 -0
  359. /package/dist/{pod-handle-UPLXOGIK.js.map → pod-handle-D6ZRTO4N.js.map} +0 -0
  360. /package/dist/{post-register-J4DEVNXK.js.map → post-register-XVGHYYSB.js.map} +0 -0
  361. /package/dist/{register-UPD4GKBC.js.map → register-FVUE46K4.js.map} +0 -0
  362. /package/dist/{registry-7KX2HWFS.js.map → registry-7PBVHSD5.js.map} +0 -0
  363. /package/dist/{registry-PKYYEHEW.js.map → registry-CCXD57GV.js.map} +0 -0
  364. /package/dist/{registry-XHCYMD34.js.map → registry-K75FRKSU.js.map} +0 -0
  365. /package/dist/{registry-XIRTZHPC.js.map → registry-KZYPKIOF.js.map} +0 -0
  366. /package/dist/{request-withdrawal-XZSESWZV.js.map → request-withdrawal-WS7PXD7B.js.map} +0 -0
  367. /package/dist/{reveal-525XWQU2.js.map → reveal-Z62PLVJT.js.map} +0 -0
  368. /package/dist/{revoke-QI7YHQ2B.js.map → revoke-JH4VQTJ3.js.map} +0 -0
  369. /package/dist/{seed-SGIF3EN4.js.map → seed-R2JK2YQK.js.map} +0 -0
  370. /package/dist/{signer-BZWDPGGN.js.map → signer-AFV6AXSN.js.map} +0 -0
  371. /package/dist/{stale-PQYPVCER.js.map → stale-FVK3WRMM.js.map} +0 -0
  372. /package/dist/{storage-MJHKNQRO.js.map → storage-EIM5HO2O.js.map} +0 -0
  373. /package/dist/{store-coordination-provider-TFHZLKHG.js.map → store-coordination-provider-HIPOZMC2.js.map} +0 -0
  374. /package/dist/{verify-J6DEOXP3.js.map → verify-KYICK5IW.js.map} +0 -0
  375. /package/dist/{walk-BX4NSB5L.js.map → walk-FV6JFWXV.js.map} +0 -0
  376. /package/dist/{withdraw-accessible-K4CPMH4C.js.map → withdraw-accessible-JYX3SPVY.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/with-party/team/deed.ts","../src/with-party/custody/liberate.ts"],"sourcesContent":["/**\n * FR-6 — Deed: sealed / hidden-owner provisioning.\n *\n * A **Deed** is a vault owned by a *latent* principal who never\n * authenticates. The owner credential (the random secret that\n * derives `KEK_owner`) is minted machine-side and sealed under a\n * **non-firm** {@link SealingKeyProvider} — that sealing boundary is\n * the cryptographic *inalienability anchor*: whoever holds the\n * provider (the client / their KMS) is the only party that can ever\n * re-derive `KEK_owner`. A firm-side custodian operates the vault\n * fully but can never reach the owner key — there is deliberately NO\n * firm-controlled fallback.\n *\n * Provisioning reuses the managed-mode seam:\n * - {@link resolveManagedSecret} mints + seals + persists the random\n * secret at `_meta/sealed-secret` (and unseals it on every\n * subsequent open through the same provider).\n * - {@link createOwnerKeyring} derives `KEK_owner` from that\n * secret and writes the `_keyring/<ownerUserId>` file.\n *\n * On top of that, a Deed writes a `_meta/deed` **marker**. The marker\n * is PLAINTEXT metadata — it records WHO the latent owner is and WHICH\n * sealing boundary protects them, so it must be readable without\n * unlocking the vault (a custodian or auditor inspecting the vault must\n * be able to see \"this is a Deed vault, owner = X, sealed under Y\"\n * without any key). The marker itself is therefore never sealed; only\n * the owner *credential* is.\n *\n * @module\n */\n\nimport { buildRecordEnvelope } from '../../kernel/enclave/index.js'\nimport type { NoydbStore } from '../../kernel/types.js'\nimport type { UnlockedKeyring } from './keyring.js'\nimport { createOwnerKeyring } from './keyring.js'\nimport type { SealingKeyProvider } from './managed-secret.js'\nimport { resolveManagedSecret } from './managed-secret.js'\n\n/** Reserved id for the Deed marker under `_meta`. */\nexport const DEED_RECORD_ID = 'deed' as const\n\n/**\n * Plaintext metadata recording a vault's latent-owner Deed. Persisted\n * at `_meta/deed`. Readable without unlocking the vault by design — it\n * carries no secret material, only the identity of the latent owner\n * and the sealing boundary that anchors inalienability.\n */\nexport interface DeedMarker {\n /** The latent owner principal — the user id of the `_keyring/<id>` owner file. */\n readonly ownerUserId: string\n /**\n * The `SealingKeyProvider.id` the owner credential is sealed under.\n * The inalienability anchor: only the holder of this (non-firm)\n * provider can re-derive `KEK_owner`. Audit metadata — never secret.\n */\n readonly sealedUnder: string\n /** Always `true` for a Deed — the owner never authenticates interactively. */\n readonly latent: true\n /** ISO-8601 timestamp the Deed was issued. */\n readonly issuedAt: string\n /**\n * ISO-8601 timestamp the vault was liberated (a new owner claimed it\n * via the audited Liberate ceremony), if any. Absent until liberation.\n */\n readonly liberatedAt?: string\n}\n\n/**\n * Wire-format payload stored inside the `_meta/deed` envelope. Carries\n * a magic marker for forensics + the {@link DeedMarker} fields. JSON,\n * AES-GCM bypassed (the marker is plaintext metadata by design).\n */\ninterface DeedEnvelopePayload extends DeedMarker {\n readonly _noydb_deed: 1\n}\n\n/**\n * Provision a Deed: a latent owner whose credential is sealed under\n * `sealing` (a NON-firm provider). Mints + seals the owner secret\n * via {@link resolveManagedSecret}, derives the owner keyring via\n * {@link createOwnerKeyring}, then writes the plaintext `_meta/deed`\n * marker. Returns the unlocked owner keyring.\n *\n * The returned keyring is the only in-memory window onto `KEK_owner`\n * for this call; the persistent re-entry point is the sealing provider\n * (re-run {@link resolveManagedSecret} with the same provider to\n * re-resolve the secret, then {@link createOwnerKeyring}/load to\n * unlock — no interactive secret is ever required).\n *\n * There is deliberately no firm-controlled fallback: the marker's\n * `sealedUnder` is the single cryptographic anchor of ownership.\n */\nexport async function createDeedOwner(\n store: NoydbStore,\n vault: string,\n ownerUserId: string,\n sealing: SealingKeyProvider,\n): Promise<UnlockedKeyring> {\n // 1. Mint + seal + persist the random owner secret under the\n // non-firm provider (writes _meta/sealed-secret).\n const secret = await resolveManagedSecret(store, vault, sealing)\n\n // 2. Derive KEK_owner from the (never-human-seen) secret and\n // write the owner keyring file.\n const keyring = await createOwnerKeyring(store, vault, { userId: ownerUserId, secret: secret })\n\n // 3. Write the plaintext Deed marker. NOT sealed — it is audit\n // metadata that must be readable without unlocking.\n await saveDeedMarker(store, vault, {\n ownerUserId,\n sealedUnder: sealing.id,\n latent: true,\n issuedAt: new Date().toISOString(),\n })\n\n return keyring\n}\n\n/**\n * Read the {@link DeedMarker} from `_meta/deed`, or `null` if the vault\n * has no Deed marker (i.e. it is not a Deed vault). Plaintext read — no\n * unlocking required.\n */\nexport async function loadDeedMarker(\n store: NoydbStore,\n vault: string,\n): Promise<DeedMarker | null> {\n const envelope = await store.get(vault, '_meta', DEED_RECORD_ID)\n if (!envelope) return null\n let payload: unknown\n try {\n payload = JSON.parse(envelope._data)\n } catch {\n return null\n }\n if (typeof payload !== 'object' || payload === null) return null\n const r = payload as Record<string, unknown>\n if (r._noydb_deed !== 1) return null\n if (\n typeof r.ownerUserId !== 'string'\n || typeof r.sealedUnder !== 'string'\n || r.latent !== true\n || typeof r.issuedAt !== 'string'\n ) {\n return null\n }\n const marker: DeedMarker = {\n ownerUserId: r.ownerUserId,\n sealedUnder: r.sealedUnder,\n latent: true,\n issuedAt: r.issuedAt,\n ...(typeof r.liberatedAt === 'string' ? { liberatedAt: r.liberatedAt } : {}),\n }\n return marker\n}\n\n/** Whether `vault` carries a Deed marker (a sealed/latent owner). */\nexport async function isDeedVault(\n store: NoydbStore,\n vault: string,\n): Promise<boolean> {\n return (await loadDeedMarker(store, vault)) !== null\n}\n\n/**\n * Persist a {@link DeedMarker} at `_meta/deed`. Mirrors\n * `saveSealedSecret`'s envelope shape: a standard\n * {@link EncryptedEnvelope} with AES-GCM bypassed (`_iv: ''`), the\n * payload stored as plaintext JSON in `_data`. The marker is metadata,\n * not a secret — sealing it would defeat its purpose (auditors /\n * custodians must read it without a key).\n *\n * @internal — used by `createDeedOwner` and (later) the Liberate\n * ceremony to stamp `liberatedAt`.\n */\nexport async function saveDeedMarker(\n store: NoydbStore,\n vault: string,\n marker: DeedMarker,\n): Promise<void> {\n const persisted: DeedEnvelopePayload = { _noydb_deed: 1, ...marker }\n const prior = await store.get(vault, '_meta', DEED_RECORD_ID)\n const env = buildRecordEnvelope(\n { collection: '_meta', id: DEED_RECORD_ID, version: (prior?._v ?? 0) + 1 },\n // AES-GCM bypassed — the marker is plaintext audit metadata.\n { iv: '', data: JSON.stringify(persisted) },\n )\n await store.put(vault, '_meta', DEED_RECORD_ID, env)\n}\n","/**\n * `liberateVault` — the audited claim of ownership over a\n * sealed-owner (Deed) vault. The inverse of withdrawal.\n *\n * A **Deed** vault's owner credential is sealed under a non-firm provider, so\n * the firm-side **custodian** (which holds every collection DEK and operates\n * the vault fully) can never reach `KEK_owner`. Liberation is the ONLY route\n * by which a custodian assumes ownership, and it is deliberately a manual,\n * audited ceremony:\n *\n * 1. gate `'liberate-vault'` (fail-closed)\n * 2. caller MUST be the `custodian` (the de-facto authority holding the DEKs)\n * 3. freeze a PRE-liberation EVIDENCE snapshot (hash-pinned in the ledger) —\n * but PRESERVE the live data for the new owner (see the freeze decision\n * below)\n * 4. mint a NEW owner keyring re-wrapping the incumbent DEKs under the new\n * owner's KEK\n * 5. lifecycle ledger `liberation-claimed:<newOwnerId>:<legalBasis>`\n * 6. stamp the `_meta/deed` marker with `liberatedAt`\n *\n * ## Security: the inalienability floor\n *\n * Liberation **mints a new owner from the custodian's DEKs** — it does NOT\n * unseal the original sealed owner. The old sealed-owner credential is left\n * untouched and ORPHANED (its `_keyring/<id>` file remains, its KEK is still\n * sealed under the non-firm provider), never impersonated. The new owner is a\n * DISTINCT principal under a fresh KEK derived from `newOwnerSecret`. This\n * preserves the inalienability floor: the act of claiming ownership is itself\n * auditable and produces a different principal, rather than silently assuming\n * the latent owner's identity.\n *\n * ## Freeze decision: snapshot-only, not freeze-and-delete\n *\n * `freezeAndDeleteClosure` (withdraw-accessible.ts) writes a hash-pinned\n * snapshot and THEN delete-closures the live records — correct for a\n * destructive withdrawal, WRONG for liberation. Liberation transfers\n * operational continuity; it must leave the live data intact for the new\n * owner. We therefore call the snapshot-only core `freezeSnapshotOnly`\n * (factored out of that module; the freeze-AND-delete withdrawal path is\n * unchanged) to pin the evidence snapshot while preserving the records.\n *\n * @module\n */\n\nimport type { Vault } from '../../kernel/vault.js'\nimport type { FactorProofBundle, KeyringFile } from '../../kernel/types.js'\nimport { PermissionDeniedError } from '../../kernel/errors.js'\nimport { wrapKey } from '../../kernel/enclave/index.js'\nimport { createOwnerKeyring } from '../team/keyring.js'\nimport type { FrozenSnapshotRef } from '../../with-audit/portability/withdraw-accessible.js'\nimport { freezeSnapshotOnly } from '../../with-audit/portability/withdraw-accessible.js'\nimport { loadDeedMarker, saveDeedMarker } from '../team/deed.js'\n\nexport interface LiberateOptions {\n /** The id of the new owner principal the custodian mints by claiming ownership. */\n readonly newOwnerId: string\n /** The secret that derives the new owner's KEK (the DEKs are re-wrapped under it). */\n readonly newOwnerSecret: string\n /** Legal/contractual basis recorded in the audit (e.g. 'contractual-handover'). */\n readonly legalBasis: string\n readonly factors?: FactorProofBundle\n}\n\nexport interface LiberateResult {\n /** The hash-pinned pre-liberation evidence snapshot. */\n readonly snapshot: FrozenSnapshotRef\n}\n\n/**\n * Audited claim of ownership over a sealed-owner vault by its custodian. See\n * the module doc for the full ceremony + security rationale.\n */\nexport async function liberateVault(\n vault: Vault,\n opts: LiberateOptions,\n): Promise<LiberateResult> {\n // 1. gate — fail-closed `liberate-vault`.\n await vault.noydb.checkGate(vault.name, 'liberate-vault', opts.factors)\n\n // 2. caller must be the custodian (the de-facto authority holding the DEKs).\n const { name: vaultName, adapter, keyring } = vault._introspectState()\n if (keyring.role !== 'custodian') {\n throw new PermissionDeniedError(\n 'liberation is claimed only by the custodian (the de-facto authority holding the DEKs)',\n )\n }\n\n // Refuse to clobber an existing principal: the new owner must be a FRESH id.\n // (Checked before any side effect so a colliding id never leaves a half-run\n // ceremony — no orphan snapshot, no partial keyring overwrite.)\n const existing = await adapter.get(vaultName, '_keyring', opts.newOwnerId)\n if (existing) {\n throw new PermissionDeniedError(\n `liberateVault: newOwnerId \"${opts.newOwnerId}\" already exists as a principal; choose a fresh id (liberation mints a distinct owner, it never overwrites an existing keyring)`,\n )\n }\n\n // 3. Pre-liberation EVIDENCE snapshot of every operational collection —\n // snapshot-only (live data preserved for the new owner; liberation\n // transfers operational continuity, it does not erase).\n const collections = await listOperationalCollections(vault)\n const snapshot = await freezeSnapshotOnly(vault, collections, { actorUserId: keyring.userId })\n\n // 4. Mint a NEW owner keyring, re-wrapping the incumbent DEKs under the new\n // owner's fresh KEK. The old sealed owner is NOT unsealed — a DISTINCT\n // principal is minted and the original owner credential is left orphaned\n // (inalienability floor). Mirrors adopt-partition.ts's DEK re-wrap.\n const newOwner = await createOwnerKeyring(adapter, vaultName, { userId: opts.newOwnerId, secret: opts.newOwnerSecret })\n if (!newOwner.kek) {\n throw new PermissionDeniedError(\n `new owner keyring for \"${opts.newOwnerId}\" has no KEK to re-wrap the incumbent DEKs under`,\n )\n }\n const env = await adapter.get(vaultName, '_keyring', opts.newOwnerId)\n if (!env) {\n throw new PermissionDeniedError(`new owner keyring for \"${opts.newOwnerId}\" did not persist`)\n }\n const keyringFile = JSON.parse(env._data) as KeyringFile\n const mergedDeks: Record<string, string> = { ...keyringFile.deks }\n for (const [collection, dek] of keyring.deks) {\n mergedDeks[collection] = await wrapKey(dek, newOwner.kek)\n }\n const mergedFile: KeyringFile = { ...keyringFile, deks: mergedDeks }\n await adapter.put(vaultName, '_keyring', opts.newOwnerId, { ...env, _data: JSON.stringify(mergedFile) })\n\n // 5. Lifecycle ledger audit (no-op if the history strategy is absent).\n await vault._getLedgerOrNull()?.append({\n op: 'lifecycle', collection: '', id: '', version: 0, actor: opts.newOwnerId, payloadHash: '',\n reason: `liberation-claimed:${opts.newOwnerId}:${opts.legalBasis}`,\n })\n\n // 6. Stamp the Deed marker with `liberatedAt` (if a marker exists).\n const marker = await loadDeedMarker(adapter, vaultName)\n if (marker) {\n await saveDeedMarker(adapter, vaultName, { ...marker, liberatedAt: new Date().toISOString() })\n }\n\n return { snapshot }\n}\n\n/**\n * Enumerate the vault's operational (user-facing) collections — those carried\n * by the caller's keyring DEK map, minus the reserved internal collections\n * (`_*`). These are the collections frozen into the evidence snapshot.\n */\nasync function listOperationalCollections(vault: Vault): Promise<readonly string[]> {\n const { keyring } = vault._introspectState()\n return [...keyring.deks.keys()].filter((c) => !c.startsWith('_'))\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/with-party/team/deed.ts","../src/with-party/custody/liberate.ts"],"sourcesContent":["/**\n * FR-6 — Deed: sealed / hidden-owner provisioning.\n *\n * A **Deed** is a vault owned by a *latent* principal who never\n * authenticates. The owner credential (the random secret that\n * derives `KEK_owner`) is minted machine-side and sealed under a\n * **non-firm** {@link SealingKeyProvider} — that sealing boundary is\n * the cryptographic *inalienability anchor*: whoever holds the\n * provider (the client / their KMS) is the only party that can ever\n * re-derive `KEK_owner`. A firm-side custodian operates the vault\n * fully but can never reach the owner key — there is deliberately NO\n * firm-controlled fallback.\n *\n * Provisioning reuses the managed-mode seam:\n * - {@link resolveManagedSecret} mints + seals + persists the random\n * secret at `_meta/sealed-secret` (and unseals it on every\n * subsequent open through the same provider).\n * - {@link createOwnerKeyring} derives `KEK_owner` from that\n * secret and writes the `_keyring/<ownerUserId>` file.\n *\n * On top of that, a Deed writes a `_meta/deed` **marker**. The marker\n * is PLAINTEXT metadata — it records WHO the latent owner is and WHICH\n * sealing boundary protects them, so it must be readable without\n * unlocking the vault (a custodian or auditor inspecting the vault must\n * be able to see \"this is a Deed vault, owner = X, sealed under Y\"\n * without any key). The marker itself is therefore never sealed; only\n * the owner *credential* is.\n *\n * @module\n */\n\nimport { buildRecordEnvelope } from '../../kernel/enclave/index.js'\nimport type { NoydbStore } from '../../kernel/types.js'\nimport type { UnlockedKeyring } from './keyring.js'\nimport { createOwnerKeyring } from './keyring.js'\nimport type { SealingKeyProvider } from './managed-secret.js'\nimport { resolveManagedSecret } from './managed-secret.js'\n\n/** Reserved id for the Deed marker under `_meta`. */\nexport const DEED_RECORD_ID = 'deed' as const\n\n/**\n * Plaintext metadata recording a vault's latent-owner Deed. Persisted\n * at `_meta/deed`. Readable without unlocking the vault by design — it\n * carries no secret material, only the identity of the latent owner\n * and the sealing boundary that anchors inalienability.\n */\nexport interface DeedMarker {\n /** The latent owner principal — the user id of the `_keyring/<id>` owner file. */\n readonly ownerUserId: string\n /**\n * The `SealingKeyProvider.id` the owner credential is sealed under.\n * The inalienability anchor: only the holder of this (non-firm)\n * provider can re-derive `KEK_owner`. Audit metadata — never secret.\n */\n readonly sealedUnder: string\n /** Always `true` for a Deed — the owner never authenticates interactively. */\n readonly latent: true\n /** ISO-8601 timestamp the Deed was issued. */\n readonly issuedAt: string\n /**\n * ISO-8601 timestamp the vault was liberated (a new owner claimed it\n * via the audited Liberate ceremony), if any. Absent until liberation.\n */\n readonly liberatedAt?: string\n}\n\n/**\n * Wire-format payload stored inside the `_meta/deed` envelope. Carries\n * a magic marker for forensics + the {@link DeedMarker} fields. JSON,\n * AES-GCM bypassed (the marker is plaintext metadata by design).\n */\ninterface DeedEnvelopePayload extends DeedMarker {\n readonly _noydb_deed: 1\n}\n\n/**\n * Provision a Deed: a latent owner whose credential is sealed under\n * `sealing` (a NON-firm provider). Mints + seals the owner secret\n * via {@link resolveManagedSecret}, derives the owner keyring via\n * {@link createOwnerKeyring}, then writes the plaintext `_meta/deed`\n * marker. Returns the unlocked owner keyring.\n *\n * The returned keyring is the only in-memory window onto `KEK_owner`\n * for this call; the persistent re-entry point is the sealing provider\n * (re-run {@link resolveManagedSecret} with the same provider to\n * re-resolve the secret, then {@link createOwnerKeyring}/load to\n * unlock — no interactive secret is ever required).\n *\n * There is deliberately no firm-controlled fallback: the marker's\n * `sealedUnder` is the single cryptographic anchor of ownership.\n */\nexport async function createDeedOwner(\n store: NoydbStore,\n vault: string,\n ownerUserId: string,\n sealing: SealingKeyProvider,\n): Promise<UnlockedKeyring> {\n // 1. Mint + seal + persist the random owner secret under the\n // non-firm provider (writes _meta/sealed-secret).\n const secret = await resolveManagedSecret(store, vault, sealing)\n\n // 2. Derive KEK_owner from the (never-human-seen) secret and\n // write the owner keyring file.\n const keyring = await createOwnerKeyring(store, vault, { userId: ownerUserId, secret: secret })\n\n // 3. Write the plaintext Deed marker. NOT sealed — it is audit\n // metadata that must be readable without unlocking.\n await saveDeedMarker(store, vault, {\n ownerUserId,\n sealedUnder: sealing.id,\n latent: true,\n issuedAt: new Date().toISOString(),\n })\n\n return keyring\n}\n\n/**\n * Read the {@link DeedMarker} from `_meta/deed`, or `null` if the vault\n * has no Deed marker (i.e. it is not a Deed vault). Plaintext read — no\n * unlocking required.\n */\nexport async function loadDeedMarker(\n store: NoydbStore,\n vault: string,\n): Promise<DeedMarker | null> {\n const envelope = await store.get(vault, '_meta', DEED_RECORD_ID)\n if (!envelope) return null\n let payload: unknown\n try {\n payload = JSON.parse(envelope._data)\n } catch {\n return null\n }\n if (typeof payload !== 'object' || payload === null) return null\n const r = payload as Record<string, unknown>\n if (r._noydb_deed !== 1) return null\n if (\n typeof r.ownerUserId !== 'string'\n || typeof r.sealedUnder !== 'string'\n || r.latent !== true\n || typeof r.issuedAt !== 'string'\n ) {\n return null\n }\n const marker: DeedMarker = {\n ownerUserId: r.ownerUserId,\n sealedUnder: r.sealedUnder,\n latent: true,\n issuedAt: r.issuedAt,\n ...(typeof r.liberatedAt === 'string' ? { liberatedAt: r.liberatedAt } : {}),\n }\n return marker\n}\n\n/** Whether `vault` carries a Deed marker (a sealed/latent owner). */\nexport async function isDeedVault(\n store: NoydbStore,\n vault: string,\n): Promise<boolean> {\n return (await loadDeedMarker(store, vault)) !== null\n}\n\n/**\n * Persist a {@link DeedMarker} at `_meta/deed`. Mirrors\n * `saveSealedSecret`'s envelope shape: a standard\n * {@link EncryptedEnvelope} with AES-GCM bypassed (`_iv: ''`), the\n * payload stored as plaintext JSON in `_data`. The marker is metadata,\n * not a secret — sealing it would defeat its purpose (auditors /\n * custodians must read it without a key).\n *\n * @internal — used by `createDeedOwner` and (later) the Liberate\n * ceremony to stamp `liberatedAt`.\n */\nexport async function saveDeedMarker(\n store: NoydbStore,\n vault: string,\n marker: DeedMarker,\n): Promise<void> {\n const persisted: DeedEnvelopePayload = { _noydb_deed: 1, ...marker }\n const prior = await store.get(vault, '_meta', DEED_RECORD_ID)\n const env = buildRecordEnvelope(\n { collection: '_meta', id: DEED_RECORD_ID, version: (prior?._v ?? 0) + 1 },\n // AES-GCM bypassed — the marker is plaintext audit metadata.\n { iv: '', data: JSON.stringify(persisted) },\n )\n await store.put(vault, '_meta', DEED_RECORD_ID, env)\n}\n","/**\n * `liberateVault` — the audited claim of ownership over a\n * sealed-owner (Deed) vault. The inverse of withdrawal.\n *\n * A **Deed** vault's owner credential is sealed under a non-firm provider, so\n * the firm-side **custodian** (which holds every collection DEK and operates\n * the vault fully) can never reach `KEK_owner`. Liberation is the ONLY route\n * by which a custodian assumes ownership, and it is deliberately a manual,\n * audited ceremony:\n *\n * 1. gate `'liberate-vault'` (fail-closed)\n * 2. caller MUST be the `custodian` (the de-facto authority holding the DEKs)\n * 3. freeze a PRE-liberation EVIDENCE snapshot (hash-pinned in the ledger) —\n * but PRESERVE the live data for the new owner (see the freeze decision\n * below)\n * 4. mint a NEW owner keyring re-wrapping the incumbent DEKs under the new\n * owner's KEK\n * 5. lifecycle ledger `liberation-claimed:<newOwnerId>:<legalBasis>`\n * 6. stamp the `_meta/deed` marker with `liberatedAt`\n *\n * ## Security: the inalienability floor\n *\n * Liberation **mints a new owner from the custodian's DEKs** — it does NOT\n * unseal the original sealed owner. The old sealed-owner credential is left\n * untouched and ORPHANED (its `_keyring/<id>` file remains, its KEK is still\n * sealed under the non-firm provider), never impersonated. The new owner is a\n * DISTINCT principal under a fresh KEK derived from `newOwnerSecret`. This\n * preserves the inalienability floor: the act of claiming ownership is itself\n * auditable and produces a different principal, rather than silently assuming\n * the latent owner's identity.\n *\n * ## Freeze decision: snapshot-only, not freeze-and-delete\n *\n * `freezeAndDeleteClosure` (withdraw-accessible.ts) writes a hash-pinned\n * snapshot and THEN delete-closures the live records — correct for a\n * destructive withdrawal, WRONG for liberation. Liberation transfers\n * operational continuity; it must leave the live data intact for the new\n * owner. We therefore call the snapshot-only core `freezeSnapshotOnly`\n * (factored out of that module; the freeze-AND-delete withdrawal path is\n * unchanged) to pin the evidence snapshot while preserving the records.\n *\n * @module\n */\n\nimport type { Vault } from '../../kernel/vault.js'\nimport type { FactorProofBundle, KeyringFile } from '../../kernel/types.js'\nimport { PermissionDeniedError } from '../../kernel/errors.js'\nimport { wrapKey } from '../../kernel/enclave/index.js'\nimport { createOwnerKeyring, requireRosterKey } from '../team/keyring.js'\nimport { mintRosterTag, assertRosterTagValid } from '../team/roster-tag.js'\nimport type { FrozenSnapshotRef } from '../../with-audit/portability/withdraw-accessible.js'\nimport { freezeSnapshotOnly } from '../../with-audit/portability/withdraw-accessible.js'\nimport { loadDeedMarker, saveDeedMarker } from '../team/deed.js'\n\nexport interface LiberateOptions {\n /** The id of the new owner principal the custodian mints by claiming ownership. */\n readonly newOwnerId: string\n /** The secret that derives the new owner's KEK (the DEKs are re-wrapped under it). */\n readonly newOwnerSecret: string\n /** Legal/contractual basis recorded in the audit (e.g. 'contractual-handover'). */\n readonly legalBasis: string\n readonly factors?: FactorProofBundle\n}\n\nexport interface LiberateResult {\n /** The hash-pinned pre-liberation evidence snapshot. */\n readonly snapshot: FrozenSnapshotRef\n}\n\n/**\n * Audited claim of ownership over a sealed-owner vault by its custodian. See\n * the module doc for the full ceremony + security rationale.\n */\nexport async function liberateVault(\n vault: Vault,\n opts: LiberateOptions,\n): Promise<LiberateResult> {\n // 1. gate — fail-closed `liberate-vault`.\n await vault.noydb.checkGate(vault.name, 'liberate-vault', opts.factors)\n\n // 2. caller must be the custodian (the de-facto authority holding the DEKs).\n const { name: vaultName, adapter, keyring } = vault._introspectState()\n if (keyring.role !== 'custodian') {\n throw new PermissionDeniedError(\n 'liberation is claimed only by the custodian (the de-facto authority holding the DEKs)',\n )\n }\n\n // Refuse to clobber an existing principal: the new owner must be a FRESH id.\n // (Checked before any side effect so a colliding id never leaves a half-run\n // ceremony — no orphan snapshot, no partial keyring overwrite.)\n const existing = await adapter.get(vaultName, '_keyring', opts.newOwnerId)\n if (existing) {\n throw new PermissionDeniedError(\n `liberateVault: newOwnerId \"${opts.newOwnerId}\" already exists as a principal; choose a fresh id (liberation mints a distinct owner, it never overwrites an existing keyring)`,\n )\n }\n\n // 3. Pre-liberation EVIDENCE snapshot of every operational collection —\n // snapshot-only (live data preserved for the new owner; liberation\n // transfers operational continuity, it does not erase).\n const collections = await listOperationalCollections(vault)\n const snapshot = await freezeSnapshotOnly(vault, collections, { actorUserId: keyring.userId })\n\n // 4. Mint a NEW owner keyring, re-wrapping the incumbent DEKs under the new\n // owner's fresh KEK. The old sealed owner is NOT unsealed — a DISTINCT\n // principal is minted and the original owner credential is left orphaned\n // (inalienability floor). Mirrors adopt-partition.ts's DEK re-wrap.\n const newOwner = await createOwnerKeyring(adapter, vaultName, { userId: opts.newOwnerId, secret: opts.newOwnerSecret })\n if (!newOwner.kek) {\n throw new PermissionDeniedError(\n `new owner keyring for \"${opts.newOwnerId}\" has no KEK to re-wrap the incumbent DEKs under`,\n )\n }\n const env = await adapter.get(vaultName, '_keyring', opts.newOwnerId)\n if (!env) {\n throw new PermissionDeniedError(`new owner keyring for \"${opts.newOwnerId}\" did not persist`)\n }\n const keyringFile = JSON.parse(env._data) as KeyringFile\n // #1096 — this is a read-BACK of the file `createOwnerKeyring` just wrote, and\n // it is about to be edited and restamped, so the store gets a window to alter\n // it in between. Verified against the NEW owner's own roster key, not the\n // incumbent's: at this instant the file is still stamped under the fresh key\n // minted above (the swap to the incumbent key happens below).\n const mintedRosterKey = requireRosterKey(newOwner, 'liberateVault')\n await assertRosterTagValid(keyringFile, mintedRosterKey, opts.newOwnerId)\n const mergedDeks: Record<string, string> = { ...keyringFile.deks }\n for (const [collection, dek] of keyring.deks) {\n mergedDeks[collection] = await wrapKey(dek, newOwner.kek)\n }\n // #1096 — liberation joins a new owner to an EXISTING vault, so the vault's\n // roster key must stay the incumbent one. `createOwnerKeyring` above minted a\n // fresh roster key (correct for a new vault, wrong here), and the merge loop\n // has just overwritten `_roster` with the incumbent's — so the tag it stamped\n // no longer matches the key in the file. Restamp under the key that actually\n // ends up persisted, or the new owner cannot open the vault they just claimed.\n //\n // Keeping the incumbent key is the substantive half: a fresh one would leave\n // the new owner unable to verify any co-member's roster, and every co-member\n // unable to verify theirs.\n const rosterKey = requireRosterKey(keyring, 'liberateVault')\n const merged: KeyringFile = { ...keyringFile, deks: mergedDeks }\n const mergedFile: KeyringFile = { ...merged, roster_tag: await mintRosterTag(merged, rosterKey) }\n await adapter.put(vaultName, '_keyring', opts.newOwnerId, { ...env, _data: JSON.stringify(mergedFile) })\n\n // 5. Lifecycle ledger audit (no-op if the history strategy is absent).\n await vault._getLedgerOrNull()?.append({\n op: 'lifecycle', collection: '', id: '', version: 0, actor: opts.newOwnerId, payloadHash: '',\n reason: `liberation-claimed:${opts.newOwnerId}:${opts.legalBasis}`,\n })\n\n // 6. Stamp the Deed marker with `liberatedAt` (if a marker exists).\n const marker = await loadDeedMarker(adapter, vaultName)\n if (marker) {\n await saveDeedMarker(adapter, vaultName, { ...marker, liberatedAt: new Date().toISOString() })\n }\n\n return { snapshot }\n}\n\n/**\n * Enumerate the vault's operational (user-facing) collections — those carried\n * by the caller's keyring DEK map, minus the reserved internal collections\n * (`_*`). These are the collections frozen into the evidence snapshot.\n */\nasync function listOperationalCollections(vault: Vault): Promise<readonly string[]> {\n const { keyring } = vault._introspectState()\n return [...keyring.deks.keys()].filter((c) => !c.startsWith('_'))\n}\n"],"mappings":"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","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  BrokerNotEnabledError
3
- } from "./chunk-P7L3OQLL.js";
3
+ } from "./chunk-PKUJ3JLQ.js";
4
4
 
5
5
  // src/port/with/broker-strategy.ts
6
6
  var NO_BROKER = {
@@ -27,4 +27,4 @@ export {
27
27
  NO_BROKER,
28
28
  buildCredentialBrokerHandle
29
29
  };
30
- //# sourceMappingURL=chunk-KM6YR5XF.js.map
30
+ //# sourceMappingURL=chunk-LLLSK7UQ.js.map
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  loadVaultPolicy,
3
3
  saveVaultPolicy
4
- } from "./chunk-DKYEVHZH.js";
4
+ } from "./chunk-3ENNPCIW.js";
5
5
  import {
6
6
  PolicyDeniedError,
7
7
  ValidationError
8
- } from "./chunk-P7L3OQLL.js";
8
+ } from "./chunk-PKUJ3JLQ.js";
9
9
 
10
10
  // src/with-party/policy/presets.ts
11
11
  var PERSONAL_POLICY = Object.freeze({
@@ -364,4 +364,4 @@ export {
364
364
  describeGate,
365
365
  createNoydbPolicy
366
366
  };
367
- //# sourceMappingURL=chunk-QPIUFRUC.js.map
367
+ //# sourceMappingURL=chunk-M3FKPVOU.js.map
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  SCHEMAS_COLLECTION
3
- } from "./chunk-YVTADFTC.js";
3
+ } from "./chunk-JPVJTTHU.js";
4
4
  import {
5
5
  assemblePodContainer,
6
6
  buildExtractedPartitionWrapper
7
- } from "./chunk-2IK6AC6A.js";
7
+ } from "./chunk-2VMCJUK6.js";
8
8
  import {
9
9
  BLOB_CHUNKS_COLLECTION,
10
10
  BLOB_COLLECTION,
@@ -12,7 +12,7 @@ import {
12
12
  BLOB_INTENT_COLLECTION,
13
13
  BLOB_SLOTS_PREFIX,
14
14
  BLOB_VERSIONS_PREFIX
15
- } from "./chunk-IOURTXTM.js";
15
+ } from "./chunk-PNXJV4OS.js";
16
16
  import {
17
17
  generateULID
18
18
  } from "./chunk-4AOERLTV.js";
@@ -23,16 +23,16 @@ import {
23
23
  canonicalJson,
24
24
  envelopePayloadHash,
25
25
  hashEntry
26
- } from "./chunk-RNSC2ARR.js";
26
+ } from "./chunk-47F6AI2K.js";
27
27
  import {
28
28
  buildRecordAad,
29
29
  openEnvelopeJson,
30
30
  recordAadFor,
31
31
  writeEnvelopeBody
32
- } from "./chunk-D5UDZANO.js";
32
+ } from "./chunk-DIVPOJPV.js";
33
33
  import {
34
34
  buildRecordEnvelope
35
- } from "./chunk-ZVAFJQZB.js";
35
+ } from "./chunk-PENPHA45.js";
36
36
  import {
37
37
  bufferToBase64,
38
38
  decrypt,
@@ -42,13 +42,13 @@ import {
42
42
  generateDEK,
43
43
  unwrapCek,
44
44
  wrapCek
45
- } from "./chunk-VJ4B3ZXY.js";
45
+ } from "./chunk-O5QXH7U7.js";
46
46
  import {
47
47
  NOYDB_BACKUP_VERSION
48
- } from "./chunk-3Y4OFWQJ.js";
48
+ } from "./chunk-IGNJOJEP.js";
49
49
  import {
50
50
  PartitionExtractionError
51
- } from "./chunk-P7L3OQLL.js";
51
+ } from "./chunk-PKUJ3JLQ.js";
52
52
 
53
53
  // src/with-cargo/walk-closure.ts
54
54
  async function walkClosure(vault, opts) {
@@ -494,4 +494,4 @@ export {
494
494
  extractPartition,
495
495
  extractPartitionCore
496
496
  };
497
- //# sourceMappingURL=chunk-CV7WXCZD.js.map
497
+ //# sourceMappingURL=chunk-M7VSXBUL.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  MaterializedViewConfigError,
3
3
  ValidationError
4
- } from "./chunk-P7L3OQLL.js";
4
+ } from "./chunk-PKUJ3JLQ.js";
5
5
 
6
6
  // src/with-formula/materialized-views/with-materialized-view.ts
7
7
  function withMaterializedView(spec) {
@@ -177,4 +177,4 @@ function withMaterializedView(spec) {
177
177
  export {
178
178
  withMaterializedView
179
179
  };
180
- //# sourceMappingURL=chunk-APV42WPR.js.map
180
+ //# sourceMappingURL=chunk-MBZFAJKM.js.map
@@ -4,10 +4,10 @@ import {
4
4
  } from "./chunk-KHKKD62N.js";
5
5
  import {
6
6
  derivePersistedSchema
7
- } from "./chunk-N7YAQKAO.js";
7
+ } from "./chunk-BPLSGN4X.js";
8
8
  import {
9
9
  loadPersistedSchema
10
- } from "./chunk-YVTADFTC.js";
10
+ } from "./chunk-JPVJTTHU.js";
11
11
 
12
12
  // src/with-shape/introspection/walk.ts
13
13
  var INTERNAL_PREFIX = "_";
@@ -238,4 +238,4 @@ function summariseAggregateOp(value) {
238
238
  export {
239
239
  dumpVaultSchema
240
240
  };
241
- //# sourceMappingURL=chunk-SG3OQCRG.js.map
241
+ //# sourceMappingURL=chunk-MQFKH3ZJ.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  AttestationNotEnabledError
3
- } from "./chunk-P7L3OQLL.js";
3
+ } from "./chunk-PKUJ3JLQ.js";
4
4
 
5
5
  // src/with-audit/attestation/strategy.ts
6
6
  var NO_ATTESTATION = {
@@ -27,4 +27,4 @@ var NO_ATTESTATION = {
27
27
  export {
28
28
  NO_ATTESTATION
29
29
  };
30
- //# sourceMappingURL=chunk-ZWKF3CD3.js.map
30
+ //# sourceMappingURL=chunk-NB2CKJ27.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  ValidationError
3
- } from "./chunk-P7L3OQLL.js";
3
+ } from "./chunk-PKUJ3JLQ.js";
4
4
 
5
5
  // src/with-audit/periods/window.ts
6
6
  var PERIODS_COLLECTION = "_periods";
@@ -23,4 +23,4 @@ export {
23
23
  PERIOD_REOPENS_COLLECTION,
24
24
  periodExclusiveUpperBound
25
25
  };
26
- //# sourceMappingURL=chunk-HTHRCGWP.js.map
26
+ //# sourceMappingURL=chunk-NCAMIRFB.js.map
@@ -7,28 +7,28 @@ import {
7
7
  deriveSchemaManifest,
8
8
  loadSchemaManifestEntry,
9
9
  saveSchemaManifest
10
- } from "./chunk-E6VDPBE3.js";
10
+ } from "./chunk-OIW75CLW.js";
11
11
  import {
12
12
  MANIFEST_COLLECTION
13
13
  } from "./chunk-EPFF7LOX.js";
14
14
  import {
15
15
  loadFence,
16
16
  saveFence
17
- } from "./chunk-HJRTFXAA.js";
17
+ } from "./chunk-FFSQFH6D.js";
18
18
  import {
19
19
  derivePersistedSchema
20
- } from "./chunk-N7YAQKAO.js";
20
+ } from "./chunk-BPLSGN4X.js";
21
21
  import {
22
22
  loadPersistedSchemaEntry,
23
23
  savePersistedSchema
24
- } from "./chunk-YVTADFTC.js";
24
+ } from "./chunk-JPVJTTHU.js";
25
25
  import {
26
26
  envelopePayloadHash
27
- } from "./chunk-RNSC2ARR.js";
27
+ } from "./chunk-47F6AI2K.js";
28
28
  import {
29
29
  ManifestConflictError,
30
30
  isConflictError
31
- } from "./chunk-P7L3OQLL.js";
31
+ } from "./chunk-PKUJ3JLQ.js";
32
32
 
33
33
  // src/with-shape/persisted-schemas/field-ids.ts
34
34
  var BASE32URL_ALPHABET = "abcdefghijklmnopqrstuvwxyz234567";
@@ -257,4 +257,4 @@ export {
257
257
  persistClassifiedMarker,
258
258
  persistSatelliteMarker
259
259
  };
260
- //# sourceMappingURL=chunk-VH2W6BOG.js.map
260
+ //# sourceMappingURL=chunk-NHXIFF4Y.js.map
@@ -96,4 +96,4 @@ export {
96
96
  evaluateClause,
97
97
  hasFnClause
98
98
  };
99
- //# sourceMappingURL=chunk-IGJCYUT5.js.map
99
+ //# sourceMappingURL=chunk-NSITFOCJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/kernel/query/predicate.ts"],"sourcesContent":["/**\n * Operator implementations for the query DSL.\n *\n * All predicates run client-side, AFTER decryption — they never see ciphertext.\n * Field clauses over a Via-covered field (e.g. money) carry their own\n * evaluator closure (see {@link FieldClause.via}), so this module has no\n * dependency on any Via feature's implementation — still tree-shakeable.\n */\n\n/** Comparison operators supported by the where() builder. */\nexport type Operator =\n | '=='\n | '!='\n | '<'\n | '<='\n | '>'\n | '>='\n | 'in'\n | 'contains'\n | 'startsWith'\n | 'between'\n\n/**\n * A single field comparison clause inside a query plan.\n * Plans are JSON-serializable, so this type uses primitives only.\n */\nexport interface FieldClause {\n readonly type: 'field'\n readonly field: string\n readonly op: Operator\n readonly value: unknown\n /**\n * Present when `field` is covered by a Via feature binding (e.g. a\n * declared money field): the opaque payload built by the binding's\n * `buildClause` at query BUILD time, plus a closure that evaluates it\n * per record via the binding's `evaluateClause`. Attached by\n * `Query.where()` / `ScanBuilder.where()` when `source.via` covers the\n * field. The closure keeps this module free of any dependency on a\n * Via feature's implementation — clauses are in-memory only, never\n * serialized, so carrying a function here is safe.\n */\n readonly via?: {\n readonly brand: string\n readonly payload: unknown\n readonly evaluate: (actual: unknown, op: string) => boolean\n /**\n * The binding's `indexProbe` result for this clause's op/payload\n * (#625) — the STORED-form operand `candidateRecords()` (`kernel/\n * query/builder.ts`) can hand to `CollectionIndexes.lookupEqual`/\n * `lookupIn` for a fast path. `undefined` (no `indexProbe` hook, or\n * the binding declined to probe this op) means the field must fall\n * back to a linear scan via `evaluate` above.\n */\n readonly indexValue?: unknown\n }\n}\n\n/**\n * A user-supplied predicate function escape hatch. Not serializable.\n *\n * The predicate accepts `unknown` at the type level so the surrounding\n * Clause type can stay non-parametric — this keeps Collection<T> covariant\n * in T at the public API surface. Builder methods cast user predicates\n * (typed `(record: T) => boolean`) into this shape on the way in.\n */\nexport interface FilterClause {\n readonly type: 'filter'\n readonly fn: (record: unknown) => boolean\n}\n\n/**\n * A declared deterministic predicate reference. The query\n * builder produces this via `.wherePredicate(name, ctx?)` when a\n * Query has been augmented with a predicates map (typically by the\n * materialized-view registry).\n *\n * `predicateHash` is the consumer-supplied stable hash for the\n * function body; `ctxHash` is the canonical-JSON SHA-256 of `ctx`.\n * Both fold into the MV's `queryHash` so a function or ctx change\n * forces refresh on next visit.\n *\n * `fn` is resolved at builder time from the predicates map and\n * embedded directly — so `evaluateClause` can fire it without a\n * runtime lookup.\n */\nexport interface WherePredicateClause {\n readonly type: 'wherePredicate'\n readonly name: string\n readonly ctx: unknown\n readonly predicateHash: string\n readonly ctxHash: string\n readonly fn: (record: unknown, ctx?: unknown) => boolean\n}\n\n/** A logical group of clauses combined by AND or OR. */\nexport interface GroupClause {\n readonly type: 'group'\n readonly op: 'and' | 'or'\n readonly clauses: readonly Clause[]\n}\n\n/**\n * Cartesian-product expansion clause. Appended to `QueryPlan.clauses`\n * by `Query.crossJoin()`. Processed in declaration order by\n * `executeClausePipeline` — NOT by `evaluateClause` (which is a\n * per-record predicate and throws on this type).\n */\nexport interface CrossJoinClause {\n readonly type: 'crossJoin'\n /** Target collection name to cross-join against. */\n readonly target: string\n /** Alias under which the right-side record is exposed on each result row. */\n readonly as: string\n /**\n * Lateral filter callback. `undefined` → full cartesian product.\n * Two call shapes:\n * - Subset: `(left) => TTarget[]` — returns the right rows for this left row\n * - Predicate: `(left) => (right) => boolean` — executor materializes then filters\n */\n readonly on?: (left: unknown) => unknown[] | ((right: unknown) => boolean)\n /** When `on:` was supplied as `{ predicate: name }`, the name is stored here for queryHash. */\n readonly onPredicateName?: string\n /** Per-clause row ceiling override. `undefined` → `DEFAULT_CROSS_JOIN_MAX_ROWS`. */\n readonly maxRows?: number\n /**\n * Left-outer mode (#1130). When the `on:` subset for a left row is empty,\n * emit that row once with `null` under `as` instead of dropping it.\n *\n * Applies to both call shapes. With `on:` the empty thing is that left\n * row's subset; without it, an empty TARGET collection is what would\n * otherwise drop every left row.\n */\n readonly outer?: boolean\n}\n\nexport type Clause = FieldClause | FilterClause | WherePredicateClause | GroupClause | CrossJoinClause\n\n/**\n * Read a possibly nested field path like \"address.city\" from a record.\n * Returns undefined if any segment is missing.\n */\nexport function readPath(record: unknown, path: string): unknown {\n if (record === null || record === undefined) return undefined\n if (!path.includes('.')) {\n return (record as Record<string, unknown>)[path]\n }\n const segments = path.split('.')\n let cursor: unknown = record\n for (const segment of segments) {\n if (cursor === null || cursor === undefined) return undefined\n cursor = (cursor as Record<string, unknown>)[segment]\n }\n return cursor\n}\n\n/**\n * Evaluate a single field clause against a record.\n * Returns false on type mismatches rather than throwing — query results\n * exclude non-matching records by definition.\n */\nexport function evaluateFieldClause(record: unknown, clause: FieldClause): boolean {\n const actual = readPath(record, clause.field)\n const { op, value } = clause\n\n // A Via-covered field (e.g. money) may store a transformed\n // representation (money: BigInt-exact in scaled-integer space) that the\n // generic paths below can't compare correctly — the operand was\n // pre-built at query BUILD time and the binding's own evaluator knows\n // how to compare it against the raw stored value.\n if (clause.via) return clause.via.evaluate(actual, op)\n\n switch (op) {\n case '==':\n return actual === value\n case '!=':\n return actual !== value\n case '<':\n return isComparable(actual, value) && (actual as number) < (value as number)\n case '<=':\n return isComparable(actual, value) && (actual as number) <= (value as number)\n case '>':\n return isComparable(actual, value) && (actual as number) > (value as number)\n case '>=':\n return isComparable(actual, value) && (actual as number) >= (value as number)\n case 'in':\n return Array.isArray(value) && value.includes(actual)\n case 'contains':\n if (typeof actual === 'string') return typeof value === 'string' && actual.includes(value)\n if (Array.isArray(actual)) return actual.includes(value)\n return false\n case 'startsWith':\n return typeof actual === 'string' && typeof value === 'string' && actual.startsWith(value)\n case 'between': {\n if (!Array.isArray(value) || value.length !== 2) return false\n const [lo, hi] = value\n if (!isComparable(actual, lo) || !isComparable(actual, hi)) return false\n return (actual as number) >= (lo as number) && (actual as number) <= (hi as number)\n }\n default: {\n // Exhaustiveness — TS will error if a new operator is added without a case.\n const _exhaustive: never = op\n void _exhaustive\n return false\n }\n }\n}\n\n/**\n * Two values are \"comparable\" if they share an order-defined runtime type.\n * Strings compare lexicographically; numbers and Dates numerically; otherwise false.\n */\nfunction isComparable(a: unknown, b: unknown): boolean {\n if (typeof a === 'number' && typeof b === 'number') return true\n if (typeof a === 'string' && typeof b === 'string') return true\n if (a instanceof Date && b instanceof Date) return true\n return false\n}\n\n/**\n * Evaluate any clause (field / filter / group) against a record.\n * The recursion depth is bounded by the user's query expression — no risk of\n * blowing the stack on a 50K-record collection.\n *\n * `fnRecord`, when provided, is the view handed to USER CALLBACK clauses\n * (`filter` / `wherePredicate`) instead of `record` — the executor passes\n * the money-decoded view there so user code never sees the stored\n * scaled-int form, while field clauses keep evaluating against the raw\n * record (their money operands are pre-quantized to that space).\n */\nexport function evaluateClause(record: unknown, clause: Clause, fnRecord?: unknown): boolean {\n switch (clause.type) {\n case 'field':\n return evaluateFieldClause(record, clause)\n case 'filter':\n return clause.fn(fnRecord !== undefined ? fnRecord : record)\n case 'wherePredicate':\n return clause.fn(fnRecord !== undefined ? fnRecord : record, clause.ctx)\n case 'crossJoin':\n throw new Error(\n `evaluateClause: 'crossJoin' clauses are expansion primitives and are not ` +\n `evaluated per-record. This is a query planner routing error — ` +\n `crossJoin clauses must be extracted from the clause list before calling ` +\n `evaluateClause or filterRecords.`,\n )\n case 'group':\n if (clause.op === 'and') {\n for (const child of clause.clauses) {\n if (!evaluateClause(record, child, fnRecord)) return false\n }\n return true\n } else {\n for (const child of clause.clauses) {\n if (evaluateClause(record, child, fnRecord)) return true\n }\n return false\n }\n }\n}\n\n/**\n * Does the clause list contain any user-callback clause (filter /\n * wherePredicate), at any group nesting depth? Used by executors to\n * decide whether the per-record decoded view needs materializing.\n */\nexport function hasFnClause(clauses: readonly Clause[]): boolean {\n for (const c of clauses) {\n if (c.type === 'filter' || c.type === 'wherePredicate') return true\n if (c.type === 'group' && hasFnClause(c.clauses)) return true\n }\n return false\n}\n"],"mappings":";AA6IO,SAAS,SAAS,QAAiB,MAAuB;AAC/D,MAAI,WAAW,QAAQ,WAAW,OAAW,QAAO;AACpD,MAAI,CAAC,KAAK,SAAS,GAAG,GAAG;AACvB,WAAQ,OAAmC,IAAI;AAAA,EACjD;AACA,QAAM,WAAW,KAAK,MAAM,GAAG;AAC/B,MAAI,SAAkB;AACtB,aAAW,WAAW,UAAU;AAC9B,QAAI,WAAW,QAAQ,WAAW,OAAW,QAAO;AACpD,aAAU,OAAmC,OAAO;AAAA,EACtD;AACA,SAAO;AACT;AAOO,SAAS,oBAAoB,QAAiB,QAA8B;AACjF,QAAM,SAAS,SAAS,QAAQ,OAAO,KAAK;AAC5C,QAAM,EAAE,IAAI,MAAM,IAAI;AAOtB,MAAI,OAAO,IAAK,QAAO,OAAO,IAAI,SAAS,QAAQ,EAAE;AAErD,UAAQ,IAAI;AAAA,IACV,KAAK;AACH,aAAO,WAAW;AAAA,IACpB,KAAK;AACH,aAAO,WAAW;AAAA,IACpB,KAAK;AACH,aAAO,aAAa,QAAQ,KAAK,KAAM,SAAqB;AAAA,IAC9D,KAAK;AACH,aAAO,aAAa,QAAQ,KAAK,KAAM,UAAsB;AAAA,IAC/D,KAAK;AACH,aAAO,aAAa,QAAQ,KAAK,KAAM,SAAqB;AAAA,IAC9D,KAAK;AACH,aAAO,aAAa,QAAQ,KAAK,KAAM,UAAsB;AAAA,IAC/D,KAAK;AACH,aAAO,MAAM,QAAQ,KAAK,KAAK,MAAM,SAAS,MAAM;AAAA,IACtD,KAAK;AACH,UAAI,OAAO,WAAW,SAAU,QAAO,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK;AACzF,UAAI,MAAM,QAAQ,MAAM,EAAG,QAAO,OAAO,SAAS,KAAK;AACvD,aAAO;AAAA,IACT,KAAK;AACH,aAAO,OAAO,WAAW,YAAY,OAAO,UAAU,YAAY,OAAO,WAAW,KAAK;AAAA,IAC3F,KAAK,WAAW;AACd,UAAI,CAAC,MAAM,QAAQ,KAAK,KAAK,MAAM,WAAW,EAAG,QAAO;AACxD,YAAM,CAAC,IAAI,EAAE,IAAI;AACjB,UAAI,CAAC,aAAa,QAAQ,EAAE,KAAK,CAAC,aAAa,QAAQ,EAAE,EAAG,QAAO;AACnE,aAAQ,UAAsB,MAAkB,UAAsB;AAAA,IACxE;AAAA,IACA,SAAS;AAEP,YAAM,cAAqB;AAC3B,WAAK;AACL,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAMA,SAAS,aAAa,GAAY,GAAqB;AACrD,MAAI,OAAO,MAAM,YAAY,OAAO,MAAM,SAAU,QAAO;AAC3D,MAAI,OAAO,MAAM,YAAY,OAAO,MAAM,SAAU,QAAO;AAC3D,MAAI,aAAa,QAAQ,aAAa,KAAM,QAAO;AACnD,SAAO;AACT;AAaO,SAAS,eAAe,QAAiB,QAAgB,UAA6B;AAC3F,UAAQ,OAAO,MAAM;AAAA,IACnB,KAAK;AACH,aAAO,oBAAoB,QAAQ,MAAM;AAAA,IAC3C,KAAK;AACH,aAAO,OAAO,GAAG,aAAa,SAAY,WAAW,MAAM;AAAA,IAC7D,KAAK;AACH,aAAO,OAAO,GAAG,aAAa,SAAY,WAAW,QAAQ,OAAO,GAAG;AAAA,IACzE,KAAK;AACH,YAAM,IAAI;AAAA,QACR;AAAA,MAIF;AAAA,IACF,KAAK;AACH,UAAI,OAAO,OAAO,OAAO;AACvB,mBAAW,SAAS,OAAO,SAAS;AAClC,cAAI,CAAC,eAAe,QAAQ,OAAO,QAAQ,EAAG,QAAO;AAAA,QACvD;AACA,eAAO;AAAA,MACT,OAAO;AACL,mBAAW,SAAS,OAAO,SAAS;AAClC,cAAI,eAAe,QAAQ,OAAO,QAAQ,EAAG,QAAO;AAAA,QACtD;AACA,eAAO;AAAA,MACT;AAAA,EACJ;AACF;AAOO,SAAS,YAAY,SAAqC;AAC/D,aAAW,KAAK,SAAS;AACvB,QAAI,EAAE,SAAS,YAAY,EAAE,SAAS,iBAAkB,QAAO;AAC/D,QAAI,EAAE,SAAS,WAAW,YAAY,EAAE,OAAO,EAAG,QAAO;AAAA,EAC3D;AACA,SAAO;AACT;","names":[]}
@@ -3,7 +3,7 @@ import {
3
3
  InvalidKeyError,
4
4
  TamperedError,
5
5
  ValidationError
6
- } from "./chunk-P7L3OQLL.js";
6
+ } from "./chunk-PKUJ3JLQ.js";
7
7
 
8
8
  // src/kernel/enclave/crypto.ts
9
9
  var PBKDF2_ITERATIONS = 6e5;
@@ -439,4 +439,4 @@ export {
439
439
  bufferToBase64,
440
440
  base64ToBuffer
441
441
  };
442
- //# sourceMappingURL=chunk-VJ4B3ZXY.js.map
442
+ //# sourceMappingURL=chunk-O5QXH7U7.js.map
@@ -1,18 +1,18 @@
1
1
  import {
2
2
  installViaBinder
3
- } from "./chunk-KDX6VEYV.js";
3
+ } from "./chunk-7JOXCSDU.js";
4
4
  import {
5
5
  buildRecordAad
6
- } from "./chunk-D5UDZANO.js";
6
+ } from "./chunk-DIVPOJPV.js";
7
7
  import {
8
8
  buildRecordEnvelope
9
- } from "./chunk-ZVAFJQZB.js";
9
+ } from "./chunk-PENPHA45.js";
10
10
  import {
11
11
  encrypt
12
- } from "./chunk-VJ4B3ZXY.js";
12
+ } from "./chunk-O5QXH7U7.js";
13
13
  import {
14
14
  ValidationError
15
- } from "./chunk-P7L3OQLL.js";
15
+ } from "./chunk-PKUJ3JLQ.js";
16
16
 
17
17
  // src/via/blob/binding.ts
18
18
  async function eraseBlobs(ctx, cfg) {
@@ -391,4 +391,4 @@ export {
391
391
  BLOB_EVICTION_AUDIT_COLLECTION,
392
392
  runCompaction
393
393
  };
394
- //# sourceMappingURL=chunk-MQXYR65M.js.map
394
+ //# sourceMappingURL=chunk-OBPL43F3.js.map
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  dekKey
3
- } from "./chunk-47ZFULEZ.js";
3
+ } from "./chunk-WUNRUSBJ.js";
4
4
  import {
5
5
  TierNotGrantedError
6
- } from "./chunk-P7L3OQLL.js";
6
+ } from "./chunk-PKUJ3JLQ.js";
7
7
 
8
8
  // src/with-party/team/tiers.ts
9
9
  function assertTierAccess(keyring, collection, tier) {
@@ -17,4 +17,4 @@ function assertTierAccess(keyring, collection, tier) {
17
17
  export {
18
18
  assertTierAccess
19
19
  };
20
- //# sourceMappingURL=chunk-HTMQBBF3.js.map
20
+ //# sourceMappingURL=chunk-OCW3IM2F.js.map
@@ -3,22 +3,22 @@ import {
3
3
  } from "./chunk-EPFF7LOX.js";
4
4
  import {
5
5
  loadFence
6
- } from "./chunk-HJRTFXAA.js";
6
+ } from "./chunk-FFSQFH6D.js";
7
7
  import {
8
8
  SCHEMAS_COLLECTION,
9
9
  loadPersistedSchema
10
- } from "./chunk-YVTADFTC.js";
10
+ } from "./chunk-JPVJTTHU.js";
11
11
  import {
12
12
  canonicalJson,
13
13
  sha256Hex
14
- } from "./chunk-RNSC2ARR.js";
14
+ } from "./chunk-47F6AI2K.js";
15
15
  import {
16
16
  openEnvelopeJson,
17
17
  writeEnvelopeBody
18
- } from "./chunk-D5UDZANO.js";
18
+ } from "./chunk-DIVPOJPV.js";
19
19
  import {
20
20
  buildSealedRecordEnvelope
21
- } from "./chunk-ZVAFJQZB.js";
21
+ } from "./chunk-PENPHA45.js";
22
22
 
23
23
  // src/with-shape/manifest/types.ts
24
24
  var MANIFEST_SCHEMA_RECORD_ID = "schema";
@@ -86,4 +86,4 @@ export {
86
86
  saveSchemaManifest,
87
87
  deriveSchemaManifest
88
88
  };
89
- //# sourceMappingURL=chunk-E6VDPBE3.js.map
89
+ //# sourceMappingURL=chunk-OIW75CLW.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  buildRecordEnvelope
3
- } from "./chunk-ZVAFJQZB.js";
3
+ } from "./chunk-PENPHA45.js";
4
4
 
5
5
  // src/with-party/team/managed-secret.ts
6
6
  var MemorySealingKeyProvider = class {
@@ -224,4 +224,4 @@ export {
224
224
  loadSealedSecret,
225
225
  resolveManagedSecret
226
226
  };
227
- //# sourceMappingURL=chunk-NRNTXBHT.js.map
227
+ //# sourceMappingURL=chunk-OTHHO3KI.js.map
@@ -1,22 +1,22 @@
1
1
  import {
2
2
  ATTESTATIONS_COLLECTION,
3
3
  loadOrCreateSigner
4
- } from "./chunk-ZBDWKPBW.js";
4
+ } from "./chunk-GWJJ5CK3.js";
5
5
  import {
6
6
  generateULID
7
7
  } from "./chunk-4AOERLTV.js";
8
8
  import {
9
9
  buildRecordAad
10
- } from "./chunk-D5UDZANO.js";
10
+ } from "./chunk-DIVPOJPV.js";
11
11
  import {
12
12
  buildRecordEnvelope
13
- } from "./chunk-ZVAFJQZB.js";
13
+ } from "./chunk-PENPHA45.js";
14
14
  import {
15
15
  encrypt
16
- } from "./chunk-VJ4B3ZXY.js";
16
+ } from "./chunk-O5QXH7U7.js";
17
17
  import {
18
18
  AttestationError
19
- } from "./chunk-P7L3OQLL.js";
19
+ } from "./chunk-PKUJ3JLQ.js";
20
20
 
21
21
  // src/with-audit/attestation/issue.ts
22
22
  import {
@@ -63,4 +63,4 @@ async function issueAttestationCore(ctx, args) {
63
63
  export {
64
64
  issueAttestationCore
65
65
  };
66
- //# sourceMappingURL=chunk-4HVTRHSA.js.map
66
+ //# sourceMappingURL=chunk-OZ5QBLEL.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  NOYDB_FORMAT_VERSION
3
- } from "./chunk-3Y4OFWQJ.js";
3
+ } from "./chunk-IGNJOJEP.js";
4
4
 
5
5
  // src/kernel/enclave/record-envelope.ts
6
6
  function buildRecordEnvelope(identity, body) {
@@ -63,4 +63,4 @@ export {
63
63
  isDeleteMarker,
64
64
  buildDeleteMarker
65
65
  };
66
- //# sourceMappingURL=chunk-ZVAFJQZB.js.map
66
+ //# sourceMappingURL=chunk-PENPHA45.js.map
@@ -4,10 +4,10 @@ import {
4
4
  persistUserVisibility,
5
5
  readUserVisibility,
6
6
  saveUserEnvelope
7
- } from "./chunk-JHO6FGZX.js";
7
+ } from "./chunk-KMGAFLCK.js";
8
8
  import {
9
9
  PolicyDeniedError
10
- } from "./chunk-P7L3OQLL.js";
10
+ } from "./chunk-PKUJ3JLQ.js";
11
11
 
12
12
  // src/with-party/directory/user-envelope/api.ts
13
13
  var UserApi = class {
@@ -379,4 +379,4 @@ export {
379
379
  UserApi,
380
380
  createUserApi
381
381
  };
382
- //# sourceMappingURL=chunk-CVYXIN5B.js.map
382
+ //# sourceMappingURL=chunk-PGHSH4TY.js.map
@@ -2,6 +2,7 @@
2
2
  var STATE_VAULT_NAME = "__noydb_state__";
3
3
  var USER_ENVELOPE_MAX_BYTES = 64 * 1024;
4
4
  var USER_ENVELOPE_COLLECTION = "_users";
5
+ var ROSTER_KEY_ID = "_roster";
5
6
 
6
7
  // src/kernel/errors.ts
7
8
  var NoydbError = class extends Error {
@@ -76,6 +77,27 @@ var KeyringCorruptError = class extends NoydbError {
76
77
  this.intactCount = opts.intactCount;
77
78
  }
78
79
  };
80
+ function keyringTamperedMessage(userId, reason) {
81
+ const head = `Keyring for "${userId}" failed roster authentication (${reason}). `;
82
+ switch (reason) {
83
+ case "canary-missing":
84
+ case "roster-key-missing":
85
+ case "roster-tag-missing":
86
+ return head + "This vault was most likely written before 0.6.0-pre.21, which is when the roster became authenticated \u2014 that format change ships without a migration, so an existing vault must be re-seeded. The same state is what an untrusted store would produce by deleting the field to escape verification, and the two are indistinguishable from here, so access is refused either way. If this vault has been opened by 0.6.0-pre.21 or later before, treat it as the second case.";
87
+ case "unparseable":
88
+ return head + "The file did not parse \u2014 truncation or corruption in transit or at rest is the likeliest cause, and a store serving deliberate garbage is indistinguishable from it. `verifyRoster()` reports which members are affected; `quarantineKeyring()` removes one.";
89
+ case "roster-tag-mismatch":
90
+ return head + "The roster tag is present but does not match the authority fields it protects, so those fields were altered after they were signed. Unlike a missing tag this is not a format-transition state \u2014 no released version wrote a mismatched tag \u2014 so the store serving this vault, or something between you and it, has changed a member's role, permissions or expiry.";
91
+ }
92
+ }
93
+ var KeyringTamperedError = class extends NoydbError {
94
+ details;
95
+ constructor(details) {
96
+ super("KEYRING_TAMPERED", keyringTamperedMessage(details.userId, details.reason));
97
+ this.name = "KeyringTamperedError";
98
+ this.details = details;
99
+ }
100
+ };
79
101
  var NoAccessError = class extends NoydbError {
80
102
  constructor(message = "No access \u2014 user does not have a key for this collection") {
81
103
  super("NO_ACCESS", message);
@@ -1567,6 +1589,7 @@ export {
1567
1589
  STATE_VAULT_NAME,
1568
1590
  USER_ENVELOPE_MAX_BYTES,
1569
1591
  USER_ENVELOPE_COLLECTION,
1592
+ ROSTER_KEY_ID,
1570
1593
  NoydbError,
1571
1594
  DebugPlaintextError,
1572
1595
  DebugReservedFieldError,
@@ -1574,6 +1597,7 @@ export {
1574
1597
  TamperedError,
1575
1598
  InvalidKeyError,
1576
1599
  KeyringCorruptError,
1600
+ KeyringTamperedError,
1577
1601
  NoAccessError,
1578
1602
  ReadOnlyError,
1579
1603
  ReadOnlyAtInstantError,
@@ -1715,4 +1739,4 @@ export {
1715
1739
  ClassifiedRotationError,
1716
1740
  SatelliteConfigError
1717
1741
  };
1718
- //# sourceMappingURL=chunk-P7L3OQLL.js.map
1742
+ //# sourceMappingURL=chunk-PKUJ3JLQ.js.map