# featherChat Task Plan **Version:** 0.0.21+ **Last Updated:** 2026-03-28 **Naming:** `FC-P{phase}-T{task}[-S{subtask}]` --- ## Completed (This Sprint) ### TUI Refactor - [x] Split `app.rs` monolith (1,756 lines) into 7 modules: types, draw, commands, input, file_transfer, network, mod - [x] 44 unit tests across types.rs, input.rs, draw.rs ### TUI Improvements - [x] Message timestamps `[HH:MM]` on every ChatLine - [x] Message scrolling (PageUp/Down by 10, Up/Down by 1, auto-snap on send) - [x] Connection status indicator (green/red dot in header) - [x] Unread badge `[N new]` when scrolled up - [x] `/help` command listing all commands + navigation - [x] Terminal bell on incoming DM ### WZP Server Integration (featherChat side) - [x] FC-2: Call state management (`calls` + `missed_calls` sled trees, `CallState`, `CallStatus`, `active_calls`) - [x] FC-3: WS call signaling awareness (Offer creates CallState, Answer updates, Hangup ends + missed call on offline) - [x] FC-5: Group-to-room mapping (`POST /groups/:name/call` with SHA-256 room ID, fan-out to members) - [x] FC-6: Presence API (`GET /presence/:fp`, `POST /presence/batch`) - [x] FC-7: Missed call notifications (flush on WS reconnect as `{"type":"missed_call"}`) - [x] FC-10: WZP relay config (`GET /wzp/relay-config` + CORS layer) ### WZP Side (all 9 tasks done by WZP team) - [x] WZP-S-1 through WZP-S-9: Identity alignment, relay auth, signaling bridge, room ACL, crypto handshake, web bridge auth, wzp-proto standalone, CLI seed input, hardcoded assumptions fixed --- ## FC-P1: Security & Auth Foundation **Goal:** Close the security gaps before wider deployment. Auth enforcement is the critical path. | ID | Task | Effort | Dep | Status | |----|------|--------|-----|--------| | FC-P1-T1 | Auth enforcement middleware | 0.5d | — | TODO | | FC-P1-T2 | Session auto-recovery | 1d | — | TODO | | FC-P1-T3 | Rate limiting + connection guards | 0.5d | — | TODO | | FC-P1-T4 | Device management + session revocation | 1d | T1 | TODO | ### FC-P1-T1: Auth Enforcement Middleware **What:** Add axum middleware to enforce bearer tokens on protected `/v1/*` routes. **Why:** Currently anyone can impersonate any fingerprint. Tokens are issued but never required. **Scope:** - Extract bearer token from `Authorization` header - Call `validate_token()` for write operations (send, groups, aliases, calls) - Read-only routes (health, key fetch) remain unauthenticated - Return 401 with clear error on invalid/missing token ### FC-P1-T2: Session Auto-Recovery **What:** When ratchet decryption fails (corrupted state), auto-send a new X3DH KeyExchange. **Why:** Corrupted session = permanent inability to decrypt from that peer. **Scope:** - Detect decryption failure in `process_wire_message()` - Delete corrupted session from local DB - Initiate fresh X3DH key exchange - Show "[session reset]" system message (like Signal) - Cap auto-recovery attempts (max 3 per peer per hour) ### FC-P1-T3: Rate Limiting + Connection Guards **What:** Tower rate-limit layer + per-fingerprint connection caps. **Why:** Zero protection against auth spam, message flooding, WS connection spam. **Scope:** - Global rate limit: 100 req/s per IP (tower-governor or tower-http) - Per-fingerprint WS connection cap: max 5 simultaneous connections - Auth challenge rate limit: max 10/minute per fingerprint - Group creation limit: max 5/hour per fingerprint ### FC-P1-T4: Device Management + Session Revocation **What:** Let users see and kill their active sessions. **Why:** Compromised or stale devices need to be revocable immediately. | Subtask | What | |---------|------| | FC-P1-T4-S1 | Server: `GET /v1/devices` — list active WS connections (device_id, IP, connected_at) | | FC-P1-T4-S2 | Server: `POST /v1/devices/:id/kick` — force-close WS + invalidate token | | FC-P1-T4-S3 | Server: `POST /v1/devices/revoke-all` — nuke all sessions except current | | FC-P1-T4-S4 | TUI: `/devices` command — list active sessions | | FC-P1-T4-S5 | TUI: `/kick ` command — revoke a specific device | **Dep on T1:** Kick/revoke endpoints must verify the requester owns the fingerprint. --- ## FC-P2: TUI Call Integration **Goal:** Make call signaling work end-to-end in the TUI. Server infrastructure is ready (FC-2/3/5/6/7). | ID | Task | Effort | Dep | Status | |----|------|--------|-----|--------| | FC-P2-T1 | `/call ` command — send CallSignal::Offer | 0.5d | — | TODO | | FC-P2-T2 | `/accept` + `/reject` commands | 0.5d | T1 | TODO | | FC-P2-T3 | `/hangup` command | 0.25d | T1 | TODO | | FC-P2-T4 | Call state machine (Idle/Ringing/Active/Ended) | 0.5d | T1 | TODO | | FC-P2-T4-S1 | Incoming call notification banner | 0.25d | T4 | TODO | | FC-P2-T4-S2 | In-call header indicator (duration, peer) | 0.25d | T4 | TODO | | FC-P2-T5 | Missed call display (parse WS JSON) | 0.25d | — | TODO | | FC-P2-T6 | `/contacts` online status via presence API | 0.25d | — | TODO | --- ## FC-P3: Web Call Integration **Goal:** Enable voice/video calling from the browser through featherChat's web client. | ID | Task | Effort | Dep | Status | |----|------|--------|-----|--------| | FC-P3-T1 | WASM: parse CallSignal in `decrypt_wire_message()` | 0.5d | — | TODO | | FC-P3-T2 | WASM: `create_call_signal()` export for JS | 0.5d | — | TODO | | FC-P3-T3 | Web client: call/accept/reject UI | 1d | T1, T2 | TODO | | FC-P3-T4 | Web client: integrate wzp-web audio bridge | 1d | T3 | TODO | | FC-P3-T5 | Extract web client from monolith (web.rs) | 1-2d | — | TODO | --- ## FC-P4: Protocol & Architecture **Goal:** Harden the protocol for forward compatibility and resilience. | ID | Task | Effort | Dep | Status | |----|------|--------|-----|--------| | FC-P4-T1 | Session state versioning | 0.5d | — | TODO | | FC-P4-T2 | WireMessage versioning (envelope format) | 1d | — | TODO | | FC-P4-T3 | Periodic auto-backup | 0.5d | — | TODO | | FC-P4-T4 | libsignal migration assessment | 1-2w | — | TODO | --- ## FC-P5: Major Features **Goal:** Core differentiators — physical delivery, federation, identity provider. | ID | Task | Effort | Dep | Status | |----|------|--------|-----|--------| | FC-P5-T1 | Mule binary (physical message delivery) | 3-5d | — | TODO | | FC-P5-T2 | DNS federation (server discovery + relay) | 2-3w | P4-T2 | TODO | | FC-P5-T3 | OIDC identity provider | 1-2w | P1-T1 | TODO | | FC-P5-T4 | Smart contract access control | 3-4w | P5-T3 | TODO | --- ## FC-P6: TUI Polish **Goal:** UX improvements for daily use. | ID | Task | Effort | Dep | Status | |----|------|--------|-----|--------| | FC-P6-T1 | Message search (local history) | 1d | — | TODO | | FC-P6-T2 | Read receipts (viewport tracking) | 0.5d | — | TODO | | FC-P6-T3 | Typing indicators | 0.5d | — | TODO | | FC-P6-T4 | Message reactions (emoji) | 1d | P4-T2 | TODO | | FC-P6-T5 | Voice messages as attachments | 1d | — | TODO | | FC-P6-T6 | Message wrapping for long text | 0.5d | — | TODO | | FC-P6-T7 | Tab completion for commands/aliases | 0.5d | — | TODO | | FC-P6-T8 | File transfer progress gauge | 0.5d | — | TODO | --- ## Parallelization Guide Tasks with **no dependencies** that can run simultaneously: **Sprint A (Security — P1):** ``` FC-P1-T1 (auth middleware) — server only FC-P1-T2 (session recovery) — client only FC-P1-T3 (rate limiting) — server only → then FC-P1-T4 (devices, needs T1) ``` **Sprint B (TUI Calls — P2):** ``` FC-P2-T1 (call command) → T2 (accept/reject) → T3 (hangup) FC-P2-T4 (state machine) → T4-S1 (banner) + T4-S2 (header) FC-P2-T5 (missed calls) — independent FC-P2-T6 (contacts online) — independent ``` **Sprint C (Web — P3):** ``` FC-P3-T1 (WASM parse) — independent FC-P3-T2 (WASM create) — independent FC-P3-T5 (extract web.rs) — independent → then T3 (call UI) → T4 (audio) ``` --- ## Server Architecture (Post-Sprint) ``` warzone-server/src/ ├── main.rs — startup, CORS, state init ├── state.rs — AppState, Connections, CallState, DedupTracker ├── db.rs — sled trees: keys, messages, groups, aliases, tokens, calls, missed_calls ├── errors.rs — AppError, AppResult ├── routes/ │ ├── mod.rs — route composition │ ├── auth.rs — challenge-response, token validation │ ├── calls.rs NEW — call CRUD, group call, missed calls API │ ├── presence.rs NEW — online status (single + batch) │ ├── wzp.rs NEW — relay config + service token │ ├── groups.rs — group management + fan-out │ ├── ws.rs — WebSocket handler + call signal awareness + missed call flush │ ├── keys.rs — pre-key bundle registration │ ├── messages.rs — HTTP message queue │ ├── aliases.rs — alias registration + resolution │ ├── health.rs — health check │ └── web.rs — embedded web client ``` ## TUI Architecture (Post-Sprint) ``` warzone-client/src/tui/ ├── mod.rs — run_tui() entry point + event loop ├── types.rs — App, ChatLine, PendingFileTransfer, ReceiptStatus, normfp() ├── draw.rs — UI rendering (timestamps, scroll, connection dot, unread badge) ├── input.rs — keyboard handling (text editing, scroll keys) ├── commands.rs — /slash commands + /help ├── file_transfer.rs — chunked file send (DM + group) └── network.rs — WS/HTTP polling + incoming message processing + bell ``` ## Test Coverage | Crate | Tests | What | |-------|------:|------| | warzone-protocol | 28 | Crypto, ratchet, X3DH, sender keys, identity, ethereum, prekeys | | warzone-client (types) | 10 | App init, ChatLine, normfp | | warzone-client (input) | 25 | All keybindings, scroll, text editing | | warzone-client (draw) | 9 | Rendering, timestamps, scroll, connection dot, unread badge | | **Total** | **72** | All passing |