diff --git a/.changeset/paginate-cursor-clamp.md b/.changeset/paginate-cursor-clamp.md
new file mode 100644
index 00000000..963cd2f1
--- /dev/null
+++ b/.changeset/paginate-cursor-clamp.md
@@ -0,0 +1,8 @@
+---
+"@concile/query-engine": patch
+---
+
+`paginate` now clamps the client-supplied cursor to the query's own index range. A forged cursor
+(or one from a different query) could previously move the scan's start or end outside the range
+the query's `eq`/range constraints define, returning rows the query should never see. An
+out-of-range cursor now yields the first page or an empty one.
diff --git a/.changeset/storage-serve-headers.md b/.changeset/storage-serve-headers.md
new file mode 100644
index 00000000..c0823dc3
--- /dev/null
+++ b/.changeset/storage-serve-headers.md
@@ -0,0 +1,9 @@
+---
+"@concile/storage": patch
+---
+
+Files streamed from `/api/storage/:id` can no longer run script on the app's origin. Every
+response now sends `X-Content-Type-Options: nosniff`, and any type outside a small inline-safe
+allowlist (raster images, audio, video, `text/plain`, PDF) is served with
+`Content-Disposition: attachment`. Previously an uploader-chosen `text/html` or `image/svg+xml`
+content type was echoed back and rendered inline. `fetch()`, `
` and `