@remnic/core 9.69.63 → 9.69.65

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 (233) hide show
  1. package/dist/access-admin-ops-surface.js +24 -24
  2. package/dist/access-authorization-probe.js +25 -25
  3. package/dist/access-boundary.js +24 -24
  4. package/dist/access-cli.js +65 -65
  5. package/dist/access-extraction-force-flush.js +24 -24
  6. package/dist/access-http-briefing.js +25 -25
  7. package/dist/access-http-query.js +26 -26
  8. package/dist/access-http.js +41 -41
  9. package/dist/access-identity-continuity-surface.js +24 -24
  10. package/dist/access-lcm-surface.js +24 -24
  11. package/dist/access-mcp-output-schemas.d.ts.map +1 -1
  12. package/dist/access-mcp-output-schemas.js +1 -1
  13. package/dist/access-mcp.js +34 -34
  14. package/dist/access-namespace-preflight.js +24 -24
  15. package/dist/access-observe-write-surface.js +24 -24
  16. package/dist/access-operations-batch.js +25 -25
  17. package/dist/access-operations.js +32 -32
  18. package/dist/access-recall-concurrency.js +24 -24
  19. package/dist/access-recall-response.d.ts.map +1 -1
  20. package/dist/access-recall-response.js +24 -24
  21. package/dist/access-recall-surface.js +24 -24
  22. package/dist/access-service.d.ts +4 -0
  23. package/dist/access-service.d.ts.map +1 -1
  24. package/dist/access-service.js +24 -24
  25. package/dist/access-surface-catalog.js +26 -26
  26. package/dist/active-recall.js +9 -9
  27. package/dist/briefing.js +10 -10
  28. package/dist/buffer.js +5 -5
  29. package/dist/causal-consolidation.js +11 -11
  30. package/dist/{chunk-52VL6LCY.js → chunk-2VH2JWYN.js} +2 -2
  31. package/dist/{chunk-VXGB766B.js → chunk-2ZVSQPAA.js} +30 -14
  32. package/dist/chunk-2ZVSQPAA.js.map +1 -0
  33. package/dist/{chunk-G4WZDQ32.js → chunk-3NG5OOCX.js} +2 -2
  34. package/dist/{chunk-KG2OOAFF.js → chunk-3NTVCMDD.js} +2 -2
  35. package/dist/{chunk-7OC3Q5X4.js → chunk-3S4R2HA5.js} +2 -2
  36. package/dist/{chunk-RA3C46VX.js → chunk-4RWPQZYD.js} +2 -2
  37. package/dist/{chunk-B5GMOOY2.js → chunk-5AABWM72.js} +3 -3
  38. package/dist/{chunk-KRPMISWO.js → chunk-5C765XYU.js} +2 -2
  39. package/dist/{chunk-24TJ77TT.js → chunk-6YTL3JYX.js} +2 -2
  40. package/dist/{chunk-F4PEETM4.js → chunk-755VRFBS.js} +2 -2
  41. package/dist/{chunk-HNOKNHFO.js → chunk-7L747CFR.js} +2 -2
  42. package/dist/{chunk-WPGR3RW4.js → chunk-7VO6E5UD.js} +2 -2
  43. package/dist/{chunk-LMLPLIT4.js → chunk-AQ6IBVFQ.js} +2 -2
  44. package/dist/{chunk-LVGVXG22.js → chunk-B2JE56NB.js} +2 -2
  45. package/dist/{chunk-L4WBADKG.js → chunk-B5EZWPSM.js} +2 -2
  46. package/dist/{chunk-EIU642TN.js → chunk-BE4GMH45.js} +2 -2
  47. package/dist/{chunk-JTTLH646.js → chunk-C2W6JKQQ.js} +2 -2
  48. package/dist/{chunk-FG5QU7A2.js → chunk-CFCAFAJC.js} +2 -2
  49. package/dist/{chunk-WAR75CRY.js → chunk-CZM4MHZF.js} +34 -29
  50. package/dist/chunk-CZM4MHZF.js.map +1 -0
  51. package/dist/{chunk-LAEW4S43.js → chunk-DDY7LJMP.js} +2 -2
  52. package/dist/{chunk-4EEDRKRT.js → chunk-DT33WNG2.js} +4 -4
  53. package/dist/{chunk-SZAWZPY6.js → chunk-E7SKAUEW.js} +7 -7
  54. package/dist/{chunk-NRVGODSE.js → chunk-EK4MOTHM.js} +6 -6
  55. package/dist/{chunk-QEGKMZNQ.js → chunk-FO5NDQZH.js} +3 -3
  56. package/dist/chunk-G26YNEOC.js +37 -0
  57. package/dist/chunk-G26YNEOC.js.map +1 -0
  58. package/dist/{chunk-GMHWCPLP.js → chunk-GZLSIPYU.js} +2 -2
  59. package/dist/{chunk-ZFUPRODV.js → chunk-HPWJ5B7D.js} +39 -3
  60. package/dist/chunk-HPWJ5B7D.js.map +1 -0
  61. package/dist/{chunk-SEHKTE4F.js → chunk-I4IKTNZP.js} +3 -3
  62. package/dist/{chunk-W65KK3X6.js → chunk-II4TIQCU.js} +2 -2
  63. package/dist/{chunk-FWVDTLRK.js → chunk-IJQEVNEF.js} +1 -1
  64. package/dist/{chunk-KXJ7XYUT.js → chunk-IOUQUXHO.js} +2 -2
  65. package/dist/{chunk-V3JM4XEI.js → chunk-ITLFUILH.js} +2 -2
  66. package/dist/{chunk-W5UAB6EH.js → chunk-IULYVB5X.js} +5 -5
  67. package/dist/{chunk-Z3YQOV45.js → chunk-JLU7WK22.js} +2 -2
  68. package/dist/{chunk-NRTVZSPO.js → chunk-L4HT5QZ5.js} +2 -2
  69. package/dist/{chunk-5QZHDS4X.js → chunk-LI4IWBLN.js} +2 -2
  70. package/dist/{chunk-3MSMBVA3.js → chunk-LQ4OSM5V.js} +3 -3
  71. package/dist/{chunk-2OUSWDY6.js → chunk-M3TMVHQ2.js} +2 -2
  72. package/dist/{chunk-IDRSTHVR.js → chunk-MB3HMRXM.js} +2 -2
  73. package/dist/{chunk-PZEXA6CM.js → chunk-MUGLJAZ3.js} +2 -2
  74. package/dist/{chunk-ZOASYXBS.js → chunk-MY2PLXSM.js} +6 -2
  75. package/dist/chunk-MY2PLXSM.js.map +1 -0
  76. package/dist/{chunk-FEHVG4C4.js → chunk-NYN4ZMPL.js} +2 -2
  77. package/dist/{chunk-ZDZJ2PG4.js → chunk-O7QF3TCV.js} +17 -17
  78. package/dist/{chunk-KV44HTMJ.js → chunk-OBD77TYC.js} +2 -2
  79. package/dist/{chunk-GYNCJSQ7.js → chunk-OCEIHKH5.js} +3 -3
  80. package/dist/{chunk-FTNV5476.js → chunk-PSGRZFBH.js} +10 -10
  81. package/dist/{chunk-FQGY7XB2.js → chunk-S52VKUUW.js} +2 -2
  82. package/dist/{chunk-D7MAYFQP.js → chunk-S7LWX2PQ.js} +2 -2
  83. package/dist/{chunk-TYP7GYRI.js → chunk-SB4ZWVKI.js} +2 -2
  84. package/dist/{chunk-KVO2BTA4.js → chunk-T2YX56QI.js} +2 -2
  85. package/dist/{chunk-G6NQ3L4T.js → chunk-T3FMRLWQ.js} +2 -2
  86. package/dist/{chunk-CDQO5DCD.js → chunk-TO3G56GM.js} +2 -2
  87. package/dist/{chunk-WEQZ5OYK.js → chunk-U6GKPSZH.js} +2 -2
  88. package/dist/{chunk-FM5HN7LL.js → chunk-WQC54W25.js} +9 -17
  89. package/dist/chunk-WQC54W25.js.map +1 -0
  90. package/dist/{chunk-XDH5MO6L.js → chunk-WZ33AIOP.js} +2 -2
  91. package/dist/{chunk-U6HXB2OG.js → chunk-XDIFADVN.js} +2 -2
  92. package/dist/{chunk-SVWYZXIL.js → chunk-XDOXR3U6.js} +2 -2
  93. package/dist/{chunk-VKDWYDFQ.js → chunk-XGLBVYEA.js} +5 -5
  94. package/dist/{chunk-5Y7VCE3A.js → chunk-XJNSOI23.js} +2 -2
  95. package/dist/{chunk-LDP6LBDS.js → chunk-Y3AFTYK4.js} +2 -2
  96. package/dist/{chunk-TPRBJF46.js → chunk-YGJMMMPN.js} +2 -2
  97. package/dist/{chunk-WKNWC46C.js → chunk-YIDBKTZJ.js} +2 -2
  98. package/dist/{chunk-F5ZCNJ3V.js → chunk-ZPPWW576.js} +2 -2
  99. package/dist/{chunk-TQC6ELJO.js → chunk-ZSXSMVW6.js} +2 -2
  100. package/dist/{chunk-6RD7MSIO.js → chunk-ZUT4FK5W.js} +2 -2
  101. package/dist/cli.js +51 -51
  102. package/dist/coding/export-okf-codegraph.js +9 -9
  103. package/dist/compounding/engine.js +10 -10
  104. package/dist/config.js +9 -9
  105. package/dist/connectors/codex-materialize-runner.js +10 -10
  106. package/dist/connectors/index.js +10 -10
  107. package/dist/convergence-refresh.js +12 -12
  108. package/dist/corpus-watermark.js +12 -12
  109. package/dist/entity-retrieval.js +10 -10
  110. package/dist/external-wiki-access.js +25 -25
  111. package/dist/extraction.js +14 -14
  112. package/dist/harmonic-retrieval.js +1 -1
  113. package/dist/index.js +65 -65
  114. package/dist/location/index.js +12 -12
  115. package/dist/maintenance/memory-governance.js +10 -10
  116. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +10 -10
  117. package/dist/maintenance/rebuild-memory-projection.js +11 -11
  118. package/dist/memory-browse-operations.js +25 -25
  119. package/dist/memory-browse.js +5 -5
  120. package/dist/namespaces/migrate.js +11 -11
  121. package/dist/namespaces/search.js +8 -8
  122. package/dist/namespaces/storage.js +10 -10
  123. package/dist/operator-doctor-corpus.js +13 -13
  124. package/dist/operator-toolkit.js +18 -18
  125. package/dist/orchestration/maintenance.js +18 -18
  126. package/dist/orchestration/recall-internal.d.ts.map +1 -1
  127. package/dist/orchestrator.js +65 -65
  128. package/dist/qmd.js +2 -2
  129. package/dist/recall-composition-decision.d.ts +9 -0
  130. package/dist/recall-composition-decision.d.ts.map +1 -1
  131. package/dist/recall-composition-decision.js +2 -1
  132. package/dist/recall-navigation-operations.js +25 -25
  133. package/dist/recall-navigation.js +24 -24
  134. package/dist/recall-state-view-admission.js +5 -5
  135. package/dist/recall-why-service.d.ts.map +1 -1
  136. package/dist/recall-why-service.js +5 -5
  137. package/dist/resume-bundles.js +9 -9
  138. package/dist/search/factory.js +7 -7
  139. package/dist/search/index.js +7 -7
  140. package/dist/search/lancedb-backend.js +2 -2
  141. package/dist/search/meilisearch-backend.js +2 -2
  142. package/dist/search/orama-backend.js +2 -2
  143. package/dist/search/port.d.ts +9 -0
  144. package/dist/search/port.d.ts.map +1 -1
  145. package/dist/search/port.js +7 -1
  146. package/dist/search/remote-backend.js +2 -2
  147. package/dist/semantic-consolidation.js +11 -11
  148. package/dist/semantic-rule-promotion.js +10 -10
  149. package/dist/semantic-rule-verifier.js +10 -10
  150. package/dist/source-agent-qualifier.js +13 -13
  151. package/dist/standup/build.js +10 -10
  152. package/dist/storage.js +9 -9
  153. package/dist/support-passport/index.js +27 -27
  154. package/dist/transfer/export-okf.js +10 -10
  155. package/dist/verified-recall.js +10 -10
  156. package/dist/who-knows-cli.js +11 -11
  157. package/dist/who-knows.js +10 -10
  158. package/package.json +2 -2
  159. package/src/access-mcp-output-schemas.ts +4 -0
  160. package/src/access-recall-response.ts +26 -1
  161. package/src/access-service.ts +1 -0
  162. package/src/orchestration/recall-internal.ts +8 -5
  163. package/src/recall-composition-decision.test.ts +75 -0
  164. package/src/recall-composition-decision.ts +52 -3
  165. package/src/recall-retrieval-failure.test.ts +245 -0
  166. package/src/recall-why-service.ts +8 -24
  167. package/src/search/port.ts +32 -0
  168. package/dist/chunk-FM5HN7LL.js.map +0 -1
  169. package/dist/chunk-U2VDCFXW.js +0 -19
  170. package/dist/chunk-U2VDCFXW.js.map +0 -1
  171. package/dist/chunk-VXGB766B.js.map +0 -1
  172. package/dist/chunk-WAR75CRY.js.map +0 -1
  173. package/dist/chunk-ZFUPRODV.js.map +0 -1
  174. package/dist/chunk-ZOASYXBS.js.map +0 -1
  175. /package/dist/{chunk-52VL6LCY.js.map → chunk-2VH2JWYN.js.map} +0 -0
  176. /package/dist/{chunk-G4WZDQ32.js.map → chunk-3NG5OOCX.js.map} +0 -0
  177. /package/dist/{chunk-KG2OOAFF.js.map → chunk-3NTVCMDD.js.map} +0 -0
  178. /package/dist/{chunk-7OC3Q5X4.js.map → chunk-3S4R2HA5.js.map} +0 -0
  179. /package/dist/{chunk-RA3C46VX.js.map → chunk-4RWPQZYD.js.map} +0 -0
  180. /package/dist/{chunk-B5GMOOY2.js.map → chunk-5AABWM72.js.map} +0 -0
  181. /package/dist/{chunk-KRPMISWO.js.map → chunk-5C765XYU.js.map} +0 -0
  182. /package/dist/{chunk-24TJ77TT.js.map → chunk-6YTL3JYX.js.map} +0 -0
  183. /package/dist/{chunk-F4PEETM4.js.map → chunk-755VRFBS.js.map} +0 -0
  184. /package/dist/{chunk-HNOKNHFO.js.map → chunk-7L747CFR.js.map} +0 -0
  185. /package/dist/{chunk-WPGR3RW4.js.map → chunk-7VO6E5UD.js.map} +0 -0
  186. /package/dist/{chunk-LMLPLIT4.js.map → chunk-AQ6IBVFQ.js.map} +0 -0
  187. /package/dist/{chunk-LVGVXG22.js.map → chunk-B2JE56NB.js.map} +0 -0
  188. /package/dist/{chunk-L4WBADKG.js.map → chunk-B5EZWPSM.js.map} +0 -0
  189. /package/dist/{chunk-EIU642TN.js.map → chunk-BE4GMH45.js.map} +0 -0
  190. /package/dist/{chunk-JTTLH646.js.map → chunk-C2W6JKQQ.js.map} +0 -0
  191. /package/dist/{chunk-FG5QU7A2.js.map → chunk-CFCAFAJC.js.map} +0 -0
  192. /package/dist/{chunk-LAEW4S43.js.map → chunk-DDY7LJMP.js.map} +0 -0
  193. /package/dist/{chunk-4EEDRKRT.js.map → chunk-DT33WNG2.js.map} +0 -0
  194. /package/dist/{chunk-SZAWZPY6.js.map → chunk-E7SKAUEW.js.map} +0 -0
  195. /package/dist/{chunk-NRVGODSE.js.map → chunk-EK4MOTHM.js.map} +0 -0
  196. /package/dist/{chunk-QEGKMZNQ.js.map → chunk-FO5NDQZH.js.map} +0 -0
  197. /package/dist/{chunk-GMHWCPLP.js.map → chunk-GZLSIPYU.js.map} +0 -0
  198. /package/dist/{chunk-SEHKTE4F.js.map → chunk-I4IKTNZP.js.map} +0 -0
  199. /package/dist/{chunk-W65KK3X6.js.map → chunk-II4TIQCU.js.map} +0 -0
  200. /package/dist/{chunk-FWVDTLRK.js.map → chunk-IJQEVNEF.js.map} +0 -0
  201. /package/dist/{chunk-KXJ7XYUT.js.map → chunk-IOUQUXHO.js.map} +0 -0
  202. /package/dist/{chunk-V3JM4XEI.js.map → chunk-ITLFUILH.js.map} +0 -0
  203. /package/dist/{chunk-W5UAB6EH.js.map → chunk-IULYVB5X.js.map} +0 -0
  204. /package/dist/{chunk-Z3YQOV45.js.map → chunk-JLU7WK22.js.map} +0 -0
  205. /package/dist/{chunk-NRTVZSPO.js.map → chunk-L4HT5QZ5.js.map} +0 -0
  206. /package/dist/{chunk-5QZHDS4X.js.map → chunk-LI4IWBLN.js.map} +0 -0
  207. /package/dist/{chunk-3MSMBVA3.js.map → chunk-LQ4OSM5V.js.map} +0 -0
  208. /package/dist/{chunk-2OUSWDY6.js.map → chunk-M3TMVHQ2.js.map} +0 -0
  209. /package/dist/{chunk-IDRSTHVR.js.map → chunk-MB3HMRXM.js.map} +0 -0
  210. /package/dist/{chunk-PZEXA6CM.js.map → chunk-MUGLJAZ3.js.map} +0 -0
  211. /package/dist/{chunk-FEHVG4C4.js.map → chunk-NYN4ZMPL.js.map} +0 -0
  212. /package/dist/{chunk-ZDZJ2PG4.js.map → chunk-O7QF3TCV.js.map} +0 -0
  213. /package/dist/{chunk-KV44HTMJ.js.map → chunk-OBD77TYC.js.map} +0 -0
  214. /package/dist/{chunk-GYNCJSQ7.js.map → chunk-OCEIHKH5.js.map} +0 -0
  215. /package/dist/{chunk-FTNV5476.js.map → chunk-PSGRZFBH.js.map} +0 -0
  216. /package/dist/{chunk-FQGY7XB2.js.map → chunk-S52VKUUW.js.map} +0 -0
  217. /package/dist/{chunk-D7MAYFQP.js.map → chunk-S7LWX2PQ.js.map} +0 -0
  218. /package/dist/{chunk-TYP7GYRI.js.map → chunk-SB4ZWVKI.js.map} +0 -0
  219. /package/dist/{chunk-KVO2BTA4.js.map → chunk-T2YX56QI.js.map} +0 -0
  220. /package/dist/{chunk-G6NQ3L4T.js.map → chunk-T3FMRLWQ.js.map} +0 -0
  221. /package/dist/{chunk-CDQO5DCD.js.map → chunk-TO3G56GM.js.map} +0 -0
  222. /package/dist/{chunk-WEQZ5OYK.js.map → chunk-U6GKPSZH.js.map} +0 -0
  223. /package/dist/{chunk-XDH5MO6L.js.map → chunk-WZ33AIOP.js.map} +0 -0
  224. /package/dist/{chunk-U6HXB2OG.js.map → chunk-XDIFADVN.js.map} +0 -0
  225. /package/dist/{chunk-SVWYZXIL.js.map → chunk-XDOXR3U6.js.map} +0 -0
  226. /package/dist/{chunk-VKDWYDFQ.js.map → chunk-XGLBVYEA.js.map} +0 -0
  227. /package/dist/{chunk-5Y7VCE3A.js.map → chunk-XJNSOI23.js.map} +0 -0
  228. /package/dist/{chunk-LDP6LBDS.js.map → chunk-Y3AFTYK4.js.map} +0 -0
  229. /package/dist/{chunk-TPRBJF46.js.map → chunk-YGJMMMPN.js.map} +0 -0
  230. /package/dist/{chunk-WKNWC46C.js.map → chunk-YIDBKTZJ.js.map} +0 -0
  231. /package/dist/{chunk-F5ZCNJ3V.js.map → chunk-ZPPWW576.js.map} +0 -0
  232. /package/dist/{chunk-TQC6ELJO.js.map → chunk-ZSXSMVW6.js.map} +0 -0
  233. /package/dist/{chunk-6RD7MSIO.js.map → chunk-ZUT4FK5W.js.map} +0 -0
@@ -4,7 +4,7 @@ import {
4
4
  SUPPORT_PASSPORT_MODEL_RESULT_PATH,
5
5
  SupportPassportModelBridge,
6
6
  parseSupportPassportModelJob
7
- } from "../chunk-LAEW4S43.js";
7
+ } from "../chunk-DDY7LJMP.js";
8
8
  import {
9
9
  DEFAULT_SUPPORT_PASSPORT_CONFIG,
10
10
  parseSupportPassportConfig
@@ -14,8 +14,8 @@ import {
14
14
  buildSupportPassportPublicRequestHandler,
15
15
  composeSupportPassportExternalRequestHandlers,
16
16
  normalizeSupportPassportNetworkAddress
17
- } from "../chunk-LVGVXG22.js";
18
- import "../chunk-24TJ77TT.js";
17
+ } from "../chunk-B2JE56NB.js";
18
+ import "../chunk-6YTL3JYX.js";
19
19
  import {
20
20
  SUPPORT_PASSPORT_DRAFT_MAX_CONTENT_CHARACTERS,
21
21
  SUPPORT_PASSPORT_DRAFT_MAX_MEMORIES,
@@ -56,7 +56,7 @@ import {
56
56
  notifySupportPassportCommitted,
57
57
  resolveSupportPassportModelRoutePlan,
58
58
  syncDirectoryForDurability
59
- } from "../chunk-VXGB766B.js";
59
+ } from "../chunk-2ZVSQPAA.js";
60
60
  import "../chunk-W4F3C7N7.js";
61
61
  import "../chunk-MPC7TYTZ.js";
62
62
  import "../chunk-ZHXSOMYH.js";
@@ -64,7 +64,7 @@ import "../chunk-IFBSZGW3.js";
64
64
  import "../chunk-C3QXITIP.js";
65
65
  import "../chunk-VQ7B2Q6M.js";
66
66
  import "../chunk-OGXXGHW6.js";
67
- import "../chunk-HNOKNHFO.js";
67
+ import "../chunk-7L747CFR.js";
68
68
  import "../chunk-PJSK6OJM.js";
69
69
  import "../chunk-GNVZQ5JN.js";
70
70
  import "../chunk-YN2UN7N3.js";
@@ -74,7 +74,7 @@ import "../chunk-6DNMUYEE.js";
74
74
  import "../chunk-P5FPO2BR.js";
75
75
  import "../chunk-6ET2VII7.js";
76
76
  import "../chunk-S4DDLTPX.js";
77
- import "../chunk-FM5HN7LL.js";
77
+ import "../chunk-WQC54W25.js";
78
78
  import "../chunk-5UBH37SL.js";
79
79
  import "../chunk-5HFVWYHL.js";
80
80
  import "../chunk-KIW3OOZE.js";
@@ -87,17 +87,17 @@ import "../chunk-H7XKCNR6.js";
87
87
  import "../chunk-VEBYLZQQ.js";
88
88
  import "../chunk-SOBJ6NEY.js";
89
89
  import "../chunk-YR6A6ZK7.js";
90
- import "../chunk-KRPMISWO.js";
90
+ import "../chunk-5C765XYU.js";
91
91
  import "../chunk-E6UNM67F.js";
92
92
  import "../chunk-6WHJ2EAB.js";
93
93
  import "../chunk-AQEJKOKI.js";
94
94
  import "../chunk-HM7RHKS4.js";
95
95
  import "../chunk-UD7UNYRD.js";
96
96
  import "../chunk-IISBCCWR.js";
97
- import "../chunk-6RD7MSIO.js";
98
- import "../chunk-TYP7GYRI.js";
97
+ import "../chunk-ZUT4FK5W.js";
98
+ import "../chunk-SB4ZWVKI.js";
99
99
  import "../chunk-2YA5N2BY.js";
100
- import "../chunk-FWVDTLRK.js";
100
+ import "../chunk-IJQEVNEF.js";
101
101
  import "../chunk-SF6RFI5Z.js";
102
102
  import "../chunk-EI6V5UXY.js";
103
103
  import "../chunk-KKNZ7PUZ.js";
@@ -120,13 +120,13 @@ import "../chunk-WUUGE7QC.js";
120
120
  import "../chunk-HRATODNO.js";
121
121
  import "../chunk-WTWQA7BB.js";
122
122
  import "../chunk-VZIAVM72.js";
123
- import "../chunk-LMLPLIT4.js";
124
- import "../chunk-CDQO5DCD.js";
125
- import "../chunk-QEGKMZNQ.js";
126
- import "../chunk-G4WZDQ32.js";
123
+ import "../chunk-AQ6IBVFQ.js";
124
+ import "../chunk-TO3G56GM.js";
125
+ import "../chunk-FO5NDQZH.js";
126
+ import "../chunk-3NG5OOCX.js";
127
127
  import "../chunk-UFGFMWAD.js";
128
128
  import "../chunk-BMWN7B3Y.js";
129
- import "../chunk-WEQZ5OYK.js";
129
+ import "../chunk-U6GKPSZH.js";
130
130
  import "../chunk-3UXOZBHV.js";
131
131
  import "../chunk-PIWFNPQT.js";
132
132
  import "../chunk-GWK7FEUL.js";
@@ -135,15 +135,15 @@ import "../chunk-GKCXTSFF.js";
135
135
  import "../chunk-2LSZVONP.js";
136
136
  import "../chunk-DEUNUKTD.js";
137
137
  import "../chunk-LXY5VVGM.js";
138
- import "../chunk-FQGY7XB2.js";
139
- import "../chunk-52VL6LCY.js";
138
+ import "../chunk-S52VKUUW.js";
139
+ import "../chunk-2VH2JWYN.js";
140
140
  import "../chunk-CSAKJVXW.js";
141
141
  import "../chunk-K2XUWZBM.js";
142
142
  import "../chunk-OD4FM2U7.js";
143
143
  import "../chunk-ZY2MNJR6.js";
144
144
  import "../chunk-2QG4SLZI.js";
145
145
  import "../chunk-TBBDFYXW.js";
146
- import "../chunk-LDP6LBDS.js";
146
+ import "../chunk-Y3AFTYK4.js";
147
147
  import "../chunk-6JMQR72P.js";
148
148
  import "../chunk-TOTT6S2V.js";
149
149
  import "../chunk-QLK3SL7Q.js";
@@ -161,18 +161,18 @@ import "../chunk-236PXYG7.js";
161
161
  import "../chunk-ZCUTSMR2.js";
162
162
  import "../chunk-QDW3E4RD.js";
163
163
  import "../chunk-LMMQKZK3.js";
164
- import "../chunk-5QZHDS4X.js";
164
+ import "../chunk-LI4IWBLN.js";
165
165
  import "../chunk-46WM6JX2.js";
166
166
  import "../chunk-UHVXE24Y.js";
167
167
  import "../chunk-D5F7TKMH.js";
168
- import "../chunk-JTTLH646.js";
169
- import "../chunk-NRVGODSE.js";
170
- import "../chunk-WPGR3RW4.js";
168
+ import "../chunk-C2W6JKQQ.js";
169
+ import "../chunk-EK4MOTHM.js";
170
+ import "../chunk-7VO6E5UD.js";
171
171
  import "../chunk-Z4TXB4K7.js";
172
- import "../chunk-D7MAYFQP.js";
173
- import "../chunk-KVO2BTA4.js";
172
+ import "../chunk-S7LWX2PQ.js";
173
+ import "../chunk-T2YX56QI.js";
174
174
  import "../chunk-CYEPCZN5.js";
175
- import "../chunk-G6NQ3L4T.js";
175
+ import "../chunk-T3FMRLWQ.js";
176
176
  import "../chunk-4O6WRBGE.js";
177
177
  import "../chunk-GUMZC2BO.js";
178
178
  import "../chunk-TFA6HPOA.js";
@@ -202,8 +202,8 @@ import "../chunk-RBOJCG4T.js";
202
202
  import "../chunk-R7QY5ZVB.js";
203
203
  import "../chunk-5WITETWU.js";
204
204
  import "../chunk-6CIAGZ6X.js";
205
- import "../chunk-KG2OOAFF.js";
206
- import "../chunk-U2VDCFXW.js";
205
+ import "../chunk-3NTVCMDD.js";
206
+ import "../chunk-G26YNEOC.js";
207
207
  import "../chunk-ZLQ37WJX.js";
208
208
  import "../chunk-IUM3VSHI.js";
209
209
  import "../chunk-C64XATK7.js";
@@ -4,24 +4,24 @@ import {
4
4
  exportOkfBundle,
5
5
  firstHeading,
6
6
  parseIncludeStatus
7
- } from "../chunk-XDH5MO6L.js";
7
+ } from "../chunk-WZ33AIOP.js";
8
8
  import {
9
9
  OKF_EXPORT_VERSION
10
10
  } from "../chunk-UJX4I26O.js";
11
11
  import "../chunk-D24OXEPB.js";
12
12
  import "../chunk-3UXOZBHV.js";
13
- import "../chunk-5QZHDS4X.js";
13
+ import "../chunk-LI4IWBLN.js";
14
14
  import "../chunk-46WM6JX2.js";
15
15
  import "../chunk-UHVXE24Y.js";
16
16
  import "../chunk-D5F7TKMH.js";
17
- import "../chunk-JTTLH646.js";
18
- import "../chunk-NRVGODSE.js";
19
- import "../chunk-WPGR3RW4.js";
17
+ import "../chunk-C2W6JKQQ.js";
18
+ import "../chunk-EK4MOTHM.js";
19
+ import "../chunk-7VO6E5UD.js";
20
20
  import "../chunk-Z4TXB4K7.js";
21
- import "../chunk-D7MAYFQP.js";
22
- import "../chunk-KVO2BTA4.js";
21
+ import "../chunk-S7LWX2PQ.js";
22
+ import "../chunk-T2YX56QI.js";
23
23
  import "../chunk-CYEPCZN5.js";
24
- import "../chunk-G6NQ3L4T.js";
24
+ import "../chunk-T3FMRLWQ.js";
25
25
  import "../chunk-4O6WRBGE.js";
26
26
  import "../chunk-GUMZC2BO.js";
27
27
  import "../chunk-TFA6HPOA.js";
@@ -51,8 +51,8 @@ import "../chunk-RBOJCG4T.js";
51
51
  import "../chunk-R7QY5ZVB.js";
52
52
  import "../chunk-5WITETWU.js";
53
53
  import "../chunk-6CIAGZ6X.js";
54
- import "../chunk-KG2OOAFF.js";
55
- import "../chunk-U2VDCFXW.js";
54
+ import "../chunk-3NTVCMDD.js";
55
+ import "../chunk-G26YNEOC.js";
56
56
  import "../chunk-ZLQ37WJX.js";
57
57
  import "../chunk-IUM3VSHI.js";
58
58
  import "../chunk-C64XATK7.js";
@@ -1,20 +1,20 @@
1
1
  import {
2
2
  compareVerifiedEpisodeResults,
3
3
  searchVerifiedEpisodes
4
- } from "./chunk-NRTVZSPO.js";
4
+ } from "./chunk-L4HT5QZ5.js";
5
5
  import "./chunk-B7RWBZXW.js";
6
- import "./chunk-5QZHDS4X.js";
6
+ import "./chunk-LI4IWBLN.js";
7
7
  import "./chunk-46WM6JX2.js";
8
8
  import "./chunk-UHVXE24Y.js";
9
9
  import "./chunk-D5F7TKMH.js";
10
- import "./chunk-JTTLH646.js";
11
- import "./chunk-NRVGODSE.js";
12
- import "./chunk-WPGR3RW4.js";
10
+ import "./chunk-C2W6JKQQ.js";
11
+ import "./chunk-EK4MOTHM.js";
12
+ import "./chunk-7VO6E5UD.js";
13
13
  import "./chunk-Z4TXB4K7.js";
14
- import "./chunk-D7MAYFQP.js";
15
- import "./chunk-KVO2BTA4.js";
14
+ import "./chunk-S7LWX2PQ.js";
15
+ import "./chunk-T2YX56QI.js";
16
16
  import "./chunk-CYEPCZN5.js";
17
- import "./chunk-G6NQ3L4T.js";
17
+ import "./chunk-T3FMRLWQ.js";
18
18
  import "./chunk-4O6WRBGE.js";
19
19
  import "./chunk-GUMZC2BO.js";
20
20
  import "./chunk-TFA6HPOA.js";
@@ -44,8 +44,8 @@ import "./chunk-RBOJCG4T.js";
44
44
  import "./chunk-R7QY5ZVB.js";
45
45
  import "./chunk-5WITETWU.js";
46
46
  import "./chunk-6CIAGZ6X.js";
47
- import "./chunk-KG2OOAFF.js";
48
- import "./chunk-U2VDCFXW.js";
47
+ import "./chunk-3NTVCMDD.js";
48
+ import "./chunk-G26YNEOC.js";
49
49
  import "./chunk-ZLQ37WJX.js";
50
50
  import "./chunk-IUM3VSHI.js";
51
51
  import "./chunk-C64XATK7.js";
@@ -4,20 +4,20 @@ import {
4
4
  renderWhoKnows,
5
5
  renderWhoKnowsJson,
6
6
  renderWhoKnowsText
7
- } from "./chunk-KV44HTMJ.js";
8
- import "./chunk-HNOKNHFO.js";
9
- import "./chunk-5QZHDS4X.js";
7
+ } from "./chunk-OBD77TYC.js";
8
+ import "./chunk-7L747CFR.js";
9
+ import "./chunk-LI4IWBLN.js";
10
10
  import "./chunk-46WM6JX2.js";
11
11
  import "./chunk-UHVXE24Y.js";
12
12
  import "./chunk-D5F7TKMH.js";
13
- import "./chunk-JTTLH646.js";
14
- import "./chunk-NRVGODSE.js";
15
- import "./chunk-WPGR3RW4.js";
13
+ import "./chunk-C2W6JKQQ.js";
14
+ import "./chunk-EK4MOTHM.js";
15
+ import "./chunk-7VO6E5UD.js";
16
16
  import "./chunk-Z4TXB4K7.js";
17
- import "./chunk-D7MAYFQP.js";
18
- import "./chunk-KVO2BTA4.js";
17
+ import "./chunk-S7LWX2PQ.js";
18
+ import "./chunk-T2YX56QI.js";
19
19
  import "./chunk-CYEPCZN5.js";
20
- import "./chunk-G6NQ3L4T.js";
20
+ import "./chunk-T3FMRLWQ.js";
21
21
  import "./chunk-4O6WRBGE.js";
22
22
  import "./chunk-GUMZC2BO.js";
23
23
  import "./chunk-TFA6HPOA.js";
@@ -47,8 +47,8 @@ import "./chunk-RBOJCG4T.js";
47
47
  import "./chunk-R7QY5ZVB.js";
48
48
  import "./chunk-5WITETWU.js";
49
49
  import "./chunk-6CIAGZ6X.js";
50
- import "./chunk-KG2OOAFF.js";
51
- import "./chunk-U2VDCFXW.js";
50
+ import "./chunk-3NTVCMDD.js";
51
+ import "./chunk-G26YNEOC.js";
52
52
  import "./chunk-ZLQ37WJX.js";
53
53
  import "./chunk-IUM3VSHI.js";
54
54
  import "./chunk-C64XATK7.js";
package/dist/who-knows.js CHANGED
@@ -9,19 +9,19 @@ import {
9
9
  loadWhoKnowsEntities,
10
10
  tokenizeTopic,
11
11
  validateWhoKnowsInput
12
- } from "./chunk-HNOKNHFO.js";
13
- import "./chunk-5QZHDS4X.js";
12
+ } from "./chunk-7L747CFR.js";
13
+ import "./chunk-LI4IWBLN.js";
14
14
  import "./chunk-46WM6JX2.js";
15
15
  import "./chunk-UHVXE24Y.js";
16
16
  import "./chunk-D5F7TKMH.js";
17
- import "./chunk-JTTLH646.js";
18
- import "./chunk-NRVGODSE.js";
19
- import "./chunk-WPGR3RW4.js";
17
+ import "./chunk-C2W6JKQQ.js";
18
+ import "./chunk-EK4MOTHM.js";
19
+ import "./chunk-7VO6E5UD.js";
20
20
  import "./chunk-Z4TXB4K7.js";
21
- import "./chunk-D7MAYFQP.js";
22
- import "./chunk-KVO2BTA4.js";
21
+ import "./chunk-S7LWX2PQ.js";
22
+ import "./chunk-T2YX56QI.js";
23
23
  import "./chunk-CYEPCZN5.js";
24
- import "./chunk-G6NQ3L4T.js";
24
+ import "./chunk-T3FMRLWQ.js";
25
25
  import "./chunk-4O6WRBGE.js";
26
26
  import "./chunk-GUMZC2BO.js";
27
27
  import "./chunk-TFA6HPOA.js";
@@ -51,8 +51,8 @@ import "./chunk-RBOJCG4T.js";
51
51
  import "./chunk-R7QY5ZVB.js";
52
52
  import "./chunk-5WITETWU.js";
53
53
  import "./chunk-6CIAGZ6X.js";
54
- import "./chunk-KG2OOAFF.js";
55
- import "./chunk-U2VDCFXW.js";
54
+ import "./chunk-3NTVCMDD.js";
55
+ import "./chunk-G26YNEOC.js";
56
56
  import "./chunk-ZLQ37WJX.js";
57
57
  import "./chunk-IUM3VSHI.js";
58
58
  import "./chunk-C64XATK7.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remnic/core",
3
- "version": "9.69.63",
3
+ "version": "9.69.65",
4
4
  "description": "Framework-agnostic Remnic memory engine — orchestrator, storage, extraction, search, trust zones",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -3317,7 +3317,7 @@
3317
3317
  "core"
3318
3318
  ],
3319
3319
  "peerDependencies": {
3320
- "@remnic/coding-graph": "^9.69.63"
3320
+ "@remnic/coding-graph": "^9.69.65"
3321
3321
  },
3322
3322
  "peerDependenciesMeta": {
3323
3323
  "@remnic/coding-graph": {
@@ -102,6 +102,10 @@ const TOOL_OUTPUT_SCHEMAS: Readonly<Record<string, Record<string, unknown>>> = {
102
102
  results: T_ARRAY,
103
103
  fallbackUsed: T_BOOLEAN,
104
104
  sourcesUsed: T_ARRAY,
105
+ retrievalFailure: objectSchema({
106
+ reason: T_STRING,
107
+ detail: T_STRING,
108
+ }),
105
109
  }),
106
110
  recall_explain: objectSchema({
107
111
  found: T_BOOLEAN,
@@ -18,6 +18,7 @@ import type { RecallDisclosure, RecallPlanMode } from "./types.js";
18
18
  import { displaySafeRecallSnapshot } from "./orchestration/recall-result-formatter.js";
19
19
  import {
20
20
  boundRecallContextComposition,
21
+ composeMissingMemoryContext,
21
22
  composeRecallContext,
22
23
  type RecallContextComposition,
23
24
  } from "./recall-context-composition.js";
@@ -221,15 +222,30 @@ export async function assembleRecallResponse(
221
222
  const admittedIds = new Set(results.map((r) => r.id));
222
223
  const droppedAny = beforeIds.some((id) => !admittedIds.has(id));
223
224
  if (droppedAny) {
225
+ const priorDegradation = effectiveComposition.degradation;
224
226
  const filteredContext = results
225
227
  .map((result) => result.content || result.preview)
226
228
  .filter((s) => s.length > 0)
227
229
  .join("\n\n");
228
- effectiveComposition = boundRecallContextComposition({
230
+ const rebuilt = boundRecallContextComposition({
229
231
  context: filteredContext,
230
232
  footer: effectiveComposition.footer,
231
233
  maxChars: deps.orchestrator.config.recallBudgetChars,
232
234
  });
235
+ effectiveComposition =
236
+ priorDegradation?.reason === "backend-unavailable"
237
+ ? rebuilt.context.trim().length === 0
238
+ ? composeMissingMemoryContext({ detail: priorDegradation.detail })
239
+ : {
240
+ ...rebuilt,
241
+ degradation: {
242
+ state: "degraded" as const,
243
+ reason: "backend-unavailable" as const,
244
+ detail: priorDegradation.detail,
245
+ ...(rebuilt.degradation?.budget ? { budget: rebuilt.degradation.budget } : {}),
246
+ },
247
+ }
248
+ : rebuilt;
233
249
  effectiveContext = composeRecallContext(effectiveComposition);
234
250
  }
235
251
  }
@@ -290,6 +306,14 @@ export async function assembleRecallResponse(
290
306
  }
291
307
  }
292
308
 
309
+ const retrievalFailure =
310
+ effectiveComposition.degradation?.reason === "backend-unavailable"
311
+ ? {
312
+ reason: "backend_unavailable" as const,
313
+ detail: effectiveComposition.degradation.detail ?? "backend_unavailable",
314
+ }
315
+ : undefined;
316
+
293
317
  return {
294
318
  response: {
295
319
  query,
@@ -297,6 +321,7 @@ export async function assembleRecallResponse(
297
321
  namespace: effectiveNamespace,
298
322
  context: effectiveContext,
299
323
  contextComposition: effectiveComposition,
324
+ ...(retrievalFailure ? { retrievalFailure } : {}),
300
325
  count: filterTags && filterTags.length > 0
301
326
  ? results.length
302
327
  : (snapshot?.memoryIds.length ?? results.length),
@@ -445,6 +445,7 @@ export interface EngramAccessRecallResponse {
445
445
  context: string;
446
446
  /** Request-local split used by adapters that must re-render a tighter prompt budget. */
447
447
  contextComposition?: RecallContextComposition;
448
+ retrievalFailure?: { reason: "backend_unavailable"; detail: string };
448
449
  count: number;
449
450
  memoryIds: string[];
450
451
  results: EngramAccessMemorySummary[];
@@ -130,11 +130,9 @@ export class RecallInternalCoordinator {
130
130
  lifecycleCaps: MemoryLifecycleCapabilitySet = resolveMemoryLifecycleCapabilities(this.deps.config),
131
131
  ): Promise<string> {
132
132
  const recallStart = Date.now();
133
- // Backend degradations observed by this recall's QMD searches (#1536):
134
- // collected via the execution-options observer and attached to the
135
- // LastRecallSnapshot after it is recorded, so surfaces can distinguish
136
- // "no matches" from "backend could not answer" (CLAUDE.md rule 34).
137
- const backendDegradations: SearchDegradation[] = options.degradationSink ?? [];
133
+ // Per-recall QMD degradations (#1536/#3082). Local array so overlapping
134
+ // recalls that share a sink cannot mark each other failed.
135
+ const backendDegradations: SearchDegradation[] = [];
138
136
  // Issue #680 — historical recall. Parse `options.asOf` once at the
139
137
  // top of the recall so each boost-pass uses identical filter logic.
140
138
  // Invalid values are rejected at input boundaries (CLI / HTTP / MCP)
@@ -4964,7 +4962,12 @@ export class RecallInternalCoordinator {
4964
4962
  compactContext: compactRecallContextFromBuckets(sectionBuckets),
4965
4963
  footer: curiosityFooter,
4966
4964
  maxChars: recallBudgetChars,
4965
+ backendDegradations,
4966
+ qmdExpected: this.deps.config.searchBackend !== "noop" && (this.deps.config.searchBackend !== "qmd" || resolveQmdCapabilities(this.deps.config).qmd),
4967
4967
  });
4968
+ if (options.degradationSink) {
4969
+ for (const d of backendDegradations) options.degradationSink.push(d);
4970
+ }
4968
4971
  notifyContextComposition(options.onContextComposition, composition, (err) => {
4969
4972
  log.warn("recall: context composition observer failed open", err);
4970
4973
  });
@@ -30,6 +30,81 @@ test("#2972 empty recall stays marker-free", () => {
30
30
  assert.equal("degradation" in composition, false);
31
31
  });
32
32
 
33
+ test("#3082 empty context plus daemon_timeout is missing, not a genuine empty", () => {
34
+ const { composition, context } = decideRecallContextComposition({
35
+ context: "",
36
+ maxChars: 512,
37
+ backendDegradations: [{ backend: "qmd", code: "daemon_timeout", detail: "no response in 8000ms" }],
38
+ });
39
+
40
+ assert.equal(composition.degradation?.state, "missing");
41
+ assert.equal(composition.degradation?.reason, "backend-unavailable");
42
+ assert.match(composition.degradation?.detail ?? "", /qmd:daemon_timeout/);
43
+ assert.match(context, /memory context unavailable/i);
44
+ });
45
+
46
+ test("#3082 vector_tier_unavailable on empty context is not an outage", () => {
47
+ const { composition, context } = decideRecallContextComposition({
48
+ context: "",
49
+ maxChars: 512,
50
+ backendDegradations: [{ backend: "qmd", code: "vector_tier_unavailable" }],
51
+ });
52
+
53
+ assert.equal(context, "");
54
+ assert.equal("degradation" in composition, false);
55
+ });
56
+
57
+ test("#3082 daemon_timeout with recalled context keeps results and marks degraded", () => {
58
+ const { composition, truncated } = decideRecallContextComposition({
59
+ context: "A remembered deployment decision.",
60
+ maxChars: 512,
61
+ backendDegradations: [{ backend: "qmd", code: "daemon_timeout", detail: "cold-tier timed out" }],
62
+ });
63
+
64
+ assert.equal(composition.context, "A remembered deployment decision.");
65
+ assert.equal(composition.degradation?.state, "degraded");
66
+ assert.equal(composition.degradation?.reason, "backend-unavailable");
67
+ assert.equal(truncated, false);
68
+ });
69
+
70
+ test("#3082 QMD-disabled backend_unavailable is not an outage", () => {
71
+ const { composition, context } = decideRecallContextComposition({
72
+ context: "",
73
+ maxChars: 512,
74
+ qmdExpected: false,
75
+ backendDegradations: [{ backend: "qmd", code: "backend_unavailable", detail: "qmd disabled" }],
76
+ });
77
+
78
+ assert.equal(context, "");
79
+ assert.equal("degradation" in composition, false);
80
+ });
81
+
82
+ test("#3082 non-QMD backend_unavailable is still an outage when QMD is off", () => {
83
+ const { composition, context } = decideRecallContextComposition({
84
+ context: "",
85
+ maxChars: 512,
86
+ qmdExpected: false,
87
+ backendDegradations: [{ backend: "remote", code: "backend_unavailable" }],
88
+ });
89
+
90
+ assert.equal(composition.degradation?.state, "missing");
91
+ assert.equal(composition.degradation?.reason, "backend-unavailable");
92
+ assert.match(context, /memory context unavailable/i);
93
+ });
94
+ test("#3082 timeout plus budget clip still reports backend-unavailable", () => {
95
+ const longContext = "A remembered deployment decision. ".repeat(40).trim();
96
+ const { composition, truncated } = decideRecallContextComposition({
97
+ context: longContext,
98
+ maxChars: 80,
99
+ backendDegradations: [{ backend: "qmd", code: "daemon_timeout", detail: "no response in 8000ms" }],
100
+ });
101
+
102
+ assert.equal(composition.degradation?.reason, "backend-unavailable");
103
+ assert.match(composition.degradation?.detail ?? "", /qmd:daemon_timeout/);
104
+ assert.ok(composition.degradation?.budget, "budget accounting stays on the overlay");
105
+ assert.equal(truncated, true);
106
+ });
107
+
33
108
  test("#2972 compact form from section buckets is preferred over clipping", () => {
34
109
  const longOne = "full-form entry one with a long body ".repeat(6).trim();
35
110
  const longTwo = "full-form entry two with a long body ".repeat(6).trim();
@@ -15,6 +15,11 @@ import {
15
15
  RECALL_CONTEXT_SEPARATOR,
16
16
  type RecallContextComposition,
17
17
  } from "./recall-context-composition.js";
18
+ import {
19
+ describeSearchDegradations,
20
+ fatalSearchDegradations,
21
+ type SearchDegradation,
22
+ } from "./search/port.js";
18
23
 
19
24
  export type RecallCompositionChunk = string | { readonly content: string };
20
25
 
@@ -23,6 +28,14 @@ export interface DecideRecallContextCompositionInput {
23
28
  compactContext?: string;
24
29
  footer?: string;
25
30
  maxChars: number;
31
+ /** Mid-recall backend degradations (#3082). Absent on the healthy path. */
32
+ backendDegradations?: readonly SearchDegradation[];
33
+ /**
34
+ * When false, `{ backend: "qmd", code: "backend_unavailable" }` is the
35
+ * QMD-disabled/noop skip marker, not an outage. Other backends still count.
36
+ * Default true so unit tests that pass degradations stay honest.
37
+ */
38
+ qmdExpected?: boolean;
26
39
  }
27
40
 
28
41
  export interface DecidedRecallContextComposition {
@@ -65,18 +78,54 @@ export function compactRecallContextFromBuckets(
65
78
  export function decideRecallContextComposition(
66
79
  input: DecideRecallContextCompositionInput,
67
80
  ): DecidedRecallContextComposition {
68
- const composition = boundRecallContextComposition({
81
+ const observed = input.backendDegradations ?? [];
82
+ const qmdExpected = input.qmdExpected !== false;
83
+ const fatal = fatalSearchDegradations(observed).filter(
84
+ (d) => qmdExpected || d.backend !== "qmd" || d.code !== "backend_unavailable",
85
+ );
86
+ if (fatal.length > 0 && input.context.trim().length === 0) {
87
+ const missing = composeMissingMemoryContext({
88
+ detail: describeSearchDegradations(fatal),
89
+ });
90
+ const composition = input.footer
91
+ ? { ...missing, footer: input.footer }
92
+ : missing;
93
+ return {
94
+ composition,
95
+ context: composeRecallContext(composition),
96
+ truncated: false,
97
+ };
98
+ }
99
+ const bounded = boundRecallContextComposition({
69
100
  context: input.context,
70
101
  footer: input.footer,
71
102
  maxChars: input.maxChars,
72
103
  compactContext: input.compactContext,
73
104
  });
105
+ if (fatal.length === 0) {
106
+ return {
107
+ composition: bounded,
108
+ context: composeRecallContext(bounded),
109
+ truncated:
110
+ bounded.degradation?.reason === "budget-clipped" ||
111
+ bounded.degradation?.reason === "budget-compacted",
112
+ };
113
+ }
114
+ const composition = {
115
+ ...bounded,
116
+ degradation: {
117
+ state: "degraded" as const,
118
+ reason: "backend-unavailable" as const,
119
+ detail: describeSearchDegradations(fatal),
120
+ ...(bounded.degradation?.budget ? { budget: bounded.degradation.budget } : {}),
121
+ },
122
+ };
74
123
  return {
75
124
  composition,
76
125
  context: composeRecallContext(composition),
77
126
  truncated:
78
- composition.degradation?.reason === "budget-clipped" ||
79
- composition.degradation?.reason === "budget-compacted",
127
+ bounded.degradation?.reason === "budget-clipped" ||
128
+ bounded.degradation?.reason === "budget-compacted",
80
129
  };
81
130
  }
82
131