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
@@ -1,2 +1,2 @@
1
- <!DOCTYPE html><!--PR51g0pS7Wp0zLzu2q6mQ--><html id="__next_error__"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/d878b929b21636c4.js"/><script src="/_next/static/chunks/f70f563804550a9c.js" async=""></script><script src="/_next/static/chunks/43d761df92da7cb6.js" async=""></script><script src="/_next/static/chunks/e281719dbabcca1d.js" async=""></script><script src="/_next/static/chunks/9e56d1f8f4d7adcb.js" async=""></script><script src="/_next/static/chunks/turbopack-768a6a8b9db952e0.js" async=""></script><script src="/_next/static/chunks/102f894cc892994d.js" async=""></script><script src="/_next/static/chunks/417032eeb2cd875f.js" async=""></script><meta name="next-size-adjust" content=""/><title>500: Internal Server Error.</title><script src="/_next/static/chunks/a6dad97d9634a72d.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div style="line-height:48px"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}
2
- @media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">500</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">Internal Server Error.</h2></div></div></div><!--$--><!--/$--><script src="/_next/static/chunks/d878b929b21636c4.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[57043,[\"/_next/static/chunks/102f894cc892994d.js\",\"/_next/static/chunks/417032eeb2cd875f.js\"],\"default\"]\n3:I[27657,[\"/_next/static/chunks/102f894cc892994d.js\",\"/_next/static/chunks/417032eeb2cd875f.js\"],\"default\"]\n4:I[56978,[\"/_next/static/chunks/102f894cc892994d.js\",\"/_next/static/chunks/417032eeb2cd875f.js\"],\"OutletBoundary\"]\n5:\"$Sreact.suspense\"\n7:I[56978,[\"/_next/static/chunks/102f894cc892994d.js\",\"/_next/static/chunks/417032eeb2cd875f.js\"],\"ViewportBoundary\"]\n9:I[56978,[\"/_next/static/chunks/102f894cc892994d.js\",\"/_next/static/chunks/417032eeb2cd875f.js\"],\"MetadataBoundary\"]\nb:I[30687,[\"/_next/static/chunks/102f894cc892994d.js\",\"/_next/static/chunks/417032eeb2cd875f.js\"],\"default\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"PR51g0pS7Wp0zLzu2q6mQ\",\"c\":[\"\",\"_global-error\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"__PAGE__\",{}]}],[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"html\",null,{\"id\":\"__next_error__\",\"children\":[[\"$\",\"head\",null,{\"children\":[\"$\",\"title\",null,{\"children\":\"500: Internal Server Error.\"}]}],[\"$\",\"body\",null,{\"children\":[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"style\":{\"lineHeight\":\"48px\"},\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}\\n@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"paddingRight\":23,\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\"},\"children\":\"500\"}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"28px\"},\"children\":\"Internal Server Error.\"}]}]]}]}]}]]}],[[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/102f894cc892994d.js\",\"async\":true,\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-1\",{\"src\":\"/_next/static/chunks/417032eeb2cd875f.js\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"$L4\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@6\"}]}]]}],{},null,false,false]},null,false,false],[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$L7\",null,{\"children\":\"$L8\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$L9\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.Metadata\",\"children\":\"$La\"}]}]}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$b\",\"$undefined\"],\"S\":true}\n"])</script><script>self.__next_f.push([1,"8:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"6:null\na:[]\n"])</script></body></html>
1
+ <!DOCTYPE html><!--UA_86bJ_tNIyDXr_i0gK6--><html id="__next_error__"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/d878b929b21636c4.js"/><script src="/_next/static/chunks/f70f563804550a9c.js" async=""></script><script src="/_next/static/chunks/43d761df92da7cb6.js" async=""></script><script src="/_next/static/chunks/e281719dbabcca1d.js" async=""></script><script src="/_next/static/chunks/9e56d1f8f4d7adcb.js" async=""></script><script src="/_next/static/chunks/turbopack-768a6a8b9db952e0.js" async=""></script><script src="/_next/static/chunks/102f894cc892994d.js" async=""></script><script src="/_next/static/chunks/417032eeb2cd875f.js" async=""></script><meta name="next-size-adjust" content=""/><title>500: Internal Server Error.</title><script src="/_next/static/chunks/a6dad97d9634a72d.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div style="line-height:48px"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}
2
+ @media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">500</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">Internal Server Error.</h2></div></div></div><!--$--><!--/$--><script src="/_next/static/chunks/d878b929b21636c4.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[57043,[\"/_next/static/chunks/102f894cc892994d.js\",\"/_next/static/chunks/417032eeb2cd875f.js\"],\"default\"]\n3:I[27657,[\"/_next/static/chunks/102f894cc892994d.js\",\"/_next/static/chunks/417032eeb2cd875f.js\"],\"default\"]\n4:I[56978,[\"/_next/static/chunks/102f894cc892994d.js\",\"/_next/static/chunks/417032eeb2cd875f.js\"],\"OutletBoundary\"]\n5:\"$Sreact.suspense\"\n7:I[56978,[\"/_next/static/chunks/102f894cc892994d.js\",\"/_next/static/chunks/417032eeb2cd875f.js\"],\"ViewportBoundary\"]\n9:I[56978,[\"/_next/static/chunks/102f894cc892994d.js\",\"/_next/static/chunks/417032eeb2cd875f.js\"],\"MetadataBoundary\"]\nb:I[30687,[\"/_next/static/chunks/102f894cc892994d.js\",\"/_next/static/chunks/417032eeb2cd875f.js\"],\"default\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"UA_86bJ-tNIyDXr-i0gK6\",\"c\":[\"\",\"_global-error\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"__PAGE__\",{}]}],[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"html\",null,{\"id\":\"__next_error__\",\"children\":[[\"$\",\"head\",null,{\"children\":[\"$\",\"title\",null,{\"children\":\"500: Internal Server Error.\"}]}],[\"$\",\"body\",null,{\"children\":[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"style\":{\"lineHeight\":\"48px\"},\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}\\n@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"paddingRight\":23,\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\"},\"children\":\"500\"}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"28px\"},\"children\":\"Internal Server Error.\"}]}]]}]}]}]]}],[[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/102f894cc892994d.js\",\"async\":true,\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-1\",{\"src\":\"/_next/static/chunks/417032eeb2cd875f.js\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"$L4\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@6\"}]}]]}],{},null,false,false]},null,false,false],[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$L7\",null,{\"children\":\"$L8\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$L9\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.Metadata\",\"children\":\"$La\"}]}]}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$b\",\"$undefined\"],\"S\":true}\n"])</script><script>self.__next_f.push([1,"8:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"6:null\na:[]\n"])</script></body></html>
@@ -99,6 +99,8 @@ export function registerAdminRoutes(app, deps) {
99
99
  options.source = req.query.source;
100
100
  if (req.query.firewallResult)
101
101
  options.firewallResult = req.query.firewallResult;
102
+ if (req.query.operation)
103
+ options.operation = req.query.operation;
102
104
  if (req.query.limit)
103
105
  options.limit = parseInt(req.query.limit, 10);
104
106
  if (req.query.project)
@@ -587,7 +587,10 @@ export function registerMemoryRoutes(app, deps) {
587
587
  }), (req, res) => {
588
588
  try {
589
589
  const id = parseInt(req.params.id, 10);
590
- const success = deleteMemory(id);
590
+ // Attribute the dashboard delete so it lands on the provenance ledger
591
+ // (the primary human-initiated delete — the source-less exemption is only
592
+ // for internal consolidate/merge machinery).
593
+ const success = deleteMemory(id, { type: 'api', identifier: `dashboard:memory-delete:${id}` });
591
594
  if (!success) {
592
595
  return res.status(404).json({ error: 'Memory not found' });
593
596
  }
@@ -1235,7 +1238,7 @@ export function registerMemoryRoutes(app, deps) {
1235
1238
  const db = getDatabase();
1236
1239
  db.prepare(`INSERT INTO quarantine (original_title, original_content, source_type, source_identifier, reason, project, status, created_at)
1237
1240
  VALUES (?, ?, ?, ?, ?, ?, 'pending', ?)`).run(memory.title, memory.content, 'dashboard', 'brain-control', req.body.reason || 'Manually quarantined from Brain dashboard', memory.project || null, new Date().toISOString());
1238
- deleteMemory(id);
1241
+ deleteMemory(id, { type: 'api', identifier: `dashboard:quarantine-delete:${id}` });
1239
1242
  res.json({ success: true, quarantined: id });
1240
1243
  }
1241
1244
  catch (error) {
@@ -187,6 +187,7 @@ export function handleV1Scan(req, res) {
187
187
  trust_score: 0,
188
188
  sensitivity_level: 'RESTRICTED',
189
189
  firewall_result: 'BLOCK',
190
+ operation: 'write',
190
191
  anomaly_score: 0.5,
191
192
  threat_indicators: '["config_tampering"]',
192
193
  blocked_patterns: '[]',
package/dist/cloud/cli.js CHANGED
@@ -1,4 +1,4 @@
1
- import { getCloudConfig, setCloudConfig, getCloudSyncControls, setCloudSyncControls, getDefenceMode, setDefenceMode, getVerifyConfig, setVerifyConfig, getReviewCopilotConfig, getOpenClawAutoMemory, setOpenClawAutoMemory, isProactiveRecallEnabled, setProactiveRecall, restore410Defaults, getRankerConfig, setRankerConfig, getToolResponseScanConfig, setToolResponseScanConfig, } from './config.js';
1
+ import { getCloudConfig, setCloudConfig, getCloudSyncControls, setCloudSyncControls, getDefenceMode, setDefenceMode, getVerifyConfig, setVerifyConfig, getReviewCopilotConfig, getOpenClawAutoMemory, setOpenClawAutoMemory, isProactiveRecallEnabled, setProactiveRecall, restore410Defaults, getRankerConfig, setRankerConfig, getToolResponseScanConfig, setToolResponseScanConfig, isRevokeBySourceEnabled, setRevokeBySourceEnabled, } from './config.js';
2
2
  const VALID_RANKER_ENGINES = ['rrf', 'legacy'];
3
3
  import { syncAllGraphToCloud } from './graph-sync.js';
4
4
  import { syncAllMemoriesToCloud } from './memory-sync.js';
@@ -22,6 +22,7 @@ export function handleCloudConfig(args) {
22
22
  console.log('\nShieldCortex Configuration:');
23
23
  console.log(` Defence Mode: ${mode}`);
24
24
  console.log(` Tool-Output Firewall: ${toolFirewall.scanToolResponses ? toolFirewall.toolResponseMode : 'Off'}`);
25
+ console.log(` Revoke-by-source: ${isRevokeBySourceEnabled() ? 'Enabled (destructive)' : 'Disabled (default)'}`);
25
26
  console.log(` Cloud Enabled: ${config.cloudEnabled ? 'Yes' : 'No'}`);
26
27
  console.log(` API Key: ${config.cloudApiKey ? config.cloudApiKey.substring(0, 12) + '...' : 'Not set'}`);
27
28
  console.log(` Base URL: ${config.cloudBaseUrl}`);
@@ -210,6 +211,16 @@ export function handleCloudConfig(args) {
210
211
  console.log('Tool-output firewall enabled (scanning on).');
211
212
  changed = true;
212
213
  }
214
+ if (args.includes('--allow-revoke-by-source')) {
215
+ setRevokeBySourceEnabled(true);
216
+ console.log('Revoke-by-source ENABLED. `forget --fromSource` can now bulk-delete a source\'s memories (trust-hierarchy ACL still applies). Disable again with --disallow-revoke-by-source when done.');
217
+ changed = true;
218
+ }
219
+ if (args.includes('--disallow-revoke-by-source')) {
220
+ setRevokeBySourceEnabled(false);
221
+ console.log('Revoke-by-source disabled (default).');
222
+ changed = true;
223
+ }
213
224
  if (args.includes('--upsell-mute')) {
214
225
  setUpsellState({ proMuted: true });
215
226
  console.log('Pro upsell muted. Re-enable with --upsell-unmute.');
@@ -238,6 +249,7 @@ export function handleCloudConfig(args) {
238
249
  console.log(' --tool-firewall-enforce Redact/withhold threatening tool output before the agent sees it');
239
250
  console.log(' --tool-firewall-advisory Log tool-output threats but deliver intact (default)');
240
251
  console.log(' --tool-firewall-off / --tool-firewall-on Disable / enable tool-output scanning');
252
+ console.log(' --allow-revoke-by-source / --disallow-revoke-by-source Enable/disable destructive forget --fromSource (default: disabled)');
241
253
  console.log(' --restore-4.10-defaults Restore pre-v4.11.0 defaults (recall on, strict interceptor, minimal preamble)');
242
254
  console.log(' --upsell-mute Suppress the Pro upsell footer in doctor');
243
255
  console.log(' --upsell-unmute Allow the Pro upsell footer to surface again');
@@ -191,6 +191,16 @@ export declare function getToolResponseScanConfig(): ToolResponseScanConfig;
191
191
  * Persists tool response scanning config.
192
192
  */
193
193
  export declare function setToolResponseScanConfig(updates: Partial<ToolResponseScanConfig>): void;
194
+ /**
195
+ * revoke-by-source (bulk delete all memories from a source) is a destructive
196
+ * mass-delete primitive. Because a prompt-injection adversary runs AS the agent
197
+ * at the agent's own trust, no in-band (trust) check can distinguish "the human
198
+ * asked" from "an injection asked". So it is gated OFF by default and can only
199
+ * be enabled by an out-of-band human action (editing config / the CLI flag) that
200
+ * a hijacked agent cannot perform.
201
+ */
202
+ export declare function isRevokeBySourceEnabled(): boolean;
203
+ export declare function setRevokeBySourceEnabled(enabled: boolean): void;
194
204
  /**
195
205
  * Returns a stable UUID for this machine.
196
206
  * Generates and persists on first call; reads from config thereafter.
@@ -938,6 +938,21 @@ export function setToolResponseScanConfig(updates) {
938
938
  raw.toolResponseMode = updates.toolResponseMode;
939
939
  });
940
940
  }
941
+ // ── Revoke-by-source gate ─────────────────────────────
942
+ /**
943
+ * revoke-by-source (bulk delete all memories from a source) is a destructive
944
+ * mass-delete primitive. Because a prompt-injection adversary runs AS the agent
945
+ * at the agent's own trust, no in-band (trust) check can distinguish "the human
946
+ * asked" from "an injection asked". So it is gated OFF by default and can only
947
+ * be enabled by an out-of-band human action (editing config / the CLI flag) that
948
+ * a hijacked agent cannot perform.
949
+ */
950
+ export function isRevokeBySourceEnabled() {
951
+ return readRawConfig().allowRevokeBySource === true;
952
+ }
953
+ export function setRevokeBySourceEnabled(enabled) {
954
+ mutateRawConfig((raw) => { raw.allowRevokeBySource = enabled; });
955
+ }
941
956
  // ── Device Identity ────────────────────────────────────
942
957
  /**
943
958
  * Returns a stable UUID for this machine.
@@ -36,6 +36,7 @@ export function getInlineSchema() {
36
36
  trust_score REAL DEFAULT 1.0,
37
37
  sensitivity_level TEXT DEFAULT 'INTERNAL',
38
38
  source TEXT DEFAULT 'user:direct',
39
+ content_hash TEXT,
39
40
  status TEXT DEFAULT 'active' CHECK(status IN ('active', 'archived', 'suppressed', 'canonical')),
40
41
  pinned INTEGER DEFAULT 0,
41
42
  reviewed_at TIMESTAMP,
@@ -84,6 +85,8 @@ export function getInlineSchema() {
84
85
  CREATE INDEX IF NOT EXISTS idx_memories_decayed_score ON memories(decayed_score DESC);
85
86
  CREATE INDEX IF NOT EXISTS idx_memories_last_accessed ON memories(last_accessed DESC);
86
87
  CREATE INDEX IF NOT EXISTS idx_memories_updated ON memories(updated_at DESC);
88
+ CREATE INDEX IF NOT EXISTS idx_memories_source ON memories(source);
89
+ CREATE INDEX IF NOT EXISTS idx_memories_content_hash ON memories(content_hash);
87
90
 
88
91
  CREATE TABLE IF NOT EXISTS sessions (
89
92
  id INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -168,6 +171,8 @@ export function getInlineSchema() {
168
171
  trust_score REAL NOT NULL,
169
172
  sensitivity_level TEXT NOT NULL DEFAULT 'INTERNAL',
170
173
  firewall_result TEXT NOT NULL CHECK(firewall_result IN ('ALLOW', 'BLOCK', 'QUARANTINE')),
174
+ operation TEXT,
175
+ content_hash TEXT,
171
176
  anomaly_score REAL DEFAULT 0.0,
172
177
  threat_indicators TEXT DEFAULT '[]',
173
178
  blocked_patterns TEXT DEFAULT '[]',
@@ -182,6 +187,7 @@ export function getInlineSchema() {
182
187
  CREATE INDEX IF NOT EXISTS idx_audit_result ON defence_audit(firewall_result);
183
188
  CREATE INDEX IF NOT EXISTS idx_audit_source ON defence_audit(source_type);
184
189
  CREATE INDEX IF NOT EXISTS idx_audit_project ON defence_audit(project);
190
+ CREATE INDEX IF NOT EXISTS idx_audit_operation ON defence_audit(operation);
185
191
 
186
192
  -- Cumulative audit aggregate (single row, id=1) — retention rollup target.
187
193
  -- See schema.sql for the rationale.
@@ -750,4 +750,38 @@ export function runMigrations(database) {
750
750
  catch (err) {
751
751
  logIfUnexpectedDdlError(err, 'mcp_tool_hashes');
752
752
  }
753
+ // Migration: provenance ledger (v4.39.0) — add an `operation` discriminator
754
+ // (read/write/delete) and a `content_hash` (write-time tamper-evidence) to
755
+ // defence_audit, a `content_hash` to memories, and an index on memories.source
756
+ // for revoke-by-source. Existing rows keep operation/content_hash NULL (legacy,
757
+ // unclassifiable). Fresh installs get these from schema.sql / inline-schema.ts.
758
+ try {
759
+ const auditCols = database.prepare("PRAGMA table_info(defence_audit)").all();
760
+ if (auditCols.length > 0) {
761
+ const auditColNames = new Set(auditCols.map((c) => c.name));
762
+ if (!auditColNames.has('operation')) {
763
+ database.exec('ALTER TABLE defence_audit ADD COLUMN operation TEXT');
764
+ }
765
+ if (!auditColNames.has('content_hash')) {
766
+ database.exec('ALTER TABLE defence_audit ADD COLUMN content_hash TEXT');
767
+ }
768
+ }
769
+ }
770
+ catch (err) {
771
+ logIfUnexpectedDdlError(err, 'defence_audit provenance columns (operation, content_hash)');
772
+ }
773
+ if (!columnNames.has('content_hash')) {
774
+ database.exec('ALTER TABLE memories ADD COLUMN content_hash TEXT');
775
+ }
776
+ // Indexes in an unconditional, self-healing block: CREATE INDEX IF NOT EXISTS
777
+ // no-ops if the column already had its index, and back-fills it if the column
778
+ // exists without it (e.g. a column added by a prior partial run).
779
+ try {
780
+ database.exec('CREATE INDEX IF NOT EXISTS idx_audit_operation ON defence_audit(operation)');
781
+ database.exec('CREATE INDEX IF NOT EXISTS idx_memories_content_hash ON memories(content_hash)');
782
+ database.exec('CREATE INDEX IF NOT EXISTS idx_memories_source ON memories(source)');
783
+ }
784
+ catch (err) {
785
+ logIfUnexpectedDdlError(err, 'provenance ledger indexes (audit operation, memories content_hash/source)');
786
+ }
753
787
  }
@@ -24,6 +24,7 @@ CREATE TABLE IF NOT EXISTS memories (
24
24
  trust_score REAL DEFAULT 1.0,
25
25
  sensitivity_level TEXT DEFAULT 'INTERNAL',
26
26
  source TEXT DEFAULT 'user:direct',
27
+ content_hash TEXT,
27
28
  status TEXT DEFAULT 'active' CHECK(status IN ('active', 'archived', 'suppressed', 'canonical')),
28
29
  pinned INTEGER DEFAULT 0,
29
30
  reviewed_at TIMESTAMP,
@@ -85,6 +86,8 @@ CREATE INDEX IF NOT EXISTS idx_memories_updated ON memories(updated_at DESC);
85
86
  CREATE INDEX IF NOT EXISTS idx_memories_status ON memories(status);
86
87
  CREATE INDEX IF NOT EXISTS idx_memories_pinned ON memories(pinned DESC);
87
88
  CREATE INDEX IF NOT EXISTS idx_memories_source_kind ON memories(source_kind);
89
+ CREATE INDEX IF NOT EXISTS idx_memories_source ON memories(source);
90
+ CREATE INDEX IF NOT EXISTS idx_memories_content_hash ON memories(content_hash);
88
91
 
89
92
  -- Session tracking for consolidation
90
93
  CREATE TABLE IF NOT EXISTS sessions (
@@ -214,6 +217,8 @@ CREATE TABLE IF NOT EXISTS defence_audit (
214
217
  trust_score REAL NOT NULL,
215
218
  sensitivity_level TEXT NOT NULL DEFAULT 'INTERNAL',
216
219
  firewall_result TEXT NOT NULL CHECK(firewall_result IN ('ALLOW', 'BLOCK', 'QUARANTINE')),
220
+ operation TEXT, -- provenance ledger: 'read' | 'write' | 'delete' (NULL on legacy rows)
221
+ content_hash TEXT, -- SHA-256 of content at write time (tamper-evidence)
217
222
  anomaly_score REAL DEFAULT 0.0,
218
223
  threat_indicators TEXT DEFAULT '[]', -- JSON array of ThreatIndicator strings
219
224
  blocked_patterns TEXT DEFAULT '[]', -- JSON array of matched patterns
@@ -228,6 +233,7 @@ CREATE INDEX IF NOT EXISTS idx_audit_timestamp ON defence_audit(timestamp DESC);
228
233
  CREATE INDEX IF NOT EXISTS idx_audit_result ON defence_audit(firewall_result);
229
234
  CREATE INDEX IF NOT EXISTS idx_audit_source ON defence_audit(source_type);
230
235
  CREATE INDEX IF NOT EXISTS idx_audit_project ON defence_audit(project);
236
+ CREATE INDEX IF NOT EXISTS idx_audit_operation ON defence_audit(operation);
231
237
 
232
238
  -- Defence: cumulative audit aggregate (single row, id=1). Retention purges roll
233
239
  -- the to-be-deleted rows' lifetime-stat contributions into this row BEFORE
@@ -15,12 +15,12 @@ export function logAudit(entry) {
15
15
  const stmt = db.prepare(`
16
16
  INSERT INTO defence_audit (
17
17
  memory_id, project, timestamp, source_type, source_identifier,
18
- trust_score, sensitivity_level, firewall_result,
18
+ trust_score, sensitivity_level, firewall_result, operation, content_hash,
19
19
  anomaly_score, threat_indicators, blocked_patterns,
20
20
  reason, fragmentation_score, pipeline_duration_ms
21
21
  ) VALUES (
22
22
  @memory_id, @project, @timestamp, @source_type, @source_identifier,
23
- @trust_score, @sensitivity_level, @firewall_result,
23
+ @trust_score, @sensitivity_level, @firewall_result, @operation, @content_hash,
24
24
  @anomaly_score, @threat_indicators, @blocked_patterns,
25
25
  @reason, @fragmentation_score, @pipeline_duration_ms
26
26
  )
@@ -34,6 +34,8 @@ export function logAudit(entry) {
34
34
  trust_score: entry.trust_score,
35
35
  sensitivity_level: entry.sensitivity_level,
36
36
  firewall_result: entry.firewall_result,
37
+ operation: entry.operation ?? null,
38
+ content_hash: entry.content_hash ?? null,
37
39
  anomaly_score: entry.anomaly_score ?? 0,
38
40
  threat_indicators: entry.threat_indicators ?? '[]',
39
41
  blocked_patterns: entry.blocked_patterns ?? '[]',
@@ -21,7 +21,7 @@ export interface AgentTimelinePoint {
21
21
  export interface AuditQueryOptions {
22
22
  startTime?: string;
23
23
  endTime?: string;
24
- operation?: 'write' | 'read' | 'delete' | 'update';
24
+ operation?: 'write' | 'read' | 'delete' | 'update' | 'revoke';
25
25
  source?: string;
26
26
  firewallResult?: FirewallResult;
27
27
  memoryId?: number;
@@ -22,6 +22,10 @@ export function queryAuditLogs(options = {}) {
22
22
  conditions.push('da.firewall_result = @firewallResult');
23
23
  params.firewallResult = options.firewallResult;
24
24
  }
25
+ if (options.operation) {
26
+ conditions.push('da.operation = @operation');
27
+ params.operation = options.operation;
28
+ }
25
29
  if (options.source) {
26
30
  conditions.push('da.source_type = @source');
27
31
  params.source = options.source;
@@ -140,22 +140,32 @@ export function purgeAuditUnderSizePressure(options = {}) {
140
140
  const total = db.prepare('SELECT COUNT(*) AS c FROM defence_audit').get().c;
141
141
  if (total <= maxRows)
142
142
  return 0;
143
- // Trim down to the cap by deleting the OLDEST rows. Find the cutoff id: keep
144
- // the newest `maxRows` by timestamp, purge everything older.
145
- const cutoffRow = db.prepare(`
146
- SELECT timestamp FROM defence_audit
147
- ORDER BY timestamp DESC
148
- LIMIT 1 OFFSET ?
149
- `).get(maxRows);
150
- if (!cutoffRow)
143
+ const over = total - maxRows;
144
+ // Forensic-aware eviction: trim the `over` oldest rows, but evict
145
+ // LOW-VALUE provenance rows first (ALLOW reads/deletes — the high-volume,
146
+ // low-forensic-value entries) and only fall back to threat rows
147
+ // (BLOCK/QUARANTINE, or anything with threat_indicators) once the low-value
148
+ // rows are exhausted. Otherwise a flood of routine reads would push the
149
+ // oldest injection/credential-leak records out from under the row cap.
150
+ const ids = db.prepare(`
151
+ SELECT id FROM defence_audit
152
+ ORDER BY
153
+ CASE WHEN firewall_result = 'ALLOW'
154
+ AND operation IN ('read', 'delete')
155
+ AND (threat_indicators IS NULL OR threat_indicators IN ('', '[]'))
156
+ THEN 0 ELSE 1 END ASC,
157
+ timestamp ASC
158
+ LIMIT ?
159
+ `).all(over).map((r) => r.id);
160
+ if (ids.length === 0)
151
161
  return 0;
152
- const where = 'timestamp <= ?';
153
- const params = [cutoffRow.timestamp];
154
- const delta = computeDelta(where, params);
162
+ const placeholders = ids.map(() => '?').join(',');
163
+ const where = `id IN (${placeholders})`;
164
+ const delta = computeDelta(where, ids);
155
165
  if (delta.total_scans === 0)
156
166
  return 0;
157
167
  rollIntoAggregate(delta);
158
- const res = db.prepare(`DELETE FROM defence_audit WHERE ${where}`).run(...params);
168
+ const res = db.prepare(`DELETE FROM defence_audit WHERE ${where}`).run(...ids);
159
169
  return Number(res.changes ?? 0);
160
170
  })();
161
171
  }
@@ -19,6 +19,7 @@ export function logIronDomeAudit(event) {
19
19
  trust_score: 0,
20
20
  sensitivity_level: 'PUBLIC',
21
21
  firewall_result: event.allowed ? 'ALLOW' : 'BLOCK',
22
+ operation: null, // iron-dome kill-switch / defence event, not a memory read/write/delete
22
23
  anomaly_score: 0,
23
24
  threat_indicators: '[]',
24
25
  blocked_patterns: '[]',
@@ -11,7 +11,7 @@ import { analyzeFirewall } from './firewall/index.js';
11
11
  import { classifySensitivity } from './sensitivity/index.js';
12
12
  import { analyzeFragmentation } from './fragmentation/index.js';
13
13
  import { scanForCredentials } from './credential-leak/index.js';
14
- import { logAudit } from './audit/index.js';
14
+ import { logAudit, createContentHash } from './audit/index.js';
15
15
  import { persistEvent } from '../api/events.js';
16
16
  import { syncToCloud } from '../cloud/sync.js';
17
17
  import { syncQuarantineToCloud } from '../cloud/quarantine-sync.js';
@@ -202,6 +202,8 @@ export function runDefencePipeline(content, title, source, config, project) {
202
202
  trust_score: trust.score,
203
203
  sensitivity_level: sensitivity.level,
204
204
  firewall_result: firewall.result,
205
+ operation: 'write',
206
+ content_hash: createContentHash(content),
205
207
  anomaly_score: firewall.anomalyScore,
206
208
  threat_indicators: JSON.stringify(firewall.threatIndicators),
207
209
  blocked_patterns: JSON.stringify(firewall.blockedPatterns),
@@ -283,6 +285,7 @@ export function runDefencePipeline(content, title, source, config, project) {
283
285
  trust_score: 0,
284
286
  sensitivity_level: 'RESTRICTED',
285
287
  firewall_result: 'BLOCK',
288
+ operation: 'write',
286
289
  anomaly_score: 1.0,
287
290
  threat_indicators: '["pipeline_error"]',
288
291
  blocked_patterns: '[]',
@@ -250,6 +250,7 @@ export function scanToolResponse(toolName, content, mode) {
250
250
  trust_score: 0.5,
251
251
  sensitivity_level: (credentials.leaked || decodedCredentialLeak) ? 'CONFIDENTIAL' : 'PUBLIC',
252
252
  firewall_result: firewallResult,
253
+ operation: 'read',
253
254
  anomaly_score: anomalyScore,
254
255
  threat_indicators: JSON.stringify(threatIndicators),
255
256
  blocked_patterns: JSON.stringify(blockedPatterns),
@@ -22,7 +22,4 @@ export interface AccessCheckMemory {
22
22
  source?: string | null;
23
23
  sensitivity_level?: string | null;
24
24
  }
25
- /**
26
- * Check whether a source has access to a memory for a given operation.
27
- */
28
- export declare function checkAccess(memory: AccessCheckMemory, source: DefenceSource, operation: 'read' | 'write' | 'delete'): AccessPolicy;
25
+ export declare function checkAccess(memory: AccessCheckMemory, source: DefenceSource, operation: 'read' | 'write' | 'delete' | 'revoke'): AccessPolicy;
@@ -12,6 +12,13 @@ import { scoreSource } from './source-scorer.js';
12
12
  /**
13
13
  * Check whether a source has access to a memory for a given operation.
14
14
  */
15
+ /** Parse a stored "type:identifier" source string back into a DefenceSource. */
16
+ function parseStoredSource(stored) {
17
+ const i = stored.indexOf(':');
18
+ if (i === -1)
19
+ return { type: 'agent', identifier: stored }; // unknown shape → low-trust agent
20
+ return { type: stored.slice(0, i), identifier: stored.slice(i + 1) };
21
+ }
15
22
  export function checkAccess(memory, source, operation) {
16
23
  const trust = scoreSource(source).score;
17
24
  const memorySource = memory.source || '__system:unattributed';
@@ -50,6 +57,31 @@ export function checkAccess(memory, source, operation) {
50
57
  }
51
58
  return deny('Can only delete own memories (trust ≥0.5)');
52
59
  }
60
+ if (operation === 'revoke') {
61
+ // Trust-hierarchy revoke (revoke-by-source remediation): own cleanup, OR a
62
+ // high-trust caller may purge a STRICTLY lower-trust source's memories.
63
+ // Equal/higher-trust targets are protected, so a 0.9 agent can never revoke
64
+ // user:direct (1.0). Single-row 'delete' stays own-only — this override is
65
+ // reachable only through the explicit revoke path.
66
+ if (isOwner && trust >= 0.5) {
67
+ return { canRead: true, canWrite: false, canDelete: true, writeRequiresQuarantine: false, reason: 'Owner revoke' };
68
+ }
69
+ // Fail-safe: never mass-revoke unattributed / unclassifiable memories. They
70
+ // have no clear owner to outrank, and a 0-trust target would be outranked by
71
+ // any caller — so a high-trust caller must NOT be able to sweep null-source
72
+ // rows by source.
73
+ if (!memory.source || memorySource === '__system:unattributed') {
74
+ return deny('Revoke denied: unattributed memories cannot be revoked by source');
75
+ }
76
+ const targetTrust = scoreSource(parseStoredSource(memorySource)).score;
77
+ if (targetTrust > 0 && trust >= 0.7 && trust > targetTrust) {
78
+ return {
79
+ canRead: true, canWrite: false, canDelete: true, writeRequiresQuarantine: false,
80
+ reason: `Trust-hierarchy revoke (caller ${trust.toFixed(2)} > target ${targetTrust.toFixed(2)})`,
81
+ };
82
+ }
83
+ return deny('Revoke denied: must own the source or outrank it (trust ≥0.7 and strictly > a known target source trust)');
84
+ }
53
85
  return deny('Unknown operation');
54
86
  }
55
87
  function allow(reason) {
@@ -33,6 +33,7 @@ export function resolveToolSource(declaredSource, options) {
33
33
  trust_score: ceilingScore,
34
34
  sensitivity_level: 'PUBLIC',
35
35
  firewall_result: 'BLOCK',
36
+ operation: null, // source-resolution meta-event, not a memory read/write/delete
36
37
  anomaly_score: 0,
37
38
  threat_indicators: JSON.stringify(['privilege_escalation']),
38
39
  blocked_patterns: '[]',
@@ -62,6 +63,7 @@ export function resolveToolSource(declaredSource, options) {
62
63
  trust_score: 0,
63
64
  sensitivity_level: 'PUBLIC',
64
65
  firewall_result: 'ALLOW',
66
+ operation: null, // source-resolution meta-event, not a memory read/write/delete
65
67
  anomaly_score: 0,
66
68
  threat_indicators: '[]',
67
69
  blocked_patterns: '[]',
@@ -129,6 +129,8 @@ export interface QuarantineEntry {
129
129
  expires_at: string | null;
130
130
  audit_id: number | null;
131
131
  }
132
+ /** Operation that produced an audit row (provenance ledger discriminator). */
133
+ export type AuditOperation = 'write' | 'read' | 'delete' | 'update' | 'revoke';
132
134
  export interface AuditEntry {
133
135
  id: number;
134
136
  memory_id: number | null;
@@ -139,6 +141,14 @@ export interface AuditEntry {
139
141
  trust_score: number;
140
142
  sensitivity_level: string;
141
143
  firewall_result: FirewallResult;
144
+ /**
145
+ * The operation that produced this row. Required on every new emission so the
146
+ * ledger is queryable by read/write/delete; `null` only on legacy rows written
147
+ * before the provenance-ledger column existed.
148
+ */
149
+ operation: AuditOperation | null;
150
+ /** SHA-256 of the content at write time (tamper-evidence); null for read/delete rows. */
151
+ content_hash?: string | null;
142
152
  anomaly_score: number;
143
153
  threat_indicators: string;
144
154
  blocked_patterns: string;
@@ -27,6 +27,7 @@ import { jaccardSimilarity } from './similarity.js';
27
27
  import { emitMemoryAccessed, emitMemoryUpdated, persistEvent, } from '../api/events.js';
28
28
  import { createMemoryLink } from './links.js';
29
29
  import { runDefencePipeline } from '../defence/index.js';
30
+ import { createContentHash } from '../defence/audit/logger.js';
30
31
  // Enrichment text is recall-query / caller-derived (attacker-influenced); scan
31
32
  // it before persisting. Trust doesn't matter here (the row keeps its own) — we
32
33
  // only act on the firewall verdict, so a low-trust web source is fine.
@@ -207,13 +208,15 @@ export function enrichMemory(memoryId, newContext, contextType = 'access') {
207
208
  if (defenceResult.firewall.result !== 'ALLOW') {
208
209
  return { enriched: false, reason: `Enrichment blocked by defence: ${defenceResult.firewall.reason}` };
209
210
  }
210
- // Update memory
211
+ // Update memory (recompute content_hash — the integrity snapshot must track
212
+ // the enriched content, not the pre-enrichment original).
211
213
  db.prepare(`
212
214
  UPDATE memories
213
215
  SET content = ?,
216
+ content_hash = ?,
214
217
  last_accessed = CURRENT_TIMESTAMP
215
218
  WHERE id = ?
216
- `).run(newContent, memoryId);
219
+ `).run(newContent, createContentHash(newContent), memoryId);
217
220
  // Update cooldown timestamp
218
221
  enrichmentTimestamps.set(memoryId, now);
219
222
  // Emit update event for dashboard
@@ -5,7 +5,7 @@
5
5
  * Handles storage, retrieval, and management of memories.
6
6
  */
7
7
  import { Memory, MemoryInput, MemoryType, MemoryConfig } from './types.js';
8
- import type { DefenceSource } from '../defence/types.js';
8
+ import type { DefenceSource, AuditOperation } from '../defence/types.js';
9
9
  export declare const MAX_CONTENT_SIZE: number;
10
10
  export declare const UNATTRIBUTED_SOURCE: DefenceSource;
11
11
  /**
@@ -20,7 +20,21 @@ export declare function getLastTruncationInfo(): {
20
20
  * Convert database row to Memory object
21
21
  */
22
22
  export declare function rowToMemory(row: Record<string, unknown>): Memory;
23
- export declare function logAccessDenial(memoryId: number, source: DefenceSource, reason: string): void;
23
+ export declare function logAccessDenial(memoryId: number, source: DefenceSource, reason: string, operation?: AuditOperation): void;
24
+ /**
25
+ * Provenance ledger: record an ALLOWED read. Emitted ONCE per tool call (not per
26
+ * row) to keep the audit table bounded — recall returns up to 50 rows, so a
27
+ * per-row emit would flood it. memory_id carries the single id for single-target
28
+ * reads; the full id list (capped) goes in blocked_patterns for forensics.
29
+ */
30
+ export declare function logAllowedRead(source: DefenceSource, tool: string, memoryIds: number[], project?: string | null): void;
31
+ /**
32
+ * Provenance ledger: record an ALLOWED delete (one row per deleted memory).
33
+ * memory_id is NULL by design — the row is emitted after the DELETE, and the
34
+ * audit.memory_id FK is ON DELETE SET NULL, so a live reference can't survive.
35
+ * The deleted id is preserved in `reason` + `blocked_patterns` for forensics.
36
+ */
37
+ export declare function logAllowedDelete(memoryId: number, source: DefenceSource, project?: string | null, operation?: AuditOperation): void;
24
38
  /**
25
39
  * Error thrown when memory creation is paused
26
40
  */
@@ -51,7 +65,9 @@ export declare function mergeMemories(keptId: number, removedId: number, options
51
65
  /**
52
66
  * Delete a memory
53
67
  */
54
- export declare function deleteMemory(id: number, source?: DefenceSource): boolean;
68
+ export declare function deleteMemory(id: number, source?: DefenceSource, opts?: {
69
+ mode?: 'delete' | 'revoke';
70
+ }): boolean;
55
71
  /**
56
72
  * Get all memories for a project
57
73
  */