Blame
|
1 | --- |
||||||
| 2 | category: reference |
|||||||
| 3 | tags: [tasks, milestones, launch] |
|||||||
|
4 | last_updated: 2026-03-18 |
||||||
|
5 | confidence: high |
||||||
| 6 | --- |
|||||||
| 7 | ||||||||
| 8 | # Pre-Launch Milestone |
|||||||
| 9 | ||||||||
| 10 | 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. |
|||||||
| 11 | ||||||||
|
12 | ## Completed |
||||||
|
13 | |||||||
|
14 | ### ~~MCP wiki routing (bug)~~ ✅ FIXED (2026-03-15) |
||||||
|
15 | Fixed and deployed. See [[Tasks/MCP_Wiki_Routing]]. |
||||||
|
16 | |||||||
|
17 | ### ~~Multi-tenant semantic search (bug)~~ ✅ FIXED (2026-03-17) |
||||||
|
18 | See [[Tasks/Semantic_Search_Architecture]] and [[Tasks/Semantic_Search_Multi_Tenant]]. |
||||||
| 19 | ||||||||
| 20 | ### ~~FAISS index corruption risk~~ ✅ RESOLVED (2026-03-15) |
|||||||
| 21 | Sync thread removed. Index updates now happen through page lifecycle hooks only. |
|||||||
| 22 | ||||||||
|
23 | ### ~~Log rotation~~ ✅ DONE (V7-6) |
||||||
| 24 | systemd journal / logrotate configured so logs don't fill the disk. |
|||||||
| 25 | ||||||||
|
26 | ### ~~OAuth token refresh~~ ✅ FIXED (2026-03-17) |
||||||
| 27 | ACCESS_TOKEN_EXPIRY_SECONDS extended from 3600 to 7 days (604800). Refresh tokens set to 30 days. |
|||||||
| 28 | ||||||||
| 29 | ### ~~Per-wiki databases~~ ✅ DEPLOYED (2026-03-17) |
|||||||
| 30 | Each wiki gets `/srv/data/wikis/{slug}/wiki.db` with preferences, drafts, user, cache tables. Resolver swaps DB per-request. |
|||||||
| 31 | ||||||||
| 32 | ### ~~Permissions panel~~ ✅ DEPLOYED (2026-03-17) |
|||||||
| 33 | Wiki owners can set READ_ACCESS/WRITE_ACCESS/ATTACHMENT_ACCESS via Otterwiki's admin UI. Resolver enforces by intersecting with platform ACL. |
|||||||
| 34 | ||||||||
| 35 | ### ~~MCP OAuth hardcoded defaults~~ ✅ DEPLOYED (2026-03-17) |
|||||||
| 36 | CONSENT_URL and PLATFORM_DOMAIN no longer default to robot.wtf. InMemoryOAuthProvider fallback when unset. |
|||||||
| 37 | ||||||||
| 38 | ### ~~MCP OAuth dynamic base URL~~ ✅ DEPLOYED (2026-03-17) |
|||||||
| 39 | OAuth metadata endpoint uses request Host header. Each wiki's MCP endpoint works correctly. |
|||||||
| 40 | ||||||||
|
41 | ### ~~SERVER_NAME hidden~~ ✅ DEPLOYED (2026-03-17) |
||||||
| 42 | SERVER_NAME field hidden from Application Preferences in PLATFORM_MODE. |
|||||||
|
43 | |||||||
|
44 | ### ~~Remove is_public toggle~~ ✅ DEPLOYED (2026-03-17) |
||||||
| 45 | READ_ACCESS replaces is_public as sole source of truth. Migration seeds READ_ACCESS=REGISTERED for private wikis. |
|||||||
| 46 | ||||||||
| 47 | ### ~~Login return_to redirect~~ ✅ DEPLOYED (2026-03-17) |
|||||||
| 48 | Resolver passes wiki URL as return_to when redirecting to login. Auth server accepts *.robot.wtf URLs. |
|||||||
|
49 | |||||||
|
50 | ### ~~SITE_NAME lazy init~~ ✅ DEPLOYED (2026-03-17) |
||||||
| 51 | display_name passed through to _init_wiki_db during lazy init. |
|||||||
|
52 | |||||||
|
53 | ### ~~Upstream bug fix~~ submitted (2026-03-17) |
||||||
| 54 | `handle_permissions_and_registration` missing ADMIN guard — PR pending to redimp/otterwiki (`fix/permissions-admin-guard`). |
|||||||
|
55 | |||||||
| 56 | ## Blocking |
|||||||
|
57 | |||||||
|
58 | ### ~~Harden per-wiki DB initialization~~ ✅ DEPLOYED (2026-03-17) |
||||||
| 59 | Comprehensive `_init_wiki_db()`: seeds SITE_NAME, READ_ACCESS, WRITE_ACCESS, ATTACHMENT_ACCESS (all REGISTERED), AUTH_METHOD (PROXY_HEADER), DISABLE_REGISTRATION, AUTO_APPROVAL (False), schema version marker. All INSERT OR IGNORE. Owner auto-seeded as admin. |
|||||||
|
60 | |||||||
|
61 | ### ~~Post-deploy smoke test~~ ✅ MERGED (2026-03-17) |
||||||
| 62 | Shell script in Ansible `post_tasks` — checks all 4 services (systemctl + HTTP), auth/MCP well-known endpoints, dynamic wiki enumeration from DB. Retry loop with 30s ceiling per service. |
|||||||
|
63 | |||||||
|
64 | ### ~~Disk usage cap~~ ✅ DEPLOYED (2026-03-17) |
||||||
| 65 | Disk quota (50MB) enforced via resolver — API gets 413, web UI gets WRITE stripped. Page count quota (500 pages) added. Cron populates both `disk_usage_bytes` and `page_count` every 15 minutes. Constants consolidated in `app/constants.py`. Cron script hardened with slug validation and trailing-slash guards. |
|||||||
|
66 | |||||||
|
67 | ### ~~Management UI usability~~ ✅ DEPLOYED (2026-03-17) |
||||||
| 68 | - ~~Wiki creation flow should default slug to username~~ Done: derives slug from Bluesky handle when username not set. Reserved names (DNS-sensitive) return empty, forcing manual entry. |
|||||||
|
69 | - ~~MCP connection instructions need to be clearer~~ Addressed: MCP info now on dashboard card with Claude Code example |
||||||
| 70 | - ~~Settings page layout needs work~~ Addressed: collapsed to single-page card layout |
|||||||
|
71 | |||||||
| 72 | ### Landing page copy |
|||||||
|
73 | Draft is live at robot.wtf/. Updated 2026-03-17. Still needs screenshots once UI is polished. |
||||||
|
74 | |||||||
|
75 | ## UX issues |
||||||
| 76 | ||||||||
|
77 | ### ~~Login page UX~~ ✅ DEPLOYED (2026-03-17) |
||||||
| 78 | JWT cookie detection: auto-redirects if authenticated, pre-fills handle if expired (sanitized, length-capped). Auth templates (login, consent, signup, error) restyled to match landing page — Pico CSS replaced with shared `style.css` + auth-specific styles. Site icon (`robot.wtf.svg`) added to favicon and nav across all pages. See [[Plans/Login_Page_UX]]. |
|||||||
|
79 | |||||||
|
80 | ### ~~Landing page redirect~~ ✅ FIXED (2026-03-17) |
||||||
| 81 | Landing page no longer auto-redirects authenticated users to dashboard. Only `/auth/login` auto-redirects. |
|||||||
| 82 | ||||||||
| 83 | ### ~~Permissions registration checkboxes~~ ✅ DEPLOYED (2026-03-17) |
|||||||
| 84 | Five registration checkboxes (DISABLE_REGISTRATION, EMAIL_NEEDS_CONFIRMATION, AUTO_APPROVAL, NOTIFY_ADMINS, NOTIFY_USER_ON_APPROVAL) hidden in PLATFORM_MODE via otterwiki fork template guards. ADMIN option also hidden from access level dropdowns. Deploy fix: `state: forcereinstall` on otterwiki pip task. |
|||||||
| 85 | ||||||||
| 86 | ### ~~Multi-worker preference staleness~~ ✅ FIXED (2026-03-17) |
|||||||
| 87 | `update_app_config()` now called on fast path in `_swap_database()`, so preference changes (e.g. READ_ACCESS) propagate immediately across workers. See [[Design/Resolver]]. |
|||||||
| 88 | ||||||||
|
89 | ### ~~Admin UI cleanup (otterwiki fork)~~ ✅ ALREADY DONE (confirmed 2026-03-17) |
||||||
| 90 | All three items were completed during Phase 2 User Management work: mail tab hidden (`@platform_mode_disabled` + nav guard), "Email" → "Handle" conditional in templates, "Approved" checkbox replaced by Role dropdown (Admin/Editor/Viewer) with `is_approved` auto-set. Tests cover all three. |
|||||||
|
91 | |||||||
|
92 | ### ~~No navigation from wiki to dashboard~~ ✅ DEPLOYED (2026-03-18) |
||||||
| 93 | Dashboard link added to otterwiki dropdown menu in PLATFORM_MODE. See [[Plans/Wiki_To_Dashboard_Navigation]]. |
|||||||
|
94 | |||||||
|
95 | ## Safety |
||||||
| 96 | ||||||||
|
97 | ### Backup coverage gaps |
||||||
| 98 | Backup cron runs every 4 hours, retains 7 days. Uses `sqlite3 .backup` for consistency. |
|||||||
|
99 | |||||||
|
100 | **What IS backed up:** `robot.db`, `mcp_oauth.db`, per-wiki `wiki.db` files. |
||||||
|
101 | |||||||
| 102 | **What is NOT backed up:** |
|||||||
| 103 | - **Git repos** (`/srv/data/wikis/{slug}/repo/`) — all wiki content. Relies on Proxmox VM snapshots. **Verify Proxmox snapshot schedule is actually running.** |
|||||||
| 104 | - **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. |
|||||||
| 105 | - FAISS indexes — can be rebuilt from wiki content (not critical). |
|||||||
| 106 | ||||||||
| 107 | **Recommended actions (in priority order):** |
|||||||
| 108 | 1. Verify Proxmox snapshots are running on schedule |
|||||||
| 109 | 2. Add `git bundle create` per wiki to the backup script |
|||||||
| 110 | 3. Add signing key backup to the script |
|||||||
| 111 | 4. Write and test a restore script |
|||||||
| 112 | 5. Automate a periodic integrity check (`PRAGMA integrity_check` on all DBs) |
|||||||
| 113 | ||||||||
| 114 | ### Backup verification |
|||||||
|
115 | No tested restore path exists. Minimal local test: pull a backup, run integrity checks on each DB, verify schema matches. |
||||||
|
116 | |||||||
|
117 | ### ~~Rate limiting + security headers~~ ✅ DEPLOYED (2026-03-17) |
||||||
| 118 | **Security headers:** HSTS (1 month), CSP, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy applied globally via Caddy snippet. |
|||||||
|
119 | |||||||
|
120 | **Rate limiting:** Flask-Limiter on auth (1/min login/signup, 2/min consent POST) and API (1/min create, 2/min delete) Flask routes. `limits` library in WSGI middleware: 5/min wiki writes, 5/min API writes, 15/min API reads. ProxyFix at outermost WSGI layer. Retry-After on all 429s. fail2ban on proxy-1 as backstop. Per-worker in-memory storage (~4x effective limits). See [[Plans/Rate_Limiting_And_Security_Headers]]. |
||||||
|
121 | |||||||
|
122 | ### OWASP remaining items |
||||||
|
123 | From [[Security/OWASP_2025_Audit]]: |
||||||
|
124 | - ~~**Bcrypt linear scan DoS**~~ ✅ MERGED (2026-03-17) |
||||||
| 125 | - ~~**Security response headers**~~ Plan ready (see above) |
|||||||
|
126 | - **Security logging:** No audit trail for auth events, ACL changes, wiki deletions. **Plan at [[Plans/Security_Logging]].** ACL hooks (`permission_changed`, `user_flags_changed`) implemented for upstream otterwiki on `feat/admin-action-hooks` — pushed to schuyler/otterwiki, ready for PR to redimp/otterwiki. |
||||||
|
127 | |||||||
|
128 | ### ~~Git remote push/pull security~~ ✅ DEPLOYED (2026-03-17) |
||||||
| 129 | Repository Management panel hidden in PLATFORM_MODE (`@platform_mode_disabled` decorator + nav guard). Pull webhook also gated. `auto_push_if_enabled()` and `auto_pull_webhook()` return early in PLATFORM_MODE — prevents outbound SSH even if previously configured. Feature may be re-enabled with proper sandboxing if there's demand. |
|||||||
|
130 | |||||||
|
131 | ### ~~Monitoring dashboard~~ ✅ DEPLOYED (2026-03-18) |
||||||
|
132 | `/app/admin/stats` page in management UI showing service health, disk usage, wiki/user counts, journal tail. Admin-only via `PLATFORM_ADMIN_DIDS`. Ansible `healthcheck`/`diskmon` roles added to deploy. See [[Plans/Monitoring_Dashboard]]. |
||||||
|
133 | |||||||
|
134 | ## Not blocking but important |
||||||
| 135 | ||||||||
|
136 | ### ~~Phase 2: User Management~~ ✅ DEPLOYED (2026-03-17) |
||||||
| 137 | Platform ACL removed entirely. Per-wiki user table is sole source of truth. Resolver restructured: owner gets ADMIN via `wikis.owner_did`, per-wiki user flags derive permissions, APPROVED access level functional, bearer tokens wiki-scoped. Dashboard collapsed to single-page card layout. Otterwiki role UI (admin/editor/viewer dropdown) deployed. Repository Management gated in PLATFORM_MODE. Init hardening comprehensive. |
|||||||
|
138 | |||||||
|
139 | ### ~~Semantic search background sync (V7-1, V7-2, V7-3)~~ ✅ DEPLOYED (2026-03-18) |
||||||
| 140 | Multi-tenant FAISS backend via `BackendRegistry` — per-wiki indexes at `/srv/data/faiss/{slug}/`. ChromaDB deprecated and disabled. Sync thread replaced by lifecycle hooks (`page_saved`/`page_deleted`/`page_renamed`). `reindex_all` is per-wiki scoped. Auto-reindex on first wiki access. See [[Tasks/Semantic_Search_Architecture]] and [[Tasks/Semantic_Search_Multi_Tenant]]. |
|||||||
|
141 | |||||||
|
142 | ### Wiki stats plugin |
||||||
| 143 | 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.** |
|||||||
|
144 | |||||||
|
145 | ### SMTP alerts test |
||||||
| 146 | Health check and disk monitoring alerts configured but not tested end-to-end. |
|||||||
|
147 | |||||||
|
148 | ### ~~CI/CD pipeline (Phase 1)~~ ✅ MERGED (2026-03-18) |
||||||
| 149 | Per-repo pytest CI via GitHub Actions on all 5 repos. `deploy.sh` wrapper in robot.wtf. Auto-deploy deferred to Phase 3. See [[Plans/CI_CD_Pipeline]]. |
|||||||
|
150 | |||||||
| 151 | ## Post-launch |
|||||||
| 152 | ||||||||
| 153 | ### Account deletion (V7-8) |
|||||||
| 154 | User can delete their account from the management UI. Deletes wiki (git repo, FAISS index), SQLite records, ACL grants. Requires typing username to confirm. |
|||||||
| 155 | ||||||||
|
156 | ### Announce to ATProto community (V7-9) |
||||||
| 157 | Post on Bluesky, add to ATProto app directories if any exist. Gated on semantic search (V7-1–V7-3) and a real user being able to sign up and use the service end-to-end without assistance. |
|||||||
| 158 | ||||||||
|
159 | ### Git clone auth |
||||||
| 160 | Read-only git clone works (V4-6) but has no auth — anyone can clone any wiki. Should require bearer token or platform JWT for private wikis. |
|||||||
| 161 | ||||||||
| 162 | ### Multiple wikis per user |
|||||||
| 163 | Currently limited to 1 wiki per user. The data model supports multiple wikis. Needs UI for wiki selection and limit increase. |
|||||||
| 164 | ||||||||
| 165 | ### Bluesky DM alerts |
|||||||
| 166 | Translate health check / disk monitoring alerts into Bluesky DMs via ATProto API. Small webhook relay. |
|||||||
| 167 | ||||||||
| 168 | ### Wiki import |
|||||||
| 169 | Import existing git repos (from GitHub, local, etc.) as a new wiki. Upload or provide a git URL. |
|||||||
| 170 | ||||||||
| 171 | ### Attachment size limits |
|||||||
| 172 | Per-file and per-wiki attachment size enforcement. Currently no limits on uploaded files. |
|||||||
| 173 | ||||||||
|
174 | ### SEO for public wikis |
||||||
| 175 | Public wikis (READ_ACCESS=ANONYMOUS) should be indexable by search engines. Needs: proper `<meta>` tags, `robots.txt` that allows crawling of public wikis, `sitemap.xml` generation per wiki, OpenGraph tags for link previews. Private wikis should have `noindex, nofollow`. |
|||||||
| 176 | ||||||||
|
177 | ### Proxmox CPU type change |
||||||
| 178 | Change from kvm64 to host to enable numpy 2.4+ and remove the pin. Requires VM reboot. See [[Dev/Proxmox_CPU_Type]]. |
|||||||
