@remnic/core 9.29.1 → 9.30.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 +11 -11
- package/dist/access-admin-ops-surface.js +19 -18
- package/dist/access-authorization-probe.d.ts +11 -11
- package/dist/access-authorization-probe.js +20 -19
- package/dist/access-boundary.d.ts +11 -11
- package/dist/access-boundary.js +19 -18
- package/dist/access-citation-namespace.js +2 -2
- package/dist/access-cli.js +45 -44
- package/dist/access-cli.js.map +1 -1
- package/dist/access-health-types.d.ts +1 -1
- package/dist/access-http-lcm-compaction.d.ts +11 -11
- package/dist/access-http.d.ts +11 -11
- package/dist/access-http.js +25 -24
- package/dist/access-identity-continuity-surface.d.ts +8 -8
- package/dist/access-identity-continuity-surface.js +19 -18
- package/dist/access-lcm-surface.d.ts +10 -10
- package/dist/access-lcm-surface.js +19 -18
- package/dist/access-mcp.d.ts +11 -11
- package/dist/access-mcp.js +23 -22
- package/dist/access-memory-search-fanout.d.ts +2 -2
- package/dist/{access-namespace-preflight-DCXBkDp0.d.ts → access-namespace-preflight-VfXssvoI.d.ts} +1 -1
- package/dist/access-namespace-preflight.d.ts +3 -3
- package/dist/access-namespace-preflight.js +19 -18
- package/dist/access-observe-write-surface.d.ts +10 -10
- package/dist/access-observe-write-surface.js +19 -18
- package/dist/access-operations-batch.js +20 -19
- package/dist/access-operations.d.ts +11 -11
- package/dist/access-operations.js +22 -21
- package/dist/access-recall-concurrency.d.ts +11 -11
- package/dist/access-recall-concurrency.js +19 -18
- package/dist/access-recall-response.d.ts +10 -10
- package/dist/access-recall-response.js +19 -18
- package/dist/access-recall-surface.d.ts +10 -10
- package/dist/access-recall-surface.js +19 -18
- package/dist/access-schema.js +3 -3
- package/dist/{access-service-DvPW_M5j.d.ts → access-service-B5RwVsTV.d.ts} +7 -7
- package/dist/access-service.d.ts +11 -11
- package/dist/access-service.js +19 -18
- package/dist/access-surface-catalog.d.ts +11 -11
- package/dist/access-wearables-meetings-surface.d.ts +4 -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 +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 +3 -2
- package/dist/briefing.js +10 -9
- package/dist/buffer-surprise-report.d.ts +1 -1
- package/dist/buffer.d.ts +3 -2
- 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/{catalog-BIVgftWu.d.ts → catalog-V7inUQdp.d.ts} +1 -1
- package/dist/causal-behavior.d.ts +1 -1
- package/dist/causal-consolidation.d.ts +1 -1
- package/dist/causal-consolidation.js +11 -10
- package/dist/causal-consolidation.js.map +1 -1
- package/dist/causal-trajectory-graph.d.ts +1 -1
- package/dist/{chunk-FZRQZW4H.js → chunk-2EUVEDF5.js} +2 -2
- package/dist/{chunk-PBUZNGMX.js → chunk-4WKA6I65.js} +20 -20
- package/dist/{chunk-PBUZNGMX.js.map → chunk-4WKA6I65.js.map} +1 -1
- package/dist/{chunk-AIK5W3IW.js → chunk-5TFP4CUL.js} +68 -2
- package/dist/chunk-5TFP4CUL.js.map +1 -0
- package/dist/{chunk-3JNDOAQ2.js → chunk-5W4ZLBEZ.js} +9 -9
- package/dist/{chunk-5ZCUDWD4.js → chunk-62U4J2GN.js} +2 -2
- package/dist/{chunk-IGPEJVBY.js → chunk-66772WBP.js} +2 -2
- package/dist/{chunk-EP5BVCRI.js → chunk-6BNE62PM.js} +2 -2
- package/dist/{chunk-AAP5T6QG.js → chunk-6DNMUYEE.js} +2 -2
- package/dist/{chunk-35DL7IOI.js → chunk-6FUPCJUL.js} +7 -7
- package/dist/{chunk-JP3YPDAW.js → chunk-6U7F52DE.js} +19 -19
- package/dist/{chunk-E4OCKU67.js → chunk-7XC2HX75.js} +2 -2
- package/dist/{chunk-OVRQLAYR.js → chunk-AZ5BTEKX.js} +2 -2
- package/dist/{chunk-2AXMQWCN.js → chunk-CZRYLSSW.js} +3 -3
- package/dist/chunk-FBUE6PD3.js +1769 -0
- package/dist/chunk-FBUE6PD3.js.map +1 -0
- package/dist/{chunk-PTSNLEXK.js → chunk-FDAMS4PK.js} +2 -2
- package/dist/{chunk-WL5EBRDH.js → chunk-FFAZ2XFU.js} +9 -8
- package/dist/chunk-FFAZ2XFU.js.map +1 -0
- package/dist/{chunk-2GXM5N5A.js → chunk-GIBMDSJ2.js} +2 -2
- package/dist/{chunk-E5OBR6CJ.js → chunk-H5CPS5JP.js} +3 -3
- package/dist/{chunk-2D7FEUCK.js → chunk-I5NLEENJ.js} +2 -2
- package/dist/{chunk-DRBXHRXE.js → chunk-IB26HVAJ.js} +2 -2
- package/dist/{chunk-QDKK63Y7.js → chunk-IC6CBHCA.js} +3 -3
- package/dist/{chunk-IAEAFLF2.js → chunk-JCBWCYEJ.js} +2 -2
- package/dist/{chunk-3PDOVUHC.js → chunk-KXB4VXHY.js} +2 -2
- package/dist/{chunk-WU7TTVOD.js → chunk-LBOD4U5B.js} +7 -7
- package/dist/{chunk-UBKEQOTD.js → chunk-LGHKJABJ.js} +3 -3
- package/dist/{chunk-VSURVXKY.js → chunk-M3C2V3PV.js} +10 -10
- package/dist/{chunk-OFHFH655.js → chunk-MJCGLM25.js} +8 -8
- package/dist/{chunk-OYJKSZIQ.js → chunk-NHWB6HG2.js} +2 -2
- package/dist/{chunk-TC3VNKGX.js → chunk-NM2WP3B7.js} +4 -4
- package/dist/{chunk-GAWOEQEQ.js → chunk-P5PXWTW7.js} +2 -2
- package/dist/chunk-PH3ZWL3W.js +786 -0
- package/dist/chunk-PH3ZWL3W.js.map +1 -0
- package/dist/{chunk-FUYEVEX7.js → chunk-PUS63Q3G.js} +24 -22
- package/dist/{chunk-FUYEVEX7.js.map → chunk-PUS63Q3G.js.map} +1 -1
- package/dist/{chunk-2QMKMVHH.js → chunk-QNWXCJ76.js} +2 -2
- package/dist/{chunk-JMQUBRV6.js → chunk-RGIWINDN.js} +340 -771
- package/dist/chunk-RGIWINDN.js.map +1 -0
- package/dist/{chunk-WRFBW2TT.js → chunk-SPJXKAVF.js} +3 -3
- package/dist/{chunk-HKJCMOT6.js → chunk-TH2LSRMG.js} +2 -2
- package/dist/{chunk-CW4AGY3G.js → chunk-VI2JQPNQ.js} +2 -2
- package/dist/{chunk-OP6F6L3S.js → chunk-W5EG6LE3.js} +2 -2
- package/dist/{chunk-DEBHXHJR.js → chunk-WIPEXG6R.js} +2 -2
- package/dist/{chunk-SH6YO3LT.js → chunk-WVO4G37W.js} +2 -2
- package/dist/{chunk-7L45JFPW.js → chunk-YTQNQ4KB.js} +14 -14
- package/dist/{chunk-PKRIQL3V.js → chunk-YTSNAUXN.js} +2 -2
- package/dist/{chunk-5QDRGWT2.js → chunk-ZPSVBSOF.js} +4 -4
- package/dist/{cli-CxoSOiG0.d.ts → cli-C4GbETPC.d.ts} +5 -5
- package/dist/cli.d.ts +13 -13
- package/dist/cli.js +36 -35
- package/dist/compounding/engine.d.ts +3 -2
- package/dist/compounding/engine.js +10 -9
- 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 +3 -3
- package/dist/connectors/codex-materialize-runner.d.ts +1 -1
- package/dist/connectors/codex-materialize-runner.js +10 -9
- package/dist/connectors/codex-materialize.d.ts +1 -1
- package/dist/connectors/index.d.ts +1 -1
- package/dist/connectors/index.js +10 -9
- package/dist/consolidation-provenance-check.d.ts +3 -2
- package/dist/consolidation-undo.d.ts +3 -2
- package/dist/contradiction/index.d.ts +3 -2
- package/dist/conversation-index/backend.d.ts +1 -1
- package/dist/conversation-index/chunker.d.ts +1 -1
- package/dist/conversation-index/faiss-adapter.d.ts +1 -1
- package/dist/conversation-index/indexer.d.ts +1 -1
- package/dist/conversation-index/search.d.ts +1 -1
- package/dist/corpus-watermark.d.ts +1 -1
- package/dist/corpus-watermark.js +12 -11
- 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 +3 -2
- package/dist/entity-retrieval.js +10 -9
- package/dist/entity-schema.d.ts +1 -1
- package/dist/explicit-capture.d.ts +52 -10
- package/dist/explicit-capture.js +13 -1
- 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 +1 -1
- package/dist/extraction.d.ts +1 -1
- package/dist/fallback-llm.d.ts +1 -1
- package/dist/{forget-HRPLVB3W.js → forget-4UY2EOKH.js} +3 -3
- 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 +47 -45
- package/dist/intent.d.ts +1 -1
- package/dist/lcm/engine.d.ts +1 -1
- package/dist/lcm/index.d.ts +1 -1
- package/dist/lcm/tools.d.ts +1 -1
- package/dist/lifecycle.d.ts +1 -1
- package/dist/live-connectors-runner.d.ts +1 -1
- package/dist/local-llm.d.ts +1 -1
- package/dist/local-model-endpoint.d.ts +1 -1
- package/dist/maintenance/memory-governance.d.ts +1 -1
- package/dist/maintenance/memory-governance.js +10 -9
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +10 -9
- package/dist/maintenance/rebuild-memory-projection.d.ts +3 -2
- package/dist/maintenance/rebuild-memory-projection.js +11 -10
- package/dist/{maintenance-Cb-PjxQd.d.ts → maintenance-CL30NWtc.d.ts} +3 -3
- package/dist/mcp-memory-inspector-app.d.ts +11 -11
- package/dist/memory-action-policy.d.ts +1 -1
- package/dist/memory-cache.d.ts +1 -1
- package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
- package/dist/memory-projection-store.d.ts +1 -1
- package/dist/memory-provenance.d.ts +1 -1
- package/dist/memory-worth-outcomes.d.ts +3 -2
- package/dist/models-json.d.ts +1 -1
- package/dist/namespaces/migrate.d.ts +4 -3
- package/dist/namespaces/migrate.js +11 -10
- package/dist/namespaces/principal.d.ts +1 -1
- package/dist/namespaces/search.d.ts +1 -1
- package/dist/namespaces/storage.d.ts +4 -3
- package/dist/namespaces/storage.js +10 -9
- 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 +5 -5
- package/dist/offline-sync.js +2 -2
- package/dist/operator-doctor-corpus.d.ts +1 -1
- package/dist/operator-doctor-corpus.js +13 -12
- package/dist/operator-doctor-replica.d.ts +1 -1
- package/dist/operator-toolkit.d.ts +4 -3
- package/dist/operator-toolkit.js +18 -17
- package/dist/orchestration/compression-guideline-coordinator.d.ts +3 -2
- package/dist/orchestration/maintenance.d.ts +5 -4
- package/dist/orchestration/maintenance.js +15 -14
- package/dist/{orchestrator-5GKqb_HL.d.ts → orchestrator-CKTCRwWV.d.ts} +7 -7
- package/dist/orchestrator.d.ts +8 -8
- package/dist/orchestrator.js +45 -44
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/{pipeline-3Qi1TpRo.d.ts → pipeline-B7wj4rRZ.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/{purge-YSGX5BOG.js → purge-533FZLS4.js} +16 -9
- package/dist/purge-533FZLS4.js.map +1 -0
- package/dist/qmd-preflight.d.ts +2 -2
- package/dist/{qmd-D9JqzzRX.d.ts → qmd-q9tg4dHp.d.ts} +1 -1
- package/dist/qmd-recall-cache.d.ts +1 -1
- package/dist/qmd.d.ts +2 -2
- 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-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-state.js +2 -2
- 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-renderer.d.ts +1 -1
- package/dist/recall-xray.d.ts +1 -1
- 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-peers-config.d.ts +1 -1
- package/dist/resolve-auth-token.d.ts +1 -1
- package/dist/resume-bundles.js +4 -4
- 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-C4g6_UdP.d.ts → scope-profiles-CWDyglPM.d.ts} +1 -1
- package/dist/search/embed-helper.d.ts +1 -1
- package/dist/search/factory.d.ts +1 -1
- package/dist/search/index.d.ts +1 -1
- package/dist/search/lancedb-backend.d.ts +1 -1
- package/dist/search/meilisearch-backend.d.ts +1 -1
- package/dist/search/noop-backend.d.ts +1 -1
- package/dist/search/orama-backend.d.ts +1 -1
- package/dist/search/port.d.ts +1 -1
- package/dist/search/remote-backend.d.ts +1 -1
- package/dist/secure-store/index.js +2 -2
- package/dist/{semantic-consolidation-BrxqnzTW.d.ts → semantic-consolidation-BUE3deLn.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +11 -10
- package/dist/semantic-rule-promotion.js +10 -9
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/semantic-rule-verifier.js +10 -9
- package/dist/{service-Bi1JgxdP.d.ts → service-CXgM0bQG.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-CcH6yPk2.d.ts → storage-DysJq-XH.d.ts} +163 -27
- package/dist/storage.d.ts +3 -2
- package/dist/storage.js +12 -10
- package/dist/summarizer.d.ts +1 -1
- package/dist/summarizer.js +3 -3
- package/dist/summary-snapshot.d.ts +1 -1
- package/dist/summary-snapshot.js +2 -2
- package/dist/temporal-supersession.d.ts +3 -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 +3 -2
- package/dist/tier-routing.d.ts +1 -1
- package/dist/topics.d.ts +1 -1
- package/dist/transcript.d.ts +1 -1
- package/dist/trust-score-stage.d.ts +1 -1
- package/dist/trust-score.d.ts +1 -1
- package/dist/{types-Dg0w9ADr.d.ts → types-aPPzhnjT.d.ts} +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/utility-runtime.d.ts +1 -1
- package/dist/utils/serialize-mutations.d.ts +11 -7
- package/dist/utils/serialize-mutations.js +1 -1
- package/dist/verified-recall.js +10 -9
- package/dist/write-envelope.d.ts +1 -1
- package/package.json +2 -2
- package/src/access-observe-write-surface.ts +1 -1
- package/src/access-service-coding-write.test.ts +40 -0
- package/src/explicit-capture.test.ts +1110 -1
- package/src/explicit-capture.ts +534 -135
- package/src/maintenance/purge.test.ts +157 -1
- package/src/maintenance/purge.ts +15 -9
- package/src/secure-store/secure-fs.ts +78 -1
- package/src/storage/content-hash-index.ts +43 -17
- package/src/storage/tombstone-blocked-capture-index.ts +562 -0
- package/src/storage/tombstone-blocked-capture-mutation.ts +284 -0
- package/src/storage/tombstone-blocked-capture-sync.ts +872 -0
- package/src/storage-fact-hash-index-defer.test.ts +2900 -57
- package/src/storage.ts +266 -265
- package/src/testing/subjects/tombstone-blocked-capture.test.ts +181 -0
- package/src/utils/serialize-mutations.test.ts +4 -1
- package/src/utils/serialize-mutations.ts +26 -27
- package/dist/chunk-55MDBZLC.js +0 -490
- package/dist/chunk-55MDBZLC.js.map +0 -1
- package/dist/chunk-AIK5W3IW.js.map +0 -1
- package/dist/chunk-JMQUBRV6.js.map +0 -1
- package/dist/chunk-WL5EBRDH.js.map +0 -1
- package/dist/purge-YSGX5BOG.js.map +0 -1
- /package/dist/{chunk-FZRQZW4H.js.map → chunk-2EUVEDF5.js.map} +0 -0
- /package/dist/{chunk-3JNDOAQ2.js.map → chunk-5W4ZLBEZ.js.map} +0 -0
- /package/dist/{chunk-5ZCUDWD4.js.map → chunk-62U4J2GN.js.map} +0 -0
- /package/dist/{chunk-IGPEJVBY.js.map → chunk-66772WBP.js.map} +0 -0
- /package/dist/{chunk-EP5BVCRI.js.map → chunk-6BNE62PM.js.map} +0 -0
- /package/dist/{chunk-AAP5T6QG.js.map → chunk-6DNMUYEE.js.map} +0 -0
- /package/dist/{chunk-35DL7IOI.js.map → chunk-6FUPCJUL.js.map} +0 -0
- /package/dist/{chunk-JP3YPDAW.js.map → chunk-6U7F52DE.js.map} +0 -0
- /package/dist/{chunk-E4OCKU67.js.map → chunk-7XC2HX75.js.map} +0 -0
- /package/dist/{chunk-OVRQLAYR.js.map → chunk-AZ5BTEKX.js.map} +0 -0
- /package/dist/{chunk-2AXMQWCN.js.map → chunk-CZRYLSSW.js.map} +0 -0
- /package/dist/{chunk-PTSNLEXK.js.map → chunk-FDAMS4PK.js.map} +0 -0
- /package/dist/{chunk-2GXM5N5A.js.map → chunk-GIBMDSJ2.js.map} +0 -0
- /package/dist/{chunk-E5OBR6CJ.js.map → chunk-H5CPS5JP.js.map} +0 -0
- /package/dist/{chunk-2D7FEUCK.js.map → chunk-I5NLEENJ.js.map} +0 -0
- /package/dist/{chunk-DRBXHRXE.js.map → chunk-IB26HVAJ.js.map} +0 -0
- /package/dist/{chunk-QDKK63Y7.js.map → chunk-IC6CBHCA.js.map} +0 -0
- /package/dist/{chunk-IAEAFLF2.js.map → chunk-JCBWCYEJ.js.map} +0 -0
- /package/dist/{chunk-3PDOVUHC.js.map → chunk-KXB4VXHY.js.map} +0 -0
- /package/dist/{chunk-WU7TTVOD.js.map → chunk-LBOD4U5B.js.map} +0 -0
- /package/dist/{chunk-UBKEQOTD.js.map → chunk-LGHKJABJ.js.map} +0 -0
- /package/dist/{chunk-VSURVXKY.js.map → chunk-M3C2V3PV.js.map} +0 -0
- /package/dist/{chunk-OFHFH655.js.map → chunk-MJCGLM25.js.map} +0 -0
- /package/dist/{chunk-OYJKSZIQ.js.map → chunk-NHWB6HG2.js.map} +0 -0
- /package/dist/{chunk-TC3VNKGX.js.map → chunk-NM2WP3B7.js.map} +0 -0
- /package/dist/{chunk-GAWOEQEQ.js.map → chunk-P5PXWTW7.js.map} +0 -0
- /package/dist/{chunk-2QMKMVHH.js.map → chunk-QNWXCJ76.js.map} +0 -0
- /package/dist/{chunk-WRFBW2TT.js.map → chunk-SPJXKAVF.js.map} +0 -0
- /package/dist/{chunk-HKJCMOT6.js.map → chunk-TH2LSRMG.js.map} +0 -0
- /package/dist/{chunk-CW4AGY3G.js.map → chunk-VI2JQPNQ.js.map} +0 -0
- /package/dist/{chunk-OP6F6L3S.js.map → chunk-W5EG6LE3.js.map} +0 -0
- /package/dist/{chunk-DEBHXHJR.js.map → chunk-WIPEXG6R.js.map} +0 -0
- /package/dist/{chunk-SH6YO3LT.js.map → chunk-WVO4G37W.js.map} +0 -0
- /package/dist/{chunk-7L45JFPW.js.map → chunk-YTQNQ4KB.js.map} +0 -0
- /package/dist/{chunk-PKRIQL3V.js.map → chunk-YTSNAUXN.js.map} +0 -0
- /package/dist/{chunk-5QDRGWT2.js.map → chunk-ZPSVBSOF.js.map} +0 -0
- /package/dist/{forget-HRPLVB3W.js.map → forget-4UY2EOKH.js.map} +0 -0
package/dist/chunk-55MDBZLC.js
DELETED
|
@@ -1,490 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
TAG_LIMITS,
|
|
3
|
-
composeMemoryEnvelope
|
|
4
|
-
} from "./chunk-CGASUJVP.js";
|
|
5
|
-
import {
|
|
6
|
-
sanitizeMemoryContent
|
|
7
|
-
} from "./chunk-5GKPFL3S.js";
|
|
8
|
-
import {
|
|
9
|
-
isSafeRouteNamespace
|
|
10
|
-
} from "./chunk-U3PN77QT.js";
|
|
11
|
-
import {
|
|
12
|
-
resolveNamespaceCapabilities
|
|
13
|
-
} from "./chunk-2XRE6FLM.js";
|
|
14
|
-
|
|
15
|
-
// src/explicit-capture.ts
|
|
16
|
-
import { randomUUID } from "crypto";
|
|
17
|
-
var INLINE_NOTE_RE = /<memory_note>([\s\S]{0,100000}?)<\/memory_note>/gi;
|
|
18
|
-
var INLINE_NOTE_MARKUP_RE = /<memory_note>[\s\S]{0,100000}?<\/memory_note>/i;
|
|
19
|
-
var INLINE_ALLOWED_CATEGORIES = /* @__PURE__ */ new Set([
|
|
20
|
-
"fact",
|
|
21
|
-
"preference",
|
|
22
|
-
"correction",
|
|
23
|
-
"entity",
|
|
24
|
-
"decision",
|
|
25
|
-
"relationship",
|
|
26
|
-
"principle",
|
|
27
|
-
"commitment",
|
|
28
|
-
"moment",
|
|
29
|
-
"skill",
|
|
30
|
-
"rule",
|
|
31
|
-
"procedure",
|
|
32
|
-
"reasoning_trace"
|
|
33
|
-
]);
|
|
34
|
-
var SECRET_PATTERNS = [
|
|
35
|
-
/\bsk-[A-Za-z0-9]{16,}\b/,
|
|
36
|
-
/\bAKIA[0-9A-Z]{16}\b/,
|
|
37
|
-
/\bBearer\s+[A-Za-z0-9._-]{16,}\b/i,
|
|
38
|
-
/\b(?:api[_-]?key|secret|token|password|passwd)\s*[:=]\s*[^\s]{8,}\b/i,
|
|
39
|
-
/\b(?:authorization)\s*:\s*[^\s]{8,}\b/i
|
|
40
|
-
];
|
|
41
|
-
var SECRET_REDACTION_PATTERNS = [
|
|
42
|
-
{ pattern: /\bsk-[A-Za-z0-9]{16,}\b/g, replacement: "[redacted openai key]" },
|
|
43
|
-
{ pattern: /\bAKIA[0-9A-Z]{16}\b/g, replacement: "[redacted aws key]" },
|
|
44
|
-
{ pattern: /\bBearer\s+[A-Za-z0-9._-]{16,}\b/gi, replacement: "Bearer [redacted token]" },
|
|
45
|
-
{
|
|
46
|
-
pattern: /\b(?:api[_-]?key|secret|token|password|passwd)\s*[:=]\s*[^\s]{8,}\b/gi,
|
|
47
|
-
replacement: "[redacted credential]"
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
pattern: /\b(?:authorization)\s*:\s*[^\s]{8,}\b/gi,
|
|
51
|
-
replacement: "authorization: [redacted credential]"
|
|
52
|
-
}
|
|
53
|
-
];
|
|
54
|
-
var EXPLICIT_CAPTURE_REVIEW_TAGS = ["explicit-capture", "queued-review"];
|
|
55
|
-
function explicitCaptureActor(source) {
|
|
56
|
-
switch (source) {
|
|
57
|
-
case "inline":
|
|
58
|
-
return "inline.memory_note";
|
|
59
|
-
case "memory_store":
|
|
60
|
-
return "tool.memory_store";
|
|
61
|
-
case "suggestion_submit":
|
|
62
|
-
return "tool.suggestion_submit";
|
|
63
|
-
default:
|
|
64
|
-
return "tool.memory_capture";
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
function asTrimmed(value) {
|
|
68
|
-
const trimmed = value?.trim();
|
|
69
|
-
return trimmed && trimmed.length > 0 ? trimmed : void 0;
|
|
70
|
-
}
|
|
71
|
-
function normalizeCaptureContent(value) {
|
|
72
|
-
return value.toLowerCase().replace(/\s+/g, " ").trim();
|
|
73
|
-
}
|
|
74
|
-
function redactSecrets(value) {
|
|
75
|
-
let redacted = value;
|
|
76
|
-
for (const { pattern, replacement } of SECRET_REDACTION_PATTERNS) {
|
|
77
|
-
redacted = redacted.replace(pattern, replacement);
|
|
78
|
-
}
|
|
79
|
-
return redacted;
|
|
80
|
-
}
|
|
81
|
-
function containsSecretLikeValue(value) {
|
|
82
|
-
return SECRET_PATTERNS.some((pattern) => pattern.test(value));
|
|
83
|
-
}
|
|
84
|
-
function assertNoSecretLikeMetadata(field, value) {
|
|
85
|
-
const trimmed = asTrimmed(value);
|
|
86
|
-
if (trimmed && containsSecretLikeValue(trimmed)) {
|
|
87
|
-
throw new Error(`${field} appears to contain a secret or credential`);
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
function assertNoSecretLikeMetadataList(field, values) {
|
|
91
|
-
for (const value of values ?? []) {
|
|
92
|
-
assertNoSecretLikeMetadata(field, value);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
function sanitizeReviewText(value, fallback) {
|
|
96
|
-
const redacted = redactSecrets(asTrimmed(value) ?? fallback);
|
|
97
|
-
const sanitized = sanitizeMemoryContent(redacted);
|
|
98
|
-
const safe = sanitized.text.trim();
|
|
99
|
-
return safe.length > 0 ? safe : fallback;
|
|
100
|
-
}
|
|
101
|
-
function sanitizeReviewMetadata(value) {
|
|
102
|
-
const trimmed = asTrimmed(value);
|
|
103
|
-
if (!trimmed) return void 0;
|
|
104
|
-
return sanitizeReviewText(trimmed, "[redacted]");
|
|
105
|
-
}
|
|
106
|
-
function sanitizeReviewTags(tags) {
|
|
107
|
-
return Array.from(new Set((tags ?? []).map((tag) => sanitizeReviewMetadata(tag)).filter((tag) => typeof tag === "string" && tag.length > 0)));
|
|
108
|
-
}
|
|
109
|
-
function normalizeExplicitCaptureError(error) {
|
|
110
|
-
if (error instanceof Error && error.message.trim().length > 0) return error.message.trim();
|
|
111
|
-
const rendered = String(error).trim();
|
|
112
|
-
return rendered.length > 0 ? rendered : "explicit capture failed";
|
|
113
|
-
}
|
|
114
|
-
function resolveExplicitCaptureReviewNamespace(orchestrator, namespace) {
|
|
115
|
-
const normalized = asTrimmed(namespace);
|
|
116
|
-
if (!normalized) return void 0;
|
|
117
|
-
return resolveExplicitCaptureNamespace(orchestrator, normalized);
|
|
118
|
-
}
|
|
119
|
-
function resolveExplicitCaptureNamespace(orchestrator, namespace) {
|
|
120
|
-
const normalized = asTrimmed(namespace);
|
|
121
|
-
if (!normalized) return void 0;
|
|
122
|
-
if (!resolveNamespaceCapabilities(orchestrator.config).namespaces) {
|
|
123
|
-
if (normalized !== orchestrator.config.defaultNamespace) {
|
|
124
|
-
throw new Error(`unsupported namespace: ${normalized}`);
|
|
125
|
-
}
|
|
126
|
-
return normalized;
|
|
127
|
-
}
|
|
128
|
-
const allowed = new Set([
|
|
129
|
-
orchestrator.config.defaultNamespace,
|
|
130
|
-
orchestrator.config.sharedNamespace,
|
|
131
|
-
...orchestrator.config.namespacePolicies.map((policy) => policy.name)
|
|
132
|
-
].map((value) => value.trim()).filter(Boolean));
|
|
133
|
-
if (!allowed.has(normalized)) {
|
|
134
|
-
throw new Error(`unsupported namespace: ${normalized}`);
|
|
135
|
-
}
|
|
136
|
-
return normalized;
|
|
137
|
-
}
|
|
138
|
-
function parseExplicitCaptureTtl(ttl) {
|
|
139
|
-
const raw = asTrimmed(ttl);
|
|
140
|
-
if (!raw) return void 0;
|
|
141
|
-
const absoluteMs = Date.parse(raw);
|
|
142
|
-
if (Number.isFinite(absoluteMs)) {
|
|
143
|
-
return new Date(absoluteMs).toISOString();
|
|
144
|
-
}
|
|
145
|
-
const relative = raw.match(/^(\d+)\s*([mhdw])$/i);
|
|
146
|
-
if (!relative) {
|
|
147
|
-
throw new Error("ttl must be an ISO-8601 timestamp or relative duration like 30m, 12h, 7d, or 2w");
|
|
148
|
-
}
|
|
149
|
-
const amount = Number.parseInt(relative[1] ?? "", 10);
|
|
150
|
-
const unit = (relative[2] ?? "").toLowerCase();
|
|
151
|
-
if (!Number.isFinite(amount) || amount <= 0) {
|
|
152
|
-
throw new Error("ttl duration must be a positive integer");
|
|
153
|
-
}
|
|
154
|
-
const multiplier = unit === "m" ? 6e4 : unit === "h" ? 60 * 6e4 : unit === "d" ? 24 * 60 * 6e4 : 7 * 24 * 60 * 6e4;
|
|
155
|
-
return new Date(Date.now() + amount * multiplier).toISOString();
|
|
156
|
-
}
|
|
157
|
-
function parseInlineConfidence(value) {
|
|
158
|
-
const trimmed = value.trim();
|
|
159
|
-
if (!/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?$/i.test(trimmed)) {
|
|
160
|
-
return Number.NaN;
|
|
161
|
-
}
|
|
162
|
-
const parsed = Number(trimmed);
|
|
163
|
-
return Number.isFinite(parsed) ? parsed : Number.NaN;
|
|
164
|
-
}
|
|
165
|
-
function parseInlineNote(block) {
|
|
166
|
-
const lines = block.replace(/\r/g, "").split("\n");
|
|
167
|
-
const note = {};
|
|
168
|
-
let idx = 0;
|
|
169
|
-
while (idx < lines.length) {
|
|
170
|
-
const rawLine = lines[idx] ?? "";
|
|
171
|
-
const line = rawLine.trim();
|
|
172
|
-
idx += 1;
|
|
173
|
-
if (line.length === 0) continue;
|
|
174
|
-
const colonIdx = line.indexOf(":");
|
|
175
|
-
if (colonIdx < 0) continue;
|
|
176
|
-
const key = line.slice(0, colonIdx).trim();
|
|
177
|
-
const value = line.slice(colonIdx + 1).trim();
|
|
178
|
-
if (key === "content" && value === "|") {
|
|
179
|
-
const contentLines = [];
|
|
180
|
-
while (idx < lines.length) {
|
|
181
|
-
const next = lines[idx] ?? "";
|
|
182
|
-
if (next.startsWith(" ") || next.startsWith(" ")) {
|
|
183
|
-
contentLines.push(next.replace(/^( |\t)/, ""));
|
|
184
|
-
idx += 1;
|
|
185
|
-
continue;
|
|
186
|
-
}
|
|
187
|
-
if (next.trim().length === 0) {
|
|
188
|
-
contentLines.push("");
|
|
189
|
-
idx += 1;
|
|
190
|
-
continue;
|
|
191
|
-
}
|
|
192
|
-
break;
|
|
193
|
-
}
|
|
194
|
-
note.content = contentLines.join("\n").trim();
|
|
195
|
-
continue;
|
|
196
|
-
}
|
|
197
|
-
switch (key) {
|
|
198
|
-
case "content":
|
|
199
|
-
note.content = value;
|
|
200
|
-
break;
|
|
201
|
-
case "category":
|
|
202
|
-
note.category = value;
|
|
203
|
-
break;
|
|
204
|
-
case "confidence":
|
|
205
|
-
note.confidence = parseInlineConfidence(value);
|
|
206
|
-
break;
|
|
207
|
-
case "namespace":
|
|
208
|
-
note.namespace = value;
|
|
209
|
-
break;
|
|
210
|
-
case "tags":
|
|
211
|
-
note.tags = value.split(",").map((entry) => entry.trim()).filter(Boolean);
|
|
212
|
-
break;
|
|
213
|
-
case "entityRef":
|
|
214
|
-
note.entityRef = value;
|
|
215
|
-
break;
|
|
216
|
-
case "ttl":
|
|
217
|
-
note.ttl = value;
|
|
218
|
-
break;
|
|
219
|
-
case "sourceReason":
|
|
220
|
-
note.sourceReason = value;
|
|
221
|
-
break;
|
|
222
|
-
default:
|
|
223
|
-
break;
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
return asTrimmed(note.content) ? note : null;
|
|
227
|
-
}
|
|
228
|
-
function parseInlineExplicitCaptureNotes(text) {
|
|
229
|
-
const notes = [];
|
|
230
|
-
for (const match of text.matchAll(INLINE_NOTE_RE)) {
|
|
231
|
-
const parsed = parseInlineNote(match[1] ?? "");
|
|
232
|
-
if (parsed) notes.push(parsed);
|
|
233
|
-
}
|
|
234
|
-
return notes;
|
|
235
|
-
}
|
|
236
|
-
function hasInlineExplicitCaptureMarkup(text) {
|
|
237
|
-
return INLINE_NOTE_MARKUP_RE.test(text);
|
|
238
|
-
}
|
|
239
|
-
function stripInlineExplicitCaptureNotes(text) {
|
|
240
|
-
return text.replace(INLINE_NOTE_RE, "").trim();
|
|
241
|
-
}
|
|
242
|
-
function validateExplicitCaptureInput(input, mode = "strict_explicit") {
|
|
243
|
-
const content = asTrimmed(input.content);
|
|
244
|
-
if (!content) throw new Error("content is required");
|
|
245
|
-
if (mode === "strict_explicit") {
|
|
246
|
-
if (content.length < 10) throw new Error("content must be at least 10 characters");
|
|
247
|
-
if (content.length > 4e3) throw new Error("content must be 4000 characters or fewer");
|
|
248
|
-
}
|
|
249
|
-
if (/<memory_note>/i.test(content) || /<\/memory_note>/i.test(content)) {
|
|
250
|
-
throw new Error("nested memory_note blocks are not allowed");
|
|
251
|
-
}
|
|
252
|
-
const category = asTrimmed(input.category) ?? "fact";
|
|
253
|
-
if (!INLINE_ALLOWED_CATEGORIES.has(category)) {
|
|
254
|
-
throw new Error(`unsupported category: ${input.category ?? category}`);
|
|
255
|
-
}
|
|
256
|
-
const sanitized = sanitizeMemoryContent(content);
|
|
257
|
-
if (!sanitized.clean) {
|
|
258
|
-
throw new Error("content failed memory sanitization");
|
|
259
|
-
}
|
|
260
|
-
for (const pattern of SECRET_PATTERNS) {
|
|
261
|
-
if (pattern.test(content)) {
|
|
262
|
-
throw new Error("content appears to contain a secret or credential");
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
assertNoSecretLikeMetadata("sourceReason", input.sourceReason);
|
|
266
|
-
assertNoSecretLikeMetadata("entityRef", input.entityRef);
|
|
267
|
-
assertNoSecretLikeMetadata("ttl", input.ttl);
|
|
268
|
-
assertNoSecretLikeMetadataList("tags", input.tags);
|
|
269
|
-
if (input.confidence !== void 0 && !Number.isFinite(input.confidence)) {
|
|
270
|
-
throw new Error("confidence must be a finite number");
|
|
271
|
-
}
|
|
272
|
-
const confidence = input.confidence === void 0 ? 0.95 : Number(input.confidence);
|
|
273
|
-
if (confidence < 0 || confidence > 1) {
|
|
274
|
-
throw new Error("confidence must be between 0 and 1");
|
|
275
|
-
}
|
|
276
|
-
const requestedNamespace = asTrimmed(input.namespace);
|
|
277
|
-
if (requestedNamespace && !isSafeRouteNamespace(requestedNamespace)) {
|
|
278
|
-
throw new Error(`unsafe namespace: ${requestedNamespace}`);
|
|
279
|
-
}
|
|
280
|
-
const expiresAt = parseExplicitCaptureTtl(input.ttl);
|
|
281
|
-
const dedupedTags = Array.from(new Set((input.tags ?? []).map((tag) => tag.trim()).filter(Boolean)));
|
|
282
|
-
if (dedupedTags.length > TAG_LIMITS.maxTags) {
|
|
283
|
-
throw new Error(`too many tags: ${dedupedTags.length} exceeds the ${TAG_LIMITS.maxTags}-tag limit`);
|
|
284
|
-
}
|
|
285
|
-
for (const tag of dedupedTags) {
|
|
286
|
-
if (tag.length > TAG_LIMITS.maxTagLength) {
|
|
287
|
-
throw new Error(`tag exceeds ${TAG_LIMITS.maxTagLength} characters: ${JSON.stringify(tag.slice(0, 40))}\u2026`);
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
return {
|
|
291
|
-
content,
|
|
292
|
-
category,
|
|
293
|
-
confidence,
|
|
294
|
-
namespace: asTrimmed(input.namespace),
|
|
295
|
-
tags: dedupedTags,
|
|
296
|
-
entityRef: asTrimmed(input.entityRef),
|
|
297
|
-
sourceReason: asTrimmed(input.sourceReason),
|
|
298
|
-
// Trimmed like the other optional metadata (#2017 review round): a
|
|
299
|
-
// whitespace-only connector previously passed validation and then blew
|
|
300
|
-
// up at strict compose time - validated input must always compose.
|
|
301
|
-
sourceConnector: asTrimmed(input.sourceConnector),
|
|
302
|
-
expiresAt
|
|
303
|
-
};
|
|
304
|
-
}
|
|
305
|
-
async function findDuplicateExplicitCapture(orchestrator, resolvedNamespace, candidate) {
|
|
306
|
-
const storage = await orchestrator.getStorage(resolvedNamespace);
|
|
307
|
-
if (candidate.category === "fact" && typeof storage.hasFactContentHash === "function") {
|
|
308
|
-
try {
|
|
309
|
-
const hasHash = await storage.hasFactContentHash(
|
|
310
|
-
candidate.content
|
|
311
|
-
);
|
|
312
|
-
if (!hasHash) {
|
|
313
|
-
const authoritative = typeof storage.isFactContentHashAuthoritative === "function" ? await storage.isFactContentHashAuthoritative() : false;
|
|
314
|
-
if (authoritative) return null;
|
|
315
|
-
}
|
|
316
|
-
} catch (err) {
|
|
317
|
-
void err;
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
const existing = await storage.readAllMemories();
|
|
321
|
-
const normalizedCandidate = normalizeCaptureContent(candidate.content);
|
|
322
|
-
const match = existing.find((memory) => {
|
|
323
|
-
const status = memory.frontmatter.status ?? "active";
|
|
324
|
-
if (status !== "active") return false;
|
|
325
|
-
if (memory.frontmatter.category !== candidate.category) return false;
|
|
326
|
-
if (normalizeCaptureContent(memory.content) !== normalizedCandidate) return false;
|
|
327
|
-
const existingConnector = memory.frontmatter.sourceConnector?.trim() || void 0;
|
|
328
|
-
const newConnector = candidate.sourceConnector?.trim() || void 0;
|
|
329
|
-
if (existingConnector !== newConnector) return false;
|
|
330
|
-
return true;
|
|
331
|
-
});
|
|
332
|
-
return match?.frontmatter.id ?? null;
|
|
333
|
-
}
|
|
334
|
-
async function persistExplicitCapture(orchestrator, candidate, source) {
|
|
335
|
-
const resolvedNamespace = candidate.namespacePreResolved ? asTrimmed(candidate.namespace) : resolveExplicitCaptureNamespace(orchestrator, candidate.namespace);
|
|
336
|
-
const duplicateOf = await findDuplicateExplicitCapture(orchestrator, resolvedNamespace, candidate);
|
|
337
|
-
if (duplicateOf) {
|
|
338
|
-
return { id: duplicateOf, duplicateOf };
|
|
339
|
-
}
|
|
340
|
-
const storage = await orchestrator.getStorage(resolvedNamespace);
|
|
341
|
-
const captureEnvelope = composeMemoryEnvelope(
|
|
342
|
-
{
|
|
343
|
-
content: candidate.content,
|
|
344
|
-
category: candidate.category,
|
|
345
|
-
confidence: candidate.confidence,
|
|
346
|
-
tags: candidate.tags,
|
|
347
|
-
...candidate.entityRef ? { entityRef: candidate.entityRef } : {},
|
|
348
|
-
...candidate.expiresAt ? { ttl: candidate.expiresAt } : {},
|
|
349
|
-
...candidate.sourceConnector ? { sourceConnector: candidate.sourceConnector } : {},
|
|
350
|
-
...candidate.sourceReason ? { sourceReason: candidate.sourceReason } : {}
|
|
351
|
-
},
|
|
352
|
-
{ source: source === "inline" ? "explicit-inline" : "explicit" }
|
|
353
|
-
);
|
|
354
|
-
const { id, tombstoneBlocked } = await storage.writeSealedMemory(captureEnvelope);
|
|
355
|
-
const created = (/* @__PURE__ */ new Date()).toISOString();
|
|
356
|
-
const event = {
|
|
357
|
-
eventId: `mle-${randomUUID()}`,
|
|
358
|
-
memoryId: id,
|
|
359
|
-
eventType: "explicit_capture_accepted",
|
|
360
|
-
timestamp: created,
|
|
361
|
-
actor: explicitCaptureActor(source),
|
|
362
|
-
reasonCode: candidate.sourceReason,
|
|
363
|
-
ruleVersion: "explicit-capture.v1"
|
|
364
|
-
};
|
|
365
|
-
await storage.appendMemoryLifecycleEvents([event]);
|
|
366
|
-
return { id, tombstoneBlocked };
|
|
367
|
-
}
|
|
368
|
-
function buildExplicitCaptureReviewContent(input, reason) {
|
|
369
|
-
const requestedContent = asTrimmed(input.content);
|
|
370
|
-
const safeContent = sanitizeReviewText(requestedContent, "[empty explicit capture]");
|
|
371
|
-
const safeCategory = sanitizeReviewMetadata(input.category);
|
|
372
|
-
const safeNamespace = sanitizeReviewMetadata(input.namespace);
|
|
373
|
-
const safeEntityRef = sanitizeReviewMetadata(input.entityRef);
|
|
374
|
-
const safeTtl = sanitizeReviewMetadata(input.ttl);
|
|
375
|
-
const safeSourceReason = sanitizeReviewMetadata(input.sourceReason);
|
|
376
|
-
const safeTags = sanitizeReviewTags(input.tags);
|
|
377
|
-
const lines = [
|
|
378
|
-
"Explicit capture queued for review.",
|
|
379
|
-
"",
|
|
380
|
-
`Reason: ${reason}`,
|
|
381
|
-
"",
|
|
382
|
-
"Submitted content:",
|
|
383
|
-
safeContent
|
|
384
|
-
];
|
|
385
|
-
const metadata = [
|
|
386
|
-
safeCategory ? `Requested category: ${safeCategory}` : void 0,
|
|
387
|
-
safeNamespace ? `Requested namespace: ${safeNamespace}` : void 0,
|
|
388
|
-
safeEntityRef ? `Requested entityRef: ${safeEntityRef}` : void 0,
|
|
389
|
-
safeTtl ? `Requested ttl: ${safeTtl}` : void 0,
|
|
390
|
-
safeSourceReason ? `Requested sourceReason: ${safeSourceReason}` : void 0,
|
|
391
|
-
safeTags.length > 0 ? `Requested tags: ${safeTags.join(", ")}` : void 0
|
|
392
|
-
].filter((entry) => typeof entry === "string" && entry.length > 0);
|
|
393
|
-
if (metadata.length > 0) {
|
|
394
|
-
lines.push("", ...metadata);
|
|
395
|
-
}
|
|
396
|
-
return lines.join("\n");
|
|
397
|
-
}
|
|
398
|
-
async function findQueuedExplicitCaptureDuplicate(orchestrator, namespace, content, sourceConnector) {
|
|
399
|
-
const storage = await orchestrator.getStorage(namespace);
|
|
400
|
-
const existing = await storage.readAllMemories();
|
|
401
|
-
const normalized = normalizeCaptureContent(content);
|
|
402
|
-
const match = existing.find((memory) => {
|
|
403
|
-
const status = memory.frontmatter.status ?? "active";
|
|
404
|
-
if (status !== "pending_review") return false;
|
|
405
|
-
if (!(memory.frontmatter.tags ?? []).includes("queued-review")) return false;
|
|
406
|
-
if (normalizeCaptureContent(memory.content) !== normalized) return false;
|
|
407
|
-
const existingConnector = memory.frontmatter.sourceConnector?.trim() || void 0;
|
|
408
|
-
const newConnector = sourceConnector?.trim() || void 0;
|
|
409
|
-
if (existingConnector !== newConnector) return false;
|
|
410
|
-
return true;
|
|
411
|
-
});
|
|
412
|
-
return match?.frontmatter.id ?? null;
|
|
413
|
-
}
|
|
414
|
-
async function queueExplicitCaptureForReview(orchestrator, input, source, error) {
|
|
415
|
-
const reason = sanitizeReviewText(normalizeExplicitCaptureError(error), "explicit capture failed");
|
|
416
|
-
const requestedNamespace = asTrimmed(input.namespace);
|
|
417
|
-
const queueNamespace = input.namespacePreResolved ? requestedNamespace : resolveExplicitCaptureReviewNamespace(orchestrator, requestedNamespace);
|
|
418
|
-
const content = buildExplicitCaptureReviewContent(input, reason);
|
|
419
|
-
const duplicateOf = await findQueuedExplicitCaptureDuplicate(orchestrator, queueNamespace, content, input.sourceConnector);
|
|
420
|
-
if (duplicateOf) {
|
|
421
|
-
return { id: duplicateOf, duplicateOf };
|
|
422
|
-
}
|
|
423
|
-
const requestedCategory = asTrimmed(input.category);
|
|
424
|
-
const reviewCategory = requestedCategory && INLINE_ALLOWED_CATEGORIES.has(requestedCategory) ? requestedCategory : "fact";
|
|
425
|
-
const requestedTags = sanitizeReviewTags(input.tags);
|
|
426
|
-
const storage = await orchestrator.getStorage(queueNamespace);
|
|
427
|
-
const reviewEnvelope = composeMemoryEnvelope(
|
|
428
|
-
{
|
|
429
|
-
content,
|
|
430
|
-
category: reviewCategory,
|
|
431
|
-
confidence: 0.2,
|
|
432
|
-
tags: Array.from(/* @__PURE__ */ new Set([...EXPLICIT_CAPTURE_REVIEW_TAGS, ...requestedTags])),
|
|
433
|
-
...sanitizeReviewMetadata(input.entityRef) ? { entityRef: sanitizeReviewMetadata(input.entityRef) } : {},
|
|
434
|
-
...input.sourceConnector ? { sourceConnector: input.sourceConnector } : {}
|
|
435
|
-
},
|
|
436
|
-
{ source: source === "inline" ? "explicit-inline-review" : "explicit-review" },
|
|
437
|
-
// The review queue is the FALLBACK for a capture that already failed
|
|
438
|
-
// primary validation — it must never be un-queueable. The tag list is
|
|
439
|
-
// machine-assembled (requested tags + the two fixed review tags), so 49+
|
|
440
|
-
// requested tags would push past the 50-tag limit and strict compose
|
|
441
|
-
// would throw, losing the capture (#2014 review round). Salvage clamps
|
|
442
|
-
// instead; the fixed review tags sort first in the assembly above, so
|
|
443
|
-
// they always survive the clamp.
|
|
444
|
-
{ salvage: true }
|
|
445
|
-
);
|
|
446
|
-
const { id } = await storage.writeSealedMemory(reviewEnvelope);
|
|
447
|
-
try {
|
|
448
|
-
const created = await storage.getMemoryById(id);
|
|
449
|
-
if (created) {
|
|
450
|
-
await storage.writeMemoryFrontmatter(created, {
|
|
451
|
-
status: "pending_review",
|
|
452
|
-
updated: (/* @__PURE__ */ new Date()).toISOString()
|
|
453
|
-
}, {
|
|
454
|
-
actor: explicitCaptureActor(source),
|
|
455
|
-
reasonCode: reason,
|
|
456
|
-
ruleVersion: "explicit-capture.v1"
|
|
457
|
-
});
|
|
458
|
-
}
|
|
459
|
-
} finally {
|
|
460
|
-
}
|
|
461
|
-
const event = {
|
|
462
|
-
eventId: `mle-${randomUUID()}`,
|
|
463
|
-
memoryId: id,
|
|
464
|
-
eventType: "explicit_capture_queued",
|
|
465
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
466
|
-
actor: explicitCaptureActor(source),
|
|
467
|
-
reasonCode: reason,
|
|
468
|
-
ruleVersion: "explicit-capture.v1"
|
|
469
|
-
};
|
|
470
|
-
await storage.appendMemoryLifecycleEvents([event]);
|
|
471
|
-
return { id };
|
|
472
|
-
}
|
|
473
|
-
function shouldSkipImplicitExtraction(cfg) {
|
|
474
|
-
return cfg.captureMode === "explicit";
|
|
475
|
-
}
|
|
476
|
-
function shouldProcessInlineExplicitCapture(cfg) {
|
|
477
|
-
return cfg.captureMode !== "implicit";
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
export {
|
|
481
|
-
parseInlineExplicitCaptureNotes,
|
|
482
|
-
hasInlineExplicitCaptureMarkup,
|
|
483
|
-
stripInlineExplicitCaptureNotes,
|
|
484
|
-
validateExplicitCaptureInput,
|
|
485
|
-
persistExplicitCapture,
|
|
486
|
-
queueExplicitCaptureForReview,
|
|
487
|
-
shouldSkipImplicitExtraction,
|
|
488
|
-
shouldProcessInlineExplicitCapture
|
|
489
|
-
};
|
|
490
|
-
//# sourceMappingURL=chunk-55MDBZLC.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/explicit-capture.ts"],"sourcesContent":["import { composeMemoryEnvelope, TAG_LIMITS } from \"./write-envelope.js\";\nimport { resolveNamespaceCapabilities } from \"./capabilities.js\";\nimport { randomUUID } from \"node:crypto\";\nimport type { Orchestrator } from \"./orchestrator.js\";\nimport { isSafeRouteNamespace } from \"./routing/engine.js\";\nimport { sanitizeMemoryContent } from \"./sanitize.js\";\nimport { ContentHashIndex } from \"./storage.js\";\nimport type { CaptureMode, MemoryCategory, MemoryLifecycleEvent, PluginConfig } from \"./types.js\";\n\nexport type ExplicitCaptureInput = {\n content: string;\n category?: string;\n confidence?: number;\n namespace?: string;\n tags?: string[];\n entityRef?: string;\n sourceConnector?: string;\n ttl?: string;\n sourceReason?: string;\n};\n\nexport type ValidExplicitCapture = {\n content: string;\n category: MemoryCategory;\n confidence: number;\n namespace?: string;\n tags: string[];\n entityRef?: string;\n sourceConnector?: string;\n expiresAt?: string;\n sourceReason?: string;\n /**\n * When true, `namespace` was already resolved AND authorized by the caller\n * (the access service's `resolveCodingScopedWriteNamespace`, which auth-checks\n * the base and derives a session-owned `project-*` overlay). The persist /\n * queue layer then routes to it directly instead of re-validating against the\n * static policy allow-list — which would otherwise reject legitimately-derived\n * dynamic project namespaces (#1434). Callers that do NOT pre-authorize the\n * namespace must leave this unset so the allow-list guard still applies.\n */\n namespacePreResolved?: boolean;\n};\n\nexport type ExplicitCaptureSource = \"memory_store\" | \"memory_capture\" | \"suggestion_submit\" | \"inline\";\ntype ExplicitCaptureValidationMode = \"legacy_tool\" | \"strict_explicit\";\n\n// Bounded body {0,100000} instead of an unbounded lazy *? so scanning for the\n// closing tag cannot backtrack polynomially on unterminated <memory_note>\n// markup in hostile turn text (CodeQL js/polynomial-redos). 100 000 chars far\n// exceeds any real inline note, so matching is behavior-preserving; the outer\n// \\s* groups were also dropped (body absorbs whitespace; captures are trimmed).\nconst INLINE_NOTE_RE = /<memory_note>([\\s\\S]{0,100000}?)<\\/memory_note>/gi;\nconst INLINE_NOTE_MARKUP_RE = /<memory_note>[\\s\\S]{0,100000}?<\\/memory_note>/i;\nconst INLINE_ALLOWED_CATEGORIES = new Set<MemoryCategory>([\n \"fact\",\n \"preference\",\n \"correction\",\n \"entity\",\n \"decision\",\n \"relationship\",\n \"principle\",\n \"commitment\",\n \"moment\",\n \"skill\",\n \"rule\",\n \"procedure\",\n \"reasoning_trace\",\n]);\n\nconst SECRET_PATTERNS: RegExp[] = [\n /\\bsk-[A-Za-z0-9]{16,}\\b/,\n /\\bAKIA[0-9A-Z]{16}\\b/,\n /\\bBearer\\s+[A-Za-z0-9._-]{16,}\\b/i,\n /\\b(?:api[_-]?key|secret|token|password|passwd)\\s*[:=]\\s*[^\\s]{8,}\\b/i,\n /\\b(?:authorization)\\s*:\\s*[^\\s]{8,}\\b/i,\n];\nconst SECRET_REDACTION_PATTERNS: Array<{ pattern: RegExp; replacement: string }> = [\n { pattern: /\\bsk-[A-Za-z0-9]{16,}\\b/g, replacement: \"[redacted openai key]\" },\n { pattern: /\\bAKIA[0-9A-Z]{16}\\b/g, replacement: \"[redacted aws key]\" },\n { pattern: /\\bBearer\\s+[A-Za-z0-9._-]{16,}\\b/gi, replacement: \"Bearer [redacted token]\" },\n {\n pattern: /\\b(?:api[_-]?key|secret|token|password|passwd)\\s*[:=]\\s*[^\\s]{8,}\\b/gi,\n replacement: \"[redacted credential]\",\n },\n {\n pattern: /\\b(?:authorization)\\s*:\\s*[^\\s]{8,}\\b/gi,\n replacement: \"authorization: [redacted credential]\",\n },\n];\nconst EXPLICIT_CAPTURE_REVIEW_TAGS = [\"explicit-capture\", \"queued-review\"];\n\nfunction explicitCaptureActor(source: ExplicitCaptureSource): string {\n switch (source) {\n case \"inline\":\n return \"inline.memory_note\";\n case \"memory_store\":\n return \"tool.memory_store\";\n case \"suggestion_submit\":\n return \"tool.suggestion_submit\";\n default:\n return \"tool.memory_capture\";\n }\n}\n\nfunction asTrimmed(value: string | undefined): string | undefined {\n const trimmed = value?.trim();\n return trimmed && trimmed.length > 0 ? trimmed : undefined;\n}\n\nfunction normalizeCaptureContent(value: string): string {\n return value\n .toLowerCase()\n .replace(/\\s+/g, \" \")\n .trim();\n}\n\nfunction redactSecrets(value: string): string {\n let redacted = value;\n for (const { pattern, replacement } of SECRET_REDACTION_PATTERNS) {\n redacted = redacted.replace(pattern, replacement);\n }\n return redacted;\n}\n\nfunction containsSecretLikeValue(value: string): boolean {\n return SECRET_PATTERNS.some((pattern) => pattern.test(value));\n}\n\nfunction assertNoSecretLikeMetadata(field: string, value: string | undefined): void {\n const trimmed = asTrimmed(value);\n if (trimmed && containsSecretLikeValue(trimmed)) {\n throw new Error(`${field} appears to contain a secret or credential`);\n }\n}\n\nfunction assertNoSecretLikeMetadataList(field: string, values: string[] | undefined): void {\n for (const value of values ?? []) {\n assertNoSecretLikeMetadata(field, value);\n }\n}\n\nfunction sanitizeReviewText(value: string | undefined, fallback: string): string {\n const redacted = redactSecrets(asTrimmed(value) ?? fallback);\n const sanitized = sanitizeMemoryContent(redacted);\n const safe = sanitized.text.trim();\n return safe.length > 0 ? safe : fallback;\n}\n\nfunction sanitizeReviewMetadata(value: string | undefined): string | undefined {\n const trimmed = asTrimmed(value);\n if (!trimmed) return undefined;\n return sanitizeReviewText(trimmed, \"[redacted]\");\n}\n\nfunction sanitizeReviewTags(tags: string[] | undefined): string[] {\n return Array.from(new Set((tags ?? [])\n .map((tag) => sanitizeReviewMetadata(tag))\n .filter((tag): tag is string => typeof tag === \"string\" && tag.length > 0)));\n}\n\nfunction normalizeExplicitCaptureError(error: unknown): string {\n if (error instanceof Error && error.message.trim().length > 0) return error.message.trim();\n const rendered = String(error).trim();\n return rendered.length > 0 ? rendered : \"explicit capture failed\";\n}\n\nfunction resolveExplicitCaptureReviewNamespace(\n orchestrator: Orchestrator,\n namespace: string | undefined,\n): string | undefined {\n const normalized = asTrimmed(namespace);\n if (!normalized) return undefined;\n return resolveExplicitCaptureNamespace(orchestrator, normalized);\n}\n\nfunction resolveExplicitCaptureNamespace(\n orchestrator: Orchestrator,\n namespace: string | undefined,\n): string | undefined {\n const normalized = asTrimmed(namespace);\n if (!normalized) return undefined;\n if (!resolveNamespaceCapabilities(orchestrator.config).namespaces) {\n if (normalized !== orchestrator.config.defaultNamespace) {\n throw new Error(`unsupported namespace: ${normalized}`);\n }\n return normalized;\n }\n const allowed = new Set([\n orchestrator.config.defaultNamespace,\n orchestrator.config.sharedNamespace,\n ...orchestrator.config.namespacePolicies.map((policy) => policy.name),\n ].map((value) => value.trim()).filter(Boolean));\n if (!allowed.has(normalized)) {\n throw new Error(`unsupported namespace: ${normalized}`);\n }\n return normalized;\n}\n\nfunction parseExplicitCaptureTtl(ttl: string | undefined): string | undefined {\n const raw = asTrimmed(ttl);\n if (!raw) return undefined;\n\n const absoluteMs = Date.parse(raw);\n if (Number.isFinite(absoluteMs)) {\n return new Date(absoluteMs).toISOString();\n }\n\n const relative = raw.match(/^(\\d+)\\s*([mhdw])$/i);\n if (!relative) {\n throw new Error(\"ttl must be an ISO-8601 timestamp or relative duration like 30m, 12h, 7d, or 2w\");\n }\n\n const amount = Number.parseInt(relative[1] ?? \"\", 10);\n const unit = (relative[2] ?? \"\").toLowerCase();\n if (!Number.isFinite(amount) || amount <= 0) {\n throw new Error(\"ttl duration must be a positive integer\");\n }\n\n const multiplier =\n unit === \"m\" ? 60_000\n : unit === \"h\" ? 60 * 60_000\n : unit === \"d\" ? 24 * 60 * 60_000\n : 7 * 24 * 60 * 60_000;\n return new Date(Date.now() + amount * multiplier).toISOString();\n}\n\nfunction parseInlineConfidence(value: string): number {\n const trimmed = value.trim();\n if (!/^[+-]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)(?:e[+-]?\\d+)?$/i.test(trimmed)) {\n return Number.NaN;\n }\n const parsed = Number(trimmed);\n return Number.isFinite(parsed) ? parsed : Number.NaN;\n}\n\nfunction parseInlineNote(block: string): ExplicitCaptureInput | null {\n const lines = block.replace(/\\r/g, \"\").split(\"\\n\");\n const note: Partial<ExplicitCaptureInput> = {};\n let idx = 0;\n\n while (idx < lines.length) {\n const rawLine = lines[idx] ?? \"\";\n const line = rawLine.trim();\n idx += 1;\n if (line.length === 0) continue;\n const colonIdx = line.indexOf(\":\");\n if (colonIdx < 0) continue;\n const key = line.slice(0, colonIdx).trim();\n const value = line.slice(colonIdx + 1).trim();\n\n if (key === \"content\" && value === \"|\") {\n const contentLines: string[] = [];\n while (idx < lines.length) {\n const next = lines[idx] ?? \"\";\n if (next.startsWith(\" \") || next.startsWith(\"\\t\")) {\n contentLines.push(next.replace(/^( |\\t)/, \"\"));\n idx += 1;\n continue;\n }\n if (next.trim().length === 0) {\n contentLines.push(\"\");\n idx += 1;\n continue;\n }\n break;\n }\n note.content = contentLines.join(\"\\n\").trim();\n continue;\n }\n\n switch (key) {\n case \"content\":\n note.content = value;\n break;\n case \"category\":\n note.category = value;\n break;\n case \"confidence\":\n note.confidence = parseInlineConfidence(value);\n break;\n case \"namespace\":\n note.namespace = value;\n break;\n case \"tags\":\n note.tags = value\n .split(\",\")\n .map((entry) => entry.trim())\n .filter(Boolean);\n break;\n case \"entityRef\":\n note.entityRef = value;\n break;\n case \"ttl\":\n note.ttl = value;\n break;\n case \"sourceReason\":\n note.sourceReason = value;\n break;\n default:\n break;\n }\n }\n\n return asTrimmed(note.content) ? (note as ExplicitCaptureInput) : null;\n}\n\nexport function parseInlineExplicitCaptureNotes(text: string): ExplicitCaptureInput[] {\n const notes: ExplicitCaptureInput[] = [];\n for (const match of text.matchAll(INLINE_NOTE_RE)) {\n const parsed = parseInlineNote(match[1] ?? \"\");\n if (parsed) notes.push(parsed);\n }\n return notes;\n}\n\nexport function hasInlineExplicitCaptureMarkup(text: string): boolean {\n return INLINE_NOTE_MARKUP_RE.test(text);\n}\n\nexport function stripInlineExplicitCaptureNotes(text: string): string {\n return text.replace(INLINE_NOTE_RE, \"\").trim();\n}\n\nexport function validateExplicitCaptureInput(\n input: ExplicitCaptureInput,\n mode: ExplicitCaptureValidationMode = \"strict_explicit\",\n): ValidExplicitCapture {\n const content = asTrimmed(input.content);\n if (!content) throw new Error(\"content is required\");\n if (mode === \"strict_explicit\") {\n if (content.length < 10) throw new Error(\"content must be at least 10 characters\");\n if (content.length > 4000) throw new Error(\"content must be 4000 characters or fewer\");\n }\n if (/<memory_note>/i.test(content) || /<\\/memory_note>/i.test(content)) {\n throw new Error(\"nested memory_note blocks are not allowed\");\n }\n\n const category = (asTrimmed(input.category) ?? \"fact\") as MemoryCategory;\n if (!INLINE_ALLOWED_CATEGORIES.has(category)) {\n throw new Error(`unsupported category: ${input.category ?? category}`);\n }\n\n const sanitized = sanitizeMemoryContent(content);\n if (!sanitized.clean) {\n throw new Error(\"content failed memory sanitization\");\n }\n for (const pattern of SECRET_PATTERNS) {\n if (pattern.test(content)) {\n throw new Error(\"content appears to contain a secret or credential\");\n }\n }\n assertNoSecretLikeMetadata(\"sourceReason\", input.sourceReason);\n assertNoSecretLikeMetadata(\"entityRef\", input.entityRef);\n assertNoSecretLikeMetadata(\"ttl\", input.ttl);\n assertNoSecretLikeMetadataList(\"tags\", input.tags);\n\n if (input.confidence !== undefined && !Number.isFinite(input.confidence)) {\n throw new Error(\"confidence must be a finite number\");\n }\n const confidence = input.confidence === undefined ? 0.95 : Number(input.confidence);\n if (confidence < 0 || confidence > 1) {\n throw new Error(\"confidence must be between 0 and 1\");\n }\n const requestedNamespace = asTrimmed(input.namespace);\n if (requestedNamespace && !isSafeRouteNamespace(requestedNamespace)) {\n throw new Error(`unsafe namespace: ${requestedNamespace}`);\n }\n const expiresAt = parseExplicitCaptureTtl(input.ttl);\n\n // #2014 review round: enforce the composer's tag contract HERE so a capture\n // that passes validation can never fail later at strict compose time\n // (validated-then-thrown was a broken contract). Same limits as TAG_LIMITS.\n const dedupedTags = Array.from(new Set((input.tags ?? []).map((tag) => tag.trim()).filter(Boolean)));\n if (dedupedTags.length > TAG_LIMITS.maxTags) {\n throw new Error(`too many tags: ${dedupedTags.length} exceeds the ${TAG_LIMITS.maxTags}-tag limit`);\n }\n for (const tag of dedupedTags) {\n if (tag.length > TAG_LIMITS.maxTagLength) {\n throw new Error(`tag exceeds ${TAG_LIMITS.maxTagLength} characters: ${JSON.stringify(tag.slice(0, 40))}…`);\n }\n }\n\n return {\n content,\n category,\n confidence,\n namespace: asTrimmed(input.namespace),\n tags: dedupedTags,\n entityRef: asTrimmed(input.entityRef),\n sourceReason: asTrimmed(input.sourceReason),\n // Trimmed like the other optional metadata (#2017 review round): a\n // whitespace-only connector previously passed validation and then blew\n // up at strict compose time - validated input must always compose.\n sourceConnector: asTrimmed(input.sourceConnector),\n expiresAt,\n };\n}\n\nasync function findDuplicateExplicitCapture(\n orchestrator: Orchestrator,\n resolvedNamespace: string | undefined,\n candidate: ValidExplicitCapture,\n): Promise<string | null> {\n const storage = await orchestrator.getStorage(resolvedNamespace);\n if (\n candidate.category === \"fact\"\n && typeof (storage as { hasFactContentHash?: (content: string) => Promise<boolean> }).hasFactContentHash === \"function\"\n ) {\n try {\n const hasHash = await (storage as { hasFactContentHash: (content: string) => Promise<boolean> }).hasFactContentHash(\n candidate.content,\n );\n if (!hasHash) {\n const authoritative =\n typeof (storage as { isFactContentHashAuthoritative?: () => Promise<boolean> | boolean }).isFactContentHashAuthoritative\n === \"function\"\n ? await (storage as { isFactContentHashAuthoritative: () => Promise<boolean> | boolean })\n .isFactContentHashAuthoritative()\n : false;\n if (authoritative) return null;\n }\n } catch (err) {\n // Fail open: hash index is only an optimization, so fall back to the full corpus scan.\n void err;\n }\n }\n const existing = await storage.readAllMemories();\n const normalizedCandidate = normalizeCaptureContent(candidate.content);\n const match = existing.find((memory) => {\n const status = memory.frontmatter.status ?? \"active\";\n if (status !== \"active\") return false;\n if (memory.frontmatter.category !== candidate.category) return false;\n if (normalizeCaptureContent(memory.content) !== normalizedCandidate) return false;\n // Connector-aware dedup: same content from different connectors is NOT\n // a duplicate. Operator (undefined) and connector-tagged memories are\n // always distinct. Normalize empty strings to undefined.\n const existingConnector = memory.frontmatter.sourceConnector?.trim() || undefined;\n const newConnector = candidate.sourceConnector?.trim() || undefined;\n if (existingConnector !== newConnector) return false;\n return true;\n });\n return match?.frontmatter.id ?? null;\n}\n\nexport async function persistExplicitCapture(\n orchestrator: Orchestrator,\n candidate: ValidExplicitCapture,\n source: ExplicitCaptureSource,\n): Promise<{ id: string; duplicateOf?: string; tombstoneBlocked?: boolean }> {\n const resolvedNamespace = candidate.namespacePreResolved\n ? asTrimmed(candidate.namespace)\n : resolveExplicitCaptureNamespace(orchestrator, candidate.namespace);\n const duplicateOf = await findDuplicateExplicitCapture(orchestrator, resolvedNamespace, candidate);\n if (duplicateOf) {\n return { id: duplicateOf, duplicateOf };\n }\n\n const storage = await orchestrator.getStorage(resolvedNamespace);\n // #1645 (review thread yG-): surface the tombstone block so callers\n // (memory_store tool, access-service HTTP/MCP) can report the capture as\n // queued for review instead of a successfully stored active memory.\n // Sealed-envelope write (issue #1989 PR2).\n const captureEnvelope = composeMemoryEnvelope(\n {\n content: candidate.content,\n category: candidate.category,\n confidence: candidate.confidence,\n tags: candidate.tags,\n ...(candidate.entityRef ? { entityRef: candidate.entityRef } : {}),\n ...(candidate.expiresAt ? { ttl: candidate.expiresAt } : {}),\n ...(candidate.sourceConnector ? { sourceConnector: candidate.sourceConnector } : {}),\n ...(candidate.sourceReason ? { sourceReason: candidate.sourceReason } : {}),\n },\n { source: source === \"inline\" ? \"explicit-inline\" : \"explicit\" },\n );\n const { id, tombstoneBlocked } = await storage.writeSealedMemory(captureEnvelope);\n // #1522: catalog touch handled at the storage chokepoint — the StorageManager's\n // post-write hook records the namespace touch automatically.\n\n const created = new Date().toISOString();\n const event: MemoryLifecycleEvent = {\n eventId: `mle-${randomUUID()}`,\n memoryId: id,\n eventType: \"explicit_capture_accepted\",\n timestamp: created,\n actor: explicitCaptureActor(source),\n reasonCode: candidate.sourceReason,\n ruleVersion: \"explicit-capture.v1\",\n };\n await storage.appendMemoryLifecycleEvents([event]);\n\n return { id, tombstoneBlocked };\n}\n\nfunction buildExplicitCaptureReviewContent(input: ExplicitCaptureInput, reason: string): string {\n const requestedContent = asTrimmed(input.content);\n const safeContent = sanitizeReviewText(requestedContent, \"[empty explicit capture]\");\n const safeCategory = sanitizeReviewMetadata(input.category);\n const safeNamespace = sanitizeReviewMetadata(input.namespace);\n const safeEntityRef = sanitizeReviewMetadata(input.entityRef);\n const safeTtl = sanitizeReviewMetadata(input.ttl);\n const safeSourceReason = sanitizeReviewMetadata(input.sourceReason);\n const safeTags = sanitizeReviewTags(input.tags);\n const lines = [\n \"Explicit capture queued for review.\",\n \"\",\n `Reason: ${reason}`,\n \"\",\n \"Submitted content:\",\n safeContent,\n ];\n const metadata = [\n safeCategory ? `Requested category: ${safeCategory}` : undefined,\n safeNamespace ? `Requested namespace: ${safeNamespace}` : undefined,\n safeEntityRef ? `Requested entityRef: ${safeEntityRef}` : undefined,\n safeTtl ? `Requested ttl: ${safeTtl}` : undefined,\n safeSourceReason ? `Requested sourceReason: ${safeSourceReason}` : undefined,\n safeTags.length > 0 ? `Requested tags: ${safeTags.join(\", \")}` : undefined,\n ].filter((entry): entry is string => typeof entry === \"string\" && entry.length > 0);\n if (metadata.length > 0) {\n lines.push(\"\", ...metadata);\n }\n return lines.join(\"\\n\");\n}\n\nasync function findQueuedExplicitCaptureDuplicate(\n orchestrator: Orchestrator,\n namespace: string | undefined,\n content: string,\n sourceConnector?: string,\n): Promise<string | null> {\n const storage = await orchestrator.getStorage(namespace);\n const existing = await storage.readAllMemories();\n const normalized = normalizeCaptureContent(content);\n const match = existing.find((memory) => {\n const status = memory.frontmatter.status ?? \"active\";\n if (status !== \"pending_review\") return false;\n if (!(memory.frontmatter.tags ?? []).includes(\"queued-review\")) return false;\n if (normalizeCaptureContent(memory.content) !== normalized) return false;\n const existingConnector = memory.frontmatter.sourceConnector?.trim() || undefined;\n const newConnector = sourceConnector?.trim() || undefined;\n if (existingConnector !== newConnector) return false;\n return true;\n });\n return match?.frontmatter.id ?? null;\n}\n\nexport async function queueExplicitCaptureForReview(\n orchestrator: Orchestrator,\n input: ExplicitCaptureInput,\n source: ExplicitCaptureSource,\n error: unknown,\n): Promise<{ id: string; duplicateOf?: string }> {\n const reason = sanitizeReviewText(normalizeExplicitCaptureError(error), \"explicit capture failed\");\n const requestedNamespace = asTrimmed(input.namespace);\n // A caller-pre-authorized namespace (e.g. a session-owned project overlay\n // from the access service) routes directly; otherwise apply the static\n // policy allow-list guard (#1434).\n const queueNamespace = (input as { namespacePreResolved?: boolean }).namespacePreResolved\n ? requestedNamespace\n : resolveExplicitCaptureReviewNamespace(orchestrator, requestedNamespace);\n const content = buildExplicitCaptureReviewContent(input, reason);\n const duplicateOf = await findQueuedExplicitCaptureDuplicate(orchestrator, queueNamespace, content, input.sourceConnector);\n if (duplicateOf) {\n return { id: duplicateOf, duplicateOf };\n }\n\n const requestedCategory = asTrimmed(input.category);\n const reviewCategory = requestedCategory && INLINE_ALLOWED_CATEGORIES.has(requestedCategory as MemoryCategory)\n ? requestedCategory as MemoryCategory\n : \"fact\";\n const requestedTags = sanitizeReviewTags(input.tags);\n const storage = await orchestrator.getStorage(queueNamespace);\n const reviewEnvelope = composeMemoryEnvelope(\n {\n content,\n category: reviewCategory,\n confidence: 0.2,\n tags: Array.from(new Set([...EXPLICIT_CAPTURE_REVIEW_TAGS, ...requestedTags])),\n ...(sanitizeReviewMetadata(input.entityRef) ? { entityRef: sanitizeReviewMetadata(input.entityRef) } : {}),\n ...(input.sourceConnector ? { sourceConnector: input.sourceConnector } : {}),\n },\n { source: source === \"inline\" ? \"explicit-inline-review\" : \"explicit-review\" },\n // The review queue is the FALLBACK for a capture that already failed\n // primary validation — it must never be un-queueable. The tag list is\n // machine-assembled (requested tags + the two fixed review tags), so 49+\n // requested tags would push past the 50-tag limit and strict compose\n // would throw, losing the capture (#2014 review round). Salvage clamps\n // instead; the fixed review tags sort first in the assembly above, so\n // they always survive the clamp.\n { salvage: true },\n );\n const { id: id } = await storage.writeSealedMemory(reviewEnvelope);\n try {\n const created = await storage.getMemoryById(id);\n if (created) {\n await storage.writeMemoryFrontmatter(created, {\n status: \"pending_review\",\n updated: new Date().toISOString(),\n }, {\n actor: explicitCaptureActor(source),\n reasonCode: reason,\n ruleVersion: \"explicit-capture.v1\",\n });\n }\n } finally {\n // Record the catalog write touch (issue #1499, round 5/6 codex P2; NIhUg).\n // A queued review capture writes memory to the namespace's root (the DEFAULT\n // root when undefined), so its `lastWriteAt` must reflect the write once\n // `writeMemory` returns an id. If the later pending-review frontmatter update\n // fails, the memory file is still durable and must not disappear from\n // writtenSince/maintenance scheduling. Guarded optional hook (rule #33).\n // #1522: catalog touch handled at the storage chokepoint.\n }\n const event: MemoryLifecycleEvent = {\n eventId: `mle-${randomUUID()}`,\n memoryId: id,\n eventType: \"explicit_capture_queued\",\n timestamp: new Date().toISOString(),\n actor: explicitCaptureActor(source),\n reasonCode: reason,\n ruleVersion: \"explicit-capture.v1\",\n };\n await storage.appendMemoryLifecycleEvents([event]);\n return { id };\n}\n\nexport function shouldSkipImplicitExtraction(cfg: Pick<PluginConfig, \"captureMode\">): boolean {\n return cfg.captureMode === \"explicit\";\n}\n\nexport function shouldProcessInlineExplicitCapture(cfg: Pick<PluginConfig, \"captureMode\">): boolean {\n return cfg.captureMode !== \"implicit\";\n}\n"],"mappings":"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","names":[]}
|