@noy-db/hub 0.7.0-pre.9 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1319 -0
- package/README.md +7 -6
- package/dist/api-TXFOVOXX.js +19 -0
- package/dist/as/index.js +14 -14
- package/dist/at/index.js +9 -10
- package/dist/attestation/index.js +18 -19
- package/dist/attestation/index.js.map +1 -1
- package/dist/{backup-QZQEP5RO.js → backup-IJTB4S4M.js} +14 -15
- package/dist/{backup-QZQEP5RO.js.map → backup-IJTB4S4M.js.map} +1 -1
- package/dist/blobs/index.js +13 -14
- package/dist/blobs/index.js.map +1 -1
- package/dist/broker/index.js +12 -13
- package/dist/broker/index.js.map +1 -1
- package/dist/by/index.js +2 -3
- package/dist/cargo/index.js +33 -34
- package/dist/{chunk-5UKIZIO3.js → chunk-2577DKXB.js} +2 -2
- package/dist/chunk-2C3AQB46.js +1652 -0
- package/dist/chunk-2C3AQB46.js.map +1 -0
- package/dist/{chunk-LUVGSKXE.js → chunk-2N4GY74U.js} +6 -6
- package/dist/{chunk-I5LSKXT6.js → chunk-2Y4IMKA6.js} +4 -4
- package/dist/{chunk-7XT7KZTN.js → chunk-3RCJJBNR.js} +10 -10
- package/dist/{chunk-GM4IM7TC.js → chunk-453F654R.js} +2 -2
- package/dist/{chunk-JUBWUJY5.js → chunk-4GVM6QZA.js} +2 -2
- package/dist/{chunk-2DGBRE4K.js → chunk-4OZNXTO4.js} +2 -2
- package/dist/{chunk-P2RJAVMR.js → chunk-5VCRVKOZ.js} +4 -4
- package/dist/{chunk-RCONOOVF.js → chunk-5WDXHNSW.js} +5 -5
- package/dist/chunk-66TQOPFM.js +37 -0
- package/dist/chunk-66TQOPFM.js.map +1 -0
- package/dist/{chunk-Q2OAAREU.js → chunk-6GMZ7HEE.js} +6 -6
- package/dist/{chunk-6L5IMNJX.js → chunk-6GOE5PGN.js} +168 -1328
- package/dist/chunk-6GOE5PGN.js.map +1 -0
- package/dist/{chunk-TQGT5BZE.js → chunk-6I2RQCET.js} +4 -4
- package/dist/{chunk-UL7TLJ54.js → chunk-6X6SEMEE.js} +6 -4
- package/dist/{chunk-UL7TLJ54.js.map → chunk-6X6SEMEE.js.map} +1 -1
- package/dist/{chunk-P7KJME6C.js → chunk-6YXCPL4T.js} +2 -2
- package/dist/{chunk-DOPZWTMJ.js → chunk-77K4PG6P.js} +8 -8
- package/dist/{chunk-LAI7ENPW.js → chunk-7MG2LHO5.js} +3 -3
- package/dist/{chunk-N4CHCXDL.js → chunk-7MG7SJT7.js} +1 -1
- package/dist/{chunk-N4CHCXDL.js.map → chunk-7MG7SJT7.js.map} +1 -1
- package/dist/{chunk-SW4TOSJL.js → chunk-7O3Y4PPD.js} +1 -1
- package/dist/chunk-7O3Y4PPD.js.map +1 -0
- package/dist/{chunk-HOIWW2LV.js → chunk-7V4TP3AF.js} +4 -4
- package/dist/{chunk-GKOJR53Y.js → chunk-ANATMFIO.js} +5 -5
- package/dist/{chunk-MU74BYOD.js → chunk-ANSIZYEG.js} +3 -3
- package/dist/{chunk-IS5LFHV2.js → chunk-AO42KJO6.js} +7 -7
- package/dist/{chunk-RPX2H2OL.js → chunk-BLN54W3L.js} +3 -3
- package/dist/{chunk-HS3LEVT4.js → chunk-BM5TWITZ.js} +7 -7
- package/dist/{chunk-JRWLUWDM.js → chunk-BOET4NA4.js} +3 -3
- package/dist/{chunk-XGXVPCYW.js → chunk-BOWNCWZT.js} +3 -3
- package/dist/{chunk-5EC7X5QA.js → chunk-BSFNRLK2.js} +5 -5
- package/dist/{chunk-65ZYRK7O.js → chunk-BUE2D7PX.js} +26 -3
- package/dist/chunk-BUE2D7PX.js.map +1 -0
- package/dist/{chunk-UTFY6W6X.js → chunk-BZ3534YM.js} +2 -2
- package/dist/chunk-CARABLSQ.js +176 -0
- package/dist/chunk-CARABLSQ.js.map +1 -0
- package/dist/{chunk-HLFLJCDX.js → chunk-CHJBLCOG.js} +7 -7
- package/dist/{chunk-OLUTCM23.js → chunk-CPWQB3N5.js} +7 -7
- package/dist/{chunk-3GIA3HJ2.js → chunk-DGOZ4UZD.js} +2 -2
- package/dist/{chunk-FPN5D4JX.js → chunk-ELNXJMGB.js} +6 -6
- package/dist/{chunk-NMDMSHBF.js → chunk-EQEYOJBM.js} +3 -3
- package/dist/{chunk-RHTPGS56.js → chunk-EYBQEIUY.js} +3 -3
- package/dist/{chunk-Q2ZN5DWZ.js → chunk-FAHMLERK.js} +2 -2
- package/dist/chunk-FFWI7UH7.js +53 -0
- package/dist/chunk-FFWI7UH7.js.map +1 -0
- package/dist/{chunk-MENI33ZV.js → chunk-FMZY5Q6L.js} +3 -3
- package/dist/{chunk-FZWAGG5T.js → chunk-FXBIP2WD.js} +6 -6
- package/dist/{chunk-OHGCRKWA.js → chunk-G56KBWFY.js} +18 -8
- package/dist/{chunk-OHGCRKWA.js.map → chunk-G56KBWFY.js.map} +1 -1
- package/dist/{chunk-K432FT7T.js → chunk-GPEQUXHL.js} +4 -4
- package/dist/{chunk-DNMTN46H.js → chunk-GY4WYNNG.js} +2 -2
- package/dist/{chunk-OQDHIAR2.js → chunk-HDOU6I2Y.js} +80 -8
- package/dist/chunk-HDOU6I2Y.js.map +1 -0
- package/dist/{chunk-MQPHKJ74.js → chunk-J6FXAEUG.js} +12 -12
- package/dist/{chunk-PV7XXAXK.js → chunk-JBDFMYKQ.js} +2 -2
- package/dist/{chunk-IZTU6RKH.js → chunk-JMGDHKQF.js} +2 -2
- package/dist/{chunk-AHIIBDNH.js → chunk-K6LHRFBL.js} +7 -7
- package/dist/{chunk-FN26SFGH.js → chunk-K7NTTA6P.js} +2 -2
- package/dist/{chunk-MV2OEK3K.js → chunk-KG7TZKZG.js} +5 -5
- package/dist/{chunk-5NKHCJU5.js → chunk-KJIMGIWO.js} +8 -8
- package/dist/{chunk-ZB2K3FV7.js → chunk-KTFRCC5C.js} +2 -2
- package/dist/{chunk-X6YRP5EC.js → chunk-KUJDV5QH.js} +5 -5
- package/dist/{chunk-PCIBCL26.js → chunk-KUX3OB6D.js} +7 -5
- package/dist/{chunk-PCIBCL26.js.map → chunk-KUX3OB6D.js.map} +1 -1
- package/dist/{chunk-OKCQNMO6.js → chunk-L742JPKZ.js} +6 -6
- package/dist/{chunk-P22XPNFW.js → chunk-L7CIOOBW.js} +2 -2
- package/dist/{chunk-QOHGWFAW.js → chunk-LWBCUYZW.js} +2 -2
- package/dist/{chunk-357ECVLE.js → chunk-MUM7IANK.js} +3 -3
- package/dist/{chunk-JFSUYGNE.js → chunk-MVMXZYXT.js} +2 -2
- package/dist/{chunk-3SWP2FYA.js → chunk-NA2NIJZI.js} +8 -8
- package/dist/{chunk-MOQ6OGKS.js → chunk-NKHRDYOR.js} +4 -4
- package/dist/{chunk-FKQCC4C5.js → chunk-NQKIUNW5.js} +2 -2
- package/dist/{chunk-SWFIXQF5.js → chunk-PT43Y56J.js} +6 -6
- package/dist/{chunk-MTTPHBIE.js → chunk-Q2PU57HC.js} +2 -2
- package/dist/{chunk-FLRLZ4XZ.js → chunk-Q7HZX3IF.js} +2 -2
- package/dist/{chunk-75WNTBZL.js → chunk-QIBVIOXO.js} +3 -3
- package/dist/{chunk-KQIDBIZL.js → chunk-QIZPZMUI.js} +2 -2
- package/dist/{chunk-VT4DTCK5.js → chunk-REDOOY2Q.js} +3 -3
- package/dist/chunk-REDOOY2Q.js.map +1 -0
- package/dist/{chunk-KZTPL7NL.js → chunk-RMF67KCG.js} +2 -2
- package/dist/{chunk-OEJ4R52I.js → chunk-RMS3NEA3.js} +2 -2
- package/dist/{chunk-VTTDPGEK.js → chunk-RRNRNANG.js} +9 -9
- package/dist/chunk-RTBJ5IOO.js +87 -0
- package/dist/chunk-RTBJ5IOO.js.map +1 -0
- package/dist/chunk-RXLYKVTF.js +17 -0
- package/dist/chunk-RXLYKVTF.js.map +1 -0
- package/dist/{chunk-XKA6UH5V.js → chunk-SFAWCTEM.js} +2 -2
- package/dist/{chunk-FYT3DXPN.js → chunk-SKGMN35F.js} +2 -2
- package/dist/{chunk-USKHHOIV.js → chunk-SL3JAAKN.js} +2 -2
- package/dist/chunk-SMH6SRX7.js +87 -0
- package/dist/chunk-SMH6SRX7.js.map +1 -0
- package/dist/{chunk-QJLOWGOU.js → chunk-SPXXX5E4.js} +12 -82
- package/dist/chunk-SPXXX5E4.js.map +1 -0
- package/dist/{chunk-JILOSL4O.js → chunk-SPYWXKJN.js} +3 -3
- package/dist/{chunk-4RUFYGWG.js → chunk-SZJ3DLZA.js} +2 -2
- package/dist/chunk-TFMM5DBB.js +20 -0
- package/dist/chunk-TFMM5DBB.js.map +1 -0
- package/dist/{chunk-O3SNM66K.js → chunk-TFR7DSOV.js} +2 -2
- package/dist/{chunk-DIVY2CJZ.js → chunk-TRGTKX5E.js} +3 -3
- package/dist/{chunk-JY4U6CYV.js → chunk-TUFM4UZP.js} +2 -2
- package/dist/{chunk-FRIVOR5N.js → chunk-U4FOQDY4.js} +5 -172
- package/dist/chunk-U4FOQDY4.js.map +1 -0
- package/dist/{chunk-DZPMKY3J.js → chunk-UGTBXF5U.js} +3 -3
- package/dist/{chunk-THNJ3IKU.js → chunk-ULUMAZ5S.js} +2 -2
- package/dist/{chunk-YHIAWECL.js → chunk-UXVWEX5L.js} +2 -2
- package/dist/{chunk-IAHDSFFA.js → chunk-UXWB3FPF.js} +10 -10
- package/dist/{chunk-NO272T7Q.js → chunk-V4PXLYWM.js} +2 -31
- package/dist/chunk-V4PXLYWM.js.map +1 -0
- package/dist/{chunk-GHADG5QZ.js → chunk-VTFVLCUH.js} +2 -2
- package/dist/{chunk-U3RMWOXY.js → chunk-VXANTWBJ.js} +3 -3
- package/dist/{chunk-5W5CEHLA.js → chunk-VXGSWL6L.js} +6 -6
- package/dist/{chunk-KHKKD62N.js → chunk-VYYM3MEN.js} +2 -16
- package/dist/chunk-VYYM3MEN.js.map +1 -0
- package/dist/{chunk-7YVSWPZB.js → chunk-WEQEYLCS.js} +7 -7
- package/dist/{chunk-TAJZ7GXO.js → chunk-X2DLENDQ.js} +3 -3
- package/dist/{chunk-2E2LT37H.js → chunk-XLMEZIAJ.js} +2 -2
- package/dist/{chunk-2MQ2D5OZ.js → chunk-XTXOCYOJ.js} +5 -5
- package/dist/{chunk-CWFH36SI.js → chunk-YSRUYAVU.js} +2 -2
- package/dist/{chunk-ZQGRZN5L.js → chunk-YYP7WSEB.js} +2 -2
- package/dist/{chunk-4U52PMEL.js → chunk-ZN4FD4PE.js} +4 -4
- package/dist/{chunk-AW4KTQA4.js → chunk-ZORTV6NH.js} +2 -2
- package/dist/{chunk-H5GVPOB4.js → chunk-ZVO4QVPD.js} +5 -5
- package/dist/classified/index.js +5 -6
- package/dist/{classified-marker-R37XW5PC.js → classified-marker-LI2SF2E4.js} +3 -5
- package/dist/{classified-marker-R37XW5PC.js.map → classified-marker-LI2SF2E4.js.map} +1 -1
- package/dist/collection-facade-4GRREZ6C.js +45 -0
- package/dist/computed-VPOKQK4N.js +10 -0
- package/dist/consent/index.js +9 -10
- package/dist/consent/index.js.map +1 -1
- package/dist/cover/index.js +9 -10
- package/dist/crdt/index.js +0 -1
- package/dist/crdt/index.js.map +1 -1
- package/dist/custody/index.js +12 -13
- package/dist/{dead-filter-GRT6RAML.js → dead-filter-TSWZQRR5.js} +2 -3
- package/dist/{dead-filter-GRT6RAML.js.map → dead-filter-TSWZQRR5.js.map} +1 -1
- package/dist/debug/index.js +1 -2
- package/dist/debug/index.js.map +1 -1
- package/dist/{delegation-6QRAYSK6.js → delegation-OVIFFPG4.js} +11 -12
- package/dist/{delegation-6QRAYSK6.js.map → delegation-OVIFFPG4.js.map} +1 -1
- package/dist/derivations/index.js +30 -16
- package/dist/derive-6O5SWQKN.js +21 -0
- package/dist/directory/index.js +10 -11
- package/dist/dispatch-S73TK3IY.js +302 -0
- package/dist/dispatch-S73TK3IY.js.map +1 -0
- package/dist/{dispatch-QCF7KPIP.js → dispatch-WC6X2M6C.js} +5 -7
- package/dist/{dispatch-QCF7KPIP.js.map → dispatch-WC6X2M6C.js.map} +1 -1
- package/dist/{enclave-OXZY3NOP.js → enclave-KJOTOH7X.js} +9 -10
- package/dist/executor-5NIMLSKZ.js +8 -0
- package/dist/executor-AQVXV5GZ.js +8 -0
- package/dist/executor-PUAO6AKJ.js +29 -0
- package/dist/export-accessible-72EQNBMR.js +22 -0
- package/dist/extract-partition-PUYNU3UF.js +37 -0
- package/dist/{fanout-sidecar-KGQCUJ7P.js → fanout-sidecar-WUFXNYP4.js} +9 -10
- package/dist/{fanout-sidecar-KGQCUJ7P.js.map → fanout-sidecar-WUFXNYP4.js.map} +1 -1
- package/dist/{fence-watcher-ZVSMLKQD.js → fence-watcher-U2PW6JU5.js} +1 -3
- package/dist/{fence-watcher-ZVSMLKQD.js.map → fence-watcher-U2PW6JU5.js.map} +1 -1
- package/dist/find-2ABFCZX4.js +10 -0
- package/dist/forget/index.js +9 -10
- package/dist/forget/index.js.map +1 -1
- package/dist/guards/index.js +4 -5
- package/dist/history/index.js +13 -14
- package/dist/history/index.js.map +1 -1
- package/dist/i18n/index.js +14 -15
- package/dist/i18n/index.js.map +1 -1
- package/dist/index.d.ts +20 -4
- package/dist/index.js +122 -115
- package/dist/index.js.map +1 -1
- package/dist/indexing/index.js +2 -3
- package/dist/indexing/index.js.map +1 -1
- package/dist/introspection/index.js +13 -13
- package/dist/issue-SIDORTSZ.js +18 -0
- package/dist/{json-schema-I22JCYCG.js → json-schema-V3M5MUCM.js} +1 -3
- package/dist/{json-schema-I22JCYCG.js.map → json-schema-V3M5MUCM.js.map} +1 -1
- package/dist/kernel/collection-config.d.ts +34 -0
- package/dist/kernel/collection.d.ts +11 -6
- package/dist/kernel/errors.d.ts +28 -0
- package/dist/kernel/match-pairs.d.ts +30 -0
- package/dist/kernel/types.d.ts +39 -0
- package/dist/lazy/index.js +3 -3
- package/dist/{ledger-ZAFULLAF.js → ledger-F33ZVMTK.js} +11 -12
- package/dist/liberate-LCDPNAG2.js +24 -0
- package/dist/link-set-FKNWAYKS.js +30 -0
- package/dist/{managed-secret-7OH7HKXV.js → managed-secret-PQYKSR6T.js} +10 -11
- package/dist/materialized-views/index.js +21 -21
- package/dist/{migrate-cek-QHZ75E6E.js → migrate-cek-5ENH64AA.js} +2 -3
- package/dist/{migrate-cek-QHZ75E6E.js.map → migrate-cek-5ENH64AA.js.map} +1 -1
- package/dist/money/index.js +4 -5
- package/dist/noydb-DUXZPKSN.js +90 -0
- package/dist/overlay-views/index.js +4 -5
- package/dist/periods/index.js +12 -13
- package/dist/pod/index.js +64 -60
- package/dist/{pod-handle-BLOI4IFY.js → pod-handle-Q736KYON.js} +10 -11
- package/dist/{pod-handle-BLOI4IFY.js.map → pod-handle-Q736KYON.js.map} +1 -1
- package/dist/policy/index.js +10 -11
- package/dist/port/to/index.d.ts +40 -0
- package/dist/portability/index.js +8 -9
- package/dist/portability/index.js.map +1 -1
- package/dist/{post-register-R33EKJQR.js → post-register-LNE2FE2A.js} +6 -7
- package/dist/{post-register-R33EKJQR.js.map → post-register-LNE2FE2A.js.map} +1 -1
- package/dist/{purge-scope-FGNNLWHD.js → purge-scope-4HEFPDOW.js} +1 -3
- package/dist/{purge-scope-FGNNLWHD.js.map → purge-scope-4HEFPDOW.js.map} +1 -1
- package/dist/query/index.js +3 -4
- package/dist/{read-only-facade-CHCKSEPD.js → read-only-facade-BIGO37U3.js} +1 -2
- package/dist/reduce/index.js +4 -5
- package/dist/reduce/index.js.map +1 -1
- package/dist/register-I2DZXGAR.js +31 -0
- package/dist/registry-23WF3TGH.js +8 -0
- package/dist/registry-4AYVUNXK.js +8 -0
- package/dist/registry-VSSQPIGF.js +18 -0
- package/dist/registry-YLEWMGAC.js +32 -0
- package/dist/request-withdrawal-KFQHEZ25.js +30 -0
- package/dist/{reveal-PI6ADRQU.js → reveal-67RDQRIN.js} +6 -7
- package/dist/{reveal-PI6ADRQU.js.map → reveal-67RDQRIN.js.map} +1 -1
- package/dist/revoke-DQDZAZZM.js +23 -0
- package/dist/satellites/index.js +1 -2
- package/dist/schema-update/index.js +2 -3
- package/dist/sealed-record/index.js +12 -13
- package/dist/sealed-record/index.js.map +1 -1
- package/dist/search/index.js +4 -5
- package/dist/{seed-CG7JMJNY.js → seed-G42JYN56.js} +12 -13
- package/dist/{seed-CG7JMJNY.js.map → seed-G42JYN56.js.map} +1 -1
- package/dist/sequence/index.js +9 -10
- package/dist/session/index.js +9 -10
- package/dist/session/index.js.map +1 -1
- package/dist/shadow/index.js +2 -3
- package/dist/shadow/index.js.map +1 -1
- package/dist/share-link/index.js +0 -1
- package/dist/share-link/index.js.map +1 -1
- package/dist/signer-WAMDZHEN.js +24 -0
- package/dist/snapshots/index.js +10 -11
- package/dist/snapshots/index.js.map +1 -1
- package/dist/{stale-HZR7745Y.js → stale-DDL7WQEZ.js} +10 -11
- package/dist/storage-FLR73HHF.js +22 -0
- package/dist/store/index.js +0 -1
- package/dist/{store-coordination-provider-MYIHSZXT.js → store-coordination-provider-MEQ2MJQG.js} +10 -11
- package/dist/{store-coordination-provider-MYIHSZXT.js.map → store-coordination-provider-MEQ2MJQG.js.map} +1 -1
- package/dist/sync/index.js +10 -11
- package/dist/sync/index.js.map +1 -1
- package/dist/team/index.js +15 -16
- package/dist/tiers/index.js +11 -12
- package/dist/to/index.js +2 -3
- package/dist/to/index.js.map +1 -1
- package/dist/transactions/index.js +3 -4
- package/dist/transactions/index.js.map +1 -1
- package/dist/{ulid-VQW6ERQN.js → ulid-4MKXG325.js} +1 -2
- package/dist/util/index.js +1 -2
- package/dist/util/index.js.map +1 -1
- package/dist/{vault-diff-FE5J35NJ.js → vault-diff-C6WUJFNP.js} +1 -2
- package/dist/vault-head/index.js +8 -9
- package/dist/vault-head/index.js.map +1 -1
- package/dist/{verify-R6CCBUA3.js → verify-KOV2G5D6.js} +5 -6
- package/dist/{verify-R6CCBUA3.js.map → verify-KOV2G5D6.js.map} +1 -1
- package/dist/walk-3UQBRMDV.js +21 -0
- package/dist/with-formula/derivations/dispatch.d.ts +16 -1
- package/dist/with-formula/derivations/registry.d.ts +20 -0
- package/dist/with-formula/derivations/trigger-match.d.ts +104 -0
- package/dist/with-formula/derivations/types.d.ts +61 -0
- package/dist/with-shape/introspection/behaviors.d.ts +7 -0
- package/dist/with-shape/introspection/describe.d.ts +10 -1
- package/dist/with-shape/introspection/field-meta.d.ts +86 -0
- package/dist/withdraw-accessible-EL5GXZBS.js +27 -0
- package/package.json +8 -3
- package/dist/api-GJQF7OAJ.js +0 -20
- package/dist/chunk-65ZYRK7O.js.map +0 -1
- package/dist/chunk-6L5IMNJX.js.map +0 -1
- package/dist/chunk-FRIVOR5N.js.map +0 -1
- package/dist/chunk-J6FXVDKC.js +0 -81
- package/dist/chunk-J6FXVDKC.js.map +0 -1
- package/dist/chunk-KHKKD62N.js.map +0 -1
- package/dist/chunk-NO272T7Q.js.map +0 -1
- package/dist/chunk-OQDHIAR2.js.map +0 -1
- package/dist/chunk-PZ5AY32C.js +0 -10
- package/dist/chunk-QJLOWGOU.js.map +0 -1
- package/dist/chunk-SW4TOSJL.js.map +0 -1
- package/dist/chunk-VT4DTCK5.js.map +0 -1
- package/dist/chunk-XJP66QEN.js +0 -344
- package/dist/chunk-XJP66QEN.js.map +0 -1
- package/dist/collection-facade-OPJ3EC4L.js +0 -45
- package/dist/computed-HW6IG5UH.js +0 -11
- package/dist/derive-AAIXSQIE.js +0 -22
- package/dist/dispatch-DR3XITEC.js +0 -194
- package/dist/dispatch-DR3XITEC.js.map +0 -1
- package/dist/executor-67NA4KPO.js +0 -29
- package/dist/executor-7JDP7UBK.js +0 -9
- package/dist/executor-CRH5OB4V.js +0 -9
- package/dist/export-accessible-K4GJAU7U.js +0 -23
- package/dist/extract-partition-YJFL5OKK.js +0 -38
- package/dist/find-SVZHMEQI.js +0 -11
- package/dist/issue-64N6OG7U.js +0 -19
- package/dist/liberate-XL6NSGOL.js +0 -25
- package/dist/link-set-LQI2IJX6.js +0 -31
- package/dist/noydb-SWUGPFBK.js +0 -86
- package/dist/register-AYBQNTM3.js +0 -32
- package/dist/registry-CQWWOBO4.js +0 -9
- package/dist/registry-JCZ4BNLV.js +0 -18
- package/dist/registry-JFFENZ44.js +0 -9
- package/dist/registry-ZA4HACYR.js +0 -19
- package/dist/request-withdrawal-7IKUIAEB.js +0 -31
- package/dist/revoke-PUJKRYJF.js +0 -24
- package/dist/signer-5TA7FUC3.js +0 -25
- package/dist/storage-J2QHNJCB.js +0 -23
- package/dist/walk-3PA4ZOKS.js +0 -21
- package/dist/withdraw-accessible-62VI4W7D.js +0 -28
- package/dist/withdraw-accessible-62VI4W7D.js.map +0 -1
- package/dist/zod-HAJM7LMS.js +0 -14763
- package/dist/zod-HAJM7LMS.js.map +0 -1
- /package/dist/{api-GJQF7OAJ.js.map → api-TXFOVOXX.js.map} +0 -0
- /package/dist/{chunk-5UKIZIO3.js.map → chunk-2577DKXB.js.map} +0 -0
- /package/dist/{chunk-LUVGSKXE.js.map → chunk-2N4GY74U.js.map} +0 -0
- /package/dist/{chunk-I5LSKXT6.js.map → chunk-2Y4IMKA6.js.map} +0 -0
- /package/dist/{chunk-7XT7KZTN.js.map → chunk-3RCJJBNR.js.map} +0 -0
- /package/dist/{chunk-GM4IM7TC.js.map → chunk-453F654R.js.map} +0 -0
- /package/dist/{chunk-JUBWUJY5.js.map → chunk-4GVM6QZA.js.map} +0 -0
- /package/dist/{chunk-2DGBRE4K.js.map → chunk-4OZNXTO4.js.map} +0 -0
- /package/dist/{chunk-P2RJAVMR.js.map → chunk-5VCRVKOZ.js.map} +0 -0
- /package/dist/{chunk-RCONOOVF.js.map → chunk-5WDXHNSW.js.map} +0 -0
- /package/dist/{chunk-Q2OAAREU.js.map → chunk-6GMZ7HEE.js.map} +0 -0
- /package/dist/{chunk-TQGT5BZE.js.map → chunk-6I2RQCET.js.map} +0 -0
- /package/dist/{chunk-P7KJME6C.js.map → chunk-6YXCPL4T.js.map} +0 -0
- /package/dist/{chunk-DOPZWTMJ.js.map → chunk-77K4PG6P.js.map} +0 -0
- /package/dist/{chunk-LAI7ENPW.js.map → chunk-7MG2LHO5.js.map} +0 -0
- /package/dist/{chunk-HOIWW2LV.js.map → chunk-7V4TP3AF.js.map} +0 -0
- /package/dist/{chunk-GKOJR53Y.js.map → chunk-ANATMFIO.js.map} +0 -0
- /package/dist/{chunk-MU74BYOD.js.map → chunk-ANSIZYEG.js.map} +0 -0
- /package/dist/{chunk-IS5LFHV2.js.map → chunk-AO42KJO6.js.map} +0 -0
- /package/dist/{chunk-RPX2H2OL.js.map → chunk-BLN54W3L.js.map} +0 -0
- /package/dist/{chunk-HS3LEVT4.js.map → chunk-BM5TWITZ.js.map} +0 -0
- /package/dist/{chunk-JRWLUWDM.js.map → chunk-BOET4NA4.js.map} +0 -0
- /package/dist/{chunk-XGXVPCYW.js.map → chunk-BOWNCWZT.js.map} +0 -0
- /package/dist/{chunk-5EC7X5QA.js.map → chunk-BSFNRLK2.js.map} +0 -0
- /package/dist/{chunk-UTFY6W6X.js.map → chunk-BZ3534YM.js.map} +0 -0
- /package/dist/{chunk-HLFLJCDX.js.map → chunk-CHJBLCOG.js.map} +0 -0
- /package/dist/{chunk-OLUTCM23.js.map → chunk-CPWQB3N5.js.map} +0 -0
- /package/dist/{chunk-3GIA3HJ2.js.map → chunk-DGOZ4UZD.js.map} +0 -0
- /package/dist/{chunk-FPN5D4JX.js.map → chunk-ELNXJMGB.js.map} +0 -0
- /package/dist/{chunk-NMDMSHBF.js.map → chunk-EQEYOJBM.js.map} +0 -0
- /package/dist/{chunk-RHTPGS56.js.map → chunk-EYBQEIUY.js.map} +0 -0
- /package/dist/{chunk-Q2ZN5DWZ.js.map → chunk-FAHMLERK.js.map} +0 -0
- /package/dist/{chunk-MENI33ZV.js.map → chunk-FMZY5Q6L.js.map} +0 -0
- /package/dist/{chunk-FZWAGG5T.js.map → chunk-FXBIP2WD.js.map} +0 -0
- /package/dist/{chunk-K432FT7T.js.map → chunk-GPEQUXHL.js.map} +0 -0
- /package/dist/{chunk-DNMTN46H.js.map → chunk-GY4WYNNG.js.map} +0 -0
- /package/dist/{chunk-MQPHKJ74.js.map → chunk-J6FXAEUG.js.map} +0 -0
- /package/dist/{chunk-PV7XXAXK.js.map → chunk-JBDFMYKQ.js.map} +0 -0
- /package/dist/{chunk-IZTU6RKH.js.map → chunk-JMGDHKQF.js.map} +0 -0
- /package/dist/{chunk-AHIIBDNH.js.map → chunk-K6LHRFBL.js.map} +0 -0
- /package/dist/{chunk-FN26SFGH.js.map → chunk-K7NTTA6P.js.map} +0 -0
- /package/dist/{chunk-MV2OEK3K.js.map → chunk-KG7TZKZG.js.map} +0 -0
- /package/dist/{chunk-5NKHCJU5.js.map → chunk-KJIMGIWO.js.map} +0 -0
- /package/dist/{chunk-ZB2K3FV7.js.map → chunk-KTFRCC5C.js.map} +0 -0
- /package/dist/{chunk-X6YRP5EC.js.map → chunk-KUJDV5QH.js.map} +0 -0
- /package/dist/{chunk-OKCQNMO6.js.map → chunk-L742JPKZ.js.map} +0 -0
- /package/dist/{chunk-P22XPNFW.js.map → chunk-L7CIOOBW.js.map} +0 -0
- /package/dist/{chunk-QOHGWFAW.js.map → chunk-LWBCUYZW.js.map} +0 -0
- /package/dist/{chunk-357ECVLE.js.map → chunk-MUM7IANK.js.map} +0 -0
- /package/dist/{chunk-JFSUYGNE.js.map → chunk-MVMXZYXT.js.map} +0 -0
- /package/dist/{chunk-3SWP2FYA.js.map → chunk-NA2NIJZI.js.map} +0 -0
- /package/dist/{chunk-MOQ6OGKS.js.map → chunk-NKHRDYOR.js.map} +0 -0
- /package/dist/{chunk-FKQCC4C5.js.map → chunk-NQKIUNW5.js.map} +0 -0
- /package/dist/{chunk-SWFIXQF5.js.map → chunk-PT43Y56J.js.map} +0 -0
- /package/dist/{chunk-MTTPHBIE.js.map → chunk-Q2PU57HC.js.map} +0 -0
- /package/dist/{chunk-FLRLZ4XZ.js.map → chunk-Q7HZX3IF.js.map} +0 -0
- /package/dist/{chunk-75WNTBZL.js.map → chunk-QIBVIOXO.js.map} +0 -0
- /package/dist/{chunk-KQIDBIZL.js.map → chunk-QIZPZMUI.js.map} +0 -0
- /package/dist/{chunk-KZTPL7NL.js.map → chunk-RMF67KCG.js.map} +0 -0
- /package/dist/{chunk-OEJ4R52I.js.map → chunk-RMS3NEA3.js.map} +0 -0
- /package/dist/{chunk-VTTDPGEK.js.map → chunk-RRNRNANG.js.map} +0 -0
- /package/dist/{chunk-XKA6UH5V.js.map → chunk-SFAWCTEM.js.map} +0 -0
- /package/dist/{chunk-FYT3DXPN.js.map → chunk-SKGMN35F.js.map} +0 -0
- /package/dist/{chunk-USKHHOIV.js.map → chunk-SL3JAAKN.js.map} +0 -0
- /package/dist/{chunk-JILOSL4O.js.map → chunk-SPYWXKJN.js.map} +0 -0
- /package/dist/{chunk-4RUFYGWG.js.map → chunk-SZJ3DLZA.js.map} +0 -0
- /package/dist/{chunk-O3SNM66K.js.map → chunk-TFR7DSOV.js.map} +0 -0
- /package/dist/{chunk-DIVY2CJZ.js.map → chunk-TRGTKX5E.js.map} +0 -0
- /package/dist/{chunk-JY4U6CYV.js.map → chunk-TUFM4UZP.js.map} +0 -0
- /package/dist/{chunk-DZPMKY3J.js.map → chunk-UGTBXF5U.js.map} +0 -0
- /package/dist/{chunk-THNJ3IKU.js.map → chunk-ULUMAZ5S.js.map} +0 -0
- /package/dist/{chunk-YHIAWECL.js.map → chunk-UXVWEX5L.js.map} +0 -0
- /package/dist/{chunk-IAHDSFFA.js.map → chunk-UXWB3FPF.js.map} +0 -0
- /package/dist/{chunk-GHADG5QZ.js.map → chunk-VTFVLCUH.js.map} +0 -0
- /package/dist/{chunk-U3RMWOXY.js.map → chunk-VXANTWBJ.js.map} +0 -0
- /package/dist/{chunk-5W5CEHLA.js.map → chunk-VXGSWL6L.js.map} +0 -0
- /package/dist/{chunk-7YVSWPZB.js.map → chunk-WEQEYLCS.js.map} +0 -0
- /package/dist/{chunk-TAJZ7GXO.js.map → chunk-X2DLENDQ.js.map} +0 -0
- /package/dist/{chunk-2E2LT37H.js.map → chunk-XLMEZIAJ.js.map} +0 -0
- /package/dist/{chunk-2MQ2D5OZ.js.map → chunk-XTXOCYOJ.js.map} +0 -0
- /package/dist/{chunk-CWFH36SI.js.map → chunk-YSRUYAVU.js.map} +0 -0
- /package/dist/{chunk-ZQGRZN5L.js.map → chunk-YYP7WSEB.js.map} +0 -0
- /package/dist/{chunk-4U52PMEL.js.map → chunk-ZN4FD4PE.js.map} +0 -0
- /package/dist/{chunk-AW4KTQA4.js.map → chunk-ZORTV6NH.js.map} +0 -0
- /package/dist/{chunk-H5GVPOB4.js.map → chunk-ZVO4QVPD.js.map} +0 -0
- /package/dist/{chunk-PZ5AY32C.js.map → collection-facade-4GRREZ6C.js.map} +0 -0
- /package/dist/{collection-facade-OPJ3EC4L.js.map → computed-VPOKQK4N.js.map} +0 -0
- /package/dist/{computed-HW6IG5UH.js.map → derive-6O5SWQKN.js.map} +0 -0
- /package/dist/{derive-AAIXSQIE.js.map → enclave-KJOTOH7X.js.map} +0 -0
- /package/dist/{enclave-OXZY3NOP.js.map → executor-5NIMLSKZ.js.map} +0 -0
- /package/dist/{executor-67NA4KPO.js.map → executor-AQVXV5GZ.js.map} +0 -0
- /package/dist/{executor-7JDP7UBK.js.map → executor-PUAO6AKJ.js.map} +0 -0
- /package/dist/{executor-CRH5OB4V.js.map → export-accessible-72EQNBMR.js.map} +0 -0
- /package/dist/{export-accessible-K4GJAU7U.js.map → extract-partition-PUYNU3UF.js.map} +0 -0
- /package/dist/{extract-partition-YJFL5OKK.js.map → find-2ABFCZX4.js.map} +0 -0
- /package/dist/{find-SVZHMEQI.js.map → issue-SIDORTSZ.js.map} +0 -0
- /package/dist/{issue-64N6OG7U.js.map → ledger-F33ZVMTK.js.map} +0 -0
- /package/dist/{ledger-ZAFULLAF.js.map → liberate-LCDPNAG2.js.map} +0 -0
- /package/dist/{liberate-XL6NSGOL.js.map → link-set-FKNWAYKS.js.map} +0 -0
- /package/dist/{link-set-LQI2IJX6.js.map → managed-secret-PQYKSR6T.js.map} +0 -0
- /package/dist/{managed-secret-7OH7HKXV.js.map → noydb-DUXZPKSN.js.map} +0 -0
- /package/dist/{noydb-SWUGPFBK.js.map → read-only-facade-BIGO37U3.js.map} +0 -0
- /package/dist/{read-only-facade-CHCKSEPD.js.map → register-I2DZXGAR.js.map} +0 -0
- /package/dist/{register-AYBQNTM3.js.map → registry-23WF3TGH.js.map} +0 -0
- /package/dist/{registry-CQWWOBO4.js.map → registry-4AYVUNXK.js.map} +0 -0
- /package/dist/{registry-JCZ4BNLV.js.map → registry-VSSQPIGF.js.map} +0 -0
- /package/dist/{registry-JFFENZ44.js.map → registry-YLEWMGAC.js.map} +0 -0
- /package/dist/{registry-ZA4HACYR.js.map → request-withdrawal-KFQHEZ25.js.map} +0 -0
- /package/dist/{request-withdrawal-7IKUIAEB.js.map → revoke-DQDZAZZM.js.map} +0 -0
- /package/dist/{revoke-PUJKRYJF.js.map → signer-WAMDZHEN.js.map} +0 -0
- /package/dist/{signer-5TA7FUC3.js.map → stale-DDL7WQEZ.js.map} +0 -0
- /package/dist/{stale-HZR7745Y.js.map → storage-FLR73HHF.js.map} +0 -0
- /package/dist/{storage-J2QHNJCB.js.map → ulid-4MKXG325.js.map} +0 -0
- /package/dist/{ulid-VQW6ERQN.js.map → vault-diff-C6WUJFNP.js.map} +0 -0
- /package/dist/{vault-diff-FE5J35NJ.js.map → walk-3UQBRMDV.js.map} +0 -0
- /package/dist/{walk-3PA4ZOKS.js.map → withdraw-accessible-EL5GXZBS.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/with-shape/introspection/field-meta.ts","../src/with-shape/introspection/describe.ts","../src/kernel/via/compose.ts","../src/kernel/via/pipeline.ts","../src/kernel/collection-config.ts","../src/kernel/via/graph.ts"],"sourcesContent":["/**\n * Consumer-neutral, data-relatable field descriptors — the canonical,\n * validator-agnostic authoring channel. Merged by `collection.describe()`.\n *\n * Descriptive, never prescriptive: label/semanticType/unit/sensitivity/\n * aggregate/aliases/displayFor only. Layout, styling, and active-locale\n * selection stay app-side.\n *\n * @module\n */\n\n/** Known semantic types; the union is open — unknown strings pass through. */\nexport type SemanticType =\n | 'date' | 'datetime' | 'email' | 'url' | 'currency' | 'percent'\n | 'country' | 'vat' | 'iban' | 'entity'\n | (string & {})\n\nexport interface FieldMeta {\n /** Human label for any displayable field. Required. */\n label: string\n description?: string\n semanticType?: SemanticType\n /** Display unit, e.g. '€', '%', 'kg'. */\n unit?: string\n /** Data classification driving redaction/inspector masking. */\n sensitivity?: 'public' | 'pii' | 'secret'\n /** Default aggregation for this field. */\n aggregate?: 'sum' | 'count' | 'distinct' | 'none'\n /** Canonical search synonyms (data vocabulary, not UI). */\n aliases?: readonly string[]\n /** Entity pairing: the field holding the human label for this id (buyerId → buyerName). */\n displayFor?: string\n /**\n * Override the widget hint derived from semanticType/type.\n * e.g. 'textarea', 'date', 'money', 'select', 'checkbox', 'number', 'text'.\n * When absent, the widget is derived automatically by buildDescription.\n */\n widget?: string\n /**\n * Card/section grouping hint for detail & form layouts (e.g. 'Identity',\n * 'Amounts'). Purely descriptive metadata — consumers group; describe()\n * keeps emitting fields alphabetically.\n */\n group?: string\n /** Relative ordering hint within (and across) groups. Lower renders first. */\n order?: number\n}\n\nexport class FieldMetaUnknownFieldError extends Error {\n constructor(public readonly collection: string, public readonly key: string) {\n super(`fieldMeta for collection \"${collection}\" references unknown field \"${key}\". `\n + `Declare it in the schema/config or remove the fieldMeta entry.`)\n this.name = 'FieldMetaUnknownFieldError'\n }\n}\n\n/** Reject fieldMeta keys that are not known fields (typo guard), fail-loud. */\nexport function validateFieldMetaKeys(\n collection: string,\n fieldMeta: Record<string, FieldMeta>,\n knownFields: ReadonlySet<string>,\n): void {\n for (const key of Object.keys(fieldMeta)) {\n if (!knownFields.has(key)) throw new FieldMetaUnknownFieldError(collection, key)\n }\n}\n\nexport interface MergeInputs {\n channel?: FieldMeta\n zodMeta?: Partial<FieldMeta>\n inferred?: Partial<FieldMeta>\n}\nexport interface ResolvedMeta extends Partial<FieldMeta> { label: string }\n\n/** camelCase / snake_case → Title Case words. */\nexport function humanizeFieldKey(key: string): string {\n return key\n .replace(/[_-]+/g, ' ')\n .replace(/([a-z0-9])([A-Z])/g, '$1 $2')\n .trim()\n .split(/\\s+/)\n .map((w) => w.charAt(0).toUpperCase() + w.slice(1))\n .join(' ')\n}\n\n/** Merge one field's metadata: channel > zodMeta > inferred; label always present. */\nexport function resolveFieldMeta(key: string, inputs: MergeInputs): ResolvedMeta {\n const { channel, zodMeta, inferred } = inputs\n const pick = <K extends keyof FieldMeta>(k: K): FieldMeta[K] | undefined =>\n channel?.[k] ?? zodMeta?.[k] ?? inferred?.[k]\n const description = pick('description')\n const semanticType = pick('semanticType')\n const unit = pick('unit')\n const sensitivity = pick('sensitivity')\n const aggregate = pick('aggregate')\n const aliases = pick('aliases')\n const displayFor = pick('displayFor')\n const widget = pick('widget')\n const group = pick('group')\n const order = pick('order')\n return {\n label: pick('label') ?? humanizeFieldKey(key),\n ...(description !== undefined ? { description } : {}),\n ...(semanticType !== undefined ? { semanticType } : {}),\n ...(unit !== undefined ? { unit } : {}),\n ...(sensitivity !== undefined ? { sensitivity } : {}),\n ...(aggregate !== undefined ? { aggregate } : {}),\n ...(aliases !== undefined ? { aliases } : {}),\n ...(displayFor !== undefined ? { displayFor } : {}),\n ...(widget !== undefined ? { widget } : {}),\n ...(group !== undefined ? { group } : {}),\n ...(order !== undefined ? { order } : {}),\n }\n}\n\n/**\n * Field KEYS from a configured validator, synchronously — the complement to\n * {@link deriveZodFields}, which derives field TYPES and must be async.\n *\n * The distinction is the whole point (#1253). `describe()`'s sync path passed\n * `zodFields: undefined`, so `fieldMeta` key-validation could never run there\n * and a typo'd key became a PHANTOM FIELD carrying its declared `sensitivity`\n * while the real field went undescribed — an inventory wrong in both\n * directions, silently, on the surface `sensitivity` exists to serve.\n *\n * That was read as unavoidable (\"the sync path cannot know the schema's\n * fields\"), which is true of types and false of keys: a Zod object exposes\n * `.shape` directly, on both v3 and v4, with no JSON-Schema derivation and no\n * `zod-to-json-schema` peer. The latter matters — on Zod 3 that peer is\n * required for the async path, so the sync path is the only one some\n * consumers can reach.\n *\n * A duck-typed probe, not a Zod dependency: an unrecognised validator returns\n * `undefined` and the caller stays silent rather than guessing, so a validator\n * hub cannot read never produces a false \"unknown field\" error.\n *\n * Wrappers (reported by the pilot on #1249's guard, and it equally affected\n * #1253's): a wrapped object's `.shape` is undefined, so \"has a schema\" and\n * \"hub can enumerate its fields\" silently diverged for exactly the schemas\n * most worth guarding — validated ones.\n *\n * ONE RULE UNWRAPS ALL OF THEM: FOLLOW THE OUTPUT SIDE. These keys describe\n * the PARSED record, so the only question a wrapper raises is whether it\n * changes the parsed shape.\n *\n * Zod 3 `ZodEffects` — `.refine()`/`.superRefine()` (`effect.type` is\n * `'refinement'`) and `z.preprocess()` (`'preprocess'`) both parse WITH\n * the inner schema, so the output is the inner object: follow\n * `_def.schema`. `.transform()` REPLACES the output, so the inner keys\n * would be a lie: stay `undefined`, deliberately.\n * Zod 4 `ZodPipe` — `z.preprocess()` is `pipe(transform -> object)` and\n * `.transform()` is `pipe(object -> transform)`. Following `_def.out`\n * resolves both correctly with no effect-kind test: preprocess reaches the\n * object, transform reaches a `ZodTransform` that has no shape and no\n * inner schema, so the loop returns `undefined` on its own.\n *\n * `preprocess` was the pilot's second finding (#1262): the first fix followed\n * refinements only, which left four of their registered collections unguarded\n * — including the one carrying their only `fieldMeta` PII declaration, i.e.\n * precisely the collection #1253 was written for. It is one string away from\n * `transform` and means the opposite thing, so a test pins the two apart.\n *\n * A duck-typed probe throughout: an unrecognised validator returns `undefined`\n * and the caller stays silent rather than guessing. Bounded depth, so a cyclic\n * duck cannot hang us.\n */\nexport function schemaFieldKeys(schema: unknown): readonly string[] | undefined {\n let s: unknown = schema\n for (let depth = 0; depth < 10; depth++) {\n if (s === null || typeof s !== 'object') return undefined\n const shape: unknown = (s as { shape?: unknown }).shape\n if (shape !== null && typeof shape === 'object') {\n const keys = Object.keys(shape as Record<string, unknown>)\n return keys.length > 0 ? keys : undefined\n }\n const def = (s as {\n _def?: { effect?: { type?: unknown }; schema?: unknown; out?: unknown }\n })._def\n // Zod 3 ZodEffects: refinement and preprocess parse WITH the inner schema,\n // so the output shape is the inner object's. `transform` replaces it.\n const effect = def?.effect?.type\n if (def?.schema !== undefined && (effect === 'refinement' || effect === 'preprocess')) {\n s = def.schema\n continue\n }\n // Zod 4 ZodPipe: the output side IS the parsed shape. `z.preprocess` puts\n // the object there; `.transform()` puts a shapeless ZodTransform there,\n // which falls out of the loop as `undefined` on the next pass.\n if (def?.out !== undefined) {\n s = def.out\n continue\n }\n return undefined\n }\n return undefined\n}\n\n/**\n * Registration-time `fieldMeta` key check (#1253 follow-up, the \"refuse as early\n * as the information allows\" pass).\n *\n * The same validation `buildDescription` runs, hoisted to collection\n * construction so a typo is refused when it is DECLARED rather than when\n * someone happens to call `describe()`. A collection nobody describes was\n * previously never checked at all — and `fieldMeta` is what carries\n * `sensitivity`, so the un-checked case was the one with a data-classification\n * inventory hanging off it.\n *\n * Deliberately NOT a replacement for the check inside `buildDescription`. There\n * are three tiers of knowability, not two:\n *\n * always — a name declared in the config itself (see the virtual-field\n * refusal in the derivation registry: \"declared and never\n * stored\" needs no schema at all)\n * at reg. — a validator whose `.shape` is readable synchronously: THIS\n * at describe — a validator whose fields only exist after async JSON-Schema\n * derivation (Zod 3 + `zod-to-json-schema`)\n *\n * The third tier is why `buildDescription` keeps its own call. Hoisting alone\n * would move the check earlier for some collections and REMOVE it for others.\n *\n * Silent when the field set cannot be enumerated, exactly as the describe-time\n * check is: a TS-generic collection names real fields that appear in no runtime\n * config, and rejecting those teaches people to stop declaring `fieldMeta`.\n */\nexport function validateFieldMetaAtRegistration(input: {\n readonly collection: string\n readonly schema?: unknown\n readonly fieldMeta?: Record<string, unknown> | undefined\n readonly configKeys: readonly string[]\n}): void {\n if (input.fieldMeta === undefined) return\n const validatorKeys = schemaFieldKeys(input.schema)\n if (validatorKeys === undefined) return\n validateFieldMetaKeys(\n input.collection,\n input.fieldMeta as Parameters<typeof validateFieldMetaKeys>[1],\n new Set<string>([...validatorKeys, ...input.configKeys]),\n )\n}\n","/**\n * `buildDescription` — pure assembler that merges collection config\n * (moneyFields / dictKeyFields / refs / computed / fieldMeta) with an\n * optional validator-derived `zodFields` map into a normalised\n * {@link CollectionDescription}.\n *\n * The sync path (`collection.describe()`) passes `zodFields: undefined`.\n * The async path supplies a populated map and validator-derived type\n * strings.\n *\n * @module\n */\n\nimport type { FieldMeta } from './field-meta.js'\nimport { resolveFieldMeta, validateFieldMetaKeys, FieldMetaUnknownFieldError, humanizeFieldKey, schemaFieldKeys } from './field-meta.js'\nexport { schemaFieldKeys }\nimport type { CollectionMeta } from './meta.js'\nimport type { MoneyDescriptor } from '../../via/money/descriptor.js'\nimport type { ViaDescriptor, ViaPosture } from '../../kernel/via/index.js'\nimport type { DictKeyDescriptor, StaticDictDescriptor } from '../../via/i18n/dictionary.js'\nimport { isStaticDictDescriptor } from '../../via/i18n/dictionary.js'\n// #650 Task 2 — native lookup()/enumOf()/dict() fields (separate from\n// dictKeyFields above, which stays the dictKey()/staticDict() alias's own\n// input). Emits the SAME `dict` block shape for byte-parity (the tiers this\n// covers — 'static' with a table, 'reserved' — are the alias-equivalent\n// ones; a first-class 'collection' backing degrades to the \"no resolved\n// labels\" fallback, same as an unresolved dynamic dictKey).\nimport type { LookupDescriptor } from '../../via/lookup/descriptor.js'\n// #650 Task 7 — the 'lookup' binding's describeFragment payload shape (the\n// first-ever NoydbVia.describeFragment consumer, via/index.ts:136). describe.ts\n// is NOT under kernel/**, so importing this via/ type directly is fine\n// (Check 14 via-layering only restricts the kernel spine).\nimport type { LookupDescribeFragment, LookupDescribeFragmentEntry } from '../../via/lookup/binding.js'\n// #657 — the 'blob' binding's describeFragment payload shape (the second-ever\n// NoydbVia.describeFragment consumer, after lookup above). Same rationale:\n// describe.ts is not under kernel/**, so importing this via/ type is fine.\nimport type { BlobDescribeFragment, BlobDescribeFragmentEntry } from '../../via/blob/binding.js'\nimport type { I18nTextDescriptor } from '../../via/i18n/core.js'\nimport type { ComputedFields } from '../../with-formula/computed/index.js'\nimport type { RefDescriptor } from '../../kernel/refs.js'\nimport type { ClassifiedFieldSpec } from '../../via/classified/descriptor.js'\nimport { derivePersistedSchema, isZod4Schema } from '../persisted-schemas/derive.js'\nimport { loadPersistedSchema } from '../persisted-schemas/storage.js'\nimport { jsonSchemaToFields } from './fields.js'\nimport type { NoydbStore } from '../../kernel/types.js'\nimport type { EnclaveKey } from '../../kernel/enclave/index.js'\n\n// ─── Public types ──────────────────────────────────────────────────────────\n\nexport interface DescribedField {\n readonly key: string\n /**\n * Stable, opaque per-field identity (#946) — survives a rename (the field\n * keeps its id when its name/`key` changes). Sourced from the persisted\n * schema's `PersistedSchemaEnvelope.fieldIds` map, so it is only present on\n * the async `describeAsync()` path for a collection that has persisted a\n * schema (`persistJsonSchema: true`) at least once; absent on the sync\n * `describe()` path (no store I/O) and on any field with no persisted id\n * yet.\n */\n readonly id?: string\n /** Sync: inferred from config ('number'|'enum'|'string'|'array'|'unknown'). Async (Task 4): validator-derived. */\n readonly type: string\n readonly optional: boolean\n readonly constraints?: Record<string, unknown>\n readonly label: string\n readonly description?: string\n /** Card/section grouping hint for detail & form layouts. From fieldMeta/zod .meta(). */\n readonly group?: string\n /** Relative ordering hint within and across groups. Lower renders first. */\n readonly order?: number\n readonly semanticType?: string\n readonly unit?: string\n readonly sensitivity?: 'public' | 'pii' | 'secret'\n readonly aggregate?: 'sum' | 'count' | 'distinct' | 'none'\n readonly aliases?: readonly string[]\n readonly ref?: { target: string; mode: string; isArray?: true }\n readonly displayFor?: string\n readonly money?: { mode: 'fixed' | 'multi'; currency?: string; scale?: number; rounding?: string }\n readonly dict?: { name: string; static: boolean; values?: readonly { value: string; label?: string }[] }\n /**\n * Normalized lookup metadata (#650 Task 7 — the first-ever\n * `NoydbVia.describeFragment` consumer; sourced from the `'lookup'`\n * binding's fragment, NOT from config directly — see `buildDescription`).\n * Present for every `lookup()`/`enumOf()`/`dict()` field, ALONGSIDE the\n * pre-existing `dict` block above (kept byte-stable for the\n * `dictKey()`/`staticDict()` alias — this is additive, not a replacement).\n * `dimension` is omitted for a bare `enumOf()` (no backing store, no\n * dimension name — the #650 Task 2 `dimension:''` sentinel resolved).\n * `keys` is the statically-known closed-vocabulary key set (declared\n * `keys`, or a static table's own keys) — omitted when membership lives\n * only in the backing collection/dictionary.\n */\n readonly lookup?: {\n readonly dimension?: string\n readonly backing: 'static' | 'reserved' | 'collection'\n readonly vocabulary: 'open' | 'closed'\n readonly key: string\n readonly altKeys?: readonly string[]\n readonly present?: { readonly label: string; readonly by?: string }\n readonly sortBy?: string\n readonly onDelete: 'restrict' | 'cascade' | 'nullify'\n readonly keys?: readonly string[]\n }\n readonly computed?: true\n /** i18n metadata for fields declared with i18nText(). Present only when the field is i18n-enabled. */\n readonly i18n?: { readonly locales?: readonly string[]; readonly densify?: boolean }\n /** Widget hint derived from semanticType+type, overridable via fieldMeta.widget. */\n readonly widget: string\n /** Whether the field is user-editable. False for computed, id, and provenance-stamped fields. */\n readonly editable: boolean\n /** Present when the field is classified. Serialized read-projection contract. */\n readonly classified?: {\n readonly preset: string\n readonly storage: 'recoverable' | 'never' | 'digest-only'\n readonly list: 'omit' | { readonly mask: string } | { readonly rider: string }\n /**\n * Present (and `true`) only when the field opted into the equatable blind\n * index. Additive metadata — emitted UNGATED (no `withClassified()` needed;\n * `toJSONSchema()` carries it too), so it advertises *that* the field is\n * equatable beyond the DEK-consent boundary. Intended: it's a structural\n * property a schema consumer legitimately needs and discloses no value. A\n * deployment wanting it gated can gate this behind its value-bearing door.\n */\n readonly equatable?: true\n }\n /**\n * Present only for a field declared via `blobFields` (#657) — out-of-band\n * attachment storage (`collection.blob(id)`), never a sealed or plaintext\n * record field. `queryable` mirrors the binding's fixed `ViaPosture`\n * (blob content is never indexed — always `'none'`); the rest mirrors the\n * declared `blobFields[field]` policy verbatim (scalars) or as a presence\n * flag (predicate knobs — a predicate has no serializable form). Sourced\n * from the `'blob'` binding's `describeFragment()`, the same\n * `viaFragments` door the `lookup` block above is sourced from.\n */\n readonly blob?: {\n readonly retainDays?: number\n readonly evictWhen?: true\n readonly legalHold?: true\n readonly retainUntil?: true\n readonly external?: true\n readonly public?: true\n readonly backlink?: string\n readonly queryable: 'none'\n }\n /**\n * Present only for a graph-tainted derived field (#638 Task 3 — computed/\n * derivation output whose effective posture was forced away from the\n * plain baseline by a source's posture, e.g. a computed field reading a\n * classified field). `forcedBy` names the immediate declared source\n * field(s) responsible.\n */\n readonly taint?: {\n readonly posture: ViaPosture\n readonly forcedBy: readonly string[]\n }\n}\n\nexport interface CollectionDescription {\n readonly collection: string\n readonly fields: readonly DescribedField[]\n /** Collection-level descriptive metadata; label falls back to the humanized collection name. */\n readonly meta: CollectionMeta\n}\n\n/** Options for the async describe(opts) overload. */\nexport interface DescribeOptions {\n /**\n * When true, resolve dynamic-dict labels from vault.dictionary(name).list()\n * and populate dict.values[].label for dynamic dictKey fields.\n */\n readonly resolveDictLabels?: boolean\n}\n\n// ─── ZodField slot (async path wires this; sync path passes undefined) ───\n\nexport interface ZodFieldSlot {\n readonly type?: string\n readonly optional?: boolean\n readonly constraints?: Record<string, unknown>\n readonly meta?: Partial<FieldMeta>\n}\n\n// ─── RECOGNIZED zod-4 .meta() keys ────────────────────────────────────────\n//\n// Empirically verified 2026-06-25 via:\n// node -e \"const {z,toJSONSchema}=require('zod'); console.log(JSON.stringify(toJSONSchema(z.object({n:z.number().meta({label:'L',unit:'kg',sensitivity:'public',semanticType:'percent',description:'d',aggregate:'sum',aliases:['a'],displayFor:'x'})}))), null, 2)\"\n// Result: .meta() keys are emitted INLINE on each JSON Schema property object\n// at the same level as `type`/`format` — NOT nested under a `metadata` key.\n// Example: z.number().meta({ unit: 'kg' }) → { \"type\": \"number\", \"unit\": \"kg\" }\n// Unknown .meta() keys (not in this set) are ignored.\nconst ZOD_META_KEYS = new Set<string>([\n 'label', 'description', 'unit', 'semanticType', 'sensitivity', 'aggregate', 'aliases', 'displayFor',\n 'group', 'order',\n])\n\n// ─── deriveZodFields ──────────────────────────────────────────────────────\n\n/**\n * Derive per-field slots from a Standard Schema validator.\n * - Calls `derivePersistedSchema` to get the JSON Schema.\n * - Falls back to `{}` for non-Zod or unknown validators.\n * - For zod-4 schemas: reads recognized `.meta()` keys from inline property annotations.\n * - Returns: `Record<fieldKey, { type, optional, constraints?, meta? }>`.\n *\n * No static zod import — all zod access is lazy via derivePersistedSchema.\n */\n\nexport async function deriveZodFields(\n schema: unknown,\n): Promise<Record<string, ZodFieldSlot>> {\n const envelope = await derivePersistedSchema(schema)\n if (!envelope.jsonSchema) return {}\n\n const isZod4 = isZod4Schema(schema)\n const jsonSchema = envelope.jsonSchema as Record<string, unknown>\n\n // Use the existing JSON-Schema→field mapper for type/optional/constraints.\n const fieldDescriptors = jsonSchemaToFields(jsonSchema, 'live-validator')\n\n // For zod-4: the JSON Schema properties contain inline .meta() annotations.\n // We need to walk the raw properties to extract recognized meta keys.\n const propertiesRaw = jsonSchema['properties'] as Record<string, Record<string, unknown>> | undefined\n\n const result: Record<string, ZodFieldSlot> = {}\n\n for (const [key, descriptor] of Object.entries(fieldDescriptors)) {\n let meta: Partial<FieldMeta> | undefined\n\n if (isZod4 && propertiesRaw) {\n const prop = propertiesRaw[key]\n if (prop) {\n const extracted: Partial<FieldMeta> = {}\n let hasAny = false\n for (const mk of ZOD_META_KEYS) {\n if (mk in prop) {\n (extracted as Record<string, unknown>)[mk] = prop[mk]\n hasAny = true\n }\n }\n if (hasAny) meta = extracted\n }\n }\n\n result[key] = {\n type: descriptor.type,\n optional: descriptor.optional === true,\n ...(descriptor.constraints !== undefined ? { constraints: descriptor.constraints } : {}),\n ...(meta !== undefined ? { meta } : {}),\n }\n }\n\n return result\n}\n\n// ─── resolveDescribeFieldIds (#946) ───────────────────────────────────────\n\n/**\n * Resolve the persisted-schema `fieldIds` map for `describeAsync()`'s\n * `BuildDescriptionInput` (#946). Returns a spreadable partial so the call\n * site can inline it with `...(await resolveDescribeFieldIds(...))` without\n * an intermediate local — `collection.ts`'s `describe()` bodies are under a\n * near-zero line-ceiling headroom.\n *\n * Silent-degrades to `{}` (no ids — every `DescribedField.id` stays\n * `undefined`, never a describe() crash) on any failure: `getDEK` throwing,\n * no persisted envelope yet, or an envelope with no `fieldIds` (legacy /\n * never-persisted). Mirrors the leak/degrade posture of\n * `satellites/dead-filter.ts`'s `liveBaseIdSetsForBundle`, but degrading to\n * \"no ids\" is lossless here (unlike that filter's data-exposure tradeoff) —\n * describe() simply omits `id` for every field.\n */\nexport async function resolveDescribeFieldIds(\n store: NoydbStore,\n vaultName: string,\n collectionName: string,\n getDEK: (collectionName: string) => Promise<EnclaveKey>,\n): Promise<{ fieldIds?: Record<string, string> }> {\n let dek: EnclaveKey\n try {\n dek = await getDEK(collectionName)\n } catch {\n return {}\n }\n const persisted = await loadPersistedSchema(store, vaultName, collectionName, dek)\n return persisted?.fieldIds !== undefined ? { fieldIds: persisted.fieldIds } : {}\n}\n\n// ─── buildDescription ─────────────────────────────────────────────────────\n\nexport interface BuildDescriptionInput {\n readonly collection: string\n readonly fieldMeta: Record<string, FieldMeta> | undefined\n /**\n * Kernel-visible collections only carry the opaque {@link ViaDescriptor}\n * marker (the kernel never inspects a Via feature's concrete descriptor\n * shape). Every entry here is actually a {@link MoneyDescriptor} — only\n * `money()` constructs them — narrowed locally below where its\n * mode/currency/scale are read for the describe() output.\n */\n readonly moneyFields: Record<string, ViaDescriptor> | undefined\n readonly dictKeyFields: Record<string, DictKeyDescriptor | StaticDictDescriptor> | undefined\n /** Native lookup()/enumOf()/dict() fields (#650 Task 2) — declared only via `viaFields`/`via()`, no sugar key. */\n readonly lookupFields?: Record<string, LookupDescriptor> | undefined\n readonly computed: ComputedFields | undefined\n readonly refs: Record<string, RefDescriptor>\n /** Async path fills this; sync path passes `undefined`. */\n readonly zodFields: Record<string, ZodFieldSlot> | undefined\n /**\n * The collection's configured validator, if any. The sync path passes it so\n * `fieldMeta` keys can still be validated (#1253): field KEYS are readable\n * synchronously via {@link schemaFieldKeys} even though field TYPES are not.\n * `undefined` means no validator is configured, which is itself informative\n * — the config keys are then the complete field set.\n */\n readonly schema?: unknown\n /**\n * Async path: when `resolveDictLabels` was true, this map holds\n * `{ dictName -> { value -> label } }` for dynamic dictKey fields.\n * Used to populate `dict.values[].label`.\n */\n readonly dictLabels?: Record<string, Record<string, string>> | undefined\n /** Collection-level descriptive metadata. Label falls back to humanized collection name. */\n readonly meta?: CollectionMeta | undefined\n /**\n * Map of field name → I18nTextDescriptor for fields declared with i18nText().\n * When present, describe() surfaces an `i18n` block on matching DescribedField entries.\n */\n readonly i18nFields?: Record<string, I18nTextDescriptor> | undefined\n /** Per-field classified specs (already resolved/flattened). */\n readonly classified?: Record<string, ClassifiedFieldSpec> | undefined\n /** Graph-computed taint overlay (#638 Task 3) — `Collection.via?.taint`. */\n readonly taint?: { readonly postures: ReadonlyMap<string, ViaPosture>; readonly provenance?: ReadonlyMap<string, readonly string[]> } | undefined\n /**\n * Per-binding `describeFragment()` output, keyed by binding brand (#650\n * Task 7 — first-ever consumer of `NoydbVia.describeFragment`,\n * `via/index.ts:136`). `Collection.describe()`/`describeAsync()` build this\n * from `this.via?.describeFragments()`. The `'lookup'` brand's fragment\n * feeds the `lookup` block below; `'blob'`'s feeds the `blob` block\n * (#657, the second consumer). Other brands' fragments ride along unread\n * until they gain a consumer too.\n */\n readonly viaFragments?: Record<string, Record<string, unknown>> | undefined\n /**\n * Persisted-schema `fieldName -> id` map (#946), resolved by the async\n * describe path via {@link resolveDescribeFieldIds}. The sync path passes\n * no `fieldIds` (no store I/O), so every field's `id` is `undefined` there.\n */\n readonly fieldIds?: Record<string, string> | undefined\n}\n\n// Re-export so that callers that want to catch the error don't need another import path.\nexport { FieldMetaUnknownFieldError }\n\n// ─── Widget derivation ────────────────────────────────────────────────────────\n\n/**\n * Derive a widget hint from resolved field metadata.\n * Priority: explicit override (resolvedWidget) > semanticType > dict > type > 'text'.\n */\nfunction deriveWidget(opts: {\n semanticType?: string\n type: string\n dict?: unknown\n /** #650 Task 7 — same 'select' outcome as `dict` (today always co-present for a lookup field via the existing `dict` block; kept as its own check so a future lookup-only field, with no `dict` block, still derives 'select'). */\n lookup?: unknown\n /** #657 — a blobFields-declared field derives the 'file' widget, never the 'text' default (binary content, not a text input). */\n blob?: unknown\n resolvedWidget?: string\n}): string {\n if (opts.resolvedWidget !== undefined) return opts.resolvedWidget\n switch (opts.semanticType) {\n case 'date':\n case 'datetime':\n return 'date'\n case 'currency':\n return 'money'\n case 'entity':\n return 'ref-select'\n case 'url':\n return 'url'\n case 'email':\n return 'email'\n case 'percent':\n return 'number'\n }\n if (opts.dict !== undefined || opts.lookup !== undefined) return 'select'\n if (opts.blob !== undefined) return 'file'\n if (opts.type === 'boolean') return 'checkbox'\n if (opts.type === 'number') return 'number'\n return 'text'\n}\n\n/**\n * Pure assembler: no I/O, no side effects.\n * Builds a {@link CollectionDescription} from the collection's in-memory config.\n *\n * When `zodFields` is supplied (async path), validates that every `fieldMeta` key\n * refers to a known field (config ∪ zodFields). Throws `FieldMetaUnknownFieldError`\n * on the first unknown key — this is the real validation that the vault.ts no-op\n * couldn't do (schema fields weren't knowable synchronously).\n */\nexport function buildDescription(input: BuildDescriptionInput): CollectionDescription {\n const { collection, fieldMeta, moneyFields, dictKeyFields, lookupFields, computed, refs, zodFields, schema, dictLabels, meta, i18nFields, classified, taint, fieldIds } = input\n\n // #650 Task 7 — the 'lookup' binding's describeFragment, keyed per field.\n // Deliberately routed through `viaFragments` rather than reused directly\n // from `lookupFields` above (which only feeds the pre-existing `dict`\n // block, byte-stable for the alias) — this IS the first-ever\n // `describeFragment` consumption the task wires up.\n const lookupFragments = (input.viaFragments?.['lookup'] as LookupDescribeFragment | undefined)?.lookupFields\n\n // #657 — the 'blob' binding's describeFragment, keyed per field (same\n // routing pattern as lookupFragments above). A blobFields-declared field\n // has no other config-map source (unlike money/dict/lookup/i18n/classified,\n // each of which is fed a dedicated map below) — `blobFragments` is BOTH\n // this field's block source AND (via its keys) how it joins `allKeys` at\n // all, since otherwise a blobFields-only field with no fieldMeta entry is\n // invisible in describe() (#657 finding 1).\n const blobFragments = (input.viaFragments?.['blob'] as BlobDescribeFragment | undefined)?.blobFields\n\n // Validate fieldMeta keys against the real known-field set = config keys ∪ the\n // validator's fields. Sound whenever that set can be enumerated COMPLETELY:\n //\n // async path zodFields is non-empty — derived types carry the keys\n // sync path `.shape` was readable — no derivation, no peer dep (#1253)\n //\n // Silent in EVERY other case, and the third one is the instructive one. It is\n // tempting to reason \"no validator configured, therefore the config keys are the\n // whole field set\" — that is FALSE. A collection may be typed by a TypeScript\n // generic alone (`v.collection<Sale>('sales', { moneyFields: … })`), whose fields\n // are real, are present in the data, and are legitimately named by `fieldMeta`,\n // yet appear in NO runtime config. Guarding there rejects correct code.\n //\n // So these are deliberate false NEGATIVES on both counts: an unreadable validator\n // and an absent one. A rule that over-fires teaches people to stop declaring\n // fieldMeta at all, which costs more than the typos it would catch.\n //\n // Before #1253 this ran on the async path alone, so a typo'd key on the sync path\n // became a phantom field carrying its `sensitivity` while the real field went\n // undescribed — see schemaFieldKeys() for why that was thought unavoidable.\n const validatorKeys = zodFields !== undefined && Object.keys(zodFields).length > 0\n ? Object.keys(zodFields)\n : schemaFieldKeys(schema)\n const canEnumerateFields = validatorKeys !== undefined\n if (canEnumerateFields && fieldMeta !== undefined) {\n const knownFields = new Set<string>([\n ...Object.keys(moneyFields ?? {}),\n ...Object.keys(dictKeyFields ?? {}),\n ...Object.keys(refs),\n ...Object.keys(computed ?? {}),\n ...(validatorKeys ?? []),\n ...Object.keys(i18nFields ?? {}),\n ...Object.keys(lookupFields ?? {}),\n ...Object.keys(blobFragments ?? {}),\n ...Object.keys(classified ?? {}),\n ])\n validateFieldMetaKeys(collection, fieldMeta, knownFields)\n }\n\n // Union of all config key sources — stable alphabetical order.\n const allKeys = new Set<string>([\n ...Object.keys(moneyFields ?? {}),\n ...Object.keys(dictKeyFields ?? {}),\n ...Object.keys(lookupFields ?? {}),\n ...Object.keys(refs),\n ...Object.keys(computed ?? {}),\n ...Object.keys(fieldMeta ?? {}),\n ...Object.keys(zodFields ?? {}),\n ...Object.keys(i18nFields ?? {}),\n ...Object.keys(classified ?? {}),\n ...Object.keys(blobFragments ?? {}),\n ])\n\n const fields: DescribedField[] = []\n\n for (const key of [...allKeys].sort()) {\n const zod = zodFields?.[key]\n // Narrow the opaque marker back to the concrete descriptor — see the\n // {@link BuildDescriptionInput.moneyFields} doc comment.\n const money = moneyFields?.[key] as MoneyDescriptor | undefined\n const dict = dictKeyFields?.[key]\n const lookupDesc = lookupFields?.[key]\n const refDesc = refs[key]\n const isComputed = computed !== undefined && key in computed\n const i18nDesc = i18nFields?.[key]\n const cls = classified?.[key]\n const blobFragmentEntry: BlobDescribeFragmentEntry | undefined = blobFragments?.[key]\n const taintPosture = taint?.postures.get(key)\n\n // ── Infer type + structural extras ────────────────────────────────────\n let type = zod?.type ?? 'unknown'\n const inferred: Partial<FieldMeta> = {}\n\n let moneyBlock: DescribedField['money'] | undefined\n let dictBlock: DescribedField['dict'] | undefined\n let refBlock: DescribedField['ref'] | undefined\n let lookupBlock: DescribedField['lookup'] | undefined\n let blobBlock: DescribedField['blob'] | undefined\n\n if (money) {\n type = 'number'\n inferred.semanticType = 'currency'\n inferred.aggregate = 'sum'\n const currency = money.soleCurrency()\n const scale = currency !== undefined ? money.scaleFor(currency) : undefined\n moneyBlock = {\n mode: money.mode,\n ...(currency !== undefined ? { currency } : {}),\n ...(scale !== undefined ? { scale } : {}),\n ...(money.rounding !== undefined ? { rounding: money.rounding } : {}),\n }\n } else if (refDesc) {\n type = refDesc.isArray ? 'array' : 'string'\n inferred.semanticType = 'entity'\n refBlock = {\n target: refDesc.target,\n mode: refDesc.mode,\n ...(refDesc.isArray ? { isArray: true as const } : {}),\n }\n } else if (dict) {\n type = 'enum'\n if (isStaticDictDescriptor(dict)) {\n // Static dict: labels available synchronously from the in-code table.\n const displayLocale = dict.displayLocale\n const values = dict.keys.map((k) => {\n const localeMap = dict.table[k]\n const label = displayLocale !== undefined\n ? (localeMap?.[displayLocale] ?? undefined)\n : undefined\n return label !== undefined\n ? { value: k, label }\n : { value: k }\n })\n dictBlock = { name: dict.name, static: true, values }\n } else {\n // Dynamic dictKey: keys declared in config; labels optionally resolved\n // from vault.dictionary(name).list() when resolveDictLabels was requested.\n const labelMap = dictLabels?.[dict.name]\n const labelMapHasEntries = labelMap !== undefined && Object.keys(labelMap).length > 0\n if (labelMapHasEntries) {\n // We have resolved labels — build values from the label map.\n const values = Object.entries(labelMap).map(([value, label]) => ({ value, label }))\n dictBlock = { name: dict.name, static: false, values }\n } else if (dict.keys !== undefined) {\n const values = dict.keys.map((k) => {\n const label = dict.labels?.[k]\n return label !== undefined ? { value: k, label } : { value: k }\n })\n dictBlock = { name: dict.name, static: false, values }\n } else {\n dictBlock = { name: dict.name, static: false }\n }\n }\n } else if (lookupDesc) {\n // Native lookup()/enumOf()/dict() field (#650 Task 2) — the SAME `dict`\n // block shape as above, for byte-parity with the dictKey()/staticDict()\n // alias. A table-bearing descriptor ('static' backing, the lookup(static)\n // form staticDict() compiles onto) resolves synchronously like a static\n // dict; a reserved-tier dict() resolves via `dictLabels` exactly like a\n // dynamic dictKey (review fix — was previously falling to the\n // declared-keys-only fallback below, breaking async describe parity);\n // everything else (collection/bare enum) falls to that fallback.\n type = 'enum'\n const lookupLabelMap = dictLabels?.[lookupDesc.dimension]\n const lookupLabelMapHasEntries = lookupLabelMap !== undefined && Object.keys(lookupLabelMap).length > 0\n if (lookupDesc.table !== undefined) {\n const displayLocale = lookupDesc.displayLocale\n const table = lookupDesc.table\n const values = (lookupDesc.keys ?? Object.keys(table)).map((k) => {\n const localeMap = table[k]\n const label = displayLocale !== undefined\n ? (localeMap?.[displayLocale] ?? undefined)\n : undefined\n return label !== undefined ? { value: k, label } : { value: k }\n })\n dictBlock = { name: lookupDesc.dimension, static: true, values }\n } else if (lookupLabelMapHasEntries) {\n const values = Object.entries(lookupLabelMap).map(([value, label]) => ({ value, label }))\n dictBlock = { name: lookupDesc.dimension, static: false, values }\n } else if (lookupDesc.keys !== undefined) {\n const values = lookupDesc.keys.map((k) => {\n const label = lookupDesc.labels?.[k]\n return label !== undefined ? { value: k, label } : { value: k }\n })\n dictBlock = { name: lookupDesc.dimension, static: false, values }\n } else {\n dictBlock = { name: lookupDesc.dimension, static: false }\n }\n } else if (i18nDesc) {\n // i18nText field: the stored value is a locale-map object, but the resolved\n // type exposed to consumers is 'string' (locale resolution collapses to a string).\n type = 'string'\n } else if (isComputed) {\n // type already initialized to zod?.type ?? 'unknown' above; no re-set needed\n } else if (blobFragmentEntry !== undefined) {\n // #657 finding 1 — a blobFields-only field (no schema/money/dict/\n // lookup/i18n config) was previously invisible; with a fieldMeta\n // entry it fell through to the 'unknown'/'text'/editable:true default,\n // actively wrong for binary content. `type` is a plain `string` on\n // DescribedField (not a closed union), so 'blob' is not a breaking\n // union extension.\n type = 'blob'\n blobBlock = { ...blobFragmentEntry, queryable: 'none' }\n }\n\n // ── lookup block (#650 Task 7 — first-ever NoydbVia.describeFragment\n // consumer) ── Sourced from `lookupFragments` (the binding's fragment),\n // NOT from `lookupDesc` above (which only feeds the pre-existing `dict`\n // block, byte-stable for the alias) — routing through the fragment is\n // the point: `backing`/`vocabulary`/`key`/`onDelete` have no other\n // source in this function, so their presence here is itself proof the\n // describeFragment seam (declared via/index.ts:136, zero consumers before\n // this task) carries data end to end from binding to describe() output.\n const lookupFragmentEntry: LookupDescribeFragmentEntry | undefined = lookupFragments?.[key]\n if (lookupFragmentEntry !== undefined) {\n lookupBlock = {\n ...(lookupFragmentEntry.dimension !== undefined ? { dimension: lookupFragmentEntry.dimension } : {}),\n backing: lookupFragmentEntry.backing,\n vocabulary: lookupFragmentEntry.vocabulary,\n key: lookupFragmentEntry.key,\n onDelete: lookupFragmentEntry.onDelete,\n ...(lookupFragmentEntry.altKeys !== undefined ? { altKeys: lookupFragmentEntry.altKeys } : {}),\n ...(lookupFragmentEntry.present !== undefined ? { present: lookupFragmentEntry.present } : {}),\n ...(lookupFragmentEntry.sortBy !== undefined ? { sortBy: lookupFragmentEntry.sortBy } : {}),\n ...(lookupFragmentEntry.keys !== undefined ? { keys: lookupFragmentEntry.keys } : {}),\n }\n }\n\n // Classified sensitivity feeds inferred meta at lowest precedence — channel\n // fieldMeta and zod .meta() still win via resolveFieldMeta's merge order.\n if (cls !== undefined) inferred.sensitivity = cls.sensitivity\n\n // ── Merge fieldMeta channel ────────────────────────────────────────────\n const channelEntry = fieldMeta?.[key]\n const zodMeta = zod?.meta\n const resolved = resolveFieldMeta(key, {\n ...(channelEntry !== undefined ? { channel: channelEntry } : {}),\n ...(zodMeta !== undefined ? { zodMeta } : {}),\n inferred,\n })\n\n // ── i18n block (only for i18nText fields) ─────────────────────────────\n let i18nBlock: DescribedField['i18n'] | undefined\n if (i18nDesc !== undefined) {\n const locales = i18nDesc.options.languages\n const densify = i18nDesc.options.densifyOnWrite\n i18nBlock = {\n ...(locales !== undefined ? { locales } : {}),\n ...(densify !== undefined ? { densify } : {}),\n }\n }\n\n // ── Widget (derived, overridable via resolvedWidget from fieldMeta/zodMeta) ──\n const widget = deriveWidget({\n type,\n ...(resolved.semanticType !== undefined ? { semanticType: resolved.semanticType } : {}),\n ...(dictBlock !== undefined ? { dict: dictBlock } : {}),\n ...(lookupBlock !== undefined ? { lookup: lookupBlock } : {}),\n ...(blobBlock !== undefined ? { blob: blobBlock } : {}),\n ...(resolved.widget !== undefined ? { resolvedWidget: resolved.widget } : {}),\n })\n\n // ── Editable: false for computed, id, provenance-stamped, blob fields ──\n // Provenance fields (_source, _sourceTs) are envelope-level metadata, not\n // user schema fields — they won't appear as keys in fieldMeta so this check\n // is implicitly handled (they'd never appear in allKeys). Explicitly guard\n // computed + 'id' as the two structural non-editable cases. A blobFields\n // field (#657) is never written through the record codec — it's mutated\n // exclusively via `collection.blob(id)` — so it is never editable either.\n const editable = !isComputed && key !== 'id' && blobBlock === undefined\n\n // ── Assemble the field (exactOptionalPropertyTypes-safe spreads) ───────\n const field: DescribedField = {\n key,\n ...(fieldIds?.[key] !== undefined ? { id: fieldIds[key] } : {}),\n type,\n optional: zod?.optional ?? false,\n ...(zod?.constraints !== undefined ? { constraints: zod.constraints } : {}),\n label: resolved.label,\n ...(resolved.description !== undefined ? { description: resolved.description } : {}),\n ...(resolved.group !== undefined ? { group: resolved.group } : {}),\n ...(resolved.order !== undefined ? { order: resolved.order } : {}),\n ...(resolved.semanticType !== undefined ? { semanticType: resolved.semanticType } : {}),\n ...(resolved.unit !== undefined ? { unit: resolved.unit } : {}),\n ...(resolved.sensitivity !== undefined ? { sensitivity: resolved.sensitivity } : {}),\n ...(resolved.aggregate !== undefined ? { aggregate: resolved.aggregate } : {}),\n ...(resolved.aliases !== undefined ? { aliases: resolved.aliases } : {}),\n ...(resolved.displayFor !== undefined ? { displayFor: resolved.displayFor } : {}),\n ...(refBlock !== undefined ? { ref: refBlock } : {}),\n ...(moneyBlock !== undefined ? { money: moneyBlock } : {}),\n ...(dictBlock !== undefined ? { dict: dictBlock } : {}),\n ...(lookupBlock !== undefined ? { lookup: lookupBlock } : {}),\n ...(blobBlock !== undefined ? { blob: blobBlock } : {}),\n ...(isComputed ? { computed: true as const } : {}),\n ...(i18nBlock !== undefined ? { i18n: i18nBlock } : {}),\n widget,\n editable,\n ...(cls !== undefined ? {\n classified: {\n preset: cls.preset,\n storage: cls.storage,\n list: cls.list.kind === 'omit' ? 'omit' as const\n : cls.list.kind === 'mask' ? { mask: cls.list.pattern }\n : { rider: cls.list.rider },\n ...(cls.equatable === true ? { equatable: true as const } : {}),\n },\n } : {}),\n ...(taintPosture !== undefined ? { taint: { posture: taintPosture, forcedBy: taint?.provenance?.get(key) ?? [] } } : {}),\n }\n\n fields.push(field)\n }\n\n // Build collection-level meta with label fallback to humanized collection name.\n const collectionMeta: CollectionMeta = {\n ...meta,\n label: meta?.label ?? humanizeFieldKey(collection),\n }\n\n return {\n collection,\n fields,\n meta: collectionMeta,\n }\n}\n","/**\n * via() — the public composer for declaring a field's Via-bound feature(s)\n * directly, as an alternative to a feature's dedicated sugar key\n * (`moneyFields`/`i18nFields`/`dictKeyFields`). Wraps one or more\n * `ViaDescriptor`s (`money()`, `i18nText()`, `dictKey()`, `staticDict()`, …)\n * into a single tagged container a collection's `viaFields` option can hold.\n *\n * Declaring a field via `via()` is equivalent to declaring the same\n * descriptor under its feature's sugar key — `compileVias`\n * (kernel/collection-config.ts) groups a `viaFields` map by each\n * descriptor's `_viaBrand` and merges it with the sugar keys, throwing when\n * the same field is declared in both places (#623 Task 9).\n */\nimport { ValidationError } from '../errors.js'\nimport type { NoydbVia, ViaDescriptor } from './index.js'\nimport type { ViaPipeline } from './pipeline.js'\n// Types + shape-classification predicates reach through the kernel's own\n// `port/with/` hook seam (never `src/via/` directly) — #623 Task 11.\n// `isI18nTextDescriptor`/`isDictKeyDescriptor` are pure tag checks moved\n// onto the port alongside `isStaticDictDescriptor` (see i18n-strategy.ts);\n// the descriptor types were already port-owned re-exports (#623 Task 8).\nimport type { DictKeyDescriptor, I18nTextDescriptor, StaticDictDescriptor } from '../../port/with/i18n-strategy.js'\nimport { isDictKeyDescriptor, isI18nTextDescriptor, isStaticDictDescriptor } from '../../port/with/i18n-strategy.js'\n// `ComputedDescriptor` is a type-only need — the eager link that makes\n// `viaBinder('computed')` resolvable lives in `collection-config.ts`'s value\n// import of this same port module (#638 Task 7).\nimport type { ComputedDescriptor } from '../../port/with/computed-strategy.js'\n// #650 Task 2 — `LookupDescriptor`/`isLookupDescriptor` reach through the\n// SAME kernel port seam (no new `src/via/**` specifier here; `linkLookupVia()`\n// already ran when the caller constructed the descriptor via `lookup()`/\n// `enumOf()`/`dict()`, so `viaBinder('lookup')` is resolvable with no eager\n// import needed here, mirroring i18n/money — see `descriptor.ts`).\nimport type { LookupDescriptor } from '../../port/with/lookup-strategy.js'\nimport { isLookupDescriptor } from '../../port/with/lookup-strategy.js'\n\n/** Tagged container returned by {@link via}. Readonly — never mutated after construction. */\nexport interface ViaFieldSpec {\n readonly _noydbVia: true\n readonly descriptors: readonly ViaDescriptor[]\n}\n\n/**\n * Compose one or more Via feature descriptors for a single field.\n *\n * @example\n * ```ts\n * vault.collection('invoices', {\n * viaFields: { total: via(money({ currency: 'EUR' })) },\n * })\n * ```\n */\nexport function via(...descriptors: ViaDescriptor[]): ViaFieldSpec {\n if (descriptors.length === 0) {\n throw new ValidationError('via(): at least one descriptor is required, e.g. via(money({ currency: \\'EUR\\' }))')\n }\n return { _noydbVia: true, descriptors }\n}\n\n/** Runtime predicate for detecting a {@link ViaFieldSpec}. */\nexport function isViaFieldSpec(x: unknown): x is ViaFieldSpec {\n return typeof x === 'object' && x !== null && (x as { _noydbVia?: unknown })._noydbVia === true\n}\n\n/** The money/i18n/lookup sugar keys + a `viaFields` map — the inputs {@link mergeViaFields} reconciles. */\nexport interface ViaFieldSources {\n readonly moneyFields?: Record<string, ViaDescriptor> | undefined\n readonly i18nFields?: Record<string, I18nTextDescriptor> | undefined\n readonly dictKeyFields?: Record<string, DictKeyDescriptor | StaticDictDescriptor> | undefined\n /** — lookup()/enumOf()/dict() sugar key (#650 Task 2). */\n readonly lookupFields?: Record<string, LookupDescriptor> | undefined\n readonly viaFields?: Record<string, ViaFieldSpec> | undefined\n}\n\n/** The effective per-feature field maps after merging sugar keys with `viaFields`. */\nexport interface MergedViaFields {\n readonly moneyFields: Record<string, ViaDescriptor> | undefined\n readonly i18nFields: Record<string, I18nTextDescriptor> | undefined\n readonly dictKeyFields: Record<string, DictKeyDescriptor | StaticDictDescriptor> | undefined\n /** `via(computed(fn, { deps, mode }))` entries (#638 Task 7) — there is no `computed`\n * sugar KEY to merge against here (unlike money/i18n/dictKey); `collection-config.ts`\n * unions this with the `computed:` option's own entries before splitting by mode. */\n readonly computedFields: Record<string, ComputedDescriptor> | undefined\n /** `lookupFields` sugar key merged with `via(lookup(...))`/`via(enumOf(...))`/`via(dict(...))`\n * entries (#650 Task 2) — a SEPARATE binding from i18n; `dictKey()`/`staticDict()` stay\n * routed onto `dictKeyFields`/the i18n binding (the alias, unchanged). */\n readonly lookupFields: Record<string, LookupDescriptor> | undefined\n}\n\n/**\n * Merge `viaFields` (the {@link via} composer) with the money/i18n sugar\n * keys into the effective maps every consumer reads — the kernel's\n * `compileVias` (the `ViaPipeline` bindings) and `vault.ts`'s own\n * i18n/dict registries (put-time validation, dict-join/search resolution)\n * both call this so a field declared via `viaFields` behaves identically to\n * one declared under its feature's sugar key.\n *\n * Each `viaFields` entry's descriptors are grouped by `_viaBrand`; an\n * `'i18n'`-branded descriptor further splits by shape (i18nText vs\n * dictKey/staticDict) via the existing descriptor-shape predicates. A field\n * name declared in BOTH a sugar key and `viaFields` throws `ValidationError`\n * — one declaration site per field (#623 Task 9).\n */\nexport function mergeViaFields(sources: ViaFieldSources): MergedViaFields {\n // Sugar-vs-sugar collision (review fix): dictKeyFields and lookupFields\n // naming the same field is otherwise silently ambiguous — mirrors the\n // viaFields-vs-sugar check below (#623 Task 9), one declaration site per field.\n for (const field of Object.keys(sources.dictKeyFields ?? {})) {\n if (sources.lookupFields && field in sources.lookupFields) {\n throw new ValidationError(\n `mergeViaFields(): field \"${field}\" is declared in both \\`dictKeyFields\\` and \\`lookupFields\\` — declare it in one place only.`,\n )\n }\n }\n if (!sources.viaFields || Object.keys(sources.viaFields).length === 0) {\n return {\n moneyFields: sources.moneyFields, i18nFields: sources.i18nFields, dictKeyFields: sources.dictKeyFields,\n computedFields: undefined, lookupFields: sources.lookupFields,\n }\n }\n const sugarFieldNames = new Set([\n ...Object.keys(sources.moneyFields ?? {}),\n ...Object.keys(sources.i18nFields ?? {}),\n ...Object.keys(sources.dictKeyFields ?? {}),\n ...Object.keys(sources.lookupFields ?? {}),\n ])\n const viaMoney: Record<string, ViaDescriptor> = {}\n const viaI18nText: Record<string, I18nTextDescriptor> = {}\n const viaDictKey: Record<string, DictKeyDescriptor | StaticDictDescriptor> = {}\n const viaComputed: Record<string, ComputedDescriptor> = {}\n const viaLookup: Record<string, LookupDescriptor> = {}\n for (const [field, spec] of Object.entries(sources.viaFields)) {\n if (sugarFieldNames.has(field)) {\n throw new ValidationError(\n `via(): field \"${field}\" is declared via both a sugar key and \\`viaFields\\` — declare it in one place only.`,\n )\n }\n for (const descriptor of spec.descriptors) {\n if (descriptor._viaBrand === 'money') {\n viaMoney[field] = descriptor\n } else if (descriptor._viaBrand === 'i18n') {\n if (isI18nTextDescriptor(descriptor)) viaI18nText[field] = descriptor\n else if (isDictKeyDescriptor(descriptor) || isStaticDictDescriptor(descriptor)) viaDictKey[field] = descriptor\n } else if (descriptor._viaBrand === 'computed') {\n viaComputed[field] = descriptor as ComputedDescriptor\n } else if (descriptor._viaBrand === 'lookup' && isLookupDescriptor(descriptor)) {\n viaLookup[field] = descriptor\n } else {\n throw new ValidationError(`via(): field \"${field}\" has a descriptor with unrecognized _viaBrand \"${descriptor._viaBrand}\" — via() only supports money/i18n/computed/lookup descriptors today.`)\n }\n }\n }\n return {\n moneyFields: Object.keys(viaMoney).length > 0 ? { ...(sources.moneyFields ?? {}), ...viaMoney } : sources.moneyFields,\n i18nFields: Object.keys(viaI18nText).length > 0 ? { ...(sources.i18nFields ?? {}), ...viaI18nText } : sources.i18nFields,\n dictKeyFields: Object.keys(viaDictKey).length > 0 ? { ...(sources.dictKeyFields ?? {}), ...viaDictKey } : sources.dictKeyFields,\n computedFields: Object.keys(viaComputed).length > 0 ? viaComputed : undefined,\n lookupFields: Object.keys(viaLookup).length > 0 ? { ...(sources.lookupFields ?? {}), ...viaLookup } : sources.lookupFields,\n }\n}\n\n/** Maps each per-family field-map's option key to its binding family name — used by\n * {@link guardCrossBindingFieldCollisions}/{@link guardReconcileCollisions} to tell a genuine\n * cross-family collision apart from the SAME family surfaced through two sugar keys\n * (`i18nFields` + `dictKeyFields` both feed the ONE 'i18n' binder — not this guard's job; a\n * family's own duplicate handling stays wherever it already lives). Moved here from\n * `collection-config.ts` (#664 Part 1) — that module now imports `guardCrossBindingFieldCollisions`\n * back from here instead (a circular import the other way: `collection-config.ts` already\n * imports FROM this module for `mergeViaFields`). Module-private — only the two guards above,\n * both in this file, read it. */\nconst VIA_FIELD_MAP_FAMILY: Readonly<Record<string, string>> = {\n moneyFields: 'money', i18nFields: 'i18n', dictKeyFields: 'i18n', lookupFields: 'lookup',\n classifiedFields: 'classified', blobFields: 'blob', computed: 'computed',\n}\n\n/**\n * #631 — declare-time cross-binding same-field collision guard. Today the same field named\n * in two DIFFERENT via-binding families (e.g. the same field in both `moneyFields` and\n * `blobFields`) resolves silently by compile-order first-wins in `ViaPipeline`'s per-field\n * posture/clause lookup — undefined pipeline behavior for a config that is almost certainly a\n * mistake. `mergeViaFields` already guards sugar-vs-`viaFields` and `dictKeyFields`-vs-\n * `lookupFields` collisions (#623 Task 9); this runs one step later, in `compileVias`\n * (fresh construction) or {@link guardReconcileCollisions} (late-attach reconcile), because\n * those are the only seams that also see `classifiedFields`/`blobFields` — neither is part of\n * `ViaFieldSources`, so `mergeViaFields` never sees them.\n *\n * WHY FAMILY-BASED, NOT PROVENANCE-BASED (#631 review, round 2 — Controller ruling): a field\n * declared via `via(computed(fn), money(...))` and a field declared via two independent sugar\n * maps (`computed: { total: fn }` + `moneyFields: { total: money(...) }`) are NOT\n * distinguishable here — `mergeViaFields` folds both declaration STYLES into the IDENTICAL\n * merged per-family field maps this function receives; provenance (which style produced a given\n * map entry) is erased before this guard ever runs. Narrowing the exemption to \"only\n * via()-composed fields\" would therefore require threading a second, parallel\n * provenance-tracking data structure through `mergeViaFields` for the sole purpose of refusing a\n * config that is BEHAVIORALLY IDENTICAL to the sanctioned one — refusing it would be a\n * behavior-lock violation (breaking a legal, meaningful config), not a bug fix. The exemption is\n * therefore keyed on the FAMILY SET alone, and instead earned empirically per family (below).\n *\n * EXEMPT (test-earned, not merely asserted): `computed` colliding with EXACTLY ONE of\n * `money`/`i18n`/`lookup` on the same field. `via()`'s descriptor loop only accepts\n * money/i18n/computed/lookup `_viaBrand`s (`mergeViaFields` throws on any other brand), so a\n * computed+classified or computed+blob same-field pairing can never arise from composition — it\n * can only come from mistakenly naming the same field in `computed`/`viaFields` AND\n * `classifiedFields`/`blobFields`, which this guard still refuses. For the three families that\n * CAN legitimately arise, each is pinned by an end-to-end runtime test proving the composition\n * does something real (not just \"doesn't throw\") — see `computed/virtual.test.ts`:\n * - money: the \"composed grammar\" tests (materialized-mode money formatting the computed\n * output; the ORIGINAL evidence this exemption started from — see the money DOES/does NOT\n * format the computed output pair).\n * - i18n (dictKey) / lookup (dict()): the \"composed grammar — computed + i18n/lookup\n * families (#631 collision-guard exemption pins)\" block, BOTH declaration styles\n * (`via(computed(...), dictKey(...)/dict(...))` and the two-independent-sugar-maps form),\n * materialized mode — proven to dress `<field>Label` off the computed output identically\n * either way (the provenance-erasure claim above, empirically confirmed). Virtual mode for\n * both families hits the SAME present-ORDER limitation money's own virtual composed-grammar\n * test already documents (i18n/lookup's `present()` runs BEFORE computed's — a virtual field\n * is never stored, so there is nothing to dress yet); pinned as a known limitation, not\n * grounds to drop the family from the exemption (materialized mode is what proves the family\n * genuinely composes).\n *\n * 3-CLAIMANT TIGHTENING (#631 review, round 2): the exemption requires EXACTLY TWO claimant\n * source-keys, not just two families. A field named in `computed` + BOTH `i18nFields` AND\n * `dictKeyFields` collapses to the same two families (`{computed, i18n}` — `dictKeyFields`\n * shares the `i18n` family) but is a genuine THREE-claimant collision: two independent i18n\n * sugar keys both claiming the field is itself a mistake this guard exists to catch, and must\n * not slip through because the family SET happens to match the earned exemption's shape.\n */\nexport function guardCrossBindingFieldCollisions(\n fieldMaps: Readonly<Record<string, Record<string, unknown> | undefined>>,\n // Minor fix (opus task review on #664a) — caller-accurate error prefix: fresh construction\n // (`collection-config.ts`) keeps the old default; {@link guardReconcileCollisions} (the\n // late-attach reconcile path) passes its OWN name instead of this function silently claiming\n // to be `compileVias()` on a call it never made.\n callerPrefix = 'compileVias()',\n): void {\n const claimantsByField = new Map<string, Set<string>>()\n for (const [sourceKey, map] of Object.entries(fieldMaps)) {\n for (const field of Object.keys(map ?? {})) {\n const claimants = claimantsByField.get(field) ?? new Set<string>()\n claimants.add(sourceKey)\n claimantsByField.set(field, claimants)\n }\n }\n for (const [field, sourceKeys] of claimantsByField) {\n const families = new Set([...sourceKeys].map((key) => VIA_FIELD_MAP_FAMILY[key]))\n if (families.size < 2) continue // same family via two sugar keys (e.g. i18n/dictKey) — not this guard's job\n // Exactly two CLAIMANTS (not just two families) — see \"3-CLAIMANT TIGHTENING\" above.\n if (sourceKeys.size === 2 && families.has('computed')) {\n const other = [...families].find((f) => f !== 'computed')\n if (other === 'money' || other === 'i18n' || other === 'lookup') continue // composed grammar, test-earned (#638/#631)\n }\n const keys = [...sourceKeys].sort().map((k) => `\\`${k}\\``)\n const joined = keys.length === 2 ? keys.join(' and ') : `${keys.slice(0, -1).join(', ')}, and ${keys[keys.length - 1]}`\n throw new ValidationError(\n `${callerPrefix}: field \"${field}\" is declared in both ${joined} — a field cannot be claimed by two ` +\n 'different via-binding families. Declare it in one place only.',\n )\n }\n}\n\n/**\n * #664 Part 1 — the late-attach reconcile-path sibling of {@link guardCrossBindingFieldCollisions}.\n * `vault.ts`'s reconcile ladder (a second-or-later `vault.collection(name, {...})` call on an\n * ALREADY-open collection) never ran the fresh-construction guard above, so two probe recipes\n * slipped through (round-2 fable review, 2026-07-13):\n *\n * - **(a) incoming×incoming** — the SAME reconcile call names a field in two different\n * families (e.g. `moneyFields`+`blobFields` both claiming `\"amount\"`). Fix: re-run\n * {@link guardCrossBindingFieldCollisions} verbatim over THIS call's own merged field maps —\n * identical semantics to fresh construction, just invoked one call later.\n * - **(b) existing×incoming** — an EARLIER call already compiled a binding covering a field\n * (money reconciled onto it, or it shipped with the collection's first declaration), and\n * THIS call's incoming family map claims the SAME field for a DIFFERENT family (e.g. call-1\n * `classifiedFields:['ssn']`, call-2 `moneyFields:{ssn}`) — undetectable by (a) alone since\n * the collision spans two calls. Read via the LIVE collection's compiled bindings\n * (`coll._via.bindings`): each `NoydbVia.covers(field)` (`via/index.ts`) plus its `brand` tells us\n * which family already owns the field, mapped through the SAME {@link VIA_FIELD_MAP_FAMILY}\n * the incoming side uses — no new collection.ts surface needed.\n *\n * Both sub-checks honor the SAME #631 exemption (`{computed,money}`/`{computed,i18n}`/\n * `{computed,lookup}`, exactly-two-claimants) as the fresh guard — a composition that would be\n * legal in one `vault.collection()` call (`via(computed(fn), money(...))`) must stay legal when\n * split across two calls (computed declared fresh, money late-attached), since the two paths are\n * behaviorally equivalent by the same provenance-erasure argument {@link guardCrossBindingFieldCollisions}\n * documents. `existingFamilies` is collected as a SET (every binding covering the field, not just\n * the first match) so an already-legally-composed pair (e.g. existing `{computed, money}`) is\n * checked against the incoming family individually — a THIRD family colliding with either half\n * is still refused.\n */\nexport function guardReconcileCollisions(\n existingVia: ViaPipeline | undefined,\n incomingFieldMaps: Readonly<Record<string, Record<string, unknown> | undefined>>,\n): void {\n guardCrossBindingFieldCollisions(incomingFieldMaps, 'guardReconcileCollisions()') // (a) incoming×incoming\n if (!existingVia) return\n // `taint` is a posture OVERLAY, not a field-owning family — under `sealAll` its `covers()` is\n // true for every non-`_` field, so it must never be mapped through VIA_FIELD_MAP_FAMILY here\n // (same exclusion precedent as via/graph-wiring.ts's `.filter(b => b.brand !== 'taint')`).\n const existingBindings: readonly NoydbVia[] = existingVia.bindings.filter((b) => b.brand !== 'taint')\n for (const [sourceKey, map] of Object.entries(incomingFieldMaps)) {\n const incomingFamily = VIA_FIELD_MAP_FAMILY[sourceKey]\n if (incomingFamily === undefined) continue\n for (const field of Object.keys(map ?? {})) {\n const existingFamilies = new Set(\n existingBindings.filter((b) => b.covers?.(field)).map((b) => b.brand),\n )\n for (const existingFamily of existingFamilies) {\n if (existingFamily === incomingFamily) continue // same family — first-wins on the _apply* side handles it\n const isExempt = (existingFamily === 'computed' && (incomingFamily === 'money' || incomingFamily === 'i18n' || incomingFamily === 'lookup'))\n || (incomingFamily === 'computed' && (existingFamily === 'money' || existingFamily === 'i18n' || existingFamily === 'lookup'))\n if (isExempt) continue // composed grammar, test-earned (#638/#631) — legal fresh, stays legal late\n throw new ValidationError(\n `vault.collection(): field \"${field}\" is already bound by the \"${existingFamily}\" via family on this ` +\n `collection — an incoming \\`${sourceKey}\\` declaration cannot claim it for a different family ` +\n `(\"${incomingFamily}\"). Declare it in one place only.`,\n )\n }\n }\n }\n}\n","import type { NoydbVia, ViaPosture, ViaWriteCtx, ViaReadCtx, ViaCryptoCtx, SealedSlotRef, ViaEraseCtx, ViaEraseReport } from './index.js'\nimport { ValidationError, FieldNotQueryableError } from '../errors.js'\n\n/** Opaque per-clause query payload carried on FieldClause (replaces the money-only slot). */\nexport interface ViaClause {\n readonly brand: string\n readonly payload: unknown\n}\n\n/**\n * The graph-computed taint overlay (#638 Task 3) — `postureFor`'s\n * assignment→enforcement bridge. `postures`/`sealFields` are the\n * enforcement-facing shapes `via/taint-binding.ts#buildTaintOverlay`\n * produces from `ViaGraph.taintedPostures`/`taintSealedFields`;\n * `provenance` (optional — introspection only, never consulted by\n * `postureFor`) is `ViaGraph.taintProvenance`'s output, surfaced by\n * `describe()`.\n */\nexport interface ViaTaintOverlay {\n readonly postures: ReadonlyMap<string, ViaPosture>\n readonly sealFields: ReadonlySet<string>\n readonly provenance?: ReadonlyMap<string, readonly string[]>\n /** #642 — the whole-record floor for a derivation/MV/overlay OUTPUT collection (the '*' target's\n * folded, clamped effective posture). postureFor falls back to it for ANY field; redactForExport\n * picks it up per-field; a sealed default drives taintBinding's sealAllFields mode. O(1) read. */\n readonly defaultPosture?: ViaPosture\n}\n\nexport class ViaPipeline {\n /**\n * Present-phase-ONLY order (#665, corrected under #665 review) — a stable\n * THREE-WAY partition of `bindings` computed once here at construction:\n * every `'money'`-brand binding first (existing relative order), then\n * every `'computed'`-brand binding (existing relative order), then\n * everything else (existing relative order). `present()` folds over this\n * instead of `bindings` so a `mode: 'virtual'` computed field's value\n * exists before i18n/lookup's dressing `present()` hooks run on it\n * (today's `compileVias` order is money→i18n→lookup→classified→\n * blob→computed, `collection-config.ts:554`, so dressing unconditionally\n * ran BEFORE the value it dresses existed). This reorder is binding-level,\n * not conditioned on any particular field composition — it applies to\n * EVERY collection that compiles a `'computed'` binding at all, not only\n * ones stacking a dresser on the SAME field as a computed one. EVERY other\n * phase (`ingest`/`encodeWrite`/`encodeAtRest`/`enforceWrite`/etc.) keeps\n * folding over `bindings` unchanged — those write/query phases need\n * money-first (`_applyMoneyFields` PREPENDS money, `_applyClassifiedFields`\n * APPENDS classified to preserve it, `kernel/collection.ts:1275-1284,1364-\n * 1368`).\n *\n * Money is deliberately carved OUT of the generic \"everything else\" slice\n * and kept FIRST — the original two-way `[computed..., rest...]` partition\n * regressed money's composed-field behavior from a benign missing-dressing\n * gap into VALUE CORRUPTION: money's `present()` DECODES its input as a\n * STORED SCALED-INT (and derives `<field>Formatted` from it) — it is not a\n * pure dressing CONSUMER like i18n/lookup, which only ADD a `<field>Label`\n * key and never rewrite the field's own value. Running money AFTER\n * computed on a field composing `computed(virtual)` + `money(...)` on\n * ITSELF means money's decode sees the virtual field's raw MAJOR-unit\n * output (e.g. `21`) and misreads it as a scaled-int, producing a\n * corrupted value (`'0.21'`) instead of the pre-#665 result (the raw `21`\n * surviving untouched, with no `Formatted` key added — a benign\n * missing-dressing gap, not a wrong value). Money-first restores money's\n * exact pre-#665 present position — byte-identical money behavior; the\n * materialized composition pins from the #631 work and the money suites\n * all ran under money-first. i18n/lookup are genuine dressing consumers\n * (they only ADD, never rewrite), so they stay after computed, which is\n * the fix #665 intended. A `'taint'` binding (appended LAST by\n * `via/graph-wiring.ts#applyTaintOverlay`) stays last here too (it's\n * neither money nor computed, so it lands at the tail of the \"everything\n * else\" slice), preserving its \"runs after computed, redacts tainted\n * virtual output\" contract (`via/taint-binding.ts`'s `taintBinding` doc\n * comment).\n *\n * Money-dressing a virtual computed field's OWN output (the composed\n * `computed(virtual) + money` case) is NOT resolved by this partition\n * alone — #669 resolves it with a separate mid-fold hook instead:\n * `NoydbVia.presentLate` runs after every binding's `present()` in this\n * money+computed segment, before the \"everything else\" segment below, so\n * money can quantize/reinterpret a virtual field's fresh MAJOR-UNITS\n * output as if it were a stored value, without perturbing this ordering\n * or the #665 invariant above it (`_presentLateBoundary` below marks\n * exactly where that mid-fold point sits within `_presentOrder`).\n */\n private readonly _presentOrder: readonly NoydbVia[]\n /** #669 — index into `_presentOrder` where the money+computed segment ends and the\n * \"everything else\" segment begins (`moneyVias.length + computedVias.length`);\n * `present()` runs every binding's `presentLate` at exactly this boundary. */\n private readonly _presentLateBoundary: number\n\n private constructor(readonly bindings: readonly NoydbVia[], readonly taint?: ViaTaintOverlay) {\n const moneyVias = bindings.filter((b) => b.brand === 'money')\n const computedVias = bindings.filter((b) => b.brand === 'computed')\n const restBindings = bindings.filter((b) => b.brand !== 'money' && b.brand !== 'computed')\n this._presentOrder = [...moneyVias, ...computedVias, ...restBindings]\n this._presentLateBoundary = moneyVias.length + computedVias.length\n }\n\n /** undefined when there is nothing to enforce — the zero-via fast path is\n * `this.via === undefined` (#553: keeps an all-plain collection sync). A\n * `'*'`-defaulted output collection (#642) counts as \"something to enforce\"\n * even with zero field-specific postures and zero bindings. */\n static build(bindings: readonly NoydbVia[], taint?: ViaTaintOverlay): ViaPipeline | undefined {\n if (bindings.length === 0 && (!taint || (taint.postures.size === 0 && taint.defaultPosture === undefined))) return undefined\n return new ViaPipeline(bindings, taint)\n }\n\n /** Refuse a write before crypto runs: awaits each binding's `enforceWrite` in order — first throw wins. */\n async enforceWrite(record: Record<string, unknown>, ctx: ViaWriteCtx): Promise<void> {\n for (const b of this.bindings) if (b.enforceWrite) await b.enforceWrite(record, ctx)\n }\n\n ingest(record: Record<string, unknown>): Record<string, unknown> {\n let r = record\n for (const b of this.bindings) if (b.ingest) r = b.ingest(r)\n return r\n }\n\n canonicalizeStored(record: Record<string, unknown>): Record<string, unknown> {\n let r = record\n for (const b of this.bindings) if (b.canonicalizeStored) r = b.canonicalizeStored(r)\n return r\n }\n\n async encodeWrite(record: Record<string, unknown>, ctx: ViaWriteCtx): Promise<Record<string, unknown>> {\n let r = record\n for (const b of this.bindings) if (b.encodeWrite) r = await b.encodeWrite(r, ctx)\n return r\n }\n\n /**\n * Final write-pipeline stage: folds each binding's `encodeAtRest` in\n * order, threading the record and accumulating the sealed-slot map. A\n * field belongs to exactly one via feature — two bindings sealing the\n * same field is a brand-keyed collision and throws.\n */\n async encodeAtRest(\n record: Record<string, unknown>,\n crypto: ViaCryptoCtx,\n ): Promise<{ record: Record<string, unknown>; sealed?: Record<string, SealedSlotRef> }> {\n let r = record\n let sealed: Record<string, SealedSlotRef> | undefined\n const sealedBy = new Map<string, string>()\n for (const b of this.bindings) {\n if (!b.encodeAtRest) continue\n const result = await b.encodeAtRest(r, crypto)\n r = result.record\n if (!result.sealed) continue\n for (const [field, ref] of Object.entries(result.sealed)) {\n const priorBrand = sealedBy.get(field)\n if (priorBrand !== undefined) {\n throw new ValidationError(\n `via encodeAtRest: field \"${field}\" sealed by binding \"${priorBrand}\" is also sealed by binding \"${b.brand}\"`,\n )\n }\n sealedBy.set(field, b.brand)\n sealed ??= {}\n sealed[field] = ref\n }\n }\n return sealed ? { record: r, sealed } : { record: r }\n }\n\n /** First read-pipeline stage: folds each binding's `decodeAtRest` in order. */\n async decodeAtRest(\n record: Record<string, unknown>,\n sealed: Record<string, SealedSlotRef>,\n crypto: ViaCryptoCtx,\n opts: { asHandles: boolean },\n ): Promise<Record<string, unknown>> {\n let r = record\n for (const b of this.bindings) if (b.decodeAtRest) r = await b.decodeAtRest(r, sealed, crypto, opts)\n return r\n }\n\n async present(record: Record<string, unknown>, ctx: ViaReadCtx): Promise<Record<string, unknown>> {\n let r = record\n for (let i = 0; i < this._presentLateBoundary; i++) {\n const b = this._presentOrder[i]!\n if (b.present) r = await b.present(r, ctx)\n }\n for (const b of this.bindings) if (b.presentLate) r = await b.presentLate(r, ctx)\n for (let i = this._presentLateBoundary; i < this._presentOrder.length; i++) {\n const b = this._presentOrder[i]!\n if (b.present) r = await b.present(r, ctx)\n }\n return r\n }\n\n buildClause(field: string, op: string, value: unknown): ViaClause | undefined {\n for (const b of this.bindings) {\n const payload = b.buildClause?.(field, op, value)\n if (payload !== undefined) return { brand: b.brand, payload }\n }\n return undefined\n }\n\n evaluateClause(clause: ViaClause, actual: unknown, op: string): boolean {\n const b = this.bindings.find((x) => x.brand === clause.brand)\n // buildClause and evaluateClause are produced/consumed by the same binding by construction.\n return b?.evaluateClause ? b.evaluateClause(actual, op, clause.payload) : false\n }\n\n /**\n * Resolve a `buildClause` payload to an index-probe operand (#625) —\n * mirrors `evaluateClause`'s brand dispatch. `undefined` (a binding\n * with no `indexProbe`, or one that declines to probe this op/payload)\n * means the caller (`candidateRecords()`) must fall back to a scan.\n */\n // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents\n indexProbe(clause: ViaClause, op: string): unknown | undefined {\n const b = this.bindings.find((x) => x.brand === clause.brand)\n return b?.indexProbe ? b.indexProbe(op, clause.payload) : undefined\n }\n\n /**\n * Resolve a raw STORED field value to its canonical eager-index bucket\n * key (#672) — folds every binding's `canonicalizeIndexKey`, first\n * non-undefined wins (same fold discipline as `buildClause`). `undefined`\n * means no binding claims `field` (or the value can't be canonicalized)\n * — the caller buckets the raw stringified value, unchanged from before\n * this hook existed.\n */\n canonicalizeIndexKey(field: string, rawValue: unknown): string | undefined {\n for (const b of this.bindings) {\n const key = b.canonicalizeIndexKey?.(field, rawValue)\n if (key !== undefined) return key\n }\n return undefined\n }\n\n decodeResults(record: unknown): unknown {\n let r = record\n for (const b of this.bindings) if (b.decodeResults) r = b.decodeResults(r)\n return r\n }\n\n /** undefined = no binding covers the field → caller falls back to generic compare. */\n compareForOrder(field: string, a: unknown, b: unknown): number | undefined {\n for (const bind of this.bindings) {\n const c = bind.compareForOrder?.(field, a, b)\n if (c !== undefined) return c\n }\n return undefined\n }\n\n /** undefined = no binding resolves an order-sort label for `key` at `field`/`locale` (#650 Task 7 —\n * the `orderBy(..., {by:'label'})` per-call-locale channel `compareForOrder` above can't serve). */\n resolveOrderLabel(field: string, key: string, locale: string | undefined): string | undefined {\n for (const bind of this.bindings) {\n const label = bind.resolveOrderLabel?.(field, key, locale)\n if (label !== undefined) return label\n }\n return undefined\n }\n\n /**\n * Which posture governs `field`, if any binding covers it — `undefined`\n * means no binding declares `field` (the generic, non-via query path\n * applies). #629 Task 8's posture consumer: `.where()`/`.orderBy()`\n * consult this before building/evaluating a clause, refusing fields whose\n * posture is `queryable: 'none'` (e.g. blob); every other posture\n * ('det-exact'/'ordered'/'full') is left to the existing per-binding\n * buildClause/evaluateClause/compareForOrder machinery, unchanged.\n *\n * #638 Task 3: the graph-computed taint overlay is consulted FIRST — a\n * derived field's assigned (most-restrictive-of-sources) posture wins over\n * whatever a binding would otherwise report for that field name (no\n * binding covers a computed/derived field today, so this never actually\n * shadows one — see `via/taint-binding.ts`'s `taintBinding.covers`, which\n * only claims the sealed subset for `encodeAtRest`/`decodeAtRest`, not for\n * this lookup).\n */\n postureFor(field: string): ViaPosture | undefined {\n const t = this.taint?.postures.get(field)\n if (t) return t\n for (const b of this.bindings) {\n if (b.covers?.(field)) return b.posture\n }\n // #642 — a '*'-defaulted output collection's whole-record floor: O(1) read,\n // no fold (the fold ran once at applyTaintOverlay/reapply time).\n return this.taint?.defaultPosture\n }\n\n /**\n * Refuse any field-based reducer over a `queryable: 'none'` field (blob) —\n * metadata-only: walks each reducer's `.field` and checks posture, no\n * rewriting. Reducers with no `.field` (e.g. `count()`) are skipped.\n *\n * Shared by `wrapReducers` below (which ALSO applies each binding's\n * rewrite, e.g. money's exact-BigInt reducer swap) and by\n * `ScanBuilder.aggregate()` (#629 Task 8 review fix wave 1), which must\n * call THIS, not `wrapReducers` — wiring full `wrapReducers` into\n * `ScanBuilder.aggregate()` would newly activate money/i18n reducer\n * wrapping on a path that has never run it, a parity-breaking behavior\n * change for existing brands.\n */\n refuseUnqueryableReducers<S>(spec: S): void {\n for (const reducer of Object.values(spec as unknown as Record<string, { readonly field?: string }>)) {\n const field = reducer?.field\n if (field !== undefined && this.postureFor(field)?.queryable === 'none') {\n throw new FieldNotQueryableError(field)\n }\n }\n }\n\n /**\n * Rewrite an aggregate spec (money exact reducers), then refuse any\n * field-based reducer over a `queryable: 'none'` field (blob) — the same\n * posture gate `.where()`/`.orderBy()` apply, extended to `.aggregate()`\n * (both the bare-spec and builder forms funnel through here).\n */\n wrapReducers<S>(spec: S): S {\n this.refuseUnqueryableReducers(spec)\n let s: unknown = spec\n for (const b of this.bindings) if (b.wrapReducers) s = b.wrapReducers(s)\n return s as S\n }\n\n /**\n * Deliberate export-layer redaction (#629 Task 9's posture consumer):\n * for every OWN field the decoded record carries, if the covering\n * binding's posture declares `exportable: false` (classified today;\n * money/i18n/blob are all `true`), replace the value with\n * {@link EXPORT_REDACTION_MARKER} — the same `'[sealed]'` string\n * `SealedHandle.toJSON()` (`kernel/types.ts`) already emits, so this is\n * byte-parity with today's accidental redaction, now independent of the\n * field's runtime shape. `SealedHandle.toJSON()` stays untouched as\n * defense-in-depth: a record read via `collection.get()` and\n * JSON.stringify'd outside `exportStream()` still gets the accident's\n * redaction on its own. Never mutates the input; returns a new object\n * only when a field was actually redacted.\n */\n redactForExport(record: Record<string, unknown>): Record<string, unknown> {\n let out: Record<string, unknown> | undefined\n for (const field of Object.keys(record)) {\n if (this.postureFor(field)?.exportable === false) {\n out ??= { ...record }\n out[field] = EXPORT_REDACTION_MARKER\n }\n }\n return out ?? record\n }\n\n /**\n * Shared fold over a subset of `this.bindings`: runs each binding's\n * `erase`, concatenating shredded/retainedShared counts and residue.\n * Consults `posture.forgettable` (#629 Task 10) — a binding declaring\n * `forgettable: false` is skipped even if it defines `erase` (none does\n * today; a future non-forgettable binding is supported without a brand check).\n */\n private async foldErase(ctx: ViaEraseCtx, bindings: readonly NoydbVia[]): Promise<ViaEraseReport> {\n let shredded = 0\n let retainedShared = 0\n const residue: unknown[] = []\n for (const b of bindings) {\n if (!b.erase || b.posture.forgettable === false) continue\n const report = await b.erase(ctx)\n shredded += report.shredded\n retainedShared += report.retainedShared ?? 0\n residue.push(...report.residue)\n }\n return retainedShared > 0 ? { shredded, residue, retainedShared } : { shredded, residue }\n }\n\n /** `forget()`'s per-ref erasure door: folds every binding's `erase`. */\n async erase(ctx: ViaEraseCtx): Promise<ViaEraseReport> {\n return this.foldErase(ctx, this.bindings)\n }\n\n /**\n * `forget()`'s SEALED-posture-only erase fold (#629 Task 10, `Collection._onViaErase`'s\n * one caller) — classified today; metadata-filtered on\n * `posture.encryptedAtRest`, not brand-checked. `undefined` when no\n * sealed-posture binding is compiled in — `vault.ts` then falls back to\n * its own bare-`sensitive` classification, which no via binding covers.\n */\n async eraseSealed(ctx: ViaEraseCtx): Promise<ViaEraseReport | undefined> {\n const sealed = this.bindings.filter((b) => b.posture.encryptedAtRest === 'sealed')\n return sealed.length === 0 ? undefined : this.foldErase(ctx, sealed)\n }\n\n /** True iff any binding implements decodeResults (query fast-path gating). */\n get hasResultDecode(): boolean {\n return this.bindings.some((b) => b.decodeResults !== undefined)\n }\n\n /**\n * True iff any binding declares an at-rest hook (`encodeAtRest`/\n * `decodeAtRest`) — the codec boundary's async-stack gate (#629 Task 3\n * consults this to choose between the hook path and today's inline\n * sealed-slot path; a stack with only sync hooks, e.g. money-only, stays\n * `false`).\n */\n get hasAtRestHooks(): boolean {\n return this.bindings.some((b) => b.encodeAtRest !== undefined || b.decodeAtRest !== undefined)\n }\n\n /**\n * Fold every binding's `describeFragment()` into one `brand -> fragment`\n * map (#650 Task 7 — the first-ever consumer; `describeFragment` was\n * declared at `via/index.ts:136` since #623 with zero callers until this task).\n * `undefined` when no compiled binding implements it. Consumed by\n * `Collection.describe()`/`describeAsync()`, threaded to `buildDescription`\n * as `BuildDescriptionInput.viaFragments`.\n */\n describeFragments(): Record<string, Record<string, unknown>> | undefined {\n let out: Record<string, Record<string, unknown>> | undefined\n for (const b of this.bindings) {\n const f = b.describeFragment?.()\n if (f !== undefined) { out ??= {}; out[b.brand] = f }\n }\n return out\n }\n}\n\n/**\n * The marker `redactForExport` writes for a non-exportable field —\n * intentionally the same literal `SealedHandle.toJSON()` (`kernel/types.ts`)\n * returns, so the two independent redaction layers (deliberate + accident)\n * produce byte-identical export output. Duplicated, not imported, because\n * `SealedHandle.toJSON()` is untouched by #629 Task 9 (belt-and-braces —\n * `via/export-posture-b.test.ts` asserts both layers agree on this string).\n */\nexport const EXPORT_REDACTION_MARKER = '[sealed]'\n\n/**\n * Structural shape `exportRedact` needs from a collection: just the typed\n * `_via` accessor `Collection` exposes (`kernel/collection.ts`, #634). A\n * named interface rather than the real `Collection` type, because\n * `collection.ts` imports `ViaPipeline` from this module — importing\n * `Collection` back here would be circular.\n */\ninterface HasViaPipeline {\n readonly _via: ViaPipeline | undefined\n}\n\n/**\n * Widened sibling of {@link HasViaPipeline}: `via/graph-wiring.ts`'s\n * `applyTaintOverlay` (#666) needs to REASSIGN the live pipeline, not just\n * read it — `_setVia` is `Collection`'s typed writer seam (`kernel/\n * collection.ts`, beside `_via`), replacing the earlier untyped `coll as {\n * via; codec: { setVia } }` cast. Exported (unlike `HasViaPipeline`) because\n * its one consumer lives in a different module.\n */\nexport interface HasWritableViaPipeline extends HasViaPipeline {\n _setVia(pipeline: ViaPipeline | undefined): void\n}\n\n/**\n * `vault.ts`'s `exportStream()` reach-in (#629 Task 9): apply the owning\n * collection's export redaction to one decoded record. Typed via {@link\n * HasViaPipeline} against `Collection`'s `_via` accessor (#634) — replaces\n * the earlier untyped any-cast reach-in.\n */\nexport function exportRedact(coll: HasViaPipeline, record: unknown): unknown {\n if (record === null || typeof record !== 'object') return record\n const via = coll._via\n return via ? via.redactForExport(record as Record<string, unknown>) : record\n}\n","/**\n * Collection construction config — the PURE half of the `Collection`\n * constructor.\n *\n * `resolveCollectionConfig` takes the raw `CollectionOpts` the Vault threads in\n * and resolves every `?? default`, every normalized/derived field, and runs the\n * pure construction-time validations (embeddings-on-CRDT, money-field paths,\n * deterministic-risk acknowledgement). It holds **no `this`** and performs no\n * external side effect — the only objects it allocates (`Set`s, `VectorSet`,\n * the CEK `Lru`) are the same instances the collection then owns by reference.\n *\n * The `this`-dependent construction (the search-index store whose persisted\n * callback closes over `this.searchContext()`, the `RecordCodec`, and the\n * SyncEngine conflict-resolver registration) stays in the constructor — those\n * genuinely capture the live instance (and the conflict-resolver closures close\n * over `conflictPolicy: ConflictPolicy<T>`, whose invariant-in-T custom-merge\n * signature can't be exposed via a method without breaking `Collection<T>`\n * assignability to `Collection<unknown>`).\n */\nimport type { StrategyBag } from '../port/with/strategies.js'\nimport type { NoydbStore, ConflictPolicy, CollectionConflictResolver, HistoryConfig, TierMode, CrossTierAccessEvent, VdigFieldPolicy } from './types.js'\nimport type { EnclaveKey } from './enclave/index.js'\nimport type { UnlockedKeyring } from '../with-party/team/keyring.js'\nimport type { NoydbEventEmitter } from './events.js'\nimport type { WriteQueueTracker } from './write-queue.js'\nimport type { WriteHookRegistry } from '../port/with/write-hooks.js'\nimport type { ServiceBus } from '../port/with/service-bus.js'\nimport type { SchemaUpdateGate } from '../with-shape/schema-update/gate.js'\nimport type { SchemaFenceController } from '../with-shape/schema-update/fence-controller.js'\nimport type { StandardSchemaV1 } from './schema.js'\nimport type { LedgerStore } from '../with-commit/history/ledger/index.js'\nimport type { CrdtMode } from '../with-commit/crdt/crdt.js'\n// CrdtStrategy imported directly from ./types.js (not with-commit/crdt/strategy.js)\n// — #667: collection-config.ts sits in the shared dts chunk with types.ts, so\n// routing this through strategy.ts's re-export closed a cycle in the dts rollup\n// graph. NO_CRDT (a runtime value, only defined in strategy.ts) still comes from there.\nimport type { ObjectProjection } from '../with-shape/blobs/object-projection.js'\nimport type { BlobFieldsConfig } from '../with-shape/blobs/blob-compaction.js'\nimport type { IndexDef } from '../with-lookup/indexing/eager-indexes.js'\nimport type { I18nTextDescriptor, DictKeyDescriptor, StaticDictDescriptor, DictionaryHandle } from '../port/with/i18n-strategy.js'\n// #650 Task 2 — `LookupDescriptor` type-only, mirroring the i18n descriptor\n// imports above; no eager value import needed (lookup()/enumOf()/dict()\n// each call `linkLookupVia()` themselves, so `viaBinder('lookup')` is\n// already resolvable by the time a `lookupFields` entry exists).\nimport type { LookupDescriptor, MaterializedBacking } from '../port/with/lookup-strategy.js'\nimport { buildPresentForJoin } from '../port/with/lookup-strategy.js'\nimport type { ComputedFields, ComputedFn, ComputedFieldEntry } from '../with-formula/computed/index.js'\nimport type { RollupDeleteIntent } from './via/dispatch.js'\n// #638 Task 7 — the value import (not just `import type`) forces the port module's eager\n// `linkComputedVia()` to run whenever this file loads (collection-config.ts is always in the\n// dependency graph), so `viaBinder('computed')` is resolvable before `compileVias` needs it.\nimport '../port/with/computed-strategy.js'\nimport type { ComputedDescriptor } from '../port/with/computed-strategy.js'\nimport {\n resolveClassifiedFields, guardClassifiedCompat,\n type ClassifiedEntry, type ResolvedClassified, type ClassifiedGuardCtx, type ClassifiedViaConfig,\n} from '../port/with/classified-strategy.js'\nimport { ClassifiedConfigError, ValidationError, UnsupportedTierCompositionError } from './errors.js'\nimport type { FieldRef, Grain } from './via/graph.js'\nimport type { FieldMeta } from '../with-shape/introspection/field-meta.js'\nimport type { CollectionMeta } from '../with-shape/introspection/meta.js'\nimport type { RefDescriptor } from './refs.js'\nimport type { JoinableSource } from './query/index.js'\nimport { VectorSet, type EmbeddingDescriptor } from '../with-lookup/embeddings/index.js'\nimport { Lru } from './cache/index.js'\nimport type { ReadOnlyVaultFacade } from '../with-audit/guards/types.js'\nimport type { DerivationRegistry } from '../with-formula/derivations/registry.js'\nimport type { TxContext } from '../with-commit/tx/transaction.js'\nimport type { MaterializedViewRegistry } from '../with-formula/materialized-views/registry.js'\nimport type { MVQueryContext } from '../with-formula/materialized-views/types.js'\nimport type { Collection, OnDirtyCallback, CacheOptions } from './collection.js'\nimport { ViaPipeline } from './via/pipeline.js'\nimport { viaBinder, type NoydbVia, type ViaDescriptor } from './via/index.js'\nimport { validateFieldMetaAtRegistration } from '../with-shape/introspection/field-meta.js'\nimport { mergeViaFields, guardCrossBindingFieldCollisions, type ViaFieldSpec } from './via/compose.js'\n\n/**\n * Raw options handed to the {@link Collection} constructor by the Vault.\n * One named type shared by the constructor and the pure resolver.\n */\nexport interface CollectionOpts<T> {\n adapter: NoydbStore\n vault: string\n name: string\n keyring: UnlockedKeyring\n encrypted: boolean\n /**\n * Every opt-in service, resolved once by `createNoydb` (#838). Replaces the\n * eleven optional `*Strategy` fields this interface used to declare, each of\n * which re-applied a `?? NO_*` default that had already been applied\n * upstream. Each entry is a tree-shake seam: an un-opted-in service holds\n * its `NO_*` stub, so the real machinery never reaches the bundle.\n */\n strategies: StrategyBag\n /**\n * Opt-in: keep the working set encrypted in RAM, decrypting on read (future phase).\n * Default false — the working set is plaintext.\n */\n ramCiphertext?: boolean\n emitter: NoydbEventEmitter\n /**\n * Vault-level in-flight write tracker. When present,\n * `put`/`delete` run inside `writeQueue.track()` so `hub.writeQueue`\n * reflects outstanding writes. Optional so direct Collection\n * construction in tests still works untracked.\n */\n writeQueue?: WriteQueueTracker | undefined\n /** Per-collection schema-update gate; `put`/`delete` await it. */\n schemaUpdateGate?: SchemaUpdateGate | undefined\n /** Vault-level fence controller; `put`/`delete` consult it. */\n schemaFence?: SchemaFenceController | undefined\n /** Hub-level write-hook registry; fired around put/delete. */\n writeHooks?: WriteHookRegistry | undefined\n /** The observe bus, threaded from Noydb. */\n subsystemBus?: ServiceBus | undefined\n /** Active transaction id supplier (null outside a transaction). */\n activeTxId?: (() => string | null) | undefined\n getDEK: (collectionName: string) => Promise<EnclaveKey>\n historyConfig?: HistoryConfig | undefined\n /**\n * When `true`, the caller explicitly provided `historyConfig` rather than\n * inheriting the vault-wide default. Used by `getConfig()` to decide\n * whether to surface `history: true` in the schema dump.\n */\n historyConfigExplicit?: boolean | undefined\n onDirty?: OnDirtyCallback | undefined\n /**\n * #693: live check for whether multi-tab coordination is active at all\n * (`Noydb._tabCoordinationActive`). When true, the shared local store may be\n * written out-of-band by another tab, so the #606 marker-id-set gate falls\n * back to an unconditional store read on re-create.\n */\n tabCoordinated?: (() => boolean) | undefined\n objectStore?: ObjectProjection | undefined\n blobFields?: BlobFieldsConfig | undefined\n /**\n * #724 Arc 10 Task 3: how `elevate()`/`demote()`/`putAtTier()` rehome a\n * SHARED blob (`refCount > 1`) it can't rewrap in place. `'isolate'`\n * (default) forks a private tier-scoped copy for the moving record and\n * releases its hold on the shared object — co-owners stay byte-for-byte\n * untouched. `'dedup'` (#741, opt-in) leaves the shared object in place;\n * the Task-1 runtime read gate still hides it, but the chunks stay\n * decryptable at rest under the flat `_blob` DEK (documented residue).\n */\n blobTierPolicy?: 'isolate' | 'dedup' | undefined\n indexes?: IndexDef[] | undefined\n /**\n * Auto-reconcile behavior for persisted-index drift on lazy-mode\n * collections. Defaults to `'off'` — operators call\n * `collection.reconcileIndex(field)` explicitly.\n *\n * - `'off'` (default): no implicit work. Same semantics as.\n * - `'dry-run'`: on first lazy-mode query, run\n * `reconcileIndex(field, { dryRun: true })` per declared field\n * and emit `index:reconciled` with the diff. Nothing is written.\n * - `'auto'`: same walk as `'dry-run'` but with `dryRun: false`.\n * Drift is repaired in-place and the fix count surfaces on the\n * event.\n *\n * Unattended long-lived processes (Workers, Node services with no\n * human operator) should set `'auto'`. Attended desktop apps should\n * leave it `'off'` and surface a manual \"rebuild indexes\" button.\n */\n reconcileOnOpen?: 'off' | 'dry-run' | 'auto'\n /**\n * Hydration mode. `'eager'` (default) loads everything into memory on\n * first access — matches behavior exactly. `'lazy'` defers loads\n * to per-id `get()` calls and bounds memory via the `cache` option.\n */\n prefetch?: boolean\n /**\n * LRU cache options. Only meaningful when `prefetch: false`. At least\n * one of `maxRecords` or `maxBytes` must be set in lazy mode — an\n * unbounded lazy cache defeats the purpose.\n */\n cache?: CacheOptions | undefined\n /**\n * Optional Standard Schema v1 validator (Zod, Valibot, ArkType,\n * Effect Schema, etc.). When set, every `put()` is validated before\n * encryption and every read is validated after decryption. See the\n * `schema` field docstring for the error semantics.\n */\n schema?: StandardSchemaV1<unknown, T> | undefined\n /** Declares this collection a satellite of `satelliteOf` (spec #591). */\n satelliteOf?: string | undefined\n /** Satellite routing table — the fields owned by this satellite (required with satelliteOf). */\n fields?: readonly string[] | undefined\n /** Registers the full-record joined handle under this name (optional; see vault.joined()). */\n joined?: string | undefined\n /**\n * Optional reference to the compartment's hash-chained ledger.\n * When present, successful mutations append a ledger entry via\n * `LedgerStore.append()`. Constructed at the Vault level and\n * threaded through — see the Vault.collection() source for\n * the wiring.\n */\n ledger?: LedgerStore | undefined\n /**\n * Optional back-reference to the owning compartment's ref\n * enforcer`).\n * Collection.put calls `enforceRefsOnPut` before the adapter\n * write; Collection.delete calls `enforceRefsOnDelete` before\n * its own adapter delete. See the `refEnforcer` field docstring\n * for the full protocol.\n */\n refEnforcer?:\n | {\n enforceRefsOnPut(collectionName: string, record: unknown): Promise<void>\n enforceRefsOnDelete(collectionName: string, id: string): Promise<void>\n /** #922 — see `Vault._deleteCascadesPossible`; consulted by `_txAtomicSafe('delete')`. */\n _deleteCascadesPossible(collectionName: string): boolean\n }\n | undefined\n /**\n * Optional back-reference to the owning compartment's join\n * resolver. When present, `query()` builds a\n * `JoinContext` so `.join(field)` can resolve through the\n * existing `ref()` declaration into the target collection.\n * Absent in tests that construct a Collection directly without\n * a vault; production usage always has one because\n * Vault.collection() passes `this` through.\n */\n joinResolver?:\n | {\n resolveSource(collectionName: string): JoinableSource | null\n resolveRef(leftCollection: string, field: string): RefDescriptor | null\n resolveDictSource?: (leftCollection: string, field: string) => JoinableSource | null\n }\n | undefined\n /** — i18nText field descriptors for locale-aware reads. */\n i18nFields?: Record<string, I18nTextDescriptor> | undefined\n /** — embedding config for write-time vector derivation + semantic retrieval. */\n embeddings?: EmbeddingDescriptor | undefined\n /** — string fields exposed to client-side `retrieve()`. */\n textIndexes?: readonly string[] | undefined\n /** — pre-build the lexical index on open (eager-only). */\n warmIndexOnOpen?: boolean | undefined\n /** — persist the lexical index as an opaque encrypted blob at `_ftindex/<name>`. */\n textIndexPersist?: boolean | undefined\n /** — dictKey field descriptors for label resolution on reads. */\n dictKeyFields?: Record<string, DictKeyDescriptor | StaticDictDescriptor> | undefined\n /** — consumer-neutral per-field descriptors. Read via getFieldMeta(). */\n fieldMeta?: Record<string, FieldMeta> | undefined\n /** — collection-level descriptive metadata. Read via getMeta(). */\n meta?: CollectionMeta | undefined\n moneyFields?: Record<string, ViaDescriptor> | undefined\n /** — declare via() composed fields; grouped by `_viaBrand` and merged with the money/i18n sugar keys above (a field in both throws). */\n viaFields?: Record<string, ViaFieldSpec> | undefined\n /** — outbound ref declarations (snapshot from vault refRegistry). Used by describe(). */\n declaredRefs?: Record<string, RefDescriptor> | undefined\n computed?: ComputedFields | undefined\n /** — declare classified() sensitive-field descriptors (sealed + riders + projections). */\n classifiedFields?: Record<string, ClassifiedEntry> | undefined\n /**\n * The forget-cascade subject key for this collection (from\n * `withForget({ subjects })`), plumbed by the Vault. Consumed by the\n * classified refusal matrix (R4: a digest-only field cannot be the subject key).\n */\n subjectKeyField?: string | undefined\n /**\n * Register a record's forget-subject ref directly (bypassing the write-hook\n * pipeline), wired by the Vault when this collection declares a forget-\n * subject field. Consumed by `putAtTier` (#766, via `TiersContext.addSubjectRef`)\n * so a record whose first write is a tier write still enters `_subject_index`.\n * `undefined` when no forget strategy declares this collection (no-op).\n */\n addSubjectRef?: ((id: string, record: unknown) => Promise<void>) | undefined\n /**\n * async callback that resolves a dict key to its label\n * for a given locale. Provided by the Vault.\n */\n dictLabelResolver?:\n | ((\n dictName: string,\n key: string,\n locale: string,\n fallback?: string | readonly string[],\n ) => Promise<string | undefined>)\n | undefined\n /**\n * Async callback to open a dynamic dictionary handle.\n * Provided by the Vault for dynamic-dict label-map resolution in\n * the search index. Static dicts bypass this.\n */\n getDictionary?: ((name: string) => Promise<DictionaryHandle>) | undefined\n /**\n * synchronous callback that validates i18nText fields\n * on put. Provided by the Vault. Throws MissingTranslationError.\n */\n i18nPutValidator?: ((record: unknown) => void) | undefined\n /** — declare lookup()/enumOf()/dict() fields (#650 Task 2 sugar key, mirrors dictKeyFields), merged with `via(lookup(...))` entries. */\n lookupFields?: Record<string, LookupDescriptor> | undefined\n /**\n * async label resolver for the `'lookup'` binding's `'static'`/`'reserved'`\n * tiers. Provided by the Vault — the SAME closure as `dictLabelResolver`\n * (static table first, else the `vault.dictionary()` handle), so a\n * native `dict()`/`lookup(static)` field resolves through identical\n * label data as its `dictKey()`/`staticDict()` alias.\n */\n lookupLabelResolver?:\n | ((dimension: string, key: string, locale: string, fallback?: string | readonly string[]) => Promise<string | undefined>)\n | undefined\n /** — the matrix (`backing:'collection'`) tier's present-time row accessor, keyed by the full\n * descriptor so it can resolve by `descriptor.key`, not the backing row's PUT-id (#651 Task 3).\n * Provided by the Vault. */\n getLookupBacking?: ((descriptor: LookupDescriptor) => (key: string) => Promise<Record<string, unknown> | undefined>) | undefined\n /** — closed-vocabulary write-time membership test (#650 Task 3). Provided by the Vault. */\n membership?: ((field: string, key: string) => boolean | Promise<boolean>) | undefined\n /** — altKeys `ingest` normalization source (#650 Task 3). Provided by the Vault. */\n getAltIndex?: ((desc: LookupDescriptor) => MaterializedBacking | undefined) | undefined\n /**\n * — sync materialized `key -> row` rows for a lookup descriptor (#650\n * Task 6, spec §5's snapshot+locale seam; matrix-tier routing added Task\n * 7). Provided by the Vault; feeds the `'lookup'` binding's\n * `compareForOrder`/`resolveOrderLabel` and this collection's\n * `presentForJoin` hook (`resolveCollectionConfig` builds the latter via\n * `buildPresentForJoin`, below).\n */\n snapshotFor?: ((descriptor: LookupDescriptor) => ReadonlyMap<string, Record<string, unknown>> | undefined) | undefined\n /**\n * translator callback from Noydb. When present, missing\n * translations for `autoTranslate: true` i18nText fields are generated\n * before the i18n validator runs.\n */\n autoTranslateHook?:\n | ((text: string, from: string, to: string, field: string, collection: string) => Promise<string>)\n | undefined\n /**\n * vault-default locale, inherited from\n * `openVault(name, { locale })` or `vault.setLocale()`.\n */\n defaultLocale?: string | undefined\n /**\n * collection-level conflict resolution policy.\n * Overrides the db-level `conflict` option for this collection only.\n */\n conflictPolicy?: ConflictPolicy<T> | undefined\n /**\n * callback to register an envelope-level resolver with the\n * SyncEngine. Provided by the Vault (wired from the SyncEngine).\n */\n onRegisterConflictResolver?: ((name: string, resolver: CollectionConflictResolver) => void) | undefined\n /**\n * CRDT mode for this collection. When set, `put()` stores\n * CRDT state in the envelope and `get()` returns the resolved snapshot.\n * `getRaw(id)` returns the full CRDT state for merge operations.\n */\n crdt?: CrdtMode | undefined\n /**\n * optional remote/sync adapter. When present, `presence()`\n * writes heartbeats to this adapter so other devices can read them.\n * If the adapter implements pub/sub, presence updates are real-time.\n */\n syncAdapter?: NoydbStore | undefined\n /**\n * called by the collection after every successful\n * `get` / `put` / `delete`. The Vault installs a callback that\n * appends a consent-audit entry when `withConsent` is active;\n * outside a consent scope the callback is a no-op. Awaited so a\n * thrown audit write surfaces to the caller.\n */\n onAccess?: (op: 'get' | 'put' | 'delete' | 'reveal' | 'verify' | 'find', id: string) => Promise<void>\n /**\n * invoked by `put`/`delete` before any adapter\n * write. Receives the prior envelope timestamp + decrypted\n * record (or `null` if no prior) and the incoming record (or\n * `null` for delete). Throws `PeriodClosedError` to abort.\n */\n /**\n * opt-in deterministic-encryption index.\n *\n * Field names listed here get a deterministic AES-GCM ciphertext\n * attached to every envelope's `_det` map, which enables blind\n * equality search via `collection.findByDet(field, value)`.\n *\n * **Leaks equality.** Two records with the same value in a\n * deterministic field produce identical ciphertexts, so anyone\n * with store access can tell which records share a value without\n * learning the value itself. This is the textbook trade-off of\n * deterministic encryption — strictly opt-in for that reason.\n *\n * Declaring any field here without also passing\n * `acknowledgeDeterministicRisk: true` throws at construction,\n * so the risk must be explicitly acknowledged.\n */\n deterministicFields?: readonly string[] | undefined\n /**\n * gate for `deterministicFields`. Must be `true` when\n * any deterministic field is declared. Any other value throws.\n */\n acknowledgeDeterministicRisk?: boolean | undefined\n /**\n * gate for the classified `equatable` knob (R8 double door). Must be `true`\n * when any classified field declares `equatable: true`; otherwise construction\n * throws. One-directional — setting it with zero equatable members is a\n * silent no-op (mirrors `acknowledgeDeterministicRisk`).\n */\n acknowledgeEquatableRisk?: boolean | undefined\n /**\n * Structural group-encryption. Fields listed here are\n * encrypted into their own `_sealed[field]` envelope slot — each under\n * an HKDF-derived per-field key — instead of sitting inside the open\n * `_data` blob. Default-off: with no `sensitive` fields the envelope is\n * byte-identical to today. Read merges them back inline (the\n * `Sealed<V>`/`reveal()` access restriction is a separate follow-up).\n *\n * **Incompatible with `perRecordKeys`/forget-cascade:** sealed\n * field keys derive off the *collection* DEK, not the per-record CEK, so\n * crypto-shredding a record does not erase its sealed fields.\n */\n sensitive?: readonly string[] | undefined\n /**\n * Per-record content-encryption keys. When `true`, every record body\n * (and every history version of it) is encrypted under a fresh\n * per-record CEK, AES-KW-wrapped under the collection DEK and stored\n * on the envelope's `_cek`. Off by default. Foundation for per-record\n * erasure and record-scoped sealing. `_det` slots stay\n * keyed to the collection DEK regardless.\n */\n perRecordKeys?: boolean | undefined\n /**\n * Per-record provenance tracking. When `true`, `put()` calls that\n * supply a `source` option stamp `_source` (opaque source id) and\n * `_sourceTs` (ISO-8601 timestamp) onto the unencrypted envelope\n * metadata. Off by default — zero cost for collections that don't\n * need lineage tracking.\n */\n provenance?: boolean | undefined\n /**\n * declared tiers this collection supports. An\n * undefined or empty list disables the hierarchical-tier surface\n * on this collection (`putAtTier`, `getAtTier`, `elevate`, `demote`\n * throw). Tier 0 is implicit and always available.\n */\n tiers?: readonly number[] | undefined\n /**\n * what a lower-tier caller sees for above-tier\n * records. Default `'invisibility'`.\n */\n tierMode?: TierMode | undefined\n /**\n * optional callback fired on every cross-tier access.\n * Provided by the Vault; collects notification events and writes\n * to the ledger.\n */\n onCrossTierAccess?: ((event: CrossTierAccessEvent) => void) | undefined\n /**\n /**\n * Optional back-reference to the owning vault's derivation\n * registry + collection accessor. When present, successful\n * `put()` dispatches registered derivation strategies for the\n * source collection.\n */\n derivationSource?: {\n registry(): DerivationRegistry\n getCollection(name: string): Collection<Record<string, unknown>>\n /**\n * Read-only vault facade handed to `derive(source, ctx)` so a\n * derivation can fetch sibling records. Same shape and\n * instance the guards service uses for `check(incoming, ctx)`.\n */\n getReadOnlyFacade(): ReadOnlyVaultFacade\n /**\n * Read access to the owning Noydb's currently-active multi-record\n * transaction context, or `null` when no transaction is running.\n * `dispatchDerivations` consults this so a recursive derived-output\n * write can register its pre-write envelope onto `ctx._executed`\n * and roll back alongside the source op on mid-batch failure.\n */\n getActiveTxContext(): TxContext | null\n /**\n * Construct a transient TxContext bound to the owning Noydb. Used\n * by `Collection.putManyAtomic` to publish an active context for\n * its Phase 2 loop.\n */\n createTxContext(): TxContext\n /** Publish a TxContext for the duration of a bulk-atomic loop. */\n setActiveTxContext(ctx: TxContext): void\n /** Drop a previously-published TxContext. */\n clearActiveTxContext(ctx: TxContext): void\n } | undefined\n /**\n * Vault-internal hook for materialized-view dispatch.\n * Parallel to `derivationSource`. When set, `Collection.put` fires\n * registered MV `onSourceWrite` after the standard derivation\n * dispatch.\n */\n materializedViewSource?: {\n\n registry(): MaterializedViewRegistry\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n getCollection(name: string): Collection<any>\n getActiveTxContext(): TxContext | null\n getQueryContext(): MVQueryContext\n } | undefined\n /**\n * #638 Task 4 — thin collector hook wired by the Vault (`Vault._collectGraphTouch`). Every\n * `sync-apply`/`cutover`/`restore` mutation origin calls `collect(this.name, id)`; a no-op\n * when no batch is open (`_beginGraphBatch()` wasn't called) or the vault has no graph.\n * `collectDelete` (#640) is the sync-apply delete socket — the resolved rollup-parent intents\n * for a deleted record, captured pre-invalidation.\n */\n graphDispatch?:\n | { collect(collection: string, id: string): void; collectDelete(collection: string, id: string, intents: readonly RollupDeleteIntent[]): void }\n | undefined\n}\n\n/** One normalized `ComputedFields` entry — a plain `ComputedFn` or a `ComputedFieldEntry`\n * reduced to its parts, `mode` always defaulted (#638 Task 7). Exported so\n * `via/graph-wiring.ts`'s reconcile-path guard can check `mode` without duplicating\n * the plain-fn-vs-object-form normalization. */\nexport interface ComputedEntryParts { readonly fn: ComputedFn; readonly deps?: readonly string[]; readonly mode: 'materialized' | 'virtual' }\n\nexport function computedEntryParts(entry: ComputedFn | ComputedFieldEntry): ComputedEntryParts {\n if (typeof entry === 'function') return { fn: entry, mode: 'materialized' }\n return { fn: entry.fn, ...(entry.deps !== undefined ? { deps: entry.deps } : {}), mode: entry.mode ?? 'materialized' }\n}\n\n/**\n * Field names a `triggerBy` match may NOT target, and the ones it may (#1266).\n *\n * Lives beside `computedEntryParts`, the other computed-mode reader. It was\n * briefly moved into the derivation registry on the theory that twenty lines\n * here cost the floor bundle 5.2% — measuring it showed the helper accounted\n * for ONE byte and the growth was elsewhere (#1268). Moved back now that a\n * second caller (the MV group-key guard) needs it and the layering forbids\n * the kernel importing the registry.\n *\n * A derivation matcher reads the STORED record, so a match target must be a\n * field that is stored. `mode: 'virtual'` computed fields are evaluated on the\n * READ path and never persisted — but they appear in `computed:` (and in\n * `via(computed(...))`) exactly like materialized ones, so the registration\n * guard accepted them and the fan-out then matched nothing, forever: the guard's\n * own stated failure mode, reached through the guard rather than around it.\n *\n * Rejected rather than supported. Matching a virtual field means running user\n * code for every candidate row, which turns an indexed narrow into a full scan\n * of the collection; `mode: 'materialized'` is stored, already works, and is\n * what the error points the caller at.\n *\n * `declared` also folds in `viaFields`, which the guard's key set previously\n * omitted entirely — a `via()`-declared MATERIALIZED field is a perfectly good\n * match target and was being rejected as a typo. An over-firing guard teaches\n * people to stop trusting it, so both directions are fixed together.\n */\nexport function matchTargetFieldNames(opts: {\n // Deliberately `unknown`-valued: the caller is generic over the record type\n // (`ComputedFields<T>`), and this reads only `mode`, so narrowing the value\n // type here would force a variance cast at every call site instead of one\n // here. Both shapes are duck-checked below.\n readonly computed?: Readonly<Record<string, unknown>> | undefined\n readonly viaFields?: Readonly<Record<string, unknown>> | undefined\n}): { readonly declared: readonly string[]; readonly virtual: readonly string[] } {\n const declared: string[] = []\n const virtual: string[] = []\n for (const [field, entry] of Object.entries(opts.computed ?? {})) {\n declared.push(field)\n const parts = computedEntryParts(entry as ComputedFn | ComputedFieldEntry)\n if (parts.mode === 'virtual') virtual.push(field)\n }\n for (const [field, spec] of Object.entries(opts.viaFields ?? {})) {\n declared.push(field)\n const descriptors = (spec as { descriptors?: readonly unknown[] }).descriptors ?? []\n for (const d of descriptors) {\n if ((d as { _viaBrand?: unknown })._viaBrand === 'computed'\n && (d as { mode?: unknown }).mode === 'virtual') virtual.push(field)\n }\n }\n return { declared, virtual }\n}\n\n/**\n * #638 Task 7 — union the `computed:` sugar option with `via(computed(...))`-declared\n * entries (`kernel/via/compose.ts#mergeViaFields`'s `computedFields` output) into ONE\n * per-field map. NEVER includes `resolvedClassified.riderComputed` — that sanctioned\n * classified→computed channel (seam map Part 4) stays outside every guard this map feeds\n * (`resolveComputedEdges`'s depsless-on-classified refusal, the rider-name collision check).\n * Both `compileVias` (to find `mode: 'virtual'` fields) and `resolveCollectionConfig`\n * (to split materialized entries into `mergedComputed` + extract graph edges) read this.\n */\nfunction unifyComputedFields<T>(opts: CollectionOpts<T>, viaComputedFields: Record<string, ComputedDescriptor> | undefined): ComputedFields {\n return { ...(opts.computed ?? {}), ...(viaComputedFields ?? {}) }\n}\n\n/**\n * Compile a collection's declared config into the ordered list of `NoydbVia`s\n * for its `ViaPipeline`.\n *\n * money then i18n then lookup then classified then blob then computed — order\n * pinned for pipeline parity with the hand-wired baseline this replaces: money\n * encode ran before the i18n write stages, and money decode ran before i18n\n * locale/dict-label resolution on read. Lookup compiles right after i18n\n * (#650 Task 2) — a separate binding for native lookup()/enumOf()/dict()\n * fields (`dictKeyFields`/`dictKey()`/`staticDict()` stay on the i18n\n * binding above, unchanged); its `present` hook only adds `<field>Label`,\n * same shape of read-time addition as i18n's own dict-label dressing, and\n * declares no write-pipeline hooks yet (Task 3 adds `ingest`/`enforceWrite`).\n * Classified compiles after those (#629 Task 6): its\n * `encodeAtRest`/`decodeAtRest` hooks make the pipeline's `hasAtRestHooks`\n * true, retiring the codec's inline `sensitiveFields` seal path\n * (record-codec.ts) for any collection that declares `classifiedFields` —\n * `classifiedGuardCtx` is the SAME `ClassifiedGuardCtx`\n * `resolveCollectionConfig` already built for door 1's\n * `guardClassifiedCompat` call, threaded in by its one caller below. Blob\n * compiles next (#629 Task 7) but its position is inert: the blob binding\n * declares NO write/read pipeline hooks (blob content is out-of-band\n * `BlobSet` side-collections — it must never flip `hasAtRestHooks`), only\n * `erase`/`describeFragment`. Computed compiles LAST (#638 Task 7) — its\n * `present` hook must run AFTER money's own `present` so a virtual field's\n * `deps` read the decoded (quantized) amount, not the raw stored form; at\n * present-time i18n/lookup's DRESSING now runs AFTER computed instead (#665\n * `_presentOrder`, `via/pipeline.ts` — compile order here is unchanged).\n * `via/graph-wiring.ts#applyTaintOverlay` appends the `taint`\n * binding after WHATEVER this function returns, so taint's present-time\n * redaction always runs after computed's regardless of this ordering.\n * {@link Collection._applyMoneyFields} PREPENDS money for the same reason\n * on its own (MV-precreation reconcile) path — see its docstring;\n * {@link Collection._applyClassifiedFields} APPENDS classified on that same\n * reconcile path (blobFields/computed have no late-attach reconcile door —\n * `viaFields`, like i18nFields/dictKeyFields, is construction-only).\n *\n * `eraseCfgOut` (#629 Task 10, optional out-param) — this function runs\n * before the owning `Collection` exists (`this.codec` isn't built yet), so\n * the classified binding's `classifySealedShred` closure can't be wired\n * here. When supplied, `eraseCfgOut.classified` is set to the SAME cfg\n * object instance handed to `viaBinder('classified')`, so a caller\n * (`resolveCollectionConfig`) can thread it out to the `Collection`\n * constructor, which mutates `classifySealedShred` in place once\n * `this.codec` exists. Additive — every existing caller omits it and keeps\n * getting a plain `NoydbVia[]`.\n */\nexport function compileVias<T>(\n opts: CollectionOpts<T>,\n classifiedGuardCtx: ClassifiedGuardCtx,\n eraseCfgOut?: { classified?: ClassifiedViaConfig },\n): NoydbVia[] {\n const { moneyFields, i18nFields, dictKeyFields, computedFields, lookupFields } = mergeViaFields(opts)\n const allComputedFields = unifyComputedFields(opts, computedFields)\n guardCrossBindingFieldCollisions({\n moneyFields, i18nFields, dictKeyFields, lookupFields,\n classifiedFields: opts.classifiedFields !== undefined\n ? resolveClassifiedFields(opts.name, opts.classifiedFields).byField\n : undefined,\n blobFields: opts.blobFields,\n computed: allComputedFields,\n })\n const bindings: NoydbVia[] = []\n // #669 — hoisted above the money push (was built at the tail of this function, alongside\n // the `computed` binding push below) so money's own binding config can be told which of\n // ITS fields are ALSO virtual-mode computed (the money+virtual-on-the-same-field\n // MAJOR-UNITS case) — money needs this at construction time; nothing else in this\n // function depends on the hoist.\n const virtualFields = new Map<string, ComputedDescriptor>()\n for (const [field, entry] of Object.entries(allComputedFields)) {\n const parts = computedEntryParts(entry)\n if (parts.mode === 'virtual') {\n virtualFields.set(field, { _viaBrand: 'computed', fn: parts.fn, mode: 'virtual', ...(parts.deps !== undefined ? { deps: parts.deps } : {}) })\n }\n }\n if (moneyFields) {\n const virtualMoney = resolveVirtualMoneyFields(Object.keys(moneyFields), (f) => virtualFields.has(f))\n bindings.push(viaBinder('money')({ moneyFields, ...(virtualMoney.size > 0 ? { virtualMoneyFields: virtualMoney } : {}) }))\n }\n if (i18nFields || dictKeyFields) {\n // Densify-enabled subset (fields opting into `densifyOnWrite: true`) —\n // undefined when none opt in, so the write path skips densify work\n // entirely for ordinary collections.\n const densify = i18nFields\n ? Object.fromEntries(\n Object.entries(i18nFields).filter(([, d]) => d.options.densifyOnWrite === true),\n )\n : {}\n const i18nDensifyFields = Object.keys(densify).length > 0 ? densify : undefined\n bindings.push(viaBinder('i18n')({\n ...(i18nFields !== undefined ? { i18nFields } : {}),\n ...(dictKeyFields !== undefined ? { dictKeyFields } : {}),\n ...(i18nDensifyFields !== undefined ? { i18nDensifyFields } : {}),\n strategy: opts.strategies.i18n,\n ...(opts.defaultLocale !== undefined ? { defaultLocale: opts.defaultLocale } : {}),\n ...(opts.autoTranslateHook !== undefined ? { autoTranslateHook: opts.autoTranslateHook } : {}),\n ...(opts.dictLabelResolver !== undefined ? { dictLabelResolver: opts.dictLabelResolver } : {}),\n ...(opts.i18nPutValidator !== undefined ? { i18nPutValidator: opts.i18nPutValidator } : {}),\n collectionName: opts.name,\n }))\n }\n // #650 Task 2 — native lookup()/enumOf()/dict() fields (the `lookupFields`\n // sugar key, merged with `via(lookup(...))` entries by mergeViaFields). A\n // SEPARATE binding from i18n above — dictKey()/staticDict() stay on the\n // i18n binding (the alias, unchanged); a collection declaring BOTH\n // dictKeyFields and lookupFields compiles both bindings.\n // must move together with via/reconcile.ts's lookup binder-config block (reconcileLookupFields,\n // the `viaBinder('lookup')({...})` call) (#664) — same option-shape contract.\n if (lookupFields !== undefined) {\n bindings.push(viaBinder('lookup')({\n lookupFields,\n ...(opts.lookupLabelResolver !== undefined ? { lookupLabelResolver: opts.lookupLabelResolver } : {}),\n ...(opts.getLookupBacking !== undefined ? { getLookupBacking: opts.getLookupBacking } : {}),\n ...(opts.membership !== undefined ? { membership: opts.membership } : {}),\n ...(opts.getAltIndex !== undefined ? { getAltIndex: opts.getAltIndex } : {}),\n ...(opts.snapshotFor !== undefined ? { snapshotFor: opts.snapshotFor } : {}),\n collectionName: opts.name,\n }))\n }\n if (opts.classifiedFields !== undefined) {\n const classifiedCfg: ClassifiedViaConfig = {\n entries: opts.classifiedFields,\n collectionName: opts.name,\n guardCtx: classifiedGuardCtx,\n }\n if (eraseCfgOut) eraseCfgOut.classified = classifiedCfg\n bindings.push(viaBinder('classified')(classifiedCfg))\n }\n if (opts.blobFields !== undefined) {\n bindings.push(viaBinder('blob')({\n fields: opts.blobFields,\n collectionName: opts.name,\n }))\n }\n if (virtualFields.size > 0) {\n bindings.push(viaBinder('computed')({ virtualFields }))\n }\n return bindings\n}\n\n/**\n * The money∩virtual-mode-computed field-name intersection (#669) — shared by\n * `compileVias` above (fresh construction, `isVirtual` closes over the just-built\n * `virtualFields` Map) and {@link Collection._applyMoneyFields} (late-attach, `isVirtual`\n * closes over the already-compiled pipeline's `computed` binding instead — virtual-mode\n * computed fields have no late-attach door of their own (declaring one on a reconcile call\n * throws), so by the time money reconciles onto an existing collection, any virtual field\n * is already sitting in `bindings`, never in `this.computed`: `resolveCollectionConfig`\n * deliberately excludes virtual-mode entries from the map it assigns to `this.computed`,\n * since that field feeds ONLY the write-time `evalComputedFields` path — see\n * `materializedComputed` above). Both callers get the identical intersection semantics from\n * one function, so money's `presentLate` MAJOR-UNITS dressing (`via/money/binding.ts`) can\n * never silently disagree between the fresh and late-attach paths.\n */\nexport function resolveVirtualMoneyFields(\n moneyFieldNames: Iterable<string>,\n isVirtual: (field: string) => boolean,\n): Set<string> {\n const out = new Set<string>()\n for (const field of moneyFieldNames) if (isVirtual(field)) out.add(field)\n return out\n}\n\n/** One `ViaGraph.registerDerived` call's worth of edge data — target + sources,\n * `kind` chosen by the caller (#638 Task 2 edge extraction). `grain` defaults to\n * `'record'` when absent; `resolveComputedEdges` (#638 Task 7) sets it to `'virtual'`\n * for a `mode: 'virtual'` computed field's edge. */\nexport interface GraphEdge { readonly target: FieldRef; readonly sources: readonly FieldRef[]; readonly grain?: Grain }\n\n/**\n * The known-field-name universe builder (#638 Task 2 fix wave 2) — used by\n * {@link resolveCollectionConfig} to validate `resolveViaDepsEdges`'s `deps`\n * entries, and by {@link resolveComputedEdges}'s classified-collection dep-name check\n * (Finding I2ii's \"shared, so the two paths cannot silently drift apart\" rationale).\n * #638 Task 7 dropped `resolveComputedEdges`'s dep-name check entirely (legalizing a\n * plain-field dep on a non-classified collection); the Task 7 review's CRITICAL finding\n * (a typo'd dep on a CLASSIFIED collection reopens the #636 leak) restored a\n * classified-only slice of it, scoped through this SAME helper rather than a\n * hand-rolled second universe — exported so `via/graph-wiring.ts`'s reconcile path can\n * build its own call-scoped knownFields the identical way the fresh path does.\n */\nexport function collectKnownFieldNames(parts: {\n readonly moneyFields?: Record<string, unknown> | undefined\n readonly i18nFields?: Record<string, unknown> | undefined\n readonly dictKeyFields?: Record<string, unknown> | undefined\n readonly classifiedFields?: Record<string, unknown> | undefined\n readonly computed?: Record<string, unknown> | undefined\n readonly lookupFields?: Record<string, unknown> | undefined\n}): Set<string> {\n return new Set<string>([\n ...Object.keys(parts.moneyFields ?? {}),\n ...Object.keys(parts.i18nFields ?? {}),\n ...Object.keys(parts.dictKeyFields ?? {}),\n ...Object.keys(parts.classifiedFields ?? {}),\n ...Object.keys(parts.computed ?? {}),\n ...Object.keys(parts.lookupFields ?? {}),\n ])\n}\n\n/** Default `knownFields` for a `resolveComputedEdges` call that never checks it\n * (`hasClassifiedFields === false`) — lets existing direct-unit-test call sites\n * omit the 4th argument. */\nconst EMPTY_KNOWN_FIELDS: ReadonlySet<string> = new Set()\n\n/**\n * Validate each `computed` entry's `deps` well-formedness and resolve them into graph\n * edges (#638 Task 2; #638 Task 7 folded the formerly-separate `computedDeps` sibling\n * option into each entry's own `{ fn, deps?, mode? }` shape — see\n * `with-formula/computed/index.ts#ComputedFieldEntry`). `computed` is the RAW\n * user-declared map — `unifyComputedFields`'s union of the `computed:` sugar option and\n * `via(computed(...))` entries, NEVER `mergedComputed`: a classified preset's\n * `riderComputed` companions are a sanctioned, already-vetted classified→computed channel\n * and are deliberately NOT subject to this guard. A depsless entry is fine UNLESS the\n * collection also declares classified fields (`hasClassifiedFields`), in which case an\n * opaque computed function could silently copy a classified field's plaintext into an\n * ordinary, unredacted field (the #636 leak) — refused at declare time, regardless of\n * `mode` (a virtual field's read-time redaction, `via/taint-binding.ts`, only fires for a\n * field the graph actually taints — a depsless one never is).\n *\n * A `deps` entry may name ANY field — including a PLAIN field with no via feature\n * declared on it at all (#638 Task 7; Task 2's original design only ever validated a\n * `deps` entry against `moneyFields`/`i18nFields`/`dictKeyFields`/`classifiedFields`/\n * `computed`'s own declared names — `collection-config.ts` has no schema-introspection\n * API to check a `deps` entry against the record's FULL field set, since\n * `StandardSchemaV1` — Zod/Valibot/ArkType/Effect, deliberately schema-library-agnostic —\n * exposes no \"list of field names\" capability). This is safe on a NON-classified\n * collection: a dep with no registered `ViaGraph` node contributes `DEFAULT_POSTURE`\n * when folded (`ViaGraph._contribution`'s `?? DEFAULT_POSTURE` fallback) — i.e. nothing,\n * exactly like any other untainted source.\n *\n * Task 7 review CRITICAL fix (empirically confirmed leak reopening): on a collection\n * that DOES declare classified fields, an UNKNOWN `deps` entry (a typo — e.g.\n * `deps: ['sssn']` instead of `['ssn']`) used to fold to `DEFAULT_POSTURE` exactly like\n * the \"harmless plain field\" case above, silently reopening the #636 leak — construction\n * didn't throw, and the derived field was written/read UNSEALED even though its `fn`\n * actually read a classified field. `knownFields` (built by {@link collectKnownFieldNames}\n * the SAME way at every call site — never a hand-rolled second universe, the exact drift\n * that caused a Task 2 bug) restores the \"every dep must name a known field\" check, but\n * ONLY when `hasClassifiedFields` — a non-classified collection keeps the Task 7 freedom\n * (any string is a legal dep, per the paragraph above) since an untainted fold there is\n * always safe regardless of typos.\n *\n * KNOWN LIMIT (pre-existing since Task 2, phase-E territory — pinned by\n * `via/taint.test.ts`'s \"KNOWN LIMIT\" test): this only checks that a `deps` entry names\n * SOME known field, not that it names the RIGHT one. A `deps` entry naming a real,\n * declared-but-WRONG field (e.g. `fn` reads classified field `ssn` but `deps: ['amount']`\n * — a genuine, known, non-classified field) still passes this check and still leaks:\n * the graph edge folds from `amount`'s posture, not `ssn`'s, so the derived field is\n * folded/sealed as if it read `amount`, while its actual output is `ssn`'s plaintext.\n * There is no schema-introspection capability (see above) to verify a `deps` entry\n * actually corresponds to what `fn` reads — closing this fully would need runtime\n * read-tracking or a schema-aware capability, out of this fix's scope.\n */\nexport function resolveComputedEdges(\n collectionName: string,\n computed: ComputedFields | undefined,\n hasClassifiedFields: boolean,\n knownFields: ReadonlySet<string> = EMPTY_KNOWN_FIELDS,\n): readonly GraphEdge[] {\n if (!computed) return []\n const edges: GraphEdge[] = []\n for (const [field, entry] of Object.entries(computed)) {\n const parts = computedEntryParts(entry)\n const deps = parts.deps\n if (deps === undefined) {\n if (hasClassifiedFields) {\n throw new ValidationError(\n `Collection \"${collectionName}\": computed field \"${field}\" has no declared \\`deps\\` and the ` +\n `collection declares classified fields — an opaque computed function could silently copy a ` +\n `classified field's plaintext into an ordinary, unredacted field. Declare \\`deps\\` naming the ` +\n `source fields it reads, e.g. computed: { ${field}: { fn, deps: [...] } } or ` +\n `via(computed(fn, { deps: [...] })).`,\n )\n }\n continue\n }\n if (deps.length === 0) {\n throw new ValidationError(`Collection \"${collectionName}\": computed field \"${field}\"'s \\`deps\\` must be non-empty.`)\n }\n for (const dep of deps) {\n if (typeof dep !== 'string' || dep.length === 0) {\n throw new ValidationError(`Collection \"${collectionName}\": computed field \"${field}\"'s \\`deps\\` entries must be non-empty strings.`)\n }\n if (hasClassifiedFields && !knownFields.has(dep)) {\n throw new ValidationError(\n `Collection \"${collectionName}\": computed field \"${field}\"'s \\`deps\\` entry \"${dep}\" does not name a ` +\n `declared field, and the collection declares classified fields — an opaque computed function could ` +\n `silently copy a classified field's plaintext into an ordinary, unredacted field via a mistyped/unknown ` +\n `dep name. Declare \\`deps\\` naming only known fields (money/i18n/dictKey/classified/computed) — check ` +\n `\"${dep}\" for a typo.`,\n )\n }\n }\n edges.push({\n target: { collection: collectionName, field },\n sources: deps.map((d) => ({ collection: collectionName, field: d })),\n grain: parts.mode === 'virtual' ? 'virtual' : 'record',\n })\n }\n return edges\n}\n\n/**\n * Extract graph edges from `NoydbVia.deps` (#638 Task 2 — `deps` goes from\n * inert to validated). For any compiled binding declaring `deps`, every field\n * it `covers()` (tested against `knownFields`) becomes a derived target whose\n * sources are `deps`; an unknown source field throws declare-time\n * `ValidationError`. No shipped binding declares `deps` today (money/i18n/\n * classified/blob don't) — this is the general path a future derive-bearing\n * binding (phase C Task 7's `computed` via-binding) plugs into.\n */\nexport function resolveViaDepsEdges(\n collectionName: string,\n bindings: readonly NoydbVia[],\n knownFields: ReadonlySet<string>,\n): readonly GraphEdge[] {\n const edges: GraphEdge[] = []\n for (const binding of bindings) {\n if (!binding.deps || binding.deps.length === 0) continue\n for (const dep of binding.deps) {\n if (!knownFields.has(dep)) {\n throw new ValidationError(\n `Collection \"${collectionName}\": via binding \"${binding.brand}\" deps references undeclared field \"${dep}\".`,\n )\n }\n }\n const sources = binding.deps.map((d) => ({ collection: collectionName, field: d }))\n for (const field of knownFields) {\n if (binding.covers?.(field)) edges.push({ target: { collection: collectionName, field }, sources })\n }\n }\n return edges\n}\n\n/**\n * Resolve the raw {@link CollectionOpts} into the concrete field values the\n * {@link Collection} constructor assigns — every `?? default`, every derived\n * `Set`/subset, plus the three pure construction-time validations. Pure: no\n * `this`, no external side effect. The allocated `Set`/`VectorSet`/`Lru`\n * instances become the collection's own by reference.\n */\nexport function resolveCollectionConfig<T>(opts: CollectionOpts<T>) {\n // Guard: CRDT collections cannot use embeddings (the embedding-derive\n // block is unreachable after the CRDT early-return in _putInternal; full\n // CRDT-derivation is out of scope).\n if (opts.embeddings && opts.crdt) {\n throw new Error(\n `Collection \"${opts.name}\": embeddings are not supported on CRDT collections (L2). Use a non-CRDT collection for semantic search.`,\n )\n }\n\n // Guard (#1269): an MV group key naming a VIRTUAL computed field on THIS\n // collection. A virtual field is evaluated on read and never stored, so the\n // MV pipeline reads the stored row, finds nothing, and buckets every row\n // under an `undefined` key — a well-formed aggregate carrying a wrong\n // NUMBER rather than an error. Same principle as the executor's existing\n // object-valued-group-key refusal (\"refuse, don't bucket wrong\") and as the\n // triggerBy virtual-target refusal (#1266).\n //\n // ⚠️ KNOWN RESIDUE — and the boundary is NOT the one two earlier versions of\n // this comment described. Stated from what the code below actually reads.\n //\n // THE BOUNDARY IS DECLARATIVE `spec.groupBy`, nothing else:\n // CAUGHT — a spec that declares `groupBy: [...]` as a top-level field\n // (`unionSources` or query-form alike). That is the only thing\n // the loop below inspects.\n // SILENT — `.groupBy(...)` chained INSIDE a `query: (db) => …` callback.\n // It is a runtime call on the query builder and never appears in\n // the spec, so there is nothing here to read.\n // IRRELEVANT — `spec.sources`. This guard never reads it, so declaring it\n // cannot bring a shape into coverage.\n //\n // ⛔ Two earlier framings of this comment were WRONG and both propagated:\n // \"an aggregate with explicit `sources` IS caught\" (withdrawn in #1278 as\n // inherited-not-measured) and \"the self-constructing single-query shape is\n // the uncovered one\" — which is worse, because it suggests dependency\n // ORDERING is what decides coverage and invites a reader to fix it by\n // declaring `sources`. Ordering decides which OTHER guard fires first (a\n // late-attach reconcile can refuse a virtual field on an already-constructed\n // collection, loudly); it does not decide this one. Measured by the pilot on\n // published pre.14 and re-derived here from the code.\n //\n // Closing the residue means inspecting the built query plan rather than the\n // spec, or refusing at compute time — filed, not guessed at. Do not restate\n // the boundary in terms of MV shape, `sources`, or construction order.\n {\n const virtualFieldNames = matchTargetFieldNames({\n computed: opts.computed as Readonly<Record<string, unknown>> | undefined,\n viaFields: opts.viaFields as Readonly<Record<string, unknown>> | undefined,\n }).virtual\n if (virtualFieldNames.length > 0) {\n const virtualSet = new Set(virtualFieldNames)\n for (const reg of opts.materializedViewSource?.registry().mvsForSource(opts.name) ?? []) {\n const spec = reg.spec as { groupBy?: string | readonly string[]; name?: string }\n const fields = spec.groupBy === undefined\n ? []\n : (typeof spec.groupBy === 'string' ? [spec.groupBy] : spec.groupBy)\n for (const f of fields) {\n if (!virtualSet.has(f)) continue\n throw new ValidationError(\n `materialized view \"${spec.name ?? reg.outputCollection}\": groupBy names \"${f}\", which `\n + `\"${opts.name}\" declares as a VIRTUAL computed field. Virtual fields are evaluated on read `\n + `and never stored, so every row would bucket under an undefined key and the aggregate would `\n + `be silently WRONG rather than an error. Declare it as \\`mode: 'materialized'\\` (stored) or `\n + `group on a stored field.`)\n }\n }\n }\n }\n\n // Guard: a `fieldMeta` key that names no real field. Hoisted here from\n // `describe()` so a typo is refused where it is DECLARED — a collection\n // nobody describes was otherwise never checked, and `fieldMeta` is what\n // carries `sensitivity`. Silent when the validator's fields cannot be read\n // synchronously; `buildDescription` keeps its own check for the async tier.\n validateFieldMetaAtRegistration({\n collection: opts.name,\n schema: opts.schema,\n fieldMeta: opts.fieldMeta as Record<string, unknown> | undefined,\n configKeys: Object.keys({\n ...opts.moneyFields, ...opts.dictKeyFields, ...opts.declaredRefs, ...opts.computed,\n ...opts.i18nFields, ...opts.lookupFields, ...opts.blobFields,\n ...opts.classifiedFields, ...opts.viaFields,\n }),\n })\n\n // Guard (#850): `sensitive` promises each field its own `_sealed` slot under\n // an HKDF-derived per-field key, but the CRDT branch of `_putInternal`\n // persists through `encryptJsonString` and returns before any sealing runs —\n // so the fields were silently stored in the ordinary body instead, with no\n // error. Refuse, matching what embeddings / unique indexes / classified\n // digest-only (R2) already do for the same underlying reason: the CRDT write\n // path bypasses the pipeline these options are enforced by. Fail loud rather\n // than deliver less encryption than the caller asked for.\n if (opts.sensitive && opts.sensitive.length > 0 && opts.crdt) {\n throw new Error(\n `Collection \"${opts.name}\": sensitive (structural group-encryption) is not supported on ` +\n `CRDT collections — the CRDT write path bypasses per-field sealing, so the fields would ` +\n `be stored in the ordinary encrypted body with no \\`_sealed\\` slot and no per-field key. ` +\n `Use a non-CRDT collection for sealed fields.`,\n )\n }\n\n // #724 I1 — a tiered collection that declares blobFields must opt into\n // perRecordKeys: legacy (non-perRecordKeys) blobs have no per-blob `_cek`,\n // so `rehomeForTier` cannot rewrap/re-put them under a tier DEK on\n // elevate/demote — they would stay tier-0-decryptable at rest. Refuse\n // loudly at construction instead of leaking silently.\n if (opts.tiers && opts.tiers.length > 0 && opts.blobFields !== undefined && Object.keys(opts.blobFields).length > 0 && opts.perRecordKeys !== true) {\n throw new UnsupportedTierCompositionError(\n 'blobs',\n `Collection \"${opts.name}\": tiered collections that declare blobFields require \\`perRecordKeys: true\\` — ` +\n `legacy (non-perRecordKeys) blobs have no per-blob content CEK and cannot be tier-isolated on elevate/demote.`,\n )\n }\n\n // #748 — tiers × a `public: true` external blob field is a structural dead\n // end, not a crypto gap the perRecordKeys mandate above can close. An\n // external-public object's key (`{collection}/{recordId}/{slotName}`) is\n // deterministic and its bytes are world-readable by design (CDN origin) —\n // elevating the owning record re-keys/re-scopes the ENCRYPTED slot catalog\n // entry, but can never retroactively hide an already-public bucket object,\n // nor stop a future `public: true` write from re-publishing it at the same\n // predictable key. Refuse at construction; private/presigned external\n // fields (`public` omitted or `false`) are unaffected — only the catalog\n // entry needs tier-isolation there, which perRecordKeys already provides.\n if (opts.tiers && opts.tiers.length > 0 && opts.blobFields !== undefined) {\n for (const [field, policy] of Object.entries(opts.blobFields)) {\n if (policy?.external && policy.public === true) {\n throw new UnsupportedTierCompositionError(\n 'blobs',\n `Collection \"${opts.name}\": blob field \"${field}\" cannot be both \\`external: true, public: true\\` ` +\n `and declared on a tiered collection — the object key is deterministic and its bytes are ` +\n `world-readable by design, so tier-invisibility can never be enforced for it once elevated. ` +\n `Use a private/presigned external field (\\`public\\` omitted or \\`false\\`) or move this field to ` +\n `a non-tiered collection.`,\n )\n }\n }\n }\n\n // #740 — tiers declare per-tier ENCRYPTION keys (elevate/demote re-key and\n // re-put the record under the target tier's DEK). A plaintext\n // (`encrypted: false`) collection has nothing to re-key: `putAtTier`/\n // `elevate` would encrypt/decrypt incoherently against a collection that\n // never encrypts. Refuse at construction instead of leaking silently.\n if (opts.tiers && opts.tiers.length > 0 && opts.encrypted === false) {\n throw new UnsupportedTierCompositionError(\n 'plaintext',\n `Collection \"${opts.name}\": tiers are per-tier ENCRYPTION keys — a plaintext collection ` +\n `(\\`encrypted: false\\`) has nothing to re-key, so \\`putAtTier\\`/\\`elevate\\` would ` +\n `encrypt/decrypt incoherently. Use an encrypted collection.`,\n )\n }\n\n // #739 — a CRDT-mode collection's decrypted body is the raw `CrdtState`\n // (edit log + bidx pointer), not the resolved record: `RecordCodec\n // .decryptRecordAtDek()` — the tier-aware pre-move decode `syncDerived`\n // uses on `elevate()`/`demote()`/`putAtTier()` (#722) — has no CRDT\n // resolution step (same gap as `getAtTier`'s tier>0 leg), so a registered\n // rollup/derivation reading this collection sees `undefined` for every\n // field (e.g. `_rollupDeleteIntents`'s `deleted[spec.rollup.key]`) and its\n // recompute silently no-ops — the #722 derived-output-follows-tier fix\n // never fires for this combination. Refuse at construction instead of\n // leaking silently.\n //\n // Caught here: rollup/derivation sources, reliably — `DerivationRegistry`\n // is fully populated (every `withDerivation()`/`withRollup()` handle\n // registered) by `Noydb.openVault()` before any `vault.collection()` call\n // reaches user code, so source/derived registration order never matters.\n //\n // NOT caught: a materialized-view SOURCE first constructed inside the\n // MV's own single-query `query(db)` callback (the common `query: (db) =>\n // db.collection(name)...` shape) — `MaterializedViewRegistry.register()`\n // invokes that callback (which constructs THIS collection) before it\n // records the dependency, so `materializedViewSource.registry()\n // .mvsForSource(name)` is still empty at this exact call. A\n // `unionSources`/aggregate-with-explicit-`sources` MV, or a source\n // constructed by an earlier `vault.collection()` call, is still caught.\n if (\n opts.tiers && opts.tiers.length > 0 && opts.crdt !== undefined &&\n ((opts.derivationSource?.registry().strategiesForSource(opts.name).length ?? 0) > 0 ||\n (opts.materializedViewSource?.registry().mvsForSource(opts.name).length ?? 0) > 0)\n ) {\n throw new UnsupportedTierCompositionError(\n 'crdt-derivation',\n `Collection \"${opts.name}\": tiers + crdt cannot be combined with this collection acting as a ` +\n `derivation/rollup source (#739) — the tier-aware pre-move decode \\`syncDerived\\` uses on ` +\n `elevate()/demote() does not resolve CRDT state, so a registered derivation/rollup reads raw ` +\n `CrdtState instead of the record and silently no-ops. Use a non-CRDT collection for a tiered ` +\n `derivation/rollup source, or move the derivation off this collection.`,\n )\n }\n\n // via() / sugar-key merge (#623 Task 9) — throws on a field declared in both.\n const effectiveViaFields = mergeViaFields(opts)\n\n const resolvedClassified: ResolvedClassified | undefined =\n opts.classifiedFields !== undefined\n ? resolveClassifiedFields(opts.name, opts.classifiedFields)\n : undefined\n\n // #638 Task 7 — union the `computed:` sugar option with `via(computed(...))` entries,\n // then split by mode: materialized (default) folds into `mergedComputed` exactly like\n // today's sugar map; virtual NEVER does (it's never stored — `evalComputedFields` must\n // not see it) and instead feeds the computed via-binding's config (`compileVias`,\n // above, does the identical split independently — both are pure/cheap, mirrors\n // `resolveCollectionConfig` already re-deriving `effectiveViaFields`).\n const allComputed = unifyComputedFields(opts, effectiveViaFields.computedFields)\n const materializedComputed: ComputedFields = {}\n for (const [field, entry] of Object.entries(allComputed)) {\n if (computedEntryParts(entry).mode !== 'virtual') materializedComputed[field] = entry\n }\n\n // rider companions run first; user `computed` fns may read them.\n // A user `computed` key colliding with a rider companion is a config error\n // (checked against BOTH modes' field names — a virtual field can collide too).\n let mergedComputed: ComputedFields | undefined =\n Object.keys(materializedComputed).length > 0 ? materializedComputed : undefined\n if (resolvedClassified !== undefined) {\n for (const key of Object.keys(allComputed)) {\n if (resolvedClassified.riderComputed[key] !== undefined) {\n throw new ClassifiedConfigError(opts.name, `computed field \"${key}\" collides with a rider companion`)\n }\n }\n mergedComputed = { ...resolvedClassified.riderComputed, ...materializedComputed }\n }\n\n // deterministic-encryption wiring\n let deterministicFields: ReadonlySet<string> | null\n if (opts.deterministicFields && opts.deterministicFields.length > 0) {\n if (opts.acknowledgeDeterministicRisk !== true) {\n throw new Error(\n `Collection \"${opts.name}\": deterministicFields requires \\`acknowledgeDeterministicRisk: true\\`. ` +\n `Deterministic encryption leaks equality between records — two records with the same field value ` +\n `produce identical ciphertexts visible to anyone with store access. If that trade-off is acceptable ` +\n `for your threat model, set \\`acknowledgeDeterministicRisk: true\\` to enable.`,\n )\n }\n deterministicFields = Object.freeze(new Set(opts.deterministicFields))\n } else {\n deterministicFields = null\n }\n\n // Refusal matrix (R1-R5) — door 1. The SAME guard + ctx runs again at door 2\n // (`_applyClassifiedFields`, the reconcile seam), because crdt/conflictPolicy/\n // perRecordKeys are construction-only while classifiedFields can attach later\n // (C5's lesson). The ctx is always built (and returned) so door 2 has it even\n // when this construction declared no classified fields.\n const guardIndexedFields = new Set<string>()\n for (const ix of opts.indexes ?? []) {\n if (typeof ix === 'string') guardIndexedFields.add(ix)\n else if (Array.isArray(ix)) for (const f of ix) guardIndexedFields.add(f)\n else for (const f of (ix as { readonly fields: readonly string[] }).fields) guardIndexedFields.add(f)\n }\n const embeddingSources = opts.embeddings === undefined ? []\n : typeof opts.embeddings.source === 'string' ? [opts.embeddings.source] : [...opts.embeddings.source]\n const classifiedGuardCtx: ClassifiedGuardCtx = {\n perRecordKeys: opts.perRecordKeys === true,\n crdt: opts.crdt !== undefined,\n hasConflictPolicy: opts.conflictPolicy !== undefined,\n storeCiphertext: opts.encrypted,\n deterministicFields,\n indexedFields: guardIndexedFields,\n textIndexFields: new Set(opts.textIndexes ?? []),\n vectorSourceFields: new Set(embeddingSources),\n subjectKeyField: opts.subjectKeyField,\n bareSensitiveFields: new Set(opts.sensitive ?? []),\n acknowledgeEquatableRisk: opts.acknowledgeEquatableRisk === true,\n }\n if (resolvedClassified !== undefined) {\n guardClassifiedCompat(opts.name, resolvedClassified.byField, classifiedGuardCtx) // door 1\n }\n\n // structural group-encryption wiring: the set of fields sealed\n // into `_sealed` per-field slots. Empty when the option is absent.\n // Recoverable classified fields are unioned in — they seal via the same\n // mechanism with zero new crypto code.\n const classifiedSensitive = resolvedClassified === undefined ? [] :\n Object.entries(resolvedClassified.byField)\n .filter(([, s]) => s.storage === 'recoverable')\n .map(([f]) => f)\n const sensitiveList = [...(opts.sensitive ?? []), ...classifiedSensitive]\n const sensitiveFields: ReadonlySet<string> = sensitiveList.length > 0\n ? Object.freeze(new Set(sensitiveList))\n : Object.freeze(new Set<string>())\n\n // Digest-only classified fields → the enclave-consumable policy map\n // (stage 2). Both the codec write path and the verify engine key off it.\n const vdigEntries: Array<readonly [string, VdigFieldPolicy]> =\n resolvedClassified === undefined ? [] :\n Object.entries(resolvedClassified.byField)\n .filter(([, s]) => s.storage === 'digest-only')\n .map(([f, s]) => [f, {\n normalize: s.verifyNormalize ?? 'password',\n notLastN: s.notLastN ?? 0,\n equatable: s.equatable === true,\n ...(s.rotateDays !== undefined ? { rotateDays: s.rotateDays } : {}),\n }] as const)\n const vdigFields: ReadonlyMap<string, VdigFieldPolicy> | null =\n vdigEntries.length > 0 ? new Map(vdigEntries) : null\n\n // per-record CEK wiring. The cache is bounded by record count; CEKs\n // are tiny CryptoKey handles, so a generous entry budget is cheap.\n const perRecordCek = opts.perRecordKeys === true\n const cekCache = perRecordCek ? new Lru<string, EnclaveKey>({ maxRecords: 4096 }) : null\n\n // #629 Task 10 — captures the classified binding's cfg (see compileVias's doc comment) for the constructor's post-codec wiring.\n const viaEraseCfgOut: { classified?: ClassifiedViaConfig } = {}\n const via = ViaPipeline.build(compileVias(opts, classifiedGuardCtx, viaEraseCfgOut))\n\n // #638 Task 2 — the field-name universe `resolveViaDepsEdges` validates `deps`\n // entries against (\"references undeclared field\" otherwise) — still true for the general\n // `NoydbVia.deps` path. `resolveComputedEdges` (#638 Task 7) only consults this when\n // `hasClassifiedFields` (the Task 7 review's CRITICAL fix — see its own doc comment): a\n // computed `deps` entry may still name a plain field with no via feature at all on a\n // NON-classified collection.\n const knownFields = collectKnownFieldNames({\n moneyFields: effectiveViaFields.moneyFields,\n i18nFields: effectiveViaFields.i18nFields,\n dictKeyFields: effectiveViaFields.dictKeyFields,\n classifiedFields: resolvedClassified?.byField,\n computed: allComputed,\n lookupFields: effectiveViaFields.lookupFields,\n })\n const computedEdges = resolveComputedEdges(opts.name, allComputed, resolvedClassified !== undefined, knownFields)\n const viaDepsEdges = resolveViaDepsEdges(opts.name, via?.bindings ?? [], knownFields)\n\n return {\n adapter: opts.adapter,\n vault: opts.vault,\n name: opts.name,\n keyring: opts.keyring,\n storeCiphertext: opts.encrypted,\n ramCiphertext: opts.ramCiphertext ?? false,\n emitter: opts.emitter,\n writeQueue: opts.writeQueue,\n schemaUpdateGate: opts.schemaUpdateGate,\n schemaFence: opts.schemaFence,\n writeHooks: opts.writeHooks,\n subsystemBus: opts.subsystemBus,\n activeTxId: opts.activeTxId,\n strategies: opts.strategies,\n objectStore: opts.objectStore,\n blobFields: opts.blobFields,\n reconcileOnOpen: opts.reconcileOnOpen ?? 'off',\n getDEK: opts.getDEK,\n onDirty: opts.onDirty,\n tabCoordinated: opts.tabCoordinated,\n historyConfig: opts.historyConfig ?? { enabled: true },\n historyConfigExplicit: opts.historyConfigExplicit ?? false,\n schema: opts.schema,\n ledger: opts.ledger,\n refEnforcer: opts.refEnforcer,\n joinResolver: opts.joinResolver,\n i18nFields: effectiveViaFields.i18nFields,\n textIndexes: opts.textIndexes,\n embeddings: opts.embeddings,\n vectorSet: opts.embeddings ? new VectorSet() : undefined,\n dictKeyFields: effectiveViaFields.dictKeyFields,\n lookupFields: effectiveViaFields.lookupFields,\n // #650 Task 6 — the sync join-dressing hook (#626 retirement, spec §5);\n // `undefined` when this collection declares neither i18nText nor lookup\n // fields, matching today's `i18nFields`-absent JoinableSource shape.\n presentForJoin: buildPresentForJoin(effectiveViaFields.i18nFields, effectiveViaFields.lookupFields, opts.snapshotFor),\n fieldMeta: opts.fieldMeta,\n meta: opts.meta,\n _refs: opts.declaredRefs ?? {},\n via,\n classifiedEraseCfg: viaEraseCfgOut.classified,\n moneyFields: effectiveViaFields.moneyFields,\n classified: resolvedClassified,\n classifiedGuardCtx,\n computed: mergedComputed,\n computedEdges,\n viaDepsEdges,\n // #638 Task 7 — every declared computed field name (both modes, both surfaces); the\n // reconcile path's cross-call depsless-computed leak-guard memory\n // (`via/graph-wiring.ts#registerCollectionGraphSources`) reads this instead of\n // `Object.keys(opts.computed ?? {})` alone, so a via(computed(...))-declared field\n // participates in that guard identically to a sugar-declared one.\n computedFieldNames: Object.keys(allComputed),\n dictLabelResolver: opts.dictLabelResolver,\n getDictionary: opts.getDictionary,\n i18nPutValidator: opts.i18nPutValidator,\n autoTranslateHook: opts.autoTranslateHook,\n defaultLocale: opts.defaultLocale,\n crdtMode: opts.crdt,\n syncAdapter: opts.syncAdapter,\n onAccess: opts.onAccess,\n derivationSource: opts.derivationSource,\n materializedViewSource: opts.materializedViewSource,\n graphDispatch: opts.graphDispatch,\n tiers: opts.tiers && opts.tiers.length > 0 ? new Set(opts.tiers) : null,\n tierMode: opts.tierMode ?? 'invisibility',\n blobTierPolicy: opts.blobTierPolicy ?? 'isolate',\n onCrossTierAccess: opts.onCrossTierAccess,\n addSubjectRef: opts.addSubjectRef,\n deterministicFields,\n sensitiveFields,\n vdigFields,\n perRecordCek,\n cekCache,\n provenance: opts.provenance === true,\n }\n}\n","// kernel/via/graph.ts — the per-vault ViaGraph dependency model (Via port phase C, #638).\n//\n// Metadata-only dependency graph over (collection, field) nodes: source-field\n// postures, derived-field edges, and the taint (effective-posture) algebra.\n// NEVER stores record values or key material — see\n// design-history/2026-07-11-via-phase-c-design.md §1/§2.\n\nimport { DerivationCycleError, MaterializedViewCycleError } from '../errors.js'\nimport type { ViaPosture } from './index.js'\n\n/** A (collection, field) node. Artifact-grain targets (rollup field, MV row-class,\n * overlay output) are modelled as a field node whose `field` is the artifact key. */\nexport interface FieldRef { readonly collection: string; readonly field: string }\n\nexport type EdgeKind = 'computed' | 'derivation' | 'rollup' | 'mv' | 'overlay' | 'ref'\n/** `'virtual'` (#638 Task 7) marks a `computed(fn, { mode: 'virtual' })` field's edge —\n * never stored (rides the `present` phase), so it can never be sealed at rest\n * ({@link ViaGraph.taintSealedFields} excludes it) and is always non-queryable\n * regardless of source posture ({@link ViaGraph.effectivePosture} clamps it). */\nexport type Grain = 'record' | 'aggregate' | 'virtual'\n\n/** Delete/forget-time referential policy for a `'ref'` edge (#650 Task 5, spec §4) — duplicated\n * (not imported) from `via/lookup/descriptor.ts`'s `OnDelete`: the kernel spine may not\n * statically import `via/**` (Check 14, `via-layering`). Keep the two in sync by hand. */\nexport type OnDelete = 'restrict' | 'cascade' | 'nullify'\n\n/** Plain (non-via) field baseline — max-permissive; taint only ever tightens. */\nexport const DEFAULT_POSTURE: ViaPosture =\n { encryptedAtRest: 'envelope', queryable: 'full', exportable: true, forgettable: false }\n\nconst QUERYABLE_RANK: Record<ViaPosture['queryable'], number> = {\n none: 0,\n 'det-exact': 1,\n ordered: 2,\n full: 3,\n}\n\n/** The per-axis \"most restrictive\" fold — pure, exported for direct unit testing. */\nexport function foldPosture(a: ViaPosture, b: ViaPosture): ViaPosture {\n return {\n encryptedAtRest: a.encryptedAtRest === 'sealed' || b.encryptedAtRest === 'sealed' ? 'sealed' : 'envelope',\n queryable: QUERYABLE_RANK[a.queryable] <= QUERYABLE_RANK[b.queryable] ? a.queryable : b.queryable,\n exportable: a.exportable && b.exportable,\n forgettable: a.forgettable || b.forgettable,\n }\n}\n\n/** Security-axes-only fold for a wildcard collection node (#642): sealed-wins encryptedAtRest,\n * AND exportable, OR forgettable — queryable is NOT folded (stays base.queryable; the sealed\n * clamp to 'none' is buildTaintOverlay's job, so inheriting `sealed` never over-restricts a\n * blob-adjacent output to unqueryable). Pure; exported for unit testing. Distinct from\n * {@link foldPosture} (which folds all four axes) — do NOT reuse foldPosture here. */\nexport function foldWildcardSecurity(base: ViaPosture, contributor: ViaPosture): ViaPosture {\n return {\n encryptedAtRest: base.encryptedAtRest === 'sealed' || contributor.encryptedAtRest === 'sealed' ? 'sealed' : 'envelope',\n queryable: base.queryable,\n exportable: base.exportable && contributor.exportable,\n forgettable: base.forgettable || contributor.forgettable,\n }\n}\n\n// the folded formula kinds a '*' source contributes its collection-fold to (ref keeps identity):\ntype FoldedKind = 'derivation' | 'rollup' | 'mv' | 'overlay'\nconst FOLDED_KINDS: ReadonlySet<EdgeKind> = new Set<FoldedKind>(['derivation', 'rollup', 'mv', 'overlay'])\n\n/** Whether `p` is exactly the plain, non-taint baseline (Task 3 — `taintProvenance`). */\nfunction isDefaultPosture(p: ViaPosture): boolean {\n return p.encryptedAtRest === DEFAULT_POSTURE.encryptedAtRest && p.queryable === DEFAULT_POSTURE.queryable &&\n p.exportable === DEFAULT_POSTURE.exportable && p.forgettable === DEFAULT_POSTURE.forgettable\n}\n\n/** One `_out` entry — a `source -> target` derived edge, carrying its OWN registration's\n * `kind` (#678). `kind` must be edge-local, not re-derived from `_in`: `_in` is single-slot\n * per target and can be overwritten by a LATER `registerDerived` call on the SAME target\n * (a dual-role target, e.g. #631's exempt {computed, lookup} field composition) — asking\n * `_in` for \"this target's current kind\" answers the wrong question for a specific edge. */\ninterface OutEdge { readonly target: FieldRef; readonly kind: EdgeKind }\n\n/** One registered `registerDerived` call — a target's whole in-edge set. */\ninterface DerivedEdge {\n readonly target: FieldRef\n readonly sources: readonly FieldRef[]\n readonly kind: EdgeKind\n readonly grain: Grain\n /** `'ref'` edges only — the referencing field's delete/forget policy (#650 Task 5). */\n readonly onDelete?: OnDelete\n /** `'ref'` edges only — the backing dimension's canonical-key FIELD NAME on its own row (matrix\n * tier's `lookup(dim, {key})`; always `'id'` for reserved/static tiers). Defaults to `'id'`\n * when absent — a referencing field always stores this field's VALUE, never the backing row's\n * PUT-id when the two differ (#650 Task 5, mirrors Task 3's membership review fix). */\n readonly keyField?: string\n}\n\nconst SEP = '\\0'\nconst EMPTY_SET: ReadonlySet<string> = new Set()\n\nfunction nodeId(ref: FieldRef): string {\n return `${ref.collection}${SEP}${ref.field}`\n}\n\n/** Inverse of `nodeId`, for building a human-readable cycle path. */\nfunction displayNodeId(id: string): string {\n const sep = id.indexOf(SEP)\n return `${id.slice(0, sep)}.${id.slice(sep + 1)}`\n}\n\n/** Metadata-only dependency graph, ONE per vault. Never stores values or key material. */\nexport class ViaGraph {\n /** Declared source-field postures (registerField), keyed by node id. */\n private readonly _posture = new Map<string, ViaPosture>()\n /** Every derived target's registration, keyed by the target's node id. */\n private readonly _in = new Map<string, DerivedEdge>()\n /** source node id -> derived edges that depend on it (dispatch/erasure), each carrying\n * its own registration's `kind` (#678 — see {@link OutEdge}). */\n private readonly _out = new Map<string, OutEdge[]>()\n /** Memoized effective posture per derived target node id. */\n private readonly _effectiveCache = new Map<string, ViaPosture>()\n /** Memoized whole-collection security-axes fold for `'*'` wildcard LEAF nodes (#642),\n * keyed by collection name — see {@link _wildcardContribution}. Cleared alongside\n * `_effectiveCache` on every `registerField`/`registerDerived` (a later-registered\n * field must re-fold on the next read — registration ordering is free). */\n private readonly _wildcardCache = new Map<string, ViaPosture>()\n /** Collections with at least one classified field (#638 Task 2 fix wave 2,\n * Finding I1 — the reconcile path's combined-state leak guard memory). */\n private readonly _classifiedCollections = new Set<string>()\n /** Computed field names declared with no `deps` entry, per collection\n * (Finding I1 — such a field registers no edge when no classified field is\n * present yet, so a LATER, separate reconcile call attaching classifiedFields\n * still needs to see it regardless of declaration order). */\n private readonly _depslessComputed = new Map<string, Set<string>>()\n\n /** Declare a source field's posture (money/i18n/classified/plain). Plain fields\n * default to `DEFAULT_POSTURE`; a later declaration for the same node wins-first (idempotent). */\n registerField(collection: string, field: string, posture: ViaPosture): void {\n const id = nodeId({ collection, field })\n if (this._posture.has(id)) return\n this._posture.set(id, posture)\n this._effectiveCache.clear()\n this._wildcardCache.clear()\n }\n\n /** A derived target depends on `sources` (may be cross-collection). `kind`/`grain`\n * drive dispatch + erasure semantics; sources drive taint. Re-registering the same\n * target replaces `_in` but does not prune stale `_out` edges — callers must\n * register each target at most once per graph lifetime. `onDelete`/`keyField` (#650 Task 5)\n * are meaningful only for `kind === 'ref'` edges — {@link referencingEdgesOf} reads them back. */\n registerDerived(target: FieldRef, sources: readonly FieldRef[], kind: EdgeKind, grain: Grain, onDelete?: OnDelete, keyField?: string): void {\n const id = nodeId(target)\n this._in.set(id, {\n target, sources, kind, grain,\n ...(onDelete !== undefined ? { onDelete } : {}),\n ...(keyField !== undefined ? { keyField } : {}),\n })\n for (const source of sources) {\n const sourceId = nodeId(source)\n const outEdge: OutEdge = { target, kind }\n const dependents = this._out.get(sourceId)\n if (dependents) dependents.push(outEdge)\n else this._out.set(sourceId, [outEdge])\n }\n this._effectiveCache.clear()\n this._wildcardCache.clear()\n }\n\n /** Whether `target` already has a registered in-edge — lets a caller skip\n * re-registering the same target (#638 Task 2 fix wave 2, Finding I2i:\n * `registerDerived`'s at-most-once contract must hold across repeated\n * identical `vault.collection()` calls, not just within a single one). */\n hasDerived(target: FieldRef): boolean {\n return this._in.has(nodeId(target))\n }\n\n /** Mark/query a collection as having declared at least one classified field. */\n markClassified(collection: string): void {\n this._classifiedCollections.add(collection)\n }\n\n isClassified(collection: string): boolean {\n return this._classifiedCollections.has(collection)\n }\n\n /** Mark/query a collection's depsless (no declared `deps`) computed\n * field names — see `_depslessComputed`'s doc comment above. */\n markDepslessComputed(collection: string, field: string): void {\n let set = this._depslessComputed.get(collection)\n if (!set) { set = new Set(); this._depslessComputed.set(collection, set) }\n set.add(field)\n }\n\n depslessComputedFields(collection: string): ReadonlySet<string> {\n return this._depslessComputed.get(collection) ?? EMPTY_SET\n }\n\n /** Every field name the graph already has memory of for `collection` — from an\n * EARLIER, separate `vault.collection()` call (registered postures, derived\n * targets, depsless-computed names) — regardless of which via feature declared\n * it. #645 — `via/graph-wiring.ts`'s reconcile-path `knownFields` universe\n * (`collectKnownFieldNames`) is scoped to THIS call's own options only, so a\n * computed field attached in a LATER call whose `deps` correctly names a field\n * declared in an EARLIER call was spuriously refused as \"unknown\"; this method\n * lets that call site union in the graph's cross-call memory. Excludes the `'*'`\n * wildcard target (an overlay/derivation whole-record fold node, never a real\n * record field — see {@link registerDerived}'s doc comment). */\n knownFieldNames(collection: string): ReadonlySet<string> {\n const out = new Set<string>()\n const prefix = `${collection}${SEP}`\n for (const id of this._posture.keys()) {\n if (id.startsWith(prefix)) out.add(id.slice(prefix.length))\n }\n for (const edge of this._in.values()) {\n if (edge.target.collection === collection && edge.target.field !== '*') out.add(edge.target.field)\n }\n const depsless = this._depslessComputed.get(collection)\n if (depsless) for (const field of depsless) out.add(field)\n return out\n }\n\n /** Reject cycles at declare time (vault open). Throws `DerivationCycleError` for a\n * derivation/rollup/computed cycle, `MaterializedViewCycleError` for an MV cycle —\n * same classes + message shape the registries throw today (behavior lock). */\n assertAcyclic(): void {\n const visited = new Set<string>()\n const stack: string[] = []\n\n /** #639 — containment expansion: writing a real field `f` on collection `C` is\n * a write to `C`, so it must ALSO reach every whole-record (`'*'`) dependent of\n * `C` — the missing reachability step that made mutual/rotating rollup cycles\n * invisible (a rollup target is always a real field node and never itself a\n * graph SOURCE, so the old `_out.get(id)`-only walk dead-ended on it).\n *\n * TRAVERSAL-LOCAL ONLY (law, #642): this is a virtual adjacency computed\n * during the DFS walk, reading `_out` only. It must NEVER be materialized via\n * `registerDerived` (no new `(C,f)→(C,'*')` edge) and must NEVER touch `_in` —\n * putting `(C,'*')` into `_in` would flip `_contribution('C\\0*')` from the\n * `_wildcardContribution` fold (`#642`) onto the `_computeEffective` path,\n * bleeding cycle-reachability taint into `foldWildcardSecurity`'s posture\n * fold. Posture folding (`_contribution`/`_computeEffective`/\n * `_wildcardContribution`) never reads `_out`, so an expansion that reads\n * `_out` only is provably unable to perturb it. */\n // #671 item 5 — exclude `kind:'ref'` consuming edges: mutual FK lookups (two\n // collections each referencing the other) are legal and must not be treated as a\n // derivation cycle. Ref edges exist for cascade/rename machinery\n // (`referencingEdgesOf`/delete-time restrict/cascade/nullify), never derivation\n // ordering, so they carry no ordering constraint here. #678 — `kind` is read off\n // THIS `_out` entry (edge-local), NOT re-derefed from `_in`: a dual-role target\n // (e.g. #631's exempt {computed, lookup} composition) can have its `_in` entry's\n // `kind` overwritten by a LATER `registerDerived` call for the SAME target, so\n // asking `_in` \"what kind is `t` registered as NOW\" wrongly excluded a real\n // computed edge from the DFS as if it were a ref edge, hiding a genuine\n // derivation cycle. Asking \"what kind is THIS specific edge\" is correct\n // regardless of what else was later registered for the target.\n const notRefEdge = (entry: OutEdge): boolean => entry.kind !== 'ref'\n const neighboursOf = (id: string): readonly FieldRef[] => {\n const own = (this._out.get(id) ?? []).filter(notRefEdge).map((entry) => entry.target)\n const sep = id.indexOf(SEP)\n if (id.slice(sep + 1) === '*') return own\n const wildcard = (this._out.get(`${id.slice(0, sep)}${SEP}*`) ?? []).filter(notRefEdge).map((entry) => entry.target)\n if (wildcard.length === 0) return own\n return [...own, ...wildcard]\n }\n\n const visit = (id: string): void => {\n const idx = stack.indexOf(id)\n if (idx !== -1) {\n const cycle = stack.slice(idx).concat(id)\n const isMv = cycle.some(cycleId => this._in.get(cycleId)?.kind === 'mv')\n const path = cycle.map(displayNodeId)\n if (isMv) throw new MaterializedViewCycleError(path)\n throw new DerivationCycleError(path)\n }\n if (visited.has(id)) return\n stack.push(id)\n for (const dependent of neighboursOf(id)) visit(nodeId(dependent))\n stack.pop()\n visited.add(id)\n }\n\n for (const id of this._out.keys()) visit(id)\n }\n\n /** A leaf (non-derived) node's own posture contribution: its declared posture,\n * or `DEFAULT_POSTURE` if never declared via `registerField`. */\n private _declaredPosture(id: string): ViaPosture {\n return this._posture.get(id) ?? DEFAULT_POSTURE\n }\n\n /** A node's posture contribution when folded into a dependent: recurse if it is itself\n * derived; else its declared/default posture — UNLESS it is a `'*'` LEAF node consumed\n * by a folded formula kind (#642, `derivation|rollup|mv|overlay`), in which case it\n * contributes its collection's whole-record security fold ({@link _wildcardContribution}).\n * `kind` is the CONSUMING edge's kind, threaded from {@link _computeEffective}. `'ref'`\n * edges (and the provenance-only untyped call, `kind` left `undefined`) keep `'*'` =\n * identity — the phase-D lookup reliance (`via/lookup/registry.ts:392-397`) that a\n * referencing field must not seal just because its dimension collection has a classified\n * column. */\n private _contribution(id: string, kind?: EdgeKind): ViaPosture {\n const edge = this._in.get(id)\n if (edge) return this._computeEffective(id, edge)\n if (kind !== undefined && FOLDED_KINDS.has(kind) && id.endsWith(`${SEP}*`)) {\n return this._wildcardContribution(id.slice(0, -2))\n }\n return this._declaredPosture(id)\n }\n\n /** Lazy fold (#642) of a collection's REGISTERED field postures on the security axes only\n * ({@link foldWildcardSecurity} — sealed-wins encryptedAtRest, AND exportable, OR\n * forgettable; queryable stays at DEFAULT_POSTURE's 'full', never folded), seeded at\n * DEFAULT_POSTURE. This is the collection-level posture a `'*'` LEAF node contributes to a\n * folded-kind formula edge (derivation/rollup/mv/overlay) — see {@link _contribution}. A\n * plain (unregistered) field contributes nothing (the identity), so the fold is strictly\n * more conservative than deps-based taint and never hits the KNOWN-LIMIT wall (it names no\n * fields — seam map §1d). Memoized per collection in `_wildcardCache`. */\n private _wildcardContribution(collection: string): ViaPosture {\n const cached = this._wildcardCache.get(collection)\n if (cached) return cached\n let result = DEFAULT_POSTURE\n const prefix = `${collection}${SEP}`\n for (const [id, posture] of this._posture) {\n if (!id.startsWith(prefix) || id === `${prefix}*`) continue\n result = foldWildcardSecurity(result, posture)\n }\n this._wildcardCache.set(collection, result)\n return result\n }\n\n private _computeEffective(id: string, edge: DerivedEdge): ViaPosture {\n const cached = this._effectiveCache.get(id)\n if (cached) return cached\n let result = DEFAULT_POSTURE\n for (const source of edge.sources) {\n result = foldPosture(result, this._contribution(nodeId(source), edge.kind))\n }\n // #638 Task 7 — a virtual field is computed fresh on every read and never\n // stored, so it is structurally unqueryable regardless of what its\n // sources' fold would otherwise permit (e.g. a money-sourced virtual\n // field must NOT inherit money's 'ordered' queryability — there is no\n // stored/indexed form to query against). Every OTHER axis (exportable/\n // forgettable/encryptedAtRest) still folds normally — the taint rule is\n // identical to a materialized field; only queryability is a fixed,\n // grain-level property, not a source-derived one.\n if (edge.grain === 'virtual' && result.queryable !== 'none') {\n result = { ...result, queryable: 'none' }\n }\n this._effectiveCache.set(id, result)\n return result\n }\n\n /** Strictest source posture on every axis, per §2. `undefined` when `target` has no\n * in-edges (not a derived field). Transitive: folds through chained derivations. */\n effectivePosture(target: FieldRef): ViaPosture | undefined {\n const id = nodeId(target)\n const edge = this._in.get(id)\n if (!edge) return undefined\n return this._computeEffective(id, edge)\n }\n\n /** Per-collection { field → effectivePosture } overlay the pipeline consumes (Task 3). */\n taintedPostures(collection: string): ReadonlyMap<string, ViaPosture> {\n const out = new Map<string, ViaPosture>()\n for (const edge of this._in.values()) {\n if (edge.target.collection !== collection) continue\n out.set(edge.target.field, this._computeEffective(nodeId(edge.target), edge))\n }\n return out\n }\n\n /** Materialized (`grain !== 'virtual'`) derived fields on `collection` whose effective\n * encryptedAtRest resolves to 'sealed' — the taint-seal set (Task 3). #638 Task 7\n * makes the `grain !== 'virtual'` filter meaningful: a `computed(fn, { mode: 'virtual' })`\n * field is never stored (rides the `present` phase, seam map Part 4's money-Formatted/\n * i18n-Label precedent), so it is EXCLUDED here even when its effective `encryptedAtRest`\n * folds to `'sealed'` — there is no envelope slot to seal. It still surfaces in\n * {@link taintedPostures} (query refusal via `postureFor`'s `queryable` clamp above, and\n * export refusal via `exportable`) — only the AT-REST SEALING ACTION is skipped. */\n taintSealedFields(collection: string): ReadonlySet<string> {\n const out = new Set<string>()\n for (const edge of this._in.values()) {\n if (edge.target.collection !== collection || edge.grain === 'virtual') continue\n const posture = this._computeEffective(nodeId(edge.target), edge)\n if (posture.encryptedAtRest === 'sealed') out.add(edge.target.field)\n }\n return out\n }\n\n /** Fields on `collection` whose registered edge is `grain === 'virtual'` (#638 Task 7) —\n * `via/graph-wiring.ts#applyTaintOverlay` intersects this with `exportable === false`\n * postures to know which virtual fields need PRESENT-TIME (not just export-time)\n * redaction, since a virtual field's value is only ever materialized inside `present()`. */\n virtualFields(collection: string): ReadonlySet<string> {\n const out = new Set<string>()\n for (const edge of this._in.values()) {\n if (edge.target.collection === collection && edge.grain === 'virtual') out.add(edge.target.field)\n }\n return out\n }\n\n /** Per-collection { field → immediate source field names that forced its\n * effective posture away from `DEFAULT_POSTURE` } — `describe()`'s\n * provenance (Task 3). Only the DIRECT declared sources are named (not the\n * ultimate origin several hops up a transitive chain); a source absent\n * from the result contributed nothing restrictive. */\n taintProvenance(collection: string): ReadonlyMap<string, readonly string[]> {\n const out = new Map<string, readonly string[]>()\n for (const edge of this._in.values()) {\n if (edge.target.collection !== collection) continue\n const forcedBy = edge.sources\n .filter((source) => !isDefaultPosture(this._contribution(nodeId(source))))\n .map((source) => source.field)\n if (forcedBy.length > 0) out.set(edge.target.field, forcedBy)\n }\n return out\n }\n\n private _targetsDependingOn(collection: string): ReadonlyArray<{ readonly target: FieldRef; readonly kind: EdgeKind; readonly grain: Grain }> {\n const out: Array<{ target: FieldRef; kind: EdgeKind; grain: Grain }> = []\n for (const edge of this._in.values()) {\n if (edge.sources.some(source => source.collection === collection)) {\n out.push({ target: edge.target, kind: edge.kind, grain: edge.grain })\n }\n }\n return out\n }\n\n /** Dispatch (Task 4): every derived target triggered by a write to `collection`. Excludes\n * `'ref'` edges (#650 Task 5 review, folded Minor) — a `'ref'` edge is consulted only by the\n * delete/forget-time restrict/cascade/nullify path ({@link referencingEdgesOf}), never by the\n * sync/cutover/restore dispatch wave (`runGraphDispatchWave`); counting it here defeated that\n * wave's zero-cost early-continue, costing every write to a referenced backing collection an\n * unconditional decrypt + two no-op dispatch passes. {@link derivedArtifactsOf} (erasure\n * fanout) still includes `'ref'` edges — the forget path genuinely needs them. */\n dependentsOf(collection: string): ReadonlyArray<{ readonly target: FieldRef; readonly kind: EdgeKind; readonly grain: Grain }> {\n return this._targetsDependingOn(collection).filter((edge) => edge.kind !== 'ref')\n }\n\n /** Erasure (Task 6): derived artifacts of a forgotten record whose source is `collection`. */\n derivedArtifactsOf(collection: string): ReadonlyArray<{ readonly target: FieldRef; readonly kind: EdgeKind; readonly grain: Grain }> {\n return this._targetsDependingOn(collection)\n }\n\n /** Referencing edges pointing AT a backing dimension (delete/forget-time restrict/cascade/\n * nullify, #650 Task 5) — an O(1) reverse lookup via the existing `_out` map (keyed at the\n * dimension's wildcard `field:'*'` node, the same convention every whole-collection source\n * already uses), NEVER a scan across collections or records. `backing` is the collection name\n * a lookup field's edge was registered against (a reserved dimension's `_dict_<name>`/\n * `_lookup_<name>` collection name, or a matrix dimension's own collection name). */\n referencingEdgesOf(backing: string): ReadonlyArray<{ readonly referencing: FieldRef; readonly onDelete: OnDelete; readonly keyField: string }> {\n const targets = this._out.get(nodeId({ collection: backing, field: '*' }))\n if (!targets) return []\n const out: Array<{ referencing: FieldRef; onDelete: OnDelete; keyField: string }> = []\n for (const entry of targets) {\n // #678 — `kind` is read directly off THIS `_out` entry (edge-local) instead of\n // re-derefing `_in`. This also fixes the symmetric ref-vanishes hazard: under a\n // registration order where a LATER `registerDerived` call for the same target\n // overwrites `_in`'s kind away from `'ref'`, the old `_in`-derefing check would\n // silently drop a genuine referencing edge from cascade/nullify delete machinery\n // even though this specific edge was truly registered as `'ref'`.\n if (entry.kind !== 'ref') continue\n const edge = this._in.get(nodeId(entry.target))\n if (edge?.onDelete !== undefined) {\n out.push({ referencing: entry.target, onDelete: edge.onDelete, keyField: edge.keyField ?? 'id' })\n }\n }\n return out\n }\n}\n"],"mappings":"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","names":["via","via"]}
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ATTESTATIONS_COLLECTION,
|
|
3
3
|
loadOrCreateSigner
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-ANATMFIO.js";
|
|
5
5
|
import {
|
|
6
6
|
generateULID
|
|
7
7
|
} from "./chunk-4AOERLTV.js";
|
|
8
8
|
import {
|
|
9
9
|
buildRecordAad
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-77K4PG6P.js";
|
|
11
11
|
import {
|
|
12
12
|
buildRecordEnvelope
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-SZJ3DLZA.js";
|
|
14
14
|
import {
|
|
15
15
|
encrypt
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-SL3JAAKN.js";
|
|
17
17
|
import {
|
|
18
18
|
AttestationError
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-7O3Y4PPD.js";
|
|
20
20
|
|
|
21
21
|
// src/with-audit/attestation/issue.ts
|
|
22
22
|
import {
|
|
@@ -63,4 +63,4 @@ async function issueAttestationCore(ctx, args) {
|
|
|
63
63
|
export {
|
|
64
64
|
issueAttestationCore
|
|
65
65
|
};
|
|
66
|
-
//# sourceMappingURL=chunk-
|
|
66
|
+
//# sourceMappingURL=chunk-2N4GY74U.js.map
|