@remnic/core 9.69.86 → 9.69.88
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/access-admin-ops-surface.js +74 -67
- package/dist/access-authorization-probe.js +75 -68
- package/dist/access-boundary.js +74 -67
- package/dist/access-citation-namespace.js +2 -2
- package/dist/access-cli.js +158 -151
- package/dist/access-cli.js.map +1 -1
- package/dist/access-extraction-force-flush.d.ts.map +1 -1
- package/dist/access-extraction-force-flush.js +74 -67
- package/dist/access-http-briefing.js +75 -68
- package/dist/access-http-offline-stream.d.ts.map +1 -1
- package/dist/access-http-offline-stream.js +1 -1
- package/dist/access-http-query.js +76 -69
- package/dist/access-http.js +100 -93
- package/dist/access-identity-continuity-surface.js +74 -67
- package/dist/access-lcm-surface.js +74 -67
- package/dist/access-mcp-output-schemas.d.ts.map +1 -1
- package/dist/access-mcp-output-schemas.js +1 -1
- package/dist/access-mcp.d.ts.map +1 -1
- package/dist/access-mcp.js +89 -82
- package/dist/access-namespace-preflight.js +74 -67
- package/dist/access-observe-write-category.js +19 -13
- package/dist/access-observe-write-surface.js +74 -67
- package/dist/access-offline-manifest.js +15 -10
- package/dist/access-operations-batch.js +78 -71
- package/dist/access-operations.js +85 -78
- package/dist/access-recall-concurrency.js +74 -67
- package/dist/access-recall-diagnostics.js +4 -4
- package/dist/access-recall-response.js +74 -67
- package/dist/access-recall-surface.js +74 -67
- package/dist/access-schema.js +15 -7
- package/dist/access-service-helpers.d.ts +1 -0
- package/dist/access-service-helpers.d.ts.map +1 -1
- package/dist/access-service-helpers.js +1 -1
- package/dist/access-service.d.ts.map +1 -1
- package/dist/access-service.js +74 -67
- package/dist/access-surface-catalog.js +76 -69
- package/dist/access-surface-catalog.js.map +1 -1
- package/dist/active-recall.js +34 -28
- package/dist/active-recall.js.map +1 -1
- package/dist/adapters/index.js +4 -4
- package/dist/adapters/registry.js +2 -2
- package/dist/{auto-sync-WEUDMXUW.js → auto-sync-U5N3CB5Y.js} +10 -10
- package/dist/background-generation.js +2 -2
- package/dist/briefing.js +18 -18
- package/dist/buffer.js +9 -8
- package/dist/calibration.js +2 -2
- package/dist/{capsule-crypto-GWVG7LGC.js → capsule-crypto-YO5QJ6L3.js} +2 -2
- package/dist/{capsule-merge-3MNURAQ3.js → capsule-merge-ZCXUPLNJ.js} +2 -2
- package/dist/causal-behavior.js +2 -2
- package/dist/causal-chain.js +2 -2
- package/dist/causal-consolidation.js +21 -21
- package/dist/causal-retrieval.js +2 -2
- package/dist/causal-trajectory-graph.js +3 -3
- package/dist/causal-trajectory.js +1 -1
- package/dist/{chunk-JE334SIA.js → chunk-22DYJLFN.js} +2 -2
- package/dist/{chunk-DGAWEJVI.js → chunk-2DLWLNO4.js} +3 -3
- package/dist/{chunk-J3IWHCMF.js → chunk-2DT7PIDZ.js} +3 -3
- package/dist/{chunk-NKFLHW7J.js → chunk-2NAD4YCI.js} +2 -2
- package/dist/{chunk-SV72F4DS.js → chunk-2WLMWP2T.js} +2 -2
- package/dist/{chunk-IVH7INFM.js → chunk-3O5BB45T.js} +7 -7
- package/dist/{chunk-RDEUG2M2.js → chunk-3SGTV7RD.js} +6 -6
- package/dist/{chunk-QOPB6KE3.js → chunk-3TB2XQ3C.js} +2 -2
- package/dist/{chunk-C7JAUNFC.js → chunk-4KN2JLQV.js} +2 -2
- package/dist/{chunk-TIQZNDZ5.js → chunk-4MP7XR5J.js} +2 -2
- package/dist/chunk-4NSLQ7EU.js +137 -0
- package/dist/chunk-4NSLQ7EU.js.map +1 -0
- package/dist/{chunk-7DE2NOON.js → chunk-4O4XCBOS.js} +3 -3
- package/dist/{chunk-SLEAJ67D.js → chunk-4OQET73E.js} +4 -4
- package/dist/{chunk-Q3THVX75.js → chunk-4RL3JOB3.js} +2 -2
- package/dist/{chunk-GDYU6VF4.js → chunk-5AYUHSAU.js} +2 -2
- package/dist/{chunk-B47OHVFT.js → chunk-5E6RYRYW.js} +7 -7
- package/dist/{chunk-2U3R3DDH.js → chunk-5FAGCOZD.js} +9 -9
- package/dist/{chunk-CRKWSSS4.js → chunk-5MNUBT7T.js} +2 -2
- package/dist/{chunk-CK5KOVHW.js → chunk-5R627MYY.js} +3 -2
- package/dist/{chunk-CK5KOVHW.js.map → chunk-5R627MYY.js.map} +1 -1
- package/dist/chunk-5X4MXNEU.js +64 -0
- package/dist/chunk-5X4MXNEU.js.map +1 -0
- package/dist/{chunk-52II7PB6.js → chunk-645WOU5I.js} +4 -4
- package/dist/{chunk-7G6WUOLB.js → chunk-66DKTOBY.js} +2 -2
- package/dist/{chunk-AZ2X5LNA.js → chunk-6LYAEM54.js} +2 -2
- package/dist/{chunk-DUJYRVUD.js → chunk-6O2VUWV6.js} +3 -3
- package/dist/{chunk-IMAP236M.js → chunk-6UQFJULG.js} +2 -2
- package/dist/chunk-75PT4N7Q.js +75 -0
- package/dist/chunk-75PT4N7Q.js.map +1 -0
- package/dist/{chunk-2I6VHX6Q.js → chunk-76M5OK7V.js} +2 -2
- package/dist/{chunk-OEBLZZKK.js → chunk-7XG7KMIW.js} +2 -2
- package/dist/{chunk-FYAU4S6E.js → chunk-A4VSOUCB.js} +3 -3
- package/dist/{chunk-GEX5NI36.js → chunk-AE5U5NMS.js} +2 -2
- package/dist/{chunk-UNJOB4DY.js → chunk-AEHVZY3X.js} +2 -2
- package/dist/{chunk-ML2MVAEZ.js → chunk-AEU4EQGV.js} +1 -1
- package/dist/{chunk-3SG4FGDV.js → chunk-AWD36R4D.js} +5 -2
- package/dist/chunk-AWD36R4D.js.map +1 -0
- package/dist/{chunk-JVY556FW.js → chunk-AWG3TIAY.js} +2 -2
- package/dist/{chunk-JX6USXZR.js → chunk-AXC4WSF3.js} +4 -4
- package/dist/{chunk-BOUFVFV2.js → chunk-AZSGSRIM.js} +2 -2
- package/dist/{chunk-VZBW6CDG.js → chunk-B3O3IRZN.js} +1 -1
- package/dist/{chunk-4V44AA7O.js → chunk-BGI4NUAO.js} +2 -2
- package/dist/{chunk-BNPLDVM6.js → chunk-BJVO4H5C.js} +2 -2
- package/dist/{chunk-S42HZILI.js → chunk-BLVR4WYU.js} +3 -3
- package/dist/{chunk-JXMECXMF.js → chunk-BOZJD5PK.js} +2 -2
- package/dist/{chunk-6DTJBTHL.js → chunk-BUQKSQXL.js} +15 -3
- package/dist/chunk-BUQKSQXL.js.map +1 -0
- package/dist/{chunk-OWHERGF2.js → chunk-BXLOS5AJ.js} +2 -2
- package/dist/{chunk-EVBI7S4J.js → chunk-C6U57KG4.js} +4 -4
- package/dist/{chunk-RB776UH3.js → chunk-C7V3KPKJ.js} +235 -93
- package/dist/chunk-C7V3KPKJ.js.map +1 -0
- package/dist/{chunk-T4BE5KJM.js → chunk-C7ZDKWPS.js} +4 -4
- package/dist/{chunk-HKFJ3PF3.js → chunk-CRXRZA3G.js} +2 -2
- package/dist/{chunk-NMBX4D7P.js → chunk-CZJA2EQE.js} +2 -2
- package/dist/{chunk-BJX3VQWZ.js → chunk-D5BSQR63.js} +2 -2
- package/dist/{chunk-MFZACYZ6.js → chunk-DGS34QSY.js} +2 -2
- package/dist/{chunk-UVYI6VIX.js → chunk-DQEMWVMT.js} +1 -1
- package/dist/{chunk-DQISIT63.js → chunk-DZ42MDZE.js} +3 -3
- package/dist/{chunk-5ELENZTA.js → chunk-EDIH6X2P.js} +2 -2
- package/dist/{chunk-3BTFBQLO.js → chunk-EFHNFTWB.js} +49 -3
- package/dist/chunk-EFHNFTWB.js.map +1 -0
- package/dist/{chunk-C3QXITIP.js → chunk-EQUD7FP4.js} +2 -2
- package/dist/chunk-ETUZFFPU.js +218 -0
- package/dist/chunk-ETUZFFPU.js.map +1 -0
- package/dist/{chunk-YNDLCWXS.js → chunk-EZ25VE3G.js} +4 -4
- package/dist/{chunk-IA3X2Y4K.js → chunk-FJLQXMTU.js} +3 -3
- package/dist/{chunk-TY446V34.js → chunk-FKD656D2.js} +2 -2
- package/dist/{chunk-CLXTDOKV.js → chunk-FUNBJQYR.js} +2 -2
- package/dist/{chunk-CLSYE5OZ.js → chunk-G2STTRYB.js} +2 -2
- package/dist/{chunk-SQDKX4RW.js → chunk-GWM6T5EQ.js} +2 -2
- package/dist/{chunk-AXDOF4VI.js → chunk-GZDTVYK2.js} +2 -2
- package/dist/{chunk-55FCXCXJ.js → chunk-H56VY4BY.js} +7 -7
- package/dist/{chunk-OM5BIPBR.js → chunk-H5BJWPUI.js} +4 -4
- package/dist/{chunk-7QK5TUTW.js → chunk-HLB7GKGG.js} +2 -2
- package/dist/{chunk-CHDGJJV6.js → chunk-HWLIMQE2.js} +2 -2
- package/dist/{chunk-QB75LKQQ.js → chunk-IOSZHHJC.js} +34 -15
- package/dist/chunk-IOSZHHJC.js.map +1 -0
- package/dist/{chunk-NAFPHFDM.js → chunk-JNLEJE4A.js} +2 -2
- package/dist/{chunk-7UUKRS3J.js → chunk-JVPWRNHA.js} +3 -3
- package/dist/{chunk-6ET2VII7.js → chunk-JYG2334B.js} +2 -2
- package/dist/chunk-K6T33R4Q.js +535 -0
- package/dist/chunk-K6T33R4Q.js.map +1 -0
- package/dist/{chunk-2QG4SLZI.js → chunk-KF7PQ7G2.js} +2 -2
- package/dist/{chunk-WIKO4SCR.js → chunk-LHRQBMJN.js} +2 -2
- package/dist/{chunk-IFCKHPY4.js → chunk-LO4UKPKX.js} +2 -2
- package/dist/{chunk-TEV2JGU5.js → chunk-LU7E2MXE.js} +19 -19
- package/dist/{chunk-RJLV4BKR.js → chunk-LV5H6FTN.js} +2 -2
- package/dist/{chunk-IBGEHKQ6.js → chunk-LW3HKRL7.js} +3 -3
- package/dist/{chunk-3XQYM4RE.js → chunk-M6C7SOR6.js} +2 -2
- package/dist/{chunk-JN72EPOE.js → chunk-MAAL6OZV.js} +7 -7
- package/dist/chunk-MAAL6OZV.js.map +1 -0
- package/dist/{chunk-MY2PLXSM.js → chunk-MCTM4YPL.js} +2 -1
- package/dist/{chunk-MY2PLXSM.js.map → chunk-MCTM4YPL.js.map} +1 -1
- package/dist/{chunk-T4QGUXCV.js → chunk-MXCAJKMA.js} +9 -9
- package/dist/{chunk-BMYZTZ5D.js → chunk-MY7B3HYC.js} +2 -2
- package/dist/{chunk-NB3LRY4T.js → chunk-N4PYB235.js} +2 -2
- package/dist/{chunk-S3YM4SZQ.js → chunk-N7QV3CMX.js} +2 -2
- package/dist/{chunk-3GN2PEOT.js → chunk-NYKIUQL6.js} +2 -2
- package/dist/{chunk-WQZZDN5M.js → chunk-OCFXVDBZ.js} +322 -376
- package/dist/chunk-OCFXVDBZ.js.map +1 -0
- package/dist/{chunk-L2LBMKSI.js → chunk-OK52IY3W.js} +10 -10
- package/dist/{chunk-WB2I2EQK.js → chunk-P2ODTYOF.js} +2 -2
- package/dist/{chunk-RIEX7NOZ.js → chunk-PEBHPCX2.js} +2 -2
- package/dist/{chunk-VYCOJKSX.js → chunk-PO7NXNGC.js} +2 -2
- package/dist/{chunk-G6SVZWPB.js → chunk-PZX3AQLF.js} +44 -1
- package/dist/chunk-PZX3AQLF.js.map +1 -0
- package/dist/{chunk-XAITGGX5.js → chunk-Q4AUIFUA.js} +4 -4
- package/dist/{chunk-EU3N5MK3.js → chunk-QAW55ZHJ.js} +4 -4
- package/dist/{chunk-SVZWVZ7E.js → chunk-QB57WIS6.js} +101 -93
- package/dist/chunk-QB57WIS6.js.map +1 -0
- package/dist/{chunk-I4G4UWQA.js → chunk-QI2E6ISQ.js} +1 -1
- package/dist/{chunk-CK5U7JGH.js → chunk-QI7K7BZ5.js} +2 -2
- package/dist/{chunk-VTPASHTO.js → chunk-R3X2T2LP.js} +3 -3
- package/dist/{chunk-I53NAHZ4.js → chunk-RBITPCMK.js} +10 -9
- package/dist/chunk-RBITPCMK.js.map +1 -0
- package/dist/{chunk-EJPF6XDQ.js → chunk-RDJ6C7NZ.js} +3 -3
- package/dist/{chunk-C2WWQ4OR.js → chunk-RMMA44HE.js} +1 -1
- package/dist/chunk-RMMA44HE.js.map +1 -0
- package/dist/{chunk-QC56VZXC.js → chunk-S2GE2K36.js} +85 -82
- package/dist/{chunk-QC56VZXC.js.map → chunk-S2GE2K36.js.map} +1 -1
- package/dist/{chunk-2UPTRDGM.js → chunk-SCXURCVT.js} +3 -3
- package/dist/{chunk-S55WTPFJ.js → chunk-STEOT4DI.js} +20 -20
- package/dist/chunk-STEOT4DI.js.map +1 -0
- package/dist/{chunk-N3MNDVJO.js → chunk-SWBC3UER.js} +2 -2
- package/dist/{chunk-ZTHGFTMW.js → chunk-TKC5LZ43.js} +2 -2
- package/dist/chunk-TYT4TEQV.js +45 -0
- package/dist/chunk-TYT4TEQV.js.map +1 -0
- package/dist/{chunk-YRLHEEQT.js → chunk-U6VC6RP3.js} +2 -2
- package/dist/chunk-UCPGOUDZ.js +726 -0
- package/dist/chunk-UCPGOUDZ.js.map +1 -0
- package/dist/{chunk-MOQPEFLN.js → chunk-UP75KL3L.js} +2 -2
- package/dist/{chunk-D5F7TKMH.js → chunk-V4JZCTMK.js} +2 -2
- package/dist/{chunk-NAYBHNGN.js → chunk-VALKBYBN.js} +2 -2
- package/dist/{chunk-BUKK5SWA.js → chunk-VDX2J7OX.js} +2 -2
- package/dist/{chunk-H36X4NRH.js → chunk-VVX5PZFS.js} +2 -2
- package/dist/{chunk-RCQKAOOB.js → chunk-W3XXFPRI.js} +52 -52
- package/dist/{chunk-W75BBBSY.js → chunk-WKY7N3L7.js} +11 -11
- package/dist/{chunk-GZAGLCQH.js → chunk-X5SHE2O3.js} +3 -3
- package/dist/{chunk-OAOBL6OY.js → chunk-XOV7NRY5.js} +5 -5
- package/dist/{chunk-FZVROZKC.js → chunk-XVZA6VXC.js} +4 -4
- package/dist/{chunk-RGMVMVMF.js → chunk-YBA52OKG.js} +2 -1
- package/dist/chunk-YBA52OKG.js.map +1 -0
- package/dist/{chunk-IP5VLSLO.js → chunk-YJ7MW627.js} +2 -2
- package/dist/{chunk-HS75MCQF.js → chunk-YRULQW5J.js} +2 -2
- package/dist/{chunk-DINRT75P.js → chunk-YSBL7VPO.js} +2 -2
- package/dist/{chunk-QWUJWBZ5.js → chunk-Z3O53WZR.js} +2 -2
- package/dist/{chunk-KERNN6BC.js → chunk-Z5LP6ILP.js} +2 -2
- package/dist/{chunk-5FNZ3G6X.js → chunk-Z6EZCN6Z.js} +5 -5
- package/dist/chunk-ZJP66Q4I.js +48 -0
- package/dist/chunk-ZJP66Q4I.js.map +1 -0
- package/dist/{chunk-JS3S2HVG.js → chunk-ZZZ4I455.js} +2 -2
- package/dist/cli.js +122 -115
- package/dist/coding/export-okf-codegraph.js +19 -19
- package/dist/coding/pre-action-gate.js +2 -2
- package/dist/compounding/engine.js +19 -19
- package/dist/config.js +34 -28
- package/dist/connectors/codex-materialize-runner.js +18 -18
- package/dist/connectors/index.js +18 -18
- package/dist/console/state.d.ts +30 -0
- package/dist/console/state.d.ts.map +1 -1
- package/dist/contradiction/index.js +7 -7
- package/dist/{contradiction-scan-5EJYRKD3.js → contradiction-scan-TAGMOUQ2.js} +3 -3
- package/dist/convergence-refresh.js +20 -20
- package/dist/corpus-watermark.js +20 -20
- package/dist/correction/correction-access-wiring.d.ts.map +1 -1
- package/dist/dashboard-runtime.js +2 -2
- package/dist/deep-recall-http-glue.js +15 -8
- package/dist/deep-recall-policy-llm.js +3 -3
- package/dist/deep-recall.js +2 -2
- package/dist/embedding-fallback.d.ts +41 -31
- package/dist/embedding-fallback.d.ts.map +1 -1
- package/dist/embedding-fallback.js +9 -1
- package/dist/embedding-generation-lock.d.ts +49 -0
- package/dist/embedding-generation-lock.d.ts.map +1 -0
- package/dist/embedding-generation-lock.js +19 -0
- package/dist/embedding-index-storage.d.ts +276 -0
- package/dist/embedding-index-storage.d.ts.map +1 -0
- package/dist/embedding-index-storage.js +28 -0
- package/dist/entity-retrieval.js +19 -19
- package/dist/event-order-recall.js +3 -3
- package/dist/explicit-capture.js +6 -6
- package/dist/external-wiki-access.js +75 -68
- package/dist/extraction-faithfulness.js +3 -3
- package/dist/extraction-judge.js +3 -3
- package/dist/extraction-liveness.d.ts +9 -0
- package/dist/extraction-liveness.d.ts.map +1 -1
- package/dist/extraction-liveness.js +2 -1
- package/dist/extraction-llm-health.d.ts +32 -0
- package/dist/extraction-llm-health.d.ts.map +1 -0
- package/dist/extraction-llm-health.js +17 -0
- package/dist/extraction-span-config.js +3 -2
- package/dist/extraction-span-materialize.js +2 -2
- package/dist/extraction.js +29 -28
- package/dist/fallback-llm.js +2 -2
- package/dist/{first-start-migration-GAT7G733.js → first-start-migration-7OATHJKB.js} +4 -4
- package/dist/{graph-edge-decay-PVKDKLQK.js → graph-edge-decay-MKIRZ762.js} +6 -6
- package/dist/graph-jsonl.js +4 -4
- package/dist/graph-snapshot.js +4 -4
- package/dist/graph.js +5 -5
- package/dist/harmonic-retrieval.js +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +237 -206
- package/dist/json-extract.d.ts.map +1 -1
- package/dist/json-extract.js +1 -1
- package/dist/lcm/engine.js +2 -2
- package/dist/lcm/index.js +5 -5
- package/dist/local-llm.d.ts.map +1 -1
- package/dist/local-llm.js +2 -2
- package/dist/location/index.js +21 -21
- package/dist/maintenance/memory-governance.js +18 -18
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +18 -18
- package/dist/maintenance/rebuild-memory-projection.js +19 -19
- package/dist/memory-browse-operations.js +75 -68
- package/dist/memory-browse.js +3 -3
- package/dist/memory-subject.js +3 -3
- package/dist/namespaces/migrate.js +19 -19
- package/dist/namespaces/search.js +4 -4
- package/dist/namespaces/storage.js +18 -18
- package/dist/offline-sync-embedding-generation.d.ts +207 -0
- package/dist/offline-sync-embedding-generation.d.ts.map +1 -0
- package/dist/offline-sync-embedding-generation.js +42 -0
- package/dist/offline-sync-embedding-generation.js.map +1 -0
- package/dist/offline-sync-exclude-globs.d.ts +15 -0
- package/dist/offline-sync-exclude-globs.d.ts.map +1 -1
- package/dist/offline-sync-exclude-globs.js +11 -3
- package/dist/offline-sync-file-io.d.ts +7 -0
- package/dist/offline-sync-file-io.d.ts.map +1 -1
- package/dist/offline-sync-file-io.js +14 -2
- package/dist/offline-sync-impression-drain.js +3 -3
- package/dist/offline-sync-runtime-state.d.ts +5 -0
- package/dist/offline-sync-runtime-state.d.ts.map +1 -0
- package/dist/offline-sync-runtime-state.js +14 -0
- package/dist/offline-sync-runtime-state.js.map +1 -0
- package/dist/offline-sync-snapshot-stream.d.ts +26 -0
- package/dist/offline-sync-snapshot-stream.d.ts.map +1 -0
- package/dist/offline-sync-snapshot-stream.js +28 -0
- package/dist/offline-sync-snapshot-stream.js.map +1 -0
- package/dist/offline-sync-upload-staging.d.ts +34 -0
- package/dist/offline-sync-upload-staging.d.ts.map +1 -0
- package/dist/offline-sync-upload-staging.js +26 -0
- package/dist/offline-sync-upload-staging.js.map +1 -0
- package/dist/offline-sync.d.ts +46 -27
- package/dist/offline-sync.d.ts.map +1 -1
- package/dist/offline-sync.js +21 -8
- package/dist/operator-doctor-corpus.js +21 -21
- package/dist/operator-toolkit.js +46 -40
- package/dist/orchestration/extraction-run.d.ts.map +1 -1
- package/dist/orchestration/maintenance.js +30 -30
- package/dist/orchestrator.d.ts.map +1 -1
- package/dist/orchestrator.js +159 -152
- package/dist/recall-navigation-operations.js +75 -68
- package/dist/recall-navigation.js +74 -67
- package/dist/recall-planner-llm.js +2 -2
- package/dist/recall-state-view-admission.js +3 -3
- package/dist/recall-why-service.js +6 -6
- package/dist/recall-why.js +3 -3
- package/dist/reconcile/manifest.js +4 -4
- package/dist/{resolution-UYJU5JUA.js → resolution-K4A3VPKZ.js} +8 -8
- package/dist/resolution-K4A3VPKZ.js.map +1 -0
- package/dist/resume-bundles.js +35 -29
- package/dist/salvage-envelope.js +5 -5
- package/dist/search/factory.js +3 -3
- package/dist/search/index.js +7 -7
- package/dist/secure-store/index.js +2 -2
- package/dist/secure-store/secure-fs.d.ts +14 -1
- package/dist/secure-store/secure-fs.d.ts.map +1 -1
- package/dist/semantic-consolidation.js +19 -19
- package/dist/semantic-rule-promotion.js +18 -18
- package/dist/semantic-rule-verifier.js +18 -18
- package/dist/source-agent-qualifier.js +23 -22
- package/dist/standup/build.js +18 -18
- package/dist/{state-ITXJKXRE.js → state-JB47KHYV.js} +2 -2
- package/dist/state-JB47KHYV.js.map +1 -0
- package/dist/storage.d.ts +9 -3
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +17 -17
- package/dist/subject-config.js +4 -4
- package/dist/summarizer.js +6 -6
- package/dist/support-passport/index.js +77 -70
- package/dist/{trace-ZFVRH4GO.js → trace-LXXCMZJA.js} +3 -3
- package/dist/transfer/backup.js +2 -2
- package/dist/transfer/capsule-export.js +2 -2
- package/dist/transfer/capsule-import.js +3 -3
- package/dist/transfer/export-okf.js +19 -19
- package/dist/{tui-55UJMJX7.js → tui-2Z5WOV7L.js} +3 -3
- package/dist/tui-2Z5WOV7L.js.map +1 -0
- package/dist/verified-recall.js +18 -18
- package/dist/who-knows-cli.js +19 -19
- package/dist/who-knows.js +18 -18
- package/dist/write-envelope.js +4 -4
- package/package.json +2 -2
- package/src/access-extraction-force-flush.ts +15 -7
- package/src/access-http-offline-stream.ts +3 -0
- package/src/access-mcp-output-schemas.ts +1 -0
- package/src/access-mcp.ts +90 -28
- package/src/access-service-health.test.ts +41 -5
- package/src/access-service-helpers.ts +1 -0
- package/src/access-service-observe-lcm-parity.test.ts +56 -24
- package/src/access-service.ts +7 -18
- package/src/console/state.test.ts +56 -0
- package/src/console/state.ts +83 -0
- package/src/correction/correction-access-wiring.ts +36 -8
- package/src/correction/correction-classify-parse.test.ts +178 -0
- package/src/embedding-fallback.ts +325 -141
- package/src/embedding-generation-lock.ts +141 -0
- package/src/embedding-index-storage.test.ts +245 -0
- package/src/embedding-index-storage.ts +1068 -0
- package/src/extraction-liveness.ts +13 -1
- package/src/extraction-llm-health.test.ts +103 -0
- package/src/extraction-llm-health.ts +71 -0
- package/src/index.ts +3 -3
- package/src/json-extract.ts +6 -0
- package/src/local-llm-thinking.test.ts +12 -0
- package/src/local-llm.ts +1 -0
- package/src/offline-sync-embedding-generation.test.ts +2173 -0
- package/src/offline-sync-embedding-generation.ts +885 -0
- package/src/offline-sync-exclude-globs.ts +112 -0
- package/src/offline-sync-file-io.ts +48 -0
- package/src/offline-sync-runtime-state.ts +48 -0
- package/src/offline-sync-snapshot-stream.ts +99 -0
- package/src/offline-sync-upload-staging.ts +291 -0
- package/src/offline-sync.test.ts +164 -1
- package/src/offline-sync.ts +458 -453
- package/src/orchestration/extraction-run.test.ts +55 -1
- package/src/orchestration/extraction-run.ts +13 -0
- package/src/orchestrator.ts +2 -1
- package/src/secure-store/secure-fs.ts +26 -6
- package/src/storage.ts +11 -6
- package/dist/chunk-3BTFBQLO.js.map +0 -1
- package/dist/chunk-3SG4FGDV.js.map +0 -1
- package/dist/chunk-6DTJBTHL.js.map +0 -1
- package/dist/chunk-AREGMX2J.js +0 -50
- package/dist/chunk-AREGMX2J.js.map +0 -1
- package/dist/chunk-C2WWQ4OR.js.map +0 -1
- package/dist/chunk-G6SVZWPB.js.map +0 -1
- package/dist/chunk-I53NAHZ4.js.map +0 -1
- package/dist/chunk-JN72EPOE.js.map +0 -1
- package/dist/chunk-QB75LKQQ.js.map +0 -1
- package/dist/chunk-RB776UH3.js.map +0 -1
- package/dist/chunk-RGMVMVMF.js.map +0 -1
- package/dist/chunk-S55WTPFJ.js.map +0 -1
- package/dist/chunk-SVZWVZ7E.js.map +0 -1
- package/dist/chunk-WQZZDN5M.js.map +0 -1
- /package/dist/{auto-sync-WEUDMXUW.js.map → auto-sync-U5N3CB5Y.js.map} +0 -0
- /package/dist/{capsule-crypto-GWVG7LGC.js.map → capsule-crypto-YO5QJ6L3.js.map} +0 -0
- /package/dist/{capsule-merge-3MNURAQ3.js.map → capsule-merge-ZCXUPLNJ.js.map} +0 -0
- /package/dist/{chunk-JE334SIA.js.map → chunk-22DYJLFN.js.map} +0 -0
- /package/dist/{chunk-DGAWEJVI.js.map → chunk-2DLWLNO4.js.map} +0 -0
- /package/dist/{chunk-J3IWHCMF.js.map → chunk-2DT7PIDZ.js.map} +0 -0
- /package/dist/{chunk-NKFLHW7J.js.map → chunk-2NAD4YCI.js.map} +0 -0
- /package/dist/{chunk-SV72F4DS.js.map → chunk-2WLMWP2T.js.map} +0 -0
- /package/dist/{chunk-IVH7INFM.js.map → chunk-3O5BB45T.js.map} +0 -0
- /package/dist/{chunk-RDEUG2M2.js.map → chunk-3SGTV7RD.js.map} +0 -0
- /package/dist/{chunk-QOPB6KE3.js.map → chunk-3TB2XQ3C.js.map} +0 -0
- /package/dist/{chunk-C7JAUNFC.js.map → chunk-4KN2JLQV.js.map} +0 -0
- /package/dist/{chunk-TIQZNDZ5.js.map → chunk-4MP7XR5J.js.map} +0 -0
- /package/dist/{chunk-7DE2NOON.js.map → chunk-4O4XCBOS.js.map} +0 -0
- /package/dist/{chunk-SLEAJ67D.js.map → chunk-4OQET73E.js.map} +0 -0
- /package/dist/{chunk-Q3THVX75.js.map → chunk-4RL3JOB3.js.map} +0 -0
- /package/dist/{chunk-GDYU6VF4.js.map → chunk-5AYUHSAU.js.map} +0 -0
- /package/dist/{chunk-B47OHVFT.js.map → chunk-5E6RYRYW.js.map} +0 -0
- /package/dist/{chunk-2U3R3DDH.js.map → chunk-5FAGCOZD.js.map} +0 -0
- /package/dist/{chunk-CRKWSSS4.js.map → chunk-5MNUBT7T.js.map} +0 -0
- /package/dist/{chunk-52II7PB6.js.map → chunk-645WOU5I.js.map} +0 -0
- /package/dist/{chunk-7G6WUOLB.js.map → chunk-66DKTOBY.js.map} +0 -0
- /package/dist/{chunk-AZ2X5LNA.js.map → chunk-6LYAEM54.js.map} +0 -0
- /package/dist/{chunk-DUJYRVUD.js.map → chunk-6O2VUWV6.js.map} +0 -0
- /package/dist/{chunk-IMAP236M.js.map → chunk-6UQFJULG.js.map} +0 -0
- /package/dist/{chunk-2I6VHX6Q.js.map → chunk-76M5OK7V.js.map} +0 -0
- /package/dist/{chunk-OEBLZZKK.js.map → chunk-7XG7KMIW.js.map} +0 -0
- /package/dist/{chunk-FYAU4S6E.js.map → chunk-A4VSOUCB.js.map} +0 -0
- /package/dist/{chunk-GEX5NI36.js.map → chunk-AE5U5NMS.js.map} +0 -0
- /package/dist/{chunk-UNJOB4DY.js.map → chunk-AEHVZY3X.js.map} +0 -0
- /package/dist/{chunk-ML2MVAEZ.js.map → chunk-AEU4EQGV.js.map} +0 -0
- /package/dist/{chunk-JVY556FW.js.map → chunk-AWG3TIAY.js.map} +0 -0
- /package/dist/{chunk-JX6USXZR.js.map → chunk-AXC4WSF3.js.map} +0 -0
- /package/dist/{chunk-BOUFVFV2.js.map → chunk-AZSGSRIM.js.map} +0 -0
- /package/dist/{chunk-VZBW6CDG.js.map → chunk-B3O3IRZN.js.map} +0 -0
- /package/dist/{chunk-4V44AA7O.js.map → chunk-BGI4NUAO.js.map} +0 -0
- /package/dist/{chunk-BNPLDVM6.js.map → chunk-BJVO4H5C.js.map} +0 -0
- /package/dist/{chunk-S42HZILI.js.map → chunk-BLVR4WYU.js.map} +0 -0
- /package/dist/{chunk-JXMECXMF.js.map → chunk-BOZJD5PK.js.map} +0 -0
- /package/dist/{chunk-OWHERGF2.js.map → chunk-BXLOS5AJ.js.map} +0 -0
- /package/dist/{chunk-EVBI7S4J.js.map → chunk-C6U57KG4.js.map} +0 -0
- /package/dist/{chunk-T4BE5KJM.js.map → chunk-C7ZDKWPS.js.map} +0 -0
- /package/dist/{chunk-HKFJ3PF3.js.map → chunk-CRXRZA3G.js.map} +0 -0
- /package/dist/{chunk-NMBX4D7P.js.map → chunk-CZJA2EQE.js.map} +0 -0
- /package/dist/{chunk-BJX3VQWZ.js.map → chunk-D5BSQR63.js.map} +0 -0
- /package/dist/{chunk-MFZACYZ6.js.map → chunk-DGS34QSY.js.map} +0 -0
- /package/dist/{chunk-UVYI6VIX.js.map → chunk-DQEMWVMT.js.map} +0 -0
- /package/dist/{chunk-DQISIT63.js.map → chunk-DZ42MDZE.js.map} +0 -0
- /package/dist/{chunk-5ELENZTA.js.map → chunk-EDIH6X2P.js.map} +0 -0
- /package/dist/{chunk-C3QXITIP.js.map → chunk-EQUD7FP4.js.map} +0 -0
- /package/dist/{chunk-YNDLCWXS.js.map → chunk-EZ25VE3G.js.map} +0 -0
- /package/dist/{chunk-IA3X2Y4K.js.map → chunk-FJLQXMTU.js.map} +0 -0
- /package/dist/{chunk-TY446V34.js.map → chunk-FKD656D2.js.map} +0 -0
- /package/dist/{chunk-CLXTDOKV.js.map → chunk-FUNBJQYR.js.map} +0 -0
- /package/dist/{chunk-CLSYE5OZ.js.map → chunk-G2STTRYB.js.map} +0 -0
- /package/dist/{chunk-SQDKX4RW.js.map → chunk-GWM6T5EQ.js.map} +0 -0
- /package/dist/{chunk-AXDOF4VI.js.map → chunk-GZDTVYK2.js.map} +0 -0
- /package/dist/{chunk-55FCXCXJ.js.map → chunk-H56VY4BY.js.map} +0 -0
- /package/dist/{chunk-OM5BIPBR.js.map → chunk-H5BJWPUI.js.map} +0 -0
- /package/dist/{chunk-7QK5TUTW.js.map → chunk-HLB7GKGG.js.map} +0 -0
- /package/dist/{chunk-CHDGJJV6.js.map → chunk-HWLIMQE2.js.map} +0 -0
- /package/dist/{chunk-NAFPHFDM.js.map → chunk-JNLEJE4A.js.map} +0 -0
- /package/dist/{chunk-7UUKRS3J.js.map → chunk-JVPWRNHA.js.map} +0 -0
- /package/dist/{chunk-6ET2VII7.js.map → chunk-JYG2334B.js.map} +0 -0
- /package/dist/{chunk-2QG4SLZI.js.map → chunk-KF7PQ7G2.js.map} +0 -0
- /package/dist/{chunk-WIKO4SCR.js.map → chunk-LHRQBMJN.js.map} +0 -0
- /package/dist/{chunk-IFCKHPY4.js.map → chunk-LO4UKPKX.js.map} +0 -0
- /package/dist/{chunk-TEV2JGU5.js.map → chunk-LU7E2MXE.js.map} +0 -0
- /package/dist/{chunk-RJLV4BKR.js.map → chunk-LV5H6FTN.js.map} +0 -0
- /package/dist/{chunk-IBGEHKQ6.js.map → chunk-LW3HKRL7.js.map} +0 -0
- /package/dist/{chunk-3XQYM4RE.js.map → chunk-M6C7SOR6.js.map} +0 -0
- /package/dist/{chunk-T4QGUXCV.js.map → chunk-MXCAJKMA.js.map} +0 -0
- /package/dist/{chunk-BMYZTZ5D.js.map → chunk-MY7B3HYC.js.map} +0 -0
- /package/dist/{chunk-NB3LRY4T.js.map → chunk-N4PYB235.js.map} +0 -0
- /package/dist/{chunk-S3YM4SZQ.js.map → chunk-N7QV3CMX.js.map} +0 -0
- /package/dist/{chunk-3GN2PEOT.js.map → chunk-NYKIUQL6.js.map} +0 -0
- /package/dist/{chunk-L2LBMKSI.js.map → chunk-OK52IY3W.js.map} +0 -0
- /package/dist/{chunk-WB2I2EQK.js.map → chunk-P2ODTYOF.js.map} +0 -0
- /package/dist/{chunk-RIEX7NOZ.js.map → chunk-PEBHPCX2.js.map} +0 -0
- /package/dist/{chunk-VYCOJKSX.js.map → chunk-PO7NXNGC.js.map} +0 -0
- /package/dist/{chunk-XAITGGX5.js.map → chunk-Q4AUIFUA.js.map} +0 -0
- /package/dist/{chunk-EU3N5MK3.js.map → chunk-QAW55ZHJ.js.map} +0 -0
- /package/dist/{chunk-I4G4UWQA.js.map → chunk-QI2E6ISQ.js.map} +0 -0
- /package/dist/{chunk-CK5U7JGH.js.map → chunk-QI7K7BZ5.js.map} +0 -0
- /package/dist/{chunk-VTPASHTO.js.map → chunk-R3X2T2LP.js.map} +0 -0
- /package/dist/{chunk-EJPF6XDQ.js.map → chunk-RDJ6C7NZ.js.map} +0 -0
- /package/dist/{chunk-2UPTRDGM.js.map → chunk-SCXURCVT.js.map} +0 -0
- /package/dist/{chunk-N3MNDVJO.js.map → chunk-SWBC3UER.js.map} +0 -0
- /package/dist/{chunk-ZTHGFTMW.js.map → chunk-TKC5LZ43.js.map} +0 -0
- /package/dist/{chunk-YRLHEEQT.js.map → chunk-U6VC6RP3.js.map} +0 -0
- /package/dist/{chunk-MOQPEFLN.js.map → chunk-UP75KL3L.js.map} +0 -0
- /package/dist/{chunk-D5F7TKMH.js.map → chunk-V4JZCTMK.js.map} +0 -0
- /package/dist/{chunk-NAYBHNGN.js.map → chunk-VALKBYBN.js.map} +0 -0
- /package/dist/{chunk-BUKK5SWA.js.map → chunk-VDX2J7OX.js.map} +0 -0
- /package/dist/{chunk-H36X4NRH.js.map → chunk-VVX5PZFS.js.map} +0 -0
- /package/dist/{chunk-RCQKAOOB.js.map → chunk-W3XXFPRI.js.map} +0 -0
- /package/dist/{chunk-W75BBBSY.js.map → chunk-WKY7N3L7.js.map} +0 -0
- /package/dist/{chunk-GZAGLCQH.js.map → chunk-X5SHE2O3.js.map} +0 -0
- /package/dist/{chunk-OAOBL6OY.js.map → chunk-XOV7NRY5.js.map} +0 -0
- /package/dist/{chunk-FZVROZKC.js.map → chunk-XVZA6VXC.js.map} +0 -0
- /package/dist/{chunk-IP5VLSLO.js.map → chunk-YJ7MW627.js.map} +0 -0
- /package/dist/{chunk-HS75MCQF.js.map → chunk-YRULQW5J.js.map} +0 -0
- /package/dist/{chunk-DINRT75P.js.map → chunk-YSBL7VPO.js.map} +0 -0
- /package/dist/{chunk-QWUJWBZ5.js.map → chunk-Z3O53WZR.js.map} +0 -0
- /package/dist/{chunk-KERNN6BC.js.map → chunk-Z5LP6ILP.js.map} +0 -0
- /package/dist/{chunk-5FNZ3G6X.js.map → chunk-Z6EZCN6Z.js.map} +0 -0
- /package/dist/{chunk-JS3S2HVG.js.map → chunk-ZZZ4I455.js.map} +0 -0
- /package/dist/{contradiction-scan-5EJYRKD3.js.map → contradiction-scan-TAGMOUQ2.js.map} +0 -0
- /package/dist/{graph-edge-decay-PVKDKLQK.js.map → embedding-generation-lock.js.map} +0 -0
- /package/dist/{resolution-UYJU5JUA.js.map → embedding-index-storage.js.map} +0 -0
- /package/dist/{state-ITXJKXRE.js.map → extraction-llm-health.js.map} +0 -0
- /package/dist/{first-start-migration-GAT7G733.js.map → first-start-migration-7OATHJKB.js.map} +0 -0
- /package/dist/{tui-55UJMJX7.js.map → graph-edge-decay-MKIRZ762.js.map} +0 -0
- /package/dist/{trace-ZFVRH4GO.js.map → trace-LXXCMZJA.js.map} +0 -0
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
|
-
import { mkdir, readFile, rename, rm, writeFile } from "node:fs/promises";
|
|
3
2
|
import { log } from "./logger.js";
|
|
4
3
|
import {
|
|
5
4
|
resolveMemoryLifecycleCapabilities,
|
|
@@ -13,9 +12,23 @@ import {
|
|
|
13
12
|
type HostEmbeddingProvider,
|
|
14
13
|
normalizeHostEmbeddingVector,
|
|
15
14
|
} from "./host-embedding-provider.js";
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
import {
|
|
16
|
+
EmbeddingIndexFileStore,
|
|
17
|
+
EmbeddingIndexStorageError,
|
|
18
|
+
type EmbeddingIndexEntry,
|
|
19
|
+
type EmbeddingIndexFile,
|
|
20
|
+
type EmbeddingIndexIdentity,
|
|
21
|
+
type EmbeddingProviderType,
|
|
22
|
+
EmbeddingIndexStoreIo,
|
|
23
|
+
} from "./embedding-index-storage.js";
|
|
24
|
+
export {
|
|
25
|
+
EmbeddingIndexCapacityError,
|
|
26
|
+
EmbeddingIndexStorageError,
|
|
27
|
+
} from "./embedding-index-storage.js";
|
|
28
|
+
export type {
|
|
29
|
+
EmbeddingIndexStatusFile,
|
|
30
|
+
EmbeddingIndexWriteFailure,
|
|
31
|
+
} from "./embedding-index-storage.js";
|
|
19
32
|
type ProviderConfig = {
|
|
20
33
|
type: EmbeddingProviderType;
|
|
21
34
|
model: string;
|
|
@@ -24,24 +37,11 @@ type ProviderConfig = {
|
|
|
24
37
|
hostProvider?: HostEmbeddingProvider;
|
|
25
38
|
};
|
|
26
39
|
|
|
27
|
-
type EmbeddingIndexEntry = {
|
|
28
|
-
vector: number[];
|
|
29
|
-
path: string;
|
|
30
|
-
};
|
|
31
|
-
|
|
32
40
|
type EmbeddingResult = {
|
|
33
41
|
provider: ProviderConfig;
|
|
34
42
|
vector: number[];
|
|
35
43
|
};
|
|
36
44
|
|
|
37
|
-
type EmbeddingIndexFile = {
|
|
38
|
-
version: 1;
|
|
39
|
-
provider: EmbeddingProviderType;
|
|
40
|
-
model: string;
|
|
41
|
-
entries: Record<string, EmbeddingIndexEntry>;
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
type EmbeddingIndexIdentity = Pick<EmbeddingIndexFile, "provider" | "model">;
|
|
45
45
|
type EmbeddingIndexComparable =
|
|
46
46
|
| EmbeddingIndexIdentity
|
|
47
47
|
| Pick<ProviderConfig, "type" | "model">;
|
|
@@ -77,6 +77,14 @@ const DEFAULT_OPENAI_MODEL = "text-embedding-3-small";
|
|
|
77
77
|
* The class name is kept for backward compatibility — `EmbeddingTimeoutError`
|
|
78
78
|
* now signals "lookup backend unavailable" rather than strictly "timed out".
|
|
79
79
|
*/
|
|
80
|
+
import {
|
|
81
|
+
assertEmbeddingGenerationLockHeld,
|
|
82
|
+
embeddingGenerationLockPath,
|
|
83
|
+
EmbeddingGenerationLockUnavailableError,
|
|
84
|
+
withEmbeddingGenerationLock,
|
|
85
|
+
type EmbeddingGenerationLockSection,
|
|
86
|
+
} from "./embedding-generation-lock.js";
|
|
87
|
+
|
|
80
88
|
export class EmbeddingTimeoutError extends Error {
|
|
81
89
|
override readonly name = "EmbeddingTimeoutError" as const;
|
|
82
90
|
constructor(message: string) {
|
|
@@ -165,12 +173,27 @@ function resolveEmbeddingIndexTimeoutMs(): number {
|
|
|
165
173
|
export type EmbedMode = "lookup" | "index";
|
|
166
174
|
|
|
167
175
|
export class EmbeddingFallback {
|
|
168
|
-
private readonly
|
|
176
|
+
private readonly store: EmbeddingIndexFileStore;
|
|
169
177
|
private loaded: EmbeddingIndexFile | null = null;
|
|
178
|
+
/** True when `loaded` was read from disk rather than started fresh, so identity probes can trust it. */
|
|
179
|
+
private loadedFromDisk = false;
|
|
170
180
|
private mutationQueue: Promise<void> = Promise.resolve();
|
|
171
181
|
|
|
172
|
-
|
|
173
|
-
|
|
182
|
+
/** The canonical state dir scoping this fallback's generation mutation lock. */
|
|
183
|
+
private readonly generationStateDir: string;
|
|
184
|
+
private readonly generationLockPath: string;
|
|
185
|
+
private lockSection: EmbeddingGenerationLockSection | null = null;
|
|
186
|
+
|
|
187
|
+
constructor(private readonly config: PluginConfig, storeIo?: EmbeddingIndexStoreIo) {
|
|
188
|
+
const stateDir = path.join(config.memoryDir, "state");
|
|
189
|
+
this.generationStateDir = stateDir;
|
|
190
|
+
this.generationLockPath = embeddingGenerationLockPath(stateDir);
|
|
191
|
+
this.store = new EmbeddingIndexFileStore(
|
|
192
|
+
path.join(stateDir, "embeddings.json"),
|
|
193
|
+
path.join(stateDir, "embeddings"),
|
|
194
|
+
path.join(stateDir, "embedding-fallback-status.json"),
|
|
195
|
+
storeIo,
|
|
196
|
+
);
|
|
174
197
|
}
|
|
175
198
|
|
|
176
199
|
async isAvailable(): Promise<boolean> {
|
|
@@ -265,61 +288,97 @@ export class EmbeddingFallback {
|
|
|
265
288
|
|
|
266
289
|
let queryResult = await this.embedForSearch(query, provider, options);
|
|
267
290
|
if (!queryResult) return [];
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
291
|
+
// Effective query embedding: swapped to the disk index's provider
|
|
292
|
+
// below when the on-disk generation has a different identity. `let` so
|
|
293
|
+
// the swap reassigns; TS narrowing bound for control flow.
|
|
294
|
+
let active = queryResult;
|
|
295
|
+
|
|
296
|
+
// Recall fails OPEN on index read failures (corrupt/oversized/mixed
|
|
297
|
+
// generations, unreadable shard dirs): return [] without caching so a
|
|
298
|
+
// later mutation still revalidates and fails closed (issue #3146).
|
|
299
|
+
try {
|
|
300
|
+
const diskIdentity = await this.readIndexIdentityFromDisk();
|
|
301
|
+
if (diskIdentity && !sameIndexIdentity(diskIdentity, queryResult.provider)) {
|
|
302
|
+
// The provider swap needs a NETWORK embed: run it OUTSIDE the
|
|
303
|
+
// generation lock, then re-verify the identity under the lock below.
|
|
304
|
+
const diskProvider = await this.resolveFallbackProviderForIndexIdentity(diskIdentity);
|
|
305
|
+
if (diskProvider) {
|
|
306
|
+
const diskQueryResult = await this.embedForSearch(query, diskProvider, options);
|
|
307
|
+
if (diskQueryResult && sameIndexIdentity(diskIdentity, diskQueryResult.provider)) {
|
|
308
|
+
active = diskQueryResult;
|
|
309
|
+
} else {
|
|
310
|
+
log.debug(
|
|
311
|
+
`embedding fallback search skipped: preserved ${diskIdentity.provider}/${diskIdentity.model} index is unavailable for lookup`,
|
|
312
|
+
);
|
|
313
|
+
return [];
|
|
314
|
+
}
|
|
276
315
|
} else {
|
|
277
316
|
log.debug(
|
|
278
|
-
`embedding fallback search skipped:
|
|
317
|
+
`embedding fallback search skipped: query provider ${queryResult.provider.type}/${queryResult.provider.model} does not match existing ${diskIdentity.provider}/${diskIdentity.model} index`,
|
|
279
318
|
);
|
|
280
319
|
return [];
|
|
281
320
|
}
|
|
282
|
-
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// Cold load only (cache miss): the complete shard enumeration + read
|
|
324
|
+
// happens under the generation mutation lock so a concurrent swap can
|
|
325
|
+
// never leave a cached SUBSET of the generation (codex
|
|
326
|
+
// PRRT_kwDORJXyws6mZ72p). Warm cached searches stay lock-free.
|
|
327
|
+
let index: EmbeddingIndexFile;
|
|
328
|
+
try {
|
|
329
|
+
index = await this.loadIndexUnderGenerationLock(active.provider);
|
|
330
|
+
} catch (err) {
|
|
331
|
+
if (err instanceof EmbeddingGenerationLockUnavailableError) {
|
|
332
|
+
// Existing read diagnostic, recorded once per failed load; recall
|
|
333
|
+
// itself fails open.
|
|
334
|
+
await this.store.recordIndexStatusForLoad(
|
|
335
|
+
`generation mutation lock unavailable: ${err instanceof Error ? err.message : String(err)}`,
|
|
336
|
+
);
|
|
337
|
+
return [];
|
|
338
|
+
}
|
|
339
|
+
throw err;
|
|
340
|
+
}
|
|
341
|
+
const ids = Object.keys(index.entries);
|
|
342
|
+
if (ids.length === 0) return [];
|
|
343
|
+
|
|
344
|
+
const includePrefix = normalizePathPrefix(options.pathPrefix);
|
|
345
|
+
const excludePrefixes = (options.pathExcludePrefixes ?? [])
|
|
346
|
+
.map((p) => normalizePathPrefix(p))
|
|
347
|
+
.filter((p): p is string => typeof p === "string");
|
|
348
|
+
|
|
349
|
+
const scored = ids
|
|
350
|
+
.map((id) => {
|
|
351
|
+
const entry = index.entries[id];
|
|
352
|
+
return {
|
|
353
|
+
id,
|
|
354
|
+
path: entry.path,
|
|
355
|
+
score: cosineSimilarity(active.vector, entry.vector),
|
|
356
|
+
};
|
|
357
|
+
})
|
|
358
|
+
.filter((r) => {
|
|
359
|
+
if (!Number.isFinite(r.score)) return false;
|
|
360
|
+
const normalized = normalizeEntryPath(r.path);
|
|
361
|
+
if (includePrefix !== undefined && !normalized.startsWith(includePrefix)) {
|
|
362
|
+
return false;
|
|
363
|
+
}
|
|
364
|
+
for (const excl of excludePrefixes) {
|
|
365
|
+
if (normalized.startsWith(excl)) return false;
|
|
366
|
+
}
|
|
367
|
+
return true;
|
|
368
|
+
})
|
|
369
|
+
.sort((a, b) => b.score - a.score)
|
|
370
|
+
.slice(0, Math.max(1, limit));
|
|
371
|
+
|
|
372
|
+
return scored;
|
|
373
|
+
} catch (err) {
|
|
374
|
+
if (err instanceof EmbeddingIndexStorageError) {
|
|
283
375
|
log.debug(
|
|
284
|
-
`embedding fallback
|
|
376
|
+
`embedding fallback index unreadable on recall path, failing open: ${err instanceof Error ? err.message : String(err)}`,
|
|
285
377
|
);
|
|
286
378
|
return [];
|
|
287
379
|
}
|
|
380
|
+
throw err;
|
|
288
381
|
}
|
|
289
|
-
|
|
290
|
-
const index = await this.loadIndex(queryResult.provider);
|
|
291
|
-
const ids = Object.keys(index.entries);
|
|
292
|
-
if (ids.length === 0) return [];
|
|
293
|
-
|
|
294
|
-
const includePrefix = normalizePathPrefix(options.pathPrefix);
|
|
295
|
-
const excludePrefixes = (options.pathExcludePrefixes ?? [])
|
|
296
|
-
.map((p) => normalizePathPrefix(p))
|
|
297
|
-
.filter((p): p is string => typeof p === "string");
|
|
298
|
-
|
|
299
|
-
const scored = ids
|
|
300
|
-
.map((id) => {
|
|
301
|
-
const entry = index.entries[id];
|
|
302
|
-
return {
|
|
303
|
-
id,
|
|
304
|
-
path: entry.path,
|
|
305
|
-
score: cosineSimilarity(queryResult.vector, entry.vector),
|
|
306
|
-
};
|
|
307
|
-
})
|
|
308
|
-
.filter((r) => {
|
|
309
|
-
if (!Number.isFinite(r.score)) return false;
|
|
310
|
-
const normalized = normalizeEntryPath(r.path);
|
|
311
|
-
if (includePrefix !== undefined && !normalized.startsWith(includePrefix)) {
|
|
312
|
-
return false;
|
|
313
|
-
}
|
|
314
|
-
for (const excl of excludePrefixes) {
|
|
315
|
-
if (normalized.startsWith(excl)) return false;
|
|
316
|
-
}
|
|
317
|
-
return true;
|
|
318
|
-
})
|
|
319
|
-
.sort((a, b) => b.score - a.score)
|
|
320
|
-
.slice(0, Math.max(1, limit));
|
|
321
|
-
|
|
322
|
-
return scored;
|
|
323
382
|
}
|
|
324
383
|
|
|
325
384
|
async indexFile(memoryId: string, content: string, filePath: string): Promise<void> {
|
|
@@ -336,25 +395,31 @@ export class EmbeddingFallback {
|
|
|
336
395
|
});
|
|
337
396
|
if (!result) return;
|
|
338
397
|
|
|
339
|
-
await this.enqueueIndexMutation(async () => {
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
398
|
+
await this.enqueueIndexMutation(memoryId, async () => {
|
|
399
|
+
try {
|
|
400
|
+
const existing = await this.readIndexIdentityFromDisk();
|
|
401
|
+
if (
|
|
402
|
+
existing &&
|
|
403
|
+
!sameIndexIdentity(existing, result.provider) &&
|
|
404
|
+
!canReplaceIndexIdentity(existing, result.provider)
|
|
405
|
+
) {
|
|
406
|
+
log.debug(
|
|
407
|
+
`embedding fallback index update skipped: ${result.provider.type}/${result.provider.model} would replace existing ${existing.provider}/${existing.model} index`,
|
|
408
|
+
);
|
|
409
|
+
return;
|
|
410
|
+
}
|
|
411
|
+
const index = await this.loadIndex(result.provider);
|
|
412
|
+
const relPath = toMemoryRelativePath(this.config.memoryDir, filePath);
|
|
413
|
+
index.entries[memoryId] = {
|
|
414
|
+
vector: result.vector,
|
|
415
|
+
path: relPath,
|
|
416
|
+
};
|
|
417
|
+
await this.saveIndex(index, { touchedIds: [memoryId], memoryId });
|
|
418
|
+
} catch (err) {
|
|
419
|
+
await this.store.recordIndexWriteOutcome(err, memoryId);
|
|
420
|
+
throw err;
|
|
350
421
|
}
|
|
351
|
-
|
|
352
|
-
const relPath = toMemoryRelativePath(this.config.memoryDir, filePath);
|
|
353
|
-
index.entries[memoryId] = {
|
|
354
|
-
vector: result.vector,
|
|
355
|
-
path: relPath,
|
|
356
|
-
};
|
|
357
|
-
await this.saveIndex(index);
|
|
422
|
+
await this.store.recordIndexWriteOutcome(null, memoryId);
|
|
358
423
|
});
|
|
359
424
|
}
|
|
360
425
|
|
|
@@ -362,7 +427,7 @@ export class EmbeddingFallback {
|
|
|
362
427
|
const provider = await this.resolveProvider();
|
|
363
428
|
if (!provider) return;
|
|
364
429
|
|
|
365
|
-
await this.enqueueIndexMutation(async () => {
|
|
430
|
+
await this.enqueueIndexMutation(memoryId, async () => {
|
|
366
431
|
const providers = [provider];
|
|
367
432
|
const diskIdentity = await this.readIndexIdentityFromDisk();
|
|
368
433
|
if (
|
|
@@ -381,17 +446,71 @@ export class EmbeddingFallback {
|
|
|
381
446
|
}
|
|
382
447
|
}
|
|
383
448
|
|
|
449
|
+
let saved = false;
|
|
384
450
|
for (const indexProvider of providers) {
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
451
|
+
try {
|
|
452
|
+
const index = await this.loadIndex(indexProvider);
|
|
453
|
+
if (!index.entries[memoryId]) continue;
|
|
454
|
+
delete index.entries[memoryId];
|
|
455
|
+
await this.saveIndex(index, { touchedIds: [memoryId], memoryId });
|
|
456
|
+
saved = true;
|
|
457
|
+
} catch (err) {
|
|
458
|
+
await this.store.recordIndexWriteOutcome(err, memoryId);
|
|
459
|
+
throw err;
|
|
460
|
+
}
|
|
389
461
|
}
|
|
462
|
+
// A no-op removal (id absent from every candidate index) performs no
|
|
463
|
+
// save: it must NOT clear a recorded persistence failure, or the
|
|
464
|
+
// operator console would report an unresolved failure as fixed
|
|
465
|
+
// without any demonstration that storage is writable (round 6).
|
|
466
|
+
if (saved) await this.store.recordIndexWriteOutcome(null, memoryId);
|
|
390
467
|
});
|
|
391
468
|
}
|
|
392
469
|
|
|
393
|
-
private enqueueIndexMutation<T>(mutation: () => Promise<T>): Promise<T> {
|
|
394
|
-
const run = this.mutationQueue
|
|
470
|
+
private enqueueIndexMutation<T>(memoryId: string | undefined, mutation: () => Promise<T>): Promise<T> {
|
|
471
|
+
const run = this.mutationQueue
|
|
472
|
+
.catch(() => undefined)
|
|
473
|
+
.then(() =>
|
|
474
|
+
withEmbeddingGenerationLock(this.generationStateDir, async (section) => {
|
|
475
|
+
this.lockSection = section;
|
|
476
|
+
try {
|
|
477
|
+
// A peer process may have persisted while this process did not
|
|
478
|
+
// hold the generation lock: drop any cached index so the
|
|
479
|
+
// mutation loads the real disk state (codex P1).
|
|
480
|
+
this.loaded = null;
|
|
481
|
+
this.loadedFromDisk = false;
|
|
482
|
+
// Recover an interrupted replacement BEFORE the mutation's identity
|
|
483
|
+
// probes and existence checks: a deletion no-op must not skip
|
|
484
|
+
// persistence while the published generation sits in the rename-gap
|
|
485
|
+
// backup, and insertions must load the restored vectors rather than
|
|
486
|
+
// a fresh empty index (issue #3148, codex round 3).
|
|
487
|
+
let recovered = false;
|
|
488
|
+
try {
|
|
489
|
+
recovered = await this.store.recoverIfInterrupted(this.generationFence());
|
|
490
|
+
} catch (err) {
|
|
491
|
+
// Record the recovery failure durably BEFORE rejecting the
|
|
492
|
+
// mutation: the write-outcome try below is never reached.
|
|
493
|
+
await this.store.recordIndexWriteOutcome(err).catch(() => undefined);
|
|
494
|
+
throw err;
|
|
495
|
+
}
|
|
496
|
+
if (recovered) {
|
|
497
|
+
this.loaded = null;
|
|
498
|
+
this.loadedFromDisk = false;
|
|
499
|
+
}
|
|
500
|
+
return await mutation();
|
|
501
|
+
} finally {
|
|
502
|
+
this.lockSection = null;
|
|
503
|
+
}
|
|
504
|
+
}).catch(async (err) => {
|
|
505
|
+
// A lock ACQUISITION failure never reaches the mutation closure's
|
|
506
|
+
// own write-outcome recording. Route it through the existing
|
|
507
|
+
// durable diagnostic exactly once (codex PRRT_kwDORJXyws6mZ8qS);
|
|
508
|
+
// in-lock failures were already recorded by the closure.
|
|
509
|
+
if (err instanceof EmbeddingGenerationLockUnavailableError) {
|
|
510
|
+
await this.store.recordIndexWriteOutcome(err, memoryId).catch(() => undefined);
|
|
511
|
+
}
|
|
512
|
+
throw err;
|
|
513
|
+
}));
|
|
395
514
|
this.mutationQueue = run.then(
|
|
396
515
|
() => undefined,
|
|
397
516
|
() => undefined,
|
|
@@ -666,32 +785,108 @@ export class EmbeddingFallback {
|
|
|
666
785
|
}
|
|
667
786
|
}
|
|
668
787
|
|
|
788
|
+
/**
|
|
789
|
+
* Load the authoritative generation for `provider`. STRICT: an unreadable,
|
|
790
|
+
* malformed, foreign-shaped, or mixed-identity index throws
|
|
791
|
+
* EmbeddingIndexStorageError instead of ever returning a partial view —
|
|
792
|
+
* recall catches it at its boundary and fails open uncached; mutations
|
|
793
|
+
* propagate it and fail closed. This.loaded is only ever assigned a fully
|
|
794
|
+
* validated generation.
|
|
795
|
+
*/
|
|
796
|
+
/**
|
|
797
|
+
* A fence the store calls immediately before destructive writes: reasserts
|
|
798
|
+
* THIS section's lock ownership after potentially long serialization.
|
|
799
|
+
* Fail closed when no section is held — persisting unsynchronized would
|
|
800
|
+
* reintroduce the lost-update race.
|
|
801
|
+
*/
|
|
802
|
+
private generationFence(): () => Promise<void> {
|
|
803
|
+
const section = this.lockSection;
|
|
804
|
+
if (!section) {
|
|
805
|
+
return async () => {
|
|
806
|
+
throw new EmbeddingIndexStorageError(
|
|
807
|
+
"embedding index mutation attempted outside the generation lock; refusing to publish",
|
|
808
|
+
);
|
|
809
|
+
};
|
|
810
|
+
}
|
|
811
|
+
return () => assertEmbeddingGenerationLockHeld(this.generationLockPath, section);
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
/**
|
|
815
|
+
* Cache-warm path: a normal search serves the in-memory index WITHOUT the
|
|
816
|
+
* lock (pre-existing staleness semantics: a peer swap between searches is
|
|
817
|
+
* refreshed by the next cold load). On a cache miss the COMPLETE load runs
|
|
818
|
+
* under the generation mutation lock so the enumeration + shard reads see
|
|
819
|
+
* exactly one generation. The identity is re-checked under the lock on the
|
|
820
|
+
* cold path; the caller has already performed any provider-swap embed
|
|
821
|
+
* outside the lock.
|
|
822
|
+
*/
|
|
823
|
+
private async loadIndexUnderGenerationLock(provider: ProviderConfig): Promise<EmbeddingIndexFile> {
|
|
824
|
+
if (this.loaded && this.loadedFromDisk) return this.loaded;
|
|
825
|
+
return await withEmbeddingGenerationLock(this.generationStateDir, async () => {
|
|
826
|
+
// Another in-process consumer may have warmed the cache while this
|
|
827
|
+
// call waited on the lock.
|
|
828
|
+
if (this.loaded && this.loadedFromDisk) return this.loaded;
|
|
829
|
+
// Re-check the on-disk identity UNDER the lock: a peer swap during the
|
|
830
|
+
// caller's embed means the cold load must fail open, never serve a
|
|
831
|
+
// mixed generation (codex PRRT_kwDORJXyws6mZ72p).
|
|
832
|
+
const diskIdentity = await this.store.identityFromDisk();
|
|
833
|
+
if (diskIdentity && !sameIndexIdentity(diskIdentity, provider)) {
|
|
834
|
+
throw new EmbeddingIndexStorageError(
|
|
835
|
+
`embedding index identity swapped to ${diskIdentity.provider}/${diskIdentity.model} during the cold load; failing open`,
|
|
836
|
+
);
|
|
837
|
+
}
|
|
838
|
+
return await this.loadIndex(provider);
|
|
839
|
+
});
|
|
840
|
+
}
|
|
841
|
+
|
|
669
842
|
private async loadIndex(provider: ProviderConfig): Promise<EmbeddingIndexFile> {
|
|
670
843
|
if (this.loaded && this.loaded.provider === provider.type && this.loaded.model === provider.model) {
|
|
671
844
|
return this.loaded;
|
|
672
845
|
}
|
|
673
846
|
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
847
|
+
const merged: Record<string, EmbeddingIndexEntry> = {};
|
|
848
|
+
let diskIdentity: EmbeddingIndexIdentity | null = null;
|
|
849
|
+
|
|
850
|
+
const layout = await this.store.detectLayout();
|
|
851
|
+
if (layout === "sharded") {
|
|
852
|
+
// Published generation: shards are the ONLY authoritative state. A
|
|
853
|
+
// legacy embeddings.json left over by a crash between the atomic
|
|
854
|
+
// publish and its recovery rename is never merged (single-generation
|
|
855
|
+
// rule, issue #3146).
|
|
856
|
+
diskIdentity = await this.store.readShardGenerationInto(merged);
|
|
857
|
+
} else if (layout === "legacy") {
|
|
858
|
+
const read = await this.store.readLegacy();
|
|
859
|
+
if (read.outcome === "ok") {
|
|
860
|
+
diskIdentity = { provider: read.file.provider, model: read.file.model };
|
|
861
|
+
Object.assign(merged, read.file.entries);
|
|
862
|
+
} else if (read.outcome === "unreadable") {
|
|
863
|
+
await this.store.recordIndexStatusForLoad(read.reason);
|
|
864
|
+
throw new EmbeddingIndexStorageError(
|
|
865
|
+
`refusing to continue from an unreadable embedding index at ${this.store.legacyPath}: ${read.reason}`,
|
|
866
|
+
);
|
|
867
|
+
} else if (read.outcome === "foreign") {
|
|
868
|
+
// Valid JSON but not an index we recognize (wrong version/shape).
|
|
869
|
+
// Overwriting it would destroy unknown data, so mutation fails
|
|
870
|
+
// closed; the file stays in place for recovery.
|
|
871
|
+
await this.store.recordIndexStatusForLoad("unrecognized index format");
|
|
872
|
+
throw new EmbeddingIndexStorageError(
|
|
873
|
+
`refusing to continue from a malformed embedding index at ${this.store.legacyPath} (unrecognized format); file preserved in place`,
|
|
874
|
+
);
|
|
692
875
|
}
|
|
693
|
-
|
|
694
|
-
//
|
|
876
|
+
// absent falls through to a fresh index; a readable legacy index with
|
|
877
|
+
// a different provider identity keeps the existing replace semantics
|
|
878
|
+
// (gated by canReplaceIndexIdentity at the mutation sites).
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
if (diskIdentity && diskIdentity.provider === provider.type && diskIdentity.model === provider.model) {
|
|
882
|
+
this.loaded = {
|
|
883
|
+
version: 1,
|
|
884
|
+
provider: provider.type,
|
|
885
|
+
model: provider.model,
|
|
886
|
+
entries: merged,
|
|
887
|
+
};
|
|
888
|
+
this.loadedFromDisk = true;
|
|
889
|
+
return this.loaded;
|
|
695
890
|
}
|
|
696
891
|
|
|
697
892
|
this.loaded = {
|
|
@@ -700,49 +895,38 @@ export class EmbeddingFallback {
|
|
|
700
895
|
model: provider.model,
|
|
701
896
|
entries: {},
|
|
702
897
|
};
|
|
898
|
+
this.loadedFromDisk = false;
|
|
703
899
|
return this.loaded;
|
|
704
900
|
}
|
|
705
901
|
|
|
706
902
|
private async readIndexIdentityFromDisk(): Promise<EmbeddingIndexIdentity | null> {
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
parsed.version === 1 &&
|
|
713
|
-
(parsed.provider === "openai" ||
|
|
714
|
-
parsed.provider === "local" ||
|
|
715
|
-
parsed.provider === "host") &&
|
|
716
|
-
typeof parsed.model === "string" &&
|
|
717
|
-
parsed.model.length > 0
|
|
718
|
-
) {
|
|
719
|
-
return {
|
|
720
|
-
provider: parsed.provider,
|
|
721
|
-
model: parsed.model,
|
|
722
|
-
};
|
|
723
|
-
}
|
|
724
|
-
} catch {
|
|
725
|
-
// Missing or invalid indexes are treated as absent; loadIndex() owns
|
|
726
|
-
// creating a fresh file when it is safe to write.
|
|
903
|
+
// After a load, `loaded` mirrors the disk state exactly (every mutation
|
|
904
|
+
// saves through saveIndex and a failed save invalidates the cache), so
|
|
905
|
+
// skip re-reading on every mutation.
|
|
906
|
+
if (this.loaded && this.loadedFromDisk) {
|
|
907
|
+
return { provider: this.loaded.provider, model: this.loaded.model };
|
|
727
908
|
}
|
|
728
|
-
return
|
|
909
|
+
return this.store.identityFromDisk();
|
|
729
910
|
}
|
|
730
911
|
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
912
|
+
/**
|
|
913
|
+
* Persist the index through the file store. On any failure the in-memory
|
|
914
|
+
* cache is invalidated: entries mutated in the cached map must never be
|
|
915
|
+
* mistaken for durable state by a retry or a later search.
|
|
916
|
+
*/
|
|
917
|
+
private async saveIndex(
|
|
918
|
+
index: EmbeddingIndexFile,
|
|
919
|
+
opts: { touchedIds?: readonly string[]; memoryId?: string } = {},
|
|
920
|
+
): Promise<void> {
|
|
738
921
|
try {
|
|
739
|
-
await
|
|
740
|
-
await rename(tempPath, this.indexPath);
|
|
922
|
+
await this.store.persist(index, { ...opts, fence: this.generationFence() });
|
|
741
923
|
} catch (err) {
|
|
742
|
-
|
|
924
|
+
this.loaded = null;
|
|
925
|
+
this.loadedFromDisk = false;
|
|
743
926
|
throw err;
|
|
744
927
|
}
|
|
745
928
|
this.loaded = index;
|
|
929
|
+
this.loadedFromDisk = true;
|
|
746
930
|
}
|
|
747
931
|
}
|
|
748
932
|
|