shieldcortex 4.37.0 → 4.39.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/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.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/read-guard.d.ts +45 -0
- package/dist/defence/trust/read-guard.js +76 -0
- package/dist/defence/trust/resolve-tool-source.js +2 -0
- package/dist/defence/types.d.ts +10 -0
- package/dist/memory/consolidate.d.ts +2 -1
- package/dist/memory/consolidate.js +7 -2
- package/dist/memory/lifecycle.js +5 -2
- package/dist/memory/store.d.ts +16 -2
- package/dist/memory/store.js +100 -6
- package/dist/server.js +25 -9
- package/dist/tools/context.d.ts +2 -0
- package/dist/tools/context.js +30 -5
- package/dist/tools/recall.d.ts +15 -0
- package/dist/tools/recall.js +39 -3
- package/package.json +1 -1
- /package/dashboard/.next/standalone/dashboard/.next/static/{Xdk3QuQEKommHIbMSem56 → LfTY3B6uX3j7zNwqqgvPG}/_buildManifest.js +0 -0
- /package/dashboard/.next/standalone/dashboard/.next/static/{Xdk3QuQEKommHIbMSem56 → LfTY3B6uX3j7zNwqqgvPG}/_clientMiddlewareManifest.json +0 -0
- /package/dashboard/.next/standalone/dashboard/.next/static/{Xdk3QuQEKommHIbMSem56 → LfTY3B6uX3j7zNwqqgvPG}/_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><!--LfTY3B6uX3j7zNwqqgvPG--><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\":\"LfTY3B6uX3j7zNwqqgvPG\",\"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) {
|
|
@@ -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 ?? '[]',
|
|
@@ -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),
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP read-path access guard.
|
|
3
|
+
*
|
|
4
|
+
* The `.mjs` prompt/session hooks already filter recalled rows before injecting
|
|
5
|
+
* them into the prompt. The MCP read TOOLS (`get_memory`, `get_related`,
|
|
6
|
+
* `get_context`, and `recall`) returned rows without applying the access-control
|
|
7
|
+
* engine consistently — so a low-trust / compromised caller could pull RESTRICTED
|
|
8
|
+
* or other-source memories verbatim. This guard closes that path by applying the
|
|
9
|
+
* SAME `checkAccess('read')` tiers the search path uses:
|
|
10
|
+
*
|
|
11
|
+
* - quarantined rows (trustScore === 0) are ALWAYS dropped (pending review);
|
|
12
|
+
* - when a caller source is present, rows the caller cannot read are dropped
|
|
13
|
+
* (RESTRICTED isolation below trust 0.7, own-only below 0.5);
|
|
14
|
+
* - owner / high-trust callers pass through in full (chosen policy — no content
|
|
15
|
+
* redaction on the MCP path; that is the prompt-hook surface's job).
|
|
16
|
+
*
|
|
17
|
+
* No source → only quarantined rows are dropped (callers that don't resolve an
|
|
18
|
+
* identity get no source-relative ACL). In practice the MCP server always
|
|
19
|
+
* resolves a source via resolveToolSource before calling the read tools.
|
|
20
|
+
*/
|
|
21
|
+
import type { DefenceSource } from '../types.js';
|
|
22
|
+
import type { Memory, ContextSummary } from '../../memory/types.js';
|
|
23
|
+
/** Filter recalled memories (camelCase Memory) to those the caller may read. */
|
|
24
|
+
export declare function guardReadMemories(memories: Memory[], source: DefenceSource | undefined): Memory[];
|
|
25
|
+
/**
|
|
26
|
+
* Filter raw snake_case DB rows (e.g. the export path's `SELECT *`) to those the
|
|
27
|
+
* caller may read. Same policy as guardReadMemories, different field casing.
|
|
28
|
+
*/
|
|
29
|
+
export declare function guardReadRows<T extends Record<string, unknown>>(rows: T[], source: DefenceSource | undefined): T[];
|
|
30
|
+
/**
|
|
31
|
+
* Sensitivity-only guard for SHARED-CONTEXT bootstrap surfaces (get_context,
|
|
32
|
+
* start_session, the memory:// resources, restore_context, detect_contradictions).
|
|
33
|
+
*
|
|
34
|
+
* These surfaces feed the prompt / a broadly-shared project summary, so they must
|
|
35
|
+
* NEVER surface RESTRICTED or quarantined rows to ANYONE (matching the .mjs
|
|
36
|
+
* prompt hooks) — but, unlike the per-caller fetch tools, they do NOT apply the
|
|
37
|
+
* source-relative own-only tier, so a low-trust subagent still receives the
|
|
38
|
+
* INTERNAL project context it legitimately needs. Credential isolation without
|
|
39
|
+
* the availability blackout.
|
|
40
|
+
*/
|
|
41
|
+
export declare function guardReadBySensitivity(memories: Memory[]): Memory[];
|
|
42
|
+
/** Apply the sensitivity guard to every memory list in a context summary. */
|
|
43
|
+
export declare function guardContextSummary(summary: ContextSummary): ContextSummary;
|
|
44
|
+
/** Guard a single memory; returns null if the caller may not read it. */
|
|
45
|
+
export declare function guardReadMemory(memory: Memory | null | undefined, source: DefenceSource | undefined): Memory | null;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP read-path access guard.
|
|
3
|
+
*
|
|
4
|
+
* The `.mjs` prompt/session hooks already filter recalled rows before injecting
|
|
5
|
+
* them into the prompt. The MCP read TOOLS (`get_memory`, `get_related`,
|
|
6
|
+
* `get_context`, and `recall`) returned rows without applying the access-control
|
|
7
|
+
* engine consistently — so a low-trust / compromised caller could pull RESTRICTED
|
|
8
|
+
* or other-source memories verbatim. This guard closes that path by applying the
|
|
9
|
+
* SAME `checkAccess('read')` tiers the search path uses:
|
|
10
|
+
*
|
|
11
|
+
* - quarantined rows (trustScore === 0) are ALWAYS dropped (pending review);
|
|
12
|
+
* - when a caller source is present, rows the caller cannot read are dropped
|
|
13
|
+
* (RESTRICTED isolation below trust 0.7, own-only below 0.5);
|
|
14
|
+
* - owner / high-trust callers pass through in full (chosen policy — no content
|
|
15
|
+
* redaction on the MCP path; that is the prompt-hook surface's job).
|
|
16
|
+
*
|
|
17
|
+
* No source → only quarantined rows are dropped (callers that don't resolve an
|
|
18
|
+
* identity get no source-relative ACL). In practice the MCP server always
|
|
19
|
+
* resolves a source via resolveToolSource before calling the read tools.
|
|
20
|
+
*/
|
|
21
|
+
import { checkAccess } from './access-control.js';
|
|
22
|
+
/**
|
|
23
|
+
* Core read decision, shared by the camelCase (Memory) and snake_case (raw row)
|
|
24
|
+
* guards so the policy lives in exactly one place.
|
|
25
|
+
*/
|
|
26
|
+
function callerCanRead(id, storedSource, sensitivityLevel, trustScore, source) {
|
|
27
|
+
// Quarantined memories are never surfaced through a normal read.
|
|
28
|
+
if (trustScore === 0)
|
|
29
|
+
return false;
|
|
30
|
+
// Without a caller identity we cannot make a source-relative decision;
|
|
31
|
+
// surface everything else (the server resolves a source in practice).
|
|
32
|
+
if (!source)
|
|
33
|
+
return true;
|
|
34
|
+
return checkAccess({ id, source: storedSource, sensitivity_level: sensitivityLevel }, source, 'read').canRead;
|
|
35
|
+
}
|
|
36
|
+
/** Filter recalled memories (camelCase Memory) to those the caller may read. */
|
|
37
|
+
export function guardReadMemories(memories, source) {
|
|
38
|
+
return memories.filter((m) => callerCanRead(m.id, m.source, m.sensitivityLevel, m.trustScore, source));
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Filter raw snake_case DB rows (e.g. the export path's `SELECT *`) to those the
|
|
42
|
+
* caller may read. Same policy as guardReadMemories, different field casing.
|
|
43
|
+
*/
|
|
44
|
+
export function guardReadRows(rows, source) {
|
|
45
|
+
return rows.filter((r) => callerCanRead(Number(r.id), r.source ?? null, r.sensitivity_level ?? null, Number(r.trust_score ?? 1), source));
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Sensitivity-only guard for SHARED-CONTEXT bootstrap surfaces (get_context,
|
|
49
|
+
* start_session, the memory:// resources, restore_context, detect_contradictions).
|
|
50
|
+
*
|
|
51
|
+
* These surfaces feed the prompt / a broadly-shared project summary, so they must
|
|
52
|
+
* NEVER surface RESTRICTED or quarantined rows to ANYONE (matching the .mjs
|
|
53
|
+
* prompt hooks) — but, unlike the per-caller fetch tools, they do NOT apply the
|
|
54
|
+
* source-relative own-only tier, so a low-trust subagent still receives the
|
|
55
|
+
* INTERNAL project context it legitimately needs. Credential isolation without
|
|
56
|
+
* the availability blackout.
|
|
57
|
+
*/
|
|
58
|
+
export function guardReadBySensitivity(memories) {
|
|
59
|
+
return memories.filter((m) => m.trustScore !== 0 && m.sensitivityLevel !== 'RESTRICTED');
|
|
60
|
+
}
|
|
61
|
+
/** Apply the sensitivity guard to every memory list in a context summary. */
|
|
62
|
+
export function guardContextSummary(summary) {
|
|
63
|
+
return {
|
|
64
|
+
...summary,
|
|
65
|
+
recentMemories: guardReadBySensitivity(summary.recentMemories),
|
|
66
|
+
keyDecisions: guardReadBySensitivity(summary.keyDecisions),
|
|
67
|
+
activePatterns: guardReadBySensitivity(summary.activePatterns),
|
|
68
|
+
pendingItems: guardReadBySensitivity(summary.pendingItems),
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/** Guard a single memory; returns null if the caller may not read it. */
|
|
72
|
+
export function guardReadMemory(memory, source) {
|
|
73
|
+
if (!memory)
|
|
74
|
+
return null;
|
|
75
|
+
return guardReadMemories([memory], source)[0] ?? null;
|
|
76
|
+
}
|
|
@@ -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';
|
|
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;
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* - Cleans up decayed/irrelevant memories
|
|
8
8
|
* - Merges similar memories to reduce redundancy
|
|
9
9
|
*/
|
|
10
|
+
import type { DefenceSource } from '../defence/types.js';
|
|
10
11
|
import { Memory, MemoryConfig, ConsolidationResult, ContextSummary } from './types.js';
|
|
11
12
|
/**
|
|
12
13
|
* Run full consolidation process
|
|
@@ -147,7 +148,7 @@ export declare function getSuggestedContext(currentContext: string, project?: st
|
|
|
147
148
|
/**
|
|
148
149
|
* Export memories as JSON (for backup/transfer)
|
|
149
150
|
*/
|
|
150
|
-
export declare function exportMemories(project?: string): string;
|
|
151
|
+
export declare function exportMemories(project?: string, source?: DefenceSource): string;
|
|
151
152
|
/**
|
|
152
153
|
* Import memories from JSON
|
|
153
154
|
*/
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import { getDatabase, withTransaction } from '../database/init.js';
|
|
11
11
|
import { expireQuarantineItems } from '../defence/quarantine/auto-expire.js';
|
|
12
|
+
import { guardReadRows } from '../defence/trust/read-guard.js';
|
|
12
13
|
import { DEFAULT_CONFIG, } from './types.js';
|
|
13
14
|
import { getMemoriesByType, getRecentMemories, promoteMemory, deleteMemory, searchMemories, getMemoryStats, updateDecayScores, addMemory, rowToMemory, } from './store.js';
|
|
14
15
|
import { processDecay, } from './decay.js';
|
|
@@ -794,7 +795,7 @@ export async function getSuggestedContext(currentContext, project, limit = 5) {
|
|
|
794
795
|
/**
|
|
795
796
|
* Export memories as JSON (for backup/transfer)
|
|
796
797
|
*/
|
|
797
|
-
export function exportMemories(project) {
|
|
798
|
+
export function exportMemories(project, source) {
|
|
798
799
|
const db = getDatabase();
|
|
799
800
|
let sql = 'SELECT * FROM memories';
|
|
800
801
|
const params = [];
|
|
@@ -804,7 +805,11 @@ export function exportMemories(project) {
|
|
|
804
805
|
}
|
|
805
806
|
sql += ' ORDER BY created_at ASC';
|
|
806
807
|
const rows = db.prepare(sql).all(...params);
|
|
807
|
-
|
|
808
|
+
// Read ACL: a bulk export is the sharpest exfil vector, so apply the same
|
|
809
|
+
// read guard as the per-tool paths — drop quarantined + rows the caller may
|
|
810
|
+
// not read (RESTRICTED isolation / own-only for low trust). With no caller
|
|
811
|
+
// source, only quarantined rows are dropped.
|
|
812
|
+
return JSON.stringify(guardReadRows(rows, source), null, 2);
|
|
808
813
|
}
|
|
809
814
|
/**
|
|
810
815
|
* Import memories from JSON
|
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): void;
|
|
24
38
|
/**
|
|
25
39
|
* Error thrown when memory creation is paused
|
|
26
40
|
*/
|