# Clavitor Website — clavitor.com ## Architecture - Go web server (`main.go`) with `go:embed` for templates, CSS, SVGs, PNGs - Templates in `templates/*.tmpl`, single CSS in `clavitor.css` - SQLite DB: `clavitor.db` (pops, telemetry, uptime, incidents, accounts, vaults, sessions) - Dev mode: auto-detected when `templates/` dir exists on disk — reloads templates per request, but CSS/SVGs require rebuild (`go:embed`) - Port 8099 - License: Elastic License 2.0 (NOT MIT) ## Deployment ### Dev (forge = 192.168.1.16, Florida — dev.clavitor.ai) ``` make dev # build + restart locally make deploy-dev # same thing ``` Dev runs on forge (localhost). `dev.clavitor.ai` DNS points to home IP. ### Prod (Zürich — zurich.inou.com — clavitor.ai) ``` make deploy-prod # cross-compile amd64, scp to Zürich, restart systemd ``` Prod runs at `/opt/clavitor-web/` as systemd service `clavitor-web`. Caddy reverse proxies `clavitor.ai`, `clavitor.com`, `www.clavitor.ai`, `www.clavitor.com` → `localhost:8099`. ### First-time setup (already done) ``` make setup-prod # creates /opt/clavitor-web, systemd service, uploads binary+db ``` Then manually update `/etc/caddy/Caddyfile` to reverse_proxy. ### SSH - Prod: `ssh root@zurich.inou.com` - Tailscale: `zurich` (100.70.148.118) — SSH may be blocked via Tailscale ## Build & Run ``` CGO_ENABLED=1 go build -o clavitor-web . ./clavitor-web ``` CSS and SVG changes require rebuild (embedded at compile time). Template changes reload in dev mode. ## Brand & Design - Light mode only. Single source of truth: `clavitor.css` - Logo: the black square (`#0A0A0A`). favicon.svg = black square - Colors: black `#0A0A0A` (brand), red `#DC2626` (accent), light red `#F5B7B7` (planned/secondary), grayscale - No purple. No green (except inherited SVG diagrams). Red is the only accent. - Square shapes for permanent UI elements. Circles only for transient animations (pulses, "You" dot) - Fonts: Figtree (body), JetBrains Mono (code/monospace) - No inline styles, no CSS in templates. Everything in clavitor.css. - Always capitalize "Clavitor" in prose. Lowercase in code/paths/commands. ## Encryption Terminology - **Vault Encryption** — whole vault at rest - **Credential Encryption** — per-field, server-side (AI agents can read via CLI) - **Identity Encryption** — per-field, client-side via WebAuthn PRF (Touch ID only, server cannot decrypt) - Never use "sealed fields", "agent fields", "L1", "L2", "L3" - Agents use CLI, NOT MCP (MCP exposes plaintext; CLI is scoped) ## POPs (Points of Presence) - Stored in `pops` table in clavitor.db — the single source of truth - Map on /hosted is generated dynamically from DB via JavaScript - Zürich = HQ, black dot, larger (11×11). Live POPs = red. Planned = light red. - "You" visitor dot = circle (not square — "you" is not clavitor) ## Key URLs - `/hosted` — hosted product page with dynamic world map - `/glass` — looking glass (latency from user's browser) - `/noc?pin=250365` — NOC dashboard (telemetry, read-only, hardcoded PIN) - `/telemetry` — POST endpoint for POP agent heartbeats (no auth) - `/ping` — server-side TCP ping (for diagnostics) ## Vault Binary - Source: `~/dev/clavitor/clovis/clovis-vault/` - Build for ARM64: `cd ~/dev/clavitor/clovis/clovis-vault && GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -o clavitor-linux-arm64 ./cmd/clavitor` - All POPs are ARM64 (AWS t4g.micro) - Vault runs on port 1984 with TLS - Has `/ping` endpoint (11 bytes, no DB, CORS via middleware) for looking glass - Has `/health` endpoint (heavier, queries DB) ## Providers - AWS: most POPs (free tier t4g.micro) - LightNode: Santiago, Bogotá, Manila, Dhaka - ishosting: Istanbul, Almaty - HostAfrica: Lagos, Nairobi - Rackmill: Perth