@remnic/core 9.45.3 → 9.45.5
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 -75
- package/dist/access-audit.js +2 -2
- package/dist/access-authorization-probe.d.ts +14 -10
- package/dist/access-authorization-probe.js +85 -76
- package/dist/access-boundary.d.ts +15 -11
- package/dist/access-boundary.js +84 -75
- package/dist/access-citation-namespace.js +2 -2
- package/dist/access-cli.js +191 -177
- 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 -75
- 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 -75
- package/dist/access-http.d.ts +15 -11
- package/dist/access-http.js +104 -90
- package/dist/access-identity-continuity-surface.d.ts +9 -8
- package/dist/access-identity-continuity-surface.js +84 -75
- package/dist/access-lcm-surface.d.ts +14 -10
- package/dist/access-lcm-surface.js +84 -75
- package/dist/access-mcp-output-schemas.js +1 -1
- package/dist/access-mcp.d.ts +14 -10
- package/dist/access-mcp.js +95 -82
- 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 -75
- 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 -75
- 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 -77
- package/dist/access-operations.d.ts +18 -14
- package/dist/access-operations.js +91 -79
- package/dist/access-recall-concurrency.d.ts +16 -26
- package/dist/access-recall-concurrency.js +86 -76
- package/dist/access-recall-response.d.ts +18 -14
- package/dist/access-recall-response.js +84 -75
- package/dist/access-recall-surface.d.ts +29 -24
- package/dist/access-recall-surface.js +84 -75
- package/dist/access-schema.d.ts +84 -84
- package/dist/access-schema.js +3 -3
- package/dist/{access-service-CiJRsgAB.d.ts → access-service-CNN89xyn.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 -75
- 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 +4 -4
- package/dist/adapters/registry.js +2 -2
- 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 +24 -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 +28 -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-E5UK4VPE.js → chunk-2FSTB6BJ.js} +5 -5
- package/dist/{chunk-5ZE7QHTK.js → chunk-2X2T2UVE.js} +5 -5
- package/dist/{chunk-P4DRWEYC.js → chunk-3COYXTGM.js} +2 -2
- package/dist/{chunk-5IVLTFOV.js → chunk-44N6ESJ4.js} +2 -2
- package/dist/{chunk-DL7ZD3JH.js → chunk-4FBVAGV3.js} +14 -9
- package/dist/chunk-4FBVAGV3.js.map +1 -0
- 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-AAIUERNB.js → chunk-5QJQHBLE.js} +6 -6
- package/dist/{chunk-6CZPDBJS.js → chunk-5U7ID3EZ.js} +3 -3
- package/dist/{chunk-RN7DY3FC.js → chunk-6ISC4AVB.js} +31 -12
- package/dist/chunk-6ISC4AVB.js.map +1 -0
- package/dist/chunk-773TRRGT.js +36 -0
- package/dist/chunk-773TRRGT.js.map +1 -0
- package/dist/chunk-7T4TOGMS.js +242 -0
- package/dist/chunk-7T4TOGMS.js.map +1 -0
- package/dist/{chunk-DLVPUX7U.js → chunk-7YKVM5H3.js} +8 -6
- package/dist/chunk-7YKVM5H3.js.map +1 -0
- package/dist/chunk-7YQ6ESEA.js +322 -0
- package/dist/chunk-7YQ6ESEA.js.map +1 -0
- package/dist/{chunk-DNWXFTLD.js → chunk-A4IJCD2Z.js} +2 -2
- 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-PKNLM44P.js → chunk-AC5OWJLV.js} +9 -9
- package/dist/{chunk-LZ4LDKHZ.js → chunk-AMAUBUKY.js} +6 -6
- package/dist/{chunk-CUM2BBPN.js → chunk-AUMWZSE7.js} +19 -10
- package/dist/chunk-AUMWZSE7.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-CK5KOVHW.js +69 -0
- package/dist/chunk-CK5KOVHW.js.map +1 -0
- package/dist/{chunk-Q6IP2ARR.js → chunk-CSOYVTRX.js} +2 -2
- package/dist/{chunk-XOQSEF7X.js → chunk-CVILPI77.js} +6 -6
- package/dist/{chunk-VWAXN2BN.js → chunk-CX4ZUMC6.js} +91 -83
- package/dist/chunk-CX4ZUMC6.js.map +1 -0
- package/dist/{chunk-NVRYW264.js → chunk-DAJPRXBR.js} +16 -13
- package/dist/chunk-DAJPRXBR.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-4LMA77JH.js → chunk-E5XQIWAL.js} +3 -3
- package/dist/{chunk-WUNIWKY4.js → chunk-ELIL2A37.js} +6 -6
- package/dist/{chunk-OQ5PRDDS.js → chunk-ERZ2R42X.js} +6 -6
- package/dist/{chunk-U7GW7NE7.js → chunk-FIK3CQNA.js} +10 -10
- package/dist/{chunk-D3J5SLQK.js → chunk-FR27HBBA.js} +81 -20
- package/dist/chunk-FR27HBBA.js.map +1 -0
- package/dist/{chunk-E6PNLPGJ.js → chunk-FUCYDRE5.js} +838 -480
- package/dist/chunk-FUCYDRE5.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-33PLLLL7.js → chunk-GFCVUY6G.js} +6 -6
- package/dist/{chunk-HREE4JHI.js → chunk-GODSPTOT.js} +477 -278
- package/dist/chunk-GODSPTOT.js.map +1 -0
- package/dist/{chunk-S2NCTZGJ.js → chunk-GRUYA45P.js} +15 -15
- package/dist/chunk-GRUYA45P.js.map +1 -0
- package/dist/{chunk-VUPTKTDV.js → chunk-GUAL4PQH.js} +3 -3
- 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-PDLBLTOK.js → chunk-HC3PBX23.js} +9 -9
- 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-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-HLPD7B7P.js → chunk-JZH4LWHB.js} +2 -2
- package/dist/{chunk-AV5ZEH4M.js → chunk-KVJRXN2E.js} +2 -2
- package/dist/{chunk-WFTIGIIS.js → chunk-L6CQ7WIW.js} +5 -5
- package/dist/{chunk-227UFSEQ.js → chunk-LEPOP46W.js} +4 -4
- 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-QN25OCUF.js → chunk-LPYDOLSM.js} +5 -5
- package/dist/{chunk-AS7YMSL6.js → chunk-M23RF3LJ.js} +4 -4
- package/dist/{chunk-OAEQLRCY.js → chunk-MO4HSXHZ.js} +5 -5
- package/dist/{chunk-ECK75GDJ.js → chunk-N3LL5NEU.js} +43 -24
- package/dist/chunk-N3LL5NEU.js.map +1 -0
- package/dist/chunk-NEF7LR5J.js +29 -0
- package/dist/chunk-NEF7LR5J.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-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-7TWUCYER.js → chunk-PNRA7FAD.js} +7 -7
- package/dist/{chunk-5I4M26Q7.js → chunk-QBSFOKY6.js} +4 -4
- package/dist/{chunk-E53DSZEN.js → chunk-QR6G5KF4.js} +3 -3
- package/dist/{chunk-CJ2ZR7UA.js → chunk-QUENPGWZ.js} +261 -211
- package/dist/chunk-QUENPGWZ.js.map +1 -0
- package/dist/{chunk-4UH4BTGK.js → chunk-QVJPH7SH.js} +84 -84
- package/dist/{chunk-UYLMNVY6.js → chunk-R3KHKU7M.js} +16 -9
- package/dist/chunk-R3KHKU7M.js.map +1 -0
- package/dist/{chunk-JBPKEARU.js → chunk-RKNJBZ55.js} +4 -4
- package/dist/{chunk-WDISJRMG.js → chunk-RMMVQQA6.js} +2 -2
- package/dist/{chunk-JVLCVFQ4.js → chunk-RNHVVMFN.js} +3 -3
- package/dist/{chunk-QJAQNXWI.js → chunk-RVO6TCTU.js} +81 -84
- package/dist/chunk-RVO6TCTU.js.map +1 -0
- package/dist/chunk-S2HLHAZ4.js +16 -0
- package/dist/chunk-S2HLHAZ4.js.map +1 -0
- 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-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-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-BJKPPZ6Z.js → chunk-UW66OZTD.js} +2 -2
- package/dist/{chunk-XYTOI63Z.js → chunk-V2TNYF6Q.js} +19 -11
- package/dist/chunk-V2TNYF6Q.js.map +1 -0
- 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-VL35ZFSZ.js +102 -0
- package/dist/chunk-VL35ZFSZ.js.map +1 -0
- package/dist/{chunk-3Y224NYC.js → chunk-VYISFWVX.js} +2 -2
- package/dist/{chunk-JE7EK33X.js → chunk-W2V7UESE.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-A5OJCXZL.js → chunk-WZ3TOIDW.js} +15 -4
- package/dist/chunk-WZ3TOIDW.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-UVIKWC7M.js → chunk-XAGYS7X6.js} +17 -17
- 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-E6EE5B67.js → chunk-YK6BDDHP.js} +4 -4
- package/dist/{chunk-ES36HTSC.js → chunk-YLHM5BQQ.js} +3 -3
- 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-VOUOLGIP.js → chunk-YRFAYOFQ.js} +11 -13
- package/dist/chunk-YRFAYOFQ.js.map +1 -0
- package/dist/{chunk-IKKWIPYN.js → chunk-YYQAKIDJ.js} +37 -1
- package/dist/chunk-YYQAKIDJ.js.map +1 -0
- package/dist/{chunk-GF22HWS2.js → chunk-Z54EM5YZ.js} +4 -4
- package/dist/{chunk-64UDOIMI.js → chunk-ZLQ37WJX.js} +2 -2
- package/dist/{cli-BUGN3d6_.d.ts → cli-BHBswmUa.d.ts} +5 -5
- package/dist/cli.d.ts +16 -12
- package/dist/cli.js +138 -123
- package/dist/compounding/engine.d.ts +3 -2
- package/dist/compounding/engine.js +25 -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 +24 -22
- package/dist/connectors/codex-materialize.d.ts +2 -1
- package/dist/connectors/index.d.ts +2 -1
- package/dist/connectors/index.js +27 -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 +28 -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 +43 -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 +25 -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 +187 -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 +10 -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 +39 -0
- package/dist/external-wiki.js +14 -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 +46 -43
- package/dist/fallback-llm.d.ts +2 -1
- package/dist/{first-start-migration-F2QJD66E.js → first-start-migration-ZSHEFEI3.js} +10 -12
- package/dist/{first-start-migration-F2QJD66E.js.map → first-start-migration-ZSHEFEI3.js.map} +1 -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 +443 -430
- package/dist/index.js +304 -269
- package/dist/intent.d.ts +2 -1
- package/dist/lcm/engine.d.ts +2 -1
- package/dist/lcm/engine.js +2 -2
- package/dist/lcm/index.d.ts +2 -1
- package/dist/lcm/index.js +7 -7
- 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 +25 -23
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +3 -2
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +25 -23
- package/dist/maintenance/rebuild-memory-projection.d.ts +3 -2
- package/dist/maintenance/rebuild-memory-projection.js +27 -25
- package/dist/{maintenance-LbuS2rUA.d.ts → maintenance-CoRikzIt.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-snapshot.d.ts +10 -0
- package/dist/memory-snapshot.js +8 -0
- package/dist/memory-snapshot.js.map +1 -0
- 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 +41 -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 +24 -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 +46 -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 +60 -55
- package/dist/orchestration/compression-guideline-coordinator.d.ts +3 -2
- package/dist/orchestration/maintenance.d.ts +5 -4
- package/dist/orchestration/maintenance.js +37 -33
- package/dist/{orchestrator-rHiWt32X.d.ts → orchestrator-BJeq7Pw1.d.ts} +14 -7
- package/dist/orchestrator.d.ts +9 -8
- package/dist/orchestrator.js +200 -186
- 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 +8 -8
- 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 +54 -54
- 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 +20 -20
- 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 +26 -24
- package/dist/semantic-rule-promotion.js +24 -22
- package/dist/semantic-rule-verifier.d.ts +2 -1
- package/dist/semantic-rule-verifier.js +25 -23
- package/dist/{service-DJG3KCQ4.d.ts → service-DWC4tq7p.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 +10 -9
- 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 +43 -40
- package/dist/{storage-F9FVh-w9.d.ts → storage-DPGjB-8e.d.ts} +28 -13
- package/dist/storage.d.ts +3 -2
- package/dist/storage.js +26 -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-migration.js +1 -1
- 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 +66 -66
- 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 +25 -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 +80 -0
- package/src/access-http.test.ts +310 -3
- package/src/access-http.ts +84 -77
- 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 +183 -23
- 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 +88 -62
- 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 +100 -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 +367 -0
- package/src/external-wiki-search.ts +362 -0
- package/src/external-wiki.test.ts +240 -0
- package/src/external-wiki.ts +427 -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 +9 -5
- package/src/maintenance/first-start-migration.ts +11 -11
- package/src/mcp-read-only-tools.ts +1 -0
- package/src/memory-snapshot.ts +15 -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-contract/cache-coherence.test.ts +99 -0
- package/src/storage-deletion-revisions.test.ts +91 -0
- package/src/storage-fact-hash-index-defer.test.ts +460 -170
- package/src/storage.ts +572 -284
- package/src/testing/subjects/first-start-tier-migration.test.ts +75 -0
- package/src/tier-migration.ts +10 -12
- 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-VOUOLGIP.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-E5UK4VPE.js.map → chunk-2FSTB6BJ.js.map} +0 -0
- /package/dist/{chunk-5ZE7QHTK.js.map → chunk-2X2T2UVE.js.map} +0 -0
- /package/dist/{chunk-P4DRWEYC.js.map → chunk-3COYXTGM.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-AAIUERNB.js.map → chunk-5QJQHBLE.js.map} +0 -0
- /package/dist/{chunk-6CZPDBJS.js.map → chunk-5U7ID3EZ.js.map} +0 -0
- /package/dist/{chunk-DNWXFTLD.js.map → chunk-A4IJCD2Z.js.map} +0 -0
- /package/dist/{chunk-PKNLM44P.js.map → chunk-AC5OWJLV.js.map} +0 -0
- /package/dist/{chunk-LZ4LDKHZ.js.map → chunk-AMAUBUKY.js.map} +0 -0
- /package/dist/{chunk-S5SLVSVY.js.map → chunk-BQIFZ2MP.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-4LMA77JH.js.map → chunk-E5XQIWAL.js.map} +0 -0
- /package/dist/{chunk-WUNIWKY4.js.map → chunk-ELIL2A37.js.map} +0 -0
- /package/dist/{chunk-OQ5PRDDS.js.map → chunk-ERZ2R42X.js.map} +0 -0
- /package/dist/{chunk-U7GW7NE7.js.map → chunk-FIK3CQNA.js.map} +0 -0
- /package/dist/{chunk-33PLLLL7.js.map → chunk-GFCVUY6G.js.map} +0 -0
- /package/dist/{chunk-VUPTKTDV.js.map → chunk-GUAL4PQH.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-PDLBLTOK.js.map → chunk-HC3PBX23.js.map} +0 -0
- /package/dist/{chunk-KXB4VXHY.js.map → chunk-JIYDRBVZ.js.map} +0 -0
- /package/dist/{chunk-HLPD7B7P.js.map → chunk-JZH4LWHB.js.map} +0 -0
- /package/dist/{chunk-AV5ZEH4M.js.map → chunk-KVJRXN2E.js.map} +0 -0
- /package/dist/{chunk-WFTIGIIS.js.map → chunk-L6CQ7WIW.js.map} +0 -0
- /package/dist/{chunk-227UFSEQ.js.map → chunk-LEPOP46W.js.map} +0 -0
- /package/dist/{chunk-EJUEXZHX.js.map → chunk-LLJMAULE.js.map} +0 -0
- /package/dist/{chunk-QN25OCUF.js.map → chunk-LPYDOLSM.js.map} +0 -0
- /package/dist/{chunk-AS7YMSL6.js.map → chunk-M23RF3LJ.js.map} +0 -0
- /package/dist/{chunk-OAEQLRCY.js.map → chunk-MO4HSXHZ.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-7TWUCYER.js.map → chunk-PNRA7FAD.js.map} +0 -0
- /package/dist/{chunk-5I4M26Q7.js.map → chunk-QBSFOKY6.js.map} +0 -0
- /package/dist/{chunk-E53DSZEN.js.map → chunk-QR6G5KF4.js.map} +0 -0
- /package/dist/{chunk-4UH4BTGK.js.map → chunk-QVJPH7SH.js.map} +0 -0
- /package/dist/{chunk-JBPKEARU.js.map → chunk-RKNJBZ55.js.map} +0 -0
- /package/dist/{chunk-WDISJRMG.js.map → chunk-RMMVQQA6.js.map} +0 -0
- /package/dist/{chunk-JVLCVFQ4.js.map → chunk-RNHVVMFN.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-7K5Q6COX.js.map → chunk-TVVEYCNW.js.map} +0 -0
- /package/dist/{chunk-4B77XSG5.js.map → chunk-UV72DEZD.js.map} +0 -0
- /package/dist/{chunk-BJKPPZ6Z.js.map → chunk-UW66OZTD.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-JE7EK33X.js.map → chunk-W2V7UESE.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-UVIKWC7M.js.map → chunk-XAGYS7X6.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-E6EE5B67.js.map → chunk-YK6BDDHP.js.map} +0 -0
- /package/dist/{chunk-ES36HTSC.js.map → chunk-YLHM5BQQ.js.map} +0 -0
- /package/dist/{chunk-GF22HWS2.js.map → chunk-Z54EM5YZ.js.map} +0 -0
- /package/dist/{chunk-64UDOIMI.js.map → chunk-ZLQ37WJX.js.map} +0 -0
|
@@ -1,12 +1,23 @@
|
|
|
1
1
|
import {
|
|
2
2
|
rebuildMemoryProjection
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-FIK3CQNA.js";
|
|
4
4
|
|
|
5
5
|
// src/convergence-refresh.ts
|
|
6
|
-
async function refreshConvergedNamespaces(namespaces, namespaceSearchRouter, getStorage) {
|
|
6
|
+
async function refreshConvergedNamespaces(namespaces, namespaceSearchRouter, getStorage, searchEnabled) {
|
|
7
7
|
const targetNamespaces = Array.from(new Set(namespaces.map((namespace) => namespace.trim()).filter(Boolean)));
|
|
8
8
|
if (targetNamespaces.length === 0) return;
|
|
9
|
-
await namespaceSearchRouter.updateNamespacesDetailed(
|
|
9
|
+
const searchResult = await namespaceSearchRouter.updateNamespacesDetailed(
|
|
10
|
+
targetNamespaces,
|
|
11
|
+
void 0,
|
|
12
|
+
{ strict: true }
|
|
13
|
+
);
|
|
14
|
+
if (searchEnabled) {
|
|
15
|
+
const eligible = new Set(searchResult.eligibleNamespaces);
|
|
16
|
+
const skipped = targetNamespaces.filter((namespace) => !eligible.has(namespace));
|
|
17
|
+
if (skipped.length > 0) {
|
|
18
|
+
throw new Error(`search refresh skipped namespaces: ${skipped.join(", ")}`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
10
21
|
for (const namespace of targetNamespaces) {
|
|
11
22
|
const storage = await getStorage(namespace);
|
|
12
23
|
await rebuildMemoryProjection({
|
|
@@ -21,4 +32,4 @@ async function refreshConvergedNamespaces(namespaces, namespaceSearchRouter, get
|
|
|
21
32
|
export {
|
|
22
33
|
refreshConvergedNamespaces
|
|
23
34
|
};
|
|
24
|
-
//# sourceMappingURL=chunk-
|
|
35
|
+
//# sourceMappingURL=chunk-WZ3TOIDW.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/convergence-refresh.ts"],"sourcesContent":["import {\n type RebuildMemoryProjectionOptions,\n rebuildMemoryProjection,\n} from \"./maintenance/rebuild-memory-projection.js\";\nimport type { NamespaceSearchRouter } from \"./namespaces/search.js\";\n\ntype ConvergenceStorage = NonNullable<RebuildMemoryProjectionOptions[\"storage\"]>;\n\nexport async function refreshConvergedNamespaces(\n namespaces: readonly string[],\n namespaceSearchRouter: Pick<NamespaceSearchRouter, \"updateNamespacesDetailed\">,\n getStorage: (namespace: string) => Promise<ConvergenceStorage>,\n searchEnabled: boolean,\n): Promise<void> {\n const targetNamespaces = Array.from(new Set(namespaces.map((namespace) => namespace.trim()).filter(Boolean)));\n if (targetNamespaces.length === 0) return;\n\n const searchResult = await namespaceSearchRouter.updateNamespacesDetailed(\n targetNamespaces,\n undefined,\n { strict: true },\n );\n if (searchEnabled) {\n const eligible = new Set(searchResult.eligibleNamespaces);\n const skipped = targetNamespaces.filter((namespace) => !eligible.has(namespace));\n if (skipped.length > 0) {\n throw new Error(`search refresh skipped namespaces: ${skipped.join(\", \")}`);\n }\n }\n\n for (const namespace of targetNamespaces) {\n const storage = await getStorage(namespace);\n await rebuildMemoryProjection({\n memoryDir: storage.dir,\n storage,\n defaultNamespace: namespace,\n dryRun: false,\n });\n }\n}\n"],"mappings":";;;;;AAQA,eAAsB,2BACpB,YACA,uBACA,YACA,eACe;AACf,QAAM,mBAAmB,MAAM,KAAK,IAAI,IAAI,WAAW,IAAI,CAAC,cAAc,UAAU,KAAK,CAAC,EAAE,OAAO,OAAO,CAAC,CAAC;AAC5G,MAAI,iBAAiB,WAAW,EAAG;AAEnC,QAAM,eAAe,MAAM,sBAAsB;AAAA,IAC/C;AAAA,IACA;AAAA,IACA,EAAE,QAAQ,KAAK;AAAA,EACjB;AACA,MAAI,eAAe;AACjB,UAAM,WAAW,IAAI,IAAI,aAAa,kBAAkB;AACxD,UAAM,UAAU,iBAAiB,OAAO,CAAC,cAAc,CAAC,SAAS,IAAI,SAAS,CAAC;AAC/E,QAAI,QAAQ,SAAS,GAAG;AACtB,YAAM,IAAI,MAAM,sCAAsC,QAAQ,KAAK,IAAI,CAAC,EAAE;AAAA,IAC5E;AAAA,EACF;AAEA,aAAW,aAAa,kBAAkB;AACxC,UAAM,UAAU,MAAM,WAAW,SAAS;AAC1C,UAAM,wBAAwB;AAAA,MAC5B,WAAW,QAAQ;AAAA,MACnB;AAAA,MACA,kBAAkB;AAAA,MAClB,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AACF;","names":[]}
|
|
@@ -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
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
readNamespaceMaintenanceLastRanStatuses,
|
|
4
4
|
readNamespaceMaintenanceStatuses,
|
|
5
5
|
runNamespaceMaintenancePlan
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-2FSTB6BJ.js";
|
|
7
7
|
import {
|
|
8
8
|
analyzeSessionIntegrity,
|
|
9
9
|
applySessionRepair,
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
} from "./chunk-CMTINOFS.js";
|
|
15
15
|
import {
|
|
16
16
|
summarizeCorpusAndReplica
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-GUAL4PQH.js";
|
|
18
18
|
import {
|
|
19
19
|
readJudgeVerdictStats
|
|
20
20
|
} from "./chunk-OZKOPQCM.js";
|
|
@@ -25,49 +25,45 @@ import {
|
|
|
25
25
|
runEvalBenchmarkCiGate,
|
|
26
26
|
validateEvalBenchmarkPack
|
|
27
27
|
} from "./chunk-3PY7VHV7.js";
|
|
28
|
+
import {
|
|
29
|
+
runConsolidationProvenanceCheck
|
|
30
|
+
} from "./chunk-HAYSYUAB.js";
|
|
28
31
|
import {
|
|
29
32
|
resolveCuratedIncludeFilesStatePath,
|
|
30
33
|
resolveNativeKnowledgeStatePath,
|
|
31
34
|
resolveOpenClawWorkspaceStatePath
|
|
32
35
|
} from "./chunk-2DQ2XREU.js";
|
|
33
|
-
import {
|
|
34
|
-
runConsolidationProvenanceCheck
|
|
35
|
-
} from "./chunk-TSH56VPU.js";
|
|
36
36
|
import {
|
|
37
37
|
reportBufferSurpriseDistribution
|
|
38
38
|
} from "./chunk-YBPYIAA5.js";
|
|
39
39
|
import {
|
|
40
40
|
parseConfig
|
|
41
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-AUMWZSE7.js";
|
|
42
42
|
import {
|
|
43
43
|
readAggregateExtractionWatermark
|
|
44
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-FR27HBBA.js";
|
|
45
45
|
import {
|
|
46
46
|
listMemoryGovernanceRuns,
|
|
47
47
|
readMemoryGovernanceRunArtifact
|
|
48
|
-
} from "./chunk-
|
|
48
|
+
} from "./chunk-HC3PBX23.js";
|
|
49
49
|
import {
|
|
50
50
|
listNamespaces
|
|
51
|
-
} from "./chunk-
|
|
51
|
+
} from "./chunk-QR6G5KF4.js";
|
|
52
52
|
import {
|
|
53
53
|
analyzeGraphHealth
|
|
54
54
|
} from "./chunk-L2DPF4DF.js";
|
|
55
55
|
import {
|
|
56
56
|
StorageManager
|
|
57
|
-
} from "./chunk-
|
|
57
|
+
} from "./chunk-FUCYDRE5.js";
|
|
58
58
|
import {
|
|
59
59
|
lintWorkspaceFiles
|
|
60
60
|
} from "./chunk-DM2T26WE.js";
|
|
61
|
-
import {
|
|
62
|
-
probeProjectionHealth
|
|
63
|
-
} from "./chunk-3CSX3ETE.js";
|
|
64
61
|
import {
|
|
65
62
|
summarizeExtractionLiveness
|
|
66
63
|
} from "./chunk-3SG4FGDV.js";
|
|
67
64
|
import {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
} from "./chunk-JUC24CTX.js";
|
|
65
|
+
probeProjectionHealth
|
|
66
|
+
} from "./chunk-3CSX3ETE.js";
|
|
71
67
|
import {
|
|
72
68
|
resolveAccessSetupCapabilities,
|
|
73
69
|
resolveCapabilities,
|
|
@@ -79,6 +75,10 @@ import {
|
|
|
79
75
|
resolvePresentationCapabilities,
|
|
80
76
|
resolveQmdCapabilities
|
|
81
77
|
} from "./chunk-2XRE6FLM.js";
|
|
78
|
+
import {
|
|
79
|
+
readEnvVar,
|
|
80
|
+
resolveHomeDir
|
|
81
|
+
} from "./chunk-JUC24CTX.js";
|
|
82
82
|
|
|
83
83
|
// src/operator-toolkit.ts
|
|
84
84
|
import path from "path";
|
|
@@ -1683,4 +1683,4 @@ export {
|
|
|
1683
1683
|
runBenchmarkRecall,
|
|
1684
1684
|
runOperatorRepair
|
|
1685
1685
|
};
|
|
1686
|
-
//# sourceMappingURL=chunk-
|
|
1686
|
+
//# sourceMappingURL=chunk-XAGYS7X6.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":"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","names":["position","buffer","unlink"]}
|
|
@@ -2,14 +2,14 @@ import {
|
|
|
2
2
|
getHostEmbeddingProvider,
|
|
3
3
|
normalizeHostEmbeddingVector
|
|
4
4
|
} from "./chunk-3ONXXHQO.js";
|
|
5
|
-
import {
|
|
6
|
-
readEnvVar
|
|
7
|
-
} from "./chunk-JUC24CTX.js";
|
|
8
5
|
import {
|
|
9
6
|
resolveLocalLlmCapabilities,
|
|
10
7
|
resolveMemoryLifecycleCapabilities,
|
|
11
8
|
resolvePipelineProcessingCapabilities
|
|
12
9
|
} from "./chunk-2XRE6FLM.js";
|
|
10
|
+
import {
|
|
11
|
+
readEnvVar
|
|
12
|
+
} from "./chunk-JUC24CTX.js";
|
|
13
13
|
import {
|
|
14
14
|
log
|
|
15
15
|
} from "./chunk-3WCASNQZ.js";
|
|
@@ -515,4 +515,4 @@ export {
|
|
|
515
515
|
EmbeddingProviderUnavailableError,
|
|
516
516
|
EmbeddingFallback
|
|
517
517
|
};
|
|
518
|
-
//# sourceMappingURL=chunk-
|
|
518
|
+
//# sourceMappingURL=chunk-YK6BDDHP.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";
|
|
@@ -613,4 +613,4 @@ export {
|
|
|
613
613
|
resolveOramaCollectionDbFilePath,
|
|
614
614
|
OramaBackend
|
|
615
615
|
};
|
|
616
|
-
//# sourceMappingURL=chunk-
|
|
616
|
+
//# sourceMappingURL=chunk-YLHM5BQQ.js.map
|
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
combineNamespaces,
|
|
3
|
-
expandScopeProfileReadNamespaces,
|
|
4
|
-
lcmReadSessionIdsForNamespaces,
|
|
5
|
-
resolveCodingNamespaceOverlay,
|
|
6
|
-
resolveScopeProfilePlan
|
|
7
|
-
} from "./chunk-BUE5E2HL.js";
|
|
8
1
|
import {
|
|
9
2
|
namespaceIdentityFromToken,
|
|
10
3
|
namespaceIdentityToken
|
|
11
4
|
} from "./chunk-EGGE52UU.js";
|
|
5
|
+
import {
|
|
6
|
+
expandScopeProfileReadNamespaces,
|
|
7
|
+
resolveScopeProfilePlan
|
|
8
|
+
} from "./chunk-BGLY7EEM.js";
|
|
12
9
|
import {
|
|
13
10
|
canReadNamespace,
|
|
14
11
|
canWriteNamespace,
|
|
@@ -19,6 +16,11 @@ import {
|
|
|
19
16
|
import {
|
|
20
17
|
resolveNamespaceCapabilities
|
|
21
18
|
} from "./chunk-2XRE6FLM.js";
|
|
19
|
+
import {
|
|
20
|
+
combineNamespaces,
|
|
21
|
+
lcmReadSessionIdsForNamespaces,
|
|
22
|
+
resolveCodingNamespaceOverlay
|
|
23
|
+
} from "./chunk-J2WC5LF4.js";
|
|
22
24
|
|
|
23
25
|
// src/scopes/scope-plan.ts
|
|
24
26
|
import path from "path";
|
|
@@ -200,4 +202,4 @@ export {
|
|
|
200
202
|
resolveWritableNamespaceValue,
|
|
201
203
|
resolveScopedWritableNamespaceValue
|
|
202
204
|
};
|
|
203
|
-
//# sourceMappingURL=chunk-
|
|
205
|
+
//# sourceMappingURL=chunk-YN6ASZUG.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/scopes/scope-plan.ts"],"sourcesContent":["/**\n * ScopePlan resolver (issue #1521).\n *\n * A single pure function that resolves every namespace-bearing read/write path\n * to one {@link ScopePlan} value object. Consumers (recall tiers, QMD router,\n * LCM reads, maintenance) never call the ad-hoc resolution helpers directly —\n * they receive a resolved plan and read its fields.\n *\n * The resolver DELEGATES to the existing helpers (`resolvePrincipal`,\n * `recallNamespacesForPrincipal`, `resolveCodingNamespaceOverlay`,\n * `resolveScopeProfilePlan`, `expandScopeProfileReadNamespaces`,\n * `combineNamespaces`, `lcmReadSessionIdsForNamespaces`) — no logic rewrite.\n * The ad-hoc inline resolution that previously lived in the orchestrator's\n * `recallInternal` and `enqueueDirectAnswerObservation` paths is replaced by a\n * single call to {@link resolveScopePlan}, eliminating the duplicated\n * namespace-set construction that produced the largest share of #1519's review\n * threads (scope-profile recall paths missing `readFallbacks` appends).\n *\n * Migration tranches (issue #1521 step 4):\n * - recall tiers (this PR): the two orchestrator recall entry points consume\n * the plan instead of building `recallNamespaces`/`observationNamespaces`\n * inline;\n * - QMD router calls, LCM reads, maintenance: follow-up PRs.\n *\n * CLAUDE.md rules honoured (pitfalls from the issue):\n * - rule 42: read/write resolve through the same layer; the coding overlay is\n * COMBINED with the principal base via `combineNamespaces`;\n * - rule 39: feature gates identical across every path the plan feeds;\n * - rule 22/48: LCM keys derived through `lcmSessionKeyForNamespace` (via\n * `lcmReadSessionIdsForNamespaces`), never hardcoded `:`-joins; unscoped LCM\n * search stays suppressed when `namespacesEnabled`.\n */\n\nimport { resolveNamespaceCapabilities } from \"../capabilities.js\";\nimport {\n canReadNamespace,\n canWriteNamespace,\n defaultNamespaceForPrincipal,\n recallNamespacesForPrincipal,\n resolvePrincipal,\n} from \"../namespaces/principal.js\";\nimport {\n namespaceIdentityFromToken,\n namespaceIdentityToken,\n} from \"../namespaces/identity.js\";\nimport path from \"node:path\";\nimport {\n capabilityAllowsOp,\n isNamespaceAllowed,\n resolveEffectiveNamespace,\n type TokenCapabilities,\n} from \"../access-token-capabilities.js\";\nimport type { ResolvedScopeProfilePlan } from \"../namespaces/scope-profiles.js\";\nimport {\n expandScopeProfileReadNamespaces,\n resolveScopeProfilePlan,\n} from \"../namespaces/scope-profiles.js\";\nimport {\n combineNamespaces,\n lcmReadSessionIdsForNamespaces,\n resolveCodingNamespaceOverlay,\n type CodingNamespaceOverlay,\n} from \"../coding/coding-namespace.js\";\nimport type { CodingContext, PluginConfig } from \"../types.js\";\n\n/**\n * A resolved scope plan: every namespace-bearing field a read or write path\n * needs, produced by ONE call to {@link resolveScopePlan}.\n *\n * Consumers read these fields directly — they never re-resolve namespaces.\n */\nexport interface ScopePlan {\n /**\n * Resolved principal under which the operation runs. `undefined` only when\n * `namespacesEnabled` is false (collapses to `\"default\"`) or no session key\n * was supplied in single-user mode.\n */\n readonly principal: string | undefined;\n\n /**\n * Explicit namespace override, trimmed, when the caller supplied one AND it\n * is readable by the principal. `undefined` when no override was given or the\n * override is not readable (the plan falls through to the coding/scope-profile\n * resolution in that case, mirroring the pre-existing observe-path behavior).\n */\n readonly namespaceOverride: string | undefined;\n\n /**\n * Resolved base (self) namespace — the effective namespace absent an explicit\n * override. This is the principal-self namespace, optionally substituted by a\n * scope-profile write layer or a coding overlay.\n *\n * Callers that persisted this as the `selfNamespace` / response namespace\n * read it here.\n */\n readonly baseNamespace: string;\n\n /**\n * Ordered, deduped read-namespace set. Includes the coding overlay fallbacks\n * (branch → project → root) combined with the principal base exactly once, so\n * the #1519 miss (scope-profile path omitted `readFallbacks` appends) cannot\n * recur — the fallback appends live in ONE place.\n */\n readonly readNamespaces: string[];\n\n /**\n * Coding overlay fallback namespaces combined with the principal base (rule\n * 42). Empty when no coding overlay applies. These are the SAME entries\n * appended into {@link readNamespaces} for the coding-overlay branch,\n * surfaced separately so consumers that need just the fallback set (e.g.\n * LCM read-key derivation) can read them without re-deriving.\n */\n readonly readFallbacks: string[];\n\n /**\n * LCM read namespace set. May differ from {@link readNamespaces} for\n * read-authorization reasons: when the principal self base is NOT in the\n * readable recall set, the overlay LCM keys collapse to the default store\n * (rule 42 read/write parity; rule 48 least-privilege) even though\n * {@link readNamespaces} still searches the overlay for QMD/file recall.\n */\n readonly lcmReadNamespaces: string[];\n\n /**\n * LCM read `session_id` set, encoded via\n * `lcmReadSessionIdsForNamespaces` (which delegates to\n * `lcmSessionKeyForNamespace`). Ordered and deduped; the primary overlay key\n * is first. Single-user / no-overlay recall collapses to `[sessionKey]` —\n * byte-for-byte the pre-#1495 behavior.\n *\n * Empty (`[]`) when a scope-profile plan is active and no `sessionKey` was\n * supplied (mirrors the pre-existing guard).\n */\n readonly lcmReadSessionIds: ReadonlyArray<string | undefined>;\n\n /**\n * Resolved coding overlay, or `null` when none applies (no coding context,\n * `codingMode.projectScope` false, `namespacesEnabled` false, or an explicit\n * readable namespace override is set).\n */\n readonly codingOverlay: { readonly namespace: string; readonly readFallbacks: readonly string[] } | null;\n\n /**\n * Resolved scope-profile plan, or `null` when no scope profile is active.\n * Consumers that branched on \"profile vs. non-profile\" read this directly.\n */\n readonly scopeProfilePlan: ResolvedScopeProfilePlan | null;\n}\n\n/**\n * Options for {@link resolveScopePlan}.\n */\nexport interface ResolveScopePlanOptions {\n /** Plugin config (namespace policies, coding mode, default namespace, …). */\n readonly config: PluginConfig;\n /** Session key (may derive the principal and/or coding context). */\n readonly sessionKey?: string;\n /**\n * Explicit namespace override (raw — the resolver trims it). When supplied\n * AND readable by the resolved principal, it wins over every other layer.\n */\n readonly namespace?: string;\n /**\n * Authenticated principal override. Access surfaces that already resolved\n * identity at the transport layer pass it here so namespace ACL decisions\n * use the same identity the surface authorized.\n */\n readonly principalOverride?: string;\n /**\n * Coding context for the session. Callers that track this on the orchestrator\n * pass `getCodingContextForSession(sessionKey)` here; the resolver never\n * reaches back into orchestrator state.\n */\n readonly codingContext?: CodingContext | null;\n /**\n * Whether namespace routing is enabled. Callers that have already read the\n * namespaces-enabled flag pass it here so the resolver does NOT re-read it\n * (keeps the scattered-read ratchet from growing, #1523).\n */\n readonly namespacesEnabled: boolean;\n}\n\n/**\n * Resolve a {@link ScopePlan} from the inputs by delegating to the existing\n * namespace-resolution helpers. Pure — no side effects, no orchestrator state.\n *\n * The caller is responsible for authorization checks that should THROW (e.g.\n * `namespacesEnabled && !principal`, or an unreadable explicit override in the\n * recall path). The resolver computes the plan; enforcement stays at the call\n * site so error semantics are unchanged.\n */\nexport function resolveScopePlan(options: ResolveScopePlanOptions): ScopePlan {\n const { config, sessionKey } = options;\n\n const namespaceOverride = options.namespace?.trim() || undefined;\n\n const principal =\n typeof options.principalOverride === \"string\" && options.principalOverride.length > 0\n ? options.principalOverride\n : resolvePrincipal(sessionKey, config);\n\n // A namespace override gates the overlay/scope-profile layers. When it is\n // readable it wins; when it is NOT readable the plan falls through to the\n // coding/scope-profile/legacy branches (mirrors the observe-path behavior\n // where an unreadable override does not throw but simply does not suppress\n // the overlay). The recall path validates readability and throws BEFORE\n // calling the resolver, so a reachable override is always readable there.\n const namespaceOverrideReadable =\n namespaceOverride !== undefined && canReadNamespace(principal, namespaceOverride, config);\n\n const readableRecallNamespaces = recallNamespacesForPrincipal(principal, config);\n\n // The orchestrator's `applyCodingRecallOverlay` gates on `namespacesEnabled`\n // (returning null when disabled), so the resolver must too — otherwise\n // single-store mode would produce apparent route separation with no actual\n // storage isolation (false-isolation trap, rule 39). The caller passes the\n // pre-read flag so the resolver does not add a scattered `config.*Enabled`\n // read (ratchet, #1523).\n const namespacesEnabled = options.namespacesEnabled;\n const codingOverlay: CodingNamespaceOverlay | null =\n namespaceOverrideReadable || !namespacesEnabled\n ? null\n : resolveCodingNamespaceOverlay(\n options.codingContext ?? null,\n config.codingMode,\n config.defaultNamespace,\n );\n\n const principalSelfNamespace = defaultNamespaceForPrincipal(principal, config);\n const codingSelfNamespace = codingOverlay\n ? combineNamespaces(principalSelfNamespace, codingOverlay.namespace)\n : null;\n\n const scopeProfilePlan = namespaceOverrideReadable\n ? null\n : resolveScopeProfilePlan({\n config,\n principal,\n codingContext: options.codingContext ?? null,\n codingOverlay,\n });\n\n const profileEffectiveNamespace =\n scopeProfilePlan?.writeNamespace || scopeProfilePlan?.readNamespaces[0];\n\n const baseNamespace = namespaceOverrideReadable\n ? namespaceOverride!\n : profileEffectiveNamespace ?? codingSelfNamespace ?? principalSelfNamespace;\n\n // ── Read namespace set ────────────────────────────────────────────────────\n let readNamespaces: string[];\n if (namespaceOverrideReadable) {\n readNamespaces = [namespaceOverride!];\n } else if (scopeProfilePlan) {\n readNamespaces = expandScopeProfileReadNamespaces({\n profilePlan: scopeProfilePlan,\n principalSelfNamespace: scopeProfilePlan.baseNamespace,\n config,\n principal,\n codingOverlay,\n legacyRecallNamespaces: readableRecallNamespaces,\n });\n } else if (codingOverlay && codingSelfNamespace) {\n // Substitute the principal's self namespace with the coding-scoped one, and\n // append any read fallbacks (branch → project, rule 42) combined with the\n // principal base so principal isolation is preserved on fallback entries.\n const mapped = readableRecallNamespaces.map((ns) =>\n ns === principalSelfNamespace ? codingSelfNamespace : ns,\n );\n const fallbackNs = codingOverlay.readFallbacks.map((fallback) =>\n combineNamespaces(principalSelfNamespace, fallback),\n );\n readNamespaces = Array.from(new Set<string>([...mapped, ...fallbackNs]));\n } else {\n readNamespaces = readableRecallNamespaces;\n }\n\n const readFallbacks = codingOverlay\n ? codingOverlay.readFallbacks.map((fb) => combineNamespaces(principalSelfNamespace, fb))\n : [];\n\n // ── LCM read namespace set ────────────────────────────────────────────────\n // The LCM overlay keys are `<principal>-project-*` sub-namespaces authorized\n // transitively by the principal SELF base. Include them ONLY when that base\n // is in the readable recall set (rule 42 / 48). When it is NOT readable, the\n // overlay rows are unauthorized for this reader, so the LCM read collapses to\n // the default store — exactly what QMD/file recall surfaces for such a\n // principal.\n const codingOverlaySelfReadable =\n codingOverlay !== null &&\n (scopeProfilePlan\n ? scopeProfilePlan.layers.some((layer) => layer.id === \"userProject\" && layer.readable)\n : readableRecallNamespaces.includes(principalSelfNamespace));\n\n let lcmReadNamespaces: string[];\n if (namespaceOverrideReadable) {\n lcmReadNamespaces = [namespaceOverride!];\n } else if (scopeProfilePlan) {\n // Scope profiles define a layered read stack; LCM-backed evidence uses the\n // same namespace set as QMD/file recall so team/global/shared observations\n // are not silently skipped.\n lcmReadNamespaces = readNamespaces;\n } else if (codingOverlay && codingSelfNamespace && codingOverlaySelfReadable) {\n const fallbackNs = codingOverlay.readFallbacks.map((fallback) =>\n combineNamespaces(principalSelfNamespace, fallback),\n );\n lcmReadNamespaces = [codingSelfNamespace, ...fallbackNs];\n } else {\n // No overlay, OR overlay present but self base unreadable → collapse to the\n // default store (raw sessionKey). No `<principal>-project-*` overlay key is\n // searched.\n lcmReadNamespaces = [config.defaultNamespace];\n }\n\n const lcmReadSessionIds =\n scopeProfilePlan && !sessionKey\n ? []\n : lcmReadSessionIdsForNamespaces(lcmReadNamespaces, sessionKey, config.defaultNamespace);\n\n return {\n principal,\n namespaceOverride: namespaceOverrideReadable ? namespaceOverride : undefined,\n baseNamespace,\n readNamespaces,\n readFallbacks,\n lcmReadNamespaces,\n lcmReadSessionIds,\n codingOverlay: codingOverlay\n ? { namespace: codingOverlay.namespace, readFallbacks: codingOverlay.readFallbacks }\n : null,\n scopeProfilePlan,\n };\n}\n\n// ────────────────────────────────────────────────────────────────────────────\n// Centralized namespace-resolution helpers (issue #1521 step 3–4)\n//\n// The three functions below consolidate the ad-hoc namespace-resolution logic\n// that was previously scattered across orchestrator.ts (namespaceFromStorageDir,\n// configuredNamespaces) and access-service.ts (resolveWritableNamespace). By\n// living in THIS module they are excluded from the adHocNamespaceResolutions\n// ratchet, and every consumer reaches them through a single well-known import\n// instead of reimplementing the derivation inline (#1519's failure mode).\n// ────────────────────────────────────────────────────────────────────────────\n\n/**\n * The configured namespace set: default + shared + every namespace-policy\n * name, trimmed and de-duplicated. Pure — reads only from `config`.\n *\n * Replaces the `configuredNamespaces()` private method that lived on both\n * `Orchestrator` and the maintenance namespace-planner (two copies of the\n * same logic).\n */\nexport function getConfiguredNamespaces(config: PluginConfig): string[] {\n return Array.from(\n new Set(\n [\n config.defaultNamespace,\n config.sharedNamespace,\n ...config.namespacePolicies.map((policy) => policy.name),\n ]\n .map((value) => value.trim())\n .filter(Boolean),\n ),\n );\n}\n\n/**\n * Options for {@link resolveNamespaceFromStorageDir}.\n */\nexport interface ResolveNamespaceFromStorageDirOptions {\n /** Plugin config (memoryDir, defaultNamespace, namespacesEnabled, …). */\n readonly config: PluginConfig;\n /**\n * Pre-computed configured-namespace set (from {@link getConfiguredNamespaces}).\n * Passed by the caller so this function does not re-derive it on every call.\n */\n readonly configuredNamespaces: readonly string[];\n /**\n * Catalog-owned dir→namespace hints (best-effort union of configured +\n * catalog-discovered). May be `undefined` when no catalog hints are loaded.\n */\n readonly hints?: ReadonlyMap<string, ReadonlySet<string>> | undefined;\n /**\n * Lazy catalog-hint loader. Called ONLY after the early returns (disabled,\n * memory root, no namespace segment, configured namespace) — matching the\n * original lazy behavior so an eager load does not mark hints as loaded\n * before the catalog file exists (codex P2).\n */\n readonly loadHints?: () => void;\n}\n\n/**\n * Derive the namespace a storage directory belongs to.\n *\n * Pure (no orchestrator state): the caller passes `config`, the configured set,\n * and any catalog hints. The logic is byte-identical to the private\n * `namespaceFromStorageDir` method that previously lived on `Orchestrator`\n * (including the token round-trip guard from codex round 6).\n */\nexport function resolveNamespaceFromStorageDir(\n storageDir: string,\n options: ResolveNamespaceFromStorageDirOptions,\n): string {\n const { config } = options;\n if (!resolveNamespaceCapabilities(config).namespaces) return config.defaultNamespace;\n const resolvedStorageDir = path.resolve(storageDir);\n const resolvedMemoryDir = path.resolve(config.memoryDir);\n if (resolvedStorageDir === resolvedMemoryDir) return config.defaultNamespace;\n const m = resolvedStorageDir.match(/[\\\\/]namespaces[\\\\/]([^\\\\/]+)$/);\n if (!m?.[1]) return config.defaultNamespace;\n const dirName = m[1];\n // Token-shaped raw names (codex P2 — NBsFz): a dir name might be a tokenized\n // identity OR a literal raw namespace name that merely LOOKS like a token.\n // A dir name that is itself a KNOWN namespace is preserved BEFORE decoding.\n if (options.configuredNamespaces.includes(dirName)) {\n return dirName;\n }\n // Load catalog hints ONLY after the early returns (codex P2: an eager load\n // before the catalog file exists would mark hints as loaded and skip later\n // catalog-derived rows).\n options.loadHints?.();\n const hints = options.hints;\n const hintedNamespaces = hints?.get(resolvedStorageDir);\n if (hintedNamespaces?.has(dirName)) {\n return dirName;\n }\n if (hintedNamespaces?.size === 1) {\n const [hintedNamespace] = hintedNamespaces;\n if (hintedNamespace) return hintedNamespace;\n }\n const decoded = namespaceIdentityFromToken(dirName);\n if (decoded && namespaceIdentityToken(decoded) === dirName) {\n return decoded;\n }\n return dirName;\n}\n\n/**\n * Result of resolving a writable namespace: either the authorized namespace\n * or a structured rejection. The caller decides how to surface the rejection\n * (e.g. as an `EngramAccessInputError` in the access-service layer), keeping\n * this module free of transport-specific error types.\n */\nexport type WritableNamespaceResult =\n | { readonly ok: true; readonly namespace: string }\n | { readonly ok: false; readonly reason: \"unsupported\" | \"not_writable\"; readonly namespace: string };\n\n/**\n * Resolve and authorize a writable namespace.\n *\n * Combines the three steps that `AccessService.resolveWritableNamespace`\n * performed inline: (1) resolve the namespace value (trim → default fallback →\n * validate against `namespacesEnabled`), (2) resolve the principal, (3) check\n * `canWriteNamespace`. Returns a structured result so this module stays free of\n * `EngramAccessInputError` (avoiding a circular dependency on access-service.ts).\n *\n * The caller throws `EngramAccessInputError` when `ok === false` — the access-\n * service wrapper does this in one place.\n */\nexport function resolveWritableNamespaceValue(\n namespace: string | undefined,\n sessionKey: string | undefined,\n authenticatedPrincipal: string | undefined,\n config: PluginConfig,\n): WritableNamespaceResult {\n const requested = namespace?.trim();\n let resolved: string;\n if (!requested) {\n resolved = config.defaultNamespace;\n } else if (\n !resolveNamespaceCapabilities(config).namespaces &&\n requested !== config.defaultNamespace\n ) {\n return { ok: false, reason: \"unsupported\", namespace: requested };\n } else {\n resolved = requested;\n }\n\n const trusted = authenticatedPrincipal?.trim();\n const principal =\n typeof trusted === \"string\" && trusted.length > 0\n ? trusted\n : resolvePrincipal(sessionKey, config);\n\n if (!canWriteNamespace(principal, resolved, config)) {\n return { ok: false, reason: \"not_writable\", namespace: resolved };\n }\n return { ok: true, namespace: resolved };\n}\n\n/**\n * Inputs already derived by the access-service's read-only coding-context\n * resolver. Keeping context discovery outside this pure function lets writes\n * and preflight checks apply identical namespace and ACL rules.\n */\nexport interface ScopedWritableNamespaceInput {\n readonly namespace?: string;\n readonly sessionKey?: string;\n readonly authenticatedPrincipal?: string;\n readonly principal: string | undefined;\n readonly codingOverlay: CodingNamespaceOverlay | null;\n readonly scopeProfile: ResolvedScopeProfilePlan | null;\n readonly config: PluginConfig;\n}\n\n/**\n * Resolve the namespace an explicit write or implicit coding-scoped write\n * would use. The caller supplies the same derived coding inputs for the real\n * write and the read-only preflight.\n */\nexport function resolveScopedWritableNamespaceValue(\n input: ScopedWritableNamespaceInput,\n): WritableNamespaceResult {\n const requested = input.namespace?.trim();\n if (requested) {\n return resolveWritableNamespaceValue(\n requested,\n input.sessionKey,\n input.authenticatedPrincipal,\n input.config,\n );\n }\n if (input.scopeProfile) {\n const selectedLayer = input.scopeProfile.layers.find(\n (layer) => layer.id === input.scopeProfile?.writeLayer,\n );\n const writeNamespaceReadable =\n input.scopeProfile.writeNamespace.length > 0 &&\n input.scopeProfile.readNamespaces.includes(input.scopeProfile.writeNamespace);\n if (!selectedLayer?.writable || !writeNamespaceReadable) {\n return {\n ok: false,\n reason: \"not_writable\",\n namespace: input.scopeProfile.writeNamespace,\n };\n }\n return { ok: true, namespace: input.scopeProfile.writeNamespace };\n }\n if (!input.codingOverlay) {\n return resolveWritableNamespaceValue(\n undefined,\n input.sessionKey,\n input.authenticatedPrincipal,\n input.config,\n );\n }\n const baseNamespace = defaultNamespaceForPrincipal(input.principal, input.config);\n if (!canWriteNamespace(input.principal, baseNamespace, input.config)) {\n return { ok: false, reason: \"not_writable\", namespace: baseNamespace };\n }\n return {\n ok: true,\n namespace: combineNamespaces(baseNamespace, input.codingOverlay.namespace),\n };\n}\n\n/**\n * Namespace preflight (issue #1888 part 3): would a write to `namespace` by a\n * caller carrying `caps` succeed? Combines the token's write-op scope, its\n * namespace allow-list, and policy writability so one call answers the real\n * question. A token that cannot actually write (no `observe`/`memory_store` in\n * its ops allow-list) or is asking about a namespace outside its allow-list\n * gets a definitive `not_writable` — revealing nothing about the namespace's\n * policy beyond what the token's own scope already implies, and never throwing\n * a hard authorization error the caller cannot distinguish from a transport\n * fault. (Unrestricted tokens pass both scope checks unchanged.)\n */\nexport function resolveNamespacePreflight(\n caps: TokenCapabilities | undefined | null,\n namespace: string | undefined,\n sessionKey: string | undefined,\n authenticatedPrincipal: string | undefined,\n config: PluginConfig,\n writeOp: string,\n): WritableNamespaceResult {\n const notWritable = (): WritableNamespaceResult => ({\n ok: false,\n reason: \"not_writable\",\n namespace: resolveEffectiveNamespace(namespace, config.defaultNamespace) ?? namespace ?? \"\",\n });\n // The token must be able to perform the write op the caller's ENABLED write\n // path actually uses (`observe` for automatic turn capture — the silent\n // #1888 data-loss path — or `memory_store` for an explicit-only install).\n // A token that cannot perform that op would drop the write, so an otherwise\n // policy-writable namespace is still reported not_writable rather than a\n // false ok:true that promises a write the token cannot make.\n if (!capabilityAllowsOp(caps, writeOp)) {\n return notWritable();\n }\n if (!isNamespaceAllowed(caps, namespace, config.defaultNamespace)) {\n return notWritable();\n }\n return resolveWritableNamespaceValue(namespace, sessionKey, authenticatedPrincipal, config);\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/scopes/scope-plan.ts"],"sourcesContent":["/**\n * ScopePlan resolver (issue #1521).\n *\n * A single pure function that resolves every namespace-bearing read/write path\n * to one {@link ScopePlan} value object. Consumers (recall tiers, QMD router,\n * LCM reads, maintenance) never call the ad-hoc resolution helpers directly —\n * they receive a resolved plan and read its fields.\n *\n * The resolver DELEGATES to the existing helpers (`resolvePrincipal`,\n * `recallNamespacesForPrincipal`, `resolveCodingNamespaceOverlay`,\n * `resolveScopeProfilePlan`, `expandScopeProfileReadNamespaces`,\n * `combineNamespaces`, `lcmReadSessionIdsForNamespaces`) — no logic rewrite.\n * The ad-hoc inline resolution that previously lived in the orchestrator's\n * `recallInternal` and `enqueueDirectAnswerObservation` paths is replaced by a\n * single call to {@link resolveScopePlan}, eliminating the duplicated\n * namespace-set construction that produced the largest share of #1519's review\n * threads (scope-profile recall paths missing `readFallbacks` appends).\n *\n * Migration tranches (issue #1521 step 4):\n * - recall tiers (this PR): the two orchestrator recall entry points consume\n * the plan instead of building `recallNamespaces`/`observationNamespaces`\n * inline;\n * - QMD router calls, LCM reads, maintenance: follow-up PRs.\n *\n * CLAUDE.md rules honoured (pitfalls from the issue):\n * - rule 42: read/write resolve through the same layer; the coding overlay is\n * COMBINED with the principal base via `combineNamespaces`;\n * - rule 39: feature gates identical across every path the plan feeds;\n * - rule 22/48: LCM keys derived through `lcmSessionKeyForNamespace` (via\n * `lcmReadSessionIdsForNamespaces`), never hardcoded `:`-joins; unscoped LCM\n * search stays suppressed when `namespacesEnabled`.\n */\n\nimport { resolveNamespaceCapabilities } from \"../capabilities.js\";\nimport {\n canReadNamespace,\n canWriteNamespace,\n defaultNamespaceForPrincipal,\n recallNamespacesForPrincipal,\n resolvePrincipal,\n} from \"../namespaces/principal.js\";\nimport {\n namespaceIdentityFromToken,\n namespaceIdentityToken,\n} from \"../namespaces/identity.js\";\nimport path from \"node:path\";\nimport {\n capabilityAllowsOp,\n isNamespaceAllowed,\n resolveEffectiveNamespace,\n type TokenCapabilities,\n} from \"../access-token-capabilities.js\";\nimport type { ResolvedScopeProfilePlan } from \"../namespaces/scope-profiles.js\";\nimport {\n expandScopeProfileReadNamespaces,\n resolveScopeProfilePlan,\n} from \"../namespaces/scope-profiles.js\";\nimport {\n combineNamespaces,\n lcmReadSessionIdsForNamespaces,\n resolveCodingNamespaceOverlay,\n type CodingNamespaceOverlay,\n} from \"../coding/coding-namespace.js\";\nimport type { CodingContext, PluginConfig } from \"../types.js\";\n\n/**\n * A resolved scope plan: every namespace-bearing field a read or write path\n * needs, produced by ONE call to {@link resolveScopePlan}.\n *\n * Consumers read these fields directly — they never re-resolve namespaces.\n */\nexport interface ScopePlan {\n /**\n * Resolved principal under which the operation runs. `undefined` only when\n * `namespacesEnabled` is false (collapses to `\"default\"`) or no session key\n * was supplied in single-user mode.\n */\n readonly principal: string | undefined;\n\n /**\n * Explicit namespace override, trimmed, when the caller supplied one AND it\n * is readable by the principal. `undefined` when no override was given or the\n * override is not readable (the plan falls through to the coding/scope-profile\n * resolution in that case, mirroring the pre-existing observe-path behavior).\n */\n readonly namespaceOverride: string | undefined;\n\n /**\n * Resolved base (self) namespace — the effective namespace absent an explicit\n * override. This is the principal-self namespace, optionally substituted by a\n * scope-profile write layer or a coding overlay.\n *\n * Callers that persisted this as the `selfNamespace` / response namespace\n * read it here.\n */\n readonly baseNamespace: string;\n\n /**\n * Ordered, deduped read-namespace set. Includes the coding overlay fallbacks\n * (branch → project → root) combined with the principal base exactly once, so\n * the #1519 miss (scope-profile path omitted `readFallbacks` appends) cannot\n * recur — the fallback appends live in ONE place.\n */\n readonly readNamespaces: string[];\n\n /**\n * Coding overlay fallback namespaces combined with the principal base (rule\n * 42). Empty when no coding overlay applies. These are the SAME entries\n * appended into {@link readNamespaces} for the coding-overlay branch,\n * surfaced separately so consumers that need just the fallback set (e.g.\n * LCM read-key derivation) can read them without re-deriving.\n */\n readonly readFallbacks: string[];\n\n /**\n * LCM read namespace set. May differ from {@link readNamespaces} for\n * read-authorization reasons: when the principal self base is NOT in the\n * readable recall set, the overlay LCM keys collapse to the default store\n * (rule 42 read/write parity; rule 48 least-privilege) even though\n * {@link readNamespaces} still searches the overlay for QMD/file recall.\n */\n readonly lcmReadNamespaces: string[];\n\n /**\n * LCM read `session_id` set, encoded via\n * `lcmReadSessionIdsForNamespaces` (which delegates to\n * `lcmSessionKeyForNamespace`). Ordered and deduped; the primary overlay key\n * is first. Single-user / no-overlay recall collapses to `[sessionKey]` —\n * byte-for-byte the pre-#1495 behavior.\n *\n * Empty (`[]`) when a scope-profile plan is active and no `sessionKey` was\n * supplied (mirrors the pre-existing guard).\n */\n readonly lcmReadSessionIds: ReadonlyArray<string | undefined>;\n\n /**\n * Resolved coding overlay, or `null` when none applies (no coding context,\n * `codingMode.projectScope` false, `namespacesEnabled` false, or an explicit\n * readable namespace override is set).\n */\n readonly codingOverlay: { readonly namespace: string; readonly readFallbacks: readonly string[] } | null;\n\n /**\n * Resolved scope-profile plan, or `null` when no scope profile is active.\n * Consumers that branched on \"profile vs. non-profile\" read this directly.\n */\n readonly scopeProfilePlan: ResolvedScopeProfilePlan | null;\n}\n\n/**\n * Options for {@link resolveScopePlan}.\n */\nexport interface ResolveScopePlanOptions {\n /** Plugin config (namespace policies, coding mode, default namespace, …). */\n readonly config: PluginConfig;\n /** Session key (may derive the principal and/or coding context). */\n readonly sessionKey?: string;\n /**\n * Explicit namespace override (raw — the resolver trims it). When supplied\n * AND readable by the resolved principal, it wins over every other layer.\n */\n readonly namespace?: string;\n /**\n * Authenticated principal override. Access surfaces that already resolved\n * identity at the transport layer pass it here so namespace ACL decisions\n * use the same identity the surface authorized.\n */\n readonly principalOverride?: string;\n /**\n * Coding context for the session. Callers that track this on the orchestrator\n * pass `getCodingContextForSession(sessionKey)` here; the resolver never\n * reaches back into orchestrator state.\n */\n readonly codingContext?: CodingContext | null;\n /**\n * Whether namespace routing is enabled. Callers that have already read the\n * namespaces-enabled flag pass it here so the resolver does NOT re-read it\n * (keeps the scattered-read ratchet from growing, #1523).\n */\n readonly namespacesEnabled: boolean;\n}\n\n/**\n * Resolve a {@link ScopePlan} from the inputs by delegating to the existing\n * namespace-resolution helpers. Pure — no side effects, no orchestrator state.\n *\n * The caller is responsible for authorization checks that should THROW (e.g.\n * `namespacesEnabled && !principal`, or an unreadable explicit override in the\n * recall path). The resolver computes the plan; enforcement stays at the call\n * site so error semantics are unchanged.\n */\nexport function resolveScopePlan(options: ResolveScopePlanOptions): ScopePlan {\n const { config, sessionKey } = options;\n\n const namespaceOverride = options.namespace?.trim() || undefined;\n\n const principal =\n typeof options.principalOverride === \"string\" && options.principalOverride.length > 0\n ? options.principalOverride\n : resolvePrincipal(sessionKey, config);\n\n // A namespace override gates the overlay/scope-profile layers. When it is\n // readable it wins; when it is NOT readable the plan falls through to the\n // coding/scope-profile/legacy branches (mirrors the observe-path behavior\n // where an unreadable override does not throw but simply does not suppress\n // the overlay). The recall path validates readability and throws BEFORE\n // calling the resolver, so a reachable override is always readable there.\n const namespaceOverrideReadable =\n namespaceOverride !== undefined && canReadNamespace(principal, namespaceOverride, config);\n\n const readableRecallNamespaces = recallNamespacesForPrincipal(principal, config);\n\n // The orchestrator's `applyCodingRecallOverlay` gates on `namespacesEnabled`\n // (returning null when disabled), so the resolver must too — otherwise\n // single-store mode would produce apparent route separation with no actual\n // storage isolation (false-isolation trap, rule 39). The caller passes the\n // pre-read flag so the resolver does not add a scattered `config.*Enabled`\n // read (ratchet, #1523).\n const namespacesEnabled = options.namespacesEnabled;\n const codingOverlay: CodingNamespaceOverlay | null =\n namespaceOverrideReadable || !namespacesEnabled\n ? null\n : resolveCodingNamespaceOverlay(\n options.codingContext ?? null,\n config.codingMode,\n config.defaultNamespace,\n );\n\n const principalSelfNamespace = defaultNamespaceForPrincipal(principal, config);\n const codingSelfNamespace = codingOverlay\n ? combineNamespaces(principalSelfNamespace, codingOverlay.namespace)\n : null;\n\n const scopeProfilePlan = namespaceOverrideReadable\n ? null\n : resolveScopeProfilePlan({\n config,\n principal,\n codingContext: options.codingContext ?? null,\n codingOverlay,\n });\n\n const profileEffectiveNamespace =\n scopeProfilePlan?.writeNamespace || scopeProfilePlan?.readNamespaces[0];\n\n const baseNamespace = namespaceOverrideReadable\n ? namespaceOverride!\n : profileEffectiveNamespace ?? codingSelfNamespace ?? principalSelfNamespace;\n\n // ── Read namespace set ────────────────────────────────────────────────────\n let readNamespaces: string[];\n if (namespaceOverrideReadable) {\n readNamespaces = [namespaceOverride!];\n } else if (scopeProfilePlan) {\n readNamespaces = expandScopeProfileReadNamespaces({\n profilePlan: scopeProfilePlan,\n principalSelfNamespace: scopeProfilePlan.baseNamespace,\n config,\n principal,\n codingOverlay,\n legacyRecallNamespaces: readableRecallNamespaces,\n });\n } else if (codingOverlay && codingSelfNamespace) {\n // Substitute the principal's self namespace with the coding-scoped one, and\n // append any read fallbacks (branch → project, rule 42) combined with the\n // principal base so principal isolation is preserved on fallback entries.\n const mapped = readableRecallNamespaces.map((ns) =>\n ns === principalSelfNamespace ? codingSelfNamespace : ns,\n );\n const fallbackNs = codingOverlay.readFallbacks.map((fallback) =>\n combineNamespaces(principalSelfNamespace, fallback),\n );\n readNamespaces = Array.from(new Set<string>([...mapped, ...fallbackNs]));\n } else {\n readNamespaces = readableRecallNamespaces;\n }\n\n const readFallbacks = codingOverlay\n ? codingOverlay.readFallbacks.map((fb) => combineNamespaces(principalSelfNamespace, fb))\n : [];\n\n // ── LCM read namespace set ────────────────────────────────────────────────\n // The LCM overlay keys are `<principal>-project-*` sub-namespaces authorized\n // transitively by the principal SELF base. Include them ONLY when that base\n // is in the readable recall set (rule 42 / 48). When it is NOT readable, the\n // overlay rows are unauthorized for this reader, so the LCM read collapses to\n // the default store — exactly what QMD/file recall surfaces for such a\n // principal.\n const codingOverlaySelfReadable =\n codingOverlay !== null &&\n (scopeProfilePlan\n ? scopeProfilePlan.layers.some((layer) => layer.id === \"userProject\" && layer.readable)\n : readableRecallNamespaces.includes(principalSelfNamespace));\n\n let lcmReadNamespaces: string[];\n if (namespaceOverrideReadable) {\n lcmReadNamespaces = [namespaceOverride!];\n } else if (scopeProfilePlan) {\n // Scope profiles define a layered read stack; LCM-backed evidence uses the\n // same namespace set as QMD/file recall so team/global/shared observations\n // are not silently skipped.\n lcmReadNamespaces = readNamespaces;\n } else if (codingOverlay && codingSelfNamespace && codingOverlaySelfReadable) {\n const fallbackNs = codingOverlay.readFallbacks.map((fallback) =>\n combineNamespaces(principalSelfNamespace, fallback),\n );\n lcmReadNamespaces = [codingSelfNamespace, ...fallbackNs];\n } else {\n // No overlay, OR overlay present but self base unreadable → collapse to the\n // default store (raw sessionKey). No `<principal>-project-*` overlay key is\n // searched.\n lcmReadNamespaces = [config.defaultNamespace];\n }\n\n const lcmReadSessionIds =\n scopeProfilePlan && !sessionKey\n ? []\n : lcmReadSessionIdsForNamespaces(lcmReadNamespaces, sessionKey, config.defaultNamespace);\n\n return {\n principal,\n namespaceOverride: namespaceOverrideReadable ? namespaceOverride : undefined,\n baseNamespace,\n readNamespaces,\n readFallbacks,\n lcmReadNamespaces,\n lcmReadSessionIds,\n codingOverlay: codingOverlay\n ? { namespace: codingOverlay.namespace, readFallbacks: codingOverlay.readFallbacks }\n : null,\n scopeProfilePlan,\n };\n}\n\n// ────────────────────────────────────────────────────────────────────────────\n// Centralized namespace-resolution helpers (issue #1521 step 3–4)\n//\n// The three functions below consolidate the ad-hoc namespace-resolution logic\n// that was previously scattered across orchestrator.ts (namespaceFromStorageDir,\n// configuredNamespaces) and access-service.ts (resolveWritableNamespace). By\n// living in THIS module they are excluded from the adHocNamespaceResolutions\n// ratchet, and every consumer reaches them through a single well-known import\n// instead of reimplementing the derivation inline (#1519's failure mode).\n// ────────────────────────────────────────────────────────────────────────────\n\n/**\n * The configured namespace set: default + shared + every namespace-policy\n * name, trimmed and de-duplicated. Pure — reads only from `config`.\n *\n * Replaces the `configuredNamespaces()` private method that lived on both\n * `Orchestrator` and the maintenance namespace-planner (two copies of the\n * same logic).\n */\nexport function getConfiguredNamespaces(config: PluginConfig): string[] {\n return Array.from(\n new Set(\n [\n config.defaultNamespace,\n config.sharedNamespace,\n ...config.namespacePolicies.map((policy) => policy.name),\n ]\n .map((value) => value.trim())\n .filter(Boolean),\n ),\n );\n}\n\n/**\n * Options for {@link resolveNamespaceFromStorageDir}.\n */\nexport interface ResolveNamespaceFromStorageDirOptions {\n /** Plugin config (memoryDir, defaultNamespace, namespacesEnabled, …). */\n readonly config: PluginConfig;\n /**\n * Pre-computed configured-namespace set (from {@link getConfiguredNamespaces}).\n * Passed by the caller so this function does not re-derive it on every call.\n */\n readonly configuredNamespaces: readonly string[];\n /**\n * Catalog-owned dir→namespace hints (best-effort union of configured +\n * catalog-discovered). May be `undefined` when no catalog hints are loaded.\n */\n readonly hints?: ReadonlyMap<string, ReadonlySet<string>> | undefined;\n /**\n * Lazy catalog-hint loader. Called ONLY after the early returns (disabled,\n * memory root, no namespace segment, configured namespace) — matching the\n * original lazy behavior so an eager load does not mark hints as loaded\n * before the catalog file exists (codex P2).\n */\n readonly loadHints?: () => void;\n}\n\n/**\n * Derive the namespace a storage directory belongs to.\n *\n * Pure (no orchestrator state): the caller passes `config`, the configured set,\n * and any catalog hints. The logic is byte-identical to the private\n * `namespaceFromStorageDir` method that previously lived on `Orchestrator`\n * (including the token round-trip guard from codex round 6).\n */\nexport function resolveNamespaceFromStorageDir(\n storageDir: string,\n options: ResolveNamespaceFromStorageDirOptions,\n): string {\n const { config } = options;\n if (!resolveNamespaceCapabilities(config).namespaces) return config.defaultNamespace;\n const resolvedStorageDir = path.resolve(storageDir);\n const resolvedMemoryDir = path.resolve(config.memoryDir);\n if (resolvedStorageDir === resolvedMemoryDir) return config.defaultNamespace;\n const m = resolvedStorageDir.match(/[\\\\/]namespaces[\\\\/]([^\\\\/]+)$/);\n if (!m?.[1]) return config.defaultNamespace;\n const dirName = m[1];\n // Token-shaped raw names (codex P2 — NBsFz): a dir name might be a tokenized\n // identity OR a literal raw namespace name that merely LOOKS like a token.\n // A dir name that is itself a KNOWN namespace is preserved BEFORE decoding.\n if (options.configuredNamespaces.includes(dirName)) {\n return dirName;\n }\n // Load catalog hints ONLY after the early returns (codex P2: an eager load\n // before the catalog file exists would mark hints as loaded and skip later\n // catalog-derived rows).\n options.loadHints?.();\n const hints = options.hints;\n const hintedNamespaces = hints?.get(resolvedStorageDir);\n if (hintedNamespaces?.has(dirName)) {\n return dirName;\n }\n if (hintedNamespaces?.size === 1) {\n const [hintedNamespace] = hintedNamespaces;\n if (hintedNamespace) return hintedNamespace;\n }\n const decoded = namespaceIdentityFromToken(dirName);\n if (decoded && namespaceIdentityToken(decoded) === dirName) {\n return decoded;\n }\n return dirName;\n}\n\n/**\n * Result of resolving a writable namespace: either the authorized namespace\n * or a structured rejection. The caller decides how to surface the rejection\n * (e.g. as an `EngramAccessInputError` in the access-service layer), keeping\n * this module free of transport-specific error types.\n */\nexport type WritableNamespaceResult =\n | { readonly ok: true; readonly namespace: string }\n | { readonly ok: false; readonly reason: \"unsupported\" | \"not_writable\"; readonly namespace: string };\n\n/**\n * Resolve and authorize a writable namespace.\n *\n * Combines the three steps that `AccessService.resolveWritableNamespace`\n * performed inline: (1) resolve the namespace value (trim → default fallback →\n * validate against `namespacesEnabled`), (2) resolve the principal, (3) check\n * `canWriteNamespace`. Returns a structured result so this module stays free of\n * `EngramAccessInputError` (avoiding a circular dependency on access-service.ts).\n *\n * The caller throws `EngramAccessInputError` when `ok === false` — the access-\n * service wrapper does this in one place.\n */\nexport function resolveWritableNamespaceValue(\n namespace: string | undefined,\n sessionKey: string | undefined,\n authenticatedPrincipal: string | undefined,\n config: PluginConfig,\n): WritableNamespaceResult {\n const requested = namespace?.trim();\n let resolved: string;\n if (!requested) {\n resolved = config.defaultNamespace;\n } else if (\n !resolveNamespaceCapabilities(config).namespaces &&\n requested !== config.defaultNamespace\n ) {\n return { ok: false, reason: \"unsupported\", namespace: requested };\n } else {\n resolved = requested;\n }\n\n const trusted = authenticatedPrincipal?.trim();\n const principal =\n typeof trusted === \"string\" && trusted.length > 0\n ? trusted\n : resolvePrincipal(sessionKey, config);\n\n if (!canWriteNamespace(principal, resolved, config)) {\n return { ok: false, reason: \"not_writable\", namespace: resolved };\n }\n return { ok: true, namespace: resolved };\n}\n\n/**\n * Inputs already derived by the access-service's read-only coding-context\n * resolver. Keeping context discovery outside this pure function lets writes\n * and preflight checks apply identical namespace and ACL rules.\n */\nexport interface ScopedWritableNamespaceInput {\n readonly namespace?: string;\n readonly sessionKey?: string;\n readonly authenticatedPrincipal?: string;\n readonly principal: string | undefined;\n readonly codingOverlay: CodingNamespaceOverlay | null;\n readonly scopeProfile: ResolvedScopeProfilePlan | null;\n readonly config: PluginConfig;\n}\n\n/**\n * Resolve the namespace an explicit write or implicit coding-scoped write\n * would use. The caller supplies the same derived coding inputs for the real\n * write and the read-only preflight.\n */\nexport function resolveScopedWritableNamespaceValue(\n input: ScopedWritableNamespaceInput,\n): WritableNamespaceResult {\n const requested = input.namespace?.trim();\n if (requested) {\n return resolveWritableNamespaceValue(\n requested,\n input.sessionKey,\n input.authenticatedPrincipal,\n input.config,\n );\n }\n if (input.scopeProfile) {\n const selectedLayer = input.scopeProfile.layers.find(\n (layer) => layer.id === input.scopeProfile?.writeLayer,\n );\n const writeNamespaceReadable =\n input.scopeProfile.writeNamespace.length > 0 &&\n input.scopeProfile.readNamespaces.includes(input.scopeProfile.writeNamespace);\n if (!selectedLayer?.writable || !writeNamespaceReadable) {\n return {\n ok: false,\n reason: \"not_writable\",\n namespace: input.scopeProfile.writeNamespace,\n };\n }\n return { ok: true, namespace: input.scopeProfile.writeNamespace };\n }\n if (!input.codingOverlay) {\n return resolveWritableNamespaceValue(\n undefined,\n input.sessionKey,\n input.authenticatedPrincipal,\n input.config,\n );\n }\n const baseNamespace = defaultNamespaceForPrincipal(input.principal, input.config);\n if (!canWriteNamespace(input.principal, baseNamespace, input.config)) {\n return { ok: false, reason: \"not_writable\", namespace: baseNamespace };\n }\n return {\n ok: true,\n namespace: combineNamespaces(baseNamespace, input.codingOverlay.namespace),\n };\n}\n\n/**\n * Namespace preflight (issue #1888 part 3): would a write to `namespace` by a\n * caller carrying `caps` succeed? Combines the token's write-op scope, its\n * namespace allow-list, and policy writability so one call answers the real\n * question. A token that cannot actually write (no `observe`/`memory_store` in\n * its ops allow-list) or is asking about a namespace outside its allow-list\n * gets a definitive `not_writable` — revealing nothing about the namespace's\n * policy beyond what the token's own scope already implies, and never throwing\n * a hard authorization error the caller cannot distinguish from a transport\n * fault. (Unrestricted tokens pass both scope checks unchanged.)\n */\nexport function resolveNamespacePreflight(\n caps: TokenCapabilities | undefined | null,\n namespace: string | undefined,\n sessionKey: string | undefined,\n authenticatedPrincipal: string | undefined,\n config: PluginConfig,\n writeOp: string,\n): WritableNamespaceResult {\n const notWritable = (): WritableNamespaceResult => ({\n ok: false,\n reason: \"not_writable\",\n namespace: resolveEffectiveNamespace(namespace, config.defaultNamespace) ?? namespace ?? \"\",\n });\n // The token must be able to perform the write op the caller's ENABLED write\n // path actually uses (`observe` for automatic turn capture — the silent\n // #1888 data-loss path — or `memory_store` for an explicit-only install).\n // A token that cannot perform that op would drop the write, so an otherwise\n // policy-writable namespace is still reported not_writable rather than a\n // false ok:true that promises a write the token cannot make.\n if (!capabilityAllowsOp(caps, writeOp)) {\n return notWritable();\n }\n if (!isNamespaceAllowed(caps, namespace, config.defaultNamespace)) {\n return notWritable();\n }\n return resolveWritableNamespaceValue(namespace, sessionKey, authenticatedPrincipal, config);\n}\n"],"mappings":"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","names":[]}
|