@remnic/core 9.45.3 → 9.45.4
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/abort-error.d.ts +2 -1
- package/dist/abort-error.js +3 -1
- package/dist/access-admin-ops-surface.d.ts +14 -10
- package/dist/access-admin-ops-surface.js +84 -76
- package/dist/access-audit.js +2 -2
- package/dist/access-authorization-probe.d.ts +14 -10
- package/dist/access-authorization-probe.js +85 -77
- package/dist/access-boundary.d.ts +15 -11
- package/dist/access-boundary.js +84 -76
- package/dist/access-citation-namespace.js +2 -2
- package/dist/access-cli.js +193 -181
- package/dist/access-cli.js.map +1 -1
- package/dist/access-coding-context-resolution.d.ts +16 -0
- package/dist/access-coding-context-resolution.js +13 -0
- package/dist/access-coding-context-resolution.js.map +1 -0
- package/dist/access-extraction-force-flush.d.ts +14 -10
- package/dist/access-extraction-force-flush.js +84 -76
- package/dist/access-health-types.d.ts +2 -1
- package/dist/access-http-lcm-compaction.d.ts +16 -12
- package/dist/access-http-lcm-compaction.js +3 -3
- package/dist/access-http-lifecycle-flush.d.ts +14 -10
- package/dist/access-http-lifecycle-flush.js +2 -2
- package/dist/access-http-offline-stream.d.ts +123 -0
- package/dist/access-http-offline-stream.js +10 -0
- package/dist/access-http-offline-stream.js.map +1 -0
- package/dist/access-http-query.js +84 -76
- package/dist/access-http.d.ts +15 -10
- package/dist/access-http.js +105 -92
- package/dist/access-identity-continuity-surface.d.ts +9 -8
- package/dist/access-identity-continuity-surface.js +84 -76
- package/dist/access-lcm-surface.d.ts +14 -10
- package/dist/access-lcm-surface.js +84 -76
- package/dist/access-mcp-output-schemas.js +1 -1
- package/dist/access-mcp.d.ts +14 -10
- package/dist/access-mcp.js +95 -83
- package/dist/access-memory-search-fanout.d.ts +3 -2
- package/dist/{access-namespace-preflight-5yZ4g6F8.d.ts → access-namespace-preflight-CWUDwB4M.d.ts} +1 -1
- package/dist/access-namespace-preflight.d.ts +4 -3
- package/dist/access-namespace-preflight.js +84 -76
- package/dist/access-observe-helpers.d.ts +1 -0
- package/dist/access-observe-helpers.js +1 -1
- package/dist/access-observe-write-surface.d.ts +16 -10
- package/dist/access-observe-write-surface.js +84 -76
- package/dist/access-offline-manifest.d.ts +104 -0
- package/dist/access-offline-manifest.js +45 -0
- package/dist/access-offline-manifest.js.map +1 -0
- package/dist/access-operations-batch.js +86 -78
- package/dist/access-operations.d.ts +15 -11
- package/dist/access-operations.js +91 -80
- package/dist/access-recall-concurrency.d.ts +16 -26
- package/dist/access-recall-concurrency.js +86 -77
- package/dist/access-recall-response.d.ts +18 -14
- package/dist/access-recall-response.js +84 -76
- package/dist/access-recall-surface.d.ts +29 -24
- package/dist/access-recall-surface.js +84 -76
- package/dist/access-schema.js +3 -3
- package/dist/{access-service-CiJRsgAB.d.ts → access-service-CsU-ljFD.d.ts} +25 -16
- package/dist/access-service-helpers.d.ts +14 -10
- package/dist/access-service.d.ts +14 -10
- package/dist/access-service.js +84 -76
- package/dist/access-surface-catalog.d.ts +14 -10
- package/dist/access-surface-catalog.js +4 -0
- package/dist/access-surface-catalog.js.map +1 -1
- package/dist/access-wearables-meetings-surface.d.ts +4 -3
- package/dist/action-confidence.d.ts +2 -1
- package/dist/active-memory-bridge.d.ts +2 -1
- package/dist/active-recall.d.ts +2 -1
- package/dist/active-recall.js +10 -8
- package/dist/active-recall.js.map +1 -1
- package/dist/adapters/index.js +7 -7
- package/dist/adapters/registry.js +3 -3
- package/dist/{auto-sync-5OE5QOZB.js → auto-sync-UPTUVE4X.js} +6 -6
- package/dist/behavior-learner.d.ts +2 -1
- package/dist/behavior-learner.js +1 -1
- package/dist/behavior-signals.d.ts +2 -1
- package/dist/bootstrap.d.ts +9 -8
- package/dist/briefing.d.ts +3 -2
- package/dist/briefing.js +23 -22
- package/dist/buffer-surprise-report.d.ts +2 -1
- package/dist/buffer-turn-helpers.d.ts +2 -1
- package/dist/buffer.d.ts +3 -2
- package/dist/buffer.js +12 -11
- package/dist/bulk-import/index.d.ts +4 -3
- package/dist/calibration.d.ts +2 -1
- package/dist/capabilities.d.ts +2 -1
- package/dist/{capsule-merge-IDWJPCWK.js → capsule-merge-Q6AR3XL7.js} +67 -54
- package/dist/capsule-merge-Q6AR3XL7.js.map +1 -0
- package/dist/{catalog-scBmy0sO.d.ts → catalog-bctMURhN.d.ts} +1 -1
- package/dist/causal-behavior.d.ts +2 -1
- package/dist/causal-behavior.js +2 -2
- package/dist/causal-chain.js +2 -2
- package/dist/causal-consolidation.d.ts +2 -1
- package/dist/causal-consolidation.js +27 -26
- package/dist/causal-consolidation.js.map +1 -1
- package/dist/causal-retrieval.js +2 -2
- package/dist/causal-trajectory-graph.d.ts +2 -1
- package/dist/causal-trajectory.js +1 -1
- package/dist/{chunk-VUPTKTDV.js → chunk-2MRHJNWL.js} +3 -3
- package/dist/{chunk-JBPKEARU.js → chunk-2QSZNTDO.js} +7 -7
- package/dist/{chunk-5IVLTFOV.js → chunk-44N6ESJ4.js} +2 -2
- package/dist/{chunk-WOCNN776.js → chunk-4POAMKV6.js} +100 -41
- package/dist/chunk-4POAMKV6.js.map +1 -0
- package/dist/{chunk-HO3QBJEY.js → chunk-5546W5SI.js} +2 -2
- package/dist/{chunk-U7GW7NE7.js → chunk-5CEECY6P.js} +10 -10
- package/dist/{chunk-4UH4BTGK.js → chunk-5SNZSWWR.js} +82 -82
- package/dist/{chunk-6CZPDBJS.js → chunk-5U7ID3EZ.js} +3 -3
- package/dist/{chunk-GF22HWS2.js → chunk-6NNNURLK.js} +7 -7
- package/dist/chunk-773TRRGT.js +36 -0
- package/dist/chunk-773TRRGT.js.map +1 -0
- package/dist/chunk-7CITSYSH.js +242 -0
- package/dist/chunk-7CITSYSH.js.map +1 -0
- package/dist/{chunk-227UFSEQ.js → chunk-7RZJWZ46.js} +5 -5
- package/dist/{chunk-E5UK4VPE.js → chunk-7SHJHPTY.js} +5 -5
- package/dist/{chunk-UVIKWC7M.js → chunk-7YERSTN7.js} +17 -17
- package/dist/{chunk-DLVPUX7U.js → chunk-7YKVM5H3.js} +8 -6
- package/dist/chunk-7YKVM5H3.js.map +1 -0
- package/dist/{chunk-3CE77VAP.js → chunk-A4JMGKCD.js} +87 -74
- package/dist/chunk-A4JMGKCD.js.map +1 -0
- package/dist/chunk-A5KNZSNA.js +26 -0
- package/dist/chunk-A5KNZSNA.js.map +1 -0
- package/dist/{chunk-S2NCTZGJ.js → chunk-AJQ57VV3.js} +15 -15
- package/dist/chunk-AJQ57VV3.js.map +1 -0
- package/dist/{chunk-CUM2BBPN.js → chunk-AUMWZSE7.js} +19 -10
- package/dist/chunk-AUMWZSE7.js.map +1 -0
- package/dist/{chunk-XYTOI63Z.js → chunk-BGHFOD5A.js} +19 -11
- package/dist/chunk-BGHFOD5A.js.map +1 -0
- package/dist/{chunk-BUE5E2HL.js → chunk-BGLY7EEM.js} +5 -314
- package/dist/chunk-BGLY7EEM.js.map +1 -0
- package/dist/chunk-BIPBQQFI.js +44 -0
- package/dist/chunk-BIPBQQFI.js.map +1 -0
- package/dist/{chunk-S5SLVSVY.js → chunk-BQIFZ2MP.js} +5 -5
- package/dist/chunk-BTTPKDIL.js +34 -0
- package/dist/{chunk-PVGDJXVK.js.map → chunk-BTTPKDIL.js.map} +1 -1
- package/dist/{chunk-E53DSZEN.js → chunk-C26TE27X.js} +3 -3
- package/dist/{chunk-LZ4LDKHZ.js → chunk-CLB32OHM.js} +6 -6
- package/dist/{chunk-Q6IP2ARR.js → chunk-CSOYVTRX.js} +2 -2
- package/dist/{chunk-XOQSEF7X.js → chunk-CVILPI77.js} +6 -6
- package/dist/chunk-D3I2MCN7.js +29 -0
- package/dist/chunk-D3I2MCN7.js.map +1 -0
- package/dist/{chunk-A5OJCXZL.js → chunk-DSUAAZZX.js} +15 -4
- package/dist/chunk-DSUAAZZX.js.map +1 -0
- package/dist/{chunk-HREE4JHI.js → chunk-DYVMXPCF.js} +486 -287
- package/dist/chunk-DYVMXPCF.js.map +1 -0
- package/dist/{chunk-J7VGGECD.js → chunk-DZPFMQZ7.js} +1 -1
- package/dist/chunk-DZPFMQZ7.js.map +1 -0
- package/dist/{chunk-PDLBLTOK.js → chunk-EITZHSX6.js} +9 -9
- package/dist/{chunk-D3J5SLQK.js → chunk-EJHEWCGQ.js} +81 -20
- package/dist/chunk-EJHEWCGQ.js.map +1 -0
- package/dist/{chunk-WUNIWKY4.js → chunk-ELIL2A37.js} +6 -6
- package/dist/{chunk-E6PNLPGJ.js → chunk-FZP32336.js} +806 -470
- package/dist/chunk-FZP32336.js.map +1 -0
- package/dist/{chunk-HZFHQ4AQ.js → chunk-G7A5HLUS.js} +23 -17
- package/dist/chunk-G7A5HLUS.js.map +1 -0
- package/dist/{chunk-CINZGPSJ.js → chunk-GUMZC2BO.js} +2 -2
- package/dist/{chunk-H24WNPA2.js → chunk-GWFSVJ4P.js} +3 -3
- package/dist/{chunk-7XC2HX75.js → chunk-GYPQL6XN.js} +157 -16
- package/dist/chunk-GYPQL6XN.js.map +1 -0
- package/dist/{chunk-TSH56VPU.js → chunk-HAYSYUAB.js} +2 -2
- package/dist/{chunk-TDHTVMPG.js → chunk-HFPASSFV.js} +7 -2
- package/dist/chunk-HFPASSFV.js.map +1 -0
- package/dist/chunk-J2WC5LF4.js +395 -0
- package/dist/chunk-J2WC5LF4.js.map +1 -0
- package/dist/{chunk-PKNLM44P.js → chunk-JH6BPLOP.js} +9 -9
- package/dist/{chunk-KXB4VXHY.js → chunk-JIYDRBVZ.js} +2 -2
- package/dist/chunk-JV3C2MNQ.js +74 -0
- package/dist/chunk-JV3C2MNQ.js.map +1 -0
- package/dist/{chunk-AV5ZEH4M.js → chunk-KVJRXN2E.js} +2 -2
- package/dist/{chunk-JVLCVFQ4.js → chunk-KXEFRMCF.js} +3 -3
- package/dist/{chunk-WFTIGIIS.js → chunk-L6CQ7WIW.js} +5 -5
- package/dist/{chunk-EJUEXZHX.js → chunk-LLJMAULE.js} +2 -2
- package/dist/{chunk-N5Z4EVOR.js → chunk-LNEWDF2A.js} +36 -11
- package/dist/chunk-LNEWDF2A.js.map +1 -0
- package/dist/{chunk-AS7YMSL6.js → chunk-M23RF3LJ.js} +4 -4
- package/dist/{chunk-UYLMNVY6.js → chunk-MDISBSYA.js} +16 -9
- package/dist/chunk-MDISBSYA.js.map +1 -0
- package/dist/{chunk-3F2LKUMU.js → chunk-NIS256NW.js} +2 -2
- package/dist/{chunk-YIAA2X3D.js → chunk-NK5RGJ65.js} +3 -3
- package/dist/chunk-NLDVVWCL.js +84 -0
- package/dist/chunk-NLDVVWCL.js.map +1 -0
- package/dist/{chunk-OQ5PRDDS.js → chunk-NTOIP2E6.js} +6 -6
- package/dist/{chunk-HLPD7B7P.js → chunk-NUEQKLNB.js} +2 -2
- package/dist/{chunk-4J7G5SY4.js → chunk-NZBZ7IS2.js} +72 -24
- package/dist/chunk-NZBZ7IS2.js.map +1 -0
- package/dist/{chunk-3TBLDMJA.js → chunk-O4KMGRXE.js} +5 -2
- package/dist/chunk-O4KMGRXE.js.map +1 -0
- package/dist/{chunk-33PLLLL7.js → chunk-P7NGM24P.js} +6 -6
- package/dist/{chunk-7TWUCYER.js → chunk-PNRA7FAD.js} +7 -7
- package/dist/{chunk-5I4M26Q7.js → chunk-QBSFOKY6.js} +4 -4
- package/dist/{chunk-QJAQNXWI.js → chunk-QCECHYZL.js} +76 -79
- package/dist/chunk-QCECHYZL.js.map +1 -0
- package/dist/{chunk-P4DRWEYC.js → chunk-QVSBTCVP.js} +2 -2
- package/dist/{chunk-AAIUERNB.js → chunk-R5RFK3CB.js} +6 -6
- package/dist/{chunk-WDISJRMG.js → chunk-RMMVQQA6.js} +2 -2
- package/dist/{chunk-KWMXR7XS.js → chunk-S2V7RUCL.js} +8 -1
- package/dist/{chunk-KWMXR7XS.js.map → chunk-S2V7RUCL.js.map} +1 -1
- package/dist/{chunk-5SM35XZR.js → chunk-S5NZBKKQ.js} +2 -2
- package/dist/{chunk-VNA7W7QF.js → chunk-SVH57F5Z.js} +12 -4
- package/dist/chunk-SVH57F5Z.js.map +1 -0
- package/dist/{chunk-WIPEXG6R.js → chunk-SXIMQLGV.js} +2 -2
- package/dist/{chunk-RVLJEII5.js → chunk-SYUBB3WM.js} +256 -187
- package/dist/chunk-SYUBB3WM.js.map +1 -0
- package/dist/{chunk-OAEQLRCY.js → chunk-TN76AKO3.js} +5 -5
- package/dist/{chunk-QN25OCUF.js → chunk-TQ4GD737.js} +5 -5
- package/dist/{chunk-VCD4PSK2.js → chunk-TQZ4DVBC.js} +7 -4
- package/dist/chunk-TQZ4DVBC.js.map +1 -0
- package/dist/{chunk-7K5Q6COX.js → chunk-TVVEYCNW.js} +4 -4
- package/dist/{chunk-DNWXFTLD.js → chunk-TYISDI6B.js} +2 -2
- package/dist/{chunk-4LMA77JH.js → chunk-U2VLVBBH.js} +3 -3
- package/dist/{chunk-5ZE7QHTK.js → chunk-ULVR5KG7.js} +5 -5
- package/dist/{chunk-NVRYW264.js → chunk-UQWIKLQK.js} +18 -15
- package/dist/chunk-UQWIKLQK.js.map +1 -0
- package/dist/{chunk-YV32N67O.js → chunk-URS5GSM7.js} +1 -1
- package/dist/chunk-URS5GSM7.js.map +1 -0
- package/dist/{chunk-4B77XSG5.js → chunk-UV72DEZD.js} +5 -5
- package/dist/{chunk-S2BBISHU.js → chunk-VANZKHTN.js} +3 -3
- package/dist/chunk-VHFXP27N.js +250 -0
- package/dist/chunk-VHFXP27N.js.map +1 -0
- package/dist/{chunk-3Y224NYC.js → chunk-VYISFWVX.js} +2 -2
- package/dist/{chunk-TIHMZFIV.js → chunk-W3IC7QOY.js} +3 -3
- package/dist/{chunk-NRV4Y3PM.js → chunk-W4FBGYGK.js} +1 -1
- package/dist/{chunk-P2BM76KT.js → chunk-WAS4HV46.js} +174 -43
- package/dist/chunk-WAS4HV46.js.map +1 -0
- package/dist/{chunk-57QKLRBV.js → chunk-WB7JSQCP.js} +2 -1
- package/dist/chunk-WB7JSQCP.js.map +1 -0
- package/dist/chunk-WGP57SR3.js +68 -0
- package/dist/chunk-WGP57SR3.js.map +1 -0
- package/dist/{chunk-ECK75GDJ.js → chunk-WQIHRA5F.js} +43 -24
- package/dist/chunk-WQIHRA5F.js.map +1 -0
- package/dist/{chunk-MU7ZHSZE.js → chunk-WZFAPHIK.js} +2 -2
- package/dist/{chunk-T2TTP3KU.js → chunk-X4IDNPOS.js} +2 -2
- package/dist/{chunk-BLAKS3CP.js → chunk-XL3TATMJ.js} +3 -3
- package/dist/{chunk-W4XJFLAL.js → chunk-XPRJSHNI.js} +2 -2
- package/dist/{chunk-5TFP4CUL.js → chunk-XQ3HXAQH.js} +14 -11
- package/dist/chunk-XQ3HXAQH.js.map +1 -0
- package/dist/{chunk-VWAXN2BN.js → chunk-XSFHWBQO.js} +93 -31
- package/dist/chunk-XSFHWBQO.js.map +1 -0
- package/dist/{chunk-DL7ZD3JH.js → chunk-XTAUXTDO.js} +14 -9
- package/dist/chunk-XTAUXTDO.js.map +1 -0
- package/dist/{chunk-JE7EK33X.js → chunk-Y7HRYCNW.js} +2 -2
- package/dist/{chunk-E6EE5B67.js → chunk-YK6BDDHP.js} +4 -4
- package/dist/{chunk-ES36HTSC.js → chunk-YLHM5BQQ.js} +3 -3
- package/dist/{chunk-RN7DY3FC.js → chunk-YMAQDHQM.js} +31 -12
- package/dist/chunk-YMAQDHQM.js.map +1 -0
- package/dist/{chunk-ULARSG5Z.js → chunk-YN6ASZUG.js} +10 -8
- package/dist/{chunk-ULARSG5Z.js.map → chunk-YN6ASZUG.js.map} +1 -1
- package/dist/{chunk-IKKWIPYN.js → chunk-YYQAKIDJ.js} +37 -1
- package/dist/chunk-YYQAKIDJ.js.map +1 -0
- package/dist/{chunk-BJKPPZ6Z.js → chunk-ZFGZ6PZ2.js} +2 -2
- package/dist/{chunk-CJ2ZR7UA.js → chunk-ZI32MKDW.js} +267 -214
- package/dist/chunk-ZI32MKDW.js.map +1 -0
- package/dist/{chunk-64UDOIMI.js → chunk-ZLQ37WJX.js} +2 -2
- package/dist/chunk-ZMAYKGPN.js +351 -0
- package/dist/chunk-ZMAYKGPN.js.map +1 -0
- package/dist/{cli-BUGN3d6_.d.ts → cli-BBHDtG36.d.ts} +5 -5
- package/dist/cli.d.ts +16 -12
- package/dist/cli.js +138 -124
- package/dist/compounding/engine.d.ts +3 -2
- package/dist/compounding/engine.js +24 -23
- package/dist/compounding/preference-consolidator.d.ts +2 -1
- package/dist/compression-optimizer.d.ts +2 -1
- package/dist/config.d.ts +2 -1
- package/dist/config.js +10 -8
- package/dist/connectors/codex-materialize-runner.d.ts +2 -1
- package/dist/connectors/codex-materialize-runner.js +23 -22
- package/dist/connectors/codex-materialize.d.ts +2 -1
- package/dist/connectors/index.d.ts +2 -1
- package/dist/connectors/index.js +26 -25
- package/dist/consolidation-provenance-check.d.ts +3 -2
- package/dist/consolidation-provenance-check.js +4 -4
- package/dist/consolidation-undo.d.ts +3 -2
- package/dist/consolidation-undo.js +10 -7
- package/dist/consolidation-undo.js.map +1 -1
- package/dist/contradiction/index.d.ts +3 -2
- package/dist/converge-config.d.ts +2 -1
- package/dist/convergence-refresh.d.ts +4 -3
- package/dist/convergence-refresh.js +27 -26
- package/dist/conversation-index/backend.d.ts +2 -1
- package/dist/conversation-index/backend.js +2 -2
- package/dist/conversation-index/chunker.d.ts +2 -1
- package/dist/conversation-index/faiss-adapter.d.ts +2 -1
- package/dist/conversation-index/indexer.d.ts +2 -1
- package/dist/conversation-index/search.d.ts +2 -1
- package/dist/corpus-watermark.d.ts +2 -1
- package/dist/corpus-watermark.js +42 -41
- package/dist/day-summary.d.ts +2 -1
- package/dist/delinearize.d.ts +2 -1
- package/dist/direct-answer-wiring.d.ts +2 -1
- package/dist/direct-answer-wiring.js +2 -2
- package/dist/direct-answer.d.ts +2 -1
- package/dist/embedding-fallback.d.ts +2 -1
- package/dist/embedding-fallback.js +2 -2
- package/dist/enrichment/index.d.ts +2 -1
- package/dist/entity-retrieval-boundaries.js +1 -1
- package/dist/entity-retrieval.d.ts +3 -2
- package/dist/entity-retrieval.js +24 -23
- package/dist/entity-schema.d.ts +2 -1
- package/dist/explicit-capture.d.ts +9 -8
- package/dist/explicit-capture.js +11 -9
- package/dist/external-wiki-access.d.ts +127 -0
- package/dist/external-wiki-access.js +186 -0
- package/dist/external-wiki-access.js.map +1 -0
- package/dist/external-wiki-cli.d.ts +13 -0
- package/dist/external-wiki-cli.js +96 -0
- package/dist/external-wiki-cli.js.map +1 -0
- package/dist/external-wiki-collection-registration.d.ts +39 -0
- package/dist/external-wiki-collection-registration.js +79 -0
- package/dist/external-wiki-collection-registration.js.map +1 -0
- package/dist/external-wiki-collection.d.ts +50 -0
- package/dist/external-wiki-collection.js +387 -0
- package/dist/external-wiki-collection.js.map +1 -0
- package/dist/external-wiki-config.d.ts +13 -0
- package/dist/external-wiki-config.js +13 -0
- package/dist/external-wiki-config.js.map +1 -0
- package/dist/external-wiki-guard.d.ts +11 -0
- package/dist/external-wiki-guard.js +18 -0
- package/dist/external-wiki-guard.js.map +1 -0
- package/dist/external-wiki-mcp-tools.d.ts +123 -0
- package/dist/external-wiki-mcp-tools.js +8 -0
- package/dist/external-wiki-mcp-tools.js.map +1 -0
- package/dist/external-wiki-search.d.ts +42 -0
- package/dist/external-wiki-search.js +11 -0
- package/dist/external-wiki-search.js.map +1 -0
- package/dist/external-wiki.d.ts +43 -0
- package/dist/external-wiki.js +16 -0
- package/dist/external-wiki.js.map +1 -0
- package/dist/extraction-error-classification.d.ts +2 -1
- package/dist/extraction-faithfulness.d.ts +2 -1
- package/dist/extraction-judge-telemetry.d.ts +2 -1
- package/dist/extraction-judge-training.d.ts +2 -1
- package/dist/extraction-judge.d.ts +2 -1
- package/dist/extraction-liveness.d.ts +2 -1
- package/dist/extraction-source-grounding-helpers.d.ts +5 -3
- package/dist/extraction-source-grounding-helpers.js +1 -1
- package/dist/extraction-source-grounding-rules.d.ts +2 -1
- package/dist/extraction-source-grounding-rules.js +2 -2
- package/dist/extraction-source-grounding.d.ts +2 -1
- package/dist/extraction-source-grounding.js +5 -5
- package/dist/extraction.d.ts +2 -1
- package/dist/extraction.js +45 -43
- package/dist/fallback-llm.d.ts +2 -1
- package/dist/graph-dashboard-diff.d.ts +2 -1
- package/dist/graph-dashboard-key.d.ts +2 -1
- package/dist/graph-dashboard-parser.d.ts +2 -1
- package/dist/graph-edge-reinforcement.d.ts +2 -1
- package/dist/graph-snapshot.d.ts +2 -1
- package/dist/graph.d.ts +2 -1
- package/dist/harmonic-retrieval.js +2 -2
- package/dist/importance.d.ts +2 -1
- package/dist/importers/index.d.ts +2 -1
- package/dist/in-flight-reads.d.ts +2 -1
- package/dist/index.d.ts +362 -350
- package/dist/index.js +291 -259
- package/dist/intent.d.ts +2 -1
- package/dist/lcm/engine.d.ts +2 -1
- package/dist/lcm/engine.js +3 -3
- package/dist/lcm/index.d.ts +2 -1
- package/dist/lcm/index.js +8 -8
- package/dist/lcm/tools.d.ts +2 -1
- package/dist/lifecycle.d.ts +2 -1
- package/dist/live-connectors-runner.d.ts +2 -1
- package/dist/local-llm.d.ts +2 -1
- package/dist/local-llm.js +2 -2
- package/dist/local-model-endpoint.d.ts +2 -1
- package/dist/maintenance/memory-governance.d.ts +2 -1
- package/dist/maintenance/memory-governance.js +24 -23
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +3 -2
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +24 -23
- package/dist/maintenance/rebuild-memory-projection.d.ts +3 -2
- package/dist/maintenance/rebuild-memory-projection.js +26 -25
- package/dist/{maintenance-LbuS2rUA.d.ts → maintenance-D2mveyCd.d.ts} +3 -3
- package/dist/mcp-memory-inspector-app.d.ts +14 -10
- package/dist/mcp-read-only-tools.js +1 -1
- package/dist/memory-action-policy.d.ts +2 -1
- package/dist/memory-cache.d.ts +2 -1
- package/dist/memory-lifecycle-ledger-utils.d.ts +2 -1
- package/dist/memory-projection-store.d.ts +2 -1
- package/dist/memory-provenance.d.ts +2 -1
- package/dist/memory-worth-outcomes.d.ts +3 -2
- package/dist/models-json.d.ts +2 -1
- package/dist/namespaces/migrate.d.ts +4 -3
- package/dist/namespaces/migrate.js +40 -39
- package/dist/namespaces/principal.d.ts +2 -1
- package/dist/namespaces/search.d.ts +2 -1
- package/dist/namespaces/search.js +18 -18
- package/dist/namespaces/storage.d.ts +4 -3
- package/dist/namespaces/storage.js +23 -22
- package/dist/native-knowledge.d.ts +2 -1
- package/dist/offline-sync-impression-drain.d.ts +2 -1
- package/dist/offline-sync-impression-drain.js +11 -9
- package/dist/offline-sync.d.ts +29 -3
- package/dist/offline-sync.js +6 -2
- package/dist/operator-doctor-corpus.d.ts +2 -1
- package/dist/operator-doctor-corpus.js +45 -44
- package/dist/operator-doctor-replica.d.ts +2 -1
- package/dist/operator-doctor-replica.js +3 -3
- package/dist/operator-toolkit.d.ts +4 -3
- package/dist/operator-toolkit.js +59 -55
- package/dist/orchestration/compression-guideline-coordinator.d.ts +3 -2
- package/dist/orchestration/maintenance.d.ts +5 -4
- package/dist/orchestration/maintenance.js +36 -33
- package/dist/{orchestrator-rHiWt32X.d.ts → orchestrator-DJYlwiUv.d.ts} +14 -7
- package/dist/orchestrator.d.ts +9 -8
- package/dist/orchestrator.js +201 -189
- package/dist/page-versioning.js +3 -3
- package/dist/patterns-cli.d.ts +2 -1
- package/dist/{pipeline-W_97O8BV.d.ts → pipeline-CNjY4wk3.d.ts} +1 -1
- package/dist/policy-runtime.d.ts +2 -1
- package/dist/policy-runtime.js +1 -1
- package/dist/proactive-contention.d.ts +2 -1
- package/dist/provenance.d.ts +2 -1
- package/dist/provenance.js +2 -2
- package/dist/{qmd-LWtMofAf.d.ts → qmd-C0UDZidt.d.ts} +9 -7
- package/dist/qmd-preflight.d.ts +5 -4
- package/dist/qmd-preflight.js +2 -2
- package/dist/qmd-recall-cache.d.ts +2 -1
- package/dist/qmd.d.ts +4 -3
- package/dist/qmd.js +5 -5
- package/dist/recall-concurrency-config.d.ts +2 -1
- package/dist/recall-disclosure-escalation.d.ts +2 -1
- package/dist/recall-explain-renderer.d.ts +2 -1
- package/dist/recall-explain-renderer.js +3 -3
- package/dist/recall-memory-map.d.ts +2 -1
- package/dist/recall-planner-llm.d.ts +2 -1
- package/dist/recall-state.d.ts +2 -1
- package/dist/recall-tag-filter.d.ts +2 -1
- package/dist/recall-timings.d.ts +2 -1
- package/dist/recall-xray-cli.d.ts +2 -1
- package/dist/recall-xray-cli.js +4 -4
- package/dist/recall-xray-renderer.d.ts +2 -1
- package/dist/recall-xray-renderer.js +3 -3
- package/dist/recall-xray.d.ts +8 -1
- package/dist/recall-xray.js +2 -2
- package/dist/reconcile/cursor.d.ts +12 -2
- package/dist/reconcile/cursor.js +46 -7
- package/dist/reconcile/cursor.js.map +1 -1
- package/dist/reconcile/manifest.d.ts +9 -2
- package/dist/reconcile/manifest.js +15 -268
- package/dist/reconcile/manifest.js.map +1 -1
- package/dist/reconcile/plan.d.ts +4 -1
- package/dist/reconcile/plan.js +4 -4
- package/dist/replay/normalizers/chatgpt.d.ts +2 -1
- package/dist/replay/normalizers/claude.d.ts +2 -1
- package/dist/replay/normalizers/openclaw.d.ts +2 -1
- package/dist/replay/normalizers/shared.d.ts +2 -1
- package/dist/replay/runner.d.ts +2 -1
- package/dist/replay/types.d.ts +2 -1
- package/dist/replica-divergence.d.ts +2 -1
- package/dist/replica-divergence.js +2 -2
- package/dist/replica-peers-config.d.ts +2 -1
- package/dist/resolve-auth-token.d.ts +2 -1
- package/dist/resume-bundles.js +12 -10
- package/dist/retrieval-agents.d.ts +4 -3
- package/dist/retrieval-agents.js +2 -2
- package/dist/retrieval-tiers.d.ts +2 -1
- package/dist/routing/engine.d.ts +2 -1
- package/dist/routing/store.d.ts +2 -1
- package/dist/salvage-envelope.d.ts +2 -1
- package/dist/schemas.d.ts +32 -32
- package/dist/{scope-profiles-BiQKOE-p.d.ts → scope-profiles-BJzp2F5A.d.ts} +1 -1
- package/dist/search/embed-helper.d.ts +2 -1
- package/dist/search/embed-helper.js +3 -3
- package/dist/search/factory.d.ts +4 -2
- package/dist/search/factory.js +20 -18
- package/dist/search/index.d.ts +2 -1
- package/dist/search/index.js +22 -22
- package/dist/search/lancedb-backend.d.ts +2 -1
- package/dist/search/lancedb-backend.js +4 -4
- package/dist/search/meilisearch-backend.d.ts +2 -1
- package/dist/search/meilisearch-backend.js +4 -4
- package/dist/search/noop-backend.d.ts +2 -1
- package/dist/search/orama-backend.d.ts +2 -1
- package/dist/search/orama-backend.js +4 -4
- package/dist/search/port.d.ts +18 -1
- package/dist/search/port.js +1 -1
- package/dist/search/remote-backend.d.ts +2 -1
- package/dist/search/remote-backend.js +2 -2
- package/dist/secure-store/index.js +2 -2
- package/dist/{semantic-consolidation-dHYCyqgh.d.ts → semantic-consolidation-D4KAZO2G.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +3 -2
- package/dist/semantic-consolidation.js +25 -24
- package/dist/semantic-rule-promotion.js +23 -22
- package/dist/semantic-rule-verifier.d.ts +2 -1
- package/dist/semantic-rule-verifier.js +24 -23
- package/dist/{service-DJG3KCQ4.d.ts → service-BeDxSqE-.d.ts} +2 -2
- package/dist/session-observer-bands.d.ts +2 -1
- package/dist/session-observer-state.d.ts +2 -1
- package/dist/shared-context/manager.d.ts +2 -1
- package/dist/shared-context/manager.js +2 -2
- package/dist/signal.d.ts +2 -1
- package/dist/source-agent-qualifier.d.ts +2 -1
- package/dist/source-agent-qualifier.js +42 -40
- package/dist/{storage-F9FVh-w9.d.ts → storage-DfjxusTE.d.ts} +24 -12
- package/dist/storage.d.ts +3 -2
- package/dist/storage.js +25 -24
- package/dist/summarizer.d.ts +2 -1
- package/dist/summarizer.js +5 -5
- package/dist/summary-snapshot.d.ts +2 -1
- package/dist/temporal-supersession.d.ts +3 -2
- package/dist/temporal-timeline-recall.d.ts +2 -1
- package/dist/temporal-validity.d.ts +2 -1
- package/dist/threading.d.ts +2 -1
- package/dist/tier-migration.d.ts +3 -2
- package/dist/tier-routing.d.ts +2 -1
- package/dist/tool-scoped-memory.d.ts +5 -1
- package/dist/tool-scoped-memory.js +3 -1
- package/dist/topics.d.ts +2 -1
- package/dist/transcript.d.ts +2 -1
- package/dist/transfer/capsule-import.js +4 -4
- package/dist/transfer/types.d.ts +12 -12
- package/dist/trust-score-stage.d.ts +2 -1
- package/dist/trust-score.d.ts +2 -1
- package/dist/{types-rEwubvim.d.ts → types-yX_FwERf.d.ts} +8 -1
- package/dist/types.d.ts +2 -1
- package/dist/types.js +1 -1
- package/dist/utility-runtime.d.ts +2 -1
- package/dist/verified-recall.js +24 -23
- package/dist/write-envelope.d.ts +2 -1
- package/package.json +2 -2
- package/src/abort-error.ts +17 -0
- package/src/access-admin-ops-surface.ts +1 -0
- package/src/access-boundary.ts +1 -0
- package/src/access-coding-context-resolution.ts +42 -0
- package/src/access-extraction-force-flush.ts +38 -2
- package/src/access-http-lcm-compaction.ts +5 -2
- package/src/access-http-offline-stream.ts +79 -0
- package/src/access-http.test.ts +310 -3
- package/src/access-http.ts +85 -21
- package/src/access-mcp-output-schemas.ts +36 -0
- package/src/access-mcp.test.ts +95 -1
- package/src/access-mcp.ts +7 -9
- package/src/access-observe-helpers.ts +64 -22
- package/src/access-observe-write-surface.ts +8 -0
- package/src/access-offline-manifest.ts +54 -0
- package/src/access-operations-batch.ts +3 -3
- package/src/access-operations.ts +13 -7
- package/src/access-recall-concurrency.ts +3 -27
- package/src/access-recall-surface.ts +3 -0
- package/src/access-service-health.test.ts +32 -7
- package/src/access-service-namespace.test.ts +55 -0
- package/src/access-service-observe-idempotency.test.ts +34 -2
- package/src/access-service-observe-lcm-parity.test.ts +138 -3
- package/src/access-service-observe-scope.test.ts +160 -1
- package/src/access-service-offline-file-content.test.ts +345 -1
- package/src/access-service.ts +86 -59
- package/src/access-surface-catalog.ts +4 -0
- package/src/admin/admin-surfaces.ts +2 -0
- package/src/binary-lifecycle/pipeline.test.ts +106 -1
- package/src/binary-lifecycle/pipeline.ts +3 -0
- package/src/coding/git-context.test.ts +47 -0
- package/src/coding/git-context.ts +129 -27
- package/src/config.test.ts +24 -0
- package/src/config.ts +9 -12
- package/src/connector-provenance.test.ts +101 -0
- package/src/consolidation-undo.ts +3 -0
- package/src/convergence-refresh.ts +14 -2
- package/src/correction/correction-access-wiring.ts +9 -7
- package/src/correction/correction-executor.test.ts +206 -2
- package/src/correction/correction-executor.ts +29 -20
- package/src/correction/correction-planner.test.ts +36 -0
- package/src/correction/correction-planner.ts +9 -15
- package/src/correction/correction-service.ts +3 -1
- package/src/correction/correction-storage-integration.test.ts +77 -0
- package/src/correction/correction-surfaces.test.ts +41 -28
- package/src/correction/passive-capture.test.ts +59 -0
- package/src/correction/passive-capture.ts +4 -1
- package/src/entity-retrieval-boundaries.ts +17 -4
- package/src/entity-retrieval.ts +27 -6
- package/src/external-wiki-access.test.ts +65 -0
- package/src/external-wiki-access.ts +31 -0
- package/src/external-wiki-cli.ts +92 -0
- package/src/external-wiki-collection-registration.test.ts +163 -0
- package/src/external-wiki-collection-registration.ts +101 -0
- package/src/external-wiki-collection.test.ts +502 -0
- package/src/external-wiki-collection.ts +503 -0
- package/src/external-wiki-config.test.ts +135 -0
- package/src/external-wiki-config.ts +100 -0
- package/src/external-wiki-guard.ts +83 -0
- package/src/external-wiki-mcp-tools.ts +23 -0
- package/src/external-wiki-search.test.ts +301 -0
- package/src/external-wiki-search.ts +362 -0
- package/src/external-wiki.test.ts +240 -0
- package/src/external-wiki.ts +453 -0
- package/src/extraction-scope-source-agent.test.ts +21 -0
- package/src/extraction-source-grounding-helpers.ts +243 -53
- package/src/extraction-source-grounding-rules.ts +133 -39
- package/src/extraction-source-grounding.test.ts +363 -33
- package/src/extraction-timeout.test.ts +1 -0
- package/src/extraction-watermark.test.ts +150 -7
- package/src/extraction.ts +8 -1
- package/src/index.ts +8 -0
- package/src/mcp-read-only-tools.ts +1 -0
- package/src/offline-sync.test.ts +194 -0
- package/src/offline-sync.ts +217 -13
- package/src/orchestration/external-wiki-recall-guard.test.ts +94 -0
- package/src/orchestration/extraction-persist.ts +19 -2
- package/src/orchestration/extraction-run-helpers.ts +37 -19
- package/src/orchestration/extraction-run.test.ts +171 -2
- package/src/orchestration/extraction-run.ts +11 -13
- package/src/orchestration/extraction-watermark.ts +106 -17
- package/src/orchestration/generic-recall-paths.ts +14 -0
- package/src/orchestration/orchestrator-helpers.ts +2 -0
- package/src/orchestration/orchestrator-init.ts +9 -0
- package/src/orchestration/recall-internal-deps.ts +6 -0
- package/src/orchestration/recall-internal.ts +154 -33
- package/src/orchestration/recall-rerank-coordinator.ts +60 -25
- package/src/orchestration/recall-search-pipeline.test.ts +75 -1
- package/src/orchestration/recall-search-pipeline.ts +50 -10
- package/src/orchestrator-convergence-refresh.test.ts +36 -2
- package/src/orchestrator.ts +13 -3
- package/src/page-versioning.ts +5 -19
- package/src/procedural/procedure-recall.ts +5 -1
- package/src/provenance-surfaces.test.ts +3 -0
- package/src/qmd-client.test.ts +78 -17
- package/src/qmd.test.ts +24 -0
- package/src/qmd.ts +224 -315
- package/src/recall-explain-renderer.ts +3 -0
- package/src/recall-rerank-coordinator.test.ts +61 -0
- package/src/recall-xray-renderer.test.ts +6 -0
- package/src/recall-xray.test.ts +88 -1
- package/src/recall-xray.ts +15 -0
- package/src/reconcile/cursor.test.ts +48 -0
- package/src/reconcile/cursor.ts +58 -11
- package/src/reconcile/manifest.test.ts +4 -0
- package/src/reconcile/manifest.ts +41 -51
- package/src/reconcile/plan.test.ts +4 -0
- package/src/reconcile/plan.ts +28 -16
- package/src/search/factory.ts +6 -6
- package/src/search/port.ts +25 -9
- package/src/secure-store/secure-fs.ts +20 -12
- package/src/secure-store/secure-store.test.ts +41 -2
- package/src/spaces/index.test.ts +61 -2
- package/src/spaces/index.ts +44 -18
- package/src/storage/entity-alias-config.ts +97 -0
- package/src/storage/entity-canonical-id-lock.ts +53 -23
- package/src/storage/entity-canonical-id-migration.ts +53 -22
- package/src/storage/entity-canonical-id-references.ts +3 -0
- package/src/storage/entity-id-safety.ts +7 -0
- package/src/storage/entity-store.ts +6 -2
- package/src/storage/memory-frontmatter-metadata.ts +4 -9
- package/src/storage/memory-migration-serialization.ts +10 -15
- package/src/storage/tombstone-blocked-capture-mutation.ts +52 -64
- package/src/storage/tombstone-blocked-capture-sync.ts +244 -199
- package/src/storage-deletion-revisions.test.ts +91 -0
- package/src/storage-fact-hash-index-defer.test.ts +446 -163
- package/src/storage.ts +534 -245
- package/src/tool-scoped-memory.ts +10 -0
- package/src/transfer/capsule-import.ts +13 -0
- package/src/transfer/capsule-merge.ts +13 -0
- package/src/trust-score-recall-paths.test.ts +75 -1
- package/src/types.ts +7 -3
- package/dist/capsule-merge-IDWJPCWK.js.map +0 -1
- package/dist/chunk-3CE77VAP.js.map +0 -1
- package/dist/chunk-3TBLDMJA.js.map +0 -1
- package/dist/chunk-4J7G5SY4.js.map +0 -1
- package/dist/chunk-57QKLRBV.js.map +0 -1
- package/dist/chunk-5TFP4CUL.js.map +0 -1
- package/dist/chunk-7XC2HX75.js.map +0 -1
- package/dist/chunk-A5OJCXZL.js.map +0 -1
- package/dist/chunk-BUE5E2HL.js.map +0 -1
- package/dist/chunk-CJ2ZR7UA.js.map +0 -1
- package/dist/chunk-CUM2BBPN.js.map +0 -1
- package/dist/chunk-D3J5SLQK.js.map +0 -1
- package/dist/chunk-DL7ZD3JH.js.map +0 -1
- package/dist/chunk-DLVPUX7U.js.map +0 -1
- package/dist/chunk-E6PNLPGJ.js.map +0 -1
- package/dist/chunk-ECK75GDJ.js.map +0 -1
- package/dist/chunk-HREE4JHI.js.map +0 -1
- package/dist/chunk-HZFHQ4AQ.js.map +0 -1
- package/dist/chunk-IKKWIPYN.js.map +0 -1
- package/dist/chunk-J7VGGECD.js.map +0 -1
- package/dist/chunk-N5Z4EVOR.js.map +0 -1
- package/dist/chunk-NVRYW264.js.map +0 -1
- package/dist/chunk-P2BM76KT.js.map +0 -1
- package/dist/chunk-PVGDJXVK.js +0 -21
- package/dist/chunk-QJAQNXWI.js.map +0 -1
- package/dist/chunk-RN7DY3FC.js.map +0 -1
- package/dist/chunk-RVLJEII5.js.map +0 -1
- package/dist/chunk-S2NCTZGJ.js.map +0 -1
- package/dist/chunk-TDHTVMPG.js.map +0 -1
- package/dist/chunk-UYLMNVY6.js.map +0 -1
- package/dist/chunk-VCD4PSK2.js.map +0 -1
- package/dist/chunk-VNA7W7QF.js.map +0 -1
- package/dist/chunk-VWAXN2BN.js.map +0 -1
- package/dist/chunk-WOCNN776.js.map +0 -1
- package/dist/chunk-XYTOI63Z.js.map +0 -1
- package/dist/chunk-YV32N67O.js.map +0 -1
- /package/dist/{auto-sync-5OE5QOZB.js.map → auto-sync-UPTUVE4X.js.map} +0 -0
- /package/dist/{chunk-VUPTKTDV.js.map → chunk-2MRHJNWL.js.map} +0 -0
- /package/dist/{chunk-JBPKEARU.js.map → chunk-2QSZNTDO.js.map} +0 -0
- /package/dist/{chunk-5IVLTFOV.js.map → chunk-44N6ESJ4.js.map} +0 -0
- /package/dist/{chunk-HO3QBJEY.js.map → chunk-5546W5SI.js.map} +0 -0
- /package/dist/{chunk-U7GW7NE7.js.map → chunk-5CEECY6P.js.map} +0 -0
- /package/dist/{chunk-4UH4BTGK.js.map → chunk-5SNZSWWR.js.map} +0 -0
- /package/dist/{chunk-6CZPDBJS.js.map → chunk-5U7ID3EZ.js.map} +0 -0
- /package/dist/{chunk-GF22HWS2.js.map → chunk-6NNNURLK.js.map} +0 -0
- /package/dist/{chunk-227UFSEQ.js.map → chunk-7RZJWZ46.js.map} +0 -0
- /package/dist/{chunk-E5UK4VPE.js.map → chunk-7SHJHPTY.js.map} +0 -0
- /package/dist/{chunk-UVIKWC7M.js.map → chunk-7YERSTN7.js.map} +0 -0
- /package/dist/{chunk-S5SLVSVY.js.map → chunk-BQIFZ2MP.js.map} +0 -0
- /package/dist/{chunk-E53DSZEN.js.map → chunk-C26TE27X.js.map} +0 -0
- /package/dist/{chunk-LZ4LDKHZ.js.map → chunk-CLB32OHM.js.map} +0 -0
- /package/dist/{chunk-Q6IP2ARR.js.map → chunk-CSOYVTRX.js.map} +0 -0
- /package/dist/{chunk-XOQSEF7X.js.map → chunk-CVILPI77.js.map} +0 -0
- /package/dist/{chunk-PDLBLTOK.js.map → chunk-EITZHSX6.js.map} +0 -0
- /package/dist/{chunk-WUNIWKY4.js.map → chunk-ELIL2A37.js.map} +0 -0
- /package/dist/{chunk-CINZGPSJ.js.map → chunk-GUMZC2BO.js.map} +0 -0
- /package/dist/{chunk-H24WNPA2.js.map → chunk-GWFSVJ4P.js.map} +0 -0
- /package/dist/{chunk-TSH56VPU.js.map → chunk-HAYSYUAB.js.map} +0 -0
- /package/dist/{chunk-PKNLM44P.js.map → chunk-JH6BPLOP.js.map} +0 -0
- /package/dist/{chunk-KXB4VXHY.js.map → chunk-JIYDRBVZ.js.map} +0 -0
- /package/dist/{chunk-AV5ZEH4M.js.map → chunk-KVJRXN2E.js.map} +0 -0
- /package/dist/{chunk-JVLCVFQ4.js.map → chunk-KXEFRMCF.js.map} +0 -0
- /package/dist/{chunk-WFTIGIIS.js.map → chunk-L6CQ7WIW.js.map} +0 -0
- /package/dist/{chunk-EJUEXZHX.js.map → chunk-LLJMAULE.js.map} +0 -0
- /package/dist/{chunk-AS7YMSL6.js.map → chunk-M23RF3LJ.js.map} +0 -0
- /package/dist/{chunk-3F2LKUMU.js.map → chunk-NIS256NW.js.map} +0 -0
- /package/dist/{chunk-YIAA2X3D.js.map → chunk-NK5RGJ65.js.map} +0 -0
- /package/dist/{chunk-OQ5PRDDS.js.map → chunk-NTOIP2E6.js.map} +0 -0
- /package/dist/{chunk-HLPD7B7P.js.map → chunk-NUEQKLNB.js.map} +0 -0
- /package/dist/{chunk-33PLLLL7.js.map → chunk-P7NGM24P.js.map} +0 -0
- /package/dist/{chunk-7TWUCYER.js.map → chunk-PNRA7FAD.js.map} +0 -0
- /package/dist/{chunk-5I4M26Q7.js.map → chunk-QBSFOKY6.js.map} +0 -0
- /package/dist/{chunk-P4DRWEYC.js.map → chunk-QVSBTCVP.js.map} +0 -0
- /package/dist/{chunk-AAIUERNB.js.map → chunk-R5RFK3CB.js.map} +0 -0
- /package/dist/{chunk-WDISJRMG.js.map → chunk-RMMVQQA6.js.map} +0 -0
- /package/dist/{chunk-5SM35XZR.js.map → chunk-S5NZBKKQ.js.map} +0 -0
- /package/dist/{chunk-WIPEXG6R.js.map → chunk-SXIMQLGV.js.map} +0 -0
- /package/dist/{chunk-OAEQLRCY.js.map → chunk-TN76AKO3.js.map} +0 -0
- /package/dist/{chunk-QN25OCUF.js.map → chunk-TQ4GD737.js.map} +0 -0
- /package/dist/{chunk-7K5Q6COX.js.map → chunk-TVVEYCNW.js.map} +0 -0
- /package/dist/{chunk-DNWXFTLD.js.map → chunk-TYISDI6B.js.map} +0 -0
- /package/dist/{chunk-4LMA77JH.js.map → chunk-U2VLVBBH.js.map} +0 -0
- /package/dist/{chunk-5ZE7QHTK.js.map → chunk-ULVR5KG7.js.map} +0 -0
- /package/dist/{chunk-4B77XSG5.js.map → chunk-UV72DEZD.js.map} +0 -0
- /package/dist/{chunk-S2BBISHU.js.map → chunk-VANZKHTN.js.map} +0 -0
- /package/dist/{chunk-3Y224NYC.js.map → chunk-VYISFWVX.js.map} +0 -0
- /package/dist/{chunk-TIHMZFIV.js.map → chunk-W3IC7QOY.js.map} +0 -0
- /package/dist/{chunk-NRV4Y3PM.js.map → chunk-W4FBGYGK.js.map} +0 -0
- /package/dist/{chunk-MU7ZHSZE.js.map → chunk-WZFAPHIK.js.map} +0 -0
- /package/dist/{chunk-T2TTP3KU.js.map → chunk-X4IDNPOS.js.map} +0 -0
- /package/dist/{chunk-BLAKS3CP.js.map → chunk-XL3TATMJ.js.map} +0 -0
- /package/dist/{chunk-W4XJFLAL.js.map → chunk-XPRJSHNI.js.map} +0 -0
- /package/dist/{chunk-JE7EK33X.js.map → chunk-Y7HRYCNW.js.map} +0 -0
- /package/dist/{chunk-E6EE5B67.js.map → chunk-YK6BDDHP.js.map} +0 -0
- /package/dist/{chunk-ES36HTSC.js.map → chunk-YLHM5BQQ.js.map} +0 -0
- /package/dist/{chunk-BJKPPZ6Z.js.map → chunk-ZFGZ6PZ2.js.map} +0 -0
- /package/dist/{chunk-64UDOIMI.js.map → chunk-ZLQ37WJX.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/orchestration/orchestrator-helpers.ts","../src/orchestration/extraction-run-helpers.ts","../src/orchestration/extraction-run.ts"],"sourcesContent":["/**\n * Orchestrator module-level helpers — relocated from orchestrator.ts\n * (issue #1526, seam 25).\n *\n * Pure functions, types, and constants that previously lived at module\n * level in orchestrator.ts: recall-mode planning, recall snapshots and\n * parsers, abort/race helpers, artifact recall limits, replay\n * source-time slicing, day-summary date utilities, and QMD startup\n * checks. orchestrator.ts re-exports the previously-public names so\n * every existing importer (coordinators, tests, root shims) keeps\n * working unchanged.\n *\n * Behavior-preserving move — no logic changes.\n */\n\nimport { createHash } from \"node:crypto\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { abortError as sharedAbortError, throwIfAborted as sharedThrowIfAborted } from \"../abort-error.js\";\nimport type { CapabilitySet } from \"../capabilities.js\";\nimport { buildCompressionGuidelinesMarkdown as buildCompressionGuidelinesMarkdownV2 } from \"../compression-optimizer.js\";\nimport { FallbackLlmClient } from \"../fallback-llm.js\";\nimport { hasBroadGraphIntent, planRecallMode } from \"../intent.js\";\nimport { resolveLifecycleState } from \"../lifecycle.js\";\nimport { log } from \"../logger.js\";\nimport type { GraphRecallRankedResult, GraphRecallShadowComparison } from \"./graph-recall-coordinator.js\";\nimport { parseQmdExplain } from \"../qmd.js\";\nimport type { GraphRecallExpandedEntry } from \"../recall-state.js\";\nimport type { RecallXrayServedBy } from \"../recall-xray.js\";\nimport type { RecallContextComposition } from \"../recall-context-composition.js\";\nimport { type BufferTurn, type MemoryActionEvent, type MemoryFile, type MemoryFrontmatter, type MemoryIntent, type PluginConfig, type QmdSearchResult, type RecallPlanMode, confidenceTier } from \"../types.js\";\nimport { categoryDirName } from \"../utils/category-dir.js\";\nimport { parseFlexibleIsoTimestamp } from \"../utils/iso-timestamp.js\";\n\nexport interface BulkImportBatchIngestResult {\n attemptedTurnCount: number;\n extractionCount: number;\n persistedCount: number;\n durableOutputCount: number;\n skippedCount: number;\n failedCount: number;\n postPersistMetadataFailureCount: number;\n processedTurnCount: number;\n}\n\nexport class BulkImportBatchPartialFailureError extends Error {\n readonly partialResult: BulkImportBatchIngestResult;\n\n readonly originalError: unknown;\n\n constructor(\n message: string,\n partialResult: BulkImportBatchIngestResult,\n originalError: unknown,\n ) {\n super(message);\n this.name = \"BulkImportBatchPartialFailureError\";\n this.partialResult = partialResult;\n this.originalError = originalError;\n }\n}\n\nexport interface GraphRecallSnapshot {\n recordedAt: string;\n mode: RecallPlanMode | string;\n queryHash: string;\n queryLength: number;\n namespaces: string[];\n seedCount: number;\n expandedCount: number;\n seeds: string[];\n expanded: GraphRecallExpandedEntry[];\n status?: \"completed\" | \"skipped\" | \"aborted\";\n reason?: string;\n shadowMode?: boolean;\n queryIntent?: MemoryIntent;\n seedResults?: GraphRecallRankedResult[];\n finalResults?: GraphRecallRankedResult[];\n shadowComparison?: GraphRecallShadowComparison;\n}\n\nexport interface IntentDebugSnapshot {\n recordedAt: string;\n promptHash: string;\n promptLength: number;\n retrievalQueryHash: string;\n retrievalQueryLength: number;\n plannerEnabled: boolean;\n plannedMode: RecallPlanMode;\n effectiveMode: RecallPlanMode;\n recallResultLimit: number;\n queryIntent: MemoryIntent;\n graphExpandedIntentDetected: boolean;\n graphDecision: {\n status: \"not_requested\" | \"skipped\" | \"completed\" | \"aborted\";\n reason?: string;\n shadowMode: boolean;\n qmdAvailable: boolean;\n graphRecallEnabled: boolean;\n multiGraphMemoryEnabled: boolean;\n };\n}\n\nexport interface QmdRecallSnapshot {\n recordedAt: string;\n queryHash: string;\n queryLength: number;\n collection?: string;\n namespaces: string[];\n fetchLimit: number;\n primaryResultCount: number;\n hybridResultCount: number;\n queryAwareSeedCount: number;\n resultCount: number;\n intentHint?: string;\n explainEnabled: boolean;\n hybridTopUpUsed: boolean;\n hybridTopUpSkippedReason?: string;\n results: QmdSearchResult[];\n}\n\nexport interface RecallModeDecision {\n plannedMode: RecallPlanMode;\n effectiveMode: RecallPlanMode;\n graphExpandedIntentDetected: boolean;\n graphReason?: string;\n /**\n * Where `plannedMode` came from (issue #1367 / Option C). `\"heuristic\"` for\n * the regex planner; `\"llm\"` when the LLM planner classified it; and\n * `\"heuristic-fallback\"` when the LLM was enabled but errored/timed out and we\n * fell back. Absent on the synchronous heuristic-only path.\n */\n plannerSource?: \"heuristic\" | \"llm\" | \"heuristic-fallback\";\n /** Short rationale from the planner (for telemetry / x-ray). */\n plannerReason?: string;\n /** Wall-clock spent in the LLM planner call, when one was made. */\n plannerLatencyMs?: number;\n /** True when the LLM planner was enabled but fell back to the heuristic. */\n plannerFallbackUsed?: boolean;\n /** Model that served the LLM classification, when one was used. */\n plannerModelUsed?: string;\n /**\n * The regex-heuristic baseline mode, captured whenever the LLM planner ran\n * (any source). Lets operators compare planned-vs-heuristic during rollout —\n * distinct from `plannedMode`, which on the LLM path is the LLM's choice.\n */\n plannerHeuristicMode?: RecallPlanMode;\n /**\n * In shadow mode, the mode the LLM *would* have chosen (recorded for\n * comparison) while `effectiveMode` stays on the heuristic decision.\n */\n shadowLlmMode?: RecallPlanMode;\n}\n\n/**\n * Map the orchestrator's internal `recallSource` strings to the\n * X-ray `servedBy` vocabulary (issue #570 PR 1). The X-ray tier\n * ladder intentionally flattens QMD / embedding / cold-fallback to\n * the `hybrid` tier because they all materialize through the same\n * hybrid BM25+vector pipeline from the caller's perspective. The\n * `recent_scan` path gets its own dedicated tier because it bypasses\n * the hybrid pipeline entirely. `none` is treated as `hybrid` on the\n * theory that a query that returned nothing still routed through the\n * hybrid pipeline — but callers should normally gate capture on\n * `recalledMemoryIds.length > 0`.\n */\nexport function mapRecallSourceToXrayServedBy(\n source:\n | \"none\"\n | \"hot_qmd\"\n | \"hot_embedding\"\n | \"cold_fallback\"\n | \"recent_scan\",\n): RecallXrayServedBy {\n // Exhaustive switch: every current union member is explicitly\n // listed so TypeScript surfaces a compile error if a new source is\n // added without a deliberate mapping. The `never`-typed fallthrough\n // keeps the function total at runtime — if the caller passes an\n // unexpected value that slipped past the type system (e.g. a JSON\n // deserialization), we still fall back to `hybrid`.\n switch (source) {\n case \"recent_scan\":\n return \"recent-scan\";\n case \"hot_qmd\":\n case \"hot_embedding\":\n case \"cold_fallback\":\n case \"none\":\n return \"hybrid\";\n }\n const _exhaustive: never = source;\n void _exhaustive;\n return \"hybrid\";\n}\n\nexport interface RecallInvocationOptions {\n namespace?: string;\n topK?: number;\n mode?: RecallPlanMode;\n abortSignal?: AbortSignal;\n /** Server-resolved identity of the connector performing this recall. */\n sourceConnector?: string;\n /**\n * Capture a `RecallXraySnapshot` for this recall (issue #570). When\n * `true`, the orchestrator builds a snapshot from the data it has\n * already gathered and stashes it in memory, accessible via\n * `getLastXraySnapshot()`. When `false` or absent, nothing is\n * captured and recall behavior is unchanged (schema-only slice).\n */\n xrayCapture?: boolean;\n /**\n * Per-invocation override for `recallBudgetChars` (issue #570 PR 3/4).\n * Flows through `getRecallBudgetChars()` for this recall only — no\n * shared config mutation, so concurrent recalls on the same\n * orchestrator are not affected (CLAUDE.md rule 47: no shared\n * mutable state across async boundaries). Must be a non-negative\n * finite integer; non-conforming values are ignored and the\n * configured budget is used.\n */\n budgetCharsOverride?: number;\n /**\n * Per-invocation principal override (issue #570 PR 4). When set,\n * the orchestrator uses this principal for ACL / namespace checks\n * instead of `resolvePrincipal(sessionKey, config)`. This is the\n * escape hatch for access surfaces (HTTP / MCP) that have already\n * authenticated the caller upstream — threading an unmapped\n * principal through the session-key-based resolver would otherwise\n * collapse it to `\"default\"` and produce false denials in\n * namespace-enabled deployments (CLAUDE.md rule 42).\n */\n principalOverride?: string;\n /**\n * Historical recall point (issue #680). When set, the orchestrator\n * filters out memories whose `valid_at` is after this timestamp OR\n * whose `invalid_at` is at-or-before this timestamp, so callers see\n * the corpus as it existed at `asOf`. ISO 8601 string; comparisons\n * use `Date.parse()` so timezone-aware values round-trip correctly\n * (CLAUDE.md gotcha — never compare ISO strings lexicographically).\n * Invalid values must be rejected at input boundaries (CLAUDE.md\n * rule 51); the orchestrator does NOT silently fall back here.\n */\n asOf?: string;\n /**\n * Issue #681 — when `true`, bypasses `graphTraversalConfidenceFloor`\n * and includes edges below the floor in graph traversal. Useful for\n * diagnostic recall queries that need to surface results that would\n * normally be pruned by confidence decay. Default `false`.\n */\n includeLowConfidence?: boolean;\n /**\n * User-aware context scopes active for this recall. Used by X-ray\n * provenance safety checks so boundary-scoped memories are evaluated\n * against the caller's real context.\n */\n currentContextScopes?: readonly unknown[];\n /**\n * Wall-clock ms the caller waited to begin execution — per-principal\n * semaphore queue + single-flight wait (issue #1906). Folded into\n * recall-timings additively as `queueWaitMs`; omitted phases are simply\n * absent, so existing timing consumers are unaffected.\n */\n queueWaitMs?: number;\n onContextComposition?: (composition: RecallContextComposition) => void | PromiseLike<void>;\n}\n\nexport type QueryAwarePrefilter = {\n candidatePaths: Set<string> | null;\n temporalFromDate: string | null;\n matchedTags: string[];\n expandedTags: string[];\n combination: \"none\" | \"temporal\" | \"tag\" | \"intersection\" | \"union\";\n filteredToFullSearch: boolean;\n};\n\n// Recall-specific abort helpers. Thin wrappers over the shared\n// `abort-error.ts` module so every abort in the codebase shares the\n// same `name === \"AbortError\"` classification contract (`isAbortError`\n// works uniformly). We keep the \"recall aborted\" default message for\n// back-compat with call-site logs; callers that pass an explicit\n// message (e.g. \"extraction aborted (before_extract)\") are unaffected.\nexport const abortRecallError = sharedAbortError;\n\nexport function throwIfRecallAborted(\n signal?: AbortSignal,\n message = \"recall aborted\",\n): void {\n sharedThrowIfAborted(signal, message);\n}\n\nexport async function raceRecallAbort<T>(\n promise: Promise<T>,\n signal?: AbortSignal,\n message = \"recall aborted\",\n): Promise<T> {\n throwIfRecallAborted(signal, message);\n if (!signal) return promise;\n\n let onAbort: (() => void) | null = null;\n const abortPromise = new Promise<T>((_resolve, reject) => {\n onAbort = () => reject(abortRecallError(message));\n signal.addEventListener(\"abort\", onAbort, { once: true });\n });\n\n try {\n return await Promise.race([promise, abortPromise]);\n } finally {\n if (onAbort) {\n signal.removeEventListener(\"abort\", onAbort);\n }\n }\n}\n\n/** Maximum age (ms) before a compaction-reset signal file is considered stale and removed. */\nexport const COMPACTION_SIGNAL_MAX_AGE_MS = 60 * 60 * 1000; // 1 hour\n\nexport const DEFAULT_QMD_STARTUP_COLLECTION_CHECK_TIMEOUT_MS = 10_000;\n\nexport type DaySummaryGatherOptions = {\n timeZone?: string;\n now?: Date;\n};\n\nexport function normalizeIanaTimeZone(value: unknown): string | undefined {\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.trim();\n if (!trimmed) return undefined;\n try {\n Intl.DateTimeFormat(undefined, { timeZone: trimmed });\n return trimmed;\n } catch {\n return undefined;\n }\n}\n\nexport function formatDateInTimeZone(date: Date, timeZone: string): string {\n const parts = new Intl.DateTimeFormat(\"en-US\", {\n timeZone,\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n }).formatToParts(date);\n const get = (type: string): string => parts.find((part) => part.type === type)?.value ?? \"\";\n return `${get(\"year\")}-${get(\"month\")}-${get(\"day\")}`;\n}\n\nexport function utcDateKey(date: Date): string {\n return date.toISOString().slice(0, 10);\n}\n\nexport function utcDateKeysAround(date: Date): string[] {\n const dayMs = 86_400_000;\n const keys = [\n utcDateKey(new Date(date.getTime() - dayMs)),\n utcDateKey(date),\n utcDateKey(new Date(date.getTime() + dayMs)),\n ];\n return keys.filter((value, index, array) => array.indexOf(value) === index);\n}\n\nexport function utcDateKeysForLocalDay(date: Date, timeZone: string): string[] {\n const targetLocalDate = formatDateInTimeZone(date, timeZone);\n const keys = new Set<string>();\n const hourMs = 3_600_000;\n const scanStart = date.getTime() - 48 * hourMs;\n const scanEnd = date.getTime() + 48 * hourMs;\n for (let ms = scanStart; ms <= scanEnd; ms += hourMs) {\n const candidate = new Date(ms);\n if (formatDateInTimeZone(candidate, timeZone) === targetLocalDate) {\n keys.add(utcDateKey(candidate));\n }\n }\n return keys.size > 0 ? [...keys].sort() : utcDateKeysAround(date);\n}\n\nexport function parseFiniteDate(value: unknown): Date | null {\n if (typeof value !== \"string\" || value.trim().length === 0) return null;\n const parsed = new Date(value);\n return Number.isFinite(parsed.getTime()) ? parsed : null;\n}\n\nexport function filterHourlySummaryMarkdownForLocalDay(\n raw: string,\n utcDate: string,\n timeZone: string,\n targetLocalDate: string,\n): string | null {\n const hourHeaderPattern = /^## ([01]\\d|2[0-3]):00[ \\t]*$/gm;\n const matches = Array.from(raw.matchAll(hourHeaderPattern));\n if (matches.length === 0) return null;\n\n const firstSectionStart = matches[0]?.index ?? 0;\n const preamble = raw.slice(0, firstSectionStart).trim();\n const sections: string[] = [];\n for (let index = 0; index < matches.length; index += 1) {\n const match = matches[index];\n const hour = match[1];\n if (!hour) continue;\n const sectionTimestamp = parseFiniteDate(`${utcDate}T${hour}:00:00.000Z`);\n if (\n !sectionTimestamp ||\n formatDateInTimeZone(sectionTimestamp, timeZone) !== targetLocalDate\n ) {\n continue;\n }\n const sectionStart = match.index ?? 0;\n const sectionEnd = matches[index + 1]?.index ?? raw.length;\n const section = raw.slice(sectionStart, sectionEnd).trim();\n if (section.length > 0) sections.push(section);\n }\n\n if (sections.length === 0) return null;\n return [preamble, ...sections]\n .filter((section) => section.length > 0)\n .join(\"\\n\\n\");\n}\n\nexport type SearchCollectionState = \"present\" | \"missing\" | \"unknown\" | \"skipped\";\n\nexport function qmdStartupCollectionCheckTimeoutMs(): number {\n const raw =\n process.env.REMNIC_QMD_STARTUP_COLLECTION_CHECK_TIMEOUT_MS ??\n process.env.ENGRAM_QMD_STARTUP_COLLECTION_CHECK_TIMEOUT_MS;\n if (raw === undefined) return DEFAULT_QMD_STARTUP_COLLECTION_CHECK_TIMEOUT_MS;\n const parsed = Number(raw);\n return Number.isFinite(parsed) && parsed >= 1_000\n ? Math.floor(parsed)\n : DEFAULT_QMD_STARTUP_COLLECTION_CHECK_TIMEOUT_MS;\n}\n\nexport async function qmdStartupCollectionCheckWithTimeout(\n promise: Promise<SearchCollectionState>,\n controller: AbortController,\n label: string,\n): Promise<SearchCollectionState> {\n const timeoutMs = qmdStartupCollectionCheckTimeoutMs();\n let timer: NodeJS.Timeout | undefined;\n let settled = false;\n\n const timeoutPromise = new Promise<SearchCollectionState>((resolve) => {\n timer = setTimeout(() => {\n if (settled) return;\n controller.abort();\n log.warn(\n `QMD startup collection check for ${label} timed out after ${timeoutMs}ms; keeping search enabled fail-open`,\n );\n resolve(\"unknown\");\n }, timeoutMs);\n timer.unref?.();\n });\n\n const checkedPromise = promise\n .catch((err): SearchCollectionState => {\n log.warn(\n `QMD startup collection check for ${label} failed; keeping search enabled fail-open: ${err}`,\n );\n return \"unknown\";\n })\n .finally(() => {\n settled = true;\n if (timer) clearTimeout(timer);\n });\n\n return await Promise.race([checkedPromise, timeoutPromise]);\n}\n\n/** Default workspace directory when no per-agent or config workspace is available. */\nexport function defaultWorkspaceDir(): string {\n return path.join(os.homedir(), \".openclaw\", \"workspace\");\n}\n\n/**\n * Produce a collision-resistant, filesystem-safe identifier from a session key.\n *\n * Session keys follow colon-delimited forms (e.g., `agent:gpucodebot:main`).\n * A naive replace (`:` → `_`) is lossy: different keys like `agent:alpha` and\n * `agent/alpha` would collide. Instead we append a short SHA-256 hash of the\n * original key to the human-readable sanitized prefix, guaranteeing uniqueness\n * while keeping filenames debuggable.\n *\n * Format: `<sanitized>-<12-char-hex-hash>`\n * Example: `agent:gpucodebot:main` → `agent_gpucodebot_main-a1b2c3d4e5f6`\n */\nexport function sanitizeSessionKeyForFilename(sessionKey: string): string {\n const readable = sessionKey.replace(/[^a-zA-Z0-9._-]/g, \"_\");\n const hash = createHash(\"sha256\")\n .update(sessionKey)\n .digest(\"hex\")\n .slice(0, 12);\n return `${readable}-${hash}`;\n}\n\nexport function sourceValidAtMs(turn: BufferTurn): number | null {\n if (typeof turn.sourceValidAt !== \"string\") return null;\n return parseFlexibleIsoTimestamp(turn.sourceValidAt.trim());\n}\n\nexport const SOURCE_VALID_AT_CONTEXT_TURNS = 2;\n\nexport function sourceValidAtSliceKey(turn: BufferTurn, index: number): string {\n const validAtMs = sourceValidAtMs(turn);\n return validAtMs === null ? `unknown:${index}` : String(validAtMs);\n}\n\nexport function asExtractionContextTurn(turn: BufferTurn): BufferTurn {\n return { ...turn, extractionContextOnly: true };\n}\n\nexport function asExtractionTargetTurn(turn: BufferTurn): BufferTurn {\n const { extractionContextOnly: _contextOnly, ...targetTurn } = turn;\n return targetTurn;\n}\n\nexport function sourceValidAtContextTurns(\n turns: readonly BufferTurn[],\n targetStart: number,\n targetEnd: number,\n targetValidAtMs: number | null,\n): BufferTurn[] {\n if (targetValidAtMs === null) return [];\n return turns\n .flatMap((turn, index) => {\n if (index >= targetStart && index < targetEnd) return [];\n const contextValidAtMs = sourceValidAtMs(turn);\n if (contextValidAtMs === null || contextValidAtMs > targetValidAtMs) {\n return [];\n }\n return [{ turn, index, validAtMs: contextValidAtMs }];\n })\n .sort((a, b) => {\n if (a.validAtMs < b.validAtMs) return -1;\n if (a.validAtMs > b.validAtMs) return 1;\n if (a.index === b.index) return 0;\n return a.index < b.index ? -1 : 1;\n })\n .slice(-SOURCE_VALID_AT_CONTEXT_TURNS)\n .map(({ turn }) => asExtractionContextTurn(turn));\n}\n\nexport function targetSourceValidAtSortMs(turns: readonly BufferTurn[]): number {\n let latestMs: number | null = null;\n for (const turn of turns) {\n if (turn.extractionContextOnly === true) continue;\n const validAtMs = sourceValidAtMs(turn);\n if (validAtMs === null) continue;\n if (latestMs === null || validAtMs > latestMs) {\n latestMs = validAtMs;\n }\n }\n return latestMs ?? Number.POSITIVE_INFINITY;\n}\n\nexport function sortSourceValidAtSlicesChronologically(\n slices: BufferTurn[][],\n): BufferTurn[][] {\n return slices\n .map((turns, order) => ({\n turns,\n order,\n targetValidAtMs: targetSourceValidAtSortMs(turns),\n }))\n .sort((a, b) => {\n if (a.targetValidAtMs < b.targetValidAtMs) return -1;\n if (a.targetValidAtMs > b.targetValidAtMs) return 1;\n if (a.order === b.order) return 0;\n return a.order < b.order ? -1 : 1;\n })\n .map((slice) => slice.turns);\n}\n\nexport function splitTurnsBySourceValidAt(\n turns: readonly BufferTurn[],\n options: { includeContext?: boolean } = {},\n): BufferTurn[][] {\n if (turns.length === 0) return [];\n if (!turns.some((turn) => sourceValidAtMs(turn) !== null)) {\n return [[...turns]];\n }\n\n const slices: BufferTurn[][] = [];\n let start = 0;\n while (start < turns.length) {\n const targetValidAtMs = sourceValidAtMs(turns[start]);\n const activeKey = sourceValidAtSliceKey(turns[start], start);\n let end = start + 1;\n while (\n end < turns.length &&\n sourceValidAtSliceKey(turns[end], end) === activeKey\n ) {\n end += 1;\n }\n\n const contextTurns =\n options.includeContext === false\n ? []\n : sourceValidAtContextTurns(turns, start, end, targetValidAtMs);\n slices.push([\n ...contextTurns,\n ...turns.slice(start, end).map(asExtractionTargetTurn),\n ]);\n start = end;\n }\n return sortSourceValidAtSlicesChronologically(slices);\n}\n\nexport function isArtifactMemoryPath(filePath: string): boolean {\n return /(?:^|[\\\\/])artifacts(?:[\\\\/]|$)/i.test(filePath);\n}\n\n/**\n * Meeting records (issue #1900) live at\n * `<root>/meetings/<YYYY-MM-DD>/mtg-<YYYY-MM-DD>-<hash>.md` — inside the QMD\n * collection root (full-text searchable) but NEVER surfaced through generic\n * recall, exactly like `artifacts/`. The predicate matches the FULL record\n * shape (anchored at the filename) rather than any `meetings` path segment, so\n * a namespaced deployment whose non-default namespace is literally named\n * `meetings` (`.../namespaces/meetings/facts/…`) keeps its ordinary memories in\n * recall — only true meeting records are excluded.\n */\nexport function isMeetingRecordPath(filePath: string): boolean {\n return /(?:^|[\\\\/])meetings[\\\\/]\\d{4}-\\d{2}-\\d{2}[\\\\/]mtg-\\d{4}-\\d{2}-\\d{2}-[0-9a-f]{8}\\.md$/i.test(filePath);\n}\n\n/** Exactly `activity/<YYYY-MM-DD>.md`, at the top level of a memory root. */\nconst ACTIVITY_DIGEST_TOPLEVEL = /^activity[\\\\/]\\d{4}-\\d{2}-\\d{2}\\.md$/i;\n/** The digest FILE shape anywhere in a path (root-unaware best-effort). */\nconst ACTIVITY_DIGEST_ANYWHERE = /(?:^|[\\\\/])activity[\\\\/]\\d{4}-\\d{2}-\\d{2}\\.md$/i;\n\n/**\n * Activity day-digests live at `<memoryRoot>/activity/<YYYY-MM-DD>.md` — a\n * dedicated searchable surface (explicit activity search), never generic recall.\n * Captured screen text must not auto-inject into ordinary prompts (issue #1899).\n * Keyed on the path (parseFrontmatter drops the digest's `kind` marker).\n *\n * Root-aware: when `memoryRoot` is given, the path is resolved relative to it and\n * must be the TOP-LEVEL `activity/<date>.md`, so an ordinary memory nested under\n * a category (e.g. `facts/proj/activity/<date>.md`) stays recallable. Without a\n * root, falls back to the digest file shape anywhere (best-effort).\n */\nexport function isActivityDigestPath(filePath: string, memoryRoot?: string): boolean {\n if (memoryRoot !== undefined && memoryRoot.length > 0) {\n const relative = path.relative(memoryRoot, path.resolve(memoryRoot, filePath));\n return ACTIVITY_DIGEST_TOPLEVEL.test(relative);\n }\n return ACTIVITY_DIGEST_ANYWHERE.test(filePath);\n}\n\nexport function buildCompressionGuidelinesMarkdown(\n events: MemoryActionEvent[],\n generatedAtIso: string = new Date().toISOString(),\n): string {\n return buildCompressionGuidelinesMarkdownV2(events, generatedAtIso);\n}\n\n\nexport function applyQueryAwareCandidateFilter(\n candidates: QmdSearchResult[],\n candidatePaths: Set<string> | null,\n): QmdSearchResult[] {\n if (!candidatePaths) return candidates;\n if (candidatePaths.size === 0) return [];\n const filtered = candidates.filter((candidate) =>\n candidatePaths.has(candidate.path),\n );\n return filtered.length > 0 ? filtered : candidates;\n}\n\nexport function tokenizeRecallQuery(prompt: string): string[] {\n return prompt\n .toLowerCase()\n .split(/[^a-z0-9]+/i)\n .map((t) => t.trim())\n .filter((t) => t.length >= 3);\n}\n\nexport function hasLifecycleMetadata(frontmatter: MemoryFrontmatter): boolean {\n return (\n frontmatter.lifecycleState !== undefined ||\n frontmatter.verificationState !== undefined ||\n frontmatter.policyClass !== undefined ||\n frontmatter.lastValidatedAt !== undefined ||\n frontmatter.decayScore !== undefined ||\n frontmatter.heatScore !== undefined\n );\n}\n\nexport function shouldFilterLifecycleRecallCandidate(\n frontmatter: MemoryFrontmatter,\n options: {\n lifecyclePolicyEnabled: boolean;\n lifecycleFilterStaleEnabled: boolean;\n },\n): boolean {\n if (!options.lifecyclePolicyEnabled || !options.lifecycleFilterStaleEnabled)\n return false;\n if (!hasLifecycleMetadata(frontmatter)) return false;\n const lifecycleState = resolveLifecycleState(frontmatter);\n return lifecycleState === \"stale\" || lifecycleState === \"archived\";\n}\n\nexport function lifecycleRecallScoreAdjustment(\n frontmatter: MemoryFrontmatter,\n options: {\n lifecyclePolicyEnabled: boolean;\n },\n): number {\n if (!options.lifecyclePolicyEnabled) return 0;\n if (!hasLifecycleMetadata(frontmatter)) return 0;\n\n let delta = 0;\n const lifecycleState = resolveLifecycleState(frontmatter);\n switch (lifecycleState) {\n case \"active\":\n delta += 0.05;\n break;\n case \"validated\":\n delta += 0.03;\n break;\n case \"candidate\":\n delta -= 0.01;\n break;\n case \"stale\":\n delta -= 0.06;\n break;\n case \"archived\":\n delta -= 0.08;\n break;\n }\n if (frontmatter.verificationState === \"disputed\") {\n delta -= 0.12;\n }\n return delta;\n}\n\nexport function computeArtifactRecallLimit(\n recallMode: RecallPlanMode,\n recallResultLimit: number,\n verbatimArtifactsMaxRecall: number,\n): number {\n if (recallMode === \"no_recall\") return 0;\n if (Math.max(0, recallResultLimit) === 0) return 0;\n const base = Math.max(0, verbatimArtifactsMaxRecall);\n if (recallMode === \"minimal\") {\n return Math.min(base, Math.max(0, recallResultLimit));\n }\n return base;\n}\n\nexport function resolveEffectiveRecallMode(options: {\n plannerEnabled: boolean;\n graphRecallEnabled: boolean;\n multiGraphMemoryEnabled: boolean;\n graphExpandedIntentEnabled?: boolean;\n prompt: string;\n}): RecallPlanMode {\n return resolveRecallModeDecision(options).effectiveMode;\n}\n\nexport interface RecallModeGraphOptions {\n plannerEnabled: boolean;\n graphRecallEnabled: boolean;\n multiGraphMemoryEnabled: boolean;\n graphExpandedIntentEnabled?: boolean;\n prompt: string;\n}\n\n/**\n * Apply the graph-mode overlay + gating to a planner-produced mode.\n *\n * Shared by the heuristic ({@link resolveRecallModeDecision}) and LLM\n * ({@link resolveRecallModeDecisionAsync}) paths so graph promotion and the\n * \"graph disabled → fall back to full\" gating behave identically regardless of\n * which planner produced `plannedModeRaw` (gotcha #39).\n */\nexport function finalizeRecallModeDecision(\n plannedModeRaw: RecallPlanMode,\n options: RecallModeGraphOptions,\n): RecallModeDecision {\n let plannedMode: RecallPlanMode = plannedModeRaw;\n const graphExpandedIntentDetected =\n options.plannerEnabled &&\n options.graphExpandedIntentEnabled === true &&\n hasBroadGraphIntent(options.prompt);\n if (plannedMode !== \"graph_mode\" && graphExpandedIntentDetected) {\n plannedMode = \"graph_mode\";\n }\n if (\n plannedMode === \"graph_mode\" &&\n (!options.graphRecallEnabled || !options.multiGraphMemoryEnabled)\n ) {\n return {\n plannedMode,\n effectiveMode: \"full\",\n graphExpandedIntentDetected,\n graphReason: !options.graphRecallEnabled\n ? \"graph recall disabled by config\"\n : \"multi-graph memory disabled by config\",\n };\n }\n return {\n plannedMode,\n effectiveMode: plannedMode,\n graphExpandedIntentDetected,\n };\n}\n\nexport function resolveRecallModeDecision(options: RecallModeGraphOptions): RecallModeDecision {\n const plannedMode: RecallPlanMode = options.plannerEnabled\n ? planRecallMode(options.prompt)\n : \"full\";\n return finalizeRecallModeDecision(plannedMode, options);\n}\n\n/**\n * Async recall-mode decision with optional LLM-based planning (issue #1367 /\n * Option C). Falls back to the heuristic decision when the LLM planner is\n * disabled, in shadow mode, or unavailable/failed — so this is always safe to\n * await on the recall hot path. Provider-agnostic: the LLM call routes through\n * the gateway/fallback chain.\n *\n * `recallPlannerEnabled === false` keeps the legacy \"always full\" behavior and\n * skips the LLM entirely (the planner as a whole is off).\n */\nexport async function resolveRecallModeDecisionAsync(\n options: RecallModeGraphOptions & {\n config: PluginConfig;\n /**\n * Recall-operation capability gates (issue #1523). REQUIRED: the recall\n * orchestrator always passes a resolved set — the LLM planner gate reads\n * `caps.recallPlannerLlm`, never re-derives from config.\n */\n caps: CapabilitySet;\n hints?: string[];\n llm?: FallbackLlmClient;\n signal?: AbortSignal;\n },\n): Promise<RecallModeDecision> {\n const heuristicDecision = resolveRecallModeDecision(options);\n\n // Planner globally off, or LLM planning not opted into → heuristic only.\n // Read the resolved capability (issue #1523) — never re-derive from config.\n const plannerLlmEnabled = options.caps.recallPlannerLlm;\n if (!options.plannerEnabled || !plannerLlmEnabled) {\n return heuristicDecision;\n }\n\n const { planRecallModeLLM } = await import(\"../recall-planner-llm.js\");\n const planned = await planRecallModeLLM(\n options.prompt,\n options.hints,\n options.config,\n options.caps,\n options.llm,\n options.signal,\n );\n\n // Shadow mode: record what the LLM would have chosen but keep the heuristic\n // effective decision (safe rollout / comparison — gotcha #30).\n if (options.config.recallPlannerShadowMode) {\n return {\n ...heuristicDecision,\n plannerSource: planned.source,\n plannerReason: `shadow:${planned.reason}`,\n plannerLatencyMs: planned.latencyMs,\n plannerFallbackUsed: planned.fallbackUsed,\n plannerModelUsed: planned.modelUsed,\n plannerHeuristicMode: planned.heuristicMode,\n shadowLlmMode: planned.mode,\n };\n }\n\n const llmDecision = finalizeRecallModeDecision(planned.mode, options);\n return {\n ...llmDecision,\n plannerSource: planned.source,\n plannerReason: planned.reason,\n plannerLatencyMs: planned.latencyMs,\n plannerFallbackUsed: planned.fallbackUsed,\n plannerModelUsed: planned.modelUsed,\n plannerHeuristicMode: planned.heuristicMode,\n };\n}\n\nexport function computeArtifactCandidateFetchLimit(\n targetCount: number,\n): number {\n const cappedTarget = Math.max(0, targetCount);\n if (cappedTarget === 0) return 0;\n const headroom = Math.max(8, cappedTarget * 4);\n return Math.min(200, cappedTarget + headroom);\n}\n\nexport function computeQmdHybridFetchLimit(\n recallFetchLimit: number,\n artifactsEnabled: boolean,\n maxArtifactRecall: number,\n): number {\n const cappedRecallLimit = Math.max(0, recallFetchLimit);\n if (cappedRecallLimit === 0) return 0;\n if (!artifactsEnabled) return cappedRecallLimit;\n // Overscan when artifacts are enabled, then filter artifact paths before\n // re-applying the recall cap to avoid artifact-dominated top-N starvation.\n const artifactHeadroom = Math.max(20, Math.max(0, maxArtifactRecall) * 8);\n return Math.min(400, cappedRecallLimit + artifactHeadroom);\n}\n\nexport function summarizeGraphShadowComparison(\n baseline: QmdSearchResult[],\n merged: QmdSearchResult[],\n topN: number,\n): {\n baselineCount: number;\n graphCount: number;\n overlapCount: number;\n overlapRatio: number;\n averageOverlapDelta: number;\n} {\n const limit = Math.max(0, Math.floor(topN));\n const baselineTop = limit > 0 ? baseline.slice(0, limit) : [];\n const graphTop = limit > 0 ? merged.slice(0, limit) : [];\n const baselineByPath = new Map(\n baselineTop.map((item) => [item.path, item.score]),\n );\n const graphByPath = new Map(graphTop.map((item) => [item.path, item.score]));\n\n let overlapCount = 0;\n let overlapDeltaSum = 0;\n for (const [p, baselineScore] of baselineByPath.entries()) {\n const graphScore = graphByPath.get(p);\n if (typeof graphScore !== \"number\") continue;\n overlapCount += 1;\n overlapDeltaSum += graphScore - baselineScore;\n }\n\n const baselineCount = baselineTop.length;\n return {\n baselineCount,\n graphCount: graphTop.length,\n overlapCount,\n overlapRatio: baselineCount > 0 ? overlapCount / baselineCount : 0,\n averageOverlapDelta: overlapCount > 0 ? overlapDeltaSum / overlapCount : 0,\n };\n}\n\nexport function parseGraphRecallRankedResults(\n value: unknown,\n): GraphRecallRankedResult[] {\n if (!Array.isArray(value)) return [];\n const parsed: GraphRecallRankedResult[] = [];\n for (const entry of value) {\n if (!entry || typeof entry !== \"object\") continue;\n const candidate = entry as Partial<GraphRecallRankedResult>;\n if (\n typeof candidate.path !== \"string\" ||\n typeof candidate.score !== \"number\"\n )\n continue;\n parsed.push({\n path: candidate.path,\n score: candidate.score,\n docid: typeof candidate.docid === \"string\" ? candidate.docid : undefined,\n sourceLabels: Array.isArray(candidate.sourceLabels)\n ? candidate.sourceLabels.filter(\n (item): item is string => typeof item === \"string\",\n )\n : [],\n });\n }\n return parsed.slice(0, 64);\n}\n\nexport function parseMemoryIntentSnapshot(value: unknown): MemoryIntent {\n const candidate =\n value && typeof value === \"object\" ? (value as Partial<MemoryIntent>) : {};\n return {\n goal: typeof candidate.goal === \"string\" ? candidate.goal : \"unknown\",\n actionType:\n typeof candidate.actionType === \"string\"\n ? candidate.actionType\n : \"unknown\",\n entityTypes: Array.isArray(candidate.entityTypes)\n ? candidate.entityTypes.filter(\n (item): item is string => typeof item === \"string\",\n )\n : [],\n taskInitiation: candidate.taskInitiation === true,\n };\n}\n\nexport function buildQmdIntentHint(intent: MemoryIntent): string | undefined {\n const parts: string[] = [];\n if (intent.goal !== \"unknown\") {\n parts.push(`goal:${intent.goal.replace(/_/g, \" \")}`);\n }\n if (intent.actionType !== \"unknown\") {\n parts.push(`action:${intent.actionType.replace(/_/g, \" \")}`);\n }\n if (intent.entityTypes.length > 0) {\n parts.push(`entities:${intent.entityTypes.join(\",\")}`);\n }\n if (intent.taskInitiation === true) {\n parts.push(\"task_initiation\");\n }\n return parts.length > 0 ? parts.join(\" \") : undefined;\n}\n\nexport function parseQmdRecallResults(value: unknown): QmdSearchResult[] {\n if (!Array.isArray(value)) return [];\n const parsed: QmdSearchResult[] = [];\n for (const entry of value) {\n if (!entry || typeof entry !== \"object\") continue;\n const candidate = entry as Partial<QmdSearchResult>;\n if (\n typeof candidate.path !== \"string\" ||\n typeof candidate.score !== \"number\"\n )\n continue;\n parsed.push({\n docid: typeof candidate.docid === \"string\" ? candidate.docid : \"\",\n path: candidate.path,\n snippet: typeof candidate.snippet === \"string\" ? candidate.snippet : \"\",\n score: candidate.score,\n explain: parseQmdExplain(candidate.explain),\n transport:\n candidate.transport === \"daemon\" ||\n candidate.transport === \"subprocess\" ||\n candidate.transport === \"hybrid\" ||\n candidate.transport === \"scoped_prefilter\"\n ? candidate.transport\n : undefined,\n });\n }\n return parsed.slice(0, 32);\n}\n\nexport function mergeArtifactRecallCandidates(\n candidatesByNamespace: MemoryFile[][],\n limit: number,\n): MemoryFile[] {\n const cappedLimit = Math.max(0, limit);\n if (cappedLimit === 0) return [];\n\n const out: MemoryFile[] = [];\n const seen = new Set<string>();\n let offset = 0;\n while (out.length < cappedLimit) {\n let hasAnyCandidateAtOffset = false;\n for (const list of candidatesByNamespace) {\n if (offset >= list.length) continue;\n hasAnyCandidateAtOffset = true;\n const item = list[offset];\n const dedupeKey = `${item.frontmatter.id}:${item.frontmatter.sourceMemoryId ?? \"\"}:${item.content}`;\n if (seen.has(dedupeKey)) continue;\n seen.add(dedupeKey);\n out.push(item);\n if (out.length >= cappedLimit) break;\n }\n if (!hasAnyCandidateAtOffset) break;\n offset += 1;\n }\n return out;\n}\n\nexport function resolveRecentThreadMemoryPaths(options: {\n threadEpisodeIds: string[];\n currentMemoryId: string;\n allMemsForGraph: MemoryFile[] | null | undefined;\n pathById?: Map<string, string>;\n storageDir: string;\n maxRecent: number;\n}): string[] {\n const maxRecent = Math.max(0, options.maxRecent);\n if (options.threadEpisodeIds.length === 0 || maxRecent === 0) return [];\n const pathById =\n options.pathById ??\n buildMemoryPathById(options.allMemsForGraph, options.storageDir);\n if (pathById.size === 0) return [];\n\n // #1635 (defensive): skip pending_review ids from legacy episode sets.\n const pendingReviewIds = new Set<string>(\n (options.allMemsForGraph ?? [])\n .filter((m) => m.frontmatter.status === \"pending_review\" && m.frontmatter.id)\n .map((m) => m.frontmatter.id as string),\n );\n\n return options.threadEpisodeIds\n .filter((id) => id !== options.currentMemoryId)\n .filter((id) => !pendingReviewIds.has(id))\n .slice(-maxRecent)\n .map((id) => pathById.get(id))\n .filter((p): p is string => typeof p === \"string\" && p.length > 0);\n}\n\nexport function buildMemoryPathById(\n allMemsForGraph: MemoryFile[] | null | undefined,\n storageDir: string,\n): Map<string, string> {\n const pathById = new Map<string, string>();\n for (const mem of allMemsForGraph ?? []) {\n const id = mem.frontmatter.id;\n if (!id) continue;\n pathById.set(id, path.relative(storageDir, mem.path));\n }\n return pathById;\n}\n\nexport function appendMemoryToGraphContext(options: {\n allMemsForGraph: MemoryFile[] | null | undefined;\n storageDir: string;\n memoryRelPath: string;\n memoryId: string;\n category: MemoryFile[\"frontmatter\"][\"category\"];\n content: string;\n entityRef: string | undefined;\n}): void {\n if (!Array.isArray(options.allMemsForGraph)) return;\n\n const nowIso = new Date().toISOString();\n options.allMemsForGraph.push({\n path: path.join(options.storageDir, options.memoryRelPath),\n content: options.content,\n frontmatter: {\n id: options.memoryId,\n category: options.category,\n created: nowIso,\n updated: nowIso,\n source: \"extraction\",\n confidence: 0.8,\n confidenceTier: \"implied\",\n tags: [],\n entityRef: options.entityRef,\n status: \"active\",\n },\n });\n}\n\nexport function resolvePersistedMemoryRelativePath(options: {\n memoryId: string;\n pathById: Map<string, string>;\n category: string;\n}): string {\n const persisted = options.pathById.get(options.memoryId);\n if (persisted) return persisted;\n if (options.category === \"correction\") {\n return path.join(\"corrections\", `${options.memoryId}.md`);\n }\n // Pick the subtree that matches the StorageManager.writeMemory routing\n // so fallback paths (used before memoryPathById has seen the fresh\n // write) agree with where the file actually lives. Routing goes through\n // the shared categoryDirName() chokepoint (utils/category-dir.ts) so\n // every category — decisions/, preferences/, reasoning-traces/, ... —\n // resolves to the same dir the writer used; otherwise graph edges point\n // at the wrong subtree and graph expansion silently drops those nodes\n // when readMemoryByPath cannot resolve them (issue #564 PR 3 / #1546).\n const subtree = categoryDirName(options.category);\n const idParts = options.memoryId.split(\"-\");\n const maybeTimestamp = Number(idParts[1]);\n if (Number.isFinite(maybeTimestamp) && maybeTimestamp > 0) {\n const day = new Date(maybeTimestamp).toISOString().slice(0, 10);\n return path.join(subtree, day, `${options.memoryId}.md`);\n }\n return path.join(subtree, `${options.memoryId}.md`);\n}\n","import type { BufferTurn, ExtractionFailureClass, ExtractionResult, MetaState } from \"../types.js\";\nimport type { StorageManager } from \"../index.js\";\nimport { log } from \"../logger.js\";\n\nexport function combineExtractionAbortSignals(\n primary: AbortSignal | undefined,\n deadlineController: AbortController | undefined,\n): AbortSignal | undefined {\n if (!deadlineController) return primary;\n return primary ? AbortSignal.any([primary, deadlineController.signal]) : deadlineController.signal;\n}\n\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nexport function deriveTopicsFromExtraction(result: ExtractionResult): string[] {\n if (!isRecord(result)) return [];\n const topics = new Set<string>();\n const facts = Array.isArray(result.facts) ? result.facts : [];\n for (const rawFact of facts) {\n if (!isRecord(rawFact)) continue;\n const tags = Array.isArray(rawFact.tags) ? rawFact.tags : [];\n for (const tag of tags) {\n if (typeof tag === \"string\" && tag.length >= 2) topics.add(tag.toLowerCase());\n }\n if (typeof rawFact.entityRef === \"string\" && rawFact.entityRef.length >= 2) {\n topics.add(rawFact.entityRef.toLowerCase());\n }\n if (typeof rawFact.category === \"string\" && rawFact.category.length > 0) {\n topics.add(rawFact.category);\n }\n }\n const entities = Array.isArray(result.entities) ? result.entities : [];\n for (const rawEntity of entities) {\n if (!isRecord(rawEntity)) continue;\n if (typeof rawEntity.name === \"string\" && rawEntity.name.length >= 2) {\n topics.add(rawEntity.name.toLowerCase());\n }\n }\n return [...topics].slice(0, 16);\n}\n\n/** Bounded cap on persisted per-fingerprint retry-state entries (per namespace meta). */\nexport const EXTRACTION_RETRY_STATE_MAX_ENTRIES = 500;\n\nexport interface ExtractionRetryStateEntry {\n attempts: number;\n nextEligibleAtMs: number;\n firstFailedAtMs: number;\n lastFailureClass: ExtractionFailureClass;\n}\n\nexport interface ExtractionResilienceStatus {\n breaker: {\n state: \"closed\" | \"open\" | \"half_open\";\n openUntilMs: number;\n consecutiveFailures: number;\n lastReason: string;\n };\n backoffFingerprintCount: number;\n}\n\n/**\n * Pure backoff scheduler. Returns the absolute ms timestamp at which a\n * fingerprint that has failed `attempts` times becomes eligible again:\n * exponential via the configured schedule, clamped to `maxBackoffMs`, with\n * ±`jitterRatio` multiplicative jitter. `rng` is injectable for deterministic\n * tests. Never returns a timestamp before `now`.\n */\nexport function computeExtractionRetryNextEligibleMs(\n attempts: number,\n scheduleMs: readonly number[],\n maxBackoffMs: number,\n jitterRatio: number,\n now: number,\n rng: () => number = Math.random,\n): number {\n if (!Number.isFinite(attempts) || !Number.isInteger(attempts) || attempts < 1) {\n throw new RangeError(\"attempts must be a finite integer >= 1\");\n }\n if (!Number.isFinite(maxBackoffMs) || maxBackoffMs < 0) {\n throw new RangeError(\"maxBackoffMs must be a finite number >= 0\");\n }\n if (!Number.isFinite(jitterRatio) || jitterRatio < 0 || jitterRatio > 1) {\n throw new RangeError(\"jitterRatio must be a finite number in [0, 1]\");\n }\n const safeNow = Number.isFinite(now) ? now : 0;\n const cap = maxBackoffMs;\n if (!Array.isArray(scheduleMs) || scheduleMs.length === 0) {\n return safeNow + cap;\n }\n const idx = Math.min(attempts - 1, scheduleMs.length - 1);\n const step = scheduleMs[idx];\n const base = Math.min(typeof step === \"number\" && Number.isFinite(step) && step > 0 ? step : cap, cap);\n const randomValue = rng();\n if (!Number.isFinite(randomValue) || randomValue < 0 || randomValue > 1) {\n throw new RangeError(\"rng() must return a finite number in [0, 1]\");\n }\n const jitter = 1 + (randomValue * 2 - 1) * jitterRatio;\n return safeNow + Math.max(0, Math.round(base * jitter));\n}\n\n/**\n * Cap the persisted retry-state array to the newest `maxEntries` by\n * firstFailedAt. Guards invalid caps so they cannot turn `slice(-maxEntries)`\n * into an unbounded copy (AGENTS.md rule 17).\n */\nexport function capExtractionRetryStateEntries<T extends { firstFailedAt: string }>(\n entries: readonly T[],\n maxEntries: number,\n): T[] {\n if (!Number.isFinite(maxEntries) || !Number.isInteger(maxEntries) || maxEntries <= 0) return [];\n const sorted = [...entries].sort((a, b) => a.firstFailedAt.localeCompare(b.firstFailedAt));\n return sorted.slice(-maxEntries);\n}\n\n/**\n * Derive a single `sourceConnector` from a batch of turns.\n * Returns the connector ONLY when ALL turns carry the same connector.\n * Mixed tagged/untagged batches return undefined — extraction facts are\n * persisted at batch level, so attributing them to the single tagged\n * connector would falsely label facts from untagged turns.\n * Conflicting connectors (different values) also return undefined.\n */\nexport function deriveSourceConnector(turns: readonly BufferTurn[]): string | undefined {\n if (turns.length === 0) return undefined;\n const connectors = new Set<string>();\n let untaggedCount = 0;\n for (const turn of turns) {\n if (typeof turn.sourceConnector === \"string\" && turn.sourceConnector.length > 0) {\n connectors.add(turn.sourceConnector);\n } else {\n untaggedCount += 1;\n }\n }\n // All turns must agree on the same connector — no untagged turns mixed in.\n if (untaggedCount > 0) return undefined;\n return connectors.size === 1 ? [...connectors][0] : undefined;\n}\n\nexport async function runExtractionPostPersistBestEffort(\n runDeadlineAware: (\n operation: () => Promise<unknown>,\n phase: string,\n clearTimerOnError?: boolean,\n options?: { ignoreAbort?: boolean; ignoreDeadline?: boolean },\n ) => Promise<unknown>,\n stage: string,\n operation: () => Promise<unknown>,\n options?: { ignoreAbort?: boolean; ignoreDeadline?: boolean; propagateErrors?: boolean },\n): Promise<void> {\n try {\n await runDeadlineAware(operation, stage, false, {\n ignoreAbort: options?.ignoreAbort,\n ignoreDeadline: options?.ignoreDeadline,\n });\n } catch (error) {\n if (options?.propagateErrors) throw error;\n log.warn(`runExtraction: ${stage} failed after persistence (non-fatal)`, error);\n }\n}\n\n/**\n * Applies deferred-judge retention only to live, non-shadow extraction runs.\n * Replay/import paths must not synthesize live-buffer entries after persistence.\n */\nexport interface ExtractionDeferRetentionOptions {\n clearBufferAfterExtraction: boolean;\n extractionJudgeShadow: boolean;\n getDeferredCount: () => number;\n normalizedTurns: BufferTurn[];\n bufferKey: string;\n retainDeferredTurns: (bufferKey: string, turns: BufferTurn[], max: number) => Promise<void>;\n}\n\nexport async function runExtractionDeferRetention(\n runPostPersistBestEffort: (\n stage: string,\n operation: () => Promise<unknown>,\n options?: { ignoreAbort?: boolean },\n ) => Promise<void>,\n options: ExtractionDeferRetentionOptions,\n): Promise<void> {\n await runPostPersistBestEffort(\"during_defer_retention\", async () => {\n if (options.clearBufferAfterExtraction && !options.extractionJudgeShadow) {\n const deferredCount = options.getDeferredCount();\n if (deferredCount > 0 && options.normalizedTurns.length > 0) {\n await options.retainDeferredTurns(options.bufferKey, options.normalizedTurns, 10);\n } else {\n await options.retainDeferredTurns(options.bufferKey, [], 0);\n }\n }\n });\n}\n\nexport interface ExtractionPostPersistOptions {\n result: ExtractionResult;\n storage: StorageManager;\n meta?: MetaState;\n extractionFingerprint?: string;\n shouldPersistProcessedFingerprint: boolean;\n recordProcessedExtractionFingerprint: (\n storage: StorageManager,\n fingerprint: string,\n meta: MetaState,\n ) => Promise<void>;\n runDeadlineAware: (\n operation: () => Promise<unknown>,\n phase: string,\n clearTimerOnError?: boolean,\n options?: { ignoreAbort?: boolean; ignoreDeadline?: boolean },\n ) => Promise<unknown>;\n isDeadlineError: (error: unknown) => boolean;\n createDeadlineError: (stage: string) => Error;\n deadlineMs?: number;\n clearBufferAfterExtraction: boolean;\n runPostPersistBestEffort: (\n stage: string,\n operation: () => Promise<unknown>,\n options?: { ignoreAbort?: boolean; ignoreDeadline?: boolean; propagateErrors?: boolean },\n ) => Promise<void>;\n extractionJudgeShadow: boolean;\n getDeferredCount: () => number;\n normalizedTurns: BufferTurn[];\n bufferKey: string;\n retainDeferredTurns: (bufferKey: string, turns: BufferTurn[], max: number) => Promise<void>;\n clearBuffer: (options?: { ignoreAbort?: boolean }) => Promise<void>;\n failOnExtractionFailure: boolean;\n}\n\nexport interface ExtractionPostPersistResult {\n meta?: MetaState;\n metadataFailed: boolean;\n}\n\nexport async function runExtractionPostPersist(\n options: ExtractionPostPersistOptions,\n): Promise<ExtractionPostPersistResult> {\n let metadataFailed = false;\n let deadlineError: Error | undefined;\n const recordFailure = (stage: string, error: unknown): void => {\n metadataFailed = true;\n if (options.isDeadlineError(error) && deadlineError === undefined) {\n deadlineError = error as Error;\n }\n log.warn(`runExtraction: ${stage} failed after durable persistence; continuing with buffer clear`, error);\n };\n let meta = options.meta;\n try {\n meta ??= (await options.runDeadlineAware(\n () => options.storage.loadMeta(),\n \"during_post_persist_load_meta\",\n false,\n )) as MetaState;\n } catch (error) {\n recordFailure(\"metadata load\", error);\n }\n if (meta && options.extractionFingerprint && options.shouldPersistProcessedFingerprint) {\n try {\n await options.runDeadlineAware(\n () => options.recordProcessedExtractionFingerprint(options.storage, options.extractionFingerprint!, meta!),\n \"during_post_persist_fingerprint\",\n false,\n );\n } catch (error) {\n recordFailure(\"processed fingerprint\", error);\n }\n }\n if (meta) {\n meta.extractionCount += 1;\n meta.lastExtractionAt = new Date().toISOString();\n meta.totalMemories += Array.isArray(options.result.facts) ? options.result.facts.length : 0;\n meta.totalEntities += Array.isArray(options.result.entities) ? options.result.entities.length : 0;\n try {\n await options.runDeadlineAware(\n () => options.storage.saveMeta(meta!),\n \"during_post_persist_meta_save\",\n false,\n );\n } catch (error) {\n recordFailure(\"metadata save\", error);\n }\n }\n const runBestEffort = options.runPostPersistBestEffort;\n await runExtractionDeferRetention(runBestEffort, {\n clearBufferAfterExtraction: options.clearBufferAfterExtraction,\n extractionJudgeShadow: options.extractionJudgeShadow,\n getDeferredCount: options.getDeferredCount,\n normalizedTurns: options.normalizedTurns,\n bufferKey: options.bufferKey,\n retainDeferredTurns: options.retainDeferredTurns,\n });\n await runBestEffort(\n \"during_buffer_clear\",\n () => options.clearBuffer({ ignoreAbort: true }),\n {\n ignoreAbort: true,\n ignoreDeadline: options.failOnExtractionFailure,\n propagateErrors: options.failOnExtractionFailure,\n },\n );\n if (options.failOnExtractionFailure && typeof options.deadlineMs === \"number\" && Date.now() >= options.deadlineMs) {\n throw options.createDeadlineError(\"during_buffer_clear\");\n }\n if (deadlineError) throw deadlineError;\n return { meta, metadataFailed };\n}\n\n/**\n * Record a processed fingerprint when applicable and advance the extraction\n * liveness watermark only for a provider-backed empty success. Fingerprinted\n * imports treat the metadata save as load-bearing dedupe state; normal live\n * runs treat the stamp as diagnostic and fail open. Deadline errors always\n * propagate.\n */\nexport async function commitEmptySuccessExtraction(args: {\n storage: StorageManager;\n meta: MetaState | null;\n extractionFingerprint: string | null;\n shouldPersistProcessedFingerprint: boolean;\n hasExtractionFailure: boolean;\n extractionSkippedReason: ExtractionResult[\"extractionSkippedReason\"];\n recordProcessedExtractionFingerprint: (storage: StorageManager, fingerprint: string, meta: MetaState) => Promise<unknown>;\n runDeadlineAware: <T>(operation: () => Promise<T>, phase: string, clearTimerOnError?: boolean) => Promise<T>;\n isDeadlineError: (error: unknown) => boolean;\n}): Promise<void> {\n const {\n storage,\n meta: existingMeta,\n extractionFingerprint,\n shouldPersistProcessedFingerprint,\n hasExtractionFailure,\n extractionSkippedReason,\n recordProcessedExtractionFingerprint,\n runDeadlineAware,\n isDeadlineError,\n } = args;\n const shouldRecordFingerprint =\n extractionFingerprint !== null &&\n shouldPersistProcessedFingerprint &&\n !hasExtractionFailure;\n const shouldStampLiveness =\n !hasExtractionFailure && extractionSkippedReason === undefined;\n if (!shouldRecordFingerprint && !shouldStampLiveness) return;\n\n const metadataFailureIsFatal = shouldRecordFingerprint;\n try {\n const meta =\n existingMeta ??\n await runDeadlineAware(\n () => storage.loadMeta(),\n \"during_empty_success_liveness_load\",\n false,\n );\n if (shouldRecordFingerprint) {\n await recordProcessedExtractionFingerprint(storage, extractionFingerprint, meta);\n }\n if (shouldStampLiveness) {\n meta.extractionCount += 1;\n meta.lastExtractionAt = new Date().toISOString();\n }\n await runDeadlineAware(\n () => storage.saveMeta(meta),\n \"during_empty_success_liveness_save\",\n false,\n );\n } catch (err) {\n if (isDeadlineError(err)) throw err;\n if (metadataFailureIsFatal) throw err;\n log.warn(\"runExtraction: failed to stamp empty-success liveness watermark (non-fatal)\", err);\n }\n}\n","/**\n * Extraction-run coordinator — extracted from the orchestrator\n * (issue #1526, seam 15).\n *\n * Owns the buffer→extract→persist pipeline orchestration:\n * - `runExtraction` — the main extraction pipeline coordinator\n * (normalize → threshold gate → namespace resolve → dedupe\n * fingerprint → extract → validate → persist → post-write hooks)\n * - dedupe support: `shouldQueueExtraction`,\n * `buildExtractionFingerprint`, `normalizeExtractionFingerprintTurns`\n * - `recordProcessedExtractionFingerprint` — meta recording\n *\n * The orchestrator constructs one instance and delegates the extraction\n * run to it. `persistExtraction`, `maybeCapturePassiveCorrections`, and\n * all post-write side-effect helpers arrive as injectable delegates so\n * the orchestrator keeps ownership of cross-subsystem routing and the\n * behavior-critical chokepoints it hosts.\n *\n * Behavior-preserving move from orchestrator.ts. No logic changes — the\n * orchestrator keeps thin delegating methods so existing call sites\n * and tests that exercise the public API continue to work.\n */\n\nimport { createHash } from \"node:crypto\";\nimport type { StorageManager } from \"../index.js\";\nimport { NamespaceStorageRouter } from \"../namespaces/storage.js\";\nimport type { ExtractionEngine } from \"../extraction.js\";\nimport type { SmartBuffer } from \"../buffer.js\";\nimport type { ThreadingManager } from \"../threading.js\";\nimport type { BoxBuilder } from \"../boxes.js\";\nimport { resolvePrincipal, defaultNamespaceForPrincipal } from \"../namespaces/principal.js\";\nimport { resolveScopeProfilePlan, type ResolvedScopeProfilePlan } from \"../namespaces/scope-profiles.js\";\nimport { resolveCodingNamespaceOverlay } from \"../coding/coding-namespace.js\";\nimport type { CodingContext } from \"../types.js\";\nimport {\n resolvePresentationCapabilities,\n resolveMemoryLifecycleCapabilities,\n type GraphConstructionCapabilitySet,\n type MemoryLifecycleCapabilitySet,\n} from \"../capabilities.js\";\nimport { parseFlexibleIsoTimestamp } from \"../utils/iso-timestamp.js\";\nimport { log } from \"../logger.js\";\nimport type { PluginConfig, BufferTurn, ExtractionResult, MetaState, ExtractionFailureClass } from \"../types.js\";\nimport type { TierMigrationCycleSummary } from \"../recall-state.js\";\n\nexport interface ExtractionRunResult {\n status: \"completed\" | \"skipped\";\n reason?: string;\n persistedCount: number;\n durableOutputCount: number;\n postPersistMetadataFailed?: boolean;\n}\n\nexport class ExtractionDeadlineError extends Error {\n readonly stage: string;\n\n constructor(stage: string) {\n super(`replay extraction deadline exceeded (${stage})`);\n this.name = \"ExtractionDeadlineError\";\n this.stage = stage;\n }\n}\n\n\n/** Dependencies injected by the orchestrator. All stable references or\n * live accessors — lazy getters for anything tests reassign\n * post-construction (buffer, extraction, storageRouter, threading). */\nexport interface ExtractionRunCoordinatorDeps {\n config: PluginConfig;\n getBuffer: () => SmartBuffer;\n getExtraction: () => Pick<ExtractionEngine, \"extract\">;\n getStorageRouter: () => Pick<NamespaceStorageRouter, \"storageFor\">;\n getThreading: () => Pick<ThreadingManager, \"processTurn\" | \"updateThreadTitle\">;\n\n persistExtraction: (\n result: ExtractionResult,\n storage: StorageManager,\n threadIdForExtraction?: string | null,\n sourceContext?: { sessionKey?: string; principal?: string; validAt?: string; sourceConnector?: string },\n baseNamespace?: string,\n scopeProfileWritePlan?: ResolvedScopeProfilePlan | null,\n sourceText?: string,\n graphCaps?: GraphConstructionCapabilitySet,\n lifecycleCaps?: MemoryLifecycleCapabilitySet\n ) => Promise<{ persistedIds: string[]; memoryPathById: Map<string, string> }>;\n\n maybeCapturePassiveCorrections: (\n turns: readonly BufferTurn[],\n opts: {\n sessionKey: string;\n principal?: string;\n namespace: string;\n bufferKey: string;\n isLiveSession: boolean;\n abortSignal?: AbortSignal;\n }\n ) => Promise<void>;\n\n resolveSelfNamespace: (sessionKey?: string) => string;\n getCodingContextForSession: (sessionKey: string) => CodingContext | null;\n applyCodingNamespaceOverlay: (sessionKey: string, namespace: string) => string;\n boxBuilderFor: (storage: StorageManager) => Pick<BoxBuilder, \"onExtraction\">;\n appendPersistedThreadEpisodes: (threadId: string, ids: string[]) => Promise<void>;\n maybeScheduleConsolidation: (nonZero: boolean) => void;\n requestQmdMaintenance: () => void;\n runTierMigrationCycle: (\n storage: StorageManager,\n trigger: \"extraction\" | \"maintenance\" | \"manual\",\n options?: {\n dryRun?: boolean;\n limitOverride?: number;\n force?: boolean;\n }\n ) => Promise<TierMigrationCycleSummary>;\n getLastPersistExtractionDeferredCount: () => number;\n recordProcessedExtractionFingerprint: (\n storage: StorageManager,\n fingerprint: string,\n preloadedMeta?: Awaited<ReturnType<StorageManager[\"loadMeta\"]>>\n ) => Promise<void>;\n}\n\n// Recall/extraction abort helpers live in orchestrator-helpers.ts since\n// #1526 seam 25; this file previously carried duplicate copies\n// (AGENTS.md rule 8 — no duplicated helpers).\nimport { raceRecallAbort, throwIfRecallAborted } from \"./orchestrator-helpers.js\";\nimport {\n capExtractionRetryStateEntries,\n combineExtractionAbortSignals,\n commitEmptySuccessExtraction,\n computeExtractionRetryNextEligibleMs,\n deriveSourceConnector,\n deriveTopicsFromExtraction,\n runExtractionPostPersist,\n runExtractionPostPersistBestEffort,\n EXTRACTION_RETRY_STATE_MAX_ENTRIES,\n} from \"./extraction-run-helpers.js\";\nimport type { ExtractionResilienceStatus, ExtractionRetryStateEntry } from \"./extraction-run-helpers.js\";\n\nexport {\n capExtractionRetryStateEntries,\n computeExtractionRetryNextEligibleMs,\n deriveSourceConnector,\n deriveTopicsFromExtraction,\n};\nexport type { ExtractionResilienceStatus };\n\n/**\n * Coordinates the extraction run pipeline. Holds the dedupe fingerprint\n * cache (`recentExtractionFingerprints`) and delegates all side effects\n * to injected orchestrator methods.\n */\nexport class ExtractionRunCoordinator {\n private readonly recentExtractionFingerprints = new Map<string, number>();\n // Per-fingerprint extraction retry/backoff state (extraction hot-loop\n // hardening). Outer key = namespace, inner key = fingerprint. Hydrated lazily\n // from namespace-scoped meta so the hot path is a Map lookup; persisted back\n // to meta on change (restart-safe, cross-process coherent via the shared\n // meta.json). The breaker below is intentionally per-process in-memory\n // (mirrors local-llm.cooldownUntilMs); a restart clears it but the persisted\n // backoff still throttles, so a restart can't resurrect the hot loop.\n private readonly extractionRetryState = new Map<string, Map<string, ExtractionRetryStateEntry>>();\n private readonly hydratedRetryNamespaces = new Set<string>();\n private providerBreaker: {\n consecutiveFailures: number;\n openUntilMs: number;\n state: \"closed\" | \"open\" | \"half_open\";\n lastReason: string;\n } = { consecutiveFailures: 0, openUntilMs: 0, state: \"closed\", lastReason: \"\" };\n\n constructor(private readonly deps: ExtractionRunCoordinatorDeps) {}\n\n private get config(): PluginConfig {\n return this.deps.config;\n }\n\n // -------------------------------------------------------------------------\n // Source-valid-at helpers (moved from orchestrator.ts module scope)\n // -------------------------------------------------------------------------\n\n private latestSourceValidAtFromTurns(turns: readonly BufferTurn[]): string | undefined {\n let latestMs: number | null = null;\n for (const turn of turns) {\n if (turn.extractionContextOnly === true) continue;\n if (typeof turn.sourceValidAt !== \"string\") continue;\n const parsed = parseFlexibleIsoTimestamp(turn.sourceValidAt.trim());\n if (parsed === null) continue;\n if (latestMs === null || parsed > latestMs) {\n latestMs = parsed;\n }\n }\n return latestMs === null ? undefined : new Date(latestMs).toISOString();\n }\n\n // -------------------------------------------------------------------------\n // Extraction dedupe fingerprint helpers\n // -------------------------------------------------------------------------\n\n normalizeExtractionFingerprintTurns(turns: BufferTurn[]): string[] {\n if (!Array.isArray(turns) || turns.length === 0) return [];\n return turns\n .filter((turn) => turn.role === \"user\" || turn.role === \"assistant\")\n .map((turn) => {\n if (typeof turn.turnFingerprint === \"string\" && turn.turnFingerprint.length > 0) {\n return `fp:${turn.turnFingerprint}`;\n }\n return `${turn.role}:${(turn.content ?? \"\").replace(/\\s+/g, \" \").trim().slice(0, this.config.extractionMaxTurnChars)}`;\n })\n .filter((value) => value.length > 0);\n }\n\n buildExtractionFingerprint(turns: BufferTurn[], bufferKey: string): string | null {\n const normalized = this.normalizeExtractionFingerprintTurns(turns).join(\"\\n\");\n if (!normalized) return null;\n return createHash(\"sha256\").update(`${bufferKey}\\n${normalized}`).digest(\"hex\");\n }\n\n shouldQueueExtraction(turns: BufferTurn[], options: { commit?: boolean; bufferKey?: string } = {}): boolean {\n const lifecycleCaps = resolveMemoryLifecycleCapabilities(this.config);\n if (!lifecycleCaps.extractionDedupe) return true;\n if (!Array.isArray(turns) || turns.length === 0) return false;\n\n const bufferKey = options.bufferKey ?? turns[0]?.sessionKey ?? \"default\";\n const fingerprint = this.buildExtractionFingerprint(turns, bufferKey);\n if (!fingerprint) return false;\n const now = Date.now();\n const seenAt = this.recentExtractionFingerprints.get(fingerprint);\n if (seenAt && now - seenAt < this.config.extractionDedupeWindowMs) {\n log.debug(\"extraction dedupe: skipped duplicate buffered turn set\");\n return false;\n }\n\n if (options.commit !== false) {\n this.recentExtractionFingerprints.set(fingerprint, now);\n }\n // Keep this cache bounded to avoid unbounded growth.\n if (options.commit !== false && this.recentExtractionFingerprints.size > 200) {\n const entries = Array.from(this.recentExtractionFingerprints.entries()).sort((a, b) => a[1] - b[1]);\n for (const [key] of entries.slice(0, entries.length - 200)) {\n this.recentExtractionFingerprints.delete(key);\n }\n }\n\n return true;\n }\n\n // -------------------------------------------------------------------------\n // Processed-fingerprint recording\n // -------------------------------------------------------------------------\n\n async recordProcessedExtractionFingerprint(\n storage: StorageManager,\n fingerprint: string,\n preloadedMeta?: Awaited<ReturnType<StorageManager[\"loadMeta\"]>>\n ): Promise<void> {\n const meta = preloadedMeta ?? (await storage.loadMeta());\n const observedAt = new Date().toISOString();\n const seen = new Map(\n (meta.processedExtractionFingerprints ?? []).map((entry) => [entry.fingerprint, entry.observedAt])\n );\n seen.set(fingerprint, observedAt);\n meta.processedExtractionFingerprints = Array.from(seen.entries())\n .map(([value, at]) => ({ fingerprint: value, observedAt: at }))\n .sort((left, right) => left.observedAt.localeCompare(right.observedAt))\n .slice(-500);\n if (!preloadedMeta) {\n await storage.saveMeta(meta);\n }\n }\n\n // -------------------------------------------------------------------------\n // Extraction retry/backoff + circuit breaker (extraction hot-loop hardening)\n // -------------------------------------------------------------------------\n\n /** Lazily hydrate the in-memory retry-state mirror for a namespace from meta.\n * One-time per namespace per coordinator; the hot path is then a Map lookup.\n * Cross-process coherence: a fresh coordinator hydrates from the shared\n * meta.json, so a failure persisted by another process is honored here. */\n private hydrateRetryStateFromMeta(namespace: string, meta: MetaState): void {\n if (this.hydratedRetryNamespaces.has(namespace)) return;\n this.hydratedRetryNamespaces.add(namespace);\n const nsMap = this.extractionRetryState.get(namespace) ?? new Map<string, ExtractionRetryStateEntry>();\n for (const entry of meta.extractionRetryState ?? []) {\n const nextEligibleAtMs = Date.parse(entry.nextEligibleAt);\n const firstFailedAtMs = Date.parse(entry.firstFailedAt);\n nsMap.set(entry.fingerprint, {\n attempts: entry.attempts,\n nextEligibleAtMs: Number.isFinite(nextEligibleAtMs) ? nextEligibleAtMs : 0,\n firstFailedAtMs: Number.isFinite(firstFailedAtMs) ? firstFailedAtMs : Date.now(),\n lastFailureClass: entry.lastFailureClass,\n });\n }\n this.extractionRetryState.set(namespace, nsMap);\n }\n\n private logBreakerTransition(state: \"closed\" | \"open\" | \"half_open\"): void {\n // Once per state change (not per attempt) — AGENTS.md observability rule.\n log.warn(\"extraction: provider circuit breaker transition\", {\n state,\n consecutiveFailures: this.providerBreaker.consecutiveFailures,\n lastReason: this.providerBreaker.lastReason,\n openUntilMs: this.providerBreaker.openUntilMs,\n });\n }\n\n /** True while the breaker suppresses non-forced attempts. Flips an expired\n * `open` breaker to `half_open`, which allows exactly one probe (the next\n * non-forced attempt) because the extraction queue is a serial drain. */\n private isProviderBreakerOpen(now: number): boolean {\n if (now < this.providerBreaker.openUntilMs) return true;\n if (this.providerBreaker.state === \"open\") {\n this.providerBreaker.state = \"half_open\";\n this.logBreakerTransition(\"half_open\");\n }\n return false;\n }\n\n private onProviderFailure(cls: ExtractionFailureClass, now: number): void {\n this.providerBreaker.consecutiveFailures += 1;\n const trip =\n cls === \"auth_config\" ||\n // A failed half-open probe re-opens immediately (standard breaker\n // semantics). Without this, an auth_config-opened breaker (which trips\n // below the threshold) would get stuck half_open after a transient\n // probe failure and stop suppressing (cursor review).\n this.providerBreaker.state === \"half_open\" ||\n this.providerBreaker.consecutiveFailures >= this.config.extractionBreakerFailureThreshold;\n if (!trip) return;\n const cooldown =\n cls === \"auth_config\"\n ? this.config.extractionBreakerAuthCooldownMs\n : this.config.extractionBreakerCooldownMs;\n this.providerBreaker.openUntilMs = now + Math.max(0, cooldown);\n this.providerBreaker.lastReason = cls;\n if (this.providerBreaker.state !== \"open\") {\n this.providerBreaker.state = \"open\";\n this.logBreakerTransition(\"open\");\n }\n }\n\n private resetProviderBreakerOnSuccess(): void {\n const wasDisturbed =\n this.providerBreaker.state !== \"closed\" ||\n this.providerBreaker.consecutiveFailures > 0 ||\n this.providerBreaker.openUntilMs > 0;\n if (!wasDisturbed) return;\n const wasOpen = this.providerBreaker.state !== \"closed\";\n this.providerBreaker.consecutiveFailures = 0;\n this.providerBreaker.openUntilMs = 0;\n this.providerBreaker.lastReason = \"\";\n this.providerBreaker.state = \"closed\";\n if (wasOpen) this.logBreakerTransition(\"closed\");\n }\n\n /** Rebuild `meta.extractionRetryState` from the in-memory namespace mirror,\n * bounded to the newest entries, and prune the mirror to match. */\n private persistRetryStateToMeta(namespace: string, meta: MetaState): void {\n const nsMap = this.extractionRetryState.get(namespace);\n const entries = nsMap\n ? Array.from(nsMap.entries()).map(([fingerprint, st]) => ({\n fingerprint,\n attempts: st.attempts,\n nextEligibleAt: new Date(st.nextEligibleAtMs).toISOString(),\n firstFailedAt: new Date(st.firstFailedAtMs).toISOString(),\n lastFailureClass: st.lastFailureClass,\n }))\n : [];\n const capped = capExtractionRetryStateEntries(entries, EXTRACTION_RETRY_STATE_MAX_ENTRIES);\n meta.extractionRetryState = capped;\n if (nsMap && capped.length < nsMap.size) {\n const kept = new Set(capped.map((e) => e.fingerprint));\n for (const key of Array.from(nsMap.keys())) {\n if (!kept.has(key)) nsMap.delete(key);\n }\n }\n }\n /** Record an extraction failure into per-fingerprint backoff state + breaker,\n * persisting to namespace meta. Fail-open: never throws upward. */\n private async recordExtractionFailure(\n storage: StorageManager,\n namespace: string,\n fingerprint: string,\n cls: ExtractionFailureClass,\n meta: MetaState,\n now: number,\n ): Promise<void> {\n try {\n this.hydrateRetryStateFromMeta(namespace, meta);\n const nsMap = this.extractionRetryState.get(namespace) ?? new Map<string, ExtractionRetryStateEntry>();\n const prev = nsMap.get(fingerprint);\n const attempts = (prev?.attempts ?? 0) + 1;\n const firstFailedAtMs = prev?.firstFailedAtMs ?? now;\n let nextEligibleAtMs: number;\n if (cls === \"parse_empty\" && attempts > this.config.extractionParseEmptyMaxAttempts) {\n // parse_empty exhausted its attempt budget → long-park (still never\n // marked processed). A dead gateway also yields unparseable output.\n nextEligibleAtMs = now + Math.max(0, this.config.extractionRetryMaxBackoffMs);\n } else {\n nextEligibleAtMs = computeExtractionRetryNextEligibleMs(\n attempts,\n this.config.extractionRetryScheduleMs,\n this.config.extractionRetryMaxBackoffMs,\n this.config.extractionRetryJitterRatio,\n now,\n );\n }\n nsMap.set(fingerprint, { attempts, nextEligibleAtMs, firstFailedAtMs, lastFailureClass: cls });\n this.extractionRetryState.set(namespace, nsMap);\n this.onProviderFailure(cls, now);\n this.persistRetryStateToMeta(namespace, meta);\n await storage.saveMeta(meta);\n } catch (err) {\n // Fail-open: recording failure state must never crash observe/recall.\n log.warn(\"runExtraction: failed to record extraction retry state (non-fatal)\", err);\n }\n }\n\n /** Delete a fingerprint's retry entry from the mirror + meta. Returns whether\n * meta changed (so the caller can decide to persist). Does not touch the\n * breaker — callers pair this with `resetProviderBreakerOnSuccess`. */\n private clearExtractionRetryEntry(namespace: string, fingerprint: string, meta: MetaState): boolean {\n const nsMap = this.extractionRetryState.get(namespace);\n if (!nsMap?.has(fingerprint)) return false;\n nsMap.delete(fingerprint);\n this.persistRetryStateToMeta(namespace, meta);\n return true;\n }\n\n /** Live in-process resilience snapshot (breaker + backoff population). */\n getExtractionResilienceStatus(): ExtractionResilienceStatus {\n let backoffFingerprintCount = 0;\n for (const nsMap of this.extractionRetryState.values()) {\n backoffFingerprintCount += nsMap.size;\n }\n return {\n breaker: {\n state: this.providerBreaker.state,\n openUntilMs: this.providerBreaker.openUntilMs,\n consecutiveFailures: this.providerBreaker.consecutiveFailures,\n lastReason: this.providerBreaker.lastReason,\n },\n backoffFingerprintCount,\n };\n }\n\n // -------------------------------------------------------------------------\n // Main extraction pipeline\n // -------------------------------------------------------------------------\n\n async runExtraction(\n turns: BufferTurn[],\n options: {\n clearBufferAfterExtraction?: boolean;\n clearMatchingTurns?: boolean;\n skipCharThreshold?: boolean;\n skipUserTurnThreshold?: boolean;\n deadlineMs?: number;\n bufferKey?: string;\n abortSignal?: AbortSignal;\n failOnExtractionFailure?: boolean;\n /**\n * Called immediately after durable extraction persistence returns, before\n * any metadata, retention, or helper work. Lifecycle callers use this\n * as the write-rate-limit commit boundary.\n */\n onDurableCommit?: () => void;\n /**\n * Explicit namespace override for the write path (#460). When set, this\n * is the namespace where extraction writes go instead of the one derived\n * from `defaultNamespaceForPrincipal(resolvePrincipal(sessionKey))`.\n * The resolved `principal` is still threaded into memory metadata for\n * provenance; only the storage target is overridden.\n */\n writeNamespaceOverride?: string;\n /**\n * Pin the provenance principal instead of deriving it from\n * `resolvePrincipal(sessionKey)`. When set, this is the identity an\n * access surface already authenticated; used so observed-turn provenance\n * is correct even though `turn.sessionKey` is the original key.\n */\n principalOverride?: string;\n /**\n * Access scope resolution may already have selected a profile while the\n * session context remains intentionally unbound. Reuse that plan for\n * persistence instead of deriving it from shared session state.\n */\n scopeProfileWritePlan?: ResolvedScopeProfilePlan | null;\n /**\n * Force the extractor call, bypassing the retry-backoff / circuit-breaker\n * gate (extraction hot-loop hardening). Set by explicit flush paths.\n */\n forceExtractionAttempt?: boolean;\n } = {}\n ): Promise<ExtractionRunResult> {\n log.debug(`running extraction on ${turns.length} turns`);\n const clearBufferAfterExtraction = options.clearBufferAfterExtraction ?? true;\n const clearMatchingTurns = options.clearMatchingTurns === true;\n const skipCharThreshold = options.skipCharThreshold ?? false;\n const skipUserTurnThreshold = options.skipUserTurnThreshold ?? false;\n const deadlineMs =\n typeof options.deadlineMs === \"number\" && Number.isFinite(options.deadlineMs) ? options.deadlineMs : undefined;\n const bufferKey = options.bufferKey ?? turns[0]?.sessionKey ?? \"default\";\n const throwIfDeadlineExceeded = (stage: string): void => {\n if (typeof deadlineMs === \"number\" && Date.now() >= deadlineMs) {\n throw new ExtractionDeadlineError(stage);\n }\n };\n const throwIfAborted = (stage: string): void => {\n throwIfRecallAborted(options.abortSignal, `extraction aborted (${stage})`);\n };\n const runPassiveCapture = async (\n captureTurns: readonly BufferTurn[],\n captureOptions: {\n sessionKey: string;\n principal?: string;\n namespace: string;\n bufferKey: string;\n isLiveSession: boolean;\n abortSignal?: AbortSignal;\n },\n ): Promise<void> => {\n const deadlineController =\n typeof deadlineMs === \"number\" && Number.isFinite(deadlineMs) ? new AbortController() : undefined;\n const captureSignal = combineExtractionAbortSignals(captureOptions.abortSignal ?? options.abortSignal,\n deadlineController);\n let deadlineTimer: NodeJS.Timeout | undefined;\n if (deadlineController && typeof deadlineMs === \"number\") {\n const scheduleDeadlineAbort = (): void => {\n const remainingMs = deadlineMs - Date.now();\n if (remainingMs <= 0) {\n deadlineController.abort();\n return;\n }\n deadlineTimer = setTimeout(\n () => {\n if (Date.now() >= deadlineMs) {\n deadlineController.abort();\n } else {\n scheduleDeadlineAbort();\n }\n },\n Math.min(remainingMs, 2_147_483_647),\n );\n };\n scheduleDeadlineAbort();\n }\n try {\n await raceRecallAbort(\n this.deps.maybeCapturePassiveCorrections(captureTurns, {\n ...captureOptions,\n ...(captureSignal ? { abortSignal: captureSignal } : {}),\n }),\n captureSignal,\n \"extraction aborted (during_passive_capture)\",\n );\n } catch (error) {\n if (typeof deadlineMs === \"number\" && Date.now() >= deadlineMs) {\n throw new ExtractionDeadlineError(\"during_passive_capture\");\n }\n throw error;\n } finally {\n if (deadlineTimer) clearTimeout(deadlineTimer);\n }\n };\n const clearBuffer = async (options?: { ignoreAbort?: boolean }) => {\n if (options?.ignoreAbort !== true) {\n throwIfDeadlineExceeded(\"before_clear_buffer\");\n throwIfAborted(\"before_clear_buffer\");\n }\n if (clearBufferAfterExtraction) {\n await this.deps\n .getBuffer()\n .clearAfterExtraction(bufferKey, turns, clearMatchingTurns ? { allowNonPrefix: true } : undefined);\n }\n };\n\n // Skip extraction for cron job sessions - these are system operations, not user conversations\n const sessionKey = turns[0]?.sessionKey ?? \"\";\n if (sessionKey.includes(\":cron:\")) {\n log.debug(`skipping extraction for cron session: ${sessionKey}`);\n await clearBuffer();\n return {\n status: \"skipped\",\n reason: \"cron_session\",\n persistedCount: 0,\n durableOutputCount: 0,\n };\n }\n\n const normalizedTurns = turns\n .filter((t) => (t.role === \"user\" || t.role === \"assistant\") && typeof t.content === \"string\")\n .map((t) => ({\n ...t,\n content: t.content.trim().slice(0, this.config.extractionMaxTurnChars),\n }))\n .filter((t) => t.content.length > 0);\n const targetTurns = normalizedTurns.filter((turn) => turn.extractionContextOnly !== true);\n if (targetTurns.length === 0) {\n log.debug(\"skipping extraction: no non-context turns after normalization\");\n // Context-only turns may still contain corrections (review: \"context-only\n // turns skip capture\"). Scan normalizedTurns before clearing the buffer.\n if (normalizedTurns.length > 0) {\n throwIfDeadlineExceeded(\"before_context_only_capture\");\n const capturePrincipal =\n typeof options.principalOverride === \"string\" && options.principalOverride.length > 0\n ? options.principalOverride\n : resolvePrincipal(sessionKey, this.config);\n const captureNamespace =\n typeof options.writeNamespaceOverride === \"string\" && options.writeNamespaceOverride.length > 0\n ? options.writeNamespaceOverride\n : this.deps.resolveSelfNamespace(sessionKey);\n await runPassiveCapture(normalizedTurns as BufferTurn[], {\n sessionKey,\n principal: capturePrincipal,\n namespace: captureNamespace,\n bufferKey,\n isLiveSession: clearBufferAfterExtraction,\n });\n throwIfDeadlineExceeded(\"before_context_only_clear\");\n }\n await clearBuffer();\n return { status: \"skipped\", reason: \"empty_normalized_turns\", persistedCount: 0, durableOutputCount: 0 };\n }\n const sourceValidAt = this.latestSourceValidAtFromTurns(targetTurns);\n throwIfDeadlineExceeded(\"before_extract\");\n throwIfAborted(\"before_extract\");\n\n const userTurns = targetTurns.filter((t) => t.role === \"user\");\n const totalChars = targetTurns.reduce((sum, t) => sum + t.content.length, 0);\n const belowCharThreshold = totalChars < this.config.extractionMinChars;\n const belowUserTurnThreshold = !skipUserTurnThreshold && userTurns.length < this.config.extractionMinUserTurns;\n if ((!skipCharThreshold && belowCharThreshold) || belowUserTurnThreshold) {\n log.debug(`skipping extraction: below threshold (totalChars=${totalChars}, userTurns=${userTurns.length})`);\n // Passive correction capture runs even when extraction is skipped for\n // being below the char/user-turn threshold (review: \"skipped extraction\n // skips capture\"). A short correction like \"stop using Vim\" is under\n // extractionMinChars but is exactly the high-value case this feature\n // exists for. The write namespace resolves through the SAME scope-profile\n // plan as the full extraction path so corrections target the active\n // profile's write layer, not just resolveSelfNamespace (review:\n // \"below-threshold wrong namespace\"). The ACL in passiveCorrectionService\n // authorizes the actual plan/apply.\n {\n const capturePrincipal =\n typeof options.principalOverride === \"string\" && options.principalOverride.length > 0\n ? options.principalOverride\n : resolvePrincipal(sessionKey, this.config);\n const captureWO =\n typeof options.writeNamespaceOverride === \"string\" && options.writeNamespaceOverride.length > 0\n ? options.writeNamespaceOverride\n : undefined;\n const captureCodingCtx = sessionKey ? this.deps.getCodingContextForSession(sessionKey) : null;\n const captureCodingOv = resolveCodingNamespaceOverlay(\n captureCodingCtx,\n this.config.codingMode,\n this.config.defaultNamespace\n );\n const captureScopePlan = resolveScopeProfilePlan({\n config: this.config,\n principal: capturePrincipal,\n codingContext: captureCodingCtx,\n codingOverlay: captureCodingOv,\n });\n const captureNamespace =\n captureWO ?? captureScopePlan?.writeNamespace ?? this.deps.resolveSelfNamespace(sessionKey);\n await runPassiveCapture(normalizedTurns as BufferTurn[], {\n sessionKey,\n principal: capturePrincipal,\n namespace: captureNamespace,\n bufferKey,\n isLiveSession: clearBufferAfterExtraction,\n });\n }\n await clearBuffer();\n return {\n status: \"skipped\",\n reason: \"below_threshold\",\n persistedCount: 0,\n durableOutputCount: 0,\n };\n }\n\n // Provenance principal honours the access-surface override (#1495 thread 1,\n // mirroring the recall path's `principalOverride`, issue #570 PR 4). Access\n // surfaces that authenticated the caller at the transport layer pass their\n // resolved principal so provenance uses the SAME identity the surface\n // authorized, instead of `resolvePrincipal(sessionKey)` — which on a\n // namespace-prefixed key would collapse to `default`. The ORIGINAL,\n // un-prefixed session key still drives threading.\n const principal =\n typeof options.principalOverride === \"string\" && options.principalOverride.length > 0\n ? options.principalOverride\n : resolvePrincipal(sessionKey, this.config);\n // Write path — explicit callers still win. Otherwise, an active hosted\n // scope profile owns the extraction write target so hook-captured turns land\n // in the same layer that profile recall searches. Without a profile, preserve\n // the existing coding-agent overlay behavior (issue #569).\n const explicitWriteNamespace =\n typeof options.writeNamespaceOverride === \"string\" && options.writeNamespaceOverride.length > 0\n ? options.writeNamespaceOverride\n : undefined;\n const codingContextForWrite = sessionKey ? this.deps.getCodingContextForSession(sessionKey) : null;\n const codingOverlayForWrite = resolveCodingNamespaceOverlay(\n codingContextForWrite,\n this.config.codingMode,\n this.config.defaultNamespace\n );\n const scopeProfileGatePlan =\n options.scopeProfileWritePlan !== undefined\n ? options.scopeProfileWritePlan\n : resolveScopeProfilePlan({\n config: this.config,\n principal,\n codingContext: codingContextForWrite,\n codingOverlay: codingOverlayForWrite,\n });\n const scopeProfileWritePlan =\n explicitWriteNamespace && options.scopeProfileWritePlan === undefined\n ? null\n : scopeProfileGatePlan;\n if (scopeProfileWritePlan) {\n const selectedLayer = scopeProfileWritePlan.layers.find((layer) => layer.id === scopeProfileWritePlan.writeLayer);\n const writeNamespaceReadable = scopeProfileWritePlan.readNamespaces.includes(\n scopeProfileWritePlan.writeNamespace\n );\n if (!selectedLayer?.writable || !writeNamespaceReadable) {\n log.warn(\n `runExtraction: skipping scope profile ${scopeProfileWritePlan.profileId} because write layer ${scopeProfileWritePlan.writeLayer} is not writable inside the profile read stack`\n );\n await clearBuffer();\n return {\n status: \"skipped\",\n reason: \"scope_profile_no_writable_layer\",\n persistedCount: 0,\n durableOutputCount: 0,\n };\n }\n }\n const selfNamespace =\n explicitWriteNamespace ??\n scopeProfileWritePlan?.writeNamespace ??\n this.deps.applyCodingNamespaceOverlay(sessionKey, defaultNamespaceForPrincipal(principal, this.config));\n const extractionDeadlineController =\n typeof deadlineMs === \"number\" && Number.isFinite(deadlineMs)\n ? new AbortController()\n : undefined;\n const extractionAbortSignal = extractionDeadlineController\n ? options.abortSignal\n ? AbortSignal.any([options.abortSignal, extractionDeadlineController.signal])\n : extractionDeadlineController.signal\n : options.abortSignal;\n let extractionDeadlineTimer: NodeJS.Timeout | undefined;\n const clearExtractionDeadlineTimer = (): void => {\n if (extractionDeadlineTimer) {\n clearTimeout(extractionDeadlineTimer);\n extractionDeadlineTimer = undefined;\n }\n };\n const runDeadlineAware = async <T>(\n operation: () => Promise<T>,\n phase: string,\n clearTimerOnError = true,\n options: { ignoreAbort?: boolean; ignoreDeadline?: boolean } = {},\n ): Promise<T> => {\n const operationSignal = options.ignoreAbort ? undefined : extractionAbortSignal;\n try {\n if (!options.ignoreDeadline && typeof deadlineMs === \"number\" && Date.now() >= deadlineMs) {\n throwIfDeadlineExceeded(phase);\n }\n if (operationSignal?.aborted) {\n throwIfAborted(phase);\n }\n return await raceRecallAbort(\n operation(),\n operationSignal,\n `extraction aborted (${phase})`,\n );\n } catch (error) {\n if (clearTimerOnError) clearExtractionDeadlineTimer();\n if (!options.ignoreDeadline && typeof deadlineMs === \"number\" && Date.now() >= deadlineMs) {\n throw new ExtractionDeadlineError(phase);\n }\n throw error;\n }\n };\n if (extractionDeadlineController && typeof deadlineMs === \"number\") {\n const deadline = deadlineMs;\n const maxTimerDelayMs = 2_147_483_647;\n const scheduleDeadlineAbort = (): void => {\n const remainingMs = deadline - Date.now();\n if (remainingMs <= 0) {\n extractionDeadlineController.abort();\n return;\n }\n extractionDeadlineTimer = setTimeout(() => {\n if (Date.now() >= deadline) {\n extractionDeadlineController.abort();\n } else {\n scheduleDeadlineAbort();\n }\n }, Math.min(remainingMs, maxTimerDelayMs));\n };\n scheduleDeadlineAbort();\n }\n const storage = await runDeadlineAware(\n () => this.deps.getStorageRouter().storageFor(selfNamespace),\n \"during_storage\",\n );\n const shouldPersistProcessedFingerprint = targetTurns.some((turn) => turn.persistProcessedFingerprint === true);\n const extractionFingerprint = this.buildExtractionFingerprint(targetTurns, bufferKey);\n let meta = extractionFingerprint && shouldPersistProcessedFingerprint\n ? await runDeadlineAware(() => storage.loadMeta(), \"during_load_meta\")\n : null;\n if (\n extractionFingerprint &&\n shouldPersistProcessedFingerprint &&\n (meta?.processedExtractionFingerprints ?? []).some((entry) => entry.fingerprint === extractionFingerprint)\n ) {\n await runDeadlineAware(() => clearBuffer(), \"during_clear_buffer\");\n clearExtractionDeadlineTimer();\n return {\n status: \"skipped\",\n reason: \"processed_fingerprint\",\n persistedCount: 0,\n durableOutputCount: 0,\n };\n }\n\n // Extraction retry/backoff + circuit-breaker gate (extraction hot-loop\n // hardening). Suppresses re-attempts of a recently-failed fingerprint and\n // short-circuits every fingerprint while the provider breaker is open, so a\n // failing LLM endpoint is not hammered once per observe. Forced flushes and\n // fail-closed callers bypass the gate (rule 18) but still record failures.\n // On a suppressed attempt the buffer is deliberately NOT cleared, so no\n // extractable turn is dropped — it is retried after cooldown/nextEligibleAt.\n const forcedExtractionAttempt =\n options.failOnExtractionFailure === true || options.forceExtractionAttempt === true;\n // Resolve the gate through the shared lifecycle capability plan (issue\n // #1523) rather than reading the raw config flag at each call site.\n const extractionRetryEnabled = resolveMemoryLifecycleCapabilities(this.config).extractionRetry;\n if (extractionFingerprint && !forcedExtractionAttempt && extractionRetryEnabled) {\n try {\n meta ??= await runDeadlineAware(() => storage.loadMeta(), \"during_retry_gate\");\n this.hydrateRetryStateFromMeta(selfNamespace, meta);\n const nowMs = Date.now();\n let suppressReason: \"provider_circuit_open\" | \"extraction_backoff\" | null = null;\n if (this.isProviderBreakerOpen(nowMs)) {\n suppressReason = \"provider_circuit_open\";\n } else {\n const st = this.extractionRetryState.get(selfNamespace)?.get(extractionFingerprint);\n if (st && nowMs < st.nextEligibleAtMs) suppressReason = \"extraction_backoff\";\n }\n if (suppressReason) {\n // Passive correction capture is local and must not be delayed by a\n // provider cooldown. It remains fail-open.\n try {\n await runDeadlineAware(\n () => runPassiveCapture(normalizedTurns as BufferTurn[], {\n sessionKey,\n principal,\n namespace: selfNamespace,\n bufferKey,\n isLiveSession: clearBufferAfterExtraction,\n }),\n \"during_passive_capture\",\n );\n } catch (captureErr) {\n if (captureErr instanceof ExtractionDeadlineError) throw captureErr;\n log.warn(\"runExtraction: passive correction capture failed on suppressed attempt (non-fatal)\", captureErr);\n }\n clearExtractionDeadlineTimer();\n return { status: \"skipped\", reason: suppressReason, persistedCount: 0, durableOutputCount: 0 };\n }\n } catch (err) {\n if (err instanceof ExtractionDeadlineError) throw err;\n // Fail-open: a gate error must never block extraction.\n log.warn(\"runExtraction: extraction retry gate check failed; proceeding (fail-open)\", err);\n }\n }\n\n // Pass existing entity names so the LLM can reuse them instead of inventing variants.\n const existingEntities = await runDeadlineAware(\n () => storage.listEntityNames(),\n \"during_list_entity_names\",\n );\n let result: ExtractionResult;\n try {\n result = await raceRecallAbort(\n this.deps.getExtraction().extract(normalizedTurns, existingEntities, extractionAbortSignal),\n extractionAbortSignal,\n \"extraction aborted (during_extract)\",\n );\n } catch (error) {\n clearExtractionDeadlineTimer();\n if (typeof deadlineMs === \"number\" && Date.now() >= deadlineMs) {\n throw new ExtractionDeadlineError(\"during_extract\");\n }\n throw error;\n }\n try {\n throwIfDeadlineExceeded(\"before_persist\");\n throwIfAborted(\"before_persist\");\n\n // Defensive: validate extraction result before processing. Explicit\n // fail-closed callers, such as flush-plan import, must not observe\n // malformed extractor output as a successful skip.\n if (!result) {\n log.warn(\"runExtraction: extraction returned null/undefined\");\n if (options.failOnExtractionFailure) {\n throw new Error(\"extraction failed: invalid_extraction_result\");\n }\n await clearBuffer();\n return {\n status: \"skipped\",\n reason: \"invalid_extraction_result\",\n persistedCount: 0,\n durableOutputCount: 0,\n };\n }\n const invalidExtractionResultFields = [\n [\"facts\", result.facts],\n [\"entities\", result.entities],\n [\"questions\", result.questions],\n [\"profileUpdates\", result.profileUpdates],\n ]\n .filter(([, value]) => !Array.isArray(value))\n .map(([field]) => field);\n if (invalidExtractionResultFields.length > 0) {\n log.warn(\"runExtraction: extraction returned invalid collection fields\", {\n invalidFields: invalidExtractionResultFields,\n resultKeys: typeof result === \"object\" && result !== null ? Object.keys(result) : [],\n });\n if (options.failOnExtractionFailure) {\n throw new Error(\"extraction failed: invalid_extraction_result\");\n }\n await clearBuffer();\n return {\n status: \"skipped\",\n reason: \"invalid_extraction_result\",\n persistedCount: 0,\n durableOutputCount: 0,\n };\n }\n const extractionFailure =\n typeof result.extractionFailure === \"string\" && result.extractionFailure.trim().length > 0\n ? result.extractionFailure\n : undefined;\n let recordedRetryFailure = false;\n // Record failure into backoff/breaker state, or heal on success. Runs for\n // every result path (empty and durable), before the fail-closed throw, so a\n // forced flush still records its failure (rule 18). Gated by\n // extractionRetryEnabled so a disabled feature restores prior behavior.\n if (extractionFingerprint && extractionRetryEnabled) {\n if (extractionFailure) {\n try {\n meta ??= await runDeadlineAware(() => storage.loadMeta(), \"during_retry_bookkeeping_load\", false);\n await runDeadlineAware(\n () =>\n this.recordExtractionFailure(\n storage,\n selfNamespace,\n extractionFingerprint,\n result.extractionFailureClass ?? \"provider_retryable\",\n meta!,\n Date.now(),\n ),\n \"during_retry_bookkeeping_save\",\n false,\n );\n // The buffer is retained below so the backoff gate can re-attempt\n // these turns after nextEligibleAt — clearing would orphan the\n // retry state.\n recordedRetryFailure = true;\n } catch (err) {\n if (err instanceof ExtractionDeadlineError) throw err;\n // Fail-open (codex review): retry bookkeeping is best-effort — a\n // corrupt or locked meta store must not reject the extraction task.\n // With no backoff recorded there is nothing to retain for, so the\n // pre-#1908 clear-buffer behavior applies below.\n log.warn(\"runExtraction: failed to load meta for retry bookkeeping (non-fatal)\", err);\n }\n } else if (result.extractionSkippedReason === undefined) {\n // Provider responded without failure → breaker heals; clear any\n // parked backoff for this fingerprint so it proceeds normally.\n this.resetProviderBreakerOnSuccess();\n try {\n meta ??= await runDeadlineAware(() => storage.loadMeta(), \"during_retry_bookkeeping_load\", false);\n // Hydrate the in-memory mirror from persisted meta before clearing.\n // A forced flush (forceExtractionAttempt) bypasses the retry gate and\n // never hydrated, so without this a stale persisted backoff entry\n // would survive a successful forced flush and keep blocking normal\n // extraction until the timer expired (cursor/codex review).\n this.hydrateRetryStateFromMeta(selfNamespace, meta);\n if (this.clearExtractionRetryEntry(selfNamespace, extractionFingerprint, meta)) {\n await runDeadlineAware(() => storage.saveMeta(meta!), \"during_retry_bookkeeping_save\", false);\n }\n } catch (err) {\n if (err instanceof ExtractionDeadlineError) throw err;\n log.warn(\"runExtraction: failed to persist cleared retry state (non-fatal)\", err);\n }\n }\n }\n if (options.failOnExtractionFailure && extractionFailure) {\n throw new Error(`extraction failed: ${extractionFailure}`);\n }\n if (\n result.facts.length === 0 &&\n result.entities.length === 0 &&\n result.questions.length === 0 &&\n result.profileUpdates.length === 0\n ) {\n log.debug(\"runExtraction: extraction produced no durable outputs; skipping persistence\");\n if (extractionFailure) {\n log.warn(\n \"runExtraction: extraction reported failure with no durable outputs; not marking fingerprint processed\",\n { extractionFailure }\n );\n }\n const emptySuccessCommit = {\n storage,\n meta,\n extractionFingerprint,\n shouldPersistProcessedFingerprint,\n hasExtractionFailure: Boolean(extractionFailure),\n extractionSkippedReason: result.extractionSkippedReason,\n recordProcessedExtractionFingerprint: this.deps.recordProcessedExtractionFingerprint,\n runDeadlineAware,\n isDeadlineError: (error: unknown) => error instanceof ExtractionDeadlineError,\n };\n if (shouldPersistProcessedFingerprint) {\n await commitEmptySuccessExtraction(emptySuccessCommit);\n }\n await runPassiveCapture(normalizedTurns as BufferTurn[], {\n sessionKey,\n principal,\n namespace: selfNamespace,\n bufferKey,\n isLiveSession: clearBufferAfterExtraction,\n });\n if (recordedRetryFailure) {\n log.debug(\"runExtraction: retaining buffer for backoff retry after failure\");\n } else {\n await clearBuffer();\n }\n if (!shouldPersistProcessedFingerprint) {\n await commitEmptySuccessExtraction(emptySuccessCommit);\n }\n return { status: \"skipped\", reason: \"empty_extraction_result\", persistedCount: 0, durableOutputCount: 0 };\n }\n\n let threadIdForExtraction: string | null = null;\n if (resolvePresentationCapabilities(this.config).threading && turns.length > 0) {\n const lastTurn = turns[turns.length - 1];\n try {\n threadIdForExtraction = await runDeadlineAware(\n () => this.deps.getThreading().processTurn(lastTurn, []),\n \"during_threading\",\n );\n } catch (err) {\n if (err instanceof ExtractionDeadlineError) throw err;\n // Fail-open: threading errors must not block memory persistence.\n log.warn(\"[threading] processTurn failed before persistence (non-fatal)\", err);\n }\n }\n throwIfDeadlineExceeded(\"before_persist\");\n throwIfAborted(\"before_persist\");\n\n const { persistedIds } = await this.deps.persistExtraction(\n result,\n storage,\n threadIdForExtraction,\n { sessionKey, principal, validAt: sourceValidAt, sourceConnector: result.sourceConnector },\n // Pass the KNOWN base namespace (NHIdx) so the catalog write touch records the\n // real namespace rather than a guess decoded from the storage dir.\n selfNamespace,\n scopeProfileWritePlan,\n // Verbatim source turns for the faithfulness gate (#1576) so it can\n // locate a quote per fact when #1575 spans are absent.\n normalizedTurns\n .map((t) => t.content)\n .join(\"\\n\\n\")\n );\n const durableOutputCount =\n result.facts.length + result.entities.length + result.questions.length + result.profileUpdates.length;\n try {\n options.onDurableCommit?.();\n } catch (error) {\n log.warn(\"runExtraction: durable-commit callback failed\", error);\n }\n const runPostPersistBestEffort = runExtractionPostPersistBestEffort.bind(null, runDeadlineAware);\n const postPersist = await runExtractionPostPersist({\n result,\n storage,\n meta: meta ?? undefined,\n extractionFingerprint: extractionFingerprint ?? undefined,\n shouldPersistProcessedFingerprint,\n recordProcessedExtractionFingerprint: this.deps.recordProcessedExtractionFingerprint,\n runDeadlineAware,\n isDeadlineError: (error) => error instanceof ExtractionDeadlineError,\n createDeadlineError: (stage) => new ExtractionDeadlineError(stage),\n deadlineMs,\n clearBufferAfterExtraction,\n runPostPersistBestEffort,\n extractionJudgeShadow: this.config.extractionJudgeShadow,\n getDeferredCount: () => this.deps.getLastPersistExtractionDeferredCount(),\n normalizedTurns: normalizedTurns as BufferTurn[],\n bufferKey,\n retainDeferredTurns: (key, retainedTurns, max) =>\n this.deps.getBuffer().retainDeferredTurns(key, retainedTurns, max),\n clearBuffer,\n failOnExtractionFailure: options.failOnExtractionFailure === true,\n });\n meta = postPersist.meta ?? null;\n const postPersistMetadataFailed = postPersist.metadataFailed;\n\n // Passive correction capture (issue #1581) — detect corrections expressed\n // passively in the extracted turns and route to the Correction Contract.\n // Runs AFTER persistence + buffer clear so a capture failure never blocks\n // the extraction return. `clearBufferAfterExtraction` gates live-session\n // auto-apply (replay/import → queue-only).\n await runPostPersistBestEffort(\"during_post_persist_passive_capture\", () =>\n runPassiveCapture(normalizedTurns as BufferTurn[], {\n sessionKey,\n principal,\n namespace: selfNamespace,\n bufferKey,\n isLiveSession: clearBufferAfterExtraction,\n abortSignal: extractionAbortSignal,\n }),\n );\n\n // Build memory box from this extraction (v8.0 Phase 2A)\n // Topics are derived from the current extraction's facts and entities only —\n // not from readAllMemories() — so box topics accurately reflect the current\n // session window and the call is free of expensive full-corpus I/O.\n if (resolvePresentationCapabilities(this.config).memoryBoxes && persistedIds.length > 0) {\n const extractionTopics = deriveTopicsFromExtraction(result);\n // Derive episodic metadata from buffer turns (REMem-inspired)\n const firstUserTurn = turns.find((t) => t.role === \"user\");\n const boxGoal = firstUserTurn?.content?.slice(0, 100)?.trim() || undefined;\n await runPostPersistBestEffort(\"during_memory_box\", () =>\n this.deps.boxBuilderFor(storage).onExtraction({\n topics: extractionTopics,\n memoryIds: persistedIds,\n timestamp: new Date().toISOString(),\n goal: boxGoal,\n }),\n );\n }\n\n // Batch-append persisted IDs so non-fact memories (entities/questions) are\n // always attached to the thread. The helper excludes pending_review ids (#1635).\n if (resolvePresentationCapabilities(this.config).threading && threadIdForExtraction && persistedIds.length > 0) {\n await runPostPersistBestEffort(\"during_thread_episode_append\", () =>\n this.deps.appendPersistedThreadEpisodes(threadIdForExtraction, persistedIds),\n );\n }\n\n // Thread title update for the already-established thread context.\n if (resolvePresentationCapabilities(this.config).threading && threadIdForExtraction) {\n const conversationContent = turns.map((t) => t.content).join(\" \");\n await runPostPersistBestEffort(\"during_thread_title_update\", () =>\n this.deps.getThreading().updateThreadTitle(threadIdForExtraction, conversationContent),\n );\n }\n\n // Check if consolidation is needed (debounced + non-zero gated).\n const nonZeroExtraction = durableOutputCount > 0;\n try {\n // The increment of nonZeroExtractionsSinceConsolidation moved into\n // the scheduler with the rest of the cadence state (issue #1526 PR1).\n this.deps.maybeScheduleConsolidation(nonZeroExtraction);\n } catch (err) {\n log.warn(\"runExtraction: consolidation scheduling failed after persistence (non-fatal)\", err);\n }\n\n try {\n this.deps.requestQmdMaintenance();\n } catch (err) {\n log.warn(\"runExtraction: QMD maintenance scheduling failed after persistence (non-fatal)\", err);\n }\n\n await runPostPersistBestEffort(\"during_tier_migration\", () =>\n this.deps.runTierMigrationCycle(storage, \"extraction\"),\n );\n\n return {\n status: \"completed\",\n persistedCount: persistedIds.length,\n durableOutputCount,\n postPersistMetadataFailed,\n };\n } finally {\n clearExtractionDeadlineTimer();\n }\n }\n}\n"],"mappings":"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","names":["buildCompressionGuidelinesMarkdown","createHash","createHash","throwIfAborted","options"]}
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-B7RWBZXW.js";
|
|
4
4
|
import {
|
|
5
5
|
resolveCausalTrajectoryStoreDir
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-W4FBGYGK.js";
|
|
7
7
|
import {
|
|
8
8
|
normalizeRecallTokens
|
|
9
9
|
} from "./chunk-ZBJMUXZH.js";
|
|
@@ -339,4 +339,4 @@ export {
|
|
|
339
339
|
scoreStitchCandidate,
|
|
340
340
|
stitchCausalChain
|
|
341
341
|
};
|
|
342
|
-
//# sourceMappingURL=chunk-
|
|
342
|
+
//# sourceMappingURL=chunk-WZFAPHIK.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
BUILTIN_CONNECTORS,
|
|
3
3
|
loadRegistry
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-PNRA7FAD.js";
|
|
5
5
|
|
|
6
6
|
// src/connectors/label.ts
|
|
7
7
|
var CONNECTOR_LABEL_MAX_LENGTH = 64;
|
|
@@ -25,4 +25,4 @@ export {
|
|
|
25
25
|
CONNECTOR_LABEL_MAX_LENGTH,
|
|
26
26
|
knownConnectorIds
|
|
27
27
|
};
|
|
28
|
-
//# sourceMappingURL=chunk-
|
|
28
|
+
//# sourceMappingURL=chunk-X4IDNPOS.js.map
|
|
@@ -4,11 +4,11 @@ import {
|
|
|
4
4
|
import {
|
|
5
5
|
isSearchAborted,
|
|
6
6
|
throwIfSearchAborted
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-GUMZC2BO.js";
|
|
8
8
|
import {
|
|
9
9
|
reportSearchDegradation,
|
|
10
10
|
resolveEnsureCollectionArgs
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-URS5GSM7.js";
|
|
12
12
|
import {
|
|
13
13
|
log
|
|
14
14
|
} from "./chunk-3WCASNQZ.js";
|
|
@@ -499,4 +499,4 @@ function isMissingVectorProviderColumnError(err) {
|
|
|
499
499
|
export {
|
|
500
500
|
LanceDbBackend
|
|
501
501
|
};
|
|
502
|
-
//# sourceMappingURL=chunk-
|
|
502
|
+
//# sourceMappingURL=chunk-XL3TATMJ.js.map
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
} from "./chunk-ZOKZIR5K.js";
|
|
5
5
|
import {
|
|
6
6
|
isAbortError
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-BTTPKDIL.js";
|
|
8
8
|
import {
|
|
9
9
|
log
|
|
10
10
|
} from "./chunk-3WCASNQZ.js";
|
|
@@ -427,4 +427,4 @@ export {
|
|
|
427
427
|
augmentWithDirectAndTemporal,
|
|
428
428
|
parallelRetrieval
|
|
429
429
|
};
|
|
430
|
-
//# sourceMappingURL=chunk-
|
|
430
|
+
//# sourceMappingURL=chunk-XPRJSHNI.js.map
|
|
@@ -43,6 +43,15 @@ function isEncryptedFile(buf) {
|
|
|
43
43
|
const b = Buffer.isBuffer(buf) ? buf : Buffer.from(buf);
|
|
44
44
|
return b.subarray(0, MAGIC_BYTES.length).equals(MAGIC_BYTES);
|
|
45
45
|
}
|
|
46
|
+
async function readPositionedPrefix(handle, buffer) {
|
|
47
|
+
let bytesRead = 0;
|
|
48
|
+
while (bytesRead < buffer.length) {
|
|
49
|
+
const result = await handle.read(buffer, bytesRead, buffer.length - bytesRead, bytesRead);
|
|
50
|
+
if (result.bytesRead === 0) break;
|
|
51
|
+
bytesRead += result.bytesRead;
|
|
52
|
+
}
|
|
53
|
+
return bytesRead;
|
|
54
|
+
}
|
|
46
55
|
async function probeEncryptedRegularFileHeader(probePath) {
|
|
47
56
|
let entryStat;
|
|
48
57
|
try {
|
|
@@ -59,7 +68,7 @@ async function probeEncryptedRegularFileHeader(probePath) {
|
|
|
59
68
|
const handle = await openFile(probePath, "r");
|
|
60
69
|
try {
|
|
61
70
|
const header = Buffer.alloc(MAGIC_HEADER_SIZE);
|
|
62
|
-
const
|
|
71
|
+
const bytesRead = await readPositionedPrefix(handle, header);
|
|
63
72
|
return isEncryptedFile(header.subarray(0, bytesRead));
|
|
64
73
|
} finally {
|
|
65
74
|
await handle.close();
|
|
@@ -208,7 +217,7 @@ async function* readMaybeEncryptedFileFromChunks(filePath, key, memoryDir, chunk
|
|
|
208
217
|
const headerSize = MAGIC_HEADER_SIZE + ENVELOPE_HEADER_SIZE;
|
|
209
218
|
try {
|
|
210
219
|
const prefix = Buffer.alloc(headerSize);
|
|
211
|
-
const
|
|
220
|
+
const prefixBytes = await readPositionedPrefix(handle, prefix);
|
|
212
221
|
const prefixView = prefix.subarray(0, prefixBytes);
|
|
213
222
|
if (!isEncryptedFile(prefixView)) {
|
|
214
223
|
if (prefixBytes > 0) yield Buffer.from(prefixView);
|
|
@@ -235,15 +244,9 @@ async function* readMaybeEncryptedFileFromChunks(filePath, key, memoryDir, chunk
|
|
|
235
244
|
if (version !== ENVELOPE_VERSION) {
|
|
236
245
|
throw new Error(`secure-store: unsupported envelope version ${version}`);
|
|
237
246
|
}
|
|
238
|
-
const salt = envelope.subarray(
|
|
239
|
-
ENVELOPE_LAYOUT.salt,
|
|
240
|
-
ENVELOPE_LAYOUT.salt + ENVELOPE_SALT_LENGTH
|
|
241
|
-
);
|
|
247
|
+
const salt = envelope.subarray(ENVELOPE_LAYOUT.salt, ENVELOPE_LAYOUT.salt + ENVELOPE_SALT_LENGTH);
|
|
242
248
|
const iv = envelope.subarray(ENVELOPE_LAYOUT.iv, ENVELOPE_LAYOUT.iv + IV_LENGTH);
|
|
243
|
-
const authTag = envelope.subarray(
|
|
244
|
-
ENVELOPE_LAYOUT.authTag,
|
|
245
|
-
ENVELOPE_LAYOUT.authTag + AUTH_TAG_LENGTH
|
|
246
|
-
);
|
|
249
|
+
const authTag = envelope.subarray(ENVELOPE_LAYOUT.authTag, ENVELOPE_LAYOUT.authTag + AUTH_TAG_LENGTH);
|
|
247
250
|
const decipher = createDecipheriv("aes-256-gcm", key, iv, { authTagLength: AUTH_TAG_LENGTH });
|
|
248
251
|
decipher.setAAD(Buffer.concat([buildHeaderAad(salt), filePathAad(filePath, memoryDir)]));
|
|
249
252
|
decipher.setAuthTag(authTag);
|
|
@@ -547,4 +550,4 @@ export {
|
|
|
547
550
|
migrateMemoryDirToEncrypted,
|
|
548
551
|
decryptMemoryDirToPlaintext
|
|
549
552
|
};
|
|
550
|
-
//# sourceMappingURL=chunk-
|
|
553
|
+
//# sourceMappingURL=chunk-XQ3HXAQH.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/secure-store/secure-fs.ts"],"sourcesContent":["/**\n * Transparent file-level encryption for the secure-store module.\n *\n * Issue #690 (PR 3/4) — storage.ts integration layer.\n *\n * This module sits between the raw filesystem and StorageManager.\n * Every memory file is either:\n * - a plain UTF-8 text file (legacy, back-compat), or\n * - a REMNIC-ENC sealed file (AES-256-GCM, see format below).\n *\n * On-disk format\n * --------------\n * Encrypted files begin with a 9-byte magic header:\n *\n * REMNIC-ENC (7 ASCII bytes)\n * VER (1 byte, currently 0x01)\n * FLAGS (1 byte, reserved, must be 0x00)\n *\n * Followed immediately by a `seal()` envelope from `cipher.ts`:\n *\n * [VERSION:1][SALT:16][IV:12][AUTHTAG:16][CIPHERTEXT:...]\n *\n * The magic header makes encrypted files sniffable without attempting\n * a full `open()` call and gives operators a clear signal that the\n * file cannot be read by opening it in an editor.\n *\n * AAD\n * ---\n * The file path relative to the memory root is bound as Associated\n * Authenticated Data (AAD) on both encrypt and decrypt. This means\n * moving or renaming an encrypted file without re-encrypting it will\n * cause auth-tag failure on the next read — the file is tied to its\n * path. Callers that move files must re-encrypt them.\n *\n * Back-compat\n * -----------\n * `readMaybeEncryptedFile` transparently handles both formats: if the\n * file does NOT start with the magic bytes, it is returned as-is (plain\n * text). This lets an operator migrate incrementally: newly-written\n * files are encrypted while existing files continue to be read in plain\n * form until `migrateMemoryDirToEncrypted` is run.\n *\n * Naming: `secure-fs.ts` (not `vault-fs.ts`) — see `kdf.ts` naming note.\n */\n\nimport { createCipheriv, createDecipheriv, randomBytes, randomUUID } from \"node:crypto\";\nimport { lstat, mkdir, open as openFile, readFile, readdir, rename, unlink, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport {\n AUTH_TAG_LENGTH,\n ENVELOPE_HEADER_SIZE,\n ENVELOPE_LAYOUT,\n ENVELOPE_SALT_LENGTH,\n ENVELOPE_VERSION,\n IV_LENGTH,\n generateSalt,\n open as openEnvelope,\n parseEnvelope,\n seal,\n} from \"./cipher.js\";\nimport { RECALL_FALLBACK_DIRS } from \"../utils/category-dir.js\";\nimport { isErrnoCode } from \"../utils/errno.js\";\n\n// ---------------------------------------------------------------------------\n// Error classes\n// ---------------------------------------------------------------------------\n\n/**\n * Thrown when a read is attempted but the keyring entry for this\n * store is absent (i.e. `secure-store unlock` has not been run\n * since the last daemon start).\n */\nexport class SecureStoreLockedError extends Error {\n constructor(message = \"secure-store is locked — run `remnic secure-store unlock` to decrypt\") {\n super(message);\n this.name = \"SecureStoreLockedError\";\n }\n}\n\n/**\n * Thrown when `open()` fails because the auth tag does not validate.\n * This covers both wrong-key and tampered-ciphertext scenarios —\n * intentionally indistinguishable from the caller's perspective.\n */\nexport class SecureStoreDecryptError extends Error {\n constructor(message = \"secure-store decryption failed — wrong key or tampered ciphertext\") {\n super(message);\n this.name = \"SecureStoreDecryptError\";\n }\n}\n\n// ---------------------------------------------------------------------------\n// Magic header\n// ---------------------------------------------------------------------------\n\n/** Magic bytes: the ASCII string \"REMNIC-ENC\" (10 bytes). */\nexport const MAGIC_BYTES = Buffer.from(\"REMNIC-ENC\", \"ascii\");\n\n/** Current on-disk version byte. */\nexport const FILE_FORMAT_VERSION = 0x01;\n\n/** Reserved flags byte — must be 0x00. */\nexport const FILE_FORMAT_FLAGS = 0x00;\n\n/** Total size of the magic header prefix (magic + version + flags). */\nexport const MAGIC_HEADER_SIZE = MAGIC_BYTES.length + 2; // 12 bytes\n\n/**\n * Exact, deterministic bytes `writeMaybeEncryptedFile` adds to an encrypted\n * file beyond its plaintext body: the magic header prefix plus the fixed\n * envelope header (version + salt + IV + auth tag). AES-256-GCM ciphertext\n * matches the plaintext length and the state-file write path applies no\n * compression, so an encrypted state file is exactly `plaintext +\n * SECURE_STORE_ENVELOPE_OVERHEAD_BYTES` on disk. Compaction reserves this so an\n * encrypted ledger lands strictly below the reader's whole-file decrypt cap\n * (issue #2033).\n */\nexport const SECURE_STORE_ENVELOPE_OVERHEAD_BYTES = MAGIC_HEADER_SIZE + ENVELOPE_HEADER_SIZE;\n\n// ---------------------------------------------------------------------------\n// Detection\n// ---------------------------------------------------------------------------\n\n/**\n * Return true iff `buf` begins with the REMNIC-ENC magic header.\n * Does not validate the envelope; just identifies the format.\n */\nexport function isEncryptedFile(buf: Uint8Array): boolean {\n if (buf.length < MAGIC_HEADER_SIZE) return false;\n const b = Buffer.isBuffer(buf) ? buf : Buffer.from(buf);\n return b.subarray(0, MAGIC_BYTES.length).equals(MAGIC_BYTES);\n}\n\ntype PositionedFileReader = {\n read: (buffer: Buffer, offset: number, length: number, position: number) => Promise<{ bytesRead: number }>;\n};\n\nasync function readPositionedPrefix(handle: PositionedFileReader, buffer: Buffer): Promise<number> {\n let bytesRead = 0;\n while (bytesRead < buffer.length) {\n const result = await handle.read(buffer, bytesRead, buffer.length - bytesRead, bytesRead);\n if (result.bytesRead === 0) break;\n bytesRead += result.bytesRead;\n }\n return bytesRead;\n}\n\n/**\n * True when the REGULAR file at `probePath` is encrypted at rest (its first\n * bytes are the REMNIC-ENC magic header). ENOENT resolves to false — an absent\n * file has nothing to probe. A symlink, FIFO, device, or any other non-regular\n * path is REFUSED with a throw rather than opened: opening a FIFO blocks until a\n * writer appears and a symlink would redirect the probe outside our tree. The\n * ledgers and per-event spills we manage are always regular files, so a\n * non-regular path is an anomaly the caller must treat as unsafe, never follow\n * (#2033). Shared by the CLI ledger recovery probe and the auto-compaction probe\n * so both enforce identical open safety.\n */\nexport async function probeEncryptedRegularFileHeader(probePath: string): Promise<boolean> {\n let entryStat;\n try {\n entryStat = await lstat(probePath);\n } catch (err) {\n if (isErrnoCode(err, \"ENOENT\")) return false;\n throw err;\n }\n if (!entryStat.isFile()) {\n throw new Error(\n `refusing to probe non-regular state path ${probePath} ` +\n `(symlink/FIFO/device); opening it could block or escape containment (#2033)`\n );\n }\n const handle = await openFile(probePath, \"r\");\n try {\n const header = Buffer.alloc(MAGIC_HEADER_SIZE);\n const bytesRead = await readPositionedPrefix(handle, header);\n return isEncryptedFile(header.subarray(0, bytesRead));\n } finally {\n await handle.close();\n }\n}\n\n// ---------------------------------------------------------------------------\n// Encrypt / decrypt file body\n// ---------------------------------------------------------------------------\n\n/**\n * Encrypt `plain` (UTF-8 content of a memory file) and return a\n * Buffer ready to write to disk.\n *\n * @param plain Plain-text file content (UTF-8 string or Buffer).\n * @param key 32-byte AES-256 key from the keyring.\n * @param aad Optional associated data — defaults to empty if omitted.\n * Callers should pass the file path relative to memoryDir\n * so the ciphertext is bound to its location.\n */\nexport function encryptFileBody(plain: string | Buffer, key: Buffer, aad?: Buffer): Buffer {\n const plainBuf = typeof plain === \"string\" ? Buffer.from(plain, \"utf8\") : plain;\n const salt = generateSalt();\n const envelope = seal(key, salt, plainBuf, aad ? { aad } : {});\n\n const header = Buffer.alloc(MAGIC_HEADER_SIZE);\n MAGIC_BYTES.copy(header, 0);\n header.writeUInt8(FILE_FORMAT_VERSION, MAGIC_BYTES.length);\n header.writeUInt8(FILE_FORMAT_FLAGS, MAGIC_BYTES.length + 1);\n\n return Buffer.concat([header, envelope]);\n}\n\n/**\n * Decrypt a buffer produced by `encryptFileBody` and return the\n * original UTF-8 content.\n *\n * Throws `SecureStoreDecryptError` on auth failure (wrong key or\n * tampered ciphertext). Throws a plain `Error` for structural problems\n * (truncated buffer, wrong magic, unsupported version).\n */\nexport function decryptFileBody(buf: Buffer, key: Buffer, aad?: Buffer): Buffer {\n if (!isEncryptedFile(buf)) {\n throw new Error(\"decryptFileBody: buffer does not start with REMNIC-ENC magic header\");\n }\n const version = buf.readUInt8(MAGIC_BYTES.length);\n if (version !== FILE_FORMAT_VERSION) {\n throw new Error(\n `decryptFileBody: unsupported file format version ${version} (this build supports ${FILE_FORMAT_VERSION})`\n );\n }\n const flags = buf.readUInt8(MAGIC_BYTES.length + 1);\n if (flags !== FILE_FORMAT_FLAGS) {\n throw new Error(`decryptFileBody: unknown flags byte 0x${flags.toString(16).padStart(2, \"0\")}`);\n }\n const envelope = buf.subarray(MAGIC_HEADER_SIZE);\n parseEnvelope(envelope);\n try {\n return openEnvelope(key, envelope, aad ? { aad } : {});\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n throw new SecureStoreDecryptError(`secure-store decryption failed: ${msg}`);\n }\n}\n\nfunction buildHeaderAad(salt: Uint8Array): Buffer {\n const out = Buffer.alloc(1 + ENVELOPE_SALT_LENGTH);\n out.writeUInt8(ENVELOPE_VERSION, 0);\n Buffer.from(salt).copy(out, 1);\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// Path → AAD helper\n// ---------------------------------------------------------------------------\n\n/**\n * Build the AAD buffer for a file at `filePath` relative to\n * `memoryDir`. The AAD binds the ciphertext to its path so a\n * file cannot be silently relocated without re-encryption.\n *\n * When `memoryDir` is supplied and `filePath` is absolute, the\n * relative sub-path is used. Otherwise `filePath` is used verbatim.\n */\nexport function filePathAad(filePath: string, memoryDir?: string): Buffer {\n let rel = filePath;\n if (memoryDir && path.isAbsolute(filePath)) {\n rel = path.relative(memoryDir, filePath);\n }\n return Buffer.from(rel, \"utf8\");\n}\n\n// ---------------------------------------------------------------------------\n// High-level read / write helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Read a file from `filePath`.\n *\n * - If the file is plaintext (no magic header), return its content\n * as-is — back-compat with unencrypted stores.\n * - If the file is encrypted AND `key` is provided, decrypt and return\n * the plaintext content.\n * - If the file is encrypted AND `key` is null, throw\n * `SecureStoreLockedError`.\n *\n * @param filePath Absolute path to the file.\n * @param key 32-byte AES-256 key, or null when the store is locked.\n * @param memoryDir Memory root for path-bound AAD. Should be absolute.\n */\nexport async function readMaybeEncryptedFileBuffer(\n filePath: string,\n key: Buffer | null,\n memoryDir?: string\n): Promise<Buffer> {\n const buf = await readFile(filePath);\n if (!isEncryptedFile(buf)) {\n // Plain file — legacy or unencrypted store.\n return buf;\n }\n // Encrypted — key required.\n if (key === null) {\n throw new SecureStoreLockedError(\n `secure-store is locked — cannot read encrypted file at ${filePath}. Run \\`remnic secure-store unlock\\` to decrypt.`\n );\n }\n return decryptFileBodyForPath(buf, key, filePath, memoryDir);\n}\n\nexport async function readMaybeEncryptedFile(\n filePath: string,\n key: Buffer | null,\n memoryDir?: string\n): Promise<string> {\n return (await readMaybeEncryptedFileBuffer(filePath, key, memoryDir)).toString(\"utf8\");\n}\n\nexport interface WriteMaybeEncryptedFileOptions {\n /**\n * File mode bits. Default 0o600 (owner read/write only).\n * Applied only on create; existing files inherit their existing mode.\n */\n mode?: number;\n /**\n * If true, write atomically via a temp file + rename (CLAUDE.md gotcha #54).\n * Default true.\n */\n atomic?: boolean;\n}\n\n/**\n * Write `content` to `filePath`.\n *\n * - If `key` is provided and non-null, encrypt the content first.\n * - If `key` is null, write the content as plain UTF-8 (unencrypted store).\n *\n * Writes atomically: content is written to a unique temp file\n * first, then renamed into place (CLAUDE.md gotcha #54 — never delete\n * before write).\n */\nexport async function writeMaybeEncryptedFile(\n filePath: string,\n content: string | Buffer,\n key: Buffer | null,\n options: WriteMaybeEncryptedFileOptions = {},\n memoryDir?: string\n): Promise<void> {\n const { mode = 0o600, atomic = true } = options;\n await mkdir(path.dirname(filePath), { recursive: true });\n\n let data: Buffer | string;\n if (key !== null) {\n const aad = filePathAad(filePath, memoryDir);\n data = encryptFileBody(content, key, aad);\n } else {\n data = content;\n }\n\n if (atomic) {\n const tempPath = uniqueAtomicTempPath(filePath, \"tmp\");\n try {\n await writeFile(tempPath, data, { mode });\n await rename(tempPath, filePath);\n } catch (err) {\n // Best-effort cleanup of the temp file.\n try {\n await unlink(tempPath);\n } catch {\n // ignore\n }\n throw err;\n }\n } else {\n await writeFile(filePath, data, { mode });\n }\n}\n\nexport async function writeMaybeEncryptedFileFromChunks(\n filePath: string,\n chunks: AsyncIterable<Buffer>,\n key: Buffer | null,\n options: WriteMaybeEncryptedFileOptions = {},\n memoryDir?: string\n): Promise<void> {\n const { mode = 0o600, atomic = true } = options;\n await mkdir(path.dirname(filePath), { recursive: true });\n const writePath = atomic ? `${filePath}.tmp-${process.pid}-${Date.now()}` : filePath;\n let completed = false;\n try {\n const handle = await openFile(writePath, \"w\", mode);\n try {\n if (key !== null) {\n const salt = generateSalt();\n const iv = randomBytes(IV_LENGTH);\n const header = Buffer.alloc(MAGIC_HEADER_SIZE + ENVELOPE_HEADER_SIZE);\n MAGIC_BYTES.copy(header, 0);\n header.writeUInt8(FILE_FORMAT_VERSION, MAGIC_BYTES.length);\n header.writeUInt8(FILE_FORMAT_FLAGS, MAGIC_BYTES.length + 1);\n const envelopeOffset = MAGIC_HEADER_SIZE;\n header.writeUInt8(ENVELOPE_VERSION, envelopeOffset + ENVELOPE_LAYOUT.version);\n salt.copy(header, envelopeOffset + ENVELOPE_LAYOUT.salt);\n iv.copy(header, envelopeOffset + ENVELOPE_LAYOUT.iv);\n await handle.write(header);\n\n const cipher = createCipheriv(\"aes-256-gcm\", key, iv, { authTagLength: AUTH_TAG_LENGTH });\n const aad = filePathAad(filePath, memoryDir);\n cipher.setAAD(Buffer.concat([buildHeaderAad(salt), aad]));\n for await (const chunk of chunks) {\n if (chunk.length === 0) continue;\n const encrypted = cipher.update(chunk);\n if (encrypted.length > 0) await handle.write(encrypted);\n }\n const final = cipher.final();\n if (final.length > 0) await handle.write(final);\n const authTag = cipher.getAuthTag();\n await handle.write(authTag, 0, authTag.length, MAGIC_HEADER_SIZE + ENVELOPE_LAYOUT.authTag);\n } else {\n for await (const chunk of chunks) {\n if (chunk.length > 0) await handle.write(chunk);\n }\n }\n } finally {\n await handle.close();\n }\n if (atomic) {\n await rename(writePath, filePath);\n }\n completed = true;\n } finally {\n if (!completed && atomic) {\n await unlink(writePath).catch(() => {});\n }\n }\n}\n\n/**\n * Stream a file through the secure-store reader without buffering the whole\n * payload. Plaintext files are passed through unchanged; encrypted files are\n * authenticated and decrypted incrementally.\n */\nexport async function* readMaybeEncryptedFileFromChunks(\n filePath: string,\n key: Buffer | null,\n memoryDir?: string,\n chunkSize = 64 * 1024\n): AsyncIterable<Buffer> {\n const handle = await openFile(filePath, \"r\");\n const headerSize = MAGIC_HEADER_SIZE + ENVELOPE_HEADER_SIZE;\n try {\n const prefix = Buffer.alloc(headerSize);\n const prefixBytes = await readPositionedPrefix(handle, prefix);\n const prefixView = prefix.subarray(0, prefixBytes);\n if (!isEncryptedFile(prefixView)) {\n if (prefixBytes > 0) yield Buffer.from(prefixView);\n let position = prefixBytes;\n const buffer = Buffer.alloc(chunkSize);\n for (;;) {\n const { bytesRead } = await handle.read(buffer, 0, buffer.length, position);\n if (bytesRead === 0) break;\n position += bytesRead;\n yield Buffer.from(buffer.subarray(0, bytesRead));\n }\n return;\n }\n if (prefixBytes < headerSize) {\n throw new Error(`encrypted file header is truncated: ${filePath}`);\n }\n if (key === null) {\n throw new SecureStoreLockedError(\n `secure-store is locked — cannot read encrypted file at ${filePath}. ` +\n \"Run `remnic secure-store unlock` to decrypt.\"\n );\n }\n const envelope = prefix.subarray(MAGIC_HEADER_SIZE);\n const version = envelope.readUInt8(ENVELOPE_LAYOUT.version);\n if (version !== ENVELOPE_VERSION) {\n throw new Error(`secure-store: unsupported envelope version ${version}`);\n }\n const salt = envelope.subarray(ENVELOPE_LAYOUT.salt, ENVELOPE_LAYOUT.salt + ENVELOPE_SALT_LENGTH);\n const iv = envelope.subarray(ENVELOPE_LAYOUT.iv, ENVELOPE_LAYOUT.iv + IV_LENGTH);\n const authTag = envelope.subarray(ENVELOPE_LAYOUT.authTag, ENVELOPE_LAYOUT.authTag + AUTH_TAG_LENGTH);\n const decipher = createDecipheriv(\"aes-256-gcm\", key, iv, { authTagLength: AUTH_TAG_LENGTH });\n decipher.setAAD(Buffer.concat([buildHeaderAad(salt), filePathAad(filePath, memoryDir)]));\n decipher.setAuthTag(authTag);\n let position = headerSize;\n const buffer = Buffer.alloc(chunkSize);\n try {\n for (;;) {\n const { bytesRead } = await handle.read(buffer, 0, buffer.length, position);\n if (bytesRead === 0) break;\n position += bytesRead;\n const plain = decipher.update(buffer.subarray(0, bytesRead));\n if (plain.length > 0) yield plain;\n }\n const final = decipher.final();\n if (final.length > 0) yield final;\n } catch (err) {\n if (err instanceof SecureStoreDecryptError) throw err;\n const message = err instanceof Error ? err.message : String(err);\n throw new SecureStoreDecryptError(`secure-store decryption failed: ${message}`);\n }\n } finally {\n await handle.close();\n }\n}\n\n// ---------------------------------------------------------------------------\n// Migration\n// ---------------------------------------------------------------------------\n\nexport interface MigrateResult {\n /** Number of files successfully encrypted. */\n encrypted: number;\n /** Number of files already encrypted (skipped). */\n skipped: number;\n /** Files that failed to encrypt (path → error message). */\n errors: Array<{ filePath: string; error: string }>;\n}\n\nexport interface DecryptResult {\n /** Number of files successfully decrypted back to plaintext. */\n decrypted: number;\n /** Number of files already plaintext (skipped). */\n skipped: number;\n /** Files that failed to decrypt (path → error message). */\n errors: Array<{ filePath: string; error: string }>;\n}\n\n/**\n * Walk `dir` recursively, find encryptable storage-managed files that are not\n * yet encrypted, and re-write them as encrypted files under `key`.\n *\n * Safety rules per CLAUDE.md gotchas #54 and #25:\n * 1. A page-version snapshot is taken (via `createVersion`) BEFORE\n * each overwrite so the plaintext version is preserved in history.\n * Since this module has no direct access to `page-versioning.ts`\n * internals, callers who have page-versioning configured should\n * pass `onBeforeEncrypt` to take the snapshot.\n * 2. The new encrypted content is written to a temp file first,\n * then renamed atomically — never deleted before written.\n * 3. If encryption of any file fails, the error is recorded and the\n * original file is left intact (partial migration is safe).\n *\n * @param dir Absolute path to the memory directory.\n * @param key 32-byte AES-256 key.\n * @param onBeforeEncrypt Optional callback invoked before encrypting\n * each file. Can be used to take page-version\n * snapshots. Errors here are non-fatal.\n */\nexport async function migrateMemoryDirToEncrypted(\n dir: string,\n key: Buffer,\n onBeforeEncrypt?: (filePath: string) => Promise<void>\n): Promise<MigrateResult> {\n const result: MigrateResult = { encrypted: 0, skipped: 0, errors: [] };\n\n const files = await collectEncryptableStorageFiles(dir);\n for (const filePath of files) {\n try {\n const buf = await readFile(filePath);\n if (isEncryptedFile(buf)) {\n result.skipped++;\n continue;\n }\n // Call optional pre-encryption hook (e.g. page-version snapshot).\n if (onBeforeEncrypt) {\n try {\n await onBeforeEncrypt(filePath);\n } catch {\n // Non-fatal — continue with encryption even if snapshot fails.\n }\n }\n const content = buf.toString(\"utf8\");\n const aad = filePathAad(filePath, dir);\n const encrypted = encryptFileBody(content, key, aad);\n\n // Atomic write: temp → rename (gotcha #54).\n const tempPath = uniqueAtomicTempPath(filePath, \"enc-tmp\");\n try {\n await writeFile(tempPath, encrypted, { mode: 0o600 });\n await rename(tempPath, filePath);\n result.encrypted++;\n } catch (writeErr) {\n // Clean up temp file, leave original intact.\n try {\n const { unlink } = await import(\"node:fs/promises\");\n await unlink(tempPath);\n } catch {\n // ignore\n }\n throw writeErr;\n }\n } catch (err) {\n result.errors.push({\n filePath,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n\n return result;\n}\n\n/**\n * Walk `dir` recursively, find storage-managed encrypted files, and\n * re-write them as plaintext under the same paths.\n *\n * This is the reversible counterpart to {@link migrateMemoryDirToEncrypted}.\n * It only touches files under the same storage-managed roots, skips\n * plaintext files, skips symlinks, excludes `.secure-store/`, and writes\n * each plaintext replacement via temp-file + rename so a per-file failure\n * leaves the ciphertext intact.\n */\nexport async function decryptMemoryDirToPlaintext(dir: string, key: Buffer): Promise<DecryptResult> {\n const result: DecryptResult = { decrypted: 0, skipped: 0, errors: [] };\n\n const files = await collectStorageManagedFiles(dir, isDecryptableStoragePath);\n for (const filePath of files) {\n try {\n const buf = await readFile(filePath);\n if (!isEncryptedFile(buf)) {\n result.skipped++;\n continue;\n }\n\n const plaintext = decryptFileBodyForPath(buf, key, filePath, dir);\n const tempPath = uniqueAtomicTempPath(filePath, \"dec-tmp\");\n try {\n await writeFile(tempPath, plaintext, { mode: 0o600 });\n await rename(tempPath, filePath);\n result.decrypted++;\n } catch (writeErr) {\n try {\n await unlink(tempPath);\n } catch {\n // ignore cleanup errors; original ciphertext is still intact.\n }\n throw writeErr;\n }\n } catch (err) {\n result.errors.push({\n filePath,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nfunction uniqueAtomicTempPath(filePath: string, label: string): string {\n return `${filePath}.${label}-${process.pid}-${Date.now()}-${randomUUID()}`;\n}\n\nfunction decryptFileBodyForPath(buf: Buffer, key: Buffer, filePath: string, memoryDir?: string): Buffer {\n const aad = filePathAad(filePath, memoryDir);\n try {\n return decryptFileBody(buf, key, aad);\n } catch (err) {\n if (!(err instanceof SecureStoreDecryptError)) {\n throw err;\n }\n const legacyRoot = legacyNamespaceAadRootForFile(filePath, memoryDir);\n if (legacyRoot) {\n try {\n return decryptFileBody(buf, key, filePathAad(filePath, legacyRoot));\n } catch {\n // Fall through to the namespace-reader fallback below.\n }\n }\n\n const topLevelRoot = topLevelAadRootForNamespaceReader(filePath, memoryDir);\n if (topLevelRoot) {\n try {\n return decryptFileBody(buf, key, filePathAad(filePath, topLevelRoot));\n } catch {\n // Preserve the caller-facing error from the canonical decrypt attempt.\n }\n }\n\n throw err;\n }\n}\n\nfunction topLevelAadRootForNamespaceReader(filePath: string, memoryDir?: string): string | null {\n if (!memoryDir || !path.isAbsolute(filePath)) return null;\n const resolvedMemoryDir = path.resolve(memoryDir);\n const rel = path.relative(resolvedMemoryDir, filePath);\n if (rel === \"\" || rel.startsWith(\"..\") || path.isAbsolute(rel)) return null;\n const parts = resolvedMemoryDir.split(path.sep);\n if (parts.length < 3 || parts.at(-2) !== \"namespaces\" || !parts.at(-1)) return null;\n const topLevelRoot = parts.slice(0, -2).join(path.sep) || path.sep;\n const topRel = path.relative(topLevelRoot, filePath);\n if (topRel === \"\" || topRel.startsWith(\"..\") || path.isAbsolute(topRel)) {\n return null;\n }\n const topParts = topRel.split(path.sep);\n if (topParts[0] !== \"namespaces\" || topParts[1] !== parts.at(-1)) {\n return null;\n }\n return topLevelRoot;\n}\n\nfunction legacyNamespaceAadRootForFile(filePath: string, memoryDir?: string): string | null {\n if (!memoryDir || !path.isAbsolute(filePath)) return null;\n const rel = path.relative(memoryDir, filePath);\n if (rel === \"\" || rel.startsWith(\"..\") || path.isAbsolute(rel)) return null;\n const parts = rel.split(path.sep);\n if (parts[0] === \"namespaces\" && parts.length >= 3 && parts[1]) {\n return path.join(memoryDir, \"namespaces\", parts[1]);\n }\n return null;\n}\n\n/**\n * Recursively collect files under `dir` that are read through the\n * storage-layer secure-store helpers, excluding symlinked entries and\n * `.secure-store/` metadata.\n */\nasync function collectEncryptableStorageFiles(dir: string, rootDir = dir): Promise<string[]> {\n return collectStorageManagedFiles(dir, isEncryptableStoragePath, rootDir);\n}\n\n/**\n * Recursively collect regular files under storage-managed roots, excluding\n * symlinked entries and `.secure-store/` metadata. This broader collector is\n * used by the decrypt/disable path so future encrypted sidecars can be\n * restored without requiring extension-specific logic.\n */\nasync function collectStorageManagedFiles(\n dir: string,\n includeFile: (filePath: string, rootDir: string) => boolean,\n rootDir = dir\n): Promise<string[]> {\n const results: string[] = [];\n let scanDir = dir;\n let scanRootDir = rootDir;\n if (path.resolve(dir) === path.resolve(rootDir)) {\n const normalizedRoot = await resolveStorageManagedRootForScan(dir);\n if (!normalizedRoot) return results;\n scanDir = normalizedRoot;\n scanRootDir = normalizedRoot;\n }\n let names: string[];\n try {\n names = await readdir(scanDir, { encoding: \"utf8\" });\n } catch {\n return results;\n }\n for (const name of names) {\n if (name.startsWith(\".secure-store\")) continue;\n const full = path.join(scanDir, name);\n let isDir = false;\n let isFile = false;\n try {\n const s = await lstat(full);\n if (s.isSymbolicLink()) continue;\n isDir = s.isDirectory();\n isFile = s.isFile();\n } catch {\n continue;\n }\n if (isDir) {\n const sub = await collectStorageManagedFiles(full, includeFile, scanRootDir);\n results.push(...sub);\n } else if (isFile && includeFile(full, scanRootDir)) {\n results.push(full);\n }\n }\n return results;\n}\n\nasync function resolveStorageManagedRootForScan(dir: string): Promise<string | null> {\n const lstatPath = normalizePathForLstat(dir);\n let stat: Awaited<ReturnType<typeof lstat>>;\n try {\n stat = await lstat(lstatPath);\n } catch (error) {\n if (isFsErrorWithCode(error, \"ENOENT\")) return null;\n throw error;\n }\n if (stat.isSymbolicLink()) {\n throw new Error(`secure-store migration root must not be a symlink: ${dir}`);\n }\n if (!stat.isDirectory()) {\n throw new Error(`secure-store migration root must be a directory: ${dir}`);\n }\n return lstatPath;\n}\n\nfunction normalizePathForLstat(filePath: string): string {\n return stripTrailingPathSeparators(path.normalize(filePath));\n}\n\nfunction isFsErrorWithCode(error: unknown, code: string): boolean {\n return typeof error === \"object\" && error !== null && (error as { code?: unknown }).code === code;\n}\n\nfunction stripTrailingPathSeparators(filePath: string): string {\n const root = path.parse(filePath).root;\n let end = filePath.length;\n while (\n end > root.length &&\n (filePath[end - 1] === path.sep || filePath[end - 1] === path.posix.sep || filePath[end - 1] === path.win32.sep)\n ) {\n end -= 1;\n }\n return end === filePath.length ? filePath : filePath.slice(0, end);\n}\n\nfunction isEncryptableStoragePath(filePath: string, rootDir: string): boolean {\n const rel = path.relative(rootDir, filePath);\n if (rel === \"\" || rel.startsWith(\"..\") || path.isAbsolute(rel)) return false;\n const normalized = normalizeStorageRelativePath(rel);\n if (normalized === \"profile.md\") return true;\n if (isEncryptableStateSidecar(normalized)) return true;\n if (isEncryptableSummarySidecar(normalized)) return true;\n const firstSegment = normalized.split(\"/\", 1)[0];\n return ENCRYPTABLE_MARKDOWN_STORAGE_ROOTS.has(firstSegment) && normalized.endsWith(\".md\");\n}\n\nfunction isDecryptableStoragePath(filePath: string, rootDir: string): boolean {\n if (isEncryptableStoragePath(filePath, rootDir)) return true;\n const rel = path.relative(rootDir, filePath);\n if (rel === \"\" || rel.startsWith(\"..\") || path.isAbsolute(rel)) return false;\n const normalized = normalizeStorageRelativePath(rel);\n const firstSegment = normalized.split(\"/\", 1)[0];\n return DECRYPTABLE_SIDECAR_ROOTS.has(firstSegment);\n}\n\nfunction normalizeStorageRelativePath(rel: string): string {\n const normalized = rel.split(path.sep).join(\"/\");\n const parts = normalized.split(\"/\");\n if (parts[0] === \"namespaces\" && parts.length >= 3) {\n return parts.slice(2).join(\"/\");\n }\n return normalized;\n}\n\n// Every recall MEMORY category directory (facts/ + the CATEGORY_DIR_MAP memory\n// dirs) must be encryptable at rest — #1546 routes decision/preference/moment/...\n// memories into their own dirs, so hardcoding only facts/corrections/procedures/\n// reasoning-traces would silently write those categories in plaintext on\n// encrypted stores. RECALL_FALLBACK_DIRS is the single source of truth for that\n// set; the extra non-category markdown roots (artifacts/archive/entities/\n// identity) are appended.\n//\n// questions/ is deliberately EXCLUDED (RECALL_FALLBACK_DIRS omits the non-memory\n// queue dirs): the question queue is written/resolved through plain readFile/\n// writeFile (StorageManager.writeQuestion/resolveQuestion), NOT the secure-file\n// helpers. Encrypting questions/ here would make migration seal those files,\n// after which resolveQuestion() would read ciphertext as UTF-8, fail to update\n// the frontmatter, and overwrite/corrupt the file while returning success\n// (codex #1563 review). Keeping questions/ plaintext preserves the queue's\n// existing behavior; #1546 does not change question encryption.\nconst ENCRYPTABLE_MARKDOWN_STORAGE_ROOTS = new Set<string>([\n ...RECALL_FALLBACK_DIRS,\n \"artifacts\",\n \"archive\",\n \"entities\",\n \"identity\",\n]);\n\nconst ENCRYPTABLE_STATE_SIDECARS = new Set([\n \"state/behavior-signals.jsonl\",\n \"state/buffer-surprise-ledger.jsonl\",\n \"state/buffer.json\",\n \"state/compression-guideline-draft-state.json\",\n \"state/compression-guideline-state.json\",\n \"state/compression-guidelines.draft.md\",\n \"state/compression-guidelines.md\",\n \"state/entity-synthesis-queue.json\",\n \"state/fact-hashes.txt\",\n \"state/memory-actions.jsonl\",\n \"state/memory-lifecycle-ledger.jsonl\",\n \"state/meta.json\",\n \"state/reextract-jobs.jsonl\",\n \"state/topics.json\",\n]);\n\nfunction isEncryptableStateSidecar(normalized: string): boolean {\n return ENCRYPTABLE_STATE_SIDECARS.has(normalized);\n}\n\nfunction isEncryptableSummarySidecar(normalized: string): boolean {\n return normalized.startsWith(\"summaries/\") && normalized.endsWith(\".json\");\n}\n\nconst DECRYPTABLE_SIDECAR_ROOTS = new Set([\"state\", \"indexes\", \"index\", \"provenance\"]);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AA6CA,SAAS,gBAAgB,kBAAkB,aAAa,kBAAkB;AAC1E,SAAS,OAAO,OAAO,QAAQ,UAAU,UAAU,SAAS,QAAQ,QAAQ,iBAAiB;AAC7F,OAAO,UAAU;AA0BV,IAAM,yBAAN,cAAqC,MAAM;AAAA,EAChD,YAAY,UAAU,6EAAwE;AAC5F,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAOO,IAAM,0BAAN,cAAsC,MAAM;AAAA,EACjD,YAAY,UAAU,0EAAqE;AACzF,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAOO,IAAM,cAAc,OAAO,KAAK,cAAc,OAAO;AAGrD,IAAM,sBAAsB;AAG5B,IAAM,oBAAoB;AAG1B,IAAM,oBAAoB,YAAY,SAAS;AAY/C,IAAM,uCAAuC,oBAAoB;AAUjE,SAAS,gBAAgB,KAA0B;AACxD,MAAI,IAAI,SAAS,kBAAmB,QAAO;AAC3C,QAAM,IAAI,OAAO,SAAS,GAAG,IAAI,MAAM,OAAO,KAAK,GAAG;AACtD,SAAO,EAAE,SAAS,GAAG,YAAY,MAAM,EAAE,OAAO,WAAW;AAC7D;AAMA,eAAe,qBAAqB,QAA8B,QAAiC;AACjG,MAAI,YAAY;AAChB,SAAO,YAAY,OAAO,QAAQ;AAChC,UAAM,SAAS,MAAM,OAAO,KAAK,QAAQ,WAAW,OAAO,SAAS,WAAW,SAAS;AACxF,QAAI,OAAO,cAAc,EAAG;AAC5B,iBAAa,OAAO;AAAA,EACtB;AACA,SAAO;AACT;AAaA,eAAsB,gCAAgC,WAAqC;AACzF,MAAI;AACJ,MAAI;AACF,gBAAY,MAAM,MAAM,SAAS;AAAA,EACnC,SAAS,KAAK;AACZ,QAAI,YAAY,KAAK,QAAQ,EAAG,QAAO;AACvC,UAAM;AAAA,EACR;AACA,MAAI,CAAC,UAAU,OAAO,GAAG;AACvB,UAAM,IAAI;AAAA,MACR,4CAA4C,SAAS;AAAA,IAEvD;AAAA,EACF;AACA,QAAM,SAAS,MAAM,SAAS,WAAW,GAAG;AAC5C,MAAI;AACF,UAAM,SAAS,OAAO,MAAM,iBAAiB;AAC7C,UAAM,YAAY,MAAM,qBAAqB,QAAQ,MAAM;AAC3D,WAAO,gBAAgB,OAAO,SAAS,GAAG,SAAS,CAAC;AAAA,EACtD,UAAE;AACA,UAAM,OAAO,MAAM;AAAA,EACrB;AACF;AAgBO,SAAS,gBAAgB,OAAwB,KAAa,KAAsB;AACzF,QAAM,WAAW,OAAO,UAAU,WAAW,OAAO,KAAK,OAAO,MAAM,IAAI;AAC1E,QAAM,OAAO,aAAa;AAC1B,QAAM,WAAW,KAAK,KAAK,MAAM,UAAU,MAAM,EAAE,IAAI,IAAI,CAAC,CAAC;AAE7D,QAAM,SAAS,OAAO,MAAM,iBAAiB;AAC7C,cAAY,KAAK,QAAQ,CAAC;AAC1B,SAAO,WAAW,qBAAqB,YAAY,MAAM;AACzD,SAAO,WAAW,mBAAmB,YAAY,SAAS,CAAC;AAE3D,SAAO,OAAO,OAAO,CAAC,QAAQ,QAAQ,CAAC;AACzC;AAUO,SAAS,gBAAgB,KAAa,KAAa,KAAsB;AAC9E,MAAI,CAAC,gBAAgB,GAAG,GAAG;AACzB,UAAM,IAAI,MAAM,qEAAqE;AAAA,EACvF;AACA,QAAM,UAAU,IAAI,UAAU,YAAY,MAAM;AAChD,MAAI,YAAY,qBAAqB;AACnC,UAAM,IAAI;AAAA,MACR,oDAAoD,OAAO,yBAAyB,mBAAmB;AAAA,IACzG;AAAA,EACF;AACA,QAAM,QAAQ,IAAI,UAAU,YAAY,SAAS,CAAC;AAClD,MAAI,UAAU,mBAAmB;AAC/B,UAAM,IAAI,MAAM,yCAAyC,MAAM,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAAE;AAAA,EAChG;AACA,QAAM,WAAW,IAAI,SAAS,iBAAiB;AAC/C,gBAAc,QAAQ;AACtB,MAAI;AACF,WAAO,KAAa,KAAK,UAAU,MAAM,EAAE,IAAI,IAAI,CAAC,CAAC;AAAA,EACvD,SAAS,KAAK;AACZ,UAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,UAAM,IAAI,wBAAwB,mCAAmC,GAAG,EAAE;AAAA,EAC5E;AACF;AAEA,SAAS,eAAe,MAA0B;AAChD,QAAM,MAAM,OAAO,MAAM,IAAI,oBAAoB;AACjD,MAAI,WAAW,kBAAkB,CAAC;AAClC,SAAO,KAAK,IAAI,EAAE,KAAK,KAAK,CAAC;AAC7B,SAAO;AACT;AAcO,SAAS,YAAY,UAAkB,WAA4B;AACxE,MAAI,MAAM;AACV,MAAI,aAAa,KAAK,WAAW,QAAQ,GAAG;AAC1C,UAAM,KAAK,SAAS,WAAW,QAAQ;AAAA,EACzC;AACA,SAAO,OAAO,KAAK,KAAK,MAAM;AAChC;AAoBA,eAAsB,6BACpB,UACA,KACA,WACiB;AACjB,QAAM,MAAM,MAAM,SAAS,QAAQ;AACnC,MAAI,CAAC,gBAAgB,GAAG,GAAG;AAEzB,WAAO;AAAA,EACT;AAEA,MAAI,QAAQ,MAAM;AAChB,UAAM,IAAI;AAAA,MACR,+DAA0D,QAAQ;AAAA,IACpE;AAAA,EACF;AACA,SAAO,uBAAuB,KAAK,KAAK,UAAU,SAAS;AAC7D;AAEA,eAAsB,uBACpB,UACA,KACA,WACiB;AACjB,UAAQ,MAAM,6BAA6B,UAAU,KAAK,SAAS,GAAG,SAAS,MAAM;AACvF;AAyBA,eAAsB,wBACpB,UACA,SACA,KACA,UAA0C,CAAC,GAC3C,WACe;AACf,QAAM,EAAE,OAAO,KAAO,SAAS,KAAK,IAAI;AACxC,QAAM,MAAM,KAAK,QAAQ,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;AAEvD,MAAI;AACJ,MAAI,QAAQ,MAAM;AAChB,UAAM,MAAM,YAAY,UAAU,SAAS;AAC3C,WAAO,gBAAgB,SAAS,KAAK,GAAG;AAAA,EAC1C,OAAO;AACL,WAAO;AAAA,EACT;AAEA,MAAI,QAAQ;AACV,UAAM,WAAW,qBAAqB,UAAU,KAAK;AACrD,QAAI;AACF,YAAM,UAAU,UAAU,MAAM,EAAE,KAAK,CAAC;AACxC,YAAM,OAAO,UAAU,QAAQ;AAAA,IACjC,SAAS,KAAK;AAEZ,UAAI;AACF,cAAM,OAAO,QAAQ;AAAA,MACvB,QAAQ;AAAA,MAER;AACA,YAAM;AAAA,IACR;AAAA,EACF,OAAO;AACL,UAAM,UAAU,UAAU,MAAM,EAAE,KAAK,CAAC;AAAA,EAC1C;AACF;AAEA,eAAsB,kCACpB,UACA,QACA,KACA,UAA0C,CAAC,GAC3C,WACe;AACf,QAAM,EAAE,OAAO,KAAO,SAAS,KAAK,IAAI;AACxC,QAAM,MAAM,KAAK,QAAQ,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;AACvD,QAAM,YAAY,SAAS,GAAG,QAAQ,QAAQ,QAAQ,GAAG,IAAI,KAAK,IAAI,CAAC,KAAK;AAC5E,MAAI,YAAY;AAChB,MAAI;AACF,UAAM,SAAS,MAAM,SAAS,WAAW,KAAK,IAAI;AAClD,QAAI;AACF,UAAI,QAAQ,MAAM;AAChB,cAAM,OAAO,aAAa;AAC1B,cAAM,KAAK,YAAY,SAAS;AAChC,cAAM,SAAS,OAAO,MAAM,oBAAoB,oBAAoB;AACpE,oBAAY,KAAK,QAAQ,CAAC;AAC1B,eAAO,WAAW,qBAAqB,YAAY,MAAM;AACzD,eAAO,WAAW,mBAAmB,YAAY,SAAS,CAAC;AAC3D,cAAM,iBAAiB;AACvB,eAAO,WAAW,kBAAkB,iBAAiB,gBAAgB,OAAO;AAC5E,aAAK,KAAK,QAAQ,iBAAiB,gBAAgB,IAAI;AACvD,WAAG,KAAK,QAAQ,iBAAiB,gBAAgB,EAAE;AACnD,cAAM,OAAO,MAAM,MAAM;AAEzB,cAAM,SAAS,eAAe,eAAe,KAAK,IAAI,EAAE,eAAe,gBAAgB,CAAC;AACxF,cAAM,MAAM,YAAY,UAAU,SAAS;AAC3C,eAAO,OAAO,OAAO,OAAO,CAAC,eAAe,IAAI,GAAG,GAAG,CAAC,CAAC;AACxD,yBAAiB,SAAS,QAAQ;AAChC,cAAI,MAAM,WAAW,EAAG;AACxB,gBAAM,YAAY,OAAO,OAAO,KAAK;AACrC,cAAI,UAAU,SAAS,EAAG,OAAM,OAAO,MAAM,SAAS;AAAA,QACxD;AACA,cAAM,QAAQ,OAAO,MAAM;AAC3B,YAAI,MAAM,SAAS,EAAG,OAAM,OAAO,MAAM,KAAK;AAC9C,cAAM,UAAU,OAAO,WAAW;AAClC,cAAM,OAAO,MAAM,SAAS,GAAG,QAAQ,QAAQ,oBAAoB,gBAAgB,OAAO;AAAA,MAC5F,OAAO;AACL,yBAAiB,SAAS,QAAQ;AAChC,cAAI,MAAM,SAAS,EAAG,OAAM,OAAO,MAAM,KAAK;AAAA,QAChD;AAAA,MACF;AAAA,IACF,UAAE;AACA,YAAM,OAAO,MAAM;AAAA,IACrB;AACA,QAAI,QAAQ;AACV,YAAM,OAAO,WAAW,QAAQ;AAAA,IAClC;AACA,gBAAY;AAAA,EACd,UAAE;AACA,QAAI,CAAC,aAAa,QAAQ;AACxB,YAAM,OAAO,SAAS,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AAAA,IACxC;AAAA,EACF;AACF;AAOA,gBAAuB,iCACrB,UACA,KACA,WACA,YAAY,KAAK,MACM;AACvB,QAAM,SAAS,MAAM,SAAS,UAAU,GAAG;AAC3C,QAAM,aAAa,oBAAoB;AACvC,MAAI;AACF,UAAM,SAAS,OAAO,MAAM,UAAU;AACtC,UAAM,cAAc,MAAM,qBAAqB,QAAQ,MAAM;AAC7D,UAAM,aAAa,OAAO,SAAS,GAAG,WAAW;AACjD,QAAI,CAAC,gBAAgB,UAAU,GAAG;AAChC,UAAI,cAAc,EAAG,OAAM,OAAO,KAAK,UAAU;AACjD,UAAIA,YAAW;AACf,YAAMC,UAAS,OAAO,MAAM,SAAS;AACrC,iBAAS;AACP,cAAM,EAAE,UAAU,IAAI,MAAM,OAAO,KAAKA,SAAQ,GAAGA,QAAO,QAAQD,SAAQ;AAC1E,YAAI,cAAc,EAAG;AACrB,QAAAA,aAAY;AACZ,cAAM,OAAO,KAAKC,QAAO,SAAS,GAAG,SAAS,CAAC;AAAA,MACjD;AACA;AAAA,IACF;AACA,QAAI,cAAc,YAAY;AAC5B,YAAM,IAAI,MAAM,uCAAuC,QAAQ,EAAE;AAAA,IACnE;AACA,QAAI,QAAQ,MAAM;AAChB,YAAM,IAAI;AAAA,QACR,+DAA0D,QAAQ;AAAA,MAEpE;AAAA,IACF;AACA,UAAM,WAAW,OAAO,SAAS,iBAAiB;AAClD,UAAM,UAAU,SAAS,UAAU,gBAAgB,OAAO;AAC1D,QAAI,YAAY,kBAAkB;AAChC,YAAM,IAAI,MAAM,8CAA8C,OAAO,EAAE;AAAA,IACzE;AACA,UAAM,OAAO,SAAS,SAAS,gBAAgB,MAAM,gBAAgB,OAAO,oBAAoB;AAChG,UAAM,KAAK,SAAS,SAAS,gBAAgB,IAAI,gBAAgB,KAAK,SAAS;AAC/E,UAAM,UAAU,SAAS,SAAS,gBAAgB,SAAS,gBAAgB,UAAU,eAAe;AACpG,UAAM,WAAW,iBAAiB,eAAe,KAAK,IAAI,EAAE,eAAe,gBAAgB,CAAC;AAC5F,aAAS,OAAO,OAAO,OAAO,CAAC,eAAe,IAAI,GAAG,YAAY,UAAU,SAAS,CAAC,CAAC,CAAC;AACvF,aAAS,WAAW,OAAO;AAC3B,QAAI,WAAW;AACf,UAAM,SAAS,OAAO,MAAM,SAAS;AACrC,QAAI;AACF,iBAAS;AACP,cAAM,EAAE,UAAU,IAAI,MAAM,OAAO,KAAK,QAAQ,GAAG,OAAO,QAAQ,QAAQ;AAC1E,YAAI,cAAc,EAAG;AACrB,oBAAY;AACZ,cAAM,QAAQ,SAAS,OAAO,OAAO,SAAS,GAAG,SAAS,CAAC;AAC3D,YAAI,MAAM,SAAS,EAAG,OAAM;AAAA,MAC9B;AACA,YAAM,QAAQ,SAAS,MAAM;AAC7B,UAAI,MAAM,SAAS,EAAG,OAAM;AAAA,IAC9B,SAAS,KAAK;AACZ,UAAI,eAAe,wBAAyB,OAAM;AAClD,YAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,YAAM,IAAI,wBAAwB,mCAAmC,OAAO,EAAE;AAAA,IAChF;AAAA,EACF,UAAE;AACA,UAAM,OAAO,MAAM;AAAA,EACrB;AACF;AA6CA,eAAsB,4BACpB,KACA,KACA,iBACwB;AACxB,QAAM,SAAwB,EAAE,WAAW,GAAG,SAAS,GAAG,QAAQ,CAAC,EAAE;AAErE,QAAM,QAAQ,MAAM,+BAA+B,GAAG;AACtD,aAAW,YAAY,OAAO;AAC5B,QAAI;AACF,YAAM,MAAM,MAAM,SAAS,QAAQ;AACnC,UAAI,gBAAgB,GAAG,GAAG;AACxB,eAAO;AACP;AAAA,MACF;AAEA,UAAI,iBAAiB;AACnB,YAAI;AACF,gBAAM,gBAAgB,QAAQ;AAAA,QAChC,QAAQ;AAAA,QAER;AAAA,MACF;AACA,YAAM,UAAU,IAAI,SAAS,MAAM;AACnC,YAAM,MAAM,YAAY,UAAU,GAAG;AACrC,YAAM,YAAY,gBAAgB,SAAS,KAAK,GAAG;AAGnD,YAAM,WAAW,qBAAqB,UAAU,SAAS;AACzD,UAAI;AACF,cAAM,UAAU,UAAU,WAAW,EAAE,MAAM,IAAM,CAAC;AACpD,cAAM,OAAO,UAAU,QAAQ;AAC/B,eAAO;AAAA,MACT,SAAS,UAAU;AAEjB,YAAI;AACF,gBAAM,EAAE,QAAAC,QAAO,IAAI,MAAM,OAAO,aAAkB;AAClD,gBAAMA,QAAO,QAAQ;AAAA,QACvB,QAAQ;AAAA,QAER;AACA,cAAM;AAAA,MACR;AAAA,IACF,SAAS,KAAK;AACZ,aAAO,OAAO,KAAK;AAAA,QACjB;AAAA,QACA,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,MACxD,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AACT;AAYA,eAAsB,4BAA4B,KAAa,KAAqC;AAClG,QAAM,SAAwB,EAAE,WAAW,GAAG,SAAS,GAAG,QAAQ,CAAC,EAAE;AAErE,QAAM,QAAQ,MAAM,2BAA2B,KAAK,wBAAwB;AAC5E,aAAW,YAAY,OAAO;AAC5B,QAAI;AACF,YAAM,MAAM,MAAM,SAAS,QAAQ;AACnC,UAAI,CAAC,gBAAgB,GAAG,GAAG;AACzB,eAAO;AACP;AAAA,MACF;AAEA,YAAM,YAAY,uBAAuB,KAAK,KAAK,UAAU,GAAG;AAChE,YAAM,WAAW,qBAAqB,UAAU,SAAS;AACzD,UAAI;AACF,cAAM,UAAU,UAAU,WAAW,EAAE,MAAM,IAAM,CAAC;AACpD,cAAM,OAAO,UAAU,QAAQ;AAC/B,eAAO;AAAA,MACT,SAAS,UAAU;AACjB,YAAI;AACF,gBAAM,OAAO,QAAQ;AAAA,QACvB,QAAQ;AAAA,QAER;AACA,cAAM;AAAA,MACR;AAAA,IACF,SAAS,KAAK;AACZ,aAAO,OAAO,KAAK;AAAA,QACjB;AAAA,QACA,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,MACxD,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AACT;AAMA,SAAS,qBAAqB,UAAkB,OAAuB;AACrE,SAAO,GAAG,QAAQ,IAAI,KAAK,IAAI,QAAQ,GAAG,IAAI,KAAK,IAAI,CAAC,IAAI,WAAW,CAAC;AAC1E;AAEA,SAAS,uBAAuB,KAAa,KAAa,UAAkB,WAA4B;AACtG,QAAM,MAAM,YAAY,UAAU,SAAS;AAC3C,MAAI;AACF,WAAO,gBAAgB,KAAK,KAAK,GAAG;AAAA,EACtC,SAAS,KAAK;AACZ,QAAI,EAAE,eAAe,0BAA0B;AAC7C,YAAM;AAAA,IACR;AACA,UAAM,aAAa,8BAA8B,UAAU,SAAS;AACpE,QAAI,YAAY;AACd,UAAI;AACF,eAAO,gBAAgB,KAAK,KAAK,YAAY,UAAU,UAAU,CAAC;AAAA,MACpE,QAAQ;AAAA,MAER;AAAA,IACF;AAEA,UAAM,eAAe,kCAAkC,UAAU,SAAS;AAC1E,QAAI,cAAc;AAChB,UAAI;AACF,eAAO,gBAAgB,KAAK,KAAK,YAAY,UAAU,YAAY,CAAC;AAAA,MACtE,QAAQ;AAAA,MAER;AAAA,IACF;AAEA,UAAM;AAAA,EACR;AACF;AAEA,SAAS,kCAAkC,UAAkB,WAAmC;AAC9F,MAAI,CAAC,aAAa,CAAC,KAAK,WAAW,QAAQ,EAAG,QAAO;AACrD,QAAM,oBAAoB,KAAK,QAAQ,SAAS;AAChD,QAAM,MAAM,KAAK,SAAS,mBAAmB,QAAQ;AACrD,MAAI,QAAQ,MAAM,IAAI,WAAW,IAAI,KAAK,KAAK,WAAW,GAAG,EAAG,QAAO;AACvE,QAAM,QAAQ,kBAAkB,MAAM,KAAK,GAAG;AAC9C,MAAI,MAAM,SAAS,KAAK,MAAM,GAAG,EAAE,MAAM,gBAAgB,CAAC,MAAM,GAAG,EAAE,EAAG,QAAO;AAC/E,QAAM,eAAe,MAAM,MAAM,GAAG,EAAE,EAAE,KAAK,KAAK,GAAG,KAAK,KAAK;AAC/D,QAAM,SAAS,KAAK,SAAS,cAAc,QAAQ;AACnD,MAAI,WAAW,MAAM,OAAO,WAAW,IAAI,KAAK,KAAK,WAAW,MAAM,GAAG;AACvE,WAAO;AAAA,EACT;AACA,QAAM,WAAW,OAAO,MAAM,KAAK,GAAG;AACtC,MAAI,SAAS,CAAC,MAAM,gBAAgB,SAAS,CAAC,MAAM,MAAM,GAAG,EAAE,GAAG;AAChE,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,8BAA8B,UAAkB,WAAmC;AAC1F,MAAI,CAAC,aAAa,CAAC,KAAK,WAAW,QAAQ,EAAG,QAAO;AACrD,QAAM,MAAM,KAAK,SAAS,WAAW,QAAQ;AAC7C,MAAI,QAAQ,MAAM,IAAI,WAAW,IAAI,KAAK,KAAK,WAAW,GAAG,EAAG,QAAO;AACvE,QAAM,QAAQ,IAAI,MAAM,KAAK,GAAG;AAChC,MAAI,MAAM,CAAC,MAAM,gBAAgB,MAAM,UAAU,KAAK,MAAM,CAAC,GAAG;AAC9D,WAAO,KAAK,KAAK,WAAW,cAAc,MAAM,CAAC,CAAC;AAAA,EACpD;AACA,SAAO;AACT;AAOA,eAAe,+BAA+B,KAAa,UAAU,KAAwB;AAC3F,SAAO,2BAA2B,KAAK,0BAA0B,OAAO;AAC1E;AAQA,eAAe,2BACb,KACA,aACA,UAAU,KACS;AACnB,QAAM,UAAoB,CAAC;AAC3B,MAAI,UAAU;AACd,MAAI,cAAc;AAClB,MAAI,KAAK,QAAQ,GAAG,MAAM,KAAK,QAAQ,OAAO,GAAG;AAC/C,UAAM,iBAAiB,MAAM,iCAAiC,GAAG;AACjE,QAAI,CAAC,eAAgB,QAAO;AAC5B,cAAU;AACV,kBAAc;AAAA,EAChB;AACA,MAAI;AACJ,MAAI;AACF,YAAQ,MAAM,QAAQ,SAAS,EAAE,UAAU,OAAO,CAAC;AAAA,EACrD,QAAQ;AACN,WAAO;AAAA,EACT;AACA,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,WAAW,eAAe,EAAG;AACtC,UAAM,OAAO,KAAK,KAAK,SAAS,IAAI;AACpC,QAAI,QAAQ;AACZ,QAAI,SAAS;AACb,QAAI;AACF,YAAM,IAAI,MAAM,MAAM,IAAI;AAC1B,UAAI,EAAE,eAAe,EAAG;AACxB,cAAQ,EAAE,YAAY;AACtB,eAAS,EAAE,OAAO;AAAA,IACpB,QAAQ;AACN;AAAA,IACF;AACA,QAAI,OAAO;AACT,YAAM,MAAM,MAAM,2BAA2B,MAAM,aAAa,WAAW;AAC3E,cAAQ,KAAK,GAAG,GAAG;AAAA,IACrB,WAAW,UAAU,YAAY,MAAM,WAAW,GAAG;AACnD,cAAQ,KAAK,IAAI;AAAA,IACnB;AAAA,EACF;AACA,SAAO;AACT;AAEA,eAAe,iCAAiC,KAAqC;AACnF,QAAM,YAAY,sBAAsB,GAAG;AAC3C,MAAI;AACJ,MAAI;AACF,WAAO,MAAM,MAAM,SAAS;AAAA,EAC9B,SAAS,OAAO;AACd,QAAI,kBAAkB,OAAO,QAAQ,EAAG,QAAO;AAC/C,UAAM;AAAA,EACR;AACA,MAAI,KAAK,eAAe,GAAG;AACzB,UAAM,IAAI,MAAM,sDAAsD,GAAG,EAAE;AAAA,EAC7E;AACA,MAAI,CAAC,KAAK,YAAY,GAAG;AACvB,UAAM,IAAI,MAAM,oDAAoD,GAAG,EAAE;AAAA,EAC3E;AACA,SAAO;AACT;AAEA,SAAS,sBAAsB,UAA0B;AACvD,SAAO,4BAA4B,KAAK,UAAU,QAAQ,CAAC;AAC7D;AAEA,SAAS,kBAAkB,OAAgB,MAAuB;AAChE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAS,MAA6B,SAAS;AAC/F;AAEA,SAAS,4BAA4B,UAA0B;AAC7D,QAAM,OAAO,KAAK,MAAM,QAAQ,EAAE;AAClC,MAAI,MAAM,SAAS;AACnB,SACE,MAAM,KAAK,WACV,SAAS,MAAM,CAAC,MAAM,KAAK,OAAO,SAAS,MAAM,CAAC,MAAM,KAAK,MAAM,OAAO,SAAS,MAAM,CAAC,MAAM,KAAK,MAAM,MAC5G;AACA,WAAO;AAAA,EACT;AACA,SAAO,QAAQ,SAAS,SAAS,WAAW,SAAS,MAAM,GAAG,GAAG;AACnE;AAEA,SAAS,yBAAyB,UAAkB,SAA0B;AAC5E,QAAM,MAAM,KAAK,SAAS,SAAS,QAAQ;AAC3C,MAAI,QAAQ,MAAM,IAAI,WAAW,IAAI,KAAK,KAAK,WAAW,GAAG,EAAG,QAAO;AACvE,QAAM,aAAa,6BAA6B,GAAG;AACnD,MAAI,eAAe,aAAc,QAAO;AACxC,MAAI,0BAA0B,UAAU,EAAG,QAAO;AAClD,MAAI,4BAA4B,UAAU,EAAG,QAAO;AACpD,QAAM,eAAe,WAAW,MAAM,KAAK,CAAC,EAAE,CAAC;AAC/C,SAAO,mCAAmC,IAAI,YAAY,KAAK,WAAW,SAAS,KAAK;AAC1F;AAEA,SAAS,yBAAyB,UAAkB,SAA0B;AAC5E,MAAI,yBAAyB,UAAU,OAAO,EAAG,QAAO;AACxD,QAAM,MAAM,KAAK,SAAS,SAAS,QAAQ;AAC3C,MAAI,QAAQ,MAAM,IAAI,WAAW,IAAI,KAAK,KAAK,WAAW,GAAG,EAAG,QAAO;AACvE,QAAM,aAAa,6BAA6B,GAAG;AACnD,QAAM,eAAe,WAAW,MAAM,KAAK,CAAC,EAAE,CAAC;AAC/C,SAAO,0BAA0B,IAAI,YAAY;AACnD;AAEA,SAAS,6BAA6B,KAAqB;AACzD,QAAM,aAAa,IAAI,MAAM,KAAK,GAAG,EAAE,KAAK,GAAG;AAC/C,QAAM,QAAQ,WAAW,MAAM,GAAG;AAClC,MAAI,MAAM,CAAC,MAAM,gBAAgB,MAAM,UAAU,GAAG;AAClD,WAAO,MAAM,MAAM,CAAC,EAAE,KAAK,GAAG;AAAA,EAChC;AACA,SAAO;AACT;AAkBA,IAAM,qCAAqC,oBAAI,IAAY;AAAA,EACzD,GAAG;AAAA,EACH;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,IAAM,6BAA6B,oBAAI,IAAI;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,SAAS,0BAA0B,YAA6B;AAC9D,SAAO,2BAA2B,IAAI,UAAU;AAClD;AAEA,SAAS,4BAA4B,YAA6B;AAChE,SAAO,WAAW,WAAW,YAAY,KAAK,WAAW,SAAS,OAAO;AAC3E;AAEA,IAAM,4BAA4B,oBAAI,IAAI,CAAC,SAAS,WAAW,SAAS,YAAY,CAAC;","names":["position","buffer","unlink"]}
|