System Architecture
How SurfDoc is built — from the parser to the workspace to the clients.
Overview
SurfDoc is a typed document format and workspace. Five principles guide every architectural decision.
Layer Cake
Each layer is independent. surf-parse works without surf-server, and surf-server works without the Surf browser.
Layer 0 (surf-parse) is the foundation. It compiles to native code and is embedded in every client via UniFFI or as a Rust dependency. Each higher layer adds functionality but never requires the layers above it.
Parse Pipeline
A .surf file goes through four stages: tokenize, parse, validate, and render. The pipeline is synchronous and deterministic.
The render stage is pluggable. The same parsed document produces HTML for the web, ANSI for the terminal, Markdown for interop, and PDF for print.
Format Architecture
SurfDoc defines 37 typed block directives organized into 4 categories. Every block has a name, defined attributes, and rendering rules.
The Web and Landing categories together contain 23 blocks, purpose-built for generating websites from SurfDoc files. This is the foundation of the phone-to-app pipeline.
Workspace Architecture
surf-server is the unified backend for SurfDoc. It serves the web UI, API, and handles authentication, document storage, and AI generation.
Authentication
SurfDoc uses OPAQUE-KE, a zero-knowledge password-authenticated key exchange. The server never sees or stores plaintext passwords.
After successful login, the server issues a signed JWT for session management.
Deployment
The SurfDoc workspace deploys as a single Rust binary on Fly.io with TLS termination at the edge proxy.
Client Architecture
surf-parse is the shared core. Every client — web or native — uses the same Rust parser for rendering SurfDoc files.
AI System
SurfDoc uses a configurable multi-provider LLM system with admin-selectable providers. Three chat modes (Research, Plan, Build) produce different SurfDoc outputs.
The AI is the controller in the Surf MVC architecture. It transforms natural language into typed SurfDoc blocks, which are then rendered by surf-parse.
Storage
SurfDoc uses PostgreSQL with a minimal, normalized schema. Application-enforced team and user scoping ensures users only access their own data.
Each domain is independent. The identity layer handles OPAQUE-KE credentials and team membership. Documents and tasks are user-scoped with folder-based organization.