@remnic/core 9.65.7 → 9.66.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/dist/access-admin-ops-surface.d.ts +15 -14
- package/dist/access-admin-ops-surface.js +65 -62
- package/dist/access-authorization-probe.d.ts +15 -14
- package/dist/access-authorization-probe.js +66 -63
- package/dist/access-boundary.d.ts +15 -14
- package/dist/access-boundary.js +65 -62
- package/dist/access-citation-namespace.js +3 -3
- package/dist/access-cli.js +182 -174
- package/dist/access-cli.js.map +1 -1
- package/dist/access-coding-context-resolution.d.ts +2 -2
- package/dist/access-coding-context-resolution.js +2 -2
- package/dist/access-extraction-force-flush.d.ts +15 -14
- package/dist/access-extraction-force-flush.js +65 -62
- package/dist/access-health-types.d.ts +2 -2
- package/dist/access-http-lcm-compaction.d.ts +15 -14
- package/dist/access-http-lifecycle-flush.d.ts +15 -14
- package/dist/access-http-offline-stream.d.ts +15 -14
- package/dist/access-http-query.d.ts +3 -3
- package/dist/access-http-query.js +67 -64
- package/dist/access-http.d.ts +16 -15
- package/dist/access-http.js +87 -84
- package/dist/access-identity-continuity-surface.d.ts +13 -12
- package/dist/access-identity-continuity-surface.js +65 -62
- package/dist/access-lcm-surface.d.ts +15 -14
- package/dist/access-lcm-surface.js +65 -62
- package/dist/access-mcp-output-schemas.js +1 -1
- package/dist/access-mcp.d.ts +15 -14
- package/dist/access-mcp.js +77 -74
- package/dist/access-memory-search-fanout.d.ts +3 -3
- package/dist/{access-namespace-preflight-8VYKmRX0.d.ts → access-namespace-preflight-CLWUoMyW.d.ts} +1 -1
- package/dist/access-namespace-preflight.d.ts +4 -4
- package/dist/access-namespace-preflight.js +65 -62
- package/dist/access-observe-write-surface.d.ts +15 -14
- package/dist/access-observe-write-surface.js +65 -62
- package/dist/access-offline-manifest.d.ts +13 -12
- package/dist/access-offline-manifest.js +16 -16
- package/dist/access-operations-batch.js +69 -66
- package/dist/access-operations.d.ts +16 -15
- package/dist/access-operations.js +74 -71
- package/dist/access-recall-concurrency.d.ts +15 -14
- package/dist/access-recall-concurrency.js +65 -62
- package/dist/access-recall-response.d.ts +15 -14
- package/dist/access-recall-response.js +65 -62
- package/dist/access-recall-surface.d.ts +15 -14
- package/dist/access-recall-surface.js +65 -62
- package/dist/access-schema.js +7 -7
- package/dist/{access-service-Crk__Git.d.ts → access-service-CEUE1Isj.d.ts} +14 -14
- package/dist/access-service-helpers.d.ts +15 -14
- package/dist/access-service.d.ts +15 -14
- package/dist/access-service.js +65 -62
- package/dist/access-surface-catalog.d.ts +15 -14
- package/dist/access-surface-catalog.js +69 -64
- package/dist/access-surface-catalog.js.map +1 -1
- package/dist/access-wearables-meetings-surface.d.ts +6 -4
- package/dist/action-confidence.d.ts +2 -2
- package/dist/active-context-config.d.ts +27 -0
- package/dist/active-context-config.js +14 -0
- package/dist/active-context-transform.d.ts +267 -0
- package/dist/active-context-transform.js +31 -0
- package/dist/active-memory-bridge.d.ts +2 -2
- package/dist/active-memory-bridge.js +2 -2
- package/dist/active-recall.d.ts +2 -2
- package/dist/active-recall.js +17 -16
- package/dist/active-recall.js.map +1 -1
- package/dist/adapters/index.js +7 -7
- package/dist/adapters/registry.js +3 -3
- package/dist/ambient-provenance.d.ts +2 -2
- package/dist/artifact-search.d.ts +2 -2
- package/dist/{auto-sync-XVMLL2RH.js → auto-sync-Q6Q2FVSC.js} +10 -10
- package/dist/behavior-learner.d.ts +2 -2
- package/dist/behavior-signals.d.ts +2 -2
- package/dist/bootstrap.d.ts +13 -12
- package/dist/briefing-window.d.ts +5 -3
- package/dist/briefing.d.ts +5 -3
- package/dist/briefing.js +33 -33
- package/dist/buffer-surprise-report.d.ts +2 -2
- package/dist/buffer-turn-helpers.d.ts +2 -2
- package/dist/buffer.d.ts +5 -3
- package/dist/buffer.js +24 -8
- package/dist/bulk-import/index.d.ts +4 -4
- package/dist/calibration.d.ts +2 -2
- package/dist/calibration.js +1 -1
- package/dist/capabilities.d.ts +2 -2
- package/dist/{capsule-merge-SGIVB3WA.js → capsule-merge-SEHERWWP.js} +4 -4
- package/dist/{catalog-DybwVNW3.d.ts → catalog-D1HgugTA.d.ts} +1 -1
- package/dist/causal-behavior.d.ts +4 -4
- package/dist/causal-consolidation.d.ts +2 -2
- package/dist/causal-consolidation.js +34 -34
- package/dist/causal-trajectory-graph.d.ts +2 -2
- package/dist/{chunk-CFGU52XJ.js → chunk-23CVL7HS.js} +2 -2
- package/dist/{chunk-PO7NXBG2.js → chunk-2GF27PGH.js} +5 -5
- package/dist/{chunk-6CPUQ5D6.js → chunk-2LBAFHOQ.js} +15 -15
- package/dist/{chunk-JBPKEARU.js → chunk-2QSZNTDO.js} +7 -7
- package/dist/{chunk-IP4ZNT4U.js → chunk-33MFRY25.js} +2 -2
- package/dist/{chunk-VFYRYFLL.js → chunk-3TSU662L.js} +3 -3
- package/dist/chunk-43HUVDTD.js +114 -0
- package/dist/chunk-43HUVDTD.js.map +1 -0
- package/dist/{chunk-VXVZ2GM3.js → chunk-4FHRZD5T.js} +2 -2
- package/dist/{chunk-FP7YTTVO.js → chunk-4OFKZAJG.js} +2 -1
- package/dist/chunk-4OFKZAJG.js.map +1 -0
- package/dist/{chunk-5VPQSRQO.js → chunk-4STAANV7.js} +3 -3
- package/dist/{chunk-46WM6JX2.js → chunk-4ZWCQJNM.js} +5 -5
- package/dist/{chunk-LLQCM2U2.js → chunk-56IV4J5W.js} +617 -167
- package/dist/chunk-56IV4J5W.js.map +1 -0
- package/dist/{chunk-52II7PB6.js → chunk-645WOU5I.js} +4 -4
- package/dist/{chunk-YKWFK7XA.js → chunk-6CEGSTBD.js} +7 -7
- package/dist/{chunk-I7EX6KSH.js → chunk-6QDXA26G.js} +264 -210
- package/dist/chunk-6QDXA26G.js.map +1 -0
- package/dist/{chunk-GEPACVWN.js → chunk-6RUHELWR.js} +3 -3
- package/dist/{chunk-ZAOHJDKH.js → chunk-72OIT7KS.js} +4 -4
- package/dist/{chunk-KQAFEZQX.js → chunk-7LCGFUMB.js} +4 -4
- package/dist/{chunk-7TCGNUVP.js → chunk-7UTDHQZ5.js} +3 -3
- package/dist/{chunk-5HK3CJAR.js → chunk-7XOG75AU.js} +3 -3
- package/dist/{chunk-7BDZTALN.js → chunk-AJTG3CP7.js} +12 -2
- package/dist/chunk-AJTG3CP7.js.map +1 -0
- package/dist/{chunk-2LWQSV6A.js → chunk-AL3UYZ5N.js} +3 -2
- package/dist/chunk-AL3UYZ5N.js.map +1 -0
- package/dist/chunk-B32WYRXX.js +77 -0
- package/dist/chunk-B32WYRXX.js.map +1 -0
- package/dist/{chunk-C24UZSFW.js → chunk-CEH2AFXG.js} +6 -6
- package/dist/{chunk-YOXVZJFM.js → chunk-CFVTRUR3.js} +2 -2
- package/dist/{chunk-ACOC27BB.js → chunk-CN4VKV3S.js} +2 -2
- package/dist/{chunk-PMVPCZJZ.js → chunk-CTCGHNWN.js} +6 -6
- package/dist/{chunk-EGBDFJ36.js → chunk-DD5JFCWM.js} +2 -2
- package/dist/{chunk-T42L3S6A.js → chunk-DDX6KIXF.js} +2 -2
- package/dist/{chunk-JIYDRBVZ.js → chunk-DJORULH3.js} +2 -2
- package/dist/{chunk-WTOZBZNN.js → chunk-DMEHOEC7.js} +6 -6
- package/dist/{chunk-OPPBTPUU.js → chunk-DUAJKRR2.js} +4 -4
- package/dist/{chunk-XDL5CYZN.js → chunk-EEOUMG3J.js} +2 -1
- package/dist/{chunk-XDL5CYZN.js.map → chunk-EEOUMG3J.js.map} +1 -1
- package/dist/{chunk-SVVIASVX.js → chunk-EFQCDJZ2.js} +7 -7
- package/dist/{chunk-Q57GOHLF.js → chunk-EGALNSZ4.js} +3 -3
- package/dist/{chunk-KCT36JAW.js → chunk-ESNFSSO4.js} +2 -2
- package/dist/{chunk-XQ3HXAQH.js → chunk-ET2CNMLD.js} +4 -4
- package/dist/{chunk-Z4U3UN56.js → chunk-EZSCW4EM.js} +6 -6
- package/dist/{chunk-F6QHHRWP.js → chunk-FESUGFIL.js} +3 -3
- package/dist/{chunk-S3K2CIK5.js → chunk-FKKGCGYL.js} +3 -3
- package/dist/{chunk-BWGCOLEL.js → chunk-FTTJRVB7.js} +2 -2
- package/dist/{chunk-JAQXUGLN.js → chunk-FYWLSFFS.js} +2 -2
- package/dist/{chunk-BJTHRFFC.js → chunk-GEJKYA7D.js} +77 -36
- package/dist/chunk-GEJKYA7D.js.map +1 -0
- package/dist/chunk-GSKINLAK.js +267 -0
- package/dist/chunk-GSKINLAK.js.map +1 -0
- package/dist/{chunk-OPGL46PX.js → chunk-GX6FTSYH.js} +2 -2
- package/dist/{chunk-A32YEQAM.js → chunk-H7VDIF2V.js} +2 -2
- package/dist/{chunk-PDDSFELN.js → chunk-HJXA6ZM7.js} +2 -2
- package/dist/{chunk-RGCF4XNH.js → chunk-HNPE66LB.js} +8 -8
- package/dist/{chunk-SEA6M7SS.js → chunk-I5VB44ZK.js} +2 -2
- package/dist/{chunk-SDEPLF7V.js → chunk-IBJ6U753.js} +2 -2
- package/dist/{chunk-EUYWQ7TS.js → chunk-IEZ6CGTW.js} +2 -2
- package/dist/{chunk-RQE4TITU.js → chunk-IHGMRDEE.js} +431 -1834
- package/dist/chunk-IHGMRDEE.js.map +1 -0
- package/dist/{chunk-3RI5Y7KU.js → chunk-IVIAHQBR.js} +2 -2
- package/dist/{chunk-7WR462EM.js → chunk-J3OND5QT.js} +4 -4
- package/dist/{chunk-UW5NPZJ2.js → chunk-JALOAKSZ.js} +59 -7
- package/dist/chunk-JALOAKSZ.js.map +1 -0
- package/dist/{chunk-T3JQTCCO.js → chunk-JI7U6AS3.js} +4 -4
- package/dist/{chunk-DVYRD4HY.js → chunk-JRRQ747T.js} +36 -7
- package/dist/chunk-JRRQ747T.js.map +1 -0
- package/dist/{chunk-I32NKXE2.js → chunk-JTWZKNUH.js} +5 -5
- package/dist/chunk-K66OY4EI.js +202 -0
- package/dist/chunk-K66OY4EI.js.map +1 -0
- package/dist/{chunk-XAB6STPO.js → chunk-KODXCHXJ.js} +17 -3
- package/dist/chunk-KODXCHXJ.js.map +1 -0
- package/dist/{chunk-ZPUIRTIZ.js → chunk-KOLJJN5G.js} +12 -75
- package/dist/chunk-KOLJJN5G.js.map +1 -0
- package/dist/{chunk-FMQ4MOQO.js → chunk-KXIXO76C.js} +32 -19
- package/dist/chunk-KXIXO76C.js.map +1 -0
- package/dist/{chunk-VKCAHCBI.js → chunk-L4X4PJYK.js} +2 -2
- package/dist/chunk-LB7WCZHY.js +553 -0
- package/dist/chunk-LB7WCZHY.js.map +1 -0
- package/dist/{chunk-W4BMEGQA.js → chunk-LUDBXTBJ.js} +8 -8
- package/dist/{chunk-I4343FIA.js → chunk-MAH64N55.js} +28 -10
- package/dist/chunk-MAH64N55.js.map +1 -0
- package/dist/{chunk-RIAM7DND.js → chunk-ME35HVDJ.js} +2 -2
- package/dist/{chunk-H63EDPFJ.js → chunk-MI2OTWV5.js} +15 -2
- package/dist/{chunk-H63EDPFJ.js.map → chunk-MI2OTWV5.js.map} +1 -1
- package/dist/{chunk-LBFFNDFM.js → chunk-MINHJ55X.js} +1 -1
- package/dist/chunk-MINHJ55X.js.map +1 -0
- package/dist/{chunk-NG3MBQV4.js → chunk-MJRGVXPQ.js} +2 -2
- package/dist/{chunk-773TRRGT.js → chunk-MJUCDM3C.js} +2 -2
- package/dist/{chunk-7F27PCSN.js → chunk-MN5NOOI7.js} +2 -2
- package/dist/{chunk-JCWY73FK.js → chunk-N4F7ZSSG.js} +2 -2
- package/dist/{chunk-TR7DGXGI.js → chunk-NACLNNFQ.js} +5 -5
- package/dist/{chunk-LC2BDILZ.js → chunk-NBP4EX5N.js} +2 -2
- package/dist/{chunk-ZVPVTPGI.js → chunk-NNZFPYYX.js} +4 -4
- package/dist/{chunk-MFOSZUIT.js → chunk-NPIBN2VL.js} +2 -2
- package/dist/{chunk-IY7UXD3J.js → chunk-O57GM3FR.js} +2 -2
- package/dist/{chunk-I2HTKOOP.js → chunk-O7ERGZDA.js} +5 -5
- package/dist/{chunk-GTSVEEP3.js → chunk-OAJMQKQR.js} +3 -3
- package/dist/{chunk-HSZMX3ZJ.js → chunk-ODW5GDFE.js} +2 -2
- package/dist/{chunk-D4QVPP3G.js → chunk-PEBH5DCK.js} +18 -11
- package/dist/chunk-PEBH5DCK.js.map +1 -0
- package/dist/{chunk-J2WC5LF4.js → chunk-QBC33MPY.js} +2 -1
- package/dist/{chunk-EOHKUWXW.js → chunk-QCRJMU5V.js} +2 -2
- package/dist/chunk-QJCWK2A7.js +1466 -0
- package/dist/chunk-QJCWK2A7.js.map +1 -0
- package/dist/{chunk-THG4GYIE.js → chunk-RDGKVH6T.js} +11 -7
- package/dist/{chunk-THG4GYIE.js.map → chunk-RDGKVH6T.js.map} +1 -1
- package/dist/{chunk-5DH6PG4B.js → chunk-RZ3IZIJG.js} +3 -3
- package/dist/{chunk-AAXJNINV.js → chunk-SN4JXNLL.js} +2 -2
- package/dist/chunk-TB2MJRI6.js +866 -0
- package/dist/chunk-TB2MJRI6.js.map +1 -0
- package/dist/{chunk-7PHI6GUI.js → chunk-TEZ2HTC7.js} +42 -2
- package/dist/chunk-TEZ2HTC7.js.map +1 -0
- package/dist/{chunk-SVSRPG6M.js → chunk-TNGH4ZYI.js} +2 -2
- package/dist/{chunk-HZNYJN77.js → chunk-TNXNECAN.js} +6 -6
- package/dist/{chunk-JOEJG4SD.js → chunk-TVW4C7PV.js} +5 -5
- package/dist/{chunk-UFKPQBXH.js → chunk-U62OK7BB.js} +2 -2
- package/dist/{chunk-R2MZCYA6.js → chunk-UNUMFURP.js} +3 -3
- package/dist/{chunk-AX7UXCHJ.js → chunk-UYA36DQ7.js} +2 -1
- package/dist/chunk-UYA36DQ7.js.map +1 -0
- package/dist/{chunk-AFR6AIM4.js → chunk-VCKWULAK.js} +112 -87
- package/dist/chunk-VCKWULAK.js.map +1 -0
- package/dist/chunk-VOSWUO3K.js +100 -0
- package/dist/chunk-VOSWUO3K.js.map +1 -0
- package/dist/{chunk-YRVAKONL.js → chunk-VQ4AMTGZ.js} +1 -1
- package/dist/{chunk-3BCULS4U.js → chunk-VQNRICAQ.js} +145 -507
- package/dist/chunk-VQNRICAQ.js.map +1 -0
- package/dist/{chunk-RAIUTAZZ.js → chunk-WKAXBXVA.js} +2 -2
- package/dist/{chunk-ZIJDI4CP.js → chunk-WKJFIMVN.js} +2 -2
- package/dist/{chunk-SXIMQLGV.js → chunk-WVGXCBOC.js} +2 -2
- package/dist/{chunk-7BEPVIH3.js → chunk-X5YYSAZX.js} +4 -4
- package/dist/{chunk-FZEEWOI2.js → chunk-XJJYSX6F.js} +2 -2
- package/dist/{chunk-F635GAL7.js → chunk-XKNHFDTT.js} +33 -13
- package/dist/chunk-XKNHFDTT.js.map +1 -0
- package/dist/{chunk-UG6VXIOK.js → chunk-XSTNGNJP.js} +2 -2
- package/dist/{chunk-YDPAE2RD.js → chunk-YFLLGRXO.js} +2 -2
- package/dist/{chunk-EZ25VE3G.js → chunk-YNDLCWXS.js} +4 -4
- package/dist/{chunk-ANJXPFRS.js → chunk-YXFCALVT.js} +14 -14
- package/dist/{chunk-Q4WONDMJ.js → chunk-YYGZJPOK.js} +2 -2
- package/dist/{chunk-5HERQ5FX.js → chunk-Z3YEGSR4.js} +10 -10
- package/dist/{chunk-YWSQD2IB.js → chunk-ZJPM7GZ3.js} +2 -2
- package/dist/{chunk-5S4LQOPE.js → chunk-ZW4VXELZ.js} +2 -2
- package/dist/{cli-B322UMvB.d.ts → cli-BEkm2MEf.d.ts} +5 -5
- package/dist/cli.d.ts +17 -16
- package/dist/cli.js +126 -120
- package/dist/coding/export-okf-codegraph.d.ts +56 -0
- package/dist/coding/export-okf-codegraph.js +526 -0
- package/dist/coding/export-okf-codegraph.js.map +1 -0
- package/dist/coding/pre-action-gate.d.ts +2 -2
- package/dist/compounding/engine.d.ts +5 -3
- package/dist/compounding/engine.js +34 -34
- package/dist/compounding/preference-consolidator.d.ts +4 -4
- package/dist/compression-optimizer.d.ts +2 -2
- package/dist/config-security.js +2 -2
- package/dist/config.d.ts +2 -2
- package/dist/config.js +17 -16
- package/dist/connectors/codex-materialize-runner.d.ts +2 -2
- package/dist/connectors/codex-materialize-runner.js +33 -33
- package/dist/connectors/codex-materialize.d.ts +2 -2
- package/dist/connectors/index.d.ts +2 -2
- package/dist/connectors/index.js +33 -33
- package/dist/consolidation-provenance-check.d.ts +5 -3
- package/dist/consolidation-provenance-check.js +5 -5
- package/dist/consolidation-undo.d.ts +5 -3
- package/dist/consolidation-undo.js +3 -3
- package/dist/context-summary.d.ts +43 -0
- package/dist/context-summary.js +14 -0
- package/dist/context-summary.js.map +1 -0
- package/dist/contradiction/index.d.ts +6 -4
- package/dist/contradiction/index.js +10 -10
- package/dist/{contradiction-scan-AKUWPX5N.js → contradiction-scan-NOYMFG66.js} +3 -3
- package/dist/contradiction-scan-NOYMFG66.js.map +1 -0
- package/dist/converge-config.d.ts +2 -2
- package/dist/convergence-refresh.d.ts +5 -3
- package/dist/convergence-refresh.js +36 -36
- package/dist/conversation-index/backend.d.ts +2 -2
- package/dist/conversation-index/chunker.d.ts +2 -2
- package/dist/conversation-index/faiss-adapter.d.ts +2 -2
- package/dist/conversation-index/indexer.d.ts +2 -2
- package/dist/conversation-index/search.d.ts +2 -2
- package/dist/corpus-watermark.d.ts +2 -2
- package/dist/corpus-watermark.js +35 -35
- package/dist/cross-lingual-recall.d.ts +2 -2
- package/dist/dashboard-runtime.js +2 -2
- package/dist/day-summary.d.ts +2 -2
- package/dist/delinearize.d.ts +2 -2
- package/dist/dependency-propagation-config.d.ts +2 -2
- package/dist/{dependency-propagation-delivery-BGcNairQ.d.ts → dependency-propagation-delivery-BCpeo14F.d.ts} +1 -1
- package/dist/direct-answer-wiring.d.ts +2 -2
- package/dist/direct-answer.d.ts +2 -2
- package/dist/embedding-fallback.d.ts +2 -2
- package/dist/enrichment/index.d.ts +2 -2
- package/dist/entity-origin-fields.d.ts +2 -2
- package/dist/entity-retrieval.d.ts +5 -3
- package/dist/entity-retrieval.js +34 -34
- package/dist/entity-schema.d.ts +2 -2
- package/dist/episodic-context.d.ts +2 -2
- package/dist/eval-trajectory-contracts.d.ts +2 -2
- package/dist/eval-trajectory-store.d.ts +2 -2
- package/dist/eval-trajectory.d.ts +2 -2
- package/dist/event-order-recall.js +3 -3
- package/dist/explicit-capture.d.ts +13 -12
- package/dist/explicit-capture.js +12 -12
- package/dist/external-wiki-access.d.ts +15 -14
- package/dist/external-wiki-access.js +66 -63
- package/dist/external-wiki-collection-registration.d.ts +2 -2
- package/dist/external-wiki-collection.d.ts +2 -2
- package/dist/external-wiki-mcp-tools.d.ts +15 -14
- package/dist/extraction-error-classification.d.ts +2 -2
- package/dist/extraction-faithfulness.d.ts +2 -2
- package/dist/extraction-faithfulness.js +2 -2
- package/dist/extraction-judge-telemetry.d.ts +2 -2
- package/dist/extraction-judge-training.d.ts +2 -2
- package/dist/extraction-judge.d.ts +2 -2
- package/dist/extraction-judge.js +2 -2
- package/dist/extraction-liveness.d.ts +2 -2
- package/dist/extraction-normalization.d.ts +2 -2
- package/dist/extraction-prompt.d.ts +2 -2
- package/dist/extraction-source-grounding-rules.d.ts +2 -2
- package/dist/extraction-source-grounding.d.ts +2 -2
- package/dist/extraction.d.ts +2 -2
- package/dist/extraction.js +47 -44
- package/dist/fallback-llm.d.ts +8 -2
- package/dist/fallback-llm.js +1 -1
- package/dist/{first-start-migration-4NETATFF.js → first-start-migration-KHIMCBIC.js} +3 -3
- package/dist/{forget-SZ2BXDGF.js → forget-2AE4MDK3.js} +3 -3
- package/dist/graph-dashboard-diff.d.ts +2 -2
- package/dist/graph-dashboard-key.d.ts +2 -2
- package/dist/graph-dashboard-parser.d.ts +2 -2
- package/dist/graph-edge-reinforcement.d.ts +2 -2
- package/dist/graph-path-reconstruction.d.ts +2 -2
- package/dist/graph-path-scoring.d.ts +2 -2
- package/dist/graph-snapshot.d.ts +2 -2
- package/dist/graph.d.ts +2 -2
- package/dist/harmonic-retrieval.js +1 -1
- package/dist/importance.d.ts +2 -2
- package/dist/importers/index.d.ts +2 -2
- package/dist/in-flight-reads.d.ts +2 -2
- package/dist/{index-By2QUAMh.d.ts → index-D_pyMUaP.d.ts} +2 -2
- package/dist/index.d.ts +261 -30
- package/dist/index.js +321 -257
- package/dist/intent.d.ts +2 -2
- package/dist/lcm/engine.d.ts +3 -3
- package/dist/lcm/engine.js +5 -4
- package/dist/lcm/index.d.ts +4 -3
- package/dist/lcm/index.js +12 -11
- package/dist/lcm/summarizer.d.ts +4 -6
- package/dist/lcm/summarizer.js +2 -1
- package/dist/lcm/tools.d.ts +4 -4
- package/dist/lifecycle.d.ts +2 -2
- package/dist/live-connectors-runner.d.ts +2 -2
- package/dist/local-llm.d.ts +2 -2
- package/dist/local-model-endpoint.d.ts +2 -2
- package/dist/location/index.d.ts +315 -6
- package/dist/location/index.js +151 -19
- package/dist/maintenance/memory-governance.d.ts +2 -2
- package/dist/maintenance/memory-governance.js +34 -34
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +5 -3
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +33 -33
- package/dist/maintenance/rebuild-memory-projection.d.ts +5 -3
- package/dist/maintenance/rebuild-memory-projection.js +35 -35
- package/dist/{maintenance-Dm2McrIx.d.ts → maintenance-DDUX9d6D.d.ts} +3 -3
- package/dist/mcp-memory-inspector-app.d.ts +15 -14
- package/dist/mcp-read-only-tools.js +1 -1
- package/dist/memory-action-policy.d.ts +18 -3
- package/dist/memory-action-policy.js +3 -1
- package/dist/memory-cache.d.ts +2 -2
- package/dist/memory-controller.d.ts +2 -2
- package/dist/memory-controller.js +2 -2
- package/dist/memory-lifecycle-ledger-utils.d.ts +2 -2
- package/dist/memory-projection-mutations.js +3 -3
- package/dist/memory-projection-store.d.ts +2 -2
- package/dist/memory-projection-store.js +1 -1
- package/dist/memory-provenance.d.ts +2 -2
- package/dist/memory-snapshot.d.ts +2 -2
- package/dist/memory-subject-cli.d.ts +15 -14
- package/dist/memory-subject.d.ts +15 -14
- package/dist/memory-subject.js +5 -5
- package/dist/memory-worth-outcomes.d.ts +5 -3
- package/dist/models-json.d.ts +2 -2
- package/dist/namespaces/migrate.d.ts +6 -4
- package/dist/namespaces/migrate.js +34 -34
- package/dist/namespaces/principal.d.ts +2 -2
- package/dist/namespaces/search.d.ts +2 -2
- package/dist/namespaces/search.js +8 -8
- package/dist/namespaces/storage.d.ts +6 -4
- package/dist/namespaces/storage.js +33 -33
- package/dist/native-knowledge.d.ts +2 -2
- package/dist/offline-sync-file-io.js +3 -3
- package/dist/offline-sync-impression-drain.d.ts +2 -2
- package/dist/offline-sync-impression-drain.js +9 -9
- package/dist/offline-sync.js +4 -4
- package/dist/operator-doctor-corpus.d.ts +2 -2
- package/dist/operator-doctor-corpus.js +36 -36
- package/dist/operator-doctor-replica.d.ts +2 -2
- package/dist/operator-toolkit.d.ts +6 -4
- package/dist/operator-toolkit.js +56 -55
- package/dist/orchestration/compression-guideline-coordinator.d.ts +5 -3
- package/dist/orchestration/maintenance.d.ts +7 -5
- package/dist/orchestration/maintenance.js +48 -47
- package/dist/{orchestrator-Co1DyfuP.d.ts → orchestrator-3F4jihCo.d.ts} +8 -8
- package/dist/orchestrator.d.ts +13 -12
- package/dist/orchestrator.js +182 -174
- package/dist/page-versioning.js +3 -3
- package/dist/patterns-cli.d.ts +2 -2
- package/dist/{pipeline-DotMnb6y.d.ts → pipeline-CB1dj6Uh.d.ts} +1 -1
- package/dist/policy-runtime.d.ts +2 -2
- package/dist/proactive-contention.d.ts +2 -2
- package/dist/provenance.d.ts +2 -2
- package/dist/{public-http-PJRtnSi-.d.ts → public-http-34-JIAGQ.d.ts} +1 -1
- package/dist/{purge-GB7PZHT2.js → purge-OP6BEDFY.js} +2 -2
- package/dist/{qmd-BP0n11fR.d.ts → qmd-edLLZXc5.d.ts} +1 -1
- package/dist/qmd-preflight.d.ts +3 -3
- package/dist/qmd-recall-cache.d.ts +2 -2
- package/dist/qmd.d.ts +3 -3
- package/dist/qmd.js +4 -4
- package/dist/recall-concurrency-config.d.ts +2 -2
- package/dist/recall-disclosure-escalation.d.ts +2 -2
- package/dist/recall-explain-renderer.d.ts +2 -2
- package/dist/recall-explain-renderer.js +3 -3
- package/dist/recall-memory-map.d.ts +2 -2
- package/dist/recall-planner-llm.d.ts +2 -2
- package/dist/recall-planner-llm.js +1 -1
- package/dist/recall-state.d.ts +2 -2
- package/dist/recall-tag-filter.d.ts +2 -2
- package/dist/recall-timings.d.ts +2 -2
- package/dist/recall-xray-cli.d.ts +2 -2
- package/dist/recall-xray-cli.js +4 -4
- package/dist/recall-xray-renderer.d.ts +2 -2
- package/dist/recall-xray-renderer.js +3 -3
- package/dist/recall-xray.d.ts +2 -2
- package/dist/recall-xray.js +2 -2
- package/dist/reconcile/cursor.d.ts +2 -2
- package/dist/reconcile/manifest.d.ts +2 -2
- package/dist/reconcile/manifest.js +5 -5
- package/dist/reconcile/plan.d.ts +2 -2
- package/dist/replay/normalizers/chatgpt.d.ts +2 -2
- package/dist/replay/normalizers/claude.d.ts +2 -2
- package/dist/replay/normalizers/openclaw.d.ts +2 -2
- package/dist/replay/normalizers/shared.d.ts +2 -2
- package/dist/replay/runner.d.ts +2 -2
- package/dist/replay/types.d.ts +2 -2
- package/dist/replica-divergence.d.ts +2 -2
- package/dist/replica-peers-config.d.ts +2 -2
- package/dist/{resolution-4552BNRV.js → resolution-4DLI3IOR.js} +11 -11
- package/dist/resolution-4DLI3IOR.js.map +1 -0
- package/dist/resolve-auth-token.d.ts +2 -2
- package/dist/resume-bundles.js +18 -17
- package/dist/retrieval-agents.d.ts +3 -3
- package/dist/retrieval-tiers.d.ts +2 -2
- package/dist/routing/engine.d.ts +2 -2
- package/dist/routing/store.d.ts +2 -2
- package/dist/salvage-envelope.d.ts +2 -2
- package/dist/salvage-envelope.js +7 -7
- package/dist/schemas.d.ts +572 -107
- package/dist/schemas.js +3 -1
- package/dist/{scope-profiles-6ChZKTy-.d.ts → scope-profiles-BF2lu81V.d.ts} +1 -1
- package/dist/search/document-scanner.js +1 -1
- package/dist/search/embed-helper.d.ts +2 -2
- package/dist/search/factory.d.ts +2 -2
- package/dist/search/factory.js +7 -7
- package/dist/search/index.d.ts +2 -2
- package/dist/search/index.js +13 -13
- package/dist/search/lancedb-backend.d.ts +2 -2
- package/dist/search/lancedb-backend.js +1 -1
- package/dist/search/meilisearch-backend.d.ts +2 -2
- package/dist/search/meilisearch-backend.js +1 -1
- package/dist/search/noop-backend.d.ts +2 -2
- package/dist/search/orama-backend.d.ts +2 -2
- package/dist/search/orama-backend.js +1 -1
- package/dist/search/port.d.ts +2 -2
- package/dist/search/remote-backend.d.ts +2 -2
- package/dist/secure-store/index.js +3 -3
- package/dist/{semantic-consolidation-DziYcW5J.d.ts → semantic-consolidation-5OuWXBRt.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +3 -3
- package/dist/semantic-consolidation.js +37 -37
- package/dist/semantic-rule-promotion.js +33 -33
- package/dist/semantic-rule-verifier.d.ts +2 -2
- package/dist/semantic-rule-verifier.js +33 -33
- package/dist/{service-C7rIBuK_.d.ts → service-CrqEhLXD.d.ts} +2 -2
- package/dist/session-observer-bands.d.ts +2 -2
- package/dist/session-observer-state.d.ts +2 -2
- package/dist/shared-context/manager.d.ts +2 -2
- package/dist/signal.d.ts +2 -2
- package/dist/source-agent-qualifier.d.ts +2 -2
- package/dist/source-agent-qualifier.js +42 -39
- package/dist/standup/build.d.ts +16 -0
- package/dist/standup/build.js +17 -0
- package/dist/standup/build.js.map +1 -0
- package/dist/{storage-B1hEx8Xg.d.ts → storage-BQn-xnxm.d.ts} +4 -1
- package/dist/storage.d.ts +5 -3
- package/dist/storage.js +32 -32
- package/dist/subject-config.d.ts +2 -2
- package/dist/subject-config.js +6 -6
- package/dist/summarizer.d.ts +2 -2
- package/dist/summarizer.js +2 -2
- package/dist/summary-snapshot.d.ts +2 -2
- package/dist/support-passport/index.d.ts +20 -19
- package/dist/support-passport/index.js +68 -65
- package/dist/temporal-supersession.d.ts +3 -3
- package/dist/temporal-timeline-recall.d.ts +2 -2
- package/dist/temporal-validity.d.ts +2 -2
- package/dist/threading.d.ts +2 -2
- package/dist/tier-migration.d.ts +5 -3
- package/dist/tier-routing.d.ts +2 -2
- package/dist/tier-routing.js +2 -2
- package/dist/{tier-stats-4B5IJ3NE.js → tier-stats-2TOW3QNL.js} +3 -3
- package/dist/topics.d.ts +2 -2
- package/dist/transcript.d.ts +2 -2
- package/dist/transfer/capsule-export.js +2 -2
- package/dist/transfer/capsule-import.js +5 -5
- package/dist/transfer/export-okf.d.ts +39 -0
- package/dist/transfer/export-okf.js +112 -0
- package/dist/transfer/export-okf.js.map +1 -0
- package/dist/transfer/types.d.ts +12 -12
- package/dist/trust-score-stage.d.ts +2 -2
- package/dist/trust-score.d.ts +2 -2
- package/dist/{types-BHDNxGTT.d.ts → types-BRpcNjHZ.d.ts} +119 -3
- package/dist/types.d.ts +2 -2
- package/dist/types.js +1 -1
- package/dist/utility-runtime.d.ts +2 -2
- package/dist/verified-recall.js +33 -33
- package/dist/who-knows-cli.d.ts +15 -14
- package/dist/who-knows-cli.js +34 -34
- package/dist/who-knows.d.ts +15 -14
- package/dist/who-knows.js +33 -33
- package/dist/write-envelope.d.ts +2 -2
- package/dist/write-envelope.js +6 -6
- package/package.json +54 -3
- package/src/access-admin-ops-surface.ts +6 -1
- package/src/access-boundary.ts +1 -0
- package/src/access-http.ts +3 -1
- package/src/access-mcp-output-schemas.ts +1 -0
- package/src/access-mcp.ts +3 -3
- package/src/access-operations.ts +1 -0
- package/src/access-service-offline-file-content.test.ts +63 -0
- package/src/access-surface-catalog.ts +2 -0
- package/src/active-context-config.ts +98 -0
- package/src/active-context-transform.test.ts +533 -0
- package/src/active-context-transform.ts +981 -0
- package/src/activity/config.test.ts +1 -0
- package/src/activity/config.ts +21 -1
- package/src/activity/index.ts +1 -0
- package/src/activity/timeline/build.ts +279 -0
- package/src/activity/timeline/categories.ts +111 -0
- package/src/activity/timeline/classify.ts +110 -0
- package/src/activity/timeline/corrections.ts +145 -0
- package/src/activity/timeline/index.ts +6 -0
- package/src/activity/timeline/timeline.test.ts +277 -0
- package/src/activity/timeline/types.ts +106 -0
- package/src/activity/types.ts +6 -0
- package/src/cli/okf-commands.ts +45 -0
- package/src/cli.ts +2 -2
- package/src/coding/export-okf-codegraph.test.ts +381 -0
- package/src/coding/export-okf-codegraph.ts +565 -0
- package/src/config.test.ts +1 -0
- package/src/config.ts +3 -5
- package/src/context-summary.ts +182 -0
- package/src/extraction-prompt-safety.test.ts +14 -2
- package/src/extraction.ts +21 -1
- package/src/fallback-llm.test.ts +134 -0
- package/src/fallback-llm.ts +77 -5
- package/src/index.ts +4 -11
- package/src/lcm/summarizer.ts +14 -93
- package/src/location/access-operations.ts +17 -8
- package/src/location/backfill.ts +137 -0
- package/src/location/config.test.ts +3 -0
- package/src/location/config.ts +46 -2
- package/src/location/http-glue.ts +1 -1
- package/src/location/index.ts +3 -0
- package/src/location/intervals.ts +1 -0
- package/src/location/matching.test.ts +65 -0
- package/src/location/matching.ts +354 -0
- package/src/location/mcp-tools.ts +2 -1
- package/src/location/surfaces.test.ts +15 -2
- package/src/location/surfaces.ts +95 -18
- package/src/location/tagging.test.ts +119 -0
- package/src/location/tagging.ts +277 -0
- package/src/location/types.ts +23 -1
- package/src/mcp-read-only-tools.ts +1 -0
- package/src/memory-action-policy.ts +28 -0
- package/src/memory-projection-store.ts +3 -1
- package/src/okf/cli.ts +18 -5
- package/src/okf/config.ts +5 -0
- package/src/okf/index-files.test.ts +60 -0
- package/src/okf/index-files.ts +114 -0
- package/src/okf/render.ts +133 -0
- package/src/okf/type-mapping.test.ts +3 -0
- package/src/okf/type-mapping.ts +2 -0
- package/src/orchestration/extraction-run.ts +2 -1
- package/src/orchestration/generic-recall-paths.ts +4 -3
- package/src/schemas.ts +17 -1
- package/src/standup/access-operations.ts +14 -0
- package/src/standup/build.test.ts +34 -0
- package/src/standup/build.ts +115 -0
- package/src/standup/http-glue.ts +15 -0
- package/src/standup/mcp-tools.ts +16 -0
- package/src/storage/context-transform-ledger.ts +39 -0
- package/src/storage/secure-line-reader.ts +50 -1
- package/src/storage.ts +4 -1
- package/src/support-passport/card-projection.ts +1 -0
- package/src/support-passport/card-service-commit-forwarding.test.ts +1 -0
- package/src/support-passport/card-service.test.ts +75 -1
- package/src/support-passport/card-service.ts +6 -3
- package/src/support-passport/card-state.ts +5 -1
- package/src/support-passport/offline-sync-guard.ts +14 -1
- package/src/transfer/export-okf.test.ts +164 -0
- package/src/transfer/export-okf.ts +286 -0
- package/src/types.ts +2 -3
- package/dist/chunk-2LWQSV6A.js.map +0 -1
- package/dist/chunk-3BCULS4U.js.map +0 -1
- package/dist/chunk-7BDZTALN.js.map +0 -1
- package/dist/chunk-7PHI6GUI.js.map +0 -1
- package/dist/chunk-AFR6AIM4.js.map +0 -1
- package/dist/chunk-AX7UXCHJ.js.map +0 -1
- package/dist/chunk-BJTHRFFC.js.map +0 -1
- package/dist/chunk-D4QVPP3G.js.map +0 -1
- package/dist/chunk-DVYRD4HY.js.map +0 -1
- package/dist/chunk-F635GAL7.js.map +0 -1
- package/dist/chunk-FMQ4MOQO.js.map +0 -1
- package/dist/chunk-FP7YTTVO.js.map +0 -1
- package/dist/chunk-I4343FIA.js.map +0 -1
- package/dist/chunk-I7EX6KSH.js.map +0 -1
- package/dist/chunk-LBFFNDFM.js.map +0 -1
- package/dist/chunk-LLQCM2U2.js.map +0 -1
- package/dist/chunk-RQE4TITU.js.map +0 -1
- package/dist/chunk-UW5NPZJ2.js.map +0 -1
- package/dist/chunk-XAB6STPO.js.map +0 -1
- package/dist/chunk-ZPUIRTIZ.js.map +0 -1
- package/dist/types-CM86alG1.d.ts +0 -89
- /package/dist/{contradiction-scan-AKUWPX5N.js.map → active-context-config.js.map} +0 -0
- /package/dist/{resolution-4552BNRV.js.map → active-context-transform.js.map} +0 -0
- /package/dist/{auto-sync-XVMLL2RH.js.map → auto-sync-Q6Q2FVSC.js.map} +0 -0
- /package/dist/{capsule-merge-SGIVB3WA.js.map → capsule-merge-SEHERWWP.js.map} +0 -0
- /package/dist/{chunk-CFGU52XJ.js.map → chunk-23CVL7HS.js.map} +0 -0
- /package/dist/{chunk-PO7NXBG2.js.map → chunk-2GF27PGH.js.map} +0 -0
- /package/dist/{chunk-6CPUQ5D6.js.map → chunk-2LBAFHOQ.js.map} +0 -0
- /package/dist/{chunk-JBPKEARU.js.map → chunk-2QSZNTDO.js.map} +0 -0
- /package/dist/{chunk-IP4ZNT4U.js.map → chunk-33MFRY25.js.map} +0 -0
- /package/dist/{chunk-VFYRYFLL.js.map → chunk-3TSU662L.js.map} +0 -0
- /package/dist/{chunk-VXVZ2GM3.js.map → chunk-4FHRZD5T.js.map} +0 -0
- /package/dist/{chunk-5VPQSRQO.js.map → chunk-4STAANV7.js.map} +0 -0
- /package/dist/{chunk-46WM6JX2.js.map → chunk-4ZWCQJNM.js.map} +0 -0
- /package/dist/{chunk-52II7PB6.js.map → chunk-645WOU5I.js.map} +0 -0
- /package/dist/{chunk-YKWFK7XA.js.map → chunk-6CEGSTBD.js.map} +0 -0
- /package/dist/{chunk-GEPACVWN.js.map → chunk-6RUHELWR.js.map} +0 -0
- /package/dist/{chunk-ZAOHJDKH.js.map → chunk-72OIT7KS.js.map} +0 -0
- /package/dist/{chunk-KQAFEZQX.js.map → chunk-7LCGFUMB.js.map} +0 -0
- /package/dist/{chunk-7TCGNUVP.js.map → chunk-7UTDHQZ5.js.map} +0 -0
- /package/dist/{chunk-5HK3CJAR.js.map → chunk-7XOG75AU.js.map} +0 -0
- /package/dist/{chunk-C24UZSFW.js.map → chunk-CEH2AFXG.js.map} +0 -0
- /package/dist/{chunk-YOXVZJFM.js.map → chunk-CFVTRUR3.js.map} +0 -0
- /package/dist/{chunk-ACOC27BB.js.map → chunk-CN4VKV3S.js.map} +0 -0
- /package/dist/{chunk-PMVPCZJZ.js.map → chunk-CTCGHNWN.js.map} +0 -0
- /package/dist/{chunk-EGBDFJ36.js.map → chunk-DD5JFCWM.js.map} +0 -0
- /package/dist/{chunk-T42L3S6A.js.map → chunk-DDX6KIXF.js.map} +0 -0
- /package/dist/{chunk-JIYDRBVZ.js.map → chunk-DJORULH3.js.map} +0 -0
- /package/dist/{chunk-WTOZBZNN.js.map → chunk-DMEHOEC7.js.map} +0 -0
- /package/dist/{chunk-OPPBTPUU.js.map → chunk-DUAJKRR2.js.map} +0 -0
- /package/dist/{chunk-SVVIASVX.js.map → chunk-EFQCDJZ2.js.map} +0 -0
- /package/dist/{chunk-Q57GOHLF.js.map → chunk-EGALNSZ4.js.map} +0 -0
- /package/dist/{chunk-KCT36JAW.js.map → chunk-ESNFSSO4.js.map} +0 -0
- /package/dist/{chunk-XQ3HXAQH.js.map → chunk-ET2CNMLD.js.map} +0 -0
- /package/dist/{chunk-Z4U3UN56.js.map → chunk-EZSCW4EM.js.map} +0 -0
- /package/dist/{chunk-F6QHHRWP.js.map → chunk-FESUGFIL.js.map} +0 -0
- /package/dist/{chunk-S3K2CIK5.js.map → chunk-FKKGCGYL.js.map} +0 -0
- /package/dist/{chunk-BWGCOLEL.js.map → chunk-FTTJRVB7.js.map} +0 -0
- /package/dist/{chunk-JAQXUGLN.js.map → chunk-FYWLSFFS.js.map} +0 -0
- /package/dist/{chunk-OPGL46PX.js.map → chunk-GX6FTSYH.js.map} +0 -0
- /package/dist/{chunk-A32YEQAM.js.map → chunk-H7VDIF2V.js.map} +0 -0
- /package/dist/{chunk-PDDSFELN.js.map → chunk-HJXA6ZM7.js.map} +0 -0
- /package/dist/{chunk-RGCF4XNH.js.map → chunk-HNPE66LB.js.map} +0 -0
- /package/dist/{chunk-SEA6M7SS.js.map → chunk-I5VB44ZK.js.map} +0 -0
- /package/dist/{chunk-SDEPLF7V.js.map → chunk-IBJ6U753.js.map} +0 -0
- /package/dist/{chunk-EUYWQ7TS.js.map → chunk-IEZ6CGTW.js.map} +0 -0
- /package/dist/{chunk-3RI5Y7KU.js.map → chunk-IVIAHQBR.js.map} +0 -0
- /package/dist/{chunk-7WR462EM.js.map → chunk-J3OND5QT.js.map} +0 -0
- /package/dist/{chunk-T3JQTCCO.js.map → chunk-JI7U6AS3.js.map} +0 -0
- /package/dist/{chunk-I32NKXE2.js.map → chunk-JTWZKNUH.js.map} +0 -0
- /package/dist/{chunk-VKCAHCBI.js.map → chunk-L4X4PJYK.js.map} +0 -0
- /package/dist/{chunk-W4BMEGQA.js.map → chunk-LUDBXTBJ.js.map} +0 -0
- /package/dist/{chunk-RIAM7DND.js.map → chunk-ME35HVDJ.js.map} +0 -0
- /package/dist/{chunk-NG3MBQV4.js.map → chunk-MJRGVXPQ.js.map} +0 -0
- /package/dist/{chunk-773TRRGT.js.map → chunk-MJUCDM3C.js.map} +0 -0
- /package/dist/{chunk-7F27PCSN.js.map → chunk-MN5NOOI7.js.map} +0 -0
- /package/dist/{chunk-JCWY73FK.js.map → chunk-N4F7ZSSG.js.map} +0 -0
- /package/dist/{chunk-TR7DGXGI.js.map → chunk-NACLNNFQ.js.map} +0 -0
- /package/dist/{chunk-LC2BDILZ.js.map → chunk-NBP4EX5N.js.map} +0 -0
- /package/dist/{chunk-ZVPVTPGI.js.map → chunk-NNZFPYYX.js.map} +0 -0
- /package/dist/{chunk-MFOSZUIT.js.map → chunk-NPIBN2VL.js.map} +0 -0
- /package/dist/{chunk-IY7UXD3J.js.map → chunk-O57GM3FR.js.map} +0 -0
- /package/dist/{chunk-I2HTKOOP.js.map → chunk-O7ERGZDA.js.map} +0 -0
- /package/dist/{chunk-GTSVEEP3.js.map → chunk-OAJMQKQR.js.map} +0 -0
- /package/dist/{chunk-HSZMX3ZJ.js.map → chunk-ODW5GDFE.js.map} +0 -0
- /package/dist/{chunk-J2WC5LF4.js.map → chunk-QBC33MPY.js.map} +0 -0
- /package/dist/{chunk-EOHKUWXW.js.map → chunk-QCRJMU5V.js.map} +0 -0
- /package/dist/{chunk-5DH6PG4B.js.map → chunk-RZ3IZIJG.js.map} +0 -0
- /package/dist/{chunk-AAXJNINV.js.map → chunk-SN4JXNLL.js.map} +0 -0
- /package/dist/{chunk-SVSRPG6M.js.map → chunk-TNGH4ZYI.js.map} +0 -0
- /package/dist/{chunk-HZNYJN77.js.map → chunk-TNXNECAN.js.map} +0 -0
- /package/dist/{chunk-JOEJG4SD.js.map → chunk-TVW4C7PV.js.map} +0 -0
- /package/dist/{chunk-UFKPQBXH.js.map → chunk-U62OK7BB.js.map} +0 -0
- /package/dist/{chunk-R2MZCYA6.js.map → chunk-UNUMFURP.js.map} +0 -0
- /package/dist/{chunk-YRVAKONL.js.map → chunk-VQ4AMTGZ.js.map} +0 -0
- /package/dist/{chunk-RAIUTAZZ.js.map → chunk-WKAXBXVA.js.map} +0 -0
- /package/dist/{chunk-ZIJDI4CP.js.map → chunk-WKJFIMVN.js.map} +0 -0
- /package/dist/{chunk-SXIMQLGV.js.map → chunk-WVGXCBOC.js.map} +0 -0
- /package/dist/{chunk-7BEPVIH3.js.map → chunk-X5YYSAZX.js.map} +0 -0
- /package/dist/{chunk-FZEEWOI2.js.map → chunk-XJJYSX6F.js.map} +0 -0
- /package/dist/{chunk-UG6VXIOK.js.map → chunk-XSTNGNJP.js.map} +0 -0
- /package/dist/{chunk-YDPAE2RD.js.map → chunk-YFLLGRXO.js.map} +0 -0
- /package/dist/{chunk-EZ25VE3G.js.map → chunk-YNDLCWXS.js.map} +0 -0
- /package/dist/{chunk-ANJXPFRS.js.map → chunk-YXFCALVT.js.map} +0 -0
- /package/dist/{chunk-Q4WONDMJ.js.map → chunk-YYGZJPOK.js.map} +0 -0
- /package/dist/{chunk-5HERQ5FX.js.map → chunk-Z3YEGSR4.js.map} +0 -0
- /package/dist/{chunk-YWSQD2IB.js.map → chunk-ZJPM7GZ3.js.map} +0 -0
- /package/dist/{chunk-5S4LQOPE.js.map → chunk-ZW4VXELZ.js.map} +0 -0
- /package/dist/{first-start-migration-4NETATFF.js.map → first-start-migration-KHIMCBIC.js.map} +0 -0
- /package/dist/{forget-SZ2BXDGF.js.map → forget-2AE4MDK3.js.map} +0 -0
- /package/dist/{purge-GB7PZHT2.js.map → purge-OP6BEDFY.js.map} +0 -0
- /package/dist/{tier-stats-4B5IJ3NE.js.map → tier-stats-2TOW3QNL.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/maintenance/projection-support.ts","../src/storage/secure-line-reader.ts","../src/storage/memory-lifecycle-ledger-access.ts"],"sourcesContent":["/**\n * Projection maintenance support (issue #2119) — helpers shared by the\n * scheduled projection rebuild, the CLI rebuild, and the ledger rebuild.\n * Lives beside the rebuild ops so the at-ceiling store/rebuild modules stay\n * within their structural ratchets.\n */\n\nimport path from \"node:path\";\nimport {\n openProjectionReadonly,\n readProjectedEntityMentions,\n readProjectedGovernanceRecord,\n readProjectedNativeKnowledgeChunks,\n type MemoryProjectionGovernanceAppliedActionRow,\n type MemoryProjectionGovernanceReviewQueueRow,\n type ProjectedEntityMentionRow,\n type ProjectedNativeKnowledgeChunkRow,\n} from \"../memory-projection-store.js\";\nimport {\n isFrontmatterDerivedLifecycleEventType,\n memoryLifecycleEventProjectionIdentity,\n} from \"../memory-lifecycle-ledger-utils.js\";\nimport type { MemoryLifecycleEvent } from \"../types.js\";\nimport type { BetterSqlite3Database } from \"../runtime/better-sqlite.js\";\n\n/** Read the projection meta rebuiltAt timestamp; null when absent/unopenable. */\nexport function readProjectionRebuiltAt(memoryDir: string): string | null {\n const db = openProjectionReadonly(memoryDir);\n if (!db) return null;\n try {\n const row = db.prepare(\"SELECT value FROM meta WHERE key = 'rebuiltAt'\").get() as\n | { value?: unknown }\n | undefined;\n return typeof row?.value === \"string\" && row.value.length > 0 ? row.value : null;\n } catch {\n return null;\n } finally {\n db.close();\n }\n}\n\n/** Format projection age description string for fallback warning telemetry. */\nexport function formatProjectionAge(rebuiltAt: string | null): string {\n if (!rebuiltAt) return \"projection never rebuilt\";\n const ageMs = Date.now() - Date.parse(rebuiltAt);\n if (!Number.isFinite(ageMs)) return `projection rebuiltAt=${rebuiltAt}`;\n const ageMin = Math.max(0, Math.round(ageMs / 60_000));\n const age = ageMin >= 120 ? `${Math.round(ageMin / 60)}h` : `${ageMin}m`;\n return `projection ${age} stale, last rebuilt ${rebuiltAt}`;\n}\n\nexport interface ProjectionLifecycleLedgerHighWater {\n eventCount: number;\n sourceEventCount: number;\n}\n\nfunction readProjectionHighWaterFromDb(\n db: BetterSqlite3Database,\n): ProjectionLifecycleLedgerHighWater | null {\n const sourceRow = db.prepare(\n \"SELECT value FROM meta WHERE key = 'sourceLifecycleLedgerEventCount'\",\n ).get() as { value?: unknown } | undefined;\n const projectedRow = db.prepare(\n \"SELECT value FROM meta WHERE key = 'projectedLifecycleLedgerEventCount'\",\n ).get() as { value?: unknown } | undefined;\n if (\n typeof sourceRow?.value !== \"string\"\n || !/^\\d+$/.test(sourceRow.value)\n || typeof projectedRow?.value !== \"string\"\n || !/^\\d+$/.test(projectedRow.value)\n ) return null;\n const sourceEventCount = Number(sourceRow.value);\n const eventCount = Number(projectedRow.value);\n if (!Number.isSafeInteger(sourceEventCount) || !Number.isSafeInteger(eventCount)) return null;\n return { eventCount, sourceEventCount };\n}\n\nexport function readProjectionLifecycleLedgerHighWater(\n memoryDir: string,\n): ProjectionLifecycleLedgerHighWater | null {\n const db = openProjectionReadonly(memoryDir);\n if (!db) return null;\n try {\n return readProjectionHighWaterFromDb(db);\n } catch {\n return null;\n } finally {\n db.close();\n }\n}\n\nexport interface ProjectionLifecycleLedgerLagTracker {\n highWater: ProjectionLifecycleLedgerHighWater;\n record(event: MemoryLifecycleEvent): { unique: boolean; projected: boolean };\n close(): void;\n}\n\nexport function openProjectionLifecycleLedgerLagTracker(\n memoryDir: string,\n): ProjectionLifecycleLedgerLagTracker | null {\n const db = openProjectionReadonly(memoryDir);\n if (!db) return null;\n try {\n const highWater = readProjectionHighWaterFromDb(db);\n if (!highWater) {\n db.close();\n return null;\n }\n db.pragma(\"temp_store = FILE\");\n db.exec(`\n CREATE TEMP TABLE projection_lag_current_identity (\n identity TEXT PRIMARY KEY\n ) WITHOUT ROWID;\n `);\n db.pragma(\"temp.cache_size = -1024\");\n const insertCurrent = db.prepare(\n \"INSERT OR IGNORE INTO projection_lag_current_identity(identity) VALUES (?)\",\n );\n const findProjectedEvent = db.prepare(\n \"SELECT 1 FROM memory_timeline WHERE event_id = ? LIMIT 1\",\n );\n const findProjectedFrontmatterEvent = db.prepare(`\n SELECT 1\n FROM memory_timeline\n WHERE memory_id = ? AND event_type = ? AND timestamp = ?\n LIMIT 1\n `);\n return {\n highWater,\n record(event) {\n if (!event.memoryId.trim()) return { unique: false, projected: false };\n const identity = memoryLifecycleEventProjectionIdentity(event);\n const inserted = insertCurrent.run(identity);\n if (inserted.changes === 0) return { unique: false, projected: false };\n const projected = isFrontmatterDerivedLifecycleEventType(event.eventType)\n ? findProjectedFrontmatterEvent.get(event.memoryId, event.eventType, event.timestamp)\n : findProjectedEvent.get(event.eventId);\n return { unique: true, projected: projected !== undefined };\n },\n close: () => db.close(),\n };\n } catch {\n db.close();\n return null;\n }\n}\n/** Write the high-water ledger marker counts to projection meta store. */\nexport function writeProjectionMetaHighWater(\n insertMeta: { run: (key: string, value: string) => void },\n sourceLifecycleLedgerEventCount: number,\n timelineRows: MemoryLifecycleEvent[],\n): void {\n insertMeta.run(\"sourceLifecycleLedgerEventCount\", String(sourceLifecycleLedgerEventCount));\n insertMeta.run(\n \"projectedLifecycleLedgerEventCount\",\n String(new Set(timelineRows.map(memoryLifecycleEventProjectionIdentity)).size),\n );\n}\n\nexport function readProjectedEntityMentionRows(\n memoryDir: string,\n): { projectionExists: boolean; rows: ProjectedEntityMentionRow[] } {\n const rows = readProjectedEntityMentions(memoryDir);\n if (rows === null) return { projectionExists: false, rows: [] };\n return { projectionExists: true, rows };\n}\n\nexport function readProjectedNativeKnowledgeRows(\n memoryDir: string,\n): { projectionExists: boolean; rows: ProjectedNativeKnowledgeChunkRow[] } {\n const rows = readProjectedNativeKnowledgeChunks(memoryDir);\n if (rows === null) return { projectionExists: false, rows: [] };\n return { projectionExists: true, rows };\n}\n\nexport function readProjectedGovernanceRows(memoryDir: string): {\n projectionExists: boolean;\n runId: string | null;\n summary: unknown;\n metrics: unknown;\n reviewQueueRows: MemoryProjectionGovernanceReviewQueueRow[];\n appliedActionRows: MemoryProjectionGovernanceAppliedActionRow[];\n report: string;\n} {\n const record = readProjectedGovernanceRecord(memoryDir);\n if (record === null) {\n return {\n projectionExists: false,\n runId: null,\n summary: undefined,\n metrics: undefined,\n reviewQueueRows: [],\n appliedActionRows: [],\n report: \"\",\n };\n }\n return {\n projectionExists: true,\n runId: record.runId,\n summary: record.summary,\n metrics: record.metrics,\n reviewQueueRows: record.reviewQueueRows,\n appliedActionRows: record.appliedActionRows,\n report: record.report,\n };\n}\n\n/**\n * Assert an optionally injected storage (e.g. the daemon's live unlocked\n * secure-store instance) is rooted at `memoryDir`, and hand it back. Shared\n * by the projection and lifecycle-ledger rebuilds so the containment guard\n * cannot drift between them; callers construct their own StorageManager when\n * nothing was injected (keeps this module off the direct-storage-import\n * ratchet, issue #1533).\n */\nexport function assertInjectedStorageRooted<T extends { dir: string }>(\n label: string,\n memoryDir: string,\n injected: T | undefined,\n): T | undefined {\n if (injected && path.resolve(injected.dir) !== path.resolve(memoryDir)) {\n throw new Error(\n `${label}: storage.dir (${injected.dir}) must match memoryDir (${memoryDir})`,\n );\n }\n return injected;\n}\n\nexport interface SkippedDuplicateMemory {\n memoryId: string;\n keptPath: string;\n skippedPath: string;\n}\n\nexport interface SkippedBlankIdMemory {\n path: string;\n}\nexport interface SkippedDuplicateTimelineEvent {\n eventId: string;\n keptPath: string;\n skippedPath: string;\n}\n\nexport interface SkippedBlankIdTimelineEvent {\n eventId: string;\n path: string;\n}\n","import { createReadStream } from \"node:fs\";\nimport { lstat, open } from \"node:fs/promises\";\nimport { createInterface } from \"node:readline\";\n\nimport { isEncryptedFile, MAGIC_HEADER_SIZE } from \"../secure-store/secure-fs.js\";\nimport type { MemoryActionEvent, MemoryLifecycleEvent } from \"../types.js\";\n\n/**\n * Whole-file decrypt ceiling for encrypted state files. V8's max string length\n * is ~512MB; a decrypted body that approaches it throws an opaque\n * `Invalid string length` on every read (the 691MB lifecycle-ledger incident).\n * We refuse at a size comfortably under the cap and point the operator at the\n * compaction remedy instead of letting the runtime crash. Plaintext streaming\n * is unaffected at any size.\n */\nexport const STATE_FILE_MAX_DECRYPT_BYTES = 400 * 1024 * 1024;\n\n/**\n * Stream plaintext files by line while preserving authenticated whole-file\n * reads for encrypted files. `maxDecryptBytes` bounds the whole-file decrypt:\n * when set, an encrypted file at/over it is refused before decryption with an\n * actionable error. The ceiling is OPT-IN so it applies ONLY to callers with a\n * compaction-backed remedy (the lifecycle ledger). Callers with no bounded\n * maintenance path — e.g. the memory-actions ledger — omit it and keep the\n * prior unbounded read (issue #1910).\n */\nexport async function* readMaybeEncryptedLines(\n filePath: string,\n readEncryptedFile: () => Promise<string>,\n maxDecryptBytes?: number,\n): AsyncGenerator<string> {\n // Reject a symlink/FIFO/device BEFORE opening, matching the maintenance ledger\n // probe (probeEncryptedRegularFileHeader, #2033): opening a FIFO blocks until a\n // writer appears and a symlink would redirect the read outside our tree. An\n // ENOENT from the missing regular file propagates so callers keep their\n // absent-file → [] behavior (they catch ENOENT), exactly as a missing open did.\n const entryStat = await lstat(filePath);\n if (!entryStat.isFile()) {\n throw new Error(\n `refusing to read non-regular state file ${filePath} `\n + `(symlink/FIFO/device); opening it could block or escape containment (#2033)`,\n );\n }\n const file = await open(filePath, \"r\");\n const header = Buffer.alloc(MAGIC_HEADER_SIZE);\n try {\n const { bytesRead } = await file.read(header, 0, header.length, 0);\n if (isEncryptedFile(header.subarray(0, bytesRead))) {\n if (maxDecryptBytes !== undefined) {\n const { size } = await file.stat();\n if (size >= maxDecryptBytes) {\n throw new Error(\n `encrypted state file ${filePath} is ${size} bytes, at or over the ${maxDecryptBytes}-byte `\n + `whole-file decrypt limit. Run 'remnic rebuild-memory-lifecycle-ledger --write' (add `\n + `'--namespace <ns>' when the path is under namespaces/<ns>/state) or 'remnic doctor' to compact it.`,\n );\n }\n }\n yield* (await readEncryptedFile()).split(\"\\n\");\n return;\n }\n\n const input = createReadStream(filePath, {\n autoClose: false,\n encoding: \"utf8\",\n fd: file.fd,\n start: 0,\n });\n const lines = createInterface({ input, crlfDelay: Infinity });\n try {\n for await (const line of lines) yield line;\n } finally {\n lines.close();\n }\n } finally {\n await file.close();\n }\n}\n\nexport async function readMemoryActionEventRowsFromLines(\n lines: AsyncIterable<string>,\n limit: number,\n): Promise<Array<{ line: number; event: MemoryActionEvent }>> {\n const out: Array<{ line: number; event: MemoryActionEvent }> = [];\n let writeIndex = 0;\n let lineNumber = 0;\n for await (const row of lines) {\n lineNumber += 1;\n const line = row.trim();\n if (!line) continue;\n try {\n const parsed = JSON.parse(line) as Partial<MemoryActionEvent>;\n const outcome = parsed.outcome === \"applied\" || parsed.outcome === \"skipped\" || parsed.outcome === \"failed\"\n ? parsed.outcome\n : null;\n if (\n typeof parsed.timestamp === \"string\" &&\n typeof parsed.action === \"string\" &&\n outcome !== null\n ) {\n const entry = {\n line: lineNumber,\n event: { ...parsed, outcome } as MemoryActionEvent,\n };\n if (out.length < limit) {\n out.push(entry);\n } else {\n out[writeIndex] = entry;\n writeIndex = (writeIndex + 1) % limit;\n }\n }\n } catch {\n // Ignore malformed rows (fail-open).\n }\n }\n return writeIndex === 0 ? out : [...out.slice(writeIndex), ...out.slice(0, writeIndex)];\n}\n\n/**\n * Validate that a parsed row carries every required lifecycle-event field.\n * Shared by the tail reader and the per-memory reader so both apply the EXACT\n * same fail-open guard as `readAllLifecycleEventsFromLedger` (`eventType` is any\n * string). Governance reads via `readMemoryLifecycleEvents(MAX_SAFE_INTEGER)`\n * must be byte-for-byte identical to `readAllMemoryLifecycleEvents`, so this\n * MUST NOT restrict `eventType` to a handled allow-list — an unknown type is\n * still admitted here and sorted deterministically by `lifecycleEventSortRank`\n * (issue #1910).\n */\nfunction isValidLifecycleEventRow(\n parsed: Partial<MemoryLifecycleEvent>,\n): parsed is MemoryLifecycleEvent {\n return (\n typeof parsed.eventId === \"string\" &&\n typeof parsed.memoryId === \"string\" &&\n typeof parsed.eventType === \"string\" &&\n typeof parsed.timestamp === \"string\" &&\n typeof parsed.actor === \"string\" &&\n typeof parsed.ruleVersion === \"string\"\n );\n}\n\n/**\n * Bounded min-heap that retains the `limit` rows that rank highest under\n * `compare`, breaking ties by append order (later rows win). Heap use is\n * O(limit); each row costs O(log limit). Used for the per-memory timeline\n * fallback, which must keep the last `limit` events in canonical\n * timestamp/event order — not merely the last `limit` appended rows.\n */\nclass BoundedLifecycleTopN {\n private readonly heap: Array<{ event: MemoryLifecycleEvent; seq: number }> = [];\n\n constructor(\n private readonly limit: number,\n private readonly compare: (a: MemoryLifecycleEvent, b: MemoryLifecycleEvent) => number,\n ) {}\n\n private less(\n a: { event: MemoryLifecycleEvent; seq: number },\n b: { event: MemoryLifecycleEvent; seq: number },\n ): boolean {\n const c = this.compare(a.event, b.event);\n return c !== 0 ? c < 0 : a.seq < b.seq;\n }\n\n add(event: MemoryLifecycleEvent, seq: number): void {\n const item = { event, seq };\n if (this.heap.length < this.limit) {\n this.heap.push(item);\n this.siftUp(this.heap.length - 1);\n } else if (this.heap.length > 0 && this.less(this.heap[0], item)) {\n this.heap[0] = item;\n this.siftDown(0);\n }\n }\n\n /** Kept rows in ascending canonical order (append order breaks ties). */\n drainSorted(): MemoryLifecycleEvent[] {\n return this.heap\n .slice()\n .sort((a, b) => (this.less(a, b) ? -1 : this.less(b, a) ? 1 : 0))\n .map((item) => item.event);\n }\n\n private siftUp(index: number): void {\n let i = index;\n while (i > 0) {\n const parent = (i - 1) >> 1;\n if (!this.less(this.heap[i], this.heap[parent])) break;\n [this.heap[i], this.heap[parent]] = [this.heap[parent], this.heap[i]];\n i = parent;\n }\n }\n\n private siftDown(index: number): void {\n let i = index;\n const n = this.heap.length;\n for (;;) {\n const left = 2 * i + 1;\n const right = 2 * i + 2;\n let smallest = i;\n if (left < n && this.less(this.heap[left], this.heap[smallest])) smallest = left;\n if (right < n && this.less(this.heap[right], this.heap[smallest])) smallest = right;\n if (smallest === i) break;\n [this.heap[i], this.heap[smallest]] = [this.heap[smallest], this.heap[i]];\n i = smallest;\n }\n }\n}\n\n/**\n * Bounded tail read for lifecycle-event rows, mirroring\n * `readMemoryActionEventRowsFromLines`: heap use is O(limit) rather than\n * O(rows), no matter how large the ledger is. When `memoryId` is supplied,\n * only rows for that memory are considered, so the per-memory timeline\n * fallback never materializes the whole ledger either.\n *\n * Without `compare`, the retained rows are the last `limit` *appended* rows\n * (returned oldest→newest of that tail); callers apply\n * `sortMemoryLifecycleEvents` for canonical ordering. With `compare`, the\n * retained rows are the `limit` rows that rank highest under `compare` (ties\n * broken by append order), returned in ascending `compare` order — preserving\n * the prior \"filter → canonical sort → last N\" semantics without loading the\n * whole file.\n */\nexport async function readMemoryLifecycleEventsFromLines(\n lines: AsyncIterable<string>,\n limit: number,\n memoryId?: string,\n compare?: (a: MemoryLifecycleEvent, b: MemoryLifecycleEvent) => number,\n onEvent?: (event: MemoryLifecycleEvent) => void,\n): Promise<MemoryLifecycleEvent[]> {\n if (limit <= 0) return [];\n const top = compare ? new BoundedLifecycleTopN(limit, compare) : null;\n const ring: MemoryLifecycleEvent[] = [];\n let writeIndex = 0;\n let seq = 0;\n for await (const row of lines) {\n const line = row.trim();\n if (!line) continue;\n try {\n const parsed = JSON.parse(line) as Partial<MemoryLifecycleEvent>;\n if (!isValidLifecycleEventRow(parsed)) continue;\n onEvent?.(parsed);\n if (memoryId !== undefined && parsed.memoryId !== memoryId) continue;\n if (top) {\n top.add(parsed, seq++);\n } else if (ring.length < limit) {\n ring.push(parsed);\n } else {\n ring[writeIndex] = parsed;\n writeIndex = (writeIndex + 1) % limit;\n }\n } catch {\n // Ignore malformed rows (fail-open).\n }\n }\n if (top) return top.drainSorted();\n return writeIndex === 0 ? ring : [...ring.slice(writeIndex), ...ring.slice(0, writeIndex)];\n}\n","import { SecureStoreLockedError } from \"../secure-store/secure-fs.js\";\nimport { isErrnoCode } from \"../utils/errno.js\";\nimport { displayErrorDetail } from \"../runtime/better-sqlite.js\";\nimport { lstat, rename, stat, unlink } from \"node:fs/promises\";\nimport { randomUUID } from \"node:crypto\";\nimport path from \"node:path\";\nimport type { MemoryLifecycleEvent } from \"../types.js\";\nimport {\n compareMemoryLifecycleEvents,\n sortMemoryLifecycleEvents,\n memoryLifecycleLedgerLockPath,\n MEMORY_LIFECYCLE_LEDGER_LOCK_STALE_MS,\n MEMORY_LIFECYCLE_LEDGER_APPEND_LOCK_MAX_WAIT_MS,\n} from \"../memory-lifecycle-ledger-utils.js\";\nimport { withHeldFileLock, type HeldFileLockOptions } from \"../utils/serialize-mutations.js\";\nimport { ensureContainedSpillDir, listContainedSpillFiles } from \"../utils/path-containment.js\";\nimport {\n readMaybeEncryptedLines,\n readMemoryLifecycleEventsFromLines,\n STATE_FILE_MAX_DECRYPT_BYTES,\n} from \"./secure-line-reader.js\";\nimport { getMemoryProjectionPath } from \"../memory-projection-store.js\";\nimport {\n openProjectionLifecycleLedgerLagTracker,\n type ProjectionLifecycleLedgerLagTracker,\n} from \"../maintenance/projection-support.js\";\nimport {\n type ProjectionLedgerLagTelemetry,\n warnProjectionFallback,\n} from \"../storage-guards.js\";\n\n/** Reads a lifecycle-ledger file through the secure whole-file/plaintext line source. */\nexport type LedgerSecureReader = (filePath: string) => Promise<string>;\n\n/**\n * Lifecycle-ledger read access, extracted from storage.ts (issues #1910,\n * #1995) so the god-file line-count ratchet does not grow. Behavior is\n * unchanged: both readers stream `state/memory-lifecycle-ledger.jsonl` through\n * the same secure whole-file-or-plaintext line source, are fail-open on\n * malformed rows, return `[]` on an absent ledger (ENOENT), and rethrow when a\n * required secure store is locked.\n */\n\n/** Reads a lifecycle-ledger file as a raw (possibly still-encrypted-on-disk)\n * buffer, decrypting through the live secure key when present. */\nexport type LedgerSecureBufferReader = (filePath: string) => Promise<Buffer>;\n\n/**\n * Parse + canonically sort lifecycle rows from a line source. Permissive\n * validation (any `eventType` string is admitted) — matches the historical\n * `readAllMemoryLifecycleEvents` contract that projection rebuild depends on.\n * Fail-open on malformed rows.\n */\nasync function collectLifecycleEvents(\n lines: AsyncIterable<string>,\n): Promise<MemoryLifecycleEvent[]> {\n const out: MemoryLifecycleEvent[] = [];\n for await (const line of lines) {\n const row = line.trim();\n if (!row) continue;\n try {\n const parsed = JSON.parse(row) as Partial<MemoryLifecycleEvent>;\n if (\n typeof parsed.eventId === \"string\" &&\n typeof parsed.memoryId === \"string\" &&\n typeof parsed.eventType === \"string\" &&\n typeof parsed.timestamp === \"string\" &&\n typeof parsed.actor === \"string\" &&\n typeof parsed.ruleVersion === \"string\"\n ) {\n out.push(parsed as MemoryLifecycleEvent);\n }\n } catch {\n // Ignore malformed rows (fail-open).\n }\n }\n return sortMemoryLifecycleEvents(out);\n}\n\n/**\n * Max bytes of a single ledger row we will decode to a V8 string. A malformed\n * or truncated row with no newline can span most of an oversized buffer;\n * decoding it whole with `buf.toString` could exceed V8's ~512MB string cap and\n * THROW before the fail-open JSON.parse in {@link collectLifecycleEvents} can\n * skip it, aborting a compaction that could otherwise rewrite the ledger from\n * its remaining good rows (#2033). Comfortably above any real fixed-schema\n * lifecycle row, far below the string cap, so a legitimate row is never dropped.\n */\nconst LEDGER_ROW_MAX_DECODE_BYTES = 64 * 1024 * 1024;\n\n/**\n * Yield ledger lines from a whole-file buffer WITHOUT ever materializing the\n * entire decrypted body as one V8 string. A decrypted Buffer can hold ~4GB\n * where a string tops out near 512MB, so this is the read compaction uses to\n * shrink an oversize encrypted ledger — the exact file the string-capped\n * `readMaybeEncryptedLines` path refuses (issue #1910, #2033 Cursor High).\n * `Buffer.indexOf` scans for the 0x0A newline natively. A single oversized row\n * with no newline (a truncated write or garbled decrypt output) is SKIPPED\n * undecoded rather than passed to `toString`, so it can never exceed the string\n * cap and abort the read; the fail-open reader drops it anyway (#2033).\n */\nasync function* linesFromBuffer(\n readBuffer: () => Promise<Buffer>,\n): AsyncGenerator<string> {\n const buf = await readBuffer();\n let start = 0;\n let nl = buf.indexOf(0x0a, start);\n while (nl !== -1) {\n if (nl - start <= LEDGER_ROW_MAX_DECODE_BYTES) yield buf.toString(\"utf8\", start, nl);\n start = nl + 1;\n nl = buf.indexOf(0x0a, start);\n }\n if (start < buf.length && buf.length - start <= LEDGER_ROW_MAX_DECODE_BYTES) {\n yield buf.toString(\"utf8\", start, buf.length);\n }\n}\n\n/**\n * Every valid ledger row in canonical order, read through the string-capped\n * secure line source (refuses an encrypted body over the whole-file decrypt\n * limit). General readers use this; compaction uses the uncapped buffer variant.\n */\nexport async function readAllLifecycleEventsFromLedger(\n ledgerPath: string,\n readSecureFile: LedgerSecureReader,\n): Promise<MemoryLifecycleEvent[]> {\n try {\n return await collectLifecycleEvents(\n readMaybeEncryptedLines(\n ledgerPath,\n () => readSecureFile(ledgerPath),\n STATE_FILE_MAX_DECRYPT_BYTES,\n ),\n );\n } catch (err) {\n if (err instanceof SecureStoreLockedError) throw err;\n if (!isErrnoCode(err, \"ENOENT\")) throw err;\n return [];\n }\n}\n\n/**\n * Compaction-only variant of {@link readAllLifecycleEventsFromLedger} that reads\n * the ledger through a decrypted BUFFER instead of the string-capped whole-file\n * path. This is what lets background compaction shrink an oversize encrypted\n * ledger: the string cap (`STATE_FILE_MAX_DECRYPT_BYTES`) that points general\n * readers at the compaction remedy would otherwise also block the remedy itself\n * (issue #1910, #2033 Cursor High). Same permissive validation, canonical sort,\n * fail-open-on-malformed, and ENOENT→[] / locked-store-rethrow contract.\n */\nexport async function readAllLifecycleEventsFromLedgerBuffer(\n ledgerPath: string,\n readSecureBuffer: LedgerSecureBufferReader,\n): Promise<MemoryLifecycleEvent[]> {\n try {\n return await collectLifecycleEvents(linesFromBuffer(() => readSecureBuffer(ledgerPath)));\n } catch (err) {\n if (err instanceof SecureStoreLockedError) throw err;\n if (!isErrnoCode(err, \"ENOENT\")) throw err;\n return [];\n }\n}\n\n/**\n * Bounded tail read: retains at most `limit` rows via a streaming min-heap so\n * the whole ledger is never materialized. Rows are always ranked by the\n * canonical comparator, so the result is the last `limit` events in canonical\n * (memoryId, timestamp, eventType) order — byte-for-byte the prior `readAll →\n * sort → slice(-limit)`, whether or not `memoryId` is supplied. Governance\n * passes `MAX_SAFE_INTEGER`, so the heap keeps every row and equals\n * `readAllMemoryLifecycleEvents` (issue #1910; CodeRabbit: keep the no-memoryId\n * read on the canonical tail). With `memoryId` only that memory's rows are\n * considered, so the per-memory timeline fallback never materializes the whole\n * ledger either.\n */\nexport async function readBoundedLifecycleEventsFromLedger(\n ledgerPath: string,\n readSecureFile: LedgerSecureReader,\n limit: number,\n memoryId?: string,\n): Promise<MemoryLifecycleEvent[]> {\n const cappedLimit = Math.max(0, Math.floor(limit));\n if (cappedLimit === 0 || Number.isNaN(cappedLimit)) return [];\n try {\n return await readMemoryLifecycleEventsFromLines(\n readMaybeEncryptedLines(\n ledgerPath,\n () => readSecureFile(ledgerPath),\n STATE_FILE_MAX_DECRYPT_BYTES,\n ),\n cappedLimit,\n memoryId,\n compareMemoryLifecycleEvents,\n );\n } catch (err) {\n if (err instanceof SecureStoreLockedError) throw err;\n if (!isErrnoCode(err, \"ENOENT\")) throw err;\n return [];\n }\n}\n\nexport interface LifecycleLedgerProjectionLagRead {\n events: MemoryLifecycleEvent[];\n currentEventCount: number;\n deltaEvents: number;\n telemetryAvailable: boolean;\n}\n\nexport async function readBoundedLifecycleEventsWithProjectionLag(\n ledgerPath: string,\n readSecureFile: LedgerSecureReader,\n limit: number,\n memoryId: string,\n tracker: ProjectionLifecycleLedgerLagTracker,\n): Promise<LifecycleLedgerProjectionLagRead> {\n let currentEventCount = 0;\n let deltaEvents = 0;\n let telemetryAvailable = true;\n try {\n const events = await readMemoryLifecycleEventsFromLines(\n readMaybeEncryptedLines(\n ledgerPath,\n () => readSecureFile(ledgerPath),\n STATE_FILE_MAX_DECRYPT_BYTES,\n ),\n Math.max(0, Math.floor(limit)),\n memoryId,\n compareMemoryLifecycleEvents,\n (event) => {\n if (!telemetryAvailable) return;\n try {\n const tracked = tracker.record(event);\n if (!tracked.unique) return;\n currentEventCount += 1;\n if (!tracked.projected) deltaEvents += 1;\n } catch {\n telemetryAvailable = false;\n currentEventCount = 0;\n deltaEvents = 0;\n }\n },\n );\n return { events, currentEventCount, deltaEvents, telemetryAvailable };\n } catch (err) {\n if (err instanceof SecureStoreLockedError) throw err;\n if (!isErrnoCode(err, \"ENOENT\")) throw err;\n return { events: [], currentEventCount: 0, deltaEvents: 0, telemetryAvailable: false };\n }\n}\n/**\n * Probe filesystem identity stamps (dev:ino:size:mtimeMs:ctimeMs) for the\n * projection database and lifecycle-ledger file. Returns `null` when either\n * file is missing or unstatable so caller can disable the lag cache without\n * throwing on transient I/O or permission errors (#2119 / review).\n */\nexport async function probeProjectionLedgerIdentities(\n projectionPath: string,\n ledgerPath: string,\n): Promise<{ projectionIdentity: string; ledgerIdentity: string } | null> {\n try {\n const [projectionIdentity, ledgerIdentity] = await Promise.all(\n [projectionPath, ledgerPath].map(async (filePath) => {\n try {\n const file = await lstat(filePath);\n return `${file.dev}:${file.ino}:${file.size}:${file.mtimeMs}:${file.ctimeMs}`;\n } catch (err) {\n if (isErrnoCode(err, \"ENOENT\")) return \"absent\";\n // Probe failure: disable lag cache, do not block the primary timeline read (#2119 review).\n return null;\n }\n }),\n );\n if (!projectionIdentity || !ledgerIdentity) return null;\n return { projectionIdentity, ledgerIdentity };\n } catch {\n return null;\n }\n}\n\nexport interface ProjectionLedgerLagScan {\n telemetry: ProjectionLedgerLagTelemetry | null;\n events: MemoryLifecycleEvent[];\n memoryId: string;\n limit: number;\n}\n\nexport class ProjectionLedgerLagManager {\n private lagCache: {\n generation: string;\n telemetry: ProjectionLedgerLagTelemetry;\n } | null = null;\n private lagInFlight: {\n generation: string;\n scan: Promise<ProjectionLedgerLagScan>;\n } | null = null;\n\n async resolveTimelineWithLag(options: {\n baseDir: string;\n ledgerPath: string;\n memoryId: string;\n cappedLimit: number;\n readSecureFile: LedgerSecureReader;\n projectionAge: () => string;\n }): Promise<MemoryLifecycleEvent[]> {\n const { baseDir, ledgerPath, memoryId, cappedLimit, readSecureFile, projectionAge } = options;\n const projectionPath = getMemoryProjectionPath(baseDir);\n const identities = await probeProjectionLedgerIdentities(projectionPath, ledgerPath);\n\n if (!identities) {\n warnProjectionFallback(baseDir, \"getMemoryTimeline\", projectionAge);\n return readBoundedLifecycleEventsFromLedger(ledgerPath, readSecureFile, cappedLimit, memoryId);\n }\n\n const { projectionIdentity, ledgerIdentity } = identities;\n const generation = `${projectionIdentity}\\0${ledgerIdentity}`;\n\n const cachedLag = this.lagCache?.generation === generation\n ? this.lagCache.telemetry\n : null;\n if (cachedLag) {\n warnProjectionFallback(baseDir, \"getMemoryTimeline\", projectionAge, cachedLag);\n return readBoundedLifecycleEventsFromLedger(ledgerPath, readSecureFile, cappedLimit, memoryId);\n }\n\n const inFlight = this.lagInFlight?.generation === generation\n ? this.lagInFlight.scan\n : null;\n if (inFlight) {\n const result = await inFlight;\n if (result.telemetry) {\n this.lagCache = { generation, telemetry: result.telemetry };\n }\n warnProjectionFallback(baseDir, \"getMemoryTimeline\", projectionAge, result.telemetry ?? undefined);\n if (result.memoryId === memoryId && result.limit === cappedLimit) return result.events;\n return readBoundedLifecycleEventsFromLedger(ledgerPath, readSecureFile, cappedLimit, memoryId);\n }\n\n const tracker = openProjectionLifecycleLedgerLagTracker(baseDir);\n if (tracker) {\n const highWater = tracker.highWater;\n const scan = (async (): Promise<ProjectionLedgerLagScan> => {\n try {\n const fallback = await readBoundedLifecycleEventsWithProjectionLag(\n ledgerPath,\n readSecureFile,\n cappedLimit,\n memoryId,\n tracker,\n );\n return {\n telemetry: fallback.telemetryAvailable\n ? {\n projectedEvents: highWater.eventCount,\n currentLedgerEvents: fallback.currentEventCount,\n deltaEvents: fallback.deltaEvents,\n }\n : null,\n events: fallback.events,\n memoryId,\n limit: cappedLimit,\n };\n } finally {\n try {\n tracker.close();\n } catch {\n // Lag telemetry cleanup must not replace a successful ledger fallback.\n }\n }\n })();\n this.lagInFlight = { generation, scan };\n try {\n const result = await scan;\n if (result.telemetry) {\n this.lagCache = { generation, telemetry: result.telemetry };\n }\n warnProjectionFallback(baseDir, \"getMemoryTimeline\", projectionAge, result.telemetry ?? undefined);\n return result.events;\n } finally {\n if (this.lagInFlight?.scan === scan) {\n this.lagInFlight = null;\n }\n }\n }\n\n warnProjectionFallback(baseDir, \"getMemoryTimeline\", projectionAge);\n return readBoundedLifecycleEventsFromLedger(ledgerPath, readSecureFile, cappedLimit, memoryId);\n }\n}\n\n/**\n * Directory holding the durable pending-append spill for a lifecycle ledger\n * (#2033). When an append cannot acquire the ledger lock within its budget —\n * because a long compaction/rebuild rewrite legitimately holds it — the event\n * is written as its OWN immutable file here instead of being dropped fail-open,\n * then folded back into the ledger by the next lock holder (a later append or\n * the maintenance drain).\n *\n * A per-event file (not a single appended file) is deliberate: each spill is\n * encrypted at its own path so the path-bound AAD stays valid, and the drainer\n * only ever deletes files it has already read — a spill that lands mid-drain is\n * simply a new file picked up on the next pass, so nothing is clobbered or lost.\n */\nexport function pendingLifecycleLedgerDir(ledgerPath: string): string {\n return `${ledgerPath}.pending.d`;\n}\n\n/**\n * Secure IO the pending spill needs. `writeSecure`/`readSecure` mirror the\n * ledger's own secure write/read so each spill file is encrypted at rest exactly\n * like the ledger it backs (each at its own path-bound AAD).\n *\n * `writeSecure` MUST be ATOMIC (#2033): it writes the payload to a temp file in\n * the SAME directory and then renames it onto `filePath`, so a concurrent lock\n * holder draining the pending dir never lists or reads a half-written spill (the\n * exact partial-fold the drain's `*.jsonl`-only lister must never see). The\n * temp+rename is bound to the FINAL path because the ciphertext's AAD is the\n * final path — an outer rename at the spill layer would leave the bytes\n * undecryptable, so the atomic step lives here in `writeSecure`. The production\n * wiring (`writeMaybeEncryptedFile`) already renames its temp onto `filePath`,\n * naming that temp `<final>.tmp-…` (never `*.jsonl`), so the drain skips it.\n */\nexport interface LifecyclePendingIo {\n writeSecure: (filePath: string, payload: string) => Promise<void>;\n readSecure: (filePath: string) => Promise<string>;\n}\n\nfunction withTrailingNewline(content: string): string {\n return content.length === 0 || content.endsWith(\"\\n\") ? content : `${content}\\n`;\n}\n\n/**\n * Serialize lifecycle events into the ledger's newline-delimited JSON payload,\n * stamping a fallback timestamp on any event that lacks one. Extracted from\n * storage.ts (issue #1995 file-size ratchet); behavior unchanged.\n */\nexport function serializeLifecycleAppendPayload(events: MemoryLifecycleEvent[]): string {\n const nowIso = new Date().toISOString();\n return events\n .map((event) => {\n const normalized: MemoryLifecycleEvent = {\n ...event,\n timestamp: event.timestamp && event.timestamp.length > 0 ? event.timestamp : nowIso,\n };\n return `${JSON.stringify(normalized)}\\n`;\n })\n .join(\"\");\n}\n\n/**\n * Write one spill file (a fresh, uniquely-named, immutable per-append file).\n * The write goes to the FINAL `<uuid>.jsonl` path through {@link LifecyclePendingIo}\n * `writeSecure`, whose atomic temp+rename (bound to that final path, since the\n * ciphertext's AAD is the final path) guarantees a concurrent lock holder's\n * drain never lists or folds a half-written spill (#2033).\n */\nasync function spillPendingAppend(\n ledgerPath: string,\n io: LifecyclePendingIo,\n payload: string,\n): Promise<void> {\n const dir = pendingLifecycleLedgerDir(ledgerPath);\n await ensureContainedSpillDir(dir);\n const finalPath = path.join(dir, `${randomUUID()}.jsonl`);\n await io.writeSecure(finalPath, payload);\n}\n\n/** Suffix marking a spill that has been CLAIMED for commit but not yet deleted. */\nconst CLAIMED_SPILL_SUFFIX = \".claimed\";\n\n/**\n * Recover claims a crashed drain left mid-flight (#2033). A crash-safe drain\n * renames `*.jsonl` → `*.jsonl.claimed` BEFORE committing (see\n * {@link claimSpillBatch}); if the process dies between that rename and the\n * ledger write, the durable `.claimed` file is the ONLY copy of those rows. This\n * renames every orphaned `*.jsonl.claimed` back to `*.jsonl` so it re-enters the\n * normal claim+commit flow — nothing a crash left behind is lost. Reads only\n * ever happen at the restored `.jsonl` path, so the path-bound AAD of an\n * encrypted spill stays valid. A file that vanished or cannot be renamed is left\n * for a later pass. MUST run under the held ledger lock, before draining.\n */\nasync function recoverOrphanedClaims(ledgerPath: string): Promise<void> {\n const claimed = await listContainedSpillFiles(\n pendingLifecycleLedgerDir(ledgerPath),\n `.jsonl${CLAIMED_SPILL_SUFFIX}`,\n );\n for (const claimedPath of claimed) {\n const original = claimedPath.slice(0, -CLAIMED_SPILL_SUFFIX.length);\n await rename(claimedPath, original).catch(() => undefined);\n }\n}\n\n/** Max bytes of pending-spill content folded into one append (#2033). The drain\n * reads and concatenates at most this many bytes of spill content per batch, so\n * a large pending queue folds in bounded segments instead of one giant string:\n * the secure-store append decrypts the active ledger and concatenates the\n * payload as a V8 string, and a single unbounded fold could throw before\n * draining or recreate an encrypted active ledger over the whole-file decrypt\n * cap, stranding the rows in the excluded pending queue. */\nconst PENDING_SPILL_BATCH_MAX_BYTES = 1024 * 1024;\n\n/**\n * Claim ONE bounded batch of spills for commit via a CRASH-SAFE rename (#2033).\n * Content is read LAZILY here — at each spill's original (AAD-bound) path, so an\n * encrypted spill still decrypts — and at most `PENDING_SPILL_BATCH_MAX_BYTES`\n * (plus one spill) is held in memory or concatenated per call, bounding both the\n * fold's memory and the payload handed to a single append. Each spill is read,\n * then atomically renamed `*.jsonl` → `*.jsonl.claimed` BEFORE its rows are\n * committed: a crash between the claim and the commit leaves the rows on disk\n * (recovered by {@link recoverOrphanedClaims}) instead of losing them. A read\n * failure propagates with the file untouched (not yet claimed), leaving it for a\n * later retry; a rename that fails skips that spill this pass. Returns the batch\n * payload, its claimed paths, and the next input index. A lone spill larger than\n * the batch limit is claimed alone so the drain always makes progress.\n */\nasync function claimSpillBatch(\n files: string[],\n startIndex: number,\n io: LifecyclePendingIo,\n): Promise<{\n payload: string;\n claimedPaths: string[];\n nextIndex: number;\n}> {\n const parts: string[] = [];\n const claimedPaths: string[] = [];\n let payloadBytes = 0;\n let nextIndex = startIndex;\n for (; nextIndex < files.length; nextIndex++) {\n const filePath = files[nextIndex]!;\n // Read at the ORIGINAL (AAD-bound) path BEFORE claiming. A read failure\n // propagates with the file untouched, so it stays for a later retry.\n const content = withTrailingNewline(await io.readSecure(filePath));\n const spillBytes = Buffer.byteLength(content, \"utf8\");\n // Stop before a spill that would overflow a non-empty batch so peak memory\n // and the single-append payload stay bounded; it starts the next batch.\n if (parts.length > 0 && payloadBytes + spillBytes > PENDING_SPILL_BATCH_MAX_BYTES) {\n break;\n }\n const claimedPath = `${filePath}${CLAIMED_SPILL_SUFFIX}`;\n try {\n await rename(filePath, claimedPath);\n } catch {\n continue; // could not claim → do not commit; a later drain retries it.\n }\n parts.push(content);\n claimedPaths.push(claimedPath);\n payloadBytes += spillBytes;\n }\n return { payload: parts.join(\"\"), claimedPaths, nextIndex };\n}\n\n/** Delete claimed spill files after their rows are durably committed. A delete\n * that fails leaves an orphan the next drain recovers and re-commits — a\n * duplicate the eventId-deduping rebuild collapses, never a lost row (#2033). */\nasync function finalizeClaimedSpills(claimedPaths: string[]): Promise<void> {\n for (const claimedPath of claimedPaths) {\n await unlink(claimedPath).catch(() => undefined);\n }\n}\n\n/** Roll a failed commit's claims back to unclaimed `*.jsonl` spills so they are\n * retried as normal spills (#2033). Best-effort: an un-renamable claim is\n * instead recovered by the next drain's orphan sweep. */\nasync function rollbackClaimedSpills(claimedPaths: string[]): Promise<void> {\n for (const claimedPath of claimedPaths) {\n const original = claimedPath.slice(0, -CLAIMED_SPILL_SUFFIX.length);\n await rename(claimedPath, original).catch(() => undefined);\n }\n}\n\n/**\n * Under the held ledger lock, fold durable pending spills into the ledger in\n * bounded batches together with `extraPayload` (a new event's rows, or \"\" for a\n * drain-only pass). Recover orphaned claims first, then repeatedly claim ONE\n * bounded batch ({@link claimSpillBatch}) — reading its content lazily — COMMIT\n * the claimed rows, and FINALIZE by deleting the claimed files. A commit failure\n * rolls the current batch's claims back to unclaimed spills and rethrows, so a\n * failed write neither loses nor double-commits rows; batches already committed\n * stay durable (append-only, eventId-deduped on rebuild). Returns true when\n * spill rows were committed.\n */\nasync function foldPendingSpillsIntoAppend(\n ledgerPath: string,\n append: (payload: string) => Promise<void>,\n extraPayload: string,\n pending: LifecyclePendingIo | undefined,\n): Promise<boolean> {\n if (!pending) {\n if (extraPayload.length > 0) await append(extraPayload);\n return false;\n }\n await recoverOrphanedClaims(ledgerPath);\n // listContainedSpillFiles rejects a symlinked pending dir and skips any\n // symlinked/escaping entry BEFORE we secure-read or later unlink it (#2033),\n // so a poisoned link cannot redirect a decrypt/delete outside the spill dir.\n const files = await listContainedSpillFiles(pendingLifecycleLedgerDir(ledgerPath));\n let nextIndex = 0;\n let drained = false;\n\n while (nextIndex < files.length) {\n const batch = await claimSpillBatch(files, nextIndex, pending);\n nextIndex = batch.nextIndex;\n if (batch.claimedPaths.length === 0) {\n if (nextIndex >= files.length) break;\n continue;\n }\n try {\n await append(batch.payload);\n } catch (err) {\n await rollbackClaimedSpills(batch.claimedPaths);\n throw err;\n }\n await finalizeClaimedSpills(batch.claimedPaths);\n drained = true;\n }\n\n if (extraPayload.length > 0) await append(extraPayload);\n return drained;\n}\n\n/**\n * Append `payload` to the lifecycle ledger under the cross-process ledger lock\n * so it is serialized against compaction's whole-file rewrite (issue #1910):\n * both hold this lock, so an append during a rewrite waits and lands on the\n * compacted ledger instead of being clobbered by the atomic rename.\n *\n * The acquisition budget defaults to MEMORY_LIFECYCLE_LEDGER_APPEND_LOCK_MAX_WAIT_MS\n * (twice the stale window), NOT withHeldFileLock's 5s default: a compaction\n * rewrite of a large ledger can legitimately hold the lock past 5s, and giving\n * up there would surface acquired=false. With this budget a normal append waits\n * out the compaction — or, if the holder crashed, past the stale-break window so\n * it still acquires.\n *\n * When the budget is nonetheless exhausted (a rewrite of a very large ledger\n * holds the lock past even this window), a configured `pending` queue makes the\n * append DURABLE instead of dropping it fail-open (#2033): the event is spilled\n * to an encrypted per-event file and folded back into the ledger by the next\n * lock holder, guaranteeing eventual append. Without a pending queue the old\n * behavior stands — REFUSE to append unlocked rather than let a rewrite clobber\n * the row. `lockOptions` lets tests shrink the budget to exercise both branches.\n */\nexport async function appendLifecycleEventsSerialized(\n ledgerPath: string,\n append: (payload: string) => Promise<void>,\n payload: string,\n pending?: LifecyclePendingIo,\n lockOptions?: Pick<HeldFileLockOptions, \"maxWaitMs\" | \"pollMs\">,\n): Promise<void> {\n await withHeldFileLock(\n memoryLifecycleLedgerLockPath(ledgerPath),\n {\n staleMs: MEMORY_LIFECYCLE_LEDGER_LOCK_STALE_MS,\n maxWaitMs: MEMORY_LIFECYCLE_LEDGER_APPEND_LOCK_MAX_WAIT_MS,\n ...lockOptions,\n },\n async (acquired) => {\n if (!acquired) {\n if (!pending) {\n throw new Error(\n \"memory-lifecycle-ledger append aborted: could not acquire the ledger lock within \"\n + \"the budget and no durable pending queue is configured; refusing to append unlocked \"\n + \"so a concurrent compaction rewrite cannot clobber the new event (issue #1910).\",\n );\n }\n await spillPendingAppend(ledgerPath, pending, payload);\n return;\n }\n await foldPendingSpillsIntoAppend(ledgerPath, append, payload, pending);\n },\n );\n}\n\n/**\n * Drain the durable pending spills into the ledger under the ledger lock WITHOUT\n * appending a new event (#2033). Maintenance calls this so events that spilled\n * while a long compaction held the lock are eventually written even when no\n * further append arrives. A non-acquired lock is a no-op (retried next pass).\n * Uses the crash-safe claim/commit protocol ({@link foldPendingSpillsIntoAppend}):\n * spills are claimed by rename before the write and deleted only after it, an\n * orphaned claim from an earlier crash is recovered first, and a write failure\n * rolls the claims back — so a process crash mid-drain can never lose a row.\n * Returns true when rows were drained.\n */\nexport async function drainPendingLifecycleAppendsSerialized(\n ledgerPath: string,\n append: (payload: string) => Promise<void>,\n pending: LifecyclePendingIo,\n lockOptions?: Pick<HeldFileLockOptions, \"maxWaitMs\" | \"pollMs\">,\n): Promise<boolean> {\n let drained = false;\n await withHeldFileLock(\n memoryLifecycleLedgerLockPath(ledgerPath),\n {\n staleMs: MEMORY_LIFECYCLE_LEDGER_LOCK_STALE_MS,\n maxWaitMs: MEMORY_LIFECYCLE_LEDGER_APPEND_LOCK_MAX_WAIT_MS,\n ...lockOptions,\n },\n async (acquired) => {\n if (!acquired) return; // lock busy; the next maintenance pass retries.\n drained = await foldPendingSpillsIntoAppend(ledgerPath, append, \"\", pending);\n },\n );\n return drained;\n}\n\n/**\n * Fast-path pending drain for a store (#2033): a no-op that takes NO lock when\n * the pending directory is absent, otherwise ensures the state dir exists and\n * drains under the ledger lock. Keeps StorageManager's public drain method a\n * thin delegate so the bounded-state logic stays in this sibling (issue #1995\n * file-size ratchet). Returns true when rows were drained.\n */\nexport async function drainPendingLifecycleLedgerIfAny(\n ledgerPath: string,\n io: LifecyclePendingIo,\n append: (payload: string) => Promise<void>,\n ensureReady: () => Promise<void>,\n): Promise<boolean> {\n try {\n await stat(pendingLifecycleLedgerDir(ledgerPath));\n } catch (err) {\n if (isErrnoCode(err, \"ENOENT\")) return false; // nothing pending — no lock taken.\n throw err;\n }\n await ensureReady();\n return drainPendingLifecycleAppendsSerialized(ledgerPath, append, io);\n}\n\n/** Result of a pre-snapshot lifecycle drain (#2033): `folded` is true when spill\n * rows were committed to the active ledger; `pendingDeferred` is true when\n * durable spill rows STILL remain in the offline-sync-EXCLUDED pending queue\n * after the attempt (the ledger lock was held by a peer, or a spill could not\n * be claimed). A caller MUST NOT report a clean snapshot while `pendingDeferred`\n * is true — those append-only rows would be silently omitted. */\nexport interface DrainPendingLifecycleForSyncResult {\n folded: boolean;\n pendingDeferred: boolean;\n}\n\n/**\n * Offline-sync pre-snapshot drain (#2033). Like {@link drainPendingLifecycleLedgerIfAny}\n * but reports whether durable rows are STILL pending after the attempt so an\n * offline snapshot never silently drops append-only lifecycle rows (promotions,\n * imports, explicit captures) that spilled while the ledger lock was held. Fast\n * no-op — no lock, no dir creation — when nothing is pending. Otherwise drains\n * under the ledger lock, then re-enumerates the pending directory: any remaining\n * live (`*.jsonl`) or crash-orphaned (`*.jsonl.claimed`) spill marks the drain as\n * deferred. A read/append failure inside the lock (locked key, encrypted body)\n * propagates to the caller, which retries or aborts.\n */\nexport async function drainPendingLifecycleLedgerForSync(\n ledgerPath: string,\n io: LifecyclePendingIo,\n append: (payload: string) => Promise<void>,\n ensureReady: () => Promise<void>,\n): Promise<DrainPendingLifecycleForSyncResult> {\n const dir = pendingLifecycleLedgerDir(ledgerPath);\n try {\n await stat(dir);\n } catch (err) {\n if (isErrnoCode(err, \"ENOENT\")) return { folded: false, pendingDeferred: false };\n throw err;\n }\n await ensureReady();\n const folded = await drainPendingLifecycleAppendsSerialized(ledgerPath, append, io);\n const remaining =\n (await listContainedSpillFiles(dir)).length +\n (await listContainedSpillFiles(dir, `.jsonl${CLAIMED_SPILL_SUFFIX}`)).length;\n return { folded, pendingDeferred: remaining > 0 };\n}\n\n/**\n * Bounded pre-snapshot drain driver (#2033): invoke `drain` up to `maxAttempts`\n * times and return once it reports no pending rows; if durable rows remain\n * deferred (ledger lock held by a peer) or every attempt throws, throw so the\n * offline-sync caller ABORTS rather than building a snapshot that silently omits\n * append-only lifecycle rows. Kept here (not in the access-service god-file, issue\n * #1995) so both snapshot entrypoints share one retry/abort contract.\n */\nexport async function drainPendingLifecycleForSyncOrThrow(\n drain: () => Promise<DrainPendingLifecycleForSyncResult>,\n maxAttempts = 3,\n): Promise<void> {\n let lastError: unknown;\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n try {\n const result = await drain();\n if (!result.pendingDeferred) return;\n lastError = undefined;\n } catch (err) {\n lastError = err;\n }\n }\n const detail = lastError\n ? `: ${displayErrorDetail(lastError) || \"unknown error\"}`\n : \" (ledger lock held by a peer)\";\n throw new Error(\n `offline-sync lifecycle drain could not fold pending memory-lifecycle events after ${maxAttempts} attempts${detail}; aborting snapshot so the pending rows are not silently excluded (#2033)`,\n );\n}\n"],"mappings":"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","names":["lstat","path","lstat","path"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/extraction.ts","../src/orchestration/dependency-revalidation.ts"],"sourcesContent":["import OpenAI from \"openai\";\nimport { isAbortError } from \"./abort-error.js\";\nimport { log } from \"./logger.js\";\nimport { delinearize } from \"./delinearize.js\";\nimport { LocalLlmClient } from \"./local-llm.js\";\nimport { shouldRunProactivePass } from \"./proactive-contention.js\";\nimport { FallbackLlmClient, fallbackLlmRuntimeContextFromConfig, gatewayTaskChainOptions } from \"./fallback-llm.js\";\nimport { revalidateDependentsViaLlm, type RevalidationFastChatCompletion } from \"./orchestration/dependency-revalidation.js\";\nimport {\n ExtractionResultSchema,\n ConsolidationResultSchema,\n IdentityConsolidationResultSchema,\n buildProfileConsolidationResultSchema,\n ProactiveExtractionResultSchema,\n ProactiveQuestionsResultSchema,\n type ContradictionVerificationResult,\n type SuggestedLinks,\n type MemorySummaryResult,\n type ProactiveQuestionsResultParsed,\n DaySummaryResultSchema,\n} from \"./schemas.js\";\nimport type {\n BufferTurn,\n ExtractionResult,\n ConsolidationResult,\n MemoryFile,\n PluginConfig,\n LlmTraceEvent,\n GatewayConfig,\n MemoryCategory,\n DaySummaryResult as DaySummaryResultShape,\n ExtractionFailureClass,\n} from \"./types.js\";\nimport { ModelRegistry } from \"./model-registry.js\";\nimport { extractJsonCandidates } from \"./json-extract.js\";\nimport { sanitizeMemoryContent } from \"./sanitize.js\";\nimport { applyWorkExtractionBoundary } from \"./work/boundary.js\";\nimport { buildChatCompletionTokenLimit, shouldAssumeOpenAiChatCompletions } from \"./openai-chat-compat.js\";\nimport { formatDaySummaryMemories, loadDaySummaryPrompt, buildExtensionsFooterForSummary } from \"./day-summary.js\";\nimport { ProfilingCollector } from \"./profiling.js\";\nimport { normalizeProcedureSteps } from \"./procedural/procedure-types.js\";\nimport { normalizeReasoningTrace } from \"./reasoning-trace-types.js\";\nimport { looksLikeMechanicalTelemetryTranscript } from \"./telemetry-transcript.js\";\nimport {\n attachExtractionProvenance,\n type ExtractionGroundingRoleSources,\n} from \"./extraction-source-grounding.js\";\nimport { applyGroundingWithConnector, headerConnector, renderExtractionConversation, resolveSourceConnector, type ExtractionGroundingContext } from \"./source-agent-qualifier.js\";\nimport { isMemoryCategory } from \"./write-envelope.js\";\nimport { classifyExtractionThrownError, classifyFallbackParseFailure } from \"./extraction-error-classification.js\";\nimport { AMBIENT_CAPTURE_PROMPT_SECTION_COMPACT, clampAmbientCaptureConfidence } from \"./ambient-provenance.js\";\nimport {\n CONSOLIDATION_RESPONSE_SCHEMA,\n CUE_ANCHOR_PROMPT_INSTRUCTION,\n EXTRACTION_RESPONSE_SHAPE,\n OUTPUT_LANGUAGE_POLICY,\n PROFILE_CONSOLIDATION_RESPONSE_SCHEMA,\n buildConsolidationSystemPrompt,\n buildExtractionInstructions,\n buildProfileConsolidationSystemPrompt,\n eventTimePromptInstruction,\n} from \"./extraction-prompt.js\";\nimport {\n containsExtractionPlaceholder,\n extractionAttributes,\n extractionCueAnchors,\n extractionText,\n isPlainRecord,\n} from \"./extraction-normalization.js\";\nexport { classifyExtractionThrownError, classifyFallbackParseFailure } from \"./extraction-error-classification.js\";\nimport { resolveLocalLlmCapabilities, resolveMemoryLifecycleCapabilities, resolvePipelineProcessingCapabilities, resolveRecallAuxiliaryCapabilities } from \"./capabilities.js\";\n\ntype ExtractionQuestion = ExtractionResult[\"questions\"][number];\ntype ExtractedFactResult = ExtractionResult[\"facts\"][number];\ntype ExtractedEntityResult = ExtractionResult[\"entities\"][number];\ntype ExtractedRelationshipResult = NonNullable<ExtractionResult[\"relationships\"]>[number];\n\nconst PROACTIVE_MIN_CONFIDENCE = 0.8;\n\nfunction extractionEntityType(value: unknown): ExtractedEntityResult[\"type\"] | undefined {\n const type = extractionText(value);\n if (\n type === \"person\" ||\n type === \"project\" ||\n type === \"tool\" ||\n type === \"company\" ||\n type === \"place\" ||\n type === \"other\"\n ) {\n return type;\n }\n return undefined;\n}\n\nfunction normalizeQuestion(question: ExtractionQuestion): ExtractionQuestion {\n const priority = Number.isFinite(question.priority)\n ? Math.max(0, Math.min(1, question.priority))\n : 0.5;\n return {\n question: typeof question.question === \"string\" ? question.question.trim() : \"\",\n context: typeof question.context === \"string\" ? question.context.trim() : \"\",\n priority,\n };\n}\n\nfunction normalizeFactKey(fact: Pick<ExtractedFactResult, \"category\" | \"content\">): string {\n return `${fact.category}:${fact.content.trim().toLowerCase()}`;\n}\n\nfunction normalizeEntityKey(entity: Pick<ExtractedEntityResult, \"name\" | \"type\">): string {\n return `${entity.type}:${entity.name.trim().toLowerCase()}`;\n}\n\nfunction normalizeRelationshipKey(\n relationship: Pick<ExtractedRelationshipResult, \"source\" | \"target\" | \"label\">,\n): string {\n return `${relationship.source.trim().toLowerCase()}=>${relationship.target.trim().toLowerCase()}:${relationship.label.trim().toLowerCase()}`;\n}\n\nfunction normalizeProfileUpdateKey(update: string): string {\n return update.trim().toLowerCase();\n}\n\nexport function shouldEnableLocalExtractionThinking(\n config: Pick<PluginConfig, \"localLlmDisableThinking\" | \"localLlmThinkingThresholdChars\">,\n conversationChars: number,\n): boolean {\n return config.localLlmDisableThinking &&\n config.localLlmThinkingThresholdChars > 0 &&\n conversationChars < config.localLlmThinkingThresholdChars;\n}\n\nfunction throwIfExtractionAborted(signal?: AbortSignal): void {\n if (!signal?.aborted) return;\n const reason = signal.reason;\n throw reason instanceof Error ? reason : new Error(\"extraction aborted\");\n}\n\nexport class ExtractionEngine {\n private client: OpenAI | null;\n private localLlm: LocalLlmClient;\n private fallbackLlm: FallbackLlmClient;\n private modelRegistry: ModelRegistry;\n private profiler: ProfilingCollector;\n\n constructor(\n private readonly config: PluginConfig,\n profilerArg?: ProfilingCollector,\n localLlm?: LocalLlmClient,\n gatewayConfig?: GatewayConfig,\n modelRegistry?: ModelRegistry,\n private readonly fastChatCompletion?: RevalidationFastChatCompletion,\n ) {\n this.profiler = profilerArg ?? new ProfilingCollector({ enabled: false, storageDir: \"/tmp/engram-profiler-disabled\", maxTraces: 0 });\n if (config.openaiApiKey) {\n this.client = new OpenAI({\n apiKey: config.openaiApiKey,\n ...(config.openaiBaseUrl ? { baseURL: config.openaiBaseUrl } : {}),\n });\n } else {\n this.client = null;\n log.warn(\"no OpenAI API key — direct OpenAI client disabled; local and gateway fallback paths remain available\");\n }\n this.localLlm = localLlm ?? new LocalLlmClient(config, modelRegistry);\n this.fallbackLlm = new FallbackLlmClient(\n gatewayConfig,\n fallbackLlmRuntimeContextFromConfig(config),\n );\n this.modelRegistry = modelRegistry ?? new ModelRegistry(config.memoryDir);\n if (config.modelSource === \"gateway\") {\n log.debug(\n `extraction engine: gateway model source active; extraction uses the gateway chain as its primary path` +\n (config.taskModelChain ? \" (taskModelChain)\" :\n config.gatewayAgentId ? ` (agent: ${config.gatewayAgentId})` : \" (defaults)\"),\n );\n } else if (config.taskModelChain) {\n // taskModelChain resolves through gateway providers, so it only applies\n // under modelSource: \"gateway\". Warn rather than silently ignore it so a\n // misconfigured plugin-mode setup is visible. Issue #1365 / PR #1370.\n log.warn(\n `taskModelChain is set but modelSource is \"${config.modelSource}\"; the chain is ignored. ` +\n `Set modelSource: \"gateway\" to use it for extraction/consolidation/summarization.`,\n );\n }\n }\n\n private get useGatewayModelSource(): boolean {\n return this.config.modelSource === \"gateway\";\n }\n\n private get shouldUseLocalLlm(): boolean {\n return resolveLocalLlmCapabilities(this.config).localLlm && !this.useGatewayModelSource;\n }\n\n private get shouldUseDirectClient(): boolean {\n return !this.useGatewayModelSource && this.client !== null;\n }\n\n /**\n * Build FallbackLlmOptions with the configured gateway agent ID injected.\n */\n private withGatewayAgent(options: import(\"./fallback-llm.js\").FallbackLlmOptions): import(\"./fallback-llm.js\").FallbackLlmOptions {\n if (!this.useGatewayModelSource) return options;\n // Shared resolution (taskModelChain > gatewayAgentId) so every background\n // task routes identically (gotcha #22). Issue #1365.\n return { ...options, ...gatewayTaskChainOptions(this.config) };\n }\n\n private emit(event: LlmTraceEvent): void {\n try {\n const cb = (globalThis as any).__openclawEngramTrace;\n if (typeof cb === \"function\") cb(event);\n } catch {\n // Never throw — broken subscriber must not crash extraction\n }\n }\n\n private directClientUsesOpenAiTokenSemantics(): boolean {\n return shouldAssumeOpenAiChatCompletions(this.config.openaiBaseUrl);\n }\n\n private sanitizeExtractionResult(result: ExtractionResult, messageTimestamp?: Date): ExtractionResult {\n const proceduralOn = this.config.procedural?.enabled === true;\n const ts = messageTimestamp ?? new Date();\n const facts = result.facts\n .filter((fact) => proceduralOn || fact.category !== \"procedure\")\n .map((fact) => {\n const sanitized = sanitizeMemoryContent(fact.content);\n if (!sanitized.clean) {\n log.warn(`extraction fact sanitized; violations=${sanitized.violations.join(\", \")}`);\n }\n let content = sanitized.text;\n // De-linearize: resolve coreferences + anchor temporal expressions\n if (resolvePipelineProcessingCapabilities(this.config).delinearize) {\n content = delinearize(content, result.entities, ts);\n }\n return {\n ...fact,\n content,\n cueAnchors: extractionCueAnchors(fact.cueAnchors),\n };\n });\n return { ...result, facts, episodeTitle: extractionText(result.episodeTitle) };\n }\n\n private hasExtractionOutputs(result: ExtractionResult): boolean {\n return result.facts.length > 0\n || result.entities.length > 0\n || result.questions.length > 0\n || result.profileUpdates.length > 0\n || (result.relationships?.length ?? 0) > 0;\n }\n\n private looksLikeExtractionResultPayload(parsed: any): boolean {\n return !!parsed &&\n typeof parsed === \"object\" &&\n !Array.isArray(parsed) &&\n (\n \"facts\" in parsed ||\n \"entities\" in parsed ||\n \"profileUpdates\" in parsed ||\n \"questions\" in parsed ||\n \"relationships\" in parsed ||\n \"identityReflection\" in parsed\n );\n }\n\n private normalizeExtractionResultPayload(parsed: any): ExtractionResult {\n const entities: ExtractedEntityResult[] = Array.isArray(parsed?.entities)\n ? parsed.entities\n .map((candidate: unknown): ExtractedEntityResult | undefined => this.normalizeEntityUpdate(candidate))\n .filter((entity: ExtractedEntityResult | undefined): entity is ExtractedEntityResult => (\n entity !== undefined && entity.name.length > 0\n ))\n : [];\n\n const facts = Array.isArray(parsed?.facts)\n ? parsed.facts\n .map((candidate: unknown) => {\n const f = isPlainRecord(candidate) ? candidate : {};\n const category = typeof f.category === \"string\" ? f.category.trim() : \"fact\";\n const reasoningTraceInput = isPlainRecord(f.reasoningTrace)\n ? f.reasoningTrace\n : isPlainRecord(f?.reasoning_trace)\n ? f.reasoning_trace\n : undefined;\n if (!isMemoryCategory(category)) return undefined;\n const procedureSteps = Array.isArray(f.procedureSteps)\n ? normalizeProcedureSteps(f.procedureSteps)\n : undefined;\n const reasoningTrace = reasoningTraceInput\n ? normalizeReasoningTrace(reasoningTraceInput) ?? undefined\n : undefined;\n if (\n containsExtractionPlaceholder(procedureSteps) ||\n containsExtractionPlaceholder(reasoningTrace)\n ) {\n return undefined;\n }\n return {\n category,\n content: extractionText(f.content) ?? extractionText(f.text) ?? \"\",\n confidence: typeof f.confidence === \"number\" ? f.confidence : 0.7,\n tags: Array.isArray(f.tags)\n ? f.tags.flatMap((tag: unknown) => {\n const text = extractionText(tag);\n return text === undefined ? [] : [text];\n })\n : [],\n entityRef: extractionText(f.entityRef),\n cueAnchors: extractionCueAnchors(f.cueAnchors),\n promptedByQuestion: extractionText(f.promptedByQuestion),\n scope:\n f.scope === \"global\" || f.scope === \"project\" ? f.scope : undefined,\n subject:\n f.subject === \"user\" || f.subject === \"agent\" ? f.subject : undefined,\n structuredAttributes: extractionAttributes(f.structuredAttributes),\n procedureSteps,\n reasoningTrace,\n quote: extractionText(f.quote),\n eventTime: extractionText(f.eventTime) ?? extractionText(f.event_time),\n };\n })\n .filter((fact: ExtractedFactResult | undefined): fact is ExtractedFactResult => (\n fact !== undefined && fact.content.length > 0\n ))\n : [];\n\n const questions: ExtractionQuestion[] = Array.isArray(parsed?.questions)\n ? parsed.questions.flatMap((candidate: unknown) => {\n const record = isPlainRecord(candidate) ? candidate : undefined;\n const question =\n extractionText(record?.question) ??\n extractionText(record?.text) ??\n extractionText(candidate);\n if (question === undefined) return [];\n return [{\n question,\n context: extractionText(record?.context) ?? \"\",\n priority: typeof record?.priority === \"number\" ? record.priority : 0.5,\n }];\n })\n : [];\n\n const profileUpdates = Array.isArray(parsed?.profileUpdates)\n ? parsed.profileUpdates.flatMap((candidate: unknown) => {\n const update = extractionText(candidate);\n return update === undefined ? [] : [update];\n })\n : [];\n\n const relationships: ExtractedRelationshipResult[] | undefined = Array.isArray(parsed?.relationships)\n ? parsed.relationships.flatMap((candidate: unknown) => {\n const relationship = isPlainRecord(candidate) ? candidate : undefined;\n const source = extractionText(relationship?.source);\n const target = extractionText(relationship?.target);\n const label = extractionText(relationship?.label);\n if (source === undefined || target === undefined || label === undefined) return [];\n return [{\n source,\n target,\n label,\n promptedByQuestion: extractionText(relationship?.promptedByQuestion),\n }];\n })\n : undefined;\n\n return {\n facts,\n entities,\n profileUpdates,\n questions,\n identityReflection: extractionText(parsed?.identityReflection),\n episodeTitle: extractionText(parsed?.episodeTitle),\n relationships,\n };\n }\n\n private normalizeEntityUpdate(entity: unknown): ExtractedEntityResult | undefined {\n const record = isPlainRecord(entity) ? entity : {};\n const rawUpdates = isPlainRecord(record.updates) ? record.updates : undefined;\n const normalizedTexts = (value: unknown): string[] =>\n Array.isArray(value)\n ? value.flatMap((candidate: unknown) => {\n const text = extractionText(candidate);\n return text === undefined ? [] : [text];\n })\n : [];\n const directFacts = normalizedTexts(record.facts);\n const updateFacts = normalizedTexts(rawUpdates?.facts);\n const scalarUpdateFacts = rawUpdates\n ? Object.entries(rawUpdates)\n .sort(([left], [right]) => left.localeCompare(right))\n .flatMap(([key, value]) => {\n if ([\"facts\", \"name\", \"promptedByQuestion\", \"structuredSections\", \"type\"].includes(key)) {\n return [];\n }\n const normalizedKey = extractionText(key);\n if (normalizedKey === undefined) return [];\n const normalizedValue = extractionText(value);\n if (normalizedValue !== undefined) return [`${normalizedKey}: ${normalizedValue}`];\n if (typeof value === \"number\" || typeof value === \"boolean\") {\n return [`${normalizedKey}: ${String(value)}`];\n }\n return [];\n })\n : [];\n const structuredSectionsSource = Array.isArray(record.structuredSections)\n ? record.structuredSections\n : Array.isArray(rawUpdates?.structuredSections)\n ? rawUpdates.structuredSections\n : [];\n const structuredSections = structuredSectionsSource.flatMap((candidate: unknown) => {\n const section = isPlainRecord(candidate) ? candidate : {};\n const key = extractionText(section.key);\n const title = extractionText(section.title);\n const facts = normalizedTexts(section.facts);\n if (key === undefined || title === undefined || facts.length === 0) return [];\n return [{ key, title, facts }];\n });\n\n const rawType = record.type ?? rawUpdates?.type;\n const type = rawType === undefined ? \"other\" : extractionEntityType(rawType);\n if (type === undefined) return undefined;\n return {\n name:\n extractionText(record.name) ??\n extractionText(record.entityId) ??\n extractionText(rawUpdates?.name) ??\n \"\",\n type,\n facts: [...directFacts, ...updateFacts, ...scalarUpdateFacts],\n structuredSections: structuredSections.length > 0 ? structuredSections : undefined,\n promptedByQuestion: extractionText(record.promptedByQuestion) ?? extractionText(rawUpdates?.promptedByQuestion),\n };\n }\n\n private parseJsonObject(content?: string | null): any | null {\n const trimmed = content?.trim();\n if (!trimmed) return null;\n\n for (const candidate of extractJsonCandidates(trimmed)) {\n try {\n return JSON.parse(candidate);\n } catch {\n // keep trying candidates\n }\n }\n\n return null;\n }\n\n private normalizeContradictionVerificationResult(parsed: any): ContradictionVerificationResult | null {\n if (!parsed || typeof parsed.isContradiction !== \"boolean\") return null;\n\n const rawWhich = parsed.whichIsNewer ?? parsed.winner;\n const normalizedWhich =\n rawWhich === \"first\" || rawWhich === \"existing\"\n ? \"first\"\n : rawWhich === \"second\" || rawWhich === \"new\"\n ? \"second\"\n : \"unclear\";\n\n return {\n isContradiction: Boolean(parsed.isContradiction),\n confidence: typeof parsed.confidence === \"number\" ? parsed.confidence : 0.5,\n reasoning:\n typeof parsed.reasoning === \"string\"\n ? parsed.reasoning\n : typeof parsed.explanation === \"string\"\n ? parsed.explanation\n : \"\",\n whichIsNewer: normalizedWhich,\n };\n }\n\n private normalizeSuggestedLinksResult(parsed: any): SuggestedLinks | null {\n if (!parsed || !Array.isArray(parsed.links)) {\n return null;\n }\n\n const normalizedLinks = parsed.links\n .map((link: any) => {\n const rawLinkType = link?.linkType ?? link?.type;\n return {\n targetId: typeof link?.targetId === \"string\" ? link.targetId : \"\",\n linkType:\n rawLinkType === \"follows\" ||\n rawLinkType === \"references\" ||\n rawLinkType === \"contradicts\" ||\n rawLinkType === \"supports\" ||\n rawLinkType === \"related\"\n ? rawLinkType\n : \"related\",\n strength: typeof link?.strength === \"number\" ? Math.max(0, Math.min(1, link.strength)) : 0.5,\n reason: typeof link?.reason === \"string\" ? link.reason : undefined,\n };\n })\n .filter((link: any) => link.targetId.length > 0);\n\n return { links: normalizedLinks };\n }\n\n private normalizeMemorySummaryResult(parsed: any): MemorySummaryResult | null {\n if (!parsed) return null;\n\n const normalized: MemorySummaryResult = {\n summaryText:\n typeof parsed.summaryText === \"string\"\n ? parsed.summaryText\n : typeof parsed.summary === \"string\"\n ? parsed.summary\n : \"\",\n keyFacts: Array.isArray(parsed.keyFacts) ? parsed.keyFacts.filter((f: unknown) => typeof f === \"string\") : [],\n keyEntities: Array.isArray(parsed.keyEntities)\n ? parsed.keyEntities.filter((e: unknown) => typeof e === \"string\")\n : Array.isArray(parsed.entities)\n ? parsed.entities.filter((e: unknown) => typeof e === \"string\")\n : [],\n };\n\n return normalized.summaryText.length > 0 ? normalized : null;\n }\n\n private normalizeDaySummaryResult(parsed: any): DaySummaryResultShape | null {\n if (!parsed) return null;\n\n const normalized: DaySummaryResultShape = {\n summary: typeof parsed.summary === \"string\" ? parsed.summary.trim() : \"\",\n bullets: Array.isArray(parsed.bullets)\n ? parsed.bullets.filter((item: unknown) => typeof item === \"string\").map((item: string) => item.trim()).filter(Boolean)\n : [],\n next_actions: Array.isArray(parsed.next_actions)\n ? parsed.next_actions.filter((item: unknown) => typeof item === \"string\").map((item: string) => item.trim()).filter(Boolean)\n : [],\n risks_or_open_loops: Array.isArray(parsed.risks_or_open_loops)\n ? parsed.risks_or_open_loops.filter((item: unknown) => typeof item === \"string\").map((item: string) => item.trim()).filter(Boolean)\n : [],\n };\n\n return normalized.summary.length > 0 ? normalized : null;\n }\n\n private sanitizeConsolidationResult(result: {\n items?: unknown[];\n profileUpdates?: unknown[];\n entityUpdates?: unknown[];\n }): ConsolidationResult {\n const items: ConsolidationResult[\"items\"] = [];\n for (const item of Array.isArray(result.items) ? result.items : []) {\n const rawAction = typeof (item as any)?.action === \"string\" ? (item as any).action.toUpperCase() : \"SKIP\";\n const action =\n rawAction === \"ADD\" ||\n rawAction === \"MERGE\" ||\n rawAction === \"UPDATE\" ||\n rawAction === \"INVALIDATE\" ||\n rawAction === \"SKIP\"\n ? rawAction\n : \"SKIP\";\n const existingId =\n typeof (item as any)?.existingId === \"string\"\n ? (item as any).existingId.trim()\n : typeof (item as any)?.newMemoryId === \"string\"\n ? (item as any).newMemoryId.trim()\n : typeof (item as any)?.memoryId === \"string\"\n ? (item as any).memoryId.trim()\n : \"\";\n if (!existingId) continue;\n const mergeWith = typeof (item as any)?.mergeWith === \"string\" ? (item as any).mergeWith : undefined;\n const reason = typeof (item as any)?.reason === \"string\" ? (item as any).reason : \"\";\n const rawUpdatedContent = typeof (item as any)?.updatedContent === \"string\" ? (item as any).updatedContent : undefined;\n if (!rawUpdatedContent) {\n items.push({ existingId, action, mergeWith, updatedContent: undefined, reason });\n continue;\n }\n const sanitized = sanitizeMemoryContent(rawUpdatedContent);\n if (!sanitized.clean) {\n log.warn(`consolidation item sanitized (${existingId}); violations=${sanitized.violations.join(\", \")}`);\n }\n items.push({\n existingId,\n action,\n mergeWith,\n updatedContent: sanitized.text,\n reason,\n });\n }\n const profileUpdates = (Array.isArray(result.profileUpdates) ? result.profileUpdates : [])\n .map((update: any) =>\n typeof update === \"string\"\n ? update.trim()\n : typeof update?.content === \"string\"\n ? update.content.trim()\n : \"\",\n )\n .filter((update) => update.length > 0);\n const entityUpdates = (Array.isArray(result.entityUpdates) ? result.entityUpdates : [])\n .map((entity: unknown): ExtractedEntityResult | undefined => this.normalizeEntityUpdate(entity))\n .filter((entity: ExtractedEntityResult | undefined): entity is ExtractedEntityResult => (\n entity !== undefined && entity.name.length > 0\n ));\n return { items, profileUpdates, entityUpdates };\n }\n\n private async applyProactiveQuestionPass(\n conversation: string,\n base: ExtractionResult,\n ctx: ExtractionGroundingContext,\n signal?: AbortSignal,\n ): Promise<ExtractionResult> {\n if (!resolvePipelineProcessingCapabilities(this.config).proactiveExtraction) return base;\n const maxAdditional = Math.max(0, Math.floor(this.config.maxProactiveQuestionsPerExtraction));\n if (!shouldRunProactivePass(this.config, maxAdditional, this.shouldUseLocalLlm, this.localLlm)) return base;\n\n try {\n const proactive = await this.generateProactiveQuestions(conversation, base, maxAdditional, ctx.ambientCapture === true, signal);\n if (proactive.length === 0) return base;\n const ambient = ctx.ambientCapture === true;\n const proactiveAdditions = await this.answerProactiveQuestions(\n conversation, base, proactive, maxAdditional, ctx.sourceConnector, ambient, signal);\n const sanitizedAdditions = this.sanitizeExtractionResult(proactiveAdditions, ctx.messageTimestamp);\n const groundedAdditions = applyGroundingWithConnector(this.config, sanitizedAdditions, ctx);\n if (!this.hasExtractionOutputs(groundedAdditions)) return base;\n return this.mergeProactiveExtractionPass(base, groundedAdditions, maxAdditional);\n } catch (err) {\n if (signal?.aborted) throw err;\n log.debug(`proactive extraction question pass failed (ignored): ${err}`);\n return base;\n }\n }\n\n private parseProactiveQuestionsFromText(\n content: string,\n existingQuestionKeys: Set<string>,\n ): ExtractionQuestion[] {\n for (const candidate of extractJsonCandidates(content)) {\n try {\n const parsed = JSON.parse(candidate) as Partial<ProactiveQuestionsResultParsed>;\n if (!Array.isArray(parsed.questions)) continue;\n return parsed.questions\n .map((q) => normalizeQuestion(q as ExtractionQuestion))\n .filter((q) => q.question.length > 0)\n .filter((q) => !existingQuestionKeys.has(q.question.toLowerCase()));\n } catch {\n // Continue to next candidate.\n }\n }\n return [];\n }\n\n private parseProactiveExtractionResultFromText(content: string): ExtractionResult | null {\n for (const candidate of extractJsonCandidates(content)) {\n try {\n const parsed = ProactiveExtractionResultSchema.parse(JSON.parse(candidate));\n return this.normalizeExtractionResultPayload({\n ...parsed,\n questions: [],\n });\n } catch {\n // Continue to next candidate.\n }\n }\n return null;\n }\n\n private async generateProactiveQuestions(\n conversation: string,\n base: ExtractionResult,\n maxAdditional: number,\n ambientCapture: boolean,\n signal?: AbortSignal,\n ): Promise<ExtractionQuestion[]> {\n const existingQuestionKeys = new Set(\n (base.questions ?? [])\n .map((q) => q.question.trim().toLowerCase())\n .filter((q) => q.length > 0),\n );\n const factsPreview = base.facts\n .slice(0, 8)\n .map((f) => `- (${f.category}) ${f.content}`)\n .join(\"\\n\");\n const existingQuestionsPreview = (base.questions ?? [])\n .slice(0, 8)\n .map((q) => `- ${q.question}`)\n .join(\"\\n\");\n\n const prompt = [\n \"You are doing a proactive second-pass memory extraction.\",\n `Generate up to ${maxAdditional} additional high-value follow-up questions not already covered.${ambientCapture ? AMBIENT_CAPTURE_PROMPT_SECTION_COMPACT : \"\"}`,\n OUTPUT_LANGUAGE_POLICY,\n \"Return only valid JSON with this shape:\",\n '{\"questions\":[{\"question\":\"...\",\"context\":\"...\",\"priority\":0.0}]}',\n \"\",\n \"Current extracted facts:\",\n factsPreview || \"(none)\",\n \"\",\n \"Questions already extracted (do not repeat):\",\n existingQuestionsPreview || \"(none)\",\n \"\",\n \"Conversation:\",\n conversation,\n ].join(\"\\n\");\n\n if (this.shouldUseLocalLlm) {\n try {\n const localResponse = await this.localLlm.chatCompletion(\n [\n {\n role: \"system\",\n content: \"You are a proactive memory extraction assistant. Output valid JSON only.\",\n },\n { role: \"user\", content: prompt },\n ],\n {\n temperature: 0.2,\n maxTokens: this.config.proactiveExtractionMaxTokens,\n timeoutMs: this.config.proactiveExtractionTimeoutMs,\n operation: \"proactive_extraction\",\n priority: \"background\",\n signal,\n },\n );\n throwIfExtractionAborted(signal);\n if (localResponse?.content) {\n const localParsed = this.parseProactiveQuestionsFromText(\n localResponse.content.trim(),\n existingQuestionKeys,\n );\n if (localParsed.length > 0) {\n return localParsed.slice(0, maxAdditional);\n }\n }\n if (!this.config.localLlmFallback) {\n return [];\n }\n } catch (err) {\n if (signal?.aborted || !this.config.localLlmFallback) {\n throw err;\n }\n }\n }\n\n const fallbackResult = await this.fallbackLlm.parseWithSchema(\n [\n {\n role: \"system\",\n content: \"Generate additional proactive memory follow-up questions. Return valid JSON only.\",\n },\n { role: \"user\", content: prompt },\n ],\n ProactiveQuestionsResultSchema,\n this.withGatewayAgent({\n temperature: 0.2,\n maxTokens: this.config.proactiveExtractionMaxTokens,\n timeoutMs: this.config.proactiveExtractionTimeoutMs,\n signal,\n }),\n );\n if (!fallbackResult?.questions) return [];\n return fallbackResult.questions\n .map((q) => normalizeQuestion(q as ExtractionQuestion))\n .filter((q) => q.question.length > 0)\n .filter((q) => !existingQuestionKeys.has(q.question.toLowerCase()))\n .slice(0, maxAdditional);\n }\n\n private async answerProactiveQuestions(\n conversation: string,\n base: ExtractionResult,\n proactiveQuestions: ExtractionQuestion[],\n maxAdditional: number,\n sourceConnector: string | undefined,\n ambientCapture: boolean,\n signal?: AbortSignal,\n ): Promise<ExtractionResult> {\n const factsPreview = base.facts\n .slice(0, 8)\n .map((f) => `- (${f.category}) ${f.content}`)\n .join(\"\\n\");\n const entitiesPreview = base.entities\n .slice(0, 8)\n .map((entity) => `- (${entity.type}) ${entity.name}: ${entity.facts.join(\"; \") || \"(no facts)\"}`)\n .join(\"\\n\");\n const proactivePreview = proactiveQuestions\n .slice(0, maxAdditional)\n .map((question, index) => `${index + 1}. ${question.question}${question.context ? `\\n context: ${question.context}` : \"\"}`)\n .join(\"\\n\");\n\n const prompt = [\n \"You are answering proactive memory follow-up questions using only the provided buffered conversation.\",\n `Return at most ${maxAdditional} additional high-confidence memory candidates that were omitted from the base extraction.`,\n `Only include information directly supported by the conversation. Do not speculate. Do not repeat the base extraction.${ambientCapture ? AMBIENT_CAPTURE_PROMPT_SECTION_COMPACT : \"\"}`,\n OUTPUT_LANGUAGE_POLICY,\n \"Return only valid JSON with this shape:\",\n '{\"facts\":[{\"category\":\"fact\",\"content\":\"...\",\"confidence\":0.0,\"tags\":[\"...\"],\"entityRef\":\"optional\",\"promptedByQuestion\":\"optional\",\"quote\":\"optional verbatim span from a single turn\"}],\"profileUpdates\":[\"...\"],\"entities\":[{\"name\":\"...\",\"type\":\"person\",\"facts\":[\"...\"],\"structuredSections\":[{\"key\":\"beliefs\",\"title\":\"Beliefs\",\"facts\":[\"...\"]}],\"promptedByQuestion\":\"optional\"}],\"relationships\":[{\"source\":\"...\",\"target\":\"...\",\"label\":\"...\",\"promptedByQuestion\":\"optional\"}]}',\n this.config.provenance?.enabled\n ? '- Source quotes: For each fact, include a \"quote\" field with the EXACT verbatim words from the conversation that support the fact (a contiguous span from a single turn, not a paraphrase). Cap at ~300 chars.'\n : \"\",\n // #1578: emit the same event-time guidance as the primary extraction\n // paths so proactive-recovered facts also carry an optional eventTime\n // (chatgpt-codex thread on extraction.ts:1607). Returns \"\" when the\n // bi-temporal gate is off, keeping the prompt unchanged by default.\n eventTimePromptInstruction(this.config),\n headerConnector(sourceConnector) !== undefined && resolveMemoryLifecycleCapabilities(this.config).extractionScopeClassification\n ? `Tool, command, or CLI-flag instructions tied to the ${sourceConnector} agent are \"project\" scope; when you recover one, begin the fact with a leading \"In ${sourceConnector}, \" clause naming that agent (e.g. \"In ${sourceConnector}, use the search tool with a repository path.\").`\n : \"\",\n \"\",\n \"Base extracted facts (do not repeat):\",\n factsPreview || \"(none)\",\n \"\",\n \"Base extracted entities (do not repeat):\",\n entitiesPreview || \"(none)\",\n \"\",\n \"Answer these follow-up questions from the same conversation only:\",\n proactivePreview || \"(none)\",\n \"\",\n \"Conversation:\",\n conversation,\n ].join(\"\\n\");\n\n if (this.shouldUseLocalLlm) {\n try {\n const localResponse = await this.localLlm.chatCompletion(\n [\n {\n role: \"system\",\n content: \"You are a proactive memory extraction assistant. Output valid JSON only.\",\n },\n { role: \"user\", content: prompt },\n ],\n {\n temperature: 0.2,\n maxTokens: this.config.proactiveExtractionMaxTokens,\n timeoutMs: this.config.proactiveExtractionTimeoutMs,\n operation: \"proactive_extraction\",\n priority: \"background\",\n signal,\n },\n );\n throwIfExtractionAborted(signal);\n if (localResponse?.content) {\n const parsed = this.parseProactiveExtractionResultFromText(localResponse.content.trim());\n if (parsed) {\n return parsed;\n }\n }\n if (!this.config.localLlmFallback) {\n return { facts: [], profileUpdates: [], entities: [], questions: [] };\n }\n } catch (err) {\n if (signal?.aborted || !this.config.localLlmFallback) {\n throw err;\n }\n }\n }\n\n const fallbackResult = await this.fallbackLlm.parseWithSchema(\n [\n {\n role: \"system\",\n content: \"Answer proactive memory follow-up questions from the provided conversation only. Return valid JSON only.\",\n },\n { role: \"user\", content: prompt },\n ],\n ProactiveExtractionResultSchema,\n this.withGatewayAgent({\n temperature: 0.2,\n maxTokens: this.config.proactiveExtractionMaxTokens,\n timeoutMs: this.config.proactiveExtractionTimeoutMs,\n signal,\n }),\n );\n if (!fallbackResult) {\n return { facts: [], profileUpdates: [], entities: [], questions: [] };\n }\n return this.normalizeExtractionResultPayload({\n ...fallbackResult,\n questions: [],\n });\n }\n\n private mergeProactiveExtractionPass(\n base: ExtractionResult,\n proactive: ExtractionResult,\n maxAdditional: number,\n ): ExtractionResult {\n const allowlist = this.config.proactiveExtractionCategoryAllowlist;\n let remainingBudget = Math.max(0, Math.floor(maxAdditional));\n const mergedFacts = [...base.facts];\n const seenFacts = new Set(base.facts.map((fact) => normalizeFactKey(fact)));\n for (const fact of proactive.facts) {\n if (remainingBudget <= 0) break;\n if (fact.confidence < PROACTIVE_MIN_CONFIDENCE) continue;\n if (allowlist && !allowlist.includes(fact.category as MemoryCategory)) continue;\n const key = normalizeFactKey(fact);\n if (seenFacts.has(key)) continue;\n seenFacts.add(key);\n mergedFacts.push({ ...fact, source: \"proactive\" });\n remainingBudget -= 1;\n }\n\n const mergedEntities = base.entities.map((entity) => ({\n ...entity,\n facts: [...entity.facts],\n structuredSections: entity.structuredSections\n ? entity.structuredSections.map((section) => ({\n ...section,\n facts: [...section.facts],\n }))\n : undefined,\n }));\n const entityIndex = new Map(mergedEntities.map((entity, index) => [normalizeEntityKey(entity), index]));\n for (const entity of proactive.entities) {\n if (remainingBudget <= 0) break;\n const key = normalizeEntityKey(entity);\n const existingIndex = entityIndex.get(key);\n if (typeof existingIndex === \"number\") {\n const existing = mergedEntities[existingIndex]!;\n const nextFacts = new Set(existing.facts.map((fact) => fact.trim()));\n const nextSections = new Map(\n (existing.structuredSections ?? []).map((section) => [section.key, {\n ...section,\n facts: [...section.facts],\n }]),\n );\n let changed = false;\n for (const fact of entity.facts) {\n const trimmed = fact.trim();\n if (!trimmed || nextFacts.has(trimmed)) continue;\n nextFacts.add(trimmed);\n changed = true;\n }\n for (const section of entity.structuredSections ?? []) {\n const existingSection = nextSections.get(section.key);\n if (!existingSection) {\n nextSections.set(section.key, {\n key: section.key,\n title: section.title,\n facts: [...section.facts],\n });\n changed = true;\n continue;\n }\n const nextSectionFacts = new Set(existingSection.facts.map((fact) => fact.trim()));\n for (const fact of section.facts) {\n const trimmed = fact.trim();\n if (!trimmed || nextSectionFacts.has(trimmed)) continue;\n nextSectionFacts.add(trimmed);\n changed = true;\n }\n existingSection.facts = Array.from(nextSectionFacts);\n }\n if (changed) {\n mergedEntities[existingIndex] = {\n ...existing,\n facts: Array.from(nextFacts),\n structuredSections: Array.from(nextSections.values()),\n source: \"proactive\",\n promptedByQuestion: existing.promptedByQuestion ?? entity.promptedByQuestion,\n };\n remainingBudget -= 1;\n }\n continue;\n }\n mergedEntities.push({\n ...entity,\n source: \"proactive\",\n structuredSections: entity.structuredSections\n ? entity.structuredSections.map((section) => ({\n ...section,\n facts: [...section.facts],\n }))\n : undefined,\n });\n entityIndex.set(key, mergedEntities.length - 1);\n remainingBudget -= 1;\n }\n\n const mergedProfileUpdates = [...base.profileUpdates];\n const seenProfileUpdates = new Set(base.profileUpdates.map((update) => normalizeProfileUpdateKey(update)));\n for (const update of proactive.profileUpdates) {\n if (remainingBudget <= 0) break;\n const key = normalizeProfileUpdateKey(update);\n if (!key || seenProfileUpdates.has(key)) continue;\n seenProfileUpdates.add(key);\n mergedProfileUpdates.push(update.trim());\n remainingBudget -= 1;\n }\n\n const mergedRelationships = [...(base.relationships ?? [])];\n const seenRelationships = new Set(mergedRelationships.map((relationship) => normalizeRelationshipKey(relationship)));\n for (const relationship of proactive.relationships ?? []) {\n if (remainingBudget <= 0) break;\n const key = normalizeRelationshipKey(relationship);\n if (seenRelationships.has(key)) continue;\n seenRelationships.add(key);\n mergedRelationships.push({ ...relationship, extractionSource: \"proactive\" });\n remainingBudget -= 1;\n }\n\n return {\n ...base,\n facts: mergedFacts,\n entities: mergedEntities,\n profileUpdates: mergedProfileUpdates,\n relationships: mergedRelationships,\n };\n }\n\n private async parseWithGatewayFallback<T>(\n traceId: string,\n operation: LlmTraceEvent[\"operation\"],\n startedAtMs: number,\n schema: { parse: (data: unknown) => T },\n messages: Array<{ role: \"system\" | \"user\" | \"assistant\"; content: string }>,\n options: { temperature?: number; maxTokens?: number } = {},\n ): Promise<T | null> {\n const detailed = await this.fallbackLlm.parseWithSchemaDetailed(messages, schema, this.withGatewayAgent(options));\n if (\"modelUsed\" in detailed) {\n const durationMs = Date.now() - startedAtMs;\n this.emit({\n kind: \"llm_end\",\n traceId,\n model: detailed.modelUsed,\n operation,\n durationMs,\n output: JSON.stringify(detailed.result).slice(0, 2000),\n });\n return detailed.result;\n }\n return null;\n }\n\n /**\n * The one funnel every successful extraction path returns through — local\n * LLM, direct client, and gateway fallback alike. The ambient clamp lives\n * here so a new path cannot bypass it (issue #2294).\n */\n private finalizeExtractionResult(\n result: ExtractionResult,\n turns: ReadonlyArray<{\n content: string;\n sessionKey?: string;\n logicalSessionKey?: string;\n timestamp: string;\n turnFingerprint?: string;\n }>,\n sourceConnector?: string,\n ambientCapture = false,\n ): ExtractionResult {\n const clamped = ambientCapture ? clampAmbientCaptureConfidence(result) : result;\n const provenanced = attachExtractionProvenance(clamped, turns, this.config.provenance);\n return sourceConnector === undefined ? provenanced : { ...provenanced, sourceConnector };\n }\n\n async extract(\n turns: BufferTurn[],\n existingEntities?: string[],\n signal?: AbortSignal,\n ): Promise<ExtractionResult> {\n const lifecycleCaps = resolveMemoryLifecycleCapabilities(this.config);\n\n // Guard: skip if buffer is empty or all turns are whitespace-only\n const substantiveTurns = turns.filter((t) => t.content.trim().length > 0);\n if (substantiveTurns.length === 0) {\n log.debug(\"extraction skipped — no substantive turns in buffer\");\n return { facts: [], profileUpdates: [], entities: [], questions: [] };\n }\n\n const boundedTurns = substantiveTurns\n .map((turn) => ({\n ...turn,\n content: turn.role === \"assistant\"\n ? applyWorkExtractionBoundary(turn.content)\n : turn.content,\n }))\n .filter((turn) => turn.content.trim().length > 0);\n // One derivation, over the turns the model actually sees (boundedTurns) —\n // the same set the qualifier, grounding source, and telemetry filter\n // operate on. result.sourceConnector carries it to persistence so the\n // orchestrator does not recompute over a different turn set (#2183).\n const resolvedConnector = resolveSourceConnector(boundedTurns);\n // Ambient-capture provenance (issue #2294): true when any contributing turn\n // came from an always-on recorder, so the prompt warns about media audio\n // and the finalize chokepoint clamps high-impact personal facts.\n const ambientCapture = boundedTurns.some(\n (turn) => turn.ambientCapture === true && turn.extractionContextOnly !== true,\n );\n // The header and qualifier strip/restore are gated on the scope-classification\n // capability; persistence records resolvedConnector regardless (trusted metadata).\n const sourceConnector = lifecycleCaps.extractionScopeClassification\n ? resolvedConnector\n : undefined;\n const { conversation, renderedConversation } = renderExtractionConversation(boundedTurns, headerConnector(sourceConnector));\n\n const groundingSource = boundedTurns\n .map((turn) => turn.content)\n .join(\"\\n\\n\");\n const assertionSource = boundedTurns\n .filter((turn) => turn.extractionContextOnly !== true)\n .map((turn) => turn.content)\n .join(\"\\n\\n\");\n const roleAssertionSources: ExtractionGroundingRoleSources = {\n profile: boundedTurns\n .filter((turn) => turn.role === \"user\" && turn.extractionContextOnly !== true)\n .map((turn) => turn.content)\n .join(\"\\n\\n\"),\n identity: boundedTurns\n .filter((turn) => turn.role === \"assistant\" && turn.extractionContextOnly !== true)\n .map((turn) => turn.content)\n .join(\"\\n\\n\"),\n };\n if (renderedConversation.trim().length === 0) {\n log.debug(\"extraction skipped — conversation only contained non-memory work-layer context\");\n return {\n facts: [],\n profileUpdates: [],\n entities: [],\n questions: [],\n extractionSkippedReason: \"conversation_only_non_memory\",\n };\n }\n if (\n lifecycleCaps.extractionTelemetryPrefilter &&\n looksLikeMechanicalTelemetryTranscript(renderedConversation)\n ) {\n log.debug(\"extraction skipped — mechanical action/state telemetry without durable-memory cues\");\n return {\n facts: [],\n profileUpdates: [],\n entities: [],\n questions: [],\n extractionSkippedReason: \"mechanical_telemetry\",\n };\n }\n\n // Use the last turn's timestamp for temporal anchoring (more accurate than wall-clock)\n const lastTurnTs = boundedTurns.length > 0 ? new Date(boundedTurns[boundedTurns.length - 1].timestamp) : undefined;\n const messageTimestamp = lastTurnTs && !isNaN(lastTurnTs.getTime()) ? lastTurnTs : undefined;\n const groundingContext: ExtractionGroundingContext = {\n groundingSource,\n assertionSource,\n roleAssertionSources,\n messageTimestamp,\n sourceConnector,\n ambientCapture,\n scopeClassificationEnabled: lifecycleCaps.extractionScopeClassification,\n };\n\n const traceId = crypto.randomUUID();\n // Only emit llm_start for the direct path when a client or local LLM is configured.\n // Fallback-only deployments skip this to avoid fake spans in Opik.\n const emittedDirectStart = !!(this.shouldUseDirectClient || this.shouldUseLocalLlm);\n if (emittedDirectStart) {\n this.emit({ kind: \"llm_start\", traceId, model: this.config.model, operation: \"extraction\", input: conversation });\n }\n let closedDirectTrace = false;\n const startTime = Date.now();\n\n // --- profiling instrumentation ---\n const extractionTraceId = this.profiler.startTrace(\"extraction\", undefined, {\n model: this.config.model,\n localLlm: resolveLocalLlmCapabilities(this.config).localLlm,\n });\n this.profiler.startSpan(\"total\", extractionTraceId);\n // True when a local or direct extractor was attempted before the gateway\n // fallback, so a gateway \"no models\" result doesn't re-classify a real\n // primary failure as auth_config (codex review: preserve direct/local failures).\n let primaryExtractorAttempted = false;\n\n try {\n // Try local LLM first if enabled\n if (this.shouldUseLocalLlm) {\n this.profiler.startSpan(\"local-llm\", extractionTraceId);\n primaryExtractorAttempted = true;\n try {\n const localResult = await this.extractWithLocalLlm(conversation, existingEntities, signal, ambientCapture);\n throwIfExtractionAborted(signal);\n if (localResult) {\n const durationMs = Date.now() - startTime;\n this.profiler.endSpan(\"local-llm\", extractionTraceId);\n this.emit({ kind: \"llm_end\", traceId, model: this.config.localLlmModel, operation: \"extraction\", durationMs });\n log.debug(`extraction: used local LLM — ${localResult.facts.length} facts, ${localResult.entities.length} entities`);\n const sanitized = this.sanitizeExtractionResult(localResult, messageTimestamp);\n const grounded = applyGroundingWithConnector(this.config, sanitized, groundingContext);\n const finalResult = await this.applyProactiveQuestionPass(conversation, grounded, groundingContext, signal);\n return this.finalizeExtractionResult(finalResult, boundedTurns, resolvedConnector, ambientCapture);\n }\n // Local failed, fall back if allowed\n if (!this.config.localLlmFallback) {\n log.warn(\"extraction: local LLM failed and fallback disabled\");\n return {\n facts: [],\n profileUpdates: [],\n entities: [],\n questions: [],\n extractionFailure: \"local_llm_unavailable\",\n extractionFailureClass: \"provider_retryable\",\n };\n }\n log.info(\"extraction: local LLM unavailable, falling back to gateway default AI\");\n } catch (err) {\n if (signal?.aborted) throw err;\n if (!this.config.localLlmFallback) {\n log.warn(\"extraction: local LLM error and fallback disabled:\", err);\n return {\n facts: [],\n profileUpdates: [],\n entities: [],\n questions: [],\n extractionFailure: \"local_llm_error\",\n extractionFailureClass: \"provider_retryable\",\n };\n }\n log.info(\"extraction: local LLM error, falling back to gateway default AI:\", err);\n } finally {\n // End local-llm span if it wasn't ended on the success path\n try { this.profiler.endSpan(\"local-llm\", extractionTraceId); } catch { /* span may already be closed */ }\n }\n }\n\n // Try direct OpenAI-compatible client (Scryr, OpenRouter, etc.)\n if (this.shouldUseDirectClient) {\n this.profiler.startSpan(\"direct-client\", extractionTraceId);\n primaryExtractorAttempted = true;\n try {\n const directResult = await this.extractWithDirectClient(conversation, existingEntities, signal, ambientCapture);\n if (directResult) {\n const durationMs = Date.now() - startTime;\n this.profiler.endSpan(\"direct-client\", extractionTraceId);\n this.emit({ kind: \"llm_end\", traceId, model: this.config.model, operation: \"extraction\", durationMs });\n log.debug(`extraction: used direct client (${this.config.model}) — ${directResult.facts.length} facts, ${directResult.entities.length} entities`);\n const sanitized = this.sanitizeExtractionResult(directResult, messageTimestamp);\n const grounded = applyGroundingWithConnector(this.config, sanitized, groundingContext);\n const finalResult = await this.applyProactiveQuestionPass(conversation, grounded, groundingContext, signal);\n return this.finalizeExtractionResult(finalResult, boundedTurns, resolvedConnector, ambientCapture);\n }\n // Emit error event so Opik sees the direct client failure before fallback.\n // Wrapped in try/catch so a subscriber error doesn't break the fallback path.\n try {\n this.emit({\n kind: \"llm_error\", traceId, model: this.config.model, operation: \"extraction\",\n durationMs: Date.now() - startTime, error: \"direct client returned no result\",\n });\n } catch { /* trace emit must not block fallback */ }\n closedDirectTrace = true;\n log.info(\"extraction: direct client returned no result, falling back to gateway AI\");\n } catch (err) {\n if (signal?.aborted) throw err;\n try {\n this.emit({\n kind: \"llm_error\", traceId, model: this.config.model, operation: \"extraction\",\n durationMs: Date.now() - startTime, error: String(err),\n });\n } catch { /* trace emit must not block fallback */ }\n closedDirectTrace = true;\n log.info(\"extraction: direct client failed, falling back to gateway AI:\", err);\n } finally {\n try { this.profiler.endSpan(\"direct-client\", extractionTraceId); } catch { /* span may already be closed */ }\n }\n }\n\n // Close any orphaned direct-path llm_start (e.g., local LLM failed, no direct client)\n if (emittedDirectStart && !closedDirectTrace) {\n try {\n this.emit({\n kind: \"llm_error\", traceId, model: this.config.model, operation: \"extraction\",\n durationMs: Date.now() - startTime, error: \"local LLM failed, handing off to gateway fallback\",\n });\n } catch { /* trace emit must not block fallback */ }\n }\n\n // In gateway mode this is the primary extraction path. In plugin mode it is the\n // final fallback after local/direct attempts fail. Emit a fresh llm_start so the\n // gateway-backed call gets its own trace rather than being orphaned under the\n // direct-client traceId.\n const fallbackTraceId = crypto.randomUUID();\n const fallbackStartTime = Date.now();\n if (this.useGatewayModelSource) {\n log.debug(\n `extraction: using gateway model chain as primary path` +\n (this.config.taskModelChain ? \" (taskModelChain)\" :\n this.config.gatewayAgentId ? ` (agent: ${this.config.gatewayAgentId})` : \" (defaults)\"),\n );\n } else {\n log.info(\"extraction: falling back to gateway default AI\");\n }\n\n this.profiler.startSpan(\"gateway-fallback\", extractionTraceId);\n try {\n const messages = [\n { role: \"system\" as const, content: buildExtractionInstructions(this.config, existingEntities, ambientCapture) },\n { role: \"user\" as const, content: conversation },\n ];\n\n this.emit({ kind: \"llm_start\", traceId: fallbackTraceId, model: \"fallback\", operation: \"extraction\", input: conversation });\n\n const detailed = await this.fallbackLlm.parseWithSchemaDetailed(\n messages,\n ExtractionResultSchema,\n this.withGatewayAgent({\n temperature: 0.3,\n maxTokens: this.config.extractionMaxOutputTokens,\n timeoutMs: this.config.localLlmTimeoutMs,\n signal,\n }),\n );\n\n const fallbackDurationMs = Date.now() - fallbackStartTime;\n\n if (\"modelUsed\" in detailed && Array.isArray(detailed.result.facts)) {\n const result = detailed.result;\n this.emit({\n kind: \"llm_end\", traceId: fallbackTraceId, model: detailed.modelUsed, operation: \"extraction\",\n durationMs: fallbackDurationMs, output: JSON.stringify(result).slice(0, 2000),\n });\n log.debug(\n `extracted ${result.facts.length} facts, ${result.entities.length} entities, ${(result.questions ?? []).length} questions via fallback (${detailed.modelUsed})`,\n );\n const normalized = this.normalizeExtractionResultPayload(result);\n const sanitized = this.sanitizeExtractionResult(normalized, messageTimestamp);\n const grounded = applyGroundingWithConnector(this.config, sanitized, groundingContext);\n const finalResult = await this.applyProactiveQuestionPass(conversation, grounded, groundingContext, signal);\n return this.finalizeExtractionResult(finalResult, boundedTurns, resolvedConnector, ambientCapture);\n }\n\n this.emit({\n kind: \"llm_error\", traceId: fallbackTraceId, model: \"fallback\", operation: \"extraction\",\n durationMs: fallbackDurationMs, error: \"fallback returned no parsed output\",\n });\n log.warn(\"extraction fallback returned no parsed output\");\n const fallbackParseFailureClass: ExtractionFailureClass =\n detailed.result === null\n ? detailed.failureReason === \"no_models\" && primaryExtractorAttempted\n ? // Gateway had no models, but a local/direct extractor already failed —\n // the root cause is the primary (transient), not gateway auth/config.\n \"provider_retryable\"\n : classifyFallbackParseFailure(detailed.failureReason)\n : \"parse_empty\";\n return {\n facts: [],\n profileUpdates: [],\n entities: [],\n questions: [],\n extractionFailure: \"fallback_no_parsed_output\",\n extractionFailureClass: fallbackParseFailureClass,\n };\n } catch (err) {\n if (signal?.aborted) throw err;\n this.emit({\n kind: \"llm_error\", traceId: fallbackTraceId, model: \"fallback\", operation: \"extraction\",\n durationMs: Date.now() - fallbackStartTime, error: String(err),\n });\n log.error(\"extraction fallback failed\", err);\n return {\n facts: [],\n profileUpdates: [],\n entities: [],\n questions: [],\n extractionFailure: \"fallback_failed\",\n extractionFailureClass: classifyExtractionThrownError(err),\n };\n } finally {\n try { this.profiler.endSpan(\"gateway-fallback\", extractionTraceId); } catch { /* span may already be closed */ }\n }\n\n } finally {\n // --- profiling: close the total span and trace ---\n this.profiler.endSpan(\"total\", extractionTraceId);\n this.profiler.endTrace(extractionTraceId); // persists to JSONL file\n }\n }\n\n /**\n * Extract memories using local LLM with JSON mode.\n * Uses a minimal prompt to fit within local model context limits (typically 4k-8k).\n */\n private async extractWithLocalLlm(\n conversation: string,\n existingEntities?: string[],\n signal?: AbortSignal,\n ambientCapture = false,\n ): Promise<ExtractionResult | null> {\n const lifecycleCaps = resolveMemoryLifecycleCapabilities(this.config);\n log.debug(\n `extractWithLocalLlm: starting extraction, localLlmEnabled=${this.shouldUseLocalLlm}, model=${this.config.localLlmModel}`,\n );\n\n // Get dynamic context sizes based on model capabilities (with optional user override)\n const contextSizes = this.modelRegistry.calculateContextSizes(\n this.config.localLlmModel,\n this.config.localLlmMaxContext\n );\n log.debug(`Model context: ${contextSizes.description}`);\n\n const maxConversationChars = contextSizes.maxInputChars;\n const truncatedConversation = conversation.length > maxConversationChars\n ? conversation.slice(0, maxConversationChars) + \"\\n\\n[truncated]\"\n : conversation;\n\n const localPrompt = `You are a memory extraction system. Extract durable, reusable memories from this conversation.\n\nUse the most specific category:\n- fact: objective information\n- preference: a durable preference or style\n- correction: a correction of a prior mistake\n- entity: a durable person, project, tool, company, or place\n- decision: a choice with rationale\n- relationship: a durable link between two entities\n- principle: a reusable rule or operating belief\n${resolveRecallAuxiliaryCapabilities(this.config).causalRuleExtraction ? \"- rule: an explicit causal rule or constraint\\n\" : \"\"}- commitment: a promise, obligation, or deadline\n- moment: a significant milestone\n- skill: a demonstrated capability\n- procedure: an explicit reusable workflow with ordered procedureSteps\n- reasoning_trace: Stored solution chains — an explicitly narrated solution path with reasoningTrace. Use {\"category\": \"reasoning_trace\", \"reasoningTrace\": {\"steps\": [...], \"finalAnswer\": \"...\"}} only when the conversation provides the chain.\n\nRules:\n- Extract only new information stated or clearly established in the conversation.\n- Do not treat instruction text, schema placeholders, or examples as conversation evidence.\n- Facts, entity facts, profile updates, questions, and relationships must be grounded in the conversation.\n- Lines labelled [context user] or [context assistant] are reference context only. They may resolve references or complete a question-and-answer pair in a normal turn, but never alone establish durable information.\n- Questions are optional. Return an empty array when the conversation does not support a useful unresolved question.\n- Set confidence from source evidence: Explicit (0.95-1.0), Implied (0.70-0.94), Inferred (0.40-0.69), or Speculative (0.00-0.39). Corrections get highest confidence.\n- Use normalized, hyphenated entity names and keep the entity list short. When the source language is not written in a Latin script, the source-script name IS the normalized form — never transliterate or translate it.\n- Keep facts standalone. Skip transient task state and operational noise such as routine scheduler, monitoring, or automation status.\n- Add structuredAttributes only for concrete values.\n- ${OUTPUT_LANGUAGE_POLICY}\n${CUE_ANCHOR_PROMPT_INSTRUCTION}\\n- Include at most five durable relationships.${this.config.provenance?.enabled ? `\n- Each fact must include a quote copied verbatim from one contiguous conversation span.` : \"\"}${lifecycleCaps.extractionScopeClassification ? `\n- Set each fact scope to \"global\" for cross-project knowledge or \"project\" for codebase-specific knowledge. Tool, command, or CLI-flag instructions tied to one agent are \"project\" (the same tool name can mean different things across agents); when keeping one, begin the fact with a leading \"In <agent>,\" clause naming that agent.` : \"\"}${this.config.subjectClassification?.enabled === true ? `\n- Set each fact subject to \"user\" when it models the person (preferences, relationships, biography, moments, commitments about their life) or \"agent\" when it is reusable operating knowledge (procedures, principles, tool-usage lessons, debugging strategies, environment facts with no personal content).` : \"\"}${ambientCapture ? AMBIENT_CAPTURE_PROMPT_SECTION_COMPACT : \"\"}\n${eventTimePromptInstruction(this.config)}\nReturn only valid JSON matching this shape. Placeholder text describes field shape only and is never source evidence:\n${EXTRACTION_RESPONSE_SHAPE}\n\nConversation:\n${truncatedConversation}`;\n\n log.debug(\n `extractWithLocalLlm: calling localLlm.chatCompletion with prompt length ${localPrompt.length}...`,\n );\n const response = await this.localLlm.chatCompletion(\n [\n { role: \"system\", content: \"You are a memory extraction system. Output valid JSON only.\" },\n { role: \"user\", content: localPrompt },\n ],\n {\n temperature: 0.1,\n maxTokens: contextSizes.maxOutputTokens,\n operation: \"extraction\",\n disableThinking: shouldEnableLocalExtractionThinking(this.config, conversation.length)\n ? false\n : undefined,\n priority: \"background\",\n signal,\n },\n );\n\n if (!response?.content) {\n log.debug(\"extractWithLocalLlm: chatCompletion returned null or empty content\");\n return null;\n }\n\n const content = response.content.trim();\n // Avoid logging model output content by default (may contain user data).\n log.debug(`extractWithLocalLlm: got response content, length=${content.length}`);\n\n for (const candidate of extractJsonCandidates(content)) {\n try {\n log.debug(`extractWithLocalLlm: attempting JSON parse, candidate length=${candidate.length}`);\n const parsed = JSON.parse(candidate);\n if (!this.looksLikeExtractionResultPayload(parsed)) {\n continue;\n }\n\n const result: ExtractionResult = this.normalizeExtractionResultPayload(parsed);\n\n log.debug(\n `extractWithLocalLlm: successfully parsed response, facts=${result.facts.length}, entities=${result.entities.length}, profileUpdates=${result.profileUpdates.length}, questions=${result.questions.length}`,\n );\n return result;\n } catch {\n // keep trying candidates\n }\n }\n\n // Try to extract partial facts from truncated JSON after all complete JSON\n // candidates fail to parse.\n log.debug(\"extractWithLocalLlm: JSON parse failed, attempting partial extraction...\");\n const partial = this.extractPartialFacts(content);\n if (partial.facts.length > 0 || partial.entities.length > 0) {\n log.debug(\n `extractWithLocalLlm: extracted ${partial.facts.length} partial facts from truncated JSON`,\n );\n return partial;\n }\n return null;\n }\n\n /**\n * Extract memories using direct OpenAI-compatible client (Chat Completions API).\n * Works with Scryr, OpenRouter, and other OpenAI-compatible endpoints.\n */\n private async extractWithDirectClient(\n conversation: string,\n existingEntities?: string[],\n signal?: AbortSignal,\n ambientCapture = false,\n ): Promise<ExtractionResult | null> {\n if (!this.client) return null;\n\n const tokenParams = buildChatCompletionTokenLimit(this.config.model, this.config.extractionMaxOutputTokens, {\n assumeOpenAI: this.directClientUsesOpenAiTokenSemantics(),\n });\n log.debug(`extractWithDirectClient: calling model=${this.config.model} tokenParams=${JSON.stringify(tokenParams)}`);\n\n const response = await this.client.chat.completions.create(\n {\n model: this.config.model,\n messages: [\n {\n role: \"system\",\n content:\n buildExtractionInstructions(this.config, existingEntities, ambientCapture) +\n `\\n\\nReturn only valid JSON matching this shape. Placeholder text describes field shape only and is never source evidence:\\n${EXTRACTION_RESPONSE_SHAPE}`,\n },\n { role: \"user\", content: conversation },\n ],\n ...tokenParams,\n },\n signal ? { signal } : undefined,\n );\n\n const content = response.choices?.[0]?.message?.content?.trim();\n if (!content) {\n log.info(`extractWithDirectClient: empty response — choices=${JSON.stringify(response.choices?.length ?? 0)} finishReason=${response.choices?.[0]?.finish_reason ?? \"n/a\"}`);\n return null;\n }\n\n log.info(\n `extractWithDirectClient: got response, length=${content.length}`,\n );\n\n for (const candidate of extractJsonCandidates(content)) {\n try {\n const parsed = JSON.parse(candidate);\n\n return this.normalizeExtractionResultPayload(parsed);\n } catch {\n // keep trying candidates\n }\n }\n\n log.info(`extractWithDirectClient: failed to parse JSON from response (first 200 chars: ${content.slice(0, 200)})`);\n return null;\n }\n\n /**\n * Extract partial facts from truncated JSON responses.\n * Local LLMs sometimes hit token limits mid-JSON. This tries to salvage valid facts.\n */\n private extractPartialFacts(jsonStr: string): ExtractionResult {\n\n const facts: ExtractionResult[\"facts\"] = [];\n const entities: ExtractionResult[\"entities\"] = [];\n\n try {\n // Find all complete fact objects (ones with all required fields)\n const factRegex = /\\{\\s*\"category\"\\s*:\\s*\"([^\"]+)\"\\s*,\\s*\"content\"\\s*:\\s*\"([^\"]+)\"\\s*,\\s*\"confidence\"\\s*:\\s*([0-9.]+)/g;\n let match;\n while ((match = factRegex.exec(jsonStr)) !== null) {\n const category = match[1]?.trim() ?? \"\";\n if (!isMemoryCategory(category)) continue;\n facts.push({\n category,\n content: match[2].replace(/\\\\n/g, '\\n').replace(/\\\\\"/g, '\"'),\n confidence: parseFloat(match[3]),\n tags: [],\n });\n }\n\n // Find all complete entity objects\n const entityRegex = /\\{\\s*\"name\"\\s*:\\s*\"([^\"]+)\"\\s*,\\s*\"type\"\\s*:\\s*\"([^\"]+)\"/g;\n while ((match = entityRegex.exec(jsonStr)) !== null) {\n const type = extractionEntityType(match[2]);\n if (type === undefined) continue;\n entities.push({\n name: match[1],\n type,\n facts: [],\n });\n }\n } catch {\n // Ignore regex errors\n }\n\n return this.normalizeExtractionResultPayload({ facts, entities, profileUpdates: [], questions: [] });\n }\n\n async consolidate(\n newMemories: MemoryFile[],\n existingMemories: MemoryFile[],\n currentProfile: string,\n ): Promise<ConsolidationResult> {\n const newList = newMemories\n .map(\n (m) =>\n `[${m.frontmatter.id}] (${m.frontmatter.category}) ${m.content}`,\n )\n .join(\"\\n\");\n\n const existingList = existingMemories\n .slice(-50) // Only consolidate against recent memories\n .map(\n (m) =>\n `[${m.frontmatter.id}] (${m.frontmatter.category}) ${m.content}`,\n )\n .join(\"\\n\");\n\n const cTraceId = crypto.randomUUID();\n this.emit({ kind: \"llm_start\", traceId: cTraceId, model: this.config.model, operation: \"consolidation\", input: newList });\n const cStartTime = Date.now();\n\n // Try local LLM first if enabled\n if (this.shouldUseLocalLlm) {\n try {\n const localResult = await this.consolidateWithLocalLlm(newList, existingList, currentProfile);\n if (localResult) {\n const durationMs = Date.now() - cStartTime;\n this.emit({ kind: \"llm_end\", traceId: cTraceId, model: this.config.localLlmModel, operation: \"consolidation\", durationMs });\n log.debug(`consolidation: used local LLM — ${localResult.items.length} decisions`);\n return this.sanitizeConsolidationResult(localResult);\n }\n if (!this.config.localLlmFallback) {\n log.warn(\"consolidation: local LLM failed and fallback disabled\");\n return { items: [], profileUpdates: [], entityUpdates: [] };\n }\n log.info(\"consolidation: local LLM unavailable, falling back to gateway AI\");\n } catch (err) {\n if (!this.config.localLlmFallback) {\n log.warn(\"consolidation: local LLM error and fallback disabled:\", err);\n return { items: [], profileUpdates: [], entityUpdates: [] };\n }\n log.info(\"consolidation: local LLM error, falling back to gateway AI:\", err);\n }\n }\n\n const fallbackResult = await this.parseWithGatewayFallback(\n cTraceId,\n \"consolidation\",\n cStartTime,\n ConsolidationResultSchema,\n [\n {\n role: \"system\",\n content: buildConsolidationSystemPrompt(this.config),\n },\n {\n role: \"user\",\n content: `Current behavioral profile:\n${currentProfile || \"(empty)\"}\n\nExisting memories:\n${existingList || \"(none)\"}\n\nNew memories to consolidate:\n${newList}\n\nConsolidate the new memories against existing ones.`,\n },\n ],\n { temperature: 0.3, maxTokens: 4096 },\n );\n if (fallbackResult) {\n log.debug(`consolidation: ${fallbackResult.items.length} decisions via fallback`);\n return this.sanitizeConsolidationResult({\n items: fallbackResult.items,\n profileUpdates: fallbackResult.profileUpdates,\n entityUpdates: fallbackResult.entityUpdates,\n });\n }\n\n // Fall back to OpenAI API\n if (!this.client) {\n log.warn(\"consolidation skipped — no OpenAI API key and local LLM failed/disabled\");\n return { items: [], profileUpdates: [], entityUpdates: [] };\n }\n\n try {\n const instructionText = `${buildConsolidationSystemPrompt(this.config)}\n\nCurrent behavioral profile:\n${currentProfile || \"(empty)\"}\n\nExisting memories:\n${existingList || \"(none)\"}\n\nNew memories to consolidate:\n${newList}\n\nRespond with valid JSON only, matching this schema:\n${CONSOLIDATION_RESPONSE_SCHEMA}`;\n\n const response = await this.client.chat.completions.create({\n model: this.config.model,\n messages: [\n { role: \"system\", content: instructionText },\n { role: \"user\", content: \"Consolidate the new memories against existing ones.\" },\n ],\n ...(this.config.reasoningEffort !== \"none\" ? { reasoning_effort: this.config.reasoningEffort } : {}),\n ...buildChatCompletionTokenLimit(this.config.model, 4096, {\n assumeOpenAI: this.directClientUsesOpenAiTokenSemantics(),\n }),\n });\n\n const rawContent = response.choices?.[0]?.message?.content?.trim();\n const cDurationMs = Date.now() - cStartTime;\n const cUsage = (response as any).usage;\n\n let parsed: any = null;\n if (rawContent) {\n for (const candidate of extractJsonCandidates(rawContent)) {\n try {\n parsed = JSON.parse(candidate);\n break;\n } catch {\n // keep trying candidates\n }\n }\n }\n\n this.emit({\n kind: \"llm_end\", traceId: cTraceId, model: this.config.model, operation: \"consolidation\", durationMs: cDurationMs,\n output: parsed ? JSON.stringify(parsed).slice(0, 2000) : undefined,\n tokenUsage: cUsage ? { input: cUsage.prompt_tokens, output: cUsage.completion_tokens, total: cUsage.total_tokens } : undefined,\n });\n\n if (parsed && Array.isArray(parsed.items)) {\n log.debug(\n `consolidation: ${parsed.items.length} decisions`,\n );\n return this.sanitizeConsolidationResult({\n items: parsed.items,\n profileUpdates: Array.isArray(parsed.profileUpdates) ? parsed.profileUpdates : [],\n entityUpdates: Array.isArray(parsed.entityUpdates) ? parsed.entityUpdates : [],\n });\n }\n\n log.warn(\"consolidation returned no parsed output\");\n return { items: [], profileUpdates: [], entityUpdates: [] };\n } catch (err) {\n this.emit({\n kind: \"llm_error\", traceId: cTraceId, model: this.config.model, operation: \"consolidation\",\n durationMs: Date.now() - cStartTime, error: String(err),\n });\n log.error(\"consolidation failed\", err);\n return { items: [], profileUpdates: [], entityUpdates: [] };\n }\n }\n\n /**\n * Consolidate memories using local LLM.\n */\n private async consolidateWithLocalLlm(\n newList: string,\n existingList: string,\n currentProfile: string,\n ): Promise<ConsolidationResult | null> {\n // Get dynamic context sizes\n const contextSizes = this.modelRegistry.calculateContextSizes(\n this.config.localLlmModel,\n this.config.localLlmMaxContext\n );\n log.debug(`Consolidation model context: ${contextSizes.description}`);\n\n const prompt = `${buildConsolidationSystemPrompt(this.config)}\n\nCurrent behavioral profile:\n${currentProfile || \"(empty)\"}\n\nExisting memories:\n${existingList || \"(none)\"}\n\nNew memories to consolidate:\n${newList}\n\nRespond with valid JSON matching this schema:\n${CONSOLIDATION_RESPONSE_SCHEMA}`;\n\n const response = await this.localLlm.chatCompletion(\n [\n { role: \"system\", content: \"You are a memory consolidation system. Output valid JSON only.\" },\n { role: \"user\", content: prompt },\n ],\n {\n temperature: 0.3,\n maxTokens: contextSizes.maxOutputTokens,\n operation: \"consolidation\",\n priority: \"background\",\n },\n );\n\n if (!response?.content) {\n return null;\n }\n\n try {\n const content = response.content.trim();\n for (const candidate of extractJsonCandidates(content)) {\n try {\n const parsed = JSON.parse(candidate);\n return {\n items: Array.isArray((parsed as any).items) ? (parsed as any).items : [],\n profileUpdates: Array.isArray((parsed as any).profileUpdates)\n ? (parsed as any).profileUpdates\n : [],\n entityUpdates: Array.isArray((parsed as any).entityUpdates)\n ? (parsed as any).entityUpdates\n : [],\n } as ConsolidationResult;\n } catch {\n // keep trying candidates\n }\n }\n return null;\n } catch (err) {\n log.warn(\"local LLM consolidation: failed to parse JSON response:\", err);\n return null;\n }\n }\n\n /**\n * Consolidate a bloated profile.md into a compact version.\n * The LLM merges duplicates, removes stale info, and preserves section structure.\n * Returns the consolidated markdown or null on failure.\n */\n async consolidateProfile(\n fullProfileContent: string,\n targetLines: number = 50,\n ): Promise<{ consolidatedProfile: string; removedCount: number; summary: string } | null> {\n const pTraceId = crypto.randomUUID();\n this.emit({ kind: \"llm_start\", traceId: pTraceId, model: this.config.model, operation: \"profile_consolidation\", input: fullProfileContent.slice(0, 2000) });\n const pStartTime = Date.now();\n\n // Try local LLM first if enabled\n if (this.shouldUseLocalLlm) {\n try {\n const localResult = await this.consolidateProfileWithLocalLlm(fullProfileContent, targetLines);\n if (localResult) {\n const durationMs = Date.now() - pStartTime;\n this.emit({ kind: \"llm_end\", traceId: pTraceId, model: this.config.localLlmModel, operation: \"profile_consolidation\", durationMs });\n log.debug(`profile consolidation: used local LLM — removed ${localResult.removedCount} items`);\n return localResult;\n }\n if (!this.config.localLlmFallback) {\n log.warn(\"profile consolidation: local LLM failed and fallback disabled\");\n return null;\n }\n log.info(\"profile consolidation: local LLM unavailable, falling back to gateway AI\");\n } catch (err) {\n if (!this.config.localLlmFallback) {\n log.warn(\"profile consolidation: local LLM error and fallback disabled:\", err);\n return null;\n }\n log.info(\"profile consolidation: local LLM error, falling back to gateway AI:\", err);\n }\n }\n\n const profileFallback = await this.parseWithGatewayFallback(\n pTraceId,\n \"profile_consolidation\",\n pStartTime,\n buildProfileConsolidationResultSchema(targetLines),\n [\n {\n role: \"system\",\n content: buildProfileConsolidationSystemPrompt(targetLines),\n },\n { role: \"user\", content: fullProfileContent },\n ],\n { temperature: 0.3, maxTokens: 4096 },\n );\n if (profileFallback) {\n log.debug(\n `profile consolidation: removed ${profileFallback.removedCount} items — ${profileFallback.summary} (fallback)`,\n );\n return profileFallback;\n }\n\n // Fall back to OpenAI API\n if (!this.client) {\n log.warn(\"profile consolidation skipped — no OpenAI API key and local LLM failed/disabled\");\n return null;\n }\n\n try {\n const instructionText = `${buildProfileConsolidationSystemPrompt(targetLines)}\n\nRespond with valid JSON matching this schema:\n${PROFILE_CONSOLIDATION_RESPONSE_SCHEMA}`;\n\n const response = await this.client.chat.completions.create({\n model: this.config.model,\n messages: [\n { role: \"system\", content: instructionText },\n { role: \"user\", content: fullProfileContent },\n ],\n ...(this.config.reasoningEffort !== \"none\" ? { reasoning_effort: this.config.reasoningEffort } : {}),\n ...buildChatCompletionTokenLimit(this.config.model, 4096, {\n assumeOpenAI: this.directClientUsesOpenAiTokenSemantics(),\n }),\n });\n\n const rawContent = response.choices?.[0]?.message?.content?.trim();\n const pDurationMs = Date.now() - pStartTime;\n const pUsage = (response as any).usage;\n\n let parsed: any = null;\n if (rawContent) {\n for (const candidate of extractJsonCandidates(rawContent)) {\n try {\n parsed = JSON.parse(candidate);\n break;\n } catch {\n // keep trying candidates\n }\n }\n }\n\n this.emit({\n kind: \"llm_end\", traceId: pTraceId, model: this.config.model, operation: \"profile_consolidation\", durationMs: pDurationMs,\n output: parsed ? parsed.summary : undefined,\n tokenUsage: pUsage ? { input: pUsage.prompt_tokens, output: pUsage.completion_tokens, total: pUsage.total_tokens } : undefined,\n });\n\n if (parsed && typeof parsed.consolidatedProfile === \"string\") {\n log.debug(\n `profile consolidation: removed ${parsed.removedCount ?? 0} items — ${parsed.summary ?? \"\"}`,\n );\n return {\n consolidatedProfile: parsed.consolidatedProfile,\n removedCount: Number(parsed.removedCount || 0),\n summary: String(parsed.summary || \"\"),\n };\n }\n\n log.warn(\"profile consolidation returned no parsed output\");\n return null;\n } catch (err) {\n this.emit({\n kind: \"llm_error\", traceId: pTraceId, model: this.config.model, operation: \"profile_consolidation\",\n durationMs: Date.now() - pStartTime, error: String(err),\n });\n log.error(\"profile consolidation failed\", err);\n return null;\n }\n }\n\n /**\n * Consolidate profile using local LLM.\n */\n private async consolidateProfileWithLocalLlm(\n fullProfileContent: string,\n targetLines: number = 50,\n ): Promise<{ consolidatedProfile: string; removedCount: number; summary: string } | null> {\n // Get dynamic context sizes\n const contextSizes = this.modelRegistry.calculateContextSizes(\n this.config.localLlmModel,\n this.config.localLlmMaxContext\n );\n log.debug(`Profile consolidation model context: ${contextSizes.description}`);\n\n const prompt = `${buildProfileConsolidationSystemPrompt(targetLines)}\n\nProfile to consolidate:\n${fullProfileContent}\n\nRespond with valid JSON matching this schema:\n${PROFILE_CONSOLIDATION_RESPONSE_SCHEMA}`;\n\n const response = await this.localLlm.chatCompletion(\n [\n { role: \"system\", content: \"You are a profile consolidation system. Output valid JSON only.\" },\n { role: \"user\", content: prompt },\n ],\n {\n temperature: 0.3,\n maxTokens: contextSizes.maxOutputTokens,\n operation: \"profile_consolidation\",\n priority: \"background\",\n },\n );\n\n if (!response?.content) {\n return null;\n }\n\n try {\n const content = response.content.trim();\n for (const candidate of extractJsonCandidates(content)) {\n try {\n const parsed = JSON.parse(candidate);\n return {\n consolidatedProfile: String((parsed as any).consolidatedProfile || \"\"),\n removedCount: Number((parsed as any).removedCount || 0),\n summary: String((parsed as any).summary || \"\"),\n };\n } catch {\n // keep trying candidates\n }\n }\n return null;\n } catch (err) {\n log.warn(\"local LLM profile consolidation: failed to parse JSON response:\", err);\n return null;\n }\n }\n\n /**\n * Consolidate IDENTITY.md reflections into a concise \"Learned Patterns\" section.\n * Returns the new content for the IDENTITY.md file (everything below the static header).\n */\n async consolidateIdentity(\n fullIdentityContent: string,\n staticHeaderEndMarker: string,\n ): Promise<{ learnedPatterns: string[]; summary: string } | null> {\n const iTraceId = crypto.randomUUID();\n this.emit({ kind: \"llm_start\", traceId: iTraceId, model: this.config.model, operation: \"identity_consolidation\", input: fullIdentityContent.slice(0, 2000) });\n const iStartTime = Date.now();\n\n // Try local LLM first if enabled\n if (this.shouldUseLocalLlm) {\n try {\n const localResult = await this.consolidateIdentityWithLocalLlm(fullIdentityContent);\n if (localResult) {\n const durationMs = Date.now() - iStartTime;\n this.emit({ kind: \"llm_end\", traceId: iTraceId, model: this.config.localLlmModel, operation: \"identity_consolidation\", durationMs });\n log.debug(`identity consolidation: used local LLM — ${localResult.learnedPatterns.length} patterns`);\n return localResult;\n }\n if (!this.config.localLlmFallback) {\n log.warn(\"identity consolidation: local LLM failed and fallback disabled\");\n return null;\n }\n log.info(\"identity consolidation: local LLM unavailable, falling back to gateway AI\");\n } catch (err) {\n if (!this.config.localLlmFallback) {\n log.warn(\"identity consolidation: local LLM error and fallback disabled:\", err);\n return null;\n }\n log.info(\"identity consolidation: local LLM error, falling back to gateway AI:\", err);\n }\n }\n\n const identityFallback = await this.parseWithGatewayFallback(\n iTraceId,\n \"identity_consolidation\",\n iStartTime,\n IdentityConsolidationResultSchema,\n [\n {\n role: \"system\",\n content: `You are an identity consolidation system. You are given the full contents of an IDENTITY.md file that contains many individual reflection entries. Your job is to:\n\n1. Read all the reflection entries (sections starting with \"## Reflection\")\n2. Extract the most important, durable behavioral patterns and lessons learned\n3. Consolidate them into concise, standalone statements (aim for 10-25 key patterns)\n4. Remove redundancy — if multiple reflections say the same thing, merge into one clear statement\n5. Prioritize patterns that are actionable and recurring over one-off observations\n6. Write a brief summary paragraph\n\nThe goal is to reduce a bloated file to a compact, high-signal set of learned patterns while preserving all genuinely useful self-knowledge.`,\n },\n { role: \"user\", content: fullIdentityContent },\n ],\n { temperature: 0.3, maxTokens: 4096 },\n );\n if (identityFallback) {\n log.debug(\n `identity consolidation: ${identityFallback.learnedPatterns.length} patterns (fallback)`,\n );\n return identityFallback;\n }\n\n // Fall back to OpenAI API\n if (!this.client) {\n log.warn(\"identity consolidation skipped — no OpenAI API key and local LLM failed/disabled\");\n return null;\n }\n\n try {\n const instructionText = `You are an identity consolidation system. You are given the full contents of an IDENTITY.md file that contains many individual reflection entries. Your job is to:\n\n1. Read all the reflection entries (sections starting with \"## Reflection\")\n2. Extract the most important, durable behavioral patterns and lessons learned\n3. Consolidate them into concise, standalone statements (aim for 10-25 key patterns)\n4. Remove redundancy — if multiple reflections say the same thing, merge into one clear statement\n5. Prioritize patterns that are actionable and recurring over one-off observations\n6. Write a brief summary paragraph\n\nThe goal is to reduce a bloated file to a compact, high-signal set of learned patterns while preserving all genuinely useful self-knowledge.\n\nRespond with valid JSON matching this schema:\n{\n \"learnedPatterns\": [\"pattern 1\", \"pattern 2\", \"pattern 3\"],\n \"summary\": \"brief summary of consolidation\"\n}`;\n\n const response = await this.client.chat.completions.create({\n model: this.config.model,\n messages: [\n { role: \"system\", content: instructionText },\n { role: \"user\", content: fullIdentityContent },\n ],\n ...(this.config.reasoningEffort !== \"none\" ? { reasoning_effort: this.config.reasoningEffort } : {}),\n ...buildChatCompletionTokenLimit(this.config.model, 4096, {\n assumeOpenAI: this.directClientUsesOpenAiTokenSemantics(),\n }),\n });\n\n const rawContent = response.choices?.[0]?.message?.content?.trim();\n const iDurationMs = Date.now() - iStartTime;\n const iUsage = (response as any).usage;\n\n let parsed: any = null;\n if (rawContent) {\n for (const candidate of extractJsonCandidates(rawContent)) {\n try {\n parsed = JSON.parse(candidate);\n break;\n } catch {\n // keep trying candidates\n }\n }\n }\n\n this.emit({\n kind: \"llm_end\", traceId: iTraceId, model: this.config.model, operation: \"identity_consolidation\", durationMs: iDurationMs,\n output: parsed ? parsed.summary : undefined,\n tokenUsage: iUsage ? { input: iUsage.prompt_tokens, output: iUsage.completion_tokens, total: iUsage.total_tokens } : undefined,\n });\n\n if (parsed && Array.isArray(parsed.learnedPatterns)) {\n const learnedPatterns = parsed.learnedPatterns\n .filter((pattern: unknown) => typeof pattern === \"string\")\n .map((pattern: string) => pattern.trim())\n .filter((pattern: string) => pattern.length > 0);\n log.debug(\n `identity consolidation: ${learnedPatterns.length} patterns`,\n );\n return {\n learnedPatterns,\n summary: String(parsed.summary || \"\"),\n };\n }\n\n log.warn(\"identity consolidation returned no parsed output\");\n return null;\n } catch (err) {\n this.emit({\n kind: \"llm_error\", traceId: iTraceId, model: this.config.model, operation: \"identity_consolidation\",\n durationMs: Date.now() - iStartTime, error: String(err),\n });\n log.error(\"identity consolidation failed\", err);\n return null;\n }\n }\n\n /**\n * Consolidate identity using local LLM.\n */\n private async consolidateIdentityWithLocalLlm(\n fullIdentityContent: string,\n ): Promise<{ learnedPatterns: string[]; summary: string } | null> {\n // Get dynamic context sizes\n const contextSizes = this.modelRegistry.calculateContextSizes(\n this.config.localLlmModel,\n this.config.localLlmMaxContext\n );\n log.debug(`Identity consolidation model context: ${contextSizes.description}`);\n\n const prompt = `You are an identity consolidation system. You are given the full contents of an IDENTITY.md file that contains many individual reflection entries. Your job is to:\n\n1. Read all the reflection entries (sections starting with \"## Reflection\")\n2. Extract the most important, durable behavioral patterns and lessons learned\n3. Consolidate them into concise, standalone statements (aim for 10-25 key patterns)\n4. Remove redundancy — if multiple reflections say the same thing, merge into one clear statement\n5. Prioritize patterns that are actionable and recurring over one-off observations\n6. Write a brief summary paragraph\n\nThe goal is to reduce a bloated file to a compact, high-signal set of learned patterns while preserving all genuinely useful self-knowledge.\n\nIDENTITY.md content:\n${fullIdentityContent}\n\nRespond with valid JSON matching this schema:\n{\n \"learnedPatterns\": [\"pattern 1\", \"pattern 2\", \"pattern 3\"],\n \"summary\": \"brief summary of consolidation\"\n}`;\n\n const response = await this.localLlm.chatCompletion(\n [\n { role: \"system\", content: \"You are an identity consolidation system. Output valid JSON only.\" },\n { role: \"user\", content: prompt },\n ],\n {\n temperature: 0.3,\n maxTokens: contextSizes.maxOutputTokens,\n operation: \"identity_consolidation\",\n priority: \"background\",\n },\n );\n\n if (!response?.content) {\n return null;\n }\n\n try {\n const content = response.content.trim();\n for (const candidate of extractJsonCandidates(content)) {\n try {\n const parsed = JSON.parse(candidate);\n return {\n learnedPatterns: Array.isArray((parsed as any).learnedPatterns)\n ? (parsed as any).learnedPatterns\n : [],\n summary: String((parsed as any).summary || \"\"),\n };\n } catch {\n // keep trying candidates\n }\n }\n return null;\n } catch (err) {\n log.warn(\"local LLM identity consolidation: failed to parse JSON response:\", err);\n return null;\n }\n }\n\n /**\n * Verify if two memories contradict each other using LLM.\n * Called when QMD finds semantically similar memories (Phase 2B).\n */\n async verifyContradiction(\n newMemory: { content: string; category: string },\n existingMemory: { id: string; content: string; category: string; created: string },\n ): Promise<ContradictionVerificationResult | null> {\n const input = `Memory 1 (existing, created ${existingMemory.created}):\nCategory: ${existingMemory.category}\nContent: ${existingMemory.content}\n\nMemory 2 (new):\nCategory: ${newMemory.category}\nContent: ${newMemory.content}`;\n\n try {\n const instructionText = `You are a contradiction detection system. Analyze whether two memories contradict each other.\n\nIMPORTANT: Not all similar memories are contradictions!\n- \"User likes TypeScript\" and \"User likes Python\" are NOT contradictions (preferences can coexist)\n- \"User prefers dark mode\" and \"User prefers light mode\" ARE contradictions (mutually exclusive)\n- \"User's email is a@b.com\" and \"User's email is c@d.com\" ARE contradictions (only one email)\n- \"User works at Acme\" and \"User used to work at Acme\" might be a contradiction (temporal change)\n\nOnly mark as contradiction if the two statements CANNOT both be true at the same time.\n\nIf they ARE contradictory, determine which represents the more recent/current state based on:\n- Explicit time references (\"now\", \"currently\", \"used to\", \"no longer\")\n- The fact that newer corrections often start with \"actually\" or \"correction\"\n- Context clues about change over time\n\nRespond with valid JSON matching this schema:\n{\n \"isContradiction\": true,\n \"confidence\": 0.95,\n \"reasoning\": \"why they contradict or don't\",\n \"whichIsNewer\": \"first\"\n}`;\n\n if (this.shouldUseLocalLlm) {\n try {\n const localResponse = await this.localLlm.chatCompletion(\n [\n { role: \"system\", content: instructionText },\n { role: \"user\", content: input },\n ],\n {\n temperature: 0.3,\n maxTokens: 2048,\n operation: \"contradiction_verification\",\n priority: \"background\",\n },\n );\n const normalized = this.normalizeContradictionVerificationResult(\n this.parseJsonObject(localResponse?.content),\n );\n if (normalized) {\n log.debug(\n `contradiction check via local LLM: ${normalized.isContradiction ? \"YES\" : \"NO\"} (confidence: ${normalized.confidence})`,\n );\n return normalized;\n }\n if (!this.config.localLlmFallback) {\n log.warn(\"contradiction verification skipped — local LLM returned invalid JSON and cloud fallback is disabled\");\n return null;\n }\n } catch (err) {\n if (!this.config.localLlmFallback) {\n log.warn(`contradiction verification skipped — local LLM failed and cloud fallback is disabled: ${err}`);\n return null;\n }\n }\n }\n\n if (!this.shouldUseDirectClient) {\n const fallbackResponse = await this.fallbackLlm.chatCompletion(\n [\n { role: \"system\", content: instructionText },\n { role: \"user\", content: input },\n ],\n this.withGatewayAgent({ temperature: 0.3, maxTokens: 2048 }),\n );\n const normalized = this.normalizeContradictionVerificationResult(\n this.parseJsonObject(fallbackResponse?.content),\n );\n if (normalized) {\n log.debug(\n `contradiction check via fallback: ${normalized.isContradiction ? \"YES\" : \"NO\"} (confidence: ${normalized.confidence})`,\n );\n return normalized;\n }\n log.warn(\"contradiction verification skipped — no OpenAI API key and fallback unavailable\");\n return null;\n }\n\n const response = await this.client!.chat.completions.create({\n model: this.config.model,\n messages: [\n { role: \"system\", content: instructionText },\n { role: \"user\", content: input },\n ],\n ...buildChatCompletionTokenLimit(this.config.model, 2048, {\n assumeOpenAI: this.directClientUsesOpenAiTokenSemantics(),\n }),\n });\n\n const normalized = this.normalizeContradictionVerificationResult(\n this.parseJsonObject(response.choices?.[0]?.message?.content),\n );\n if (normalized) {\n log.debug(\n `contradiction check: ${normalized.isContradiction ? \"YES\" : \"NO\"} (confidence: ${normalized.confidence})`,\n );\n return normalized;\n }\n\n return null;\n } catch (err) {\n log.error(\"contradiction verification failed\", err);\n return null;\n }\n }\n async revalidateDependents(\n superseded: { id: string; content: string },\n replacement: { id: string; content: string } | null,\n dependents: Array<{ id: string; category: string; content: string }>,\n signal?: AbortSignal,\n ): Promise<{\n verdicts: Array<{\n memoryId: string;\n verdict: \"still_valid\" | \"invalidated\" | \"uncertain\";\n reason?: string;\n }>;\n }> {\n const complete: RevalidationFastChatCompletion = async (messages, options) => {\n try {\n const fast = await this.fastChatCompletion?.(messages, options);\n if (fast) return fast;\n } catch (error) {\n if (isAbortError(error) || options.signal?.aborted) throw error;\n log.warn(`dependency revalidation fast route failed: ${error}`);\n }\n if (this.shouldUseLocalLlm) {\n try {\n const local = await this.localLlm.chatCompletion(messages, options);\n if (local || !this.config.localLlmFallback) return local;\n } catch (error) {\n if (!this.config.localLlmFallback) throw error;\n }\n }\n if (!this.shouldUseDirectClient) {\n return this.fallbackLlm.chatCompletion(messages, this.withGatewayAgent(options));\n }\n const client = this.client;\n if (!client) return null;\n if (!shouldAssumeOpenAiChatCompletions(client.baseURL ?? this.config.openaiBaseUrl)) {\n const response = await client.chat.completions.create(\n {\n model: this.config.model,\n messages,\n max_tokens: options.maxTokens,\n },\n { signal: options.signal },\n );\n const content = response.choices[0]?.message?.content;\n return typeof content === \"string\" ? { content } : null;\n }\n const response = await client.responses.create({\n model: this.config.model,\n instructions: messages.find((message) => message.role === \"system\")?.content,\n input: messages.filter((message) => message.role !== \"system\").map((message) => message.content).join(\"\\n\\n\"),\n max_output_tokens: options.maxTokens,\n }, { signal: options.signal });\n return typeof response.output_text === \"string\" ? { content: response.output_text } : null;\n };\n return revalidateDependentsViaLlm(\n { fastChatCompletion: complete, parseJsonObject: this.parseJsonObject },\n superseded,\n replacement,\n dependents,\n { signal, timeoutMs: this.config.dependencyPropagation.timeoutMs },\n );\n }\n async suggestLinks(\n newMemory: { content: string; category: string },\n candidateMemories: Array<{ id: string; content: string; category: string }>,\n ): Promise<SuggestedLinks | null> {\n if (candidateMemories.length === 0) {\n return { links: [] };\n }\n\n const candidateList = candidateMemories\n .map((m, i) => `[${i + 1}] ID: ${m.id}\\nCategory: ${m.category}\\nContent: ${m.content}`)\n .join(\"\\n\\n\");\n\n const input = `New memory:\nCategory: ${newMemory.category}\nContent: ${newMemory.content}\n\nCandidate memories to link to:\n${candidateList}`;\n\n try {\n const instructionText = `You are a memory linking system. Analyze the new memory and suggest relationships to existing memories.\n\nLink types:\n- follows: This memory is a continuation or next step (e.g., decision follows discussion)\n- references: This memory mentions or refers to the other (e.g., fact references entity)\n- contradicts: This memory conflicts with the other (use sparingly, only for true contradictions)\n- supports: This memory provides evidence or reinforcement (e.g., example supports principle)\n- related: General topical relationship\n\nRules:\n- Only suggest links with strength > 0.5\n- Quality over quantity — 0-3 links is typical\n- Prefer specific link types over generic \"related\"\n- Consider entity references, topics, and causal relationships\n\nRespond with valid JSON matching this schema:\n{\n \"links\": [{\"targetId\": \"memory-id\", \"linkType\": \"follows|references|contradicts|supports|related\", \"strength\": 0.8, \"reason\": \"why\"}]\n}`;\n\n if (this.shouldUseLocalLlm) {\n try {\n const localResponse = await this.localLlm.chatCompletion(\n [\n { role: \"system\", content: instructionText },\n { role: \"user\", content: input },\n ],\n {\n temperature: 0.3,\n maxTokens: 2048,\n operation: \"link_suggestion\",\n priority: \"background\",\n },\n );\n const normalized = this.normalizeSuggestedLinksResult(this.parseJsonObject(localResponse?.content));\n if (normalized) {\n log.debug(`suggested ${normalized.links.length} links via local LLM`);\n return normalized;\n }\n if (!this.config.localLlmFallback) {\n log.warn(\"link suggestion skipped — local LLM returned invalid JSON and cloud fallback is disabled\");\n return null;\n }\n } catch (err) {\n if (!this.config.localLlmFallback) {\n log.warn(`link suggestion skipped — local LLM failed and cloud fallback is disabled: ${err}`);\n return null;\n }\n }\n }\n\n if (!this.shouldUseDirectClient) {\n const fallbackResponse = await this.fallbackLlm.chatCompletion(\n [\n { role: \"system\", content: instructionText },\n { role: \"user\", content: input },\n ],\n this.withGatewayAgent({ temperature: 0.3, maxTokens: 2048 }),\n );\n const normalized = this.normalizeSuggestedLinksResult(this.parseJsonObject(fallbackResponse?.content));\n if (normalized) {\n log.debug(`suggested ${normalized.links.length} links via fallback`);\n return normalized;\n }\n log.warn(\"link suggestion skipped — no OpenAI API key and fallback unavailable\");\n return null;\n }\n\n const response = await this.client!.chat.completions.create({\n model: this.config.model,\n messages: [\n { role: \"system\", content: instructionText },\n { role: \"user\", content: input },\n ],\n ...buildChatCompletionTokenLimit(this.config.model, 2048, {\n assumeOpenAI: this.directClientUsesOpenAiTokenSemantics(),\n }),\n });\n\n const normalized = this.normalizeSuggestedLinksResult(\n this.parseJsonObject(response.choices?.[0]?.message?.content),\n );\n if (normalized) {\n log.debug(`suggested ${normalized.links.length} links`);\n return normalized;\n }\n\n return null;\n } catch (err) {\n log.error(\"link suggestion failed\", err);\n return null;\n }\n }\n\n async generateDaySummary(memories: string | MemoryFile[]): Promise<DaySummaryResultShape | null> {\n if (!resolveRecallAuxiliaryCapabilities(this.config).daySummary) {\n log.warn(\"day summary skipped — disabled by config\");\n return null;\n }\n\n const memoryContext = formatDaySummaryMemories(memories);\n if (memoryContext.length === 0) return null;\n\n const instructionText = await loadDaySummaryPrompt();\n\n // Append extension footer when extensions are active (#382)\n let extensionsFooter = \"\";\n try {\n extensionsFooter = await buildExtensionsFooterForSummary(this.config);\n } catch {\n // Non-fatal: skip extension footer if discovery fails\n }\n\n const userPrompt = `Generate an end-of-day summary from this Remnic memory context:\n\n${memoryContext}${extensionsFooter.length > 0 ? `\\n\\n${extensionsFooter}` : \"\"}`;\n const traceId = crypto.randomUUID();\n const startedAt = Date.now();\n this.emit({ kind: \"llm_start\", traceId, model: this.config.model, operation: \"day_summary\", input: memoryContext.slice(0, 4000) });\n\n if (this.shouldUseLocalLlm) {\n try {\n const localResponse = await this.localLlm.chatCompletion(\n [\n { role: \"system\", content: `${instructionText}\n\nReturn valid JSON only.` },\n { role: \"user\", content: userPrompt },\n ],\n {\n temperature: 0.2,\n maxTokens: 2048,\n operation: \"day_summary\",\n priority: \"background\",\n },\n );\n const normalized = this.normalizeDaySummaryResult(this.parseJsonObject(localResponse?.content));\n if (normalized) {\n this.emit({ kind: \"llm_end\", traceId, model: this.config.localLlmModel, operation: \"day_summary\", durationMs: Date.now() - startedAt, output: JSON.stringify(normalized).slice(0, 2000) });\n log.debug(`generated day summary via local LLM (${normalized.bullets.length} bullets)`);\n return normalized;\n }\n if (!this.config.localLlmFallback) {\n this.emit({ kind: \"llm_error\", traceId, model: this.config.localLlmModel, operation: \"day_summary\", durationMs: Date.now() - startedAt, error: \"local LLM returned invalid JSON and fallback disabled\" });\n log.warn(\"day summary skipped — local LLM returned invalid JSON and fallback disabled\");\n return null;\n }\n } catch (err) {\n if (!this.config.localLlmFallback) {\n this.emit({ kind: \"llm_error\", traceId, model: this.config.localLlmModel, operation: \"day_summary\", durationMs: Date.now() - startedAt, error: String(err) });\n log.warn(`day summary skipped — local LLM failed and fallback disabled: ${err}`);\n return null;\n }\n }\n }\n\n const fallbackResult = await this.parseWithGatewayFallback(\n traceId,\n \"day_summary\",\n startedAt,\n DaySummaryResultSchema,\n [\n { role: \"system\", content: `${instructionText}\n\nReturn valid JSON only.` },\n { role: \"user\", content: userPrompt },\n ],\n { temperature: 0.2, maxTokens: 2048 },\n );\n if (fallbackResult) {\n const normalized = this.normalizeDaySummaryResult(fallbackResult);\n if (normalized) {\n log.debug(`generated day summary via fallback (${normalized.bullets.length} bullets)`);\n return normalized;\n }\n }\n\n // Direct Responses API fallback (AGENTS.md-compliant: never Chat Completions)\n if (this.shouldUseDirectClient) {\n try {\n const response = await (this.client as any).responses.create({\n model: this.config.model,\n instructions: `${instructionText}\\n\\nReturn valid JSON only.`,\n input: userPrompt,\n max_output_tokens: 2048,\n });\n const rawText = typeof response.output_text === \"string\" ? response.output_text : JSON.stringify(response.output_text ?? \"\");\n const normalized = this.normalizeDaySummaryResult(this.parseJsonObject(rawText));\n if (normalized) {\n this.emit({ kind: \"llm_end\", traceId, model: this.config.model, operation: \"day_summary\", durationMs: Date.now() - startedAt, output: JSON.stringify(normalized).slice(0, 2000) });\n log.debug(`generated day summary via Responses API (${normalized.bullets.length} bullets)`);\n return normalized;\n }\n this.emit({ kind: \"llm_error\", traceId, model: this.config.model, operation: \"day_summary\", durationMs: Date.now() - startedAt, error: \"Responses API returned unparseable output\" });\n } catch (err) {\n this.emit({ kind: \"llm_error\", traceId, model: this.config.model, operation: \"day_summary\", durationMs: Date.now() - startedAt, error: `Responses API failed: ${err}` });\n }\n }\n\n this.emit({ kind: \"llm_error\", traceId, model: this.config.model, operation: \"day_summary\", durationMs: Date.now() - startedAt, error: \"all generation paths exhausted (local LLM + gateway + Responses API)\" });\n log.warn(\"day summary skipped — all generation paths exhausted\");\n return null;\n }\n\n\n /**\n * Summarize a batch of old memories into a compact summary (Phase 4A).\n */\n async summarizeMemories(\n memories: Array<{ id: string; content: string; category: string; created: string }>,\n ): Promise<MemorySummaryResult | null> {\n if (memories.length === 0) return null;\n\n const memoryList = memories\n .map((m) => `[${m.id}] (${m.category}, ${m.created.slice(0, 10)})\\n${m.content}`)\n .join(\"\\n\\n\");\n\n try {\n const instructionText = `You are a memory summarization system. You are given a batch of old memories that need to be compressed into a summary.\n\nYour task:\n1. Write a concise summary paragraph (2-4 sentences) capturing the essence of these memories\n2. Extract the 5-10 most important facts that should be preserved\n3. List the key entities mentioned\n\nGuidelines:\n- Preserve specific, actionable information\n- Merge redundant details into single statements\n- Focus on durable insights, not transient details\n- Maintain any preferences, decisions, or corrections as key facts\n\nRespond with valid JSON matching this schema:\n{\n \"summaryText\": \"concise summary paragraph\",\n \"keyFacts\": [\"fact 1\", \"fact 2\"],\n \"keyEntities\": [\"entity-1\", \"entity-2\"]\n}`;\n\n if (this.shouldUseLocalLlm) {\n try {\n const localResponse = await this.localLlm.chatCompletion(\n [\n { role: \"system\", content: instructionText },\n { role: \"user\", content: `Summarize these ${memories.length} memories:\\n\\n${memoryList}` },\n ],\n {\n temperature: 0.3,\n maxTokens: 4096,\n operation: \"memory_summarization\",\n priority: \"background\",\n },\n );\n const normalized = this.normalizeMemorySummaryResult(this.parseJsonObject(localResponse?.content));\n if (normalized) {\n log.debug(\n `summarized ${memories.length} memories into ${normalized.keyFacts.length} key facts via local LLM`,\n );\n return normalized;\n }\n if (!this.config.localLlmFallback) {\n log.warn(\"summarization skipped — local LLM returned invalid JSON and cloud fallback is disabled\");\n return null;\n }\n } catch (err) {\n if (!this.config.localLlmFallback) {\n log.warn(`summarization skipped — local LLM failed and cloud fallback is disabled: ${err}`);\n return null;\n }\n }\n }\n\n if (!this.shouldUseDirectClient) {\n const fallbackResponse = await this.fallbackLlm.chatCompletion(\n [\n { role: \"system\", content: instructionText },\n { role: \"user\", content: `Summarize these ${memories.length} memories:\\n\\n${memoryList}` },\n ],\n this.withGatewayAgent({ temperature: 0.3, maxTokens: 4096 }),\n );\n const normalized = this.normalizeMemorySummaryResult(this.parseJsonObject(fallbackResponse?.content));\n if (normalized) {\n log.debug(`summarized ${memories.length} memories into ${normalized.keyFacts.length} key facts via fallback`);\n return normalized;\n }\n log.warn(\"summarization skipped — no OpenAI API key and fallback unavailable\");\n return null;\n }\n\n const response = await this.client!.chat.completions.create({\n model: this.config.model,\n messages: [\n { role: \"system\", content: instructionText },\n { role: \"user\", content: `Summarize these ${memories.length} memories:\\n\\n${memoryList}` },\n ],\n ...buildChatCompletionTokenLimit(this.config.model, 4096, {\n assumeOpenAI: this.directClientUsesOpenAiTokenSemantics(),\n }),\n });\n\n const normalized = this.normalizeMemorySummaryResult(\n this.parseJsonObject(response.choices?.[0]?.message?.content),\n );\n if (normalized) {\n log.debug(`summarized ${memories.length} memories into ${normalized.keyFacts.length} key facts`);\n return normalized;\n }\n\n return null;\n } catch (err) {\n log.error(\"memory summarization failed\", err);\n return null;\n }\n }\n}\n","/**\n * LLM revalidation of dependent memories after a support link breaks.\n *\n * Extracted from ExtractionEngine to keep extraction.ts under its ratchet\n * ceiling. The ExtractionEngine.revalidateDependents method delegates here.\n */\n\nexport interface RevalidationVerdict {\n memoryId: string;\n verdict: \"still_valid\" | \"invalidated\" | \"uncertain\";\n reason?: string;\n}\n\nexport type RevalidationFastChatCompletion = (\n messages: Array<{ role: \"system\" | \"user\" | \"assistant\"; content: string }>,\n options: {\n temperature?: number;\n maxTokens?: number;\n timeoutMs?: number;\n operation?: string;\n priority?: \"background\" | \"recall-critical\";\n signal?: AbortSignal;\n },\n) => Promise<{ content: string } | null>;\n\nexport interface RevalidationDeps {\n fastChatCompletion: RevalidationFastChatCompletion;\n parseJsonObject: (raw: string | null) => unknown;\n}\n\nfunction isPlainRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction buildPrompt(\n superseded: { id: string; content: string },\n replacement: { id: string; content: string } | null,\n dependents: Array<{ id: string; category: string; content: string }>,\n): { input: string; instructionText: string } {\n const dependentPrompt = dependents\n .map(\n (memory, index) =>\n `[${index + 1}] id: ${memory.id} | category: ${memory.category}\\n${memory.content}`,\n )\n .join(\"\\n\\n\");\n const input = `SUPERSEDED MEMORY (id: ${superseded.id}):\n${superseded.content}\n\nREPLACEMENT (id: ${replacement?.id ?? \"none\"}):\n${replacement?.content ?? \"none — the memory was removed without replacement\"}\n\nDEPENDENTS TO REVALIDATE (return exactly one verdict per id):\n${dependentPrompt}`;\n const instructionText = `You revalidate dependent memory claims after a supporting memory changes.\nFor each requested memory, decide whether its claim still holds.\nReturn valid JSON only:\n{\"verdicts\":[{\"memoryId\":\"id\",\"verdict\":\"still_valid|invalidated|uncertain\",\"reason\":\"brief reason\"}]}\nNever invent memory IDs. Use \"uncertain\" when the evidence is insufficient.`;\n return { input, instructionText };\n}\n\nfunction normalizeVerdicts(\n parsed: unknown,\n dependents: Array<{ id: string }>,\n): RevalidationVerdict[] {\n const raw: unknown[] = isPlainRecord(parsed) && Array.isArray(parsed.verdicts) ? parsed.verdicts : [];\n const requested = new Set(dependents.map((memory) => memory.id));\n const seen = new Set<string>();\n const normalized: RevalidationVerdict[] = [];\n for (const candidate of raw) {\n if (!isPlainRecord(candidate)) continue;\n const memoryId = typeof candidate.memoryId === \"string\" ? candidate.memoryId.trim() : \"\";\n if (!requested.has(memoryId) || seen.has(memoryId)) continue;\n seen.add(memoryId);\n const verdict =\n candidate.verdict === \"still_valid\" ||\n candidate.verdict === \"invalidated\" ||\n candidate.verdict === \"uncertain\"\n ? candidate.verdict\n : \"uncertain\";\n normalized.push({\n memoryId,\n verdict,\n ...(typeof candidate.reason === \"string\" ? { reason: candidate.reason } : {}),\n });\n }\n return dependents.map((memory) => {\n const verdict = normalized.find((candidate) => candidate.memoryId === memory.id);\n return verdict ?? { memoryId: memory.id, verdict: \"uncertain\" as const };\n });\n}\n\nexport async function revalidateDependentsViaLlm(\n deps: RevalidationDeps,\n superseded: { id: string; content: string },\n replacement: { id: string; content: string } | null,\n dependents: Array<{ id: string; category: string; content: string }>,\n options: { signal?: AbortSignal; timeoutMs?: number } = {},\n): Promise<{ verdicts: RevalidationVerdict[] }> {\n const { input, instructionText } = buildPrompt(superseded, replacement, dependents);\n const maxTokens = Math.max(1024, dependents.length * 256);\n const response = await deps.fastChatCompletion(\n [\n { role: \"system\", content: instructionText },\n { role: \"user\", content: input },\n ],\n {\n temperature: 0.2,\n maxTokens,\n operation: \"dependency_revalidation\",\n priority: \"background\",\n timeoutMs: options.timeoutMs,\n signal: options.signal,\n },\n );\n const rawContent = response?.content ?? null;\n if (!rawContent?.trim()) {\n throw new Error(\"fast completion returned no dependency revalidation output\");\n }\n\n return { verdicts: normalizeVerdicts(deps.parseJsonObject(rawContent), dependents) };\n}\n"],"mappings":"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","names":["isPlainRecord","normalized","response"]}
|