shieldcortex 4.35.0 → 4.37.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 (244) 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/server/app/_global-error.html +2 -2
  4. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.rsc +1 -1
  5. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  6. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  7. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  8. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  9. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  10. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.html +1 -1
  11. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.rsc +1 -1
  12. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  13. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  14. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  15. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  16. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  17. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  18. package/dashboard/.next/standalone/dashboard/.next/server/app/admin.html +1 -1
  19. package/dashboard/.next/standalone/dashboard/.next/server/app/admin.rsc +1 -1
  20. package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/!KGRhc2hib2FyZCk/admin/__PAGE__.segment.rsc +1 -1
  21. package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/!KGRhc2hib2FyZCk/admin.segment.rsc +1 -1
  22. package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  23. package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/_full.segment.rsc +1 -1
  24. package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/_head.segment.rsc +1 -1
  25. package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/_index.segment.rsc +1 -1
  26. package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/_tree.segment.rsc +1 -1
  27. package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.html +1 -1
  28. package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.rsc +1 -1
  29. package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/!KGRhc2hib2FyZCk/cloud/__PAGE__.segment.rsc +1 -1
  30. package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/!KGRhc2hib2FyZCk/cloud.segment.rsc +1 -1
  31. package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  32. package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/_full.segment.rsc +1 -1
  33. package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/_head.segment.rsc +1 -1
  34. package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/_index.segment.rsc +1 -1
  35. package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/_tree.segment.rsc +1 -1
  36. package/dashboard/.next/standalone/dashboard/.next/server/app/index.html +1 -1
  37. package/dashboard/.next/standalone/dashboard/.next/server/app/index.rsc +1 -1
  38. package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  39. package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_full.segment.rsc +1 -1
  40. package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_head.segment.rsc +1 -1
  41. package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_index.segment.rsc +1 -1
  42. package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  43. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.html +1 -1
  44. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.rsc +1 -1
  45. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/!KGRhc2hib2FyZCk/memory/capture/__PAGE__.segment.rsc +1 -1
  46. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/!KGRhc2hib2FyZCk/memory/capture.segment.rsc +1 -1
  47. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
  48. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  49. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/_full.segment.rsc +1 -1
  50. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/_head.segment.rsc +1 -1
  51. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/_index.segment.rsc +1 -1
  52. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/_tree.segment.rsc +1 -1
  53. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.html +1 -1
  54. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.rsc +1 -1
  55. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/!KGRhc2hib2FyZCk/memory/graph/__PAGE__.segment.rsc +1 -1
  56. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/!KGRhc2hib2FyZCk/memory/graph.segment.rsc +1 -1
  57. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
  58. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  59. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/_full.segment.rsc +1 -1
  60. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/_head.segment.rsc +1 -1
  61. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/_index.segment.rsc +1 -1
  62. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/_tree.segment.rsc +1 -1
  63. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.html +1 -1
  64. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.rsc +1 -1
  65. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/!KGRhc2hib2FyZCk/memory/recall/__PAGE__.segment.rsc +1 -1
  66. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/!KGRhc2hib2FyZCk/memory/recall.segment.rsc +1 -1
  67. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
  68. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  69. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/_full.segment.rsc +1 -1
  70. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/_head.segment.rsc +1 -1
  71. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/_index.segment.rsc +1 -1
  72. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/_tree.segment.rsc +1 -1
  73. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.html +1 -1
  74. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.rsc +1 -1
  75. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/!KGRhc2hib2FyZCk/memory/replay/__PAGE__.segment.rsc +1 -1
  76. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/!KGRhc2hib2FyZCk/memory/replay.segment.rsc +1 -1
  77. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
  78. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  79. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/_full.segment.rsc +1 -1
  80. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/_head.segment.rsc +1 -1
  81. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/_index.segment.rsc +1 -1
  82. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/_tree.segment.rsc +1 -1
  83. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.html +1 -1
  84. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.rsc +1 -1
  85. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/!KGRhc2hib2FyZCk/memory/review/__PAGE__.segment.rsc +1 -1
  86. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/!KGRhc2hib2FyZCk/memory/review.segment.rsc +1 -1
  87. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
  88. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  89. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/_full.segment.rsc +1 -1
  90. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/_head.segment.rsc +1 -1
  91. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/_index.segment.rsc +1 -1
  92. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/_tree.segment.rsc +1 -1
  93. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.html +1 -1
  94. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.rsc +1 -1
  95. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/!KGRhc2hib2FyZCk/memory/timeline/__PAGE__.segment.rsc +1 -1
  96. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/!KGRhc2hib2FyZCk/memory/timeline.segment.rsc +1 -1
  97. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
  98. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  99. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/_full.segment.rsc +1 -1
  100. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/_head.segment.rsc +1 -1
  101. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/_index.segment.rsc +1 -1
  102. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/_tree.segment.rsc +1 -1
  103. package/dashboard/.next/standalone/dashboard/.next/server/app/memory.html +1 -1
  104. package/dashboard/.next/standalone/dashboard/.next/server/app/memory.rsc +1 -1
  105. package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/!KGRhc2hib2FyZCk/memory/__PAGE__.segment.rsc +1 -1
  106. package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
  107. package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  108. package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/_full.segment.rsc +1 -1
  109. package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/_head.segment.rsc +1 -1
  110. package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/_index.segment.rsc +1 -1
  111. package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/_tree.segment.rsc +1 -1
  112. package/dashboard/.next/standalone/dashboard/.next/server/app/overview.html +1 -1
  113. package/dashboard/.next/standalone/dashboard/.next/server/app/overview.rsc +1 -1
  114. package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/!KGRhc2hib2FyZCk/overview/__PAGE__.segment.rsc +1 -1
  115. package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/!KGRhc2hib2FyZCk/overview.segment.rsc +1 -1
  116. package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  117. package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/_full.segment.rsc +1 -1
  118. package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/_head.segment.rsc +1 -1
  119. package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/_index.segment.rsc +1 -1
  120. package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/_tree.segment.rsc +1 -1
  121. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.html +1 -1
  122. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.rsc +1 -1
  123. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/!KGRhc2hib2FyZCk/protection/audit/__PAGE__.segment.rsc +1 -1
  124. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/!KGRhc2hib2FyZCk/protection/audit.segment.rsc +1 -1
  125. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
  126. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  127. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/_full.segment.rsc +1 -1
  128. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/_head.segment.rsc +1 -1
  129. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/_index.segment.rsc +1 -1
  130. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/_tree.segment.rsc +1 -1
  131. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.html +1 -1
  132. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.rsc +1 -1
  133. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/!KGRhc2hib2FyZCk/protection/intercepts/__PAGE__.segment.rsc +1 -1
  134. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/!KGRhc2hib2FyZCk/protection/intercepts.segment.rsc +1 -1
  135. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
  136. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  137. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/_full.segment.rsc +1 -1
  138. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/_head.segment.rsc +1 -1
  139. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/_index.segment.rsc +1 -1
  140. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/_tree.segment.rsc +1 -1
  141. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.html +1 -1
  142. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.rsc +1 -1
  143. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/!KGRhc2hib2FyZCk/protection/iron-dome/__PAGE__.segment.rsc +1 -1
  144. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/!KGRhc2hib2FyZCk/protection/iron-dome.segment.rsc +1 -1
  145. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
  146. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  147. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/_full.segment.rsc +1 -1
  148. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/_head.segment.rsc +1 -1
  149. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/_index.segment.rsc +1 -1
  150. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/_tree.segment.rsc +1 -1
  151. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.html +1 -1
  152. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.rsc +1 -1
  153. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/!KGRhc2hib2FyZCk/protection/policies/__PAGE__.segment.rsc +1 -1
  154. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/!KGRhc2hib2FyZCk/protection/policies.segment.rsc +1 -1
  155. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
  156. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  157. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/_full.segment.rsc +1 -1
  158. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/_head.segment.rsc +1 -1
  159. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/_index.segment.rsc +1 -1
  160. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/_tree.segment.rsc +1 -1
  161. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.html +1 -1
  162. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.rsc +1 -1
  163. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/!KGRhc2hib2FyZCk/protection/quarantine/__PAGE__.segment.rsc +1 -1
  164. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/!KGRhc2hib2FyZCk/protection/quarantine.segment.rsc +1 -1
  165. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
  166. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  167. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/_full.segment.rsc +1 -1
  168. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/_head.segment.rsc +1 -1
  169. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/_index.segment.rsc +1 -1
  170. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/_tree.segment.rsc +1 -1
  171. package/dashboard/.next/standalone/dashboard/.next/server/app/protection.html +1 -1
  172. package/dashboard/.next/standalone/dashboard/.next/server/app/protection.rsc +1 -1
  173. package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/!KGRhc2hib2FyZCk/protection/__PAGE__.segment.rsc +1 -1
  174. package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
  175. package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  176. package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/_full.segment.rsc +1 -1
  177. package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/_head.segment.rsc +1 -1
  178. package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/_index.segment.rsc +1 -1
  179. package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/_tree.segment.rsc +1 -1
  180. package/dashboard/.next/standalone/dashboard/.next/server/app/settings.html +1 -1
  181. package/dashboard/.next/standalone/dashboard/.next/server/app/settings.rsc +1 -1
  182. package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/!KGRhc2hib2FyZCk/settings/__PAGE__.segment.rsc +1 -1
  183. package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/!KGRhc2hib2FyZCk/settings.segment.rsc +1 -1
  184. package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  185. package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/_full.segment.rsc +1 -1
  186. package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/_head.segment.rsc +1 -1
  187. package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/_index.segment.rsc +1 -1
  188. package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
  189. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.html +1 -1
  190. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.rsc +1 -1
  191. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/!KGRhc2hib2FyZCk/supply-chain/xray/__PAGE__.segment.rsc +1 -1
  192. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/!KGRhc2hib2FyZCk/supply-chain/xray.segment.rsc +1 -1
  193. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/!KGRhc2hib2FyZCk/supply-chain.segment.rsc +1 -1
  194. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  195. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/_full.segment.rsc +1 -1
  196. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/_head.segment.rsc +1 -1
  197. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/_index.segment.rsc +1 -1
  198. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/_tree.segment.rsc +1 -1
  199. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.html +1 -1
  200. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.rsc +1 -1
  201. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/!KGRhc2hib2FyZCk/supply-chain/__PAGE__.segment.rsc +1 -1
  202. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/!KGRhc2hib2FyZCk/supply-chain.segment.rsc +1 -1
  203. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  204. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/_full.segment.rsc +1 -1
  205. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/_head.segment.rsc +1 -1
  206. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/_index.segment.rsc +1 -1
  207. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/_tree.segment.rsc +1 -1
  208. package/dashboard/.next/standalone/dashboard/.next/server/app/xray.html +1 -1
  209. package/dashboard/.next/standalone/dashboard/.next/server/app/xray.rsc +1 -1
  210. package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/!KGRhc2hib2FyZCk/xray/__PAGE__.segment.rsc +1 -1
  211. package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/!KGRhc2hib2FyZCk/xray.segment.rsc +1 -1
  212. package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  213. package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/_full.segment.rsc +1 -1
  214. package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/_head.segment.rsc +1 -1
  215. package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/_index.segment.rsc +1 -1
  216. package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/_tree.segment.rsc +1 -1
  217. package/dashboard/.next/standalone/dashboard/.next/server/pages/404.html +1 -1
  218. package/dashboard/.next/standalone/dashboard/.next/server/pages/500.html +2 -2
  219. package/dist/api/routes/memories.js +14 -1
  220. package/dist/cloud/cli.js +26 -1
  221. package/dist/defence/firewall/markdown-image-detector.d.ts +15 -0
  222. package/dist/defence/firewall/markdown-image-detector.js +30 -0
  223. package/dist/defence/quarantine/review.js +29 -7
  224. package/dist/defence/tool-response-enforce.d.ts +57 -0
  225. package/dist/defence/tool-response-enforce.js +107 -0
  226. package/dist/defence/tool-response-scanner.d.ts +6 -3
  227. package/dist/defence/tool-response-scanner.js +56 -6
  228. package/dist/defence/trust/recall-filter.js +6 -2
  229. package/dist/defence/trust/source-scorer.js +5 -0
  230. package/dist/defence/types.d.ts +9 -0
  231. package/dist/memory/consolidate.js +50 -18
  232. package/dist/memory/lifecycle.js +13 -0
  233. package/dist/memory/store.d.ts +1 -0
  234. package/dist/memory/store.js +73 -54
  235. package/dist/server.d.ts +6 -0
  236. package/dist/server.js +52 -2
  237. package/package.json +1 -1
  238. package/scripts/lib/recall-defence.mjs +254 -0
  239. package/scripts/lib/save-memory.mjs +12 -3
  240. package/scripts/prompt-recall-hook.mjs +33 -0
  241. package/scripts/session-start-hook.mjs +36 -4
  242. /package/dashboard/.next/standalone/dashboard/.next/static/{h2qG7AvaXDfMKQrI-bK4V → Xdk3QuQEKommHIbMSem56}/_buildManifest.js +0 -0
  243. /package/dashboard/.next/standalone/dashboard/.next/static/{h2qG7AvaXDfMKQrI-bK4V → Xdk3QuQEKommHIbMSem56}/_clientMiddlewareManifest.json +0 -0
  244. /package/dashboard/.next/standalone/dashboard/.next/static/{h2qG7AvaXDfMKQrI-bK4V → Xdk3QuQEKommHIbMSem56}/_ssgManifest.js +0 -0
@@ -0,0 +1,254 @@
1
+ /**
2
+ * Recall-boundary defence shim (Feature #1).
3
+ *
4
+ * The read hooks (prompt-recall, session-start) used to inject recalled memory
5
+ * VERBATIM into the model prompt with no defence. This module sits between the
6
+ * SQL SELECT and the formatter: it filters rows by trust/sensitivity (via the
7
+ * dead-no-more filterByTrust) and re-scans surviving content for injection /
8
+ * credentials / encoded payloads, withholding (not deleting) anything bad so a
9
+ * poisoned or RESTRICTED row never reaches the model.
10
+ *
11
+ * `defendRecallRows` is PURE + dependency-injected so it unit-tests with no dist
12
+ * build and no DB. `loadRecallDefence` / `emitRecallAudit` (below) wire the real
13
+ * dist modules for the hooks and are exercised by the integration test.
14
+ */
15
+
16
+ import { dirname, resolve } from 'node:path';
17
+ import { fileURLToPath, pathToFileURL } from 'node:url';
18
+
19
+ const RESTRICTED_MARKER = '[REDACTED - RESTRICTED]';
20
+
21
+ let _recallDefenceCache = null;
22
+ let _recallDefenceCacheKey = null;
23
+
24
+ /**
25
+ * Lazy-load the built dist defence modules the read hooks need. Returns null if
26
+ * the dist build is missing/incomplete → the caller MUST fail OPEN (leave recall
27
+ * unchanged), because blanking recall in an un-built dev workspace would break
28
+ * the product. Imports only LEAF detector modules (never dist/defence/pipeline.js)
29
+ * to stay inside the hook's <500ms budget; caches across invocations.
30
+ *
31
+ * @param {string} [distRootOverride] test seam — point at an empty dir to assert fail-open.
32
+ */
33
+ export async function loadRecallDefence(distRootOverride) {
34
+ const here = dirname(fileURLToPath(import.meta.url));
35
+ const distRoot = distRootOverride ?? resolve(here, '..', '..', 'dist');
36
+ if (_recallDefenceCache && _recallDefenceCacheKey === distRoot) return _recallDefenceCache;
37
+
38
+ try {
39
+ const [trustMod, firewallMod, credMod, auditMod, initMod, sanitiseMod] = await Promise.all([
40
+ import(pathToFileURL(resolve(distRoot, 'defence', 'trust', 'recall-filter.js')).href),
41
+ import(pathToFileURL(resolve(distRoot, 'defence', 'firewall', 'index.js')).href),
42
+ import(pathToFileURL(resolve(distRoot, 'defence', 'credential-leak', 'index.js')).href),
43
+ import(pathToFileURL(resolve(distRoot, 'defence', 'audit', 'logger.js')).href),
44
+ import(pathToFileURL(resolve(distRoot, 'database', 'init.js')).href),
45
+ import(pathToFileURL(resolve(distRoot, 'defence', 'input-sanitisation', 'index.js')).href).catch(() => ({})),
46
+ ]);
47
+
48
+ if (
49
+ typeof trustMod.filterByTrust !== 'function' ||
50
+ typeof firewallMod.detectInstructions !== 'function' ||
51
+ typeof firewallMod.detectEncoding !== 'function' ||
52
+ typeof credMod.scanForCredentials !== 'function' ||
53
+ typeof auditMod.logAudit !== 'function' ||
54
+ typeof initMod.initDatabase !== 'function'
55
+ ) {
56
+ return null;
57
+ }
58
+
59
+ _recallDefenceCache = {
60
+ filterByTrust: trustMod.filterByTrust,
61
+ // Optional — strips zero-width/RTL/control bytes before scanning so a
62
+ // hidden injection can't dodge the regex detectors; defendRecallRows guards.
63
+ sanitiseInput: sanitiseMod.sanitiseInput,
64
+ detectInstructions: firewallMod.detectInstructions,
65
+ detectEncoding: firewallMod.detectEncoding,
66
+ // Optional — older dist builds may not export it; defendRecallRows guards.
67
+ detectMarkdownImageExfil: firewallMod.detectMarkdownImageExfil,
68
+ scanForCredentials: credMod.scanForCredentials,
69
+ logAudit: auditMod.logAudit,
70
+ initDatabase: initMod.initDatabase,
71
+ isDatabaseInitialized: initMod.isDatabaseInitialized,
72
+ getDatabase: initMod.getDatabase,
73
+ closeDatabase: initMod.closeDatabase,
74
+ };
75
+ _recallDefenceCacheKey = distRoot;
76
+ return _recallDefenceCache;
77
+ } catch {
78
+ return null;
79
+ }
80
+ }
81
+
82
+ /**
83
+ * Point the dist DB singleton (used by logAudit) at the hook's DB so withhold
84
+ * audit rows are visible across connections. Only needed when ≥1 row is withheld
85
+ * — keep it out of the common all-clear path. Best-effort.
86
+ */
87
+ export function ensureRecallAuditDb(defence, dbPath) {
88
+ if (!defence || !dbPath || dbPath === ':memory:') return;
89
+ try {
90
+ if (defence.isDatabaseInitialized && defence.isDatabaseInitialized()) {
91
+ const current = defence.getDatabase();
92
+ if (current && current.name === dbPath) return;
93
+ if (defence.closeDatabase) defence.closeDatabase();
94
+ }
95
+ defence.initDatabase(dbPath);
96
+ } catch {
97
+ // logAudit no-ops gracefully if the singleton isn't initialised.
98
+ }
99
+ }
100
+
101
+ /**
102
+ * Write a defence_audit row recording a withheld/redacted recall. Best-effort —
103
+ * never throws into the hook (a recall must not fail because audit failed).
104
+ */
105
+ export function emitRecallAudit(logAudit, { memoryId, action, layer, reason, project } = {}) {
106
+ try {
107
+ logAudit({
108
+ memory_id: typeof memoryId === 'number' ? memoryId : null,
109
+ project: project ?? null,
110
+ timestamp: new Date().toISOString(),
111
+ source_type: 'hook',
112
+ source_identifier: 'recall-defence',
113
+ trust_score: 0,
114
+ sensitivity_level: 'INTERNAL',
115
+ // No 'READ' firewall result exists; encode the withhold as BLOCK (dropped)
116
+ // / QUARANTINE (redacted) with the detail in `reason`.
117
+ firewall_result: action === 'redacted' ? 'QUARANTINE' : 'BLOCK',
118
+ anomaly_score: 0,
119
+ threat_indicators: JSON.stringify([`recall:${layer ?? 'unknown'}`]),
120
+ blocked_patterns: '[]',
121
+ reason: `recall-withheld: ${reason ?? layer ?? 'policy'}`,
122
+ fragmentation_score: null,
123
+ pipeline_duration_ms: 0,
124
+ });
125
+ } catch {
126
+ // best-effort
127
+ }
128
+ }
129
+
130
+ function parseMetadata(meta) {
131
+ if (meta == null) return {};
132
+ if (typeof meta === 'object') return meta;
133
+ if (typeof meta === 'string') {
134
+ try {
135
+ return JSON.parse(meta);
136
+ } catch {
137
+ return {};
138
+ }
139
+ }
140
+ return {};
141
+ }
142
+
143
+ /**
144
+ * Filter recalled rows through the trust/sensitivity + content defence layers.
145
+ *
146
+ * @param {Array<object>} rows raw recalled rows (better-sqlite3 rows — NOT mutated)
147
+ * @param {{ minTrust?: number, project?: string, reviewedPinnedBypass?: boolean }} opts
148
+ * @param {{ filterByTrust, detectInstructions, scanForCredentials, detectEncoding }} deps
149
+ * @returns {{ kept: object[], actions: Array<{id:any, action:'allowed'|'dropped'|'redacted', layer:string|null, reason:string|null}> }}
150
+ */
151
+ export function defendRecallRows(rows, opts = {}, deps) {
152
+ const minTrust = typeof opts.minTrust === 'number' ? opts.minTrust : 0;
153
+ const reviewedPinnedBypass = opts.reviewedPinnedBypass !== false; // default ON
154
+ const actions = [];
155
+
156
+ // Shallow copies — never mutate the better-sqlite3 rows (reused by the dedupe
157
+ // ring + telemetry). Coalesce undefined trust → 1.0 (column DEFAULT 1.0) so a
158
+ // legacy un-migrated row isn't dropped as trust 0 by filterByTrust.
159
+ const copies = rows.map((r) => ({
160
+ ...r,
161
+ trust_score: r.trust_score ?? 1.0,
162
+ metadata: parseMetadata(r.metadata),
163
+ }));
164
+
165
+ // Trust + sensitivity: drops quarantined/below-minTrust, redacts RESTRICTED.
166
+ const trusted = deps.filterByTrust(copies, minTrust, opts.project);
167
+ const trustedIds = new Set(trusted.map((r) => r.id));
168
+ for (const c of copies) {
169
+ if (!trustedIds.has(c.id)) {
170
+ actions.push({ id: c.id, action: 'dropped', layer: 'trust', reason: `trust<${minTrust} or quarantined` });
171
+ }
172
+ }
173
+
174
+ const kept = [];
175
+ for (const row of trusted) {
176
+ // Already redacted by the trust layer — keep the masked row, don't re-scan
177
+ // the marker.
178
+ if (row.content === RESTRICTED_MARKER) {
179
+ actions.push({ id: row.id, action: 'redacted', layer: 'restricted', reason: 'RESTRICTED content redacted on recall' });
180
+ kept.push(row);
181
+ continue;
182
+ }
183
+
184
+ // Reviewed/pinned bypass: a human-reviewed or pinned memory skips the
185
+ // content detectors (trust/RESTRICTED above still applied) so a legitimately
186
+ // reviewed security note isn't re-suppressed at read time.
187
+ if (reviewedPinnedBypass && (row.reviewed_at != null || row.pinned)) {
188
+ actions.push({ id: row.id, action: 'allowed', layer: 'bypass', reason: 'reviewed/pinned — content scan skipped' });
189
+ kept.push(row);
190
+ continue;
191
+ }
192
+
193
+ const content = typeof row.content === 'string' ? row.content : '';
194
+ // Sanitise (strip zero-width / RTL / control bytes) BEFORE scanning — the
195
+ // write path does this, so an injection hidden behind zero-width chars
196
+ // otherwise dodges the read-path regex detectors. Scan the sanitised form;
197
+ // the original (benign zero-width is harmless) is what gets injected.
198
+ const scanContent = deps.sanitiseInput ? (deps.sanitiseInput(content)?.sanitised ?? content) : content;
199
+
200
+ const instr = deps.detectInstructions(scanContent);
201
+ if (instr && instr.detected) {
202
+ actions.push({ id: row.id, action: 'dropped', layer: 'instruction', reason: `instruction:${(instr.patterns ?? []).join(',')}` });
203
+ continue;
204
+ }
205
+
206
+ // Mirror the WRITE path: drop only on a BLOCKING credential finding, not a
207
+ // warned/logged one. A benign high-entropy hash / cache key is stored
208
+ // (write blocks only on action==='blocked'), so recall must not be stricter
209
+ // or it silently withholds legitimate notes.
210
+ const cred = deps.scanForCredentials(scanContent);
211
+ const credBlocked = !!cred && Array.isArray(cred.findings) && cred.findings.some((f) => f && f.action === 'blocked');
212
+ if (credBlocked) {
213
+ const blocked = cred.findings.filter((f) => f && f.action === 'blocked');
214
+ actions.push({ id: row.id, action: 'dropped', layer: 'credential', reason: `credential:${blocked.length}` });
215
+ continue;
216
+ }
217
+
218
+ // Decode-and-rescan: a bare encoding flag is NOT a drop (base64 hashes are
219
+ // common) — only drop if a DECODED snippet itself trips a detector.
220
+ const enc = deps.detectEncoding(scanContent);
221
+ if (enc && enc.detected) {
222
+ let malicious = false;
223
+ for (const snippet of enc.decodedSnippets ?? []) {
224
+ const di = deps.detectInstructions(snippet);
225
+ const dc = deps.scanForCredentials(snippet);
226
+ const dcBlocked = !!dc && Array.isArray(dc.findings) && dc.findings.some((f) => f && f.action === 'blocked');
227
+ if ((di && di.detected) || dcBlocked) {
228
+ malicious = true;
229
+ break;
230
+ }
231
+ }
232
+ if (malicious) {
233
+ actions.push({ id: row.id, action: 'dropped', layer: 'encoding', reason: `encoding-payload:${(enc.encodingTypes ?? []).join(',')}` });
234
+ continue;
235
+ }
236
+ }
237
+
238
+ // Markdown-image exfil: a stored ![alt](url?d=<smuggled>) is a click-free
239
+ // data-leak shape the write firewall catches but the read path didn't.
240
+ // detectMarkdownImageExfil only flags data-bearing image URLs (low FP).
241
+ if (deps.detectMarkdownImageExfil) {
242
+ const mdImg = deps.detectMarkdownImageExfil(scanContent);
243
+ if (mdImg && mdImg.detected) {
244
+ actions.push({ id: row.id, action: 'dropped', layer: 'markdown-image-exfil', reason: `markdown-image-exfil:${(mdImg.urls ?? []).length}` });
245
+ continue;
246
+ }
247
+ }
248
+
249
+ actions.push({ id: row.id, action: 'allowed', layer: null, reason: null });
250
+ kept.push(row);
251
+ }
252
+
253
+ return { kept, actions };
254
+ }
@@ -76,7 +76,11 @@ export async function saveAutoExtractedMemory(db, memory, project, opts = {}) {
76
76
  const decision = result.firewall.result;
77
77
 
78
78
  if (decision === 'ALLOW') {
79
- insertMemoryRow(db, memory, project, sourceIdentifier);
79
+ // Persist the COMPUTED trust + sensitivity from the scan — not the schema
80
+ // DEFAULT (trust 1.0 / INTERNAL). The INSERT used to omit these columns, so
81
+ // every hook-captured memory was over-trusted at 1.0, undercutting the
82
+ // recall shim's trust filter.
83
+ insertMemoryRow(db, memory, project, sourceIdentifier, result.trust?.score, result.sensitivity?.level);
80
84
  return;
81
85
  }
82
86
 
@@ -99,7 +103,7 @@ export async function saveAutoExtractedMemory(db, memory, project, opts = {}) {
99
103
 
100
104
  // ==================== Internal: writes ====================
101
105
 
102
- function insertMemoryRow(db, memory, project, sourceIdentifier) {
106
+ function insertMemoryRow(db, memory, project, sourceIdentifier, trustScore, sensitivityLevel) {
103
107
  const timestamp = new Date().toISOString();
104
108
 
105
109
  // Cross-call, CROSS-PATH exact-title dedup: the hook fires repeatedly (per
@@ -153,9 +157,10 @@ function insertMemoryRow(db, memory, project, sourceIdentifier) {
153
157
  INSERT INTO memories (
154
158
  uuid, title, content, type, category, salience, tags, project,
155
159
  memory_purpose, source, source_kind, capture_method,
160
+ trust_score, sensitivity_level,
156
161
  created_at, last_accessed
157
162
  )
158
- VALUES (?, ?, ?, 'short_term', ?, ?, ?, ?, ?, ?, 'hook', 'auto', ?, ?)
163
+ VALUES (?, ?, ?, 'short_term', ?, ?, ?, ?, ?, ?, 'hook', 'auto', ?, ?, ?, ?)
159
164
  `).run(
160
165
  randomUUID(),
161
166
  memory.title,
@@ -166,6 +171,10 @@ function insertMemoryRow(db, memory, project, sourceIdentifier) {
166
171
  project || null,
167
172
  memory.memoryPurpose ?? 'project',
168
173
  `hook:${sourceIdentifier}`,
174
+ // Computed by the scan above (hook source → 0.8). Fall back to the schema
175
+ // defaults only if the pipeline somehow returned no trust/sensitivity.
176
+ typeof trustScore === 'number' ? trustScore : 1.0,
177
+ sensitivityLevel ?? 'INTERNAL',
169
178
  timestamp,
170
179
  timestamp,
171
180
  );
@@ -24,6 +24,7 @@ import { computeEffectiveSalience } from './lib/salience.mjs';
24
24
  import { writeRecallLog } from './lib/recall-log.mjs';
25
25
  import { recordHookInvocation } from './lib/telemetry.mjs';
26
26
  import { filterByRelevance, extractQueryTerms } from './lib/recall-relevance.mjs';
27
+ import { defendRecallRows, loadRecallDefence, ensureRecallAuditDb, emitRecallAudit } from './lib/recall-defence.mjs';
27
28
 
28
29
  // ==================== CONFIG ====================
29
30
 
@@ -135,6 +136,7 @@ function recallRelevant(db, project, prompt) {
135
136
  SELECT
136
137
  m.id, m.title, m.content, m.category, m.salience, fts.rank,
137
138
  m.pinned, m.access_count, m.last_accessed,
139
+ m.trust_score, m.sensitivity_level, m.metadata, m.reviewed_at,
138
140
  COALESCE(m.downvote_count, 0) AS downvote_count
139
141
  FROM memories m
140
142
  JOIN memories_fts fts ON m.id = fts.rowid
@@ -184,6 +186,7 @@ function recallRelevant(db, project, prompt) {
184
186
  SELECT
185
187
  id, title, content, category, salience,
186
188
  pinned, access_count, last_accessed,
189
+ trust_score, sensitivity_level, metadata, reviewed_at,
187
190
  COALESCE(downvote_count, 0) AS downvote_count
188
191
  FROM memories
189
192
  WHERE category = ?
@@ -517,6 +520,36 @@ process.stdin.on('end', async () => {
517
520
  }
518
521
  }
519
522
 
523
+ // ── RECALL-BOUNDARY DEFENCE (Feature #1) ─────────────────────────────
524
+ // Filter poisoned / RESTRICTED / credential-bearing rows OUT of the recalled
525
+ // set before they're formatted into the prompt. Runs after dedupe (acts on
526
+ // the final injected set) and before format + ring + telemetry (so those see
527
+ // only safe rows). FAIL-OPEN: a missing dist build leaves recall unchanged.
528
+ if (config.recallDefence !== false && memories.length > 0) {
529
+ try {
530
+ const defence = await loadRecallDefence();
531
+ if (defence) {
532
+ const minTrust = typeof config.recallDefenceMinTrust === 'number' ? config.recallDefenceMinTrust : 0;
533
+ const { kept: safe, actions } = defendRecallRows(memories, { minTrust, project }, defence);
534
+ const withheld = actions.filter((a) => a.action !== 'allowed');
535
+ if (withheld.length > 0) {
536
+ console.error(
537
+ `[shieldcortex] recall-defence withheld ${withheld.length} memory row(s): ` +
538
+ withheld.map((w) => `#${w.id}:${w.layer}`).join(', '),
539
+ );
540
+ // Only touch a writable audit connection when something was withheld.
541
+ ensureRecallAuditDb(defence, dbPath);
542
+ for (const a of withheld) {
543
+ emitRecallAudit(defence.logAudit, { memoryId: a.id, action: a.action, layer: a.layer, reason: a.reason, project });
544
+ }
545
+ }
546
+ memories = safe;
547
+ }
548
+ } catch (e) {
549
+ console.error('[shieldcortex] recall-defence skipped:', e?.message ?? e);
550
+ }
551
+ }
552
+
520
553
  const context = formatRecallContext(memories);
521
554
 
522
555
  // Update the session ring with the hashes of what we just injected.
@@ -25,6 +25,7 @@ import { homedir } from 'os';
25
25
  import { deriveProjectKey } from './lib/project-key.mjs';
26
26
  import { truncatePreservingWords } from './lib/truncate.mjs';
27
27
  import { orderByEffectiveSalience } from './lib/session-context.mjs';
28
+ import { defendRecallRows, loadRecallDefence, ensureRecallAuditDb, emitRecallAudit } from './lib/recall-defence.mjs';
28
29
 
29
30
  const NEW_DB_DIR = join(homedir(), '.shieldcortex');
30
31
  const LEGACY_DB_DIR = join(homedir(), '.claude-cortex');
@@ -94,7 +95,8 @@ function getProjectContext(db, project) {
94
95
  // computeEffectiveSalience.
95
96
  const candidates = db.prepare(`
96
97
  SELECT id, title, content, category, type, salience, tags, created_at,
97
- pinned, access_count, last_accessed, COALESCE(downvote_count, 0) AS downvote_count
98
+ pinned, access_count, last_accessed, trust_score, sensitivity_level, metadata, reviewed_at,
99
+ COALESCE(downvote_count, 0) AS downvote_count
98
100
  FROM memories
99
101
  WHERE (project = ? OR project IS NULL)
100
102
  AND salience >= ?
@@ -111,7 +113,8 @@ function getProjectContext(db, project) {
111
113
  const excludeIds = memories.map(m => m.id);
112
114
  const placeholders = excludeIds.length > 0 ? excludeIds.map(() => '?').join(',') : '0';
113
115
  const recent = db.prepare(`
114
- SELECT id, title, content, category, type, salience, tags, created_at
116
+ SELECT id, title, content, category, type, salience, tags, created_at,
117
+ pinned, trust_score, sensitivity_level, metadata, reviewed_at
115
118
  FROM memories
116
119
  WHERE (project = ? OR project IS NULL)
117
120
  AND id NOT IN (${placeholders})
@@ -208,7 +211,7 @@ process.stdin.on('readable', () => {
208
211
  }
209
212
  });
210
213
 
211
- process.stdin.on('end', () => {
214
+ process.stdin.on('end', async () => {
212
215
  try {
213
216
  const hookData = JSON.parse(input || '{}');
214
217
  const source = typeof hookData.source === 'string' ? hookData.source : 'startup';
@@ -239,8 +242,37 @@ process.stdin.on('end', () => {
239
242
  } else {
240
243
  const db = new Database(DB_PATH, { readonly: true, timeout: 5000 });
241
244
  memories = getProjectContext(db, project);
242
- context = formatContext(memories, project);
243
245
  db.close();
246
+
247
+ // ── RECALL-BOUNDARY DEFENCE (Feature #1) ───────────────────────────
248
+ // Same shim as prompt-recall: drop poisoned / RESTRICTED / credential
249
+ // rows from the session preamble before they're formatted. FAIL-OPEN if
250
+ // the dist build is missing (recall preamble unchanged).
251
+ if (config.recallDefence !== false && memories.length > 0) {
252
+ try {
253
+ const defence = await loadRecallDefence();
254
+ if (defence) {
255
+ const minTrust = typeof config.recallDefenceMinTrust === 'number' ? config.recallDefenceMinTrust : 0;
256
+ const { kept: safe, actions } = defendRecallRows(memories, { minTrust, project }, defence);
257
+ const withheld = actions.filter((a) => a.action !== 'allowed');
258
+ if (withheld.length > 0) {
259
+ console.error(
260
+ `[shieldcortex] recall-defence (session-start) withheld ${withheld.length} memory row(s): ` +
261
+ withheld.map((w) => `#${w.id}:${w.layer}`).join(', '),
262
+ );
263
+ ensureRecallAuditDb(defence, DB_PATH);
264
+ for (const a of withheld) {
265
+ emitRecallAudit(defence.logAudit, { memoryId: a.id, action: a.action, layer: a.layer, reason: a.reason, project });
266
+ }
267
+ }
268
+ memories = safe;
269
+ }
270
+ } catch (e) {
271
+ console.error('[shieldcortex] recall-defence skipped:', e?.message ?? e);
272
+ }
273
+ }
274
+
275
+ context = formatContext(memories, project);
244
276
  }
245
277
 
246
278
  if (context) {