@remnic/core 9.65.1 → 9.65.2
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 +35 -34
- package/dist/access-authorization-probe.d.ts +12 -13
- package/dist/access-authorization-probe.js +36 -35
- package/dist/access-boundary.d.ts +12 -156
- package/dist/access-boundary.js +35 -34
- package/dist/access-cli.js +107 -104
- package/dist/access-cli.js.map +1 -1
- package/dist/access-coding-context-resolution.d.ts +1 -1
- package/dist/access-extraction-force-flush.d.ts +11 -11
- package/dist/access-extraction-force-flush.js +35 -34
- package/dist/access-health-types.d.ts +1 -1
- package/dist/access-http-lcm-compaction.d.ts +11 -11
- package/dist/access-http-lifecycle-flush.d.ts +12 -13
- package/dist/access-http-offline-stream.d.ts +11 -11
- package/dist/access-http-query.d.ts +2 -2
- package/dist/access-http-query.js +37 -36
- package/dist/access-http.d.ts +12 -12
- package/dist/access-http.js +54 -53
- package/dist/access-identity-continuity-surface.d.ts +9 -9
- package/dist/access-identity-continuity-surface.js +35 -34
- package/dist/access-lcm-surface.d.ts +11 -11
- package/dist/access-lcm-surface.js +35 -34
- package/dist/access-mcp-admin-tools.js +1 -1
- package/dist/access-mcp-output-schemas.js +1 -1
- package/dist/access-mcp.d.ts +11 -11
- package/dist/access-mcp.js +47 -44
- package/dist/access-memory-search-fanout.d.ts +2 -2
- package/dist/{access-namespace-preflight-BKUnKsBv.d.ts → access-namespace-preflight-Dhvcl-T0.d.ts} +1 -1
- package/dist/access-namespace-preflight.d.ts +3 -3
- package/dist/access-namespace-preflight.js +35 -34
- package/dist/access-observe-write-surface.d.ts +11 -11
- package/dist/access-observe-write-surface.js +35 -34
- package/dist/access-offline-manifest.d.ts +9 -9
- package/dist/access-offline-manifest.js +5 -5
- package/dist/access-operations-batch.js +38 -37
- package/dist/access-operations.d.ts +18 -19
- package/dist/access-operations.js +41 -40
- package/dist/access-recall-concurrency.d.ts +11 -11
- package/dist/access-recall-concurrency.js +35 -34
- package/dist/access-recall-response.d.ts +11 -11
- package/dist/access-recall-response.js +35 -34
- package/dist/access-recall-surface.d.ts +11 -11
- package/dist/access-recall-surface.js +35 -34
- package/dist/access-schema.d.ts +118 -118
- package/dist/access-schema.js +3 -3
- package/dist/{access-service-B1Lbb-nQ.d.ts → access-service-Bke1alZO.d.ts} +478 -74
- package/dist/access-service-helpers.d.ts +11 -11
- package/dist/access-service.d.ts +11 -11
- package/dist/access-service.js +35 -34
- package/dist/access-surface-catalog.d.ts +12 -13
- package/dist/access-surface-catalog.js +39 -36
- package/dist/access-surface-catalog.js.map +1 -1
- package/dist/access-wearables-meetings-surface.d.ts +3 -3
- package/dist/action-confidence.d.ts +1 -1
- package/dist/active-memory-bridge.d.ts +1 -1
- package/dist/active-recall.d.ts +1 -1
- package/dist/active-recall.js +6 -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 +1 -1
- package/dist/artifact-search.d.ts +1 -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 +1 -1
- package/dist/behavior-signals.d.ts +1 -1
- package/dist/bootstrap.d.ts +9 -9
- package/dist/briefing-window.d.ts +2 -2
- package/dist/briefing.d.ts +2 -2
- package/dist/briefing.js +16 -15
- package/dist/buffer-surprise-report.d.ts +1 -1
- package/dist/buffer-turn-helpers.d.ts +1 -1
- package/dist/buffer.d.ts +2 -2
- package/dist/buffer.js +4 -4
- package/dist/bulk-import/index.d.ts +3 -3
- package/dist/calibration.d.ts +1 -1
- package/dist/calibration.js +1 -1
- package/dist/capabilities.d.ts +1 -1
- package/dist/{capsule-crypto-7FJQINUR.js → capsule-crypto-YO5QJ6L3.js} +2 -2
- package/dist/{catalog-DjVhJoRM.d.ts → catalog-DV6qnbr7.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 +17 -16
- package/dist/causal-consolidation.js.map +1 -1
- package/dist/causal-trajectory-graph.d.ts +1 -1
- package/dist/{chunk-LYIZXQYY.js → chunk-2E36UXVW.js} +2 -2
- package/dist/{chunk-7QFBLYFP.js → chunk-2XDWWPTN.js} +3 -3
- package/dist/{chunk-CFRBTATE.js → chunk-2YI72KM3.js} +3 -3
- package/dist/{chunk-3YTTAGPB.js → chunk-3DVBKTSO.js} +2 -2
- package/dist/{chunk-VPGRXEAB.js → chunk-3I7ASZN3.js} +2 -2
- package/dist/{chunk-EIR5VLIH.js → chunk-4K7IW3F7.js} +2 -2
- package/dist/chunk-4K7IW3F7.js.map +1 -0
- package/dist/{chunk-WTOE7CW4.js → chunk-4KYOLI6M.js} +13 -13
- package/dist/chunk-573TEZCD.js +88 -0
- package/dist/chunk-573TEZCD.js.map +1 -0
- package/dist/{chunk-ESCQ6LY7.js → chunk-5NM4OH4P.js} +3 -3
- package/dist/{chunk-Y23B2QXP.js → chunk-5YQ63T4B.js} +2 -2
- package/dist/{chunk-PMVPCZJZ.js → chunk-6433HV72.js} +2 -2
- 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-W6TSGWYS.js → chunk-7YQ4IYS2.js} +2 -2
- package/dist/chunk-AAXJNINV.js +55 -0
- package/dist/chunk-AAXJNINV.js.map +1 -0
- package/dist/{chunk-YQ3CBLL4.js → chunk-BWLRUMOG.js} +78 -8
- package/dist/chunk-BWLRUMOG.js.map +1 -0
- 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-5UYSCYR7.js → chunk-CT56C22C.js} +4 -4
- package/dist/{chunk-HJQZQUPC.js → chunk-DJZWNKFO.js} +5 -5
- package/dist/{chunk-X7Y7WX73.js → chunk-DQEMWVMT.js} +1 -1
- package/dist/{chunk-CCTVAVTT.js → chunk-DZUJ46DO.js} +2 -2
- package/dist/{chunk-N6TRHP72.js → chunk-EILZG5VC.js} +2 -2
- package/dist/{chunk-GXWDWOWP.js → chunk-GDFVPUJ5.js} +2 -2
- package/dist/{chunk-7PWWGYGO.js → chunk-GNCCUR6K.js} +2 -2
- package/dist/{chunk-KPBLJCCV.js → chunk-IID2CMUU.js} +2 -2
- package/dist/{chunk-DEFI2QBT.js → chunk-J275IYMG.js} +25 -22
- package/dist/chunk-J275IYMG.js.map +1 -0
- package/dist/{chunk-UYCIS6V5.js → chunk-JCWY73FK.js} +2 -2
- package/dist/{chunk-SYJ6EKKE.js → chunk-JYYBA7TF.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-LWVO2QZV.js → chunk-LGO6A7GJ.js} +50 -50
- package/dist/{chunk-CEQF6L5K.js → chunk-LUNJ3WFO.js} +9 -7
- package/dist/chunk-LUNJ3WFO.js.map +1 -0
- package/dist/{chunk-2572MRP2.js → chunk-LZH5FR2W.js} +2 -2
- package/dist/{chunk-256FBCVX.js → chunk-M4AHBM72.js} +7 -7
- package/dist/{chunk-YEQEGSJA.js → chunk-MN4KB2A4.js} +3 -3
- package/dist/{chunk-AGKIG3YA.js → chunk-NKKD4ZAU.js} +2 -2
- package/dist/{chunk-3TMYV3LP.js → chunk-NTWN6HB2.js} +5 -5
- package/dist/{chunk-63FHSH7E.js → chunk-OCZIYAE5.js} +4 -4
- package/dist/{chunk-I2HTKOOP.js → chunk-ODZG724P.js} +2 -2
- package/dist/{chunk-HQSBYI5X.js → chunk-OTHZWLUD.js} +2 -2
- package/dist/{chunk-4W6INNXO.js → chunk-PE255F4T.js} +2 -2
- package/dist/{chunk-6L27N6YI.js → chunk-QOS5LBZN.js} +2 -2
- package/dist/{chunk-G72IPMR7.js → chunk-R4OCGPSH.js} +2 -2
- package/dist/{chunk-MIBKEW7A.js → chunk-R7JAM2XF.js} +3 -3
- 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-JBPKEARU.js → chunk-RKNJBZ55.js} +4 -4
- package/dist/{chunk-HUNSEO5U.js → chunk-S2DPMJXH.js} +2 -2
- package/dist/{chunk-3PXVYJMC.js → chunk-SB7D4BT7.js} +536 -114
- package/dist/chunk-SB7D4BT7.js.map +1 -0
- package/dist/{chunk-JFJ3MHGV.js → chunk-SBDCZ2AX.js} +1 -1
- package/dist/chunk-SBDCZ2AX.js.map +1 -0
- package/dist/{chunk-HQSPXTQO.js → chunk-SIHSCCUQ.js} +1 -1
- package/dist/{chunk-R3AAOKR2.js → chunk-SPUJNJJC.js} +2 -2
- package/dist/{chunk-IAY7YBXS.js → chunk-SQI57UCJ.js} +2 -2
- package/dist/{chunk-CTQRPANJ.js → chunk-SVSRPG6M.js} +2 -2
- package/dist/{chunk-56BSXSHC.js → chunk-TBOJ76ER.js} +14 -1
- package/dist/{chunk-56BSXSHC.js.map → chunk-TBOJ76ER.js.map} +1 -1
- package/dist/{chunk-Z54TXZ2F.js → chunk-TF77C7SV.js} +14 -7
- package/dist/chunk-TF77C7SV.js.map +1 -0
- package/dist/{chunk-S2VBSTTA.js → chunk-THG4GYIE.js} +2 -2
- package/dist/{chunk-IXRC7EQG.js → chunk-TR7DGXGI.js} +2 -2
- package/dist/{chunk-GEULB2VI.js → chunk-TZNQUNKL.js} +7 -1
- package/dist/chunk-TZNQUNKL.js.map +1 -0
- package/dist/{chunk-BC4QD3FM.js → chunk-UIN2BWDD.js} +2 -2
- package/dist/{chunk-JTSVMJHV.js → chunk-UXO5IMBK.js} +3 -3
- package/dist/{chunk-DBXZZIDU.js → chunk-V3MXUL3D.js} +138 -73
- package/dist/chunk-V3MXUL3D.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-MDVBCPOS.js → chunk-XCTXS7VY.js} +2 -2
- package/dist/{chunk-53ENM6F6.js → chunk-XRYZRW54.js} +2 -2
- package/dist/{chunk-VJ6ECBIP.js → chunk-Y7DK7HHJ.js} +2 -2
- package/dist/{chunk-3MADV4YC.js → chunk-YB42WZCY.js} +2 -2
- package/dist/{chunk-X5SDZMO7.js → chunk-YHCBJULX.js} +2 -2
- package/dist/{chunk-3RHFGGI5.js → chunk-YLDXWCZP.js} +20 -5
- package/dist/chunk-YLDXWCZP.js.map +1 -0
- package/dist/{chunk-6JJT5AKI.js → chunk-Z7PBQPJ4.js} +2 -2
- package/dist/{chunk-ALCJRQ72.js → chunk-ZO6AXLEH.js} +2 -2
- package/dist/{chunk-VZVP2W4O.js → chunk-ZQHI2BZB.js} +2 -2
- package/dist/{chunk-CUS6S7PN.js → chunk-ZWXJBFZU.js} +9 -9
- package/dist/chunk-ZWXJBFZU.js.map +1 -0
- package/dist/{cli-Pulnz-qm.d.ts → cli-cShQ13XG.d.ts} +5 -5
- package/dist/cli.d.ts +13 -13
- package/dist/cli.js +77 -75
- package/dist/coding/pre-action-gate.d.ts +1 -1
- package/dist/compounding/engine.d.ts +2 -2
- package/dist/compounding/engine.js +17 -16
- 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 +6 -1
- package/dist/connectors/codex-materialize-runner.d.ts +1 -1
- package/dist/connectors/codex-materialize-runner.js +16 -15
- package/dist/connectors/codex-materialize.d.ts +1 -1
- package/dist/connectors/index.d.ts +1 -1
- package/dist/connectors/index.js +16 -15
- package/dist/consolidation-provenance-check.d.ts +2 -2
- package/dist/consolidation-undo.d.ts +2 -2
- package/dist/contradiction/index.d.ts +2 -2
- package/dist/contradiction/index.js +10 -2
- package/dist/converge-config.d.ts +1 -1
- package/dist/convergence-refresh.d.ts +2 -2
- package/dist/convergence-refresh.js +18 -17
- 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 +18 -17
- package/dist/cross-lingual-recall.d.ts +1 -1
- package/dist/day-summary.d.ts +1 -1
- package/dist/delinearize.d.ts +1 -1
- package/dist/dependency-propagation-config.d.ts +1 -1
- package/dist/{dependency-propagation-delivery-Co17gxYb.d.ts → dependency-propagation-delivery-CsGg-VwS.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-origin-fields.d.ts +1 -1
- package/dist/entity-retrieval.d.ts +2 -2
- package/dist/entity-retrieval.js +16 -15
- package/dist/entity-schema.d.ts +1 -1
- package/dist/episodic-context.d.ts +1 -1
- package/dist/explicit-capture.d.ts +9 -9
- package/dist/explicit-capture.js +7 -6
- package/dist/external-wiki-access.d.ts +12 -13
- package/dist/external-wiki-access.js +36 -35
- package/dist/external-wiki-collection-registration.d.ts +1 -1
- package/dist/external-wiki-collection.d.ts +1 -1
- package/dist/external-wiki-mcp-tools.d.ts +11 -11
- 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-judge.js +2 -2
- package/dist/extraction-liveness.d.ts +1 -1
- package/dist/extraction-normalization.d.ts +1 -1
- package/dist/extraction-normalization.js +2 -2
- package/dist/extraction-prompt.d.ts +2 -2
- package/dist/extraction-prompt.js +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/extraction.js +22 -21
- package/dist/fallback-llm.d.ts +1 -1
- package/dist/graph-dashboard-diff.d.ts +1 -1
- package/dist/graph-dashboard-key.d.ts +1 -1
- package/dist/graph-dashboard-parser.d.ts +1 -1
- package/dist/graph-edge-reinforcement.d.ts +1 -1
- package/dist/graph-path-reconstruction.d.ts +1 -1
- package/dist/graph-path-scoring.d.ts +1 -1
- package/dist/graph-snapshot.d.ts +1 -1
- package/dist/graph.d.ts +1 -1
- package/dist/harmonic-retrieval.js +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 +716 -699
- package/dist/index.js +173 -125
- package/dist/intent.d.ts +1 -1
- package/dist/lcm/engine.d.ts +1 -1
- package/dist/lcm/engine.js +3 -3
- package/dist/lcm/index.d.ts +1 -1
- package/dist/lcm/index.js +6 -6
- package/dist/lcm/tools.d.ts +1 -1
- package/dist/lifecycle.d.ts +1 -1
- package/dist/live-connectors-runner.d.ts +1 -1
- package/dist/local-llm.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 +16 -15
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +16 -15
- package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-projection.js +17 -16
- package/dist/{maintenance-DiSLtVN7.d.ts → maintenance-jhMpeGne.d.ts} +3 -3
- package/dist/mcp-memory-inspector-app.d.ts +11 -11
- package/dist/mcp-read-only-tools.js +1 -1
- 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-snapshot.d.ts +1 -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 +5 -4
- package/dist/memory-worth-outcomes.js +1 -1
- package/dist/models-json.d.ts +1 -1
- package/dist/namespaces/migrate.d.ts +3 -3
- package/dist/namespaces/migrate.js +17 -16
- package/dist/namespaces/principal.d.ts +1 -1
- package/dist/namespaces/search.d.ts +1 -1
- package/dist/namespaces/search.js +6 -6
- package/dist/namespaces/storage.d.ts +3 -3
- package/dist/namespaces/storage.js +16 -15
- package/dist/native-knowledge.d.ts +1 -1
- package/dist/offline-sync-impression-drain.d.ts +1 -1
- package/dist/operator-doctor-corpus.d.ts +1 -1
- package/dist/operator-doctor-corpus.js +19 -18
- package/dist/operator-doctor-replica.d.ts +1 -1
- package/dist/operator-toolkit.d.ts +3 -3
- package/dist/operator-toolkit.js +26 -24
- package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
- package/dist/orchestration/maintenance.d.ts +4 -4
- package/dist/orchestration/maintenance.js +22 -21
- package/dist/{orchestrator-DzCaxNS4.d.ts → orchestrator-DyGUC7re.d.ts} +8 -8
- package/dist/orchestrator.d.ts +9 -9
- package/dist/orchestrator.js +108 -105
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/{pipeline-HJ8DKbFl.d.ts → pipeline-C25Oxtp1.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/{public-http-DwXauTX3.d.ts → public-http-CMe7NQzj.d.ts} +1 -1
- package/dist/{qmd-BzxluoLt.d.ts → qmd-DkDVCbgF.d.ts} +1 -1
- package/dist/qmd-preflight.d.ts +2 -2
- package/dist/qmd-recall-cache.d.ts +1 -1
- package/dist/qmd.d.ts +2 -2
- package/dist/qmd.js +4 -4
- package/dist/recall-concurrency-config.d.ts +1 -1
- package/dist/recall-disclosure-escalation.d.ts +1 -1
- package/dist/recall-explain-renderer.d.ts +1 -1
- package/dist/recall-explain-renderer.js +3 -3
- package/dist/recall-memory-map.d.ts +1 -1
- package/dist/recall-planner-llm.d.ts +1 -1
- package/dist/recall-state.d.ts +1 -1
- package/dist/recall-tag-filter.d.ts +1 -1
- package/dist/recall-timings.d.ts +1 -1
- package/dist/recall-xray-cli.d.ts +1 -1
- package/dist/recall-xray-cli.js +4 -4
- package/dist/recall-xray-renderer.d.ts +1 -1
- package/dist/recall-xray-renderer.js +3 -3
- package/dist/recall-xray.d.ts +1 -1
- package/dist/recall-xray.js +2 -2
- package/dist/reconcile/cursor.d.ts +1 -1
- package/dist/reconcile/manifest.d.ts +1 -1
- package/dist/reconcile/manifest.js +3 -3
- package/dist/reconcile/plan.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/{resolution-DKMBPXHI.js → resolution-MFY72STR.js} +11 -3
- package/dist/resolution-MFY72STR.js.map +1 -0
- package/dist/resolve-auth-token.d.ts +1 -1
- package/dist/resume-bundles.js +7 -2
- package/dist/retrieval-agents.d.ts +2 -2
- package/dist/retrieval-tiers.d.ts +1 -1
- package/dist/routing/engine.d.ts +1 -1
- package/dist/routing/store.d.ts +1 -1
- package/dist/salvage-envelope.d.ts +1 -1
- package/dist/salvage-envelope.js +10 -2
- package/dist/schemas.d.ts +104 -90
- package/dist/schemas.js +1 -1
- package/dist/{scope-profiles-CEMZz0t5.d.ts → scope-profiles-B9xMoFO-.d.ts} +1 -1
- package/dist/search/embed-helper.d.ts +1 -1
- package/dist/search/factory.d.ts +1 -1
- package/dist/search/factory.js +5 -5
- package/dist/search/index.d.ts +1 -1
- package/dist/search/index.js +9 -9
- package/dist/search/lancedb-backend.d.ts +1 -1
- package/dist/search/meilisearch-backend.d.ts +1 -1
- package/dist/search/noop-backend.d.ts +1 -1
- package/dist/search/orama-backend.d.ts +1 -1
- package/dist/search/port.d.ts +1 -1
- package/dist/search/remote-backend.d.ts +1 -1
- package/dist/{semantic-consolidation-D9dYj6vu.d.ts → semantic-consolidation-C4uykW84.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +17 -16
- package/dist/semantic-rule-promotion.js +16 -15
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/semantic-rule-verifier.js +16 -15
- package/dist/{service-_qgST_0y.d.ts → service-DCZDZNcV.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 +11 -11
- package/dist/signal.d.ts +1 -1
- package/dist/source-agent-qualifier.d.ts +1 -1
- package/dist/source-agent-qualifier.js +18 -17
- package/dist/{storage-B9lbNTYE.d.ts → storage-CcKmEjL8.d.ts} +3 -2
- package/dist/storage.d.ts +2 -2
- package/dist/storage.js +18 -17
- package/dist/subject-config.d.ts +38 -0
- package/dist/subject-config.js +20 -0
- package/dist/subject-config.js.map +1 -0
- package/dist/summarizer.d.ts +1 -1
- package/dist/summary-snapshot.d.ts +1 -1
- package/dist/support-passport/index.d.ts +14 -14
- package/dist/support-passport/index.js +38 -37
- package/dist/temporal-supersession.d.ts +2 -2
- package/dist/temporal-timeline-recall.d.ts +1 -1
- package/dist/temporal-validity.d.ts +1 -1
- package/dist/threading.d.ts +1 -1
- package/dist/tier-migration.d.ts +2 -2
- package/dist/tier-routing.d.ts +1 -1
- package/dist/topics.d.ts +1 -1
- package/dist/transcript.d.ts +1 -1
- package/dist/transfer/backup.js +2 -2
- package/dist/transfer/capsule-export.js +2 -2
- package/dist/transfer/capsule-import.js +2 -2
- package/dist/transfer/types.d.ts +66 -66
- package/dist/trust-score-stage.d.ts +1 -1
- package/dist/trust-score.d.ts +1 -1
- package/dist/{types-BrEzuxPA.d.ts → types-Pi0lfaEt.d.ts} +38 -29
- package/dist/types.d.ts +1 -1
- package/dist/types.js +1 -1
- package/dist/utility-runtime.d.ts +1 -1
- package/dist/verified-recall.js +16 -15
- package/dist/who-knows-cli.d.ts +11 -11
- package/dist/who-knows-cli.js +17 -16
- package/dist/who-knows.d.ts +11 -11
- package/dist/who-knows.js +16 -15
- package/dist/write-envelope.d.ts +5 -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 +2 -0
- package/src/access-mcp-admin-tools.ts +14 -0
- package/src/access-mcp-output-schemas.ts +6 -0
- package/src/access-mcp.ts +6 -6
- package/src/access-operations-batch.ts +8 -0
- package/src/access-service.ts +85 -0
- package/src/access-surface-catalog.ts +2 -0
- package/src/config.ts +10 -17
- package/src/extraction-prompt.ts +1 -0
- package/src/extraction.ts +4 -1
- package/src/index.ts +5 -6
- 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/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/schemas.ts +7 -0
- package/src/spaces/index.ts +38 -2
- package/src/storage.ts +6 -2
- package/src/subject-config.ts +80 -0
- package/src/types.ts +26 -29
- package/src/write-envelope.test.ts +14 -0
- package/src/write-envelope.ts +24 -3
- 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-MSTNSVXI.js.map +0 -1
- package/dist/chunk-YQ3CBLL4.js.map +0 -1
- package/dist/chunk-Z54TXZ2F.js.map +0 -1
- /package/dist/{capsule-crypto-7FJQINUR.js.map → capsule-crypto-YO5QJ6L3.js.map} +0 -0
- /package/dist/{chunk-LYIZXQYY.js.map → chunk-2E36UXVW.js.map} +0 -0
- /package/dist/{chunk-7QFBLYFP.js.map → chunk-2XDWWPTN.js.map} +0 -0
- /package/dist/{chunk-CFRBTATE.js.map → chunk-2YI72KM3.js.map} +0 -0
- /package/dist/{chunk-3YTTAGPB.js.map → chunk-3DVBKTSO.js.map} +0 -0
- /package/dist/{chunk-VPGRXEAB.js.map → chunk-3I7ASZN3.js.map} +0 -0
- /package/dist/{chunk-WTOE7CW4.js.map → chunk-4KYOLI6M.js.map} +0 -0
- /package/dist/{chunk-ESCQ6LY7.js.map → chunk-5NM4OH4P.js.map} +0 -0
- /package/dist/{chunk-Y23B2QXP.js.map → chunk-5YQ63T4B.js.map} +0 -0
- /package/dist/{chunk-PMVPCZJZ.js.map → chunk-6433HV72.js.map} +0 -0
- /package/dist/{chunk-NS5ETDYD.js.map → chunk-7BEPVIH3.js.map} +0 -0
- /package/dist/{chunk-W6TSGWYS.js.map → chunk-7YQ4IYS2.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-5UYSCYR7.js.map → chunk-CT56C22C.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-CCTVAVTT.js.map → chunk-DZUJ46DO.js.map} +0 -0
- /package/dist/{chunk-N6TRHP72.js.map → chunk-EILZG5VC.js.map} +0 -0
- /package/dist/{chunk-GXWDWOWP.js.map → chunk-GDFVPUJ5.js.map} +0 -0
- /package/dist/{chunk-7PWWGYGO.js.map → chunk-GNCCUR6K.js.map} +0 -0
- /package/dist/{chunk-KPBLJCCV.js.map → chunk-IID2CMUU.js.map} +0 -0
- /package/dist/{chunk-UYCIS6V5.js.map → chunk-JCWY73FK.js.map} +0 -0
- /package/dist/{chunk-SYJ6EKKE.js.map → chunk-JYYBA7TF.js.map} +0 -0
- /package/dist/{chunk-T42L3S6A.js.map → chunk-LBWQ65SX.js.map} +0 -0
- /package/dist/{chunk-LWVO2QZV.js.map → chunk-LGO6A7GJ.js.map} +0 -0
- /package/dist/{chunk-2572MRP2.js.map → chunk-LZH5FR2W.js.map} +0 -0
- /package/dist/{chunk-256FBCVX.js.map → chunk-M4AHBM72.js.map} +0 -0
- /package/dist/{chunk-YEQEGSJA.js.map → chunk-MN4KB2A4.js.map} +0 -0
- /package/dist/{chunk-AGKIG3YA.js.map → chunk-NKKD4ZAU.js.map} +0 -0
- /package/dist/{chunk-3TMYV3LP.js.map → chunk-NTWN6HB2.js.map} +0 -0
- /package/dist/{chunk-63FHSH7E.js.map → chunk-OCZIYAE5.js.map} +0 -0
- /package/dist/{chunk-I2HTKOOP.js.map → chunk-ODZG724P.js.map} +0 -0
- /package/dist/{chunk-HQSBYI5X.js.map → chunk-OTHZWLUD.js.map} +0 -0
- /package/dist/{chunk-4W6INNXO.js.map → chunk-PE255F4T.js.map} +0 -0
- /package/dist/{chunk-6L27N6YI.js.map → chunk-QOS5LBZN.js.map} +0 -0
- /package/dist/{chunk-G72IPMR7.js.map → chunk-R4OCGPSH.js.map} +0 -0
- /package/dist/{chunk-MIBKEW7A.js.map → chunk-R7JAM2XF.js.map} +0 -0
- /package/dist/{chunk-JBPKEARU.js.map → chunk-RKNJBZ55.js.map} +0 -0
- /package/dist/{chunk-HUNSEO5U.js.map → chunk-S2DPMJXH.js.map} +0 -0
- /package/dist/{chunk-HQSPXTQO.js.map → chunk-SIHSCCUQ.js.map} +0 -0
- /package/dist/{chunk-R3AAOKR2.js.map → chunk-SPUJNJJC.js.map} +0 -0
- /package/dist/{chunk-IAY7YBXS.js.map → chunk-SQI57UCJ.js.map} +0 -0
- /package/dist/{chunk-CTQRPANJ.js.map → chunk-SVSRPG6M.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-BC4QD3FM.js.map → chunk-UIN2BWDD.js.map} +0 -0
- /package/dist/{chunk-JTSVMJHV.js.map → chunk-UXO5IMBK.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-MDVBCPOS.js.map → chunk-XCTXS7VY.js.map} +0 -0
- /package/dist/{chunk-53ENM6F6.js.map → chunk-XRYZRW54.js.map} +0 -0
- /package/dist/{chunk-VJ6ECBIP.js.map → chunk-Y7DK7HHJ.js.map} +0 -0
- /package/dist/{chunk-3MADV4YC.js.map → chunk-YB42WZCY.js.map} +0 -0
- /package/dist/{chunk-X5SDZMO7.js.map → chunk-YHCBJULX.js.map} +0 -0
- /package/dist/{chunk-6JJT5AKI.js.map → chunk-Z7PBQPJ4.js.map} +0 -0
- /package/dist/{chunk-ALCJRQ72.js.map → chunk-ZO6AXLEH.js.map} +0 -0
- /package/dist/{chunk-VZVP2W4O.js.map → chunk-ZQHI2BZB.js.map} +0 -0
- /package/dist/{resolution-DKMBPXHI.js.map → memory-subject-cli.js.map} +0 -0
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
*/
|
|
13
13
|
import type { MemoryFile, MemoryStatus, PluginConfig } from "../types.js";
|
|
14
14
|
import type { StorageManager } from "../storage.js";
|
|
15
|
+
import { isActiveMemoryStatus } from "../memory-lifecycle-ledger-utils.js";
|
|
16
|
+
import { readProcedureMaintenanceMarker } from "./library-maintenance.js";
|
|
15
17
|
|
|
16
18
|
export interface ProcedureStatusCounts {
|
|
17
19
|
total: number;
|
|
@@ -50,6 +52,10 @@ export interface ProcedureStatsReport {
|
|
|
50
52
|
counts: ProcedureStatusCounts;
|
|
51
53
|
recent: ProcedureStatsRecent;
|
|
52
54
|
config: ProcedureStatsConfigSnapshot;
|
|
55
|
+
/** ISO timestamp of the last library-maintenance run marker, or null (issue #2370). */
|
|
56
|
+
lastMaintenanceAt: string | null;
|
|
57
|
+
/** Active procedures currently carrying a `needsRepair` flag (issue #2370). */
|
|
58
|
+
needsRepairFlags: number;
|
|
53
59
|
}
|
|
54
60
|
|
|
55
61
|
function snapshotConfig(config: PluginConfig): ProcedureStatsConfigSnapshot {
|
|
@@ -102,6 +108,7 @@ export async function computeProcedureStats(options: {
|
|
|
102
108
|
let lastWriteMs: number | null = null;
|
|
103
109
|
let writesLast7Days = 0;
|
|
104
110
|
let minerSourced = 0;
|
|
111
|
+
let needsRepairFlags = 0;
|
|
105
112
|
|
|
106
113
|
const known: MemoryStatus[] = [
|
|
107
114
|
"active",
|
|
@@ -159,8 +166,15 @@ export async function computeProcedureStats(options: {
|
|
|
159
166
|
if (m.frontmatter.source === "procedure-miner") {
|
|
160
167
|
minerSourced += 1;
|
|
161
168
|
}
|
|
169
|
+
if (
|
|
170
|
+
m.frontmatter.structuredAttributes?.needsRepair !== undefined &&
|
|
171
|
+
isActiveMemoryStatus(m.frontmatter.status)
|
|
172
|
+
) {
|
|
173
|
+
needsRepairFlags += 1;
|
|
174
|
+
}
|
|
162
175
|
}
|
|
163
176
|
|
|
177
|
+
const maintenanceMarker = await readProcedureMaintenanceMarker(storage.dir);
|
|
164
178
|
return {
|
|
165
179
|
schemaVersion: 1,
|
|
166
180
|
generatedAt: new Date(nowMs).toISOString(),
|
|
@@ -171,6 +185,8 @@ export async function computeProcedureStats(options: {
|
|
|
171
185
|
minerSourced,
|
|
172
186
|
},
|
|
173
187
|
config: snapshotConfig(config),
|
|
188
|
+
lastMaintenanceAt: maintenanceMarker?.lastRunAt ?? null,
|
|
189
|
+
needsRepairFlags,
|
|
174
190
|
};
|
|
175
191
|
}
|
|
176
192
|
|
|
@@ -210,5 +226,9 @@ export function formatProcedureStatsText(report: ProcedureStatsReport): string {
|
|
|
210
226
|
lines.push(` lastWriteAt: ${recent.lastWriteAt ?? "(none)"}`);
|
|
211
227
|
lines.push(` writesLast7Days: ${recent.writesLast7Days}`);
|
|
212
228
|
lines.push(` minerSourced: ${recent.minerSourced}`);
|
|
229
|
+
lines.push("");
|
|
230
|
+
lines.push(` maintenance:`);
|
|
231
|
+
lines.push(` lastMaintenanceAt: ${report.lastMaintenanceAt ?? "(never)"}`);
|
|
232
|
+
lines.push(` needsRepairFlags: ${report.needsRepairFlags}`);
|
|
213
233
|
return lines.join("\n") + "\n";
|
|
214
234
|
}
|
package/src/schemas.ts
CHANGED
|
@@ -103,6 +103,13 @@ export const ExtractedFactSchema = z.object({
|
|
|
103
103
|
.describe(
|
|
104
104
|
'Scope classification: "global" for cross-project knowledge (framework bugs, library behavior, API patterns, user preferences, general coding patterns); "project" for project-specific knowledge (file paths, env configs, deployment details, project workarounds) and for tool, command, or CLI-flag instructions tied to one agent, since the same tool name can mean different things across agents. When keeping such an agent-tied instruction, begin the fact with a leading "In <agent>," clause naming that agent. Defaults to "project" when a coding context is active.',
|
|
105
105
|
),
|
|
106
|
+
subject: z
|
|
107
|
+
.enum(["user", "agent"])
|
|
108
|
+
.optional()
|
|
109
|
+
.nullable()
|
|
110
|
+
.describe(
|
|
111
|
+
'Memory subject: "user" when the fact models the person (preferences, relationships, biography, moments, commitments about their life); "agent" when it is reusable operating knowledge (procedures, principles, tool-usage lessons, debugging strategies, environment facts with no personal content). Emit only for fact/decision-like facts; the category defaults cover preference, relationship, moment, commitment, procedure, principle, and skill.',
|
|
112
|
+
),
|
|
106
113
|
quote: z
|
|
107
114
|
.string()
|
|
108
115
|
.optional()
|
package/src/spaces/index.ts
CHANGED
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
* through push/pull and promotion workflows.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
+
import { evaluateSubjectGuard } from "../memory-subject.js";
|
|
12
|
+
import type { SubjectGuardMode } from "../types.js";
|
|
11
13
|
import { spawnSync } from "node:child_process";
|
|
12
14
|
import crypto from "node:crypto";
|
|
13
15
|
import fs from "node:fs";
|
|
@@ -99,6 +101,8 @@ export interface SpacePromoteResult {
|
|
|
99
101
|
memoriesPromoted: number;
|
|
100
102
|
conflicts: ConflictEntry[];
|
|
101
103
|
durationMs: number;
|
|
104
|
+
/** Subject-guard warnings (issue #2372): user-subject memories promoted to a shared team space under "warn". */
|
|
105
|
+
subjectWarnings?: string[];
|
|
102
106
|
}
|
|
103
107
|
|
|
104
108
|
export interface ConflictEntry {
|
|
@@ -748,7 +752,10 @@ export function shareSpace(spaceId: string, members: string[], baseDir?: string)
|
|
|
748
752
|
export async function promoteSpace(
|
|
749
753
|
sourceSpaceId: string,
|
|
750
754
|
targetSpaceId: string,
|
|
751
|
-
options?: {
|
|
755
|
+
options?: {
|
|
756
|
+
memoryIds?: string[]; force?: boolean; forceOverwrite?: boolean; baseDir?: string;
|
|
757
|
+
subjectGuard?: SubjectGuardMode; allowUserSubject?: boolean;
|
|
758
|
+
}
|
|
752
759
|
): Promise<SpacePromoteResult> {
|
|
753
760
|
const startTime = Date.now();
|
|
754
761
|
const manifest = loadManifest(options?.baseDir);
|
|
@@ -766,6 +773,33 @@ export async function promoteSpace(
|
|
|
766
773
|
}
|
|
767
774
|
}
|
|
768
775
|
|
|
776
|
+
// Subject guard (issue #2372): the SAME gate as the scope-profile promotion
|
|
777
|
+
// path — a user-subject (or unstamped, fail-closed) memory promoted into a
|
|
778
|
+
// TEAM space warns/rejects with the override named; recorded in the audit trail.
|
|
779
|
+
const subjectWarnings: string[] = [];
|
|
780
|
+
const warnedMemoryIds: string[] = [];
|
|
781
|
+
if (target.kind === "team") {
|
|
782
|
+
const sourceFiles = fs.existsSync(source.memoryDir) ? walkMd(fs.realpathSync(source.memoryDir)) : [];
|
|
783
|
+
for (const file of sourceFiles) {
|
|
784
|
+
const fm = parseSimpleFrontmatter(fs.readFileSync(file, "utf8"));
|
|
785
|
+
if (!fm?.id) continue;
|
|
786
|
+
if (options?.memoryIds?.length && !options.memoryIds.includes(fm.id)) continue;
|
|
787
|
+
const decision = evaluateSubjectGuard({
|
|
788
|
+
subject: fm.subject === "user" || fm.subject === "agent" ? fm.subject : undefined,
|
|
789
|
+
sharedTarget: true,
|
|
790
|
+
mode: options?.subjectGuard ?? "warn",
|
|
791
|
+
allowUserSubject: options?.allowUserSubject,
|
|
792
|
+
});
|
|
793
|
+
if (decision.action === "reject") {
|
|
794
|
+
throw new Error(`space promote blocked by subject guard: memory ${fm.id} — ${decision.reason}`);
|
|
795
|
+
}
|
|
796
|
+
if (decision.action === "warn") {
|
|
797
|
+
subjectWarnings.push(`memory ${fm.id}: ${decision.reason}`);
|
|
798
|
+
warnedMemoryIds.push(fm.id);
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
|
|
769
803
|
const result = await copyMemories(source.memoryDir, target.memoryDir, {
|
|
770
804
|
filterIds: options?.memoryIds,
|
|
771
805
|
force: options?.forceOverwrite !== undefined ? options.forceOverwrite : (options?.force ?? false),
|
|
@@ -776,7 +810,8 @@ export async function promoteSpace(
|
|
|
776
810
|
action: "space.promote",
|
|
777
811
|
sourceSpaceId,
|
|
778
812
|
targetSpaceId,
|
|
779
|
-
details: `Promoted ${result.merged} memories from "${source.name}" to "${target.name}"`,
|
|
813
|
+
details: `Promoted ${result.merged} memories from "${source.name}" to "${target.name}"${subjectWarnings.length > 0 ? `; subject-guard warned ${subjectWarnings.length} user-subject memories (${warnedMemoryIds.join(", ")})` : ""}${options?.allowUserSubject === true ? "; user-subject override: --allow-user-subject" : ""}`,
|
|
814
|
+
...(warnedMemoryIds.length > 0 ? { memoryIds: warnedMemoryIds } : {}),
|
|
780
815
|
},
|
|
781
816
|
options?.baseDir
|
|
782
817
|
);
|
|
@@ -787,6 +822,7 @@ export async function promoteSpace(
|
|
|
787
822
|
memoriesPromoted: result.merged,
|
|
788
823
|
conflicts: result.conflicts,
|
|
789
824
|
durationMs: Date.now() - startTime,
|
|
825
|
+
...(subjectWarnings.length > 0 ? { subjectWarnings } : {}),
|
|
790
826
|
};
|
|
791
827
|
}
|
|
792
828
|
|
package/src/storage.ts
CHANGED
|
@@ -166,6 +166,7 @@ import type {
|
|
|
166
166
|
VerificationState,
|
|
167
167
|
PolicyClass,
|
|
168
168
|
MemoryStatus,
|
|
169
|
+
MemorySubject,
|
|
169
170
|
MemoryActionEvent,
|
|
170
171
|
MemoryLifecycleEvent,
|
|
171
172
|
MemoryLifecycleEventType,
|
|
@@ -326,6 +327,7 @@ function serializeFrontmatter(fm: MemoryFrontmatter): string {
|
|
|
326
327
|
if (fm.language) lines.push(`language: ${fm.language}`);
|
|
327
328
|
if (fm.type !== undefined) lines.push(`type: ${fm.type}`);
|
|
328
329
|
if (fm.origin) lines.push(`origin: ${/^[A-Za-z0-9:_.*-]+$/.test(fm.origin) ? fm.origin : JSON.stringify(fm.origin)}`);
|
|
330
|
+
if (fm.subject) lines.push(`subject: ${fm.subject}`);
|
|
329
331
|
if (fm.entityRef) lines.push(`entityRef: ${fm.entityRef}`);
|
|
330
332
|
if (fm.sourceConnector) {
|
|
331
333
|
// YAML-injection guard (review thread QMPsP): emit unquoted for
|
|
@@ -871,6 +873,7 @@ export function parseFrontmatter(raw: string): { frontmatter: MemoryFrontmatter;
|
|
|
871
873
|
tags,
|
|
872
874
|
entityRef: fm.entityRef || undefined,
|
|
873
875
|
origin: fm.origin !== undefined ? parseOriginClass(decodeYamlScalar(fm.origin)) : undefined,
|
|
876
|
+
subject: fm.subject === "user" || fm.subject === "agent" ? fm.subject : undefined,
|
|
874
877
|
sourceConnector: fm.sourceConnector ? decodeYamlScalar(fm.sourceConnector) || undefined : undefined,
|
|
875
878
|
toolScoped: fm.toolScoped === "true" ? true : undefined,
|
|
876
879
|
supersedes: fm.supersedes || undefined,
|
|
@@ -1739,6 +1742,7 @@ export interface WriteMemoryOptions {
|
|
|
1739
1742
|
origin?: string;
|
|
1740
1743
|
sourceConnector?: string;
|
|
1741
1744
|
toolScoped?: true;
|
|
1745
|
+
subject?: MemorySubject;
|
|
1742
1746
|
}
|
|
1743
1747
|
|
|
1744
1748
|
/**
|
|
@@ -1747,7 +1751,7 @@ export interface WriteMemoryOptions {
|
|
|
1747
1751
|
*/
|
|
1748
1752
|
export type SealedWriteExtras = Omit<
|
|
1749
1753
|
WriteMemoryOptions,
|
|
1750
|
-
"confidence" | "tags" | "entityRef" | "source" | "expiresAt" | "validAt" | "structuredAttributes" | "sourceConnector" | "origin"
|
|
1754
|
+
"confidence" | "tags" | "entityRef" | "source" | "expiresAt" | "validAt" | "structuredAttributes" | "sourceConnector" | "origin" | "subject"
|
|
1751
1755
|
>;
|
|
1752
1756
|
|
|
1753
1757
|
export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
@@ -3791,7 +3795,7 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
3791
3795
|
fm.sourceConnector = options.sourceConnector;
|
|
3792
3796
|
}
|
|
3793
3797
|
if (options.origin !== undefined) fm.origin = parseOriginClass(options.origin);
|
|
3794
|
-
|
|
3798
|
+
if (options.subject !== undefined) fm.subject = options.subject;
|
|
3795
3799
|
// Assemble the persisted body (attribute-suffix enrichment + combined
|
|
3796
3800
|
// sanitize) via the SHARED helper — the sealed-envelope composer uses the
|
|
3797
3801
|
// same one, so the two write paths cannot diverge (issue #1989 PR2).
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config parsing for the memory-subject runtime knobs (issue #2372).
|
|
3
|
+
*
|
|
4
|
+
* Extracted from config.ts (its structural-ratchet ceiling forbids growth);
|
|
5
|
+
* `parseConfig` spreads `parseSubjectRuntimeConfig(cfg)` into the plugin
|
|
6
|
+
* config literal.
|
|
7
|
+
*
|
|
8
|
+
* Validation posture (Review Prevention Checklist §1/§24/§39): invalid
|
|
9
|
+
* values are REJECTED loudly, never silently reinterpreted — but an omitted
|
|
10
|
+
* key takes the documented default. The deliberate asymmetry from the issue
|
|
11
|
+
* stands: classification defaults OFF while the guard defaults "warn", so
|
|
12
|
+
* enabling classification later immediately yields promotion warnings
|
|
13
|
+
* without a second flag flip, and with classification off, unstamped
|
|
14
|
+
* memories still only warn (never silently promote) at shared targets.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { coerceBool, coerceNumber } from "./connectors/coerce.js";
|
|
18
|
+
import {
|
|
19
|
+
isSubjectGuardMode,
|
|
20
|
+
PROMOTION_CANDIDATES_DEFAULT_MIN_ACCESS,
|
|
21
|
+
} from "./memory-subject.js";
|
|
22
|
+
import type { SubjectGuardMode } from "./types.js";
|
|
23
|
+
|
|
24
|
+
export interface SubjectRuntimeConfig {
|
|
25
|
+
subjectClassification: { enabled: boolean };
|
|
26
|
+
subjectGuard: SubjectGuardMode;
|
|
27
|
+
promotionCandidates: { minAccessCount: number };
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Reject a non-object block loudly (rule 51 / §1): a shorthand like
|
|
32
|
+
* `subjectClassification: false` must never normalize silently to `{}`.
|
|
33
|
+
* Returns void so callers read the block through a DIRECT `cfg.<key>`
|
|
34
|
+
* member access — the config-contract parser walker derives nested key
|
|
35
|
+
* paths from those accesses, and a helper return value hides them.
|
|
36
|
+
*/
|
|
37
|
+
function assertObjectBlock(value: unknown, key: string, shape: string): void {
|
|
38
|
+
if (value === undefined) return;
|
|
39
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
40
|
+
throw new Error(
|
|
41
|
+
`${key} must be an object (got ${JSON.stringify(value)}). Use ${shape} (issue #2372).`,
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function parseSubjectRuntimeConfig(cfg: Record<string, unknown>): SubjectRuntimeConfig {
|
|
47
|
+
assertObjectBlock(cfg.subjectClassification, "subjectClassification", "subjectClassification: { enabled: true }");
|
|
48
|
+
const classification = (cfg.subjectClassification ?? {}) as Record<string, unknown>;
|
|
49
|
+
const rawEnabled = classification.enabled;
|
|
50
|
+
const enabledCoerced = coerceBool(rawEnabled);
|
|
51
|
+
if (rawEnabled !== undefined && enabledCoerced === undefined) {
|
|
52
|
+
throw new Error(
|
|
53
|
+
`subjectClassification.enabled must be a boolean or one of "true"/"false"/"1"/"0"/` +
|
|
54
|
+
`"yes"/"no"/"on"/"off" (got ${JSON.stringify(rawEnabled)}) — rejected, not defaulted (issue #2372).`,
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
const rawGuard = cfg.subjectGuard;
|
|
58
|
+
if (rawGuard !== undefined && !isSubjectGuardMode(rawGuard)) {
|
|
59
|
+
throw new Error(
|
|
60
|
+
`subjectGuard must be one of: off, warn, enforce (got ${JSON.stringify(rawGuard)}) — ` +
|
|
61
|
+
`rejected, not defaulted (issue #2372; checklist §1/§39).`,
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
assertObjectBlock(cfg.promotionCandidates, "promotionCandidates", "promotionCandidates: { minAccessCount: 3 }");
|
|
65
|
+
const candidates = (cfg.promotionCandidates ?? {}) as Record<string, unknown>;
|
|
66
|
+
const minAccessRaw = coerceNumber(candidates.minAccessCount);
|
|
67
|
+
if (candidates.minAccessCount !== undefined && (minAccessRaw === undefined || !Number.isFinite(minAccessRaw) || minAccessRaw < 0)) {
|
|
68
|
+
throw new Error(
|
|
69
|
+
`promotionCandidates.minAccessCount must be a non-negative number (got ${JSON.stringify(candidates.minAccessCount)}) — rejected, not defaulted (issue #2372).`,
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
subjectClassification: { enabled: rawEnabled === undefined ? false : enabledCoerced === true },
|
|
74
|
+
subjectGuard: isSubjectGuardMode(rawGuard) ? rawGuard : "warn",
|
|
75
|
+
promotionCandidates: {
|
|
76
|
+
minAccessCount:
|
|
77
|
+
minAccessRaw !== undefined ? Math.floor(minAccessRaw) : PROMOTION_CANDIDATES_DEFAULT_MIN_ACCESS,
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -11,8 +11,11 @@ import type { ContradictionLocalizationConfig, ContradictionScanConfig } from ".
|
|
|
11
11
|
import type { GraphPathScoringConfig } from "./graph-path-scoring-config.js";
|
|
12
12
|
export type { ContradictionLocalizationConfig, ContradictionScanConfig } from "./contradiction-config.js";
|
|
13
13
|
export type { GraphPathScoringConfig } from "./graph-path-scoring-config.js";
|
|
14
|
+
import type { ProceduralMaintenanceConfig } from "./procedural/maintenance-config.js";
|
|
14
15
|
|
|
15
16
|
import type { AmbientCaptureProvenance, BufferTurnOwner, SecurityConfig, OriginMetadata } from "./security/types.js";
|
|
17
|
+
export type MemorySubject = "user" | "agent";
|
|
18
|
+
export type SubjectGuardMode = "off" | "warn" | "enforce";
|
|
16
19
|
export type ReasoningEffort = "none" | "low" | "medium" | "high";
|
|
17
20
|
export type TriggerMode = "smart" | "every_n" | "time_based";
|
|
18
21
|
export type ConvergeConflictPolicy = "newest-wins" | "manual";
|
|
@@ -383,7 +386,6 @@ export interface DreamsPhasesConfig {
|
|
|
383
386
|
deepSleep: DreamsDeepSleepConfig;
|
|
384
387
|
}
|
|
385
388
|
|
|
386
|
-
/** Procedural memory (issue #519): mining + recall gates. All sub-features default off. */
|
|
387
389
|
export interface ProceduralConfig {
|
|
388
390
|
enabled: boolean;
|
|
389
391
|
/** Minimum cluster size before emitting a candidate; `0` disables mining (`minOccurrences_zero`). */
|
|
@@ -396,8 +398,8 @@ export interface ProceduralConfig {
|
|
|
396
398
|
lookbackDays: number;
|
|
397
399
|
/** When true, installer may register the nightly procedural mining cron (default off). */
|
|
398
400
|
proceduralMiningCronAutoRegister: boolean;
|
|
399
|
-
/** Max procedure memories to inject on task-initiation recall (1–10). */
|
|
400
401
|
recallMaxProcedures: number;
|
|
402
|
+
maintenance: ProceduralMaintenanceConfig;
|
|
401
403
|
}
|
|
402
404
|
|
|
403
405
|
/**
|
|
@@ -1041,14 +1043,11 @@ export interface PluginConfig extends BoundedJsonlStateConfig, SecurityConfig {
|
|
|
1041
1043
|
recallMaxConcurrentPerPrincipal: number;
|
|
1042
1044
|
/** Coalesce identical concurrent recalls per principal; each caller gets its own clone. Default true. */
|
|
1043
1045
|
recallSingleFlightEnabled: boolean;
|
|
1044
|
-
// Memory Worth recall filter (issue #560 PR 4)
|
|
1045
1046
|
/**
|
|
1046
|
-
* When true, recall multiplies candidate scores by the Memory Worth
|
|
1047
|
-
*
|
|
1048
|
-
*
|
|
1049
|
-
*
|
|
1050
|
-
* are untouched (multiplier 1.0). Default false — flip to true in PR 5
|
|
1051
|
-
* once the benchmark shows precision tie-or-win.
|
|
1047
|
+
* When true, recall multiplies candidate scores by the Memory Worth factor
|
|
1048
|
+
* from `mw_success` / `mw_fail` (see `computeMemoryWorth`): failed memories
|
|
1049
|
+
* sink; neutral ones untouched (multiplier 1.0). Default false until the
|
|
1050
|
+
* benchmark shows precision tie-or-win.
|
|
1052
1051
|
*/
|
|
1053
1052
|
recallMemoryWorthFilterEnabled: boolean;
|
|
1054
1053
|
/**
|
|
@@ -1265,6 +1264,10 @@ export interface PluginConfig extends BoundedJsonlStateConfig, SecurityConfig {
|
|
|
1265
1264
|
codexCompat: CodexCompatConfig;
|
|
1266
1265
|
/** When true (default), LLM classifies facts as `"project"` or `"global"` scope for promotion across projects. */
|
|
1267
1266
|
extractionScopeClassificationEnabled: boolean;
|
|
1267
|
+
subjectClassification: { enabled: boolean };
|
|
1268
|
+
subjectGuard: SubjectGuardMode;
|
|
1269
|
+
/** Min accessCount reuse signal for promotion candidates (issue #2372). Default 3. */
|
|
1270
|
+
promotionCandidates: { minAccessCount: number };
|
|
1268
1271
|
// Extraction judge (issue #376)
|
|
1269
1272
|
/** Enable the LLM-as-judge fact-worthiness gate on extracted facts. Default false (opt-in). */
|
|
1270
1273
|
extractionJudgeEnabled: boolean;
|
|
@@ -2804,6 +2807,8 @@ export interface MemoryFrontmatter extends SourceConnectorProvenance, OriginMeta
|
|
|
2804
2807
|
/** True when write-time classification ties this memory to its source connector's tools or commands. */
|
|
2805
2808
|
toolScoped?: true;
|
|
2806
2809
|
id: string;
|
|
2810
|
+
/** Whom this memory models (issue #2372). The promotion guard treats absent as "user" (fail closed). */
|
|
2811
|
+
subject?: MemorySubject;
|
|
2807
2812
|
category: MemoryCategory;
|
|
2808
2813
|
/** OKF v0.1 interop metadata (issue #1946). Inert: presentation only, never overrides `category`. */
|
|
2809
2814
|
type?: string;
|
|
@@ -2824,12 +2829,8 @@ export interface MemoryFrontmatter extends SourceConnectorProvenance, OriginMeta
|
|
|
2824
2829
|
/** Memory status: active (default), pending_review, rejected, quarantined, superseded, archived, or forgotten */
|
|
2825
2830
|
status?: MemoryStatus;
|
|
2826
2831
|
/**
|
|
2827
|
-
* Tombstone block marker (issue #1579)
|
|
2828
|
-
*
|
|
2829
|
-
* `status: "pending_review"` and this field set to the tombstone id — making
|
|
2830
|
-
* the block VISIBLE (rule 34: never a silent drop) rather than silently
|
|
2831
|
-
* discarding the extraction. Approving the memory through the review queue
|
|
2832
|
-
* emits a revocation that re-allows the content.
|
|
2832
|
+
* Tombstone block marker (issue #1579): persisted `pending_review` with this
|
|
2833
|
+
* set to the tombstone id — a VISIBLE block (rule 34); approval revokes it.
|
|
2833
2834
|
*/
|
|
2834
2835
|
blockedBy?: string;
|
|
2835
2836
|
/** Which tombstone tier matched (`exact`/`normalized`/`keyed`/`semantic`). */
|
|
@@ -3234,29 +3235,25 @@ export interface ExtractedFact {
|
|
|
3234
3235
|
*/
|
|
3235
3236
|
provenance?: "verified" | "unverified" | "none";
|
|
3236
3237
|
/**
|
|
3237
|
-
* Transient LLM
|
|
3238
|
-
*
|
|
3239
|
-
*
|
|
3240
|
-
* checklist §13). Absent on facts that have already passed the validator.
|
|
3238
|
+
* Transient LLM quote (issue #1575 PR 2): consumed by the post-parse
|
|
3239
|
+
* validator to build `sources`, stripped before persistence, never in
|
|
3240
|
+
* content-hash dedup (rule 23 / checklist §13).
|
|
3241
3241
|
*/
|
|
3242
3242
|
quote?: string;
|
|
3243
3243
|
/**
|
|
3244
|
-
* Transient requireSpans signal (
|
|
3245
|
-
*
|
|
3246
|
-
* `
|
|
3247
|
-
* in any source turn. Read by the persist path to route the fact to
|
|
3248
|
-
* `pending_review` instead of `active`. Stripped before persistence —
|
|
3249
|
-
* it never reaches frontmatter (chatgpt-codex-connector thread 4xB).
|
|
3244
|
+
* Transient requireSpans signal (#1575 PR 2): quote unlocatable while
|
|
3245
|
+
* `provenance.requireSpans` is on. Persist path routes the fact to
|
|
3246
|
+
* `pending_review`. Stripped before persistence — never reaches frontmatter.
|
|
3250
3247
|
*/
|
|
3251
3248
|
requireSpansPending?: boolean;
|
|
3252
3249
|
promptedByQuestion?: string;
|
|
3253
3250
|
/**
|
|
3254
|
-
*
|
|
3255
|
-
*
|
|
3256
|
-
* classifies each fact. Default is `"project"` when a coding context is
|
|
3257
|
-
* active, `"global"` when no coding context is present.
|
|
3251
|
+
* Project- vs global-scoped; emitted when `extractionScopeClassificationEnabled`.
|
|
3252
|
+
* Defaults to "project" with a coding context active, else "global".
|
|
3258
3253
|
*/
|
|
3259
3254
|
scope?: MemoryScope;
|
|
3255
|
+
/** Extractor-assigned subject, present only when subjectClassification.enabled (issue #2372). */
|
|
3256
|
+
subject?: MemorySubject;
|
|
3260
3257
|
/** Structured key-value attributes extracted from the content (e.g., product attributes, dates, quantities). */
|
|
3261
3258
|
structuredAttributes?: Record<string, string>;
|
|
3262
3259
|
/** When category is `procedure`, ordered steps with intents (persisted under procedures/). */
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
WRITE_FINGERPRINT_FIELDS,
|
|
10
10
|
buildWriteIdempotencyPayload,
|
|
11
11
|
composeMemoryEnvelope,
|
|
12
|
+
sealedWriteToLegacyArgs,
|
|
12
13
|
isSealedMemoryEnvelope,
|
|
13
14
|
type FingerprintScope,
|
|
14
15
|
type MemoryWriteInput,
|
|
@@ -198,6 +199,7 @@ test("registry and exempt list disjointly cover every MemoryWriteInput field", (
|
|
|
198
199
|
sourceConnector: "bee",
|
|
199
200
|
sourceReason: "r",
|
|
200
201
|
origin: "user",
|
|
202
|
+
subject: "user",
|
|
201
203
|
};
|
|
202
204
|
for (const key of Object.keys(populated)) {
|
|
203
205
|
assert.ok(classified.has(key), `field ${key} is not classified`);
|
|
@@ -682,3 +684,15 @@ test("structural fallback rejects prototype-inherited accessors (round 13)", ()
|
|
|
682
684
|
"prototype-inherited getter lookalike must be rejected",
|
|
683
685
|
);
|
|
684
686
|
});
|
|
687
|
+
|
|
688
|
+
test("sealedWriteToLegacyArgs always copies sourceConnector from the envelope", () => {
|
|
689
|
+
const envelope = composeMemoryEnvelope(
|
|
690
|
+
minimalInput({ sourceConnector: "chatgpt" }),
|
|
691
|
+
CTX,
|
|
692
|
+
);
|
|
693
|
+
const mapped = sealedWriteToLegacyArgs(envelope, { sourceConnector: "smuggled" });
|
|
694
|
+
assert.equal(mapped.options.sourceConnector, "chatgpt");
|
|
695
|
+
const empty = composeMemoryEnvelope(minimalInput(), CTX);
|
|
696
|
+
const cleared = sealedWriteToLegacyArgs(empty, { sourceConnector: "smuggled" });
|
|
697
|
+
assert.equal(cleared.options.sourceConnector, undefined);
|
|
698
|
+
});
|
package/src/write-envelope.ts
CHANGED
|
@@ -24,7 +24,8 @@
|
|
|
24
24
|
* the write call sites onto this module (see #1989 for the slicing).
|
|
25
25
|
*/
|
|
26
26
|
|
|
27
|
-
import
|
|
27
|
+
import { isMemorySubject } from "./memory-subject.js";
|
|
28
|
+
import type { MemoryCategory, MemorySubject } from "./types.js";
|
|
28
29
|
import { normalizeTags } from "./recall-tag-filter.js";
|
|
29
30
|
import { parseFlexibleIsoTimestamp } from "./utils/iso-timestamp.js";
|
|
30
31
|
import { assemblePersistedBody } from "./structured-attributes.js";
|
|
@@ -61,6 +62,8 @@ export interface MemoryWriteInput {
|
|
|
61
62
|
sourceConnector?: string;
|
|
62
63
|
/** Origin class stamped at creation time (issue #1955). */
|
|
63
64
|
origin?: string;
|
|
65
|
+
/** Whom the memory models (issue #2372): "user" or "agent". */
|
|
66
|
+
subject?: MemorySubject;
|
|
64
67
|
/** Human-readable provenance note. */
|
|
65
68
|
sourceReason?: string;
|
|
66
69
|
}
|
|
@@ -184,6 +187,7 @@ export interface SealedMemoryEnvelope {
|
|
|
184
187
|
readonly validAt: string | undefined;
|
|
185
188
|
readonly sourceConnector: string | undefined;
|
|
186
189
|
readonly origin: string | undefined;
|
|
190
|
+
readonly subject: MemorySubject | undefined;
|
|
187
191
|
readonly sourceReason: string | undefined;
|
|
188
192
|
readonly source: string;
|
|
189
193
|
/** ISO timestamp the envelope was composed (from ctx.now). */
|
|
@@ -430,6 +434,18 @@ export function composeMemoryEnvelope(
|
|
|
430
434
|
}
|
|
431
435
|
}
|
|
432
436
|
|
|
437
|
+
let subject: MemorySubject | undefined;
|
|
438
|
+
if (input.subject !== undefined) {
|
|
439
|
+
if (!isMemorySubject(input.subject)) {
|
|
440
|
+
hygiene.flag(
|
|
441
|
+
"subject",
|
|
442
|
+
`must be "user" or "agent" (got ${JSON.stringify(input.subject)}) — dropped`,
|
|
443
|
+
);
|
|
444
|
+
} else {
|
|
445
|
+
subject = input.subject;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
|
|
433
449
|
// validAt stays FATAL in salvage too: legacy writeMemory throws on an
|
|
434
450
|
// invalid validAt (normalizeMemoryWriteTimestamp), so salvage-dropping it
|
|
435
451
|
// would CHANGE behavior rather than preserve it.
|
|
@@ -465,11 +481,12 @@ export function composeMemoryEnvelope(
|
|
|
465
481
|
structuredAttributes: attributes?.canonical,
|
|
466
482
|
rawStructuredAttributes: attributes?.raw,
|
|
467
483
|
entityRef: normalizeOptionalString("entityRef", input.entityRef, hygiene),
|
|
484
|
+
origin: normalizeOptionalString("origin", input.origin, hygiene),
|
|
485
|
+
subject,
|
|
468
486
|
confidence,
|
|
469
487
|
ttl: normalizeOptionalString("ttl", input.ttl, hygiene),
|
|
470
488
|
validAt,
|
|
471
489
|
sourceConnector: normalizeOptionalString("sourceConnector", input.sourceConnector, hygiene),
|
|
472
|
-
origin: normalizeOptionalString("origin", input.origin, hygiene),
|
|
473
490
|
sourceReason: normalizeOptionalString("sourceReason", input.sourceReason, hygiene),
|
|
474
491
|
source: ctx.source.trim(),
|
|
475
492
|
composedAt: now.toISOString(),
|
|
@@ -656,8 +673,9 @@ export function sealedWriteToLegacyArgs(
|
|
|
656
673
|
// extras — a conditional spread let extras.sourceConnector smuggle
|
|
657
674
|
// unvalidated connector provenance past the sealed envelope when the
|
|
658
675
|
// envelope had none.
|
|
659
|
-
sourceConnector: envelope.sourceConnector,
|
|
660
676
|
origin: envelope.origin,
|
|
677
|
+
sourceConnector: envelope.sourceConnector,
|
|
678
|
+
subject: envelope.subject,
|
|
661
679
|
},
|
|
662
680
|
};
|
|
663
681
|
}
|
|
@@ -695,6 +713,9 @@ export const FINGERPRINT_EXEMPT_FIELDS = [
|
|
|
695
713
|
// Free-text provenance note; carries no identity.
|
|
696
714
|
// Origin is provenance metadata, not write identity (#1955).
|
|
697
715
|
"origin",
|
|
716
|
+
// Subject is derived classification metadata (#2372): two writes identical
|
|
717
|
+
// except subject are the same memory for dedup purposes.
|
|
718
|
+
"subject",
|
|
698
719
|
"sourceReason",
|
|
699
720
|
] as const satisfies readonly (keyof MemoryWriteInput)[];
|
|
700
721
|
|