shieldcortex 4.28.1 → 4.29.0

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 (249) hide show
  1. package/dashboard/.next/standalone/dashboard/.next/BUILD_ID +1 -1
  2. package/dashboard/.next/standalone/dashboard/.next/build-manifest.json +2 -2
  3. package/dashboard/.next/standalone/dashboard/.next/prerender-manifest.json +3 -3
  4. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.html +2 -2
  5. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.rsc +1 -1
  6. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  7. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  8. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  9. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  10. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  11. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.html +2 -2
  12. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.rsc +1 -1
  13. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  14. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  15. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  16. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  17. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  18. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  19. package/dashboard/.next/standalone/dashboard/.next/server/app/admin.html +1 -1
  20. package/dashboard/.next/standalone/dashboard/.next/server/app/admin.rsc +1 -1
  21. package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/!KGRhc2hib2FyZCk/admin/__PAGE__.segment.rsc +1 -1
  22. package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/!KGRhc2hib2FyZCk/admin.segment.rsc +1 -1
  23. package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  24. package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/_full.segment.rsc +1 -1
  25. package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/_head.segment.rsc +1 -1
  26. package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/_index.segment.rsc +1 -1
  27. package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/_tree.segment.rsc +1 -1
  28. package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.html +1 -1
  29. package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.rsc +1 -1
  30. package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/!KGRhc2hib2FyZCk/cloud/__PAGE__.segment.rsc +1 -1
  31. package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/!KGRhc2hib2FyZCk/cloud.segment.rsc +1 -1
  32. package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  33. package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/_full.segment.rsc +1 -1
  34. package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/_head.segment.rsc +1 -1
  35. package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/_index.segment.rsc +1 -1
  36. package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/_tree.segment.rsc +1 -1
  37. package/dashboard/.next/standalone/dashboard/.next/server/app/index.html +1 -1
  38. package/dashboard/.next/standalone/dashboard/.next/server/app/index.rsc +1 -1
  39. package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  40. package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_full.segment.rsc +1 -1
  41. package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_head.segment.rsc +1 -1
  42. package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_index.segment.rsc +1 -1
  43. package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  44. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.html +1 -1
  45. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.rsc +1 -1
  46. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/!KGRhc2hib2FyZCk/memory/capture/__PAGE__.segment.rsc +1 -1
  47. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/!KGRhc2hib2FyZCk/memory/capture.segment.rsc +1 -1
  48. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
  49. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  50. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/_full.segment.rsc +1 -1
  51. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/_head.segment.rsc +1 -1
  52. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/_index.segment.rsc +1 -1
  53. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/_tree.segment.rsc +1 -1
  54. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.html +1 -1
  55. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.rsc +1 -1
  56. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/!KGRhc2hib2FyZCk/memory/graph/__PAGE__.segment.rsc +1 -1
  57. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/!KGRhc2hib2FyZCk/memory/graph.segment.rsc +1 -1
  58. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
  59. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  60. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/_full.segment.rsc +1 -1
  61. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/_head.segment.rsc +1 -1
  62. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/_index.segment.rsc +1 -1
  63. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/_tree.segment.rsc +1 -1
  64. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.html +1 -1
  65. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.rsc +1 -1
  66. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/!KGRhc2hib2FyZCk/memory/recall/__PAGE__.segment.rsc +1 -1
  67. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/!KGRhc2hib2FyZCk/memory/recall.segment.rsc +1 -1
  68. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
  69. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  70. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/_full.segment.rsc +1 -1
  71. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/_head.segment.rsc +1 -1
  72. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/_index.segment.rsc +1 -1
  73. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/_tree.segment.rsc +1 -1
  74. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.html +2 -2
  75. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.rsc +1 -1
  76. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/!KGRhc2hib2FyZCk/memory/replay/__PAGE__.segment.rsc +1 -1
  77. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/!KGRhc2hib2FyZCk/memory/replay.segment.rsc +1 -1
  78. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
  79. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  80. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/_full.segment.rsc +1 -1
  81. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/_head.segment.rsc +1 -1
  82. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/_index.segment.rsc +1 -1
  83. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/_tree.segment.rsc +1 -1
  84. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.html +1 -1
  85. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.rsc +1 -1
  86. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/!KGRhc2hib2FyZCk/memory/review/__PAGE__.segment.rsc +1 -1
  87. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/!KGRhc2hib2FyZCk/memory/review.segment.rsc +1 -1
  88. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
  89. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  90. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/_full.segment.rsc +1 -1
  91. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/_head.segment.rsc +1 -1
  92. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/_index.segment.rsc +1 -1
  93. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/_tree.segment.rsc +1 -1
  94. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.html +1 -1
  95. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.rsc +1 -1
  96. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/!KGRhc2hib2FyZCk/memory/timeline/__PAGE__.segment.rsc +1 -1
  97. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/!KGRhc2hib2FyZCk/memory/timeline.segment.rsc +1 -1
  98. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
  99. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  100. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/_full.segment.rsc +1 -1
  101. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/_head.segment.rsc +1 -1
  102. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/_index.segment.rsc +1 -1
  103. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/_tree.segment.rsc +1 -1
  104. package/dashboard/.next/standalone/dashboard/.next/server/app/memory.html +2 -2
  105. package/dashboard/.next/standalone/dashboard/.next/server/app/memory.rsc +1 -1
  106. package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/!KGRhc2hib2FyZCk/memory/__PAGE__.segment.rsc +1 -1
  107. package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
  108. package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  109. package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/_full.segment.rsc +1 -1
  110. package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/_head.segment.rsc +1 -1
  111. package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/_index.segment.rsc +1 -1
  112. package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/_tree.segment.rsc +1 -1
  113. package/dashboard/.next/standalone/dashboard/.next/server/app/overview.html +2 -2
  114. package/dashboard/.next/standalone/dashboard/.next/server/app/overview.rsc +1 -1
  115. package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/!KGRhc2hib2FyZCk/overview/__PAGE__.segment.rsc +1 -1
  116. package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/!KGRhc2hib2FyZCk/overview.segment.rsc +1 -1
  117. package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  118. package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/_full.segment.rsc +1 -1
  119. package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/_head.segment.rsc +1 -1
  120. package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/_index.segment.rsc +1 -1
  121. package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/_tree.segment.rsc +1 -1
  122. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.html +1 -1
  123. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.rsc +1 -1
  124. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/!KGRhc2hib2FyZCk/protection/audit/__PAGE__.segment.rsc +1 -1
  125. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/!KGRhc2hib2FyZCk/protection/audit.segment.rsc +1 -1
  126. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
  127. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  128. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/_full.segment.rsc +1 -1
  129. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/_head.segment.rsc +1 -1
  130. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/_index.segment.rsc +1 -1
  131. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/_tree.segment.rsc +1 -1
  132. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.html +1 -1
  133. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.rsc +1 -1
  134. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/!KGRhc2hib2FyZCk/protection/intercepts/__PAGE__.segment.rsc +1 -1
  135. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/!KGRhc2hib2FyZCk/protection/intercepts.segment.rsc +1 -1
  136. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
  137. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  138. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/_full.segment.rsc +1 -1
  139. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/_head.segment.rsc +1 -1
  140. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/_index.segment.rsc +1 -1
  141. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/_tree.segment.rsc +1 -1
  142. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.html +1 -1
  143. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.rsc +1 -1
  144. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/!KGRhc2hib2FyZCk/protection/iron-dome/__PAGE__.segment.rsc +1 -1
  145. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/!KGRhc2hib2FyZCk/protection/iron-dome.segment.rsc +1 -1
  146. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
  147. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  148. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/_full.segment.rsc +1 -1
  149. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/_head.segment.rsc +1 -1
  150. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/_index.segment.rsc +1 -1
  151. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/_tree.segment.rsc +1 -1
  152. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.html +1 -1
  153. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.rsc +1 -1
  154. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/!KGRhc2hib2FyZCk/protection/policies/__PAGE__.segment.rsc +1 -1
  155. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/!KGRhc2hib2FyZCk/protection/policies.segment.rsc +1 -1
  156. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
  157. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  158. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/_full.segment.rsc +1 -1
  159. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/_head.segment.rsc +1 -1
  160. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/_index.segment.rsc +1 -1
  161. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/_tree.segment.rsc +1 -1
  162. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.html +1 -1
  163. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.rsc +1 -1
  164. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/!KGRhc2hib2FyZCk/protection/quarantine/__PAGE__.segment.rsc +1 -1
  165. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/!KGRhc2hib2FyZCk/protection/quarantine.segment.rsc +1 -1
  166. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
  167. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  168. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/_full.segment.rsc +1 -1
  169. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/_head.segment.rsc +1 -1
  170. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/_index.segment.rsc +1 -1
  171. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/_tree.segment.rsc +1 -1
  172. package/dashboard/.next/standalone/dashboard/.next/server/app/protection.html +2 -2
  173. package/dashboard/.next/standalone/dashboard/.next/server/app/protection.rsc +1 -1
  174. package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/!KGRhc2hib2FyZCk/protection/__PAGE__.segment.rsc +1 -1
  175. package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
  176. package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  177. package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/_full.segment.rsc +1 -1
  178. package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/_head.segment.rsc +1 -1
  179. package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/_index.segment.rsc +1 -1
  180. package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/_tree.segment.rsc +1 -1
  181. package/dashboard/.next/standalone/dashboard/.next/server/app/settings.html +2 -2
  182. package/dashboard/.next/standalone/dashboard/.next/server/app/settings.rsc +1 -1
  183. package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/!KGRhc2hib2FyZCk/settings/__PAGE__.segment.rsc +1 -1
  184. package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/!KGRhc2hib2FyZCk/settings.segment.rsc +1 -1
  185. package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  186. package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/_full.segment.rsc +1 -1
  187. package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/_head.segment.rsc +1 -1
  188. package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/_index.segment.rsc +1 -1
  189. package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
  190. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.html +1 -1
  191. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.rsc +1 -1
  192. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/!KGRhc2hib2FyZCk/supply-chain/xray/__PAGE__.segment.rsc +1 -1
  193. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/!KGRhc2hib2FyZCk/supply-chain/xray.segment.rsc +1 -1
  194. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/!KGRhc2hib2FyZCk/supply-chain.segment.rsc +1 -1
  195. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  196. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/_full.segment.rsc +1 -1
  197. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/_head.segment.rsc +1 -1
  198. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/_index.segment.rsc +1 -1
  199. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/_tree.segment.rsc +1 -1
  200. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.html +1 -1
  201. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.rsc +1 -1
  202. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/!KGRhc2hib2FyZCk/supply-chain/__PAGE__.segment.rsc +1 -1
  203. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/!KGRhc2hib2FyZCk/supply-chain.segment.rsc +1 -1
  204. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  205. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/_full.segment.rsc +1 -1
  206. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/_head.segment.rsc +1 -1
  207. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/_index.segment.rsc +1 -1
  208. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/_tree.segment.rsc +1 -1
  209. package/dashboard/.next/standalone/dashboard/.next/server/app/xray.html +2 -2
  210. package/dashboard/.next/standalone/dashboard/.next/server/app/xray.rsc +1 -1
  211. package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/!KGRhc2hib2FyZCk/xray/__PAGE__.segment.rsc +1 -1
  212. package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/!KGRhc2hib2FyZCk/xray.segment.rsc +1 -1
  213. package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  214. package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/_full.segment.rsc +1 -1
  215. package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/_head.segment.rsc +1 -1
  216. package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/_index.segment.rsc +1 -1
  217. package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/_tree.segment.rsc +1 -1
  218. package/dashboard/.next/standalone/dashboard/.next/server/pages/404.html +2 -2
  219. package/dashboard/.next/standalone/dashboard/.next/server/pages/500.html +2 -2
  220. package/dashboard/.next/standalone/dashboard/.next/server/server-reference-manifest.js +1 -1
  221. package/dashboard/.next/standalone/dashboard/.next/server/server-reference-manifest.json +1 -1
  222. package/dist/cli/doctor.d.ts +17 -0
  223. package/dist/cli/doctor.js +44 -0
  224. package/dist/cli/memory.d.ts +23 -0
  225. package/dist/cli/memory.js +101 -0
  226. package/dist/database/init.d.ts +9 -0
  227. package/dist/database/init.js +32 -4
  228. package/dist/database/migrations.js +126 -0
  229. package/dist/memory/consolidate.d.ts +82 -6
  230. package/dist/memory/consolidate.js +287 -117
  231. package/dist/setup/openclaw.d.ts +26 -0
  232. package/dist/setup/openclaw.js +61 -0
  233. package/dist/tools/remember.js +24 -3
  234. package/hooks/openclaw/cortex-memory/handler.ts +223 -171
  235. package/hooks/openclaw/cortex-memory/runtime.mjs +64 -0
  236. package/package.json +1 -1
  237. package/scripts/lib/dedup.mjs +99 -0
  238. package/scripts/lib/openclaw-extract.mjs +129 -0
  239. package/scripts/lib/recall-log.mjs +16 -1
  240. package/scripts/lib/recall-relevance.mjs +191 -0
  241. package/scripts/lib/salience.mjs +8 -3
  242. package/scripts/lib/save-memory.mjs +62 -6
  243. package/scripts/lib/session-context.mjs +30 -0
  244. package/scripts/postinstall.mjs +29 -10
  245. package/scripts/prompt-recall-hook.mjs +118 -15
  246. package/scripts/session-start-hook.mjs +17 -6
  247. /package/dashboard/.next/standalone/dashboard/.next/static/{N9XiRuuRX4eTtiJFa43tY → 0HpUm8SRvm9fnWVO0OBB2}/_buildManifest.js +0 -0
  248. /package/dashboard/.next/standalone/dashboard/.next/static/{N9XiRuuRX4eTtiJFa43tY → 0HpUm8SRvm9fnWVO0OBB2}/_clientMiddlewareManifest.json +0 -0
  249. /package/dashboard/.next/standalone/dashboard/.next/static/{N9XiRuuRX4eTtiJFa43tY → 0HpUm8SRvm9fnWVO0OBB2}/_ssgManifest.js +0 -0
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Session-start context ordering helpers.
3
+ *
4
+ * The boot preamble used to order high-priority memories by raw
5
+ * `salience DESC, last_accessed DESC`. Because ~80% of rows sit at raw
6
+ * salience=1.0 (the "wall"), that ordering was an 80% tie and effectively
7
+ * random. Ranking by *effective* salience (recency × access × pin ×
8
+ * downvote_penalty — see scripts/lib/salience.mjs) lets fresh/relevant
9
+ * memories rank above stale 1.0 ones.
10
+ *
11
+ * Kept pure + side-effect-free so it's unit-testable without importing the
12
+ * hook entrypoint (which runs a stdin/process.exit IIFE at module load).
13
+ */
14
+
15
+ import { computeEffectiveSalience } from './salience.mjs';
16
+
17
+ /**
18
+ * Sort memories by effective salience, highest first. Returns a new array;
19
+ * the input is not mutated. `opts` is passed through to
20
+ * computeEffectiveSalience so tests can inject a deterministic `now`.
21
+ *
22
+ * @param {Array<object>} memories
23
+ * @param {object} [opts] - forwarded to computeEffectiveSalience (e.g. { now })
24
+ * @returns {Array<object>}
25
+ */
26
+ export function orderByEffectiveSalience(memories, opts = {}) {
27
+ return [...memories].sort(
28
+ (a, b) => computeEffectiveSalience(b, opts) - computeEffectiveSalience(a, opts),
29
+ );
30
+ }
@@ -174,21 +174,40 @@ if (isGlobal && !isCI) {
174
174
  console.warn('[shieldcortex] To manually install after confirming OpenClaw support:');
175
175
  console.warn('[shieldcortex] shieldcortex openclaw install --no-plugins');
176
176
  } else if (state.pluginInstalled) {
177
- // Bug #15: Plugin exists from a previous install auto-copy new files
177
+ // Bug #15 + Task 6b: a previous install left the plugin (and possibly the
178
+ // hook) on disk. Both are installed by file-copy, so a package bump
179
+ // leaves them stale until something re-copies them.
178
180
  console.log('');
179
- console.log('[shieldcortex] Existing plugin detected. Copying updated plugin files...');
180
- const copied = autoCopyPlugin(state.pluginDir, cliPath);
181
- if (copied) {
182
- console.log('[shieldcortex] Plugin files updated. Run full refresh for hook updates:');
183
- console.log('[shieldcortex] shieldcortex openclaw install');
184
- } else {
185
- // Fall back to full refresh
186
- console.log('[shieldcortex] Auto-copy failed. Running full OpenClaw refresh...');
181
+ if (state.hookInstalled) {
182
+ // Hook present → run the full refresh ONLY. `shieldcortex openclaw
183
+ // install` re-copies the hook (copyHookFiles) AND re-installs/registers
184
+ // the plugin in one idempotent pass, so a standalone autoCopyPlugin()
185
+ // here would copy the plugin a second time for no benefit. The full
186
+ // refresh is the single guarantee that keeps the file-copied hook from
187
+ // going stale on a plugin-present update.
188
+ console.log('[shieldcortex] Refreshing OpenClaw hook + plugin to latest version...');
187
189
  const ok = refreshOpenClawInstall(cliPath);
188
190
  if (!ok) {
189
- console.warn('[shieldcortex] ⚠ OpenClaw auto-refresh failed (non-fatal).');
191
+ console.warn('[shieldcortex] ⚠ OpenClaw hook + plugin refresh failed (non-fatal).');
190
192
  console.warn('[shieldcortex] Run manually: shieldcortex openclaw install');
191
193
  }
194
+ } else {
195
+ // Plugin-only (no hook) → just freshen the plugin files in place, with
196
+ // a full-refresh fallback if the in-place copy fails.
197
+ console.log('[shieldcortex] Existing plugin detected. Copying updated plugin files...');
198
+ const copied = autoCopyPlugin(state.pluginDir, cliPath);
199
+ if (copied) {
200
+ console.log('[shieldcortex] Plugin files updated.');
201
+ console.log('[shieldcortex] No hook installed. Run full setup for hook + memory:');
202
+ console.log('[shieldcortex] shieldcortex openclaw install');
203
+ } else {
204
+ console.warn('[shieldcortex] ⚠ Plugin auto-copy failed — running full refresh.');
205
+ const ok = refreshOpenClawInstall(cliPath);
206
+ if (!ok) {
207
+ console.warn('[shieldcortex] ⚠ OpenClaw auto-refresh failed (non-fatal).');
208
+ console.warn('[shieldcortex] Run manually: shieldcortex openclaw install');
209
+ }
210
+ }
192
211
  }
193
212
  } else if (state.hookInstalled) {
194
213
  // Hook exists but no plugin — run full refresh
@@ -22,6 +22,7 @@ import { truncatePreservingWords } from './lib/truncate.mjs';
22
22
  import { compareRecallResults } from './lib/recall-rank.mjs';
23
23
  import { computeEffectiveSalience } from './lib/salience.mjs';
24
24
  import { writeRecallLog } from './lib/recall-log.mjs';
25
+ import { filterByRelevance, extractQueryTerms } from './lib/recall-relevance.mjs';
25
26
 
26
27
  // ==================== CONFIG ====================
27
28
 
@@ -37,6 +38,47 @@ const MIN_SALIENCE = 0.2;
37
38
  const DEDUP_RING_SIZE = 5;
38
39
  const DEDUP_TTL_MS = 60 * 60 * 1000; // forget session rings after 1h idle
39
40
 
41
+ // ── P4 recall relevance gate (B9) ────────────────────────────────────────
42
+ // Term-coverage is the PRIMARY gate; relative BM25 floor is secondary. SHADOW
43
+ // MODE is the default: we compute the gate and LOG what it would drop, but
44
+ // inject the original set unchanged until SHIELDCORTEX_RECALL_ENFORCE=1. This
45
+ // lets us tune thresholds from real fleet recall-logs before trading recall
46
+ // noise for amnesia. All thresholds are env-tunable (pickNumber pattern,
47
+ // mirrors scripts/lib/salience.mjs).
48
+
49
+ // Resolve a numeric tuning constant from a SHIELDCORTEX_* env var, falling back
50
+ // to the documented default. Returns the default for a NaN/empty env var so a
51
+ // typo can't silently zero out a threshold. (Same contract as salience.mjs's
52
+ // pickNumber, minus the explicit-override arg — the hook has no overrides.)
53
+ function pickNumber(envName, fallback) {
54
+ const fromEnv = Number(process.env[envName]);
55
+ if (Number.isFinite(fromEnv) && process.env[envName] !== undefined && process.env[envName] !== '') {
56
+ return fromEnv;
57
+ }
58
+ return fallback;
59
+ }
60
+
61
+ // Truthy env flag: "1", "true", "yes", "on" (case-insensitive). Unset = false.
62
+ function pickBool(envName) {
63
+ const v = (process.env[envName] || '').trim().toLowerCase();
64
+ return v === '1' || v === 'true' || v === 'yes' || v === 'on';
65
+ }
66
+
67
+ const RECALL_ENFORCE = pickBool('SHIELDCORTEX_RECALL_ENFORCE');
68
+ const RECALL_MIN_TERMS = pickNumber('SHIELDCORTEX_RECALL_MIN_TERMS', 2);
69
+ const RECALL_REL_FACTOR = pickNumber('SHIELDCORTEX_RECALL_REL_FACTOR', 0.35);
70
+ // Absolute BM25 floor is OFF by default (null) — it has no safe default across
71
+ // corpus sizes: on a small/new FTS index real bm25 ranks are tiny (~-1e-6), so
72
+ // any fixed floor would drop even a perfect full-coverage match the moment an
73
+ // operator sets SHIELDCORTEX_RECALL_ENFORCE=1. The relative floor + term-
74
+ // coverage do the gating; tune the absolute floor from fleet recall-logs if a
75
+ // real corpus shows it's needed. Read the env only if present; absent → null.
76
+ const RECALL_MAX_BM25 =
77
+ process.env.SHIELDCORTEX_RECALL_MAX_BM25 !== undefined &&
78
+ process.env.SHIELDCORTEX_RECALL_MAX_BM25 !== ''
79
+ ? pickNumber('SHIELDCORTEX_RECALL_MAX_BM25', null)
80
+ : null;
81
+
40
82
  function loadConfig() {
41
83
  try {
42
84
  if (existsSync(CONFIG_PATH)) {
@@ -62,14 +104,14 @@ function getDbPath() {
62
104
 
63
105
  // ==================== FTS5 QUERY ====================
64
106
 
107
+ // Build the FTS5 MATCH expression from the same distinct terms the relevance
108
+ // gate scores against. extractQueryTerms (recall-relevance.mjs) is the single
109
+ // source of truth for "which words count" — strip FTS5 operators, drop boolean
110
+ // keywords, keep words longer than two chars, cap at six. Keeping both in sync
111
+ // is load-bearing: the gate must score the SAME terms the FTS query OR-joined.
65
112
  function escapeFts5(query) {
66
- return query
67
- .replace(/[*(){}[\]<>~^"]/g, ' ')
68
- .replace(/\b(AND|OR|NOT|NEAR)\b/gi, '')
69
- .split(/\s+/)
70
- .filter(w => w.length > 2)
71
- .map(w => `"${w}"`)
72
- .slice(0, 6)
113
+ return extractQueryTerms(query)
114
+ .map((w) => `"${w}"`)
73
115
  .join(' OR ');
74
116
  }
75
117
 
@@ -78,6 +120,7 @@ function escapeFts5(query) {
78
120
  function recallRelevant(db, project, prompt) {
79
121
  const results = [];
80
122
  const seen = new Set();
123
+ let ftsHits = 0;
81
124
 
82
125
  // 1. FTS5 text search
83
126
  const ftsQuery = escapeFts5(prompt);
@@ -110,6 +153,7 @@ function recallRelevant(db, project, prompt) {
110
153
  // it doesn't collide with any future SELECT column.
111
154
  row._source = 'fts';
112
155
  results.push(row);
156
+ ftsHits += 1;
113
157
  }
114
158
  }
115
159
  } catch {
@@ -124,7 +168,13 @@ function recallRelevant(db, project, prompt) {
124
168
  else if (/\b(deploy|release|publish|ship)\b/.test(promptLower)) categoryBoost = 'architecture';
125
169
  else if (/\b(prefer|style|convention|format)\b/.test(promptLower)) categoryBoost = 'preference';
126
170
 
127
- if (categoryBoost && results.length < MAX_RESULTS) {
171
+ // P4 (B9 item 6): only fire the category-boost fallback when the FTS path
172
+ // found at least one on-topic hit. The fallback has ZERO query relevance —
173
+ // it matches purely on category + salience — so firing it whenever the
174
+ // result set is short was a back-door for off-topic high-salience rows on a
175
+ // prompt that didn't match ANY memory. Requiring an FTS hit means the prompt
176
+ // is genuinely on-topic for this project before we top up from its category.
177
+ if (categoryBoost && ftsHits > 0 && results.length < MAX_RESULTS) {
128
178
  try {
129
179
  // v4.25.0: project the salience-formula inputs (same as the FTS
130
180
  // SELECT above) so compareRecallResults can compute effective
@@ -160,7 +210,16 @@ function recallRelevant(db, project, prompt) {
160
210
  // v4.25.1: return the full sorted set alongside the sliced top-N so the
161
211
  // recall ring buffer can log which candidates were considered but didn't
162
212
  // make the cut. The top-N is the existing public contract.
163
- return { topN: results.slice(0, MAX_RESULTS), fullSet: results };
213
+ //
214
+ // P4: also surface the distinct query terms (the same set escapeFts5 OR-
215
+ // joined) and the FTS hit count so the caller can run the relevance gate
216
+ // and the dedupe step against a consistent term list.
217
+ return {
218
+ topN: results.slice(0, MAX_RESULTS),
219
+ fullSet: results,
220
+ queryTerms: extractQueryTerms(prompt),
221
+ ftsHits,
222
+ };
164
223
  }
165
224
 
166
225
  // ==================== DEDUPE STATE ====================
@@ -213,13 +272,26 @@ function hashContent(s) {
213
272
 
214
273
  const RECALL_LOG_PROMPT_CAP = 200;
215
274
 
216
- function buildLogCandidates({ fullSet, topN, injected, dedupHashes }) {
275
+ function buildLogCandidates({ fullSet, topN, injected, dedupHashes, relevanceDrops }) {
217
276
  const injectedIds = new Set(injected.map((m) => m.id));
218
277
  const topNIds = new Set(topN.map((m) => m.id));
278
+ // P4: id → 'below_term_coverage' | 'below_relevance_floor'. Populated even
279
+ // in shadow mode (where these rows ARE still injected) so the recall-log
280
+ // surfaces "considered but below floor" to `shieldcortex inspect last-recall`
281
+ // for threshold tuning before enforcement. Map is empty when the gate found
282
+ // nothing to drop.
283
+ const relDrops = relevanceDrops instanceof Map ? relevanceDrops : new Map();
219
284
  return fullSet.map((row) => {
220
285
  const wasInjected = injectedIds.has(row.id);
221
286
  let dropReason = null;
222
- if (!wasInjected) {
287
+ // The relevance-gate reason takes precedence for a row it flagged: it's the
288
+ // most specific "why this is noise" signal, and in shadow mode it's the
289
+ // ONLY drop signal (the row is still injected, so the dedupe/top-N branches
290
+ // below wouldn't fire). When enforcing, a gate-dropped row is also not
291
+ // injected, so this is still the correct reason.
292
+ if (relDrops.has(row.id)) {
293
+ dropReason = relDrops.get(row.id);
294
+ } else if (!wasInjected) {
223
295
  if (topNIds.has(row.id) && dedupHashes.has(hashContent(row.content))) {
224
296
  dropReason = 'dedupe';
225
297
  } else if (!topNIds.has(row.id)) {
@@ -246,7 +318,7 @@ function buildLogCandidates({ fullSet, topN, injected, dedupHashes }) {
246
318
  });
247
319
  }
248
320
 
249
- function logRecallRun({ prompt, sessionId, project, fullSet, topN, injected, dedupHashes, context }) {
321
+ function logRecallRun({ prompt, sessionId, project, fullSet, topN, injected, dedupHashes, context, relevanceDrops }) {
250
322
  try {
251
323
  const promptCapped = prompt.length > RECALL_LOG_PROMPT_CAP
252
324
  ? prompt.slice(0, RECALL_LOG_PROMPT_CAP) + '…'
@@ -257,7 +329,7 @@ function logRecallRun({ prompt, sessionId, project, fullSet, topN, injected, ded
257
329
  sessionId: sessionId ?? null,
258
330
  project: project ?? null,
259
331
  minSalience: MIN_SALIENCE,
260
- candidates: buildLogCandidates({ fullSet, topN, injected, dedupHashes }),
332
+ candidates: buildLogCandidates({ fullSet, topN, injected, dedupHashes, relevanceDrops }),
261
333
  injectedCount: injected.length,
262
334
  finalContextChars: context ? context.length : 0,
263
335
  });
@@ -362,14 +434,42 @@ process.stdin.on('end', async () => {
362
434
  }
363
435
 
364
436
  const db = new Database(dbPath, { readonly: true, timeout: 2000 });
365
- const { topN, fullSet } = recallRelevant(db, project, prompt);
437
+ const { topN, fullSet, queryTerms } = recallRelevant(db, project, prompt);
366
438
  db.close();
367
- let memories = topN;
439
+
440
+ // ── P4 recall relevance gate (B9) ───────────────────────────────────
441
+ // Run the term-coverage + relative-BM25 gate over the would-be-injected
442
+ // top-N. SHADOW MODE (default): record the would-drops in the recall log
443
+ // but inject the ORIGINAL top-N unchanged. ENFORCE mode
444
+ // (SHIELDCORTEX_RECALL_ENFORCE=1): inject only the survivors. Either way
445
+ // the dropped rows STAY in fullSet so `inspect last-recall` shows them as
446
+ // "considered but below floor".
447
+ const { kept, dropped } = filterByRelevance(topN, {
448
+ queryTerms,
449
+ minTermMatches: RECALL_MIN_TERMS,
450
+ relFactor: RECALL_REL_FACTOR,
451
+ maxBm25: RECALL_MAX_BM25,
452
+ });
453
+ const relevanceDrops = new Map(dropped.map((d) => [d.row.id, d.reason]));
454
+ if (dropped.length > 0) {
455
+ // Visible in the hook's stderr diagnostics; the structured detail lands
456
+ // in the recall log via relevanceDrops.
457
+ console.error(
458
+ `[shieldcortex] Recall relevance gate (${RECALL_ENFORCE ? 'ENFORCE' : 'SHADOW'}): ` +
459
+ `${dropped.length}/${topN.length} would-drop ` +
460
+ `(${dropped.map((d) => `#${d.row.id}:${d.reason}`).join(', ')})`,
461
+ );
462
+ }
463
+ // SHADOW = inject original top-N; ENFORCE = inject only survivors.
464
+ let memories = RECALL_ENFORCE ? kept : topN;
368
465
 
369
466
  if (memories.length === 0) {
370
467
  // v4.25.1: still log no-candidate runs ONLY when the FTS step actually
371
468
  // ran (fullSet has something filtered out before the slice). Pure
372
469
  // empties (no FTS match at all) skip the log — saves disk + signal.
470
+ // P4: in ENFORCE mode the gate can empty the set (the "weather query →
471
+ // inject nothing" case) even though fullSet has rows — those are logged
472
+ // with their relevance dropReason. The empty-path logger still fires.
373
473
  if (fullSet.length > 0) {
374
474
  logRecallRun({
375
475
  prompt,
@@ -380,6 +480,7 @@ process.stdin.on('end', async () => {
380
480
  injected: [],
381
481
  dedupHashes: new Set(),
382
482
  context: null,
483
+ relevanceDrops,
383
484
  });
384
485
  }
385
486
  process.exit(0);
@@ -409,6 +510,7 @@ process.stdin.on('end', async () => {
409
510
  injected: [],
410
511
  dedupHashes,
411
512
  context: null,
513
+ relevanceDrops,
412
514
  });
413
515
  process.exit(0);
414
516
  }
@@ -455,6 +557,7 @@ process.stdin.on('end', async () => {
455
557
  injected: memories,
456
558
  dedupHashes,
457
559
  context,
560
+ relevanceDrops,
458
561
  });
459
562
 
460
563
  console.log(JSON.stringify(output));
@@ -24,6 +24,7 @@ import { join } from 'path';
24
24
  import { homedir } from 'os';
25
25
  import { deriveProjectKey } from './lib/project-key.mjs';
26
26
  import { truncatePreservingWords } from './lib/truncate.mjs';
27
+ import { orderByEffectiveSalience } from './lib/session-context.mjs';
27
28
 
28
29
  const NEW_DB_DIR = join(homedir(), '.shieldcortex');
29
30
  const LEGACY_DB_DIR = join(homedir(), '.claude-cortex');
@@ -84,19 +85,29 @@ You have access to a persistent memory system. Use it proactively:
84
85
  function getProjectContext(db, project) {
85
86
  const memories = [];
86
87
 
87
- const highPriority = db.prepare(`
88
- SELECT id, title, content, category, type, salience, tags, created_at
88
+ // Over-fetch a candidate pool (raw salience is a stable pre-filter), then
89
+ // rank by *effective* salience in JS and slice. Widening the SQL LIMIT past
90
+ // MAX gives the effective-salience sort room to promote a fresher/more-active
91
+ // row over a higher raw-salience one *within the candidate window* — it is a
92
+ // pragmatic widening, not a guarantee that every deep-tail row is reconsidered.
93
+ // The projected pinned/access_count/last_accessed/downvote_count columns feed
94
+ // computeEffectiveSalience.
95
+ const candidates = db.prepare(`
96
+ SELECT id, title, content, category, type, salience, tags, created_at,
97
+ pinned, access_count, last_accessed, COALESCE(downvote_count, 0) AS downvote_count
89
98
  FROM memories
90
99
  WHERE (project = ? OR project IS NULL)
91
100
  AND salience >= ?
92
101
  AND type IN ('long_term', 'episodic')
93
102
  ORDER BY salience DESC, last_accessed DESC
94
103
  LIMIT ?
95
- `).all(project, MIN_SALIENCE_THRESHOLD, MAX_CONTEXT_MEMORIES);
104
+ `).all(project, MIN_SALIENCE_THRESHOLD, MAX_CONTEXT_MEMORIES * 8);
96
105
 
97
- memories.push(...highPriority);
106
+ const ranked = orderByEffectiveSalience(candidates).slice(0, MAX_CONTEXT_MEMORIES);
98
107
 
99
- if (memories.length < 5) {
108
+ memories.push(...ranked);
109
+
110
+ if (memories.length < MAX_CONTEXT_MEMORIES) {
100
111
  const excludeIds = memories.map(m => m.id);
101
112
  const placeholders = excludeIds.length > 0 ? excludeIds.map(() => '?').join(',') : '0';
102
113
  const recent = db.prepare(`
@@ -106,7 +117,7 @@ function getProjectContext(db, project) {
106
117
  AND id NOT IN (${placeholders})
107
118
  ORDER BY created_at DESC
108
119
  LIMIT ?
109
- `).all(project, ...excludeIds, 5 - memories.length);
120
+ `).all(project, ...excludeIds, MAX_CONTEXT_MEMORIES - memories.length);
110
121
 
111
122
  memories.push(...recent);
112
123
  }