diff --git a/docs/stash-exports/2026-07-30-backend-migration/README.md b/docs/stash-exports/2026-07-30-backend-migration/README.md
new file mode 100644
index 0000000..c04394c
--- /dev/null
+++ b/docs/stash-exports/2026-07-30-backend-migration/README.md
@@ -0,0 +1,21 @@
+# Backend migration stash exports
+
+These patches preserve the three non-empty RipGuard stashes that existed before the 2026-07-30 backend migration. Each file is the verbatim output of `git stash show -p --binary --include-untracked` and retains blob IDs for `git apply --3way` recovery.
+
+None applied cleanly forward or in reverse to `origin/main` at `1dd284b`, so none was treated as empty or already landed.
+
+| Patch | Stash commit | First parent | Original message |
+| --- | --- | --- | --- |
+| `testnet-landing-polish-fd51ae9.patch` | `fd51ae94223aa486184b588a890a249d278f32ca` | `4c553dd1445820b2842eaad61853fe1d3791d651` | `WIP on testnet: 4c553dd visual: polish landing page fold` |
+| `testnet-client-providers-2623bb8.patch` | `2623bb8d39a76a80c5b9214251c5118365f3d2ac` | `1ea67c8eccc7d5603e8a3115348eb71ee06e960b` | `On testnet: testnet: ClientProviders ssr:false fix + untracked files` |
+| `exit-strategy-readme-14906e5.patch` | `14906e5646c3b45029333650e15111c2b1eb7b9f` | `83aa38e657a88356a456548c64d391ea17a2ac1e` | `WIP on feat/exit-strategy-lab: 97f1f5b Fix testnet vault visibility: use 2k block chunks on Base Sepolia` |
+
+## Recovery
+
+Start from the patch's first-parent commit when possible, then run:
+
+```sh
+git apply --3way path/to/export.patch
+```
+
+Review before committing. These patches predate the current multi-chain and Solana code and may need manual conflict resolution.
diff --git a/docs/stash-exports/2026-07-30-backend-migration/exit-strategy-readme-14906e5.patch b/docs/stash-exports/2026-07-30-backend-migration/exit-strategy-readme-14906e5.patch
new file mode 100644
index 0000000..f136f71
--- /dev/null
+++ b/docs/stash-exports/2026-07-30-backend-migration/exit-strategy-readme-14906e5.patch
@@ -0,0 +1,37 @@
+diff --git a/README.md b/README.md
+index ab57bd6..baa6b5b 100644
+--- a/README.md
++++ b/README.md
+@@ -34,21 +34,14 @@ Or set a custom schedule.
+
+ ## Architecture
+
+-The `RipGuardRouter` is a stateless, non-upgradeable wrapper around Sablier Lockup. It:
+-
+-- Pulls USDC from the user
+-- Creates a non-cancelable Sablier Lockup Linear stream
+-- Routes a 0.5% broker fee to the treasury via Sablier's native mechanism
+-- Never holds funds beyond a single transaction
+-- Has no admin functions, no owner, no pause
++RipGuard has no custom on-chain contract. The frontend calls the Sablier Lockup v2.0 contract directly — your USDC goes from your wallet into Sablier's immutable protocol. The 0.5% broker fee is collected via Sablier's native broker mechanism at stream creation time; RipGuard never holds your funds.
+
+ **On-chain contracts (Base Mainnet):**
+
+-- **RipGuardRouter**: [`packages/contracts/src/RipGuardRouter.sol`](packages/contracts/src/RipGuardRouter.sol)
+ - **Sablier Lockup**: [`0xb5D78DD3276325f5FAF3106Cc4Acc56E28e0Fe3B`](https://basescan.org/address/0xb5D78DD3276325f5FAF3106Cc4Acc56E28e0Fe3B) (Sablier Lockup v2.0)
+ - **USDC**: [`0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913`](https://basescan.org/address/0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913)
+
+-All streams are created as **non-cancelable, non-transferable** Lockup Linear streams with both sender and recipient set to the depositor.
++All streams are created as **non-cancelable, non-transferable** Lockup Linear streams with both sender and recipient set to the depositor. No RipGuard contract exists between you and Sablier.
+
+ ## Stack
+
+@@ -88,7 +81,7 @@ forge test
+
+ ## Security
+
+-The `RipGuardRouter` is intentionally minimal — it holds no state, has no admin functions, and cannot be upgraded. All funds flow through [Sablier's audited Lockup protocol](https://docs.sablier.com/contracts/v2/security). RipGuard never custodies funds; the router is stateless and all locks are enforced by Sablier's battle-tested on-chain contracts.
++RipGuard has no custom contract between you and your funds. The app calls the Sablier Lockup v2.0 contract directly — all locks are created in and enforced by [Sablier's audited, immutable protocol](https://docs.sablier.com/contracts/v2/security). The only RipGuard-authored code is the frontend UI and a reference `RipGuardRouter.sol` in `packages/contracts/` (undeployed, written as a fee-routing reference implementation).
+
+ If you find a vulnerability, please report it responsibly by emailing the team rather than opening a public issue.
+
diff --git a/docs/stash-exports/2026-07-30-backend-migration/testnet-client-providers-2623bb8.patch b/docs/stash-exports/2026-07-30-backend-migration/testnet-client-providers-2623bb8.patch
new file mode 100644
index 0000000..20af76a
--- /dev/null
+++ b/docs/stash-exports/2026-07-30-backend-migration/testnet-client-providers-2623bb8.patch
@@ -0,0 +1,22 @@
+diff --git a/packages/app/src/app/layout.tsx b/packages/app/src/app/layout.tsx
+index c7fe435..72191dd 100644
+--- a/packages/app/src/app/layout.tsx
++++ b/packages/app/src/app/layout.tsx
+@@ -1,7 +1,7 @@
+ import type { Metadata } from "next";
+ import { Geist, Geist_Mono } from "next/font/google";
+-import { Providers } from "@/providers";
+ import { TestnetBanner } from "@/components/TestnetBanner";
++import { ClientProviders } from "@/components/ClientProviders";
+ import "./globals.css";
+
+ const geistSans = Geist({
+@@ -50,7 +50,7 @@ export default function RootLayout({
+ className={`${geistSans.variable} ${geistMono.variable} antialiased bg-black text-white`}
+ >
+
+- {children}
++ {children}
+