@noy-db/hub 0.3.0-pre.11 → 0.3.0-pre.13
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.
- package/dist/aggregate/index.js +4 -4
- package/dist/api-ZGS6LCOF.js +20 -0
- package/dist/as/index.js +11 -11
- package/dist/attestation/index.js +18 -18
- package/dist/{backup-XA5STIYQ.js → backup-BJ57IKAO.js} +28 -11
- package/dist/backup-BJ57IKAO.js.map +1 -0
- package/dist/blobs/index.js +12 -10
- package/dist/blobs/index.js.map +1 -1
- package/dist/broker/index.js +12 -12
- package/dist/bundle/index.js +25 -22
- package/dist/bundle/index.js.map +1 -1
- package/dist/by/index.js +2 -2
- package/dist/cargo/index.js +22 -22
- package/dist/{chunk-WGV4CUZT.js → chunk-2NVOWNI3.js} +4 -4
- package/dist/{chunk-WGV4CUZT.js.map → chunk-2NVOWNI3.js.map} +1 -1
- package/dist/{chunk-OFJ5GPNA.js → chunk-3B5VVCNY.js} +2 -2
- package/dist/{chunk-KPGX66PM.js → chunk-3LQ2YKO4.js} +2 -2
- package/dist/{chunk-D26JB3LZ.js → chunk-3QCRBHCY.js} +2 -2
- package/dist/{chunk-H6CZSDWK.js → chunk-454JXE57.js} +3 -3
- package/dist/{chunk-H6CZSDWK.js.map → chunk-454JXE57.js.map} +1 -1
- package/dist/{chunk-DGH65E7Q.js → chunk-4CTHCN4J.js} +24 -10
- package/dist/chunk-4CTHCN4J.js.map +1 -0
- package/dist/{chunk-4N5QFSNQ.js → chunk-4JBYV75E.js} +5 -5
- package/dist/{chunk-UTLEAJXC.js → chunk-4NXKCLLQ.js} +2 -2
- package/dist/{chunk-ARSAMO24.js → chunk-4VNQOLML.js} +2 -2
- package/dist/{chunk-X6CMGUAG.js → chunk-5M5DVGV7.js} +2 -2
- package/dist/{chunk-DJ3VKYFA.js → chunk-5O3XF4DV.js} +4 -4
- package/dist/chunk-5O3XF4DV.js.map +1 -0
- package/dist/{chunk-XHV25KBM.js → chunk-5YOLBEQ6.js} +2 -2
- package/dist/{chunk-CB25ONKC.js → chunk-6CRIV7DE.js} +2 -2
- package/dist/{chunk-BE7N3AXA.js → chunk-6JTIAGHD.js} +3 -3
- package/dist/{chunk-JOQ53DMI.js → chunk-6QTNZJBS.js} +3 -3
- package/dist/{chunk-BZO4WCJI.js → chunk-6T2SCQRU.js} +4 -4
- package/dist/{chunk-FQQF23MC.js → chunk-7DSTRQIJ.js} +2 -2
- package/dist/{chunk-IP2QBAGS.js → chunk-AUSTCW2X.js} +10 -10
- package/dist/{chunk-A2Y6YFVN.js → chunk-B3HJYUOF.js} +2 -2
- package/dist/{chunk-SRVQHVNX.js → chunk-BDVFPG6Y.js} +5 -5
- package/dist/{chunk-FH542DDY.js → chunk-BIOUI4HL.js} +50 -1
- package/dist/chunk-BIOUI4HL.js.map +1 -0
- package/dist/{chunk-YXOUQ2H7.js → chunk-CAF6WOK7.js} +2 -2
- package/dist/{chunk-H6HM6CVR.js → chunk-CDUQTA3Z.js} +114 -12
- package/dist/chunk-CDUQTA3Z.js.map +1 -0
- package/dist/{chunk-HUS3J5WM.js → chunk-CIE2BASH.js} +2 -2
- package/dist/{chunk-DIRRS7WP.js → chunk-CRI4OUV4.js} +2 -2
- package/dist/{chunk-FXK4X4BL.js → chunk-DLG74CNB.js} +4 -4
- package/dist/{chunk-WTUNZACT.js → chunk-E5ZQT5KX.js} +2 -2
- package/dist/{chunk-DMFNPHCX.js → chunk-EQO2UVP4.js} +6 -6
- package/dist/{chunk-MCEKIAO4.js → chunk-ERJ7FU55.js} +3 -3
- package/dist/{chunk-6QILBDZU.js → chunk-EVVGJDRQ.js} +3 -3
- package/dist/{chunk-7VSGW5KJ.js → chunk-EVX47VBM.js} +2 -2
- package/dist/{chunk-D3EFFFOL.js → chunk-EXK7QRWF.js} +5 -5
- package/dist/{chunk-5JB73NMC.js → chunk-EYZ6IQ6X.js} +5 -5
- package/dist/{chunk-BCYQA5BK.js → chunk-F64IRYG3.js} +2 -2
- package/dist/{chunk-K62IUKOD.js → chunk-FHS2HQSH.js} +5 -5
- package/dist/{chunk-2JMMY7HZ.js → chunk-FM3G3NOY.js} +27 -9
- package/dist/chunk-FM3G3NOY.js.map +1 -0
- package/dist/{chunk-67TNU77I.js → chunk-FUG4SFN3.js} +2 -2
- package/dist/{chunk-ZP5PL65C.js → chunk-GKEWXIV5.js} +2 -2
- package/dist/{chunk-RKRGDAS7.js → chunk-GTGPO5KW.js} +5 -5
- package/dist/{chunk-MSPNM2OM.js → chunk-HB3RFQSC.js} +3 -3
- package/dist/{chunk-W5D62AQD.js → chunk-HDMEGAQE.js} +20 -7
- package/dist/chunk-HDMEGAQE.js.map +1 -0
- package/dist/chunk-HDQIIUPH.js +135 -0
- package/dist/chunk-HDQIIUPH.js.map +1 -0
- package/dist/{chunk-7QIXUSDQ.js → chunk-HTJQYHZP.js} +15 -12
- package/dist/chunk-HTJQYHZP.js.map +1 -0
- package/dist/{chunk-OOLO4LQG.js → chunk-I6GALP6E.js} +6 -6
- package/dist/{chunk-57V5S7PW.js → chunk-IL6POWCW.js} +6 -6
- package/dist/{chunk-7NS43EXZ.js → chunk-IU6SNYX6.js} +5 -5
- package/dist/{chunk-5ZOSG3RJ.js → chunk-J2ZX2XUV.js} +5 -5
- package/dist/{chunk-L2SNBIV7.js → chunk-JIF24JPM.js} +57 -15
- package/dist/chunk-JIF24JPM.js.map +1 -0
- package/dist/{chunk-SYMS4546.js → chunk-JKJOGPZN.js} +2 -2
- package/dist/{chunk-CKZW6P5V.js → chunk-JNAI2HN2.js} +1 -1
- package/dist/chunk-JNAI2HN2.js.map +1 -0
- package/dist/{chunk-AWB5JZW6.js → chunk-JZUV47FZ.js} +2 -2
- package/dist/{chunk-ODJWBC5I.js → chunk-K5IMOGHB.js} +2 -2
- package/dist/{chunk-3G4KMVUN.js → chunk-KSKBRKGJ.js} +3 -3
- package/dist/{chunk-HFJIGWJC.js → chunk-LASZKVMO.js} +3 -3
- package/dist/{chunk-IGJHJYM6.js → chunk-LXEXBTKL.js} +4 -4
- package/dist/{chunk-3CNQ7FQ3.js → chunk-M4CV6BRT.js} +119 -25
- package/dist/chunk-M4CV6BRT.js.map +1 -0
- package/dist/{chunk-H44ZE4IE.js → chunk-MEFJPTZ4.js} +33 -17
- package/dist/chunk-MEFJPTZ4.js.map +1 -0
- package/dist/{chunk-PR5LC5YX.js → chunk-MV43JSJF.js} +4 -4
- package/dist/{chunk-ELNBMFOS.js → chunk-NJ4EOKMB.js} +4 -4
- package/dist/{chunk-PXWVF7MC.js → chunk-NR5LT5RY.js} +7 -7
- package/dist/{chunk-QYPKGVT4.js → chunk-NWSGI5C7.js} +3 -3
- package/dist/{chunk-P5RY4ZWD.js → chunk-OSDB5WW3.js} +92 -15
- package/dist/chunk-OSDB5WW3.js.map +1 -0
- package/dist/chunk-PN2XMATY.js +37 -0
- package/dist/chunk-PN2XMATY.js.map +1 -0
- package/dist/{chunk-25NDNMQ7.js → chunk-Q5VNKNE5.js} +3 -3
- package/dist/{chunk-CIKY6I4W.js → chunk-QLWMEXCT.js} +2 -2
- package/dist/{chunk-VA4ZWLFY.js → chunk-QRB7NAOJ.js} +2 -2
- package/dist/{chunk-3MSQLQNZ.js → chunk-R4ROFEYC.js} +2 -2
- package/dist/{chunk-BEIRE5K4.js → chunk-RCVJZMFE.js} +4 -4
- package/dist/{chunk-VR24ILCR.js → chunk-RIX4V2TB.js} +3 -3
- package/dist/{chunk-Q3XSMOZM.js → chunk-RYCTDFUX.js} +2 -2
- package/dist/{chunk-7E67FJ33.js → chunk-RZ5SVOYR.js} +2 -2
- package/dist/{chunk-IDIV5NVH.js → chunk-SLFHQTTW.js} +5 -5
- package/dist/chunk-SNZ6URZZ.js +2782 -0
- package/dist/chunk-SNZ6URZZ.js.map +1 -0
- package/dist/{chunk-C3YH34IL.js → chunk-T2FFWNPK.js} +3 -3
- package/dist/{chunk-O2DYPAZY.js → chunk-UNFPPVNI.js} +2 -2
- package/dist/{chunk-MELR46EF.js → chunk-VFUPHI2Z.js} +63 -10
- package/dist/chunk-VFUPHI2Z.js.map +1 -0
- package/dist/{chunk-GA2QHD6P.js → chunk-VLFCJYTL.js} +9 -9
- package/dist/{chunk-YSXEFGND.js → chunk-VN3DBQAU.js} +2 -2
- package/dist/{chunk-C7NTK5I3.js → chunk-VZRODIM3.js} +4 -4
- package/dist/{chunk-QLLKLFE2.js → chunk-W22IKJE2.js} +2 -2
- package/dist/{chunk-5XIPOCQC.js → chunk-X3YYQWOQ.js} +3 -3
- package/dist/{chunk-A2QF4JUE.js → chunk-X7QBD67R.js} +625 -293
- package/dist/chunk-X7QBD67R.js.map +1 -0
- package/dist/{chunk-QQJXBZCO.js → chunk-XDYREZWE.js} +82 -10
- package/dist/chunk-XDYREZWE.js.map +1 -0
- package/dist/{chunk-OEAATWH5.js → chunk-XWZVFISC.js} +40 -6
- package/dist/{chunk-OEAATWH5.js.map → chunk-XWZVFISC.js.map} +1 -1
- package/dist/{chunk-XFXUTFWQ.js → chunk-YFXZEAYK.js} +6 -6
- package/dist/{chunk-7ITPJFGC.js → chunk-ZAJAVEXY.js} +2 -2
- package/dist/{chunk-4R4Q64W5.js → chunk-ZICD77GM.js} +2 -2
- package/dist/{chunk-45ZZLTFH.js → chunk-ZJ2AK4V7.js} +2 -2
- package/dist/{chunk-UFILRICG.js → chunk-ZUODRVHY.js} +2 -2
- package/dist/classified/index.js +5 -5
- package/dist/{classified-marker-LQWWQNIJ.js → classified-marker-CZKA6ITE.js} +8 -4
- package/dist/classified-marker-CZKA6ITE.js.map +1 -0
- package/dist/collection-facade-TLWIPI76.js +44 -0
- package/dist/{computed-W6MVAMWZ.js → computed-ZIQTYTDI.js} +3 -3
- package/dist/consent/index.js +9 -9
- package/dist/{dead-filter-4KXZEB3X.js → dead-filter-ESOBZZP5.js} +2 -2
- package/dist/delegation-W7ZV2322.js +25 -0
- package/dist/derivations/index.js +12 -12
- package/dist/derive-H2BJTLUI.js +21 -0
- package/dist/{enclave-VXAQD4XJ.js → enclave-AP3I5W7O.js} +15 -9
- package/dist/executor-KGWTNEQD.js +9 -0
- package/dist/executor-OVEXR6RT.js +9 -0
- package/dist/executor-UNEH5ZYH.js +25 -0
- package/dist/export-accessible-PCMXSUZS.js +23 -0
- package/dist/extract-partition-SWHFSYJO.js +38 -0
- package/dist/{fanout-sidecar-CKYFH33E.js → fanout-sidecar-A765THMX.js} +9 -9
- package/dist/find-N6345CNT.js +11 -0
- package/dist/forget/index.js +9 -9
- package/dist/guards/index.js +3 -3
- package/dist/history/index.js +14 -11
- package/dist/history/index.js.map +1 -1
- package/dist/i18n/index.js +14 -14
- package/dist/index.d.ts +5 -1
- package/dist/index.js +108 -89
- package/dist/index.js.map +1 -1
- package/dist/indexing/index.js +5 -5
- package/dist/indexing/index.js.map +1 -1
- package/dist/issue-5OKB6I2R.js +19 -0
- package/dist/kernel/best-effort-revert.d.ts +52 -0
- package/dist/kernel/collection-config.d.ts +28 -0
- package/dist/kernel/collection.d.ts +49 -32
- package/dist/kernel/enclave/classify/verify.d.ts +3 -0
- package/dist/kernel/enclave/index.d.ts +2 -1
- package/dist/kernel/enclave/record-keys/deterministic.d.ts +1 -0
- package/dist/kernel/enclave/record-keys/lifecycle.d.ts +50 -0
- package/dist/kernel/enclave/record-keys/record-codec.d.ts +27 -0
- package/dist/kernel/errors.d.ts +75 -1
- package/dist/kernel/lazy-count.d.ts +13 -0
- package/dist/kernel/noydb.d.ts +8 -0
- package/dist/kernel/tier-visibility.d.ts +54 -0
- package/dist/kernel/types.d.ts +92 -0
- package/dist/kernel/vault.d.ts +23 -6
- package/dist/kernel/via/dispatch.d.ts +10 -0
- package/dist/kernel/via/graph.d.ts +2 -1
- package/dist/{ledger-FU6GH5EH.js → ledger-GFBKVPV4.js} +11 -11
- package/dist/legacy/bundle.d.ts +1 -1
- package/dist/liberate-3VDOT4KO.js +24 -0
- package/dist/{link-set-MNADSH5M.js → link-set-Z7Q2ASFX.js} +11 -11
- package/dist/materialized-views/index.js +18 -18
- package/dist/noydb-ZCJOYBDI.js +68 -0
- package/dist/on/index.js +9 -9
- package/dist/overlay-views/index.js +4 -4
- package/dist/periods/index.js +12 -12
- package/dist/pod/index.js +11 -11
- package/dist/{policy-JTFOPPUU.js → policy-Z3RUAIY2.js} +5 -5
- package/dist/port/with/blob-strategy.d.ts +17 -0
- package/dist/port/with/lookup-strategy.d.ts +2 -1
- package/dist/portability/index.js +8 -8
- package/dist/{post-register-HAWO3O7O.js → post-register-JTH76BLY.js} +12 -7
- package/dist/post-register-JTH76BLY.js.map +1 -0
- package/dist/{public-envelope-NJVB7LPA.js → public-envelope-B4KNWVUA.js} +4 -4
- package/dist/query/index.js +5 -5
- package/dist/register-VAHONCID.js +23 -0
- package/dist/registry-7MLVD3VO.js +19 -0
- package/dist/registry-EPKPD5SM.js +18 -0
- package/dist/registry-P5T7PS2U.js +9 -0
- package/dist/request-withdrawal-TI3A5WPS.js +31 -0
- package/dist/{reveal-BOY7XYFH.js → reveal-DIBHLUZX.js} +7 -7
- package/dist/reveal-DIBHLUZX.js.map +1 -0
- package/dist/revoke-FDRD6GRW.js +24 -0
- package/dist/satellites/index.js +1 -1
- package/dist/sealed-record/index.js +12 -12
- package/dist/{seed-4RRXT42N.js → seed-Q6M2IZFL.js} +11 -11
- package/dist/session/index.js +9 -9
- package/dist/shadow/index.js +2 -2
- package/dist/signer-MUWEIUI6.js +25 -0
- package/dist/snapshots/index.js +10 -10
- package/dist/stale-OSQ7J3AA.js +29 -0
- package/dist/storage-MVFCGEQE.js +23 -0
- package/dist/{store-coordination-provider-HPYVFJCV.js → store-coordination-provider-64OEZFGS.js} +3 -3
- package/dist/sync/index.js +9 -9
- package/dist/team/index.js +15 -15
- package/dist/tiers/index.js +14 -10
- package/dist/to/index.js +1 -1
- package/dist/tx/index.js +3 -3
- package/dist/util/index.js +1 -1
- package/dist/{verify-66RHOW7N.js → verify-ZASTRNPR.js} +9 -8
- package/dist/verify-ZASTRNPR.js.map +1 -0
- package/dist/via/lookup/registry.d.ts +9 -0
- package/dist/via/money/where.d.ts +27 -6
- package/dist/{walk-2RWEOCAS.js → walk-SVNDIZ62.js} +11 -11
- package/dist/with/index.js +11 -11
- package/dist/with-audit/forget/strategy.d.ts +22 -0
- package/dist/with-audit/tiers/index.d.ts +275 -3
- package/dist/with-audit/tiers/strategy.d.ts +5 -4
- package/dist/with-cargo/describe-extraction.d.ts +9 -1
- package/dist/with-cargo/extract-partition.d.ts +9 -1
- package/dist/with-cargo/walk-closure.d.ts +32 -3
- package/dist/with-commit/history/history.d.ts +46 -0
- package/dist/with-commit/history/ledger/store.d.ts +21 -0
- package/dist/with-commit/history/strategy.d.ts +10 -0
- package/dist/with-commit/history/time-machine.d.ts +23 -0
- package/dist/with-commit/tx/elevated-handle.d.ts +2 -1
- package/dist/with-commit/tx/transaction.d.ts +5 -0
- package/dist/with-formula/materialized-views/executor.d.ts +9 -0
- package/dist/with-formula/materialized-views/stale.d.ts +52 -1
- package/dist/with-lookup/embeddings/index.d.ts +1 -0
- package/dist/with-lookup/embeddings/vec-id.d.ts +47 -0
- package/dist/with-lookup/indexing/collection-facade.d.ts +38 -1
- package/dist/with-lookup/indexing/lazy-builder.d.ts +35 -2
- package/dist/with-lookup/indexing/persisted-indexes.d.ts +44 -1
- package/dist/with-lookup/search/collection-facade.d.ts +40 -0
- package/dist/with-lookup/search/persisted-index-store.d.ts +82 -2
- package/dist/with-lookup/search/strategy.d.ts +4 -0
- package/dist/with-party/team/sync.d.ts +9 -0
- package/dist/with-shape/blobs/blob-intent.d.ts +153 -0
- package/dist/with-shape/blobs/blob-set.d.ts +949 -5
- package/dist/with-shape/satellites/fanout.d.ts +5 -4
- package/dist/with-shape/satellites/migrate-cek.d.ts +26 -0
- package/dist/with-shape/satellites/types.d.ts +11 -0
- package/dist/withdraw-accessible-WZIEVWSR.js +28 -0
- package/package.json +3 -3
- package/dist/api-YGMINAET.js +0 -20
- package/dist/backup-XA5STIYQ.js.map +0 -1
- package/dist/chunk-2JMMY7HZ.js.map +0 -1
- package/dist/chunk-3CNQ7FQ3.js.map +0 -1
- package/dist/chunk-7QIXUSDQ.js.map +0 -1
- package/dist/chunk-A2QF4JUE.js.map +0 -1
- package/dist/chunk-AOVDSIL3.js +0 -1221
- package/dist/chunk-AOVDSIL3.js.map +0 -1
- package/dist/chunk-CKZW6P5V.js.map +0 -1
- package/dist/chunk-DGH65E7Q.js.map +0 -1
- package/dist/chunk-DJ3VKYFA.js.map +0 -1
- package/dist/chunk-FH542DDY.js.map +0 -1
- package/dist/chunk-H44ZE4IE.js.map +0 -1
- package/dist/chunk-H6HM6CVR.js.map +0 -1
- package/dist/chunk-L2SNBIV7.js.map +0 -1
- package/dist/chunk-MELR46EF.js.map +0 -1
- package/dist/chunk-P5RY4ZWD.js.map +0 -1
- package/dist/chunk-QQJXBZCO.js.map +0 -1
- package/dist/chunk-TPH5EO6L.js +0 -54
- package/dist/chunk-TPH5EO6L.js.map +0 -1
- package/dist/chunk-W5D62AQD.js.map +0 -1
- package/dist/classified-marker-LQWWQNIJ.js.map +0 -1
- package/dist/collection-facade-YE2O4J4O.js +0 -39
- package/dist/delegation-OPUU3R2E.js +0 -25
- package/dist/derive-BGUHU663.js +0 -21
- package/dist/executor-GTVSUUBX.js +0 -25
- package/dist/executor-GZWMTOXB.js +0 -9
- package/dist/executor-XXGS4S3K.js +0 -9
- package/dist/export-accessible-BMULIOYB.js +0 -23
- package/dist/extract-partition-JUQTWDXR.js +0 -36
- package/dist/find-XRGCNGNN.js +0 -11
- package/dist/issue-UB6AA5M6.js +0 -19
- package/dist/liberate-YUN7W5QG.js +0 -24
- package/dist/noydb-6JLBZU4U.js +0 -67
- package/dist/post-register-HAWO3O7O.js.map +0 -1
- package/dist/register-VCKOBWKT.js +0 -23
- package/dist/registry-72UKJ2L4.js +0 -9
- package/dist/registry-BZFLJNEH.js +0 -18
- package/dist/registry-YJEYSYI5.js +0 -19
- package/dist/request-withdrawal-6MJRMFHF.js +0 -31
- package/dist/reveal-BOY7XYFH.js.map +0 -1
- package/dist/revoke-4KUNSVJC.js +0 -24
- package/dist/signer-DDDXP5JD.js +0 -25
- package/dist/stale-NXPT56JA.js +0 -14
- package/dist/storage-IR6EEAV2.js +0 -23
- package/dist/verify-66RHOW7N.js.map +0 -1
- package/dist/withdraw-accessible-CLMZEHQT.js +0 -28
- /package/dist/{api-YGMINAET.js.map → api-ZGS6LCOF.js.map} +0 -0
- /package/dist/{chunk-OFJ5GPNA.js.map → chunk-3B5VVCNY.js.map} +0 -0
- /package/dist/{chunk-KPGX66PM.js.map → chunk-3LQ2YKO4.js.map} +0 -0
- /package/dist/{chunk-D26JB3LZ.js.map → chunk-3QCRBHCY.js.map} +0 -0
- /package/dist/{chunk-4N5QFSNQ.js.map → chunk-4JBYV75E.js.map} +0 -0
- /package/dist/{chunk-UTLEAJXC.js.map → chunk-4NXKCLLQ.js.map} +0 -0
- /package/dist/{chunk-ARSAMO24.js.map → chunk-4VNQOLML.js.map} +0 -0
- /package/dist/{chunk-X6CMGUAG.js.map → chunk-5M5DVGV7.js.map} +0 -0
- /package/dist/{chunk-XHV25KBM.js.map → chunk-5YOLBEQ6.js.map} +0 -0
- /package/dist/{chunk-CB25ONKC.js.map → chunk-6CRIV7DE.js.map} +0 -0
- /package/dist/{chunk-BE7N3AXA.js.map → chunk-6JTIAGHD.js.map} +0 -0
- /package/dist/{chunk-JOQ53DMI.js.map → chunk-6QTNZJBS.js.map} +0 -0
- /package/dist/{chunk-BZO4WCJI.js.map → chunk-6T2SCQRU.js.map} +0 -0
- /package/dist/{chunk-FQQF23MC.js.map → chunk-7DSTRQIJ.js.map} +0 -0
- /package/dist/{chunk-IP2QBAGS.js.map → chunk-AUSTCW2X.js.map} +0 -0
- /package/dist/{chunk-A2Y6YFVN.js.map → chunk-B3HJYUOF.js.map} +0 -0
- /package/dist/{chunk-SRVQHVNX.js.map → chunk-BDVFPG6Y.js.map} +0 -0
- /package/dist/{chunk-YXOUQ2H7.js.map → chunk-CAF6WOK7.js.map} +0 -0
- /package/dist/{chunk-HUS3J5WM.js.map → chunk-CIE2BASH.js.map} +0 -0
- /package/dist/{chunk-DIRRS7WP.js.map → chunk-CRI4OUV4.js.map} +0 -0
- /package/dist/{chunk-FXK4X4BL.js.map → chunk-DLG74CNB.js.map} +0 -0
- /package/dist/{chunk-WTUNZACT.js.map → chunk-E5ZQT5KX.js.map} +0 -0
- /package/dist/{chunk-DMFNPHCX.js.map → chunk-EQO2UVP4.js.map} +0 -0
- /package/dist/{chunk-MCEKIAO4.js.map → chunk-ERJ7FU55.js.map} +0 -0
- /package/dist/{chunk-6QILBDZU.js.map → chunk-EVVGJDRQ.js.map} +0 -0
- /package/dist/{chunk-7VSGW5KJ.js.map → chunk-EVX47VBM.js.map} +0 -0
- /package/dist/{chunk-D3EFFFOL.js.map → chunk-EXK7QRWF.js.map} +0 -0
- /package/dist/{chunk-5JB73NMC.js.map → chunk-EYZ6IQ6X.js.map} +0 -0
- /package/dist/{chunk-BCYQA5BK.js.map → chunk-F64IRYG3.js.map} +0 -0
- /package/dist/{chunk-K62IUKOD.js.map → chunk-FHS2HQSH.js.map} +0 -0
- /package/dist/{chunk-67TNU77I.js.map → chunk-FUG4SFN3.js.map} +0 -0
- /package/dist/{chunk-ZP5PL65C.js.map → chunk-GKEWXIV5.js.map} +0 -0
- /package/dist/{chunk-RKRGDAS7.js.map → chunk-GTGPO5KW.js.map} +0 -0
- /package/dist/{chunk-MSPNM2OM.js.map → chunk-HB3RFQSC.js.map} +0 -0
- /package/dist/{chunk-OOLO4LQG.js.map → chunk-I6GALP6E.js.map} +0 -0
- /package/dist/{chunk-57V5S7PW.js.map → chunk-IL6POWCW.js.map} +0 -0
- /package/dist/{chunk-7NS43EXZ.js.map → chunk-IU6SNYX6.js.map} +0 -0
- /package/dist/{chunk-5ZOSG3RJ.js.map → chunk-J2ZX2XUV.js.map} +0 -0
- /package/dist/{chunk-SYMS4546.js.map → chunk-JKJOGPZN.js.map} +0 -0
- /package/dist/{chunk-AWB5JZW6.js.map → chunk-JZUV47FZ.js.map} +0 -0
- /package/dist/{chunk-ODJWBC5I.js.map → chunk-K5IMOGHB.js.map} +0 -0
- /package/dist/{chunk-3G4KMVUN.js.map → chunk-KSKBRKGJ.js.map} +0 -0
- /package/dist/{chunk-HFJIGWJC.js.map → chunk-LASZKVMO.js.map} +0 -0
- /package/dist/{chunk-IGJHJYM6.js.map → chunk-LXEXBTKL.js.map} +0 -0
- /package/dist/{chunk-PR5LC5YX.js.map → chunk-MV43JSJF.js.map} +0 -0
- /package/dist/{chunk-ELNBMFOS.js.map → chunk-NJ4EOKMB.js.map} +0 -0
- /package/dist/{chunk-PXWVF7MC.js.map → chunk-NR5LT5RY.js.map} +0 -0
- /package/dist/{chunk-QYPKGVT4.js.map → chunk-NWSGI5C7.js.map} +0 -0
- /package/dist/{chunk-25NDNMQ7.js.map → chunk-Q5VNKNE5.js.map} +0 -0
- /package/dist/{chunk-CIKY6I4W.js.map → chunk-QLWMEXCT.js.map} +0 -0
- /package/dist/{chunk-VA4ZWLFY.js.map → chunk-QRB7NAOJ.js.map} +0 -0
- /package/dist/{chunk-3MSQLQNZ.js.map → chunk-R4ROFEYC.js.map} +0 -0
- /package/dist/{chunk-BEIRE5K4.js.map → chunk-RCVJZMFE.js.map} +0 -0
- /package/dist/{chunk-VR24ILCR.js.map → chunk-RIX4V2TB.js.map} +0 -0
- /package/dist/{chunk-Q3XSMOZM.js.map → chunk-RYCTDFUX.js.map} +0 -0
- /package/dist/{chunk-7E67FJ33.js.map → chunk-RZ5SVOYR.js.map} +0 -0
- /package/dist/{chunk-IDIV5NVH.js.map → chunk-SLFHQTTW.js.map} +0 -0
- /package/dist/{chunk-C3YH34IL.js.map → chunk-T2FFWNPK.js.map} +0 -0
- /package/dist/{chunk-O2DYPAZY.js.map → chunk-UNFPPVNI.js.map} +0 -0
- /package/dist/{chunk-GA2QHD6P.js.map → chunk-VLFCJYTL.js.map} +0 -0
- /package/dist/{chunk-YSXEFGND.js.map → chunk-VN3DBQAU.js.map} +0 -0
- /package/dist/{chunk-C7NTK5I3.js.map → chunk-VZRODIM3.js.map} +0 -0
- /package/dist/{chunk-QLLKLFE2.js.map → chunk-W22IKJE2.js.map} +0 -0
- /package/dist/{chunk-5XIPOCQC.js.map → chunk-X3YYQWOQ.js.map} +0 -0
- /package/dist/{chunk-XFXUTFWQ.js.map → chunk-YFXZEAYK.js.map} +0 -0
- /package/dist/{chunk-7ITPJFGC.js.map → chunk-ZAJAVEXY.js.map} +0 -0
- /package/dist/{chunk-4R4Q64W5.js.map → chunk-ZICD77GM.js.map} +0 -0
- /package/dist/{chunk-45ZZLTFH.js.map → chunk-ZJ2AK4V7.js.map} +0 -0
- /package/dist/{chunk-UFILRICG.js.map → chunk-ZUODRVHY.js.map} +0 -0
- /package/dist/{collection-facade-YE2O4J4O.js.map → collection-facade-TLWIPI76.js.map} +0 -0
- /package/dist/{computed-W6MVAMWZ.js.map → computed-ZIQTYTDI.js.map} +0 -0
- /package/dist/{dead-filter-4KXZEB3X.js.map → dead-filter-ESOBZZP5.js.map} +0 -0
- /package/dist/{delegation-OPUU3R2E.js.map → delegation-W7ZV2322.js.map} +0 -0
- /package/dist/{derive-BGUHU663.js.map → derive-H2BJTLUI.js.map} +0 -0
- /package/dist/{enclave-VXAQD4XJ.js.map → enclave-AP3I5W7O.js.map} +0 -0
- /package/dist/{executor-GTVSUUBX.js.map → executor-KGWTNEQD.js.map} +0 -0
- /package/dist/{executor-GZWMTOXB.js.map → executor-OVEXR6RT.js.map} +0 -0
- /package/dist/{executor-XXGS4S3K.js.map → executor-UNEH5ZYH.js.map} +0 -0
- /package/dist/{export-accessible-BMULIOYB.js.map → export-accessible-PCMXSUZS.js.map} +0 -0
- /package/dist/{extract-partition-JUQTWDXR.js.map → extract-partition-SWHFSYJO.js.map} +0 -0
- /package/dist/{fanout-sidecar-CKYFH33E.js.map → fanout-sidecar-A765THMX.js.map} +0 -0
- /package/dist/{find-XRGCNGNN.js.map → find-N6345CNT.js.map} +0 -0
- /package/dist/{issue-UB6AA5M6.js.map → issue-5OKB6I2R.js.map} +0 -0
- /package/dist/{ledger-FU6GH5EH.js.map → ledger-GFBKVPV4.js.map} +0 -0
- /package/dist/{liberate-YUN7W5QG.js.map → liberate-3VDOT4KO.js.map} +0 -0
- /package/dist/{link-set-MNADSH5M.js.map → link-set-Z7Q2ASFX.js.map} +0 -0
- /package/dist/{noydb-6JLBZU4U.js.map → noydb-ZCJOYBDI.js.map} +0 -0
- /package/dist/{policy-JTFOPPUU.js.map → policy-Z3RUAIY2.js.map} +0 -0
- /package/dist/{public-envelope-NJVB7LPA.js.map → public-envelope-B4KNWVUA.js.map} +0 -0
- /package/dist/{register-VCKOBWKT.js.map → register-VAHONCID.js.map} +0 -0
- /package/dist/{registry-72UKJ2L4.js.map → registry-7MLVD3VO.js.map} +0 -0
- /package/dist/{registry-BZFLJNEH.js.map → registry-EPKPD5SM.js.map} +0 -0
- /package/dist/{registry-YJEYSYI5.js.map → registry-P5T7PS2U.js.map} +0 -0
- /package/dist/{request-withdrawal-6MJRMFHF.js.map → request-withdrawal-TI3A5WPS.js.map} +0 -0
- /package/dist/{revoke-4KUNSVJC.js.map → revoke-FDRD6GRW.js.map} +0 -0
- /package/dist/{seed-4RRXT42N.js.map → seed-Q6M2IZFL.js.map} +0 -0
- /package/dist/{signer-DDDXP5JD.js.map → signer-MUWEIUI6.js.map} +0 -0
- /package/dist/{stale-NXPT56JA.js.map → stale-OSQ7J3AA.js.map} +0 -0
- /package/dist/{storage-IR6EEAV2.js.map → storage-MVFCGEQE.js.map} +0 -0
- /package/dist/{store-coordination-provider-HPYVFJCV.js.map → store-coordination-provider-64OEZFGS.js.map} +0 -0
- /package/dist/{walk-2RWEOCAS.js.map → walk-SVNDIZ62.js.map} +0 -0
- /package/dist/{withdraw-accessible-CLMZEHQT.js.map → withdraw-accessible-WZIEVWSR.js.map} +0 -0
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
dictCollectionName
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-NJ4EOKMB.js";
|
|
4
4
|
import {
|
|
5
5
|
getAtPath,
|
|
6
6
|
presentI18nForJoin
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-6JTIAGHD.js";
|
|
8
8
|
import {
|
|
9
9
|
PeriodClosedError,
|
|
10
10
|
UnknownDictCodeError,
|
|
11
11
|
ValidationError
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-BIOUI4HL.js";
|
|
13
13
|
|
|
14
14
|
// src/via/lookup/registry.ts
|
|
15
15
|
function enforceStaticDictOnPut(staticFields, record) {
|
|
@@ -132,6 +132,15 @@ function collectLookupDictCompat(lookupFields) {
|
|
|
132
132
|
}
|
|
133
133
|
return { dictFieldMap, staticEntries };
|
|
134
134
|
}
|
|
135
|
+
function reservedDictDepsOf(names, dictKeyFieldRegistry) {
|
|
136
|
+
const out = /* @__PURE__ */ new Set();
|
|
137
|
+
for (const name of names) {
|
|
138
|
+
const fieldMap = dictKeyFieldRegistry.get(name);
|
|
139
|
+
if (!fieldMap) continue;
|
|
140
|
+
for (const dictName of Object.values(fieldMap)) out.add(dictCollectionName(dictName));
|
|
141
|
+
}
|
|
142
|
+
return [...out];
|
|
143
|
+
}
|
|
135
144
|
function materializeBackingTable(descriptor, rows) {
|
|
136
145
|
const keys = new Set(rows.keys());
|
|
137
146
|
const owner = /* @__PURE__ */ new Map();
|
|
@@ -345,6 +354,8 @@ async function runGraphDispatchWave(vault, batch) {
|
|
|
345
354
|
for (const [id, intents] of touch.deletes) {
|
|
346
355
|
try {
|
|
347
356
|
await coll._recomputeDeletedRollups(intents, wave);
|
|
357
|
+
await coll.dispatchMaterializedViewsOnDelete(id);
|
|
358
|
+
await coll.dispatchArrayDerivationsOnDelete(id);
|
|
348
359
|
} catch (err) {
|
|
349
360
|
console.warn(`[via-dispatch] wave delete-recompute failed for ${collectionName}/${id}:`, err);
|
|
350
361
|
vault._emit("derivation:wave-error", { collection: collectionName, id, error: err });
|
|
@@ -385,19 +396,21 @@ function ledgerAuditHook(ledger, actor) {
|
|
|
385
396
|
};
|
|
386
397
|
}
|
|
387
398
|
async function forgetDerivedFanout(vault, ref, envelope, stats, lookupCompareKeys) {
|
|
388
|
-
const edges = vault.graph.derivedArtifactsOf(ref.collection);
|
|
389
|
-
if (edges.length === 0) return;
|
|
390
399
|
const coll = vault._getCollection(ref.collection);
|
|
391
|
-
if (
|
|
400
|
+
if (coll) {
|
|
401
|
+
const mv = await coll.dispatchMaterializedViewsOnDelete(ref.id);
|
|
402
|
+
stats.recordsErased += mv.deleted;
|
|
403
|
+
stats.derivedResidueUndecodable.push(...mv.residueUndecodable);
|
|
404
|
+
stats.derivedResidueDeclined.push(...mv.residueDeclined);
|
|
405
|
+
}
|
|
406
|
+
const edges = vault.graph.derivedArtifactsOf(ref.collection);
|
|
407
|
+
if (edges.length === 0 || !coll) return;
|
|
392
408
|
if (edges.some((e) => e.kind === "ref")) {
|
|
393
409
|
const { cascaded, nullified, residue } = await applyLookupRefsFanout(vault, ref.collection, ref.id, lookupCompareKeys);
|
|
394
410
|
stats.lookupReferencesCascaded += cascaded;
|
|
395
411
|
stats.lookupReferencesNullified += nullified;
|
|
396
412
|
stats.lookupReferencesResidue.push(...residue);
|
|
397
413
|
}
|
|
398
|
-
if (edges.some((e) => e.kind === "mv")) {
|
|
399
|
-
stats.recordsErased += await coll.dispatchMaterializedViewsOnDelete(ref.id);
|
|
400
|
-
}
|
|
401
414
|
if (edges.some((e) => e.kind === "derivation")) {
|
|
402
415
|
stats.recordsErased += await coll.dispatchArrayDerivationsOnDelete(ref.id, true);
|
|
403
416
|
}
|
|
@@ -446,6 +459,7 @@ export {
|
|
|
446
459
|
updateReferencingRecords,
|
|
447
460
|
resolveLabelFromMap,
|
|
448
461
|
collectLookupDictCompat,
|
|
462
|
+
reservedDictDepsOf,
|
|
449
463
|
checkLookupMembership,
|
|
450
464
|
coerceLookupKey,
|
|
451
465
|
matchesReferencingValue,
|
|
@@ -463,4 +477,4 @@ export {
|
|
|
463
477
|
ledgerAuditHook,
|
|
464
478
|
forgetDerivedFanout
|
|
465
479
|
};
|
|
466
|
-
//# sourceMappingURL=chunk-
|
|
480
|
+
//# sourceMappingURL=chunk-4CTHCN4J.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/via/lookup/registry.ts","../src/via/lookup/snapshot.ts","../src/port/with/lookup-strategy.ts","../src/kernel/via/dispatch.ts"],"sourcesContent":["/**\n * Pure dict-registry helpers — extracted from `kernel/vault.ts`'s dict\n * bodies (#650 Task 1 — via-lookup extraction, phase D).\n *\n * These take the vault-resident registry Maps (and a couple of vault-bound\n * callbacks) as ARGUMENTS instead of closing over `this` — no `Vault`\n * import here, so this module stays a plain, testable function library.\n * `kernel/vault.ts` keeps the registry Maps themselves (they're populated\n * by `vault.collection()` and read by the backup path) and calls these\n * helpers through the `port/with/lookup-strategy.ts` seam.\n */\n\nimport { getAtPath } from '../../kernel/paths.js'\nimport { UnknownDictCodeError, ValidationError } from '../../kernel/errors.js'\nimport type { JoinableSource } from '../../kernel/query/index.js'\nimport type { FieldRef, ViaGraph } from '../../kernel/via/graph.js'\nimport type { StaticDictDescriptor } from '../../port/with/i18n-strategy.js'\nimport { dictCollectionName, type LookupHandle } from './handle.js'\nimport type { LookupDescriptor, OnDelete } from './descriptor.js'\n\n/**\n * Validate staticDict codes on a `put()`. For each `staticDict()` field,\n * every stored code must be a declared key of the descriptor's table, else\n * `UnknownDictCodeError`. Opt out per descriptor with `{ validateCodes:\n * false }`. Supports scalar, dotted, and `[].`-wildcard field paths via\n * `getAtPath` (same path support as i18n validation).\n *\n * `staticFields` is the collection's `field → StaticDictDescriptor` map\n * (`Vault#staticDescriptorByField.get(collectionName)`) — `undefined`/empty\n * is a no-op.\n */\nexport function enforceStaticDictOnPut(\n staticFields: Record<string, StaticDictDescriptor> | undefined,\n record: unknown,\n): void {\n if (!staticFields || Object.keys(staticFields).length === 0) return\n if (!record || typeof record !== 'object') return\n\n const obj = record as Record<string, unknown>\n for (const [field, desc] of Object.entries(staticFields)) {\n if (desc.validateCodes === false) continue\n const known = new Set<string>(desc.keys)\n const values = getAtPath(obj, field)\n for (const value of values) {\n if (value === undefined || value === null) continue\n const codes = Array.isArray(value) ? value : [value]\n for (const code of codes) {\n if (typeof code !== 'string') continue\n if (!known.has(code)) {\n throw new UnknownDictCodeError(desc.name, field, code)\n }\n }\n }\n }\n}\n\n/**\n * Build a `JoinableSource` for a dictKey field, for use in dict joins.\n * Returns a source whose snapshot contains `{ key, labels, ...labels }`\n * records — one per dictionary entry — keyed by the stable key.\n *\n * staticDict: a code-table-backed source — snapshot() materialises the\n * in-memory table into rows, mirroring `LookupHandle.snapshotEntries()`.\n * Carries `displayLocale` so a locale-less `{ by: 'label' }` query has a\n * default locale to resolve at.\n *\n * Plain dictKey: the snapshot is built synchronously from the\n * `LookupHandle`'s write-through cache, which is populated on every\n * `put()`, `rename()`, `delete()`, and `list()` call. For pre-existing\n * data not yet touched this session, call `await vault.dictionary(name).list()`\n * first to warm the cache.\n *\n * Returns `null` when `field` is not a dictKey in `leftCollection`.\n */\nexport function resolveDictSource(\n leftCollection: string,\n field: string,\n staticDescriptorByField: ReadonlyMap<string, Record<string, StaticDictDescriptor>>,\n dictKeyFieldRegistry: ReadonlyMap<string, Record<string, string>>,\n getDictionaryHandle: (name: string) => LookupHandle,\n): JoinableSource | null {\n const staticFields = staticDescriptorByField.get(leftCollection)\n if (staticFields && field in staticFields) {\n const desc = staticFields[field]!\n const rows: readonly Record<string, unknown>[] = Object.entries(desc.table).map(\n ([key, labels]) => ({ key, labels, ...(labels as Record<string, string>) }),\n )\n const source: JoinableSource = {\n snapshot(): readonly unknown[] {\n return rows\n },\n lookupById(id: string): unknown {\n return rows.find((e) => e['key'] === id)\n },\n }\n if (desc.displayLocale !== undefined) {\n ;(source as { displayLocale?: string }).displayLocale = desc.displayLocale\n }\n return source\n }\n\n const dictFields = dictKeyFieldRegistry.get(leftCollection)\n if (!dictFields || !(field in dictFields)) return null\n const dictName = dictFields[field]\n if (!dictName) return null\n const handle = getDictionaryHandle(dictName)\n return {\n snapshot(): readonly unknown[] {\n return handle.snapshotEntries()\n },\n lookupById(id: string): unknown {\n const entries = handle.snapshotEntries()\n return entries.find((e) => e['key'] === id)\n },\n }\n}\n\n/** The minimal collection surface `updateReferencingRecords` needs. */\nexport interface DictReferencingCollection {\n list(): Promise<Record<string, unknown>[]>\n put(id: string, record: Record<string, unknown>): Promise<unknown>\n}\n\n/**\n * Find and rewrite records in every registered collection whose\n * dictKeyField points at `name`, replacing `oldKey` with `newKey`. Used by\n * `LookupHandle.rename()` (the only sanctioned mass-mutation path for\n * dictKey fields) via the vault's `findAndUpdateReferences` callback.\n *\n * `registry` is `Vault#dictKeyFieldRegistry` (collection name → field name\n * → dictionary name); `getCollection` is the vault's collection accessor —\n * rewrites go through the public `coll.put()` choke point, same as before.\n */\nexport async function updateReferencingRecords(\n registry: ReadonlyMap<string, Record<string, string>>,\n getCollection: (collectionName: string) => DictReferencingCollection,\n name: string,\n oldKey: string,\n newKey: string,\n): Promise<void> {\n for (const [collectionName, dictFields] of registry) {\n // Find fields that point at this dictionary\n const fields = Object.entries(dictFields)\n .filter(([, dn]) => dn === name)\n .map(([field]) => field)\n if (fields.length === 0) continue\n\n const coll = getCollection(collectionName)\n const records = await coll.list()\n for (const record of records) {\n let changed = false\n const updated = { ...record }\n for (const field of fields) {\n if (updated[field] === oldKey) {\n updated[field] = newKey\n changed = true\n }\n }\n if (changed) {\n const id = record['id'] as string | undefined\n if (id !== undefined) {\n await coll.put(id, updated)\n }\n }\n }\n }\n}\n\n/**\n * Resolve a label from an in-memory `{ locale -> label }` map, walking the\n * same fallback chain semantics as `LookupHandle.resolveLabel` (#650 Task 2\n * — moved here from `kernel/vault.ts` so the SAME chain serves both the\n * i18n binding's `dictLabelResolver` and the lookup binding's\n * `lookupLabelResolver`, which #650 Task 2 wires to the identical closure).\n */\nexport function resolveLabelFromMap(\n labels: Readonly<Record<string, string>>,\n locale: string,\n fallback?: string | readonly string[],\n): string | undefined {\n if (labels[locale] !== undefined) return labels[locale]\n const chain = Array.isArray(fallback)\n ? (fallback as readonly string[])\n : fallback\n ? [fallback as string]\n : []\n for (const fb of chain) {\n if (fb === 'any') {\n const any = Object.values(labels)[0]\n if (any !== undefined) return any\n } else if (labels[fb] !== undefined) {\n return labels[fb]\n }\n }\n return undefined\n}\n\n/**\n * Project a native `lookup(dimension, { backing:'static', table, … })`\n * descriptor into the legacy `StaticDictDescriptor` shape — the\n * alias-equivalence compat seam (#650 Task 2) that lets a native\n * static-tier lookup field reuse the SAME vault registries\n * (`staticByName`/`staticDescriptorByField`) — and therefore the same\n * `dictLabelResolver`/`resolveDictSource` machinery — as its `staticDict()`\n * alias. `vocabulary:'closed'` maps to `validateCodes:true` (closed = only\n * declared codes are legal); `'open'` maps to `validateCodes:false`.\n * Returns `undefined` for non-static or table-less (bare `enumOf`)\n * descriptors — those have nothing to register.\n */\nexport function lookupToStaticDictCompat(desc: LookupDescriptor): StaticDictDescriptor | undefined {\n if (desc.backing !== 'static' || desc.table === undefined) return undefined\n return {\n _noydbStaticDict: true,\n _viaBrand: 'i18n',\n name: desc.dimension,\n table: desc.table,\n keys: desc.keys ?? Object.keys(desc.table),\n ...(desc.displayLocale !== undefined ? { displayLocale: desc.displayLocale } : {}),\n ...(desc.onMissing !== undefined ? { onMissing: desc.onMissing } : {}),\n ...(desc.substitute !== undefined ? { substitute: desc.substitute } : {}),\n validateCodes: desc.vocabulary === 'closed',\n }\n}\n\n/** The vault-registry entries a collection's `lookupFields` contribute — the alias-equivalence bridge (#650 Task 2). */\nexport interface LookupDictCompat {\n /** Reserved-tier fields: field name -> dimension (dictionary) name — merges into `dictKeyFieldRegistry`. */\n readonly dictFieldMap: Record<string, string>\n /** Static-tier (table-bearing) fields, projected — merges into `staticDescriptorByField`/`staticByName`. */\n readonly staticEntries: ReadonlyArray<readonly [string, StaticDictDescriptor]>\n}\n\n/**\n * Bridge a collection's `lookupFields` into the SAME shape the legacy dict\n * registries expect, so `resolveDictSource`/`dictLabelResolver` (and\n * therefore `.join()`/`orderBy({by:'label'})`) serve a native `dict()`/\n * `lookup(static)` field identically to its `dictKey()`/`staticDict()`\n * alias — the reserved-vs-first-class-backing \"matrix\" tier is NOT bridged\n * here (no vault registry backs it; Task 5/6 build its own graph edge /\n * snapshot seam).\n */\nexport function collectLookupDictCompat(\n lookupFields: Record<string, LookupDescriptor> | undefined,\n): LookupDictCompat {\n const dictFieldMap: Record<string, string> = {}\n const staticEntries: Array<readonly [string, StaticDictDescriptor]> = []\n for (const [field, desc] of Object.entries(lookupFields ?? {})) {\n if (desc.backing === 'reserved') {\n dictFieldMap[field] = desc.dimension\n } else {\n const compat = lookupToStaticDictCompat(desc)\n if (compat) staticEntries.push([field, compat])\n }\n }\n return { dictFieldMap, staticEntries }\n}\n\n/**\n * Reserved-dict deps of a set of named collections (#653) — the `_dict_*`\n * collections partial sync must auto-include alongside a `collections`\n * filter, mirroring `SyncEngine`'s existing satellite-pair expansion.\n * One hop is provably complete: `vault.collection()` refuses `_dict_*`\n * names, so a dict can never itself declare lookup fields — no\n * dict-of-dict chain to recurse through.\n */\nexport function reservedDictDepsOf(\n names: readonly string[],\n dictKeyFieldRegistry: ReadonlyMap<string, Record<string, string>>,\n): readonly string[] {\n const out = new Set<string>()\n for (const name of names) {\n const fieldMap = dictKeyFieldRegistry.get(name)\n if (!fieldMap) continue\n for (const dictName of Object.values(fieldMap)) out.add(dictCollectionName(dictName))\n }\n return [...out]\n}\n\n/**\n * A lookup dimension's sync membership/altKey table, materialized from its\n * backing rows (#650 Task 3). `keys` is every canonical key present;\n * `altIndex` maps an altKey candidate VALUE to its owning canonical key.\n */\nexport interface MaterializedBacking {\n /** Canonical key values present in the materialized rows. */\n readonly keys: ReadonlySet<string>\n /** altKey candidate value -> canonical key. */\n readonly altIndex: ReadonlyMap<string, string>\n}\n\n/**\n * Build a lookup dimension's altKey index from its backing rows, enforcing\n * declare/warm-time uniqueness across `key ∪ altKeys` values (#650 Task 3 —\n * the CHE/SWZ drift class: two different rows must never claim the same\n * candidate key). `rows` is keyed by canonical key (`row[descriptor.key]`\n * for the matrix tier; the dimension's own key for static/reserved).\n * An altKey candidate VALUE may be a string or number — both normalize via\n * `coerceLookupKey` (#651 Task 3); non-scalar/absent values are skipped.\n * Pure — no I/O. Throws `ValidationError` on collision.\n */\nexport function materializeBackingTable(\n descriptor: LookupDescriptor,\n rows: ReadonlyMap<string, Record<string, unknown>>,\n): MaterializedBacking {\n const keys = new Set<string>(rows.keys())\n // Every value that has claimed ownership so far (canonical keys seed it) —\n // the union `key ∪ altKeys` uniqueness set the spec requires.\n const owner = new Map<string, string>()\n for (const key of keys) owner.set(key, key)\n\n const altIndex = new Map<string, string>()\n const altFields = descriptor.altKeys ?? []\n for (const [canonicalKey, row] of rows) {\n for (const altField of altFields) {\n const value = coerceLookupKey(row[altField])\n if (value === undefined || value === '') continue\n const existingOwner = owner.get(value)\n if (existingOwner !== undefined && existingOwner !== canonicalKey) {\n throw new ValidationError(\n `lookup \"${descriptor.dimension}\": altKey field \"${altField}\" value \"${value}\" is claimed by ` +\n `both \"${existingOwner}\" and \"${canonicalKey}\" — key/altKey values must be unique across the dimension.`,\n )\n }\n owner.set(value, canonicalKey)\n altIndex.set(value, canonicalKey)\n }\n }\n return { keys, altIndex }\n}\n\n/**\n * Closed-vocabulary membership test for one candidate key (#650 Task 3).\n * Static tier: sync, against the in-config key set (declared `keys`, or the\n * table's own keys when table-bearing). Reserved tier: sync — the declared\n * `keys` union the reserved handle's live write-through snapshot (closes\n * #649 for the native `dict()` spelling: the declared-keys promise the old\n * `dictKey()` doc comment made falsely). Matrix (collection) tier: sync —\n * delegates to `buildLookupAltIndex` so membership is checked against the\n * SAME `row[descriptor.key]` keying the altKey index uses (review fix,\n * Important 1: an earlier PUT-id `.get(key)` scan disagreed with the\n * altIndex whenever `descriptor.key !== 'id'`, wrongly rejecting valid\n * non-id candidates and wrongly accepting an unrelated row's PUT-id).\n */\nexport function checkLookupMembership(\n descriptor: LookupDescriptor,\n key: string,\n getDictionary: (dimension: string) => LookupHandle,\n getCollection: (dimension: string) => { querySourceForJoin(): JoinableSource },\n): boolean {\n if (descriptor.backing === 'static') {\n const known = descriptor.keys ?? (descriptor.table ? Object.keys(descriptor.table) : [])\n return known.includes(key)\n }\n if (descriptor.backing === 'reserved') {\n if ((descriptor.keys ?? []).includes(key)) return true\n return getDictionary(descriptor.dimension).snapshotEntries().some((e) => e['key'] === key)\n }\n return buildLookupAltIndex(descriptor, getDictionary, getCollection).keys.has(key)\n}\n\n/**\n * The ONE guarded key coercion (#651 Task 3, dm12) — string/number values\n * coerce to their canonical `String()` form; everything else (`null`,\n * `undefined`, objects, …) coerces to `undefined`. Every consumer that turns\n * a raw record field into a lookup key routes through this, closing the\n * bare-`String()` `\"undefined\"`/`\"null\"`-key poisoning class (seam map\n * finding 6): a row whose key field is genuinely absent must never mint the\n * literal candidate string `\"undefined\"`.\n */\nexport function coerceLookupKey(raw: unknown): string | undefined {\n return typeof raw === 'string' || typeof raw === 'number' ? String(raw) : undefined\n}\n\n/**\n * Resolve a backing row's canonical key VALUE — `coerceLookupKey(row[descriptor.key])`\n * (#651 Task 3). The matrix tier's `row[descriptor.key]`, never the row's own PUT-id\n * when the two differ (`descriptor.key !== 'id'`).\n */\nexport function resolveBackingRowKey(\n descriptor: LookupDescriptor,\n row: Record<string, unknown>,\n): string | undefined {\n return coerceLookupKey(row[descriptor.key])\n}\n\n/**\n * The referencing-side match predicate — does `rec[field]` (coerced) equal an\n * already-coerced `compareKey` (#651 Task 3)? Shared by every site that scans a\n * referencing collection for rows pointing at a given backing key\n * (`with-shape/links/vault-facade.ts`'s ref-delete propagation, `kernel/via/dispatch.ts`'s\n * forget-fanout twin).\n */\nexport function matchesReferencingValue(\n rec: Record<string, unknown>,\n field: string,\n compareKey: string,\n): boolean {\n return coerceLookupKey(rec[field]) === compareKey\n}\n\n/**\n * Materialize a lookup dimension's altKey index from whatever backing data\n * is synchronously available (#650 Task 3 — the `ingest` source). Static:\n * the in-config table. Reserved: the reserved handle's live write-through\n * cache (the same warm-via-put()/list() cache `resolveDictSource` already\n * relies on). Matrix (collection): the backing collection's own in-memory\n * eager cache via `querySourceForJoin()` — already public, already the\n * mechanism `.join()` uses (`with-shape/links/vault-facade.ts`'s\n * `resolveSource`); no new I/O, no fire-and-forget warm step. Like that\n * existing join precedent, a dimension collection this vault session has\n * not yet opened/populated sees an empty snapshot (no altKey normalization\n * until it has rows) — open/populate it first for normalization to apply.\n * A matrix row whose `descriptor.key` field coerces to `undefined` (missing/\n * non-scalar) is SKIPPED — never enters the index under a poisoned\n * `\"undefined\"` key (#651 Task 3, dm12).\n */\nexport function buildLookupAltIndex(\n descriptor: LookupDescriptor,\n getDictionary: (dimension: string) => LookupHandle,\n getCollection: (dimension: string) => { querySourceForJoin(): JoinableSource },\n): MaterializedBacking {\n if (descriptor.backing === 'static') {\n return materializeBackingTable(descriptor, new Map(Object.entries(descriptor.table ?? {})))\n }\n if (descriptor.backing === 'reserved') {\n const entries = getDictionary(descriptor.dimension).snapshotEntries()\n return materializeBackingTable(descriptor, new Map(entries.map((e) => [String(e['key']), e])))\n }\n const rows = getCollection(descriptor.dimension).querySourceForJoin().snapshot()\n const keyed = new Map<string, Record<string, unknown>>()\n for (const r of rows) {\n const row = r as Record<string, unknown>\n const key = resolveBackingRowKey(descriptor, row)\n if (key !== undefined) keyed.set(key, row)\n }\n return materializeBackingTable(descriptor, keyed)\n}\n\n/** One cross-collection `'ref'` graph edge a lookup field declares (#650 Task 5). Module-private —\n * only `registerLookupRefEdges` below (the exported entry point) consumes it. */\ninterface LookupRefEdge {\n readonly referencing: FieldRef\n readonly sources: readonly FieldRef[]\n readonly onDelete: OnDelete\n /** The backing dimension's canonical-key FIELD NAME on its own row (`desc.key` — matrix tier\n * only varies this; reserved/static tiers are always `'id'`). A referencing field always\n * stores THIS field's value, never the backing row's PUT-id when the two differ. */\n readonly keyField: string\n}\n\n/**\n * Compute the cross-collection `'ref'` edges a collection's `lookupFields` declare (#650 Task 5,\n * spec §4) — one edge per non-static-backing field: target = the referencing field; sources =\n * the backing dimension's whole-collection node (`field:'*'`, the wildcard key\n * `ViaGraph.referencingEdgesOf` does its O(1) reverse lookup against) PLUS, when the descriptor\n * names a presentation field (`present.label`), that SPECIFIC field too. `foldPosture`'s\n * `DEFAULT_POSTURE` is the fold's identity element, so adding the wildcard alongside a real field\n * source changes nothing when that field is plain — but folds in a classified/money posture when\n * it isn't (taint composition, spec §4: \"a lookup edge whose source names a classified field\n * contributes that field's posture\"). Static tier (`backing:'static'`) has no backing collection/\n * dimension rows to reference-check — excluded. Pure; consumed only by `registerLookupRefEdges` below.\n */\nfunction collectLookupRefEdges(\n collectionName: string,\n lookupFields: Record<string, LookupDescriptor> | undefined,\n): readonly LookupRefEdge[] {\n const edges: LookupRefEdge[] = []\n for (const [field, desc] of Object.entries(lookupFields ?? {})) {\n if (desc.backing === 'static') continue\n const backing = desc.backing === 'reserved' ? dictCollectionName(desc.dimension) : desc.dimension\n edges.push({\n referencing: { collection: collectionName, field },\n sources: [\n { collection: backing, field: '*' },\n ...(desc.present?.label !== undefined ? [{ collection: backing, field: desc.present.label }] : []),\n ],\n onDelete: desc.onDelete,\n keyField: desc.key,\n })\n }\n return edges\n}\n\n/** Thin wrapper — `collectLookupRefEdges` + one `graph.registerDerived` call per edge. Lets\n * `vault.collection()` (kernel-surface-budgeted, #650 Task 5) register a collection's lookup-ref\n * edges with a single line, keeping the ceiling-guarded call site a thin call (route logic here). */\nexport function registerLookupRefEdges(\n graph: ViaGraph,\n collectionName: string,\n lookupFields: Record<string, LookupDescriptor> | undefined,\n): void {\n for (const e of collectLookupRefEdges(collectionName, lookupFields)) {\n graph.registerDerived(e.referencing, e.sources, 'ref', 'record', e.onDelete, e.keyField)\n }\n}\n\n/**\n * `LookupViaConfig.snapshotFor`'s vault-built row source (#650 Task 6, spec\n * §5; matrix-tier coverage added #650 Task 7, spec §6 — Task 6 deferred it,\n * see `task-6-report.md`'s Concerns #1; the reviewer's Task-7 dispatch\n * refuted the \"needs a new vault-resident registry\" premise: the descriptor\n * is already in hand at both call sites, so `snapshotFor` just needs to\n * ACCEPT it). Takes the full `descriptor` (not a bare dimension name) so it\n * can route the matrix tier's `key` field, which — unlike reserved tier's\n * hardcoded `'id'` — varies per collection. Routes on `descriptor.backing`:\n *\n * - **reserved**: rows come straight from the SAME `LookupHandle.\n * snapshotEntries()` write-through cache `dictLabelResolver`/\n * `resolveDictSource` already read (no second copy), keyed by each\n * entry's own canonical `key` (always `'id'` by construction for this\n * tier — `dict()`'s factory hardcodes it).\n * - **collection** (matrix): rows come from `getCollection(dimension).\n * querySourceForJoin().snapshot()` — the SAME sync, already-live cache\n * `buildLookupAltIndex`'s matrix branch (above, this file) and `.join()`\n * itself already read — re-keyed via `resolveBackingRowKey(descriptor, row)`,\n * NOT the row's own PUT-id (which may differ when `key !== 'id'`; the exact\n * distinction the #650 Task 3 review fix already applies to\n * `checkLookupMembership`'s matrix branch). A row whose `descriptor.key`\n * field coerces to `undefined` is skipped (#651 Task 3, dm12).\n * - **static**: never routed here — `descriptor.table` is read directly by\n * the caller (`binding.ts`'s `compareLookupOrder`/`resolveLookupOrderLabel`,\n * `snapshot.ts`'s `presentLookupForJoin`); no vault call needed.\n *\n * `isReservedDimension` is the vault's `reservedLookupCollections`\n * membership test.\n */\nexport function buildLookupSnapshotRows(\n descriptor: LookupDescriptor,\n isReservedDimension: (dimension: string) => boolean,\n getDictionary: (dimension: string) => LookupHandle,\n getCollection: (dimension: string) => { querySourceForJoin(): JoinableSource },\n): ReadonlyMap<string, Record<string, unknown>> | undefined {\n const dimension = descriptor.dimension\n if (isReservedDimension(dimension)) {\n const rows = new Map<string, Record<string, unknown>>()\n for (const entry of getDictionary(dimension).snapshotEntries()) {\n const key = entry['key']\n if (typeof key === 'string') rows.set(key, entry)\n }\n return rows\n }\n if (descriptor.backing === 'collection') {\n const rawRows = getCollection(dimension).querySourceForJoin().snapshot()\n const rows = new Map<string, Record<string, unknown>>()\n for (const r of rawRows) {\n const row = r as Record<string, unknown>\n const key = resolveBackingRowKey(descriptor, row)\n if (key !== undefined) rows.set(key, row)\n }\n return rows\n }\n return undefined\n}\n","/**\n * The sync lookup snapshot + join/locale seam (#650 Task 6, spec §5 — \"the\n * snapshot+locale seam\"). Retires the #626 kernel→via grandfather:\n * `kernel/query/join.ts` no longer imports `via/i18n/core.js` directly\n * — it calls the `presentForJoin` hook this file's `buildPresentForJoin`\n * builds instead (seam map Part 2 item 4, the #626 reviewer-spec'd shape:\n * a sync `presentI18nForJoin`-class hook on `JoinableSource`).\n *\n * `LookupSnapshot` is the sync materialized `key -> row` view over ONE\n * lookup dimension's ALREADY-LIVE backing data (the `active.ts`\n * `_syncCache`/`snapshotEntries` write-through-cache pattern — never a\n * second copy of the data: `LookupViaConfig.snapshotFor`'s vault-built\n * closure reads the SAME `LookupHandle._syncCache` /\n * first-class-collection cache every other lookup consumer\n * (`dictLabelResolver`, `resolveDictSource`, `getAltIndex`) already reads).\n * Serves (reserved AND matrix tier since #650 Task 7 — `registry.ts`'s\n * `buildLookupSnapshotRows` routes both; static tier is read straight off\n * `descriptor.table` by every consumer below, never through this cache):\n * - join dressing (`presentForJoin`, consumed by `kernel/query/join.ts`\n * via `JoinableSource.presentForJoin`)\n * - dimension sort (`compareForOrder`, consumed by\n * `via/lookup/binding.ts`'s `ViaBinding.compareForOrder` closure)\n * - per-call-locale order-label resolution (`resolveOrderLabel`, #650\n * Task 7 — the `orderBy(..., {by:'label'})` channel `compareForOrder`\n * structurally can't serve, no locale param; consumed by\n * `kernel/query/builder.ts`'s `buildOrderLabelMaps`)\n * - membership: reserved/static-tier membership (#650 Task 3,\n * `checkLookupMembership`) already reads the identical sync caches\n * directly — not re-plumbed through this file; see\n * `.superpowers/sdd/task-6-report.md`'s \"bridge disposition\" section.\n *\n * Sync end-to-end (#553) — every function here is a pure, synchronous\n * transform over already-materialized rows; no store read, no Promise.\n */\nimport type { LookupDescriptor } from './descriptor.js'\nimport { presentI18nForJoin, type I18nTextDescriptor } from '../i18n/core.js'\n\n/** A lookup dimension's sync materialized view — see file header. */\nexport interface LookupSnapshot {\n /** The full backing row for `key`, or `undefined` when `key` isn't (yet) present in the snapshot. */\n row(key: string): Record<string, unknown> | undefined\n /** The dimension's declared presentation label for `key` at `locale` — mirrors `binding.ts`'s `fetchLookupLabel` (matrix-row branch), generalized to any tier's already-materialized rows. */\n label(key: string, locale: string, fallback?: unknown): string | undefined\n /**\n * Exact ordering for two canonical keys against `descriptor.sortBy`\n * (falls back to `present.label`, then to the raw keys) at `locale`.\n * Never throws — degrades to comparing the raw keys when no sortable\n * value resolves for either side.\n */\n compareKeys(a: string, b: string, locale: string): number\n}\n\n/** Read one row field, resolving a `by`-keyed (locale-map) value when `by` is declared. */\nfunction readRowField(\n row: Record<string, unknown> | undefined,\n field: string | undefined,\n by: string | undefined,\n locale: string,\n fallback?: unknown,\n): string | undefined {\n if (!row || field === undefined) return undefined\n const raw = row[field]\n if (by === undefined) return typeof raw === 'string' ? raw : undefined\n if (!raw || typeof raw !== 'object') return undefined\n const map = raw as Record<string, unknown>\n const val = map[locale]\n if (typeof val === 'string') return val\n if (typeof fallback === 'string' && typeof map[fallback] === 'string') return map[fallback]\n return undefined\n}\n\n/**\n * Build a sync `LookupSnapshot` over one dimension's already-materialized\n * rows (canonical-key -> row, the SAME keying `materializeBackingTable`\n * (`registry.ts`, #650 Task 3) uses). Pure — never reads a store.\n */\nexport function buildLookupSnapshot(\n dimension: string,\n rows: ReadonlyMap<string, Record<string, unknown>>,\n descriptor: LookupDescriptor,\n): LookupSnapshot {\n void dimension // identity only — kept for parity with materializeBackingTable/buildLookupAltIndex's signature and future diagnostics\n return {\n row: (key) => rows.get(key),\n label: (key, locale, fallback) =>\n readRowField(rows.get(key), descriptor.present?.label, descriptor.present?.by, locale, fallback),\n compareKeys: (a, b, locale) => {\n const sortField = descriptor.sortBy ?? descriptor.present?.label\n const av = readRowField(rows.get(a), sortField, descriptor.present?.by, locale) ?? a\n const bv = readRowField(rows.get(b), sortField, descriptor.present?.by, locale) ?? b\n return av < bv ? -1 : av > bv ? 1 : 0\n },\n }\n}\n\n/**\n * The lookup-label HALF of `presentForJoin` (#626 retirement, spec §5;\n * matrix-tier coverage added #650 Task 7) — resolves `<field>Label` for\n * every declared lookup field with a `present` dressing dimension, sync,\n * from `getSnapshotRows` (the vault-built `LookupViaConfig.snapshotFor`\n * closure — now descriptor-routed, see `registry.ts`'s\n * `buildLookupSnapshotRows`; static tier reads its own in-config `table`\n * directly, no vault call — never `undefined` for a declared static table).\n * Mirrors `binding.ts`'s `runLookupPresent` (the async `present()` hook)\n * minus the array/`[].`-wildcard handling that hook needs for full-record\n * reads — join dressing only ever sees the joined RIGHT-side record's\n * scalar fields, so that complexity doesn't apply here.\n */\nfunction presentLookupForJoin(\n record: Record<string, unknown>,\n locale: string,\n lookupFields: Record<string, LookupDescriptor>,\n getSnapshotRows: (descriptor: LookupDescriptor) => ReadonlyMap<string, Record<string, unknown>> | undefined,\n): Record<string, unknown> {\n let result = record\n for (const [field, desc] of Object.entries(lookupFields)) {\n if (desc.present === undefined) continue\n const raw = record[field]\n if (typeof raw !== 'string') continue\n const rows = desc.backing === 'static'\n ? (desc.table ? new Map(Object.entries(desc.table)) : undefined)\n : getSnapshotRows(desc)\n if (!rows) continue\n const label = buildLookupSnapshot(desc.dimension, rows, desc).label(raw, locale)\n if (label === undefined) continue\n if (result === record) result = { ...record }\n result[`${field}Label`] = label\n }\n return result\n}\n\n/**\n * Build the combined sync `presentForJoin(record, locale)` hook a\n * `Collection` attaches to the `JoinableSource` it exposes\n * (`querySourceForJoin()`) — the i18n-text half (`presentI18nForJoin`, the\n * exact `applyI18nLocale(..., 'join')` partial application\n * `kernel/query/join.ts` used to call directly, #626) composed with the\n * lookup-label half above. `undefined` when the collection declares\n * neither — `JoinableSource.presentForJoin` then stays unset, matching\n * today's `i18nFields`-absent behavior exactly (#626 parity lock).\n */\nexport function buildPresentForJoin(\n i18nFields: Record<string, I18nTextDescriptor> | undefined,\n lookupFields: Record<string, LookupDescriptor> | undefined,\n getSnapshotRows: ((descriptor: LookupDescriptor) => ReadonlyMap<string, Record<string, unknown>> | undefined) | undefined,\n): ((record: unknown, locale: string) => unknown) | undefined {\n const hasI18n = i18nFields !== undefined && Object.keys(i18nFields).length > 0\n const hasLookup = lookupFields !== undefined && Object.keys(lookupFields).length > 0\n if (!hasI18n && !hasLookup) return undefined\n const resolveRows = getSnapshotRows ?? (() => undefined)\n return (record, locale) => {\n if (record === null || typeof record !== 'object') return record\n let result = record as Record<string, unknown>\n if (hasI18n) result = presentI18nForJoin(result, i18nFields, locale)\n if (hasLookup) result = presentLookupForJoin(result, locale, lookupFields, resolveRows)\n return result\n }\n}\n","/**\n * Lookup strategy seam (#650 Task 1 — via-lookup extraction, phase D of the\n * Via port; precedent: `port/with/i18n-strategy.ts`). Lives on the `/with`\n * port (the one seam the kernel spine may import statically) so `Vault` can\n * reach the dict-registry pure helpers and the `LookupHandle`/`NO_LOOKUP`\n * types without a spine→`via/` static import (Check 14 via-layering bans\n * that; `port/with/` is always allowed, Check 9's sanctioned exception).\n *\n * `kernel/vault.ts` imports ONLY this module for lookup — never\n * `via/lookup/*` directly.\n *\n * This task (#650 Task 1) is a pure move: `Vault.dictionary()` still\n * constructs its handle through `i18nStrategy.buildDictionaryHandle`\n * (`port/with/i18n-strategy.ts`), which now internally delegates to\n * `withLookup().buildLookupHandle` (same handle, new home). `LookupStrategy`\n * / `NO_LOOKUP` / `isLookupCollectionName` here are the seam later phase-D\n * tasks bind `vault.collection()`'s lookup fields onto — unused by Task 1's\n * wiring, but their exact shapes are frozen now so later tasks don't\n * re-litigate them.\n */\n\nimport type { NoydbStore, EncryptedEnvelope } from '../../kernel/types.js'\nimport type { LedgerStore } from '../../with-commit/history/ledger/store.js'\nimport type { UnlockedKeyring } from '../../with-party/team/keyring.js'\nimport type { NoydbEventEmitter } from '../../kernel/events.js'\nimport type { ViaCryptoCtx } from '../../kernel/via/index.js'\nimport type { LookupHandle, DictionaryOptions } from '../../via/lookup/handle.js'\nimport {\n enforceStaticDictOnPut,\n resolveDictSource,\n updateReferencingRecords,\n resolveLabelFromMap,\n collectLookupDictCompat,\n lookupToStaticDictCompat,\n reservedDictDepsOf,\n materializeBackingTable,\n checkLookupMembership,\n buildLookupAltIndex,\n registerLookupRefEdges,\n buildLookupSnapshotRows,\n coerceLookupKey,\n resolveBackingRowKey,\n matchesReferencingValue,\n type DictReferencingCollection,\n type LookupDictCompat,\n type MaterializedBacking,\n} from '../../via/lookup/registry.js'\nimport { buildPresentForJoin } from '../../via/lookup/snapshot.js'\nimport type { LookupDescriptor } from '../../via/lookup/descriptor.js'\n\n/**\n * Backing options for `LookupStrategy.buildLookupHandle` — same shape as\n * `DictionaryOptions` (kept as a distinct alias since the \"lookup\" name is\n * the forward-looking one; `DictionaryOptions` stays the dict-tier name).\n */\nexport type LookupBackingOptions = DictionaryOptions\n\n/**\n * Options accepted by `LookupStrategy.buildLookupHandle`. Mirrors the\n * `LookupHandle` constructor verbatim, plus the two choke-point\n * participation hooks (`onDirty`/`onRecordMutated`) #647 (Task 4) wires —\n * both `undefined` in this task (pure move, no new call sites).\n */\nexport interface BuildLookupHandleOptions<Keys extends string = string> {\n readonly adapter: NoydbStore\n readonly compartmentName: string\n readonly dimensionName: string\n readonly keyring: UnlockedKeyring\n /**\n * The `reservedEnvelopes('_dict_')` capability (#629 Task 4) — the\n * handle's sanctioned crypto door onto its `_dict_<name>` collection.\n * Bound by the Vault to its own `getDEK`, the same per-collection-name\n * DEK resolver every other collection uses.\n */\n readonly reservedEnvelopes: ReturnType<ViaCryptoCtx['reservedEnvelopes']>\n readonly encrypted: boolean\n readonly ledger: LedgerStore | undefined\n readonly options: LookupBackingOptions\n readonly findAndUpdateReferences:\n | ((dimension: string, oldKey: string, newKey: string) => Promise<void>)\n | undefined\n readonly emitter: NoydbEventEmitter\n /**\n * #647 fix wave 1 — mints a version-ordered delete-marker envelope. Bound by the Vault to the\n * real `kernel/enclave` `buildDeleteMarker` function — `LookupHandle` (`via/lookup/**`)\n * may not import `kernel/enclave/` itself (Check 11/15), so this capability is injected the\n * same way `reservedEnvelopes` above is.\n */\n readonly buildDeleteMarker: (version: number, actor: string) => EncryptedEnvelope\n /** #650 Task 4 (#647) — choke-point participation hooks. */\n readonly onDirty?: ((collection: string, id: string, action: 'put' | 'delete', version: number) => Promise<void>) | undefined\n readonly onRecordMutated?: ((collection: string, id: string, action: 'put' | 'delete', version: number) => Promise<void>) | undefined\n /**\n * #650 Task 5 (#648) — the real reference check `LookupHandle.delete()`'s strict branch calls:\n * restrict throws `DictKeyInUseError` naming the referencing collection, cascade/nullify apply\n * their propagation. Bound by the Vault (never a `Collection`/keyring/DEK reach-around); a\n * no-op when the dimension has no declared lookup-referencing edges (today's dangling behavior\n * for undeclared refs is unaffected). Return value is discarded by the handle — callers who\n * need cascade/nullify counts (forget) go through `VaultLinks` directly.\n */\n readonly checkReferencesOnDelete?: ((key: string) => Promise<unknown>) | undefined\n /**\n * Used by the active strategy to satisfy the generic-key parameter on the\n * returned handle. The NO_LOOKUP stub never reads it. Mirrors\n * `BuildDictionaryHandleOptions._keyMarker` (`port/with/i18n-strategy.ts`).\n */\n // marker generic — runtime sees no value\n _keyMarker?: Keys\n}\n\nexport interface LookupStrategy {\n /**\n * Construct a typed `LookupHandle` for the named dimension. Throws under\n * `NO_LOOKUP`.\n */\n buildLookupHandle<Keys extends string = string>(\n opts: BuildLookupHandleOptions<Keys>,\n ): LookupHandle<Keys>\n}\n\nfunction notEnabled(op: string): Error {\n return new Error(\n `${op}: the NO_LOOKUP stub was reached, which should be unreachable today — there is no ` +\n '`lookupStrategy` `createNoydb({ ... })` option yet to select this stub over the real one; ' +\n '`vault.dictionary()` always resolves through `withLookup()` (see `via/i18n/active.ts`\\'s ' +\n 'delegation). This is forward scaffolding for a later task (mirrors `NO_I18N`\\'s shape) — if you ' +\n 'hit this, it indicates a bug, not a missing opt-in.',\n )\n}\n\n/**\n * No-lookup stub. Mirrors `NO_I18N.buildDictionaryHandle`'s shape, but unlike `NO_I18N` (wired as\n * `vault.ts`'s `opts.i18nStrategy ?? NO_I18N` default), nothing selects this stub today — there is\n * no `lookupStrategy` option on `createNoydb()`; `vault.dictionary()`'s only construction path\n * (`Vault.i18nStrategy.buildDictionaryHandle` → `withLookup().buildLookupHandle`) never reaches\n * here. Kept as forward scaffolding for a later task that wires an independent lookup opt-in.\n */\nexport const NO_LOOKUP: LookupStrategy = {\n buildLookupHandle() {\n throw notEnabled('vault.dictionary()')\n },\n}\n\n/** `_dict_*` (legacy dict tier) and `_lookup_*` (the phase-D reserved backing). */\nexport const LOOKUP_COLLECTION_PREFIXES = ['_dict_', '_lookup_'] as const\n\n/** Return true when a collection name is a reserved lookup-backing collection. */\nexport function isLookupCollectionName(name: string): boolean {\n return LOOKUP_COLLECTION_PREFIXES.some((prefix) => name.startsWith(prefix))\n}\n\n// Re-exported pure registry helpers (#650 Task 1) — `kernel/vault.ts`'s\n// thin delegators call these directly; small always-on functions, not\n// behind the tree-shake seam (same bundling class as `isLookupCollectionName`\n// above, just too large to duplicate inline like that one is).\nexport { enforceStaticDictOnPut, resolveDictSource, updateReferencingRecords }\nexport type { DictReferencingCollection }\n\n// #650 Task 4 (#647) — the reserved-collection naming helper `vault.ts`'s sync-registry\n// bookkeeping needs (mapping a declared dimension name to its `_dict_<name>` collection name).\nexport { dictCollectionName } from '../../via/lookup/handle.js'\n\n// #650 Task 2 — the alias-equivalence bridge (`resolveLabelFromMap` +\n// `collectLookupDictCompat`/`lookupToStaticDictCompat`) + the runtime\n// brand/shape predicates `via/compose.ts` needs to route `'lookup'`-branded\n// descriptors, mirroring `isI18nTextDescriptor`/`isDictKeyDescriptor` below.\nexport { resolveLabelFromMap, collectLookupDictCompat, lookupToStaticDictCompat }\nexport type { LookupDictCompat }\n\n// #653 — partial-sync reserved-dict expansion: maps a set of named collections to the\n// one-hop `_dict_*` deps their lookup fields reference, off `dictKeyFieldRegistry`.\nexport { reservedDictDepsOf }\n\n// #650 Task 3 — altKeys ingest normalization + open/closed vocabulary\n// governance: the declare/warm-time altIndex builder + the membership test\n// vault.ts's `membership`/`getAltIndex` closures delegate to.\nexport { materializeBackingTable, checkLookupMembership, buildLookupAltIndex }\nexport type { MaterializedBacking }\n\n// #650 Task 5 — registers a collection's lookup-fields' cross-collection 'ref' graph edges.\nexport { registerLookupRefEdges }\n\n// #650 Task 6 — the sync snapshot+locale seam (#626 retirement, spec §5):\n// `snapshotFor`'s vault-built row source + the combined presentForJoin\n// builder `kernel/collection-config.ts` calls to build the\n// `JoinableSource.presentForJoin` hook `kernel/query/join.ts` consumes.\nexport { buildLookupSnapshotRows, buildPresentForJoin }\nexport type { LookupSnapshot } from '../../via/lookup/snapshot.js'\n\n// #651 Task 3 — the ONE descriptor-keyed key-resolution core (guarded coercion +\n// backing-row-key resolve + referencing-value match) — every consumer (vault.ts,\n// with-shape/links/vault-facade.ts, kernel/via/dispatch.ts) routes through here,\n// never a bare `String()`, ending the dm12 dialect drift.\nexport { coerceLookupKey, resolveBackingRowKey, matchesReferencingValue }\n\n/** Runtime predicate for detecting a `LookupDescriptor` (any of the three tiers). */\nexport function isLookupDescriptor(x: unknown): x is LookupDescriptor {\n return (\n typeof x === 'object' &&\n x !== null &&\n (x as { _viaBrand?: unknown })._viaBrand === 'lookup'\n )\n}\n\n/** Runtime predicate for the bare enum tier (`backing:'static'`, no in-code `table` — no label source). */\nexport function isEnumDescriptor(x: unknown): x is LookupDescriptor {\n return isLookupDescriptor(x) && x.backing === 'static' && x.table === undefined\n}\n\n/**\n * Type-only re-exports — the kernel spine imports these descriptor/handle\n * types through the port instead of reaching into `via/lookup/*` or\n * `via/i18n/*` directly. `isolatedModules: true` erases these at\n * build time — no runtime coupling.\n */\nexport type { LookupHandle, DictEntry, DictionaryOptions } from '../../via/lookup/handle.js'\nexport type { LookupDescriptor, Vocabulary, LookupBacking, OnDelete } from '../../via/lookup/descriptor.js'\nexport type { LookupViaConfig } from '../../via/lookup/binding.js'\nexport type { DictKeyDescriptor, StaticDictDescriptor } from '../../via/i18n/dictionary.js'\n","// kernel/via/dispatch.ts — the batched, origin-aware sync/cutover/restore dispatch wave\n// (Via port phase C, #638 Task 4, fixes #621).\n//\n// `Collection._onRecordMutated`'s `sync-apply`/`cutover`/`restore` cases feed touched\n// (collection, id) pairs into a per-session `GraphBatch` (owned by `Vault._collectGraphTouch`)\n// instead of dispatching inline — the `local-write` path keeps its own byte-identical inline\n// dispatch (`wave` stays `undefined` there, per the spec's behavior lock). At batch-flush time\n// `runGraphDispatchWave` decrypts each touched record (id threaded into the decrypt, matching\n// the phase-B at-rest contract) and re-runs the SAME `dispatchDerivations`/\n// `dispatchMaterializedViews` the local-write path uses, sharing one `WaveContext` so N touched\n// records feeding the SAME rollup/MV target recompute exactly once (per-target dedup).\n// See docs/superpowers/specs/2026-07-11-via-phase-c-design.md §3.\n\nimport type { ViaGraph } from './graph.js'\nimport type { Collection } from '../collection.js'\nimport type { EncryptedEnvelope } from '../types.js'\nimport { PeriodClosedError } from '../errors.js'\nimport { matchesReferencingValue } from '../../port/with/lookup-strategy.js'\n\n/** One deleted child's resolved rollup PARENT intent (#640) — ids + a field name only. A\n * resolved `parentId` is an id, same class as any touched record id — never a stored value. */\nexport interface RollupDeleteIntent {\n readonly into: string\n readonly parentId: string\n readonly field: string\n}\n\n/** One collection's batched touches this session (#640 widens the #638 `Set<string>` shape):\n * `puts` — the original semantics, unchanged; `deletes` — a deleted record's id mapped to its\n * resolved rollup-parent intents, captured PRE-invalidation by `Collection._onRecordMutated`'s\n * sync-apply delete case (the FK is only readable there — see `kernel/collection.ts\n * #_rollupDeleteIntents`). */\nexport interface GraphTouch {\n readonly puts: Set<string>\n readonly deletes: Map<string, readonly RollupDeleteIntent[]>\n}\n\n/** Per-session touched set — collection → its `GraphTouch`. Metadata only — ids (collection\n * names, record ids INCLUDING resolved rollup parent ids) and field names; NEVER record payload\n * or key material. A resolved parentId is an id, same class as the touched ids — not a stored\n * value. */\nexport type GraphBatch = Map<string, GraphTouch>\n\n/** Get-or-create `batch`'s `GraphTouch` entry for `collection` (#640) — shared by\n * `Vault._collectGraphTouch`/`_collectGraphDelete` so each stays a one-line call. */\nexport function touchFor(batch: GraphBatch, collection: string): GraphTouch {\n let t = batch.get(collection)\n if (!t) {\n t = { puts: new Set(), deletes: new Map() }\n batch.set(collection, t)\n }\n return t\n}\n\n/** #640 — sync, I/O-free: `deleted`'s resolved rollup PARENT intents (the FK is only readable\n * NOW, before the record is gone) — a pure function so `Collection._rollupDeleteIntents` stays\n * a one-line delegator under the kernel-surface ceiling. `registry` is `this.derivationSource\n * ?.registry()`; `collectionName` is `this.name` (the CHILD/`rollup.from` side). Generic over\n * the registry's own spec shape so this file never imports a `with-formula` type (port-layering\n * — via/dispatch.ts must not gain a with-* import). */\nexport function resolveRollupDeleteIntents<S extends { source: string; rollup?: { from: string; key: string; field: string } }>(\n registry: { strategiesForSource(name: string): ReadonlyArray<{ spec: S }> } | undefined,\n collectionName: string,\n deleted: Record<string, unknown>,\n): RollupDeleteIntent[] {\n if (!registry) return []\n const intents: RollupDeleteIntent[] = []\n for (const { spec } of registry.strategiesForSource(collectionName)) {\n if (!spec.rollup || spec.rollup.from !== collectionName) continue\n const kv = deleted[spec.rollup.key]\n if (typeof kv === 'string' || typeof kv === 'number') intents.push({ into: spec.source, parentId: String(kv), field: spec.rollup.field })\n }\n return intents\n}\n\n/** #640 — resolve a `RollupDeleteIntent` back to its registry `spec`. The wave's per-intent\n * driver needs `spec.rollup.compute`, which `GraphBatch`'s metadata-only pin forbids batching —\n * so it's re-resolved here, post-boundary, instead of carried across it. `undefined` if the\n * intent's originating strategy was unregistered between collect time and wave time (residual\n * gap, freshness-only). */\nexport function findRollupSpecForIntent<S extends { source: string; rollup?: { from: string; field: string } }>(\n registry: { strategiesForSource(name: string): ReadonlyArray<{ spec: S }> } | undefined,\n collectionName: string,\n intent: RollupDeleteIntent,\n): S | undefined {\n return registry?.strategiesForSource(collectionName).find((s) => s.spec.source === intent.into && s.spec.rollup?.field === intent.field && s.spec.rollup?.from === collectionName)?.spec\n}\n\n/** One dedup ledger for a single wave — a target is recomputed at most once (mark-on-check). */\nexport class WaveContext {\n private readonly _seen = new Set<string>()\n seen(targetKey: string): boolean {\n if (this._seen.has(targetKey)) return true\n this._seen.add(targetKey)\n return false\n }\n}\n\n/** The slice of `Vault` the wave needs: the shared graph (the #553 zero-cost skip) and cached-\n * collection lookup — never constructs, since a touched collection is, by construction,\n * already open (it just fired `_onRecordMutated`). */\nexport interface VaultLike {\n readonly graph: ViaGraph\n _getCollection(name: string): Collection<Record<string, unknown>> | undefined\n /** #640 (#644 item 3) — structured wave-error surfacing, additive to the existing console.warn. */\n _emit(event: string, payload: unknown): void\n}\n\n/**\n * Run ONE dispatch wave for a completed batch: for each touched (collection, id), decrypt the\n * applied envelope (id threaded), then run the SAME `dispatchDerivations` +\n * `dispatchMaterializedViews` the local-write path uses — with a shared `WaveContext` so N\n * touched records feeding the SAME target recompute once. #553: a collection with no graph\n * out-edges (e.g. money-only) is skipped before any decrypt/dispatch async work.\n */\nexport async function runGraphDispatchWave(vault: VaultLike, batch: GraphBatch): Promise<void> {\n const wave = new WaveContext()\n for (const [collectionName, touch] of batch) {\n if (vault.graph.dependentsOf(collectionName).length === 0) continue\n const coll = vault._getCollection(collectionName)\n if (!coll) continue\n for (const id of touch.puts) {\n try {\n // Decrypt is INSIDE the per-id isolation boundary (whole-branch review Important\n // finding, #638): an undecryptable synced envelope (`TamperedError`) must not\n // escape `_getStoredRecordForDispatch` and abort the wave — that would propagate\n // through `_flushGraphBatch` and reject the surrounding `SyncEngine.pull`/`push`\n // AFTER records were already applied + meta persisted, starving every other\n // touched target in the same batch.\n const stored = await coll._getStoredRecordForDispatch(id)\n if (!stored) continue\n await coll.dispatchDerivations(id, stored.record, stored.version, wave)\n await coll.dispatchMaterializedViews(id, stored.record, wave)\n } catch (err) {\n // #638 Task 5 review mandate: one touched record's recompute must not abort the\n // whole wave (starving co-batched healthy targets) or the pull/push it's nested\n // inside. `PeriodClosedError` never reaches here — `putDerivedOutput` already\n // intercepts it at every output-write call site and turns it into a skip+event.\n // Anything else (a genuine decrypt failure, a derive()/executor bug, a schema\n // violation on the output, ...) is surfaced — not silently swallowed — via the\n // SAME console.warn channel `dispatchDerivations`/the MV executor already use for\n // their own non-strict-mode output failures, then isolated to just this one id.\n // #644 item 3: ADDITIVELY (never in place of the warn) emit a structured event too,\n // so a listener doesn't have to scrape console output to react to a wave failure.\n console.warn(`[via-dispatch] wave recompute failed for ${collectionName}/${id}:`, err)\n vault._emit('derivation:wave-error', { collection: collectionName, id, error: err })\n }\n }\n // #640 — delete-kind touches: the deleted child's rollup-parent intents, resolved (sync,\n // pre-invalidation) at collect time by `Collection._rollupDeleteIntents`. Same per-id\n // isolation as the puts loop above. #658: the wave now ALSO heals MV rows and array-shape\n // derivation output rows for the deleted child — parity with the local-delete boundary\n // (`Collection._doDelete`'s `!internal` block, which already calls all three). Still never\n // routed through `dispatchDerivations` (the mutation-choke-point.test.ts:85-99 pin — sync-\n // applied deletes never RE-DERIVE); `dispatchMaterializedViewsOnDelete`/\n // `dispatchArrayDerivationsOnDelete` only need `id` (MV refresh recomputes+diffs; array-\n // derivation reads its per-source sidecar) and never call `derive()`, so the pin holds.\n for (const [id, intents] of touch.deletes) {\n try {\n await coll._recomputeDeletedRollups(intents, wave)\n // #658: record-shape same-id outputs are left untouched (eraseRecordShapeToo defaults\n // false), matching local delete — the user deletes those directly if wanted.\n // #658: TODO dedup MV refresh per wave — `dispatchMaterializedViewsOnDelete` doesn't\n // accept a `WaveContext` (unlike the put-path `dispatchMaterializedViews`), so N deleted\n // children of one eager MV in a batch each trigger a full refresh pass. Threading `wave`\n // through would touch collection.ts's zero-slack kernel-surface ceiling for a perf-only\n // win; correctness doesn't depend on it (idempotent per source-id) — left as a follow-up.\n await coll.dispatchMaterializedViewsOnDelete(id)\n await coll.dispatchArrayDerivationsOnDelete(id)\n } catch (err) {\n console.warn(`[via-dispatch] wave delete-recompute failed for ${collectionName}/${id}:`, err)\n vault._emit('derivation:wave-error', { collection: collectionName, id, error: err })\n }\n }\n }\n}\n\n/** A record's post-freeze source mutation, for the `'derivation:skipped-frozen'` event\n * and the optional audit-trail entry. See {@link putDerivedOutput}. */\nexport interface DerivationSkippedFrozen {\n readonly source: { readonly collection: string; readonly id: string }\n readonly target: { readonly collection: string; readonly id: string }\n readonly period: string\n readonly endDate: string\n}\n\n/** The minimal put-capable shape `putDerivedOutput` needs. Any `Collection<T>` structurally\n * satisfies this — its real `options` type is a superset of what's declared here. */\nexport interface CollectionLike {\n put(id: string, value: unknown, options?: { readonly source?: string }): Promise<void>\n}\n\nexport interface PutDerivedOutputCtx {\n readonly emit: (ev: string, p: unknown) => void\n readonly source: { readonly collection: string; readonly id: string }\n readonly audit?: ((e: DerivationSkippedFrozen) => Promise<void>) | undefined\n}\n\n/**\n * Attempt a dispatch-driven output write. On `PeriodClosedError` (the closed-period\n * `beforePut` gate — `freezePeriod`/`archivePeriod` add no separate gate, per seam map\n * Part 7): SKIP (no `_ts` stamped — the gate throws before any write happens), emit\n * `'derivation:skipped-frozen'` on the event bus (ALWAYS), and append an audit-trail entry\n * when the with-history ledger is active. Returns `'written' | 'skipped-frozen'`. Any OTHER\n * error propagates unchanged — this helper narrows exactly one error class. The SOURCE\n * write is never wrapped through this helper — only derived-output writes are (§7).\n */\nexport async function putDerivedOutput(\n outColl: CollectionLike, id: string, value: unknown,\n ctx: PutDerivedOutputCtx,\n options?: { readonly source?: string },\n): Promise<'written' | 'skipped-frozen'> {\n try {\n await outColl.put(id, value, options)\n return 'written'\n } catch (err) {\n if (!(err instanceof PeriodClosedError)) throw err\n // Reach-around for the target collection's private `name` — the SAME pattern\n // `with-formula/materialized-views/executor.ts`'s `listOutputIds` already uses to\n // read a `Collection`'s private `adapter`/`vault`/`name` fields from outside the class.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const targetCollection = (outColl as any).name as string\n const event: DerivationSkippedFrozen = {\n source: ctx.source,\n target: { collection: targetCollection, id },\n period: err.periodName,\n endDate: err.endDate,\n }\n ctx.emit('derivation:skipped-frozen', event)\n if (ctx.audit) await ctx.audit(event)\n return 'skipped-frozen'\n }\n}\n\n/** Structural (no static import — kernel spine may not statically reach a with-* service,\n * the S4 gate recipe `check-architecture.mjs`'s port-layering check enforces) shape of the\n * with-history `LedgerStore.append` seam this helper needs. */\ninterface AuditLedgerLike {\n append(input: {\n readonly op: 'lifecycle'\n readonly collection: string\n readonly id: string\n readonly version: number\n readonly actor: string\n readonly payloadHash: string\n readonly reason?: string\n }): Promise<unknown>\n}\n\n/** @internal — the optional with-history ledger audit hook for `putDerivedOutput`, present\n * only when the ledger is active (mirrors every other kernel event's `if (this.ledger)`\n * gate). Encoded as a `'lifecycle'` entry — the existing \"non-data audit event\" op (the\n * same convention `forget`'s JSON-summary-in-`reason` entry uses; `ledger/entry.ts:88-104`). */\nexport function ledgerAuditHook(\n ledger: AuditLedgerLike | undefined, actor: string,\n): ((e: DerivationSkippedFrozen) => Promise<void>) | undefined {\n if (!ledger) return undefined\n return async (e) => {\n await ledger.append({\n op: 'lifecycle', collection: e.target.collection, id: e.target.id, version: 0, actor, payloadHash: '',\n reason: JSON.stringify({ event: 'derivation-skipped-frozen', ...e }),\n })\n }\n}\n\n/** `recomputeRollup`/`dispatchRollupsOnDelete`'s per-target write outcome (#638 Task 6):\n * `'written'`/`'skipped-frozen'` mirror {@link putDerivedOutput}'s result; `'noop'` covers\n * no-parent/no-change/deduped-by-wave — nothing to report either way. */\nexport type RollupOutcome = 'written' | 'skipped-frozen' | 'noop'\n\n/** Mutable accumulator `forgetDerivedFanout` writes into, one per `Vault.forget()` call — keeps\n * the per-ref loop's call site to a single line under vault.ts's tight kernel-surface ceiling.\n * Maps 1:1 onto `ForgetResult`'s additive fields (`with-audit/forget/strategy.ts`). */\nexport interface ForgetFanoutStats {\n recordsErased: number\n aggregatesRecomputed: number\n readonly residueFrozen: string[]\n /** #650 Task 5 (#648) — referencing records tombstoned via a `'ref'` edge's `cascade` policy. */\n lookupReferencesCascaded: number\n /** #650 Task 5 (#648) — referencing fields cleared via a `'ref'` edge's `nullify` policy. */\n lookupReferencesNullified: number\n /** #650 Task 5 review (Important fix) — `'ref'` edges whose compare-key could NOT be resolved,\n * even from the LIVE pre-shred row (the backing row itself is unreadable) — propagation was\n * skipped for these, reported here so the skip is never silent. `backing:key:collection.field`\n * entries, one per un-propagated edge. */\n readonly lookupReferencesResidue: string[]\n /** #776/#782/#785 — `outputCollection:id` MV-output rows that survived erasure invalidation\n * (eager tombstone leg AND lazy/manual `invalidateMVAtRest`) despite belonging to the\n * forgotten subject, because the ownership stamp could not be decoded (undecodable under\n * the default DEK — e.g. elevated above tier 0 on a tiered output collection). Ownership\n * UNCONFIRMED. Never erased, but surfaced here rather than silently skipped. */\n readonly derivedResidueUndecodable: string[]\n /** #782/#785 — `outputCollection:id` MV-output rows that decoded and stamp-matched but whose\n * `_internalDelete` declined (the #718 tier-elevation gate). Ownership CONFIRMED, erasure\n * declined — a real silent survival, surfaced here rather than silently skipped. */\n readonly derivedResidueDeclined: string[]\n}\n\n/**\n * #622 — after `_writeTombstone(ref.id, actor)` erases the forgotten subject's own record, fan\n * out to its derived residue via the graph (spec §5): record-grain artifacts (MV rows,\n * array-shape derivation rows, same-id record-shape derivation copies) are ERASED through the\n * SAME `!internal` housekeeping-bypass machinery the ordinary delete path uses (no user\n * `onDelete` re-fires — the shred-is-not-a-domain-delete property `_writeTombstone` protects);\n * aggregate-grain rollups are RECOMPUTED without the forgotten contribution in open periods, or\n * skip+audit (via `putDerivedOutput`, already wired into the rollup/MV output paths) in frozen\n * ones. Mutates `stats` in place. `envelope` is `ref`'s PRE-tombstone envelope, decoded only if\n * a rollup edge is actually present — the #553 zero-cost-skip discipline: no decrypt for the\n * common case of a forgotten record with no aggregate-grain consumer, and no work at all when\n * `ref.collection` has no graph out-edges. `lookupCompareKeys` is the `'ref'` edges' compare-key\n * map, resolved from the LIVE row BEFORE any shred (`VaultLinks.checkLookupRefsRestrict`'s return\n * value — `Vault.forget()`'s pre-shred restrict check doubles as the live-resolve pass) — see\n * {@link applyLookupRefsFanout}.\n */\nexport async function forgetDerivedFanout(\n vault: VaultLike,\n ref: { readonly collection: string; readonly id: string },\n envelope: EncryptedEnvelope | null,\n stats: ForgetFanoutStats,\n lookupCompareKeys: ReadonlyMap<string, string | undefined>,\n): Promise<void> {\n const coll = vault._getCollection(ref.collection)\n\n // #761 item 4 — drive the MV arm off `dispatchMaterializedViewsOnDelete` UNCONDITIONALLY,\n // ABOVE the `edges` check below: `registry.edges()` drops the same-collection\n // partition-disjoint MV edge (registry.ts's `sources.length === 0 → continue`), so a\n // same-collection MV's source collection never appears in `vault.graph`'s derived-artifact\n // edges even though the MV IS registered — forget() would otherwise never reach it.\n // `dispatchMaterializedViewsOnDelete` self-guards O(1) via `mvsForSource` (a no-op when\n // this collection isn't an MV source), so this is safe to call unconditionally. Safe to\n // route through the eager executor's tombstone leg ONLY because that leg is now\n // stamp-scoped (#762) — before that fix this would have opened a NEW forget-time\n // data-loss path into the unscoped tombstone diff.\n if (coll) {\n const mv = await coll.dispatchMaterializedViewsOnDelete(ref.id)\n stats.recordsErased += mv.deleted\n stats.derivedResidueUndecodable.push(...mv.residueUndecodable)\n stats.derivedResidueDeclined.push(...mv.residueDeclined)\n }\n\n const edges = vault.graph.derivedArtifactsOf(ref.collection)\n if (edges.length === 0 || !coll) return\n\n // #650 Task 5 (#648) — 'ref' cascade/nullify propagate ADDITIVELY, here, AFTER the shred\n // (restrict already refused BEFORE any shred — the caller's pre-tombstone check, spec §4).\n // The I/O shell (loop shape, collection accessor) is duplicated, not imported, from\n // `VaultLinks.applyLookupRefsPropagation`/`checkLookupRefsRestrict` (with-shape/links/\n // vault-facade.ts) — the kernel spine may not statically import a with-* service\n // (port-layering, the #638 Task 5 via/dispatch.ts precedent); `vault._getCollection` is\n // cached-only while `VaultLinks`' accessor constructs. The pure match predicate itself is\n // shared through the port seam (#651 Task 3 — `matchesReferencingValue`, `port/with/\n // lookup-strategy.ts`), so only the shell, not the coercion logic, stays duplicated. A\n // referencing edge whose dimension uses a non-default `key` (matrix tier only) needs the\n // backing row's OWN value at that field, not its PUT-id — the row is ALREADY tombstoned by\n // now, so it's read from `lookupCompareKeys`, resolved by the caller from the LIVE row\n // BEFORE the shred (#650 Task 5 review, Important fix — eliminates the post-shred\n // envelope-decode dependency this used to have, which silently skipped propagation whenever\n // that decode failed).\n if (edges.some((e) => e.kind === 'ref')) {\n const { cascaded, nullified, residue } = await applyLookupRefsFanout(vault, ref.collection, ref.id, lookupCompareKeys)\n stats.lookupReferencesCascaded += cascaded\n stats.lookupReferencesNullified += nullified\n stats.lookupReferencesResidue.push(...residue)\n }\n\n if (edges.some((e) => e.kind === 'derivation')) {\n // #622 review Finding 1: count REAL erasures (dispatchArrayDerivationsOnDelete's own\n // `_internalDelete`-backed tally), not the derivation EDGE count — an edge exists whenever\n // this collection is ANY trigger (source/sources[]/triggerBy), but the same-id record-shape\n // guard only erases for `spec.source === this.name`, and `derive()` may never have produced\n // an output row (optional-skip) in the first place. Both cases must contribute 0, not +1.\n stats.recordsErased += await coll.dispatchArrayDerivationsOnDelete(ref.id, true)\n }\n\n if (envelope && edges.some((e) => e.kind === 'rollup')) {\n const priorRecord = await coll._decodeEnvelope(envelope, ref.id)\n if (priorRecord) {\n for (const r of await coll.dispatchRollupsOnDelete(ref.id, priorRecord)) {\n if (r.outcome === 'written') stats.aggregatesRecomputed += 1\n else if (r.outcome === 'skipped-frozen') stats.residueFrozen.push(`${r.into}:${r.parentId}`)\n }\n }\n }\n}\n\n/**\n * Apply `cascade`/`nullify` propagation for `backing`'s non-restrict `'ref'` edges — the\n * forget-path counterpart of `VaultLinks.applyLookupRefsPropagation` (I/O shell duplicated, not\n * imported, match predicate shared via the port — see {@link forgetDerivedFanout}'s call site\n * comment). `restrict` edges are skipped here: the\n * forget loop's `checkLookupRefsRestrict`-equivalent call already refused (or the reference no\n * longer existed) BEFORE `_writeTombstone` ran, so by the time this runs only cascade/nullify\n * remain to propagate. `compareKeys` is the non-`'id'`-`keyField` compare-value map, resolved by\n * the caller from the LIVE row BEFORE the shred (#650 Task 5 review, Important fix) — the live row\n * is already shredded by the time THIS function runs, so it can no longer resolve one itself. A\n * `keyField` absent from (or `undefined` in) the map means that live resolve failed too — the edge\n * is reported as residue instead of silently skipped (never a bare `continue` with no trace).\n */\nasync function applyLookupRefsFanout(\n vault: VaultLike,\n backing: string,\n key: string,\n compareKeys: ReadonlyMap<string, string | undefined>,\n): Promise<{ cascaded: number; nullified: number; residue: string[] }> {\n let cascaded = 0\n let nullified = 0\n const residue: string[] = []\n for (const { referencing, onDelete, keyField } of vault.graph.referencingEdgesOf(backing)) {\n if (onDelete === 'restrict') continue\n const compareKey = keyField === 'id' ? key : compareKeys.get(keyField)\n if (compareKey === undefined) {\n residue.push(`${backing}:${key}:${referencing.collection}.${referencing.field}`)\n continue\n }\n const coll = vault._getCollection(referencing.collection)\n if (!coll) continue\n const matches = (await coll.list()).filter((rec) => matchesReferencingValue(rec, referencing.field, compareKey))\n for (const rec of matches) {\n const id = rec['id'] as string | undefined\n if (id === undefined) continue\n if (onDelete === 'cascade') {\n await coll.delete(id)\n cascaded++\n } else if (onDelete === 'nullify') {\n await coll.put(id, { ...rec, [referencing.field]: null })\n nullified++\n }\n }\n }\n return { cascaded, nullified, residue }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import {
|
|
2
2
|
openEnvelopeJson
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-XDYREZWE.js";
|
|
4
4
|
import {
|
|
5
5
|
encrypt
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-CIE2BASH.js";
|
|
7
7
|
import {
|
|
8
8
|
NOYDB_FORMAT_VERSION
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-JNAI2HN2.js";
|
|
10
10
|
import {
|
|
11
11
|
ConflictError,
|
|
12
12
|
USER_ENVELOPE_COLLECTION,
|
|
13
13
|
USER_ENVELOPE_MAX_BYTES,
|
|
14
14
|
UserEnvelopeOversizedError
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-BIOUI4HL.js";
|
|
16
16
|
|
|
17
17
|
// src/with-party/directory/storage.ts
|
|
18
18
|
var META_COLLECTION = "_meta";
|
|
@@ -147,4 +147,4 @@ export {
|
|
|
147
147
|
deleteUserEnvelope,
|
|
148
148
|
listUserEnvelopeIds
|
|
149
149
|
};
|
|
150
|
-
//# sourceMappingURL=chunk-
|
|
150
|
+
//# sourceMappingURL=chunk-4JBYV75E.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
MaterializedViewConfigError,
|
|
3
3
|
ValidationError
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-BIOUI4HL.js";
|
|
5
5
|
|
|
6
6
|
// src/with-formula/materialized-views/with-materialized-view.ts
|
|
7
7
|
function withMaterializedView(spec) {
|
|
@@ -94,4 +94,4 @@ function withMaterializedView(spec) {
|
|
|
94
94
|
export {
|
|
95
95
|
withMaterializedView
|
|
96
96
|
};
|
|
97
|
-
//# sourceMappingURL=chunk-
|
|
97
|
+
//# sourceMappingURL=chunk-4NXKCLLQ.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
NoydbError
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-BIOUI4HL.js";
|
|
4
4
|
|
|
5
5
|
// src/kernel/via/index.ts
|
|
6
6
|
var binders = /* @__PURE__ */ new Map();
|
|
@@ -26,4 +26,4 @@ export {
|
|
|
26
26
|
isViaInstalled,
|
|
27
27
|
viaBinder
|
|
28
28
|
};
|
|
29
|
-
//# sourceMappingURL=chunk-
|
|
29
|
+
//# sourceMappingURL=chunk-4VNQOLML.js.map
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
} from "./chunk-LP7BEXCT.js";
|
|
6
6
|
import {
|
|
7
7
|
bufferToBase64
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-CIE2BASH.js";
|
|
9
9
|
|
|
10
10
|
// src/kernel/enclave/classify/bidx.ts
|
|
11
11
|
var subtle = globalThis.crypto.subtle;
|
|
@@ -66,4 +66,4 @@ export {
|
|
|
66
66
|
mintBidxTag,
|
|
67
67
|
computeBidxTarget
|
|
68
68
|
};
|
|
69
|
-
//# sourceMappingURL=chunk-
|
|
69
|
+
//# sourceMappingURL=chunk-5M5DVGV7.js.map
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
openEnvelopeJson
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-XDYREZWE.js";
|
|
4
4
|
import {
|
|
5
5
|
encrypt,
|
|
6
6
|
hmacSha256Hex,
|
|
7
7
|
sha256Hex
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-CIE2BASH.js";
|
|
9
9
|
import {
|
|
10
10
|
NOYDB_FORMAT_VERSION
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-JNAI2HN2.js";
|
|
12
12
|
|
|
13
13
|
// src/with-audit/forget/strategy.ts
|
|
14
14
|
var NO_FORGET = { subjects: {} };
|
|
@@ -147,4 +147,4 @@ export {
|
|
|
147
147
|
coerceSubjectId,
|
|
148
148
|
readDottedPath
|
|
149
149
|
};
|
|
150
|
-
//# sourceMappingURL=chunk-
|
|
150
|
+
//# sourceMappingURL=chunk-5O3XF4DV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/with-audit/forget/strategy.ts","../src/with-audit/forget/subject-index.ts"],"sourcesContent":["/**\n * `withForgetCascade` — declaration surface for GDPR right-to-erasure via\n * per-record CEK crypto-shred.\n *\n * This file holds only the *declaration* shape and the disabled sentinel.\n * The actual erasure machinery lives in:\n * - `subject-index.ts` — the encrypted `_subject_index` reserved collection\n * - `vault.ts` `forget()` — the per-record tombstone + ledger flow\n * - `collection.ts` `_writeTombstone` — the envelope rewrite\n *\n * A `ForgetStrategy` declares which collections carry erasable subject data\n * and the (dotted-path) field on each record that names the data subject.\n * Declaring a collection here ALSO forces `perRecordKeys: true` for it (a\n * shred can only erase a record whose body is keyed off a per-record CEK),\n * so adopters opt into the CEK foundation transitively.\n *\n * @module\n */\nimport type { LedgerEntry } from '../../with-commit/history/ledger/entry.js'\n\n/**\n * User-supplied declaration passed to {@link withForgetCascade}. Maps a\n * collection name to the record field (dotted path supported, e.g.\n * `'billing.buyerId'`) that identifies the data subject for erasure.\n *\n * ```ts\n * withForgetCascade({ subjects: { invoices: 'buyerId', contacts: 'id' } })\n * ```\n */\nexport interface SubjectDeclaration {\n readonly subjects: Record<string, string>\n /**\n * #633 — opt-in: gate the vault-level `_sealed_cek` and blob purges on\n * per-collection via declarations instead of running them unconditionally\n * for every forgotten ref. Default `false`/absent = today's unconditional\n * behavior (byte-identical). See `purge-scope.ts` for the partition logic\n * and the `scopedPurgeResidue` skip-reporting this enables.\n *\n * **Footgun:** a bare `sensitive: [...]` collection — no `classifiedFields`\n * (no classified via binder compiled in) — counts as UNDECLARED for the\n * sealed-CEK arm. Under `scopedPurge: true`, its `_sealed_cek` host-delivery\n * envelopes are SKIPPED, not purged (reported via `scopedPurgeResidue`,\n * reason `'skipped-undeclared-sealed-cek'`) even if that collection called\n * `sealRecordToHost()` — the sealed CEK stays recoverable by that granted\n * host until purged. Add a `classifiedFields` binding to close the gap, or\n * leave `scopedPurge` off/false for the unconditional (always-purged) default.\n * The declaration signal is session-local: a declared collection never opened\n * (with its config) before `forget()` in this session counts as UNDECLARED —\n * open it first, or its entries are skipped-and-reported.\n */\n readonly scopedPurge?: boolean\n}\n\n/**\n * Resolved forget strategy threaded through Noydb → every Vault. Carries\n * the same `subjects` map the user declared. `NO_FORGET` (empty map) is the\n * off-by-default sentinel; `vault.forget()` throws\n * `ForgetStrategyNotConfiguredError` when the map is empty.\n */\nexport interface ForgetStrategy {\n /** Collection → subject-field (dotted path). Empty under `NO_FORGET`. */\n readonly subjects: Readonly<Record<string, string>>\n /** #633 — see {@link SubjectDeclaration.scopedPurge}. */\n readonly scopedPurge?: boolean\n}\n\n/**\n * Disabled sentinel — no collections declare a subject field. `vault.forget()`\n * refuses with `ForgetStrategyNotConfiguredError`; no write hooks register; no\n * collection is forced into `perRecordKeys`. Non-adopters pay nothing.\n */\nexport const NO_FORGET: ForgetStrategy = { subjects: {} }\n\n// The `withForgetCascade` factory lives in `active.ts` (canonical\n// strategy.ts/active.ts/index.ts split); this file holds only the\n// declaration shape + disabled sentinel.\n\n/**\n * The outcome of a `vault.forget(subjectId)` call.\n *\n * `unmigratedRecords` lists `collection:id` pairs that were tombstoned but\n * whose body had NOT been migrated to a per-record CEK at shred time (legacy\n * body still under the shared collection DEK). Those records are tombstoned\n * (live envelope + history stripped) but their pre-shred ciphertext, if it\n * leaked into a backup before migration, remains decryptable under the\n * collection DEK — so erasure-completeness is NOT guaranteed for them. Run\n * the per-record-CEK migration pass, then re-forget, to close the gap.\n *\n * Blob attachments: a shredded record's **erasable** blobs (on a\n * `perRecordKeys` collection) are crypto-shredded inline — `blobsShredded`\n * counts those taken to refCount 0 (BlobObject deleted → chunks permanently\n * undecryptable), `blobsRetainedShared` counts those still referenced by\n * another record (shared content legitimately persists for its other owner).\n * `blobResidueCollections` now lists only collections with blobs that could\n * NOT be crypto-shredded: **legacy** blobs (no per-blob `_cek`, chunks under\n * the shared `_blob` DEK — migrate them), or a session without the blob\n * service loaded. An all-erasable subject yields an empty residue list.\n */\nexport interface ForgetResult {\n /** The subject id passed to `forget()`. Echoed for caller convenience. */\n readonly subject: string\n /** Count of live records rewritten to a tombstone. */\n readonly recordsShredded: number\n /** Count of `_history` envelopes tombstoned across all shredded records. */\n readonly historyVersionsShredded: number\n /** Distinct collections that had at least one record shredded. */\n readonly collections: readonly string[]\n /** `collection:id` pairs shredded while still un-migrated (see type docs). */\n readonly unmigratedRecords: readonly string[]\n /** Count of erasable blobs crypto-shredded (refCount → 0, BlobObject deleted). */\n readonly blobsShredded: number\n /** Count of erasable blobs retained because still referenced elsewhere (shared). */\n readonly blobsRetainedShared: number\n /** Collections with blobs that could NOT be crypto-shredded — legacy (no `_cek`) or blobs disabled (see type docs). */\n readonly blobResidueCollections: readonly string[]\n /**\n * Count of persisted `_idx/<field>/<recordId>` index side-cars hard-deleted\n * across the shredded records. These live under the retained\n * collection DEK, so crypto-shred alone would leave the indexed field VALUES\n * readable — `forget()` must delete them.\n */\n readonly indexPostingsPurged: number\n /**\n * `collection:id:field` entries whose persisted `_idx` side-car could NOT be\n * deleted — index residue that still leaks the indexed value under the\n * retained collection DEK. Non-empty means erasure is INCOMPLETE: retry, or\n * purge the side-car out of band.\n */\n readonly indexResidue: readonly string[]\n /**\n * Count of `_sealed[field]` slots dropped from the live store across the\n * shredded records. For slots written under `sensitive` +\n * `perRecordKeys` (the current path), the key derives off the per-record CEK,\n * so tombstoning the record — which drops `_cek` and `_sealed` — also\n * crypto-shreds the value. A legacy slot (written before per-record CEKs) keys\n * off the collection DEK instead, so dropping it removes it from the live store but a\n * pre-forget backup remains recoverable by a DEK holder (same caveat `_data`\n * carries); migrate by re-`put`ting before forgetting for full crypto-shred.\n */\n readonly sealedFieldsShredded: number\n /** Count of `_sealed_cek` host-delivery envelopes deleted (#H-1). A record sealed to an\n * at-* host via sealRecordToHost persists its raw CEK there; forget() must destroy them. */\n readonly sealedCekEnvelopesPurged: number\n /** `collection:id` whose `_sealed_cek` purge failed (residue — the host-recoverable CEK may survive). */\n readonly sealedCekResidue: readonly string[]\n /** `collection:id:field` sealed slots that were DEK-derived (legacy, written before per-record CEKs) and thus NOT crypto-shredded\n * by dropping `_cek` — the collection DEK is retained, so synced/backup copies stay decryptable (#M-1). */\n readonly sealedResidue: readonly string[]\n /** Count of `_ledger_deltas` rows hard-deleted across the shredded records (#734) — the\n * erasure twin of #729's elevate-side purge. Entry metadata (that the record was mutated,\n * at which version/timestamp/actor) is retained; only the plaintext delta content is removed. */\n readonly ledgerDeltasPurged: number\n /** `collection:id` refs whose `_ledger_deltas` purge failed — plaintext delta residue still\n * readable under the retained ledger DEK. Non-empty means erasure is INCOMPLETE. */\n readonly ledgerDeltaResidue: readonly string[]\n /** The single `op:'forget'` ledger entry appended for this erasure. */\n readonly ledgerEntry: LedgerEntry\n /** #622 — record-grain derived artifacts (MV rows, per-record derived copies) erased\n * because their source subject was forgotten. Overlay outputs are intentionally out of\n * scope here — an overlay is always sourced from an MV, never directly from a subject\n * collection, so the personal-data-bearing MV rows it reads are already erased above. */\n readonly derivedRecordsErased: number\n /** #622 — aggregate-grain targets (rollups) recomputed without the forgotten contribution. */\n readonly derivedAggregatesRecomputed: number\n /** #622 — `collection:id` derived writes SKIPPED because the target period is frozen\n * (recompute deferred; the aggregate retains the forgotten contribution — audited). */\n readonly derivedResidueFrozen: readonly string[]\n /** #650 Task 5 (#648) — referencing records tombstoned via a `'ref'` edge's `cascade` policy. */\n readonly lookupReferencesCascaded: number\n /** #650 Task 5 (#648) — referencing fields cleared via a `'ref'` edge's `nullify` policy. */\n readonly lookupReferencesNullified: number\n /** #650 Task 5 review (Important fix) — `'ref'` edges whose compare-key could NOT be resolved,\n * even from the LIVE pre-shred backing row — cascade/nullify propagation was SKIPPED for these.\n * Always empty in the ordinary case; non-empty means the skip is reported, never silent. */\n readonly lookupReferencesResidue: readonly string[]\n /** #633 — scoped-purge skip notices (opt-in `scopedPurge`, see {@link SubjectDeclaration}).\n * Always empty under the unconditional default. Non-empty means a `_sealed_cek` entry or a\n * blob scan was skipped for an undeclared collection — reported, never a silent skip. */\n readonly scopedPurgeResidue: readonly ScopedPurgeResidueNotice[]\n /** #776/#782/#785 — `collection:id` MV-output rows that survived erasure invalidation (eager\n * tombstone leg AND lazy/manual `invalidateMVAtRest`) despite belonging to the forgotten\n * subject, because the `_materializedFrom` ownership stamp could NOT be decoded (undecodable\n * under the collection's default DEK — e.g. elevated above tier 0 on a tiered output\n * collection; ownership unconfirmed — could be a plain user record on a same-collection\n * partition MV). Never erased, but surfaced here rather than silently skipped (the #724\n * posture). Non-empty means the row may still hold the forgotten/pre-elevation contribution,\n * decryptable by tier-holders. */\n readonly derivedResidueUndecodable: readonly string[]\n /** #782/#785 — `collection:id` MV-output rows that DID decode and stamp-match via\n * `_materializedFrom`, but whose erasure was declined by the #718 tier-elevation gate\n * (`_internalDelete` returned false). Ownership CONFIRMED here — a real silent survival,\n * not a stamp-mismatch skip — surfaced rather than dropped. Non-empty means a live,\n * tier-holder-decryptable copy of the forgotten contribution was deliberately retained. */\n readonly derivedResidueDeclined: readonly string[]\n}\n\n/** #633 — the two `scopedPurgeResidue` skip reasons. Single source of truth: `purge-scope.ts`\n * (the port-internal partition helpers) imports this rather than redeclaring it. */\nexport type ScopedPurgeResidueReason = 'skipped-undeclared-sealed-cek' | 'skipped-undeclared-blob-scan'\n\n/** #633 — one `ForgetResult.scopedPurgeResidue` entry: an undeclared collection's sealed-CEK\n * entries left unpurged, or its blob scan skipped entirely, under `scopedPurge`. `count` is the\n * number of `_sealed_cek` entries left in place (sealed-cek reason) or the number of refs whose\n * blob scan was skipped (blob-scan reason) — aggregated per collection across the whole call. */\nexport interface ScopedPurgeResidueNotice {\n readonly reason: ScopedPurgeResidueReason\n readonly collection: string\n readonly count: number\n}\n","/**\n * The encrypted subject index.\n *\n * GDPR crypto-shred needs to answer \"which records belong to data subject\n * X?\" portably (the index must travel with the vault/bundle) WITHOUT leaking\n * subject-equivalence to the store. The rejected alternative — an unencrypted\n * subject tag in envelope metadata — would let anyone with store access see\n * which records share a subject. Instead we keep a reserved `_subject_index`\n * collection, encrypted under its OWN DEK (`getDEK('_subject_index')`):\n *\n * - record id = `HMAC-SHA256(indexDEK, subjectId)` (M-2). A bare\n * `sha256Hex(subjectId)` would be offline-computable: an attacker with\n * store access and a candidate list (emails / customer ids are low-entropy)\n * could dictionary the hash to confirm \"subject X is present here.\" Keying\n * the id with the vault-only index DEK removes that capability — without the\n * DEK the id cannot be derived. (Legacy entries written before M-2 used the\n * bare sha256 id; the read/remove paths dual-look-up both forms.)\n * - record body = AES-GCM(JSON `{ r: [{ collection, id }], p }`) under the\n * index DEK, where `p` pads the plaintext to a bucketed length so the\n * ciphertext `_data` length does not leak the approximate record count.\n * Legacy bodies were a bare `[{ collection, id }]` array; reads accept both.\n *\n * ## Concurrency (RISK #3 — known v1 limitation)\n *\n * `addSubjectRef` / `removeSubjectRef` are read-modify-write with no CAS. The\n * design assumes a SINGLE WRITER (the noy-db single-process write model). Two\n * concurrent writers racing on the SAME subject can lose an entry (last-write\n * wins on the ref list). This is documented, not fixed in v1:\n * `rebuildSubjectIndex` performs a full scan to recover a correct index from\n * the canonical records, so a lost ref is recoverable. A CAS-backed index is\n * deferred to a later slice.\n *\n * @module\n */\nimport { encrypt, openEnvelopeJson, hmacSha256Hex, sha256Hex, type EnclaveKey } from '../../kernel/enclave/index.js'\nimport type { NoydbStore, EncryptedEnvelope } from '../../kernel/types.js'\nimport { NOYDB_FORMAT_VERSION } from '../../kernel/types.js'\n\n/** Reserved collection holding the encrypted subject → records index. */\nexport const SUBJECT_INDEX_COLLECTION = '_subject_index'\n\n/**\n * Bucket (bytes) the encrypted ref-list plaintext is padded up to, so the\n * ciphertext `_data` length leaks only `count` rounded up to a bucket — not the\n * exact record count. 256 keeps small subjects (the common case) indistinguishable.\n */\nconst REF_LIST_BUCKET = 256\n\n/** A single record reference held in a subject's index entry. */\nexport interface SubjectRef {\n readonly collection: string\n readonly id: string\n}\n\ntype GetDEK = (collectionName: string) => Promise<EnclaveKey>\n\n/** SHA-256 hex of a UTF-8 string. The LEGACY (pre-M-2) subject-index key. */\nasync function sha256HexString(input: string): Promise<string> {\n return sha256Hex(new TextEncoder().encode(input))\n}\n\n/**\n * The subject-index record id(s) to consult for a subject, most-current first.\n *\n * - Encrypted vault: the PRIMARY id is `HMAC-SHA256(indexDEK, subjectId)` (M-2)\n * — not offline-computable. The LEGACY `sha256Hex(subjectId)` id is also\n * returned so reads/removes still find entries written before M-2 (dual-lookup).\n * - Plaintext/debug vault: no DEK to key with, so the only id is the legacy\n * sha256 form (unchanged behaviour — plaintext mode is not zero-knowledge anyway).\n */\nasync function subjectKeys(getDEK: GetDEK, encrypted: boolean, subjectId: string): Promise<string[]> {\n const legacy = await sha256HexString(subjectId)\n if (!encrypted) return [legacy]\n const dek = await getDEK(SUBJECT_INDEX_COLLECTION)\n const keyed = await hmacSha256Hex(dek, new TextEncoder().encode(subjectId))\n return keyed === legacy ? [keyed] : [keyed, legacy]\n}\n\n/** The id new writes land under (keyed when encrypted, else legacy sha256). */\nasync function primarySubjectKey(getDEK: GetDEK, encrypted: boolean, subjectId: string): Promise<string> {\n return (await subjectKeys(getDEK, encrypted, subjectId))[0]!\n}\n\n/** Parse a stored ref-list body: new padded `{ r, p }` wrapper OR legacy bare array. */\nfunction parseRefs(json: string): SubjectRef[] {\n const parsed = JSON.parse(json) as SubjectRef[] | { r: SubjectRef[] }\n return Array.isArray(parsed) ? parsed : parsed.r\n}\n\n/** Serialize + pad the ref list to a bucket boundary (encrypted vaults only). */\nfunction serializeRefs(refs: SubjectRef[]): string {\n const base = JSON.stringify({ r: refs, p: '' })\n const pad = Math.ceil(base.length / REF_LIST_BUCKET) * REF_LIST_BUCKET - base.length\n return JSON.stringify({ r: refs, p: ' '.repeat(pad) })\n}\n\n/** Read + decrypt the ref list at a SINGLE index key. Returns `[]` when absent. */\nasync function readRefs(\n adapter: NoydbStore,\n vault: string,\n getDEK: GetDEK,\n encrypted: boolean,\n key: string,\n): Promise<SubjectRef[]> {\n const env = await adapter.get(vault, SUBJECT_INDEX_COLLECTION, key)\n if (!env || !env._data) return []\n if (!encrypted) return parseRefs(env._data)\n const dek = await getDEK(SUBJECT_INDEX_COLLECTION)\n const json = await openEnvelopeJson(env, dek)\n return parseRefs(json)\n}\n\n/** Encrypt + write a ref list for a subject under its derived key. */\nasync function writeRefs(\n adapter: NoydbStore,\n vault: string,\n getDEK: GetDEK,\n encrypted: boolean,\n key: string,\n refs: SubjectRef[],\n): Promise<void> {\n let env: EncryptedEnvelope\n if (!encrypted) {\n // Plaintext/debug vault: keep the legacy bare-array form (no padding needed).\n env = { _noydb: NOYDB_FORMAT_VERSION, _v: 1, _ts: new Date().toISOString(), _iv: '', _data: JSON.stringify(refs) }\n } else {\n const dek = await getDEK(SUBJECT_INDEX_COLLECTION)\n const { iv, data } = await encrypt(serializeRefs(refs), dek)\n env = { _noydb: NOYDB_FORMAT_VERSION, _v: 1, _ts: new Date().toISOString(), _iv: iv, _data: data }\n }\n await adapter.put(vault, SUBJECT_INDEX_COLLECTION, key, env)\n}\n\n/**\n * Add a `{ collection, id }` ref to a subject's index entry (idempotent —\n * a duplicate ref is not appended). Read-modify-write; see the concurrency\n * note in the module docstring.\n */\nexport async function addSubjectRef(\n adapter: NoydbStore,\n vault: string,\n getDEK: GetDEK,\n encrypted: boolean,\n subjectId: string,\n ref: SubjectRef,\n): Promise<void> {\n const key = await primarySubjectKey(getDEK, encrypted, subjectId)\n const refs = await readRefs(adapter, vault, getDEK, encrypted, key)\n if (refs.some((r) => r.collection === ref.collection && r.id === ref.id)) return\n refs.push(ref)\n await writeRefs(adapter, vault, getDEK, encrypted, key, refs)\n}\n\n/**\n * Remove a `{ collection, id }` ref from a subject's index entry. When the\n * last ref is removed the (now empty) entry is deleted so the store holds no\n * residual key for an erased subject.\n */\nexport async function removeSubjectRef(\n adapter: NoydbStore,\n vault: string,\n getDEK: GetDEK,\n encrypted: boolean,\n subjectId: string,\n ref: SubjectRef,\n): Promise<void> {\n // Dual-lookup: drop the ref from BOTH the keyed (M-2) and the legacy sha256\n // entry, so a pre-M-2 subject is still fully erased.\n for (const key of await subjectKeys(getDEK, encrypted, subjectId)) {\n const refs = await readRefs(adapter, vault, getDEK, encrypted, key)\n const next = refs.filter((r) => !(r.collection === ref.collection && r.id === ref.id))\n if (next.length === refs.length) continue\n if (next.length === 0) {\n await adapter.delete(vault, SUBJECT_INDEX_COLLECTION, key)\n } else {\n await writeRefs(adapter, vault, getDEK, encrypted, key, next)\n }\n }\n}\n\n/**\n * Look up every record ref for a subject. Returns `[]` when none exist. Unions\n * the keyed (M-2) and legacy sha256 entries (dual-lookup), deduplicated, so a\n * subject indexed before M-2 is still fully found.\n */\nexport async function lookupSubject(\n adapter: NoydbStore,\n vault: string,\n getDEK: GetDEK,\n encrypted: boolean,\n subjectId: string,\n): Promise<SubjectRef[]> {\n const keys = await subjectKeys(getDEK, encrypted, subjectId)\n const seen = new Set<string>()\n const out: SubjectRef[] = []\n for (const key of keys) {\n for (const ref of await readRefs(adapter, vault, getDEK, encrypted, key)) {\n const dedup = `${ref.collection}\\u0000${ref.id}`\n if (seen.has(dedup)) continue\n seen.add(dedup)\n out.push(ref)\n }\n }\n return out\n}\n\n/**\n * Rebuild the entire subject index from the canonical records (the recovery\n * path for the documented read-modify-write race). Scans each declared\n * collection, reads `record[subjectField]` (dotted path), and rewrites the\n * index from scratch. Tombstoned (already-shredded) records contribute no\n * ref — their body is gone, so they cannot be re-indexed.\n *\n * `decodeRecord` decrypts an envelope to a plain object (or returns null for\n * a tombstone / unreadable record); supplied by the caller so this module\n * stays free of Collection internals.\n */\nexport async function rebuildSubjectIndex(\n adapter: NoydbStore,\n vault: string,\n getDEK: GetDEK,\n encrypted: boolean,\n subjects: Readonly<Record<string, string>>,\n decodeRecord: (collection: string, id: string, env: EncryptedEnvelope) => Promise<Record<string, unknown> | null>,\n): Promise<number> {\n // Drop every existing index entry first so removed refs don't linger.\n const existing = await adapter.list(vault, SUBJECT_INDEX_COLLECTION)\n for (const k of existing) {\n await adapter.delete(vault, SUBJECT_INDEX_COLLECTION, k)\n }\n\n // subjectId → refs, accumulated across all declared collections.\n const bySubject = new Map<string, SubjectRef[]>()\n for (const [collection, field] of Object.entries(subjects)) {\n const ids = await adapter.list(vault, collection)\n for (const id of ids) {\n if (id.startsWith('_')) continue\n const env = await adapter.get(vault, collection, id)\n if (!env || !env._data) continue // missing or tombstone\n const record = await decodeRecord(collection, id, env)\n if (record === null) continue\n const subjectValue = readDottedPath(record, field)\n if (subjectValue === undefined || subjectValue === null) continue\n const subjectId = coerceSubjectId(subjectValue)\n const list = bySubject.get(subjectId) ?? []\n list.push({ collection, id })\n bySubject.set(subjectId, list)\n }\n }\n\n let entries = 0\n for (const [subjectId, refs] of bySubject) {\n const key = await primarySubjectKey(getDEK, encrypted, subjectId)\n await writeRefs(adapter, vault, getDEK, encrypted, key, refs)\n entries++\n }\n return entries\n}\n\n/**\n * Coerce a read subject-field value to a stable string id. Primitives use\n * their natural string form; objects/arrays are JSON-stringified so structural\n * subjects still get a deterministic key (avoids the `[object Object]` trap).\n */\nexport function coerceSubjectId(value: unknown): string {\n if (typeof value === 'string') return value\n if (typeof value === 'number' || typeof value === 'boolean' || typeof value === 'bigint') {\n return String(value)\n }\n return JSON.stringify(value)\n}\n\n/** Read a (possibly dotted) field path from a plain record. */\nexport function readDottedPath(record: Record<string, unknown>, field: string): unknown {\n if (!field.includes('.')) return record[field]\n let cursor: unknown = record\n for (const segment of field.split('.')) {\n if (cursor === null || cursor === undefined) return undefined\n cursor = (cursor as Record<string, unknown>)[segment]\n }\n return cursor\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AttestationNotEnabledError
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-BIOUI4HL.js";
|
|
4
4
|
|
|
5
5
|
// src/with-audit/attestation/strategy.ts
|
|
6
6
|
var NO_ATTESTATION = {
|
|
@@ -27,4 +27,4 @@ var NO_ATTESTATION = {
|
|
|
27
27
|
export {
|
|
28
28
|
NO_ATTESTATION
|
|
29
29
|
};
|
|
30
|
-
//# sourceMappingURL=chunk-
|
|
30
|
+
//# sourceMappingURL=chunk-5YOLBEQ6.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ValidationError
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-BIOUI4HL.js";
|
|
4
4
|
|
|
5
5
|
// src/with-formula/derivations/with-derivation.ts
|
|
6
6
|
function withDerivation(spec) {
|
|
@@ -126,4 +126,4 @@ export {
|
|
|
126
126
|
withDerivation,
|
|
127
127
|
withRollup
|
|
128
128
|
};
|
|
129
|
-
//# sourceMappingURL=chunk-
|
|
129
|
+
//# sourceMappingURL=chunk-6CRIV7DE.js.map
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
installViaBinder
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-4VNQOLML.js";
|
|
4
4
|
import {
|
|
5
5
|
LocaleNotSpecifiedError,
|
|
6
6
|
MissingTranslationError,
|
|
7
7
|
ScriptViolationError,
|
|
8
8
|
TranslatorNotConfiguredError
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-BIOUI4HL.js";
|
|
10
10
|
|
|
11
11
|
// src/port/with/i18n-strategy.ts
|
|
12
12
|
function notEnabled(op) {
|
|
@@ -618,4 +618,4 @@ export {
|
|
|
618
618
|
presentI18nForJoin,
|
|
619
619
|
stripI18nFilled
|
|
620
620
|
};
|
|
621
|
-
//# sourceMappingURL=chunk-
|
|
621
|
+
//# sourceMappingURL=chunk-6JTIAGHD.js.map
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
hasExportCapability,
|
|
3
3
|
hasImportCapability
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-J2ZX2XUV.js";
|
|
5
5
|
import {
|
|
6
6
|
ExportCapabilityError,
|
|
7
7
|
ImportCapabilityError
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-BIOUI4HL.js";
|
|
9
9
|
|
|
10
10
|
// src/port/with/capabilities.ts
|
|
11
11
|
function assertCanExport(keyring, tier, format) {
|
|
@@ -252,4 +252,4 @@ export {
|
|
|
252
252
|
ServiceBus,
|
|
253
253
|
SubsystemBus
|
|
254
254
|
};
|
|
255
|
-
//# sourceMappingURL=chunk-
|
|
255
|
+
//# sourceMappingURL=chunk-6QTNZJBS.js.map
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
grant,
|
|
3
3
|
revoke
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-J2ZX2XUV.js";
|
|
5
5
|
import {
|
|
6
6
|
CargoNotEnabledError,
|
|
7
7
|
CustodyNotEnabledError
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-BIOUI4HL.js";
|
|
9
9
|
|
|
10
10
|
// src/with-cargo/strategy.ts
|
|
11
11
|
var NO_CARGO = {
|
|
@@ -24,7 +24,7 @@ function withCustody() {
|
|
|
24
24
|
return host._revokeCustodianImpl(revoke, vault, options, factors);
|
|
25
25
|
},
|
|
26
26
|
async liberate(vault, opts) {
|
|
27
|
-
const { liberateVault } = await import("./liberate-
|
|
27
|
+
const { liberateVault } = await import("./liberate-3VDOT4KO.js");
|
|
28
28
|
return liberateVault(vault, opts);
|
|
29
29
|
}
|
|
30
30
|
};
|
|
@@ -83,4 +83,4 @@ export {
|
|
|
83
83
|
NO_CUSTODY,
|
|
84
84
|
CustodyApi
|
|
85
85
|
};
|
|
86
|
-
//# sourceMappingURL=chunk-
|
|
86
|
+
//# sourceMappingURL=chunk-6T2SCQRU.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
NOYDB_FORMAT_VERSION
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-JNAI2HN2.js";
|
|
4
4
|
|
|
5
5
|
// src/kernel/enclave/record-keys/tombstone.ts
|
|
6
6
|
function isTombstoneShape(envelope) {
|
|
@@ -42,4 +42,4 @@ export {
|
|
|
42
42
|
isDeleteMarker,
|
|
43
43
|
buildDeleteMarker
|
|
44
44
|
};
|
|
45
|
-
//# sourceMappingURL=chunk-
|
|
45
|
+
//# sourceMappingURL=chunk-7DSTRQIJ.js.map
|
|
@@ -4,18 +4,18 @@ import {
|
|
|
4
4
|
loadShamirRecoveryEntries,
|
|
5
5
|
unwrapDeksFromPaperEntry,
|
|
6
6
|
unwrapDeksFromShamirEntry
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import {
|
|
9
|
-
dekKey
|
|
10
|
-
} from "./chunk-4R4Q64W5.js";
|
|
7
|
+
} from "./chunk-EVVGJDRQ.js";
|
|
11
8
|
import {
|
|
12
9
|
assertStrongPassphrase,
|
|
13
10
|
mintKeyringCanary,
|
|
14
11
|
persistKeyring
|
|
15
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-J2ZX2XUV.js";
|
|
13
|
+
import {
|
|
14
|
+
dekKey
|
|
15
|
+
} from "./chunk-ZICD77GM.js";
|
|
16
16
|
import {
|
|
17
17
|
openEnvelopeJson
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-XDYREZWE.js";
|
|
19
19
|
import {
|
|
20
20
|
base64ToBuffer,
|
|
21
21
|
bufferToBase64,
|
|
@@ -24,10 +24,10 @@ import {
|
|
|
24
24
|
generateSalt,
|
|
25
25
|
unwrapKey,
|
|
26
26
|
wrapKey
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-CIE2BASH.js";
|
|
28
28
|
import {
|
|
29
29
|
NOYDB_KEYRING_VERSION
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-JNAI2HN2.js";
|
|
31
31
|
import {
|
|
32
32
|
DelegationTargetMissingError,
|
|
33
33
|
InvalidKeyError,
|
|
@@ -37,7 +37,7 @@ import {
|
|
|
37
37
|
RecoveryProfileNotImplementedError,
|
|
38
38
|
TeamNotEnabledError,
|
|
39
39
|
ValidationError
|
|
40
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-BIOUI4HL.js";
|
|
41
41
|
|
|
42
42
|
// src/with-party/team/magic-link-grant.ts
|
|
43
43
|
var MAGIC_LINK_GRANTS_COLLECTION = "_magic_link_grants";
|
|
@@ -586,4 +586,4 @@ export {
|
|
|
586
586
|
removeAuthenticator,
|
|
587
587
|
findAuthenticator
|
|
588
588
|
};
|
|
589
|
-
//# sourceMappingURL=chunk-
|
|
589
|
+
//# sourceMappingURL=chunk-AUSTCW2X.js.map
|