@remnic/core 9.65.1 → 9.65.3
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 +44 -44
- package/dist/access-admin-ops-surface.js +36 -35
- package/dist/access-authorization-probe.d.ts +39 -40
- package/dist/access-authorization-probe.js +37 -36
- package/dist/access-boundary.d.ts +41 -185
- package/dist/access-boundary.js +36 -35
- package/dist/access-cli.js +110 -107
- package/dist/access-cli.js.map +1 -1
- package/dist/access-coding-context-resolution.d.ts +3 -1
- package/dist/access-extraction-force-flush.d.ts +25 -25
- package/dist/access-extraction-force-flush.js +36 -35
- package/dist/access-health-types.d.ts +3 -1
- package/dist/access-http-lcm-compaction.d.ts +39 -39
- package/dist/access-http-lifecycle-flush.d.ts +40 -41
- package/dist/access-http-offline-stream.d.ts +25 -25
- package/dist/access-http-query.d.ts +4 -2
- package/dist/access-http-query.js +38 -37
- package/dist/access-http.d.ts +51 -44
- package/dist/access-http.js +57 -56
- package/dist/access-identity-continuity-surface.d.ts +12 -12
- package/dist/access-identity-continuity-surface.js +36 -35
- package/dist/access-lcm-surface.d.ts +27 -27
- package/dist/access-lcm-surface.js +36 -35
- package/dist/access-mcp-admin-tools.d.ts +9 -1
- package/dist/access-mcp-admin-tools.js +3 -1
- package/dist/access-mcp-output-schemas.js +1 -1
- package/dist/access-mcp.d.ts +39 -39
- package/dist/access-mcp.js +50 -47
- package/dist/access-memory-search-fanout.d.ts +4 -2
- package/dist/{access-namespace-preflight-BKUnKsBv.d.ts → access-namespace-preflight-B7Usyz-K.d.ts} +1 -1
- package/dist/access-namespace-preflight.d.ts +5 -3
- package/dist/access-namespace-preflight.js +36 -35
- package/dist/access-observe-write-surface.d.ts +39 -39
- package/dist/access-observe-write-surface.js +36 -35
- package/dist/access-offline-manifest.d.ts +12 -12
- package/dist/access-offline-manifest.js +5 -5
- package/dist/access-operations-batch.js +41 -40
- package/dist/access-operations.d.ts +46 -47
- package/dist/access-operations.js +44 -43
- package/dist/access-recall-concurrency.d.ts +40 -40
- package/dist/access-recall-concurrency.js +36 -35
- package/dist/access-recall-response.d.ts +24 -24
- package/dist/access-recall-response.js +36 -35
- package/dist/access-recall-surface.d.ts +24 -24
- package/dist/access-recall-surface.js +36 -35
- package/dist/access-schema.d.ts +139 -139
- package/dist/access-schema.js +3 -3
- package/dist/{access-service-B1Lbb-nQ.d.ts → access-service-DkaIG3n8.d.ts} +688 -140
- package/dist/access-service-helpers.d.ts +40 -40
- package/dist/access-service.d.ts +47 -47
- package/dist/access-service.js +36 -35
- package/dist/access-surface-catalog.d.ts +41 -42
- package/dist/access-surface-catalog.js +44 -37
- package/dist/access-surface-catalog.js.map +1 -1
- package/dist/access-wearables-meetings-surface.d.ts +5 -3
- package/dist/action-confidence.d.ts +3 -1
- package/dist/active-memory-bridge.d.ts +3 -1
- package/dist/active-recall.d.ts +3 -1
- package/dist/active-recall.js +11 -1
- package/dist/active-recall.js.map +1 -1
- package/dist/adapters/index.js +4 -4
- package/dist/adapters/registry.js +2 -2
- package/dist/ambient-provenance.d.ts +3 -1
- package/dist/artifact-search.d.ts +3 -1
- package/dist/{auto-sync-5L7EUZ27.js → auto-sync-H64ZCNIR.js} +13 -5
- package/dist/{auto-sync-5L7EUZ27.js.map → auto-sync-H64ZCNIR.js.map} +1 -1
- package/dist/behavior-learner.d.ts +3 -1
- package/dist/behavior-signals.d.ts +3 -1
- package/dist/bootstrap.d.ts +12 -12
- package/dist/briefing-window.d.ts +4 -2
- package/dist/briefing.d.ts +4 -2
- package/dist/briefing.js +16 -15
- package/dist/buffer-surprise-report.d.ts +3 -1
- package/dist/buffer-turn-helpers.d.ts +3 -1
- package/dist/buffer.d.ts +4 -2
- package/dist/buffer.js +4 -4
- package/dist/bulk-import/index.d.ts +5 -3
- package/dist/calibration.d.ts +3 -1
- package/dist/calibration.js +1 -1
- package/dist/capabilities.d.ts +3 -1
- package/dist/{capsule-crypto-7FJQINUR.js → capsule-crypto-YO5QJ6L3.js} +2 -2
- package/dist/{catalog-DjVhJoRM.d.ts → catalog-CX2BZEJh.d.ts} +1 -1
- package/dist/causal-behavior.d.ts +1 -1
- package/dist/causal-consolidation.d.ts +3 -1
- package/dist/causal-consolidation.js +20 -19
- package/dist/causal-consolidation.js.map +1 -1
- package/dist/causal-trajectory-graph.d.ts +1 -1
- package/dist/{chunk-MIBKEW7A.js → chunk-2VXWFYJE.js} +3 -3
- package/dist/{chunk-3YTTAGPB.js → chunk-3DVBKTSO.js} +2 -2
- package/dist/{chunk-EIR5VLIH.js → chunk-4K7IW3F7.js} +2 -2
- package/dist/chunk-4K7IW3F7.js.map +1 -0
- package/dist/{chunk-JTSVMJHV.js → chunk-4XDGYCZI.js} +3 -3
- package/dist/chunk-573TEZCD.js +88 -0
- package/dist/chunk-573TEZCD.js.map +1 -0
- package/dist/{chunk-HQSBYI5X.js → chunk-57HVIG5U.js} +2 -2
- package/dist/{chunk-PMVPCZJZ.js → chunk-6433HV72.js} +2 -2
- package/dist/{chunk-N6TRHP72.js → chunk-6TAX66IA.js} +2 -2
- package/dist/{chunk-AGKIG3YA.js → chunk-6VALIZKG.js} +2 -2
- package/dist/{chunk-YQ3CBLL4.js → chunk-76PL4XLG.js} +512 -8
- package/dist/chunk-76PL4XLG.js.map +1 -0
- package/dist/{chunk-4NZHHGVL.js → chunk-7BDZTALN.js} +4 -1
- package/dist/chunk-7BDZTALN.js.map +1 -0
- package/dist/{chunk-NS5ETDYD.js → chunk-7BEPVIH3.js} +3 -3
- package/dist/{chunk-JG22O53B.js → chunk-7CBKAQIG.js} +2 -1
- package/dist/chunk-7CBKAQIG.js.map +1 -0
- package/dist/{chunk-LYIZXQYY.js → chunk-7KFIMGMP.js} +2 -2
- package/dist/{chunk-LWVO2QZV.js → chunk-7QOO4LGC.js} +56 -56
- package/dist/chunk-AAXJNINV.js +55 -0
- package/dist/chunk-AAXJNINV.js.map +1 -0
- package/dist/{chunk-56BSXSHC.js → chunk-AB3A7EFH.js} +31 -2
- package/dist/{chunk-56BSXSHC.js.map → chunk-AB3A7EFH.js.map} +1 -1
- package/dist/{chunk-CCTVAVTT.js → chunk-AUO2LJ3K.js} +2 -2
- package/dist/{chunk-ALCJRQ72.js → chunk-AYDDB3XI.js} +2 -2
- package/dist/{chunk-3TMYV3LP.js → chunk-AYYGRVRP.js} +5 -5
- package/dist/{chunk-W6TSGWYS.js → chunk-AZAA5DNP.js} +2 -2
- package/dist/{chunk-WTOE7CW4.js → chunk-BKYPJUQL.js} +122 -16
- package/dist/chunk-BKYPJUQL.js.map +1 -0
- package/dist/{chunk-6JJT5AKI.js → chunk-BQUEAVNW.js} +2 -2
- package/dist/{chunk-2NLLXCJG.js → chunk-BXLOS5AJ.js} +2 -2
- package/dist/{chunk-CEH2AFXG.js → chunk-C24UZSFW.js} +6 -6
- package/dist/{chunk-ZPN7W3OP.js → chunk-CDUUDBWJ.js} +3 -3
- package/dist/{chunk-35NN3ZFA.js → chunk-CTVWELNK.js} +21 -3
- package/dist/chunk-CTVWELNK.js.map +1 -0
- package/dist/{chunk-Y23B2QXP.js → chunk-D27J626P.js} +2 -2
- package/dist/{chunk-2572MRP2.js → chunk-DHTQP334.js} +2 -2
- package/dist/{chunk-HJQZQUPC.js → chunk-DJZWNKFO.js} +5 -5
- package/dist/{chunk-X7Y7WX73.js → chunk-DQEMWVMT.js} +1 -1
- package/dist/{chunk-VJ6ECBIP.js → chunk-E4MVQQVX.js} +2 -2
- package/dist/{chunk-SYJ6EKKE.js → chunk-EIVIB73I.js} +2 -2
- package/dist/{chunk-HUNSEO5U.js → chunk-EV3YFLCB.js} +2 -2
- package/dist/{chunk-GEULB2VI.js → chunk-FC7TIRFS.js} +21 -1
- package/dist/chunk-FC7TIRFS.js.map +1 -0
- package/dist/{chunk-VPGRXEAB.js → chunk-G57LQRP6.js} +2 -2
- package/dist/{chunk-BC4QD3FM.js → chunk-GN55KU2P.js} +2 -2
- package/dist/{chunk-4W6INNXO.js → chunk-GUXS322H.js} +2 -2
- package/dist/{chunk-DBXZZIDU.js → chunk-H5FW4S5Q.js} +434 -693
- package/dist/chunk-H5FW4S5Q.js.map +1 -0
- package/dist/chunk-I32NKXE2.js +879 -0
- package/dist/chunk-I32NKXE2.js.map +1 -0
- package/dist/{chunk-3MADV4YC.js → chunk-IQSC3V2E.js} +2 -2
- package/dist/{chunk-UYCIS6V5.js → chunk-JCWY73FK.js} +2 -2
- package/dist/{chunk-T42L3S6A.js → chunk-LBWQ65SX.js} +4 -4
- package/dist/{chunk-MSTNSVXI.js → chunk-LDBFXD4F.js} +2 -1
- package/dist/chunk-LDBFXD4F.js.map +1 -0
- package/dist/{chunk-CEQF6L5K.js → chunk-LUNJ3WFO.js} +9 -7
- package/dist/chunk-LUNJ3WFO.js.map +1 -0
- package/dist/{chunk-256FBCVX.js → chunk-M4AHBM72.js} +7 -7
- package/dist/{chunk-YEQEGSJA.js → chunk-MBDJJTAT.js} +3 -3
- package/dist/{chunk-IAY7YBXS.js → chunk-MRTUN665.js} +2 -2
- package/dist/{chunk-JFJ3MHGV.js → chunk-NXKJHSDN.js} +1 -1
- package/dist/chunk-NXKJHSDN.js.map +1 -0
- package/dist/{chunk-R3AAOKR2.js → chunk-NZWEEALH.js} +2 -2
- package/dist/{chunk-I2HTKOOP.js → chunk-ODZG724P.js} +2 -2
- package/dist/{chunk-7QFBLYFP.js → chunk-OJD4WS2E.js} +3 -3
- package/dist/{chunk-CUS6S7PN.js → chunk-OLWTCWQ2.js} +9 -9
- package/dist/chunk-OLWTCWQ2.js.map +1 -0
- package/dist/{chunk-53ENM6F6.js → chunk-P4DHENRE.js} +2 -2
- package/dist/{chunk-DEFI2QBT.js → chunk-PAYGC3BD.js} +52 -22
- package/dist/chunk-PAYGC3BD.js.map +1 -0
- package/dist/{chunk-KPBLJCCV.js → chunk-PDVQ5JU3.js} +2 -2
- package/dist/{chunk-7BY7V4YX.js → chunk-Q4WONDMJ.js} +4 -3
- package/dist/{chunk-7BY7V4YX.js.map → chunk-Q4WONDMJ.js.map} +1 -1
- package/dist/{chunk-ESCQ6LY7.js → chunk-QFMO32TO.js} +3 -3
- package/dist/{chunk-HQSPXTQO.js → chunk-QXIQPCCN.js} +1 -1
- package/dist/{chunk-CFRBTATE.js → chunk-R47WINCY.js} +3 -3
- package/dist/{chunk-G72IPMR7.js → chunk-R4OCGPSH.js} +2 -2
- package/dist/{chunk-LCU5R6TQ.js → chunk-RAIUTAZZ.js} +22 -3
- package/dist/chunk-RAIUTAZZ.js.map +1 -0
- package/dist/chunk-RIAM7DND.js +167 -0
- package/dist/chunk-RIAM7DND.js.map +1 -0
- package/dist/{chunk-VZVP2W4O.js → chunk-RK4WXUI2.js} +2 -2
- package/dist/{chunk-JBPKEARU.js → chunk-RKNJBZ55.js} +4 -4
- package/dist/{chunk-6L27N6YI.js → chunk-S7Q5CM7E.js} +2 -2
- package/dist/{chunk-CTQRPANJ.js → chunk-SVSRPG6M.js} +2 -2
- package/dist/{chunk-GXWDWOWP.js → chunk-TDKSCV62.js} +2 -2
- package/dist/{chunk-S2VBSTTA.js → chunk-THG4GYIE.js} +2 -2
- package/dist/{chunk-IXRC7EQG.js → chunk-TR7DGXGI.js} +2 -2
- package/dist/{chunk-63FHSH7E.js → chunk-TYUS5TLG.js} +4 -4
- package/dist/{chunk-7PWWGYGO.js → chunk-URHCUXKI.js} +2 -2
- package/dist/{chunk-Z54TXZ2F.js → chunk-VA5KMSAE.js} +16 -7
- package/dist/chunk-VA5KMSAE.js.map +1 -0
- package/dist/{chunk-KQAFEZQX.js → chunk-VDX2J7OX.js} +2 -2
- package/dist/{chunk-MUJ4QFUQ.js → chunk-W4BMEGQA.js} +4 -4
- package/dist/{chunk-5HK3CJAR.js → chunk-W675UJCZ.js} +2 -2
- package/dist/{chunk-3PXVYJMC.js → chunk-WN5FSGLE.js} +2077 -215
- package/dist/chunk-WN5FSGLE.js.map +1 -0
- package/dist/{chunk-3RHFGGI5.js → chunk-YF6UHWOV.js} +30 -10
- package/dist/chunk-YF6UHWOV.js.map +1 -0
- package/dist/{chunk-X5SDZMO7.js → chunk-YHCBJULX.js} +2 -2
- package/dist/{chunk-5UYSCYR7.js → chunk-Z4RPXHJH.js} +4 -4
- package/dist/{cli-Pulnz-qm.d.ts → cli-ChKeYMZv.d.ts} +5 -5
- package/dist/cli.d.ts +25 -25
- package/dist/cli.js +81 -78
- package/dist/coding/pre-action-gate.d.ts +2 -60
- package/dist/compounding/engine.d.ts +4 -2
- package/dist/compounding/engine.js +17 -16
- package/dist/compounding/preference-consolidator.d.ts +3 -1
- package/dist/compression-optimizer.d.ts +3 -1
- package/dist/config.d.ts +3 -1
- package/dist/config.js +11 -1
- package/dist/connectors/codex-materialize-runner.d.ts +3 -1
- package/dist/connectors/codex-materialize-runner.js +16 -15
- package/dist/connectors/codex-materialize.d.ts +3 -1
- package/dist/connectors/index.d.ts +3 -1
- package/dist/connectors/index.js +16 -15
- package/dist/consolidation-provenance-check.d.ts +4 -2
- package/dist/consolidation-undo.d.ts +4 -2
- package/dist/contradiction/index.d.ts +10 -270
- package/dist/contradiction/index.js +20 -7
- package/dist/{contradiction-review-QKJH5DKD.js → contradiction-review-WRVLRWHS.js} +6 -2
- package/dist/{contradiction-scan-VOTQRRSX.js → contradiction-scan-AKUWPX5N.js} +5 -3
- package/dist/converge-config.d.ts +3 -1
- package/dist/convergence-refresh.d.ts +4 -2
- package/dist/convergence-refresh.js +18 -17
- package/dist/conversation-index/backend.d.ts +3 -1
- package/dist/conversation-index/chunker.d.ts +3 -1
- package/dist/conversation-index/faiss-adapter.d.ts +3 -1
- package/dist/conversation-index/indexer.d.ts +3 -1
- package/dist/conversation-index/search.d.ts +3 -1
- package/dist/corpus-watermark.d.ts +3 -1
- package/dist/corpus-watermark.js +18 -17
- package/dist/cross-lingual-recall.d.ts +3 -1
- package/dist/day-summary.d.ts +3 -1
- package/dist/delinearize.d.ts +3 -1
- package/dist/dependency-propagation-config.d.ts +3 -1
- package/dist/{dependency-propagation-delivery-Co17gxYb.d.ts → dependency-propagation-delivery-B8ZMBBCY.d.ts} +1 -1
- package/dist/direct-answer-wiring.d.ts +3 -1
- package/dist/direct-answer.d.ts +3 -1
- package/dist/embedding-fallback.d.ts +3 -1
- package/dist/enrichment/index.d.ts +3 -1
- package/dist/entity-origin-fields.d.ts +3 -1
- package/dist/entity-retrieval.d.ts +4 -2
- package/dist/entity-retrieval.js +16 -15
- package/dist/entity-schema.d.ts +3 -1
- package/dist/episodic-context.d.ts +3 -1
- package/dist/explicit-capture.d.ts +12 -12
- package/dist/explicit-capture.js +7 -6
- package/dist/external-wiki-access.d.ts +41 -42
- package/dist/external-wiki-access.js +37 -36
- package/dist/external-wiki-collection-registration.d.ts +3 -1
- package/dist/external-wiki-collection.d.ts +3 -1
- package/dist/external-wiki-mcp-tools.d.ts +40 -40
- package/dist/extraction-error-classification.d.ts +3 -1
- package/dist/extraction-faithfulness.d.ts +3 -1
- package/dist/extraction-judge-telemetry.d.ts +3 -1
- package/dist/extraction-judge-training.d.ts +3 -1
- package/dist/extraction-judge.d.ts +3 -1
- package/dist/extraction-judge.js +2 -2
- package/dist/extraction-liveness.d.ts +3 -1
- package/dist/extraction-normalization.d.ts +3 -1
- package/dist/extraction-normalization.js +2 -2
- package/dist/extraction-prompt.d.ts +4 -2
- package/dist/extraction-prompt.js +1 -1
- package/dist/extraction-source-grounding-rules.d.ts +3 -1
- package/dist/extraction-source-grounding.d.ts +3 -1
- package/dist/extraction.d.ts +3 -1
- package/dist/extraction.js +22 -21
- package/dist/fallback-llm.d.ts +3 -1
- package/dist/graph-dashboard-diff.d.ts +3 -1
- package/dist/graph-dashboard-key.d.ts +3 -1
- package/dist/graph-dashboard-parser.d.ts +3 -1
- package/dist/graph-edge-reinforcement.d.ts +3 -1
- package/dist/graph-path-reconstruction.d.ts +3 -1
- package/dist/graph-path-scoring.d.ts +3 -1
- package/dist/graph-snapshot.d.ts +3 -1
- package/dist/graph.d.ts +3 -1
- package/dist/harmonic-retrieval.js +1 -1
- package/dist/importance.d.ts +3 -1
- package/dist/importers/index.d.ts +3 -1
- package/dist/in-flight-reads.d.ts +3 -1
- package/dist/index-CexDrJzC.d.ts +284 -0
- package/dist/index.d.ts +946 -707
- package/dist/index.js +253 -151
- package/dist/intent.d.ts +3 -1
- package/dist/lcm/engine.d.ts +3 -1
- package/dist/lcm/engine.js +3 -3
- package/dist/lcm/index.d.ts +3 -1
- package/dist/lcm/index.js +6 -6
- package/dist/lcm/tools.d.ts +3 -1
- package/dist/lifecycle.d.ts +3 -1
- package/dist/live-connectors-runner.d.ts +3 -1
- package/dist/local-llm.d.ts +3 -1
- package/dist/local-model-endpoint.d.ts +3 -1
- package/dist/maintenance/memory-governance.d.ts +3 -1
- package/dist/maintenance/memory-governance.js +16 -15
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +4 -2
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +16 -15
- package/dist/maintenance/rebuild-memory-projection.d.ts +4 -2
- package/dist/maintenance/rebuild-memory-projection.js +17 -16
- package/dist/{maintenance-DiSLtVN7.d.ts → maintenance-nkdtSrVr.d.ts} +3 -3
- package/dist/mcp-memory-inspector-app.d.ts +37 -37
- package/dist/mcp-read-only-tools.js +1 -1
- package/dist/memory-action-policy.d.ts +3 -1
- package/dist/memory-cache.d.ts +3 -1
- package/dist/memory-lifecycle-ledger-utils.d.ts +3 -1
- package/dist/memory-projection-store.d.ts +3 -1
- package/dist/memory-provenance.d.ts +3 -1
- package/dist/memory-snapshot.d.ts +3 -1
- package/dist/memory-subject-cli.d.ts +177 -0
- package/dist/memory-subject-cli.js +16 -0
- package/dist/memory-subject.d.ts +128 -0
- package/dist/memory-subject.js +44 -0
- package/dist/memory-subject.js.map +1 -0
- package/dist/memory-worth-outcomes.d.ts +7 -4
- package/dist/memory-worth-outcomes.js +1 -1
- package/dist/models-json.d.ts +3 -1
- package/dist/namespaces/migrate.d.ts +5 -3
- package/dist/namespaces/migrate.js +17 -16
- package/dist/namespaces/principal.d.ts +3 -1
- package/dist/namespaces/search.d.ts +3 -1
- package/dist/namespaces/search.js +6 -6
- package/dist/namespaces/storage.d.ts +5 -3
- package/dist/namespaces/storage.js +16 -15
- package/dist/native-knowledge.d.ts +3 -1
- package/dist/offline-sync-impression-drain.d.ts +3 -1
- package/dist/operator-doctor-corpus.d.ts +3 -1
- package/dist/operator-doctor-corpus.js +19 -18
- package/dist/operator-doctor-replica.d.ts +3 -1
- package/dist/operator-toolkit.d.ts +5 -3
- package/dist/operator-toolkit.js +29 -24
- package/dist/orchestration/compression-guideline-coordinator.d.ts +4 -2
- package/dist/orchestration/maintenance.d.ts +6 -4
- package/dist/orchestration/maintenance.js +22 -21
- package/dist/{orchestrator-DzCaxNS4.d.ts → orchestrator-Bvq1-RQs.d.ts} +23 -9
- package/dist/orchestrator.d.ts +12 -12
- package/dist/orchestrator.js +111 -108
- package/dist/patterns-cli.d.ts +3 -1
- package/dist/{pipeline-HJ8DKbFl.d.ts → pipeline-C8vfIiTX.d.ts} +1 -1
- package/dist/policy-runtime.d.ts +3 -1
- package/dist/proactive-contention.d.ts +3 -1
- package/dist/provenance.d.ts +3 -1
- package/dist/{public-http-DwXauTX3.d.ts → public-http-Cy0aYbys.d.ts} +1 -1
- package/dist/{qmd-BzxluoLt.d.ts → qmd-B9p1SZTZ.d.ts} +1 -1
- package/dist/qmd-preflight.d.ts +4 -2
- package/dist/qmd-recall-cache.d.ts +3 -1
- package/dist/qmd.d.ts +4 -2
- package/dist/qmd.js +4 -4
- package/dist/recall-concurrency-config.d.ts +3 -1
- package/dist/recall-disclosure-escalation.d.ts +3 -1
- package/dist/recall-explain-renderer.d.ts +3 -1
- package/dist/recall-explain-renderer.js +3 -3
- package/dist/recall-memory-map.d.ts +3 -1
- package/dist/recall-planner-llm.d.ts +3 -1
- package/dist/recall-state.d.ts +3 -1
- package/dist/recall-tag-filter.d.ts +3 -1
- package/dist/recall-timings.d.ts +3 -1
- package/dist/recall-xray-cli.d.ts +3 -1
- package/dist/recall-xray-cli.js +4 -4
- package/dist/recall-xray-renderer.d.ts +3 -1
- package/dist/recall-xray-renderer.js +3 -3
- package/dist/recall-xray.d.ts +3 -1
- package/dist/recall-xray.js +2 -2
- package/dist/reconcile/cursor.d.ts +3 -1
- package/dist/reconcile/manifest.d.ts +3 -1
- package/dist/reconcile/manifest.js +3 -3
- package/dist/reconcile/plan.d.ts +3 -1
- package/dist/replay/normalizers/chatgpt.d.ts +3 -1
- package/dist/replay/normalizers/claude.d.ts +3 -1
- package/dist/replay/normalizers/openclaw.d.ts +3 -1
- package/dist/replay/normalizers/shared.d.ts +3 -1
- package/dist/replay/runner.d.ts +3 -1
- package/dist/replay/types.d.ts +3 -1
- package/dist/replica-divergence.d.ts +3 -1
- package/dist/replica-peers-config.d.ts +3 -1
- package/dist/resolution-4552BNRV.js +36 -0
- package/dist/resolution-4552BNRV.js.map +1 -0
- package/dist/resolve-auth-token.d.ts +3 -1
- package/dist/resume-bundles.js +9 -2
- package/dist/retrieval-agents.d.ts +4 -2
- package/dist/retrieval-tiers.d.ts +3 -1
- package/dist/routing/engine.d.ts +3 -1
- package/dist/routing/store.d.ts +3 -1
- package/dist/salvage-envelope.d.ts +3 -1
- package/dist/salvage-envelope.js +10 -2
- package/dist/schemas.d.ts +130 -116
- package/dist/schemas.js +1 -1
- package/dist/{scope-profiles-CEMZz0t5.d.ts → scope-profiles-DLrRxFWR.d.ts} +1 -1
- package/dist/search/embed-helper.d.ts +3 -1
- package/dist/search/factory.d.ts +3 -1
- package/dist/search/factory.js +5 -5
- package/dist/search/index.d.ts +3 -1
- package/dist/search/index.js +9 -9
- package/dist/search/lancedb-backend.d.ts +3 -1
- package/dist/search/meilisearch-backend.d.ts +3 -1
- package/dist/search/noop-backend.d.ts +3 -1
- package/dist/search/orama-backend.d.ts +3 -1
- package/dist/search/port.d.ts +3 -1
- package/dist/search/remote-backend.d.ts +3 -1
- package/dist/{semantic-TddhF0y7.d.ts → semantic-BalR6EXU.d.ts} +1 -1
- package/dist/{semantic-consolidation-D9dYj6vu.d.ts → semantic-consolidation-DlN6xe20.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +4 -2
- package/dist/semantic-consolidation.js +17 -16
- package/dist/semantic-rule-promotion.js +16 -15
- package/dist/semantic-rule-verifier.d.ts +3 -1
- package/dist/semantic-rule-verifier.js +16 -15
- package/dist/{service-_qgST_0y.d.ts → service-GkYyVfm9.d.ts} +2 -2
- package/dist/session-observer-bands.d.ts +3 -1
- package/dist/session-observer-state.d.ts +3 -1
- package/dist/shared-context/manager.d.ts +13 -11
- package/dist/signal.d.ts +3 -1
- package/dist/source-agent-qualifier.d.ts +3 -1
- package/dist/source-agent-qualifier.js +18 -17
- package/dist/{storage-B9lbNTYE.d.ts → storage-BIDzuKIn.d.ts} +3 -2
- package/dist/storage.d.ts +4 -2
- package/dist/storage.js +18 -17
- package/dist/subject-config.d.ts +40 -0
- package/dist/subject-config.js +20 -0
- package/dist/subject-config.js.map +1 -0
- package/dist/summarizer.d.ts +3 -1
- package/dist/summary-snapshot.d.ts +3 -1
- package/dist/support-passport/index.d.ts +43 -43
- package/dist/support-passport/index.js +39 -38
- package/dist/temporal-supersession.d.ts +4 -2
- package/dist/temporal-timeline-recall.d.ts +3 -1
- package/dist/temporal-validity.d.ts +3 -1
- package/dist/threading.d.ts +3 -1
- package/dist/tier-migration.d.ts +4 -2
- package/dist/tier-routing.d.ts +3 -1
- package/dist/topics.d.ts +3 -1
- package/dist/transcript.d.ts +3 -1
- package/dist/transfer/backup.js +2 -2
- package/dist/transfer/capsule-export.js +2 -2
- package/dist/transfer/capsule-import.js +2 -2
- package/dist/transfer/types.d.ts +86 -86
- package/dist/trust-score-stage.d.ts +3 -1
- package/dist/trust-score.d.ts +3 -1
- package/dist/{types-BrEzuxPA.d.ts → types-BxAcOl5Q.d.ts} +360 -32
- package/dist/types.d.ts +3 -1
- package/dist/types.js +1 -1
- package/dist/utility-runtime.d.ts +3 -1
- package/dist/verified-recall.js +16 -15
- package/dist/who-knows-cli.d.ts +40 -40
- package/dist/who-knows-cli.js +17 -16
- package/dist/who-knows.d.ts +42 -42
- package/dist/who-knows.js +16 -15
- package/dist/write-envelope.d.ts +7 -2
- package/dist/write-envelope.js +10 -1
- package/package.json +2 -2
- package/scripts/build-with-heap.mjs +1 -1
- package/src/access-boundary.ts +6 -0
- package/src/access-http.ts +6 -5
- package/src/access-mcp-admin-tools.ts +38 -0
- package/src/access-mcp-output-schemas.ts +20 -0
- package/src/access-mcp.ts +8 -8
- package/src/access-operations-batch.ts +13 -0
- package/src/access-service.ts +112 -0
- package/src/access-surface-catalog.test.ts +24 -0
- package/src/access-surface-catalog.ts +6 -0
- package/src/coding/action-gate.test.ts +341 -0
- package/src/coding/action-gate.ts +556 -0
- package/src/config.ts +15 -17
- package/src/contradiction/contradiction-review.ts +50 -4
- package/src/contradiction/contradiction-scan.ts +14 -3
- package/src/contradiction/resolution.ts +50 -2
- package/src/extraction-prompt.ts +1 -0
- package/src/extraction.ts +4 -1
- package/src/index.ts +9 -9
- package/src/mcp-read-only-tools.ts +1 -0
- package/src/memory-subject-cli.ts +135 -0
- package/src/memory-subject.test.ts +48 -0
- package/src/memory-subject.ts +314 -0
- package/src/memory-worth-outcomes.test.ts +6 -2
- package/src/memory-worth-outcomes.ts +11 -7
- package/src/operator-toolkit.ts +1 -1
- package/src/orchestration/extraction-persist.ts +48 -48
- package/src/orchestration/recall-internal.ts +6 -5
- package/src/orchestration/recall-rerank-coordinator.ts +123 -4
- package/src/orchestration/recall-result-formatter.ts +6 -2
- package/src/orchestration/recall-search-pipeline.ts +14 -1
- package/src/preferences/drift-config.ts +118 -0
- package/src/preferences/drift-recall.ts +133 -0
- package/src/preferences/drift-types.ts +87 -0
- package/src/preferences/index.ts +12 -0
- package/src/preferences/preference-drift.test.ts +690 -0
- package/src/preferences/preference-drift.ts +724 -0
- package/src/procedural/library-maintenance.test.ts +582 -0
- package/src/procedural/library-maintenance.ts +546 -0
- package/src/procedural/maintenance-config.ts +78 -0
- package/src/procedural/procedure-recall.ts +29 -1
- package/src/procedural/procedure-stats.ts +20 -0
- package/src/review/review-deck-access.test.ts +325 -0
- package/src/review/review-deck-http-base.ts +133 -0
- package/src/review/review-deck-mutation.test.ts +417 -0
- package/src/review/review-deck-mutation.ts +677 -0
- package/src/review/review-deck-snapshot.ts +196 -0
- package/src/review/review-deck-surface.ts +117 -0
- package/src/review/review-deck.test.ts +347 -0
- package/src/review/review-deck.ts +311 -0
- package/src/schemas.ts +7 -0
- package/src/spaces/index.ts +38 -2
- package/src/storage.ts +10 -8
- package/src/subject-config.ts +80 -0
- package/src/types.ts +33 -32
- package/src/write-envelope.test.ts +14 -0
- package/src/write-envelope.ts +24 -3
- package/dist/chunk-35NN3ZFA.js.map +0 -1
- package/dist/chunk-3PXVYJMC.js.map +0 -1
- package/dist/chunk-3RHFGGI5.js.map +0 -1
- package/dist/chunk-4NZHHGVL.js.map +0 -1
- package/dist/chunk-CEQF6L5K.js.map +0 -1
- package/dist/chunk-CUS6S7PN.js.map +0 -1
- package/dist/chunk-DBXZZIDU.js.map +0 -1
- package/dist/chunk-DEFI2QBT.js.map +0 -1
- package/dist/chunk-EIR5VLIH.js.map +0 -1
- package/dist/chunk-GEULB2VI.js.map +0 -1
- package/dist/chunk-JFJ3MHGV.js.map +0 -1
- package/dist/chunk-JG22O53B.js.map +0 -1
- package/dist/chunk-LCU5R6TQ.js.map +0 -1
- package/dist/chunk-MDVBCPOS.js +0 -402
- package/dist/chunk-MDVBCPOS.js.map +0 -1
- package/dist/chunk-MSTNSVXI.js.map +0 -1
- package/dist/chunk-WTOE7CW4.js.map +0 -1
- package/dist/chunk-YQ3CBLL4.js.map +0 -1
- package/dist/chunk-Z54TXZ2F.js.map +0 -1
- package/dist/resolution-DKMBPXHI.js +0 -18
- /package/dist/{capsule-crypto-7FJQINUR.js.map → capsule-crypto-YO5QJ6L3.js.map} +0 -0
- /package/dist/{chunk-MIBKEW7A.js.map → chunk-2VXWFYJE.js.map} +0 -0
- /package/dist/{chunk-3YTTAGPB.js.map → chunk-3DVBKTSO.js.map} +0 -0
- /package/dist/{chunk-JTSVMJHV.js.map → chunk-4XDGYCZI.js.map} +0 -0
- /package/dist/{chunk-HQSBYI5X.js.map → chunk-57HVIG5U.js.map} +0 -0
- /package/dist/{chunk-PMVPCZJZ.js.map → chunk-6433HV72.js.map} +0 -0
- /package/dist/{chunk-N6TRHP72.js.map → chunk-6TAX66IA.js.map} +0 -0
- /package/dist/{chunk-AGKIG3YA.js.map → chunk-6VALIZKG.js.map} +0 -0
- /package/dist/{chunk-NS5ETDYD.js.map → chunk-7BEPVIH3.js.map} +0 -0
- /package/dist/{chunk-LYIZXQYY.js.map → chunk-7KFIMGMP.js.map} +0 -0
- /package/dist/{chunk-LWVO2QZV.js.map → chunk-7QOO4LGC.js.map} +0 -0
- /package/dist/{chunk-CCTVAVTT.js.map → chunk-AUO2LJ3K.js.map} +0 -0
- /package/dist/{chunk-ALCJRQ72.js.map → chunk-AYDDB3XI.js.map} +0 -0
- /package/dist/{chunk-3TMYV3LP.js.map → chunk-AYYGRVRP.js.map} +0 -0
- /package/dist/{chunk-W6TSGWYS.js.map → chunk-AZAA5DNP.js.map} +0 -0
- /package/dist/{chunk-6JJT5AKI.js.map → chunk-BQUEAVNW.js.map} +0 -0
- /package/dist/{chunk-2NLLXCJG.js.map → chunk-BXLOS5AJ.js.map} +0 -0
- /package/dist/{chunk-CEH2AFXG.js.map → chunk-C24UZSFW.js.map} +0 -0
- /package/dist/{chunk-ZPN7W3OP.js.map → chunk-CDUUDBWJ.js.map} +0 -0
- /package/dist/{chunk-Y23B2QXP.js.map → chunk-D27J626P.js.map} +0 -0
- /package/dist/{chunk-2572MRP2.js.map → chunk-DHTQP334.js.map} +0 -0
- /package/dist/{chunk-HJQZQUPC.js.map → chunk-DJZWNKFO.js.map} +0 -0
- /package/dist/{chunk-X7Y7WX73.js.map → chunk-DQEMWVMT.js.map} +0 -0
- /package/dist/{chunk-VJ6ECBIP.js.map → chunk-E4MVQQVX.js.map} +0 -0
- /package/dist/{chunk-SYJ6EKKE.js.map → chunk-EIVIB73I.js.map} +0 -0
- /package/dist/{chunk-HUNSEO5U.js.map → chunk-EV3YFLCB.js.map} +0 -0
- /package/dist/{chunk-VPGRXEAB.js.map → chunk-G57LQRP6.js.map} +0 -0
- /package/dist/{chunk-BC4QD3FM.js.map → chunk-GN55KU2P.js.map} +0 -0
- /package/dist/{chunk-4W6INNXO.js.map → chunk-GUXS322H.js.map} +0 -0
- /package/dist/{chunk-3MADV4YC.js.map → chunk-IQSC3V2E.js.map} +0 -0
- /package/dist/{chunk-UYCIS6V5.js.map → chunk-JCWY73FK.js.map} +0 -0
- /package/dist/{chunk-T42L3S6A.js.map → chunk-LBWQ65SX.js.map} +0 -0
- /package/dist/{chunk-256FBCVX.js.map → chunk-M4AHBM72.js.map} +0 -0
- /package/dist/{chunk-YEQEGSJA.js.map → chunk-MBDJJTAT.js.map} +0 -0
- /package/dist/{chunk-IAY7YBXS.js.map → chunk-MRTUN665.js.map} +0 -0
- /package/dist/{chunk-R3AAOKR2.js.map → chunk-NZWEEALH.js.map} +0 -0
- /package/dist/{chunk-I2HTKOOP.js.map → chunk-ODZG724P.js.map} +0 -0
- /package/dist/{chunk-7QFBLYFP.js.map → chunk-OJD4WS2E.js.map} +0 -0
- /package/dist/{chunk-53ENM6F6.js.map → chunk-P4DHENRE.js.map} +0 -0
- /package/dist/{chunk-KPBLJCCV.js.map → chunk-PDVQ5JU3.js.map} +0 -0
- /package/dist/{chunk-ESCQ6LY7.js.map → chunk-QFMO32TO.js.map} +0 -0
- /package/dist/{chunk-HQSPXTQO.js.map → chunk-QXIQPCCN.js.map} +0 -0
- /package/dist/{chunk-CFRBTATE.js.map → chunk-R47WINCY.js.map} +0 -0
- /package/dist/{chunk-G72IPMR7.js.map → chunk-R4OCGPSH.js.map} +0 -0
- /package/dist/{chunk-VZVP2W4O.js.map → chunk-RK4WXUI2.js.map} +0 -0
- /package/dist/{chunk-JBPKEARU.js.map → chunk-RKNJBZ55.js.map} +0 -0
- /package/dist/{chunk-6L27N6YI.js.map → chunk-S7Q5CM7E.js.map} +0 -0
- /package/dist/{chunk-CTQRPANJ.js.map → chunk-SVSRPG6M.js.map} +0 -0
- /package/dist/{chunk-GXWDWOWP.js.map → chunk-TDKSCV62.js.map} +0 -0
- /package/dist/{chunk-S2VBSTTA.js.map → chunk-THG4GYIE.js.map} +0 -0
- /package/dist/{chunk-IXRC7EQG.js.map → chunk-TR7DGXGI.js.map} +0 -0
- /package/dist/{chunk-63FHSH7E.js.map → chunk-TYUS5TLG.js.map} +0 -0
- /package/dist/{chunk-7PWWGYGO.js.map → chunk-URHCUXKI.js.map} +0 -0
- /package/dist/{chunk-KQAFEZQX.js.map → chunk-VDX2J7OX.js.map} +0 -0
- /package/dist/{chunk-MUJ4QFUQ.js.map → chunk-W4BMEGQA.js.map} +0 -0
- /package/dist/{chunk-5HK3CJAR.js.map → chunk-W675UJCZ.js.map} +0 -0
- /package/dist/{chunk-X5SDZMO7.js.map → chunk-YHCBJULX.js.map} +0 -0
- /package/dist/{chunk-5UYSCYR7.js.map → chunk-Z4RPXHJH.js.map} +0 -0
- /package/dist/{contradiction-review-QKJH5DKD.js.map → contradiction-review-WRVLRWHS.js.map} +0 -0
- /package/dist/{contradiction-scan-VOTQRRSX.js.map → contradiction-scan-AKUWPX5N.js.map} +0 -0
- /package/dist/{resolution-DKMBPXHI.js.map → memory-subject-cli.js.map} +0 -0
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memory subject: user-centric vs agent-centric classification (issue #2372).
|
|
3
|
+
*
|
|
4
|
+
* Scope says WHERE a memory lives; subject says WHOM it is about — and that
|
|
5
|
+
* is what determines where it may safely go. `user` memories model one
|
|
6
|
+
* person (preferences, relationships, biography, moments, commitments);
|
|
7
|
+
* `agent` memories model how to operate (procedures, principles,
|
|
8
|
+
* tool-usage lessons, debugging strategies, environment facts with no
|
|
9
|
+
* personal content).
|
|
10
|
+
*
|
|
11
|
+
* This module owns, in one place:
|
|
12
|
+
* - the deterministic write-time classification (category defaults with an
|
|
13
|
+
* optional extractor override),
|
|
14
|
+
* - the promotion guard shared by EVERY promotion surface (spaces promote
|
|
15
|
+
* AND scope-profile promotion targets — AGENTS.md §27 uniform gating),
|
|
16
|
+
* - read-only promotion-candidate surfacing (reuse-signaled agent-subject
|
|
17
|
+
* memories with no equivalent in the target layer), and
|
|
18
|
+
* - the deterministic backfill pass (shadow/apply, no LLM).
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import { ContentHashIndex } from "./storage/content-hash-index.js";
|
|
22
|
+
import { sanitizeMemoryContent } from "./sanitize.js";
|
|
23
|
+
import type { McpTool } from "./access-mcp.js";
|
|
24
|
+
import type { MemoryCategory, MemoryFile, MemorySubject, SubjectGuardMode } from "./types.js";
|
|
25
|
+
|
|
26
|
+
export const SUBJECT_VALUES = ["user", "agent"] as const;
|
|
27
|
+
export const SUBJECT_GUARD_MODES = ["off", "warn", "enforce"] as const;
|
|
28
|
+
|
|
29
|
+
/** The CLI / per-call override that permits a user-subject promotion. */
|
|
30
|
+
export const SUBJECT_GUARD_OVERRIDE_FLAG = "--allow-user-subject";
|
|
31
|
+
|
|
32
|
+
export function isMemorySubject(value: unknown): value is MemorySubject {
|
|
33
|
+
return value === "user" || value === "agent";
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function isSubjectGuardMode(value: unknown): value is SubjectGuardMode {
|
|
37
|
+
return value === "off" || value === "warn" || value === "enforce";
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// ---------------------------------------------------------------------------
|
|
41
|
+
// Write-time classification
|
|
42
|
+
// ---------------------------------------------------------------------------
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Deterministic category defaults (issue #2372 §1):
|
|
46
|
+
* user — preference, relationship, moment, commitment
|
|
47
|
+
* agent — procedure, principle, skill
|
|
48
|
+
* Every other category has no default; the resolver falls back to `"user"`,
|
|
49
|
+
* the most-restrictive value (Review Prevention Checklist §36 — an unsafe
|
|
50
|
+
* enum default is never the convenient one).
|
|
51
|
+
*/
|
|
52
|
+
const SUBJECT_CATEGORY_DEFAULTS: Partial<Record<MemoryCategory, MemorySubject>> = {
|
|
53
|
+
preference: "user",
|
|
54
|
+
relationship: "user",
|
|
55
|
+
moment: "user",
|
|
56
|
+
commitment: "user",
|
|
57
|
+
procedure: "agent",
|
|
58
|
+
principle: "agent",
|
|
59
|
+
skill: "agent",
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export function subjectDefaultForCategory(category: MemoryCategory): MemorySubject {
|
|
63
|
+
return SUBJECT_CATEGORY_DEFAULTS[category] ?? "user";
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Resolve the write-time subject: the extractor's single-token value when it
|
|
68
|
+
* emitted a valid one, else the category default. Never reclassifies on read.
|
|
69
|
+
*/
|
|
70
|
+
export function resolveWriteSubject(
|
|
71
|
+
category: MemoryCategory,
|
|
72
|
+
extractorValue: unknown,
|
|
73
|
+
): MemorySubject {
|
|
74
|
+
return isMemorySubject(extractorValue) ? extractorValue : subjectDefaultForCategory(category);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// ---------------------------------------------------------------------------
|
|
78
|
+
// Promotion guard (uniform across every promotion surface — §27)
|
|
79
|
+
// ---------------------------------------------------------------------------
|
|
80
|
+
|
|
81
|
+
/** Scope-profile promotion targets that are shared layers. */
|
|
82
|
+
export function isSharedPromotionTarget(target: string): boolean {
|
|
83
|
+
return target === "teamProject" || target === "serverShared";
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export interface SubjectGuardDecision {
|
|
87
|
+
action: "allow" | "warn" | "reject";
|
|
88
|
+
/** Effective subject — an absent subject resolves to "user" (fail closed, §36). */
|
|
89
|
+
effectiveSubject: MemorySubject;
|
|
90
|
+
/** Structured reason; empty string when action === "allow". */
|
|
91
|
+
reason: string;
|
|
92
|
+
/** The override that permits this promotion when action is reject/warn. */
|
|
93
|
+
override: typeof SUBJECT_GUARD_OVERRIDE_FLAG;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Evaluate one promotion against the subject guard. Shared by the spaces
|
|
98
|
+
* promotion workflow and the scope-profile promotion targets so the two
|
|
99
|
+
* surfaces cannot drift (issue #2372 acceptance 2, AGENTS.md §27).
|
|
100
|
+
*
|
|
101
|
+
* - mode "off", non-shared targets, agent-subject memories, and explicit
|
|
102
|
+
* `allowUserSubject` overrides all allow.
|
|
103
|
+
* - a `user`-subject memory (or a memory with NO subject — fail closed)
|
|
104
|
+
* promoted to a shared layer warns under "warn" and rejects under
|
|
105
|
+
* "enforce", with the override named in the reason (§39: never a silent
|
|
106
|
+
* accept).
|
|
107
|
+
*/
|
|
108
|
+
export function evaluateSubjectGuard(params: {
|
|
109
|
+
subject: MemorySubject | undefined;
|
|
110
|
+
sharedTarget: boolean;
|
|
111
|
+
mode: SubjectGuardMode;
|
|
112
|
+
allowUserSubject?: boolean;
|
|
113
|
+
}): SubjectGuardDecision {
|
|
114
|
+
const effectiveSubject = params.subject ?? "user";
|
|
115
|
+
const base = { effectiveSubject, override: SUBJECT_GUARD_OVERRIDE_FLAG } as const;
|
|
116
|
+
if (params.mode === "off" || !params.sharedTarget || effectiveSubject === "agent") {
|
|
117
|
+
return { action: "allow", reason: "", ...base };
|
|
118
|
+
}
|
|
119
|
+
if (params.allowUserSubject === true) {
|
|
120
|
+
return { action: "allow", reason: "user-subject promotion override accepted", ...base };
|
|
121
|
+
}
|
|
122
|
+
return {
|
|
123
|
+
action: params.mode === "enforce" ? "reject" : "warn",
|
|
124
|
+
reason:
|
|
125
|
+
`subject=${effectiveSubject} memory targets a shared layer (team/server); ` +
|
|
126
|
+
`user-subject memories model one person and must not be shared; ` +
|
|
127
|
+
`override with ${SUBJECT_GUARD_OVERRIDE_FLAG} (allowUserSubject: true) if intended`,
|
|
128
|
+
...base,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// ---------------------------------------------------------------------------
|
|
133
|
+
// Promotion candidates (read-only surfacing — no auto-promotion)
|
|
134
|
+
// ---------------------------------------------------------------------------
|
|
135
|
+
|
|
136
|
+
export type PromotionReuseSignal = "reinforcement" | "memory_worth" | "access_count";
|
|
137
|
+
|
|
138
|
+
export interface PromotionCandidate {
|
|
139
|
+
id: string;
|
|
140
|
+
path: string;
|
|
141
|
+
category: MemoryCategory;
|
|
142
|
+
content: string;
|
|
143
|
+
accessCount: number;
|
|
144
|
+
reinforcementCount: number;
|
|
145
|
+
mwSuccess: number;
|
|
146
|
+
mwFail: number;
|
|
147
|
+
reuseSignal: PromotionReuseSignal;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/** Default reuse-signal threshold for `accessCount` (config `promotionCandidates.minAccessCount`). */
|
|
151
|
+
export const PROMOTION_CANDIDATES_DEFAULT_MIN_ACCESS = 3;
|
|
152
|
+
|
|
153
|
+
/** Canonical content form for target-equivalence checks (same normalize pipeline as dedup). */
|
|
154
|
+
export function promotionCandidateKey(content: string): string {
|
|
155
|
+
return ContentHashIndex.normalizeContent(sanitizeMemoryContent(content).text);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* List `subject: "agent"` memories that (a) are active, (b) show a reuse
|
|
160
|
+
* signal (`reinforcement_count > 0` OR `mw_success > mw_fail` OR
|
|
161
|
+
* `accessCount >= minAccessCount`), and (c) have no equivalent already in
|
|
162
|
+
* the promotion target layer (content-hash check via the dedup normalizer).
|
|
163
|
+
* Pure over the two memory lists; callers resolve namespaces.
|
|
164
|
+
*/
|
|
165
|
+
export function computePromotionCandidates(options: {
|
|
166
|
+
memories: MemoryFile[];
|
|
167
|
+
targetMemories: MemoryFile[];
|
|
168
|
+
minAccessCount: number;
|
|
169
|
+
limit?: number;
|
|
170
|
+
}): PromotionCandidate[] {
|
|
171
|
+
if (!Number.isFinite(options.minAccessCount) || options.minAccessCount < 0) {
|
|
172
|
+
throw new Error(
|
|
173
|
+
`computePromotionCandidates: minAccessCount must be a non-negative number (got ${String(options.minAccessCount)})`,
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
const targetKeys = new Set(
|
|
177
|
+
options.targetMemories.map((m) => promotionCandidateKey(m.content ?? "")),
|
|
178
|
+
);
|
|
179
|
+
const out: PromotionCandidate[] = [];
|
|
180
|
+
for (const memory of options.memories) {
|
|
181
|
+
const fm = memory.frontmatter;
|
|
182
|
+
if (fm.subject !== "agent") continue;
|
|
183
|
+
if ((fm.status ?? "active") !== "active") continue;
|
|
184
|
+
const reinforcementCount = fm.reinforcement_count ?? 0;
|
|
185
|
+
const mwSuccess = fm.mw_success ?? 0;
|
|
186
|
+
const mwFail = fm.mw_fail ?? 0;
|
|
187
|
+
const accessCount = fm.accessCount ?? 0;
|
|
188
|
+
let reuseSignal: PromotionReuseSignal | undefined;
|
|
189
|
+
if (reinforcementCount > 0) reuseSignal = "reinforcement";
|
|
190
|
+
else if (mwSuccess > mwFail) reuseSignal = "memory_worth";
|
|
191
|
+
else if (accessCount >= options.minAccessCount) reuseSignal = "access_count";
|
|
192
|
+
if (reuseSignal === undefined) continue;
|
|
193
|
+
if (targetKeys.has(promotionCandidateKey(memory.content ?? ""))) continue;
|
|
194
|
+
out.push({
|
|
195
|
+
id: fm.id,
|
|
196
|
+
path: memory.path,
|
|
197
|
+
category: fm.category,
|
|
198
|
+
content: memory.content ?? "",
|
|
199
|
+
|
|
200
|
+
accessCount,
|
|
201
|
+
reinforcementCount,
|
|
202
|
+
mwSuccess,
|
|
203
|
+
mwFail,
|
|
204
|
+
reuseSignal,
|
|
205
|
+
});
|
|
206
|
+
if (options.limit !== undefined && out.length >= options.limit) break;
|
|
207
|
+
}
|
|
208
|
+
return out;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
export interface PromotionCandidatesResult {
|
|
212
|
+
namespace: string;
|
|
213
|
+
targetNamespace: string;
|
|
214
|
+
minAccessCount: number;
|
|
215
|
+
candidates: PromotionCandidate[];
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
export const PROMOTION_CANDIDATES_MCP_TOOLS: McpTool[] = [
|
|
219
|
+
{
|
|
220
|
+
// Registered as `engram.promotion_candidates`; `withToolAliases` emits
|
|
221
|
+
// the canonical `remnic.promotion_candidates` alias (dual-naming).
|
|
222
|
+
name: "engram.promotion_candidates",
|
|
223
|
+
description:
|
|
224
|
+
"List agent-subject memories in the caller's namespace that are active, show a reuse signal (reinforcement_count > 0, mw_success > mw_fail, or accessCount >= threshold), and have no equivalent in the promotion target layer (default: the shared namespace). Read-only report; promotion itself uses the existing promotion commands (issue #2372).",
|
|
225
|
+
inputSchema: {
|
|
226
|
+
type: "object",
|
|
227
|
+
properties: {
|
|
228
|
+
namespace: {
|
|
229
|
+
type: "string",
|
|
230
|
+
description:
|
|
231
|
+
"Optional source namespace. Enforced against the caller's principal the same way recall is.",
|
|
232
|
+
},
|
|
233
|
+
targetNamespace: {
|
|
234
|
+
type: "string",
|
|
235
|
+
description: "Promotion target layer checked for existing equivalents. Default: the shared namespace.",
|
|
236
|
+
},
|
|
237
|
+
limit: {
|
|
238
|
+
type: "integer",
|
|
239
|
+
minimum: 1,
|
|
240
|
+
maximum: 100,
|
|
241
|
+
description: "Maximum candidates to return (default 20, max 100).",
|
|
242
|
+
},
|
|
243
|
+
},
|
|
244
|
+
additionalProperties: false,
|
|
245
|
+
},
|
|
246
|
+
},
|
|
247
|
+
];
|
|
248
|
+
|
|
249
|
+
// ---------------------------------------------------------------------------
|
|
250
|
+
// Backfill (governance shadow/apply — deterministic rules only, no LLM)
|
|
251
|
+
// ---------------------------------------------------------------------------
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Storage surface the backfill needs (mirrors pattern-reinforcement's
|
|
255
|
+
* structural interface so tests can pass an in-memory stub).
|
|
256
|
+
* `writeMemoryFrontmatter` invalidates caches and syncs the fact-hash index
|
|
257
|
+
* (§25/§31), so a stamped memory is immediately discoverable.
|
|
258
|
+
*/
|
|
259
|
+
export interface SubjectBackfillStorage {
|
|
260
|
+
readAllMemories(): Promise<MemoryFile[]>;
|
|
261
|
+
writeMemoryFrontmatter(memory: MemoryFile, patch: Partial<MemoryFile["frontmatter"]>): Promise<boolean>;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
export interface SubjectBackfillReport {
|
|
265
|
+
mode: "shadow" | "apply";
|
|
266
|
+
scanned: number;
|
|
267
|
+
stamped: number;
|
|
268
|
+
alreadyStamped: number;
|
|
269
|
+
stamps: Array<{
|
|
270
|
+
id: string;
|
|
271
|
+
category: MemoryCategory;
|
|
272
|
+
subject: MemorySubject;
|
|
273
|
+
path: string;
|
|
274
|
+
}>;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Stamp `subject` on memories that have none, using ONLY the deterministic
|
|
279
|
+
* category defaults (never an LLM, never reclassifying an existing subject —
|
|
280
|
+
* issue #2372 §1.3). `shadow` reports the intended stamps without writing;
|
|
281
|
+
* `apply` writes through `writeMemoryFrontmatter`, which invalidates the
|
|
282
|
+
* memory caches and re-syncs the fact-hash index.
|
|
283
|
+
*/
|
|
284
|
+
export async function backfillMemorySubjects(options: {
|
|
285
|
+
storage: SubjectBackfillStorage;
|
|
286
|
+
mode: "shadow" | "apply";
|
|
287
|
+
}): Promise<SubjectBackfillReport> {
|
|
288
|
+
const memories = await options.storage.readAllMemories();
|
|
289
|
+
const report: SubjectBackfillReport = {
|
|
290
|
+
mode: options.mode,
|
|
291
|
+
scanned: memories.length,
|
|
292
|
+
stamped: 0,
|
|
293
|
+
alreadyStamped: 0,
|
|
294
|
+
stamps: [],
|
|
295
|
+
};
|
|
296
|
+
for (const memory of memories) {
|
|
297
|
+
if (memory.frontmatter.subject !== undefined) {
|
|
298
|
+
report.alreadyStamped++;
|
|
299
|
+
continue;
|
|
300
|
+
}
|
|
301
|
+
const subject = subjectDefaultForCategory(memory.frontmatter.category);
|
|
302
|
+
report.stamps.push({
|
|
303
|
+
id: memory.frontmatter.id,
|
|
304
|
+
category: memory.frontmatter.category,
|
|
305
|
+
subject,
|
|
306
|
+
path: memory.path,
|
|
307
|
+
});
|
|
308
|
+
if (options.mode === "apply") {
|
|
309
|
+
await options.storage.writeMemoryFrontmatter(memory, { subject });
|
|
310
|
+
}
|
|
311
|
+
report.stamped++;
|
|
312
|
+
}
|
|
313
|
+
return report;
|
|
314
|
+
}
|
|
@@ -306,11 +306,15 @@ test("concurrent outcomes for the same memory do NOT lose updates", async () =>
|
|
|
306
306
|
}
|
|
307
307
|
});
|
|
308
308
|
|
|
309
|
-
test("eligible-category set is exactly {fact}", () => {
|
|
309
|
+
test("eligible-category set is exactly {fact, procedure}", () => {
|
|
310
310
|
// Pinning this keeps PR 3 in lockstep with the PR 1 doctor allowlist in
|
|
311
311
|
// operator-toolkit.ts (MEMORY_WORTH_ELIGIBLE_CATEGORIES). If either side
|
|
312
312
|
// expands, this test and the doctor test must both be updated.
|
|
313
|
+
// `procedure` joined in issue #2370: the procedure library-health loop
|
|
314
|
+
// retires on failure-dominant mw_* counters, so injected procedures must
|
|
315
|
+
// accrue outcomes.
|
|
313
316
|
const eligible = memoryWorthOutcomeEligibleCategories();
|
|
314
|
-
assert.equal(eligible.size,
|
|
317
|
+
assert.equal(eligible.size, 2);
|
|
315
318
|
assert.ok(eligible.has("fact"));
|
|
319
|
+
assert.ok(eligible.has("procedure"));
|
|
316
320
|
});
|
|
@@ -20,8 +20,9 @@
|
|
|
20
20
|
* preserved. The PR 1 serializer rejects negative / non-integer counters,
|
|
21
21
|
* so we rely on that for defensive validation rather than duplicating it.
|
|
22
22
|
* - Only instruments categories in `MEMORY_WORTH_OUTCOME_ELIGIBLE_CATEGORIES`
|
|
23
|
-
* (currently `fact
|
|
24
|
-
* operator-toolkit.ts for
|
|
23
|
+
* (currently `fact` and `procedure` — procedures joined in issue #2370 —
|
|
24
|
+
* matching `MEMORY_WORTH_ELIGIBLE_CATEGORIES` in operator-toolkit.ts for
|
|
25
|
+
* the doctor audit). Non-eligible memories return
|
|
25
26
|
* `{ ok: false, reason: "ineligible_category" }` rather than throwing so
|
|
26
27
|
* the caller — typically a ledger consumer draining heterogeneous events
|
|
27
28
|
* — doesn't need to pre-filter by category.
|
|
@@ -94,14 +95,17 @@ function runSerialized<T>(key: string, task: () => Promise<T>): Promise<T> {
|
|
|
94
95
|
}
|
|
95
96
|
|
|
96
97
|
/**
|
|
97
|
-
* Categories currently instrumented for Memory Worth counters.
|
|
98
|
-
* in
|
|
99
|
-
*
|
|
100
|
-
*
|
|
98
|
+
* Categories currently instrumented for Memory Worth counters. `procedure`
|
|
99
|
+
* joined in issue #2370 — the procedure library-health maintenance loop
|
|
100
|
+
* retires on failure-dominant `mw_*` counters, so injected procedures must
|
|
101
|
+
* be able to accrue outcomes. Must be kept in sync with
|
|
102
|
+
* `MEMORY_WORTH_ELIGIBLE_CATEGORIES` in `operator-toolkit.ts`. Declared
|
|
103
|
+
* here (not imported) to avoid a circular dep with operator-toolkit, which
|
|
104
|
+
* imports from this file's peers. The two constants are validated by a
|
|
101
105
|
* test to stay in lockstep.
|
|
102
106
|
*/
|
|
103
107
|
const MEMORY_WORTH_OUTCOME_ELIGIBLE_CATEGORIES: ReadonlySet<MemoryFrontmatter["category"]> =
|
|
104
|
-
new Set(["fact"]);
|
|
108
|
+
new Set(["fact", "procedure"]);
|
|
105
109
|
|
|
106
110
|
/**
|
|
107
111
|
* Exported so downstream tests / operators can query the allowlist without
|
package/src/operator-toolkit.ts
CHANGED
|
@@ -1580,7 +1580,7 @@ export async function runOperatorDoctor(options: OperatorDoctorOptions): Promise
|
|
|
1580
1580
|
* alongside the scoring/increment logic so the doctor audit stays in sync.
|
|
1581
1581
|
*/
|
|
1582
1582
|
const MEMORY_WORTH_ELIGIBLE_CATEGORIES: ReadonlySet<MemoryFile["frontmatter"]["category"]> =
|
|
1583
|
-
new Set(["fact"]);
|
|
1583
|
+
new Set(["fact", "procedure"]);
|
|
1584
1584
|
|
|
1585
1585
|
/**
|
|
1586
1586
|
* Count memories that pre-date the Memory Worth counters introduced in issue
|
|
@@ -74,6 +74,7 @@ import {
|
|
|
74
74
|
} from "../behavior-signals.js";
|
|
75
75
|
import { buildProcedurePersistBody } from "../procedural/procedure-types.js";
|
|
76
76
|
import { stripAttributesSuffix } from "../structured-attributes.js";
|
|
77
|
+
import { evaluateSubjectGuard, isSharedPromotionTarget, resolveWriteSubject } from "../memory-subject.js";
|
|
77
78
|
import { LocalLlmClient } from "../local-llm.js";
|
|
78
79
|
import type { ExtractionEngine } from "../extraction.js";
|
|
79
80
|
import {
|
|
@@ -94,6 +95,7 @@ import type {
|
|
|
94
95
|
MemoryFile,
|
|
95
96
|
MemoryFrontmatter,
|
|
96
97
|
MemoryLink,
|
|
98
|
+
MemorySubject,
|
|
97
99
|
PluginConfig,
|
|
98
100
|
ProvenanceSource,
|
|
99
101
|
MemoryCategory,
|
|
@@ -338,6 +340,19 @@ export class ExtractionPersistCoordinator {
|
|
|
338
340
|
// introduced (ratchet scatteredConfigFlagReads; see #1523).
|
|
339
341
|
const namespacesEnabled = resolveNamespaceCapabilities(this.deps.config).namespaces;
|
|
340
342
|
const sourceConnector = sourceContext?.sourceConnector; const origin = classifyExtractionOrigin(sourceContext);
|
|
343
|
+
// Subject guard (issue #2372): the ONE gate shared by every extraction-side
|
|
344
|
+
// promotion path so behavior matches the spaces surface (§27).
|
|
345
|
+
const subjectGuardAllows = (subject: MemorySubject | undefined, target: string, label: string): boolean => {
|
|
346
|
+
const decision = evaluateSubjectGuard({
|
|
347
|
+
subject,
|
|
348
|
+
sharedTarget: isSharedPromotionTarget(target),
|
|
349
|
+
mode: this.deps.config.subjectGuard,
|
|
350
|
+
});
|
|
351
|
+
if (decision.action !== "allow") {
|
|
352
|
+
log.warn(`subject-guard(${decision.action}) ${label}: ${decision.reason}`);
|
|
353
|
+
}
|
|
354
|
+
return decision.action !== "reject";
|
|
355
|
+
};
|
|
341
356
|
const promoteMemoryToProfileTargets = async (options: {
|
|
342
357
|
sourceStorage: StorageManager;
|
|
343
358
|
category: string;
|
|
@@ -353,8 +368,7 @@ export class ExtractionPersistCoordinator {
|
|
|
353
368
|
intentEntityTypes?: string[];
|
|
354
369
|
memoryKind?: MemoryFrontmatter["memoryKind"];
|
|
355
370
|
validAt?: string;
|
|
356
|
-
// #1578 — bi-temporal bounds +
|
|
357
|
-
// target copies (same defect class as shared promotion; cursor bugbot).
|
|
371
|
+
// #1578 — bi-temporal bounds + provenance forwarded to profile-target copies.
|
|
358
372
|
invalidAt?: string;
|
|
359
373
|
observedAt?: string;
|
|
360
374
|
eventTimeSource?: "extracted" | "assumed";
|
|
@@ -362,6 +376,7 @@ export class ExtractionPersistCoordinator {
|
|
|
362
376
|
sources?: ProvenanceSource[];
|
|
363
377
|
provenance?: "verified" | "unverified" | "none";
|
|
364
378
|
toolScoped?: true;
|
|
379
|
+
subject?: MemorySubject;
|
|
365
380
|
harmonicFact?: Omit<
|
|
366
381
|
HarmonicConstructionInput["persistedFacts"][number],
|
|
367
382
|
"memoryId"
|
|
@@ -392,6 +407,7 @@ export class ExtractionPersistCoordinator {
|
|
|
392
407
|
try {
|
|
393
408
|
const targetStorage = await this.deps.getStorageRouter().storageFor(target.namespace);
|
|
394
409
|
if (targetStorage.dir === options.sourceStorage.dir) continue;
|
|
410
|
+
if (!subjectGuardAllows(options.subject, target.target, `profile promotion to ${target.target}`)) continue;
|
|
395
411
|
// Compose BEFORE the dedup gate (#2014 round 2): salvage mode may
|
|
396
412
|
// drop or clamp attributes, and the dedup hash, contentHashSource,
|
|
397
413
|
// and supersession keys below must all describe the SURVIVING
|
|
@@ -406,6 +422,7 @@ export class ExtractionPersistCoordinator {
|
|
|
406
422
|
structuredAttributes: options.structuredAttributes,
|
|
407
423
|
validAt: options.validAt,
|
|
408
424
|
...(sourceContext?.sourceConnector ? { sourceConnector: sourceContext.sourceConnector } : {}),
|
|
425
|
+
...(options.subject !== undefined ? { subject: options.subject } : {}),
|
|
409
426
|
},
|
|
410
427
|
{ source: `${options.source}-${target.target}-promotion` },
|
|
411
428
|
);
|
|
@@ -557,8 +574,7 @@ export class ExtractionPersistCoordinator {
|
|
|
557
574
|
memoryKind?: MemoryFrontmatter["memoryKind"];
|
|
558
575
|
validAt?: string;
|
|
559
576
|
// #1578 — bi-temporal bounds + ingestion provenance forwarded to the
|
|
560
|
-
// shared-namespace copy
|
|
561
|
-
// window as the source fact (cursor bugbot).
|
|
577
|
+
// shared-namespace copy (cursor bugbot).
|
|
562
578
|
invalidAt?: string;
|
|
563
579
|
observedAt?: string;
|
|
564
580
|
eventTimeSource?: "extracted" | "assumed";
|
|
@@ -568,6 +584,7 @@ export class ExtractionPersistCoordinator {
|
|
|
568
584
|
/** Claim-level provenance spans (issue #1575 PR 2). */
|
|
569
585
|
sources?: ProvenanceSource[];
|
|
570
586
|
provenance?: "verified" | "unverified" | "none";
|
|
587
|
+
subject?: MemorySubject;
|
|
571
588
|
harmonicFact?: Omit<
|
|
572
589
|
HarmonicConstructionInput["persistedFacts"][number],
|
|
573
590
|
"memoryId"
|
|
@@ -591,43 +608,19 @@ export class ExtractionPersistCoordinator {
|
|
|
591
608
|
)
|
|
592
609
|
)
|
|
593
610
|
return;
|
|
611
|
+
if (!subjectGuardAllows(options.subject, "serverShared", "shared promotion")) return;
|
|
594
612
|
try {
|
|
595
613
|
const sharedStorage = await this.deps.getStorageRouter().storageFor(
|
|
596
614
|
this.deps.config.sharedNamespace,
|
|
597
615
|
);
|
|
598
|
-
// Dedup gate: canonicalize content before hashing.
|
|
599
|
-
//
|
|
600
|
-
//
|
|
601
|
-
//
|
|
602
|
-
//
|
|
603
|
-
//
|
|
604
|
-
//
|
|
605
|
-
//
|
|
606
|
-
// relayed or reprocessed fact). Strip any pre-existing citation so the
|
|
607
|
-
// dedup key matches the hash stored from the original un-cited write.
|
|
608
|
-
// PR #402 round-6 (Fix #2 / chatgpt-codex P1 PRRT_kwDORJXyws56U74n):
|
|
609
|
-
// Compute the enriched content before the hash-dedup check so the
|
|
610
|
-
// lookup uses the same content that writeMemory will actually store.
|
|
611
|
-
// When structuredAttributes are present, writeMemory appends an
|
|
612
|
-
// "[Attributes: ...]" suffix before hashing; hasFactContentHash must
|
|
613
|
-
// receive the same enriched body or the check is against a different
|
|
614
|
-
// hash and dedup fails to fire (letting duplicates through) or fires
|
|
615
|
-
// when it shouldn't (collapsing memories with different enrichments).
|
|
616
|
-
// Fix #1 (P2 PRRT_kwDORJXyws56VHZc): use normalizeAttributePairs so
|
|
617
|
-
// key order and casing are canonical — identical to the enrichment
|
|
618
|
-
// applied by storage.writeMemory — preventing spurious hash misses
|
|
619
|
-
// when attribute maps arrive with different insertion orders or casing.
|
|
620
|
-
// Fix #4 (Low PRRT_kwDORJXyws56VHth): sanitize the base content before
|
|
621
|
-
// building dedupContent. writeMemory runs sanitizeMemoryContent on the
|
|
622
|
-
// enriched body before hashing; if sanitization redacts the content to
|
|
623
|
-
// REDACTED_PLACEHOLDER the stored hash is for the redacted form, not
|
|
624
|
-
// the raw form. Computing dedupContent from sanitized.text here ensures
|
|
625
|
-
// the hash lookup and the normalizedIncoming comparison both use the
|
|
626
|
-
// same content that writeMemory will actually store.
|
|
627
|
-
// Combined fix: strip any pre-existing citation FIRST to obtain
|
|
628
|
-
// rawContent (the canonical body), then sanitize rawContent (not
|
|
629
|
-
// options.content) when building dedupContent, so that citation
|
|
630
|
-
// stripping and sanitization are applied in a consistent order.
|
|
616
|
+
// Dedup gate: canonicalize content before hashing. Strip any
|
|
617
|
+
// pre-existing citation FIRST (applyInlineCitation appends a
|
|
618
|
+
// timestamped marker, so hashing cited content defeats dedup and
|
|
619
|
+
// call sites may pass already-cited content), then sanitize the base
|
|
620
|
+
// and build the attribute-enriched body with normalizeAttributePairs
|
|
621
|
+
// — the same canonicalization writeMemory applies — so the hash
|
|
622
|
+
// lookup uses the exact body writeMemory stores (#369/#401, #402
|
|
623
|
+
// round-6 fixes; PRRT_kwDORJXyws56VHZc / VHth).
|
|
631
624
|
const rawContent =
|
|
632
625
|
citationEnabled &&
|
|
633
626
|
hasCitationForTemplate(options.content, citationTemplate)
|
|
@@ -649,6 +642,7 @@ export class ExtractionPersistCoordinator {
|
|
|
649
642
|
structuredAttributes: options.structuredAttributes,
|
|
650
643
|
validAt: options.validAt,
|
|
651
644
|
...(sourceContext?.sourceConnector ? { sourceConnector: sourceContext.sourceConnector } : {}),
|
|
645
|
+
...(options.subject !== undefined ? { subject: options.subject } : {}),
|
|
652
646
|
},
|
|
653
647
|
{ source: `${options.source}-shared-promotion` },
|
|
654
648
|
);
|
|
@@ -1330,7 +1324,8 @@ export class ExtractionPersistCoordinator {
|
|
|
1330
1324
|
profileAllowsSharedWrites &&
|
|
1331
1325
|
this.deps.storageDirNamespace(storage.dir) !== this.deps.config.sharedNamespace &&
|
|
1332
1326
|
shouldPromoteGlobalFactToShared({ scope: f.scope, content: f.content,
|
|
1333
|
-
sourceConnector, procedureSteps: f.procedureSteps })
|
|
1327
|
+
sourceConnector, procedureSteps: f.procedureSteps }) &&
|
|
1328
|
+
subjectGuardAllows(f.subject, "serverShared", "pre-judge shared routing")
|
|
1334
1329
|
) {
|
|
1335
1330
|
factNs = this.deps.config.sharedNamespace;
|
|
1336
1331
|
}
|
|
@@ -1577,10 +1572,13 @@ export class ExtractionPersistCoordinator {
|
|
|
1577
1572
|
);
|
|
1578
1573
|
}
|
|
1579
1574
|
}
|
|
1580
|
-
|
|
1581
|
-
//
|
|
1582
|
-
|
|
1583
|
-
|
|
1575
|
+
// Write-time subject stamp (issue #2372): extractor token over the
|
|
1576
|
+
// category default; absent when classification is disabled (byte-identical).
|
|
1577
|
+
const factSubject = this.deps.config.subjectClassification?.enabled === true
|
|
1578
|
+
? resolveWriteSubject(writeCategory, fact.subject)
|
|
1579
|
+
: undefined;
|
|
1580
|
+
// Scope-based namespace routing: a `global` fact (no explicit routing
|
|
1581
|
+
// rule) promotes to the shared namespace unless a guard withholds it.
|
|
1584
1582
|
if (
|
|
1585
1583
|
lifecycleCaps.extractionScopeClassification &&
|
|
1586
1584
|
namespacesEnabled &&
|
|
@@ -1590,7 +1588,7 @@ export class ExtractionPersistCoordinator {
|
|
|
1590
1588
|
const currentNs = this.deps.storageDirNamespace(targetStorage.dir);
|
|
1591
1589
|
if (currentNs !== this.deps.config.sharedNamespace && profileAllowsSharedWrites) {
|
|
1592
1590
|
if (shouldPromoteGlobalFactToShared({ scope: fact.scope, content: fact.content,
|
|
1593
|
-
sourceConnector, procedureSteps: fact.procedureSteps })) {
|
|
1591
|
+
sourceConnector, procedureSteps: fact.procedureSteps }) && subjectGuardAllows(fact.subject, "serverShared", "scope-routing")) {
|
|
1594
1592
|
try {
|
|
1595
1593
|
targetStorage = await this.deps.getStorageRouter().storageFor(
|
|
1596
1594
|
this.deps.config.sharedNamespace,
|
|
@@ -2383,6 +2381,7 @@ export class ExtractionPersistCoordinator {
|
|
|
2383
2381
|
sourceStorage: targetStorage,
|
|
2384
2382
|
category: writeCategory,
|
|
2385
2383
|
content: fact.content,
|
|
2384
|
+
subject: factSubject,
|
|
2386
2385
|
confidence: fact.confidence,
|
|
2387
2386
|
tags: fact.tags,
|
|
2388
2387
|
entityRef: fact.entityRef,
|
|
@@ -2579,6 +2578,7 @@ export class ExtractionPersistCoordinator {
|
|
|
2579
2578
|
structuredAttributes: fact.structuredAttributes,
|
|
2580
2579
|
validAt: biTemporal ? biTemporal.validFrom : sourceContext?.validAt,
|
|
2581
2580
|
...(extractionSourceConnector ? { sourceConnector: extractionSourceConnector } : {}),
|
|
2581
|
+
...(factSubject !== undefined ? { subject: factSubject } : {}),
|
|
2582
2582
|
},
|
|
2583
2583
|
{ source: extractionWriteSource },
|
|
2584
2584
|
);
|
|
@@ -2697,6 +2697,7 @@ export class ExtractionPersistCoordinator {
|
|
|
2697
2697
|
category: writeCategory,
|
|
2698
2698
|
content: fact.content,
|
|
2699
2699
|
confidence: fact.confidence,
|
|
2700
|
+
subject: factSubject,
|
|
2700
2701
|
tags: fact.tags,
|
|
2701
2702
|
entityRef:
|
|
2702
2703
|
typeof (fact as any).entityRef === "string"
|
|
@@ -2822,11 +2823,10 @@ export class ExtractionPersistCoordinator {
|
|
|
2822
2823
|
}
|
|
2823
2824
|
}
|
|
2824
2825
|
|
|
2825
|
-
// Tracks whether THIS extraction persisted any durable, non-fact output
|
|
2826
|
-
//
|
|
2827
|
-
//
|
|
2828
|
-
//
|
|
2829
|
-
// base-namespace catalog touch after all writes complete (NHZEZ, codex P2).
|
|
2826
|
+
// Tracks whether THIS extraction persisted any durable, non-fact output
|
|
2827
|
+
// (entity / relationship / profile / question) to the BASE namespace.
|
|
2828
|
+
// A fact-less extraction still records exactly one base-namespace catalog
|
|
2829
|
+
// touch after all writes complete (NHZEZ, codex P2).
|
|
2830
2830
|
let durableNonFactWritten = false;
|
|
2831
2831
|
let durableNonFactTouchRecorded = false;
|
|
2832
2832
|
const touchBaseNonFactNamespace = () => {
|
|
@@ -39,7 +39,7 @@ import { canReadNamespace, resolvePrincipal } from "../namespaces/principal.js";
|
|
|
39
39
|
import { collectNativeKnowledgeChunks, formatNativeKnowledgeSection, searchNativeKnowledge } from "../native-knowledge.js";
|
|
40
40
|
import { objectiveStateStoreOverrideForNamespace, searchObjectiveStateSnapshots } from "../objective-state.js";
|
|
41
41
|
import { type GraphRecallRankedResult, type GraphRecallShadowComparison, mergeGraphExpandedResults } from "./graph-recall-coordinator.js";
|
|
42
|
-
import { buildProcedureRecallSection } from "../procedural/procedure-recall.js";
|
|
42
|
+
import { buildProcedureRecallSection, mergeProcedureInjections } from "../procedural/procedure-recall.js";
|
|
43
43
|
import { canRecallToolScopedMemory } from "../tool-scoped-memory.js";
|
|
44
44
|
import { buildQmdRecallCacheKey, getCachedQmdRecall, setCachedQmdRecall } from "../qmd-recall-cache.js";
|
|
45
45
|
import { MEMORY_ID_PATTERN } from "../recall-handles.js";
|
|
@@ -2671,6 +2671,7 @@ export class RecallInternalCoordinator {
|
|
|
2671
2671
|
return section;
|
|
2672
2672
|
})();
|
|
2673
2673
|
|
|
2674
|
+
const procedureInjectedMemories: Array<{ id: string; path: string; namespace?: string }> = [];
|
|
2674
2675
|
const procedureRecallPromise = (async (): Promise<string | null> => {
|
|
2675
2676
|
if (this.deps.config.procedural?.enabled !== true) return null;
|
|
2676
2677
|
if (!this.deps.isRecallSectionEnabled("procedure-recall", true)) return null;
|
|
@@ -2679,10 +2680,7 @@ export class RecallInternalCoordinator {
|
|
|
2679
2680
|
profileStorage,
|
|
2680
2681
|
retrievalQuery,
|
|
2681
2682
|
this.deps.config,
|
|
2682
|
-
{
|
|
2683
|
-
partitionToolScoped: lifecycleCaps.extractionScopeClassification,
|
|
2684
|
-
requestingConnector: options.sourceConnector,
|
|
2685
|
-
},
|
|
2683
|
+
{ partitionToolScoped: lifecycleCaps.extractionScopeClassification, requestingConnector: options.sourceConnector, injectedMemories: procedureInjectedMemories },
|
|
2686
2684
|
);
|
|
2687
2685
|
} catch (err) {
|
|
2688
2686
|
log.debug(
|
|
@@ -4946,6 +4944,9 @@ export class RecallInternalCoordinator {
|
|
|
4946
4944
|
const assembledRecall = this.deps.assembleRecallSections(
|
|
4947
4945
|
sectionBuckets, contextBudgetForFooter(recallBudgetChars, curiosityFooter),
|
|
4948
4946
|
);
|
|
4947
|
+
if (procedureRecallSection !== null && assembledRecall.includedIds.includes("procedure-recall")) {
|
|
4948
|
+
assembledRecall.includedMemories = mergeProcedureInjections(assembledRecall.includedMemories, procedureInjectedMemories);
|
|
4949
|
+
}
|
|
4949
4950
|
recalledMemoryIds = assembledRecall.includedMemories.map((memory) => memory.id);
|
|
4950
4951
|
recalledMemoryPaths = assembledRecall.includedMemories.map((memory) => memory.path);
|
|
4951
4952
|
recalledMemoryNamespaces = assembledRecall.includedMemories.map((memory) => memory.namespace);
|