@noy-db/hub 0.6.0-pre.0 → 0.6.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 (285) hide show
  1. package/codemods/0.4.0-pre.json +699 -0
  2. package/dist/{api-67SBPMMH.js → api-RXUMEKT3.js} +6 -6
  3. package/dist/attestation/index.js +12 -12
  4. package/dist/attestation/index.js.map +1 -1
  5. package/dist/{backup-GAYWQAFN.js → backup-AVAGHAJE.js} +25 -6
  6. package/dist/backup-AVAGHAJE.js.map +1 -0
  7. package/dist/blobs/index.js +5 -5
  8. package/dist/broker/index.js +6 -6
  9. package/dist/{bundle-handle-5OUAI7CV.js → bundle-handle-GFNHT52M.js} +2 -2
  10. package/dist/cargo/index.js +18 -18
  11. package/dist/{chunk-CYQOUTMY.js → chunk-2BMRJ6LQ.js} +2 -2
  12. package/dist/{chunk-HS7HNYBD.js → chunk-2DHSSLOD.js} +6 -6
  13. package/dist/{chunk-JH3OHQM4.js → chunk-2Z3NCLNX.js} +6 -6
  14. package/dist/{chunk-NVU7ZMPN.js → chunk-3IXIU6FP.js} +2 -2
  15. package/dist/{chunk-XBLKM73C.js → chunk-3JVXVJ7L.js} +8 -8
  16. package/dist/{chunk-FY343IZR.js → chunk-3URQC7EH.js} +3 -3
  17. package/dist/{chunk-BPTZ4K5L.js → chunk-4GZ6XOVW.js} +7 -7
  18. package/dist/{chunk-ROWL352P.js → chunk-4I72F5DF.js} +4 -4
  19. package/dist/{chunk-EK7DT5BT.js → chunk-4VUPLMZ6.js} +39 -3
  20. package/dist/chunk-4VUPLMZ6.js.map +1 -0
  21. package/dist/{chunk-LBGPO5RL.js → chunk-52JPHN5N.js} +4 -4
  22. package/dist/{chunk-27TCYH6G.js → chunk-5JY5TSVY.js} +3 -3
  23. package/dist/{chunk-27TCYH6G.js.map → chunk-5JY5TSVY.js.map} +1 -1
  24. package/dist/chunk-5O5HRRTV.js +201 -0
  25. package/dist/chunk-5O5HRRTV.js.map +1 -0
  26. package/dist/{chunk-ZXJXDHNK.js → chunk-5ZKS6ZE2.js} +2 -2
  27. package/dist/{chunk-ZXJXDHNK.js.map → chunk-5ZKS6ZE2.js.map} +1 -1
  28. package/dist/{chunk-MVOWXQHN.js → chunk-6BU3L4UE.js} +2 -2
  29. package/dist/{chunk-OSFPNKY4.js → chunk-6FJWSWFT.js} +2 -2
  30. package/dist/chunk-6FJWSWFT.js.map +1 -0
  31. package/dist/{chunk-CJ73OLMW.js → chunk-6HFM7EIT.js} +1 -1
  32. package/dist/chunk-6HFM7EIT.js.map +1 -0
  33. package/dist/{chunk-PGAPBZEK.js → chunk-6NVPFKN3.js} +4 -4
  34. package/dist/{chunk-24UICKTB.js → chunk-6SAFL5YE.js} +2 -2
  35. package/dist/chunk-6SAFL5YE.js.map +1 -0
  36. package/dist/{chunk-NQRJ5AJO.js → chunk-7H73RIE3.js} +2 -2
  37. package/dist/{chunk-NQCNSVGI.js → chunk-7MNBICB5.js} +3 -3
  38. package/dist/{chunk-T4GPR2IR.js → chunk-7TSYBD3E.js} +1 -1
  39. package/dist/chunk-7TSYBD3E.js.map +1 -0
  40. package/dist/{chunk-TLNNHG3A.js → chunk-ADW22QSB.js} +3 -3
  41. package/dist/{chunk-TLNNHG3A.js.map → chunk-ADW22QSB.js.map} +1 -1
  42. package/dist/{chunk-3UK6STWO.js → chunk-BEFVYAR5.js} +3 -3
  43. package/dist/{chunk-TFZ7LLOQ.js → chunk-BRVW2GS5.js} +5 -5
  44. package/dist/{chunk-V5C5NNBR.js → chunk-CDB2HVQW.js} +3 -3
  45. package/dist/{chunk-3HYWYLXL.js → chunk-CEJWMBXO.js} +1 -1
  46. package/dist/chunk-CEJWMBXO.js.map +1 -0
  47. package/dist/{chunk-2KIV7BEK.js → chunk-FDX7OWWI.js} +1 -1
  48. package/dist/chunk-FDX7OWWI.js.map +1 -0
  49. package/dist/{chunk-4MQDV3HZ.js → chunk-FFDNKRCY.js} +2 -2
  50. package/dist/{chunk-PP5CO2PR.js → chunk-FMQJZH4R.js} +2 -2
  51. package/dist/{chunk-JSRU5W2M.js → chunk-FZ6NYJ7L.js} +3 -3
  52. package/dist/{chunk-ZGGVOADG.js → chunk-G6S5VVHP.js} +2 -2
  53. package/dist/{chunk-3IIPWA75.js → chunk-GAG7QOVO.js} +27 -2
  54. package/dist/chunk-GAG7QOVO.js.map +1 -0
  55. package/dist/{chunk-JXIDGFKS.js → chunk-HPLWFNG4.js} +3 -1
  56. package/dist/chunk-HPLWFNG4.js.map +1 -0
  57. package/dist/{chunk-ZWMO5GL5.js → chunk-JJNOLSG5.js} +3 -3
  58. package/dist/{chunk-RLWY6Z44.js → chunk-JRKZTEZZ.js} +62 -6
  59. package/dist/chunk-JRKZTEZZ.js.map +1 -0
  60. package/dist/chunk-N35NC4JH.js +123 -0
  61. package/dist/chunk-N35NC4JH.js.map +1 -0
  62. package/dist/{chunk-3CLZY46Y.js → chunk-N3BI6P3J.js} +295 -109
  63. package/dist/chunk-N3BI6P3J.js.map +1 -0
  64. package/dist/{chunk-SRGJET2F.js → chunk-NJDQ4YSV.js} +2 -2
  65. package/dist/{chunk-JEM2IGS3.js → chunk-NPP5R7FF.js} +5 -5
  66. package/dist/{chunk-DPJTDNUF.js → chunk-O2ERS4UJ.js} +5 -5
  67. package/dist/{chunk-F3GVO44K.js → chunk-PDLLCOGD.js} +3 -3
  68. package/dist/{chunk-VBY6ZLJT.js → chunk-PL2GHSCM.js} +3 -3
  69. package/dist/{chunk-DCMQR46R.js → chunk-PNKHAKQ7.js} +3 -3
  70. package/dist/{chunk-MXZ5TSTR.js → chunk-PPMBY7YS.js} +6 -6
  71. package/dist/{chunk-ZK4CO2KZ.js → chunk-Q6TEJXBX.js} +4 -4
  72. package/dist/{chunk-GS5RT2KK.js → chunk-QULVCV3M.js} +2 -2
  73. package/dist/chunk-QULVCV3M.js.map +1 -0
  74. package/dist/{chunk-KZ3KMDN3.js → chunk-RTAMLDWP.js} +6 -2
  75. package/dist/chunk-RTAMLDWP.js.map +1 -0
  76. package/dist/{chunk-MZ5ZFO2D.js → chunk-RXYYFSBB.js} +82 -110
  77. package/dist/chunk-RXYYFSBB.js.map +1 -0
  78. package/dist/{chunk-4VCWI42L.js → chunk-SUFG5E73.js} +2 -2
  79. package/dist/{chunk-SKONR2OL.js → chunk-U5O6GIWZ.js} +2 -2
  80. package/dist/{chunk-HFKGIBMD.js → chunk-VZ3XFUQ7.js} +2 -2
  81. package/dist/{chunk-3EO7RZLJ.js → chunk-W77KZHCW.js} +4 -4
  82. package/dist/{chunk-P7NGLLUF.js → chunk-WASHZV34.js} +2 -2
  83. package/dist/{chunk-XB7LUDKM.js → chunk-WFUIE565.js} +3 -3
  84. package/dist/{chunk-RPXL6KSX.js → chunk-WLZ47GSL.js} +3 -3
  85. package/dist/{chunk-MJWCLSQL.js → chunk-X56RTUK3.js} +3 -3
  86. package/dist/{chunk-OMSAULZM.js → chunk-XEJA6K76.js} +9 -9
  87. package/dist/{chunk-MC2LFTQM.js → chunk-XWX7GL56.js} +2 -2
  88. package/dist/{chunk-46V67XP5.js → chunk-YJ6IONGA.js} +2 -2
  89. package/dist/chunk-YJ6IONGA.js.map +1 -0
  90. package/dist/{chunk-24ZLWWEO.js → chunk-YPYHVOXP.js} +1 -1
  91. package/dist/chunk-YPYHVOXP.js.map +1 -0
  92. package/dist/{chunk-2LGDCNFJ.js → chunk-Z45YRGFO.js} +1 -1
  93. package/dist/chunk-Z45YRGFO.js.map +1 -0
  94. package/dist/classified/index.js +3 -3
  95. package/dist/{classified-marker-MH3ON5OL.js → classified-marker-2KJAXRRO.js} +3 -3
  96. package/dist/{collection-facade-AHT7FATG.js → collection-facade-QEJIM6BC.js} +8 -8
  97. package/dist/consent/index.js +4 -4
  98. package/dist/cover/index.js +2 -2
  99. package/dist/custody/index.js +6 -6
  100. package/dist/{dead-filter-U575NGSH.js → dead-filter-DCB62VWW.js} +2 -2
  101. package/dist/{delegation-PDYL6RWT.js → delegation-MO7YZYJS.js} +4 -4
  102. package/dist/derivations/index.js +6 -6
  103. package/dist/{derive-AKT4KU36.js → derive-IUA6JFLB.js} +5 -5
  104. package/dist/directory/index.js +5 -5
  105. package/dist/{dispatch-4XIJSFTT.js → dispatch-FZEAWKVM.js} +5 -5
  106. package/dist/{dispatch-N5HGVUGU.js → dispatch-MJ6SHB3Y.js} +9 -9
  107. package/dist/{enclave-OPK24QDR.js → enclave-JU4YIEPB.js} +4 -4
  108. package/dist/{executor-3JZ4POTW.js → executor-YIQB2S6N.js} +9 -8
  109. package/dist/{export-accessible-CPTP5STN.js → export-accessible-4S36PQNR.js} +7 -7
  110. package/dist/{extract-partition-TWXPHVU7.js → extract-partition-IO7FDZ2P.js} +10 -10
  111. package/dist/{fanout-sidecar-T2ZGLQFE.js → fanout-sidecar-NNAJQXMX.js} +4 -4
  112. package/dist/forget/index.js +4 -4
  113. package/dist/guards/index.js +1 -1
  114. package/dist/history/index.js +6 -6
  115. package/dist/i18n/index.js +6 -6
  116. package/dist/index.d.ts +3 -2
  117. package/dist/index.js +69 -63
  118. package/dist/index.js.map +1 -1
  119. package/dist/introspection/index.js +6 -6
  120. package/dist/{issue-N74C55X6.js → issue-RIVHSY2S.js} +6 -6
  121. package/dist/kernel/secret-mode.d.ts +1 -1
  122. package/dist/kernel/types.d.ts +41 -6
  123. package/dist/kernel/vault.d.ts +19 -15
  124. package/dist/{ledger-DONWFC5M.js → ledger-AETNF4OM.js} +6 -6
  125. package/dist/liberate-GFN4C7RR.js +24 -0
  126. package/dist/{link-set-2TTP4VLO.js → link-set-E5HNY67I.js} +5 -5
  127. package/dist/{managed-secret-EAOYWRYF.js → managed-secret-CWQ6PND5.js} +3 -3
  128. package/dist/materialized-views/index.js +10 -9
  129. package/dist/money/index.js +10 -6
  130. package/dist/{noydb-6W2XGQCS.js → noydb-SNZONAYA.js} +28 -28
  131. package/dist/overlay-views/index.js +1 -1
  132. package/dist/periods/index.js +17 -7
  133. package/dist/pod/index.js +31 -31
  134. package/dist/policy/index.js +3 -3
  135. package/dist/port/with/collection-options.d.ts +1 -1
  136. package/dist/portability/index.js +6 -6
  137. package/dist/{post-register-ORQOQJCS.js → post-register-2XSSMGEQ.js} +4 -4
  138. package/dist/{register-LHETZRJM.js → register-4EFJCVYD.js} +11 -11
  139. package/dist/{registry-JRIN447B.js → registry-4SDHHOJ7.js} +6 -6
  140. package/dist/{registry-AMAZ6QRZ.js → registry-OYTFGWVK.js} +4 -4
  141. package/dist/{request-withdrawal-2DN2RGCO.js → request-withdrawal-KGXGDPVQ.js} +9 -9
  142. package/dist/{reveal-AG4SCHUQ.js → reveal-BW36KCOQ.js} +3 -3
  143. package/dist/{revoke-ZX4NM2CJ.js → revoke-JFN773KF.js} +6 -6
  144. package/dist/sealed-record/index.js +6 -6
  145. package/dist/search/index.js +1 -1
  146. package/dist/{seed-IRCDGIRK.js → seed-GDV5PT4R.js} +6 -6
  147. package/dist/sequence/index.js +4 -4
  148. package/dist/session/index.js +3 -3
  149. package/dist/{signer-7KHD4OL2.js → signer-TA55QB6R.js} +5 -5
  150. package/dist/snapshots/index.js +5 -5
  151. package/dist/{stale-K734VACF.js → stale-ARHFVL5U.js} +5 -5
  152. package/dist/{storage-4H2GF6RQ.js → storage-V7MTFAQJ.js} +5 -5
  153. package/dist/{store-coordination-provider-4SKLSFUG.js → store-coordination-provider-GFCUOBR6.js} +3 -3
  154. package/dist/sync/index.js +5 -5
  155. package/dist/team/index.js +8 -8
  156. package/dist/tiers/index.js +4 -4
  157. package/dist/via/classified/descriptor.d.ts +1 -1
  158. package/dist/via/money/exact.d.ts +44 -0
  159. package/dist/via/money/index.d.ts +2 -0
  160. package/dist/via/money/normalize.d.ts +20 -0
  161. package/dist/{walk-MQHYNDLZ.js → walk-3ZECBFDA.js} +7 -7
  162. package/dist/with-audit/attestation/index.d.ts +1 -1
  163. package/dist/with-audit/guards/immutable-guard.d.ts +14 -0
  164. package/dist/with-audit/guards/with-guard.d.ts +1 -1
  165. package/dist/with-audit/periods/active.d.ts +28 -1
  166. package/dist/with-audit/periods/index.d.ts +4 -2
  167. package/dist/with-audit/periods/periods.d.ts +160 -5
  168. package/dist/with-audit/periods/strategy.d.ts +13 -4
  169. package/dist/with-audit/periods/vault-facade.d.ts +89 -10
  170. package/dist/with-audit/periods/window.d.ts +10 -0
  171. package/dist/with-cargo/index.d.ts +2 -2
  172. package/dist/with-commit/history/ledger/entry.d.ts +1 -1
  173. package/dist/with-commit/numbering/descriptor.d.ts +1 -1
  174. package/dist/with-formula/derivations/with-derivation.d.ts +1 -1
  175. package/dist/with-formula/materialized-views/types.d.ts +52 -0
  176. package/dist/with-formula/materialized-views/with-materialized-view.d.ts +3 -3
  177. package/dist/with-formula/overlay-views/with-overlayed-view.d.ts +1 -1
  178. package/dist/with-party/custody/index.d.ts +1 -1
  179. package/dist/with-party/directory/user-envelope/index.d.ts +1 -1
  180. package/dist/with-party/directory/user-envelope/storage.d.ts +1 -1
  181. package/dist/with-party/team/echo-ceremony.d.ts +3 -3
  182. package/dist/with-party/team/echo-secret.d.ts +2 -2
  183. package/dist/with-party/team/keyring.d.ts +10 -1
  184. package/dist/with-pod/bundle.d.ts +15 -0
  185. package/dist/with-shape/introspection/index.d.ts +2 -1
  186. package/dist/with-shape/introspection/types.d.ts +1 -1
  187. package/dist/with-shape/persisted-schemas/derive.d.ts +1 -1
  188. package/dist/with-shape/persisted-schemas/index.d.ts +1 -1
  189. package/dist/with-shape/persisted-schemas/types.d.ts +1 -1
  190. package/dist/{withdraw-accessible-JSDQHXHE.js → withdraw-accessible-7PG4DYQK.js} +8 -8
  191. package/package.json +6 -4
  192. package/dist/backup-GAYWQAFN.js.map +0 -1
  193. package/dist/chunk-24UICKTB.js.map +0 -1
  194. package/dist/chunk-24ZLWWEO.js.map +0 -1
  195. package/dist/chunk-2KIV7BEK.js.map +0 -1
  196. package/dist/chunk-2LGDCNFJ.js.map +0 -1
  197. package/dist/chunk-3CLZY46Y.js.map +0 -1
  198. package/dist/chunk-3HYWYLXL.js.map +0 -1
  199. package/dist/chunk-3IIPWA75.js.map +0 -1
  200. package/dist/chunk-46V67XP5.js.map +0 -1
  201. package/dist/chunk-CJ73OLMW.js.map +0 -1
  202. package/dist/chunk-EK7DT5BT.js.map +0 -1
  203. package/dist/chunk-GS5RT2KK.js.map +0 -1
  204. package/dist/chunk-JXIDGFKS.js.map +0 -1
  205. package/dist/chunk-KZ3KMDN3.js.map +0 -1
  206. package/dist/chunk-LTU4FLHG.js +0 -131
  207. package/dist/chunk-LTU4FLHG.js.map +0 -1
  208. package/dist/chunk-MZ5ZFO2D.js.map +0 -1
  209. package/dist/chunk-OSFPNKY4.js.map +0 -1
  210. package/dist/chunk-RLWY6Z44.js.map +0 -1
  211. package/dist/chunk-T4GPR2IR.js.map +0 -1
  212. package/dist/liberate-KICI7AJN.js +0 -24
  213. /package/dist/{api-67SBPMMH.js.map → api-RXUMEKT3.js.map} +0 -0
  214. /package/dist/{bundle-handle-5OUAI7CV.js.map → bundle-handle-GFNHT52M.js.map} +0 -0
  215. /package/dist/{chunk-CYQOUTMY.js.map → chunk-2BMRJ6LQ.js.map} +0 -0
  216. /package/dist/{chunk-HS7HNYBD.js.map → chunk-2DHSSLOD.js.map} +0 -0
  217. /package/dist/{chunk-JH3OHQM4.js.map → chunk-2Z3NCLNX.js.map} +0 -0
  218. /package/dist/{chunk-NVU7ZMPN.js.map → chunk-3IXIU6FP.js.map} +0 -0
  219. /package/dist/{chunk-XBLKM73C.js.map → chunk-3JVXVJ7L.js.map} +0 -0
  220. /package/dist/{chunk-FY343IZR.js.map → chunk-3URQC7EH.js.map} +0 -0
  221. /package/dist/{chunk-BPTZ4K5L.js.map → chunk-4GZ6XOVW.js.map} +0 -0
  222. /package/dist/{chunk-ROWL352P.js.map → chunk-4I72F5DF.js.map} +0 -0
  223. /package/dist/{chunk-LBGPO5RL.js.map → chunk-52JPHN5N.js.map} +0 -0
  224. /package/dist/{chunk-MVOWXQHN.js.map → chunk-6BU3L4UE.js.map} +0 -0
  225. /package/dist/{chunk-PGAPBZEK.js.map → chunk-6NVPFKN3.js.map} +0 -0
  226. /package/dist/{chunk-NQRJ5AJO.js.map → chunk-7H73RIE3.js.map} +0 -0
  227. /package/dist/{chunk-NQCNSVGI.js.map → chunk-7MNBICB5.js.map} +0 -0
  228. /package/dist/{chunk-3UK6STWO.js.map → chunk-BEFVYAR5.js.map} +0 -0
  229. /package/dist/{chunk-TFZ7LLOQ.js.map → chunk-BRVW2GS5.js.map} +0 -0
  230. /package/dist/{chunk-V5C5NNBR.js.map → chunk-CDB2HVQW.js.map} +0 -0
  231. /package/dist/{chunk-4MQDV3HZ.js.map → chunk-FFDNKRCY.js.map} +0 -0
  232. /package/dist/{chunk-PP5CO2PR.js.map → chunk-FMQJZH4R.js.map} +0 -0
  233. /package/dist/{chunk-JSRU5W2M.js.map → chunk-FZ6NYJ7L.js.map} +0 -0
  234. /package/dist/{chunk-ZGGVOADG.js.map → chunk-G6S5VVHP.js.map} +0 -0
  235. /package/dist/{chunk-ZWMO5GL5.js.map → chunk-JJNOLSG5.js.map} +0 -0
  236. /package/dist/{chunk-SRGJET2F.js.map → chunk-NJDQ4YSV.js.map} +0 -0
  237. /package/dist/{chunk-JEM2IGS3.js.map → chunk-NPP5R7FF.js.map} +0 -0
  238. /package/dist/{chunk-DPJTDNUF.js.map → chunk-O2ERS4UJ.js.map} +0 -0
  239. /package/dist/{chunk-F3GVO44K.js.map → chunk-PDLLCOGD.js.map} +0 -0
  240. /package/dist/{chunk-VBY6ZLJT.js.map → chunk-PL2GHSCM.js.map} +0 -0
  241. /package/dist/{chunk-DCMQR46R.js.map → chunk-PNKHAKQ7.js.map} +0 -0
  242. /package/dist/{chunk-MXZ5TSTR.js.map → chunk-PPMBY7YS.js.map} +0 -0
  243. /package/dist/{chunk-ZK4CO2KZ.js.map → chunk-Q6TEJXBX.js.map} +0 -0
  244. /package/dist/{chunk-4VCWI42L.js.map → chunk-SUFG5E73.js.map} +0 -0
  245. /package/dist/{chunk-SKONR2OL.js.map → chunk-U5O6GIWZ.js.map} +0 -0
  246. /package/dist/{chunk-HFKGIBMD.js.map → chunk-VZ3XFUQ7.js.map} +0 -0
  247. /package/dist/{chunk-3EO7RZLJ.js.map → chunk-W77KZHCW.js.map} +0 -0
  248. /package/dist/{chunk-P7NGLLUF.js.map → chunk-WASHZV34.js.map} +0 -0
  249. /package/dist/{chunk-XB7LUDKM.js.map → chunk-WFUIE565.js.map} +0 -0
  250. /package/dist/{chunk-RPXL6KSX.js.map → chunk-WLZ47GSL.js.map} +0 -0
  251. /package/dist/{chunk-MJWCLSQL.js.map → chunk-X56RTUK3.js.map} +0 -0
  252. /package/dist/{chunk-OMSAULZM.js.map → chunk-XEJA6K76.js.map} +0 -0
  253. /package/dist/{chunk-MC2LFTQM.js.map → chunk-XWX7GL56.js.map} +0 -0
  254. /package/dist/{classified-marker-MH3ON5OL.js.map → classified-marker-2KJAXRRO.js.map} +0 -0
  255. /package/dist/{collection-facade-AHT7FATG.js.map → collection-facade-QEJIM6BC.js.map} +0 -0
  256. /package/dist/{dead-filter-U575NGSH.js.map → dead-filter-DCB62VWW.js.map} +0 -0
  257. /package/dist/{delegation-PDYL6RWT.js.map → delegation-MO7YZYJS.js.map} +0 -0
  258. /package/dist/{derive-AKT4KU36.js.map → derive-IUA6JFLB.js.map} +0 -0
  259. /package/dist/{dispatch-4XIJSFTT.js.map → dispatch-FZEAWKVM.js.map} +0 -0
  260. /package/dist/{dispatch-N5HGVUGU.js.map → dispatch-MJ6SHB3Y.js.map} +0 -0
  261. /package/dist/{enclave-OPK24QDR.js.map → enclave-JU4YIEPB.js.map} +0 -0
  262. /package/dist/{executor-3JZ4POTW.js.map → executor-YIQB2S6N.js.map} +0 -0
  263. /package/dist/{export-accessible-CPTP5STN.js.map → export-accessible-4S36PQNR.js.map} +0 -0
  264. /package/dist/{extract-partition-TWXPHVU7.js.map → extract-partition-IO7FDZ2P.js.map} +0 -0
  265. /package/dist/{fanout-sidecar-T2ZGLQFE.js.map → fanout-sidecar-NNAJQXMX.js.map} +0 -0
  266. /package/dist/{issue-N74C55X6.js.map → issue-RIVHSY2S.js.map} +0 -0
  267. /package/dist/{ledger-DONWFC5M.js.map → ledger-AETNF4OM.js.map} +0 -0
  268. /package/dist/{liberate-KICI7AJN.js.map → liberate-GFN4C7RR.js.map} +0 -0
  269. /package/dist/{link-set-2TTP4VLO.js.map → link-set-E5HNY67I.js.map} +0 -0
  270. /package/dist/{managed-secret-EAOYWRYF.js.map → managed-secret-CWQ6PND5.js.map} +0 -0
  271. /package/dist/{noydb-6W2XGQCS.js.map → noydb-SNZONAYA.js.map} +0 -0
  272. /package/dist/{post-register-ORQOQJCS.js.map → post-register-2XSSMGEQ.js.map} +0 -0
  273. /package/dist/{register-LHETZRJM.js.map → register-4EFJCVYD.js.map} +0 -0
  274. /package/dist/{registry-AMAZ6QRZ.js.map → registry-4SDHHOJ7.js.map} +0 -0
  275. /package/dist/{registry-JRIN447B.js.map → registry-OYTFGWVK.js.map} +0 -0
  276. /package/dist/{request-withdrawal-2DN2RGCO.js.map → request-withdrawal-KGXGDPVQ.js.map} +0 -0
  277. /package/dist/{reveal-AG4SCHUQ.js.map → reveal-BW36KCOQ.js.map} +0 -0
  278. /package/dist/{revoke-ZX4NM2CJ.js.map → revoke-JFN773KF.js.map} +0 -0
  279. /package/dist/{seed-IRCDGIRK.js.map → seed-GDV5PT4R.js.map} +0 -0
  280. /package/dist/{signer-7KHD4OL2.js.map → signer-TA55QB6R.js.map} +0 -0
  281. /package/dist/{stale-K734VACF.js.map → stale-ARHFVL5U.js.map} +0 -0
  282. /package/dist/{storage-4H2GF6RQ.js.map → storage-V7MTFAQJ.js.map} +0 -0
  283. /package/dist/{store-coordination-provider-4SKLSFUG.js.map → store-coordination-provider-GFCUOBR6.js.map} +0 -0
  284. /package/dist/{walk-MQHYNDLZ.js.map → walk-3ZECBFDA.js.map} +0 -0
  285. /package/dist/{withdraw-accessible-JSDQHXHE.js.map → withdraw-accessible-7PG4DYQK.js.map} +0 -0
@@ -268,6 +268,21 @@ export interface WritePodOptions {
268
268
  }
269
269
  /** @deprecated Use `WritePodOptions`. */
270
270
  export type WriteNoydbBundleOptions = WritePodOptions;
271
+ /**
272
+ * Every key `writePod` reads, in declaration order (#991).
273
+ *
274
+ * A pod is a wire artifact, so an option this list doesn't name is refused
275
+ * rather than ignored: a dropped write option produces a structurally valid
276
+ * bundle that is missing something, and the defect surfaces later — in
277
+ * whoever imports it — with nothing left to trace it back to.
278
+ *
279
+ * `bundle-option-keys.test.ts` parses `WritePodOptions` out of this file and
280
+ * fails if the two ever drift, so adding an option is enough; you do not have
281
+ * to remember to update this list, only to keep the interface shape parseable.
282
+ *
283
+ * @internal
284
+ */
285
+ export declare const WRITE_POD_OPTION_KEYS: readonly ["compression", "collections", "since", "where", "tierAtMost", "exportSecret", "recipients", "autoCredentials", "sealedCredentials", "autoSecrets", "sealedSecrets", "sign", "engineRange", "unlockMethods", "hasApp", "species", "pointerMode", "redirect"];
271
286
  /**
272
287
  * Result returned by `readPod`. The caller is expected to
273
288
  * pass `dumpJson` into `vault.load(json, secret)` to
@@ -3,7 +3,7 @@
3
3
  * {@link VaultSchemaSnapshot} describing the vault's shape and (optional)
4
4
  * stats. Consumed by `noydb describe` for human-readable audit output.
5
5
  *
6
- * @see docs/superpowers/specs/2026-05-22-schema-dump-design.md
6
+ * @see design-history/2026-05-22-schema-dump-design.md
7
7
  *
8
8
  * @module
9
9
  */
@@ -14,6 +14,7 @@ export { jsonSchemaToFields } from './fields.js';
14
14
  export type { SchemaIntrospection } from './types.js';
15
15
  export type { FieldMeta, SemanticType } from './field-meta.js';
16
16
  export type { CollectionDescription, DescribedField, DescribeOptions } from './describe.js';
17
+ export type { StandardSchemaV1Issue } from '../../kernel/schema.js';
17
18
  export { applyListProjection } from './projection.js';
18
19
  export type { ListProjectionOptions } from './projection.js';
19
20
  export type { BehaviorSummary, GuardBehaviorEntry, DerivationBehaviorEntry, DerivationOutputEntry, MaterializedViewBehaviorEntry, OverlayBehaviorEntry, SatelliteBehaviorEntry, } from './behaviors.js';
@@ -3,7 +3,7 @@
3
3
  * by `vault.dumpSchema()`. Consumed by the upcoming `noydb describe`
4
4
  * CLI to emit human-readable YAML/JSON audit output.
5
5
  *
6
- * @see docs/superpowers/specs/2026-05-22-schema-dump-design.md
6
+ * @see design-history/2026-05-22-schema-dump-design.md
7
7
  *
8
8
  * @module
9
9
  */
@@ -5,7 +5,7 @@
5
5
  * hub never statically imports zod. Other validator families write a stub
6
6
  * envelope flagging the kind.
7
7
  *
8
- * @see docs/superpowers/specs/2026-05-22-schema-dump-design.md
8
+ * @see design-history/2026-05-22-schema-dump-design.md
9
9
  *
10
10
  * @module
11
11
  */
@@ -10,7 +10,7 @@
10
10
  * Standard Schema validators (Valibot, ArkType, Effect Schema) write a
11
11
  * stub envelope flagging the kind without a JSON Schema body.
12
12
  *
13
- * @see docs/superpowers/specs/2026-05-22-schema-dump-design.md
13
+ * @see design-history/2026-05-22-schema-dump-design.md
14
14
  *
15
15
  * @module
16
16
  */
@@ -5,7 +5,7 @@
5
5
  * collection's records. Auditors who can unlock the collection's data can
6
6
  * also read its schema; nothing more.
7
7
  *
8
- * @see docs/superpowers/specs/2026-05-22-schema-dump-design.md
8
+ * @see design-history/2026-05-22-schema-dump-design.md
9
9
  *
10
10
  * @module
11
11
  */
@@ -4,18 +4,18 @@ import {
4
4
  freezeSnapshotOnly,
5
5
  randomId,
6
6
  withdrawAccessibleData
7
- } from "./chunk-JSRU5W2M.js";
8
- import "./chunk-4MQDV3HZ.js";
9
- import "./chunk-EK7DT5BT.js";
10
- import "./chunk-CYQOUTMY.js";
11
- import "./chunk-FY343IZR.js";
12
- import "./chunk-NQRJ5AJO.js";
7
+ } from "./chunk-FZ6NYJ7L.js";
8
+ import "./chunk-FFDNKRCY.js";
9
+ import "./chunk-4VUPLMZ6.js";
10
+ import "./chunk-2BMRJ6LQ.js";
11
+ import "./chunk-3URQC7EH.js";
12
+ import "./chunk-7H73RIE3.js";
13
13
  import "./chunk-HXGUIPQB.js";
14
14
  import "./chunk-AR2JDFAE.js";
15
15
  import "./chunk-747LRSOO.js";
16
16
  import "./chunk-LP7BEXCT.js";
17
17
  import "./chunk-VCETL77O.js";
18
- import "./chunk-24ZLWWEO.js";
18
+ import "./chunk-YPYHVOXP.js";
19
19
  import "./chunk-HNGSV2YC.js";
20
20
  import "./chunk-PZ5AY32C.js";
21
21
  export {
@@ -25,4 +25,4 @@ export {
25
25
  randomId,
26
26
  withdrawAccessibleData
27
27
  };
28
- //# sourceMappingURL=withdraw-accessible-JSDQHXHE.js.map
28
+ //# sourceMappingURL=withdraw-accessible-7PG4DYQK.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@noy-db/hub",
3
- "version": "0.6.0-pre.0",
3
+ "version": "0.6.0-pre.10",
4
4
  "description": "Zero-knowledge, offline-first, encrypted document store — core library with AES-256-GCM, PBKDF2, multi-user keyring, and sync engine",
5
5
  "license": "MIT",
6
6
  "author": "vLannaAi <vicio@lanna.ai>",
@@ -20,6 +20,7 @@
20
20
  "types": "./dist/index.d.ts",
21
21
  "default": "./dist/index.js"
22
22
  },
23
+ "./codemods/0.4.0-pre.json": "./codemods/0.4.0-pre.json",
23
24
  "./i18n": {
24
25
  "types": "./dist/via/i18n/index.d.ts",
25
26
  "default": "./dist/i18n/index.js"
@@ -202,20 +203,21 @@
202
203
  "files": [
203
204
  "dist",
204
205
  "README.md",
205
- "LICENSE"
206
+ "LICENSE",
207
+ "codemods"
206
208
  ],
207
209
  "engines": {
208
210
  "node": ">=22.0.0"
209
211
  },
210
212
  "dependencies": {
211
- "@noy-db/attestation": "0.6.0-pre.0"
213
+ "@noy-db/attestation": "0.6.0-pre.10"
212
214
  },
213
215
  "devDependencies": {
214
216
  "@types/node": "^22.0.0",
215
217
  "esbuild": "^0.25.0",
216
218
  "zod": "^4.0.0",
217
219
  "zod-to-json-schema": "^3.25.2",
218
- "@noy-db/on-shamir": "0.6.0-pre.0"
220
+ "@noy-db/on-shamir": "0.6.0-pre.10"
219
221
  },
220
222
  "peerDependencies": {
221
223
  "zod-to-json-schema": "^3.25.0"
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/with-pod/backup.ts"],"sourcesContent":["/**\n * Vault backup / restore / integrity.\n *\n * Holds `dump()` (verifiable encrypted JSON backup, including the blob\n * collections so blob \"covers\" travel in the bundle), `load()` (restore +\n * post-load integrity gate), `verifyBackupIntegrity()` (chain + data-envelope\n * cross-check), and `exportJSON()` (plaintext per-collection export, built on\n * the vault's `exportStream`). Behaviour is byte-identical to the inline\n * `Vault` methods these functions replaced — every dependency the moving code\n * touched on `this.*` arrives via {@link BackupContext}. `Vault` keeps the\n * public methods as thin delegators.\n *\n * Internal — reached through `vault.dump()` / `vault.load()` / etc.\n */\nimport { NOYDB_BACKUP_VERSION } from '../kernel/types.js'\nimport { BackupLedgerError, BackupCorruptedError } from '../kernel/errors.js'\nimport { LEDGER_COLLECTION, LEDGER_DELTAS_COLLECTION } from '../with-commit/history/ledger/constants.js'\nimport { SCHEMAS_COLLECTION } from '../with-shape/persisted-schemas/storage.js'\nimport { SEQUENCE_COLLECTION } from '../with-commit/sequence/index.js'\nimport { MANIFEST_COLLECTION } from '../with-shape/manifest/reserved-collections.js'\nimport type {\n NoydbStore,\n EncryptedEnvelope,\n VaultBackup,\n VaultSnapshot,\n ExportStreamOptions,\n ExportChunk,\n} from '../kernel/types.js'\nimport type { LedgerStore } from '../with-commit/history/ledger/store.js'\n\n/** Everything the moving backup methods touched on the vault's `this.*`. */\nexport interface BackupContext {\n /** The ciphertext store. */\n readonly adapter: NoydbStore\n /** Vault namespace name. */\n readonly vault: string\n /** The invoking keyring's user id (read fresh per call). */\n userId(): string\n /** The vault's ledger store, or null when history is off. */\n getLedgerOrNull(): LedgerStore | null\n /** Recompute an envelope's `payloadHash` (bound `historyStrategy.envelopePayloadHash`). */\n envelopePayloadHash(envelope: EncryptedEnvelope): Promise<string>\n /**\n * Refresh the in-memory keyring from the freshly-loaded keyring file and\n * rebuild the DEK resolver. No-op when the vault has no `reloadKeyring`\n * callback (plaintext vaults / test constructions).\n */\n reloadKeyringAndRebuildDEK(): Promise<void>\n /** Clear the vault's collection cache (post-load). */\n clearCollectionCache(): void\n /** Reset the ledger store so the next `ledger()` rebuilds its head cache. */\n resetLedgerStore(): void\n /** The vault's decrypt+ACL export stream (used by `exportJSON`). */\n exportStream(opts: ExportStreamOptions): AsyncIterableIterator<ExportChunk>\n}\n\n/** Result of {@link verifyBackupIntegrity}. */\nexport type VerifyBackupResult =\n | { readonly ok: true; readonly head: string; readonly length: number }\n | {\n readonly ok: false\n readonly kind: 'chain'\n readonly divergedAt: number\n readonly message: string\n }\n | {\n readonly ok: false\n readonly kind: 'data'\n readonly collection: string\n readonly id: string\n readonly message: string\n }\n\n/**\n * Dump vault as a verifiable encrypted JSON backup string.\n *\n * backups embed the current ledger head and the full `_ledger` +\n * `_ledger_deltas` internal collections so the receiver can run\n * `verifyBackupIntegrity()` after `load()` and detect any tampering between\n * dump and restore. Backups produced without a ledger skip the integrity check\n * with a warning — both modes round-trip cleanly.\n */\nexport async function dumpVault(ctx: BackupContext): Promise<string> {\n const snapshot = await ctx.adapter.loadAll(ctx.vault)\n\n // Load keyrings (separate path because loadAll filters them out\n // along with all other underscore-prefixed internal collections).\n const keyringIds = await ctx.adapter.list(ctx.vault, '_keyring')\n const keyrings: Record<string, unknown> = {}\n for (const keyringId of keyringIds) {\n const envelope = await ctx.adapter.get(ctx.vault, '_keyring', keyringId)\n if (envelope) {\n keyrings[keyringId] = JSON.parse(envelope._data)\n }\n }\n\n // Load the ledger entries + deltas so the receiver can replay\n // the chain after restore. Without this, `load()` would have an\n // empty ledger and `verifyBackupIntegrity()` would have nothing\n // to compare against.\n //\n // Also enumerate the blob collections so blob content (\"covers\")\n // travels in the bundle (the blob DEK already travels in `_keyring`).\n // Literals are inlined (not imported from blobs/blob-set.ts) to keep\n // the blob runtime out of this kernel hot path — they mirror\n // BLOB_INDEX/CHUNKS/EVICTION_AUDIT_COLLECTION and SLOTS/VERSIONS_PREFIX.\n // The collect-loop skips empty ids, so this no-ops without blobs.\n const internalSnapshot: VaultSnapshot = {}\n const internalNames = [\n LEDGER_COLLECTION, LEDGER_DELTAS_COLLECTION, SCHEMAS_COLLECTION, SEQUENCE_COLLECTION,\n MANIFEST_COLLECTION, // #941: the pod's manifest-set record(s) travel in the bundle too\n '_history', // full-snapshot version history — so history()/getVersion()/diff() survive the bundle\n '_blob_index', '_blob_chunks', '_blob_eviction_audit',\n // #753 spec §7 Q3: `_blob_intent` markers travel too — restoring mid-op\n // state (a blob row without its marker) would reproduce the ambiguity\n // the journal exists to prevent. Note: `_mv_stale` does NOT travel\n // today (a pre-existing, separate gap) — observed here, tracked on\n // #761, not fixed in this pass.\n '_blob_intent',\n // #769: `_blob_slots_<c>` envelopes travel verbatim (raw ciphertext,\n // same DEK, same vault) — including any `SlotRecord.pendingRelease`\n // resume breadcrumb they carry. This is INTENTIONALLY the opposite of\n // `extract-partition`'s `reKeyBlobs`, which STRIPS `pendingRelease`:\n // a full-vault backup restores into the SAME vault it was taken from,\n // so a breadcrumb taken mid-rehome (together with its `_blob_intent`\n // marker, carried above) is resumable on restore — carry-and-resume is\n // correct here. A partition extraction crosses vaults: the breadcrumb's\n // old eTag may not exist in the destination, so it must be stripped\n // there instead. Asymmetry: backup = same-vault-resumable = carry;\n // partition = cross-vault = strip-breadcrumb-carry-marker.\n ...Object.keys(snapshot).flatMap((c) => [`_blob_slots_${c}`, `_blob_versions_${c}`]),\n ]\n for (const internalName of internalNames) {\n const ids = await ctx.adapter.list(ctx.vault, internalName)\n if (ids.length === 0) continue\n const records: Record<string, EncryptedEnvelope> = {}\n for (const id of ids) {\n const envelope = await ctx.adapter.get(ctx.vault, internalName, id)\n if (envelope) records[id] = envelope\n }\n internalSnapshot[internalName] = records\n }\n\n // Embed the ledger head if there's a chain. An empty ledger\n // (fresh vault) leaves `ledgerHead` undefined, which\n // load() treats the same as a legacy backup (no integrity\n // check, console warning). If history is not opted in,\n // `getLedgerOrNull` returns null and we skip embedding entirely\n // — the backup is still valid, just without the integrity head.\n const ledgerForHead = ctx.getLedgerOrNull()\n const head = ledgerForHead ? await ledgerForHead.head() : null\n const backup: VaultBackup = {\n _noydb_backup: NOYDB_BACKUP_VERSION,\n _compartment: ctx.vault,\n _exported_at: new Date().toISOString(),\n _exported_by: ctx.userId(),\n keyrings: keyrings as VaultBackup['keyrings'],\n collections: snapshot,\n ...(Object.keys(internalSnapshot).length > 0\n ? { _internal: internalSnapshot }\n : {}),\n ...(head\n ? {\n ledgerHead: {\n hash: head.hash,\n index: head.entry.index,\n ts: head.entry.ts,\n },\n }\n : {}),\n }\n\n return JSON.stringify(backup)\n}\n\n/**\n * Restore a vault from a verifiable backup. After loading, runs\n * `verifyBackupIntegrity()` to confirm the hash chain, the embedded head, and\n * every data envelope's payload hash. Legacy backups (no `ledgerHead`) load\n * with a console warning and skip the integrity check.\n */\nexport async function loadVault(ctx: BackupContext, backupJson: string): Promise<void> {\n const backup = JSON.parse(backupJson) as VaultBackup\n\n // 1. Restore data collections.\n await ctx.adapter.saveAll(ctx.vault, backup.collections)\n\n // 2. Restore keyrings.\n for (const [userId, keyringFile] of Object.entries(backup.keyrings)) {\n const envelope = {\n _noydb: 1 as const,\n _v: 1,\n _ts: new Date().toISOString(),\n _iv: '',\n _data: JSON.stringify(keyringFile),\n }\n await ctx.adapter.put(ctx.vault, '_keyring', userId, envelope)\n }\n\n // 3. Restore internal collections (`_ledger`, `_ledger_deltas`).\n // Required so verifyBackupIntegrity has the chain to walk.\n if (backup._internal) {\n for (const [internalName, records] of Object.entries(backup._internal)) {\n for (const [id, envelope] of Object.entries(records)) {\n await ctx.adapter.put(ctx.vault, internalName, id, envelope)\n }\n }\n }\n\n // 4. Refresh the in-memory keyring from the freshly-loaded\n // keyring file. Without this, the Vault's getDEK\n // closure still holds the OLD session's DEKs, and every\n // decrypt of a loaded ledger entry / data envelope fails\n // with TamperedError because the DEK doesn't match the\n // ciphertext that was encrypted with the SOURCE user's DEK.\n // Skipped for plaintext vaults and for tests that\n // construct Vault without a reloadKeyring callback.\n await ctx.reloadKeyringAndRebuildDEK()\n\n // 5. Clear collection cache + reset the ledger store so the\n // next ledger() call rebuilds its head cache from the\n // freshly-loaded entries.\n ctx.clearCollectionCache()\n ctx.resetLedgerStore()\n\n // 5. Run the verification gate. Legacy backups (no ledgerHead)\n // skip this with a one-line warning so existing consumers can\n // still read them while migrating.\n if (!backup.ledgerHead) {\n console.warn(\n `[noy-db] Loaded a legacy backup with no ledgerHead — ` +\n `verifiable-backup integrity check skipped. ` +\n `Re-export with a ledger-aware build to get tamper detection.`,\n )\n return\n }\n\n const result = await verifyBackupIntegrity(ctx)\n if (!result.ok) {\n // Surface the most specific error class we can. The result\n // shape carries enough info for callers to inspect.\n if (result.kind === 'data') {\n throw new BackupCorruptedError(\n result.collection,\n result.id,\n result.message,\n )\n }\n throw new BackupLedgerError(result.message, result.divergedAt)\n }\n\n // 6. Cross-check: the freshly-verified head must match the\n // value embedded at dump time. A mismatch means someone\n // truncated or extended the chain after dump.\n if (result.head !== backup.ledgerHead.hash) {\n throw new BackupLedgerError(\n `Backup ledger head mismatch: embedded \"${backup.ledgerHead.hash}\" ` +\n `but reconstructed \"${result.head}\".`,\n )\n }\n}\n\n/**\n * End-to-end backup integrity check: `ledger.verify()` (hash chain) plus a data\n * envelope cross-check (every current record's `_data` hash must match the\n * latest `put` entry's `payloadHash`). Returns a discriminated union so callers\n * can distinguish chain vs data failures.\n */\nexport async function verifyBackupIntegrity(ctx: BackupContext): Promise<VerifyBackupResult> {\n // Step 1: chain verification. Without the history strategy there\n // is no ledger; an unaudited backup verifies trivially as `ok`\n // because there's nothing to diverge from.\n const ledgerForVerify = ctx.getLedgerOrNull()\n if (!ledgerForVerify) {\n return { ok: true, head: '', length: 0 }\n }\n const chainResult = await ledgerForVerify.verify()\n if (!chainResult.ok) {\n return {\n ok: false,\n kind: 'chain',\n divergedAt: chainResult.divergedAt,\n message:\n `Ledger chain diverged at index ${chainResult.divergedAt}: ` +\n `expected prevHash \"${chainResult.expected}\" but found \"${chainResult.actual}\".`,\n }\n }\n\n // Step 2: data envelope cross-check. Walk every entry in the\n // ledger and, for the LATEST `put` per (collection, id), recompute\n // the data envelope's payloadHash and compare. Earlier puts of the\n // same id are skipped because the data collection only holds the\n // current version — historical envelopes live in the deltas\n // collection (which is itself protected by the chain).\n // Reuse the ledger we already resolved in step 1.\n const allEntries = await ledgerForVerify.loadAllEntries()\n\n // Find the latest non-delete entry per (collection, id). Walk\n // the entries in reverse so we hit the latest first; mark each\n // (collection, id) as seen and skip subsequent entries.\n const seen = new Set<string>()\n const latest = new Map<\n string,\n { collection: string; id: string; expectedHash: string }\n >()\n for (let i = allEntries.length - 1; i >= 0; i--) {\n const entry = allEntries[i]\n if (!entry) continue\n // Amendment entries are multi-record audit entries whose\n // `collection` and `id` are empty strings — building a `\"/\"`\n // key here would mark that synthetic slot as seen and falsely\n // trip the data check on a record that never existed. Skip\n // them BEFORE the key/seen bookkeeping so they neither\n // tombstone real entries nor enter the latest map.\n if (entry.op === 'amendment' || entry.op === 'lifecycle') continue\n const key = `${entry.collection}/${entry.id}`\n if (seen.has(key)) continue\n seen.add(key)\n // For deletes the data collection should NOT have the record,\n // so we skip — there's nothing to cross-check. Marking the key\n // as seen above ensures any earlier `put` of the same id is\n // also skipped (the record was subsequently deleted).\n if (entry.op === 'delete') continue\n latest.set(key, {\n collection: entry.collection,\n id: entry.id,\n expectedHash: entry.payloadHash,\n })\n }\n\n for (const { collection, id, expectedHash } of latest.values()) {\n const envelope = await ctx.adapter.get(ctx.vault, collection, id)\n if (!envelope) {\n return {\n ok: false,\n kind: 'data',\n collection,\n id,\n message:\n `Ledger expects data record \"${collection}/${id}\" to exist, ` +\n `but the adapter has no envelope for it.`,\n }\n }\n const actualHash = await ctx.envelopePayloadHash(envelope)\n if (actualHash !== expectedHash) {\n return {\n ok: false,\n kind: 'data',\n collection,\n id,\n message:\n `Data envelope \"${collection}/${id}\" has been tampered with: ` +\n `expected payloadHash \"${expectedHash}\", got \"${actualHash}\".`,\n }\n }\n }\n\n return {\n ok: true,\n head: chainResult.head,\n length: chainResult.length,\n }\n}\n\n/**\n * Plaintext per-collection export, built on the vault's `exportStream`. Forces\n * collection granularity (record-by-record output makes no sense in a single\n * string) and merges dictionary snapshots across collections.\n */\nexport async function exportVaultJSON(ctx: BackupContext, opts: ExportStreamOptions = {}): Promise<string> {\n // Force per-collection granularity regardless of caller setting:\n // record-by-record output doesn't make sense in a single string.\n const collections: Record<\n string,\n {\n schema: null\n refs: Record<string, { target: string; mode: 'strict' | 'warn' | 'cascade' }>\n records: unknown[]\n }\n > = {}\n let ledgerHead: ExportChunk['ledgerHead'] | undefined\n // Merged dictionary snapshot across all collections.\n // Only populated when `resolveLabels` is not set.\n const allDictionaries: Record<\n string, // collection name\n Record<string, Record<string, Record<string, string>>>\n > = {}\n\n for await (const chunk of ctx.exportStream({\n granularity: 'collection',\n withLedgerHead: opts.withLedgerHead === true,\n // Thread the export locale so records are read at the\n // `export` layer (i18nText collapsed + dictKey/staticDict labels resolved).\n ...(opts.resolveLabels !== undefined ? { resolveLabels: opts.resolveLabels } : {}),\n })) {\n collections[chunk.collection] = {\n schema: null, // Standard Schema validators are not JSON-serializable\n refs: chunk.refs,\n records: chunk.records,\n }\n if (chunk.ledgerHead) ledgerHead = chunk.ledgerHead\n // Collect dictionary snapshots unless resolveLabels is set\n if (!opts.resolveLabels && chunk.dictionaries) {\n allDictionaries[chunk.collection] = chunk.dictionaries\n }\n }\n\n const hasDictionaries = Object.keys(allDictionaries).length > 0\n return JSON.stringify({\n _noydb_export: 1,\n _compartment: ctx.vault,\n _exported_at: new Date().toISOString(),\n _exported_by: ctx.userId(),\n collections,\n ...(hasDictionaries ? { _dictionaries: allDictionaries } : {}),\n ...(ledgerHead ? { ledgerHead } : {}),\n })\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkFA,eAAsB,UAAU,KAAqC;AACnE,QAAM,WAAW,MAAM,IAAI,QAAQ,QAAQ,IAAI,KAAK;AAIpD,QAAM,aAAa,MAAM,IAAI,QAAQ,KAAK,IAAI,OAAO,UAAU;AAC/D,QAAM,WAAoC,CAAC;AAC3C,aAAW,aAAa,YAAY;AAClC,UAAM,WAAW,MAAM,IAAI,QAAQ,IAAI,IAAI,OAAO,YAAY,SAAS;AACvE,QAAI,UAAU;AACZ,eAAS,SAAS,IAAI,KAAK,MAAM,SAAS,KAAK;AAAA,IACjD;AAAA,EACF;AAaA,QAAM,mBAAkC,CAAC;AACzC,QAAM,gBAAgB;AAAA,IACpB;AAAA,IAAmB;AAAA,IAA0B;AAAA,IAAoB;AAAA,IACjE;AAAA;AAAA,IACA;AAAA;AAAA,IACA;AAAA,IAAe;AAAA,IAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAM/B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAYA,GAAG,OAAO,KAAK,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,eAAe,CAAC,IAAI,kBAAkB,CAAC,EAAE,CAAC;AAAA,EACrF;AACA,aAAW,gBAAgB,eAAe;AACxC,UAAM,MAAM,MAAM,IAAI,QAAQ,KAAK,IAAI,OAAO,YAAY;AAC1D,QAAI,IAAI,WAAW,EAAG;AACtB,UAAM,UAA6C,CAAC;AACpD,eAAW,MAAM,KAAK;AACpB,YAAM,WAAW,MAAM,IAAI,QAAQ,IAAI,IAAI,OAAO,cAAc,EAAE;AAClE,UAAI,SAAU,SAAQ,EAAE,IAAI;AAAA,IAC9B;AACA,qBAAiB,YAAY,IAAI;AAAA,EACnC;AAQA,QAAM,gBAAgB,IAAI,gBAAgB;AAC1C,QAAM,OAAO,gBAAgB,MAAM,cAAc,KAAK,IAAI;AAC1D,QAAM,SAAsB;AAAA,IAC1B,eAAe;AAAA,IACf,cAAc,IAAI;AAAA,IAClB,eAAc,oBAAI,KAAK,GAAE,YAAY;AAAA,IACrC,cAAc,IAAI,OAAO;AAAA,IACzB;AAAA,IACA,aAAa;AAAA,IACb,GAAI,OAAO,KAAK,gBAAgB,EAAE,SAAS,IACvC,EAAE,WAAW,iBAAiB,IAC9B,CAAC;AAAA,IACL,GAAI,OACA;AAAA,MACE,YAAY;AAAA,QACV,MAAM,KAAK;AAAA,QACX,OAAO,KAAK,MAAM;AAAA,QAClB,IAAI,KAAK,MAAM;AAAA,MACjB;AAAA,IACF,IACA,CAAC;AAAA,EACP;AAEA,SAAO,KAAK,UAAU,MAAM;AAC9B;AAQA,eAAsB,UAAU,KAAoB,YAAmC;AACrF,QAAM,SAAS,KAAK,MAAM,UAAU;AAGpC,QAAM,IAAI,QAAQ,QAAQ,IAAI,OAAO,OAAO,WAAW;AAGvD,aAAW,CAAC,QAAQ,WAAW,KAAK,OAAO,QAAQ,OAAO,QAAQ,GAAG;AACnE,UAAM,WAAW;AAAA,MACf,QAAQ;AAAA,MACR,IAAI;AAAA,MACJ,MAAK,oBAAI,KAAK,GAAE,YAAY;AAAA,MAC5B,KAAK;AAAA,MACL,OAAO,KAAK,UAAU,WAAW;AAAA,IACnC;AACA,UAAM,IAAI,QAAQ,IAAI,IAAI,OAAO,YAAY,QAAQ,QAAQ;AAAA,EAC/D;AAIA,MAAI,OAAO,WAAW;AACpB,eAAW,CAAC,cAAc,OAAO,KAAK,OAAO,QAAQ,OAAO,SAAS,GAAG;AACtE,iBAAW,CAAC,IAAI,QAAQ,KAAK,OAAO,QAAQ,OAAO,GAAG;AACpD,cAAM,IAAI,QAAQ,IAAI,IAAI,OAAO,cAAc,IAAI,QAAQ;AAAA,MAC7D;AAAA,IACF;AAAA,EACF;AAUA,QAAM,IAAI,2BAA2B;AAKrC,MAAI,qBAAqB;AACzB,MAAI,iBAAiB;AAKrB,MAAI,CAAC,OAAO,YAAY;AACtB,YAAQ;AAAA,MACN;AAAA,IAGF;AACA;AAAA,EACF;AAEA,QAAM,SAAS,MAAM,sBAAsB,GAAG;AAC9C,MAAI,CAAC,OAAO,IAAI;AAGd,QAAI,OAAO,SAAS,QAAQ;AAC1B,YAAM,IAAI;AAAA,QACR,OAAO;AAAA,QACP,OAAO;AAAA,QACP,OAAO;AAAA,MACT;AAAA,IACF;AACA,UAAM,IAAI,kBAAkB,OAAO,SAAS,OAAO,UAAU;AAAA,EAC/D;AAKA,MAAI,OAAO,SAAS,OAAO,WAAW,MAAM;AAC1C,UAAM,IAAI;AAAA,MACR,0CAA0C,OAAO,WAAW,IAAI,wBAC1C,OAAO,IAAI;AAAA,IACnC;AAAA,EACF;AACF;AAQA,eAAsB,sBAAsB,KAAiD;AAI3F,QAAM,kBAAkB,IAAI,gBAAgB;AAC5C,MAAI,CAAC,iBAAiB;AACpB,WAAO,EAAE,IAAI,MAAM,MAAM,IAAI,QAAQ,EAAE;AAAA,EACzC;AACA,QAAM,cAAc,MAAM,gBAAgB,OAAO;AACjD,MAAI,CAAC,YAAY,IAAI;AACnB,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,YAAY,YAAY;AAAA,MACxB,SACE,kCAAkC,YAAY,UAAU,wBAClC,YAAY,QAAQ,gBAAgB,YAAY,MAAM;AAAA,IAChF;AAAA,EACF;AASA,QAAM,aAAa,MAAM,gBAAgB,eAAe;AAKxD,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,SAAS,oBAAI,IAGjB;AACF,WAAS,IAAI,WAAW,SAAS,GAAG,KAAK,GAAG,KAAK;AAC/C,UAAM,QAAQ,WAAW,CAAC;AAC1B,QAAI,CAAC,MAAO;AAOZ,QAAI,MAAM,OAAO,eAAe,MAAM,OAAO,YAAa;AAC1D,UAAM,MAAM,GAAG,MAAM,UAAU,IAAI,MAAM,EAAE;AAC3C,QAAI,KAAK,IAAI,GAAG,EAAG;AACnB,SAAK,IAAI,GAAG;AAKZ,QAAI,MAAM,OAAO,SAAU;AAC3B,WAAO,IAAI,KAAK;AAAA,MACd,YAAY,MAAM;AAAA,MAClB,IAAI,MAAM;AAAA,MACV,cAAc,MAAM;AAAA,IACtB,CAAC;AAAA,EACH;AAEA,aAAW,EAAE,YAAY,IAAI,aAAa,KAAK,OAAO,OAAO,GAAG;AAC9D,UAAM,WAAW,MAAM,IAAI,QAAQ,IAAI,IAAI,OAAO,YAAY,EAAE;AAChE,QAAI,CAAC,UAAU;AACb,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,MAAM;AAAA,QACN;AAAA,QACA;AAAA,QACA,SACE,+BAA+B,UAAU,IAAI,EAAE;AAAA,MAEnD;AAAA,IACF;AACA,UAAM,aAAa,MAAM,IAAI,oBAAoB,QAAQ;AACzD,QAAI,eAAe,cAAc;AAC/B,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,MAAM;AAAA,QACN;AAAA,QACA;AAAA,QACA,SACE,kBAAkB,UAAU,IAAI,EAAE,mDACT,YAAY,WAAW,UAAU;AAAA,MAC9D;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,MAAM,YAAY;AAAA,IAClB,QAAQ,YAAY;AAAA,EACtB;AACF;AAOA,eAAsB,gBAAgB,KAAoB,OAA4B,CAAC,GAAoB;AAGzG,QAAM,cAOF,CAAC;AACL,MAAI;AAGJ,QAAM,kBAGF,CAAC;AAEL,mBAAiB,SAAS,IAAI,aAAa;AAAA,IACzC,aAAa;AAAA,IACb,gBAAgB,KAAK,mBAAmB;AAAA;AAAA;AAAA,IAGxC,GAAI,KAAK,kBAAkB,SAAY,EAAE,eAAe,KAAK,cAAc,IAAI,CAAC;AAAA,EAClF,CAAC,GAAG;AACF,gBAAY,MAAM,UAAU,IAAI;AAAA,MAC9B,QAAQ;AAAA;AAAA,MACR,MAAM,MAAM;AAAA,MACZ,SAAS,MAAM;AAAA,IACjB;AACA,QAAI,MAAM,WAAY,cAAa,MAAM;AAEzC,QAAI,CAAC,KAAK,iBAAiB,MAAM,cAAc;AAC7C,sBAAgB,MAAM,UAAU,IAAI,MAAM;AAAA,IAC5C;AAAA,EACF;AAEA,QAAM,kBAAkB,OAAO,KAAK,eAAe,EAAE,SAAS;AAC9D,SAAO,KAAK,UAAU;AAAA,IACpB,eAAe;AAAA,IACf,cAAc,IAAI;AAAA,IAClB,eAAc,oBAAI,KAAK,GAAE,YAAY;AAAA,IACrC,cAAc,IAAI,OAAO;AAAA,IACzB;AAAA,IACA,GAAI,kBAAkB,EAAE,eAAe,gBAAgB,IAAI,CAAC;AAAA,IAC5D,GAAI,aAAa,EAAE,WAAW,IAAI,CAAC;AAAA,EACrC,CAAC;AACH;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/with-commit/history/ledger/entry.ts","../src/with-commit/history/ledger/hash.ts"],"sourcesContent":["/**\n * Ledger entry shape + canonical JSON + sha256 helpers.\n *\n * This file holds the PURE primitives used by the hash-chained ledger:\n * the entry type, the deterministic (sort-stable) JSON encoder, and\n * the sha256 hasher that produces `prevHash` and `ledger.head()`.\n *\n * Everything here is validator-free and side-effect free — the only\n * runtime dep is Web Crypto's `subtle.digest` for the sha256 call,\n * which we already use for every other hashing operation in the core.\n *\n * The hash chain property works like this:\n *\n * hash(entry[i]) = sha256(canonicalJSON(entry[i]))\n * entry[i+1].prevHash = hash(entry[i])\n *\n * Any modification to `entry[i]` (field values, field order, whitespace)\n * produces a different `hash(entry[i])`, which means `entry[i+1]`'s\n * stored `prevHash` no longer matches the recomputed hash, which means\n * `verify()` returns `{ ok: false, divergedAt: i + 1 }`. The chain is\n * append-only and tamper-evident without external anchoring.\n */\n\n/**\n * A single ledger entry in its plaintext form — what gets serialized,\n * hashed, and then encrypted with the ledger DEK before being written\n * to the `_ledger/` adapter collection.\n *\n * ## Why hash the ciphertext, not the plaintext?\n *\n * `payloadHash` is the sha256 of the record's ENCRYPTED envelope bytes,\n * not its plaintext. This matters:\n *\n * 1. **Zero-knowledge preserved.** A user (or a third party) can\n * verify the ledger against the stored envelopes without any\n * decryption keys. The adapter layer already holds only\n * ciphertext, so hashing the ciphertext keeps the ledger at the\n * same privacy level as the adapter.\n *\n * 2. **Determinism.** Plaintext → ciphertext is randomized by the\n * fresh per-write IV, so `hash(plaintext)` would need extra\n * normalization. `hash(ciphertext)` is already deterministic and\n * unique per write.\n *\n * 3. **Detection property.** If an attacker modifies even one byte of\n * the stored ciphertext (trying to flip a record), the hash\n * changes, the ledger's recorded `payloadHash` no longer matches,\n * and a data-integrity check fails. We don't do that check in\n * `verify()` today, but the\n * hook is there for a future `verifyIntegrity()` follow-up.\n *\n * Fields marked `op`, `collection`, `id`, `version`, `ts`, `actor` are\n * plaintext METADATA about the operation — NOT the record itself. The\n * entry is still encrypted at rest via the ledger DEK, but adapters\n * could theoretically infer operation patterns from the sizes and\n * timestamps. This is an accepted trade-off for the tamper-evidence\n * property; full ORAM-level privacy is out of scope for noy-db.\n */\nimport { sha256Hex as sha256HexBytes } from '../../../kernel/enclave/index.js'\n\nexport interface LedgerEntry {\n /**\n * Zero-based sequential position of this entry in the chain. The\n * canonical adapter key is this number zero-padded to 10 digits\n * (`\"0000000001\"`) so lexicographic ordering matches numeric order.\n */\n readonly index: number\n\n /**\n * Hex-encoded sha256 of the canonical JSON of the PREVIOUS entry.\n * The genesis entry (index 0) has `prevHash === ''` — the first\n * entry in a fresh vault has nothing to point back to.\n */\n readonly prevHash: string\n\n /**\n * Which kind of mutation this entry records. only supports\n * data operations (`put`, `delete`, `amendment`). Access-control\n * operations (`grant`, `revoke`, `rotate`) will be added in a\n * follow-up once the keyring write path is instrumented — that's\n * tracked in the epic issue.\n *\n * `'amendment'` is the multi-record audit entry written by the\n * guards service when an admin/owner uses `withTransactions(...)`\n * to repair a constraint-violating state. See `amendment` field\n * below for the structured payload.\n *\n * `'lifecycle'` records a non-data audit event (e.g. partition\n * handover) — `collection`/`id` are empty and the event detail\n * lives in `reason` (e.g. `'partition-handed-over:<sealId>'`). Like\n * `amendment`, it carries no data envelope, so `verifyBackupIntegrity`\n * skips it in the data cross-check (it still participates in the\n * tamper-evident chain).\n *\n * `'forget'` is the single summary entry written by `vault.forget()`\n * (GDPR crypto-shred). `collection`/`id` are empty and `version`\n * is 0 — a forget is not scoped to one record. `payloadHash` carries\n * `sha256Hex(subjectId)` so the ledger PROVES \"subject X existed and\n * was erased on date D\" without retaining the subject id or any\n * plaintext; `reason` holds a JSON summary of the shred counts. Like\n * `amendment`/`lifecycle` it carries no data envelope and is skipped\n * by the reconstruct walker (it still participates in the chain, so\n * `verify()` passes after a shred).\n */\n readonly op: 'put' | 'delete' | 'amendment' | 'lifecycle' | 'migration' | 'forget'\n\n /** The collection the mutation targeted. */\n readonly collection: string\n\n /** The record id the mutation targeted. */\n readonly id: string\n\n /**\n * The record version AFTER this mutation. For `put` this is the\n * newly assigned version; for `delete` this is the version that\n * was deleted (the last version visible to reads).\n */\n readonly version: number\n\n /** ISO timestamp of the mutation. */\n readonly ts: string\n\n /** User id of the actor who performed the mutation. */\n readonly actor: string\n\n /**\n * Hex-encoded sha256 over the encrypted envelope's `_data` field, plus its\n * sealed-field ciphertext map (`_sealed`) when the record carries one —\n * so the ledger attests to both the open body and every sealed\n * value. A record with no `_sealed` hashes `_data` alone.\n * For `put`, this is the hash of the new ciphertext. For `delete`,\n * it's the hash of the last visible ciphertext at deletion time, or the empty\n * string if nothing was there to delete. Hashing the ciphertext (not the\n * plaintext) preserves zero-knowledge — see the file docstring. The exact\n * recipe lives in `envelopePayloadHash` (`hash.ts`).\n */\n readonly payloadHash: string\n\n /**\n * Optional human-readable tag describing why this mutation happened.\n * Threaded through `collection.put(_, _, { reason })`. Common\n * values include `'import:csv'`, `'import:json'`, `'import:xlsx'` from\n * `as-*` ImportPlan.apply(), but consumers can use any string for\n * domain-specific audit filtering. Auto-strip via `canonicalJson` —\n * absent on the wire, never serialized as `null`.\n *\n * Audit consumers filter: `entries.filter(e => e.reason?.startsWith('import:'))`.\n */\n readonly reason?: string\n\n /**\n * Optional hex-encoded sha256 of the encrypted JSON Patch delta\n * blob stored alongside this entry in `_ledger_deltas/`. Present\n * only for `put` operations that had a previous version — the\n * genesis put of a new record, and every `delete`, leave this\n * field undefined.\n *\n * The delta payload itself lives in a sibling internal collection\n * (`_ledger_deltas/<paddedIndex>`) and is encrypted with the\n * ledger DEK. Callers use `ledger.loadDelta(index)` to decrypt and\n * deserialize it when reconstructing a historical version.\n *\n * Why optional instead of always-present: the first put of a\n * record has no previous version to diff against, so storing an\n * empty patch would be noise. For deletes there's no \"next\" state\n * to describe with a delta. Both cases set this field to undefined.\n *\n * Note: the canonical-JSON hasher treats `undefined` as invalid\n * (it's one of the guard rails), so on the wire this field is\n * either `{ deltaHash: '<hex>' }` or absent from the JSON\n * entirely — never `{ deltaHash: undefined }`.\n */\n readonly deltaHash?: string\n\n /**\n * Present only when `op === 'amendment'`. Records the human reason,\n * the role of the actor, the (collection, id, vBefore, vAfter) tuple\n * for every record touched, and which guard invariants passed.\n *\n * See docs/superpowers/specs/2026-05-18-guards-design.md.\n */\n readonly amendment?: {\n readonly reason: string\n readonly role: 'admin' | 'owner'\n readonly changes: ReadonlyArray<{\n readonly collection: string\n readonly id: string\n readonly vBefore: number\n readonly vAfter: number\n }>\n readonly invariantsPassed: ReadonlyArray<string>\n }\n}\n\n/**\n * Canonical (sort-stable) JSON encoder.\n *\n * This function is the load-bearing primitive of the hash chain:\n * `sha256(canonicalJSON(entry))` must produce the same hex string\n * every time, on every machine, for the same logical entry — otherwise\n * `verify()` would return `{ ok: false }` on cross-platform reads.\n *\n * JavaScript's `JSON.stringify` is almost canonical, but NOT quite:\n * it preserves the insertion order of object keys, which means\n * `{a:1,b:2}` and `{b:2,a:1}` serialize differently. We fix this by\n * recursively walking objects and sorting their keys before\n * concatenation.\n *\n * Arrays keep their original order (reordering them would change\n * semantics). Numbers, strings, booleans, and `null` use the default\n * JSON encoding. `undefined` and functions are rejected — ledger\n * entries are plain data, and silently dropping `undefined` would\n * break the \"same input → same hash\" property if a caller forgot to\n * omit a field.\n *\n * Performance: one pass per nesting level; O(n log n) for key sorting\n * at each object. Entries are small (< 1 KB) so this is negligible\n * compared to the sha256 call.\n */\nexport function canonicalJson(value: unknown): string {\n if (value === null) return 'null'\n if (typeof value === 'boolean') return value ? 'true' : 'false'\n if (typeof value === 'number') {\n if (!Number.isFinite(value)) {\n throw new Error(\n `canonicalJson: refusing to encode non-finite number ${String(value)}`,\n )\n }\n return JSON.stringify(value)\n }\n if (typeof value === 'string') return JSON.stringify(value)\n if (typeof value === 'bigint') {\n throw new Error('canonicalJson: BigInt is not JSON-serializable')\n }\n if (typeof value === 'undefined' || typeof value === 'function') {\n throw new Error(\n `canonicalJson: refusing to encode ${typeof value} — include all fields explicitly`,\n )\n }\n if (Array.isArray(value)) {\n return '[' + value.map((v) => canonicalJson(v)).join(',') + ']'\n }\n if (typeof value === 'object') {\n const obj = value as Record<string, unknown>\n const keys = Object.keys(obj).sort()\n const parts: string[] = []\n for (const key of keys) {\n parts.push(JSON.stringify(key) + ':' + canonicalJson(obj[key]))\n }\n return '{' + parts.join(',') + '}'\n }\n throw new Error(`canonicalJson: unexpected value type: ${typeof value}`)\n}\n\n/**\n * Compute a hex-encoded sha256 of a string via Web Crypto's subtle API.\n *\n * We use hex (not base64) for hashes because hex is case-insensitive,\n * fixed-length (64 chars), and easier to compare visually in debug\n * output. Base64 would save a few bytes in storage but every encrypted\n * ledger entry is already much larger than the hash itself.\n */\nexport async function sha256Hex(input: string): Promise<string> {\n return sha256HexBytes(new TextEncoder().encode(input))\n}\n\n/**\n * Compute the canonical hash of a ledger entry. Short wrapper around\n * `canonicalJson` + `sha256Hex`; callers use this instead of composing\n * the two functions every time, so any future change to the hashing\n * pipeline (e.g., adding a domain-separation prefix) lives in one place.\n */\nexport async function hashEntry(entry: LedgerEntry): Promise<string> {\n return sha256Hex(canonicalJson(entry))\n}\n\n/**\n * Pad an index to the canonical 10-digit form used as the adapter key.\n * Ten digits is enough for ~10 billion ledger entries per vault\n * — far beyond any realistic use case, but cheap enough that the extra\n * digits don't hurt storage.\n */\nexport function paddedIndex(index: number): string {\n return String(index).padStart(10, '0')\n}\n\n/** Parse a padded adapter key back into a number. Returns NaN on malformed input. */\nexport function parseIndex(key: string): number {\n return Number.parseInt(key, 10)\n}\n","/**\n * Envelope payload hash — pinned in its own leaf module so consumers\n * (DictionaryHandle, the active history strategy) can import it\n * without dragging in the `LedgerStore` class.\n *\n * see `constants.ts` for the broader rationale.\n *\n * @internal\n */\n\nimport type { EncryptedEnvelope } from '../../../kernel/types.js'\nimport { sha256Hex } from './entry.js'\nimport { envelopeBodyForHash } from '../../../kernel/enclave/index.js'\n\n/**\n * Compute the `payloadHash` value for an encrypted envelope. Used by\n * `LedgerStore.append` for both put (hash the new envelope) and\n * delete (hash the previous envelope) paths, and by\n * `DictionaryHandle` so its ledger entries match the same contract.\n *\n * Hashes the open `_data` ciphertext, plus the sealed-field ciphertext\n * map (`_sealed`) when a record carries one — so the ledger attests to\n * both the open body AND every sealed value … and the verify-digest\n * ciphertext map (`_vdig`), each bound only when present — the `_vdig`\n * binding is the temporal-rollback detector for the C1 splice class.\n * `rotateRecordCek` rewrites `_vdig` with no ledger entry, the same\n * pre-existing rotation property `_sealed`/`_cek` already have\n * (`verifyBackupIntegrity` flags rotated records until re-anchored).\n *\n * Returns the empty string when there is no envelope (delete of a\n * never-existed record). The empty string tolerated by the ledger\n * entry's `payloadHash` field as the canonical \"nothing here\" value.\n */\nexport async function envelopePayloadHash(\n envelope: EncryptedEnvelope | null,\n): Promise<string> {\n if (!envelope) return ''\n // Back-compat: a record with NO sealed fields hashes as sha256 of\n // `_data` alone — so every pre-existing ledger entry\n // and every non-sealed backup verifies byte-identically. A record WITH\n // `_sealed` widens the hash to also bind the sealed-field ciphertext, so the\n // ledger attests to sealed-value tamper/erasure (a dropped or swapped\n // `_sealed[field]` now diverges `verifyBackupIntegrity`'s data cross-check).\n // `envelopeBodyForHash` (the enclave barrel's C1 protected-body access\n // contract) derives this exact string — see its own doc for the\n // canonicalization recipe (sorted keys, independent of `_sealed`'s\n // field-insertion / store-serialization order).\n //\n // `_cek` is deliberately NOT bound: a tampered wrapped-CEK already self-\n // detects (it fails to unwrap), and `rotateRecordCek` rewrites `_cek` with no\n // ledger entry — binding it would make every legitimate rotation fail verify.\n //\n // RESIDUAL: a backup containing sealed records created BEFORE this change\n // stored `payloadHash` over `_data` only, so it will fail the data cross-check\n // and must be re-anchored (re-`put`/re-baseline). Sealed fields are new, so\n // this is expected to affect ~no real vault.\n //\n // The two branches are NOT domain-separated — D1 pins the no-`_sealed` branch\n // to exactly `sha256(_data)`, so it cannot carry a discriminator tag. An actor\n // with raw-store write access could therefore set a non-sealed record's `_data`\n // equal to the canonical-JSON string below and collide a sealed record's hash —\n // but doing so overwrites `_data` itself, which then no longer GCM-decrypts, so\n // it only suppresses the verify signal on an already-destroyed record; it cannot\n // silently erase one sealed field while leaving the record readable.\n return sha256Hex(envelopeBodyForHash(envelope))\n}\n"],"mappings":";;;;;;;;AA2NO,SAAS,cAAc,OAAwB;AACpD,MAAI,UAAU,KAAM,QAAO;AAC3B,MAAI,OAAO,UAAU,UAAW,QAAO,QAAQ,SAAS;AACxD,MAAI,OAAO,UAAU,UAAU;AAC7B,QAAI,CAAC,OAAO,SAAS,KAAK,GAAG;AAC3B,YAAM,IAAI;AAAA,QACR,uDAAuD,OAAO,KAAK,CAAC;AAAA,MACtE;AAAA,IACF;AACA,WAAO,KAAK,UAAU,KAAK;AAAA,EAC7B;AACA,MAAI,OAAO,UAAU,SAAU,QAAO,KAAK,UAAU,KAAK;AAC1D,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,IAAI,MAAM,gDAAgD;AAAA,EAClE;AACA,MAAI,OAAO,UAAU,eAAe,OAAO,UAAU,YAAY;AAC/D,UAAM,IAAI;AAAA,MACR,qCAAqC,OAAO,KAAK;AAAA,IACnD;AAAA,EACF;AACA,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,MAAM,MAAM,IAAI,CAAC,MAAM,cAAc,CAAC,CAAC,EAAE,KAAK,GAAG,IAAI;AAAA,EAC9D;AACA,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,MAAM;AACZ,UAAM,OAAO,OAAO,KAAK,GAAG,EAAE,KAAK;AACnC,UAAM,QAAkB,CAAC;AACzB,eAAW,OAAO,MAAM;AACtB,YAAM,KAAK,KAAK,UAAU,GAAG,IAAI,MAAM,cAAc,IAAI,GAAG,CAAC,CAAC;AAAA,IAChE;AACA,WAAO,MAAM,MAAM,KAAK,GAAG,IAAI;AAAA,EACjC;AACA,QAAM,IAAI,MAAM,yCAAyC,OAAO,KAAK,EAAE;AACzE;AAUA,eAAsBA,WAAU,OAAgC;AAC9D,SAAO,UAAe,IAAI,YAAY,EAAE,OAAO,KAAK,CAAC;AACvD;AAQA,eAAsB,UAAU,OAAqC;AACnE,SAAOA,WAAU,cAAc,KAAK,CAAC;AACvC;AAQO,SAAS,YAAY,OAAuB;AACjD,SAAO,OAAO,KAAK,EAAE,SAAS,IAAI,GAAG;AACvC;AAGO,SAAS,WAAW,KAAqB;AAC9C,SAAO,OAAO,SAAS,KAAK,EAAE;AAChC;;;AChQA,eAAsB,oBACpB,UACiB;AACjB,MAAI,CAAC,SAAU,QAAO;AA4BtB,SAAOC,WAAU,oBAAoB,QAAQ,CAAC;AAChD;","names":["sha256Hex","sha256Hex"]}