@noy-db/hub 0.3.0-pre.8 → 0.3.0

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 (955) hide show
  1. package/dist/aggregate/index.js +9 -8
  2. package/dist/aggregate/index.js.map +1 -1
  3. package/dist/api-ZGS6LCOF.js +20 -0
  4. package/dist/as/index.js +11 -11
  5. package/dist/attestation/index.js +18 -18
  6. package/dist/backup-BJ57IKAO.js +242 -0
  7. package/dist/backup-BJ57IKAO.js.map +1 -0
  8. package/dist/blobs/index.js +13 -11
  9. package/dist/blobs/index.js.map +1 -1
  10. package/dist/broker/index.js +92 -0
  11. package/dist/broker/index.js.map +1 -0
  12. package/dist/bundle/index.js +25 -22
  13. package/dist/bundle/index.js.map +1 -1
  14. package/dist/by/index.js +2 -2
  15. package/dist/cargo/index.js +31 -31
  16. package/dist/chunk-2NVOWNI3.js +167 -0
  17. package/dist/chunk-2NVOWNI3.js.map +1 -0
  18. package/dist/chunk-3B5VVCNY.js +71 -0
  19. package/dist/chunk-3LQ2YKO4.js +230 -0
  20. package/dist/chunk-3QCRBHCY.js +54 -0
  21. package/dist/chunk-454JXE57.js +1697 -0
  22. package/dist/chunk-454JXE57.js.map +1 -0
  23. package/dist/chunk-4CTHCN4J.js +480 -0
  24. package/dist/chunk-4CTHCN4J.js.map +1 -0
  25. package/dist/chunk-4GPE63GU.js +111 -0
  26. package/dist/chunk-4GPE63GU.js.map +1 -0
  27. package/dist/chunk-4JBYV75E.js +150 -0
  28. package/dist/chunk-4NXKCLLQ.js +97 -0
  29. package/dist/chunk-4VNQOLML.js +29 -0
  30. package/dist/chunk-4VNQOLML.js.map +1 -0
  31. package/dist/chunk-5M5DVGV7.js +69 -0
  32. package/dist/chunk-5O3XF4DV.js +150 -0
  33. package/dist/chunk-5O3XF4DV.js.map +1 -0
  34. package/dist/chunk-5YOLBEQ6.js +30 -0
  35. package/dist/chunk-6CRIV7DE.js +129 -0
  36. package/dist/chunk-6JTIAGHD.js +621 -0
  37. package/dist/chunk-6JTIAGHD.js.map +1 -0
  38. package/dist/chunk-6QTNZJBS.js +255 -0
  39. package/dist/chunk-6T2SCQRU.js +86 -0
  40. package/dist/chunk-7DSTRQIJ.js +45 -0
  41. package/dist/chunk-AUSTCW2X.js +589 -0
  42. package/dist/chunk-B3HJYUOF.js +209 -0
  43. package/dist/chunk-BDVFPG6Y.js +164 -0
  44. package/dist/chunk-BIOUI4HL.js +1554 -0
  45. package/dist/chunk-BIOUI4HL.js.map +1 -0
  46. package/dist/chunk-CAF6WOK7.js +36 -0
  47. package/dist/chunk-CDUQTA3Z.js +381 -0
  48. package/dist/chunk-CDUQTA3Z.js.map +1 -0
  49. package/dist/chunk-CIE2BASH.js +404 -0
  50. package/dist/chunk-CRI4OUV4.js +42 -0
  51. package/dist/chunk-DLG74CNB.js +91 -0
  52. package/dist/chunk-E5ZQT5KX.js +30 -0
  53. package/dist/chunk-E5ZQT5KX.js.map +1 -0
  54. package/dist/chunk-EQO2UVP4.js +247 -0
  55. package/dist/chunk-EQO2UVP4.js.map +1 -0
  56. package/dist/chunk-ERJ7FU55.js +367 -0
  57. package/dist/chunk-EVVGJDRQ.js +205 -0
  58. package/dist/chunk-EVX47VBM.js +74 -0
  59. package/dist/chunk-EVX47VBM.js.map +1 -0
  60. package/dist/chunk-EXK7QRWF.js +59 -0
  61. package/dist/chunk-EYZ6IQ6X.js +202 -0
  62. package/dist/chunk-F64IRYG3.js +45 -0
  63. package/dist/chunk-FHS2HQSH.js +823 -0
  64. package/dist/chunk-FM3G3NOY.js +206 -0
  65. package/dist/chunk-FM3G3NOY.js.map +1 -0
  66. package/dist/chunk-FUG4SFN3.js +36 -0
  67. package/dist/chunk-FUG4SFN3.js.map +1 -0
  68. package/dist/chunk-GKEWXIV5.js +80 -0
  69. package/dist/chunk-GTGPO5KW.js +59 -0
  70. package/dist/chunk-HB3RFQSC.js +95 -0
  71. package/dist/chunk-HDMEGAQE.js +957 -0
  72. package/dist/chunk-HDMEGAQE.js.map +1 -0
  73. package/dist/chunk-HDQIIUPH.js +135 -0
  74. package/dist/chunk-HDQIIUPH.js.map +1 -0
  75. package/dist/chunk-HTJQYHZP.js +344 -0
  76. package/dist/chunk-HTJQYHZP.js.map +1 -0
  77. package/dist/chunk-I6GALP6E.js +99 -0
  78. package/dist/chunk-IGJCYUT5.js +99 -0
  79. package/dist/chunk-IGJCYUT5.js.map +1 -0
  80. package/dist/chunk-IL6POWCW.js +130 -0
  81. package/dist/chunk-IU6SNYX6.js +117 -0
  82. package/dist/chunk-J2ZX2XUV.js +778 -0
  83. package/dist/chunk-JIF24JPM.js +495 -0
  84. package/dist/chunk-JIF24JPM.js.map +1 -0
  85. package/dist/chunk-JK733I5V.js +23 -0
  86. package/dist/chunk-JK733I5V.js.map +1 -0
  87. package/dist/chunk-JKJOGPZN.js +29 -0
  88. package/dist/chunk-JNAI2HN2.js +32 -0
  89. package/dist/chunk-JNAI2HN2.js.map +1 -0
  90. package/dist/chunk-JZUV47FZ.js +41 -0
  91. package/dist/chunk-K5IMOGHB.js +30 -0
  92. package/dist/chunk-KPZS5QAQ.js +151 -0
  93. package/dist/chunk-KPZS5QAQ.js.map +1 -0
  94. package/dist/chunk-KSKBRKGJ.js +291 -0
  95. package/dist/chunk-KSKBRKGJ.js.map +1 -0
  96. package/dist/chunk-LASZKVMO.js +382 -0
  97. package/dist/chunk-LXEXBTKL.js +515 -0
  98. package/dist/chunk-LXEXBTKL.js.map +1 -0
  99. package/dist/chunk-M4CV6BRT.js +524 -0
  100. package/dist/chunk-M4CV6BRT.js.map +1 -0
  101. package/dist/chunk-MEFJPTZ4.js +371 -0
  102. package/dist/chunk-MEFJPTZ4.js.map +1 -0
  103. package/dist/chunk-MV43JSJF.js +265 -0
  104. package/dist/chunk-MV43JSJF.js.map +1 -0
  105. package/dist/chunk-NJ4EOKMB.js +392 -0
  106. package/dist/chunk-NJ4EOKMB.js.map +1 -0
  107. package/dist/chunk-NR5LT5RY.js +135 -0
  108. package/dist/chunk-NWSGI5C7.js +261 -0
  109. package/dist/chunk-NWSGI5C7.js.map +1 -0
  110. package/dist/chunk-OSDB5WW3.js +739 -0
  111. package/dist/chunk-OSDB5WW3.js.map +1 -0
  112. package/dist/chunk-PN2XMATY.js +37 -0
  113. package/dist/chunk-PN2XMATY.js.map +1 -0
  114. package/dist/chunk-Q5VNKNE5.js +70 -0
  115. package/dist/chunk-QLWMEXCT.js +21 -0
  116. package/dist/chunk-QRB7NAOJ.js +123 -0
  117. package/dist/chunk-R4ROFEYC.js +74 -0
  118. package/dist/chunk-RCVJZMFE.js +164 -0
  119. package/dist/chunk-RCVJZMFE.js.map +1 -0
  120. package/dist/chunk-RIX4V2TB.js +367 -0
  121. package/dist/chunk-RYCTDFUX.js +40 -0
  122. package/dist/chunk-RZ5SVOYR.js +155 -0
  123. package/dist/chunk-SLFHQTTW.js +99 -0
  124. package/dist/chunk-SNZ6URZZ.js +2782 -0
  125. package/dist/chunk-SNZ6URZZ.js.map +1 -0
  126. package/dist/chunk-T2FFWNPK.js +75 -0
  127. package/dist/chunk-T2FFWNPK.js.map +1 -0
  128. package/dist/chunk-UNFPPVNI.js +23 -0
  129. package/dist/chunk-VFUPHI2Z.js +333 -0
  130. package/dist/chunk-VFUPHI2Z.js.map +1 -0
  131. package/dist/chunk-VLFCJYTL.js +235 -0
  132. package/dist/chunk-VN3DBQAU.js +124 -0
  133. package/dist/chunk-VYYM3MEN.js +98 -0
  134. package/dist/chunk-VYYM3MEN.js.map +1 -0
  135. package/dist/chunk-VZRODIM3.js +49 -0
  136. package/dist/chunk-W22IKJE2.js +94 -0
  137. package/dist/chunk-X3YYQWOQ.js +155 -0
  138. package/dist/chunk-X7QBD67R.js +14405 -0
  139. package/dist/chunk-X7QBD67R.js.map +1 -0
  140. package/dist/chunk-XDYREZWE.js +1128 -0
  141. package/dist/chunk-XDYREZWE.js.map +1 -0
  142. package/dist/chunk-XWZVFISC.js +720 -0
  143. package/dist/chunk-XWZVFISC.js.map +1 -0
  144. package/dist/chunk-YFXZEAYK.js +85 -0
  145. package/dist/chunk-ZAJAVEXY.js +50 -0
  146. package/dist/chunk-ZICD77GM.js +34 -0
  147. package/dist/chunk-ZJ2AK4V7.js +38 -0
  148. package/dist/chunk-ZJ2AK4V7.js.map +1 -0
  149. package/dist/chunk-ZUODRVHY.js +14 -0
  150. package/dist/classified/index.js +5 -3
  151. package/dist/classified-marker-CZKA6ITE.js +28 -0
  152. package/dist/classified-marker-CZKA6ITE.js.map +1 -0
  153. package/dist/collection-facade-TLWIPI76.js +44 -0
  154. package/dist/computed-ZIQTYTDI.js +11 -0
  155. package/dist/consent/index.js +9 -9
  156. package/dist/crdt/index.js +1 -1
  157. package/dist/dead-filter-ESOBZZP5.js +28 -0
  158. package/dist/delegation-W7ZV2322.js +25 -0
  159. package/dist/derivations/index.js +12 -11
  160. package/dist/derive-H2BJTLUI.js +21 -0
  161. package/dist/enclave-AP3I5W7O.js +141 -0
  162. package/dist/executor-KGWTNEQD.js +9 -0
  163. package/dist/executor-OVEXR6RT.js +9 -0
  164. package/dist/executor-UNEH5ZYH.js +25 -0
  165. package/dist/export-accessible-PCMXSUZS.js +23 -0
  166. package/dist/extract-partition-SWHFSYJO.js +38 -0
  167. package/dist/fanout-sidecar-A765THMX.js +74 -0
  168. package/dist/find-N6345CNT.js +11 -0
  169. package/dist/forget/index.js +10 -10
  170. package/dist/forget/index.js.map +1 -1
  171. package/dist/guards/index.js +6 -6
  172. package/dist/history/index.js +14 -11
  173. package/dist/history/index.js.map +1 -1
  174. package/dist/i18n/index.js +50 -37
  175. package/dist/i18n/index.js.map +1 -1
  176. package/dist/index.d.ts +307 -1459
  177. package/dist/index.js +595 -198
  178. package/dist/index.js.map +1 -1
  179. package/dist/indexing/index.js +7 -7
  180. package/dist/indexing/index.js.map +1 -1
  181. package/dist/issue-5OKB6I2R.js +19 -0
  182. package/dist/kernel/best-effort-revert.d.ts +52 -0
  183. package/dist/kernel/cache/index.d.ts +10 -0
  184. package/dist/kernel/cache/lru.d.ts +97 -0
  185. package/dist/kernel/cache/policy.d.ts +32 -0
  186. package/dist/kernel/collection-config.d.ts +809 -0
  187. package/dist/kernel/collection.d.ts +1522 -0
  188. package/dist/kernel/constants.d.ts +18 -0
  189. package/dist/kernel/debug.d.ts +25 -0
  190. package/dist/kernel/enclave/broker/proof.d.ts +154 -0
  191. package/dist/kernel/enclave/classify/bidx.d.ts +77 -0
  192. package/dist/kernel/enclave/classify/compare.d.ts +10 -0
  193. package/dist/kernel/enclave/classify/digest.d.ts +8 -0
  194. package/dist/kernel/enclave/classify/find.d.ts +36 -0
  195. package/dist/kernel/enclave/classify/kofn.d.ts +7 -0
  196. package/dist/kernel/enclave/classify/normalize.d.ts +7 -0
  197. package/dist/kernel/enclave/classify/reveal.d.ts +10 -0
  198. package/dist/kernel/enclave/classify/vdig.d.ts +39 -0
  199. package/dist/kernel/enclave/classify/verify.d.ts +36 -0
  200. package/dist/kernel/enclave/classify/write.d.ts +8 -0
  201. package/dist/kernel/enclave/crypto.d.ts +263 -0
  202. package/dist/kernel/enclave/index.d.ts +79 -0
  203. package/dist/kernel/enclave/record-keys/deterministic.d.ts +55 -0
  204. package/dist/kernel/enclave/record-keys/envelope-body.d.ts +79 -0
  205. package/dist/kernel/enclave/record-keys/lifecycle.d.ts +107 -0
  206. package/dist/kernel/enclave/record-keys/record-codec.d.ts +328 -0
  207. package/dist/kernel/enclave/record-keys/sealed-slot.d.ts +14 -0
  208. package/dist/kernel/enclave/record-keys/sealed-slots.d.ts +123 -0
  209. package/dist/kernel/enclave/record-keys/sealing.d.ts +70 -0
  210. package/dist/kernel/enclave/record-keys/tombstone.d.ts +57 -0
  211. package/dist/kernel/env-check.d.ts +1 -0
  212. package/dist/kernel/errors.d.ts +1922 -0
  213. package/dist/kernel/events.d.ts +11 -0
  214. package/dist/kernel/lazy-count.d.ts +13 -0
  215. package/dist/kernel/memory-store.d.ts +17 -0
  216. package/dist/kernel/mutation.d.ts +14 -0
  217. package/dist/kernel/noydb.d.ts +826 -0
  218. package/dist/kernel/paths.d.ts +25 -0
  219. package/dist/kernel/query/builder.d.ts +520 -0
  220. package/dist/kernel/query/index.d.ts +31 -0
  221. package/dist/kernel/query/join.d.ts +205 -0
  222. package/dist/kernel/query/live.d.ts +111 -0
  223. package/dist/kernel/query/predicate.d.ts +139 -0
  224. package/dist/kernel/query/scan-builder.d.ts +334 -0
  225. package/dist/kernel/refs.d.ts +205 -0
  226. package/dist/kernel/schema.d.ts +134 -0
  227. package/dist/kernel/sync-policy.d.ts +188 -0
  228. package/dist/kernel/tier-visibility.d.ts +54 -0
  229. package/dist/kernel/types.d.ts +3239 -0
  230. package/dist/kernel/util/discriminant.d.ts +58 -0
  231. package/dist/kernel/util/index.d.ts +14 -0
  232. package/dist/kernel/util/sanitize-filename.d.ts +75 -0
  233. package/dist/kernel/validation.d.ts +130 -0
  234. package/dist/kernel/vault.d.ts +1740 -0
  235. package/dist/kernel/via/compose.d.ts +144 -0
  236. package/dist/kernel/via/dispatch.d.ts +195 -0
  237. package/dist/kernel/via/graph-wiring.d.ts +145 -0
  238. package/dist/kernel/via/graph.d.ts +166 -0
  239. package/dist/kernel/via/index.d.ts +200 -0
  240. package/dist/kernel/via/pipeline.d.ts +266 -0
  241. package/dist/kernel/via/reconcile.d.ts +153 -0
  242. package/dist/kernel/via/taint-binding.d.ts +66 -0
  243. package/dist/kernel/write-queue.d.ts +46 -0
  244. package/dist/ledger-GFBKVPV4.js +42 -0
  245. package/dist/legacy/bundle.d.ts +30 -0
  246. package/dist/legacy/kernel.d.ts +33 -0
  247. package/dist/liberate-3VDOT4KO.js +24 -0
  248. package/dist/link-set-Z7Q2ASFX.js +31 -0
  249. package/dist/materialized-views/index.js +19 -15
  250. package/dist/noydb-ZCJOYBDI.js +68 -0
  251. package/dist/on/index.js +9 -9
  252. package/dist/overlay-views/index.js +4 -4
  253. package/dist/periods/index.js +12 -12
  254. package/dist/pod/index.js +11 -11
  255. package/dist/policy-Z3RUAIY2.js +41 -0
  256. package/dist/port/as/index.d.ts +26 -0
  257. package/dist/port/at/index.d.ts +18 -0
  258. package/dist/port/by/default-provider.d.ts +9 -0
  259. package/dist/port/by/index.d.ts +17 -0
  260. package/dist/port/by/types.d.ts +86 -0
  261. package/dist/port/in/index.d.ts +21 -0
  262. package/dist/port/on/index.d.ts +27 -0
  263. package/dist/port/to/index.d.ts +19 -0
  264. package/dist/port/ui/index.d.ts +21 -0
  265. package/dist/port/with/blob-strategy.d.ts +98 -0
  266. package/dist/port/with/broker-strategy.d.ts +84 -0
  267. package/dist/port/with/capabilities.d.ts +31 -0
  268. package/dist/port/with/classified-marker.d.ts +9 -0
  269. package/dist/port/with/classified-strategy.d.ts +62 -0
  270. package/dist/port/with/computed-strategy.d.ts +19 -0
  271. package/dist/port/with/i18n-strategy.d.ts +175 -0
  272. package/dist/port/with/index.d.ts +18 -0
  273. package/dist/port/with/lazy-strategy.d.ts +48 -0
  274. package/dist/port/with/lookup-strategy.d.ts +129 -0
  275. package/dist/port/with/service-bus.d.ts +156 -0
  276. package/dist/port/with/team-strategy.d.ts +36 -0
  277. package/dist/port/with/write-hooks.d.ts +34 -0
  278. package/dist/portability/index.js +8 -8
  279. package/dist/post-register-JTH76BLY.js +60 -0
  280. package/dist/post-register-JTH76BLY.js.map +1 -0
  281. package/dist/public-envelope-B4KNWVUA.js +32 -0
  282. package/dist/purge-scope-FGNNLWHD.js +24 -0
  283. package/dist/purge-scope-FGNNLWHD.js.map +1 -0
  284. package/dist/query/index.js +9 -6
  285. package/dist/read-only-facade-CHCKSEPD.js +8 -0
  286. package/dist/register-VAHONCID.js +23 -0
  287. package/dist/registry-7MLVD3VO.js +19 -0
  288. package/dist/registry-EPKPD5SM.js +18 -0
  289. package/dist/registry-P5T7PS2U.js +9 -0
  290. package/dist/request-withdrawal-TI3A5WPS.js +31 -0
  291. package/dist/reveal-DIBHLUZX.js +38 -0
  292. package/dist/reveal-DIBHLUZX.js.map +1 -0
  293. package/dist/revoke-FDRD6GRW.js +24 -0
  294. package/dist/satellites/index.js +1 -1
  295. package/dist/sealed-record/index.js +12 -12
  296. package/dist/seed-Q6M2IZFL.js +231 -0
  297. package/dist/seed-Q6M2IZFL.js.map +1 -0
  298. package/dist/session/index.js +9 -9
  299. package/dist/shadow/index.js +2 -2
  300. package/dist/signer-MUWEIUI6.js +25 -0
  301. package/dist/snapshots/index.js +10 -10
  302. package/dist/stale-OSQ7J3AA.js +29 -0
  303. package/dist/storage-MVFCGEQE.js +23 -0
  304. package/dist/store-coordination-provider-64OEZFGS.js +142 -0
  305. package/dist/sync/index.js +9 -9
  306. package/dist/team/index.js +15 -15
  307. package/dist/tiers/index.js +14 -10
  308. package/dist/to/index.js +1 -2
  309. package/dist/tx/index.js +3 -3
  310. package/dist/util/index.js +1 -1
  311. package/dist/verify-ZASTRNPR.js +140 -0
  312. package/dist/verify-ZASTRNPR.js.map +1 -0
  313. package/dist/via/blob/active.d.ts +34 -0
  314. package/dist/via/blob/binding.d.ts +86 -0
  315. package/dist/via/blob/index.d.ts +34 -0
  316. package/dist/via/classified/active.d.ts +3 -0
  317. package/dist/via/classified/binding.d.ts +83 -0
  318. package/dist/via/classified/config-drift.d.ts +34 -0
  319. package/dist/via/classified/descriptor.d.ts +66 -0
  320. package/dist/via/classified/errors.d.ts +19 -0
  321. package/dist/via/classified/guards.d.ts +23 -0
  322. package/dist/via/classified/index.d.ts +11 -0
  323. package/dist/via/classified/presets.d.ts +65 -0
  324. package/dist/via/classified/resolve.d.ts +9 -0
  325. package/dist/via/classified/strategy.d.ts +11 -0
  326. package/dist/via/classified/validators.d.ts +3 -0
  327. package/dist/via/classified/write.d.ts +4 -0
  328. package/dist/via/computed/binding.d.ts +34 -0
  329. package/dist/via/computed/descriptor.d.ts +35 -0
  330. package/dist/via/i18n/active.d.ts +28 -0
  331. package/dist/via/i18n/binding.d.ts +36 -0
  332. package/dist/via/i18n/core.d.ts +267 -0
  333. package/dist/via/i18n/densify.d.ts +24 -0
  334. package/dist/via/i18n/dictionary.d.ts +200 -0
  335. package/dist/via/i18n/index.d.ts +21 -0
  336. package/dist/via/i18n/policy.d.ts +44 -0
  337. package/dist/via/i18n/script.d.ts +26 -0
  338. package/dist/via/i18n/strategy.d.ts +13 -0
  339. package/dist/via/lookup/active.d.ts +19 -0
  340. package/dist/via/lookup/binding.d.ts +99 -0
  341. package/dist/via/lookup/descriptor.d.ts +123 -0
  342. package/dist/via/lookup/handle.d.ts +220 -0
  343. package/dist/via/lookup/index.d.ts +17 -0
  344. package/dist/via/lookup/registry.d.ts +228 -0
  345. package/dist/via/lookup/snapshot.d.ts +67 -0
  346. package/dist/via/money/arith.d.ts +68 -0
  347. package/dist/via/money/binding.d.ts +21 -0
  348. package/dist/via/money/branded.d.ts +61 -0
  349. package/dist/via/money/descriptor.d.ts +73 -0
  350. package/dist/via/money/fixed-point.d.ts +51 -0
  351. package/dist/via/money/index.d.ts +15 -0
  352. package/dist/via/money/iso4217.d.ts +6 -0
  353. package/dist/via/money/money-reducer.d.ts +33 -0
  354. package/dist/via/money/normalize.d.ts +105 -0
  355. package/dist/via/money/paths.d.ts +61 -0
  356. package/dist/via/money/where.d.ts +127 -0
  357. package/dist/walk-SVNDIZ62.js +241 -0
  358. package/dist/with/index.js +11 -11
  359. package/dist/with-audit/attestation/active.d.ts +10 -0
  360. package/dist/with-audit/attestation/index.d.ts +16 -0
  361. package/dist/with-audit/attestation/issue.d.ts +29 -0
  362. package/dist/with-audit/attestation/revoke.d.ts +15 -0
  363. package/dist/with-audit/attestation/signer.d.ts +33 -0
  364. package/dist/with-audit/attestation/strategy.d.ts +44 -0
  365. package/dist/with-audit/attestation/vault-facade.d.ts +62 -0
  366. package/dist/with-audit/consent/active.d.ts +14 -0
  367. package/dist/with-audit/consent/consent.d.ts +114 -0
  368. package/dist/with-audit/consent/index.d.ts +14 -0
  369. package/dist/with-audit/consent/strategy.d.ts +36 -0
  370. package/dist/with-audit/forget/active.d.ts +31 -0
  371. package/dist/with-audit/forget/index.d.ts +28 -0
  372. package/dist/with-audit/forget/purge-scope.d.ts +54 -0
  373. package/dist/with-audit/forget/strategy.d.ts +199 -0
  374. package/dist/with-audit/forget/subject-index.d.ts +83 -0
  375. package/dist/with-audit/guards/executor.d.ts +26 -0
  376. package/dist/with-audit/guards/immutable-guard.d.ts +63 -0
  377. package/dist/with-audit/guards/index.d.ts +10 -0
  378. package/dist/with-audit/guards/read-only-facade.d.ts +31 -0
  379. package/dist/with-audit/guards/registry.d.ts +83 -0
  380. package/dist/with-audit/guards/transition-guard.d.ts +82 -0
  381. package/dist/with-audit/guards/types.d.ts +134 -0
  382. package/dist/with-audit/guards/with-guard.d.ts +15 -0
  383. package/dist/with-audit/periods/active.d.ts +11 -0
  384. package/dist/with-audit/periods/index.d.ts +18 -0
  385. package/dist/with-audit/periods/periods.d.ts +417 -0
  386. package/dist/with-audit/periods/strategy.d.ts +32 -0
  387. package/dist/with-audit/periods/vault-facade.d.ts +95 -0
  388. package/dist/with-audit/portability/active.d.ts +11 -0
  389. package/dist/with-audit/portability/export-accessible.d.ts +46 -0
  390. package/dist/with-audit/portability/index.d.ts +18 -0
  391. package/dist/with-audit/portability/request-withdrawal.d.ts +85 -0
  392. package/dist/with-audit/portability/strategy.d.ts +31 -0
  393. package/dist/with-audit/portability/withdraw-accessible.d.ts +82 -0
  394. package/dist/with-audit/sealed-record/active.d.ts +9 -0
  395. package/dist/with-audit/sealed-record/index.d.ts +55 -0
  396. package/dist/with-audit/sealed-record/strategy.d.ts +34 -0
  397. package/dist/with-audit/sealed-record/types.d.ts +27 -0
  398. package/dist/with-audit/tiers/active.d.ts +9 -0
  399. package/dist/with-audit/tiers/index.d.ts +394 -0
  400. package/dist/with-audit/tiers/strategy.d.ts +36 -0
  401. package/dist/with-cargo/active.d.ts +11 -0
  402. package/dist/with-cargo/adopt-partition.d.ts +81 -0
  403. package/dist/with-cargo/decrypt-partition.d.ts +19 -0
  404. package/dist/with-cargo/describe-extraction.d.ts +41 -0
  405. package/dist/with-cargo/extract-partition.d.ts +155 -0
  406. package/dist/with-cargo/index.d.ts +33 -0
  407. package/dist/with-cargo/strategy.d.ts +30 -0
  408. package/dist/with-cargo/vault-diff.d.ts +144 -0
  409. package/dist/with-cargo/walk-closure.d.ts +67 -0
  410. package/dist/with-commit/crdt/active.d.ts +25 -0
  411. package/dist/with-commit/crdt/crdt.d.ts +42 -0
  412. package/dist/with-commit/crdt/index.d.ts +16 -0
  413. package/dist/with-commit/crdt/strategy.d.ts +25 -0
  414. package/dist/with-commit/history/active.d.ts +40 -0
  415. package/dist/with-commit/history/diff.d.ts +23 -0
  416. package/dist/with-commit/history/history.d.ts +73 -0
  417. package/dist/with-commit/history/index.d.ts +30 -0
  418. package/dist/with-commit/history/ledger/constants.d.ts +37 -0
  419. package/dist/with-commit/history/ledger/entry.d.ts +195 -0
  420. package/dist/with-commit/history/ledger/hash.d.ts +30 -0
  421. package/dist/with-commit/history/ledger/index.d.ts +19 -0
  422. package/dist/with-commit/history/ledger/patch.d.ts +99 -0
  423. package/dist/with-commit/history/ledger/store.d.ts +356 -0
  424. package/dist/with-commit/history/strategy.d.ts +136 -0
  425. package/dist/with-commit/history/time-machine.d.ts +202 -0
  426. package/dist/with-commit/numbering/descriptor.d.ts +27 -0
  427. package/dist/with-commit/numbering/index.d.ts +69 -0
  428. package/dist/with-commit/sequence/active.d.ts +10 -0
  429. package/dist/with-commit/sequence/index.d.ts +150 -0
  430. package/dist/with-commit/sequence/strategy.d.ts +26 -0
  431. package/dist/with-commit/tx/active.d.ts +27 -0
  432. package/dist/with-commit/tx/dry-run.d.ts +29 -0
  433. package/dist/with-commit/tx/elevated-handle.d.ts +59 -0
  434. package/dist/with-commit/tx/index.d.ts +13 -0
  435. package/dist/with-commit/tx/invariants.d.ts +68 -0
  436. package/dist/with-commit/tx/strategy.d.ts +23 -0
  437. package/dist/with-commit/tx/transaction.d.ts +212 -0
  438. package/dist/with-fork/archive/engine.d.ts +71 -0
  439. package/dist/with-fork/archive/index.d.ts +23 -0
  440. package/dist/with-fork/shadow/active.d.ts +6 -0
  441. package/dist/with-fork/shadow/index.d.ts +14 -0
  442. package/dist/with-fork/shadow/strategy.d.ts +28 -0
  443. package/dist/with-fork/shadow/vault-frame.d.ts +93 -0
  444. package/dist/with-fork/snapshots/active.d.ts +20 -0
  445. package/dist/with-fork/snapshots/engine.d.ts +36 -0
  446. package/dist/with-fork/snapshots/index.d.ts +5 -0
  447. package/dist/with-fork/snapshots/noydb-facade.d.ts +64 -0
  448. package/dist/with-fork/snapshots/policy.d.ts +23 -0
  449. package/dist/with-fork/snapshots/scheduler.d.ts +34 -0
  450. package/dist/with-fork/snapshots/strategy.d.ts +48 -0
  451. package/dist/with-formula/computed/index.d.ts +48 -0
  452. package/dist/with-formula/computed/lazy.d.ts +13 -0
  453. package/dist/with-formula/derivations/executor.d.ts +61 -0
  454. package/dist/with-formula/derivations/fanout-sidecar.d.ts +75 -0
  455. package/dist/with-formula/derivations/index.d.ts +6 -0
  456. package/dist/with-formula/derivations/registry.d.ts +67 -0
  457. package/dist/with-formula/derivations/stale.d.ts +39 -0
  458. package/dist/with-formula/derivations/strategy-hash.d.ts +1 -0
  459. package/dist/with-formula/derivations/types.d.ts +248 -0
  460. package/dist/with-formula/derivations/with-derivation.d.ts +10 -0
  461. package/dist/with-formula/derivations/with-rollup.d.ts +34 -0
  462. package/dist/with-formula/materialized-views/dependency-analyzer.d.ts +58 -0
  463. package/dist/with-formula/materialized-views/executor.d.ts +80 -0
  464. package/dist/with-formula/materialized-views/index.d.ts +11 -0
  465. package/dist/with-formula/materialized-views/query-hash.d.ts +23 -0
  466. package/dist/with-formula/materialized-views/registry.d.ts +99 -0
  467. package/dist/with-formula/materialized-views/stale.d.ts +113 -0
  468. package/dist/with-formula/materialized-views/types.d.ts +318 -0
  469. package/dist/with-formula/materialized-views/with-materialized-view.d.ts +24 -0
  470. package/dist/with-formula/overlay-views/index.d.ts +5 -0
  471. package/dist/with-formula/overlay-views/registry.d.ts +42 -0
  472. package/dist/with-formula/overlay-views/types.d.ts +97 -0
  473. package/dist/with-formula/overlay-views/virtual-collection.d.ts +90 -0
  474. package/dist/with-formula/overlay-views/with-overlayed-view.d.ts +9 -0
  475. package/dist/with-lookup/aggregate/active.d.ts +33 -0
  476. package/dist/with-lookup/aggregate/aggregation.d.ts +166 -0
  477. package/dist/with-lookup/aggregate/canonical-key.d.ts +16 -0
  478. package/dist/with-lookup/aggregate/groupby.d.ts +280 -0
  479. package/dist/with-lookup/aggregate/index.d.ts +23 -0
  480. package/dist/with-lookup/aggregate/reducers.d.ts +257 -0
  481. package/dist/with-lookup/aggregate/strategy.d.ts +59 -0
  482. package/dist/with-lookup/embeddings/cosine.d.ts +2 -0
  483. package/dist/with-lookup/embeddings/descriptor.d.ts +8 -0
  484. package/dist/with-lookup/embeddings/index.d.ts +4 -0
  485. package/dist/with-lookup/embeddings/vec-id.d.ts +47 -0
  486. package/dist/with-lookup/embeddings/vector-set.d.ts +19 -0
  487. package/dist/with-lookup/indexing/active.d.ts +30 -0
  488. package/dist/with-lookup/indexing/collection-facade.d.ts +157 -0
  489. package/dist/with-lookup/indexing/eager-indexes.d.ts +122 -0
  490. package/dist/with-lookup/indexing/index.d.ts +27 -0
  491. package/dist/with-lookup/indexing/lazy-builder.d.ts +102 -0
  492. package/dist/with-lookup/indexing/persisted-indexes.d.ts +229 -0
  493. package/dist/with-lookup/indexing/strategy.d.ts +56 -0
  494. package/dist/with-lookup/indexing/unique-constraints.d.ts +74 -0
  495. package/dist/with-lookup/search/active.d.ts +10 -0
  496. package/dist/with-lookup/search/build-docs.d.ts +15 -0
  497. package/dist/with-lookup/search/collection-facade.d.ts +163 -0
  498. package/dist/with-lookup/search/fuse.d.ts +22 -0
  499. package/dist/with-lookup/search/index-store.d.ts +19 -0
  500. package/dist/with-lookup/search/index.d.ts +19 -0
  501. package/dist/with-lookup/search/inverted-index.d.ts +47 -0
  502. package/dist/with-lookup/search/persisted-index-store.d.ts +121 -0
  503. package/dist/with-lookup/search/retrieve-types.d.ts +29 -0
  504. package/dist/with-lookup/search/scan.d.ts +28 -0
  505. package/dist/with-lookup/search/segment.d.ts +15 -0
  506. package/dist/with-lookup/search/serialize.d.ts +4 -0
  507. package/dist/with-lookup/search/snippet.d.ts +5 -0
  508. package/dist/with-lookup/search/strategy.d.ts +41 -0
  509. package/dist/with-lookup/search/tokenize.d.ts +12 -0
  510. package/dist/with-party/auth-introspection/index.d.ts +44 -0
  511. package/dist/with-party/broker/active.d.ts +23 -0
  512. package/dist/with-party/broker/index.d.ts +28 -0
  513. package/dist/with-party/broker/seed.d.ts +77 -0
  514. package/dist/with-party/custody/active.d.ts +10 -0
  515. package/dist/with-party/custody/index.d.ts +69 -0
  516. package/dist/with-party/custody/liberate.d.ts +64 -0
  517. package/dist/with-party/custody/strategy.d.ts +48 -0
  518. package/dist/with-party/directory/index.d.ts +11 -0
  519. package/dist/with-party/directory/public-envelope/index.d.ts +12 -0
  520. package/dist/with-party/directory/public-envelope/schema.d.ts +24 -0
  521. package/dist/with-party/directory/public-envelope/storage.d.ts +59 -0
  522. package/dist/with-party/directory/public-envelope/types.d.ts +80 -0
  523. package/dist/with-party/directory/storage.d.ts +33 -0
  524. package/dist/with-party/directory/types.d.ts +43 -0
  525. package/dist/with-party/directory/user-envelope/api.d.ts +201 -0
  526. package/dist/with-party/directory/user-envelope/index.d.ts +12 -0
  527. package/dist/with-party/directory/user-envelope/storage.d.ts +54 -0
  528. package/dist/with-party/directory/visibility.d.ts +47 -0
  529. package/dist/with-party/policy/engine.d.ts +60 -0
  530. package/dist/with-party/policy/index.d.ts +15 -0
  531. package/dist/with-party/policy/noydb-facade.d.ts +39 -0
  532. package/dist/with-party/policy/presets.d.ts +38 -0
  533. package/dist/with-party/policy/storage.d.ts +31 -0
  534. package/dist/with-party/session/active.d.ts +34 -0
  535. package/dist/with-party/session/dev-unlock.d.ts +128 -0
  536. package/dist/with-party/session/index.d.ts +23 -0
  537. package/dist/with-party/session/session-policy.d.ts +92 -0
  538. package/dist/with-party/session/session.d.ts +131 -0
  539. package/dist/with-party/session/strategy.d.ts +42 -0
  540. package/dist/with-party/session/unlock-state.d.ts +47 -0
  541. package/dist/with-party/sync/index.d.ts +31 -0
  542. package/dist/with-party/tab-coordination.d.ts +73 -0
  543. package/dist/with-party/tab-write-relay.d.ts +39 -0
  544. package/dist/with-party/team/active.d.ts +13 -0
  545. package/dist/with-party/team/authenticators.d.ts +95 -0
  546. package/dist/with-party/team/deed.d.ts +97 -0
  547. package/dist/with-party/team/delegation.d.ts +88 -0
  548. package/dist/with-party/team/index.d.ts +38 -0
  549. package/dist/with-party/team/keyring.d.ts +318 -0
  550. package/dist/with-party/team/magic-link-grant.d.ts +152 -0
  551. package/dist/with-party/team/managed-passphrase.d.ts +280 -0
  552. package/dist/with-party/team/noydb-facade.d.ts +484 -0
  553. package/dist/with-party/team/peer-recover.d.ts +81 -0
  554. package/dist/with-party/team/presence.d.ts +81 -0
  555. package/dist/with-party/team/recovery.d.ts +191 -0
  556. package/dist/with-party/team/reserved-secret-collections.d.ts +41 -0
  557. package/dist/with-party/team/rotate-recover.d.ts +275 -0
  558. package/dist/with-party/team/shamir-recovery-provider.d.ts +15 -0
  559. package/dist/with-party/team/strategy.d.ts +9 -0
  560. package/dist/with-party/team/sync-active.d.ts +33 -0
  561. package/dist/with-party/team/sync-credentials.d.ts +113 -0
  562. package/dist/with-party/team/sync-strategy.d.ts +67 -0
  563. package/dist/with-party/team/sync-transaction.d.ts +39 -0
  564. package/dist/with-party/team/sync.d.ts +174 -0
  565. package/dist/with-party/team/tiers.d.ts +39 -0
  566. package/dist/with-party/team/wrapped-deks.d.ts +86 -0
  567. package/dist/with-pod/backup.d.ts +74 -0
  568. package/dist/with-pod/bundle.d.ts +414 -0
  569. package/dist/with-pod/format.d.ts +203 -0
  570. package/dist/with-pod/index.d.ts +20 -0
  571. package/dist/with-pod/pod-store.d.ts +54 -0
  572. package/dist/with-pod/ulid.d.ts +64 -0
  573. package/dist/with-shape/blobs/blob-compaction.d.ts +170 -0
  574. package/dist/with-shape/blobs/blob-intent.d.ts +153 -0
  575. package/dist/with-shape/blobs/blob-set.d.ts +1286 -0
  576. package/dist/with-shape/blobs/export-blobs.d.ts +110 -0
  577. package/dist/with-shape/blobs/import-external.d.ts +50 -0
  578. package/dist/with-shape/blobs/mime-magic.d.ts +48 -0
  579. package/dist/with-shape/blobs/object-projection.d.ts +70 -0
  580. package/dist/with-shape/introspection/describe.d.ts +237 -0
  581. package/dist/with-shape/introspection/field-meta.d.ts +61 -0
  582. package/dist/with-shape/introspection/fields.d.ts +14 -0
  583. package/dist/with-shape/introspection/index.d.ts +12 -0
  584. package/dist/with-shape/introspection/json-schema.d.ts +13 -0
  585. package/dist/with-shape/introspection/meta.d.ts +22 -0
  586. package/dist/with-shape/introspection/projection.d.ts +13 -0
  587. package/dist/with-shape/introspection/types.d.ts +154 -0
  588. package/dist/with-shape/introspection/walk.d.ts +50 -0
  589. package/dist/with-shape/links/lazy-handle.d.ts +36 -0
  590. package/dist/with-shape/links/link-set.d.ts +67 -0
  591. package/dist/with-shape/links/names.d.ts +65 -0
  592. package/dist/with-shape/links/vault-facade.d.ts +211 -0
  593. package/dist/with-shape/persisted-schemas/canonicalize.d.ts +11 -0
  594. package/dist/with-shape/persisted-schemas/derive.d.ts +29 -0
  595. package/dist/with-shape/persisted-schemas/index.d.ts +21 -0
  596. package/dist/with-shape/persisted-schemas/register.d.ts +66 -0
  597. package/dist/with-shape/persisted-schemas/storage.d.ts +61 -0
  598. package/dist/with-shape/persisted-schemas/types.d.ts +54 -0
  599. package/dist/with-shape/satellites/dead-filter.d.ts +21 -0
  600. package/dist/with-shape/satellites/declare.d.ts +60 -0
  601. package/dist/with-shape/satellites/existence.d.ts +5 -0
  602. package/dist/with-shape/satellites/fanout.d.ts +38 -0
  603. package/dist/with-shape/satellites/forget.d.ts +47 -0
  604. package/dist/with-shape/satellites/index.d.ts +3 -0
  605. package/dist/with-shape/satellites/joined.d.ts +19 -0
  606. package/dist/with-shape/satellites/marker.d.ts +10 -0
  607. package/dist/with-shape/satellites/migrate-cek.d.ts +26 -0
  608. package/dist/with-shape/satellites/post-register.d.ts +6 -0
  609. package/dist/with-shape/satellites/proxy.d.ts +37 -0
  610. package/dist/with-shape/satellites/raw-target.d.ts +14 -0
  611. package/dist/with-shape/satellites/registry.d.ts +19 -0
  612. package/dist/with-shape/satellites/types.d.ts +37 -0
  613. package/dist/with-shape/satellites/validate.d.ts +17 -0
  614. package/dist/with-shape/schema-update/client-registry.d.ts +35 -0
  615. package/dist/with-shape/schema-update/cutover.d.ts +5 -0
  616. package/dist/with-shape/schema-update/delta.d.ts +2 -0
  617. package/dist/with-shape/schema-update/dispatch.d.ts +3 -0
  618. package/dist/with-shape/schema-update/fence-controller.d.ts +62 -0
  619. package/dist/with-shape/schema-update/fence-watcher.d.ts +37 -0
  620. package/dist/with-shape/schema-update/fence.d.ts +15 -0
  621. package/dist/with-shape/schema-update/gate.d.ts +16 -0
  622. package/dist/with-shape/schema-update/index.d.ts +6 -0
  623. package/dist/with-shape/schema-update/store-coordination-provider.d.ts +29 -0
  624. package/dist/with-shape/schema-update/strategies.d.ts +12 -0
  625. package/dist/with-shape/schema-update/types.d.ts +53 -0
  626. package/dist/with-store/index.d.ts +15 -0
  627. package/dist/with-store/lazy/active.d.ts +12 -0
  628. package/dist/with-store/lazy/index.d.ts +14 -0
  629. package/dist/with-store/lazy/strategy.d.ts +9 -0
  630. package/dist/with-store/route-store.d.ts +259 -0
  631. package/dist/with-store/store-middleware.d.ts +189 -0
  632. package/dist/withdraw-accessible-WZIEVWSR.js +28 -0
  633. package/package.json +47 -55
  634. package/dist/adapter/index.d.ts +0 -5
  635. package/dist/adapter/index.js +0 -15
  636. package/dist/aggregate/index.d.ts +0 -42
  637. package/dist/api-JDWL67WL.js +0 -20
  638. package/dist/as/index.d.ts +0 -7
  639. package/dist/at/index.d.ts +0 -5
  640. package/dist/attestation/index.d.ts +0 -20
  641. package/dist/backup-WRGNTGJF.js +0 -225
  642. package/dist/backup-WRGNTGJF.js.map +0 -1
  643. package/dist/blobs/index.d.ts +0 -44
  644. package/dist/bundle/index.d.ts +0 -122
  645. package/dist/bundle-DzWtVw7w.d.ts +0 -548
  646. package/dist/by/index.d.ts +0 -1
  647. package/dist/cargo/index.d.ts +0 -9
  648. package/dist/chunk-25G7PUTA.js +0 -235
  649. package/dist/chunk-26FSVNBL.js +0 -34
  650. package/dist/chunk-2PJB6H3H.js +0 -167
  651. package/dist/chunk-2PJB6H3H.js.map +0 -1
  652. package/dist/chunk-37JZR7CY.js +0 -91
  653. package/dist/chunk-3KBK5LU4.js +0 -117
  654. package/dist/chunk-3YKBGS3I.js +0 -686
  655. package/dist/chunk-3YKBGS3I.js.map +0 -1
  656. package/dist/chunk-44DV37ZV.js +0 -75
  657. package/dist/chunk-44DV37ZV.js.map +0 -1
  658. package/dist/chunk-47C4CI7R.js +0 -108
  659. package/dist/chunk-47C4CI7R.js.map +0 -1
  660. package/dist/chunk-4VDFUBTS.js +0 -275
  661. package/dist/chunk-4VDFUBTS.js.map +0 -1
  662. package/dist/chunk-55LSDABW.js +0 -94
  663. package/dist/chunk-56JB2BGI.js +0 -13003
  664. package/dist/chunk-56JB2BGI.js.map +0 -1
  665. package/dist/chunk-5GQE5IDB.js +0 -513
  666. package/dist/chunk-5GQE5IDB.js.map +0 -1
  667. package/dist/chunk-5HRJQSKN.js +0 -202
  668. package/dist/chunk-5HZULLHE.js +0 -404
  669. package/dist/chunk-5JQMX2EH.js +0 -50
  670. package/dist/chunk-5UOPIPZC.js +0 -95
  671. package/dist/chunk-5YBUFCFF.js +0 -135
  672. package/dist/chunk-62APEMF3.js +0 -280
  673. package/dist/chunk-62APEMF3.js.map +0 -1
  674. package/dist/chunk-6P5AJ2ZS.js +0 -120
  675. package/dist/chunk-6P5AJ2ZS.js.map +0 -1
  676. package/dist/chunk-6PALJTC2.js +0 -430
  677. package/dist/chunk-6PALJTC2.js.map +0 -1
  678. package/dist/chunk-6S7T6WC4.js +0 -111
  679. package/dist/chunk-6S7T6WC4.js.map +0 -1
  680. package/dist/chunk-6Z435B6N.js +0 -1656
  681. package/dist/chunk-6Z435B6N.js.map +0 -1
  682. package/dist/chunk-723XB5NX.js +0 -86
  683. package/dist/chunk-7CZ6YXMO.js +0 -124
  684. package/dist/chunk-7KTL4RHZ.js +0 -120
  685. package/dist/chunk-7KTL4RHZ.js.map +0 -1
  686. package/dist/chunk-7TAV3BFQ.js +0 -766
  687. package/dist/chunk-7TAV3BFQ.js.map +0 -1
  688. package/dist/chunk-BASCPHNM.js +0 -380
  689. package/dist/chunk-BASCPHNM.js.map +0 -1
  690. package/dist/chunk-BGIZAFY7.js +0 -1
  691. package/dist/chunk-BJ2XF2RC.js +0 -823
  692. package/dist/chunk-BM6E4MUT.js +0 -881
  693. package/dist/chunk-BM6E4MUT.js.map +0 -1
  694. package/dist/chunk-BTFTHF6Q.js +0 -42
  695. package/dist/chunk-C4NOLA5X.js +0 -132
  696. package/dist/chunk-C4NOLA5X.js.map +0 -1
  697. package/dist/chunk-CHK5VVMI.js +0 -155
  698. package/dist/chunk-DCVVCJVB.js +0 -45
  699. package/dist/chunk-EU7HDMT3.js +0 -54
  700. package/dist/chunk-F3EKFGUS.js +0 -99
  701. package/dist/chunk-FCOZ7DEC.js +0 -355
  702. package/dist/chunk-FCOZ7DEC.js.map +0 -1
  703. package/dist/chunk-FWART3VA.js +0 -205
  704. package/dist/chunk-FZK3JJJK.js +0 -150
  705. package/dist/chunk-GDOOG5YQ.js +0 -382
  706. package/dist/chunk-GLVXQU3E.js +0 -155
  707. package/dist/chunk-HU55NPHZ.js +0 -80
  708. package/dist/chunk-I6JJ6VJS.js +0 -97
  709. package/dist/chunk-I6URUNTD.js +0 -59
  710. package/dist/chunk-IARAK3PK.js +0 -14
  711. package/dist/chunk-II6DLDZM.js +0 -30
  712. package/dist/chunk-J5YUA6JB.js +0 -23
  713. package/dist/chunk-J7OH6R4K.js +0 -49
  714. package/dist/chunk-K2WCO3NX.js +0 -1
  715. package/dist/chunk-L6Q5NA22.js +0 -40
  716. package/dist/chunk-LFGJG4XZ.js +0 -30
  717. package/dist/chunk-M3OYTM5Z.js +0 -85
  718. package/dist/chunk-MOQ5M46U.js +0 -209
  719. package/dist/chunk-NTPWQH4S.js +0 -589
  720. package/dist/chunk-OJ64XMPJ.js +0 -1434
  721. package/dist/chunk-OJ64XMPJ.js.map +0 -1
  722. package/dist/chunk-OWGAXPRE.js +0 -129
  723. package/dist/chunk-P2PEPSPK.js +0 -230
  724. package/dist/chunk-P6TZ3IVN.js +0 -453
  725. package/dist/chunk-P6TZ3IVN.js.map +0 -1
  726. package/dist/chunk-PAJCRV7O.js +0 -123
  727. package/dist/chunk-PMMV5SQC.js +0 -416
  728. package/dist/chunk-PMMV5SQC.js.map +0 -1
  729. package/dist/chunk-PPPZIBKY.js +0 -261
  730. package/dist/chunk-PPPZIBKY.js.map +0 -1
  731. package/dist/chunk-PVC2FBCQ.js +0 -45
  732. package/dist/chunk-PYIUDUGS.js +0 -36
  733. package/dist/chunk-QABECTNN.js +0 -255
  734. package/dist/chunk-QYMMMKOO.js +0 -164
  735. package/dist/chunk-R4IVPJHN.js +0 -130
  736. package/dist/chunk-REWTMYSF.js +0 -32
  737. package/dist/chunk-REWTMYSF.js.map +0 -1
  738. package/dist/chunk-RNYDHIQL.js +0 -367
  739. package/dist/chunk-RUIMKQTA.js +0 -23
  740. package/dist/chunk-RUIMKQTA.js.map +0 -1
  741. package/dist/chunk-TCGVRKOS.js +0 -367
  742. package/dist/chunk-TIAYXOEI.js +0 -99
  743. package/dist/chunk-TQ3REHVF.js +0 -95
  744. package/dist/chunk-TQ3REHVF.js.map +0 -1
  745. package/dist/chunk-TUL5YQWF.js +0 -777
  746. package/dist/chunk-U7LV2DUN.js +0 -74
  747. package/dist/chunk-UB3XHGFG.js +0 -181
  748. package/dist/chunk-UB3XHGFG.js.map +0 -1
  749. package/dist/chunk-UMH35AQV.js +0 -70
  750. package/dist/chunk-UWZ7O4NR.js +0 -29
  751. package/dist/chunk-V76PHWLE.js +0 -41
  752. package/dist/chunk-VFQOE76I.js +0 -69
  753. package/dist/chunk-VIWOGJ2O.js +0 -71
  754. package/dist/chunk-VK6OC22R.js +0 -37
  755. package/dist/chunk-VK6OC22R.js.map +0 -1
  756. package/dist/chunk-VVLOWY74.js +0 -150
  757. package/dist/chunk-VVLOWY74.js.map +0 -1
  758. package/dist/chunk-W3JABOVB.js +0 -53
  759. package/dist/chunk-W3JABOVB.js.map +0 -1
  760. package/dist/chunk-WPNP3NF5.js +0 -1221
  761. package/dist/chunk-WPNP3NF5.js.map +0 -1
  762. package/dist/chunk-X5QZAJDB.js +0 -59
  763. package/dist/chunk-X6VNIRHS.js +0 -239
  764. package/dist/chunk-X6VNIRHS.js.map +0 -1
  765. package/dist/chunk-XBPUVQDO.js +0 -664
  766. package/dist/chunk-XBPUVQDO.js.map +0 -1
  767. package/dist/chunk-XW5LZYV4.js +0 -21
  768. package/dist/chunk-YTCCC6NG.js +0 -320
  769. package/dist/chunk-YTCCC6NG.js.map +0 -1
  770. package/dist/classified/index.d.ts +0 -17
  771. package/dist/collection-facade-EJVIN2BY.js +0 -39
  772. package/dist/computed-6FOFXQPE.js +0 -11
  773. package/dist/config-drift-RFEVGBKR.js +0 -24
  774. package/dist/config-drift-RFEVGBKR.js.map +0 -1
  775. package/dist/consent/index.d.ts +0 -23
  776. package/dist/crdt/index.d.ts +0 -34
  777. package/dist/dead-filter-RHMNYOXP.js +0 -28
  778. package/dist/decrypt-partition-IHtxEnTi.d.ts +0 -21
  779. package/dist/delegation-IHXOASHV.js +0 -25
  780. package/dist/derivations/index.d.ts +0 -70
  781. package/dist/derive-CD3ZVIXK.js +0 -21
  782. package/dist/describe/index.d.ts +0 -1
  783. package/dist/describe/index.js +0 -1
  784. package/dist/describe-C6iHNlqJ.d.ts +0 -162
  785. package/dist/dev-unlock-wgQ7Ci5I.d.ts +0 -263
  786. package/dist/discriminant-BN9REW3o.d.ts +0 -60
  787. package/dist/enclave-KGEUW2GL.js +0 -123
  788. package/dist/executor-EUPYHCLU.js +0 -9
  789. package/dist/executor-KZ4B3PRT.js +0 -9
  790. package/dist/executor-MHUM2VZK.js +0 -21
  791. package/dist/export-accessible-Z3NSZZHN.js +0 -23
  792. package/dist/extract-partition-VSKT35JG.js +0 -36
  793. package/dist/fanout-sidecar-NBDKKCHT.js +0 -74
  794. package/dist/find-OH4BEULF.js +0 -11
  795. package/dist/forget/index.d.ts +0 -36
  796. package/dist/guards/index.d.ts +0 -35
  797. package/dist/hash-CwHnoKyW.d.ts +0 -72
  798. package/dist/history/index.d.ts +0 -61
  799. package/dist/i18n/index.d.ts +0 -37
  800. package/dist/in/index.d.ts +0 -5
  801. package/dist/index-B9QdHytu.d.ts +0 -123
  802. package/dist/index-CTvUp94-.d.ts +0 -123
  803. package/dist/index-Dn5GzPg_.d.ts +0 -22138
  804. package/dist/indexing/index.d.ts +0 -39
  805. package/dist/issue-AEOL6RXA.js +0 -19
  806. package/dist/kernel/index.d.ts +0 -32
  807. package/dist/kernel/index.js +0 -59
  808. package/dist/lazy/index.d.ts +0 -21
  809. package/dist/ledger-3LR3YO2W.js +0 -42
  810. package/dist/liberate-XSEPRWEA.js +0 -24
  811. package/dist/link-set-NSUIX6BR.js +0 -31
  812. package/dist/materialized-views/index.d.ts +0 -173
  813. package/dist/mime-magic-CYbFNQ4h.d.ts +0 -103
  814. package/dist/noydb-POVTIVQ6.js +0 -62
  815. package/dist/on/index.d.ts +0 -5
  816. package/dist/overlay-views/index.d.ts +0 -98
  817. package/dist/periods/index.d.ts +0 -20
  818. package/dist/pod/index.d.ts +0 -63
  819. package/dist/policy-Y7HL2KGA.js +0 -41
  820. package/dist/portability/index.d.ts +0 -20
  821. package/dist/post-register-KOFRTCDD.js +0 -55
  822. package/dist/post-register-KOFRTCDD.js.map +0 -1
  823. package/dist/public-envelope-NC7SPNMV.js +0 -32
  824. package/dist/query/index.d.ts +0 -5
  825. package/dist/read-only-facade-5ADRJVTM.js +0 -8
  826. package/dist/register-3D6R2MKN.js +0 -23
  827. package/dist/registry-AI4E46PD.js +0 -19
  828. package/dist/registry-HSNQ4NBP.js +0 -9
  829. package/dist/registry-WIX6QCV5.js +0 -17
  830. package/dist/request-withdrawal-GU4XS2R5.js +0 -31
  831. package/dist/reveal-5Y777N5Q.js +0 -38
  832. package/dist/reveal-5Y777N5Q.js.map +0 -1
  833. package/dist/revoke-ZFETCLYV.js +0 -24
  834. package/dist/revoke-ZFETCLYV.js.map +0 -1
  835. package/dist/satellites/index.d.ts +0 -5
  836. package/dist/sealed-record/index.d.ts +0 -69
  837. package/dist/session/index.d.ts +0 -44
  838. package/dist/shadow/index.d.ts +0 -15
  839. package/dist/signer-GAIMQQ2J.js +0 -25
  840. package/dist/signer-GAIMQQ2J.js.map +0 -1
  841. package/dist/snapshots/index.d.ts +0 -26
  842. package/dist/stale-77LP2EEF.js +0 -14
  843. package/dist/stale-77LP2EEF.js.map +0 -1
  844. package/dist/storage-KEXIXLGM.js +0 -23
  845. package/dist/storage-KEXIXLGM.js.map +0 -1
  846. package/dist/store-coordination-provider-NJDDZ264.js +0 -142
  847. package/dist/subject-index-O75wKshW.d.ts +0 -362
  848. package/dist/sync/index.d.ts +0 -41
  849. package/dist/team/index.d.ts +0 -155
  850. package/dist/tiers/index.d.ts +0 -5
  851. package/dist/to/index.d.ts +0 -5
  852. package/dist/transition-guard-D5RLJv8S.d.ts +0 -165
  853. package/dist/tx/index.d.ts +0 -35
  854. package/dist/ui/index.d.ts +0 -1
  855. package/dist/ulid-DRH25k3y.d.ts +0 -66
  856. package/dist/util/index.d.ts +0 -79
  857. package/dist/validators-C3lrVF-c.d.ts +0 -101
  858. package/dist/vault-diff-_LSIcOMv.d.ts +0 -147
  859. package/dist/verify-CAYGXYNO.js +0 -139
  860. package/dist/verify-CAYGXYNO.js.map +0 -1
  861. package/dist/walk-SMAE4IEI.js +0 -241
  862. package/dist/with/index.d.ts +0 -38
  863. package/dist/with-materialized-view-Xv1-9Bh0.d.ts +0 -27
  864. package/dist/with-overlayed-view-CuWhq_-C.d.ts +0 -12
  865. package/dist/with-rollup-K_iwal4b.d.ts +0 -47
  866. package/dist/withdraw-accessible-Q7BULAN5.js +0 -28
  867. package/dist/withdraw-accessible-Q7BULAN5.js.map +0 -1
  868. /package/dist/{adapter/index.js.map → api-ZGS6LCOF.js.map} +0 -0
  869. /package/dist/{chunk-VIWOGJ2O.js.map → chunk-3B5VVCNY.js.map} +0 -0
  870. /package/dist/{chunk-P2PEPSPK.js.map → chunk-3LQ2YKO4.js.map} +0 -0
  871. /package/dist/{chunk-EU7HDMT3.js.map → chunk-3QCRBHCY.js.map} +0 -0
  872. /package/dist/{chunk-FZK3JJJK.js.map → chunk-4JBYV75E.js.map} +0 -0
  873. /package/dist/{chunk-I6JJ6VJS.js.map → chunk-4NXKCLLQ.js.map} +0 -0
  874. /package/dist/{chunk-VFQOE76I.js.map → chunk-5M5DVGV7.js.map} +0 -0
  875. /package/dist/{chunk-LFGJG4XZ.js.map → chunk-5YOLBEQ6.js.map} +0 -0
  876. /package/dist/{chunk-OWGAXPRE.js.map → chunk-6CRIV7DE.js.map} +0 -0
  877. /package/dist/{chunk-QABECTNN.js.map → chunk-6QTNZJBS.js.map} +0 -0
  878. /package/dist/{chunk-723XB5NX.js.map → chunk-6T2SCQRU.js.map} +0 -0
  879. /package/dist/{chunk-PVC2FBCQ.js.map → chunk-7DSTRQIJ.js.map} +0 -0
  880. /package/dist/{chunk-NTPWQH4S.js.map → chunk-AUSTCW2X.js.map} +0 -0
  881. /package/dist/{chunk-MOQ5M46U.js.map → chunk-B3HJYUOF.js.map} +0 -0
  882. /package/dist/{chunk-QYMMMKOO.js.map → chunk-BDVFPG6Y.js.map} +0 -0
  883. /package/dist/{chunk-PYIUDUGS.js.map → chunk-CAF6WOK7.js.map} +0 -0
  884. /package/dist/{chunk-5HZULLHE.js.map → chunk-CIE2BASH.js.map} +0 -0
  885. /package/dist/{chunk-BTFTHF6Q.js.map → chunk-CRI4OUV4.js.map} +0 -0
  886. /package/dist/{chunk-37JZR7CY.js.map → chunk-DLG74CNB.js.map} +0 -0
  887. /package/dist/{chunk-TCGVRKOS.js.map → chunk-ERJ7FU55.js.map} +0 -0
  888. /package/dist/{chunk-FWART3VA.js.map → chunk-EVVGJDRQ.js.map} +0 -0
  889. /package/dist/{chunk-X5QZAJDB.js.map → chunk-EXK7QRWF.js.map} +0 -0
  890. /package/dist/{chunk-5HRJQSKN.js.map → chunk-EYZ6IQ6X.js.map} +0 -0
  891. /package/dist/{chunk-DCVVCJVB.js.map → chunk-F64IRYG3.js.map} +0 -0
  892. /package/dist/{chunk-BJ2XF2RC.js.map → chunk-FHS2HQSH.js.map} +0 -0
  893. /package/dist/{chunk-HU55NPHZ.js.map → chunk-GKEWXIV5.js.map} +0 -0
  894. /package/dist/{chunk-I6URUNTD.js.map → chunk-GTGPO5KW.js.map} +0 -0
  895. /package/dist/{chunk-5UOPIPZC.js.map → chunk-HB3RFQSC.js.map} +0 -0
  896. /package/dist/{chunk-F3EKFGUS.js.map → chunk-I6GALP6E.js.map} +0 -0
  897. /package/dist/{chunk-R4IVPJHN.js.map → chunk-IL6POWCW.js.map} +0 -0
  898. /package/dist/{chunk-3KBK5LU4.js.map → chunk-IU6SNYX6.js.map} +0 -0
  899. /package/dist/{chunk-TUL5YQWF.js.map → chunk-J2ZX2XUV.js.map} +0 -0
  900. /package/dist/{chunk-UWZ7O4NR.js.map → chunk-JKJOGPZN.js.map} +0 -0
  901. /package/dist/{chunk-V76PHWLE.js.map → chunk-JZUV47FZ.js.map} +0 -0
  902. /package/dist/{chunk-II6DLDZM.js.map → chunk-K5IMOGHB.js.map} +0 -0
  903. /package/dist/{chunk-GDOOG5YQ.js.map → chunk-LASZKVMO.js.map} +0 -0
  904. /package/dist/{chunk-5YBUFCFF.js.map → chunk-NR5LT5RY.js.map} +0 -0
  905. /package/dist/{chunk-UMH35AQV.js.map → chunk-Q5VNKNE5.js.map} +0 -0
  906. /package/dist/{chunk-XW5LZYV4.js.map → chunk-QLWMEXCT.js.map} +0 -0
  907. /package/dist/{chunk-PAJCRV7O.js.map → chunk-QRB7NAOJ.js.map} +0 -0
  908. /package/dist/{chunk-U7LV2DUN.js.map → chunk-R4ROFEYC.js.map} +0 -0
  909. /package/dist/{chunk-RNYDHIQL.js.map → chunk-RIX4V2TB.js.map} +0 -0
  910. /package/dist/{chunk-L6Q5NA22.js.map → chunk-RYCTDFUX.js.map} +0 -0
  911. /package/dist/{chunk-CHK5VVMI.js.map → chunk-RZ5SVOYR.js.map} +0 -0
  912. /package/dist/{chunk-TIAYXOEI.js.map → chunk-SLFHQTTW.js.map} +0 -0
  913. /package/dist/{chunk-J5YUA6JB.js.map → chunk-UNFPPVNI.js.map} +0 -0
  914. /package/dist/{chunk-25G7PUTA.js.map → chunk-VLFCJYTL.js.map} +0 -0
  915. /package/dist/{chunk-7CZ6YXMO.js.map → chunk-VN3DBQAU.js.map} +0 -0
  916. /package/dist/{chunk-J7OH6R4K.js.map → chunk-VZRODIM3.js.map} +0 -0
  917. /package/dist/{chunk-55LSDABW.js.map → chunk-W22IKJE2.js.map} +0 -0
  918. /package/dist/{chunk-GLVXQU3E.js.map → chunk-X3YYQWOQ.js.map} +0 -0
  919. /package/dist/{chunk-M3OYTM5Z.js.map → chunk-YFXZEAYK.js.map} +0 -0
  920. /package/dist/{chunk-5JQMX2EH.js.map → chunk-ZAJAVEXY.js.map} +0 -0
  921. /package/dist/{chunk-26FSVNBL.js.map → chunk-ZICD77GM.js.map} +0 -0
  922. /package/dist/{chunk-IARAK3PK.js.map → chunk-ZUODRVHY.js.map} +0 -0
  923. /package/dist/{api-JDWL67WL.js.map → collection-facade-TLWIPI76.js.map} +0 -0
  924. /package/dist/{chunk-BGIZAFY7.js.map → computed-ZIQTYTDI.js.map} +0 -0
  925. /package/dist/{dead-filter-RHMNYOXP.js.map → dead-filter-ESOBZZP5.js.map} +0 -0
  926. /package/dist/{chunk-K2WCO3NX.js.map → delegation-W7ZV2322.js.map} +0 -0
  927. /package/dist/{collection-facade-EJVIN2BY.js.map → derive-H2BJTLUI.js.map} +0 -0
  928. /package/dist/{computed-6FOFXQPE.js.map → enclave-AP3I5W7O.js.map} +0 -0
  929. /package/dist/{delegation-IHXOASHV.js.map → executor-KGWTNEQD.js.map} +0 -0
  930. /package/dist/{derive-CD3ZVIXK.js.map → executor-OVEXR6RT.js.map} +0 -0
  931. /package/dist/{describe/index.js.map → executor-UNEH5ZYH.js.map} +0 -0
  932. /package/dist/{enclave-KGEUW2GL.js.map → export-accessible-PCMXSUZS.js.map} +0 -0
  933. /package/dist/{executor-EUPYHCLU.js.map → extract-partition-SWHFSYJO.js.map} +0 -0
  934. /package/dist/{fanout-sidecar-NBDKKCHT.js.map → fanout-sidecar-A765THMX.js.map} +0 -0
  935. /package/dist/{executor-KZ4B3PRT.js.map → find-N6345CNT.js.map} +0 -0
  936. /package/dist/{executor-MHUM2VZK.js.map → issue-5OKB6I2R.js.map} +0 -0
  937. /package/dist/{export-accessible-Z3NSZZHN.js.map → ledger-GFBKVPV4.js.map} +0 -0
  938. /package/dist/{extract-partition-VSKT35JG.js.map → liberate-3VDOT4KO.js.map} +0 -0
  939. /package/dist/{find-OH4BEULF.js.map → link-set-Z7Q2ASFX.js.map} +0 -0
  940. /package/dist/{issue-AEOL6RXA.js.map → noydb-ZCJOYBDI.js.map} +0 -0
  941. /package/dist/{kernel/index.js.map → policy-Z3RUAIY2.js.map} +0 -0
  942. /package/dist/{ledger-3LR3YO2W.js.map → public-envelope-B4KNWVUA.js.map} +0 -0
  943. /package/dist/{liberate-XSEPRWEA.js.map → read-only-facade-CHCKSEPD.js.map} +0 -0
  944. /package/dist/{link-set-NSUIX6BR.js.map → register-VAHONCID.js.map} +0 -0
  945. /package/dist/{noydb-POVTIVQ6.js.map → registry-7MLVD3VO.js.map} +0 -0
  946. /package/dist/{policy-Y7HL2KGA.js.map → registry-EPKPD5SM.js.map} +0 -0
  947. /package/dist/{public-envelope-NC7SPNMV.js.map → registry-P5T7PS2U.js.map} +0 -0
  948. /package/dist/{read-only-facade-5ADRJVTM.js.map → request-withdrawal-TI3A5WPS.js.map} +0 -0
  949. /package/dist/{register-3D6R2MKN.js.map → revoke-FDRD6GRW.js.map} +0 -0
  950. /package/dist/{registry-AI4E46PD.js.map → signer-MUWEIUI6.js.map} +0 -0
  951. /package/dist/{registry-HSNQ4NBP.js.map → stale-OSQ7J3AA.js.map} +0 -0
  952. /package/dist/{registry-WIX6QCV5.js.map → storage-MVFCGEQE.js.map} +0 -0
  953. /package/dist/{store-coordination-provider-NJDDZ264.js.map → store-coordination-provider-64OEZFGS.js.map} +0 -0
  954. /package/dist/{walk-SMAE4IEI.js.map → walk-SVNDIZ62.js.map} +0 -0
  955. /package/dist/{request-withdrawal-GU4XS2R5.js.map → withdraw-accessible-WZIEVWSR.js.map} +0 -0
@@ -0,0 +1,3239 @@
1
+ /**
2
+ * Core types — the {@link NoydbStore} interface, envelope format, roles, and
3
+ * all configuration shapes consumed by {@link createNoydb}.
4
+ *
5
+ * ## What lives here
6
+ *
7
+ * - **{@link NoydbStore}** — the 6-method contract every backend must implement
8
+ * (`get`, `put`, `delete`, `list`, `loadAll`, `saveAll`).
9
+ * - **{@link EncryptedEnvelope}** — the wire format stored by backends:
10
+ * `{ _noydb, _v, _ts, _iv, _data }`. Backends only ever see this shape.
11
+ * - **{@link Role} / {@link Permission}** — the access-control vocabulary
12
+ * (`owner`, `admin`, `operator`, `viewer`, `client`).
13
+ * - **{@link NoydbOptions}** — the full configuration object passed to
14
+ * {@link createNoydb}.
15
+ *
16
+ * ## Extending the store interface
17
+ *
18
+ * All optional store capabilities (`ping`, `listPage`, `listSince`,
19
+ * `presencePublish`, `presenceSubscribe`, `listVaults`) are additive extensions
20
+ * discovered via `'method' in store`. Implementing them unlocks features but
21
+ * is never required — core always falls back to the 6-method baseline.
22
+ *
23
+ * @module
24
+ */
25
+ import type { StandardSchemaV1 } from './schema.js';
26
+ import type { DeferredNumberingConfig } from '../with-commit/numbering/descriptor.js';
27
+ import type { SyncPolicy } from './sync-policy.js';
28
+ import type { BlobStrategy } from '../port/with/blob-strategy.js';
29
+ import type { ArchiveStrategy } from '../with-fork/archive/index.js';
30
+ import type { IndexStrategy } from '../with-lookup/indexing/strategy.js';
31
+ import type { AggregateStrategy } from '../with-lookup/aggregate/strategy.js';
32
+ import type { ConsentStrategy } from '../with-audit/consent/strategy.js';
33
+ import type { PeriodsStrategy } from '../with-audit/periods/strategy.js';
34
+ import type { ShadowStrategy } from '../with-fork/shadow/strategy.js';
35
+ import type { TxStrategy } from '../with-commit/tx/strategy.js';
36
+ import type { HistoryStrategy } from '../with-commit/history/strategy.js';
37
+ import type { ForgetStrategy } from '../with-audit/forget/strategy.js';
38
+ import type { SnapshotStrategy } from '../with-fork/snapshots/strategy.js';
39
+ import type { DerivationSkippedFrozen } from './via/dispatch.js';
40
+ import type { AttestationStrategy } from '../with-audit/attestation/strategy.js';
41
+ import type { ClassifiedStrategy } from '../port/with/classified-strategy.js';
42
+ import type { TiersStrategy } from '../with-audit/tiers/strategy.js';
43
+ import type { SealedRecordStrategy } from '../with-audit/sealed-record/strategy.js';
44
+ import type { PortabilityStrategy } from '../with-audit/portability/strategy.js';
45
+ import type { SequenceStrategy } from '../with-commit/sequence/strategy.js';
46
+ import type { CustodyStrategy } from '../with-party/custody/strategy.js';
47
+ import type { TeamStrategy } from '../port/with/team-strategy.js';
48
+ import type { BrokerStrategy } from '../port/with/broker-strategy.js';
49
+ import type { LazyStrategy } from '../port/with/lazy-strategy.js';
50
+ import type { SearchStrategy } from '../with-lookup/search/strategy.js';
51
+ import type { CargoStrategy } from '../with-cargo/strategy.js';
52
+ import type { Layer, I18nStrategy } from '../port/with/i18n-strategy.js';
53
+ import type { SessionStrategy } from '../with-party/session/strategy.js';
54
+ import type { SyncStrategy } from '../with-party/team/sync-strategy.js';
55
+ import type { GuardStrategyHandleAny } from '../with-audit/guards/types.js';
56
+ import type { DerivationStrategyHandle } from '../with-formula/derivations/types.js';
57
+ import type { UnlockedKeyring } from '../with-party/team/keyring.js';
58
+ import type { PassphrasePolicy } from './validation.js';
59
+ import type { PublicEnvelopeSchema } from '../with-party/directory/public-envelope/types.js';
60
+ import type { MaterializedViewStrategyHandle } from '../with-formula/materialized-views/types.js';
61
+ import type { OverlayedViewStrategyHandle } from '../with-formula/overlay-views/types.js';
62
+ import type { SealingKeyProvider, RecipientHint } from '../with-party/team/managed-passphrase.js';
63
+ import type { ShamirRecoveryProvider } from '../with-party/team/shamir-recovery-provider.js';
64
+ import type { ObjectProjection } from '../with-shape/blobs/object-projection.js';
65
+ import type { CoordinationProvider } from '../port/by/types.js';
66
+ import type { ScriptWarning } from '../port/with/i18n-strategy.js';
67
+ import type { ViaDescriptor } from './via/index.js';
68
+ import type { EnclaveKey } from './enclave/index.js';
69
+ /** Format version for encrypted record envelopes. */
70
+ export declare const NOYDB_FORMAT_VERSION: 1;
71
+ /** Format version for keyring files. */
72
+ export declare const NOYDB_KEYRING_VERSION: 1;
73
+ /** Format version for backup files. */
74
+ export declare const NOYDB_BACKUP_VERSION: 1;
75
+ /** Format version for sync metadata. */
76
+ export declare const NOYDB_SYNC_VERSION: 1;
77
+ /**
78
+ * Access role assigned to a user within a vault.
79
+ *
80
+ * Roles control both the operations a user can perform and which DEKs
81
+ * they receive in their keyring:
82
+ *
83
+ * | Role | Collections | Can grant/revoke | Can export |
84
+ * |-------------|-----------------|:----------------:|:----------:|
85
+ * | `owner` | all (rw) | Yes (all roles) | Yes |
86
+ * | `admin` | all (rw) | Yes (≤ admin) | Yes |
87
+ * | `custodian` | all (rw) | No (see below) | Yes |
88
+ * | `operator` | explicit (rw) | No | ACL-scoped |
89
+ * | `viewer` | all (ro) | No | Yes |
90
+ * | `client` | explicit (ro) | No | ACL-scoped |
91
+ *
92
+ * **`custodian` (FR-6 sovereign custody).** Operationally admin-rank —
93
+ * rw + access on every collection, receives all collection DEKs on grant
94
+ * — but is *provably non-owning*: it CANNOT grant, revoke, rotate keys,
95
+ * destructively withdraw/sever, or extract-and-sever a partition (rotate is
96
+ * blocked in `rotateKeys`, sever in `withdrawAccessibleData`, and extract in
97
+ * `extractPartition`). Only the (sealed Deed) **owner** may
98
+ * mint or remove a custodian; an admin cannot. This is the inalienability
99
+ * floor — a custodian can run the vault day-to-day yet never escalate to
100
+ * the owner credential.
101
+ */
102
+ export type Role = 'owner' | 'admin' | 'custodian' | 'operator' | 'viewer' | 'client';
103
+ /**
104
+ * Read-write or read-only access on a collection.
105
+ * Stored per-collection in the user's keyring.
106
+ */
107
+ export type Permission = 'rw' | 'ro';
108
+ /**
109
+ * Map of collection name → permission level for a user's keyring entry.
110
+ * `'*'` is the wildcard collection matching all collections in the vault.
111
+ */
112
+ export type Permissions = Record<string, Permission>;
113
+ /** The encrypted wrapper stored by stores. Stores only ever see this. */
114
+ export interface EncryptedEnvelope {
115
+ readonly _noydb: typeof NOYDB_FORMAT_VERSION;
116
+ readonly _v: number;
117
+ readonly _ts: string;
118
+ readonly _iv: string;
119
+ readonly _data: string;
120
+ /** User who created this version (unencrypted metadata). */
121
+ readonly _by?: string;
122
+ /**
123
+ * Opaque provenance source id — which party/registry wrote this version.
124
+ * Unencrypted; present only when the collection opts into `provenance: true`
125
+ * and a `source` is supplied to `put()`. Off by default (zero cost).
126
+ */
127
+ readonly _source?: string;
128
+ /** ISO-8601 timestamp the provenance source was recorded. Present alongside `_source`. */
129
+ readonly _sourceTs?: string;
130
+ /**
131
+ * Hierarchical access tier. Omitted → tier 0.
132
+ *
133
+ * Unencrypted on purpose — the store reads it to route the envelope
134
+ * to the right DEK slot without having to try-decrypt against every
135
+ * tier. Only leaks the tier of each record, not any value
136
+ * equivalence.
137
+ */
138
+ readonly _tier?: number;
139
+ /**
140
+ * User id who last elevated this record. Used by
141
+ * `demote()` to gate the reverse operation: only the original
142
+ * elevator or an owner can demote a record back down. Cleared on
143
+ * every successful demote so a later re-elevate requires the new
144
+ * actor to own the demotion right.
145
+ */
146
+ readonly _elevatedBy?: string;
147
+ /**
148
+ * Deterministic-encryption index. Map of field name →
149
+ * base64 deterministic ciphertext. Present only when the collection
150
+ * declares `deterministicFields` and the feature is acknowledged. The
151
+ * field names are unencrypted (they're the index keys); the values
152
+ * are AES-GCM ciphertext with an HKDF-derived deterministic IV.
153
+ *
154
+ * Enables blind equality search (`collection.findByDet(field,
155
+ * value)`) without decrypting every record. Leaks equality as a known
156
+ * side channel.
157
+ */
158
+ readonly _det?: Record<string, string>;
159
+ /**
160
+ * Structural group-encryption. Map of sensitive field name →
161
+ * per-field sealed ciphertext in `iv:data` form (same shape as a `_det`
162
+ * slot). Present only when the collection declares `sensitive` fields and
163
+ * at least one is present on the record. Each field is encrypted under its
164
+ * own HKDF-derived per-field key (`deriveSealedFieldKey`, domain-separated
165
+ * by `<collection>/sealed/<field>`), and is kept OUT of the open `_data`
166
+ * blob — so a reader who can open `_data` still cannot see sealed fields
167
+ * without re-deriving each field key. With no sensitive fields declared the
168
+ * map is absent and `_data` is unchanged (byte-identical to legacy output).
169
+ */
170
+ readonly _sealed?: Record<string, string>;
171
+ /**
172
+ * Verify-digest slots (classified stage 2). Map of digest-only field name →
173
+ * AES-256-GCM `iv:data` blob sealed under the HKDF(CEK) vdig slot key with
174
+ * AAD ['noydb-classify-vdig', collection, recordId, field]. The store sees
175
+ * only ciphertext; only the enclave verify path can read the digest. At most
176
+ * one of `_sealed[field]` / `_vdig[field]` exists per field (I4).
177
+ */
178
+ readonly _vdig?: Record<string, string>;
179
+ /**
180
+ * Equatable blind-index tags (classified slice 2b). Map of digest-only field
181
+ * name → base64 33-byte tag (1-byte cost/version discriminator ‖ 32-byte keyed
182
+ * MAC), CURRENT VALUE ONLY (the _vdig ring is never indexed). This is the ONLY
183
+ * store-visible classified artifact: a keyed MAC, comparable without a key
184
+ * ceremony, with NO inline cryptographic integrity by construction. Invariant:
185
+ * _bidx[field] present ⇒ _vdig[field] present. Confirm-by-verify (findByDigest)
186
+ * makes any read-side orphan/splice unreturnable.
187
+ */
188
+ readonly _bidx?: Record<string, string>;
189
+ /**
190
+ * Per-record content-encryption key (CEK), base64 AES-KW-wrapped under
191
+ * the collection (or tier) DEK. Present only on records written by a
192
+ * collection opened with `perRecordKeys: true`. When present, the body
193
+ * (`_iv`/`_data`) is encrypted under the unwrapped CEK rather than the
194
+ * collection DEK directly.
195
+ *
196
+ * Presence is the format discriminant: `_cek` absent → legacy body
197
+ * keyed off the collection DEK (read unchanged); `_cek` present →
198
+ * unwrap under the collection DEK, then decrypt the body under the CEK.
199
+ *
200
+ * The CEK is stable across every version of a record (insert mints it;
201
+ * updates and history snapshots reuse it), so all `_history` envelopes
202
+ * for a record carry the same `_cek`. This is the foundation for
203
+ * per-record erasure and record-scoped sealing.
204
+ *
205
+ * `_det` slots are deliberately NOT keyed off the CEK — they remain
206
+ * keyed to the collection DEK so blind-equality search keeps working
207
+ * across records.
208
+ */
209
+ readonly _cek?: string;
210
+ /**
211
+ * Debug-plaintext marker. Present only on records written by a vault opened
212
+ * with `debugPlaintext: true` (which requires `encrypt: false`). When set,
213
+ * the record's own fields are inlined as top-level keys on this envelope
214
+ * (beside the reserved `_`-prefixed metadata) and `_data` is empty — so
215
+ * native store tooling (jq, S3 console) reads the record directly. The read
216
+ * path reconstructs the record from the non-`_` keys; the marker makes a
217
+ * debug envelope self-describing, so a classic plaintext reader handles it too.
218
+ */
219
+ readonly _debug?: typeof NOYDB_FORMAT_VERSION;
220
+ /**
221
+ * #589: this envelope is a delete marker (ordinary `collection.delete()` under
222
+ * sync). Empty `_data`, no `_cek`, but version-ordered — a higher-`_v` re-create
223
+ * resurrects the id. Distinct from a forget crypto-shred tombstone, which is
224
+ * terminal. Reads treat it as absent.
225
+ */
226
+ readonly _del?: true;
227
+ }
228
+ /** Spine policy for one digest-only classified field — the enclave-consumable
229
+ * projection of a ClassifiedFieldSpec (the enclave never imports with-*). */
230
+ export interface VdigFieldPolicy {
231
+ readonly normalize: 'password' | 'secret-answer';
232
+ /** Ring size for reuse refusal; 0 = no ring. Cap 8 (spec Q4). */
233
+ readonly notLastN: number;
234
+ readonly rotateDays?: number;
235
+ /** default false — refused unless the double door is open (R8) */
236
+ readonly equatable: boolean;
237
+ }
238
+ /**
239
+ * The persisted classified-fields config marker (C-A / R10). Reuses the
240
+ * stage-2 persisted-schema record; this is the shape of the marker stored
241
+ * there.
242
+ */
243
+ export interface ClassifiedMarker {
244
+ /** field names declared digest-only (have _vdig); non-empty ⇒ writes need the classified codec */
245
+ readonly digestOnly: readonly string[];
246
+ /** field names additionally declared equatable (have _bidx when covered) */
247
+ readonly equatable: readonly string[];
248
+ /**
249
+ * Lifetime epoch (#597) — same shape/intent as `PairingMarker.epoch`
250
+ * (`with-shape/satellites/types.ts`): an opaque, stable-per-collection-
251
+ * lifetime stamp minted the first time this marker is persisted and
252
+ * carried forward unchanged by an IDENTICAL re-persist for the SAME
253
+ * collection (the equality fast path). NOTE: unlike `PairingMarker` (whose
254
+ * R-S9 refuses divergent redeclares), a classified marker IS rewritten
255
+ * wholesale on a genuine reconfiguration (changed digestOnly/equatable
256
+ * set) — so the epoch re-stamps to the fresh value then (see
257
+ * `config-drift.ts`'s `markerForFields`). Optional: markers persisted
258
+ * before this field existed have none. Deliberately excluded from the
259
+ * classified-marker equality check in
260
+ * `with-shape/persisted-schemas/register.ts`. ADDITIVE ONLY today: no
261
+ * delete-collection API exists yet, so a stale marker on a reused name is
262
+ * unreachable; the epoch-MISMATCH rejection this would enable is a
263
+ * deferred follow-up once name reuse is possible — whoever wires it must
264
+ * first make reconfiguration carry the prior epoch forward.
265
+ */
266
+ readonly epoch?: string;
267
+ }
268
+ /** Verdict-only egress of the enclave oracle (spec §3). */
269
+ export interface ClassifiedVerdict {
270
+ readonly ok: boolean;
271
+ /** I1: present ONLY when ok === true — never computed for a false verdict. */
272
+ readonly mustRotate?: true;
273
+ }
274
+ /**
275
+ * Opaque access gate for a sealed (`sensitive`) field returned by a public
276
+ * read (the access layer). The handle carries only the per-field
277
+ * **ciphertext** — the plaintext is never materialised into the working-set
278
+ * cache. Call {@link Sealed.reveal} to decrypt the value on demand.
279
+ *
280
+ * A handle is intentionally NOT usable as `V`: it serialises to a non-leaking
281
+ * marker (`JSON.stringify` / structured logging emit `'[sealed]'`, never the
282
+ * value) and exposes no synchronous accessor.
283
+ */
284
+ export interface Sealed<V> {
285
+ /** Discriminant — always `true`, lets callers narrow a field to a handle. */
286
+ readonly sealed: true;
287
+ /** Decrypt and return the underlying value. */
288
+ reveal(): Promise<V>;
289
+ }
290
+ /**
291
+ * The shape a public read returns for a collection that declares `sensitive`
292
+ * fields `S`: every sealed field becomes an opaque {@link Sealed} handle while
293
+ * the rest of the record is unchanged. The `[S] extends [never]` guard collapses
294
+ * `SealedView<T, never>` to exactly `T`, so collections with no sensitive fields
295
+ * are unaffected — a plain `Omit<T, never>` is *not* a faithful identity for
296
+ * generic intersection record types (it can degrade intersection-only members to
297
+ * `unknown`), which would break consumers like the derivation/MV `_derivedFrom` /
298
+ * `_materializedFrom` reads.
299
+ */
300
+ export type SealedView<T, S extends keyof T> = [S] extends [never] ? T : Omit<T, S> & {
301
+ readonly [K in S]: Sealed<T[K]>;
302
+ };
303
+ /**
304
+ * The type of a field-name argument to the query/scan DSL (`where`, `orderBy`,
305
+ * …) for a collection whose sealed (`sensitive`) fields are `S`.
306
+ *
307
+ * Guarded so the common case is unchanged: with **no** sensitive fields
308
+ * (`S = never`) it is exactly `string` — collections that don't opt into
309
+ * `sensitive` keep today's permissive DSL, zero churn. Once a field is
310
+ * declared `sensitive`, the DSL narrows to the non-sensitive field names, so
311
+ * `where('ssn', …)` becomes a compile error. TypeScript cannot subtract a
312
+ * literal from `string`, so refusing a sensitive name necessarily means
313
+ * narrowing to the known field-name union — this is intentional and only
314
+ * affects collections that opted in.
315
+ *
316
+ * When `Q` (the indexed-field set) is given, `where()` is additionally
317
+ * restricted to `Q` minus any sensitive fields — the escape hatch for
318
+ * non-indexed filters is `scan()`. `Q = never` (the default) preserves the
319
+ * existing 2-param behaviour exactly (zero churn).
320
+ */
321
+ export type QueryField<T, S extends keyof T = never, Q extends keyof T & string = never> = [
322
+ Q
323
+ ] extends [never] ? ([S] extends [never] ? string : Exclude<keyof T & string, S>) : Exclude<Q, S>;
324
+ /**
325
+ * The type of a field-name reference in a collection's index-declaration
326
+ * options (`indexes`, `deterministicFields`, `textIndexes`). Same guarded
327
+ * narrowing as {@link QueryField}: permissive `string` until a field is
328
+ * declared `sensitive`, then the sensitive names are refused (a plaintext
329
+ * secondary index over a sealed field defeats non-residency). Kept distinct
330
+ * from `QueryField` so the two DSL surfaces can diverge later without coupling.
331
+ *
332
+ * When `Q` (the indexed-field set) is given, the `indexes` option is
333
+ * additionally restricted to `Q` minus any sensitive fields — declaring `Q`
334
+ * but listing a different field in `indexes` becomes a compile error.
335
+ * `Q = never` (the default) preserves the existing 2-param behaviour.
336
+ */
337
+ export type IndexFieldName<T, S extends keyof T = never, Q extends keyof T & string = never> = [
338
+ Q
339
+ ] extends [never] ? ([S] extends [never] ? string : Exclude<keyof T & string, S>) : Exclude<Q, S>;
340
+ /**
341
+ * Generic form of the runtime `IndexDef` (see `indexing/eager-indexes.ts`)
342
+ * parameterised by the allowed field-name set `F`. Used to refuse `sensitive`
343
+ * fields in the `indexes` collection option at compile time while leaving the
344
+ * runtime `IndexDef` (string-based) untouched. `IndexDefFor<string>` is
345
+ * structurally identical to `IndexDef`, which is why `vault.collection` can cast
346
+ * the narrowed public option to `IndexDef[]` at the runtime boundary (through
347
+ * `unknown`, solely to drop the `readonly`).
348
+ * **Keep this in sync with `IndexDef`** — if `IndexDef` gains a new union member,
349
+ * add it here too, or that boundary cast will silently admit shapes the runtime
350
+ * machinery does not narrow.
351
+ */
352
+ export type IndexDefFor<F extends string> = F | {
353
+ readonly fields: readonly F[];
354
+ readonly unique?: boolean;
355
+ } | readonly F[];
356
+ /**
357
+ * The type of the `sensitive` collection option, conditional on whether the
358
+ * caller opted into compile-time refusal via an explicit second generic.
359
+ * With no 2nd generic (`S = never`) it accepts any field array — runtime
360
+ * sealing only, no compile refusal, non-breaking. With `S` given, it is
361
+ * `readonly S[]`, which ties the runtime array to the declared sensitive
362
+ * union so the two cannot drift.
363
+ */
364
+ export type SensitiveOpt<T, S extends keyof T> = [S] extends [never] ? readonly (keyof T & string)[] : readonly S[];
365
+ /**
366
+ * The type of the `moneyFields` collection option, conditional on whether the
367
+ * caller opted into compile-time money-field typing via the 4th generic `M`.
368
+ * Typed against the opaque {@link ViaDescriptor} marker rather than the
369
+ * concrete `MoneyDescriptor` — the kernel never inspects a Via feature's
370
+ * descriptor shape, only its declaring service does.
371
+ * A `money()` descriptor structurally satisfies `ViaDescriptor` (it carries
372
+ * `_viaBrand: 'money'`), so this stays publicly assignable from `money()`
373
+ * call sites. With no `M` (`M = never`) it accepts any
374
+ * `Record<string, ViaDescriptor>` — runtime money only, no compile-level
375
+ * narrowing, non-breaking. With `M` given, it is `Record<M, ViaDescriptor>`,
376
+ * tying the runtime map to the declared money-field union so the two cannot
377
+ * drift.
378
+ */
379
+ export type MoneyFieldsOpt<T, M extends keyof T & string = never> = [
380
+ M
381
+ ] extends [never] ? Record<string, ViaDescriptor> : Record<M, ViaDescriptor>;
382
+ /**
383
+ * Concrete {@link Sealed} handle. Holds the reveal closure (which captures the
384
+ * field's ciphertext blob and the unseal routine) in a private field, so it is
385
+ * invisible to `JSON.stringify`, `util.inspect`, and `Object.keys`. `toJSON`
386
+ * returns the marker `'[sealed]'` — a handle can never leak its value through
387
+ * serialisation or logging because the plaintext is not stored on it at all.
388
+ */
389
+ export declare class SealedHandle<V> implements Sealed<V> {
390
+ #private;
391
+ readonly sealed: true;
392
+ constructor(reveal: () => Promise<V>);
393
+ reveal(): Promise<V>;
394
+ /** Non-leaking serialisation marker — never the underlying value. */
395
+ toJSON(): string;
396
+ }
397
+ /**
398
+ * Handover-capable provider. Implemented additionally by asymmetric/granted
399
+ * providers (cloud-KMS asymmetric, Azure RSA Key Vault, AWS KMS with grant).
400
+ * Self-only providers (macOS Keychain, env-var, WebAuthn-PRF) do NOT
401
+ * implement this — the §11.2 capability matrix lives in the type system.
402
+ *
403
+ * Per foundation §11.4. A function that requires recipient-target sealing
404
+ * takes `RecipientSealer`, not `SealingKeyProvider` — the compiler rejects
405
+ * passing a self-only provider at the spec site.
406
+ */
407
+ export interface RecipientSealer {
408
+ readonly id: string;
409
+ /** Produce hint material a sender uses to seal-for-this-recipient. */
410
+ publishRecipientHint(): Promise<RecipientHint>;
411
+ /**
412
+ * Seal plaintext for the recipient described by `hint`. Returns opaque
413
+ * bytes — same contract as `SealingKeyProvider.seal()`. The bundle
414
+ * layer base64-encodes the bytes into `SealedAutoUnlockEntry.sealed`
415
+ * without inspecting them.
416
+ */
417
+ sealForRecipient(plaintext: Uint8Array, hint: RecipientHint): Promise<Uint8Array>;
418
+ }
419
+ /**
420
+ * Thin delivery envelope persisted at
421
+ * `_sealed_cek/<collection>/<id>/<pid>`. The grantor writes one per
422
+ * (record, recipient host) pair. `payload` is the base64 of the bytes returned
423
+ * by {@link RecipientSealer.sealForRecipient} over a UTF-8
424
+ * `JSON.stringify({@link SealedCekBinding})`.
425
+ *
426
+ * `expiresAt` is duplicated here for a cheap pre-unseal reject, but is NOT
427
+ * authoritative — the binding inside `payload` carries the expiry the host
428
+ * verifies after unsealing, so a tampered delivery envelope cannot extend a
429
+ * grant.
430
+ */
431
+ export interface SealedCekDeliveryEnvelope {
432
+ /** Envelope schema version. */
433
+ readonly v: 1;
434
+ /** Magic marker for forensics + format detection. */
435
+ readonly _noydb_sealed_cek: 1;
436
+ /** Recipient host provider id; matches the sealer's `.id` / hint `pid`. */
437
+ readonly pid: string;
438
+ /** base64 of the sealed {@link SealedCekBinding} bytes. */
439
+ readonly payload: string;
440
+ /** Fast-path expiry hint (ISO 8601). Authoritative copy is inside `payload`. */
441
+ readonly expiresAt: string;
442
+ }
443
+ /**
444
+ * The plaintext struct sealed for the recipient host. After the host unseals
445
+ * `SealedCekDeliveryEnvelope.payload` it parses this and MUST verify:
446
+ * - `collection` + `id` match the record envelope it is decrypting, and
447
+ * - `expiresAt` has not passed (authoritative expiry check).
448
+ *
449
+ * `cek` is the base64 of the raw 32-byte AES-256-GCM record CEK.
450
+ */
451
+ export interface SealedCekBinding {
452
+ /** Collection the CEK belongs to. */
453
+ readonly collection: string;
454
+ /** Record id the CEK belongs to. */
455
+ readonly id: string;
456
+ /** base64 of the raw AES-256-GCM CEK bytes. */
457
+ readonly cek: string;
458
+ /** Authoritative expiry (ISO 8601). */
459
+ readonly expiresAt: string;
460
+ }
461
+ /**
462
+ * Placeholder returned by `getAtTier()` in `'ghost'` mode when a
463
+ * record is at a tier the caller cannot decrypt. Record existence is
464
+ * advertised — the id and tier are visible — but contents are
465
+ * withheld. `canElevateFrom` lists user ids authorized to elevate
466
+ * access for this caller when known; absent when the workflow is
467
+ * not configured.
468
+ */
469
+ export interface GhostRecord {
470
+ readonly _ghost: true;
471
+ readonly _tier: number;
472
+ readonly canElevateFrom?: readonly string[];
473
+ }
474
+ /** Control what lower-tier reads see above their clearance. */
475
+ export type TierMode = 'invisibility' | 'ghost';
476
+ /**
477
+ * Event emitted when a record at a tier above the caller's inherent
478
+ * clearance is read or written successfully (via elevation or
479
+ * delegation). Always written to the ledger; subscribers get a
480
+ * real-time feed.
481
+ */
482
+ export interface CrossTierAccessEvent {
483
+ readonly actor: string;
484
+ readonly collection: string;
485
+ readonly id: string;
486
+ readonly tier: number;
487
+ /** How the caller gained tier access: they elevated it, or a delegation is active. */
488
+ readonly authorization: 'elevation' | 'delegation' | 'inherent';
489
+ readonly op: 'get' | 'put' | 'elevate' | 'demote';
490
+ readonly ts: string;
491
+ /**
492
+ * When `authorization === 'elevation'`, the audit reason string the
493
+ * caller passed to `vault.elevate(...)`. Empty for inherent /
494
+ * delegation paths.
495
+ */
496
+ readonly reason?: string;
497
+ /**
498
+ * When `authorization === 'elevation'`, the tier the caller's
499
+ * keyring effectively held BEFORE elevation. Useful for audit
500
+ * dashboards distinguishing "operator elevating to 2" from
501
+ * "inherent tier-2 write."
502
+ */
503
+ readonly elevatedFrom?: number;
504
+ }
505
+ /**
506
+ * A single deterministic-ciphertext index slot on an envelope. Stored
507
+ * as `iv:data` (both base64, colon-separated) so a single string per
508
+ * field keeps the envelope compact.
509
+ */
510
+ export type DeterministicCipher = string;
511
+ /** All records across all collections for a compartment. */
512
+ export type VaultSnapshot = Record<string, Record<string, EncryptedEnvelope>>;
513
+ /**
514
+ * Result of a single page fetch via the optional `listPage` adapter extension.
515
+ *
516
+ * `items` carries the actual encrypted envelopes (not just ids) so the
517
+ * caller can decrypt and emit a single record without an extra `get()`
518
+ * round-trip per id. `nextCursor` is `null` on the final page.
519
+ */
520
+ export interface ListPageResult {
521
+ /** Encrypted envelopes for this page, in adapter-defined order. */
522
+ items: Array<{
523
+ id: string;
524
+ envelope: EncryptedEnvelope;
525
+ }>;
526
+ /** Opaque cursor for the next page, or `null` if this was the last page. */
527
+ nextCursor: string | null;
528
+ }
529
+ export interface NoydbStore {
530
+ /**
531
+ * Optional human-readable store name (e.g. 'memory', 'file', 'dynamo').
532
+ * Used in diagnostic messages and the listPage fallback warning. Stores
533
+ * are encouraged to set this so logs are clearer about which backend is
534
+ * involved when something goes wrong.
535
+ */
536
+ name?: string;
537
+ /**
538
+ * Optional declared store capabilities (CAS atomicity, native tx, blob
539
+ * size limits, auth). Consumers that require a capability — e.g.
540
+ * `vault.sequence().next()` needs `casAtomic` — read it here.
541
+ */
542
+ capabilities?: StoreCapabilities;
543
+ /** Get a single record. Returns null if not found. */
544
+ get(vault: string, collection: string, id: string): Promise<EncryptedEnvelope | null>;
545
+ /** Put a record. Throws ConflictError if expectedVersion doesn't match. */
546
+ put(vault: string, collection: string, id: string, envelope: EncryptedEnvelope, expectedVersion?: number): Promise<void>;
547
+ /** Delete a record. */
548
+ delete(vault: string, collection: string, id: string): Promise<void>;
549
+ /** List all record IDs in a collection. */
550
+ list(vault: string, collection: string): Promise<string[]>;
551
+ /** Load all records for a vault (initial hydration). */
552
+ loadAll(vault: string): Promise<VaultSnapshot>;
553
+ /** Save all records for a vault (bulk write / restore). */
554
+ saveAll(vault: string, data: VaultSnapshot): Promise<void>;
555
+ /** Optional connectivity check for sync engine. */
556
+ ping?(): Promise<boolean>;
557
+ /**
558
+ * The store's authoritative time as a bounded-uncertainty interval.
559
+ * Present iff `capabilities.serverWriteTime` is true. Monotonic
560
+ * non-decreasing across calls on a single store.
561
+ */
562
+ getStoreTime?(): Promise<StoreTime>;
563
+ /**
564
+ * Optional: list record IDs in a collection that have `_ts` after `since`.
565
+ * Used by partial sync (`pull({ modifiedSince })`). Stores that omit this
566
+ * fall back to a full `loadAll` + client-side timestamp filter.
567
+ */
568
+ listSince?(vault: string, collection: string, since: string): Promise<string[]>;
569
+ /**
570
+ * Optional pagination extension. Stores that implement `listPage` get
571
+ * the streaming `Collection.scan()` fast path; stores that don't are
572
+ * silently fallen back to a full `loadAll()` + slice (with a one-time
573
+ * console.warn).
574
+ *
575
+ * `cursor` is opaque to the core — each store encodes its own paging
576
+ * state (DynamoDB: base64 LastEvaluatedKey JSON; S3: ContinuationToken;
577
+ * memory/file/browser: numeric offset of a sorted id list). Pass
578
+ * `undefined` to start from the beginning.
579
+ *
580
+ * `limit` is a soft upper bound on `items.length`. Stores MAY return
581
+ * fewer items even when more exist (e.g. if the underlying store has
582
+ * its own page size cap), and MUST signal "no more pages" by returning
583
+ * `nextCursor: null`.
584
+ *
585
+ * The 6-method core contract is unchanged — this is an additive
586
+ * extension discovered via `'listPage' in adapter`.
587
+ */
588
+ listPage?(vault: string, collection: string, cursor?: string, limit?: number): Promise<ListPageResult>;
589
+ /**
590
+ * Optional pub/sub for real-time presence.
591
+ * Publish an encrypted payload to a presence channel.
592
+ * Falls back to storage-based polling when absent.
593
+ */
594
+ presencePublish?(channel: string, payload: string): Promise<void>;
595
+ /**
596
+ * Optional pub/sub for real-time presence.
597
+ * Subscribe to a presence channel. Returns an unsubscribe function.
598
+ * Falls back to storage-based polling when absent.
599
+ */
600
+ presenceSubscribe?(channel: string, callback: (payload: string) => void): () => void;
601
+ /**
602
+ * Optional cross-vault enumeration extension.
603
+ *
604
+ * Returns the names of every top-level vault the store
605
+ * currently stores. Used by `Noydb.listAccessibleVaults()` to
606
+ * enumerate the universe of vaults before filtering down to
607
+ * the ones the calling principal can actually unwrap.
608
+ *
609
+ * **Why this is optional:** the storage shape of compartments
610
+ * differs across backends. Memory and file stores store
611
+ * vaults as top-level keys / directories and can enumerate
612
+ * them in O(1) calls. DynamoDB stores everything in a single table
613
+ * keyed by `(compartment#collection, id)` — enumerating compartments
614
+ * requires either a Scan (expensive, eventually consistent, leaks
615
+ * ciphertext metadata) or a dedicated GSI that the consumer
616
+ * provisioned. S3 needs a prefix list (cheap if enabled, ACL-sensitive
617
+ * otherwise). Browser localStorage can scan keys by prefix.
618
+ *
619
+ * Stores that cannot implement `listVaults` cheaply or
620
+ * cleanly should omit it. Core surfaces a `StoreCapabilityError`
621
+ * with a clear message when a caller invokes
622
+ * `listAccessibleVaults()` against a store that doesn't
623
+ * provide this method, so consumers know to either upgrade their
624
+ * store, provide a candidate list explicitly to `queryAcross()`,
625
+ * or fall back to maintaining the compartment index out of band.
626
+ *
627
+ * **Privacy note:** `listVaults` returns *every* compartment
628
+ * the store has, not just the ones the caller can access. The
629
+ * existence-leak filtering (returning only compartments whose
630
+ * keyring the caller can unwrap) happens in core, not in the
631
+ * store. The store is trusted to know its own contents — that
632
+ * is not a leak in the threat model. The leak the API guards
633
+ * against is the *return value* of `listAccessibleVaults()`
634
+ * exposing existence to a downstream observer who only sees that
635
+ * function's output.
636
+ *
637
+ * The 6-method core contract is unchanged — this is an additive
638
+ * extension discovered via `'listVaults' in store`.
639
+ */
640
+ listVaults?(): Promise<string[]>;
641
+ /**
642
+ * Optional: generate a presigned URL for direct client download.
643
+ * Only meaningful for object stores (S3, GCS) that support URL signing.
644
+ * Returns a time-limited URL that fetches the encrypted envelope directly.
645
+ * The caller must decrypt client-side (the URL returns ciphertext).
646
+ */
647
+ presignUrl?(vault: string, collection: string, id: string, expiresInSeconds?: number): Promise<string>;
648
+ /**
649
+ * Optional: estimate current storage usage.
650
+ * Returns `{ usedBytes, quotaBytes }` or null if the store cannot estimate.
651
+ * Used by quota-aware routing to detect overflow conditions.
652
+ */
653
+ estimateUsage?(): Promise<{
654
+ usedBytes: number;
655
+ quotaBytes: number;
656
+ } | null>;
657
+ /**
658
+ * Optional multi-record atomic write.
659
+ *
660
+ * When present, `db.transaction(async (tx) => { ... })` uses this to
661
+ * commit every staged op in one storage-layer transaction — either
662
+ * all ops land or none do, regardless of which records they touch.
663
+ * Every `TxOp.expectedVersion` (when set) must be honored atomically
664
+ * alongside the write; any violation throws `ConflictError` and the
665
+ * whole batch fails.
666
+ *
667
+ * Stores that omit this fall through to the hub's per-record OCC
668
+ * fallback: pre-flight CAS check, then sequential `put`/`delete`
669
+ * with best-effort unwind on mid-batch failure (see
670
+ * `runTransaction` for the exact semantics and crash window).
671
+ *
672
+ * Native implementations: `to-memory` (single Map mutation),
673
+ * `to-dynamo` (`TransactWriteItems`), `to-browser-idb` (one
674
+ * `readwrite` transaction). File / S3 cannot implement this
675
+ * atomically and should omit the method.
676
+ */
677
+ tx?(ops: readonly TxOp[]): Promise<void>;
678
+ }
679
+ /**
680
+ * A single staged operation inside a `db.transaction(fn)` commit. The
681
+ * hub assembles `TxOp[]` from the user's `tx.collection().put/delete`
682
+ * calls, encrypts any `record` values into `envelope`, and hands the
683
+ * array to `NoydbStore.tx()` when the store supports atomic batch
684
+ * writes. Stores that implement `tx()` MUST honor every
685
+ * `expectedVersion` atomically against the stored envelope version.
686
+ */
687
+ export interface TxOp {
688
+ readonly type: 'put' | 'delete';
689
+ readonly vault: string;
690
+ readonly collection: string;
691
+ readonly id: string;
692
+ /** Populated for `type: 'put'` — the encrypted envelope to write. */
693
+ readonly envelope?: EncryptedEnvelope;
694
+ /** Optional per-record CAS. Mismatch must throw `ConflictError`. */
695
+ readonly expectedVersion?: number;
696
+ }
697
+ /** Type-safe helper for creating store factories. */
698
+ export declare function createStore<TOptions>(factory: (options: TOptions) => NoydbStore): (options: TOptions) => NoydbStore;
699
+ /**
700
+ * Interchange formats `@noy-db/as-*` packages can produce. `'*'` is a
701
+ * wildcard granting every current + future plaintext format.
702
+ */
703
+ export type ExportFormat = 'xlsx' | 'csv' | 'json' | 'ndjson' | 'xml' | 'sql' | 'pdf' | 'blob' | 'zip' | '*';
704
+ /**
705
+ * Owner-granted export capability on a keyring.
706
+ *
707
+ * Two independent dimensions:
708
+ *
709
+ * - `plaintext` — per-format allowlist for record formatters + blob
710
+ * extractors that emit plaintext bytes (`as-xlsx`, `as-csv`,
711
+ * `as-blob`, `as-zip`, …). **Defaults to empty** for every role;
712
+ * the owner/admin must positively grant per-format (or `'*'`).
713
+ * - `bundle` — boolean for `.noydb` encrypted container export
714
+ * (`as-noydb`). **Default policy: on for owner/admin, off for
715
+ * operator/viewer/client** — applied when the field is absent or
716
+ * undefined (see `hasExportCapability`).
717
+ */
718
+ export interface ExportCapability {
719
+ readonly plaintext?: readonly ExportFormat[];
720
+ readonly bundle?: boolean;
721
+ }
722
+ /**
723
+ * Owner-granted import capability on a keyring (sibling of
724
+ * `ExportCapability`, issue ).
725
+ *
726
+ * Two independent dimensions:
727
+ *
728
+ * - `plaintext` — per-format allowlist for `as-*` readers that ingest
729
+ * plaintext bytes (`as-csv`, `as-json`, `as-ndjson`, `as-zip`, …).
730
+ * Defaults to empty for every role; the owner/admin must positively
731
+ * grant per-format (or `'*'`).
732
+ * - `bundle` — boolean gate for `.noydb` bundle import. **Defaults to
733
+ * `false` for every role**, including owner/admin. Import is more
734
+ * dangerous than export (corrupts vs leaks), so the policy is
735
+ * default-closed across the board — the owner explicitly opts a
736
+ * keyring in via `db.grant({ importCapability: { bundle: true } })`.
737
+ */
738
+ export interface ImportCapability {
739
+ readonly plaintext?: readonly ExportFormat[];
740
+ readonly bundle?: boolean;
741
+ }
742
+ /**
743
+ * Forward-declared on-disk shape for `VaultPolicy` — the actual policy
744
+ * model is declared further down in this file (#9), see {@link VaultPolicy}.
745
+ * Declared here as an `unknown`-typed map (rather than `VaultPolicy` itself)
746
+ * so the `KeyringFile.policy` field can still round-trip foreign/older
747
+ * documents that don't strictly satisfy the current shape.
748
+ *
749
+ * @internal
750
+ */
751
+ export type VaultPolicyOnDisk = Record<string, unknown>;
752
+ /**
753
+ * Recovery profile enrolled at vault creation.
754
+ *
755
+ * - `paper` — `on-recovery` codes (the standard end-to-end profile).
756
+ * - `shamir` / `multi-channel` / `admin-mediated` — API surface ships;
757
+ * per-profile dispatch lands in follow-up issues. Calling
758
+ * `db.recoverPassphrase` against these throws
759
+ * {@link RecoveryProfileNotImplementedError}.
760
+ */
761
+ export type RecoveryEnrollment = {
762
+ readonly profile: 'paper';
763
+ /** Number of single-use codes to print at enrollment. */
764
+ readonly codes: number;
765
+ } | {
766
+ readonly profile: 'shamir';
767
+ readonly k: number;
768
+ readonly n: number;
769
+ readonly trustees: ReadonlyArray<string>;
770
+ } | {
771
+ readonly profile: 'multi-channel';
772
+ readonly email?: string;
773
+ readonly pin?: boolean;
774
+ readonly paperCodes?: number;
775
+ } | {
776
+ readonly profile: 'admin-mediated';
777
+ readonly grantorUserId: string;
778
+ };
779
+ /**
780
+ * One tier-2 authenticator slot inside a keyring file. Each slot
781
+ * independently wraps the SAME KEK under a method-specific derived key
782
+ * (LUKS pattern). Adding or removing a slot is a constant-time keyring
783
+ * write — no DEK re-keying required.
784
+ *
785
+ * @see https://github.com/vLannaAi/noy-db-docs/blob/main/content/docs/services/session-tiers.md → Tier 2 — Authenticate (multi-slot)
786
+ */
787
+ /**
788
+ * Shared fields across all authenticator slot variants. The variant
789
+ * (`KeyringAuthenticatorWrappingKEK` vs `KeyringAuthenticatorWrappingDEKs`)
790
+ * carries the actual wrapped material; everything below is identity +
791
+ * metadata only.
792
+ */
793
+ interface KeyringAuthenticatorBase {
794
+ /** Caller-chosen identifier — e.g. `'webauthn-yubikey-blue'`, `'oidc-google'`, `'password'`. */
795
+ readonly id: string;
796
+ /** Method family — selects which `@noy-db/on-*` package handles unlock. */
797
+ readonly method: 'webauthn' | 'oidc' | 'password';
798
+ /** ISO-8601 timestamp at which the slot was added. */
799
+ readonly enrolled_at: string;
800
+ /**
801
+ * Which session tier ENROLLED this slot. Tier 1 enrolls a fresh slot;
802
+ * tier 2 may add a sibling slot when the active policy permits.
803
+ */
804
+ readonly enrolled_via_tier: 1 | 2;
805
+ /**
806
+ * Method-specific metadata: WebAuthn cred id, OIDC issuer/sub, PBKDF2
807
+ * salt for `on-password`, etc. The schema is open by design — the
808
+ * `@noy-db/on-*` package owns the contents.
809
+ */
810
+ readonly meta: Record<string, unknown>;
811
+ }
812
+ /**
813
+ * Slot that wraps the KEK directly under a method-derived AES-KW key.
814
+ * Used by ceremonies where the on-* package can produce/recover an
815
+ * extractable KEK from its own credential — WebAuthn (PRF-derived
816
+ * wrapping key) and split-key OIDC.
817
+ *
818
+ * `wrapKind` is optional/absent on older slots — those
819
+ * legacy slots are treated as wrap-KEK by default at unlock time.
820
+ */
821
+ export interface KeyringAuthenticatorWrappingKEK extends KeyringAuthenticatorBase {
822
+ readonly wrapKind?: 'kek';
823
+ /** Base64 wrapped-KEK ciphertext under the method-derived key. */
824
+ readonly wrapped_kek: string;
825
+ /** XOR guard — wrap-KEK slots must NOT carry wrap-DEKs material. */
826
+ readonly wrapped_deks?: never;
827
+ /** XOR guard — wrap-KEK slots must NOT carry wrap-DEKs material. */
828
+ readonly iv?: never;
829
+ }
830
+ /**
831
+ * Slot that wraps the DEK set (not the KEK) under a method-derived
832
+ * AES-GCM key — sidesteps the non-extractable-KEK constraint by
833
+ * encrypting the serialized `{ deks: { collection: rawDekBase64 } }`
834
+ * directly. Mirrors the format used by `mintPaperRecoveryEntry`
835
+ * (`PaperRecoveryEntry`) and `@noy-db/on-pin`'s `PinResumeState` —
836
+ * the unified wrap-DEKs primitive across tier-0 / tier-2 / tier-3.
837
+ *
838
+ * Trade-off: a slot of this kind reconstructs `UnlockedKeyring` with
839
+ * `kek: null` after unlock. That is semantically correct for tier-2
840
+ * (sensitive ops like `enrollAuthenticator` / `rotatePassphrase`
841
+ * require a tier-1 unlock anyway) and matches how `@noy-db/on-pin`
842
+ * already behaves at tier 3.
843
+ *
844
+ * @see `mintPaperRecoveryEntry` in `team/recovery.ts` — same shape on
845
+ * a different on-disk path (`_meta/recovery-paper`).
846
+ */
847
+ export interface KeyringAuthenticatorWrappingDEKs extends KeyringAuthenticatorBase {
848
+ readonly wrapKind: 'deks';
849
+ /** Base64 AES-GCM ciphertext of `{ deks: { collection: base64rawDek } }`. */
850
+ readonly wrapped_deks: string;
851
+ /** Base64 AES-GCM IV used for the `wrapped_deks` ciphertext. */
852
+ readonly iv: string;
853
+ /** XOR guard — wrap-DEKs slots must NOT carry wrap-KEK material. */
854
+ readonly wrapped_kek?: never;
855
+ }
856
+ /**
857
+ * Discriminated union over the two wrap-format variants. Reads from
858
+ * disk should always go through this type so the variant is preserved.
859
+ *
860
+ * Discriminator: `wrapKind`. Absent → wrap-KEK (legacy / WebAuthn /
861
+ * OIDC). Present and `'deks'` → wrap-DEKs (password / future on-* that
862
+ * want to sidestep extractable-KEK).
863
+ *
864
+ * The type-level XOR enforces "exactly one of `wrapped_kek` /
865
+ * `wrapped_deks` is present" — a structural guarantee that the runtime
866
+ * dispatch is safe.
867
+ */
868
+ export type KeyringAuthenticator = KeyringAuthenticatorWrappingKEK | KeyringAuthenticatorWrappingDEKs;
869
+ export interface KeyringFile {
870
+ readonly _noydb_keyring: typeof NOYDB_KEYRING_VERSION;
871
+ readonly user_id: string;
872
+ readonly display_name: string;
873
+ readonly role: Role;
874
+ readonly permissions: Permissions;
875
+ readonly deks: Record<string, string>;
876
+ readonly salt: string;
877
+ readonly created_at: string;
878
+ readonly granted_by: string;
879
+ /**
880
+ * Passphrase canary — base64 AES-KW-wrapped form of a known constant
881
+ * 256-bit value, wrapped under the keyring's KEK.
882
+ *
883
+ * Optional: older keyrings load with no canary and fall back to
884
+ * the multi-DEK corruption heuristic. Newer keyrings
885
+ * carry one and let `loadKeyring` distinguish wrong-passphrase
886
+ * from corruption even when ALL DEKs (including a single-DEK keyring's
887
+ * sole DEK) are corrupted.
888
+ *
889
+ * AES-KW is deterministic — every write site mints fresh on each
890
+ * persist; same KEK + same constant input always produces the same
891
+ * ciphertext, so this round-trips without state.
892
+ */
893
+ readonly canary?: string;
894
+ /**
895
+ * Tier-2 authenticator slots (multi-slot keyring extension).
896
+ * Optional / append-only: keyring files written before the
897
+ * extension load with an empty list. Each slot independently wraps
898
+ * the same KEK; any one of them unlocks.
899
+ *
900
+ * @see KeyringAuthenticator
901
+ */
902
+ readonly authenticators?: readonly KeyringAuthenticator[];
903
+ /**
904
+ * Per-keyring policy override (reserved). The on-disk format
905
+ * accepts the field for forward compatibility with the Option C
906
+ * merge engine deferred to a later release; v1.0 reads only the
907
+ * vault-level `_meta/policy` document, so this field is parsed and
908
+ * round-tripped but never enforced.
909
+ */
910
+ readonly policy?: VaultPolicyOnDisk;
911
+ /**
912
+ * Optional — authorization spec capability bits. Absent on keyrings written
913
+ * before the RFC implementation. Loading falls back to role-based
914
+ * defaults (owner/admin get bundle-on, everyone else off).
915
+ */
916
+ readonly export_capability?: ExportCapability;
917
+ /**
918
+ * Optional bundle-slot expiry. ISO-8601 timestamp; past
919
+ * the cutoff `loadKeyring` throws `KeyringExpiredError` before any
920
+ * DEK unwrap is attempted. Useful for time-boxed audit access:
921
+ * "this slot works for 30 days then becomes opaque to its holder."
922
+ *
923
+ * Absent on live keyrings written via `db.grant()` — the field is
924
+ * meaningful for `BundleRecipient` slots produced by
925
+ * `writePod({ recipients: [...] })`. Setting it on a live
926
+ * keyring is allowed but unusual.
927
+ */
928
+ readonly expires_at?: string;
929
+ /**
930
+ * Optional — issue import-capability bits. Absent on keyrings
931
+ * written before landed. Loading falls back to default-closed
932
+ * for every role and every format.
933
+ */
934
+ readonly import_capability?: ImportCapability;
935
+ /**
936
+ * hierarchical access clearance. Absent → 0 (advisory;
937
+ * the real check is whether the DEK map carries a `collection#tier`
938
+ * entry for the requested tier). Owners and admins default to the
939
+ * highest tier they have DEKs for at grant time.
940
+ */
941
+ readonly clearance?: number;
942
+ }
943
+ export interface VaultBackup {
944
+ readonly _noydb_backup: typeof NOYDB_BACKUP_VERSION;
945
+ readonly _compartment: string;
946
+ readonly _exported_at: string;
947
+ readonly _exported_by: string;
948
+ readonly keyrings: Record<string, KeyringFile>;
949
+ readonly collections: VaultSnapshot;
950
+ /**
951
+ * Internal collections (`_ledger`, `_ledger_deltas`, `_history`, `_sync`, …)
952
+ * captured alongside the data collections. Optional for backwards
953
+ * compat with backups, which only stored data collections —
954
+ * loading a backup leaves the ledger empty (and `verifyBackupIntegrity`
955
+ * skips the chain check, surfacing only a console warning).
956
+ */
957
+ readonly _internal?: VaultSnapshot;
958
+ /**
959
+ * Verifiable-backup metadata. Embeds the ledger head at
960
+ * dump time so `load()` can cross-check that the loaded chain matches
961
+ * exactly what was exported. A backup whose chain has been tampered
962
+ * with — either by modifying ledger entries or by modifying data
963
+ * envelopes that the chain references — fails this check.
964
+ *
965
+ * Optional for backwards compat with backups; missing means
966
+ * "legacy backup, load with a warning, no integrity check".
967
+ */
968
+ readonly ledgerHead?: {
969
+ /** Hex sha256 of the canonical JSON of the last ledger entry. */
970
+ readonly hash: string;
971
+ /** Sequential index of the last ledger entry. */
972
+ readonly index: number;
973
+ /** ISO timestamp captured at dump time. */
974
+ readonly ts: string;
975
+ };
976
+ }
977
+ /**
978
+ * Options for `Vault.exportStream()` and `Vault.exportJSON()`.
979
+ *
980
+ * The defaults match the most common consumer pattern: one chunk per
981
+ * collection, no ledger metadata. Per-record streaming and ledger-head
982
+ * inclusion are opt-in because both add structure most consumers don't
983
+ * need.
984
+ */
985
+ export interface ExportStreamOptions {
986
+ /**
987
+ * `'collection'` (default) yields one chunk per collection with all
988
+ * records bundled in `chunk.records`. `'record'` yields one chunk per
989
+ * record, useful for arbitrarily large collections that should never
990
+ * be materialized as a single array.
991
+ */
992
+ readonly granularity?: 'collection' | 'record';
993
+ /**
994
+ * When `true`, every chunk includes the current compartment ledger
995
+ * head under `chunk.ledgerHead`. The value is identical across every
996
+ * chunk in a single export (one ledger per compartment). Forward-
997
+ * compatible with future partition work where the head would become
998
+ * per-partition. Default: `false`.
999
+ */
1000
+ readonly withLedgerHead?: boolean;
1001
+ /**
1002
+ * Export locale (BCP 47, e.g. `'th'`). When set, records are read at this
1003
+ * locale through the **`export` layer**: `i18nText` fields collapse to
1004
+ * the locale string (honoring each field's `export`-layer `onMissing` policy)
1005
+ * and `dictKey`/`staticDict` `<field>Label`s are resolved — a single-locale
1006
+ * export. The raw `dictionaries` snapshot is then redundant and omitted. This
1007
+ * applies to BOTH `exportStream()` and `exportJSON()`.
1008
+ *
1009
+ * Default: `undefined` — raw `{locale}` maps + the `_dictionaries` snapshot
1010
+ * (a full, all-locale backup; format packages apply their own locale strategy).
1011
+ */
1012
+ readonly resolveLabels?: string;
1013
+ }
1014
+ /**
1015
+ * One chunk yielded by `Vault.exportStream()`.
1016
+ *
1017
+ * `granularity: 'collection'` yields one chunk per collection with the
1018
+ * full record array in `records`. `granularity: 'record'` yields one
1019
+ * chunk per record with `records` containing exactly one element — the
1020
+ * `schema` and `refs` metadata is repeated on every chunk so consumers
1021
+ * doing per-record streaming don't have to thread state across yields.
1022
+ */
1023
+ export interface ExportChunk<T = unknown> {
1024
+ /** Collection name (no leading underscore — internal collections are filtered out). */
1025
+ readonly collection: string;
1026
+ /**
1027
+ * Standard Schema validator attached to the collection at `collection()`
1028
+ * construction time, or `null` if no schema was provided. Surfaced so
1029
+ * downstream serializers (`@noy-db/as-*` packages, custom
1030
+ * exporters) can produce schema-aware output (typed CSV headers, XSD
1031
+ * generation, etc.) without poking at collection internals.
1032
+ */
1033
+ readonly schema: StandardSchemaV1<unknown, T> | null;
1034
+ /**
1035
+ * Foreign-key references declared on the collection via the `refs`
1036
+ * option, as the `{ field → { target, mode } }` map produced by
1037
+ * `RefRegistry.getOutbound`. Empty object when no refs were declared.
1038
+ */
1039
+ readonly refs: Record<string, {
1040
+ readonly target: string;
1041
+ readonly mode: 'strict' | 'warn' | 'cascade';
1042
+ }>;
1043
+ /**
1044
+ * Decrypted, ACL-scoped, schema-validated records. Length 1 in
1045
+ * `granularity: 'record'` mode, full collection in `granularity: 'collection'`
1046
+ * mode. Records are returned by reference from the collection's eager
1047
+ * cache where applicable — consumers must treat them as immutable.
1048
+ */
1049
+ readonly records: T[];
1050
+ /**
1051
+ * Dictionary snapshots for every `dictKey` field declared on this
1052
+ * collection. Captured once at stream-start and held
1053
+ * constant across all chunks within the same export — a rename
1054
+ * mid-export does not change the snapshot. `undefined` when the
1055
+ * collection has no `dictKeyFields`.
1056
+ *
1057
+ * Shape: `{ [fieldName]: { [stableKey]: { [locale]: label } } }`
1058
+ *
1059
+ * @example
1060
+ * ```ts
1061
+ * chunk.dictionaries?.status?.paid?.th // → 'ชำระแล้ว'
1062
+ * ```
1063
+ */
1064
+ readonly dictionaries?: Record<string, // field name
1065
+ Record<string, Record<string, string>>>;
1066
+ /**
1067
+ * Vault ledger head at export time. Present only when
1068
+ * `exportStream({ withLedgerHead: true })` was called. Identical
1069
+ * across every chunk in the same export — included on every chunk
1070
+ * for forward-compatibility with future per-partition ledgers, where
1071
+ * the value will differ per chunk.
1072
+ */
1073
+ readonly ledgerHead?: {
1074
+ readonly hash: string;
1075
+ readonly index: number;
1076
+ readonly ts: string;
1077
+ };
1078
+ }
1079
+ export interface DirtyEntry {
1080
+ readonly vault: string;
1081
+ readonly collection: string;
1082
+ readonly id: string;
1083
+ readonly action: 'put' | 'delete';
1084
+ readonly version: number;
1085
+ readonly timestamp: string;
1086
+ }
1087
+ export interface SyncMetadata {
1088
+ readonly _noydb_sync: typeof NOYDB_SYNC_VERSION;
1089
+ readonly last_push: string | null;
1090
+ readonly last_pull: string | null;
1091
+ readonly dirty: DirtyEntry[];
1092
+ }
1093
+ export interface Conflict {
1094
+ readonly vault: string;
1095
+ readonly collection: string;
1096
+ readonly id: string;
1097
+ readonly local: EncryptedEnvelope;
1098
+ readonly remote: EncryptedEnvelope;
1099
+ readonly localVersion: number;
1100
+ readonly remoteVersion: number;
1101
+ /**
1102
+ * Present only when the collection uses `conflictPolicy: 'manual'`.
1103
+ * Call `resolve(winner)` to commit the winning envelope, or
1104
+ * `resolve(null)` to defer (conflict stays queued for the next sync).
1105
+ * Called synchronously inside the `sync:conflict` event handler.
1106
+ */
1107
+ readonly resolve?: (winner: EncryptedEnvelope | null) => void;
1108
+ }
1109
+ /**
1110
+ * #590: sync suppressed a live envelope because a crypto-shred tombstone is
1111
+ * terminal for its record id. Reported on push/pull results (`erasures`) and
1112
+ * via the `'sync:erasure'` event; conflict resolvers are never consulted for
1113
+ * tombstone pairs.
1114
+ */
1115
+ export interface ErasureEnforcement {
1116
+ readonly vault: string;
1117
+ readonly collection: string;
1118
+ readonly id: string;
1119
+ /** The winning tombstone (as stored after enforcement). */
1120
+ readonly tombstone: EncryptedEnvelope;
1121
+ /** The live envelope that lost: a suppressed dirty local edit, or the remote copy destroyed by re-assertion. */
1122
+ readonly suppressed: EncryptedEnvelope;
1123
+ readonly direction: 'pull' | 'push';
1124
+ }
1125
+ /**
1126
+ * A same-device cross-tab write conflict: another tab overwrote a
1127
+ * document this tab had written, having diverged from an older base. Records
1128
+ * are decrypted (cross-tab handlers reconcile in plaintext). `base` is the
1129
+ * common ancestor from history, or null when history is unavailable.
1130
+ */
1131
+ export interface WriteConflict {
1132
+ readonly vault: string;
1133
+ readonly collection: string;
1134
+ readonly docId: string;
1135
+ readonly local: unknown;
1136
+ readonly remote: unknown;
1137
+ readonly base: unknown;
1138
+ readonly localVersion: number;
1139
+ readonly remoteVersion: number;
1140
+ readonly baseVersion: number;
1141
+ }
1142
+ export type ConflictStrategy = 'local-wins' | 'remote-wins' | 'version' | ((conflict: Conflict) => 'local' | 'remote');
1143
+ /**
1144
+ * Collection-level conflict policy.
1145
+ * Overrides the db-level `conflict` option for the specific collection.
1146
+ *
1147
+ * - `'last-writer-wins'` — higher `_ts` wins (timestamp LWW).
1148
+ * - `'first-writer-wins'` — lower `_v` wins (earlier version is preserved).
1149
+ * - `'manual'` — emits `sync:conflict` with a `resolve` callback. Call
1150
+ * `resolve(winner)` synchronously to commit or `resolve(null)` to defer.
1151
+ * - Custom fn — synchronous `(local: T, remote: T) => T`. Must be pure.
1152
+ *
1153
+ * **Delete-vs-edit caveat:** `'last-writer-wins'`, `'first-writer-wins'`,
1154
+ * and `'manual'` compare/hand over raw envelopes, so an edit CAN win over
1155
+ * a delete marker (a later `_ts`, an earlier `_v`, or the app's own
1156
+ * `resolve()` choice). A custom fn, and the CRDT merge modes `'lww-map'`/
1157
+ * `'rga'` (`crdtStrategy`), CANNOT: their shared resolver wrapper decrypts
1158
+ * both sides first and short-circuits to whichever side is the
1159
+ * shredded/tombstoned one *before* the merge function (or CRDT merge)
1160
+ * ever runs — delete unconditionally wins. CRDT mode `'yjs'` is the
1161
+ * exception among CRDT modes: it never decrypts and falls back to a
1162
+ * plain higher-`_v`-wins compare, so an edit can beat a delete there too.
1163
+ */
1164
+ export type ConflictPolicy<T> = 'last-writer-wins' | 'first-writer-wins' | 'manual' | ((local: T, remote: T) => T);
1165
+ /**
1166
+ * Envelope-level resolver registered per collection with the SyncEngine.
1167
+ * Receives the `id` of the conflicting record and both envelopes.
1168
+ * Returns the winning envelope, or `null` to defer resolution.
1169
+ * @internal
1170
+ */
1171
+ export type CollectionConflictResolver = (id: string, local: EncryptedEnvelope, remote: EncryptedEnvelope) => Promise<EncryptedEnvelope | null>;
1172
+ /** Options for targeted push operations. */
1173
+ export interface PushOptions {
1174
+ /** Only push records belonging to these collections. Omit to push all dirty. */
1175
+ collections?: string[];
1176
+ }
1177
+ /** Options for targeted pull operations. */
1178
+ export interface PullOptions {
1179
+ /** Only pull these collections. Omit to pull all. */
1180
+ collections?: string[];
1181
+ /**
1182
+ * Only pull records with `_ts` strictly after this ISO timestamp.
1183
+ * Stores that implement `listSince` use it directly; others fall back
1184
+ * to a full scan with client-side filtering.
1185
+ */
1186
+ modifiedSince?: string;
1187
+ }
1188
+ export interface PushResult {
1189
+ readonly pushed: number;
1190
+ readonly conflicts: Conflict[];
1191
+ readonly errors: Error[];
1192
+ /** #590: tombstone enforcements applied during this run (never resolver-visible). */
1193
+ readonly erasures?: ErasureEnforcement[];
1194
+ }
1195
+ export interface PullResult {
1196
+ readonly pulled: number;
1197
+ readonly conflicts: Conflict[];
1198
+ readonly errors: Error[];
1199
+ /** #590: tombstone enforcements applied during this run (never resolver-visible). */
1200
+ readonly erasures?: ErasureEnforcement[];
1201
+ }
1202
+ /** Result of a sync transaction commit. */
1203
+ export interface SyncTransactionResult {
1204
+ readonly status: 'committed' | 'conflict';
1205
+ readonly pushed: number;
1206
+ readonly conflicts: Conflict[];
1207
+ /** #590: staged writes suppressed by tombstone enforcement during commit. */
1208
+ readonly erasures?: ErasureEnforcement[];
1209
+ }
1210
+ export interface SyncStatus {
1211
+ readonly dirty: number;
1212
+ readonly lastPush: string | null;
1213
+ readonly lastPull: string | null;
1214
+ readonly online: boolean;
1215
+ }
1216
+ export type SyncTargetRole = 'sync-peer' | 'backup' | 'archive';
1217
+ /**
1218
+ * A sync target with role and optional per-target policy.
1219
+ *
1220
+ * | Role | Direction | Conflict resolution | Typical use |
1221
+ * |-------------|---------------|---------------------|--------------------------|
1222
+ * | `sync-peer` | Bidirectional | ConflictStrategy | DynamoDB live sync |
1223
+ * | `backup` | Push-only | N/A (receives merged)| S3 dump, Google Drive |
1224
+ * | `archive` | Push-only | N/A | IPFS, Git tags, S3 Lock |
1225
+ */
1226
+ export interface SyncTarget {
1227
+ /** The store to sync with. */
1228
+ readonly store: NoydbStore;
1229
+ /** Role determines sync direction and conflict handling. */
1230
+ readonly role: SyncTargetRole;
1231
+ /** Per-target sync policy. Inherits store-category default when absent. */
1232
+ readonly policy?: SyncPolicy;
1233
+ /** Human-readable label for DevTools and audit logs. */
1234
+ readonly label?: string;
1235
+ }
1236
+ export interface ChangeEvent {
1237
+ readonly vault: string;
1238
+ readonly collection: string;
1239
+ readonly id: string;
1240
+ readonly action: 'put' | 'delete';
1241
+ }
1242
+ export interface NoydbEventMap {
1243
+ 'change': ChangeEvent;
1244
+ 'error': Error;
1245
+ /**
1246
+ * Same-instance signal that this vault's schema-fence state changed.
1247
+ * For UI integration. Cross-client coordination goes
1248
+ * through the store, not this event.
1249
+ */
1250
+ 'schema:fence-changed': {
1251
+ vault: string;
1252
+ currentSchemaVersion: number;
1253
+ fenceState: 'normal' | 'draining' | 'migrating' | 'complete';
1254
+ };
1255
+ 'sync:push': PushResult;
1256
+ 'sync:pull': PullResult;
1257
+ 'sync:erasure': ErasureEnforcement;
1258
+ 'sync:conflict': Conflict;
1259
+ 'write:conflict': WriteConflict;
1260
+ 'sync:online': void;
1261
+ 'sync:offline': void;
1262
+ 'sync:backup-error': {
1263
+ vault: string;
1264
+ target: string;
1265
+ error: Error;
1266
+ };
1267
+ 'history:save': {
1268
+ vault: string;
1269
+ collection: string;
1270
+ id: string;
1271
+ version: number;
1272
+ };
1273
+ 'history:prune': {
1274
+ vault: string;
1275
+ collection: string;
1276
+ id: string;
1277
+ pruned: number;
1278
+ };
1279
+ /**
1280
+ * A non-fatal i18n script violation under `onScriptViolation: 'warn' | 'filter'`.
1281
+ * 'warn' stored the value as-is; 'filter' stripped disallowed characters
1282
+ * (the event is the only signal the stored data was mutated). 'reject'
1283
+ * throws `ScriptViolationError` and emits nothing.
1284
+ */
1285
+ 'i18n:script-violation': {
1286
+ vault: string;
1287
+ collection: string;
1288
+ id: string;
1289
+ mode: 'warn' | 'filter';
1290
+ warning: ScriptWarning;
1291
+ };
1292
+ /**
1293
+ * Emitted when a persisted-index side-car put/delete fails after the
1294
+ * main record write already succeeded. The main record is durable; the
1295
+ * index mirror may have drifted. Operators reconcile via
1296
+ * `collection.reconcileIndex(field)`.
1297
+ */
1298
+ 'index:write-partial': {
1299
+ vault: string;
1300
+ collection: string;
1301
+ id: string;
1302
+ action: 'put' | 'delete';
1303
+ error: Error;
1304
+ };
1305
+ /**
1306
+ * emitted by `Collection.ensurePersistedIndexesLoaded()`
1307
+ * once per field on first lazy-mode query when
1308
+ * `reconcileOnOpen: 'auto' | 'dry-run'` is configured. `applied` is
1309
+ * `0` in `'dry-run'` mode. `skipped` is reserved for a future
1310
+ * drift-stamp optimization that short-circuits the reconcile when
1311
+ * the mirror version matches what's on disk — currently always
1312
+ * `false` (the full reconcile runs every session).
1313
+ */
1314
+ 'index:reconciled': {
1315
+ vault: string;
1316
+ collection: string;
1317
+ field: string;
1318
+ missing: readonly string[];
1319
+ stale: readonly string[];
1320
+ applied: number;
1321
+ skipped: boolean;
1322
+ };
1323
+ /**
1324
+ * #638 Task 5 — a dispatch-driven derivation/rollup/MV output write targeted a row whose
1325
+ * period is closed. The write is SKIPPED (the historical value stands); the SOURCE write
1326
+ * that triggered the recompute still succeeded. See `kernel/via/dispatch.ts#putDerivedOutput`.
1327
+ * `source.id` may be a non-record sentinel (e.g. `'refreshView'`) for manual bulk-refresh-
1328
+ * triggered skips, not a real source record id.
1329
+ */
1330
+ 'derivation:skipped-frozen': DerivationSkippedFrozen;
1331
+ /**
1332
+ * #654 — an ordinary-delete lookup-ref `cascade`/`nullify` propagation edge whose compare-key
1333
+ * could not be resolved from the backing row (matrix custom-key row unreadable — corruption
1334
+ * class). The delete itself proceeds (only `restrict` edges fail closed, via
1335
+ * `RestrictRefUnresolvableError`); this edge's propagation is skipped and reported here instead
1336
+ * of silently dropped — the ordinary-delete counterpart of the forget path's
1337
+ * `ForgetResult.lookupReferencesResidue` channel. `residue` entries are `backing:key:
1338
+ * collection.field`, one per un-propagated edge (see `VaultLinks.applyLookupRefsPropagation`).
1339
+ */
1340
+ 'lookup:propagation-residue': {
1341
+ vault: string;
1342
+ dimension: string;
1343
+ key: string;
1344
+ residue: readonly string[];
1345
+ };
1346
+ /**
1347
+ * #640 rider (#644 item 3) — the sync/cutover/restore dispatch wave's per-id recompute failed
1348
+ * (a genuine decrypt failure, a derive()/executor bug, a schema violation on the output, ...).
1349
+ * ADDITIVE to the existing `console.warn` in `runGraphDispatchWave` — never replaces it, so no
1350
+ * listener-dependent silence. One event per failed (collection, id); the wave still isolates
1351
+ * the failure to just that one record. See `kernel/via/dispatch.ts#runGraphDispatchWave`.
1352
+ */
1353
+ 'derivation:wave-error': {
1354
+ collection: string;
1355
+ id: string;
1356
+ error: unknown;
1357
+ };
1358
+ }
1359
+ export interface GrantOptions {
1360
+ readonly userId: string;
1361
+ readonly displayName: string;
1362
+ readonly role: Role;
1363
+ readonly passphrase: string;
1364
+ readonly permissions?: Permissions;
1365
+ /**
1366
+ * Optional `@noy-db/as-*` export capability. Omit or
1367
+ * leave undefined to apply role-based defaults (see
1368
+ * `hasExportCapability` and `ExportCapability`).
1369
+ */
1370
+ readonly exportCapability?: ExportCapability;
1371
+ /**
1372
+ * Optional `@noy-db/as-*` import capability (issue ). Omit or
1373
+ * leave undefined for default-closed semantics — no plaintext format
1374
+ * is grantable until positively listed; bundle import is denied.
1375
+ */
1376
+ readonly importCapability?: ImportCapability;
1377
+ /**
1378
+ * Skip phrase-format strength validation (issue #7). Defaults to
1379
+ * false — `grant()` rejects phrases that don't meet the configured
1380
+ * `PassphrasePolicy`. Test fixtures and CLI scripts pass `true`.
1381
+ */
1382
+ readonly allowWeakPassphrase?: boolean;
1383
+ /**
1384
+ * Initial user-envelope payload for the new principal. Sealed under
1385
+ * the same vault DEK (the reserved `_users` collection's DEK) and
1386
+ * persisted alongside the keyring during grant.
1387
+ *
1388
+ * **Bootstrap-only.** Once the new user activates and writes their
1389
+ * own envelope, the own-only write rule kicks in — admins cannot
1390
+ * edit a teammate's envelope after activation. Use this field for
1391
+ * pre-fill at invite time (e.g. "displayName: Bob, locale: en-US")
1392
+ * and let the user take over from there.
1393
+ *
1394
+ * Hub does not introspect the payload; it is JSON-serialized and
1395
+ * encrypted opaquely. Apps own the schema.
1396
+ *
1397
+ * @see docs/superpowers/specs/2026-05-05-user-envelope-design.md → Lifecycle
1398
+ */
1399
+ readonly initialProfile?: unknown;
1400
+ }
1401
+ /**
1402
+ * Caller payload for `db.updateUser`. Mutate one or more
1403
+ * identity fields on an existing keyring without rotating any keys.
1404
+ *
1405
+ * `role`, `displayName`, and `permissions` live in the plaintext header
1406
+ * of `_keyring/<userId>` (the sync engine reads them without keys).
1407
+ * Mutating them is a JSON header swap — no DEK rewrap, no KEK
1408
+ * required, no authenticator slots touched. Tier-2 slots and recovery
1409
+ * enrollments survive unchanged. Last-write-wins through the existing
1410
+ * keyring put (same concurrency story as `db.grant` / `db.revoke`).
1411
+ *
1412
+ * Top-level fields are partial-merge: absent fields are not modified.
1413
+ * `null` on `displayName` clears the field (stored as the empty string;
1414
+ * UI consumers typically render the empty case by falling back to the
1415
+ * user id). `undefined` / absent leaves the field untouched. Mirrors
1416
+ * the `null`-as-clear convention `UserApi.updateMe` uses.
1417
+ *
1418
+ * `permissions`, however, is a **full replacement** at the map level —
1419
+ * passing `{ invoices: 'rw' }` REPLACES the entire permissions map,
1420
+ * silently dropping any other entries. To partially update, read the
1421
+ * current keyring and merge: `permissions: { ...current, invoices: 'rw' }`.
1422
+ * To clear all permissions, pass `permissions: {}` explicitly.
1423
+ *
1424
+ * Role-elevation guard: the same hierarchy as `db.grant`. Admins can
1425
+ * change `admin` / `operator` / `viewer` / `client` to and from each
1426
+ * other; admins cannot promote to or demote from `owner`. Owners can
1427
+ * do anything. Non-admin callers (operator/viewer/client) cannot call
1428
+ * `db.updateUser` at all — for self-displayName changes, use
1429
+ * `vault.user.updateMe` (the user-envelope API).
1430
+ */
1431
+ export interface UpdateUserOptions {
1432
+ readonly userId: string;
1433
+ readonly role?: Role;
1434
+ readonly displayName?: string | null;
1435
+ readonly permissions?: Permissions;
1436
+ }
1437
+ export interface RevokeOptions {
1438
+ readonly userId: string;
1439
+ readonly rotateKeys?: boolean;
1440
+ /**
1441
+ * Cascade behavior when the revoked user is an admin who has granted
1442
+ * other admins.
1443
+ *
1444
+ * - `'strict'` (default) — recursively revoke every admin that the
1445
+ * target (transitively) granted. The cascade walks the
1446
+ * `granted_by` field on each keyring file and stops at non-admin
1447
+ * leaves. All affected collections are accumulated and rotated in
1448
+ * a single pass at the end, so cascade cost is O(records in
1449
+ * affected collections), not O(records × cascade depth).
1450
+ *
1451
+ * - `'warn'` — leave the descendant admins in place but emit a
1452
+ * `console.warn` listing them. Useful for diagnostic dry runs and
1453
+ * for environments where the operator wants to clean up the
1454
+ * delegation tree manually.
1455
+ *
1456
+ * No effect when the target is not an admin (operators, viewers, and
1457
+ * clients cannot grant other users, so they have no delegation
1458
+ * subtree to cascade through). Defaults to `'strict'`.
1459
+ */
1460
+ readonly cascade?: 'strict' | 'warn';
1461
+ }
1462
+ /**
1463
+ * One entry returned by `Noydb.listAccessibleVaults()`. Carries
1464
+ * the compartment id and the role the calling principal holds in it,
1465
+ * so the consumer can decide how to fan out without re-checking
1466
+ * permissions per vault.
1467
+ */
1468
+ export interface AccessibleVault {
1469
+ readonly id: string;
1470
+ readonly role: Role;
1471
+ }
1472
+ /**
1473
+ * Options for `Noydb.listAccessibleVaults()`.
1474
+ */
1475
+ export interface ListAccessibleVaultsOptions {
1476
+ /**
1477
+ * Minimum role the caller must hold to include a vault in the
1478
+ * result. Vaults where the caller's role is strictly *below*
1479
+ * this threshold are silently excluded. Defaults to `'client'`,
1480
+ * which means "every vault I can unwrap is returned." Set to
1481
+ * `'admin'` for "vaults where I can grant/revoke," or
1482
+ * `'owner'` for "vaults I own."
1483
+ *
1484
+ * The privilege ordering used:
1485
+ * `client (1) < viewer (2) < operator (3) < admin (4) < owner (5)`
1486
+ *
1487
+ * Note: `viewer` and `client` are conceptually peers in the ACL
1488
+ * (neither can grant), but `viewer` has read-all access while
1489
+ * `client` has only explicit-collection read. The numeric order
1490
+ * reflects "how much can this principal see," not "how much can
1491
+ * this principal modify."
1492
+ */
1493
+ readonly minRole?: Role;
1494
+ }
1495
+ /**
1496
+ * Options for `Noydb.queryAcross()`.
1497
+ */
1498
+ export interface QueryAcrossOptions {
1499
+ /**
1500
+ * Maximum number of compartments to process in parallel. Defaults
1501
+ * to `1` (sequential) — conservative because the per-compartment
1502
+ * callback typically does its own I/O and an unbounded fan-out can
1503
+ * exhaust adapter connections (DynamoDB throughput, S3 socket
1504
+ * limits, browser fetch concurrency).
1505
+ *
1506
+ * Set to `4` or `8` for cloud-backed compartments where parallelism
1507
+ * is the whole point of fanning out. Set to `1` (default) for local
1508
+ * adapters where the disk I/O serializes anyway.
1509
+ */
1510
+ readonly concurrency?: number;
1511
+ /**
1512
+ * Open shards non-creatingly — a missing grant throws instead of
1513
+ * self-provisioning. Default: `true` (create iff the vault has no
1514
+ * `_keyring/*`). Pass `false` for strict open-existing semantics
1515
+ * (e.g. federation read fan-out where shards are pre-provisioned
1516
+ * and an absent grant should fail closed).
1517
+ */
1518
+ readonly create?: boolean;
1519
+ }
1520
+ /**
1521
+ * One entry in the array returned by `Noydb.queryAcross()`. Either
1522
+ * `result` is set (callback succeeded for this compartment) or
1523
+ * `error` is set (callback threw, or compartment failed to open).
1524
+ *
1525
+ * Per-compartment errors do **not** abort the overall fan-out — every
1526
+ * compartment is given a chance to run its callback, and the
1527
+ * partition between success and failure is exposed in the return
1528
+ * value. Consumers that want fail-fast semantics can check
1529
+ * `r.error !== undefined` and short-circuit themselves.
1530
+ */
1531
+ export type QueryAcrossResult<T> = {
1532
+ readonly vault: string;
1533
+ readonly result: T;
1534
+ readonly error?: undefined;
1535
+ } | {
1536
+ readonly vault: string;
1537
+ readonly result?: undefined;
1538
+ readonly error: Error;
1539
+ };
1540
+ export interface UserInfo {
1541
+ readonly userId: string;
1542
+ readonly displayName: string;
1543
+ readonly role: Role;
1544
+ readonly permissions: Permissions;
1545
+ readonly createdAt: string;
1546
+ readonly grantedBy: string;
1547
+ }
1548
+ /**
1549
+ * Operations that a session policy can require re-authentication for.
1550
+ * Passed as the `requireReAuthFor` array in `SessionPolicy`.
1551
+ */
1552
+ export type ReAuthOperation = 'export' | 'grant' | 'revoke' | 'rotate' | 'changeSecret';
1553
+ /**
1554
+ * Session policy controlling lifetime, re-auth requirements, and
1555
+ * background-lock behavior.
1556
+ *
1557
+ * All timeout values are in milliseconds. `undefined` means "no limit."
1558
+ * The policy is evaluated lazily — it does not start timers itself;
1559
+ * enforcement happens at the Noydb call site.
1560
+ */
1561
+ export interface SessionPolicy {
1562
+ /**
1563
+ * Idle timeout in ms. If no NOYDB operation is performed for this
1564
+ * duration, the session is revoked on the next operation attempt
1565
+ * (which will throw `SessionExpiredError`). The idle clock resets
1566
+ * on every successful operation.
1567
+ *
1568
+ * Default: `undefined` (no idle timeout).
1569
+ */
1570
+ readonly idleTimeoutMs?: number;
1571
+ /**
1572
+ * Absolute timeout in ms from session creation. After this duration
1573
+ * the session is unconditionally revoked regardless of activity.
1574
+ *
1575
+ * Default: `undefined` (no absolute timeout).
1576
+ */
1577
+ readonly absoluteTimeoutMs?: number;
1578
+ /**
1579
+ * Operations that require the user to re-authenticate (re-enter their
1580
+ * passphrase or perform a fresh WebAuthn assertion) before proceeding,
1581
+ * even if the session is still alive.
1582
+ *
1583
+ * Common pattern: `requireReAuthFor: ['export', 'grant']` — allow
1584
+ * read/write operations in the background but demand a fresh credential
1585
+ * for high-risk mutations.
1586
+ *
1587
+ * Default: `[]` (no extra re-auth requirements).
1588
+ */
1589
+ readonly requireReAuthFor?: readonly ReAuthOperation[];
1590
+ /**
1591
+ * If `true`, the session is revoked when the page goes to the background
1592
+ * (visibilitychange event, `document.hidden === true`). Useful for
1593
+ * high-sensitivity deployments where leaving the tab is treated as
1594
+ * a session boundary.
1595
+ *
1596
+ * No-op in non-browser environments (Node.js, workers without document).
1597
+ * Default: `false`.
1598
+ */
1599
+ readonly lockOnBackground?: boolean;
1600
+ }
1601
+ /**
1602
+ * Locale-aware read options. Pass to `Collection.get()`, `list()`,
1603
+ * `query()`, and `scan()` to trigger per-record locale resolution for
1604
+ * `dictKey` and `i18nText` fields.
1605
+ *
1606
+ * - **`locale: 'raw'`** — skip resolution for `i18nText` fields and
1607
+ * return the full `{ [locale]: string }` map. Dict key fields still
1608
+ * return the stable key (no `<field>Label` added).
1609
+ * - **`fallback`** — single locale code or ordered list. Use `'any'` as
1610
+ * the last element to fall back to any present translation.
1611
+ *
1612
+ * When neither the call-level locale nor the compartment's default locale
1613
+ * is set, reading a record with `i18nText` fields throws
1614
+ * `LocaleNotSpecifiedError`.
1615
+ */
1616
+ export interface LocaleReadOptions {
1617
+ /**
1618
+ * The target locale code (e.g. `'th'`), or `'raw'` to return the full
1619
+ * language map without resolution.
1620
+ */
1621
+ readonly locale?: string;
1622
+ /**
1623
+ * Fallback locale or ordered fallback chain. Use `'any'` as the last
1624
+ * element to fall back to any present translation.
1625
+ */
1626
+ readonly fallback?: string | readonly string[];
1627
+ /**
1628
+ * @internal — the resolution layer this read belongs to (`'read'` by
1629
+ * default). Threaded by layer-tagged read facades (guard / derivation)
1630
+ * so `applyI18nLocale` and dictKey `resolvePolicy` select that layer's
1631
+ * `onMissing` policy instead of the `'read'` policy. Not part of the
1632
+ * public read API — callers select policy via the field's `onMissing`
1633
+ * map, not by setting this.
1634
+ */
1635
+ readonly _layer?: Layer;
1636
+ }
1637
+ /**
1638
+ * Context passed to the consumer-supplied `plaintextTranslator` function.
1639
+ * The hook receives the source text plus enough metadata to route it to the
1640
+ * right translation service and record what it did.
1641
+ */
1642
+ export interface PlaintextTranslatorContext {
1643
+ /** The plaintext string to translate. */
1644
+ readonly text: string;
1645
+ /** BCP 47 source locale (the locale the text is written in). */
1646
+ readonly from: string;
1647
+ /** BCP 47 target locale to translate into. */
1648
+ readonly to: string;
1649
+ /** The schema field name that triggered the translation. */
1650
+ readonly field: string;
1651
+ /** The collection the record is being put into. */
1652
+ readonly collection: string;
1653
+ }
1654
+ /**
1655
+ * A consumer-supplied async function that translates a single string
1656
+ * from one locale to another. noy-db ships no built-in translator.
1657
+ *
1658
+ * **Security:** this function receives plaintext. The consumer is
1659
+ * responsible for the data policy of whatever service it calls. See
1660
+ * `NOYDB_SPEC.md § Zero-Knowledge Storage` and the `plaintextTranslator`
1661
+ * JSDoc on `NoydbOptions` for the full invariant statement.
1662
+ */
1663
+ export type PlaintextTranslatorFn = (ctx: PlaintextTranslatorContext) => Promise<string>;
1664
+ /**
1665
+ * One entry in the in-process translator audit log. Cleared when
1666
+ * `db.close()` is called — same lifetime as the KEK and DEKs.
1667
+ *
1668
+ * Deliberately omits any content hash or translated-text fingerprint
1669
+ * to prevent correlation attacks on the audit trail.
1670
+ */
1671
+ export interface TranslatorAuditEntry {
1672
+ readonly type: 'translator-invocation';
1673
+ /** Schema field name that was translated. */
1674
+ readonly field: string;
1675
+ /** Collection the record belongs to. */
1676
+ readonly collection: string;
1677
+ /** Source locale. */
1678
+ readonly fromLocale: string;
1679
+ /** Target locale. */
1680
+ readonly toLocale: string;
1681
+ /**
1682
+ * Consumer-provided translator name from
1683
+ * `NoydbOptions.plaintextTranslatorName`. Defaults to `'anonymous'`
1684
+ * when not supplied.
1685
+ */
1686
+ readonly translatorName: string;
1687
+ /** ISO 8601 timestamp of the invocation. */
1688
+ readonly timestamp: string;
1689
+ /**
1690
+ * `true` when the result was served from the in-process cache rather
1691
+ * than by calling the translator function. Present only on cache hits
1692
+ * so the absence of the field also communicates a cache miss.
1693
+ */
1694
+ readonly cached?: true;
1695
+ }
1696
+ /**
1697
+ * A presence peer entry. `lastSeen` is an ISO timestamp set by core on each
1698
+ * `update()` call. Stale entries (lastSeen older than `staleMs`) are filtered
1699
+ * before delivering to the subscriber callback.
1700
+ */
1701
+ export interface PresencePeer<P> {
1702
+ readonly userId: string;
1703
+ readonly payload: P;
1704
+ readonly lastSeen: string;
1705
+ }
1706
+ /** Per-collection CRDT mode. */
1707
+ export type CrdtMode = 'lww-map' | 'rga' | 'yjs';
1708
+ /**
1709
+ * Per-field last-write-wins registers.
1710
+ * Each field carries its latest value and the ISO timestamp of the last write.
1711
+ * Merge: for each field, keep the entry with the lexicographically higher `ts`.
1712
+ */
1713
+ export interface LwwMapState {
1714
+ readonly _crdt: 'lww-map';
1715
+ readonly fields: Record<string, {
1716
+ readonly v: unknown;
1717
+ readonly ts: string;
1718
+ }>;
1719
+ }
1720
+ /**
1721
+ * Simplified Replicated Growable Array.
1722
+ * Items are assigned stable NID (noy-db id) strings on first insertion.
1723
+ * Deleted items are tracked as tombstones so concurrent removals commute.
1724
+ *
1725
+ * The resolved snapshot is the ordered list of non-tombstoned `v` values.
1726
+ */
1727
+ export interface RgaState {
1728
+ readonly _crdt: 'rga';
1729
+ readonly items: ReadonlyArray<{
1730
+ readonly nid: string;
1731
+ readonly v: unknown;
1732
+ }>;
1733
+ readonly tombstones: readonly string[];
1734
+ }
1735
+ /**
1736
+ * Yjs binary state marker. `update` is base64(Y.encodeStateAsUpdate()).
1737
+ * Core stores and retrieves the blob opaquely. `@noy-db/yjs` is responsible
1738
+ * for encoding, decoding, and merging via `Y.mergeUpdates`.
1739
+ * Core falls back to last-write-wins (higher `_v`) for conflict resolution.
1740
+ */
1741
+ export interface YjsState {
1742
+ readonly _crdt: 'yjs';
1743
+ /** base64-encoded Y.encodeStateAsUpdate() bytes. */
1744
+ readonly update: string;
1745
+ }
1746
+ export type CrdtState = LwwMapState | RgaState | YjsState;
1747
+ /**
1748
+ * Seam interface. `@internal`.
1749
+ *
1750
+ * @internal
1751
+ */
1752
+ export interface CrdtStrategy {
1753
+ buildLwwMapState(record: Record<string, unknown>, previous: LwwMapState | undefined, now: string): LwwMapState;
1754
+ buildRgaState(items: readonly unknown[], previous: RgaState | undefined, idGen: () => string): RgaState;
1755
+ mergeCrdtStates(local: CrdtState, remote: CrdtState): CrdtState;
1756
+ resolveCrdtSnapshot(state: CrdtState): unknown;
1757
+ }
1758
+ /**
1759
+ * Second store shape for blob-store backends (Drive, WebDAV, Git, iCloud)
1760
+ * that operate on whole-vault bundles rather than per-record KV.
1761
+ *
1762
+ * Implement `readBundle` / `writeBundle` instead of the six-method KV
1763
+ * contract. Use `wrapBundleStore()` from `@noy-db/hub` to convert to a
1764
+ * `NoydbStore` that the rest of the API consumes transparently.
1765
+ *
1766
+ * Named `NoydbPodStore` (not `NoydbBundleAdapter`) for consistency
1767
+ * with the hub / to-* / in-* rename. Concrete implementations ship
1768
+ * in `@noy-db/to-*` packages starting in.
1769
+ */
1770
+ export interface NoydbPodStore {
1771
+ /** Discriminant for engine auto-detection of store shape. */
1772
+ readonly kind: 'bundle';
1773
+ /** Human-readable name for diagnostics (e.g. `'drive'`, `'webdav'`). */
1774
+ readonly name?: string;
1775
+ /**
1776
+ * Read the entire vault as raw bytes. Returns `null` if no bundle exists
1777
+ * yet (first open of a brand-new vault).
1778
+ */
1779
+ readBundle(vaultId: string): Promise<{
1780
+ bytes: Uint8Array;
1781
+ version: string;
1782
+ } | null>;
1783
+ /**
1784
+ * Write the entire vault as raw bytes. `expectedVersion` is the version
1785
+ * token from the last `readBundle` (or `null` for a first write).
1786
+ * Implementations MUST reject the write if the stored version has advanced
1787
+ * past `expectedVersion` — throw `PodVersionConflictError`.
1788
+ * Returns the new version token on success.
1789
+ */
1790
+ writeBundle(vaultId: string, bytes: Uint8Array, expectedVersion: string | null): Promise<{
1791
+ version: string;
1792
+ }>;
1793
+ /** Delete a vault bundle. Idempotent — no-op if the bundle does not exist. */
1794
+ deleteBundle(vaultId: string): Promise<void>;
1795
+ /** List all vault bundles managed by this store. */
1796
+ listBundles(): Promise<Array<{
1797
+ vaultId: string;
1798
+ version: string;
1799
+ size: number;
1800
+ }>>;
1801
+ }
1802
+ /** @deprecated Use `NoydbPodStore`. */
1803
+ export type NoydbBundleStore = NoydbPodStore;
1804
+ /**
1805
+ * Content-addressed blob object stored in the vault-level blob index.
1806
+ * Identified by HMAC-SHA-256(blobDEK, plaintext) — opaque to the store.
1807
+ *
1808
+ * Shared across all collections within a vault for deduplication: two
1809
+ * records that attach identical byte content reference the same `eTag`
1810
+ * and share a single set of encrypted chunks in `_blob_chunks`.
1811
+ */
1812
+ export interface BlobObject {
1813
+ /** HMAC-SHA-256 hex of the original plaintext bytes, keyed by `_blob` DEK. */
1814
+ readonly eTag: string;
1815
+ /** Original uncompressed size in bytes. */
1816
+ readonly size: number;
1817
+ /** Compressed size in bytes (the payload that is actually encrypted and chunked). */
1818
+ readonly compressedSize: number;
1819
+ /** Compression algorithm applied before encryption. */
1820
+ readonly compression: 'gzip' | 'none';
1821
+ /** Raw chunk size in bytes used at write time. Readers MUST use this value. */
1822
+ readonly chunkSize: number;
1823
+ /** Total number of chunks written. Reader expects exactly this many. */
1824
+ readonly chunkCount: number;
1825
+ /** MIME type if provided or auto-detected at upload time. */
1826
+ readonly mimeType?: string;
1827
+ /** ISO timestamp of first upload. */
1828
+ readonly createdAt: string;
1829
+ /** Live reference count — slots + published versions pointing to this blob. */
1830
+ readonly refCount: number;
1831
+ /**
1832
+ * Base64 AES-KW-wrapped per-blob **content CEK** (wrapped under the `_blob`
1833
+ * DEK). Present on erasable-collection blobs (`perRecordKeys`): the chunks
1834
+ * are encrypted under this content CEK rather than directly under the `_blob`
1835
+ * DEK, so deleting this BlobObject at `refCount → 0` crypto-shreds the chunks
1836
+ * (they become permanently undecryptable). Absent → legacy blob, chunks
1837
+ * decrypt directly under the `_blob` DEK (read unchanged). See
1838
+ * docs/superpowers/specs/2026-06-13-per-blob-cek-design.md.
1839
+ */
1840
+ readonly _cek?: string;
1841
+ /**
1842
+ * Transient migration marker. Present only while a legacy
1843
+ * blob is being migrated to a content CEK: it holds the wrapped content CEK
1844
+ * BEFORE the chunks have been re-encrypted under it. Readers **ignore**
1845
+ * `_cekPending` (they key off `_cek`), so the blob stays readable under the
1846
+ * `_blob` DEK during migration AND the content CEK survives a crash → a
1847
+ * re-run resumes and promotes `_cekPending` → `_cek`. Never set on a settled blob.
1848
+ */
1849
+ readonly _cekPending?: string;
1850
+ /**
1851
+ * Hint indicating which store holds the chunk data.
1852
+ * Used by `routeStore` size-tiered routing: `'default'` for small blobs
1853
+ * stored inline (e.g. DynamoDB), `'blobs'` for large blobs in the overflow
1854
+ * store (e.g. S3). Absent when no routing is configured.
1855
+ */
1856
+ readonly storeHint?: 'default' | 'blobs';
1857
+ /**
1858
+ * Bounded ring (K=8 — an AUDIT-VISIBLE concurrency bound, not an
1859
+ * implementation detail) of the most recent op-stamp identities applied to
1860
+ * this object's `refCount`. Appended in the SAME CAS write as the
1861
+ * `refCount` change it stamps (`BlobSet`'s `casUpdateRefCountStamped`),
1862
+ * never a separate write — no crash window between the two. Oldest entry
1863
+ * is evicted once the ring exceeds K entries.
1864
+ *
1865
+ * The blob durability journal (#753, spec §7 C2/C4) uses membership here
1866
+ * as its test-and-set: a stamped mutator re-reads this ring on every CAS
1867
+ * attempt (including retries) BEFORE computing its delta — stamp already
1868
+ * present → that mutation already landed → skip re-applying it. This is
1869
+ * what makes a crash-resumed refCount decrement/increment exactly-once
1870
+ * rather than at-least-once.
1871
+ *
1872
+ * Two acceptances, by design — SHRED only (see the #746 whole-branch
1873
+ * review correction below for rehome):
1874
+ * - **Eviction beyond K, for SHRED.** More than 8 distinct in-flight
1875
+ * stamped operations racing the SAME object between reads is far
1876
+ * outside any expected co-ownership fan-out; a 9th racer whose stamp
1877
+ * gets evicted before it re-reads can only double-apply an idempotent
1878
+ * CAS delta — never silently lose one (the DECREMENT delta is bounded
1879
+ * by the marker's authoritative captured `hold.n`, applied as ONE CAS
1880
+ * per eTag — never per-row — so eviction has nothing row-scoped to
1881
+ * re-apply against). Not a data-loss risk for shred, just a documented
1882
+ * concurrency bound.
1883
+ * - **Stale stamps on a retained object.** A `retainedShared` object (one
1884
+ * reference released, others still live) keeps whatever stamp its last
1885
+ * CAS write appended even after that operation's marker is gone —
1886
+ * harmless bookkeeping, not crypto material (unlike `_cek`), that sits
1887
+ * inert until the object's next CAS write evicts or overwrites it.
1888
+ *
1889
+ * **#746 whole-branch review correction — this ring is NOT the sole
1890
+ * idempotency source for REHOME.** Rehome's destination `+1`s are
1891
+ * ROW-SCOPED (`${opId}:${slotName}` / `${opId}:${versionKey}`, one stamp
1892
+ * PER CONTRIBUTING ROW, not one per eTag). Within a SINGLE op this ring is
1893
+ * sufficient — rows are processed sequentially and each row's referencing
1894
+ * update lands before the next row's `+1`, so a row whose stamp is later
1895
+ * evicted is already seen as "moved" (skipped) on resume, never
1896
+ * re-incremented. The genuine over-count is **concurrent independent ops**
1897
+ * (distinct `opId`s) converging on one shared destination: ≥8 of them can
1898
+ * evict a crashed op's row-stamp before it resumes, and a naive ring-only
1899
+ * resume would then double-apply that row's `+1` — a real, silent,
1900
+ * permanent-leak over-count, not merely eviction-tolerant like shred's.
1901
+ * `BlobIntent.appliedStamps` (`blob-intent.ts`) is rehome's ring-INDEPENDENT
1902
+ * backstop: an unbounded, per-op, per-record log of confirmed row-stamps,
1903
+ * consulted BEFORE this ring on every resume (see
1904
+ * `BlobSet.applyStampedIncrement`). This ring stays the fast first-line
1905
+ * check; `appliedStamps` makes correctness independent of ring eviction
1906
+ * **except** in one intrinsic non-atomic window: the destination `+1`/ring
1907
+ * write (A) and the `appliedStamps` append (B) are separate object writes,
1908
+ * A before B (deliberately — B-first could under-count and crypto-shred a
1909
+ * still-referenced object, i.e. data loss, strictly worse than a
1910
+ * retained-too-long leak). A crash BETWEEN A and B followed by ≥8 concurrent
1911
+ * evictions before resume can still over-count. This window is intrinsic
1912
+ * (rehome, unlike shred, cannot pre-capture destinations at mint time) and
1913
+ * fail-safe-directed; it is a documented residual (see the arc changeset).
1914
+ */
1915
+ readonly lastOps?: readonly string[];
1916
+ }
1917
+ /**
1918
+ * Slot record — mutable metadata linking a named slot on a record
1919
+ * to a `BlobObject` via its eTag.
1920
+ *
1921
+ * Multiple slots (even across different records) may reference the same
1922
+ * `eTag` — the underlying chunks are shared. Updating metadata creates
1923
+ * a new envelope version (`_v++`) while the blob data is unchanged.
1924
+ */
1925
+ export interface SlotRecord {
1926
+ /**
1927
+ * Reference to the `BlobObject` in `_blob_index` (chunk-based blobs).
1928
+ * Empty string (`''`) for an `external` slot, whose bytes live in the
1929
+ * `ObjectProjection` rather than `_blob_chunks` — read `external` instead.
1930
+ */
1931
+ readonly eTag: string;
1932
+ /**
1933
+ * External-projection reference. Present when the blob field is declared
1934
+ * `external`: the raw bytes live in the vault's `ObjectProjection` at `key`
1935
+ * (unencrypted), not in `_blob_chunks`. This slot record (in the encrypted
1936
+ * collection) remains the catalog entry — the anchoring invariant.
1937
+ */
1938
+ readonly external?: {
1939
+ readonly key: string;
1940
+ readonly contentType?: string;
1941
+ readonly public?: boolean;
1942
+ /** Opaque-token backlink stamped on the object (when `backlink:'opaque-token'`). */
1943
+ readonly backlink?: string;
1944
+ /**
1945
+ * Secondary metadata store synced from the object / its processing pipeline
1946
+ * (e.g. video `duration`, image `width`/`height`, arbitrary metatags).
1947
+ * Populated via `BlobSet.setExternalMeta()` — typically an AWS-side callback.
1948
+ */
1949
+ readonly meta?: Record<string, unknown>;
1950
+ };
1951
+ /** User-visible filename for the slot. */
1952
+ readonly filename: string;
1953
+ /** Original uncompressed size in bytes (denormalized from `BlobObject`). */
1954
+ readonly size: number;
1955
+ /** MIME type. Takes precedence over the MIME type stored in `BlobObject`. */
1956
+ readonly mimeType?: string;
1957
+ /** ISO timestamp of the upload that set this slot. */
1958
+ readonly uploadedAt: string;
1959
+ /** User ID of the uploader, if available. */
1960
+ readonly uploadedBy?: string;
1961
+ /**
1962
+ * Internal rehome-journal bookkeeping (#746 spec §7 review, carried
1963
+ * finding (b)) — NEVER part of the public `list()`/`SlotInfo` contract
1964
+ * (`BlobSet.list()` filters it out explicitly). Set, in the SAME CAS
1965
+ * write that points this slot at its new (rehomed) eTag, to the OLD eTag
1966
+ * still awaiting its refCount release: `putUnderDEK`'s slot-CAS and its
1967
+ * old-eTag release are two separate writes, and a crash between them
1968
+ * would otherwise lose the only record of which object still needs
1969
+ * releasing (the slot map itself has already moved past it) — a
1970
+ * permanent stranded-refcount leak. Cleared once the release lands.
1971
+ * Only ever set under a marker-governed (stamped) rehome; absent on
1972
+ * every ordinary `put()`.
1973
+ */
1974
+ readonly pendingRelease?: string;
1975
+ }
1976
+ /** Result of `BlobSet.list()` — slot record plus its named slot key. */
1977
+ export interface SlotInfo extends SlotRecord {
1978
+ /** The slot name (key in the record's slot map). */
1979
+ readonly name: string;
1980
+ }
1981
+ /**
1982
+ * Explicitly published version snapshot — an independent reference to a
1983
+ * blob at a specific point in time.
1984
+ */
1985
+ export interface VersionRecord {
1986
+ /** User-defined label (e.g. `'issued-2025-01'`, `'amendment-2025-02'`). */
1987
+ readonly label: string;
1988
+ /** eTag of the blob snapshot at publish time — independent of the current slot. */
1989
+ readonly eTag: string;
1990
+ /** ISO timestamp when the version was published. */
1991
+ readonly publishedAt: string;
1992
+ /** User ID of the publisher, if available. */
1993
+ readonly publishedBy?: string;
1994
+ }
1995
+ /** Options for `BlobSet.put()`. */
1996
+ export interface BlobPutOptions {
1997
+ /** MIME type hint. If omitted, auto-detected from magic bytes. */
1998
+ mimeType?: string;
1999
+ /**
2000
+ * Raw chunk size in bytes. Priority: this value > store.maxBlobBytes > 256 KB.
2001
+ */
2002
+ chunkSize?: number;
2003
+ /**
2004
+ * Whether to gzip-compress bytes before encrypting. Default: `true`.
2005
+ * Auto-set to `false` for pre-compressed MIME types (JPEG, PNG, ZIP, etc.).
2006
+ */
2007
+ compress?: boolean;
2008
+ /** User ID to record as `uploadedBy`. Defaults to the Noydb session user. */
2009
+ uploadedBy?: string;
2010
+ /**
2011
+ * User-visible filename to store on the slot. Defaults to the slot name.
2012
+ * Differs from the slot name when the caller wants a display/download name
2013
+ * (e.g. slot `attachment` holding `invoice-2024.pdf`); this is the value
2014
+ * that the L1 lexical index tokenizes for blob fields.
2015
+ */
2016
+ filename?: string;
2017
+ }
2018
+ /** Options for `BlobSet.response()` and `BlobSet.responseVersion()`. */
2019
+ export interface BlobResponseOptions {
2020
+ /**
2021
+ * When `true`, sets `Content-Disposition: inline; filename="..."` so
2022
+ * the browser renders the file in the tab. Default (`false`) sets
2023
+ * `attachment; filename="..."` which triggers a download.
2024
+ */
2025
+ inline?: boolean;
2026
+ /** Override the filename in the Content-Disposition header. */
2027
+ filename?: string;
2028
+ }
2029
+ export type StoreAuthKind = 'none' | 'filesystem' | 'api-key' | 'iam' | 'oauth' | 'kerberos' | 'browser-origin';
2030
+ export interface StoreAuth {
2031
+ kind: StoreAuthKind | StoreAuthKind[];
2032
+ required: boolean;
2033
+ flow: 'static' | 'oauth' | 'kerberos' | 'implicit';
2034
+ }
2035
+ /** Vendor-neutral short-lived store credentials. `kind` is the credential-PAYLOAD
2036
+ * discriminator — orthogonal to StoreAuthKind ('iam'|'api-key'|…), which is unchanged. */
2037
+ export type StoreCredentials = {
2038
+ readonly kind: 'aws';
2039
+ readonly accessKeyId: string;
2040
+ readonly secretAccessKey: string;
2041
+ readonly sessionToken?: string;
2042
+ readonly expiresAt?: string;
2043
+ } | {
2044
+ readonly kind: 'token';
2045
+ readonly token: string;
2046
+ readonly expiresAt?: string;
2047
+ };
2048
+ /** Refresh hook a store calls when it has no credentials or they are near expiry. */
2049
+ export type StoreCredentialSource = () => Promise<StoreCredentials>;
2050
+ /**
2051
+ * The store's authoritative clock as a bounded-uncertainty interval
2052
+ * (Spanner TrueTime model). True time is provably within [earliest, latest];
2053
+ * `latest - earliest` is the clock-uncertainty bound ε. Used by deferred
2054
+ * numbering to order records by store-commit-time and to commit-wait. Never
2055
+ * the client wall clock.
2056
+ */
2057
+ export interface StoreTime {
2058
+ readonly earliest: number;
2059
+ readonly latest: number;
2060
+ }
2061
+ export interface StoreCapabilities {
2062
+ /**
2063
+ * true — the store's expectedVersion check and write are atomic at the
2064
+ * storage layer. Two concurrent puts with the same expectedVersion will
2065
+ * produce exactly one success and one ConflictError.
2066
+ * false — check and write are separate operations with a race window.
2067
+ */
2068
+ casAtomic: boolean;
2069
+ /**
2070
+ * true — the store exposes an authoritative {@link NoydbStore.getStoreTime}
2071
+ * clock and records are ordered by store-commit-time. Required for
2072
+ * `withDeferredNumbering`. Absent/false — the store cannot back deferred
2073
+ * numbering (use CAS `sequence().next()` or per-series).
2074
+ */
2075
+ serverWriteTime?: boolean;
2076
+ /**
2077
+ * Advisory geographic region this store serves (e.g. `'eu'`, `'us'`).
2078
+ * Purely declarative — no behavior change for stores that omit it. The
2079
+ * federation data-residency guard compares this against a
2080
+ * `sharding.regionOf(record)` to refuse non-compliant shard placement.
2081
+ */
2082
+ region?: string;
2083
+ auth: StoreAuth;
2084
+ /**
2085
+ * true — the store implements {@link NoydbStore.tx} and commits
2086
+ * every op atomically at the storage layer. The hub's
2087
+ * `db.transaction(fn)` will delegate to `tx(ops)` and surface a
2088
+ * single pass/fail outcome. false (or absent) — no native
2089
+ * multi-record atomicity; the hub falls back to per-record OCC
2090
+ * with best-effort unwind on partial failure.
2091
+ */
2092
+ txAtomic?: boolean;
2093
+ /**
2094
+ * Maximum raw bytes per blob chunk record.
2095
+ * `undefined` — no limit (S3, file, IDB); blob stored as single chunk.
2096
+ * `256 * 1024` — DynamoDB (400 KB item limit minus envelope overhead).
2097
+ * `5 * 1024 * 1024` — localStorage quota safety.
2098
+ */
2099
+ maxBlobBytes?: number;
2100
+ /**
2101
+ * true — the store is a tiered router (`routeStore`) with a cold route,
2102
+ * so `compact(vault, { before })` can relocate records hot → cold and
2103
+ * reads fall through to cold. `vault.archivePeriod()` requires this.
2104
+ */
2105
+ coldArchival?: boolean;
2106
+ }
2107
+ export interface NoydbOptions {
2108
+ /** The ciphertext store. Optional — defaults to the built-in `memoryStore()` (non-persistent). */
2109
+ readonly store?: NoydbStore;
2110
+ /**
2111
+ * tree-shake seam — optional blob strategy. Pass `withBlobs()`
2112
+ * from `@noy-db/hub/blobs` to enable `collection.blob(id)` storage.
2113
+ * When omitted, hub's blob machinery stays out of the bundle (ESM
2114
+ * tree-shaking) and `collection.blob(id)` throws with a pointer at
2115
+ * the subpath. `BlobStrategy` is `@internal` — users only construct
2116
+ * it via the subpath factory.
2117
+ *
2118
+ * @internal
2119
+ */
2120
+ readonly blobStrategy?: BlobStrategy;
2121
+ /**
2122
+ * Cold-storage archival target. `withArchive({ store })` designates a
2123
+ * second store that holds archived record envelopes. Enables
2124
+ * `vault.archive()` / `vault.restore()` / `vault.listArchived()`.
2125
+ */
2126
+ readonly archiveStrategy?: ArchiveStrategy;
2127
+ /**
2128
+ * tree-shake seam — optional indexing strategy. Pass
2129
+ * `withIndexing()` from `@noy-db/hub/indexing` to enable eager-mode
2130
+ * `==/in` fast-paths, lazy-mode `.lazyQuery()`, rebuild/reconcile,
2131
+ * and auto-reconcile. When omitted, indexing code never reaches the
2132
+ * bundle; `.lazyQuery()` throws with a pointer at the subpath, and
2133
+ * eager-mode collections fall back to linear scans regardless of
2134
+ * `indexes: [...]` declarations. `IndexStrategy` is `@internal` —
2135
+ * users only construct it via the subpath factory.
2136
+ *
2137
+ * @internal
2138
+ */
2139
+ readonly indexStrategy?: IndexStrategy;
2140
+ /**
2141
+ * tree-shake seam — optional aggregate strategy. Pass
2142
+ * `withAggregate()` from `@noy-db/hub/aggregate` to enable
2143
+ * `.aggregate()` and `.groupBy()` on Query. When omitted, those
2144
+ * methods throw with a pointer at the subpath; the ~886 LOC of
2145
+ * Aggregation + GroupedQuery machinery never reaches the bundle.
2146
+ * Streaming `scan().aggregate()` works independently of this
2147
+ * strategy — it doesn't use the `Aggregation` class.
2148
+ *
2149
+ * @internal
2150
+ */
2151
+ readonly aggregateStrategy?: AggregateStrategy;
2152
+ /**
2153
+ * tree-shake seam — optional CRDT strategy. Required when
2154
+ * any collection is declared with `crdt: 'lww-map' | 'rga' | 'yjs'`;
2155
+ * otherwise the first put/sync-merge hitting the CRDT path throws.
2156
+ * When omitted, ~221 LOC of LWW-Map / RGA / merge helpers never
2157
+ * reach the bundle.
2158
+ *
2159
+ * @internal
2160
+ */
2161
+ readonly crdtStrategy?: CrdtStrategy;
2162
+ /**
2163
+ * tree-shake seam — strategy for the collection-level hierarchical-tier
2164
+ * operations. Pass `withTiers()` from `@noy-db/hub/tiers` to enable
2165
+ * `putAtTier`/`getAtTier`/`listAtTier`/`elevate`/`demote` on collections
2166
+ * declared with `{ tiers: [...] }`. When omitted, all five throw
2167
+ * `TiersNotEnabledError` and the tier read/write/re-key engine never
2168
+ * reaches the bundle.
2169
+ *
2170
+ * @internal
2171
+ */
2172
+ readonly tiersStrategy?: TiersStrategy;
2173
+ /**
2174
+ * tree-shake seam — optional consent-audit strategy. Pass
2175
+ * `withConsent()` from `@noy-db/hub/consent` to enable per-op audit
2176
+ * writes into `_consent_audit` when a consent scope is active.
2177
+ * When omitted, `vault.consentAudit()` returns `[]` and writes are
2178
+ * no-ops; the consent module's ~194 LOC never reaches the bundle.
2179
+ *
2180
+ * @internal
2181
+ */
2182
+ readonly consentStrategy?: ConsentStrategy;
2183
+ /**
2184
+ * tree-shake seam — optional periods strategy. Pass
2185
+ * `withPeriods()` from `@noy-db/hub/periods` to enable
2186
+ * `vault.closePeriod()` / `.openPeriod()` / write-guard on closed
2187
+ * periods. When omitted, `vault.listPeriods()` returns `[]` and
2188
+ * the write-guard is a no-op; the ~363 LOC of period validation +
2189
+ * ledger appending stay out of the bundle.
2190
+ *
2191
+ * @internal
2192
+ */
2193
+ readonly periodsStrategy?: PeriodsStrategy;
2194
+ /**
2195
+ * tree-shake seam — optional VaultFrame strategy. Pass
2196
+ * `withShadow()` from `@noy-db/hub/shadow` to enable
2197
+ * `vault.frame()`. Without it, calling `vault.frame()` throws.
2198
+ *
2199
+ * @internal
2200
+ */
2201
+ readonly shadowStrategy?: ShadowStrategy;
2202
+ /**
2203
+ * tree-shake seam — optional multi-record transactions. Pass
2204
+ * `withTransactions()` from `@noy-db/hub/tx` to enable
2205
+ * `db.transaction(fn)`. Without it, calling the method throws.
2206
+ *
2207
+ * @internal
2208
+ */
2209
+ readonly txStrategy?: TxStrategy;
2210
+ /**
2211
+ * tree-shake seam — optional history + ledger + time-machine.
2212
+ * Pass `withHistory()` from `@noy-db/hub/history` to enable
2213
+ * per-record version snapshots, the hash-chained audit ledger, JSON
2214
+ * Patch deltas, `vault.ledger()`, `vault.at()`, and the
2215
+ * `collection.history()` / `getVersion()` / `revert()` / `diff()` /
2216
+ * `clearHistory()` / `pruneRecordHistory()` read APIs. When omitted,
2217
+ * snapshots/prune/clear are silent no-ops, the read APIs throw with
2218
+ * a pointer at the subpath, and ~1,880 LOC stay out of the bundle.
2219
+ *
2220
+ * @internal
2221
+ */
2222
+ readonly historyStrategy?: HistoryStrategy;
2223
+ /**
2224
+ * GDPR right-to-erasure. Pass `withForgetCascade({ subjects })`
2225
+ * from `@noy-db/hub/forget` to declare which collections carry erasable
2226
+ * subject data and the record field naming the data subject. Enables
2227
+ * `vault.forget(subjectId)` crypto-shred (rewrite-to-tombstone of the live
2228
+ * record + every history version → body permanently undecryptable, single
2229
+ * `op:'forget'` ledger entry, chain still verifies). Each declared
2230
+ * collection is forced to `perRecordKeys: true`. When omitted (the
2231
+ * `NO_FORGET` default), `vault.forget()` throws
2232
+ * `ForgetStrategyNotConfiguredError` and no subject-index write hooks run.
2233
+ * Requires `historyStrategy` (the ledger) for the erasure-proof entry.
2234
+ */
2235
+ readonly forgetStrategy?: ForgetStrategy;
2236
+ /**
2237
+ * tree-shake seam — optional i18n strategy. Pass `withI18n()`
2238
+ * from `@noy-db/hub/i18n` to enable `i18nText`/`dictKey` field
2239
+ * resolution on reads, `i18nText` validation on writes, and
2240
+ * `vault.dictionary(name)`. When omitted, locale resolution is the
2241
+ * identity (raw values returned), the validators throw with a
2242
+ * pointer to the subpath, and ~854 LOC of dictionary + locale
2243
+ * machinery stay out of the bundle.
2244
+ *
2245
+ * @internal
2246
+ */
2247
+ readonly i18nStrategy?: I18nStrategy;
2248
+ /**
2249
+ * tree-shake seam — optional session-policy strategy. Pass
2250
+ * `withSession()` from `@noy-db/hub/session` to enable
2251
+ * `sessionPolicy` validation, `PolicyEnforcer` lifecycle (idle /
2252
+ * absolute timeouts, lockOnBackground), and global session-token
2253
+ * revocation. When omitted, setting `sessionPolicy` throws at
2254
+ * `createNoydb()` time, and ~495 LOC of policy + token machinery
2255
+ * stay out of the bundle.
2256
+ *
2257
+ * @internal
2258
+ */
2259
+ readonly sessionStrategy?: SessionStrategy;
2260
+ /**
2261
+ * tree-shake seam — optional sync engine + presence strategy.
2262
+ * Pass `withSync()` from `@noy-db/hub/sync` to enable
2263
+ * `db.push()` / `pull()` / replication, `db.transaction(vault)`
2264
+ * for sync-aware transactions, and `collection.presence()`. When
2265
+ * omitted, configuring `sync` / calling these surfaces throws with
2266
+ * a pointer at the subpath, and ~856 LOC of replication + presence
2267
+ * machinery stay out of the bundle. Keyring stays core; grant/
2268
+ * revoke/magic-link/delegation tree-shake via direct imports.
2269
+ *
2270
+ * @internal
2271
+ */
2272
+ readonly syncStrategy?: SyncStrategy;
2273
+ /**
2274
+ * Tree-shake seam — optional snapshot-lifecycle service. Pass
2275
+ * `withSnapshots({ store })` from `@noy-db/hub/snapshots` to enable
2276
+ * `db.snapshot()`, `db.listSnapshots()`, and `db.restoreSnapshot()`.
2277
+ * When omitted, all three methods throw with a pointer at the subpath.
2278
+ */
2279
+ readonly snapshotStrategy?: SnapshotStrategy;
2280
+ /**
2281
+ * Tree-shake seam — optional attestation capability. Pass
2282
+ * `withAttestation()` from `@noy-db/hub/attestation` to enable
2283
+ * `vault.issueAttestation()`, `vault.getDocumentSigningPublicKey()`,
2284
+ * `vault.revokeAttestation()`, `vault.unrevokeAttestation()`,
2285
+ * `vault.getRevokedDocIds()`, and `vault.publishRevocationList()`. When
2286
+ * omitted, all six throw `AttestationNotEnabledError` and the issue/revoke/
2287
+ * signer engines are tree-shaken out.
2288
+ */
2289
+ readonly attestationStrategy?: AttestationStrategy;
2290
+ /**
2291
+ * Tree-shake seam — optional classified-field capability. Pass
2292
+ * `withClassified()` from `@noy-db/hub/classified` to enable
2293
+ * `collection.reveal()`. When omitted, `reveal()` throws
2294
+ * `ClassifiedNotEnabledError` and the reveal engine is tree-shaken out.
2295
+ */
2296
+ readonly classifiedStrategy?: ClassifiedStrategy;
2297
+ /**
2298
+ * Tree-shake seam — optional sealed-record (grantor-side) capability. Pass
2299
+ * `withSealedRecord()` from `@noy-db/hub/sealed-record` to enable
2300
+ * `vault.sealRecordToHost()`, `vault.revokeSealedRecord()`, and
2301
+ * `vault.rotateRecordCek()`. When omitted, all three throw
2302
+ * `SealedRecordNotEnabledError` and the record-keys grantor engine is reached
2303
+ * only via opt-in. The host-side `openSealedRecord` opener stays ungated.
2304
+ */
2305
+ readonly sealedRecordStrategy?: SealedRecordStrategy;
2306
+ /**
2307
+ * Tree-shake seam — optional portability (data-sovereignty) capability. Pass
2308
+ * `withPortability()` from `@noy-db/hub/portability` to enable the
2309
+ * `vault.user.*` export/withdrawal surface (`exportMyAccessibleData`,
2310
+ * `unilateralWithdrawal`, `requestWithdrawal`, `listWithdrawalRequests`,
2311
+ * `approveWithdrawal`, `rejectWithdrawal`). When omitted, all six throw
2312
+ * `PortabilityNotEnabledError` and the export/withdraw/request engines are
2313
+ * reached only via opt-in.
2314
+ */
2315
+ readonly portabilityStrategy?: PortabilityStrategy;
2316
+ /**
2317
+ * Tree-shake seam — optional atomic-sequence capability. Pass
2318
+ * `withSequence()` from `@noy-db/hub` to enable `vault.sequence(name)`
2319
+ * (`.next()` / `.peek()` / `.seedTo()`). When omitted, `vault.sequence()`
2320
+ * throws `SequenceNotEnabledError` and the CAS `SequenceStore` engine is
2321
+ * reached only via opt-in. Deferred-numbering series (`numbering:
2322
+ * [withDeferredNumbering(...)]`) are a separate capability and stay live.
2323
+ */
2324
+ readonly sequenceStrategy?: SequenceStrategy;
2325
+ /**
2326
+ * Tree-shake seam — optional sovereign-custody (FR-6) capability. Pass
2327
+ * `withCustody()` from `@noy-db/hub` to enable minting / removing a
2328
+ * `custodian` (`db.grantCustodian` / `db.revokeCustodian` and the
2329
+ * `vault.custody.*` facade) plus the `vault.custody.liberate()` ceremony.
2330
+ * When omitted, those throw `CustodyNotEnabledError` and the liberate engine
2331
+ * is reached only via opt-in. The lower-level `liberateVault` free function
2332
+ * stays ungated (it has no createNoydb instance to gate against).
2333
+ */
2334
+ readonly custodyStrategy?: CustodyStrategy;
2335
+ /**
2336
+ * Tree-shake seam — optional multi-user team capability (#267
2337
+ * keyring-grant → team split). Pass `withTeam()` from `@noy-db/hub/team`
2338
+ * to enable `db.grant` / `db.revoke` / `db.rotate`. When omitted, those
2339
+ * throw `TeamNotEnabledError` and the keyring grant/revoke/rotate engines
2340
+ * are reached only via opt-in — the always-on floor is single-user.
2341
+ * Single-user primitives (owner keyring, unlock, `listUsers`,
2342
+ * `updateUser`, passphrase rotate/recover) stay ungated, as does the
2343
+ * `createDeedOwner` free function (no createNoydb instance to gate
2344
+ * against).
2345
+ */
2346
+ readonly teamStrategy?: TeamStrategy;
2347
+ /**
2348
+ * Tree-shake seam — optional credential-broker capability (#479). Pass
2349
+ * `brokerStrategy: withBroker(config)` from `@noy-db/hub/broker` to
2350
+ * enable `vault.broker()` (`.enroll()` / `.rotate()` /
2351
+ * `.credentialSource(profile?)`). When omitted, `vault.broker()` throws
2352
+ * `BrokerNotEnabledError` and the seed lifecycle + network/cache engine
2353
+ * are reached only via opt-in.
2354
+ */
2355
+ readonly brokerStrategy?: BrokerStrategy;
2356
+ /**
2357
+ * Opt-in seam — the `lazy` service (#267). Pass `withLazy()` from
2358
+ * `@noy-db/hub/lazy` to explicitly enable lazy mode's bounded-LRU
2359
+ * working set for collections declared with `prefetch: false`. When
2360
+ * omitted, `prefetch: false` still works via the deprecated implicit
2361
+ * back-compat path (identical behavior, one-time deprecation warn);
2362
+ * the implicit path will be removed at 1.0.
2363
+ */
2364
+ readonly lazyStrategy?: LazyStrategy;
2365
+ /**
2366
+ * Tree-shake seam — optional search / retrieval capability. Pass
2367
+ * `withSearch()` from `@noy-db/hub` to enable a collection's `search`
2368
+ * / `retrieve` / `similarTo` / `warmIndex` / `flushIndex` methods and the
2369
+ * put()-time embedding-vector compute for collections declaring `embeddings`.
2370
+ * When omitted, those throw `SearchNotEnabledError` and the search/retrieval
2371
+ * engine is reached only via opt-in. Embedding compute is paired with search
2372
+ * (a vector no gated retrieval could read would be dead weight).
2373
+ */
2374
+ readonly searchStrategy?: SearchStrategy;
2375
+ /**
2376
+ * Tree-shake seam — optional cargo (partition extraction) capability
2377
+ * (FR-6/FR-7). Pass `withCargo()` from `@noy-db/hub/cargo` to enable the
2378
+ * source-side `extractPartition(vault, …)` free function. When omitted, it
2379
+ * throws `CargoNotEnabledError` and the extraction crypto is reached only via
2380
+ * opt-in. The recipient-side `adoptPartition` / `decryptExtractedPartition`
2381
+ * free functions — and `diffVault` (shared import/merge infra) — operate
2382
+ * without a gated source instance and stay ungated.
2383
+ */
2384
+ readonly cargoStrategy?: CargoStrategy;
2385
+ /**
2386
+ * Optional guard strategies — collection-level write guards. Each
2387
+ * handle is the output of `withGuard()` from `@noy-db/hub/guards`.
2388
+ * Multiple guards per collection are allowed; they are dispatched
2389
+ * in registration order on `collection.put()`.
2390
+ */
2391
+ readonly guardStrategies?: ReadonlyArray<GuardStrategyHandleAny>;
2392
+ /**
2393
+ * Deferred-numbering series declared via `withDeferredNumbering(...)`.
2394
+ * `vault.sequence(series).next({ for })` then assigns gap-free serials at a
2395
+ * numbering pass (`vault.runNumberingPass(series)`) instead of via CAS.
2396
+ */
2397
+ readonly numbering?: ReadonlyArray<DeferredNumberingConfig>;
2398
+ /**
2399
+ * Optional derivation strategies — source-to-output projections that
2400
+ * fire on `collection.put()`. Each handle is the output of
2401
+ * `withDerivation()` from `@noy-db/hub/derivations`. The vault
2402
+ * validates the derivation graph for cycles on `openVault`; a cyclic
2403
+ * graph throws `DerivationCycleError`.
2404
+ */
2405
+ readonly derivationStrategies?: ReadonlyArray<DerivationStrategyHandle>;
2406
+ /**
2407
+ * Optional materialized-view strategies.
2408
+ * Each handle returned by `withMaterializedView()` from
2409
+ * `@noy-db/hub/materialized-views`. The vault runs unified cycle
2410
+ * detection across the MV + derivation graphs at `openVault`; a
2411
+ * cyclic graph throws `MaterializedViewCycleError`.
2412
+ */
2413
+ readonly materializedViewStrategies?: ReadonlyArray<MaterializedViewStrategyHandle>;
2414
+ /**
2415
+ * Optional overlay strategies. Each handle returned by
2416
+ * `withOverlayedView()` from `@noy-db/hub/overlay-views`. The vault
2417
+ * validates name uniqueness + base concreteness + overlay
2418
+ * availability at `openVault`; a clash throws one of the
2419
+ * `Overlay*Error` family.
2420
+ */
2421
+ readonly overlayedViewStrategies?: ReadonlyArray<OverlayedViewStrategyHandle>;
2422
+ /** Optional remote store(s) for sync. Accepts a single store, a SyncTarget, or an array. */
2423
+ readonly sync?: NoydbStore | SyncTarget | SyncTarget[];
2424
+ /** User identifier. */
2425
+ readonly user: string;
2426
+ /** Passphrase for key derivation. Required unless encrypt is false or `getKeyring` is provided. */
2427
+ readonly secret?: string;
2428
+ /**
2429
+ * Optional callback that returns an unlocked keyring for a given vault.
2430
+ * Use this to plug in WebAuthn / OIDC / Shamir / any unlock path that
2431
+ * produces an `UnlockedKeyring` outside the passphrase model.
2432
+ *
2433
+ * When set, `secret` MUST NOT also be set — `createNoydb` throws if both
2434
+ * are supplied. When neither is set (and `encrypt !== false`), `createNoydb`
2435
+ * also throws.
2436
+ *
2437
+ * The callback is called lazily, on the first operation that needs the
2438
+ * keyring for a given vault. Noydb caches the returned keyring per-vault
2439
+ * for the lifetime of the instance, so the callback is invoked at most
2440
+ * once per `(instance, vault)` pair (assuming the callback resolves
2441
+ * successfully). If the callback rejects, the rejection surfaces from the
2442
+ * first vault operation that triggered the unlock; subsequent operations
2443
+ * will retry the callback.
2444
+ *
2445
+ * @example
2446
+ * ```ts
2447
+ * import { createNoydb } from '@noy-db/hub'
2448
+ * import { unlockWebAuthn } from '@noy-db/on-webauthn'
2449
+ *
2450
+ * const enrollment = await loadEnrollment()
2451
+ * const db = await createNoydb({
2452
+ * store,
2453
+ * user: 'alice',
2454
+ * getKeyring: (vault) => unlockWebAuthn(enrollment),
2455
+ * })
2456
+ * ```
2457
+ *
2458
+ * Note: this callback is responsible for both the "open existing vault"
2459
+ * and the "create new vault" cases. Unlike the passphrase path, there is
2460
+ * no automatic `NoAccessError` → `createOwnerKeyring` fallback, because
2461
+ * the callback owner has the UI context to decide which path to run.
2462
+ * For first-time bootstrap, use a passphrase or recovery code, enroll
2463
+ * WebAuthn from the unlocked keyring, then swap to `getKeyring` on
2464
+ * subsequent sessions.
2465
+ */
2466
+ readonly getKeyring?: (vault: string) => Promise<UnlockedKeyring>;
2467
+ /**
2468
+ * Passphrase mode. Default `'standard'`.
2469
+ *
2470
+ * - `'standard'` — the legacy flow. `secret` supplies the
2471
+ * plaintext passphrase, the user knows it, and the policy gate
2472
+ * `rotate-passphrase` is enabled.
2473
+ * - `'managed'` — rubber-hose-resistant mode. Hub generates a
2474
+ * 256-bit random passphrase at first open and seals it under
2475
+ * the provided `sealingKey`. The user never sees or types the
2476
+ * passphrase, defeating the $5-wrench attack. Mutually
2477
+ * exclusive with `secret` and `getKeyring`.
2478
+ *
2479
+ * @see https://github.com/vLannaAi/noy-db-docs/blob/main/content/docs/services/session-tiers.md → Managed-passphrase mode
2480
+ */
2481
+ readonly passphraseMode?: 'standard' | 'managed';
2482
+ /**
2483
+ * Provider that seals/unseals the auto-generated managed-mode
2484
+ * passphrase. Required when `passphraseMode === 'managed'`; ignored
2485
+ * otherwise. Implementations live in per-platform packages
2486
+ * (`@noy-db/seal-macos-keychain`, `@noy-db/seal-wincred`,
2487
+ * `@noy-db/seal-libsecret`, `@noy-db/seal-aws-kms`, …).
2488
+ */
2489
+ readonly sealingKey?: SealingKeyProvider;
2490
+ /** Required to use `profile: 'shamir'` recovery. Pass
2491
+ * `shamirRecoveryProvider()` from `@noy-db/on-shamir`. */
2492
+ readonly shamirRecovery?: ShamirRecoveryProvider;
2493
+ /** Auth method. Default: 'passphrase'. */
2494
+ readonly auth?: 'passphrase' | 'biometric';
2495
+ /** Enable encryption. Default: true. */
2496
+ readonly encrypt?: boolean;
2497
+ /**
2498
+ * Debug-only: lay plaintext records out as directly-inspectable store
2499
+ * objects (record fields inlined beside envelope metadata, `_debug: 1`) so
2500
+ * native store tooling can read them without unwrapping `_data`. Requires
2501
+ * `encrypt: false` — combining with encryption throws `DebugPlaintextError`
2502
+ * at construction. NEVER enable for production or client data.
2503
+ */
2504
+ readonly debugPlaintext?: boolean;
2505
+ /**
2506
+ * Object projection for direct-serve / external blob fields (`as-*`, e.g.
2507
+ * `@noy-db/as-aws-s3`). Blob fields declared `external` route their RAW bytes
2508
+ * to this projection as a single native object (servable from S3/CDN) instead
2509
+ * of the encrypted-chunk path; the encrypted record/slot stays the catalog.
2510
+ * Sees plaintext bytes — outside the zero-knowledge guarantee.
2511
+ */
2512
+ readonly objectStore?: ObjectProjection;
2513
+ /** Conflict resolution strategy. Default: 'version'. */
2514
+ readonly conflict?: ConflictStrategy;
2515
+ /**
2516
+ * Sync scheduling policy. Controls when push/pull fire.
2517
+ * Default inferred from store category: per-record → `on-change`,
2518
+ * bundle → `debounce 30s`.
2519
+ */
2520
+ readonly syncPolicy?: SyncPolicy;
2521
+ /**
2522
+ * @deprecated Use `syncPolicy` instead. Kept for backward compatibility.
2523
+ * When both are supplied, `syncPolicy` takes precedence.
2524
+ */
2525
+ readonly autoSync?: boolean;
2526
+ /**
2527
+ * @deprecated Use `syncPolicy` instead. Kept for backward compatibility.
2528
+ */
2529
+ readonly syncInterval?: number;
2530
+ /**
2531
+ * Session timeout in ms. Clears keys after inactivity. Default: none.
2532
+ * @deprecated Use `sessionPolicy.idleTimeoutMs` instead. This field is
2533
+ * still honored for backwards compatibility but `sessionPolicy` takes
2534
+ * precedence when both are supplied.
2535
+ */
2536
+ readonly sessionTimeout?: number;
2537
+ /**
2538
+ * Session policy controlling lifetime, re-auth requirements, and
2539
+ * background-lock behavior. When supplied, replaces the
2540
+ * legacy `sessionTimeout` field.
2541
+ */
2542
+ readonly sessionPolicy?: SessionPolicy;
2543
+ /**
2544
+ * Validate passphrase strength against the phrase format
2545
+ * on first-time keyring creation. When
2546
+ * `true`, weak phrases throw {@link WeakPassphraseError} from
2547
+ * `createNoydb()` / `db.rotatePassphrase()`. Default: `false` for
2548
+ * back-compat; planned to flip to `true` in a future major release.
2549
+ */
2550
+ readonly validatePassphrase?: boolean;
2551
+ /**
2552
+ * Vault-level policy gate document. When present, the hub
2553
+ * persists the merged policy at `_meta/policy` on first-time vault
2554
+ * creation and gates sensitive operations (`db.rotatePassphrase`,
2555
+ * `db.export*`, …) against it. Omitted ⇒ the engine uses
2556
+ * {@link PERSONAL_POLICY}. Use {@link STRICT_POLICY} for regulated
2557
+ * deployments.
2558
+ *
2559
+ * The on-disk document is the source of truth — the policy field
2560
+ * is only honored at vault creation; subsequent runs read from
2561
+ * `_meta/policy`. Use `db.updatePolicy()` to change it deliberately.
2562
+ *
2563
+ * Imported from `@noy-db/hub` as a type-only reference; the runtime
2564
+ * import lives in `policy/index.ts`.
2565
+ */
2566
+ readonly policy?: VaultPolicy;
2567
+ /**
2568
+ * Mandatory recovery profile enrollment. Vaults with
2569
+ * `recover-passphrase` enabled MUST register at least one profile
2570
+ * before being production-ready, otherwise `createNoydb()` throws
2571
+ * {@link RecoveryNotEnrolledError}. Set
2572
+ * `policy.gates['recover-passphrase'].enabled = false` to
2573
+ * deliberately opt out of recovery (passphrase loss = data loss).
2574
+ *
2575
+ * The `'paper'` profile is supported end-to-end. Other
2576
+ * profiles ship the API shape and throw
2577
+ * {@link RecoveryProfileNotImplementedError} during use.
2578
+ */
2579
+ readonly recovery?: ReadonlyArray<RecoveryEnrollment>;
2580
+ /**
2581
+ * When `true`, `createNoydb` rejects vaults with no recovery
2582
+ * entries persisted (per the spec's mandatory-enrollment
2583
+ * requirement). Default `false` for back-compat; planned to
2584
+ * flip to `true` in a future major release. Apps in regulated
2585
+ * environments should turn this on now.
2586
+ */
2587
+ readonly requireRecovery?: boolean;
2588
+ /**
2589
+ * What to do when `openVault` finds an existing keyring in the store that
2590
+ * cannot be decrypted with the supplied credentials (`InvalidKeyError`).
2591
+ *
2592
+ * - `'error'` (default) — propagate the error. The app must prompt the user
2593
+ * to supply the correct credentials or clear both the data and auth stores.
2594
+ * - `'reset'` — delete the stale keyring and re-initialise the vault from
2595
+ * scratch using the current credentials. Use this when the data store can
2596
+ * become detached from the auth store (e.g. the user cleared the IndexedDB
2597
+ * data records but not the keyring row, or a WebAuthn credential was rotated).
2598
+ * **All previously encrypted data is unrecoverable after a reset.**
2599
+ *
2600
+ * Only applies to the passphrase (`secret`) path. When `getKeyring` is used,
2601
+ * the callback is responsible for handling stale-keyring detection itself.
2602
+ */
2603
+ readonly onInvalidKey?: 'error' | 'reset';
2604
+ /**
2605
+ * Enable the public envelope service (`https://github.com/vLannaAi/noy-db-docs/blob/main/content/docs/services/public-envelope.md`).
2606
+ * Pass `true` for the default schema (every standard field, 256 KB
2607
+ * icon cap, 200-char text cap), or a `PublicEnvelopeSchema` to
2608
+ * narrow what the owner can set. Off by default — vaults written
2609
+ * by hubs without this option carry no envelope, full stop.
2610
+ */
2611
+ readonly publicEnvelope?: true | PublicEnvelopeSchema;
2612
+ /** Audit history configuration. */
2613
+ readonly history?: HistoryConfig;
2614
+ /**
2615
+ * Consumer-supplied translation function for `i18nText` fields with
2616
+ * `autoTranslate: true`.
2617
+ *
2618
+ * ⚠ **`plaintextTranslator` receives unencrypted text.** Configuring
2619
+ * this hook causes plaintext to leave noy-db's zero-knowledge boundary
2620
+ * over whatever channel the consumer's implementation uses. noy-db ships
2621
+ * no built-in translator and adds no translator SDKs as dependencies.
2622
+ * The consumer chooses and owns the data policy of the external service.
2623
+ *
2624
+ * Per-field opt-in via `autoTranslate: true` on `i18nText()`. Calling
2625
+ * `put()` on a collection with `autoTranslate: true` fields while this
2626
+ * option is absent throws `TranslatorNotConfiguredError`.
2627
+ *
2628
+ * See `NOYDB_SPEC.md § Zero-Knowledge Storage` for the invariant text.
2629
+ */
2630
+ readonly plaintextTranslator?: PlaintextTranslatorFn;
2631
+ /**
2632
+ * Human-readable name for the translator, recorded in the in-process
2633
+ * audit log (e.g. `'deepl-pro-with-dpa'`, `'self-hosted-llama-7b'`).
2634
+ * Defaults to `'anonymous'` when not supplied.
2635
+ */
2636
+ readonly plaintextTranslatorName?: string;
2637
+ /**
2638
+ * Drain-barrier coordination transport for the schema fence.
2639
+ * When omitted, the kernel uses a {@link CoordinationProvider} backed by the
2640
+ * primary store (`StoreCoordinationProvider`), reproducing today's
2641
+ * store-polling fence behavior byte-for-byte. `@noy-db/by-tabs` /
2642
+ * `@noy-db/by-peer` inject a real-time push transport here; an external
2643
+ * orchestrator (`@klum-db/lobby`) drives it through the `Noydb` handle.
2644
+ *
2645
+ * @internal
2646
+ */
2647
+ readonly coordinationStrategy?: CoordinationProvider;
2648
+ /**
2649
+ * Pre-resolved factory for the `vault.user` per-principal user-envelope
2650
+ * API. `createNoydb()` always resolves this itself (dynamically
2651
+ * importing `with-party/directory/user-envelope/api.js`) before
2652
+ * constructing `Noydb` — mirrors the {@link coordinationStrategy}
2653
+ * pre-resolve above. There is no supported way to override it; it exists
2654
+ * as an options-bag field only so `createNoydb()` can thread the
2655
+ * pre-resolved value into the constructor without a second parameter.
2656
+ *
2657
+ * @internal
2658
+ */
2659
+ readonly userApiFactory?: UserApiFactory;
2660
+ /**
2661
+ * Pre-resolved factory for the `NoydbPolicy` service (vault-policy
2662
+ * read/update/bootstrap + session-policy enforcer wiring).
2663
+ * `createNoydb()` always resolves this itself (dynamically importing
2664
+ * `with-party/policy/index.js`) before constructing `Noydb` — mirrors the
2665
+ * {@link coordinationStrategy} / {@link userApiFactory} pre-resolves
2666
+ * above. There is no supported way to override it.
2667
+ *
2668
+ * @internal
2669
+ */
2670
+ readonly policyFactory?: NoydbPolicyFactory;
2671
+ /**
2672
+ * Pre-resolved policy-gate engine function (`checkGate`).
2673
+ * `createNoydb()` always resolves this itself (dynamically importing
2674
+ * `with-party/policy/index.js`) before constructing `Noydb` — same
2675
+ * pre-resolve pattern as {@link policyFactory}.
2676
+ *
2677
+ * @internal
2678
+ */
2679
+ readonly policyCheckGateFn?: PolicyCheckGateFn;
2680
+ /**
2681
+ * Stable id for the session that owns this instance's writers (one user's
2682
+ * writers across vaults). Tags every {@link WriterPresence} the fence
2683
+ * watcher reports. Defaults to a fresh ULID per `Noydb` instance.
2684
+ *
2685
+ * @internal
2686
+ */
2687
+ readonly sessionId?: string;
2688
+ }
2689
+ /** History configuration. */
2690
+ export interface HistoryConfig {
2691
+ /** Enable history tracking. Default: true. */
2692
+ readonly enabled?: boolean;
2693
+ /** Maximum history entries per record. Oldest pruned on overflow. Default: unlimited. */
2694
+ readonly maxVersions?: number;
2695
+ /**
2696
+ * Participate in the vault-wide hash-chained tamper ledger. Default:
2697
+ * `true` (every write of this collection appends a ledger entry when
2698
+ * `withHistory()` is active). Set `false` to exclude this collection's
2699
+ * writes from the chain — its puts/deletes leave no ledger entry,
2700
+ * confining tamper-evidence to the collections where it carries weight.
2701
+ * Independent of `enabled`, which gates per-record snapshots. Has no
2702
+ * effect when `withHistory()` is not active (there is no ledger).
2703
+ */
2704
+ readonly ledger?: boolean;
2705
+ }
2706
+ /** Options for querying history. */
2707
+ export interface HistoryOptions {
2708
+ /** Start date (inclusive), ISO 8601. */
2709
+ readonly from?: string;
2710
+ /** End date (inclusive), ISO 8601. */
2711
+ readonly to?: string;
2712
+ /** Maximum entries to return. */
2713
+ readonly limit?: number;
2714
+ }
2715
+ /** Options for pruning history. */
2716
+ export interface PruneOptions {
2717
+ /** Keep only the N most recent versions. */
2718
+ readonly keepVersions?: number;
2719
+ /** Delete versions older than this date, ISO 8601. */
2720
+ readonly beforeDate?: string;
2721
+ }
2722
+ /** A decrypted history entry. */
2723
+ export interface HistoryEntry<T> {
2724
+ readonly version: number;
2725
+ readonly timestamp: string;
2726
+ readonly userId: string;
2727
+ readonly record: T;
2728
+ }
2729
+ /** Per-item options for `Collection.putMany()`. */
2730
+ export interface PutManyItemOptions {
2731
+ /**
2732
+ * Optimistic-concurrency check: fail this item if the stored version
2733
+ * is not `expectedVersion`. Honored only in `atomic: true` mode;
2734
+ * ignored in the default best-effort loop.
2735
+ */
2736
+ readonly expectedVersion?: number;
2737
+ }
2738
+ /**
2739
+ * Batch-level options for `Collection.putMany()` and `deleteMany()`.
2740
+ *
2741
+ * `atomic: true` switches the call from best-effort loop
2742
+ * to all-or-nothing: a pre-flight CAS check runs first, then every op
2743
+ * is executed; any mid-batch failure triggers a best-effort revert.
2744
+ * On failure in atomic mode the whole call throws — you won't get a
2745
+ * partial `PutManyResult`. On success the result mirrors the default
2746
+ * loop's shape.
2747
+ */
2748
+ export interface PutManyOptions {
2749
+ readonly atomic?: boolean;
2750
+ }
2751
+ /** Result of `Collection.putMany()`. */
2752
+ export interface PutManyResult {
2753
+ /** `true` iff every entry succeeded. */
2754
+ readonly ok: boolean;
2755
+ /** IDs that were successfully written. */
2756
+ readonly success: readonly string[];
2757
+ /** Entries that failed, with the error that prevented each write. */
2758
+ readonly failures: ReadonlyArray<{
2759
+ readonly id: string;
2760
+ readonly error: Error;
2761
+ }>;
2762
+ }
2763
+ /** Result of `Collection.deleteMany()`. Same shape as `PutManyResult`. */
2764
+ export interface DeleteManyResult {
2765
+ readonly ok: boolean;
2766
+ readonly success: readonly string[];
2767
+ readonly failures: ReadonlyArray<{
2768
+ readonly id: string;
2769
+ readonly error: Error;
2770
+ }>;
2771
+ }
2772
+ /**
2773
+ * Thin reader view of a user envelope. The on-disk shape is the standard
2774
+ * {@link EncryptedEnvelope}; this is what callers see after the storage
2775
+ * layer has decrypted the payload.
2776
+ *
2777
+ * Hub commits to the `keyringId` ⇔ `userId` identity and the `_v` / `_ts`
2778
+ * envelope metadata. The `data` payload is fully app-defined — hub does
2779
+ * not introspect, validate, or reserve any keys inside it.
2780
+ */
2781
+ export interface UserEnvelope<T> {
2782
+ /** The principal id this envelope belongs to. Equals the keyring `user_id`. */
2783
+ readonly keyringId: string;
2784
+ /** App-owned payload. Opaque to hub. */
2785
+ readonly data: T;
2786
+ /** Optimistic-concurrency version. Increments on every write. */
2787
+ readonly _v: number;
2788
+ /** ISO timestamp of the last write. */
2789
+ readonly _ts: string;
2790
+ }
2791
+ /**
2792
+ * Recursive partial. Used for `updateMe(patch)` so callers can hand in
2793
+ * deeply-nested partial shapes and have them deep-merged onto the
2794
+ * current envelope.
2795
+ */
2796
+ export type DeepPartial<T> = T extends object ? {
2797
+ [P in keyof T]?: DeepPartial<T[P]>;
2798
+ } : T;
2799
+ /**
2800
+ * Recursive partial with `null` allowed at every level — used by
2801
+ * `updateMe` to express deletion intent in addition to merge.
2802
+ *
2803
+ * Semantics inside `updateMe`:
2804
+ * - `undefined` (or absent key) — skip; source value preserved
2805
+ * - `null` — delete the key from the resulting envelope
2806
+ * - any other value — overwrite (deep-merge for plain objects,
2807
+ * replace for primitives / arrays)
2808
+ *
2809
+ * Matches lodash `_.merge` behavior on `null` and Firestore's
2810
+ * `FieldValue.delete()` semantics. Loosened from `DeepPartial<T>`.
2811
+ * Consumers wanting the original "merge-only" surface can keep
2812
+ * importing `DeepPartial` and avoid passing `null`.
2813
+ */
2814
+ export type DeepPartialOrNull<T> = T extends object ? {
2815
+ [P in keyof T]?: DeepPartialOrNull<T[P]> | null;
2816
+ } : T;
2817
+ /** Cancel a previously-registered subscription. */
2818
+ export type Unsubscribe = () => void;
2819
+ /**
2820
+ * Optional factor-proof bundle threaded into gated user-envelope
2821
+ * operations. Same shape as `Noydb.checkGate(vault, gate, presented)`
2822
+ * accepts elsewhere — apps that have already presented a TOTP/email-OTP
2823
+ * for this session pass it here to satisfy tightened policies.
2824
+ */
2825
+ export interface UserEnvelopePresented {
2826
+ readonly factors?: readonly FactorProof[];
2827
+ readonly sharedDevice?: boolean;
2828
+ }
2829
+ /**
2830
+ * Callback used by `UserApi` to validate the active session against a
2831
+ * policy gate. Provided by the `Vault` constructor; in production this
2832
+ * delegates to `Noydb.checkGate(vault, gate, presented)`. In tests, a
2833
+ * no-op stub is fine.
2834
+ */
2835
+ export type UserEnvelopeCheckGate = (gate: 'edit-own-profile' | 'view-team-profiles' | 'client-unilateral-withdraw' | 'user-request-withdrawal' | 'approve-user-withdrawal', presented?: UserEnvelopePresented) => Promise<void>;
2836
+ /**
2837
+ * Reactive handle returned by `live()`. `current` is the most recently
2838
+ * observed value; `subscribe(cb)` fires on subsequent local writes.
2839
+ * `stop()` releases the underlying subscription.
2840
+ */
2841
+ export interface LiveUserEnvelope<T> {
2842
+ current(): UserEnvelope<T> | null;
2843
+ subscribe(cb: (env: UserEnvelope<T> | null) => void): Unsubscribe;
2844
+ stop(): void;
2845
+ }
2846
+ /**
2847
+ * The 2nd positional parameter of a {@link PortabilityStrategy} method
2848
+ * (index 1, right after the leading `vault` argument).
2849
+ */
2850
+ type PortabilityParam1<K extends keyof PortabilityStrategy> = Parameters<PortabilityStrategy[K]>[1];
2851
+ /**
2852
+ * The 3rd positional parameter (index 2) — only present on
2853
+ * `approveWithdrawal` / `rejectWithdrawal` (requestId is index 1 there).
2854
+ */
2855
+ type PortabilityParam2<K extends keyof PortabilityStrategy> = Parameters<PortabilityStrategy[K]>[2];
2856
+ type PortabilityReturn<K extends keyof PortabilityStrategy> = ReturnType<PortabilityStrategy[K]>;
2857
+ /**
2858
+ * Public `vault.user.*` API surface — the CONTRACT. The implementation
2859
+ * (`UserApi`) lives at `with-party/directory/user-envelope/api.ts` and
2860
+ * `implements` this interface; `createNoydb()` wires it in via the
2861
+ * pre-resolved {@link UserApiFactory}.
2862
+ *
2863
+ * Three families:
2864
+ * - Write-self: `me` / `updateMe` / `setMe` — always target the writer's
2865
+ * own keyringId. **Own-only write rule** is structural — no method
2866
+ * exists to write someone else's envelope.
2867
+ * - Read-anyone: `get` / `list` — read other principals' envelopes
2868
+ * (subject to `view-team-profiles` policy gate).
2869
+ * - Reactive: `subscribe` / `live` — in-process event emission on local
2870
+ * writes. Cross-instance updates land via the team/sync engine and
2871
+ * surface to subscribers when the sync diff replays through this API.
2872
+ *
2873
+ * @see docs/superpowers/specs/2026-05-05-user-envelope-design.md
2874
+ */
2875
+ export interface VaultUserApi {
2876
+ requestWithdrawal(opts?: PortabilityParam1<'requestWithdrawal'>): PortabilityReturn<'requestWithdrawal'>;
2877
+ listWithdrawalRequests(opts?: PortabilityParam1<'listWithdrawalRequests'>): PortabilityReturn<'listWithdrawalRequests'>;
2878
+ approveWithdrawal(requestId: PortabilityParam1<'approveWithdrawal'>, opts?: PortabilityParam2<'approveWithdrawal'>): PortabilityReturn<'approveWithdrawal'>;
2879
+ rejectWithdrawal(requestId: PortabilityParam1<'rejectWithdrawal'>, opts?: PortabilityParam2<'rejectWithdrawal'>): PortabilityReturn<'rejectWithdrawal'>;
2880
+ unilateralWithdrawal(opts: PortabilityParam1<'withdrawAccessibleData'>): PortabilityReturn<'withdrawAccessibleData'>;
2881
+ exportMyAccessibleData(opts?: PortabilityParam1<'exportAccessibleData'>): PortabilityReturn<'exportAccessibleData'>;
2882
+ me<T = unknown>(): Promise<UserEnvelope<T> | null>;
2883
+ updateMe<T extends object = Record<string, unknown>>(patch: DeepPartialOrNull<T>, presented?: UserEnvelopePresented): Promise<UserEnvelope<T>>;
2884
+ setMe<T = unknown>(payload: T, presented?: UserEnvelopePresented): Promise<UserEnvelope<T>>;
2885
+ getMyVisibility(): Promise<{
2886
+ readonly hidden: boolean;
2887
+ }>;
2888
+ setMyVisibility(visibility: {
2889
+ readonly hidden: boolean;
2890
+ }): Promise<void>;
2891
+ get<T = unknown>(keyringId: string, presented?: UserEnvelopePresented): Promise<UserEnvelope<T> | null>;
2892
+ list<T = unknown>(presented?: UserEnvelopePresented): Promise<UserEnvelope<T>[]>;
2893
+ subscribe<T = unknown>(keyringId: string, cb: (env: UserEnvelope<T> | null) => void): Unsubscribe;
2894
+ live<T = unknown>(keyringId: string): LiveUserEnvelope<T>;
2895
+ }
2896
+ /**
2897
+ * Constructor dependencies for `UserApi` (the {@link VaultUserApi}
2898
+ * implementation). Built by `Vault`'s constructor and passed to the
2899
+ * pre-resolved {@link UserApiFactory}.
2900
+ */
2901
+ export interface UserApiDeps {
2902
+ readonly adapter: NoydbStore;
2903
+ readonly vaultName: string;
2904
+ /** The writer's own keyringId. Frozen at construction time. */
2905
+ readonly writerKeyringId: string;
2906
+ readonly getDek: () => Promise<EnclaveKey>;
2907
+ /**
2908
+ * Policy-gate validator. When omitted, gates are skipped — useful
2909
+ * for low-level tests that exercise the storage layer directly.
2910
+ * Production paths always wire the Noydb-backed implementation.
2911
+ */
2912
+ readonly checkGate?: UserEnvelopeCheckGate;
2913
+ /**
2914
+ * Noydb-backed `exportMyAccessibleData`, injected by the Vault
2915
+ * (which holds the keyring + bundle machinery). Omitted in low-level tests.
2916
+ */
2917
+ readonly exportAccessible?: (opts: PortabilityParam1<'exportAccessibleData'>) => PortabilityReturn<'exportAccessibleData'>;
2918
+ /**
2919
+ * Noydb-backed `unilateralWithdrawal`, injected by the Vault.
2920
+ * Destructive — extract + dispose (delete | freeze). Omitted in low-level tests.
2921
+ */
2922
+ readonly unilateralWithdraw?: (opts: PortabilityParam1<'withdrawAccessibleData'>) => PortabilityReturn<'withdrawAccessibleData'>;
2923
+ /**
2924
+ * Noydb-backed two-party withdrawal ceremony, injected by the
2925
+ * Vault. requestWithdraw = requester side; the rest = owner side.
2926
+ */
2927
+ readonly requestWithdraw?: (opts: PortabilityParam1<'requestWithdrawal'>) => PortabilityReturn<'requestWithdrawal'>;
2928
+ readonly listWithdrawals?: (opts: PortabilityParam1<'listWithdrawalRequests'>) => PortabilityReturn<'listWithdrawalRequests'>;
2929
+ readonly approveWithdraw?: (requestId: PortabilityParam1<'approveWithdrawal'>, opts: PortabilityParam2<'approveWithdrawal'>) => PortabilityReturn<'approveWithdrawal'>;
2930
+ readonly rejectWithdraw?: (requestId: PortabilityParam1<'rejectWithdrawal'>, opts: PortabilityParam2<'rejectWithdrawal'>) => PortabilityReturn<'rejectWithdrawal'>;
2931
+ }
2932
+ /**
2933
+ * Factory that builds the `vault.user` API implementation from its
2934
+ * dependencies. `createNoydb()` pre-resolves the real implementation
2935
+ * (`with-party/directory/user-envelope/api.js#createUserApi`) via a
2936
+ * dynamic import before constructing `Noydb`, so `Vault`'s constructor
2937
+ * can call it synchronously — the two sync `subscribe`/`live` methods on
2938
+ * `VaultUserApi` are why `vault.user` must be built synchronously.
2939
+ */
2940
+ export type UserApiFactory = (deps: UserApiDeps) => VaultUserApi;
2941
+ /**
2942
+ * A single factor surface — the proof an actor presents at gate time.
2943
+ *
2944
+ * | Kind | Source | Off-device? |
2945
+ * |---|---|---|
2946
+ * | `totp` | RFC 6238 authenticator app (Google Auth, 1Password) | yes |
2947
+ * | `email-otp` | one-time code mailed to the user | yes |
2948
+ * | `recovery` | printable Base32 code (`@noy-db/on-recovery`) | yes (paper) |
2949
+ * | `shamir` | k-of-n threshold share (`@noy-db/on-shamir`) | yes |
2950
+ * | `webauthn-roaming` | hardware key (YubiKey, SoloKey, Titan) | yes (key portable) |
2951
+ * | `webauthn-platform` | platform passkey (Touch ID, Face ID, Hello) | no (device-bound) |
2952
+ * | `password` | tier-2 password (`@noy-db/on-password`) | no |
2953
+ * | `pin` | tier-3 quick-resume PIN (`@noy-db/on-pin`) | no |
2954
+ *
2955
+ * Off-device kinds (TOTP, email-OTP, recovery, shamir, roaming WebAuthn)
2956
+ * are the strongest factor proofs because they require something
2957
+ * separate from the device the user just unlocked. Platform / password /
2958
+ * PIN are useful for "fresh proof of *this* user" but don't bind across
2959
+ * devices — policies can require ANY of them or insist on a count of 2
2960
+ * to force a mix.
2961
+ *
2962
+ * `webauthn-platform`, `password`, `pin` — for consumers with no
2963
+ * off-device infrastructure (no TOTP, no email-OTP, paper recovery not
2964
+ * enrolled) who want to require "any second factor I have wired"
2965
+ * without losing the freshness guarantee.
2966
+ */
2967
+ export type FactorKind = 'totp' | 'email-otp' | 'recovery' | 'shamir' | 'webauthn-roaming' | 'webauthn-platform' | 'password' | 'pin';
2968
+ /**
2969
+ * One factor requirement entry. The default is "any one of the listed
2970
+ * factors, fresh within the last 5 minutes". Bumping `count` requires N
2971
+ * distinct fresh proofs; bumping `freshnessMs` widens the acceptance
2972
+ * window.
2973
+ */
2974
+ export interface FactorRequirement {
2975
+ readonly anyOf: ReadonlyArray<FactorKind>;
2976
+ /** Number of distinct factors required. Default 1. */
2977
+ readonly count?: number;
2978
+ /** How recent each proof must be. Default 5 minutes. */
2979
+ readonly freshnessMs?: number;
2980
+ }
2981
+ /** Soft signals layered on top of the gate verdict — never block on their own. */
2982
+ export interface WarningRules {
2983
+ /** Behavior on shared-device tier-1 ops. `'block'` raises a `PolicyDeniedError`. */
2984
+ readonly sharedDevice?: 'warn' | 'block';
2985
+ /** Behavior on weak tier-2 (e.g. password-only) for sensitive ops. */
2986
+ readonly weakAuthenticator?: 'warn' | 'block';
2987
+ }
2988
+ /**
2989
+ * Policy applied to one named gate. `enabled: false` disables the
2990
+ * action entirely (useful in managed-passphrase mode where rotation is
2991
+ * impossible by construction).
2992
+ */
2993
+ export interface GatePolicy {
2994
+ /** Minimum tier the active session must hold. */
2995
+ readonly minTier: 1 | 2 | 3;
2996
+ /** Extra freshness-bound proofs required at gate time. */
2997
+ readonly factors?: ReadonlyArray<FactorRequirement>;
2998
+ readonly warn?: WarningRules;
2999
+ readonly enabled?: boolean;
3000
+ }
3001
+ /**
3002
+ * Built-in gate names. App-defined gates live in the `app:*` namespace
3003
+ * and use the same engine; the engine treats unknown names with no
3004
+ * configured policy as "no gate" (no-op).
3005
+ */
3006
+ export type BuiltInGateName = 'rotate-passphrase' | 'recover-passphrase' | 'enroll-authenticator' | 'remove-authenticator'
3007
+ /**
3008
+ * Authorize a deliberate paper-recovery-code regeneration —
3009
+ * `db.rotateRecovery`. Symmetric to `rotate-passphrase` for
3010
+ * the case where the user remembers their passphrase but wants a
3011
+ * fresh sheet (lost the printout, suspect compromise of the off-site
3012
+ * copy). PERSONAL allows tier-1; STRICT requires an off-device
3013
+ * factor so a stolen unlocked laptop cannot silently mint a new
3014
+ * sheet for an attacker.
3015
+ */
3016
+ | 'rotate-recovery'
3017
+ /**
3018
+ * Authorize a meta-only mutation on an existing authenticator slot —
3019
+ * `db.updateAuthenticator`. The slot's wrap material, id, and
3020
+ * method are immutable through this gate; only the `meta` blob
3021
+ * (nicknames, method-specific labels) can change. Anti-slot-swap
3022
+ * guard is preserved structurally regardless of this gate's
3023
+ * settings.
3024
+ */
3025
+ | 'update-authenticator' | 'rotate-unlock' | 'enroll-user' | 'revoke-user' | 'export-bundle' | 'export-plaintext' | 'view-user-auth'
3026
+ /** Authorize a write to one's own user envelope. */
3027
+ | 'edit-own-profile'
3028
+ /** Authorize reading other principals' user envelopes. */
3029
+ | 'view-team-profiles'
3030
+ /**
3031
+ * Authorize an atomic peer-recovery — `db.recoverUser`.
3032
+ * Distinct from `revoke-user` because peer-recovery is intentional
3033
+ * re-issuance of someone's keyring under a temp passphrase, NOT
3034
+ * removal. Allows owner→owner natively (matches the threat model:
3035
+ * a co-owner explicitly recovering another co-owner). Ships with a
3036
+ * factor-proof default in `STRICT_POLICY` so the issuer must
3037
+ * affirmatively prove identity at the moment of recovery.
3038
+ */
3039
+ | 'peer-recover-user'
3040
+ /**
3041
+ * Authorize a post-grant identity mutation — `db.updateUser`.
3042
+ * Covers `role`, `displayName`, `permissions` changes on an existing
3043
+ * keyring. Pure plaintext-header rewrite — no DEKs touched, no KEK
3044
+ * required. The role-elevation guard inside the implementation
3045
+ * mirrors `db.grant`'s hierarchy (admin cannot promote to owner)
3046
+ * regardless of this gate's settings.
3047
+ */
3048
+ | 'update-user'
3049
+ /**
3050
+ * Authorize a non-owner's self-service **destructive** withdrawal —
3051
+ * `vault.user.unilateralWithdrawal`. The actor exports their
3052
+ * own re-keyed copy and then removes (delete-closure) or freezes the
3053
+ * source records. Because it both egresses data AND destroys the
3054
+ * firm's live copy, it MUST fail closed: undefined in a policy = denied.
3055
+ * Hosts opt in explicitly (and typically pin `minTier`/factor proofs).
3056
+ */
3057
+ | 'client-unilateral-withdraw'
3058
+ /**
3059
+ * Authorize FILING a two-party withdrawal request —
3060
+ * `vault.user.requestWithdrawal`. Non-destructive (writes a
3061
+ * pending request only); enabled by default so a read-only client can ask.
3062
+ */
3063
+ | 'user-request-withdrawal'
3064
+ /**
3065
+ * Authorize DECIDING a two-party withdrawal request (approve/reject) —
3066
+ * `vault.user.approveWithdrawal` / `rejectWithdrawal`. The approve
3067
+ * path is destructive (extract-and-dispose under firm authority), so it
3068
+ * defaults to a tier-2 floor; owner/admin role is enforced structurally.
3069
+ */
3070
+ | 'approve-user-withdrawal'
3071
+ /**
3072
+ * Authorize minting a **custodian** — `db.grantCustodian` (FR-6). The
3073
+ * custodian is the de-facto operational authority on a sealed-owner (Deed)
3074
+ * vault, so granting one is an ownership-level act: this gate MUST fail
3075
+ * closed (undefined in a policy = denied) and owner-only role is enforced
3076
+ * structurally. Hosts opt in explicitly, typically pinning factor proofs.
3077
+ */
3078
+ | 'grant-custodian'
3079
+ /**
3080
+ * Authorize the audited **Liberate** ceremony — `vault.custody.liberate`
3081
+ * (FR-6). The custodian (holding the live DEKs) claims ownership of a
3082
+ * sealed-owner vault under a recorded legal basis, minting a NEW owner
3083
+ * keyring. Destructive-of-the-old-ownership and irreversible, so it MUST
3084
+ * fail closed (undefined = denied); the caller-is-custodian check is
3085
+ * enforced structurally in the ceremony.
3086
+ */
3087
+ | 'liberate-vault';
3088
+ /** Either a built-in gate name or an `app:*` custom gate. */
3089
+ export type GateName = BuiltInGateName | `app:${string}`;
3090
+ /**
3091
+ * Top-level policy object. Persisted at `_meta/policy` once at vault
3092
+ * creation. The `passphrase` block configures the strength rules
3093
+ * applied at every passphrase ingress; `gates` configures
3094
+ * the action-level requirements.
3095
+ */
3096
+ export interface VaultPolicy {
3097
+ readonly passphrase?: PassphrasePolicy;
3098
+ readonly gates: Partial<Record<GateName, GatePolicy>>;
3099
+ }
3100
+ /** Concrete proof an actor presents to {@link checkGate}. */
3101
+ export interface FactorProof {
3102
+ readonly kind: FactorKind;
3103
+ /** ISO-8601 timestamp the proof was minted at. Compared against `freshnessMs`. */
3104
+ readonly mintedAt?: string;
3105
+ /** Method-specific payload. The engine treats it as opaque — verification is delegated. */
3106
+ readonly payload?: unknown;
3107
+ }
3108
+ /**
3109
+ * Bundle of factor proofs + session-context flags passed to a gated
3110
+ * Noydb method. Used as the optional last parameter of every method
3111
+ * that runs through `checkGate`: `db.grant`, `db.revoke`, `db.updateUser`,
3112
+ * `db.enrollAuthenticator`, `db.removeAuthenticator`, `db.updateAuthenticator`,
3113
+ * `db.enrollWebAuthn`, `db.rotatePassphrase`, `db.recoverPassphrase`,
3114
+ * `db.recoverUser`, `db.enrollUnlock`, `db.describeUserAuth`,
3115
+ * `db.describeAllUsersAuth`.
3116
+ *
3117
+ * Previously this type was inlined at every call site as
3118
+ * `{ factors?: ReadonlyArray<FactorProof>; sharedDevice?: boolean }`
3119
+ * and parameter names alternated between `factors` and `presented`.
3120
+ * Now exported so consumers can name their helpers and so the param
3121
+ * name converges to `factors` everywhere.
3122
+ */
3123
+ export interface FactorProofBundle {
3124
+ readonly factors?: ReadonlyArray<FactorProof>;
3125
+ readonly sharedDevice?: boolean;
3126
+ }
3127
+ /** Active session tier — what the engine compares against `gate.minTier`. */
3128
+ export type ActiveTier = 1 | 2 | 3;
3129
+ /**
3130
+ * Caller-supplied context for the policy engine's `checkGate`/`describeGate`.
3131
+ * Structural mirror of `with-party/policy/engine.ts`'s `CheckGateContext` —
3132
+ * duplicated here (rather than imported) because the kernel spine may not
3133
+ * statically import a with-* service; see {@link PolicyCheckGateFn}.
3134
+ */
3135
+ export interface PolicyCheckGateContext {
3136
+ /** Tier the active session currently holds. */
3137
+ readonly activeTier: ActiveTier;
3138
+ /** Proofs the actor is presenting for this gate. */
3139
+ readonly factors?: ReadonlyArray<FactorProof>;
3140
+ /**
3141
+ * If the host knows the actor is on a shared device, set this to
3142
+ * `true` so the engine can apply `warn.sharedDevice` rules. Defaults
3143
+ * to `false`.
3144
+ */
3145
+ readonly sharedDevice?: boolean;
3146
+ /**
3147
+ * Override `now()` for tests. Defaults to `Date.now()`.
3148
+ * @internal
3149
+ */
3150
+ readonly now?: number;
3151
+ }
3152
+ /**
3153
+ * Structural type of the policy engine's `checkGate` function. The real
3154
+ * implementation lives at `with-party/policy/engine.ts#checkGate`;
3155
+ * `createNoydb()` pre-resolves it via a dynamic import (mirrors
3156
+ * {@link UserApiFactory}) so `Noydb.checkGate` can call it without the
3157
+ * spine statically importing the service.
3158
+ */
3159
+ export type PolicyCheckGateFn = (policy: VaultPolicy, gate: GateName, context: PolicyCheckGateContext) => Promise<void>;
3160
+ /**
3161
+ * Public `NoydbPolicy` surface — the CONTRACT. The implementation
3162
+ * (`NoydbPolicy` class) lives at `with-party/policy/noydb-facade.ts`;
3163
+ * `createNoydb()` wires it in via the pre-resolved {@link NoydbPolicyFactory}.
3164
+ */
3165
+ export interface NoydbPolicyApi {
3166
+ /**
3167
+ * Touch the policy enforcer for a vault (records activity, resets
3168
+ * idle timer). Also touches the legacy session timer. No-op if no enforcer.
3169
+ */
3170
+ touchPolicy(vault?: string): void;
3171
+ /**
3172
+ * Check that a policy-guarded operation is permitted.
3173
+ * Throws `SessionPolicyError` if re-auth is required.
3174
+ */
3175
+ checkPolicyOperation(vault: string, op: ReAuthOperation): void;
3176
+ /**
3177
+ * Read the active policy for a vault. Loads from `_meta/policy` on
3178
+ * first call; subsequent calls hit the in-memory cache. Throws
3179
+ * `ValidationError` if the vault has not been opened.
3180
+ */
3181
+ getPolicy(vault: string): Promise<VaultPolicy>;
3182
+ /**
3183
+ * Replace the policy document at `_meta/policy` and update the
3184
+ * in-memory cache. Gated by the `enroll-user` policy (a policy
3185
+ * change is fundamentally a privilege-management action).
3186
+ */
3187
+ updatePolicy(vault: string, override: Partial<VaultPolicy>): Promise<VaultPolicy>;
3188
+ /** Read or persist the vault policy at `_meta/policy` on first open. */
3189
+ bootstrapPolicy(vault: string, opts?: {
3190
+ skipManagedCheck?: boolean;
3191
+ }): Promise<void>;
3192
+ }
3193
+ /**
3194
+ * Constructor dependencies for `NoydbPolicy` (the {@link NoydbPolicyApi}
3195
+ * implementation). Everything the policy/session-policy methods touch on
3196
+ * the owning `Noydb` instance's `this.*`.
3197
+ *
3198
+ * The `policyEnforcers` map is typed structurally (rather than importing
3199
+ * `PolicyEnforcer` from `with-party/session/session-policy.ts`) so this
3200
+ * spine-resident interface never needs a with-* import; the real
3201
+ * `PolicyEnforcer` class satisfies this shape.
3202
+ */
3203
+ export interface NoydbPolicyDeps {
3204
+ /** In-memory vault-policy cache (Noydb-resident; read/written by reference). */
3205
+ readonly policyCache: Map<string, VaultPolicy>;
3206
+ /** Per-vault session-policy enforcers (Noydb-resident; read/written by reference). */
3207
+ readonly policyEnforcers: Map<string, {
3208
+ touch(): void;
3209
+ destroy(): void;
3210
+ checkOperation(op: ReAuthOperation): void;
3211
+ }>;
3212
+ /** The ciphertext store. */
3213
+ readonly store: NoydbStore;
3214
+ /** Whether records are encrypted (`options.encrypt !== false`). */
3215
+ readonly encrypted: boolean;
3216
+ /** The configured session policy, or undefined. */
3217
+ readonly sessionPolicy: SessionPolicy | undefined;
3218
+ /** The developer-supplied default policy, or undefined. */
3219
+ readonly policyOption: VaultPolicy | undefined;
3220
+ /** Whether the owning instance has been closed. */
3221
+ isClosed(): boolean;
3222
+ /** Reset the kernel-resident idle/session timer. */
3223
+ resetSessionTimer(): void;
3224
+ /** Managed-recovery enrolment check (kernel-resident; called on bootstrap). */
3225
+ assertRecoveryEnrolled(vault: string, policy: VaultPolicy, opts?: {
3226
+ skipManagedCheck?: boolean;
3227
+ }): Promise<void>;
3228
+ /** Evict the keyring + vault caches when a session is revoked. */
3229
+ onSessionRevoke(vault: string): void;
3230
+ }
3231
+ /**
3232
+ * Factory that builds the `NoydbPolicy` service implementation from its
3233
+ * dependencies. `createNoydb()` pre-resolves the real implementation
3234
+ * (`with-party/policy/noydb-facade.js#createNoydbPolicy`) via a dynamic
3235
+ * import before constructing `Noydb`, so the constructor can call it
3236
+ * synchronously — mirrors {@link UserApiFactory}.
3237
+ */
3238
+ export type NoydbPolicyFactory = (deps: NoydbPolicyDeps) => NoydbPolicyApi;
3239
+ export {};