@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,311 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
|
|
3
|
+
export type ReviewDeckChoice = "keep" | "prepare_fix" | "not_true";
|
|
4
|
+
export type ReviewDeckRisk = "reversible";
|
|
5
|
+
|
|
6
|
+
export interface ReviewDeckEvidence {
|
|
7
|
+
sourceMemoryId?: string;
|
|
8
|
+
sourceDate?: string;
|
|
9
|
+
excerpt?: string;
|
|
10
|
+
relation: "supports" | "conflicts" | "origin";
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface ReviewDeckItem {
|
|
14
|
+
schemaVersion: 1;
|
|
15
|
+
itemId: string;
|
|
16
|
+
source: "review";
|
|
17
|
+
sourceId: string;
|
|
18
|
+
memoryId?: string;
|
|
19
|
+
content: string;
|
|
20
|
+
category?: string;
|
|
21
|
+
lifecycleState?: string;
|
|
22
|
+
confidence?: number;
|
|
23
|
+
confidenceTier?: string;
|
|
24
|
+
reviewReason: string;
|
|
25
|
+
reviewReasonLabel: string;
|
|
26
|
+
supportCount: number;
|
|
27
|
+
provenance: readonly ReviewDeckEvidence[];
|
|
28
|
+
allowedChoices: readonly ReviewDeckChoice[];
|
|
29
|
+
choiceRisk: Readonly<Record<ReviewDeckChoice, ReviewDeckRisk | "unavailable">>;
|
|
30
|
+
namespace: string;
|
|
31
|
+
revision: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface ReviewDeckPage {
|
|
35
|
+
schemaVersion: 1;
|
|
36
|
+
items: readonly ReviewDeckItem[];
|
|
37
|
+
nextCursor?: string;
|
|
38
|
+
total: number;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export type ReviewDeckActionRequest =
|
|
42
|
+
| { schemaVersion: 1; itemId: string; revision: string; action: "keep" | "not_true"; idempotencyKey: string }
|
|
43
|
+
| { schemaVersion: 1; itemId: string; revision: string; action: "prepare_fix"; correctionText: string; idempotencyKey: string };
|
|
44
|
+
|
|
45
|
+
export interface ReviewDeckActionReceipt {
|
|
46
|
+
schemaVersion: 1;
|
|
47
|
+
receiptId: string;
|
|
48
|
+
itemId: string;
|
|
49
|
+
action: "keep" | "not_true" | "prepare_fix" | "undo";
|
|
50
|
+
outcome: "planned" | "applied" | "conflict" | "failed";
|
|
51
|
+
effect: string;
|
|
52
|
+
undoAvailable: boolean;
|
|
53
|
+
appliedRevision?: string;
|
|
54
|
+
correctionPlanId?: string;
|
|
55
|
+
correctionPreview?: unknown;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface ReviewDeckUndoRequest {
|
|
59
|
+
schemaVersion: 1;
|
|
60
|
+
receiptId: string;
|
|
61
|
+
expectedRevision: string;
|
|
62
|
+
idempotencyKey: string;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export interface ReviewDeckSourceRow {
|
|
66
|
+
itemId: string;
|
|
67
|
+
filePath: string;
|
|
68
|
+
fileContent: string;
|
|
69
|
+
revision: string;
|
|
70
|
+
content: string;
|
|
71
|
+
category?: string;
|
|
72
|
+
confidence?: number;
|
|
73
|
+
confidenceTier?: string;
|
|
74
|
+
reviewReason: string;
|
|
75
|
+
created: string;
|
|
76
|
+
source?: string;
|
|
77
|
+
blockedBy?: string;
|
|
78
|
+
lifecycleState?: string;
|
|
79
|
+
context?: string;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export interface ReviewDeckSnapshot {
|
|
83
|
+
corpusVersion: string;
|
|
84
|
+
total: number;
|
|
85
|
+
rows: readonly ReviewDeckSourceRow[];
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export interface ReviewDeckCursorScope {
|
|
89
|
+
principalDigest: string;
|
|
90
|
+
namespace: string;
|
|
91
|
+
filterDigest: string;
|
|
92
|
+
corpusVersion: string;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export class ReviewDeckCursorError extends Error {
|
|
96
|
+
constructor(message = "Invalid review deck cursor") {
|
|
97
|
+
super(message);
|
|
98
|
+
this.name = "ReviewDeckCursorError";
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const ALLOWED_CHOICES = ["keep", "prepare_fix", "not_true"] as const satisfies readonly ReviewDeckChoice[];
|
|
103
|
+
const REVERSIBLE_RISK = {
|
|
104
|
+
keep: "reversible",
|
|
105
|
+
prepare_fix: "reversible",
|
|
106
|
+
not_true: "reversible",
|
|
107
|
+
} as const satisfies Record<ReviewDeckChoice, ReviewDeckRisk>;
|
|
108
|
+
|
|
109
|
+
const REVIEW_REASON_LABELS: Record<string, string> = {
|
|
110
|
+
low_confidence: "Low confidence",
|
|
111
|
+
suggestion: "Suggested memory",
|
|
112
|
+
tombstone_blocked: "Blocked by a deletion",
|
|
113
|
+
contradiction: "Conflicts with another memory",
|
|
114
|
+
duplicate: "Possible duplicate",
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
const EXCERPT_LIMIT = 240;
|
|
118
|
+
|
|
119
|
+
export function computeReviewItemRevision(fileContent: string): string {
|
|
120
|
+
return `rv1:${createHash("sha256").update(fileContent).digest("hex")}`;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export function projectReviewDeckItem(row: ReviewDeckSourceRow, namespace: string): ReviewDeckItem {
|
|
124
|
+
const provenance = provenanceFromRow(row);
|
|
125
|
+
return {
|
|
126
|
+
schemaVersion: 1,
|
|
127
|
+
itemId: row.itemId,
|
|
128
|
+
source: "review",
|
|
129
|
+
sourceId: row.itemId,
|
|
130
|
+
memoryId: row.itemId,
|
|
131
|
+
content: row.content,
|
|
132
|
+
...(row.category !== undefined ? { category: row.category } : {}),
|
|
133
|
+
...(row.lifecycleState !== undefined ? { lifecycleState: row.lifecycleState } : {}),
|
|
134
|
+
...(row.confidence !== undefined ? { confidence: row.confidence } : {}),
|
|
135
|
+
...(row.confidenceTier !== undefined ? { confidenceTier: row.confidenceTier } : {}),
|
|
136
|
+
reviewReason: row.reviewReason,
|
|
137
|
+
reviewReasonLabel: reviewReasonLabel(row.reviewReason),
|
|
138
|
+
supportCount: provenance.filter((entry) => entry.relation === "supports").length,
|
|
139
|
+
provenance,
|
|
140
|
+
allowedChoices: ALLOWED_CHOICES,
|
|
141
|
+
choiceRisk: REVERSIBLE_RISK,
|
|
142
|
+
namespace,
|
|
143
|
+
revision: row.revision,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export function compareReviewDeckRows(a: ReviewDeckSourceRow, b: ReviewDeckSourceRow): number {
|
|
148
|
+
const aBlocked = a.blockedBy && a.blockedBy.length > 0 ? 0 : 1;
|
|
149
|
+
const bBlocked = b.blockedBy && b.blockedBy.length > 0 ? 0 : 1;
|
|
150
|
+
if (aBlocked !== bBlocked) return aBlocked - bBlocked;
|
|
151
|
+
const aConfidence = a.confidence ?? 0.5;
|
|
152
|
+
const bConfidence = b.confidence ?? 0.5;
|
|
153
|
+
if (aConfidence !== bConfidence) return aConfidence < bConfidence ? -1 : 1;
|
|
154
|
+
if (a.created !== b.created) return a.created < b.created ? -1 : 1;
|
|
155
|
+
if (a.itemId !== b.itemId) return a.itemId < b.itemId ? -1 : 1;
|
|
156
|
+
return 0;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export function encodeReviewDeckCursor(scope: ReviewDeckCursorScope, lastSortKey: string): string {
|
|
160
|
+
return Buffer.from(
|
|
161
|
+
JSON.stringify({
|
|
162
|
+
v: 1,
|
|
163
|
+
p: scope.principalDigest,
|
|
164
|
+
n: scope.namespace,
|
|
165
|
+
f: scope.filterDigest,
|
|
166
|
+
c: scope.corpusVersion,
|
|
167
|
+
k: lastSortKey,
|
|
168
|
+
}),
|
|
169
|
+
"utf8",
|
|
170
|
+
).toString("base64url");
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export function decodeReviewDeckCursor(cursor: string, scope: ReviewDeckCursorScope): string {
|
|
174
|
+
const payload = parseCursorPayload(cursor);
|
|
175
|
+
if (
|
|
176
|
+
payload.p !== scope.principalDigest
|
|
177
|
+
|| payload.n !== scope.namespace
|
|
178
|
+
|| payload.f !== scope.filterDigest
|
|
179
|
+
|| payload.c !== scope.corpusVersion
|
|
180
|
+
) {
|
|
181
|
+
throw new ReviewDeckCursorError("Review deck cursor scope mismatch");
|
|
182
|
+
}
|
|
183
|
+
return payload.k;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export function buildReviewDeckPage(
|
|
187
|
+
rows: readonly ReviewDeckSourceRow[],
|
|
188
|
+
opts: { scope: ReviewDeckCursorScope; cursor?: string; limit: number },
|
|
189
|
+
): ReviewDeckPage {
|
|
190
|
+
const sorted = [...rows].sort(compareReviewDeckRows);
|
|
191
|
+
const limit = Math.max(0, opts.limit);
|
|
192
|
+
let start = 0;
|
|
193
|
+
if (opts.cursor !== undefined) {
|
|
194
|
+
const lastSortKey = decodeReviewDeckCursor(opts.cursor, opts.scope);
|
|
195
|
+
start = sorted.findIndex((row) => reviewDeckSortKey(row) > lastSortKey);
|
|
196
|
+
if (start < 0) start = sorted.length;
|
|
197
|
+
}
|
|
198
|
+
const pageRows = limit === 0 ? [] : sorted.slice(start, start + limit);
|
|
199
|
+
const items = pageRows.map((row) => projectReviewDeckItem(row, opts.scope.namespace));
|
|
200
|
+
const consumed = start + pageRows.length;
|
|
201
|
+
const nextCursor =
|
|
202
|
+
pageRows.length > 0 && consumed < sorted.length
|
|
203
|
+
? encodeReviewDeckCursor(opts.scope, reviewDeckSortKey(pageRows[pageRows.length - 1]))
|
|
204
|
+
: undefined;
|
|
205
|
+
return {
|
|
206
|
+
schemaVersion: 1,
|
|
207
|
+
items,
|
|
208
|
+
total: sorted.length,
|
|
209
|
+
...(nextCursor !== undefined ? { nextCursor } : {}),
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
function reviewDeckSortKey(row: ReviewDeckSourceRow): string {
|
|
214
|
+
const blocked = row.blockedBy && row.blockedBy.length > 0 ? "0" : "1";
|
|
215
|
+
return `${blocked}\t${(row.confidence ?? 0.5).toFixed(6)}\t${row.created}\t${row.itemId}`;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
function reviewReasonLabel(reason: string): string {
|
|
219
|
+
const known = REVIEW_REASON_LABELS[reason];
|
|
220
|
+
if (known) return known;
|
|
221
|
+
const words = reason.split("_").filter((part) => part.length > 0);
|
|
222
|
+
if (words.length === 0) return "Review";
|
|
223
|
+
return words
|
|
224
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
|
|
225
|
+
.join(" ");
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
function provenanceFromRow(row: ReviewDeckSourceRow): ReviewDeckEvidence[] {
|
|
229
|
+
const fm = parseFrontmatterFields(row.fileContent);
|
|
230
|
+
const source = nonempty(row.source) ?? nonempty(fm.source);
|
|
231
|
+
const context = nonempty(row.context) ?? nonempty(fm.context);
|
|
232
|
+
const created = nonempty(row.created) ?? nonempty(fm.created);
|
|
233
|
+
const supportIds = idList(fm.supports);
|
|
234
|
+
const conflictIds = [...idList(fm.conflicts), ...idList(fm.contradicts)];
|
|
235
|
+
const relatedIds = idList(fm.relatedMemoryIds);
|
|
236
|
+
const relatedRelation = row.reviewReason === "contradiction" ? "conflicts" : "supports";
|
|
237
|
+
const provenance: ReviewDeckEvidence[] = [];
|
|
238
|
+
if (source !== undefined || context !== undefined) {
|
|
239
|
+
provenance.push({
|
|
240
|
+
relation: "origin",
|
|
241
|
+
...(created !== undefined ? { sourceDate: created } : {}),
|
|
242
|
+
excerpt: truncateExcerpt(context ?? source ?? ""),
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
for (const sourceMemoryId of supportIds) {
|
|
246
|
+
provenance.push({ relation: "supports", sourceMemoryId });
|
|
247
|
+
}
|
|
248
|
+
for (const sourceMemoryId of conflictIds) {
|
|
249
|
+
provenance.push({ relation: "conflicts", sourceMemoryId });
|
|
250
|
+
}
|
|
251
|
+
for (const sourceMemoryId of relatedIds) {
|
|
252
|
+
if (supportIds.includes(sourceMemoryId) || conflictIds.includes(sourceMemoryId)) continue;
|
|
253
|
+
provenance.push({ relation: relatedRelation, sourceMemoryId });
|
|
254
|
+
}
|
|
255
|
+
return provenance;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function parseFrontmatterFields(content: string): Record<string, string> {
|
|
259
|
+
if (!content.startsWith("---\n")) return {};
|
|
260
|
+
const end = content.indexOf("\n---", 4);
|
|
261
|
+
if (end === -1) return {};
|
|
262
|
+
const fields: Record<string, string> = {};
|
|
263
|
+
for (const line of content.slice(4, end).split("\n")) {
|
|
264
|
+
const colonIdx = line.indexOf(":");
|
|
265
|
+
if (colonIdx === -1) continue;
|
|
266
|
+
fields[line.slice(0, colonIdx).trim()] = line.slice(colonIdx + 1).trim();
|
|
267
|
+
}
|
|
268
|
+
return fields;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
function idList(value: string | undefined): string[] {
|
|
272
|
+
if (value === undefined || value.length === 0) return [];
|
|
273
|
+
return value
|
|
274
|
+
.replace(/^\[|\]$/g, "")
|
|
275
|
+
.split(",")
|
|
276
|
+
.map((part) => part.trim().replace(/^["']|["']$/g, ""))
|
|
277
|
+
.filter((part) => part.length > 0);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
function nonempty(value: string | undefined): string | undefined {
|
|
281
|
+
if (value === undefined) return undefined;
|
|
282
|
+
return value.trim().length > 0 ? value : undefined;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
function truncateExcerpt(value: string): string {
|
|
286
|
+
return value.length <= EXCERPT_LIMIT ? value : value.slice(0, EXCERPT_LIMIT);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
function parseCursorPayload(cursor: string): { v: 1; p: string; n: string; f: string; c: string; k: string } {
|
|
290
|
+
if (cursor.length === 0) throw new ReviewDeckCursorError("Malformed review deck cursor");
|
|
291
|
+
let parsed: unknown;
|
|
292
|
+
try {
|
|
293
|
+
parsed = JSON.parse(Buffer.from(cursor, "base64url").toString("utf8"));
|
|
294
|
+
} catch {
|
|
295
|
+
throw new ReviewDeckCursorError("Malformed review deck cursor");
|
|
296
|
+
}
|
|
297
|
+
if (!parsed || typeof parsed !== "object") throw new ReviewDeckCursorError("Malformed review deck cursor");
|
|
298
|
+
const record = parsed as Record<string, unknown>;
|
|
299
|
+
if (record.v !== 1) throw new ReviewDeckCursorError("Unsupported review deck cursor schema");
|
|
300
|
+
if (
|
|
301
|
+
typeof record.p !== "string"
|
|
302
|
+
|| typeof record.n !== "string"
|
|
303
|
+
|| typeof record.f !== "string"
|
|
304
|
+
|| typeof record.c !== "string"
|
|
305
|
+
|| typeof record.k !== "string"
|
|
306
|
+
|| record.k.length === 0
|
|
307
|
+
) {
|
|
308
|
+
throw new ReviewDeckCursorError("Malformed review deck cursor");
|
|
309
|
+
}
|
|
310
|
+
return { v: 1, p: record.p, n: record.n, f: record.f, c: record.c, k: record.k };
|
|
311
|
+
}
|
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
|
@@ -13,11 +13,8 @@ import {
|
|
|
13
13
|
} from "node:fs/promises";
|
|
14
14
|
import { appendFileSync, createReadStream, mkdirSync, readFileSync, statSync } from "node:fs";
|
|
15
15
|
import { createHash } from "node:crypto";
|
|
16
|
-
import {
|
|
17
|
-
|
|
18
|
-
computeLegacyContentHash,
|
|
19
|
-
normalizeContent,
|
|
20
|
-
} from "./content-hash.js";
|
|
16
|
+
import { computeLegacyContentHash, normalizeContent } from "./content-hash.js";
|
|
17
|
+
import { parseDriftProvenance, serializeDriftProvenance } from "./preferences/drift-types.js";
|
|
21
18
|
import { raceAbort } from "./abort-error.js";
|
|
22
19
|
import { checkCorpusReadAbort, type CorpusReadOptions } from "./corpus-read-cancellation.js";
|
|
23
20
|
import { selectArtifactMatches, type ArtifactSearchOptions } from "./artifact-search.js";
|
|
@@ -28,7 +25,6 @@ import { createMemorySnapshot } from "./memory-snapshot.js";
|
|
|
28
25
|
import { assertMemoryFrontmatterId, warnProjectionFallback } from "./storage-guards.js";
|
|
29
26
|
import { createTombstoneMigrationSourceContents } from "./storage/tombstone-migration-sources.js";
|
|
30
27
|
import { MemoryReadStore, readWindowedMemories, type WindowedMemoryReadOptions, type WindowedMemoryReadResult } from "./storage/memory-read-store.js";
|
|
31
|
-
import { hasSupersessionAudit } from "./storage/supersession-audit.js";
|
|
32
28
|
import { runCommittedInvalidation } from "./storage/committed-invalidation.js";
|
|
33
29
|
import { renderProfileWithLastUpdated, stripOkfProfileFrontmatter, withOkfProfileFrontmatter } from "./storage/profile-header.js";
|
|
34
30
|
import { parseQuestionFile as parseQuestionFileText } from "./storage/questions-file.js";
|
|
@@ -166,6 +162,7 @@ import type {
|
|
|
166
162
|
VerificationState,
|
|
167
163
|
PolicyClass,
|
|
168
164
|
MemoryStatus,
|
|
165
|
+
MemorySubject,
|
|
169
166
|
MemoryActionEvent,
|
|
170
167
|
MemoryLifecycleEvent,
|
|
171
168
|
MemoryLifecycleEventType,
|
|
@@ -326,6 +323,7 @@ function serializeFrontmatter(fm: MemoryFrontmatter): string {
|
|
|
326
323
|
if (fm.language) lines.push(`language: ${fm.language}`);
|
|
327
324
|
if (fm.type !== undefined) lines.push(`type: ${fm.type}`);
|
|
328
325
|
if (fm.origin) lines.push(`origin: ${/^[A-Za-z0-9:_.*-]+$/.test(fm.origin) ? fm.origin : JSON.stringify(fm.origin)}`);
|
|
326
|
+
if (fm.subject) lines.push(`subject: ${fm.subject}`);
|
|
329
327
|
if (fm.entityRef) lines.push(`entityRef: ${fm.entityRef}`);
|
|
330
328
|
if (fm.sourceConnector) {
|
|
331
329
|
// YAML-injection guard (review thread QMPsP): emit unquoted for
|
|
@@ -406,6 +404,7 @@ function serializeFrontmatter(fm: MemoryFrontmatter): string {
|
|
|
406
404
|
assertMemoryWorthCounter("mw_fail", fm.mw_fail);
|
|
407
405
|
lines.push(`mw_fail: ${fm.mw_fail}`);
|
|
408
406
|
}
|
|
407
|
+
lines.push(...serializeDriftProvenance(fm));
|
|
409
408
|
// Importance scoring
|
|
410
409
|
if (fm.importance) {
|
|
411
410
|
lines.push(`importanceScore: ${fm.importance.score}`);
|
|
@@ -871,6 +870,7 @@ export function parseFrontmatter(raw: string): { frontmatter: MemoryFrontmatter;
|
|
|
871
870
|
tags,
|
|
872
871
|
entityRef: fm.entityRef || undefined,
|
|
873
872
|
origin: fm.origin !== undefined ? parseOriginClass(decodeYamlScalar(fm.origin)) : undefined,
|
|
873
|
+
subject: fm.subject === "user" || fm.subject === "agent" ? fm.subject : undefined,
|
|
874
874
|
sourceConnector: fm.sourceConnector ? decodeYamlScalar(fm.sourceConnector) || undefined : undefined,
|
|
875
875
|
toolScoped: fm.toolScoped === "true" ? true : undefined,
|
|
876
876
|
supersedes: fm.supersedes || undefined,
|
|
@@ -916,6 +916,7 @@ export function parseFrontmatter(raw: string): { frontmatter: MemoryFrontmatter;
|
|
|
916
916
|
// Memory Worth counters (issue #560)
|
|
917
917
|
mw_success,
|
|
918
918
|
mw_fail,
|
|
919
|
+
...parseDriftProvenance(fm),
|
|
919
920
|
// Importance scoring
|
|
920
921
|
importance,
|
|
921
922
|
// Chunking
|
|
@@ -1739,6 +1740,7 @@ export interface WriteMemoryOptions {
|
|
|
1739
1740
|
origin?: string;
|
|
1740
1741
|
sourceConnector?: string;
|
|
1741
1742
|
toolScoped?: true;
|
|
1743
|
+
subject?: MemorySubject;
|
|
1742
1744
|
}
|
|
1743
1745
|
|
|
1744
1746
|
/**
|
|
@@ -1747,7 +1749,7 @@ export interface WriteMemoryOptions {
|
|
|
1747
1749
|
*/
|
|
1748
1750
|
export type SealedWriteExtras = Omit<
|
|
1749
1751
|
WriteMemoryOptions,
|
|
1750
|
-
"confidence" | "tags" | "entityRef" | "source" | "expiresAt" | "validAt" | "structuredAttributes" | "sourceConnector" | "origin"
|
|
1752
|
+
"confidence" | "tags" | "entityRef" | "source" | "expiresAt" | "validAt" | "structuredAttributes" | "sourceConnector" | "origin" | "subject"
|
|
1751
1753
|
>;
|
|
1752
1754
|
|
|
1753
1755
|
export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
@@ -3791,7 +3793,7 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
3791
3793
|
fm.sourceConnector = options.sourceConnector;
|
|
3792
3794
|
}
|
|
3793
3795
|
if (options.origin !== undefined) fm.origin = parseOriginClass(options.origin);
|
|
3794
|
-
|
|
3796
|
+
if (options.subject !== undefined) fm.subject = options.subject;
|
|
3795
3797
|
// Assemble the persisted body (attribute-suffix enrichment + combined
|
|
3796
3798
|
// sanitize) via the SHARED helper — the sealed-envelope composer uses the
|
|
3797
3799
|
// 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
|
+
}
|