@noy-db/hub 0.6.0-pre.2 → 0.6.0-pre.21

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 (499) hide show
  1. package/CHANGELOG.md +5234 -0
  2. package/codemods/0.4.0-pre.json +699 -0
  3. package/codemods/0.6.0-pre.json +211 -0
  4. package/dist/api-EYNT6KGS.js +20 -0
  5. package/dist/attestation/index.js +19 -19
  6. package/dist/{backup-YYBE5RPC.js → backup-FSC36VWC.js} +36 -18
  7. package/dist/backup-FSC36VWC.js.map +1 -0
  8. package/dist/blobs/index.js +13 -13
  9. package/dist/broker/index.js +12 -12
  10. package/dist/cargo/index.js +33 -33
  11. package/dist/{chunk-35EBKWQU.js → chunk-2LFOMUEA.js} +4 -4
  12. package/dist/{chunk-OF3L2SD6.js → chunk-32B7VCKU.js} +2 -2
  13. package/dist/{chunk-MSWYQLMQ.js → chunk-3B6S6RSI.js} +2 -2
  14. package/dist/{chunk-PJNTR2NV.js → chunk-3ENNPCIW.js} +7 -10
  15. package/dist/chunk-3ENNPCIW.js.map +1 -0
  16. package/dist/{chunk-7F4DBNSP.js → chunk-3O72ZD2E.js} +3 -3
  17. package/dist/{chunk-FNSMZQS4.js → chunk-3PMFMUFX.js} +2 -2
  18. package/dist/{chunk-WQDTCJ6W.js → chunk-45YHJ3GV.js} +11 -3
  19. package/dist/{chunk-WQDTCJ6W.js.map → chunk-45YHJ3GV.js.map} +1 -1
  20. package/dist/{chunk-NIVEDYJZ.js → chunk-4A34KWOU.js} +31 -49
  21. package/dist/chunk-4A34KWOU.js.map +1 -0
  22. package/dist/{chunk-ZJADGNYF.js → chunk-4AOERLTV.js} +1 -1
  23. package/dist/chunk-4AOERLTV.js.map +1 -0
  24. package/dist/{chunk-EDXAQ6JI.js → chunk-4N5Q23KV.js} +87 -34
  25. package/dist/chunk-4N5Q23KV.js.map +1 -0
  26. package/dist/{chunk-VV4NSB7P.js → chunk-4OQZNXQG.js} +15 -24
  27. package/dist/chunk-4OQZNXQG.js.map +1 -0
  28. package/dist/{chunk-FAXZQ5UF.js → chunk-4RAS6HN6.js} +2 -2
  29. package/dist/{chunk-C2OOEM57.js → chunk-4YL2LMXK.js} +92 -35
  30. package/dist/chunk-4YL2LMXK.js.map +1 -0
  31. package/dist/{chunk-EP7VPR7Y.js → chunk-5Q7AJ7DN.js} +11 -8
  32. package/dist/chunk-5Q7AJ7DN.js.map +1 -0
  33. package/dist/{chunk-VMCCGUQB.js → chunk-6JPGVL7X.js} +2 -2
  34. package/dist/{chunk-PRDRGL73.js → chunk-6KTVJ5ZZ.js} +17 -14
  35. package/dist/chunk-6KTVJ5ZZ.js.map +1 -0
  36. package/dist/{chunk-4MC5JRRX.js → chunk-6WO62AJW.js} +14 -15
  37. package/dist/chunk-6WO62AJW.js.map +1 -0
  38. package/dist/{chunk-WLYIROCJ.js → chunk-6YD5SYQS.js} +2 -2
  39. package/dist/{chunk-YAWK6AWF.js → chunk-7KAE7CQ2.js} +2 -2
  40. package/dist/{chunk-MWKDOHEF.js → chunk-7LNE2N2V.js} +17 -10
  41. package/dist/chunk-7LNE2N2V.js.map +1 -0
  42. package/dist/{chunk-5PR33AC4.js → chunk-7PJ3BKHS.js} +20 -17
  43. package/dist/chunk-7PJ3BKHS.js.map +1 -0
  44. package/dist/{chunk-JXIDGFKS.js → chunk-A4TOGAUW.js} +4 -2
  45. package/dist/chunk-A4TOGAUW.js.map +1 -0
  46. package/dist/{chunk-VCETL77O.js → chunk-AU3AUJIZ.js} +27 -7
  47. package/dist/chunk-AU3AUJIZ.js.map +1 -0
  48. package/dist/{chunk-NKH7GSIH.js → chunk-AUPSEJ7O.js} +4 -4
  49. package/dist/{chunk-CCZJJ4I2.js → chunk-B6IYATME.js} +4 -4
  50. package/dist/{chunk-WYZ5MYUA.js → chunk-BAHOV5I5.js} +44 -42
  51. package/dist/chunk-BAHOV5I5.js.map +1 -0
  52. package/dist/{chunk-G5APARUV.js → chunk-BEZDLIDG.js} +13 -15
  53. package/dist/chunk-BEZDLIDG.js.map +1 -0
  54. package/dist/{chunk-ERB6NDDW.js → chunk-CAGI4LLJ.js} +427 -72
  55. package/dist/chunk-CAGI4LLJ.js.map +1 -0
  56. package/dist/{chunk-4UVDI4XE.js → chunk-CLAHBPOI.js} +4 -4
  57. package/dist/{chunk-HNGSV2YC.js → chunk-CWM4GQD2.js} +39 -10
  58. package/dist/chunk-CWM4GQD2.js.map +1 -0
  59. package/dist/{chunk-HVQGCKY4.js → chunk-D3R7Q4QK.js} +2 -2
  60. package/dist/{chunk-I4F6PKUK.js → chunk-DIZ6HM7Q.js} +16 -17
  61. package/dist/chunk-DIZ6HM7Q.js.map +1 -0
  62. package/dist/{chunk-ZNACADFG.js → chunk-DVRZYAGT.js} +4 -4
  63. package/dist/chunk-DVRZYAGT.js.map +1 -0
  64. package/dist/{chunk-P7OG2ETF.js → chunk-DXKLLKME.js} +3 -3
  65. package/dist/{chunk-TDJPS3T2.js → chunk-E5SC6ENM.js} +24 -19
  66. package/dist/chunk-E5SC6ENM.js.map +1 -0
  67. package/dist/{chunk-26JMGSSC.js → chunk-EES37S2V.js} +4 -4
  68. package/dist/chunk-EES37S2V.js.map +1 -0
  69. package/dist/{chunk-JIUVJ4M7.js → chunk-EKEIEJL6.js} +2 -2
  70. package/dist/{chunk-GASWQ3XG.js → chunk-ESKIAXO2.js} +15 -16
  71. package/dist/chunk-ESKIAXO2.js.map +1 -0
  72. package/dist/{chunk-TOAIYQJR.js → chunk-FFSQFH6D.js} +7 -10
  73. package/dist/chunk-FFSQFH6D.js.map +1 -0
  74. package/dist/{chunk-DG27IUVI.js → chunk-FS7NTGCJ.js} +2 -2
  75. package/dist/{chunk-V5KYPBUR.js → chunk-FW7NGYLT.js} +11 -14
  76. package/dist/chunk-FW7NGYLT.js.map +1 -0
  77. package/dist/{chunk-52QYGZHH.js → chunk-GBBDFE6C.js} +2 -2
  78. package/dist/chunk-GBBDFE6C.js.map +1 -0
  79. package/dist/{chunk-HXGUIPQB.js → chunk-GQXFOAYZ.js} +3 -3
  80. package/dist/{chunk-BTVYJWSN.js → chunk-GTHVPVAR.js} +10 -10
  81. package/dist/{chunk-DMQCLZ4Z.js → chunk-GWO2IDAB.js} +2 -2
  82. package/dist/{chunk-6HFM7EIT.js → chunk-H3G4I3PN.js} +2 -2
  83. package/dist/chunk-HK67PX4J.js +27 -0
  84. package/dist/chunk-HK67PX4J.js.map +1 -0
  85. package/dist/{chunk-E7OBCBXS.js → chunk-HQSPF5IY.js} +22 -18
  86. package/dist/chunk-HQSPF5IY.js.map +1 -0
  87. package/dist/{chunk-VJFMXYKP.js → chunk-HR5R5JOM.js} +2 -2
  88. package/dist/{chunk-FDX7OWWI.js → chunk-HYYVT2KZ.js} +2 -2
  89. package/dist/{chunk-JRCYZEHU.js → chunk-I6QKB7MT.js} +2 -2
  90. package/dist/{chunk-MZ5ZFO2D.js → chunk-ICDHUUMQ.js} +84 -112
  91. package/dist/chunk-ICDHUUMQ.js.map +1 -0
  92. package/dist/{chunk-W5W6KHN2.js → chunk-IGNJOJEP.js} +1 -1
  93. package/dist/chunk-IGNJOJEP.js.map +1 -0
  94. package/dist/{chunk-KUDZVJKQ.js → chunk-IJ46VCWD.js} +2 -2
  95. package/dist/{chunk-4HDYQL3J.js → chunk-INMHEMXX.js} +2 -2
  96. package/dist/{chunk-66W5OOCX.js → chunk-JLYQQNY4.js} +52 -65
  97. package/dist/chunk-JLYQQNY4.js.map +1 -0
  98. package/dist/{chunk-UHXCLPGC.js → chunk-JNMTN5D5.js} +2 -2
  99. package/dist/chunk-JNMTN5D5.js.map +1 -0
  100. package/dist/{chunk-I4ZAO7F7.js → chunk-JWMBG5S3.js} +7 -11
  101. package/dist/chunk-JWMBG5S3.js.map +1 -0
  102. package/dist/chunk-KRVS7YWY.js +123 -0
  103. package/dist/chunk-KRVS7YWY.js.map +1 -0
  104. package/dist/{chunk-AR2JDFAE.js → chunk-KV6JM2IA.js} +2 -2
  105. package/dist/{chunk-PVU7LW5L.js → chunk-KX57HODD.js} +6 -6
  106. package/dist/{chunk-PY7CI6L5.js → chunk-LGFTOU27.js} +553 -275
  107. package/dist/chunk-LGFTOU27.js.map +1 -0
  108. package/dist/chunk-LN7P6MZB.js +190 -0
  109. package/dist/chunk-LN7P6MZB.js.map +1 -0
  110. package/dist/{chunk-UIBGXRDD.js → chunk-LX46B56Q.js} +25 -31
  111. package/dist/chunk-LX46B56Q.js.map +1 -0
  112. package/dist/{chunk-CEJWMBXO.js → chunk-LXECF2ZR.js} +2 -2
  113. package/dist/{chunk-7VHY5E3X.js → chunk-MSLPDFK2.js} +7 -7
  114. package/dist/{chunk-I6SDX7WX.js → chunk-MZTUTEHP.js} +16 -22
  115. package/dist/chunk-MZTUTEHP.js.map +1 -0
  116. package/dist/{chunk-VRA4Q7DA.js → chunk-NCCEDL2K.js} +55 -48
  117. package/dist/chunk-NCCEDL2K.js.map +1 -0
  118. package/dist/{chunk-HNHCQ556.js → chunk-NR2SUJ3H.js} +2 -2
  119. package/dist/{chunk-AHLJSVRL.js → chunk-NW4TY6VC.js} +5 -7
  120. package/dist/chunk-NW4TY6VC.js.map +1 -0
  121. package/dist/{chunk-RKKORO4M.js → chunk-O742QBZZ.js} +10 -10
  122. package/dist/chunk-O742QBZZ.js.map +1 -0
  123. package/dist/{chunk-VN45YLWM.js → chunk-OHOKBMTM.js} +343 -132
  124. package/dist/chunk-OHOKBMTM.js.map +1 -0
  125. package/dist/{chunk-W3TVWF6N.js → chunk-OIBEJN5H.js} +2 -2
  126. package/dist/{chunk-QD724WDJ.js → chunk-OMYCSTXL.js} +4 -4
  127. package/dist/{chunk-Z45YRGFO.js → chunk-ONVD6GBY.js} +2 -2
  128. package/dist/{chunk-TAGFGKHP.js → chunk-OTHHO3KI.js} +7 -10
  129. package/dist/chunk-OTHHO3KI.js.map +1 -0
  130. package/dist/{chunk-3737A6EA.js → chunk-P2MR5UNE.js} +75 -18
  131. package/dist/chunk-P2MR5UNE.js.map +1 -0
  132. package/dist/chunk-PENPHA45.js +66 -0
  133. package/dist/chunk-PENPHA45.js.map +1 -0
  134. package/dist/{chunk-3FSX6LDG.js → chunk-PPCOKVFA.js} +8 -3
  135. package/dist/{chunk-3FSX6LDG.js.map → chunk-PPCOKVFA.js.map} +1 -1
  136. package/dist/{chunk-VOQW5LAM.js → chunk-QSIEL6TL.js} +102 -71
  137. package/dist/chunk-QSIEL6TL.js.map +1 -0
  138. package/dist/chunk-RFO4UXKQ.js +201 -0
  139. package/dist/chunk-RFO4UXKQ.js.map +1 -0
  140. package/dist/{chunk-KCQX65FU.js → chunk-RKCRPPNB.js} +3 -3
  141. package/dist/{chunk-7TSYBD3E.js → chunk-RSXQNFGO.js} +2 -2
  142. package/dist/{chunk-SZ2K3MHL.js → chunk-S56VYR4Q.js} +8 -11
  143. package/dist/{chunk-SZ2K3MHL.js.map → chunk-S56VYR4Q.js.map} +1 -1
  144. package/dist/{chunk-7NXHMW6Y.js → chunk-SYS46BL7.js} +2 -2
  145. package/dist/{chunk-55LKVALY.js → chunk-T7IR4N2S.js} +1 -3
  146. package/dist/chunk-T7IR4N2S.js.map +1 -0
  147. package/dist/{chunk-A67356IR.js → chunk-T7JGWTES.js} +33 -8
  148. package/dist/chunk-T7JGWTES.js.map +1 -0
  149. package/dist/{chunk-WHJKIZS7.js → chunk-TDSN2O2V.js} +27 -149
  150. package/dist/chunk-TDSN2O2V.js.map +1 -0
  151. package/dist/{chunk-747LRSOO.js → chunk-TMBSPLUG.js} +2 -2
  152. package/dist/{chunk-LWSJG3LI.js → chunk-TQPASLY4.js} +7 -3
  153. package/dist/chunk-TQPASLY4.js.map +1 -0
  154. package/dist/{chunk-WKPJXWKR.js → chunk-TX5MKAHA.js} +3 -3
  155. package/dist/{chunk-HFQ6LGIO.js → chunk-U27Y4DJZ.js} +12 -10
  156. package/dist/{chunk-HFQ6LGIO.js.map → chunk-U27Y4DJZ.js.map} +1 -1
  157. package/dist/{chunk-E6427JU2.js → chunk-VVSOPRUE.js} +18 -2
  158. package/dist/chunk-VVSOPRUE.js.map +1 -0
  159. package/dist/{chunk-7G6VDWXB.js → chunk-WVE6YKMX.js} +3 -3
  160. package/dist/chunk-WVE6YKMX.js.map +1 -0
  161. package/dist/{chunk-GLKDWWNO.js → chunk-YALD3SST.js} +16 -14
  162. package/dist/chunk-YALD3SST.js.map +1 -0
  163. package/dist/{chunk-NJDQ4YSV.js → chunk-YKXZHUOW.js} +4 -4
  164. package/dist/{chunk-VW6ZZGCG.js → chunk-ZLHHE5XZ.js} +3 -3
  165. package/dist/{chunk-FUHKW252.js → chunk-ZZXLB6AS.js} +2 -2
  166. package/dist/classified/index.js +5 -5
  167. package/dist/{classified-marker-FTOX7Q5L.js → classified-marker-NA6HUV33.js} +3 -3
  168. package/dist/collection-facade-VBM35WAH.js +45 -0
  169. package/dist/{computed-6G5M3UPH.js → computed-GSTLWSY5.js} +3 -3
  170. package/dist/consent/index.js +10 -10
  171. package/dist/cover/index.js +10 -3
  172. package/dist/custody/index.js +11 -11
  173. package/dist/{dead-filter-ENRIOQIE.js → dead-filter-UALP5DJX.js} +2 -2
  174. package/dist/debug/index.js +1 -1
  175. package/dist/{delegation-SSEPLXXO.js → delegation-JLNXM7KH.js} +24 -23
  176. package/dist/delegation-JLNXM7KH.js.map +1 -0
  177. package/dist/derivations/index.js +12 -12
  178. package/dist/derive-YUO3TQYN.js +22 -0
  179. package/dist/directory/index.js +10 -10
  180. package/dist/{dispatch-RE74SH6L.js → dispatch-4ZHLSFZQ.js} +5 -5
  181. package/dist/{dispatch-BDVGYC6X.js → dispatch-77CB75KB.js} +18 -18
  182. package/dist/{enclave-52VUXNRL.js → enclave-O4NOROCJ.js} +27 -9
  183. package/dist/executor-CZDXBXKE.js +29 -0
  184. package/dist/executor-DVJAWN3B.js +9 -0
  185. package/dist/executor-VRLG4TQJ.js +9 -0
  186. package/dist/export-accessible-UXSMG7AB.js +23 -0
  187. package/dist/extract-partition-TVY7AMKH.js +38 -0
  188. package/dist/{fanout-sidecar-DTBIDOWF.js → fanout-sidecar-NLQ7QAYW.js} +18 -27
  189. package/dist/fanout-sidecar-NLQ7QAYW.js.map +1 -0
  190. package/dist/find-WSARMJBW.js +11 -0
  191. package/dist/forget/index.js +9 -9
  192. package/dist/guards/index.js +7 -7
  193. package/dist/history/index.js +23 -20
  194. package/dist/history/index.js.map +1 -1
  195. package/dist/i18n/index.js +14 -14
  196. package/dist/index.d.ts +33 -15
  197. package/dist/index.js +187 -191
  198. package/dist/index.js.map +1 -1
  199. package/dist/indexing/index.js +2 -2
  200. package/dist/introspection/index.js +11 -11
  201. package/dist/issue-3JNJNPT3.js +19 -0
  202. package/dist/kernel/constants.d.ts +18 -0
  203. package/dist/kernel/enclave/crypto.d.ts +24 -4
  204. package/dist/kernel/enclave/index.d.ts +9 -2
  205. package/dist/kernel/enclave/record-aad.d.ts +131 -0
  206. package/dist/kernel/enclave/record-envelope.d.ts +76 -0
  207. package/dist/kernel/enclave/record-keys/envelope-body.d.ts +34 -2
  208. package/dist/kernel/enclave/record-keys/lifecycle.d.ts +22 -5
  209. package/dist/kernel/enclave/record-keys/record-codec.d.ts +47 -14
  210. package/dist/kernel/enclave/record-keys/rekey-blob.d.ts +88 -0
  211. package/dist/kernel/enclave/record-keys/rekey.d.ts +68 -0
  212. package/dist/kernel/enclave/record-keys/tombstone.d.ts +3 -2
  213. package/dist/kernel/errors.d.ts +71 -12
  214. package/dist/kernel/merge-authority.d.ts +25 -0
  215. package/dist/kernel/noydb.d.ts +27 -4
  216. package/dist/kernel/query/builder.d.ts +15 -2
  217. package/dist/kernel/query/join.d.ts +27 -0
  218. package/dist/kernel/sync-policy.d.ts +0 -2
  219. package/dist/kernel/tier-visibility.d.ts +15 -0
  220. package/dist/kernel/types.d.ts +145 -12
  221. package/dist/kernel/vault.d.ts +22 -18
  222. package/dist/kernel/via/index.d.ts +11 -2
  223. package/dist/{ledger-4WJL66BW.js → ledger-MVPNG5OS.js} +11 -11
  224. package/dist/liberate-4LOJOLDT.js +24 -0
  225. package/dist/{link-set-N4ZPV6E6.js → link-set-3POMQR3I.js} +11 -11
  226. package/dist/{managed-secret-OTHS64IF.js → managed-secret-IARIJJ7Q.js} +11 -3
  227. package/dist/materialized-views/index.js +22 -21
  228. package/dist/migrate-cek-XM2ETTZW.js +19 -0
  229. package/dist/migrate-cek-XM2ETTZW.js.map +1 -0
  230. package/dist/money/index.js +12 -8
  231. package/dist/noydb-IRILUDED.js +84 -0
  232. package/dist/overlay-views/index.js +4 -4
  233. package/dist/periods/index.js +22 -12
  234. package/dist/pod/index.js +75 -86
  235. package/dist/pod-handle-MELERCKU.js +41 -0
  236. package/dist/pod-handle-MELERCKU.js.map +1 -0
  237. package/dist/policy/index.js +11 -4
  238. package/dist/port/to/index.d.ts +4 -4
  239. package/dist/port/to/locator.d.ts +54 -8
  240. package/dist/port/with/i18n-strategy.d.ts +4 -1
  241. package/dist/port/with/lookup-strategy.d.ts +4 -1
  242. package/dist/port/with/merge-authority.d.ts +52 -0
  243. package/dist/port/with/service-bus.d.ts +0 -4
  244. package/dist/port/with/strategies.d.ts +2 -0
  245. package/dist/port/with/team-strategy.d.ts +5 -1
  246. package/dist/portability/index.js +8 -8
  247. package/dist/{post-register-ZAG2CAIY.js → post-register-Z5T7FY45.js} +6 -6
  248. package/dist/query/index.js +3 -3
  249. package/dist/reduce/index.js +4 -4
  250. package/dist/register-UZ37QPDB.js +32 -0
  251. package/dist/registry-ETJNA7PO.js +9 -0
  252. package/dist/registry-F7U6KSLX.js +9 -0
  253. package/dist/registry-L4ELKX6C.js +18 -0
  254. package/dist/registry-SDT5LIGO.js +19 -0
  255. package/dist/request-withdrawal-PVFEYX57.js +31 -0
  256. package/dist/{reveal-CMOJY4VO.js → reveal-DQ2E3QAZ.js} +6 -6
  257. package/dist/revoke-YXY6SHUH.js +24 -0
  258. package/dist/satellites/index.js +1 -1
  259. package/dist/schema-update/index.js +2 -2
  260. package/dist/sealed-record/index.js +20 -13
  261. package/dist/sealed-record/index.js.map +1 -1
  262. package/dist/search/index.js +4 -4
  263. package/dist/{seed-UK4QRIUN.js → seed-DZ4ORU5N.js} +19 -22
  264. package/dist/seed-DZ4ORU5N.js.map +1 -0
  265. package/dist/sequence/index.js +9 -9
  266. package/dist/session/index.js +10 -10
  267. package/dist/shadow/index.js +2 -2
  268. package/dist/share-link/index.js +1 -1
  269. package/dist/signer-Q7XQBMPA.js +25 -0
  270. package/dist/snapshots/index.js +10 -10
  271. package/dist/snapshots/index.js.map +1 -1
  272. package/dist/{stale-ZWXSOWJI.js → stale-NI7SAXAZ.js} +10 -10
  273. package/dist/storage-3VNGSHXS.js +23 -0
  274. package/dist/{store-coordination-provider-PB6QZ57W.js → store-coordination-provider-TYKNR3OU.js} +18 -12
  275. package/dist/store-coordination-provider-TYKNR3OU.js.map +1 -0
  276. package/dist/sync/index.js +11 -11
  277. package/dist/team/index.js +15 -14
  278. package/dist/tiers/index.js +11 -10
  279. package/dist/to/index.js +17 -9
  280. package/dist/to/index.js.map +1 -1
  281. package/dist/transactions/index.js +4 -4
  282. package/dist/{ulid-PTAIMDG4.js → ulid-VQW6ERQN.js} +2 -2
  283. package/dist/util/index.js +1 -1
  284. package/dist/vault-head/index.js +115 -0
  285. package/dist/vault-head/index.js.map +1 -0
  286. package/dist/{verify-RO5RTZOJ.js → verify-6J2YLKSO.js} +5 -5
  287. package/dist/via/lookup/handle.d.ts +4 -1
  288. package/dist/via/money/exact.d.ts +44 -0
  289. package/dist/via/money/index.d.ts +2 -0
  290. package/dist/via/money/normalize.d.ts +20 -0
  291. package/dist/walk-WRA7RAPY.js +21 -0
  292. package/dist/with-audit/guards/immutable-guard.d.ts +14 -0
  293. package/dist/with-audit/periods/active.d.ts +28 -1
  294. package/dist/with-audit/periods/index.d.ts +4 -2
  295. package/dist/with-audit/periods/periods.d.ts +161 -6
  296. package/dist/with-audit/periods/strategy.d.ts +14 -5
  297. package/dist/with-audit/periods/vault-facade.d.ts +89 -10
  298. package/dist/with-audit/periods/window.d.ts +10 -0
  299. package/dist/with-audit/sealed-record/index.d.ts +13 -0
  300. package/dist/with-audit/tiers/index.d.ts +17 -2
  301. package/dist/with-cargo/adopt-partition.d.ts +1 -1
  302. package/dist/with-cargo/extract-partition.d.ts +1 -1
  303. package/dist/with-cargo/index.d.ts +2 -2
  304. package/dist/with-commit/history/history.d.ts +26 -0
  305. package/dist/with-commit/history/index.d.ts +2 -1
  306. package/dist/with-commit/history/ledger/store.d.ts +7 -1
  307. package/dist/with-commit/history/strategy.d.ts +11 -1
  308. package/dist/with-commit/numbering/index.d.ts +0 -5
  309. package/dist/with-commit/vault-head/active.d.ts +2 -0
  310. package/dist/with-commit/vault-head/head.d.ts +28 -0
  311. package/dist/with-commit/vault-head/index.d.ts +10 -0
  312. package/dist/with-commit/vault-head/strategy.d.ts +127 -0
  313. package/dist/with-commit/vault-head/verify.d.ts +90 -0
  314. package/dist/with-formula/materialized-views/types.d.ts +52 -0
  315. package/dist/with-party/directory/cover/storage.d.ts +0 -8
  316. package/dist/with-party/directory/storage.d.ts +0 -11
  317. package/dist/with-party/directory/visibility.d.ts +0 -21
  318. package/dist/with-party/policy/storage.d.ts +0 -10
  319. package/dist/with-party/team/index.d.ts +1 -1
  320. package/dist/with-party/team/keyring.d.ts +149 -3
  321. package/dist/with-party/team/noydb-facade.d.ts +5 -1
  322. package/dist/with-party/team/roster-tag.d.ts +101 -0
  323. package/dist/with-party/team/tiers.d.ts +2 -1
  324. package/dist/with-pod/format.d.ts +10 -12
  325. package/dist/with-pod/index.d.ts +10 -10
  326. package/dist/with-pod/open.d.ts +2 -2
  327. package/dist/with-pod/pod-handle.d.ts +19 -0
  328. package/dist/with-pod/pod-store.d.ts +0 -8
  329. package/dist/with-pod/{bundle.d.ts → pod.d.ts} +26 -19
  330. package/dist/with-pod/ulid.d.ts +1 -1
  331. package/dist/with-shape/blobs/blob-set.d.ts +2 -2
  332. package/dist/with-shape/introspection/index.d.ts +1 -0
  333. package/dist/with-sync/engine.d.ts +54 -5
  334. package/dist/with-sync/strategy.d.ts +3 -0
  335. package/dist/withdraw-accessible-4JTDFRFZ.js +28 -0
  336. package/package.json +13 -5
  337. package/dist/api-WVY3H3YH.js +0 -20
  338. package/dist/backup-YYBE5RPC.js.map +0 -1
  339. package/dist/bundle-handle-JEUWU2SJ.js +0 -36
  340. package/dist/bundle-handle-JEUWU2SJ.js.map +0 -1
  341. package/dist/chunk-26JMGSSC.js.map +0 -1
  342. package/dist/chunk-3737A6EA.js.map +0 -1
  343. package/dist/chunk-4MC5JRRX.js.map +0 -1
  344. package/dist/chunk-52QYGZHH.js.map +0 -1
  345. package/dist/chunk-55LKVALY.js.map +0 -1
  346. package/dist/chunk-5PR33AC4.js.map +0 -1
  347. package/dist/chunk-66W5OOCX.js.map +0 -1
  348. package/dist/chunk-7G6VDWXB.js.map +0 -1
  349. package/dist/chunk-A67356IR.js.map +0 -1
  350. package/dist/chunk-AFHQATY4.js +0 -47
  351. package/dist/chunk-AFHQATY4.js.map +0 -1
  352. package/dist/chunk-AHLJSVRL.js.map +0 -1
  353. package/dist/chunk-C2OOEM57.js.map +0 -1
  354. package/dist/chunk-DIMKRG2E.js +0 -131
  355. package/dist/chunk-DIMKRG2E.js.map +0 -1
  356. package/dist/chunk-E6427JU2.js.map +0 -1
  357. package/dist/chunk-E7OBCBXS.js.map +0 -1
  358. package/dist/chunk-EDXAQ6JI.js.map +0 -1
  359. package/dist/chunk-EP7VPR7Y.js.map +0 -1
  360. package/dist/chunk-ERB6NDDW.js.map +0 -1
  361. package/dist/chunk-G5APARUV.js.map +0 -1
  362. package/dist/chunk-GASWQ3XG.js.map +0 -1
  363. package/dist/chunk-GLKDWWNO.js.map +0 -1
  364. package/dist/chunk-HNGSV2YC.js.map +0 -1
  365. package/dist/chunk-I4F6PKUK.js.map +0 -1
  366. package/dist/chunk-I4ZAO7F7.js.map +0 -1
  367. package/dist/chunk-I6SDX7WX.js.map +0 -1
  368. package/dist/chunk-JXIDGFKS.js.map +0 -1
  369. package/dist/chunk-LWSJG3LI.js.map +0 -1
  370. package/dist/chunk-MWKDOHEF.js.map +0 -1
  371. package/dist/chunk-MZ5ZFO2D.js.map +0 -1
  372. package/dist/chunk-NIVEDYJZ.js.map +0 -1
  373. package/dist/chunk-NWCGDAV6.js +0 -45
  374. package/dist/chunk-NWCGDAV6.js.map +0 -1
  375. package/dist/chunk-PJNTR2NV.js.map +0 -1
  376. package/dist/chunk-PRDRGL73.js.map +0 -1
  377. package/dist/chunk-PY7CI6L5.js.map +0 -1
  378. package/dist/chunk-RKKORO4M.js.map +0 -1
  379. package/dist/chunk-TAGFGKHP.js.map +0 -1
  380. package/dist/chunk-TDJPS3T2.js.map +0 -1
  381. package/dist/chunk-TOAIYQJR.js.map +0 -1
  382. package/dist/chunk-UHXCLPGC.js.map +0 -1
  383. package/dist/chunk-UIBGXRDD.js.map +0 -1
  384. package/dist/chunk-V5KYPBUR.js.map +0 -1
  385. package/dist/chunk-VCETL77O.js.map +0 -1
  386. package/dist/chunk-VN45YLWM.js.map +0 -1
  387. package/dist/chunk-VOQW5LAM.js.map +0 -1
  388. package/dist/chunk-VRA4Q7DA.js.map +0 -1
  389. package/dist/chunk-VV4NSB7P.js.map +0 -1
  390. package/dist/chunk-W5W6KHN2.js.map +0 -1
  391. package/dist/chunk-WHJKIZS7.js.map +0 -1
  392. package/dist/chunk-WYZ5MYUA.js.map +0 -1
  393. package/dist/chunk-ZJADGNYF.js.map +0 -1
  394. package/dist/chunk-ZNACADFG.js.map +0 -1
  395. package/dist/collection-facade-QN5ULWYC.js +0 -45
  396. package/dist/delegation-SSEPLXXO.js.map +0 -1
  397. package/dist/derive-6V3PIZF7.js +0 -22
  398. package/dist/executor-CYJQLKKI.js +0 -9
  399. package/dist/executor-FHHLXO4Y.js +0 -28
  400. package/dist/executor-S4QIKEHW.js +0 -9
  401. package/dist/export-accessible-PE5AYKZR.js +0 -23
  402. package/dist/extract-partition-X2L26O6A.js +0 -38
  403. package/dist/fanout-sidecar-DTBIDOWF.js.map +0 -1
  404. package/dist/find-RBBYKXI7.js +0 -11
  405. package/dist/issue-RNU55YOF.js +0 -19
  406. package/dist/liberate-PX4CAT5V.js +0 -24
  407. package/dist/noydb-YPSEGK32.js +0 -83
  408. package/dist/register-TMD6YRCX.js +0 -32
  409. package/dist/registry-CZVINVQH.js +0 -9
  410. package/dist/registry-FVLDWQKT.js +0 -18
  411. package/dist/registry-IKUR2MXD.js +0 -9
  412. package/dist/registry-JET4HBLY.js +0 -19
  413. package/dist/request-withdrawal-RH55LNZL.js +0 -31
  414. package/dist/revoke-R5TBYVA6.js +0 -24
  415. package/dist/seed-UK4QRIUN.js.map +0 -1
  416. package/dist/signer-AGALOXOO.js +0 -25
  417. package/dist/storage-N7LB275C.js +0 -23
  418. package/dist/store-coordination-provider-PB6QZ57W.js.map +0 -1
  419. package/dist/walk-OCUHCYJ6.js +0 -21
  420. package/dist/with-pod/bundle-handle.d.ts +0 -9
  421. package/dist/withdraw-accessible-QQNWM5BO.js +0 -28
  422. /package/dist/{api-WVY3H3YH.js.map → api-EYNT6KGS.js.map} +0 -0
  423. /package/dist/{chunk-35EBKWQU.js.map → chunk-2LFOMUEA.js.map} +0 -0
  424. /package/dist/{chunk-OF3L2SD6.js.map → chunk-32B7VCKU.js.map} +0 -0
  425. /package/dist/{chunk-MSWYQLMQ.js.map → chunk-3B6S6RSI.js.map} +0 -0
  426. /package/dist/{chunk-7F4DBNSP.js.map → chunk-3O72ZD2E.js.map} +0 -0
  427. /package/dist/{chunk-FNSMZQS4.js.map → chunk-3PMFMUFX.js.map} +0 -0
  428. /package/dist/{chunk-FAXZQ5UF.js.map → chunk-4RAS6HN6.js.map} +0 -0
  429. /package/dist/{chunk-VMCCGUQB.js.map → chunk-6JPGVL7X.js.map} +0 -0
  430. /package/dist/{chunk-WLYIROCJ.js.map → chunk-6YD5SYQS.js.map} +0 -0
  431. /package/dist/{chunk-YAWK6AWF.js.map → chunk-7KAE7CQ2.js.map} +0 -0
  432. /package/dist/{chunk-NKH7GSIH.js.map → chunk-AUPSEJ7O.js.map} +0 -0
  433. /package/dist/{chunk-CCZJJ4I2.js.map → chunk-B6IYATME.js.map} +0 -0
  434. /package/dist/{chunk-4UVDI4XE.js.map → chunk-CLAHBPOI.js.map} +0 -0
  435. /package/dist/{chunk-HVQGCKY4.js.map → chunk-D3R7Q4QK.js.map} +0 -0
  436. /package/dist/{chunk-P7OG2ETF.js.map → chunk-DXKLLKME.js.map} +0 -0
  437. /package/dist/{chunk-JIUVJ4M7.js.map → chunk-EKEIEJL6.js.map} +0 -0
  438. /package/dist/{chunk-DG27IUVI.js.map → chunk-FS7NTGCJ.js.map} +0 -0
  439. /package/dist/{chunk-HXGUIPQB.js.map → chunk-GQXFOAYZ.js.map} +0 -0
  440. /package/dist/{chunk-BTVYJWSN.js.map → chunk-GTHVPVAR.js.map} +0 -0
  441. /package/dist/{chunk-DMQCLZ4Z.js.map → chunk-GWO2IDAB.js.map} +0 -0
  442. /package/dist/{chunk-6HFM7EIT.js.map → chunk-H3G4I3PN.js.map} +0 -0
  443. /package/dist/{chunk-VJFMXYKP.js.map → chunk-HR5R5JOM.js.map} +0 -0
  444. /package/dist/{chunk-FDX7OWWI.js.map → chunk-HYYVT2KZ.js.map} +0 -0
  445. /package/dist/{chunk-JRCYZEHU.js.map → chunk-I6QKB7MT.js.map} +0 -0
  446. /package/dist/{chunk-KUDZVJKQ.js.map → chunk-IJ46VCWD.js.map} +0 -0
  447. /package/dist/{chunk-4HDYQL3J.js.map → chunk-INMHEMXX.js.map} +0 -0
  448. /package/dist/{chunk-AR2JDFAE.js.map → chunk-KV6JM2IA.js.map} +0 -0
  449. /package/dist/{chunk-PVU7LW5L.js.map → chunk-KX57HODD.js.map} +0 -0
  450. /package/dist/{chunk-CEJWMBXO.js.map → chunk-LXECF2ZR.js.map} +0 -0
  451. /package/dist/{chunk-7VHY5E3X.js.map → chunk-MSLPDFK2.js.map} +0 -0
  452. /package/dist/{chunk-HNHCQ556.js.map → chunk-NR2SUJ3H.js.map} +0 -0
  453. /package/dist/{chunk-W3TVWF6N.js.map → chunk-OIBEJN5H.js.map} +0 -0
  454. /package/dist/{chunk-QD724WDJ.js.map → chunk-OMYCSTXL.js.map} +0 -0
  455. /package/dist/{chunk-Z45YRGFO.js.map → chunk-ONVD6GBY.js.map} +0 -0
  456. /package/dist/{chunk-KCQX65FU.js.map → chunk-RKCRPPNB.js.map} +0 -0
  457. /package/dist/{chunk-7TSYBD3E.js.map → chunk-RSXQNFGO.js.map} +0 -0
  458. /package/dist/{chunk-7NXHMW6Y.js.map → chunk-SYS46BL7.js.map} +0 -0
  459. /package/dist/{chunk-747LRSOO.js.map → chunk-TMBSPLUG.js.map} +0 -0
  460. /package/dist/{chunk-WKPJXWKR.js.map → chunk-TX5MKAHA.js.map} +0 -0
  461. /package/dist/{chunk-NJDQ4YSV.js.map → chunk-YKXZHUOW.js.map} +0 -0
  462. /package/dist/{chunk-VW6ZZGCG.js.map → chunk-ZLHHE5XZ.js.map} +0 -0
  463. /package/dist/{chunk-FUHKW252.js.map → chunk-ZZXLB6AS.js.map} +0 -0
  464. /package/dist/{classified-marker-FTOX7Q5L.js.map → classified-marker-NA6HUV33.js.map} +0 -0
  465. /package/dist/{collection-facade-QN5ULWYC.js.map → collection-facade-VBM35WAH.js.map} +0 -0
  466. /package/dist/{computed-6G5M3UPH.js.map → computed-GSTLWSY5.js.map} +0 -0
  467. /package/dist/{dead-filter-ENRIOQIE.js.map → dead-filter-UALP5DJX.js.map} +0 -0
  468. /package/dist/{derive-6V3PIZF7.js.map → derive-YUO3TQYN.js.map} +0 -0
  469. /package/dist/{dispatch-RE74SH6L.js.map → dispatch-4ZHLSFZQ.js.map} +0 -0
  470. /package/dist/{dispatch-BDVGYC6X.js.map → dispatch-77CB75KB.js.map} +0 -0
  471. /package/dist/{enclave-52VUXNRL.js.map → enclave-O4NOROCJ.js.map} +0 -0
  472. /package/dist/{executor-CYJQLKKI.js.map → executor-CZDXBXKE.js.map} +0 -0
  473. /package/dist/{executor-FHHLXO4Y.js.map → executor-DVJAWN3B.js.map} +0 -0
  474. /package/dist/{executor-S4QIKEHW.js.map → executor-VRLG4TQJ.js.map} +0 -0
  475. /package/dist/{export-accessible-PE5AYKZR.js.map → export-accessible-UXSMG7AB.js.map} +0 -0
  476. /package/dist/{extract-partition-X2L26O6A.js.map → extract-partition-TVY7AMKH.js.map} +0 -0
  477. /package/dist/{find-RBBYKXI7.js.map → find-WSARMJBW.js.map} +0 -0
  478. /package/dist/{issue-RNU55YOF.js.map → issue-3JNJNPT3.js.map} +0 -0
  479. /package/dist/{ledger-4WJL66BW.js.map → ledger-MVPNG5OS.js.map} +0 -0
  480. /package/dist/{liberate-PX4CAT5V.js.map → liberate-4LOJOLDT.js.map} +0 -0
  481. /package/dist/{link-set-N4ZPV6E6.js.map → link-set-3POMQR3I.js.map} +0 -0
  482. /package/dist/{managed-secret-OTHS64IF.js.map → managed-secret-IARIJJ7Q.js.map} +0 -0
  483. /package/dist/{noydb-YPSEGK32.js.map → noydb-IRILUDED.js.map} +0 -0
  484. /package/dist/{post-register-ZAG2CAIY.js.map → post-register-Z5T7FY45.js.map} +0 -0
  485. /package/dist/{register-TMD6YRCX.js.map → register-UZ37QPDB.js.map} +0 -0
  486. /package/dist/{registry-CZVINVQH.js.map → registry-ETJNA7PO.js.map} +0 -0
  487. /package/dist/{registry-FVLDWQKT.js.map → registry-F7U6KSLX.js.map} +0 -0
  488. /package/dist/{registry-IKUR2MXD.js.map → registry-L4ELKX6C.js.map} +0 -0
  489. /package/dist/{registry-JET4HBLY.js.map → registry-SDT5LIGO.js.map} +0 -0
  490. /package/dist/{request-withdrawal-RH55LNZL.js.map → request-withdrawal-PVFEYX57.js.map} +0 -0
  491. /package/dist/{reveal-CMOJY4VO.js.map → reveal-DQ2E3QAZ.js.map} +0 -0
  492. /package/dist/{revoke-R5TBYVA6.js.map → revoke-YXY6SHUH.js.map} +0 -0
  493. /package/dist/{signer-AGALOXOO.js.map → signer-Q7XQBMPA.js.map} +0 -0
  494. /package/dist/{stale-ZWXSOWJI.js.map → stale-NI7SAXAZ.js.map} +0 -0
  495. /package/dist/{storage-N7LB275C.js.map → storage-3VNGSHXS.js.map} +0 -0
  496. /package/dist/{ulid-PTAIMDG4.js.map → ulid-VQW6ERQN.js.map} +0 -0
  497. /package/dist/{verify-RO5RTZOJ.js.map → verify-6J2YLKSO.js.map} +0 -0
  498. /package/dist/{walk-OCUHCYJ6.js.map → walk-WRA7RAPY.js.map} +0 -0
  499. /package/dist/{withdraw-accessible-QQNWM5BO.js.map → withdraw-accessible-4JTDFRFZ.js.map} +0 -0
@@ -0,0 +1,76 @@
1
+ import type { EncryptedEnvelope } from '../types.js';
2
+ import type { RecordIdentity } from './record-aad.js';
3
+ /** The body an envelope carries, independent of who is writing it. */
4
+ export interface RecordEnvelopeBody {
5
+ /** AES-GCM IV, base64. Empty string for a plaintext or tombstone envelope. */
6
+ readonly iv: string;
7
+ /** Ciphertext (or plaintext JSON when the collection stores plaintext). */
8
+ readonly data: string;
9
+ /** ISO timestamp. Defaults to now — pass it when the caller has a real one. */
10
+ readonly ts?: string | undefined;
11
+ /** Wrapped per-record CEK, when the record has one. */
12
+ readonly cek?: string | undefined;
13
+ readonly provenance?: {
14
+ readonly source: string;
15
+ readonly sourceTs: string;
16
+ } | undefined;
17
+ /**
18
+ * Slots the envelope may additionally carry.
19
+ *
20
+ * `_tier`, `_by` and `_v` are deliberately NOT here — they come from
21
+ * `identity`, which is the single source for all three. See
22
+ * {@link buildRecordEnvelope}.
23
+ */
24
+ readonly extra?: Partial<Pick<EncryptedEnvelope, '_det' | '_sealed' | '_vdig' | '_bidx'>> | undefined;
25
+ }
26
+ /**
27
+ * Build an envelope for `identity`.
28
+ *
29
+ * ## `identity` is the SINGLE SOURCE for `_by`, `_tier` and `_v`
30
+ *
31
+ * All three are stamped from it, and `RecordEnvelopeBody` deliberately cannot
32
+ * carry them. That is not tidiness — it is what makes the AAD binding safe.
33
+ *
34
+ * The caller encrypts the body under AAD derived from `{collection, id, tier,
35
+ * by, version}`. A reader recomputes that AAD from the address it fetched from
36
+ * plus `_tier`/`_by`/`_v` read back **off the envelope** (`recordAadFor`). So if the
37
+ * identity a writer *declares* could differ from the fields it *stamps*, the
38
+ * AAD would not reproduce and the record would be undecryptable — silently, at
39
+ * write time, discoverable only on the next read, and invisible to every gate
40
+ * because the envelope is perfectly well-formed.
41
+ *
42
+ * An earlier draft took both and asserted they agreed. The assertion fired 230
43
+ * times on the existing tree, which is the argument against it: a rule that can
44
+ * be violated is a rule someone must remember. Taking one source removes the
45
+ * violation instead of reporting it.
46
+ */
47
+ export declare function buildRecordEnvelope(identity: RecordIdentity, body: RecordEnvelopeBody): EncryptedEnvelope;
48
+ /**
49
+ * Build an envelope from an already-sealed body — the output of
50
+ * `writeEnvelopeBody` — **without the caller ever naming `_iv`/`_data`/`_cek`**.
51
+ *
52
+ * This exists because of a guard, and the guard was right. Migrating
53
+ * `writeEnvelopeBody` callers to {@link buildRecordEnvelope} meant rewriting
54
+ * `...body` (a spread, which names nothing) into `iv: body._iv, data:
55
+ * body._data, cek: body._cek` — and `enclave-body-only` failed it: three new
56
+ * protected-body accesses in files that previously had zero.
57
+ *
58
+ * That is the correct outcome rather than an obstacle. #1051 exists to move
59
+ * knowledge of the envelope's shape *inward*; a migration that spreads the
60
+ * protected field names outward to every caller would have defeated its own
61
+ * purpose while looking like progress. The pairing belongs here.
62
+ *
63
+ * ## It takes a SEALER, not a sealed body — and that is load-bearing (#1041)
64
+ *
65
+ * The obvious shape is `(identity, alreadySealedBody, rest)`. That requires the
66
+ * caller to name the identity TWICE — once for `writeEnvelopeBody` and once
67
+ * here — and the two must agree byte for byte or the record is sealed under
68
+ * AAD no reader can reproduce.
69
+ *
70
+ * They did not agree. `with-party/broker/seed.ts` sealed against
71
+ * `{collection, id}` and stamped `{collection, id, by}`, so every broker seed
72
+ * became unreadable the moment AAD switched on. Taking the sealer means the
73
+ * identity is written once and handed to both — divergence stops being
74
+ * possible rather than being something to remember.
75
+ */
76
+ export declare function buildSealedRecordEnvelope(identity: RecordIdentity, seal: (identity: RecordIdentity) => Promise<Pick<EncryptedEnvelope, '_iv' | '_data' | '_cek'>>, body: Omit<RecordEnvelopeBody, 'iv' | 'data' | 'cek'>): Promise<EncryptedEnvelope>;
@@ -13,6 +13,7 @@
13
13
  * per-function doc for its oracle call site) — this file introduces no new
14
14
  * crypto or semantics, only a narrower door onto what already runs.
15
15
  */
16
+ import { type RecordIdentity, type RecordRef } from '../record-aad.js';
16
17
  import { type EnclaveKey } from '../crypto.js';
17
18
  import type { EncryptedEnvelope } from '../../types.js';
18
19
  /**
@@ -27,7 +28,7 @@ import type { EncryptedEnvelope } from '../../types.js';
27
28
  * (the collection DEK), decrypt the body under the unwrapped CEK.
28
29
  * - `env._cek` absent → legacy path, decrypt the body directly under `key`.
29
30
  */
30
- export declare function openEnvelopeJson(env: EncryptedEnvelope, key: EnclaveKey, opts?: {
31
+ export declare function openEnvelopeJson(ref: RecordRef, env: EncryptedEnvelope, key: EnclaveKey, opts?: {
31
32
  encrypted?: boolean;
32
33
  }): Promise<string>;
33
34
  /**
@@ -43,7 +44,7 @@ export declare function openEnvelopeJson(env: EncryptedEnvelope, key: EnclaveKey
43
44
  * generated here rather than supplied by the caller).
44
45
  * - otherwise → legacy path, body encrypted directly under `key`.
45
46
  */
46
- export declare function writeEnvelopeBody(json: string, key: EnclaveKey, opts?: {
47
+ export declare function writeEnvelopeBody(identity: RecordIdentity, json: string, key: EnclaveKey, opts?: {
47
48
  encrypted?: boolean;
48
49
  perRecordKey?: boolean;
49
50
  }): Promise<Pick<EncryptedEnvelope, '_iv' | '_data' | '_cek'>>;
@@ -85,3 +86,34 @@ export declare function hasPerRecordKey(env: EncryptedEnvelope): boolean;
85
86
  * `envelope-body.test.ts`).
86
87
  */
87
88
  export declare function envelopeBodyForHash(env: EncryptedEnvelope): string;
89
+ /**
90
+ * Does `env` carry an AEAD-sealed body at all?
91
+ *
92
+ * The one question callers outside the enclave legitimately need to ask about
93
+ * `_iv` — a tombstone and a plaintext-collection record have none, so there is
94
+ * nothing to authenticate and nothing to re-seal. Both {@link
95
+ * verifyRecordIdentity} (which treats them as vacuously authentic) and the
96
+ * merge authority's `advance` (which stamps them without re-sealing) turn on
97
+ * it, and asking it here keeps `_iv` from leaking back out to the callers —
98
+ * which `enclave-body-only` refused, correctly, when `advance` tested it inline.
99
+ */
100
+ export declare function hasSealedBody(env: Pick<EncryptedEnvelope, '_iv'>): boolean;
101
+ /**
102
+ * Does `env` authenticate at the identity `ref` claims, under `key`? (#1042)
103
+ *
104
+ * The merge's fail-closed check, living here because it is envelope surgery:
105
+ * deciding "is there a sealed body at all" reads `_iv`, which
106
+ * `enclave-body-only` reserves to this folder. An earlier draft did that test
107
+ * in `kernel/noydb.ts` and the guard refused it — correctly, since a caller
108
+ * outside the enclave inspecting protected fields is how envelope knowledge
109
+ * leaks back out.
110
+ *
111
+ * Returns a boolean rather than throwing: `applyRemote` must be able to reject
112
+ * one poisoned record without halting an entire sync, and a hostile store
113
+ * would very much like the opposite.
114
+ *
115
+ * **A record with no sealed body is vacuously authentic** — a tombstone carries
116
+ * none, and a plaintext collection has no AEAD to verify. Those are pass-through
117
+ * by construction, not by omission.
118
+ */
119
+ export declare function verifyRecordIdentity(ref: RecordRef, env: EncryptedEnvelope, key: EnclaveKey): Promise<boolean>;
@@ -21,6 +21,7 @@
21
21
  */
22
22
  import { type EnclaveKey } from '../crypto.js';
23
23
  import type { EncryptedEnvelope } from '../../types.js';
24
+ import { type RecordIdentity } from '../record-aad.js';
24
25
  import type { Lru } from '../../cache/index.js';
25
26
  /** Dependencies {@link resolveStableCek} needs from its collection. */
26
27
  export interface StableCekDeps {
@@ -46,15 +47,31 @@ export interface RewrappedBody {
46
47
  readonly cek: EnclaveKey | null;
47
48
  }
48
49
  /**
49
- * Move a record body from `fromDek` to `toDek`.
50
+ * Move a record body from `fromDek`/`from` to `toDek`/`to`.
50
51
  *
51
52
  * - Per-record-key record (`_cek` present): unwrap the CEK under `fromDek`,
52
53
  * re-encrypt the body under the SAME CEK, re-wrap the CEK under `toDek`. The
53
54
  * body key is unchanged → history-chain identity preserved.
54
55
  * - Legacy record (no `_cek`): decrypt under `fromDek`, re-encrypt under `toDek`
55
- * directly — byte-for-byte the pre-CEK behaviour.
56
+ * directly.
57
+ *
58
+ * ## Why it takes TWO identities (#1041)
59
+ *
60
+ * A rewrap is the one operation where the identity genuinely **changes**. A
61
+ * tier move rewrites `_tier`; a history snapshot lands at a different
62
+ * `(collection, id)` entirely. Since AAD binds both, the body must be opened
63
+ * under the identity it currently has and re-sealed under the one it is moving
64
+ * to. A single identity would be wrong for one end or the other.
65
+ *
66
+ * ⚠️ **This retires an optimisation, deliberately.** Callers used to compute
67
+ * ONE rewrap and reuse the bytes for both a tier move's live write and its
68
+ * `_history` snapshot (#728). Those now have different destination identities,
69
+ * so they need different AAD and therefore different ciphertext — the same
70
+ * bytes cannot satisfy both. Reusing one rewrap for two destinations is now a
71
+ * silent corruption, not a saving: it produces a record that opens at one
72
+ * address and not the other.
56
73
  */
57
- export declare function rewrapBodyToDek(envelope: Pick<EncryptedEnvelope, '_iv' | '_data' | '_cek'>, fromDek: EnclaveKey, toDek: EnclaveKey): Promise<RewrappedBody>;
74
+ export declare function rewrapBodyToDek(from: RecordIdentity, to: RecordIdentity, envelope: Pick<EncryptedEnvelope, '_iv' | '_data' | '_cek' | '_tier' | '_by'>, fromDek: EnclaveKey, toDek: EnclaveKey): Promise<RewrappedBody>;
58
75
  /**
59
76
  * Merge an ALREADY-rewrapped {@link RewrappedBody} into `envelope`, keeping
60
77
  * every field but the re-keyed body (`_iv`/`_data`/`_cek`) unchanged.
@@ -76,7 +93,7 @@ export declare function applyRewrappedBody(envelope: EncryptedEnvelope, body: Re
76
93
  * envelope, generalized to any envelope shape (history callers don't bump
77
94
  * `_v`/`_ts`/`_tier` the way a tier move does).
78
95
  */
79
- export declare function rewrapEnvelope(envelope: EncryptedEnvelope, fromDek: EnclaveKey, toDek: EnclaveKey): Promise<EncryptedEnvelope>;
96
+ export declare function rewrapEnvelope(identity: RecordIdentity, envelope: EncryptedEnvelope, fromDek: EnclaveKey, toDek: EnclaveKey): Promise<EncryptedEnvelope>;
80
97
  /**
81
98
  * Is `envelope` ALREADY wrapped under `dek` (a per-record CEK wrapped under
82
99
  * `dek`, or — legacy, no `_cek` — the body itself decryptable under `dek`)?
@@ -104,4 +121,4 @@ export declare function rewrapEnvelope(envelope: EncryptedEnvelope, fromDek: Enc
104
121
  * those fields themselves, preserving the check-architecture body-access
105
122
  * ratchet.
106
123
  */
107
- export declare function isRewrappedUnder(envelope: Pick<EncryptedEnvelope, '_iv' | '_data' | '_cek'>, dek: EnclaveKey): Promise<boolean>;
124
+ export declare function isRewrappedUnder(identity: RecordIdentity, envelope: Pick<EncryptedEnvelope, '_iv' | '_data' | '_cek'>, dek: EnclaveKey): Promise<boolean>;
@@ -18,6 +18,7 @@
18
18
  */
19
19
  import { type EnclaveKey } from '../crypto.js';
20
20
  import { type EncryptedEnvelope, type CrdtMode, type CrdtStrategy, type VdigFieldPolicy, type SealedHandle } from '../../types.js';
21
+ import { type RecordIdentity, type RecordRef } from '../record-aad.js';
21
22
  import { type StandardSchemaV1 } from '../../schema.js';
22
23
  import type { Lru } from '../../cache/index.js';
23
24
  import type { ViaCryptoCtx } from '../../via/index.js';
@@ -127,11 +128,9 @@ export declare class RecordCodec<T> {
127
128
  * parts. Pure, no crypto. Each call stamps its own `_ts` — provenance carries
128
129
  * a SEPARATE timestamp (computed by the caller), so the two never share one.
129
130
  */
130
- static buildEnvelope(p: {
131
- version: number;
131
+ static buildEnvelope(identity: RecordIdentity, p: {
132
132
  iv: string;
133
133
  data: string;
134
- by?: string;
135
134
  cek?: string;
136
135
  provenance?: {
137
136
  source: string;
@@ -140,10 +139,8 @@ export declare class RecordCodec<T> {
140
139
  extra?: Partial<Pick<EncryptedEnvelope, '_tier' | '_det' | '_sealed'>>;
141
140
  }): EncryptedEnvelope;
142
141
  /** Plaintext (`_iv:''`) body envelope — the `!storeCiphertext` shape. */
143
- static buildPlaintextEnvelope(p: {
144
- version: number;
142
+ static buildPlaintextEnvelope(identity: RecordIdentity, p: {
145
143
  data: string;
146
- by?: string;
147
144
  provenance?: {
148
145
  source: string;
149
146
  sourceTs: string;
@@ -157,7 +154,7 @@ export declare class RecordCodec<T> {
157
154
  * (see {@link encryptRecord}). Rejects `_`-prefixed record fields, which
158
155
  * would collide with the reserved metadata namespace.
159
156
  */
160
- buildDebugEnvelope(record: T, version: number, source?: string, sourceTs?: string): EncryptedEnvelope;
157
+ buildDebugEnvelope(id: string, record: T, version: number, source?: string, sourceTs?: string): EncryptedEnvelope;
161
158
  /**
162
159
  * Encrypt a JSON body into an envelope.
163
160
  *
@@ -167,11 +164,41 @@ export declare class RecordCodec<T> {
167
164
  * path encrypts the body directly under the collection DEK — byte-identical
168
165
  * to pre-CEK behaviour, so non-adopting collections pay nothing.
169
166
  */
170
- encryptJsonString(json: string, version: number, cek?: EnclaveKey, source?: string, sourceTs?: string): Promise<EncryptedEnvelope>;
171
- encryptRecord(record: T, version: number, cek?: EnclaveKey, source?: string, sourceTs?: string, vdig?: {
167
+ /**
168
+ * `ref` is the identity the envelope is sealed against, and it is **the
169
+ * location the bytes are stored at** — not necessarily this codec's own
170
+ * collection (#1051).
171
+ *
172
+ * That distinction was discovered here rather than assumed. Several callers
173
+ * put the result somewhere else entirely: search's vector sidecar lands in
174
+ * `_vec` under `encodeVecId(name, id)`, the lexical index under `_ft/<name>`,
175
+ * indexing's entries under a synthetic `idxId`. A codec that supplied
176
+ * `this.ctx.name` for those would seal them against a collection they are not
177
+ * in, and once AAD binds identity every one of them would fail to verify.
178
+ *
179
+ * ⚠️ **`_history` is the open case, and it is #1041's to settle.** Snapshots
180
+ * are produced with the LIVE record's identity here and then re-homed by
181
+ * `saveHistory` into `_history/<historyId(collection,id,_v)>`. Both readings
182
+ * are defensible — bind where it lives, or bind what it is a copy of — and
183
+ * the choice must be made before AAD is switched on, not inferred from this
184
+ * migration.
185
+ */
186
+ encryptJsonString(ref: RecordRef, json: string, version: number, cek?: EnclaveKey, source?: string, sourceTs?: string): Promise<EncryptedEnvelope>;
187
+ /**
188
+ * `ref` is FIRST and required (#1051). It was previously a trailing optional
189
+ * `id?: string`, which TypeScript cannot promote to required because it sits
190
+ * after other optionals — so the migration would have needed an `id ?? ''`
191
+ * fallback. That is exactly the silent default this issue exists to remove:
192
+ * once identity is bound into the AEAD, every record written with an empty id
193
+ * binds to the SAME identity and becomes interchangeable with the others.
194
+ * An object, not a bare string, so a swap with `version`/`source` cannot
195
+ * compile on the hottest write path. Carries the collection too — see
196
+ * {@link encryptJsonString} for why the codec must not assume its own.
197
+ */
198
+ encryptRecord(ref: RecordRef, record: T, version: number, cek?: EnclaveKey, source?: string, sourceTs?: string, vdig?: {
172
199
  readonly id: string;
173
200
  readonly prev: EncryptedEnvelope | null;
174
- }, id?: string): Promise<EncryptedEnvelope>;
201
+ }): Promise<EncryptedEnvelope>;
175
202
  /**
176
203
  * Resolve the per-record CEK for a stored envelope, or `undefined` for a
177
204
  * legacy (`_cek`-absent) envelope. Unwraps `_cek` under the collection DEK and
@@ -195,7 +222,14 @@ export declare class RecordCodec<T> {
195
222
  * The optional `id` lets reads populate the CEK cache; it is omitted by
196
223
  * callers (history, conflict merge) that have only the envelope.
197
224
  */
198
- decryptJsonString(envelope: EncryptedEnvelope, id?: string): Promise<string | null>;
225
+ /**
226
+ * `ref` must be the SAME identity the writer sealed against — which is the
227
+ * storage address, not necessarily this codec's own collection. Search's
228
+ * vector sidecar lives in `_vec`, its lexical index in `_ft`; passing
229
+ * `this.ctx.name` for those would recompute the wrong AAD and fail to open a
230
+ * perfectly good record (#1041).
231
+ */
232
+ decryptJsonString(ref: RecordRef, envelope: EncryptedEnvelope): Promise<string | null>;
199
233
  /**
200
234
  * Unseal a single `_sealed[field]` slot to its plaintext value: derive the
201
235
  * per-field key off the collection DEK, AES-GCM-decrypt the `iv:data` blob,
@@ -304,7 +338,7 @@ export declare class RecordCodec<T> {
304
338
  * output-recompute path, not the public per-record read surface schema
305
339
  * validation guards.
306
340
  */
307
- decryptRecordAtDek(envelope: EncryptedEnvelope, dek: EnclaveKey, id?: string): Promise<T | null>;
341
+ decryptRecordAtDek(ref: RecordRef, envelope: EncryptedEnvelope, dek: EnclaveKey): Promise<T | null>;
308
342
  /**
309
343
  * Decrypt an envelope into a record of type `T`.
310
344
  *
@@ -320,9 +354,8 @@ export declare class RecordCodec<T> {
320
354
  * that may predate a schema change, so validating it would be a
321
355
  * false positive. Every non-history read leaves this flag `false`.
322
356
  */
323
- decryptRecord(envelope: EncryptedEnvelope, opts?: {
357
+ decryptRecord(ref: RecordRef, envelope: EncryptedEnvelope, opts?: {
324
358
  skipValidation?: boolean;
325
- id?: string;
326
359
  sealedAsHandles?: boolean;
327
360
  }): Promise<T | null>;
328
361
  }
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Re-key a vault's blob set from an old `_blob` DEK to a new one (#1122).
3
+ *
4
+ * ## The defect this closes
5
+ *
6
+ * `rotateKeys` re-keys `store.list(vault, <slot>)` plus the derived refs
7
+ * `derivedRefsFor` declares. That assumes a DEK slot named `X` protects data
8
+ * filed under collection `X`. For `_blob` it is false: the slot is `_blob`, but
9
+ * every byte it protects lives in `_blob_index` and `_blob_chunks`. So rotating
10
+ * `_blob` minted a fresh DEK, re-encrypted **nothing**, and made every blob in
11
+ * the vault permanently unreadable — reported to the user as `TamperedError`,
12
+ * i.e. as an attack, when it was self-inflicted. An ordinary `revoke` of a
13
+ * whole-vault grantee reaches it, because such a grantee's DEK map contains
14
+ * `_blob`.
15
+ *
16
+ * ## Why this cannot be done by `rekeyEnvelopeIfNeeded` alone
17
+ *
18
+ * Two of the three surfaces do not have the shape that helper assumes:
19
+ *
20
+ * - a **chunk** envelope is sealed over raw bytes under a bespoke AAD
21
+ * (`{eTag}:{index}:{count}`), not under the record AAD, so the generic
22
+ * helper cannot open it;
23
+ * - an **index** envelope's body is JSON that may itself carry a wrapped
24
+ * per-blob content CEK (`_cek` / `_cekPending`). Re-encrypting the body under
25
+ * the new DEK without re-wrapping that CEK leaves a blob whose metadata opens
26
+ * and whose bytes never will.
27
+ *
28
+ * ## Why it lives in the enclave
29
+ *
30
+ * It reads and writes protected body slots and it unwraps/re-wraps keys — the
31
+ * two things `enclave-body-only` reserves to `kernel/enclave/**`, and the same
32
+ * reason `rekeyEnvelopeToDek` moved here in #1074. `with-party` orchestrates
33
+ * the rotation and must not touch a body to do it.
34
+ *
35
+ * The blob layout below is duplicated from its owner rather than imported:
36
+ * `with-shape/blobs/blob-set.ts` already imports `with-party/team/tiers.js`, so
37
+ * a `with-party → with-shape` import would close a cycle, and the kernel may
38
+ * not depend on a service. `BlobObject` itself is a kernel type, so only the
39
+ * three collection/id string layouts are copied, with their owner named.
40
+ *
41
+ * @packageDocumentation
42
+ */
43
+ import { type EnclaveKey } from '../crypto.js';
44
+ import type { NoydbStore } from '../../types.js';
45
+ /**
46
+ * What a rotation did to the blob set.
47
+ *
48
+ * Deliberately NOT on the enclave barrel: no caller outside this module binds
49
+ * it, and that surface is the fork-swap trust boundary, so exporting a type
50
+ * nobody consumes is pure widening.
51
+ *
52
+ * It is a return value rather than a log line because `foreign` and `blobs`
53
+ * are the only way to tell "left alone, correctly" from "left alone, because
54
+ * the caller passed a wrong `otherDeks` set". Both re-key nothing and both
55
+ * return successfully. `rotate-preserves-blobs.test.ts` asserts these counts
56
+ * against a direct call for exactly that reason.
57
+ */
58
+ export interface BlobRekeyReport {
59
+ /** Index envelopes moved onto the new DEK. */
60
+ readonly blobs: number;
61
+ /** Chunk envelopes re-encrypted under the new DEK. */
62
+ readonly chunks: number;
63
+ /**
64
+ * Index envelopes left alone because they open under a DEK the caller holds
65
+ * for a DIFFERENT slot — an elevated blob, sealed under `_blob#<tier>`. Those
66
+ * are that slot's rotation to do, not this one's.
67
+ */
68
+ readonly foreign: number;
69
+ /** Index envelopes already under the new DEK — a resumed rotation. */
70
+ readonly alreadyMoved: number;
71
+ }
72
+ /**
73
+ * Move every blob sealed under `oldDek` onto `newDek`.
74
+ *
75
+ * Chunks are re-encrypted BEFORE their index entry is re-sealed, and that order
76
+ * is the resume property: an index entry still readable under `oldDek` means
77
+ * its chunks may be half-moved (each one is probed individually), and an index
78
+ * entry readable under `newDek` means its chunks are already done. An
79
+ * interrupted rotation is finished by re-running it with the same `newDek`.
80
+ *
81
+ * `otherDeks` is what keeps a tier-elevated blob from being mistaken for a
82
+ * damaged one. Membership in `_blob_index` is by DEK, not by collection name:
83
+ * a record elevated to tier N has its blob metadata sealed under `_blob#N`. An
84
+ * envelope that opens under NONE of the keys the caller holds is genuinely
85
+ * unreadable and throws, exactly as `rekeyEnvelopeIfNeeded` does — silently
86
+ * walking past it would turn a loud failure into permanent quiet loss.
87
+ */
88
+ export declare function rekeyBlobSet(adapter: NoydbStore, vault: string, oldDek: EnclaveKey, newDek: EnclaveKey, otherDeks?: readonly EnclaveKey[]): Promise<BlobRekeyReport>;
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Re-key one envelope from an old collection DEK to a new one (#1074).
3
+ *
4
+ * Lives in the enclave because it is envelope surgery: it reads and writes the
5
+ * protected body slots (`_iv`/`_data`/`_cek`), which `enclave-body-only`
6
+ * reserves to `kernel/enclave/**`. `rotateKeys` previously did this inline in
7
+ * `with-party/team/keyring.ts` and got it wrong in two ways that the guard
8
+ * would have caught had the code lived here.
9
+ *
10
+ * @packageDocumentation
11
+ */
12
+ import { type EnclaveKey } from '../crypto.js';
13
+ import type { EncryptedEnvelope } from '../../types.js';
14
+ /**
15
+ * Produce the envelope `envelope` becomes once its collection's DEK rotates
16
+ * from `oldDek` to `newDek`.
17
+ *
18
+ * **Every slot is carried forward except `_bidx`.** The previous inline version
19
+ * built a fresh literal holding only `_noydb/_v/_ts/_iv/_data`, silently
20
+ * discarding `_by`, `_tier`, `_cek`, `_sealed`, `_vdig` and `_source`. Losing
21
+ * `_tier` was the worst of those: tier-0 reads treat elevated as missing, so an
22
+ * elevated record did not error after a rotation — it simply disappeared.
23
+ *
24
+ * `_bidx` is dropped deliberately. It is a DEK-rooted equality tag, so a tag
25
+ * carried across a DEK rotation can never be re-derived to match a query again
26
+ * while still leaking the old equality partition. Index coverage regrows
27
+ * per-record on the next `put()` under the new DEK.
28
+ *
29
+ * Two shapes, and picking the wrong one is why this needed a helper:
30
+ *
31
+ * - **per-record CEK** (`_cek` present) — the body is sealed under the CEK and
32
+ * the CEK is wrapped under the collection DEK, so rotation re-wraps the CEK
33
+ * and leaves the body **untouched**. The old inline code instead ran
34
+ * `decrypt(body, oldDek)` on these, which throws: rotation could not complete
35
+ * on a collection containing any CEK record.
36
+ * - **bare** — body sealed directly under the DEK, so decrypt and re-encrypt.
37
+ *
38
+ * Idempotence is the caller's problem, not this function's: it assumes
39
+ * `envelope` is still under `oldDek`. A resumable rotation must know which side
40
+ * of the migration each record is on before calling.
41
+ */
42
+ export declare function rekeyEnvelopeToDek(ref: {
43
+ readonly collection: string;
44
+ readonly id: string;
45
+ }, envelope: EncryptedEnvelope, oldDek: EnclaveKey, newDek: EnclaveKey): Promise<EncryptedEnvelope>;
46
+ /**
47
+ * Resumable variant: returns the re-keyed envelope, or `null` when `envelope`
48
+ * is **already** under `newDek` and needs no work (#1074 part 2).
49
+ *
50
+ * A rotation interrupted mid-collection leaves records on both sides of the
51
+ * migration. Resuming means re-running the rotation with the *same* new DEK,
52
+ * which requires distinguishing "not yet moved" from "already moved" without
53
+ * the caller touching protected slots.
54
+ *
55
+ * Detection is by trial decryption under `oldDek`. There is no metadata that
56
+ * says which DEK sealed a record — deliberately, since such a marker would be
57
+ * store-writable and therefore a downgrade lever (the same reasoning that
58
+ * keeps the reader from branching on `_noydb`).
59
+ *
60
+ * A record that opens under *neither* key is genuinely damaged and rethrows,
61
+ * rather than being silently skipped: a rotation that quietly walked past
62
+ * unreadable records would convert a loud failure into permanent silent loss,
63
+ * which is the defect this whole issue is about.
64
+ */
65
+ export declare function rekeyEnvelopeIfNeeded(ref: {
66
+ readonly collection: string;
67
+ readonly id: string;
68
+ }, envelope: EncryptedEnvelope, oldDek: EnclaveKey, newDek: EnclaveKey): Promise<EncryptedEnvelope | null>;
@@ -16,6 +16,7 @@
16
16
  * vault; it calls into these.
17
17
  */
18
18
  import { type EncryptedEnvelope } from '../../types.js';
19
+ import type { RecordRef } from '../record-aad.js';
19
20
  /**
20
21
  * Shape-only tombstone recognition for layers that have no per-collection
21
22
  * context (the sync engine, #590): a tombstone carries an empty `_data` and
@@ -45,7 +46,7 @@ export declare function isTombstone(envelope: EncryptedEnvelope, encrypted: bool
45
46
  * Deliberately omits `_iv`/`_data`/`_cek`/`_det` — that omission *is* the
46
47
  * erasure.
47
48
  */
48
- export declare function buildTombstone(version: number, actor: string): EncryptedEnvelope;
49
+ export declare function buildTombstone(ref: RecordRef, version: number, actor: string): EncryptedEnvelope;
49
50
  /** #589: is this envelope an ordinary-delete marker (version-ordered, reads as absent)? */
50
51
  export declare function isDeleteMarker(envelope: EncryptedEnvelope): boolean;
51
52
  /**
@@ -54,4 +55,4 @@ export declare function isDeleteMarker(envelope: EncryptedEnvelope): boolean;
54
55
  * keeps the displaced `_v` — so it wins convergence over the pre-delete copy and a
55
56
  * re-create can still win over it at a higher version.
56
57
  */
57
- export declare function buildDeleteMarker(version: number, actor: string): EncryptedEnvelope;
58
+ export declare function buildDeleteMarker(ref: RecordRef, version: number, actor: string): EncryptedEnvelope;
@@ -10,7 +10,9 @@
10
10
  * ├─ Crypto errors
11
11
  * │ ├─ DecryptionError — AES-GCM tag failure
12
12
  * │ ├─ TamperedError — ciphertext modified after write
13
- * │ └─ InvalidKeyError — wrong secret / corrupt keyring
13
+ * │ ├─ InvalidKeyError — wrong secret / corrupt keyring
14
+ * │ ├─ KeyringCorruptError — partial DEK corruption, KEK correct
15
+ * │ └─ KeyringTamperedError — keyring roster failed authentication (#1096)
14
16
  * ├─ Access errors
15
17
  * │ ├─ NoAccessError — no DEK for this collection
16
18
  * │ ├─ ReadOnlyError — ro permission, write attempted
@@ -52,7 +54,7 @@
52
54
  * │ ├─ BackupLedgerError — hash-chain verification failed
53
55
  * │ └─ BackupCorruptedError — envelope hash mismatch in dump
54
56
  * ├─ Bundle errors
55
- * │ └─ BundleIntegrityError — .noydb body sha256 mismatch
57
+ * │ └─ PodIntegrityError — .noydb body sha256 mismatch
56
58
  * ├─ Session errors
57
59
  * │ ├─ SessionExpiredError
58
60
  * │ ├─ SessionNotFoundError
@@ -143,7 +145,23 @@ export declare class DecryptionError extends NoydbError {
143
145
  * Treat it as a security alert: the stored bytes are not what NOYDB wrote.
144
146
  */
145
147
  export declare class TamperedError extends NoydbError {
146
- constructor(message?: string);
148
+ /**
149
+ * Why the tag check failed, when the enclave could tell (#1103).
150
+ *
151
+ * `'unbound-legacy-format'` — the body opens under an EMPTY AAD, so it was
152
+ * sealed before identity binding (#1041) and this is a format transition, not
153
+ * an attack. Positive evidence, not a guess: producing a body that decrypts
154
+ * under this DEK requires the DEK, which an untrusted store does not hold.
155
+ *
156
+ * Absent — no benign explanation was found. Treat as the security alert this
157
+ * error has always been.
158
+ *
159
+ * The field is additive and the throw is unchanged, so
160
+ * `catch (e) { if (e instanceof TamperedError) … }` keeps working; callers
161
+ * that want to tell a migration from a breach can now read this.
162
+ */
163
+ readonly reason?: 'unbound-legacy-format';
164
+ constructor(message?: string, reason?: 'unbound-legacy-format');
147
165
  }
148
166
  /**
149
167
  * Thrown when key unwrapping fails, typically because the secret is wrong
@@ -177,6 +195,51 @@ export declare class KeyringCorruptError extends NoydbError {
177
195
  message?: string;
178
196
  });
179
197
  }
198
+ /**
199
+ * #1096 — the keyring's plaintext AUTHORITY half failed authentication.
200
+ *
201
+ * Thrown by `loadKeyring` when the canary is absent, when the reserved
202
+ * roster-key DEK entry is absent, or when the keys check out (KEK proven
203
+ * correct) but `roster_tag` is missing or does not match the file.
204
+ *
205
+ * Distinct from {@link KeyringCorruptError}: the KEYS are fine; the ROSTER —
206
+ * `role`, `permissions`, `granted_by`, the capability grants — is what cannot
207
+ * be trusted. A `_keyring` file is stored plaintext so admins can edit a
208
+ * member's authority without holding that member's credential, which left
209
+ * those fields authenticated by nothing; this error is what a hostile store
210
+ * editing them now produces.
211
+ *
212
+ * Deliberately raised only AFTER the key-unwrap epilogue, so a plain
213
+ * wrong-secret keeps reporting as `InvalidKeyError` and is never
214
+ * misannounced to the user as an attack.
215
+ */
216
+ /**
217
+ * Why a `_keyring` file failed roster authentication (#1096).
218
+ *
219
+ * Named rather than inlined because a third consumer now reports it without
220
+ * throwing: `RotateResult.unverified` (#1114) lists the members a rotation
221
+ * skipped, and a union duplicated per call site drifts.
222
+ */
223
+ export type KeyringTamperedReason = 'canary-missing' | 'roster-key-missing' | 'roster-tag-missing' | 'roster-tag-mismatch'
224
+ /**
225
+ * The file did not parse at all (#1121). Never thrown by
226
+ * `assertRosterAuthenticated` — which cannot reach a file it could not read —
227
+ * but reported by `verifyRoster` and accepted by `quarantineKeyring`, because
228
+ * truncation and bitrot produce the most literally unauthenticatable file
229
+ * there is and the tools for unauthenticatable files must not be the ones
230
+ * that choke on it.
231
+ */
232
+ | 'unparseable';
233
+ export declare class KeyringTamperedError extends NoydbError {
234
+ readonly details: {
235
+ readonly userId: string;
236
+ readonly reason: KeyringTamperedReason;
237
+ };
238
+ constructor(details: {
239
+ readonly userId: string;
240
+ readonly reason: KeyringTamperedReason;
241
+ });
242
+ }
180
243
  /**
181
244
  * Thrown when the authenticated user does not have a DEK for the requested
182
245
  * collection — i.e. the collection is not in their keyring at all.
@@ -277,7 +340,7 @@ export declare class ExportCapabilityError extends NoydbError {
277
340
  * can show a precise "this bundle slot has expired" message instead
278
341
  * of the generic decryption-failure UX.
279
342
  *
280
- * Used predominantly on `BundleRecipient` slots produced by
343
+ * Used predominantly on `PodRecipient` slots produced by
281
344
  * `writePod({ recipients: [...] })` to time-box audit access.
282
345
  */
283
346
  export declare class KeyringExpiredError extends NoydbError {
@@ -759,10 +822,6 @@ export declare class PodVersionConflictError extends NoydbError {
759
822
  readonly remoteVersion: string;
760
823
  constructor(remoteVersion: string, message?: string);
761
824
  }
762
- /** @deprecated Use `PodVersionConflictError`. */
763
- export declare const BundleVersionConflictError: typeof PodVersionConflictError;
764
- /** @deprecated Use `PodVersionConflictError`. */
765
- export type BundleVersionConflictError = PodVersionConflictError;
766
825
  /**
767
826
  * Thrown when a sync operation (push or pull) fails due to a network error.
768
827
  *
@@ -1012,7 +1071,7 @@ export declare class FieldNotQueryableError extends NoydbError {
1012
1071
  * format violations like a missing magic prefix or malformed
1013
1072
  * header JSON) so consumers can pattern-match the corruption case
1014
1073
  * and handle it differently from a producer bug. A
1015
- * `BundleIntegrityError` indicates "the bytes you got are not
1074
+ * `PodIntegrityError` indicates "the bytes you got are not
1016
1075
  * what was written"; a plain `Error` from `parsePrefixAndHeader`
1017
1076
  * indicates "what was written wasn't a valid bundle in the first
1018
1077
  * place."
@@ -1022,7 +1081,7 @@ export declare class FieldNotQueryableError extends NoydbError {
1022
1081
  * written) but it surfaces with the same error class because the
1023
1082
  * end result is "the body cannot be turned back into a dump."
1024
1083
  */
1025
- export declare class BundleIntegrityError extends NoydbError {
1084
+ export declare class PodIntegrityError extends NoydbError {
1026
1085
  constructor(message: string);
1027
1086
  }
1028
1087
  /**
@@ -1046,7 +1105,7 @@ export declare class PodHeaderVerificationError extends NoydbError {
1046
1105
  * surface an actionable prompt:
1047
1106
  *
1048
1107
  * ```
1049
- * BundleSealMismatchError: bundle carries sealed secret for user "alice"
1108
+ * PodSealMismatchError: bundle carries sealed secret for user "alice"
1050
1109
  * under provider "macos-keychain:com.acme.app/alice@acme.example",
1051
1110
  * but no registered provider matches that pid.
1052
1111
  * ```
@@ -1059,7 +1118,7 @@ export declare class PodHeaderVerificationError extends NoydbError {
1059
1118
  * 3. Inspect without unsealing — pass no `sealingProviders` to
1060
1119
  * receive the sealed entries unmodified for offline analysis.
1061
1120
  */
1062
- export declare class BundleSealMismatchError extends NoydbError {
1121
+ export declare class PodSealMismatchError extends NoydbError {
1063
1122
  readonly userId: string;
1064
1123
  readonly pid: string;
1065
1124
  constructor(userId: string, pid: string);