@remnic/core 9.3.751 → 9.3.752
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/access-boundary.d.ts +5 -5
- package/dist/access-boundary.js +29 -29
- package/dist/access-cli.js +88 -88
- package/dist/access-http.d.ts +5 -5
- package/dist/access-http.js +35 -35
- package/dist/access-mcp.d.ts +5 -5
- package/dist/access-mcp.js +34 -34
- package/dist/access-operations-batch.js +31 -31
- package/dist/access-operations.d.ts +5 -5
- package/dist/access-operations.js +33 -33
- package/dist/access-recall-surface.d.ts +363 -0
- package/dist/access-recall-surface.js +128 -0
- package/dist/access-schema.js +7 -7
- package/dist/{access-service-DmAEOJdJ.d.ts → access-service-C2cOHQvg.d.ts} +7 -26
- package/dist/access-service.d.ts +5 -5
- package/dist/access-service.js +28 -28
- package/dist/access-surface-catalog.d.ts +5 -5
- package/dist/action-confidence.d.ts +1 -1
- package/dist/active-memory-bridge.d.ts +1 -1
- package/dist/active-recall.d.ts +1 -1
- package/dist/active-recall.js +1 -1
- package/dist/behavior-learner.d.ts +1 -1
- package/dist/behavior-signals.d.ts +1 -1
- package/dist/bootstrap.d.ts +4 -4
- package/dist/briefing.d.ts +1 -1
- package/dist/briefing.js +4 -4
- package/dist/buffer-surprise-report.d.ts +1 -1
- package/dist/buffer.d.ts +1 -1
- package/dist/buffer.js +2 -2
- package/dist/calibration.d.ts +1 -1
- package/dist/capabilities.d.ts +1 -1
- package/dist/{capsule-crypto-7FJQINUR.js → capsule-crypto-CZJSLEFG.js} +3 -3
- package/dist/{catalog-BpOcwHdE.d.ts → catalog-D_FvzTM0.d.ts} +1 -1
- package/dist/causal-behavior.d.ts +1 -1
- package/dist/causal-behavior.js +2 -2
- package/dist/causal-chain.js +2 -2
- package/dist/causal-consolidation.d.ts +1 -1
- package/dist/causal-consolidation.js +9 -9
- package/dist/causal-retrieval.js +2 -2
- package/dist/causal-trajectory-graph.d.ts +1 -1
- package/dist/causal-trajectory.js +1 -1
- package/dist/{chunk-2NLLXCJG.js → chunk-2BFLDH5F.js} +2 -2
- package/dist/{chunk-UU32EAIY.js → chunk-2DPCAW2T.js} +5 -5
- package/dist/{chunk-5PZCDUJ6.js → chunk-2U4E34Y3.js} +4 -4
- package/dist/{chunk-JRZV3767.js → chunk-33NX5BLR.js} +4 -4
- package/dist/{chunk-X7Y7WX73.js → chunk-437S3G37.js} +2 -2
- package/dist/{chunk-HAZVVOYT.js → chunk-5DXUE7GB.js} +2 -2
- package/dist/{chunk-4DLFJJOQ.js → chunk-5JAT4ZJD.js} +4 -4
- package/dist/{chunk-RS25QOKZ.js → chunk-64SE4X5G.js} +2 -2
- package/dist/{chunk-QRRBXD24.js → chunk-67JRXV6Z.js} +7 -7
- package/dist/{chunk-WA7FECSG.js → chunk-6ROCH5JV.js} +7 -7
- package/dist/{chunk-5QANTTY2.js → chunk-BIAMJUUJ.js} +4 -4
- package/dist/{chunk-IKHKHADN.js → chunk-C4LNKQ3M.js} +5 -5
- package/dist/{chunk-B35L45HZ.js → chunk-DC5OBZS3.js} +2 -2
- package/dist/{chunk-ORAK3LNZ.js → chunk-ER3CCWK2.js} +2 -2
- package/dist/{chunk-SD34EK4Z.js → chunk-FEELYTRT.js} +5 -5
- package/dist/{chunk-KQAFEZQX.js → chunk-FLVL4L3L.js} +2 -2
- package/dist/{chunk-WIWPSQYU.js → chunk-FXRFFYWD.js} +4 -4
- package/dist/{chunk-W3M34XT4.js → chunk-GECEETQ3.js} +4 -4
- package/dist/{chunk-WWSXVOGY.js → chunk-GFGYHLON.js} +2 -2
- package/dist/{chunk-BJMBJZ2Y.js → chunk-GWTFLF2P.js} +59 -59
- package/dist/chunk-GWTFLF2P.js.map +1 -0
- package/dist/{chunk-WOX2UW4K.js → chunk-IBPEVGP5.js} +2 -2
- package/dist/{chunk-JZ7P26GF.js → chunk-IQWFWSCP.js} +4 -4
- package/dist/{chunk-6SXNQFHB.js → chunk-J2JB6BHT.js} +8 -8
- package/dist/{chunk-K2JM4DZZ.js → chunk-JHZ3LEM7.js} +2 -2
- package/dist/{chunk-YGGXUNS4.js → chunk-JNKSFIAY.js} +45 -45
- package/dist/{chunk-CGZWGVQF.js → chunk-K5CWCJKJ.js} +6 -6
- package/dist/{chunk-TPLE6SNY.js → chunk-KFNG72W7.js} +7 -7
- package/dist/{chunk-4NWIGAIC.js → chunk-KT2VQLP7.js} +8 -8
- package/dist/{chunk-6FNZ3NMS.js → chunk-L3VSTJ2V.js} +2 -2
- package/dist/{chunk-ARV3AUOM.js → chunk-M5QKGHCR.js} +2 -2
- package/dist/{chunk-E4PFDD3N.js → chunk-MEPWWSTD.js} +4 -4
- package/dist/{chunk-V5RVMULT.js → chunk-MLDAD27I.js} +7 -7
- package/dist/{chunk-K2R3DEEH.js → chunk-MTN2G4DT.js} +2 -2
- package/dist/{chunk-DBSMLRTO.js → chunk-MW7UUXTA.js} +5 -5
- package/dist/{chunk-OSMBC3JU.js → chunk-OKOF7ITI.js} +6 -6
- package/dist/{chunk-DBRVU5PR.js → chunk-OVMLS7TN.js} +3 -3
- package/dist/{chunk-NNL4LJAD.js → chunk-QMMCMV2L.js} +5 -5
- package/dist/{chunk-RNWWAS5V.js → chunk-QRM3K3XT.js} +5 -5
- package/dist/{chunk-HM6UJPPO.js → chunk-R7TGDLV3.js} +4 -4
- package/dist/{chunk-EEKDRAWX.js → chunk-RBYV3WSB.js} +4 -4
- package/dist/{chunk-LOPZ2DWR.js → chunk-RRRZ3CLN.js} +4 -4
- package/dist/{chunk-7TWA7DKP.js → chunk-S5UYWK3O.js} +6 -6
- package/dist/{chunk-QOGXUNWL.js → chunk-SC5AEZLU.js} +9 -9
- package/dist/{chunk-SNEXVX3U.js → chunk-UFNQKZV7.js} +15 -15
- package/dist/{chunk-W3BFT5OJ.js → chunk-V4ZPLQLC.js} +2 -2
- package/dist/{chunk-SQNED75R.js → chunk-V5UV7BOA.js} +1 -1
- package/dist/{chunk-RWZB6MAY.js → chunk-VQL22SHO.js} +891 -1002
- package/dist/chunk-VQL22SHO.js.map +1 -0
- package/dist/{chunk-UETBEHBA.js → chunk-VX2RYM2K.js} +2232 -1942
- package/dist/chunk-VX2RYM2K.js.map +1 -0
- package/dist/{chunk-K5LLP4CY.js → chunk-XKAOT4ZB.js} +4 -4
- package/dist/{chunk-ZBVQ4ZM4.js → chunk-YGNQG4Q6.js} +8 -8
- package/dist/{chunk-EZ25VE3G.js → chunk-YNDLCWXS.js} +4 -4
- package/dist/{chunk-HYI2GP3F.js → chunk-ZGGI3COG.js} +9 -9
- package/dist/{cli-lmf5RGyQ.d.ts → cli-DFUU9WYu.d.ts} +3 -3
- package/dist/cli.d.ts +6 -6
- package/dist/cli.js +60 -60
- package/dist/compounding/engine.d.ts +1 -1
- package/dist/compounding/engine.js +6 -6
- package/dist/compounding/preference-consolidator.d.ts +1 -1
- package/dist/compression-optimizer.d.ts +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.js +1 -1
- package/dist/connectors/codex-materialize-runner.d.ts +1 -1
- package/dist/connectors/codex-materialize-runner.js +5 -5
- package/dist/connectors/codex-materialize.d.ts +1 -1
- package/dist/connectors/index.d.ts +1 -1
- package/dist/connectors/index.js +7 -7
- package/dist/consolidation-provenance-check.d.ts +1 -1
- package/dist/consolidation-undo.d.ts +1 -1
- package/dist/contradiction/index.d.ts +1 -1
- package/dist/contradiction/index.js +2 -2
- package/dist/{contradiction-scan-3FJYWS3G.js → contradiction-scan-KO4WWCS4.js} +3 -3
- package/dist/contradiction-scan-KO4WWCS4.js.map +1 -0
- package/dist/conversation-index/backend.d.ts +1 -1
- package/dist/conversation-index/chunker.d.ts +1 -1
- package/dist/conversation-index/faiss-adapter.d.ts +1 -1
- package/dist/conversation-index/indexer.d.ts +1 -1
- package/dist/conversation-index/search.d.ts +1 -1
- package/dist/dashboard-runtime.js +2 -2
- package/dist/day-summary.d.ts +1 -1
- package/dist/day-summary.js +2 -2
- package/dist/delinearize.d.ts +1 -1
- package/dist/direct-answer-wiring.d.ts +1 -1
- package/dist/direct-answer.d.ts +1 -1
- package/dist/embedding-fallback.d.ts +1 -1
- package/dist/embedding-fallback.js +2 -2
- package/dist/enrichment/index.d.ts +1 -1
- package/dist/entity-retrieval.d.ts +1 -1
- package/dist/entity-retrieval.js +5 -5
- package/dist/entity-schema.d.ts +1 -1
- package/dist/explicit-capture.d.ts +4 -4
- package/dist/explicit-capture.js +2 -2
- package/dist/extraction-faithfulness.d.ts +1 -1
- package/dist/extraction-judge-telemetry.d.ts +1 -1
- package/dist/extraction-judge-training.d.ts +1 -1
- package/dist/extraction-judge.d.ts +1 -1
- package/dist/extraction.d.ts +1 -1
- package/dist/extraction.js +4 -4
- package/dist/fallback-llm.d.ts +1 -1
- package/dist/graph-dashboard-diff.d.ts +1 -1
- package/dist/graph-dashboard-key.d.ts +1 -1
- package/dist/graph-dashboard-parser.d.ts +1 -1
- package/dist/graph-edge-reinforcement.d.ts +1 -1
- package/dist/graph-snapshot.d.ts +1 -1
- package/dist/graph.d.ts +1 -1
- package/dist/identity-continuity.d.ts +1 -1
- package/dist/importance.d.ts +1 -1
- package/dist/index.d.ts +9 -9
- package/dist/index.js +142 -142
- package/dist/intent.d.ts +1 -1
- package/dist/lcm/engine.d.ts +1 -1
- package/dist/lcm/engine.js +3 -3
- package/dist/lcm/index.d.ts +1 -1
- package/dist/lcm/index.js +8 -8
- package/dist/lcm/tools.d.ts +1 -1
- package/dist/lifecycle.d.ts +1 -1
- package/dist/live-connectors-runner.d.ts +1 -1
- package/dist/local-llm.d.ts +1 -1
- package/dist/local-llm.js +2 -2
- package/dist/local-model-endpoint.d.ts +1 -1
- package/dist/maintenance/memory-governance.d.ts +1 -1
- package/dist/maintenance/memory-governance.js +4 -4
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +4 -4
- package/dist/maintenance/rebuild-memory-projection.js +5 -5
- package/dist/mcp-memory-inspector-app.d.ts +5 -5
- package/dist/memory-action-policy.d.ts +1 -1
- package/dist/memory-cache.d.ts +1 -1
- package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
- package/dist/memory-projection-store.d.ts +1 -1
- package/dist/memory-provenance.d.ts +1 -1
- package/dist/memory-worth-outcomes.d.ts +1 -1
- package/dist/models-json.d.ts +1 -1
- package/dist/namespaces/migrate.d.ts +2 -2
- package/dist/namespaces/migrate.js +10 -10
- package/dist/namespaces/principal.d.ts +1 -1
- package/dist/namespaces/search.d.ts +1 -1
- package/dist/namespaces/search.js +4 -4
- package/dist/namespaces/storage.d.ts +2 -2
- package/dist/namespaces/storage.js +6 -6
- package/dist/native-knowledge.d.ts +1 -1
- package/dist/operator-toolkit.d.ts +1 -1
- package/dist/operator-toolkit.js +17 -17
- package/dist/orchestration/compression-guideline-coordinator.d.ts +1 -1
- package/dist/orchestration/compression-guideline-coordinator.js +2 -2
- package/dist/orchestration/maintenance.d.ts +2 -2
- package/dist/orchestration/maintenance.js +10 -10
- package/dist/{orchestrator-D7bb8ZGp.d.ts → orchestrator-BhxMxtQJ.d.ts} +27 -106
- package/dist/orchestrator.d.ts +4 -4
- package/dist/orchestrator.js +86 -86
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/policy-runtime.d.ts +1 -1
- package/dist/provenance.d.ts +1 -1
- package/dist/qmd-recall-cache.d.ts +1 -1
- package/dist/qmd.d.ts +1 -1
- package/dist/recall-disclosure-escalation.d.ts +1 -1
- package/dist/recall-explain-renderer.d.ts +1 -1
- package/dist/recall-planner-llm.d.ts +1 -1
- package/dist/recall-state.d.ts +1 -1
- package/dist/recall-tag-filter.d.ts +1 -1
- package/dist/recall-xray-cli.d.ts +1 -1
- package/dist/recall-xray-renderer.d.ts +1 -1
- package/dist/recall-xray.d.ts +1 -1
- package/dist/resolve-auth-token.d.ts +1 -1
- package/dist/resume-bundles.js +1 -1
- package/dist/retrieval-agents.d.ts +1 -1
- package/dist/retrieval-tiers.d.ts +1 -1
- package/dist/routing/engine.d.ts +1 -1
- package/dist/routing/store.d.ts +1 -1
- package/dist/routing/store.js +2 -2
- package/dist/schemas.d.ts +22 -22
- package/dist/search/embed-helper.d.ts +1 -1
- package/dist/search/embed-helper.js +2 -2
- package/dist/search/factory.d.ts +1 -1
- package/dist/search/factory.js +3 -3
- package/dist/search/index.d.ts +1 -1
- package/dist/search/index.js +3 -3
- package/dist/search/lancedb-backend.d.ts +1 -1
- package/dist/search/meilisearch-backend.d.ts +1 -1
- package/dist/search/noop-backend.d.ts +1 -1
- package/dist/search/orama-backend.d.ts +1 -1
- package/dist/search/port.d.ts +1 -1
- package/dist/search/remote-backend.d.ts +1 -1
- package/dist/secure-store/index.js +2 -2
- package/dist/{semantic-consolidation-CTfbVwCA.d.ts → semantic-consolidation-BrsoFeMP.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +7 -7
- package/dist/semantic-rule-promotion.js +4 -4
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/semantic-rule-verifier.js +4 -4
- package/dist/session-observer-bands.d.ts +1 -1
- package/dist/session-observer-state.d.ts +1 -1
- package/dist/shared-context/manager.d.ts +1 -1
- package/dist/shared-context/manager.js +2 -2
- package/dist/signal.d.ts +1 -1
- package/dist/storage.d.ts +1 -1
- package/dist/storage.js +3 -3
- package/dist/summarizer.d.ts +1 -1
- package/dist/summarizer.js +3 -3
- package/dist/summary-snapshot.d.ts +1 -1
- package/dist/temporal-supersession.d.ts +1 -1
- package/dist/temporal-validity.d.ts +1 -1
- package/dist/threading.d.ts +1 -1
- package/dist/tier-migration.d.ts +1 -1
- package/dist/tier-routing.d.ts +1 -1
- package/dist/topics.d.ts +1 -1
- package/dist/transcript.d.ts +1 -1
- package/dist/transfer/backup.js +3 -3
- package/dist/transfer/capsule-export.js +3 -3
- package/dist/transfer/capsule-import.js +3 -3
- package/dist/transfer/types.d.ts +12 -12
- package/dist/trust-score-stage.d.ts +1 -1
- package/dist/trust-score.d.ts +1 -1
- package/dist/{types-D4NYDtXI.d.ts → types-BfI4uJeb.d.ts} +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/utility-runtime.d.ts +1 -1
- package/dist/verified-recall.js +4 -4
- package/package.json +2 -2
- package/src/access-recall-surface.ts +1552 -0
- package/src/access-service.ts +29 -1219
- package/src/orchestration/recall-entry.ts +290 -0
- package/src/orchestration/session-context.ts +407 -0
- package/src/orchestrator.ts +125 -462
- package/dist/chunk-BJMBJZ2Y.js.map +0 -1
- package/dist/chunk-RWZB6MAY.js.map +0 -1
- package/dist/chunk-UETBEHBA.js.map +0 -1
- /package/dist/{capsule-crypto-7FJQINUR.js.map → access-recall-surface.js.map} +0 -0
- /package/dist/{contradiction-scan-3FJYWS3G.js.map → capsule-crypto-CZJSLEFG.js.map} +0 -0
- /package/dist/{chunk-2NLLXCJG.js.map → chunk-2BFLDH5F.js.map} +0 -0
- /package/dist/{chunk-UU32EAIY.js.map → chunk-2DPCAW2T.js.map} +0 -0
- /package/dist/{chunk-5PZCDUJ6.js.map → chunk-2U4E34Y3.js.map} +0 -0
- /package/dist/{chunk-JRZV3767.js.map → chunk-33NX5BLR.js.map} +0 -0
- /package/dist/{chunk-X7Y7WX73.js.map → chunk-437S3G37.js.map} +0 -0
- /package/dist/{chunk-HAZVVOYT.js.map → chunk-5DXUE7GB.js.map} +0 -0
- /package/dist/{chunk-4DLFJJOQ.js.map → chunk-5JAT4ZJD.js.map} +0 -0
- /package/dist/{chunk-RS25QOKZ.js.map → chunk-64SE4X5G.js.map} +0 -0
- /package/dist/{chunk-QRRBXD24.js.map → chunk-67JRXV6Z.js.map} +0 -0
- /package/dist/{chunk-WA7FECSG.js.map → chunk-6ROCH5JV.js.map} +0 -0
- /package/dist/{chunk-5QANTTY2.js.map → chunk-BIAMJUUJ.js.map} +0 -0
- /package/dist/{chunk-IKHKHADN.js.map → chunk-C4LNKQ3M.js.map} +0 -0
- /package/dist/{chunk-B35L45HZ.js.map → chunk-DC5OBZS3.js.map} +0 -0
- /package/dist/{chunk-ORAK3LNZ.js.map → chunk-ER3CCWK2.js.map} +0 -0
- /package/dist/{chunk-SD34EK4Z.js.map → chunk-FEELYTRT.js.map} +0 -0
- /package/dist/{chunk-KQAFEZQX.js.map → chunk-FLVL4L3L.js.map} +0 -0
- /package/dist/{chunk-WIWPSQYU.js.map → chunk-FXRFFYWD.js.map} +0 -0
- /package/dist/{chunk-W3M34XT4.js.map → chunk-GECEETQ3.js.map} +0 -0
- /package/dist/{chunk-WWSXVOGY.js.map → chunk-GFGYHLON.js.map} +0 -0
- /package/dist/{chunk-WOX2UW4K.js.map → chunk-IBPEVGP5.js.map} +0 -0
- /package/dist/{chunk-JZ7P26GF.js.map → chunk-IQWFWSCP.js.map} +0 -0
- /package/dist/{chunk-6SXNQFHB.js.map → chunk-J2JB6BHT.js.map} +0 -0
- /package/dist/{chunk-K2JM4DZZ.js.map → chunk-JHZ3LEM7.js.map} +0 -0
- /package/dist/{chunk-YGGXUNS4.js.map → chunk-JNKSFIAY.js.map} +0 -0
- /package/dist/{chunk-CGZWGVQF.js.map → chunk-K5CWCJKJ.js.map} +0 -0
- /package/dist/{chunk-TPLE6SNY.js.map → chunk-KFNG72W7.js.map} +0 -0
- /package/dist/{chunk-4NWIGAIC.js.map → chunk-KT2VQLP7.js.map} +0 -0
- /package/dist/{chunk-6FNZ3NMS.js.map → chunk-L3VSTJ2V.js.map} +0 -0
- /package/dist/{chunk-ARV3AUOM.js.map → chunk-M5QKGHCR.js.map} +0 -0
- /package/dist/{chunk-E4PFDD3N.js.map → chunk-MEPWWSTD.js.map} +0 -0
- /package/dist/{chunk-V5RVMULT.js.map → chunk-MLDAD27I.js.map} +0 -0
- /package/dist/{chunk-K2R3DEEH.js.map → chunk-MTN2G4DT.js.map} +0 -0
- /package/dist/{chunk-DBSMLRTO.js.map → chunk-MW7UUXTA.js.map} +0 -0
- /package/dist/{chunk-OSMBC3JU.js.map → chunk-OKOF7ITI.js.map} +0 -0
- /package/dist/{chunk-DBRVU5PR.js.map → chunk-OVMLS7TN.js.map} +0 -0
- /package/dist/{chunk-NNL4LJAD.js.map → chunk-QMMCMV2L.js.map} +0 -0
- /package/dist/{chunk-RNWWAS5V.js.map → chunk-QRM3K3XT.js.map} +0 -0
- /package/dist/{chunk-HM6UJPPO.js.map → chunk-R7TGDLV3.js.map} +0 -0
- /package/dist/{chunk-EEKDRAWX.js.map → chunk-RBYV3WSB.js.map} +0 -0
- /package/dist/{chunk-LOPZ2DWR.js.map → chunk-RRRZ3CLN.js.map} +0 -0
- /package/dist/{chunk-7TWA7DKP.js.map → chunk-S5UYWK3O.js.map} +0 -0
- /package/dist/{chunk-QOGXUNWL.js.map → chunk-SC5AEZLU.js.map} +0 -0
- /package/dist/{chunk-SNEXVX3U.js.map → chunk-UFNQKZV7.js.map} +0 -0
- /package/dist/{chunk-W3BFT5OJ.js.map → chunk-V4ZPLQLC.js.map} +0 -0
- /package/dist/{chunk-SQNED75R.js.map → chunk-V5UV7BOA.js.map} +0 -0
- /package/dist/{chunk-K5LLP4CY.js.map → chunk-XKAOT4ZB.js.map} +0 -0
- /package/dist/{chunk-ZBVQ4ZM4.js.map → chunk-YGNQG4Q6.js.map} +0 -0
- /package/dist/{chunk-EZ25VE3G.js.map → chunk-YNDLCWXS.js.map} +0 -0
- /package/dist/{chunk-HYI2GP3F.js.map → chunk-ZGGI3COG.js.map} +0 -0
package/src/orchestrator.ts
CHANGED
|
@@ -118,6 +118,8 @@ import { PersistenceIndexCoordinator } from "./orchestration/persistence-index.j
|
|
|
118
118
|
import { WorkspaceOpsCoordinator } from "./orchestration/workspace-ops.js";
|
|
119
119
|
import { NamespaceReadFanoutCoordinator } from "./orchestration/namespace-read-fanout.js";
|
|
120
120
|
import { selfDeps } from "./orchestration/self-deps.js";
|
|
121
|
+
import { RecallEntryCoordinator } from "./orchestration/recall-entry.js";
|
|
122
|
+
import { SessionContextCoordinator } from "./orchestration/session-context.js";
|
|
121
123
|
import {
|
|
122
124
|
abortRecallError,
|
|
123
125
|
buildCompressionGuidelinesMarkdown,
|
|
@@ -663,7 +665,7 @@ export class Orchestrator {
|
|
|
663
665
|
* project/branch scope a session is operating in (rule 42 — read + write
|
|
664
666
|
* through the same namespace layer).
|
|
665
667
|
*/
|
|
666
|
-
private
|
|
668
|
+
private _codingContextBySession = new Map<string, CodingContext>();
|
|
667
669
|
/**
|
|
668
670
|
* Per-session peer ID registry (issue #679 PR 3/5).
|
|
669
671
|
* Set by connectors / hooks via `setPeerIdForSession` so `recallInternal`
|
|
@@ -672,7 +674,19 @@ export class Orchestrator {
|
|
|
672
674
|
* Keyed by sessionKey so concurrent sessions don't clobber each other
|
|
673
675
|
* (rule 11 — scope globals per plugin ID / session).
|
|
674
676
|
*/
|
|
675
|
-
private
|
|
677
|
+
private _peerIdBySession = new Map<string, string>();
|
|
678
|
+
/**
|
|
679
|
+
* Defensive init for the session-binding maps (issue #1526 seam 28
|
|
680
|
+
* review). `Object.create(Orchestrator.prototype)` stubs in legacy
|
|
681
|
+
* tests skip class-field initializers, so the maps may be undefined on
|
|
682
|
+
* fakes; SessionContextCoordinator calls this before writing so the
|
|
683
|
+
* maps are created ON THE ORCHESTRATOR (or fake), never on the
|
|
684
|
+
* coordinator.
|
|
685
|
+
*/
|
|
686
|
+
ensureSessionBindingMaps(): void {
|
|
687
|
+
this._codingContextBySession ??= new Map<string, CodingContext>();
|
|
688
|
+
this._peerIdBySession ??= new Map<string, string>();
|
|
689
|
+
}
|
|
676
690
|
private routingRulesStore: RoutingRulesStore | null = null;
|
|
677
691
|
private contentHashIndex: ContentHashIndex | null = null;
|
|
678
692
|
private readonly contentHashIndexesByStorageDir = new Map<string, ContentHashIndex>();
|
|
@@ -969,188 +983,59 @@ export class Orchestrator {
|
|
|
969
983
|
return this.applyCodingNamespaceOverlay(sessionKey, base);
|
|
970
984
|
}
|
|
971
985
|
|
|
972
|
-
/**
|
|
973
|
-
* Effective namespace a same-session LCM/structured-history READER must use
|
|
974
|
-
* to find what the access `observe` surface WROTE (#1495 thread 2).
|
|
975
|
-
*
|
|
976
|
-
* This MUST mirror the `observe` scope plan's write-namespace resolution, NOT
|
|
977
|
-
* `resolveSelfNamespace`: when no coding overlay applies, `observe` archives
|
|
978
|
-
* under `config.defaultNamespace` (an unqualified observed turn is NOT moved
|
|
979
|
-
* to the principal self namespace — identical to
|
|
980
|
-
* `resolveCodingScopedWriteNamespace`/`memory_store`, rule 39). Only when a
|
|
981
|
-
* coding overlay actually changes the namespace does the writer (and so the
|
|
982
|
-
* reader) use the overlaid `project-*` namespace. Returning the self base for
|
|
983
|
-
* the no-overlay case would prefix the read key with a namespace the writer
|
|
984
|
-
* never used, so the reader would miss its own evidence.
|
|
985
|
-
*
|
|
986
|
-
* Honours the access-surface `principalOverride` (#1505 thread 2, codex): when
|
|
987
|
-
* a recall supplies an authenticated principal NOT encoded in the raw
|
|
988
|
-
* `sessionKey`, `observe` archived LCM under THAT principal's base namespace.
|
|
989
|
-
* Deriving the base from `resolvePrincipal(sessionKey)` alone could fall back
|
|
990
|
-
* to `default`, so principal `alice` observing `sess-1` would write under
|
|
991
|
-
* `alice` but READ under `default`. Threading the override here keeps the read
|
|
992
|
-
* base identical to the write base.
|
|
993
|
-
*
|
|
994
|
-
* READ-AUTHORIZATION gate (#1505 round 3, codex P2 "Gate LCM recall keys by
|
|
995
|
-
* readable namespaces"): the overlay LCM read key is a `<principal>-project-*`
|
|
996
|
-
* sub-namespace of the principal SELF base. The normal recall namespace set
|
|
997
|
-
* below only substitutes the coding overlay when the principal SELF base is
|
|
998
|
-
* actually in the readable recall set (`recallNamespacesForPrincipal` — gated
|
|
999
|
-
* by `defaultRecallNamespaces.includes("self")` AND `canReadNamespace`). If a
|
|
1000
|
-
* principal can WRITE but not READ its self namespace (or `defaultRecall-
|
|
1001
|
-
* Namespaces` omits `self`), QMD/file recall never touches those overlay rows,
|
|
1002
|
-
* so neither may the LCM read key. When the self base is NOT readable, fall
|
|
1003
|
-
* back to the default store — exactly what an unqualified, unauthorized recall
|
|
1004
|
-
* resolves to — rather than injecting overlay rows the rest of recall excludes
|
|
1005
|
-
* (rule 42 read/write parity; rule 48 least-privilege).
|
|
1006
|
-
*/
|
|
1007
986
|
private lcmReadNamespaceForSession(
|
|
1008
987
|
sessionKey?: string,
|
|
1009
988
|
principalOverride?: string,
|
|
1010
989
|
): string {
|
|
1011
|
-
|
|
1012
|
-
typeof
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
// No overlay → collapse to the default store so the LCM key is the raw
|
|
1018
|
-
// sessionKey, exactly what an unqualified observe archived under.
|
|
1019
|
-
if (overlaid === base) return this.config.defaultNamespace;
|
|
1020
|
-
// Overlay applied. Only honour it when the principal SELF base is in the
|
|
1021
|
-
// readable recall set (same gate the recall namespace set uses to
|
|
1022
|
-
// substitute the overlay). Otherwise the overlay rows are unauthorized for
|
|
1023
|
-
// this reader — fall back to the default store so the LCM read matches
|
|
1024
|
-
// what QMD/file recall would surface.
|
|
1025
|
-
const selfReadableInRecall = recallNamespacesForPrincipal(
|
|
1026
|
-
principal,
|
|
1027
|
-
this.config,
|
|
1028
|
-
).includes(base);
|
|
1029
|
-
return selfReadableInRecall ? overlaid : this.config.defaultNamespace;
|
|
990
|
+
return (this.sessionContextCoordinator ?? new SessionContextCoordinator(
|
|
991
|
+
selfDeps<ConstructorParameters<typeof SessionContextCoordinator>[0]>(this),
|
|
992
|
+
)).lcmReadNamespaceForSession(
|
|
993
|
+
sessionKey,
|
|
994
|
+
principalOverride,
|
|
995
|
+
);
|
|
1030
996
|
}
|
|
1031
997
|
|
|
1032
|
-
/**
|
|
1033
|
-
* Attach a coding-agent context to a session (issue #569). Called by the
|
|
1034
|
-
* Claude Code / Codex / Cursor connectors at session start after
|
|
1035
|
-
* `resolveGitContext(cwd)`. The context is consulted by the recall path
|
|
1036
|
-
* and the write path so that memories route to a project- (and optionally
|
|
1037
|
-
* branch-) scoped namespace.
|
|
1038
|
-
*
|
|
1039
|
-
* Pass `null` to clear.
|
|
1040
|
-
*/
|
|
1041
998
|
setCodingContextForSession(sessionKey: string, codingContext: CodingContext | null): void {
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
(this as unknown as { _codingContextBySession: Map<string, CodingContext> })._codingContextBySession = new Map();
|
|
1049
|
-
}
|
|
1050
|
-
if (codingContext === null) {
|
|
1051
|
-
this._codingContextBySession.delete(sessionKey);
|
|
1052
|
-
return;
|
|
1053
|
-
}
|
|
1054
|
-
this._codingContextBySession.set(sessionKey, codingContext);
|
|
999
|
+
return (this.sessionContextCoordinator ?? new SessionContextCoordinator(
|
|
1000
|
+
selfDeps<ConstructorParameters<typeof SessionContextCoordinator>[0]>(this),
|
|
1001
|
+
)).setCodingContextForSession(
|
|
1002
|
+
sessionKey,
|
|
1003
|
+
codingContext,
|
|
1004
|
+
);
|
|
1055
1005
|
}
|
|
1056
1006
|
|
|
1057
|
-
/**
|
|
1058
|
-
* Read-only accessor for the coding context attached to a session. Returns
|
|
1059
|
-
* `null` when none is set. Used by `remnic doctor` and by tests.
|
|
1060
|
-
*
|
|
1061
|
-
* Defensive `_codingContextBySession` lookup — legacy orchestrator-flush
|
|
1062
|
-
* tests use `Object.create(Orchestrator.prototype)` which does not run
|
|
1063
|
-
* class-field initializers, so the Map may be undefined on stubs.
|
|
1064
|
-
*/
|
|
1065
1007
|
getCodingContextForSession(sessionKey: string | undefined): CodingContext | null {
|
|
1066
|
-
|
|
1067
|
-
|
|
1008
|
+
return (this.sessionContextCoordinator ?? new SessionContextCoordinator(
|
|
1009
|
+
selfDeps<ConstructorParameters<typeof SessionContextCoordinator>[0]>(this),
|
|
1010
|
+
)).getCodingContextForSession(
|
|
1011
|
+
sessionKey,
|
|
1012
|
+
);
|
|
1068
1013
|
}
|
|
1069
1014
|
|
|
1070
|
-
/**
|
|
1071
|
-
* Shared helper used by both the recall path and the write path (rule 42).
|
|
1072
|
-
*
|
|
1073
|
-
* Given a base namespace computed from the principal, returns the overlaid
|
|
1074
|
-
* coding namespace when the session has a coding context AND
|
|
1075
|
-
* `codingMode.projectScope` is true AND `namespacesEnabled` is true.
|
|
1076
|
-
* Otherwise returns `baseNamespace` unchanged — CLAUDE.md #30 escape hatch.
|
|
1077
|
-
*
|
|
1078
|
-
* Principal isolation (CLAUDE.md rule 42): the overlay is COMBINED with
|
|
1079
|
-
* the principal-derived `baseNamespace` rather than replacing it, so two
|
|
1080
|
-
* principals working in the same repository do not share memories through
|
|
1081
|
-
* a common `project-*` namespace.
|
|
1082
|
-
*
|
|
1083
|
-
* Namespaces-disabled gate: when `namespacesEnabled` is false, the
|
|
1084
|
-
* storage router maps every namespace to the same `memoryDir`. Returning
|
|
1085
|
-
* `project-*` in that mode would create apparent route separation with
|
|
1086
|
-
* no actual storage isolation — a false-isolation trap. In that mode we
|
|
1087
|
-
* return `baseNamespace` unchanged so coding mode degrades to the existing
|
|
1088
|
-
* unscoped behavior.
|
|
1089
|
-
*
|
|
1090
|
-
* @internal
|
|
1091
|
-
*/
|
|
1092
1015
|
applyCodingNamespaceOverlay(sessionKey: string | undefined, baseNamespace: string): string {
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1016
|
+
return (this.sessionContextCoordinator ?? new SessionContextCoordinator(
|
|
1017
|
+
selfDeps<ConstructorParameters<typeof SessionContextCoordinator>[0]>(this),
|
|
1018
|
+
)).applyCodingNamespaceOverlay(
|
|
1019
|
+
sessionKey,
|
|
1020
|
+
baseNamespace,
|
|
1021
|
+
);
|
|
1098
1022
|
}
|
|
1099
1023
|
|
|
1100
|
-
/**
|
|
1101
|
-
* Register a peer ID for a session so recall can inject the peer's
|
|
1102
|
-
* profile into context (issue #679 PR 3/5). Pass `null` to clear.
|
|
1103
|
-
*
|
|
1104
|
-
* Connectors and the `before_agent_start` hook call this when the
|
|
1105
|
-
* session's counter-party is known. The ID is validated against
|
|
1106
|
-
* `PEER_ID_PATTERN` before storing.
|
|
1107
|
-
*
|
|
1108
|
-
* Fail-closed (Codex P1 review): an invalid peerId clears any
|
|
1109
|
-
* previously registered mapping for the session rather than silently
|
|
1110
|
-
* keeping stale data. This prevents a malformed metadata update from
|
|
1111
|
-
* mixing one peer's profile context into another session.
|
|
1112
|
-
*
|
|
1113
|
-
* Defensive init (Cursor review + rule 16): `Object.create(
|
|
1114
|
-
* Orchestrator.prototype)` stubs in legacy tests skip class-field
|
|
1115
|
-
* initializers, so `_peerIdBySession` may be undefined. Mirror the
|
|
1116
|
-
* same guard used by `setCodingContextForSession`.
|
|
1117
|
-
*/
|
|
1118
1024
|
setPeerIdForSession(sessionKey: string, peerId: string | null): void {
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
this._peerIdBySession.delete(sessionKey);
|
|
1126
|
-
return;
|
|
1127
|
-
}
|
|
1128
|
-
// Basic pattern guard — full validation lives in peers/storage.ts.
|
|
1129
|
-
// Invalid input is fail-closed: clear the existing mapping so stale
|
|
1130
|
-
// peer context can't bleed in after a bad metadata update (Codex P1).
|
|
1131
|
-
if (
|
|
1132
|
-
typeof peerId !== "string" ||
|
|
1133
|
-
peerId.length === 0 ||
|
|
1134
|
-
peerId.length > 64 ||
|
|
1135
|
-
!/^[A-Za-z0-9]+(?:[._-][A-Za-z0-9]+)*$/.test(peerId)
|
|
1136
|
-
) {
|
|
1137
|
-
log.warn(`setPeerIdForSession: invalid peerId — clearing session mapping`);
|
|
1138
|
-
this._peerIdBySession.delete(sessionKey);
|
|
1139
|
-
return;
|
|
1140
|
-
}
|
|
1141
|
-
this._peerIdBySession.set(sessionKey, peerId);
|
|
1025
|
+
return (this.sessionContextCoordinator ?? new SessionContextCoordinator(
|
|
1026
|
+
selfDeps<ConstructorParameters<typeof SessionContextCoordinator>[0]>(this),
|
|
1027
|
+
)).setPeerIdForSession(
|
|
1028
|
+
sessionKey,
|
|
1029
|
+
peerId,
|
|
1030
|
+
);
|
|
1142
1031
|
}
|
|
1143
1032
|
|
|
1144
|
-
/**
|
|
1145
|
-
* Return the peer ID registered for a session, or `null` when none
|
|
1146
|
-
* is set. Used by `recallInternal` to inject the peer profile section.
|
|
1147
|
-
* Defensive `_peerIdBySession` lookup — legacy orchestrator-flush tests
|
|
1148
|
-
* use `Object.create(Orchestrator.prototype)` which skips class-field
|
|
1149
|
-
* initializers, so the Map may be undefined on stubs.
|
|
1150
|
-
*/
|
|
1151
1033
|
getPeerIdForSession(sessionKey: string | undefined): string | null {
|
|
1152
|
-
|
|
1153
|
-
|
|
1034
|
+
return (this.sessionContextCoordinator ?? new SessionContextCoordinator(
|
|
1035
|
+
selfDeps<ConstructorParameters<typeof SessionContextCoordinator>[0]>(this),
|
|
1036
|
+
)).getPeerIdForSession(
|
|
1037
|
+
sessionKey,
|
|
1038
|
+
);
|
|
1154
1039
|
}
|
|
1155
1040
|
|
|
1156
1041
|
/**
|
|
@@ -2161,24 +2046,11 @@ export class Orchestrator {
|
|
|
2161
2046
|
dryRun?: boolean;
|
|
2162
2047
|
storage?: StorageManager;
|
|
2163
2048
|
}): Promise<{ scannedMemories: number; appliedActionCount: number; notes?: string }> {
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
mode: options?.dryRun === true ? "shadow" : "apply",
|
|
2170
|
-
});
|
|
2171
|
-
if (options?.dryRun !== true) {
|
|
2172
|
-
try {
|
|
2173
|
-
await this.processEntitySynthesisQueue(
|
|
2174
|
-
this.storageDirNamespace(targetStorage.dir),
|
|
2175
|
-
5,
|
|
2176
|
-
);
|
|
2177
|
-
} catch (error) {
|
|
2178
|
-
log.debug(`deep-sleep governance: entity synthesis refresh failed after apply: ${error}`);
|
|
2179
|
-
}
|
|
2180
|
-
}
|
|
2181
|
-
return summarizeGovernanceResultForDreams(govResult, options?.dryRun === true);
|
|
2049
|
+
return (this.sessionContextCoordinator ?? new SessionContextCoordinator(
|
|
2050
|
+
selfDeps<ConstructorParameters<typeof SessionContextCoordinator>[0]>(this),
|
|
2051
|
+
)).runDeepSleepGovernanceNow(
|
|
2052
|
+
options,
|
|
2053
|
+
);
|
|
2182
2054
|
}
|
|
2183
2055
|
|
|
2184
2056
|
// Issue #1526 (seam 5): semantic consolidation moved to
|
|
@@ -2232,23 +2104,11 @@ export class Orchestrator {
|
|
|
2232
2104
|
async generateDaySummary(
|
|
2233
2105
|
memories: string | MemoryFile[],
|
|
2234
2106
|
): Promise<DaySummaryResult | null> {
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
new Promise((resolve) => {
|
|
2241
|
-
initGateTimeoutHandle = setTimeout(
|
|
2242
|
-
resolve,
|
|
2243
|
-
this.config.initGateTimeoutMs,
|
|
2244
|
-
);
|
|
2245
|
-
}),
|
|
2246
|
-
]);
|
|
2247
|
-
} finally {
|
|
2248
|
-
if (initGateTimeoutHandle) clearTimeout(initGateTimeoutHandle);
|
|
2249
|
-
}
|
|
2250
|
-
}
|
|
2251
|
-
return this.extraction.generateDaySummary(memories);
|
|
2107
|
+
return (this.sessionContextCoordinator ?? new SessionContextCoordinator(
|
|
2108
|
+
selfDeps<ConstructorParameters<typeof SessionContextCoordinator>[0]>(this),
|
|
2109
|
+
)).generateDaySummary(
|
|
2110
|
+
memories,
|
|
2111
|
+
);
|
|
2252
2112
|
}
|
|
2253
2113
|
|
|
2254
2114
|
/**
|
|
@@ -2453,136 +2313,13 @@ export class Orchestrator {
|
|
|
2453
2313
|
sessionKey?: string,
|
|
2454
2314
|
options: RecallInvocationOptions = {},
|
|
2455
2315
|
): Promise<string> {
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
abortController.abort();
|
|
2464
|
-
};
|
|
2465
|
-
if (options.abortSignal?.aborted) {
|
|
2466
|
-
abortController.abort();
|
|
2467
|
-
} else {
|
|
2468
|
-
options.abortSignal?.addEventListener("abort", onAbort, { once: true });
|
|
2469
|
-
}
|
|
2470
|
-
|
|
2471
|
-
const principal =
|
|
2472
|
-
typeof options.principalOverride === "string" &&
|
|
2473
|
-
options.principalOverride.length > 0
|
|
2474
|
-
? options.principalOverride
|
|
2475
|
-
: resolvePrincipal(sessionKey, this.config);
|
|
2476
|
-
const namespacesEnabled = resolveNamespaceCapabilities(this.config).namespaces;
|
|
2477
|
-
if (namespacesEnabled && !principal) {
|
|
2478
|
-
throw new Error("authentication required: namespaces are enabled and no principal was supplied");
|
|
2479
|
-
}
|
|
2480
|
-
|
|
2481
|
-
// Wait for initialization to complete before attempting recall. The timeout
|
|
2482
|
-
// is configurable so OpenClaw's per-hook budget and Remnic's internal init
|
|
2483
|
-
// gate can stay aligned during cold starts.
|
|
2484
|
-
let initGateTimeoutHandle: NodeJS.Timeout | null = null;
|
|
2485
|
-
let onInitGateAbort: (() => void) | null = null;
|
|
2486
|
-
if (this.initPromise) {
|
|
2487
|
-
const gateResult = await Promise.race([
|
|
2488
|
-
this.initPromise.then(() => "ok" as const),
|
|
2489
|
-
new Promise<"timeout">((resolve) => {
|
|
2490
|
-
initGateTimeoutHandle = setTimeout(
|
|
2491
|
-
() => resolve("timeout"),
|
|
2492
|
-
this.config.initGateTimeoutMs,
|
|
2493
|
-
);
|
|
2494
|
-
}),
|
|
2495
|
-
abortController.signal.aborted
|
|
2496
|
-
? Promise.resolve("aborted" as const)
|
|
2497
|
-
: new Promise<"aborted">((resolve) => {
|
|
2498
|
-
onInitGateAbort = () => resolve("aborted");
|
|
2499
|
-
abortController.signal.addEventListener(
|
|
2500
|
-
"abort",
|
|
2501
|
-
onInitGateAbort,
|
|
2502
|
-
{ once: true },
|
|
2503
|
-
);
|
|
2504
|
-
}),
|
|
2505
|
-
]);
|
|
2506
|
-
if (initGateTimeoutHandle) clearTimeout(initGateTimeoutHandle);
|
|
2507
|
-
if (onInitGateAbort)
|
|
2508
|
-
abortController.signal.removeEventListener("abort", onInitGateAbort);
|
|
2509
|
-
if (gateResult === "aborted") {
|
|
2510
|
-
this.logRecallFailure(abortRecallError("recall aborted before init"));
|
|
2511
|
-
return "";
|
|
2512
|
-
}
|
|
2513
|
-
if (gateResult === "timeout") {
|
|
2514
|
-
log.warn("recall: init gate timed out — proceeding without full init");
|
|
2515
|
-
}
|
|
2516
|
-
}
|
|
2517
|
-
|
|
2518
|
-
// Secure-store lock gate (issue #690 PR 3/4).
|
|
2519
|
-
// If secure-store is enabled but the keyring holds no key for this
|
|
2520
|
-
// memory directory, reject recall with a clear human-readable error
|
|
2521
|
-
// rather than surfacing a cryptic SecureStoreLockedError from deep
|
|
2522
|
-
// inside the storage layer.
|
|
2523
|
-
if (resolveRecallAuxiliaryCapabilities(this.config).secureStore && !this.storage.isSecureStoreUnlocked()) {
|
|
2524
|
-
const lockedMsg =
|
|
2525
|
-
"[secure-store locked] Memory store is encrypted and locked. " +
|
|
2526
|
-
"Unlock the secure-store inside this daemon process, or restart the daemon through a secure-store aware launcher that installs the key.";
|
|
2527
|
-
log.warn("recall blocked: secure-store is locked");
|
|
2528
|
-
return lockedMsg;
|
|
2529
|
-
}
|
|
2530
|
-
|
|
2531
|
-
// Keep outer recall timeout above worst-case serialized hybrid search:
|
|
2532
|
-
// QMD subprocess BM25 (30s) + vector (30s) can consume ~60s under contention.
|
|
2533
|
-
try {
|
|
2534
|
-
const recallPromise = this.recallInternal(prompt, sessionKey, {
|
|
2535
|
-
...options,
|
|
2536
|
-
abortSignal: abortController.signal,
|
|
2537
|
-
}, caps, graphCaps);
|
|
2538
|
-
const RECALL_TIMEOUT_MS = this.config.recallOuterTimeoutMs ?? 75_000;
|
|
2539
|
-
if (RECALL_TIMEOUT_MS <= 0) {
|
|
2540
|
-
return await recallPromise;
|
|
2541
|
-
}
|
|
2542
|
-
|
|
2543
|
-
let timeoutHandle: NodeJS.Timeout | null = null;
|
|
2544
|
-
const timeoutPromise = new Promise<string>((_, reject) => {
|
|
2545
|
-
timeoutHandle = setTimeout(() => {
|
|
2546
|
-
abortController.abort();
|
|
2547
|
-
reject(new Error("recall timeout"));
|
|
2548
|
-
}, RECALL_TIMEOUT_MS);
|
|
2549
|
-
});
|
|
2550
|
-
|
|
2551
|
-
let recallResult: string;
|
|
2552
|
-
try {
|
|
2553
|
-
recallResult = await Promise.race([recallPromise, timeoutPromise]);
|
|
2554
|
-
} finally {
|
|
2555
|
-
if (timeoutHandle) clearTimeout(timeoutHandle);
|
|
2556
|
-
}
|
|
2557
|
-
|
|
2558
|
-
// Observation-mode direct-answer tier (issue #518 slice 3c).
|
|
2559
|
-
// Runs after the user's recall already succeeded, fire-and-forget,
|
|
2560
|
-
// so annotation latency can never delay the caller's response.
|
|
2561
|
-
if (caps.recallDirectAnswer && sessionKey) {
|
|
2562
|
-
try {
|
|
2563
|
-
this.enqueueDirectAnswerObservation(
|
|
2564
|
-
prompt,
|
|
2565
|
-
sessionKey,
|
|
2566
|
-
options.namespace?.trim() || undefined,
|
|
2567
|
-
options.principalOverride,
|
|
2568
|
-
caps,
|
|
2569
|
-
namespacesEnabled,
|
|
2570
|
-
);
|
|
2571
|
-
} catch (err) {
|
|
2572
|
-
log.debug(`direct-answer observation setup failed: ${err}`);
|
|
2573
|
-
}
|
|
2574
|
-
}
|
|
2575
|
-
|
|
2576
|
-
return recallResult;
|
|
2577
|
-
} catch (err) {
|
|
2578
|
-
this.logRecallFailure(err);
|
|
2579
|
-
// endTrace() is safe here: if no trace is active (disabled or already
|
|
2580
|
-
// closed by recallInternal's try/finally), it returns null immediately.
|
|
2581
|
-
this.profiler.endTrace();
|
|
2582
|
-
return ""; // Return empty context on timeout/error
|
|
2583
|
-
} finally {
|
|
2584
|
-
options.abortSignal?.removeEventListener("abort", onAbort);
|
|
2585
|
-
}
|
|
2316
|
+
return (this.recallEntryCoordinator ?? new RecallEntryCoordinator(
|
|
2317
|
+
selfDeps<ConstructorParameters<typeof RecallEntryCoordinator>[0]>(this),
|
|
2318
|
+
)).recall(
|
|
2319
|
+
prompt,
|
|
2320
|
+
sessionKey,
|
|
2321
|
+
options,
|
|
2322
|
+
);
|
|
2586
2323
|
}
|
|
2587
2324
|
|
|
2588
2325
|
/**
|
|
@@ -2649,28 +2386,11 @@ export class Orchestrator {
|
|
|
2649
2386
|
}
|
|
2650
2387
|
|
|
2651
2388
|
private logRecallFailure(err: unknown): void {
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
if (idleSinceLastFailureMs >= LOG_WINDOW_MS) {
|
|
2658
|
-
this.suppressedRecallFailures = 0;
|
|
2659
|
-
}
|
|
2660
|
-
|
|
2661
|
-
if (now - this.lastRecallFailureLogAtMs >= LOG_WINDOW_MS) {
|
|
2662
|
-
const suffix =
|
|
2663
|
-
this.suppressedRecallFailures > 0
|
|
2664
|
-
? ` (suppressed ${this.suppressedRecallFailures} similar failures in last minute)`
|
|
2665
|
-
: "";
|
|
2666
|
-
log.warn(`recall timed out or failed: ${errorMsg}${suffix}`);
|
|
2667
|
-
this.lastRecallFailureLogAtMs = now;
|
|
2668
|
-
this.suppressedRecallFailures = 0;
|
|
2669
|
-
return;
|
|
2670
|
-
}
|
|
2671
|
-
|
|
2672
|
-
this.suppressedRecallFailures += 1;
|
|
2673
|
-
log.debug(`recall timed out or failed (suppressed): ${errorMsg}`);
|
|
2389
|
+
return (this.recallEntryCoordinator ?? new RecallEntryCoordinator(
|
|
2390
|
+
selfDeps<ConstructorParameters<typeof RecallEntryCoordinator>[0]>(this),
|
|
2391
|
+
)).logRecallFailure(
|
|
2392
|
+
err,
|
|
2393
|
+
);
|
|
2674
2394
|
}
|
|
2675
2395
|
|
|
2676
2396
|
private artifactTypeForCategory(
|
|
@@ -3101,6 +2821,40 @@ export class Orchestrator {
|
|
|
3101
2821
|
return this._namespaceReadFanoutCoordinator;
|
|
3102
2822
|
}
|
|
3103
2823
|
|
|
2824
|
+
/** RecallEntryCoordinator (issue #1526 seam 28). Lazy; selfDeps live wiring. */
|
|
2825
|
+
private _recallEntryCoordinator: RecallEntryCoordinator | undefined;
|
|
2826
|
+
|
|
2827
|
+
private get recallEntryCoordinator(): RecallEntryCoordinator {
|
|
2828
|
+
if (!this._recallEntryCoordinator) {
|
|
2829
|
+
this._recallEntryCoordinator = new RecallEntryCoordinator(
|
|
2830
|
+
selfDeps<ConstructorParameters<typeof RecallEntryCoordinator>[0]>(this),
|
|
2831
|
+
);
|
|
2832
|
+
}
|
|
2833
|
+
return this._recallEntryCoordinator;
|
|
2834
|
+
}
|
|
2835
|
+
|
|
2836
|
+
/** SessionContextCoordinator (issue #1526 seam 28). Lazy; selfDeps live wiring. */
|
|
2837
|
+
private _sessionContextCoordinator: SessionContextCoordinator | undefined;
|
|
2838
|
+
|
|
2839
|
+
/**
|
|
2840
|
+
* Self-handle read through the selfDeps proxy (seam 28): coordinators
|
|
2841
|
+
* that construct services against the orchestrator instance (e.g. the
|
|
2842
|
+
* passive-correction CorrectionService) receive it via deps instead of
|
|
2843
|
+
* capturing the coordinator's own `this`.
|
|
2844
|
+
*/
|
|
2845
|
+
get orchestratorSelf(): Orchestrator {
|
|
2846
|
+
return this;
|
|
2847
|
+
}
|
|
2848
|
+
|
|
2849
|
+
private get sessionContextCoordinator(): SessionContextCoordinator {
|
|
2850
|
+
if (!this._sessionContextCoordinator) {
|
|
2851
|
+
this._sessionContextCoordinator = new SessionContextCoordinator(
|
|
2852
|
+
selfDeps<ConstructorParameters<typeof SessionContextCoordinator>[0]>(this),
|
|
2853
|
+
);
|
|
2854
|
+
}
|
|
2855
|
+
return this._sessionContextCoordinator;
|
|
2856
|
+
}
|
|
2857
|
+
|
|
3104
2858
|
private async recallInternal(
|
|
3105
2859
|
prompt: string,
|
|
3106
2860
|
sessionKey?: string,
|
|
@@ -3147,39 +2901,12 @@ export class Orchestrator {
|
|
|
3147
2901
|
bufferKey?: string;
|
|
3148
2902
|
},
|
|
3149
2903
|
): Promise<void> {
|
|
3150
|
-
|
|
3151
|
-
typeof
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
typeof sessionKey !== "string" ||
|
|
3157
|
-
sessionKey.length === 0 ||
|
|
3158
|
-
typeof this.buffer.findBufferKeysForSession !== "function"
|
|
3159
|
-
? []
|
|
3160
|
-
: await this.buffer.findBufferKeysForSession(sessionKey);
|
|
3161
|
-
const bufferKeys = explicitBufferKey
|
|
3162
|
-
? [explicitBufferKey]
|
|
3163
|
-
: discoveredBufferKeys.length > 0
|
|
3164
|
-
? discoveredBufferKeys
|
|
3165
|
-
: typeof sessionKey === "string" && sessionKey.length > 0
|
|
3166
|
-
? [sessionKey]
|
|
3167
|
-
: ["default"];
|
|
3168
|
-
for (const bufferKey of bufferKeys) {
|
|
3169
|
-
const turns = this.buffer.getTurns(bufferKey);
|
|
3170
|
-
if (turns.length === 0) continue;
|
|
3171
|
-
await new Promise<void>((resolve, reject) => {
|
|
3172
|
-
void this
|
|
3173
|
-
.queueBufferedExtraction(turns, "trigger_mode", {
|
|
3174
|
-
bufferKey,
|
|
3175
|
-
clearBufferAfterExtraction: true,
|
|
3176
|
-
skipDedupeCheck: true,
|
|
3177
|
-
abortSignal: options.abortSignal,
|
|
3178
|
-
onTaskSettled: (error) => (error ? reject(error) : resolve()),
|
|
3179
|
-
})
|
|
3180
|
-
.catch(reject);
|
|
3181
|
-
});
|
|
3182
|
-
}
|
|
2904
|
+
return (this.sessionContextCoordinator ?? new SessionContextCoordinator(
|
|
2905
|
+
selfDeps<ConstructorParameters<typeof SessionContextCoordinator>[0]>(this),
|
|
2906
|
+
)).flushSession(
|
|
2907
|
+
sessionKey,
|
|
2908
|
+
options,
|
|
2909
|
+
);
|
|
3183
2910
|
}
|
|
3184
2911
|
|
|
3185
2912
|
async ingestReplayBatch(
|
|
@@ -3334,52 +3061,11 @@ export class Orchestrator {
|
|
|
3334
3061
|
);
|
|
3335
3062
|
}
|
|
3336
3063
|
|
|
3337
|
-
/** Lazily construct the CorrectionService for passive capture. Stateless
|
|
3338
|
-
* across requests (per #1580 design); cached for the orchestrator's life. */
|
|
3339
3064
|
private passiveCorrectionService(): CorrectionService {
|
|
3340
|
-
|
|
3341
|
-
|
|
3342
|
-
|
|
3343
|
-
|
|
3344
|
-
// ACL"). A correction detected in session S plans only against S readable
|
|
3345
|
-
// namespaces and applies only to writable ones (rule 42) — passive
|
|
3346
|
-
// capture never becomes a cross-tenant mutation vector. Mirrors the
|
|
3347
|
-
// access-service createCorrectionService wiring rather than bypassing it.
|
|
3348
|
-
resolveAuthorizedNamespace: async (req) => {
|
|
3349
|
-
const principal = req.principal || resolvePrincipal(req.sessionKey, this.config);
|
|
3350
|
-
const ns = req.namespace ?? defaultNamespaceForPrincipal(principal, this.config);
|
|
3351
|
-
if (!canWriteNamespace(principal, ns, this.config)) {
|
|
3352
|
-
throw new Error(
|
|
3353
|
-
`passive correction: namespace "${ns}" is not writable for principal ${principal ?? "(none)"}`,
|
|
3354
|
-
);
|
|
3355
|
-
}
|
|
3356
|
-
return ns;
|
|
3357
|
-
},
|
|
3358
|
-
resolveReadableNamespaces: (req) => {
|
|
3359
|
-
const principal = req.principal || resolvePrincipal(req.sessionKey, this.config);
|
|
3360
|
-
return recallNamespacesForPrincipal(principal, this.config);
|
|
3361
|
-
},
|
|
3362
|
-
canWriteNamespace: async (req) => {
|
|
3363
|
-
const principal = req.principal || resolvePrincipal(req.sessionKey, this.config);
|
|
3364
|
-
return canWriteNamespace(principal, req.namespace, this.config);
|
|
3365
|
-
},
|
|
3366
|
-
llmComplete: async ({ system, user }) => {
|
|
3367
|
-
const llmResult = await this.localLlm.chatCompletion(
|
|
3368
|
-
[
|
|
3369
|
-
{ role: "system", content: system },
|
|
3370
|
-
{ role: "user", content: user },
|
|
3371
|
-
],
|
|
3372
|
-
{ operation: "correction-classify", priority: "background" },
|
|
3373
|
-
);
|
|
3374
|
-
if (!llmResult) {
|
|
3375
|
-
throw new Error(
|
|
3376
|
-
"passive correction classify+draft: local LLM unavailable (disabled or in cooldown)",
|
|
3377
|
-
);
|
|
3378
|
-
}
|
|
3379
|
-
return llmResult.content;
|
|
3380
|
-
},
|
|
3381
|
-
});
|
|
3382
|
-
return this._passiveCorrectionService;
|
|
3065
|
+
return (this.sessionContextCoordinator ?? new SessionContextCoordinator(
|
|
3066
|
+
selfDeps<ConstructorParameters<typeof SessionContextCoordinator>[0]>(this),
|
|
3067
|
+
)).passiveCorrectionService(
|
|
3068
|
+
);
|
|
3383
3069
|
}
|
|
3384
3070
|
|
|
3385
3071
|
async runExtraction(
|
|
@@ -3706,24 +3392,11 @@ export class Orchestrator {
|
|
|
3706
3392
|
private queueEvalShadowRecall(
|
|
3707
3393
|
record: Omit<EvalShadowRecallRecord, "schemaVersion">,
|
|
3708
3394
|
): void {
|
|
3709
|
-
|
|
3710
|
-
|
|
3711
|
-
|
|
3712
|
-
|
|
3713
|
-
|
|
3714
|
-
try {
|
|
3715
|
-
await recordEvalShadowRecall({
|
|
3716
|
-
memoryDir: this.config.memoryDir,
|
|
3717
|
-
evalStoreDir: this.config.evalStoreDir,
|
|
3718
|
-
record: {
|
|
3719
|
-
schemaVersion: 1,
|
|
3720
|
-
...record,
|
|
3721
|
-
},
|
|
3722
|
-
});
|
|
3723
|
-
} catch (err) {
|
|
3724
|
-
log.debug(`eval shadow recall write failed: ${err}`);
|
|
3725
|
-
}
|
|
3726
|
-
});
|
|
3395
|
+
return (this.recallEntryCoordinator ?? new RecallEntryCoordinator(
|
|
3396
|
+
selfDeps<ConstructorParameters<typeof RecallEntryCoordinator>[0]>(this),
|
|
3397
|
+
)).queueEvalShadowRecall(
|
|
3398
|
+
record,
|
|
3399
|
+
);
|
|
3727
3400
|
}
|
|
3728
3401
|
|
|
3729
3402
|
private publishRecallResults(options: {
|
|
@@ -3747,20 +3420,10 @@ export class Orchestrator {
|
|
|
3747
3420
|
*/
|
|
3748
3421
|
trustByPath?: Map<string, TrustStageResultItem> | null;
|
|
3749
3422
|
}): void {
|
|
3750
|
-
|
|
3751
|
-
|
|
3752
|
-
|
|
3753
|
-
|
|
3754
|
-
const injectable = trustByPath
|
|
3755
|
-
? options.results.filter((r) => !trustByPath.get(r.path)?.quarantined)
|
|
3756
|
-
: options.results;
|
|
3757
|
-
const memoryIds = this.extractMemoryIdsFromResults(injectable);
|
|
3758
|
-
this.trackMemoryAccess(memoryIds);
|
|
3759
|
-
|
|
3760
|
-
this.appendRecallSection(
|
|
3761
|
-
options.sectionBuckets,
|
|
3762
|
-
sectionId,
|
|
3763
|
-
this.formatQmdResults(options.title, injectable, options.sessionKey, trustByPath),
|
|
3423
|
+
return (this.recallEntryCoordinator ?? new RecallEntryCoordinator(
|
|
3424
|
+
selfDeps<ConstructorParameters<typeof RecallEntryCoordinator>[0]>(this),
|
|
3425
|
+
)).publishRecallResults(
|
|
3426
|
+
options,
|
|
3764
3427
|
);
|
|
3765
3428
|
}
|
|
3766
3429
|
|