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.
- package/dashboard/.next/standalone/dashboard/.next/BUILD_ID +1 -1
- package/dashboard/.next/standalone/dashboard/.next/build-manifest.json +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.html +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/!KGRhc2hib2FyZCk/admin/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/!KGRhc2hib2FyZCk/admin.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/!KGRhc2hib2FyZCk/cloud/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/!KGRhc2hib2FyZCk/cloud.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/!KGRhc2hib2FyZCk/memory/capture/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/!KGRhc2hib2FyZCk/memory/capture.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/!KGRhc2hib2FyZCk/memory/graph/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/!KGRhc2hib2FyZCk/memory/graph.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/!KGRhc2hib2FyZCk/memory/recall/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/!KGRhc2hib2FyZCk/memory/recall.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/!KGRhc2hib2FyZCk/memory/replay/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/!KGRhc2hib2FyZCk/memory/replay.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/!KGRhc2hib2FyZCk/memory/review/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/!KGRhc2hib2FyZCk/memory/review.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/!KGRhc2hib2FyZCk/memory/timeline/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/!KGRhc2hib2FyZCk/memory/timeline.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/!KGRhc2hib2FyZCk/memory/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/!KGRhc2hib2FyZCk/overview/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/!KGRhc2hib2FyZCk/overview.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/!KGRhc2hib2FyZCk/protection/audit/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/!KGRhc2hib2FyZCk/protection/audit.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/!KGRhc2hib2FyZCk/protection/intercepts/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/!KGRhc2hib2FyZCk/protection/intercepts.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/!KGRhc2hib2FyZCk/protection/iron-dome/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/!KGRhc2hib2FyZCk/protection/iron-dome.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/!KGRhc2hib2FyZCk/protection/policies/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/!KGRhc2hib2FyZCk/protection/policies.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/!KGRhc2hib2FyZCk/protection/quarantine/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/!KGRhc2hib2FyZCk/protection/quarantine.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/!KGRhc2hib2FyZCk/protection/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/!KGRhc2hib2FyZCk/settings/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/!KGRhc2hib2FyZCk/settings.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/!KGRhc2hib2FyZCk/supply-chain/xray/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/!KGRhc2hib2FyZCk/supply-chain/xray.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/!KGRhc2hib2FyZCk/supply-chain.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/!KGRhc2hib2FyZCk/supply-chain/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/!KGRhc2hib2FyZCk/supply-chain.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/!KGRhc2hib2FyZCk/xray/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/!KGRhc2hib2FyZCk/xray.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/pages/404.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/pages/500.html +2 -2
- package/dist/api/routes/admin.js +2 -0
- package/dist/api/routes/memories.js +5 -2
- package/dist/api/visualization-server.js +1 -0
- package/dist/cloud/cli.js +13 -1
- package/dist/cloud/config.d.ts +10 -0
- package/dist/cloud/config.js +15 -0
- package/dist/database/inline-schema.js +6 -0
- package/dist/database/migrations.js +34 -0
- package/dist/database/schema.sql +6 -0
- package/dist/defence/audit/logger.js +4 -2
- package/dist/defence/audit/queries.d.ts +1 -1
- package/dist/defence/audit/queries.js +4 -0
- package/dist/defence/audit/retention.js +22 -12
- package/dist/defence/iron-dome/audit.js +1 -0
- package/dist/defence/pipeline.js +4 -1
- package/dist/defence/tool-response-scanner.js +1 -0
- package/dist/defence/trust/access-control.d.ts +1 -4
- package/dist/defence/trust/access-control.js +32 -0
- package/dist/defence/trust/resolve-tool-source.js +2 -0
- package/dist/defence/types.d.ts +10 -0
- package/dist/memory/lifecycle.js +5 -2
- package/dist/memory/store.d.ts +19 -3
- package/dist/memory/store.js +105 -9
- package/dist/server.js +9 -1
- package/dist/tools/context.js +15 -1
- package/dist/tools/forget.d.ts +3 -0
- package/dist/tools/forget.js +53 -1
- package/dist/tools/recall.js +9 -1
- package/package.json +1 -1
- /package/dashboard/.next/standalone/dashboard/.next/static/{PR51g0pS7Wp0zLzu2q6mQ → UA_86bJ-tNIyDXr-i0gK6}/_buildManifest.js +0 -0
- /package/dashboard/.next/standalone/dashboard/.next/static/{PR51g0pS7Wp0zLzu2q6mQ → UA_86bJ-tNIyDXr-i0gK6}/_clientMiddlewareManifest.json +0 -0
- /package/dashboard/.next/standalone/dashboard/.next/static/{PR51g0pS7Wp0zLzu2q6mQ → UA_86bJ-tNIyDXr-i0gK6}/_ssgManifest.js +0 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
<!DOCTYPE html><!--
|
|
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\":\"
|
|
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,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";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>
|
package/dist/api/routes/admin.js
CHANGED
|
@@ -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
|
-
|
|
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) {
|
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');
|
package/dist/cloud/config.d.ts
CHANGED
|
@@ -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.
|
package/dist/cloud/config.js
CHANGED
|
@@ -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
|
}
|
package/dist/database/schema.sql
CHANGED
|
@@ -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
|
-
|
|
144
|
-
// the
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
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
|
|
153
|
-
const
|
|
154
|
-
const delta = computeDelta(where,
|
|
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(...
|
|
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: '[]',
|
package/dist/defence/pipeline.js
CHANGED
|
@@ -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: '[]',
|
package/dist/defence/types.d.ts
CHANGED
|
@@ -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;
|
package/dist/memory/lifecycle.js
CHANGED
|
@@ -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
|
package/dist/memory/store.d.ts
CHANGED
|
@@ -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
|
|
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
|
*/
|