@noy-db/hub 0.7.0-pre.1 → 0.7.0-pre.10

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 (364) hide show
  1. package/CHANGELOG.md +198 -0
  2. package/README.md +4 -1
  3. package/dist/api-GJQF7OAJ.js +20 -0
  4. package/dist/as/index.js +11 -11
  5. package/dist/at/index.js +9 -9
  6. package/dist/attestation/index.js +18 -18
  7. package/dist/{backup-Z7ZBTAQ6.js → backup-QZQEP5RO.js} +12 -12
  8. package/dist/blobs/index.js +13 -13
  9. package/dist/broker/index.js +12 -12
  10. package/dist/by/index.js +2 -2
  11. package/dist/cargo/index.js +33 -30
  12. package/dist/{chunk-AB5P32RE.js → chunk-2DGBRE4K.js} +2 -2
  13. package/dist/{chunk-XVU7J43V.js → chunk-2E2LT37H.js} +2 -2
  14. package/dist/{chunk-4LPF226H.js → chunk-2MQ2D5OZ.js} +5 -5
  15. package/dist/{chunk-DBNYPLWY.js → chunk-357ECVLE.js} +3 -3
  16. package/dist/{chunk-SHILAQH5.js → chunk-3GIA3HJ2.js} +2 -2
  17. package/dist/{chunk-QGJ4XIA7.js → chunk-3SWP2FYA.js} +8 -8
  18. package/dist/{chunk-N4CNVSUF.js → chunk-4RUFYGWG.js} +2 -2
  19. package/dist/{chunk-4G25SDQL.js → chunk-4U52PMEL.js} +4 -4
  20. package/dist/{chunk-H7HP56F6.js → chunk-5EC7X5QA.js} +5 -5
  21. package/dist/{chunk-WK5FSW7T.js → chunk-5NKHCJU5.js} +8 -8
  22. package/dist/{chunk-PQ6Z2TAP.js → chunk-5UKIZIO3.js} +2 -2
  23. package/dist/{chunk-QHJKK77B.js → chunk-5W5CEHLA.js} +6 -6
  24. package/dist/{chunk-YPSOHDNC.js → chunk-65ZYRK7O.js} +2 -2
  25. package/dist/{chunk-4ZPE6SKS.js → chunk-75WNTBZL.js} +3 -3
  26. package/dist/{chunk-H4M7ADXY.js → chunk-7PC3DRG7.js} +27 -17
  27. package/dist/chunk-7PC3DRG7.js.map +1 -0
  28. package/dist/{chunk-OWLVBOWO.js → chunk-7XT7KZTN.js} +10 -10
  29. package/dist/{chunk-QI5NWLVW.js → chunk-AHIIBDNH.js} +7 -7
  30. package/dist/{chunk-XSN63FUS.js → chunk-AW4KTQA4.js} +2 -2
  31. package/dist/{chunk-KDJGJR7F.js → chunk-CWFH36SI.js} +2 -2
  32. package/dist/{chunk-X67FCULK.js → chunk-DIVY2CJZ.js} +3 -3
  33. package/dist/{chunk-Z2PWOSCJ.js → chunk-DNMTN46H.js} +2 -2
  34. package/dist/{chunk-2LPVI4PX.js → chunk-DOPZWTMJ.js} +20 -8
  35. package/dist/chunk-DOPZWTMJ.js.map +1 -0
  36. package/dist/{chunk-HTGRQZFB.js → chunk-DZPMKY3J.js} +3 -3
  37. package/dist/{chunk-XJ3FEKEY.js → chunk-FKQCC4C5.js} +2 -2
  38. package/dist/{chunk-E6YA6UAP.js → chunk-FLRLZ4XZ.js} +2 -2
  39. package/dist/{chunk-ALUNQEBY.js → chunk-FN26SFGH.js} +2 -2
  40. package/dist/{chunk-TVIFAHZR.js → chunk-FPN5D4JX.js} +6 -6
  41. package/dist/{chunk-VTG7327U.js → chunk-FRIVOR5N.js} +4 -4
  42. package/dist/{chunk-3QARDAYW.js → chunk-FYT3DXPN.js} +2 -2
  43. package/dist/{chunk-YMLQBZFJ.js → chunk-FZWAGG5T.js} +6 -6
  44. package/dist/{chunk-CBRS2NEK.js → chunk-GHADG5QZ.js} +2 -2
  45. package/dist/{chunk-3L2MVE36.js → chunk-GKOJR53Y.js} +5 -5
  46. package/dist/{chunk-Y6GZ2P4M.js → chunk-GM4IM7TC.js} +2 -2
  47. package/dist/{chunk-CN6B5PEN.js → chunk-H5GVPOB4.js} +5 -5
  48. package/dist/{chunk-467SKJ65.js → chunk-HOIWW2LV.js} +4 -4
  49. package/dist/{chunk-ALB64CZM.js → chunk-HS3LEVT4.js} +7 -7
  50. package/dist/{chunk-YXA2TCTZ.js → chunk-I5LSKXT6.js} +4 -4
  51. package/dist/{chunk-S35S77YU.js → chunk-IAHDSFFA.js} +10 -10
  52. package/dist/{chunk-X62MEF2O.js → chunk-IRHIA3AL.js} +3 -3
  53. package/dist/{chunk-F23WQK3G.js → chunk-IS5LFHV2.js} +7 -7
  54. package/dist/{chunk-POS53FG6.js → chunk-IZTU6RKH.js} +2 -2
  55. package/dist/{chunk-VAG47QHV.js → chunk-J6FXVDKC.js} +2 -2
  56. package/dist/{chunk-2GXEQUEX.js → chunk-JFSUYGNE.js} +2 -2
  57. package/dist/{chunk-LR4Z47QD.js → chunk-JILOSL4O.js} +3 -3
  58. package/dist/{chunk-RC4BROYR.js → chunk-JRWLUWDM.js} +3 -3
  59. package/dist/{chunk-Z2WK53N6.js → chunk-JUBWUJY5.js} +2 -2
  60. package/dist/{chunk-JVLSU7S2.js → chunk-JY4U6CYV.js} +2 -2
  61. package/dist/{chunk-3SMSERQU.js → chunk-KKZPQLDH.js} +80 -80
  62. package/dist/{chunk-WLLUM35R.js → chunk-KQIDBIZL.js} +2 -2
  63. package/dist/{chunk-LKFKXS5K.js → chunk-KZTPL7NL.js} +2 -2
  64. package/dist/{chunk-S2VG3ABP.js → chunk-LAI7ENPW.js} +3 -3
  65. package/dist/{chunk-ZO252Q5S.js → chunk-LUVGSKXE.js} +6 -6
  66. package/dist/{chunk-PGFKIOR3.js → chunk-MENI33ZV.js} +3 -3
  67. package/dist/{chunk-MTBXJAS4.js → chunk-MOQ6OGKS.js} +4 -4
  68. package/dist/{chunk-5ACAVJUI.js → chunk-MTTPHBIE.js} +2 -2
  69. package/dist/{chunk-T3PHCEN4.js → chunk-MU74BYOD.js} +3 -3
  70. package/dist/{chunk-DFAUMLD7.js → chunk-MV2OEK3K.js} +5 -5
  71. package/dist/{chunk-RK7N4OQ5.js → chunk-N4CHCXDL.js} +3 -1
  72. package/dist/chunk-N4CHCXDL.js.map +1 -0
  73. package/dist/{chunk-LF6DMX4C.js → chunk-NMDMSHBF.js} +3 -3
  74. package/dist/{chunk-H3VG6XBC.js → chunk-NUXTUGAD.js} +15 -13
  75. package/dist/chunk-NUXTUGAD.js.map +1 -0
  76. package/dist/{chunk-225O5CXQ.js → chunk-O3SNM66K.js} +2 -2
  77. package/dist/{chunk-YCSM3GZU.js → chunk-OEJ4R52I.js} +2 -2
  78. package/dist/{chunk-IESNYJXZ.js → chunk-OKCQNMO6.js} +6 -6
  79. package/dist/{chunk-H36KSN6X.js → chunk-OLUTCM23.js} +7 -7
  80. package/dist/{chunk-RDHUZ674.js → chunk-OQDHIAR2.js} +4 -4
  81. package/dist/{chunk-KN4W2OQ4.js → chunk-OXZSMX2H.js} +10 -8
  82. package/dist/{chunk-KN4W2OQ4.js.map → chunk-OXZSMX2H.js.map} +1 -1
  83. package/dist/{chunk-DKWPJOYH.js → chunk-P22XPNFW.js} +2 -2
  84. package/dist/{chunk-GK4DRVUD.js → chunk-P2RJAVMR.js} +4 -4
  85. package/dist/{chunk-UCUALOSM.js → chunk-P7KJME6C.js} +2 -2
  86. package/dist/{chunk-HM4JSXX2.js → chunk-PCIBCL26.js} +3 -3
  87. package/dist/{chunk-4A4TYISP.js → chunk-PV7XXAXK.js} +2 -2
  88. package/dist/{chunk-5AFMP532.js → chunk-Q2OAAREU.js} +6 -6
  89. package/dist/{chunk-Z7ZXZL6Y.js → chunk-Q2ZN5DWZ.js} +2 -2
  90. package/dist/{chunk-L6GTLZRK.js → chunk-QJLOWGOU.js} +5 -5
  91. package/dist/{chunk-7LYUJNU3.js → chunk-QOHGWFAW.js} +2 -2
  92. package/dist/{chunk-6FOGTKBY.js → chunk-RCONOOVF.js} +5 -5
  93. package/dist/{chunk-VFIWDPXZ.js → chunk-RPX2H2OL.js} +3 -3
  94. package/dist/{chunk-JBIV4FLR.js → chunk-SW4TOSJL.js} +5 -1
  95. package/dist/chunk-SW4TOSJL.js.map +1 -0
  96. package/dist/{chunk-PCQDY6QN.js → chunk-SWFIXQF5.js} +6 -6
  97. package/dist/{chunk-ISSU3OH6.js → chunk-T66OY2U5.js} +7 -7
  98. package/dist/{chunk-6EW2UCVF.js → chunk-TAJZ7GXO.js} +3 -3
  99. package/dist/{chunk-57JTHWLQ.js → chunk-TQGT5BZE.js} +4 -4
  100. package/dist/{chunk-TOV6VMHF.js → chunk-U3RMWOXY.js} +3 -3
  101. package/dist/{chunk-PUJTKLPL.js → chunk-UL7TLJ54.js} +3 -3
  102. package/dist/{chunk-W5LHQXZU.js → chunk-USKHHOIV.js} +2 -2
  103. package/dist/{chunk-J4MN6XIU.js → chunk-UTFY6W6X.js} +2 -2
  104. package/dist/{chunk-P6ASQOZR.js → chunk-VT4DTCK5.js} +2 -2
  105. package/dist/{chunk-A2YW5EMU.js → chunk-X6YRP5EC.js} +5 -5
  106. package/dist/{chunk-FOG7YEJP.js → chunk-XGXVPCYW.js} +3 -3
  107. package/dist/{chunk-5263OEM3.js → chunk-XJP66QEN.js} +2 -2
  108. package/dist/{chunk-5W7YXFV5.js → chunk-XJTGBHK6.js} +67 -22
  109. package/dist/chunk-XJTGBHK6.js.map +1 -0
  110. package/dist/{chunk-OPXR4PB2.js → chunk-XKA6UH5V.js} +2 -2
  111. package/dist/{chunk-XDVVBETV.js → chunk-YHIAWECL.js} +2 -2
  112. package/dist/{chunk-J4UJ5FRV.js → chunk-Z277MC2O.js} +4 -4
  113. package/dist/{chunk-F7ZFRPGQ.js → chunk-ZB2K3FV7.js} +2 -2
  114. package/dist/{chunk-NLKLXXTO.js → chunk-ZQGRZN5L.js} +2 -2
  115. package/dist/classified/index.js +5 -5
  116. package/dist/{classified-marker-BSQHU4JT.js → classified-marker-R37XW5PC.js} +3 -3
  117. package/dist/collection-facade-OPJ3EC4L.js +45 -0
  118. package/dist/{computed-ASBNTLOK.js → computed-HW6IG5UH.js} +3 -3
  119. package/dist/consent/index.js +9 -9
  120. package/dist/cover/index.js +9 -9
  121. package/dist/custody/index.js +12 -12
  122. package/dist/{dead-filter-QKU56XTQ.js → dead-filter-GRT6RAML.js} +2 -2
  123. package/dist/debug/index.js +1 -1
  124. package/dist/{delegation-XWRPYODW.js → delegation-6QRAYSK6.js} +11 -11
  125. package/dist/derivations/index.js +12 -12
  126. package/dist/derive-AAIXSQIE.js +22 -0
  127. package/dist/directory/index.js +10 -10
  128. package/dist/{dispatch-4AP4PUZU.js → dispatch-DR3XITEC.js} +18 -18
  129. package/dist/{dispatch-VR4LRXZ7.js → dispatch-QCF7KPIP.js} +5 -5
  130. package/dist/{enclave-NYPT7WA7.js → enclave-OXZY3NOP.js} +9 -9
  131. package/dist/executor-67NA4KPO.js +29 -0
  132. package/dist/executor-7JDP7UBK.js +9 -0
  133. package/dist/executor-CRH5OB4V.js +9 -0
  134. package/dist/export-accessible-K4GJAU7U.js +23 -0
  135. package/dist/extract-partition-YJFL5OKK.js +38 -0
  136. package/dist/{fanout-sidecar-IWP3R4RC.js → fanout-sidecar-KGQCUJ7P.js} +9 -9
  137. package/dist/find-SVZHMEQI.js +11 -0
  138. package/dist/forget/index.js +9 -9
  139. package/dist/guards/index.js +4 -4
  140. package/dist/history/index.js +13 -13
  141. package/dist/i18n/index.js +14 -14
  142. package/dist/index.d.ts +13 -1
  143. package/dist/index.js +98 -92
  144. package/dist/index.js.map +1 -1
  145. package/dist/indexing/index.js +2 -2
  146. package/dist/introspection/index.js +11 -11
  147. package/dist/issue-64N6OG7U.js +19 -0
  148. package/dist/kernel/errors.d.ts +17 -0
  149. package/dist/kernel/types.d.ts +75 -0
  150. package/dist/{ledger-T5K4P2D7.js → ledger-ZAFULLAF.js} +11 -11
  151. package/dist/liberate-QAUKHU6W.js +25 -0
  152. package/dist/{link-set-76JZ6YB4.js → link-set-LQI2IJX6.js} +11 -11
  153. package/dist/{managed-secret-6YC32VXG.js → managed-secret-7OH7HKXV.js} +10 -10
  154. package/dist/materialized-views/index.js +20 -20
  155. package/dist/{migrate-cek-LBRKYUZZ.js → migrate-cek-QHZ75E6E.js} +2 -2
  156. package/dist/money/index.js +4 -4
  157. package/dist/noydb-ZUS5XAFT.js +86 -0
  158. package/dist/overlay-views/index.js +4 -4
  159. package/dist/periods/index.js +12 -12
  160. package/dist/pod/index.js +57 -57
  161. package/dist/{pod-handle-P6DPBM5U.js → pod-handle-BLOI4IFY.js} +9 -9
  162. package/dist/policy/index.js +10 -10
  163. package/dist/port/to/index.d.ts +2 -0
  164. package/dist/portability/index.js +8 -8
  165. package/dist/{post-register-53O7AJRZ.js → post-register-R33EKJQR.js} +6 -6
  166. package/dist/query/index.js +3 -3
  167. package/dist/reduce/index.js +4 -4
  168. package/dist/register-AYBQNTM3.js +32 -0
  169. package/dist/registry-CQWWOBO4.js +9 -0
  170. package/dist/registry-JCZ4BNLV.js +18 -0
  171. package/dist/registry-JFFENZ44.js +9 -0
  172. package/dist/registry-ZA4HACYR.js +19 -0
  173. package/dist/request-withdrawal-7IKUIAEB.js +31 -0
  174. package/dist/{reveal-XBIMHAXR.js → reveal-PI6ADRQU.js} +6 -6
  175. package/dist/revoke-PUJKRYJF.js +24 -0
  176. package/dist/satellites/index.js +1 -1
  177. package/dist/schema-update/index.js +2 -2
  178. package/dist/sealed-record/index.js +12 -12
  179. package/dist/search/index.js +4 -4
  180. package/dist/{seed-NSNIGYXE.js → seed-MCCGVPRI.js} +12 -12
  181. package/dist/sequence/index.js +9 -9
  182. package/dist/session/index.js +9 -9
  183. package/dist/shadow/index.js +2 -2
  184. package/dist/signer-5TA7FUC3.js +25 -0
  185. package/dist/snapshots/index.js +10 -10
  186. package/dist/{stale-MCS46TFO.js → stale-HZR7745Y.js} +10 -10
  187. package/dist/storage-J2QHNJCB.js +23 -0
  188. package/dist/{store-coordination-provider-6FM26VQM.js → store-coordination-provider-MYIHSZXT.js} +10 -10
  189. package/dist/sync/index.js +10 -10
  190. package/dist/team/index.js +15 -15
  191. package/dist/tiers/index.js +11 -11
  192. package/dist/to/index.js +8 -2
  193. package/dist/to/index.js.map +1 -1
  194. package/dist/transactions/index.js +3 -3
  195. package/dist/util/index.js +1 -1
  196. package/dist/vault-head/index.js +8 -8
  197. package/dist/{verify-WYOFLSNA.js → verify-R6CCBUA3.js} +5 -5
  198. package/dist/walk-3PA4ZOKS.js +21 -0
  199. package/dist/with-cargo/index.d.ts +1 -0
  200. package/dist/with-party/team/roster-epoch.d.ts +71 -0
  201. package/dist/with-party/team/roster-tag.d.ts +1 -1
  202. package/dist/withdraw-accessible-62VI4W7D.js +28 -0
  203. package/package.json +3 -3
  204. package/dist/api-EQYRTZO2.js +0 -20
  205. package/dist/chunk-2LPVI4PX.js.map +0 -1
  206. package/dist/chunk-5W7YXFV5.js.map +0 -1
  207. package/dist/chunk-H3VG6XBC.js.map +0 -1
  208. package/dist/chunk-H4M7ADXY.js.map +0 -1
  209. package/dist/chunk-JBIV4FLR.js.map +0 -1
  210. package/dist/chunk-RK7N4OQ5.js.map +0 -1
  211. package/dist/collection-facade-LG3NYZVB.js +0 -45
  212. package/dist/derive-CXHCY46K.js +0 -22
  213. package/dist/executor-3KFRQETS.js +0 -29
  214. package/dist/executor-AFHQYRAU.js +0 -9
  215. package/dist/executor-YYDW6XQI.js +0 -9
  216. package/dist/export-accessible-BX2ILB4C.js +0 -23
  217. package/dist/extract-partition-UPOVITFI.js +0 -38
  218. package/dist/find-SZBL2HPB.js +0 -11
  219. package/dist/issue-G53NB6EW.js +0 -19
  220. package/dist/liberate-VEOZRESE.js +0 -25
  221. package/dist/noydb-4VV2ZGLZ.js +0 -86
  222. package/dist/register-6TCBR6XD.js +0 -32
  223. package/dist/registry-DH2L4O2V.js +0 -18
  224. package/dist/registry-IWFMXCHX.js +0 -9
  225. package/dist/registry-Q3FG3OAX.js +0 -9
  226. package/dist/registry-YC3IFG3A.js +0 -19
  227. package/dist/request-withdrawal-NM5VYR6F.js +0 -31
  228. package/dist/revoke-MJNYWO72.js +0 -24
  229. package/dist/signer-6XVS2AU3.js +0 -25
  230. package/dist/storage-ZXUT476I.js +0 -23
  231. package/dist/walk-JNEOYCAU.js +0 -21
  232. package/dist/withdraw-accessible-ILTSXTIE.js +0 -28
  233. /package/dist/{api-EQYRTZO2.js.map → api-GJQF7OAJ.js.map} +0 -0
  234. /package/dist/{backup-Z7ZBTAQ6.js.map → backup-QZQEP5RO.js.map} +0 -0
  235. /package/dist/{chunk-AB5P32RE.js.map → chunk-2DGBRE4K.js.map} +0 -0
  236. /package/dist/{chunk-XVU7J43V.js.map → chunk-2E2LT37H.js.map} +0 -0
  237. /package/dist/{chunk-4LPF226H.js.map → chunk-2MQ2D5OZ.js.map} +0 -0
  238. /package/dist/{chunk-DBNYPLWY.js.map → chunk-357ECVLE.js.map} +0 -0
  239. /package/dist/{chunk-SHILAQH5.js.map → chunk-3GIA3HJ2.js.map} +0 -0
  240. /package/dist/{chunk-QGJ4XIA7.js.map → chunk-3SWP2FYA.js.map} +0 -0
  241. /package/dist/{chunk-N4CNVSUF.js.map → chunk-4RUFYGWG.js.map} +0 -0
  242. /package/dist/{chunk-4G25SDQL.js.map → chunk-4U52PMEL.js.map} +0 -0
  243. /package/dist/{chunk-H7HP56F6.js.map → chunk-5EC7X5QA.js.map} +0 -0
  244. /package/dist/{chunk-WK5FSW7T.js.map → chunk-5NKHCJU5.js.map} +0 -0
  245. /package/dist/{chunk-PQ6Z2TAP.js.map → chunk-5UKIZIO3.js.map} +0 -0
  246. /package/dist/{chunk-QHJKK77B.js.map → chunk-5W5CEHLA.js.map} +0 -0
  247. /package/dist/{chunk-YPSOHDNC.js.map → chunk-65ZYRK7O.js.map} +0 -0
  248. /package/dist/{chunk-4ZPE6SKS.js.map → chunk-75WNTBZL.js.map} +0 -0
  249. /package/dist/{chunk-OWLVBOWO.js.map → chunk-7XT7KZTN.js.map} +0 -0
  250. /package/dist/{chunk-QI5NWLVW.js.map → chunk-AHIIBDNH.js.map} +0 -0
  251. /package/dist/{chunk-XSN63FUS.js.map → chunk-AW4KTQA4.js.map} +0 -0
  252. /package/dist/{chunk-KDJGJR7F.js.map → chunk-CWFH36SI.js.map} +0 -0
  253. /package/dist/{chunk-X67FCULK.js.map → chunk-DIVY2CJZ.js.map} +0 -0
  254. /package/dist/{chunk-Z2PWOSCJ.js.map → chunk-DNMTN46H.js.map} +0 -0
  255. /package/dist/{chunk-HTGRQZFB.js.map → chunk-DZPMKY3J.js.map} +0 -0
  256. /package/dist/{chunk-XJ3FEKEY.js.map → chunk-FKQCC4C5.js.map} +0 -0
  257. /package/dist/{chunk-E6YA6UAP.js.map → chunk-FLRLZ4XZ.js.map} +0 -0
  258. /package/dist/{chunk-ALUNQEBY.js.map → chunk-FN26SFGH.js.map} +0 -0
  259. /package/dist/{chunk-TVIFAHZR.js.map → chunk-FPN5D4JX.js.map} +0 -0
  260. /package/dist/{chunk-VTG7327U.js.map → chunk-FRIVOR5N.js.map} +0 -0
  261. /package/dist/{chunk-3QARDAYW.js.map → chunk-FYT3DXPN.js.map} +0 -0
  262. /package/dist/{chunk-YMLQBZFJ.js.map → chunk-FZWAGG5T.js.map} +0 -0
  263. /package/dist/{chunk-CBRS2NEK.js.map → chunk-GHADG5QZ.js.map} +0 -0
  264. /package/dist/{chunk-3L2MVE36.js.map → chunk-GKOJR53Y.js.map} +0 -0
  265. /package/dist/{chunk-Y6GZ2P4M.js.map → chunk-GM4IM7TC.js.map} +0 -0
  266. /package/dist/{chunk-CN6B5PEN.js.map → chunk-H5GVPOB4.js.map} +0 -0
  267. /package/dist/{chunk-467SKJ65.js.map → chunk-HOIWW2LV.js.map} +0 -0
  268. /package/dist/{chunk-ALB64CZM.js.map → chunk-HS3LEVT4.js.map} +0 -0
  269. /package/dist/{chunk-YXA2TCTZ.js.map → chunk-I5LSKXT6.js.map} +0 -0
  270. /package/dist/{chunk-S35S77YU.js.map → chunk-IAHDSFFA.js.map} +0 -0
  271. /package/dist/{chunk-X62MEF2O.js.map → chunk-IRHIA3AL.js.map} +0 -0
  272. /package/dist/{chunk-F23WQK3G.js.map → chunk-IS5LFHV2.js.map} +0 -0
  273. /package/dist/{chunk-POS53FG6.js.map → chunk-IZTU6RKH.js.map} +0 -0
  274. /package/dist/{chunk-VAG47QHV.js.map → chunk-J6FXVDKC.js.map} +0 -0
  275. /package/dist/{chunk-2GXEQUEX.js.map → chunk-JFSUYGNE.js.map} +0 -0
  276. /package/dist/{chunk-LR4Z47QD.js.map → chunk-JILOSL4O.js.map} +0 -0
  277. /package/dist/{chunk-RC4BROYR.js.map → chunk-JRWLUWDM.js.map} +0 -0
  278. /package/dist/{chunk-Z2WK53N6.js.map → chunk-JUBWUJY5.js.map} +0 -0
  279. /package/dist/{chunk-JVLSU7S2.js.map → chunk-JY4U6CYV.js.map} +0 -0
  280. /package/dist/{chunk-3SMSERQU.js.map → chunk-KKZPQLDH.js.map} +0 -0
  281. /package/dist/{chunk-WLLUM35R.js.map → chunk-KQIDBIZL.js.map} +0 -0
  282. /package/dist/{chunk-LKFKXS5K.js.map → chunk-KZTPL7NL.js.map} +0 -0
  283. /package/dist/{chunk-S2VG3ABP.js.map → chunk-LAI7ENPW.js.map} +0 -0
  284. /package/dist/{chunk-ZO252Q5S.js.map → chunk-LUVGSKXE.js.map} +0 -0
  285. /package/dist/{chunk-PGFKIOR3.js.map → chunk-MENI33ZV.js.map} +0 -0
  286. /package/dist/{chunk-MTBXJAS4.js.map → chunk-MOQ6OGKS.js.map} +0 -0
  287. /package/dist/{chunk-5ACAVJUI.js.map → chunk-MTTPHBIE.js.map} +0 -0
  288. /package/dist/{chunk-T3PHCEN4.js.map → chunk-MU74BYOD.js.map} +0 -0
  289. /package/dist/{chunk-DFAUMLD7.js.map → chunk-MV2OEK3K.js.map} +0 -0
  290. /package/dist/{chunk-LF6DMX4C.js.map → chunk-NMDMSHBF.js.map} +0 -0
  291. /package/dist/{chunk-225O5CXQ.js.map → chunk-O3SNM66K.js.map} +0 -0
  292. /package/dist/{chunk-YCSM3GZU.js.map → chunk-OEJ4R52I.js.map} +0 -0
  293. /package/dist/{chunk-IESNYJXZ.js.map → chunk-OKCQNMO6.js.map} +0 -0
  294. /package/dist/{chunk-H36KSN6X.js.map → chunk-OLUTCM23.js.map} +0 -0
  295. /package/dist/{chunk-RDHUZ674.js.map → chunk-OQDHIAR2.js.map} +0 -0
  296. /package/dist/{chunk-DKWPJOYH.js.map → chunk-P22XPNFW.js.map} +0 -0
  297. /package/dist/{chunk-GK4DRVUD.js.map → chunk-P2RJAVMR.js.map} +0 -0
  298. /package/dist/{chunk-UCUALOSM.js.map → chunk-P7KJME6C.js.map} +0 -0
  299. /package/dist/{chunk-HM4JSXX2.js.map → chunk-PCIBCL26.js.map} +0 -0
  300. /package/dist/{chunk-4A4TYISP.js.map → chunk-PV7XXAXK.js.map} +0 -0
  301. /package/dist/{chunk-5AFMP532.js.map → chunk-Q2OAAREU.js.map} +0 -0
  302. /package/dist/{chunk-Z7ZXZL6Y.js.map → chunk-Q2ZN5DWZ.js.map} +0 -0
  303. /package/dist/{chunk-L6GTLZRK.js.map → chunk-QJLOWGOU.js.map} +0 -0
  304. /package/dist/{chunk-7LYUJNU3.js.map → chunk-QOHGWFAW.js.map} +0 -0
  305. /package/dist/{chunk-6FOGTKBY.js.map → chunk-RCONOOVF.js.map} +0 -0
  306. /package/dist/{chunk-VFIWDPXZ.js.map → chunk-RPX2H2OL.js.map} +0 -0
  307. /package/dist/{chunk-PCQDY6QN.js.map → chunk-SWFIXQF5.js.map} +0 -0
  308. /package/dist/{chunk-ISSU3OH6.js.map → chunk-T66OY2U5.js.map} +0 -0
  309. /package/dist/{chunk-6EW2UCVF.js.map → chunk-TAJZ7GXO.js.map} +0 -0
  310. /package/dist/{chunk-57JTHWLQ.js.map → chunk-TQGT5BZE.js.map} +0 -0
  311. /package/dist/{chunk-TOV6VMHF.js.map → chunk-U3RMWOXY.js.map} +0 -0
  312. /package/dist/{chunk-PUJTKLPL.js.map → chunk-UL7TLJ54.js.map} +0 -0
  313. /package/dist/{chunk-W5LHQXZU.js.map → chunk-USKHHOIV.js.map} +0 -0
  314. /package/dist/{chunk-J4MN6XIU.js.map → chunk-UTFY6W6X.js.map} +0 -0
  315. /package/dist/{chunk-P6ASQOZR.js.map → chunk-VT4DTCK5.js.map} +0 -0
  316. /package/dist/{chunk-A2YW5EMU.js.map → chunk-X6YRP5EC.js.map} +0 -0
  317. /package/dist/{chunk-FOG7YEJP.js.map → chunk-XGXVPCYW.js.map} +0 -0
  318. /package/dist/{chunk-5263OEM3.js.map → chunk-XJP66QEN.js.map} +0 -0
  319. /package/dist/{chunk-OPXR4PB2.js.map → chunk-XKA6UH5V.js.map} +0 -0
  320. /package/dist/{chunk-XDVVBETV.js.map → chunk-YHIAWECL.js.map} +0 -0
  321. /package/dist/{chunk-J4UJ5FRV.js.map → chunk-Z277MC2O.js.map} +0 -0
  322. /package/dist/{chunk-F7ZFRPGQ.js.map → chunk-ZB2K3FV7.js.map} +0 -0
  323. /package/dist/{chunk-NLKLXXTO.js.map → chunk-ZQGRZN5L.js.map} +0 -0
  324. /package/dist/{classified-marker-BSQHU4JT.js.map → classified-marker-R37XW5PC.js.map} +0 -0
  325. /package/dist/{collection-facade-LG3NYZVB.js.map → collection-facade-OPJ3EC4L.js.map} +0 -0
  326. /package/dist/{computed-ASBNTLOK.js.map → computed-HW6IG5UH.js.map} +0 -0
  327. /package/dist/{dead-filter-QKU56XTQ.js.map → dead-filter-GRT6RAML.js.map} +0 -0
  328. /package/dist/{delegation-XWRPYODW.js.map → delegation-6QRAYSK6.js.map} +0 -0
  329. /package/dist/{derive-CXHCY46K.js.map → derive-AAIXSQIE.js.map} +0 -0
  330. /package/dist/{dispatch-4AP4PUZU.js.map → dispatch-DR3XITEC.js.map} +0 -0
  331. /package/dist/{dispatch-VR4LRXZ7.js.map → dispatch-QCF7KPIP.js.map} +0 -0
  332. /package/dist/{enclave-NYPT7WA7.js.map → enclave-OXZY3NOP.js.map} +0 -0
  333. /package/dist/{executor-3KFRQETS.js.map → executor-67NA4KPO.js.map} +0 -0
  334. /package/dist/{executor-AFHQYRAU.js.map → executor-7JDP7UBK.js.map} +0 -0
  335. /package/dist/{executor-YYDW6XQI.js.map → executor-CRH5OB4V.js.map} +0 -0
  336. /package/dist/{export-accessible-BX2ILB4C.js.map → export-accessible-K4GJAU7U.js.map} +0 -0
  337. /package/dist/{extract-partition-UPOVITFI.js.map → extract-partition-YJFL5OKK.js.map} +0 -0
  338. /package/dist/{fanout-sidecar-IWP3R4RC.js.map → fanout-sidecar-KGQCUJ7P.js.map} +0 -0
  339. /package/dist/{find-SZBL2HPB.js.map → find-SVZHMEQI.js.map} +0 -0
  340. /package/dist/{issue-G53NB6EW.js.map → issue-64N6OG7U.js.map} +0 -0
  341. /package/dist/{ledger-T5K4P2D7.js.map → ledger-ZAFULLAF.js.map} +0 -0
  342. /package/dist/{liberate-VEOZRESE.js.map → liberate-QAUKHU6W.js.map} +0 -0
  343. /package/dist/{link-set-76JZ6YB4.js.map → link-set-LQI2IJX6.js.map} +0 -0
  344. /package/dist/{managed-secret-6YC32VXG.js.map → managed-secret-7OH7HKXV.js.map} +0 -0
  345. /package/dist/{migrate-cek-LBRKYUZZ.js.map → migrate-cek-QHZ75E6E.js.map} +0 -0
  346. /package/dist/{noydb-4VV2ZGLZ.js.map → noydb-ZUS5XAFT.js.map} +0 -0
  347. /package/dist/{pod-handle-P6DPBM5U.js.map → pod-handle-BLOI4IFY.js.map} +0 -0
  348. /package/dist/{post-register-53O7AJRZ.js.map → post-register-R33EKJQR.js.map} +0 -0
  349. /package/dist/{register-6TCBR6XD.js.map → register-AYBQNTM3.js.map} +0 -0
  350. /package/dist/{registry-DH2L4O2V.js.map → registry-CQWWOBO4.js.map} +0 -0
  351. /package/dist/{registry-IWFMXCHX.js.map → registry-JCZ4BNLV.js.map} +0 -0
  352. /package/dist/{registry-Q3FG3OAX.js.map → registry-JFFENZ44.js.map} +0 -0
  353. /package/dist/{registry-YC3IFG3A.js.map → registry-ZA4HACYR.js.map} +0 -0
  354. /package/dist/{request-withdrawal-NM5VYR6F.js.map → request-withdrawal-7IKUIAEB.js.map} +0 -0
  355. /package/dist/{reveal-XBIMHAXR.js.map → reveal-PI6ADRQU.js.map} +0 -0
  356. /package/dist/{revoke-MJNYWO72.js.map → revoke-PUJKRYJF.js.map} +0 -0
  357. /package/dist/{seed-NSNIGYXE.js.map → seed-MCCGVPRI.js.map} +0 -0
  358. /package/dist/{signer-6XVS2AU3.js.map → signer-5TA7FUC3.js.map} +0 -0
  359. /package/dist/{stale-MCS46TFO.js.map → stale-HZR7745Y.js.map} +0 -0
  360. /package/dist/{storage-ZXUT476I.js.map → storage-J2QHNJCB.js.map} +0 -0
  361. /package/dist/{store-coordination-provider-6FM26VQM.js.map → store-coordination-provider-MYIHSZXT.js.map} +0 -0
  362. /package/dist/{verify-WYOFLSNA.js.map → verify-R6CCBUA3.js.map} +0 -0
  363. /package/dist/{walk-JNEOYCAU.js.map → walk-3PA4ZOKS.js.map} +0 -0
  364. /package/dist/{withdraw-accessible-ILTSXTIE.js.map → withdraw-accessible-62VI4W7D.js.map} +0 -0
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  buildRecordEnvelope
3
- } from "./chunk-N4CNVSUF.js";
3
+ } from "./chunk-4RUFYGWG.js";
4
4
  import {
5
5
  ValidationError
6
- } from "./chunk-JBIV4FLR.js";
6
+ } from "./chunk-SW4TOSJL.js";
7
7
 
8
8
  // src/with-party/directory/cover/custom.ts
9
9
  var CUSTOM_KEY_PATTERN = /^[a-z0-9]+([.-][a-z0-9]+)+$/i;
@@ -230,4 +230,4 @@ export {
230
230
  resolveLocale,
231
231
  pickLocale
232
232
  };
233
- //# sourceMappingURL=chunk-LF6DMX4C.js.map
233
+ //# sourceMappingURL=chunk-NMDMSHBF.js.map
@@ -1,46 +1,47 @@
1
1
  import {
2
2
  walkClosure
3
- } from "./chunk-OWLVBOWO.js";
3
+ } from "./chunk-7XT7KZTN.js";
4
4
  import {
5
5
  resolveManagedSecret
6
- } from "./chunk-Z2WK53N6.js";
6
+ } from "./chunk-JUBWUJY5.js";
7
7
  import {
8
8
  parseExtractedPartitionBody,
9
9
  readPod,
10
10
  readPodHeader
11
- } from "./chunk-6FOGTKBY.js";
11
+ } from "./chunk-RCONOOVF.js";
12
12
  import {
13
13
  createOwnerKeyring,
14
14
  mintRosterTag,
15
+ nextRosterEpoch,
15
16
  requireRosterKey
16
- } from "./chunk-5W7YXFV5.js";
17
+ } from "./chunk-XJTGBHK6.js";
17
18
  import {
18
19
  LedgerStore
19
- } from "./chunk-IESNYJXZ.js";
20
+ } from "./chunk-OKCQNMO6.js";
20
21
  import {
21
22
  LEDGER_COLLECTION
22
23
  } from "./chunk-I7FD46FF.js";
23
24
  import {
24
25
  openEnvelopeJson
25
- } from "./chunk-2LPVI4PX.js";
26
+ } from "./chunk-DOPZWTMJ.js";
26
27
  import {
27
28
  buildRecordEnvelope
28
- } from "./chunk-N4CNVSUF.js";
29
+ } from "./chunk-4RUFYGWG.js";
29
30
  import {
30
31
  base64ToBuffer,
31
32
  wrapKey
32
- } from "./chunk-W5LHQXZU.js";
33
+ } from "./chunk-USKHHOIV.js";
33
34
  import {
34
35
  AdoptionStateError,
35
36
  TransferSealError,
36
37
  ValidationError
37
- } from "./chunk-JBIV4FLR.js";
38
+ } from "./chunk-SW4TOSJL.js";
38
39
 
39
40
  // src/with-cargo/active.ts
40
41
  function withCargo() {
41
42
  return {
42
43
  async extractPartition(vault, opts) {
43
- const { extractPartitionCore } = await import("./extract-partition-UPOVITFI.js");
44
+ const { extractPartitionCore } = await import("./extract-partition-YJFL5OKK.js");
44
45
  return extractPartitionCore(vault, opts);
45
46
  }
46
47
  };
@@ -226,8 +227,9 @@ async function createOwnerOnAdoptedPartition(store, vaultName, opts) {
226
227
  mergedDeks[collection] = await wrapKey(dek, kek);
227
228
  }
228
229
  const merged = { ...keyringFile, deks: mergedDeks };
230
+ const withEpoch = { ...merged, roster_epoch: nextRosterEpoch(keyringFile.roster_epoch) };
229
231
  const rosterKey = requireRosterKey(unlocked, "adoptPartition");
230
- const mergedFile = { ...merged, roster_tag: await mintRosterTag(merged, rosterKey) };
232
+ const mergedFile = { ...withEpoch, roster_tag: await mintRosterTag(withEpoch, rosterKey) };
231
233
  await store.put(vaultName, "_keyring", userId, { ...env, _data: JSON.stringify(mergedFile) });
232
234
  }
233
235
  const ledgerDek = partitionDeks.get(LEDGER_COLLECTION);
@@ -250,7 +252,7 @@ async function createOwnerOnAdoptedPartition(store, vaultName, opts) {
250
252
  }
251
253
  }
252
254
  if (isManaged(opts)) {
253
- const { createNoydb } = await import("./noydb-4VV2ZGLZ.js");
255
+ const { createNoydb } = await import("./noydb-ZUS5XAFT.js");
254
256
  const db = await createNoydb({
255
257
  store,
256
258
  user: userId,
@@ -305,4 +307,4 @@ export {
305
307
  withCargo,
306
308
  describeExtraction
307
309
  };
308
- //# sourceMappingURL=chunk-H3VG6XBC.js.map
310
+ //# sourceMappingURL=chunk-NUXTUGAD.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/with-cargo/active.ts","../src/with-cargo/describe-extraction.ts","../src/with-cargo/adopt-partition.ts","../src/with-cargo/decrypt-partition.ts"],"sourcesContent":["/**\n * Enable the cargo (partition extraction) capability.\n * Pass to `createNoydb({ cargoStrategy: withCargo() })` to make the source-side\n * `extractPartition(vault, ...)` free function live. The extraction crypto\n * engine is dynamically imported here, so it stays out of the floor bundle\n * until opted in. The recipient-side `adoptPartition` /\n * `decryptExtractedPartition` free functions — and `diffVault` (shared\n * import/merge infra) — are ungated and unaffected.\n */\nimport type { CargoStrategy } from './strategy.js'\n\nexport function withCargo(): CargoStrategy {\n return {\n async extractPartition(vault, opts) {\n const { extractPartitionCore } = await import('./extract-partition.js')\n return extractPartitionCore(vault, opts)\n },\n }\n}\n","/**\n * Partition-extraction dry-run. Read-only preview of what an\n * `extractPartition` would move: record counts, byte totals, and the\n * timestamp span per collection — computed from raw encrypted\n * envelopes WITHOUT decrypting them. Writes nothing, mutates nothing.\n *\n * @module\n */\nimport type { Vault } from '../kernel/vault.js'\nimport { walkClosure, type WalkClosureOptions, type DanglingRefNotice } from './walk-closure.js'\n\nexport interface ExtractionPreview {\n readonly totalRecords: number\n /** Sum of serialized encrypted-envelope sizes (bytes). */\n readonly totalBytes: number\n readonly byCollection: ReadonlyArray<{\n readonly name: string\n readonly recordCount: number\n readonly bytes: number\n /** Earliest envelope `_ts` in this collection (lexicographic). */\n readonly oldestTs?: string\n readonly newestTs?: string\n }>\n readonly graph: { readonly depth: number; readonly cyclesDetected: boolean }\n /** Records the walk reached but whose envelope couldn't be read. */\n readonly inaccessible: ReadonlyArray<{ readonly collection: string; readonly id: string }>\n /**\n * #772: outbound FK edges whose referenced parent was excluded from the\n * closure (missing, or tier-elevated and therefore invisible) — mirrors\n * `ExtractPartitionResult.danglingRefs` (#759) so a preview/extract pair\n * gives the SAME signal. A parent excluded this way never appears in\n * `byCollection` at all; this is the only preview-time indicator.\n */\n readonly danglingRefs: ReadonlyArray<DanglingRefNotice>\n}\n\nexport async function describeExtraction(\n vault: Vault,\n opts: WalkClosureOptions,\n): Promise<ExtractionPreview> {\n const { closure, graph, danglingRefs } = await walkClosure(vault, opts)\n\n const { name: vaultName, adapter } = vault._introspectState()\n const encoder = new TextEncoder()\n\n const byCollection: Array<{\n name: string; recordCount: number; bytes: number; oldestTs?: string; newestTs?: string\n }> = []\n const inaccessible: Array<{ collection: string; id: string }> = []\n let totalBytes = 0\n let totalRecords = 0\n\n for (const [collectionName, ids] of closure) {\n let bytes = 0\n let oldestTs: string | undefined\n let newestTs: string | undefined\n let recordCount = 0\n\n for (const id of ids) {\n const env = await adapter.get(vaultName, collectionName, id)\n if (!env) {\n // Walk reached it (via decrypted list) but the raw store read\n // returned nothing — surface rather than miscount.\n inaccessible.push({ collection: collectionName, id })\n continue\n }\n recordCount++\n bytes += encoder.encode(JSON.stringify(env)).length\n const ts = env._ts\n if (oldestTs === undefined || ts < oldestTs) oldestTs = ts\n if (newestTs === undefined || ts > newestTs) newestTs = ts\n }\n\n byCollection.push({\n name: collectionName,\n recordCount,\n bytes,\n // Spread conditionally — exactOptionalPropertyTypes forbids an\n // explicit `undefined` on an optional property.\n ...(oldestTs !== undefined ? { oldestTs } : {}),\n ...(newestTs !== undefined ? { newestTs } : {}),\n })\n totalBytes += bytes\n totalRecords += recordCount\n }\n\n byCollection.sort((a, b) => a.name.localeCompare(b.name))\n\n return Object.freeze({\n totalRecords,\n totalBytes,\n byCollection,\n graph,\n inaccessible,\n danglingRefs,\n })\n}\n","/**\n * Partition adoption. Recipient side: verify an extracted bundle,\n * validate the transfer key, import the re-keyed collections into a\n * destination store, and record an `_meta/adoption` marker. The bundle\n * stays UNOWNED after adoption — `createOwnerOnAdoptedPartition`\n * mints the owner; the transfer seal is then destroyed.\n *\n * @module\n */\nimport { base64ToBuffer, wrapKey, type EnclaveKey } from '../kernel/enclave/index.js'\nimport { TransferSealError, AdoptionStateError, ValidationError } from '../kernel/errors.js'\nimport type { NoydbStore, VaultSnapshot, KeyringFile } from '../kernel/types.js'\nimport { createOwnerKeyring, requireRosterKey } from '../with-party/team/keyring.js'\nimport { mintRosterTag } from '../with-party/team/roster-tag.js' // #1115\nimport { nextRosterEpoch } from '../with-party/team/roster-epoch.js' // #1097\nimport { resolveManagedSecret } from '../with-party/team/managed-secret.js'\nimport type { NoydbSealer } from '../with-party/team/managed-secret.js'\nimport type { NoydbShamir } from '../with-party/team/noydb-shamir.js'\nimport type { RecoveryEnrollmentInput } from '../with-party/team/rotate-recover.js'\nimport { LedgerStore } from '../with-commit/history/ledger/store.js'\nimport { LEDGER_COLLECTION } from '../with-commit/history/ledger/constants.js'\nimport type { TransferSealPayload } from '../with-pod/pod.js'\nimport { readPodHeader, readPod, parseExtractedPartitionBody } from '../with-pod/pod.js'\nimport { buildRecordEnvelope } from '../kernel/enclave/index.js'\n\n/**\n * Reverse of `sealDeks`. Imports the transfer key, decrypts the\n * sealed `{ collection: base64(rawDEK) }` map (layout iv(12)‖ct‖tag), and\n * re-imports each DEK as an AES-GCM key. Throws `TransferSealError` on a\n * wrong key (AES-GCM auth-tag failure) or malformed payload.\n */\nexport async function unsealDeks(\n seal: TransferSealPayload,\n transferKey: Uint8Array,\n): Promise<Map<string, EnclaveKey>> {\n if (transferKey.byteLength !== 32) {\n throw new TransferSealError(\n `transfer key must be 32 bytes, got ${transferKey.byteLength}.`,\n )\n }\n const key = await crypto.subtle.importKey('raw', transferKey as BufferSource, 'AES-GCM', false, ['decrypt'])\n const raw = base64ToBuffer(seal.payload)\n let plaintext: ArrayBuffer\n try {\n plaintext = await crypto.subtle.decrypt(\n { name: 'AES-GCM', iv: raw.slice(0, 12) as BufferSource },\n key,\n raw.slice(12) as BufferSource,\n )\n } catch {\n throw new TransferSealError(\n 'transfer seal could not be opened — wrong transfer key (AES-GCM authentication failed).',\n )\n }\n let dekMap: Record<string, string>\n try {\n dekMap = JSON.parse(new TextDecoder().decode(plaintext)) as Record<string, string>\n } catch {\n throw new TransferSealError('transfer seal payload is not valid JSON after decryption.')\n }\n const deks = new Map<string, EnclaveKey>()\n for (const [collection, b64] of Object.entries(dekMap)) {\n // Extractable: the recipient must be able to re-wrap these under their\n // own KEK (AES-KW) at owner-creation. Matches generateDEK.\n const dek = await crypto.subtle.importKey('raw', base64ToBuffer(b64) as BufferSource, 'AES-GCM', true, ['encrypt', 'decrypt'])\n deks.set(collection, dek)\n }\n return deks\n}\n\nexport interface AdoptPartitionOptions {\n readonly transferKey: Uint8Array\n readonly destinationStore: NoydbStore\n readonly vaultName: string\n}\n\nexport interface AdoptPartitionResult {\n readonly vaultName: string\n readonly needsOwner: true\n readonly sealId: string\n}\n\nexport async function adoptPartition(\n bundleBytes: Uint8Array,\n opts: AdoptPartitionOptions,\n): Promise<AdoptPartitionResult> {\n const { transferKey, destinationStore, vaultName } = opts\n\n const header = readPodHeader(bundleBytes)\n if (header.bundleKind !== 'extracted-partition' || header.transferSeal === undefined) {\n throw new ValidationError(\n 'adoptPartition requires an extracted-partition bundle with a transfer seal. '\n + 'For ordinary backups use readPod + vault.load.',\n )\n }\n\n const { dumpJson } = await readPod(bundleBytes)\n const { dump, seal } = parseExtractedPartitionBody(dumpJson)\n\n // Validate the transfer key by unsealing in memory; throws\n // TransferSealError on mismatch. DEKs are discarded here — they stay\n // sealed at rest (in _meta/adoption) until owner-creation wraps them under the\n // recipient's KEK.\n await unsealDeks(seal, transferKey)\n\n // Single-occupancy per vaultName: an `_meta/adoption` marker already present\n // means this slot holds a partition (adopted-and-unowned, or already owned).\n // saveAll below would overwrite its data and replace the marker, stranding the\n // prior adoption's transfer seal. Refuse regardless of sealId — re-adopting the\n // SAME bundle is a redundant call, and adopting a DIFFERENT bundle here would\n // clobber the existing partition. Either way, pick a fresh vaultName.\n const existing = await destinationStore.get(vaultName, '_meta', 'adoption')\n if (existing) {\n const prior = JSON.parse(existing._data) as { sealId?: string }\n if (prior.sealId === seal.sealId) {\n throw new AdoptionStateError(\n `partition (sealId ${seal.sealId}) is already adopted into vault \"${vaultName}\".`,\n )\n }\n throw new AdoptionStateError(\n `vault \"${vaultName}\" already holds an adopted partition (sealId ${prior.sealId}); `\n + `adopting a different partition (sealId ${seal.sealId}) here would overwrite it. `\n + `Adopt into a fresh vaultName instead.`,\n )\n }\n\n // The marker-only check above misses a worse case: a vaultName already in use\n // by an ORDINARY vault (createNoydb + openVault) carries no `_meta/adoption`,\n // yet `saveAll` below is destructive on SQL adapters (`DELETE FROM ... WHERE\n // vault = ?` followed by upsert) and would wipe the legitimate keyring +\n // data. Refuse adoption into ANY occupied slot — a fresh vaultName is the\n // documented precondition.\n const existingKeyring = await destinationStore.list(vaultName, '_keyring')\n if (existingKeyring.length > 0) {\n throw new AdoptionStateError(\n `vault \"${vaultName}\" already holds a keyring (an unrelated owner exists at this slot); `\n + `adoptPartition requires a fresh vaultName to avoid destructive saveAll on SQL adapters.`,\n )\n }\n\n const backup = JSON.parse(dump) as { collections: VaultSnapshot; _internal?: VaultSnapshot }\n await destinationStore.saveAll(vaultName, backup.collections)\n\n // Import carried internal collections (e.g. _schemas from carrySchemas).\n // saveAll only writes data collections; _internal is written per-record.\n if (backup._internal) {\n for (const [collection, records] of Object.entries(backup._internal)) {\n for (const [id, envelope] of Object.entries(records)) {\n await destinationStore.put(vaultName, collection, id, envelope)\n }\n }\n }\n\n const adoptedAt = new Date().toISOString()\n const adoption = { sealId: seal.sealId, adoptedAt, needsOwner: true as const, transferSeal: seal }\n await destinationStore.put(vaultName, '_meta', 'adoption',\n buildRecordEnvelope({ collection: '_meta', id: 'adoption', version: 1 },\n { ts: adoptedAt, iv: '', data: JSON.stringify(adoption) }))\n\n return { vaultName, needsOwner: true, sealId: seal.sealId }\n}\n\nexport interface CreateOwnerResult {\n readonly vaultName: string\n readonly userId: string\n}\n\n/** Standard-mode owner: recipient supplies the secret. */\nexport interface CreateOwnerStandardOptions {\n readonly userId: string\n readonly secret: string\n readonly transferKey: Uint8Array\n}\n\n/**\n * Managed-mode owner: the secret is minted + sealed under\n * a `NoydbSealer` (e.g. an `at-*` OS keychain) so the partition\n * auto-unlocks on the recipient's device. Managed mode mandates a strong\n * (Shamir) recovery profile at creation, which needs the\n * `shamirRecovery` provider injected.\n */\nexport interface CreateOwnerManagedOptions {\n readonly userId: string\n readonly secretMode: 'managed'\n readonly sealingKey: NoydbSealer\n readonly recovery: ReadonlyArray<RecoveryEnrollmentInput>\n readonly shamirRecovery: NoydbShamir\n readonly transferKey: Uint8Array\n}\n\nexport type CreateOwnerOptions = CreateOwnerStandardOptions | CreateOwnerManagedOptions\n\nfunction isManaged(o: CreateOwnerOptions): o is CreateOwnerManagedOptions {\n return 'secretMode' in o && o.secretMode === 'managed'\n}\n\n/**\n * Mint the first owner keyring on an adopted-but-unowned partition,\n * then destroy the transfer seal.\n *\n * Standard mode: the recipient supplies a secret. Managed mode: the\n * secret is minted + sealed under a `NoydbSealer` and a strong\n * (Shamir) recovery profile is enrolled — orchestrated via the existing\n * `openVaultAndEnrollRecovery` ceremony.\n *\n * Either way, reuses `createOwnerKeyring` to derive the KEK + write the base\n * keyring, then wraps the partition's DEKs (recovered from the seal) under that\n * KEK and re-persists the merged keyring file.\n *\n * Idempotent under retry: the seal is destroyed LAST (Stage D), after the\n * keyring (Stage A), the ledger transition (Stage B), and — in managed mode —\n * strong-recovery enrollment (Stage C). A failure in the fallible enrollment\n * step leaves the seal intact, and re-running with the same `userId` +\n * `transferKey` resumes from the first incomplete stage. (Multi-profile recovery\n * arrays may re-enroll an already-enrolled profile on retry; managed mode's\n * mandated single Shamir profile does not.)\n */\nexport async function createOwnerOnAdoptedPartition(\n store: NoydbStore,\n vaultName: string,\n opts: CreateOwnerOptions,\n): Promise<CreateOwnerResult> {\n const { userId, transferKey } = opts\n\n // Managed mode requires a strong (Shamir) recovery profile, validated BEFORE\n // any disk write — same gate as createNoydb.\n if (isManaged(opts) && !opts.recovery.some((r) => r.profile === 'shamir')) {\n throw new AdoptionStateError(\n 'managed-mode adoption requires at least one strong (shamir) recovery profile in '\n + '`recovery` — paper alone is not strong when there is no user secret to fall back on.',\n )\n }\n\n // 1. Verify adopted-unowned state.\n const adoptionEnv = await store.get(vaultName, '_meta', 'adoption')\n if (!adoptionEnv) {\n throw new AdoptionStateError(\n `vault \"${vaultName}\" is not an adopted partition (no _meta/adoption). `\n + `createOwnerOnAdoptedPartition only applies to vaults created via adoptPartition.`,\n )\n }\n const adoption = JSON.parse(adoptionEnv._data) as {\n sealId: string; adoptedAt: string; needsOwner?: boolean\n consumedAt?: string; transferSeal?: TransferSealPayload\n }\n if (adoption.consumedAt !== undefined || adoption.transferSeal === undefined) {\n throw new AdoptionStateError(\n `vault \"${vaultName}\" already has an owner (transfer seal consumed at ${adoption.consumedAt}).`,\n )\n }\n\n // 2. Recover the partition DEKs from the seal (throws on wrong key) BEFORE\n // writing any keyring, so a bad transfer key leaves no trace. Always\n // validated, including when resuming a partial prior call.\n const partitionDeks = await unsealDeks(adoption.transferSeal, transferKey)\n\n // The ceremony below is split into stages so a failure in the fallible\n // managed-enrollment step (network/provider outage) leaves the call RETRYABLE\n // — the seal is destroyed only once everything durable is in place. Each stage\n // detects its own prior completion rather than relying on a single resume bit.\n\n // A keyring present for a DIFFERENT user (with the seal still unconsumed) is a\n // genuine second-owner attempt — refuse it. A same-user keyring is a resumed\n // partial call and is handled by the stage checks below.\n const existingKeyring = await store.get(vaultName, '_keyring', userId)\n const otherOwners = (await store.list(vaultName, '_keyring')).filter((u) => u !== userId)\n if (otherOwners.length > 0) {\n throw new AdoptionStateError(\n `vault \"${vaultName}\" already has a keyring for a different owner; cannot create owner \"${userId}\".`,\n )\n }\n\n // Stage A — mint the owner keyring + merge the partition DEKs. Considered done\n // only when the keyring already holds every partition DEK. createOwnerKeyring\n // overwrites (fresh KEK + fresh _users DEK), so re-running is safe ONLY while\n // no recovery has been enrolled yet — guaranteed here because enrollment\n // (Stage C) runs strictly after Stage A completes.\n const partitionCollections = [...partitionDeks.keys()]\n const priorDeks = existingKeyring ? (JSON.parse(existingKeyring._data) as KeyringFile).deks : {}\n const ownerMinted = existingKeyring !== null && partitionCollections.every((c) => c in priorDeks)\n if (!ownerMinted) {\n // Resolve the owner secret. Managed mode mints a random secret, seals\n // it under the provider, and persists _meta/sealed-secret (so the\n // partition auto-unlocks on the recipient's device); standard mode uses the\n // caller's secret. Idempotent under retry — resolveManagedSecret's reopen\n // arm reuses an already-sealed secret.\n const secret = isManaged(opts)\n ? await resolveManagedSecret(store, vaultName, opts.sealingKey)\n : opts.secret\n\n // Mint the owner keyring (KEK + _users DEK + canary, written to disk).\n const unlocked = await createOwnerKeyring(store, vaultName, { userId: userId, secret: secret })\n\n // Merge the partition DEKs (wrapped under the new KEK) into the keyring.\n const env = await store.get(vaultName, '_keyring', userId)\n if (!env) throw new AdoptionStateError(`keyring write for \"${userId}\" did not persist`)\n const keyringFile = JSON.parse(env._data) as KeyringFile\n const kek = unlocked.kek\n if (!kek) throw new AdoptionStateError(`owner keyring for \"${userId}\" has no KEK to wrap partition DEKs under`)\n const mergedDeks: Record<string, string> = { ...keyringFile.deks }\n for (const [collection, dek] of partitionDeks) {\n mergedDeks[collection] = await wrapKey(dek, kek)\n }\n // #1115 — RESTAMP. The roster tag now covers the DEK key SET, and this merge\n // is precisely a change to that set: adoption joins the partition's\n // collections to a keyring `createOwnerKeyring` stamped moments earlier\n // without them. Writing the merged file under the old tag would leave every\n // adopted vault failing `roster-tag-mismatch` on its first open.\n //\n // The roster key is the one just minted for this NEW vault — unlike\n // `liberateVault`, which joins an EXISTING vault and must keep the\n // incumbent key so co-members can still verify each other.\n const merged: KeyringFile = { ...keyringFile, deks: mergedDeks }\n // #1097 — stamped BEFORE the tag is minted, so it lands inside the\n // authenticated canonical and a store can neither edit nor strip it.\n const withEpoch = { ...merged, roster_epoch: nextRosterEpoch(keyringFile.roster_epoch) }\n const rosterKey = requireRosterKey(unlocked, 'adoptPartition')\n const mergedFile: KeyringFile = { ...withEpoch, roster_tag: await mintRosterTag(withEpoch, rosterKey) }\n await store.put(vaultName, '_keyring', userId, { ...env, _data: JSON.stringify(mergedFile) })\n }\n\n // Stage B — record the ownership transition on the carried\n // audit chain (carryLedger sealed the _ledger DEK). No-op without that DEK.\n // Idempotent: appended only if the closing `transfer-seal-consumed` entry is\n // absent, so a retry does not duplicate the pair.\n const ledgerDek = partitionDeks.get(LEDGER_COLLECTION)\n if (ledgerDek) {\n const ledger = new LedgerStore({\n adapter: store,\n vault: vaultName,\n encrypted: true,\n getDEK: async () => ledgerDek,\n actor: userId,\n })\n const creationReason = `creation-of-new-owner:${userId}`\n const consumedReason = `transfer-seal-consumed:${adoption.sealId}`\n // Gate each append on its own presence — a crash or store error strictly\n // between the two adjacent puts would otherwise re-append the first one\n // on retry. The pair is the audit record, not a single transaction.\n const recordedReasons = new Set((await ledger.loadAllEntries()).map((e) => e.reason))\n if (!recordedReasons.has(creationReason)) {\n await ledger.append({ op: 'lifecycle', collection: '', id: '', version: 0, actor: '', payloadHash: '', reason: creationReason })\n }\n if (!recordedReasons.has(consumedReason)) {\n await ledger.append({ op: 'lifecycle', collection: '', id: '', version: 0, actor: '', payloadHash: '', reason: consumedReason })\n }\n }\n\n // Stage C — Managed mode: enroll the mandatory strong recovery\n // by orchestrating the existing public ceremony. The partition is\n // now a managed-mode vault on disk (sealed secret + keyring), so we\n // open it as a normal client and let openVaultAndEnrollRecovery do the\n // gate-bypass + enroll + re-assert. Dynamic import keeps the Noydb class\n // out of the @noy-db/hub/cargo static graph. Runs BEFORE seal destruction\n // so a failure here leaves the seal intact and the call retryable.\n if (isManaged(opts)) {\n const { createNoydb } = await import('../kernel/noydb.js')\n const db = await createNoydb({\n store,\n user: userId,\n secretMode: 'managed',\n sealingKey: opts.sealingKey,\n shamirRecovery: opts.shamirRecovery,\n })\n await db.team.openVaultAndEnrollRecovery(vaultName, { recovery: opts.recovery })\n }\n\n // Stage D — Destroy the transfer seal LAST — the commit point. Everything\n // above is either idempotent or resumable, so the seal is only consumed\n // once the owner keyring (and, in managed mode, strong recovery) is\n // durably in place. Retain sealId + consumedAt for audit.\n const consumed = { sealId: adoption.sealId, adoptedAt: adoption.adoptedAt, consumedAt: new Date().toISOString() }\n await store.put(vaultName, '_meta', 'adoption', { ...adoptionEnv, _data: JSON.stringify(consumed) })\n\n return { vaultName, userId }\n}\n","/**\n * Read-side counterpart to `extractPartition`: decrypt an\n * extracted-partition bundle's records to plaintext using its transfer\n * key, WITHOUT adopting it into a vault. Used by an outward\n * orchestration layer's reconcile/merge and field-authority flows to\n * compare incoming records against a receiver. The transfer key validates the bundle\n * (wrong key throws).\n * @module\n */\nimport type { EncryptedEnvelope } from '../kernel/types.js'\nimport { openEnvelopeJson } from '../kernel/enclave/index.js'\nimport { readPodHeader, readPod, parseExtractedPartitionBody } from '../with-pod/pod.js'\nimport { unsealDeks } from './adopt-partition.js'\n\n/** One decrypted record from an extracted-partition compartment. */\nexport interface DecryptedRecord {\n readonly id: string\n readonly record: Record<string, unknown>\n /** Source envelope write timestamp (ISO) — for last-write-wins merges. */\n readonly ts: string\n /** Source envelope version. */\n readonly version: number\n /** Provenance source id (FR-5). Present only when the source collection had provenance:true and a source was supplied on put. */\n readonly source?: string\n /** ISO-8601 timestamp the provenance source was recorded (FR-5). */\n readonly sourceTs?: string\n}\n\n/**\n * Decrypt every record of an extracted-partition bundle to plaintext,\n * grouped by collection. Throws if the bundle isn't an\n * extracted-partition or the transfer key is wrong.\n */\nexport async function decryptExtractedPartition(\n bundleBytes: Uint8Array,\n transferKey: Uint8Array,\n): Promise<Record<string, DecryptedRecord[]>> {\n const header = readPodHeader(bundleBytes)\n if (header.bundleKind !== 'extracted-partition' || header.transferSeal === undefined) {\n throw new Error('decryptExtractedPartition: bundle is not an extracted-partition.')\n }\n const { dumpJson } = await readPod(bundleBytes)\n const { dump, seal } = parseExtractedPartitionBody(dumpJson)\n const deks = await unsealDeks(seal, transferKey) // throws TransferSealError on wrong key\n const backup = JSON.parse(dump) as { collections: Record<string, Record<string, EncryptedEnvelope>> }\n const out: Record<string, DecryptedRecord[]> = {}\n for (const [collection, byId] of Object.entries(backup.collections)) {\n const dek = deks.get(collection)\n if (dek === undefined) continue // no DEK sealed for this collection — skip\n const recs: DecryptedRecord[] = []\n for (const [id, env] of Object.entries(byId)) {\n const plaintext = await openEnvelopeJson({ collection, id }, env, dek)\n const body = JSON.parse(plaintext) as Record<string, unknown>\n recs.push({\n id,\n record: { ...body, id },\n ts: env._ts,\n version: env._v,\n ...(env._source !== undefined ? { source: env._source } : {}),\n ...(env._sourceTs !== undefined ? { sourceTs: env._sourceTs } : {}),\n })\n }\n out[collection] = recs\n }\n return out\n}\n"],"mappings":"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","names":[]}
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  DerivationCapExceededError,
3
3
  DerivationOutputShapeError
4
- } from "./chunk-JBIV4FLR.js";
4
+ } from "./chunk-SW4TOSJL.js";
5
5
 
6
6
  // src/with-formula/derivations/executor.ts
7
7
  var DerivationExecutor = {
@@ -121,4 +121,4 @@ var DerivationExecutor = {
121
121
  export {
122
122
  DerivationExecutor
123
123
  };
124
- //# sourceMappingURL=chunk-225O5CXQ.js.map
124
+ //# sourceMappingURL=chunk-O3SNM66K.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  NonAdditiveSchemaChangeError,
3
3
  SchemaLockedError
4
- } from "./chunk-JBIV4FLR.js";
4
+ } from "./chunk-SW4TOSJL.js";
5
5
 
6
6
  // src/with-shape/schema-update/strategies.ts
7
7
  function blindUpdate() {
@@ -62,4 +62,4 @@ export {
62
62
  lockSchema,
63
63
  coordinatedCutover
64
64
  };
65
- //# sourceMappingURL=chunk-YCSM3GZU.js.map
65
+ //# sourceMappingURL=chunk-OEJ4R52I.js.map
@@ -7,21 +7,21 @@ import {
7
7
  hashEntry,
8
8
  paddedIndex,
9
9
  sha256Hex
10
- } from "./chunk-RC4BROYR.js";
10
+ } from "./chunk-JRWLUWDM.js";
11
11
  import {
12
12
  buildRecordAad,
13
13
  openEnvelopeJson
14
- } from "./chunk-2LPVI4PX.js";
14
+ } from "./chunk-DOPZWTMJ.js";
15
15
  import {
16
16
  buildRecordEnvelope
17
- } from "./chunk-N4CNVSUF.js";
17
+ } from "./chunk-4RUFYGWG.js";
18
18
  import {
19
19
  encrypt
20
- } from "./chunk-W5LHQXZU.js";
20
+ } from "./chunk-USKHHOIV.js";
21
21
  import {
22
22
  LedgerContentionError,
23
23
  isConflictError
24
- } from "./chunk-JBIV4FLR.js";
24
+ } from "./chunk-SW4TOSJL.js";
25
25
 
26
26
  // src/with-commit/history/ledger/patch.ts
27
27
  function computePatch(prev, next) {
@@ -699,4 +699,4 @@ export {
699
699
  applyPatch,
700
700
  LedgerStore
701
701
  };
702
- //# sourceMappingURL=chunk-IESNYJXZ.js.map
702
+ //# sourceMappingURL=chunk-OKCQNMO6.js.map
@@ -7,27 +7,27 @@ import {
7
7
  PERIOD_FREEZES_COLLECTION,
8
8
  PERIOD_TARGET_PURGES_COLLECTION,
9
9
  periodExclusiveUpperBound
10
- } from "./chunk-Z7ZXZL6Y.js";
10
+ } from "./chunk-Q2ZN5DWZ.js";
11
11
  import {
12
12
  envelopeBodySize
13
- } from "./chunk-2LPVI4PX.js";
13
+ } from "./chunk-DOPZWTMJ.js";
14
14
  import {
15
15
  buildRecordEnvelope,
16
16
  isDeleteMarker,
17
17
  isTombstoneShape
18
- } from "./chunk-N4CNVSUF.js";
18
+ } from "./chunk-4RUFYGWG.js";
19
19
  import {
20
20
  decrypt,
21
21
  derivePresenceKey,
22
22
  encrypt
23
- } from "./chunk-W5LHQXZU.js";
23
+ } from "./chunk-USKHHOIV.js";
24
24
  import {
25
25
  NOYDB_SYNC_VERSION
26
- } from "./chunk-RK7N4OQ5.js";
26
+ } from "./chunk-N4CHCXDL.js";
27
27
  import {
28
28
  ValidationError,
29
29
  isConflictError
30
- } from "./chunk-JBIV4FLR.js";
30
+ } from "./chunk-SW4TOSJL.js";
31
31
 
32
32
  // src/with-sync/presence.ts
33
33
  var subtle = globalThis.crypto.subtle;
@@ -1213,4 +1213,4 @@ export {
1213
1213
  SyncEngine,
1214
1214
  SyncTransaction
1215
1215
  };
1216
- //# sourceMappingURL=chunk-H36KSN6X.js.map
1216
+ //# sourceMappingURL=chunk-OLUTCM23.js.map
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  ViaGraph
3
- } from "./chunk-5263OEM3.js";
3
+ } from "./chunk-XJP66QEN.js";
4
4
  import {
5
5
  sha256Hex
6
- } from "./chunk-W5LHQXZU.js";
6
+ } from "./chunk-USKHHOIV.js";
7
7
  import {
8
8
  DerivationCycleError,
9
9
  DuplicateBehaviorNameError
10
- } from "./chunk-JBIV4FLR.js";
10
+ } from "./chunk-SW4TOSJL.js";
11
11
 
12
12
  // src/with-formula/derivations/strategy-hash.ts
13
13
  async function computeStrategyHash(source, outputKeys, derive, sources) {
@@ -172,4 +172,4 @@ var DerivationRegistry = class {
172
172
  export {
173
173
  DerivationRegistry
174
174
  };
175
- //# sourceMappingURL=chunk-RDHUZ674.js.map
175
+ //# sourceMappingURL=chunk-OQDHIAR2.js.map
@@ -1,24 +1,25 @@
1
1
  import {
2
2
  freezeSnapshotOnly
3
- } from "./chunk-H7HP56F6.js";
3
+ } from "./chunk-5EC7X5QA.js";
4
4
  import {
5
5
  resolveManagedSecret
6
- } from "./chunk-Z2WK53N6.js";
6
+ } from "./chunk-JUBWUJY5.js";
7
7
  import {
8
8
  assertRosterTagValid,
9
9
  createOwnerKeyring,
10
10
  mintRosterTag,
11
+ nextRosterEpoch,
11
12
  requireRosterKey
12
- } from "./chunk-5W7YXFV5.js";
13
+ } from "./chunk-XJTGBHK6.js";
13
14
  import {
14
15
  buildRecordEnvelope
15
- } from "./chunk-N4CNVSUF.js";
16
+ } from "./chunk-4RUFYGWG.js";
16
17
  import {
17
18
  wrapKey
18
- } from "./chunk-W5LHQXZU.js";
19
+ } from "./chunk-USKHHOIV.js";
19
20
  import {
20
21
  PermissionDeniedError
21
- } from "./chunk-JBIV4FLR.js";
22
+ } from "./chunk-SW4TOSJL.js";
22
23
 
23
24
  // src/with-party/team/deed.ts
24
25
  var DEED_RECORD_ID = "deed";
@@ -107,7 +108,8 @@ async function liberateVault(vault, opts) {
107
108
  }
108
109
  const rosterKey = requireRosterKey(keyring, "liberateVault");
109
110
  const merged = { ...keyringFile, deks: mergedDeks };
110
- const mergedFile = { ...merged, roster_tag: await mintRosterTag(merged, rosterKey) };
111
+ const withEpoch = { ...merged, roster_epoch: nextRosterEpoch(keyringFile.roster_epoch) };
112
+ const mergedFile = { ...withEpoch, roster_tag: await mintRosterTag(withEpoch, rosterKey) };
111
113
  await adapter.put(vaultName, "_keyring", opts.newOwnerId, { ...env, _data: JSON.stringify(mergedFile) });
112
114
  await vault._getLedgerOrNull()?.append({
113
115
  op: "lifecycle",
@@ -135,4 +137,4 @@ export {
135
137
  isDeedVault,
136
138
  liberateVault
137
139
  };
138
- //# sourceMappingURL=chunk-KN4W2OQ4.js.map
140
+ //# sourceMappingURL=chunk-OXZSMX2H.js.map
@@ -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 NoydbSealer} — 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 { NoydbSealer } 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 `NoydbSealer.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: NoydbSealer,\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
+ {"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 NoydbSealer} — 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 { NoydbSealer } 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 `NoydbSealer.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: NoydbSealer,\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 { nextRosterEpoch } from '../team/roster-epoch.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 // #1097 — stamped BEFORE the tag is minted, so it lands inside the\n // authenticated canonical and a store can neither edit nor strip it.\n const withEpoch = { ...merged, roster_epoch: nextRosterEpoch(keyringFile.roster_epoch) }\n const mergedFile: KeyringFile = { ...withEpoch, roster_tag: await mintRosterTag(withEpoch, 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
  writePod
3
- } from "./chunk-6FOGTKBY.js";
3
+ } from "./chunk-RCONOOVF.js";
4
4
 
5
5
  // src/with-audit/portability/export-accessible.ts
6
6
  function resolveAccessibleCollections(keyring, scope, writableOnly = false) {
@@ -42,4 +42,4 @@ export {
42
42
  buildAccessibleBundle,
43
43
  exportAccessibleData
44
44
  };
45
- //# sourceMappingURL=chunk-DKWPJOYH.js.map
45
+ //# sourceMappingURL=chunk-P22XPNFW.js.map
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  installViaBinder
3
- } from "./chunk-XDVVBETV.js";
3
+ } from "./chunk-YHIAWECL.js";
4
4
  import {
5
5
  SealedHandle
6
- } from "./chunk-RK7N4OQ5.js";
6
+ } from "./chunk-N4CHCXDL.js";
7
7
  import {
8
8
  ClassifiedConfigError,
9
9
  ClassifiedNotEnabledError
10
- } from "./chunk-JBIV4FLR.js";
10
+ } from "./chunk-SW4TOSJL.js";
11
11
 
12
12
  // src/via/classified/descriptor.ts
13
13
  function isClassifiedFieldSpec(x) {
@@ -262,4 +262,4 @@ export {
262
262
  enforceClassifiedWrite,
263
263
  NO_CLASSIFIED
264
264
  };
265
- //# sourceMappingURL=chunk-GK4DRVUD.js.map
265
+ //# sourceMappingURL=chunk-P2RJAVMR.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  SealedRecordNotEnabledError
3
- } from "./chunk-JBIV4FLR.js";
3
+ } from "./chunk-SW4TOSJL.js";
4
4
 
5
5
  // src/with-audit/sealed-record/strategy.ts
6
6
  var NO_SEALED_RECORD = {
@@ -18,4 +18,4 @@ var NO_SEALED_RECORD = {
18
18
  export {
19
19
  NO_SEALED_RECORD
20
20
  };
21
- //# sourceMappingURL=chunk-UCUALOSM.js.map
21
+ //# sourceMappingURL=chunk-P7KJME6C.js.map
@@ -4,10 +4,10 @@ import {
4
4
  } from "./chunk-KHKKD62N.js";
5
5
  import {
6
6
  derivePersistedSchema
7
- } from "./chunk-P6ASQOZR.js";
7
+ } from "./chunk-VT4DTCK5.js";
8
8
  import {
9
9
  loadPersistedSchema
10
- } from "./chunk-YXA2TCTZ.js";
10
+ } from "./chunk-I5LSKXT6.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-HM4JSXX2.js.map
241
+ //# sourceMappingURL=chunk-PCIBCL26.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  BrokerNotEnabledError
3
- } from "./chunk-JBIV4FLR.js";
3
+ } from "./chunk-SW4TOSJL.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-4A4TYISP.js.map
30
+ //# sourceMappingURL=chunk-PV7XXAXK.js.map
@@ -1,20 +1,20 @@
1
1
  import {
2
2
  linkCollectionName,
3
3
  linkRowKey
4
- } from "./chunk-WLLUM35R.js";
4
+ } from "./chunk-KQIDBIZL.js";
5
5
  import {
6
6
  buildRecordAad,
7
7
  openEnvelopeJson
8
- } from "./chunk-2LPVI4PX.js";
8
+ } from "./chunk-DOPZWTMJ.js";
9
9
  import {
10
10
  buildRecordEnvelope
11
- } from "./chunk-N4CNVSUF.js";
11
+ } from "./chunk-4RUFYGWG.js";
12
12
  import {
13
13
  encrypt
14
- } from "./chunk-W5LHQXZU.js";
14
+ } from "./chunk-USKHHOIV.js";
15
15
  import {
16
16
  NoydbError
17
- } from "./chunk-JBIV4FLR.js";
17
+ } from "./chunk-SW4TOSJL.js";
18
18
 
19
19
  // src/with-shape/links/link-set.ts
20
20
  var LinkSet = class {
@@ -130,4 +130,4 @@ export {
130
130
  LinkSet,
131
131
  LinkEndpointError
132
132
  };
133
- //# sourceMappingURL=chunk-5AFMP532.js.map
133
+ //# sourceMappingURL=chunk-Q2OAAREU.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  ValidationError
3
- } from "./chunk-JBIV4FLR.js";
3
+ } from "./chunk-SW4TOSJL.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-Z7ZXZL6Y.js.map
26
+ //# sourceMappingURL=chunk-Q2ZN5DWZ.js.map
@@ -5,7 +5,7 @@ import {
5
5
  buildStringFieldEntries,
6
6
  extractSnippet,
7
7
  searchScan
8
- } from "./chunk-S35S77YU.js";
8
+ } from "./chunk-IAHDSFFA.js";
9
9
  import {
10
10
  fuseRetrieval
11
11
  } from "./chunk-AURFOK3D.js";
@@ -13,14 +13,14 @@ import {
13
13
  getAtPath,
14
14
  isStaticDictDescriptor,
15
15
  stripI18nFilled
16
- } from "./chunk-X67FCULK.js";
16
+ } from "./chunk-DIVY2CJZ.js";
17
17
  import {
18
18
  liveRecordIsElevated
19
- } from "./chunk-POS53FG6.js";
19
+ } from "./chunk-IZTU6RKH.js";
20
20
  import {
21
21
  EmbeddingDimMismatchError,
22
22
  EmbeddingModelMismatchError
23
- } from "./chunk-JBIV4FLR.js";
23
+ } from "./chunk-SW4TOSJL.js";
24
24
 
25
25
  // src/with-lookup/embeddings/cosine.ts
26
26
  function cosine(a, b) {
@@ -394,4 +394,4 @@ export {
394
394
  rebuildEmbeddings,
395
395
  syncTierSearch
396
396
  };
397
- //# sourceMappingURL=chunk-L6GTLZRK.js.map
397
+ //# sourceMappingURL=chunk-QJLOWGOU.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  NoydbError
3
- } from "./chunk-JBIV4FLR.js";
3
+ } from "./chunk-SW4TOSJL.js";
4
4
 
5
5
  // src/with-formula/computed/index.ts
6
6
  var ComputedFieldError = class extends NoydbError {
@@ -35,4 +35,4 @@ export {
35
35
  ComputedFieldError,
36
36
  evalComputedFields
37
37
  };
38
- //# sourceMappingURL=chunk-7LYUJNU3.js.map
38
+ //# sourceMappingURL=chunk-QOHGWFAW.js.map