@remnic/core 9.3.725 → 9.3.727
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-boundary.d.ts +5 -5
- package/dist/access-boundary.js +28 -27
- package/dist/access-cli.js +65 -63
- package/dist/access-cli.js.map +1 -1
- package/dist/access-http.d.ts +20 -5
- package/dist/access-http.js +34 -33
- package/dist/access-mcp.d.ts +5 -5
- package/dist/access-mcp.js +31 -30
- package/dist/access-operations-batch.js +29 -28
- package/dist/access-operations.d.ts +5 -5
- package/dist/access-operations.js +30 -29
- package/dist/{access-service-B2PlPtxh.d.ts → access-service-Bgpjxo4f.d.ts} +36 -4
- package/dist/access-service.d.ts +5 -5
- package/dist/access-service.js +27 -26
- package/dist/access-surface-catalog.d.ts +5 -5
- package/dist/action-confidence.d.ts +1 -1
- package/dist/active-memory-bridge.d.ts +1 -1
- package/dist/active-recall.d.ts +1 -1
- package/dist/active-recall.js +3 -3
- package/dist/adapters/index.js +4 -4
- package/dist/adapters/registry.js +2 -2
- package/dist/behavior-learner.d.ts +1 -1
- package/dist/behavior-signals.d.ts +1 -1
- package/dist/bootstrap.d.ts +4 -4
- package/dist/briefing.d.ts +1 -1
- package/dist/briefing.js +9 -8
- package/dist/buffer-surprise-report.d.ts +1 -1
- package/dist/buffer.d.ts +1 -1
- package/dist/calibration.d.ts +1 -1
- package/dist/capabilities.d.ts +1 -1
- package/dist/{catalog-CzUb-GyD.d.ts → catalog-bMczlO2G.d.ts} +1 -1
- package/dist/causal-behavior.d.ts +1 -1
- package/dist/causal-consolidation.d.ts +1 -1
- package/dist/causal-consolidation.js +10 -9
- package/dist/causal-consolidation.js.map +1 -1
- package/dist/causal-trajectory-graph.d.ts +1 -1
- package/dist/{chunk-KGZF2VO3.js → chunk-27QQC7ZX.js} +80 -19
- package/dist/{chunk-KGZF2VO3.js.map → chunk-27QQC7ZX.js.map} +1 -1
- package/dist/{chunk-HCVWF657.js → chunk-2KAYTPPT.js} +12 -12
- package/dist/{chunk-4SF232E6.js → chunk-36SEDFAU.js} +19 -7
- package/dist/chunk-36SEDFAU.js.map +1 -0
- package/dist/{chunk-ZK2L72VN.js → chunk-37436GML.js} +2 -2
- package/dist/{chunk-SC2YAWRF.js → chunk-3TSTGI6F.js} +2 -2
- package/dist/{chunk-FACTVMXQ.js → chunk-4H4F3BFL.js} +2 -2
- package/dist/{chunk-WAFDHKES.js → chunk-4NOI577P.js} +2 -2
- package/dist/{chunk-YQMPUYHE.js → chunk-4NR2PDZ5.js} +2 -2
- package/dist/{chunk-TAPSNIMA.js → chunk-5CEJH5ZN.js} +4 -4
- package/dist/{chunk-FN6QP7JQ.js → chunk-6PY5YJAV.js} +100 -14
- package/dist/{chunk-FN6QP7JQ.js.map → chunk-6PY5YJAV.js.map} +1 -1
- package/dist/{chunk-PKMQK2WY.js → chunk-773DPI6T.js} +4 -4
- package/dist/{chunk-4R3CGCI5.js → chunk-7RLCCNHU.js} +15 -12
- package/dist/chunk-7RLCCNHU.js.map +1 -0
- package/dist/{chunk-XGTBNVIU.js → chunk-AAD2ZS6P.js} +11 -1
- package/dist/chunk-AAD2ZS6P.js.map +1 -0
- package/dist/{chunk-Z3FGC3QE.js → chunk-AQLOP5F4.js} +139 -30
- package/dist/chunk-AQLOP5F4.js.map +1 -0
- package/dist/{chunk-FXCIOLRB.js → chunk-ASKXIAHD.js} +2 -2
- package/dist/{chunk-5OPYYPJN.js → chunk-CBWI22JN.js} +2 -2
- package/dist/{chunk-ZOHMPFOB.js → chunk-CKFLLAIS.js} +3 -3
- package/dist/{chunk-GZQXOQQ2.js → chunk-CSRXQ6NB.js} +5 -5
- package/dist/{chunk-QR67FU5G.js → chunk-CTOQEZSN.js} +2 -2
- package/dist/{chunk-ZUDM75KG.js → chunk-DCWIQFNA.js} +4 -4
- package/dist/{chunk-6CWGS2LY.js → chunk-DKJCRGWM.js} +3 -3
- package/dist/{chunk-JJJCVCCQ.js → chunk-DMQWV6SQ.js} +2 -2
- package/dist/{chunk-F3XZN24Z.js → chunk-DRUDC2UX.js} +2 -2
- package/dist/{chunk-4WZ3J7M6.js → chunk-EY6MDMHK.js} +2 -2
- package/dist/{chunk-YNDLCWXS.js → chunk-EZ25VE3G.js} +4 -4
- package/dist/{chunk-C4X4QGIO.js → chunk-G6NKALRN.js} +5 -2
- package/dist/chunk-G6NKALRN.js.map +1 -0
- package/dist/{chunk-6SQQOJ4U.js → chunk-GKRLPHPU.js} +2 -2
- package/dist/{chunk-D7EBTQ24.js → chunk-HOHVIVDR.js} +2 -2
- package/dist/{chunk-RKNJBZ55.js → chunk-JBPKEARU.js} +4 -4
- package/dist/{chunk-UBHVAGO7.js → chunk-JYLFZWUX.js} +2 -2
- package/dist/{chunk-LD53WPMU.js → chunk-LQ6JI4VH.js} +4 -4
- package/dist/chunk-LTHVM4XN.js +109 -0
- package/dist/chunk-LTHVM4XN.js.map +1 -0
- package/dist/{chunk-WM7DNKBD.js → chunk-M4V2JVSZ.js} +2 -2
- package/dist/{chunk-I2HL5M6T.js → chunk-MJIHJ7OG.js} +52 -52
- package/dist/{chunk-J334N6QV.js → chunk-MLKWJOAJ.js} +2 -2
- package/dist/{chunk-C6BWLYW5.js → chunk-N3VNUM4Z.js} +171 -79
- package/dist/chunk-N3VNUM4Z.js.map +1 -0
- package/dist/{chunk-DF3I6JGP.js → chunk-NSA5ZRUL.js} +15 -15
- package/dist/{chunk-VI5SGGXB.js → chunk-OEEW4KJA.js} +4 -4
- package/dist/{chunk-7AG54AF3.js → chunk-PUR2CKX2.js} +1 -1
- package/dist/chunk-PUR2CKX2.js.map +1 -0
- package/dist/{chunk-NT36GU6X.js → chunk-R7IYU5DZ.js} +2 -2
- package/dist/{chunk-TT5U3UDO.js → chunk-SNKPUJHR.js} +4 -4
- package/dist/{chunk-T55EGZSJ.js → chunk-UVPL565C.js} +2 -2
- package/dist/chunk-W5H6ZRPT.js +14 -0
- package/dist/chunk-W5H6ZRPT.js.map +1 -0
- package/dist/{chunk-YQGHW5ML.js → chunk-WRFKZEO6.js} +4 -4
- package/dist/{chunk-KLFYKC3K.js → chunk-XPHVAOBT.js} +195 -74
- package/dist/chunk-XPHVAOBT.js.map +1 -0
- package/dist/{chunk-H7HUQIY7.js → chunk-Y4YD5TYW.js} +3 -3
- package/dist/{chunk-MDBZTH7N.js → chunk-YKBHOBJK.js} +44 -10
- package/dist/chunk-YKBHOBJK.js.map +1 -0
- package/dist/{chunk-YUYPWJD3.js → chunk-YOLZS7NY.js} +2 -2
- package/dist/{chunk-6OIDDKAA.js → chunk-YTU7WKYN.js} +35 -9
- package/dist/chunk-YTU7WKYN.js.map +1 -0
- package/dist/{cli-IOlDHSBT.d.ts → cli-BLME420h.d.ts} +3 -3
- package/dist/cli.d.ts +6 -6
- package/dist/cli.js +60 -59
- package/dist/compat/codex-cli-fallback.d.ts +1 -0
- package/dist/compat/codex-cli-fallback.js +22 -0
- package/dist/compat/codex-cli-fallback.js.map +1 -0
- package/dist/compat/codex-thread-key.d.ts +1 -0
- package/dist/compat/codex-thread-key.js +18 -0
- package/dist/compat/codex-thread-key.js.map +1 -0
- package/dist/compounding/engine.d.ts +1 -1
- package/dist/compounding/engine.js +9 -8
- package/dist/compounding/preference-consolidator.d.ts +1 -1
- package/dist/compression-optimizer.d.ts +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.js +3 -3
- package/dist/connectors/codex-materialize-runner.d.ts +1 -1
- package/dist/connectors/codex-materialize-runner.js +9 -8
- package/dist/connectors/codex-materialize.d.ts +1 -1
- package/dist/connectors/index.d.ts +1 -1
- package/dist/connectors/index.js +9 -8
- package/dist/consolidation-provenance-check.d.ts +1 -1
- package/dist/consolidation-undo.d.ts +1 -1
- package/dist/content-hash.d.ts +14 -0
- package/dist/content-hash.js +10 -0
- package/dist/content-hash.js.map +1 -0
- package/dist/contradiction/index.d.ts +1 -1
- package/dist/conversation-index/backend.d.ts +1 -1
- package/dist/conversation-index/backend.js +2 -2
- package/dist/conversation-index/chunker.d.ts +1 -1
- package/dist/conversation-index/faiss-adapter.d.ts +1 -1
- package/dist/conversation-index/indexer.d.ts +1 -1
- package/dist/conversation-index/search.d.ts +1 -1
- package/dist/dashboard-runtime.js +2 -2
- package/dist/day-summary.d.ts +1 -1
- package/dist/delinearize.d.ts +1 -1
- package/dist/direct-answer-wiring.d.ts +1 -1
- package/dist/direct-answer.d.ts +1 -1
- package/dist/embedding-fallback.d.ts +1 -1
- package/dist/enrichment/index.d.ts +1 -1
- package/dist/entity-retrieval.d.ts +1 -1
- package/dist/entity-retrieval.js +9 -8
- package/dist/entity-schema.d.ts +1 -1
- package/dist/explicit-capture.d.ts +4 -4
- package/dist/extraction-faithfulness.d.ts +1 -1
- package/dist/extraction-faithfulness.js +2 -2
- package/dist/extraction-judge-telemetry.d.ts +1 -1
- package/dist/extraction-judge-training.d.ts +1 -1
- package/dist/extraction-judge.d.ts +1 -1
- package/dist/extraction-redaction-rules.d.ts +33 -0
- package/dist/extraction-redaction-rules.js +14 -0
- package/dist/extraction-redaction-rules.js.map +1 -0
- package/dist/extraction.d.ts +1 -1
- package/dist/extraction.js +3 -3
- package/dist/faithfulness-config.d.ts +1 -0
- package/dist/faithfulness-config.js +1 -1
- package/dist/fallback-llm.d.ts +1 -1
- package/dist/{forget-OEE5OELK.js → forget-WYLR4ZFV.js} +2 -2
- package/dist/graph-dashboard-diff.d.ts +1 -1
- package/dist/graph-dashboard-key.d.ts +1 -1
- package/dist/graph-dashboard-parser.d.ts +1 -1
- package/dist/graph-edge-reinforcement.d.ts +1 -1
- package/dist/graph-snapshot.d.ts +1 -1
- package/dist/graph.d.ts +1 -1
- package/dist/identity-continuity.d.ts +1 -1
- package/dist/importance.d.ts +1 -1
- package/dist/index.d.ts +9 -9
- package/dist/index.js +107 -105
- package/dist/index.js.map +1 -1
- package/dist/intent.d.ts +1 -1
- package/dist/lcm/engine.d.ts +1 -1
- package/dist/lcm/engine.js +2 -2
- package/dist/lcm/index.d.ts +1 -1
- package/dist/lcm/index.js +4 -4
- package/dist/lcm/tools.d.ts +1 -1
- package/dist/lifecycle.d.ts +1 -1
- package/dist/live-connectors-runner.d.ts +1 -1
- package/dist/local-llm.d.ts +1 -1
- package/dist/local-model-endpoint.d.ts +9 -4
- package/dist/local-model-endpoint.js +1 -1
- package/dist/maintenance/memory-governance.d.ts +1 -1
- package/dist/maintenance/memory-governance.js +9 -8
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +9 -8
- package/dist/maintenance/rebuild-memory-projection.js +10 -9
- package/dist/mcp-memory-inspector-app.d.ts +5 -5
- package/dist/memory-action-policy.d.ts +1 -1
- package/dist/memory-cache.d.ts +1 -1
- package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
- package/dist/memory-projection-store.d.ts +1 -1
- package/dist/memory-provenance.d.ts +1 -1
- package/dist/memory-worth-outcomes.d.ts +1 -1
- package/dist/models-json.d.ts +1 -1
- package/dist/namespaces/migrate.d.ts +2 -2
- package/dist/namespaces/migrate.js +19 -18
- package/dist/namespaces/principal.d.ts +1 -1
- package/dist/namespaces/search.d.ts +1 -1
- package/dist/namespaces/search.js +9 -9
- package/dist/namespaces/storage.d.ts +2 -2
- package/dist/namespaces/storage.js +9 -8
- package/dist/native-knowledge.d.ts +1 -1
- package/dist/operator-toolkit.d.ts +1 -1
- package/dist/operator-toolkit.js +28 -27
- package/dist/orchestration/maintenance.d.ts +2 -2
- package/dist/orchestration/maintenance.js +11 -10
- package/dist/{orchestrator-C_OMSIMZ.d.ts → orchestrator-DqPAz8ot.d.ts} +3 -3
- package/dist/orchestrator.d.ts +4 -4
- package/dist/orchestrator.js +51 -49
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/policy-runtime.d.ts +1 -1
- package/dist/provenance.d.ts +1 -1
- package/dist/provenance.js +1 -1
- package/dist/qmd-recall-cache.d.ts +1 -1
- package/dist/qmd.d.ts +1 -1
- package/dist/recall-disclosure-escalation.d.ts +1 -1
- package/dist/recall-explain-renderer.d.ts +1 -1
- package/dist/recall-explain-renderer.js +3 -3
- package/dist/recall-planner-llm.d.ts +1 -1
- package/dist/recall-state.d.ts +1 -1
- package/dist/recall-tag-filter.d.ts +1 -1
- package/dist/recall-xray-cli.d.ts +1 -1
- package/dist/recall-xray-cli.js +4 -4
- package/dist/recall-xray-renderer.d.ts +1 -1
- package/dist/recall-xray-renderer.js +3 -3
- package/dist/recall-xray.d.ts +1 -1
- package/dist/recall-xray.js +2 -2
- package/dist/resolve-auth-token.d.ts +1 -1
- package/dist/resume-bundles.js +4 -4
- package/dist/retrieval-agents.d.ts +1 -1
- package/dist/retrieval-tiers.d.ts +1 -1
- package/dist/routing/engine.d.ts +1 -1
- package/dist/routing/store.d.ts +1 -1
- package/dist/schemas.d.ts +22 -22
- package/dist/search/embed-helper.d.ts +1 -1
- package/dist/search/factory.d.ts +1 -1
- package/dist/search/factory.js +8 -8
- package/dist/search/index.d.ts +1 -1
- package/dist/search/index.js +14 -14
- package/dist/search/lancedb-backend.d.ts +1 -1
- package/dist/search/lancedb-backend.js +2 -2
- package/dist/search/meilisearch-backend.d.ts +1 -1
- package/dist/search/meilisearch-backend.js +2 -2
- package/dist/search/noop-backend.d.ts +1 -1
- package/dist/search/orama-backend.d.ts +1 -1
- package/dist/search/orama-backend.js +2 -2
- package/dist/search/port.d.ts +1 -1
- package/dist/search/remote-backend.d.ts +1 -1
- package/dist/{semantic-consolidation-B8LiYtvx.d.ts → semantic-consolidation-Cl15ksZy.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +10 -9
- package/dist/semantic-rule-promotion.js +9 -8
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/semantic-rule-verifier.js +9 -8
- package/dist/session-observer-bands.d.ts +1 -1
- package/dist/session-observer-state.d.ts +1 -1
- package/dist/shared-context/manager.d.ts +1 -1
- package/dist/signal.d.ts +1 -1
- package/dist/storage.d.ts +3 -3
- package/dist/storage.js +9 -8
- package/dist/summarizer.d.ts +1 -1
- package/dist/summary-snapshot.d.ts +1 -1
- package/dist/temporal-supersession.d.ts +1 -1
- package/dist/temporal-validity.d.ts +1 -1
- package/dist/threading.d.ts +1 -1
- package/dist/tier-migration.d.ts +1 -1
- package/dist/tier-routing.d.ts +1 -1
- package/dist/topics.d.ts +1 -1
- package/dist/transcript.d.ts +1 -1
- package/dist/transfer/types.d.ts +12 -12
- package/dist/trust-score-stage.d.ts +1 -1
- package/dist/trust-score.d.ts +1 -1
- package/dist/{types-DmTaqob2.d.ts → types-ChQb9D6s.d.ts} +8 -0
- package/dist/types.d.ts +1 -1
- package/dist/types.js +1 -1
- package/dist/utility-runtime.d.ts +1 -1
- package/dist/verified-recall.js +9 -8
- package/package.json +26 -2
- package/src/access-http.ts +68 -1
- package/src/admin/admin-surfaces.test.ts +289 -0
- package/src/admin/admin-surfaces.ts +138 -7
- package/src/bitemporal-dedup-backfill.test.ts +294 -0
- package/src/chat/chat-engine.test.ts +66 -1
- package/src/chat/chat-http.test.ts +119 -1
- package/src/chat/chat-http.ts +252 -97
- package/src/chat/chat-session.ts +143 -7
- package/src/compat/codex-cli-fallback.ts +23 -0
- package/src/compat/codex-subpath-aliases.test.ts +93 -0
- package/src/compat/codex-thread-key.ts +23 -0
- package/src/config.test.ts +50 -0
- package/src/config.ts +21 -4
- package/src/content-hash.ts +24 -0
- package/src/correction/correction-access-wiring.ts +104 -19
- package/src/correction/correction-contract.ts +68 -10
- package/src/correction/correction-executor.test.ts +112 -2
- package/src/correction/correction-executor.ts +65 -5
- package/src/correction/correction-planner.test.ts +47 -0
- package/src/correction/correction-planner.ts +40 -1
- package/src/correction/correction-storage-integration.test.ts +183 -0
- package/src/extraction-faithfulness.test.ts +240 -0
- package/src/extraction-faithfulness.ts +58 -6
- package/src/extraction-redaction-rules.test.ts +213 -0
- package/src/extraction-redaction-rules.ts +208 -0
- package/src/faithfulness-config.ts +16 -1
- package/src/local-model-endpoint.ts +24 -3
- package/src/orchestrator.ts +252 -9
- package/src/provenance-extraction.test.ts +266 -0
- package/src/provenance.ts +66 -16
- package/src/storage.ts +6 -10
- package/src/types.ts +8 -0
- package/dist/chunk-4R3CGCI5.js.map +0 -1
- package/dist/chunk-4SF232E6.js.map +0 -1
- package/dist/chunk-6OIDDKAA.js.map +0 -1
- package/dist/chunk-7AG54AF3.js.map +0 -1
- package/dist/chunk-C4X4QGIO.js.map +0 -1
- package/dist/chunk-C6BWLYW5.js.map +0 -1
- package/dist/chunk-KLFYKC3K.js.map +0 -1
- package/dist/chunk-MDBZTH7N.js.map +0 -1
- package/dist/chunk-XGTBNVIU.js.map +0 -1
- package/dist/chunk-Z3FGC3QE.js.map +0 -1
- /package/dist/{chunk-HCVWF657.js.map → chunk-2KAYTPPT.js.map} +0 -0
- /package/dist/{chunk-ZK2L72VN.js.map → chunk-37436GML.js.map} +0 -0
- /package/dist/{chunk-SC2YAWRF.js.map → chunk-3TSTGI6F.js.map} +0 -0
- /package/dist/{chunk-FACTVMXQ.js.map → chunk-4H4F3BFL.js.map} +0 -0
- /package/dist/{chunk-WAFDHKES.js.map → chunk-4NOI577P.js.map} +0 -0
- /package/dist/{chunk-YQMPUYHE.js.map → chunk-4NR2PDZ5.js.map} +0 -0
- /package/dist/{chunk-TAPSNIMA.js.map → chunk-5CEJH5ZN.js.map} +0 -0
- /package/dist/{chunk-PKMQK2WY.js.map → chunk-773DPI6T.js.map} +0 -0
- /package/dist/{chunk-FXCIOLRB.js.map → chunk-ASKXIAHD.js.map} +0 -0
- /package/dist/{chunk-5OPYYPJN.js.map → chunk-CBWI22JN.js.map} +0 -0
- /package/dist/{chunk-ZOHMPFOB.js.map → chunk-CKFLLAIS.js.map} +0 -0
- /package/dist/{chunk-GZQXOQQ2.js.map → chunk-CSRXQ6NB.js.map} +0 -0
- /package/dist/{chunk-QR67FU5G.js.map → chunk-CTOQEZSN.js.map} +0 -0
- /package/dist/{chunk-ZUDM75KG.js.map → chunk-DCWIQFNA.js.map} +0 -0
- /package/dist/{chunk-6CWGS2LY.js.map → chunk-DKJCRGWM.js.map} +0 -0
- /package/dist/{chunk-JJJCVCCQ.js.map → chunk-DMQWV6SQ.js.map} +0 -0
- /package/dist/{chunk-F3XZN24Z.js.map → chunk-DRUDC2UX.js.map} +0 -0
- /package/dist/{chunk-4WZ3J7M6.js.map → chunk-EY6MDMHK.js.map} +0 -0
- /package/dist/{chunk-YNDLCWXS.js.map → chunk-EZ25VE3G.js.map} +0 -0
- /package/dist/{chunk-6SQQOJ4U.js.map → chunk-GKRLPHPU.js.map} +0 -0
- /package/dist/{chunk-D7EBTQ24.js.map → chunk-HOHVIVDR.js.map} +0 -0
- /package/dist/{chunk-RKNJBZ55.js.map → chunk-JBPKEARU.js.map} +0 -0
- /package/dist/{chunk-UBHVAGO7.js.map → chunk-JYLFZWUX.js.map} +0 -0
- /package/dist/{chunk-LD53WPMU.js.map → chunk-LQ6JI4VH.js.map} +0 -0
- /package/dist/{chunk-WM7DNKBD.js.map → chunk-M4V2JVSZ.js.map} +0 -0
- /package/dist/{chunk-I2HL5M6T.js.map → chunk-MJIHJ7OG.js.map} +0 -0
- /package/dist/{chunk-J334N6QV.js.map → chunk-MLKWJOAJ.js.map} +0 -0
- /package/dist/{chunk-DF3I6JGP.js.map → chunk-NSA5ZRUL.js.map} +0 -0
- /package/dist/{chunk-VI5SGGXB.js.map → chunk-OEEW4KJA.js.map} +0 -0
- /package/dist/{chunk-NT36GU6X.js.map → chunk-R7IYU5DZ.js.map} +0 -0
- /package/dist/{chunk-TT5U3UDO.js.map → chunk-SNKPUJHR.js.map} +0 -0
- /package/dist/{chunk-T55EGZSJ.js.map → chunk-UVPL565C.js.map} +0 -0
- /package/dist/{chunk-YQGHW5ML.js.map → chunk-WRFKZEO6.js.map} +0 -0
- /package/dist/{chunk-H7HUQIY7.js.map → chunk-Y4YD5TYW.js.map} +0 -0
- /package/dist/{chunk-YUYPWJD3.js.map → chunk-YOLZS7NY.js.map} +0 -0
- /package/dist/{forget-OEE5OELK.js.map → forget-WYLR4ZFV.js.map} +0 -0
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* extraction-redaction-rules.ts — consults persisted correction redaction
|
|
3
|
+
* rules during the extraction→persist path so a `never_store` / redaction_rule
|
|
4
|
+
* correction actually blocks future extraction of matching content (issue
|
|
5
|
+
* #1669, #1580 follow-up).
|
|
6
|
+
*
|
|
7
|
+
* The Correction Contract persists `redaction_rule` patterns to
|
|
8
|
+
* `<storage>/state/corrections/redaction-rules/<slug>.json` (one file per
|
|
9
|
+
* rule, idempotent on pattern). This module reads those patterns at the start
|
|
10
|
+
* of each extraction persist pass and exposes a pure matcher the orchestrator
|
|
11
|
+
* consults BEFORE a fact reaches the storage write chokepoint — mirroring how
|
|
12
|
+
* tombstones are consulted at the write chokepoint (#1579), but one stage
|
|
13
|
+
* earlier so the content never even lands as `pending_review`.
|
|
14
|
+
*
|
|
15
|
+
* Scope (issue #1669): the extraction layer consults the rules. Persistence
|
|
16
|
+
* stays owned by the correction module. This helper is the read surface.
|
|
17
|
+
*
|
|
18
|
+
* Safety: patterns are validated at correction-apply time
|
|
19
|
+
* (`validateRedactionPattern` — bounded literal/safe-regex, no catastrophic
|
|
20
|
+
* shapes). We compile defensively here too: a pattern that fails to compile
|
|
21
|
+
* as a regex is treated as a literal substring, and any matcher error is
|
|
22
|
+
* swallowed (fail-open to "no match") so a malformed rule can never block the
|
|
23
|
+
* entire extraction pipeline.
|
|
24
|
+
*/
|
|
25
|
+
import { readdir, readFile } from "node:fs/promises";
|
|
26
|
+
import path from "node:path";
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Directory (relative to a namespace storage dir) where redaction rules live.
|
|
30
|
+
* Kept in sync with `registerRedactionRuleFn` in correction-access-wiring.ts.
|
|
31
|
+
*/
|
|
32
|
+
export const REDACTION_RULES_SUBDIR = path.join("state", "corrections", "redaction-rules");
|
|
33
|
+
|
|
34
|
+
/** Maximum number of rule files read per pass (defense in depth). */
|
|
35
|
+
const MAX_RULE_FILES = 256;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* A compiled redaction rule. `pattern` is the original (validated) pattern;
|
|
39
|
+
* `matcher` returns true when content should be withheld.
|
|
40
|
+
*/
|
|
41
|
+
export interface CompiledRedactionRule {
|
|
42
|
+
pattern: string;
|
|
43
|
+
matcher: (content: string) => boolean;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** Shape persisted by `registerRedactionRuleFn`. */
|
|
47
|
+
interface RedactionRuleFile {
|
|
48
|
+
pattern: string;
|
|
49
|
+
namespace?: string;
|
|
50
|
+
createdAt?: string;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Only `/…/`-wrapped patterns compile as RegExp; everything else is a literal
|
|
55
|
+
* substring (review thread P1). An unwrapped pattern like `abc+def` must match
|
|
56
|
+
* the literal string `abc+def`, NOT the regex `abccccdef`.
|
|
57
|
+
*/
|
|
58
|
+
function isRegexLike(pattern: string): boolean {
|
|
59
|
+
return pattern.startsWith("/") && pattern.endsWith("/") && pattern.length >= 2;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Reject patterns prone to catastrophic backtracking (ReDoS, review thread #3).
|
|
64
|
+
* Mirrors the safe-regex heuristic: a quantifier inside a group that is itself
|
|
65
|
+
* quantified creates exponential blowup on near-miss inputs. Also rejects
|
|
66
|
+
* patterns with overlapping alternation under repetition
|
|
67
|
+
* (e.g. (a|a)*). Returns true when the pattern is safe to compile.
|
|
68
|
+
*
|
|
69
|
+
* This is a second line of defense — validateRedactionPattern runs first at
|
|
70
|
+
* apply time, but a hand-edited rule file or an edge case can still slip past.
|
|
71
|
+
*/
|
|
72
|
+
function isSafeRegex(source: string): boolean {
|
|
73
|
+
if (source.length === 0 || source.length > 512) return false;
|
|
74
|
+
// Reject overly-broad patterns (.*) that would match every fact and
|
|
75
|
+
// withhold all extraction (cursor Bugbot thread — mirrors
|
|
76
|
+
// isUnsafeRedactionRegex in correction-contract.ts).
|
|
77
|
+
if (/(?:^|[^\\])\(\.\*\)|(?:^|[^\\])\.\*|(?:^|[^\\])\.\+|^\.([^*+]?)$/.test(source)) {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
// group body itself ends with a quantifier. This catches (a+)+, (a*)*, etc.
|
|
81
|
+
// Also catches overlapping alternation like (a|a)+.
|
|
82
|
+
for (let i = 0; i < source.length; i++) {
|
|
83
|
+
if (source[i] !== "(") continue;
|
|
84
|
+
// Find the matching close paren
|
|
85
|
+
let depth = 1;
|
|
86
|
+
let j = i + 1;
|
|
87
|
+
while (j < source.length && depth > 0) {
|
|
88
|
+
if (source[j] === "\\") { j += 2; continue; }
|
|
89
|
+
if (source[j] === "(") depth++;
|
|
90
|
+
else if (source[j] === ")") depth--;
|
|
91
|
+
j++;
|
|
92
|
+
}
|
|
93
|
+
if (depth !== 0) continue; // unbalanced — will fail RegExp compile anyway
|
|
94
|
+
// Check if the char after the closing paren is a quantifier
|
|
95
|
+
const afterGroup = source[j];
|
|
96
|
+
if (afterGroup !== "+" && afterGroup !== "*" && afterGroup !== "{") continue;
|
|
97
|
+
const groupBody = source.slice(i + 1, j - 1);
|
|
98
|
+
// The group body ends with a quantifier on a non-escape char
|
|
99
|
+
if (/[+*?]$/.test(groupBody) || /\{\d+,?\d*\}[+*?]?$/.test(groupBody)) {
|
|
100
|
+
// Nested quantifier → potential ReDoS
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
// Overlapping alternation: (a|a)+ where branches share a common prefix
|
|
104
|
+
if (groupBody.includes("|")) {
|
|
105
|
+
const branches = groupBody.split("|");
|
|
106
|
+
if (branches.length >= 2) {
|
|
107
|
+
const firstChars = new Set(branches.map((b) => b[0]).filter(Boolean));
|
|
108
|
+
if (firstChars.size < branches.filter((b) => b.length > 0).length) {
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
i = j;
|
|
114
|
+
}
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Compile a single pattern into a matcher. A literal pattern matches by
|
|
120
|
+
* case-sensitive substring; a `/…/`-wrapped pattern compiles into a RegExp
|
|
121
|
+
* anchored to search (global flag off — we only need a boolean). Compilation
|
|
122
|
+
* failures fall back to literal substring so a bad pattern never throws here.
|
|
123
|
+
*/
|
|
124
|
+
export function compileRedactionPattern(pattern: string): CompiledRedactionRule {
|
|
125
|
+
const trimmed = pattern.trim();
|
|
126
|
+
if (!isRegexLike(trimmed)) {
|
|
127
|
+
return { pattern: trimmed, matcher: (content) => content.includes(trimmed) };
|
|
128
|
+
}
|
|
129
|
+
const body = trimmed.slice(1, -1);
|
|
130
|
+
try {
|
|
131
|
+
if (!isSafeRegex(body)) {
|
|
132
|
+
if (body.length === 0) return { pattern: trimmed, matcher: () => false };
|
|
133
|
+
return { pattern: trimmed, matcher: (content) => content.includes(body) };
|
|
134
|
+
}
|
|
135
|
+
const re = new RegExp(body);
|
|
136
|
+
if (re.test("")) {
|
|
137
|
+
// Zero-width regex matches every string — would withhold all extraction.
|
|
138
|
+
return { pattern: trimmed, matcher: (content) => content.includes(body) };
|
|
139
|
+
}
|
|
140
|
+
return { pattern: trimmed, matcher: (content) => re.test(content) };
|
|
141
|
+
} catch {
|
|
142
|
+
// Malformed regex despite validation (e.g. rule file hand-edited) —
|
|
143
|
+
// treat as a literal on the BODY so the rule still does something useful.
|
|
144
|
+
return { pattern: trimmed, matcher: (content) => content.includes(body) };
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Load + compile every redaction rule persisted under a namespace's storage
|
|
150
|
+
* dir. Returns an empty array when the directory is absent or unreadable
|
|
151
|
+
* (fail-open — a missing or corrupt rules dir must never block extraction).
|
|
152
|
+
*/
|
|
153
|
+
export async function loadRedactionRules(stateDir: string): Promise<CompiledRedactionRule[]> {
|
|
154
|
+
const dir = path.join(stateDir, REDACTION_RULES_SUBDIR);
|
|
155
|
+
let names: string[];
|
|
156
|
+
try {
|
|
157
|
+
names = await readdir(dir);
|
|
158
|
+
} catch {
|
|
159
|
+
// ENOENT (cold install, no rules yet) or permission error — no rules.
|
|
160
|
+
return [];
|
|
161
|
+
}
|
|
162
|
+
// Sort deterministically (alphabetical by filename) so the set of rules
|
|
163
|
+
// that survives the MAX_RULE_FILES cap is NOT filesystem-dependent (review
|
|
164
|
+
// thread P2). Without this, readdir order varies by OS/FS and the silently
|
|
165
|
+
// truncated rules are arbitrary — a never-store pattern could be dropped.
|
|
166
|
+
const jsonFiles = names.filter((n) => n.endsWith(".json")).sort();
|
|
167
|
+
if (jsonFiles.length > MAX_RULE_FILES) {
|
|
168
|
+
// Visible failure mode: log a warning so the operator knows rules were
|
|
169
|
+
// truncated, rather than silently dropping enforcement.
|
|
170
|
+
console.warn(
|
|
171
|
+
`extraction-redaction: ${jsonFiles.length} redaction rules in ${dir} exceed the ${MAX_RULE_FILES} cap; ` +
|
|
172
|
+
`${jsonFiles.length - MAX_RULE_FILES} rules will NOT be enforced. Remove unused rules or raise the cap.`,
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
const rules: CompiledRedactionRule[] = [];
|
|
176
|
+
for (const name of jsonFiles.slice(0, MAX_RULE_FILES)) {
|
|
177
|
+
try {
|
|
178
|
+
const raw = await readFile(path.join(dir, name), "utf-8");
|
|
179
|
+
const parsed = JSON.parse(raw) as RedactionRuleFile;
|
|
180
|
+
if (typeof parsed?.pattern !== "string" || parsed.pattern.trim().length === 0) continue;
|
|
181
|
+
rules.push(compileRedactionPattern(parsed.pattern));
|
|
182
|
+
} catch {
|
|
183
|
+
// Skip a corrupt rule file rather than failing the pass (rule 34 —
|
|
184
|
+
// visible skip, never a silent pipeline block).
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return rules;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Test content against a set of compiled rules. Returns true if ANY rule
|
|
192
|
+
* matches (the content should be withheld). An empty rule set never matches.
|
|
193
|
+
*/
|
|
194
|
+
export function contentMatchesRedactionRules(
|
|
195
|
+
content: string,
|
|
196
|
+
rules: readonly CompiledRedactionRule[],
|
|
197
|
+
): boolean {
|
|
198
|
+
for (const rule of rules) {
|
|
199
|
+
try {
|
|
200
|
+
if (rule.matcher(content)) return true;
|
|
201
|
+
} catch {
|
|
202
|
+
// A matcher should not throw (compilation already fell back), but if a
|
|
203
|
+
// RegExp blows up on pathological input we skip that rule rather than
|
|
204
|
+
// failing the whole gate.
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* `config.ts` spread the result in one line.
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import { coerceNumber } from "./connectors/coerce.js";
|
|
20
|
+
import { coerceBool, coerceNumber } from "./connectors/coerce.js";
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* Parse a value as a strict integer >= `min`, throwing on anything else.
|
|
@@ -67,6 +67,7 @@ export function parseFaithfulnessGateConfig(cfg: Record<string, unknown>): {
|
|
|
67
67
|
extractionFaithfulnessBaseUrl: string;
|
|
68
68
|
extractionFaithfulnessContextChars: number;
|
|
69
69
|
extractionFaithfulnessTimeoutMs: number;
|
|
70
|
+
extractionFaithfulnessLocalParseFallback: boolean;
|
|
70
71
|
} {
|
|
71
72
|
const gateValue = cfg.extractionFaithfulnessGate;
|
|
72
73
|
let extractionFaithfulnessGate: "off" | "shadow" | "enforce";
|
|
@@ -105,12 +106,26 @@ export function parseFaithfulnessGateConfig(cfg: Record<string, unknown>): {
|
|
|
105
106
|
60_000,
|
|
106
107
|
);
|
|
107
108
|
|
|
109
|
+
// Issue #1700 nit #6: resilient-fallback toggle for the local model-lab
|
|
110
|
+
// endpoint. Default false preserves the loud-signal behavior (a 200-with-
|
|
111
|
+
// garbage local response surfaces malformed_output so a misconfigured
|
|
112
|
+
// endpoint is visible); true falls back to the configured chain on local
|
|
113
|
+
// parse failure. Byte-identical pre-feature when unset (rule 39).
|
|
114
|
+
// coerceBool for CLI-string parity: a CLI override like
|
|
115
|
+
// --config extractionFaithfulnessLocalParseFallback=true reaches here as the
|
|
116
|
+
// string "true"; === true would silently leave the flag disabled. Matches
|
|
117
|
+
// every other CLI-settable boolean in config.ts (gotcha 36, codex P2
|
|
118
|
+
// PRRT_kwDORJXyws6O6gDQ / cursor BUGBOT e273b22c).
|
|
119
|
+
const extractionFaithfulnessLocalParseFallback =
|
|
120
|
+
coerceBool(cfg.extractionFaithfulnessLocalParseFallback) === true;
|
|
121
|
+
|
|
108
122
|
return {
|
|
109
123
|
extractionFaithfulnessGate,
|
|
110
124
|
extractionFaithfulnessModel,
|
|
111
125
|
extractionFaithfulnessBaseUrl,
|
|
112
126
|
extractionFaithfulnessContextChars,
|
|
113
127
|
extractionFaithfulnessTimeoutMs,
|
|
128
|
+
extractionFaithfulnessLocalParseFallback,
|
|
114
129
|
};
|
|
115
130
|
}
|
|
116
131
|
|
|
@@ -42,10 +42,15 @@ export interface EndpointChatMessage {
|
|
|
42
42
|
|
|
43
43
|
/** Options for a single local-endpoint chat call. */
|
|
44
44
|
export interface EndpointChatOptions {
|
|
45
|
-
/** Per-call timeout in ms.
|
|
46
|
-
* (matches the local-LLM precedent
|
|
47
|
-
* timer so one slow server can't starve the batch). */
|
|
45
|
+
/** Per-call timeout in ms. Bounds each attempt so one slow server can't
|
|
46
|
+
* starve the batch (matches the local-LLM precedent). */
|
|
48
47
|
timeoutMs: number;
|
|
48
|
+
/** Optional batch AbortSignal forwarded into the probe (issue #1700 nit #5).
|
|
49
|
+
* When the batch budget elapses (or the caller aborts), the in-flight probe
|
|
50
|
+
* aborts immediately instead of waiting for its own `timeoutMs` — a
|
|
51
|
+
* micro-optimization, not a correctness fix (the outer race already bounds
|
|
52
|
+
* the total). Undefined preserves the prior per-attempt-only behavior. */
|
|
53
|
+
signal?: AbortSignal;
|
|
49
54
|
/** Sampling temperature — classification wants low entropy (0.0–0.2). */
|
|
50
55
|
temperature?: number;
|
|
51
56
|
/** Max output tokens. */
|
|
@@ -119,6 +124,21 @@ export async function callOpenAiCompatibleChat(
|
|
|
119
124
|
const url = joinBaseUrl(endpoint.baseUrl, "/chat/completions");
|
|
120
125
|
const controller = new AbortController();
|
|
121
126
|
const timer = setTimeout(() => controller.abort(), options.timeoutMs);
|
|
127
|
+
// Forward the batch AbortSignal into the probe (issue #1700 nit #5): if the
|
|
128
|
+
// batch budget already elapsed, abort the in-flight probe immediately rather
|
|
129
|
+
// than waiting for the probe's own timeoutMs. AbortSignal.any is ES2024
|
|
130
|
+
// (forbidden here); wire the listener manually + guard the already-aborted
|
|
131
|
+
// case. The fetch still uses the probe's controller, so clearing the timer
|
|
132
|
+
// below is the only cleanup needed.
|
|
133
|
+
const batchSignal = options.signal;
|
|
134
|
+
const onBatchAbort = () => controller.abort();
|
|
135
|
+
if (batchSignal) {
|
|
136
|
+
if (batchSignal.aborted) {
|
|
137
|
+
controller.abort();
|
|
138
|
+
} else {
|
|
139
|
+
batchSignal.addEventListener("abort", onBatchAbort, { once: true });
|
|
140
|
+
}
|
|
141
|
+
}
|
|
122
142
|
try {
|
|
123
143
|
const body: Record<string, unknown> = {
|
|
124
144
|
model: endpoint.model,
|
|
@@ -150,6 +170,7 @@ export async function callOpenAiCompatibleChat(
|
|
|
150
170
|
return { content, modelUsed: extractModel(parsed) ?? endpoint.model };
|
|
151
171
|
} finally {
|
|
152
172
|
clearTimeout(timer);
|
|
173
|
+
if (batchSignal) batchSignal.removeEventListener("abort", onBatchAbort);
|
|
153
174
|
}
|
|
154
175
|
}
|
|
155
176
|
|