PAI v2 — System Architecture¶
Overview¶
PAI is a bootable Debian 12 live USB operating system designed as an AI-first workstation with privacy features. It combines a local LLM engine (Ollama), a full-featured AI interface (PAI UI), and a privacy-hardened desktop environment into a single ISO image.
flowchart TB
subgraph USB["PAI Live USB"]
direction TB
subgraph Desktop["Desktop — Sway / Wayland"]
direction LR
FF["Firefox ESR<br/>+ Tor proxy"]
UI["PAI UI :3210<br/>Chat · Agents · Tools<br/>Knowledge Base · MCP"]
OL["Ollama :11434<br/>Local LLM inference<br/>~/.ollama/"]
UI -- "REST API" --> OL
end
subgraph Privacy["Privacy & Network"]
direction LR
UFW["UFW Firewall<br/>deny inbound"]
MAC["MAC Spoof<br/>on boot"]
TOR["Tor (opt-in)<br/>pai-privacy on/off"]
end
LUKS["LUKS Encrypted Persistence<br/>home · SSH · GPG · wallets · models"]
Desktop --- Privacy
Privacy --- LUKS
end
Project Structure¶
pai-v2/
├── config/ # Live-build config (monolithic, used for builds)
│ ├── hooks/live/ # All hooks (19 total, run in order during build)
│ ├── includes.chroot_after_packages/ # Files injected into the ISO
│ │ ├── usr/local/bin/ # PAI scripts (9 tools)
│ │ └── etc/systemd/system/ # Systemd services (6 units)
│ └── package-lists/ # Debian packages to install
│
├── shared/ # Shared hooks for multi-edition builds
│ ├── hooks/live/ # 16 common hooks (no desktop/UI-specific)
│ ├── includes/ # Common scripts, services
│ └── package-lists/ # Base packages
│
├── desktop/ # Desktop Edition (Sway compositor)
│ ├── Dockerfile.build
│ └── build.sh
│
├── web/ # Web Edition (CTRL web OS, kiosk mode)
│ ├── Dockerfile.build
│ └── build.sh
│
├── pai-ui/ # AI Interface (rebranded LobeChat)
│ ├── src/ # Next.js app source
│ ├── packages/ # Monorepo packages (database, model-runtime, etc.)
│ └── apps/desktop/ # Electron desktop app
│
├── docs/ # Documentation
├── Dockerfile.build # Docker build for ISO creation
├── build.sh # ISO build script
└── README.md
Boot Flow¶
BIOS/UEFI
└─► GRUB (from ISO)
└─► Linux kernel + initramfs (live-boot)
└─► systemd
├── pai-persistence.service → Prompt for LUKS unlock (tty2)
├── pai-mac-spoof.service → Randomize MAC address
├── ollama.service → Start Ollama LLM server (:11434)
├── pai-ui.service → Start PAI UI (:3210)
├── ufw → Firewall (deny inbound)
└── getty + auto-login
└─► Sway (Wayland compositor)
├── Waybar (status bar: privacy, crypto, system)
└─► Firefox ESR → http://localhost:3210 (PAI UI)
Component Details¶
1. Ollama — Local LLM Engine¶
- Port: 11434 (localhost only, blocked externally by UFW)
- User:
ollama(dedicated system user) - Models stored:
/usr/share/ollama/.ollama/models/ - Service:
ollama.service— auto-starts, restarts on failure - Supports: Llama 3, Mistral, Phi, Gemma, CodeLlama, and any GGUF model
- CPU-only: No GPU drivers in the live ISO to keep size manageable
2. PAI UI — AI Interface¶
PAI UI is a rebranded fork of LobeChat (MIT license). It provides:
- Multi-model chat: Talk to any Ollama model, or connect cloud APIs (OpenAI, Anthropic, Groq)
- Agent teams: Create and orchestrate groups of AI agents
- Agent marketplace: Browse and install pre-built agents
- Function calling / tools: MCP integration, built-in tools, web browsing
- Knowledge base: RAG with local document indexing
- Plugins: Extensible plugin system
Runtime:
- Next.js app served on port 3210
- Talks to Ollama via http://localhost:11434
- Data stored in local SQLite/IndexedDB (no external database needed)
3. Desktop — Sway (Wayland)¶
| Component | Purpose |
|---|---|
| Sway | Tiling Wayland compositor (i3-compatible) |
| Waybar | Status bar (privacy mode, crypto prices, system stats) |
| Foot | Terminal emulator |
| Firefox ESR | Web browser (opens PAI UI on launch) |
| Swaylock | Screen lock |
| PCManFM | File manager |
| Mousepad | Text editor |
Keybindings:
- Alt+Enter — Terminal
- Alt+F4 — Close window
- Alt+L — Lock screen
- Alt+1/2/3 — Switch workspace
4. Privacy Layer¶
All privacy features are configured at build time but some are opt-in at runtime:
| Feature | Default | Toggle |
|---|---|---|
| MAC address spoofing | Active (on every boot) | Always on |
| UFW firewall (deny inbound) | Active | Always on |
| Tor transparent proxy | Inactive | sudo pai-privacy on/off |
| DNS over Tor | Inactive | Activated with pai-privacy |
Network architecture (privacy mode off):
Network architecture (privacy mode on):
App → iptables → Tor TransPort (9040) → Tor network → Internet
DNS → Tor DNSPort (5353) → resolved via Tor
5. Persistence Layer¶
PAI runs from a read-only squashfs — RAM changes are lost on shutdown. The persistence system provides opt-in encrypted storage on a separate USB partition.
Setup (first time): sudo pai-persistence setup
- Creates a LUKS-encrypted partition on the USB
- Formats as ext4, mounts at /mnt/pai-persist
Save (manual): pai-save
- Syncs home directory, SSH keys, GPG keyring, Electrum wallet, shell history, Ollama models, chat history to the encrypted partition
Auto-save: pai-save-on-shutdown.service
- Triggers pai-persistence save on shutdown/reboot/halt
Auto-unlock: pai-persistence.service
- Prompts for LUKS passphrase on tty2 at boot
- Restores saved data after unlock
What's persisted:
| Data | Location |
|------|----------|
| Home directory | ~/ |
| SSH keys | ~/.ssh/ |
| GPG keyring | ~/.gnupg/ |
| Electrum wallet | ~/.electrum/ |
| Shell history | ~/.bash_history, ~/.zsh_history |
| Ollama models | /usr/share/ollama/.ollama/models/ |
| Chat history | PAI UI local storage |
Build System¶
PAI ISOs are built using Debian's live-build inside a Docker container:
# Build the ISO
docker build -t pai-builder -f Dockerfile.build .
docker run --privileged -v $(pwd)/output:/pai/output pai-builder
# → output/pai.iso (~900MB–1.2GB)
Build Hook Pipeline¶
Hooks run inside the chroot in numerical order during lb chroot:
| # | Hook | Purpose |
|---|---|---|
| 0100 | install-ollama | Download Ollama binary, create user, enable service |
| 0200 | install-pai-ui | Build and install PAI UI (replaces old open-webui hook) |
| 0300 | configure-desktop | Sway config, Waybar, keybindings, wallpaper |
| 0350 | auto-login | Getty auto-login → Sway on tty1 |
| 0400 | plymouth-theme | Boot splash screen |
| 0450 | mac-spoof | NetworkManager MAC randomization |
| 0500 | firewall | UFW: deny inbound, allow loopback |
| 0550 | tor-config | Pre-configure Tor (inactive by default) |
| 0600 | configure-electrum | Electrum Bitcoin wallet config |
| 0610 | install-monero-wallet | Monero wallet setup |
| 0650 | install-ai-tools | Additional AI utilities |
| 0710 | install-dev-languages | Development language runtimes |
| 0730 | install-git-tools | Git, Git LFS, SSH config |
| 0740 | configure-terminal | Terminal theme, aliases, prompt |
| 0750 | configure-media | Audio (PipeWire), media players |
| 0800 | configure-networking-privacy | DNS, hostname, network hardening |
| 0830 | configure-encryption-privacy | GPG, full-disk encryption tools |
| 0840 | configure-utilities | System utilities, convenience scripts |
| 0900 | configure-persistence | Persistence services, sudoers, MOTD |
Systemd Services¶
| Service | Type | Description |
|---|---|---|
ollama.service |
simple | Ollama LLM server (port 11434) |
pai-ui.service |
simple | PAI UI web server (port 3210) |
pai-mac-spoof.service |
oneshot | Randomize MAC on boot |
pai-persistence.service |
oneshot | LUKS unlock + restore on boot |
pai-save-on-shutdown.service |
oneshot | Auto-save before shutdown |
pai-setup.service |
oneshot | First-boot initialization |
Bundled Scripts¶
| Script | Purpose |
|---|---|
pai-persistence |
Full persistence lifecycle (setup, unlock, save, restore, status) |
pai-save |
Quick save shortcut |
pai-privacy |
Toggle Tor transparent proxy |
pai-mac-spoof |
Force MAC randomization |
pai-ssh-setup |
Generate SSH keys, configure agent |
pai-transcribe |
Local speech-to-text via Whisper |
pai-waybar-privacy |
Waybar module: privacy mode indicator |
pai-waybar-crypto |
Waybar module: crypto price ticker |
pai-setup |
First-boot system initialization |
Editions¶
PAI ships as separate ISOs per edition. All editions share the same base hooks and packages.
Desktop Edition (default)¶
- Sway tiling compositor + Waybar
- Full Wayland desktop with Firefox, terminal, file manager
- PAI UI opens in Firefox on boot
Web Edition¶
- CTRL web OS (HTML/CSS/JS desktop-in-a-browser)
- Cage/kiosk mode (minimal Wayland, no window manager chrome)
- Lighter footprint, touch-friendly
ARM64 Edition¶
- Same as Desktop but compiled for ARM64 (Apple Silicon, Raspberry Pi)
- No torbrowser-launcher (unavailable on ARM64)
Network Ports (localhost only)¶
| Port | Service | Accessible from |
|---|---|---|
| 11434 | Ollama API | localhost only (UFW blocks external) |
| 3210 | PAI UI | localhost only |
| 9040 | Tor TransPort | localhost only (when privacy mode on) |
| 5353 | Tor DNSPort | localhost only (when privacy mode on) |
Technology Stack¶
| Layer | Technology |
|---|---|
| Base OS | Debian 12 (Bookworm) |
| Build system | live-build + Docker |
| Desktop | Sway (Wayland) |
| Terminal | Foot |
| Browser | Firefox ESR |
| AI engine | Ollama (CPU inference) |
| AI interface | PAI UI (Next.js, forked from LobeChat) |
| Audio | PipeWire + WirePlumber |
| Firewall | UFW (iptables) |
| Anonymity | Tor |
| Encryption | LUKS2 (dm-crypt) |
| Crypto | Electrum (BTC), Monero wallet |
License¶
- PAI system integration: GPL v3
- PAI UI: MIT (derived from LobeChat by LobeHub)
- Ollama: MIT
- Debian packages: Various (GPL, LGPL, BSD, MIT)