@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,556 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Action-site failure gate (issue #2382, slice 1 — core contract).
|
|
3
|
+
*
|
|
4
|
+
* The H6 study (#1963) measured that a failure memory delivered in the prompt
|
|
5
|
+
* preamble barely changes behaviour, while the same memory delivered at the
|
|
6
|
+
* moment the agent proposes the matched action removes the repeated failure.
|
|
7
|
+
* This module productionises that delivery point: `ActionGateService` wraps the
|
|
8
|
+
* experimental `PreActionFailureGate` primitive, adds failure-class memory
|
|
9
|
+
* candidates, a per-turn budget, cross-channel suppression, and telemetry.
|
|
10
|
+
*
|
|
11
|
+
* Scope, per the study's honest limit: the gate removes a known failure mode.
|
|
12
|
+
* It does not improve task completion. It is advisory only — it never blocks an
|
|
13
|
+
* action, never outruns its deadline, and fails open on every error path.
|
|
14
|
+
*/
|
|
15
|
+
import type { ActionIntent, ActionStrategyId } from "../causal-trajectory.js";
|
|
16
|
+
import { coerceBool, coerceNumber } from "../connectors/coerce.js";
|
|
17
|
+
import type { CodingContext, MemoryFile } from "../types.js";
|
|
18
|
+
import {
|
|
19
|
+
PRE_ACTION_GATE_DEFAULT_TIMEOUT_MS,
|
|
20
|
+
type PreActionFailureGate,
|
|
21
|
+
normalizeActionIntent,
|
|
22
|
+
sanitizePayloadString,
|
|
23
|
+
} from "./pre-action-gate.js";
|
|
24
|
+
|
|
25
|
+
export const ACTION_GATE_DEFAULT_MAX_ADVISORIES_PER_TURN = 3;
|
|
26
|
+
/** Bound on a single advisory payload, above the primitive's citation bound. */
|
|
27
|
+
const MAX_ADVISORY_CHARS = 400;
|
|
28
|
+
/** Bounded lexical matching: terms considered from one proposed action. */
|
|
29
|
+
const MAX_ACTION_TERMS = 24;
|
|
30
|
+
const MIN_TERM_CHARS = 3;
|
|
31
|
+
/** Fraction of action terms a failure memory must mention to be a candidate. */
|
|
32
|
+
const MIN_TERM_OVERLAP_RATIO = 0.6;
|
|
33
|
+
/** Sessions tracked for suppression before the oldest is evicted. */
|
|
34
|
+
const MAX_TRACKED_SESSIONS = 200;
|
|
35
|
+
/** Memory ids remembered per session for cross-channel suppression. */
|
|
36
|
+
const MAX_TRACKED_IDS_PER_SESSION = 200;
|
|
37
|
+
|
|
38
|
+
export interface ActionGateConfig {
|
|
39
|
+
/**
|
|
40
|
+
* Master gate. Default `false`: when disabled no lookup, no matching, and no
|
|
41
|
+
* suppression bookkeeping runs on any path.
|
|
42
|
+
*/
|
|
43
|
+
enabled: boolean;
|
|
44
|
+
/** Hard latency cap for a whole gate evaluation. Overrun fails open. */
|
|
45
|
+
timeoutMs: number;
|
|
46
|
+
/** Advisories injected per turn. `0` disables injection and all lookups. */
|
|
47
|
+
maxAdvisoriesPerTurn: number;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export const ACTION_GATE_DEFAULTS: ActionGateConfig = {
|
|
51
|
+
enabled: false,
|
|
52
|
+
timeoutMs: PRE_ACTION_GATE_DEFAULT_TIMEOUT_MS,
|
|
53
|
+
maxAdvisoriesPerTurn: ACTION_GATE_DEFAULT_MAX_ADVISORIES_PER_TURN,
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export function parseActionGateConfig(raw: unknown): ActionGateConfig {
|
|
57
|
+
if (raw !== undefined && (raw === null || typeof raw !== "object" || Array.isArray(raw))) {
|
|
58
|
+
throw new Error(
|
|
59
|
+
`actionGate must be an object (got ${JSON.stringify(raw)}). Use actionGate: { enabled: true } to opt in.`
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
const block = (raw ?? {}) as Record<string, unknown>;
|
|
63
|
+
const rawEnabled = block.enabled;
|
|
64
|
+
let enabled = ACTION_GATE_DEFAULTS.enabled;
|
|
65
|
+
if (rawEnabled !== undefined) {
|
|
66
|
+
const coerced = coerceBool(rawEnabled);
|
|
67
|
+
if (coerced === undefined) {
|
|
68
|
+
throw new Error(
|
|
69
|
+
`actionGate.enabled must be a boolean or one of "true"/"false"/"1"/"0"/"yes"/"no"/"on"/"off" (got ${JSON.stringify(rawEnabled)}).`
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
enabled = coerced;
|
|
73
|
+
}
|
|
74
|
+
const rawTimeout = coerceNumber(block.timeoutMs);
|
|
75
|
+
const timeoutMs =
|
|
76
|
+
rawTimeout !== undefined && Number.isFinite(rawTimeout)
|
|
77
|
+
? Math.min(5000, Math.max(1, Math.floor(rawTimeout)))
|
|
78
|
+
: ACTION_GATE_DEFAULTS.timeoutMs;
|
|
79
|
+
const rawMax = coerceNumber(block.maxAdvisoriesPerTurn);
|
|
80
|
+
// Zero-limit semantics are a compatibility contract: `0` stays `0`.
|
|
81
|
+
const maxAdvisoriesPerTurn =
|
|
82
|
+
rawMax !== undefined && Number.isFinite(rawMax)
|
|
83
|
+
? Math.min(20, Math.max(0, Math.floor(rawMax)))
|
|
84
|
+
: ACTION_GATE_DEFAULTS.maxAdvisoriesPerTurn;
|
|
85
|
+
return { enabled, timeoutMs, maxAdvisoriesPerTurn };
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export type ActionGateStatus = "DISABLED" | "NO_MATCH" | "MATCH_WARN" | "ERROR_FAIL_OPEN";
|
|
89
|
+
|
|
90
|
+
export interface ActionGateRequest {
|
|
91
|
+
sessionKey: string;
|
|
92
|
+
/** Turn identity: the per-turn budget and dedupe reset when this changes. */
|
|
93
|
+
turnId: string;
|
|
94
|
+
strategyId: ActionStrategyId;
|
|
95
|
+
intent: ActionIntent;
|
|
96
|
+
codingContext: CodingContext;
|
|
97
|
+
/** Memory directory ALREADY resolved for the caller's readable namespace. */
|
|
98
|
+
memoryDir: string;
|
|
99
|
+
/** Resolved readable namespace, passed verbatim to candidate sources. */
|
|
100
|
+
namespace?: string;
|
|
101
|
+
causalTrajectoryStoreDir?: string;
|
|
102
|
+
signal?: AbortSignal;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export interface ActionGateAdvisory {
|
|
106
|
+
/** Trajectory id or memory id — the unit of dedupe and suppression. */
|
|
107
|
+
memoryId: string;
|
|
108
|
+
sourceId: string;
|
|
109
|
+
text: string;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export interface ActionGateDecision {
|
|
113
|
+
status: ActionGateStatus;
|
|
114
|
+
advisories: ActionGateAdvisory[];
|
|
115
|
+
/** Candidates withheld: already delivered this turn/session, or over budget. */
|
|
116
|
+
suppressedIds: string[];
|
|
117
|
+
/** Source failures, kept distinct from "no candidates" (rule 22). */
|
|
118
|
+
degradations: string[];
|
|
119
|
+
fingerprint?: string;
|
|
120
|
+
reason?: string;
|
|
121
|
+
latencyMs: number;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export interface ActionGateCandidate {
|
|
125
|
+
memoryId: string;
|
|
126
|
+
advisoryText: string;
|
|
127
|
+
/** Deterministic ranking key; higher wins, ties break on `memoryId`. */
|
|
128
|
+
score?: number;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export interface ActionGateCandidateQuery {
|
|
132
|
+
sessionKey: string;
|
|
133
|
+
fingerprint: string;
|
|
134
|
+
/** Normalized, deduplicated lexical terms describing the proposed action. */
|
|
135
|
+
actionTerms: string[];
|
|
136
|
+
strategyId: ActionStrategyId;
|
|
137
|
+
intent: ActionIntent;
|
|
138
|
+
codingContext: CodingContext;
|
|
139
|
+
memoryDir: string;
|
|
140
|
+
namespace?: string;
|
|
141
|
+
causalTrajectoryStoreDir?: string;
|
|
142
|
+
signal?: AbortSignal;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export type ActionGateSourceResult = { ok: true; candidates: ActionGateCandidate[] } | { ok: false; reason: string };
|
|
146
|
+
|
|
147
|
+
export interface ActionGateCandidateSource {
|
|
148
|
+
readonly id: string;
|
|
149
|
+
find(query: ActionGateCandidateQuery): Promise<ActionGateSourceResult>;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export interface ActionGateAuditRecord {
|
|
153
|
+
ts: string;
|
|
154
|
+
sessionKey: string;
|
|
155
|
+
turnId: string;
|
|
156
|
+
status: ActionGateStatus;
|
|
157
|
+
latencyMs: number;
|
|
158
|
+
fingerprint?: string;
|
|
159
|
+
deliveredIds: string[];
|
|
160
|
+
suppressedIds: string[];
|
|
161
|
+
degradations: string[];
|
|
162
|
+
reason?: string;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export type ActionGateAuditSink = (record: ActionGateAuditRecord) => void | Promise<void>;
|
|
166
|
+
|
|
167
|
+
export interface ActionGateServiceDependencies {
|
|
168
|
+
sources?: ActionGateCandidateSource[];
|
|
169
|
+
audit?: ActionGateAuditSink;
|
|
170
|
+
clock?: () => number;
|
|
171
|
+
now?: () => Date;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Deterministic, local term extraction from a proposed action. No LLM and no
|
|
176
|
+
* I/O: this runs in the hot path ahead of the tool call.
|
|
177
|
+
*/
|
|
178
|
+
export function actionTermsFor(intent: ActionIntent): string[] {
|
|
179
|
+
const raw =
|
|
180
|
+
intent.kind === "command"
|
|
181
|
+
? [intent.command, ...(intent.args ?? [])]
|
|
182
|
+
: [intent.filePath, intent.editKind, intent.symbol ?? "", intent.range ?? ""];
|
|
183
|
+
const terms: string[] = [];
|
|
184
|
+
const seen = new Set<string>();
|
|
185
|
+
for (const piece of raw) {
|
|
186
|
+
for (const token of sanitizePayloadString(piece ?? "")
|
|
187
|
+
.toLowerCase()
|
|
188
|
+
.split(/[^a-z0-9._-]+/)) {
|
|
189
|
+
const term = token.replace(/^[._-]+|[._-]+$/g, "");
|
|
190
|
+
if (term.length < MIN_TERM_CHARS || seen.has(term)) continue;
|
|
191
|
+
seen.add(term);
|
|
192
|
+
terms.push(term);
|
|
193
|
+
if (terms.length >= MAX_ACTION_TERMS) return terms;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return terms;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Failure-class markers on stored memories, read from frontmatter only so the
|
|
201
|
+
* decision stays deterministic: explicit corrections, procedures flagged for
|
|
202
|
+
* repair by library maintenance, and memories whose recorded outcomes are
|
|
203
|
+
* failure-dominant.
|
|
204
|
+
*/
|
|
205
|
+
export function isFailureClassMemory(memory: MemoryFile): boolean {
|
|
206
|
+
const fm = memory.frontmatter;
|
|
207
|
+
if (fm.status !== undefined && fm.status !== "active") return false;
|
|
208
|
+
if (fm.category === "correction") return true;
|
|
209
|
+
if (fm.structuredAttributes?.needsRepair === "true") return true;
|
|
210
|
+
const failures = typeof fm.mw_fail === "number" ? fm.mw_fail : 0;
|
|
211
|
+
const successes = typeof fm.mw_success === "number" ? fm.mw_success : 0;
|
|
212
|
+
return failures > 0 && failures > successes;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
export interface FailureMemorySourceDependencies {
|
|
216
|
+
/**
|
|
217
|
+
* Namespace-scoped listing of candidate memories. Callers wire this to a
|
|
218
|
+
* storage read for the SAME namespace the gate request resolved, so a
|
|
219
|
+
* principal can never receive another principal's advisories.
|
|
220
|
+
*/
|
|
221
|
+
listMemories: (options: {
|
|
222
|
+
namespace?: string;
|
|
223
|
+
memoryDir: string;
|
|
224
|
+
signal?: AbortSignal;
|
|
225
|
+
}) => Promise<MemoryFile[]>;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Failure-class memory candidates, matched by bounded lexical overlap against
|
|
230
|
+
* the proposed action's terms. Deterministic and local by construction.
|
|
231
|
+
*/
|
|
232
|
+
export function createFailureMemoryCandidateSource(deps: FailureMemorySourceDependencies): ActionGateCandidateSource {
|
|
233
|
+
return {
|
|
234
|
+
id: "failure-memory",
|
|
235
|
+
async find(query) {
|
|
236
|
+
if (query.actionTerms.length === 0) return { ok: true, candidates: [] };
|
|
237
|
+
let memories: MemoryFile[];
|
|
238
|
+
try {
|
|
239
|
+
memories = await deps.listMemories({
|
|
240
|
+
namespace: query.namespace,
|
|
241
|
+
memoryDir: query.memoryDir,
|
|
242
|
+
signal: query.signal,
|
|
243
|
+
});
|
|
244
|
+
} catch (error) {
|
|
245
|
+
return { ok: false, reason: error instanceof Error ? error.message : String(error) };
|
|
246
|
+
}
|
|
247
|
+
const required = Math.max(1, Math.ceil(query.actionTerms.length * MIN_TERM_OVERLAP_RATIO));
|
|
248
|
+
const candidates: ActionGateCandidate[] = [];
|
|
249
|
+
for (const memory of memories) {
|
|
250
|
+
if (!isFailureClassMemory(memory)) continue;
|
|
251
|
+
const haystack = `${memory.content} ${(memory.frontmatter.tags ?? []).join(" ")}`.toLowerCase();
|
|
252
|
+
let hits = 0;
|
|
253
|
+
for (const term of query.actionTerms) if (haystack.includes(term)) hits += 1;
|
|
254
|
+
if (hits < required) continue;
|
|
255
|
+
candidates.push({
|
|
256
|
+
memoryId: memory.frontmatter.id,
|
|
257
|
+
score: hits,
|
|
258
|
+
advisoryText: `[ActionGate] A stored failure memory matches this action: "${memory.content}".`,
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
candidates.sort((left, right) => {
|
|
262
|
+
const byScore = (right.score ?? 0) - (left.score ?? 0);
|
|
263
|
+
return byScore !== 0 ? byScore : left.memoryId.localeCompare(right.memoryId);
|
|
264
|
+
});
|
|
265
|
+
return { ok: true, candidates };
|
|
266
|
+
},
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Candidate source over recorded causal-trajectory failures, delegating the
|
|
272
|
+
* fingerprint match to the existing `PreActionFailureGate` primitive.
|
|
273
|
+
*/
|
|
274
|
+
export function createTrajectoryCandidateSource(gate: PreActionFailureGate): ActionGateCandidateSource {
|
|
275
|
+
return {
|
|
276
|
+
id: "causal-trajectory",
|
|
277
|
+
async find(query) {
|
|
278
|
+
const result = await gate.evaluate({
|
|
279
|
+
sessionKey: query.sessionKey,
|
|
280
|
+
strategyId: query.strategyId,
|
|
281
|
+
intent: query.intent,
|
|
282
|
+
codingContext: query.codingContext,
|
|
283
|
+
memoryDir: query.memoryDir,
|
|
284
|
+
causalTrajectoryStoreDir: query.causalTrajectoryStoreDir,
|
|
285
|
+
signal: query.signal,
|
|
286
|
+
});
|
|
287
|
+
if (result.status === "ERROR_FAIL_OPEN") {
|
|
288
|
+
return { ok: false, reason: result.reason ?? "pre-action gate failed open" };
|
|
289
|
+
}
|
|
290
|
+
if (result.status !== "MATCH_WARN" || !result.matchedTrajectoryId || !result.advisoryText) {
|
|
291
|
+
return { ok: true, candidates: [] };
|
|
292
|
+
}
|
|
293
|
+
return {
|
|
294
|
+
ok: true,
|
|
295
|
+
candidates: [
|
|
296
|
+
{
|
|
297
|
+
memoryId: result.matchedTrajectoryId,
|
|
298
|
+
// Trajectory matches are exact fingerprint hits: rank above lexical ones.
|
|
299
|
+
score: Number.MAX_SAFE_INTEGER,
|
|
300
|
+
advisoryText: result.advisoryText,
|
|
301
|
+
},
|
|
302
|
+
],
|
|
303
|
+
};
|
|
304
|
+
},
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
interface SessionSuppression {
|
|
309
|
+
turnId: string;
|
|
310
|
+
/** Ids the gate delivered during `turnId`. */
|
|
311
|
+
deliveredThisTurn: Set<string>;
|
|
312
|
+
/** Ids the gate delivered anywhere in the session; turn-start must skip them. */
|
|
313
|
+
deliveredByGate: Set<string>;
|
|
314
|
+
/** Ids turn-start injection already delivered; the gate must skip them. */
|
|
315
|
+
deliveredByTurnStart: Set<string>;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Advisory gate evaluated immediately before an agent action.
|
|
320
|
+
*
|
|
321
|
+
* Delivery is bounded three ways: a hard deadline, `maxAdvisoriesPerTurn`, and
|
|
322
|
+
* dedupe per memory per turn. Cross-channel suppression keeps one memory from
|
|
323
|
+
* arriving twice in a session — once here and once from turn-start recall.
|
|
324
|
+
*/
|
|
325
|
+
export class ActionGateService {
|
|
326
|
+
private readonly config: ActionGateConfig;
|
|
327
|
+
private readonly sources: ActionGateCandidateSource[];
|
|
328
|
+
private readonly audit?: ActionGateAuditSink;
|
|
329
|
+
private readonly clock: () => number;
|
|
330
|
+
private readonly now: () => Date;
|
|
331
|
+
private readonly sessions = new Map<string, SessionSuppression>();
|
|
332
|
+
|
|
333
|
+
constructor(config: ActionGateConfig, deps: ActionGateServiceDependencies = {}) {
|
|
334
|
+
this.config = config;
|
|
335
|
+
this.sources = deps.sources ?? [];
|
|
336
|
+
this.audit = deps.audit;
|
|
337
|
+
this.clock = deps.clock ?? Date.now;
|
|
338
|
+
this.now = deps.now ?? (() => new Date());
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Memory ids the gate already delivered in this session. Turn-start recall
|
|
343
|
+
* filters these out before its own cap, honouring the filter-then-cap order.
|
|
344
|
+
*/
|
|
345
|
+
public suppressedForTurnStart(sessionKey: string): string[] {
|
|
346
|
+
if (!this.config.enabled) return [];
|
|
347
|
+
return [...(this.sessions.get(sessionKey)?.deliveredByGate ?? [])];
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/** Record ids turn-start recall injected, so the gate will not repeat them. */
|
|
351
|
+
public noteTurnStartDelivery(sessionKey: string, memoryIds: readonly string[]): void {
|
|
352
|
+
if (!this.config.enabled || memoryIds.length === 0) return;
|
|
353
|
+
const state = this.sessionState(sessionKey, undefined);
|
|
354
|
+
for (const id of memoryIds) this.addTracked(state.deliveredByTurnStart, id);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
public resetSession(sessionKey: string): void {
|
|
358
|
+
this.sessions.delete(sessionKey);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
async evaluate(request: ActionGateRequest): Promise<ActionGateDecision> {
|
|
362
|
+
const startedAt = this.clock();
|
|
363
|
+
if (!this.config.enabled) {
|
|
364
|
+
return {
|
|
365
|
+
status: "DISABLED",
|
|
366
|
+
advisories: [],
|
|
367
|
+
suppressedIds: [],
|
|
368
|
+
degradations: [],
|
|
369
|
+
reason: "actionGate.enabled is false",
|
|
370
|
+
latencyMs: 0,
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
if (this.config.maxAdvisoriesPerTurn === 0) {
|
|
374
|
+
return this.finish(request, startedAt, {
|
|
375
|
+
status: "DISABLED",
|
|
376
|
+
advisories: [],
|
|
377
|
+
suppressedIds: [],
|
|
378
|
+
degradations: [],
|
|
379
|
+
reason: "actionGate.maxAdvisoriesPerTurn is 0",
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
let fingerprint: string;
|
|
384
|
+
try {
|
|
385
|
+
fingerprint = normalizeActionIntent(request.intent, request.strategyId, request.codingContext).fingerprint;
|
|
386
|
+
} catch (error) {
|
|
387
|
+
return this.finish(request, startedAt, {
|
|
388
|
+
status: "ERROR_FAIL_OPEN",
|
|
389
|
+
advisories: [],
|
|
390
|
+
suppressedIds: [],
|
|
391
|
+
degradations: [],
|
|
392
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
const deadline = startedAt + this.config.timeoutMs;
|
|
397
|
+
const collected = await this.collect(request, fingerprint, deadline);
|
|
398
|
+
const state = this.sessionState(request.sessionKey, request.turnId);
|
|
399
|
+
const advisories: ActionGateAdvisory[] = [];
|
|
400
|
+
const suppressedIds: string[] = [];
|
|
401
|
+
for (const { sourceId, candidate } of collected.candidates) {
|
|
402
|
+
if (state.deliveredThisTurn.has(candidate.memoryId) || state.deliveredByTurnStart.has(candidate.memoryId)) {
|
|
403
|
+
suppressedIds.push(candidate.memoryId);
|
|
404
|
+
continue;
|
|
405
|
+
}
|
|
406
|
+
if (advisories.length >= this.config.maxAdvisoriesPerTurn) {
|
|
407
|
+
suppressedIds.push(candidate.memoryId);
|
|
408
|
+
continue;
|
|
409
|
+
}
|
|
410
|
+
advisories.push({
|
|
411
|
+
memoryId: candidate.memoryId,
|
|
412
|
+
sourceId,
|
|
413
|
+
text: sanitizePayloadString(candidate.advisoryText).replace(/\s+/g, " ").slice(0, MAX_ADVISORY_CHARS),
|
|
414
|
+
});
|
|
415
|
+
this.addTracked(state.deliveredThisTurn, candidate.memoryId);
|
|
416
|
+
this.addTracked(state.deliveredByGate, candidate.memoryId);
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
const status: ActionGateStatus =
|
|
420
|
+
advisories.length > 0 ? "MATCH_WARN" : collected.degradations.length > 0 ? "ERROR_FAIL_OPEN" : "NO_MATCH";
|
|
421
|
+
return this.finish(request, startedAt, {
|
|
422
|
+
status,
|
|
423
|
+
advisories,
|
|
424
|
+
suppressedIds,
|
|
425
|
+
degradations: collected.degradations,
|
|
426
|
+
fingerprint,
|
|
427
|
+
reason: status === "ERROR_FAIL_OPEN" ? collected.degradations[0] : undefined,
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
private async collect(
|
|
432
|
+
request: ActionGateRequest,
|
|
433
|
+
fingerprint: string,
|
|
434
|
+
deadline: number
|
|
435
|
+
): Promise<{
|
|
436
|
+
candidates: Array<{ sourceId: string; candidate: ActionGateCandidate }>;
|
|
437
|
+
degradations: string[];
|
|
438
|
+
}> {
|
|
439
|
+
if (this.sources.length === 0) return { candidates: [], degradations: [] };
|
|
440
|
+
const timeoutAbort = new AbortController();
|
|
441
|
+
const signal = request.signal
|
|
442
|
+
? AbortSignal.any([request.signal, timeoutAbort.signal])
|
|
443
|
+
: timeoutAbort.signal;
|
|
444
|
+
const query: ActionGateCandidateQuery = {
|
|
445
|
+
sessionKey: request.sessionKey,
|
|
446
|
+
fingerprint,
|
|
447
|
+
actionTerms: actionTermsFor(request.intent),
|
|
448
|
+
strategyId: request.strategyId,
|
|
449
|
+
intent: request.intent,
|
|
450
|
+
codingContext: request.codingContext,
|
|
451
|
+
memoryDir: request.memoryDir,
|
|
452
|
+
namespace: request.namespace,
|
|
453
|
+
causalTrajectoryStoreDir: request.causalTrajectoryStoreDir,
|
|
454
|
+
signal,
|
|
455
|
+
};
|
|
456
|
+
const remaining = Math.max(1, deadline - this.clock());
|
|
457
|
+
let onTimeout!: (value: ActionGateSourceResult) => void;
|
|
458
|
+
const timeoutResult = new Promise<ActionGateSourceResult>((resolve) => {
|
|
459
|
+
onTimeout = resolve;
|
|
460
|
+
});
|
|
461
|
+
const timer = setTimeout(() => {
|
|
462
|
+
timeoutAbort.abort();
|
|
463
|
+
onTimeout({ ok: false, reason: `action gate timed out after ${this.config.timeoutMs}ms` });
|
|
464
|
+
}, remaining);
|
|
465
|
+
try {
|
|
466
|
+
const settled = await Promise.all(
|
|
467
|
+
this.sources.map(async (source) => {
|
|
468
|
+
let result: ActionGateSourceResult;
|
|
469
|
+
try {
|
|
470
|
+
result = await Promise.race([source.find(query), timeoutResult]);
|
|
471
|
+
} catch (error) {
|
|
472
|
+
result = { ok: false, reason: error instanceof Error ? error.message : String(error) };
|
|
473
|
+
}
|
|
474
|
+
return { source, result };
|
|
475
|
+
})
|
|
476
|
+
);
|
|
477
|
+
const candidates: Array<{ sourceId: string; candidate: ActionGateCandidate }> = [];
|
|
478
|
+
const degradations: string[] = [];
|
|
479
|
+
for (const { source, result } of settled) {
|
|
480
|
+
if (!result.ok) {
|
|
481
|
+
degradations.push(`${source.id}: ${result.reason}`);
|
|
482
|
+
continue;
|
|
483
|
+
}
|
|
484
|
+
for (const candidate of result.candidates) candidates.push({ sourceId: source.id, candidate });
|
|
485
|
+
}
|
|
486
|
+
candidates.sort((left, right) => {
|
|
487
|
+
const byScore = (right.candidate.score ?? 0) - (left.candidate.score ?? 0);
|
|
488
|
+
if (byScore !== 0) return byScore;
|
|
489
|
+
const bySource = left.sourceId.localeCompare(right.sourceId);
|
|
490
|
+
return bySource !== 0 ? bySource : left.candidate.memoryId.localeCompare(right.candidate.memoryId);
|
|
491
|
+
});
|
|
492
|
+
return { candidates, degradations };
|
|
493
|
+
} finally {
|
|
494
|
+
clearTimeout(timer);
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
private finish(
|
|
499
|
+
request: ActionGateRequest,
|
|
500
|
+
startedAt: number,
|
|
501
|
+
decision: Omit<ActionGateDecision, "latencyMs">
|
|
502
|
+
): ActionGateDecision {
|
|
503
|
+
const latencyMs = Math.max(0, this.clock() - startedAt);
|
|
504
|
+
const result: ActionGateDecision = { ...decision, latencyMs };
|
|
505
|
+
if (this.audit) {
|
|
506
|
+
const record: ActionGateAuditRecord = {
|
|
507
|
+
ts: this.now().toISOString(),
|
|
508
|
+
sessionKey: request.sessionKey,
|
|
509
|
+
turnId: request.turnId,
|
|
510
|
+
status: result.status,
|
|
511
|
+
latencyMs,
|
|
512
|
+
fingerprint: result.fingerprint,
|
|
513
|
+
deliveredIds: result.advisories.map((advisory) => advisory.memoryId),
|
|
514
|
+
suppressedIds: result.suppressedIds,
|
|
515
|
+
degradations: result.degradations,
|
|
516
|
+
reason: result.reason,
|
|
517
|
+
};
|
|
518
|
+
// Telemetry must never break the action it observes.
|
|
519
|
+
void Promise.resolve()
|
|
520
|
+
.then(() => this.audit?.(record))
|
|
521
|
+
.catch(() => undefined);
|
|
522
|
+
}
|
|
523
|
+
return result;
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
private sessionState(sessionKey: string, turnId: string | undefined): SessionSuppression {
|
|
527
|
+
let state = this.sessions.get(sessionKey);
|
|
528
|
+
if (!state) {
|
|
529
|
+
if (this.sessions.size >= MAX_TRACKED_SESSIONS) {
|
|
530
|
+
const oldest = this.sessions.keys().next().value;
|
|
531
|
+
if (oldest !== undefined) this.sessions.delete(oldest);
|
|
532
|
+
}
|
|
533
|
+
state = {
|
|
534
|
+
turnId: turnId ?? "",
|
|
535
|
+
deliveredThisTurn: new Set(),
|
|
536
|
+
deliveredByGate: new Set(),
|
|
537
|
+
deliveredByTurnStart: new Set(),
|
|
538
|
+
};
|
|
539
|
+
this.sessions.set(sessionKey, state);
|
|
540
|
+
}
|
|
541
|
+
if (turnId !== undefined && state.turnId !== turnId) {
|
|
542
|
+
state.turnId = turnId;
|
|
543
|
+
state.deliveredThisTurn.clear();
|
|
544
|
+
}
|
|
545
|
+
return state;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
private addTracked(set: Set<string>, value: string): void {
|
|
549
|
+
if (set.has(value)) return;
|
|
550
|
+
if (set.size >= MAX_TRACKED_IDS_PER_SESSION) {
|
|
551
|
+
const oldest = set.values().next().value;
|
|
552
|
+
if (oldest !== undefined) set.delete(oldest);
|
|
553
|
+
}
|
|
554
|
+
set.add(value);
|
|
555
|
+
}
|
|
556
|
+
}
|
package/src/config.ts
CHANGED
|
@@ -37,10 +37,13 @@ import { expandTildePath } from "./utils/path.js";
|
|
|
37
37
|
// lives in connectors/coerce.ts (a tiny, dependency-free module) so neither
|
|
38
38
|
// config.ts → connectors/index.ts nor the reverse circular import arises.
|
|
39
39
|
import { coerceBool, coerceBooleanLike, coerceInstallExtension, coerceNumber } from "./connectors/coerce.js";
|
|
40
|
+
import { parseSubjectRuntimeConfig } from "./subject-config.js";
|
|
40
41
|
import { parseRecallConcurrencyConfig } from "./recall-concurrency-config.js";
|
|
41
42
|
import { parseExtractionLivenessConfig } from "./extraction-liveness.js";
|
|
42
43
|
import { parseReplicaPeersConfig } from "./replica-peers-config.js";
|
|
43
44
|
import { parseDependencyPropagationConfig } from "./dependency-propagation-config.js";
|
|
45
|
+
import { parseProceduralMaintenanceConfig } from "./procedural/maintenance-config.js";
|
|
46
|
+
import { parseDriftDetectionConfig } from "./preferences/drift-config.js";
|
|
44
47
|
import {
|
|
45
48
|
parseContradictionLocalizationConfig,
|
|
46
49
|
parseContradictionScanConfig,
|
|
@@ -66,6 +69,7 @@ import { parseLocationConfig } from "./location/config.js";
|
|
|
66
69
|
import { parseOkfConfig } from "./okf/config.js";
|
|
67
70
|
import { parseBoundedJsonlStateConfig } from "./bounded-jsonl-state.js";
|
|
68
71
|
import { parseCodingKnowledgeConfig } from "./coding/coding-knowledge-config.js";
|
|
72
|
+
import { parseActionGateConfig } from "./coding/action-gate.js";
|
|
69
73
|
import { parseChatConfig } from "./chat/chat-config.js";
|
|
70
74
|
import { parseSupportPassportConfig } from "./support-passport/config.js";
|
|
71
75
|
import { parseCorrectionIntentConfig, parseFaithfulnessGateConfig } from "./faithfulness-config.js";
|
|
@@ -1123,16 +1127,9 @@ export function parseConfig(
|
|
|
1123
1127
|
recallMaxCoerced !== undefined && Number.isFinite(recallMaxCoerced)
|
|
1124
1128
|
? Math.min(10, Math.max(1, Math.floor(recallMaxCoerced)))
|
|
1125
1129
|
: 2;
|
|
1126
|
-
|
|
1127
|
-
//
|
|
1128
|
-
//
|
|
1129
|
-
// the feature off. CLAUDE.md rules:
|
|
1130
|
-
// - #30 — escape hatch remains for operators who want to stay opt-out.
|
|
1131
|
-
// - #36 — "false"-ish strings coerce to false via coerceBool.
|
|
1132
|
-
// - #51 — when the key IS present but the value can't be understood
|
|
1133
|
-
// (typo like `"fales"` or a number like `0`), reject loudly instead
|
|
1134
|
-
// of silently flipping the default. Silent fallback on bad input is
|
|
1135
|
-
// how procedural memory would end up "fail-open" for typos.
|
|
1130
|
+
const maintenance = parseProceduralMaintenanceConfig(rawProcedural.maintenance);
|
|
1131
|
+
// Default-on procedural memory (issue #567 PR 4/5). Explicit false-ish
|
|
1132
|
+
// values stay off. Unknown values throw.
|
|
1136
1133
|
const rawEnabledValue = rawProcedural.enabled;
|
|
1137
1134
|
let proceduralEnabled: boolean;
|
|
1138
1135
|
if (rawEnabledValue === undefined) {
|
|
@@ -1147,6 +1144,7 @@ export function parseConfig(
|
|
|
1147
1144
|
proceduralEnabled = enabledCoerced;
|
|
1148
1145
|
}
|
|
1149
1146
|
const procedural: ProceduralConfig = {
|
|
1147
|
+
maintenance,
|
|
1150
1148
|
enabled: proceduralEnabled,
|
|
1151
1149
|
/** `0` skips all mining (`minOccurrences_zero`); otherwise clusters need at least this many members. */
|
|
1152
1150
|
minOccurrences: Math.min(1000, Math.max(0, proceduralMinRaw)),
|
|
@@ -1793,6 +1791,8 @@ export function parseConfig(
|
|
|
1793
1791
|
contradictionAutoResolve: cfg.contradictionAutoResolve !== false,
|
|
1794
1792
|
// Contradiction Scan cron (issue #520)
|
|
1795
1793
|
contradictionScan: parseContradictionScanConfig(cfg.contradictionScan),
|
|
1794
|
+
// Preference drift detection (issue #2371)
|
|
1795
|
+
driftDetection: parseDriftDetectionConfig(cfg.driftDetection),
|
|
1796
1796
|
dependencyPropagation: parseDependencyPropagationConfig(cfg),
|
|
1797
1797
|
// Temporal Supersession (issue #375)
|
|
1798
1798
|
temporalSupersessionEnabled: cfg.temporalSupersessionEnabled !== false, // On by default
|
|
@@ -2333,6 +2333,7 @@ export function parseConfig(
|
|
|
2333
2333
|
bridgeMode: cfg.bridgeMode === undefined ? "embedded" : String(cfg.bridgeMode),
|
|
2334
2334
|
codexCompat,
|
|
2335
2335
|
codingKnowledge: parseCodingKnowledgeConfig(cfg.codingKnowledge),
|
|
2336
|
+
actionGate: parseActionGateConfig(cfg.actionGate),
|
|
2336
2337
|
chat: parseChatConfig(cfg.chat),
|
|
2337
2338
|
supportPassport: parseSupportPassportConfig(cfg.supportPassport),
|
|
2338
2339
|
hourlySummariesEnabled: cfg.hourlySummariesEnabled !== false, // default: true
|
|
@@ -2755,11 +2756,11 @@ export function parseConfig(
|
|
|
2755
2756
|
}
|
|
2756
2757
|
return "low";
|
|
2757
2758
|
})(),
|
|
2758
|
-
// Extraction scope classification
|
|
2759
|
-
//
|
|
2760
|
-
// facts are promoted to the shared namespace. Default true (rule 30 gate).
|
|
2759
|
+
// Extraction scope classification (rule 30 gate): "global" facts promote
|
|
2760
|
+
// to the shared namespace. Default true.
|
|
2761
2761
|
extractionScopeClassificationEnabled:
|
|
2762
2762
|
coerceBool(cfg.extractionScopeClassificationEnabled) !== false,
|
|
2763
|
+
...parseSubjectRuntimeConfig(cfg),
|
|
2763
2764
|
// Extraction judge (issue #376). Opt-in LLM-as-judge fact-worthiness gate.
|
|
2764
2765
|
extractionJudgeEnabled: cfg.extractionJudgeEnabled === true,
|
|
2765
2766
|
extractionJudgeModel:
|
|
@@ -2778,10 +2779,7 @@ export function parseConfig(
|
|
|
2778
2779
|
? Math.floor(cfg.extractionJudgeMaxDeferrals)
|
|
2779
2780
|
: 2,
|
|
2780
2781
|
// Judge telemetry (issue #562 PR 3): opt-in structured emit to the
|
|
2781
|
-
// observation ledger
|
|
2782
|
-
// Uses `coerceBool` so CLI-style string inputs (`"true"`, `"false"`,
|
|
2783
|
-
// `"1"`, `"0"`) are accepted consistently with the rest of the
|
|
2784
|
-
// codebase (CLAUDE.md gotcha 36).
|
|
2782
|
+
// observation ledger; `coerceBool` accepts CLI-style strings (gotcha 36).
|
|
2785
2783
|
extractionJudgeTelemetryEnabled:
|
|
2786
2784
|
coerceBool(cfg.extractionJudgeTelemetryEnabled) === true,
|
|
2787
2785
|
// Judge training-pair collection (issue #562 PR 4): opt-in shim for a
|