@remnic/core 9.30.1 → 9.32.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/access-admin-ops-surface.d.ts +10 -10
- package/dist/access-admin-ops-surface.js +55 -44
- package/dist/access-authorization-probe.d.ts +10 -10
- package/dist/access-authorization-probe.js +56 -45
- package/dist/access-boundary.d.ts +13 -11
- package/dist/access-boundary.js +55 -44
- package/dist/access-cli.js +170 -126
- package/dist/access-cli.js.map +1 -1
- package/dist/access-extraction-force-flush.d.ts +119 -0
- package/dist/access-extraction-force-flush.js +171 -0
- package/dist/access-health-types.d.ts +1 -1
- package/dist/access-http-lcm-compaction.d.ts +47 -13
- package/dist/access-http-lcm-compaction.js +7 -3
- package/dist/access-http-lifecycle-flush.d.ts +132 -0
- package/dist/access-http-lifecycle-flush.js +9 -0
- package/dist/access-http-lifecycle-flush.js.map +1 -0
- package/dist/access-http.d.ts +11 -10
- package/dist/access-http.js +71 -59
- package/dist/access-identity-continuity-surface.d.ts +8 -8
- package/dist/access-identity-continuity-surface.js +55 -44
- package/dist/access-lcm-surface.d.ts +10 -10
- package/dist/access-lcm-surface.js +55 -44
- package/dist/access-mcp-output-schemas.js +1 -1
- package/dist/access-mcp.d.ts +16 -10
- package/dist/access-mcp.js +63 -52
- package/dist/access-memory-search-fanout.d.ts +2 -2
- package/dist/{access-namespace-preflight-VfXssvoI.d.ts → access-namespace-preflight-COhbXBqS.d.ts} +1 -1
- package/dist/access-namespace-preflight.d.ts +3 -3
- package/dist/access-namespace-preflight.js +55 -44
- package/dist/access-observe-helpers.d.ts +22 -0
- package/dist/access-observe-helpers.js +10 -0
- package/dist/access-observe-helpers.js.map +1 -0
- package/dist/access-observe-write-surface.d.ts +51 -47
- package/dist/access-observe-write-surface.js +55 -44
- package/dist/access-operations-batch.js +58 -47
- package/dist/access-operations.d.ts +11 -11
- package/dist/access-operations.js +60 -49
- package/dist/access-recall-concurrency.d.ts +10 -10
- package/dist/access-recall-concurrency.js +55 -44
- package/dist/access-recall-response.d.ts +10 -10
- package/dist/access-recall-response.js +55 -44
- package/dist/access-recall-surface.d.ts +10 -10
- package/dist/access-recall-surface.js +55 -44
- package/dist/access-schema.d.ts +37 -7
- package/dist/access-schema.js +5 -3
- package/dist/{access-service-B5RwVsTV.d.ts → access-service-BmBTtEKO.d.ts} +44 -20
- package/dist/access-service-helpers.d.ts +113 -0
- package/dist/access-service-helpers.js +8 -0
- package/dist/access-service-helpers.js.map +1 -0
- package/dist/access-service.d.ts +10 -10
- package/dist/access-service.js +55 -44
- package/dist/access-surface-catalog.d.ts +10 -10
- package/dist/access-surface-catalog.js +2 -0
- package/dist/access-surface-catalog.js.map +1 -1
- package/dist/access-wearables-meetings-surface.d.ts +3 -3
- 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 +2 -2
- package/dist/adapters/index.js +7 -7
- package/dist/adapters/registry.js +3 -3
- package/dist/behavior-learner.d.ts +1 -1
- package/dist/behavior-signals.d.ts +1 -1
- package/dist/bootstrap.d.ts +8 -8
- package/dist/briefing.d.ts +2 -2
- package/dist/briefing.js +14 -14
- package/dist/buffer-surprise-report.d.ts +1 -1
- package/dist/buffer-turn-helpers.d.ts +5 -0
- package/dist/buffer-turn-helpers.js +24 -0
- package/dist/buffer-turn-helpers.js.map +1 -0
- package/dist/buffer.d.ts +17 -4
- package/dist/buffer.js +21 -1
- package/dist/bulk-import/index.d.ts +3 -3
- package/dist/calibration.d.ts +1 -1
- package/dist/capabilities.d.ts +1 -1
- package/dist/{capsule-crypto-GWVG7LGC.js → capsule-crypto-7FJQINUR.js} +2 -2
- package/dist/capsule-crypto-7FJQINUR.js.map +1 -0
- package/dist/{capsule-merge-5KKJQBWQ.js → capsule-merge-2H2IUTBT.js} +4 -4
- package/dist/{catalog-V7inUQdp.d.ts → catalog-Dm-DvNBY.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 +21 -22
- package/dist/causal-consolidation.js.map +1 -1
- 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-LEPOP46W.js → chunk-227UFSEQ.js} +4 -4
- package/dist/{chunk-I5NLEENJ.js → chunk-27HHNYSQ.js} +3 -3
- package/dist/{chunk-2SA56WMI.js → chunk-2LTDWSR6.js} +4 -4
- package/dist/{chunk-OWHERGF2.js → chunk-2NLLXCJG.js} +2 -2
- package/dist/{chunk-SPJXKAVF.js → chunk-2NTGBZLZ.js} +14 -13
- package/dist/chunk-2NTGBZLZ.js.map +1 -0
- package/dist/{chunk-P5PXWTW7.js → chunk-2Q4JJ3FZ.js} +3 -3
- package/dist/{chunk-G5R3D5UP.js → chunk-2QIMTVEJ.js} +6 -5
- package/dist/chunk-2QIMTVEJ.js.map +1 -0
- package/dist/{chunk-H5CPS5JP.js → chunk-35IVNNRK.js} +3 -3
- package/dist/{chunk-LBOD4U5B.js → chunk-3EQ2XB3W.js} +6 -6
- package/dist/{chunk-YTSNAUXN.js → chunk-3F2LKUMU.js} +22 -8
- package/dist/chunk-3F2LKUMU.js.map +1 -0
- package/dist/chunk-3QL24R5Y.js +9 -0
- package/dist/chunk-3QL24R5Y.js.map +1 -0
- package/dist/chunk-4RNZMRAV.js +60 -0
- package/dist/chunk-4RNZMRAV.js.map +1 -0
- package/dist/chunk-5IVLTFOV.js +65 -0
- package/dist/chunk-5IVLTFOV.js.map +1 -0
- package/dist/{chunk-2EUVEDF5.js → chunk-5WZVQRHV.js} +2 -2
- package/dist/{chunk-ALSGMEJR.js → chunk-65ZPVYTA.js} +7 -7
- package/dist/{chunk-GIBMDSJ2.js → chunk-6P7MTSU5.js} +2 -2
- package/dist/{chunk-5VQJBH2G.js → chunk-6TAUHL33.js} +2 -2
- package/dist/{chunk-WVO4G37W.js → chunk-7TEZUUGM.js} +3 -3
- package/dist/{chunk-MJCGLM25.js → chunk-7VUAG236.js} +5 -5
- package/dist/{chunk-CZRYLSSW.js → chunk-AJL6NNX6.js} +2 -2
- package/dist/{chunk-LGHKJABJ.js → chunk-AQEJE3WO.js} +40 -18
- package/dist/chunk-AQEJE3WO.js.map +1 -0
- package/dist/{chunk-66772WBP.js → chunk-AQWVJURR.js} +5 -5
- package/dist/{chunk-RKNJBZ55.js → chunk-AU7Q3LSC.js} +7 -7
- package/dist/{chunk-IYZ5K7MU.js → chunk-BUE5E2HL.js} +4 -187
- package/dist/chunk-BUE5E2HL.js.map +1 -0
- package/dist/{chunk-NHWB6HG2.js → chunk-CE5355TT.js} +21 -5
- package/dist/chunk-CE5355TT.js.map +1 -0
- package/dist/{chunk-M3C2V3PV.js → chunk-CJDNT45S.js} +12 -12
- package/dist/{chunk-D2ANTDGO.js → chunk-E6BMSH7U.js} +2 -2
- package/dist/{chunk-CKMO4RDY.js → chunk-EMDLM3LW.js} +4 -4
- package/dist/chunk-ER7W6H4T.js +112 -0
- package/dist/chunk-ER7W6H4T.js.map +1 -0
- package/dist/{chunk-RGIWINDN.js → chunk-FHBITMRY.js} +30 -30
- package/dist/{chunk-6FUPCJUL.js → chunk-FMFLGS5Z.js} +54 -54
- package/dist/chunk-FMFLGS5Z.js.map +1 -0
- package/dist/{chunk-FDAMS4PK.js → chunk-G2YQ57YO.js} +4 -4
- package/dist/{chunk-6U7F52DE.js → chunk-HFQQWAMS.js} +62 -62
- package/dist/{chunk-5W4ZLBEZ.js → chunk-HKPJPOW7.js} +2 -2
- package/dist/{chunk-JCBWCYEJ.js → chunk-IGWFKW4B.js} +2 -2
- package/dist/{chunk-AITCS2RC.js → chunk-IJ7HK452.js} +4 -4
- package/dist/{chunk-4WKA6I65.js → chunk-J3ZGPYXB.js} +1135 -311
- package/dist/chunk-J3ZGPYXB.js.map +1 -0
- package/dist/{chunk-D3LMYTBV.js → chunk-J7WZUL2K.js} +9 -9
- package/dist/{chunk-5W7CTZ2E.js → chunk-KQAFEZQX.js} +4 -4
- package/dist/{chunk-YNQBRLC5.js → chunk-LUQ443JP.js} +520 -2011
- package/dist/chunk-LUQ443JP.js.map +1 -0
- package/dist/{chunk-Z54EM5YZ.js → chunk-MAXVH44E.js} +7 -7
- package/dist/{chunk-WZFAPHIK.js → chunk-MU7ZHSZE.js} +2 -2
- package/dist/chunk-N5Z4EVOR.js +123 -0
- package/dist/chunk-N5Z4EVOR.js.map +1 -0
- package/dist/{chunk-AZ5BTEKX.js → chunk-NQUF7XKR.js} +2 -2
- package/dist/{chunk-W4FBGYGK.js → chunk-NRV4Y3PM.js} +1 -1
- package/dist/{chunk-62U4J2GN.js → chunk-ODGOP7P2.js} +2 -2
- package/dist/{chunk-QJAQNXWI.js → chunk-ONHRRJZM.js} +6 -6
- package/dist/{chunk-ACXPX4AG.js → chunk-OPBTPRGY.js} +2 -2
- package/dist/{chunk-XOZ4ALGB.js → chunk-QDTZ2HF7.js} +3 -3
- package/dist/{chunk-GBJ4RDFR.js → chunk-QIHIHZYC.js} +66 -91
- package/dist/chunk-QIHIHZYC.js.map +1 -0
- package/dist/{chunk-ZPSVBSOF.js → chunk-QMWFQBIL.js} +3 -3
- package/dist/{chunk-W5EG6LE3.js → chunk-THCPRMRF.js} +3 -3
- package/dist/{chunk-4A6YGWQN.js → chunk-TL4TO3EA.js} +115 -120
- package/dist/chunk-TL4TO3EA.js.map +1 -0
- package/dist/{chunk-VI2JQPNQ.js → chunk-U7QYBSQJ.js} +2 -2
- package/dist/chunk-ULARSG5Z.js +203 -0
- package/dist/chunk-ULARSG5Z.js.map +1 -0
- package/dist/{chunk-TH2LSRMG.js → chunk-UORKJ34C.js} +2 -2
- package/dist/{chunk-4Z4XNEWZ.js → chunk-VCD4PSK2.js} +56 -12
- package/dist/chunk-VCD4PSK2.js.map +1 -0
- package/dist/{chunk-K5GB36ME.js → chunk-VMZ56EE3.js} +2 -2
- package/dist/{chunk-HUHX2OCX.js → chunk-VVDPPDDF.js} +1 -1
- package/dist/chunk-VVDPPDDF.js.map +1 -0
- package/dist/{chunk-RMMVQQA6.js → chunk-WDISJRMG.js} +2 -2
- package/dist/{chunk-B6JDYXL7.js → chunk-WWUVONGW.js} +7 -1
- package/dist/chunk-WWUVONGW.js.map +1 -0
- package/dist/{chunk-UVYI6VIX.js → chunk-X7Y7WX73.js} +1 -1
- package/dist/{chunk-CVILPI77.js → chunk-XOQSEF7X.js} +6 -6
- package/dist/{chunk-RPW2NOU6.js → chunk-YIAA2X3D.js} +41 -1
- package/dist/chunk-YIAA2X3D.js.map +1 -0
- package/dist/chunk-YPC7W6GA.js +1604 -0
- package/dist/chunk-YPC7W6GA.js.map +1 -0
- package/dist/{chunk-YTQNQ4KB.js → chunk-YX5LN6JR.js} +3 -3
- package/dist/{chunk-IC6CBHCA.js → chunk-Z7XKUWYS.js} +2 -2
- package/dist/{chunk-PHWUFPCO.js → chunk-ZCPP5OW6.js} +61 -53
- package/dist/chunk-ZCPP5OW6.js.map +1 -0
- package/dist/{cli-C4GbETPC.d.ts → cli-DRJLv1Xt.d.ts} +5 -5
- package/dist/cli.d.ts +12 -12
- package/dist/cli.js +96 -86
- package/dist/compounding/engine.d.ts +2 -2
- package/dist/compounding/engine.js +14 -14
- 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 +2 -2
- package/dist/connectors/codex-materialize-runner.d.ts +1 -1
- package/dist/connectors/codex-materialize-runner.js +14 -15
- package/dist/connectors/codex-materialize.d.ts +1 -1
- package/dist/connectors/index.d.ts +3 -2
- package/dist/connectors/index.js +24 -23
- package/dist/consolidation-provenance-check.d.ts +2 -2
- package/dist/consolidation-provenance-check.js +5 -5
- package/dist/consolidation-undo.d.ts +2 -2
- package/dist/consolidation-undo.js +3 -3
- package/dist/contradiction/index.d.ts +2 -2
- package/dist/contradiction/index.js +4 -4
- package/dist/conversation-index/backend.d.ts +1 -1
- package/dist/conversation-index/backend.js +2 -2
- 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/corpus-watermark.d.ts +1 -1
- package/dist/corpus-watermark.js +26 -26
- package/dist/day-summary.d.ts +1 -1
- 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/enrichment/index.d.ts +1 -1
- package/dist/entity-retrieval.d.ts +2 -2
- package/dist/entity-retrieval.js +14 -14
- package/dist/entity-schema.d.ts +1 -1
- package/dist/explicit-capture.d.ts +8 -8
- package/dist/extraction-error-classification.d.ts +1 -1
- 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-liveness.d.ts +1 -1
- package/dist/extraction-source-grounding-rules.d.ts +1 -1
- package/dist/extraction-source-grounding.d.ts +15 -2
- package/dist/extraction-source-grounding.js +10 -1
- package/dist/extraction.d.ts +2 -15
- package/dist/extraction.js +5 -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/importance.d.ts +1 -1
- package/dist/importers/index.d.ts +1 -1
- package/dist/in-flight-reads.d.ts +1 -1
- package/dist/index.d.ts +19 -19
- package/dist/index.js +253 -246
- 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 +6 -6
- 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-helpers.d.ts +7 -0
- package/dist/local-llm-helpers.js +16 -0
- package/dist/local-llm-helpers.js.map +1 -0
- package/dist/local-llm.d.ts +3 -6
- package/dist/local-llm.js +2 -1
- package/dist/local-model-endpoint.d.ts +1 -1
- package/dist/maintenance/memory-governance.d.ts +1 -1
- package/dist/maintenance/memory-governance.js +14 -14
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +14 -14
- package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-projection.js +15 -15
- package/dist/{maintenance-CL30NWtc.d.ts → maintenance-C6Pffz30.d.ts} +3 -3
- package/dist/mcp-memory-inspector-app.d.ts +10 -10
- package/dist/memory-action-policy.d.ts +1 -1
- package/dist/memory-cache.d.ts +1 -1
- package/dist/memory-corpus-version.js +2 -2
- 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 +2 -2
- package/dist/models-json.d.ts +1 -1
- package/dist/namespaces/migrate.d.ts +3 -3
- package/dist/namespaces/migrate.js +24 -24
- package/dist/namespaces/principal.d.ts +1 -1
- package/dist/namespaces/search.d.ts +1 -1
- package/dist/namespaces/search.js +9 -9
- package/dist/namespaces/storage.d.ts +3 -3
- package/dist/namespaces/storage.js +14 -14
- package/dist/native-knowledge.d.ts +1 -1
- package/dist/offline-sync-impression-drain.d.ts +1 -1
- package/dist/offline-sync-impression-drain.js +6 -5
- package/dist/operator-doctor-corpus.d.ts +1 -1
- package/dist/operator-doctor-corpus.js +29 -29
- package/dist/operator-doctor-replica.d.ts +1 -1
- package/dist/operator-doctor-replica.js +3 -3
- package/dist/operator-toolkit.d.ts +3 -3
- package/dist/operator-toolkit.js +39 -38
- package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
- package/dist/orchestration/maintenance.d.ts +4 -4
- package/dist/orchestration/maintenance.js +22 -21
- package/dist/{orchestrator-CKTCRwWV.d.ts → orchestrator-eQlmasno.d.ts} +72 -34
- package/dist/orchestrator.d.ts +8 -8
- package/dist/orchestrator.js +169 -162
- package/dist/page-versioning.js +3 -3
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/{pipeline-B7wj4rRZ.d.ts → pipeline-CZGmAMQ2.d.ts} +1 -1
- package/dist/policy-runtime.d.ts +1 -1
- package/dist/proactive-contention.d.ts +1 -1
- package/dist/provenance.d.ts +1 -1
- package/dist/{qmd-q9tg4dHp.d.ts → qmd-DBj4MF8T.d.ts} +1 -1
- package/dist/qmd-preflight.d.ts +2 -2
- package/dist/qmd-recall-cache.d.ts +1 -1
- package/dist/qmd.d.ts +2 -2
- package/dist/qmd.js +4 -4
- package/dist/recall-concurrency-config.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-explain-renderer.js +3 -3
- package/dist/recall-memory-map.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-timings.d.ts +1 -1
- package/dist/recall-xray-cli.d.ts +1 -1
- package/dist/recall-xray-cli.js +4 -4
- package/dist/recall-xray-renderer.d.ts +1 -1
- package/dist/recall-xray-renderer.js +3 -3
- package/dist/recall-xray.d.ts +1 -1
- package/dist/recall-xray.js +2 -2
- package/dist/replay/normalizers/chatgpt.d.ts +1 -1
- package/dist/replay/normalizers/claude.d.ts +1 -1
- package/dist/replay/normalizers/openclaw.d.ts +1 -1
- package/dist/replay/normalizers/shared.d.ts +1 -1
- package/dist/replay/runner.d.ts +1 -1
- package/dist/replay/types.d.ts +1 -1
- package/dist/replica-divergence.d.ts +1 -1
- package/dist/replica-divergence.js +2 -2
- package/dist/replica-peers-config.d.ts +1 -1
- package/dist/resolve-auth-token.d.ts +1 -1
- package/dist/resume-bundles.js +2 -2
- package/dist/retrieval-agents.d.ts +2 -2
- 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/salvage-envelope.d.ts +1 -1
- package/dist/{scope-profiles-CWDyglPM.d.ts → scope-profiles-S85lrsUn.d.ts} +1 -1
- package/dist/search/embed-helper.d.ts +1 -1
- package/dist/search/factory.d.ts +1 -1
- package/dist/search/factory.js +8 -8
- package/dist/search/index.d.ts +1 -1
- package/dist/search/index.js +12 -12
- 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/{semantic-consolidation-BUE3deLn.d.ts → semantic-consolidation-DVzDcV6x.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +17 -18
- package/dist/semantic-rule-promotion.js +14 -14
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/semantic-rule-verifier.js +14 -14
- package/dist/{service-CXgM0bQG.d.ts → service-C2M-wD4W.d.ts} +2 -2
- 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/signal.d.ts +1 -1
- package/dist/{storage-DysJq-XH.d.ts → storage-dyBC3Q84.d.ts} +1 -1
- package/dist/storage.d.ts +2 -2
- package/dist/storage.js +13 -13
- package/dist/summarizer.d.ts +1 -1
- package/dist/summarizer.js +3 -2
- package/dist/summary-snapshot.d.ts +1 -1
- package/dist/temporal-supersession.d.ts +2 -2
- package/dist/temporal-timeline-recall.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 +2 -2
- package/dist/tier-routing.d.ts +1 -1
- package/dist/tokens.js +2 -2
- package/dist/topics.d.ts +1 -1
- package/dist/transcript.d.ts +1 -1
- package/dist/transfer/backup.js +2 -2
- package/dist/transfer/capsule-export.js +2 -2
- package/dist/transfer/capsule-import.js +5 -5
- package/dist/trust-score-stage.d.ts +1 -1
- package/dist/trust-score.d.ts +1 -1
- package/dist/{types-aPPzhnjT.d.ts → types-D63ZI--P.d.ts} +23 -2
- package/dist/types.d.ts +1 -1
- package/dist/types.js +1 -1
- package/dist/utility-runtime.d.ts +1 -1
- package/dist/verified-recall.js +14 -14
- package/dist/write-envelope.d.ts +1 -1
- package/package.json +2 -2
- package/src/access-boundary.ts +3 -0
- package/src/access-cli.test.ts +93 -0
- package/src/access-cli.ts +56 -2
- package/src/access-extraction-force-flush.ts +177 -0
- package/src/access-http-extraction-force-flush.test.ts +132 -0
- package/src/access-http-lcm-compaction.ts +99 -22
- package/src/access-http-lifecycle-flush.ts +81 -0
- package/src/access-http.test.ts +227 -0
- package/src/access-http.ts +33 -40
- package/src/access-mcp-output-schemas.ts +6 -0
- package/src/access-mcp.test.ts +40 -0
- package/src/access-mcp.ts +32 -1
- package/src/access-observe-helpers.ts +180 -0
- package/src/access-observe-write-surface.ts +78 -19
- package/src/access-operations-batch.ts +2 -1
- package/src/access-schema-pi.test.ts +17 -0
- package/src/access-schema.ts +28 -11
- package/src/access-service-helpers.ts +46 -0
- package/src/access-service-observe-lcm-parity.test.ts +781 -31
- package/src/access-service-observe-scope.test.ts +88 -0
- package/src/access-service.ts +46 -128
- package/src/access-surface-catalog.test.ts +32 -0
- package/src/access-surface-catalog.ts +2 -0
- package/src/buffer-session.test.ts +148 -0
- package/src/buffer-turn-helpers.ts +152 -0
- package/src/buffer.ts +126 -201
- package/src/connectors/index.ts +1 -1
- package/src/connectors/label.ts +18 -0
- package/src/correction/correction-access-wiring.ts +79 -27
- package/src/correction/correction-executor.test.ts +542 -1
- package/src/correction/correction-executor.ts +309 -89
- package/src/correction/correction-planner.test.ts +35 -1
- package/src/correction/correction-planner.ts +50 -3
- package/src/correction/correction-service.ts +12 -7
- package/src/correction/correction-storage-integration.test.ts +172 -1
- package/src/correction/passive-capture.test.ts +35 -0
- package/src/correction/passive-capture.ts +17 -3
- package/src/extraction-source-grounding.ts +55 -1
- package/src/extraction-timeout.test.ts +51 -0
- package/src/extraction.ts +64 -90
- package/src/local-llm-headers-timeout.test.ts +48 -0
- package/src/local-llm-helpers.ts +58 -0
- package/src/local-llm.ts +62 -58
- package/src/orchestration/extraction-run-helpers.ts +309 -0
- package/src/orchestration/extraction-run.test.ts +350 -7
- package/src/orchestration/extraction-run.ts +327 -250
- package/src/orchestration/recall-result-formatter.ts +21 -2
- package/src/orchestration/recall-search-pipeline.test.ts +34 -0
- package/src/orchestration/recall-search-pipeline.ts +9 -1
- package/src/orchestration/session-context.ts +193 -18
- package/src/orchestration/turn-ingestion.ts +61 -11
- package/src/orchestrator-flush.test.ts +511 -5
- package/src/orchestrator.ts +8 -6
- package/src/recall-source-connector-label.test.ts +300 -0
- package/src/types.ts +3 -3
- package/dist/chunk-3UXOZBHV.js +0 -20
- package/dist/chunk-3UXOZBHV.js.map +0 -1
- package/dist/chunk-4A6YGWQN.js.map +0 -1
- package/dist/chunk-4WKA6I65.js.map +0 -1
- package/dist/chunk-4Z4XNEWZ.js.map +0 -1
- package/dist/chunk-6FUPCJUL.js.map +0 -1
- package/dist/chunk-B6JDYXL7.js.map +0 -1
- package/dist/chunk-G5R3D5UP.js.map +0 -1
- package/dist/chunk-GBJ4RDFR.js.map +0 -1
- package/dist/chunk-HUHX2OCX.js.map +0 -1
- package/dist/chunk-IYZ5K7MU.js.map +0 -1
- package/dist/chunk-LGHKJABJ.js.map +0 -1
- package/dist/chunk-NHWB6HG2.js.map +0 -1
- package/dist/chunk-PHWUFPCO.js.map +0 -1
- package/dist/chunk-RPW2NOU6.js.map +0 -1
- package/dist/chunk-SPJXKAVF.js.map +0 -1
- package/dist/chunk-YNQBRLC5.js.map +0 -1
- package/dist/chunk-YTSNAUXN.js.map +0 -1
- /package/dist/{capsule-crypto-GWVG7LGC.js.map → access-extraction-force-flush.js.map} +0 -0
- /package/dist/{capsule-merge-5KKJQBWQ.js.map → capsule-merge-2H2IUTBT.js.map} +0 -0
- /package/dist/{chunk-LEPOP46W.js.map → chunk-227UFSEQ.js.map} +0 -0
- /package/dist/{chunk-I5NLEENJ.js.map → chunk-27HHNYSQ.js.map} +0 -0
- /package/dist/{chunk-2SA56WMI.js.map → chunk-2LTDWSR6.js.map} +0 -0
- /package/dist/{chunk-OWHERGF2.js.map → chunk-2NLLXCJG.js.map} +0 -0
- /package/dist/{chunk-P5PXWTW7.js.map → chunk-2Q4JJ3FZ.js.map} +0 -0
- /package/dist/{chunk-H5CPS5JP.js.map → chunk-35IVNNRK.js.map} +0 -0
- /package/dist/{chunk-LBOD4U5B.js.map → chunk-3EQ2XB3W.js.map} +0 -0
- /package/dist/{chunk-2EUVEDF5.js.map → chunk-5WZVQRHV.js.map} +0 -0
- /package/dist/{chunk-ALSGMEJR.js.map → chunk-65ZPVYTA.js.map} +0 -0
- /package/dist/{chunk-GIBMDSJ2.js.map → chunk-6P7MTSU5.js.map} +0 -0
- /package/dist/{chunk-5VQJBH2G.js.map → chunk-6TAUHL33.js.map} +0 -0
- /package/dist/{chunk-WVO4G37W.js.map → chunk-7TEZUUGM.js.map} +0 -0
- /package/dist/{chunk-MJCGLM25.js.map → chunk-7VUAG236.js.map} +0 -0
- /package/dist/{chunk-CZRYLSSW.js.map → chunk-AJL6NNX6.js.map} +0 -0
- /package/dist/{chunk-66772WBP.js.map → chunk-AQWVJURR.js.map} +0 -0
- /package/dist/{chunk-RKNJBZ55.js.map → chunk-AU7Q3LSC.js.map} +0 -0
- /package/dist/{chunk-M3C2V3PV.js.map → chunk-CJDNT45S.js.map} +0 -0
- /package/dist/{chunk-D2ANTDGO.js.map → chunk-E6BMSH7U.js.map} +0 -0
- /package/dist/{chunk-CKMO4RDY.js.map → chunk-EMDLM3LW.js.map} +0 -0
- /package/dist/{chunk-RGIWINDN.js.map → chunk-FHBITMRY.js.map} +0 -0
- /package/dist/{chunk-FDAMS4PK.js.map → chunk-G2YQ57YO.js.map} +0 -0
- /package/dist/{chunk-6U7F52DE.js.map → chunk-HFQQWAMS.js.map} +0 -0
- /package/dist/{chunk-5W4ZLBEZ.js.map → chunk-HKPJPOW7.js.map} +0 -0
- /package/dist/{chunk-JCBWCYEJ.js.map → chunk-IGWFKW4B.js.map} +0 -0
- /package/dist/{chunk-AITCS2RC.js.map → chunk-IJ7HK452.js.map} +0 -0
- /package/dist/{chunk-D3LMYTBV.js.map → chunk-J7WZUL2K.js.map} +0 -0
- /package/dist/{chunk-5W7CTZ2E.js.map → chunk-KQAFEZQX.js.map} +0 -0
- /package/dist/{chunk-Z54EM5YZ.js.map → chunk-MAXVH44E.js.map} +0 -0
- /package/dist/{chunk-WZFAPHIK.js.map → chunk-MU7ZHSZE.js.map} +0 -0
- /package/dist/{chunk-AZ5BTEKX.js.map → chunk-NQUF7XKR.js.map} +0 -0
- /package/dist/{chunk-W4FBGYGK.js.map → chunk-NRV4Y3PM.js.map} +0 -0
- /package/dist/{chunk-62U4J2GN.js.map → chunk-ODGOP7P2.js.map} +0 -0
- /package/dist/{chunk-QJAQNXWI.js.map → chunk-ONHRRJZM.js.map} +0 -0
- /package/dist/{chunk-ACXPX4AG.js.map → chunk-OPBTPRGY.js.map} +0 -0
- /package/dist/{chunk-XOZ4ALGB.js.map → chunk-QDTZ2HF7.js.map} +0 -0
- /package/dist/{chunk-ZPSVBSOF.js.map → chunk-QMWFQBIL.js.map} +0 -0
- /package/dist/{chunk-W5EG6LE3.js.map → chunk-THCPRMRF.js.map} +0 -0
- /package/dist/{chunk-VI2JQPNQ.js.map → chunk-U7QYBSQJ.js.map} +0 -0
- /package/dist/{chunk-TH2LSRMG.js.map → chunk-UORKJ34C.js.map} +0 -0
- /package/dist/{chunk-K5GB36ME.js.map → chunk-VMZ56EE3.js.map} +0 -0
- /package/dist/{chunk-RMMVQQA6.js.map → chunk-WDISJRMG.js.map} +0 -0
- /package/dist/{chunk-UVYI6VIX.js.map → chunk-X7Y7WX73.js.map} +0 -0
- /package/dist/{chunk-CVILPI77.js.map → chunk-XOQSEF7X.js.map} +0 -0
- /package/dist/{chunk-YTQNQ4KB.js.map → chunk-YX5LN6JR.js.map} +0 -0
- /package/dist/{chunk-IC6CBHCA.js.map → chunk-Z7XKUWYS.js.map} +0 -0
|
@@ -8,16 +8,13 @@ import {
|
|
|
8
8
|
} from "./chunk-GDB4J2H3.js";
|
|
9
9
|
import {
|
|
10
10
|
importCapsule
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-65ZPVYTA.js";
|
|
12
|
+
import {
|
|
13
|
+
CONNECTOR_ID_PATTERN
|
|
14
|
+
} from "./chunk-2QIMTVEJ.js";
|
|
12
15
|
import {
|
|
13
16
|
WriteQuarantineStore
|
|
14
17
|
} from "./chunk-PJSK6OJM.js";
|
|
15
|
-
import {
|
|
16
|
-
trustResultFor
|
|
17
|
-
} from "./chunk-GNVZQ5JN.js";
|
|
18
|
-
import {
|
|
19
|
-
renderEpistemicHedge
|
|
20
|
-
} from "./chunk-YN2UN7N3.js";
|
|
21
18
|
import {
|
|
22
19
|
getTrustZoneStoreStatus,
|
|
23
20
|
isTrustZoneName,
|
|
@@ -27,22 +24,28 @@ import {
|
|
|
27
24
|
seedTrustZoneDemoDataset,
|
|
28
25
|
summarizeTrustZonePromotionReadiness
|
|
29
26
|
} from "./chunk-JGSKJHF7.js";
|
|
27
|
+
import {
|
|
28
|
+
trustResultFor
|
|
29
|
+
} from "./chunk-GNVZQ5JN.js";
|
|
30
|
+
import {
|
|
31
|
+
renderEpistemicHedge
|
|
32
|
+
} from "./chunk-YN2UN7N3.js";
|
|
30
33
|
import {
|
|
31
34
|
planSessionTranscriptMigration
|
|
32
35
|
} from "./chunk-P5FPO2BR.js";
|
|
33
|
-
import {
|
|
34
|
-
boundRecallContextComposition,
|
|
35
|
-
composeRecallContext
|
|
36
|
-
} from "./chunk-AHVEHR6K.js";
|
|
37
36
|
import {
|
|
38
37
|
decideDisclosureEscalation
|
|
39
38
|
} from "./chunk-H7XKCNR6.js";
|
|
40
39
|
import {
|
|
41
40
|
toRecallExplainJson
|
|
42
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-VMZ56EE3.js";
|
|
43
42
|
import {
|
|
44
43
|
estimateRecallTokens
|
|
45
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-OPBTPRGY.js";
|
|
45
|
+
import {
|
|
46
|
+
boundRecallContextComposition,
|
|
47
|
+
composeRecallContext
|
|
48
|
+
} from "./chunk-AHVEHR6K.js";
|
|
46
49
|
import {
|
|
47
50
|
buildProposedActions,
|
|
48
51
|
buildQualityScore,
|
|
@@ -50,10 +53,7 @@ import {
|
|
|
50
53
|
listMemoryGovernanceRuns,
|
|
51
54
|
readMemoryGovernanceRunArtifact,
|
|
52
55
|
runMemoryGovernance
|
|
53
|
-
} from "./chunk-
|
|
54
|
-
import {
|
|
55
|
-
ReplicaDivergenceMonitor
|
|
56
|
-
} from "./chunk-CVILPI77.js";
|
|
56
|
+
} from "./chunk-THCPRMRF.js";
|
|
57
57
|
import {
|
|
58
58
|
recordObjectiveStateSnapshotsFromObservedMessages
|
|
59
59
|
} from "./chunk-ICP53SKG.js";
|
|
@@ -62,21 +62,15 @@ import {
|
|
|
62
62
|
} from "./chunk-6HMYUWXR.js";
|
|
63
63
|
import {
|
|
64
64
|
offlineSyncStorageForSnapshot
|
|
65
|
-
} from "./chunk-
|
|
65
|
+
} from "./chunk-7TEZUUGM.js";
|
|
66
66
|
import {
|
|
67
|
-
combineNamespaces,
|
|
68
|
-
defaultGitInvoker,
|
|
69
|
-
expandScopeProfileReadNamespaces,
|
|
70
|
-
lcmSessionKeyForNamespace,
|
|
71
|
-
projectTagProjectId,
|
|
72
|
-
resolveCodingNamespaceOverlay,
|
|
73
|
-
resolveGitContext,
|
|
74
67
|
resolveScopePlan,
|
|
75
|
-
resolveScopeProfilePlan,
|
|
76
68
|
resolveScopedWritableNamespaceValue,
|
|
77
|
-
resolveWritableNamespaceValue
|
|
78
|
-
|
|
79
|
-
|
|
69
|
+
resolveWritableNamespaceValue
|
|
70
|
+
} from "./chunk-ULARSG5Z.js";
|
|
71
|
+
import {
|
|
72
|
+
ReplicaDivergenceMonitor
|
|
73
|
+
} from "./chunk-XOQSEF7X.js";
|
|
80
74
|
import {
|
|
81
75
|
recordMemoryOutcome
|
|
82
76
|
} from "./chunk-EIR5VLIH.js";
|
|
@@ -104,34 +98,55 @@ import {
|
|
|
104
98
|
import {
|
|
105
99
|
CorpusWatermarkCache,
|
|
106
100
|
computeServiceCorpusCensus
|
|
107
|
-
} from "./chunk-
|
|
101
|
+
} from "./chunk-6P7MTSU5.js";
|
|
108
102
|
import {
|
|
109
103
|
namespaceCollectionName
|
|
110
|
-
} from "./chunk-
|
|
104
|
+
} from "./chunk-E6BMSH7U.js";
|
|
111
105
|
import {
|
|
112
106
|
CrossNamespaceBudget,
|
|
113
107
|
toBudgetWarning
|
|
114
108
|
} from "./chunk-UFGFMWAD.js";
|
|
109
|
+
import {
|
|
110
|
+
ExtractionDeadlineError
|
|
111
|
+
} from "./chunk-YPC7W6GA.js";
|
|
112
|
+
import {
|
|
113
|
+
combineNamespaces,
|
|
114
|
+
defaultGitInvoker,
|
|
115
|
+
expandScopeProfileReadNamespaces,
|
|
116
|
+
lcmSessionKeyForNamespace,
|
|
117
|
+
projectTagProjectId,
|
|
118
|
+
resolveCodingNamespaceOverlay,
|
|
119
|
+
resolveGitContext,
|
|
120
|
+
resolveScopeProfilePlan,
|
|
121
|
+
sanitizeFragment
|
|
122
|
+
} from "./chunk-BUE5E2HL.js";
|
|
123
|
+
import {
|
|
124
|
+
defaultCapsulesDir
|
|
125
|
+
} from "./chunk-ZY2MNJR6.js";
|
|
126
|
+
import {
|
|
127
|
+
filterTrajectoriesByLookbackDays,
|
|
128
|
+
readCausalTrajectoryRecords
|
|
129
|
+
} from "./chunk-NRV4Y3PM.js";
|
|
115
130
|
import {
|
|
116
131
|
FileCalendarSource,
|
|
117
132
|
buildBriefing,
|
|
118
133
|
enqueuePassiveCorrectionNotification,
|
|
119
134
|
parseBriefingFocus,
|
|
120
135
|
parseBriefingWindow
|
|
121
|
-
} from "./chunk-
|
|
136
|
+
} from "./chunk-AJL6NNX6.js";
|
|
122
137
|
import {
|
|
123
138
|
parseEntityFile,
|
|
124
139
|
qmdCollectionPathParts,
|
|
125
140
|
qmdResultPathCandidates,
|
|
126
141
|
selfDeps
|
|
127
|
-
} from "./chunk-
|
|
142
|
+
} from "./chunk-FHBITMRY.js";
|
|
128
143
|
import {
|
|
129
144
|
supersessionKeysForFact
|
|
130
145
|
} from "./chunk-DNHVPZOD.js";
|
|
131
146
|
import {
|
|
132
147
|
DEFAULT_RECALL_DISCLOSURE,
|
|
133
148
|
isRecallDisclosure
|
|
134
|
-
} from "./chunk-
|
|
149
|
+
} from "./chunk-VVDPPDDF.js";
|
|
135
150
|
import {
|
|
136
151
|
namespaceIdentityFromToken
|
|
137
152
|
} from "./chunk-EGGE52UU.js";
|
|
@@ -169,17 +184,27 @@ import {
|
|
|
169
184
|
} from "./chunk-BT7NVCML.js";
|
|
170
185
|
import {
|
|
171
186
|
createVersion
|
|
172
|
-
} from "./chunk-
|
|
187
|
+
} from "./chunk-6TAUHL33.js";
|
|
173
188
|
import {
|
|
174
189
|
computeContentHash
|
|
175
190
|
} from "./chunk-W5H6ZRPT.js";
|
|
176
191
|
import {
|
|
177
|
-
|
|
178
|
-
|
|
192
|
+
assertOperationAuthorizationAllowed,
|
|
193
|
+
capabilityAllowsOp,
|
|
194
|
+
enforceNamespaceAllowList,
|
|
195
|
+
isNamespaceAllowed,
|
|
196
|
+
tokenCapabilityStore
|
|
197
|
+
} from "./chunk-MZWSOLMT.js";
|
|
179
198
|
import {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
199
|
+
meetingsBuild,
|
|
200
|
+
meetingsGet,
|
|
201
|
+
meetingsList,
|
|
202
|
+
wearablesStatus,
|
|
203
|
+
wearablesSync,
|
|
204
|
+
wearablesTranscriptDay,
|
|
205
|
+
wearablesTranscriptMemories,
|
|
206
|
+
wearablesTranscriptSearch
|
|
207
|
+
} from "./chunk-SYOIVK7K.js";
|
|
183
208
|
import {
|
|
184
209
|
ExtractionLivenessWarnThrottle,
|
|
185
210
|
computeExtractionLivenessStatus
|
|
@@ -196,7 +221,7 @@ import {
|
|
|
196
221
|
} from "./chunk-JAKIDQB2.js";
|
|
197
222
|
import {
|
|
198
223
|
exportCapsule
|
|
199
|
-
} from "./chunk-
|
|
224
|
+
} from "./chunk-KQAFEZQX.js";
|
|
200
225
|
import {
|
|
201
226
|
evaluateActionConfidence
|
|
202
227
|
} from "./chunk-Z2YFLXHU.js";
|
|
@@ -212,22 +237,8 @@ import {
|
|
|
212
237
|
readOfflineSyncFileContentChunk
|
|
213
238
|
} from "./chunk-7XC2HX75.js";
|
|
214
239
|
import {
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
enforceNamespaceAllowList,
|
|
218
|
-
isNamespaceAllowed,
|
|
219
|
-
tokenCapabilityStore
|
|
220
|
-
} from "./chunk-MZWSOLMT.js";
|
|
221
|
-
import {
|
|
222
|
-
meetingsBuild,
|
|
223
|
-
meetingsGet,
|
|
224
|
-
meetingsList,
|
|
225
|
-
wearablesStatus,
|
|
226
|
-
wearablesSync,
|
|
227
|
-
wearablesTranscriptDay,
|
|
228
|
-
wearablesTranscriptMemories,
|
|
229
|
-
wearablesTranscriptSearch
|
|
230
|
-
} from "./chunk-SYOIVK7K.js";
|
|
240
|
+
delegateExtractionForceFlush
|
|
241
|
+
} from "./chunk-3QL24R5Y.js";
|
|
231
242
|
import {
|
|
232
243
|
defaultNamespaceAtFlatRoot,
|
|
233
244
|
mergeMemorySearchDefaultFallback,
|
|
@@ -257,6 +268,10 @@ import {
|
|
|
257
268
|
resolveRecallEnhancementCapabilities,
|
|
258
269
|
resolveSecurityCapabilities
|
|
259
270
|
} from "./chunk-2XRE6FLM.js";
|
|
271
|
+
import {
|
|
272
|
+
PendingObserveExtractionTracker,
|
|
273
|
+
pendingObserveScopeHint
|
|
274
|
+
} from "./chunk-N5Z4EVOR.js";
|
|
260
275
|
import {
|
|
261
276
|
EngramAccessForbiddenError,
|
|
262
277
|
EngramAccessInputError,
|
|
@@ -268,6 +283,7 @@ import {
|
|
|
268
283
|
} from "./chunk-VFUEZZBS.js";
|
|
269
284
|
import {
|
|
270
285
|
abortError,
|
|
286
|
+
isAbortError,
|
|
271
287
|
throwIfAborted
|
|
272
288
|
} from "./chunk-PVGDJXVK.js";
|
|
273
289
|
import {
|
|
@@ -2853,7 +2869,9 @@ var CorrectionPlanner = class _CorrectionPlanner {
|
|
|
2853
2869
|
* Plan a correction. `readableNamespaces` is the AUTHORIZED read scope the
|
|
2854
2870
|
* service resolved for this caller; the planner never trusts a caller string.
|
|
2855
2871
|
*/
|
|
2856
|
-
async plan(request, readableNamespaces) {
|
|
2872
|
+
async plan(request, readableNamespaces, opts) {
|
|
2873
|
+
const abortSignal = opts?.abortSignal;
|
|
2874
|
+
throwIfAborted(abortSignal, "correction planning aborted");
|
|
2857
2875
|
const cleaned = validateCorrectionRequest(request);
|
|
2858
2876
|
if (cleaned.text.length > CORRECTION_TEXT_MAX) {
|
|
2859
2877
|
throw new CorrectionContractError("CorrectionRequest.text too long.");
|
|
@@ -2869,16 +2887,19 @@ var CorrectionPlanner = class _CorrectionPlanner {
|
|
|
2869
2887
|
"Correction requires at least one readable namespace \u2014 principal has no read scope."
|
|
2870
2888
|
);
|
|
2871
2889
|
}
|
|
2872
|
-
const located = await this.locateCandidates(cleaned, namespaces);
|
|
2890
|
+
const located = await this.locateCandidates(cleaned, namespaces, abortSignal);
|
|
2891
|
+
throwIfAborted(abortSignal, "correction planning aborted");
|
|
2873
2892
|
if (located.candidates.length === 0) {
|
|
2874
2893
|
return this.persist(
|
|
2875
|
-
this.emptyPlan(cleaned, namespaces[0], "no matching memories found for the correction text")
|
|
2894
|
+
this.emptyPlan(cleaned, namespaces[0], "no matching memories found for the correction text"),
|
|
2895
|
+
abortSignal
|
|
2876
2896
|
);
|
|
2877
2897
|
}
|
|
2878
2898
|
const llm = await this.deps.classifyAndDraft({
|
|
2879
2899
|
text: cleaned.text,
|
|
2880
2900
|
candidates: located.candidates
|
|
2881
2901
|
});
|
|
2902
|
+
throwIfAborted(abortSignal, "correction planning aborted");
|
|
2882
2903
|
for (const action of llm.actions) {
|
|
2883
2904
|
validateCorrectionAction(action);
|
|
2884
2905
|
if (action.kind === "redaction_rule") {
|
|
@@ -2909,6 +2930,7 @@ var CorrectionPlanner = class _CorrectionPlanner {
|
|
|
2909
2930
|
}
|
|
2910
2931
|
}
|
|
2911
2932
|
const diff = llm.fallback ? "" : await this.deps.renderDiff({ candidates: located.candidates, actions: llm.actions });
|
|
2933
|
+
throwIfAborted(abortSignal, "correction planning aborted");
|
|
2912
2934
|
const createdAt = this.deps.now().toISOString();
|
|
2913
2935
|
const expiresAt = new Date(
|
|
2914
2936
|
this.deps.now().getTime() + this.deps.planTtlHours * 60 * 60 * 1e3
|
|
@@ -2934,20 +2956,23 @@ var CorrectionPlanner = class _CorrectionPlanner {
|
|
|
2934
2956
|
expiresAt,
|
|
2935
2957
|
status: "pending"
|
|
2936
2958
|
};
|
|
2937
|
-
|
|
2959
|
+
throwIfAborted(abortSignal, "correction planning aborted");
|
|
2960
|
+
return this.persist(plan, abortSignal);
|
|
2938
2961
|
}
|
|
2939
|
-
async locateCandidates(request, namespaces) {
|
|
2962
|
+
async locateCandidates(request, namespaces, abortSignal) {
|
|
2940
2963
|
if (request.targetIds && request.targetIds.length > 0) {
|
|
2941
2964
|
const targets = await this.deps.resolveTargets({
|
|
2942
2965
|
targetIds: request.targetIds,
|
|
2943
2966
|
namespaces
|
|
2944
2967
|
});
|
|
2968
|
+
throwIfAborted(abortSignal, "correction planning aborted");
|
|
2945
2969
|
const seedIds2 = targets.map((c) => c.memoryId);
|
|
2946
2970
|
const neighbors2 = await this.deps.expandNeighbors({
|
|
2947
2971
|
seedIds: seedIds2,
|
|
2948
2972
|
namespaces,
|
|
2949
2973
|
limit: this.deps.maxAffected
|
|
2950
2974
|
});
|
|
2975
|
+
throwIfAborted(abortSignal, "correction planning aborted");
|
|
2951
2976
|
return { candidates: mergeCandidates(targets, neighbors2).slice(0, this.deps.maxAffected) };
|
|
2952
2977
|
}
|
|
2953
2978
|
const searched = await this.deps.searchCorpus({
|
|
@@ -2955,6 +2980,7 @@ var CorrectionPlanner = class _CorrectionPlanner {
|
|
|
2955
2980
|
namespaces,
|
|
2956
2981
|
limit: this.deps.maxAffected
|
|
2957
2982
|
});
|
|
2983
|
+
throwIfAborted(abortSignal, "correction planning aborted");
|
|
2958
2984
|
if (searched.length === 0) return { candidates: [] };
|
|
2959
2985
|
const seedIds = searched.slice(0, Math.min(5, searched.length)).map((c) => c.memoryId);
|
|
2960
2986
|
const neighbors = await this.deps.expandNeighbors({
|
|
@@ -2962,6 +2988,7 @@ var CorrectionPlanner = class _CorrectionPlanner {
|
|
|
2962
2988
|
namespaces,
|
|
2963
2989
|
limit: this.deps.maxAffected
|
|
2964
2990
|
});
|
|
2991
|
+
throwIfAborted(abortSignal, "correction planning aborted");
|
|
2965
2992
|
return { candidates: mergeCandidates(searched, neighbors).slice(0, this.deps.maxAffected) };
|
|
2966
2993
|
}
|
|
2967
2994
|
deriveAffected(candidates, llm) {
|
|
@@ -3024,16 +3051,21 @@ var CorrectionPlanner = class _CorrectionPlanner {
|
|
|
3024
3051
|
async pendingDir(namespace) {
|
|
3025
3052
|
return path4.join(await this.deps.storageDir(namespace), "state", "corrections", "pending");
|
|
3026
3053
|
}
|
|
3027
|
-
async persist(plan) {
|
|
3054
|
+
async persist(plan, abortSignal) {
|
|
3055
|
+
throwIfAborted(abortSignal, "correction planning aborted");
|
|
3028
3056
|
const dir = await this.pendingDir(plan.namespace);
|
|
3057
|
+
throwIfAborted(abortSignal, "correction planning aborted");
|
|
3029
3058
|
const target = path4.join(dir, `${plan.planId}.json`);
|
|
3030
3059
|
const sensitive = plan.classification === "never_store" || plan.actions.some((a) => a.kind === "redaction_rule");
|
|
3031
3060
|
const persistedPlan = sensitive ? { ...plan, request: { ...plan.request, text: REDACTED_REQUEST_TEXT } } : plan;
|
|
3032
3061
|
await serializeMutations(`correction-plan:${target}`, async () => {
|
|
3062
|
+
throwIfAborted(abortSignal, "correction planning aborted");
|
|
3033
3063
|
await mkdir2(dir, { recursive: true });
|
|
3034
3064
|
const tmp = `${target}.${process.pid}.${Date.now().toString(36)}.tmp`;
|
|
3065
|
+
throwIfAborted(abortSignal, "correction planning aborted");
|
|
3035
3066
|
await writeFile2(tmp, `${JSON.stringify(persistedPlan)}
|
|
3036
3067
|
`, "utf-8");
|
|
3068
|
+
throwIfAborted(abortSignal, "correction planning aborted");
|
|
3037
3069
|
await rename2(tmp, target);
|
|
3038
3070
|
});
|
|
3039
3071
|
return plan;
|
|
@@ -3106,6 +3138,32 @@ var CorrectionPlanner = class _CorrectionPlanner {
|
|
|
3106
3138
|
}
|
|
3107
3139
|
const tmp = `${file}.${process.pid}.${Date.now().toString(36)}.tmp`;
|
|
3108
3140
|
await writeFile2(tmp, `${JSON.stringify(plan)}
|
|
3141
|
+
`, "utf-8");
|
|
3142
|
+
await rename2(tmp, file);
|
|
3143
|
+
});
|
|
3144
|
+
}
|
|
3145
|
+
/**
|
|
3146
|
+
* Return an applying plan to the pending queue when cancellation arrives
|
|
3147
|
+
* before its first correction mutation.
|
|
3148
|
+
*/
|
|
3149
|
+
async resetApplying(namespace, planId) {
|
|
3150
|
+
assertSafePlanId(planId);
|
|
3151
|
+
const file = path4.join(await this.pendingDir(namespace), `${planId}.json`);
|
|
3152
|
+
await serializeMutations(`correction-plan:${file}`, async () => {
|
|
3153
|
+
let raw;
|
|
3154
|
+
try {
|
|
3155
|
+
raw = await readFile4(file, "utf-8");
|
|
3156
|
+
} catch (err) {
|
|
3157
|
+
const code = err?.code;
|
|
3158
|
+
if (code === "ENOENT") return;
|
|
3159
|
+
throw err;
|
|
3160
|
+
}
|
|
3161
|
+
const plan = parsePlan(raw);
|
|
3162
|
+
if (!plan || plan.status !== "applying") return;
|
|
3163
|
+
plan.status = "pending";
|
|
3164
|
+
delete plan.applyingAt;
|
|
3165
|
+
const tmp = `${file}.${process.pid}.${Date.now().toString(36)}.tmp`;
|
|
3166
|
+
await writeFile2(tmp, `${JSON.stringify(plan)}
|
|
3109
3167
|
`, "utf-8");
|
|
3110
3168
|
await rename2(tmp, file);
|
|
3111
3169
|
});
|
|
@@ -3234,6 +3292,7 @@ var CorrectionExecutor = class {
|
|
|
3234
3292
|
* plan is rejected. Returns the {@link CorrectionOutcome}.
|
|
3235
3293
|
*/
|
|
3236
3294
|
async apply(namespace, planId, opts) {
|
|
3295
|
+
throwIfAborted(opts.abortSignal, "correction apply aborted");
|
|
3237
3296
|
if (!opts.confirm) {
|
|
3238
3297
|
throw new CorrectionContractError(
|
|
3239
3298
|
"Correction apply requires explicit confirmation (correction.applyRequiresConfirm)."
|
|
@@ -3241,11 +3300,13 @@ var CorrectionExecutor = class {
|
|
|
3241
3300
|
}
|
|
3242
3301
|
return serializeMutations(
|
|
3243
3302
|
`correction-apply:${namespace}:${planId}`,
|
|
3244
|
-
() => this.applyInternal(namespace, planId, opts.canWriteDestination)
|
|
3303
|
+
() => this.applyInternal(namespace, planId, opts.canWriteDestination, opts.abortSignal)
|
|
3245
3304
|
);
|
|
3246
3305
|
}
|
|
3247
|
-
async applyInternal(namespace, planId, canWriteDestination) {
|
|
3306
|
+
async applyInternal(namespace, planId, canWriteDestination, abortSignal) {
|
|
3307
|
+
throwIfAborted(abortSignal, "correction apply aborted");
|
|
3248
3308
|
const plan = await this.planner.loadPlan(namespace, planId);
|
|
3309
|
+
throwIfAborted(abortSignal, "correction apply aborted");
|
|
3249
3310
|
if (!plan) {
|
|
3250
3311
|
throw new CorrectionContractError(`Correction plan not found: ${planId}`);
|
|
3251
3312
|
}
|
|
@@ -3274,6 +3335,7 @@ var CorrectionExecutor = class {
|
|
|
3274
3335
|
validateRedactionPattern(action.pattern);
|
|
3275
3336
|
}
|
|
3276
3337
|
}
|
|
3338
|
+
throwIfAborted(abortSignal, "correction apply aborted");
|
|
3277
3339
|
try {
|
|
3278
3340
|
await this.planner.markConsumed(namespace, planId, "applying");
|
|
3279
3341
|
} catch {
|
|
@@ -3281,11 +3343,79 @@ var CorrectionExecutor = class {
|
|
|
3281
3343
|
`Correction plan ${planId}: cannot mark in-progress (filesystem unwritable?) \u2014 aborting before any mutation.`
|
|
3282
3344
|
);
|
|
3283
3345
|
}
|
|
3346
|
+
const resetApplying = async () => {
|
|
3347
|
+
try {
|
|
3348
|
+
await this.planner.resetApplying(namespace, planId);
|
|
3349
|
+
} catch (resetError) {
|
|
3350
|
+
log.warn(
|
|
3351
|
+
`Correction plan ${planId}: cancellation reset failed; leaving plan applying: ${resetError instanceof Error ? resetError.message : String(resetError)}`
|
|
3352
|
+
);
|
|
3353
|
+
}
|
|
3354
|
+
};
|
|
3355
|
+
try {
|
|
3356
|
+
throwIfAborted(abortSignal, "correction apply aborted");
|
|
3357
|
+
} catch (error) {
|
|
3358
|
+
await resetApplying();
|
|
3359
|
+
throw error;
|
|
3360
|
+
}
|
|
3284
3361
|
const results = [];
|
|
3285
3362
|
const appliedTouched = [];
|
|
3363
|
+
const retiredReplacementActions = /* @__PURE__ */ new Set();
|
|
3364
|
+
const removeFailedResultsFor = (action) => {
|
|
3365
|
+
for (let i = results.length - 1; i >= 0; i -= 1) {
|
|
3366
|
+
if (results[i]?.action === action && results[i]?.status === "failed") {
|
|
3367
|
+
results.splice(i, 1);
|
|
3368
|
+
}
|
|
3369
|
+
}
|
|
3370
|
+
};
|
|
3371
|
+
let mutationCommitted = false;
|
|
3372
|
+
let cancellationSafeAfterCommit = false;
|
|
3373
|
+
let cancellationRequestedAfterCommit = false;
|
|
3374
|
+
const throwIfAbortedBeforeCommit = () => {
|
|
3375
|
+
if (!mutationCommitted || !cancellationSafeAfterCommit) {
|
|
3376
|
+
throwIfAborted(abortSignal, "correction apply aborted");
|
|
3377
|
+
}
|
|
3378
|
+
};
|
|
3379
|
+
const stopBeforeNewAction = async () => {
|
|
3380
|
+
if (!abortSignal?.aborted) return false;
|
|
3381
|
+
if (!mutationCommitted) {
|
|
3382
|
+
try {
|
|
3383
|
+
throwIfAborted(abortSignal, "correction apply aborted");
|
|
3384
|
+
} catch (error) {
|
|
3385
|
+
await resetApplying();
|
|
3386
|
+
throw error;
|
|
3387
|
+
}
|
|
3388
|
+
}
|
|
3389
|
+
cancellationRequestedAfterCommit = true;
|
|
3390
|
+
return true;
|
|
3391
|
+
};
|
|
3392
|
+
const throwIfAbortedBeforeCommitAndReset = async () => {
|
|
3393
|
+
try {
|
|
3394
|
+
throwIfAbortedBeforeCommit();
|
|
3395
|
+
} catch (error) {
|
|
3396
|
+
if (!mutationCommitted) await resetApplying();
|
|
3397
|
+
const reason = abortSignal?.reason;
|
|
3398
|
+
if (reason instanceof Error && reason.name !== "AbortError") throw reason;
|
|
3399
|
+
throw error;
|
|
3400
|
+
}
|
|
3401
|
+
};
|
|
3286
3402
|
for (const action of plan.actions) {
|
|
3403
|
+
if (await stopBeforeNewAction()) break;
|
|
3287
3404
|
if (action.kind === "supersede" && action.replacement) {
|
|
3288
|
-
|
|
3405
|
+
let loser;
|
|
3406
|
+
try {
|
|
3407
|
+
loser = await this.deps.getMemory(namespace, action.loserId, abortSignal);
|
|
3408
|
+
} catch (error) {
|
|
3409
|
+
if (abortSignal?.aborted) {
|
|
3410
|
+
if (!mutationCommitted) {
|
|
3411
|
+
await resetApplying();
|
|
3412
|
+
throwIfAborted(abortSignal, "correction apply aborted");
|
|
3413
|
+
}
|
|
3414
|
+
cancellationRequestedAfterCommit = true;
|
|
3415
|
+
break;
|
|
3416
|
+
}
|
|
3417
|
+
throw error;
|
|
3418
|
+
}
|
|
3289
3419
|
if (!loser) {
|
|
3290
3420
|
results.push({
|
|
3291
3421
|
action,
|
|
@@ -3295,20 +3425,42 @@ var CorrectionExecutor = class {
|
|
|
3295
3425
|
continue;
|
|
3296
3426
|
}
|
|
3297
3427
|
try {
|
|
3298
|
-
const newId = await this.deps.writeReplacement(
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
|
|
3428
|
+
const newId = await this.deps.writeReplacement(
|
|
3429
|
+
namespace,
|
|
3430
|
+
{
|
|
3431
|
+
content: action.replacement.content,
|
|
3432
|
+
...action.replacement.category ? { category: action.replacement.category } : {},
|
|
3433
|
+
...action.replacement.confidence !== void 0 ? { confidence: action.replacement.confidence } : {},
|
|
3434
|
+
...action.replacement.tags ? { tags: action.replacement.tags } : {},
|
|
3435
|
+
...action.replacement.entityRef ? { entityRef: action.replacement.entityRef } : {},
|
|
3436
|
+
...action.replacement.validAt ? { validAt: action.replacement.validAt } : {},
|
|
3437
|
+
...action.replacement.observedAt ? { observedAt: action.replacement.observedAt } : {},
|
|
3438
|
+
...action.replacement.structuredAttributes ? { structuredAttributes: action.replacement.structuredAttributes } : {},
|
|
3439
|
+
supersedes: action.loserId
|
|
3440
|
+
},
|
|
3441
|
+
abortSignal
|
|
3442
|
+
);
|
|
3443
|
+
mutationCommitted = true;
|
|
3309
3444
|
results.push({ action, status: "applied", memoryId: newId });
|
|
3310
3445
|
appliedTouched.push(newId);
|
|
3446
|
+
const retirementResultBeforePhase2 = results.at(-1);
|
|
3447
|
+
await this.retireAndTombstone(namespace, action, "supersession", results, appliedTouched, {
|
|
3448
|
+
supersededBy: newId
|
|
3449
|
+
});
|
|
3450
|
+
const retirementResult = results.at(-1);
|
|
3451
|
+
if (retirementResult !== retirementResultBeforePhase2 && retirementResult?.action === action && retirementResult.status === "applied") {
|
|
3452
|
+
retiredReplacementActions.add(action);
|
|
3453
|
+
cancellationSafeAfterCommit = true;
|
|
3454
|
+
}
|
|
3311
3455
|
} catch (err) {
|
|
3456
|
+
if (abortSignal?.aborted) {
|
|
3457
|
+
if (!mutationCommitted) {
|
|
3458
|
+
await resetApplying();
|
|
3459
|
+
throw err;
|
|
3460
|
+
}
|
|
3461
|
+
cancellationRequestedAfterCommit = true;
|
|
3462
|
+
break;
|
|
3463
|
+
}
|
|
3312
3464
|
results.push({
|
|
3313
3465
|
action,
|
|
3314
3466
|
status: "failed",
|
|
@@ -3317,67 +3469,152 @@ var CorrectionExecutor = class {
|
|
|
3317
3469
|
}
|
|
3318
3470
|
} else if (action.kind === "edit") {
|
|
3319
3471
|
try {
|
|
3320
|
-
const editedId = await this.deps.applyEdit(
|
|
3472
|
+
const editedId = await this.deps.applyEdit(
|
|
3473
|
+
namespace,
|
|
3474
|
+
action.memoryId,
|
|
3475
|
+
action.patch,
|
|
3476
|
+
abortSignal
|
|
3477
|
+
);
|
|
3478
|
+
mutationCommitted = true;
|
|
3479
|
+
cancellationSafeAfterCommit = true;
|
|
3321
3480
|
results.push({ action, status: "applied", memoryId: editedId });
|
|
3322
3481
|
appliedTouched.push(editedId);
|
|
3323
3482
|
} catch (err) {
|
|
3483
|
+
if (abortSignal?.aborted) {
|
|
3484
|
+
if (!mutationCommitted) {
|
|
3485
|
+
await resetApplying();
|
|
3486
|
+
throw err;
|
|
3487
|
+
}
|
|
3488
|
+
cancellationRequestedAfterCommit = true;
|
|
3489
|
+
break;
|
|
3490
|
+
}
|
|
3324
3491
|
results.push({ action, status: "failed", error: errMsg(err) });
|
|
3325
3492
|
}
|
|
3326
3493
|
} else if (action.kind === "redaction_rule") {
|
|
3327
3494
|
try {
|
|
3328
|
-
await this.deps.registerRedactionRule(
|
|
3495
|
+
await this.deps.registerRedactionRule(
|
|
3496
|
+
namespace,
|
|
3497
|
+
action.pattern,
|
|
3498
|
+
abortSignal
|
|
3499
|
+
);
|
|
3500
|
+
mutationCommitted = true;
|
|
3501
|
+
cancellationSafeAfterCommit = true;
|
|
3329
3502
|
results.push({ action, status: "applied" });
|
|
3330
3503
|
} catch (err) {
|
|
3504
|
+
if (abortSignal?.aborted) {
|
|
3505
|
+
if (!mutationCommitted) {
|
|
3506
|
+
await resetApplying();
|
|
3507
|
+
throw err;
|
|
3508
|
+
}
|
|
3509
|
+
cancellationRequestedAfterCommit = true;
|
|
3510
|
+
break;
|
|
3511
|
+
}
|
|
3331
3512
|
results.push({ action, status: "failed", error: errMsg(err) });
|
|
3332
3513
|
}
|
|
3333
3514
|
}
|
|
3334
3515
|
}
|
|
3335
3516
|
for (const action of plan.actions) {
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
|
|
3339
|
-
);
|
|
3340
|
-
if (action.
|
|
3341
|
-
|
|
3342
|
-
|
|
3343
|
-
await this.retireAndTombstone(namespace, action, "supersession", results, appliedTouched, {
|
|
3344
|
-
supersededBy: replacementResult?.memoryId
|
|
3345
|
-
});
|
|
3346
|
-
} else if (action.kind === "retract") {
|
|
3347
|
-
await this.retireAndTombstone(namespace, action, "retraction", results, appliedTouched);
|
|
3348
|
-
} else if (action.kind === "rescope") {
|
|
3349
|
-
try {
|
|
3350
|
-
const allowed = canWriteDestination ? await canWriteDestination(action.toNamespace) : true;
|
|
3351
|
-
if (!allowed) {
|
|
3352
|
-
results.push({
|
|
3353
|
-
action,
|
|
3354
|
-
status: "failed",
|
|
3355
|
-
error: `rescope destination namespace not writable: ${action.toNamespace}`
|
|
3356
|
-
});
|
|
3517
|
+
const needsPhase2Work = action.kind === "retract" || action.kind === "rescope" || action.kind === "supersede" && !retiredReplacementActions.has(action);
|
|
3518
|
+
if (needsPhase2Work && await stopBeforeNewAction()) break;
|
|
3519
|
+
try {
|
|
3520
|
+
if (action.kind === "supersede" && retiredReplacementActions.has(action)) continue;
|
|
3521
|
+
if (action.kind === "supersede") {
|
|
3522
|
+
const replacementResult = results.find((r) => r.action === action && r.status === "applied");
|
|
3523
|
+
if (action.replacement && !replacementResult) {
|
|
3357
3524
|
continue;
|
|
3358
3525
|
}
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
|
|
3526
|
+
await this.retireAndTombstone(
|
|
3527
|
+
namespace,
|
|
3528
|
+
action,
|
|
3529
|
+
"supersession",
|
|
3530
|
+
results,
|
|
3531
|
+
appliedTouched,
|
|
3532
|
+
{ supersededBy: replacementResult?.memoryId },
|
|
3533
|
+
abortSignal
|
|
3534
|
+
);
|
|
3535
|
+
if (results.at(-1)?.status === "applied") {
|
|
3536
|
+
mutationCommitted = true;
|
|
3537
|
+
cancellationSafeAfterCommit = true;
|
|
3538
|
+
}
|
|
3539
|
+
if (results.at(-1)?.action === action && results.at(-1)?.status === "applied") {
|
|
3540
|
+
removeFailedResultsFor(action);
|
|
3541
|
+
}
|
|
3542
|
+
} else if (action.kind === "retract") {
|
|
3543
|
+
await this.retireAndTombstone(
|
|
3544
|
+
namespace,
|
|
3545
|
+
action,
|
|
3546
|
+
"retraction",
|
|
3547
|
+
results,
|
|
3548
|
+
appliedTouched,
|
|
3549
|
+
{},
|
|
3550
|
+
abortSignal
|
|
3551
|
+
);
|
|
3552
|
+
if (results.at(-1)?.status === "applied") {
|
|
3553
|
+
mutationCommitted = true;
|
|
3554
|
+
cancellationSafeAfterCommit = true;
|
|
3555
|
+
}
|
|
3556
|
+
if (results.at(-1)?.action === action && results.at(-1)?.status === "applied") {
|
|
3557
|
+
removeFailedResultsFor(action);
|
|
3558
|
+
}
|
|
3559
|
+
} else if (action.kind === "rescope") {
|
|
3362
3560
|
try {
|
|
3363
|
-
await
|
|
3364
|
-
|
|
3561
|
+
const allowed = canWriteDestination ? await canWriteDestination(action.toNamespace) : true;
|
|
3562
|
+
if (!allowed) {
|
|
3563
|
+
results.push({
|
|
3564
|
+
action,
|
|
3565
|
+
status: "failed",
|
|
3566
|
+
error: `rescope destination namespace not writable: ${action.toNamespace}`
|
|
3567
|
+
});
|
|
3568
|
+
continue;
|
|
3569
|
+
}
|
|
3570
|
+
const destId = await this.deps.rescopeMemory(
|
|
3571
|
+
namespace,
|
|
3572
|
+
action.memoryId,
|
|
3573
|
+
action.toNamespace,
|
|
3574
|
+
abortSignal
|
|
3575
|
+
);
|
|
3576
|
+
mutationCommitted = true;
|
|
3577
|
+
cancellationSafeAfterCommit = true;
|
|
3578
|
+
results.push({ action, status: "applied", memoryId: destId });
|
|
3579
|
+
appliedTouched.push(action.memoryId);
|
|
3580
|
+
try {
|
|
3581
|
+
await this.deps.propagate(action.toNamespace, [destId], void 0);
|
|
3582
|
+
} catch {
|
|
3583
|
+
}
|
|
3584
|
+
} catch (err) {
|
|
3585
|
+
if (abortSignal?.aborted) {
|
|
3586
|
+
if (!mutationCommitted) throw err;
|
|
3587
|
+
cancellationRequestedAfterCommit = true;
|
|
3588
|
+
break;
|
|
3589
|
+
}
|
|
3590
|
+
results.push({ action, status: "failed", error: errMsg(err) });
|
|
3365
3591
|
}
|
|
3366
|
-
} catch (err) {
|
|
3367
|
-
results.push({ action, status: "failed", error: errMsg(err) });
|
|
3368
3592
|
}
|
|
3593
|
+
} catch (err) {
|
|
3594
|
+
if (abortSignal?.aborted) {
|
|
3595
|
+
if (!mutationCommitted) {
|
|
3596
|
+
await resetApplying();
|
|
3597
|
+
throw err;
|
|
3598
|
+
}
|
|
3599
|
+
cancellationRequestedAfterCommit = true;
|
|
3600
|
+
break;
|
|
3601
|
+
}
|
|
3602
|
+
throw err;
|
|
3369
3603
|
}
|
|
3370
3604
|
}
|
|
3605
|
+
await throwIfAbortedBeforeCommitAndReset();
|
|
3371
3606
|
const propagationWarnings = [];
|
|
3372
3607
|
if (appliedTouched.length > 0) {
|
|
3373
3608
|
try {
|
|
3374
|
-
await this.deps.propagate(namespace, appliedTouched);
|
|
3609
|
+
await this.deps.propagate(namespace, appliedTouched, cancellationSafeAfterCommit ? void 0 : abortSignal);
|
|
3375
3610
|
} catch (err) {
|
|
3611
|
+
if ((!mutationCommitted || !cancellationSafeAfterCommit) && abortSignal?.aborted) throw err;
|
|
3376
3612
|
propagationWarnings.push(`propagation failed (non-fatal): ${errMsg(err)}`);
|
|
3377
3613
|
}
|
|
3378
3614
|
}
|
|
3615
|
+
await throwIfAbortedBeforeCommitAndReset();
|
|
3379
3616
|
const anyFailed = results.some((r) => r.status === "failed");
|
|
3380
|
-
const status = anyFailed ? "partial" : "applied";
|
|
3617
|
+
const status = anyFailed || cancellationRequestedAfterCommit ? "partial" : "applied";
|
|
3381
3618
|
const appliedAt = this.deps.now().toISOString();
|
|
3382
3619
|
const outcome = {
|
|
3383
3620
|
planId,
|
|
@@ -3391,19 +3628,25 @@ var CorrectionExecutor = class {
|
|
|
3391
3628
|
outcome.warnings = propagationWarnings;
|
|
3392
3629
|
}
|
|
3393
3630
|
try {
|
|
3394
|
-
const auditId = await this.deps.appendAuditRecord(
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3631
|
+
const auditId = await this.deps.appendAuditRecord(
|
|
3632
|
+
namespace,
|
|
3633
|
+
{
|
|
3634
|
+
planId,
|
|
3635
|
+
classification: plan.classification,
|
|
3636
|
+
outcome,
|
|
3637
|
+
requestText: plan.request.text
|
|
3638
|
+
},
|
|
3639
|
+
cancellationSafeAfterCommit ? void 0 : abortSignal
|
|
3640
|
+
);
|
|
3400
3641
|
outcome.auditMemoryId = auditId;
|
|
3401
3642
|
} catch (err) {
|
|
3643
|
+
if ((!mutationCommitted || !cancellationSafeAfterCommit) && abortSignal?.aborted) throw err;
|
|
3402
3644
|
outcome.warnings = [
|
|
3403
3645
|
...propagationWarnings,
|
|
3404
3646
|
`audit record write failed (non-fatal): ${errMsg(err)}`
|
|
3405
3647
|
];
|
|
3406
3648
|
}
|
|
3649
|
+
await throwIfAbortedBeforeCommitAndReset();
|
|
3407
3650
|
try {
|
|
3408
3651
|
await this.planner.markConsumed(namespace, planId, status);
|
|
3409
3652
|
} catch (err) {
|
|
@@ -3412,11 +3655,11 @@ var CorrectionExecutor = class {
|
|
|
3412
3655
|
}
|
|
3413
3656
|
return outcome;
|
|
3414
3657
|
}
|
|
3415
|
-
async retireAndTombstone(namespace, action, reason, results, appliedTouched, opts = {}) {
|
|
3658
|
+
async retireAndTombstone(namespace, action, reason, results, appliedTouched, opts = {}, abortSignal) {
|
|
3416
3659
|
const memoryId = action.kind === "supersede" ? action.loserId : action.kind === "retract" ? action.memoryId : null;
|
|
3417
3660
|
if (!memoryId) return;
|
|
3418
3661
|
try {
|
|
3419
|
-
const memory = await this.deps.getMemory(namespace, memoryId);
|
|
3662
|
+
const memory = await this.deps.getMemory(namespace, memoryId, abortSignal);
|
|
3420
3663
|
if (!memory) {
|
|
3421
3664
|
results.push({
|
|
3422
3665
|
action,
|
|
@@ -3426,25 +3669,34 @@ var CorrectionExecutor = class {
|
|
|
3426
3669
|
return;
|
|
3427
3670
|
}
|
|
3428
3671
|
const validUntil = this.deps.biTemporalEnabled ? this.deps.now().toISOString() : void 0;
|
|
3429
|
-
const tombstoneId = await this.deps.appendTombstone(
|
|
3430
|
-
|
|
3431
|
-
|
|
3432
|
-
|
|
3433
|
-
|
|
3434
|
-
|
|
3435
|
-
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
|
|
3439
|
-
|
|
3440
|
-
|
|
3441
|
-
|
|
3442
|
-
|
|
3443
|
-
|
|
3444
|
-
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
-
|
|
3672
|
+
const tombstoneId = await this.deps.appendTombstone(
|
|
3673
|
+
namespace,
|
|
3674
|
+
{
|
|
3675
|
+
reason,
|
|
3676
|
+
sourceMemoryId: memoryId,
|
|
3677
|
+
rawContent: memory.rawContent,
|
|
3678
|
+
...memory.entityRef ? { entityRef: memory.entityRef } : {},
|
|
3679
|
+
...memory.supersessionKey ? { supersessionKey: memory.supersessionKey } : {},
|
|
3680
|
+
// #1672 item 4: carry the canonical contentHash (exact tier) and the
|
|
3681
|
+
// full supersession-key set (keyed tier) so paraphrased re-observations
|
|
3682
|
+
// of the same supersession identity are blocked, not just the literal
|
|
3683
|
+
// body. Without these the tombstone projected from a structured fact
|
|
3684
|
+
// dropped both fields and the fact could resurrect.
|
|
3685
|
+
...memory.contentHash ? { contentHash: memory.contentHash } : {},
|
|
3686
|
+
...memory.supersessionKeys && memory.supersessionKeys.length > 0 ? { supersessionKeys: memory.supersessionKeys } : {}
|
|
3687
|
+
},
|
|
3688
|
+
abortSignal
|
|
3689
|
+
);
|
|
3690
|
+
await this.deps.retireMemory(
|
|
3691
|
+
namespace,
|
|
3692
|
+
memoryId,
|
|
3693
|
+
{
|
|
3694
|
+
status: reason === "supersession" ? "superseded" : "retracted",
|
|
3695
|
+
...opts.supersededBy ? { supersededBy: opts.supersededBy } : {},
|
|
3696
|
+
...validUntil ? { validUntil } : {}
|
|
3697
|
+
},
|
|
3698
|
+
tombstoneId === null ? abortSignal : void 0
|
|
3699
|
+
);
|
|
3448
3700
|
results.push({
|
|
3449
3701
|
action,
|
|
3450
3702
|
status: "applied",
|
|
@@ -3453,6 +3705,7 @@ var CorrectionExecutor = class {
|
|
|
3453
3705
|
});
|
|
3454
3706
|
appliedTouched.push(memoryId);
|
|
3455
3707
|
} catch (err) {
|
|
3708
|
+
if (abortSignal?.aborted) throw err;
|
|
3456
3709
|
results.push({ action, status: "failed", error: errMsg(err) });
|
|
3457
3710
|
}
|
|
3458
3711
|
}
|
|
@@ -3490,17 +3743,16 @@ var CorrectionService = class {
|
|
|
3490
3743
|
* the principal can write, so reading from a non-writable namespace to
|
|
3491
3744
|
* draft a correction that can never be applied would be misleading.
|
|
3492
3745
|
*/
|
|
3493
|
-
async plan(request) {
|
|
3746
|
+
async plan(request, opts) {
|
|
3494
3747
|
this.requireEnabled();
|
|
3748
|
+
throwIfAborted(opts?.abortSignal, "correction planning aborted");
|
|
3495
3749
|
const authorized = await this.deps.policy.resolveAuthorizedNamespace(request);
|
|
3496
|
-
|
|
3750
|
+
throwIfAborted(opts?.abortSignal, "correction planning aborted");
|
|
3751
|
+
return this.planner.plan(request, [authorized], opts);
|
|
3497
3752
|
}
|
|
3498
|
-
/**
|
|
3499
|
-
* Apply a persisted plan by id. Requires `confirm: true` (or interactive
|
|
3500
|
-
* yes at the CLI) when `applyRequiresConfirm` is on (default).
|
|
3501
|
-
*/
|
|
3502
3753
|
async apply(planId, opts) {
|
|
3503
3754
|
this.requireEnabled();
|
|
3755
|
+
throwIfAborted(opts.abortSignal, "correction apply aborted");
|
|
3504
3756
|
if (this.deps.applyRequiresConfirm() && opts.confirm !== true) {
|
|
3505
3757
|
throw new CorrectionContractError(
|
|
3506
3758
|
"Correction apply requires explicit confirmation (pass `confirm: true`)."
|
|
@@ -3511,8 +3763,10 @@ var CorrectionService = class {
|
|
|
3511
3763
|
...opts.sessionKey ? { sessionKey: opts.sessionKey } : {},
|
|
3512
3764
|
...opts.principal ? { principal: opts.principal } : {}
|
|
3513
3765
|
});
|
|
3766
|
+
throwIfAborted(opts.abortSignal, "correction apply aborted");
|
|
3514
3767
|
return this.executor.apply(namespace, planId, {
|
|
3515
3768
|
confirm: true,
|
|
3769
|
+
abortSignal: opts.abortSignal,
|
|
3516
3770
|
// Authorize rescope destinations through the namespace policy bound to
|
|
3517
3771
|
// THIS caller's principal (review thread: authorize-rescope-destination).
|
|
3518
3772
|
canWriteDestination: (dest) => this.deps.policy.canWriteNamespace({
|
|
@@ -3809,27 +4063,32 @@ function describeAfterState(action) {
|
|
|
3809
4063
|
}
|
|
3810
4064
|
function makeExecutorDeps(wiring, opts) {
|
|
3811
4065
|
return {
|
|
3812
|
-
getMemory: async (namespace, memoryId) => getExecutorMemory(wiring, namespace, memoryId),
|
|
3813
|
-
writeReplacement: async (namespace, draft) => writeReplacementMemory(wiring, namespace, draft),
|
|
3814
|
-
applyEdit: async (namespace, memoryId, patch) => applyEditMemory(wiring, namespace, memoryId, patch),
|
|
3815
|
-
retireMemory: async (namespace, memoryId, retireOpts) => retireMemoryFn(wiring, namespace, memoryId, retireOpts),
|
|
3816
|
-
rescopeMemory: async (namespace, memoryId, toNamespace) => rescopeMemoryFn(wiring, namespace, memoryId, toNamespace),
|
|
3817
|
-
appendTombstone: async (namespace, input) => appendTombstoneFn(wiring, namespace, input),
|
|
3818
|
-
registerRedactionRule: async (namespace, pattern) => registerRedactionRuleFn(wiring, namespace, pattern),
|
|
3819
|
-
appendAuditRecord: async (namespace, record) => appendAuditRecordFn(wiring, namespace, record),
|
|
3820
|
-
propagate: async (namespace, touchedMemoryIds) => propagateFn(wiring, namespace, touchedMemoryIds),
|
|
4066
|
+
getMemory: async (namespace, memoryId, abortSignal) => getExecutorMemory(wiring, namespace, memoryId, abortSignal),
|
|
4067
|
+
writeReplacement: async (namespace, draft, abortSignal) => writeReplacementMemory(wiring, namespace, draft, abortSignal),
|
|
4068
|
+
applyEdit: async (namespace, memoryId, patch, abortSignal) => applyEditMemory(wiring, namespace, memoryId, patch, abortSignal),
|
|
4069
|
+
retireMemory: async (namespace, memoryId, retireOpts, abortSignal) => retireMemoryFn(wiring, namespace, memoryId, retireOpts, abortSignal),
|
|
4070
|
+
rescopeMemory: async (namespace, memoryId, toNamespace, abortSignal) => rescopeMemoryFn(wiring, namespace, memoryId, toNamespace, abortSignal),
|
|
4071
|
+
appendTombstone: async (namespace, input, abortSignal) => appendTombstoneFn(wiring, namespace, input, abortSignal),
|
|
4072
|
+
registerRedactionRule: async (namespace, pattern, abortSignal) => registerRedactionRuleFn(wiring, namespace, pattern, abortSignal),
|
|
4073
|
+
appendAuditRecord: async (namespace, record, abortSignal) => appendAuditRecordFn(wiring, namespace, record, abortSignal),
|
|
4074
|
+
propagate: async (namespace, touchedMemoryIds, abortSignal) => propagateFn(wiring, namespace, touchedMemoryIds, abortSignal),
|
|
3821
4075
|
biTemporalEnabled: opts.biTemporalEnabled,
|
|
3822
4076
|
now: () => /* @__PURE__ */ new Date()
|
|
3823
4077
|
};
|
|
3824
4078
|
}
|
|
3825
|
-
async function getExecutorMemory(wiring, namespace, memoryId) {
|
|
4079
|
+
async function getExecutorMemory(wiring, namespace, memoryId, abortSignal) {
|
|
4080
|
+
throwIfAborted(abortSignal, "correction apply aborted");
|
|
3826
4081
|
const storage = await wiring.orchestrator.getStorage(namespace);
|
|
4082
|
+
throwIfAborted(abortSignal, "correction apply aborted");
|
|
3827
4083
|
const m = await storage.getMemoryById(memoryId);
|
|
4084
|
+
throwIfAborted(abortSignal, "correction apply aborted");
|
|
3828
4085
|
if (!m) return null;
|
|
3829
4086
|
return toExecutorMemory(m);
|
|
3830
4087
|
}
|
|
3831
|
-
async function writeReplacementMemory(wiring, namespace, draft) {
|
|
4088
|
+
async function writeReplacementMemory(wiring, namespace, draft, abortSignal) {
|
|
4089
|
+
throwIfAborted(abortSignal, "correction apply aborted");
|
|
3832
4090
|
const storage = await wiring.orchestrator.getStorage(namespace);
|
|
4091
|
+
throwIfAborted(abortSignal, "correction apply aborted");
|
|
3833
4092
|
if (draft.category !== void 0 && !isMemoryCategory(draft.category)) {
|
|
3834
4093
|
throw new CorrectionContractError(
|
|
3835
4094
|
`correction draft carries unrecognized category ${JSON.stringify(draft.category)} \u2014 expected a valid memory category`
|
|
@@ -3852,6 +4111,7 @@ async function writeReplacementMemory(wiring, namespace, draft) {
|
|
|
3852
4111
|
if (draftEnvelope.salvageNotes.length > 0) {
|
|
3853
4112
|
log.warn(`correction write salvaged invalid fields: ${draftEnvelope.salvageNotes.join("; ")}`);
|
|
3854
4113
|
}
|
|
4114
|
+
throwIfAborted(abortSignal, "correction apply aborted");
|
|
3855
4115
|
const { id, tombstoneBlocked } = await storage.writeSealedMemory(draftEnvelope, {
|
|
3856
4116
|
...draft.observedAt ? { observedAt: draft.observedAt } : {},
|
|
3857
4117
|
...draft.supersedes ? { supersedes: draft.supersedes } : {}
|
|
@@ -3863,11 +4123,15 @@ async function writeReplacementMemory(wiring, namespace, draft) {
|
|
|
3863
4123
|
}
|
|
3864
4124
|
return id;
|
|
3865
4125
|
}
|
|
3866
|
-
async function applyEditMemory(wiring, namespace, memoryId, patch) {
|
|
4126
|
+
async function applyEditMemory(wiring, namespace, memoryId, patch, abortSignal) {
|
|
4127
|
+
throwIfAborted(abortSignal, "correction apply aborted");
|
|
3867
4128
|
const storage = await wiring.orchestrator.getStorage(namespace);
|
|
4129
|
+
throwIfAborted(abortSignal, "correction apply aborted");
|
|
3868
4130
|
const existing = await storage.getMemoryById(memoryId);
|
|
4131
|
+
throwIfAborted(abortSignal, "correction apply aborted");
|
|
3869
4132
|
if (!existing) throw new CorrectionContractError(`memory not found for edit: ${memoryId}`);
|
|
3870
4133
|
const contentHashForPatch = existing.frontmatter.category === "fact" ? computeContentHash(sanitizeMemoryContent(patch).text) : void 0;
|
|
4134
|
+
throwIfAborted(abortSignal, "correction apply aborted");
|
|
3871
4135
|
await storage.writeMemoryFrontmatter(
|
|
3872
4136
|
{ ...existing, content: patch },
|
|
3873
4137
|
{
|
|
@@ -3877,29 +4141,37 @@ async function applyEditMemory(wiring, namespace, memoryId, patch) {
|
|
|
3877
4141
|
);
|
|
3878
4142
|
return memoryId;
|
|
3879
4143
|
}
|
|
3880
|
-
async function retireMemoryFn(wiring, namespace, memoryId, opts) {
|
|
4144
|
+
async function retireMemoryFn(wiring, namespace, memoryId, opts, abortSignal) {
|
|
4145
|
+
throwIfAborted(abortSignal, "correction apply aborted");
|
|
3881
4146
|
const storage = await wiring.orchestrator.getStorage(namespace);
|
|
4147
|
+
throwIfAborted(abortSignal, "correction apply aborted");
|
|
3882
4148
|
const memory = await storage.getMemoryById(memoryId);
|
|
4149
|
+
throwIfAborted(abortSignal, "correction apply aborted");
|
|
3883
4150
|
if (!memory) throw new CorrectionContractError(`memory not found for retire: ${memoryId}`);
|
|
3884
4151
|
const storageStatus = opts.status === "retracted" ? "forgotten" : "superseded";
|
|
4152
|
+
throwIfAborted(abortSignal, "correction apply aborted");
|
|
3885
4153
|
await storage.writeMemoryFrontmatter(memory, {
|
|
3886
4154
|
status: storageStatus,
|
|
3887
4155
|
...opts.supersededBy ? { supersededBy: opts.supersededBy } : {},
|
|
3888
4156
|
...opts.status === "superseded" ? { supersededAt: (/* @__PURE__ */ new Date()).toISOString() } : {},
|
|
3889
|
-
// validUntil is the bi-temporal end; absent when the gate is off.
|
|
3890
4157
|
...opts.validUntil ? { invalid_at: opts.validUntil } : {}
|
|
3891
4158
|
});
|
|
3892
4159
|
}
|
|
3893
|
-
async function rescopeMemoryFn(wiring, namespace, memoryId, toNamespace) {
|
|
4160
|
+
async function rescopeMemoryFn(wiring, namespace, memoryId, toNamespace, abortSignal) {
|
|
4161
|
+
throwIfAborted(abortSignal, "correction apply aborted");
|
|
3894
4162
|
const sourceStorage = await wiring.orchestrator.getStorage(namespace);
|
|
4163
|
+
throwIfAborted(abortSignal, "correction apply aborted");
|
|
3895
4164
|
const memory = await sourceStorage.getMemoryById(memoryId);
|
|
4165
|
+
throwIfAborted(abortSignal, "correction apply aborted");
|
|
3896
4166
|
if (!memory) throw new CorrectionContractError(`memory not found for rescope: ${memoryId}`);
|
|
3897
4167
|
if (memory.frontmatter.status && memory.frontmatter.status !== "active") {
|
|
3898
4168
|
throw new CorrectionContractError(
|
|
3899
4169
|
`cannot rescope memory ${memoryId}: source is ${memory.frontmatter.status}, not active`
|
|
3900
4170
|
);
|
|
3901
4171
|
}
|
|
4172
|
+
throwIfAborted(abortSignal, "correction apply aborted");
|
|
3902
4173
|
const destStorage = await wiring.orchestrator.getStorage(toNamespace);
|
|
4174
|
+
throwIfAborted(abortSignal, "correction apply aborted");
|
|
3903
4175
|
const fm = memory.frontmatter;
|
|
3904
4176
|
const destContent = fm.structuredAttributes ? stripAttributesSuffix(memory.content) : memory.content;
|
|
3905
4177
|
const rescopeEnvelope = composeMemoryEnvelope(
|
|
@@ -3918,6 +4190,7 @@ async function rescopeMemoryFn(wiring, namespace, memoryId, toNamespace) {
|
|
|
3918
4190
|
if (rescopeEnvelope.salvageNotes.length > 0) {
|
|
3919
4191
|
log.warn(`rescope write salvaged invalid fields: ${rescopeEnvelope.salvageNotes.join("; ")}`);
|
|
3920
4192
|
}
|
|
4193
|
+
throwIfAborted(abortSignal, "correction apply aborted");
|
|
3921
4194
|
const { id: destId, tombstoneBlocked: destBlocked } = await destStorage.writeSealedMemory(rescopeEnvelope, {
|
|
3922
4195
|
...fm.observedAt ? { observedAt: fm.observedAt } : {},
|
|
3923
4196
|
...fm.memoryKind ? { memoryKind: fm.memoryKind } : {},
|
|
@@ -3949,13 +4222,17 @@ async function rescopeMemoryFn(wiring, namespace, memoryId, toNamespace) {
|
|
|
3949
4222
|
}
|
|
3950
4223
|
return destId;
|
|
3951
4224
|
}
|
|
3952
|
-
async function appendTombstoneFn(wiring, namespace, input) {
|
|
4225
|
+
async function appendTombstoneFn(wiring, namespace, input, abortSignal) {
|
|
4226
|
+
throwIfAborted(abortSignal, "correction apply aborted");
|
|
3953
4227
|
const storage = await wiring.orchestrator.getStorage(namespace);
|
|
4228
|
+
throwIfAborted(abortSignal, "correction apply aborted");
|
|
3954
4229
|
const enabled = typeof storage.isTombstonesEnabled === "function" ? storage.isTombstonesEnabled() : true;
|
|
3955
4230
|
const keys = input.supersessionKeys && input.supersessionKeys.length > 0 ? input.supersessionKeys : input.supersessionKey ? [input.supersessionKey] : [void 0];
|
|
3956
4231
|
const writtenIds = [];
|
|
3957
4232
|
let firstId = null;
|
|
4233
|
+
let committed = false;
|
|
3958
4234
|
for (const key of keys) {
|
|
4235
|
+
if (!committed) throwIfAborted(abortSignal, "correction apply aborted");
|
|
3959
4236
|
const result = await storage.appendTombstone({
|
|
3960
4237
|
reason: input.reason,
|
|
3961
4238
|
createdBy: "user_correction",
|
|
@@ -3977,26 +4254,37 @@ async function appendTombstoneFn(wiring, namespace, input) {
|
|
|
3977
4254
|
);
|
|
3978
4255
|
}
|
|
3979
4256
|
if (firstId === null) firstId = result;
|
|
3980
|
-
if (result)
|
|
4257
|
+
if (result) {
|
|
4258
|
+
writtenIds.push(result);
|
|
4259
|
+
committed = true;
|
|
4260
|
+
}
|
|
3981
4261
|
}
|
|
3982
4262
|
return firstId;
|
|
3983
4263
|
}
|
|
3984
|
-
async function registerRedactionRuleFn(wiring, namespace, pattern) {
|
|
4264
|
+
async function registerRedactionRuleFn(wiring, namespace, pattern, abortSignal) {
|
|
4265
|
+
throwIfAborted(abortSignal, "correction apply aborted");
|
|
3985
4266
|
const storage = await wiring.orchestrator.getStorage(namespace);
|
|
4267
|
+
throwIfAborted(abortSignal, "correction apply aborted");
|
|
3986
4268
|
const dir = path5.join(storage.dir, "state", "corrections", "redaction-rules");
|
|
3987
4269
|
await mkdir3(dir, { recursive: true });
|
|
4270
|
+
throwIfAborted(abortSignal, "correction apply aborted");
|
|
3988
4271
|
const slugBase = pattern.replace(/[^a-zA-Z0-9]+/g, "-").slice(0, 48) || "rule";
|
|
3989
4272
|
const patternHash = createHash2("sha256").update(pattern).digest("hex").slice(0, 16);
|
|
3990
4273
|
const slug = `${slugBase}-${patternHash}`;
|
|
4274
|
+
throwIfAborted(abortSignal, "correction apply aborted");
|
|
3991
4275
|
await writeFile3(
|
|
3992
4276
|
path5.join(dir, `${slug}.json`),
|
|
3993
4277
|
`${JSON.stringify({ pattern, namespace, createdAt: (/* @__PURE__ */ new Date()).toISOString() })}
|
|
3994
4278
|
`,
|
|
3995
4279
|
"utf-8"
|
|
3996
4280
|
);
|
|
4281
|
+
throwIfAborted(abortSignal, "correction apply aborted");
|
|
3997
4282
|
}
|
|
3998
|
-
async function appendAuditRecordFn(wiring, namespace, record) {
|
|
4283
|
+
async function appendAuditRecordFn(wiring, namespace, record, abortSignal) {
|
|
4284
|
+
throwIfAborted(abortSignal, "correction apply aborted");
|
|
3999
4285
|
const storage = await wiring.orchestrator.getStorage(namespace);
|
|
4286
|
+
throwIfAborted(abortSignal, "correction apply aborted");
|
|
4287
|
+
throwIfAborted(abortSignal, "correction apply aborted");
|
|
4000
4288
|
const { id } = await storage.writeSealedMemory(
|
|
4001
4289
|
composeMemoryEnvelope(
|
|
4002
4290
|
{
|
|
@@ -4009,6 +4297,7 @@ async function appendAuditRecordFn(wiring, namespace, record) {
|
|
|
4009
4297
|
),
|
|
4010
4298
|
{}
|
|
4011
4299
|
);
|
|
4300
|
+
throwIfAborted(abortSignal, "correction apply aborted");
|
|
4012
4301
|
return id;
|
|
4013
4302
|
}
|
|
4014
4303
|
function buildAuditBody(record) {
|
|
@@ -4030,15 +4319,19 @@ function buildAuditBody(record) {
|
|
|
4030
4319
|
}
|
|
4031
4320
|
return lines.join("\n");
|
|
4032
4321
|
}
|
|
4033
|
-
async function propagateFn(wiring, namespace, touchedMemoryIds) {
|
|
4322
|
+
async function propagateFn(wiring, namespace, touchedMemoryIds, abortSignal) {
|
|
4034
4323
|
for (const id of touchedMemoryIds) {
|
|
4324
|
+
throwIfAborted(abortSignal, "correction apply aborted");
|
|
4035
4325
|
try {
|
|
4036
4326
|
const storage = await wiring.orchestrator.getStorage(namespace);
|
|
4327
|
+
throwIfAborted(abortSignal, "correction apply aborted");
|
|
4037
4328
|
const orchestrator = wiring.orchestrator;
|
|
4038
4329
|
if (typeof orchestrator.indexPersistedMemory === "function") {
|
|
4039
4330
|
await orchestrator.indexPersistedMemory(storage, id);
|
|
4331
|
+
throwIfAborted(abortSignal, "correction apply aborted");
|
|
4040
4332
|
}
|
|
4041
|
-
} catch {
|
|
4333
|
+
} catch (err) {
|
|
4334
|
+
if (abortSignal?.aborted) throw err;
|
|
4042
4335
|
}
|
|
4043
4336
|
}
|
|
4044
4337
|
}
|
|
@@ -4387,6 +4680,7 @@ async function capturePassiveCorrections(corrections, ctx, config, deps, dedupSt
|
|
|
4387
4680
|
const plans = [];
|
|
4388
4681
|
telemetry.detected = corrections.length;
|
|
4389
4682
|
for (const correction of corrections) {
|
|
4683
|
+
if (ctx.abortSignal?.aborted) return { telemetry, plans };
|
|
4390
4684
|
const fp = correctionFingerprint(ctx.bufferKey, correction);
|
|
4391
4685
|
if (dedupState.has(fp)) {
|
|
4392
4686
|
continue;
|
|
@@ -4409,13 +4703,14 @@ async function capturePassiveCorrections(corrections, ctx, config, deps, dedupSt
|
|
|
4409
4703
|
};
|
|
4410
4704
|
let plan;
|
|
4411
4705
|
try {
|
|
4412
|
-
plan = await deps.planCorrection(request);
|
|
4706
|
+
plan = await deps.planCorrection(request, { abortSignal: ctx.abortSignal });
|
|
4413
4707
|
} catch (err) {
|
|
4414
4708
|
log.warn(
|
|
4415
4709
|
`passive-correction: planning failed for "${correction.targetHint.slice(0, 60)}": ${err instanceof Error ? err.message : String(err)}`
|
|
4416
4710
|
);
|
|
4417
4711
|
continue;
|
|
4418
4712
|
}
|
|
4713
|
+
if (ctx.abortSignal?.aborted) return { telemetry, plans };
|
|
4419
4714
|
plans.push(plan);
|
|
4420
4715
|
dedupState.add(fp);
|
|
4421
4716
|
if (config.mode === "queue") {
|
|
@@ -4433,7 +4728,8 @@ async function capturePassiveCorrections(corrections, ctx, config, deps, dedupSt
|
|
|
4433
4728
|
confirm: true,
|
|
4434
4729
|
namespace: ctx.namespace,
|
|
4435
4730
|
...ctx.sessionKey ? { sessionKey: ctx.sessionKey } : {},
|
|
4436
|
-
...ctx.principal ? { principal: ctx.principal } : {}
|
|
4731
|
+
...ctx.principal ? { principal: ctx.principal } : {},
|
|
4732
|
+
abortSignal: ctx.abortSignal
|
|
4437
4733
|
});
|
|
4438
4734
|
if (outcome.status !== "applied") {
|
|
4439
4735
|
log.warn(
|
|
@@ -4878,6 +5174,7 @@ var OPERATION_NAMES = [
|
|
|
4878
5174
|
"observe",
|
|
4879
5175
|
"lcm_search",
|
|
4880
5176
|
"lcm_compaction_flush",
|
|
5177
|
+
"extraction_force_flush",
|
|
4881
5178
|
"lcm_compaction_record",
|
|
4882
5179
|
"continuity_audit_generate",
|
|
4883
5180
|
"continuity_incident_open",
|
|
@@ -5581,12 +5878,524 @@ import * as nodePath3 from "path";
|
|
|
5581
5878
|
|
|
5582
5879
|
// src/access-observe-write-surface.ts
|
|
5583
5880
|
import { createHash as createHash4 } from "crypto";
|
|
5881
|
+
|
|
5882
|
+
// src/orchestration/session-context.ts
|
|
5883
|
+
var SessionOwnershipError = class extends Error {
|
|
5884
|
+
constructor(message) {
|
|
5885
|
+
super(message);
|
|
5886
|
+
this.name = "SessionOwnershipError";
|
|
5887
|
+
}
|
|
5888
|
+
};
|
|
5889
|
+
var MAX_SET_TIMEOUT_MS = 2147483647;
|
|
5890
|
+
async function awaitSessionFlushPhase(task, options) {
|
|
5891
|
+
const abortMessage = options.reason === "access_force_flush" ? "extraction force-flush aborted" : "session flush aborted";
|
|
5892
|
+
throwIfAborted(options.abortSignal, abortMessage);
|
|
5893
|
+
const deadline = options.extractionDeadlineMs;
|
|
5894
|
+
if (typeof deadline === "number" && Date.now() >= deadline) {
|
|
5895
|
+
options.onDeadline?.();
|
|
5896
|
+
throw new ExtractionDeadlineError(options.deadlineStage ?? "before_buffer_flush");
|
|
5897
|
+
}
|
|
5898
|
+
const taskPromise = Promise.resolve().then(task);
|
|
5899
|
+
if (!options.abortSignal && typeof deadline !== "number") return taskPromise;
|
|
5900
|
+
let abortHandler;
|
|
5901
|
+
let deadlineTimer;
|
|
5902
|
+
const abortPromise = options.abortSignal === void 0 ? void 0 : new Promise((_resolve, reject) => {
|
|
5903
|
+
abortHandler = () => reject(abortError(abortMessage));
|
|
5904
|
+
options.abortSignal?.addEventListener("abort", abortHandler, { once: true });
|
|
5905
|
+
});
|
|
5906
|
+
const deadlinePromise = typeof deadline !== "number" ? void 0 : new Promise((_resolve, reject) => {
|
|
5907
|
+
const schedule = () => {
|
|
5908
|
+
const remainingMs = deadline - Date.now();
|
|
5909
|
+
if (remainingMs <= 0) {
|
|
5910
|
+
options.onDeadline?.();
|
|
5911
|
+
reject(new ExtractionDeadlineError(options.deadlineStage ?? "before_buffer_flush"));
|
|
5912
|
+
return;
|
|
5913
|
+
}
|
|
5914
|
+
deadlineTimer = setTimeout(schedule, Math.min(remainingMs, MAX_SET_TIMEOUT_MS));
|
|
5915
|
+
deadlineTimer.unref?.();
|
|
5916
|
+
};
|
|
5917
|
+
schedule();
|
|
5918
|
+
});
|
|
5919
|
+
const races = [taskPromise];
|
|
5920
|
+
if (abortPromise) races.push(abortPromise);
|
|
5921
|
+
if (deadlinePromise) races.push(deadlinePromise);
|
|
5922
|
+
try {
|
|
5923
|
+
return await Promise.race(races);
|
|
5924
|
+
} finally {
|
|
5925
|
+
if (abortHandler && options.abortSignal) {
|
|
5926
|
+
options.abortSignal.removeEventListener("abort", abortHandler);
|
|
5927
|
+
}
|
|
5928
|
+
if (deadlineTimer) clearTimeout(deadlineTimer);
|
|
5929
|
+
}
|
|
5930
|
+
}
|
|
5931
|
+
var SessionContextCoordinator = class {
|
|
5932
|
+
constructor(deps) {
|
|
5933
|
+
this.deps = deps;
|
|
5934
|
+
}
|
|
5935
|
+
deps;
|
|
5936
|
+
/**
|
|
5937
|
+
* Effective namespace a same-session LCM/structured-history READER must use
|
|
5938
|
+
* to find what the access `observe` surface WROTE (#1495 thread 2).
|
|
5939
|
+
*
|
|
5940
|
+
* This MUST mirror the `observe` scope plan's write-namespace resolution, NOT
|
|
5941
|
+
* `resolveSelfNamespace`: when no coding overlay applies, `observe` archives
|
|
5942
|
+
* under `config.defaultNamespace` (an unqualified observed turn is NOT moved
|
|
5943
|
+
* to the principal self namespace — identical to
|
|
5944
|
+
* `resolveCodingScopedWriteNamespace`/`memory_store`, rule 39). Only when a
|
|
5945
|
+
* coding overlay actually changes the namespace does the writer (and so the
|
|
5946
|
+
* reader) use the overlaid `project-*` namespace. Returning the self base for
|
|
5947
|
+
* the no-overlay case would prefix the read key with a namespace the writer
|
|
5948
|
+
* never used, so the reader would miss its own evidence.
|
|
5949
|
+
*
|
|
5950
|
+
* Honours the access-surface `principalOverride` (#1505 thread 2, codex): when
|
|
5951
|
+
* a recall supplies an authenticated principal NOT encoded in the raw
|
|
5952
|
+
* `sessionKey`, `observe` archived LCM under THAT principal's base namespace.
|
|
5953
|
+
* Deriving the base from `resolvePrincipal(sessionKey)` alone could fall back
|
|
5954
|
+
* to `default`, so principal `alice` observing `sess-1` would write under
|
|
5955
|
+
* `alice` but READ under `default`. Threading the override here keeps the read
|
|
5956
|
+
* base identical to the write base.
|
|
5957
|
+
*
|
|
5958
|
+
* READ-AUTHORIZATION gate (#1505 round 3, codex P2 "Gate LCM recall keys by
|
|
5959
|
+
* readable namespaces"): the overlay LCM read key is a `<principal>-project-*`
|
|
5960
|
+
* sub-namespace of the principal SELF base. The normal recall namespace set
|
|
5961
|
+
* below only substitutes the coding overlay when the principal SELF base is
|
|
5962
|
+
* actually in the readable recall set (`recallNamespacesForPrincipal` — gated
|
|
5963
|
+
* by `defaultRecallNamespaces.includes("self")` AND `canReadNamespace`). If a
|
|
5964
|
+
* principal can WRITE but not READ its self namespace (or `defaultRecall-
|
|
5965
|
+
* Namespaces` omits `self`), QMD/file recall never touches those overlay rows,
|
|
5966
|
+
* so neither may the LCM read key. When the self base is NOT readable, fall
|
|
5967
|
+
* back to the default store — exactly what an unqualified, unauthorized recall
|
|
5968
|
+
* resolves to — rather than injecting overlay rows the rest of recall excludes
|
|
5969
|
+
* (rule 42 read/write parity; rule 48 least-privilege).
|
|
5970
|
+
*/
|
|
5971
|
+
lcmReadNamespaceForSession(sessionKey, principalOverride) {
|
|
5972
|
+
const principal = typeof principalOverride === "string" && principalOverride.length > 0 ? principalOverride : this.deps.resolvePrincipal(sessionKey);
|
|
5973
|
+
const base = defaultNamespaceForPrincipal(principal, this.deps.config);
|
|
5974
|
+
const overlaid = this.deps.applyCodingNamespaceOverlay(sessionKey, base);
|
|
5975
|
+
if (overlaid === base) return this.deps.config.defaultNamespace;
|
|
5976
|
+
const selfReadableInRecall = recallNamespacesForPrincipal(
|
|
5977
|
+
principal,
|
|
5978
|
+
this.deps.config
|
|
5979
|
+
).includes(base);
|
|
5980
|
+
return selfReadableInRecall ? overlaid : this.deps.config.defaultNamespace;
|
|
5981
|
+
}
|
|
5982
|
+
/**
|
|
5983
|
+
* Attach a coding-agent context to a session (issue #569). Called by the
|
|
5984
|
+
* Claude Code / Codex / Cursor connectors at session start after
|
|
5985
|
+
* `resolveGitContext(cwd)`. The context is consulted by the recall path
|
|
5986
|
+
* and the write path so that memories route to a project- (and optionally
|
|
5987
|
+
* branch-) scoped namespace.
|
|
5988
|
+
*
|
|
5989
|
+
* Pass `null` to clear.
|
|
5990
|
+
*/
|
|
5991
|
+
setCodingContextForSession(sessionKey, codingContext) {
|
|
5992
|
+
if (typeof sessionKey !== "string" || sessionKey.length === 0) return;
|
|
5993
|
+
this.deps.ensureSessionBindingMaps();
|
|
5994
|
+
if (codingContext === null) {
|
|
5995
|
+
this.deps._codingContextBySession.delete(sessionKey);
|
|
5996
|
+
return;
|
|
5997
|
+
}
|
|
5998
|
+
this.deps._codingContextBySession.set(sessionKey, codingContext);
|
|
5999
|
+
}
|
|
6000
|
+
/**
|
|
6001
|
+
* Read-only accessor for the coding context attached to a session. Returns
|
|
6002
|
+
* `null` when none is set. Used by `remnic doctor` and by tests.
|
|
6003
|
+
*
|
|
6004
|
+
* Defensive `_codingContextBySession` lookup — legacy orchestrator-flush
|
|
6005
|
+
* tests use `Object.create(Orchestrator.prototype)` which does not run
|
|
6006
|
+
* class-field initializers, so the Map may be undefined on stubs.
|
|
6007
|
+
*/
|
|
6008
|
+
getCodingContextForSession(sessionKey) {
|
|
6009
|
+
if (typeof sessionKey !== "string" || sessionKey.length === 0) return null;
|
|
6010
|
+
return this.deps._codingContextBySession?.get(sessionKey) ?? null;
|
|
6011
|
+
}
|
|
6012
|
+
/**
|
|
6013
|
+
* Shared helper used by both the recall path and the write path (rule 42).
|
|
6014
|
+
*
|
|
6015
|
+
* Given a base namespace computed from the principal, returns the overlaid
|
|
6016
|
+
* coding namespace when the session has a coding context AND
|
|
6017
|
+
* `codingMode.projectScope` is true AND `namespacesEnabled` is true.
|
|
6018
|
+
* Otherwise returns `baseNamespace` unchanged — CLAUDE.md #30 escape hatch.
|
|
6019
|
+
*
|
|
6020
|
+
* Principal isolation (CLAUDE.md rule 42): the overlay is COMBINED with
|
|
6021
|
+
* the principal-derived `baseNamespace` rather than replacing it, so two
|
|
6022
|
+
* principals working in the same repository do not share memories through
|
|
6023
|
+
* a common `project-*` namespace.
|
|
6024
|
+
*
|
|
6025
|
+
* Namespaces-disabled gate: when `namespacesEnabled` is false, the
|
|
6026
|
+
* storage router maps every namespace to the same `memoryDir`. Returning
|
|
6027
|
+
* `project-*` in that mode would create apparent route separation with
|
|
6028
|
+
* no actual storage isolation — a false-isolation trap. In that mode we
|
|
6029
|
+
* return `baseNamespace` unchanged so coding mode degrades to the existing
|
|
6030
|
+
* unscoped behavior.
|
|
6031
|
+
*
|
|
6032
|
+
* @internal
|
|
6033
|
+
*/
|
|
6034
|
+
applyCodingNamespaceOverlay(sessionKey, baseNamespace) {
|
|
6035
|
+
if (!resolveNamespaceCapabilities(this.deps.config).namespaces) return baseNamespace;
|
|
6036
|
+
const codingContext = this.deps.getCodingContextForSession(sessionKey);
|
|
6037
|
+
const overlay = resolveCodingNamespaceOverlay(codingContext, this.deps.config.codingMode, this.deps.config.defaultNamespace);
|
|
6038
|
+
if (!overlay) return baseNamespace;
|
|
6039
|
+
return combineNamespaces(baseNamespace, overlay.namespace);
|
|
6040
|
+
}
|
|
6041
|
+
/**
|
|
6042
|
+
* Register a peer ID for a session so recall can inject the peer's
|
|
6043
|
+
* profile into context (issue #679 PR 3/5). Pass `null` to clear.
|
|
6044
|
+
*
|
|
6045
|
+
* Connectors and the `before_agent_start` hook call this when the
|
|
6046
|
+
* session's counter-party is known. The ID is validated against
|
|
6047
|
+
* `PEER_ID_PATTERN` before storing.
|
|
6048
|
+
*
|
|
6049
|
+
* Fail-closed (Codex P1 review): an invalid peerId clears any
|
|
6050
|
+
* previously registered mapping for the session rather than silently
|
|
6051
|
+
* keeping stale data. This prevents a malformed metadata update from
|
|
6052
|
+
* mixing one peer's profile context into another session.
|
|
6053
|
+
*
|
|
6054
|
+
* Defensive init (Cursor review + rule 16): `Object.create(
|
|
6055
|
+
* Orchestrator.prototype)` stubs in legacy tests skip class-field
|
|
6056
|
+
* initializers, so `_peerIdBySession` may be undefined. Mirror the
|
|
6057
|
+
* same guard used by `setCodingContextForSession`.
|
|
6058
|
+
*/
|
|
6059
|
+
setPeerIdForSession(sessionKey, peerId) {
|
|
6060
|
+
if (typeof sessionKey !== "string" || sessionKey.length === 0) return;
|
|
6061
|
+
this.deps.ensureSessionBindingMaps();
|
|
6062
|
+
if (peerId === null) {
|
|
6063
|
+
this.deps._peerIdBySession.delete(sessionKey);
|
|
6064
|
+
return;
|
|
6065
|
+
}
|
|
6066
|
+
if (typeof peerId !== "string" || peerId.length === 0 || peerId.length > 64 || !/^[A-Za-z0-9]+(?:[._-][A-Za-z0-9]+)*$/.test(peerId)) {
|
|
6067
|
+
log.warn(`setPeerIdForSession: invalid peerId \u2014 clearing session mapping`);
|
|
6068
|
+
this.deps._peerIdBySession.delete(sessionKey);
|
|
6069
|
+
return;
|
|
6070
|
+
}
|
|
6071
|
+
this.deps._peerIdBySession.set(sessionKey, peerId);
|
|
6072
|
+
}
|
|
6073
|
+
/**
|
|
6074
|
+
* Return the peer ID registered for a session, or `null` when none
|
|
6075
|
+
* is set. Used by `recallInternal` to inject the peer profile section.
|
|
6076
|
+
* Defensive `_peerIdBySession` lookup — legacy orchestrator-flush tests
|
|
6077
|
+
* use `Object.create(Orchestrator.prototype)` which skips class-field
|
|
6078
|
+
* initializers, so the Map may be undefined on stubs.
|
|
6079
|
+
*/
|
|
6080
|
+
getPeerIdForSession(sessionKey) {
|
|
6081
|
+
if (typeof sessionKey !== "string" || sessionKey.length === 0) return null;
|
|
6082
|
+
return this.deps._peerIdBySession?.get(sessionKey) ?? null;
|
|
6083
|
+
}
|
|
6084
|
+
async runDeepSleepGovernanceNow(options) {
|
|
6085
|
+
const targetStorage = options?.storage ?? this.deps.storage;
|
|
6086
|
+
const { runMemoryGovernance: runMemoryGovernance3 } = await import("./maintenance/memory-governance.js");
|
|
6087
|
+
const { summarizeGovernanceResultForDreams } = await import("./dreams-ledger-567VKVOU.js");
|
|
6088
|
+
const govResult = await runMemoryGovernance3({
|
|
6089
|
+
memoryDir: targetStorage.dir,
|
|
6090
|
+
mode: options?.dryRun === true ? "shadow" : "apply"
|
|
6091
|
+
});
|
|
6092
|
+
if (options?.dryRun !== true) {
|
|
6093
|
+
try {
|
|
6094
|
+
await this.deps.entitySynthesisCoordinator.processQueue(
|
|
6095
|
+
this.deps.storageDirNamespace(targetStorage.dir),
|
|
6096
|
+
5
|
|
6097
|
+
);
|
|
6098
|
+
} catch (error) {
|
|
6099
|
+
log.debug(`deep-sleep governance: entity synthesis refresh failed after apply: ${error}`);
|
|
6100
|
+
}
|
|
6101
|
+
}
|
|
6102
|
+
return summarizeGovernanceResultForDreams(govResult, options?.dryRun === true);
|
|
6103
|
+
}
|
|
6104
|
+
async generateDaySummary(memories) {
|
|
6105
|
+
if (this.deps.initPromise) {
|
|
6106
|
+
let initGateTimeoutHandle;
|
|
6107
|
+
try {
|
|
6108
|
+
await Promise.race([
|
|
6109
|
+
this.deps.initPromise.catch(() => void 0),
|
|
6110
|
+
new Promise((resolve4) => {
|
|
6111
|
+
initGateTimeoutHandle = setTimeout(
|
|
6112
|
+
resolve4,
|
|
6113
|
+
this.deps.config.initGateTimeoutMs
|
|
6114
|
+
);
|
|
6115
|
+
})
|
|
6116
|
+
]);
|
|
6117
|
+
} finally {
|
|
6118
|
+
if (initGateTimeoutHandle) clearTimeout(initGateTimeoutHandle);
|
|
6119
|
+
}
|
|
6120
|
+
}
|
|
6121
|
+
return this.deps.extraction.generateDaySummary(memories);
|
|
6122
|
+
}
|
|
6123
|
+
async flushSession(sessionKey, options) {
|
|
6124
|
+
if (typeof this.deps.buffer.flushPendingSave === "function") {
|
|
6125
|
+
await awaitSessionFlushPhase(
|
|
6126
|
+
() => this.deps.buffer.flushPendingSave({ throwOnFailure: true }),
|
|
6127
|
+
options
|
|
6128
|
+
);
|
|
6129
|
+
} else {
|
|
6130
|
+
throwIfAborted(
|
|
6131
|
+
options.abortSignal,
|
|
6132
|
+
options.reason === "access_force_flush" ? "extraction force-flush aborted" : "session flush aborted"
|
|
6133
|
+
);
|
|
6134
|
+
if (typeof options.extractionDeadlineMs === "number" && Date.now() >= options.extractionDeadlineMs) {
|
|
6135
|
+
throw new ExtractionDeadlineError("before_buffer_flush");
|
|
6136
|
+
}
|
|
6137
|
+
}
|
|
6138
|
+
const explicitBufferKey = typeof options.bufferKey === "string" && options.bufferKey.length > 0 ? options.bufferKey : null;
|
|
6139
|
+
const discoveredBufferKeys = explicitBufferKey || typeof sessionKey !== "string" || sessionKey.length === 0 || typeof this.deps.buffer.findBufferKeysForSession !== "function" ? [] : await awaitSessionFlushPhase(
|
|
6140
|
+
() => this.deps.buffer.findBufferKeysForSession(sessionKey),
|
|
6141
|
+
options
|
|
6142
|
+
);
|
|
6143
|
+
const bufferKeys = explicitBufferKey ? [explicitBufferKey] : discoveredBufferKeys.length > 0 ? discoveredBufferKeys : typeof sessionKey === "string" && sessionKey.length > 0 ? [sessionKey] : ["default"];
|
|
6144
|
+
const namespacesEnabled = this.deps.config === void 0 || resolveNamespaceCapabilities(this.deps.config).namespaces === true;
|
|
6145
|
+
const scopedRequest = typeof options.writeNamespaceOverride === "string" || typeof options.principalOverride === "string";
|
|
6146
|
+
const ownershipEnforced = namespacesEnabled && scopedRequest;
|
|
6147
|
+
const ownerPrincipal = typeof options.principalOverride === "string" && options.principalOverride.trim().length > 0 ? options.principalOverride.trim() : void 0;
|
|
6148
|
+
const resolvedSessionPrincipal = ownershipEnforced && ownerPrincipal !== void 0 && this.deps.config ? resolvePrincipal(sessionKey, this.deps.config) : void 0;
|
|
6149
|
+
const opaqueScopedSession = ownershipEnforced && ownerPrincipal !== void 0 && (resolvedSessionPrincipal === void 0 || resolvedSessionPrincipal === "default");
|
|
6150
|
+
const belongsToSession = (turn) => {
|
|
6151
|
+
if (turn.sessionKey !== sessionKey) return false;
|
|
6152
|
+
if (!ownershipEnforced || ownerPrincipal === void 0) return true;
|
|
6153
|
+
if (turn.sessionOwnerPrincipal === ownerPrincipal) return true;
|
|
6154
|
+
return turn.sessionOwnerPrincipal === void 0 && this.deps.config !== void 0 && resolvePrincipal(turn.sessionKey, this.deps.config) === ownerPrincipal;
|
|
6155
|
+
};
|
|
6156
|
+
if (opaqueScopedSession && bufferKeys.some(
|
|
6157
|
+
(bufferKey) => this.deps.buffer.getTurns(bufferKey).some((turn) => turn.sessionKey === sessionKey && turn.sessionOwnerPrincipal === void 0)
|
|
6158
|
+
)) {
|
|
6159
|
+
throw new SessionOwnershipError(
|
|
6160
|
+
`session ${sessionKey} has buffered turns without trusted ownership`
|
|
6161
|
+
);
|
|
6162
|
+
}
|
|
6163
|
+
for (const bufferKey of bufferKeys) {
|
|
6164
|
+
const turns = this.deps.buffer.getTurns(bufferKey);
|
|
6165
|
+
const turnsForSession = scopedRequest ? turns.filter(belongsToSession) : turns;
|
|
6166
|
+
if (turnsForSession.length === 0) continue;
|
|
6167
|
+
const retainedTurnsForOtherSessions = scopedRequest && typeof this.deps.buffer.getRetainedDeferredTurns === "function" ? this.deps.buffer.getRetainedDeferredTurns(bufferKey).filter((turn) => !belongsToSession(turn)) : [];
|
|
6168
|
+
try {
|
|
6169
|
+
await new Promise((resolve4, reject) => {
|
|
6170
|
+
void this.deps.queueBufferedExtraction(turnsForSession, "trigger_mode", {
|
|
6171
|
+
bufferKey,
|
|
6172
|
+
clearBufferAfterExtraction: true,
|
|
6173
|
+
skipDedupeCheck: true,
|
|
6174
|
+
skipCharThreshold: true,
|
|
6175
|
+
skipUserTurnThreshold: true,
|
|
6176
|
+
failOnExtractionFailure: options.failOnExtractionFailure === true,
|
|
6177
|
+
forceExtractionAttempt: true,
|
|
6178
|
+
abortSignal: options.abortSignal,
|
|
6179
|
+
extractionDeadlineMs: options.extractionDeadlineMs,
|
|
6180
|
+
writeNamespaceOverride: options.writeNamespaceOverride,
|
|
6181
|
+
principalOverride: options.principalOverride,
|
|
6182
|
+
scopeProfileWritePlan: options.scopeProfileWritePlan,
|
|
6183
|
+
clearMatchingTurns: options.clearMatchingTurns ?? scopedRequest,
|
|
6184
|
+
onDurableCommit: options.onCommitted,
|
|
6185
|
+
onTaskSettled: (error) => error ? reject(error) : resolve4()
|
|
6186
|
+
}).catch(reject);
|
|
6187
|
+
});
|
|
6188
|
+
} finally {
|
|
6189
|
+
if (retainedTurnsForOtherSessions.length > 0 && typeof this.deps.buffer.retainDeferredTurns === "function") {
|
|
6190
|
+
const retainedAfterExtraction = this.deps.buffer.getRetainedDeferredTurns(bufferKey);
|
|
6191
|
+
await this.deps.buffer.retainDeferredTurns(
|
|
6192
|
+
bufferKey,
|
|
6193
|
+
[
|
|
6194
|
+
...retainedAfterExtraction.filter((turn) => belongsToSession(turn)),
|
|
6195
|
+
...retainedTurnsForOtherSessions
|
|
6196
|
+
],
|
|
6197
|
+
10
|
|
6198
|
+
).catch((error) => {
|
|
6199
|
+
log.warn(
|
|
6200
|
+
`session flush could not restore retained turns for other sessions in ${bufferKey}`,
|
|
6201
|
+
error
|
|
6202
|
+
);
|
|
6203
|
+
});
|
|
6204
|
+
}
|
|
6205
|
+
}
|
|
6206
|
+
}
|
|
6207
|
+
}
|
|
6208
|
+
/** Lazily construct the CorrectionService for passive capture. Stateless
|
|
6209
|
+
* across requests (per #1580 design); cached for the orchestrator's life. */
|
|
6210
|
+
passiveCorrectionService() {
|
|
6211
|
+
if (this.deps._passiveCorrectionService) return this.deps._passiveCorrectionService;
|
|
6212
|
+
this.deps._passiveCorrectionService = createCorrectionService({
|
|
6213
|
+
orchestrator: this.deps.orchestratorSelf,
|
|
6214
|
+
// Session-scoped write ACL (review: "passive capture bypasses write
|
|
6215
|
+
// ACL"). A correction detected in session S plans only against S readable
|
|
6216
|
+
// namespaces and applies only to writable ones (rule 42) — passive
|
|
6217
|
+
// capture never becomes a cross-tenant mutation vector. Mirrors the
|
|
6218
|
+
// access-service createCorrectionService wiring rather than bypassing it.
|
|
6219
|
+
resolveAuthorizedNamespace: async (req) => {
|
|
6220
|
+
const principal = req.principal || resolvePrincipal(req.sessionKey, this.deps.config);
|
|
6221
|
+
const ns = req.namespace ?? defaultNamespaceForPrincipal(principal, this.deps.config);
|
|
6222
|
+
if (!canWriteNamespace(principal, ns, this.deps.config)) {
|
|
6223
|
+
throw new Error(
|
|
6224
|
+
`passive correction: namespace "${ns}" is not writable for principal ${principal ?? "(none)"}`
|
|
6225
|
+
);
|
|
6226
|
+
}
|
|
6227
|
+
return ns;
|
|
6228
|
+
},
|
|
6229
|
+
resolveReadableNamespaces: (req) => {
|
|
6230
|
+
const principal = req.principal || resolvePrincipal(req.sessionKey, this.deps.config);
|
|
6231
|
+
return recallNamespacesForPrincipal(principal, this.deps.config);
|
|
6232
|
+
},
|
|
6233
|
+
canWriteNamespace: async (req) => {
|
|
6234
|
+
const principal = req.principal || resolvePrincipal(req.sessionKey, this.deps.config);
|
|
6235
|
+
return canWriteNamespace(principal, req.namespace, this.deps.config);
|
|
6236
|
+
},
|
|
6237
|
+
llmComplete: async ({ system, user }) => {
|
|
6238
|
+
const llmResult = await this.deps.localLlm.chatCompletion(
|
|
6239
|
+
[
|
|
6240
|
+
{ role: "system", content: system },
|
|
6241
|
+
{ role: "user", content: user }
|
|
6242
|
+
],
|
|
6243
|
+
{ operation: "correction-classify", priority: "background" }
|
|
6244
|
+
);
|
|
6245
|
+
if (!llmResult) {
|
|
6246
|
+
throw new Error(
|
|
6247
|
+
"passive correction classify+draft: local LLM unavailable (disabled or in cooldown)"
|
|
6248
|
+
);
|
|
6249
|
+
}
|
|
6250
|
+
return llmResult.content;
|
|
6251
|
+
}
|
|
6252
|
+
});
|
|
6253
|
+
return this.deps._passiveCorrectionService;
|
|
6254
|
+
}
|
|
6255
|
+
};
|
|
6256
|
+
|
|
6257
|
+
// src/access-extraction-force-flush.ts
|
|
6258
|
+
async function extractionForceFlush(deps, request, waitForPendingObserveExtraction) {
|
|
6259
|
+
if (!request.sessionKey || typeof request.sessionKey !== "string" || request.sessionKey.trim().length === 0) {
|
|
6260
|
+
throw new EngramAccessInputError("sessionKey is required and must be a non-empty string");
|
|
6261
|
+
}
|
|
6262
|
+
if (request.deadlineMs !== void 0 && (!Number.isFinite(request.deadlineMs) || request.deadlineMs < 0)) {
|
|
6263
|
+
throw new EngramAccessInputError("deadlineMs must be a finite non-negative number");
|
|
6264
|
+
}
|
|
6265
|
+
const authenticatedPrincipal = request.authenticatedPrincipal?.trim();
|
|
6266
|
+
throwIfAborted(request.abortSignal, "extraction force-flush aborted");
|
|
6267
|
+
const namespacesEnabled = resolveNamespaceCapabilities(deps.orchestrator.config).namespaces === true;
|
|
6268
|
+
const sessionPrincipal = namespacesEnabled ? resolvePrincipal(request.sessionKey, deps.orchestrator.config) : void 0;
|
|
6269
|
+
if (namespacesEnabled) {
|
|
6270
|
+
if (!authenticatedPrincipal || sessionPrincipal !== void 0 && sessionPrincipal !== "default" && sessionPrincipal !== authenticatedPrincipal) {
|
|
6271
|
+
throw new EngramAccessInputError("sessionKey is not owned by authenticated principal");
|
|
6272
|
+
}
|
|
6273
|
+
}
|
|
6274
|
+
let committed = false;
|
|
6275
|
+
const markCommitted = () => {
|
|
6276
|
+
if (committed) return;
|
|
6277
|
+
committed = true;
|
|
6278
|
+
request.onCommitted?.();
|
|
6279
|
+
};
|
|
6280
|
+
let abortHandler;
|
|
6281
|
+
try {
|
|
6282
|
+
const scope = await deps.resolveMemoryScopePlan(request);
|
|
6283
|
+
const reservationScopeHint = pendingObserveScopeHint(request);
|
|
6284
|
+
const cancelScopedPendingObserveExtractions = () => {
|
|
6285
|
+
deps.cancelPendingObserveExtractions?.(
|
|
6286
|
+
request.sessionKey,
|
|
6287
|
+
scope.principal,
|
|
6288
|
+
scope.writeNamespace,
|
|
6289
|
+
reservationScopeHint
|
|
6290
|
+
);
|
|
6291
|
+
};
|
|
6292
|
+
if (request.abortSignal?.aborted) cancelScopedPendingObserveExtractions();
|
|
6293
|
+
throwIfAborted(request.abortSignal, "extraction force-flush aborted");
|
|
6294
|
+
if (typeof request.deadlineMs === "number" && request.deadlineMs <= Date.now()) {
|
|
6295
|
+
cancelScopedPendingObserveExtractions();
|
|
6296
|
+
throw new EngramAccessInputError("extraction force-flush deadline exceeded before buffer drain");
|
|
6297
|
+
}
|
|
6298
|
+
abortHandler = cancelScopedPendingObserveExtractions;
|
|
6299
|
+
request.abortSignal?.addEventListener("abort", abortHandler, { once: true });
|
|
6300
|
+
await awaitSessionFlushPhase(
|
|
6301
|
+
() => deps.orchestrator.flushSession(request.sessionKey, {
|
|
6302
|
+
reason: "access_force_flush",
|
|
6303
|
+
abortSignal: request.abortSignal,
|
|
6304
|
+
failOnExtractionFailure: true,
|
|
6305
|
+
extractionDeadlineMs: request.deadlineMs,
|
|
6306
|
+
writeNamespaceOverride: scope.writeNamespace,
|
|
6307
|
+
principalOverride: typeof scope.principal === "string" && scope.principal.length > 0 ? scope.principal : void 0,
|
|
6308
|
+
scopeProfileWritePlan: scope.scopeProfilePlan,
|
|
6309
|
+
onCommitted: markCommitted
|
|
6310
|
+
}),
|
|
6311
|
+
{
|
|
6312
|
+
abortSignal: request.abortSignal,
|
|
6313
|
+
extractionDeadlineMs: request.deadlineMs,
|
|
6314
|
+
reason: "access_force_flush",
|
|
6315
|
+
deadlineStage: "buffer_drain",
|
|
6316
|
+
onDeadline: cancelScopedPendingObserveExtractions
|
|
6317
|
+
}
|
|
6318
|
+
);
|
|
6319
|
+
markCommitted();
|
|
6320
|
+
if (waitForPendingObserveExtraction) {
|
|
6321
|
+
let cancelPendingObserveExtraction;
|
|
6322
|
+
await awaitSessionFlushPhase(
|
|
6323
|
+
() => waitForPendingObserveExtraction(
|
|
6324
|
+
request.sessionKey,
|
|
6325
|
+
scope.principal,
|
|
6326
|
+
scope.writeNamespace,
|
|
6327
|
+
request.abortSignal,
|
|
6328
|
+
(cancel) => {
|
|
6329
|
+
cancelPendingObserveExtraction = cancel;
|
|
6330
|
+
},
|
|
6331
|
+
reservationScopeHint
|
|
6332
|
+
),
|
|
6333
|
+
{
|
|
6334
|
+
abortSignal: request.abortSignal,
|
|
6335
|
+
extractionDeadlineMs: request.deadlineMs,
|
|
6336
|
+
reason: "access_force_flush",
|
|
6337
|
+
deadlineStage: "pending_observe_extraction",
|
|
6338
|
+
onDeadline: () => {
|
|
6339
|
+
cancelScopedPendingObserveExtractions();
|
|
6340
|
+
cancelPendingObserveExtraction?.();
|
|
6341
|
+
}
|
|
6342
|
+
}
|
|
6343
|
+
);
|
|
6344
|
+
}
|
|
6345
|
+
const buffer = deps.orchestrator.buffer;
|
|
6346
|
+
if (buffer && typeof buffer.clearRetainedTurnsForSession === "function") {
|
|
6347
|
+
try {
|
|
6348
|
+
await awaitSessionFlushPhase(
|
|
6349
|
+
() => buffer.clearRetainedTurnsForSession(request.sessionKey, namespacesEnabled ? scope.principal : void 0, {
|
|
6350
|
+
abortSignal: request.abortSignal,
|
|
6351
|
+
deadlineMs: request.deadlineMs
|
|
6352
|
+
}),
|
|
6353
|
+
{
|
|
6354
|
+
abortSignal: request.abortSignal,
|
|
6355
|
+
extractionDeadlineMs: request.deadlineMs,
|
|
6356
|
+
reason: "access_force_flush",
|
|
6357
|
+
deadlineStage: "retained_turn_cleanup"
|
|
6358
|
+
}
|
|
6359
|
+
);
|
|
6360
|
+
} catch (cleanupError) {
|
|
6361
|
+
if (isAbortError(cleanupError) || cleanupError instanceof ExtractionDeadlineError) {
|
|
6362
|
+
throw cleanupError;
|
|
6363
|
+
}
|
|
6364
|
+
log.warn(
|
|
6365
|
+
`extractionForceFlush: retained-turn cleanup failed after a successful flush, continuing: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}`
|
|
6366
|
+
);
|
|
6367
|
+
}
|
|
6368
|
+
}
|
|
6369
|
+
return {
|
|
6370
|
+
flushed: true,
|
|
6371
|
+
sessionKey: request.sessionKey,
|
|
6372
|
+
namespace: deps.legacyResponseNamespaceForScope(scope),
|
|
6373
|
+
effectiveNamespace: scope.writeNamespace
|
|
6374
|
+
};
|
|
6375
|
+
} catch (error) {
|
|
6376
|
+
if (error instanceof SessionOwnershipError) {
|
|
6377
|
+
throw new EngramAccessForbiddenError(error.message);
|
|
6378
|
+
}
|
|
6379
|
+
if (error instanceof ExtractionDeadlineError) {
|
|
6380
|
+
throw new EngramAccessInputError(error.message);
|
|
6381
|
+
}
|
|
6382
|
+
throw error;
|
|
6383
|
+
} finally {
|
|
6384
|
+
if (abortHandler) request.abortSignal?.removeEventListener("abort", abortHandler);
|
|
6385
|
+
}
|
|
6386
|
+
}
|
|
6387
|
+
|
|
6388
|
+
// src/access-observe-write-surface.ts
|
|
5584
6389
|
var AccessObserveWriteSurface = class {
|
|
5585
6390
|
constructor(deps) {
|
|
5586
6391
|
this.deps = deps;
|
|
5587
6392
|
}
|
|
5588
6393
|
deps;
|
|
5589
6394
|
quarantineStoreInstance;
|
|
6395
|
+
pendingObserveExtractions = new PendingObserveExtractionTracker();
|
|
6396
|
+
cancelPendingObserveExtractions(sessionKey, principal, namespace, scopeHint) {
|
|
6397
|
+
this.pendingObserveExtractions.cancel(sessionKey, principal, namespace, scopeHint);
|
|
6398
|
+
}
|
|
5590
6399
|
quarantineStore() {
|
|
5591
6400
|
if (!this.quarantineStoreInstance) {
|
|
5592
6401
|
this.quarantineStoreInstance = new WriteQuarantineStore(
|
|
@@ -5991,111 +6800,144 @@ var AccessObserveWriteSurface = class {
|
|
|
5991
6800
|
throw new EngramAccessInputError(`invalid message role: ${msg.role} (expected 'user' or 'assistant')`);
|
|
5992
6801
|
}
|
|
5993
6802
|
}
|
|
5994
|
-
|
|
6803
|
+
const observePreparation = this.pendingObserveExtractions.reserve(
|
|
6804
|
+
request.sessionKey,
|
|
6805
|
+
pendingObserveScopeHint(request)
|
|
6806
|
+
);
|
|
5995
6807
|
try {
|
|
5996
|
-
scope
|
|
5997
|
-
} catch (err) {
|
|
5998
|
-
if (request.suppressQuarantine !== true) {
|
|
5999
|
-
await this.parkRejectedWrite(err, "observe", request);
|
|
6000
|
-
}
|
|
6001
|
-
throw err;
|
|
6002
|
-
}
|
|
6003
|
-
const writeNamespace = scope.writeNamespace;
|
|
6004
|
-
const namespace = this.deps.legacyResponseNamespaceForScope(scope);
|
|
6005
|
-
const shouldWriteObjectiveState = resolveObjectiveStateCapabilities(this.deps.orchestrator.config).objectiveStateMemory === true && resolveObjectiveStateCapabilities(this.deps.orchestrator.config).objectiveStateSnapshotWrites === true;
|
|
6006
|
-
await this.deps.maybeAttachCodingContext(request.sessionKey, {
|
|
6007
|
-
cwd: request.cwd,
|
|
6008
|
-
projectTag: request.projectTag
|
|
6009
|
-
});
|
|
6010
|
-
const lcmSessionKey = lcmSessionKeyForNamespace(writeNamespace, request.sessionKey, this.deps.orchestrator.config.defaultNamespace) ?? request.sessionKey;
|
|
6011
|
-
if (shouldWriteObjectiveState) {
|
|
6808
|
+
let scope;
|
|
6012
6809
|
try {
|
|
6013
|
-
|
|
6014
|
-
scope.objectiveStateNamespace
|
|
6015
|
-
);
|
|
6016
|
-
await recordObjectiveStateSnapshotsFromObservedMessages({
|
|
6017
|
-
memoryDir: objectiveStateLocation.memoryDir,
|
|
6018
|
-
objectiveStateStoreDir: objectiveStateLocation.objectiveStateStoreDir,
|
|
6019
|
-
objectiveStateMemoryEnabled: resolveObjectiveStateCapabilities(this.deps.orchestrator.config).objectiveStateMemory,
|
|
6020
|
-
objectiveStateSnapshotWritesEnabled: resolveObjectiveStateCapabilities(this.deps.orchestrator.config).objectiveStateSnapshotWrites,
|
|
6021
|
-
sessionKey: request.sessionKey,
|
|
6022
|
-
recordedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6023
|
-
messages: request.messages
|
|
6024
|
-
});
|
|
6810
|
+
scope = await this.deps.resolveMemoryScopePlan(request);
|
|
6025
6811
|
} catch (err) {
|
|
6026
|
-
|
|
6812
|
+
if (request.suppressQuarantine !== true) {
|
|
6813
|
+
await this.parkRejectedWrite(err, "observe", request);
|
|
6814
|
+
}
|
|
6815
|
+
throw err;
|
|
6027
6816
|
}
|
|
6028
|
-
|
|
6029
|
-
|
|
6030
|
-
|
|
6031
|
-
|
|
6032
|
-
|
|
6033
|
-
|
|
6034
|
-
|
|
6035
|
-
|
|
6036
|
-
|
|
6037
|
-
|
|
6038
|
-
|
|
6039
|
-
|
|
6040
|
-
|
|
6041
|
-
|
|
6042
|
-
|
|
6043
|
-
|
|
6044
|
-
|
|
6045
|
-
|
|
6046
|
-
|
|
6047
|
-
|
|
6048
|
-
|
|
6049
|
-
|
|
6050
|
-
|
|
6051
|
-
|
|
6052
|
-
|
|
6053
|
-
|
|
6054
|
-
parts: m.parts,
|
|
6055
|
-
rawContent: m.rawContent,
|
|
6056
|
-
sourceFormat: m.sourceFormat,
|
|
6057
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6058
|
-
...request.sourceConnector ? { sourceConnector: request.sourceConnector } : {}
|
|
6059
|
-
}));
|
|
6060
|
-
const writeNamespaceOverride = resolveNamespaceCapabilities(this.deps.orchestrator.config).namespaces === true ? writeNamespace : void 0;
|
|
6061
|
-
const principalOverride = typeof scope.principal === "string" && scope.principal.length > 0 ? scope.principal : void 0;
|
|
6062
|
-
try {
|
|
6063
|
-
const extractionPromise = this.deps.orchestrator.ingestReplayBatch(turns, {
|
|
6064
|
-
archiveLcm: false,
|
|
6065
|
-
writeNamespaceOverride,
|
|
6066
|
-
principalOverride
|
|
6067
|
-
});
|
|
6068
|
-
extractionPromise.catch((err) => {
|
|
6069
|
-
log.error(`access-observe background extraction failed: ${err}`);
|
|
6070
|
-
});
|
|
6071
|
-
extractionQueued = true;
|
|
6072
|
-
} catch (err) {
|
|
6073
|
-
log.error(`access-observe extraction enqueue failed: ${err}`);
|
|
6817
|
+
const writeNamespace = scope.writeNamespace;
|
|
6818
|
+
observePreparation.setScope(scope.principal, writeNamespace);
|
|
6819
|
+
const namespace = this.deps.legacyResponseNamespaceForScope(scope);
|
|
6820
|
+
const shouldWriteObjectiveState = resolveObjectiveStateCapabilities(this.deps.orchestrator.config).objectiveStateMemory === true && resolveObjectiveStateCapabilities(this.deps.orchestrator.config).objectiveStateSnapshotWrites === true;
|
|
6821
|
+
await this.deps.maybeAttachCodingContext(request.sessionKey, {
|
|
6822
|
+
cwd: request.cwd,
|
|
6823
|
+
projectTag: request.projectTag
|
|
6824
|
+
});
|
|
6825
|
+
const lcmSessionKey = lcmSessionKeyForNamespace(writeNamespace, request.sessionKey, this.deps.orchestrator.config.defaultNamespace) ?? request.sessionKey;
|
|
6826
|
+
if (shouldWriteObjectiveState) {
|
|
6827
|
+
try {
|
|
6828
|
+
const objectiveStateLocation = await this.deps.objectiveStateStoreLocationForNamespace(
|
|
6829
|
+
scope.objectiveStateNamespace
|
|
6830
|
+
);
|
|
6831
|
+
await recordObjectiveStateSnapshotsFromObservedMessages({
|
|
6832
|
+
memoryDir: objectiveStateLocation.memoryDir,
|
|
6833
|
+
objectiveStateStoreDir: objectiveStateLocation.objectiveStateStoreDir,
|
|
6834
|
+
objectiveStateMemoryEnabled: resolveObjectiveStateCapabilities(this.deps.orchestrator.config).objectiveStateMemory,
|
|
6835
|
+
objectiveStateSnapshotWritesEnabled: resolveObjectiveStateCapabilities(this.deps.orchestrator.config).objectiveStateSnapshotWrites,
|
|
6836
|
+
sessionKey: request.sessionKey,
|
|
6837
|
+
recordedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6838
|
+
messages: request.messages
|
|
6839
|
+
});
|
|
6840
|
+
} catch (err) {
|
|
6841
|
+
log.error(`access-observe objective-state snapshot write failed: ${err}`);
|
|
6842
|
+
}
|
|
6074
6843
|
}
|
|
6844
|
+
let lcmArchived = false;
|
|
6845
|
+
if (this.deps.orchestrator.lcmEngine && this.deps.orchestrator.lcmEngine.enabled) {
|
|
6846
|
+
try {
|
|
6847
|
+
this.deps.orchestrator.lcmEngine.enqueueObserveMessages(lcmSessionKey, request.messages);
|
|
6848
|
+
lcmArchived = true;
|
|
6849
|
+
} catch (err) {
|
|
6850
|
+
log.error(`access-observe LCM enqueue failed: ${err}`);
|
|
6851
|
+
}
|
|
6852
|
+
}
|
|
6853
|
+
let extractionQueued = false;
|
|
6854
|
+
if (request.skipExtraction !== true) {
|
|
6855
|
+
const turns = request.messages.map((m) => ({
|
|
6856
|
+
source: "openclaw",
|
|
6857
|
+
// Identity-vs-routing separation (#1505 thread 1, cursor): extraction
|
|
6858
|
+
// derives the provenance principal via `resolvePrincipal(turn.sessionKey)`
|
|
6859
|
+
// and threads `turn.sessionKey` into conversation threading. Feeding the
|
|
6860
|
+
// namespace-PREFIXED `lcmSessionKey` here mis-derived the principal to
|
|
6861
|
+
// `default` (a `<ns>:<key>` string matches no prefix/map rule and fails
|
|
6862
|
+
// the `agent:` heuristic). Pass the ORIGINAL sessionKey so identity is
|
|
6863
|
+
// correct; storage routing is pinned separately via
|
|
6864
|
+
// writeNamespaceOverride below, and the authenticated principal is pinned
|
|
6865
|
+
// via principalOverride.
|
|
6866
|
+
sessionKey: request.sessionKey,
|
|
6867
|
+
role: m.role,
|
|
6868
|
+
content: m.content,
|
|
6869
|
+
parts: m.parts,
|
|
6870
|
+
rawContent: m.rawContent,
|
|
6871
|
+
sourceFormat: m.sourceFormat,
|
|
6872
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6873
|
+
...request.sourceConnector ? { sourceConnector: request.sourceConnector } : {}
|
|
6874
|
+
}));
|
|
6875
|
+
const writeNamespaceOverride = resolveNamespaceCapabilities(this.deps.orchestrator.config).namespaces === true ? writeNamespace : void 0;
|
|
6876
|
+
const principalOverride = typeof scope.principal === "string" && scope.principal.length > 0 ? scope.principal : void 0;
|
|
6877
|
+
if (!observePreparation.isCancelled()) {
|
|
6878
|
+
try {
|
|
6879
|
+
const observeAbortController = new AbortController();
|
|
6880
|
+
const extractionPromise = this.deps.orchestrator.ingestReplayBatch(turns, {
|
|
6881
|
+
archiveLcm: false,
|
|
6882
|
+
writeNamespaceOverride,
|
|
6883
|
+
principalOverride,
|
|
6884
|
+
abortSignal: observeAbortController.signal,
|
|
6885
|
+
...typeof request.authenticatedPrincipal === "string" && request.authenticatedPrincipal.trim().length > 0 ? { sessionOwnerPrincipal: request.authenticatedPrincipal.trim() } : {}
|
|
6886
|
+
});
|
|
6887
|
+
extractionPromise.catch((err) => {
|
|
6888
|
+
log.error(`access-observe background extraction failed: ${err}`);
|
|
6889
|
+
});
|
|
6890
|
+
this.pendingObserveExtractions.track(
|
|
6891
|
+
this.pendingObserveExtractions.key(request.sessionKey, scope.principal, writeNamespace),
|
|
6892
|
+
extractionPromise,
|
|
6893
|
+
observeAbortController
|
|
6894
|
+
);
|
|
6895
|
+
extractionQueued = true;
|
|
6896
|
+
} catch (err) {
|
|
6897
|
+
log.error(`access-observe extraction enqueue failed: ${err}`);
|
|
6898
|
+
}
|
|
6899
|
+
}
|
|
6900
|
+
}
|
|
6901
|
+
log.info(
|
|
6902
|
+
`access-observe namespace=${namespace} effectiveNamespace=${writeNamespace} sessionKey=${request.sessionKey} messages=${request.messages.length} lcm=${lcmArchived} extraction=${extractionQueued}`
|
|
6903
|
+
);
|
|
6904
|
+
return {
|
|
6905
|
+
accepted: request.messages.length,
|
|
6906
|
+
sessionKey: request.sessionKey,
|
|
6907
|
+
namespace,
|
|
6908
|
+
effectiveNamespace: writeNamespace,
|
|
6909
|
+
scopeDebug: {
|
|
6910
|
+
principal: scope.principal,
|
|
6911
|
+
explicitNamespace: scope.explicitNamespace,
|
|
6912
|
+
baseNamespace: scope.baseNamespace,
|
|
6913
|
+
writeNamespace: scope.writeNamespace,
|
|
6914
|
+
codingOverlayApplied: scope.codingOverlayApplied,
|
|
6915
|
+
readNamespaces: scope.readNamespaces,
|
|
6916
|
+
scopeProfile: scope.scopeProfile,
|
|
6917
|
+
writeLayer: scope.writeLayer,
|
|
6918
|
+
layers: scope.layers,
|
|
6919
|
+
promotionTargets: scope.promotionTargets
|
|
6920
|
+
},
|
|
6921
|
+
lcmArchived,
|
|
6922
|
+
extractionQueued
|
|
6923
|
+
};
|
|
6924
|
+
} finally {
|
|
6925
|
+
observePreparation.release();
|
|
6075
6926
|
}
|
|
6076
|
-
|
|
6077
|
-
|
|
6927
|
+
}
|
|
6928
|
+
async extractionForceFlush(request) {
|
|
6929
|
+
return extractionForceFlush(
|
|
6930
|
+
this.deps,
|
|
6931
|
+
request,
|
|
6932
|
+
(sessionKey, principal, namespace, abortSignal, registerCancellation, scopeHint) => this.pendingObserveExtractions.wait(
|
|
6933
|
+
sessionKey,
|
|
6934
|
+
principal,
|
|
6935
|
+
namespace,
|
|
6936
|
+
abortSignal,
|
|
6937
|
+
registerCancellation,
|
|
6938
|
+
scopeHint
|
|
6939
|
+
)
|
|
6078
6940
|
);
|
|
6079
|
-
return {
|
|
6080
|
-
accepted: request.messages.length,
|
|
6081
|
-
sessionKey: request.sessionKey,
|
|
6082
|
-
namespace,
|
|
6083
|
-
effectiveNamespace: writeNamespace,
|
|
6084
|
-
scopeDebug: {
|
|
6085
|
-
principal: scope.principal,
|
|
6086
|
-
explicitNamespace: scope.explicitNamespace,
|
|
6087
|
-
baseNamespace: scope.baseNamespace,
|
|
6088
|
-
writeNamespace: scope.writeNamespace,
|
|
6089
|
-
codingOverlayApplied: scope.codingOverlayApplied,
|
|
6090
|
-
readNamespaces: scope.readNamespaces,
|
|
6091
|
-
scopeProfile: scope.scopeProfile,
|
|
6092
|
-
writeLayer: scope.writeLayer,
|
|
6093
|
-
layers: scope.layers,
|
|
6094
|
-
promotionTargets: scope.promotionTargets
|
|
6095
|
-
},
|
|
6096
|
-
lcmArchived,
|
|
6097
|
-
extractionQueued
|
|
6098
|
-
};
|
|
6099
6941
|
}
|
|
6100
6942
|
async workTask(request) {
|
|
6101
6943
|
const STATUSES = /* @__PURE__ */ new Set(["todo", "in_progress", "blocked", "done", "cancelled"]);
|
|
@@ -7222,6 +8064,15 @@ import * as nodePath2 from "path";
|
|
|
7222
8064
|
|
|
7223
8065
|
// src/orchestration/recall-result-formatter.ts
|
|
7224
8066
|
import path8 from "path";
|
|
8067
|
+
|
|
8068
|
+
// src/connectors/label.ts
|
|
8069
|
+
var CONNECTOR_LABEL_MAX_LENGTH = 64;
|
|
8070
|
+
|
|
8071
|
+
// src/orchestration/recall-result-formatter.ts
|
|
8072
|
+
function renderConnectorLabel(connector) {
|
|
8073
|
+
if (!connector || !CONNECTOR_ID_PATTERN.test(connector)) return null;
|
|
8074
|
+
return connector.length <= CONNECTOR_LABEL_MAX_LENGTH ? connector : `${connector.slice(0, CONNECTOR_LABEL_MAX_LENGTH - 1)}\u2026`;
|
|
8075
|
+
}
|
|
7225
8076
|
function hasIdentityRecoveryIntent(prompt) {
|
|
7226
8077
|
const text = typeof prompt === "string" ? prompt.toLowerCase() : "";
|
|
7227
8078
|
if (!text) return false;
|
|
@@ -7306,14 +8157,16 @@ var RecallResultFormatter = class {
|
|
|
7306
8157
|
${snippet}`;
|
|
7307
8158
|
const handle = handleByIndex.get(i);
|
|
7308
8159
|
const withHandle = handle ? `${head.trimEnd()} ${handle}` : head.trimEnd();
|
|
8160
|
+
const connectorLabel = renderConnectorLabel(r.sourceConnector);
|
|
8161
|
+
const withConnector = connectorLabel ? `${withHandle} [agent: ${connectorLabel}]` : withHandle;
|
|
7309
8162
|
if (hedgeMap) {
|
|
7310
8163
|
const item = trustResultFor(hedgeMap, r);
|
|
7311
8164
|
if (item) {
|
|
7312
8165
|
const hedge = renderEpistemicHedge(item.trust);
|
|
7313
|
-
if (hedge.length > 0) return `${
|
|
8166
|
+
if (hedge.length > 0) return `${withConnector} ${hedge}`;
|
|
7314
8167
|
}
|
|
7315
8168
|
}
|
|
7316
|
-
return
|
|
8169
|
+
return withConnector;
|
|
7317
8170
|
});
|
|
7318
8171
|
return { heading: `## ${title}`, entries };
|
|
7319
8172
|
}
|
|
@@ -9189,54 +10042,19 @@ var EngramAccessService = class {
|
|
|
9189
10042
|
principal,
|
|
9190
10043
|
this.orchestrator.config
|
|
9191
10044
|
);
|
|
9192
|
-
const
|
|
9193
|
-
|
|
9194
|
-
|
|
9195
|
-
|
|
9196
|
-
|
|
9197
|
-
|
|
9198
|
-
if (attachedContext) {
|
|
9199
|
-
this.orchestrator.setCodingContextForSession(
|
|
9200
|
-
request.sessionKey,
|
|
9201
|
-
attachedContext
|
|
9202
|
-
);
|
|
9203
|
-
seededContext = true;
|
|
9204
|
-
}
|
|
9205
|
-
}
|
|
9206
|
-
const clearSeededContext = () => {
|
|
9207
|
-
if (seededContext && hasSession) {
|
|
9208
|
-
this.orchestrator.setCodingContextForSession(request.sessionKey, null);
|
|
9209
|
-
}
|
|
9210
|
-
};
|
|
10045
|
+
const {
|
|
10046
|
+
overlay: codingOverlay,
|
|
10047
|
+
profilePlan
|
|
10048
|
+
} = await this.resolveCodingScopeInputs(request);
|
|
10049
|
+
const overlaidBase = codingOverlay ? combineNamespaces(baseNamespace, codingOverlay.namespace) : baseNamespace;
|
|
10050
|
+
const codingOverlayApplied = overlaidBase !== baseNamespace;
|
|
9211
10051
|
const assertWriteNamespaceAllowed = (namespace) => {
|
|
9212
|
-
|
|
9213
|
-
this.assertTokenCanWriteNamespace(namespace);
|
|
9214
|
-
} catch (error) {
|
|
9215
|
-
clearSeededContext();
|
|
9216
|
-
throw error;
|
|
9217
|
-
}
|
|
10052
|
+
this.assertTokenCanWriteNamespace(namespace);
|
|
9218
10053
|
};
|
|
9219
|
-
const overlaidBase = this.orchestrator.applyCodingNamespaceOverlay(
|
|
9220
|
-
request.sessionKey,
|
|
9221
|
-
baseNamespace
|
|
9222
|
-
);
|
|
9223
|
-
const codingOverlayApplied = overlaidBase !== baseNamespace;
|
|
9224
|
-
const codingOverlay = overlayEligible ? resolveCodingNamespaceOverlay(
|
|
9225
|
-
attachedContext,
|
|
9226
|
-
this.orchestrator.config.codingMode,
|
|
9227
|
-
this.orchestrator.config.defaultNamespace
|
|
9228
|
-
) : null;
|
|
9229
|
-
const profilePlan = resolveScopeProfilePlan({
|
|
9230
|
-
config: this.orchestrator.config,
|
|
9231
|
-
principal,
|
|
9232
|
-
codingContext: attachedContext,
|
|
9233
|
-
codingOverlay
|
|
9234
|
-
});
|
|
9235
10054
|
if (profilePlan) {
|
|
9236
10055
|
const selectedLayer = profilePlan.layers.find((layer) => layer.id === profilePlan.writeLayer);
|
|
9237
10056
|
const writeNamespaceReadable = profilePlan.writeNamespace.length > 0 && profilePlan.readNamespaces.includes(profilePlan.writeNamespace);
|
|
9238
10057
|
if (!selectedLayer?.writable || !writeNamespaceReadable) {
|
|
9239
|
-
clearSeededContext();
|
|
9240
10058
|
throw new NamespaceNotWritableError(
|
|
9241
10059
|
profilePlan.writeNamespace,
|
|
9242
10060
|
principal,
|
|
@@ -9266,6 +10084,7 @@ var EngramAccessService = class {
|
|
|
9266
10084
|
objectiveStateNamespace: profilePlan.writeNamespace,
|
|
9267
10085
|
readNamespaces: readNamespaces2,
|
|
9268
10086
|
scopeProfile: profilePlan.profileId,
|
|
10087
|
+
scopeProfilePlan: profilePlan,
|
|
9269
10088
|
writeLayer: profilePlan.writeLayer,
|
|
9270
10089
|
layers: profilePlan.layers,
|
|
9271
10090
|
promotionTargets: profilePlan.promotionTargets,
|
|
@@ -9281,7 +10100,6 @@ var EngramAccessService = class {
|
|
|
9281
10100
|
);
|
|
9282
10101
|
const willWriteObjectiveState = resolveObjectiveStateCapabilities(this.orchestrator.config).objectiveStateMemory === true && resolveObjectiveStateCapabilities(this.orchestrator.config).objectiveStateSnapshotWrites === true;
|
|
9283
10102
|
if (willWriteObjectiveState && resolveNamespaceCapabilities(this.orchestrator.config).namespaces === true && !canWriteNamespace(principal, baseNamespace, this.orchestrator.config)) {
|
|
9284
|
-
clearSeededContext();
|
|
9285
10103
|
throw new NamespaceNotWritableError(baseNamespace, principal);
|
|
9286
10104
|
}
|
|
9287
10105
|
assertWriteNamespaceAllowed(writeNamespace2);
|
|
@@ -9304,7 +10122,6 @@ var EngramAccessService = class {
|
|
|
9304
10122
|
};
|
|
9305
10123
|
}
|
|
9306
10124
|
if (!canWriteNamespace(principal, baseNamespace, this.orchestrator.config)) {
|
|
9307
|
-
clearSeededContext();
|
|
9308
10125
|
throw new NamespaceNotWritableError(baseNamespace, principal);
|
|
9309
10126
|
}
|
|
9310
10127
|
const writeNamespace = overlaidBase;
|
|
@@ -11055,6 +11872,12 @@ var EngramAccessService = class {
|
|
|
11055
11872
|
namespace
|
|
11056
11873
|
};
|
|
11057
11874
|
}
|
|
11875
|
+
async extractionForceFlush(request) {
|
|
11876
|
+
return delegateExtractionForceFlush(this.accessObserveWriteSurface, request);
|
|
11877
|
+
}
|
|
11878
|
+
cancelPendingObserveExtractions(sessionKey, principal, namespace, scopeHint) {
|
|
11879
|
+
this.accessObserveWriteSurface.cancelPendingObserveExtractions(sessionKey, principal, namespace, scopeHint);
|
|
11880
|
+
}
|
|
11058
11881
|
async lcmCompactionRecord(request) {
|
|
11059
11882
|
if (!request.sessionKey || typeof request.sessionKey !== "string" || request.sessionKey.trim().length === 0) {
|
|
11060
11883
|
throw new EngramAccessInputError("sessionKey is required and must be a non-empty string");
|
|
@@ -12464,7 +13287,6 @@ export {
|
|
|
12464
13287
|
isCodegraphToolName,
|
|
12465
13288
|
DELTA_SUBCOMMANDS,
|
|
12466
13289
|
CorrectionContractError,
|
|
12467
|
-
createCorrectionService,
|
|
12468
13290
|
detectPassiveCorrections,
|
|
12469
13291
|
capturePassiveCorrections,
|
|
12470
13292
|
clusterByKey,
|
|
@@ -12486,6 +13308,8 @@ export {
|
|
|
12486
13308
|
resolveNamespaceWritablePreflight,
|
|
12487
13309
|
resolveAuthorizedNamespaceWritablePreflight,
|
|
12488
13310
|
resolveQueryNamespaceWritablePreflight,
|
|
13311
|
+
SessionContextCoordinator,
|
|
13312
|
+
extractionForceFlush,
|
|
12489
13313
|
AccessObserveWriteSurface,
|
|
12490
13314
|
AccessLcmSurface,
|
|
12491
13315
|
hasIdentityRecoveryIntent,
|
|
@@ -12501,4 +13325,4 @@ export {
|
|
|
12501
13325
|
EngramAccessService,
|
|
12502
13326
|
AccessAdminOpsSurface
|
|
12503
13327
|
};
|
|
12504
|
-
//# sourceMappingURL=chunk-
|
|
13328
|
+
//# sourceMappingURL=chunk-J3ZGPYXB.js.map
|