shieldcortex 4.38.0 → 4.40.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 (250) 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/admin.js +2 -0
  220. package/dist/api/routes/memories.js +5 -2
  221. package/dist/api/visualization-server.js +1 -0
  222. package/dist/cloud/cli.js +13 -1
  223. package/dist/cloud/config.d.ts +10 -0
  224. package/dist/cloud/config.js +15 -0
  225. package/dist/database/inline-schema.js +6 -0
  226. package/dist/database/migrations.js +34 -0
  227. package/dist/database/schema.sql +6 -0
  228. package/dist/defence/audit/logger.js +4 -2
  229. package/dist/defence/audit/queries.d.ts +1 -1
  230. package/dist/defence/audit/queries.js +4 -0
  231. package/dist/defence/audit/retention.js +22 -12
  232. package/dist/defence/iron-dome/audit.js +1 -0
  233. package/dist/defence/pipeline.js +4 -1
  234. package/dist/defence/tool-response-scanner.js +1 -0
  235. package/dist/defence/trust/access-control.d.ts +1 -4
  236. package/dist/defence/trust/access-control.js +32 -0
  237. package/dist/defence/trust/resolve-tool-source.js +2 -0
  238. package/dist/defence/types.d.ts +10 -0
  239. package/dist/memory/lifecycle.js +5 -2
  240. package/dist/memory/store.d.ts +19 -3
  241. package/dist/memory/store.js +105 -9
  242. package/dist/server.js +9 -1
  243. package/dist/tools/context.js +15 -1
  244. package/dist/tools/forget.d.ts +3 -0
  245. package/dist/tools/forget.js +53 -1
  246. package/dist/tools/recall.js +9 -1
  247. package/package.json +1 -1
  248. /package/dashboard/.next/standalone/dashboard/.next/static/{PR51g0pS7Wp0zLzu2q6mQ → UA_86bJ-tNIyDXr-i0gK6}/_buildManifest.js +0 -0
  249. /package/dashboard/.next/standalone/dashboard/.next/static/{PR51g0pS7Wp0zLzu2q6mQ → UA_86bJ-tNIyDXr-i0gK6}/_clientMiddlewareManifest.json +0 -0
  250. /package/dashboard/.next/standalone/dashboard/.next/static/{PR51g0pS7Wp0zLzu2q6mQ → UA_86bJ-tNIyDXr-i0gK6}/_ssgManifest.js +0 -0
@@ -21,7 +21,7 @@ import { syncMemoryDeleteToCloud, syncMemoryUpsertToCloud } from '../cloud/memor
21
21
  import { isFeatureEnabled } from '../license/gate.js';
22
22
  import { checkAccess } from '../defence/trust/access-control.js';
23
23
  import { scoreSource } from '../defence/trust/source-scorer.js';
24
- import { logAudit } from '../defence/audit/logger.js';
24
+ import { logAudit, createContentHash } from '../defence/audit/logger.js';
25
25
  import { dispatchWebhook } from '../events/webhooks.js';
26
26
  import { safeJsonParse } from './fts.js';
27
27
  // Internal use of the link API. links.ts also imports from store.ts (getMemoryById,
@@ -230,7 +230,7 @@ function checkRateLimit(source) {
230
230
  // ── Read-Time Access Control ──
231
231
  // Exported because search-recall.ts also calls logAccessDenial inside its
232
232
  // post-search ACL filter (cycle artifact, not intended public API).
233
- export function logAccessDenial(memoryId, source, reason) {
233
+ export function logAccessDenial(memoryId, source, reason, operation = 'read') {
234
234
  const trust = scoreSource(source).score;
235
235
  logAudit({
236
236
  memory_id: memoryId,
@@ -241,6 +241,7 @@ export function logAccessDenial(memoryId, source, reason) {
241
241
  trust_score: trust,
242
242
  sensitivity_level: 'INTERNAL',
243
243
  firewall_result: 'BLOCK',
244
+ operation,
244
245
  anomaly_score: 0,
245
246
  threat_indicators: '[]',
246
247
  blocked_patterns: '[]',
@@ -249,6 +250,58 @@ export function logAccessDenial(memoryId, source, reason) {
249
250
  pipeline_duration_ms: 0,
250
251
  });
251
252
  }
253
+ /**
254
+ * Provenance ledger: record an ALLOWED read. Emitted ONCE per tool call (not per
255
+ * row) to keep the audit table bounded — recall returns up to 50 rows, so a
256
+ * per-row emit would flood it. memory_id carries the single id for single-target
257
+ * reads; the full id list (capped) goes in blocked_patterns for forensics.
258
+ */
259
+ export function logAllowedRead(source, tool, memoryIds, project) {
260
+ if (memoryIds.length === 0)
261
+ return;
262
+ logAudit({
263
+ memory_id: memoryIds.length === 1 ? memoryIds[0] : null,
264
+ project: project ?? null,
265
+ timestamp: new Date().toISOString(),
266
+ source_type: source.type,
267
+ source_identifier: source.identifier,
268
+ trust_score: scoreSource(source).score,
269
+ sensitivity_level: 'INTERNAL',
270
+ firewall_result: 'ALLOW',
271
+ operation: 'read',
272
+ anomaly_score: 0,
273
+ threat_indicators: '[]',
274
+ blocked_patterns: JSON.stringify(memoryIds.slice(0, 50)),
275
+ reason: `read ${memoryIds.length} memor${memoryIds.length === 1 ? 'y' : 'ies'} via ${tool}`,
276
+ fragmentation_score: null,
277
+ pipeline_duration_ms: null,
278
+ });
279
+ }
280
+ /**
281
+ * Provenance ledger: record an ALLOWED delete (one row per deleted memory).
282
+ * memory_id is NULL by design — the row is emitted after the DELETE, and the
283
+ * audit.memory_id FK is ON DELETE SET NULL, so a live reference can't survive.
284
+ * The deleted id is preserved in `reason` + `blocked_patterns` for forensics.
285
+ */
286
+ export function logAllowedDelete(memoryId, source, project, operation = 'delete') {
287
+ logAudit({
288
+ memory_id: null,
289
+ project: project ?? null,
290
+ timestamp: new Date().toISOString(),
291
+ source_type: source.type,
292
+ source_identifier: source.identifier,
293
+ trust_score: scoreSource(source).score,
294
+ sensitivity_level: 'INTERNAL',
295
+ firewall_result: 'ALLOW',
296
+ operation,
297
+ anomaly_score: 0,
298
+ threat_indicators: '[]',
299
+ blocked_patterns: JSON.stringify([memoryId]),
300
+ reason: `deleted memory #${memoryId}`,
301
+ fragmentation_score: null,
302
+ pipeline_duration_ms: null,
303
+ });
304
+ }
252
305
  /**
253
306
  * Filter raw DB rows by access control before converting to Memory objects.
254
307
  * Returns only rows the source is allowed to read.
@@ -324,6 +377,7 @@ export function addMemory(input, config = DEFAULT_CONFIG, source) {
324
377
  trust_score: scoreSource(source).score,
325
378
  sensitivity_level: 'INTERNAL',
326
379
  firewall_result: 'BLOCK',
380
+ operation: 'write',
327
381
  anomaly_score: 1.0,
328
382
  threat_indicators: JSON.stringify(['rate_limit_exceeded']),
329
383
  blocked_patterns: '[]',
@@ -413,8 +467,11 @@ export function addMemory(input, config = DEFAULT_CONFIG, source) {
413
467
  // defenceResult is always set now (every write is scanned), so always stamp
414
468
  // the pipeline's real trust + sensitivity alongside the resolved source —
415
469
  // no source-less branch can default to trust 1.0 / unscanned INTERNAL.
416
- db.prepare(`UPDATE memories SET trust_score = ?, sensitivity_level = ?, source = ? WHERE id = ?`)
417
- .run(defenceResult.trust.score, defenceResult.sensitivity.level, sourceDetails.sourceValue, result.lastInsertRowid);
470
+ db.prepare(`UPDATE memories SET trust_score = ?, sensitivity_level = ?, source = ?, content_hash = ? WHERE id = ?`)
471
+ // content_hash = SHA-256 of the SUBMITTED content (a write-time provenance
472
+ // snapshot), matching the write-audit row in pipeline.ts. Consistent for
473
+ // >10KB memories too (where the STORED content is truncated).
474
+ .run(defenceResult.trust.score, defenceResult.sensitivity.level, sourceDetails.sourceValue, createContentHash(input.content), result.lastInsertRowid);
418
475
  return result.lastInsertRowid;
419
476
  })();
420
477
  const memory = getMemoryById(insertedId);
@@ -701,6 +758,14 @@ export function updateMemory(id, updates) {
701
758
  if (embeddedTextChanged) {
702
759
  fields.push('embedding = NULL');
703
760
  }
761
+ // STALENESS: content_hash is a write-time integrity snapshot. When content
762
+ // changes it must be recomputed in the SAME UPDATE — otherwise the stored hash
763
+ // refers to the old content and any tamper check false-positives on a
764
+ // legitimately-edited memory.
765
+ if (updates.content !== undefined) {
766
+ fields.push('content_hash = ?');
767
+ values.push(createContentHash(updates.content));
768
+ }
704
769
  if (fields.length === 0)
705
770
  return existing;
706
771
  values.push(id);
@@ -721,6 +786,28 @@ export function updateMemory(id, updates) {
721
786
  console.error('[shieldcortex] Entity extraction refresh failed:', e);
722
787
  }
723
788
  }
789
+ // Provenance ledger: a content/title change is an update-class mutation.
790
+ if (updates.content !== undefined || updates.title !== undefined) {
791
+ const changed = [updates.title !== undefined ? 'title' : null, updates.content !== undefined ? 'content' : null].filter(Boolean).join('+');
792
+ logAudit({
793
+ memory_id: id,
794
+ project: updatedMemory.project ?? null,
795
+ timestamp: new Date().toISOString(),
796
+ source_type: 'cli',
797
+ source_identifier: 'memory-update',
798
+ trust_score: updatedMemory.trustScore ?? 1,
799
+ sensitivity_level: updatedMemory.sensitivityLevel ?? 'INTERNAL',
800
+ firewall_result: 'ALLOW',
801
+ operation: 'update',
802
+ content_hash: updates.content !== undefined ? createContentHash(updates.content) : null,
803
+ anomaly_score: 0,
804
+ threat_indicators: '[]',
805
+ blocked_patterns: '[]',
806
+ reason: `updated memory #${id} (${changed})`,
807
+ fragmentation_score: null,
808
+ pipeline_duration_ms: null,
809
+ });
810
+ }
724
811
  // Emit event for real-time dashboard (in-process)
725
812
  emitMemoryUpdated(updatedMemory);
726
813
  // Persist event for cross-process IPC (MCP → Dashboard)
@@ -804,6 +891,7 @@ export function mergeMemories(keptId, removedId, options, source = { type: 'cli'
804
891
  db.prepare(`
805
892
  UPDATE memories
806
893
  SET content = ?,
894
+ content_hash = ?,
807
895
  tags = ?,
808
896
  salience = ?,
809
897
  project = ?,
@@ -822,7 +910,7 @@ export function mergeMemories(keptId, removedId, options, source = { type: 'cli'
822
910
  embedding = NULL,
823
911
  updated_at = CURRENT_TIMESTAMP
824
912
  WHERE id = ?
825
- `).run(mergedContent, JSON.stringify(mergedTags), mergedSalience, mergedProject, JSON.stringify(mergedMetadata), mergedScope, mergedTransferable ? 1 : 0, mergedStatus, mergedPinned ? 1 : 0, mergedReviewedBy, new Date().toISOString(), mergedTrustScore, mergedSensitivity, mergedCloudExcluded ? 1 : 0, mergedAccessCount, mergedLastAccessed, kept.id);
913
+ `).run(mergedContent, createContentHash(mergedContent), JSON.stringify(mergedTags), mergedSalience, mergedProject, JSON.stringify(mergedMetadata), mergedScope, mergedTransferable ? 1 : 0, mergedStatus, mergedPinned ? 1 : 0, mergedReviewedBy, new Date().toISOString(), mergedTrustScore, mergedSensitivity, mergedCloudExcluded ? 1 : 0, mergedAccessCount, mergedLastAccessed, kept.id);
826
914
  const updatedMemory = getMemoryById(kept.id);
827
915
  try {
828
916
  const extraction = extractFromMemory(updatedMemory.title, updatedMemory.content, updatedMemory.category);
@@ -848,15 +936,17 @@ export function mergeMemories(keptId, removedId, options, source = { type: 'cli'
848
936
  /**
849
937
  * Delete a memory
850
938
  */
851
- export function deleteMemory(id, source) {
939
+ export function deleteMemory(id, source, opts) {
852
940
  const db = getDatabase();
853
- // ACCESS CONTROL: Check delete permission
941
+ const aclOp = opts?.mode ?? 'delete';
942
+ // ACCESS CONTROL: Check delete permission. mode 'revoke' uses the
943
+ // trust-hierarchy rule (own OR outrank); 'delete' (default) stays own-only.
854
944
  if (source) {
855
945
  const row = db.prepare('SELECT id, source, sensitivity_level FROM memories WHERE id = ?').get(id);
856
946
  if (row) {
857
- const policy = checkAccess({ id: row.id, source: row.source, sensitivity_level: row.sensitivity_level }, source, 'delete');
947
+ const policy = checkAccess({ id: row.id, source: row.source, sensitivity_level: row.sensitivity_level }, source, aclOp);
858
948
  if (!policy.canDelete) {
859
- logAccessDenial(id, source, policy.reason);
949
+ logAccessDenial(id, source, policy.reason, aclOp);
860
950
  return false;
861
951
  }
862
952
  }
@@ -874,6 +964,12 @@ export function deleteMemory(id, source) {
874
964
  const result = db.prepare('DELETE FROM memories WHERE id = ?').run(id);
875
965
  // Emit event for real-time dashboard (in-process)
876
966
  if (result.changes > 0 && memory) {
967
+ // Provenance ledger: record the allowed delete (one row per memory) when the
968
+ // caller is attributed. Internal source-less deletes (merge/consolidation)
969
+ // are machinery, not user actions, so they're not audited here.
970
+ if (source) {
971
+ logAllowedDelete(id, source, memory.project ?? null, aclOp);
972
+ }
877
973
  if (isFeatureEnabled('cloud_sync')) {
878
974
  syncMemoryDeleteToCloud(memory);
879
975
  syncGraphDeleteForMemoryToCloud(memory);
package/dist/server.js CHANGED
@@ -23,6 +23,7 @@ import { checkDatabaseSize } from './database/init.js';
23
23
  import { queryAuditLogs, getAuditStats, getLifetimeStats } from './defence/audit/index.js';
24
24
  import { scanExistingMemories } from './defence/scanner/index.js';
25
25
  import { resolveToolSource as resolveToolSourceImpl } from './defence/trust/resolve-tool-source.js';
26
+ import { inferSourceFromEnvironment } from './defence/trust/env-detector.js';
26
27
  import { scanToolResponse, shouldScanToolResponse } from './defence/tool-response-scanner.js';
27
28
  import { UNTRUSTED_TOOL_TAG } from './defence/tool-response-enforce.js';
28
29
  import { guardReadBySensitivity, guardContextSummary } from './defence/trust/read-guard.js';
@@ -287,8 +288,15 @@ Modes: search (query-based), recent (by time), important (by salience)`, {
287
288
  confirm: z.boolean().optional().default(false)
288
289
  .describe('Confirm bulk delete'),
289
290
  source: sourceParam,
291
+ fromSource: z.string().optional()
292
+ .describe('Revoke-by-source: delete all memories written by this source ("type:identifier", or "type:*" for a whole type). Authorised by the trust-hierarchy revoke ACL (own the source or outrank it). Use project:"*" to revoke across all projects.'),
290
293
  }, { title: 'Delete Memories', readOnlyHint: false, destructiveHint: true, idempotentHint: false }, withKillSwitchGuard('memory_write', async (args) => {
291
- const source = resolveToolSource(args.source, 'forget');
294
+ // Delete is destructive, and revoke-by-source grants cross-identity power,
295
+ // so the caller identity MUST be the unspoofable runtime identity — derive
296
+ // it from the environment, NOT the MCP-declared `source` param. Honouring a
297
+ // declared identity would let a caller claim ownership of any peer source's
298
+ // memories (the clamp only caps trust SCORE, not identity).
299
+ const source = inferSourceFromEnvironment().source;
292
300
  const result = await executeForget({ ...args, source });
293
301
  return {
294
302
  content: [{ type: 'text', text: formatForgetResult(result) }],
@@ -6,7 +6,7 @@
6
6
  */
7
7
  import { z } from 'zod';
8
8
  import { generateContextSummary, formatContextSummary, startSession, endSession, getSuggestedContext, consolidate, previewConsolidation, exportMemories, importMemories, } from '../memory/consolidate.js';
9
- import { getMemoryStats } from '../memory/store.js';
9
+ import { getMemoryStats, logAllowedRead } from '../memory/store.js';
10
10
  import { getSalienceDistribution } from '../memory/metrics.js';
11
11
  import { getDatabase } from '../database/init.js';
12
12
  import { resolveProject } from '../context/project-context.js';
@@ -61,6 +61,16 @@ export async function executeGetContext(input) {
61
61
  }
62
62
  break;
63
63
  }
64
+ // Provenance ledger: one allowed-read row per get_context call, covering
65
+ // every memory surfaced into the context.
66
+ const source = input.source;
67
+ if (source) {
68
+ const surfacedIds = [
69
+ ...summary.recentMemories, ...summary.keyDecisions,
70
+ ...summary.activePatterns, ...summary.pendingItems, ...relevantMemories,
71
+ ].map(m => m.id);
72
+ logAllowedRead(source, 'get_context', [...new Set(surfacedIds)], projectFilter);
73
+ }
64
74
  return {
65
75
  success: true,
66
76
  context,
@@ -270,6 +280,10 @@ export function executeExport(input) {
270
280
  // Read ACL: filter the bulk dump to rows this caller may read.
271
281
  const data = exportMemories(projectFilter, input.source);
272
282
  const memories = JSON.parse(data);
283
+ // Provenance ledger: a bulk export is the highest-value read to audit.
284
+ if (input.source) {
285
+ logAllowedRead(input.source, 'export_memories', memories.map(m => m.id), projectFilter);
286
+ }
273
287
  return {
274
288
  success: true,
275
289
  data,
@@ -23,6 +23,7 @@ export declare const forgetSchema: z.ZodObject<{
23
23
  type: "user" | "cli" | "hook" | "email" | "web" | "agent" | "file" | "api" | "tool_response";
24
24
  identifier: string;
25
25
  }>>;
26
+ fromSource: z.ZodOptional<z.ZodString>;
26
27
  }, "strip", z.ZodTypeAny, {
27
28
  confirm: boolean;
28
29
  dryRun: boolean;
@@ -36,6 +37,7 @@ export declare const forgetSchema: z.ZodObject<{
36
37
  query?: string | undefined;
37
38
  olderThan?: number | undefined;
38
39
  belowSalience?: number | undefined;
40
+ fromSource?: string | undefined;
39
41
  }, {
40
42
  source?: {
41
43
  type: "user" | "cli" | "hook" | "email" | "web" | "agent" | "file" | "api" | "tool_response";
@@ -49,6 +51,7 @@ export declare const forgetSchema: z.ZodObject<{
49
51
  olderThan?: number | undefined;
50
52
  belowSalience?: number | undefined;
51
53
  dryRun?: boolean | undefined;
54
+ fromSource?: string | undefined;
52
55
  }>;
53
56
  export type ForgetInput = z.infer<typeof forgetSchema>;
54
57
  /**
@@ -8,6 +8,13 @@ import { deleteMemory, searchMemories, getMemoryById } from '../memory/store.js'
8
8
  import { getDatabase, withTransaction } from '../database/init.js';
9
9
  import { MemoryNotFoundError, BulkDeleteSafetyError, formatErrorForMcp, } from '../errors.js';
10
10
  import { resolveProject } from '../context/project-context.js';
11
+ import { isRevokeBySourceEnabled } from '../cloud/config.js';
12
+ /**
13
+ * Upper bound on rows a single revoke-by-source call may delete. Caps the blast
14
+ * radius of the mass-delete primitive — a larger match must be narrowed (by
15
+ * project/category/etc.) or paged.
16
+ */
17
+ const MAX_REVOKE_ROWS = 500;
11
18
  // Input schema for the forget tool
12
19
  export const forgetSchema = z.object({
13
20
  id: z.number().optional().describe('Specific memory ID to delete'),
@@ -28,6 +35,8 @@ export const forgetSchema = z.object({
28
35
  type: z.enum(['user', 'cli', 'hook', 'email', 'web', 'agent', 'file', 'api', 'tool_response']),
29
36
  identifier: z.string(),
30
37
  }).optional().describe('Caller identity for access control'),
38
+ fromSource: z.string().optional()
39
+ .describe('Revoke-by-source: delete all memories written by this source. Exact "type:identifier", or a "type:*" / "type:" prefix to revoke a whole source type. Authorised by the trust-hierarchy revoke ACL (you must own the source or outrank it). Distinct from `source` (the caller).'),
31
40
  });
32
41
  /**
33
42
  * Execute the forget tool
@@ -35,6 +44,15 @@ export const forgetSchema = z.object({
35
44
  export async function executeForget(input) {
36
45
  try {
37
46
  const db = getDatabase();
47
+ // Revoke-by-source gate: a destructive mass-delete primitive that a hijacked
48
+ // agent must not be able to invoke. OFF by default; only an out-of-band human
49
+ // action (`shieldcortex config --allow-revoke-by-source`) enables it.
50
+ if (input.fromSource !== undefined && !isRevokeBySourceEnabled()) {
51
+ return {
52
+ success: false,
53
+ error: 'revoke-by-source is disabled. Enable it deliberately with `shieldcortex config --allow-revoke-by-source` (an out-of-band action), then re-run.',
54
+ };
55
+ }
38
56
  // Resolve project (auto-detect if not provided)
39
57
  const resolvedProject = resolveProject(input.project);
40
58
  const source = input.source;
@@ -101,6 +119,28 @@ export async function executeForget(input) {
101
119
  conditions.push('salience < ?');
102
120
  params.push(input.belowSalience);
103
121
  }
122
+ // Revoke-by-source: target every memory written by a given source. Exact
123
+ // "type:identifier", or a "type:*" / "type:" prefix for a whole source type.
124
+ // Per-row authorisation is the trust-hierarchy revoke ACL (in deleteMemory
125
+ // via mode:'revoke') — this clause only SELECTS the candidates. Project scope
126
+ // still applies; pass project:"*" to revoke a source across all projects.
127
+ if (input.fromSource !== undefined) {
128
+ const fs = input.fromSource.trim();
129
+ if (!fs || fs === '*' || fs === ':' || fs === ':*') {
130
+ return {
131
+ success: false,
132
+ error: 'fromSource must name a source (e.g. "agent:agent-spawned" or "agent:*"), not a blanket wildcard.',
133
+ };
134
+ }
135
+ if (fs.endsWith(':*') || fs.endsWith(':')) {
136
+ conditions.push('source LIKE ?');
137
+ params.push(`${fs.replace(/:\*?$/, '')}:%`);
138
+ }
139
+ else {
140
+ conditions.push('source = ?');
141
+ params.push(fs);
142
+ }
143
+ }
104
144
  if (conditions.length === 0) {
105
145
  return {
106
146
  success: false,
@@ -113,6 +153,15 @@ export async function executeForget(input) {
113
153
  if (affected.length === 0) {
114
154
  return { success: true, deleted: 0, memories: [] };
115
155
  }
156
+ // Blast-radius cap on revoke-by-source: refuse a single call that would
157
+ // delete more than MAX_REVOKE_ROWS — narrow it (by project/category/etc.).
158
+ if (input.fromSource !== undefined && affected.length > MAX_REVOKE_ROWS) {
159
+ return {
160
+ success: false,
161
+ wouldDelete: affected.length,
162
+ error: `revoke-by-source matched ${affected.length} memories (cap ${MAX_REVOKE_ROWS}). Narrow the scope (project/category/query) and re-run.`,
163
+ };
164
+ }
116
165
  // Dry run - just show what would be deleted
117
166
  if (input.dryRun) {
118
167
  return {
@@ -138,10 +187,13 @@ export async function executeForget(input) {
138
187
  // delete, and the dashboard `memory_deleted` event. A low-trust / non-owner
139
188
  // caller therefore can't mass-delete protected memories. better-sqlite3 is
140
189
  // synchronous, so the per-row loop stays inside one transaction atomically.
190
+ // revoke-by-source uses the trust-hierarchy revoke ACL (own OR outrank);
191
+ // every other bulk forget stays own-only.
192
+ const deleteMode = input.fromSource !== undefined ? 'revoke' : 'delete';
141
193
  const deletedMemories = [];
142
194
  withTransaction(() => {
143
195
  for (const memory of affected) {
144
- if (deleteMemory(memory.id, source)) {
196
+ if (deleteMemory(memory.id, source, { mode: deleteMode })) {
145
197
  deletedMemories.push(memory);
146
198
  }
147
199
  }
@@ -4,7 +4,7 @@
4
4
  * Search and retrieve memories using semantic search and filters.
5
5
  */
6
6
  import { z } from 'zod';
7
- import { searchMemories, recallWithEmbeddings, accessMemory, getRecentMemories, getHighPriorityMemories, getRelatedMemories } from '../memory/store.js';
7
+ import { searchMemories, recallWithEmbeddings, accessMemory, getRecentMemories, getHighPriorityMemories, getRelatedMemories, logAllowedRead } from '../memory/store.js';
8
8
  import { formatTimeSinceAccess } from '../memory/decay.js';
9
9
  import { MemoryNotFoundError, formatErrorForMcp } from '../errors.js';
10
10
  import { resolveProject } from '../context/project-context.js';
@@ -115,6 +115,9 @@ export async function executeRecall(input) {
115
115
  }
116
116
  return m;
117
117
  });
118
+ // Provenance ledger: one allowed-read row per recall call (not per memory).
119
+ if (source)
120
+ logAllowedRead(source, `recall:${input.mode}`, memories.map(m => m.id), projectFilter);
118
121
  return {
119
122
  success: true,
120
123
  memories,
@@ -196,6 +199,8 @@ export function executeGetMemory(input) {
196
199
  error: error.toUserMessage(),
197
200
  };
198
201
  }
202
+ if (input.source)
203
+ logAllowedRead(input.source, 'get_memory', [allowed.id], allowed.project ?? null);
199
204
  return { success: true, memory: allowed };
200
205
  }
201
206
  catch (error) {
@@ -215,6 +220,9 @@ export function executeGetRelated(input) {
215
220
  try {
216
221
  const related = getRelatedMemories(input.id);
217
222
  const allowedIds = new Set(guardReadMemories(related.map((r) => r.memory), input.source).map((m) => m.id));
223
+ if (input.source && allowedIds.size > 0) {
224
+ logAllowedRead(input.source, 'get_related', [...allowedIds]);
225
+ }
218
226
  return { success: true, related: related.filter((r) => allowedIds.has(r.memory.id)) };
219
227
  }
220
228
  catch (error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shieldcortex",
3
- "version": "4.38.0",
3
+ "version": "4.40.0",
4
4
  "description": "Trustworthy memory and security for AI agents. Recall debugging, review queue, OpenClaw session capture, and memory poisoning defence for Claude Code, Codex, OpenClaw, LangChain, and MCP agents.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",