diff --git a/V2_ROADMAP.md b/V2_ROADMAP.md
index a49ca548..3e85bc16 100644
--- a/V2_ROADMAP.md
+++ b/V2_ROADMAP.md
@@ -33,10 +33,13 @@ Each version ships 1–2 major features. Ship small, ship often.
| [v2.3](docs/roadmap/v2.3.md) | **Sharing** | Share links, direct links, password / expiration / limits |
| [v2.4](docs/roadmap/v2.4.md) | **Image Hosting** | Upload API, PicGo / uPic / ShareX integration, custom domain |
| [v2.5](docs/roadmap/v2.5.md) | **Multi-Platform Deployment** | 7 first-class targets via Turso (CF, Docker, AWS Lambda, Vercel, Netlify, Azure, GCP); avatar upload |
-| [v2.6](docs/roadmap/v2.6.md) | **Backup** | zpan-cli (Rust) one-way backup for NAS / desktop |
-| [v2.7](docs/roadmap/v2.7.md) | **Sync & Desktop** | Bidirectional sync + Tauri desktop tray app |
-| [v2.8](docs/roadmap/v2.8.md) | **Managed Service** | Payments, analytics, webhooks, audit log, site branding (white-label) |
-| [v2.9](docs/roadmap/v2.9.md) | **Managed Advanced** | Content moderation, server-side processing, custom domain provisioning |
+| [v2.6](docs/roadmap/v2.6.md) | **Pro Launch** | License system, Stripe self-service purchase, redemption codes, white-label, retroactive Pro gates on operator-grade v2.x features |
+| [v2.7](docs/roadmap/v2.7.md) | **Pro Operator** | Audit log, webhooks, anti-abuse stack for open registration |
+| [v2.8](docs/roadmap/v2.8.md) | **Pro Analytics & Identity** | Analytics dashboard, SSO enterprise (multi-IdP OIDC + SAML), LDAP / SCIM |
+| [v2.9](docs/roadmap/v2.9.md) | **Backup** | zpan-cli (Rust) one-way backup for NAS / desktop |
+| [v2.10](docs/roadmap/v2.10.md) | **Sync & Desktop** | Bidirectional sync + Tauri desktop tray app |
+
+Managed cloud services (content moderation, server-side processing, managed custom domains) live in a separate closed-source repo and version independently. They are consumed by ZPan via HTTP, and do not affect self-hosted deployments that don't opt in.
## Deployment Options
@@ -52,11 +55,51 @@ v2.0–v2.4 ship on two runtimes. v2.5 expands to seven.
Same codebase, same features, seven runtimes. Turso provides the database for every non-CF target (9 GB free tier, no credit card). Object storage is decoupled — users bring any S3-compatible bucket (R2, S3, B2, Tigris), which is what makes Azure and GCP viable targets without adapting to their non-S3 native blob stores.
-## Free vs Paid
+## Community vs Pro
-**Self-hosted: Full-featured, always free.** Every feature from v2.0 through v2.7 ships with zero restrictions — file management, sharing, auth, backup, sync, teams, branding. No artificial limits, no feature gating.
+ZPan is split into two editions. Both run the same open-source codebase — Pro features are unlocked by a license token, Managed is Pro operated by us.
-**Managed version: Convenience + platform-exclusive capabilities.** Charges for managed R2 hosting and features that require server-side infrastructure (analytics, webhooks, audit log, content moderation, server-side processing). See [v2.8](docs/roadmap/v2.8.md) and [v2.9](docs/roadmap/v2.9.md) for pricing details.
+### ZPan Community (free, open source)
+
+Everything an individual, family, or small team needs to self-host:
+
+- File management, upload, download, browse, search
+- Personal account + social login + basic OIDC (single IdP)
+- Share links + password + expiration + download limits
+- Image hosting API + PicGo / uPic / ShareX + custom domain
+- Up to 3 team workspaces + shared folders + basic roles
+- Backup CLI + desktop app + bidirectional sync
+- All 7 deployment targets
+
+No artificial limits, no functionality gated behind paywalls. If you are the administrator of your own instance, Community covers you.
+
+### ZPan Pro (paid license)
+
+Operator-grade features for running ZPan as a service (internally at a company, publicly as a product, or commercially for customers). The rule of thumb: **features that help you *use* ZPan are free; features that help you *operate* ZPan for others are Pro.**
+
+- Open registration (the public signup mode) + anti-abuse tooling (captcha, rate limit, email verification)
+- Audit logs + webhook notifications + analytics dashboard
+- White-label (logo / favicon / wordmark / custom branding)
+- SSO enterprise (multi-IdP OIDC + SAML), LDAP / SCIM provisioning
+- Advanced RBAC / custom roles, retention policies
+- Admin impersonation, per-user quotas, multi-tenant isolation
+
+Pro is one product with two delivery modes:
+
+- **Self-hosted Pro** — buy a license, run ZPan yourself. License token verified locally with an embedded public key; works offline.
+- **Managed Pro** — same features, we operate the ZPan instance and storage. You stop caring about ops.
+
+Licenses can be purchased self-service via Stripe or redeemed from codes issued by the ZPan team. See [v2.6](docs/roadmap/v2.6.md) for the launch plan.
+
+**Retroactive gates.** A small number of features shipped in v2.0–v2.5 are operator-grade and become Pro-only starting in v2.6: `open` registration mode (from v2.1), a cap of 3 team workspaces (from v2.2), and admin-set per-team storage quotas (from v2.2). Closed / invite-only registration, single-IdP OIDC, all sharing and image-hosting features, and all deployment targets remain Community. See [v2.6](docs/roadmap/v2.6.md) for the complete list.
+
+### Managed Cloud Services (separate repo)
+
+A small set of Pro features depend on backend infrastructure we host: content moderation (third-party NSFW scanning), server-side processing (thumbnails, transcoding, archive extraction), and managed custom domains (SSL provisioning). Those services live in a separate closed-source repo (`zpan-cloud`) and version independently. Self-hosted Pro users call these services via HTTPS; usage included up to a monthly quota per plan, overage billed post-paid with a user-set hard cap.
+
+### Pricing
+
+Initial pricing target: a single Pro SKU with generous monthly quotas covering ~90% of users. Tiered plans (Team, Business) follow once Pro validates. Full pricing is in [v2.6](docs/roadmap/v2.6.md).
## v1 Issues Addressed
diff --git a/docs/roadmap/v2.10.md b/docs/roadmap/v2.10.md
new file mode 100644
index 00000000..b865a79d
--- /dev/null
+++ b/docs/roadmap/v2.10.md
@@ -0,0 +1,45 @@
+# v2.10 — Sync & Desktop App
+
+Upgrade zpan-cli from one-way backup to bidirectional sync. Ship the desktop tray app.
+
+> Originally planned as v2.7. Deferred behind Pro Launch so the commercial foundation ships first.
+
+## Major Features
+
+### Bidirectional Sync
+- **Two-way sync** — changes on any device propagate to all others via S3
+- **Change log** — server tracks every file create / update / delete with device attribution
+- **Conflict resolution** — when two devices edit the same file, keep both copies (remote version wins, local saved as `.conflict` variant). Optional: last-write-wins mode
+- **Selective sync** — choose which folders to sync on each device
+- **Multi-device** — sync between laptop, desktop, NAS, any number of machines
+
+### Upgrade Path
+- zpan-cli `backup` command unchanged (one-way, safe)
+- New `sync` command enables bidirectional mode
+- Same tool, same config format, new capability
+
+### Desktop Tray App (Tauri)
+
+Graphical interface for backup and sync, built with Tauri 2. Shares core logic with zpan-cli via the `zpan-core` Rust crate.
+
+- **System tray** with status menu:
+ - Backup status (last run, next scheduled)
+ - Sync status (synced / syncing / conflict)
+ - Pause / resume
+ - Open settings
+ - Open ZPan web UI in browser
+- **Settings window** — configure backup directories, sync folders, server connection, schedule
+- **Native notifications** — backup complete, sync conflict detected, storage quota warning
+- **Auto-start on login**
+- **macOS, Windows, Linux** builds
+
+## User Scenarios
+
+**Freelancer with multiple machines:**
+> I work on my desktop at home and laptop at the cafe. I sync `~/Documents` on both. Files stay in sync without thinking about it.
+
+**Non-technical user:**
+> I install the ZPan desktop app, log in, pick a folder to back up, and forget about it. The tray icon shows me it's working. I never touch the command line.
+
+**Small team sharing a NAS:**
+> We sync a shared folder between our NAS and each team member's laptop. Everyone has the latest files, even when working remotely.
diff --git a/docs/roadmap/v2.6.md b/docs/roadmap/v2.6.md
index ddeeecff..dd1f54e1 100644
--- a/docs/roadmap/v2.6.md
+++ b/docs/roadmap/v2.6.md
@@ -1,35 +1,144 @@
-# v2.6 — Backup
+# v2.6 — Pro Launch
-A lightweight CLI agent that backs up local files to S3 via ZPan.
+Introduce ZPan Pro. Ship the cloud-account binding flow, the entitlement verification layer, the feature-gating framework, and a single visible Pro feature — white-label — so there is something concrete to sell on day one.
+
+**Activation is never local.** Purchase, subscription management, and redemption-code activation all happen on `cloud.zpan.app`. ZPan instances only *bind* to a cloud account; their Pro status mirrors the bound account's entitlement automatically. There is no token to paste and no redemption code field inside ZPan.
+
+Pro features can be added continuously in later versions. This version's job is to make the **machinery** for paid features exist.
+
+## Depends on
+
+- [cloud v0.1](https://github.com/saltbo/zpan-cloud/blob/main/docs/roadmap/v0.1.md) — cloud accounts, instance pairing, cloud dashboard (purchase + redemption + subscription management), entitlement API must be live
## Major Features
-### zpan-cli (Rust, in monorepo under `native/`)
-- **One-way backup** — push local files to S3, local deletions do NOT delete remote copies
-- **Incremental** — only upload new or changed files (hash + mtime comparison)
-- **Preserve directory structure** — local paths map to remote paths as-is
-- **Scheduled runs** — built-in cron (e.g. every night at 2 AM)
-- **Directory watching** — optional real-time mode, upload on file change
-- **Resumable uploads** — large files use multipart upload, resume on failure
-- **Config file** — YAML config for persistent backup jobs
-- **Cross-platform** — macOS, Linux, Windows, ARM (NAS friendly)
-- **Small binary** — ~5MB static binary, no runtime dependencies
-- **Docker image** — mount volume, set env vars, done (for NAS users)
+### Cloud Account Binding
-### ZPan API Additions
-- Batch presigned URL endpoint — request upload URLs for many files in one call
-- File fingerprint check — client sends hashes, server returns which need uploading
-- Backup status visible in web UI
+The only licensing action exposed in ZPan is "Connect to ZPan Cloud". Everything else lives on the cloud side.
+
+**Binding flow (device-code style)**:
+
+1. Admin clicks "Connect to Cloud" in `Settings → Billing`
+2. ZPan calls `POST cloud.zpan.app/api/pairings` — receives a short human-readable code (e.g. `ABC-123`) and a pairing URL
+3. ZPan displays: "Visit **cloud.zpan.app/pair** and enter code `ABC-123`"
+4. User signs in (or signs up) on cloud.zpan.app, enters the code, confirms the pairing (instance host + instance name shown for verification)
+5. ZPan polls `GET cloud.zpan.app/api/pairings/{code}` every 5 seconds
+6. Once the user approves, cloud returns a long-lived refresh token + the first entitlement certificate
+7. ZPan stores the refresh token in its database (admin-only read)
+
+Device code is chosen over OAuth redirect because ZPan instances often run on internal networks, homelab IPs, or behind NAT — requiring a public return URL would break those deployments.
+
+**Disconnect** (either side can initiate):
+- In ZPan: "Disconnect from Cloud" — deletes local credentials, entitlement certificate is discarded, feature gates lock immediately
+- In cloud dashboard: "Unbind instance" — ZPan's next refresh returns `401 Unbound`, feature gates lock on that refresh
+
+### Entitlement System
+
+Cloud is the source of truth. ZPan fetches, caches locally, and verifies offline.
+
+- **Entitlement certificate** — Ed25519-signed document from cloud containing `account_id`, `plan`, `features[]`, `instance_id`, `issued_at`, `expires_at` (24-hour TTL)
+- **Ed25519 public key** embedded in every ZPan build at compile time — verification is fully local, zero network calls per feature check
+- **Refresh cadence** — a background task refreshes the certificate every 6 hours using the stored refresh token
+- **Offline tolerance** — because the certificate is valid for 24 hours, a ZPan instance can stay offline up to 24 hours and still enforce Pro correctly
+- **Hard fail after expiry** — once the cached certificate's `expires_at` passes and cloud is unreachable, feature gates fall back to Community until the next successful refresh
+- **Revocation is implicit** — there is no separate revocation list. Because certificates are short-lived, unbinding on cloud takes effect within 24 hours at worst (or instantly if the ZPan instance is online at the next scheduled refresh)
+
+### Feature Gate Framework
+
+New module `server/licensing/` with three primitives:
+
+- `verify(cert)` — Ed25519 signature check + expiry check against the cached certificate
+- `requireFeature(name)` — middleware for API routes; returns `402 Payment Required` when the feature is not in the current entitlement
+- `hasFeature(name)` — synchronous boolean for UI conditional rendering
+
+Frontend components:
+
+- `` — small "Pro" tag rendered next to gated features in menus / settings
+- `` — block-level upsell shown in place of a gated UI region; CTA goes to "Connect to Cloud" (if unbound) or "Manage on Cloud" (if bound but feature not in plan)
+
+### Billing Dashboard
+
+`Settings → Billing` page. Two states only — bound or unbound. Zero purchase UI, zero redemption UI.
+
+**If unbound (Community)**:
+- Comparison table: Community vs Pro feature list
+- Primary CTA: "Connect to ZPan Cloud" → launches the device-code binding flow
+- Short explainer: "Create or sign in to your ZPan Cloud account, then activate Pro there. This instance will mirror your account's Pro status automatically."
+
+**If bound**:
+- Cloud account identity (email or username, fetched from cloud)
+- Plan name + current entitlement expiry (next refresh time shown for transparency)
+- Feature list (every feature unlocked under the current plan)
+- Primary CTA: "Manage on Cloud" → opens `cloud.zpan.app/dashboard` in a new tab (this is where the user does purchase, renewal, payment method changes, invoices, redemption-code entry)
+- Secondary CTA: "Disconnect from Cloud"
+- Last-refresh timestamp + manual "Refresh now" button (for support scenarios where a just-completed purchase on cloud should reflect immediately)
+
+### First Pro Feature: White-Label
+
+Pure client-side. No cloud dependency beyond the entitlement gate. Demonstrates upgrade value visually.
+
+- **Custom site logo** — replaces ZPan wordmark in nav and auth pages
+- **Custom favicon**
+- **Custom wordmark text** — replace "ZPan" in page titles and copy
+- **Remove "Powered by ZPan" footer** — Community deployments keep it, Pro can hide it
+- **Asset storage** — uploaded to `_system/branding/` in the instance's own S3 bucket
+- **Admin page** — `Settings → Branding`: upload logo, favicon; edit wordmark text; preview live
+
+Deliberately excluded from v2.6 (deferred to later Pro versions):
+- Custom brand colors and fonts
+- Per-tenant branding (when multi-tenant ships)
+- Custom email templates
+
+### Retroactive Pro Gates
+
+Features shipped in earlier versions that are **operator-grade** (help you run ZPan as a service for others) become Pro-only starting in v2.6. The framework is the same: if you are the administrator of your own instance using ZPan yourself, nothing changes. If you are running ZPan as a platform for unknown third parties, you'll hit these gates.
+
+Three gates in v2.6:
+
+**1. Open registration mode** (from v2.1)
+- Registration modes `closed` and `invite-only` remain **Community**.
+- Registration mode `open` (anyone can sign up via the public form) becomes **Pro**.
+- Without a Pro license, `open` is rejected; registration mode falls back to `invite-only`.
+
+**2. Team count ≤ 3** (from v2.2)
+- Community instances can create up to **3 teams** (inclusive of the default personal workspace).
+- 4th team creation is blocked in UI; API returns 402.
+- Rationale: a single person or family team doesn't need more than 3 team workspaces; anyone building past that is running ZPan as a platform.
+
+**3. Per-team storage quota** (from v2.2)
+- Admin-set per-team storage quotas become **Pro**. Without Pro, the quota field is hidden and no per-team enforcement runs.
+
+Everything else from v2.0–v2.5 stays Community:
+- Social login, OIDC (single IdP), invite codes (single and bulk generation)
+- Team workspaces (up to 3), shared folders, member roles, activity feed, public user profile
+- All sharing features (password, expiration, download limits, direct links)
+- All image hosting (upload API, PicGo / ShareX integration, per-org custom domain, hotlink protection)
+- All 7 deployment targets
+
+## Non-goals for v2.6
+
+- **Token paste activation** — the old model of "purchase → receive token email → paste into ZPan" is deliberately replaced by account binding
+- **In-ZPan purchase UI** — all purchase flows live on `cloud.zpan.app`
+- **In-ZPan redemption code input** — redemption also lives on cloud dashboard
+- **Metered / usage-based billing** — no cloud-dependent features yet, not needed
+- **Team / Business tiers** — single Pro SKU only
+- **Multi-seat** — one Pro subscription binds one ZPan instance
+- **Multi-bind per account** — a single Pro subscription can only bind one active instance. Binding a second instance on the same Pro account requires unbinding the first, or a future Team plan
+- **Refund automation** — manual via Stripe dashboard on cloud side
+- **Chinese local payment (Alipay / WeChat Pay)** — Stripe-only at launch, evaluated post-launch
## User Scenarios
-**Photographer with a NAS:**
-> I have 500GB of photos on my Synology. I run zpan-cli in Docker, it backs up to R2 nightly. If my NAS dies, I browse and download everything from ZPan's web UI.
+**Indie dev launching a paid service:**
+> I run ZPan on my VPS. I click "Connect to Cloud", see a pairing code, go to cloud.zpan.app/pair on my laptop, sign in with GitHub, confirm "Bind instance at files.mycompany.com". Back in ZPan the UI shows "Bound to alice@example.com · Plan: Community". I click "Manage on Cloud", subscribe to Pro, and within 30 seconds my ZPan lights up as Pro — I go to Settings → Branding, upload my logo, and my instance looks like my product.
-**Developer with a laptop:**
-> I run `zpan-cli backup --dir ~/Projects --cron "0 2 * * *"`. Every night my projects are backed up. If my laptop gets stolen, I pull everything from ZPan.
+**Contributor who got a code:**
+> I submitted a solid PR. The maintainer sends me a ZPan Pro code good for 1 year. I already have a cloud.zpan.app account, so I sign in there, paste the code on the "Redeem" page. My cloud account is now Pro. I go back to my self-hosted ZPan, click "Connect to Cloud", pair it to my account, Pro unlocks. No code ever touched my ZPan instance.
+
+**Community user hits a gate:**
+> I try to create a 4th team workspace. The "New Team" button shows a Pro badge; clicking it opens a dialog: "Community supports up to 3 teams. Pro removes the limit. **Connect to Cloud** to upgrade." I click through, sign up for a cloud account, and from the cloud dashboard I either start a trial or redeem a code. The moment my account has Pro, my ZPan instance reflects it.
## v1 Issues Resolved
-- **#136** Desktop client — zpan-cli for command line, desktop tray app in v2.7
-
+- **#18** Purchasable storage — reframed as ZPan Pro via bound cloud account (storage is still BYO S3)
+- **#161** Custom logo — shipped as the first Pro feature under white-label
diff --git a/docs/roadmap/v2.7.md b/docs/roadmap/v2.7.md
index 8f660077..12fa2b6b 100644
--- a/docs/roadmap/v2.7.md
+++ b/docs/roadmap/v2.7.md
@@ -1,43 +1,67 @@
-# v2.7 — Sync & Desktop App
+# v2.7 — Pro Operator
-Upgrade zpan-cli from one-way backup to bidirectional sync. Ship the desktop tray app.
+Three Pro features that together make ZPan safe to open up to the public: audit log (what happened), webhooks (tell my other systems), and anti-abuse tooling for the `open` registration mode (which was Pro-gated in v2.6).
+
+All three are local to ZPan — no cloud service dependency.
## Major Features
-### Bidirectional Sync
-- **Two-way sync** — changes on any device propagate to all others via S3
-- **Change log** — server tracks every file create / update / delete with device attribution
-- **Conflict resolution** — when two devices edit the same file, keep both copies (remote version wins, local saved as `.conflict` variant). Optional: last-write-wins mode
-- **Selective sync** — choose which folders to sync on each device
-- **Multi-device** — sync between laptop, desktop, NAS, any number of machines
+### Audit Log
-### Upgrade Path
-- zpan-cli `backup` command unchanged (one-way, safe)
-- New `sync` command enables bidirectional mode
-- Same tool, same config format, new capability
+- **User actions logged**: upload, download, delete, move, rename, share created / revoked, login, password change
+- **Admin actions logged**: user create / disable / delete, role change, storage config change, branding change, license activation
+- **Log entry fields**: timestamp, actor (user / admin / system), action, subject (file / user / config), IP, user-agent, result (success / failure)
+- **Storage** — dedicated `audit_log` table, indexed on (actor, timestamp) and (action, timestamp)
+- **Retention** — configurable: 30 / 90 / 365 days / forever. Default 90.
+- **Admin UI** — filterable list, date range, actor search, action filter
+- **Export** — CSV and JSONL download for compliance / ingestion into external SIEM
+- **No public API for audit log in v2.7** — read access via admin UI only. API access is a Team-tier addition later.
-### Desktop Tray App (Tauri)
+### Webhook Notifications
-Graphical interface for backup and sync, built with Tauri 2. Shares core logic with zpan-cli via the `zpan-core` Rust crate.
+- **Events**: `file.uploaded`, `file.deleted`, `share.created`, `share.accessed`, `share.revoked`, `user.created`, `quota.warning`
+- **Endpoint configuration** — admin adds webhook URL, picks subscribed events, gets a signing secret
+- **Payload signing** — HMAC-SHA256, header `X-ZPan-Signature: sha256=...`
+- **Delivery**:
+ - Async queue, fire-and-forget from main request path
+ - Retry on 5xx / network error: 1m, 5m, 30m, 2h, 12h (5 attempts)
+ - 4xx → no retry, marked failed
+- **Delivery log** — per-event record: payload, response status, latency, retry count
+- **Admin UI** — list endpoints, test-fire button (sends a sample payload), inspect delivery history
-- **System tray** with status menu:
- - Backup status (last run, next scheduled)
- - Sync status (synced / syncing / conflict)
- - Pause / resume
- - Open settings
- - Open ZPan web UI in browser
-- **Settings window** — configure backup directories, sync folders, server connection, schedule
-- **Native notifications** — backup complete, sync conflict detected, storage quota warning
-- **Auto-start on login**
-- **macOS, Windows, Linux** builds
+### Anti-Abuse Stack for Open Registration
+
+The `open` registration mode itself became Pro-gated in v2.6. This version ships the anti-abuse tooling that makes `open` mode safe to turn on — without it, Pro users who enable `open` must roll their own protection at the CDN layer.
+
+Active only when registration mode is `open`:
+
+- **Email verification** — double opt-in, account inactive until verified
+- **Captcha** — Turnstile (CF) / hCaptcha on signup form, configurable provider
+- **Rate limiting** — IP-based signup throttle (5/hour/IP default), admin-configurable
+- **Disposable email block** — bundled list of known disposable domains, admin can add to allowlist
+- **Username uniqueness + reserved list** — reject admin / root / zpan / system / ...
+- **Admin moderation** — new signups visible in user list, admin can bulk-disable / delete suspicious accounts
+
+Gated under `requireFeature('open-registration')` — the same feature flag as the mode toggle itself, so the whole operator-registration toolset is one on-or-off thing from a licensing perspective.
+
+## Non-goals for v2.7
+
+- **Advanced RBAC / custom roles** — v2.8
+- **Quota per user** — v2.8 (part of multi-tenant)
+- **Public API access to audit log** — Team tier later
+- **Intrusion detection / anomaly detection on audit stream** — way later
## User Scenarios
-**Freelancer with multiple machines:**
-> I work on my desktop at home and laptop at the cafe. I sync `~/Documents` on both. Files stay in sync without thinking about it.
+**SaaS operator running ZPan for customer file transfer:**
+> I opened public registration so my customers can sign up themselves. Turnstile and email verification keep bots out. Audit log tells me who downloaded what, and webhooks push file events into our existing Slack channel.
-**Non-technical user:**
-> I install the ZPan desktop app, log in, pick a folder to back up, and forget about it. The tray icon shows me it's working. I never touch the command line.
+**Compliance-sensitive internal deployment:**
+> HR stores confidential docs in ZPan. I don't need open registration, but I do need audit logs for quarterly compliance review. I export last quarter as CSV, done.
-**Small team sharing a NAS:**
-> We sync a shared folder between our NAS and each team member's laptop. Everyone has the latest files, even when working remotely.
+**Indie developer with a Discord community:**
+> Webhooks fire on every upload to a Discord channel so my community sees what's new without me announcing it.
+
+## v1 Issues Resolved
+
+- **#171** Audit log — shipped as Pro feature
diff --git a/docs/roadmap/v2.8.md b/docs/roadmap/v2.8.md
index 4df2c59c..618752cd 100644
--- a/docs/roadmap/v2.8.md
+++ b/docs/roadmap/v2.8.md
@@ -1,72 +1,69 @@
-# v2.8 — Managed Service
+# v2.8 — Pro Analytics & Identity
-Launch the hosted version of ZPan with payments and platform-exclusive features.
+The "enterprise-ready" version. Analytics gives operators the numbers to run a service; SSO and LDAP/SCIM make ZPan buyable by companies that require them.
-> These features are **managed version only** — they require server-side infrastructure. Self-hosted ZPan remains full-featured and free through v2.7.
+All features local to ZPan — no cloud dependency.
## Major Features
-### Payments & Plans
-- Stripe subscription billing
-- Free / Pro / Team tiers with defined limits
-- Usage metering (storage, API calls, bandwidth)
-- Self-service upgrade / downgrade
-- Grace period — plan expires, files preserved (read-only) for 30 days
-
### Analytics Dashboard
-- Storage usage trends over time
-- Bandwidth consumption per day/week/month
-- Popular files ranked by downloads / views
-- Share link analytics (views, downloads, geographic distribution)
-- API usage (call counts, error rates)
-### Webhook Notifications
-- Fire HTTP callbacks on events (file uploaded, deleted, share accessed, quota warning)
-- Retry with exponential backoff
-- Delivery history and debug logs
+Admin-facing dashboard under `Settings → Analytics`.
-### Audit Log
-- User activity log (uploads, downloads, deletes, share creation)
-- Admin action log (user management, storage changes)
-- Filterable by user, action type, date range
-- CSV/JSON export for compliance
+- **Storage trends** — total used / delta by day / week / month, grouped by file type
+- **Bandwidth consumption** — uploads + downloads, day / week / month
+- **Popular files** — top N by downloads and by views, filterable by time window
+- **Share link analytics** — per-link views, downloads, unique IPs, referrer breakdown
+- **User activity** — active users / signups / retention cohorts (for open-registration deployments)
+- **API usage** — call counts, error rates, by endpoint
+- **Data aggregation** — hourly rollups in a dedicated `analytics_hourly` table, daily/monthly computed from hourly
+- **Retention** — raw events 7 days, hourly rollups 90 days, daily rollups forever
+- **Export** — any chart as CSV
-### Site Branding (white-label)
-- Custom site logo (replaces ZPan wordmark in nav and auth pages)
-- Custom favicon
-- Stored under `_system/branding/` in the workspace's S3 bucket
-- Managed-plan tier-gated. Self-hosted users keep the default ZPan brand.
-- Future: custom brand colors and fonts (evaluated post-v2.8 based on Pro / Team demand)
+### SSO Enterprise
-## Pricing
+Community has basic single-IdP OIDC (v2.1). Pro adds the "sell to companies" tier.
-| | Free | Pro ($9/mo) | Team ($29/mo) |
-|--|------|-------------|---------------|
-| **Hosting** | | | |
-| Storage (managed R2) | 1 GB | 50 GB | 200 GB |
-| Requests | 100K/mo | 1M/mo | Unlimited |
-| Storage backends | 1 (managed R2) | Bring your own S3 | Multiple |
-| Backup CLI | No | Yes | Yes |
-| Sync | No | No | Yes |
-| Team members | — | — | 5 (+$5/ea) |
-| **Platform-exclusive** | | | |
-| Analytics | — | Basic | Full |
-| Webhooks | — | 3 endpoints | Unlimited |
-| Audit log | — | 7 days | 90 days |
-| Site branding (logo / favicon) | — | Yes | Yes |
-| **Support** | Community | Email | Priority |
+- **Multiple OIDC providers simultaneously** — users see a list of "Sign in with X" options (Azure AD, Google Workspace, Okta, Auth0, etc.)
+- **SAML 2.0** — for enterprise IdPs that don't speak OIDC
+- **Pre-configured IdP templates** — one-click setup for common IdPs (paste tenant ID, done) instead of 20-field forms
+- **Force SSO** — admin can disable username/password login, require SSO for all users
+- **Just-in-time provisioning** — user exists in IdP → account auto-created on first login
+- **Group → role mapping** — IdP groups mapped to ZPan roles (e.g. `zpan-admin` group → admin role)
+- **SSO session management** — single logout, session timeout tied to IdP policy
-> Self-hosted gets everything in v2.0–v2.7 with no limits. This table only applies to the managed version.
+### LDAP / SCIM Provisioning
-## Revenue Milestones
+- **LDAP sync** (one-way, IdP → ZPan):
+ - Configurable search base + filter
+ - Periodic sync (every N minutes) + on-demand "Sync now"
+ - User create / update / disable based on LDAP state
+ - Attribute mapping (email, name, avatar)
+- **SCIM 2.0 endpoint** (IdP pushes to ZPan):
+ - Expose `/scim/v2/Users` and `/scim/v2/Groups`
+ - Bearer-token auth per IdP
+ - Compatible with Okta, Azure AD SCIM, OneLogin
+- **Deprovisioning** — LDAP user disabled → ZPan user disabled (not deleted); files preserved, access revoked
-- **Launch**: Free tier for user acquisition
-- **Month 3**: Enable Pro, target ShareX/PicGo community
-- **Month 6**: Enable Team, target indie dev teams
-- **Year 1**: Target $5K MRR
+## Non-goals for v2.8
+
+- **Custom RBAC / role builder** — future Pro increment
+- **Retention policies / automatic deletion** — future Pro increment
+- **Multi-tenant isolation** (many workspaces per instance as hard tenants) — future Pro increment, likely Team tier
+- **Analytics API** — read via admin UI only for v2.8
+- **MFA for local accounts** — deferred, may ship as separate Community feature
+
+## User Scenarios
+
+**Series-B startup:**
+> We already use Okta for everything. Setting up ZPan took 10 minutes: paste the Okta metadata URL, map the "engineering" group to admin, turn off password login. New hires get ZPan access automatically via Okta group membership.
+
+**Agency running ZPan for multiple projects:**
+> The analytics dashboard is how we justify the spend to clients. "Here's traffic to your share links this month, here's the top files." Export to CSV, paste into the monthly report.
+
+**Enterprise with Active Directory:**
+> AD is the source of truth. LDAP sync runs every 5 minutes. When HR offboards someone in AD, their ZPan account is disabled within 5 minutes, files stay where they are for handover.
## v1 Issues Resolved
-- **#171** Audit log (managed only)
-- **#18** Purchasable storage
-- **#161** Custom logo — reframed as managed-only white-label feature
+- **#18** Purchasable storage — already addressed in v2.6 (ZPan Pro), analytics here surfaces usage clearly
diff --git a/docs/roadmap/v2.9.md b/docs/roadmap/v2.9.md
index 75903590..5caf5239 100644
--- a/docs/roadmap/v2.9.md
+++ b/docs/roadmap/v2.9.md
@@ -1,39 +1,36 @@
-# v2.9 — Managed Advanced
+# v2.9 — Backup
-Advanced platform features for the managed version.
+A lightweight CLI agent that backs up local files to S3 via ZPan.
-> These features are **managed version only**. Self-hosted ZPan remains full-featured and free.
+> Originally planned as v2.6. Deferred behind Pro Launch so the commercial foundation ships first.
## Major Features
-### Content Moderation
-- Upload scanning against moderation API (NSFW detection, etc.)
-- Admin review queue for flagged files
-- Auto-suspend accounts with repeated violations
-- Configurable content policies
+### zpan-cli (Rust, in monorepo under `native/`)
+- **One-way backup** — push local files to S3, local deletions do NOT delete remote copies
+- **Incremental** — only upload new or changed files (hash + mtime comparison)
+- **Preserve directory structure** — local paths map to remote paths as-is
+- **Scheduled runs** — built-in cron (e.g. every night at 2 AM)
+- **Directory watching** — optional real-time mode, upload on file change
+- **Resumable uploads** — large files use multipart upload, resume on failure
+- **Config file** — YAML config for persistent backup jobs
+- **Cross-platform** — macOS, Linux, Windows, ARM (NAS friendly)
+- **Small binary** — ~5MB static binary, no runtime dependencies
+- **Docker image** — mount volume, set env vars, done (for NAS users)
-### Server-side Processing
-- Archive extraction — upload a zip, extract contents to S3 via background worker
-- Thumbnail generation — auto-generate image thumbnails
-- File format conversion (e.g. HEIC to JPEG)
+### ZPan API Additions
+- Batch presigned URL endpoint — request upload URLs for many files in one call
+- File fingerprint check — client sends hashes, server returns which need uploading
+- Backup status visible in web UI
-### Managed Custom Domains
-- One-click custom domain — enter domain, platform provisions SSL and routing
-- Guided DNS verification with CNAME instructions
-- Vanity share URLs using your domain
+## User Scenarios
-> Self-hosted users already configure custom domains by pointing their own DNS (v2.4). This managed feature automates SSL and routing.
+**Photographer with a NAS:**
+> I have 500GB of photos on my Synology. I run zpan-cli in Docker, it backs up to R2 nightly. If my NAS dies, I browse and download everything from ZPan's web UI.
-## Pricing Update
-
-These features extend the Team plan ($29/mo):
-
-| Feature | Pro | Team |
-|---------|-----|------|
-| Custom domain (managed) | Yes | Yes |
-| Content moderation | — | Yes |
-| Server-side processing | — | Yes |
+**Developer with a laptop:**
+> I run `zpan-cli backup --dir ~/Projects --cron "0 2 * * *"`. Every night my projects are backed up. If my laptop gets stolen, I pull everything from ZPan.
## v1 Issues Resolved
-- **#158** Content moderation / NSFW detection (managed only)
+- **#136** Desktop client — zpan-cli for command line, desktop tray app in v2.10