Blame
|
1 | --- |
||||||
| 2 | category: reference |
|||||||
| 3 | tags: [dev, vps, progress] |
|||||||
| 4 | last_updated: 2026-03-15 |
|||||||
| 5 | confidence: high |
|||||||
| 6 | --- |
|||||||
| 7 | ||||||||
| 8 | # VPS Deployment Progress |
|||||||
| 9 | ||||||||
| 10 | Tracking the implementation of robot.wtf on the Debian 12 / Proxmox VM. See [[Tasks/VPS_Phases]] for the full plan. |
|||||||
| 11 | ||||||||
| 12 | ## Completed |
|||||||
| 13 | ||||||||
| 14 | ### V0: VM Infrastructure (2026-03-15) |
|||||||
| 15 | - Ansible playbook provisioning: base packages, `/srv` directory structure, Python venv, crypto keys, SQLite schema |
|||||||
| 16 | - RS256 signing keypair + EC P-256 ATProto client JWK generated |
|||||||
| 17 | - Playbook idempotent, tested via full re-run |
|||||||
| 18 | - VPS at 192.168.77.107 (WireGuard backplane), Caddy on separate host |
|||||||
| 19 | ||||||||
| 20 | ### V1: Otterwiki on Caddy (2026-03-15) |
|||||||
| 21 | - **V1-1/V1-2:** Data access layer ported from DynamoDB to SQLite (21 files, 2399 lines, 55 tests) |
|||||||
| 22 | - **V1-3:** Gunicorn entry points, systemd units, Ansible deploy role (4 services on ports 8000-8003) |
|||||||
| 23 | - **V1-4:** Caddy wildcard config with on-demand TLS, `/api/internal/check-slug` for cert validation |
|||||||
| 24 | - **V1-5:** Full stack smoke tested — otterwiki serving pages, MCP connected via Claude Code |
|||||||
| 25 | ||||||||
| 26 | Key findings during V1: |
|||||||
| 27 | - `RETAIN_PAGE_NAME_CASE = True` required (otterwiki lowercases filenames without it) |
|||||||
| 28 | - `TREAT_UNDERSCORE_AS_SPACE_FOR_TITLES = True` for clean URLs |
|||||||
| 29 | - ManagementMiddleware needed `/api/v1/*` and `/api/internal/*` passthroughs |
|||||||
| 30 | - numpy/chromadb X86_V2 issue on the Proxmox VM (semantic search deferred) |
|||||||
| 31 | ||||||||
| 32 | ### VS-1: ATProto OAuth Spike (2026-03-15) |
|||||||
| 33 | - Bluesky cookbook demo adapted for robot.wtf |
|||||||
| 34 | - Real Bluesky login completed end-to-end |
|||||||
| 35 | - ATProto client JWK must be EC P-256 / ES256 (not RSA) — V0 playbook corrected |
|||||||
| 36 | - DPoP nonce handling works, identity-only scope validated |
|||||||
| 37 | - Findings at [[Dev/VS-1_ATProto_Spike]] |
|||||||
| 38 | ||||||||
| 39 | ### V2: Migrate Dev Wiki (2026-03-15) |
|||||||
| 40 | - Dev wiki cloned from dev.wikibot.io via git smart HTTP (`/.git/info/refs`) |
|||||||
| 41 | - Running at https://dev.robot.wtf/ with MCP connected |
|||||||
| 42 | - 3gw wiki NOT migrated (DNS CNAME exception keeps it on home server) |
|||||||
| 43 | - MCP bearer token auth working for Claude Code |
|||||||
| 44 | ||||||||
| 45 | ## In Progress |
|||||||
| 46 | ||||||||
| 47 | ### VS-2: MCP OAuth for Claude.ai |
|||||||
| 48 | - Making FastMCP's OAuth provider persistent (SQLite-backed) so Claude.ai doesn't lose auth on restart |
|||||||
| 49 | - Caddy routes updated to proxy OAuth paths to MCP sidecar |
|||||||
| 50 | - Manager agent running in otterwiki-mcp repo |
|||||||
| 51 | ||||||||
| 52 | ### V3: ATProto OAuth Production Auth Service |
|||||||
| 53 | - Evolving VS-1 spike into production auth service on port 8003 |
|||||||
| 54 | - Platform JWT cookie on `.robot.wtf` domain |
|||||||
| 55 | - Signup flow (choose username from Bluesky handle) |
|||||||
| 56 | - Manager agent running in robot.wtf repo |
|||||||
| 57 | ||||||||
|
58 | ### V3: ATProto OAuth Production Auth Service (2026-03-15) |
||||||
| 59 | - Production auth on port 8003 with ATProto OAuth (Bluesky login) |
|||||||
| 60 | - Platform JWT cookie on `.robot.wtf` domain |
|||||||
| 61 | - Signup flow: choose username from Bluesky handle |
|||||||
| 62 | - OAuth callback, session management, DPoP nonce handling |
|||||||
| 63 | ||||||||
| 64 | ### V4: Management API + Wiki Lifecycle (2026-03-15) |
|||||||
| 65 | - Wiki CRUD via REST API (`/api/wikis`) and web UI (`/app/create`, `/app/wiki/{slug}/*`) |
|||||||
| 66 | - ACL enforcement (owner, collaborator roles) |
|||||||
| 67 | - MCP token generation, hashing, regeneration |
|||||||
| 68 | - Git repo initialization with Home.md bootstrap |
|||||||
| 69 | ||||||||
| 70 | ### V5: MCP OAuth AS (2026-03-15) |
|||||||
| 71 | - FastMCP OAuth provider with SQLite-backed persistence |
|||||||
| 72 | - Claude.ai can connect via OAuth consent flow |
|||||||
| 73 | - Caddy routes proxy OAuth paths to MCP sidecar |
|||||||
| 74 | ||||||||
| 75 | ### V6: Frontend + Landing Page (2026-03-15) |
|||||||
| 76 | - Static landing page at `robot.wtf/` |
|||||||
| 77 | - Dashboard at `/app/` with wiki list and create CTA |
|||||||
| 78 | - Wiki settings, MCP connection instructions, token regeneration |
|||||||
| 79 | - OWASP audit completed (10 parallel agents) |
|||||||
| 80 | ||||||||
| 81 | ### V7: Operational Hardening (2026-03-15) |
|||||||
| 82 | - Healthcheck endpoints, backup cron, disk quota enforcement |
|||||||
| 83 | - Logging, systemd units, graceful restarts |
|||||||
| 84 | ||||||||
| 85 | ### Bugfixes (2026-03-16) |
|||||||
| 86 | - Signup/login redirect fixed: users now land on dashboard instead of marketing page |
|||||||
| 87 | - Landing page redirects authenticated users to dashboard |
|||||||
| 88 | - Private wiki subdomains redirect unauthenticated browsers to login (not JSON 403) |
|||||||
| 89 | - Two beta users (gruen, igor) manually onboarded with wiki records |
|||||||
| 90 | - Details: [[Dev/2026-03-16_Beta_User_TLS_Fix]] |
|||||||
| 91 | ||||||||
|
92 | ### Semantic Search + Infrastructure (2026-03-17) |
||||||
| 93 | - **Multi-tenant semantic search fixed:** slug derivation, auto-reindex empty backends, per-backend reindex lock, stale fallback removal. 104 tests. |
|||||||
| 94 | - **FAISS backend safety:** query() TOCTOU race fixed (snapshot under lock), atomic save (temp files + rename), mismatch detection on load. |
|||||||
| 95 | - **Async reindex:** POST /api/v1/reindex returns 202, background thread, GET /api/v1/reindex/status for polling. Dev wiki reindexed: 76 pages, 590 chunks. |
|||||||
| 96 | - **Wiki template seeding:** New wikis seeded from `templates/default-wiki/` (Home, Getting Started, Agent Guide). Ansible deploys templates to VPS. |
|||||||
| 97 | - **Wiki path consolidation:** Migrated all wikis from `/srv/wikis/` to `/srv/data/wikis/`. Quota script updated. Single canonical storage location. |
|||||||
| 98 | - **Landing page copy updated.** |
|||||||
| 99 | - **Broken beta user wikis (gruen, igor) deleted** — repos were bare, created incorrectly during manual onboarding. Users can recreate via UI. |
|||||||
| 100 | - **OAuth finding:** Claude.ai does not use refresh tokens. Re-auths every hour. Mitigation (extend token lifetime) not yet implemented. |
|||||||
| 101 | ||||||||
|
102 | ## Not Started |
||||||
| 103 | ||||||||
|
104 | - Custom domains (non-robot.wtf) |
||||||
| 105 | - Per-wiki SQLite DB (re-enable admin panels) |
|||||||
|
106 | |||||||
| 107 | ## Architecture Notes |
|||||||
| 108 | ||||||||
| 109 | | Service | Port | Process | Status | |
|||||||
| 110 | |---------|------|---------|--------| |
|||||||
| 111 | | Otterwiki WSGI | 8000 | Gunicorn | Running | |
|||||||
| 112 | | MCP sidecar | 8001 | uvicorn (FastMCP) | Running | |
|||||||
| 113 | | Platform API | 8002 | Gunicorn | Running (stubs) | |
|||||||
| 114 | | Auth service | 8003 | Gunicorn | Running (stubs) | |
|||||||
| 115 | ||||||||
| 116 | All deployed via Ansible (`ansible/deploy.yml`). Config in `/srv/data/robot.env` and `/srv/data/settings.cfg`, both generated from Jinja2 templates with `force: false` (won't overwrite existing secrets). |
|||||||
| 117 | ||||||||
| 118 | Repos: |
|||||||
| 119 | - `robot.wtf` — platform code (Ansible, middleware, auth, management) |
|||||||
| 120 | - `otterwiki-mcp` — standalone MCP server (FastMCP, 12 tools, dual auth) |
|||||||
| 121 | - `otterwiki` — upstream fork (`wikibot-io` branch: lifecycle hooks, proxy auth, platform mode) |
|||||||
| 122 | - `otterwiki-api` — REST API plugin |
|||||||
| 123 | - `otterwiki-semantic-search` — semantic search plugin (ChromaDB/FAISS) |
|||||||
