@noy-db/hub 0.4.0 → 0.6.0-pre.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 (438) hide show
  1. package/dist/api-67SBPMMH.js +20 -0
  2. package/dist/attestation/index.js +18 -18
  3. package/dist/{backup-X7F3TCFV.js → backup-GAYWQAFN.js} +16 -11
  4. package/dist/backup-GAYWQAFN.js.map +1 -0
  5. package/dist/blobs/index.js +20 -20
  6. package/dist/broker/index.js +12 -12
  7. package/dist/bundle-handle-5OUAI7CV.js +36 -0
  8. package/dist/bundle-handle-5OUAI7CV.js.map +1 -0
  9. package/dist/cargo/index.js +36 -36
  10. package/dist/{chunk-DQZXPGGZ.js → chunk-24UICKTB.js} +3 -3
  11. package/dist/{chunk-77AEMXFA.js → chunk-24ZLWWEO.js} +1 -1
  12. package/dist/chunk-24ZLWWEO.js.map +1 -0
  13. package/dist/{chunk-2BET5QTS.js → chunk-27TCYH6G.js} +5 -5
  14. package/dist/{chunk-MSMJJB4J.js → chunk-2KIV7BEK.js} +2 -2
  15. package/dist/{chunk-6ZNSB3H6.js → chunk-2LGDCNFJ.js} +2 -2
  16. package/dist/{chunk-GTYFIVIZ.js → chunk-35EBKWQU.js} +5 -5
  17. package/dist/chunk-35EBKWQU.js.map +1 -0
  18. package/dist/{chunk-WBKZUO5V.js → chunk-3737A6EA.js} +3 -3
  19. package/dist/{chunk-ZBYFMI6D.js → chunk-3CLZY46Y.js} +638 -300
  20. package/dist/chunk-3CLZY46Y.js.map +1 -0
  21. package/dist/{chunk-HLKXPJ4V.js → chunk-3EO7RZLJ.js} +6 -6
  22. package/dist/{chunk-JYJFGD2H.js → chunk-3FSX6LDG.js} +2 -2
  23. package/dist/{chunk-MXUT7FTE.js → chunk-3HYWYLXL.js} +2 -2
  24. package/dist/{chunk-IVYQAVWO.js → chunk-3IIPWA75.js} +11 -11
  25. package/dist/{chunk-7H3WWH6J.js → chunk-3UK6STWO.js} +3 -3
  26. package/dist/chunk-46V67XP5.js +117 -0
  27. package/dist/chunk-46V67XP5.js.map +1 -0
  28. package/dist/{chunk-NJ4DYYO5.js → chunk-4HDYQL3J.js} +2 -2
  29. package/dist/{chunk-P4JO3H6R.js → chunk-4MQDV3HZ.js} +2 -2
  30. package/dist/{chunk-X4MVWPHV.js → chunk-4UVDI4XE.js} +3 -3
  31. package/dist/{chunk-LXRTP3AQ.js → chunk-4VCWI42L.js} +2 -2
  32. package/dist/{chunk-QJNCB5SK.js → chunk-747LRSOO.js} +2 -2
  33. package/dist/{chunk-3HUYRN24.js → chunk-7F4DBNSP.js} +3 -3
  34. package/dist/{chunk-UADPR6F4.js → chunk-7G6VDWXB.js} +3 -3
  35. package/dist/{chunk-PTHKZWEH.js → chunk-AHLJSVRL.js} +2 -2
  36. package/dist/{chunk-NFZGZ4AK.js → chunk-AR2JDFAE.js} +2 -2
  37. package/dist/{chunk-3ECU57YH.js → chunk-BPTZ4K5L.js} +11 -11
  38. package/dist/{chunk-KRCBZYTZ.js → chunk-CCZJJ4I2.js} +4 -4
  39. package/dist/{chunk-NYEFP7DY.js → chunk-CJ73OLMW.js} +2 -2
  40. package/dist/{chunk-Q36YXK77.js → chunk-CYQOUTMY.js} +3 -3
  41. package/dist/{chunk-RBTVFPHF.js → chunk-DCMQR46R.js} +5 -5
  42. package/dist/{chunk-TG634KCO.js → chunk-DG27IUVI.js} +2 -2
  43. package/dist/{chunk-E23UGFVC.js → chunk-DMQCLZ4Z.js} +8 -6
  44. package/dist/chunk-DMQCLZ4Z.js.map +1 -0
  45. package/dist/{chunk-ZNWSG7XC.js → chunk-DPJTDNUF.js} +68 -34
  46. package/dist/chunk-DPJTDNUF.js.map +1 -0
  47. package/dist/{chunk-V6UQZA2H.js → chunk-E6427JU2.js} +2 -2
  48. package/dist/{chunk-JEI6JJNI.js → chunk-EK7DT5BT.js} +220 -13
  49. package/dist/chunk-EK7DT5BT.js.map +1 -0
  50. package/dist/chunk-EPFF7LOX.js +14 -0
  51. package/dist/chunk-EPFF7LOX.js.map +1 -0
  52. package/dist/{chunk-TWPK7KUJ.js → chunk-F3GVO44K.js} +6 -6
  53. package/dist/{chunk-QD46HPZG.js → chunk-FAXZQ5UF.js} +2 -2
  54. package/dist/{chunk-IG6KUWBX.js → chunk-FNSMZQS4.js} +2 -2
  55. package/dist/{chunk-BLBAQRBM.js → chunk-FUHKW252.js} +2 -2
  56. package/dist/{chunk-SU6SGWXM.js → chunk-FY343IZR.js} +8 -8
  57. package/dist/{chunk-KPZS5QAQ.js → chunk-GQ3BX5EA.js} +9 -1
  58. package/dist/chunk-GQ3BX5EA.js.map +1 -0
  59. package/dist/{chunk-DAFBJS4Y.js → chunk-GS5RT2KK.js} +4 -4
  60. package/dist/{chunk-5UQ7Y6SQ.js → chunk-HFKGIBMD.js} +3 -3
  61. package/dist/{chunk-QZWTRENR.js → chunk-HNGSV2YC.js} +133 -1
  62. package/dist/chunk-HNGSV2YC.js.map +1 -0
  63. package/dist/chunk-HNHCQ556.js +63 -0
  64. package/dist/chunk-HNHCQ556.js.map +1 -0
  65. package/dist/chunk-HS7HNYBD.js +91 -0
  66. package/dist/chunk-HS7HNYBD.js.map +1 -0
  67. package/dist/{chunk-SHEEBRZ4.js → chunk-HVQGCKY4.js} +2 -2
  68. package/dist/{chunk-35NMVJ7I.js → chunk-HXGUIPQB.js} +3 -3
  69. package/dist/{chunk-ERGECZEI.js → chunk-JEM2IGS3.js} +9 -9
  70. package/dist/chunk-JH3OHQM4.js +260 -0
  71. package/dist/chunk-JH3OHQM4.js.map +1 -0
  72. package/dist/{chunk-L3YYLT4E.js → chunk-JIUVJ4M7.js} +2 -2
  73. package/dist/{chunk-55LX6FSX.js → chunk-JRCYZEHU.js} +2 -2
  74. package/dist/{chunk-SFBYQMZM.js → chunk-JSRU5W2M.js} +5 -5
  75. package/dist/{chunk-NM5UYF6Q.js → chunk-JXIDGFKS.js} +2 -2
  76. package/dist/{chunk-VYYM3MEN.js → chunk-KHKKD62N.js} +16 -2
  77. package/dist/chunk-KHKKD62N.js.map +1 -0
  78. package/dist/{chunk-FQ5CHJR7.js → chunk-KUDZVJKQ.js} +21 -2
  79. package/dist/chunk-KUDZVJKQ.js.map +1 -0
  80. package/dist/{chunk-RO5NM6UI.js → chunk-KZ3KMDN3.js} +2 -2
  81. package/dist/{chunk-HZZP2ZIG.js → chunk-LBGPO5RL.js} +6 -6
  82. package/dist/{chunk-ZFG5EBI3.js → chunk-LTU4FLHG.js} +57 -27
  83. package/dist/chunk-LTU4FLHG.js.map +1 -0
  84. package/dist/{chunk-CLE3TMIS.js → chunk-MC2LFTQM.js} +5 -2
  85. package/dist/{chunk-467SWYT5.js → chunk-MJWCLSQL.js} +17 -8
  86. package/dist/chunk-MJWCLSQL.js.map +1 -0
  87. package/dist/{chunk-W3G5REIU.js → chunk-MSWYQLMQ.js} +2 -2
  88. package/dist/{chunk-WK7ULBTP.js → chunk-MVOWXQHN.js} +5 -3
  89. package/dist/chunk-MVOWXQHN.js.map +1 -0
  90. package/dist/{chunk-2J6UEN2V.js → chunk-MXZ5TSTR.js} +118 -4
  91. package/dist/chunk-MXZ5TSTR.js.map +1 -0
  92. package/dist/{chunk-SGDPRCC4.js → chunk-MZ5ZFO2D.js} +3 -3
  93. package/dist/{chunk-NBXFCQX4.js → chunk-NQCNSVGI.js} +9 -9
  94. package/dist/chunk-NQCNSVGI.js.map +1 -0
  95. package/dist/{chunk-EFJAAFBW.js → chunk-NQRJ5AJO.js} +2 -2
  96. package/dist/{chunk-Q2SEJMP2.js → chunk-NVU7ZMPN.js} +2 -2
  97. package/dist/{chunk-ZTLOXFPB.js → chunk-OF3L2SD6.js} +2 -2
  98. package/dist/{chunk-LLYIMSQQ.js → chunk-OMSAULZM.js} +11 -11
  99. package/dist/{chunk-SF2ZIRD6.js → chunk-OSFPNKY4.js} +3 -3
  100. package/dist/{chunk-WUHEP3HH.js → chunk-P7NGLLUF.js} +5 -5
  101. package/dist/{chunk-RQ4ZI4ZI.js → chunk-PGAPBZEK.js} +7 -7
  102. package/dist/{chunk-T2MOJF76.js → chunk-PP5CO2PR.js} +6 -6
  103. package/dist/{chunk-Q5YJCVJY.js → chunk-RLWY6Z44.js} +227 -41
  104. package/dist/chunk-RLWY6Z44.js.map +1 -0
  105. package/dist/{chunk-QGIBI6GL.js → chunk-ROWL352P.js} +5 -5
  106. package/dist/{chunk-ZHDSUZQU.js → chunk-RPXL6KSX.js} +4 -4
  107. package/dist/{chunk-DTFA5DO4.js → chunk-SKONR2OL.js} +3 -3
  108. package/dist/{chunk-AT2JJEKJ.js → chunk-SRGJET2F.js} +16 -5
  109. package/dist/chunk-SRGJET2F.js.map +1 -0
  110. package/dist/{chunk-4ZKNC6A6.js → chunk-T4GPR2IR.js} +2 -2
  111. package/dist/{chunk-NLYALJMY.js → chunk-TFZ7LLOQ.js} +113 -36
  112. package/dist/chunk-TFZ7LLOQ.js.map +1 -0
  113. package/dist/{chunk-TS5XLBZR.js → chunk-TLNNHG3A.js} +4 -4
  114. package/dist/{chunk-6UBZ6I5Z.js → chunk-UHXCLPGC.js} +2 -2
  115. package/dist/{chunk-KD4HGBJV.js → chunk-V5C5NNBR.js} +4 -4
  116. package/dist/{chunk-WYUAEZSC.js → chunk-VBY6ZLJT.js} +15 -14
  117. package/dist/chunk-VBY6ZLJT.js.map +1 -0
  118. package/dist/{chunk-AKKRXT23.js → chunk-VCETL77O.js} +34 -16
  119. package/dist/chunk-VCETL77O.js.map +1 -0
  120. package/dist/{chunk-5GQEU4DN.js → chunk-VJFMXYKP.js} +2 -2
  121. package/dist/{chunk-5DRROK5W.js → chunk-VMCCGUQB.js} +2 -2
  122. package/dist/{chunk-IXNCZTWA.js → chunk-W3TVWF6N.js} +2 -2
  123. package/dist/{chunk-W66AM5IB.js → chunk-WLYIROCJ.js} +2 -2
  124. package/dist/{chunk-OWHP3H5C.js → chunk-XB7LUDKM.js} +4 -4
  125. package/dist/{chunk-KYRDJI5O.js → chunk-XBLKM73C.js} +10 -10
  126. package/dist/{chunk-MHMLXJ3I.js → chunk-YAWK6AWF.js} +2 -2
  127. package/dist/{chunk-PWPYO73B.js → chunk-ZGGVOADG.js} +5 -5
  128. package/dist/{chunk-YGK2HMLR.js → chunk-ZK4CO2KZ.js} +9 -9
  129. package/dist/chunk-ZK4CO2KZ.js.map +1 -0
  130. package/dist/{chunk-DSDXAKIP.js → chunk-ZVF37PKE.js} +34 -5
  131. package/dist/chunk-ZVF37PKE.js.map +1 -0
  132. package/dist/{chunk-IFOH7RBI.js → chunk-ZWMO5GL5.js} +5 -5
  133. package/dist/{chunk-LRRX57UA.js → chunk-ZXJXDHNK.js} +4 -4
  134. package/dist/classified/index.js +5 -5
  135. package/dist/{classified-marker-LE54HWSX.js → classified-marker-MH3ON5OL.js} +3 -3
  136. package/dist/collection-facade-AHT7FATG.js +45 -0
  137. package/dist/{computed-AB45PS4V.js → computed-6G5M3UPH.js} +3 -3
  138. package/dist/consent/index.js +9 -9
  139. package/dist/cover/index.js +3 -3
  140. package/dist/custody/index.js +11 -11
  141. package/dist/{dead-filter-V3LVWYEJ.js → dead-filter-U575NGSH.js} +2 -2
  142. package/dist/debug/index.js +1 -1
  143. package/dist/{delegation-JDUMAF6L.js → delegation-PDYL6RWT.js} +10 -10
  144. package/dist/derivations/index.js +12 -12
  145. package/dist/derive-AKT4KU36.js +22 -0
  146. package/dist/directory/index.js +10 -10
  147. package/dist/{dispatch-6TV3DGO6.js → dispatch-4XIJSFTT.js} +5 -5
  148. package/dist/{dispatch-W7NWQ637.js → dispatch-N5HGVUGU.js} +18 -18
  149. package/dist/{enclave-YFCLPIDR.js → enclave-OPK24QDR.js} +13 -9
  150. package/dist/executor-3JZ4POTW.js +28 -0
  151. package/dist/executor-CYJQLKKI.js +9 -0
  152. package/dist/executor-S4QIKEHW.js +9 -0
  153. package/dist/export-accessible-CPTP5STN.js +23 -0
  154. package/dist/extract-partition-TWXPHVU7.js +38 -0
  155. package/dist/{fanout-sidecar-273RDMYS.js → fanout-sidecar-T2ZGLQFE.js} +9 -9
  156. package/dist/find-RBBYKXI7.js +11 -0
  157. package/dist/forget/index.js +9 -9
  158. package/dist/guards/index.js +6 -6
  159. package/dist/history/index.js +15 -15
  160. package/dist/i18n/index.js +14 -14
  161. package/dist/index.d.ts +35 -7
  162. package/dist/index.js +279 -202
  163. package/dist/index.js.map +1 -1
  164. package/dist/indexing/index.js +3 -3
  165. package/dist/introspection/index.js +12 -12
  166. package/dist/issue-N74C55X6.js +19 -0
  167. package/dist/kernel/collection-config.d.ts +4 -0
  168. package/dist/kernel/collection.d.ts +34 -8
  169. package/dist/kernel/cutover-transform.d.ts +64 -0
  170. package/dist/kernel/enclave/crypto.d.ts +24 -0
  171. package/dist/kernel/enclave/index.d.ts +2 -1
  172. package/dist/kernel/errors.d.ts +138 -0
  173. package/dist/kernel/noydb.d.ts +10 -1
  174. package/dist/kernel/put-many-atomic.d.ts +45 -0
  175. package/dist/kernel/secret-mode.d.ts +59 -0
  176. package/dist/kernel/types.d.ts +98 -7
  177. package/dist/kernel/validation.d.ts +33 -0
  178. package/dist/kernel/vault.d.ts +32 -6
  179. package/dist/{ledger-XE7JF2I2.js → ledger-DONWFC5M.js} +11 -11
  180. package/dist/liberate-KICI7AJN.js +24 -0
  181. package/dist/{link-set-CGYC3OH5.js → link-set-2TTP4VLO.js} +11 -11
  182. package/dist/managed-secret-EAOYWRYF.js +27 -0
  183. package/dist/materialized-views/index.js +19 -19
  184. package/dist/money/index.js +3 -3
  185. package/dist/noydb-6W2XGQCS.js +83 -0
  186. package/dist/overlay-views/index.js +6 -6
  187. package/dist/periods/index.js +16 -16
  188. package/dist/pod/index.js +121 -12
  189. package/dist/policy/index.js +4 -4
  190. package/dist/port/to/index.d.ts +3 -1
  191. package/dist/port/to/locator.d.ts +84 -0
  192. package/dist/port/with/device-seal-strategy.d.ts +16 -0
  193. package/dist/port/with/strategies.d.ts +2 -0
  194. package/dist/port/with/write-hooks.d.ts +6 -0
  195. package/dist/portability/index.js +8 -8
  196. package/dist/{post-register-LY35EDTJ.js → post-register-ORQOQJCS.js} +6 -6
  197. package/dist/query/index.js +4 -4
  198. package/dist/reduce/index.js +4 -4
  199. package/dist/register-LHETZRJM.js +32 -0
  200. package/dist/registry-AMAZ6QRZ.js +19 -0
  201. package/dist/registry-CZVINVQH.js +9 -0
  202. package/dist/registry-IKUR2MXD.js +9 -0
  203. package/dist/registry-JRIN447B.js +18 -0
  204. package/dist/request-withdrawal-2DN2RGCO.js +31 -0
  205. package/dist/{reveal-T34ADTPY.js → reveal-AG4SCHUQ.js} +6 -6
  206. package/dist/revoke-ZX4NM2CJ.js +24 -0
  207. package/dist/satellites/index.js +1 -1
  208. package/dist/schema-update/index.js +6 -6
  209. package/dist/sealed-record/index.js +12 -12
  210. package/dist/search/index.js +4 -4
  211. package/dist/{seed-JOV54PB3.js → seed-IRCDGIRK.js} +15 -15
  212. package/dist/seed-IRCDGIRK.js.map +1 -0
  213. package/dist/sequence/index.js +9 -9
  214. package/dist/session/index.js +9 -9
  215. package/dist/shadow/index.js +2 -2
  216. package/dist/signer-7KHD4OL2.js +25 -0
  217. package/dist/snapshots/index.js +10 -10
  218. package/dist/{stale-T3V7XEOB.js → stale-K734VACF.js} +10 -10
  219. package/dist/storage-4H2GF6RQ.js +23 -0
  220. package/dist/{store-coordination-provider-AHGFEMFA.js → store-coordination-provider-4SKLSFUG.js} +3 -3
  221. package/dist/sync/index.js +10 -10
  222. package/dist/team/index.js +27 -15
  223. package/dist/tiers/index.js +10 -10
  224. package/dist/to/index.js +28 -3
  225. package/dist/to/index.js.map +1 -1
  226. package/dist/transactions/index.js +3 -3
  227. package/dist/util/index.js +1 -1
  228. package/dist/{verify-7XWHJWUN.js → verify-RO5RTZOJ.js} +5 -5
  229. package/dist/walk-MQHYNDLZ.js +21 -0
  230. package/dist/with-audit/guards/registry.d.ts +8 -1
  231. package/dist/with-audit/guards/types.d.ts +5 -0
  232. package/dist/with-audit/periods/index.d.ts +1 -1
  233. package/dist/with-audit/periods/periods.d.ts +7 -0
  234. package/dist/with-commit/tx/atomic-eligibility.d.ts +13 -11
  235. package/dist/with-formula/derivations/registry.d.ts +6 -0
  236. package/dist/with-formula/derivations/types.d.ts +5 -0
  237. package/dist/with-lookup/indexing/eager-indexes.d.ts +10 -0
  238. package/dist/with-party/team/device-seal.d.ts +25 -0
  239. package/dist/with-party/team/echo-ceremony.d.ts +74 -0
  240. package/dist/with-party/team/echo-secret.d.ts +56 -0
  241. package/dist/with-party/team/index.d.ts +8 -0
  242. package/dist/with-party/team/keyring.d.ts +71 -9
  243. package/dist/with-party/team/rotate-recover.d.ts +99 -5
  244. package/dist/with-pod/bundle-handle.d.ts +9 -0
  245. package/dist/with-pod/bundle.d.ts +100 -2
  246. package/dist/with-pod/format.d.ts +92 -1
  247. package/dist/with-pod/index.d.ts +22 -1
  248. package/dist/with-pod/open.d.ts +117 -0
  249. package/dist/with-pod/redirect.d.ts +78 -0
  250. package/dist/with-pod/signature.d.ts +13 -0
  251. package/dist/with-shape/introspection/behaviors.d.ts +100 -0
  252. package/dist/with-shape/introspection/derivation-key.d.ts +17 -0
  253. package/dist/with-shape/introspection/describe.d.ts +36 -0
  254. package/dist/with-shape/introspection/index.d.ts +1 -0
  255. package/dist/with-shape/introspection/subsystem-matrix.d.ts +22 -0
  256. package/dist/with-shape/introspection/types.d.ts +2 -1
  257. package/dist/with-shape/links/names.d.ts +14 -0
  258. package/dist/with-shape/manifest/derive.d.ts +86 -0
  259. package/dist/with-shape/manifest/reserved-collections.d.ts +27 -0
  260. package/dist/with-shape/manifest/storage.d.ts +62 -0
  261. package/dist/with-shape/manifest/sync.d.ts +135 -0
  262. package/dist/with-shape/manifest/types.d.ts +49 -0
  263. package/dist/with-shape/manifest/writer.d.ts +32 -0
  264. package/dist/with-shape/persisted-schemas/field-ids.d.ts +29 -0
  265. package/dist/with-shape/persisted-schemas/register.d.ts +3 -0
  266. package/dist/with-shape/persisted-schemas/types.d.ts +17 -0
  267. package/dist/with-shape/schema-update/fence-controller.d.ts +34 -0
  268. package/dist/with-shape/schema-update/fence.d.ts +9 -0
  269. package/dist/with-shape/schema-update/strategies.d.ts +18 -2
  270. package/dist/with-shape/schema-update/types.d.ts +11 -0
  271. package/dist/with-sync/engine.d.ts +17 -0
  272. package/dist/with-sync/presence.d.ts +31 -1
  273. package/dist/withdraw-accessible-JSDQHXHE.js +28 -0
  274. package/dist/withdraw-accessible-JSDQHXHE.js.map +1 -0
  275. package/package.json +3 -3
  276. package/dist/api-SI2IVBQO.js +0 -20
  277. package/dist/backup-X7F3TCFV.js.map +0 -1
  278. package/dist/chunk-2J6UEN2V.js.map +0 -1
  279. package/dist/chunk-467SWYT5.js.map +0 -1
  280. package/dist/chunk-4JQK3L4V.js +0 -41
  281. package/dist/chunk-4JQK3L4V.js.map +0 -1
  282. package/dist/chunk-77AEMXFA.js.map +0 -1
  283. package/dist/chunk-AKKRXT23.js.map +0 -1
  284. package/dist/chunk-AT2JJEKJ.js.map +0 -1
  285. package/dist/chunk-DSDXAKIP.js.map +0 -1
  286. package/dist/chunk-E23UGFVC.js.map +0 -1
  287. package/dist/chunk-FQ5CHJR7.js.map +0 -1
  288. package/dist/chunk-GTYFIVIZ.js.map +0 -1
  289. package/dist/chunk-JEI6JJNI.js.map +0 -1
  290. package/dist/chunk-JQ2AX4T5.js +0 -23
  291. package/dist/chunk-JQ2AX4T5.js.map +0 -1
  292. package/dist/chunk-KPZS5QAQ.js.map +0 -1
  293. package/dist/chunk-NBXFCQX4.js.map +0 -1
  294. package/dist/chunk-NLYALJMY.js.map +0 -1
  295. package/dist/chunk-Q5YJCVJY.js.map +0 -1
  296. package/dist/chunk-QZWTRENR.js.map +0 -1
  297. package/dist/chunk-S7GIXBXV.js +0 -129
  298. package/dist/chunk-S7GIXBXV.js.map +0 -1
  299. package/dist/chunk-SBHN6QUT.js +0 -25
  300. package/dist/chunk-SBHN6QUT.js.map +0 -1
  301. package/dist/chunk-VYYM3MEN.js.map +0 -1
  302. package/dist/chunk-WK7ULBTP.js.map +0 -1
  303. package/dist/chunk-WYUAEZSC.js.map +0 -1
  304. package/dist/chunk-YGK2HMLR.js.map +0 -1
  305. package/dist/chunk-ZBYFMI6D.js.map +0 -1
  306. package/dist/chunk-ZFG5EBI3.js.map +0 -1
  307. package/dist/chunk-ZNWSG7XC.js.map +0 -1
  308. package/dist/collection-facade-DO2AABZT.js +0 -45
  309. package/dist/derive-ZPGVLE2Q.js +0 -22
  310. package/dist/executor-FPHKWDWT.js +0 -28
  311. package/dist/executor-IEBLTBCW.js +0 -9
  312. package/dist/executor-RM7XWQDU.js +0 -9
  313. package/dist/export-accessible-EKM3HGB2.js +0 -23
  314. package/dist/extract-partition-LS4ET5A6.js +0 -38
  315. package/dist/find-OZMTRIK3.js +0 -11
  316. package/dist/issue-LIA7FXBJ.js +0 -19
  317. package/dist/liberate-WZ3RHVKW.js +0 -24
  318. package/dist/noydb-ZLPVCDES.js +0 -81
  319. package/dist/register-6RIBIT3I.js +0 -25
  320. package/dist/registry-7Y5WF7GS.js +0 -9
  321. package/dist/registry-BWD2ED52.js +0 -8
  322. package/dist/registry-MUSL4AW6.js +0 -19
  323. package/dist/registry-RON4WHAP.js +0 -18
  324. package/dist/request-withdrawal-FT3ORAWN.js +0 -31
  325. package/dist/revoke-HC7WG3HE.js +0 -24
  326. package/dist/seed-JOV54PB3.js.map +0 -1
  327. package/dist/signer-CTWOH6KT.js +0 -25
  328. package/dist/storage-LLNLPWWB.js +0 -23
  329. package/dist/walk-G3NFEP5L.js +0 -21
  330. package/dist/withdraw-accessible-ANSVG6XG.js +0 -28
  331. /package/dist/{api-SI2IVBQO.js.map → api-67SBPMMH.js.map} +0 -0
  332. /package/dist/{chunk-DQZXPGGZ.js.map → chunk-24UICKTB.js.map} +0 -0
  333. /package/dist/{chunk-2BET5QTS.js.map → chunk-27TCYH6G.js.map} +0 -0
  334. /package/dist/{chunk-MSMJJB4J.js.map → chunk-2KIV7BEK.js.map} +0 -0
  335. /package/dist/{chunk-6ZNSB3H6.js.map → chunk-2LGDCNFJ.js.map} +0 -0
  336. /package/dist/{chunk-WBKZUO5V.js.map → chunk-3737A6EA.js.map} +0 -0
  337. /package/dist/{chunk-HLKXPJ4V.js.map → chunk-3EO7RZLJ.js.map} +0 -0
  338. /package/dist/{chunk-JYJFGD2H.js.map → chunk-3FSX6LDG.js.map} +0 -0
  339. /package/dist/{chunk-MXUT7FTE.js.map → chunk-3HYWYLXL.js.map} +0 -0
  340. /package/dist/{chunk-IVYQAVWO.js.map → chunk-3IIPWA75.js.map} +0 -0
  341. /package/dist/{chunk-7H3WWH6J.js.map → chunk-3UK6STWO.js.map} +0 -0
  342. /package/dist/{chunk-NJ4DYYO5.js.map → chunk-4HDYQL3J.js.map} +0 -0
  343. /package/dist/{chunk-P4JO3H6R.js.map → chunk-4MQDV3HZ.js.map} +0 -0
  344. /package/dist/{chunk-X4MVWPHV.js.map → chunk-4UVDI4XE.js.map} +0 -0
  345. /package/dist/{chunk-LXRTP3AQ.js.map → chunk-4VCWI42L.js.map} +0 -0
  346. /package/dist/{chunk-QJNCB5SK.js.map → chunk-747LRSOO.js.map} +0 -0
  347. /package/dist/{chunk-3HUYRN24.js.map → chunk-7F4DBNSP.js.map} +0 -0
  348. /package/dist/{chunk-UADPR6F4.js.map → chunk-7G6VDWXB.js.map} +0 -0
  349. /package/dist/{chunk-PTHKZWEH.js.map → chunk-AHLJSVRL.js.map} +0 -0
  350. /package/dist/{chunk-NFZGZ4AK.js.map → chunk-AR2JDFAE.js.map} +0 -0
  351. /package/dist/{chunk-3ECU57YH.js.map → chunk-BPTZ4K5L.js.map} +0 -0
  352. /package/dist/{chunk-KRCBZYTZ.js.map → chunk-CCZJJ4I2.js.map} +0 -0
  353. /package/dist/{chunk-NYEFP7DY.js.map → chunk-CJ73OLMW.js.map} +0 -0
  354. /package/dist/{chunk-Q36YXK77.js.map → chunk-CYQOUTMY.js.map} +0 -0
  355. /package/dist/{chunk-RBTVFPHF.js.map → chunk-DCMQR46R.js.map} +0 -0
  356. /package/dist/{chunk-TG634KCO.js.map → chunk-DG27IUVI.js.map} +0 -0
  357. /package/dist/{chunk-V6UQZA2H.js.map → chunk-E6427JU2.js.map} +0 -0
  358. /package/dist/{chunk-TWPK7KUJ.js.map → chunk-F3GVO44K.js.map} +0 -0
  359. /package/dist/{chunk-QD46HPZG.js.map → chunk-FAXZQ5UF.js.map} +0 -0
  360. /package/dist/{chunk-IG6KUWBX.js.map → chunk-FNSMZQS4.js.map} +0 -0
  361. /package/dist/{chunk-BLBAQRBM.js.map → chunk-FUHKW252.js.map} +0 -0
  362. /package/dist/{chunk-SU6SGWXM.js.map → chunk-FY343IZR.js.map} +0 -0
  363. /package/dist/{chunk-DAFBJS4Y.js.map → chunk-GS5RT2KK.js.map} +0 -0
  364. /package/dist/{chunk-5UQ7Y6SQ.js.map → chunk-HFKGIBMD.js.map} +0 -0
  365. /package/dist/{chunk-SHEEBRZ4.js.map → chunk-HVQGCKY4.js.map} +0 -0
  366. /package/dist/{chunk-35NMVJ7I.js.map → chunk-HXGUIPQB.js.map} +0 -0
  367. /package/dist/{chunk-ERGECZEI.js.map → chunk-JEM2IGS3.js.map} +0 -0
  368. /package/dist/{chunk-L3YYLT4E.js.map → chunk-JIUVJ4M7.js.map} +0 -0
  369. /package/dist/{chunk-55LX6FSX.js.map → chunk-JRCYZEHU.js.map} +0 -0
  370. /package/dist/{chunk-SFBYQMZM.js.map → chunk-JSRU5W2M.js.map} +0 -0
  371. /package/dist/{chunk-NM5UYF6Q.js.map → chunk-JXIDGFKS.js.map} +0 -0
  372. /package/dist/{chunk-RO5NM6UI.js.map → chunk-KZ3KMDN3.js.map} +0 -0
  373. /package/dist/{chunk-HZZP2ZIG.js.map → chunk-LBGPO5RL.js.map} +0 -0
  374. /package/dist/{chunk-CLE3TMIS.js.map → chunk-MC2LFTQM.js.map} +0 -0
  375. /package/dist/{chunk-W3G5REIU.js.map → chunk-MSWYQLMQ.js.map} +0 -0
  376. /package/dist/{chunk-SGDPRCC4.js.map → chunk-MZ5ZFO2D.js.map} +0 -0
  377. /package/dist/{chunk-EFJAAFBW.js.map → chunk-NQRJ5AJO.js.map} +0 -0
  378. /package/dist/{chunk-Q2SEJMP2.js.map → chunk-NVU7ZMPN.js.map} +0 -0
  379. /package/dist/{chunk-ZTLOXFPB.js.map → chunk-OF3L2SD6.js.map} +0 -0
  380. /package/dist/{chunk-LLYIMSQQ.js.map → chunk-OMSAULZM.js.map} +0 -0
  381. /package/dist/{chunk-SF2ZIRD6.js.map → chunk-OSFPNKY4.js.map} +0 -0
  382. /package/dist/{chunk-WUHEP3HH.js.map → chunk-P7NGLLUF.js.map} +0 -0
  383. /package/dist/{chunk-RQ4ZI4ZI.js.map → chunk-PGAPBZEK.js.map} +0 -0
  384. /package/dist/{chunk-T2MOJF76.js.map → chunk-PP5CO2PR.js.map} +0 -0
  385. /package/dist/{chunk-QGIBI6GL.js.map → chunk-ROWL352P.js.map} +0 -0
  386. /package/dist/{chunk-ZHDSUZQU.js.map → chunk-RPXL6KSX.js.map} +0 -0
  387. /package/dist/{chunk-DTFA5DO4.js.map → chunk-SKONR2OL.js.map} +0 -0
  388. /package/dist/{chunk-4ZKNC6A6.js.map → chunk-T4GPR2IR.js.map} +0 -0
  389. /package/dist/{chunk-TS5XLBZR.js.map → chunk-TLNNHG3A.js.map} +0 -0
  390. /package/dist/{chunk-6UBZ6I5Z.js.map → chunk-UHXCLPGC.js.map} +0 -0
  391. /package/dist/{chunk-KD4HGBJV.js.map → chunk-V5C5NNBR.js.map} +0 -0
  392. /package/dist/{chunk-5GQEU4DN.js.map → chunk-VJFMXYKP.js.map} +0 -0
  393. /package/dist/{chunk-5DRROK5W.js.map → chunk-VMCCGUQB.js.map} +0 -0
  394. /package/dist/{chunk-IXNCZTWA.js.map → chunk-W3TVWF6N.js.map} +0 -0
  395. /package/dist/{chunk-W66AM5IB.js.map → chunk-WLYIROCJ.js.map} +0 -0
  396. /package/dist/{chunk-OWHP3H5C.js.map → chunk-XB7LUDKM.js.map} +0 -0
  397. /package/dist/{chunk-KYRDJI5O.js.map → chunk-XBLKM73C.js.map} +0 -0
  398. /package/dist/{chunk-MHMLXJ3I.js.map → chunk-YAWK6AWF.js.map} +0 -0
  399. /package/dist/{chunk-PWPYO73B.js.map → chunk-ZGGVOADG.js.map} +0 -0
  400. /package/dist/{chunk-IFOH7RBI.js.map → chunk-ZWMO5GL5.js.map} +0 -0
  401. /package/dist/{chunk-LRRX57UA.js.map → chunk-ZXJXDHNK.js.map} +0 -0
  402. /package/dist/{classified-marker-LE54HWSX.js.map → classified-marker-MH3ON5OL.js.map} +0 -0
  403. /package/dist/{collection-facade-DO2AABZT.js.map → collection-facade-AHT7FATG.js.map} +0 -0
  404. /package/dist/{computed-AB45PS4V.js.map → computed-6G5M3UPH.js.map} +0 -0
  405. /package/dist/{dead-filter-V3LVWYEJ.js.map → dead-filter-U575NGSH.js.map} +0 -0
  406. /package/dist/{delegation-JDUMAF6L.js.map → delegation-PDYL6RWT.js.map} +0 -0
  407. /package/dist/{derive-ZPGVLE2Q.js.map → derive-AKT4KU36.js.map} +0 -0
  408. /package/dist/{dispatch-6TV3DGO6.js.map → dispatch-4XIJSFTT.js.map} +0 -0
  409. /package/dist/{dispatch-W7NWQ637.js.map → dispatch-N5HGVUGU.js.map} +0 -0
  410. /package/dist/{enclave-YFCLPIDR.js.map → enclave-OPK24QDR.js.map} +0 -0
  411. /package/dist/{executor-FPHKWDWT.js.map → executor-3JZ4POTW.js.map} +0 -0
  412. /package/dist/{executor-IEBLTBCW.js.map → executor-CYJQLKKI.js.map} +0 -0
  413. /package/dist/{executor-RM7XWQDU.js.map → executor-S4QIKEHW.js.map} +0 -0
  414. /package/dist/{export-accessible-EKM3HGB2.js.map → export-accessible-CPTP5STN.js.map} +0 -0
  415. /package/dist/{extract-partition-LS4ET5A6.js.map → extract-partition-TWXPHVU7.js.map} +0 -0
  416. /package/dist/{fanout-sidecar-273RDMYS.js.map → fanout-sidecar-T2ZGLQFE.js.map} +0 -0
  417. /package/dist/{find-OZMTRIK3.js.map → find-RBBYKXI7.js.map} +0 -0
  418. /package/dist/{issue-LIA7FXBJ.js.map → issue-N74C55X6.js.map} +0 -0
  419. /package/dist/{ledger-XE7JF2I2.js.map → ledger-DONWFC5M.js.map} +0 -0
  420. /package/dist/{liberate-WZ3RHVKW.js.map → liberate-KICI7AJN.js.map} +0 -0
  421. /package/dist/{link-set-CGYC3OH5.js.map → link-set-2TTP4VLO.js.map} +0 -0
  422. /package/dist/{noydb-ZLPVCDES.js.map → managed-secret-EAOYWRYF.js.map} +0 -0
  423. /package/dist/{register-6RIBIT3I.js.map → noydb-6W2XGQCS.js.map} +0 -0
  424. /package/dist/{post-register-LY35EDTJ.js.map → post-register-ORQOQJCS.js.map} +0 -0
  425. /package/dist/{registry-7Y5WF7GS.js.map → register-LHETZRJM.js.map} +0 -0
  426. /package/dist/{registry-BWD2ED52.js.map → registry-AMAZ6QRZ.js.map} +0 -0
  427. /package/dist/{registry-MUSL4AW6.js.map → registry-CZVINVQH.js.map} +0 -0
  428. /package/dist/{registry-RON4WHAP.js.map → registry-IKUR2MXD.js.map} +0 -0
  429. /package/dist/{request-withdrawal-FT3ORAWN.js.map → registry-JRIN447B.js.map} +0 -0
  430. /package/dist/{revoke-HC7WG3HE.js.map → request-withdrawal-2DN2RGCO.js.map} +0 -0
  431. /package/dist/{reveal-T34ADTPY.js.map → reveal-AG4SCHUQ.js.map} +0 -0
  432. /package/dist/{signer-CTWOH6KT.js.map → revoke-ZX4NM2CJ.js.map} +0 -0
  433. /package/dist/{stale-T3V7XEOB.js.map → signer-7KHD4OL2.js.map} +0 -0
  434. /package/dist/{storage-LLNLPWWB.js.map → stale-K734VACF.js.map} +0 -0
  435. /package/dist/{walk-G3NFEP5L.js.map → storage-4H2GF6RQ.js.map} +0 -0
  436. /package/dist/{store-coordination-provider-AHGFEMFA.js.map → store-coordination-provider-4SKLSFUG.js.map} +0 -0
  437. /package/dist/{verify-7XWHJWUN.js.map → verify-RO5RTZOJ.js.map} +0 -0
  438. /package/dist/{withdraw-accessible-ANSVG6XG.js.map → walk-MQHYNDLZ.js.map} +0 -0
@@ -0,0 +1,74 @@
1
+ /**
2
+ * `beginEchoUnlock` — the interactive ceremony API (spec
3
+ * docs/superpowers/specs/2026-08-02-echo-secret-design.md, #940, Task 6).
4
+ *
5
+ * Split out of `echo-secret.ts` (which owns only the block builders +
6
+ * verifiers) because this module orchestrates BOTH `echo-secret.ts`
7
+ * (`verifyPrompt`/`resolveEchoReveal`/`verifyTypedEcho`) AND `keyring.ts`
8
+ * (`loadKeyring`) — and `keyring.ts` itself imports `buildEchoBlock` from
9
+ * `echo-secret.ts`. Keeping the ceremony here instead of inside
10
+ * `echo-secret.ts` yields a clean DAG (`echo-ceremony.ts` → {`echo-secret.ts`,
11
+ * `keyring.ts`}; `keyring.ts` → `echo-secret.ts`) instead of a two-file
12
+ * cycle, and restores `echo-secret.ts`'s documented charter (builders +
13
+ * verifiers only).
14
+ *
15
+ * @module
16
+ */
17
+ import type { NoydbStore } from '../../kernel/types.js';
18
+ import type { DeviceSealProvider } from './device-seal.js';
19
+ import { type UnlockedKeyring } from './keyring.js';
20
+ /** Options for {@link beginEchoUnlock}. */
21
+ export interface BeginEchoUnlockOptions {
22
+ readonly userId: string;
23
+ readonly prompt: string;
24
+ readonly deviceSeal?: DeviceSealProvider;
25
+ }
26
+ /**
27
+ * A prompt-verified, in-progress echo unlock. Stateless w.r.t. attempts —
28
+ * `complete()` may be called more than once (e.g. retry after a wrong key).
29
+ */
30
+ export interface EchoCeremony {
31
+ /**
32
+ * Echo to display for owner recognition; null ⇒ degraded: ask the owner to
33
+ * TYPE it.
34
+ *
35
+ * Conforming-player contract (spec
36
+ * docs/superpowers/specs/2026-08-02-echo-secret-design.md, "Ceremony"):
37
+ * when the owner does NOT recognize the revealed echo, the player MUST show
38
+ * a hard phishing warning — do not continue, open the official app, rotate
39
+ * the secret immediately — MUST NOT offer any skip or
40
+ * "verification unavailable" fallback, and MUST simply abandon the ceremony
41
+ * by never calling {@link EchoCeremony.complete}. The kernel cannot enforce
42
+ * this terminal state; it is the player's obligation.
43
+ */
44
+ readonly reveal: string | null;
45
+ readonly maskHint: string | undefined;
46
+ /** Complete the ceremony. `echo` is REQUIRED when `reveal` is null. */
47
+ complete(input: {
48
+ readonly echo?: string;
49
+ readonly key: string;
50
+ }): Promise<UnlockedKeyring>;
51
+ }
52
+ /**
53
+ * Begin the interactive anti-phishing unlock ceremony (spec decision 4):
54
+ * prompt → echo reveal → key. Fetches and parses the `_keyring/{userId}`
55
+ * row (same store path as `loadKeyring`), verifies the prompt, and resolves
56
+ * the echo for display (or degrades to the typed-echo path when the reveal
57
+ * cannot be resolved — sealed reveal under a foreign device).
58
+ *
59
+ * Conforming-player contract (spec
60
+ * docs/superpowers/specs/2026-08-02-echo-secret-design.md): an owner who does
61
+ * not recognize `ceremony.reveal` is looking at a phish. The player MUST then
62
+ * show a hard warning (stop, open the official app, rotate the secret now),
63
+ * MUST NOT offer a skip / "verification unavailable" fallback or any
64
+ * single-field secret entry, and MUST abandon the ceremony without calling
65
+ * `complete()`.
66
+ *
67
+ * @throws NoAccessError when no keyring exists for `userId` (mirrors
68
+ * `loadKeyring`'s missing-row error).
69
+ * @throws KeyringExpiredError when the slot is past its `expires_at` —
70
+ * checked before the prompt is verified, so an expired slot never reveals.
71
+ * @throws ValidationError when the keyring is not an echo keyring.
72
+ * @throws WrongPromptError when the prompt fails its verifier.
73
+ */
74
+ export declare function beginEchoUnlock(store: NoydbStore, vault: string, opts: BeginEchoUnlockOptions): Promise<EchoCeremony>;
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Echo-block builders + verifiers (spec
3
+ * docs/superpowers/specs/2026-08-02-echo-secret-design.md, #940).
4
+ *
5
+ * Builds and verifies the on-keyring {@link KeyringEchoBlock} declaration
6
+ * for the 3-part echo ceremony (prompt → echo → key). This module owns:
7
+ *
8
+ * - Minting the prompt/echo canary verifiers (the "canary trick": AES-KW
9
+ * wrap a constant 32-byte key under `deriveSecretKey(part, salt, …)`;
10
+ * verify = unwrap succeeds).
11
+ * - Building the reveal blob per the hybrid reveal policy (spec decision
12
+ * 4): `portable` (AES-GCM under the prompt, own salt), `sealed`
13
+ * (opaque to hub, unsealed only by the enrolling device's
14
+ * {@link DeviceSealProvider}), or `none`.
15
+ * - Resolving the echo for display (`resolveEchoReveal`, `null` ⇒
16
+ * degraded typed-echo path) and verifying a typed echo
17
+ * (`verifyTypedEcho`) for that degraded path.
18
+ *
19
+ * Deriving the actual KEK from all three parts together is
20
+ * `deriveEchoKey`/`encodeEchoParts` (`kernel/enclave/crypto.ts`) — a
21
+ * separate concern from this module's per-part verifiers.
22
+ *
23
+ * Known, accepted disclosure: `prompt_verifier` and `echo_verifier` are
24
+ * offline brute-force oracles for anyone holding the keyring file (600K
25
+ * PBKDF2 per guess), and the `sealed` reveal blob is unpadded so its length
26
+ * discloses the echo's UTF-8 byte length — see the threat model in
27
+ * `docs/superpowers/specs/2026-08-02-echo-secret-design.md`.
28
+ *
29
+ * @module
30
+ */
31
+ import { type EchoSecretParts } from '../../kernel/enclave/index.js';
32
+ import type { KeyringEchoBlock } from '../../kernel/types.js';
33
+ import type { DeviceSealProvider } from './device-seal.js';
34
+ /** Same iteration floor as the KEK (spec resolved question 1). */
35
+ export declare const ECHO_KDF_ITERATIONS = 600000;
36
+ export type EchoRevealChoice = {
37
+ readonly kind: 'portable';
38
+ } | {
39
+ readonly kind: 'sealed';
40
+ readonly deviceSeal: DeviceSealProvider;
41
+ } | {
42
+ readonly kind: 'none';
43
+ };
44
+ /** Build the on-keyring echo declaration for a fresh enrollment. */
45
+ export declare function buildEchoBlock(parts: EchoSecretParts, reveal: EchoRevealChoice, maskHint?: string): Promise<KeyringEchoBlock>;
46
+ export declare function verifyPrompt(block: KeyringEchoBlock, prompt: string): Promise<boolean>;
47
+ /**
48
+ * Resolve the echo for display. `null` ⇒ degraded path: the player
49
+ * must ask the owner to TYPE the echo (verify via {@link verifyTypedEcho}).
50
+ * Callers MUST verify the prompt first — this assumes it.
51
+ *
52
+ * @throws WrongPromptError when the prompt cannot open the portable reveal
53
+ * (callers should verifyPrompt first for a boolean check).
54
+ */
55
+ export declare function resolveEchoReveal(block: KeyringEchoBlock, prompt: string, deviceSeal?: DeviceSealProvider): Promise<string | null>;
56
+ export declare function verifyTypedEcho(block: KeyringEchoBlock, echo: string): Promise<boolean>;
@@ -32,4 +32,12 @@ export type { WrappedDeksBlob } from './wrapped-deks.js';
32
32
  export { writeMagicLinkGrant, readMagicLinkGrantRecord, listMagicLinkGrants, unwrapMagicLinkGrant, revokeMagicLinkGrant, deriveMagicLinkContentKey, magicLinkGrantRecordId, isMagicLinkGrantExpired, } from './magic-link-grant.js';
33
33
  export { hasExportCapability, evaluateExportCapability, } from './keyring.js';
34
34
  export { hasImportCapability, evaluateImportCapability, } from './keyring.js';
35
+ export { buildEchoBlock, verifyPrompt, resolveEchoReveal, verifyTypedEcho, } from './echo-secret.js';
36
+ export type { EchoRevealChoice } from './echo-secret.js';
37
+ export { beginEchoUnlock } from './echo-ceremony.js';
38
+ export type { BeginEchoUnlockOptions, EchoCeremony } from './echo-ceremony.js';
39
+ export { MemoryDeviceSealProvider } from './device-seal.js';
40
+ export type { DeviceSealProvider } from './device-seal.js';
41
+ export type { EchoSecretParts } from '../../kernel/enclave/index.js';
42
+ export type { KeyringEchoBlock, NoydbStore } from '../../kernel/types.js';
35
43
  export { describeAuthConfig, diagramAuthConfig, describeUserAuth, describeAllUsersAuth, } from '../auth-introspection/index.js';
@@ -1,6 +1,7 @@
1
- import type { NoydbStore, KeyringFile, KeyringAuthenticator, Role, Permissions, GrantOptions, RevokeOptions, UpdateUserOptions, UserInfo, ExportCapability, ExportFormat, ImportCapability, VaultPolicyOnDisk, UserEnvelope } from '../../kernel/types.js';
2
- import { type EnclaveKey } from '../../kernel/enclave/index.js';
3
- import { type SecretPolicy } from '../../kernel/validation.js';
1
+ import type { NoydbStore, KeyringFile, KeyringAuthenticator, Role, Permissions, GrantOptions, RevokeOptions, UpdateUserOptions, UserInfo, EncryptedEnvelope, ExportCapability, ExportFormat, ImportCapability, VaultPolicyOnDisk, UserEnvelope } from '../../kernel/types.js';
2
+ import { type EnclaveKey, type EchoSecretParts } from '../../kernel/enclave/index.js';
3
+ import { type SecretPolicy, type EchoSecretPolicy } from '../../kernel/validation.js';
4
+ import type { DeviceSealProvider } from './device-seal.js';
4
5
  /** In-memory representation of an unlocked keyring. */
5
6
  export interface UnlockedKeyring {
6
7
  readonly userId: string;
@@ -75,9 +76,34 @@ export declare function mintKeyringCanary(kek: EnclaveKey): Promise<string>;
75
76
  export interface LoadKeyringOptions {
76
77
  /** The user whose keyring to unlock. */
77
78
  readonly userId: string;
78
- /** That user's secret. */
79
- readonly secret: string;
79
+ /**
80
+ * That user's secret — a single string for a standard keyring, or the
81
+ * structured 3-part {@link EchoSecretParts} for an echo keyring (spec
82
+ * #940, AG-1: a single string can never unlock an echo keyring).
83
+ */
84
+ readonly secret: string | EchoSecretParts;
80
85
  }
86
+ /**
87
+ * KDF dispatch for tier-1 unlock (spec #940). An echo keyring accepts
88
+ * ONLY structured parts (AG-1 — no single string is key-equivalent);
89
+ * a standard keyring accepts only a string.
90
+ */
91
+ export declare function deriveKekForKeyring(file: KeyringFile, secret: string | EchoSecretParts, salt: Uint8Array): Promise<EnclaveKey>;
92
+ /** Parse a raw keyring envelope. Single sanctioned reader of `_data` for keyring files. */
93
+ export declare function parseKeyringEnvelope(envelope: EncryptedEnvelope): KeyringFile;
94
+ /** Fetch + parse a user's keyring file; undefined when the row is missing. */
95
+ export declare function readKeyringFile(store: NoydbStore, vault: string, userId: string): Promise<{
96
+ readonly envelope: EncryptedEnvelope;
97
+ readonly file: KeyringFile;
98
+ } | undefined>;
99
+ /**
100
+ * Shared expiry gate — refuse to unwrap an expired slot. Call before any
101
+ * KEK derivation so an expired slot doesn't leak timing on the secret.
102
+ * Comparison uses Date.parse → ms-since-epoch; an unparseable expires_at is
103
+ * treated as "no expiry" so a malformed value can't silently lock users out
104
+ * (it'll surface in tests).
105
+ */
106
+ export declare function assertKeyringNotExpired(file: KeyringFile): void;
81
107
  /** Load and unlock a user's keyring for a vault. */
82
108
  export declare function loadKeyring(store: NoydbStore, vault: string, opts: LoadKeyringOptions): Promise<UnlockedKeyring>;
83
109
  /**
@@ -100,12 +126,34 @@ export declare function assertKeyringOpenAllowed(store: NoydbStore, vault: strin
100
126
  export interface CreateOwnerKeyringOptions extends SecretPolicy {
101
127
  /** The owner to create. */
102
128
  readonly userId: string;
103
- /** The owner's secret. */
104
- readonly secret: string;
129
+ /**
130
+ * The owner's secret — a plain string for a standard keyring, or the
131
+ * structured 3-part {@link EchoSecretParts} to enroll an echo keyring
132
+ * (spec #940). The shape alone selects the KDF and whether an `echo`
133
+ * block is written.
134
+ */
135
+ readonly secret: string | EchoSecretParts;
105
136
  /** Gate creation on the phrase-format strength rules. Default false. */
106
137
  readonly validate?: boolean;
107
138
  /** Escape hatch for fixtures and migrations — skips the strength gate. */
108
139
  readonly allowWeakSecret?: boolean;
140
+ /**
141
+ * Echo enrollment only: device-local sealer for the reveal blob. Present
142
+ * ⇒ `reveal: 'sealed'` (attacker-B resistance); absent ⇒ `reveal:
143
+ * 'portable'` (spec resolved question 4). Ignored for a string secret.
144
+ */
145
+ readonly deviceSeal?: DeviceSealProvider;
146
+ /** Echo enrollment only: optional display hint for the masked echo. */
147
+ readonly echoMaskHint?: string;
148
+ /**
149
+ * Echo enrollment only: strength-policy knobs for the 3-part secret's
150
+ * prompt / combined floors — the parts-path counterpart of the
151
+ * flattened `SecretPolicy` fields this options bag already extends
152
+ * (those apply to a STRING secret via `assertStrongSecret`; this
153
+ * applies to {@link EchoSecretParts} via `assertStrongEchoSecret`).
154
+ * Ignored for a string secret.
155
+ */
156
+ readonly echoSecretPolicy?: EchoSecretPolicy;
109
157
  }
110
158
  /**
111
159
  * Create the initial owner keyring for a new vault.
@@ -196,6 +244,15 @@ export interface ChangeSecretOptions extends SecretPolicy {
196
244
  * the OLD secret is not retyped.
197
245
  */
198
246
  export declare function changeSecret(store: NoydbStore, vault: string, keyring: UnlockedKeyring, opts: ChangeSecretOptions): Promise<UnlockedKeyring>;
247
+ /**
248
+ * Echo-mode recipient secret (spec #940). A pod slot may embed the reveal
249
+ * (`'portable'`, default) or omit it (`'none'`) — `'sealed'` is
250
+ * live-device-only and unavailable here: `writePod` has no device context
251
+ * to seal the reveal blob against.
252
+ */
253
+ export interface EchoRecipientSecret extends EchoSecretParts {
254
+ readonly reveal?: 'portable' | 'none';
255
+ }
199
256
  /**
200
257
  * Recipient slot in a re-keyed `.noydb` bundle. Each slot becomes its
201
258
  * own keyring file inside the bundle, sealed with its own secret.
@@ -209,8 +266,13 @@ export interface BundleRecipient {
209
266
  readonly id: string;
210
267
  /** Optional display name. Defaults to `id`. */
211
268
  readonly displayName?: string;
212
- /** Secret the recipient will type to unlock. */
213
- readonly secret: string;
269
+ /**
270
+ * Secret the recipient will type to unlock — a plain string for a
271
+ * standard keyring, or the structured 3-part {@link EchoRecipientSecret}
272
+ * to embed an echo keyring so the anti-phishing ceremony travels with
273
+ * the pod (spec #940).
274
+ */
275
+ readonly secret: string | EchoRecipientSecret;
214
276
  /** Role on the destination vault. Defaults to `'viewer'`. */
215
277
  readonly role?: Role;
216
278
  /**
@@ -17,13 +17,31 @@
17
17
  * @module
18
18
  */
19
19
  import type { NoydbStore } from '../../kernel/types.js';
20
- import { type EnclaveKey } from '../../kernel/enclave/index.js';
20
+ import { type EnclaveKey, type EchoSecretParts } from '../../kernel/enclave/index.js';
21
21
  import { type PaperRecoveryEntry } from './recovery.js';
22
22
  import type { ShamirRecoveryProvider } from './shamir-recovery-provider.js';
23
- import { type SecretPolicy } from '../../kernel/validation.js';
23
+ import { type SecretPolicy, type EchoSecretPolicy } from '../../kernel/validation.js';
24
24
  import type { UnlockedKeyring } from './keyring.js';
25
+ import type { DeviceSealProvider } from './device-seal.js';
25
26
  import type { KeyringAuthenticator } from '../../kernel/types.js';
26
27
  import type { EnrollAuthenticatorOptions } from './authenticators.js';
28
+ /**
29
+ * Echo-enrollment knobs for a rotation whose NEW secret is 3-part (spec #940).
30
+ *
31
+ * Deliberately NOT exported: it is reachable structurally through
32
+ * {@link RotateSecretInput.echoOptions}, and exporting it would mean adding it
33
+ * to the team + root barrels for a type consumers never need to name.
34
+ */
35
+ interface RotateEchoOptions {
36
+ /**
37
+ * Device-local sealer for the reveal blob. Present ⇒ `reveal: 'sealed'`;
38
+ * absent ⇒ `reveal: 'portable'`. Mirrors
39
+ * {@link CreateOwnerKeyringOptions.deviceSeal}.
40
+ */
41
+ readonly deviceSeal?: DeviceSealProvider;
42
+ /** Optional display hint for the masked echo. */
43
+ readonly maskHint?: string;
44
+ }
27
45
  /**
28
46
  * Context handed to a {@link SlotRewrapCeremony} when `rotateSecret`
29
47
  * preserves a tier-2 slot. The ceremony's job is to re-derive its
@@ -65,10 +83,50 @@ export interface SlotRewrapContext {
65
83
  export type SlotRewrapCeremony = (ctx: SlotRewrapContext) => Promise<EnrollAuthenticatorOptions>;
66
84
  /** Caller payload for {@link rotateSecret}. */
67
85
  export interface RotateSecretInput {
68
- readonly oldSecret: string;
69
- readonly newSecret: string;
86
+ /**
87
+ * The secret currently opening the keyring — a string for a standard
88
+ * keyring, the 3-part {@link EchoSecretParts} for an echo one. The shape
89
+ * must MATCH the stored keyring: `deriveKekForKeyring` refuses a string on
90
+ * an echo keyring (`EchoCeremonyRequiredError`, AG-1) and parts on a
91
+ * standard one (`ValidationError`).
92
+ */
93
+ readonly oldSecret: string | EchoSecretParts;
94
+ /**
95
+ * The secret to rotate TO. Its shape — independent of `oldSecret`'s —
96
+ * decides the keyring's mode after rotation: parts enroll an `echo` block
97
+ * (standard→echo upgrade, or a re-mint on echo→echo), a string removes any
98
+ * existing one (echo→standard downgrade).
99
+ */
100
+ readonly newSecret: string | EchoSecretParts;
101
+ /**
102
+ * Strength-policy knobs applied when `newSecret` is a STRING. Ignored
103
+ * for 3-part {@link EchoSecretParts} — see `echoSecretPolicy` for the
104
+ * parts-path counterpart.
105
+ */
70
106
  readonly secretPolicy?: SecretPolicy;
107
+ /**
108
+ * Strength-policy knobs applied when `newSecret` is 3-part
109
+ * {@link EchoSecretParts} (prompt / combined floors). Ignored for a
110
+ * string `newSecret` — see `secretPolicy` for the string-path
111
+ * counterpart.
112
+ */
113
+ readonly echoSecretPolicy?: EchoSecretPolicy;
71
114
  readonly allowWeakSecret?: boolean;
115
+ /**
116
+ * Echo-enrollment knobs for the block minted when `newSecret` is 3-part.
117
+ * Ignored for a string `newSecret` (no block is written).
118
+ */
119
+ readonly echoOptions?: RotateEchoOptions;
120
+ /**
121
+ * Explicit confirmation for an echo→standard rotation. When the stored
122
+ * keyring has an `echo` block AND `newSecret` is a plain string, the
123
+ * rotation is a security-posture downgrade — and that shape is decided
124
+ * purely by argument shape, so it must be opted into explicitly. Without
125
+ * this flag such a rotation throws `ValidationError` BEFORE any write
126
+ * (and before deriving the new KEK). Upgrades (string→parts) and
127
+ * same-mode rotations (string→string, parts→parts) never require it.
128
+ */
129
+ readonly allowModeDowngrade?: boolean;
72
130
  /**
73
131
  * Map of slot id → re-enrolment ceremony. Slots whose id appears
74
132
  * here are PRESERVED across rotation (the ceremony re-derives the
@@ -99,7 +157,13 @@ export interface RotateSecretInput {
99
157
  * the rewrapped slots atomically with the rotation. Slots whose id
100
158
  * isn't in the map are still dropped.
101
159
  *
160
+ * Either secret may be a string or 3-part {@link EchoSecretParts}; the two
161
+ * shapes are independent, so a rotation doubles as the standard↔echo
162
+ * upgrade/downgrade ceremony (spec #940).
163
+ *
102
164
  * @throws `InvalidKeyError` if `oldSecret` does not unwrap the keyring.
165
+ * @throws `EchoCeremonyRequiredError` if `oldSecret` is a string but the
166
+ * keyring is an echo keyring.
103
167
  * @throws `WeakSecretError` if `newSecret` fails the strength rule.
104
168
  * @throws `ValidationError` if a ceremony's result mismatches the
105
169
  * slot's id or method (anti-slot-swap guard).
@@ -130,9 +194,38 @@ export type RecoveryProof = {
130
194
  };
131
195
  };
132
196
  export interface RecoverSecretInput {
133
- readonly newSecret: string;
197
+ /**
198
+ * The secret to recover TO. As in {@link RotateSecretInput}, the shape
199
+ * decides the recovered keyring's mode: 3-part {@link EchoSecretParts}
200
+ * enroll a fresh (always PORTABLE) `echo` block, a string leaves the
201
+ * keyring standard and removes any block the old one carried.
202
+ *
203
+ * Recovery deliberately has no `echoOptions` counterpart — a device seal
204
+ * would bind the reveal blob to the device running the recovery, which is
205
+ * not necessarily the device the user will unlock from. Seal it afterwards
206
+ * with an explicit `rotateSecret`.
207
+ *
208
+ * A string `newSecret` on a previously-echo keyring performs the same
209
+ * echo→standard downgrade as `rotateSecret`, but WITHOUT an
210
+ * `allowModeDowngrade` gate — recovery is already a proof-gated reset
211
+ * ceremony (a valid recovery code/shares), so the shape-alone check
212
+ * `rotateSecret` needs is redundant here by design.
213
+ */
214
+ readonly newSecret: string | EchoSecretParts;
134
215
  readonly recoveryProof: RecoveryProof;
216
+ /**
217
+ * Strength-policy knobs applied when `newSecret` is a STRING. Ignored
218
+ * for 3-part {@link EchoSecretParts} — see `echoSecretPolicy` for the
219
+ * parts-path counterpart.
220
+ */
135
221
  readonly secretPolicy?: SecretPolicy;
222
+ /**
223
+ * Strength-policy knobs applied when `newSecret` is 3-part
224
+ * {@link EchoSecretParts} (prompt / combined floors). Ignored for a
225
+ * string `newSecret` — see `secretPolicy` for the string-path
226
+ * counterpart.
227
+ */
228
+ readonly echoSecretPolicy?: EchoSecretPolicy;
136
229
  readonly allowWeakSecret?: boolean;
137
230
  /**
138
231
  * After a successful paper-recovery, replace ALL remaining recovery
@@ -273,3 +366,4 @@ export type RecoveryEnrollmentInput = {
273
366
  * stored set).
274
367
  */
275
368
  export declare function recoverSecret(provider: ShamirRecoveryProvider | undefined, store: NoydbStore, vault: string, userId: string, input: RecoverSecretInput): Promise<UnlockedKeyring>;
369
+ export {};
@@ -0,0 +1,9 @@
1
+ import type { NoydbStore } from '../kernel/types.js';
2
+ /**
3
+ * Return the stable opaque bundle handle for the given vault adapter,
4
+ * generating and persisting a fresh ULID on first call.
5
+ *
6
+ * See {@link import('../kernel/vault.js').Vault.getBundleHandle} for
7
+ * the full rationale and storage-path documentation.
8
+ */
9
+ export declare function buildBundleHandle(adapter: NoydbStore, name: string): Promise<string>;
@@ -32,7 +32,9 @@
32
32
  * call can also feed verification tools, format inspectors, or
33
33
  * archive utilities that don't care about decryption.
34
34
  */
35
- import { type NoydbPodHeader } from './format.js';
35
+ import { type NoydbPodHeader, type UnlockMethod } from './format.js';
36
+ import type { Redirect } from './redirect.js';
37
+ import type { DocSigner } from '../with-audit/attestation/signer.js';
36
38
  import type { Vault } from '../kernel/vault.js';
37
39
  import type { BundleRecipient } from '../with-party/team/keyring.js';
38
40
  import type { Cover } from '../with-party/directory/cover/types.js';
@@ -230,6 +232,39 @@ export interface WritePodOptions {
230
232
  readonly provider: SealingKeyProvider;
231
233
  readonly perUser: Record<string, string>;
232
234
  };
235
+ /**
236
+ * Pod-header signing control (#943).
237
+ *
238
+ * - omitted (default) — sign the header iff the source vault has a
239
+ * persisted document signer (`vault._loadPodSigner()` returns
240
+ * non-null). A vault that never minted a signer produces an
241
+ * unsigned `formatVersion: 1` header, exactly as before.
242
+ * - `false` — never sign, even if a signer is persisted.
243
+ * - an explicit {@link DocSigner} — sign with the supplied keypair
244
+ * without touching the vault's persisted signer (test / advanced
245
+ * injection). Does not mint or persist anything.
246
+ *
247
+ * Signing NEVER mints a signer as a side effect of export: an absent
248
+ * signer means an unsigned pod, not an on-the-fly key generation.
249
+ */
250
+ readonly sign?: false | DocSigner;
251
+ /**
252
+ * Header L2 fields (#942) — pre-auth dispatch metadata written verbatim
253
+ * into the pod header. See `NoydbPodHeader` for the disclosure rationale
254
+ * of each. All optional; absence produces a legacy-shaped header exactly
255
+ * as before.
256
+ */
257
+ readonly engineRange?: string;
258
+ readonly unlockMethods?: readonly UnlockMethod[];
259
+ readonly hasApp?: boolean;
260
+ readonly species?: 'full' | 'connection' | 'snapshot' | 'redirect' | 'group';
261
+ readonly pointerMode?: 'public' | 'private';
262
+ /**
263
+ * Signed "this moved, go there" pointer (#944), written verbatim into
264
+ * the plaintext header. Pass an already-signed {@link Redirect}
265
+ * (mint one via `signRedirect`) — `writePod` does not sign it for you.
266
+ */
267
+ readonly redirect?: Redirect;
233
268
  }
234
269
  /** @deprecated Use `WritePodOptions`. */
235
270
  export type WriteNoydbBundleOptions = WritePodOptions;
@@ -353,7 +388,14 @@ export declare function assembleBundleContainer(opts: {
353
388
  bodyJsonStr: string;
354
389
  compression: WritePodOptions['compression'];
355
390
  /** Header fields beyond the always-present four. */
356
- headerExtras?: Partial<Pick<NoydbPodHeader, 'publicEnvelope' | 'autoUnlock' | 'bundleKind' | 'transferSeal'>>;
391
+ headerExtras?: Partial<Pick<NoydbPodHeader, 'publicEnvelope' | 'autoUnlock' | 'bundleKind' | 'transferSeal' | 'engineRange' | 'unlockMethods' | 'hasApp' | 'species' | 'pointerMode' | 'redirect'>>;
392
+ /**
393
+ * When present, the assembled header is signed (#943): the header is
394
+ * bumped to `formatVersion: 2` and carries the sig/keyId/sigAlg tuple.
395
+ * Absent → an unsigned `formatVersion: 1` header (partitions, and pods
396
+ * from vaults without a signer, stay unsigned).
397
+ */
398
+ signer?: DocSigner;
357
399
  }): Promise<Uint8Array>;
358
400
  export declare function writePod(vault: Vault, opts?: WritePodOptions): Promise<Uint8Array>;
359
401
  /** @deprecated Use `writePod`. */
@@ -375,6 +417,50 @@ export declare const writeNoydbBundle: typeof writePod;
375
417
  export declare function readPodHeader(bytes: Uint8Array): NoydbPodHeader;
376
418
  /** @deprecated Use `readPodHeader`. */
377
419
  export declare const readNoydbBundleHeader: typeof readPodHeader;
420
+ /**
421
+ * Outcome of {@link verifyPodHeader}.
422
+ *
423
+ * - `verified` — the header carried a sig-tuple, its `keyId` is in
424
+ * `trustedKeys`, and the signature checks out over the canonical
425
+ * header bytes.
426
+ * - `unsigned` — the header carried no signature (a legacy v1 pod, or a
427
+ * v2 pod written with `{ sign: false }`). Not an error; just unauthenticated.
428
+ * - `untrusted` — the header is signed but its `keyId` is not one the
429
+ * caller trusts. The signature was NOT checked.
430
+ * - `tampered` — the header is signed by a trusted key but the signature
431
+ * does not verify: the signed bytes were altered, or the mapped public
432
+ * key is not the one that actually signed.
433
+ */
434
+ export interface PodVerifyResult {
435
+ readonly status: 'verified' | 'unsigned' | 'untrusted' | 'tampered';
436
+ /** The header's `keyId`, present whenever the header carried a sig-tuple. */
437
+ readonly keyId?: string;
438
+ }
439
+ /**
440
+ * Authenticate a pod header (#943) — a pure, dependency-free, WebCrypto-only
441
+ * verifier. Given only the raw pod bytes and a `trustedKeys` map
442
+ * (`keyId → publicKeyB64` the caller already trusts), it reports whether the
443
+ * header was signed by a trusted document signer.
444
+ *
445
+ * Pairs with the signing half in `assembleBundleContainer`/`writePod`: the
446
+ * signed payload is the final wire header with `sig` removed, so verification
447
+ * reconstructs it by stripping EXACTLY the `sig` field — `keyId`, `sigAlg`,
448
+ * and every other header field stay in the verified payload.
449
+ *
450
+ * No store, enclave, or vault dependency — reachable from a static page with
451
+ * only the pod bytes, the trusted-key map, and `globalThis.crypto`.
452
+ *
453
+ * SECURITY — authenticity is not integrity. A `verified` result proves the
454
+ * header (which includes the *claimed* `bodySha256`) is signed by a trusted
455
+ * key; it does NOT prove the body matches that hash. To trust the pod's
456
+ * BODY you MUST also confirm the body hashes to `header.bodySha256` — call
457
+ * `readPod`, which throws `BundleIntegrityError` on mismatch. A `verified`
458
+ * header paired with a swapped body is caught only by that integrity check.
459
+ * This function stays body-free by design so a static page can authenticate a
460
+ * header without decompressing the body; composing the two checks is the
461
+ * caller's responsibility. See `docs/subsystems/pod-signature.md`.
462
+ */
463
+ export declare function verifyPodHeader(bytes: Uint8Array, trustedKeys: Readonly<Record<string, string>>): Promise<PodVerifyResult>;
378
464
  /**
379
465
  * Read just the bundle's cover (`https://github.com/vLannaAi/noy-db-docs/blob/main/content/docs/services/public-envelope.md`)
380
466
  * — without verifying the body or even parsing the dump JSON. Pass
@@ -391,6 +477,18 @@ export declare const readNoydbBundleHeader: typeof readPodHeader;
391
477
  export declare function readPodCover(bytes: Uint8Array, opts?: {
392
478
  readonly locale?: string;
393
479
  }): Cover | undefined;
480
+ /**
481
+ * Read just the bundle's Redirect record (#944) — without verifying the
482
+ * body or even parsing the dump JSON. Pass the raw bundle bytes; receive
483
+ * the header's `redirect` field or `undefined` if the bundle was written
484
+ * without one.
485
+ *
486
+ * The record is returned UNVERIFIED: `validateBundleHeader` only checks
487
+ * its shape at parse time (a parser has no `trustedKeys`). Callers that
488
+ * intend to follow the redirect MUST separately call `verifyRedirect`
489
+ * (`redirect.js`) before trusting `target`.
490
+ */
491
+ export declare function readPodRedirect(bytes: Uint8Array): Redirect | undefined;
394
492
  /**
395
493
  * Read a full `.noydb` bundle: validate magic + header, verify
396
494
  * integrity hash over the body bytes, decompress, and return the
@@ -46,12 +46,15 @@
46
46
  * bundle and verify its integrity — nothing about the contents.
47
47
  */
48
48
  import type { Cover } from '../with-party/directory/cover/types.js';
49
+ import type { Redirect } from './redirect.js';
49
50
  /** Magic bytes 'NDB1' (ASCII), identifying a NOYDB bundle. */
50
51
  export declare const NOYDB_BUNDLE_MAGIC: Uint8Array<ArrayBuffer>;
51
52
  /** Total fixed prefix before the header JSON: 4+1+1+4 bytes. */
52
53
  export declare const NOYDB_BUNDLE_PREFIX_BYTES = 10;
53
- /** Current bundle format version. Bumped on layout changes. */
54
+ /** Current bundle format version. Bumped on layout changes. Default for unsigned pods. */
54
55
  export declare const NOYDB_BUNDLE_FORMAT_VERSION = 1;
56
+ /** Format version for pods carrying a header signature (`sig`/`keyId`/`sigAlg`). */
57
+ export declare const NOYDB_BUNDLE_FORMAT_VERSION_SIGNED = 2;
55
58
  /**
56
59
  * Bitfield interpretation of the flags byte.
57
60
  *
@@ -157,7 +160,95 @@ export interface NoydbPodHeader {
157
160
  readonly alg: 'aes-256-gcm-pre-shared';
158
161
  readonly sealId: string;
159
162
  };
163
+ /**
164
+ * Non-secret 16-hex-char fingerprint identifying the signing key
165
+ * used for `sig`. A hash prefix, not the key itself — discloses no
166
+ * crypto config, safe under minimum-disclosure. Present iff `sig`
167
+ * and `sigAlg` are also present (all-or-nothing 3-tuple), and only
168
+ * on `formatVersion === 2` headers.
169
+ */
170
+ readonly keyId?: string;
171
+ /**
172
+ * Signature authenticating the rest of the header (base64url,
173
+ * no padding). Verifies the header wasn't tampered with in
174
+ * transit/storage — see `with-pod/signature.ts`. Part of the
175
+ * sig/keyId/sigAlg 3-tuple.
176
+ */
177
+ readonly sig?: string;
178
+ /**
179
+ * Signature algorithm for `sig`. Named `sigAlg` (not `alg`) to
180
+ * avoid confusion with `transferSeal.alg`. Part of the
181
+ * sig/keyId/sigAlg 3-tuple.
182
+ */
183
+ readonly sigAlg?: 'ed25519';
184
+ /**
185
+ * Engine version range that wrote (and can read) this pod, e.g.
186
+ * `'^0.5.0'`. Discloses only a semver range — no timestamps, no
187
+ * identities — so a version-skew triage step (open a decade-old
188
+ * pod → route to a version-matched read-only player instead of a
189
+ * hard failure) or a landing page can branch before any library
190
+ * code runs. Safe under minimum-disclosure: a range says nothing
191
+ * about who wrote the pod or when.
192
+ */
193
+ readonly engineRange?: string;
194
+ /**
195
+ * Declared unlock method(s), e.g. `['password', 'webauthn']`. Lets
196
+ * a landing/player present the right unlock UI pre-library, and is
197
+ * ALL a shared connection pod may disclose about its bootstrap
198
+ * (auth method + endpoint class). Safe under minimum-disclosure: it
199
+ * names a method family, not a credential, key, or identity.
200
+ *
201
+ * The member set mirrors the `@noy-db/on-*` package family
202
+ * (`on-password`, `on-webauthn`, `on-oidc`, `on-totp`,
203
+ * `on-email-otp`, `on-magic-link`, `on-pin`, `on-recovery`,
204
+ * `on-shamir`) — the top-level "which on-* package to load" method
205
+ * name, not the finer-grained `FactorKind` used by policy gates
206
+ * (which splits WebAuthn into `webauthn-roaming` /
207
+ * `webauthn-platform` for factor-proof freshness). `on-threat` is
208
+ * excluded — it's a lockout/duress helper, not an unlock method a
209
+ * landing page would present.
210
+ */
211
+ readonly unlockMethods?: readonly UnlockMethod[];
212
+ /**
213
+ * App-manifest presence flag. Lets a landing fork between
214
+ * "orphan pod → read-only browse" and "linked app → launch flow"
215
+ * without reading the body. Safe under minimum-disclosure: a
216
+ * boolean, not the app's identity or contents.
217
+ */
218
+ readonly hasApp?: boolean;
219
+ /**
220
+ * Artifact species hint for dispatcher branching, cloud tooling,
221
+ * and the share-flow guard that warns when a data-bearing pod is
222
+ * shared where a pointer was intended. An "orphan" pod is derived
223
+ * (`species: 'full'` + `hasApp: false`), not a separate species.
224
+ * Safe under minimum-disclosure: a coarse artifact-shape label, not
225
+ * contents or identity.
226
+ */
227
+ readonly species?: 'full' | 'connection' | 'snapshot' | 'redirect' | 'group';
228
+ /**
229
+ * Whether the app pointer (if any) is disclosed pre-auth. Default
230
+ * is `'private'` by product decision (recorded in #942) — absence
231
+ * means private by convention; this field is never auto-injected,
232
+ * only an author's explicit opt-in writes `'public'`. Safe under
233
+ * minimum-disclosure: a disclosure-policy flag, not the pointer
234
+ * itself.
235
+ */
236
+ readonly pointerMode?: 'public' | 'private';
237
+ /**
238
+ * Signed "this moved, go there" pointer (#944). Carried in the
239
+ * PLAINTEXT header (not the encrypted body) so a dispatcher can follow
240
+ * it pre-auth — no secret, no decompression. Structurally validated
241
+ * here (shape only); the record's OWN signature is a separate
242
+ * verification step (`verifyRedirect`) since a parser has no
243
+ * `trustedKeys`. `readPodRedirect` returns this field UNVERIFIED.
244
+ */
245
+ readonly redirect?: Redirect;
160
246
  }
247
+ /**
248
+ * Declared unlock method names — mirrors the `@noy-db/on-*` package
249
+ * family (see `unlockMethods` doc comment on `NoydbPodHeader`).
250
+ */
251
+ export type UnlockMethod = 'password' | 'webauthn' | 'oidc' | 'totp' | 'email-otp' | 'magic-link' | 'pin' | 'recovery' | 'shamir';
161
252
  /** @deprecated Use `NoydbPodHeader`. */
162
253
  export type NoydbBundleHeader = NoydbPodHeader;
163
254
  /**