@remnic/core 1.1.0 → 1.1.1
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-audit.d.ts +56 -0
- package/dist/access-audit.js +9 -0
- package/dist/access-cli.js +62 -45
- package/dist/access-cli.js.map +1 -1
- package/dist/access-http.d.ts +16 -9
- package/dist/access-http.js +25 -17
- package/dist/access-mcp.d.ts +16 -9
- package/dist/access-mcp.js +29 -7
- package/dist/access-schema.d.ts +124 -33
- package/dist/access-schema.js +5 -1
- package/dist/{access-service-HmO1Trrx.d.ts → access-service-Br8ZydTK.d.ts} +158 -63
- package/dist/access-service.d.ts +13 -6
- package/dist/access-service.js +22 -14
- package/dist/bootstrap.d.ts +6 -3
- package/dist/briefing.d.ts +1 -0
- package/dist/briefing.js +7 -6
- package/dist/buffer-surprise-report.d.ts +70 -0
- package/dist/buffer-surprise-report.js +7 -0
- package/dist/buffer-surprise-report.js.map +1 -0
- package/dist/buffer-surprise.d.ts +98 -0
- package/dist/buffer-surprise.js +11 -0
- package/dist/buffer-surprise.js.map +1 -0
- package/dist/buffer.d.ts +100 -2
- package/dist/buffer.js +1 -1
- package/dist/calibration.js +5 -5
- package/dist/causal-behavior.js +4 -4
- package/dist/causal-chain.js +2 -2
- package/dist/causal-consolidation.js +17 -16
- package/dist/causal-consolidation.js.map +1 -1
- package/dist/causal-retrieval.js +4 -4
- package/dist/causal-trajectory.js +1 -1
- package/dist/{chunk-QNJMBKFK.js → chunk-2LGMW3DJ.js} +3 -2
- package/dist/chunk-2LGMW3DJ.js.map +1 -0
- package/dist/{chunk-QDYXG4CS.js → chunk-3FPTCC3Z.js} +4 -3
- package/dist/chunk-3FPTCC3Z.js.map +1 -0
- package/dist/chunk-3GPTTA4J.js +57 -0
- package/dist/chunk-3GPTTA4J.js.map +1 -0
- package/dist/{chunk-44ICJRF3.js → chunk-3GXCSUXR.js} +4 -4
- package/dist/{chunk-ITRLGI2T.js → chunk-3OGMS3PE.js} +2 -2
- package/dist/chunk-54V4BZWP.js +139 -0
- package/dist/chunk-54V4BZWP.js.map +1 -0
- package/dist/chunk-5JRF2PZA.js +67 -0
- package/dist/chunk-5JRF2PZA.js.map +1 -0
- package/dist/chunk-64NJRYU2.js +332 -0
- package/dist/chunk-64NJRYU2.js.map +1 -0
- package/dist/{chunk-OIT5QGG4.js → chunk-6AUUAZEX.js} +72 -2
- package/dist/chunk-6AUUAZEX.js.map +1 -0
- package/dist/{chunk-ZVBB3T7V.js → chunk-7I7FKFZH.js} +24 -22
- package/dist/chunk-7I7FKFZH.js.map +1 -0
- package/dist/chunk-AJU4PJGY.js +126 -0
- package/dist/chunk-AJU4PJGY.js.map +1 -0
- package/dist/chunk-ASAITVLA.js +64 -0
- package/dist/chunk-ASAITVLA.js.map +1 -0
- package/dist/{chunk-3QHL5ABG.js → chunk-B5WXLVDY.js} +187 -6
- package/dist/chunk-B5WXLVDY.js.map +1 -0
- package/dist/{chunk-SYUK3VLY.js → chunk-BGJGXLZ7.js} +111 -2
- package/dist/{chunk-SYUK3VLY.js.map → chunk-BGJGXLZ7.js.map} +1 -1
- package/dist/{chunk-MBJHSA7F.js → chunk-BK2EFTE2.js} +258 -13
- package/dist/chunk-BK2EFTE2.js.map +1 -0
- package/dist/chunk-C4SQJZAF.js +486 -0
- package/dist/chunk-C4SQJZAF.js.map +1 -0
- package/dist/{chunk-6UJ47TVX.js → chunk-CUPFXL3J.js} +2 -2
- package/dist/chunk-DF3RVK3X.js +119 -0
- package/dist/chunk-DF3RVK3X.js.map +1 -0
- package/dist/{chunk-37UIFYWO.js → chunk-DFTTJYSO.js} +108 -9
- package/dist/chunk-DFTTJYSO.js.map +1 -0
- package/dist/chunk-DGVM5SFL.js +69 -0
- package/dist/chunk-DGVM5SFL.js.map +1 -0
- package/dist/chunk-EIR5VLIH.js +90 -0
- package/dist/chunk-EIR5VLIH.js.map +1 -0
- package/dist/{chunk-PAORGQRI.js → chunk-EPQJM2GC.js} +37 -23
- package/dist/chunk-EPQJM2GC.js.map +1 -0
- package/dist/{chunk-GV6NLQ4X.js → chunk-F5VP6YCB.js} +374 -16
- package/dist/chunk-F5VP6YCB.js.map +1 -0
- package/dist/{chunk-6ZH4TU6I.js → chunk-FAAFWE4G.js} +2 -1
- package/dist/chunk-FAAFWE4G.js.map +1 -0
- package/dist/{chunk-7WQ6SLIE.js → chunk-FVA6TGI3.js} +2 -2
- package/dist/chunk-GDFS42HT.js +206 -0
- package/dist/chunk-GDFS42HT.js.map +1 -0
- package/dist/{chunk-MVTHXUBX.js → chunk-GKFXUTJ2.js} +479 -20
- package/dist/chunk-GKFXUTJ2.js.map +1 -0
- package/dist/{chunk-NQEVYWX6.js → chunk-HK3FGIEW.js} +209 -5
- package/dist/chunk-HK3FGIEW.js.map +1 -0
- package/dist/chunk-IISBCCWR.js +52 -0
- package/dist/chunk-IISBCCWR.js.map +1 -0
- package/dist/{chunk-WBSAYXVI.js → chunk-INXV5JBT.js} +198 -42
- package/dist/chunk-INXV5JBT.js.map +1 -0
- package/dist/chunk-JBMSGZEQ.js +441 -0
- package/dist/chunk-JBMSGZEQ.js.map +1 -0
- package/dist/{chunk-J4IYOZZ5.js → chunk-JXS5PDQ7.js} +3 -1
- package/dist/chunk-JXS5PDQ7.js.map +1 -0
- package/dist/{chunk-6LX5ORAS.js → chunk-KUB6JU6H.js} +4 -4
- package/dist/chunk-KVBLZUKV.js +173 -0
- package/dist/chunk-KVBLZUKV.js.map +1 -0
- package/dist/chunk-LBLXEFWK.js +51 -0
- package/dist/chunk-LBLXEFWK.js.map +1 -0
- package/dist/{chunk-3WHVNEN7.js → chunk-LTCGGW2D.js} +1 -1
- package/dist/chunk-LTCGGW2D.js.map +1 -0
- package/dist/{chunk-UEYA6UC7.js → chunk-NZLQTHS5.js} +25 -2
- package/dist/chunk-NZLQTHS5.js.map +1 -0
- package/dist/chunk-PVPWZSSI.js +37 -0
- package/dist/chunk-PVPWZSSI.js.map +1 -0
- package/dist/{chunk-4NRAJUDS.js → chunk-RBBWYEFJ.js} +1 -1
- package/dist/chunk-RFYAYKTD.js +146 -0
- package/dist/chunk-RFYAYKTD.js.map +1 -0
- package/dist/{chunk-DHHP2Z4X.js → chunk-RGLL5SPU.js} +2 -2
- package/dist/{chunk-3SV6CQHO.js → chunk-S3EEFKNY.js} +101 -65
- package/dist/chunk-S3EEFKNY.js.map +1 -0
- package/dist/chunk-SOBJ6NEY.js +18 -0
- package/dist/chunk-SOBJ6NEY.js.map +1 -0
- package/dist/{chunk-JIU55F3X.js → chunk-SPI27QT6.js} +2 -2
- package/dist/chunk-TVVEYCNW.js +65 -0
- package/dist/chunk-TVVEYCNW.js.map +1 -0
- package/dist/chunk-ULYOGL6R.js +322 -0
- package/dist/chunk-ULYOGL6R.js.map +1 -0
- package/dist/{chunk-47UU5PU2.js → chunk-VBVG2M5G.js} +18 -3
- package/dist/chunk-VBVG2M5G.js.map +1 -0
- package/dist/{chunk-7ECD5ATE.js → chunk-VDX363PS.js} +2 -2
- package/dist/{chunk-DEPL3635.js → chunk-VYM3VWOF.js} +1432 -188
- package/dist/chunk-VYM3VWOF.js.map +1 -0
- package/dist/{chunk-MTLYEMJB.js → chunk-WCLICCGB.js} +18 -3
- package/dist/chunk-WCLICCGB.js.map +1 -0
- package/dist/{chunk-4LACOVZX.js → chunk-WVVA7F5A.js} +2 -2
- package/dist/chunk-X6GF3FX2.js +26 -0
- package/dist/chunk-X6GF3FX2.js.map +1 -0
- package/dist/{chunk-3QFQGRHO.js → chunk-XMHBH5H6.js} +4 -4
- package/dist/{chunk-BLKTA7MM.js → chunk-YNQKWQT4.js} +50 -17
- package/dist/chunk-YNQKWQT4.js.map +1 -0
- package/dist/chunk-ZAIM4TUE.js +488 -0
- package/dist/chunk-ZAIM4TUE.js.map +1 -0
- package/dist/{chunk-N42IWANG.js → chunk-ZEM3OK2K.js} +2 -2
- package/dist/chunk-ZZTOURJI.js +91 -0
- package/dist/chunk-ZZTOURJI.js.map +1 -0
- package/dist/{cli-BneVIEvh.d.ts → cli-BkeRaYfk.d.ts} +2 -2
- package/dist/cli.d.ts +13 -6
- package/dist/cli.js +40 -29
- package/dist/config.js +1 -1
- package/dist/consolidation-operator.d.ts +41 -0
- package/dist/consolidation-operator.js +11 -0
- package/dist/consolidation-operator.js.map +1 -0
- package/dist/consolidation-provenance-check.d.ts +68 -0
- package/dist/consolidation-provenance-check.js +9 -0
- package/dist/consolidation-provenance-check.js.map +1 -0
- package/dist/consolidation-undo.d.ts +123 -0
- package/dist/consolidation-undo.js +426 -0
- package/dist/consolidation-undo.js.map +1 -0
- package/dist/{contradiction-scan-GR33PONM.js → contradiction-scan-E3GJTI4F.js} +43 -7
- package/dist/contradiction-scan-E3GJTI4F.js.map +1 -0
- package/dist/cross-namespace-budget.d.ts +133 -0
- package/dist/cross-namespace-budget.js +9 -0
- package/dist/cross-namespace-budget.js.map +1 -0
- package/dist/direct-answer-wiring.js +5 -70
- package/dist/direct-answer-wiring.js.map +1 -1
- package/dist/{engine-5TIQBYZR.js → engine-F3GOXGE5.js} +8 -7
- package/dist/engine-F3GOXGE5.js.map +1 -0
- package/dist/entity-retrieval.d.ts +1 -0
- package/dist/entity-retrieval.js +7 -6
- package/dist/explicit-capture.d.ts +6 -3
- package/dist/explicit-capture.js +2 -2
- package/dist/extraction-judge-telemetry.d.ts +113 -0
- package/dist/extraction-judge-telemetry.js +14 -0
- package/dist/extraction-judge-telemetry.js.map +1 -0
- package/dist/extraction-judge-training.d.ts +85 -0
- package/dist/extraction-judge-training.js +16 -0
- package/dist/extraction-judge-training.js.map +1 -0
- package/dist/extraction-judge.d.ts +124 -2
- package/dist/extraction-judge.js +11 -1
- package/dist/extraction.js +6 -5
- package/dist/fallback-llm.js +2 -2
- package/dist/graph-recall.d.ts +100 -0
- package/dist/graph-recall.js +8 -0
- package/dist/graph-recall.js.map +1 -0
- package/dist/graph-retrieval.d.ts +271 -0
- package/dist/graph-retrieval.js +21 -0
- package/dist/graph-retrieval.js.map +1 -0
- package/dist/importance.js +1 -1
- package/dist/index.d.ts +585 -20
- package/dist/index.js +503 -312
- package/dist/index.js.map +1 -1
- package/dist/memory-worth-bench.d.ts +51 -0
- package/dist/memory-worth-bench.js +131 -0
- package/dist/memory-worth-bench.js.map +1 -0
- package/dist/memory-worth-filter.d.ts +128 -0
- package/dist/memory-worth-filter.js +10 -0
- package/dist/memory-worth-filter.js.map +1 -0
- package/dist/memory-worth-outcomes.d.ts +118 -0
- package/dist/memory-worth-outcomes.js +9 -0
- package/dist/memory-worth-outcomes.js.map +1 -0
- package/dist/memory-worth.d.ts +102 -0
- package/dist/memory-worth.js +7 -0
- package/dist/memory-worth.js.map +1 -0
- package/dist/operator-toolkit.d.ts +40 -1
- package/dist/operator-toolkit.js +23 -14
- package/dist/{orchestrator-DRYA6_lW.d.ts → orchestrator-CmJ-NTdJ.d.ts} +233 -8
- package/dist/orchestrator.d.ts +6 -3
- package/dist/orchestrator.js +49 -39
- package/dist/page-versioning.d.ts +12 -1
- package/dist/page-versioning.js +5 -3
- package/dist/{port-C1GZFv8h.d.ts → port-BADbLZU5.d.ts} +2 -2
- package/dist/qmd-recall-cache.d.ts +1 -1
- package/dist/qmd.d.ts +5 -3
- package/dist/qmd.js +1 -1
- package/dist/reasoning-trace-recall.d.ts +90 -0
- package/dist/reasoning-trace-recall.js +13 -0
- package/dist/reasoning-trace-recall.js.map +1 -0
- package/dist/reasoning-trace-types.d.ts +54 -0
- package/dist/reasoning-trace-types.js +17 -0
- package/dist/reasoning-trace-types.js.map +1 -0
- package/dist/recall-audit-anomaly.d.ts +112 -0
- package/dist/recall-audit-anomaly.js +11 -0
- package/dist/recall-audit-anomaly.js.map +1 -0
- package/dist/recall-audit.js +5 -44
- package/dist/recall-audit.js.map +1 -1
- package/dist/recall-explain-renderer.d.ts +49 -0
- package/dist/recall-explain-renderer.js +18 -0
- package/dist/recall-explain-renderer.js.map +1 -0
- package/dist/recall-state.d.ts +12 -1
- package/dist/recall-state.js +1 -1
- package/dist/recall-xray-cli.d.ts +40 -0
- package/dist/recall-xray-cli.js +11 -0
- package/dist/recall-xray-cli.js.map +1 -0
- package/dist/recall-xray-renderer.d.ts +44 -0
- package/dist/recall-xray-renderer.js +18 -0
- package/dist/recall-xray-renderer.js.map +1 -0
- package/dist/recall-xray.d.ts +179 -0
- package/dist/recall-xray.js +13 -0
- package/dist/recall-xray.js.map +1 -0
- package/dist/resume-bundles.js +5 -5
- package/dist/retrieval-agents.d.ts +1 -1
- package/dist/retrieval-tiers.d.ts +17 -0
- package/dist/retrieval-tiers.js +9 -0
- package/dist/retrieval-tiers.js.map +1 -0
- package/dist/schemas.d.ts +287 -31
- package/dist/schemas.js +1 -1
- package/dist/{semantic-consolidation-DrvSYRdB.d.ts → semantic-consolidation-CxJU6MJk.d.ts} +62 -1
- package/dist/semantic-consolidation.d.ts +2 -1
- package/dist/semantic-consolidation.js +21 -7
- package/dist/semantic-rule-promotion.js +7 -6
- package/dist/semantic-rule-verifier.js +7 -6
- package/dist/storage.d.ts +82 -1
- package/dist/storage.js +6 -5
- package/dist/summarizer.js +3 -3
- package/dist/temporal-supersession.d.ts +1 -0
- package/dist/tier-migration.d.ts +2 -1
- package/dist/types.d.ts +276 -2
- package/dist/types.js +1 -1
- package/dist/verified-recall.js +7 -6
- package/package.json +1 -1
- package/dist/chunk-37UIFYWO.js.map +0 -1
- package/dist/chunk-3QHL5ABG.js.map +0 -1
- package/dist/chunk-3SV6CQHO.js.map +0 -1
- package/dist/chunk-3WHVNEN7.js.map +0 -1
- package/dist/chunk-47UU5PU2.js.map +0 -1
- package/dist/chunk-6ZH4TU6I.js.map +0 -1
- package/dist/chunk-BLKTA7MM.js.map +0 -1
- package/dist/chunk-DEPL3635.js.map +0 -1
- package/dist/chunk-GV6NLQ4X.js.map +0 -1
- package/dist/chunk-J4IYOZZ5.js.map +0 -1
- package/dist/chunk-LAYN4LDC.js +0 -267
- package/dist/chunk-LAYN4LDC.js.map +0 -1
- package/dist/chunk-MBJHSA7F.js.map +0 -1
- package/dist/chunk-MTLYEMJB.js.map +0 -1
- package/dist/chunk-MVTHXUBX.js.map +0 -1
- package/dist/chunk-NQEVYWX6.js.map +0 -1
- package/dist/chunk-OIT5QGG4.js.map +0 -1
- package/dist/chunk-PAORGQRI.js.map +0 -1
- package/dist/chunk-QDYXG4CS.js.map +0 -1
- package/dist/chunk-QNJMBKFK.js.map +0 -1
- package/dist/chunk-UEYA6UC7.js.map +0 -1
- package/dist/chunk-UVJFDP7P.js +0 -202
- package/dist/chunk-UVJFDP7P.js.map +0 -1
- package/dist/chunk-WBSAYXVI.js.map +0 -1
- package/dist/chunk-ZVBB3T7V.js.map +0 -1
- package/dist/contradiction-scan-GR33PONM.js.map +0 -1
- /package/dist/{engine-5TIQBYZR.js.map → access-audit.js.map} +0 -0
- /package/dist/{chunk-44ICJRF3.js.map → chunk-3GXCSUXR.js.map} +0 -0
- /package/dist/{chunk-ITRLGI2T.js.map → chunk-3OGMS3PE.js.map} +0 -0
- /package/dist/{chunk-6UJ47TVX.js.map → chunk-CUPFXL3J.js.map} +0 -0
- /package/dist/{chunk-7WQ6SLIE.js.map → chunk-FVA6TGI3.js.map} +0 -0
- /package/dist/{chunk-6LX5ORAS.js.map → chunk-KUB6JU6H.js.map} +0 -0
- /package/dist/{chunk-4NRAJUDS.js.map → chunk-RBBWYEFJ.js.map} +0 -0
- /package/dist/{chunk-DHHP2Z4X.js.map → chunk-RGLL5SPU.js.map} +0 -0
- /package/dist/{chunk-JIU55F3X.js.map → chunk-SPI27QT6.js.map} +0 -0
- /package/dist/{chunk-7ECD5ATE.js.map → chunk-VDX363PS.js.map} +0 -0
- /package/dist/{chunk-4LACOVZX.js.map → chunk-WVVA7F5A.js.map} +0 -0
- /package/dist/{chunk-3QFQGRHO.js.map → chunk-XMHBH5H6.js.map} +0 -0
- /package/dist/{chunk-N42IWANG.js.map → chunk-ZEM3OK2K.js.map} +0 -0
package/dist/types.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
type ReasoningEffort = "none" | "low" | "medium" | "high";
|
|
2
2
|
type TriggerMode = "smart" | "every_n" | "time_based";
|
|
3
3
|
type SignalLevel = "none" | "low" | "medium" | "high";
|
|
4
|
-
type MemoryCategory = "fact" | "preference" | "correction" | "entity" | "decision" | "relationship" | "principle" | "commitment" | "moment" | "skill" | "rule" | "procedure";
|
|
4
|
+
type MemoryCategory = "fact" | "preference" | "correction" | "entity" | "decision" | "relationship" | "principle" | "commitment" | "moment" | "skill" | "rule" | "procedure" | "reasoning_trace";
|
|
5
5
|
type ConsolidationAction = "ADD" | "MERGE" | "UPDATE" | "INVALIDATE" | "SKIP";
|
|
6
6
|
type ConfidenceTier = "explicit" | "implied" | "inferred" | "speculative";
|
|
7
7
|
type PrincipalFromSessionKeyMode = "map" | "prefix" | "regex";
|
|
@@ -165,6 +165,48 @@ interface ProceduralConfig {
|
|
|
165
165
|
/** Max procedure memories to inject on task-initiation recall (1–10). */
|
|
166
166
|
recallMaxProcedures: number;
|
|
167
167
|
}
|
|
168
|
+
/**
|
|
169
|
+
* Coding-agent mode config (issue #569).
|
|
170
|
+
*
|
|
171
|
+
* When the connector provides a `CodingContext` (see below), Remnic overlays
|
|
172
|
+
* a project- and/or branch-scoped namespace on top of the principal's default
|
|
173
|
+
* namespace so that memories written while working on project A do not surface
|
|
174
|
+
* while working on project B.
|
|
175
|
+
*
|
|
176
|
+
* Both flags default off-for-branch / on-for-project. Per CLAUDE.md #30 every
|
|
177
|
+
* filter or transform needs an escape hatch: set `projectScope: false` to
|
|
178
|
+
* exactly restore pre-#569 behaviour.
|
|
179
|
+
*/
|
|
180
|
+
interface CodingModeConfig {
|
|
181
|
+
/**
|
|
182
|
+
* When true (default), a session with a resolved `CodingContext` uses a
|
|
183
|
+
* project-scoped namespace. When false, the principal's default namespace
|
|
184
|
+
* is used unchanged (pre-#569 behaviour).
|
|
185
|
+
*/
|
|
186
|
+
projectScope: boolean;
|
|
187
|
+
/**
|
|
188
|
+
* When true, recall/write also overlay the current branch on top of the
|
|
189
|
+
* project namespace. Default false — branch-scope is opt-in because active
|
|
190
|
+
* development typically wants recall across branches. (Wired by PR 3 of
|
|
191
|
+
* issue #569; declared here so the schema ships in one slice.)
|
|
192
|
+
*/
|
|
193
|
+
branchScope: boolean;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Session-scoped coding context. Produced by `resolveGitContext()` in the
|
|
197
|
+
* connector layer and attached to a session so that recall + write paths can
|
|
198
|
+
* compute an overlay namespace.
|
|
199
|
+
*
|
|
200
|
+
* All fields mirror `GitContext` from `./coding/git-context.ts`; kept as a
|
|
201
|
+
* separate interface because `types.ts` must stay dependency-free (it is
|
|
202
|
+
* imported by every other module).
|
|
203
|
+
*/
|
|
204
|
+
interface CodingContext {
|
|
205
|
+
projectId: string;
|
|
206
|
+
branch: string | null;
|
|
207
|
+
rootPath: string;
|
|
208
|
+
defaultBranch: string | null;
|
|
209
|
+
}
|
|
168
210
|
/** Configuration for the nightly contradiction-scan cron (issue #520). */
|
|
169
211
|
interface ContradictionScanConfig {
|
|
170
212
|
/** Master switch for the contradiction scan cron. Default true. */
|
|
@@ -223,6 +265,47 @@ interface PluginConfig {
|
|
|
223
265
|
triggerMode: TriggerMode;
|
|
224
266
|
bufferMaxTurns: number;
|
|
225
267
|
bufferMaxMinutes: number;
|
|
268
|
+
/**
|
|
269
|
+
* Surprise-gated buffer flush (issue #563, D-MEM).
|
|
270
|
+
*
|
|
271
|
+
* When enabled, every turn added to the smart buffer is scored against a
|
|
272
|
+
* configurable window of recent memories using an embedding-distance proxy
|
|
273
|
+
* for novelty (see `buffer-surprise.ts`). A turn whose surprise score
|
|
274
|
+
* exceeds `bufferSurpriseThreshold` triggers an immediate extract flush,
|
|
275
|
+
* even if the existing signal/turn-count/time triggers would otherwise keep
|
|
276
|
+
* buffering. Disabled by default — when `false`, buffer behavior is
|
|
277
|
+
* identical to pre-#563 code. Additive only: existing triggers are never
|
|
278
|
+
* suppressed by this flag.
|
|
279
|
+
*/
|
|
280
|
+
bufferSurpriseTriggerEnabled: boolean;
|
|
281
|
+
/**
|
|
282
|
+
* Threshold in `[0, 1]` above which a surprise score causes an immediate
|
|
283
|
+
* flush. `0.35` is a conservative default chosen to favor precision over
|
|
284
|
+
* recall during the opt-in phase. Ignored unless
|
|
285
|
+
* `bufferSurpriseTriggerEnabled` is `true`.
|
|
286
|
+
*/
|
|
287
|
+
bufferSurpriseThreshold: number;
|
|
288
|
+
/**
|
|
289
|
+
* Number of nearest neighbors to average over when computing the surprise
|
|
290
|
+
* score (see `computeSurprise`). Default `5`. Clamped to the recent-memory
|
|
291
|
+
* window size at call time.
|
|
292
|
+
*/
|
|
293
|
+
bufferSurpriseK: number;
|
|
294
|
+
/**
|
|
295
|
+
* Maximum number of recent memories to sample when computing the surprise
|
|
296
|
+
* score. Bounds embedding cost per turn. Default `20`. Set to `0` to
|
|
297
|
+
* disable the trigger even when the flag is on (no memories to compare
|
|
298
|
+
* against → treat as not-applicable rather than maximally surprising).
|
|
299
|
+
*/
|
|
300
|
+
bufferSurpriseRecentMemoryCount: number;
|
|
301
|
+
/**
|
|
302
|
+
* Hard timeout (ms) for the surprise probe. If the probe does not
|
|
303
|
+
* resolve within this window, the buffer treats the probe as failed,
|
|
304
|
+
* logs at debug, and falls through to the existing triggers. Ensures
|
|
305
|
+
* a slow or hung embedder cannot stall the turn-append path. Default
|
|
306
|
+
* `2000` (2s).
|
|
307
|
+
*/
|
|
308
|
+
bufferSurpriseProbeTimeoutMs: number;
|
|
226
309
|
consolidateEveryN: number;
|
|
227
310
|
highSignalPatterns: string[];
|
|
228
311
|
maxMemoryTokens: number;
|
|
@@ -318,6 +401,22 @@ interface PluginConfig {
|
|
|
318
401
|
* Default false — enable explicitly after bench validation.
|
|
319
402
|
*/
|
|
320
403
|
recallDirectAnswerEnabled: boolean;
|
|
404
|
+
/**
|
|
405
|
+
* Graph-based retrieval tier via Personalized PageRank (issue #559 PR 4).
|
|
406
|
+
* When true, recall builds a retrieval graph from memory frontmatter
|
|
407
|
+
* and runs PPR, merging the result with QMD via MMR. Default false —
|
|
408
|
+
* ships off pending the retrieval-graph bench in PR 5.
|
|
409
|
+
*/
|
|
410
|
+
recallGraphEnabled: boolean;
|
|
411
|
+
/** PPR damping factor used when `recallGraphEnabled` is true. */
|
|
412
|
+
recallGraphDamping: number;
|
|
413
|
+
/** PPR power-iteration cap used when `recallGraphEnabled` is true. */
|
|
414
|
+
recallGraphIterations: number;
|
|
415
|
+
/**
|
|
416
|
+
* Max memories returned by the graph tier before MMR. Set to 0 to
|
|
417
|
+
* disable the graph tier's contribution without flipping the flag.
|
|
418
|
+
*/
|
|
419
|
+
recallGraphTopK: number;
|
|
321
420
|
/**
|
|
322
421
|
* Minimum token-overlap ratio (query tokens ∩ memory tokens / query tokens)
|
|
323
422
|
* required for direct-answer eligibility. Set to 0 to disable the gate.
|
|
@@ -338,6 +437,56 @@ interface PluginConfig {
|
|
|
338
437
|
* whose resolved taxonomy category is not in this list never qualify.
|
|
339
438
|
*/
|
|
340
439
|
recallDirectAnswerEligibleTaxonomyBuckets: string[];
|
|
440
|
+
/**
|
|
441
|
+
* Cross-namespace query-budget limiter (issue #565 PR 4/5). When true,
|
|
442
|
+
* a principal that issues a burst of recalls against namespaces other
|
|
443
|
+
* than their own is throttled once its per-window count crosses
|
|
444
|
+
* `recallCrossNamespaceBudgetHardLimit`. Default false — ships disabled.
|
|
445
|
+
*/
|
|
446
|
+
recallCrossNamespaceBudgetEnabled: boolean;
|
|
447
|
+
/** Rolling window in milliseconds over which cross-namespace reads are counted. */
|
|
448
|
+
recallCrossNamespaceBudgetWindowMs: number;
|
|
449
|
+
/**
|
|
450
|
+
* Soft threshold — the first point at which the limiter flags a burst.
|
|
451
|
+
* Calls are still allowed; anomaly detection (issue #565 PR 5) will
|
|
452
|
+
* surface the warning.
|
|
453
|
+
*/
|
|
454
|
+
recallCrossNamespaceBudgetSoftLimit: number;
|
|
455
|
+
/** Hard threshold — calls past this count are denied in the window. */
|
|
456
|
+
recallCrossNamespaceBudgetHardLimit: number;
|
|
457
|
+
/**
|
|
458
|
+
* When true, recall multiplies candidate scores by the Memory Worth
|
|
459
|
+
* factor computed from `mw_success` / `mw_fail` counters on each
|
|
460
|
+
* memory's frontmatter (see `computeMemoryWorth`). Memories with a
|
|
461
|
+
* history of failed sessions sink; neutral / uninstrumented memories
|
|
462
|
+
* are untouched (multiplier 1.0). Default false — flip to true in PR 5
|
|
463
|
+
* once the benchmark shows precision tie-or-win.
|
|
464
|
+
*/
|
|
465
|
+
recallMemoryWorthFilterEnabled: boolean;
|
|
466
|
+
/**
|
|
467
|
+
* Recall-audit anomaly detector (issue #565 PR 5/5). When true,
|
|
468
|
+
* access surfaces run the anomaly detector over a tail of the audit
|
|
469
|
+
* trail after each recall and surface any flags via logs / metrics.
|
|
470
|
+
* Ships disabled.
|
|
471
|
+
*/
|
|
472
|
+
recallAuditAnomalyDetectionEnabled: boolean;
|
|
473
|
+
/** Rolling window over which audit entries are analyzed. */
|
|
474
|
+
recallAuditAnomalyWindowMs: number;
|
|
475
|
+
/** Threshold for the `repeat-query` flag. */
|
|
476
|
+
recallAuditAnomalyRepeatQueryLimit: number;
|
|
477
|
+
/** Threshold for the `namespace-walk` flag (distinct namespaces). */
|
|
478
|
+
recallAuditAnomalyNamespaceWalkLimit: number;
|
|
479
|
+
/** Threshold for the `high-cardinality-return` flag. */
|
|
480
|
+
recallAuditAnomalyHighCardinalityLimit: number;
|
|
481
|
+
/** Threshold for the `rapid-fire` flag. */
|
|
482
|
+
recallAuditAnomalyRapidFireLimit: number;
|
|
483
|
+
/**
|
|
484
|
+
* Optional half-life for Memory Worth decay, in milliseconds. When
|
|
485
|
+
* positive, older outcome observations are exponentially decayed toward
|
|
486
|
+
* the uniform prior. Set to 0 (default) to disable decay and use raw
|
|
487
|
+
* counter values.
|
|
488
|
+
*/
|
|
489
|
+
recallMemoryWorthHalfLifeMs: number;
|
|
341
490
|
memoryLinkingEnabled: boolean;
|
|
342
491
|
threadingEnabled: boolean;
|
|
343
492
|
threadingGapMinutes: number;
|
|
@@ -394,6 +543,7 @@ interface PluginConfig {
|
|
|
394
543
|
activeRecallAllowChainedActiveMemory: boolean;
|
|
395
544
|
dreaming: DreamingConfig;
|
|
396
545
|
procedural: ProceduralConfig;
|
|
546
|
+
codingMode: CodingModeConfig;
|
|
397
547
|
heartbeat: HeartbeatConfig;
|
|
398
548
|
slotBehavior: SlotBehaviorConfig;
|
|
399
549
|
codexCompat: CodexCompatConfig;
|
|
@@ -405,6 +555,35 @@ interface PluginConfig {
|
|
|
405
555
|
extractionJudgeBatchSize: number;
|
|
406
556
|
/** Shadow mode: log judge verdicts but do not filter facts. Default false. */
|
|
407
557
|
extractionJudgeShadow: boolean;
|
|
558
|
+
/**
|
|
559
|
+
* Maximum number of times the same candidate text may be deferred before
|
|
560
|
+
* the judge forcibly converts the verdict to `"reject"`. Prevents
|
|
561
|
+
* pathological LLM responses from looping forever on ambiguous facts.
|
|
562
|
+
* Defaults to 2 (issue #562, PR 2).
|
|
563
|
+
*/
|
|
564
|
+
extractionJudgeMaxDeferrals: number;
|
|
565
|
+
/**
|
|
566
|
+
* Emit structured telemetry rows to
|
|
567
|
+
* `state/observation-ledger/extraction-judge-verdicts.jsonl` on every
|
|
568
|
+
* judge verdict. Off by default; enable to collect defer-rate / latency
|
|
569
|
+
* metrics for operator dashboards (issue #562, PR 3).
|
|
570
|
+
*/
|
|
571
|
+
extractionJudgeTelemetryEnabled: boolean;
|
|
572
|
+
/**
|
|
573
|
+
* Collect `(candidate_text, verdict_kind, reason)` tuples into
|
|
574
|
+
* `~/.remnic/judge-training/<date>.jsonl` for use by a future GRPO
|
|
575
|
+
* training pipeline (issue #562, PR 4). Off by default. Rows live in
|
|
576
|
+
* the user's home directory rather than the shared memory directory so
|
|
577
|
+
* they are not committed, sync'd, or bundled into memory exports.
|
|
578
|
+
*/
|
|
579
|
+
collectJudgeTrainingPairs: boolean;
|
|
580
|
+
/**
|
|
581
|
+
* Override directory for judge training-pair collection. Empty string
|
|
582
|
+
* means use the default (`~/.remnic/judge-training`). Primarily for
|
|
583
|
+
* tests and for operators who want the output to land in a specific
|
|
584
|
+
* location.
|
|
585
|
+
*/
|
|
586
|
+
judgeTrainingDir: string;
|
|
408
587
|
hourlySummariesEnabled: boolean;
|
|
409
588
|
daySummaryEnabled: boolean;
|
|
410
589
|
/** If true, Engram may attempt to auto-register an hourly summary cron job (default off). */
|
|
@@ -469,6 +648,15 @@ interface PluginConfig {
|
|
|
469
648
|
semanticConsolidationExcludeCategories: string[];
|
|
470
649
|
semanticConsolidationIntervalHours: number;
|
|
471
650
|
semanticConsolidationMaxPerRun: number;
|
|
651
|
+
/**
|
|
652
|
+
* When true (default), semantic-consolidation prompts the LLM with an
|
|
653
|
+
* operator-aware format asking for JSON `{operator, output}` and records
|
|
654
|
+
* the resulting SPLIT/MERGE/UPDATE operator on `derived_via`. When
|
|
655
|
+
* false, falls back to the legacy plain-text prompt — `derived_via` is
|
|
656
|
+
* still populated via the cluster-shape heuristic in
|
|
657
|
+
* `chooseConsolidationOperator`. Issue #561 PR 3.
|
|
658
|
+
*/
|
|
659
|
+
operatorAwareConsolidationEnabled: boolean;
|
|
472
660
|
creationMemoryEnabled: boolean;
|
|
473
661
|
memoryUtilityLearningEnabled: boolean;
|
|
474
662
|
promotionByOutcomeEnabled: boolean;
|
|
@@ -690,6 +878,13 @@ interface PluginConfig {
|
|
|
690
878
|
recallMmrLambda: number;
|
|
691
879
|
/** MMR is applied over the top N candidates per section. Default 40. */
|
|
692
880
|
recallMmrTopN: number;
|
|
881
|
+
/**
|
|
882
|
+
* Boost stored `reasoning_trace` memories in recall results when the
|
|
883
|
+
* incoming query reads like a problem-solving ask (e.g. "how do I…",
|
|
884
|
+
* "step by step", "walk me through…"). Default false — opt in after
|
|
885
|
+
* benchmarking (issue #564 PR 3).
|
|
886
|
+
*/
|
|
887
|
+
recallReasoningTraceBoostEnabled: boolean;
|
|
693
888
|
qmdRecallCacheTtlMs: number;
|
|
694
889
|
qmdRecallCacheStaleTtlMs: number;
|
|
695
890
|
qmdRecallCacheMaxEntries: number;
|
|
@@ -1111,6 +1306,13 @@ interface BufferEntryState {
|
|
|
1111
1306
|
turns: BufferTurn[];
|
|
1112
1307
|
lastExtractionAt: string | null;
|
|
1113
1308
|
extractionCount: number;
|
|
1309
|
+
/**
|
|
1310
|
+
* Turns retained across `clearAfterExtraction` so a later extraction pass
|
|
1311
|
+
* sees the context that caused a defer verdict (issue #562, PR 2). Bounded
|
|
1312
|
+
* to the configured retention cap by `retainDeferredTurns`. Empty / absent
|
|
1313
|
+
* means no retention in effect.
|
|
1314
|
+
*/
|
|
1315
|
+
retainedTurns?: BufferTurn[];
|
|
1114
1316
|
}
|
|
1115
1317
|
interface BufferState {
|
|
1116
1318
|
turns: BufferTurn[];
|
|
@@ -1150,6 +1352,40 @@ interface BehaviorSignalEvent {
|
|
|
1150
1352
|
signalHash: string;
|
|
1151
1353
|
source: "extraction" | "correction";
|
|
1152
1354
|
}
|
|
1355
|
+
/**
|
|
1356
|
+
* One row of the buffer-surprise telemetry ledger (issue #563 PR 3).
|
|
1357
|
+
*
|
|
1358
|
+
* Emitted by `SmartBuffer` each time the surprise probe produces a score
|
|
1359
|
+
* for an incoming turn (i.e. the feature flag is on and the existing
|
|
1360
|
+
* trigger-logic path called through to the probe). Not written when the
|
|
1361
|
+
* probe is skipped — the absence of a row is meaningful and matches the
|
|
1362
|
+
* "probe was not consulted" state.
|
|
1363
|
+
*
|
|
1364
|
+
* The ledger is intentionally lean: we record the score, the threshold in
|
|
1365
|
+
* force, whether the turn caused a flush, and the turn count so operators
|
|
1366
|
+
* can re-derive precision/recall without replaying traffic. Turn content
|
|
1367
|
+
* is never persisted — this ledger is safe to commit to shared storage.
|
|
1368
|
+
*/
|
|
1369
|
+
interface BufferSurpriseEvent {
|
|
1370
|
+
/** Literal tag to simplify multiplexed log consumers. */
|
|
1371
|
+
event: "BUFFER_SURPRISE";
|
|
1372
|
+
/** ISO timestamp when the decision was made. Server-side, not turn ts. */
|
|
1373
|
+
timestamp: string;
|
|
1374
|
+
/** Buffer identifier (session / thread). Opaque string. */
|
|
1375
|
+
bufferKey: string;
|
|
1376
|
+
/** Session key if available; null when the turn has no session binding. */
|
|
1377
|
+
sessionKey: string | null;
|
|
1378
|
+
/** Role of the scored turn. */
|
|
1379
|
+
turnRole: "user" | "assistant";
|
|
1380
|
+
/** Surprise score in `[0, 1]`, already clamped. */
|
|
1381
|
+
surpriseScore: number;
|
|
1382
|
+
/** Threshold in force when the decision was made. */
|
|
1383
|
+
threshold: number;
|
|
1384
|
+
/** Whether this turn upgraded `keep_buffering` → `extract_now`. */
|
|
1385
|
+
triggeredFlush: boolean;
|
|
1386
|
+
/** Number of turns in the buffer (including the current turn). */
|
|
1387
|
+
turnCountInWindow: number;
|
|
1388
|
+
}
|
|
1153
1389
|
/** Memory status for lifecycle management */
|
|
1154
1390
|
type MemoryStatus = "active" | "pending_review" | "rejected" | "quarantined" | "superseded" | "archived";
|
|
1155
1391
|
type LifecycleState = "candidate" | "validated" | "active" | "stale" | "archived";
|
|
@@ -1207,6 +1443,10 @@ interface MemoryFrontmatter {
|
|
|
1207
1443
|
accessCount?: number;
|
|
1208
1444
|
/** Last time this memory was accessed (ISO 8601) */
|
|
1209
1445
|
lastAccessed?: string;
|
|
1446
|
+
/** Number of sessions where this memory was retrieved and the outcome was judged a success. */
|
|
1447
|
+
mw_success?: number;
|
|
1448
|
+
/** Number of sessions where this memory was retrieved and the outcome was judged a failure. */
|
|
1449
|
+
mw_fail?: number;
|
|
1210
1450
|
/** Importance score with level, reasons, and keywords */
|
|
1211
1451
|
importance?: ImportanceScore;
|
|
1212
1452
|
/** Parent memory ID if this is a chunk */
|
|
@@ -1238,6 +1478,26 @@ interface MemoryFrontmatter {
|
|
|
1238
1478
|
* [Source: ...] format and silently fails for custom citation templates.
|
|
1239
1479
|
*/
|
|
1240
1480
|
contentHash?: string;
|
|
1481
|
+
/**
|
|
1482
|
+
* Consolidation provenance — pointers to the page-versioning snapshots
|
|
1483
|
+
* that this memory was derived from (issue #561). Each entry is a
|
|
1484
|
+
* `"<memory-path>:<version-number>"` string (e.g.
|
|
1485
|
+
* `"facts/preferences.md:3"`) referencing a snapshot recorded by
|
|
1486
|
+
* `page-versioning.ts`.
|
|
1487
|
+
*
|
|
1488
|
+
* PR 1 introduces this field as read-through only — storage preserves
|
|
1489
|
+
* it verbatim but no code produces it yet. PR 2 populates it on
|
|
1490
|
+
* consolidation writes; PR 4 adds a `remnic doctor` integrity check
|
|
1491
|
+
* that validates each referent actually exists.
|
|
1492
|
+
*/
|
|
1493
|
+
derived_from?: string[];
|
|
1494
|
+
/**
|
|
1495
|
+
* Which consolidation operator produced this memory (issue #561). See
|
|
1496
|
+
* `ConsolidationOperator` in `semantic-consolidation.ts` for the
|
|
1497
|
+
* operator algebra. Absent on memories that were not produced by a
|
|
1498
|
+
* consolidation pass.
|
|
1499
|
+
*/
|
|
1500
|
+
derived_via?: "split" | "merge" | "update";
|
|
1241
1501
|
}
|
|
1242
1502
|
/** Memory link relationship types */
|
|
1243
1503
|
type MemoryLinkType = "follows" | "references" | "contradicts" | "supports" | "related";
|
|
@@ -1306,6 +1566,20 @@ interface ExtractedFact {
|
|
|
1306
1566
|
structuredAttributes?: Record<string, string>;
|
|
1307
1567
|
/** When category is `procedure`, ordered steps with intents (persisted under procedures/). */
|
|
1308
1568
|
procedureSteps?: ExtractedProcedureStep[];
|
|
1569
|
+
/**
|
|
1570
|
+
* When category is `reasoning_trace`, the stored solution chain the user
|
|
1571
|
+
* walked through. Persisted under reasoning-traces/.
|
|
1572
|
+
*/
|
|
1573
|
+
reasoningTrace?: ExtractedReasoningTrace;
|
|
1574
|
+
}
|
|
1575
|
+
interface ExtractedReasoningTraceStep {
|
|
1576
|
+
order: number;
|
|
1577
|
+
description: string;
|
|
1578
|
+
}
|
|
1579
|
+
interface ExtractedReasoningTrace {
|
|
1580
|
+
steps: ExtractedReasoningTraceStep[];
|
|
1581
|
+
finalAnswer: string;
|
|
1582
|
+
observedOutcome?: string;
|
|
1309
1583
|
}
|
|
1310
1584
|
interface MemoryIntent {
|
|
1311
1585
|
goal: string;
|
|
@@ -1766,4 +2040,4 @@ interface HourlySummary {
|
|
|
1766
2040
|
generatedAt: string;
|
|
1767
2041
|
}
|
|
1768
2042
|
|
|
1769
|
-
export { type AccessTrackingEntry, type ActiveRecallChatType, type ActiveRecallModelFallbackPolicy, type ActiveRecallPromptStyle, type ActiveRecallQueryMode, type ActiveRecallThinking, type AgentAccessHttpConfig, type AgentDefaultsConfig, type AgentPersona, type AgentPersonaModelConfig, type BehaviorLoopAdjustment, type BehaviorLoopPolicyState, type BehaviorSignalDirection, type BehaviorSignalEvent, type BehaviorSignalType, type BootstrapOptions, type BootstrapResult, type BriefingActiveThread, type BriefingCalendarSourceError, type BriefingConfig, type BriefingFocus, type BriefingFollowup, type BriefingOpenCommitment, type BriefingRecentEntity, type BriefingResult, type BriefingSections, type BriefingWindow, type BufferEntryState, type BufferState, type BufferTurn, type CalendarEvent, type CalendarSource, type CaptureMode, type Checkpoint, type CodexCompactionFlushMode, type CodexCompatConfig, type CodexConnectorConfig, type CompressionGuidelineActivationState, type CompressionGuidelineOptimizerActionSummary, type CompressionGuidelineOptimizerEventCounts, type CompressionGuidelineOptimizerRuleUpdate, type CompressionGuidelineOptimizerSourceWindow, type CompressionGuidelineOptimizerState, type ConfidenceTier, type ConsolidationAction, type ConsolidationItem, type ConsolidationObservation, type ConsolidationResult, type ContinuityImprovementLoop, type ContinuityIncidentCloseInput, type ContinuityIncidentOpenInput, type ContinuityIncidentRecord, type ContinuityIncidentState, type ContinuityLoopCadence, type ContinuityLoopReviewInput, type ContinuityLoopStatus, type ContinuityLoopUpsertInput, type ContradictionScanConfig, type ConversationThread, type CronConversationRecallMode, type CronRecallMode, type DaySummaryResult, type DreamingConfig, type DreamingNarrativePromptStyle, type EngramTraceEvent, type EntityActivityEntry, type EntityFile, type EntityMention, type EntityRelationship, type EntitySchemaDefinition, type EntitySchemaSectionDefinition, type EntityStructuredSection, type EntityTimelineEntry, type ExtractedFact, type ExtractedProcedureStep, type ExtractedQuestion, type ExtractedRelationship, type ExtractionPassSource, type ExtractionResult, type FileHygieneConfig, type GatewayConfig, type HeartbeatConfig, type HeartbeatDetectionMode, type HourlySummary, type IdentityInjectionMode, type ImportanceLevel, type ImportanceScore, type LifecycleState, type LlmTraceCallback, type LlmTraceEvent, type MemoryActionEligibilityContext, type MemoryActionEligibilitySource, type MemoryActionEvent, type MemoryActionOutcome, type MemoryActionPolicyDecision, type MemoryActionPolicyResult, type MemoryActionStatus, type MemoryActionType, type MemoryCategory, type MemoryFile, type MemoryFrontmatter, type MemoryIntent, type MemoryLifecycleEvent, type MemoryLifecycleEventType, type MemoryLifecycleStateSummary, type MemoryLink, type MemoryLinkType, type MemoryOsPresetName, type MemoryProjectionCurrentState, type MemoryStatus, type MemorySummary, type MetaState, type ModelApi, type ModelDefinitionConfig, type ModelProviderAuthMode, type ModelProviderConfig, type NamespacePolicy, type NativeKnowledgeConfig, type NativeKnowledgeFolderRuleConfig, type NativeKnowledgeObsidianVaultConfig, type NativeKnowledgeOpenClawWorkspaceConfig, type PluginConfig, type PolicyClass, type PrincipalFromSessionKeyMode, type PrincipalRule, type ProceduralConfig, type QmdSearchExplain, type QmdSearchResult, type QuestionEntry, type ReasoningEffort, type RecallPipelineConfig, type RecallPlanMode, type RecallSectionConfig, type RecallTierExplain, type RecallTraceEvent, type RelevanceFeedback, type RetrievalTier, SPECULATIVE_TTL_DAYS, type ScoredEntity, type SemanticChunkingConfigShape, type SessionObserverBandConfig, type SignalLevel, type SignalScanResult, type SlotBehaviorConfig, type SlotMismatchMode, type TopicScore, type TranscriptEntry, type TriggerMode, type VerificationState, confidenceTier };
|
|
2043
|
+
export { type AccessTrackingEntry, type ActiveRecallChatType, type ActiveRecallModelFallbackPolicy, type ActiveRecallPromptStyle, type ActiveRecallQueryMode, type ActiveRecallThinking, type AgentAccessHttpConfig, type AgentDefaultsConfig, type AgentPersona, type AgentPersonaModelConfig, type BehaviorLoopAdjustment, type BehaviorLoopPolicyState, type BehaviorSignalDirection, type BehaviorSignalEvent, type BehaviorSignalType, type BootstrapOptions, type BootstrapResult, type BriefingActiveThread, type BriefingCalendarSourceError, type BriefingConfig, type BriefingFocus, type BriefingFollowup, type BriefingOpenCommitment, type BriefingRecentEntity, type BriefingResult, type BriefingSections, type BriefingWindow, type BufferEntryState, type BufferState, type BufferSurpriseEvent, type BufferTurn, type CalendarEvent, type CalendarSource, type CaptureMode, type Checkpoint, type CodexCompactionFlushMode, type CodexCompatConfig, type CodexConnectorConfig, type CodingContext, type CodingModeConfig, type CompressionGuidelineActivationState, type CompressionGuidelineOptimizerActionSummary, type CompressionGuidelineOptimizerEventCounts, type CompressionGuidelineOptimizerRuleUpdate, type CompressionGuidelineOptimizerSourceWindow, type CompressionGuidelineOptimizerState, type ConfidenceTier, type ConsolidationAction, type ConsolidationItem, type ConsolidationObservation, type ConsolidationResult, type ContinuityImprovementLoop, type ContinuityIncidentCloseInput, type ContinuityIncidentOpenInput, type ContinuityIncidentRecord, type ContinuityIncidentState, type ContinuityLoopCadence, type ContinuityLoopReviewInput, type ContinuityLoopStatus, type ContinuityLoopUpsertInput, type ContradictionScanConfig, type ConversationThread, type CronConversationRecallMode, type CronRecallMode, type DaySummaryResult, type DreamingConfig, type DreamingNarrativePromptStyle, type EngramTraceEvent, type EntityActivityEntry, type EntityFile, type EntityMention, type EntityRelationship, type EntitySchemaDefinition, type EntitySchemaSectionDefinition, type EntityStructuredSection, type EntityTimelineEntry, type ExtractedFact, type ExtractedProcedureStep, type ExtractedQuestion, type ExtractedReasoningTrace, type ExtractedReasoningTraceStep, type ExtractedRelationship, type ExtractionPassSource, type ExtractionResult, type FileHygieneConfig, type GatewayConfig, type HeartbeatConfig, type HeartbeatDetectionMode, type HourlySummary, type IdentityInjectionMode, type ImportanceLevel, type ImportanceScore, type LifecycleState, type LlmTraceCallback, type LlmTraceEvent, type MemoryActionEligibilityContext, type MemoryActionEligibilitySource, type MemoryActionEvent, type MemoryActionOutcome, type MemoryActionPolicyDecision, type MemoryActionPolicyResult, type MemoryActionStatus, type MemoryActionType, type MemoryCategory, type MemoryFile, type MemoryFrontmatter, type MemoryIntent, type MemoryLifecycleEvent, type MemoryLifecycleEventType, type MemoryLifecycleStateSummary, type MemoryLink, type MemoryLinkType, type MemoryOsPresetName, type MemoryProjectionCurrentState, type MemoryStatus, type MemorySummary, type MetaState, type ModelApi, type ModelDefinitionConfig, type ModelProviderAuthMode, type ModelProviderConfig, type NamespacePolicy, type NativeKnowledgeConfig, type NativeKnowledgeFolderRuleConfig, type NativeKnowledgeObsidianVaultConfig, type NativeKnowledgeOpenClawWorkspaceConfig, type PluginConfig, type PolicyClass, type PrincipalFromSessionKeyMode, type PrincipalRule, type ProceduralConfig, type QmdSearchExplain, type QmdSearchResult, type QuestionEntry, type ReasoningEffort, type RecallPipelineConfig, type RecallPlanMode, type RecallSectionConfig, type RecallTierExplain, type RecallTraceEvent, type RelevanceFeedback, type RetrievalTier, SPECULATIVE_TTL_DAYS, type ScoredEntity, type SemanticChunkingConfigShape, type SessionObserverBandConfig, type SignalLevel, type SignalScanResult, type SlotBehaviorConfig, type SlotMismatchMode, type TopicScore, type TranscriptEntry, type TriggerMode, type VerificationState, confidenceTier };
|
package/dist/types.js
CHANGED
package/dist/verified-recall.js
CHANGED
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
import {
|
|
2
2
|
searchVerifiedEpisodes
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-CUPFXL3J.js";
|
|
4
4
|
import "./chunk-URB2WSKZ.js";
|
|
5
5
|
import "./chunk-DT5TVLJE.js";
|
|
6
|
-
import "./chunk-
|
|
7
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-F5VP6YCB.js";
|
|
7
|
+
import "./chunk-LTCGGW2D.js";
|
|
8
8
|
import "./chunk-4KAN3GZ3.js";
|
|
9
|
-
import "./chunk-6ZH4TU6I.js";
|
|
10
|
-
import "./chunk-SCU65EZI.js";
|
|
11
|
-
import "./chunk-BOUYNNYD.js";
|
|
12
9
|
import "./chunk-6PFRXT4K.js";
|
|
13
10
|
import "./chunk-TP4FZJIZ.js";
|
|
11
|
+
import "./chunk-SCU65EZI.js";
|
|
12
|
+
import "./chunk-BOUYNNYD.js";
|
|
14
13
|
import "./chunk-DM2T26WE.js";
|
|
15
14
|
import "./chunk-QSVPYQPG.js";
|
|
16
15
|
import "./chunk-M62O4P4T.js";
|
|
17
16
|
import "./chunk-4DJQYKMN.js";
|
|
17
|
+
import "./chunk-X6GF3FX2.js";
|
|
18
|
+
import "./chunk-FAAFWE4G.js";
|
|
18
19
|
import "./chunk-2ODBA7MQ.js";
|
|
19
20
|
export {
|
|
20
21
|
searchVerifiedEpisodes
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/access-http.ts","../src/adapters/types.ts","../src/adapters/claude-code.ts","../src/adapters/codex.ts","../src/adapters/replit.ts","../src/adapters/hermes.ts","../src/adapters/registry.ts"],"sourcesContent":["import { createServer, type IncomingMessage, type Server, type ServerResponse } from \"node:http\";\nimport { randomUUID, timingSafeEqual } from \"node:crypto\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { fileURLToPath, URL } from \"node:url\";\nimport { log } from \"./logger.js\";\nimport { EngramAccessInputError, type EngramAccessService } from \"./access-service.js\";\nimport { EngramMcpServer } from \"./access-mcp.js\";\nimport { validateRequest, type SchemaName, type SchemaTypeFor } from \"./access-schema.js\";\nimport type { RecallPlanMode } from \"./types.js\";\nimport { isTrustZoneName, type TrustZoneName, type TrustZoneRecordKind, type TrustZoneSourceClass } from \"./trust-zones.js\";\nimport { AdapterRegistry, type ResolvedIdentity } from \"./adapters/index.js\";\nimport type { CitationEntry } from \"./citations.js\";\n\nexport interface EngramAccessHttpServerOptions {\n service: EngramAccessService;\n host?: string;\n port?: number;\n authToken?: string;\n /** Additional valid tokens (for multi-connector auth). Checked alongside authToken. */\n authTokens?: string[];\n /** Dynamic token loader — called on each auth check so new/revoked tokens take effect without restart. */\n authTokensGetter?: () => string[];\n principal?: string;\n maxBodyBytes?: number;\n adminConsoleEnabled?: boolean;\n adminConsolePublicDir?: string;\n trustPrincipalHeader?: boolean;\n /** Enable adapter-based identity resolution from request headers */\n enableAdapters?: boolean;\n /** Custom adapter registry (defaults to built-in adapters) */\n adapterRegistry?: AdapterRegistry;\n /** Enable oai-mem-citation blocks in recall responses (issue #379). */\n citationsEnabled?: boolean;\n /** Auto-enable citations for Codex adapter connections (issue #379). */\n citationsAutoDetect?: boolean;\n}\n\nexport interface EngramAccessHttpServerStatus {\n running: boolean;\n host: string;\n port: number;\n maxBodyBytes: number;\n}\n\nfunction resolveDefaultAdminConsolePublicDir(): string {\n const candidates = [\n fileURLToPath(new URL(\"../admin-console/public\", import.meta.url)),\n fileURLToPath(new URL(\"./admin-console/public\", import.meta.url)),\n ];\n return candidates.find((candidate) => existsSync(candidate)) ?? candidates[0];\n}\n\nconst defaultAdminConsolePublicDir = resolveDefaultAdminConsolePublicDir();\nconst correlationIdStore = new AsyncLocalStorage<string>();\n\nconst WRITE_RATE_LIMIT_WINDOW_MS = 60_000;\nconst WRITE_RATE_LIMIT_MAX_REQUESTS = 30;\nconst TRUST_ZONE_RECORD_KINDS = [\"memory\", \"artifact\", \"state\", \"trajectory\", \"external\"] as const;\nconst TRUST_ZONE_SOURCE_CLASSES = [\"tool_output\", \"web_content\", \"subagent_trace\", \"system_memory\", \"user_input\", \"manual\"] as const;\n\nclass HttpError extends Error {\n readonly code: string;\n readonly details?: unknown;\n constructor(readonly status: number, message: string, code?: string, details?: unknown) {\n super(message);\n this.code = code ?? `http_${status}`;\n this.details = details;\n }\n}\n\nfunction hostToUrlAuthority(host: string): string {\n if (host.includes(\":\") && !host.startsWith(\"[\") && !host.endsWith(\"]\")) {\n return `[${host}]`;\n }\n return host;\n}\n\nfunction parseTrustZoneKindFilter(raw: string | null): TrustZoneRecordKind | undefined {\n if (raw === null) return undefined;\n if ((TRUST_ZONE_RECORD_KINDS as readonly string[]).includes(raw)) {\n return raw as TrustZoneRecordKind;\n }\n throw new HttpError(400, `kind must be one of ${TRUST_ZONE_RECORD_KINDS.join(\"|\")}`, \"invalid_kind_filter\");\n}\n\nfunction parseTrustZoneSourceClassFilter(raw: string | null): TrustZoneSourceClass | undefined {\n if (raw === null) return undefined;\n if ((TRUST_ZONE_SOURCE_CLASSES as readonly string[]).includes(raw)) {\n return raw as TrustZoneSourceClass;\n }\n throw new HttpError(400, `sourceClass must be one of ${TRUST_ZONE_SOURCE_CLASSES.join(\"|\")}`, \"invalid_source_class_filter\");\n}\n\nfunction parseTrustZoneFilter(raw: string | null): TrustZoneName | undefined {\n if (raw === null) return undefined;\n if (isTrustZoneName(raw)) {\n return raw;\n }\n throw new HttpError(400, \"zone must be one of quarantine|working|trusted\", \"invalid_zone_filter\");\n}\n\nexport class EngramAccessHttpServer {\n private readonly service: EngramAccessService;\n private readonly host: string;\n private readonly requestedPort: number;\n private readonly authToken?: string;\n private readonly authTokens: string[];\n private readonly authTokensGetter?: () => string[];\n private readonly authenticatedPrincipal?: string;\n private readonly maxBodyBytes: number;\n private readonly adminConsoleEnabled: boolean;\n private readonly adminConsolePublicDir: string;\n private readonly trustPrincipalHeader: boolean;\n private readonly adapterRegistry: AdapterRegistry | null;\n private readonly writeRequestTimestamps: number[] = [];\n private readonly mcpServer: EngramMcpServer;\n private server: Server | null = null;\n private boundPort = 0;\n\n constructor(options: EngramAccessHttpServerOptions) {\n this.service = options.service;\n this.host = options.host?.trim() || \"127.0.0.1\";\n this.requestedPort = Number.isFinite(options.port) ? Math.max(0, Math.floor(options.port ?? 0)) : 0;\n this.authToken = options.authToken?.trim() || undefined;\n this.authTokens = (options.authTokens ?? []).map((t) => t.trim()).filter(Boolean);\n this.authTokensGetter = options.authTokensGetter;\n this.authenticatedPrincipal = options.principal?.trim() || undefined;\n this.maxBodyBytes = Number.isFinite(options.maxBodyBytes)\n ? Math.max(1, Math.floor(options.maxBodyBytes ?? 131072))\n : 131072;\n this.adminConsoleEnabled = options.adminConsoleEnabled !== false;\n this.adminConsolePublicDir = options.adminConsolePublicDir ?? defaultAdminConsolePublicDir;\n this.trustPrincipalHeader = options.trustPrincipalHeader === true;\n this.adapterRegistry = options.enableAdapters !== false\n ? (options.adapterRegistry ?? new AdapterRegistry())\n : null;\n this.mcpServer = new EngramMcpServer(this.service, {\n principal: options.principal,\n citationsEnabled: options.citationsEnabled,\n citationsAutoDetect: options.citationsAutoDetect,\n });\n }\n\n async start(): Promise<EngramAccessHttpServerStatus> {\n if (!this.authToken && this.authTokens.length === 0 && !this.authTokensGetter) {\n throw new Error(\"engram access HTTP requires authToken or authTokens\");\n }\n if (this.server) return this.status();\n\n const server = createServer((req, res) => {\n const correlationId = randomUUID();\n correlationIdStore.run(correlationId, () => {\n void this.handle(req, res, correlationId).catch((err) => {\n log.debug(`engram access HTTP request failed [${correlationId}]: ${err}`);\n if (err instanceof HttpError) {\n const payload: Record<string, unknown> = { error: err.message, code: err.code };\n if (err.details) payload.details = err.details;\n this.respondJson(res, err.status, payload);\n return;\n }\n if (err instanceof EngramAccessInputError) {\n this.respondJson(res, 400, { error: err.message, code: \"input_error\" });\n return;\n }\n if (res.headersSent) {\n res.destroy(err as Error);\n return;\n }\n this.respondJson(res, 500, { error: \"internal_error\", code: \"internal_error\" });\n });\n });\n });\n\n try {\n await new Promise<void>((resolve, reject) => {\n const onError = (err: Error) => {\n server.off(\"listening\", onListening);\n reject(err);\n };\n const onListening = () => {\n server.off(\"error\", onError);\n resolve();\n };\n server.once(\"error\", onError);\n server.once(\"listening\", onListening);\n server.listen(this.requestedPort, this.host);\n });\n } catch (err) {\n server.close();\n throw err;\n }\n\n this.server = server;\n const address = server.address();\n this.boundPort = typeof address === \"object\" && address ? address.port : this.requestedPort;\n return this.status();\n }\n\n async stop(): Promise<void> {\n if (!this.server) return;\n const server = this.server;\n this.server = null;\n this.boundPort = 0;\n await new Promise<void>((resolve, reject) => {\n server.close((err) => (err ? reject(err) : resolve()));\n });\n }\n\n status(): EngramAccessHttpServerStatus {\n return {\n running: this.server !== null,\n host: this.host,\n port: this.boundPort,\n maxBodyBytes: this.maxBodyBytes,\n };\n }\n\n /**\n * Resolve the adapter identity for the incoming request.\n * Includes MCP clientInfo from the last initialize handshake if available.\n * Returns null if no adapter matches or adapters are disabled.\n */\n resolveAdapterIdentity(req: IncomingMessage): ResolvedIdentity | null {\n if (!this.adapterRegistry) return null;\n // Look up clientInfo for this specific MCP session to avoid cross-session leaks.\n // Non-MCP requests (no mcp-session-id header) get undefined clientInfo and\n // rely on HTTP headers for adapter matching.\n const sessionId = (() => {\n const raw = req.headers[\"mcp-session-id\"];\n return typeof raw === \"string\" ? raw.trim() : undefined;\n })();\n return this.adapterRegistry.resolve({\n headers: req.headers as Record<string, string | string[] | undefined>,\n clientInfo: this.mcpServer.getClientInfo(sessionId),\n });\n }\n\n /** Cache for per-request identity resolution (avoids double adapter resolution) */\n private identityCache = new WeakMap<IncomingMessage, { principal?: string; namespace?: string }>();\n\n /** Resolve principal and namespace from request headers and adapter identity */\n private resolveRequestIdentity(req: IncomingMessage): { principal?: string; namespace?: string } {\n const cached = this.identityCache.get(req);\n if (cached) return cached;\n let principal: string | undefined;\n let namespace: string | undefined;\n\n // Explicit header override takes priority for principal\n if (this.trustPrincipalHeader) {\n const headerVal = req.headers[\"x-engram-principal\"];\n const raw = Array.isArray(headerVal) ? headerVal[0] : headerVal;\n if (typeof raw === \"string\") {\n const trimmed = raw.trim();\n if (trimmed.length > 0) {\n principal = trimmed;\n }\n }\n }\n\n // Try adapter-based identity resolution for both principal and namespace\n const adapterIdentity = this.resolveAdapterIdentity(req);\n if (adapterIdentity) {\n if (!principal) {\n principal = adapterIdentity.principal;\n }\n namespace = adapterIdentity.namespace;\n }\n\n if (!principal) {\n principal = this.authenticatedPrincipal;\n }\n\n const result = { principal, namespace };\n this.identityCache.set(req, result);\n return result;\n }\n\n private resolveRequestPrincipal(req: IncomingMessage): string | undefined {\n return this.resolveRequestIdentity(req).principal;\n }\n\n /** Resolve namespace: only use the explicit body value. Adapter-inferred namespace\n * is intentionally NOT used as a fallback for REST requests — omitting namespace\n * should default to the server's global namespace, not silently scope to an adapter. */\n private resolveNamespace(_req: IncomingMessage, bodyNamespace?: string): string | undefined {\n return bodyNamespace || undefined;\n }\n\n private async handle(req: IncomingMessage, res: ServerResponse, correlationId: string): Promise<void> {\n const parsed = new URL(req.url ?? \"/\", `http://${hostToUrlAuthority(this.host)}`);\n const pathname = parsed.pathname;\n\n if (this.adminConsoleEnabled && await this.handleAdminConsole(req, res, pathname)) {\n return;\n }\n\n if (!this.isAuthorized(req)) {\n const body = JSON.stringify({ error: \"unauthorized\", code: \"unauthorized\" });\n res.writeHead(401, {\n \"content-type\": \"application/json; charset=utf-8\",\n \"www-authenticate\": \"Bearer\",\n \"x-request-id\": correlationId,\n });\n res.end(body);\n return;\n }\n\n if (req.method === \"POST\" && pathname === \"/mcp\") {\n await this.handleMcpRequest(req, res);\n return;\n }\n\n if (req.method === \"GET\" && pathname === \"/engram/v1/health\") {\n this.respondJson(res, 200, await this.service.health());\n return;\n }\n\n if (req.method === \"GET\" && pathname === \"/engram/v1/adapters\") {\n const identity = this.resolveAdapterIdentity(req);\n this.respondJson(res, 200, {\n adaptersEnabled: this.adapterRegistry !== null,\n registered: this.adapterRegistry?.list() ?? [],\n resolved: identity,\n });\n return;\n }\n\n if (req.method === \"POST\" && pathname === \"/engram/v1/recall\") {\n const body = await this.readValidatedBody(req, \"recall\");\n const response = await this.service.recall({\n query: body.query ?? \"\",\n sessionKey: body.sessionKey,\n namespace: this.resolveNamespace(req, body.namespace),\n topK: body.topK,\n mode: body.mode as RecallPlanMode | \"auto\" | undefined,\n includeDebug: body.includeDebug === true,\n });\n this.respondJson(res, 200, response);\n return;\n }\n\n if (req.method === \"POST\" && pathname === \"/engram/v1/recall/explain\") {\n const body = await this.readValidatedBody(req, \"recallExplain\");\n const response = await this.service.recallExplain({\n sessionKey: body.sessionKey,\n namespace: this.resolveNamespace(req, body.namespace),\n });\n this.respondJson(res, 200, response);\n return;\n }\n\n if (req.method === \"POST\" && pathname === \"/engram/v1/observe\") {\n const body = await this.readValidatedBody(req, \"observe\");\n this.ensureWriteRateLimitAvailable();\n const response = await this.service.observe({\n sessionKey: body.sessionKey,\n messages: body.messages,\n namespace: this.resolveNamespace(req, body.namespace),\n authenticatedPrincipal: this.resolveRequestPrincipal(req),\n skipExtraction: body.skipExtraction === true,\n });\n this.recordWriteRateLimitHit();\n this.respondJson(res, 202, response);\n return;\n }\n\n if (req.method === \"POST\" && pathname === \"/engram/v1/lcm/search\") {\n const body = await this.readValidatedBody(req, \"lcmSearch\");\n const response = await this.service.lcmSearch({\n query: body.query,\n sessionKey: body.sessionKey,\n namespace: this.resolveNamespace(req, body.namespace),\n authenticatedPrincipal: this.resolveRequestPrincipal(req),\n limit: body.limit,\n });\n this.respondJson(res, 200, response);\n return;\n }\n\n if (req.method === \"GET\" && pathname === \"/engram/v1/lcm/status\") {\n this.respondJson(res, 200, await this.service.lcmStatus());\n return;\n }\n\n if (req.method === \"POST\" && pathname === \"/engram/v1/memories\") {\n const body = await this.readValidatedBody(req, \"memoryStore\");\n const request = {\n schemaVersion: body.schemaVersion,\n idempotencyKey: body.idempotencyKey,\n dryRun: body.dryRun === true,\n sessionKey: body.sessionKey,\n authenticatedPrincipal: this.resolveRequestPrincipal(req),\n content: body.content,\n category: body.category,\n confidence: body.confidence,\n namespace: this.resolveNamespace(req, body.namespace),\n tags: body.tags,\n entityRef: body.entityRef,\n ttl: body.ttl,\n sourceReason: body.sourceReason,\n };\n const idempotencyStatus = await this.service.peekMemoryStoreIdempotency(request);\n if (idempotencyStatus === \"miss\" && request.dryRun !== true) {\n this.ensureWriteRateLimitAvailable();\n }\n const response = await this.service.memoryStore(request);\n if (this.shouldCountWriteRateLimit(response as { dryRun?: boolean; idempotencyReplay?: boolean })) {\n this.recordWriteRateLimitHit();\n }\n this.respondJson(res, this.writeResponseStatus(response), response);\n return;\n }\n\n if (req.method === \"POST\" && pathname === \"/engram/v1/suggestions\") {\n const body = await this.readValidatedBody(req, \"suggestionSubmit\");\n const request = {\n schemaVersion: body.schemaVersion,\n idempotencyKey: body.idempotencyKey,\n dryRun: body.dryRun === true,\n sessionKey: body.sessionKey,\n authenticatedPrincipal: this.resolveRequestPrincipal(req),\n content: body.content,\n category: body.category,\n confidence: body.confidence,\n namespace: this.resolveNamespace(req, body.namespace),\n tags: body.tags,\n entityRef: body.entityRef,\n ttl: body.ttl,\n sourceReason: body.sourceReason,\n };\n const idempotencyStatus = await this.service.peekSuggestionSubmitIdempotency(request);\n if (idempotencyStatus === \"miss\" && request.dryRun !== true) {\n this.ensureWriteRateLimitAvailable();\n }\n const response = await this.service.suggestionSubmit(request);\n if (this.shouldCountWriteRateLimit(response as { dryRun?: boolean; idempotencyReplay?: boolean })) {\n this.recordWriteRateLimitHit();\n }\n this.respondJson(res, this.writeResponseStatus(response), response);\n return;\n }\n\n if (req.method === \"GET\" && pathname === \"/engram/v1/memories\") {\n const limitRaw = parseInt(parsed.searchParams.get(\"limit\") ?? \"50\", 10);\n const offsetRaw = parseInt(parsed.searchParams.get(\"offset\") ?? \"0\", 10);\n const sortParam = parsed.searchParams.get(\"sort\") ?? undefined;\n const sort = sortParam === \"updated_desc\"\n || sortParam === \"updated_asc\"\n || sortParam === \"created_desc\"\n || sortParam === \"created_asc\"\n ? sortParam\n : undefined;\n const response = await this.service.memoryBrowse({\n query: parsed.searchParams.get(\"q\") ?? undefined,\n status: parsed.searchParams.get(\"status\") ?? undefined,\n category: parsed.searchParams.get(\"category\") ?? undefined,\n namespace: parsed.searchParams.get(\"namespace\") ?? undefined,\n sort,\n limit: Number.isFinite(limitRaw) ? limitRaw : 50,\n offset: Number.isFinite(offsetRaw) ? offsetRaw : 0,\n });\n this.respondJson(res, 200, response);\n return;\n }\n\n const memoryMatch = pathname.match(/^\\/engram\\/v1\\/memories\\/([^/]+)$/);\n if (req.method === \"GET\" && memoryMatch) {\n const memoryId = decodeURIComponent(memoryMatch[1] ?? \"\");\n const namespace = parsed.searchParams.get(\"namespace\") ?? undefined;\n const response = await this.service.memoryGet(memoryId, namespace, this.resolveRequestPrincipal(req));\n this.respondJson(res, response.found ? 200 : 404, response);\n return;\n }\n\n const timelineMatch = pathname.match(/^\\/engram\\/v1\\/memories\\/([^/]+)\\/timeline$/);\n if (req.method === \"GET\" && timelineMatch) {\n const memoryId = decodeURIComponent(timelineMatch[1] ?? \"\");\n const namespace = parsed.searchParams.get(\"namespace\") ?? undefined;\n const limitRaw = parseInt(parsed.searchParams.get(\"limit\") ?? \"200\", 10);\n const limit = Number.isFinite(limitRaw) ? limitRaw : 200;\n const response = await this.service.memoryTimeline(memoryId, namespace, limit, this.resolveRequestPrincipal(req));\n this.respondJson(res, response.found ? 200 : 404, response);\n return;\n }\n\n if (req.method === \"GET\" && pathname === \"/engram/v1/entities\") {\n const limitRaw = parseInt(parsed.searchParams.get(\"limit\") ?? \"50\", 10);\n const offsetRaw = parseInt(parsed.searchParams.get(\"offset\") ?? \"0\", 10);\n const response = await this.service.entityList({\n namespace: parsed.searchParams.get(\"namespace\") ?? undefined,\n query: parsed.searchParams.get(\"q\") ?? undefined,\n limit: Number.isFinite(limitRaw) ? limitRaw : 50,\n offset: Number.isFinite(offsetRaw) ? offsetRaw : 0,\n });\n this.respondJson(res, 200, response);\n return;\n }\n\n const entityMatch = pathname.match(/^\\/engram\\/v1\\/entities\\/([^/]+)$/);\n if (req.method === \"GET\" && entityMatch) {\n const entityName = decodeURIComponent(entityMatch[1] ?? \"\");\n const namespace = parsed.searchParams.get(\"namespace\") ?? undefined;\n const response = await this.service.entityGet(entityName, namespace);\n this.respondJson(res, response.found ? 200 : 404, response);\n return;\n }\n\n if (req.method === \"GET\" && pathname === \"/engram/v1/review-queue\") {\n const response = await this.service.reviewQueue(\n parsed.searchParams.get(\"runId\") ?? undefined,\n parsed.searchParams.get(\"namespace\") ?? undefined,\n this.resolveRequestPrincipal(req),\n );\n this.respondJson(res, 200, response);\n return;\n }\n\n if (req.method === \"GET\" && pathname === \"/engram/v1/maintenance\") {\n this.respondJson(res, 200, await this.service.maintenance(parsed.searchParams.get(\"namespace\") ?? undefined, this.resolveRequestPrincipal(req)));\n return;\n }\n\n if (req.method === \"GET\" && pathname === \"/engram/v1/quality\") {\n this.respondJson(res, 200, await this.service.quality(parsed.searchParams.get(\"namespace\") ?? undefined, this.resolveRequestPrincipal(req)));\n return;\n }\n\n if (req.method === \"GET\" && pathname === \"/engram/v1/trust-zones/status\") {\n this.respondJson(\n res,\n 200,\n await this.service.trustZoneStatus(parsed.searchParams.get(\"namespace\") ?? undefined, this.resolveRequestPrincipal(req)),\n );\n return;\n }\n\n if (req.method === \"GET\" && pathname === \"/engram/v1/trust-zones/records\") {\n const limitRaw = parseInt(parsed.searchParams.get(\"limit\") ?? \"25\", 10);\n const offsetRaw = parseInt(parsed.searchParams.get(\"offset\") ?? \"0\", 10);\n const response = await this.service.trustZoneBrowse({\n query: parsed.searchParams.get(\"q\") ?? undefined,\n zone: parseTrustZoneFilter(parsed.searchParams.get(\"zone\")),\n kind: parseTrustZoneKindFilter(parsed.searchParams.get(\"kind\")),\n sourceClass: parseTrustZoneSourceClassFilter(parsed.searchParams.get(\"sourceClass\")),\n namespace: parsed.searchParams.get(\"namespace\") ?? undefined,\n limit: Number.isFinite(limitRaw) ? limitRaw : 25,\n offset: Number.isFinite(offsetRaw) ? offsetRaw : 0,\n }, this.resolveRequestPrincipal(req));\n this.respondJson(res, 200, response);\n return;\n }\n\n if (req.method === \"POST\" && pathname === \"/engram/v1/review-disposition\") {\n const body = await this.readValidatedBody(req, \"reviewDisposition\");\n this.ensureWriteRateLimitAvailable();\n const response = await this.service.reviewDisposition({\n memoryId: body.memoryId,\n status: body.status,\n reasonCode: body.reasonCode,\n namespace: this.resolveNamespace(req, body.namespace),\n authenticatedPrincipal: this.resolveRequestPrincipal(req),\n });\n if (this.shouldCountWriteRateLimit(response as unknown as { dryRun?: boolean; idempotencyReplay?: boolean })) {\n this.recordWriteRateLimitHit();\n }\n this.respondJson(res, 200, response);\n return;\n }\n\n if (req.method === \"POST\" && pathname === \"/engram/v1/trust-zones/promote\") {\n const body = await this.readValidatedBody(req, \"trustZonePromote\");\n const dryRun = body.dryRun === true;\n if (!dryRun) {\n this.ensureWriteRateLimitAvailable();\n }\n const response = await this.service.trustZonePromote({\n recordId: body.recordId,\n targetZone: body.targetZone,\n promotionReason: body.promotionReason,\n recordedAt: body.recordedAt,\n summary: body.summary,\n dryRun,\n namespace: this.resolveNamespace(req, body.namespace),\n authenticatedPrincipal: this.resolveRequestPrincipal(req),\n });\n if (this.shouldCountWriteRateLimit(response as unknown as { dryRun?: boolean; idempotencyReplay?: boolean })) {\n this.recordWriteRateLimitHit();\n }\n this.respondJson(res, response.dryRun ? 200 : 201, response);\n return;\n }\n\n if (req.method === \"POST\" && pathname === \"/engram/v1/trust-zones/demo-seed\") {\n const body = await this.readValidatedBody(req, \"trustZoneDemoSeed\");\n const dryRun = body.dryRun === true;\n if (!dryRun) {\n this.ensureWriteRateLimitAvailable();\n }\n const response = await this.service.trustZoneDemoSeed({\n scenario: body.scenario,\n recordedAt: body.recordedAt,\n dryRun,\n namespace: this.resolveNamespace(req, body.namespace),\n authenticatedPrincipal: this.resolveRequestPrincipal(req),\n });\n if (this.shouldCountWriteRateLimit(response as unknown as { dryRun?: boolean; idempotencyReplay?: boolean })) {\n this.recordWriteRateLimitHit();\n }\n this.respondJson(res, response.dryRun ? 200 : 201, response);\n return;\n }\n\n // Citation usage tracking (issue #379)\n if (req.method === \"POST\" && pathname === \"/v1/citations/observed\") {\n const body = await this.readJsonBody(req);\n if (!body || typeof body !== \"object\" || Array.isArray(body)) {\n throw new HttpError(400, \"request body must be a JSON object\", \"invalid_body\");\n }\n const payload = body as Record<string, unknown>;\n const sessionId = typeof payload.sessionId === \"string\" ? payload.sessionId : undefined;\n const namespace = typeof payload.namespace === \"string\" ? payload.namespace : undefined;\n const citationsRaw = payload.citations;\n if (!citationsRaw || typeof citationsRaw !== \"object\" || Array.isArray(citationsRaw)) {\n throw new HttpError(400, \"citations must be a JSON object with entries and rolloutIds\", \"invalid_citations\");\n }\n const citObj = citationsRaw as Record<string, unknown>;\n const entries: CitationEntry[] = [];\n if (Array.isArray(citObj.entries)) {\n for (const raw of citObj.entries) {\n if (raw && typeof raw === \"object\" && !Array.isArray(raw)) {\n const e = raw as Record<string, unknown>;\n if (\n typeof e.path === \"string\" &&\n typeof e.lineStart === \"number\" &&\n typeof e.lineEnd === \"number\"\n ) {\n entries.push({\n path: e.path,\n lineStart: e.lineStart,\n lineEnd: e.lineEnd,\n note: typeof e.note === \"string\" ? e.note : \"\",\n });\n }\n }\n }\n }\n const rolloutIds: string[] = [];\n if (Array.isArray(citObj.rolloutIds)) {\n for (const id of citObj.rolloutIds) {\n if (typeof id === \"string\" && id.length > 0) {\n rolloutIds.push(id);\n }\n }\n }\n\n // Record usage: for each citation entry, try to increment usage on the\n // matching memory. The service exposes recordAccess for this purpose.\n // Pass authenticatedPrincipal so namespace ACL checks use the same\n // identity resolution as other write endpoints (Finding #1, issue #379).\n let matched = 0;\n let submitted = 0;\n if (typeof this.service.recordCitationUsage === \"function\") {\n const result = await this.service.recordCitationUsage({\n sessionId,\n namespace: this.resolveNamespace(req, namespace),\n authenticatedPrincipal: this.resolveRequestPrincipal(req),\n entries,\n rolloutIds,\n });\n submitted = result.submitted;\n matched = result.matched;\n }\n\n this.respondJson(res, 200, {\n ok: true,\n submitted,\n matched,\n entriesReceived: entries.length,\n rolloutIdsReceived: rolloutIds.length,\n });\n return;\n }\n\n // ── Contradiction Review (issue #520) ─────────────────────────────────────\n if (req.method === \"GET\" && pathname === \"/engram/v1/review/contradictions\") {\n const VALID_FILTERS = new Set([\"all\", \"unresolved\", \"contradicts\", \"independent\", \"duplicates\", \"needs-user\"]);\n const rawFilter = parsed.searchParams.get(\"filter\") ?? \"unresolved\";\n if (!VALID_FILTERS.has(rawFilter)) {\n this.respondJson(res, 400, { error: `Invalid filter '${rawFilter}'. Valid: ${[...VALID_FILTERS].join(\", \")}` });\n return;\n }\n const namespace = parsed.searchParams.get(\"namespace\") ?? undefined;\n const limitRaw = parseInt(parsed.searchParams.get(\"limit\") ?? \"50\", 10);\n const { listPairs } = await import(\"./contradiction/contradiction-review.js\");\n const result = listPairs(this.service.memoryDir, {\n filter: rawFilter as \"all\" | \"unresolved\" | \"contradicts\" | \"independent\" | \"duplicates\" | \"needs-user\",\n namespace,\n limit: Number.isFinite(limitRaw) ? limitRaw : 50,\n });\n this.respondJson(res, 200, result);\n return;\n }\n\n if (req.method === \"GET\" && pathname.startsWith(\"/engram/v1/review/contradictions/\")) {\n const pairId = pathname.split(\"/\").pop() ?? \"\";\n const { readPair } = await import(\"./contradiction/contradiction-review.js\");\n const pair = readPair(this.service.memoryDir, pairId);\n if (!pair) {\n this.respondJson(res, 404, { error: \"pair_not_found\" });\n return;\n }\n this.respondJson(res, 200, pair);\n return;\n }\n\n if (req.method === \"POST\" && pathname === \"/engram/v1/review/resolve\") {\n const body = await this.readJsonBody(req) as Record<string, unknown>;\n const pairId = typeof body.pairId === \"string\" ? body.pairId : \"\";\n const verb = typeof body.verb === \"string\" ? body.verb : \"\";\n if (!pairId || !verb) {\n this.respondJson(res, 400, { error: \"pairId and verb are required\" });\n return;\n }\n const { isValidResolutionVerb, executeResolution } = await import(\"./contradiction/resolution.js\");\n if (!isValidResolutionVerb(verb)) {\n this.respondJson(res, 400, { error: `Invalid verb: ${verb}. Must be one of: keep-a, keep-b, merge, both-valid, needs-more-context` });\n return;\n }\n const result = await executeResolution(this.service.memoryDir, this.service.storageRef, pairId, verb);\n this.respondJson(res, 200, result);\n return;\n }\n\n if (req.method === \"POST\" && pathname === \"/engram/v1/contradiction-scan\") {\n const body = await this.readJsonBody(req) as Record<string, unknown>;\n const { runContradictionScan } = await import(\"./contradiction/contradiction-scan.js\");\n const result = await runContradictionScan({\n storage: this.service.storageRef,\n config: this.service.configRef,\n memoryDir: this.service.memoryDir,\n embeddingLookup: this.service.embeddingLookupRef,\n localLlm: this.service.localLlmRef,\n fallbackLlm: this.service.fallbackLlmRef,\n namespace: typeof body.namespace === \"string\" ? body.namespace : undefined,\n });\n this.respondJson(res, 200, result);\n return;\n }\n\n this.respondJson(res, 404, { error: \"not_found\", code: \"not_found\" });\n }\n\n private async handleMcpRequest(req: IncomingMessage, res: ServerResponse): Promise<void> {\n const body = await this.readJsonBody(req);\n const request = body as {\n jsonrpc?: string;\n id?: string | number | null;\n method?: string;\n params?: Record<string, unknown>;\n };\n\n // Enforce write rate limiting for MCP tool calls that mutate state,\n // matching the same protection applied to the REST write endpoints.\n // Pre-check ensures capacity; post-check skips counting dry runs and\n // idempotency replays, consistent with the REST handlers.\n const isMcpWrite =\n request.method === \"tools/call\" &&\n typeof request.params?.name === \"string\" &&\n (request.params.name === \"engram.memory_store\" || request.params.name === \"engram.suggestion_submit\" || request.params.name === \"engram.observe\");\n if (isMcpWrite) {\n this.ensureWriteRateLimitAvailable();\n }\n\n const sessionId = (() => {\n const raw = req.headers[\"mcp-session-id\"];\n return typeof raw === \"string\" ? raw.trim() : undefined;\n })();\n const mcpCorrelationId = correlationIdStore.getStore() ?? randomUUID();\n const response = await this.mcpServer.handleRequest(request, {\n principalOverride: this.resolveRequestPrincipal(req),\n sessionId,\n correlationId: mcpCorrelationId,\n });\n\n if (isMcpWrite && response !== null) {\n const result = (response as Record<string, unknown>).result as Record<string, unknown> | undefined;\n const isError = result?.isError === true;\n const structured = result?.structuredContent as { dryRun?: boolean; idempotencyReplay?: boolean } | undefined;\n if (!isError && structured && this.shouldCountWriteRateLimit(structured)) {\n this.recordWriteRateLimitHit();\n }\n }\n if (response === null) {\n res.statusCode = 202;\n res.end();\n return;\n }\n // If this was an initialize response, pop the session ID keyed by\n // correlation ID (unique per HTTP request, not client-chosen JSON-RPC id).\n const assignedSessionId = this.mcpServer.popInitSessionId(mcpCorrelationId);\n if (assignedSessionId) {\n res.setHeader(\"mcp-session-id\", assignedSessionId);\n }\n this.respondJson(res, 200, response);\n }\n\n private respondJson(res: ServerResponse, status: number, payload: unknown): void {\n const body = JSON.stringify(payload, null, 2);\n res.statusCode = status;\n res.setHeader(\"content-type\", \"application/json; charset=utf-8\");\n res.setHeader(\"content-length\", String(Buffer.byteLength(body)));\n const cid = correlationIdStore.getStore();\n if (cid) {\n res.setHeader(\"x-request-id\", cid);\n }\n res.end(body);\n }\n\n private async handleAdminConsole(\n req: IncomingMessage,\n res: ServerResponse,\n pathname: string,\n ): Promise<boolean> {\n if (req.method !== \"GET\") return false;\n if (pathname === \"/engram/ui\" || pathname === \"/engram/ui/\") {\n await this.respondStatic(res, path.join(this.adminConsolePublicDir, \"index.html\"), \"text/html; charset=utf-8\");\n return true;\n }\n if (pathname === \"/engram/ui/app.js\") {\n await this.respondStatic(res, path.join(this.adminConsolePublicDir, \"app.js\"), \"application/javascript; charset=utf-8\");\n return true;\n }\n return false;\n }\n\n private async respondStatic(res: ServerResponse, filePath: string, contentType: string): Promise<void> {\n try {\n const body = await readFile(filePath, \"utf-8\");\n res.statusCode = 200;\n res.setHeader(\"content-type\", contentType);\n res.setHeader(\"content-length\", String(Buffer.byteLength(body)));\n res.end(body);\n } catch {\n this.respondJson(res, 404, { error: \"not_found\" });\n }\n }\n\n private async readJsonBody(req: IncomingMessage): Promise<Record<string, unknown>> {\n const chunks: Buffer[] = [];\n let total = 0;\n for await (const chunk of req) {\n const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);\n total += buffer.length;\n if (total > this.maxBodyBytes) {\n throw new HttpError(413, \"request_body_too_large\", \"request_body_too_large\");\n }\n chunks.push(buffer);\n }\n if (chunks.length === 0) return {};\n const raw = Buffer.concat(chunks).toString(\"utf-8\").trim();\n if (raw.length === 0) return {};\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n throw new HttpError(400, \"invalid_json\", \"invalid_json\");\n }\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n throw new HttpError(400, \"invalid_json_object\", \"invalid_json_object\");\n }\n return parsed as Record<string, unknown>;\n }\n\n private async readValidatedBody<S extends SchemaName>(req: IncomingMessage, schemaName: S): Promise<SchemaTypeFor<S>> {\n const raw = await this.readJsonBody(req);\n const result = validateRequest(schemaName, raw);\n if (!result.success) {\n throw new HttpError(400, result.error.error, \"validation_error\", result.error.details);\n }\n return result.data as SchemaTypeFor<S>;\n }\n\n private isAuthorized(req: IncomingMessage): boolean {\n if (!this.authToken && this.authTokens.length === 0 && !this.authTokensGetter) return false;\n const raw = req.headers.authorization;\n if (!raw) return false;\n const separator = raw.indexOf(\" \");\n if (separator <= 0) return false;\n const scheme = raw.slice(0, separator).toLowerCase();\n if (scheme !== \"bearer\") return false;\n const token = raw.slice(separator + 1).trim();\n // Check primary token\n if (this.authToken && this.timingSafeStringEqual(token, this.authToken)) return true;\n // Check static multi-connector tokens\n for (const valid of this.authTokens) {\n if (this.timingSafeStringEqual(token, valid)) return true;\n }\n // Check dynamic tokens (reloaded per request for generate/revoke without restart)\n if (this.authTokensGetter) {\n for (const valid of this.authTokensGetter()) {\n if (this.timingSafeStringEqual(token, valid)) return true;\n }\n }\n return false;\n }\n\n private timingSafeStringEqual(a: string, b: string): boolean {\n const left = this.encodeSecret(a);\n const right = this.encodeSecret(b);\n if (!left || !right) return false;\n return timingSafeEqual(left, right);\n }\n\n private encodeSecret(value: string): Buffer | null {\n const encoded = Buffer.from(value, \"utf-8\");\n if (encoded.length > 1024) return null;\n const out = Buffer.alloc(2 + 1024);\n out.writeUInt16BE(encoded.length, 0);\n encoded.copy(out, 2);\n return out;\n }\n\n private writeResponseStatus(response: { dryRun: boolean; status: string }): number {\n if (response.dryRun === true) return 200;\n if (response.status === \"stored\" || response.status === \"queued_for_review\") return 201;\n return 200;\n }\n\n private ensureWriteRateLimitAvailable(): void {\n const now = Date.now();\n while (\n this.writeRequestTimestamps.length > 0 &&\n now - (this.writeRequestTimestamps[0] ?? 0) > WRITE_RATE_LIMIT_WINDOW_MS\n ) {\n this.writeRequestTimestamps.shift();\n }\n if (this.writeRequestTimestamps.length >= WRITE_RATE_LIMIT_MAX_REQUESTS) {\n throw new HttpError(429, \"write_rate_limited\", \"write_rate_limited\");\n }\n }\n\n private recordWriteRateLimitHit(): void {\n this.writeRequestTimestamps.push(Date.now());\n }\n\n private shouldCountWriteRateLimit(response: { dryRun?: boolean; idempotencyReplay?: boolean }): boolean {\n return response.dryRun !== true && response.idempotencyReplay !== true;\n }\n}\n","/**\n * Adapter interface for external system identity resolution.\n *\n * Each adapter maps an external system's session/identity conventions\n * to Engram's namespace + principal model. Adapters are stateless and\n * lightweight — they don't manage lifecycles or load plugins.\n */\n\nexport interface AdapterContext {\n /** Raw HTTP headers from the incoming request */\n headers: Record<string, string | string[] | undefined>;\n /** MCP client info (from initialize handshake, if available) */\n clientInfo?: { name: string; version?: string };\n /** Explicit session key from request args */\n sessionKey?: string;\n}\n\nexport interface ResolvedIdentity {\n /** Engram namespace (scopes memory access) */\n namespace: string;\n /** Engram principal (authorization subject) */\n principal: string;\n /** Session key for continuity tracking */\n sessionKey?: string;\n /** Which adapter resolved this identity */\n adapterId: string;\n}\n\nexport interface EngramAdapter {\n /** Adapter identifier (e.g., \"claude-code\", \"codex\", \"hermes\", \"replit\") */\n readonly id: string;\n\n /** Whether this adapter recognizes the given request context */\n matches(context: AdapterContext): boolean;\n\n /** Map external session/identity to Engram namespace + principal */\n resolveIdentity(context: AdapterContext): ResolvedIdentity;\n}\n\n/**\n * Extract and trim a single header value from a headers record.\n * Returns undefined if the header is missing, empty, or all whitespace.\n */\nexport function headerValue(\n headers: Record<string, string | string[] | undefined>,\n key: string,\n): string | undefined {\n const raw = headers[key];\n const value = Array.isArray(raw) ? raw[0] : raw;\n return typeof value === \"string\" && value.trim().length > 0 ? value.trim() : undefined;\n}\n","import { headerValue, type AdapterContext, type EngramAdapter, type ResolvedIdentity } from \"./types.js\";\n\n/**\n * Claude Code adapter.\n *\n * Detection: Claude Code sends clientInfo.name = \"claude-code\" in the\n * MCP initialize handshake, and User-Agent: claude-code/<version> in\n * HTTP requests. Project path is available via MCP ListRoots capability\n * (server receives the cwd as a file:// URI root), not via headers.\n *\n * For HTTP REST (non-MCP) requests, detection relies on User-Agent or\n * user-configured X-Engram-Client-Id header in .claude.json headers.\n *\n * Namespace/principal can be set by configuring custom headers in\n * .claude.json or .mcp.json:\n * \"headers\": { \"X-Engram-Namespace\": \"my-project\", \"X-Engram-Principal\": \"my-team\" }\n */\nexport class ClaudeCodeAdapter implements EngramAdapter {\n readonly id = \"claude-code\";\n\n matches(context: AdapterContext): boolean {\n // Primary: MCP clientInfo from initialize handshake (exact match)\n if (context.clientInfo?.name === \"claude-code\") return true;\n\n // Fallback: User-Agent header (Claude Code sends \"claude-code/<version>\")\n const ua = headerValue(context.headers, \"user-agent\");\n if (ua && ua.toLowerCase().startsWith(\"claude-code/\")) return true;\n\n // Fallback: user-configured client identifier header\n const clientId = headerValue(context.headers, \"x-engram-client-id\");\n if (clientId?.toLowerCase() === \"claude-code\") return true;\n\n return false;\n }\n\n resolveIdentity(context: AdapterContext): ResolvedIdentity {\n // MCP session ID (standard MCP header, server-assigned)\n const mcpSessionId = headerValue(context.headers, \"mcp-session-id\");\n\n // Principal: explicit header > default\n const principal = headerValue(context.headers, \"x-engram-principal\")\n || \"claude-code\";\n\n // Namespace: explicit header > default\n const namespace = headerValue(context.headers, \"x-engram-namespace\")\n || \"claude-code\";\n\n return {\n namespace,\n principal,\n sessionKey: mcpSessionId ?? context.sessionKey,\n adapterId: this.id,\n };\n }\n}\n\n","import { headerValue, type AdapterContext, type EngramAdapter, type ResolvedIdentity } from \"./types.js\";\n\n/**\n * Codex CLI adapter.\n *\n * Detection: Codex CLI sends clientInfo.name = \"codex-mcp-client\" and\n * clientInfo.title = \"Codex\" in the MCP initialize handshake. It does\n * NOT send agent names, session IDs, or project context automatically.\n *\n * For Streamable HTTP transport, Codex supports custom headers via\n * http_headers in ~/.codex/config.toml:\n * [mcp_servers.engram]\n * url = \"http://localhost:4318/mcp\"\n * http_headers = { \"X-Engram-Namespace\" = \"my-project\", \"X-Engram-Principal\" = \"codex-agent\" }\n *\n * Codex also sends a custom \"sandbox_state\" RPC notification after\n * init with sandbox policy info (read-only/writable paths).\n */\nexport class CodexAdapter implements EngramAdapter {\n readonly id = \"codex\";\n\n matches(context: AdapterContext): boolean {\n // Primary: MCP clientInfo from initialize handshake (exact match)\n if (context.clientInfo?.name === \"codex-mcp-client\") return true;\n\n // Also match on clientInfo name containing \"codex\" for forward compat\n const clientName = context.clientInfo?.name?.toLowerCase() ?? \"\";\n if (clientName.includes(\"codex\") && clientName !== \"codex-mcp-client\") return true;\n\n // Fallback: user-configured client identifier header\n const clientId = headerValue(context.headers, \"x-engram-client-id\");\n if (clientId?.toLowerCase() === \"codex\") return true;\n\n return false;\n }\n\n resolveIdentity(context: AdapterContext): ResolvedIdentity {\n // MCP session ID (standard MCP header, server-assigned)\n const mcpSessionId = headerValue(context.headers, \"mcp-session-id\");\n\n // Principal: explicit header > default\n const principal = headerValue(context.headers, \"x-engram-principal\")\n || \"codex\";\n\n // Namespace: explicit header > default\n const namespace = headerValue(context.headers, \"x-engram-namespace\")\n || \"codex\";\n\n return {\n namespace,\n principal,\n sessionKey: mcpSessionId ?? context.sessionKey,\n adapterId: this.id,\n };\n }\n}\n\n","import { headerValue, type AdapterContext, type EngramAdapter, type ResolvedIdentity } from \"./types.js\";\n\n/**\n * Replit Agent adapter.\n *\n * Detection: Replit Agent supports MCP natively (HTTP-only, configured\n * via the Integrations pane). It does NOT send identifying headers\n * automatically — detection relies on user-configured custom headers\n * in Replit's MCP Integrations UI.\n *\n * Replit provides env vars to running code (REPL_ID, REPL_OWNER,\n * REPL_SLUG) but these are NOT sent as HTTP headers to MCP servers.\n *\n * To identify Replit connections, users should configure a custom header\n * in the Replit Integrations pane when adding the Engram MCP server:\n * Header Name: X-Engram-Client-Id\n * Header Value: replit\n *\n * Optionally also set X-Engram-Namespace and X-Engram-Principal for\n * project/user scoping.\n */\nexport class ReplitAdapter implements EngramAdapter {\n readonly id = \"replit\";\n\n matches(context: AdapterContext): boolean {\n // Primary: user-configured client identifier header\n const clientId = headerValue(context.headers, \"x-engram-client-id\");\n if (clientId?.toLowerCase() === \"replit\") return true;\n\n // MCP clientInfo (Replit's MCP client name is not publicly documented,\n // but check for it in case it becomes available)\n const clientName = context.clientInfo?.name?.toLowerCase() ?? \"\";\n if (clientName.includes(\"replit\")) return true;\n\n return false;\n }\n\n resolveIdentity(context: AdapterContext): ResolvedIdentity {\n const mcpSessionId = headerValue(context.headers, \"mcp-session-id\");\n\n const principal = headerValue(context.headers, \"x-engram-principal\")\n || \"replit-agent\";\n\n const namespace = headerValue(context.headers, \"x-engram-namespace\")\n || \"replit\";\n\n return {\n namespace,\n principal,\n sessionKey: mcpSessionId ?? context.sessionKey,\n adapterId: this.id,\n };\n }\n}\n\n","import { headerValue, type AdapterContext, type EngramAdapter, type ResolvedIdentity } from \"./types.js\";\n\n/**\n * Hermes Agent adapter.\n *\n * Detection: Hermes supports both MCP (via config.yaml mcp_servers)\n * and a dedicated MemoryProvider plugin protocol (Python). The MCP\n * client name is not yet publicly documented, so detection uses:\n *\n * 1. X-Hermes-Session-Id header — confirmed in v0.7.0 API server\n * 2. User-configured headers in Hermes MCP config:\n * mcp_servers:\n * engram:\n * url: \"http://localhost:4318/mcp\"\n * headers:\n * X-Engram-Client-Id: \"hermes\"\n * X-Engram-Namespace: \"my-profile\"\n * 3. MCP clientInfo name containing \"hermes\" (for forward compat)\n *\n * Hermes profiles isolate agent state under ~/.hermes/profiles/<name>/.\n * Each profile can map to a separate Engram namespace via the\n * X-Engram-Namespace header.\n *\n * For deeper integration, Hermes v0.7.0+ supports MemoryProvider\n * plugins (Python protocol with initialize/enrich_turn/sync_turn/\n * shutdown). A Python Engram MemoryProvider plugin would be the\n * optimal integration path — see docs/integration/hermes-setup.md.\n */\nexport class HermesAdapter implements EngramAdapter {\n readonly id = \"hermes\";\n\n matches(context: AdapterContext): boolean {\n // Confirmed header from Hermes v0.7.0 API server\n if (headerValue(context.headers, \"x-hermes-session-id\")) return true;\n\n // User-configured client identifier header\n const clientId = headerValue(context.headers, \"x-engram-client-id\");\n if (clientId?.toLowerCase() === \"hermes\") return true;\n\n // MCP clientInfo (for forward compat when Hermes documents its name)\n const clientName = context.clientInfo?.name?.toLowerCase() ?? \"\";\n if (clientName.includes(\"hermes\")) return true;\n\n return false;\n }\n\n resolveIdentity(context: AdapterContext): ResolvedIdentity {\n const sessionId = headerValue(context.headers, \"x-hermes-session-id\");\n\n const principal = headerValue(context.headers, \"x-engram-principal\")\n || \"hermes-agent\";\n\n const namespace = headerValue(context.headers, \"x-engram-namespace\")\n || \"hermes\";\n\n return {\n namespace,\n principal,\n sessionKey: sessionId ?? context.sessionKey,\n adapterId: this.id,\n };\n }\n}\n\n","import type { AdapterContext, EngramAdapter, ResolvedIdentity } from \"./types.js\";\nimport { ClaudeCodeAdapter } from \"./claude-code.js\";\nimport { CodexAdapter } from \"./codex.js\";\nimport { ReplitAdapter } from \"./replit.js\";\nimport { HermesAdapter } from \"./hermes.js\";\n\n/**\n * Adapter registry. Attempts to identify which external system is\n * connecting by checking each registered adapter in order. Falls back\n * to explicit namespace/principal from the request args.\n */\nexport class AdapterRegistry {\n private readonly adapters: EngramAdapter[];\n\n constructor(adapters?: EngramAdapter[]) {\n this.adapters = adapters ?? [\n new HermesAdapter(),\n new ReplitAdapter(),\n new CodexAdapter(),\n new ClaudeCodeAdapter(),\n ];\n }\n\n /**\n * Try each adapter in order. Return the first match, or null if\n * no adapter recognizes the request context.\n */\n resolve(context: AdapterContext): ResolvedIdentity | null {\n for (const adapter of this.adapters) {\n if (adapter.matches(context)) {\n return adapter.resolveIdentity(context);\n }\n }\n return null;\n }\n\n /** List registered adapter IDs */\n list(): string[] {\n return this.adapters.map((a) => a.id);\n }\n}\n"],"mappings":"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","names":[]}
|