# MASTER PLAN > Archipelago project task tracking and roadmap. ## Roadmap | ID | Title | Priority | Status | Dependencies | |----|-------|----------|--------|--------------| | **BUG-1** | **Random logout / CSRF mismatch** | **P0** | PLANNED | - | | **TASK-2** | **Roll incoming-tx into deploy & ISO** | **P2** | PLANNED | - | | **BUG-3** | **IndeedHub WebSocket spam in console** | **P2** | PLANNED | - | ## Active Work ### BUG-1: Random logout / CSRF mismatch (PLANNED) **Priority**: P0 — Critical **Status**: PLANNED (2026-03-15) Sessions expire unexpectedly during normal use. Backend sessions now persist to disk (`/var/lib/archipelago/sessions.json`) but CSRF token mismatch (403) still causes logouts. Need to investigate CSRF token lifecycle and fix the mismatch between cookie and header values. **Root cause analysis so far**: - Sessions were purely in-memory — fixed with disk persistence - CSRF validation compares cookie value vs `X-CSRF-Token` header — both present but don't match - Log: `403 CSRF mismatch — rejecting RPC call ... has_cookie=true has_header=true` - Possible cause: cookie value rotated (e.g., new login in another tab) but frontend cached old value **Key files**: - `core/archipelago/src/session.rs` — session store (now persisted) - `core/archipelago/src/api/rpc/mod.rs:273-307` — CSRF validation - `neode-ui/src/api/rpc-client.ts:18-45` — frontend CSRF extraction from cookie **Tasks**: - [ ] Investigate CSRF token rotation — when/why cookie and header diverge - [ ] Add logging to CSRF validation to capture actual cookie vs header values - [ ] Consider returning CSRF token in response body (not just cookie) for explicit client storage - [ ] Test multi-tab scenario where one tab's login rotates the CSRF token - [ ] Verify session persistence survives deploys (second deploy test) ### TASK-2: Roll incoming-tx into deploy & ISO (PLANNED) **Priority**: P2 — Medium **Status**: PLANNED (2026-03-16) The incoming transactions feature (lnd.gettransactions RPC + wallet badge UI + auto-refresh) is working on .228. Roll changes into deploy-to-target.sh and build-auto-installer-iso.sh so fresh installs and deploys get it automatically. Do not break existing changes. **Key files changed**: - `core/archipelago/src/api/rpc/lnd.rs` — new `handle_lnd_gettransactions` method - `core/archipelago/src/api/rpc/mod.rs` — registered `lnd.gettransactions` route - `neode-ui/src/views/Web5.vue` — incoming tx badge, panel, auto-refresh polling - `neode-ui/src/style.css` — incoming-tx-badge, incoming-tx-row, incoming-tx-slide classes **Tasks**: - [ ] Verify changes are already captured by existing deploy (backend build + frontend build) - [ ] Ensure ISO build captures the updated Rust binary and frontend dist - [ ] Test that no existing deploy/build logic is broken ### BUG-3: IndeedHub WebSocket spam in console (PLANNED) **Priority**: P2 — Medium **Status**: PLANNED (2026-03-16) `ws://localhost:7777/` connection refused fills browser console endlessly when IndeedHub is loaded in iframe. IndeedHub's compiled frontend bundle hardcodes `localhost` for WebSocket connections. When loaded from a remote host, `localhost` resolves to the user's machine, not the server. **Root cause**: IndeedHub's Next.js build bakes `localhost:7777` into the WebSocket URL. The nginx WebSocket proxy at `/app/indeedhub/ws/` exists but is unused because IndeedHub loads via direct port 7777, not through the proxy path. **Tasks**: - [ ] Rebuild IndeedHub with `NEXT_PUBLIC_WS_URL` env var pointing to relative URL or actual server address - [ ] Alternatively, configure IndeedHub to use relative WebSocket URLs (`/ws/` instead of `ws://localhost:7777/`) - [ ] Test that WebSocket reconnection works after the fix ## Completed