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