An open source, human-only, text-based social network. No AI-generated content. No AI scrapers. No AI training.
The dream is to have a community built, community hosted, human only social site. The potential to have one last place we can trust is human only. I am not 100% certain this is possible, so this might just be an attempt at a proof of concept.
The number one priority for the Anti AI strategy is to find a way to block OpenClaw-like agents that are using tools like Scrapling.
solbook is built specifically to resist AI bots, scrapers, and synthetic content. Every contributor should understand and maintain these protections:
| Layer | Implementation | File |
|---|---|---|
robots.txt |
Disallows 20+ known AI crawler user agents | apps/web/public/robots.txt |
ai.txt |
Machine-readable AI access policy | apps/web/public/ai.txt |
X-Robots-Tag header |
noai, noimageai on every response |
apps/web/src/middleware.ts |
| HTML meta tag | <meta name="robots" content="noai, noimageai"> |
apps/web/src/app/layout.tsx |
| Layer | Implementation | File |
|---|---|---|
| Vercel Bot Management | AI bots and standard bots managed rulesets | - |
| User-agent blocking | 403 for known AI/bot UAs at the edge | apps/web/src/middleware.ts |
| Honeypot paths | Silent 200 to log/trap automated scanners | apps/web/src/middleware.ts |
| IP blacklisting (planned) | Upstash Redis — see ROADMAP | — |
| Layer | Implementation | Notes |
|---|---|---|
| Paste prevention | onPaste blocked on composer textarea |
Prevents bulk AI-generated text |
| Copy prevention | onCopy blocked on post content |
Deters training data extraction |
| Character limit | 280 chars, enforced server-side | Limits bulk content injection |
| Layer | Implementation | Notes |
|---|---|---|
| Phone OTP | Required for signup | Links account to real phone number |
| Passkey (WebAuthn) | Required after OTP | Hardware-bound, not replayable |
| No password auth | Passkey-only after setup | Eliminates credential stuffing |
All content requires authentication. There are no public-facing content routes — every page that displays posts, profiles, or feeds sits behind an auth guard. If you add a new route:
- Place it inside the
(app)route group (web) or ensure it is only reachable after auth (mobile). Anonymous access to content routes is not permitted. - Supabase RLS enforces this at the database layer — the PostgREST anon role has zero permissions; only the
authenticatedrole can read data. - The middleware matcher must cover it for UA blocking.
- Add honeypot paths if the route could attract automated scanners.
See apps/web/.env.local.example for required variables. All Supabase access is server-side only — no NEXT_PUBLIC_SUPABASE_URL or anon key is ever exposed to the client.
See ROADMAP.md for planned features, MVP progress, and the ongoing anti-AI hardening backlog.
- Monorepo: Turborepo + bun workspaces
- Web: Next.js 15 (App Router), Tailwind CSS v4, TypeScript
- Backend: Supabase (Auth, PostgreSQL, Row-Level Security)
- Auth: Phone OTP → Passkey (WebAuthn via SimpleWebAuthn)
- Package manager: bun
- bun v1.0+
- Supabase CLI
- Docker Desktop (for local Supabase)
# Install dependencies
bun install
# Start local Supabase (requires Docker)
supabase start
# Copy env example and fill in values
cp apps/web/.env.local.example apps/web/.env.local
# Start the dev server
bun dev# All packages
bun test
# Web app only
cd apps/web && bun test
# Shared package only
cd packages/shared && bun testsolbook/
├── apps/
│ └── web/ # Next.js 15 web app
│ ├── src/
│ │ ├── app/ # App Router pages & layouts
│ │ ├── components/
│ │ ├── lib/ # Server utilities
│ │ └── middleware.ts
│ └── public/
│ ├── robots.txt
│ └── ai.txt
├── packages/
│ └── shared/ # Types, validation, Supabase client
├── supabase/
│ └── migrations/ # Database schema
└── docs/
└── superpowers/ # Design specs and implementation plans
MIT