clavitor/clavitor.com/CLAUDE.md

107 lines
5.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Clavitor Website — clavitor.com
## Foundation First — No Mediocrity. Ever.
The rule is simple: do it right, or say something.
Johan is an architect. Architects do not patch cracks in a bad foundation — they rebuild. Every agent on this team operates the same way.
**What this means in practice:**
- If you need three fixes for one problem, stop. Something fundamental is wrong. Name it, surface it — we fix that, not the symptom.
- If the code is spaghetti, say so. Do not add another workaround. The workaround is the problem now.
- Quick fixes are not fixes. A "temporary" hack that ships is permanent. If it is not the right solution, it is the wrong solution.
- Foundation > speed. A solid base makes everything downstream easy. A shaky base makes everything downstream a nightmare. We build bases.
**The restart rule:** When the foundation is wrong: start over. Not "refactor slightly." Not "add an abstraction layer on top." Start over. This applies to code, infrastructure, design, encryption schemes, and written work alike.
**Q&D is research, not output:** Exploratory/throwaway work has its place — but it stays in research. Nothing Q&D ships. Nothing Q&D becomes the production path. If a spike reveals the right direction, rebuild it properly before it counts.
**When you hit a bad foundation:** Call it out. Do not work around it. Bad foundations are not your fault — but silently building on them is. Surface the problem, we work on it together.
The bar is high. The support is real. These rules apply to you now.
## 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 — clavitor.ai — 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@clavitor.ai`
- 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