@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.
Files changed (287) hide show
  1. package/dist/access-audit.d.ts +56 -0
  2. package/dist/access-audit.js +9 -0
  3. package/dist/access-cli.js +62 -45
  4. package/dist/access-cli.js.map +1 -1
  5. package/dist/access-http.d.ts +16 -9
  6. package/dist/access-http.js +25 -17
  7. package/dist/access-mcp.d.ts +16 -9
  8. package/dist/access-mcp.js +29 -7
  9. package/dist/access-schema.d.ts +124 -33
  10. package/dist/access-schema.js +5 -1
  11. package/dist/{access-service-HmO1Trrx.d.ts → access-service-Br8ZydTK.d.ts} +158 -63
  12. package/dist/access-service.d.ts +13 -6
  13. package/dist/access-service.js +22 -14
  14. package/dist/bootstrap.d.ts +6 -3
  15. package/dist/briefing.d.ts +1 -0
  16. package/dist/briefing.js +7 -6
  17. package/dist/buffer-surprise-report.d.ts +70 -0
  18. package/dist/buffer-surprise-report.js +7 -0
  19. package/dist/buffer-surprise-report.js.map +1 -0
  20. package/dist/buffer-surprise.d.ts +98 -0
  21. package/dist/buffer-surprise.js +11 -0
  22. package/dist/buffer-surprise.js.map +1 -0
  23. package/dist/buffer.d.ts +100 -2
  24. package/dist/buffer.js +1 -1
  25. package/dist/calibration.js +5 -5
  26. package/dist/causal-behavior.js +4 -4
  27. package/dist/causal-chain.js +2 -2
  28. package/dist/causal-consolidation.js +17 -16
  29. package/dist/causal-consolidation.js.map +1 -1
  30. package/dist/causal-retrieval.js +4 -4
  31. package/dist/causal-trajectory.js +1 -1
  32. package/dist/{chunk-QNJMBKFK.js → chunk-2LGMW3DJ.js} +3 -2
  33. package/dist/chunk-2LGMW3DJ.js.map +1 -0
  34. package/dist/{chunk-QDYXG4CS.js → chunk-3FPTCC3Z.js} +4 -3
  35. package/dist/chunk-3FPTCC3Z.js.map +1 -0
  36. package/dist/chunk-3GPTTA4J.js +57 -0
  37. package/dist/chunk-3GPTTA4J.js.map +1 -0
  38. package/dist/{chunk-44ICJRF3.js → chunk-3GXCSUXR.js} +4 -4
  39. package/dist/{chunk-ITRLGI2T.js → chunk-3OGMS3PE.js} +2 -2
  40. package/dist/chunk-54V4BZWP.js +139 -0
  41. package/dist/chunk-54V4BZWP.js.map +1 -0
  42. package/dist/chunk-5JRF2PZA.js +67 -0
  43. package/dist/chunk-5JRF2PZA.js.map +1 -0
  44. package/dist/chunk-64NJRYU2.js +332 -0
  45. package/dist/chunk-64NJRYU2.js.map +1 -0
  46. package/dist/{chunk-OIT5QGG4.js → chunk-6AUUAZEX.js} +72 -2
  47. package/dist/chunk-6AUUAZEX.js.map +1 -0
  48. package/dist/{chunk-ZVBB3T7V.js → chunk-7I7FKFZH.js} +24 -22
  49. package/dist/chunk-7I7FKFZH.js.map +1 -0
  50. package/dist/chunk-AJU4PJGY.js +126 -0
  51. package/dist/chunk-AJU4PJGY.js.map +1 -0
  52. package/dist/chunk-ASAITVLA.js +64 -0
  53. package/dist/chunk-ASAITVLA.js.map +1 -0
  54. package/dist/{chunk-3QHL5ABG.js → chunk-B5WXLVDY.js} +187 -6
  55. package/dist/chunk-B5WXLVDY.js.map +1 -0
  56. package/dist/{chunk-SYUK3VLY.js → chunk-BGJGXLZ7.js} +111 -2
  57. package/dist/{chunk-SYUK3VLY.js.map → chunk-BGJGXLZ7.js.map} +1 -1
  58. package/dist/{chunk-MBJHSA7F.js → chunk-BK2EFTE2.js} +258 -13
  59. package/dist/chunk-BK2EFTE2.js.map +1 -0
  60. package/dist/chunk-C4SQJZAF.js +486 -0
  61. package/dist/chunk-C4SQJZAF.js.map +1 -0
  62. package/dist/{chunk-6UJ47TVX.js → chunk-CUPFXL3J.js} +2 -2
  63. package/dist/chunk-DF3RVK3X.js +119 -0
  64. package/dist/chunk-DF3RVK3X.js.map +1 -0
  65. package/dist/{chunk-37UIFYWO.js → chunk-DFTTJYSO.js} +108 -9
  66. package/dist/chunk-DFTTJYSO.js.map +1 -0
  67. package/dist/chunk-DGVM5SFL.js +69 -0
  68. package/dist/chunk-DGVM5SFL.js.map +1 -0
  69. package/dist/chunk-EIR5VLIH.js +90 -0
  70. package/dist/chunk-EIR5VLIH.js.map +1 -0
  71. package/dist/{chunk-PAORGQRI.js → chunk-EPQJM2GC.js} +37 -23
  72. package/dist/chunk-EPQJM2GC.js.map +1 -0
  73. package/dist/{chunk-GV6NLQ4X.js → chunk-F5VP6YCB.js} +374 -16
  74. package/dist/chunk-F5VP6YCB.js.map +1 -0
  75. package/dist/{chunk-6ZH4TU6I.js → chunk-FAAFWE4G.js} +2 -1
  76. package/dist/chunk-FAAFWE4G.js.map +1 -0
  77. package/dist/{chunk-7WQ6SLIE.js → chunk-FVA6TGI3.js} +2 -2
  78. package/dist/chunk-GDFS42HT.js +206 -0
  79. package/dist/chunk-GDFS42HT.js.map +1 -0
  80. package/dist/{chunk-MVTHXUBX.js → chunk-GKFXUTJ2.js} +479 -20
  81. package/dist/chunk-GKFXUTJ2.js.map +1 -0
  82. package/dist/{chunk-NQEVYWX6.js → chunk-HK3FGIEW.js} +209 -5
  83. package/dist/chunk-HK3FGIEW.js.map +1 -0
  84. package/dist/chunk-IISBCCWR.js +52 -0
  85. package/dist/chunk-IISBCCWR.js.map +1 -0
  86. package/dist/{chunk-WBSAYXVI.js → chunk-INXV5JBT.js} +198 -42
  87. package/dist/chunk-INXV5JBT.js.map +1 -0
  88. package/dist/chunk-JBMSGZEQ.js +441 -0
  89. package/dist/chunk-JBMSGZEQ.js.map +1 -0
  90. package/dist/{chunk-J4IYOZZ5.js → chunk-JXS5PDQ7.js} +3 -1
  91. package/dist/chunk-JXS5PDQ7.js.map +1 -0
  92. package/dist/{chunk-6LX5ORAS.js → chunk-KUB6JU6H.js} +4 -4
  93. package/dist/chunk-KVBLZUKV.js +173 -0
  94. package/dist/chunk-KVBLZUKV.js.map +1 -0
  95. package/dist/chunk-LBLXEFWK.js +51 -0
  96. package/dist/chunk-LBLXEFWK.js.map +1 -0
  97. package/dist/{chunk-3WHVNEN7.js → chunk-LTCGGW2D.js} +1 -1
  98. package/dist/chunk-LTCGGW2D.js.map +1 -0
  99. package/dist/{chunk-UEYA6UC7.js → chunk-NZLQTHS5.js} +25 -2
  100. package/dist/chunk-NZLQTHS5.js.map +1 -0
  101. package/dist/chunk-PVPWZSSI.js +37 -0
  102. package/dist/chunk-PVPWZSSI.js.map +1 -0
  103. package/dist/{chunk-4NRAJUDS.js → chunk-RBBWYEFJ.js} +1 -1
  104. package/dist/chunk-RFYAYKTD.js +146 -0
  105. package/dist/chunk-RFYAYKTD.js.map +1 -0
  106. package/dist/{chunk-DHHP2Z4X.js → chunk-RGLL5SPU.js} +2 -2
  107. package/dist/{chunk-3SV6CQHO.js → chunk-S3EEFKNY.js} +101 -65
  108. package/dist/chunk-S3EEFKNY.js.map +1 -0
  109. package/dist/chunk-SOBJ6NEY.js +18 -0
  110. package/dist/chunk-SOBJ6NEY.js.map +1 -0
  111. package/dist/{chunk-JIU55F3X.js → chunk-SPI27QT6.js} +2 -2
  112. package/dist/chunk-TVVEYCNW.js +65 -0
  113. package/dist/chunk-TVVEYCNW.js.map +1 -0
  114. package/dist/chunk-ULYOGL6R.js +322 -0
  115. package/dist/chunk-ULYOGL6R.js.map +1 -0
  116. package/dist/{chunk-47UU5PU2.js → chunk-VBVG2M5G.js} +18 -3
  117. package/dist/chunk-VBVG2M5G.js.map +1 -0
  118. package/dist/{chunk-7ECD5ATE.js → chunk-VDX363PS.js} +2 -2
  119. package/dist/{chunk-DEPL3635.js → chunk-VYM3VWOF.js} +1432 -188
  120. package/dist/chunk-VYM3VWOF.js.map +1 -0
  121. package/dist/{chunk-MTLYEMJB.js → chunk-WCLICCGB.js} +18 -3
  122. package/dist/chunk-WCLICCGB.js.map +1 -0
  123. package/dist/{chunk-4LACOVZX.js → chunk-WVVA7F5A.js} +2 -2
  124. package/dist/chunk-X6GF3FX2.js +26 -0
  125. package/dist/chunk-X6GF3FX2.js.map +1 -0
  126. package/dist/{chunk-3QFQGRHO.js → chunk-XMHBH5H6.js} +4 -4
  127. package/dist/{chunk-BLKTA7MM.js → chunk-YNQKWQT4.js} +50 -17
  128. package/dist/chunk-YNQKWQT4.js.map +1 -0
  129. package/dist/chunk-ZAIM4TUE.js +488 -0
  130. package/dist/chunk-ZAIM4TUE.js.map +1 -0
  131. package/dist/{chunk-N42IWANG.js → chunk-ZEM3OK2K.js} +2 -2
  132. package/dist/chunk-ZZTOURJI.js +91 -0
  133. package/dist/chunk-ZZTOURJI.js.map +1 -0
  134. package/dist/{cli-BneVIEvh.d.ts → cli-BkeRaYfk.d.ts} +2 -2
  135. package/dist/cli.d.ts +13 -6
  136. package/dist/cli.js +40 -29
  137. package/dist/config.js +1 -1
  138. package/dist/consolidation-operator.d.ts +41 -0
  139. package/dist/consolidation-operator.js +11 -0
  140. package/dist/consolidation-operator.js.map +1 -0
  141. package/dist/consolidation-provenance-check.d.ts +68 -0
  142. package/dist/consolidation-provenance-check.js +9 -0
  143. package/dist/consolidation-provenance-check.js.map +1 -0
  144. package/dist/consolidation-undo.d.ts +123 -0
  145. package/dist/consolidation-undo.js +426 -0
  146. package/dist/consolidation-undo.js.map +1 -0
  147. package/dist/{contradiction-scan-GR33PONM.js → contradiction-scan-E3GJTI4F.js} +43 -7
  148. package/dist/contradiction-scan-E3GJTI4F.js.map +1 -0
  149. package/dist/cross-namespace-budget.d.ts +133 -0
  150. package/dist/cross-namespace-budget.js +9 -0
  151. package/dist/cross-namespace-budget.js.map +1 -0
  152. package/dist/direct-answer-wiring.js +5 -70
  153. package/dist/direct-answer-wiring.js.map +1 -1
  154. package/dist/{engine-5TIQBYZR.js → engine-F3GOXGE5.js} +8 -7
  155. package/dist/engine-F3GOXGE5.js.map +1 -0
  156. package/dist/entity-retrieval.d.ts +1 -0
  157. package/dist/entity-retrieval.js +7 -6
  158. package/dist/explicit-capture.d.ts +6 -3
  159. package/dist/explicit-capture.js +2 -2
  160. package/dist/extraction-judge-telemetry.d.ts +113 -0
  161. package/dist/extraction-judge-telemetry.js +14 -0
  162. package/dist/extraction-judge-telemetry.js.map +1 -0
  163. package/dist/extraction-judge-training.d.ts +85 -0
  164. package/dist/extraction-judge-training.js +16 -0
  165. package/dist/extraction-judge-training.js.map +1 -0
  166. package/dist/extraction-judge.d.ts +124 -2
  167. package/dist/extraction-judge.js +11 -1
  168. package/dist/extraction.js +6 -5
  169. package/dist/fallback-llm.js +2 -2
  170. package/dist/graph-recall.d.ts +100 -0
  171. package/dist/graph-recall.js +8 -0
  172. package/dist/graph-recall.js.map +1 -0
  173. package/dist/graph-retrieval.d.ts +271 -0
  174. package/dist/graph-retrieval.js +21 -0
  175. package/dist/graph-retrieval.js.map +1 -0
  176. package/dist/importance.js +1 -1
  177. package/dist/index.d.ts +585 -20
  178. package/dist/index.js +503 -312
  179. package/dist/index.js.map +1 -1
  180. package/dist/memory-worth-bench.d.ts +51 -0
  181. package/dist/memory-worth-bench.js +131 -0
  182. package/dist/memory-worth-bench.js.map +1 -0
  183. package/dist/memory-worth-filter.d.ts +128 -0
  184. package/dist/memory-worth-filter.js +10 -0
  185. package/dist/memory-worth-filter.js.map +1 -0
  186. package/dist/memory-worth-outcomes.d.ts +118 -0
  187. package/dist/memory-worth-outcomes.js +9 -0
  188. package/dist/memory-worth-outcomes.js.map +1 -0
  189. package/dist/memory-worth.d.ts +102 -0
  190. package/dist/memory-worth.js +7 -0
  191. package/dist/memory-worth.js.map +1 -0
  192. package/dist/operator-toolkit.d.ts +40 -1
  193. package/dist/operator-toolkit.js +23 -14
  194. package/dist/{orchestrator-DRYA6_lW.d.ts → orchestrator-CmJ-NTdJ.d.ts} +233 -8
  195. package/dist/orchestrator.d.ts +6 -3
  196. package/dist/orchestrator.js +49 -39
  197. package/dist/page-versioning.d.ts +12 -1
  198. package/dist/page-versioning.js +5 -3
  199. package/dist/{port-C1GZFv8h.d.ts → port-BADbLZU5.d.ts} +2 -2
  200. package/dist/qmd-recall-cache.d.ts +1 -1
  201. package/dist/qmd.d.ts +5 -3
  202. package/dist/qmd.js +1 -1
  203. package/dist/reasoning-trace-recall.d.ts +90 -0
  204. package/dist/reasoning-trace-recall.js +13 -0
  205. package/dist/reasoning-trace-recall.js.map +1 -0
  206. package/dist/reasoning-trace-types.d.ts +54 -0
  207. package/dist/reasoning-trace-types.js +17 -0
  208. package/dist/reasoning-trace-types.js.map +1 -0
  209. package/dist/recall-audit-anomaly.d.ts +112 -0
  210. package/dist/recall-audit-anomaly.js +11 -0
  211. package/dist/recall-audit-anomaly.js.map +1 -0
  212. package/dist/recall-audit.js +5 -44
  213. package/dist/recall-audit.js.map +1 -1
  214. package/dist/recall-explain-renderer.d.ts +49 -0
  215. package/dist/recall-explain-renderer.js +18 -0
  216. package/dist/recall-explain-renderer.js.map +1 -0
  217. package/dist/recall-state.d.ts +12 -1
  218. package/dist/recall-state.js +1 -1
  219. package/dist/recall-xray-cli.d.ts +40 -0
  220. package/dist/recall-xray-cli.js +11 -0
  221. package/dist/recall-xray-cli.js.map +1 -0
  222. package/dist/recall-xray-renderer.d.ts +44 -0
  223. package/dist/recall-xray-renderer.js +18 -0
  224. package/dist/recall-xray-renderer.js.map +1 -0
  225. package/dist/recall-xray.d.ts +179 -0
  226. package/dist/recall-xray.js +13 -0
  227. package/dist/recall-xray.js.map +1 -0
  228. package/dist/resume-bundles.js +5 -5
  229. package/dist/retrieval-agents.d.ts +1 -1
  230. package/dist/retrieval-tiers.d.ts +17 -0
  231. package/dist/retrieval-tiers.js +9 -0
  232. package/dist/retrieval-tiers.js.map +1 -0
  233. package/dist/schemas.d.ts +287 -31
  234. package/dist/schemas.js +1 -1
  235. package/dist/{semantic-consolidation-DrvSYRdB.d.ts → semantic-consolidation-CxJU6MJk.d.ts} +62 -1
  236. package/dist/semantic-consolidation.d.ts +2 -1
  237. package/dist/semantic-consolidation.js +21 -7
  238. package/dist/semantic-rule-promotion.js +7 -6
  239. package/dist/semantic-rule-verifier.js +7 -6
  240. package/dist/storage.d.ts +82 -1
  241. package/dist/storage.js +6 -5
  242. package/dist/summarizer.js +3 -3
  243. package/dist/temporal-supersession.d.ts +1 -0
  244. package/dist/tier-migration.d.ts +2 -1
  245. package/dist/types.d.ts +276 -2
  246. package/dist/types.js +1 -1
  247. package/dist/verified-recall.js +7 -6
  248. package/package.json +1 -1
  249. package/dist/chunk-37UIFYWO.js.map +0 -1
  250. package/dist/chunk-3QHL5ABG.js.map +0 -1
  251. package/dist/chunk-3SV6CQHO.js.map +0 -1
  252. package/dist/chunk-3WHVNEN7.js.map +0 -1
  253. package/dist/chunk-47UU5PU2.js.map +0 -1
  254. package/dist/chunk-6ZH4TU6I.js.map +0 -1
  255. package/dist/chunk-BLKTA7MM.js.map +0 -1
  256. package/dist/chunk-DEPL3635.js.map +0 -1
  257. package/dist/chunk-GV6NLQ4X.js.map +0 -1
  258. package/dist/chunk-J4IYOZZ5.js.map +0 -1
  259. package/dist/chunk-LAYN4LDC.js +0 -267
  260. package/dist/chunk-LAYN4LDC.js.map +0 -1
  261. package/dist/chunk-MBJHSA7F.js.map +0 -1
  262. package/dist/chunk-MTLYEMJB.js.map +0 -1
  263. package/dist/chunk-MVTHXUBX.js.map +0 -1
  264. package/dist/chunk-NQEVYWX6.js.map +0 -1
  265. package/dist/chunk-OIT5QGG4.js.map +0 -1
  266. package/dist/chunk-PAORGQRI.js.map +0 -1
  267. package/dist/chunk-QDYXG4CS.js.map +0 -1
  268. package/dist/chunk-QNJMBKFK.js.map +0 -1
  269. package/dist/chunk-UEYA6UC7.js.map +0 -1
  270. package/dist/chunk-UVJFDP7P.js +0 -202
  271. package/dist/chunk-UVJFDP7P.js.map +0 -1
  272. package/dist/chunk-WBSAYXVI.js.map +0 -1
  273. package/dist/chunk-ZVBB3T7V.js.map +0 -1
  274. package/dist/contradiction-scan-GR33PONM.js.map +0 -1
  275. /package/dist/{engine-5TIQBYZR.js.map → access-audit.js.map} +0 -0
  276. /package/dist/{chunk-44ICJRF3.js.map → chunk-3GXCSUXR.js.map} +0 -0
  277. /package/dist/{chunk-ITRLGI2T.js.map → chunk-3OGMS3PE.js.map} +0 -0
  278. /package/dist/{chunk-6UJ47TVX.js.map → chunk-CUPFXL3J.js.map} +0 -0
  279. /package/dist/{chunk-7WQ6SLIE.js.map → chunk-FVA6TGI3.js.map} +0 -0
  280. /package/dist/{chunk-6LX5ORAS.js.map → chunk-KUB6JU6H.js.map} +0 -0
  281. /package/dist/{chunk-4NRAJUDS.js.map → chunk-RBBWYEFJ.js.map} +0 -0
  282. /package/dist/{chunk-DHHP2Z4X.js.map → chunk-RGLL5SPU.js.map} +0 -0
  283. /package/dist/{chunk-JIU55F3X.js.map → chunk-SPI27QT6.js.map} +0 -0
  284. /package/dist/{chunk-7ECD5ATE.js.map → chunk-VDX363PS.js.map} +0 -0
  285. /package/dist/{chunk-4LACOVZX.js.map → chunk-WVVA7F5A.js.map} +0 -0
  286. /package/dist/{chunk-3QFQGRHO.js.map → chunk-XMHBH5H6.js.map} +0 -0
  287. /package/dist/{chunk-N42IWANG.js.map → chunk-ZEM3OK2K.js.map} +0 -0
@@ -2,7 +2,7 @@ import {
2
2
  CompoundingEngine,
3
3
  SharedContextManager,
4
4
  defaultTierMigrationCycleBudget
5
- } from "./chunk-DHHP2Z4X.js";
5
+ } from "./chunk-RGLL5SPU.js";
6
6
  import {
7
7
  extractTopics
8
8
  } from "./chunk-UHGBNIOS.js";
@@ -11,9 +11,6 @@ import {
11
11
  applyUtilityRankingRuntimeDelta,
12
12
  loadUtilityRuntimeValues
13
13
  } from "./chunk-FSFEQI74.js";
14
- import {
15
- HourlySummarizer
16
- } from "./chunk-N42IWANG.js";
17
14
  import {
18
15
  applyTemporalSupersession,
19
16
  normalizeSupersessionKey,
@@ -32,11 +29,8 @@ import {
32
29
  SessionObserverState
33
30
  } from "./chunk-JR4ZC3G4.js";
34
31
  import {
35
- semanticChunkContent
36
- } from "./chunk-KVE7R4CG.js";
37
- import {
38
- findUnresolvedEntityRefs
39
- } from "./chunk-X7XN6YU4.js";
32
+ HourlySummarizer
33
+ } from "./chunk-ZEM3OK2K.js";
40
34
  import {
41
35
  RelevanceStore
42
36
  } from "./chunk-5NPGSAVB.js";
@@ -66,10 +60,19 @@ import {
66
60
  applyRuntimeRetrievalPolicy
67
61
  } from "./chunk-5IZL4DCV.js";
68
62
  import {
69
- buildQmdRecallCacheKey,
70
- getCachedQmdRecall,
71
- setCachedQmdRecall
72
- } from "./chunk-YCN4BVDK.js";
63
+ LastRecallStore,
64
+ TierMigrationStatusStore,
65
+ clampGraphRecallExpandedEntries
66
+ } from "./chunk-VBVG2M5G.js";
67
+ import {
68
+ buildXraySnapshot
69
+ } from "./chunk-KVBLZUKV.js";
70
+ import {
71
+ findUnresolvedEntityRefs
72
+ } from "./chunk-X7XN6YU4.js";
73
+ import {
74
+ applyReasoningTraceBoost
75
+ } from "./chunk-ZZTOURJI.js";
73
76
  import {
74
77
  reorderRecallResultsWithMmr
75
78
  } from "./chunk-YDBIWGNI.js";
@@ -77,10 +80,10 @@ import {
77
80
  createRecallSectionMetricRecorder
78
81
  } from "./chunk-7DHTMOND.js";
79
82
  import {
80
- LastRecallStore,
81
- TierMigrationStatusStore,
82
- clampGraphRecallExpandedEntries
83
- } from "./chunk-47UU5PU2.js";
83
+ buildQmdRecallCacheKey,
84
+ getCachedQmdRecall,
85
+ setCachedQmdRecall
86
+ } from "./chunk-YCN4BVDK.js";
84
87
  import {
85
88
  NegativeExampleStore
86
89
  } from "./chunk-D654IBA6.js";
@@ -88,8 +91,9 @@ import {
88
91
  evaluateMemoryActionPolicy
89
92
  } from "./chunk-H63EDPFJ.js";
90
93
  import {
91
- classifyMemoryKind
92
- } from "./chunk-YAZNBMNF.js";
94
+ applyMemoryWorthFilter,
95
+ buildMemoryWorthCounterMap
96
+ } from "./chunk-3GPTTA4J.js";
93
97
  import {
94
98
  hasBroadGraphIntent,
95
99
  inferIntentFromText,
@@ -98,16 +102,28 @@ import {
98
102
  planRecallMode
99
103
  } from "./chunk-GGD5W7TB.js";
100
104
  import {
105
+ classifyMemoryKind
106
+ } from "./chunk-YAZNBMNF.js";
107
+ import {
108
+ EXTRACTION_JUDGE_VERDICT_CATEGORY,
109
+ recordJudgeVerdict
110
+ } from "./chunk-AJU4PJGY.js";
111
+ import {
112
+ recordJudgeTrainingPair
113
+ } from "./chunk-DF3RVK3X.js";
114
+ import {
115
+ createDeferCountMap,
101
116
  createVerdictCache,
117
+ getVerdictKind,
102
118
  judgeFactDurability,
103
119
  validateProcedureExtraction
104
- } from "./chunk-LAYN4LDC.js";
120
+ } from "./chunk-C4SQJZAF.js";
105
121
  import {
106
122
  ExtractionEngine
107
- } from "./chunk-3SV6CQHO.js";
123
+ } from "./chunk-S3EEFKNY.js";
108
124
  import {
109
125
  parseMemoryActionEligibilityContext
110
- } from "./chunk-UEYA6UC7.js";
126
+ } from "./chunk-NZLQTHS5.js";
111
127
  import {
112
128
  ProfilingCollector
113
129
  } from "./chunk-NBNN5GOB.js";
@@ -118,8 +134,8 @@ import {
118
134
  LocalLlmClient
119
135
  } from "./chunk-JL2PU6AI.js";
120
136
  import {
121
- formatDaySummaryMemories
122
- } from "./chunk-GZCUW5IC.js";
137
+ tryDirectAnswer
138
+ } from "./chunk-6AUUAZEX.js";
123
139
  import {
124
140
  EmbeddingFallback
125
141
  } from "./chunk-ALXMCZEU.js";
@@ -127,20 +143,24 @@ import {
127
143
  buildEntityRecallSection,
128
144
  entityRecentTranscriptLookbackHours,
129
145
  readRecentEntityTranscriptEntries
130
- } from "./chunk-7WQ6SLIE.js";
146
+ } from "./chunk-FVA6TGI3.js";
147
+ import {
148
+ formatDaySummaryMemories
149
+ } from "./chunk-GZCUW5IC.js";
131
150
  import {
132
151
  RoutingRulesStore,
152
+ expandTildePath,
133
153
  normalizeReplaySessionKey
134
- } from "./chunk-PAORGQRI.js";
154
+ } from "./chunk-EPQJM2GC.js";
135
155
  import {
136
156
  searchVerifiedEpisodes
137
- } from "./chunk-6UJ47TVX.js";
157
+ } from "./chunk-CUPFXL3J.js";
138
158
  import {
139
159
  ThreadingManager
140
160
  } from "./chunk-JRNQ3RNA.js";
141
161
  import {
142
162
  searchVerifiedSemanticRules
143
- } from "./chunk-JIU55F3X.js";
163
+ } from "./chunk-SPI27QT6.js";
144
164
  import {
145
165
  searchWorkProductLedgerEntries
146
166
  } from "./chunk-CULXMQJH.js";
@@ -154,10 +174,10 @@ import {
154
174
  createConversationIndexRuntime,
155
175
  createSearchBackend,
156
176
  writeConversationChunks
157
- } from "./chunk-ZVBB3T7V.js";
177
+ } from "./chunk-7I7FKFZH.js";
158
178
  import {
159
179
  parseQmdExplain
160
- } from "./chunk-BLKTA7MM.js";
180
+ } from "./chunk-YNQKWQT4.js";
161
181
  import {
162
182
  PolicyRuntimeManager
163
183
  } from "./chunk-EABGC2TL.js";
@@ -170,7 +190,10 @@ import {
170
190
  import {
171
191
  isAboveImportanceThreshold,
172
192
  scoreImportance
173
- } from "./chunk-J4IYOZZ5.js";
193
+ } from "./chunk-JXS5PDQ7.js";
194
+ import {
195
+ launchProcessSync
196
+ } from "./chunk-LK6SGL53.js";
174
197
  import {
175
198
  collectNativeKnowledgeChunks,
176
199
  formatNativeKnowledgeSection,
@@ -179,6 +202,9 @@ import {
179
202
  import {
180
203
  recordEvalShadowRecall
181
204
  } from "./chunk-K6WK37A6.js";
205
+ import {
206
+ GraphIndex
207
+ } from "./chunk-C2EFFULQ.js";
182
208
  import {
183
209
  CODEX_THREAD_KEY_PREFIX
184
210
  } from "./chunk-3PG3H5TD.js";
@@ -191,22 +217,28 @@ import {
191
217
  refineCompressionGuidelineCandidateSemantically,
192
218
  renderCompressionGuidelinesMarkdown
193
219
  } from "./chunk-2NMMFZ5T.js";
220
+ import {
221
+ semanticChunkContent
222
+ } from "./chunk-KVE7R4CG.js";
223
+ import {
224
+ chunkContent
225
+ } from "./chunk-4WMCPJWX.js";
226
+ import {
227
+ SmartBuffer
228
+ } from "./chunk-JBMSGZEQ.js";
194
229
  import {
195
230
  buildConsolidationPrompt,
196
231
  buildExtensionsBlockForConsolidation,
232
+ buildOperatorAwareConsolidationPrompt,
233
+ chooseConsolidationOperator,
197
234
  findSimilarClusters,
198
235
  materializeAfterSemanticConsolidation,
199
- parseConsolidationResponse
200
- } from "./chunk-SYUK3VLY.js";
236
+ parseConsolidationResponse,
237
+ parseOperatorAwareConsolidationResponse
238
+ } from "./chunk-BGJGXLZ7.js";
201
239
  import {
202
240
  FallbackLlmClient
203
- } from "./chunk-44ICJRF3.js";
204
- import {
205
- GraphIndex
206
- } from "./chunk-C2EFFULQ.js";
207
- import {
208
- chunkContent
209
- } from "./chunk-4WMCPJWX.js";
241
+ } from "./chunk-3GXCSUXR.js";
210
242
  import {
211
243
  buildRecallQueryPolicy
212
244
  } from "./chunk-6HZ6AO2P.js";
@@ -217,15 +249,12 @@ import {
217
249
  import {
218
250
  BootstrapEngine
219
251
  } from "./chunk-N53K2EXC.js";
220
- import {
221
- BoxBuilder
222
- } from "./chunk-URB2WSKZ.js";
223
- import {
224
- SmartBuffer
225
- } from "./chunk-UVJFDP7P.js";
226
252
  import {
227
253
  isDisagreementPrompt
228
254
  } from "./chunk-XYIK4LF6.js";
255
+ import {
256
+ BoxBuilder
257
+ } from "./chunk-URB2WSKZ.js";
229
258
  import {
230
259
  abortError,
231
260
  isAbortError,
@@ -235,20 +264,21 @@ import {
235
264
  resolveHomeDir
236
265
  } from "./chunk-MARWOCVP.js";
237
266
  import {
267
+ listTrustZoneRecords,
238
268
  searchTrustZoneRecords
239
269
  } from "./chunk-EQINRHYR.js";
270
+ import {
271
+ buildProcedurePersistBody
272
+ } from "./chunk-QDW3E4RD.js";
240
273
  import {
241
274
  shouldSkipImplicitExtraction
242
- } from "./chunk-QDYXG4CS.js";
275
+ } from "./chunk-3FPTCC3Z.js";
243
276
  import {
244
277
  selectRouteRule
245
- } from "./chunk-QNJMBKFK.js";
246
- import {
247
- buildProcedurePersistBody
248
- } from "./chunk-QDW3E4RD.js";
278
+ } from "./chunk-2LGMW3DJ.js";
249
279
  import {
250
280
  searchCausalTrajectories
251
- } from "./chunk-4NRAJUDS.js";
281
+ } from "./chunk-RBBWYEFJ.js";
252
282
  import {
253
283
  canReadNamespace,
254
284
  defaultNamespaceForPrincipal,
@@ -267,10 +297,10 @@ import {
267
297
  normalizeAttributePairs,
268
298
  normalizeEntityName,
269
299
  parseEntityFile
270
- } from "./chunk-GV6NLQ4X.js";
300
+ } from "./chunk-F5VP6YCB.js";
271
301
  import {
272
302
  confidenceTier
273
- } from "./chunk-3WHVNEN7.js";
303
+ } from "./chunk-LTCGGW2D.js";
274
304
  import {
275
305
  attachCitation,
276
306
  hasCitationForTemplate,
@@ -291,17 +321,17 @@ import {
291
321
  } from "./chunk-2ODBA7MQ.js";
292
322
 
293
323
  // src/orchestrator.ts
294
- import path5 from "path";
324
+ import path7 from "path";
295
325
  import os from "os";
296
326
  import { createHash as createHash2, randomBytes } from "crypto";
297
327
  import { existsSync as existsSync2 } from "fs";
298
328
  import {
299
- mkdir as mkdir4,
329
+ mkdir as mkdir5,
300
330
  readdir as readdir3,
301
- readFile as readFile3,
331
+ readFile as readFile4,
302
332
  stat as stat3,
303
333
  unlink as unlink2,
304
- writeFile as writeFile3
334
+ writeFile as writeFile4
305
335
  } from "fs/promises";
306
336
 
307
337
  // src/migrate/from-engram.ts
@@ -878,7 +908,7 @@ async function buildProcedureRecallSection(storage, prompt, config) {
878
908
  10,
879
909
  Math.max(
880
910
  1,
881
- typeof config.procedural.recallMaxProcedures === "number" && Number.isFinite(config.procedural.recallMaxProcedures) ? Math.floor(config.procedural.recallMaxProcedures) : 3
911
+ typeof config.procedural.recallMaxProcedures === "number" && Number.isFinite(config.procedural.recallMaxProcedures) ? Math.floor(config.procedural.recallMaxProcedures) : 2
882
912
  )
883
913
  );
884
914
  const all = await storage.readAllMemories();
@@ -1119,12 +1149,253 @@ async function decideSemanticDedup(content, lookup, options) {
1119
1149
  };
1120
1150
  }
1121
1151
 
1122
- // src/lcm/schema.ts
1152
+ // src/taxonomy/default-taxonomy.ts
1153
+ var DEFAULT_TAXONOMY = {
1154
+ version: 1,
1155
+ categories: [
1156
+ {
1157
+ id: "corrections",
1158
+ name: "Corrections",
1159
+ description: "Corrections to previously stored information",
1160
+ filingRules: ["Any update that supersedes a prior fact"],
1161
+ priority: 10,
1162
+ memoryCategories: ["correction"]
1163
+ },
1164
+ {
1165
+ id: "principles",
1166
+ name: "Principles",
1167
+ description: "Rules, guidelines, and recurring patterns",
1168
+ filingRules: ["A guiding principle, rule, or skill"],
1169
+ priority: 20,
1170
+ memoryCategories: ["principle", "rule", "skill"]
1171
+ },
1172
+ {
1173
+ id: "procedures",
1174
+ name: "Procedures",
1175
+ description: "Ordered multi-step workflows the user repeats",
1176
+ filingRules: ["A repeatable sequence of steps or commands for a task"],
1177
+ priority: 25,
1178
+ memoryCategories: ["procedure"]
1179
+ },
1180
+ {
1181
+ id: "entities",
1182
+ name: "Entities",
1183
+ description: "People, organizations, places, projects",
1184
+ filingRules: ["Named entity with attributes"],
1185
+ priority: 30,
1186
+ memoryCategories: ["entity", "relationship"]
1187
+ },
1188
+ {
1189
+ id: "decisions",
1190
+ name: "Decisions",
1191
+ description: "Choices made and their rationale",
1192
+ filingRules: ["A decision or commitment with reasoning"],
1193
+ priority: 35,
1194
+ memoryCategories: ["decision", "commitment"]
1195
+ },
1196
+ {
1197
+ id: "preferences",
1198
+ name: "Preferences",
1199
+ description: "User likes, dislikes, and style choices",
1200
+ filingRules: ["Anything expressing a preference or taste"],
1201
+ priority: 40,
1202
+ memoryCategories: ["preference"]
1203
+ },
1204
+ {
1205
+ id: "facts",
1206
+ name: "Facts",
1207
+ description: "Objective statements about the world",
1208
+ filingRules: ["Any factual claim or piece of information"],
1209
+ priority: 50,
1210
+ memoryCategories: ["fact"]
1211
+ },
1212
+ {
1213
+ id: "moments",
1214
+ name: "Moments",
1215
+ description: "Significant events or experiences",
1216
+ filingRules: ["A specific event worth remembering"],
1217
+ priority: 60,
1218
+ memoryCategories: ["moment"]
1219
+ },
1220
+ {
1221
+ id: "reasoning-traces",
1222
+ name: "Reasoning Traces",
1223
+ description: "Stored intermediate reasoning / solution chains for a problem the agent previously solved",
1224
+ filingRules: [
1225
+ "A multi-step reasoning chain or solution walkthrough the agent can replay for a similar problem"
1226
+ ],
1227
+ priority: 55,
1228
+ memoryCategories: ["reasoning_trace"]
1229
+ }
1230
+ ]
1231
+ };
1232
+
1233
+ // src/taxonomy/resolver-doc-generator.ts
1234
+ function generateResolverDocument(taxonomy) {
1235
+ const sorted = [...taxonomy.categories].sort((a, b) => {
1236
+ if (a.priority !== b.priority) return a.priority - b.priority;
1237
+ return a.id.localeCompare(b.id);
1238
+ });
1239
+ const lines = [
1240
+ "# Memory Filing Resolver",
1241
+ "",
1242
+ "Given a new piece of knowledge, follow this tree to determine where it belongs.",
1243
+ ""
1244
+ ];
1245
+ let step = 1;
1246
+ for (const cat of sorted) {
1247
+ lines.push(`## Step ${step}: ${cat.description}?`);
1248
+ lines.push("");
1249
+ for (const rule of cat.filingRules) {
1250
+ lines.push(`- ${rule}`);
1251
+ }
1252
+ lines.push("");
1253
+ lines.push(
1254
+ `> YES: File under **${cat.id}/** (priority ${cat.priority})`
1255
+ );
1256
+ lines.push("");
1257
+ step++;
1258
+ }
1259
+ lines.push("## Tie-breaking");
1260
+ lines.push("");
1261
+ lines.push(
1262
+ "If a fact could go in multiple categories, file under the one with the **lowest priority number**."
1263
+ );
1264
+ lines.push("");
1265
+ lines.push(`---`);
1266
+ lines.push(`*Generated from taxonomy v${taxonomy.version}*`);
1267
+ lines.push("");
1268
+ return lines.join("\n");
1269
+ }
1270
+
1271
+ // src/taxonomy/taxonomy-loader.ts
1272
+ import { readFile as readFile3, mkdir as mkdir3, writeFile as writeFile3 } from "fs/promises";
1123
1273
  import path3 from "path";
1124
- import { mkdir as mkdir3 } from "fs/promises";
1274
+ var TAXONOMY_DIR = ".taxonomy";
1275
+ var TAXONOMY_FILE = "taxonomy.json";
1276
+ var MAX_SLUG_LENGTH = 32;
1277
+ var SLUG_RE = /^[a-z][a-z0-9-]*$/;
1278
+ function validateSlug(slug) {
1279
+ if (slug.length === 0) {
1280
+ throw new Error("Taxonomy category ID must not be empty");
1281
+ }
1282
+ if (slug.length > MAX_SLUG_LENGTH) {
1283
+ throw new Error(
1284
+ `Taxonomy category ID "${slug}" exceeds ${MAX_SLUG_LENGTH} characters`
1285
+ );
1286
+ }
1287
+ if (!SLUG_RE.test(slug)) {
1288
+ throw new Error(
1289
+ `Taxonomy category ID "${slug}" is invalid: must be lowercase letters, digits, and hyphens, starting with a letter`
1290
+ );
1291
+ }
1292
+ }
1293
+ function validateTaxonomy(taxonomy) {
1294
+ if (typeof taxonomy.version !== "number" || taxonomy.version < 1) {
1295
+ throw new Error("Taxonomy version must be a positive integer");
1296
+ }
1297
+ if (!Array.isArray(taxonomy.categories)) {
1298
+ throw new Error("Taxonomy categories must be an array");
1299
+ }
1300
+ const seenIds = /* @__PURE__ */ new Set();
1301
+ for (const cat of taxonomy.categories) {
1302
+ validateSlug(cat.id);
1303
+ if (seenIds.has(cat.id)) {
1304
+ throw new Error(`Duplicate taxonomy category ID: "${cat.id}"`);
1305
+ }
1306
+ seenIds.add(cat.id);
1307
+ if (typeof cat.name !== "string" || cat.name.trim().length === 0) {
1308
+ throw new Error(`Taxonomy category "${cat.id}" must have a non-empty name`);
1309
+ }
1310
+ if (typeof cat.description !== "string" || cat.description.trim().length === 0) {
1311
+ throw new Error(`Taxonomy category "${cat.id}" must have a non-empty description`);
1312
+ }
1313
+ if (!Array.isArray(cat.filingRules)) {
1314
+ throw new Error(`Taxonomy category "${cat.id}" filingRules must be an array`);
1315
+ }
1316
+ if (typeof cat.priority !== "number" || !Number.isFinite(cat.priority)) {
1317
+ throw new Error(`Taxonomy category "${cat.id}" must have a finite numeric priority`);
1318
+ }
1319
+ if (!Array.isArray(cat.memoryCategories)) {
1320
+ throw new Error(`Taxonomy category "${cat.id}" memoryCategories must be an array`);
1321
+ }
1322
+ if (cat.parentId !== void 0) {
1323
+ if (typeof cat.parentId !== "string") {
1324
+ throw new Error(`Taxonomy category "${cat.id}" parentId must be a string if set`);
1325
+ }
1326
+ }
1327
+ }
1328
+ for (const cat of taxonomy.categories) {
1329
+ if (cat.parentId !== void 0 && !seenIds.has(cat.parentId)) {
1330
+ throw new Error(
1331
+ `Taxonomy category "${cat.id}" references unknown parentId "${cat.parentId}"`
1332
+ );
1333
+ }
1334
+ }
1335
+ }
1336
+ async function loadTaxonomy(memoryDir) {
1337
+ const taxonomyPath = path3.join(memoryDir, TAXONOMY_DIR, TAXONOMY_FILE);
1338
+ let raw;
1339
+ try {
1340
+ raw = await readFile3(taxonomyPath, "utf-8");
1341
+ } catch (err) {
1342
+ if (err instanceof Error && err.code === "ENOENT") {
1343
+ return structuredClone(DEFAULT_TAXONOMY);
1344
+ }
1345
+ throw err;
1346
+ }
1347
+ const parsed = JSON.parse(raw);
1348
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
1349
+ throw new Error("taxonomy.json must be a JSON object");
1350
+ }
1351
+ const obj = parsed;
1352
+ const userVersion = typeof obj.version === "number" ? obj.version : DEFAULT_TAXONOMY.version;
1353
+ const userCategories = Array.isArray(obj.categories) ? obj.categories : [];
1354
+ const userIdCounts = /* @__PURE__ */ new Map();
1355
+ for (const cat of userCategories) {
1356
+ const id = typeof cat.id === "string" ? cat.id : String(cat.id);
1357
+ userIdCounts.set(id, (userIdCounts.get(id) ?? 0) + 1);
1358
+ }
1359
+ const duplicateIds = [...userIdCounts.entries()].filter(([, count]) => count > 1).map(([id]) => id);
1360
+ if (duplicateIds.length > 0) {
1361
+ throw new Error(
1362
+ `Duplicate category IDs in taxonomy.json: ${duplicateIds.map((id) => `"${id}"`).join(", ")}`
1363
+ );
1364
+ }
1365
+ const mergedMap = /* @__PURE__ */ new Map();
1366
+ for (const cat of DEFAULT_TAXONOMY.categories) {
1367
+ mergedMap.set(cat.id, { ...cat });
1368
+ }
1369
+ for (const cat of userCategories) {
1370
+ mergedMap.set(cat.id, cat);
1371
+ }
1372
+ const merged = {
1373
+ version: userVersion,
1374
+ categories: [...mergedMap.values()]
1375
+ };
1376
+ validateTaxonomy(merged);
1377
+ return merged;
1378
+ }
1379
+ async function saveTaxonomy(memoryDir, taxonomy) {
1380
+ validateTaxonomy(taxonomy);
1381
+ const dir = path3.join(memoryDir, TAXONOMY_DIR);
1382
+ await mkdir3(dir, { recursive: true });
1383
+ const filePath = path3.join(dir, TAXONOMY_FILE);
1384
+ await writeFile3(filePath, JSON.stringify(taxonomy, null, 2) + "\n", "utf-8");
1385
+ }
1386
+ function getTaxonomyDir(memoryDir) {
1387
+ return path3.join(memoryDir, TAXONOMY_DIR);
1388
+ }
1389
+ function getTaxonomyFilePath(memoryDir) {
1390
+ return path3.join(memoryDir, TAXONOMY_DIR, TAXONOMY_FILE);
1391
+ }
1392
+
1393
+ // src/lcm/schema.ts
1394
+ import path4 from "path";
1395
+ import { mkdir as mkdir4 } from "fs/promises";
1125
1396
  var LCM_SCHEMA_VERSION = 1;
1126
1397
  function openLcmDatabase(memoryDir) {
1127
- const dbPath = path3.join(memoryDir, "state", "lcm.sqlite");
1398
+ const dbPath = path4.join(memoryDir, "state", "lcm.sqlite");
1128
1399
  const db = openBetterSqlite3(dbPath);
1129
1400
  db.pragma("journal_mode = WAL");
1130
1401
  db.pragma("busy_timeout = 5000");
@@ -1133,7 +1404,7 @@ function openLcmDatabase(memoryDir) {
1133
1404
  return db;
1134
1405
  }
1135
1406
  async function ensureLcmStateDir(memoryDir) {
1136
- await mkdir3(path3.join(memoryDir, "state"), { recursive: true });
1407
+ await mkdir4(path4.join(memoryDir, "state"), { recursive: true });
1137
1408
  }
1138
1409
  function applySchema(db) {
1139
1410
  const versionRow = db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='lcm_meta'").get();
@@ -2397,7 +2668,7 @@ function chunkTranscriptEntries(sessionKey, entries, opts) {
2397
2668
 
2398
2669
  // src/conversation-index/cleanup.ts
2399
2670
  import { readdir as readdir2, rm as rm3 } from "fs/promises";
2400
- import path4 from "path";
2671
+ import path5 from "path";
2401
2672
  async function cleanupConversationChunks(rootDir, retentionDays) {
2402
2673
  if (!Number.isFinite(retentionDays) || retentionDays <= 0) return;
2403
2674
  const cutoffMs = Date.now() - retentionDays * 24 * 60 * 60 * 1e3;
@@ -2405,7 +2676,7 @@ async function cleanupConversationChunks(rootDir, retentionDays) {
2405
2676
  const sessions = await readdir2(rootDir, { withFileTypes: true });
2406
2677
  for (const s of sessions) {
2407
2678
  if (!s.isDirectory()) continue;
2408
- const sessionDir = path4.join(rootDir, s.name);
2679
+ const sessionDir = path5.join(rootDir, s.name);
2409
2680
  const dayDirs = await readdir2(sessionDir, { withFileTypes: true });
2410
2681
  for (const d of dayDirs) {
2411
2682
  if (!d.isDirectory()) continue;
@@ -2413,7 +2684,7 @@ async function cleanupConversationChunks(rootDir, retentionDays) {
2413
2684
  const dayMs = (/* @__PURE__ */ new Date(d.name + "T00:00:00.000Z")).getTime();
2414
2685
  if (!Number.isFinite(dayMs)) continue;
2415
2686
  if (dayMs < cutoffMs) {
2416
- await rm3(path4.join(sessionDir, d.name), { recursive: true, force: true });
2687
+ await rm3(path5.join(sessionDir, d.name), { recursive: true, force: true });
2417
2688
  }
2418
2689
  }
2419
2690
  try {
@@ -2429,6 +2700,264 @@ async function cleanupConversationChunks(rootDir, retentionDays) {
2429
2700
  }
2430
2701
  }
2431
2702
 
2703
+ // src/coding/git-context.ts
2704
+ import path6 from "path";
2705
+ var DEFAULT_GIT_TIMEOUT_MS = 2e3;
2706
+ function defaultGitInvoker() {
2707
+ return (cwd, args) => {
2708
+ const result = launchProcessSync("git", args, {
2709
+ cwd,
2710
+ encoding: "utf-8",
2711
+ timeout: DEFAULT_GIT_TIMEOUT_MS,
2712
+ shell: false
2713
+ });
2714
+ if (result.error) {
2715
+ return { stdout: "", exitCode: 127 };
2716
+ }
2717
+ return {
2718
+ stdout: typeof result.stdout === "string" ? result.stdout : "",
2719
+ exitCode: typeof result.status === "number" ? result.status : 1
2720
+ };
2721
+ };
2722
+ }
2723
+ function stableHash(input) {
2724
+ let hash = 2166136261;
2725
+ for (let i = 0; i < input.length; i++) {
2726
+ hash ^= input.charCodeAt(i);
2727
+ hash = Math.imul(hash, 16777619) >>> 0;
2728
+ }
2729
+ return hash.toString(16).padStart(8, "0");
2730
+ }
2731
+ function normalizeOriginUrl(rawUrl) {
2732
+ let url = rawUrl.trim();
2733
+ if (!url) return "";
2734
+ if (/\.git$/i.test(url)) url = url.slice(0, -4);
2735
+ if (/^[A-Za-z]:[\\/]/.test(url)) {
2736
+ return url.toLowerCase();
2737
+ }
2738
+ const protoMatch = /^[a-z][a-z0-9+.-]*:\/\/(?:[^@/]+@)?(\[[^\]]+\]|[^/:]*)(?::(\d+))?(\/.*)?$/i.exec(url);
2739
+ if (protoMatch) {
2740
+ let host = protoMatch[1] ?? "";
2741
+ const wasBracketed = host.startsWith("[") && host.endsWith("]");
2742
+ if (wasBracketed) host = host.slice(1, -1);
2743
+ const port = protoMatch[2];
2744
+ const repoPath = (protoMatch[3] ?? "").replace(/^\/+/, "");
2745
+ const hostPort = port ? wasBracketed ? `[${host}]:${port}` : `${host}:${port}` : host;
2746
+ const prefix = hostPort.length > 0 ? hostPort : "localhost";
2747
+ return `${prefix}/${repoPath}`.toLowerCase();
2748
+ }
2749
+ const scpMatch = /^(?:([^@\s/]+)@)?(\[[^\]]+\]|[^:@\s/]+):(.+)$/.exec(url);
2750
+ if (scpMatch) {
2751
+ let host = scpMatch[2] ?? "";
2752
+ if (host.startsWith("[") && host.endsWith("]")) host = host.slice(1, -1);
2753
+ const repoPath = scpMatch[3] ?? "";
2754
+ if (repoPath.startsWith("//")) {
2755
+ return url.toLowerCase();
2756
+ }
2757
+ return `${host}/${repoPath.replace(/^\/+/, "")}`.toLowerCase();
2758
+ }
2759
+ return url.toLowerCase();
2760
+ }
2761
+ async function resolveGitContext(cwd, options = {}) {
2762
+ try {
2763
+ if (typeof cwd !== "string" || cwd.length === 0) return null;
2764
+ const expanded = expandTildePath(cwd);
2765
+ if (!path6.isAbsolute(expanded)) return null;
2766
+ const invoker = options.invoker ?? defaultGitInvoker();
2767
+ const topLevel = invoker(expanded, ["rev-parse", "--show-toplevel"]);
2768
+ if (topLevel.exitCode !== 0) return null;
2769
+ const rootPath = topLevel.stdout.trim();
2770
+ if (!rootPath) return null;
2771
+ const branchResult = invoker(rootPath, ["rev-parse", "--abbrev-ref", "HEAD"]);
2772
+ let branch = null;
2773
+ if (branchResult.exitCode === 0) {
2774
+ const raw = branchResult.stdout.trim();
2775
+ branch = raw && raw !== "HEAD" ? raw : null;
2776
+ } else {
2777
+ const unbornRef = invoker(rootPath, ["symbolic-ref", "--quiet", "HEAD"]);
2778
+ if (unbornRef.exitCode === 0) {
2779
+ const raw = unbornRef.stdout.trim();
2780
+ const prefix = "refs/heads/";
2781
+ if (raw.startsWith(prefix)) {
2782
+ const candidate = raw.slice(prefix.length);
2783
+ if (candidate) branch = candidate;
2784
+ }
2785
+ }
2786
+ }
2787
+ const originResult = invoker(rootPath, ["remote", "get-url", "origin"]);
2788
+ let projectId;
2789
+ if (originResult.exitCode === 0) {
2790
+ const normalized = normalizeOriginUrl(originResult.stdout);
2791
+ projectId = normalized ? `origin:${stableHash(normalized)}` : `root:${stableHash(rootPath)}`;
2792
+ } else {
2793
+ projectId = `root:${stableHash(rootPath)}`;
2794
+ }
2795
+ const headRef = invoker(rootPath, ["symbolic-ref", "--quiet", "refs/remotes/origin/HEAD"]);
2796
+ let defaultBranch = null;
2797
+ if (headRef.exitCode === 0) {
2798
+ const raw = headRef.stdout.trim();
2799
+ const prefix = "refs/remotes/origin/";
2800
+ if (raw.startsWith(prefix)) {
2801
+ const candidate = raw.slice(prefix.length);
2802
+ if (candidate) defaultBranch = candidate;
2803
+ }
2804
+ }
2805
+ return {
2806
+ projectId,
2807
+ branch,
2808
+ rootPath,
2809
+ defaultBranch
2810
+ };
2811
+ } catch {
2812
+ return null;
2813
+ }
2814
+ }
2815
+
2816
+ // src/coding/coding-namespace.ts
2817
+ function sanitizeFragment(input) {
2818
+ if (typeof input !== "string") return "";
2819
+ const trimmed = input.trim().toLowerCase();
2820
+ let out = "";
2821
+ let prevIsDash = true;
2822
+ for (let i = 0; i < trimmed.length; i += 1) {
2823
+ const c = trimmed[i];
2824
+ const cc = trimmed.charCodeAt(i);
2825
+ const isSafe = cc >= 48 && cc <= 57 || cc >= 97 && cc <= 122 || cc === 46 || cc === 95;
2826
+ if (isSafe) {
2827
+ out += c;
2828
+ prevIsDash = false;
2829
+ } else if (!prevIsDash) {
2830
+ out += "-";
2831
+ prevIsDash = true;
2832
+ }
2833
+ }
2834
+ if (out.endsWith("-")) out = out.slice(0, -1);
2835
+ return out;
2836
+ }
2837
+ var MAX_NAMESPACE_LEN = 64;
2838
+ var HASH_SUFFIX_LEN = 9;
2839
+ function capLength(value) {
2840
+ if (value.length <= MAX_NAMESPACE_LEN) return value;
2841
+ const hash = stableHash(value);
2842
+ let end = MAX_NAMESPACE_LEN - HASH_SUFFIX_LEN;
2843
+ while (end > 0 && value.charCodeAt(end - 1) === 45) end -= 1;
2844
+ return `${value.slice(0, end)}-${hash}`;
2845
+ }
2846
+ function projectNamespaceName(projectId) {
2847
+ const frag = sanitizeFragment(projectId);
2848
+ return capLength(`project-${frag || "unknown"}`);
2849
+ }
2850
+ function sanitizeBaseFragment(input) {
2851
+ if (typeof input !== "string") return "";
2852
+ const trimmed = input.trim();
2853
+ let out = "";
2854
+ let prevIsDash = true;
2855
+ for (let i = 0; i < trimmed.length; i += 1) {
2856
+ const c = trimmed[i];
2857
+ const cc = trimmed.charCodeAt(i);
2858
+ const isSafe = cc >= 48 && cc <= 57 || cc >= 65 && cc <= 90 || cc >= 97 && cc <= 122 || cc === 46 || cc === 95;
2859
+ if (isSafe) {
2860
+ out += c;
2861
+ prevIsDash = false;
2862
+ } else if (!prevIsDash) {
2863
+ out += "-";
2864
+ prevIsDash = true;
2865
+ }
2866
+ }
2867
+ if (out.endsWith("-")) out = out.slice(0, -1);
2868
+ return out;
2869
+ }
2870
+ function combineNamespaces(base, overlay) {
2871
+ const baseFrag = sanitizeBaseFragment(base);
2872
+ const overlayFrag = sanitizeFragment(overlay);
2873
+ if (!baseFrag) return capLength(overlayFrag || "unknown");
2874
+ if (!overlayFrag) return capLength(baseFrag);
2875
+ return capLength(`${baseFrag}-${overlayFrag}`);
2876
+ }
2877
+ function branchNamespaceName(projectId, branch) {
2878
+ const projectFrag = sanitizeFragment(projectId);
2879
+ const trimmedBranch = branch.trim();
2880
+ const branchFrag = sanitizeFragment(trimmedBranch);
2881
+ const disambig = trimmedBranch.length > 0 && branchFrag !== trimmedBranch;
2882
+ const base = `project-${projectFrag || "unknown"}-branch-${branchFrag || "unknown"}`;
2883
+ const suffixed = disambig ? `${base}-${stableHash(trimmedBranch)}` : base;
2884
+ return capLength(suffixed);
2885
+ }
2886
+ function resolveCodingNamespaceOverlay(codingContext, config) {
2887
+ if (!codingContext) return null;
2888
+ if (!config.projectScope) return null;
2889
+ const projectId = typeof codingContext.projectId === "string" ? codingContext.projectId.trim() : "";
2890
+ if (!projectId) return null;
2891
+ const projectNs = projectNamespaceName(projectId);
2892
+ if (config.branchScope && typeof codingContext.branch === "string" && codingContext.branch.length > 0) {
2893
+ const branchNs = branchNamespaceName(projectId, codingContext.branch);
2894
+ return {
2895
+ namespace: branchNs,
2896
+ readFallbacks: [projectNs],
2897
+ scope: "branch"
2898
+ };
2899
+ }
2900
+ return {
2901
+ namespace: projectNs,
2902
+ readFallbacks: [],
2903
+ scope: "project"
2904
+ };
2905
+ }
2906
+ function describeCodingScope(codingContext, config) {
2907
+ const projectId = codingContext?.projectId ?? null;
2908
+ const branch = codingContext?.branch ?? null;
2909
+ if (!codingContext) {
2910
+ return {
2911
+ scope: "none",
2912
+ projectId: null,
2913
+ branch: null,
2914
+ effectiveNamespace: null,
2915
+ readFallbacks: [],
2916
+ disabledReason: "no-context"
2917
+ };
2918
+ }
2919
+ if (!config.projectScope) {
2920
+ return {
2921
+ scope: "none",
2922
+ projectId,
2923
+ branch,
2924
+ effectiveNamespace: null,
2925
+ readFallbacks: [],
2926
+ disabledReason: "disabled"
2927
+ };
2928
+ }
2929
+ const trimmedId = typeof projectId === "string" ? projectId.trim() : "";
2930
+ if (!trimmedId) {
2931
+ return {
2932
+ scope: "none",
2933
+ projectId,
2934
+ branch,
2935
+ effectiveNamespace: null,
2936
+ readFallbacks: [],
2937
+ disabledReason: "empty-project"
2938
+ };
2939
+ }
2940
+ const overlay = resolveCodingNamespaceOverlay(codingContext, config);
2941
+ if (!overlay) {
2942
+ return {
2943
+ scope: "none",
2944
+ projectId,
2945
+ branch,
2946
+ effectiveNamespace: null,
2947
+ readFallbacks: [],
2948
+ disabledReason: "disabled"
2949
+ };
2950
+ }
2951
+ return {
2952
+ scope: overlay.scope,
2953
+ projectId,
2954
+ branch,
2955
+ effectiveNamespace: overlay.namespace,
2956
+ readFallbacks: overlay.readFallbacks,
2957
+ disabledReason: null
2958
+ };
2959
+ }
2960
+
2432
2961
  // src/orchestrator.ts
2433
2962
  function dedupeEntitySynthesisEvidenceEntries(entries) {
2434
2963
  const dedupedEvidenceEntries = [];
@@ -2493,6 +3022,20 @@ function fingerprintEntitySynthesisEvidence(entity) {
2493
3022
  fingerprint.update(fingerprintEntityStructuredFacts(entity) ?? "");
2494
3023
  return fingerprint.digest("hex");
2495
3024
  }
3025
+ function mapRecallSourceToXrayServedBy(source) {
3026
+ switch (source) {
3027
+ case "recent_scan":
3028
+ return "recent-scan";
3029
+ case "hot_qmd":
3030
+ case "hot_embedding":
3031
+ case "cold_fallback":
3032
+ case "none":
3033
+ return "hybrid";
3034
+ }
3035
+ const _exhaustive = source;
3036
+ void _exhaustive;
3037
+ return "hybrid";
3038
+ }
2496
3039
  var abortRecallError = abortError;
2497
3040
  function throwIfRecallAborted(signal, message = "recall aborted") {
2498
3041
  throwIfAborted(signal, message);
@@ -2515,7 +3058,7 @@ async function raceRecallAbort(promise, signal, message = "recall aborted") {
2515
3058
  }
2516
3059
  var COMPACTION_SIGNAL_MAX_AGE_MS = 60 * 60 * 1e3;
2517
3060
  function defaultWorkspaceDir() {
2518
- return path5.join(os.homedir(), ".openclaw", "workspace");
3061
+ return path7.join(os.homedir(), ".openclaw", "workspace");
2519
3062
  }
2520
3063
  function sanitizeSessionKeyForFilename(sessionKey) {
2521
3064
  const readable = sessionKey.replace(/[^a-zA-Z0-9._-]/g, "_");
@@ -2683,11 +3226,11 @@ function mergeGraphExpandedResults(primary, expanded) {
2683
3226
  return Array.from(mergedByPath.values());
2684
3227
  }
2685
3228
  function graphPathRelativeToStorage(storageDir, candidatePath) {
2686
- const absolutePath = path5.isAbsolute(candidatePath) ? candidatePath : path5.resolve(storageDir, candidatePath);
2687
- const rel = path5.relative(storageDir, absolutePath);
3229
+ const absolutePath = path7.isAbsolute(candidatePath) ? candidatePath : path7.resolve(storageDir, candidatePath);
3230
+ const rel = path7.relative(storageDir, absolutePath);
2688
3231
  if (!rel || rel === ".") return null;
2689
3232
  if (rel.startsWith("..")) return null;
2690
- return rel.split(path5.sep).join("/");
3233
+ return rel.split(path7.sep).join("/");
2691
3234
  }
2692
3235
  function normalizeGraphActivationScore(score) {
2693
3236
  const bounded = Number.isFinite(score) && score > 0 ? score : 0;
@@ -2829,7 +3372,7 @@ function buildMemoryPathById(allMemsForGraph, storageDir) {
2829
3372
  for (const mem of allMemsForGraph ?? []) {
2830
3373
  const id = mem.frontmatter.id;
2831
3374
  if (!id) continue;
2832
- pathById.set(id, path5.relative(storageDir, mem.path));
3375
+ pathById.set(id, path7.relative(storageDir, mem.path));
2833
3376
  }
2834
3377
  return pathById;
2835
3378
  }
@@ -2837,7 +3380,7 @@ function appendMemoryToGraphContext(options) {
2837
3380
  if (!Array.isArray(options.allMemsForGraph)) return;
2838
3381
  const nowIso = (/* @__PURE__ */ new Date()).toISOString();
2839
3382
  options.allMemsForGraph.push({
2840
- path: path5.join(options.storageDir, options.memoryRelPath),
3383
+ path: path7.join(options.storageDir, options.memoryRelPath),
2841
3384
  content: options.content,
2842
3385
  frontmatter: {
2843
3386
  id: options.memoryId,
@@ -2857,15 +3400,16 @@ function resolvePersistedMemoryRelativePath(options) {
2857
3400
  const persisted = options.pathById.get(options.memoryId);
2858
3401
  if (persisted) return persisted;
2859
3402
  if (options.category === "correction") {
2860
- return path5.join("corrections", `${options.memoryId}.md`);
3403
+ return path7.join("corrections", `${options.memoryId}.md`);
2861
3404
  }
3405
+ const subtree = options.category === "procedure" ? "procedures" : options.category === "reasoning_trace" ? "reasoning-traces" : "facts";
2862
3406
  const idParts = options.memoryId.split("-");
2863
3407
  const maybeTimestamp = Number(idParts[1]);
2864
3408
  if (Number.isFinite(maybeTimestamp) && maybeTimestamp > 0) {
2865
3409
  const day = new Date(maybeTimestamp).toISOString().slice(0, 10);
2866
- return path5.join("facts", day, `${options.memoryId}.md`);
3410
+ return path7.join(subtree, day, `${options.memoryId}.md`);
2867
3411
  }
2868
- return path5.join("facts", `${options.memoryId}.md`);
3412
+ return path7.join(subtree, `${options.memoryId}.md`);
2869
3413
  }
2870
3414
  var Orchestrator = class _Orchestrator {
2871
3415
  storage;
@@ -2884,12 +3428,39 @@ var Orchestrator = class _Orchestrator {
2884
3428
  localLlm;
2885
3429
  fastLlm;
2886
3430
  judgeVerdictCache;
2887
- fastGatewayLlm;
3431
+ /**
3432
+ * Per-orchestrator defer-counter map (issue #562, PR 2). Tracks how many
3433
+ * times the judge has returned `"defer"` for a given candidate content
3434
+ * hash so the defer cap can be enforced.
3435
+ */
3436
+ judgeDeferCounts;
3437
+ /**
3438
+ * Side-channel: number of facts deferred in the most recent
3439
+ * `persistExtraction` call (issue #562, PR 2). The caller reads this after
3440
+ * `persistExtraction` returns to decide whether to retain buffer turns for
3441
+ * the next extraction pass. Not part of the return signature because many
3442
+ * callers already destructure `persistedIds` by position.
3443
+ */
3444
+ lastPersistExtractionDeferredCount = 0;
3445
+ _fastGatewayLlm;
3446
+ get fastGatewayLlm() {
3447
+ return this._fastGatewayLlm;
3448
+ }
2888
3449
  modelRegistry;
2889
3450
  relevance;
2890
3451
  negatives;
2891
3452
  lastRecall;
2892
3453
  tierMigrationStatus;
3454
+ /**
3455
+ * In-memory X-ray snapshot from the most recent `recall()` call that
3456
+ * was invoked with `xrayCapture: true` (issue #570 PR 1). Scope is
3457
+ * per-process; later slices add CLI/HTTP/MCP surfaces that consume
3458
+ * this via the shared renderer. `null` until the first capture, and
3459
+ * NEVER overwritten by a recall that did not request capture —
3460
+ * requests without the flag leave prior captures intact so the
3461
+ * capturing caller can still read their snapshot back.
3462
+ */
3463
+ lastXraySnapshot = null;
2893
3464
  embeddingFallback;
2894
3465
  conversationIndexDir;
2895
3466
  extraction;
@@ -2905,6 +3476,16 @@ var Orchestrator = class _Orchestrator {
2905
3476
  /** Lossless Context Management engine — proactive session archive + DAG summarization. */
2906
3477
  lcmEngine = null;
2907
3478
  rerankCache = new RerankCache();
3479
+ /**
3480
+ * Short-TTL cache for Memory Worth counter lookups so interactive recall
3481
+ * doesn't trigger a full `readAllMemories` scan per query. Keyed by
3482
+ * namespace; the filter unions across namespaces at query time. The TTL
3483
+ * is intentionally short (seconds, not minutes) because counters are
3484
+ * mutated by `recordMemoryOutcome` asynchronously and we'd rather serve
3485
+ * a 30-second-stale worth score than a stable-but-wrong one.
3486
+ */
3487
+ memoryWorthCounterCache = /* @__PURE__ */ new Map();
3488
+ static MEMORY_WORTH_CACHE_TTL_MS = 3e4;
2908
3489
  /**
2909
3490
  * Per-session workspace overrides keyed by sessionKey.
2910
3491
  * Set by the before_agent_start hook so recall() uses the correct
@@ -2912,6 +3493,14 @@ var Orchestrator = class _Orchestrator {
2912
3493
  * Using a Map prevents concurrent sessions from overwriting each other.
2913
3494
  */
2914
3495
  _recallWorkspaceOverrides = /* @__PURE__ */ new Map();
3496
+ /**
3497
+ * Per-session coding-agent context (issue #569). Populated by connectors at
3498
+ * session-start (PRs 5/6/7) via `setCodingContextForSession`. Used by both
3499
+ * the recall path and the write path so that memory routing respects the
3500
+ * project/branch scope a session is operating in (rule 42 — read + write
3501
+ * through the same namespace layer).
3502
+ */
3503
+ _codingContextBySession = /* @__PURE__ */ new Map();
2915
3504
  routingRulesStore = null;
2916
3505
  contentHashIndex = null;
2917
3506
  artifactSourceStatusCache = /* @__PURE__ */ new WeakMap();
@@ -2945,6 +3534,10 @@ var Orchestrator = class _Orchestrator {
2945
3534
  runtimePolicyValues = null;
2946
3535
  utilityRuntimeValues = null;
2947
3536
  evalShadowWriteChain = Promise.resolve();
3537
+ // Pending background observation-mode direct-answer annotations (#518).
3538
+ // Tracks fire-and-forget `annotateDirectAnswerTier` calls so callers (tests,
3539
+ // waitForDirectAnswerObservationIdle) can await settlement.
3540
+ directAnswerObservationChain = Promise.resolve();
2948
3541
  // Initialization gate: recall() awaits this before proceeding
2949
3542
  initPromise = null;
2950
3543
  resolveInit = null;
@@ -2983,6 +3576,9 @@ var Orchestrator = class _Orchestrator {
2983
3576
  this.deferredInitAbort = null;
2984
3577
  }
2985
3578
  }
3579
+ async disposeSearchBackendIfNeeded() {
3580
+ await this.qmd.dispose?.();
3581
+ }
2986
3582
  /** Set per-session workspace for the next recall() call (compaction reset). @internal */
2987
3583
  setRecallWorkspaceOverride(sessionKey, dir) {
2988
3584
  this._recallWorkspaceOverrides.set(sessionKey, dir);
@@ -2995,10 +3591,96 @@ var Orchestrator = class _Orchestrator {
2995
3591
  return resolvePrincipal(sessionKey, this.config);
2996
3592
  }
2997
3593
  resolveSelfNamespace(sessionKey) {
2998
- return defaultNamespaceForPrincipal(
3594
+ const base = defaultNamespaceForPrincipal(
2999
3595
  this.resolvePrincipal(sessionKey),
3000
3596
  this.config
3001
3597
  );
3598
+ return this.applyCodingNamespaceOverlay(sessionKey, base);
3599
+ }
3600
+ /**
3601
+ * Attach a coding-agent context to a session (issue #569). Called by the
3602
+ * Claude Code / Codex / Cursor connectors at session start after
3603
+ * `resolveGitContext(cwd)`. The context is consulted by the recall path
3604
+ * and the write path so that memories route to a project- (and optionally
3605
+ * branch-) scoped namespace.
3606
+ *
3607
+ * Pass `null` to clear.
3608
+ */
3609
+ setCodingContextForSession(sessionKey, codingContext) {
3610
+ if (typeof sessionKey !== "string" || sessionKey.length === 0) return;
3611
+ if (!this._codingContextBySession) {
3612
+ this._codingContextBySession = /* @__PURE__ */ new Map();
3613
+ }
3614
+ if (codingContext === null) {
3615
+ this._codingContextBySession.delete(sessionKey);
3616
+ return;
3617
+ }
3618
+ this._codingContextBySession.set(sessionKey, codingContext);
3619
+ }
3620
+ /**
3621
+ * Read-only accessor for the coding context attached to a session. Returns
3622
+ * `null` when none is set. Used by `remnic doctor` and by tests.
3623
+ *
3624
+ * Defensive `_codingContextBySession` lookup — legacy orchestrator-flush
3625
+ * tests use `Object.create(Orchestrator.prototype)` which does not run
3626
+ * class-field initializers, so the Map may be undefined on stubs.
3627
+ */
3628
+ getCodingContextForSession(sessionKey) {
3629
+ if (typeof sessionKey !== "string" || sessionKey.length === 0) return null;
3630
+ return this._codingContextBySession?.get(sessionKey) ?? null;
3631
+ }
3632
+ /**
3633
+ * Shared helper used by both the recall path and the write path (rule 42).
3634
+ *
3635
+ * Given a base namespace computed from the principal, returns the overlaid
3636
+ * coding namespace when the session has a coding context AND
3637
+ * `codingMode.projectScope` is true AND `namespacesEnabled` is true.
3638
+ * Otherwise returns `baseNamespace` unchanged — CLAUDE.md #30 escape hatch.
3639
+ *
3640
+ * Principal isolation (CLAUDE.md rule 42): the overlay is COMBINED with
3641
+ * the principal-derived `baseNamespace` rather than replacing it, so two
3642
+ * principals working in the same repository do not share memories through
3643
+ * a common `project-*` namespace.
3644
+ *
3645
+ * Namespaces-disabled gate: when `namespacesEnabled` is false, the
3646
+ * storage router maps every namespace to the same `memoryDir`. Returning
3647
+ * `project-*` in that mode would create apparent route separation with
3648
+ * no actual storage isolation — a false-isolation trap. In that mode we
3649
+ * return `baseNamespace` unchanged so coding mode degrades to the existing
3650
+ * unscoped behavior.
3651
+ *
3652
+ * @internal
3653
+ */
3654
+ applyCodingNamespaceOverlay(sessionKey, baseNamespace) {
3655
+ if (!this.config.namespacesEnabled) return baseNamespace;
3656
+ const codingContext = this.getCodingContextForSession(sessionKey);
3657
+ const overlay = resolveCodingNamespaceOverlay(codingContext, this.config.codingMode);
3658
+ if (!overlay) return baseNamespace;
3659
+ return combineNamespaces(baseNamespace, overlay.namespace);
3660
+ }
3661
+ /**
3662
+ * Read-side overlay: returns the list of namespaces a session should read
3663
+ * from, including any read fallbacks (branch → project asymmetry lands in
3664
+ * PR 3; PR 2 returns an empty fallbacks list).
3665
+ *
3666
+ * Returns `null` when:
3667
+ * - `namespacesEnabled` is false (overlay would create false isolation)
3668
+ * - no context attached to the session
3669
+ * - `codingMode.projectScope` is false (CLAUDE.md #30 escape hatch)
3670
+ *
3671
+ * The returned `namespace` / `readFallbacks` are RAW overlay fragments
3672
+ * (e.g. `project-origin-ab12`). Callers MUST combine them with the
3673
+ * principal-derived base through `combineNamespaces()` before passing to
3674
+ * storage, so principal isolation is preserved (rule 42).
3675
+ *
3676
+ * @internal
3677
+ */
3678
+ applyCodingRecallOverlay(sessionKey) {
3679
+ if (!this.config.namespacesEnabled) return null;
3680
+ const codingContext = this.getCodingContextForSession(sessionKey);
3681
+ const overlay = resolveCodingNamespaceOverlay(codingContext, this.config.codingMode);
3682
+ if (!overlay) return null;
3683
+ return { namespace: overlay.namespace, readFallbacks: overlay.readFallbacks };
3002
3684
  }
3003
3685
  async getStorageForNamespace(namespace) {
3004
3686
  const ns = typeof namespace === "string" && namespace.trim().length > 0 ? namespace.trim() : this.config.defaultNamespace;
@@ -3083,7 +3765,7 @@ var Orchestrator = class _Orchestrator {
3083
3765
  this.config = config;
3084
3766
  this.profiler = new ProfilingCollector({
3085
3767
  enabled: config.profilingEnabled,
3086
- storageDir: config.profilingStorageDir || path5.join(config.memoryDir, "profiling"),
3768
+ storageDir: config.profilingStorageDir || path7.join(config.memoryDir, "profiling"),
3087
3769
  maxTraces: config.profilingMaxTraces
3088
3770
  });
3089
3771
  this.storageRouter = new NamespaceStorageRouter(config);
@@ -3110,7 +3792,7 @@ var Orchestrator = class _Orchestrator {
3110
3792
  this.compounding = config.compoundingEnabled ? new CompoundingEngine(config) : void 0;
3111
3793
  this.buffer = new SmartBuffer(config, this.storage);
3112
3794
  this.transcript = new TranscriptManager(config);
3113
- this.conversationIndexDir = path5.join(
3795
+ this.conversationIndexDir = path7.join(
3114
3796
  config.memoryDir,
3115
3797
  "conversation-index",
3116
3798
  "chunks"
@@ -3134,6 +3816,7 @@ var Orchestrator = class _Orchestrator {
3134
3816
  this.transcript
3135
3817
  );
3136
3818
  this.judgeVerdictCache = createVerdictCache();
3819
+ this.judgeDeferCounts = createDeferCountMap();
3137
3820
  this.localLlm = new LocalLlmClient(config, this.modelRegistry);
3138
3821
  this.localLlm.disableThinking = config.localLlmDisableThinking;
3139
3822
  this.fastLlm = config.localLlmFastEnabled ? (() => {
@@ -3149,7 +3832,7 @@ var Orchestrator = class _Orchestrator {
3149
3832
  client.disableThinking = true;
3150
3833
  return client;
3151
3834
  })() : this.localLlm;
3152
- this.fastGatewayLlm = config.modelSource === "gateway" ? new FallbackLlmClient(config.gatewayConfig) : null;
3835
+ this._fastGatewayLlm = config.modelSource === "gateway" ? new FallbackLlmClient(config.gatewayConfig) : null;
3153
3836
  if (config.modelSource === "gateway") {
3154
3837
  log.debug(
3155
3838
  `orchestrator: gateway model source active` + (config.gatewayAgentId ? ` (primary: ${config.gatewayAgentId})` : "") + (config.fastGatewayAgentId ? ` (fast: ${config.fastGatewayAgentId})` : "")
@@ -3163,7 +3846,7 @@ var Orchestrator = class _Orchestrator {
3163
3846
  this.modelRegistry
3164
3847
  );
3165
3848
  this.threading = new ThreadingManager(
3166
- path5.join(config.memoryDir, "threads"),
3849
+ path7.join(config.memoryDir, "threads"),
3167
3850
  config.threadingGapMinutes
3168
3851
  );
3169
3852
  this.tmtBuilder = new TmtBuilder(config.memoryDir, {
@@ -3349,9 +4032,9 @@ var Orchestrator = class _Orchestrator {
3349
4032
  * routes through the gateway chain. Otherwise uses the local fast LLM.
3350
4033
  */
3351
4034
  async fastChatCompletion(messages, options) {
3352
- if (this.fastGatewayLlm && this.config.modelSource === "gateway") {
4035
+ if (this._fastGatewayLlm && this.config.modelSource === "gateway") {
3353
4036
  const agentId = this.config.fastGatewayAgentId || this.config.gatewayAgentId || void 0;
3354
- const result2 = await this.fastGatewayLlm.chatCompletion(
4037
+ const result2 = await this._fastGatewayLlm.chatCompletion(
3355
4038
  messages,
3356
4039
  { temperature: options.temperature, maxTokens: options.maxTokens, timeoutMs: options.timeoutMs, agentId }
3357
4040
  );
@@ -3366,7 +4049,7 @@ var Orchestrator = class _Orchestrator {
3366
4049
  * Otherwise returns the local fast LLM directly.
3367
4050
  */
3368
4051
  get fastLlmForRerank() {
3369
- if (this.fastGatewayLlm && this.config.modelSource === "gateway") {
4052
+ if (this._fastGatewayLlm && this.config.modelSource === "gateway") {
3370
4053
  return {
3371
4054
  chatCompletion: (messages, options) => this.fastChatCompletion(messages, options ?? {})
3372
4055
  };
@@ -3408,7 +4091,7 @@ var Orchestrator = class _Orchestrator {
3408
4091
  promotionByOutcomeEnabled: this.config.promotionByOutcomeEnabled
3409
4092
  });
3410
4093
  if (this.config.factDeduplicationEnabled) {
3411
- const stateDir = path5.join(this.config.memoryDir, "state");
4094
+ const stateDir = path7.join(this.config.memoryDir, "state");
3412
4095
  this.contentHashIndex = new ContentHashIndex(stateDir);
3413
4096
  await this.contentHashIndex.load();
3414
4097
  log.info(
@@ -3437,7 +4120,7 @@ var Orchestrator = class _Orchestrator {
3437
4120
  const files = await readdir3(wsDir).catch(() => []);
3438
4121
  for (const f of files) {
3439
4122
  if (!f.startsWith(".compaction-reset-signal-")) continue;
3440
- const fp = path5.join(wsDir, f);
4123
+ const fp = path7.join(wsDir, f);
3441
4124
  const s = await stat3(fp).catch(() => null);
3442
4125
  if (s && Date.now() - s.mtimeMs >= COMPACTION_SIGNAL_MAX_AGE_MS) {
3443
4126
  await unlink2(fp).catch(() => {
@@ -3466,6 +4149,7 @@ var Orchestrator = class _Orchestrator {
3466
4149
  (entry) => entry.namespace === this.config.defaultNamespace
3467
4150
  )?.state ?? "unknown";
3468
4151
  if (defaultState === "missing") {
4152
+ await this.disposeSearchBackendIfNeeded();
3469
4153
  this.qmd = new NoopSearchBackend();
3470
4154
  log.warn(
3471
4155
  "Search collection missing for Remnic memory store; disabling search retrieval for this runtime (fallback retrieval remains enabled)"
@@ -3526,10 +4210,11 @@ var Orchestrator = class _Orchestrator {
3526
4210
  log.info("QMD startup sync: updating index to match current disk state");
3527
4211
  if (this.config.namespacesEnabled) {
3528
4212
  await this.namespaceSearchRouter.updateNamespaces(
3529
- this.configuredNamespaces()
4213
+ this.configuredNamespaces(),
4214
+ { signal }
3530
4215
  );
3531
4216
  } else {
3532
- await this.qmd.update();
4217
+ await this.qmd.update({ signal });
3533
4218
  }
3534
4219
  log.info("QMD startup sync: complete");
3535
4220
  this.deferredSyncSucceeded = true;
@@ -3546,7 +4231,7 @@ var Orchestrator = class _Orchestrator {
3546
4231
  const warmupNs = this.config.defaultNamespace;
3547
4232
  log.info("QMD warmup: pre-loading models with a test search");
3548
4233
  warmupPromises.push(
3549
- this.qmd.search("warmup", warmupNs, 1).then(() => {
4234
+ this.qmd.search("warmup", warmupNs, 1, void 0, { signal }).then(() => {
3550
4235
  log.info("QMD warmup: complete");
3551
4236
  }).catch((err) => {
3552
4237
  log.debug(`QMD warmup search failed (non-fatal): ${err}`);
@@ -3686,6 +4371,7 @@ var Orchestrator = class _Orchestrator {
3686
4371
  if ("available" in this.qmd) {
3687
4372
  this.qmd.available = false;
3688
4373
  }
4374
+ await this.disposeSearchBackendIfNeeded();
3689
4375
  this.qmd = new NoopSearchBackend();
3690
4376
  log.warn("startupSearchSync: search collection missing; disabling search (fallback retrieval remains enabled)");
3691
4377
  return false;
@@ -3700,9 +4386,12 @@ var Orchestrator = class _Orchestrator {
3700
4386
  log.info("startupSearchSync: updating index to match current disk state");
3701
4387
  let namespacesUpdated = 0;
3702
4388
  if (this.config.namespacesEnabled) {
3703
- namespacesUpdated = await this.namespaceSearchRouter.updateNamespaces(namespaces);
4389
+ namespacesUpdated = await this.namespaceSearchRouter.updateNamespaces(
4390
+ namespaces,
4391
+ { signal }
4392
+ );
3704
4393
  } else {
3705
- await this.qmd.update(signal);
4394
+ await this.qmd.update({ signal });
3706
4395
  }
3707
4396
  if (signal?.aborted) {
3708
4397
  log.debug("startupSearchSync: aborted after update");
@@ -3746,7 +4435,7 @@ var Orchestrator = class _Orchestrator {
3746
4435
  */
3747
4436
  async autoRegisterDaySummaryCron() {
3748
4437
  const home = resolveHomeDir();
3749
- const jobsPath = path5.join(home, ".openclaw", "cron", "jobs.json");
4438
+ const jobsPath = path7.join(home, ".openclaw", "cron", "jobs.json");
3750
4439
  try {
3751
4440
  if (!existsSync2(jobsPath)) {
3752
4441
  log.debug(
@@ -3770,7 +4459,7 @@ var Orchestrator = class _Orchestrator {
3770
4459
  }
3771
4460
  async autoRegisterNightlyGovernanceCron() {
3772
4461
  const home = process.env.HOME || os.homedir();
3773
- const jobsPath = path5.join(home, ".openclaw", "cron", "jobs.json");
4462
+ const jobsPath = path7.join(home, ".openclaw", "cron", "jobs.json");
3774
4463
  try {
3775
4464
  if (!existsSync2(jobsPath)) {
3776
4465
  log.debug("nightly governance cron: jobs.json not found, skipping auto-register");
@@ -3792,7 +4481,7 @@ var Orchestrator = class _Orchestrator {
3792
4481
  }
3793
4482
  async autoRegisterProceduralMiningCron() {
3794
4483
  const home = resolveHomeDir();
3795
- const jobsPath = path5.join(home, ".openclaw", "cron", "jobs.json");
4484
+ const jobsPath = path7.join(home, ".openclaw", "cron", "jobs.json");
3796
4485
  try {
3797
4486
  if (!existsSync2(jobsPath)) {
3798
4487
  log.debug("procedural mining cron: jobs.json not found, skipping auto-register");
@@ -3812,7 +4501,7 @@ var Orchestrator = class _Orchestrator {
3812
4501
  }
3813
4502
  async autoRegisterContradictionScanCron() {
3814
4503
  const home = resolveHomeDir();
3815
- const jobsPath = path5.join(home, ".openclaw", "cron", "jobs.json");
4504
+ const jobsPath = path7.join(home, ".openclaw", "cron", "jobs.json");
3816
4505
  try {
3817
4506
  if (!existsSync2(jobsPath)) {
3818
4507
  log.debug("contradiction scan cron: jobs.json not found, skipping auto-register");
@@ -3848,15 +4537,15 @@ var Orchestrator = class _Orchestrator {
3848
4537
  this.lastFileHygieneRunAtMs = now;
3849
4538
  if (hygiene.rotateEnabled) {
3850
4539
  for (const rel of hygiene.rotatePaths) {
3851
- const abs = path5.isAbsolute(rel) ? rel : path5.join(this.config.workspaceDir, rel);
4540
+ const abs = path7.isAbsolute(rel) ? rel : path7.join(this.config.workspaceDir, rel);
3852
4541
  try {
3853
- const raw = await readFile3(abs, "utf-8");
4542
+ const raw = await readFile4(abs, "utf-8");
3854
4543
  if (raw.length > hygiene.rotateMaxBytes) {
3855
- const archiveDir = path5.join(
4544
+ const archiveDir = path7.join(
3856
4545
  this.config.workspaceDir,
3857
4546
  hygiene.archiveDir
3858
4547
  );
3859
- const base = path5.basename(abs);
4548
+ const base = path7.basename(abs);
3860
4549
  const prefix = base.toUpperCase().replace(/\.MD$/i, "").replace(/[^A-Z0-9]+/g, "-") || "FILE";
3861
4550
  const { newContent } = await rotateMarkdownFileToArchive({
3862
4551
  filePath: abs,
@@ -3864,7 +4553,7 @@ var Orchestrator = class _Orchestrator {
3864
4553
  archivePrefix: prefix,
3865
4554
  keepTailChars: hygiene.rotateKeepTailChars
3866
4555
  });
3867
- await writeFile3(abs, newContent, "utf-8");
4556
+ await writeFile4(abs, newContent, "utf-8");
3868
4557
  }
3869
4558
  } catch {
3870
4559
  }
@@ -3881,8 +4570,8 @@ var Orchestrator = class _Orchestrator {
3881
4570
  log.warn(w.message);
3882
4571
  }
3883
4572
  if (hygiene.warningsLogEnabled && warnings.length > 0) {
3884
- const fp = path5.join(this.config.memoryDir, hygiene.warningsLogPath);
3885
- await mkdir4(path5.dirname(fp), { recursive: true });
4573
+ const fp = path7.join(this.config.memoryDir, hygiene.warningsLogPath);
4574
+ await mkdir5(path7.dirname(fp), { recursive: true });
3886
4575
  const stamp = (/* @__PURE__ */ new Date()).toISOString();
3887
4576
  const block = `
3888
4577
 
@@ -3891,11 +4580,11 @@ var Orchestrator = class _Orchestrator {
3891
4580
  ` + warnings.map((w) => `- ${w.message}`).join("\n") + "\n";
3892
4581
  let existing = "";
3893
4582
  try {
3894
- existing = await readFile3(fp, "utf-8");
4583
+ existing = await readFile4(fp, "utf-8");
3895
4584
  } catch {
3896
4585
  existing = "# Engram File Hygiene Warnings\n";
3897
4586
  }
3898
- await writeFile3(fp, existing + block, "utf-8");
4587
+ await writeFile4(fp, existing + block, "utf-8");
3899
4588
  }
3900
4589
  }
3901
4590
  }
@@ -3979,14 +4668,15 @@ var Orchestrator = class _Orchestrator {
3979
4668
  }
3980
4669
  for (const cluster of clusters) {
3981
4670
  try {
3982
- let prompt = buildConsolidationPrompt(cluster);
4671
+ const operatorAwareEnabled = this.config.operatorAwareConsolidationEnabled === true;
4672
+ let prompt = operatorAwareEnabled ? buildOperatorAwareConsolidationPrompt(cluster) : buildConsolidationPrompt(cluster);
3983
4673
  if (extensionsBlock.length > 0) {
3984
4674
  prompt += "\n\n" + extensionsBlock;
3985
4675
  }
3986
4676
  const messages = [
3987
4677
  {
3988
4678
  role: "system",
3989
- content: "You are a memory consolidation system. Output only the consolidated memory text."
4679
+ content: operatorAwareEnabled ? 'You are a memory consolidation system. Return ONLY a JSON object with two keys, "operator" and "output". The "operator" value MUST be one of the exact strings "merge", "update", or "split" \u2014 never a pipe-separated placeholder, never prose. The "output" value is the canonical memory text.' : "You are a memory consolidation system. Output only the consolidated memory text."
3990
4680
  },
3991
4681
  { role: "user", content: prompt }
3992
4682
  ];
@@ -4012,13 +4702,31 @@ var Orchestrator = class _Orchestrator {
4012
4702
  result.errors++;
4013
4703
  continue;
4014
4704
  }
4015
- const canonicalContent = parseConsolidationResponse(response.content);
4705
+ let canonicalContent;
4706
+ let operator;
4707
+ if (operatorAwareEnabled) {
4708
+ const parsed = parseOperatorAwareConsolidationResponse(
4709
+ response.content,
4710
+ cluster
4711
+ );
4712
+ canonicalContent = parsed.output;
4713
+ operator = parsed.operator;
4714
+ } else {
4715
+ canonicalContent = parseConsolidationResponse(response.content);
4716
+ operator = chooseConsolidationOperator(cluster);
4717
+ }
4016
4718
  cluster.canonicalContent = canonicalContent;
4017
4719
  const sorted = [...cluster.memories].sort(
4018
4720
  (a, b) => new Date(b.frontmatter.created).getTime() - new Date(a.frontmatter.created).getTime()
4019
4721
  );
4020
4722
  const newest = sorted[0];
4021
4723
  const lineageIds = cluster.memories.map((m) => m.frontmatter.id);
4724
+ const derivedFromEntries = [];
4725
+ for (const m of cluster.memories) {
4726
+ if (!m.path) continue;
4727
+ const entry = await this.storage.snapshotForProvenance(m.path);
4728
+ if (entry) derivedFromEntries.push(entry);
4729
+ }
4022
4730
  const canonicalId = await this.storage.writeMemory(
4023
4731
  newest.frontmatter.category,
4024
4732
  canonicalContent,
@@ -4031,7 +4739,9 @@ var Orchestrator = class _Orchestrator {
4031
4739
  )
4032
4740
  ],
4033
4741
  source: "semantic-consolidation",
4034
- lineage: lineageIds
4742
+ lineage: lineageIds,
4743
+ derivedFrom: derivedFromEntries.length > 0 ? derivedFromEntries : void 0,
4744
+ derivedVia: operator
4035
4745
  }
4036
4746
  );
4037
4747
  result.memoriesConsolidated++;
@@ -4273,18 +4983,18 @@ ${evidenceText}`
4273
4983
  const datesToScan = [yesterday, utcToday].filter(
4274
4984
  (v, i, a) => a.indexOf(v) === i
4275
4985
  );
4276
- const factsBaseDir = path5.join(storage.dir, "facts");
4986
+ const factsBaseDir = path7.join(storage.dir, "facts");
4277
4987
  const MAX_CHARS = 1e5;
4278
4988
  const facts = [];
4279
4989
  for (const date of datesToScan) {
4280
- const factsDir = path5.join(factsBaseDir, date);
4990
+ const factsDir = path7.join(factsBaseDir, date);
4281
4991
  try {
4282
4992
  const entries = await readdir3(factsDir, { withFileTypes: true });
4283
4993
  for (const entry of entries) {
4284
4994
  if (!entry.name.endsWith(".md")) continue;
4285
- const fullPath = path5.join(factsDir, entry.name);
4995
+ const fullPath = path7.join(factsDir, entry.name);
4286
4996
  try {
4287
- const raw = await readFile3(fullPath, "utf-8");
4997
+ const raw = await readFile4(fullPath, "utf-8");
4288
4998
  const fmMatch = raw.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);
4289
4999
  if (!fmMatch) continue;
4290
5000
  const fmBlock = fmMatch[1];
@@ -4298,7 +5008,7 @@ ${evidenceText}`
4298
5008
  facts.push({
4299
5009
  path: fullPath,
4300
5010
  frontmatter: {
4301
- id: fm.id || path5.basename(entry.name, ".md"),
5011
+ id: fm.id || path7.basename(entry.name, ".md"),
4302
5012
  category: fm.category || "fact",
4303
5013
  created: fm.created || "unknown",
4304
5014
  updated: fm.updated || fm.created || "unknown",
@@ -4319,15 +5029,15 @@ ${evidenceText}`
4319
5029
  (a, b) => a.frontmatter.created < b.frontmatter.created ? -1 : 1
4320
5030
  );
4321
5031
  const hourlySummaries = [];
4322
- const hourlyBaseDir = path5.join(storage.dir, "summaries", "hourly");
5032
+ const hourlyBaseDir = path7.join(storage.dir, "summaries", "hourly");
4323
5033
  try {
4324
5034
  const sessionKeys = await readdir3(hourlyBaseDir, { withFileTypes: true });
4325
5035
  for (const sk of sessionKeys) {
4326
5036
  if (!sk.isDirectory()) continue;
4327
5037
  for (const date of datesToScan) {
4328
- const summaryFile = path5.join(hourlyBaseDir, sk.name, `${date}.md`);
5038
+ const summaryFile = path7.join(hourlyBaseDir, sk.name, `${date}.md`);
4329
5039
  try {
4330
- const raw = await readFile3(summaryFile, "utf-8");
5040
+ const raw = await readFile4(summaryFile, "utf-8");
4331
5041
  if (raw.trim().length > 0) {
4332
5042
  hourlySummaries.push(raw.trim());
4333
5043
  }
@@ -4423,13 +5133,13 @@ ${evidenceText}`
4423
5133
  }
4424
5134
  async getLastGraphRecallSnapshot(namespace) {
4425
5135
  const storage = await this.getStorage(namespace);
4426
- const snapshotPath = path5.join(
5136
+ const snapshotPath = path7.join(
4427
5137
  storage.dir,
4428
5138
  "state",
4429
5139
  "last_graph_recall.json"
4430
5140
  );
4431
5141
  try {
4432
- const raw = await readFile3(snapshotPath, "utf-8");
5142
+ const raw = await readFile4(snapshotPath, "utf-8");
4433
5143
  const parsed = JSON.parse(raw);
4434
5144
  if (!parsed || typeof parsed !== "object") return null;
4435
5145
  return {
@@ -4462,9 +5172,9 @@ ${evidenceText}`
4462
5172
  }
4463
5173
  async getLastIntentSnapshot(namespace) {
4464
5174
  const storage = await this.getStorage(namespace);
4465
- const snapshotPath = path5.join(storage.dir, "state", "last_intent.json");
5175
+ const snapshotPath = path7.join(storage.dir, "state", "last_intent.json");
4466
5176
  try {
4467
- const raw = await readFile3(snapshotPath, "utf-8");
5177
+ const raw = await readFile4(snapshotPath, "utf-8");
4468
5178
  const parsed = JSON.parse(raw);
4469
5179
  if (!parsed || typeof parsed !== "object") return null;
4470
5180
  const graphDecision = parsed.graphDecision && typeof parsed.graphDecision === "object" ? parsed.graphDecision : void 0;
@@ -4495,13 +5205,13 @@ ${evidenceText}`
4495
5205
  }
4496
5206
  async getLastQmdRecallSnapshot(namespace) {
4497
5207
  const storage = await this.getStorage(namespace);
4498
- const snapshotPath = path5.join(
5208
+ const snapshotPath = path7.join(
4499
5209
  storage.dir,
4500
5210
  "state",
4501
5211
  "last_qmd_recall.json"
4502
5212
  );
4503
5213
  try {
4504
- const raw = await readFile3(snapshotPath, "utf-8");
5214
+ const raw = await readFile4(snapshotPath, "utf-8");
4505
5215
  const parsed = JSON.parse(raw);
4506
5216
  if (!parsed || typeof parsed !== "object") return null;
4507
5217
  return {
@@ -4647,7 +5357,7 @@ ${r.snippet.trim()}
4647
5357
  const entries = await readdir3(dir, { withFileTypes: true });
4648
5358
  let total = 0;
4649
5359
  for (const entry of entries) {
4650
- const fullPath = path5.join(dir, entry.name);
5360
+ const fullPath = path7.join(dir, entry.name);
4651
5361
  if (entry.isDirectory()) {
4652
5362
  total += await this.countConversationChunkDocs(fullPath);
4653
5363
  continue;
@@ -4918,11 +5628,24 @@ ${r.snippet.trim()}
4918
5628
  reject(new Error("recall timeout"));
4919
5629
  }, RECALL_TIMEOUT_MS);
4920
5630
  });
5631
+ let recallResult;
4921
5632
  try {
4922
- return await Promise.race([recallPromise, timeoutPromise]);
5633
+ recallResult = await Promise.race([recallPromise, timeoutPromise]);
4923
5634
  } finally {
4924
5635
  if (timeoutHandle) clearTimeout(timeoutHandle);
4925
5636
  }
5637
+ if (this.config.recallDirectAnswerEnabled && sessionKey) {
5638
+ try {
5639
+ this.enqueueDirectAnswerObservation(
5640
+ prompt,
5641
+ sessionKey,
5642
+ options.namespace?.trim() || void 0
5643
+ );
5644
+ } catch (err) {
5645
+ log.debug(`direct-answer observation setup failed: ${err}`);
5646
+ }
5647
+ }
5648
+ return recallResult;
4926
5649
  } catch (err) {
4927
5650
  this.logRecallFailure(err);
4928
5651
  this.profiler.endTrace();
@@ -4931,6 +5654,183 @@ ${r.snippet.trim()}
4931
5654
  options.abortSignal?.removeEventListener("abort", onAbort);
4932
5655
  }
4933
5656
  }
5657
+ /**
5658
+ * Return the most recent X-ray snapshot captured during a
5659
+ * `recall()` call that passed `xrayCapture: true` (issue #570 PR 1).
5660
+ * Returns `null` when no such capture has occurred on this
5661
+ * orchestrator instance. Returned snapshot is a deep copy so
5662
+ * caller mutation cannot tear the stored value.
5663
+ */
5664
+ getLastXraySnapshot() {
5665
+ if (!this.lastXraySnapshot) return null;
5666
+ return structuredClone(this.lastXraySnapshot);
5667
+ }
5668
+ /** Clear the captured X-ray snapshot. Exposed for tests / explicit reset. */
5669
+ clearLastXraySnapshot() {
5670
+ this.lastXraySnapshot = null;
5671
+ }
5672
+ /**
5673
+ * Await the in-flight observation-mode direct-answer annotation chain.
5674
+ * Resolves to true when settled, false on timeout.
5675
+ */
5676
+ async waitForDirectAnswerObservationIdle(timeoutMs = 6e4) {
5677
+ let timeoutHandle = null;
5678
+ try {
5679
+ const timeoutPromise = new Promise((resolve) => {
5680
+ timeoutHandle = setTimeout(() => resolve("timeout"), timeoutMs);
5681
+ });
5682
+ const result = await Promise.race([
5683
+ this.directAnswerObservationChain.then(() => "ok"),
5684
+ timeoutPromise
5685
+ ]);
5686
+ if (result === "timeout") {
5687
+ log.warn(
5688
+ `waitForDirectAnswerObservationIdle timed out after ${timeoutMs}ms`
5689
+ );
5690
+ return false;
5691
+ }
5692
+ return true;
5693
+ } finally {
5694
+ if (timeoutHandle) clearTimeout(timeoutHandle);
5695
+ }
5696
+ }
5697
+ enqueueDirectAnswerObservation(prompt, sessionKey, namespaceOverride) {
5698
+ const expectedSnapshot = this.lastRecall.get(sessionKey);
5699
+ if (expectedSnapshot === null) return;
5700
+ if (expectedSnapshot.plannerMode === "no_recall") return;
5701
+ const principal = resolvePrincipal(sessionKey, this.config);
5702
+ const observationCodingOverlay = namespaceOverride && canReadNamespace(principal, namespaceOverride, this.config) ? null : this.applyCodingRecallOverlay(sessionKey);
5703
+ const observationPrincipalSelf = defaultNamespaceForPrincipal(principal, this.config);
5704
+ const observationCodingSelf = observationCodingOverlay ? combineNamespaces(observationPrincipalSelf, observationCodingOverlay.namespace) : null;
5705
+ let observationNamespaces;
5706
+ if (namespaceOverride && canReadNamespace(principal, namespaceOverride, this.config)) {
5707
+ observationNamespaces = [namespaceOverride];
5708
+ } else if (observationCodingOverlay && observationCodingSelf) {
5709
+ const base = recallNamespacesForPrincipal(principal, this.config);
5710
+ const mapped = base.map(
5711
+ (ns) => ns === observationPrincipalSelf ? observationCodingSelf : ns
5712
+ );
5713
+ const fallbackNs = observationCodingOverlay.readFallbacks.map(
5714
+ (fallback) => combineNamespaces(observationPrincipalSelf, fallback)
5715
+ );
5716
+ observationNamespaces = Array.from(/* @__PURE__ */ new Set([...mapped, ...fallbackNs]));
5717
+ } else {
5718
+ observationNamespaces = recallNamespacesForPrincipal(principal, this.config);
5719
+ }
5720
+ const observationQueryPolicy = buildRecallQueryPolicy(prompt, sessionKey, {
5721
+ cronRecallPolicyEnabled: this.config.cronRecallPolicyEnabled,
5722
+ cronRecallNormalizedQueryMaxChars: this.config.cronRecallNormalizedQueryMaxChars,
5723
+ cronRecallInstructionHeavyTokenCap: this.effectiveCronRecallInstructionHeavyTokenCap(),
5724
+ cronConversationRecallMode: this.config.cronConversationRecallMode
5725
+ });
5726
+ const observationQuery = observationQueryPolicy.retrievalQuery || prompt;
5727
+ const expectedIdentity = {
5728
+ writeNonce: expectedSnapshot.writeNonce,
5729
+ traceId: expectedSnapshot.traceId,
5730
+ recordedAt: expectedSnapshot.recordedAt
5731
+ };
5732
+ const previous = this.directAnswerObservationChain;
5733
+ this.directAnswerObservationChain = previous.catch(() => void 0).then(async () => {
5734
+ try {
5735
+ await this.annotateDirectAnswerTier(
5736
+ observationQuery,
5737
+ sessionKey,
5738
+ observationNamespaces,
5739
+ expectedIdentity,
5740
+ void 0
5741
+ );
5742
+ } catch (err) {
5743
+ log.debug(`direct-answer observation chain error: ${err}`);
5744
+ }
5745
+ });
5746
+ }
5747
+ async annotateDirectAnswerTier(prompt, sessionKey, namespaces, expectedIdentity, _parentAbortSignal) {
5748
+ const tierStart = Date.now();
5749
+ try {
5750
+ if (namespaces.length === 0) return;
5751
+ const trustZoneByNsAndRecordId = /* @__PURE__ */ new Map();
5752
+ const trustZoneKey = (ns, recordId) => `${ns}\0${recordId}`;
5753
+ const scopedStorages = /* @__PURE__ */ new Map();
5754
+ for (const ns of namespaces) {
5755
+ const storage = await this.storageRouter.storageFor(ns);
5756
+ scopedStorages.set(ns, storage);
5757
+ const trustZones = await listTrustZoneRecords({
5758
+ memoryDir: storage.dir,
5759
+ trustZoneStoreDir: this.config.trustZoneStoreDir,
5760
+ limit: 200
5761
+ }).catch(() => ({
5762
+ allRecords: []
5763
+ }));
5764
+ for (const record of trustZones.allRecords ?? []) {
5765
+ trustZoneByNsAndRecordId.set(
5766
+ trustZoneKey(ns, record.recordId),
5767
+ record.zone
5768
+ );
5769
+ }
5770
+ }
5771
+ const memoryNamespaceByPath = /* @__PURE__ */ new Map();
5772
+ const memoryNamespaceById = /* @__PURE__ */ new Map();
5773
+ let candidatesConsidered = 0;
5774
+ const sources = {
5775
+ taxonomy: DEFAULT_TAXONOMY,
5776
+ listCandidateMemories: async (options) => {
5777
+ const targetNs = options.namespace;
5778
+ const storage = scopedStorages.get(targetNs) ?? await this.storageRouter.storageFor(targetNs);
5779
+ const all = await storage.readAllMemories();
5780
+ const active = [];
5781
+ for (const m of all) {
5782
+ if ((m.frontmatter.status ?? "active") === "active") {
5783
+ active.push(m);
5784
+ memoryNamespaceByPath.set(m.path, targetNs);
5785
+ if (m.frontmatter.id) {
5786
+ memoryNamespaceById.set(m.frontmatter.id, targetNs);
5787
+ }
5788
+ }
5789
+ }
5790
+ candidatesConsidered += active.length;
5791
+ return active;
5792
+ },
5793
+ trustZoneFor: async (memoryId) => {
5794
+ const ns = memoryNamespaceById.get(memoryId);
5795
+ if (!ns) return null;
5796
+ return trustZoneByNsAndRecordId.get(
5797
+ trustZoneKey(ns, memoryId)
5798
+ ) ?? null;
5799
+ },
5800
+ importanceFor: (memory) => typeof memory.frontmatter.importance?.score === "number" ? memory.frontmatter.importance.score : 0
5801
+ };
5802
+ let result;
5803
+ for (const ns of namespaces) {
5804
+ const r = await tryDirectAnswer({
5805
+ query: prompt,
5806
+ namespace: ns,
5807
+ config: this.config,
5808
+ sources
5809
+ });
5810
+ if (r.eligible && r.winner) {
5811
+ result = r;
5812
+ break;
5813
+ }
5814
+ }
5815
+ if (!result?.eligible || !result?.winner) return;
5816
+ const explain = {
5817
+ tier: "direct-answer",
5818
+ tierReason: result.narrative,
5819
+ filteredBy: result.filteredBy,
5820
+ candidatesConsidered,
5821
+ latencyMs: Date.now() - tierStart,
5822
+ sourceAnchors: [{ path: result.winner.memory.path }]
5823
+ };
5824
+ await this.lastRecall.annotateTierExplain(
5825
+ sessionKey,
5826
+ explain,
5827
+ expectedIdentity
5828
+ );
5829
+ } catch (err) {
5830
+ if (err instanceof Error && err.name === "AbortError") return;
5831
+ log.debug(`direct-answer observation failed: ${err}`);
5832
+ }
5833
+ }
4934
5834
  logRecallFailure(err) {
4935
5835
  const now = Date.now();
4936
5836
  const errorMsg = err instanceof Error ? err.message : String(err);
@@ -5334,7 +6234,7 @@ ${r.snippet.trim()}
5334
6234
  0
5335
6235
  );
5336
6236
  seedPaths.push(
5337
- ...seedRelativePaths.map((rel) => path5.join(storage.dir, rel))
6237
+ ...seedRelativePaths.map((rel) => path7.join(storage.dir, rel))
5338
6238
  );
5339
6239
  const seedSet = new Set(seedRelativePaths);
5340
6240
  const expanded = await this.graphIndexFor(storage).spreadingActivation(
@@ -5344,7 +6244,7 @@ ${r.snippet.trim()}
5344
6244
  if (expanded.length === 0) continue;
5345
6245
  for (const candidate of expanded.slice(0, perNamespaceExpandedCap)) {
5346
6246
  if (seedSet.has(candidate.path)) continue;
5347
- const memoryPath = path5.resolve(storage.dir, candidate.path);
6247
+ const memoryPath = path7.resolve(storage.dir, candidate.path);
5348
6248
  const memory = await storage.readMemoryByPath(memoryPath);
5349
6249
  if (!memory) continue;
5350
6250
  if (isArtifactMemoryPath(memory.path)) continue;
@@ -5368,7 +6268,7 @@ ${r.snippet.trim()}
5368
6268
  path: memory.path,
5369
6269
  score,
5370
6270
  namespace,
5371
- seed: path5.resolve(storage.dir, candidate.seed),
6271
+ seed: path7.resolve(storage.dir, candidate.seed),
5372
6272
  hopDepth: candidate.hopDepth,
5373
6273
  decayedWeight: candidate.decayedWeight,
5374
6274
  graphType: candidate.graphType
@@ -5384,12 +6284,12 @@ ${r.snippet.trim()}
5384
6284
  }
5385
6285
  async recordLastGraphRecallSnapshot(options) {
5386
6286
  try {
5387
- const snapshotPath = path5.join(
6287
+ const snapshotPath = path7.join(
5388
6288
  options.storage.dir,
5389
6289
  "state",
5390
6290
  "last_graph_recall.json"
5391
6291
  );
5392
- await mkdir4(path5.dirname(snapshotPath), { recursive: true });
6292
+ await mkdir5(path7.dirname(snapshotPath), { recursive: true });
5393
6293
  const now = (/* @__PURE__ */ new Date()).toISOString();
5394
6294
  const totalSeedCount = options.seedPaths.length;
5395
6295
  const totalExpandedCount = options.expandedPaths.length;
@@ -5416,20 +6316,20 @@ ${r.snippet.trim()}
5416
6316
  finalResults: (options.finalResults ?? []).slice(0, 64),
5417
6317
  shadowComparison: options.shadowComparison
5418
6318
  };
5419
- await writeFile3(snapshotPath, JSON.stringify(payload, null, 2), "utf-8");
6319
+ await writeFile4(snapshotPath, JSON.stringify(payload, null, 2), "utf-8");
5420
6320
  } catch (err) {
5421
6321
  log.debug(`last graph recall write failed: ${err}`);
5422
6322
  }
5423
6323
  }
5424
6324
  async recordLastIntentSnapshot(options) {
5425
6325
  try {
5426
- const snapshotPath = path5.join(
6326
+ const snapshotPath = path7.join(
5427
6327
  options.storage.dir,
5428
6328
  "state",
5429
6329
  "last_intent.json"
5430
6330
  );
5431
- await mkdir4(path5.dirname(snapshotPath), { recursive: true });
5432
- await writeFile3(
6331
+ await mkdir5(path7.dirname(snapshotPath), { recursive: true });
6332
+ await writeFile4(
5433
6333
  snapshotPath,
5434
6334
  JSON.stringify(options.snapshot, null, 2),
5435
6335
  "utf-8"
@@ -5440,13 +6340,13 @@ ${r.snippet.trim()}
5440
6340
  }
5441
6341
  async recordLastQmdRecallSnapshot(options) {
5442
6342
  try {
5443
- const snapshotPath = path5.join(
6343
+ const snapshotPath = path7.join(
5444
6344
  options.storage.dir,
5445
6345
  "state",
5446
6346
  "last_qmd_recall.json"
5447
6347
  );
5448
- await mkdir4(path5.dirname(snapshotPath), { recursive: true });
5449
- await writeFile3(
6348
+ await mkdir5(path7.dirname(snapshotPath), { recursive: true });
6349
+ await writeFile4(
5450
6350
  snapshotPath,
5451
6351
  JSON.stringify(options.snapshot, null, 2),
5452
6352
  "utf-8"
@@ -5460,9 +6360,9 @@ ${r.snippet.trim()}
5460
6360
  const stateDir = await this.resolveStateDirForNamespace(
5461
6361
  options.namespace
5462
6362
  );
5463
- const snapshotPath = path5.join(stateDir, "last_intent.json");
5464
- await mkdir4(path5.dirname(snapshotPath), { recursive: true });
5465
- await writeFile3(
6363
+ const snapshotPath = path7.join(stateDir, "last_intent.json");
6364
+ await mkdir5(path7.dirname(snapshotPath), { recursive: true });
6365
+ await writeFile4(
5466
6366
  snapshotPath,
5467
6367
  JSON.stringify(options.snapshot, null, 2),
5468
6368
  "utf-8"
@@ -5473,12 +6373,12 @@ ${r.snippet.trim()}
5473
6373
  }
5474
6374
  async resolveStateDirForNamespace(namespace) {
5475
6375
  if (!this.config.namespacesEnabled) {
5476
- return path5.join(this.config.memoryDir, "state");
6376
+ return path7.join(this.config.memoryDir, "state");
5477
6377
  }
5478
6378
  if (namespace !== this.config.defaultNamespace) {
5479
- return path5.join(this.config.memoryDir, "namespaces", namespace, "state");
6379
+ return path7.join(this.config.memoryDir, "namespaces", namespace, "state");
5480
6380
  }
5481
- const candidate = path5.join(
6381
+ const candidate = path7.join(
5482
6382
  this.config.memoryDir,
5483
6383
  "namespaces",
5484
6384
  this.config.defaultNamespace
@@ -5486,11 +6386,11 @@ ${r.snippet.trim()}
5486
6386
  try {
5487
6387
  const candidateStat = await stat3(candidate);
5488
6388
  if (candidateStat.isDirectory()) {
5489
- return path5.join(candidate, "state");
6389
+ return path7.join(candidate, "state");
5490
6390
  }
5491
6391
  } catch {
5492
6392
  }
5493
- return path5.join(this.config.memoryDir, "state");
6393
+ return path7.join(this.config.memoryDir, "state");
5494
6394
  }
5495
6395
  buildGraphRecallRankedResults(results, sourceLabelResolver, limit = 64) {
5496
6396
  return results.slice(0, limit).map((result) => ({
@@ -5576,7 +6476,10 @@ ${r.snippet.trim()}
5576
6476
  }
5577
6477
  return reserved;
5578
6478
  }
5579
- getRecallBudgetChars() {
6479
+ getRecallBudgetChars(override) {
6480
+ if (typeof override === "number" && Number.isFinite(override) && override >= 0) {
6481
+ return Math.floor(override);
6482
+ }
5580
6483
  const configuredBudget = this.config.recallBudgetChars;
5581
6484
  if (typeof configuredBudget === "number" && Number.isFinite(configuredBudget) && configuredBudget >= 0) {
5582
6485
  return Math.floor(configuredBudget);
@@ -5587,7 +6490,7 @@ ${r.snippet.trim()}
5587
6490
  }
5588
6491
  return 0;
5589
6492
  }
5590
- assembleRecallSections(sectionBuckets) {
6493
+ assembleRecallSections(sectionBuckets, budgetOverride) {
5591
6494
  const orderedEntries = [];
5592
6495
  const pipeline = Array.isArray(this.config.recallPipeline) ? this.config.recallPipeline : [];
5593
6496
  const orderedIds = pipeline.filter((entry) => entry.enabled !== false).map((entry) => entry.id);
@@ -5603,7 +6506,7 @@ ${r.snippet.trim()}
5603
6506
  if (chunks.length === 0) continue;
5604
6507
  orderedEntries.push({ id, content: chunks.join("\n\n") });
5605
6508
  }
5606
- const budget = this.getRecallBudgetChars();
6509
+ const budget = this.getRecallBudgetChars(budgetOverride);
5607
6510
  if (budget === 0) {
5608
6511
  return {
5609
6512
  sections: [],
@@ -5735,6 +6638,13 @@ ${r.snippet.trim()}
5735
6638
  let recalledMemoryCount = 0;
5736
6639
  let recalledMemoryIds = [];
5737
6640
  let recalledMemoryPaths = [];
6641
+ const xrayBranchPoolSize = {
6642
+ hot_qmd: 0,
6643
+ hot_embedding: 0,
6644
+ cold_fallback: 0,
6645
+ recent_scan: 0
6646
+ };
6647
+ const xrayColdPoolSink = { size: 0 };
5738
6648
  let identityInjectionModeUsed = "none";
5739
6649
  let identityInjectedChars = 0;
5740
6650
  let identityInjectionTruncated = false;
@@ -5795,7 +6705,7 @@ ${r.snippet.trim()}
5795
6705
  this.config.verbatimArtifactsMaxRecall
5796
6706
  );
5797
6707
  const embeddingFetchLimit = computedFetchLimit;
5798
- const principal = resolvePrincipal(sessionKey, this.config);
6708
+ const principal = typeof options.principalOverride === "string" && options.principalOverride.length > 0 ? options.principalOverride : resolvePrincipal(sessionKey, this.config);
5799
6709
  const namespaceOverride = options.namespace?.trim() || void 0;
5800
6710
  const readableRecallNamespaces = recallNamespacesForPrincipal(
5801
6711
  principal,
@@ -5806,8 +6716,24 @@ ${r.snippet.trim()}
5806
6716
  `namespace override is not readable: ${namespaceOverride}`
5807
6717
  );
5808
6718
  }
5809
- const selfNamespace = namespaceOverride ?? defaultNamespaceForPrincipal(principal, this.config);
5810
- const recallNamespaces = namespaceOverride ? [namespaceOverride] : readableRecallNamespaces;
6719
+ const codingOverlay = namespaceOverride ? null : this.applyCodingRecallOverlay(sessionKey);
6720
+ const principalSelfNamespace = defaultNamespaceForPrincipal(principal, this.config);
6721
+ const codingSelfNamespace = codingOverlay ? combineNamespaces(principalSelfNamespace, codingOverlay.namespace) : null;
6722
+ const selfNamespace = namespaceOverride ?? codingSelfNamespace ?? principalSelfNamespace;
6723
+ let recallNamespaces;
6724
+ if (namespaceOverride) {
6725
+ recallNamespaces = [namespaceOverride];
6726
+ } else if (codingOverlay && codingSelfNamespace) {
6727
+ const mapped = readableRecallNamespaces.map(
6728
+ (ns) => ns === principalSelfNamespace ? codingSelfNamespace : ns
6729
+ );
6730
+ const fallbackNs = codingOverlay.readFallbacks.map(
6731
+ (fallback) => combineNamespaces(principalSelfNamespace, fallback)
6732
+ );
6733
+ recallNamespaces = Array.from(/* @__PURE__ */ new Set([...mapped, ...fallbackNs]));
6734
+ } else {
6735
+ recallNamespaces = readableRecallNamespaces;
6736
+ }
5811
6737
  const qmdAvailable = this.qmd.isAvailable();
5812
6738
  let graphDecisionStatus = recallDecision.plannedMode === "graph_mode" ? "skipped" : "not_requested";
5813
6739
  let graphDecisionReason = recallDecision.graphReason;
@@ -5824,7 +6750,7 @@ ${r.snippet.trim()}
5824
6750
  const graphExpandedResultPaths = /* @__PURE__ */ new Set();
5825
6751
  const graphSourceLabelsForPath = (resultPath) => {
5826
6752
  const labels = [];
5827
- const normalizedPath = resultPath.split(path5.sep).join("/");
6753
+ const normalizedPath = resultPath.split(path7.sep).join("/");
5828
6754
  const isEntityPath = normalizedPath.startsWith("entities/") || normalizedPath.includes("/entities/");
5829
6755
  if (graphBaselinePaths.has(resultPath)) labels.push("baseline");
5830
6756
  if (graphExpandedResultPaths.has(resultPath))
@@ -5862,6 +6788,32 @@ ${r.snippet.trim()}
5862
6788
  const earlySessionKey = sessionKey ?? "default";
5863
6789
  this._recallWorkspaceOverrides.delete(earlySessionKey);
5864
6790
  timings.total = `${Date.now() - recallStart}ms`;
6791
+ if (options.xrayCapture === true && !options.abortSignal?.aborted) {
6792
+ try {
6793
+ this.lastXraySnapshot = buildXraySnapshot({
6794
+ query: retrievalQuery,
6795
+ tierExplain: null,
6796
+ results: [],
6797
+ filters: [
6798
+ {
6799
+ name: "planner-mode",
6800
+ considered: 0,
6801
+ admitted: 0,
6802
+ reason: "no_recall"
6803
+ }
6804
+ ],
6805
+ budget: {
6806
+ chars: this.getRecallBudgetChars(options.budgetCharsOverride),
6807
+ used: 0
6808
+ },
6809
+ sessionKey,
6810
+ namespace: selfNamespace,
6811
+ traceId
6812
+ });
6813
+ } catch (err) {
6814
+ log.debug(`x-ray capture (no_recall) failed: ${err}`);
6815
+ }
6816
+ }
5865
6817
  if (sessionKey) {
5866
6818
  this.lastRecall.record({
5867
6819
  sessionKey,
@@ -7011,16 +7963,16 @@ ${formatted}`;
7011
7963
  if (!this.config.compactionResetEnabled) return null;
7012
7964
  const workspaceDir = compactionWorkspaceDir || this.config.workspaceDir || defaultWorkspaceDir();
7013
7965
  const safeSessionKey = sanitizeSessionKeyForFilename(effectiveSessionKey);
7014
- const signalPath = path5.join(
7966
+ const signalPath = path7.join(
7015
7967
  workspaceDir,
7016
7968
  `.compaction-reset-signal-${safeSessionKey}`
7017
7969
  );
7018
- const bootPath = path5.join(workspaceDir, "BOOT.md");
7970
+ const bootPath = path7.join(workspaceDir, "BOOT.md");
7019
7971
  try {
7020
7972
  const signalStat = await stat3(signalPath).catch(() => null);
7021
7973
  if (!signalStat) return null;
7022
7974
  const signalAge = Date.now() - signalStat.mtimeMs;
7023
- const signalData = JSON.parse(await readFile3(signalPath, "utf-8"));
7975
+ const signalData = JSON.parse(await readFile4(signalPath, "utf-8"));
7024
7976
  if (signalData.sessionKey !== effectiveSessionKey) {
7025
7977
  log.debug(
7026
7978
  `recall: compaction signal is for ${signalData.sessionKey}, not ${effectiveSessionKey} \u2014 skipping`
@@ -7040,7 +7992,7 @@ ${formatted}`;
7040
7992
 
7041
7993
  `;
7042
7994
  try {
7043
- const bootContent = await readFile3(bootPath, "utf-8");
7995
+ const bootContent = await readFile4(bootPath, "utf-8");
7044
7996
  section += "### BOOT.md (working state before compaction)\n\n";
7045
7997
  section += bootContent + "\n";
7046
7998
  } catch {
@@ -7747,7 +8699,18 @@ ${tmtNode.summary}`
7747
8699
  "rerankProvider=cloud is reserved/experimental in v2.2.0; skipping rerank"
7748
8700
  );
7749
8701
  }
8702
+ if (this.config.recallMemoryWorthFilterEnabled && memoryResults.length > 0) {
8703
+ try {
8704
+ memoryResults = await this.applyMemoryWorthRerank(memoryResults, recallNamespaces);
8705
+ } catch (err) {
8706
+ log.debug("memory-worth filter failed open", { error: err.message });
8707
+ }
8708
+ }
7750
8709
  const effectiveGateScore = preAugmentTopScore > 0 ? Math.max(preAugmentTopScore, maxSpecializedScore) : 0;
8710
+ xrayBranchPoolSize.hot_qmd = Math.max(
8711
+ xrayBranchPoolSize.hot_qmd,
8712
+ memoryResults.length
8713
+ );
7751
8714
  let confidenceGateRejected = false;
7752
8715
  if (this.config.recallConfidenceGateEnabled && effectiveGateScore > 0) {
7753
8716
  if (effectiveGateScore < this.config.recallConfidenceGateThreshold) {
@@ -7761,7 +8724,8 @@ ${tmtNode.summary}`
7761
8724
  memoryResults = this.diversifyAndLimitRecallResults(
7762
8725
  "memories",
7763
8726
  memoryResults,
7764
- recallResultLimit
8727
+ recallResultLimit,
8728
+ retrievalQuery
7765
8729
  );
7766
8730
  if (this.config.memoryReconstructionEnabled && memoryResults.length > 0) {
7767
8731
  try {
@@ -7846,10 +8810,15 @@ ${tmtNode.summary}`
7846
8810
  recallNamespaces,
7847
8811
  retrievalQuery
7848
8812
  );
8813
+ xrayBranchPoolSize.hot_embedding = Math.max(
8814
+ xrayBranchPoolSize.hot_embedding,
8815
+ boostedScoped.length
8816
+ );
7849
8817
  const scoped = this.diversifyAndLimitRecallResults(
7850
8818
  "memories",
7851
8819
  boostedScoped,
7852
- recallResultLimit
8820
+ recallResultLimit,
8821
+ retrievalQuery
7853
8822
  );
7854
8823
  if (scoped.length > 0) {
7855
8824
  if (shouldPersistGraphSnapshot) {
@@ -7882,7 +8851,8 @@ ${tmtNode.summary}`
7882
8851
  recallResultLimit,
7883
8852
  recallMode,
7884
8853
  queryAwarePrefilter,
7885
- abortSignal: options.abortSignal
8854
+ abortSignal: options.abortSignal,
8855
+ xrayPoolSizeSink: xrayColdPoolSink
7886
8856
  });
7887
8857
  if (longTerm.length > 0) {
7888
8858
  if (shouldPersistGraphSnapshot) {
@@ -7966,10 +8936,15 @@ ${tmtNode.summary}`
7966
8936
  recallNamespaces,
7967
8937
  retrievalQuery
7968
8938
  );
8939
+ xrayBranchPoolSize.hot_embedding = Math.max(
8940
+ xrayBranchPoolSize.hot_embedding,
8941
+ boostedScoped.length
8942
+ );
7969
8943
  const scoped = this.diversifyAndLimitRecallResults(
7970
8944
  "memories",
7971
8945
  boostedScoped,
7972
- recallResultLimit
8946
+ recallResultLimit,
8947
+ retrievalQuery
7973
8948
  );
7974
8949
  if (scoped.length > 0) {
7975
8950
  if (shouldPersistGraphSnapshot) {
@@ -8023,7 +8998,8 @@ ${tmtNode.summary}`
8023
8998
  recallResultLimit,
8024
8999
  recallMode,
8025
9000
  queryAwarePrefilter,
8026
- abortSignal: options.abortSignal
9001
+ abortSignal: options.abortSignal,
9002
+ xrayPoolSizeSink: xrayColdPoolSink
8027
9003
  });
8028
9004
  if (longTerm.length > 0) {
8029
9005
  recallSource = "cold_fallback";
@@ -8065,10 +9041,15 @@ ${tmtNode.summary}`
8065
9041
  retrievalQuery,
8066
9042
  preloadedMap
8067
9043
  )).sort((a, b) => b.score - a.score);
9044
+ xrayBranchPoolSize.recent_scan = Math.max(
9045
+ xrayBranchPoolSize.recent_scan,
9046
+ boostedRecent.length
9047
+ );
8068
9048
  const recent = this.diversifyAndLimitRecallResults(
8069
9049
  "memories",
8070
9050
  boostedRecent,
8071
- recallResultLimit
9051
+ recallResultLimit,
9052
+ retrievalQuery
8072
9053
  );
8073
9054
  if (recent.length > 0) {
8074
9055
  if (shouldPersistGraphSnapshot) {
@@ -8101,7 +9082,8 @@ ${tmtNode.summary}`
8101
9082
  recallResultLimit,
8102
9083
  recallMode,
8103
9084
  queryAwarePrefilter,
8104
- abortSignal: options.abortSignal
9085
+ abortSignal: options.abortSignal,
9086
+ xrayPoolSizeSink: xrayColdPoolSink
8105
9087
  });
8106
9088
  if (longTerm.length > 0) {
8107
9089
  if (shouldPersistGraphSnapshot) {
@@ -8137,7 +9119,8 @@ ${tmtNode.summary}`
8137
9119
  recallResultLimit,
8138
9120
  recallMode,
8139
9121
  queryAwarePrefilter,
8140
- abortSignal: options.abortSignal
9122
+ abortSignal: options.abortSignal,
9123
+ xrayPoolSizeSink: xrayColdPoolSink
8141
9124
  });
8142
9125
  if (longTerm.length > 0) {
8143
9126
  if (shouldPersistGraphSnapshot) {
@@ -8296,7 +9279,10 @@ _Context: ${topQuestion.context}_`
8296
9279
  );
8297
9280
  const timingParts = Object.entries(timings).map(([k, v]) => `${k}=${v}`).join(", ");
8298
9281
  log.info(`recall timings: ${timingParts}`);
8299
- const assembledRecall = this.assembleRecallSections(sectionBuckets);
9282
+ const assembledRecall = this.assembleRecallSections(
9283
+ sectionBuckets,
9284
+ options.budgetCharsOverride
9285
+ );
8300
9286
  const context = assembledRecall.sections.length === 0 ? "" : assembledRecall.sections.join("\n\n---\n\n");
8301
9287
  const sourcesUsed = this.collectLastRecallSources(
8302
9288
  sectionBuckets,
@@ -8312,6 +9298,73 @@ _Context: ${topQuestion.context}_`
8312
9298
  includedSections: assembledRecall.includedIds,
8313
9299
  omittedSections: assembledRecall.omittedIds
8314
9300
  });
9301
+ if (options.xrayCapture === true && !options.abortSignal?.aborted) {
9302
+ try {
9303
+ const servedBy = mapRecallSourceToXrayServedBy(recallSource);
9304
+ const idFromPath = (p) => {
9305
+ const match = p.match(/([^/]+)\.md$/);
9306
+ return match ? match[1] ?? null : null;
9307
+ };
9308
+ const results = [];
9309
+ for (const recalledPath of recalledMemoryPaths) {
9310
+ const derivedId = idFromPath(recalledPath);
9311
+ if (!derivedId) continue;
9312
+ results.push({
9313
+ memoryId: derivedId,
9314
+ path: recalledPath,
9315
+ servedBy,
9316
+ scoreDecomposition: { final: 0 },
9317
+ admittedBy: []
9318
+ });
9319
+ }
9320
+ let xrayConsidered;
9321
+ switch (recallSource) {
9322
+ case "hot_qmd":
9323
+ xrayConsidered = xrayBranchPoolSize.hot_qmd;
9324
+ break;
9325
+ case "hot_embedding":
9326
+ xrayConsidered = xrayBranchPoolSize.hot_embedding;
9327
+ break;
9328
+ case "cold_fallback":
9329
+ xrayConsidered = xrayColdPoolSink.size;
9330
+ break;
9331
+ case "recent_scan":
9332
+ xrayConsidered = xrayBranchPoolSize.recent_scan;
9333
+ break;
9334
+ case "none":
9335
+ xrayConsidered = recalledMemoryCount;
9336
+ break;
9337
+ default: {
9338
+ const _exhaustive = recallSource;
9339
+ void _exhaustive;
9340
+ xrayConsidered = recalledMemoryCount;
9341
+ }
9342
+ }
9343
+ xrayConsidered = Math.max(xrayConsidered, recalledMemoryIds.length);
9344
+ const filters = [
9345
+ {
9346
+ name: "recall-result-limit",
9347
+ considered: xrayConsidered,
9348
+ admitted: recalledMemoryIds.length
9349
+ }
9350
+ ];
9351
+ this.lastXraySnapshot = buildXraySnapshot({
9352
+ query: retrievalQuery,
9353
+ tierExplain: null,
9354
+ results,
9355
+ filters,
9356
+ budget: {
9357
+ chars: this.getRecallBudgetChars(options.budgetCharsOverride),
9358
+ used: assembledRecall.finalChars
9359
+ },
9360
+ sessionKey,
9361
+ namespace: selfNamespace,
9362
+ traceId
9363
+ });
9364
+ } catch (err) {
9365
+ log.debug(`x-ray capture failed: ${err}`);
9366
+ }
9367
+ }
8315
9368
  if (sessionKey) {
8316
9369
  throwIfRecallAborted(options.abortSignal);
8317
9370
  this.lastRecall.record({
@@ -8788,7 +9841,10 @@ ${normalized}`).digest("hex");
8788
9841
  return;
8789
9842
  }
8790
9843
  const principal = resolvePrincipal(sessionKey, this.config);
8791
- const selfNamespace = typeof options.writeNamespaceOverride === "string" && options.writeNamespaceOverride.length > 0 ? options.writeNamespaceOverride : defaultNamespaceForPrincipal(principal, this.config);
9844
+ const selfNamespace = typeof options.writeNamespaceOverride === "string" && options.writeNamespaceOverride.length > 0 ? options.writeNamespaceOverride : this.applyCodingNamespaceOverlay(
9845
+ sessionKey,
9846
+ defaultNamespaceForPrincipal(principal, this.config)
9847
+ );
8792
9848
  const storage = await this.storageRouter.storageFor(selfNamespace);
8793
9849
  const shouldPersistProcessedFingerprint = normalizedTurns.some(
8794
9850
  (turn) => turn.persistProcessedFingerprint === true
@@ -8881,6 +9937,24 @@ ${normalized}`).digest("hex");
8881
9937
  } catch (error) {
8882
9938
  postPersistMetaError = error;
8883
9939
  }
9940
+ try {
9941
+ if (clearBufferAfterExtraction && !this.config.extractionJudgeShadow) {
9942
+ const deferredCount = this.lastPersistExtractionDeferredCount;
9943
+ if (deferredCount > 0 && normalizedTurns.length > 0) {
9944
+ await this.buffer.retainDeferredTurns(
9945
+ bufferKey,
9946
+ normalizedTurns,
9947
+ 10
9948
+ );
9949
+ } else {
9950
+ await this.buffer.retainDeferredTurns(bufferKey, [], 0);
9951
+ }
9952
+ }
9953
+ } catch (err) {
9954
+ log.debug(
9955
+ `extraction-judge: defer retention failed (non-fatal): ${err instanceof Error ? err.message : String(err)}`
9956
+ );
9957
+ }
8884
9958
  await clearBuffer({ ignoreAbort: true });
8885
9959
  if (this.config.memoryBoxesEnabled && persistedIds.length > 0) {
8886
9960
  const extractionTopics = deriveTopicsFromExtraction(result);
@@ -9013,7 +10087,7 @@ ${normalized}`).digest("hex");
9013
10087
  );
9014
10088
  this.tierMigrationInFlight = true;
9015
10089
  try {
9016
- const coldStorage = new StorageManager(path5.join(storage.dir, "cold"));
10090
+ const coldStorage = new StorageManager(path7.join(storage.dir, "cold"));
9017
10091
  const [hotMemories, coldMemories] = await Promise.all([
9018
10092
  storage.readAllMemories(),
9019
10093
  coldStorage.readAllMemories()
@@ -9462,6 +10536,7 @@ ${normalized}`).digest("hex");
9462
10536
  }
9463
10537
  let judgeVerdictsByFactIndex = null;
9464
10538
  let judgeGatedCount = 0;
10539
+ this.lastPersistExtractionDeferredCount = 0;
9465
10540
  if (this.config.extractionJudgeEnabled) {
9466
10541
  try {
9467
10542
  const judgeCandidates = [];
@@ -9496,12 +10571,56 @@ ${normalized}`).digest("hex");
9496
10571
  });
9497
10572
  candidateToFactIndex.push(fi);
9498
10573
  }
10574
+ const judgeTelemetryOpts = {
10575
+ enabled: this.config.extractionJudgeTelemetryEnabled === true,
10576
+ memoryDir: this.config.memoryDir
10577
+ };
10578
+ const judgeTrainingOpts = {
10579
+ enabled: this.config.collectJudgeTrainingPairs === true,
10580
+ ...this.config.judgeTrainingDir ? { directory: this.config.judgeTrainingDir } : {}
10581
+ };
10582
+ const judgeTelemetryHandler = judgeTelemetryOpts.enabled || judgeTrainingOpts.enabled ? (obs) => {
10583
+ const ts = (/* @__PURE__ */ new Date()).toISOString();
10584
+ const verdictKind = getVerdictKind(obs.verdict);
10585
+ if (judgeTelemetryOpts.enabled) {
10586
+ const event = {
10587
+ version: 1,
10588
+ category: EXTRACTION_JUDGE_VERDICT_CATEGORY,
10589
+ ts,
10590
+ verdictKind,
10591
+ reason: obs.verdict.reason,
10592
+ deferrals: obs.priorDeferrals,
10593
+ elapsedMs: obs.elapsedMs,
10594
+ candidateCategory: obs.candidate.category,
10595
+ confidence: obs.candidate.confidence,
10596
+ contentHash: obs.contentHash,
10597
+ fromCache: obs.source === "cache",
10598
+ ...obs.source === "llm-cap-rejected" ? { deferCapTriggered: true } : {}
10599
+ };
10600
+ void recordJudgeVerdict(event, judgeTelemetryOpts);
10601
+ }
10602
+ if (judgeTrainingOpts.enabled) {
10603
+ const pair = {
10604
+ version: 1,
10605
+ ts,
10606
+ candidateText: obs.candidate.text,
10607
+ candidateCategory: obs.candidate.category,
10608
+ ...typeof obs.candidate.confidence === "number" ? { candidateConfidence: obs.candidate.confidence } : {},
10609
+ verdictKind,
10610
+ reason: obs.verdict.reason,
10611
+ priorDeferrals: obs.priorDeferrals
10612
+ };
10613
+ void recordJudgeTrainingPair(pair, judgeTrainingOpts);
10614
+ }
10615
+ } : void 0;
9499
10616
  const judgeResult = await judgeFactDurability(
9500
10617
  judgeCandidates,
9501
10618
  this.config,
9502
10619
  this.localLlm,
9503
10620
  new FallbackLlmClient(this.config.gatewayConfig),
9504
- this.judgeVerdictCache
10621
+ this.judgeVerdictCache,
10622
+ this.judgeDeferCounts,
10623
+ judgeTelemetryHandler
9505
10624
  );
9506
10625
  judgeVerdictsByFactIndex = /* @__PURE__ */ new Map();
9507
10626
  for (const [candidateIdx, verdict] of judgeResult.verdicts) {
@@ -9511,8 +10630,9 @@ ${normalized}`).digest("hex");
9511
10630
  }
9512
10631
  }
9513
10632
  log.info(
9514
- `extraction-judge: ${judgeResult.verdicts.size}/${judgeCandidates.length} facts evaluated, ${judgeResult.cached} cached, ${judgeResult.judged} judged, ${judgeResult.elapsed}ms`
10633
+ `extraction-judge: ${judgeResult.verdicts.size}/${judgeCandidates.length} facts evaluated, ${judgeResult.cached} cached, ${judgeResult.judged} judged, ${judgeResult.deferred} deferred` + (judgeResult.deferredCappedToReject > 0 ? ` (${judgeResult.deferredCappedToReject} cap-rejected)` : "") + `, ${judgeResult.elapsed}ms`
9515
10634
  );
10635
+ this.lastPersistExtractionDeferredCount = judgeResult.deferred;
9516
10636
  } catch (err) {
9517
10637
  log.warn(
9518
10638
  `extraction-judge: pipeline error, proceeding without filtering (fail-open): ${err instanceof Error ? err.message : String(err)}`
@@ -9587,10 +10707,17 @@ ${normalized}`).digest("hex");
9587
10707
  if (judgeVerdictsByFactIndex) {
9588
10708
  const verdict = judgeVerdictsByFactIndex.get(factLoopIndex);
9589
10709
  if (verdict && !verdict.durable) {
10710
+ const verdictKind = getVerdictKind(verdict);
9590
10711
  if (this.config.extractionJudgeShadow) {
9591
10712
  log.info(
9592
- `extraction-judge[shadow]: would reject "${fact.content.slice(0, 60)}\u2026" reason="${verdict.reason}"`
10713
+ `extraction-judge[shadow]: would ${verdictKind} "${fact.content.slice(0, 60)}\u2026" reason="${verdict.reason}"`
10714
+ );
10715
+ } else if (verdictKind === "defer") {
10716
+ judgeGatedCount++;
10717
+ log.debug(
10718
+ `extraction-judge: deferred "${fact.content.slice(0, 60)}\u2026" reason="${verdict.reason}"`
9593
10719
  );
10720
+ continue;
9594
10721
  } else {
9595
10722
  judgeGatedCount++;
9596
10723
  log.debug(
@@ -10133,7 +11260,7 @@ ${normalized}`).digest("hex");
10133
11260
  const allMems = allMemsForGraph ?? [];
10134
11261
  for (const m of allMems) {
10135
11262
  if (m.frontmatter.entityRef === entityRef) {
10136
- const rel = path5.relative(storage.dir, m.path);
11263
+ const rel = path7.relative(storage.dir, m.path);
10137
11264
  if (rel !== memoryRelPath) entitySiblings.push(rel);
10138
11265
  }
10139
11266
  }
@@ -10404,14 +11531,14 @@ ${normalized}`).digest("hex");
10404
11531
  }
10405
11532
  if (this.config.semanticConsolidationEnabled) {
10406
11533
  try {
10407
- const stateFilePath = path5.join(
11534
+ const stateFilePath = path7.join(
10408
11535
  this.config.memoryDir,
10409
11536
  "state",
10410
11537
  "semantic-consolidation-last-run.json"
10411
11538
  );
10412
11539
  let shouldRun = true;
10413
11540
  try {
10414
- const stateRaw = await readFile3(stateFilePath, "utf-8");
11541
+ const stateRaw = await readFile4(stateFilePath, "utf-8");
10415
11542
  const stateData = JSON.parse(stateRaw);
10416
11543
  if (stateData.lastRunAt) {
10417
11544
  const lastRunMs = new Date(stateData.lastRunAt).getTime();
@@ -10434,9 +11561,9 @@ ${normalized}`).digest("hex");
10434
11561
  allMemories = await this.storage.readAllMemories();
10435
11562
  }
10436
11563
  if (semResult.errors === 0 || semResult.memoriesArchived > 0) {
10437
- const stateDir = path5.join(this.config.memoryDir, "state");
10438
- await mkdir4(stateDir, { recursive: true });
10439
- await writeFile3(
11564
+ const stateDir = path7.join(this.config.memoryDir, "state");
11565
+ await mkdir5(stateDir, { recursive: true });
11566
+ await writeFile4(
10440
11567
  stateFilePath,
10441
11568
  JSON.stringify({ lastRunAt: (/* @__PURE__ */ new Date()).toISOString() }),
10442
11569
  "utf-8"
@@ -10908,13 +12035,13 @@ ${texts.map((t, i) => `[${i + 1}] ${t}`).join("\n\n")}`;
10908
12035
  protectedCategories: this.config.lifecycleProtectedCategories
10909
12036
  }
10910
12037
  };
10911
- const metricsPath = path5.join(
12038
+ const metricsPath = path7.join(
10912
12039
  this.storage.dir,
10913
12040
  "state",
10914
12041
  "lifecycle-metrics.json"
10915
12042
  );
10916
- await mkdir4(path5.dirname(metricsPath), { recursive: true });
10917
- await writeFile3(metricsPath, JSON.stringify(metrics, null, 2), "utf-8");
12043
+ await mkdir5(path7.dirname(metricsPath), { recursive: true });
12044
+ await writeFile4(metricsPath, JSON.stringify(metrics, null, 2), "utf-8");
10918
12045
  }
10919
12046
  /**
10920
12047
  * Archive old, low-importance, rarely-accessed facts (v6.0).
@@ -11417,11 +12544,97 @@ ${lines.join("\n\n")}`;
11417
12544
  *
11418
12545
  * Callers must pass the full candidate pool (post-rerank, pre-slice).
11419
12546
  */
11420
- diversifyAndLimitRecallResults(sectionId, results, limit) {
12547
+ async applyMemoryWorthRerank(results, namespaces) {
12548
+ const counters = /* @__PURE__ */ new Map();
12549
+ const seenNamespaces = /* @__PURE__ */ new Set();
12550
+ const nowMs = Date.now();
12551
+ for (const [key, entry] of this.memoryWorthCounterCache) {
12552
+ if (nowMs - entry.at >= _Orchestrator.MEMORY_WORTH_CACHE_TTL_MS) {
12553
+ this.memoryWorthCounterCache.delete(key);
12554
+ }
12555
+ }
12556
+ for (const ns of namespaces) {
12557
+ if (seenNamespaces.has(ns)) continue;
12558
+ seenNamespaces.add(ns);
12559
+ try {
12560
+ const cached = this.memoryWorthCounterCache.get(ns);
12561
+ let nsMap;
12562
+ if (cached && nowMs - cached.at < _Orchestrator.MEMORY_WORTH_CACHE_TTL_MS) {
12563
+ nsMap = cached.counters;
12564
+ } else {
12565
+ const storage = await this.getStorage(ns);
12566
+ const memories = await storage.readAllMemories();
12567
+ nsMap = buildMemoryWorthCounterMap(memories);
12568
+ this.memoryWorthCounterCache.set(ns, { at: nowMs, counters: nsMap });
12569
+ }
12570
+ for (const [path8, c] of nsMap) counters.set(path8, c);
12571
+ } catch (err) {
12572
+ log.debug("memory-worth: failed to read namespace, skipping", {
12573
+ namespace: ns,
12574
+ error: err.message
12575
+ });
12576
+ }
12577
+ }
12578
+ const missing = results.filter((r) => !counters.has(r.path));
12579
+ if (missing.length > 0) {
12580
+ let reader = null;
12581
+ for (const ns of namespaces) {
12582
+ try {
12583
+ reader = await this.getStorage(ns);
12584
+ break;
12585
+ } catch {
12586
+ }
12587
+ }
12588
+ if (reader) {
12589
+ for (const r of missing) {
12590
+ try {
12591
+ const memory = await reader.readMemoryByPath(r.path);
12592
+ if (!memory) continue;
12593
+ const fm = memory.frontmatter;
12594
+ if (fm.mw_success === void 0 && fm.mw_fail === void 0) continue;
12595
+ counters.set(r.path, {
12596
+ mw_success: fm.mw_success,
12597
+ mw_fail: fm.mw_fail,
12598
+ lastAccessed: fm.lastAccessed
12599
+ });
12600
+ } catch (err) {
12601
+ log.debug("memory-worth: direct path lookup failed", {
12602
+ path: r.path,
12603
+ error: err.message
12604
+ });
12605
+ }
12606
+ }
12607
+ }
12608
+ }
12609
+ if (counters.size === 0) return results;
12610
+ const rankedInputs = results.map((r, i) => ({
12611
+ path: r.path,
12612
+ // Large positive rank score so multiplier math stays well-scaled and
12613
+ // we never hit zero; descending so earlier items rank higher.
12614
+ score: results.length - i
12615
+ }));
12616
+ const filtered = applyMemoryWorthFilter(rankedInputs, {
12617
+ counters,
12618
+ now: /* @__PURE__ */ new Date(),
12619
+ halfLifeMs: this.config.recallMemoryWorthHalfLifeMs > 0 ? this.config.recallMemoryWorthHalfLifeMs : void 0
12620
+ });
12621
+ const byPath = new Map(results.map((r) => [r.path, r]));
12622
+ const reordered = [];
12623
+ for (const item of filtered) {
12624
+ const original = byPath.get(item.path);
12625
+ if (original) reordered.push(original);
12626
+ }
12627
+ return reordered;
12628
+ }
12629
+ diversifyAndLimitRecallResults(sectionId, results, limit, retrievalQuery) {
11421
12630
  const safeLimit = typeof limit === "number" && Number.isFinite(limit) ? Math.max(0, Math.floor(limit)) : 0;
11422
12631
  if (!Array.isArray(results) || results.length === 0) return [];
11423
12632
  if (safeLimit === 0) return [];
11424
- const diversified = this.applyMmrToQmdResults(sectionId, results);
12633
+ const boosted = this.config.recallReasoningTraceBoostEnabled && typeof retrievalQuery === "string" ? applyReasoningTraceBoost(results, {
12634
+ enabled: true,
12635
+ query: retrievalQuery
12636
+ }) : results;
12637
+ const diversified = this.applyMmrToQmdResults(sectionId, boosted);
11425
12638
  return diversified.slice(0, safeLimit);
11426
12639
  }
11427
12640
  /**
@@ -11525,12 +12738,12 @@ ${lines.join("\n\n")}`;
11525
12738
  */
11526
12739
  semanticDedupScopeFor(targetStorage) {
11527
12740
  if (!this.config.namespacesEnabled) return {};
11528
- const memoryDir = path5.resolve(this.config.memoryDir);
11529
- const storageDir = path5.resolve(targetStorage.dir);
12741
+ const memoryDir = path7.resolve(this.config.memoryDir);
12742
+ const storageDir = path7.resolve(targetStorage.dir);
11530
12743
  if (storageDir === memoryDir) {
11531
12744
  return { pathExcludePrefixes: ["namespaces/"] };
11532
12745
  }
11533
- let rel = path5.relative(memoryDir, storageDir);
12746
+ let rel = path7.relative(memoryDir, storageDir);
11534
12747
  if (!rel || rel.startsWith("..")) {
11535
12748
  log.debug(
11536
12749
  `semantic dedup: target storage dir ${storageDir} is outside memoryDir ${memoryDir}; scoping lookup to absolute path prefix`
@@ -11549,7 +12762,7 @@ ${lines.join("\n\n")}`;
11549
12762
  if (hits.length === 0) return [];
11550
12763
  const results = [];
11551
12764
  for (const hit of hits) {
11552
- const fullPath = path5.isAbsolute(hit.path) ? hit.path : path5.join(this.config.memoryDir, hit.path);
12765
+ const fullPath = path7.isAbsolute(hit.path) ? hit.path : path7.join(this.config.memoryDir, hit.path);
11553
12766
  const memory = await this.storage.readMemoryByPath(fullPath);
11554
12767
  if (!memory) continue;
11555
12768
  results.push({
@@ -11726,10 +12939,26 @@ ${lines.join("\n\n")}`;
11726
12939
  "rerankProvider=cloud is reserved/experimental in v2.2.0; skipping rerank"
11727
12940
  );
11728
12941
  }
12942
+ if (this.config.recallMemoryWorthFilterEnabled && results.length > 0) {
12943
+ try {
12944
+ results = await this.applyMemoryWorthRerank(results, options.recallNamespaces);
12945
+ } catch (err) {
12946
+ log.debug("memory-worth filter (cold) failed open", {
12947
+ error: err.message
12948
+ });
12949
+ }
12950
+ }
12951
+ if (options.xrayPoolSizeSink) {
12952
+ options.xrayPoolSizeSink.size = Math.max(
12953
+ options.xrayPoolSizeSink.size,
12954
+ results.length
12955
+ );
12956
+ }
11729
12957
  return this.diversifyAndLimitRecallResults(
11730
12958
  "memories",
11731
12959
  results,
11732
- options.recallResultLimit
12960
+ options.recallResultLimit,
12961
+ options.prompt
11733
12962
  );
11734
12963
  }
11735
12964
  // ---------------------------------------------------------------------------
@@ -12123,8 +13352,8 @@ ${lines.join("\n\n")}`;
12123
13352
  }
12124
13353
  namespaceFromStorageDir(storageDir) {
12125
13354
  if (!this.config.namespacesEnabled) return this.config.defaultNamespace;
12126
- const resolvedStorageDir = path5.resolve(storageDir);
12127
- const resolvedMemoryDir = path5.resolve(this.config.memoryDir);
13355
+ const resolvedStorageDir = path7.resolve(storageDir);
13356
+ const resolvedMemoryDir = path7.resolve(this.config.memoryDir);
12128
13357
  if (resolvedStorageDir === resolvedMemoryDir)
12129
13358
  return this.config.defaultNamespace;
12130
13359
  const m = resolvedStorageDir.match(/[\\/]namespaces[\\/]([^\\/]+)$/);
@@ -12157,6 +13386,21 @@ export {
12157
13386
  migrateFromEngram,
12158
13387
  buildProcedureRecallSection,
12159
13388
  decideSemanticDedup,
13389
+ DEFAULT_TAXONOMY,
13390
+ generateResolverDocument,
13391
+ validateSlug,
13392
+ validateTaxonomy,
13393
+ loadTaxonomy,
13394
+ saveTaxonomy,
13395
+ getTaxonomyDir,
13396
+ getTaxonomyFilePath,
13397
+ stableHash,
13398
+ normalizeOriginUrl,
13399
+ resolveGitContext,
13400
+ projectNamespaceName,
13401
+ branchNamespaceName,
13402
+ resolveCodingNamespaceOverlay,
13403
+ describeCodingScope,
12160
13404
  dedupeEntitySynthesisEvidenceEntries,
12161
13405
  defaultWorkspaceDir,
12162
13406
  sanitizeSessionKeyForFilename,
@@ -12185,4 +13429,4 @@ export {
12185
13429
  resolvePersistedMemoryRelativePath,
12186
13430
  Orchestrator
12187
13431
  };
12188
- //# sourceMappingURL=chunk-DEPL3635.js.map
13432
+ //# sourceMappingURL=chunk-VYM3VWOF.js.map