Commit d81ed3

2026-03-17 04:31:26 Claude (MCP): [mcp] Update pre-launch tasks: mark completed items, add backup findings, add new items from 2026-03-17 session
Tasks/Pre_Launch.md ..
@@ 1,7 1,7 @@
---
category: reference
tags: [tasks, milestones, launch]
- last_updated: 2026-03-15
+ last_updated: 2026-03-17
confidence: high
---
@@ 9,45 9,103 @@
Work required before opening robot.wtf to the ATProto community. Everything here is either a bug, a missing feature that blocks usability, or a safety issue.
- ## Blocking
+ ## Completed
### ~~MCP wiki routing (bug)~~ ✅ FIXED (2026-03-15)
- Fixed and deployed. otterwiki-mcp `1f22d71` adds Host header forwarding via ContextVar; robot.wtf `9d932b9` adds PLATFORM_DOMAIN env var. 12 tests passing. See [[Tasks/MCP_Wiki_Routing]].
+ Fixed and deployed. See [[Tasks/MCP_Wiki_Routing]].
### ~~Multi-tenant semantic search (bug)~~ ✅ FIXED (2026-03-17)
- All 4 bugs fixed: slug derivation, auto-reindex empty backends, per-backend reindex lock, stale fallback removal. Also fixed: FAISS backend safety (query TOCTOU race, atomic save, mismatch detection on load), async reindex endpoint (POST returns 202, background thread, status polling). Dev wiki reindexed: 76 pages, 590 chunks. See [[Tasks/Semantic_Search_Architecture]] and [[Tasks/Semantic_Search_Multi_Tenant]].
+ See [[Tasks/Semantic_Search_Architecture]] and [[Tasks/Semantic_Search_Multi_Tenant]].
+
+ ### ~~FAISS index corruption risk~~ ✅ RESOLVED (2026-03-15)
+ Sync thread removed. Index updates now happen through page lifecycle hooks only.
+
+ ### ~~OAuth token refresh~~ ✅ FIXED (2026-03-17)
+ ACCESS_TOKEN_EXPIRY_SECONDS extended from 3600 to 7 days (604800). Refresh tokens set to 30 days.
+
+ ### ~~Per-wiki databases~~ ✅ DEPLOYED (2026-03-17)
+ Each wiki gets `/srv/data/wikis/{slug}/wiki.db` with preferences, drafts, user, cache tables. Resolver swaps DB per-request.
+
+ ### ~~Permissions panel~~ ✅ DEPLOYED (2026-03-17)
+ Wiki owners can set READ_ACCESS/WRITE_ACCESS/ATTACHMENT_ACCESS via Otterwiki's admin UI. Resolver enforces by intersecting with platform ACL.
+
+ ### ~~MCP OAuth hardcoded defaults~~ ✅ DEPLOYED (2026-03-17)
+ CONSENT_URL and PLATFORM_DOMAIN no longer default to robot.wtf. InMemoryOAuthProvider fallback when unset.
+
+ ### ~~MCP OAuth dynamic base URL~~ ✅ DEPLOYED (2026-03-17)
+ OAuth metadata endpoint uses request Host header. Each wiki's MCP endpoint works correctly.
+
+ ### ~~SERVER_NAME hidden~~ ✅ MERGED (2026-03-17)
+ SERVER_NAME field hidden from Application Preferences in PLATFORM_MODE. Awaiting next deploy.
+
+ ### ~~Upstream bug fix~~ submitted (2026-03-17)
+ `handle_permissions_and_registration` missing ADMIN guard — PR pending to redimp/otterwiki (`fix/permissions-admin-guard`).
+
+ ## In Progress
+
+ ### Remove `is_public` toggle (2026-03-17)
+ `READ_ACCESS` preference replaces `is_public` as sole source of truth for anonymous access. Migration seeds `READ_ACCESS=REGISTERED` for wikis with `is_public=0`. In final verification.
+
+ ## Blocking
### Disk usage cap
- No per-wiki disk space limit. A user could fill the VPS. See [[Tasks/Disk_Usage_Cap]]. 50MB per wiki proposed.
+ No per-wiki disk space limit. `page_count` and `disk_usage_bytes` fields in robot.db always read 0 — tier limits and quota enforcement are dead code. Design doc at [[Design/Wiki_Stats_Plugin]] describes an otterwiki plugin approach using lifecycle hooks + cron backstop. **Not yet implemented.**
### Management UI usability
- The dashboard works but needs UX iteration:
- - Wiki creation flow should default slug to username (or let user pick wiki domain at signup)
+ Dashboard needs cleanup now that permissions moved to Otterwiki's admin:
+ - `is_public` toggle being removed (in progress)
+ - Wiki creation flow should default slug to username
- MCP connection instructions need to be clearer
- Settings page layout needs work
- - Consider re-enabling Otterwiki's content/editing admin settings (currently hidden by PLATFORM_MODE)
### Landing page copy
Draft is live at robot.wtf/. Updated 2026-03-17. Still needs screenshots once UI is polished.
## Safety
- ### Backup verification
- Backup cron is running (V7-4) but needs a test restore to verify it works.
+ ### Backup coverage gaps
+ Backup cron runs every 4 hours, retains 7 days. Uses `sqlite3 .backup` for consistency.
- ### SMTP alerts test
- Health check and disk monitoring alerts are configured but haven't been tested end-to-end. Send a test alert to verify Gmail relay works.
+ **What IS backed up:** `robot.db`, `mcp_oauth.db`, per-wiki `wiki.db` files (added 2026-03-17).
+
+ **What is NOT backed up:**
+ - **Git repos** (`/srv/data/wikis/{slug}/repo/`) — all wiki content. Relies on Proxmox VM snapshots. **Verify Proxmox snapshot schedule is actually running.**
+ - **Signing keys** (`signing_key.pem`, `signing_key.pub`, `client_jwk.json`, `client_jwk_pub.json`) — losing these breaks all OAuth sessions. Generated once, never backed up. Should be added to backup script or Ansible vault.
+ - FAISS indexes — can be rebuilt from wiki content (not critical).
+ - `robot.env`, `settings.cfg` — reproducible from Ansible vars + vault (not critical).
+
+ **Recommended actions (in priority order):**
+ 1. Verify Proxmox snapshots are running on schedule
+ 2. Add `git bundle create` per wiki to the backup script
+ 3. Add signing key backup to the script
+ 4. Write and test a restore script
+ 5. Automate a periodic integrity check (`PRAGMA integrity_check` on all DBs)
+
+ ### Backup verification
+ No tested restore path exists. Minimal local test: pull a backup, run integrity checks on each DB, verify schema matches. Full test: restore to a container, start services, verify wiki access. See above for detailed plan.
### Rate limiting
- No rate limiting on any endpoint. Caddy can add this, but nothing is configured. Not critical for soft launch with a small community, but needed before wider announcement.
+ No rate limiting on any endpoint. Caddy can add this. Not critical for soft launch with small community, needed before wider announcement.
+
+ ### OWASP high-priority items
+ From [[Security/OWASP_2025_Audit]]:
+ - **Bcrypt linear scan DoS:** `scan_by_token()` iterates all wiki rows with `bcrypt.checkpw()` per MCP request. O(N) bcrypt operations. Needs index or prefix-based lookup.
+ - **Security response headers:** Add `X-Content-Type-Options`, `X-Frame-Options`, `Strict-Transport-Security` in Caddy.
+ - **Security logging:** No audit trail for auth events, ACL changes, wiki deletions.
+
+ ### Git remote push/pull security
+ Repository Management admin panel lets wiki owners store SSH keys that the platform executes. Should be gated or disabled in PLATFORM_MODE. Noted in [[Design/Admin_Panel_Reenablement]].
## Not blocking but important
- ### ~~FAISS index corruption risk~~ ✅ RESOLVED (2026-03-15)
- Sync thread removed. Index updates now happen through page lifecycle hooks only. No more daemon thread killed without cleanup.
+ ### Phase 2: User Management
+ Explicit user roster per wiki. Admin adds DID handles, sets per-user flags. Completes the APPROVED access level. Design at [[Design/Admin_Panel_Reenablement]] (Phase 2 section). **Parked — implement after current batch.**
+
+ ### Wiki stats plugin
+ Track page count and disk usage via otterwiki lifecycle hooks. Enables tier limits and quota enforcement. Design at [[Design/Wiki_Stats_Plugin]]. **Parked — design only.**
- ### OAuth token refresh
- Investigated 2026-03-17: Claude.ai does NOT use refresh tokens. It re-runs the full auth flow when access tokens expire (1 hour). Users see a re-auth prompt roughly hourly. Mitigation: extend ACCESS_TOKEN_EXPIRY_SECONDS from 3600 to 7 days. Not yet implemented.
+ ### SMTP alerts test
+ Health check and disk monitoring alerts configured but not tested end-to-end.
- ### ~~Stale pages in wrong wiki~~ ✅ N/A
- No `_default` wiki directory exists on the robot.wtf VPS — only user wikis (gruen, igor). The stale pages concern was from the wikibot.io era and does not apply to this deployment.
+ ### CI/CD pipeline
+ Currently deploy is `git push` + `ansible-playbook`. GitHub Actions for tests on PR + auto-deploy would reduce risk.
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9