Files
featherChat/warzone/docs/TASK_PLAN.md
Siavash Sameni c2be68ca20 docs: comprehensive update all docs to v0.0.46
11 files updated to reflect current state (v0.0.22 → v0.0.46):

ARCHITECTURE.md:
- Ring tones, group calls, read receipts, markdown rendering sections
- Bot API expanded (BotFather, numeric IDs, Telegram compat)
- Admin commands, known issues, 155 tests

TASK_PLAN.md:
- All P1-P4 marked DONE with version numbers
- Additional completed work section (bots, ETH, ring tones, group calls)
- New FC-P7 (Voice & Transport): cpal, Sender Keys, WebTransport
- FC-P6-T9/T10 added

PROGRESS.md:
- Full version history table v0.0.22 through v0.0.46
- Known issues section

README.md:
- Voice calls, ring tones, group calls, read receipts, markdown, 155 tests

SECURITY.md:
- Bot API security, voice call security, admin commands sections
- Updated protection tables

USAGE.md:
- Group calls, read receipts, markdown formatting, admin commands

CLIENT.md:
- Call commands, read receipts, markdown rendering

LLM_HELP.md + LLM_BOT_DEV.md:
- Call/group call/admin commands, ring tones, per-bot numeric IDs

TESTING_E2E.md:
- Tests 16-18: ring tones, group calls, admin commands

CLAUDE.md:
- Ring tone notes, group signal endpoint, MLS roadmap

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 09:47:13 +04:00

288 lines
13 KiB
Markdown

# featherChat Task Plan
**Version:** 0.0.46
**Last Updated:** 2026-03-30
**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
### Additional Completed Work (not in original plan)
- [x] ETH address integration — display everywhere TUI + Web (v0.0.22-0.0.24)
- [x] Federation persistent WS + text selection (v0.0.25-0.0.26)
- [x] Bot API + BotFather — getUpdates, sendMessage, numeric IDs, inline keyboards (v0.0.27-0.0.33)
- [x] Bot sendMessage fix, per-bot ID mapping (v0.0.34)
- [x] Markdown rendering in TUI + Web messages (v0.0.42)
- [x] Call ring tones (v0.0.45)
- [x] Group calls + group call fixes (v0.0.45-0.0.46)
- [x] Admin commands (v0.0.46)
- [x] Deploy scripts: build-linux.sh + build-bleeding.sh
---
## FC-P1: Security & Auth Foundation — DONE
**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 | — | DONE |
| FC-P1-T2 | Session auto-recovery | 1d | — | DONE |
| FC-P1-T3 | Rate limiting + connection guards | 0.5d | — | DONE |
| FC-P1-T4 | Device management + session revocation | 1d | T1 | DONE |
### 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 <device_id>` command — revoke a specific device |
**Dep on T1:** Kick/revoke endpoints must verify the requester owns the fingerprint.
---
## FC-P2: TUI Call Integration — DONE (v0.0.36-0.0.37)
**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 <fp>` command — send CallSignal::Offer | 0.5d | — | DONE (v0.0.36) |
| FC-P2-T2 | `/accept` + `/reject` commands | 0.5d | T1 | DONE (v0.0.36) |
| FC-P2-T3 | `/hangup` command | 0.25d | T1 | DONE (v0.0.36) |
| FC-P2-T4 | Call state machine (Idle/Ringing/Active/Ended) | 0.5d | T1 | DONE (v0.0.37) |
| FC-P2-T4-S1 | Incoming call notification banner | 0.25d | T4 | DONE (v0.0.37) |
| FC-P2-T4-S2 | In-call header indicator (duration, peer) | 0.25d | T4 | DONE (v0.0.37) |
| FC-P2-T5 | Missed call display (parse WS JSON) | 0.25d | — | DONE (v0.0.37) |
| FC-P2-T6 | `/contacts` online status via presence API | 0.25d | — | DONE (v0.0.37) |
---
## FC-P3: Web Call Integration — DONE (v0.0.35-0.0.44)
**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 | — | DONE (v0.0.35) |
| FC-P3-T2 | WASM: `create_call_signal()` export for JS | 0.5d | — | DONE (v0.0.35) |
| FC-P3-T3 | Web client: call/accept/reject UI | 1d | T1, T2 | DONE (v0.0.36) |
| FC-P3-T4 | Web client: integrate wzp-web audio bridge | 1d | T3 | DONE (v0.0.43) |
| FC-P3-T5 | Extract web client from monolith (web.rs) | 1-2d | — | TODO |
---
## FC-P4: Protocol & Architecture — DONE (v0.0.38-0.0.39)
**Goal:** Harden the protocol for forward compatibility and resilience.
| ID | Task | Effort | Dep | Status |
|----|------|--------|-----|--------|
| FC-P4-T1 | Session state versioning | 0.5d | — | DONE (v0.0.38) |
| FC-P4-T2 | WireMessage versioning (envelope format) | 1d | — | DONE (v0.0.38) |
| FC-P4-T3 | OTPK replenishment | 0.5d | — | DONE (v0.0.39) |
| FC-P4-T4 | Periodic auto-backup | 0.5d | — | DONE (v0.0.38) |
---
## FC-P5: Major Features
**Goal:** Core differentiators — physical delivery, federation, identity provider, E2E group calls.
| 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-P5-T5 | MLS group call E2E encryption (RFC 9420) | 4-6w | — | TODO |
### FC-P5-T5: MLS for Group Call E2E (RFC 9420)
**Current state:** Group calls use transport encryption only (QUIC). Audio is encrypted on the wire but the WZP relay can see it. Direct 1:1 calls are E2E encrypted via existing Double Ratchet.
**Goal:** E2E encrypt group call audio using MLS (Messaging Layer Security, RFC 9420).
**Why MLS over alternatives:**
- **Sender Keys** (Signal/WhatsApp): simpler but O(n) key distribution, no forward secrecy on member change
- **MLS/TreeKEM**: O(log n) key updates, forward secrecy on every member change, designed for groups
- **RFC 9420** is an IETF standard with multiple implementations (OpenMLS in Rust)
**Approach:**
1. Integrate `openmls` crate for key agreement
2. Each group call creates an MLS group (epoch 0)
3. Members join via Welcome messages distributed through existing E2E channels
4. Audio frames encrypted with the group's current epoch key (AES-GCM)
5. Member leave triggers Commit + UpdatePath (O(log n) key rotation)
6. WZP relay sees only ciphertext
**Dependencies:** OpenMLS crate, WASM compatibility for browser side
---
## 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 | — | DONE (v0.0.41) |
| 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 | — | DONE (v0.0.39) |
| FC-P6-T7 | Tab completion for commands/aliases | 0.5d | — | DONE (v0.0.39) |
| FC-P6-T8 | File transfer progress gauge | 0.5d | — | TODO |
| FC-P6-T9 | TUI address clipboard copy | 0.5d | — | TODO |
| FC-P6-T10 | Web virtual scroll for large history | 0.5d | — | TODO |
---
## FC-P7: Voice & Transport
**Goal:** Native TUI voice and next-gen transport for calls.
| ID | Task | Effort | Dep | Status |
|----|------|--------|-----|--------|
| FC-P7-T1 | TUI voice calls via cpal | 1-2d | — | TODO |
| FC-P7-T2 | Sender Keys for DM call E2E | 1w | — | TODO |
| FC-P7-T3 | WebTransport to replace wzp-web bridge | 2w | — | TODO |
---
## Parallelization Guide
Tasks with **no dependencies** that can run simultaneously:
**Sprint A (Security — P1):** DONE
```
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):** DONE
```
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):** DONE (except T5)
```
FC-P3-T1 (WASM parse) — independent
FC-P3-T2 (WASM create) — independent
FC-P3-T5 (extract web.rs) — independent (TODO)
→ 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 |
| warzone-server | 10+ | Server integration tests |
| **Total** | **~155** | All passing |